00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <sys/types.h>
00038 #include <sys/stat.h>
00039 #include <unistd.h>
00040 #include <string.h>
00041 #include <strings.h>
00042 #include <dirent.h>
00043 #include <ctype.h>
00044
00045 #ifndef _GNU_SOURCE
00046 #define _GNU_SOURCE
00047 #endif
00048 #include <fnmatch.h>
00049
00050 #include <libxml/xmlmemory.h>
00051 #include <libxml/tree.h>
00052 #include <libxml/parser.h>
00053
00054 #include "gridsite.h"
00055
00056
00057
00058 #ifdef XACML_DEBUG
00059 #define XACML_DEBUG_FILE "/tmp/grstxacmldebug.out"
00060 #endif
00061
00062
00063
00064
00065
00066
00067 extern char *grst_perm_syms[];
00068 extern GRSTgaclPerm grst_perm_vals[];
00069
00070
00071 FILE* debugfile;
00072
00073 GRSTgaclAcl *GRSTgaclAclParse(xmlDocPtr, xmlNodePtr, GRSTgaclAcl *);
00074 GRSTgaclAcl *GRSTxacmlAclParse(xmlDocPtr, xmlNodePtr, GRSTgaclAcl *);
00075 int GRSTxacmlPermPrint(GRSTgaclPerm perm, FILE *fp);
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 static GRSTgaclCred *GRSTxacmlCredParse(xmlNodePtr cur)
00086
00087
00088
00089
00090 {
00091 xmlNodePtr attr_val;
00092 xmlNodePtr attr_des;
00093 GRSTgaclCred *cred;
00094
00095
00096
00097 if ( (xmlStrcmp(cur->name, (const xmlChar *) "AnySubject") == 0)) cred = GRSTgaclCredNew("any-user");
00098
00099 else{
00100
00101 attr_val=cur->xmlChildrenNode->xmlChildrenNode;
00102 attr_des=attr_val->next;
00103
00104 cred = GRSTgaclCredNew((char *) xmlNodeGetContent(attr_des->properties->children));
00105
00106 cred->next = NULL;
00107
00108
00109 GRSTgaclCredAddValue(cred, (char *) xmlNodeGetContent(attr_des->properties->next->children),
00110 (char *) xmlNodeGetContent(attr_val));
00111 }
00112
00113 return cred;
00114 }
00115
00116 static GRSTgaclEntry *GRSTxacmlEntryParse(xmlNodePtr cur)
00117
00118
00119
00120
00121
00122 {
00123 int i, check=0;
00124 xmlNodePtr cur2;
00125 xmlNodePtr rule_root=cur;
00126 GRSTgaclEntry *entry;
00127 GRSTgaclCred *cred;
00128
00129
00130
00131
00132
00133
00134 cur = cur->xmlChildrenNode->xmlChildrenNode;
00135
00136 #ifdef XACML_DEBUG
00137 fprintf (debugfile, "Starting to Parse Entry\n");
00138 #endif
00139 entry = GRSTgaclEntryNew();
00140
00141 while (cur!=NULL){
00142
00143 if (xmlStrcmp(cur->name, (const xmlChar *) "Subjects") == 0){
00144 #ifdef XACML_DEBUG
00145 fprintf (debugfile, "Starting to Parse Credentials\n");
00146 #endif
00147 if (check==0){
00148
00149 cur2=cur->xmlChildrenNode;
00150 while (cur2!=NULL){
00151 if ( ((cred = GRSTxacmlCredParse(cur2)) != NULL) && (!GRSTgaclEntryAddCred(entry, cred))){
00152 GRSTgaclCredFree(cred);
00153 GRSTgaclEntryFree(entry);
00154 return NULL;
00155 }
00156 cur2=cur2->next;
00157 }
00158 }
00159 }
00160
00161 else if (xmlStrcmp(cur->name, (const xmlChar *) "Actions") == 0){
00162 #ifdef XACML_DEBUG
00163 fprintf (debugfile, "Starting to Parse Permissions\n");
00164 #endif
00165 if (xmlStrcmp(xmlNodeGetContent(rule_root->properties->next->children), (const xmlChar *) "Permit") == 0 ){
00166 #ifdef XACML_DEBUG
00167 fprintf (debugfile, "\tPermit-ed actions: ");
00168 #endif
00169 for (cur2 = cur->xmlChildrenNode; cur2 != NULL; cur2=cur2->next)
00170 for (i=0; grst_perm_syms[i] != NULL; ++i)
00171 if (xmlStrcmp(xmlNodeGetContent(cur2->xmlChildrenNode->xmlChildrenNode), (const xmlChar *) grst_perm_syms[i]) == 0)
00172 {
00173 #ifdef XACML_DEBUG
00174 fprintf (debugfile, "%s ", grst_perm_syms[i]);
00175 #endif
00176 GRSTgaclEntryAllowPerm(entry, grst_perm_vals[i]);
00177 }
00178 }
00179
00180 if (xmlStrcmp(xmlNodeGetContent(rule_root->properties->next->children), (const xmlChar *) "Deny") == 0 ) {
00181 #ifdef XACML_DEBUG
00182 fprintf (debugfile, "\tDeny-ed actions: ");
00183 #endif
00184 for (cur2 = cur->xmlChildrenNode; cur2 != NULL; cur2=cur2->next)
00185 for (i=0; grst_perm_syms[i] != NULL; ++i)
00186 if (xmlStrcmp(xmlNodeGetContent(cur2->xmlChildrenNode->xmlChildrenNode), (const xmlChar *) grst_perm_syms[i]) == 0)
00187 {
00188
00189 #ifdef XACML_DEBUG
00190 fprintf (debugfile, "%s ", grst_perm_syms[i]);
00191 #endif
00192 GRSTgaclEntryDenyPerm(entry, grst_perm_vals[i]);
00193 }
00194 }
00195
00196 }
00197 else{
00198 #ifdef XACML_DEBUG
00199 fprintf (debugfile, "OOOPSIE\n");
00200 #endif
00201 GRSTgaclEntryFree(entry);
00202 return NULL;
00203 }
00204
00205 cur=cur->next;
00206
00207
00208
00209
00210 if (cur==NULL)
00211 if (check==0)
00212 if (rule_root->next!=NULL)
00213 if ( strncmp((const char*)xmlNodeGetContent(rule_root->properties->children),
00214 (const char*)xmlNodeGetContent(rule_root->next->properties->children),
00215 6) == 0){
00216 #ifdef XACML_DEBUG
00217 fprintf (debugfile, "End of perms and creds, next is %s \n", xmlNodeGetContent(rule_root->next->properties->children));
00218 #endif
00219 rule_root=rule_root->next;
00220 cur=rule_root->xmlChildrenNode->xmlChildrenNode;
00221 #ifdef XACML_DEBUG
00222 fprintf (debugfile, "skipped to <%s> tag of next Rule\n", cur->name);
00223 #endif
00224 check++;
00225 }
00226 }
00227
00228 return entry;
00229 }
00230
00231 GRSTgaclAcl *GRSTxacmlAclLoadFile(char *filename)
00232 {
00233 xmlDocPtr doc;
00234 xmlNodePtr cur;
00235 GRSTgaclAcl *acl=NULL;
00236
00237 doc = xmlParseFile(filename);
00238 if (doc == NULL) return NULL;
00239
00240 cur = xmlDocGetRootElement(doc);
00241 if (cur == NULL) return NULL;
00242
00243 if (!xmlStrcmp(cur->name, (const xmlChar *) "Policy")) { acl=GRSTxacmlAclParse(doc, cur, acl);}
00244 else if (!xmlStrcmp(cur->name, (const xmlChar *) "gacl")) {acl=GRSTgaclAclParse(doc, cur, acl);}
00245 else
00246 {
00247 xmlFreeDoc(doc);
00248 free(cur);
00249 return NULL;
00250 }
00251
00252 xmlFreeDoc(doc);
00253 return acl;
00254 }
00255
00256 GRSTgaclAcl *GRSTxacmlAclParse(xmlDocPtr doc, xmlNodePtr cur, GRSTgaclAcl *acl)
00257 {
00258 GRSTgaclEntry *entry;
00259
00260 #ifdef XACML_DEBUG
00261 debugfile=fopen(XACML_DEBUG_FILE, "w");
00262 fprintf (debugfile, "ACL loaded..\n");
00263 fprintf (debugfile, "Parsing XACML\n");
00264 #endif
00265
00266
00267
00268 cur = cur->xmlChildrenNode->next;
00269
00270 acl = GRSTgaclAclNew();
00271
00272 while (cur != NULL){
00273
00274 if ( !xmlStrcmp(cur->name, (const xmlChar *)"Rule") )
00275 {
00276 #ifdef XACML_DEBUG
00277 fprintf (debugfile, "Rule %s found\n", xmlNodeGetContent(cur->properties->children) );
00278 fprintf (debugfile, "Parsing Entry for this rule\n");
00279 #endif
00280 entry = GRSTxacmlEntryParse(cur);
00281
00282 if (entry == NULL)
00283 {
00284 GRSTgaclAclFree(acl);
00285 return NULL;
00286 }
00287 else GRSTgaclAclAddEntry(acl, entry);
00288
00289 #ifdef XACML_DEBUG
00290 fprintf (debugfile, "Entry read in\n\n");
00291 #endif
00292 }
00293
00294
00295
00296 if (cur->next != NULL)
00297 {
00298 if ( strncmp((const char*)xmlNodeGetContent(cur->properties->children),
00299 (const char*)xmlNodeGetContent(cur->next->properties->children),
00300 6) == 0)
00301 {
00302 #ifdef XACML_DEBUG
00303 fprintf (debugfile, "skipping next rule %s, should have been caught previously\n\n", xmlNodeGetContent(cur->next->properties->children) );
00304 #endif
00305 cur=cur->next;
00306 }
00307 }
00308
00309 cur=cur->next;
00310
00311 }
00312
00313 #ifdef XACML_DEBUG
00314 fprintf (debugfile, "Finished loading ACL - Fanfare!\n");
00315 fclose(debugfile);
00316 #endif
00317
00318 return acl;
00319 }
00320
00321
00322 int GRSTxacmlFileIsAcl(char *pathandfile)
00323
00324
00325 {
00326 char *filename;
00327
00328 filename = rindex(pathandfile, '/');
00329 if (filename == NULL) filename = pathandfile;
00330 else filename++;
00331
00332 return (strncmp((const char*)filename, GRST_ACL_FILE, sizeof(GRST_ACL_FILE) - 1) == 0);
00333 }
00334
00335 char *GRSTxacmlFileFindAclname(char *pathandfile)
00336
00337
00338
00339 {
00340 char *path, *p;
00341 struct stat statbuf;
00342
00343 path = malloc(strlen(pathandfile) + sizeof(GRST_ACL_FILE) + 1);
00344 strcpy(path, pathandfile);
00345
00346 if (stat(path, &statbuf) == 0)
00347 {
00348 if (!S_ISDIR(statbuf.st_mode))
00349 {
00350 p = rindex(path, '/');
00351 if (p != NULL) *p = '\0';
00352 }
00353 }
00354
00355 while (path[0] != '\0')
00356 {
00357 strcat(path, "/");
00358 strcat(path, GRST_ACL_FILE);
00359
00360 if (stat(path, &statbuf) == 0) return path;
00361
00362 p = rindex(path, '/');
00363 *p = '\0';
00364
00365 p = rindex(path, '/');
00366 if (p == NULL) break;
00367
00368 *p = '\0';
00369 }
00370
00371 free(path);
00372 return NULL;
00373 }
00374
00375 GRSTgaclAcl *GRSTxacmlAclLoadforFile(char *pathandfile)
00376
00377
00378 {
00379 char *path;
00380 GRSTgaclAcl *acl;
00381
00382 path = GRSTxacmlFileFindAclname(pathandfile);
00383
00384 if (path != NULL)
00385 {
00386 acl = GRSTxacmlAclLoadFile(path);
00387 free(path);
00388 return acl;
00389 }
00390
00391 return NULL;
00392 }
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 int GRSTxacmlCredPrint(GRSTgaclCred *cred, FILE *fp)
00403
00404
00405
00406 {
00407 char *q;
00408
00409 if (cred->auri != NULL)
00410 {
00411 fputs("\t\t\t\t<Subject>\n", fp);
00412 fputs("\t\t\t\t\t<SubjectMatch MatchId=\"urn:oasis:names:tc:xacml:1.0:function:string-equal\">\n", fp);
00413 fputs("\t\t\t\t\t\t<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">", fp);
00414 for (q=cred->auri; *q != '\0'; ++q)
00415 if (*q == '<') fputs("<", fp);
00416 else if (*q == '>') fputs(">", fp);
00417 else if (*q == '&') fputs("&" , fp);
00418 else if (*q == '\'') fputs("'", fp);
00419 else if (*q == '"') fputs(""", fp);
00420 else fputc(*q, fp);
00421
00422
00423 fputs("</AttributeValue>\n", fp);
00424
00425 fputs("\t\t\t\t\t\t<SubjectAttributeDesignator\n", fp);
00426 fputs("\t\t\t\t\t\t\tAttributeId=", fp);
00427 fprintf(fp, "\"cred\"\n");
00428 fputs("\t\t\t\t\t\t\tDataType=", fp);
00429 fprintf(fp, "\"auri\"/>\n");
00430 fputs("\t\t\t\t\t</SubjectMatch>\n", fp);
00431 fputs("\t\t\t\t</Subject>\n", fp);
00432 }
00433 else fputs("\t\t\t\t<AnySubject/>\n", fp);
00434
00435 return 1;
00436 }
00437
00438
00439 int GRSTxacmlEntryPrint(GRSTgaclEntry *entry, FILE *fp, int rule_number)
00440 {
00441 GRSTgaclCred *cred;
00442 GRSTgaclPerm i;
00443
00444 if (entry->allowed){
00445
00446 fprintf(fp, "\t<Rule RuleId=\"Entry%dA\" Effect=\"Permit\">\n", rule_number);
00447 fputs("\t\t<Target>\n", fp);
00448 fputs("\t\t\t<Subjects>\n", fp);
00449
00450 for (cred = entry->firstcred; cred != NULL; cred = cred->next)
00451 GRSTxacmlCredPrint(cred, fp);
00452
00453 fputs("\t\t\t</Subjects>\n", fp);
00454 fputs("\t\t\t<Actions>\n", fp);
00455
00456 for (i=GRST_PERM_READ; i <= GRST_PERM_ADMIN; ++i)
00457 if ((entry->allowed) & i) GRSTxacmlPermPrint(i, fp);
00458
00459 fputs("\t\t\t</Actions>\n", fp);
00460 fputs("\t\t</Target>\n", fp);
00461 fputs("\t</Rule>\n", fp);
00462 }
00463
00464 if (entry->denied){
00465
00466 fprintf(fp, "\t<Rule RuleId=\"Entry%dD\" Effect=\"Deny\">\n", rule_number);
00467 fputs("\t\t<Target>\n", fp);
00468 fputs("\t\t\t<Subjects>\n", fp);
00469
00470 for (cred = entry->firstcred; cred != NULL; cred = cred->next)
00471 GRSTxacmlCredPrint(cred, fp);
00472
00473 fputs("\t\t\t</Subjects>\n", fp);
00474 fputs("\t\t\t<Actions>\n", fp);
00475
00476 for (i=GRST_PERM_READ; i <= GRST_PERM_ADMIN; ++i)
00477 if (entry->denied & i) GRSTxacmlPermPrint(i, fp);
00478
00479 fputs("\t\t\t</Actions>\n", fp);
00480 fputs("\t\t</Target>\n", fp);
00481 fputs("\t</Rule>\n", fp);
00482 }
00483 return 1;
00484 }
00485
00486
00487 int GRSTxacmlPermPrint(GRSTgaclPerm perm, FILE *fp)
00488 {
00489 GRSTgaclPerm i;
00490
00491 for (i=GRST_PERM_READ; grst_perm_syms[i] != NULL; ++i)
00492 if (perm == grst_perm_vals[i])
00493 {
00494
00495 fputs("\t\t\t\t<Action>\n", fp);
00496 fputs("\t\t\t\t\t<ActionMatch MatchId=\"urn:oasis:names:tc:xacml:1.0:function:string-equal\">\n", fp);
00497 fputs("\t\t\t\t\t\t<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">", fp);
00498 fprintf(fp, "%s", grst_perm_syms[i]);
00499 fputs("</AttributeValue>\n", fp);
00500 fputs("\t\t\t\t\t\t<ActionAttributeDesignator\n", fp);
00501 fputs("\t\t\t\t\t\t\tAttributeId=\"urn:oasis:names:tc:xacml:1.0:action:action-id\"\n", fp);
00502 fputs("\t\t\t\t\t\t\tDataType=\"http://www.w3.org/2001/XMLSchema#string\"/>\n", fp);
00503 fputs("\t\t\t\t\t</ActionMatch>\n", fp);
00504 fputs("\t\t\t\t</Action>\n",fp);
00505
00506 return 1;
00507 }
00508
00509 return 0;
00510 }
00511
00512 int GRSTxacmlAclPrint(GRSTgaclAcl *acl, FILE *fp, char* dir_uri)
00513 {
00514 GRSTgaclEntry *entry;
00515 int rule_number=1;
00516
00517 fputs("<Policy", fp);
00518 fputs("\txmlns=\"urn:oasis:names:tc:xacml:1.0:policy\"\n", fp);
00519 fputs("\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n", fp);
00520 fputs("\txsi:schemaLocation=\"urn:oasis:names:tc:xacml:1.0:policy cs-xacml-schema-policy-01.xsd\"\n", fp);
00521 fputs("\tPolicyId=\"GridSitePolicy\"\n", fp);
00522 fputs("\tRuleCombiningAlgId=\"urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:deny-overrides\">\n\n", fp);
00523
00524 fputs("\t<Target>\n\t\t<Resources>\n\t\t\t<Resource>\n", fp);
00525 fputs("\t\t\t\t<ResourceMatch MatchId=\"urn:oasis:names:tc:xacml:1.0:function:string-equal\">\n", fp);
00526 fputs("\t\t\t\t\t<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">", fp);
00527 fprintf(fp, "%s", dir_uri);
00528 fputs("</AttributeValue>\n", fp);
00529 fputs("\t\t\t\t\t<ResourceAttributeDesignator\n", fp);
00530 fputs("\t\t\t\t\t\tAttributeId=\"urn:oasis:names:tc:xacml:1.0:resource:resource-id\"\n", fp);
00531 fputs("\t\t\t\t\t\tDataType=\"http://www.w3.org/2001/XMLSchema#string\"/>\n", fp);
00532
00533 fputs("\t\t\t\t</ResourceMatch>\n\t\t\t</Resource>\n\t\t</Resources>\n\t\t<Subjects>\n\t\t\t<AnySubject/>\n\t\t</Subjects>", fp);
00534 fputs("\n\t\t<Actions>\n\t\t\t<AnyAction/>\n\t\t</Actions>\n\t</Target>\n\n", fp);
00535
00536 for (entry = acl->firstentry; entry != NULL; entry = entry->next){
00537
00538 GRSTxacmlEntryPrint(entry, fp, rule_number);
00539 rule_number++;
00540 }
00541
00542 fputs("</Policy>\n", fp);
00543
00544 return 1;
00545 }
00546
00547 int GRSTxacmlAclSave(GRSTgaclAcl *acl, char *filename, char* dir_uri)
00548 {
00549 int ret;
00550 FILE *fp;
00551
00552 fp = fopen(filename, "w");
00553 if (fp == NULL) return 0;
00554
00555 fprintf(fp,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
00556
00557 ret = GRSTxacmlAclPrint(acl, fp, dir_uri);
00558
00559 fclose(fp);
00560
00561 return ret;
00562 }
00563
00564
00565
00566