00001 /* 00002 * Copyright (c) Members of the EGEE Collaboration. 2006-2010. 00003 * See http://www.eu-egee.org/partners/ for details on the copyright holders. 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 /************* 00019 * Simple Argus PEP client example 00020 * 00021 * gcc -I/usr/include -L/usr/lib64 -largus-pep pep_client_example.c -o pep_client_example 00022 * 00023 * or use "pkg-config libargus-pep --cflags --libs" to dertermine the required CFLAGS and 00024 * LDFLAGS. 00025 * 00026 * Author: Valery Tschopp <valery.tschopp@switch.ch> 00027 * $Id: pep_client_example.c 2010 2011-01-26 14:43:13Z vtschopp $ 00028 ************/ 00029 00030 #include <stdio.h> 00031 #include <stdlib.h> 00032 00033 /* include Argus PEP API header */ 00034 #include "argus/pep.h" 00035 00036 /* prototypes */ 00037 static int create_xacml_request(xacml_request_t ** request,const char * subjectid, const char * resourceid, const char * actionid); 00038 static int process_xacml_response(const xacml_response_t * response); 00039 static const char * decision_tostring(xacml_decision_t decision); 00040 static const char * fulfillon_tostring(xacml_fulfillon_t fulfillon); 00041 00042 /* 00043 * main 00044 */ 00045 int main(void) { 00046 00047 /* Argus PEP client handle */ 00048 PEP * pep; 00049 00050 /* functions return code */ 00051 pep_error_t pep_rc; /* PEP function error */ 00052 int rc; /* others functions */ 00053 00054 /* XACML request and response */ 00055 xacml_request_t * request; 00056 xacml_response_t * response; 00057 00058 char * pep_url, * subjectid, * resourceid, * actionid; 00059 00060 /* dump library version */ 00061 fprintf(stdout,"using %s\n",pep_version()); 00062 00063 00064 /* create the PEP client handle */ 00065 pep= pep_initialize(); 00066 if (pep == NULL) { 00067 fprintf(stderr,"failed to create PEP client\n"); 00068 exit(1); 00069 } 00070 00071 /* debugging options */ 00072 pep_setoption(pep,PEP_OPTION_LOG_STDERR,stderr); 00073 pep_setoption(pep,PEP_OPTION_LOG_LEVEL,PEP_LOGLEVEL_DEBUG); 00074 00075 /* configure PEP client: PEPd url */ 00076 pep_url= "http://demeter.switch.ch:8154/authz"; 00077 pep_rc= pep_setoption(pep,PEP_OPTION_ENDPOINT_URL,pep_url); 00078 if (pep_rc != PEP_OK) { 00079 fprintf(stderr,"failed to set PEPd url: %s: %s\n", pep_url, pep_strerror(pep_rc)); 00080 exit(1); 00081 } 00082 00083 /* create the XACML request */ 00084 subjectid= "CN=Valery Tschopp 9FEE5EE3,O=Switch - Teleinformatikdienste fuer Lehre und Forschung,DC=slcs,DC=switch,DC=ch"; 00085 resourceid= "switch"; 00086 actionid= "switch"; 00087 rc= create_xacml_request(&request,subjectid,resourceid,actionid); 00088 if (rc != 0) { 00089 fprintf(stderr,"failed to create XACML request\n"); 00090 exit(1); 00091 } 00092 00093 /* submit the XACML request */ 00094 pep_rc= pep_authorize(pep,&request, &response); 00095 if (pep_rc != PEP_OK) { 00096 fprintf(stderr,"failed to authorize XACML request: %s\n", pep_strerror(pep_rc)); 00097 exit(1); 00098 } 00099 00100 /* parse and process XACML response */ 00101 rc= process_xacml_response(response); 00102 00103 /* delete resquest and response objs */ 00104 xacml_request_delete(request); 00105 xacml_response_delete(response); 00106 00107 /* release the PEP client handle */ 00108 pep_destroy(pep); 00109 00110 return 0; 00111 } 00112 00113 /* 00114 * Creates a XACML Request containing a XACML Subject with the given subjectid, a XACML Resource 00115 * with the given resourceid and a XACML Action with the given actionid. 00116 * 00117 * @param [in/out] request address of the pointer to the XACML request object 00118 * @param [in] subjectid, a X.509 DN, attribute value of the XACML Request/Subject element 00119 * @param [in] resourceid attribute value of the XACML Request/Resource element 00120 * @param [in] actionid attribute value of the XACML Request/Action element 00121 * @return 0 on success or error code on failure. 00122 */ 00123 static int create_xacml_request(xacml_request_t ** request,const char * subjectid, const char * resourceid, const char * actionid) 00124 { 00125 xacml_subject_t * subject; 00126 xacml_attribute_t * subject_attr_id; 00127 xacml_resource_t * resource; 00128 xacml_attribute_t * resource_attr_id; 00129 xacml_action_t * action; 00130 xacml_attribute_t * action_attr_id; 00131 00132 /* XACML Subject with subjectid Attribute value */ 00133 subject= xacml_subject_create(); 00134 if (subject == NULL) { 00135 fprintf(stderr,"can not create XACML Subject\n"); 00136 return 1; 00137 } 00138 subject_attr_id= xacml_attribute_create(XACML_SUBJECT_ID); 00139 if (subject_attr_id == NULL) { 00140 fprintf(stderr,"can not create XACML Subject/Attribute:%s\n",XACML_SUBJECT_ID); 00141 xacml_subject_delete(subject); 00142 return 1; 00143 } 00144 // set X.509 DN value 00145 xacml_attribute_addvalue(subject_attr_id,subjectid); 00146 // set attribute datatype for X.509 DN 00147 xacml_attribute_setdatatype(subject_attr_id,XACML_DATATYPE_X500NAME); 00148 xacml_subject_addattribute(subject,subject_attr_id); 00149 00150 /* XACML Resource with resourceid Attribute value */ 00151 resource= xacml_resource_create(); 00152 if (resource == NULL) { 00153 fprintf(stderr,"can not create XACML Resource\n"); 00154 xacml_subject_delete(subject); 00155 return 2; 00156 } 00157 resource_attr_id= xacml_attribute_create(XACML_RESOURCE_ID); 00158 if (resource_attr_id == NULL) { 00159 fprintf(stderr,"can not create XACML Resource/Attribute:%s\n",XACML_RESOURCE_ID); 00160 xacml_subject_delete(subject); 00161 xacml_resource_delete(resource); 00162 return 2; 00163 } 00164 xacml_attribute_addvalue(resource_attr_id,resourceid); 00165 xacml_resource_addattribute(resource,resource_attr_id); 00166 00167 /* XACML Action with actionid Attribute value */ 00168 action= xacml_action_create(); 00169 if (action == NULL) { 00170 fprintf(stderr,"can not create XACML Action\n"); 00171 xacml_subject_delete(subject); 00172 xacml_resource_delete(resource); 00173 return 3; 00174 } 00175 action_attr_id= xacml_attribute_create(XACML_ACTION_ID); 00176 if (action_attr_id == NULL) { 00177 fprintf(stderr,"can not create XACML Action/Attribute:%s\n",XACML_ACTION_ID); 00178 xacml_subject_delete(subject); 00179 xacml_resource_delete(resource); 00180 xacml_action_delete(action); 00181 return 3; 00182 } 00183 xacml_attribute_addvalue(action_attr_id,actionid); 00184 xacml_action_addattribute(action,action_attr_id); 00185 00186 /* XACML Request with all elements */ 00187 *request= xacml_request_create(); 00188 if (*request == NULL) { 00189 fprintf(stderr,"can not create XACML Request\n"); 00190 xacml_subject_delete(subject); 00191 xacml_resource_delete(resource); 00192 xacml_action_delete(action); 00193 return 4; 00194 } 00195 xacml_request_addsubject(*request,subject); 00196 xacml_request_addresource(*request,resource); 00197 xacml_request_setaction(*request,action); 00198 00199 return 0; 00200 } 00201 00202 /* 00203 * Simply dump the XACML response. 00204 * 00205 * @param [in] response the XAXML response 00206 * @return 0 on success or error code on failure. 00207 */ 00208 static int process_xacml_response(const xacml_response_t * response) { 00209 size_t results_l; 00210 int i, j, k; 00211 if (response == NULL) { 00212 fprintf(stderr,"response is NULL\n"); 00213 return 1; 00214 } 00215 results_l= xacml_response_results_length(response); 00216 fprintf(stdout,"response: %d results\n", (int)results_l); 00217 for(i= 0; i<results_l; i++) { 00218 xacml_result_t * result; 00219 xacml_status_t * status; 00220 xacml_statuscode_t * statuscode, * subcode; 00221 size_t obligations_l; 00222 00223 result= xacml_response_getresult(response,i); 00224 fprintf(stdout,"response.result[%d].decision= %s\n", i, decision_tostring(xacml_result_getdecision(result))); 00225 fprintf(stdout,"response.result[%d].resourceid= %s\n", i, xacml_result_getresourceid(result)); 00226 00227 status= xacml_result_getstatus(result); 00228 fprintf(stdout,"response.result[%d].status.message= %s\n", i, xacml_status_getmessage(status)); 00229 statuscode= xacml_status_getcode(status); 00230 fprintf(stdout,"response.result[%d].status.code.value= %s\n", i, xacml_statuscode_getvalue(statuscode)); 00231 subcode= xacml_statuscode_getsubcode(statuscode); 00232 if (subcode != NULL) { 00233 fprintf(stdout,"response.result[%d].status.code.subcode.value= %s\n", i, xacml_statuscode_getvalue(subcode)); 00234 } 00235 obligations_l= xacml_result_obligations_length(result); 00236 fprintf(stdout,"response.result[%d]: %d obligations\n", i, (int)obligations_l); 00237 for(j= 0; j<obligations_l; j++) { 00238 size_t attrs_l; 00239 xacml_obligation_t * obligation= xacml_result_getobligation(result,j); 00240 fprintf(stdout,"response.result[%d].obligation[%d].id= %s\n",i,j, xacml_obligation_getid(obligation)); 00241 fprintf(stdout,"response.result[%d].obligation[%d].fulfillOn= %s\n",i,j, fulfillon_tostring(xacml_obligation_getfulfillon(obligation))); 00242 attrs_l= xacml_obligation_attributeassignments_length(obligation); 00243 fprintf(stdout,"response.result[%d].obligation[%d]: %d attribute assignments\n",i,j,(int)attrs_l); 00244 for (k= 0; k<attrs_l; k++) { 00245 xacml_attributeassignment_t * attr= xacml_obligation_getattributeassignment(obligation,k); 00246 fprintf(stdout,"response.result[%d].obligation[%d].attributeassignment[%d].id= %s\n",i,j,k,xacml_attributeassignment_getid(attr)); 00247 fprintf(stdout,"response.result[%d].obligation[%d].attributeassignment[%d].datatype= %s\n",i,j,k,xacml_attributeassignment_getdatatype(attr)); 00248 fprintf(stdout,"response.result[%d].obligation[%d].attributeassignment[%d].value= %s\n",i,j,k,xacml_attributeassignment_getvalue(attr)); 00249 } 00250 } 00251 } 00252 return 0; 00253 } 00254 00255 /* 00256 * Returns the string representation of the decision. 00257 */ 00258 static const char * decision_tostring(xacml_decision_t decision) { 00259 switch(decision) { 00260 case XACML_DECISION_DENY: 00261 return "Deny"; 00262 break; 00263 case XACML_DECISION_PERMIT: 00264 return "Permit"; 00265 break; 00266 case XACML_DECISION_INDETERMINATE: 00267 return "Indeterminate"; 00268 break; 00269 case XACML_DECISION_NOT_APPLICABLE: 00270 return "Not Applicable"; 00271 break; 00272 default: 00273 return "ERROR (Unknown Decision)"; 00274 break; 00275 } 00276 } 00277 00278 /* 00279 * Returns the string representation of the fulfillOn. 00280 */ 00281 static const char * fulfillon_tostring(xacml_fulfillon_t fulfillon) { 00282 switch(fulfillon) { 00283 case XACML_FULFILLON_DENY: 00284 return "Deny"; 00285 break; 00286 case XACML_FULFILLON_PERMIT: 00287 return "Permit"; 00288 break; 00289 default: 00290 return "ERROR (Unknown FulfillOn)"; 00291 break; 00292 } 00293 }