Back to index

nordugrid-arc-nox  1.1.0~rc6
Public Member Functions | Static Public Member Functions | Protected Member Functions | Private Member Functions | Private Attributes | Static Private Attributes | Friends
ArcSec::ArcEvaluator Class Reference

Execute the policy evaluation, based on the request and policy. More...

#include <ArcEvaluator.h>

Inheritance diagram for ArcSec::ArcEvaluator:
Inheritance graph
[legend]
Collaboration diagram for ArcSec::ArcEvaluator:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 ArcEvaluator (Arc::XMLNode *cfg)
 ArcEvaluator (const char *cfgfile)
virtual ~ArcEvaluator ()
virtual Responseevaluate (Request *request)
 Evaluate the request based on the policy information inside PolicyStore.
virtual Responseevaluate (const Source &request)
 Evaluates the request by using a specified source.
virtual Responseevaluate (Request *request, const Source &policy)
 Evaluate the specified request against the policy from specified source.
virtual Responseevaluate (const Source &request, const Source &policy)
 Evaluate the request from specified source against the policy from specified source.
virtual Responseevaluate (Request *request, Policy *policyobj)
 Evaluate the specified request against the specified policy.
virtual Responseevaluate (const Source &request, Policy *policyobj)
 Evaluate the request from specified source against the specified policy.
virtual AttributeFactorygetAttrFactory ()
 Get the AttributeFactory object.
virtual FnFactorygetFnFactory ()
 Get the FnFactory object.
virtual AlgFactorygetAlgFactory ()
 Get the AlgFactory object.
virtual void addPolicy (const Source &policy, const std::string &id="")
 Add policy from specified source to the evaluator.
virtual void addPolicy (Policy *policy, const std::string &id="")
 Add policy to the evaluator.
virtual void removePolicies (void)
virtual void setCombiningAlg (EvaluatorCombiningAlg alg)
 Specifies one of simple combining algorithms.
virtual void setCombiningAlg (CombiningAlg *alg)
 Specifies loadable combining algorithms.
virtual const char * getName (void) const
 Get the name of this evaluator.

Static Public Member Functions

static Arc::Pluginget_evaluator (Arc::PluginArgument *arg)

Protected Member Functions

virtual Responseevaluate (EvaluationCtx *ctx)
 Evaluate the request by using the EvaluationCtx object (which includes the information about request).

Private Member Functions

virtual void parsecfg (Arc::XMLNode &cfg)
 Parse the configuration, and dynamically create PolicyStore, AttributeFactory, FnFactory and AlgFactoryy.
virtual Requestmake_reqobj (Arc::XMLNode &reqnode)

Private Attributes

PolicyStoreplstore
FnFactoryfnfactory
AttributeFactoryattrfactory
AlgFactoryalgfactory
EvaluatorContextcontext
Arc::XMLNodem_cfg
std::string request_classname
EvaluatorCombiningAlg combining_alg
CombiningAlgcombining_alg_ex

Static Private Attributes

static Arc::Logger logger

Friends

class EvaluatorContext

Detailed Description

Execute the policy evaluation, based on the request and policy.

Definition at line 20 of file ArcEvaluator.h.


Constructor & Destructor Documentation

Definition at line 129 of file ArcEvaluator.cpp.

                                          : Evaluator(cfg), m_cfg(cfg) {
  plstore = NULL;;
  fnfactory = NULL;
  attrfactory = NULL;
  algfactory = NULL;
  combining_alg = EvaluatorFailsOnDeny;
  combining_alg_ex = NULL;
  context = NULL;

  parsecfg(*m_cfg);
}

Here is the call graph for this function:

Here is the caller graph for this function:

ArcEvaluator::ArcEvaluator ( const char *  cfgfile)

Definition at line 141 of file ArcEvaluator.cpp.

                                               : Evaluator(cfgfile){
  combining_alg = EvaluatorFailsOnDeny;
  combining_alg_ex = NULL;
  std::string str;
  std::string xml_str = "";
  std::ifstream f(cfgfile);
  while (f >> str) {
    xml_str.append(str);
    xml_str.append(" ");
  }
  f.close();

  Arc::XMLNode node(xml_str);
  parsecfg(node); 
}

