1 17 18 package org.apache.geronimo.security; 19 20 import java.io.Serializable ; 21 import java.security.AccessControlContext ; 22 import java.security.AccessControlException ; 23 import java.security.AccessController ; 24 import java.security.InvalidKeyException ; 25 import java.security.NoSuchAlgorithmException ; 26 import java.security.Principal ; 27 import java.security.PrivilegedAction ; 28 import java.util.Hashtable ; 29 import java.util.IdentityHashMap ; 30 import java.util.Map ; 31 import java.util.Set ; 32 import javax.crypto.Mac; 33 import javax.crypto.SecretKey; 34 import javax.crypto.spec.SecretKeySpec; 35 import javax.security.auth.Subject ; 36 import javax.security.jacc.EJBRoleRefPermission ; 37 38 import org.apache.geronimo.security.realm.providers.GeronimoCallerPrincipal; 39 40 41 44 public class ContextManager { 45 private static ThreadLocal currentCallerId = new ThreadLocal (); 46 private static final ThreadLocal callers = new ThreadLocal (); 47 private static Map subjectContexts = new IdentityHashMap (); 48 private static Map subjectIds = new Hashtable (); 49 private static long nextSubjectId = System.currentTimeMillis(); 50 51 private static SecretKey key; 52 private static String algorithm; 53 private static String password; 54 55 public static final GeronimoSecurityPermission GET_CONTEXT = new GeronimoSecurityPermission("getContext"); 56 public static final GeronimoSecurityPermission SET_CONTEXT = new GeronimoSecurityPermission("setContext"); 57 58 static { 59 password = "secret"; 60 ContextManager.setAlgorithm("HmacSHA1"); 61 } 62 63 69 public static Subject getServerSideSubject(Subject clientSideSubject) { 70 Set set = clientSideSubject.getPrincipals(IdentificationPrincipal.class); 71 if(set == null || set.size() == 0) { 72 return null; 73 } 74 IdentificationPrincipal idp = (IdentificationPrincipal)set.iterator().next(); 75 return getRegisteredSubject(idp.getId()); 76 } 77 78 public static void setCurrentCallerId(Serializable id) { 79 SecurityManager sm = System.getSecurityManager(); 80 if (sm != null) sm.checkPermission(SET_CONTEXT); 81 82 currentCallerId.set(id); 83 } 84 85 public static Serializable getCurrentCallerId() { 86 SecurityManager sm = System.getSecurityManager(); 87 if (sm != null) sm.checkPermission(GET_CONTEXT); 88 89 return (Serializable ) currentCallerId.get(); 90 } 91 92 public static void setCallers(Subject currentCaller, Subject nextCaller) { 93 SecurityManager sm = System.getSecurityManager(); 94 if (sm != null) sm.checkPermission(SET_CONTEXT); 95 assert currentCaller != null; 96 assert nextCaller != null; 97 Callers newCallers = new Callers(currentCaller, nextCaller); 98 callers.set(newCallers); 99 } 100 101 public static void clearCallers() { 102 callers.set(null); 103 } 104 105 public static Callers getCallers() { 106 SecurityManager sm = System.getSecurityManager(); 107 if (sm != null) sm.checkPermission(GET_CONTEXT); 108 return (Callers) callers.get(); 109 } 110 111 public static Callers setNextCaller(Subject nextCaller) { 112 SecurityManager sm = System.getSecurityManager(); 113 if (sm != null) sm.checkPermission(SET_CONTEXT); 114 assert nextCaller != null; 115 Callers oldCallers = (Callers) callers.get(); 116 assert oldCallers != null; 117 Callers newCallers = new Callers(oldCallers.getNextCaller(), nextCaller); 118 callers.set(newCallers); 119 return oldCallers; 120 } 121 122 public static Callers pushNextCaller(Subject nextCaller) { 123 SecurityManager sm = System.getSecurityManager(); 124 if (sm != null) sm.checkPermission(SET_CONTEXT); 125 Callers oldCallers = (Callers) callers.get(); 126 Subject oldNextCaller = oldCallers == null? null: oldCallers.getNextCaller(); 127 Subject newNextCaller = nextCaller == null? oldNextCaller : nextCaller; 128 Callers newCallers = new Callers(oldNextCaller, newNextCaller); 129 callers.set(newCallers); 130 return oldCallers; 131 } 132 133 public static void popCallers(Callers oldCallers) { 134 SecurityManager sm = System.getSecurityManager(); 135 if (sm != null) sm.checkPermission(SET_CONTEXT); 136 callers.set(oldCallers); 137 } 138 139 public static Subject getCurrentCaller() { 140 SecurityManager sm = System.getSecurityManager(); 141 if (sm != null) sm.checkPermission(GET_CONTEXT); 142 143 Callers callers = (Callers) ContextManager.callers.get(); 144 return callers == null? null: callers.getCurrentCaller(); 145 } 146 147 public static Subject getNextCaller() { 148 SecurityManager sm = System.getSecurityManager(); 149 if (sm != null) sm.checkPermission(GET_CONTEXT); 150 151 Callers callers = (Callers) ContextManager.callers.get(); 152 return callers == null? null: callers.getNextCaller(); 153 } 154 155 public static AccessControlContext getCurrentContext() { 156 SecurityManager sm = System.getSecurityManager(); 157 if (sm != null) sm.checkPermission(GET_CONTEXT); 158 159 Callers threadLocalCallers = (Callers) callers.get(); 160 assert threadLocalCallers != null : "No current callers"; 161 Subject currentSubject = threadLocalCallers.getCurrentCaller(); 162 assert currentSubject != null : "No current caller"; 163 Context context = (Context ) subjectContexts.get(currentSubject); 164 165 assert context != null : "No registered context"; 166 167 return context.context; 168 } 169 170 public static Principal getCurrentPrincipal(Subject callerSubject) { 171 SecurityManager sm = System.getSecurityManager(); 172 if (sm != null) sm.checkPermission(GET_CONTEXT); 173 174 if (callerSubject == null) { 175 return new Principal () { 176 public String getName() { 177 return ""; 178 } 179 }; 180 } 181 Context context = (Context ) subjectContexts.get(callerSubject); 182 183 assert context != null : "No registered context"; 184 185 return context.principal; 186 } 187 188 public static SubjectId getCurrentId() { 189 SecurityManager sm = System.getSecurityManager(); 190 if (sm != null) sm.checkPermission(GET_CONTEXT); 191 192 Callers threadLocalCallers = (Callers) callers.get(); 193 assert threadLocalCallers != null : "No current callers"; 194 Subject currentSubject = threadLocalCallers.getCurrentCaller(); 195 assert currentSubject != null : "No current caller"; 196 Context context = (Context ) subjectContexts.get(currentSubject); 197 198 assert context != null : "No registered context"; 199 200 return context.id; 201 } 202 203 public static SubjectId getSubjectId(Subject subject) { 204 SecurityManager sm = System.getSecurityManager(); 205 if (sm != null) sm.checkPermission(GET_CONTEXT); 206 207 Context context = (Context ) subjectContexts.get(subject); 208 209 return (context != null ? context.id : null); 210 } 211 212 public static boolean isCallerInRole(String EJBName, String role) { 213 if (EJBName == null) throw new IllegalArgumentException ("EJBName must not be null"); 214 if (role == null) throw new IllegalArgumentException ("Role must not be null"); 215 216 try { 217 Callers currentCallers = (Callers)callers.get(); 218 if (currentCallers == null) { 219 return false; 220 } 221 Subject currentSubject = currentCallers.getCurrentCaller(); 222 if (currentSubject == null) { 223 return false; 224 } 225 226 Context context = (Context ) subjectContexts.get(currentSubject); 227 228 assert context != null : "No registered context"; 229 230 context.context.checkPermission(new EJBRoleRefPermission (EJBName, role)); 231 } catch (AccessControlException e) { 232 return false; 233 } 234 return true; 235 } 236 237 public static Subject getRegisteredSubject(SubjectId id) { 238 return (Subject ) subjectIds.get(id); 239 } 240 241 public static synchronized SubjectId registerSubject(Subject subject) { 242 SecurityManager sm = System.getSecurityManager(); 243 if (sm != null) sm.checkPermission(SET_CONTEXT); 244 245 if (subject == null) throw new IllegalArgumentException ("Subject must not be null"); 246 247 AccessControlContext acc = (AccessControlContext ) Subject.doAsPrivileged(subject, new PrivilegedAction () { 248 public Object run() { 249 return AccessController.getContext(); 250 } 251 }, null); 252 253 Context context = new Context (); 254 context.subject = subject; 255 context.context = acc; 256 Set principals = subject.getPrincipals((Class )GeronimoCallerPrincipal.class); 257 if (!principals.isEmpty()) { 258 context.principal = (Principal ) principals.iterator().next(); 259 } else if (!(principals = subject.getPrincipals(PrimaryRealmPrincipal.class)).isEmpty()) { 260 context.principal = (PrimaryRealmPrincipal) principals.iterator().next(); 261 } else if (!(principals = subject.getPrincipals(RealmPrincipal.class)).isEmpty()) { 262 context.principal = (RealmPrincipal) principals.iterator().next(); 263 } else if (!(principals = subject.getPrincipals()).isEmpty()) { 264 context.principal = (Principal ) principals.iterator().next(); 265 } 266 Long id = new Long (nextSubjectId++); 267 context.id = new SubjectId(id, hash(id)); 268 269 subjectIds.put(context.id, subject); 270 subjectContexts.put(subject, context); 271 272 return context.id; 273 } 274 275 public static synchronized void unregisterSubject(Subject subject) { 276 SecurityManager sm = System.getSecurityManager(); 277 if (sm != null) sm.checkPermission(SET_CONTEXT); 278 279 if (subject == null) throw new IllegalArgumentException ("Subject must not be null"); 280 281 Context context = (Context ) subjectContexts.get(subject); 282 if (context == null) return; 283 284 subjectIds.remove(context.id); 285 subjectContexts.remove(subject); 286 } 287 288 305 public static IdentificationPrincipal getThreadPrincipal() { 306 SecurityManager sm = System.getSecurityManager(); 307 if (sm != null) sm.checkPermission(GET_CONTEXT); 308 309 Subject subject = Subject.getSubject(AccessController.getContext()); 310 if (subject != null) { 311 Set set = subject.getPrincipals(IdentificationPrincipal.class); 312 if (!set.isEmpty()) return (IdentificationPrincipal) set.iterator().next(); 313 } 314 return null; 315 } 316 317 public static String getAlgorithm() { 318 SecurityManager sm = System.getSecurityManager(); 319 if (sm != null) sm.checkPermission(GET_CONTEXT); 320 321 return algorithm; 322 } 323 324 public static void setAlgorithm(String algorithm) { 325 SecurityManager sm = System.getSecurityManager(); 326 if (sm != null) sm.checkPermission(SET_CONTEXT); 327 328 ContextManager.algorithm = algorithm; 329 330 key = new SecretKeySpec(password.getBytes(), algorithm); 331 332 335 try { 336 Mac mac = Mac.getInstance(algorithm); 337 mac.init(key); 338 } catch (NoSuchAlgorithmException e) { 339 assert false : "Should never have reached here"; 340 } catch (InvalidKeyException e) { 341 assert false : "Should never have reached here"; 342 } 343 } 344 345 public static String getPassword() { 346 SecurityManager sm = System.getSecurityManager(); 347 if (sm != null) sm.checkPermission(GET_CONTEXT); 348 349 return password; 350 } 351 352 public static void setPassword(String password) { 353 SecurityManager sm = System.getSecurityManager(); 354 if (sm != null) sm.checkPermission(SET_CONTEXT); 355 356 ContextManager.password = password; 357 358 key = new SecretKeySpec(password.getBytes(), algorithm); 359 } 360 361 private static byte[] hash(Long id) { 362 long n = id.longValue(); 363 byte[] bytes = new byte[8]; 364 for (int i = 7; i >= 0; i--) { 365 bytes[i] = (byte) (n); 366 n >>>= 8; 367 } 368 369 try { 370 Mac mac = Mac.getInstance(algorithm); 371 mac.init(key); 372 mac.update(bytes); 373 374 return mac.doFinal(); 375 } catch (NoSuchAlgorithmException e) { 376 } catch (InvalidKeyException e) { 377 } 378 assert false : "Should never have reached here"; 379 return null; 380 } 381 382 private static class Context { 383 SubjectId id; 384 AccessControlContext context; 385 Subject subject; 386 Principal principal; 387 } 388 389 } 390 | Popular Tags |