1 23 24 package com.sun.enterprise.iiop.security; 25 26 36 37 import org.omg.CORBA.*; 38 import org.omg.PortableInterceptor.*; 39 import org.omg.IOP.*; 40 41 import java.util.*; 42 import java.security.cert.X509Certificate ; 43 44 45 import com.sun.corba.ee.org.omg.CSI.*; 46 import com.sun.corba.ee.org.omg.GSSUP.*; 47 48 49 import sun.security.util.DerInputStream; 50 import sun.security.util.DerOutputStream; 51 import sun.security.util.DerValue; 52 53 import sun.security.x509.*; import javax.security.auth.*; 56 import com.sun.enterprise.security.auth.login.PasswordCredential; 57 import com.sun.enterprise.security.auth.login.X509CertificateCredential; 58 import com.sun.enterprise.util.ORBManager; 59 import com.sun.enterprise.util.LocalStringManagerImpl; 60 import com.sun.enterprise.log.Log; 61 import java.util.logging.*; 62 import com.sun.logging.*; 63 66 67 public class SecServerRequestInterceptor 68 extends org.omg.CORBA.LocalObject 69 implements ServerRequestInterceptor 70 { 71 72 private static java.util.logging.Logger _logger=null; 73 static{ 74 _logger=LogDomains.getLogger(LogDomains.CORBA_LOGGER); 75 } 76 private static LocalStringManagerImpl localStrings = 77 new LocalStringManagerImpl(SecServerRequestInterceptor.class); 78 private InheritableThreadLocal counterForCalls = new InheritableThreadLocal (); 79 80 85 protected static final int SECURITY_ATTRIBUTE_SERVICE_ID = 15; 86 private static final int INVALID_MECHANISM_MAJOR = 2; 88 private static final int INVALID_MECHANISM_MINOR = 1; 89 90 91 private static final boolean NO_REPLACE = false; 92 93 94 private String prname; 95 private String name; 96 private Codec codec; 97 private ORB orb; 98 SecurityService secsvc = null; 100 101 public SecServerRequestInterceptor( String name, Codec codec) { 102 this.name = name; 103 this.codec = codec; 104 this.prname = name + "::"; 105 } 106 107 public String name() { 108 return name; 109 } 110 111 115 116 117 private SASContextBody createContextError(int status) { 118 124 125 return createContextError(1, status); 126 } 127 128 130 private SASContextBody createContextError(int major, int minor) { 131 132 if(_logger.isLoggable(Level.FINE)) { 133 _logger.log(Level.FINE,"Creating ContextError message: major code = "+ major+ "minor code= "+ minor); 134 } 135 byte error_token[] = {} ; 136 ContextError ce = new ContextError(0, 137 major, minor, error_token); 140 SASContextBody sasctxtbody = new SASContextBody(); 141 sasctxtbody.error_msg(ce); 142 return sasctxtbody; 143 } 144 145 149 private SASContextBody createCompleteEstablishContext(int status) { 150 156 if(_logger.isLoggable(Level.FINE)){ 157 _logger.log(Level.FINE,"Creating CompleteEstablishContext message"); 158 } 159 byte[] final_context_token = {} ; 160 CompleteEstablishContext cec = new CompleteEstablishContext( 161 0, false, final_context_token); 164 SASContextBody sasctxtbody = new SASContextBody(); 165 sasctxtbody.complete_msg(cec); 166 return sasctxtbody; 167 } 168 169 173 private ServiceContext createSvcContext(SASContextBody sasctxtbody) { 174 175 ServiceContext sc = null; 176 177 Any a = orb.create_any(); 178 SASContextBodyHelper.insert(a, sasctxtbody); 179 180 byte[] cdr_encoded_saselm = {}; 181 try { 182 cdr_encoded_saselm = codec.encode_value(a); 183 } catch (Exception e) { 184 _logger.log(Level.SEVERE,"iiop.encode_exception",e); 185 } 186 sc = new ServiceContext(); 187 sc.context_id = SECURITY_ATTRIBUTE_SERVICE_ID; 188 sc.context_data = cdr_encoded_saselm; 189 return sc; 190 191 } 192 193 200 private void createIdCred(SecurityContext sc, IdentityToken idtok) 201 throws Exception { 202 203 byte[] derenc ; Any any; 206 switch (idtok.discriminator()) { 207 208 case ITTAbsent.value: 209 if(_logger.isLoggable(Level.FINE)){ 210 _logger.log(Level.FINE,"Identity token type is Absent"); 211 } 212 sc.identcls = null; 213 break; 214 215 case ITTAnonymous.value: 216 if(_logger.isLoggable(Level.FINE)){ 217 _logger.log(Level.FINE,"Identity token type is Anonymous"); 218 _logger.log(Level.FINE,"Adding AnonyCredential to subject's PublicCredentials"); 219 } 220 sc.subject.getPublicCredentials().add(new AnonCredential()); 221 sc.identcls = AnonCredential.class; 222 break; 223 224 case ITTDistinguishedName.value: 225 226 227 derenc = idtok.dn(); 228 229 if (isCDR(derenc)) { 230 any = codec.decode_value(derenc, X501DistinguishedNameHelper.type()); 231 232 233 derenc = X501DistinguishedNameHelper.extract(any); 234 } 235 if(_logger.isLoggable(Level.FINE)){ 236 _logger.log(Level.FINE,"Create an X500Name object from identity token"); 237 } 238 X500Name name = new X500Name(derenc); 239 if(_logger.isLoggable(Level.FINE)) { 240 _logger.log(Level.FINE,"Identity to be asserted is " + name.toString()); 241 _logger.log(Level.FINE,"Adding X500Name to subject's PublicCredentials"); 242 } 243 sc.subject.getPublicCredentials().add(name); 244 sc.identcls = X500Name.class; 245 break; 246 247 case ITTX509CertChain.value: 248 249 if(_logger.isLoggable(Level.FINE)){ 250 _logger.log(Level.FINE,"Identity token type is a X509 Certificate Chain"); 251 } 252 derenc = idtok.certificate_chain(); 253 254 if (isCDR(derenc)) { 255 256 any = codec.decode_value(derenc, X509CertificateChainHelper.type()); 257 258 259 derenc = X509CertificateChainHelper.extract(any); 260 } 261 262 DerInputStream din = new DerInputStream(derenc); 263 264 268 DerValue[] derval = din.getSequence(1); 269 X509Certificate [] certchain = 270 new X509CertImpl[derval.length]; 271 277 if(_logger.isLoggable(Level.FINE)){ 278 _logger.log(Level.FINE,"Contents of X509 Certificate chain:"); 279 } 280 for (int i = 0; i < certchain.length; i++) { 281 certchain[i] = new X509CertImpl(derval[i]); 282 if(_logger.isLoggable(Level.FINE)){ 283 _logger.log(Level.FINE," " + certchain[i].getSubjectDN().getName()); 284 } 285 } 286 if(_logger.isLoggable(Level.FINE)){ 287 _logger.log(Level.FINE,"Creating a X509CertificateCredential object from certchain"); 288 } 289 294 X509CertificateCredential cred = 295 new X509CertificateCredential(certchain, certchain[0].getSubjectDN().getName(), "default"); 296 if(_logger.isLoggable(Level.FINE)){ 297 _logger.log(Level.FINE,"Adding X509CertificateCredential to subject's PublicCredentials"); 298 } 299 sc.subject.getPublicCredentials().add(cred); 300 sc.identcls = X509CertificateCredential.class; 301 break; 302 303 case ITTPrincipalName.value: 304 if(_logger.isLoggable(Level.FINE)){ 305 _logger.log(Level.FINE,"Identity token type is GSS Exported Name"); 306 } 307 byte[] expname = idtok.principal_name(); 308 309 if (isCDR(expname)) { 310 311 any = codec.decode_value(expname, GSS_NT_ExportedNameHelper.type()); 312 313 expname = GSS_NT_ExportedNameHelper.extract(any); 314 } 315 if ( ! GSSUtils.verifyMechOID(GSSUtils.GSSUP_MECH_OID, expname)) { 316 throw new SecurityException ( 317 localStrings.getLocalString("secserverreqinterceptor.err_unknown_idassert_type", 318 "Unknown identity assertion type.")); 319 } 320 321 GSSUPName gssname = new GSSUPName(expname); 322 323 sc.subject.getPublicCredentials().add(gssname); 324 sc.identcls = GSSUPName.class; 325 _logger.log(Level.FINE,"Adding GSSUPName credential to subject"); 326 break; 327 328 default: 329 _logger.log(Level.SEVERE,"iiop.unknown_identity"); 330 throw new SecurityException ( 331 localStrings.getLocalString("secserverreqinterceptor.err_unknown_idassert_type", 332 "Unknown identity assertion type.")); 333 } 334 } 335 336 341 private boolean isCDR(byte[] bytes) { 342 return (bytes != null && bytes.length > 0 && 343 (bytes[0] == 0x0 || bytes[0] == 0x1)); 344 } 345 346 355 private void createAuthCred(SecurityContext sc, byte[] authtok) throws Exception 356 { 357 _logger.log(Level.FINE,"Constructing a PasswordCredential from client authentication token"); 358 359 GSSUPToken tok = GSSUPToken.getServerSideInstance(orb, codec, authtok); 360 361 final PasswordCredential pwdcred = tok.getPwdcred(); 362 final SecurityContext fsc = sc; 363 if(_logger.isLoggable(Level.FINE)) { 364 _logger.log(Level.FINE,"Password credential = " + pwdcred.toString()); 365 _logger.log(Level.FINE,"Adding PasswordCredential to subject's PrivateCredentials"); 366 } 367 java.security.AccessController.doPrivileged(new java.security.PrivilegedAction () { 368 public java.lang.Object run() { 369 fsc.subject.getPrivateCredentials().add(pwdcred); 370 return null; 371 } 372 }); 373 sc = fsc; 374 sc.authcls = PasswordCredential.class; 375 } 376 377 public void receive_request(ServerRequestInfo ri) 378 throws ForwardRequest 379 { 380 SecurityContext seccontext = null; ServiceContext sc = null; int status = 0; 383 boolean raise_no_perm = false; 384 385 if (_logger.isLoggable(Level.FINE)) { 386 _logger.log(Level.FINE, "++++ Entered " + prname + "receive_request"); 387 } 388 389 secsvc = Csiv2Manager.getSecurityService(); 390 orb = ORBManager.getORB(); 391 392 401 402 try { 403 sc = ri.get_request_service_context(SECURITY_ATTRIBUTE_SERVICE_ID); 404 } catch (org.omg.CORBA.BAD_PARAM e) { 405 if(_logger.isLoggable(Level.FINE)){ 406 _logger.log(Level.FINE,"No SAS context element found in service context list"); 407 } 408 int secStatus = secsvc.setSecurityContext(null, ri.object_id(), 409 ri.operation()); 410 411 if (secStatus == SecurityService.STATUS_FAILED){ 412 SASContextBody sasctxbody = createContextError(INVALID_MECHANISM_MAJOR, 413 INVALID_MECHANISM_MINOR); 414 sc = createSvcContext(sasctxbody); 415 ri.add_reply_service_context(sc, NO_REPLACE); 416 if(_logger.isLoggable(Level.FINE)) { 417 _logger.log(Level.FINE, 418 "SecServerRequestInterceptor.receive_request: NO_PERMISSION"); 419 } 420 throw new NO_PERMISSION(); 421 } 422 return; 423 } 424 425 if(_logger.isLoggable(Level.FINE)){ 426 _logger.log(Level.FINE,"Received a non null SAS context element"); 427 } 428 429 Any SasAny = orb.create_any(); 430 try { 431 SasAny = codec.decode_value(sc.context_data, SASContextBodyHelper.type()); 432 } catch (Exception e) { 433 _logger.log(Level.SEVERE,"iiop.decode_exception",e); 434 throw new SecurityException ( 435 localStrings.getLocalString("secserverreqinterceptor.err_cdr_decode", 436 "CDR Decoding error for SAS context element.")); 437 } 438 439 if(_logger.isLoggable(Level.FINE)){ 440 _logger.log(Level.FINE,"Successfully decoded CDR encoded SAS context element."); 441 } 442 SASContextBody sasctxbody = SASContextBodyHelper.extract(SasAny); 443 444 short sasdiscr = sasctxbody.discriminator(); 445 if(_logger.isLoggable(Level.FINE)){ 446 _logger.log(Level.FINE,"SAS context element is a/an " + SvcContextUtils.getMsgname(sasdiscr)+ " message"); 447 } 448 449 450 462 463 if (sasdiscr == MTMessageInContext.value) { 464 sasctxbody = createContextError(SvcContextUtils.MessageInContextMinor); 465 sc = createSvcContext(sasctxbody); 466 if(_logger.isLoggable(Level.FINE)){ 467 _logger.log(Level.FINE,"Adding ContextError message to service context list"); 468 _logger.log(Level.FINE,"SecurityContext set to null"); 469 } 470 ri.add_reply_service_context(sc, NO_REPLACE); 471 474 throw new NO_PERMISSION(); 475 } 476 477 487 488 if (sasdiscr != MTEstablishContext.value) { 489 _logger.log(Level.SEVERE,"iiop.not_establishcontext_msg"); 490 throw new SecurityException ( 491 localStrings.getLocalString("secserverreqinterceptor.err_not_ec_msg", 492 "Received message not an EstablishContext message.")); 493 } 494 495 EstablishContext ec = sasctxbody.establish_msg(); 496 497 seccontext = new SecurityContext(); 498 seccontext.subject = new Subject(); 499 500 try { 501 if (ec.client_authentication_token.length != 0) { 502 if(_logger.isLoggable(Level.FINE)){ 503 _logger.log(Level.FINE,"Message contains Client Authentication Token"); 504 } 505 createAuthCred(seccontext, ec.client_authentication_token); 506 } 507 } catch (Exception e) { 508 _logger.log(Level.SEVERE,"iiop.authentication_exception",e); 509 throw new SecurityException ( 510 localStrings.getLocalString("secsercverreqinterceptor.err_cred_create", 511 "Error while creating a JAAS subject credential.")); 512 513 514 } 515 516 try{ 517 if (ec.identity_token != null) { 518 if(_logger.isLoggable(Level.FINE)){ 519 _logger.log(Level.FINE,"Message contains an Identity Token"); 520 } 521 createIdCred(seccontext, ec.identity_token); 522 } 523 } catch (SecurityException secex){ 524 _logger.log(Level.SEVERE,"iiop.security_exception",secex); 525 sasctxbody = createContextError(INVALID_MECHANISM_MAJOR, 526 INVALID_MECHANISM_MINOR); 527 sc = createSvcContext(sasctxbody); 528 ri.add_reply_service_context(sc, NO_REPLACE); 529 throw new NO_PERMISSION(); 530 } catch (Exception e) { 531 _logger.log(Level.SEVERE,"iiop.generic_exception",e); 532 throw new SecurityException ( 533 localStrings.getLocalString("secsercverreqinterceptor.err_cred_create", 534 "Error while creating a JAAS subject credential.")); 535 536 } 537 538 if(_logger.isLoggable(Level.FINE)){ 539 _logger.log(Level.FINE,"Invoking setSecurityContext() to set security context"); 540 } 541 status = secsvc.setSecurityContext(seccontext, ri.object_id(), ri.operation()); 542 if(_logger.isLoggable(Level.FINE)){ 543 _logger.log(Level.FINE,"setSecurityContext() returned status code " + status); 544 } 545 554 if (status == SecurityService.STATUS_FAILED) { 555 if(_logger.isLoggable(Level.FINE)){ 556 _logger.log(Level.FINE,"setSecurityContext() returned STATUS_FAILED"); 557 } 558 sasctxbody = createContextError(status); 559 sc = createSvcContext(sasctxbody); 560 if(_logger.isLoggable(Level.FINE)){ 561 _logger.log(Level.FINE,"Adding ContextError message to service context list"); 562 } 563 ri.add_reply_service_context(sc, NO_REPLACE); 564 throw new NO_PERMISSION(); 565 } 566 567 if(_logger.isLoggable(Level.FINE)){ 568 _logger.log(Level.FINE,"setSecurityContext() returned SUCCESS"); 569 } 570 sasctxbody = createCompleteEstablishContext(status); 571 sc = createSvcContext(sasctxbody); 572 if(_logger.isLoggable(Level.FINE)){ 573 _logger.log(Level.FINE,"Adding CompleteEstablisContext message to service context list"); 574 } 575 ri.add_reply_service_context(sc, NO_REPLACE); 576 } 577 578 583 public void receive_request_service_contexts(ServerRequestInfo ri) 584 throws ForwardRequest 585 { 586 Counter cntr = (Counter)counterForCalls.get(); 591 if (cntr == null){ 592 cntr = new Counter(); 593 counterForCalls.set(cntr); 594 } 595 if (cntr.count == 0){ 596 SecurityService secsvc = Csiv2Manager.getSecurityService(); 597 secsvc.unsetSecurityContext(); 598 } 599 cntr.increment(); 600 } 601 602 public void send_reply(ServerRequestInfo ri) 603 { 604 unsetSecurityContext(); 605 } 606 607 public void send_exception(ServerRequestInfo ri) 608 throws ForwardRequest 609 { 610 unsetSecurityContext(); 611 } 612 613 public void send_other(ServerRequestInfo ri) 614 throws ForwardRequest 615 { 616 unsetSecurityContext(); 617 } 618 619 public void destroy() 620 { 621 } 622 623 private void unsetSecurityContext(){ 624 Counter cntr = (Counter)counterForCalls.get(); 625 if (cntr == null){ cntr = new Counter(1); 627 } 628 cntr.decrement(); 629 if (cntr.count == 0){ 630 SecurityService secsvc = Csiv2Manager.getSecurityService(); 631 secsvc.unsetSecurityContext(); 632 } 633 } 634 } 635 636 class Counter { 637 638 public int count = 0; 639 public Counter(int count){ 640 this.count = count; 641 } 642 public Counter(){ 643 count = 0; 644 } 645 public void setCount(int counter){ 646 count = counter; 647 } 648 public void increment(){ 649 count++; 650 } 651 public void decrement(){ 652 count--; 653 } 654 public String display(){ 655 return " Counter = " +count; 656 } 657 } 658 | Popular Tags |