1 | |
package org.apache.maven.scm.provider.cvslib.cvsjava.util; |
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
|
17 | |
|
18 | |
|
19 | |
|
20 | |
|
21 | |
|
22 | |
import ch.ethz.ssh2.Connection; |
23 | |
import ch.ethz.ssh2.Session; |
24 | |
import ch.ethz.ssh2.StreamGobbler; |
25 | |
import org.netbeans.lib.cvsclient.CVSRoot; |
26 | |
import org.netbeans.lib.cvsclient.command.CommandAbortedException; |
27 | |
import org.netbeans.lib.cvsclient.connection.AbstractConnection; |
28 | |
import org.netbeans.lib.cvsclient.connection.AuthenticationException; |
29 | |
import org.netbeans.lib.cvsclient.connection.ConnectionModifier; |
30 | |
import org.netbeans.lib.cvsclient.util.LoggedDataInputStream; |
31 | |
import org.netbeans.lib.cvsclient.util.LoggedDataOutputStream; |
32 | |
|
33 | |
import java.io.BufferedReader; |
34 | |
import java.io.File; |
35 | |
import java.io.IOException; |
36 | |
import java.io.InputStream; |
37 | |
import java.io.InputStreamReader; |
38 | |
|
39 | |
|
40 | |
|
41 | |
|
42 | |
|
43 | |
public class ExtConnection |
44 | |
extends AbstractConnection |
45 | |
{ |
46 | |
private String host; |
47 | |
|
48 | |
private int port; |
49 | |
|
50 | |
private String userName; |
51 | |
|
52 | |
private String password; |
53 | |
|
54 | |
private Connection connection; |
55 | |
|
56 | |
private Session session; |
57 | |
|
58 | |
private BufferedReader stderrReader; |
59 | |
|
60 | |
public ExtConnection( CVSRoot cvsRoot ) |
61 | |
{ |
62 | 0 | this( cvsRoot.getHostName(), cvsRoot.getPort(), cvsRoot.getUserName(), cvsRoot.getPassword(), |
63 | |
cvsRoot.getRepository() ); |
64 | 0 | } |
65 | |
|
66 | |
public ExtConnection( String host, int port, String username, String password, String repository ) |
67 | 0 | { |
68 | 0 | this.userName = username; |
69 | |
|
70 | 0 | if ( this.userName == null ) |
71 | |
{ |
72 | 0 | this.userName = System.getProperty( "user.name" ); |
73 | |
} |
74 | |
|
75 | 0 | this.password = password; |
76 | |
|
77 | 0 | this.host = host; |
78 | |
|
79 | 0 | setRepository( repository ); |
80 | |
|
81 | 0 | this.port = port; |
82 | |
|
83 | 0 | if ( this.port == 0 ) |
84 | |
{ |
85 | 0 | this.port = 22; |
86 | |
} |
87 | 0 | } |
88 | |
|
89 | |
|
90 | |
public void open() |
91 | |
throws AuthenticationException, CommandAbortedException |
92 | |
{ |
93 | 0 | connection = new Connection( host, port ); |
94 | |
|
95 | |
|
96 | |
|
97 | |
|
98 | |
|
99 | |
|
100 | |
|
101 | |
try |
102 | |
{ |
103 | |
|
104 | 0 | connection.connect(); |
105 | |
} |
106 | 0 | catch ( IOException e ) |
107 | |
{ |
108 | 0 | String message = "Cannot connect. Reason: " + e.getMessage(); |
109 | 0 | throw new AuthenticationException( message, e, message ); |
110 | 0 | } |
111 | |
|
112 | 0 | File privateKey = getPrivateKey(); |
113 | |
|
114 | |
try |
115 | |
{ |
116 | |
boolean authenticated; |
117 | 0 | if ( privateKey != null && privateKey.exists() ) |
118 | |
{ |
119 | 0 | authenticated = connection.authenticateWithPublicKey( userName, privateKey, getPassphrase() ); |
120 | |
} |
121 | |
else |
122 | |
{ |
123 | 0 | authenticated = connection.authenticateWithPassword( userName, password ); |
124 | |
} |
125 | |
|
126 | 0 | if ( !authenticated ) |
127 | |
{ |
128 | 0 | String message = "Authentication failed."; |
129 | 0 | throw new AuthenticationException( message, message ); |
130 | |
} |
131 | |
} |
132 | 0 | catch ( IOException e ) |
133 | |
{ |
134 | 0 | closeConnection(); |
135 | 0 | String message = "Cannot authenticate. Reason: " + e.getMessage(); |
136 | 0 | throw new AuthenticationException( message, e, message ); |
137 | 0 | } |
138 | |
|
139 | |
try |
140 | |
{ |
141 | 0 | session = connection.openSession(); |
142 | |
} |
143 | 0 | catch ( IOException e ) |
144 | |
{ |
145 | 0 | String message = "Cannot open session. Reason: " + e.getMessage(); |
146 | 0 | throw new CommandAbortedException( message, message ); |
147 | 0 | } |
148 | |
|
149 | 0 | String command = "cvs server"; |
150 | |
try |
151 | |
{ |
152 | 0 | session.execCommand( command ); |
153 | |
} |
154 | 0 | catch ( IOException e ) |
155 | |
{ |
156 | 0 | String message = "Cannot execute remote command: " + command; |
157 | 0 | throw new CommandAbortedException( message, message ); |
158 | 0 | } |
159 | |
|
160 | 0 | InputStream stdout = new StreamGobbler( session.getStdout() ); |
161 | 0 | InputStream stderr = new StreamGobbler( session.getStderr() ); |
162 | 0 | stderrReader = new BufferedReader( new InputStreamReader( stderr ) ); |
163 | 0 | setInputStream( new LoggedDataInputStream( stdout ) ); |
164 | 0 | setOutputStream( new LoggedDataOutputStream( session.getStdin() ) ); |
165 | 0 | } |
166 | |
|
167 | |
|
168 | |
public void verify() |
169 | |
throws AuthenticationException |
170 | |
{ |
171 | |
try |
172 | |
{ |
173 | 0 | open(); |
174 | 0 | verifyProtocol(); |
175 | 0 | close(); |
176 | |
} |
177 | 0 | catch ( Exception e ) |
178 | |
{ |
179 | 0 | String message = "Failed to verify the connection: " + e.getMessage(); |
180 | 0 | throw new AuthenticationException( message, e, message ); |
181 | 0 | } |
182 | 0 | } |
183 | |
|
184 | |
private void closeConnection() |
185 | |
{ |
186 | |
try |
187 | |
{ |
188 | 0 | if ( stderrReader != null ) |
189 | |
{ |
190 | |
while ( true ) |
191 | |
{ |
192 | 0 | String line = stderrReader.readLine(); |
193 | 0 | if ( line == null ) |
194 | |
{ |
195 | 0 | break; |
196 | |
} |
197 | |
|
198 | 0 | System.err.println( line ); |
199 | 0 | } |
200 | |
} |
201 | |
} |
202 | 0 | catch ( IOException e ) |
203 | |
{ |
204 | |
|
205 | 0 | } |
206 | |
|
207 | 0 | if ( session != null ) |
208 | |
{ |
209 | 0 | System.out.println( "Exit code:" + session.getExitStatus().intValue() ); |
210 | 0 | session.close(); |
211 | |
} |
212 | |
|
213 | 0 | if ( connection != null ) |
214 | |
{ |
215 | 0 | connection.close(); |
216 | |
} |
217 | |
|
218 | 0 | reset(); |
219 | 0 | } |
220 | |
|
221 | |
private void reset() |
222 | |
{ |
223 | 0 | connection = null; |
224 | 0 | session = null; |
225 | 0 | stderrReader = null; |
226 | 0 | setInputStream( null ); |
227 | 0 | setOutputStream( null ); |
228 | 0 | } |
229 | |
|
230 | |
|
231 | |
public void close() |
232 | |
throws IOException |
233 | |
{ |
234 | 0 | closeConnection(); |
235 | 0 | } |
236 | |
|
237 | |
|
238 | |
public boolean isOpen() |
239 | |
{ |
240 | 0 | return connection != null; |
241 | |
} |
242 | |
|
243 | |
|
244 | |
public int getPort() |
245 | |
{ |
246 | 0 | return port; |
247 | |
} |
248 | |
|
249 | |
|
250 | |
public void modifyInputStream( ConnectionModifier modifier ) |
251 | |
throws IOException |
252 | |
{ |
253 | 0 | modifier.modifyInputStream( getInputStream() ); |
254 | 0 | } |
255 | |
|
256 | |
|
257 | |
public void modifyOutputStream( ConnectionModifier modifier ) |
258 | |
throws IOException |
259 | |
{ |
260 | 0 | modifier.modifyOutputStream( getOutputStream() ); |
261 | 0 | } |
262 | |
|
263 | |
private File getPrivateKey() |
264 | |
{ |
265 | |
|
266 | 0 | File privateKey = null; |
267 | 0 | if ( password == null ) |
268 | |
{ |
269 | 0 | String pk = System.getProperty( "maven.scm.cvs.java.ssh.privateKey" ); |
270 | 0 | if ( pk != null ) |
271 | |
{ |
272 | 0 | privateKey = new File( pk ); |
273 | |
} |
274 | |
else |
275 | |
{ |
276 | 0 | privateKey = findPrivateKey(); |
277 | |
} |
278 | |
} |
279 | 0 | return privateKey; |
280 | |
} |
281 | |
|
282 | |
private String getPassphrase() |
283 | |
{ |
284 | 0 | String passphrase = System.getProperty( "maven.scm.cvs.java.ssh.passphrase" ); |
285 | |
|
286 | 0 | if ( passphrase == null ) |
287 | |
{ |
288 | 0 | passphrase = ""; |
289 | |
} |
290 | |
|
291 | 0 | return passphrase; |
292 | |
} |
293 | |
|
294 | |
private File findPrivateKey() |
295 | |
{ |
296 | 0 | String privateKeyDirectory = System.getProperty( "maven.scm.ssh.privateKeyDirectory" ); |
297 | |
|
298 | 0 | if ( privateKeyDirectory == null ) |
299 | |
{ |
300 | 0 | privateKeyDirectory = System.getProperty( "user.home" ); |
301 | |
} |
302 | |
|
303 | 0 | File privateKey = new File( privateKeyDirectory, ".ssh/id_dsa" ); |
304 | |
|
305 | 0 | if ( !privateKey.exists() ) |
306 | |
{ |
307 | 0 | privateKey = new File( privateKeyDirectory, ".ssh/id_rsa" ); |
308 | |
} |
309 | |
|
310 | 0 | return privateKey; |
311 | |
} |
312 | |
} |