1 23 24 package com.sun.enterprise.security.jauth; 25 26 import java.lang.reflect.Method ; 27 28 import java.util.Collection ; 29 import java.util.HashMap ; 30 import java.util.Iterator ; 31 import java.util.ArrayList ; 32 33 import javax.xml.XMLConstants ; 34 import javax.xml.namespace.QName ; 35 import javax.xml.soap.MimeHeaders ; 36 import javax.xml.soap.SOAPBody ; 37 import javax.xml.soap.SOAPException ; 38 import javax.xml.soap.SOAPElement ; 39 import javax.xml.soap.SOAPEnvelope ; 40 import javax.xml.soap.SOAPMessage ; 41 import javax.xml.soap.Name ; 42 import javax.xml.soap.SOAPPart ; 43 import javax.xml.ws.handler.MessageContext; 44 import javax.xml.ws.handler.soap.SOAPMessageContext; 45 46 import javax.security.auth.callback.CallbackHandler ; 47 48 import com.sun.enterprise.security.jauth.AuthConfig; 49 import com.sun.enterprise.security.jauth.AuthPolicy; 50 import com.sun.enterprise.security.jauth.ServerAuthContext; 51 import com.sun.enterprise.webservice.WsUtil; 52 53 import com.sun.enterprise.deployment.WebServiceEndpoint; 54 import com.sun.enterprise.deployment.MethodDescriptor; 55 import com.sun.enterprise.deployment.runtime.common.MessageDescriptor; 56 import com.sun.enterprise.deployment.runtime.common.MessageSecurityDescriptor; 57 import com.sun.enterprise.deployment.runtime.common.MessageSecurityBindingDescriptor; 58 import com.sun.enterprise.deployment.runtime.common.ProtectionDescriptor; 59 60 import com.sun.xml.rpc.spi.runtime.StreamingHandler; 61 62 import com.sun.xml.ws.spi.runtime.Invoker; 63 import com.sun.xml.ws.handler.SHDSOAPMessageContext; 64 65 import java.util.logging.Logger ; 66 import java.util.logging.Level ; 67 import com.sun.logging.LogDomains; 68 69 76 public class BaseAuthConfig { 77 78 private static Logger logger = LogDomains.getLogger(LogDomains.SECURITY_LOGGER); 79 80 private Object defaultContext_; 81 82 private MessageSecurityDescriptor superMSD_; 84 private int superIndex_; 85 86 private ArrayList contexts_; 87 88 private ArrayList messageSecurityDescriptors_; 89 90 private ArrayList contextsForOpcodes_; 91 92 private HashMap contextsForOpNames_; 93 94 private boolean onePolicy_; 95 96 private Object contextLock = new Object (); 97 98 private ExplicitNull explicitNull = new ExplicitNull(); 99 100 protected BaseAuthConfig(Object context) { 101 102 defaultContext_ = context; 103 superMSD_ = null; 104 superIndex_ = -1; 105 106 messageSecurityDescriptors_ = null; 107 contexts_ = null; 108 contextsForOpcodes_ = null; 109 contextsForOpNames_ = null; 110 111 onePolicy_ = true; 112 113 if(logger.isLoggable(Level.FINE)){ 114 logger.fine("WSS: New BAC defaultContext: " + defaultContext_); 115 } 116 } 117 118 protected BaseAuthConfig (ArrayList descriptors, ArrayList authContexts) { 119 120 defaultContext_ = null; 121 superMSD_ = null; 122 superIndex_ = -1; 123 124 messageSecurityDescriptors_ = descriptors; 125 contexts_ = authContexts; 126 contextsForOpcodes_ = null; 127 contextsForOpNames_ = null; 128 129 onePolicy_ = true; 130 131 for (int i = 0; i < descriptors.size(); i++) { 132 133 MessageSecurityDescriptor msd = 134 (MessageSecurityDescriptor) descriptors.get(i); 135 136 140 for (int j = 0; j < descriptors.size(); j++) { 141 if (j != i && !policiesAreEqual 142 (msd,((MessageSecurityDescriptor) descriptors.get(j)))) { 143 onePolicy_ = false; 144 } 145 } 146 } 147 148 for (int i = 0; defaultContext_ == null && i < descriptors.size(); i++) { 149 150 MessageSecurityDescriptor msd = (MessageSecurityDescriptor) descriptors.get(i); 151 152 AuthPolicy requestPolicy = 153 getAuthPolicy(msd.getRequestProtectionDescriptor()); 154 155 AuthPolicy responsePolicy = 156 getAuthPolicy(msd.getResponseProtectionDescriptor()); 157 158 boolean noProtection = (!requestPolicy.authRequired() && 159 !responsePolicy.authRequired()); 160 161 if (i==0 && onePolicy_ && noProtection) { 164 defaultContext_ = explicitNull; 165 break; 166 } 167 168 ArrayList mDs = msd.getMessageDescriptors(); 169 170 for (int j=0; mDs != null && j < mDs.size(); j++) { 171 172 MessageDescriptor mD = (MessageDescriptor) mDs.get(j); 173 MethodDescriptor methD = mD.getMethodDescriptor(); 174 175 if ((mD.getOperationName() == null && methD == null) || 177 (methD != null && methD.getStyle() == 1)) { 178 179 if (onePolicy_) { 180 defaultContext_ = contexts_.get(i); 182 if (defaultContext_ == null) { 183 defaultContext_ = explicitNull; 184 } 185 break; 186 } else if (superIndex_ == -1) { 187 if (noProtection) { 189 defaultContext_ = explicitNull; 190 } else { 191 superIndex_ = i; 192 } 193 } else if (!policiesAreEqual(msd,((MessageSecurityDescriptor) 194 descriptors.get(superIndex_)))) { 195 defaultContext_ = explicitNull; 198 superIndex_ = -1; 199 break; 200 } 201 } 202 } 203 } 204 if (superIndex_ >=0) { 208 superMSD_ = (MessageSecurityDescriptor) descriptors.get(superIndex_); 209 } 210 211 if(logger.isLoggable(Level.FINE)){ 212 logger.fine("WSS: new BAC defaultContext_: " + defaultContext_ + 213 " superMSD index: " + superIndex_ + " onePolicy_: " + onePolicy_); 214 } 215 } 216 217 protected static AuthPolicy getAuthPolicy(ProtectionDescriptor pd) { 218 int sourceAuthType = AuthPolicy.SOURCE_AUTH_NONE; 219 boolean recipientAuth = false; 220 boolean beforeContent = false; 221 if (pd != null) { 222 String source = pd.getAttributeValue 223 (ProtectionDescriptor.AUTH_SOURCE); 224 if (source != null) { 225 if (source.equals(AuthPolicy.SENDER)) { 226 sourceAuthType = AuthPolicy.SOURCE_AUTH_SENDER; 227 } else if (source.equals(AuthPolicy.CONTENT)) { 228 sourceAuthType = AuthPolicy.SOURCE_AUTH_CONTENT; 229 } 230 } 231 String recipient = pd.getAttributeValue 232 (ProtectionDescriptor.AUTH_RECIPIENT); 233 if (recipient != null) { 234 recipientAuth = true; 235 if (recipient.equals(AuthPolicy.BEFORE_CONTENT)) { 236 beforeContent = true; 237 } else if (recipient.equals(AuthPolicy.AFTER_CONTENT)) { 238 beforeContent = false; 239 } 240 } 241 } 242 return new AuthPolicy(sourceAuthType,recipientAuth,beforeContent); 243 } 244 245 private static boolean 246 isMatchingMSD(MethodDescriptor targetMD, MessageSecurityDescriptor mSD) { 247 ArrayList messageDescriptors = mSD.getMessageDescriptors(); 248 if (messageDescriptors.size() == 0) { 249 return true; 254 } 255 256 for (int i=0; i<messageDescriptors.size(); i++) { 257 MessageDescriptor nextMD = 258 (MessageDescriptor) messageDescriptors.get(i); 259 MethodDescriptor mD = nextMD.getMethodDescriptor(); 260 String opName = nextMD.getOperationName(); 261 262 if (opName == null && (mD == null || mD.implies(targetMD))){ 263 return true; 264 } 265 } 266 267 return false; 268 } 269 270 private static boolean 271 policiesAreEqual(MessageSecurityDescriptor reference, 272 MessageSecurityDescriptor other) { 273 if (!getAuthPolicy 274 (reference.getRequestProtectionDescriptor()).equals 275 (getAuthPolicy(other.getRequestProtectionDescriptor())) || 276 277 !getAuthPolicy 278 (reference.getResponseProtectionDescriptor()).equals 279 (getAuthPolicy(other.getResponseProtectionDescriptor()))) { 280 281 return false; 282 } 283 return true; 284 } 285 286 292 private Object getContextForMethod(Method m) { 293 Object rvalue = null; 294 synchronized(contextLock) { 295 if (defaultContext_ != null) { 296 rvalue = defaultContext_; 297 if(logger.isLoggable(Level.FINE)){ 298 logger.fine("WSS: ForMethod returning default_context: " + rvalue); 299 } 300 return rvalue; 301 } 302 } 303 if (m != null) { 304 int match = -1; 305 MethodDescriptor targetMD = new MethodDescriptor(m); 306 for (int i = 0; i < messageSecurityDescriptors_.size(); i++) { 307 if (isMatchingMSD(targetMD,(MessageSecurityDescriptor) 308 messageSecurityDescriptors_.get(i))) { 309 if (match < 0) { 310 match = i; 311 } else if (!policiesAreEqual 312 ((MessageSecurityDescriptor) 313 messageSecurityDescriptors_.get(match), 314 (MessageSecurityDescriptor) 315 messageSecurityDescriptors_.get(i))) { 316 317 319 rvalue = explicitNull; 320 match = -1; 321 if(logger.isLoggable(Level.FINE)){ 322 logger.fine("WSS: ForMethod detected conflicting policies: " + 323 match + "." + i); 324 } 325 break; 326 } 327 } 328 } 329 if (match >= 0) { 330 rvalue = contexts_.get(match); 331 if (rvalue == null) { 332 rvalue = explicitNull; 333 } 334 if(logger.isLoggable(Level.FINE)){ 335 logger.fine("WSS: ForMethod returning matched context: " + rvalue); 336 } 337 } 338 } else if (onePolicy_ && contexts_.size() > 0) { 339 350 rvalue = contexts_.get(0); 351 if(logger.isLoggable(Level.FINE)){ 352 logger.fine("WSS: ForMethod resorting to first context: " + rvalue); 353 } 354 355 } else { 356 if(logger.isLoggable(Level.FINE)){ 357 logger.fine("WSS: Unable to select policy for SOAP Message"); 358 } 359 throw new RuntimeException ("Unable to select policy for Message"); 360 } 361 return rvalue; 362 } 363 364 private boolean methodIsCovered(Method m) { 367 boolean rvalue = true; 368 if (messageSecurityDescriptors_ != null) { 369 MethodDescriptor targetMD = new MethodDescriptor(m); 370 for (int i = 0; i < messageSecurityDescriptors_.size(); i++) { 371 if (i == 0) { 372 rvalue = false; 373 } 374 if (isMatchingMSD(targetMD,(MessageSecurityDescriptor) 375 messageSecurityDescriptors_.get(i))) { 376 rvalue = true; 377 break; 378 } 379 } 380 } 381 return rvalue; 382 } 383 384 private Object getExplicitContextForOpCode(StreamingHandler handler, 385 int opcode) throws ClassNotFoundException , NoSuchMethodException { 386 387 Object rvalue = null; 388 389 synchronized(contextLock) { 390 391 if (contextsForOpcodes_ == null && defaultContext_ == null) { 392 393 395 boolean onePolicyForAll = onePolicy_; 396 397 Method m = null; 398 for (int i = 0; i == 0 || m != null; i++) { 399 if (i == 0) { 400 contextsForOpcodes_ = new ArrayList (); 401 } 402 if (handler != null) { 403 m = handler.getMethodForOpcode(i); 404 } 405 if (m != null) { 406 Object o = getContextForMethod(m); 407 contextsForOpcodes_.add(o); 408 409 415 if (o == null) { 416 onePolicyForAll = false; 417 } 418 } 419 } 420 if (onePolicyForAll && contextsForOpcodes_.size() > 0) { 421 defaultContext_ = contextsForOpcodes_.get(0); 422 } 423 } 424 if (defaultContext_ != null) { 425 rvalue = defaultContext_; 426 if(logger.isLoggable(Level.FINE)){ 427 logger.fine("WSS: ForOpCode returning default_context: " + rvalue); 428 } 429 } 430 } 431 432 if (rvalue == null) { 433 if (opcode >=0 && opcode < contextsForOpcodes_.size()) { 434 rvalue = contextsForOpcodes_.get(opcode); 435 } else if (opcode < 0) { 436 rvalue = getContextForMethod(null); 439 } 440 } 441 return rvalue; 442 } 443 444 protected Object getContextForOpCode(StreamingHandler handler, int opcode) 445 throws ClassNotFoundException , NoSuchMethodException { 446 Object rvalue = getExplicitContextForOpCode(handler,opcode); 447 if (rvalue != null && rvalue instanceof ExplicitNull) { 448 rvalue = null; 449 } 450 return rvalue; 451 } 452 453 private static String getOpName(SOAPMessage message) { 454 455 String rvalue = null; 456 457 460 MimeHeaders headers = message.getMimeHeaders(); 461 if (headers != null) { 462 String [] actions = headers.getHeader("SOAPAction"); 463 if (actions != null && actions.length > 0) { 464 rvalue = actions[0]; 465 if (rvalue != null && rvalue.equals("\"\"")) { 466 rvalue = null; 467 } 468 } 469 } 470 471 474 if (rvalue == null) { 475 Name name = getName(message); 476 if (name != null) { 477 rvalue = name.getLocalName(); 478 } 479 } 480 481 return rvalue; 482 } 483 484 private static String getOpName(SOAPMessageContext soapMC) { 485 486 String rvalue = null; 487 488 QName qName = (QName ) soapMC.get(MessageContext.WSDL_OPERATION); 490 if (qName != null) { 491 rvalue = qName.getLocalPart(); 492 } else { 493 rvalue = getOpName(WsUtil.getMessageWithName(soapMC)); 494 } 495 496 return rvalue; 497 } 498 499 private Object getContextForOpName(String operation) { 500 501 synchronized(contextLock) { 502 if (contextsForOpNames_ == null) { 503 504 506 contextsForOpNames_ = new HashMap (); 507 for (int i=0; messageSecurityDescriptors_ != null && 508 i < messageSecurityDescriptors_.size(); i++) { 509 510 MessageSecurityDescriptor mSD = (MessageSecurityDescriptor) 511 messageSecurityDescriptors_.get(i); 512 513 ArrayList mDs = mSD.getMessageDescriptors(); 514 515 for (int j=0; mDs != null && j < mDs.size(); j++) { 516 517 MessageDescriptor mD = (MessageDescriptor) mDs.get(j); 518 String opName = mD.getOperationName(); 519 520 if (opName != null) { 521 522 if (contextsForOpNames_.containsKey(opName)) { 523 524 Integer k = (Integer ) contextsForOpNames_.get(opName); 525 if (k != null) { 526 527 MessageSecurityDescriptor other = 528 (MessageSecurityDescriptor) 529 messageSecurityDescriptors_.get(k.intValue()); 530 531 533 if (!policiesAreEqual(mSD,other)) { 534 contextsForOpNames_.put(opName,null); 535 } 536 } 537 } else if (superMSD_!=null && !policiesAreEqual(mSD,superMSD_)){ 538 contextsForOpNames_.put(opName,null); 540 } else { 541 contextsForOpNames_.put(opName,new Integer (i)); 542 } 543 } 544 } 545 } 546 } 547 } 548 549 Object rvalue = null; 550 if (operation != null) { 551 if (contextsForOpNames_.containsKey(operation)) { 552 Integer k = (Integer ) contextsForOpNames_.get(operation); 553 if (k != null) { 554 rvalue = contexts_.get(k.intValue()); 555 } 556 } else if (superIndex_ >= 0) { 557 rvalue = contexts_.get(superIndex_); 560 } 561 562 if (rvalue == null) { 563 rvalue = explicitNull; 566 } 567 if (logger.isLoggable(Level.FINE)) { 568 logger.fine("WSS: ForOpName=" + operation + " context: " + rvalue); 569 } 570 } 571 return rvalue; 572 } 573 574 588 private Object getContextForMessage(SOAPMessage message) { 589 590 String opName = getOpName(message); 591 592 Object rvalue = getContextForOpName(opName); 593 if (rvalue == null) { 594 595 599 rvalue = getContextForMethod(null); 600 601 } 602 return rvalue; 603 } 604 605 protected Object getContext(StreamingHandler handler,SOAPMessage message){ 606 607 Object rvalue = null; 608 609 synchronized(contextLock) { 610 if (defaultContext_ != null) { 611 rvalue = defaultContext_; 612 } 613 } 614 615 if (rvalue == null) { 616 617 if (handler == null) { 618 619 622 rvalue = getContextForMessage(message); 623 624 } else { 625 626 int opCode = handler.getOpcodeForRequestMessage(message); 627 628 if (opCode == -1) { 629 630 633 rvalue = getContextForMethod(null); 634 635 } else { 636 637 try { 638 rvalue = getExplicitContextForOpCode(handler,opCode); 639 640 643 if (rvalue == null) { 644 645 rvalue = getContextForMessage(message); 646 647 } 648 } catch (ClassNotFoundException cnfe) { 649 throw new RuntimeException (cnfe); 650 } catch (NoSuchMethodException nsme) { 651 throw new RuntimeException (nsme); 652 } 653 } 654 } 655 } 656 657 if (rvalue != null && rvalue instanceof ExplicitNull) { 658 rvalue = null; 659 } 660 661 if(logger.isLoggable(Level.FINE)){ 662 logger.fine("WSS: getContext returning: " + rvalue); 663 } 664 665 return rvalue; 666 } 667 668 protected Object getContext(SOAPMessageContext soapMC) { 670 671 Object rvalue = null; 672 673 synchronized(contextLock) { 674 if (defaultContext_ != null) { 675 rvalue = defaultContext_; 676 } 677 } 678 679 if (rvalue == null) { 680 681 Method m = getMethod(soapMC); 682 String opName = null; 683 684 if (m != null) { 685 rvalue = getContextForMethod(m); 686 } 687 688 if (rvalue == null) { 689 opName = getOpName(soapMC); 690 if (opName != null) { 691 rvalue = getContextForOpName(opName); 692 } 693 } 694 695 if (rvalue == null && (m == null || opName == null)) { 696 697 700 rvalue = getContextForMethod(null); 701 } 702 } 703 704 if (rvalue != null && rvalue instanceof ExplicitNull) { 705 rvalue = null; 706 } 707 708 return rvalue; 709 } 710 711 private static Name getName(SOAPMessage message) { 712 Name rvalue = null; 713 SOAPPart soap = message.getSOAPPart(); 714 if (soap != null) { 715 try { 716 SOAPEnvelope envelope = soap.getEnvelope(); 717 if (envelope != null) { 718 SOAPBody body = envelope.getBody(); 719 if (body != null) { 720 Iterator it = body.getChildElements(); 721 while (it.hasNext()) { 722 Object o = it.next(); 723 if (o instanceof SOAPElement ) { 724 rvalue = ((SOAPElement ) o).getElementName(); 725 break; 726 } 727 } 728 } 729 } 730 } catch (SOAPException se) { 731 if(logger.isLoggable(Level.FINE)){ 732 logger.log(Level.FINE,"WSS: Unable to get SOAP envelope", 733 se); 734 } 735 } 736 } 737 738 return rvalue; 739 } 740 741 public static Method getMethod(SOAPMessageContext soapMC) { 742 743 Method m = null; 744 745 if (soapMC instanceof SHDSOAPMessageContext) { 746 747 m = ((SHDSOAPMessageContext)soapMC).getMethod(); 748 749 if (m == null) { 750 751 QName qName = (QName ) 752 soapMC.get(MessageContext.WSDL_OPERATION); 753 754 if (qName == null) { 755 756 Name name = getName(WsUtil.getMessageWithName(soapMC)); 757 758 if (name != null) { 759 760 String prefix = name.getPrefix(); 761 762 qName = new QName 763 (name.getURI(), name.getLocalName(), 764 (prefix != null ? prefix : 765 XMLConstants.DEFAULT_NS_PREFIX)) ; 766 } 767 } 768 if (qName != null) { 769 Invoker invoker = 770 ((SHDSOAPMessageContext)soapMC).getInvoker(); 771 m = invoker.getMethod(qName); 772 } 773 } 774 } 775 return m; 776 } 777 778 782 public QName [] getMechanisms() { 786 return mechanisms; 787 } 788 789 private static QName mechanisms[] = new QName [] { 791 new QName ( "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security", "wsse") }; 792 793 796 class ExplicitNull { 797 798 ExplicitNull() { 799 } 800 801 public boolean equals(Object other) { 802 return (other != null && other instanceof ExplicitNull ? true : false); 803 } 804 805 public String toString() { 806 return "ExplicitNull"; 807 } 808 } 809 } 810 | Popular Tags |