1 23 24 package com.sun.enterprise.security.jauth; 25 26 import java.io.*; 27 import java.util.*; 28 import java.net.URL ; 29 30 import java.lang.reflect.Constructor ; 31 import java.lang.reflect.Method ; 32 import java.lang.reflect.InvocationTargetException ; 33 34 import javax.security.auth.Subject ; 35 import javax.security.auth.callback.Callback ; 36 import javax.security.auth.callback.CallbackHandler ; 37 import javax.security.auth.callback.UnsupportedCallbackException ; 38 import javax.security.auth.login.AppConfigurationEntry ; 39 40 import sun.security.util.PropertyExpander; 41 import sun.security.util.Debug; 42 43 48 class ConfigFile extends AuthConfig { 49 50 private int epoch; 53 54 private String parserClassName; 56 57 private ConfigParser parser; 59 60 static final String CLIENT = "client"; 62 static final String SERVER = "server"; 63 64 private static final String DEFAULT_HANDLER = 65 "auth.login.defaultCallbackHandler"; 66 67 private static final String DEFAULT_PARSER_CLASS = 68 "com.sun.enterprise.security.jauth.ConfigXMLParser"; 69 70 private static final Debug debug = 71 Debug.getInstance("configfile", "[ConfigFile]"); 72 73 ConfigFile() throws IOException { 74 String propertyValue = System.getProperty("configfile.parser"); 75 if (propertyValue == null) { 76 parserClassName = DEFAULT_PARSER_CLASS; 77 } else { 78 parserClassName = propertyValue; 79 } 80 this.epoch = 1; 81 parser = ConfigFile.loadParser(parserClassName); 82 } 83 84 89 public ClientAuthContext getClientAuthContext(String intercept, 90 String id, 91 AuthPolicy requestPolicy, 92 AuthPolicy responsePolicy, 93 CallbackHandler handler) 94 throws AuthException { 95 96 ConfigFile.Entry[] entries = getEntries(intercept, 97 id, 98 requestPolicy, 99 responsePolicy, 100 CLIENT); 101 if (entries == null || entries.length == 0) { 102 return null; 103 } 104 105 107 if (handler == null) { 108 handler = ConfigFile.loadDefaultCallbackHandler(); 109 } else if (handler instanceof DependentCallbackHandler) { 110 handler = new DelegatingHandler(handler); 111 } 112 113 for (int i = 0; i < entries.length; i++) { 114 entries[i].module = ConfigFile.createModule(entries[i], handler); 115 } 116 117 return new ConfigClient(entries); 118 } 119 120 125 public ServerAuthContext getServerAuthContext(String intercept, 126 String id, 127 AuthPolicy requestPolicy, 128 AuthPolicy responsePolicy, 129 CallbackHandler handler) 130 throws AuthException { 131 132 ConfigFile.Entry[] entries = getEntries(intercept, 133 id, 134 requestPolicy, 135 responsePolicy, 136 SERVER); 137 if (entries == null || entries.length == 0) { 138 return null; 139 } 140 141 143 if (handler == null) { 144 handler = ConfigFile.loadDefaultCallbackHandler(); 145 } else if (handler instanceof DependentCallbackHandler) { 146 handler = new DelegatingHandler(handler); 147 } 148 149 for (int i = 0; i < entries.length; i++) { 150 entries[i].module = ConfigFile.createModule(entries[i], handler); 151 } 152 153 return new ConfigServer(entries); 154 } 155 156 public void refresh() throws AuthException { 157 synchronized (parser) { 158 ConfigParser nextParser; 159 int next = this.epoch + 1; 160 try { 161 nextParser = ConfigFile.loadParser(parserClassName); 162 } catch (IOException ioe) { 163 throw new AuthException(ioe.toString()); 164 } 165 this.epoch = (next == 0 ? 1 : next); 166 parser = nextParser; 167 } 168 } 169 170 private ConfigFile.Entry[] getEntries(String intercept, 171 String id, 172 AuthPolicy requestPolicy, 173 AuthPolicy responsePolicy, 174 String type) { 175 176 178 HashMap configMap; 179 180 synchronized (parser) { 181 configMap = parser.getConfigMap(); 182 } 183 184 if (configMap == null) { 185 return null; 186 } 187 188 190 InterceptEntry intEntry = (InterceptEntry)configMap.get(intercept); 191 if (intEntry == null || intEntry.idMap == null) { 192 if (debug != null) { 193 debug.println("module config has no IDs configured for [" + 194 intercept + 195 "]"); 196 } 197 return null; 198 } 199 200 202 IDEntry idEntry = null; 203 if (id == null || (idEntry = (IDEntry)intEntry.idMap.get(id)) == null) { 204 205 211 if (debug != null) { 212 debug.println("DD did not specify ID, " + 213 "or DD-specified ID for [" + 214 intercept + 215 "] not found in config -- " + 216 "attempting to look for default ID"); 217 } 218 219 String defaultID; 220 if (CLIENT.equals(type)) { 221 defaultID = intEntry.defaultClientID; 222 } else { 223 defaultID = intEntry.defaultServerID; 224 } 225 226 idEntry = (IDEntry)intEntry.idMap.get(defaultID); 227 if (idEntry == null) { 228 229 231 if (debug != null) { 232 debug.println("no default config ID for [" + 233 intercept + 234 "]"); 235 } 236 return null; 237 } 238 } 239 240 243 if (idEntry.type.indexOf(type) < 0) { 245 if (debug != null) { 246 debug.println("request type [" + 247 type + 248 "] does not match config type [" + 249 idEntry.type + 250 "]"); 251 } 252 return null; 253 } 254 255 AuthPolicy reqP = (requestPolicy != null || responsePolicy != null) ? 257 requestPolicy : 258 idEntry.requestPolicy; 260 AuthPolicy respP = (requestPolicy != null || responsePolicy != null) ? 261 responsePolicy : 262 idEntry.responsePolicy; 264 if (reqP == null && respP == null) { 266 if (debug != null) { 267 debug.println("no policy applies"); 268 } 269 return null; 270 } 271 272 274 ConfigFile.Entry[] entries = new Entry [idEntry.modules.size()]; 275 for (int i = 0; i < entries.length; i++) { 276 AppConfigurationEntry aEntry = 277 (AppConfigurationEntry )idEntry.modules.get(i); 278 entries[i] = new ConfigFile.Entry(reqP, 279 respP, 280 aEntry.getLoginModuleName(), 281 aEntry.getControlFlag(), 282 aEntry.getOptions()); 283 } 284 285 if (debug != null) { 286 debug.println("getEntries found " + 287 entries.length + 288 " entries for: " + 289 intercept + 290 " -- " 291 + id); 292 293 for (int i = 0; i < entries.length; i++) { 294 debug.println("Entry " + (i+1) + ":" + 295 "\n module class: " + entries[i].getLoginModuleName() + 296 "\n flag: " + entries[i].getControlFlag() + 297 "\n options: " + entries[i].getOptions() + 298 "\n request policy: " + entries[i].requestPolicy + 299 "\n response policy: " + entries[i].responsePolicy); 300 } 301 } 302 303 return entries; 304 } 305 306 311 private static ConfigParser loadParser(String className) 312 throws IOException { 313 try { 314 315 final String finalClassName = className; 316 final ClassLoader finalLoader = AuthConfig.getClassLoader(); 317 318 return (ConfigParser)java.security.AccessController.doPrivileged 319 (new java.security.PrivilegedExceptionAction () { 320 public Object run() throws Exception { 321 Class c = Class.forName(finalClassName,true,finalLoader); 322 return c.newInstance(); 323 } 324 }); 325 } catch (java.security.PrivilegedActionException pae) { 326 IOException iex = new IOException(pae.getException().toString()); 327 iex.initCause(pae.getException()); 328 throw iex; 329 } 330 } 331 332 335 private static CallbackHandler loadDefaultCallbackHandler() 336 throws AuthException { 337 338 try { 340 341 final ClassLoader finalLoader = AuthConfig.getClassLoader(); 342 343 return (CallbackHandler ) 344 java.security.AccessController.doPrivileged 345 (new java.security.PrivilegedExceptionAction () { 346 public Object run() throws Exception { 347 348 String className = 349 System.getProperty("configfile.handler"); 350 351 if (className == null || className.length() == 0) { 352 className = 353 java.security.Security.getProperty(DEFAULT_HANDLER); 354 355 if (className == null || className.length() == 0) { 356 return null; 357 } 358 } 359 360 Class c = Class.forName(className, 361 true, 362 finalLoader); 363 return c.newInstance(); 364 } 365 }); 366 } catch (java.security.PrivilegedActionException pae) { 367 AuthException aex = new AuthException(pae.getException().toString()); 368 aex.initCause(pae.getException()); 369 throw aex; 370 } 371 } 372 373 376 private static Object createModule(ConfigFile.Entry entry, 377 CallbackHandler handler) 378 throws AuthException { 379 try { 380 381 383 Object newModule = entry.newInstance(); 384 385 387 Object [] initArgs = { entry.getRequestPolicy(), 388 entry.getResponsePolicy(), 389 handler, 390 entry.getOptions() }; 391 392 boolean foundOne = false; 393 Method [] mArray = newModule.getClass().getMethods(); 394 for (int i = 0; i < mArray.length; i++) { 395 if (mArray[i].getName().equals(AuthContext.INIT)) { 396 mArray[i].invoke(newModule, initArgs); 397 foundOne = true; 398 break; 399 } 400 } 401 402 if (foundOne) { 403 return newModule; 405 } 406 407 throw new SecurityException ("could not find " + 408 AuthContext.INIT + 409 " method in module"); 410 411 } catch (Exception e) { 412 if (e instanceof AuthException) { 413 throw (AuthException)e; 414 } 415 AuthException ae = new AuthException(); 416 ae.initCause(e); 417 throw ae; 418 } 419 } 420 421 434 static class Entry extends javax.security.auth.login.AppConfigurationEntry { 435 436 private static final Class [] PARAMS = { }; 438 private static final Object [] ARGS = { }; 439 440 private AuthPolicy requestPolicy; 441 private AuthPolicy responsePolicy; 442 Object module; 445 464 Entry(AuthPolicy requestPolicy, 465 AuthPolicy responsePolicy, 466 String moduleClass, 467 AppConfigurationEntry.LoginModuleControlFlag flag, 468 Map options) { 469 super(moduleClass, flag, options); 470 this.requestPolicy = requestPolicy; 471 this.responsePolicy = responsePolicy; 472 } 473 474 479 AuthPolicy getRequestPolicy() { 480 return requestPolicy; 481 } 482 483 488 AuthPolicy getResponsePolicy() { 489 return responsePolicy; 490 } 491 492 504 Object newInstance() throws AuthException { 505 try { 506 final ClassLoader finalLoader= AuthConfig.getClassLoader(); 507 String clazz = getLoginModuleName(); 508 Class c = Class.forName(clazz, 509 true, 510 finalLoader); 511 java.lang.reflect.Constructor constructor = 512 c.getConstructor(PARAMS); 513 return constructor.newInstance(ARGS); 514 } catch (Exception e) { 515 AuthException ae = new AuthException(); 516 ae.initCause(e); 517 throw ae; 518 } 519 } 520 } 521 522 525 static class InterceptEntry { 526 527 String defaultClientID; 528 String defaultServerID; 529 HashMap idMap; 530 531 InterceptEntry(String defaultClientID, 532 String defaultServerID, 533 HashMap idMap) { 534 this.defaultClientID = defaultClientID; 535 this.defaultServerID = defaultServerID; 536 this.idMap = idMap; 537 } 538 } 539 540 543 static class IDEntry { 544 545 private String type; private AuthPolicy requestPolicy; 547 private AuthPolicy responsePolicy; 548 private ArrayList modules; 549 550 IDEntry(String type, 551 AuthPolicy requestPolicy, 552 AuthPolicy responsePolicy, 553 ArrayList modules) { 554 555 this.type = type; 556 this.modules = modules; 557 this.requestPolicy = requestPolicy; 558 this.responsePolicy = responsePolicy; 559 } 560 561 IDEntry(String type, 563 String requestPolicy, 564 String responsePolicy, 565 ArrayList modules) { 566 567 this.type = type; 568 569 if (requestPolicy != null) { 570 this.requestPolicy = 571 new AuthPolicy(AuthPolicy.SOURCE_AUTH_SENDER, 572 true, true); } 575 if (responsePolicy != null) { 576 this.responsePolicy = 577 new AuthPolicy(AuthPolicy.SOURCE_AUTH_CONTENT, 578 true, false); } 581 582 this.modules = modules; 583 } 584 } 585 586 589 private static class ConfigClient implements ClientAuthContext { 590 591 private AuthContext context; 593 594 private static final sun.security.util.Debug debug = 595 sun.security.util.Debug.getInstance("configclient", 596 "[ConfigClient]"); 597 598 ConfigClient(Entry [] entries) throws AuthException { 599 context = new AuthContext(entries, debug); 600 } 601 602 public void secureRequest(AuthParam param, 603 Subject subject, 604 Map sharedState) 605 throws AuthException { 606 607 Object [] args = { param, subject, sharedState }; 609 context.invoke(AuthContext.SECURE_REQUEST, args); 610 } 611 612 public void validateResponse(AuthParam param, 613 Subject subject, 614 Map sharedState) 615 throws AuthException { 616 Object [] args = { param, subject, sharedState }; 618 context.invoke(AuthContext.VALIDATE_RESPONSE, args); 619 } 620 621 public void disposeSubject(Subject subject, 622 Map sharedState) 623 throws AuthException { 624 Object [] args = { subject, sharedState }; 626 context.invoke(AuthContext.DISPOSE_SUBJECT, args); 627 } 628 } 629 630 633 private static class ConfigServer implements ServerAuthContext { 634 635 private AuthContext context; 637 638 private static final sun.security.util.Debug debug = 639 sun.security.util.Debug.getInstance("configserver", 640 "[ConfigServer]"); 641 642 ConfigServer(Entry [] entries) throws AuthException { 643 644 context = new AuthContext(entries, debug); 645 } 646 647 public void validateRequest(AuthParam param, 648 Subject subject, 649 Map sharedState) 650 throws AuthException { 651 Object [] args = { param, subject, sharedState }; 653 context.invoke(AuthContext.VALIDATE_REQUEST, args); 654 } 655 656 public void secureResponse(AuthParam param, 657 Subject subject, 658 Map sharedState) 659 throws AuthException { 660 Object [] args = { param, subject, sharedState }; 662 context.invoke(AuthContext.SECURE_RESPONSE, args); 663 } 664 665 public void disposeSubject(Subject subject, 666 Map sharedState) 667 throws AuthException { 668 Object [] args = { subject, sharedState }; 670 context.invoke(AuthContext.DISPOSE_SUBJECT, args); 671 } 672 673 public boolean managesSessions(Map sharedState) 674 throws AuthException { 675 676 Object [] args = { sharedState }; 678 Object [] rValues = null; 679 680 try { 681 rValues = context.invoke(AuthContext.MANAGES_SESSIONS, args); 682 } catch (AuthException ae) { 683 if (!(ae.getCause() instanceof NoSuchMethodException )) { 686 throw ae; 687 } 688 } 689 690 boolean rvalue = false; 691 692 for (int i=0; rValues != null && i<rValues.length; i++) { 693 if (rValues[i] != null) { 694 boolean thisValue = ((Boolean ) rValues[i]).booleanValue(); 695 rvalue = rvalue | thisValue; 696 } 697 } 698 699 return rvalue; 700 } 701 } 702 703 private class DelegatingHandler implements CallbackHandler { 704 705 CallbackHandler handler; 706 707 CallbackHandler defaultHandler; 708 709 private DelegatingHandler(CallbackHandler cbh) { 710 handler = cbh; 711 try { 712 defaultHandler = ConfigFile.loadDefaultCallbackHandler(); 713 } catch (Exception e) { 714 defaultHandler = null; 715 } 716 } 717 718 public void handle (Callback [] callbacks) 719 throws IOException, UnsupportedCallbackException { 720 if (defaultHandler == null) { 721 handler.handle(callbacks); 722 } 723 else { 724 Callback [] oneCallback = new Callback [1]; 725 for (int i=0; i<callbacks.length; i++) { 726 727 boolean tryDefault = false; 728 729 oneCallback[0] = callbacks[i]; 730 try { 731 handler.handle(oneCallback); 732 } catch (UnsupportedCallbackException uce) { 733 tryDefault = true; 734 } 735 if (tryDefault) { 736 defaultHandler.handle(oneCallback); 737 } 738 } 739 } 740 } 741 } 742 743 } 744 | Popular Tags |