Commit 127a957aee7bf7ae242a606d035e9e3d9b300307
1 parent
fb4c6c15
Allow runtime inspection/override of crypto provider
Showing
3 changed files
with
62 additions
and
2 deletions
include/qpdf/QPDFCryptoProvider.hh
| ... | ... | @@ -26,6 +26,7 @@ |
| 26 | 26 | #include <qpdf/QPDFCryptoImpl.hh> |
| 27 | 27 | #include <string> |
| 28 | 28 | #include <map> |
| 29 | +#include <set> | |
| 29 | 30 | #include <memory> |
| 30 | 31 | #include <functional> |
| 31 | 32 | |
| ... | ... | @@ -64,6 +65,14 @@ class QPDFCryptoProvider |
| 64 | 65 | QPDF_DLL |
| 65 | 66 | static void setDefaultProvider(std::string const& name); |
| 66 | 67 | |
| 68 | + // Get the names of registered implementations | |
| 69 | + QPDF_DLL | |
| 70 | + static std::set<std::string> getRegisteredImpls(); | |
| 71 | + | |
| 72 | + // Get the name of the default crypto provider | |
| 73 | + QPDF_DLL | |
| 74 | + static std::string getDefaultProvider(); | |
| 75 | + | |
| 67 | 76 | private: |
| 68 | 77 | QPDFCryptoProvider(); |
| 69 | 78 | ~QPDFCryptoProvider() = default; | ... | ... |
libqpdf/QPDFCryptoProvider.cc
| 1 | 1 | #include <qpdf/QPDFCryptoProvider.hh> |
| 2 | 2 | #include <qpdf/qpdf-config.h> |
| 3 | +#include <qpdf/QUtil.hh> | |
| 3 | 4 | #include <stdexcept> |
| 4 | 5 | |
| 5 | 6 | #ifdef USE_CRYPTO_NATIVE |
| ... | ... | @@ -49,7 +50,12 @@ QPDFCryptoProvider::QPDFCryptoProvider() : |
| 49 | 50 | #ifdef USE_CRYPTO_GNUTLS |
| 50 | 51 | registerImpl_internal<QPDFCrypto_gnutls>("gnutls"); |
| 51 | 52 | #endif |
| 52 | - setDefaultProvider_internal(DEFAULT_CRYPTO); | |
| 53 | + std::string default_crypto; | |
| 54 | + if (! QUtil::get_env("QPDF_CRYPTO_PROVIDER", &default_crypto)) | |
| 55 | + { | |
| 56 | + default_crypto = DEFAULT_CRYPTO; | |
| 57 | + } | |
| 58 | + setDefaultProvider_internal(default_crypto); | |
| 53 | 59 | } |
| 54 | 60 | |
| 55 | 61 | QPDFCryptoProvider& |
| ... | ... | @@ -83,5 +89,31 @@ QPDFCryptoProvider::registerImpl_internal(std::string const& name) |
| 83 | 89 | void |
| 84 | 90 | QPDFCryptoProvider::setDefaultProvider_internal(std::string const& name) |
| 85 | 91 | { |
| 92 | + if (! this->m->providers.count(name)) | |
| 93 | + { | |
| 94 | + throw std::logic_error( | |
| 95 | + "QPDFCryptoProvider: request to set default" | |
| 96 | + " provider to unknown implementation \"" + | |
| 97 | + name + "\""); | |
| 98 | + } | |
| 86 | 99 | this->m->default_provider = name; |
| 87 | 100 | } |
| 101 | + | |
| 102 | +std::set<std::string> | |
| 103 | +QPDFCryptoProvider::getRegisteredImpls() | |
| 104 | +{ | |
| 105 | + std::set<std::string> result; | |
| 106 | + QPDFCryptoProvider& p = getInstance(); | |
| 107 | + for (auto iter = p.m->providers.begin(); iter != p.m->providers.end(); | |
| 108 | + ++iter) | |
| 109 | + { | |
| 110 | + result.insert((*iter).first); | |
| 111 | + } | |
| 112 | + return result; | |
| 113 | +} | |
| 114 | + | |
| 115 | +std::string | |
| 116 | +QPDFCryptoProvider::getDefaultProvider() | |
| 117 | +{ | |
| 118 | + return getInstance().m->default_provider; | |
| 119 | +} | ... | ... |
qpdf/qpdf.cc
| ... | ... | @@ -24,6 +24,7 @@ |
| 24 | 24 | #include <qpdf/QPDFAcroFormDocumentHelper.hh> |
| 25 | 25 | #include <qpdf/QPDFExc.hh> |
| 26 | 26 | #include <qpdf/QPDFSystemError.hh> |
| 27 | +#include <qpdf/QPDFCryptoProvider.hh> | |
| 27 | 28 | |
| 28 | 29 | #include <qpdf/QPDFWriter.hh> |
| 29 | 30 | #include <qpdf/QIntC.hh> |
| ... | ... | @@ -624,6 +625,7 @@ class ArgParser |
| 624 | 625 | void argCompletionBash(); |
| 625 | 626 | void argCompletionZsh(); |
| 626 | 627 | void argJsonHelp(); |
| 628 | + void argShowCrypto(); | |
| 627 | 629 | void argPositional(char* arg); |
| 628 | 630 | void argPassword(char* parameter); |
| 629 | 631 | void argEmpty(); |
| ... | ... | @@ -829,6 +831,7 @@ ArgParser::initOptionTable() |
| 829 | 831 | (*t)["completion-bash"] = oe_bare(&ArgParser::argCompletionBash); |
| 830 | 832 | (*t)["completion-zsh"] = oe_bare(&ArgParser::argCompletionZsh); |
| 831 | 833 | (*t)["json-help"] = oe_bare(&ArgParser::argJsonHelp); |
| 834 | + (*t)["show-crypto"] = oe_bare(&ArgParser::argShowCrypto); | |
| 832 | 835 | |
| 833 | 836 | t = &this->main_option_table; |
| 834 | 837 | char const* yn[] = {"y", "n", 0}; |
| ... | ... | @@ -1098,6 +1101,7 @@ ArgParser::argHelp() |
| 1098 | 1101 | << "--version show version of qpdf\n" |
| 1099 | 1102 | << "--copyright show qpdf's copyright and license information\n" |
| 1100 | 1103 | << "--help show command-line argument help\n" |
| 1104 | + << "--show-crypto show supported crypto providers; default is first\n" | |
| 1101 | 1105 | << "--completion-bash output a bash complete command you can eval\n" |
| 1102 | 1106 | << "--completion-zsh output a zsh complete command you can eval\n" |
| 1103 | 1107 | << "--password=password specify a password for accessing encrypted files\n" |
| ... | ... | @@ -1552,6 +1556,21 @@ ArgParser::argJsonHelp() |
| 1552 | 1556 | } |
| 1553 | 1557 | |
| 1554 | 1558 | void |
| 1559 | +ArgParser::argShowCrypto() | |
| 1560 | +{ | |
| 1561 | + auto crypto = QPDFCryptoProvider::getRegisteredImpls(); | |
| 1562 | + std::string default_crypto = QPDFCryptoProvider::getDefaultProvider(); | |
| 1563 | + std::cout << default_crypto << std::endl; | |
| 1564 | + for (auto iter = crypto.begin(); iter != crypto.end(); ++iter) | |
| 1565 | + { | |
| 1566 | + if (*iter != default_crypto) | |
| 1567 | + { | |
| 1568 | + std::cout << *iter << std::endl; | |
| 1569 | + } | |
| 1570 | + } | |
| 1571 | +} | |
| 1572 | + | |
| 1573 | +void | |
| 1555 | 1574 | ArgParser::argPassword(char* parameter) |
| 1556 | 1575 | { |
| 1557 | 1576 | o.password = parameter; |
| ... | ... | @@ -5228,10 +5247,10 @@ int realmain(int argc, char* argv[]) |
| 5228 | 5247 | // it holds dynamic memory used for argv. |
| 5229 | 5248 | Options o; |
| 5230 | 5249 | ArgParser ap(argc, argv, o); |
| 5231 | - ap.parseOptions(); | |
| 5232 | 5250 | |
| 5233 | 5251 | try |
| 5234 | 5252 | { |
| 5253 | + ap.parseOptions(); | |
| 5235 | 5254 | PointerHolder<QPDF> pdf_ph = |
| 5236 | 5255 | process_file(o.infilename, o.password, o); |
| 5237 | 5256 | QPDF& pdf = *pdf_ph; | ... | ... |