Support TLS CN authentication and per-image permissions in vitastor-cli serve
This commit is contained in:
@@ -262,6 +262,7 @@ void etcd_state_client_t::parse_config(const json11::Json & config)
|
||||
}
|
||||
this->etcd_ca = config["etcd_ca"].string_value();
|
||||
this->etcd_prefix = config["etcd_prefix"].string_value();
|
||||
this->use_auth = config["use_auth"].bool_value();
|
||||
if (this->etcd_prefix == "")
|
||||
{
|
||||
this->etcd_prefix = "/vitastor";
|
||||
@@ -1353,6 +1354,14 @@ void etcd_state_client_t::parse_state(const etcd_kv_t & kv)
|
||||
if (on_change_node_placement_hook)
|
||||
on_change_node_placement_hook();
|
||||
}
|
||||
else if (use_auth && key.substr(0, etcd_prefix.length()+13) == etcd_prefix+"/config/user/")
|
||||
{
|
||||
// <etcd_prefix>/config/user/<username>
|
||||
if (!value.is_object())
|
||||
user_info.erase(key.substr(etcd_prefix.length()+13));
|
||||
else
|
||||
user_info[key.substr(etcd_prefix.length()+13)] = value;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t etcd_state_client_t::parse_immediate_commit(const std::string & immediate_commit_str, uint32_t default_value)
|
||||
|
||||
@@ -145,6 +145,7 @@ public:
|
||||
int etcd_slow_timeout = 5000;
|
||||
int etcd_min_reload_interval = 1000;
|
||||
bool infinite_start = true;
|
||||
bool use_auth = false;
|
||||
uint64_t global_block_size = DEFAULT_BLOCK_SIZE;
|
||||
uint32_t global_bitmap_granularity = DEFAULT_BITMAP_GRANULARITY;
|
||||
uint32_t global_immediate_commit = IMMEDIATE_NONE;
|
||||
@@ -170,6 +171,7 @@ public:
|
||||
std::set<osd_num_t> seen_peers;
|
||||
std::map<inode_t, inode_config_t> inode_config;
|
||||
std::map<std::string, inode_t> inode_by_name;
|
||||
std::map<std::string, json11::Json> user_info;
|
||||
json11::Json node_placement;
|
||||
|
||||
std::function<void(std::map<std::string, etcd_kv_t> &)> on_change_hook;
|
||||
|
||||
+19
-10
@@ -187,6 +187,19 @@ bool openssl_ctx_use_ca(SSL_CTX *ssl_ctx, const std::string & file_or_pem)
|
||||
: !!SSL_CTX_load_verify_locations(ssl_ctx, file_or_pem.c_str(), NULL);
|
||||
}
|
||||
|
||||
static std::string openssl_get_cn(X509 *x509)
|
||||
{
|
||||
X509_NAME* subj = X509_get_subject_name(x509);
|
||||
int pos = X509_NAME_get_index_by_NID(subj, NID_commonName, -1);
|
||||
if (pos != -1)
|
||||
{
|
||||
X509_NAME_ENTRY* cn = X509_NAME_get_entry(subj, pos);
|
||||
ASN1_STRING* str = X509_NAME_ENTRY_get_data(cn);
|
||||
return std::string((const char*)ASN1_STRING_get0_data(str), ASN1_STRING_length(str));
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool openssl_ctx_use_cert(SSL_CTX *ssl_ctx, const std::string & file_or_pem, std::string & common_name)
|
||||
{
|
||||
BIO *bio = NULL;
|
||||
@@ -208,16 +221,7 @@ bool openssl_ctx_use_cert(SSL_CTX *ssl_ctx, const std::string & file_or_pem, std
|
||||
{
|
||||
ok = SSL_CTX_use_certificate(ssl_ctx, x509);
|
||||
if (ok)
|
||||
{
|
||||
X509_NAME* subj = X509_get_subject_name(x509);
|
||||
int pos = X509_NAME_get_index_by_NID(subj, NID_commonName, -1);
|
||||
if (pos != -1)
|
||||
{
|
||||
X509_NAME_ENTRY* cn = X509_NAME_get_entry(subj, pos);
|
||||
ASN1_STRING* str = X509_NAME_ENTRY_get_data(cn);
|
||||
common_name = std::string((const char*)ASN1_STRING_get0_data(str), ASN1_STRING_length(str));
|
||||
}
|
||||
}
|
||||
common_name = openssl_get_cn(x509);
|
||||
X509_free(x509);
|
||||
}
|
||||
BIO_free(bio);
|
||||
@@ -1136,6 +1140,11 @@ bool http_co_t::handle_read()
|
||||
}
|
||||
state = HTTP_CO_REQ_HDR_RECEIVED;
|
||||
parse_http_headers(response, &parsed, true);
|
||||
if (ssl)
|
||||
{
|
||||
auto x509 = SSL_get0_peer_certificate(ssl_cli);
|
||||
parsed.headers["_tls_common_name"] = openssl_get_cn(x509);
|
||||
}
|
||||
auto conn_it = parsed.headers.find("connection");
|
||||
keepalive = (conn_it != parsed.headers.end() && conn_it->second == "keep-alive");
|
||||
auto enc_it = parsed.headers.find("transfer-encoding");
|
||||
|
||||
Reference in New Issue
Block a user