Here is the call graph for this function:

Definition at line 430 of file ArcEvaluator.cpp.

                           {
  //TODO delete all the object
  if(plstore)
    delete plstore;
  if(context)
    delete context;
  if(fnfactory)
    delete fnfactory;
  if(attrfactory)
    delete attrfactory;
  if(algfactory)
    delete algfactory;
}

Member Function Documentation

virtual void ArcSec::ArcEvaluator::addPolicy ( const Source policy,
const std::string &  id = "" 
) [inline, virtual]

Add policy from specified source to the evaluator.

Policy will be marked with id.

Implements ArcSec::Evaluator.

Definition at line 56 of file ArcEvaluator.h.

                                                                        {
    plstore->addPolicy(policy, context, id);
  };

Here is the call graph for this function:

virtual void ArcSec::ArcEvaluator::addPolicy ( Policy policy,
const std::string &  id = "" 
) [inline, virtual]

Add policy to the evaluator.

Policy will be marked with id. The policy object is taken over by this instance and will be destroyed in destructor.

Implements ArcSec::Evaluator.

Definition at line 60 of file ArcEvaluator.h.

                                                                  {
    plstore->addPolicy(policy, context, id);
  };

Here is the call graph for this function:

Response * ArcEvaluator::evaluate ( Request request) [virtual]

Evaluate the request based on the policy information inside PolicyStore.

Implements ArcSec::Evaluator.

