CAS Unit Tests
Clover coverage report - CAS Unit Tests
Coverage timestamp: Mon Jul 4 2005 18:13:17 CDT
file stats: LOC: 946   Methods: 15
NCLOC: 718   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
CasQueryPortImpl.java 0% 0% 0% 0%
coverage
 1    /*
 2    * Portions of this file Copyright 1999-2005 University of Chicago
 3    * Portions of this file Copyright 1999-2005 The University of Southern California.
 4    *
 5    * This file or a portion of this file is licensed under the
 6    * terms of the Globus Toolkit Public License, found at
 7    * http://www.globus.org/toolkit/download/license.html.
 8    * If you redistribute this file, with or without
 9    * modifications, you must include this notice in the file.
 10    */
 11    package org.globus.cas.impl.service;
 12   
 13    import org.globus.cas.faults.CasFault;
 14    import org.globus.cas.faults.NoPermissionFault;
 15   
 16    import org.globus.cas.types.VoidType;
 17    import org.globus.cas.types.ObjectData;
 18    import org.globus.cas.types.PolicyData;
 19    import org.globus.cas.types.CasObjectData;
 20    import org.globus.cas.types.UserGroupData;
 21    import org.globus.cas.types.ObjectGroupData;
 22    import org.globus.cas.types.SAMLAuthzQueryType;
 23    import org.globus.cas.types.CasObjectDesc;
 24    import org.globus.cas.types.ArrayOfCasObjectData;
 25    import org.globus.cas.types.ArrayOfString;
 26    import org.globus.cas.types.GetGroupMembers;
 27    import org.globus.cas.types.GetAssertionParam;
 28    import org.globus.cas.types.ArrayOfSAMLAuthzQueryType;
 29   
 30    import org.globus.wsrf.security.SecurityManager;
 31    import org.globus.wsrf.security.SecurityException;
 32   
 33    import javax.security.auth.Subject;
 34   
 35    import java.security.cert.X509Certificate;
 36   
 37    import org.globus.gsi.jaas.JaasGssUtil;
 38    import org.globus.gsi.gssapi.GlobusGSSCredentialImpl;
 39   
 40    import org.globus.cas.impl.CasConstants;
 41   
 42    import org.globus.cas.impl.databaseAccess.CasDBException;
 43    import org.globus.cas.impl.databaseAccess.UserDataHandler;
 44    import org.globus.cas.impl.databaseAccess.ObjectDataHandler;
 45    import org.globus.cas.impl.databaseAccess.PolicyDataHandler;
 46    import org.globus.cas.impl.databaseAccess.PermissionsHandler;
 47    import org.globus.cas.impl.databaseAccess.PolicyQueryHandler;
 48    import org.globus.cas.impl.databaseAccess.NamespaceDataHandler;
 49    import org.globus.cas.impl.databaseAccess.UserGroupDataHandler;
 50    import org.globus.cas.impl.databaseAccess.ServiceTypeDataHandler;
 51    import org.globus.cas.impl.databaseAccess.TrustAnchorDataHandler;
 52    import org.globus.cas.impl.databaseAccess.ObjectGroupDataHandler;
 53    import org.globus.cas.impl.databaseAccess.ExternalPolicyEvaluator;
 54    import org.globus.cas.impl.databaseAccess.ServiceTypeActionHandler;
 55   
 56    import java.util.Vector;
 57    import java.util.Iterator;
 58    import java.util.Calendar;
 59    import java.util.StringTokenizer;
 60   
 61    import org.w3c.dom.Element;
 62   
 63    import org.apache.axis.message.MessageElement;
 64   
 65    import org.opensaml.SAMLAction;
 66    import org.opensaml.SAMLSubject;
 67    import org.opensaml.SAMLException;
 68    import org.opensaml.SAMLAuthorizationDecisionQuery;
 69    import org.opensaml.SAMLAuthorizationDecisionStatement;
 70   
 71    import org.apache.xml.security.signature.XMLSignature;
 72   
 73    import org.globus.wsrf.ResourceContext;
 74    import org.globus.wsrf.impl.security.SecurityMessageElement;
 75   
 76    import org.apache.commons.logging.Log;
 77    import org.apache.commons.logging.LogFactory;
 78   
 79    import org.globus.util.I18n;
 80   
 81    /**
 82    * Implementation of CAS Query interface
 83    */
 84    public class CasQueryPortImpl {
 85   
 86    static Log logger = LogFactory.getLog(CasQueryPortImpl.class.getName());
 87   
 88    private static I18n i18n =
 89    I18n.getI18n("org.globus.cas.impl.service.errors",
 90    CasQueryPortImpl.class.getClassLoader());
 91   
 92    private int defaultAssertionLifetime = 24 * 60 * 60;
 93    private int serverAssertionLifetime = 24 * 60 * 60;
 94   
 95   
 96  0 public CasQueryPortImpl() throws Exception {
 97   
 98  0 ResourceContext context = ResourceContext.getResourceContext();
 99  0 CasResource resource = (CasResource)context.getResource();
 100  0 if (resource.getMaxAssertionLifetime() != -1) {
 101  0 serverAssertionLifetime = resource.getMaxAssertionLifetime();
 102    } else {
 103  0 serverAssertionLifetime = defaultAssertionLifetime;
 104    }
 105    }
 106   
 107    /**
 108    * Method to get nickname of the user invoking the method
 109    *
 110    * @return user name of the user invoking the method
 111    * @exception CasFault if any other error occurs.
 112    */
 113  0 public String whoami(VoidType voidType) throws CasFault {
 114  0 logger.debug("whoami");
 115  0 return CasService.getCallerNickname();
 116    }
 117   
 118    /**
 119    * Method to get all applicable policies
 120    *
 121    * @param type
 122    * type of object whose policy is needed
 123    * trustAnchor/namespace/user/userGroup/object/objectGroup/
 124    * serviceType, serviceTypeAction/serviceActionGroup
 125    * @param name
 126    * identifier for the object
 127    * trustAnchorNickname/namespaceNickname/userNickname/userGroupName/
 128    * object(namespace|name)/objectGroupName/serviceTypeName/
 129    * serviceTypeAction(serviceType/action)/serviceActionGroupName
 130    * @return an array of PolicyData
 131    * @exception NoPermissionFault if the client does not have
 132    * permission to perform this operation.
 133    * @exception CasFault if any other error occurs.
 134    */
 135  0 public ArrayOfCasObjectData findApplicablePolicy(CasObjectDesc desc)
 136    throws CasFault, NoPermissionFault {
 137   
 138  0 String type = desc.getTypeOfCasObject();
 139  0 String name = desc.getNameOfCasObject();
 140   
 141  0 String baseErrMsg = i18n.getMessage("retrErr", "applicable policies");
 142  0 logger.debug("findAppPolicy" + name + " " + type);
 143  0 if ((type == null) || (name == null)) {
 144  0 String err = i18n.getMessage("allParamErr");
 145  0 logger.error(err);
 146  0 throw CasService.makeFault(baseErrMsg + err);
 147    }
 148  0 String userName = CasService.getCallerNickname();
 149    // policy check: if user has cas/query permissions
 150  0 checkQueryPermissions(userName, baseErrMsg);
 151  0 try {
 152  0 if (type.trim().equals(CasConstants.OBJECT_SPEC)) {
 153  0 logger.debug("Object, get object Id");
 154  0 name = CasService.getObjectId(name);
 155  0 } else if (type.trim().equals(CasConstants.SERVICEACTION_SPEC)) {
 156  0 logger.debug("ServiceAction, get serviceAction Id");
 157  0 name = CasService.getServiceActionId(name);
 158    }
 159  0 return new ArrayOfCasObjectData(PolicyQueryHandler.
 160    getAllApplicablePolicy(type,
 161    name));
 162    }
 163    catch (CasDBException exp) {
 164  0 logger.error(baseErrMsg, exp);
 165  0 throw CasService.makeFault(baseErrMsg + exp.getMessage(), exp);
 166    }
 167    }
 168   
 169    /**
 170    * Method to get a list of objects
 171    *
 172    * @param type
 173    * type of object
 174    * "user" or "userGroup" or "object" or "objectGroup" or
 175    * "serviceAction" or "serviceActionGroup" or "serviceType"
 176    * or "namespace" or "trustAnchor" or "policy"
 177    * @return list of objects of the particular type
 178    * @exception NoPermissionFault if the client does not have
 179    * permission to perform this operation.
 180    * @exception CasFault if any other error occurs.
 181    */
 182  0 public ArrayOfString list(String type) throws
 183    CasFault, NoPermissionFault {
 184  0 logger.debug("list of " + type);
 185   
 186  0 String baseErrMsg = i18n.getMessage("listErr", type);
 187  0 String userName = CasService.getCallerNickname();
 188    // policy check: if user has cas/query permissions
 189  0 checkQueryPermissions(userName, baseErrMsg);
 190   
 191  0 if (type == null) {
 192  0 String err = i18n.getMessage("allParamErr");
 193  0 logger.error(err);
 194  0 throw CasService.makeFault(baseErrMsg + err);
 195    }
 196  0 try {
 197  0 if (type.trim().equals(CasConstants.TRUSTANCHOR_SPEC)) {
 198  0 logger.debug("List trust achors");
 199  0 return new ArrayOfString(TrustAnchorDataHandler.list());
 200  0 } else if (type.trim().equals(CasConstants.USER_SPEC)) {
 201  0 logger.debug("List user");
 202  0 return new ArrayOfString(UserDataHandler.list());
 203  0 } else if (type.trim().equals(CasConstants.USERGP_SPEC)) {
 204  0 logger.debug("List user group");
 205  0 return new ArrayOfString(UserGroupDataHandler.list());
 206  0 } else if (type.trim().equals(CasConstants.OBJECT_SPEC)) {
 207  0 logger.debug("List object");
 208  0 return new ArrayOfString(ObjectDataHandler.list());
 209  0 } else if (type.trim().equals(CasConstants.OBJECTGP_SPEC)) {
 210  0 logger.debug("List object group");
 211  0 return new ArrayOfString(ObjectGroupDataHandler.list());
 212  0 } else if (type.trim().equals(CasConstants.NAMESPACE_SPEC)) {
 213  0 logger.debug("List Namespace");
 214  0 return new ArrayOfString(NamespaceDataHandler.list());
 215  0 } else if (type.trim().equals(CasConstants.SERVICETYPE_SPEC)) {
 216  0 logger.debug("List Service Type");
 217  0 return new ArrayOfString(ServiceTypeDataHandler.list());
 218  0 } else if (type.trim().equals(
 219    CasConstants.SERVICEACTION_SPEC)) {
 220  0 logger.debug("List Service Action ");
 221  0 return new ArrayOfString(ServiceTypeActionHandler
 222    .listServiceActionMappings());
 223  0 } else if (type.trim().equals(
 224    CasConstants.SERVICEACTIONGP_SPEC)) {
 225  0 logger.debug("List Service Action Groups ");
 226  0 return new ArrayOfString(ServiceTypeActionHandler
 227    .listServiceActionGroups());
 228  0 } else if (type.trim().equals(CasConstants.POLICY_SPEC)) {
 229  0 logger.debug("List Policy");
 230  0 return new ArrayOfString(PolicyDataHandler.list());
 231    }else {
 232  0 String errMesg =
 233    i18n.getMessage("typeErr",
 234    CasConstants.TRUSTANCHOR_SPEC + " or "
 235    + CasConstants.USER_SPEC + " or "
 236    + CasConstants.USERGP_SPEC + " or "
 237    + CasConstants.OBJECT_SPEC + " or "
 238    + CasConstants.OBJECTGP_SPEC + " or "
 239    + CasConstants.NAMESPACE_SPEC + " or "
 240    + CasConstants.SERVICETYPE_SPEC + " or "
 241    + CasConstants.SERVICEACTION_SPEC + " or "
 242    + CasConstants.SERVICEACTIONGP_SPEC
 243    + " or " + CasConstants.POLICY_SPEC);
 244  0 logger.error(errMesg);
 245  0 throw CasService.makeFault(baseErrMsg + errMesg);
 246    }
 247    }
 248    catch (CasDBException exp) {
 249  0 logger.error(baseErrMsg, exp);
 250  0 throw CasService.makeFault(baseErrMsg + exp.getMessage(), exp);
 251    }
 252    }
 253   
 254    /** Method to get an object given its identifier
 255    *
 256    * @param type
 257    * type of object
 258    * "user" or "userGroup" or "object" or "objectGroup" or
 259    * "serviceType" or "trustAnchor" or "namespace" or "policy"
 260    * @param name
 261    * name that identifies the object
 262    * userName, userGroupName, object(objectNamespace|objectName),
 263    * objectGroupName, serviceTypeName, trustAnchorNick,
 264    * namespaceNick, policyId
 265    * @return returns the CasObject that represents the object of type
 266    * "type" and name. Returns null if such an object does not exist
 267    * @exception NoPermissionFault if the client does not have
 268    * permission to perform this operation.
 269    * @exception CasFault if any other error occurs.
 270    */
 271  0 public CasObjectData getCasObject(CasObjectDesc desc)
 272    throws CasFault, NoPermissionFault {
 273   
 274  0 String type = desc.getTypeOfCasObject();
 275  0 String name = desc.getNameOfCasObject();
 276   
 277  0 String baseErrMsg = i18n.getMessage("retrErr", type);
 278  0 logger.debug("getCasObject " + type + " " + name);
 279  0 String userName = CasService.getCallerNickname();
 280    // policy check: if user has cas/query permissions
 281  0 checkQueryPermissions(userName, baseErrMsg);
 282   
 283  0 if ((type == null) || (name == null)) {
 284  0 String err = i18n.getMessage("allParamErr");
 285  0 logger.error(err);
 286  0 throw CasService.makeFault(baseErrMsg + err);
 287    }
 288   
 289  0 try {
 290  0 if (type.trim().equals(CasConstants.TRUSTANCHOR_SPEC)) {
 291  0 logger.debug("Get trust anchors");
 292  0 return TrustAnchorDataHandler.retrieveObject(name);
 293  0 } else if (type.trim().equals(CasConstants.USER_SPEC)) {
 294  0 logger.debug("Get user");
 295  0 return UserDataHandler.retrieveObject(name);
 296  0 } else if (type.trim().equals(CasConstants.USERGP_SPEC)) {
 297  0 logger.debug("Get user group");
 298  0 return UserGroupDataHandler.retrieveObject(name);
 299  0 } else if (type.trim().equals(CasConstants.OBJECT_SPEC)) {
 300  0 logger.debug("Get object Id and get object");
 301  0 String id = CasService.getObjectId(name);
 302  0 return ObjectDataHandler.retrieveObjectForId(id);
 303  0 } else if (type.trim().equals(CasConstants.OBJECTGP_SPEC)) {
 304  0 logger.debug("Get object group");
 305  0 return ObjectGroupDataHandler.retrieveObject(name);
 306  0 } else if (type.trim().equals(CasConstants.NAMESPACE_SPEC)) {
 307  0 logger.debug("Get namespace");
 308  0 return NamespaceDataHandler.retrieveObject(name);
 309  0 } else if (type.trim().equals(CasConstants.SERVICETYPE_SPEC)) {
 310  0 logger.debug("Get service type");
 311  0 return ServiceTypeDataHandler.retrieveObject(name);
 312  0 } else if (type.trim().equals(CasConstants.POLICY_SPEC)) {
 313  0 logger.debug("Get policy");
 314  0 return PolicyDataHandler.retrieveObject(name);
 315    }else {
 316  0 String errMesg =
 317    i18n.getMessage("typeErr",
 318    CasConstants.TRUSTANCHOR_SPEC + " or "
 319    + CasConstants.USER_SPEC + " or "
 320    + CasConstants.USERGP_SPEC + " or "
 321    + CasConstants.OBJECT_SPEC + " or "
 322    + CasConstants.OBJECTGP_SPEC + " or "
 323    + CasConstants.NAMESPACE_SPEC + " or "
 324    + CasConstants.SERVICETYPE_SPEC + " or "
 325    + CasConstants.POLICY_SPEC);
 326  0 logger.error(errMesg);
 327  0 throw CasService.makeFault(baseErrMsg + errMesg);
 328    }
 329    }
 330    catch (CasDBException exp) {
 331  0 logger.error("getCasObject of " + type + " group failed", exp);
 332  0 throw CasService.makeFault(baseErrMsg + exp.getMessage(), exp);
 333    }
 334    }
 335   
 336    /**
 337    * Method that returns the group members as an array of string
 338    *
 339    * @param groupType
 340    * Type of group. Should be "user" or "object" or "serviceAction"
 341    * @param groupName
 342    * Name of the group whose members are to be retrieved
 343    * @return Group member identifiers as an array of strings
 344    * @exception NoPermissionFault if the client does not have
 345    * permission to perform this operation.
 346    * @exception CasFault if any other error occurs.
 347    */
 348  0 public ArrayOfString getGroupMembers(GetGroupMembers gpMembers)
 349    throws CasFault, NoPermissionFault {
 350   
 351  0 String groupType = gpMembers.getTypeOfGroup();
 352  0 String groupName = gpMembers.getNameOfGroup();
 353   
 354  0 String baseErrMsg = i18n.getMessage("gpMemListErr");
 355  0 logger.debug("getGroupMembers " + groupType + " " + groupName);
 356  0 String userName = CasService.getCallerNickname();
 357    // policy check: if user has cas/query permissions
 358  0 checkQueryPermissions(userName, baseErrMsg);
 359   
 360  0 if ((groupType == null) || (groupName == null)) {
 361  0 String err = i18n.getMessage("allParamErr");
 362  0 logger.error(err);
 363  0 throw CasService.makeFault(baseErrMsg + err);
 364    }
 365   
 366  0 try {
 367  0 if (groupType.trim().equals(CasConstants.USER_SPEC)) {
 368  0 logger.debug("User group");
 369  0 UserGroupData userGroup =
 370    (UserGroupData)UserGroupDataHandler.retrieveObject(
 371    groupName.trim());
 372  0 if (userGroup == null) {
 373  0 String errMesg =
 374    i18n.getMessage("doesNotExist", new Object[] {
 375    "User group ", groupName.trim() });
 376  0 logger.error(errMesg);
 377  0 throw CasService.makeFault(baseErrMsg + errMesg);
 378    }
 379  0 return userGroup.getUserNames();
 380  0 } else if (groupType.trim().equals(CasConstants.OBJECT_SPEC)) {
 381  0 logger.debug("Object group");
 382  0 ObjectGroupData objGroup =
 383    (ObjectGroupData)ObjectGroupDataHandler.retrieveObject(
 384    groupName.trim());
 385  0 if (objGroup == null) {
 386  0 String errMesg =
 387    i18n.getMessage("doesNotExist", new Object[]
 388    { "Object group ", groupName.trim()});
 389  0 logger.error(errMesg);
 390  0 throw CasService.makeFault(baseErrMsg + errMesg);
 391    }
 392  0 ArrayOfString returnSpecArray =
 393    objGroup.getObjectSpecs();
 394  0 if (returnSpecArray == null) {
 395  0 logger.debug("No members in this group");
 396  0 return null;
 397    } else {
 398  0 String returnSpec[] = returnSpecArray.getStrings();
 399  0 String returnSpecDesc[] =
 400    objGroup.getObjectSpecsDesc().getStrings();
 401  0 String[] retString = new String[returnSpec.length];
 402  0 for (int i=0; i<returnSpec.length; i++) {
 403  0 String retSpec = returnSpec[i];
 404  0 if (returnSpecDesc[i].equals(
 405    CasConstants.OBJECT_SPEC)) {
 406  0 ObjectData obj =
 407    ObjectDataHandler.retrieveObjectForId(retSpec);
 408  0 retSpec = obj.getObjectNamespace()
 409    + CasConstants.OBJECTSPEC_DELIMITER
 410    + obj.getObjectName();
 411    }
 412  0 retString[i] = retSpec + ", " + returnSpecDesc[i];
 413    }
 414  0 return new ArrayOfString(retString);
 415    }
 416  0 } else if (groupType.trim().equals(
 417    CasConstants.SERVICEACTION_SPEC)) {
 418  0 logger.debug("Service action group");
 419  0 String retValue[] =
 420    ServiceTypeActionHandler.retrieveServiceActionGpEntries(
 421    groupName.trim());
 422  0 return new ArrayOfString(retValue);
 423    } else {
 424  0 String errMesg =
 425    i18n.getMessage("typeErr", CasConstants.USER_SPEC +
 426    " or " + CasConstants.OBJECT_SPEC + " or "
 427    + CasConstants.SERVICEACTION_SPEC);
 428  0 logger.error(errMesg);
 429  0 throw CasService.makeFault(baseErrMsg + errMesg);
 430    }
 431    } catch (CasDBException exp) {
 432  0 logger.error(baseErrMsg, exp);
 433  0 throw CasService.makeFault(baseErrMsg + exp.getMessage(), exp);
 434    }
 435    }
 436   
 437    /**
 438    * Method that generated an assertion with a list of AuthzDecisionStmt
 439    * that represent the list of actions that are permitted.
 440    *
 441    * @param lifetimeInSeconds
 442    * Requested lifetime on the assertion in seconds
 443    * @param SAMLAthzQueryType
 444    * - A SAMLAuthorizationDecisionQuery object (OpenSAML data type is
 445    * passed as xsd:any).
 446    * - The resource maybe set as wildcard or namspace|name.
 447    * - A vector of actions are set as a part of the query -
 448    * if the first SAMLAction is set to wildcard, then rest
 449    * are ignored. Otherwise action should be serviceType/action
 450    * - SAMLSubject must have the user's DN.
 451    * @return SAMLAsssertion
 452    * A SAMLAssertion object with SAMLAuthorizationDecisionStatement(s)
 453    * (OpenSAML datatype is passed as xsd:any)
 454    * @exception NoPermissionFault if the client does not have
 455    * permission to perform this operation.
 456    * @exception CasFault if any error occurs.
 457    */
 458  0 public org.globus.cas.types.SAMLAssertion
 459    getAssertion(GetAssertionParam getAssertionParam)
 460    throws CasFault, NoPermissionFault {
 461   
 462  0 SAMLAuthzQueryType[] queries = null;
 463  0 ArrayOfSAMLAuthzQueryType array =
 464    getAssertionParam.getSamlAuthzQuery();
 465  0 if (array != null) {
 466  0 queries = array.getSAMLAuthzTypes();
 467    }
 468  0 int lifetimeInSeconds = getAssertionParam.getLifetime();
 469   
 470  0 logger.debug(" Generate assertion " + lifetimeInSeconds);
 471  0 String baseErrMsg = i18n.getMessage("assertionGenErr");
 472   
 473  0 String userNick = CasService.getCallerNickname();
 474  0 logger.debug("User nick is " + userNick);
 475   
 476  0 boolean casQueryPermChecked = false;
 477  0 if (queries != null) {
 478  0 Vector samlQueryVector = null;
 479  0 Vector queryNickVector = null;
 480  0 for (int i=0; i<queries.length; i++) {
 481  0 logger.debug("get authzDecStmt Query");
 482  0 SAMLAuthorizationDecisionQuery samlQuery =
 483    getAuthzDecisionQuery(queries[i]);
 484  0 if (samlQuery == null)
 485  0 continue;
 486    // Get subject name and hence username for which the query is.
 487  0 SAMLSubject receivedSubject = samlQuery.getSubject();
 488  0 String userDN = receivedSubject.getName();
 489  0 String issuerDN = receivedSubject.getNameQualifier();
 490  0 Iterator confIterator =
 491    receivedSubject.getConfirmationMethods();
 492  0 String confMethod = null;
 493  0 if (confIterator.hasNext()) {
 494  0 confMethod = (String)confIterator.next();
 495    } else {
 496  0 String err = i18n.getMessage("noConfMethod");
 497  0 logger.error(err);
 498  0 throw CasService.makeFault(baseErrMsg + err);
 499    }
 500  0 String queryUserNick =
 501    getUserNickname(userDN, issuerDN, confMethod);
 502    // Check permissions
 503  0 if (queryUserNick.equals(userNick)) {
 504  0 logger.debug("Assertions for self requested, permission"
 505    + " check not required");
 506    } else {
 507  0 if (!casQueryPermChecked) {
 508  0 checkQueryPermissions(userNick, baseErrMsg);
 509  0 casQueryPermChecked = true;
 510    }
 511    }
 512  0 if (samlQueryVector == null)
 513  0 samlQueryVector = new Vector();
 514  0 if (queryNickVector == null)
 515  0 queryNickVector = new Vector();
 516  0 samlQueryVector.add(samlQuery);
 517  0 queryNickVector.add(queryUserNick);
 518    }
 519   
 520  0 if (samlQueryVector == null)
 521  0 return null;
 522    // Permissions for allqueries ascertained. Get stmts now
 523  0 Vector samlAuthzDecisionVector = null;
 524  0 for (int i=0; i<samlQueryVector.size(); i++) {
 525  0 SAMLAuthorizationDecisionQuery samlQuery =
 526    (SAMLAuthorizationDecisionQuery)samlQueryVector.get(i);
 527  0 Vector authzStmts =
 528    getAuthzDecisionStmts(samlQuery,
 529    (String)queryNickVector.get(i));
 530  0 if (authzStmts != null) {
 531  0 if (samlAuthzDecisionVector == null) {
 532  0 samlAuthzDecisionVector = new Vector();
 533    }
 534  0 logger.debug("add stmts");
 535  0 samlAuthzDecisionVector.addAll(authzStmts);
 536    }
 537    }
 538    // No Authz Decision stmt - return null
 539  0 if (samlAuthzDecisionVector ==null) {
 540  0 logger.debug("No authz decision vector");
 541  0 return null;
 542    }
 543  0 return constructSAMLAssertion(lifetimeInSeconds, baseErrMsg,
 544    samlAuthzDecisionVector);
 545    }
 546    else {
 547  0 return null;
 548    }
 549    }
 550   
 551  0 private org.globus.cas.types.SAMLAssertion
 552    constructSAMLAssertion(int lifetimeInSeconds, String baseErrMsg,
 553    Vector samlAuthzDecisionVector)
 554    throws CasFault {
 555   
 556    // get server credential
 557  0 GlobusGSSCredentialImpl credential = getServerCredential();
 558    // get DN of CA
 559  0 String dnOfCA = getDNofServerCA(credential);
 560    // SAML assertion construction
 561  0 Calendar notOnOrAfter = Calendar.getInstance();
 562  0 Calendar notBefore = Calendar.getInstance();
 563  0 notBefore.setTime(notOnOrAfter.getTime());
 564    // requested lifetime is greater than max server assertion
 565    // then use max server assertion
 566  0 logger.debug("lifitimeInSec " + lifetimeInSeconds + " max server "
 567    + serverAssertionLifetime);
 568  0 if (lifetimeInSeconds > serverAssertionLifetime) {
 569  0 logger.debug("Requested lifetime greater than max server"
 570    + " lifetime");
 571  0 notOnOrAfter.add(Calendar.SECOND, serverAssertionLifetime);
 572    } else {
 573  0 notOnOrAfter.add(Calendar.SECOND, lifetimeInSeconds);
 574    }
 575   
 576  0 org.opensaml.SAMLAssertion samlAssertion = null;
 577  0 try {
 578   
 579  0 samlAssertion =
 580    new org.opensaml.SAMLAssertion(dnOfCA,
 581    notBefore.getTime(),
 582    notOnOrAfter.getTime(),
 583    null,
 584    null,
 585    samlAuthzDecisionVector);
 586    }
 587    catch (SAMLException exp) {
 588  0 String errMesg = i18n.getMessage("assertionGenErr");
 589  0 logger.error(errMesg, exp);
 590  0 throw CasService.makeFault(baseErrMsg + errMesg + exp.getMessage(),
 591    exp);
 592    }
 593   
 594    // get cert chain
 595  0 Vector certs = getCertificates(credential);
 596    // Sign assertion
 597  0 try {
 598  0 samlAssertion.sign(XMLSignature.ALGO_ID_SIGNATURE_RSA,
 599    credential.getPrivateKey(), certs, false);
 600    }
 601    catch (SAMLException exp) {
 602  0 String errMesg = i18n.getMessage("assertionSignErr");
 603  0 logger.error(errMesg, exp);
 604  0 throw CasService.makeFault(baseErrMsg + errMesg + exp.getMessage(),
 605    exp);
 606    }
 607   
 608  0 org.globus.cas.types.SAMLAssertion retSAMLAssertion =
 609    new org.globus.cas.types.SAMLAssertion();
 610  0 SecurityMessageElement msgElem =
 611    new SecurityMessageElement((Element)samlAssertion.toDOM());
 612  0 retSAMLAssertion.set_any(new MessageElement[] { msgElem });
 613   
 614  0 logger.debug("SAML assertion: " + samlAssertion.toString());
 615  0 return retSAMLAssertion;
 616    }
 617   
 618    // Takes a single SAMLQuery and returns SAMLAuthorizationDecisionQuery
 619  0 private SAMLAuthorizationDecisionQuery
 620    getAuthzDecisionQuery(SAMLAuthzQueryType query) throws CasFault {
 621  0 logger.debug("get Authz Query");
 622  0 if (query == null)
 623  0 return null;
 624   
 625  0 MessageElement[] msgElement = query.get_any();
 626  0 SAMLAuthorizationDecisionQuery samlQuery = null;
 627  0 try {
 628  0 samlQuery =
 629    new SAMLAuthorizationDecisionQuery(msgElement[0].getAsDOM());
 630    }
 631    catch (Exception exp) {
 632  0 String err = i18n.getMessage("samlAuthzQueryErr");
 633  0 logger.error(err, exp);
 634  0 throw CasService.makeFault(err + exp.getMessage(), exp);
 635    }
 636   
 637  0 return samlQuery;
 638    }
 639   
 640    // Takes a single SAMLQuery and returns a Vector of SAMLAuthzDecision
 641    // Stmts.
 642  0 private Vector
 643    getAuthzDecisionStmts(SAMLAuthorizationDecisionQuery samlQuery,
 644    String queryUserNick)
 645    throws CasFault {
 646   
 647  0 logger.debug("get Authz Decision Stmt");
 648  0 if (samlQuery == null) {
 649  0 logger.debug("Query is null");
 650  0 return null;
 651    }
 652   
 653  0 String baseErrMsg = i18n.getMessage("samlDecisionStmtErr");
 654   
 655  0 Vector samlDecisionStmtVector = null;
 656   
 657    // wildcard
 658  0 boolean resourceWildcard = false;
 659    // Get resource name (should objectNamespace|objectName or wildcard)
 660  0 String resource = samlQuery.getResource();
 661  0 if (resource == null) {
 662  0 String err = i18n.getMessage("samlResourceNull");
 663  0 logger.error(err);
 664  0 throw CasService.makeFault(baseErrMsg + err);
 665    }
 666  0 logger.debug("Resource is " + resource);
 667  0 if (resource.equals(CasConstants.RESOURCE_WILDCARD)) {
 668  0 logger.debug("Resource is wildcard");
 669  0 resourceWildcard = true;
 670    }
 671   
 672    // Vector of actions
 673    // Get actions for which assertion is requested
 674  0 Iterator actionEnum = samlQuery.getActions();
 675  0 if (actionEnum.hasNext()) {
 676    // authz policies
 677  0 Vector authorizedPolicies = null;
 678    // Get action
 679  0 SAMLAction samlAction = (SAMLAction)actionEnum.next();
 680  0 String actionNamespace = samlAction.getNamespace();
 681  0 String actionName = samlAction.getData();
 682  0 logger.debug("samlAction name " + actionNamespace + " namespace "
 683    + actionName);
 684    // action can be wildcard or serviceType and action
 685  0 String serviceActionId = null;
 686  0 try {
 687  0 if ((actionNamespace.equals(CasConstants.ACTION_NS_WILDCARD))
 688    && (actionName.equals(CasConstants.ACTION_WILDCARD))) {
 689  0 logger.debug("Action is wildcard, all actions");
 690  0 if (resourceWildcard) {
 691  0 logger.debug("resource and action are wildcard");
 692  0 authorizedPolicies =
 693    ExternalPolicyEvaluator.getPolicies(queryUserNick);
 694    } else {
 695  0 logger.debug("action is wildcard, resource is not");
 696  0 authorizedPolicies =
 697    ExternalPolicyEvaluator.getPoliciesForResource(
 698    queryUserNick,
 699    resource);
 700    }
 701    } else {
 702  0 logger.debug("Action is not wildcard, serviceType/action");
 703    // get a set of action ids FILLME
 704  0 Vector actionIds = new Vector();
 705  0 actionIds.add(CasService.getServiceActionId(
 706    actionNamespace
 707    + CasConstants.SERVICEACTION_DELIMITER
 708    + actionName));
 709  0 while (actionEnum.hasNext()) {
 710  0 SAMLAction temp = (SAMLAction)actionEnum.next();
 711  0 serviceActionId =
 712    CasService.getServiceActionId(
 713    temp.getNamespace() +
 714    CasConstants.SERVICEACTION_DELIMITER
 715    + temp.getData());
 716  0 actionIds.add(serviceActionId);
 717    }
 718  0 if (actionIds == null) {
 719  0 logger.debug("No action ids found");
 720  0 return null;
 721    }
 722  0 if (resourceWildcard) {
 723  0 logger.debug("resource is wildcard, action is not");
 724  0 authorizedPolicies =
 725    ExternalPolicyEvaluator.getPoliciesForActions(
 726    queryUserNick,
 727    actionIds);
 728    } else {
 729  0 logger.debug("resource and action are not wild card");
 730  0 authorizedPolicies =
 731    ExternalPolicyEvaluator.getPolicies(
 732    queryUserNick,
 733    resource,
 734    actionIds);
 735    }
 736    }
 737    } catch (CasDBException exp) {
 738  0 logger.error(baseErrMsg, exp);
 739  0 throw CasService.makeFault(baseErrMsg + exp.getMessage(), exp);
 740    }
 741   
 742    // The authorized policies is a Vector of Vector, each
 743    // is per resource and each requires one AuthzDecision Stmt.
 744  0 if ((authorizedPolicies != null) &&
 745    (authorizedPolicies.size() > 0)) {
 746  0 logger.debug("Authorized policies not null "
 747    + authorizedPolicies.size());
 748  0 for (int i=0; i<authorizedPolicies.size(); i++) {
 749    // All these policies are on same resource.
 750  0 Vector policies = (Vector)authorizedPolicies.get(i);
 751  0 int numPolicies = policies.size();
 752  0 logger.debug("On one resurce " + numPolicies);
 753    // Set of actions for this resource.
 754  0 Vector authzActions = new Vector(numPolicies);
 755  0 PolicyData policyData = null;
 756  0 for (int j=0; j<numPolicies; j++) {
 757  0 policyData = (PolicyData)policies.get(j);
 758  0 String serviceInfo = null;
 759  0 try {
 760  0 serviceInfo =
 761    ServiceTypeActionHandler.getServiceActionMapping(
 762    policyData.getActionSpec());
 763    } catch (CasDBException exp) {
 764  0 String errMesg =
 765    i18n.getMessage("retrErr",
 766    "service mapping");
 767  0 logger.error(errMesg, exp);
 768  0 throw CasService.makeFault(baseErrMsg + errMesg
 769    + exp.getMessage(),exp);
 770   
 771    }
 772    // FIXME add check for tokenizer failing, just in case!
 773  0 StringTokenizer str =
 774    new StringTokenizer
 775    (serviceInfo,
 776    CasConstants.SERVICEACTION_DELIMITER);
 777  0 try {
 778  0 SAMLAction authzAction =
 779    new SAMLAction(str.nextToken(),
 780    str.nextToken());
 781  0 authzActions.add(authzAction);
 782    }
 783    catch (SAMLException exp) {
 784  0 String errMesg = i18n.getMessage("samlActionErr");
 785  0 logger.error(errMesg, exp);
 786  0 throw CasService.makeFault(baseErrMsg + errMesg
 787    + exp.getMessage(),exp);
 788    }
 789    }
 790   
 791  0 String currentVectorResource = null;
 792  0 try {
 793  0 if (resourceWildcard) {
 794  0 currentVectorResource = ObjectDataHandler
 795    .getObjectDescription(policyData
 796    .getObjectSpec());
 797    } else {
 798    // all assertions should only be onr
 799    // requested object irrespective of what
 800    // policy object it matched on. For wild
 801    // card scenarios, that object may not
 802    // exist in database, so use the resource
 803    // string provided.
 804  0 currentVectorResource = resource;
 805    }
 806    } catch (CasDBException exp) {
 807  0 String errMesg = i18n.getMessage("retrErr",
 808    "Object description");
 809  0 logger.error(errMesg, exp);
 810  0 throw CasService.makeFault(baseErrMsg + errMesg
 811    + exp.getMessage(),exp);
 812    }
 813    // Construct stmt. One per resource is created.
 814  0 SAMLAuthorizationDecisionStatement samlAuthzDecisionStmt =
 815    null;
 816  0 if (samlDecisionStmtVector == null) {
 817  0 samlDecisionStmtVector = new Vector();
 818    }
 819  0 SAMLSubject receivedSubject = samlQuery.getSubject();
 820  0 logger.debug("Adding SAML authz with subject "
 821    + receivedSubject);
 822  0 logger.debug("SAML Authz for resource "
 823    + currentVectorResource);
 824  0 try {
 825  0 samlAuthzDecisionStmt =
 826    new SAMLAuthorizationDecisionStatement(
 827    receivedSubject, currentVectorResource,
 828    CasConstants.SAML_DECISION,
 829    authzActions, null);
 830    }
 831    catch (SAMLException exp) {
 832  0 logger.error(baseErrMsg, exp);
 833  0 throw CasService.makeFault(baseErrMsg + "\n"
 834    + exp.getMessage(), exp);
 835    }
 836  0 logger.debug("SAML Authz stmt is "
 837    + samlAuthzDecisionStmt);
 838  0 samlDecisionStmtVector.add(samlAuthzDecisionStmt);
 839    }
 840    }
 841    }
 842  0 return samlDecisionStmtVector;
 843    }
 844   
 845    // Returns credential
 846  0 private GlobusGSSCredentialImpl getServerCredential() throws CasFault {
 847   
 848  0 Subject subject = null;
 849  0 try {
 850  0 subject = SecurityManager.getManager()
 851    .getServiceSubject(CasConstants.SERVICE_NAME);
 852    } catch (SecurityException exp) {
 853  0 String err = i18n.getMessage("serverSubErr");
 854  0 logger.error(err, exp);
 855  0 throw CasService.makeFault(err, exp);
 856    }
 857  0 if (subject == null) {
 858  0 logger.debug("Subject is null");
 859    }
 860   
 861  0 GlobusGSSCredentialImpl credential =
 862    (GlobusGSSCredentialImpl)JaasGssUtil.getCredential(subject);
 863   
 864  0 if (credential == null) {
 865  0 String errMesg = i18n.getMessage("noCredFound");
 866  0 logger.error(errMesg);
 867  0 throw CasService.makeFault(errMesg);
 868    }
 869  0 return credential;
 870    }
 871   
 872  0 private String getUserNickname(String userDN, String issuerDN,
 873    String authMethod)
 874    throws CasFault {
 875    /* FIXME Uncomment when caller's issuer's DN can be extracted
 876    so that all calls expects userDN and issuerDN
 877    try {
 878    String nickname =
 879    TrustAnchorDataHandler.getNickname(issuerDN, authMethod);
 880    if (nickname == null) {
 881    String err = "Trust anchor with " + issuerDN + " and "
 882    + authMethod + " not on CAS server";
 883    logger.error(err);
 884    throw (CasFault)FaultHelper.makeFault(CasFault.class, err);
 885    }
 886    */
 887  0 try {
 888  0 String userNick =
 889    UserDataHandler.getUserNickname(userDN);
 890  0 if (userNick == null) {
 891  0 String err = i18n.getMessage("retrUserNickErr", userDN);
 892  0 logger.error(err);
 893  0 throw CasService.makeFault(err);
 894    }
 895  0 return userNick;
 896    } catch (CasDBException exp) {
 897  0 String errMesg = i18n.getMessage("retrErr", "user data");
 898  0 logger.error(errMesg + exp.toString());
 899  0 throw CasService.makeFault(errMesg + exp.getMessage(), exp);
 900    }
 901    }
 902   
 903   
 904    // Returns certs if it exists, else null
 905  0 private Vector getCertificates(GlobusGSSCredentialImpl credential) {
 906   
 907  0 X509Certificate[] certArray = credential.getCertificateChain();
 908  0 Vector certs = null;
 909  0 if (certArray.length > 0) {
 910  0 certs = new Vector(certArray.length);
 911  0 for (int i=0; i<certArray.length; i++) {
 912  0 certs.add(certArray[i]);
 913    }
 914    }
 915  0 return certs;
 916    }
 917   
 918    // Returns DN of CA
 919  0 private String getDNofServerCA(GlobusGSSCredentialImpl credential)
 920    throws CasFault {
 921   
 922  0 Vector certs = getCertificates(credential);
 923  0 if (certs == null) {
 924  0 String errMesg = i18n.getMessage("certNotFound");
 925  0 logger.error(errMesg);
 926  0 throw CasService.makeFault(errMesg);
 927    }
 928  0 X509Certificate caCert = (X509Certificate)certs.get(certs.size()-1);
 929  0 return caCert.getIssuerDN().getName();
 930    }
 931   
 932  0 private void checkQueryPermissions(String userName, String baseErrMsg)
 933    throws NoPermissionFault, CasFault {
 934  0 try {
 935  0 if (!PermissionsHandler.canQuery(userName)) {
 936  0 String er = i18n.getMessage("noPermErr", userName);
 937  0 logger.error(er);
 938  0 throw new NoPermissionFault(baseErrMsg + er);
 939    }
 940    }
 941    catch (CasDBException exp) {
 942  0 logger.error(baseErrMsg, exp);
 943  0 throw CasService.makeFault(baseErrMsg + exp.getMessage(), exp);
 944    }
 945    }
 946    }