造冰箱的大熊猫@cnblogs 2019/1/21

1、环境

操作系统/Ubuntu 16.04.5 LTS,内核/4.15.0-43-generic,convert/ImageMagick 6.8.9-9

2、问题

使用convert命令将一个jpeg格式的图片文件转换为pdf文档时,提示“convert: not authorized `1.pdf` @ error/constitute.c/WriteImage/1028”错误。

$ convert 1.jpg 1.pdf
convert: not authorized `1.pdf` @ error/constitute.c/WriteImage/1028.
$

3、分析

不关心问题原因的,可以跳过这部分直接跳到下面的“4、排除故障”。

从sourceforge下载ImageMagick的源代码压缩包(版本6.8.9-10,没找到6.8.9-9的源代码)[1]。解压缩获得源代码。

根据错误信息,在源代码“magick”目录下打开“constitute.c”文件,并跳转到该文件的1028行(下面代码中第6行)。从代码中可以看到,错误是由于IsRightsAuthorized()函数返回错误导致的。

  domain=CoderPolicyDomain;
rights=WritePolicyRights;
if (IsRightsAuthorized(domain,rights,write_info->magick) == MagickFalse)
{
sans_exception=DestroyExceptionInfo(sans_exception);
write_info=DestroyImageInfo(write_info);
errno=EPERM;
ThrowBinaryException(PolicyError,"NotAuthorized",filename);
}

打开“policy.c” 文件,找到IsRightsAuthorized()函数的代码(如下所示),判断函数返回失败(MagickFalse)是由于给定的PolicyDomian和PoicyRights与policy_cache中的值不匹配导致的。

MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
const PolicyRights rights,const char *pattern)
{
const PolicyInfo
*policy_info; ExceptionInfo
*exception; MagickBooleanType
authorized; register PolicyInfo
*p; (void) LogMagickEvent(PolicyEvent,GetMagickModule(),
"Domain: %s; rights=%s; pattern=\"%s\" ...",
CommandOptionToMnemonic(MagickPolicyDomainOptions,domain),
CommandOptionToMnemonic(MagickPolicyRightsOptions,rights),pattern);
exception=AcquireExceptionInfo();
policy_info=GetPolicyInfo("*",exception);
exception=DestroyExceptionInfo(exception);
if (policy_info == (PolicyInfo *) NULL)
return(MagickTrue);
authorized=MagickTrue;
LockSemaphoreInfo(policy_semaphore);
ResetLinkedListIterator(policy_cache);
p=(PolicyInfo *) GetNextValueInLinkedList(policy_cache);
while ((p != (PolicyInfo *) NULL) && (authorized != MagickFalse))
{
if ((p->domain == domain) &&
(GlobExpression(pattern,p->pattern,MagickFalse) != MagickFalse))
{
if (((rights & ReadPolicyRights) != 0) &&
((p->rights & ReadPolicyRights) == 0))
authorized=MagickFalse;
if (((rights & WritePolicyRights) != 0) &&
((p->rights & WritePolicyRights) == 0))
authorized=MagickFalse;
if (((rights & ExecutePolicyRights) != 0) &&
((p->rights & ExecutePolicyRights) == 0))
authorized=MagickFalse;
}
p=(PolicyInfo *) GetNextValueInLinkedList(policy_cache);
}
UnlockSemaphoreInfo(policy_semaphore);
return(authorized);
}

在该文件中继续搜索,发现policy_cache由IsPolicyCacheInstantiated()函数从PolicyFilename指向的文件中读取。而PolicyFilename为“policy.xml”(#define PolicyFilename  "policy.xml")。

static MagickBooleanType IsPolicyCacheInstantiated(ExceptionInfo *exception)
{
if (policy_cache == (LinkedListInfo *) NULL)
{
if (policy_semaphore == (SemaphoreInfo *) NULL)
ActivateSemaphoreInfo(&policy_semaphore);
LockSemaphoreInfo(policy_semaphore);
if (policy_cache == (LinkedListInfo *) NULL)
policy_cache=AcquirePolicyCache(PolicyFilename,exception);
UnlockSemaphoreInfo(policy_semaphore);
}
return(policy_cache != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
}

在“/etc/ImageMagick-6”下搜索到“policy.xml”文件。根据该文件中给出的注释信息,pdf文件的权限被设置为“none”,要想获得写权限,需增加“write”权限。具体操作步骤参考“4、排除故障”。

在policy.xml禁止pdf写权限是在Ubuntu的某次安全性升级时实施的[2],具体与imagemagickluanchpad的安全策略相关[ 3]。没仔细研究到底是什么情况,有兴趣的研究明白的请告知。

4、排除故障

使用文件编辑器打开“/etc/ImageMagick-6/policy.xml”,找到类似“<policy domain="coder" rights="none" pattern="PDF" />”的一行,将其中的“none”改为“write”,保存文件。重新执行convert命令即可。

参考

[1] ImageMagick 6.8.9源代码 @ sourceforge

[2] imagemagick change log "disable ghostscript handled types by default in policy.xml" @ lunchpad.net

[3] security policy说明 @ imagemagick

最新文章

  1. php 将查询出的数组数据存入redis
  2. js中的hasOwnProperty()和isPrototypeOf()
  3. Apache使用mod_deflate模块压缩页面优化传输速度
  4. Ajax与Json的一些总结
  5. C#三元运算符
  6. asp.net网站性能优化2则
  7. [JavaScript]plupload多图片上传图片
  8. i/10和i取最后两位的精妙算法(前方高能)
  9. log4j配置及使用
  10. 一款好用的JS时间日期插件layDate
  11. [Unity优化]批处理01:Statistics窗口
  12. js自动时间
  13. Spark学习(一)
  14. matlab : Nelder mead simplex 单纯形直接搜索算法;
  15. Rsync 常见错误及解决方法
  16. 【转】Python数据类型之“序列概述与基本序列类型(Basic Sequences)”
  17. BZOJ 3498: PA2009 Cakes 一类经典的三元环计数问题
  18. 解决Win10 Virtualbox5.2.18桥接不能联网小记
  19. python变量交换及注释种类,注释注意事项/注释排查方法
  20. 无线渗透开启WPS功能的路由器

热门文章

  1. JS实现点击查看密码功能,再次点击隐藏密码!
  2. log4j rootLogger配置示例(log4j.properties)
  3. python中while循环打印星星的四种形状
  4. Js 更换html同一父元素下子元素的位置
  5. 如何调试Python程序 通过IDLE
  6. 如何将webstrom本地的代码上传到github上
  7. VMwarevSphere Client 链接 vCenter Server中的主机,开启虚拟机提示:在主机当前连接状况下不允许执行该操作
  8. linux 进程优先级 调度 nice pri
  9. pandas中Series对象下的str所拥有的方法(df[&quot;xx&quot;].str)
  10. deep_learning_neural network梯度下降