mirror of
https://github.com/qpdf/qpdf.git
synced 2025-04-02 14:41:50 +00:00
Implement new --encrypt args and completion (fixes #784)
Positional arguments are supported in a backward-compatible way, but completion no longer guides users to it.
This commit is contained in:
parent
1173a0bdfc
commit
7d7e2234a5
@ -1,5 +1,13 @@
|
|||||||
2023-12-22 Jay Berkenbilt <ejb@ql.org>
|
2023-12-22 Jay Berkenbilt <ejb@ql.org>
|
||||||
|
|
||||||
|
* Allow the syntax "--encrypt --user-password=user-password
|
||||||
|
--owner-password=owner-password --bits={40,128,256}" when
|
||||||
|
encrypting PDF files. This is an alternative to the syntax
|
||||||
|
"--encrypt user-password owner-password {40,128,256}", which will
|
||||||
|
continue to be supported. The new syntax works better with shell
|
||||||
|
completion and allows creation of passwords that start with "-".
|
||||||
|
Fixes #874.
|
||||||
|
|
||||||
* When setting a check box value, allow any value other than /Off
|
* When setting a check box value, allow any value other than /Off
|
||||||
to mean checked. This is permitted by the spec. Previously, any
|
to mean checked. This is permitted by the spec. Previously, any
|
||||||
value other than /Yes or /Off was rejected. Fixes #1056.
|
value other than /Yes or /Off was rejected. Fixes #1056.
|
||||||
|
4
job.sums
4
job.sums
@ -8,10 +8,10 @@ include/qpdf/auto_job_c_pages.hh b3cc0f21029f6d89efa043dcdbfa183cb59325b6506001c
|
|||||||
include/qpdf/auto_job_c_uo.hh ae21b69a1efa9333050f4833d465f6daff87e5b38e5106e49bbef5d4132e4ed1
|
include/qpdf/auto_job_c_uo.hh ae21b69a1efa9333050f4833d465f6daff87e5b38e5106e49bbef5d4132e4ed1
|
||||||
job.yml 4f89fc7b622df897d30d403d8035aa36fc7de8d8c43042c736e0300d904cb05c
|
job.yml 4f89fc7b622df897d30d403d8035aa36fc7de8d8c43042c736e0300d904cb05c
|
||||||
libqpdf/qpdf/auto_job_decl.hh 9c6f701c29f3f764d620186bed92685a2edf2e4d11e4f4532862c05470cfc4d2
|
libqpdf/qpdf/auto_job_decl.hh 9c6f701c29f3f764d620186bed92685a2edf2e4d11e4f4532862c05470cfc4d2
|
||||||
libqpdf/qpdf/auto_job_help.hh 788320d439519ecd284621531e96ee698965a9ad342fd423c5fb1de75d2a06b1
|
libqpdf/qpdf/auto_job_help.hh ea1fdca2aa405bdf193732c5a2789c602efe2add3aa6e2dceecfacee175ce65c
|
||||||
libqpdf/qpdf/auto_job_init.hh b4c2b3724fba61f1206fd3bae81951636852592f67a63ef9539839c2c5995065
|
libqpdf/qpdf/auto_job_init.hh b4c2b3724fba61f1206fd3bae81951636852592f67a63ef9539839c2c5995065
|
||||||
libqpdf/qpdf/auto_job_json_decl.hh 06caa46eaf71db8a50c046f91866baa8087745a9474319fb7c86d92634cc8297
|
libqpdf/qpdf/auto_job_json_decl.hh 06caa46eaf71db8a50c046f91866baa8087745a9474319fb7c86d92634cc8297
|
||||||
libqpdf/qpdf/auto_job_json_init.hh f5acb9aa103131cb68dec0e12c4d237a6459bdb49b24773c24f0c2724a462b8f
|
libqpdf/qpdf/auto_job_json_init.hh f5acb9aa103131cb68dec0e12c4d237a6459bdb49b24773c24f0c2724a462b8f
|
||||||
libqpdf/qpdf/auto_job_schema.hh b53c006fec2e75b1b73588d242d49a32f7d3db820b1541de106c5d4c27fbb4d9
|
libqpdf/qpdf/auto_job_schema.hh b53c006fec2e75b1b73588d242d49a32f7d3db820b1541de106c5d4c27fbb4d9
|
||||||
manual/_ext/qpdf.py 6add6321666031d55ed4aedf7c00e5662bba856dfcd66ccb526563bffefbb580
|
manual/_ext/qpdf.py 6add6321666031d55ed4aedf7c00e5662bba856dfcd66ccb526563bffefbb580
|
||||||
manual/cli.rst b524f96f2a6f338f3e4350703598c56ba22e8f12a8efb7a441648c6dbf0a455e
|
manual/cli.rst 28cc6b36b26377404022bab467e6a16085023fdfa5d9d419595ffcae6c69d531
|
||||||
|
@ -35,6 +35,9 @@ namespace
|
|||||||
std::shared_ptr<QPDFJob::EncConfig> c_enc;
|
std::shared_ptr<QPDFJob::EncConfig> c_enc;
|
||||||
std::vector<std::string> accumulated_args;
|
std::vector<std::string> accumulated_args;
|
||||||
std::shared_ptr<char> pages_password{nullptr};
|
std::shared_ptr<char> pages_password{nullptr};
|
||||||
|
std::string user_password;
|
||||||
|
std::string owner_password;
|
||||||
|
bool used_enc_password_args{false};
|
||||||
bool gave_input{false};
|
bool gave_input{false};
|
||||||
bool gave_output{false};
|
bool gave_output{false};
|
||||||
};
|
};
|
||||||
@ -161,40 +164,61 @@ void
|
|||||||
ArgParser::argEncrypt()
|
ArgParser::argEncrypt()
|
||||||
{
|
{
|
||||||
this->accumulated_args.clear();
|
this->accumulated_args.clear();
|
||||||
if (this->ap.isCompleting() && this->ap.argsLeft() == 0) {
|
|
||||||
this->ap.insertCompletion("user-password");
|
|
||||||
}
|
|
||||||
this->ap.selectOptionTable(O_ENCRYPTION);
|
this->ap.selectOptionTable(O_ENCRYPTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ArgParser::argEncPositional(std::string const& arg)
|
ArgParser::argEncPositional(std::string const& arg)
|
||||||
{
|
{
|
||||||
|
if (used_enc_password_args) {
|
||||||
|
usage("positional and dashed encryption arguments may not be mixed");
|
||||||
|
}
|
||||||
|
|
||||||
this->accumulated_args.push_back(arg);
|
this->accumulated_args.push_back(arg);
|
||||||
size_t n_args = this->accumulated_args.size();
|
if (this->accumulated_args.size() < 3) {
|
||||||
if (n_args < 3) {
|
|
||||||
if (this->ap.isCompleting() && (this->ap.argsLeft() == 0)) {
|
|
||||||
if (n_args == 1) {
|
|
||||||
this->ap.insertCompletion("owner-password");
|
|
||||||
} else if (n_args == 2) {
|
|
||||||
this->ap.insertCompletion("40");
|
|
||||||
this->ap.insertCompletion("128");
|
|
||||||
this->ap.insertCompletion("256");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::string user_password = this->accumulated_args.at(0);
|
user_password = this->accumulated_args.at(0);
|
||||||
std::string owner_password = this->accumulated_args.at(1);
|
owner_password = this->accumulated_args.at(1);
|
||||||
std::string len_str = this->accumulated_args.at(2);
|
auto len_str = this->accumulated_args.at(2);
|
||||||
|
this->accumulated_args.clear();
|
||||||
|
argEncBits(len_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ArgParser::argEncUserPassword(std::string const& arg)
|
||||||
|
{
|
||||||
|
if (!accumulated_args.empty()) {
|
||||||
|
usage("positional and dashed encryption arguments may not be mixed");
|
||||||
|
}
|
||||||
|
this->used_enc_password_args = true;
|
||||||
|
this->user_password = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ArgParser::argEncOwnerPassword(std::string const& arg)
|
||||||
|
{
|
||||||
|
if (!accumulated_args.empty()) {
|
||||||
|
usage("positional and dashed encryption arguments may not be mixed");
|
||||||
|
}
|
||||||
|
this->used_enc_password_args = true;
|
||||||
|
this->owner_password = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ArgParser::argEncBits(std::string const& arg)
|
||||||
|
{
|
||||||
|
if (!accumulated_args.empty()) {
|
||||||
|
usage("positional and dashed encryption arguments may not be mixed");
|
||||||
|
}
|
||||||
int keylen = 0;
|
int keylen = 0;
|
||||||
if (len_str == "40") {
|
if (arg == "40") {
|
||||||
keylen = 40;
|
keylen = 40;
|
||||||
this->ap.selectOptionTable(O_40_BIT_ENCRYPTION);
|
this->ap.selectOptionTable(O_40_BIT_ENCRYPTION);
|
||||||
} else if (len_str == "128") {
|
} else if (arg == "128") {
|
||||||
keylen = 128;
|
keylen = 128;
|
||||||
this->ap.selectOptionTable(O_128_BIT_ENCRYPTION);
|
this->ap.selectOptionTable(O_128_BIT_ENCRYPTION);
|
||||||
} else if (len_str == "256") {
|
} else if (arg == "256") {
|
||||||
keylen = 256;
|
keylen = 256;
|
||||||
this->ap.selectOptionTable(O_256_BIT_ENCRYPTION);
|
this->ap.selectOptionTable(O_256_BIT_ENCRYPTION);
|
||||||
} else {
|
} else {
|
||||||
@ -203,24 +227,6 @@ ArgParser::argEncPositional(std::string const& arg)
|
|||||||
this->c_enc = c_main->encrypt(keylen, user_password, owner_password);
|
this->c_enc = c_main->encrypt(keylen, user_password, owner_password);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ArgParser::argEncUserPassword(std::string const& arg)
|
|
||||||
{
|
|
||||||
// QXXXQ
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ArgParser::argEncOwnerPassword(std::string const& arg)
|
|
||||||
{
|
|
||||||
// QXXXQ
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ArgParser::argEncBits(std::string const& arg)
|
|
||||||
{
|
|
||||||
// QXXXQ
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ArgParser::argPages()
|
ArgParser::argPages()
|
||||||
{
|
{
|
||||||
|
@ -148,29 +148,14 @@ the structure without changing the content.
|
|||||||
)");
|
)");
|
||||||
ap.addOptionHelp("--linearize", "transformation", "linearize (web-optimize) output", R"(Create linearized (web-optimized) output files.
|
ap.addOptionHelp("--linearize", "transformation", "linearize (web-optimize) output", R"(Create linearized (web-optimized) output files.
|
||||||
)");
|
)");
|
||||||
ap.addOptionHelp("--encrypt", "transformation", "start encryption options", R"(--encrypt user-password owner-password key-length [options] --
|
ap.addOptionHelp("--encrypt", "transformation", "start encryption options", R"(--encrypt [options] --
|
||||||
|
|
||||||
Run qpdf --help=encryption for details.
|
Run qpdf --help=encryption for details.
|
||||||
)");
|
)");
|
||||||
ap.addOptionHelp("--user-password", "transformation", "specify user password", R"(--user-password=user-password
|
|
||||||
|
|
||||||
Set the user password.
|
|
||||||
)");
|
|
||||||
ap.addOptionHelp("--owner-password", "transformation", "specify owner password", R"(--owner-password=owner-password
|
|
||||||
|
|
||||||
Set the owner password.
|
|
||||||
)");
|
|
||||||
ap.addOptionHelp("--bits", "transformation", "specify encryption bit depth", R"(--bits={48|128|256}
|
|
||||||
|
|
||||||
Set the encrypt bit depth. Use 256.
|
|
||||||
)");
|
|
||||||
ap.addOptionHelp("--decrypt", "transformation", "remove encryption from input file", R"(Create an unencrypted output file even if the input file was
|
ap.addOptionHelp("--decrypt", "transformation", "remove encryption from input file", R"(Create an unencrypted output file even if the input file was
|
||||||
encrypted. Normally qpdf preserves whatever encryption was
|
encrypted. Normally qpdf preserves whatever encryption was
|
||||||
present on the input file. This option overrides that behavior.
|
present on the input file. This option overrides that behavior.
|
||||||
)");
|
)");
|
||||||
}
|
|
||||||
static void add_help_3(QPDFArgParser& ap)
|
|
||||||
{
|
|
||||||
ap.addOptionHelp("--remove-restrictions", "transformation", "remove security restrictions from input file", R"(Remove restrictions associated with digitally signed PDF files.
|
ap.addOptionHelp("--remove-restrictions", "transformation", "remove security restrictions from input file", R"(Remove restrictions associated with digitally signed PDF files.
|
||||||
This may be combined with --decrypt to allow free editing of
|
This may be combined with --decrypt to allow free editing of
|
||||||
previously signed/encrypted files. This option invalidates the
|
previously signed/encrypted files. This option invalidates the
|
||||||
@ -187,6 +172,9 @@ ap.addOptionHelp("--encryption-file-password", "transformation", "supply passwor
|
|||||||
If the file named in --copy-encryption requires a password, use
|
If the file named in --copy-encryption requires a password, use
|
||||||
this option to supply the password.
|
this option to supply the password.
|
||||||
)");
|
)");
|
||||||
|
}
|
||||||
|
static void add_help_3(QPDFArgParser& ap)
|
||||||
|
{
|
||||||
ap.addOptionHelp("--qdf", "transformation", "enable viewing PDF code in a text editor", R"(Create a PDF file suitable for viewing in a text editor and even
|
ap.addOptionHelp("--qdf", "transformation", "enable viewing PDF code in a text editor", R"(Create a PDF file suitable for viewing in a text editor and even
|
||||||
editing. This is for editing the PDF code, not the page contents.
|
editing. This is for editing the PDF code, not the page contents.
|
||||||
All streams that can be uncompressed are uncompressed, and
|
All streams that can be uncompressed are uncompressed, and
|
||||||
@ -282,9 +270,6 @@ ap.addOptionHelp("--ii-min-bytes", "transformation", "set minimum size for --ext
|
|||||||
Don't externalize inline images smaller than this size. The
|
Don't externalize inline images smaller than this size. The
|
||||||
default is 1,024. Use 0 for no minimum.
|
default is 1,024. Use 0 for no minimum.
|
||||||
)");
|
)");
|
||||||
}
|
|
||||||
static void add_help_4(QPDFArgParser& ap)
|
|
||||||
{
|
|
||||||
ap.addOptionHelp("--min-version", "transformation", "set minimum PDF version", R"(--min-version=version
|
ap.addOptionHelp("--min-version", "transformation", "set minimum PDF version", R"(--min-version=version
|
||||||
|
|
||||||
Force the PDF version of the output to be at least the specified
|
Force the PDF version of the output to be at least the specified
|
||||||
@ -312,6 +297,9 @@ resulting set of pages, where :odd starts with the first page and
|
|||||||
:even starts with the second page. These are odd and even pages
|
:even starts with the second page. These are odd and even pages
|
||||||
from the resulting set, not based on the original page numbers.
|
from the resulting set, not based on the original page numbers.
|
||||||
)");
|
)");
|
||||||
|
}
|
||||||
|
static void add_help_4(QPDFArgParser& ap)
|
||||||
|
{
|
||||||
ap.addHelpTopic("modification", "change parts of the PDF", R"(Modification options make systematic changes to certain parts of
|
ap.addHelpTopic("modification", "change parts of the PDF", R"(Modification options make systematic changes to certain parts of
|
||||||
the PDF, causing the PDF to render differently from the original.
|
the PDF, causing the PDF to render differently from the original.
|
||||||
)");
|
)");
|
||||||
@ -404,18 +392,33 @@ ap.addOptionHelp("--keep-inline-images", "modification", "exclude inline images
|
|||||||
)");
|
)");
|
||||||
ap.addOptionHelp("--remove-page-labels", "modification", "remove explicit page numbers", R"(Exclude page labels (explicit page numbers) from the output file.
|
ap.addOptionHelp("--remove-page-labels", "modification", "remove explicit page numbers", R"(Exclude page labels (explicit page numbers) from the output file.
|
||||||
)");
|
)");
|
||||||
}
|
|
||||||
static void add_help_5(QPDFArgParser& ap)
|
|
||||||
{
|
|
||||||
ap.addHelpTopic("encryption", "create encrypted files", R"(Create encrypted files. Usage:
|
ap.addHelpTopic("encryption", "create encrypted files", R"(Create encrypted files. Usage:
|
||||||
|
|
||||||
|
--encrypt \
|
||||||
|
[--user-password=user-password] \
|
||||||
|
[--owner-password=owner-password] \
|
||||||
|
--bits=key-length [options] --
|
||||||
|
|
||||||
|
OR
|
||||||
|
|
||||||
--encrypt user-password owner-password key-length [options] --
|
--encrypt user-password owner-password key-length [options] --
|
||||||
|
|
||||||
Either or both of user-password and owner-password may be empty
|
The first form, with flags for the passwords and bit length, was
|
||||||
strings, though setting either to the empty string enables the file
|
introduced in qpdf 11.7.0. Only the --bits option is is mandatory.
|
||||||
to be opened and decrypted without a password. key-length may be
|
This form allows you to use any text as the password. If passwords
|
||||||
40, 128, or 256. Encryption options are terminated by "--" by
|
are specified, they must be given before the --bits option.
|
||||||
itself.
|
|
||||||
|
The second form has been in qpdf since the beginning and wil
|
||||||
|
continue to be supported. Either or both of user-password and
|
||||||
|
owner-password may be empty strings.
|
||||||
|
|
||||||
|
The key-length parameter must be either 40, 128, or 256. The user
|
||||||
|
and/or owner password may be omitted. Omitting either pasword
|
||||||
|
enables the PDF file to be opened without a password. Specifying
|
||||||
|
the same value for the user and owner password and specifying an
|
||||||
|
empty owner password are both considered insecure.
|
||||||
|
|
||||||
|
Encryption options are terminated by "--" by itself.
|
||||||
|
|
||||||
40-bit encryption is insecure, as is 128-bit encryption without
|
40-bit encryption is insecure, as is 128-bit encryption without
|
||||||
AES. Use 256-bit encryption unless you have a specific reason to
|
AES. Use 256-bit encryption unless you have a specific reason to
|
||||||
@ -468,6 +471,22 @@ Values for modify-opt:
|
|||||||
annotate form + commenting and modifying forms
|
annotate form + commenting and modifying forms
|
||||||
all allow full document modification
|
all allow full document modification
|
||||||
)");
|
)");
|
||||||
|
ap.addOptionHelp("--user-password", "encryption", "specify user password", R"(--user-password=user-password
|
||||||
|
|
||||||
|
Set the user password of the encrypted file.
|
||||||
|
)");
|
||||||
|
ap.addOptionHelp("--owner-password", "encryption", "specify owner password", R"(--owner-password=owner-password
|
||||||
|
|
||||||
|
Set the owner password of the encrypted file.
|
||||||
|
)");
|
||||||
|
}
|
||||||
|
static void add_help_5(QPDFArgParser& ap)
|
||||||
|
{
|
||||||
|
ap.addOptionHelp("--bits", "encryption", "specify encryption key length", R"(--bits={48|128|256}
|
||||||
|
|
||||||
|
Specify the encryption key length. For best security, always use
|
||||||
|
a key length of 256.
|
||||||
|
)");
|
||||||
ap.addOptionHelp("--accessibility", "encryption", "restrict document accessibility", R"(--accessibility=[y|n]
|
ap.addOptionHelp("--accessibility", "encryption", "restrict document accessibility", R"(--accessibility=[y|n]
|
||||||
|
|
||||||
This option is ignored except with very old encryption formats.
|
This option is ignored except with very old encryption formats.
|
||||||
|
119
manual/cli.rst
119
manual/cli.rst
@ -714,7 +714,7 @@ Related Options
|
|||||||
important cross-reference information typically appears at the end
|
important cross-reference information typically appears at the end
|
||||||
of the file.
|
of the file.
|
||||||
|
|
||||||
.. qpdf:option:: --encrypt user-password owner-password key-length [options] --
|
.. qpdf:option:: --encrypt [options] --
|
||||||
|
|
||||||
.. help: start encryption options
|
.. help: start encryption options
|
||||||
|
|
||||||
@ -723,32 +723,6 @@ Related Options
|
|||||||
This flag starts encryption options, used to create encrypted
|
This flag starts encryption options, used to create encrypted
|
||||||
files. Please see :ref:`encryption-options` for details.
|
files. Please see :ref:`encryption-options` for details.
|
||||||
|
|
||||||
.. qpdf:option:: --user-password=user-password
|
|
||||||
|
|
||||||
.. help: specify user password
|
|
||||||
|
|
||||||
Set the user password.
|
|
||||||
|
|
||||||
Set the user password for the encrypted file.
|
|
||||||
|
|
||||||
.. qpdf:option:: --owner-password=owner-password
|
|
||||||
|
|
||||||
.. help: specify owner password
|
|
||||||
|
|
||||||
Set the owner password.
|
|
||||||
|
|
||||||
Set the owner password for the encrypted file.
|
|
||||||
|
|
||||||
.. qpdf:option:: --bits={48|128|256}
|
|
||||||
|
|
||||||
.. help: specify encryption bit depth
|
|
||||||
|
|
||||||
Set the encrypt bit depth. Use 256.
|
|
||||||
|
|
||||||
Set the bit depth for encrypted files. You should always use
|
|
||||||
``--bits=256`` unless you have a strong reason to create a file
|
|
||||||
with weaker encryption.
|
|
||||||
|
|
||||||
.. qpdf:option:: --decrypt
|
.. qpdf:option:: --decrypt
|
||||||
|
|
||||||
.. help: remove encryption from input file
|
.. help: remove encryption from input file
|
||||||
@ -1758,13 +1732,31 @@ Encryption
|
|||||||
|
|
||||||
Create encrypted files. Usage:
|
Create encrypted files. Usage:
|
||||||
|
|
||||||
|
--encrypt \
|
||||||
|
[--user-password=user-password] \
|
||||||
|
[--owner-password=owner-password] \
|
||||||
|
--bits=key-length [options] --
|
||||||
|
|
||||||
|
OR
|
||||||
|
|
||||||
--encrypt user-password owner-password key-length [options] --
|
--encrypt user-password owner-password key-length [options] --
|
||||||
|
|
||||||
Either or both of user-password and owner-password may be empty
|
The first form, with flags for the passwords and bit length, was
|
||||||
strings, though setting either to the empty string enables the file
|
introduced in qpdf 11.7.0. Only the --bits option is is mandatory.
|
||||||
to be opened and decrypted without a password. key-length may be
|
This form allows you to use any text as the password. If passwords
|
||||||
40, 128, or 256. Encryption options are terminated by "--" by
|
are specified, they must be given before the --bits option.
|
||||||
itself.
|
|
||||||
|
The second form has been in qpdf since the beginning and wil
|
||||||
|
continue to be supported. Either or both of user-password and
|
||||||
|
owner-password may be empty strings.
|
||||||
|
|
||||||
|
The key-length parameter must be either 40, 128, or 256. The user
|
||||||
|
and/or owner password may be omitted. Omitting either pasword
|
||||||
|
enables the PDF file to be opened without a password. Specifying
|
||||||
|
the same value for the user and owner password and specifying an
|
||||||
|
empty owner password are both considered insecure.
|
||||||
|
|
||||||
|
Encryption options are terminated by "--" by itself.
|
||||||
|
|
||||||
40-bit encryption is insecure, as is 128-bit encryption without
|
40-bit encryption is insecure, as is 128-bit encryption without
|
||||||
AES. Use 256-bit encryption unless you have a specific reason to
|
AES. Use 256-bit encryption unless you have a specific reason to
|
||||||
@ -1823,17 +1815,38 @@ and :qpdf:ref:`--copy-encryption`. For a more in-depth technical
|
|||||||
discussion of how PDF encryption works internally, see
|
discussion of how PDF encryption works internally, see
|
||||||
:ref:`pdf-encryption`.
|
:ref:`pdf-encryption`.
|
||||||
|
|
||||||
To create an encrypted file, use
|
To create an encrypted file, use one of
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
--encrypt \
|
||||||
|
[--user-password=user-password] \
|
||||||
|
[--owner-password=owner-password] \
|
||||||
|
--bits=key-length [options] --
|
||||||
|
|
||||||
|
OR
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
--encrypt user-password owner-password key-length [options] --
|
--encrypt user-password owner-password key-length [options] --
|
||||||
|
|
||||||
Either or both of :samp:`{user-password}` and :samp:`{owner-password}`
|
The first form, with flags for the passwords and bit length, was
|
||||||
may be empty strings, though setting either to the empty string
|
introduced in qpdf 11.7.0. Only the :qpdf:ref:`--bits` option is is
|
||||||
enables the file to be opened and decrypted without a password..
|
mandatory. This form allows you to use any text as the password. If
|
||||||
:samp:`{key-length}` may be ``40``, ``128``, or ``256``. Encryption
|
passwords are specified, they must be given before the
|
||||||
options are terminated by ``--`` by itself.
|
:qpdf:ref:`--bits` option.
|
||||||
|
|
||||||
|
The second form has been in qpdf since the beginning and wil
|
||||||
|
continue to be supported. Either or both of user-password and
|
||||||
|
owner-password may be empty strings.
|
||||||
|
|
||||||
|
The ``key-length`` parameter must be either ``40``, ``128``, or
|
||||||
|
``256``. The user and/or owner password may be omitted. Omitting
|
||||||
|
either pasword enables the PDF file to be opened without a password.
|
||||||
|
Specifying the same value for the user and owner password and
|
||||||
|
specifying an empty owner password are both considered insecure.
|
||||||
|
|
||||||
|
Encryption options are terminated by ``--`` by itself.
|
||||||
|
|
||||||
40-bit encryption is insecure, as is 128-bit encryption without AES.
|
40-bit encryption is insecure, as is 128-bit encryption without AES.
|
||||||
Use 256-bit encryption unless you have a specific reason to use an
|
Use 256-bit encryption unless you have a specific reason to use an
|
||||||
@ -1971,6 +1984,36 @@ help for each option.
|
|||||||
Related Options
|
Related Options
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. qpdf:option:: --user-password=user-password
|
||||||
|
|
||||||
|
.. help: specify user password
|
||||||
|
|
||||||
|
Set the user password of the encrypted file.
|
||||||
|
|
||||||
|
Set the user passwrod of the encrypted file. Conforming readers
|
||||||
|
apply security restrictions to files opened with the user password.
|
||||||
|
|
||||||
|
.. qpdf:option:: --owner-password=owner-password
|
||||||
|
|
||||||
|
.. help: specify owner password
|
||||||
|
|
||||||
|
Set the owner password of the encrypted file.
|
||||||
|
|
||||||
|
Set the owner passwrod of the encrypted file. Conforming readers
|
||||||
|
apply allow security restrictions to be changed or overridden when
|
||||||
|
files are opened with the owner password.
|
||||||
|
|
||||||
|
.. qpdf:option:: --bits={48|128|256}
|
||||||
|
|
||||||
|
.. help: specify encryption key length
|
||||||
|
|
||||||
|
Specify the encryption key length. For best security, always use
|
||||||
|
a key length of 256.
|
||||||
|
|
||||||
|
Set the key length for encrypted files. You should always use
|
||||||
|
``--bits=256`` unless you have a strong reason to create a file
|
||||||
|
with weaker encryption.
|
||||||
|
|
||||||
.. qpdf:option:: --accessibility=[y|n]
|
.. qpdf:option:: --accessibility=[y|n]
|
||||||
|
|
||||||
.. help: restrict document accessibility
|
.. help: restrict document accessibility
|
||||||
|
@ -61,6 +61,16 @@ Planned changes for future 12.x (subject to change):
|
|||||||
Previously, any value other than ``/Yes`` or ``/Off`` was
|
Previously, any value other than ``/Yes`` or ``/Off`` was
|
||||||
rejected.
|
rejected.
|
||||||
|
|
||||||
|
- CLI Enhancements:
|
||||||
|
|
||||||
|
- Allow the syntax ``--encrypt --user-password=user-password
|
||||||
|
--owner-password=owner-password --bits={40,128,256}`` when
|
||||||
|
encrypting PDF files. This is an alternative to the syntax
|
||||||
|
``--encrypt user-password owner-password {40,128,256}``, which
|
||||||
|
will continue to be supported. The new syntax works better with
|
||||||
|
shell completion and allows creation of passwords that start
|
||||||
|
with ``-``.
|
||||||
|
|
||||||
- Build Enhancements:
|
- Build Enhancements:
|
||||||
|
|
||||||
- The qpdf test suite now passes when qpdf is linked with an
|
- The qpdf test suite now passes when qpdf is linked with an
|
||||||
|
@ -15,7 +15,7 @@ cleanup();
|
|||||||
|
|
||||||
my $td = new TestDriver('arg-parsing');
|
my $td = new TestDriver('arg-parsing');
|
||||||
|
|
||||||
my $n_tests = 17;
|
my $n_tests = 21;
|
||||||
|
|
||||||
$td->runtest("required argument",
|
$td->runtest("required argument",
|
||||||
{$td->COMMAND => "qpdf --password minimal.pdf"},
|
{$td->COMMAND => "qpdf --password minimal.pdf"},
|
||||||
@ -108,5 +108,21 @@ $td->runtest("empty and replace-input",
|
|||||||
$td->EXIT_STATUS => 2},
|
$td->EXIT_STATUS => 2},
|
||||||
$td->NORMALIZE_NEWLINES);
|
$td->NORMALIZE_NEWLINES);
|
||||||
|
|
||||||
|
# Disallow mixing positional and flag-style encryption arguments.
|
||||||
|
my @bad_enc = (
|
||||||
|
"u --owner-password=x",
|
||||||
|
"u o --bits=128",
|
||||||
|
"--user-password=u o",
|
||||||
|
"--user-password=u --owner-password=o 256",
|
||||||
|
);
|
||||||
|
foreach my $arg (@bad_enc)
|
||||||
|
{
|
||||||
|
$td->runtest("mixed encryption args ($arg)",
|
||||||
|
{$td->COMMAND => "qpdf --encrypt $arg"},
|
||||||
|
{$td->REGEXP => ".*positional and dashed encryption arguments may not be mixed",
|
||||||
|
$td->EXIT_STATUS => 2},
|
||||||
|
$td->NORMALIZE_NEWLINES);
|
||||||
|
}
|
||||||
|
|
||||||
cleanup();
|
cleanup();
|
||||||
$td->report($n_tests);
|
$td->report($n_tests);
|
||||||
|
@ -29,14 +29,7 @@ my @completion_tests = (
|
|||||||
['qpdf ', undef, 'top'],
|
['qpdf ', undef, 'top'],
|
||||||
['qpdf -', undef, 'top-arg'],
|
['qpdf -', undef, 'top-arg'],
|
||||||
['qpdf --enc', undef, 'enc'],
|
['qpdf --enc', undef, 'enc'],
|
||||||
['qpdf --encrypt ', undef, 'encrypt'],
|
['qpdf --encrypt -', undef, 'encrypt'],
|
||||||
['qpdf --encrypt u ', undef, 'encrypt-u'],
|
|
||||||
['qpdf --encrypt u o ', undef, 'encrypt-u-o'],
|
|
||||||
['qpdf @encrypt-u o ', undef, 'encrypt-u-o'],
|
|
||||||
['qpdf --encrypt u o 40 --', undef, 'encrypt-40'],
|
|
||||||
['qpdf --encrypt u o 128 --', undef, 'encrypt-128'],
|
|
||||||
['qpdf --encrypt u o 256 --', undef, 'encrypt-256'],
|
|
||||||
['qpdf --encrypt u o bad --', undef, 'encrypt-bad'],
|
|
||||||
['qpdf --split-pag', undef, 'split'],
|
['qpdf --split-pag', undef, 'split'],
|
||||||
['qpdf --decode-l', undef, 'decode-l'],
|
['qpdf --decode-l', undef, 'decode-l'],
|
||||||
['qpdf --decode-lzzz', 15, 'decode-l'],
|
['qpdf --decode-lzzz', 15, 'decode-l'],
|
||||||
@ -44,11 +37,11 @@ my @completion_tests = (
|
|||||||
['qpdf --decode-level=g', undef, 'decode-level-g'],
|
['qpdf --decode-level=g', undef, 'decode-level-g'],
|
||||||
['qpdf --check -', undef, 'later-arg'],
|
['qpdf --check -', undef, 'later-arg'],
|
||||||
['qpdf infile outfile oops --ch', undef, 'usage-empty'],
|
['qpdf infile outfile oops --ch', undef, 'usage-empty'],
|
||||||
['qpdf --encrypt \'user " password\' ', undef, 'quoting'],
|
['qpdf \'input " file\' --q', undef, 'quoting'],
|
||||||
['qpdf --encrypt \'user password\' ', undef, 'quoting'],
|
['qpdf \'input file\' --q', undef, 'quoting'],
|
||||||
['qpdf --encrypt "user password" ', undef, 'quoting'],
|
['qpdf "input file" --q', undef, 'quoting'],
|
||||||
['qpdf --encrypt "user pass\'word" ', undef, 'quoting'],
|
['qpdf "input fi\'le" --q', undef, 'quoting'],
|
||||||
['qpdf --encrypt user\ password ', undef, 'quoting'],
|
['qpdf input\ file --q', undef, 'quoting'],
|
||||||
);
|
);
|
||||||
my $n_tests = 2 * scalar(@completion_tests);
|
my $n_tests = 2 * scalar(@completion_tests);
|
||||||
my $completion_filter =
|
my $completion_filter =
|
||||||
|
6
qpdf/qtest/qpdf/completion-encrypt-zsh.out
Normal file
6
qpdf/qtest/qpdf/completion-encrypt-zsh.out
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
--bits=128
|
||||||
|
--bits=256
|
||||||
|
--bits=40
|
||||||
|
--owner-password=
|
||||||
|
--user-password=
|
||||||
|
!--print
|
@ -1,2 +1,7 @@
|
|||||||
user-password
|
--bits=
|
||||||
|
--owner-password=
|
||||||
|
--user-password=
|
||||||
|
!--bits=128
|
||||||
|
!--bits=256
|
||||||
|
!--bits=40
|
||||||
!--print
|
!--print
|
||||||
|
@ -1 +1 @@
|
|||||||
owner-password
|
--qdf
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
--encrypt
|
--encrypt
|
||||||
u
|
--bits=2
|
||||||
|
Loading…
x
Reference in New Issue
Block a user