void xacml_response_delete(xacml_response_t * response) { if (response == NULL) return; if (response->request != NULL) xacml_request_delete(response->request); llist_delete_elements(response->results,(delete_element_func)xacml_result_delete); llist_delete(response->results); free(response); response= NULL; }
int xacml_response_setrequest(xacml_response_t * response, xacml_request_t * request) { if (response == NULL || request == NULL) { log_error("xacml_response_setrequest: NULL response or request."); return PEP_XACML_ERROR; } if (response->request != NULL) xacml_request_delete(response->request); response->request= request; return PEP_XACML_OK; }
pep_error_t pep_authorize(PEP * pep, xacml_request_t ** request, xacml_response_t ** response) { int i= 0; int pip_rc, oh_rc; //pep_buffer_t * output, * b64output, * b64input, * input; size_t output_l, b64output_l; pep_error_t marshal_rc, unmarshal_rc; CURLcode curl_rc; long http_code= 0; xacml_request_t * effective_request; if (pep == NULL) { pep_log_error("pep_authorize: NULL pep handle"); return PEP_ERR_NULL_POINTER; } if (pep->option_endpoint_url == NULL) { pep_log_error("pep_authorize: NULL mandatory option PEP_OPTION_ENDPOINT_URL"); return PEP_ERR_NULL_POINTER; } if (request == NULL || *request == NULL) { pep_log_error("pep_authorize: PEP#%d NULL request pointer",pep->id); return PEP_ERR_NULL_POINTER; } /* apply pips if enabled and any */ if (pep->option_pips_enabled && pep_llist_length(pep->pips) > 0) { size_t pips_l= pep_llist_length(pep->pips); pep_log_info("pep_authorize: PEP#%d %d PIPs available, processing...",pep->id, (int)pips_l); for (i= 0; i<pips_l; i++) { pep_pip_t * pip= pep_llist_get(pep->pips,i); if (pip != NULL) { pep_log_debug("pep_authorize: PEP#%d calling pip[%s]->process(request)...",pep->id,pip->id); pip_rc= pip->process(request); if (pip_rc != 0) { pep_log_error("pep_authorize: PIP[%s] process(request) failed: %d", pip->id, pip_rc); return PEP_ERR_PIP_PROCESS; } } } } /* marshal the authorization request into output buffer */ pep->output= pep_buffer_create(512); if (pep->output == NULL) { pep_log_error("pep_authorize: PEP#%d can't create output buffer (512 bytes).",pep->id); return PEP_ERR_MEMORY; } marshal_rc= xacml_request_marshalling(*request,pep->output); if ( marshal_rc != PEP_OK ) { pep_log_error("pep_authorize: PEP#%d can't marshal XACML request: %s.",pep->id,pep_strerror(marshal_rc)); pep_buffer_delete(pep->output); return marshal_rc; } /* base64 encode the output buffer */ output_l= pep_buffer_length(pep->output); pep->b64output= pep_buffer_create( output_l ); if (pep->b64output == NULL) { pep_log_error("pep_authorize: PEP#%d can't create base64 output buffer (%d bytes).",pep->id,(int)output_l); pep_buffer_delete(pep->output); return PEP_ERR_MEMORY; } pep_log_debug("pep_authorize: PEP#%d: encoding base64 output...",pep->id); pep_base64_encode_buffer_l(pep->output,pep->b64output,BASE64_DEFAULT_LINE_SIZE); /* output buffer not needed anymore. */ pep_buffer_delete(pep->output); /* configure curl handler to POST the base64 encoded marshalled PEP request buffer */ curl_rc= curl_easy_setopt(pep->curl, CURLOPT_POST, 1L); if (curl_rc != CURLE_OK) { pep_log_error("pep_authorize: PEP#%d curl_easy_setopt(curl,CURLOPT_POST,1) failed: %s.",pep->id,curl_easy_strerror(curl_rc)); pep_buffer_delete(pep->b64output); return PEP_ERR_CURL + curl_rc; } b64output_l= pep_buffer_length(pep->b64output); curl_rc= curl_easy_setopt(pep->curl, CURLOPT_POSTFIELDSIZE, (long)b64output_l); if (curl_rc != CURLE_OK) { pep_log_error("pep_authorize: PEP#%d curl_easy_setopt(curl,CURLOPT_POSTFIELDSIZE,%d) failed: %s.",pep->id,(int)b64output_l,curl_easy_strerror(curl_rc)); pep_buffer_delete(pep->b64output); return PEP_ERR_CURL + curl_rc; } curl_rc= curl_easy_setopt(pep->curl, CURLOPT_READDATA, pep->b64output); if (curl_rc != CURLE_OK) { pep_log_error("pep_authorize: PEP#%d curl_easy_setopt(curl,CURLOPT_READDATA,b64output) failed: %s.",pep->id,curl_easy_strerror(curl_rc)); pep_buffer_delete(pep->b64output); return PEP_ERR_CURL + curl_rc; } curl_rc= curl_easy_setopt(pep->curl, CURLOPT_READFUNCTION, pep_buffer_read); if (curl_rc != CURLE_OK) { pep_log_error("pep_authorize: PEP#%d curl_easy_setopt(curl,CURLOPT_READFUNCTION,buffer_read) failed: %s.",pep->id,curl_easy_strerror(curl_rc)); pep_buffer_delete(pep->b64output); return PEP_ERR_CURL + curl_rc; } /* configure curl handler to read the base64 encoded HTTP response */ pep->b64input= pep_buffer_create(1024); if (pep->b64input == NULL) { pep_log_error("pep_authorize: PEP#%d can't create base64 input buffer.",pep->id); pep_buffer_delete(pep->b64output); return PEP_ERR_MEMORY; } curl_rc= curl_easy_setopt(pep->curl, CURLOPT_WRITEDATA, pep->b64input); if (curl_rc != CURLE_OK) { pep_log_error("pep_authorize: PEP#%d curl_easy_setopt(curl,CURLOPT_WRITEDATA,b64input) failed: %s.",pep->id,curl_easy_strerror(curl_rc)); pep_buffer_delete(pep->b64output); pep_buffer_delete(pep->b64input); return PEP_ERR_CURL + curl_rc; } curl_rc= curl_easy_setopt(pep->curl, CURLOPT_WRITEFUNCTION, pep_buffer_write); if (curl_rc != CURLE_OK) { pep_log_error("pep_authorize: PEP#%d curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,buffer_write) failed: %s.",pep->id,curl_easy_strerror(curl_rc)); pep_buffer_delete(pep->b64output); pep_buffer_delete(pep->b64input); return PEP_ERR_CURL + curl_rc; } /* send the request */ pep_log_info("pep_authorize: PEP#%d sending XACML request to: %s",pep->id,pep->option_endpoint_url); curl_rc= curl_easy_perform(pep->curl); if (curl_rc != CURLE_OK) { pep_log_error("pep_authorize: PEP#%d sending XACML request to %s failed: curl[%d] %s.",pep->id,pep->option_endpoint_url,(int)curl_rc,curl_easy_strerror(curl_rc)); pep_buffer_delete(pep->b64output); pep_buffer_delete(pep->b64input); return PEP_ERR_CURL + curl_rc; } /* check for HTTP 200 response code */ http_code= 0; curl_rc= curl_easy_getinfo(pep->curl,CURLINFO_RESPONSE_CODE,&http_code); if (curl_rc != CURLE_OK) { pep_log_error("pep_authorize: PEP#%d curl_easy_getinfo(pep->curl,CURLINFO_RESPONSE_CODE,&http_code) failed: %s.",pep->id,curl_easy_strerror(curl_rc)); pep_buffer_delete(pep->b64output); pep_buffer_delete(pep->b64input); return PEP_ERR_CURL + curl_rc; } if (http_code != 200) { pep_log_error("pep_authorize: PEP#%d: HTTP status code: %d.",pep->id,(int)http_code); pep_buffer_delete(pep->b64output); pep_buffer_delete(pep->b64input); return PEP_ERR_AUTHZ_REQUEST; } /* not required anymore */ pep_buffer_delete(pep->b64output); pep_log_debug("pep_authorize: PEP#%d: HTTP status code: %d.",pep->id,(int)http_code); /* create the Hessian input buffer */ pep->input= pep_buffer_create(1024); if (pep->input == NULL) { pep_log_error("pep_authorize: PEP#%d can't create input buffer.",pep->id); pep_buffer_delete(pep->b64input); return PEP_ERR_MEMORY; } /* base64 decode the input buffer into the Hessian buffer. */ pep_log_debug("pep_authorize: PEP#%d: decoding base64 input...",pep->id); pep_base64_decode_buffer(pep->b64input,pep->input); /* unmarshal the PEP response */ unmarshal_rc= xacml_response_unmarshalling(response,pep->input); if ( unmarshal_rc != PEP_OK) { pep_log_error("pep_authorize: PEP#%d can't unmarshal the XACML response: %s.", pep->id, pep_strerror(unmarshal_rc)); pep_buffer_delete(pep->b64input); pep_buffer_delete(pep->input); return unmarshal_rc; } pep_log_info("pep_authorize: PEP#%d XACML Response decoded and deserialized.",pep->id); /* not required anymore */ pep_buffer_delete(pep->b64input); pep_buffer_delete(pep->input); /* get effective response */ effective_request= xacml_response_getrequest(*response); if (effective_request != NULL) { pep_log_debug("pep_authorize: PEP#%d effective request received",pep->id); /* delete original */ xacml_request_delete(*request); /* and replace by effective one */ *request= xacml_response_relinquishrequest(*response); } /* apply obligation handlers if enabled and any */ if (pep->option_ohs_enabled && pep_llist_length(pep->ohs) > 0) { size_t ohs_l= pep_llist_length(pep->ohs); pep_log_info("pep_authorize: PEP#%d %d OHs available, processing...",pep->id,(int)ohs_l); for (i= 0; i<ohs_l; i++) { pep_obligationhandler_t * oh= pep_llist_get(pep->ohs,i); if (oh != NULL) { pep_log_debug("pep_authorize: PEP#%d calling OH[%s]->process(request,response)...",pep->id,oh->id); oh_rc = oh->process(request,response); if (oh_rc != 0) { pep_log_error("pep_authorize: PEP#%d OH[%s] process(request,response) failed: %d.",pep->id,oh->id,oh_rc); return PEP_ERR_OH_PROCESS; } } } } return PEP_OK; }
/* * main */ int main(void) { /* Argus PEP client handle */ PEP * pep; /* functions return code */ pep_error_t pep_rc; /* PEP function error */ int rc; /* others functions */ /* XACML request and response */ xacml_request_t * request; xacml_response_t * response; char * pep_url, * subjectid, * resourceid, * actionid; /* dump library version */ fprintf(stdout,"using %s\n",pep_version()); /* create the PEP client handle */ pep= pep_initialize(); if (pep == NULL) { fprintf(stderr,"failed to create PEP client\n"); exit(1); } /* debugging options */ pep_setoption(pep,PEP_OPTION_LOG_STDERR,stderr); pep_setoption(pep,PEP_OPTION_LOG_LEVEL,PEP_LOGLEVEL_DEBUG); /* configure PEP client: PEP Server endpoint url */ pep_url= "https://chaos.switch.ch:8154/authz"; pep_rc= pep_setoption(pep,PEP_OPTION_ENDPOINT_URL,pep_url); if (pep_rc != PEP_OK) { fprintf(stderr,"failed to set PEP endpoint: %s: %s\n", pep_url, pep_strerror(pep_rc)); exit(1); } /* configure PEP client: private key and certificate required to access the PEP Server */ /* endpoint (HTTPS with client authentication) */ pep_rc= pep_setoption(pep,PEP_OPTION_ENDPOINT_CLIENT_KEY,"/etc/grid-security/hostkey.pem"); if (pep_rc != PEP_OK) { fprintf(stderr,"failed to set client key: %s: %s\n", "/etc/grid-security/hostkey.pem", pep_strerror(pep_rc)); exit(1); } pep_rc= pep_setoption(pep,PEP_OPTION_ENDPOINT_CLIENT_CERT,"/etc/grid-security/hostcert.pem"); if (pep_rc != PEP_OK) { fprintf(stderr,"failed to set client cert: %s: %s\n", "/etc/grid-security/hostcert.pem", pep_strerror(pep_rc)); exit(1); } /* server certificate CA path for validation */ pep_rc= pep_setoption(pep,PEP_OPTION_ENDPOINT_SERVER_CAPATH,"/etc/grid-security/certificates"); if (pep_rc != PEP_OK) { fprintf(stderr,"failed to set server CA path: %s: %s\n", "/etc/grid-security/certificates", pep_strerror(pep_rc)); exit(1); } /* create the XACML request */ subjectid= "CN=Valery Tschopp 9FEE5EE3,O=Switch - Teleinformatikdienste fuer Lehre und Forschung,DC=slcs,DC=switch,DC=ch"; resourceid= "switch"; actionid= "switch"; rc= create_xacml_request(&request,subjectid,resourceid,actionid); if (rc != 0) { fprintf(stderr,"failed to create XACML request\n"); exit(1); } /* submit the XACML request */ pep_rc= pep_authorize(pep,&request, &response); if (pep_rc != PEP_OK) { fprintf(stderr,"failed to authorize XACML request: %s\n", pep_strerror(pep_rc)); exit(1); } /* parse and process XACML response */ rc= process_xacml_response(response); /* delete resquest and response objs */ xacml_request_delete(request); xacml_response_delete(response); /* release the PEP client handle */ pep_destroy(pep); return 0; }
/* * MAIN * * usage: ./test-pep <URL> */ int main(int argc, char **argv) { PEP * pep; pep_error_t pep_rc; char * url= "http://localhost:8080/PEPd/authz?random"; if (argc == 2) { url= argv[1]; info("%s: using endpoint URL: %s",argv[0], url); } info("initialize PEP..."); pep= pep_initialize(); if (pep == NULL) { error("test_pep: pep_initialize() failed"); return -1; } info("set LOG options..."); pep_setoption(pep,PEP_OPTION_LOG_STDERR,stderr); pep_setoption(pep,PEP_OPTION_LOG_LEVEL,PEP_LOGLEVEL_DEBUG); // DEBUG, INFO, WARN and ERROR pep_setoption(pep,PEP_OPTION_LOG_HANDLER,log_handler_pep); // will override stderr log handler info("create PIP"); pep_pip_t * pip= pip_create("PIPRequestDumper",pip_init,pip_process,pip_destroy); if (pip == NULL) { error("test_pep: pip_create(...) failed"); pep_destroy(pep); return -1; } info("install PIP: %s",pip->id); pep_rc= pep_addpip(pep,pip); if (pep_rc != PEP_OK) { error("test_pep: pep_addpip() failed: %s",pep_strerror(pep_rc)); pep_destroy(pep); return -1; } info("install PIP: %s",authzinterop2gridwn_adapter_pip->id); pep_rc= pep_addpip(pip,authzinterop2gridwn_adapter_pip); if (pep_rc != PEP_OK) { error("test_pep: pep_addpip() failed: %s",pep_strerror(pep_rc)); pep_destroy(pep); return -1; } info("install PIP: %s",pip->id); pep_rc= pep_addpip(pep,pip); if (pep_rc != PEP_OK) { error("test_pep: pep_addpip() failed: %s",pep_strerror(pep_rc)); pep_destroy(pep); return -1; } info("create OH and add to PEP..."); pep_obligationhandler_t * oh= oh_create("OHResponseDumper",oh_init,oh_process,oh_destroy); if (oh == NULL) { error("test_pep: oh_create(...) failed"); pep_destroy(pep); return -1; } pep_rc= pep_addobligationhandler(pep,oh); if (pep_rc != PEP_OK) { error("test_pep: pep_addobligationhandler() failed: %s",pep_strerror(pep_rc)); pep_destroy(pep); return -1; } // create a XACML request info("create XACML request..."); xacml_request_t * request= xacml_request_create(); assert(request); info("add XACML subject(cert-chain)..."); xacml_subject_t * subject= xacml_subject_create(); assert(subject); xacml_attribute_t * certchain= xacml_attribute_create(XACML_AUTHZINTEROP_SUBJECT_CERTCHAIN); assert(certchain); xacml_attribute_addvalue(certchain,"PEM_ENCODE_PROXY_CERTCHAIN..."); xacml_attribute_setdatatype(certchain,XACML_DATATYPE_BASE64BINARY); xacml_subject_addattribute(subject,certchain); xacml_request_addsubject(request,subject); info("add XACML resource(resource-id)..."); xacml_resource_t * resource= xacml_resource_create(); assert(resource); xacml_attribute_t * resource_id= xacml_attribute_create(XACML_RESOURCE_ID); assert(resource_id); xacml_attribute_addvalue(resource_id,"http://authz-interop.org/xacml/resource/resource-type/wn"); xacml_resource_addattribute(resource,resource_id); xacml_request_addresource(request,resource); info("set XACML action(action-id)..."); xacml_action_t * action= xacml_action_create(); assert(action); xacml_attribute_t * action_id= xacml_attribute_create(XACML_ACTION_ID); assert(action_id); xacml_attribute_addvalue(action_id,"http://authz-interop.org/xacml/action/action-type/execute-now"); xacml_action_addattribute(action,action_id); xacml_request_setaction(request,action); info("set XACML environment(path)..."); xacml_environment_t * environment= xacml_environment_create(); assert(environment); xacml_attribute_t * path= xacml_attribute_create("x-urn:authz:env:path"); assert(path); xacml_attribute_addvalue(path,"/usr/bin"); xacml_attribute_addvalue(path,"/opt/glite/bin"); xacml_attribute_addvalue(path,"/home/johndoe/bin"); xacml_environment_addattribute(environment,path); xacml_request_setenvironment(request,environment); // add many PEPd endpoints for failover testing info("set PEPd endpoint: %s", url); pep_rc= pep_setoption(PEP_OPTION_ENDPOINT_URL, url); info("set PEPd endpoint: %s", "http://www.google.com"); pep_rc= pep_setoption(PEP_OPTION_ENDPOINT_URL, "http://www.google.com"); info("set PEPd endpoint: %s", "http://localhost:8080/PEPd/authz?s7"); pep_rc= pep_setoption(PEP_OPTION_ENDPOINT_URL, "http://localhost:8080/PEPd/authz?s7"); info("set PEPd endpoint: %s", "http://nasjflkasdjflj.com"); pep_rc= pep_setoption(PEP_OPTION_ENDPOINT_URL, "http://nasjflkasdjflj.com"); info("set PEPd endpoint: %s", "http://localhost:8080/PEPd/authz?s3"); pep_rc= pep_setoption(PEP_OPTION_ENDPOINT_URL, "http://localhost:8080/PEPd/authz?s3"); info("set PEPd endpoint: %s", "http://hestia.switch.ch/PEPd/authz?s8"); pep_rc= pep_setoption(PEP_OPTION_ENDPOINT_URL, "http://hestia.switch.ch/PEPd/authz?s8"); info("set PEPd endpoint: %s", "http://localhost:8080"); // respond OK 200 pep_rc= pep_setoption(PEP_OPTION_ENDPOINT_URL, "http://localhost:8080"); // send authz request and process if (pep_rc != PEP_OK) { error("test_pep: pep_setoption(PEP_OPTION_ENDPOINT_URL,%s) failed: %s",url,pep_strerror(pep_rc)); pep_destroy(); return -1; } info("send XACML request to PEPd"); xacml_response_t * response= NULL; pep_rc= pep_authorize(&request,&response); if (pep_rc != PEP_OK) { error("test_pep: pep_authorize(request,response) failed: %s",pep_strerror(pep_rc)); xacml_request_delete(request); xacml_response_delete(response); pep_destroy(); pip_delete(pip); oh_delete(oh); return -1; } info("delete XACML request and response..."); xacml_request_delete(request); xacml_response_delete(response); info("destroy PEP..."); pep_rc= pep_destroy(); if (pep_rc != PEP_OK) { error("test_pep: pep_destroy() failed: %s",pep_strerror(pep_rc)); pip_delete(pip); oh_delete(oh); return pep_rc; } // WARNING: call these only AFTER pep_destroy()... info("delete PIP and OH structs..."); pip_delete(pip); oh_delete(oh); info("done."); return 0; }