|
MagickCore
6.7.5
|
00001 /* 00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00003 % % 00004 % % 00005 % PPPP OOO L IIIII CCCC Y Y % 00006 % P P O O L I C Y Y % 00007 % PPPP O O L I C Y % 00008 % P O O L I C Y % 00009 % P OOO LLLLL IIIII CCCC Y % 00010 % % 00011 % % 00012 % MagickCore Policy Methods % 00013 % % 00014 % Software Design % 00015 % John Cristy % 00016 % July 1992 % 00017 % % 00018 % % 00019 % Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization % 00020 % dedicated to making software imaging solutions freely available. % 00021 % % 00022 % You may not use this file except in compliance with the License. You may % 00023 % obtain a copy of the License at % 00024 % % 00025 % http://www.imagemagick.org/script/license.php % 00026 % % 00027 % Unless required by applicable law or agreed to in writing, software % 00028 % distributed under the License is distributed on an "AS IS" BASIS, % 00029 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 00030 % See the License for the specific language governing permissions and % 00031 % limitations under the License. % 00032 % % 00033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00034 % 00035 % We use linked-lists because splay-trees do not currently support duplicate 00036 % key / value pairs (.e.g X11 green compliance and SVG green compliance). 00037 % 00038 */ 00039 00040 /* 00041 Include declarations. 00042 */ 00043 #include "MagickCore/studio.h" 00044 #include "MagickCore/client.h" 00045 #include "MagickCore/configure.h" 00046 #include "MagickCore/configure-private.h" 00047 #include "MagickCore/exception.h" 00048 #include "MagickCore/exception-private.h" 00049 #include "MagickCore/memory_.h" 00050 #include "MagickCore/monitor.h" 00051 #include "MagickCore/monitor-private.h" 00052 #include "MagickCore/option.h" 00053 #include "MagickCore/policy.h" 00054 #include "MagickCore/policy-private.h" 00055 #include "MagickCore/semaphore.h" 00056 #include "MagickCore/string_.h" 00057 #include "MagickCore/token.h" 00058 #include "MagickCore/utility.h" 00059 #include "MagickCore/utility-private.h" 00060 #include "MagickCore/xml-tree.h" 00061 00062 /* 00063 Define declarations. 00064 */ 00065 #define PolicyFilename "policy.xml" 00066 00067 /* 00068 Typedef declarations. 00069 */ 00070 struct _PolicyInfo 00071 { 00072 char 00073 *path; 00074 00075 PolicyDomain 00076 domain; 00077 00078 PolicyRights 00079 rights; 00080 00081 char 00082 *name, 00083 *pattern, 00084 *value; 00085 00086 MagickBooleanType 00087 exempt, 00088 stealth, 00089 debug; 00090 00091 SemaphoreInfo 00092 *semaphore; 00093 00094 size_t 00095 signature; 00096 }; 00097 00098 typedef struct _PolicyMapInfo 00099 { 00100 const PolicyDomain 00101 domain; 00102 00103 const PolicyRights 00104 rights; 00105 00106 const char 00107 *name, 00108 *pattern, 00109 *value; 00110 } PolicyMapInfo; 00111 00112 /* 00113 Static declarations. 00114 */ 00115 static const PolicyMapInfo 00116 PolicyMap[] = 00117 { 00118 { UndefinedPolicyDomain, UndefinedPolicyRights, (const char *) NULL, 00119 (const char *) NULL, (const char *) NULL } 00120 }; 00121 00122 static LinkedListInfo 00123 *policy_list = (LinkedListInfo *) NULL; 00124 00125 static SemaphoreInfo 00126 *policy_semaphore = (SemaphoreInfo *) NULL; 00127 00128 static volatile MagickBooleanType 00129 instantiate_policy = MagickFalse; 00130 00131 /* 00132 Forward declarations. 00133 */ 00134 static MagickBooleanType 00135 InitializePolicyList(ExceptionInfo *), 00136 LoadPolicyLists(const char *,ExceptionInfo *); 00137 00138 /* 00139 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00140 % % 00141 % % 00142 % % 00143 + G e t P o l i c y I n f o % 00144 % % 00145 % % 00146 % % 00147 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00148 % 00149 % GetPolicyInfo() searches the policy list for the specified name and if found 00150 % returns attributes for that policy. 00151 % 00152 % The format of the GetPolicyInfo method is: 00153 % 00154 % PolicyInfo *GetPolicyInfo(const char *name,ExceptionInfo *exception) 00155 % 00156 % A description of each parameter follows: 00157 % 00158 % o name: the policy name. 00159 % 00160 % o exception: return any errors or warnings in this structure. 00161 % 00162 */ 00163 static PolicyInfo *GetPolicyInfo(const char *name,ExceptionInfo *exception) 00164 { 00165 char 00166 policyname[MaxTextExtent]; 00167 00168 register PolicyInfo 00169 *p; 00170 00171 register char 00172 *q; 00173 00174 assert(exception != (ExceptionInfo *) NULL); 00175 if ((policy_list == (LinkedListInfo *) NULL) || 00176 (instantiate_policy == MagickFalse)) 00177 if (InitializePolicyList(exception) == MagickFalse) 00178 return((PolicyInfo *) NULL); 00179 if ((policy_list == (LinkedListInfo *) NULL) || 00180 (IsLinkedListEmpty(policy_list) != MagickFalse)) 00181 return((PolicyInfo *) NULL); 00182 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0)) 00183 return((PolicyInfo *) GetValueFromLinkedList(policy_list,0)); 00184 /* 00185 Strip names of whitespace. 00186 */ 00187 (void) CopyMagickString(policyname,name,MaxTextExtent); 00188 for (q=policyname; *q != '\0'; q++) 00189 { 00190 if (isspace((int) ((unsigned char) *q)) == 0) 00191 continue; 00192 (void) CopyMagickString(q,q+1,MaxTextExtent); 00193 q--; 00194 } 00195 /* 00196 Search for policy tag. 00197 */ 00198 LockSemaphoreInfo(policy_semaphore); 00199 ResetLinkedListIterator(policy_list); 00200 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list); 00201 while (p != (PolicyInfo *) NULL) 00202 { 00203 if (LocaleCompare(policyname,p->name) == 0) 00204 break; 00205 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list); 00206 } 00207 if (p != (PolicyInfo *) NULL) 00208 (void) InsertValueInLinkedList(policy_list,0, 00209 RemoveElementByValueFromLinkedList(policy_list,p)); 00210 UnlockSemaphoreInfo(policy_semaphore); 00211 return(p); 00212 } 00213 00214 /* 00215 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00216 % % 00217 % % 00218 % % 00219 % G e t P o l i c y I n f o L i s t % 00220 % % 00221 % % 00222 % % 00223 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00224 % 00225 % GetPolicyInfoList() returns any policies that match the specified pattern. 00226 % 00227 % The format of the GetPolicyInfoList function is: 00228 % 00229 % const PolicyInfo **GetPolicyInfoList(const char *pattern, 00230 % size_t *number_policies,ExceptionInfo *exception) 00231 % 00232 % A description of each parameter follows: 00233 % 00234 % o pattern: Specifies a pointer to a text string containing a pattern. 00235 % 00236 % o number_policies: returns the number of policies in the list. 00237 % 00238 % o exception: return any errors or warnings in this structure. 00239 % 00240 */ 00241 MagickExport const PolicyInfo **GetPolicyInfoList(const char *pattern, 00242 size_t *number_policies,ExceptionInfo *exception) 00243 { 00244 const PolicyInfo 00245 **policies; 00246 00247 register const PolicyInfo 00248 *p; 00249 00250 register ssize_t 00251 i; 00252 00253 /* 00254 Allocate policy list. 00255 */ 00256 assert(pattern != (char *) NULL); 00257 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern); 00258 assert(number_policies != (size_t *) NULL); 00259 *number_policies=0; 00260 p=GetPolicyInfo("*",exception); 00261 if (p == (const PolicyInfo *) NULL) 00262 return((const PolicyInfo **) NULL); 00263 policies=(const PolicyInfo **) AcquireQuantumMemory((size_t) 00264 GetNumberOfElementsInLinkedList(policy_list)+1UL,sizeof(*policies)); 00265 if (policies == (const PolicyInfo **) NULL) 00266 return((const PolicyInfo **) NULL); 00267 /* 00268 Generate policy list. 00269 */ 00270 LockSemaphoreInfo(policy_semaphore); 00271 ResetLinkedListIterator(policy_list); 00272 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list); 00273 for (i=0; p != (const PolicyInfo *) NULL; ) 00274 { 00275 if ((p->stealth == MagickFalse) && 00276 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse)) 00277 policies[i++]=p; 00278 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list); 00279 } 00280 UnlockSemaphoreInfo(policy_semaphore); 00281 policies[i]=(PolicyInfo *) NULL; 00282 *number_policies=(size_t) i; 00283 return(policies); 00284 } 00285 00286 /* 00287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00288 % % 00289 % % 00290 % % 00291 % G e t P o l i c y L i s t % 00292 % % 00293 % % 00294 % % 00295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00296 % 00297 % GetPolicyList() returns any policies that match the specified pattern. 00298 % 00299 % The format of the GetPolicyList function is: 00300 % 00301 % char **GetPolicyList(const char *pattern,size_t *number_policies, 00302 % ExceptionInfo *exception) 00303 % 00304 % A description of each parameter follows: 00305 % 00306 % o pattern: a pointer to a text string containing a pattern. 00307 % 00308 % o number_policies: returns the number of policies in the list. 00309 % 00310 % o exception: return any errors or warnings in this structure. 00311 % 00312 */ 00313 MagickExport char **GetPolicyList(const char *pattern, 00314 size_t *number_policies,ExceptionInfo *exception) 00315 { 00316 char 00317 **policies; 00318 00319 register const PolicyInfo 00320 *p; 00321 00322 register ssize_t 00323 i; 00324 00325 /* 00326 Allocate policy list. 00327 */ 00328 assert(pattern != (char *) NULL); 00329 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern); 00330 assert(number_policies != (size_t *) NULL); 00331 *number_policies=0; 00332 p=GetPolicyInfo("*",exception); 00333 if (p == (const PolicyInfo *) NULL) 00334 return((char **) NULL); 00335 policies=(char **) AcquireQuantumMemory((size_t) 00336 GetNumberOfElementsInLinkedList(policy_list)+1UL,sizeof(*policies)); 00337 if (policies == (char **) NULL) 00338 return((char **) NULL); 00339 /* 00340 Generate policy list. 00341 */ 00342 LockSemaphoreInfo(policy_semaphore); 00343 ResetLinkedListIterator(policy_list); 00344 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list); 00345 for (i=0; p != (const PolicyInfo *) NULL; ) 00346 { 00347 if ((p->stealth == MagickFalse) && 00348 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse)) 00349 policies[i++]=ConstantString(p->name); 00350 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list); 00351 } 00352 UnlockSemaphoreInfo(policy_semaphore); 00353 policies[i]=(char *) NULL; 00354 *number_policies=(size_t) i; 00355 return(policies); 00356 } 00357 00358 /* 00359 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00360 % % 00361 % % 00362 % % 00363 % G e t P o l i c y V a l u e % 00364 % % 00365 % % 00366 % % 00367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00368 % 00369 % GetPolicyValue() returns the value associated with the named policy. 00370 % 00371 % The format of the GetPolicyValue method is: 00372 % 00373 % char *GetPolicyValue(const char *name) 00374 % 00375 % A description of each parameter follows: 00376 % 00377 % o policy_info: The policy info. 00378 % 00379 */ 00380 MagickExport char *GetPolicyValue(const char *name) 00381 { 00382 const char 00383 *value; 00384 00385 const PolicyInfo 00386 *policy_info; 00387 00388 ExceptionInfo 00389 *exception; 00390 00391 assert(name != (const char *) NULL); 00392 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name); 00393 exception=AcquireExceptionInfo(); 00394 policy_info=GetPolicyInfo(name,exception); 00395 exception=DestroyExceptionInfo(exception); 00396 if (policy_info == (PolicyInfo *) NULL) 00397 return((char *) NULL); 00398 value=policy_info->value; 00399 if ((value == (const char *) NULL) || (*value == '\0')) 00400 return((char *) NULL); 00401 return(ConstantString(value)); 00402 } 00403 00404 /* 00405 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00406 % % 00407 % % 00408 % % 00409 + I n i t i a l i z e P o l i c y L i s t % 00410 % % 00411 % % 00412 % % 00413 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00414 % 00415 % InitializePolicyList() initializes the policy list. 00416 % 00417 % The format of the InitializePolicyList method is: 00418 % 00419 % MagickBooleanType InitializePolicyList(ExceptionInfo *exception) 00420 % 00421 % A description of each parameter follows. 00422 % 00423 % o exception: return any errors or warnings in this structure. 00424 % 00425 */ 00426 static MagickBooleanType InitializePolicyList(ExceptionInfo *exception) 00427 { 00428 if ((policy_list == (LinkedListInfo *) NULL) && 00429 (instantiate_policy == MagickFalse)) 00430 { 00431 if (policy_semaphore == (SemaphoreInfo *) NULL) 00432 AcquireSemaphoreInfo(&policy_semaphore); 00433 LockSemaphoreInfo(policy_semaphore); 00434 if ((policy_list == (LinkedListInfo *) NULL) && 00435 (instantiate_policy == MagickFalse)) 00436 { 00437 (void) LoadPolicyLists(PolicyFilename,exception); 00438 instantiate_policy=MagickTrue; 00439 } 00440 UnlockSemaphoreInfo(policy_semaphore); 00441 } 00442 return(policy_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse); 00443 } 00444 00445 /* 00446 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00447 % % 00448 % % 00449 % % 00450 % I s R i g h t s A u t h o r i z e d % 00451 % % 00452 % % 00453 % % 00454 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00455 % 00456 % IsRightsAuthorized() returns MagickTrue if the policy authorizes the 00457 % requested rights for the specified domain. 00458 % 00459 % The format of the IsRightsAuthorized method is: 00460 % 00461 % MagickBooleanType IsRightsAuthorized(const PolicyDomain domain, 00462 % const PolicyRights rights,const char *pattern) 00463 % 00464 % A description of each parameter follows: 00465 % 00466 % o domain: the policy domain. 00467 % 00468 % o rights: the policy rights. 00469 % 00470 % o pattern: the coder, delegate, filter, or path pattern. 00471 % 00472 */ 00473 MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain, 00474 const PolicyRights rights,const char *pattern) 00475 { 00476 const PolicyInfo 00477 *policy_info; 00478 00479 ExceptionInfo 00480 *exception; 00481 00482 MagickBooleanType 00483 authorized; 00484 00485 register PolicyInfo 00486 *p; 00487 00488 (void) LogMagickEvent(PolicyEvent,GetMagickModule(), 00489 "Domain: %s; rights=%s; pattern=\"%s\" ...", 00490 CommandOptionToMnemonic(MagickPolicyDomainOptions,domain), 00491 CommandOptionToMnemonic(MagickPolicyRightsOptions,rights),pattern); 00492 exception=AcquireExceptionInfo(); 00493 policy_info=GetPolicyInfo("*",exception); 00494 exception=DestroyExceptionInfo(exception); 00495 if (policy_info == (PolicyInfo *) NULL) 00496 return(MagickTrue); 00497 authorized=MagickTrue; 00498 LockSemaphoreInfo(policy_semaphore); 00499 ResetLinkedListIterator(policy_list); 00500 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list); 00501 while ((p != (PolicyInfo *) NULL) && (authorized != MagickFalse)) 00502 { 00503 if ((p->domain == domain) && 00504 (GlobExpression(pattern,p->pattern,MagickFalse) != MagickFalse)) 00505 { 00506 if (((rights & ReadPolicyRights) != 0) && 00507 ((p->rights & ReadPolicyRights) == 0)) 00508 authorized=MagickFalse; 00509 if (((rights & WritePolicyRights) != 0) && 00510 ((p->rights & WritePolicyRights) == 0)) 00511 authorized=MagickFalse; 00512 if (((rights & ExecutePolicyRights) != 0) && 00513 ((p->rights & ExecutePolicyRights) == 0)) 00514 authorized=MagickFalse; 00515 } 00516 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list); 00517 } 00518 UnlockSemaphoreInfo(policy_semaphore); 00519 return(authorized); 00520 } 00521 00522 /* 00523 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00524 % % 00525 % % 00526 % % 00527 % L i s t P o l i c y I n f o % 00528 % % 00529 % % 00530 % % 00531 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00532 % 00533 % ListPolicyInfo() lists policies to the specified file. 00534 % 00535 % The format of the ListPolicyInfo method is: 00536 % 00537 % MagickBooleanType ListPolicyInfo(FILE *file,ExceptionInfo *exception) 00538 % 00539 % A description of each parameter follows. 00540 % 00541 % o file: List policy names to this file handle. 00542 % 00543 % o exception: return any errors or warnings in this structure. 00544 % 00545 */ 00546 MagickExport MagickBooleanType ListPolicyInfo(FILE *file, 00547 ExceptionInfo *exception) 00548 { 00549 const char 00550 *path, 00551 *domain; 00552 00553 const PolicyInfo 00554 **policy_info; 00555 00556 register ssize_t 00557 i; 00558 00559 size_t 00560 number_policies; 00561 00562 /* 00563 List name and attributes of each policy in the list. 00564 */ 00565 if (file == (const FILE *) NULL) 00566 file=stdout; 00567 policy_info=GetPolicyInfoList("*",&number_policies,exception); 00568 if (policy_info == (const PolicyInfo **) NULL) 00569 return(MagickFalse); 00570 path=(const char *) NULL; 00571 for (i=0; i < (ssize_t) number_policies; i++) 00572 { 00573 if (policy_info[i]->stealth != MagickFalse) 00574 continue; 00575 if (((path == (const char *) NULL) || 00576 (LocaleCompare(path,policy_info[i]->path) != 0)) && 00577 (policy_info[i]->path != (char *) NULL)) 00578 (void) FormatLocaleFile(file,"\nPath: %s\n",policy_info[i]->path); 00579 path=policy_info[i]->path; 00580 domain=CommandOptionToMnemonic(MagickPolicyDomainOptions, 00581 policy_info[i]->domain); 00582 (void) FormatLocaleFile(file," Policy: %s\n",domain); 00583 if ((policy_info[i]->domain == ResourcePolicyDomain) || 00584 (policy_info[i]->domain == SystemPolicyDomain)) 00585 { 00586 if (policy_info[i]->name != (char *) NULL) 00587 (void) FormatLocaleFile(file," name: %s\n",policy_info[i]->name); 00588 if (policy_info[i]->value != (char *) NULL) 00589 (void) FormatLocaleFile(file," value: %s\n",policy_info[i]->value); 00590 } 00591 else 00592 { 00593 (void) FormatLocaleFile(file," rights: "); 00594 if (policy_info[i]->rights == NoPolicyRights) 00595 (void) FormatLocaleFile(file,"None "); 00596 if ((policy_info[i]->rights & ReadPolicyRights) != 0) 00597 (void) FormatLocaleFile(file,"Read "); 00598 if ((policy_info[i]->rights & WritePolicyRights) != 0) 00599 (void) FormatLocaleFile(file,"Write "); 00600 if ((policy_info[i]->rights & ExecutePolicyRights) != 0) 00601 (void) FormatLocaleFile(file,"Execute "); 00602 (void) FormatLocaleFile(file,"\n"); 00603 if (policy_info[i]->pattern != (char *) NULL) 00604 (void) FormatLocaleFile(file," pattern: %s\n", 00605 policy_info[i]->pattern); 00606 } 00607 } 00608 policy_info=(const PolicyInfo **) RelinquishMagickMemory((void *) 00609 policy_info); 00610 (void) fflush(file); 00611 return(MagickTrue); 00612 } 00613 00614 /* 00615 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00616 % % 00617 % % 00618 % % 00619 + L o a d P o l i c y L i s t % 00620 % % 00621 % % 00622 % % 00623 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00624 % 00625 % LoadPolicyList() loads the policy configuration file which provides a mapping 00626 % between policy attributes and a policy domain. 00627 % 00628 % The format of the LoadPolicyList method is: 00629 % 00630 % MagickBooleanType LoadPolicyList(const char *xml,const char *filename, 00631 % const size_t depth,ExceptionInfo *exception) 00632 % 00633 % A description of each parameter follows: 00634 % 00635 % o xml: The policy list in XML format. 00636 % 00637 % o filename: The policy list filename. 00638 % 00639 % o depth: depth of <include /> statements. 00640 % 00641 % o exception: return any errors or warnings in this structure. 00642 % 00643 */ 00644 static MagickBooleanType LoadPolicyList(const char *xml,const char *filename, 00645 const size_t depth,ExceptionInfo *exception) 00646 { 00647 char 00648 keyword[MaxTextExtent], 00649 *token; 00650 00651 PolicyInfo 00652 *policy_info; 00653 00654 const char 00655 *q; 00656 00657 MagickBooleanType 00658 status; 00659 00660 /* 00661 Load the policy map file. 00662 */ 00663 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), 00664 "Loading policy file \"%s\" ...",filename); 00665 if (xml == (char *) NULL) 00666 return(MagickFalse); 00667 if (policy_list == (LinkedListInfo *) NULL) 00668 { 00669 policy_list=NewLinkedList(0); 00670 if (policy_list == (LinkedListInfo *) NULL) 00671 { 00672 ThrowFileException(exception,ResourceLimitError, 00673 "MemoryAllocationFailed",filename); 00674 return(MagickFalse); 00675 } 00676 } 00677 status=MagickTrue; 00678 policy_info=(PolicyInfo *) NULL; 00679 token=AcquireString(xml); 00680 for (q=(const char *) xml; *q != '\0'; ) 00681 { 00682 /* 00683 Interpret XML. 00684 */ 00685 GetMagickToken(q,&q,token); 00686 if (*token == '\0') 00687 break; 00688 (void) CopyMagickString(keyword,token,MaxTextExtent); 00689 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0) 00690 { 00691 /* 00692 Docdomain element. 00693 */ 00694 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0')) 00695 GetMagickToken(q,&q,token); 00696 continue; 00697 } 00698 if (LocaleNCompare(keyword,"<!--",4) == 0) 00699 { 00700 /* 00701 Comment element. 00702 */ 00703 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0')) 00704 GetMagickToken(q,&q,token); 00705 continue; 00706 } 00707 if (LocaleCompare(keyword,"<include") == 0) 00708 { 00709 /* 00710 Include element. 00711 */ 00712 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0')) 00713 { 00714 (void) CopyMagickString(keyword,token,MaxTextExtent); 00715 GetMagickToken(q,&q,token); 00716 if (*token != '=') 00717 continue; 00718 GetMagickToken(q,&q,token); 00719 if (LocaleCompare(keyword,"file") == 0) 00720 { 00721 if (depth > 200) 00722 (void) ThrowMagickException(exception,GetMagickModule(), 00723 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token); 00724 else 00725 { 00726 char 00727 path[MaxTextExtent], 00728 *xml; 00729 00730 GetPathComponent(filename,HeadPath,path); 00731 if (*path != '\0') 00732 (void) ConcatenateMagickString(path,DirectorySeparator, 00733 MaxTextExtent); 00734 if (*token == *DirectorySeparator) 00735 (void) CopyMagickString(path,token,MaxTextExtent); 00736 else 00737 (void) ConcatenateMagickString(path,token,MaxTextExtent); 00738 xml=FileToString(path,~0,exception); 00739 if (xml != (char *) NULL) 00740 { 00741 status=LoadPolicyList(xml,path,depth+1,exception); 00742 xml=(char *) RelinquishMagickMemory(xml); 00743 } 00744 } 00745 } 00746 } 00747 continue; 00748 } 00749 if (LocaleCompare(keyword,"<policy") == 0) 00750 { 00751 /* 00752 Policy element. 00753 */ 00754 policy_info=(PolicyInfo *) AcquireMagickMemory(sizeof(*policy_info)); 00755 if (policy_info == (PolicyInfo *) NULL) 00756 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 00757 (void) ResetMagickMemory(policy_info,0,sizeof(*policy_info)); 00758 policy_info->path=ConstantString(filename); 00759 policy_info->exempt=MagickFalse; 00760 policy_info->signature=MagickSignature; 00761 continue; 00762 } 00763 if (policy_info == (PolicyInfo *) NULL) 00764 continue; 00765 if (LocaleCompare(keyword,"/>") == 0) 00766 { 00767 status=AppendValueToLinkedList(policy_list,policy_info); 00768 if (status == MagickFalse) 00769 (void) ThrowMagickException(exception,GetMagickModule(), 00770 ResourceLimitError,"MemoryAllocationFailed","`%s'", 00771 policy_info->name); 00772 policy_info=(PolicyInfo *) NULL; 00773 } 00774 GetMagickToken(q,(const char **) NULL,token); 00775 if (*token != '=') 00776 continue; 00777 GetMagickToken(q,&q,token); 00778 GetMagickToken(q,&q,token); 00779 switch (*keyword) 00780 { 00781 case 'D': 00782 case 'd': 00783 { 00784 if (LocaleCompare((char *) keyword,"domain") == 0) 00785 { 00786 policy_info->domain=(PolicyDomain) ParseCommandOption( 00787 MagickPolicyDomainOptions,MagickTrue,token); 00788 break; 00789 } 00790 break; 00791 } 00792 case 'N': 00793 case 'n': 00794 { 00795 if (LocaleCompare((char *) keyword,"name") == 0) 00796 { 00797 policy_info->name=ConstantString(token); 00798 break; 00799 } 00800 break; 00801 } 00802 case 'P': 00803 case 'p': 00804 { 00805 if (LocaleCompare((char *) keyword,"pattern") == 0) 00806 { 00807 policy_info->pattern=ConstantString(token); 00808 break; 00809 } 00810 break; 00811 } 00812 case 'R': 00813 case 'r': 00814 { 00815 if (LocaleCompare((char *) keyword,"rights") == 0) 00816 { 00817 policy_info->rights=(PolicyRights) ParseCommandOption( 00818 MagickPolicyRightsOptions,MagickTrue,token); 00819 break; 00820 } 00821 break; 00822 } 00823 case 'S': 00824 case 's': 00825 { 00826 if (LocaleCompare((char *) keyword,"stealth") == 0) 00827 { 00828 policy_info->stealth=IsMagickTrue(token); 00829 break; 00830 } 00831 break; 00832 } 00833 case 'V': 00834 case 'v': 00835 { 00836 if (LocaleCompare((char *) keyword,"value") == 0) 00837 { 00838 policy_info->value=ConstantString(token); 00839 break; 00840 } 00841 break; 00842 } 00843 default: 00844 break; 00845 } 00846 } 00847 token=(char *) RelinquishMagickMemory(token); 00848 return(status); 00849 } 00850 00851 /* 00852 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00853 % % 00854 % % 00855 % % 00856 % L o a d P o l i c y L i s t s % 00857 % % 00858 % % 00859 % % 00860 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00861 % 00862 % LoadPolicyList() loads one or more policy configuration file which provides a 00863 % mapping between policy attributes and a policy name. 00864 % 00865 % The format of the LoadPolicyLists method is: 00866 % 00867 % MagickBooleanType LoadPolicyLists(const char *filename, 00868 % ExceptionInfo *exception) 00869 % 00870 % A description of each parameter follows: 00871 % 00872 % o filename: the font file name. 00873 % 00874 % o exception: return any errors or warnings in this structure. 00875 % 00876 */ 00877 static MagickBooleanType LoadPolicyLists(const char *filename, 00878 ExceptionInfo *exception) 00879 { 00880 const StringInfo 00881 *option; 00882 00883 LinkedListInfo 00884 *options; 00885 00886 MagickStatusType 00887 status; 00888 00889 register ssize_t 00890 i; 00891 00892 /* 00893 Load built-in policy map. 00894 */ 00895 status=MagickFalse; 00896 if (policy_list == (LinkedListInfo *) NULL) 00897 { 00898 policy_list=NewLinkedList(0); 00899 if (policy_list == (LinkedListInfo *) NULL) 00900 { 00901 ThrowFileException(exception,ResourceLimitError, 00902 "MemoryAllocationFailed",filename); 00903 return(MagickFalse); 00904 } 00905 } 00906 for (i=0; i < (ssize_t) (sizeof(PolicyMap)/sizeof(*PolicyMap)); i++) 00907 { 00908 PolicyInfo 00909 *policy_info; 00910 00911 register const PolicyMapInfo 00912 *p; 00913 00914 p=PolicyMap+i; 00915 policy_info=(PolicyInfo *) AcquireMagickMemory(sizeof(*policy_info)); 00916 if (policy_info == (PolicyInfo *) NULL) 00917 { 00918 (void) ThrowMagickException(exception,GetMagickModule(), 00919 ResourceLimitError,"MemoryAllocationFailed","`%s'",policy_info->name); 00920 continue; 00921 } 00922 (void) ResetMagickMemory(policy_info,0,sizeof(*policy_info)); 00923 policy_info->path=(char *) "[built-in]"; 00924 policy_info->domain=p->domain; 00925 policy_info->rights=p->rights; 00926 policy_info->name=(char *) p->name; 00927 policy_info->pattern=(char *) p->pattern; 00928 policy_info->value=(char *) p->value; 00929 policy_info->exempt=MagickTrue; 00930 policy_info->signature=MagickSignature; 00931 status=AppendValueToLinkedList(policy_list,policy_info); 00932 if (status == MagickFalse) 00933 (void) ThrowMagickException(exception,GetMagickModule(), 00934 ResourceLimitError,"MemoryAllocationFailed","`%s'",policy_info->name); 00935 } 00936 /* 00937 Load external policy map. 00938 */ 00939 options=GetConfigureOptions(filename,exception); 00940 option=(const StringInfo *) GetNextValueInLinkedList(options); 00941 while (option != (const StringInfo *) NULL) 00942 { 00943 status|=LoadPolicyList((const char *) GetStringInfoDatum(option), 00944 GetStringInfoPath(option),0,exception); 00945 option=(const StringInfo *) GetNextValueInLinkedList(options); 00946 } 00947 options=DestroyConfigureOptions(options); 00948 return(status != 0 ? MagickTrue : MagickFalse); 00949 } 00950 00951 /* 00952 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00953 % % 00954 % % 00955 % % 00956 + P o l i c y C o m p o n e n t G e n e s i s % 00957 % % 00958 % % 00959 % % 00960 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00961 % 00962 % PolicyComponentGenesis() instantiates the policy component. 00963 % 00964 % The format of the PolicyComponentGenesis method is: 00965 % 00966 % MagickBooleanType PolicyComponentGenesis(void) 00967 % 00968 */ 00969 MagickPrivate MagickBooleanType PolicyComponentGenesis(void) 00970 { 00971 AcquireSemaphoreInfo(&policy_semaphore); 00972 return(MagickTrue); 00973 } 00974 00975 /* 00976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00977 % % 00978 % % 00979 % % 00980 + P o l i c y C o m p o n e n t T e r m i n u s % 00981 % % 00982 % % 00983 % % 00984 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00985 % 00986 % PolicyComponentTerminus() destroys the policy component. 00987 % 00988 % The format of the PolicyComponentTerminus method is: 00989 % 00990 % PolicyComponentTerminus(void) 00991 % 00992 */ 00993 00994 static void *DestroyPolicyElement(void *policy_info) 00995 { 00996 register PolicyInfo 00997 *p; 00998 00999 p=(PolicyInfo *) policy_info; 01000 if (p->exempt == MagickFalse) 01001 { 01002 if (p->value != (char *) NULL) 01003 p->value=DestroyString(p->value); 01004 if (p->pattern != (char *) NULL) 01005 p->pattern=DestroyString(p->pattern); 01006 if (p->name != (char *) NULL) 01007 p->name=DestroyString(p->name); 01008 if (p->path != (char *) NULL) 01009 p->path=DestroyString(p->path); 01010 } 01011 p=(PolicyInfo *) RelinquishMagickMemory(p); 01012 return((void *) NULL); 01013 } 01014 01015 MagickPrivate void PolicyComponentTerminus(void) 01016 { 01017 if (policy_semaphore == (SemaphoreInfo *) NULL) 01018 AcquireSemaphoreInfo(&policy_semaphore); 01019 LockSemaphoreInfo(policy_semaphore); 01020 if (policy_list != (LinkedListInfo *) NULL) 01021 policy_list=DestroyLinkedList(policy_list,DestroyPolicyElement); 01022 instantiate_policy=MagickFalse; 01023 UnlockSemaphoreInfo(policy_semaphore); 01024 DestroySemaphoreInfo(&policy_semaphore); 01025 }