1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package net.sf.hermesftp.cmd;
26
27 import java.io.IOException;
28 import java.net.Socket;
29
30 import javax.net.SocketFactory;
31 import javax.net.ssl.SSLSocket;
32 import javax.net.ssl.SSLSocketFactory;
33
34 import net.sf.hermesftp.common.FtpConstants;
35 import net.sf.hermesftp.common.FtpSessionContext;
36 import net.sf.hermesftp.exception.FtpConfigException;
37 import net.sf.hermesftp.utils.IOUtils;
38
39 /***
40 * Provider for the client socket (active transfer). The creation of the socket is deferred until it
41 * is needed.
42 *
43 * @author Behnke
44 */
45 public class ActiveModeSocketProvider implements SocketProvider {
46
47 private FtpSessionContext ctx;
48
49 private DataChannelInfo dataChannelInfo;
50
51 private Socket socket;
52
53 /***
54 * Constructor.
55 *
56 * @param ctx Session context.
57 * @param info Channel about the data channel to open.
58 */
59 public ActiveModeSocketProvider(FtpSessionContext ctx, DataChannelInfo info) {
60 this.ctx = ctx;
61 this.dataChannelInfo = info;
62 }
63
64 /***
65 * {@inheritDoc}
66 */
67 public DataChannelInfo init() throws IOException {
68 closeSocket();
69 return dataChannelInfo;
70 }
71
72 /***
73 * {@inheritDoc}
74 */
75 public Socket provideSocket() throws IOException {
76 if (socket == null) {
77 socket = createClientSocket();
78 }
79 return socket;
80 }
81
82 /***
83 * {@inheritDoc}
84 */
85 public void closeSocket() {
86 if (socket != null) {
87 IOUtils.closeGracefully(socket);
88 socket = null;
89 }
90
91 }
92
93 private Socket createClientSocket() throws IOException {
94 Socket dataSocket;
95 Boolean dataProtection = (Boolean) ctx.getAttribute(FtpConstants.ATTR_DATA_PROT);
96 boolean ssl = dataProtection != null && dataProtection.booleanValue();
97 if (ssl) {
98 SSLSocketFactory factory;
99 try {
100 factory = ctx.getOptions().getSslContext().getSocketFactory();
101 } catch (FtpConfigException e) {
102 throw new IOException("Setting up SSL failed.");
103 }
104 SSLSocket sslSocket = (SSLSocket) factory.createSocket(dataChannelInfo.getAddress(),
105 dataChannelInfo.getPort());
106 sslSocket.setUseClientMode(false);
107 enableCipherSuites(sslSocket);
108 dataSocket = sslSocket;
109 } else {
110 dataSocket = SocketFactory.getDefault().createSocket(dataChannelInfo.getAddress(),
111 dataChannelInfo.getPort());
112 }
113 return dataSocket;
114 }
115
116 /***
117 * Enables the configured cipher suites in the passed socket.
118 *
119 * @param sslSocket The socket.
120 */
121 private void enableCipherSuites(SSLSocket sslSocket) {
122 String[] cipherSuites = ctx.getOptions().getStringArray(FtpConstants.OPT_SSL_CIPHER_SUITES, null);
123 if (cipherSuites != null) {
124 if (cipherSuites.length == 1 && FtpConstants.WILDCARD.equals(cipherSuites[0])) {
125 sslSocket.setEnabledCipherSuites(sslSocket.getSupportedCipherSuites());
126 } else {
127 sslSocket.setEnabledCipherSuites(cipherSuites);
128 }
129 }
130 }
131
132 }