1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.net.ftp;
19
20 import java.io.BufferedReader;
21 import java.io.BufferedWriter;
22 import java.io.IOException;
23 import java.io.InputStreamReader;
24 import java.io.OutputStreamWriter;
25 import java.net.Socket;
26 import java.security.KeyManagementException;
27 import java.security.NoSuchAlgorithmException;
28
29 import javax.net.ssl.KeyManager;
30 import javax.net.ssl.SSLContext;
31 import javax.net.ssl.SSLException;
32 import javax.net.ssl.SSLServerSocketFactory;
33 import javax.net.ssl.SSLSocket;
34 import javax.net.ssl.SSLSocketFactory;
35 import javax.net.ssl.TrustManager;
36
37
38
39
40
41
42
43
44 public class FTPSClient extends FTPClient {
45
46
47 public static String KEYSTORE_ALGORITHM;
48
49 public static String TRUSTSTORE_ALGORITHM;
50
51 public static String PROVIDER;
52
53 public static String STORE_TYPE;
54
55
56 private static final String[] PROT_COMMAND_VALUE = {"C","E","S","P"};
57
58 private static final String DEFAULT_PROT = "C";
59
60 private static final String DEFAULT_PROTOCOL = "TLS";
61
62
63 private boolean isImplicit;
64
65 private String protocol = DEFAULT_PROTOCOL;
66
67 private String auth = DEFAULT_PROTOCOL;
68
69 private SSLContext context;
70
71 private Socket planeSocket;
72
73 private boolean isCreation = true;
74
75 private boolean isClientMode = true;
76
77 private boolean isNeedClientAuth = false;
78
79 private boolean isWantClientAuth = false;
80
81 private String[] suites = null;
82
83 private String[] protocols = null;
84
85
86 private TrustManager trustManager = new FTPSTrustManager();
87
88
89 private KeyManager keyManager;
90
91
92
93
94
95
96 public FTPSClient() throws NoSuchAlgorithmException {
97 this.protocol = DEFAULT_PROTOCOL;
98 this.isImplicit = false;
99 }
100
101
102
103
104
105
106
107 public FTPSClient(boolean isImplicit) throws NoSuchAlgorithmException {
108 this.protocol = DEFAULT_PROTOCOL;
109 this.isImplicit = isImplicit;
110 }
111
112
113
114
115
116
117
118 public FTPSClient(String protocol) throws NoSuchAlgorithmException {
119 this.protocol = protocol;
120 this.isImplicit = false;
121 }
122
123
124
125
126
127
128
129
130 public FTPSClient(String protocol, boolean isImplicit)
131 throws NoSuchAlgorithmException {
132 this.protocol = protocol;
133 this.isImplicit = isImplicit;
134 }
135
136
137
138
139
140
141
142 public void setAuthValue(String auth) {
143 this.auth = auth;
144 }
145
146
147
148
149
150 public String getAuthValue() {
151 return this.auth;
152 }
153
154
155
156
157
158
159
160
161
162
163 @Override
164 protected void _connectAction_() throws IOException {
165
166 if (isImplicit) sslNegotiation();
167 super._connectAction_();
168
169 if (!isImplicit) {
170 execAUTH();
171 sslNegotiation();
172 }
173 }
174
175
176
177
178
179
180
181 private void execAUTH() throws SSLException, IOException {
182 int replyCode = sendCommand(
183 FTPSCommand._commands[FTPSCommand.AUTH], auth);
184 if (FTPReply.SECURITY_MECHANISM_IS_OK == replyCode) {
185
186
187 } else if (FTPReply.SECURITY_DATA_EXCHANGE_COMPLETE != replyCode) {
188 throw new SSLException(getReplyString());
189 }
190 }
191
192
193
194
195
196 private void initSslContext() throws IOException {
197 if(context == null) {
198 try {
199 context = SSLContext.getInstance(protocol);
200
201 context.init(new KeyManager[] { getKeyManager() } , new TrustManager[] { getTrustManager() } , null);
202 } catch (KeyManagementException e) {
203 IOException ioe = new IOException("Could not initialize SSL context");
204 ioe.initCause(e);
205 throw ioe;
206 } catch (NoSuchAlgorithmException e) {
207 IOException ioe = new IOException("Could not initialize SSL context");
208 ioe.initCause(e);
209 throw ioe;
210 }
211 }
212 }
213
214
215
216
217
218
219 private void sslNegotiation() throws IOException {
220
221 planeSocket = _socket_;
222
223 initSslContext();
224
225 SSLSocketFactory ssf = context.getSocketFactory();
226 String ip = _socket_.getInetAddress().getHostAddress();
227 int port = _socket_.getPort();
228 SSLSocket socket =
229 (SSLSocket) ssf.createSocket(_socket_, ip, port, true);
230 socket.setEnableSessionCreation(isCreation);
231 socket.setUseClientMode(isClientMode);
232
233 if (!isClientMode) {
234 socket.setNeedClientAuth(isNeedClientAuth);
235 socket.setWantClientAuth(isWantClientAuth);
236 }
237 if (protocols != null) socket.setEnabledProtocols(protocols);
238 if (suites != null) socket.setEnabledCipherSuites(suites);
239
240 socket.startHandshake();
241
242 _socket_ = socket;
243 _controlInput_ = new BufferedReader(new InputStreamReader(
244 socket .getInputStream(), getControlEncoding()));
245 _controlOutput_ = new BufferedWriter(new OutputStreamWriter(
246 socket.getOutputStream(), getControlEncoding()));
247 }
248
249
250
251
252
253 private KeyManager getKeyManager() {
254 return keyManager;
255 }
256
257
258
259
260
261
262 public void setKeyManager(KeyManager keyManager) {
263 this.keyManager = keyManager;
264 }
265
266
267
268
269
270 public void setEnabledSessionCreation(boolean isCreation) {
271 this.isCreation = isCreation;
272 }
273
274
275
276
277
278
279
280
281 public boolean getEnableSessionCreation() {
282 if (_socket_ instanceof SSLSocket)
283 return ((SSLSocket)_socket_).getEnableSessionCreation();
284 return false;
285 }
286
287
288
289
290
291 public void setNeedClientAuth(boolean isNeedClientAuth) {
292 this.isNeedClientAuth = isNeedClientAuth;
293 }
294
295
296
297
298
299
300
301 public boolean getNeedClientAuth() {
302 if (_socket_ instanceof SSLSocket)
303 return ((SSLSocket)_socket_).getNeedClientAuth();
304 return false;
305 }
306
307
308
309
310
311
312
313 public void setWantClientAuth(boolean isWantClientAuth) {
314 this.isWantClientAuth = isWantClientAuth;
315 }
316
317
318
319
320
321
322
323 public boolean getWantClientAuth() {
324 if (_socket_ instanceof SSLSocket)
325 return ((SSLSocket)_socket_).getWantClientAuth();
326 return false;
327 }
328
329
330
331
332
333
334 public void setUseClientMode(boolean isClientMode) {
335 this.isClientMode = isClientMode;
336 }
337
338
339
340
341
342
343
344
345 public boolean getUseClientMode() {
346 if (_socket_ instanceof SSLSocket)
347 return ((SSLSocket)_socket_).getUseClientMode();
348 return false;
349 }
350
351
352
353
354
355
356 public void setEnabledCipherSuites(String[] cipherSuites) {
357 suites = new String[cipherSuites.length];
358 System.arraycopy(cipherSuites, 0, suites, 0, cipherSuites.length);
359 }
360
361
362
363
364
365
366
367 public String[] getEnabledCipherSuites() {
368 if (_socket_ instanceof SSLSocket)
369 return ((SSLSocket)_socket_).getEnabledCipherSuites();
370 return null;
371 }
372
373
374
375
376
377
378 public void setEnabledProtocols(String[] protocolVersions) {
379 protocols = new String[protocolVersions.length];
380 System.arraycopy(protocolVersions, 0, protocols, 0, protocolVersions.length);
381 }
382
383
384
385
386
387
388
389 public String[] getEnabledProtocols() {
390 if (_socket_ instanceof SSLSocket)
391 return ((SSLSocket)_socket_).getEnabledProtocols();
392 return null;
393 }
394
395
396
397
398
399
400
401
402 public void execPBSZ(long pbsz) throws SSLException, IOException {
403 if (pbsz < 0 || 4294967295L < pbsz)
404 throw new IllegalArgumentException();
405 if (FTPReply.COMMAND_OK != sendCommand(
406 FTPSCommand._commands[FTPSCommand.PBSZ],String.valueOf(pbsz)))
407 throw new SSLException(getReplyString());
408 }
409
410
411
412
413
414
415
416
417
418
419
420
421 public void execPROT(String prot) throws SSLException, IOException {
422 if (prot == null) prot = DEFAULT_PROT;
423 if (!checkPROTValue(prot)) throw new IllegalArgumentException();
424 if (FTPReply.COMMAND_OK != sendCommand(
425 FTPSCommand._commands[FTPSCommand.PROT], prot))
426 throw new SSLException(getReplyString());
427 if (DEFAULT_PROT.equals(prot)) {
428 setSocketFactory(null);
429 setServerSocketFactory(null);
430 } else {
431 setSocketFactory(new FTPSSocketFactory(context));
432
433 initSslContext();
434
435 SSLServerSocketFactory ssf = context.getServerSocketFactory();
436
437 setServerSocketFactory(ssf);
438 }
439 }
440
441
442
443
444
445
446 private boolean checkPROTValue(String prot) {
447 for (int p = 0; p < PROT_COMMAND_VALUE.length; p++) {
448 if (PROT_COMMAND_VALUE[p].equals(prot)) return true;
449 }
450 return false;
451 }
452
453
454
455
456
457
458
459
460
461
462
463 @Override
464 public int sendCommand(String command, String args) throws IOException {
465 int repCode = super.sendCommand(command, args);
466 if (FTPSCommand._commands[FTPSCommand.CCC].equals(command)) {
467 if (FTPReply.COMMAND_OK == repCode) {
468
469 _socket_ = planeSocket;
470 setSocketFactory(null);
471 } else {
472 throw new SSLException(getReplyString());
473 }
474 }
475 return repCode;
476 }
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491 @Override
492 protected Socket _openDataConnection_(int command, String arg)
493 throws IOException {
494 Socket socket = super._openDataConnection_(command, arg);
495 if (socket != null && socket instanceof SSLSocket) {
496 SSLSocket sslSocket = (SSLSocket)socket;
497 sslSocket.setUseClientMode(isClientMode);
498 sslSocket.setEnableSessionCreation(isCreation);
499
500 if (!isClientMode) {
501 sslSocket.setNeedClientAuth(isNeedClientAuth);
502 sslSocket.setWantClientAuth(isWantClientAuth);
503 }
504 if (suites != null)
505 sslSocket.setEnabledCipherSuites(suites);
506 if (protocols != null)
507 sslSocket.setEnabledProtocols(protocols);
508 sslSocket.startHandshake();
509 }
510 return socket;
511 }
512
513
514
515
516
517
518 public TrustManager getTrustManager() {
519 return trustManager;
520 }
521
522
523
524
525
526
527 public void setTrustManager(TrustManager trustManager) {
528 this.trustManager = trustManager;
529 }
530
531
532
533 }