From 6ccff4c232f2c867cef173c7bfc9ca79ea43a15d Mon Sep 17 00:00:00 2001 From: Akira Kakuto Date: Wed, 9 Mar 2011 05:32:47 +0000 Subject: add a new special pdf:encrypt by Matthias Franz. git-svn-id: svn://tug.org/texlive/trunk@21656 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/xdvipdfmx/ChangeLog.TL | 6 ++ Build/source/texk/xdvipdfmx/src/dpxfile.c | 131 ++++++++++++++++++++++++--- Build/source/texk/xdvipdfmx/src/dvi.c | 57 +++++++++++- Build/source/texk/xdvipdfmx/src/dvi.h | 3 +- Build/source/texk/xdvipdfmx/src/dvipdfmx.c | 33 +++++-- Build/source/texk/xdvipdfmx/src/pdfencrypt.c | 48 +++++----- Build/source/texk/xdvipdfmx/src/pdfencrypt.h | 4 +- Build/source/texk/xdvipdfmx/src/spc_pdfm.c | 1 + 8 files changed, 235 insertions(+), 48 deletions(-) (limited to 'Build/source/texk/xdvipdfmx') diff --git a/Build/source/texk/xdvipdfmx/ChangeLog.TL b/Build/source/texk/xdvipdfmx/ChangeLog.TL index a688f921aa9..f083bfa8c17 100644 --- a/Build/source/texk/xdvipdfmx/ChangeLog.TL +++ b/Build/source/texk/xdvipdfmx/ChangeLog.TL @@ -1,6 +1,12 @@ ChangeLog.TL: TeX Live (TL) changes for xdvipdfmx ================================================= +2011-03-09 Akira Kakuto + * src/dpxfile.c: Avoid to use system(). + * src/dvi.c, src/dvi.h, src/dvipdfmx.c, src/pdfencript.c, + src/pdfencrypt.h, src/spc_pdfm.c: new special pdf:encrypt + by Matthias Franz. + 2011-02-28 Peter Breitenlohner * src/pngimage.c (create_cspace_ICCBased): Avoid libpng-1.5.x diff --git a/Build/source/texk/xdvipdfmx/src/dpxfile.c b/Build/source/texk/xdvipdfmx/src/dpxfile.c index 8e89f207911..e7cbf85a54d 100644 --- a/Build/source/texk/xdvipdfmx/src/dpxfile.c +++ b/Build/source/texk/xdvipdfmx/src/dpxfile.c @@ -1,8 +1,8 @@ -/* $Header: /home/cvsroot/dvipdfmx/src/dpxfile.c,v 1.25 2009/03/12 19:29:48 matthias Exp $ +/* $Header: /home/cvsroot/dvipdfmx/src/dpxfile.c,v 1.27 2011/03/05 02:01:28 chofchof Exp $ This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata, + Copyright (C) 2007 by Jin-Hwan Cho and Shunsaku Hirata, the dvipdfmx project team Copyright (C) 1998, 1999 by Mark A. Wicks @@ -35,6 +35,23 @@ #include "dpxfile.h" +#include +#include +#ifdef WIN32 +#include +#include +#else +#if HAVE_SYS_WAIT_H +#include +#endif +#ifndef WEXITSTATUS +#define WEXITSTATUS(val) ((unsigned)(val) >> 8) +#endif +#ifndef WIFEXITED +#define WIFEXITED(val) (((val) & 255) == 0) +#endif +#endif + static int verbose = 0; void @@ -135,6 +152,104 @@ miktex_find_psheader_file (const char *filename, char *buf) static char _tmpbuf[_MAX_PATH+1]; #endif /* MIKTEX */ +static int exec_spawn (char *cmd) +{ + char **cmdv, **qv; + char *p, *pp; + char buf[512]; + int i, ret; + + if (!cmd || !*cmd) + return -1; + i = 0; + p = cmd; + while (*p) { + if (*p == ' ' || *p == '\t') + i++; + p++; + } + cmdv = (char **) xmalloc (sizeof (char *) * (i+2)); + p = cmd; + qv = cmdv; + while (*p == ' ' || *p == '\t') + p++; + while (*p) { + pp = buf; + if (*p == '"') { + p++; + while (*p != '"') { + if (*p == '\0') { + free (cmdv); + return -1; + } + *pp++ = *p++; + } + p++; + } else if (*p == '\'') { + p++; + while (*p != '\'') { + if (*p == '\0') { + free (cmdv); + return -1; + } + *pp++ = *p++; + } + p++; + } else { + while (*p != ' ' && *p != '\t' && *p) +#ifdef WIN32 + if (*p == '\'') { + *pp++ = '\"'; + p++; + } else { + *pp++ = *p++; + } +#else + *pp++ = *p++; +#endif + } + *pp = '\0'; + if ((pp = strchr (buf, ' ')) || (pp = strchr (buf, '\t'))) { +#ifdef WIN32 + *qv = concat3 ("\"", buf, "\""); +#else + *qv = concat3 ("'", buf, "'"); +#endif + } else { + *qv = concat (buf, ""); + } + while (*p == ' ' || *p == '\t') + p++; + qv++; + } + *qv = NULL; +#ifdef WIN32 + ret = spawnvp (_P_WAIT, *cmdv, (const char* const*) cmdv); +#else + i = fork (); + if (i < 0) + ret = -1; + else if (i == 0) { + if (execvp (*cmdv, cmdv)) + ret = -1; + } else { + if (wait (&ret) == i) { + ret = (WIFEXITED (ret) ? WEXITSTATUS (ret) : -1); + } else { + ret = -1; + } + } +#endif + qv = cmdv; + if (qv) { + while (*qv) { + free (*qv); + qv++; + } + free (cmdv); + } + return ret; +} /* ensuresuffix() returns a copy of basename if sfx is "". */ static char * @@ -695,7 +810,6 @@ dpx_delete_temp_file (char *tmp) return; } -#ifdef HAVE_SYSTEM /* dpx_file_apply_filter() is used for converting unsupported graphics * format to one of the formats that dvipdfmx can natively handle. * 'input' is the filename of the original file and 'output' is actually @@ -703,6 +817,7 @@ dpx_delete_temp_file (char *tmp) * This should be system dependent. (MiKTeX may want something different) * Please modify as appropriate (see also pdfximage.c and dvipdfmx.c). */ + int dpx_file_apply_filter (const char *cmdtmpl, const char *input, const char *output, @@ -773,21 +888,13 @@ if ((l) + (n) >= (m)) { \ return -1; } - error = system(cmd); + error = exec_spawn(cmd); if (error) WARN("Filtering file via command -->%s<-- failed.", cmd); RELEASE(cmd); return error; } -#else -int -dpx_file_apply_filter (const char *cmdtmpl, const char *input, const char *output) -{ - WARN("Your system does not have system()."); - return -1; -} -#endif /* HAVE_SYSTEM */ static char _sbuf[128]; /* diff --git a/Build/source/texk/xdvipdfmx/src/dvi.c b/Build/source/texk/xdvipdfmx/src/dvi.c index a0ab254d4f5..f6b4f8a92e7 100644 --- a/Build/source/texk/xdvipdfmx/src/dvi.c +++ b/Build/source/texk/xdvipdfmx/src/dvi.c @@ -45,6 +45,7 @@ #include "pdfdev.h" #include "pdfdoc.h" #include "pdfparse.h" +#include "pdfencrypt.h" #include "fontmap.h" @@ -2490,7 +2491,10 @@ read_length (double *vp, double mag, const char **pp, const char *endptr) static int -scan_special (double *wd, double *ht, double *xo, double *yo, char *lm, unsigned *minorversion, const char *buf, UNSIGNED_QUAD size) +scan_special (double *wd, double *ht, double *xo, double *yo, char *lm, + unsigned *minorversion, + int *do_enc, unsigned *key_bits, unsigned *permission, char *owner_pw, char *user_pw, + const char *buf, UNSIGNED_QUAD size) { char *q; const char *p = buf, *endptr; @@ -2597,6 +2601,48 @@ scan_special (double *wd, double *ht, double *xo, double *yo, char *lm, unsigned *minorversion = (unsigned)strtol(kv, NULL, 10); RELEASE(kv); } + } else if (ns_pdf && !strcmp(q, "encrypt") && do_enc) { + *do_enc = 1; + *owner_pw = *user_pw = 0; + while (!error && p < endptr) { + char *kp = parse_c_ident(&p, endptr); + if (!kp) + break; + else { + pdf_obj *obj; + skip_white(&p, endptr); + if (!strcmp(kp, "ownerpw")) { + if ((obj = parse_pdf_string(&p, endptr))) { + strncpy(owner_pw, pdf_string_value(obj), MAX_PWD_LEN); + pdf_release_obj(obj); + } else + error = -1; + } else if (!strcmp(kp, "userpw")) { + if ((obj = parse_pdf_string(&p, endptr))) { + strncpy(user_pw, pdf_string_value(obj), MAX_PWD_LEN); + pdf_release_obj(obj); + } else + error = -1; + } else if (!strcmp(kp, "length")) { + if ((obj = parse_pdf_number(&p, endptr)) && PDF_OBJ_NUMBERTYPE(obj)) { + *key_bits = (unsigned) pdf_number_value(obj); + } else + error = -1; + if (obj) + pdf_release_obj(obj); + } else if (!strcmp(kp, "perm")) { + if ((obj = parse_pdf_number(&p, endptr)) && PDF_OBJ_NUMBERTYPE(obj)) { + *permission = (unsigned) pdf_number_value(obj); + } else + error = -1; + if (obj) + pdf_release_obj(obj); + } else + error = -1; + RELEASE(kp); + } + skip_white(&p, endptr); + } } RELEASE(q); } @@ -2609,7 +2655,8 @@ void dvi_scan_specials (long page_no, double *page_width, double *page_height, double *x_offset, double *y_offset, char *landscape, - unsigned *minorversion) + unsigned *minorversion, + int *do_enc, unsigned *key_bits, unsigned *permission, char *owner_pw, char *user_pw) { FILE *fp = dvi_file; long offset; @@ -2649,8 +2696,10 @@ dvi_scan_specials (long page_no, } if (fread(dvi_page_buffer + dvi_page_buf_index, sizeof(char), size, fp) != size) ERROR("Reading DVI file failed!"); - scan_special(page_width, page_height, x_offset, y_offset, landscape, minorversion, - (char*)dvi_page_buffer + dvi_page_buf_index, size); + if (scan_special(page_width, page_height, x_offset, y_offset, landscape, minorversion, + do_enc, key_bits, permission, owner_pw, user_pw, + (char*)dvi_page_buffer + dvi_page_buf_index, size)) + WARN("Reading special command failed: \"%.*s\"", size, (char*)dvi_page_buffer + dvi_page_buf_index); dvi_page_buf_index += size; continue; } diff --git a/Build/source/texk/xdvipdfmx/src/dvi.h b/Build/source/texk/xdvipdfmx/src/dvi.h index d4a87a2a79b..396d9b8f0f1 100644 --- a/Build/source/texk/xdvipdfmx/src/dvi.h +++ b/Build/source/texk/xdvipdfmx/src/dvi.h @@ -73,7 +73,8 @@ extern void dvi_do_page (long page_no, extern void dvi_scan_specials (long page_no, double *width, double *height, double *x_offset, double *y_offset, - char *landscape, unsigned *minorversion); + char *landscape, unsigned *minorversion, + int *do_enc, unsigned *key_bits, unsigned *permission, char *owner_pw, char *user_pw); extern int dvi_locate_font (const char *name, spt_t ptsize); /* link or nolink: diff --git a/Build/source/texk/xdvipdfmx/src/dvipdfmx.c b/Build/source/texk/xdvipdfmx/src/dvipdfmx.c index 5e7e8c8abaf..6e0431b7791 100644 --- a/Build/source/texk/xdvipdfmx/src/dvipdfmx.c +++ b/Build/source/texk/xdvipdfmx/src/dvipdfmx.c @@ -140,7 +140,7 @@ usage (int exit_code) fprintf (stdout, "\nThis is %s-%s by Jonathan Kew and Jin-Hwan Cho,\n", PACKAGE, VERSION); fprintf (stdout, "an extended version of DVIPDFMx, which in turn was\n"); fprintf (stdout, "an extended version of dvipdfm-0.13.2c developed by Mark A. Wicks.\n"); - fprintf (stdout, "\nCopyright (c) 2006-2008 SIL International and Jin-Hwan Cho.\n"); + fprintf (stdout, "\nCopyright (c) 2006-2011 SIL International and Jin-Hwan Cho.\n"); fprintf (stdout, "\nThis is free software; you can redistribute it and/or modify\n"); fprintf (stdout, "it under the terms of the GNU General Public License as published by\n"); fprintf (stdout, "the Free Software Foundation; either version 2 of the License, or\n"); @@ -175,7 +175,7 @@ usage (int exit_code) fprintf (stdout, "\t\tAnd negative values replace old values.\n"); fprintf (stdout, "-D template\tPS->PDF conversion command line template [none]\n"); fprintf (stdout, "-E \t\tAlways try to embed fonts, regardless of licensing flags.\n"); - fprintf (stdout, "-K number\tEncryption key bits [40]\n"); + fprintf (stdout, "-K number\tEncryption key length [40]\n"); fprintf (stdout, "-O number\tSet maximum depth of open bookmark items [0]\n"); fprintf (stdout, "-P number\tSet permission flags for PDF encryption [0x003C]\n"); fprintf (stdout, "-S \t\tEnable PDF encryption\n"); @@ -511,10 +511,10 @@ do_args (int argc, char *argv[]) do_encryption = 1; break; case 'K': - CHECK_ARG(1, "encryption key bits"); + CHECK_ARG(1, "encryption key length"); key_bits = (unsigned) atoi(argv[1]); - if (key_bits < 40 || key_bits > 128) - ERROR("Invalid encryption key bits specified: %s", argv[1]); + if (key_bits < 40 || key_bits > 128 || (key_bits & 0x7)) + ERROR("Invalid encryption key length specified: %s", argv[1]); POP_ARG(); break; case 'P': @@ -708,7 +708,7 @@ do_dvi_pages (void) page_width = paper_width; page_height = paper_height; w = page_width; h = page_height; lm = landscape_mode; xo = x_offset; yo = y_offset; - dvi_scan_specials(page_no, &w, &h, &xo, &yo, &lm, NULL); + dvi_scan_specials(page_no, &w, &h, &xo, &yo, &lm, NULL, NULL, NULL, NULL, NULL, NULL); if (lm != landscape_mode) { SWAP(w, h); landscape_mode = lm; @@ -859,7 +859,7 @@ main (int argc, char *argv[]) set_default_pdf_filename(); if (do_encryption) { - pdf_enc_set_passwd(key_bits, permission, dvi_filename, pdf_filename); + pdf_enc_set_passwd(key_bits, permission, NULL, NULL); if (key_bits > 40 && pdf_get_version() < 4) pdf_set_version(4); } @@ -870,6 +870,7 @@ main (int argc, char *argv[]) dvi2pts = 0.01; /* dvi2pts controls accuracy. */ } else { unsigned ver_minor = 0; + char owner_pw[MAX_PWD_LEN], user_pw[MAX_PWD_LEN]; /* Dependency between DVI and PDF side is rather complicated... */ dvi2pts = dvi_init(dvi_filename, mag); if (dvi2pts == 0.0) @@ -877,7 +878,23 @@ main (int argc, char *argv[]) pdf_doc_set_creator(dvi_comment()); - dvi_scan_specials(0, &paper_width, &paper_height, &x_offset, &y_offset, &landscape_mode, &ver_minor); + if (do_encryption) + /* command line takes precedence */ + dvi_scan_specials(0, &paper_width, &paper_height, &x_offset, &y_offset, &landscape_mode, + &ver_minor, NULL, NULL, NULL, NULL, NULL); + else { + dvi_scan_specials(0, &paper_width, &paper_height, &x_offset, &y_offset, &landscape_mode, + &ver_minor, &do_encryption, &key_bits, &permission, owner_pw, user_pw); + if (do_encryption) { + if (key_bits < 40 || key_bits > 128 || (key_bits & 0x7)) + ERROR("Invalid encryption key length specified: %u", key_bits); + else if (key_bits > 40 && pdf_get_version() < 4) + ERROR("Chosen key length requires at least PDF 1.4. " + "Use \"-V 4\" to change."); + do_encryption = 1; + pdf_enc_set_passwd(key_bits, permission, owner_pw, user_pw); + } + } if (ver_minor >= PDF_VERSION_MIN && ver_minor <= PDF_VERSION_MAX) { pdf_set_version(ver_minor); } diff --git a/Build/source/texk/xdvipdfmx/src/pdfencrypt.c b/Build/source/texk/xdvipdfmx/src/pdfencrypt.c index d90c77c23e2..8edf21acb06 100644 --- a/Build/source/texk/xdvipdfmx/src/pdfencrypt.c +++ b/Build/source/texk/xdvipdfmx/src/pdfencrypt.c @@ -46,7 +46,6 @@ #define MAX_KEY_LEN 16 #define MAX_STR_LEN 32 -#define MAX_PWD_LEN 128 static unsigned char algorithm, revision, key_size; static unsigned long permission; @@ -365,27 +364,33 @@ static char *getpass (const char *prompt) } #endif -void pdf_enc_set_passwd (unsigned bits, unsigned perm, char *dviname, char *pdfname) +void pdf_enc_set_passwd (unsigned bits, unsigned perm, const char *owner_pw, const char *user_pw) { - register char *retry_passwd; - - while (1) { - strcpy(owner_passwd, getpass("Owner password: ")); - retry_passwd = getpass("Re-enter owner password: "); - if (!strcmp(owner_passwd, retry_passwd)) - break; - fputs("Password is not identical.\nTry again.\n", stderr); - fflush(stderr); - } - - while (1) { - strcpy(user_passwd, getpass("User password: ")); - retry_passwd = getpass("Re-enter user password: "); - if (!strcmp(user_passwd, retry_passwd)) - break; - fputs("Password is not identical.\nTry again.\n", stderr); - fflush(stderr); - } + char *retry_passwd; + + if (owner_pw) { + strncpy(owner_passwd, owner_pw, MAX_PWD_LEN); + } else + while (1) { + strncpy(owner_passwd, getpass("Owner password: "), MAX_PWD_LEN); + retry_passwd = getpass("Re-enter owner password: "); + if (!strncmp(owner_passwd, retry_passwd, MAX_PWD_LEN)) + break; + fputs("Password is not identical.\nTry again.\n", stderr); + fflush(stderr); + } + + if (user_pw) { + strncpy(user_passwd, user_pw, MAX_PWD_LEN); + } else + while (1) { + strncpy(user_passwd, getpass("User password: "), MAX_PWD_LEN); + retry_passwd = getpass("Re-enter user password: "); + if (!strncmp(user_passwd, retry_passwd, MAX_PWD_LEN)) + break; + fputs("Password is not identical.\nTry again.\n", stderr); + fflush(stderr); + } key_size = (unsigned char)(bits / 8); algorithm = (key_size == 5 ? 1 : 2); @@ -394,7 +399,6 @@ void pdf_enc_set_passwd (unsigned bits, unsigned perm, char *dviname, char *pdfn if (revision == 3) permission |= 0xFFFFF000; - compute_id_string(dviname, pdfname); compute_owner_password(); compute_user_password(); } diff --git a/Build/source/texk/xdvipdfmx/src/pdfencrypt.h b/Build/source/texk/xdvipdfmx/src/pdfencrypt.h index 4735d89d976..8b4d536b323 100644 --- a/Build/source/texk/xdvipdfmx/src/pdfencrypt.h +++ b/Build/source/texk/xdvipdfmx/src/pdfencrypt.h @@ -25,11 +25,13 @@ #include "pdfobj.h" +#define MAX_PWD_LEN 128 + extern void pdf_enc_set_verbose (void); extern pdf_obj *pdf_enc_id_array (void); extern void pdf_enc_set_label (unsigned long label); extern void pdf_enc_set_generation (unsigned generation); -extern void pdf_enc_set_passwd (unsigned size, unsigned perm, char *dviname, char *pdfname); +extern void pdf_enc_set_passwd (unsigned size, unsigned perm, const char *owner, const char *user); extern void pdf_encrypt_data (unsigned char *data, unsigned long len); extern pdf_obj *pdf_encrypt_obj (void); diff --git a/Build/source/texk/xdvipdfmx/src/spc_pdfm.c b/Build/source/texk/xdvipdfmx/src/spc_pdfm.c index fd337d8cf0c..2561d3ffcda 100644 --- a/Build/source/texk/xdvipdfmx/src/spc_pdfm.c +++ b/Build/source/texk/xdvipdfmx/src/spc_pdfm.c @@ -2054,6 +2054,7 @@ static struct spc_handler pdfm_handlers[] = { {"code", spc_handler_pdfm_code}, {"minorversion", spc_handler_pdfm_do_nothing}, + {"encrypt", spc_handler_pdfm_do_nothing}, }; int -- cgit v1.2.3