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;
21
22
23 import org.apache.directory.api.ldap.codec.api.LdapDecoder;
24 import org.apache.directory.api.ldap.codec.api.LdapMessageContainer;
25 import org.apache.directory.api.ldap.codec.api.SchemaBinaryAttributeDetector;
26 import org.apache.directory.api.ldap.model.exception.ResponseCarryingMessageException;
27 import org.apache.directory.api.ldap.model.message.Control;
28 import org.apache.directory.api.ldap.model.message.Message;
29 import org.apache.directory.api.ldap.model.message.Request;
30 import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
31 import org.apache.directory.api.ldap.model.message.ResultResponse;
32 import org.apache.directory.api.ldap.model.message.ResultResponseRequest;
33 import org.apache.directory.api.ldap.model.message.extended.NoticeOfDisconnect;
34 import org.apache.mina.core.buffer.IoBuffer;
35 import org.apache.mina.core.session.IoSession;
36 import org.apache.mina.filter.FilterEvent;
37 import org.apache.mina.filter.ssl.SslEvent;
38 import org.apache.mina.handler.demux.DemuxingIoHandler;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42
43
44
45
46
47
48
49
50
51
52 class LdapProtocolHandler extends DemuxingIoHandler
53 {
54
55 private static final Logger LOG = LoggerFactory.getLogger( LdapProtocolHandler.class );
56
57
58 private final LdapServer ldapServer;
59
60
61
62
63
64
65
66 LdapProtocolHandler( LdapServer ldapServer )
67 {
68 this.ldapServer = ldapServer;
69 }
70
71
72
73
74
75
76
77
78 @Override
79 public void sessionCreated( IoSession session ) throws Exception
80 {
81
82 LdapSessionapSession.html#LdapSession">LdapSession ldapSession = new LdapSession( session );
83 ldapServer.getLdapSessionManager().addLdapSession( ldapSession );
84
85
86 session.setAttribute( LdapDecoder.MAX_PDU_SIZE_ATTR, ldapServer.getDirectoryService().getMaxPDUSize() );
87
88
89 LdapMessageContainer<Message> ldapMessageContainer =
90 new LdapMessageContainer<>(
91 ldapServer.getDirectoryService().getLdapCodecService(),
92 new SchemaBinaryAttributeDetector(
93 ldapServer.getDirectoryService().getSchemaManager() ) );
94
95 session.setAttribute( LdapDecoder.MESSAGE_CONTAINER_ATTR, ldapMessageContainer );
96 }
97
98
99
100
101
102
103
104
105 @Override
106 public void sessionClosed( IoSession session )
107 {
108
109 LdapSession ldapSession = ldapServer.getLdapSessionManager().removeLdapSession( session );
110
111
112 cleanUpSession( ldapSession );
113 }
114
115
116
117
118
119
120
121
122 private void cleanUpSession( LdapSession ldapSession )
123 {
124 if ( ldapSession == null )
125 {
126 LOG.debug( "Null LdapSession given to cleanUpSession." );
127 return;
128 }
129
130 LOG.debug( "Cleaning the {} session", ldapSession );
131
132
133 ldapSession.abandonAllOutstandingRequests();
134
135 if ( !ldapSession.getIoSession().isClosing() || ldapSession.getIoSession().isConnected() )
136 {
137 try
138 {
139 ldapSession.getIoSession().closeNow();
140 }
141 catch ( Throwable t )
142 {
143 LOG.warn( "Failed to close IoSession for LdapSession." );
144 }
145 }
146 }
147
148
149
150
151
152 @Override
153 public void messageSent( IoSession session, Object message ) throws Exception
154 {
155
156
157 if ( message instanceof IoBuffer )
158 {
159
160 return;
161 }
162
163 super.messageSent( session, message );
164 }
165
166
167
168
169
170 @Override
171 public void event( IoSession session, FilterEvent event ) throws Exception
172 {
173 if ( event instanceof SslEvent )
174 {
175 if ( ( ( SslEvent ) event ) == SslEvent.SECURED )
176 {
177 LdapSession ldapSession = ldapServer.getLdapSessionManager().getLdapSession( session );
178 LOG.debug( "Session {} secured", ldapSession );
179 }
180 else
181 {
182 LdapSession ldapSession = ldapServer.getLdapSessionManager().getLdapSession( session );
183 LOG.debug( "Session {} not secured", ldapSession );
184 }
185 }
186 }
187
188
189
190
191
192 @Override
193 public void messageReceived( IoSession session, Object message ) throws Exception
194 {
195
196
197
198
199
200
201
202
203
204
205 if ( ( ( Request ) message ).getControls().size() > 0
206 && message instanceof ResultResponseRequest )
207 {
208 ResultResponseRequest req = ( ResultResponseRequest ) message;
209
210 for ( Control control : req.getControls().values() )
211 {
212 if ( control.isCritical() && !ldapServer.getSupportedControls().contains( control.getOid() ) )
213 {
214 ResultResponse resp = req.getResultResponse();
215 resp.getLdapResult().setDiagnosticMessage( "Unsupport critical control: " + control.getOid() );
216 resp.getLdapResult().setResultCode( ResultCodeEnum.UNAVAILABLE_CRITICAL_EXTENSION );
217 session.write( resp );
218
219 return;
220 }
221 }
222 }
223
224 super.messageReceived( session, message );
225 }
226
227
228
229
230
231 @Override
232 public void exceptionCaught( IoSession session, Throwable cause )
233 {
234 if ( cause.getCause() instanceof ResponseCarryingMessageException )
235 {
236 ResponseCarryingMessageException rcme = ( ResponseCarryingMessageException ) cause.getCause();
237
238 if ( rcme.getResponse() != null )
239 {
240 session.write( rcme.getResponse() );
241 return;
242 }
243 }
244
245 LOG.warn( "Unexpected exception forcing session to close: sending disconnect notice to client.", cause );
246
247 session.write( NoticeOfDisconnect.PROTOCOLERROR );
248 session.closeOnFlush();
249
250
251 }
252 }