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.sasl.gssapi;
21
22
23 import java.security.PrivilegedExceptionAction;
24 import java.util.HashMap;
25 import java.util.Map;
26
27 import javax.security.auth.Subject;
28 import javax.security.auth.callback.CallbackHandler;
29 import javax.security.auth.kerberos.KerberosKey;
30 import javax.security.auth.kerberos.KerberosPrincipal;
31 import javax.security.sasl.Sasl;
32 import javax.security.sasl.SaslServer;
33
34 import org.apache.directory.api.ldap.model.constants.SupportedSaslMechanisms;
35 import org.apache.directory.api.ldap.model.message.BindRequest;
36 import org.apache.directory.api.ldap.model.name.Dn;
37 import org.apache.directory.server.core.api.CoreSession;
38 import org.apache.directory.server.i18n.I18n;
39 import org.apache.directory.server.kerberos.shared.store.PrincipalStoreEntry;
40 import org.apache.directory.server.protocol.shared.kerberos.GetPrincipal;
41 import org.apache.directory.server.ldap.LdapServer;
42 import org.apache.directory.server.ldap.LdapSession;
43 import org.apache.directory.server.ldap.handlers.sasl.AbstractMechanismHandler;
44 import org.apache.directory.server.ldap.handlers.sasl.SaslConstants;
45 import org.apache.directory.server.protocol.shared.ServiceConfigurationException;
46 import org.apache.directory.shared.kerberos.codec.types.EncryptionType;
47 import org.apache.directory.shared.kerberos.components.EncryptionKey;
48
49
50
51
52
53
54
55 public class GssapiMechanismHandler extends AbstractMechanismHandler
56 {
57 public SaslServer handleMechanism( LdapSession ldapSession, BindRequest bindRequest ) throws Exception
58 {
59 SaslServer ss = ( SaslServer ) ldapSession.getSaslProperty( SaslConstants.SASL_SERVER );
60
61 if ( ss == null )
62 {
63 Subject subject = getSubject( ldapSession.getLdapServer() );
64 final String saslHost = ( String ) ldapSession.getSaslProperty( SaslConstants.SASL_HOST );
65 final Map<String, String> saslProps = ( Map<String, String> ) ldapSession
66 .getSaslProperty( SaslConstants.SASL_PROPS );
67
68 CoreSession adminSession = ldapSession.getLdapServer().getDirectoryService().getAdminSession();
69
70 final CallbackHandler callbackHandler = new GssapiCallbackHandler( ldapSession, adminSession, bindRequest );
71
72 ss = Subject.doAs( subject, new PrivilegedExceptionAction<SaslServer>()
73 {
74 public SaslServer run() throws Exception
75 {
76 return Sasl.createSaslServer( SupportedSaslMechanisms.GSSAPI, SaslConstants.LDAP_PROTOCOL,
77 saslHost, saslProps, callbackHandler );
78 }
79 } );
80
81 ldapSession.putSaslProperty( SaslConstants.SASL_SERVER, ss );
82 }
83
84 return ss;
85 }
86
87
88
89
90
91 public void init( LdapSession ldapSession )
92 {
93
94 String saslHost = ldapSession.getLdapServer().getSaslHost();
95 ldapSession.putSaslProperty( SaslConstants.SASL_HOST, saslHost );
96
97 Map<String, String> saslProps = new HashMap<>();
98 saslProps.put( Sasl.QOP, ldapSession.getLdapServer().getSaslQopString() );
99 ldapSession.putSaslProperty( SaslConstants.SASL_PROPS, saslProps );
100 }
101
102
103
104
105
106
107
108 public void cleanup( LdapSession ldapSession )
109 {
110
111 insertSaslFilter( ldapSession );
112
113
114 ldapSession.removeSaslProperty( SaslConstants.SASL_HOST );
115 ldapSession.removeSaslProperty( SaslConstants.SASL_USER_BASE_DN );
116 ldapSession.removeSaslProperty( SaslConstants.SASL_MECH );
117 ldapSession.removeSaslProperty( SaslConstants.SASL_PROPS );
118 ldapSession.removeSaslProperty( SaslConstants.SASL_AUTHENT_USER );
119 }
120
121
122 private Subject getSubject( LdapServer ldapServer ) throws Exception
123 {
124 String servicePrincipalName = ldapServer.getSaslPrincipal();
125 KerberosPrincipal servicePrincipal = new KerberosPrincipal( servicePrincipalName );
126 GetPrincipalprotocol/shared/kerberos/GetPrincipal.html#GetPrincipal">GetPrincipal getPrincipal = new GetPrincipal( servicePrincipal );
127
128 PrincipalStoreEntry entry = null;
129
130 try
131 {
132 entry = findPrincipal( ldapServer, getPrincipal );
133 }
134 catch ( ServiceConfigurationException sce )
135 {
136 String message = I18n.err( I18n.ERR_659, servicePrincipalName, ldapServer.getSearchBaseDn() );
137 throw new ServiceConfigurationException( message, sce );
138 }
139
140 if ( entry == null )
141 {
142 String message = I18n.err( I18n.ERR_659, servicePrincipalName, ldapServer.getSearchBaseDn() );
143 throw new ServiceConfigurationException( message );
144 }
145
146 Subject subject = new Subject();
147
148 for ( EncryptionType encryptionType : entry.getKeyMap().keySet() )
149 {
150 EncryptionKey key = entry.getKeyMap().get( encryptionType );
151
152 byte[] keyBytes = key.getKeyValue();
153 int type = key.getKeyType().getValue();
154 int kvno = key.getKeyVersion();
155
156 KerberosKey serviceKey = new KerberosKey( servicePrincipal, keyBytes, type, kvno );
157
158 subject.getPrivateCredentials().add( serviceKey );
159 }
160
161 return subject;
162 }
163
164
165 private PrincipalStoreEntry findPrincipal( LdapServer ldapServer, GetPrincipal getPrincipal ) throws Exception
166 {
167 CoreSession adminSession = ldapServer.getDirectoryService().getAdminSession();
168 return ( PrincipalStoreEntry ) getPrincipal.execute( adminSession, new Dn( ldapServer.getSearchBaseDn() ) );
169 }
170 }