sb.append((char) c);
}
}
SshClient client = null;
Terminal terminal = null;
SshAgent agent = null;
int exitStatus = 0;
try {
agent = startAgent(user);
client = SshClient.setUpDefaultClient();
client.setAgentFactory(new LocalAgentFactory(agent));
client.getProperties().put(SshAgent.SSH_AUTHSOCKET_ENV_NAME, "local");
client.start();
int retries = 0;
ClientSession session = null;
do {
ConnectFuture future = client.connect(host, port);
future.await();
try {
session = future.getSession();
} catch (RuntimeSshException ex) {
if (retries++ < retryAttempts) {
Thread.sleep(retryDelay * 1000);
System.out.println("retrying (attempt " + retries + ") ...");
} else {
throw ex;
}
}
} while (session == null);
if (!session.authAgent(user).await().isSuccess()) {
if (password == null) {
Console console = System.console();
if (console != null) {
char[] readPassword = console.readPassword("Password: ");
if (readPassword != null) {
password = new String(readPassword);
}
} else {
throw new Exception("Unable to prompt password: could not get system console");
}
}
if (!session.authPassword(user, password).await().isSuccess()) {
throw new Exception("Authentication failure");
}
}
ClientChannel channel;
if (sb.length() > 0) {
channel = session.createChannel("exec", sb.append("\n").toString());
channel.setIn(new ByteArrayInputStream(new byte[0]));
} else {
terminal = new TerminalFactory().getTerminal();
channel = session.createChannel("shell");
ConsoleInputStream in = new ConsoleInputStream(terminal.wrapInIfNeeded(System.in));
new Thread(in).start();
channel.setIn(in);
((ChannelShell) channel).setPtyColumns(terminal != null ? terminal.getWidth() : 80);
((ChannelShell) channel).setupSensibleDefaultPty();
((ChannelShell) channel).setAgentForwarding(true);
String ctype = System.getenv("LC_CTYPE");
if (ctype == null) {
ctype = Locale.getDefault().toString() + "."
+ System.getProperty("input.encoding", Charset.defaultCharset().name());
}
((ChannelShell) channel).setEnv("LC_CTYPE", ctype);
}
channel.setOut(AnsiConsole.wrapOutputStream(System.out));
channel.setErr(AnsiConsole.wrapOutputStream(System.err));
channel.open();
channel.waitFor(ClientChannel.CLOSED, 0);
if (channel.getExitStatus() != null) {
exitStatus = channel.getExitStatus();
}
} catch (Throwable t) {
if (level > 1) {
t.printStackTrace();
} else {
System.err.println(t.getMessage());
}
System.exit(1);
} finally {
try {
client.stop();
} catch (Throwable t) { }
try {
if (terminal != null) {
terminal.restore();
}
} catch (Throwable t) { }
}
System.exit(exitStatus);
}