1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.server.ldap.handlers.extended;
21
22
23 import java.security.Provider;
24 import java.security.SecureRandom;
25 import java.security.Security;
26 import java.util.Collections;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Set;
30
31 import javax.net.ssl.SSLContext;
32 import javax.net.ssl.TrustManager;
33
34 import org.apache.directory.api.ldap.extras.extended.startTls.StartTlsRequest;
35 import org.apache.directory.api.ldap.extras.extended.startTls.StartTlsResponse;
36 import org.apache.directory.api.ldap.extras.extended.startTls.StartTlsResponseImpl;
37 import org.apache.directory.api.ldap.model.message.ExtendedRequest;
38 import org.apache.directory.api.ldap.model.message.ExtendedResponse;
39 import org.apache.directory.api.ldap.model.message.LdapResult;
40 import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
41 import org.apache.directory.ldap.client.api.NoVerificationTrustManager;
42 import org.apache.directory.server.i18n.I18n;
43 import org.apache.directory.server.ldap.ExtendedOperationHandler;
44 import org.apache.directory.server.ldap.LdapServer;
45 import org.apache.directory.server.ldap.LdapSession;
46 import org.apache.directory.server.protocol.shared.transport.TcpTransport;
47 import org.apache.directory.server.protocol.shared.transport.Transport;
48 import org.apache.mina.core.filterchain.IoFilterChain;
49 import org.apache.mina.filter.ssl.SslFilter;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52
53
54
55
56
57
58
59
60 public class StartTlsHandler implements ExtendedOperationHandler<ExtendedRequest, ExtendedResponse>
61 {
62 public static final String EXTENSION_OID = StartTlsRequest.EXTENSION_OID;
63
64 private static final Set<String> EXTENSION_OIDS;
65 private static final Logger LOG = LoggerFactory.getLogger( StartTlsHandler.class );
66
67
68 private SSLContext sslContext;
69
70
71 private List<String> cipherSuite;
72
73
74 private List<String> enabledProtocols;
75
76
77 private boolean needClientAuth;
78
79
80 private boolean wantClientAuth;
81
82 static
83 {
84 Set<String> set = new HashSet<>( 3 );
85 set.add( EXTENSION_OID );
86 EXTENSION_OIDS = Collections.unmodifiableSet( set );
87 }
88
89
90
91
92
93 public void handleExtendedOperation( LdapSession session, ExtendedRequest req ) throws Exception
94 {
95 LOG.info( "Handling StartTLS request." );
96
97 IoFilterChain chain = session.getIoSession().getFilterChain();
98 SslFilter sslFilter = ( SslFilter ) chain.get( "sslFilter" );
99
100 if ( sslFilter == null )
101 {
102 sslFilter = new SslFilter( sslContext, false );
103
104
105 if ( ( cipherSuite != null ) && !cipherSuite.isEmpty() )
106 {
107 sslFilter.setEnabledCipherSuites( cipherSuite.toArray( new String[cipherSuite.size()] ) );
108 }
109
110
111 if ( ( enabledProtocols != null ) && !enabledProtocols.isEmpty() )
112 {
113 sslFilter.setEnabledProtocols( enabledProtocols.toArray( new String[enabledProtocols.size()] ) );
114 }
115 else
116 {
117
118 sslFilter.setEnabledProtocols( new String[]{ "TLSv1", "TLSv1.1", "TLSv1.2" } );
119 }
120
121
122 sslFilter.setNeedClientAuth( needClientAuth );
123 sslFilter.setWantClientAuth( wantClientAuth );
124
125 chain.addFirst( "sslFilter", sslFilter );
126 }
127 else
128 {
129
130 sslFilter.setEnabledProtocols( new String[]
131 { "TLSv1", "TLSv1.1", "TLSv1.2" } );
132 sslFilter.startSsl( session.getIoSession() );
133 }
134
135 StartTlsResponse res = new StartTlsResponseImpl( req.getMessageId() );
136 LdapResult result = res.getLdapResult();
137 result.setResultCode( ResultCodeEnum.SUCCESS );
138 res.setResponseName( EXTENSION_OID );
139
140
141 session.getIoSession().setAttribute( SslFilter.DISABLE_ENCRYPTION_ONCE );
142 session.getIoSession().write( res );
143 }
144
145
146
147
148
149 public final Set<String> getExtensionOids()
150 {
151 return EXTENSION_OIDS;
152 }
153
154
155
156
157
158 public final String getOid()
159 {
160 return EXTENSION_OID;
161 }
162
163
164
165
166
167 public void setLdapServer( LdapServer ldapServer )
168 {
169 LOG.debug( "Setting LDAP Service" );
170 Provider provider = Security.getProvider( "SUN" );
171 LOG.debug( "provider = {}", provider );
172
173 try
174 {
175 sslContext = SSLContext.getInstance( "TLS" );
176 }
177 catch ( Exception e )
178 {
179 throw new RuntimeException( I18n.err( I18n.ERR_681 ), e );
180 }
181
182 try
183 {
184 sslContext.init( ldapServer.getKeyManagerFactory().getKeyManagers(), new TrustManager[]
185 { new NoVerificationTrustManager() }, new SecureRandom() );
186 }
187 catch ( Exception e )
188 {
189 throw new RuntimeException( I18n.err( I18n.ERR_682 ), e );
190 }
191
192
193 Transport[] transports = ldapServer.getTransports();
194
195
196 for ( Transport transport : transports )
197 {
198 if ( transport instanceof TcpTransport )
199 {
200 TcpTransport./../../org/apache/directory/server/protocol/shared/transport/TcpTransport.html#TcpTransport">TcpTransport tcpTransport = ( TcpTransport ) transport;
201
202 cipherSuite = tcpTransport.getCipherSuite();
203 enabledProtocols = tcpTransport.getEnabledProtocols();
204 needClientAuth = tcpTransport.isNeedClientAuth();
205 wantClientAuth = tcpTransport.isWantClientAuth();
206
207 break;
208 }
209 }
210 }
211 }