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 javax.naming.ldap.Control;
24
25 import org.apache.directory.shared.ldap.message.ExtendedRequest;
26 import org.apache.directory.shared.ldap.message.ExtendedRequestImpl;
27 import org.apache.directory.shared.ldap.message.MutableControl;
28 import org.apache.directory.shared.ldap.message.Request;
29 import org.apache.directory.shared.ldap.message.ResponseCarryingMessageException;
30 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
31 import org.apache.directory.shared.ldap.message.ResultResponse;
32 import org.apache.directory.shared.ldap.message.ResultResponseRequest;
33 import org.apache.directory.shared.ldap.message.extended.NoticeOfDisconnect;
34 import org.apache.mina.common.IoFilterChain;
35 import org.apache.mina.common.IoHandler;
36 import org.apache.mina.common.IoSession;
37 import org.apache.mina.filter.SSLFilter;
38 import org.apache.mina.filter.codec.ProtocolCodecFilter;
39 import org.apache.mina.handler.demux.DemuxingIoHandler;
40 import org.apache.mina.util.SessionLog;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44
45
46
47
48
49
50
51
52
53
54
55 class LdapProtocolHandler extends DemuxingIoHandler
56 {
57
58 private static final Logger LOG = LoggerFactory.getLogger( LdapProtocolHandler.class );
59
60
61 private final LdapService ldapService;
62
63
64
65
66
67
68
69 LdapProtocolHandler( LdapService ldapService )
70 {
71 this.ldapService = ldapService;
72 }
73
74
75
76
77
78
79 public void sessionCreated( IoSession session ) throws Exception
80 {
81 LdapSession ldapSession = new LdapSession( session );
82 IoFilterChain filters = session.getFilterChain();
83 filters.addLast( "codec", new ProtocolCodecFilter( ldapService.getProtocolCodecFactory() ) );
84 ldapService.getLdapSessionManager().addLdapSession( ldapSession );
85 }
86
87
88
89
90
91
92 public void sessionClosed( IoSession session )
93 {
94 LdapSession ldapSession = ldapService.getLdapSessionManager().removeLdapSession( session );
95 cleanUpSession( ldapSession );
96 }
97
98
99
100
101
102
103
104
105 private void cleanUpSession( LdapSession ldapSession )
106 {
107 if ( ldapSession == null )
108 {
109 LOG.warn( "Null LdapSession given to cleanUpSession." );
110 return;
111 }
112
113 if ( ldapSession != null )
114 {
115 ldapSession.abandonAllOutstandingRequests();
116 }
117
118 if ( ! ldapSession.getIoSession().isClosing() || ldapSession.getIoSession().isConnected() )
119 {
120 try
121 {
122 ldapSession.getIoSession().close();
123 }
124 catch ( Throwable t )
125 {
126 LOG.warn( "Failed to close IoSession for LdapSession." );
127 }
128 }
129 }
130
131
132
133
134
135
136 public void messageReceived( IoSession session, Object message ) throws Exception
137 {
138
139
140
141
142
143
144
145
146
147
148
149 if ( message == SSLFilter.SESSION_SECURED )
150 {
151 ExtendedRequest req = new ExtendedRequestImpl( 0 );
152 req.setOid( "1.3.6.1.4.1.1466.20037" );
153 req.setPayload( "SECURED".getBytes( "ISO-8859-1" ) );
154 message = req;
155 }
156 else if ( message == SSLFilter.SESSION_UNSECURED )
157 {
158 ExtendedRequest req = new ExtendedRequestImpl( 0 );
159 req.setOid( "1.3.6.1.4.1.1466.20037" );
160 req.setPayload( "UNSECURED".getBytes( "ISO-8859-1" ) );
161 message = req;
162 }
163
164 if ( ( ( Request ) message ).getControls().size() > 0 && message instanceof ResultResponseRequest )
165 {
166 ResultResponseRequest req = ( ResultResponseRequest ) message;
167 for ( Control control1 : req.getControls().values() )
168 {
169 MutableControl control = ( MutableControl ) control1;
170 if ( control.isCritical() && ! ldapService.getSupportedControls().contains( control.getID() ) )
171 {
172 ResultResponse resp = req.getResultResponse();
173 resp.getLdapResult().setErrorMessage( "Unsupport critical control: " + control.getID() );
174 resp.getLdapResult().setResultCode( ResultCodeEnum.UNAVAILABLE_CRITICAL_EXTENSION );
175 session.write( resp );
176 return;
177 }
178 }
179 }
180
181 super.messageReceived( session, message );
182 }
183
184
185
186
187
188
189 public void exceptionCaught( IoSession session, Throwable cause )
190 {
191 if ( cause.getCause() instanceof ResponseCarryingMessageException )
192 {
193 ResponseCarryingMessageException rcme = ( ResponseCarryingMessageException ) cause.getCause();
194
195 if ( rcme.getResponse() != null )
196 {
197 session.write( rcme.getResponse() );
198 return;
199 }
200 }
201
202 SessionLog.warn( session,
203 "Unexpected exception forcing session to close: sending disconnect notice to client.", cause );
204
205 session.write( NoticeOfDisconnect.PROTOCOLERROR );
206 LdapSession ldapSession = this.ldapService.getLdapSessionManager().removeLdapSession( session );
207 cleanUpSession( ldapSession );
208 session.close();
209 }
210 }