1 /***
2 *
3 */
4 package de.cohesion.bssh.impl;
5
6 import java.io.IOException;
7
8 import ch.ethz.ssh2.Connection;
9 import de.cohesion.bssh.Member;
10 import de.cohesion.bssh.PasswordStore;
11 import de.cohesion.bssh.impl.io.Console;
12 import de.cohesion.bssh.impl.io.PasswordHelper;
13
14 /***
15 * @author schulzs
16 *
17 */
18 public class SSHConnectionFactory implements Factory<Member, Connection> {
19
20 private final PasswordStore store;
21
22 private final int retries;
23
24 public SSHConnectionFactory(int retries, final PasswordStore store) {
25 this.retries = retries;
26 this.store = store;
27 }
28
29 public Connection create(final Member m) throws InstantiationException {
30
31 Member credMember = m;
32 if (m instanceof GatewayMemberImpl) {
33 credMember = GatewayMemberImpl.class.cast(m).getProxied();
34 }
35
36
37
38
39
40 char[] password = null;
41 try {
42 password = store.getPassword(credMember);
43 } catch (Exception e) {
44
45
46
47
48 Console.getLock().lock();
49 try {
50 password = PasswordHelper.getPassword(System.in,
51 "Provide password for " + credMember + ": ");
52 store.store(credMember, password);
53 } catch (IOException ioe) {
54 InstantiationException ie = new InstantiationException(
55 "storing password failed");
56 ie.initCause(ioe);
57 throw ie;
58 } finally {
59 Console.getLock().unlock();
60 }
61 }
62
63 Connection c = new Connection(m.getHost().getHostAddress(), m.getPort());
64
65 try {
66
67
68 boolean connected = false;
69 int tries = 0;
70 while (!connected) {
71 try {
72 c.connect();
73 connected = true;
74 break;
75 } catch (IOException ioe) {
76 if (tries >= retries - 1) {
77 throw ioe;
78 }
79 }
80
81 tries++;
82
83
84
85
86
87 try {
88 long duration = Math.round(Math.pow(2, tries)) * 1000;
89 Thread.sleep(duration);
90 } catch (InterruptedException ie) {
91
92 }
93
94 }
95
96
97 boolean success = false;
98 if (c.isAuthMethodAvailable(m.getUserName(), "password")) {
99 success = c.authenticateWithPassword(m.getUserName(),
100 new String(password));
101 } else if (c.isAuthMethodAvailable(m.getUserName(),
102 "keyboard-interactive")) {
103 ChallengeHandler h = new PasswordChallengeHandler(password);
104 success = c.authenticateWithKeyboardInteractive(
105 m.getUserName(), new ChallengeHandlerAdapter(h));
106 }
107 if (success == false) {
108 throw new IOException("authentication failed.");
109 }
110 } catch (IOException ioe) {
111 InstantiationException ie = new InstantiationException(
112 "connection refused");
113 ie.initCause(ioe);
114 throw ie;
115 }
116
117 return c;
118
119 }
120
121 public void destroy(final Connection c) {
122 c.close();
123 }
124
125 }