40#include "MagickCore/studio.h"
41#include "MagickCore/cache-private.h"
42#include "MagickCore/client.h"
43#include "MagickCore/configure.h"
44#include "MagickCore/configure-private.h"
45#include "MagickCore/exception.h"
46#include "MagickCore/exception-private.h"
47#include "MagickCore/linked-list-private.h"
48#include "MagickCore/magick-private.h"
49#include "MagickCore/memory_.h"
50#include "MagickCore/memory-private.h"
51#include "MagickCore/monitor.h"
52#include "MagickCore/monitor-private.h"
53#include "MagickCore/option.h"
54#include "MagickCore/policy.h"
55#include "MagickCore/policy-private.h"
56#include "MagickCore/resource_.h"
57#include "MagickCore/resource-private.h"
58#include "MagickCore/semaphore.h"
59#include "MagickCore/stream-private.h"
60#include "MagickCore/string_.h"
61#include "MagickCore/string-private.h"
62#include "MagickCore/token.h"
63#include "MagickCore/timer-private.h"
64#include "MagickCore/utility.h"
65#include "MagickCore/utility-private.h"
66#include "MagickCore/xml-tree.h"
67#include "MagickCore/xml-tree-private.h"
68#if defined(MAGICKCORE_XML_DELEGATE)
69# include <libxml/parser.h>
70# include <libxml/tree.h>
76#define PolicyFilename "policy.xml"
126static const PolicyMapInfo
129 { UndefinedPolicyDomain, UndefinedPolicyRights, (
const char *) NULL,
130 (
const char *) NULL, (
const char *) NULL }
134 *policy_cache = (LinkedListInfo *) NULL;
142static MagickBooleanType
143 IsPolicyCacheInstantiated(ExceptionInfo *),
144 LoadPolicyCache(LinkedListInfo *,
const char *,
const char *,
const size_t,
148 *DestroyPolicyElement(
void *);
177static LinkedListInfo *AcquirePolicyCache(
const char *filename,
178 ExceptionInfo *exception)
192 cache=NewLinkedList(0);
194#if MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
195 magick_unreferenced(filename);
196 status=LoadPolicyCache(cache,ZeroConfigurationPolicy,
"[zero-configuration]",0,
206 options=GetConfigureOptions(filename,exception);
207 option=(
const StringInfo *) GetNextValueInLinkedList(options);
208 while (option != (
const StringInfo *) NULL)
210 status=LoadPolicyCache(cache,(
const char *) GetStringInfoDatum(option),
211 GetStringInfoPath(option),0,exception);
212 if (status == MagickFalse)
214 option=(
const StringInfo *) GetNextValueInLinkedList(options);
216 options=DestroyConfigureOptions(options);
219 if (status == MagickFalse)
221 cache=DestroyLinkedList(cache,DestroyPolicyElement);
222 CatchException(exception);
223 return((LinkedListInfo *) NULL);
228 for (i=0; i < (ssize_t) (
sizeof(PolicyMap)/
sizeof(*PolicyMap)); i++)
237 policy_info=(PolicyInfo *) AcquireMagickMemory(
sizeof(*policy_info));
238 if (policy_info == (PolicyInfo *) NULL)
240 (void) ThrowMagickException(exception,GetMagickModule(),
241 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
242 p->name == (
char *) NULL ?
"" : p->name);
243 CatchException(exception);
246 (void) memset(policy_info,0,
sizeof(*policy_info));
247 policy_info->path=(
char *)
"[built-in]";
248 policy_info->domain=p->domain;
249 policy_info->rights=p->rights;
250 policy_info->name=(
char *) p->name;
251 policy_info->pattern=(
char *) p->pattern;
252 policy_info->value=(
char *) p->value;
253 policy_info->exempt=MagickTrue;
254 policy_info->signature=MagickCoreSignature;
255 status=AppendValueToLinkedList(cache,policy_info);
256 if (status == MagickFalse)
258 (void) ThrowMagickException(exception,GetMagickModule(),
259 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
260 p->name == (
char *) NULL ?
"" : p->name);
261 CatchException(exception);
292static PolicyInfo *GetPolicyInfo(
const char *name,ExceptionInfo *exception)
295 policyname[MagickPathExtent],
307 assert(exception != (ExceptionInfo *) NULL);
308 if (IsPolicyCacheInstantiated(exception) == MagickFalse)
309 return((PolicyInfo *) NULL);
314 if (name != (
const char *) NULL)
315 (void) CopyMagickString(policyname,name,MagickPathExtent);
316 for (q=policyname; *q !=
'\0'; q++)
318 if (isspace((
int) ((
unsigned char) *q)) == 0)
320 (void) CopyMagickString(q,q+1,MagickPathExtent);
326 domain=UndefinedPolicyDomain;
327 for (q=policyname; *q !=
'\0'; q++)
332 domain=(PolicyDomain) ParseCommandOption(MagickPolicyDomainOptions,
333 MagickTrue,policyname);
334 (void) CopyMagickString(policyname,q+1,MagickPathExtent);
340 policy=(PolicyInfo *) NULL;
341 LockSemaphoreInfo(policy_semaphore);
342 ResetLinkedListIterator(policy_cache);
343 p=GetHeadElementInLinkedList(policy_cache);
344 if ((name == (
const char *) NULL) || (LocaleCompare(name,
"*") == 0))
346 UnlockSemaphoreInfo(policy_semaphore);
347 if (p != (ElementInfo *) NULL)
348 policy=(PolicyInfo *) p->value;
351 while (p != (ElementInfo *) NULL)
353 policy=(PolicyInfo *) p->value;
354 if ((domain == UndefinedPolicyDomain) || (policy->domain == domain))
355 if (LocaleCompare(policyname,policy->name) == 0)
359 if (p == (ElementInfo *) NULL)
360 policy=(PolicyInfo *) NULL;
362 (
void) SetHeadElementInLinkedList(policy_cache,p);
363 UnlockSemaphoreInfo(policy_semaphore);
394MagickExport
const PolicyInfo **GetPolicyInfoList(
const char *pattern,
395 size_t *number_policies,ExceptionInfo *exception)
406 assert(pattern != (
char *) NULL);
407 assert(number_policies != (
size_t *) NULL);
408 if (IsEventLogging() != MagickFalse)
409 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
411 if (IsPolicyCacheInstantiated(exception) == MagickFalse)
412 return((
const PolicyInfo **) NULL);
413 policies=(
const PolicyInfo **) AcquireQuantumMemory((
size_t)
414 GetNumberOfElementsInLinkedList(policy_cache)+1UL,
sizeof(*policies));
415 if (policies == (
const PolicyInfo **) NULL)
416 return((
const PolicyInfo **) NULL);
417 LockSemaphoreInfo(policy_semaphore);
418 p=GetHeadElementInLinkedList(policy_cache);
419 for (i=0; p != (ElementInfo *) NULL; )
424 policy=(
const PolicyInfo *) p->value;
425 if ((policy->stealth == MagickFalse) &&
426 (GlobExpression(policy->name,pattern,MagickFalse) != MagickFalse))
427 policies[i++]=policy;
430 UnlockSemaphoreInfo(policy_semaphore);
432 policies=(
const PolicyInfo **) RelinquishMagickMemory((
void*) policies);
434 policies[i]=(PolicyInfo *) NULL;
435 *number_policies=(size_t) i;
467static char *AcquirePolicyString(
const char *source,
const size_t pad)
476 if (source != (
char *) NULL)
477 length+=strlen(source);
478 destination=(
char *) NULL;
481 destination=(
char *) AcquireMagickMemory((length+pad)*
sizeof(*destination));
482 if (destination == (
char *) NULL)
483 ThrowFatalException(ResourceLimitFatalError,
"UnableToAcquireString");
484 if (source != (
char *) NULL)
485 (void) memcpy(destination,source,length*
sizeof(*destination));
486 destination[length]=
'\0';
490MagickExport
char **GetPolicyList(
const char *pattern,
size_t *number_policies,
491 ExceptionInfo *exception)
502 assert(pattern != (
char *) NULL);
503 assert(number_policies != (
size_t *) NULL);
504 if (IsEventLogging() != MagickFalse)
505 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
507 if (IsPolicyCacheInstantiated(exception) == MagickFalse)
508 return((
char **) NULL);
509 policies=(
char **) AcquireQuantumMemory((
size_t)
510 GetNumberOfElementsInLinkedList(policy_cache)+1UL,
sizeof(*policies));
511 if (policies == (
char **) NULL)
512 return((
char **) NULL);
513 LockSemaphoreInfo(policy_semaphore);
514 p=GetHeadElementInLinkedList(policy_cache);
515 for (i=0; p != (ElementInfo *) NULL; )
520 policy=(
const PolicyInfo *) p->value;
521 if ((policy->stealth == MagickFalse) &&
522 (GlobExpression(policy->name,pattern,MagickFalse) != MagickFalse))
523 policies[i++]=AcquirePolicyString(policy->name,1);
526 UnlockSemaphoreInfo(policy_semaphore);
528 policies=(
char **) RelinquishMagickMemory(policies);
530 policies[i]=(
char *) NULL;
531 *number_policies=(size_t) i;
557MagickExport
char *GetPolicyValue(
const char *name)
568 assert(name != (
const char *) NULL);
569 if (IsEventLogging() != MagickFalse)
570 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",name);
571 exception=AcquireExceptionInfo();
572 policy_info=GetPolicyInfo(name,exception);
573 exception=DestroyExceptionInfo(exception);
574 if (policy_info == (PolicyInfo *) NULL)
575 return((
char *) NULL);
576 value=policy_info->value;
577 if ((value == (
const char *) NULL) || (*value ==
'\0'))
578 return((
char *) NULL);
579 return(AcquirePolicyString(value,1));
609static inline MagickBooleanType IsPolicyPathSeparator(
const char c)
611#if defined(MAGICKCORE_WINDOWS_SUPPORT)
612 if ((c ==
'/') || (c ==
'\\'))
615 return(c == *DirectorySeparator ? MagickTrue : MagickFalse);
618static inline MagickBooleanType IsPathContainsSymlink(
const char *path)
621 partial[MagickPathExtent];
629 if (path == (
const char *) NULL)
633 if (IsPolicyPathSeparator(*p) != MagickFalse)
638 if ((offset+1) >= (ssize_t)
sizeof(partial))
640 partial[offset++]=(*DirectorySeparator);
642 partial[offset]=
'\0';
647 component[MagickPathExtent];
655 while ((*p !=
'\0') && (IsPolicyPathSeparator(*p) == MagickFalse) &&
656 ((i+1) < (ssize_t)
sizeof(component)))
657 component[i++]=(*p++);
664 if (IsPolicyPathSeparator(*p) != MagickFalse)
668 if ((offset > 0) && (partial[offset-1] != *DirectorySeparator))
673 if ((offset+1) >= (ssize_t)
sizeof(partial))
675 partial[offset++]=(*DirectorySeparator);
676 partial[offset]=
'\0';
681 if ((offset+i) >= (ssize_t)
sizeof(partial))
683 (void) memcpy(partial+offset,component,i);
685 partial[offset]=
'\0';
691 if (is_symlink_utf8(partial) != MagickFalse)
697 if (IsPolicyPathSeparator(*p) != MagickFalse)
703MagickExport MagickBooleanType IsPathAuthorized(
const PolicyRights rights,
706 MagickBooleanType symlink_follow_allowed = IsRightsAuthorizedByName(
707 SystemPolicyDomain,
"symlink",rights,
"follow");
708 MagickBooleanType status =
709 ((IsRightsAuthorized(PathPolicyDomain,rights,path) != MagickFalse) &&
710 ((symlink_follow_allowed != MagickFalse) ||
711 (is_symlink_utf8(path) == MagickFalse))) ? MagickTrue : MagickFalse;
712 if ((status != MagickFalse) && (symlink_follow_allowed == MagickFalse))
714 if ((is_symlink_utf8(path) != MagickFalse) ||
715 (IsPathContainsSymlink(path) != MagickFalse))
718 if (status != MagickFalse)
719 status=IsFileResourceIdentityValid(path);
746static MagickBooleanType IsPolicyCacheInstantiated(ExceptionInfo *exception)
748 if (policy_cache == (LinkedListInfo *) NULL)
750 (void) GetMaxMemoryRequest();
752 ActivateSemaphoreInfo(&policy_semaphore);
753 LockSemaphoreInfo(policy_semaphore);
754 if (policy_cache == (LinkedListInfo *) NULL)
755 policy_cache=AcquirePolicyCache(PolicyFilename,exception);
756 UnlockSemaphoreInfo(policy_semaphore);
758 return(policy_cache != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
795MagickExport MagickBooleanType IsRightsAuthorizedByName(
796 const PolicyDomain domain,
const char *name,
const PolicyRights rights,
800 *canonical_directory = (
char *) NULL,
801 *canonical_path = (
char *) NULL,
802 *canonical_candidate = (
char *) NULL,
803 directory[MagickPathExtent],
804 filename[MagickPathExtent];
813 matched_any = MagickFalse,
814 paths_provisioned = MagickFalse,
815 resolved_matched_any = MagickFalse,
819 effective_rights = AllPolicyRights,
820 resolved_rights = AllPolicyRights;
825 if ((GetLogEventMask() & PolicyEvent) != 0)
826 (void) LogMagickEvent(PolicyEvent,GetMagickModule(),
827 "Domain: %s; name: %s; rights=%s; pattern=\"%s\"; ...",
828 CommandOptionToMnemonic(MagickPolicyDomainOptions,domain),
829 name == (
const char *) NULL ?
"undefined" : name,
830 CommandOptionToMnemonic(MagickPolicyRightsOptions,rights),
831 pattern == (
const char *) NULL ?
"undefined" : pattern);
832 exception=AcquireExceptionInfo();
833 status=IsPolicyCacheInstantiated(exception);
834 exception=DestroyExceptionInfo(exception);
835 if (status == MagickFalse)
837 if ((GetLogEventMask() & PolicyEvent) != 0)
838 (void) LogMagickEvent(PolicyEvent,GetMagickModule(),
839 " authorized: false (security policies could not be loaded)");
849 LockSemaphoreInfo(policy_semaphore);
850 ResetLinkedListIterator(policy_cache);
851 p=GetHeadElementInLinkedList(policy_cache);
852 for ( ; p != (ElementInfo *) NULL; p=p->next)
855 *policy = (PolicyInfo *) p->value;
860 if (policy->domain != domain)
862 if ((name != (
char *) NULL) && (LocaleCompare(name,policy->name) != 0))
864 match=GlobExpression(pattern,policy->pattern,MagickFalse);
865 if (policy->domain == PathPolicyDomain)
867 if (paths_provisioned == MagickFalse)
872 paths_provisioned=MagickTrue;
873 GetPathComponent(pattern,HeadPath,directory);
874 GetPathComponent(pattern,TailPath,filename);
875 canonical_directory=realpath_utf8(directory);
876 if ((canonical_directory != (
char *) NULL) && (*filename !=
'\0'))
881 length=strlen(canonical_directory)+strlen(filename)+2;
882 canonical_candidate=(
char *) AcquireCriticalMemory(length*
883 sizeof(*canonical_candidate));
884 if (canonical_candidate != (
char *) NULL)
885 (void) FormatLocaleString(canonical_candidate,length,
"%s%s%s",
886 canonical_directory,DirectorySeparator,filename);
888 canonical_path=realpath_utf8(pattern);
893 if ((canonical_directory != (
char *) NULL) && (match == MagickFalse))
894 match=GlobExpression(canonical_directory,policy->pattern,MagickFalse);
895 if ((canonical_candidate != (
char *) NULL) && (match == MagickFalse))
896 match=GlobExpression(canonical_candidate,policy->pattern,MagickFalse);
900 if ((canonical_path != (
char *) NULL) &&
901 (GlobExpression(canonical_path,policy->pattern,MagickFalse) != MagickFalse))
903 resolved_matched_any=MagickTrue;
904 resolved_rights=policy->rights;
907 if (match == MagickFalse)
909 matched_any=MagickTrue;
910 effective_rights=policy->rights;
912 UnlockSemaphoreInfo(policy_semaphore);
917 if (matched_any != MagickFalse)
919 if (((rights & ReadPolicyRights) != 0) &&
920 ((effective_rights & ReadPolicyRights) == 0))
922 if (((rights & WritePolicyRights) != 0) &&
923 ((effective_rights & WritePolicyRights) == 0))
925 if (((rights & ExecutePolicyRights) != 0) &&
926 ((effective_rights & ExecutePolicyRights) == 0))
929 if (resolved_matched_any != MagickFalse)
931 if (((rights & ReadPolicyRights) != 0) &&
932 ((resolved_rights & ReadPolicyRights) == 0))
934 if (((rights & WritePolicyRights) != 0) &&
935 ((resolved_rights & WritePolicyRights) == 0))
937 if (((rights & ExecutePolicyRights) != 0) &&
938 ((resolved_rights & ExecutePolicyRights) == 0))
945 if ((paths_provisioned != MagickFalse) && (canonical_path == (
char *) NULL) &&
946 (is_symlink_utf8(pattern) != MagickFalse))
948 if (canonical_directory != (
char *) NULL)
949 canonical_directory=DestroyString(canonical_directory);
950 if (canonical_candidate != (
char *) NULL)
951 canonical_candidate=DestroyString(canonical_candidate);
952 if (canonical_path != (
char *) NULL)
953 canonical_path=DestroyString(canonical_path);
954 if ((GetLogEventMask() & PolicyEvent) != 0)
955 (void) LogMagickEvent(PolicyEvent,GetMagickModule(),
956 " authorized: %s",status == MagickFalse ?
"false" :
"true");
960MagickExport MagickBooleanType IsRightsAuthorized(
const PolicyDomain domain,
961 const PolicyRights rights,
const char *pattern)
963 return(IsRightsAuthorizedByName(domain,(
const char *) NULL,rights,pattern));
990MagickExport MagickBooleanType ListPolicyInfo(FILE *file,
991 ExceptionInfo *exception)
1009 if (file == (
const FILE *) NULL)
1011 policy_info=GetPolicyInfoList(
"*",&number_policies,exception);
1012 if (policy_info == (
const PolicyInfo **) NULL)
1013 return(MagickFalse);
1014 path=(
const char *) NULL;
1015 for (i=0; i < (ssize_t) number_policies; i++)
1017 if (policy_info[i]->stealth != MagickFalse)
1019 if (((path == (
const char *) NULL) ||
1020 (LocaleCompare(path,policy_info[i]->path) != 0)) &&
1021 (policy_info[i]->path != (
char *) NULL))
1022 (void) FormatLocaleFile(file,
"\nPath: %s\n",policy_info[i]->path);
1023 path=policy_info[i]->path;
1024 domain=CommandOptionToMnemonic(MagickPolicyDomainOptions,
1025 policy_info[i]->domain);
1026 (void) FormatLocaleFile(file,
" Policy: %s\n",domain);
1027 if ((policy_info[i]->domain == CachePolicyDomain) ||
1028 (policy_info[i]->domain == ResourcePolicyDomain) ||
1029 (policy_info[i]->domain == SystemPolicyDomain))
1031 if (policy_info[i]->name != (
char *) NULL)
1032 (void) FormatLocaleFile(file,
" name: %s\n",policy_info[i]->name);
1033 if (policy_info[i]->value != (
char *) NULL)
1034 (void) FormatLocaleFile(file,
" value: %s\n",policy_info[i]->value);
1038 (void) FormatLocaleFile(file,
" rights: ");
1039 if (policy_info[i]->rights == NoPolicyRights)
1040 (void) FormatLocaleFile(file,
"None ");
1041 if ((policy_info[i]->rights & ReadPolicyRights) != 0)
1042 (void) FormatLocaleFile(file,
"Read ");
1043 if ((policy_info[i]->rights & WritePolicyRights) != 0)
1044 (void) FormatLocaleFile(file,
"Write ");
1045 if ((policy_info[i]->rights & ExecutePolicyRights) != 0)
1046 (void) FormatLocaleFile(file,
"Execute ");
1047 (void) FormatLocaleFile(file,
"\n");
1048 if (policy_info[i]->pattern != (
char *) NULL)
1049 (void) FormatLocaleFile(file,
" pattern: %s\n",
1050 policy_info[i]->pattern);
1053 policy_info=(
const PolicyInfo **) RelinquishMagickMemory((
void *)
1055 (void) fflush(file);
1090static void *DestroyPolicyElement(
void *policy_info)
1095 p=(PolicyInfo *) policy_info;
1096 if (p->exempt == MagickFalse)
1098 if (p->value != (
char *) NULL)
1099 p->value=DestroyString(p->value);
1100 if (p->pattern != (
char *) NULL)
1101 p->pattern=DestroyString(p->pattern);
1102 if (p->name != (
char *) NULL)
1103 p->name=DestroyString(p->name);
1104 if (p->path != (
char *) NULL)
1105 p->path=DestroyString(p->path);
1107 p=(PolicyInfo *) RelinquishMagickMemory(p);
1108 return((
void *) NULL);
1111static MagickBooleanType LoadPolicyCache(LinkedListInfo *cache,
1112 const char *policy,
const char *filename,
const size_t depth,
1113 ExceptionInfo *exception)
1116 keyword[MagickPathExtent],
1134 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1135 "Loading policy file \"%s\" ...",filename);
1136 if (policy == (
char *) NULL)
1137 return(MagickFalse);
1139 policy_info=(PolicyInfo *) NULL;
1140 token=AcquirePolicyString(policy,MagickPathExtent);
1141 extent=strlen(token)+MagickPathExtent;
1142 for (q=policy; *q !=
'\0'; )
1147 if (SkipXMLComment(&q) == MagickFalse)
1149 (void) ThrowMagickException(exception,GetMagickModule(),
1150 ConfigureError,
"UnterminatedComment",
"`%s'",filename);
1154 (void) GetNextToken(q,&q,extent,token);
1157 (void) CopyMagickString(keyword,token,MagickPathExtent);
1158 if (LocaleNCompare(keyword,
"<!DOCTYPE",9) == 0)
1160 if (SkipXMLDocType(&q) == MagickFalse)
1165 (void) ThrowMagickException(exception,GetMagickModule(),
1166 ConfigureError,
"UnterminatedDOCTYPE",
"`%s'",filename);
1172 if (LocaleCompare(keyword,
"<include") == 0)
1177 while (((*token !=
'/') && (*(token+1) !=
'>')) && (*q !=
'\0'))
1179 (void) CopyMagickString(keyword,token,MagickPathExtent);
1180 (void) GetNextToken(q,&q,extent,token);
1183 (void) GetNextToken(q,&q,extent,token);
1184 if (LocaleCompare(keyword,
"file") == 0)
1186 if (depth >= MagickMaxRecursionDepth)
1187 (void) ThrowMagickException(exception,GetMagickModule(),
1188 ConfigureError,
"IncludeElementNestedTooDeeply",
"`%s'",token);
1192 path[MagickPathExtent],
1195 GetPathComponent(filename,HeadPath,path);
1197 (void) ConcatenateMagickString(path,DirectorySeparator,
1199 if (*token == *DirectorySeparator)
1200 (void) CopyMagickString(path,token,MagickPathExtent);
1202 (
void) ConcatenateMagickString(path,token,MagickPathExtent);
1203 file_xml=FileToXML(path,~0UL);
1204 if (file_xml != (
char *) NULL)
1206 if (LoadPolicyCache(cache,file_xml,path,depth+1,exception) == MagickFalse)
1208 file_xml=DestroyString(file_xml);
1209 if (status == MagickFalse)
1215 if (status == MagickFalse)
1219 if (LocaleCompare(keyword,
"<policy") == 0)
1224 policy_info=(PolicyInfo *) AcquireCriticalMemory(
sizeof(*policy_info));
1225 (void) memset(policy_info,0,
sizeof(*policy_info));
1226 policy_info->path=AcquirePolicyString(filename,1);
1227 policy_info->exempt=MagickFalse;
1228 policy_info->signature=MagickCoreSignature;
1231 if (policy_info == (PolicyInfo *) NULL)
1233 if ((LocaleCompare(keyword,
"/>") == 0) ||
1234 (LocaleCompare(keyword,
"</policy>") == 0))
1236 status=AppendValueToLinkedList(cache,policy_info);
1237 if (status == MagickFalse)
1238 (void) ThrowMagickException(exception,GetMagickModule(),
1239 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
1241 policy_info=(PolicyInfo *) NULL;
1244 (void) GetNextToken(q,(
const char **) NULL,extent,token);
1247 (void) GetNextToken(q,&q,extent,token);
1248 (void) GetNextToken(q,&q,extent,token);
1254 if (LocaleCompare((
char *) keyword,
"domain") == 0)
1256 policy_info->domain=(PolicyDomain) ParseCommandOption(
1257 MagickPolicyDomainOptions,MagickTrue,token);
1265 if (LocaleCompare((
char *) keyword,
"name") == 0)
1267 policy_info->name=AcquirePolicyString(token,1);
1275 if (LocaleCompare((
char *) keyword,
"pattern") == 0)
1277 policy_info->pattern=AcquirePolicyString(token,1);
1285 if (LocaleCompare((
char *) keyword,
"rights") == 0)
1287 policy_info->rights=(PolicyRights) ParseCommandOption(
1288 MagickPolicyRightsOptions,MagickTrue,token);
1296 if (LocaleCompare((
char *) keyword,
"stealth") == 0)
1298 policy_info->stealth=IsStringTrue(token);
1306 if (LocaleCompare((
char *) keyword,
"value") == 0)
1308 policy_info->value=AcquirePolicyString(token,1);
1317 if (policy_info != (PolicyInfo *) NULL)
1318 (void) DestroyPolicyElement(policy_info);
1319 token=(
char *) RelinquishMagickMemory(token);
1341MagickPrivate MagickBooleanType PolicyComponentGenesis(
void)
1344 policy_semaphore=AcquireSemaphoreInfo();
1366MagickPrivate
void PolicyComponentTerminus(
void)
1369 ActivateSemaphoreInfo(&policy_semaphore);
1370 LockSemaphoreInfo(policy_semaphore);
1371 if (policy_cache != (LinkedListInfo *) NULL)
1372 policy_cache=DestroyLinkedList(policy_cache,DestroyPolicyElement);
1373 UnlockSemaphoreInfo(policy_semaphore);
1374 RelinquishSemaphoreInfo(&policy_semaphore);
1404static MagickBooleanType ValidateSecurityPolicy(
const char *policy,
1405 const char *url,ExceptionInfo *exception)
1407#if defined(MAGICKCORE_XML_DELEGATE)
1414 document=xmlReadMemory(policy,(
int) strlen(policy),url,NULL,
1415 XML_PARSE_NOERROR | XML_PARSE_NOWARNING);
1416 if (document == (xmlDocPtr) NULL)
1418 (void) ThrowMagickException(exception,GetMagickModule(),ConfigureError,
1419 "PolicyValidationException",
"'%s'",url);
1420 return(MagickFalse);
1422 xmlFreeDoc(document);
1431MagickExport MagickBooleanType SetMagickSecurityPolicy(
const char *policy,
1432 ExceptionInfo *exception)
1446 assert(exception != (ExceptionInfo *) NULL);
1447 if (policy == (
const char *) NULL)
1448 return(MagickFalse);
1449 if (ValidateSecurityPolicy(policy,PolicyFilename,exception) == MagickFalse)
1450 return(MagickFalse);
1451 LockSemaphoreInfo(policy_semaphore);
1452 status=LoadPolicyCache(policy_cache,policy,
"[user-policy]",0,exception);
1453 UnlockSemaphoreInfo(policy_semaphore);
1454 if (status == MagickFalse)
1459 user_policies=NewLinkedList(0);
1460 status=LoadPolicyCache(user_policies,policy,
"[user-policy]",0,exception);
1461 if (status == MagickFalse)
1463 user_policies=DestroyLinkedList(user_policies,DestroyPolicyElement);
1464 return(MagickFalse);
1466 ResetLinkedListIterator(user_policies);
1467 p=(PolicyInfo *) GetNextValueInLinkedList(user_policies);
1468 while (p != (PolicyInfo *) NULL)
1470 if ((p->name != (
char *) NULL) && (p->value != (
char *) NULL))
1471 (void) SetMagickSecurityPolicyValue(p->domain,p->name,p->value,exception);
1472 p=(PolicyInfo *) GetNextValueInLinkedList(user_policies);
1474 user_policies=DestroyLinkedList(user_policies,DestroyPolicyElement);
1511MagickExport MagickBooleanType SetMagickSecurityPolicyValue(
1512 const PolicyDomain domain,
const char *name,
const char *value,
1513 ExceptionInfo *exception)
1515 magick_unreferenced(exception);
1516 assert(exception != (ExceptionInfo *) NULL);
1517 if ((name == (
const char *) NULL) || (value == (
const char *) NULL))
1518 return(MagickFalse);
1521 case CachePolicyDomain:
1523 if (LocaleCompare(name,
"memory-map") == 0)
1525 if (LocaleCompare(value,
"anonymous") != 0)
1526 return(MagickFalse);
1527 ResetCacheAnonymousMemory();
1528 ResetStreamAnonymousMemory();
1533 case ResourcePolicyDomain:
1538 type=ParseCommandOption(MagickResourceOptions,MagickFalse,name);
1544 limit=MagickResourceInfinity;
1545 if (LocaleCompare(
"unlimited",value) != 0)
1546 limit=StringToMagickSizeType(value,100.0);
1547 if ((ResourceType) type == TimeResource)
1548 limit=(MagickSizeType) ParseMagickTimeToLive(value);
1549 return(SetMagickResourceLimit((ResourceType) type,limit));
1553 case SystemPolicyDomain:
1555 if (LocaleCompare(name,
"max-memory-request") == 0)
1560 limit=MagickResourceInfinity;
1561 if (LocaleCompare(
"unlimited",value) != 0)
1562 limit=StringToMagickSizeType(value,100.0);
1563 SetMaxMemoryRequest(limit);
1566 if (LocaleCompare(name,
"max-profile-size") == 0)
1571 limit=MagickResourceInfinity;
1572 if (LocaleCompare(
"unlimited",value) != 0)
1573 limit=StringToMagickSizeType(value,100.0);
1574 SetMaxProfileSize(limit);
1577 if (LocaleCompare(name,
"memory-map") == 0)
1579 if (LocaleCompare(value,
"anonymous") != 0)
1580 return(MagickFalse);
1581 ResetVirtualAnonymousMemory();
1584 if (LocaleCompare(name,
"precision") == 0)
1589 limit=StringToInteger(value);
1590 SetMagickPrecision(limit);
1595 case CoderPolicyDomain:
1596 case DelegatePolicyDomain:
1597 case FilterPolicyDomain:
1598 case ModulePolicyDomain:
1599 case PathPolicyDomain:
1603 return(MagickFalse);