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.kerberos.sam;
21
22
23 import java.util.HashMap;
24 import java.util.Hashtable;
25 import java.util.Map;
26
27 import javax.naming.NamingException;
28 import javax.naming.directory.DirContext;
29 import javax.security.auth.kerberos.KerberosKey;
30
31 import org.apache.directory.server.kerberos.shared.messages.value.SamType;
32 import org.apache.directory.server.kerberos.shared.store.PrincipalStoreEntry;
33
34
35
36
37
38
39
40
41
42 public final class SamSubsystem
43 {
44
45 public static final String PROPKEY_BASE = "kerberos.sam.type.";
46
47
48 public static SamSubsystem instance;
49
50
51 private final Map<SamType, SamVerifier> verifiers = new HashMap<SamType, SamVerifier>();
52
53
54 private KeyIntegrityChecker keyChecker;
55
56
57 private DirContext userContext;
58 private String userBaseRdn;
59
60
61
62
63
64
65
66 public static SamSubsystem getInstance()
67 {
68 if ( instance == null )
69 {
70 instance = new SamSubsystem();
71 }
72
73 return instance;
74 }
75
76
77
78
79
80
81
82 public void setIntegrityChecker( KeyIntegrityChecker keyChecker )
83 {
84 this.keyChecker = keyChecker;
85 }
86
87
88
89
90
91
92
93
94
95
96
97
98 public KerberosKey verify( PrincipalStoreEntry entry, byte[] sad ) throws SamException
99 {
100 SamVerifier verifier = null;
101
102 if ( keyChecker == null )
103 {
104 throw new IllegalStateException( "SamSubsystem not enabled with key integrity checker" );
105 }
106
107 if ( entry.getSamType() == null )
108 {
109 throw new SamException( entry.getSamType(), "Entry has null SAM type" );
110 }
111
112 if ( verifiers.containsKey( entry.getSamType() ) )
113 {
114 verifier = verifiers.get( entry.getSamType() );
115
116 return verifier.verify( entry.getPrincipal(), sad );
117 }
118
119 String key = PROPKEY_BASE + entry.getSamType().getOrdinal();
120
121 Hashtable<Object, Object> env = new Hashtable<Object, Object>();
122
123 try
124 {
125 env.putAll( userContext.getEnvironment() );
126 }
127 catch ( NamingException e )
128 {
129 e.printStackTrace();
130 }
131
132 if ( !env.containsKey( key ) )
133 {
134 String msg = "Could not find property '" + key + "'";
135
136 throw new SamException( entry.getSamType(), msg );
137 }
138
139 String fqcn = ( String ) env.get( key );
140
141 try
142 {
143 Class c = Class.forName( fqcn );
144
145 verifier = ( SamVerifier ) c.newInstance();
146
147 try
148 {
149 verifier.setUserContext( ( DirContext ) userContext.lookup( userBaseRdn ) );
150 }
151 catch ( NamingException e )
152 {
153 e.printStackTrace();
154
155 }
156
157 verifier.setIntegrityChecker( keyChecker );
158
159 verifier.startup();
160
161 if ( !verifier.getSamType().equals( entry.getSamType() ) )
162 {
163 String msg = "Expecting entries with SAM type of " + verifier.getSamType();
164
165 msg += " but got a type of entry with SAM type of " + entry.getSamType();
166
167 throw new SamException( entry.getSamType(), msg );
168 }
169
170 verifiers.put( verifier.getSamType(), verifier );
171
172 return verifier.verify( entry.getPrincipal(), sad );
173 }
174 catch ( ClassNotFoundException e )
175 {
176 String msg = "Could not find verifier class '" + fqcn;
177
178 msg += "' for SamType( " + entry.getSamType() + " ) ";
179
180 throw new SamException( entry.getSamType(), msg, e );
181 }
182 catch ( IllegalAccessException e )
183 {
184 String msg = "No public default constructor on class '" + fqcn;
185
186 msg += "' for SamType( " + entry.getSamType() + " ) ";
187
188 throw new SamException( entry.getSamType(), msg, e );
189 }
190 catch ( InstantiationException e )
191 {
192 String msg = "Failed on default constructor invocation for class '" + fqcn;
193
194 msg += "' for SamType( " + entry.getSamType() + " ) ";
195
196 throw new SamException( entry.getSamType(), msg, e );
197 }
198 }
199
200
201
202
203
204
205
206
207 public void setUserContext( DirContext userContext, String userBaseRdn )
208 {
209 this.userContext = userContext;
210 this.userBaseRdn = userBaseRdn;
211 }
212 }