mirror of https://github.com/aria2/aria2
AppleTLS: Support credentials via KeyChain fingerprints
parent
89cf6c0468
commit
82a861f8d8
|
@ -34,21 +34,111 @@
|
||||||
/* copyright --> */
|
/* copyright --> */
|
||||||
#include "AppleTLSContext.h"
|
#include "AppleTLSContext.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include "LogFactory.h"
|
#include "LogFactory.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
#include "MessageDigest.h"
|
||||||
#include "fmt.h"
|
#include "fmt.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
using namespace aria2;
|
||||||
|
|
||||||
|
#if defined(__MAC_10_6)
|
||||||
|
static const void *query_keys[] = {
|
||||||
|
kSecClass,
|
||||||
|
kSecReturnRef,
|
||||||
|
kSecMatchPolicy,
|
||||||
|
kSecMatchLimit
|
||||||
|
};
|
||||||
|
|
||||||
|
class cfrelease {
|
||||||
|
const void *ptr_;
|
||||||
|
public:
|
||||||
|
inline cfrelease(const void *ptr) : ptr_(ptr) {}
|
||||||
|
inline ~cfrelease() { if (ptr_) CFRelease(ptr_); }
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline bool isWhitespace(char c)
|
||||||
|
{
|
||||||
|
// Fingerprints are often separated by colons
|
||||||
|
return isspace(c) || c == ':';
|
||||||
|
}
|
||||||
|
static inline std::string stripWhitespace(std::string str)
|
||||||
|
{
|
||||||
|
str.erase(std::remove_if(str.begin(), str.end(), isWhitespace), str.end());
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct hash_validator {
|
||||||
|
const std::string& hash_;
|
||||||
|
hash_validator(const std::string& hash) : hash_(hash) {}
|
||||||
|
inline bool operator()(std::string type) const {
|
||||||
|
return MessageDigest::isValidHash(type, hash_);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hash_finder {
|
||||||
|
CFDataRef data_;
|
||||||
|
const std::string& hash_;
|
||||||
|
hash_finder(CFDataRef data, const std::string& hash)
|
||||||
|
: data_(data), hash_(hash)
|
||||||
|
{}
|
||||||
|
inline bool operator()(std::string type) const {
|
||||||
|
std::string hash = MessageDigest::create(type)->update(
|
||||||
|
CFDataGetBytePtr(data_), CFDataGetLength(data_)).digest();
|
||||||
|
hash = util::toHex(hash);
|
||||||
|
return hash == hash_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
std::string errToString(OSStatus err)
|
||||||
|
{
|
||||||
|
std::string rv = "Unkown error";
|
||||||
|
CFStringRef cerr = SecCopyErrorMessageString(err, 0);
|
||||||
|
if (cerr) {
|
||||||
|
size_t len = CFStringGetLength(cerr) * 4;
|
||||||
|
char *buf = new char[len];
|
||||||
|
if (CFStringGetCString(cerr, buf, len, kCFStringEncodingUTF8)) {
|
||||||
|
rv = buf;
|
||||||
|
}
|
||||||
|
delete [] buf;
|
||||||
|
CFRelease(cerr);
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // defined(__MAC_10_6)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
TLSContext* TLSContext::make(TLSSessionSide side) {
|
TLSContext* TLSContext::make(TLSSessionSide side)
|
||||||
|
{
|
||||||
return new AppleTLSContext(side);
|
return new AppleTLSContext(side);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppleTLSContext::~AppleTLSContext()
|
||||||
|
{
|
||||||
|
if (credentials_) {
|
||||||
|
CFRelease(credentials_);
|
||||||
|
credentials_ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool AppleTLSContext::addCredentialFile(const std::string& certfile,
|
bool AppleTLSContext::addCredentialFile(const std::string& certfile,
|
||||||
const std::string& keyfile)
|
const std::string& keyfile)
|
||||||
{
|
{
|
||||||
A2_LOG_WARN("TLS credential files are not supported. Use the KeyChain to manage your certificates.");
|
if (tryAsFingerprint(certfile)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
A2_LOG_WARN("TLS credential files are not supported. Use the KeyChain to manage your certificates and provide a fingerprint. See the manual.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,5 +148,98 @@ bool AppleTLSContext::addTrustedCACertFile(const std::string& certfile)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SecIdentityRef AppleTLSContext::getCredentials()
|
||||||
|
{
|
||||||
|
return credentials_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AppleTLSContext::tryAsFingerprint(const std::string& fingerprint)
|
||||||
|
{
|
||||||
|
std::string fp = stripWhitespace(fingerprint);
|
||||||
|
// Verify this is a valid hex representation and normalize.
|
||||||
|
fp = util::toHex(util::fromHex(fp.begin(), fp.end()));
|
||||||
|
|
||||||
|
// Verify this can represent a hash
|
||||||
|
std::vector<std::string> ht = MessageDigest::getSupportedHashTypes();
|
||||||
|
if (std::find_if(ht.begin(), ht.end(), hash_validator(fp)) == ht.end()) {
|
||||||
|
A2_LOG_INFO(fmt("%s is not a fingerprint, invalid hash representation", fingerprint.c_str()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__MAC_10_6)
|
||||||
|
A2_LOG_DEBUG(fmt("Looking for cert with fingerprint %s", fp.c_str()));
|
||||||
|
|
||||||
|
// Build and run the KeyChain the query.
|
||||||
|
SecPolicyRef policy = SecPolicyCreateSSL(true, 0);
|
||||||
|
if (!policy) {
|
||||||
|
A2_LOG_ERROR("Failed to create SecPolicy");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cfrelease del_policy(policy);
|
||||||
|
const void *query_values[] = {
|
||||||
|
kSecClassIdentity,
|
||||||
|
kCFBooleanTrue,
|
||||||
|
policy,
|
||||||
|
kSecMatchLimitAll
|
||||||
|
};
|
||||||
|
CFDictionaryRef query = CFDictionaryCreate(0, query_keys, query_values,
|
||||||
|
4, 0, 0);
|
||||||
|
if (!query) {
|
||||||
|
A2_LOG_ERROR("Failed to create identity query");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cfrelease del_query(query);
|
||||||
|
CFArrayRef identities;
|
||||||
|
OSStatus err = SecItemCopyMatching(query, (CFTypeRef*)&identities);
|
||||||
|
if (err != errSecSuccess) {
|
||||||
|
A2_LOG_ERROR("Query failed: " + errToString(err));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alrighty, search the fingerprint.
|
||||||
|
const size_t nvals = CFArrayGetCount(identities);
|
||||||
|
for (size_t i = 0; i < nvals; ++i) {
|
||||||
|
SecIdentityRef id = (SecIdentityRef)CFArrayGetValueAtIndex(identities, i);
|
||||||
|
if (!id) {
|
||||||
|
A2_LOG_ERROR("Failed to get a value!");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
SecCertificateRef ref = 0;
|
||||||
|
if (SecIdentityCopyCertificate(id, &ref) != errSecSuccess) {
|
||||||
|
A2_LOG_ERROR("Failed to get a certref!");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cfrelease del_ref(ref);
|
||||||
|
CFDataRef data = SecCertificateCopyData(ref);
|
||||||
|
if (!data) {
|
||||||
|
A2_LOG_ERROR("Failed to get a data!");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cfrelease del_data(data);
|
||||||
|
|
||||||
|
// Do try all supported hash algorithms.
|
||||||
|
// Usually the fingerprint would be sha1 or md5, however this is more
|
||||||
|
// future-proof. Also "usually" doesn't cut it; there is already software
|
||||||
|
// using SHA-2 class algos, and SHA-3 is standardized and potential users
|
||||||
|
// cannot be far.
|
||||||
|
if (std::find_if(ht.begin(), ht.end(), hash_finder(data, fp)) == ht.end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
A2_LOG_INFO("Found cert with matching fingerprint");
|
||||||
|
credentials_ = id;
|
||||||
|
CFRetain(id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
A2_LOG_ERROR(fmt("Failed to lookup %s in your KeyChain", fingerprint.c_str()));
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#else // defined(__MAC_10_6)
|
||||||
|
|
||||||
|
A2_LOG_ERROR("Your system does not support creditials via fingerprints; Upgrade to OSX 10.6 or later");
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#endif // defined(__MAC_10_6)
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -50,10 +50,11 @@ class AppleTLSContext : public TLSContext {
|
||||||
public:
|
public:
|
||||||
AppleTLSContext(TLSSessionSide side)
|
AppleTLSContext(TLSSessionSide side)
|
||||||
: side_(side),
|
: side_(side),
|
||||||
verifyPeer_(true)
|
verifyPeer_(true),
|
||||||
|
credentials_(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual ~AppleTLSContext() {}
|
virtual ~AppleTLSContext();
|
||||||
|
|
||||||
// private key `keyfile' must be decrypted.
|
// private key `keyfile' must be decrypted.
|
||||||
virtual bool addCredentialFile(const std::string& certfile,
|
virtual bool addCredentialFile(const std::string& certfile,
|
||||||
|
@ -80,9 +81,14 @@ public:
|
||||||
verifyPeer_ = verify;
|
verifyPeer_ = verify;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SecIdentityRef getCredentials();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TLSSessionSide side_;
|
TLSSessionSide side_;
|
||||||
bool verifyPeer_;
|
bool verifyPeer_;
|
||||||
|
SecIdentityRef credentials_;
|
||||||
|
|
||||||
|
bool tryAsFingerprint(const std::string& fingerprint);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -39,8 +39,9 @@
|
||||||
|
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
|
||||||
#include "fmt.h"
|
|
||||||
#include "LogFactory.h"
|
#include "LogFactory.h"
|
||||||
|
#include "a2functional.h"
|
||||||
|
#include "fmt.h"
|
||||||
|
|
||||||
#define ioErr -36
|
#define ioErr -36
|
||||||
#define paramErr -50
|
#define paramErr -50
|
||||||
|
@ -52,6 +53,28 @@ namespace {
|
||||||
static const SSLProtocol kTLSProtocol12 = (SSLProtocol)(kSSLProtocolAll + 2);
|
static const SSLProtocol kTLSProtocol12 = (SSLProtocol)(kSSLProtocolAll + 2);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CIPHER_NO_DHPARAM
|
||||||
|
// Diffie-Hellman params, to seed the engine instead of having it spend up
|
||||||
|
// to 30 seconds on generating them. It should be save to share these. :p
|
||||||
|
// This was generated using: openssl dhparam -outform DER 2048
|
||||||
|
static const uint8_t dhparam[] =
|
||||||
|
"\x30\x82\x01\x08\x02\x82\x01\x01\x00\x97\xea\xd0\x46\xf7\xae\xa7\x76\x80"
|
||||||
|
"\x9c\x74\x56\x98\xd8\x56\x97\x2b\x20\x6c\x77\xe2\x82\xbb\xc8\x84\xbe\xe7"
|
||||||
|
"\x63\xaf\xcc\x30\xd0\x67\x97\x7d\x1b\xab\x59\x30\xa9\x13\x67\x21\xd7\xd4"
|
||||||
|
"\x0e\x46\xcf\xe5\x80\xdf\xc9\xb9\xba\x54\x9b\x46\x2f\x3b\x45\xfc\x2f\xaf"
|
||||||
|
"\xad\xc0\x17\x56\xdd\x52\x42\x57\x45\x70\x14\xe5\xbe\x67\xaa\xde\x69\x75"
|
||||||
|
"\x30\x0d\xf9\xa2\xc4\x63\x4d\x7a\x39\xef\x14\x62\x18\x33\x44\xa1\xf9\xc1"
|
||||||
|
"\x52\xd1\xb6\x72\x21\x98\xf8\xab\x16\x1b\x7b\x37\x65\xe3\xc5\x11\x00\xf6"
|
||||||
|
"\x36\x1f\xd8\x5f\xd8\x9f\x43\xa8\xce\x9d\xbf\x5e\xd6\x2d\xfa\x0a\xc2\x01"
|
||||||
|
"\x54\xc2\xd9\x81\x54\x55\xb5\x26\xf8\x88\x37\xf5\xfe\xe0\xef\x4a\x34\x81"
|
||||||
|
"\xdc\x5a\xb3\x71\x46\x27\xe3\xcd\x24\xf6\x1b\xf1\xe2\x0f\xc2\xa1\x39\x53"
|
||||||
|
"\x5b\xc5\x38\x46\x8e\x67\x4c\xd9\xdd\xe4\x37\x06\x03\x16\xf1\x1d\x7a\xba"
|
||||||
|
"\x2d\xc1\xe4\x03\x1a\x58\xe5\x29\x5a\x29\x06\x69\x61\x7a\xd8\xa9\x05\x9f"
|
||||||
|
"\xc1\xa2\x45\x9c\x17\xad\x52\x69\x33\xdc\x18\x8d\x15\xa6\x5e\xcd\x94\xf4"
|
||||||
|
"\x45\xbb\x9f\xc2\x7b\x85\x00\x61\xb0\x1a\xdc\x3c\x86\xaa\x9f\x5c\x04\xb3"
|
||||||
|
"\x90\x0b\x35\x64\xff\xd9\xe3\xac\xf2\xf2\xeb\x3a\x63\x02\x01\x02";
|
||||||
|
#endif // CIPHER_NO_DHPARAM
|
||||||
|
|
||||||
static inline const char *protoToString(SSLProtocol proto) {
|
static inline const char *protoToString(SSLProtocol proto) {
|
||||||
switch (proto) {
|
switch (proto) {
|
||||||
case kSSLProtocol2:
|
case kSSLProtocol2:
|
||||||
|
@ -309,8 +332,41 @@ AppleTLSSession::AppleTLSSession(AppleTLSContext* ctx)
|
||||||
if (SSLSetEnabledCiphers(sslCtx_, &enabled[0], enabled.size()) != noErr) {
|
if (SSLSetEnabledCiphers(sslCtx_, &enabled[0], enabled.size()) != noErr) {
|
||||||
A2_LOG_ERROR("AppleTLS: Failed to set enabled ciphers list");
|
A2_LOG_ERROR("AppleTLS: Failed to set enabled ciphers list");
|
||||||
state_ = st_error;
|
state_ = st_error;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (ctx->getSide() == TLS_SERVER) {
|
||||||
|
SecIdentityRef creds = ctx->getCredentials();
|
||||||
|
if (!creds) {
|
||||||
|
A2_LOG_ERROR("AppleTLS: No credentials");
|
||||||
|
state_ = st_error;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CFArrayRef certs = CFArrayCreate(0, (const void**)&creds, 1, 0);
|
||||||
|
if (!certs) {
|
||||||
|
A2_LOG_ERROR("AppleTLS: Failed to setup credentials");
|
||||||
|
state_ = st_error;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto_delete<const void*> del_certs(certs, CFRelease);
|
||||||
|
lastError_ = SSLSetCertificate(sslCtx_, certs);
|
||||||
|
if (lastError_ != noErr) {
|
||||||
|
A2_LOG_ERROR(fmt("AppleTLS: Failed to set credentials: %s", getLastErrorString().c_str()));
|
||||||
|
state_ = st_error;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef CIPHER_NO_DHPARAM
|
||||||
|
lastError_ = SSLSetDiffieHellmanParams(sslCtx_, dhparam, sizeof(dhparam));
|
||||||
|
if (lastError_ != noErr) {
|
||||||
|
A2_LOG_WARN(fmt("AppleTLS: Failed to set DHParams: %s", getLastErrorString().c_str()));
|
||||||
|
// Engine will still generate some for us, so this is no problem, except
|
||||||
|
// it will take longer.
|
||||||
|
}
|
||||||
|
#endif // CIPHER_NO_DHPARAM
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AppleTLSSession::~AppleTLSSession()
|
AppleTLSSession::~AppleTLSSession()
|
||||||
|
|
|
@ -33,6 +33,9 @@
|
||||||
*/
|
*/
|
||||||
/* copyright --> */
|
/* copyright --> */
|
||||||
#include "MessageDigest.h"
|
#include "MessageDigest.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "MessageDigestImpl.h"
|
#include "MessageDigestImpl.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "array_fun.h"
|
#include "array_fun.h"
|
||||||
|
@ -84,19 +87,24 @@ bool MessageDigest::supports(const std::string& hashType)
|
||||||
return MessageDigestImpl::supports(hashType);
|
return MessageDigestImpl::supports(hashType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> MessageDigest::getSupportedHashTypes()
|
||||||
|
{
|
||||||
|
std::vector<std::string> rv;
|
||||||
|
for (HashTypeEntry *i = vbegin(hashTypes), *eoi = vend(hashTypes);
|
||||||
|
i != eoi; ++i) {
|
||||||
|
if (MessageDigestImpl::supports(i->hashType)) {
|
||||||
|
rv.push_back(i->hashType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
std::string MessageDigest::getSupportedHashTypeString()
|
std::string MessageDigest::getSupportedHashTypeString()
|
||||||
{
|
{
|
||||||
std::string s;
|
std::vector<std::string> ht = getSupportedHashTypes();
|
||||||
for(HashTypeEntry* i = vbegin(hashTypes), *eoi = vend(hashTypes); i != eoi;
|
std::stringstream ss;
|
||||||
++i) {
|
std::copy(ht.begin(), ht.end(), std::ostream_iterator<std::string>(ss, ", "));
|
||||||
if(MessageDigestImpl::supports(i->hashType)) {
|
return ss.str().substr(ss.str().length() - 2);
|
||||||
if(!s.empty()) {
|
|
||||||
s += ", ";
|
|
||||||
}
|
|
||||||
s += i->hashType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t MessageDigest::getDigestLength(const std::string& hashType)
|
size_t MessageDigest::getDigestLength(const std::string& hashType)
|
||||||
|
@ -162,9 +170,10 @@ void MessageDigest::reset()
|
||||||
pImpl_->reset();
|
pImpl_->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageDigest::update(const void* data, size_t length)
|
MessageDigest& MessageDigest::update(const void* data, size_t length)
|
||||||
{
|
{
|
||||||
pImpl_->update(data, length);
|
pImpl_->update(data, length);
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageDigest::digest(unsigned char* md)
|
void MessageDigest::digest(unsigned char* md)
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "SharedHandle.h"
|
#include "SharedHandle.h"
|
||||||
|
|
||||||
|
@ -68,6 +69,9 @@ public:
|
||||||
// Returns true if hashType is supported. Otherwise returns false.
|
// Returns true if hashType is supported. Otherwise returns false.
|
||||||
static bool supports(const std::string& hashType);
|
static bool supports(const std::string& hashType);
|
||||||
|
|
||||||
|
// Returns a vector containing supported hash function textual names.
|
||||||
|
static std::vector<std::string> getSupportedHashTypes();
|
||||||
|
|
||||||
// Returns string containing supported hash function textual names
|
// Returns string containing supported hash function textual names
|
||||||
// joined with ','.
|
// joined with ','.
|
||||||
static std::string getSupportedHashTypeString();
|
static std::string getSupportedHashTypeString();
|
||||||
|
@ -93,7 +97,7 @@ public:
|
||||||
// Resets this object so that it can be reused.
|
// Resets this object so that it can be reused.
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
void update(const void* data, size_t length);
|
MessageDigest& update(const void* data, size_t length);
|
||||||
|
|
||||||
// Stores digest in the region pointed by md. It is caller's
|
// Stores digest in the region pointed by md. It is caller's
|
||||||
// responsibility to allocate memory at least getDigestLength().
|
// responsibility to allocate memory at least getDigestLength().
|
||||||
|
|
|
@ -141,8 +141,11 @@ error_code::Value MultiUrlRequestInfo::execute()
|
||||||
#ifdef ENABLE_SSL
|
#ifdef ENABLE_SSL
|
||||||
if(option_->getAsBool(PREF_ENABLE_RPC) &&
|
if(option_->getAsBool(PREF_ENABLE_RPC) &&
|
||||||
option_->getAsBool(PREF_RPC_SECURE)) {
|
option_->getAsBool(PREF_RPC_SECURE)) {
|
||||||
if(!option_->blank(PREF_RPC_CERTIFICATE) &&
|
if(!option_->blank(PREF_RPC_CERTIFICATE)
|
||||||
!option_->blank(PREF_RPC_PRIVATE_KEY)) {
|
#ifndef HAVE_APPLETLS
|
||||||
|
&& !option_->blank(PREF_RPC_PRIVATE_KEY)
|
||||||
|
#endif // HAVE_APPLETLS
|
||||||
|
) {
|
||||||
// We set server TLS context to the SocketCore before creating
|
// We set server TLS context to the SocketCore before creating
|
||||||
// DownloadEngine instance.
|
// DownloadEngine instance.
|
||||||
SharedHandle<TLSContext> svTlsContext(TLSContext::make(TLS_SERVER));
|
SharedHandle<TLSContext> svTlsContext(TLSContext::make(TLS_SERVER));
|
||||||
|
|
|
@ -788,11 +788,20 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
|
||||||
handlers.push_back(op);
|
handlers.push_back(op);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
OptionHandler* op(new LocalFilePathOptionHandler
|
OptionHandler* op(
|
||||||
|
#ifdef HAVE_APPLETLS
|
||||||
|
new DefaultOptionHandler
|
||||||
|
(PREF_RPC_CERTIFICATE,
|
||||||
|
TEXT_RPC_CERTIFICATE,
|
||||||
|
NO_DEFAULT_VALUE)
|
||||||
|
#else // HAVE_APPLETLS
|
||||||
|
new LocalFilePathOptionHandler
|
||||||
(PREF_RPC_CERTIFICATE,
|
(PREF_RPC_CERTIFICATE,
|
||||||
TEXT_RPC_CERTIFICATE,
|
TEXT_RPC_CERTIFICATE,
|
||||||
NO_DEFAULT_VALUE,
|
NO_DEFAULT_VALUE,
|
||||||
false));
|
false)
|
||||||
|
#endif
|
||||||
|
);
|
||||||
op->addTag(TAG_RPC);
|
op->addTag(TAG_RPC);
|
||||||
handlers.push_back(op);
|
handlers.push_back(op);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue