diff --git a/ChangeLog b/ChangeLog index 39d37b7c..292c294c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2008-11-08 Tatsuhiro Tsujikawa + + Added client certificate authentication for SSL/TLS. + Currently a private key must be decrypted for use with aria2. + If a user accidentally gives encrypted file to aria2 then following + thing happens: + If encrypted private key is given to aria2, it behaves differently + depending on the ssl library it uses. If aria2 built with openssl then + openssl prompts the user for password. If aria2 build with gnutls then + aria2 exists with error at start up. + * src/DownloadEngineFactory.cc + * src/MultiUrlRequestInfo.cc + * src/OptionHandlerFactory.cc + * src/option_processing.cc + * src/prefs.cc + * src/prefs.h + * src/usage_text.h + 2008-11-08 Tatsuhiro Tsujikawa Introduced TLSContext that holds TLS related data that can be shared diff --git a/src/DownloadEngineFactory.cc b/src/DownloadEngineFactory.cc index 181d02eb..da72e7df 100644 --- a/src/DownloadEngineFactory.cc +++ b/src/DownloadEngineFactory.cc @@ -54,10 +54,6 @@ #include "TimedHaltCommand.h" #include "DownloadResult.h" #include "ServerStatMan.h" -#ifdef ENABLE_SSL -# include "SocketCore.h" -# include "TLSContext.h" -#endif // ENABLE_SSL namespace aria2 { @@ -86,11 +82,6 @@ DownloadEngineFactory::newDownloadEngine(Option* op, DownloadEngineHandle e(new DownloadEngine()); e->option = op; -#ifdef ENABLE_SSL - SharedHandle tlsContext(new TLSContext()); - SocketCore::setTLSContext(tlsContext); -#endif - RequestGroupManHandle requestGroupMan(new RequestGroupMan(workingSet, MAX_CONCURRENT_DOWNLOADS, op)); diff --git a/src/MultiUrlRequestInfo.cc b/src/MultiUrlRequestInfo.cc index 369e9122..0524a965 100644 --- a/src/MultiUrlRequestInfo.cc +++ b/src/MultiUrlRequestInfo.cc @@ -54,6 +54,10 @@ #include "File.h" #include "Netrc.h" #include "AuthConfigFactory.h" +#ifdef ENABLE_SSL +# include "SocketCore.h" +# include "TLSContext.h" +#endif // ENABLE_SSL namespace aria2 { @@ -132,6 +136,16 @@ int MultiUrlRequestInfo::execute() } e->setAuthConfigFactory(authConfigFactory); +#ifdef ENABLE_SSL + SharedHandle tlsContext(new TLSContext()); + if(_option->defined(PREF_CERTIFICATE) && + _option->defined(PREF_PRIVATE_KEY)) { + tlsContext->addClientKeyFile(_option->get(PREF_CERTIFICATE), + _option->get(PREF_PRIVATE_KEY)); + } + SocketCore::setTLSContext(tlsContext); +#endif + std::string serverStatIf = _option->get(PREF_SERVER_STAT_IF); if(!serverStatIf.empty()) { e->_requestGroupMan->loadServerStat(serverStatIf); diff --git a/src/OptionHandlerFactory.cc b/src/OptionHandlerFactory.cc index aaabda1d..2f17df92 100644 --- a/src/OptionHandlerFactory.cc +++ b/src/OptionHandlerFactory.cc @@ -429,6 +429,13 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers() handlers.push_back(op); } // HTTP Specific Options + { + SharedHandle op(new DefaultOptionHandler + (PREF_CERTIFICATE, + TEXT_CERTIFICATE)); + op->addTag(TAG_HTTP); + handlers.push_back(op); + } { SharedHandle op(new BooleanOptionHandler (PREF_ENABLE_HTTP_KEEP_ALIVE, @@ -498,6 +505,13 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers() true)); handlers.push_back(op); } + { + SharedHandle op(new DefaultOptionHandler + (PREF_PRIVATE_KEY, + TEXT_PRIVATE_KEY)); + op->addTag(TAG_HTTP); + handlers.push_back(op); + } { SharedHandle op(new DefaultOptionHandler (PREF_REFERER, diff --git a/src/option_processing.cc b/src/option_processing.cc index ef323151..9e7bd607 100644 --- a/src/option_processing.cc +++ b/src/option_processing.cc @@ -182,6 +182,8 @@ Option* option_processing(int argc, char* const argv[]) { PREF_FTP_PROXY.c_str(), required_argument, &lopt, 228 }, { PREF_ALL_PROXY.c_str(), required_argument, &lopt, 229 }, { PREF_PROXY_METHOD.c_str(), required_argument, &lopt, 230 }, + { PREF_CERTIFICATE.c_str(), required_argument, &lopt, 231 }, + { PREF_PRIVATE_KEY.c_str(), required_argument, &lopt, 232 }, #if defined ENABLE_BITTORRENT || defined ENABLE_METALINK { PREF_SHOW_FILES.c_str(), no_argument, NULL, 'S' }, { PREF_SELECT_FILE.c_str(), required_argument, &lopt, 21 }, @@ -450,6 +452,12 @@ Option* option_processing(int argc, char* const argv[]) case 230: cmdstream << PREF_PROXY_METHOD << "=" << optarg << "\n"; break; + case 231: + cmdstream << PREF_CERTIFICATE << "=" << optarg << "\n"; + break; + case 232: + cmdstream << PREF_PRIVATE_KEY << "=" << optarg << "\n"; + break; } break; } diff --git a/src/prefs.cc b/src/prefs.cc index 4a9b1290..dccc0db2 100644 --- a/src/prefs.cc +++ b/src/prefs.cc @@ -180,6 +180,10 @@ const std::string PREF_ENABLE_HTTP_PIPELINING("enable-http-pipelining"); const std::string PREF_MAX_HTTP_PIPELINING("max-http-pipelining"); // value: string const std::string PREF_HEADER("header"); +// value: string that your file system recognizes as a file name. +const std::string PREF_CERTIFICATE("certificate"); +// value: string that your file system recognizes as a file name. +const std::string PREF_PRIVATE_KEY("private-key"); /** * Proxy related preferences diff --git a/src/prefs.h b/src/prefs.h index ba115244..9d7c863c 100644 --- a/src/prefs.h +++ b/src/prefs.h @@ -86,7 +86,7 @@ extern const std::string PREF_STARTUP_IDLE_TIME; // value: prealloc | none extern const std::string PREF_FILE_ALLOCATION; extern const std::string V_PREALLOC; -#// value: 1*digit +// value: 1*digit extern const std::string PREF_NO_FILE_ALLOCATION_LIMIT; // value: true | false extern const std::string PREF_ALLOW_OVERWRITE; @@ -184,6 +184,10 @@ extern const std::string PREF_ENABLE_HTTP_PIPELINING; extern const std::string PREF_MAX_HTTP_PIPELINING; // value: string extern const std::string PREF_HEADER; +// value: string that your file system recognizes as a file name. +extern const std::string PREF_CERTIFICATE; +// value: string that your file system recognizes as a file name. +extern const std::string PREF_PRIVATE_KEY; /**; * Proxy related preferences diff --git a/src/usage_text.h b/src/usage_text.h index f5ecf09d..e40cec17 100644 --- a/src/usage_text.h +++ b/src/usage_text.h @@ -389,3 +389,12 @@ _(" --auto-save-interval=SEC Save a control file(*.aria2) every SEC seconds. " If 0 is given, a control file is not saved during\n"\ " download. aria2 saves a control file when it stops\n"\ " regardless of the value.") +#define TEXT_CERTIFICATE \ +_(" --certificate=FILE Use the client certificate in FILE.\n"\ + " The certificate must be in PEM format.\n"\ + " You may use --private-key option to specify the\n"\ + " private key.") +#define TEXT_PRIVATE_KEY \ +_(" --private-key=FILE Use the private key in FILE.\n"\ + " The private key must be decrypted and in PEM\n"\ + " format. See also --certificate option.")