1 package org.jacorb.security.sas; 2 3 22 23 import java.util.Hashtable ; 24 25 import org.apache.avalon.framework.configuration.Configurable; 26 import org.apache.avalon.framework.configuration.Configuration; 27 import org.apache.avalon.framework.configuration.ConfigurationException; 28 import org.apache.avalon.framework.logger.Logger; 29 import org.jacorb.orb.MinorCodes; 30 import org.jacorb.orb.giop.GIOPConnection; 31 import org.jacorb.orb.portableInterceptor.ServerRequestInfoImpl; 32 import org.jacorb.sasPolicy.ATLASPolicy; 33 import org.jacorb.sasPolicy.ATLASPolicyValues; 34 import org.jacorb.sasPolicy.ATLAS_POLICY_TYPE; 35 import org.jacorb.sasPolicy.SASPolicy; 36 import org.jacorb.sasPolicy.SASPolicyValues; 37 import org.jacorb.sasPolicy.SAS_POLICY_TYPE; 38 import org.omg.CORBA.Any ; 39 import org.omg.CORBA.BAD_PARAM ; 40 import org.omg.CORBA.CompletionStatus ; 41 import org.omg.CORBA.portable.ObjectImpl ; 42 import org.omg.CSI.CompleteEstablishContext; 43 import org.omg.CSI.ContextError; 44 import org.omg.CSI.EstablishContext; 45 import org.omg.CSI.MTEstablishContext; 46 import org.omg.CSI.MTMessageInContext; 47 import org.omg.CSI.MessageInContext; 48 import org.omg.CSI.SASContextBody; 49 import org.omg.CSI.SASContextBodyHelper; 50 import org.omg.IOP.Codec ; 51 import org.omg.IOP.ENCODING_CDR_ENCAPS ; 52 import org.omg.IOP.Encoding ; 53 import org.omg.IOP.ServiceContext ; 54 import org.omg.IOP.CodecFactoryPackage.UnknownEncoding ; 55 import org.omg.PortableInterceptor.ForwardRequest ; 56 import org.omg.PortableInterceptor.ORBInitInfo ; 57 import org.omg.PortableInterceptor.ServerRequestInfo ; 58 import org.omg.PortableInterceptor.ServerRequestInterceptor ; 59 import org.omg.CORBA.Policy ; 60 61 67 68 public class SASTargetInterceptor 69 extends org.omg.CORBA.LocalObject 70 implements ServerRequestInterceptor , Configurable 71 { 72 private static final String name = "SASTargetInterceptor"; 73 74 private Logger logger = null; 75 76 protected org.jacorb.orb.ORB orb = null; 77 protected Codec codec = null; 78 79 protected int sasReplySlotID = -1; 80 protected int clientUserNameSlotID = -1; 81 protected int sasContextsCubby = -1; 82 83 protected boolean useSsl = false; 84 protected ISASContext sasContext = null; 85 86 87 public SASTargetInterceptor(ORBInitInfo info) 88 throws UnknownEncoding , ConfigurationException 89 { 90 sasReplySlotID = info.allocate_slot_id(); 91 sasContextsCubby = org.jacorb.orb.giop.GIOPConnection.allocate_cubby_id(); 92 Encoding encoding = 93 new Encoding (ENCODING_CDR_ENCAPS.value, (byte) 1, (byte) 0); 94 codec = 95 info.codec_factory().create_codec(encoding); 96 97 orb = ((org.jacorb.orb.portableInterceptor.ORBInitInfoImpl)info).getORB (); 98 configure( orb.getConfiguration()); 99 } 100 101 public void configure(Configuration configuration) 102 throws ConfigurationException 103 { 104 logger = 105 ((org.jacorb.config.Configuration)configuration).getNamedLogger("jacorb.security.sas.TSS"); 106 107 useSsl = 108 configuration.getAttribute("jacorb.security.sas.tss.requires_sas","false").equals("true"); 109 110 String contextClass = null; 111 try 112 { 113 contextClass = configuration.getAttribute("jacorb.security.sas.contextClass"); 114 Class c = 115 org.jacorb.util.ObjectUtil.classForName(contextClass); 116 sasContext = (ISASContext)c.newInstance(); 117 } 118 catch(ConfigurationException ce) 119 { 120 if (logger.isDebugEnabled()) 121 logger.debug("ConfigurationException", ce); 122 } 123 catch (Exception e) 124 { 125 if (logger.isErrorEnabled()) 126 logger.error("Could not instantiate class " + contextClass + ": " + e); 127 } 128 129 if (sasContext == null) 130 { 131 if (logger.isErrorEnabled()) 132 logger.error("Could not load SAS context class: "+ contextClass); 133 } 134 else 135 { 136 sasContext.configure(configuration); 137 sasContext.initTarget(); 138 } 139 } 140 141 public String name() 142 { 143 return name; 144 } 145 146 public void destroy() 147 { 148 } 149 150 public void receive_request_service_contexts( ServerRequestInfo ri ) 151 throws ForwardRequest 152 { 153 if (logger.isDebugEnabled()) 154 logger.debug("receive_request_service_contexts for " + ri.operation()); 155 156 Policy targetSasPolicy = null; 158 try { 159 targetSasPolicy = ri.get_server_policy(SAS_POLICY_TYPE.value); 160 } 161 catch(Exception ex) { 162 } 163 164 if( targetSasPolicy == null ) { 165 return; 168 } 169 170 if (sasContext == null) 171 return; 172 173 GIOPConnection connection = 174 ((ServerRequestInfoImpl) ri).request.getConnection(); 175 176 if (useSsl && !connection.isSSL()) 178 { 179 if (logger.isErrorEnabled()) 180 logger.error("SSL required for operation " + ri.operation()); 181 throw new org.omg.CORBA.NO_PERMISSION ("SSL Required!", 182 MinorCodes.SAS_TSS_FAILURE, 183 CompletionStatus.COMPLETED_NO); 184 } 185 186 SASContextBody contextBody = null; 188 long client_context_id = 0; 189 byte[] contextToken = null; 190 try 191 { 192 ServiceContext ctx = 193 ri.get_request_service_context(SASInitializer.SecurityAttributeService); 194 Any ctx_any = 195 codec.decode_value( ctx.context_data, SASContextBodyHelper.type() ); 196 contextBody = SASContextBodyHelper.extract(ctx_any); 197 } 198 catch (BAD_PARAM e) 199 { 200 } 201 catch (Exception e) 202 { 203 if (logger.isWarnEnabled()) 204 logger.warn("Could not parse service context: ", e); 205 makeContextError(ri, client_context_id, 1, 1, new byte[0]); 206 throw new org.omg.CORBA.NO_PERMISSION ("Could not parse service context: " + 207 e, 208 MinorCodes.SAS_TSS_FAILURE, 209 CompletionStatus.COMPLETED_NO); 210 } 211 if (contextBody == null) 212 return; 213 214 if (contextBody.discriminator() == MTMessageInContext.value) 216 { 217 MessageInContext msg = null; 218 try 219 { 220 msg = contextBody.in_context_msg(); 221 client_context_id = msg.client_context_id; 222 contextToken = getSASContext(connection, msg.client_context_id); 223 } 224 catch (Exception e) 225 { 226 if (logger.isErrorEnabled()) 227 logger.error("Could not parse service MessageInContext " + 228 ri.operation() + ": " + e); 229 makeContextError(ri, client_context_id, 1, 1, new byte[0]); 230 throw new org.omg.CORBA.NO_PERMISSION ("SAS Error parsing MessageInContext: " + 231 e, 232 MinorCodes.SAS_TSS_FAILURE, 233 CompletionStatus.COMPLETED_NO); 234 } 235 if (contextToken == null) 236 { 237 if (logger.isErrorEnabled()) 238 logger.error("Invalid context in MessageInContext " + 239 ri.operation() + ": " + msg.client_context_id); 240 241 makeContextError(ri, client_context_id, 2, 1, new byte[0]); 242 throw new org.omg.CORBA.NO_PERMISSION ("SAS Invalid context in MessageInContext", 243 MinorCodes.SAS_TSS_FAILURE, 244 CompletionStatus.COMPLETED_NO); 245 } 246 } 247 248 String principalName = null; 250 if (contextBody.discriminator() == MTEstablishContext.value) 251 { 252 EstablishContext msg = null; 253 try 254 { 255 msg = contextBody.establish_msg(); 256 client_context_id = msg.client_context_id; 257 contextToken = msg.client_authentication_token; 258 259 if (!sasContext.validateContext(orb, codec, contextToken)) { 260 logger.info("Could not validate context EstablishContext " + ri.operation()); 261 makeContextError(ri, client_context_id, 1, 1, contextToken); 262 throw new org.omg.CORBA.NO_PERMISSION ("SAS Error validating context", 263 MinorCodes.SAS_TSS_FAILURE, 264 CompletionStatus.COMPLETED_NO); 265 } 266 principalName = sasContext.getValidatedPrincipal(); 267 } 268 catch (org.omg.CORBA.NO_PERMISSION e) 269 { 270 if (logger.isErrorEnabled()) 271 logger.error("Err " + ri.operation() + ": " + e); 272 makeContextError(ri, client_context_id, 1, 1, contextToken); 273 throw e; 274 } 275 catch (Exception e) 276 { 277 if (logger.isErrorEnabled()) 278 logger.error("Could not parse service EstablishContext " + 279 ri.operation() + ": " + e); 280 makeContextError(ri, client_context_id, 1, 1, contextToken); 281 throw new org.omg.CORBA.NO_PERMISSION ("SAS Error parsing EstablishContext: " + 282 e, MinorCodes.SAS_TSS_FAILURE, 283 CompletionStatus.COMPLETED_NO); 284 } 285 if (contextToken == null) 286 { 287 if (logger.isErrorEnabled()) 288 logger.error("Could not parse service EstablishContext " + 289 ri.operation() + ": " + msg.client_context_id); 290 makeContextError(ri, client_context_id, 1, 1, contextToken); 291 throw new org.omg.CORBA.NO_PERMISSION ("SAS Error parsing EstablishContext", 292 MinorCodes.SAS_TSS_FAILURE, 293 CompletionStatus.COMPLETED_NO); 294 } 295 } 296 297 try 299 { 300 Any nameAny = orb.create_any(); 301 if (principalName == null) 302 principalName = 303 getSASContextPrincipalName(connection, client_context_id); 304 305 nameAny.insert_string(principalName); 306 ri.set_slot( SASInitializer.sasPrincipalNamePIC, nameAny); 307 } 308 catch (Exception e) 309 { 310 if (logger.isErrorEnabled()) 311 logger.error("Error inserting service context into slots for " + 312 ri.operation() + ": " + e); 313 makeContextError(ri, client_context_id, 1, 1, contextToken); 314 throw new org.omg.CORBA.NO_PERMISSION ("SAS Error insert service context into slots: " + e, 315 MinorCodes.SAS_TSS_FAILURE, 316 CompletionStatus.COMPLETED_NO); 317 } 318 } 319 320 public void receive_request( ServerRequestInfo ri ) 321 throws ForwardRequest 322 { 323 if (logger.isDebugEnabled()) 324 logger.debug("receive_request for "+ri.operation()); 325 326 if (sasContext == null) 327 return; 328 GIOPConnection connection = 329 ((ServerRequestInfoImpl) ri).request.getConnection(); 330 331 SASPolicyValues sasValues = null; 333 try 334 { 335 ObjectImpl oi = 336 (ObjectImpl )((ServerRequestInfoImpl) ri).target(); 337 org.jacorb.orb.Delegate d = 338 (org.jacorb.orb.Delegate)oi._get_delegate(); 339 SASPolicy policy = 340 (SASPolicy)d.getPOA().getPolicy(SAS_POLICY_TYPE.value); 341 if (policy != null) 342 sasValues = policy.value(); 343 } 344 catch (BAD_PARAM e) 345 { 346 if (logger.isDebugEnabled()) 347 logger.debug("No SAS Policy for "+ri.operation()); 348 } 349 catch (Exception e) 350 { 351 if (logger.isWarnEnabled()) 352 logger.warn("Error fetching SAS policy for "+ 353 ri.operation()+": "+e); 354 throw new org.omg.CORBA.NO_PERMISSION ("Error fetching SAS policy: "+e, 355 MinorCodes.SAS_TSS_FAILURE, 356 CompletionStatus.COMPLETED_NO); 357 } 358 if (sasValues == null) 359 return; 360 if (sasValues.targetRequires == 0 && sasValues.targetSupports == 0) 361 return; 362 363 ATLASPolicyValues atlasValues = null; 364 try 365 { 366 ObjectImpl oi = (ObjectImpl )((ServerRequestInfoImpl) ri).target(); 367 org.jacorb.orb.Delegate d = (org.jacorb.orb.Delegate)oi._get_delegate(); 368 ATLASPolicy policy = (ATLASPolicy)d.getPOA().getPolicy(ATLAS_POLICY_TYPE.value); 369 if (policy != null) 370 atlasValues = policy.value(); 371 } 372 catch (BAD_PARAM e) 373 { 374 if (logger.isDebugEnabled()) 375 logger.debug("No ATLAS Policy for "+ri.operation()); 376 } 377 catch (Exception e) 378 { 379 if (logger.isWarnEnabled()) 380 logger.warn("Error fetching ATLAS policy for "+ 381 ri.operation()+": "+e); 382 throw new org.omg.CORBA.NO_PERMISSION ("Error fetching ATLAS policy: "+e, 383 MinorCodes.SAS_TSS_FAILURE, 384 CompletionStatus.COMPLETED_NO); 385 } 386 387 SASContextBody contextBody = null; 389 long client_context_id = 0; 390 byte[] contextToken = null; 391 try 392 { 393 ServiceContext ctx = 394 ri.get_request_service_context(SASInitializer.SecurityAttributeService); 395 Any ctx_any = 396 codec.decode_value( ctx.context_data, SASContextBodyHelper.type() ); 397 contextBody = 398 SASContextBodyHelper.extract(ctx_any); 399 } 400 catch (BAD_PARAM e) 401 { 402 if (logger.isDebugEnabled()) 403 logger.debug("Could not parse service context for operation " + 404 ri.operation()); 405 } 406 catch (Exception e) 407 { 408 if (logger.isWarnEnabled()) 409 logger.warn("Could not parse service context for operation " + 410 ri.operation() + ": " + e); 411 } 412 413 if (contextBody == null && 414 (sasValues.targetRequires & org.omg.CSIIOP.EstablishTrustInClient.value) != 0 && 415 !ri.operation().equals("_non_existent") && 416 !ri.operation().equals("_is_a")) 417 { 418 if (logger.isErrorEnabled()) 419 logger.error("Did not parse service context for operation " + 420 ri.operation()); 421 throw new org.omg.CORBA.NO_PERMISSION ("No SAS service context found", 422 MinorCodes.SAS_TSS_FAILURE, 423 CompletionStatus.COMPLETED_NO); 424 } 425 if (contextBody == null) 426 { 427 if (logger.isDebugEnabled()) 428 logger.debug("No context found, but not required"); 429 return; 430 } 431 432 if (contextBody.discriminator() == MTMessageInContext.value) 434 { 435 MessageInContext msg = null; 436 try 437 { 438 msg = contextBody.in_context_msg(); 439 client_context_id = msg.client_context_id; 440 contextToken = getSASContext(connection, msg.client_context_id); 441 } 442 catch (Exception e) 443 { 444 if (logger.isErrorEnabled()) 445 logger.error("Could not parse service MessageInContext " + 446 ri.operation() + ": " + e); 447 makeContextError(ri, client_context_id, 1, 1, contextToken); 448 throw new org.omg.CORBA.NO_PERMISSION ("SAS Error parsing MessageInContext: " + e, 449 MinorCodes.SAS_TSS_FAILURE, 450 CompletionStatus.COMPLETED_NO); 451 } 452 if (contextToken == null) 453 { 454 if (logger.isErrorEnabled()) 455 logger.error("Could not find context in MessageInContext " + 456 ri.operation() + ": " + msg.client_context_id); 457 makeContextError(ri, client_context_id, 2, 1, contextToken); 458 throw new org.omg.CORBA.NO_PERMISSION ("SAS Error invalid context in MessageInContext", 459 MinorCodes.SAS_TSS_FAILURE, 460 CompletionStatus.COMPLETED_NO); 461 } 462 } 463 464 if (contextBody.discriminator() == MTEstablishContext.value) 466 { 467 EstablishContext msg = null; 468 String principalName = null; 469 try 470 { 471 msg = contextBody.establish_msg(); 472 client_context_id = msg.client_context_id; 473 contextToken = msg.client_authentication_token; 474 475 principalName = sasContext.getValidatedPrincipal(); 476 } 477 catch (org.omg.CORBA.NO_PERMISSION e) 478 { 479 if (logger.isErrorEnabled()) 480 logger.error("Err " + ri.operation() + ": " + e); 481 makeContextError(ri, client_context_id, 1, 1, contextToken); 482 throw e; 483 } 484 catch (Exception e) 485 { 486 if (logger.isErrorEnabled()) 487 logger.error("Could not parse service EstablishContext " + 488 ri.operation() + ": " + e); 489 makeContextError(ri, client_context_id, 2, 1, contextToken); 490 throw new org.omg.CORBA.NO_PERMISSION ("SAS Error parsing EstablishContext: " + e, 491 MinorCodes.SAS_TSS_FAILURE, 492 CompletionStatus.COMPLETED_NO); 493 } 494 if (contextToken == null) 495 { 496 if (logger.isErrorEnabled()) 497 logger.error("Could not parse service EstablishContext " + 498 ri.operation() + ": " + msg.client_context_id); 499 makeContextError(ri, client_context_id, 2, 1, contextToken); 500 501 throw new org.omg.CORBA.NO_PERMISSION ("SAS Error parsing EstablishContext", 502 MinorCodes.SAS_TSS_FAILURE, 503 CompletionStatus.COMPLETED_NO); 504 } 505 506 if (sasValues.stateful) 508 cacheSASContext(connection, msg.client_context_id, 509 contextToken, principalName); 510 } 511 512 try 514 { 515 makeCompleteEstablishContext(ri, client_context_id, sasValues); 516 } 517 catch (Exception e) 518 { 519 if (logger.isErrorEnabled()) 520 logger.error("Error inserting service context into slots for " + 521 ri.operation() + ": " + e); 522 makeContextError(ri, client_context_id, 1, 1, contextToken); 523 throw new org.omg.CORBA.NO_PERMISSION ("SAS Error insert service context into slots: " + e, MinorCodes.SAS_TSS_FAILURE, CompletionStatus.COMPLETED_NO); 524 } 525 } 526 527 public void send_reply( ServerRequestInfo ri ) 528 { 529 if (logger.isDebugEnabled()) 530 logger.debug("send_reply for "+ri.operation()); 531 532 567 } 568 569 public void send_exception( ServerRequestInfo ri ) 570 throws ForwardRequest 571 { 572 if (logger.isDebugEnabled()) 573 logger.debug("send_exception for "+ri.operation()); 574 575 613 } 614 615 public void send_other( ServerRequestInfo ri ) 616 throws ForwardRequest 617 { 618 if (logger.isDebugEnabled()) 619 logger.debug("send_other for "+ri.operation()); 620 } 621 622 protected Any makeCompleteEstablishContext(ServerRequestInfo ri, long client_context_id, SASPolicyValues sasValues) { 623 CompleteEstablishContext msg = new CompleteEstablishContext(); 624 msg.client_context_id = client_context_id; 625 msg.context_stateful = sasValues.stateful; 626 msg.final_context_token = new byte[0]; 627 SASContextBody contextBody = new SASContextBody(); 628 contextBody.complete_msg(msg); 629 Any any = orb.create_any(); 630 SASContextBodyHelper.insert( any, contextBody ); 631 if (ri != null) 632 { 633 try 634 { 635 ri.add_reply_service_context(new ServiceContext (SASInitializer.SecurityAttributeService, codec.encode_value( any ) ), true); 636 } 637 catch (Exception e) 638 { 639 logger.error("Error setting reply service context:" + e); 640 throw new org.omg.CORBA.NO_PERMISSION ("SAS Error setting reply service context: " + e, MinorCodes.SAS_TSS_FAILURE, CompletionStatus.COMPLETED_MAYBE); 641 } 642 } 643 return any; 644 } 645 646 protected Any makeContextError(ServerRequestInfo ri, long client_context_id, int major_status, int minor_status, byte[] error_token) { 647 ContextError msg = new ContextError(); 648 msg.client_context_id = client_context_id; 649 msg.error_token = error_token; 650 msg.major_status = major_status; 651 msg.minor_status = minor_status; 652 SASContextBody contextBody = new SASContextBody(); 653 contextBody.error_msg(msg); 654 Any any = orb.create_any(); 655 SASContextBodyHelper.insert( any, contextBody ); 656 if (ri != null) 657 { 658 try 659 { 660 ri.add_reply_service_context(new ServiceContext (SASInitializer.SecurityAttributeService, codec.encode_value( any ) ), true); 661 } 662 catch (Exception e) 663 { 664 logger.error("Error setting reply service context:" + e); 665 throw new org.omg.CORBA.NO_PERMISSION ("SAS Error setting reply service context: " + e, MinorCodes.SAS_TSS_FAILURE, CompletionStatus.COMPLETED_MAYBE); 666 } 667 } 668 return any; 669 } 670 671 673 class CachedContext 674 { 675 public byte[] client_authentication_token; 676 public String principalName; 677 CachedContext(byte[] client_authentication_token, String principalName) 678 { 679 this.client_authentication_token = client_authentication_token; 680 this.principalName = principalName; 681 } 682 } 683 684 public void cacheSASContext(GIOPConnection connection, 685 long client_context_id, 686 byte[] client_authentication_token, 687 String principalName) 688 { 689 synchronized ( connection ) 690 { 691 Hashtable sasContexts = 692 (Hashtable ) connection.get_cubby(sasContextsCubby); 693 if (sasContexts == null) 694 { 695 sasContexts = new Hashtable (); 696 connection.set_cubby(sasContextsCubby, sasContexts); 697 } 698 sasContexts.put(new Long (client_context_id), 699 new CachedContext(client_authentication_token, principalName)); 700 } 701 } 702 703 public void purgeSASContext(GIOPConnection connection, long client_context_id) 704 { 705 synchronized ( connection ) 706 { 707 Hashtable sasContexts = (Hashtable ) connection.get_cubby(sasContextsCubby); 708 if (sasContexts == null) 709 { 710 sasContexts = new Hashtable (); 711 connection.set_cubby(sasContextsCubby, sasContexts); 712 } 713 sasContexts.remove(new Long (client_context_id)); 714 } 715 } 716 717 public byte[] getSASContext(GIOPConnection connection, long client_context_id) 718 { 719 Long key = new Long (client_context_id); 720 synchronized ( connection ) 721 { 722 Hashtable sasContexts = (Hashtable ) connection.get_cubby(sasContextsCubby); 723 if (sasContexts == null) 724 { 725 sasContexts = new Hashtable (); 726 connection.set_cubby(sasContextsCubby, sasContexts); 727 } 728 if (!sasContexts.containsKey(key)) 729 return null; 730 return ((CachedContext)sasContexts.get(key)).client_authentication_token; 731 } 732 } 733 734 public String getSASContextPrincipalName(GIOPConnection connection, 735 long client_context_id) 736 { 737 Long key = new Long (client_context_id); 738 synchronized ( connection ) 739 { 740 Hashtable sasContexts = 741 (Hashtable ) connection.get_cubby(sasContextsCubby); 742 if (sasContexts == null) 743 { 744 sasContexts = new Hashtable (); 745 connection.set_cubby(sasContextsCubby, sasContexts); 746 } 747 if (!sasContexts.containsKey(key)) 748 return null; 749 return ((CachedContext)sasContexts.get(key)).principalName; 750 } 751 } 752 } 753 | Popular Tags |