Definition at line 182 of file ArcEvaluator.cpp.

                                                {
  Request* req = request;
  req->setAttributeFactory(attrfactory);
  req->make_request();

  EvaluationCtx * evalctx = NULL;
  evalctx =  new ArcEvaluationCtx(req);

  //evaluate the request based on policy
  if(evalctx)
    return evaluate(evalctx);
  return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Response * ArcEvaluator::evaluate ( const Source request) [virtual]

Evaluates the request by using a specified source.

Implements ArcSec::Evaluator.

Definition at line 197 of file ArcEvaluator.cpp.

                                                 {
  //0.Prepare request for evaluation
  Arc::XMLNode node = req.Get();
  NS ns;
  ns["ra"]="http://www.nordugrid.org/schemas/request-arc";
  node.Namespaces(ns);

  //1.Create the request object according to the configuration
  Request* request = make_reqobj(node);
  if(request == NULL) return NULL;
  
  //2.Pre-process the Request object
  request->setAttributeFactory(attrfactory);
  request->make_request();
  
  EvaluationCtx * evalctx = new ArcEvaluationCtx(request);
  
  //3.evaluate the request based on policy
  Response* resp = evaluate(evalctx);

  delete request;

  return resp;
}

Here is the call graph for this function:

Response * ArcEvaluator::evaluate ( Request request,
const Source policy 
) [virtual]

Evaluate the specified request against the policy from specified source.

In some implementations all of the existing policies inside the evaluator may be destroyed by this method.

Implements ArcSec::Evaluator.

Definition at line 394 of file ArcEvaluator.cpp.

                                                                       {
  plstore->removePolicies();
  plstore->addPolicy(policy, context, "");
  Response* resp = evaluate(request);
  plstore->removePolicies();
  return resp;
}

Here is the call graph for this function:

Response * ArcEvaluator::evaluate ( const Source request,
const Source policy 
) [virtual]

Evaluate the request from specified source against the policy from specified source.

In some implementations all of the existing policie inside the evaluator may be destroyed by this method.

Implements ArcSec::Evaluator.

Definition at line 402 of file ArcEvaluator.cpp.

                                                                            {
  plstore->removePolicies();
  plstore->addPolicy(policy, context, "");
  Response* resp = evaluate(request);
  plstore->removePolicies();
  return resp;
}

Here is the call graph for this function:

Response * ArcEvaluator::evaluate ( Request request,
Policy policyobj 
) [virtual]

Evaluate the specified request against the specified policy.

In some implementations all of the existing policy inside the evaluator may be destroyed by this method.

Implements ArcSec::Evaluator.

Definition at line 410 of file ArcEvaluator.cpp.

                                                                    {
  plstore->removePolicies();
  plstore->addPolicy(policyobj, context, "");
  Response* resp = evaluate(request);
  plstore->releasePolicies();
  return resp;
}

Here is the call graph for this function:

Response * ArcEvaluator::evaluate ( const Source request,
Policy policyobj 
) [virtual]

Evaluate the request from specified source against the specified policy.

In some implementations all of the existing policie inside the evaluator may be destroyed by this method.

Implements ArcSec::Evaluator.

Definition at line 418 of file ArcEvaluator.cpp.

                                                                         {
  plstore->removePolicies();
  plstore->addPolicy(policyobj, context, "");
  Response* resp = evaluate(request);
  plstore->releasePolicies();
  return resp;
}

Here is the call graph for this function:

Response * ArcEvaluator::evaluate ( EvaluationCtx ctx) [protected, virtual]

Evaluate the request by using the EvaluationCtx object (which includes the information about request).

The ctx is destroyed inside this method (why?!?!?).

Implements ArcSec::Evaluator.

Definition at line 223 of file ArcEvaluator.cpp.

                                                      {
  if(!evl_ctx) return NULL;
  //Split request into <subject, action, object, environment> tuples
  ArcEvaluationCtx* ctx = dynamic_cast<ArcEvaluationCtx*>(evl_ctx);
  if(!ctx) {
    delete evl_ctx;
    return NULL;
  }
  ctx->split();
  
  std::list<PolicyStore::PolicyElement> policies;
  std::list<PolicyStore::PolicyElement>::iterator policyit;
  std::list<RequestTuple*> reqtuples = ctx->getRequestTuples();
  std::list<RequestTuple*>::iterator it;
  
  Response* resp = new Response();
  resp->setRequestSize(reqtuples.size());
  for(it = reqtuples.begin(); it != reqtuples.end(); it++){
    //set the current RequestTuple for evaluation
    //RequestTuple will be evaluated one by one
    ctx->setEvalTuple(*it);

    policies = plstore->findPolicy(ctx);

    std::list<PolicyStore::PolicyElement> permitset;
    
    if(!combining_alg) {

    bool atleast_onepermit = false;
    bool atleast_onedeny = false;
    bool atleast_onenotapplicable = false;
    bool atleast_oneindeterminate = false;
    Result result = DECISION_NOT_APPLICABLE;

    //Each policy evaluates the present RequestTuple, using default combiningalg between <Policy>s: PERMIT-OVERRIDES
    for(policyit = policies.begin(); policyit != policies.end(); policyit++){
      Result res = ((Policy*)(*policyit))->eval(ctx);

      logger.msg(INFO,"Result value (0=Permit, 1=Deny, 2=Indeterminate, 3=Not_Applicable): %d", res);

      if(combining_alg == EvaluatorStopsOnDeny) {
        if(res == DECISION_PERMIT){
          permitset.push_back(*policyit);
          atleast_onepermit = true;
        }
       else if(res == DECISION_DENY) {
          atleast_onedeny = true; 
          break;
        }
        else if(res == DECISION_INDETERMINATE)
          atleast_oneindeterminate = true;
        else if(res == DECISION_NOT_APPLICABLE)
          atleast_onenotapplicable = true;

      } else if(combining_alg == EvaluatorStopsOnPermit) {
        if(res == DECISION_PERMIT){
          permitset.push_back(*policyit);
          atleast_onepermit = true;
          break;
        }
        else if(res == DECISION_DENY)
          atleast_onedeny = true;
        else if(res == DECISION_INDETERMINATE)
          atleast_oneindeterminate = true;
        else if(res == DECISION_NOT_APPLICABLE)
          atleast_onenotapplicable = true;

      } else if(combining_alg == EvaluatorStopsNever) {
        if(res == DECISION_PERMIT){
          permitset.push_back(*policyit);
          atleast_onepermit = true;
        }
        else if(res == DECISION_DENY) 
          atleast_onedeny = true;
        else if(res == DECISION_INDETERMINATE)
          atleast_oneindeterminate = true;
        else if(res == DECISION_NOT_APPLICABLE)
          atleast_onenotapplicable = true;

      } else { // EvaluatorFailsOnDeny
        //If there is one policy gives negative evaluation result, then jump out
        //For RequestTuple which is denied, we will not feedback any information so far
        if(res == DECISION_PERMIT){
          permitset.push_back(*policyit);
          atleast_onepermit = true;
        } 
        else if (res == DECISION_DENY) {
          atleast_onedeny = true;
          permitset.clear();
          break;
        }
        else if(res == DECISION_INDETERMINATE)
          atleast_oneindeterminate = true;
        else if(res == DECISION_NOT_APPLICABLE)
          atleast_onenotapplicable = true;
      };
    }

    //The decision for this RequestTuple is recorded. Here the algorithm is Permit-Overides,
    //if any policy gives "Permit", the result is "Permit";
    //if no policy gives "Permit", and any policy gives "Deny", the result is "Deny"; 
    //if no policy gives "Permit", no policy gives "Deny", 
    if(atleast_onepermit == true) result = DECISION_PERMIT;
    else if(atleast_onepermit == false && atleast_onedeny ==true) result = DECISION_DENY;
    else if(atleast_onepermit == false && atleast_onedeny ==false && atleast_oneindeterminate == true) result = DECISION_INDETERMINATE;
    else if(atleast_onepermit == false && atleast_onedeny ==false && atleast_oneindeterminate == false && 
            atleast_onenotapplicable == true) result = DECISION_NOT_APPLICABLE;


    ResponseItem* item = new ResponseItem;
    ArcRequestTuple* reqtuple = new ArcRequestTuple;
    reqtuple->duplicate(*it);

    item->reqtp = reqtuple;
    item->reqxml = reqtuple->getNode();
    item->res = result;

    //For RequestTuple that passes the evaluation check, fill the information into ResponseItem
    if(atleast_onepermit){
      std::list<PolicyStore::PolicyElement>::iterator permit_it;
      for(permit_it = permitset.begin(); permit_it != permitset.end(); permit_it++){
        item->pls.push_back((Policy*)(*permit_it));
        EvalResult evalres = ((Policy*)(*permit_it))->getEvalResult();
        //TODO, handle policyset
        XMLNode policyxml = evalres.node;
        (item->plsxml).push_back(policyxml);
      }
    }
    //Store the ResponseItem
    resp->addResponseItem(item);
    
    } else { // if(combining_alg_ex)
      // Now if real combining algorithm defined use it instead
      // of hardcoded mess above.
      std::list<Policy*> plist;
      // Preparing list of policies to evaluate
      for(policyit = policies.begin(); policyit != policies.end(); policyit++){
        plist.push_back((Policy*)(*policyit));
      };
      // Running request tuple and policies through evaluator 
      // and combining results 
      // TODO: record permitset (is it really needed?)
      Result result = combining_alg_ex->combine(ctx,plist);
      ResponseItem* item = new ResponseItem;
      ArcRequestTuple* reqtuple = new ArcRequestTuple;
//      reqtuple->duplicate((ArcRequestTuple*)(*it));
      reqtuple->duplicate(*it);
      item->reqtp = reqtuple;
      item->reqxml = reqtuple->getNode();
      item->res = result;
      // Recording positive response - not implemented yet
      //if(result == DECISION_PERMIT) {
      //  std::list<PolicyStore::PolicyElement>::iterator permit_it;
      //  for(pit = permitset.begin(); pit != permitset.end(); pit++){
      //    item->pls.push_back((Policy*)(*pit));
      //    EvalResult evalres = ((Policy*)(*pit))->getEvalResult();
      //    //TODO, handle policyset
      //    XMLNode policyxml = evalres.node;
      //    (item->plsxml).push_back(policyxml);
      //  }
      //}
      //Store the ResponseItem
      resp->addResponseItem(item);
    }
  }

  delete evl_ctx; 

  return resp;
}

Here is the call graph for this function:

Definition at line 16 of file ArcEvaluator.cpp.

                                                                   {
    Arc::ClassLoaderPluginArgument* clarg =
            arg?dynamic_cast<Arc::ClassLoaderPluginArgument*>(arg):NULL;
    if(!clarg) return NULL;
    return new ArcSec::ArcEvaluator((Arc::XMLNode*)(*clarg));
}

Here is the call graph for this function:

virtual AlgFactory* ArcSec::ArcEvaluator::getAlgFactory ( ) [inline, virtual]

Get the AlgFactory object.

Implements ArcSec::Evaluator.

Definition at line 54 of file ArcEvaluator.h.

{ return algfactory; };

Get the AttributeFactory object.

Implements ArcSec::Evaluator.

Definition at line 52 of file ArcEvaluator.h.

{ return attrfactory;};
virtual FnFactory* ArcSec::ArcEvaluator::getFnFactory ( ) [inline, virtual]

Get the FnFactory object.

Implements ArcSec::Evaluator.

Definition at line 53 of file ArcEvaluator.h.

{ return fnfactory; };
const char * ArcEvaluator::getName ( void  ) const [virtual]

Get the name of this evaluator.

Implements ArcSec::Evaluator.

Definition at line 426 of file ArcEvaluator.cpp.

                                            {
  return "arc.evaluator";
}
Request * ArcEvaluator::make_reqobj ( Arc::XMLNode reqnode) [private, virtual]

Definition at line 165 of file ArcEvaluator.cpp.

                                                  {
  Request* request = NULL;
  std::string requestor;

  Arc::ClassLoader* classloader = NULL;
  //Since the configuration information for loader has been got before (when create ArcEvaluator), 
  //it is not necessary to get once more here
  classloader = ClassLoader::getClassLoader();

  //Load the Request object
  request = (ArcSec::Request*)(classloader->Instance(request_classname,&reqnode));
  if(request == NULL)
    logger.msg(Arc::ERROR, "Can not dynamically produce Request");

  return request;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void ArcEvaluator::parsecfg ( Arc::XMLNode cfg) [private, virtual]

Parse the configuration, and dynamically create PolicyStore, AttributeFactory, FnFactory and AlgFactoryy.

Implements ArcSec::Evaluator.

Definition at line 33 of file ArcEvaluator.cpp.

                                          {
  std::string policystore, policylocation, functionfactory, attributefactory, combingalgfactory;
  XMLNode nd;

  Arc::NS nsList;
  std::list<XMLNode> res;
  nsList.insert(std::pair<std::string, std::string>("pdp","http://www.nordugrid.org/schemas/pdp/Config"));
  
  //Get the name of "PolicyStore" class
  //res = cfg.XPathLookup("//pdp:PolicyStore", nsList);
  //presently, there can be only one PolicyStore
  //if(!(res.empty())){
  //  nd = *(res.begin());
  //  policystore = (std::string)(nd.Attribute("name"));
  //  policylocation =  (std::string)(nd.Attribute("location"));
  //}
  //else if (res.empty()){ 
  //  logger.msg(ERROR, "No any policy exists, the policy engine can not be loaded");
  //  exit(1);
  //}

  //Get the name of "FunctionFactory" class
  res = cfg.XPathLookup("//pdp:FunctionFactory", nsList);
  if(!(res.empty())){
    nd = *(res.begin());
    functionfactory = (std::string)(nd.Attribute("name"));
  } 
  else { logger.msg(ERROR, "Can not parse classname for FunctionFactory from configuration"); return;}
          
  //Get the name of "AttributeFactory" class
  res = cfg.XPathLookup("//pdp:AttributeFactory", nsList);
  if(!(res.empty())){
    nd = *(res.begin());
    attributefactory = (std::string)(nd.Attribute("name"));
  }  
  else { logger.msg(ERROR, "Can not parse classname for AttributeFactory from configuration"); return;}

  //Get the name of "CombiningAlgorithmFactory" class
  res = cfg.XPathLookup("//pdp:CombingAlgorithmFactory", nsList);
  if(!(res.empty())){
    nd = *(res.begin());
    combingalgfactory = (std::string)(nd.Attribute("name"));
  }
  else { logger.msg(ERROR, "Can not parse classname for CombiningAlgorithmFactory from configuration"); return;}

  //Get the name of the "Request" class
  res = m_cfg->XPathLookup("//pdp:Request", nsList);
  if(!(res.empty())){
    nd = *(res.begin());
    request_classname = (std::string)(nd.Attribute("name"));
  }
  else { logger.msg(ERROR, "Can not parse classname for Request from configuration"); return;}

  //Get the name of the "Policy" class
  std::string policy_classname;
  res = m_cfg->XPathLookup("//pdp:Policy", nsList);
  if(!(res.empty())){
    nd = *(res.begin());
    policy_classname = (std::string)(nd.Attribute("name"));
  }
  else { logger.msg(ERROR, "Can not parse classname for Policy from configuration"); return;}

  //Get the ClassLoader object; The object which loads this ArcEvaluator should have 
  //constructed ClassLoader by using ClassLoader(cfg), and putting the configuration 
  //information into it; meanwhile ClassLoader is designed as a Singleton, so here 
  //we don't need to intialte ClassLoader by using ClassLoader(cfg);
  ClassLoader* classloader;
  classloader=ClassLoader::getClassLoader();

  attrfactory=NULL;
  attrfactory = (AttributeFactory*)(classloader->Instance(attributefactory));
  if(attrfactory == NULL)
    logger.msg(ERROR, "Can not dynamically produce AttributeFactory");

  fnfactory=NULL;
  fnfactory = (FnFactory*)(classloader->Instance(functionfactory));
  if(fnfactory == NULL)
    logger.msg(ERROR, "Can not dynamically produce FnFactory");

  algfactory=NULL;
  algfactory = (AlgFactory*)(classloader->Instance(combingalgfactory));
  if(algfactory == NULL)
    logger.msg(ERROR, "Can not dynamically produce AlgFacroty");

  //Create the EvaluatorContext for the usage of creating Policy
  context = new EvaluatorContext(this);

  std::string alg("Permit-Overrides");
  //std::list<std::string> filelist;
  //filelist.push_back(policylocation);
  //plstore = new PolicyStore(filelist, alg, policy_classname, context);
  plstore = new PolicyStore(alg, policy_classname, context);
  if(plstore == NULL)
    logger.msg(ERROR, "Can not create PolicyStore object");
}

Here is the call graph for this function:

Here is the caller graph for this function:

virtual void ArcSec::ArcEvaluator::removePolicies ( void  ) [inline, virtual]

Definition at line 64 of file ArcEvaluator.h.

Here is the call graph for this function:

Specifies one of simple combining algorithms.

In case of multiple policies their results will be combined using this algorithm.

Implements ArcSec::Evaluator.

Definition at line 157 of file ArcEvaluator.cpp.

                                                            {
  combining_alg = alg;
}
void ArcEvaluator::setCombiningAlg ( CombiningAlg alg) [virtual]

Specifies loadable combining algorithms.

In case of multiple policies their results will be combined using this algorithm. To switch to simple algorithm specify NULL argument.

Implements ArcSec::Evaluator.

Definition at line 161 of file ArcEvaluator.cpp.

                                                    {
  combining_alg_ex = alg;
}

Friends And Related Function Documentation

friend class EvaluatorContext [friend]

Definition at line 21 of file ArcEvaluator.h.


Member Data Documentation

Definition at line 27 of file ArcEvaluator.h.

Definition at line 26 of file ArcEvaluator.h.

Definition at line 34 of file ArcEvaluator.h.

Definition at line 36 of file ArcEvaluator.h.

Definition at line 29 of file ArcEvaluator.h.

Definition at line 25 of file ArcEvaluator.h.

Reimplemented from ArcSec::Evaluator.

Definition at line 23 of file ArcEvaluator.h.

Definition at line 31 of file ArcEvaluator.h.

Definition at line 24 of file ArcEvaluator.h.

Definition at line 32 of file ArcEvaluator.h.


The documentation for this class was generated from the following files: