2 * Copyright 2000-2018 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package jetbrains.buildServer.buildTriggers.vcs.git.agent.command.impl;
19 import jetbrains.buildServer.buildTriggers.vcs.git.AuthSettings;
20 import jetbrains.buildServer.buildTriggers.vcs.git.AuthenticationMethod;
21 import jetbrains.buildServer.buildTriggers.vcs.git.agent.Context;
22 import jetbrains.buildServer.buildTriggers.vcs.git.agent.GitCommandLine;
23 import jetbrains.buildServer.log.Loggers;
24 import jetbrains.buildServer.ssh.TeamCitySshKey;
25 import jetbrains.buildServer.ssh.VcsRootSshKeyManager;
26 import jetbrains.buildServer.util.FileUtil;
27 import jetbrains.buildServer.vcs.VcsException;
28 import jetbrains.buildServer.vcs.VcsRoot;
29 import jetbrains.buildServer.version.ServerVersionHolder;
30 import jetbrains.buildServer.version.ServerVersionInfo;
31 import org.jetbrains.annotations.NotNull;
32 import org.jetbrains.annotations.Nullable;
33 import org.jetbrains.git4idea.ssh.GitSSHHandler;
34 import org.jetbrains.git4idea.ssh.GitSSHService;
37 import java.io.IOException;
38 import java.util.ArrayList;
39 import java.util.List;
40 import java.util.Vector;
43 * SSH handler implementation
45 public class SshHandler implements GitSSHService.Handler {
49 private final int myHandlerNo;
53 private final GitSSHService mySsh;
54 private final AuthSettings myAuthSettings;
55 private final List<File> myFilesToClean = new ArrayList<File>();
58 * The constructor that registers the handler in the SSH service and command line
60 * @param ssh the SSH service
61 * @param authSettings authentication settings
62 * @param cmd the command line to register with
63 * @throws VcsException if there is a problem with registering the handler
65 public SshHandler(@NotNull GitSSHService ssh,
66 @Nullable VcsRootSshKeyManager sshKeyManager,
67 @NotNull AuthSettings authSettings,
68 @NotNull GitCommandLine cmd,
70 @NotNull Context ctx) throws VcsException {
72 myAuthSettings = authSettings;
73 cmd.addEnvParam(GitSSHHandler.SSH_PORT_ENV, Integer.toString(mySsh.getXmlRcpPort()));
74 if (myAuthSettings.isIgnoreKnownHosts())
75 cmd.addEnvParam(GitSSHHandler.SSH_IGNORE_KNOWN_HOSTS_ENV, "true");
76 if (authSettings.getAuthMethod() == AuthenticationMethod.TEAMCITY_SSH_KEY) {
77 String keyId = authSettings.getTeamCitySshKeyId();
78 if (keyId != null && sshKeyManager != null) {
79 VcsRoot root = myAuthSettings.getRoot();
81 TeamCitySshKey key = sshKeyManager.getKey(root);
84 File privateKey = FileUtil.createTempFile(tmpDir, "key", "", true);
85 myFilesToClean.add(privateKey);
86 FileUtil.writeFileAndReportErrors(privateKey, new String(key.getPrivateKey()));
87 cmd.addEnvParam(GitSSHHandler.TEAMCITY_PRIVATE_KEY_PATH, privateKey.getCanonicalPath());
88 String passphrase = myAuthSettings.getPassphrase();
89 cmd.addEnvParam(GitSSHHandler.TEAMCITY_PASSPHRASE, passphrase != null ? passphrase : "");
90 } catch (Exception e) {
92 throw new VcsException(e);
98 if (ctx.getSshMacType() != null)
99 cmd.addEnvParam(GitSSHHandler.TEAMCITY_SSH_MAC_TYPE, ctx.getSshMacType());
100 if (ctx.getPreferredSshAuthMethods() != null)
101 cmd.addEnvParam(GitSSHHandler.TEAMCITY_SSH_PREFERRED_AUTH_METHODS, ctx.getPreferredSshAuthMethods());
102 cmd.addEnvParam(GitSSHHandler.TEAMCITY_DEBUG_SSH, String.valueOf(Loggers.VCS.isDebugEnabled()));
103 String teamCityVersion = getTeamCityVersion();
104 if (teamCityVersion != null) {
105 cmd.addEnvParam(GitSSHHandler.TEAMCITY_VERSION, teamCityVersion);
108 cmd.addEnvParam(GitSSHHandler.GIT_SSH_ENV, ssh.getScriptPath());
109 } catch (IOException e) {
111 throw new VcsException("SSH script cannot be generated", e);
113 myHandlerNo = ssh.registerHandler(this);
114 cmd.addEnvParam(GitSSHHandler.SSH_HANDLER_ENV, Integer.toString(myHandlerNo));
118 * Unregister the handler
120 public void unregister() {
122 mySsh.unregisterHandler(myHandlerNo);
126 private void deleteKeys() {
127 for (File f : myFilesToClean) {
132 public boolean verifyServerHostKey(String hostname,
134 String serverHostKeyAlgorithm,
135 String serverHostKey,
140 public String askPassphrase(String username, String keyPath, boolean resetPassword, String lastError) {
144 return myAuthSettings.getPassphrase();
147 public Vector<String> replyToChallenge(String username,
151 Vector<String> prompt,
152 Vector<Boolean> echo,
157 public String askPassword(String username, boolean resetPassword, String lastError) {
158 // The password is injected into URL
163 private static String getTeamCityVersion() {
165 ServerVersionInfo version = ServerVersionHolder.getVersion();
166 return "TeamCity Agent " + version.getDisplayVersion();
167 } catch (Exception e) {