MagickCore  6.7.5
policy.c
Go to the documentation of this file.
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 }