Support SSL client cert and added ssl_client_cert option
This commit is contained in:
parent
9ab5a2ea73
commit
95026804e9
|
@ -179,6 +179,18 @@ server certificate won't be checked against the available certificate authoritie
|
|||
\fB\-o\fR ssl_verify_hostname (default="2")
|
||||
When 0, do not verify the SSL certificate against the hostname.
|
||||
.TP
|
||||
\fB\-o\fR ssl_client_cert (default="")
|
||||
Specify an SSL client certificate.
|
||||
Specify this optional parameter in the following format:
|
||||
"<SSL Cert>[:<Cert Type>[:<Private Key>[:<Key Type>
|
||||
[:<Password>]]]]"
|
||||
<SSL Cert>: Client certificate.
|
||||
Specify the file path or NickName(for NSS, etc.).
|
||||
<Cert Type>: Type of certificate, default is "PEM"(optional).
|
||||
<Private Key>: Certificate's private key file(optional).
|
||||
<Key Type>: Type of private key, default is "PEM"(optional).
|
||||
<Password>: Passphrase of the private key(optional). It is also possible to omit this value and specify it using the environment variable "S3FS_SSL_PRIVKEY_PASSWORD".
|
||||
.TP
|
||||
\fB\-o\fR nodnscache - disable DNS cache.
|
||||
s3fs is always using DNS cache, this option make DNS cache disable.
|
||||
.TP
|
||||
|
|
106
src/curl.cpp
106
src/curl.cpp
|
@ -83,6 +83,7 @@ static constexpr char SPECIAL_DARWIN_MIME_FILE[] = "/etc/apache2/mime.typ
|
|||
//-------------------------------------------------------------------
|
||||
// Class S3fsCurl
|
||||
//-------------------------------------------------------------------
|
||||
constexpr char S3fsCurl::S3FS_SSL_PRIVKEY_PASSWORD[];
|
||||
pthread_mutex_t S3fsCurl::curl_warnings_lock;
|
||||
pthread_mutex_t S3fsCurl::curl_handles_lock;
|
||||
S3fsCurl::callback_locks_t S3fsCurl::callback_locks;
|
||||
|
@ -107,6 +108,12 @@ bool S3fsCurl::is_verbose = false;
|
|||
bool S3fsCurl::is_dump_body = false;
|
||||
S3fsCred* S3fsCurl::ps3fscred = nullptr;
|
||||
long S3fsCurl::ssl_verify_hostname = 1; // default(original code...)
|
||||
// SSL client cert options
|
||||
std::string S3fsCurl::client_cert;
|
||||
std::string S3fsCurl::client_cert_type;
|
||||
std::string S3fsCurl::client_priv_key;
|
||||
std::string S3fsCurl::client_priv_key_type;
|
||||
std::string S3fsCurl::client_key_password;
|
||||
|
||||
// protected by curl_warnings_lock
|
||||
bool S3fsCurl::curl_warnings_once = false;
|
||||
|
@ -1013,6 +1020,75 @@ long S3fsCurl::SetSslVerifyHostname(long value)
|
|||
return old;
|
||||
}
|
||||
|
||||
bool S3fsCurl::SetSSLClientCertOptions(const std::string& values)
|
||||
{
|
||||
// Parse values:
|
||||
// <values> = "<SSL Client Cert>:<SSL Cert Type>:<SSL Cert Private Key>:<SSL Cert Private Type>:<Key Password>"
|
||||
//
|
||||
if(values.empty()){
|
||||
return false;
|
||||
}
|
||||
|
||||
std::list<std::string> valarr;
|
||||
std::string::size_type start_pos = 0;
|
||||
std::string::size_type pos;
|
||||
do{
|
||||
if(std::string::npos == (pos = values.find(':', start_pos))){
|
||||
valarr.push_back(values.substr(start_pos));
|
||||
start_pos = pos;
|
||||
}else{
|
||||
if(0 < (pos - start_pos)){
|
||||
valarr.push_back(values.substr(start_pos, (pos - start_pos)));
|
||||
}else{
|
||||
valarr.emplace_back("");
|
||||
}
|
||||
start_pos = ++pos;
|
||||
}
|
||||
}while(std::string::npos != start_pos);
|
||||
|
||||
// set client cert
|
||||
if(!valarr.empty() && !valarr.front().empty()){
|
||||
S3fsCurl::client_cert = valarr.front();
|
||||
valarr.pop_front();
|
||||
|
||||
// set client cert type
|
||||
if(!valarr.empty()){
|
||||
S3fsCurl::client_cert_type = valarr.front(); // allow empty(default: PEM)
|
||||
valarr.pop_front();
|
||||
|
||||
// set client private key
|
||||
if(!valarr.empty()){
|
||||
S3fsCurl::client_priv_key = valarr.front(); // allow empty
|
||||
valarr.pop_front();
|
||||
|
||||
// set client private key type
|
||||
if(!valarr.empty()){
|
||||
S3fsCurl::client_priv_key_type = valarr.front(); // allow empty(default: PEM)
|
||||
valarr.pop_front();
|
||||
|
||||
// set key password
|
||||
if(!valarr.empty()){
|
||||
S3fsCurl::client_key_password = valarr.front(); // allow empty
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// [NOTE]
|
||||
// If the private key is set but the password is not set,
|
||||
// check the environment variables.
|
||||
//
|
||||
if(!S3fsCurl::client_priv_key.empty() && S3fsCurl::client_key_password.empty()){
|
||||
const char* pass = std::getenv(S3fsCurl::S3FS_SSL_PRIVKEY_PASSWORD);
|
||||
if(pass != nullptr){
|
||||
S3fsCurl::client_key_password = pass;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool S3fsCurl::SetMultipartSize(off_t size)
|
||||
{
|
||||
size = size * 1024 * 1024;
|
||||
|
@ -1985,6 +2061,36 @@ bool S3fsCurl::ResetHandle(AutoLock::Type locktype)
|
|||
}
|
||||
}
|
||||
}
|
||||
// SSL Client Cert
|
||||
if(!S3fsCurl::client_cert.empty()){
|
||||
if(CURLE_OK != curl_easy_setopt(hCurl, CURLOPT_SSLCERT, S3fsCurl::client_cert.c_str())){
|
||||
return false;
|
||||
}
|
||||
if(!S3fsCurl::client_cert_type.empty() && 0 != strcasecmp(S3fsCurl::client_cert_type.c_str(), "PEM")){ // "PEM" is default
|
||||
if(CURLE_OK != curl_easy_setopt(hCurl, CURLOPT_SSLCERTTYPE, S3fsCurl::client_cert_type.c_str())){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Private key
|
||||
if(!S3fsCurl::client_priv_key.empty()){
|
||||
if(CURLE_OK != curl_easy_setopt(hCurl, CURLOPT_SSLKEY, S3fsCurl::client_priv_key.c_str())){
|
||||
return false;
|
||||
}
|
||||
if(!S3fsCurl::client_priv_key_type.empty() && 0 != strcasecmp(S3fsCurl::client_priv_key_type.c_str(), "PEM")){ // "PEM" is default
|
||||
if(CURLE_OK != curl_easy_setopt(hCurl, CURLOPT_SSLKEYTYPE, S3fsCurl::client_priv_key_type.c_str())){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Password
|
||||
if(!S3fsCurl::client_key_password.empty()){
|
||||
if(CURLE_OK != curl_easy_setopt(hCurl, CURLOPT_KEYPASSWD, S3fsCurl::client_key_password.c_str())){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if((S3fsCurl::is_dns_cache || S3fsCurl::is_ssl_session_cache) && S3fsCurl::hCurlShare){
|
||||
if(CURLE_OK != curl_easy_setopt(hCurl, CURLOPT_SHARE, S3fsCurl::hCurlShare)){
|
||||
return false;
|
||||
|
|
|
@ -110,6 +110,9 @@ class S3fsCurl
|
|||
IAMROLE
|
||||
};
|
||||
|
||||
// Environment name
|
||||
static constexpr char S3FS_SSL_PRIVKEY_PASSWORD[] = "S3FS_SSL_PRIVKEY_PASSWORD";
|
||||
|
||||
// class variables
|
||||
static pthread_mutex_t curl_warnings_lock;
|
||||
static bool curl_warnings_once; // emit older curl warnings only once
|
||||
|
@ -139,6 +142,11 @@ class S3fsCurl
|
|||
static bool is_dump_body;
|
||||
static S3fsCred* ps3fscred;
|
||||
static long ssl_verify_hostname;
|
||||
static std::string client_cert;
|
||||
static std::string client_cert_type;
|
||||
static std::string client_priv_key;
|
||||
static std::string client_priv_key_type;
|
||||
static std::string client_key_password;
|
||||
static curltime_t curl_times;
|
||||
static curlprogress_t curl_progress;
|
||||
static std::string curl_ca_bundle;
|
||||
|
@ -317,6 +325,7 @@ class S3fsCurl
|
|||
static bool IsDumpBody() { return S3fsCurl::is_dump_body; }
|
||||
static long SetSslVerifyHostname(long value);
|
||||
static long GetSslVerifyHostname() { return S3fsCurl::ssl_verify_hostname; }
|
||||
static bool SetSSLClientCertOptions(const std::string& values);
|
||||
static void ResetOffset(S3fsCurl* pCurl);
|
||||
// maximum parallel GET and PUT requests
|
||||
static int SetMaxParallelCount(int value);
|
||||
|
|
|
@ -5085,6 +5085,14 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
else if(is_prefix(arg, "ssl_client_cert=")){
|
||||
std::string values = strchr(arg, '=') + sizeof(char);
|
||||
if(!S3fsCurl::SetSSLClientCertOptions(values)){
|
||||
S3FS_PRN_EXIT("failed to set SSL client certification options.");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
// Detect options for credential
|
||||
//
|
||||
|
|
|
@ -217,6 +217,21 @@ static constexpr char help_string[] =
|
|||
" ssl_verify_hostname (default=\"2\")\n"
|
||||
" - When 0, do not verify the SSL certificate against the hostname.\n"
|
||||
"\n"
|
||||
" ssl_client_cert (default=\"\")\n"
|
||||
" - Specify an SSL client certificate.\n"
|
||||
" Specify this optional parameter in the following format:\n"
|
||||
" \"<SSL Cert>[:<Cert Type>[:<Private Key>[:<Key Type>\n"
|
||||
" [:<Password>]]]]\"\n"
|
||||
" <SSL Cert>: Client certificate.\n"
|
||||
" Specify the file path or NickName(for NSS, etc.).\n"
|
||||
" <Cert Type>: Type of certificate, default is \"PEM\"(optional).\n"
|
||||
" <Private Key>: Certificate's private key file(optional).\n"
|
||||
" <Key Type>: Type of private key, default is \"PEM\"(optional).\n"
|
||||
" <Password>: Passphrase of the private key(optional).\n"
|
||||
" It is also possible to omit this value and specify\n"
|
||||
" it using the environment variable\n"
|
||||
" \"S3FS_SSL_PRIVKEY_PASSWORD\".\n"
|
||||
"\n"
|
||||
" nodnscache (disable DNS cache)\n"
|
||||
" - s3fs is always using DNS cache, this option make DNS cache disable.\n"
|
||||
"\n"
|
||||
|
|
Loading…
Reference in New Issue