MagickCore  7.0.8
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://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"
45 #include "MagickCore/client.h"
46 #include "MagickCore/configure.h"
48 #include "MagickCore/exception.h"
51 #include "MagickCore/memory_.h"
53 #include "MagickCore/monitor.h"
55 #include "MagickCore/option.h"
56 #include "MagickCore/policy.h"
58 #include "MagickCore/resource_.h"
60 #include "MagickCore/semaphore.h"
62 #include "MagickCore/string_.h"
64 #include "MagickCore/token.h"
65 #include "MagickCore/utility.h"
67 #include "MagickCore/xml-tree.h"
69 
70 /*
71  Define declarations.
72 */
73 #define PolicyFilename "policy.xml"
74 
75 /*
76  Typedef declarations.
77 */
79 {
80  char
81  *path;
82 
85 
88 
89  char
90  *name,
91  *pattern,
92  *value;
93 
96  stealth,
97  debug;
98 
101 
102  size_t
104 };
105 
106 typedef struct _PolicyMapInfo
107 {
108  const PolicyDomain
110 
111  const PolicyRights
113 
114  const char
116  *pattern,
117  *value;
118 } PolicyMapInfo;
119 
120 /*
121  Static declarations.
122 */
123 static const PolicyMapInfo
125  {
126  { UndefinedPolicyDomain, UndefinedPolicyRights, (const char *) NULL,
127  (const char *) NULL, (const char *) NULL }
128  };
129 
130 static LinkedListInfo
132 
133 static SemaphoreInfo
135 
136 /*
137  Forward declarations.
138 */
139 static MagickBooleanType
141  LoadPolicyCache(LinkedListInfo *,const char *,const char *,const size_t,
142  ExceptionInfo *);
143 
144 /*
145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
146 % %
147 % %
148 % %
149 % A c q u i r e P o l i c y C a c h e %
150 % %
151 % %
152 % %
153 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
154 %
155 % AcquirePolicyCache() caches one or more policy configurations which provides
156 % a mapping between policy attributes and a policy name.
157 %
158 % The format of the AcquirePolicyCache method is:
159 %
160 % LinkedListInfo *AcquirePolicyCache(const char *filename,
161 % ExceptionInfo *exception)
162 %
163 % A description of each parameter follows:
164 %
165 % o filename: the policy configuration file name.
166 %
167 % o exception: return any errors or warnings in this structure.
168 %
169 */
170 static LinkedListInfo *AcquirePolicyCache(const char *filename,
171  ExceptionInfo *exception)
172 {
174  *cache;
175 
177  status;
178 
179  register ssize_t
180  i;
181 
182  /*
183  Load external policy map.
184  */
185  cache=NewLinkedList(0);
186  status=MagickTrue;
187 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
188  status=LoadPolicyCache(cache,ZeroConfigurationPolicy,"[zero-configuration]",0,
189  exception);
190 #else
191  {
192  const StringInfo
193  *option;
194 
196  *options;
197 
198  options=GetConfigureOptions(filename,exception);
199  option=(const StringInfo *) GetNextValueInLinkedList(options);
200  while (option != (const StringInfo *) NULL)
201  {
202  status&=LoadPolicyCache(cache,(const char *) GetStringInfoDatum(option),
203  GetStringInfoPath(option),0,exception);
204  option=(const StringInfo *) GetNextValueInLinkedList(options);
205  }
206  options=DestroyConfigureOptions(options);
207  }
208 #endif
209  /*
210  Load built-in policy map.
211  */
212  for (i=0; i < (ssize_t) (sizeof(PolicyMap)/sizeof(*PolicyMap)); i++)
213  {
214  PolicyInfo
215  *policy_info;
216 
217  register const PolicyMapInfo
218  *p;
219 
220  p=PolicyMap+i;
221  policy_info=(PolicyInfo *) AcquireMagickMemory(sizeof(*policy_info));
222  if (policy_info == (PolicyInfo *) NULL)
223  {
224  (void) ThrowMagickException(exception,GetMagickModule(),
225  ResourceLimitError,"MemoryAllocationFailed","`%s'",p->name);
226  continue;
227  }
228  (void) memset(policy_info,0,sizeof(*policy_info));
229  policy_info->path=(char *) "[built-in]";
230  policy_info->domain=p->domain;
231  policy_info->rights=p->rights;
232  policy_info->name=(char *) p->name;
233  policy_info->pattern=(char *) p->pattern;
234  policy_info->value=(char *) p->value;
235  policy_info->exempt=MagickTrue;
236  policy_info->signature=MagickCoreSignature;
237  status&=AppendValueToLinkedList(cache,policy_info);
238  if (status == MagickFalse)
239  (void) ThrowMagickException(exception,GetMagickModule(),
240  ResourceLimitError,"MemoryAllocationFailed","`%s'",policy_info->name);
241  }
242  return(cache);
243 }
244 
245 /*
246 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
247 % %
248 % %
249 % %
250 + G e t P o l i c y I n f o %
251 % %
252 % %
253 % %
254 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
255 %
256 % GetPolicyInfo() searches the policy list for the specified name and if found
257 % returns attributes for that policy.
258 %
259 % The format of the GetPolicyInfo method is:
260 %
261 % PolicyInfo *GetPolicyInfo(const char *name,ExceptionInfo *exception)
262 %
263 % A description of each parameter follows:
264 %
265 % o name: the policy name.
266 %
267 % o exception: return any errors or warnings in this structure.
268 %
269 */
270 static PolicyInfo *GetPolicyInfo(const char *name,ExceptionInfo *exception)
271 {
272  char
273  policyname[MagickPathExtent];
274 
276  domain;
277 
278  register PolicyInfo
279  *p;
280 
281  register char
282  *q;
283 
284  assert(exception != (ExceptionInfo *) NULL);
285  if (IsPolicyCacheInstantiated(exception) == MagickFalse)
286  return((PolicyInfo *) NULL);
287  /*
288  Strip names of whitespace.
289  */
290  *policyname='\0';
291  if (name != (const char *) NULL)
292  (void) CopyMagickString(policyname,name,MagickPathExtent);
293  for (q=policyname; *q != '\0'; q++)
294  {
295  if (isspace((int) ((unsigned char) *q)) == 0)
296  continue;
297  (void) CopyMagickString(q,q+1,MagickPathExtent);
298  q--;
299  }
300  /*
301  Strip domain from policy name (e.g. resource:map).
302  */
303  domain=UndefinedPolicyDomain;
304  for (q=policyname; *q != '\0'; q++)
305  {
306  if (*q != ':')
307  continue;
308  *q='\0';
310  MagickTrue,policyname);
311  (void) CopyMagickString(policyname,q+1,MagickPathExtent);
312  break;
313  }
314  /*
315  Search for policy tag.
316  */
320  if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
321  {
323  return(p);
324  }
325  while (p != (PolicyInfo *) NULL)
326  {
327  if ((domain == UndefinedPolicyDomain) || (p->domain == domain))
328  if (LocaleCompare(policyname,p->name) == 0)
329  break;
331  }
332  if (p != (PolicyInfo *) NULL)
336  return(p);
337 }
338 
339 /*
340 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
341 % %
342 % %
343 % %
344 % G e t P o l i c y I n f o L i s t %
345 % %
346 % %
347 % %
348 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
349 %
350 % GetPolicyInfoList() returns any policies that match the specified pattern.
351 %
352 % The format of the GetPolicyInfoList function is:
353 %
354 % const PolicyInfo **GetPolicyInfoList(const char *pattern,
355 % size_t *number_policies,ExceptionInfo *exception)
356 %
357 % A description of each parameter follows:
358 %
359 % o pattern: Specifies a pointer to a text string containing a pattern.
360 %
361 % o number_policies: returns the number of policies in the list.
362 %
363 % o exception: return any errors or warnings in this structure.
364 %
365 */
366 MagickExport const PolicyInfo **GetPolicyInfoList(const char *pattern,
367  size_t *number_policies,ExceptionInfo *exception)
368 {
369  const PolicyInfo
370  **policies;
371 
372  register const PolicyInfo
373  *p;
374 
375  register ssize_t
376  i;
377 
378  /*
379  Allocate policy list.
380  */
381  assert(pattern != (char *) NULL);
382  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
383  assert(number_policies != (size_t *) NULL);
384  *number_policies=0;
385  p=GetPolicyInfo("*",exception);
386  if (p == (const PolicyInfo *) NULL)
387  return((const PolicyInfo **) NULL);
388  policies=(const PolicyInfo **) AcquireQuantumMemory((size_t)
389  GetNumberOfElementsInLinkedList(policy_cache)+1UL,sizeof(*policies));
390  if (policies == (const PolicyInfo **) NULL)
391  return((const PolicyInfo **) NULL);
392  /*
393  Generate policy list.
394  */
398  for (i=0; p != (const PolicyInfo *) NULL; )
399  {
400  if ((p->stealth == MagickFalse) &&
401  (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
402  policies[i++]=p;
404  }
406  policies[i]=(PolicyInfo *) NULL;
407  *number_policies=(size_t) i;
408  return(policies);
409 }
410 
411 /*
412 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
413 % %
414 % %
415 % %
416 % G e t P o l i c y L i s t %
417 % %
418 % %
419 % %
420 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
421 %
422 % GetPolicyList() returns any policies that match the specified pattern.
423 %
424 % The format of the GetPolicyList function is:
425 %
426 % char **GetPolicyList(const char *pattern,size_t *number_policies,
427 % ExceptionInfo *exception)
428 %
429 % A description of each parameter follows:
430 %
431 % o pattern: a pointer to a text string containing a pattern.
432 %
433 % o number_policies: returns the number of policies in the list.
434 %
435 % o exception: return any errors or warnings in this structure.
436 %
437 */
438 MagickExport char **GetPolicyList(const char *pattern,
439  size_t *number_policies,ExceptionInfo *exception)
440 {
441  char
442  **policies;
443 
444  register const PolicyInfo
445  *p;
446 
447  register ssize_t
448  i;
449 
450  /*
451  Allocate policy list.
452  */
453  assert(pattern != (char *) NULL);
454  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
455  assert(number_policies != (size_t *) NULL);
456  *number_policies=0;
457  p=GetPolicyInfo("*",exception);
458  if (p == (const PolicyInfo *) NULL)
459  return((char **) NULL);
460  policies=(char **) AcquireQuantumMemory((size_t)
461  GetNumberOfElementsInLinkedList(policy_cache)+1UL,sizeof(*policies));
462  if (policies == (char **) NULL)
463  return((char **) NULL);
464  /*
465  Generate policy list.
466  */
470  for (i=0; p != (const PolicyInfo *) NULL; )
471  {
472  if ((p->stealth == MagickFalse) &&
473  (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
474  policies[i++]=ConstantString(p->name);
476  }
478  policies[i]=(char *) NULL;
479  *number_policies=(size_t) i;
480  return(policies);
481 }
482 
483 /*
484 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
485 % %
486 % %
487 % %
488 % G e t P o l i c y V a l u e %
489 % %
490 % %
491 % %
492 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
493 %
494 % GetPolicyValue() returns the value associated with the named policy.
495 %
496 % The format of the GetPolicyValue method is:
497 %
498 % char *GetPolicyValue(const char *name)
499 %
500 % A description of each parameter follows:
501 %
502 % o name: The name of the policy.
503 %
504 */
505 MagickExport char *GetPolicyValue(const char *name)
506 {
507  const char
508  *value;
509 
510  const PolicyInfo
511  *policy_info;
512 
514  *exception;
515 
516  assert(name != (const char *) NULL);
517  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
518  exception=AcquireExceptionInfo();
519  policy_info=GetPolicyInfo(name,exception);
520  exception=DestroyExceptionInfo(exception);
521  if (policy_info == (PolicyInfo *) NULL)
522  return((char *) NULL);
523  value=policy_info->value;
524  if ((value == (const char *) NULL) || (*value == '\0'))
525  return((char *) NULL);
526  return(ConstantString(value));
527 }
528 
529 /*
530 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
531 % %
532 % %
533 % %
534 + 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 %
535 % %
536 % %
537 % %
538 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
539 %
540 % IsPolicyCacheInstantiated() determines if the policy list is instantiated.
541 % If not, it instantiates the list and returns it.
542 %
543 % The format of the IsPolicyInstantiated method is:
544 %
545 % MagickBooleanType IsPolicyCacheInstantiated(ExceptionInfo *exception)
546 %
547 % A description of each parameter follows.
548 %
549 % o exception: return any errors or warnings in this structure.
550 %
551 */
553 {
554  if (policy_cache == (LinkedListInfo *) NULL)
555  {
556  if (policy_semaphore == (SemaphoreInfo *) NULL)
559  if (policy_cache == (LinkedListInfo *) NULL)
562  }
563  return(policy_cache != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
564 }
565 
566 /*
567 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
568 % %
569 % %
570 % %
571 % I s R i g h t s A u t h o r i z e d %
572 % %
573 % %
574 % %
575 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
576 %
577 % IsRightsAuthorized() returns MagickTrue if the policy authorizes the
578 % requested rights for the specified domain.
579 %
580 % The format of the IsRightsAuthorized method is:
581 %
582 % MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
583 % const PolicyRights rights,const char *pattern)
584 %
585 % A description of each parameter follows:
586 %
587 % o domain: the policy domain.
588 %
589 % o rights: the policy rights.
590 %
591 % o pattern: the coder, delegate, filter, or path pattern.
592 %
593 */
595  const PolicyRights rights,const char *pattern)
596 {
597  const PolicyInfo
598  *policy_info;
599 
601  *exception;
602 
604  authorized;
605 
606  register PolicyInfo
607  *p;
608 
610  "Domain: %s; rights=%s; pattern=\"%s\" ...",
613  exception=AcquireExceptionInfo();
614  policy_info=GetPolicyInfo("*",exception);
615  exception=DestroyExceptionInfo(exception);
616  if (policy_info == (PolicyInfo *) NULL)
617  return(MagickTrue);
618  authorized=MagickTrue;
622  while (p != (PolicyInfo *) NULL)
623  {
624  if ((p->domain == domain) &&
626  {
627  if ((rights & ReadPolicyRights) != 0)
628  authorized=(p->rights & ReadPolicyRights) != 0 ? MagickTrue :
629  MagickFalse;
630  if ((rights & WritePolicyRights) != 0)
631  authorized=(p->rights & WritePolicyRights) != 0 ? MagickTrue :
632  MagickFalse;
633  if ((rights & ExecutePolicyRights) != 0)
634  authorized=(p->rights & ExecutePolicyRights) != 0 ? MagickTrue :
635  MagickFalse;
636  }
638  }
640  return(authorized);
641 }
642 
643 /*
644 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
645 % %
646 % %
647 % %
648 % L i s t P o l i c y I n f o %
649 % %
650 % %
651 % %
652 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
653 %
654 % ListPolicyInfo() lists policies to the specified file.
655 %
656 % The format of the ListPolicyInfo method is:
657 %
658 % MagickBooleanType ListPolicyInfo(FILE *file,ExceptionInfo *exception)
659 %
660 % A description of each parameter follows.
661 %
662 % o file: List policy names to this file handle.
663 %
664 % o exception: return any errors or warnings in this structure.
665 %
666 */
668  ExceptionInfo *exception)
669 {
670  const char
671  *path,
672  *domain;
673 
674  const PolicyInfo
675  **policy_info;
676 
677  register ssize_t
678  i;
679 
680  size_t
681  number_policies;
682 
683  /*
684  List name and attributes of each policy in the list.
685  */
686  if (file == (const FILE *) NULL)
687  file=stdout;
688  policy_info=GetPolicyInfoList("*",&number_policies,exception);
689  if (policy_info == (const PolicyInfo **) NULL)
690  return(MagickFalse);
691  path=(const char *) NULL;
692  for (i=0; i < (ssize_t) number_policies; i++)
693  {
694  if (policy_info[i]->stealth != MagickFalse)
695  continue;
696  if (((path == (const char *) NULL) ||
697  (LocaleCompare(path,policy_info[i]->path) != 0)) &&
698  (policy_info[i]->path != (char *) NULL))
699  (void) FormatLocaleFile(file,"\nPath: %s\n",policy_info[i]->path);
700  path=policy_info[i]->path;
702  policy_info[i]->domain);
703  (void) FormatLocaleFile(file," Policy: %s\n",domain);
704  if ((policy_info[i]->domain == CachePolicyDomain) ||
705  (policy_info[i]->domain == ResourcePolicyDomain) ||
706  (policy_info[i]->domain == SystemPolicyDomain))
707  {
708  if (policy_info[i]->name != (char *) NULL)
709  (void) FormatLocaleFile(file," name: %s\n",policy_info[i]->name);
710  if (policy_info[i]->value != (char *) NULL)
711  (void) FormatLocaleFile(file," value: %s\n",policy_info[i]->value);
712  }
713  else
714  {
715  (void) FormatLocaleFile(file," rights: ");
716  if (policy_info[i]->rights == NoPolicyRights)
717  (void) FormatLocaleFile(file,"None ");
718  if ((policy_info[i]->rights & ReadPolicyRights) != 0)
719  (void) FormatLocaleFile(file,"Read ");
720  if ((policy_info[i]->rights & WritePolicyRights) != 0)
721  (void) FormatLocaleFile(file,"Write ");
722  if ((policy_info[i]->rights & ExecutePolicyRights) != 0)
723  (void) FormatLocaleFile(file,"Execute ");
724  (void) FormatLocaleFile(file,"\n");
725  if (policy_info[i]->pattern != (char *) NULL)
726  (void) FormatLocaleFile(file," pattern: %s\n",
727  policy_info[i]->pattern);
728  }
729  }
730  policy_info=(const PolicyInfo **) RelinquishMagickMemory((void *)
731  policy_info);
732  (void) fflush(file);
733  return(MagickTrue);
734 }
735 
736 /*
737 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
738 % %
739 % %
740 % %
741 + L o a d P o l i c y C a c h e %
742 % %
743 % %
744 % %
745 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
746 %
747 % LoadPolicyCache() loads the policy configurations which provides a mapping
748 % between policy attributes and a policy domain.
749 %
750 % The format of the LoadPolicyCache method is:
751 %
752 % MagickBooleanType LoadPolicyCache(LinkedListInfo *cache,const char *xml,
753 % const char *filename,const size_t depth,ExceptionInfo *exception)
754 %
755 % A description of each parameter follows:
756 %
757 % o xml: The policy list in XML format.
758 %
759 % o filename: The policy list filename.
760 %
761 % o depth: depth of <include /> statements.
762 %
763 % o exception: return any errors or warnings in this structure.
764 %
765 */
766 static MagickBooleanType LoadPolicyCache(LinkedListInfo *cache,const char *xml,
767  const char *filename,const size_t depth,ExceptionInfo *exception)
768 {
769  char
770  keyword[MagickPathExtent],
771  *token;
772 
773  const char
774  *q;
775 
777  status;
778 
779  PolicyInfo
780  *policy_info;
781 
782  size_t
783  extent;
784 
785  /*
786  Load the policy map file.
787  */
789  "Loading policy file \"%s\" ...",filename);
790  if (xml == (char *) NULL)
791  return(MagickFalse);
792  status=MagickTrue;
793  policy_info=(PolicyInfo *) NULL;
794  token=AcquireString(xml);
795  extent=strlen(token)+MagickPathExtent;
796  for (q=(const char *) xml; *q != '\0'; )
797  {
798  /*
799  Interpret XML.
800  */
801  GetNextToken(q,&q,extent,token);
802  if (*token == '\0')
803  break;
804  (void) CopyMagickString(keyword,token,MagickPathExtent);
805  if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
806  {
807  /*
808  Docdomain element.
809  */
810  while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
811  GetNextToken(q,&q,extent,token);
812  continue;
813  }
814  if (LocaleNCompare(keyword,"<!--",4) == 0)
815  {
816  /*
817  Comment element.
818  */
819  while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
820  GetNextToken(q,&q,extent,token);
821  continue;
822  }
823  if (LocaleCompare(keyword,"<include") == 0)
824  {
825  /*
826  Include element.
827  */
828  while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
829  {
830  (void) CopyMagickString(keyword,token,MagickPathExtent);
831  GetNextToken(q,&q,extent,token);
832  if (*token != '=')
833  continue;
834  GetNextToken(q,&q,extent,token);
835  if (LocaleCompare(keyword,"file") == 0)
836  {
837  if (depth > MagickMaxRecursionDepth)
838  (void) ThrowMagickException(exception,GetMagickModule(),
839  ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
840  else
841  {
842  char
843  path[MagickPathExtent],
844  *file_xml;
845 
846  GetPathComponent(filename,HeadPath,path);
847  if (*path != '\0')
850  if (*token == *DirectorySeparator)
851  (void) CopyMagickString(path,token,MagickPathExtent);
852  else
853  (void) ConcatenateMagickString(path,token,MagickPathExtent);
854  file_xml=FileToXML(path,~0UL);
855  if (file_xml != (char *) NULL)
856  {
857  status&=LoadPolicyCache(cache,file_xml,path,
858  depth+1,exception);
859  file_xml=DestroyString(file_xml);
860  }
861  }
862  }
863  }
864  continue;
865  }
866  if (LocaleCompare(keyword,"<policy") == 0)
867  {
868  /*
869  Policy element.
870  */
871  policy_info=(PolicyInfo *) AcquireCriticalMemory(sizeof(*policy_info));
872  (void) memset(policy_info,0,sizeof(*policy_info));
873  policy_info->path=ConstantString(filename);
874  policy_info->exempt=MagickFalse;
875  policy_info->signature=MagickCoreSignature;
876  continue;
877  }
878  if (policy_info == (PolicyInfo *) NULL)
879  continue;
880  if ((LocaleCompare(keyword,"/>") == 0) ||
881  (LocaleCompare(keyword,"</policy>") == 0))
882  {
883  status=AppendValueToLinkedList(cache,policy_info);
884  if (status == MagickFalse)
885  (void) ThrowMagickException(exception,GetMagickModule(),
886  ResourceLimitError,"MemoryAllocationFailed","`%s'",
887  policy_info->name);
888  policy_info=(PolicyInfo *) NULL;
889  continue;
890  }
891  GetNextToken(q,(const char **) NULL,extent,token);
892  if (*token != '=')
893  continue;
894  GetNextToken(q,&q,extent,token);
895  GetNextToken(q,&q,extent,token);
896  switch (*keyword)
897  {
898  case 'D':
899  case 'd':
900  {
901  if (LocaleCompare((char *) keyword,"domain") == 0)
902  {
903  policy_info->domain=(PolicyDomain) ParseCommandOption(
905  break;
906  }
907  break;
908  }
909  case 'N':
910  case 'n':
911  {
912  if (LocaleCompare((char *) keyword,"name") == 0)
913  {
914  policy_info->name=ConstantString(token);
915  break;
916  }
917  break;
918  }
919  case 'P':
920  case 'p':
921  {
922  if (LocaleCompare((char *) keyword,"pattern") == 0)
923  {
924  policy_info->pattern=ConstantString(token);
925  break;
926  }
927  break;
928  }
929  case 'R':
930  case 'r':
931  {
932  if (LocaleCompare((char *) keyword,"rights") == 0)
933  {
934  policy_info->rights=(PolicyRights) ParseCommandOption(
936  break;
937  }
938  break;
939  }
940  case 'S':
941  case 's':
942  {
943  if (LocaleCompare((char *) keyword,"stealth") == 0)
944  {
945  policy_info->stealth=IsStringTrue(token);
946  break;
947  }
948  break;
949  }
950  case 'V':
951  case 'v':
952  {
953  if (LocaleCompare((char *) keyword,"value") == 0)
954  {
955  policy_info->value=ConstantString(token);
956  break;
957  }
958  break;
959  }
960  default:
961  break;
962  }
963  }
964  token=(char *) RelinquishMagickMemory(token);
965  return(status != 0 ? MagickTrue : MagickFalse);
966 }
967 
968 /*
969 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
970 % %
971 % %
972 % %
973 + P o l i c y C o m p o n e n t G e n e s i s %
974 % %
975 % %
976 % %
977 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
978 %
979 % PolicyComponentGenesis() instantiates the policy component.
980 %
981 % The format of the PolicyComponentGenesis method is:
982 %
983 % MagickBooleanType PolicyComponentGenesis(void)
984 %
985 */
987 {
988  if (policy_semaphore == (SemaphoreInfo *) NULL)
990  return(MagickTrue);
991 }
992 
993 /*
994 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
995 % %
996 % %
997 % %
998 + P o l i c y C o m p o n e n t T e r m i n u s %
999 % %
1000 % %
1001 % %
1002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1003 %
1004 % PolicyComponentTerminus() destroys the policy component.
1005 %
1006 % The format of the PolicyComponentTerminus method is:
1007 %
1008 % PolicyComponentTerminus(void)
1009 %
1010 */
1011 
1012 static void *DestroyPolicyElement(void *policy_info)
1013 {
1014  register PolicyInfo
1015  *p;
1016 
1017  p=(PolicyInfo *) policy_info;
1018  if (p->exempt == MagickFalse)
1019  {
1020  if (p->value != (char *) NULL)
1021  p->value=DestroyString(p->value);
1022  if (p->pattern != (char *) NULL)
1023  p->pattern=DestroyString(p->pattern);
1024  if (p->name != (char *) NULL)
1025  p->name=DestroyString(p->name);
1026  if (p->path != (char *) NULL)
1027  p->path=DestroyString(p->path);
1028  }
1030  return((void *) NULL);
1031 }
1032 
1034 {
1035  if (policy_semaphore == (SemaphoreInfo *) NULL)
1038  if (policy_cache != (LinkedListInfo *) NULL)
1042 }
1043 
1044 /*
1045 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1046 % %
1047 % %
1048 % %
1049 % S e t M a g i c k S e c u r i t y P o l i c y %
1050 % %
1051 % %
1052 % %
1053 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1054 %
1055 % SetMagickSecurityPolicy() sets the ImageMagick security policy. It returns
1056 % MagickFalse if the policy is already set or if the policy does not parse.
1057 %
1058 % The format of the SetMagickSecurityPolicy method is:
1059 %
1060 % MagickBooleanType SetMagickSecurityPolicy(const char *policy,
1061 % ExceptionInfo *exception)
1062 %
1063 % A description of each parameter follows:
1064 %
1065 % o policy: the security policy in the XML format.
1066 %
1067 % o exception: return any errors or warnings in this structure.
1068 %
1069 */
1071  ExceptionInfo *exception)
1072 {
1073  PolicyInfo
1074  *p;
1075 
1077  status;
1078 
1079  assert(exception != (ExceptionInfo *) NULL);
1080  if (policy == (const char *) NULL)
1081  return(MagickFalse);
1082  if (IsPolicyCacheInstantiated(exception) == MagickFalse)
1083  return(MagickFalse);
1087  if ((p != (PolicyInfo *) NULL) && (p->domain != UndefinedPolicyDomain))
1088  {
1090  return(MagickFalse);
1091  }
1093  status=LoadPolicyCache(policy_cache,policy,"[user-policy]",0,exception);
1094  if (status == MagickFalse)
1095  return(MagickFalse);
1096  return(ResourceComponentGenesis());
1097 }
1098 
1099 /*
1100 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1101 % %
1102 % %
1103 % %
1104 % S e t M a g i c k S e c u r i t y P o l i c y V a l u e %
1105 % %
1106 % %
1107 % %
1108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1109 %
1110 % SetMagickSecurityPolicyValue() sets a value associated with an ImageMagick
1111 % security policy. For most policies, the value must be less than any value
1112 % set by the security policy configuration file (i.e. policy.xml). It returns
1113 % MagickFalse if the policy cannot be modified or if the policy does not parse.
1114 %
1115 % The format of the SetMagickSecurityPolicyValue method is:
1116 %
1117 % MagickBooleanType SetMagickSecurityPolicyValue(
1118 % const PolicyDomain domain,const char *name,const char *value,
1119 % ExceptionInfo *exception)
1120 %
1121 % A description of each parameter follows:
1122 %
1123 % o domain: the domain of the policy (e.g. system, resource).
1124 %
1125 % o name: the name of the policy.
1126 %
1127 % o value: the value to set the policy to.
1128 %
1129 % o exception: return any errors or warnings in this structure.
1130 %
1131 */
1132 
1134  const char *name,const char *value)
1135 {
1137  status;
1138 
1139  register PolicyInfo
1140  *p;
1141 
1142  status=MagickTrue;
1146  while (p != (PolicyInfo *) NULL)
1147  {
1148  if ((p->domain == domain) && (LocaleCompare(name,p->name) == 0))
1149  break;
1151  }
1152  if (p != (PolicyInfo *) NULL)
1153  {
1154  if (p->value != (char *) NULL)
1155  p->value=DestroyString(p->value);
1156  }
1157  else
1158  {
1159  p=(PolicyInfo *) AcquireCriticalMemory(sizeof(*p));
1160  (void) memset(p,0,sizeof(*p));
1161  p->exempt=MagickFalse;
1163  p->domain=domain;
1164  p->name=ConstantString(name);
1166  }
1167  p->value=ConstantString(value);
1169  if (status == MagickFalse)
1171  return(status);
1172 }
1173 
1175  const PolicyDomain domain,const char *name,const char *value,
1176  ExceptionInfo *exception)
1177 {
1178  char
1179  *current_value;
1180 
1181  magick_unreferenced(exception);
1182  assert(exception != (ExceptionInfo *) NULL);
1183  if ((name == (const char *) NULL) || (value == (const char *) NULL))
1184  return(MagickFalse);
1185  switch(domain)
1186  {
1187  case CachePolicyDomain:
1188  {
1189  if (LocaleCompare(name,"memory-map") == 0)
1190  {
1191  if (LocaleCompare(value,"anonymous") != 0)
1192  return(MagickFalse);
1195  return(SetPolicyValue(domain,name,value));
1196  }
1197  if (LocaleCompare(name,"synchronize") == 0)
1198  return(SetPolicyValue(domain,name,value));
1199  break;
1200  }
1201  case ResourcePolicyDomain:
1202  {
1203  ssize_t
1204  type;
1205 
1206  if (LocaleCompare(name,"temporary-path") == 0)
1207  return(SetPolicyValue(domain,name,value));
1209  if (type >= 0)
1210  {
1212  limit;
1213 
1214  limit=MagickResourceInfinity;
1215  if (LocaleCompare("unlimited",value) != 0)
1216  limit=StringToMagickSizeType(value,100.0);
1217  return(SetMagickResourceLimit((ResourceType) type,limit));
1218  }
1219  break;
1220  }
1221  case SystemPolicyDomain:
1222  {
1223  if (LocaleCompare(name,"max-memory-request") == 0)
1224  {
1225  current_value=GetPolicyValue("system:max-memory-request");
1226  if ((current_value == (char *) NULL) ||
1227  (StringToSizeType(value,100.0) < StringToSizeType(current_value,100.0)))
1228  {
1230  return(SetPolicyValue(domain,name,value));
1231  }
1232  }
1233  if (LocaleCompare(name,"memory-map") == 0)
1234  {
1235  if (LocaleCompare(value,"anonymous") != 0)
1236  return(MagickFalse);
1238  return(SetPolicyValue(domain,name,value));
1239  }
1240  if (LocaleCompare(name,"precision") == 0)
1241  {
1243  return(SetPolicyValue(domain,name,value));
1244  }
1245  if (LocaleCompare(name,"shred") == 0)
1246  {
1247  current_value=GetPolicyValue("system:shred");
1248  if ((current_value == (char *) NULL) ||
1249  (StringToInteger(value) > StringToInteger(current_value)))
1250  return(SetPolicyValue(domain,name,value));
1251  }
1252  break;
1253  }
1254  case CoderPolicyDomain:
1255  case DelegatePolicyDomain:
1256  case FilterPolicyDomain:
1257  case ModulePolicyDomain:
1258  case PathPolicyDomain:
1259  default:
1260  break;
1261  }
1262  return(MagickFalse);
1263 }
MagickBooleanType stealth
Definition: policy.c:95
char * value
Definition: policy.c:90
MagickPrivate MagickBooleanType ResourceComponentGenesis(void)
Definition: resource.c:1088
#define MagickMaxRecursionDepth
Definition: studio.h:344
static size_t StringToSizeType(const char *string, const double interval)
MagickExport const PolicyInfo ** GetPolicyInfoList(const char *pattern, size_t *number_policies, ExceptionInfo *exception)
Definition: policy.c:366
MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain, const PolicyRights rights, const char *pattern)
Definition: policy.c:594
MagickExport MagickBooleanType ListPolicyInfo(FILE *file, ExceptionInfo *exception)
Definition: policy.c:667
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:2963
static SemaphoreInfo * policy_semaphore
Definition: policy.c:134
SemaphoreInfo * semaphore
Definition: policy.c:100
PolicyRights
Definition: policy.h:41
static int StringToInteger(const char *magick_restrict value)
MagickExport LinkedListInfo * DestroyLinkedList(LinkedListInfo *list_info, void *(*relinquish_value)(void *))
Definition: linked-list.c:219
struct _PolicyMapInfo PolicyMapInfo
char * name
Definition: policy.c:90
MagickBooleanType debug
Definition: policy.c:95
MagickExport size_t ConcatenateMagickString(char *destination, const char *source, const size_t length)
Definition: string.c:426
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:115
char * pattern
Definition: policy.c:90
MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type, const MagickSizeType limit)
Definition: resource.c:1285
static PolicyInfo * GetPolicyInfo(const char *name, ExceptionInfo *exception)
Definition: policy.c:270
MagickExport ExceptionInfo * AcquireExceptionInfo(void)
Definition: exception.c:108
MagickExport MagickBooleanType AppendValueToLinkedList(LinkedListInfo *list_info, const void *value)
Definition: linked-list.c:111
static void * AcquireCriticalMemory(const size_t size)
MagickExport void * RemoveElementByValueFromLinkedList(LinkedListInfo *list_info, const void *value)
Definition: linked-list.c:756
static LinkedListInfo * policy_cache
Definition: policy.c:131
MagickPrivate MagickBooleanType PolicyComponentGenesis(void)
Definition: policy.c:986
MagickExport MagickBooleanType SetMagickSecurityPolicyValue(const PolicyDomain domain, const char *name, const char *value, ExceptionInfo *exception)
Definition: policy.c:1174
Definition: log.h:52
static const PolicyMapInfo PolicyMap[]
Definition: policy.c:124
MagickExport void * GetNextValueInLinkedList(LinkedListInfo *list_info)
Definition: linked-list.c:305
size_t signature
Definition: policy.c:103
#define MagickCoreSignature
MagickExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:293
MagickExport unsigned char * GetStringInfoDatum(const StringInfo *string_info)
Definition: string.c:1295
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:766
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:409
MagickBooleanType
Definition: magick-type.h:156
#define DirectorySeparator
Definition: studio.h:259
unsigned int MagickStatusType
Definition: magick-type.h:119
MagickExport char * AcquireString(const char *source)
Definition: string.c:129
MagickPrivate void ResetMagickPrecision(void)
Definition: magick.c:1659
MagickExport const char * CommandOptionToMnemonic(const CommandOption option, const ssize_t type)
Definition: option.c:2676
MagickExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
Definition: memory.c:533
MagickExport int LocaleNCompare(const char *p, const char *q, const size_t length)
Definition: locale.c:1540
MagickExport MagickBooleanType GlobExpression(const char *expression, const char *pattern, const MagickBooleanType case_insensitive)
Definition: token.c:353
size_t MagickSizeType
Definition: magick-type.h:128
#define MagickPathExtent
MagickExport MagickBooleanType IsStringTrue(const char *value)
Definition: string.c:1505
static MagickBooleanType SetPolicyValue(const PolicyDomain domain, const char *name, const char *value)
Definition: policy.c:1133
PolicyRights rights
Definition: policy.c:87
MagickExport char ** GetPolicyList(const char *pattern, size_t *number_policies, ExceptionInfo *exception)
Definition: policy.c:438
MagickPrivate void ResetCacheAnonymousMemory(void)
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:1064
MagickExport MagickBooleanType LogMagickEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
Definition: log.c:1398
MagickExport LinkedListInfo * NewLinkedList(const size_t capacity)
Definition: linked-list.c:713
MagickPrivate void ResetStreamAnonymousMemory(void)
MagickExport size_t CopyMagickString(char *destination, const char *source, const size_t length)
Definition: string.c:755
PolicyDomain
Definition: policy.h:28
ResourceType
Definition: resource_.h:25
MagickExport int LocaleCompare(const char *p, const char *q)
Definition: locale.c:1440
#define GetMagickModule()
Definition: log.h:28
MagickExport const char * GetStringInfoPath(const StringInfo *string_info)
Definition: string.c:1382
MagickBooleanType exempt
Definition: policy.c:95
MagickExport void GetNextToken(const char *start, const char **end, const size_t extent, char *token)
Definition: token.c:172
#define PolicyFilename
Definition: policy.c:73
#define MagickResourceInfinity
Definition: resource_.h:41
MagickExport MagickBooleanType SetMagickSecurityPolicy(const char *policy, ExceptionInfo *exception)
Definition: policy.c:1070
MagickExport char * DestroyString(char *string)
Definition: string.c:823
MagickExport void * AcquireMagickMemory(const size_t size)
Definition: memory.c:462
MagickExport void ActivateSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition: semaphore.c:97
const char * pattern
Definition: policy.c:115
MagickExport size_t GetNumberOfElementsInLinkedList(const LinkedListInfo *list_info)
Definition: linked-list.c:348
static MagickSizeType StringToMagickSizeType(const char *string, const double interval)
static LinkedListInfo * AcquirePolicyCache(const char *filename, ExceptionInfo *exception)
Definition: policy.c:170
MagickExport char * GetPolicyValue(const char *name)
Definition: policy.c:505
const PolicyDomain domain
Definition: policy.c:109
PolicyDomain domain
Definition: policy.c:84
MagickExport void * RelinquishMagickMemory(void *memory)
Definition: memory.c:1054
#define magick_unreferenced(x)
const PolicyRights rights
Definition: policy.c:112
#define MagickPrivate
MagickPrivate char * FileToXML(const char *, const size_t)
Definition: xml-tree.c:599
#define MagickExport
MagickPrivate void PolicyComponentTerminus(void)
Definition: policy.c:1033
const char * value
Definition: policy.c:115
static void * DestroyPolicyElement(void *policy_info)
Definition: policy.c:1012
MagickPrivate void ResetMaxMemoryRequest(void)
char * path
Definition: policy.c:81
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:700
MagickPrivate void ResetVirtualAnonymousMemory(void)
Definition: memory.c:1227
MagickExport ExceptionInfo * DestroyExceptionInfo(ExceptionInfo *exception)
Definition: exception.c:411
static MagickBooleanType IsPolicyCacheInstantiated(ExceptionInfo *)
Definition: policy.c:552