MagickCore  7.0.7
Convert, Edit, Or Compose Bitmap Images
policy.c
Go to the documentation of this file.
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % PPPP OOO L IIIII CCCC Y Y %
6 % P P O O L I C Y Y %
7 % PPPP O O L I C Y %
8 % P O O L I C Y %
9 % P OOO LLLLL IIIII CCCC Y %
10 % %
11 % %
12 % MagickCore Policy Methods %
13 % %
14 % Software Design %
15 % Cristy %
16 % July 1992 %
17 % %
18 % %
19 % Copyright 1999-2018 ImageMagick Studio LLC, a non-profit organization %
20 % dedicated to making software imaging solutions freely available. %
21 % %
22 % You may not use this file except in compliance with the License. You may %
23 % obtain a copy of the License at %
24 % %
25 % https://www.imagemagick.org/script/license.php %
26 % %
27 % Unless required by applicable law or agreed to in writing, software %
28 % distributed under the License is distributed on an "AS IS" BASIS, %
29 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
30 % See the License for the specific language governing permissions and %
31 % limitations under the License. %
32 % %
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34 %
35 % We use linked-lists because splay-trees do not currently support duplicate
36 % key / value pairs (.e.g X11 green compliance and SVG green compliance).
37 %
38 */
39 
40 /*
41  Include declarations.
42 */
43 #include "MagickCore/studio.h"
44 #include "MagickCore/client.h"
45 #include "MagickCore/configure.h"
47 #include "MagickCore/exception.h"
49 #include "MagickCore/memory_.h"
51 #include "MagickCore/monitor.h"
53 #include "MagickCore/option.h"
54 #include "MagickCore/policy.h"
57 #include "MagickCore/semaphore.h"
58 #include "MagickCore/string_.h"
59 #include "MagickCore/token.h"
60 #include "MagickCore/utility.h"
62 #include "MagickCore/xml-tree.h"
64 
65 /*
66  Define declarations.
67 */
68 #define PolicyFilename "policy.xml"
69 
70 /*
71  Typedef declarations.
72 */
74 {
75  char
76  *path;
77 
80 
83 
84  char
85  *name,
86  *pattern,
87  *value;
88 
91  stealth,
92  debug;
93 
96 
97  size_t
99 };
100 
101 typedef struct _PolicyMapInfo
102 {
103  const PolicyDomain
105 
106  const PolicyRights
108 
109  const char
111  *pattern,
112  *value;
113 } PolicyMapInfo;
114 
115 /*
116  Static declarations.
117 */
118 static const PolicyMapInfo
120  {
121  { UndefinedPolicyDomain, UndefinedPolicyRights, (const char *) NULL,
122  (const char *) NULL, (const char *) NULL }
123  };
124 
125 static LinkedListInfo
127 
128 static SemaphoreInfo
130 
131 /*
132  Forward declarations.
133 */
134 static MagickBooleanType
136  LoadPolicyCache(LinkedListInfo *,const char *,const char *,const size_t,
137  ExceptionInfo *);
138 
139 /*
140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
141 % %
142 % %
143 % %
144 % A c q u i r e P o l i c y C a c h e %
145 % %
146 % %
147 % %
148 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
149 %
150 % AcquirePolicyCache() caches one or more policy configurations which provides
151 % a mapping between policy attributes and a policy name.
152 %
153 % The format of the AcquirePolicyCache method is:
154 %
155 % LinkedListInfo *AcquirePolicyCache(const char *filename,
156 % ExceptionInfo *exception)
157 %
158 % A description of each parameter follows:
159 %
160 % o filename: the policy configuration file name.
161 %
162 % o exception: return any errors or warnings in this structure.
163 %
164 */
165 static LinkedListInfo *AcquirePolicyCache(const char *filename,
166  ExceptionInfo *exception)
167 {
169  *cache;
170 
172  status;
173 
174  register ssize_t
175  i;
176 
177  /*
178  Load external policy map.
179  */
180  cache=NewLinkedList(0);
181  status=MagickTrue;
182 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
183  status=LoadPolicyCache(cache,ZeroConfigurationPolicy,"[zero-configuration]",0,
184  exception);
185 #else
186  {
187  const StringInfo
188  *option;
189 
191  *options;
192 
193  options=GetConfigureOptions(filename,exception);
194  option=(const StringInfo *) GetNextValueInLinkedList(options);
195  while (option != (const StringInfo *) NULL)
196  {
197  status&=LoadPolicyCache(cache,(const char *) GetStringInfoDatum(option),
198  GetStringInfoPath(option),0,exception);
199  option=(const StringInfo *) GetNextValueInLinkedList(options);
200  }
201  options=DestroyConfigureOptions(options);
202  }
203 #endif
204  /*
205  Load built-in policy map.
206  */
207  for (i=0; i < (ssize_t) (sizeof(PolicyMap)/sizeof(*PolicyMap)); i++)
208  {
209  PolicyInfo
210  *policy_info;
211 
212  register const PolicyMapInfo
213  *p;
214 
215  p=PolicyMap+i;
216  policy_info=(PolicyInfo *) AcquireMagickMemory(sizeof(*policy_info));
217  if (policy_info == (PolicyInfo *) NULL)
218  {
219  (void) ThrowMagickException(exception,GetMagickModule(),
220  ResourceLimitError,"MemoryAllocationFailed","`%s'",p->name);
221  continue;
222  }
223  (void) ResetMagickMemory(policy_info,0,sizeof(*policy_info));
224  policy_info->path=(char *) "[built-in]";
225  policy_info->domain=p->domain;
226  policy_info->rights=p->rights;
227  policy_info->name=(char *) p->name;
228  policy_info->pattern=(char *) p->pattern;
229  policy_info->value=(char *) p->value;
230  policy_info->exempt=MagickTrue;
231  policy_info->signature=MagickCoreSignature;
232  status&=AppendValueToLinkedList(cache,policy_info);
233  if (status == MagickFalse)
234  (void) ThrowMagickException(exception,GetMagickModule(),
235  ResourceLimitError,"MemoryAllocationFailed","`%s'",policy_info->name);
236  }
237  return(cache);
238 }
239 
240 /*
241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
242 % %
243 % %
244 % %
245 + G e t P o l i c y I n f o %
246 % %
247 % %
248 % %
249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
250 %
251 % GetPolicyInfo() searches the policy list for the specified name and if found
252 % returns attributes for that policy.
253 %
254 % The format of the GetPolicyInfo method is:
255 %
256 % PolicyInfo *GetPolicyInfo(const char *name,ExceptionInfo *exception)
257 %
258 % A description of each parameter follows:
259 %
260 % o name: the policy name.
261 %
262 % o exception: return any errors or warnings in this structure.
263 %
264 */
265 static PolicyInfo *GetPolicyInfo(const char *name,ExceptionInfo *exception)
266 {
267  char
268  policyname[MagickPathExtent];
269 
271  domain;
272 
273  register PolicyInfo
274  *p;
275 
276  register char
277  *q;
278 
279  assert(exception != (ExceptionInfo *) NULL);
280  if (IsPolicyCacheInstantiated(exception) == MagickFalse)
281  return((PolicyInfo *) NULL);
282  /*
283  Strip names of whitespace.
284  */
285  *policyname='\0';
286  if (name != (const char *) NULL)
287  (void) CopyMagickString(policyname,name,MagickPathExtent);
288  for (q=policyname; *q != '\0'; q++)
289  {
290  if (isspace((int) ((unsigned char) *q)) == 0)
291  continue;
292  (void) CopyMagickString(q,q+1,MagickPathExtent);
293  q--;
294  }
295  /*
296  Strip domain from policy name (e.g. resource:map).
297  */
298  domain=UndefinedPolicyDomain;
299  for (q=policyname; *q != '\0'; q++)
300  {
301  if (*q != ':')
302  continue;
303  *q='\0';
305  MagickTrue,policyname);
306  (void) CopyMagickString(policyname,q+1,MagickPathExtent);
307  break;
308  }
309  /*
310  Search for policy tag.
311  */
315  if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
316  {
318  return(p);
319  }
320  while (p != (PolicyInfo *) NULL)
321  {
322  if ((domain == UndefinedPolicyDomain) || (p->domain == domain))
323  if (LocaleCompare(policyname,p->name) == 0)
324  break;
326  }
327  if (p != (PolicyInfo *) NULL)
331  return(p);
332 }
333 
334 /*
335 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
336 % %
337 % %
338 % %
339 % G e t P o l i c y I n f o L i s t %
340 % %
341 % %
342 % %
343 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
344 %
345 % GetPolicyInfoList() returns any policies that match the specified pattern.
346 %
347 % The format of the GetPolicyInfoList function is:
348 %
349 % const PolicyInfo **GetPolicyInfoList(const char *pattern,
350 % size_t *number_policies,ExceptionInfo *exception)
351 %
352 % A description of each parameter follows:
353 %
354 % o pattern: Specifies a pointer to a text string containing a pattern.
355 %
356 % o number_policies: returns the number of policies in the list.
357 %
358 % o exception: return any errors or warnings in this structure.
359 %
360 */
362  size_t *number_policies,ExceptionInfo *exception)
363 {
364  const PolicyInfo
365  **policies;
366 
367  register const PolicyInfo
368  *p;
369 
370  register ssize_t
371  i;
372 
373  /*
374  Allocate policy list.
375  */
376  assert(pattern != (char *) NULL);
378  assert(number_policies != (size_t *) NULL);
379  *number_policies=0;
380  p=GetPolicyInfo("*",exception);
381  if (p == (const PolicyInfo *) NULL)
382  return((const PolicyInfo **) NULL);
383  policies=(const PolicyInfo **) AcquireQuantumMemory((size_t)
384  GetNumberOfElementsInLinkedList(policy_cache)+1UL,sizeof(*policies));
385  if (policies == (const PolicyInfo **) NULL)
386  return((const PolicyInfo **) NULL);
387  /*
388  Generate policy list.
389  */
393  for (i=0; p != (const PolicyInfo *) NULL; )
394  {
395  if ((p->stealth == MagickFalse) &&
396  (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
397  policies[i++]=p;
399  }
401  policies[i]=(PolicyInfo *) NULL;
402  *number_policies=(size_t) i;
403  return(policies);
404 }
405 
406 /*
407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
408 % %
409 % %
410 % %
411 % G e t P o l i c y L i s t %
412 % %
413 % %
414 % %
415 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
416 %
417 % GetPolicyList() returns any policies that match the specified pattern.
418 %
419 % The format of the GetPolicyList function is:
420 %
421 % char **GetPolicyList(const char *pattern,size_t *number_policies,
422 % ExceptionInfo *exception)
423 %
424 % A description of each parameter follows:
425 %
426 % o pattern: a pointer to a text string containing a pattern.
427 %
428 % o number_policies: returns the number of policies in the list.
429 %
430 % o exception: return any errors or warnings in this structure.
431 %
432 */
433 MagickExport char **GetPolicyList(const char *pattern,
434  size_t *number_policies,ExceptionInfo *exception)
435 {
436  char
437  **policies;
438 
439  register const PolicyInfo
440  *p;
441 
442  register ssize_t
443  i;
444 
445  /*
446  Allocate policy list.
447  */
448  assert(pattern != (char *) NULL);
450  assert(number_policies != (size_t *) NULL);
451  *number_policies=0;
452  p=GetPolicyInfo("*",exception);
453  if (p == (const PolicyInfo *) NULL)
454  return((char **) NULL);
455  policies=(char **) AcquireQuantumMemory((size_t)
456  GetNumberOfElementsInLinkedList(policy_cache)+1UL,sizeof(*policies));
457  if (policies == (char **) NULL)
458  return((char **) NULL);
459  /*
460  Generate policy list.
461  */
465  for (i=0; p != (const PolicyInfo *) NULL; )
466  {
467  if ((p->stealth == MagickFalse) &&
468  (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
469  policies[i++]=ConstantString(p->name);
471  }
473  policies[i]=(char *) NULL;
474  *number_policies=(size_t) i;
475  return(policies);
476 }
477 
478 /*
479 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
480 % %
481 % %
482 % %
483 % G e t P o l i c y V a l u e %
484 % %
485 % %
486 % %
487 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
488 %
489 % GetPolicyValue() returns the value associated with the named policy.
490 %
491 % The format of the GetPolicyValue method is:
492 %
493 % char *GetPolicyValue(const char *name)
494 %
495 % A description of each parameter follows:
496 %
497 % o policy_info: The policy info.
498 %
499 */
500 MagickExport char *GetPolicyValue(const char *name)
501 {
502  const char
503  *value;
504 
505  const PolicyInfo
506  *policy_info;
507 
509  *exception;
510 
511  assert(name != (const char *) NULL);
513  exception=AcquireExceptionInfo();
514  policy_info=GetPolicyInfo(name,exception);
515  exception=DestroyExceptionInfo(exception);
516  if (policy_info == (PolicyInfo *) NULL)
517  return((char *) NULL);
518  value=policy_info->value;
519  if ((value == (const char *) NULL) || (*value == '\0'))
520  return((char *) NULL);
521  return(ConstantString(value));
522 }
523 
524 /*
525 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
526 % %
527 % %
528 % %
529 + I s P o l i c y C a c h e I n s t a n t i a t e d %
530 % %
531 % %
532 % %
533 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
534 %
535 % IsPolicyCacheInstantiated() determines if the policy list is instantiated.
536 % If not, it instantiates the list and returns it.
537 %
538 % The format of the IsPolicyInstantiated method is:
539 %
540 % MagickBooleanType IsPolicyCacheInstantiated(ExceptionInfo *exception)
541 %
542 % A description of each parameter follows.
543 %
544 % o exception: return any errors or warnings in this structure.
545 %
546 */
548 {
549  if (policy_cache == (LinkedListInfo *) NULL)
550  {
551  if (policy_semaphore == (SemaphoreInfo *) NULL)
554  if (policy_cache == (LinkedListInfo *) NULL)
557  }
558  return(policy_cache != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
559 }
560 
561 /*
562 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
563 % %
564 % %
565 % %
566 % I s R i g h t s A u t h o r i z e d %
567 % %
568 % %
569 % %
570 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
571 %
572 % IsRightsAuthorized() returns MagickTrue if the policy authorizes the
573 % requested rights for the specified domain.
574 %
575 % The format of the IsRightsAuthorized method is:
576 %
577 % MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
578 % const PolicyRights rights,const char *pattern)
579 %
580 % A description of each parameter follows:
581 %
582 % o domain: the policy domain.
583 %
584 % o rights: the policy rights.
585 %
586 % o pattern: the coder, delegate, filter, or path pattern.
587 %
588 */
590  const PolicyRights rights,const char *pattern)
591 {
592  const PolicyInfo
593  *policy_info;
594 
596  *exception;
597 
599  authorized;
600 
601  register PolicyInfo
602  *p;
603 
605  "Domain: %s; rights=%s; pattern=\"%s\" ...",
608  exception=AcquireExceptionInfo();
609  policy_info=GetPolicyInfo("*",exception);
610  exception=DestroyExceptionInfo(exception);
611  if (policy_info == (PolicyInfo *) NULL)
612  return(MagickTrue);
613  authorized=MagickTrue;
617  while (p != (PolicyInfo *) NULL)
618  {
619  if ((p->domain == domain) &&
621  {
622  if ((rights & ReadPolicyRights) != 0)
623  authorized=(p->rights & ReadPolicyRights) != 0 ? MagickTrue :
624  MagickFalse;
625  if ((rights & WritePolicyRights) != 0)
626  authorized=(p->rights & WritePolicyRights) != 0 ? MagickTrue :
627  MagickFalse;
628  if ((rights & ExecutePolicyRights) != 0)
629  authorized=(p->rights & ExecutePolicyRights) != 0 ? MagickTrue :
630  MagickFalse;
631  }
633  }
635  return(authorized);
636 }
637 
638 /*
639 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
640 % %
641 % %
642 % %
643 % L i s t P o l i c y I n f o %
644 % %
645 % %
646 % %
647 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
648 %
649 % ListPolicyInfo() lists policies to the specified file.
650 %
651 % The format of the ListPolicyInfo method is:
652 %
653 % MagickBooleanType ListPolicyInfo(FILE *file,ExceptionInfo *exception)
654 %
655 % A description of each parameter follows.
656 %
657 % o file: List policy names to this file handle.
658 %
659 % o exception: return any errors or warnings in this structure.
660 %
661 */
663  ExceptionInfo *exception)
664 {
665  const char
666  *path,
667  *domain;
668 
669  const PolicyInfo
670  **policy_info;
671 
672  register ssize_t
673  i;
674 
675  size_t
676  number_policies;
677 
678  /*
679  List name and attributes of each policy in the list.
680  */
681  if (file == (const FILE *) NULL)
682  file=stdout;
683  policy_info=GetPolicyInfoList("*",&number_policies,exception);
684  if (policy_info == (const PolicyInfo **) NULL)
685  return(MagickFalse);
686  path=(const char *) NULL;
687  for (i=0; i < (ssize_t) number_policies; i++)
688  {
689  if (policy_info[i]->stealth != MagickFalse)
690  continue;
691  if (((path == (const char *) NULL) ||
692  (LocaleCompare(path,policy_info[i]->path) != 0)) &&
693  (policy_info[i]->path != (char *) NULL))
694  (void) FormatLocaleFile(file,"\nPath: %s\n",policy_info[i]->path);
695  path=policy_info[i]->path;
697  policy_info[i]->domain);
698  (void) FormatLocaleFile(file," Policy: %s\n",domain);
699  if ((policy_info[i]->domain == CachePolicyDomain) ||
700  (policy_info[i]->domain == ResourcePolicyDomain) ||
701  (policy_info[i]->domain == SystemPolicyDomain))
702  {
703  if (policy_info[i]->name != (char *) NULL)
704  (void) FormatLocaleFile(file," name: %s\n",policy_info[i]->name);
705  if (policy_info[i]->value != (char *) NULL)
706  (void) FormatLocaleFile(file," value: %s\n",policy_info[i]->value);
707  }
708  else
709  {
710  (void) FormatLocaleFile(file," rights: ");
711  if (policy_info[i]->rights == NoPolicyRights)
712  (void) FormatLocaleFile(file,"None ");
713  if ((policy_info[i]->rights & ReadPolicyRights) != 0)
714  (void) FormatLocaleFile(file,"Read ");
715  if ((policy_info[i]->rights & WritePolicyRights) != 0)
716  (void) FormatLocaleFile(file,"Write ");
717  if ((policy_info[i]->rights & ExecutePolicyRights) != 0)
718  (void) FormatLocaleFile(file,"Execute ");
719  (void) FormatLocaleFile(file,"\n");
720  if (policy_info[i]->pattern != (char *) NULL)
721  (void) FormatLocaleFile(file," pattern: %s\n",
722  policy_info[i]->pattern);
723  }
724  }
725  policy_info=(const PolicyInfo **) RelinquishMagickMemory((void *)
726  policy_info);
727  (void) fflush(file);
728  return(MagickTrue);
729 }
730 
731 /*
732 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
733 % %
734 % %
735 % %
736 + L o a d P o l i c y C a c h e %
737 % %
738 % %
739 % %
740 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
741 %
742 % LoadPolicyCache() loads the policy configurations which provides a mapping
743 % between policy attributes and a policy domain.
744 %
745 % The format of the LoadPolicyCache method is:
746 %
747 % MagickBooleanType LoadPolicyCache(LinkedListInfo *cache,const char *xml,
748 % const char *filename,const size_t depth,ExceptionInfo *exception)
749 %
750 % A description of each parameter follows:
751 %
752 % o xml: The policy list in XML format.
753 %
754 % o filename: The policy list filename.
755 %
756 % o depth: depth of <include /> statements.
757 %
758 % o exception: return any errors or warnings in this structure.
759 %
760 */
761 static MagickBooleanType LoadPolicyCache(LinkedListInfo *cache,const char *xml,
762  const char *filename,const size_t depth,ExceptionInfo *exception)
763 {
764  char
765  keyword[MagickPathExtent],
766  *token;
767 
768  const char
769  *q;
770 
772  status;
773 
774  PolicyInfo
775  *policy_info;
776 
777  size_t
778  extent;
779 
780  /*
781  Load the policy map file.
782  */
784  "Loading policy file \"%s\" ...",filename);
785  if (xml == (char *) NULL)
786  return(MagickFalse);
787  status=MagickTrue;
788  policy_info=(PolicyInfo *) NULL;
789  token=AcquireString(xml);
790  extent=strlen(token)+MagickPathExtent;
791  for (q=(const char *) xml; *q != '\0'; )
792  {
793  /*
794  Interpret XML.
795  */
796  GetNextToken(q,&q,extent,token);
797  if (*token == '\0')
798  break;
799  (void) CopyMagickString(keyword,token,MagickPathExtent);
800  if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
801  {
802  /*
803  Docdomain element.
804  */
805  while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
806  GetNextToken(q,&q,extent,token);
807  continue;
808  }
809  if (LocaleNCompare(keyword,"<!--",4) == 0)
810  {
811  /*
812  Comment element.
813  */
814  while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
815  GetNextToken(q,&q,extent,token);
816  continue;
817  }
818  if (LocaleCompare(keyword,"<include") == 0)
819  {
820  /*
821  Include element.
822  */
823  while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
824  {
825  (void) CopyMagickString(keyword,token,MagickPathExtent);
826  GetNextToken(q,&q,extent,token);
827  if (*token != '=')
828  continue;
829  GetNextToken(q,&q,extent,token);
830  if (LocaleCompare(keyword,"file") == 0)
831  {
832  if (depth > 200)
833  (void) ThrowMagickException(exception,GetMagickModule(),
834  ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
835  else
836  {
837  char
839  *file_xml;
840 
841  GetPathComponent(filename,HeadPath,path);
842  if (*path != '\0')
845  if (*token == *DirectorySeparator)
846  (void) CopyMagickString(path,token,MagickPathExtent);
847  else
848  (void) ConcatenateMagickString(path,token,MagickPathExtent);
849  file_xml=FileToXML(path,~0UL);
850  if (file_xml != (char *) NULL)
851  {
852  status&=LoadPolicyCache(cache,file_xml,path,
853  depth+1,exception);
854  file_xml=DestroyString(file_xml);
855  }
856  }
857  }
858  }
859  continue;
860  }
861  if (LocaleCompare(keyword,"<policy") == 0)
862  {
863  /*
864  Policy element.
865  */
866  policy_info=(PolicyInfo *) AcquireCriticalMemory(sizeof(*policy_info));
867  (void) ResetMagickMemory(policy_info,0,sizeof(*policy_info));
868  policy_info->path=ConstantString(filename);
869  policy_info->exempt=MagickFalse;
870  policy_info->signature=MagickCoreSignature;
871  continue;
872  }
873  if (policy_info == (PolicyInfo *) NULL)
874  continue;
875  if ((LocaleCompare(keyword,"/>") == 0) ||
876  (LocaleCompare(keyword,"</policy>") == 0))
877  {
878  status=AppendValueToLinkedList(cache,policy_info);
879  if (status == MagickFalse)
880  (void) ThrowMagickException(exception,GetMagickModule(),
881  ResourceLimitError,"MemoryAllocationFailed","`%s'",
882  policy_info->name);
883  policy_info=(PolicyInfo *) NULL;
884  continue;
885  }
886  GetNextToken(q,(const char **) NULL,extent,token);
887  if (*token != '=')
888  continue;
889  GetNextToken(q,&q,extent,token);
890  GetNextToken(q,&q,extent,token);
891  switch (*keyword)
892  {
893  case 'D':
894  case 'd':
895  {
896  if (LocaleCompare((char *) keyword,"domain") == 0)
897  {
898  policy_info->domain=(PolicyDomain) ParseCommandOption(
900  break;
901  }
902  break;
903  }
904  case 'N':
905  case 'n':
906  {
907  if (LocaleCompare((char *) keyword,"name") == 0)
908  {
909  policy_info->name=ConstantString(token);
910  break;
911  }
912  break;
913  }
914  case 'P':
915  case 'p':
916  {
917  if (LocaleCompare((char *) keyword,"pattern") == 0)
918  {
919  policy_info->pattern=ConstantString(token);
920  break;
921  }
922  break;
923  }
924  case 'R':
925  case 'r':
926  {
927  if (LocaleCompare((char *) keyword,"rights") == 0)
928  {
929  policy_info->rights=(PolicyRights) ParseCommandOption(
931  break;
932  }
933  break;
934  }
935  case 'S':
936  case 's':
937  {
938  if (LocaleCompare((char *) keyword,"stealth") == 0)
939  {
940  policy_info->stealth=IsStringTrue(token);
941  break;
942  }
943  break;
944  }
945  case 'V':
946  case 'v':
947  {
948  if (LocaleCompare((char *) keyword,"value") == 0)
949  {
950  policy_info->value=ConstantString(token);
951  break;
952  }
953  break;
954  }
955  default:
956  break;
957  }
958  }
959  token=(char *) RelinquishMagickMemory(token);
960  return(status != 0 ? MagickTrue : MagickFalse);
961 }
962 
963 /*
964 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
965 % %
966 % %
967 % %
968 + P o l i c y C o m p o n e n t G e n e s i s %
969 % %
970 % %
971 % %
972 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
973 %
974 % PolicyComponentGenesis() instantiates the policy component.
975 %
976 % The format of the PolicyComponentGenesis method is:
977 %
978 % MagickBooleanType PolicyComponentGenesis(void)
979 %
980 */
982 {
983  if (policy_semaphore == (SemaphoreInfo *) NULL)
985  return(MagickTrue);
986 }
987 
988 /*
989 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
990 % %
991 % %
992 % %
993 + P o l i c y C o m p o n e n t T e r m i n u s %
994 % %
995 % %
996 % %
997 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
998 %
999 % PolicyComponentTerminus() destroys the policy component.
1000 %
1001 % The format of the PolicyComponentTerminus method is:
1002 %
1003 % PolicyComponentTerminus(void)
1004 %
1005 */
1006 
1007 static void *DestroyPolicyElement(void *policy_info)
1008 {
1009  register PolicyInfo
1010  *p;
1011 
1012  p=(PolicyInfo *) policy_info;
1013  if (p->exempt == MagickFalse)
1014  {
1015  if (p->value != (char *) NULL)
1016  p->value=DestroyString(p->value);
1017  if (p->pattern != (char *) NULL)
1018  p->pattern=DestroyString(p->pattern);
1019  if (p->name != (char *) NULL)
1020  p->name=DestroyString(p->name);
1021  if (p->path != (char *) NULL)
1022  p->path=DestroyString(p->path);
1023  }
1025  return((void *) NULL);
1026 }
1027 
1029 {
1030  if (policy_semaphore == (SemaphoreInfo *) NULL)
1033  if (policy_cache != (LinkedListInfo *) NULL)
1037 }
1038 
1039 /*
1040 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1041 % %
1042 % %
1043 % %
1044 % S e t M a g i c k S e c u r i t y P o l i c y %
1045 % %
1046 % %
1047 % %
1048 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1049 %
1050 % SetMagickSecurityPolicy() sets the ImageMagick security policy. It returns
1051 % MagickFalse if the policy is already set or if the policy does not parse.
1052 %
1053 % The format of the SetMagickSecurityPolicy method is:
1054 %
1055 % MagickBooleanType SetMagickSecurityPolicy(const char *policy,
1056 % ExceptionInfo *exception)
1057 %
1058 % A description of each parameter follows:
1059 %
1060 % o policy: the security policy in the XML format.
1061 %
1062 % o exception: return any errors or warnings in this structure.
1063 %
1064 */
1066  ExceptionInfo *exception)
1067 {
1068  PolicyInfo
1069  *p;
1070 
1072  status;
1073 
1074  assert(exception != (ExceptionInfo *) NULL);
1075  if (policy == (const char *) NULL)
1076  return(MagickFalse);
1077  if (IsPolicyCacheInstantiated(exception) == MagickFalse)
1078  return(MagickFalse);
1082  if ((p != (PolicyInfo *) NULL) && (p->domain != UndefinedPolicyDomain))
1083  {
1085  return(MagickFalse);
1086  }
1088  status=LoadPolicyCache(policy_cache,policy,"[user-policy]",0,exception);
1089  if (status == MagickFalse)
1090  return(MagickFalse);
1091  return(ResourceComponentGenesis());
1092 }
MagickBooleanType stealth
Definition: policy.c:90
char * value
Definition: policy.c:85
MagickPrivate MagickBooleanType ResourceComponentGenesis(void)
Definition: resource.c:1187
MagickExport const PolicyInfo ** GetPolicyInfoList(const char *pattern, size_t *number_policies, ExceptionInfo *exception)
Definition: policy.c:361
MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain, const PolicyRights rights, const char *pattern)
Definition: policy.c:589
MagickExport MagickBooleanType ListPolicyInfo(FILE *file, ExceptionInfo *exception)
Definition: policy.c:662
MagickExport void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:450
MagickExport void ResetLinkedListIterator(LinkedListInfo *list_info)
Definition: linked-list.c:959
MagickExport ssize_t ParseCommandOption(const CommandOption option, const MagickBooleanType list, const char *options)
Definition: option.c:2953
static SemaphoreInfo * policy_semaphore
Definition: policy.c:129
SemaphoreInfo * semaphore
Definition: policy.c:95
PolicyRights
Definition: policy.h:40
MagickExport LinkedListInfo * DestroyLinkedList(LinkedListInfo *list_info, void *(*relinquish_value)(void *))
Definition: linked-list.c:219
struct _PolicyMapInfo PolicyMapInfo
char * name
Definition: policy.c:85
MagickBooleanType debug
Definition: policy.c:90
MagickExport size_t ConcatenateMagickString(char *destination, const char *source, const size_t length)
Definition: string.c:410
MagickExport SemaphoreInfo * AcquireSemaphoreInfo(void)
Definition: semaphore.c:192
MagickExport MagickBooleanType InsertValueInLinkedList(LinkedListInfo *list_info, const size_t index, const void *value)
Definition: linked-list.c:447
const char * name
Definition: policy.c:110
char * pattern
Definition: policy.c:85
static PolicyInfo * GetPolicyInfo(const char *name, ExceptionInfo *exception)
Definition: policy.c:265
MagickExport ExceptionInfo * AcquireExceptionInfo(void)
Definition: exception.c:108
MagickExport MagickBooleanType AppendValueToLinkedList(LinkedListInfo *list_info, const void *value)
Definition: linked-list.c:111
MagickExport void * RemoveElementByValueFromLinkedList(LinkedListInfo *list_info, const void *value)
Definition: linked-list.c:756
static LinkedListInfo * policy_cache
Definition: policy.c:126
MagickPrivate MagickBooleanType PolicyComponentGenesis(void)
Definition: policy.c:981
Definition: log.h:52
static const PolicyMapInfo PolicyMap[]
Definition: policy.c:119
MagickExport void * GetNextValueInLinkedList(LinkedListInfo *list_info)
Definition: linked-list.c:305
size_t signature
Definition: policy.c:98
#define MagickCoreSignature
MagickExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:293
MagickExport unsigned char * GetStringInfoDatum(const StringInfo *string_info)
Definition: string.c:1283
MagickExport LinkedListInfo * GetConfigureOptions(const char *filename, ExceptionInfo *exception)
Definition: configure.c:654
static MagickBooleanType LoadPolicyCache(LinkedListInfo *, const char *, const char *, const size_t, ExceptionInfo *)
Definition: policy.c:761
MagickExport void GetPathComponent(const char *path, PathType type, char *component)
Definition: utility.c:1213
MagickExport ssize_t FormatLocaleFile(FILE *file, const char *magick_restrict format,...)
Definition: locale.c:378
MagickBooleanType
Definition: magick-type.h:156
#define DirectorySeparator
Definition: studio.h:254
unsigned int MagickStatusType
Definition: magick-type.h:119
MagickExport char * AcquireString(const char *source)
Definition: string.c:124
MagickExport void * ResetMagickMemory(void *memory, int byte, const size_t size)
Definition: memory.c:1164
MagickExport const char * CommandOptionToMnemonic(const CommandOption option, const ssize_t type)
Definition: option.c:2666
MagickExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
Definition: memory.c:529
MagickExport int LocaleNCompare(const char *p, const char *q, const size_t length)
Definition: locale.c:1509
MagickExport MagickBooleanType GlobExpression(const char *expression, const char *pattern, const MagickBooleanType case_insensitive)
Definition: token.c:349
#define MagickPathExtent
MagickExport MagickBooleanType IsStringTrue(const char *value)
Definition: string.c:1464
MagickExport MagickBooleanType static void * AcquireCriticalMemory(const size_t size)
PolicyRights rights
Definition: policy.c:82
MagickExport char ** GetPolicyList(const char *pattern, size_t *number_policies, ExceptionInfo *exception)
Definition: policy.c:433
MagickExport MagickBooleanType ThrowMagickException(ExceptionInfo *exception, const char *module, const char *function, const size_t line, const ExceptionType severity, const char *tag, const char *format,...)
Definition: exception.c:1058
MagickExport MagickBooleanType LogMagickEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
Definition: log.c:1397
MagickExport LinkedListInfo * NewLinkedList(const size_t capacity)
Definition: linked-list.c:713
MagickExport size_t CopyMagickString(char *destination, const char *source, const size_t length)
Definition: string.c:742
PolicyDomain
Definition: policy.h:28
MagickExport int LocaleCompare(const char *p, const char *q)
Definition: locale.c:1409
#define GetMagickModule()
Definition: log.h:28
MagickExport const char * GetStringInfoPath(const StringInfo *string_info)
Definition: string.c:1341
MagickBooleanType exempt
Definition: policy.c:90
MagickExport void GetNextToken(const char *start, const char **end, const size_t extent, char *token)
Definition: token.c:171
#define PolicyFilename
Definition: policy.c:68
MagickExport MagickBooleanType SetMagickSecurityPolicy(const char *policy, ExceptionInfo *exception)
Definition: policy.c:1065
MagickExport char * DestroyString(char *string)
Definition: string.c:810
MagickExport void * AcquireMagickMemory(const size_t size)
Definition: memory.c:458
MagickExport void ActivateSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition: semaphore.c:97
const char * pattern
Definition: policy.c:110
MagickExport size_t GetNumberOfElementsInLinkedList(const LinkedListInfo *list_info)
Definition: linked-list.c:348
static LinkedListInfo * AcquirePolicyCache(const char *filename, ExceptionInfo *exception)
Definition: policy.c:165
MagickExport char * GetPolicyValue(const char *name)
Definition: policy.c:500
const PolicyDomain domain
Definition: policy.c:104
PolicyDomain domain
Definition: policy.c:79
MagickExport void * RelinquishMagickMemory(void *memory)
Definition: memory.c:1038
const PolicyRights rights
Definition: policy.c:107
#define MagickPrivate
MagickPrivate char * FileToXML(const char *, const size_t)
Definition: xml-tree.c:600
#define MagickExport
MagickPrivate void PolicyComponentTerminus(void)
Definition: policy.c:1028
const char * value
Definition: policy.c:110
static void * DestroyPolicyElement(void *policy_info)
Definition: policy.c:1007
char * path
Definition: policy.c:76
MagickExport void RelinquishSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition: semaphore.c:351
MagickExport LinkedListInfo * DestroyConfigureOptions(LinkedListInfo *options)
Definition: configure.c:326
MagickExport char * ConstantString(const char *source)
Definition: string.c:687
MagickExport ExceptionInfo * DestroyExceptionInfo(ExceptionInfo *exception)
Definition: exception.c:417
static MagickBooleanType IsPolicyCacheInstantiated(ExceptionInfo *)
Definition: policy.c:547