in git-agent/src/main/java/jetbrains/buildServer/buildTriggers/vcs/git/agent/JSchClient.java [110:234]
public void run() throws Exception {
myLogger.log(Logger.INFO, "SSH command to run: " + myCommand);
ChannelExec channel = null;
Session session = null;
try {
JSchConfigInitializer.initJSchConfig(JSch.class);
JSch.setLogger(myLogger);
JSch jsch = new JSch();
String privateKeyPath = myEnvironmentAccessor.apply(GitSSHHandler.TEAMCITY_PRIVATE_KEY_PATH);
if (privateKeyPath != null) {
jsch.addIdentity(privateKeyPath, myEnvironmentAccessor.apply(GitSSHHandler.TEAMCITY_PASSPHRASE));
} else {
String userHome = System.getProperty("user.home");
if (userHome != null) {
File homeDir = new File(userHome);
File ssh = new File(homeDir, ".ssh");
File rsa = new File(ssh, "id_rsa");
if (rsa.isFile()) {
jsch.addIdentity(rsa.getAbsolutePath());
}
File dsa = new File(ssh, "id_dsa");
if (dsa.isFile()) {
jsch.addIdentity(dsa.getAbsolutePath());
}
File config = new File(ssh, "config");
if (config.isFile()) {
ConfigRepository configRepository = OpenSSHConfig.parseFile(config.getAbsolutePath());
jsch.setConfigRepository(new TeamCityConfigRepository(configRepository, myUsername));
}
}
}
session = jsch.getSession(myUsername, myHost, myPort != null ? myPort : 22);
SshPubkeyAcceptedAlgorithms.configureSession(session);
String teamCityVersion = myEnvironmentAccessor.apply(GitSSHHandler.TEAMCITY_VERSION);
if (teamCityVersion != null) {
session.setClientVersion(GitUtils.getSshClientVersion(session.getClientVersion(), teamCityVersion));
}
if (Boolean.parseBoolean(myEnvironmentAccessor.apply(GitSSHHandler.SSH_IGNORE_KNOWN_HOSTS_ENV))) {
session.setConfig("StrictHostKeyChecking", "no");
} else {
String knownHostsFilePath = myEnvironmentAccessor.apply(GitSSHHandler.SSH_KNOWN_HOSTS_FILE);
File knownHosts = null;
if (knownHostsFilePath != null) {
knownHosts = new File(knownHostsFilePath);
} else {
String userHome = System.getProperty("user.home");
if (userHome != null) {
File homeDir = new File(userHome);
File ssh = new File(homeDir, ".ssh");
knownHosts = new File(ssh, "known_hosts");
}
}
if (knownHosts != null && knownHosts.isFile()) {
try {
jsch.setKnownHosts(knownHosts.getAbsolutePath());
} catch (Exception e) {
myLogger.log(Logger.WARN, "Failed to configure known hosts: '" + e.toString() + "'");
}
}
}
String authMethods = myEnvironmentAccessor.apply(GitSSHHandler.TEAMCITY_SSH_PREFERRED_AUTH_METHODS);
if (isNotEmpty(authMethods))
session.setConfig("PreferredAuthentications", authMethods);
if (!myOptions.isEmpty()) {
for (final Map.Entry<String, String> opEntry : myOptions.entrySet()) {
session.setConfig(opEntry.getKey(), opEntry.getValue());
}
}
EmptySecurityCallbackHandler.install();
// It looks like sometimes session/channel close() doesn't interrupt
// all reads. Ask jsch to create daemon threads so that uninterrupted
// threads don't prevent us from exit.
session.setDaemonThread(true);
final Integer connectTimeoutSeconds = getConnectTimeoutSeconds();
if (connectTimeoutSeconds != null) {
session.connect(connectTimeoutSeconds * 1000);
} else {
session.connect();
}
channel = (ChannelExec) session.openChannel("exec");
channel.setPty(false);
channel.setCommand(myCommand);
channel.setInputStream(System.in);
channel.setErrStream(System.err);
final String sendEnv = myEnvironmentAccessor.apply(GitSSHHandler.TEAMCITY_SSH_REQUEST_TOKEN);
if (isNotEmpty(sendEnv)) {
channel.setEnv(GitSSHHandler.TEAMCITY_SSH_REQUEST_TOKEN, sendEnv);
}
InputStream input = channel.getInputStream();
Integer timeoutSeconds = getTimeoutSeconds();
if (timeoutSeconds != null) {
channel.connect(timeoutSeconds * 1000);
} else {
channel.connect();
}
if (!channel.isConnected() && input.available() == 0) {
throw new IOException("Connection failed");
}
Copy copyThread = new Copy(input);
if (timeoutSeconds != null) {
new Timer(copyThread, timeoutSeconds).start();
}
copyThread.start();
copyThread.join();
copyThread.rethrowError();
} finally {
if (channel != null)
channel.disconnect();
if (session != null)
session.disconnect();
}
}