Compare commits
49
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ad5d56bd0 | ||
|
|
e869672a86 | ||
|
|
4a9f82856c | ||
|
|
b3f53dfe92 | ||
|
|
3ded073790 | ||
|
|
337e097000 | ||
|
|
b9a5e6b7e8 | ||
|
|
bf0e648d70 | ||
|
|
35e7bc8aeb | ||
|
|
9a5fabddb4 | ||
|
|
088e85a423 | ||
|
|
43f1d58f29 | ||
|
|
a6b29a01a2 | ||
|
|
5d65d87dfb | ||
|
|
ddf28feaf8 | ||
|
|
a57049be63 | ||
|
|
7f53e315c5 | ||
|
|
48756520dd | ||
|
|
4f23b242f3 | ||
|
|
c371b74e12 | ||
|
|
c014d20fca | ||
|
|
9b2480d552 | ||
|
|
1ae10c21ca | ||
|
|
4698009b59 | ||
|
|
d0e0b70f81 | ||
|
|
914f42da5c | ||
|
|
273b641820 | ||
|
|
4f9de7a6fb | ||
|
|
d3c529abd7 | ||
|
|
a8e19ba28a | ||
|
|
64a8cd1f4b | ||
|
|
cc6e531410 | ||
|
|
ca608d0b87 | ||
|
|
0e095d2347 | ||
|
|
4fe2a0a3eb | ||
|
|
1a4d275616 | ||
|
|
803c870493 | ||
|
|
0d97fba466 | ||
|
|
41100260ec | ||
|
|
07c9606594 | ||
|
|
4ba361d83d | ||
|
|
662fb86eae | ||
|
|
1df8b51abb | ||
|
|
d2d01e5183 | ||
|
|
3d96c3907e | ||
|
|
fb483185ff | ||
|
|
d6eb00e18e | ||
|
|
34d47bd62a | ||
|
|
2846eba3af |
@@ -262,4 +262,3 @@ Options:
|
|||||||
| `--logfile <FILE>` | log to the specified file |
|
| `--logfile <FILE>` | log to the specified file |
|
||||||
| `--enforce 1` | enforce permissions at the server side (no by default) |
|
| `--enforce 1` | enforce permissions at the server side (no by default) |
|
||||||
| `--foreground 1` | stay in foreground, do not daemonize |
|
| `--foreground 1` | stay in foreground, do not daemonize |
|
||||||
| `--trace` | trace all NFS requests |
|
|
||||||
|
|||||||
@@ -274,4 +274,3 @@ VitastorFS из GPUDirect.
|
|||||||
| `--logfile <FILE>` | записывать логи в заданный файл |
|
| `--logfile <FILE>` | записывать логи в заданный файл |
|
||||||
| `--enforce 1` | проверять права доступа на стороне сервера (по умолчанию нет) |
|
| `--enforce 1` | проверять права доступа на стороне сервера (по умолчанию нет) |
|
||||||
| `--foreground 1` | не уходить в фон после запуска |
|
| `--foreground 1` | не уходить в фон после запуска |
|
||||||
| `--trace` | логгировать все запросы NFS |
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ if (RDMACM_LIBRARIES)
|
|||||||
set(MSGR_RDMACM "msgr_rdmacm.cpp")
|
set(MSGR_RDMACM "msgr_rdmacm.cpp")
|
||||||
endif (RDMACM_LIBRARIES)
|
endif (RDMACM_LIBRARIES)
|
||||||
add_library(vitastor_common STATIC
|
add_library(vitastor_common STATIC
|
||||||
../util/epoll_manager.cpp etcd_state_client.cpp messenger.cpp ../util/addr_util.cpp ../util/xxh_x86dispatch.c ../util/openssl_util.cpp
|
../util/epoll_manager.cpp etcd_state_client.cpp messenger.cpp ../util/addr_util.cpp ../util/xxh_x86dispatch.c
|
||||||
msgr_encrypt.cpp msgr_stop.cpp msgr_op.cpp msgr_send.cpp msgr_receive.cpp ../util/ringloop.cpp ../../json11/json11.cpp
|
msgr_encrypt.cpp msgr_stop.cpp msgr_op.cpp msgr_send.cpp msgr_receive.cpp ../util/ringloop.cpp ../../json11/json11.cpp
|
||||||
http_client.cpp osd_ops.cpp pg_states.cpp ../util/timerfd_manager.cpp ../util/str_util.cpp ../util/json_util.cpp ${MSGR_RDMA} ${MSGR_RDMACM}
|
http_client.cpp osd_ops.cpp pg_states.cpp ../util/timerfd_manager.cpp ../util/str_util.cpp ../util/json_util.cpp ${MSGR_RDMA} ${MSGR_RDMACM}
|
||||||
)
|
)
|
||||||
@@ -102,7 +102,7 @@ add_executable(test_cluster_client
|
|||||||
EXCLUDE_FROM_ALL
|
EXCLUDE_FROM_ALL
|
||||||
../test/test_cluster_client.cpp
|
../test/test_cluster_client.cpp
|
||||||
pg_states.cpp osd_ops.cpp cluster_client.cpp cluster_client_list.cpp cluster_client_wb.cpp cluster_client_icache.cpp msgr_op.cpp ../test/mock/messenger.cpp msgr_stop.cpp msgr_encrypt.cpp
|
pg_states.cpp osd_ops.cpp cluster_client.cpp cluster_client_list.cpp cluster_client_wb.cpp cluster_client_icache.cpp msgr_op.cpp ../test/mock/messenger.cpp msgr_stop.cpp msgr_encrypt.cpp
|
||||||
etcd_state_client.cpp ../util/timerfd_manager.cpp ../util/addr_util.cpp ../util/str_util.cpp ../util/json_util.cpp ../util/xxh_x86dispatch.c ../util/openssl_util.cpp ../../json11/json11.cpp
|
etcd_state_client.cpp ../util/timerfd_manager.cpp ../util/addr_util.cpp ../util/str_util.cpp ../util/json_util.cpp ../util/xxh_x86dispatch.c ../../json11/json11.cpp
|
||||||
)
|
)
|
||||||
target_link_libraries(test_cluster_client ${OPENSSL_LIBRARIES} ${ISAL_CRYPTO_LIBRARIES})
|
target_link_libraries(test_cluster_client ${OPENSSL_LIBRARIES} ${ISAL_CRYPTO_LIBRARIES})
|
||||||
target_compile_definitions(test_cluster_client PUBLIC -D__MOCK__)
|
target_compile_definitions(test_cluster_client PUBLIC -D__MOCK__)
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
#include "openssl_util.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// libc-ares
|
// libc-ares
|
||||||
@@ -164,6 +163,105 @@ void http_ares_cb(void *data, ares_socket_t socket_fd, int readable, int writabl
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_OPENSSL
|
||||||
|
bool openssl_ctx_add_ca(SSL_CTX *ssl_ctx, const std::string & file_or_pem)
|
||||||
|
{
|
||||||
|
std::string pem;
|
||||||
|
BIO *bio = NULL;
|
||||||
|
if (file_or_pem.substr(0, 5) != "-----")
|
||||||
|
{
|
||||||
|
pem = read_file(file_or_pem);
|
||||||
|
bio = BIO_new_mem_buf(pem.data(), pem.size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bio = BIO_new_mem_buf(file_or_pem.data(), file_or_pem.size());
|
||||||
|
if (!bio)
|
||||||
|
return false;
|
||||||
|
X509 *x509 = PEM_read_bio_X509(bio, NULL, 0, NULL);
|
||||||
|
bool ok = !!x509;
|
||||||
|
if (x509)
|
||||||
|
{
|
||||||
|
X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
|
||||||
|
X509_STORE_add_cert(store, x509);
|
||||||
|
X509_free(x509);
|
||||||
|
}
|
||||||
|
BIO_free(bio);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool openssl_ctx_use_ca(SSL_CTX *ssl_ctx, const std::string & file_or_pem)
|
||||||
|
{
|
||||||
|
if (file_or_pem.substr(0, 5) == "-----")
|
||||||
|
{
|
||||||
|
return openssl_ctx_add_ca(ssl_ctx, file_or_pem);
|
||||||
|
}
|
||||||
|
return file_or_pem.empty()
|
||||||
|
? !!SSL_CTX_set_default_verify_paths(ssl_ctx)
|
||||||
|
: !!SSL_CTX_load_verify_locations(ssl_ctx, file_or_pem.c_str(), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
std::string contents;
|
||||||
|
if (file_or_pem.substr(0, 5) == "-----")
|
||||||
|
bio = BIO_new_mem_buf(file_or_pem.data(), file_or_pem.size());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
contents = read_file(file_or_pem);
|
||||||
|
if (!contents.size())
|
||||||
|
return false;
|
||||||
|
bio = BIO_new_mem_buf(contents.data(), contents.size());
|
||||||
|
}
|
||||||
|
if (!bio)
|
||||||
|
return false;
|
||||||
|
X509 *x509 = PEM_read_bio_X509(bio, NULL, 0, NULL);
|
||||||
|
bool ok = !!x509;
|
||||||
|
if (x509)
|
||||||
|
{
|
||||||
|
ok = SSL_CTX_use_certificate(ssl_ctx, x509);
|
||||||
|
if (ok)
|
||||||
|
common_name = openssl_get_cn(x509);
|
||||||
|
X509_free(x509);
|
||||||
|
}
|
||||||
|
BIO_free(bio);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool openssl_ctx_use_key(SSL_CTX *ssl_ctx, const std::string & file_or_pem)
|
||||||
|
{
|
||||||
|
if (file_or_pem.substr(0, 5) == "-----")
|
||||||
|
{
|
||||||
|
BIO *bio = BIO_new_mem_buf(file_or_pem.data(), file_or_pem.size());
|
||||||
|
if (!bio)
|
||||||
|
return false;
|
||||||
|
EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
|
||||||
|
bool ok = !!pkey;
|
||||||
|
if (pkey)
|
||||||
|
{
|
||||||
|
ok = SSL_CTX_use_PrivateKey(ssl_ctx, pkey);
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
|
}
|
||||||
|
BIO_free(bio);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
return !!SSL_CTX_use_PrivateKey_file(ssl_ctx, file_or_pem.c_str(), SSL_FILETYPE_PEM);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
http_context_t* http_context_init(timerfd_manager_t *tfd, const std::string & ssl_cert, const std::string & ssl_key,
|
http_context_t* http_context_init(timerfd_manager_t *tfd, const std::string & ssl_cert, const std::string & ssl_key,
|
||||||
const std::string & ssl_ca, bool verify_peer, std::string & error)
|
const std::string & ssl_ca, bool verify_peer, std::string & error)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,6 +8,10 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include "json11/json11.hpp"
|
#include "json11/json11.hpp"
|
||||||
|
|
||||||
|
#ifdef WITH_OPENSSL
|
||||||
|
#include <openssl/types.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define WS_CONTINUATION 0
|
#define WS_CONTINUATION 0
|
||||||
#define WS_TEXT 1
|
#define WS_TEXT 1
|
||||||
#define WS_BINARY 2
|
#define WS_BINARY 2
|
||||||
@@ -69,3 +73,11 @@ void http_close(http_co_t *co);
|
|||||||
void http_destroy(http_co_t *co);
|
void http_destroy(http_co_t *co);
|
||||||
|
|
||||||
#pragma GCC visibility pop
|
#pragma GCC visibility pop
|
||||||
|
|
||||||
|
#ifdef WITH_OPENSSL
|
||||||
|
bool openssl_ctx_add_ca(SSL_CTX *ssl_ctx, const std::string & file_or_pem);
|
||||||
|
bool openssl_ctx_use_ca(SSL_CTX *ssl_ctx, const std::string & file_or_pem);
|
||||||
|
std::string openssl_get_cn(X509 *x509);
|
||||||
|
bool openssl_ctx_use_cert(SSL_CTX *ssl_ctx, const std::string & file_or_pem, std::string & common_name);
|
||||||
|
bool openssl_ctx_use_key(SSL_CTX *ssl_ctx, const std::string & file_or_pem);
|
||||||
|
#endif
|
||||||
|
|||||||
+108
-4
@@ -15,6 +15,11 @@
|
|||||||
#ifdef WITH_RDMA
|
#ifdef WITH_RDMA
|
||||||
#include "msgr_rdma.h"
|
#include "msgr_rdma.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "http_client.h"
|
||||||
|
#include <openssl/bio.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/pem.h>
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
|
|
||||||
@@ -118,7 +123,44 @@ void msgr_iothread_t::run()
|
|||||||
|
|
||||||
void osd_messenger_t::init()
|
void osd_messenger_t::init()
|
||||||
{
|
{
|
||||||
init_tls();
|
if (!tls_cert.empty() || !tls_key.empty() || !osd_tls_ca.empty() || !client_tls_ca.empty())
|
||||||
|
{
|
||||||
|
// Initialize TLS context
|
||||||
|
if (tls_cert.empty() || tls_key.empty() || osd_tls_ca.empty() || osd_num && client_tls_ca.empty())
|
||||||
|
{
|
||||||
|
if (osd_num)
|
||||||
|
fprintf(stderr, "Vitastor OSD TLS requires osd_tls_cert, osd_tls_key, osd_tls_ca, client_tls_ca\n");
|
||||||
|
else
|
||||||
|
fprintf(stderr, "Vitastor client TLS requires tls_cert, tls_key and osd_tls_ca\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ssl_ctx = SSL_CTX_new(TLS_method());
|
||||||
|
if (!ssl_ctx)
|
||||||
|
{
|
||||||
|
init_err:
|
||||||
|
fprintf(stderr, "OpenSSL initialization failed: %s\n", ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
|
||||||
|
bool ok = SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
|
||||||
|
ok = ok && openssl_ctx_add_ca(ssl_ctx, osd_tls_ca);
|
||||||
|
if (osd_num)
|
||||||
|
{
|
||||||
|
// OSD uses 2 separate root certificates to distinguish between clients and peer OSDs
|
||||||
|
ok = ok && openssl_ctx_add_ca(ssl_ctx, client_tls_ca);
|
||||||
|
}
|
||||||
|
ok = ok && openssl_ctx_use_cert(ssl_ctx, tls_cert, tls_cn);
|
||||||
|
ok = ok && openssl_ctx_use_key(ssl_ctx, tls_key);
|
||||||
|
if (!ok)
|
||||||
|
{
|
||||||
|
SSL_CTX_free(ssl_ctx);
|
||||||
|
ssl_ctx = NULL;
|
||||||
|
goto init_err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#ifdef WITH_RDMACM
|
#ifdef WITH_RDMACM
|
||||||
if (use_rdmacm)
|
if (use_rdmacm)
|
||||||
{
|
{
|
||||||
@@ -305,7 +347,30 @@ osd_messenger_t::~osd_messenger_t()
|
|||||||
{
|
{
|
||||||
destroy_aes_xts_decrypt(decrypt_ctx);
|
destroy_aes_xts_decrypt(decrypt_ctx);
|
||||||
}
|
}
|
||||||
destroy_tls();
|
#ifdef WITH_ISAL_CRYPTO
|
||||||
|
for (isal_gcm_context_data *ctx: encrypt_gcm_pool)
|
||||||
|
{
|
||||||
|
free(ctx);
|
||||||
|
}
|
||||||
|
for (isal_gcm_context_data *ctx: decrypt_gcm_pool)
|
||||||
|
{
|
||||||
|
free(ctx);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for (EVP_CIPHER_CTX *ctx: encrypt_gcm_pool)
|
||||||
|
{
|
||||||
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
|
}
|
||||||
|
for (EVP_CIPHER_CTX *ctx: decrypt_gcm_pool)
|
||||||
|
{
|
||||||
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (ssl_ctx)
|
||||||
|
{
|
||||||
|
SSL_CTX_free(ssl_ctx);
|
||||||
|
ssl_ctx = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void osd_messenger_t::parse_config(const json11::Json & config)
|
void osd_messenger_t::parse_config(const json11::Json & config)
|
||||||
@@ -364,6 +429,15 @@ void osd_messenger_t::parse_config(const json11::Json & config)
|
|||||||
osd_tls_ca = config["osd_tls_ca"].string_value();
|
osd_tls_ca = config["osd_tls_ca"].string_value();
|
||||||
client_tls_ca = config["client_tls_ca"].string_value();
|
client_tls_ca = config["client_tls_ca"].string_value();
|
||||||
}
|
}
|
||||||
|
test_osd_aes_key.resize(32);
|
||||||
|
if (fromhexstr(config["test_osd_aes_key"].string_value(), 32, (uint8_t*)test_osd_aes_key.data()) != 32)
|
||||||
|
test_osd_aes_key.clear();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef WITH_ISAL_CRYPTO
|
||||||
|
isal_aes_gcm_pre_256(test_osd_aes_key.data(), &test_osd_aes_key_isal);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
if (!osd_num)
|
if (!osd_num)
|
||||||
this->iothread_count = (uint32_t)config["client_iothread_count"].uint64_value();
|
this->iothread_count = (uint32_t)config["client_iothread_count"].uint64_value();
|
||||||
else
|
else
|
||||||
@@ -594,7 +668,7 @@ void osd_messenger_t::handle_connect_epoll(int peer_fd)
|
|||||||
handle_peer_epoll(peer_fd, epoll_events);
|
handle_peer_epoll(peer_fd, epoll_events);
|
||||||
});
|
});
|
||||||
// Check OSD number
|
// Check OSD number
|
||||||
init_tls_client(cl);
|
ssl_init(cl, false);
|
||||||
check_peer_config(cl);
|
check_peer_config(cl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -836,7 +910,7 @@ void osd_messenger_t::accept_connections(int listen_fd)
|
|||||||
cl->peer_fd = peer_fd;
|
cl->peer_fd = peer_fd;
|
||||||
cl->peer_state = PEER_CONNECTED;
|
cl->peer_state = PEER_CONNECTED;
|
||||||
cl->in_buf = (uint8_t*)malloc_or_die(receive_buffer_size);
|
cl->in_buf = (uint8_t*)malloc_or_die(receive_buffer_size);
|
||||||
init_tls_client(cl);
|
ssl_init(cl, true);
|
||||||
// Add FD to epoll
|
// Add FD to epoll
|
||||||
tfd->set_fd_handler(peer_fd, false, [this](int peer_fd, int epoll_events)
|
tfd->set_fd_handler(peer_fd, false, [this](int peer_fd, int epoll_events)
|
||||||
{
|
{
|
||||||
@@ -851,6 +925,36 @@ void osd_messenger_t::accept_connections(int listen_fd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void osd_messenger_t::ssl_init(osd_client_t *cl, bool server_mode)
|
||||||
|
{
|
||||||
|
if (!tls_cert.empty())
|
||||||
|
{
|
||||||
|
cl->write_to_ssl = BIO_new(BIO_s_mem());
|
||||||
|
cl->read_from_ssl = BIO_new(BIO_s_mem());
|
||||||
|
cl->ssl_cli = SSL_new(ssl_ctx);
|
||||||
|
if (!cl->ssl_cli)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "OpenSSL initialization failed: %s\n", ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (server_mode)
|
||||||
|
{
|
||||||
|
SSL_set_accept_state(cl->ssl_cli);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SSL_set_connect_state(cl->ssl_cli);
|
||||||
|
}
|
||||||
|
SSL_set_bio(cl->ssl_cli, cl->write_to_ssl, cl->read_from_ssl);
|
||||||
|
bool ok = ssl_do_handshake(cl);
|
||||||
|
assert(ok);
|
||||||
|
}
|
||||||
|
else if (!test_osd_aes_key.empty())
|
||||||
|
{
|
||||||
|
cl->gcm_enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WITH_RDMA
|
#ifdef WITH_RDMA
|
||||||
msgr_rdma_context_t* osd_messenger_t::choose_rdma_context(osd_client_t *cl)
|
msgr_rdma_context_t* osd_messenger_t::choose_rdma_context(osd_client_t *cl)
|
||||||
{
|
{
|
||||||
|
|||||||
+8
-19
@@ -46,9 +46,6 @@
|
|||||||
|
|
||||||
#define DEFAULT_MIN_ZEROCOPY_SEND_SIZE 32*1024
|
#define DEFAULT_MIN_ZEROCOPY_SEND_SIZE 32*1024
|
||||||
|
|
||||||
#define AES_256_GCM_KEY_SIZE 32
|
|
||||||
#define AES_256_GCM_IV_SIZE 12
|
|
||||||
|
|
||||||
struct msgr_sendp_t
|
struct msgr_sendp_t
|
||||||
{
|
{
|
||||||
osd_op_t *op;
|
osd_op_t *op;
|
||||||
@@ -101,17 +98,13 @@ struct osd_client_t
|
|||||||
BIO *read_from_ssl = NULL;
|
BIO *read_from_ssl = NULL;
|
||||||
uint8_t *ssl_out_buf = NULL;
|
uint8_t *ssl_out_buf = NULL;
|
||||||
size_t ssl_out_buf_size = 0, ssl_out_buf_cap = 0;
|
size_t ssl_out_buf_size = 0, ssl_out_buf_cap = 0;
|
||||||
int ssl_handshake_pending = 0;
|
bool ssl_handshake_done = false;
|
||||||
msgr_tls_record_hdr_t ssl_read_record;
|
msgr_tls_record_hdr_t ssl_read_record;
|
||||||
size_t ssl_read_header_size = 0;
|
size_t ssl_read_header_size = 0;
|
||||||
bool ssl_more_to_buffer = false;
|
bool ssl_more_to_buffer = false;
|
||||||
|
|
||||||
bool gcm_enabled = false;
|
bool gcm_enabled = false;
|
||||||
std::vector<uint8_t> my_secret, peer_secret;
|
|
||||||
std::vector<uint8_t> my_key, peer_key;
|
|
||||||
uint64_t my_iv_ctr, peer_iv_ctr;
|
|
||||||
#ifdef WITH_ISAL_CRYPTO
|
#ifdef WITH_ISAL_CRYPTO
|
||||||
isal_gcm_key_data my_key_isal, peer_key_isal;
|
|
||||||
isal_gcm_context_data *enc_ctx = NULL;
|
isal_gcm_context_data *enc_ctx = NULL;
|
||||||
isal_gcm_context_data *dec_ctx = NULL;
|
isal_gcm_context_data *dec_ctx = NULL;
|
||||||
#else
|
#else
|
||||||
@@ -273,6 +266,10 @@ protected:
|
|||||||
std::string tls_key;
|
std::string tls_key;
|
||||||
std::string osd_tls_ca;
|
std::string osd_tls_ca;
|
||||||
std::string client_tls_ca;
|
std::string client_tls_ca;
|
||||||
|
std::string test_osd_aes_key; // FIXME Insecure, only for PoC tests
|
||||||
|
#ifdef WITH_ISAL_CRYPTO
|
||||||
|
isal_gcm_key_data test_osd_aes_key_isal;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_RDMA
|
#ifdef WITH_RDMA
|
||||||
bool use_rdma = true;
|
bool use_rdma = true;
|
||||||
@@ -291,18 +288,10 @@ protected:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
SSL_CTX *ssl_ctx = NULL;
|
SSL_CTX *ssl_ctx = NULL;
|
||||||
EVP_KDF_CTX *kdf_ctx = NULL;
|
|
||||||
X509 *tls_cert_obj = NULL;
|
|
||||||
X509 *osd_tls_ca_obj = NULL;
|
|
||||||
X509 *client_tls_ca_obj = NULL;
|
|
||||||
std::string tls_cn;
|
std::string tls_cn;
|
||||||
|
|
||||||
void init_tls();
|
void ssl_init(osd_client_t *cl, bool server_mode);
|
||||||
void destroy_tls();
|
bool ssl_do_handshake(osd_client_t *cl);
|
||||||
void init_tls_client(osd_client_t *cl);
|
|
||||||
bool do_tls_handshake(osd_client_t *cl, bool from_recv = false);
|
|
||||||
bool finalize_tls_handshake(osd_client_t *cl);
|
|
||||||
bool derive_aes_keys(osd_client_t *cl, bool update_my, bool update_peer);
|
|
||||||
|
|
||||||
std::vector<msgr_iothread_t*> iothreads;
|
std::vector<msgr_iothread_t*> iothreads;
|
||||||
std::vector<uint64_t> read_ready_clients;
|
std::vector<uint64_t> read_ready_clients;
|
||||||
@@ -397,7 +386,7 @@ protected:
|
|||||||
|
|
||||||
void handle_read(int result, osd_client_t *cl);
|
void handle_read(int result, osd_client_t *cl);
|
||||||
bool handle_read_buffer(osd_client_t *cl, uint8_t *curbuf, size_t bufsize);
|
bool handle_read_buffer(osd_client_t *cl, uint8_t *curbuf, size_t bufsize);
|
||||||
template<typename T> size_t handle_buffer_with(osd_client_t *cl, uint8_t *curbuf, size_t bufsize);
|
template<typename T> bool handle_buffer_with(osd_client_t *cl, uint8_t *curbuf, size_t bufsize);
|
||||||
bool handle_hdr(osd_client_t *cl);
|
bool handle_hdr(osd_client_t *cl);
|
||||||
bool allocate_op_buffers(osd_client_t *cl);
|
bool allocate_op_buffers(osd_client_t *cl);
|
||||||
bool allocate_reply_buffers(osd_client_t *cl, osd_op_t *op);
|
bool allocate_reply_buffers(osd_client_t *cl, osd_op_t *op);
|
||||||
|
|||||||
@@ -7,22 +7,9 @@
|
|||||||
#include <isa-l_crypto/isal_crypto_api.h>
|
#include <isa-l_crypto/isal_crypto_api.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
#include "str_util.h"
|
|
||||||
#include "etcd_state_client.h"
|
#include "etcd_state_client.h"
|
||||||
#include "messenger.h"
|
#include "messenger.h"
|
||||||
#include "msgr_encrypt.h"
|
#include "msgr_encrypt.h"
|
||||||
#include "http_client.h"
|
|
||||||
#include "openssl_util.h"
|
|
||||||
|
|
||||||
#include <openssl/kdf.h>
|
|
||||||
#include <openssl/ssl.h>
|
|
||||||
#include <openssl/err.h>
|
|
||||||
|
|
||||||
#define MSGR_HSP_HS 1
|
|
||||||
#define MSGR_HSP_SEND 2
|
|
||||||
#define MSGR_HSP_RECV 4
|
|
||||||
|
|
||||||
op_aes_xts_encrypt_t::op_aes_xts_encrypt_t()
|
op_aes_xts_encrypt_t::op_aes_xts_encrypt_t()
|
||||||
{
|
{
|
||||||
@@ -492,303 +479,3 @@ void osd_messenger_t::op_encrypt_free(osd_client_t* cl)
|
|||||||
cl->xts_enc_ctx = NULL;
|
cl->xts_enc_ctx = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tls_secrets_t
|
|
||||||
{
|
|
||||||
std::vector<uint8_t> client_secret;
|
|
||||||
std::vector<uint8_t> server_secret;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Sadly we have to use a global variable to capture TLS 1.3 secrets
|
|
||||||
static std::mutex logged_secrets_mu;
|
|
||||||
static std::map<const SSL*, tls_secrets_t> logged_secrets;
|
|
||||||
|
|
||||||
static void openssl_key_log(const SSL *ssl, const char *line)
|
|
||||||
{
|
|
||||||
// Format: <CLIENT|SERVER>_TRAFFIC_SECRET_0 <server_random> <secret>
|
|
||||||
bool is_client_secret = !strncmp(line, "CLIENT_TRAFFIC_SECRET_0 ", strlen("CLIENT_TRAFFIC_SECRET_0 "));
|
|
||||||
bool is_server_secret = !strncmp(line, "SERVER_TRAFFIC_SECRET_0 ", strlen("SERVER_TRAFFIC_SECRET_0 "));
|
|
||||||
if (!is_client_secret && !is_server_secret)
|
|
||||||
return;
|
|
||||||
const char *hex = strchr(line+strlen("CLIENT_TRAFFIC_SECRET_0 "), ' ');
|
|
||||||
if (!hex)
|
|
||||||
return;
|
|
||||||
hex++;
|
|
||||||
size_t len = strlen(hex);
|
|
||||||
logged_secrets_mu.lock();
|
|
||||||
auto & secrets = logged_secrets[ssl];
|
|
||||||
logged_secrets_mu.unlock();
|
|
||||||
auto & secret = is_client_secret ? secrets.client_secret : secrets.server_secret;
|
|
||||||
secret.resize(len/2);
|
|
||||||
fromhexstr(hex, len, secret.data(), secret.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool derive_kdf(EVP_KDF_CTX* kdf_ctx, const uint8_t* insecret, size_t insecret_len,
|
|
||||||
const uint8_t* salt, size_t salt_len, const char *label, uint8_t *key, size_t size)
|
|
||||||
{
|
|
||||||
OSSL_PARAM params[5];
|
|
||||||
int n = 0;
|
|
||||||
params[n++] = OSSL_PARAM_construct_utf8_string("digest", (char*)"sha384", (size_t)7);
|
|
||||||
params[n++] = OSSL_PARAM_construct_octet_string("key", (void*)insecret, insecret_len);
|
|
||||||
params[n++] = OSSL_PARAM_construct_octet_string("info", (void*)label, strlen(label)+1);
|
|
||||||
if (salt)
|
|
||||||
params[n++] = OSSL_PARAM_construct_octet_string("salt", (void*)salt, salt_len);
|
|
||||||
params[n++] = OSSL_PARAM_construct_end();
|
|
||||||
assert(n <= sizeof(params)/sizeof(OSSL_PARAM));
|
|
||||||
if (EVP_KDF_CTX_set_params(kdf_ctx, params) <= 0)
|
|
||||||
{
|
|
||||||
ERR_print_errors_fp(stderr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (EVP_KDF_derive(kdf_ctx, key, size, NULL) <= 0)
|
|
||||||
{
|
|
||||||
ERR_print_errors_fp(stderr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool osd_messenger_t::derive_aes_keys(osd_client_t *cl, bool update_my, bool update_peer)
|
|
||||||
{
|
|
||||||
std::vector<uint8_t> old_my = cl->my_key, old_peer = cl->peer_key;
|
|
||||||
if (!cl->my_secret.size() || !cl->peer_secret.size())
|
|
||||||
{
|
|
||||||
assert(cl->ssl_cli);
|
|
||||||
logged_secrets_mu.lock();
|
|
||||||
auto & secrets = logged_secrets[cl->ssl_cli];
|
|
||||||
cl->my_secret = std::move(cl->is_incoming ? secrets.client_secret : secrets.server_secret);
|
|
||||||
cl->peer_secret = std::move(!cl->is_incoming ? secrets.client_secret : secrets.server_secret);
|
|
||||||
logged_secrets.erase(cl->ssl_cli);
|
|
||||||
logged_secrets_mu.unlock();
|
|
||||||
SSL_free(cl->ssl_cli);
|
|
||||||
cl->ssl_cli = NULL;
|
|
||||||
cl->gcm_enabled = true;
|
|
||||||
cl->write_to_ssl = NULL;
|
|
||||||
cl->read_from_ssl = NULL;
|
|
||||||
if (cl->my_secret.size() < 32 || cl->peer_secret.size() < 32)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Client %ju error: failed to capture TLS handshake results\n", cl->client_id);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Both keys include AES key and iv + xxhash3 secret
|
|
||||||
const auto len = AES_256_GCM_KEY_SIZE + AES_256_GCM_IV_SIZE + XXH_SECRET_DEFAULT_SIZE;
|
|
||||||
cl->my_key.resize(len);
|
|
||||||
cl->peer_key.resize(len);
|
|
||||||
bool ok = true;
|
|
||||||
if (update_my || !old_my.size())
|
|
||||||
{
|
|
||||||
ok = ok && derive_kdf(kdf_ctx, cl->my_secret.data(), cl->my_secret.size(),
|
|
||||||
old_my.size() ? old_my.data() : NULL, old_my.size(),
|
|
||||||
cl->is_incoming ? "server key" : "client key",
|
|
||||||
cl->my_key.data(), len);
|
|
||||||
#ifdef WITH_ISAL_CRYPTO
|
|
||||||
if (ok)
|
|
||||||
isal_aes_gcm_pre_256(cl->my_key.data(), &cl->my_key_isal);
|
|
||||||
#endif
|
|
||||||
cl->my_iv_ctr = 0;
|
|
||||||
}
|
|
||||||
if (update_peer || !old_peer.size())
|
|
||||||
{
|
|
||||||
ok = ok && derive_kdf(kdf_ctx, cl->peer_secret.data(), cl->peer_secret.size(),
|
|
||||||
old_peer.size() ? old_peer.data() : NULL, old_peer.size(),
|
|
||||||
!cl->is_incoming ? "server key" : "client key",
|
|
||||||
cl->peer_key.data(), len);
|
|
||||||
#ifdef WITH_ISAL_CRYPTO
|
|
||||||
if (ok)
|
|
||||||
isal_aes_gcm_pre_256(cl->peer_key.data(), &cl->peer_key_isal);
|
|
||||||
#endif
|
|
||||||
cl->peer_iv_ctr = 0;
|
|
||||||
}
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
void osd_messenger_t::init_tls()
|
|
||||||
{
|
|
||||||
if (!tls_cert.empty() || !tls_key.empty() || !osd_tls_ca.empty() || !client_tls_ca.empty())
|
|
||||||
{
|
|
||||||
// Initialize TLS context
|
|
||||||
if (tls_cert.empty() || tls_key.empty() || osd_tls_ca.empty() || osd_num && client_tls_ca.empty())
|
|
||||||
{
|
|
||||||
if (osd_num)
|
|
||||||
fprintf(stderr, "Vitastor OSD TLS requires osd_tls_cert, osd_tls_key, osd_tls_ca, client_tls_ca\n");
|
|
||||||
else
|
|
||||||
fprintf(stderr, "Vitastor client TLS requires tls_cert, tls_key and osd_tls_ca\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ssl_ctx = SSL_CTX_new(TLS_method());
|
|
||||||
if (!ssl_ctx)
|
|
||||||
{
|
|
||||||
init_err:
|
|
||||||
fprintf(stderr, "OpenSSL initialization failed: %s\n", ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
// Always use TLS 1.3 with AES-256-GCM
|
|
||||||
SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
|
|
||||||
SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION);
|
|
||||||
SSL_CTX_set_ciphersuites(ssl_ctx, "TLS_AES_256_GCM_SHA384");
|
|
||||||
SSL_CTX_set_keylog_callback(ssl_ctx, openssl_key_log);
|
|
||||||
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
|
|
||||||
bool ok = SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
|
|
||||||
ok = ok && (osd_tls_ca_obj = openssl_load_cert(osd_tls_ca));
|
|
||||||
ok = ok && X509_STORE_add_cert(SSL_CTX_get_cert_store(ssl_ctx), osd_tls_ca_obj);
|
|
||||||
if (osd_num)
|
|
||||||
{
|
|
||||||
// OSD uses 2 separate root certificates to distinguish between clients and peer OSDs
|
|
||||||
ok = ok && (client_tls_ca_obj = openssl_load_cert(client_tls_ca));
|
|
||||||
ok = ok && X509_STORE_add_cert(SSL_CTX_get_cert_store(ssl_ctx), client_tls_ca_obj);
|
|
||||||
}
|
|
||||||
ok = ok && openssl_ctx_use_cert(ssl_ctx, tls_cert, tls_cn);
|
|
||||||
ok = ok && openssl_ctx_use_key(ssl_ctx, tls_key);
|
|
||||||
EVP_KDF *kdf;
|
|
||||||
ok = ok && (kdf = EVP_KDF_fetch(NULL, "hkdf", NULL));
|
|
||||||
ok = ok && (kdf_ctx = EVP_KDF_CTX_new(kdf));
|
|
||||||
if (kdf)
|
|
||||||
EVP_KDF_free(kdf);
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
SSL_CTX_free(ssl_ctx);
|
|
||||||
ssl_ctx = NULL;
|
|
||||||
goto init_err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void osd_messenger_t::init_tls_client(osd_client_t *cl)
|
|
||||||
{
|
|
||||||
if (!tls_cert.empty())
|
|
||||||
{
|
|
||||||
cl->write_to_ssl = BIO_new(BIO_s_mem());
|
|
||||||
cl->read_from_ssl = BIO_new(BIO_s_mem());
|
|
||||||
cl->ssl_cli = SSL_new(ssl_ctx);
|
|
||||||
cl->ssl_handshake_pending = MSGR_HSP_HS;
|
|
||||||
if (!cl->ssl_cli)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "OpenSSL initialization failed: %s\n", ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (cl->is_incoming)
|
|
||||||
{
|
|
||||||
SSL_set_accept_state(cl->ssl_cli);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SSL_set_connect_state(cl->ssl_cli);
|
|
||||||
}
|
|
||||||
SSL_set_bio(cl->ssl_cli, cl->write_to_ssl, cl->read_from_ssl);
|
|
||||||
bool ok = do_tls_handshake(cl);
|
|
||||||
assert(ok);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool osd_messenger_t::do_tls_handshake(osd_client_t *cl, bool from_recv)
|
|
||||||
{
|
|
||||||
if (!(cl->ssl_handshake_pending & MSGR_HSP_HS))
|
|
||||||
return true;
|
|
||||||
int r = SSL_do_handshake(cl->ssl_cli);
|
|
||||||
if (r > 0)
|
|
||||||
{
|
|
||||||
// Server-side OpenSSL treats handshake as finalized only when receiving
|
|
||||||
// the first message, so we transmit 1 byte after connecting and only then
|
|
||||||
// finalize the handshake
|
|
||||||
cl->ssl_handshake_pending = MSGR_HSP_SEND|MSGR_HSP_RECV;
|
|
||||||
if (cl->write_state == 0 && from_recv)
|
|
||||||
{
|
|
||||||
cl->write_state = CL_WRITE_READY;
|
|
||||||
write_ready_clients.push_back(cl->client_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
r = SSL_get_error(cl->ssl_cli, r);
|
|
||||||
if (r != 0 && r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Client %ju TLS handshake error: %s, stopping client\n", cl->client_id, ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
cl->io_error = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (from_recv && cl->write_state == 0 && openssl_bio_nonempty(cl->read_from_ssl))
|
|
||||||
{
|
|
||||||
cl->write_state = CL_WRITE_READY;
|
|
||||||
write_ready_clients.push_back(cl->client_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool osd_messenger_t::finalize_tls_handshake(osd_client_t *cl)
|
|
||||||
{
|
|
||||||
if (cl->ssl_handshake_pending)
|
|
||||||
return true;
|
|
||||||
// Capture secrets and switch to direct AES-256-GCM encryption
|
|
||||||
if (!derive_aes_keys(cl, true, true))
|
|
||||||
{
|
|
||||||
cl->io_error = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (cl->read_op)
|
|
||||||
{
|
|
||||||
assert(!cl->read_op_pos);
|
|
||||||
delete cl->read_op;
|
|
||||||
cl->read_op = NULL;
|
|
||||||
}
|
|
||||||
if (cl->write_op)
|
|
||||||
{
|
|
||||||
assert(!cl->write_op_pos);
|
|
||||||
cl->write_ops.insert(cl->write_ops.begin(), cl->write_op);
|
|
||||||
cl->write_op = NULL;
|
|
||||||
}
|
|
||||||
if (cl->write_state == 0)
|
|
||||||
{
|
|
||||||
cl->write_state = CL_WRITE_READY;
|
|
||||||
write_ready_clients.push_back(cl->client_id);
|
|
||||||
}
|
|
||||||
// Switched to direct AES-GCM, stop SSL callers
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void osd_messenger_t::destroy_tls()
|
|
||||||
{
|
|
||||||
#ifdef WITH_ISAL_CRYPTO
|
|
||||||
for (isal_gcm_context_data *ctx: encrypt_gcm_pool)
|
|
||||||
{
|
|
||||||
free(ctx);
|
|
||||||
}
|
|
||||||
for (isal_gcm_context_data *ctx: decrypt_gcm_pool)
|
|
||||||
{
|
|
||||||
free(ctx);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
for (EVP_CIPHER_CTX *ctx: encrypt_gcm_pool)
|
|
||||||
{
|
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
|
||||||
}
|
|
||||||
for (EVP_CIPHER_CTX *ctx: decrypt_gcm_pool)
|
|
||||||
{
|
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (osd_tls_ca_obj)
|
|
||||||
{
|
|
||||||
X509_free(osd_tls_ca_obj);
|
|
||||||
osd_tls_ca_obj = NULL;
|
|
||||||
}
|
|
||||||
if (client_tls_ca_obj)
|
|
||||||
{
|
|
||||||
X509_free(client_tls_ca_obj);
|
|
||||||
client_tls_ca_obj = NULL;
|
|
||||||
}
|
|
||||||
if (ssl_ctx)
|
|
||||||
{
|
|
||||||
SSL_CTX_free(ssl_ctx);
|
|
||||||
ssl_ctx = NULL;
|
|
||||||
}
|
|
||||||
if (kdf_ctx)
|
|
||||||
{
|
|
||||||
EVP_KDF_CTX_free(kdf_ctx);
|
|
||||||
kdf_ctx = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
osd_op_t::~osd_op_t()
|
osd_op_t::~osd_op_t()
|
||||||
{
|
{
|
||||||
assert(!bs_op);
|
assert(!bs_op);
|
||||||
assert(!op_data);
|
|
||||||
if (bitmap_buf)
|
if (bitmap_buf)
|
||||||
{
|
{
|
||||||
free(bitmap_buf);
|
free(bitmap_buf);
|
||||||
@@ -27,6 +26,10 @@ osd_op_t::~osd_op_t()
|
|||||||
{
|
{
|
||||||
free(enc_buf);
|
free(enc_buf);
|
||||||
}
|
}
|
||||||
|
if (op_data)
|
||||||
|
{
|
||||||
|
free(op_data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool osd_op_t::is_recovery_related()
|
bool osd_op_t::is_recovery_related()
|
||||||
|
|||||||
@@ -590,7 +590,36 @@ void osd_messenger_t::try_send_rdma(osd_client_t *cl)
|
|||||||
while (!rc->send_out_full && copied > 0 && rc->cur_send < rc->max_send)
|
while (!rc->send_out_full && copied > 0 && rc->cur_send < rc->max_send)
|
||||||
{
|
{
|
||||||
dst = (uint8_t*)rc->send_out.buf + rc->send_out_pos;
|
dst = (uint8_t*)rc->send_out.buf + rc->send_out_pos;
|
||||||
dst_len = (rc->send_out_pos < rc->send_out_size ? rc->send_out_size-rc->send_out_pos : rc->send_done_pos-rc->send_out_pos);
|
if (rc->send_out_pos >= rc->send_done_pos)
|
||||||
|
{
|
||||||
|
dst_len = rc->send_out_size-rc->send_out_pos;
|
||||||
|
if (dst_len < 4096)
|
||||||
|
{
|
||||||
|
// free end of the buffer is too small, skip
|
||||||
|
rc->send_out_pos = 0;
|
||||||
|
if (rc->send_out_pos >= rc->send_done_pos)
|
||||||
|
rc->send_out_full = true;
|
||||||
|
if (!rc->send_sizes.size())
|
||||||
|
{
|
||||||
|
rc->send_done_pos += dst_len;
|
||||||
|
rc->send_out_full = false;
|
||||||
|
if (rc->send_done_pos == rc->send_out_size)
|
||||||
|
rc->send_done_pos = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rc->send_sizes.back() += dst_len;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dst_len = rc->send_done_pos-rc->send_out_pos;
|
||||||
|
if (dst_len < 4096)
|
||||||
|
{
|
||||||
|
// too small buffer, stop
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (dst_len > rc->max_msg)
|
if (dst_len > rc->max_msg)
|
||||||
dst_len = rc->max_msg;
|
dst_len = rc->max_msg;
|
||||||
copied = copy_ops_to(cl, dst, dst_len);
|
copied = copy_ops_to(cl, dst, dst_len);
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ struct rdmacm_connecting_t
|
|||||||
int tcp_port = 0;
|
int tcp_port = 0;
|
||||||
int timeout_ms = 0;
|
int timeout_ms = 0;
|
||||||
int timeout_id = -1;
|
int timeout_id = -1;
|
||||||
bool is_incoming = false;
|
|
||||||
msgr_rdma_context_t *rdma_context = NULL;
|
msgr_rdma_context_t *rdma_context = NULL;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -293,7 +292,6 @@ void osd_messenger_t::rdmacm_accept(rdma_cm_event *ev)
|
|||||||
conn->client_id = next_client_id++;
|
conn->client_id = next_client_id++;
|
||||||
conn->parsed_addr = *(sockaddr_storage*)rdma_get_peer_addr(ev->id);
|
conn->parsed_addr = *(sockaddr_storage*)rdma_get_peer_addr(ev->id);
|
||||||
conn->rdma_context = rdma_context;
|
conn->rdma_context = rdma_context;
|
||||||
conn->is_incoming = true;
|
|
||||||
rdmacm_set_conn_timeout(conn);
|
rdmacm_set_conn_timeout(conn);
|
||||||
rdmacm_connecting[ev->id] = conn;
|
rdmacm_connecting[ev->id] = conn;
|
||||||
fprintf(stderr, "[OSD %ju] new client %ju: connection from %s via RDMA-CM\n", this->osd_num, conn->client_id,
|
fprintf(stderr, "[OSD %ju] new client %ju: connection from %s via RDMA-CM\n", this->osd_num, conn->client_id,
|
||||||
@@ -494,13 +492,11 @@ void osd_messenger_t::rdmacm_established(rdma_cm_event *ev)
|
|||||||
cl->peer_addr = conn->parsed_addr;
|
cl->peer_addr = conn->parsed_addr;
|
||||||
cl->peer_port = conn->rdmacm_port;
|
cl->peer_port = conn->rdmacm_port;
|
||||||
cl->client_id = conn->client_id;
|
cl->client_id = conn->client_id;
|
||||||
cl->is_incoming = conn->is_incoming;
|
|
||||||
cl->peer_state = PEER_RDMA;
|
cl->peer_state = PEER_RDMA;
|
||||||
cl->connect_timeout_id = -1;
|
cl->connect_timeout_id = -1;
|
||||||
cl->osd_num = peer_osd;
|
cl->osd_num = peer_osd;
|
||||||
cl->in_buf = (uint8_t*)malloc_or_die(receive_buffer_size);
|
cl->in_buf = (uint8_t*)malloc_or_die(receive_buffer_size);
|
||||||
cl->rdma_conn = rc;
|
cl->rdma_conn = rc;
|
||||||
init_tls_client(cl);
|
|
||||||
clients[conn->client_id] = cl;
|
clients[conn->client_id] = cl;
|
||||||
if (conn->timeout_id >= 0)
|
if (conn->timeout_id >= 0)
|
||||||
{
|
{
|
||||||
|
|||||||
+60
-94
@@ -4,21 +4,16 @@
|
|||||||
#define _XOPEN_SOURCE
|
#define _XOPEN_SOURCE
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include "messenger.h"
|
#include "messenger.h"
|
||||||
#include "openssl_util.h"
|
|
||||||
|
|
||||||
#include <openssl/bio.h>
|
#include <openssl/bio.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
|
|
||||||
#define RDR_GCM 1
|
#define RDR_TLS 1
|
||||||
#define RDR_XTS 2
|
#define RDR_XTS 2
|
||||||
#define RDR_NO_CSUM 4
|
#define RDR_NO_CSUM 4
|
||||||
|
|
||||||
#define MSGR_HSP_HS 1
|
|
||||||
#define MSGR_HSP_SEND 2
|
|
||||||
#define MSGR_HSP_RECV 4
|
|
||||||
|
|
||||||
class msgr_op_reader_t
|
class msgr_op_reader_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -104,30 +99,6 @@ class ssl_op_reader_t: public msgr_op_reader_t
|
|||||||
size_t bufsize;
|
size_t bufsize;
|
||||||
size_t done;
|
size_t done;
|
||||||
|
|
||||||
bool read_ssl(void *buf, size_t & len)
|
|
||||||
{
|
|
||||||
int ok = SSL_read_ex(cl->ssl_cli, buf, len, &len);
|
|
||||||
if (ok > 0)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
len = 0;
|
|
||||||
ok = SSL_get_error(cl->ssl_cli, ok);
|
|
||||||
if (ok == SSL_ERROR_ZERO_RETURN)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Client %ju TLS disconnected\n", cl->client_id);
|
|
||||||
cl->io_error = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (ok != 0 && ok != SSL_ERROR_WANT_WRITE && ok != SSL_ERROR_WANT_READ)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Client %ju TLS read error: %s. Disconnecting client\n", cl->client_id, ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
cl->io_error = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ssl_op_reader_t(osd_messenger_t* msgr, osd_client_t* cl, uint8_t *curbuf, size_t bufsize):
|
ssl_op_reader_t(osd_messenger_t* msgr, osd_client_t* cl, uint8_t *curbuf, size_t bufsize):
|
||||||
msgr(msgr), cl(cl), from(cl->read_op_pos), curbuf(curbuf), bufsize(bufsize), done(0)
|
msgr(msgr), cl(cl), from(cl->read_op_pos), curbuf(curbuf), bufsize(bufsize), done(0)
|
||||||
@@ -195,7 +166,7 @@ public:
|
|||||||
if (done >= bufsize)
|
if (done >= bufsize)
|
||||||
return false;
|
return false;
|
||||||
size_t n = dst_len-from;
|
size_t n = dst_len-from;
|
||||||
if (!(flags & RDR_GCM) || !cl->ssl_cli)
|
if (!(flags & RDR_TLS) || !cl->ssl_cli)
|
||||||
{
|
{
|
||||||
if (n > bufsize-done)
|
if (n > bufsize-done)
|
||||||
n = bufsize-done;
|
n = bufsize-done;
|
||||||
@@ -229,31 +200,42 @@ public:
|
|||||||
assert(dst != NULL);
|
assert(dst != NULL);
|
||||||
buffer_again:
|
buffer_again:
|
||||||
buffer_encrypted();
|
buffer_encrypted();
|
||||||
if (cl->ssl_handshake_pending)
|
if (!cl->ssl_handshake_done)
|
||||||
{
|
{
|
||||||
if (!msgr->do_tls_handshake(cl, true))
|
if (!msgr->ssl_do_handshake(cl))
|
||||||
return false;
|
return false;
|
||||||
if (cl->ssl_handshake_pending & MSGR_HSP_RECV)
|
if (cl->write_state == 0)
|
||||||
{
|
{
|
||||||
uint8_t first_byte = 0;
|
// SSL_ERROR_WANT_WRITE is absolutely non-informative with memory BIO, it basically never happens
|
||||||
size_t b = 1;
|
// So we have to check memory BIO for outstanding data
|
||||||
if (!read_ssl(&first_byte, b))
|
char *bio_buf = NULL;
|
||||||
return false;
|
size_t bio_sz = BIO_get_mem_data(cl->read_from_ssl, &bio_buf);
|
||||||
if (!b)
|
if (bio_sz > 0)
|
||||||
{
|
{
|
||||||
if (done < bufsize)
|
cl->write_state = CL_WRITE_READY;
|
||||||
goto buffer_again;
|
msgr->write_ready_clients.push_back(cl->client_id);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
cl->ssl_handshake_pending &= ~MSGR_HSP_RECV;
|
|
||||||
if (!msgr->finalize_tls_handshake(cl))
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!read_ssl(dst+from, n))
|
int ok = SSL_read_ex(cl->ssl_cli, dst+from, n, &n);
|
||||||
|
if (!ok)
|
||||||
{
|
{
|
||||||
if (done < bufsize)
|
ok = SSL_get_error(cl->ssl_cli, ok);
|
||||||
goto buffer_again;
|
if (ok == SSL_ERROR_WANT_READ)
|
||||||
|
{
|
||||||
|
if (done < bufsize)
|
||||||
|
goto buffer_again;
|
||||||
|
}
|
||||||
|
else if (ok == SSL_ERROR_ZERO_RETURN)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Client %ju TLS disconnected\n", cl->client_id);
|
||||||
|
cl->io_error = true;
|
||||||
|
}
|
||||||
|
else if (ok != 0 && ok != SSL_ERROR_WANT_WRITE)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Client %ju TLS read error: %s. Disconnecting client\n", cl->client_id, ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
cl->io_error = true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (cl->read_csum_state && !(flags & RDR_NO_CSUM))
|
if (cl->read_csum_state && !(flags & RDR_NO_CSUM))
|
||||||
@@ -327,15 +309,16 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
uint8_t iv[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
|
||||||
#ifdef WITH_ISAL_CRYPTO
|
#ifdef WITH_ISAL_CRYPTO
|
||||||
int r = isal_aes_gcm_init_256(&cl->peer_key_isal, cl->dec_ctx, cl->peer_key.data() + AES_256_GCM_KEY_SIZE, NULL, 0);
|
int r = isal_aes_gcm_init_256(&msgr->test_osd_aes_key_isal, cl->dec_ctx, iv, NULL, 0);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "isal_aes_gcm_init_256 error %d\n", r);
|
fprintf(stderr, "isal_aes_gcm_init_256 error %d\n", r);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int r = EVP_DecryptInit_ex(cl->dec_ctx, NULL, NULL, cl->peer_key.data(), cl->peer_key.data() + AES_256_GCM_KEY_SIZE);
|
int r = EVP_DecryptInit_ex(cl->dec_ctx, NULL, NULL, (uint8_t*)msgr->test_osd_aes_key.data(), iv);
|
||||||
if (r != 1)
|
if (r != 1)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "DecryptInit error: ");
|
fprintf(stderr, "DecryptInit error: ");
|
||||||
@@ -343,9 +326,6 @@ public:
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// Increase IV
|
|
||||||
cl->peer_iv_ctr++;
|
|
||||||
(*(uint64_t*)(cl->peer_key.data() + AES_256_GCM_KEY_SIZE))++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool read(uint8_t *dst, size_t dst_len, int flags) override
|
bool read(uint8_t *dst, size_t dst_len, int flags) override
|
||||||
@@ -359,7 +339,7 @@ public:
|
|||||||
if (done >= bufsize)
|
if (done >= bufsize)
|
||||||
return false;
|
return false;
|
||||||
size_t n = dst_len-from;
|
size_t n = dst_len-from;
|
||||||
if (!(flags & RDR_GCM))
|
if (!(flags & RDR_TLS))
|
||||||
{
|
{
|
||||||
if (n > bufsize-done)
|
if (n > bufsize-done)
|
||||||
n = bufsize-done;
|
n = bufsize-done;
|
||||||
@@ -395,7 +375,7 @@ public:
|
|||||||
if (n > bufsize-done)
|
if (n > bufsize-done)
|
||||||
n = bufsize-done;
|
n = bufsize-done;
|
||||||
#ifdef WITH_ISAL_CRYPTO
|
#ifdef WITH_ISAL_CRYPTO
|
||||||
int r = isal_aes_gcm_dec_256_update(&cl->peer_key_isal, cl->dec_ctx, dst+from, curbuf+done, n);
|
int r = isal_aes_gcm_dec_256_update(&msgr->test_osd_aes_key_isal, cl->dec_ctx, dst+from, curbuf+done, n);
|
||||||
assert(!r);
|
assert(!r);
|
||||||
#else
|
#else
|
||||||
int actual_out;
|
int actual_out;
|
||||||
@@ -435,7 +415,7 @@ public:
|
|||||||
}
|
}
|
||||||
#ifdef WITH_ISAL_CRYPTO
|
#ifdef WITH_ISAL_CRYPTO
|
||||||
uint8_t calc_tag[16];
|
uint8_t calc_tag[16];
|
||||||
int r = isal_aes_gcm_dec_256_finalize(&cl->peer_key_isal, cl->dec_ctx, calc_tag, 16);
|
int r = isal_aes_gcm_dec_256_finalize(&msgr->test_osd_aes_key_isal, cl->dec_ctx, calc_tag, 16);
|
||||||
assert(r == 0);
|
assert(r == 0);
|
||||||
if (cl->dec_tag_size > 0)
|
if (cl->dec_tag_size > 0)
|
||||||
{
|
{
|
||||||
@@ -548,15 +528,17 @@ public:
|
|||||||
|
|
||||||
bool read(uint8_t *dst, size_t dst_len, int flags) override
|
bool read(uint8_t *dst, size_t dst_len, int flags) override
|
||||||
{
|
{
|
||||||
|
if (cl->gcm_enabled)
|
||||||
|
return false; // FIXME Only for tests, use copy-only with AES
|
||||||
if (from >= dst_len)
|
if (from >= dst_len)
|
||||||
{
|
{
|
||||||
// Skip
|
// Skip
|
||||||
from -= dst_len;
|
from -= dst_len;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((flags & RDR_GCM) && (cl->ssl_cli || cl->gcm_enabled))
|
if ((flags & RDR_TLS) && cl->ssl_cli)
|
||||||
{
|
{
|
||||||
// Can't inplace read TLS/GCM data
|
// Can't inplace read TLS data
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (cl->recv_list.size() >= IOV_MAX)
|
if (cl->recv_list.size() >= IOV_MAX)
|
||||||
@@ -776,29 +758,15 @@ void osd_messenger_t::handle_immediate_ops()
|
|||||||
|
|
||||||
bool osd_messenger_t::handle_read_buffer(osd_client_t *cl, uint8_t *curbuf, size_t bufsize)
|
bool osd_messenger_t::handle_read_buffer(osd_client_t *cl, uint8_t *curbuf, size_t bufsize)
|
||||||
{
|
{
|
||||||
size_t done;
|
if (cl->gcm_enabled)
|
||||||
if (cl->ssl_cli)
|
|
||||||
{
|
{
|
||||||
done = handle_buffer_with<ssl_op_reader_t>(cl, curbuf, bufsize);
|
return handle_buffer_with<gcm_op_reader_t>(cl, curbuf, bufsize);
|
||||||
if (done > 0 && done < bufsize && !cl->ssl_cli && cl->gcm_enabled)
|
|
||||||
{
|
|
||||||
done += handle_buffer_with<gcm_op_reader_t>(cl, curbuf+done, bufsize-done);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (cl->gcm_enabled)
|
return handle_buffer_with<copy_op_reader_t>(cl, curbuf, bufsize);
|
||||||
{
|
|
||||||
done = handle_buffer_with<gcm_op_reader_t>(cl, curbuf, bufsize);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
done = handle_buffer_with<copy_op_reader_t>(cl, curbuf, bufsize);
|
|
||||||
}
|
|
||||||
assert(!done || done == bufsize);
|
|
||||||
return !!done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
size_t osd_messenger_t::handle_buffer_with(osd_client_t *cl, uint8_t *curbuf, size_t bufsize)
|
bool osd_messenger_t::handle_buffer_with(osd_client_t *cl, uint8_t *curbuf, size_t bufsize)
|
||||||
{
|
{
|
||||||
T rdr(this, cl, curbuf, bufsize);
|
T rdr(this, cl, curbuf, bufsize);
|
||||||
// Reset OSD ping state
|
// Reset OSD ping state
|
||||||
@@ -822,22 +790,20 @@ size_t osd_messenger_t::handle_buffer_with(osd_client_t *cl, uint8_t *curbuf, si
|
|||||||
{
|
{
|
||||||
if (!cl->read_csum_state)
|
if (!cl->read_csum_state)
|
||||||
cl->read_csum_state = XXH3_createState();
|
cl->read_csum_state = XXH3_createState();
|
||||||
if (cl->peer_key.size() == AES_256_GCM_KEY_SIZE + AES_256_GCM_IV_SIZE + XXH_SECRET_DEFAULT_SIZE)
|
XXH3_64bits_reset(cl->read_csum_state);
|
||||||
XXH3_64bits_reset_withSecret(cl->read_csum_state, cl->peer_key.data() + AES_256_GCM_KEY_SIZE + AES_256_GCM_IV_SIZE, XXH_SECRET_DEFAULT_SIZE);
|
|
||||||
else
|
|
||||||
XXH3_64bits_reset(cl->read_csum_state);
|
|
||||||
}
|
}
|
||||||
if (!op_read_from(cl, rdr) || !handle_finished_op(cl))
|
if (!op_read_from(cl, rdr) || !handle_finished_op(cl))
|
||||||
{
|
{
|
||||||
if (cl->io_error)
|
if (cl->io_error)
|
||||||
{
|
{
|
||||||
stop_client(cl->client_id);
|
stop_client(cl->client_id);
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rdr.get_done();
|
assert(rdr.get_done() == bufsize);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool osd_messenger_t::handle_hdr(osd_client_t *cl)
|
bool osd_messenger_t::handle_hdr(osd_client_t *cl)
|
||||||
@@ -1016,7 +982,7 @@ bool osd_messenger_t::op_read_from(osd_client_t *cl, msgr_op_reader_t & rdr)
|
|||||||
bool hdr = (cl->read_op_pos < OSD_PACKET_SIZE);
|
bool hdr = (cl->read_op_pos < OSD_PACKET_SIZE);
|
||||||
if (hdr || op->op_type == OSD_OP_IN)
|
if (hdr || op->op_type == OSD_OP_IN)
|
||||||
{
|
{
|
||||||
if (!rdr.read(op->req.buf, OSD_PACKET_SIZE, RDR_GCM | (cl->proto_csum_status == MSGR_CSUM_PAYLOAD ? RDR_NO_CSUM : 0)))
|
if (!rdr.read(op->req.buf, OSD_PACKET_SIZE, RDR_TLS | (cl->proto_csum_status == MSGR_CSUM_PAYLOAD ? RDR_NO_CSUM : 0)))
|
||||||
return false;
|
return false;
|
||||||
if (hdr)
|
if (hdr)
|
||||||
{
|
{
|
||||||
@@ -1032,7 +998,7 @@ bool osd_messenger_t::op_read_from(osd_client_t *cl, msgr_op_reader_t & rdr)
|
|||||||
if (op->req.hdr.opcode == OSD_OP_SEC_WRITE ||
|
if (op->req.hdr.opcode == OSD_OP_SEC_WRITE ||
|
||||||
op->req.hdr.opcode == OSD_OP_SEC_WRITE_STABLE)
|
op->req.hdr.opcode == OSD_OP_SEC_WRITE_STABLE)
|
||||||
{
|
{
|
||||||
if (!rdr.read((uint8_t*)op->bitmap, op->req.sec_rw.attr_len, RDR_GCM))
|
if (!rdr.read((uint8_t*)op->bitmap, op->req.sec_rw.attr_len, RDR_TLS))
|
||||||
return false;
|
return false;
|
||||||
if (!rdr.read((uint8_t*)op->buf, op->req.sec_rw.len, 0))
|
if (!rdr.read((uint8_t*)op->buf, op->req.sec_rw.len, 0))
|
||||||
return false;
|
return false;
|
||||||
@@ -1040,12 +1006,12 @@ bool osd_messenger_t::op_read_from(osd_client_t *cl, msgr_op_reader_t & rdr)
|
|||||||
else if (op->req.hdr.opcode == OSD_OP_SEC_STABILIZE ||
|
else if (op->req.hdr.opcode == OSD_OP_SEC_STABILIZE ||
|
||||||
op->req.hdr.opcode == OSD_OP_SEC_ROLLBACK)
|
op->req.hdr.opcode == OSD_OP_SEC_ROLLBACK)
|
||||||
{
|
{
|
||||||
if (!rdr.read((uint8_t*)op->buf, op->req.sec_stab.len, RDR_GCM))
|
if (!rdr.read((uint8_t*)op->buf, op->req.sec_stab.len, RDR_TLS))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (op->req.hdr.opcode == OSD_OP_SEC_READ_BMP)
|
else if (op->req.hdr.opcode == OSD_OP_SEC_READ_BMP)
|
||||||
{
|
{
|
||||||
if (!rdr.read((uint8_t*)op->buf, op->req.sec_read_bmp.len, RDR_GCM))
|
if (!rdr.read((uint8_t*)op->buf, op->req.sec_read_bmp.len, RDR_TLS))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (op->req.hdr.opcode == OSD_OP_WRITE)
|
else if (op->req.hdr.opcode == OSD_OP_WRITE)
|
||||||
@@ -1055,20 +1021,20 @@ bool osd_messenger_t::op_read_from(osd_client_t *cl, msgr_op_reader_t & rdr)
|
|||||||
}
|
}
|
||||||
else if (op->req.hdr.opcode == OSD_OP_SHOW_CONFIG)
|
else if (op->req.hdr.opcode == OSD_OP_SHOW_CONFIG)
|
||||||
{
|
{
|
||||||
if (!rdr.read((uint8_t*)op->buf, op->req.show_conf.json_len, RDR_GCM))
|
if (!rdr.read((uint8_t*)op->buf, op->req.show_conf.json_len, RDR_TLS))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!rdr.read(op->reply.buf, OSD_PACKET_SIZE, RDR_GCM | (cl->proto_csum_status == MSGR_CSUM_PAYLOAD ? RDR_NO_CSUM : 0)))
|
if (!rdr.read(op->reply.buf, OSD_PACKET_SIZE, RDR_TLS | (cl->proto_csum_status == MSGR_CSUM_PAYLOAD ? RDR_NO_CSUM : 0)))
|
||||||
return false;
|
return false;
|
||||||
switched_type:
|
switched_type:
|
||||||
if (op->reply.hdr.opcode == OSD_OP_SEC_READ)
|
if (op->reply.hdr.opcode == OSD_OP_SEC_READ)
|
||||||
{
|
{
|
||||||
if (op->reply.sec_rw.attr_len > 0)
|
if (op->reply.sec_rw.attr_len > 0)
|
||||||
{
|
{
|
||||||
if (!rdr.read((uint8_t*)op->bitmap, op->reply.sec_rw.attr_len, RDR_GCM))
|
if (!rdr.read((uint8_t*)op->bitmap, op->reply.sec_rw.attr_len, RDR_TLS))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (op->reply.hdr.retval > 0)
|
if (op->reply.hdr.retval > 0)
|
||||||
@@ -1082,7 +1048,7 @@ switched_type:
|
|||||||
{
|
{
|
||||||
if (op->reply.rw.bitmap_len > 0)
|
if (op->reply.rw.bitmap_len > 0)
|
||||||
{
|
{
|
||||||
if (!rdr.read((uint8_t*)op->bitmap, op->reply.rw.bitmap_len, RDR_GCM))
|
if (!rdr.read((uint8_t*)op->bitmap, op->reply.rw.bitmap_len, RDR_TLS))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (op->reply.hdr.retval > 0)
|
if (op->reply.hdr.retval > 0)
|
||||||
@@ -1094,25 +1060,25 @@ switched_type:
|
|||||||
}
|
}
|
||||||
else if (op->reply.hdr.opcode == OSD_OP_SEC_LIST && op->reply.hdr.retval > 0)
|
else if (op->reply.hdr.opcode == OSD_OP_SEC_LIST && op->reply.hdr.retval > 0)
|
||||||
{
|
{
|
||||||
if (!rdr.read((uint8_t*)op->buf, sizeof(obj_ver_id) * op->reply.hdr.retval, RDR_GCM))
|
if (!rdr.read((uint8_t*)op->buf, sizeof(obj_ver_id) * op->reply.hdr.retval, RDR_TLS))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if ((op->reply.hdr.opcode == OSD_OP_SEC_READ_BMP ||
|
else if ((op->reply.hdr.opcode == OSD_OP_SEC_READ_BMP ||
|
||||||
op->reply.hdr.opcode == OSD_OP_SHOW_CONFIG) && op->reply.hdr.retval > 0)
|
op->reply.hdr.opcode == OSD_OP_SHOW_CONFIG) && op->reply.hdr.retval > 0)
|
||||||
{
|
{
|
||||||
if (!rdr.read((uint8_t*)op->buf, op->reply.hdr.retval, RDR_GCM))
|
if (!rdr.read((uint8_t*)op->buf, op->reply.hdr.retval, RDR_TLS))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (op->reply.hdr.opcode == OSD_OP_DESCRIBE && op->reply.describe.result_bytes > 0)
|
else if (op->reply.hdr.opcode == OSD_OP_DESCRIBE && op->reply.describe.result_bytes > 0)
|
||||||
{
|
{
|
||||||
if (!rdr.read((uint8_t*)op->buf, op->reply.describe.result_bytes, RDR_GCM))
|
if (!rdr.read((uint8_t*)op->buf, op->reply.describe.result_bytes, RDR_TLS))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cl->proto_csum_status == MSGR_CSUM_FULL ||
|
if (cl->proto_csum_status == MSGR_CSUM_FULL ||
|
||||||
cl->read_op_size > 0 && cl->proto_csum_status == MSGR_CSUM_PAYLOAD)
|
cl->read_op_size > 0 && cl->proto_csum_status == MSGR_CSUM_PAYLOAD)
|
||||||
{
|
{
|
||||||
if (!rdr.read((uint8_t*)&op->csum, 8, RDR_GCM|RDR_NO_CSUM))
|
if (!rdr.read((uint8_t*)&op->csum, 8, RDR_TLS|RDR_NO_CSUM))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!rdr.finish())
|
if (!rdr.finish())
|
||||||
|
|||||||
+95
-119
@@ -12,14 +12,10 @@
|
|||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
|
|
||||||
#define WR_GCM 1
|
#define WR_TLS 1
|
||||||
#define WR_XTS 2
|
#define WR_XTS 2
|
||||||
#define WR_NO_CSUM 4
|
#define WR_NO_CSUM 4
|
||||||
|
|
||||||
#define MSGR_HSP_HS 1
|
|
||||||
#define MSGR_HSP_SEND 2
|
|
||||||
#define MSGR_HSP_RECV 4
|
|
||||||
|
|
||||||
class msgr_op_writer_t
|
class msgr_op_writer_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -39,8 +35,6 @@ protected:
|
|||||||
size_t done;
|
size_t done;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr static bool is_ssl = false;
|
|
||||||
|
|
||||||
copy_op_writer_t(osd_messenger_t* msgr, osd_client_t* cl, uint8_t *curbuf, size_t bufsize):
|
copy_op_writer_t(osd_messenger_t* msgr, osd_client_t* cl, uint8_t *curbuf, size_t bufsize):
|
||||||
msgr(msgr), cl(cl), from(cl->write_op_pos), curbuf(curbuf), bufsize(bufsize), done(0)
|
msgr(msgr), cl(cl), from(cl->write_op_pos), curbuf(curbuf), bufsize(bufsize), done(0)
|
||||||
{}
|
{}
|
||||||
@@ -101,8 +95,6 @@ class ssl_op_writer_t: public msgr_op_writer_t
|
|||||||
size_t done;
|
size_t done;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr static bool is_ssl = true;
|
|
||||||
|
|
||||||
ssl_op_writer_t(osd_messenger_t* msgr, osd_client_t* cl, uint8_t *curbuf, size_t bufsize):
|
ssl_op_writer_t(osd_messenger_t* msgr, osd_client_t* cl, uint8_t *curbuf, size_t bufsize):
|
||||||
msgr(msgr), cl(cl), from(cl->write_op_pos), curbuf(curbuf), bufsize(bufsize), done(0)
|
msgr(msgr), cl(cl), from(cl->write_op_pos), curbuf(curbuf), bufsize(bufsize), done(0)
|
||||||
{
|
{
|
||||||
@@ -113,29 +105,14 @@ public:
|
|||||||
from = cl->write_op_pos;
|
from = cl->write_op_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool flush_ssl()
|
void flush_ssl()
|
||||||
{
|
{
|
||||||
if (cl->ssl_handshake_pending)
|
if (!cl->ssl_handshake_done)
|
||||||
{
|
{
|
||||||
if (!msgr->do_tls_handshake(cl))
|
if (!msgr->ssl_do_handshake(cl))
|
||||||
return false;
|
return;
|
||||||
if (cl->ssl_handshake_pending & MSGR_HSP_SEND)
|
|
||||||
{
|
|
||||||
uint8_t first_byte = 0;
|
|
||||||
size_t f = 0;
|
|
||||||
if (!write_to_ssl(cl, &first_byte, 1, 0, f))
|
|
||||||
return false;
|
|
||||||
cl->write_op_pos--;
|
|
||||||
if (!_flush_ssl())
|
|
||||||
return false;
|
|
||||||
cl->ssl_handshake_pending &= ~MSGR_HSP_SEND;
|
|
||||||
if (!msgr->finalize_tls_handshake(cl))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (!_flush_ssl())
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return true;
|
_flush_ssl();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _flush_ssl()
|
bool _flush_ssl()
|
||||||
@@ -154,8 +131,6 @@ public:
|
|||||||
cl->ssl_more_to_buffer = true;
|
cl->ssl_more_to_buffer = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
cl->ssl_more_to_buffer = false;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -199,7 +174,7 @@ public:
|
|||||||
from -= src_len;
|
from -= src_len;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!(flags & WR_GCM) || !cl->ssl_cli)
|
if (!(flags & WR_TLS) || !cl->ssl_cli)
|
||||||
{
|
{
|
||||||
if (flags & WR_XTS)
|
if (flags & WR_XTS)
|
||||||
{
|
{
|
||||||
@@ -220,12 +195,12 @@ public:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (cl->ssl_handshake_pending)
|
if (!cl->ssl_handshake_done)
|
||||||
{
|
{
|
||||||
if (!_flush_ssl())
|
if (!msgr->ssl_do_handshake(cl))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!cl->ssl_handshake_pending)
|
if (cl->ssl_handshake_done)
|
||||||
{
|
{
|
||||||
if (!write_to_ssl(cl, src, src_len, flags, from))
|
if (!write_to_ssl(cl, src, src_len, flags, from))
|
||||||
return false;
|
return false;
|
||||||
@@ -261,8 +236,6 @@ class gcm_op_writer_t: public msgr_op_writer_t
|
|||||||
size_t done;
|
size_t done;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr static bool is_ssl = false;
|
|
||||||
|
|
||||||
gcm_op_writer_t(osd_messenger_t* msgr, osd_client_t* cl, uint8_t *curbuf, size_t bufsize):
|
gcm_op_writer_t(osd_messenger_t* msgr, osd_client_t* cl, uint8_t *curbuf, size_t bufsize):
|
||||||
msgr(msgr), cl(cl), from(cl->write_op_pos), curbuf(curbuf), bufsize(bufsize), done(0)
|
msgr(msgr), cl(cl), from(cl->write_op_pos), curbuf(curbuf), bufsize(bufsize), done(0)
|
||||||
{
|
{
|
||||||
@@ -300,15 +273,16 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
uint8_t iv[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
|
||||||
#ifdef WITH_ISAL_CRYPTO
|
#ifdef WITH_ISAL_CRYPTO
|
||||||
int r = isal_aes_gcm_init_256(&cl->my_key_isal, cl->enc_ctx, cl->my_key.data() + AES_256_GCM_KEY_SIZE, NULL, 0);
|
int r = isal_aes_gcm_init_256(&msgr->test_osd_aes_key_isal, cl->enc_ctx, iv, NULL, 0);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "isal_aes_gcm_init_256 error %d\n", r);
|
fprintf(stderr, "isal_aes_gcm_init_256 error %d\n", r);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int r = EVP_EncryptInit_ex(cl->enc_ctx, NULL, NULL, (uint8_t*)cl->my_key.data(), cl->my_key.data() + AES_256_GCM_KEY_SIZE);
|
int r = EVP_EncryptInit_ex(cl->enc_ctx, NULL, NULL, (uint8_t*)msgr->test_osd_aes_key.data(), iv);
|
||||||
if (r != 1)
|
if (r != 1)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "EncryptInit error: ");
|
fprintf(stderr, "EncryptInit error: ");
|
||||||
@@ -316,9 +290,6 @@ public:
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// Increase IV
|
|
||||||
cl->my_iv_ctr++;
|
|
||||||
(*(uint64_t*)(cl->my_key.data() + AES_256_GCM_KEY_SIZE))++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_ctx(osd_messenger_t* msgr, osd_client_t *cl)
|
static void free_ctx(osd_messenger_t* msgr, osd_client_t *cl)
|
||||||
@@ -343,7 +314,7 @@ public:
|
|||||||
from -= src_len;
|
from -= src_len;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!(flags & WR_GCM))
|
if (!(flags & WR_TLS))
|
||||||
{
|
{
|
||||||
if (flags & WR_XTS)
|
if (flags & WR_XTS)
|
||||||
{
|
{
|
||||||
@@ -372,7 +343,7 @@ public:
|
|||||||
if (!n)
|
if (!n)
|
||||||
return false;
|
return false;
|
||||||
#ifdef WITH_ISAL_CRYPTO
|
#ifdef WITH_ISAL_CRYPTO
|
||||||
int r = isal_aes_gcm_enc_256_update(&cl->my_key_isal, cl->enc_ctx, curbuf+done, src+from, n);
|
int r = isal_aes_gcm_enc_256_update(&msgr->test_osd_aes_key_isal, cl->enc_ctx, curbuf+done, src+from, n);
|
||||||
assert(!r);
|
assert(!r);
|
||||||
#else
|
#else
|
||||||
int actual_out;
|
int actual_out;
|
||||||
@@ -399,7 +370,7 @@ public:
|
|||||||
static void write_tag_to(osd_messenger_t *msgr, osd_client_t *cl, uint8_t *dst)
|
static void write_tag_to(osd_messenger_t *msgr, osd_client_t *cl, uint8_t *dst)
|
||||||
{
|
{
|
||||||
#ifdef WITH_ISAL_CRYPTO
|
#ifdef WITH_ISAL_CRYPTO
|
||||||
int r = isal_aes_gcm_enc_256_finalize(&cl->my_key_isal, cl->enc_ctx, dst, 16);
|
int r = isal_aes_gcm_enc_256_finalize(&msgr->test_osd_aes_key_isal, cl->enc_ctx, dst, 16);
|
||||||
assert(!r);
|
assert(!r);
|
||||||
#else
|
#else
|
||||||
int actual_out = 0;
|
int actual_out = 0;
|
||||||
@@ -454,12 +425,12 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// FIXME Split into 3 classes - basic, tls and gcm
|
||||||
class get_op_writer_t: public msgr_op_writer_t
|
class get_op_writer_t: public msgr_op_writer_t
|
||||||
{
|
{
|
||||||
osd_messenger_t* msgr;
|
osd_messenger_t* msgr;
|
||||||
osd_client_t* cl;
|
osd_client_t* cl;
|
||||||
size_t from;
|
size_t from;
|
||||||
size_t done;
|
|
||||||
size_t enc_size;
|
size_t enc_size;
|
||||||
size_t done_enc;
|
size_t done_enc;
|
||||||
|
|
||||||
@@ -497,7 +468,6 @@ class get_op_writer_t: public msgr_op_writer_t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
cl->send_list.push_back((iovec){ .iov_base = cl->ssl_out_buf+cl->ssl_out_buf_size, .iov_len = n });
|
cl->send_list.push_back((iovec){ .iov_base = cl->ssl_out_buf+cl->ssl_out_buf_size, .iov_len = n });
|
||||||
done += n;
|
|
||||||
cl->ssl_out_buf_size += n;
|
cl->ssl_out_buf_size += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -511,16 +481,13 @@ class get_op_writer_t: public msgr_op_writer_t
|
|||||||
if (r > 0)
|
if (r > 0)
|
||||||
n += r;
|
n += r;
|
||||||
} while (cl->ssl_out_buf_size+n >= cl->ssl_out_buf_cap);
|
} while (cl->ssl_out_buf_size+n >= cl->ssl_out_buf_cap);
|
||||||
cl->ssl_more_to_buffer = false;
|
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
send_out_buf(n);
|
send_out_buf(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr static bool is_ssl = true;
|
get_op_writer_t(osd_messenger_t* msgr, osd_client_t* cl):
|
||||||
|
msgr(msgr), cl(cl), from(cl->write_op_pos), enc_size(0), done_enc(0)
|
||||||
get_op_writer_t(osd_messenger_t* msgr, osd_client_t* cl, uint8_t*, size_t):
|
|
||||||
msgr(msgr), cl(cl), from(cl->write_op_pos), done(0), enc_size(0), done_enc(0)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -535,32 +502,18 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool flush_ssl()
|
void flush_ssl()
|
||||||
{
|
{
|
||||||
if (cl->ssl_cli && cl->ssl_handshake_pending)
|
if (!cl->ssl_handshake_done)
|
||||||
{
|
{
|
||||||
if (!msgr->do_tls_handshake(cl))
|
if (!msgr->ssl_do_handshake(cl))
|
||||||
return false;
|
return;
|
||||||
if (cl->ssl_handshake_pending & MSGR_HSP_SEND)
|
|
||||||
{
|
|
||||||
uint8_t first_byte = 0;
|
|
||||||
size_t f = 0;
|
|
||||||
if (!ssl_op_writer_t::write_to_ssl(cl, &first_byte, 1, 0, f))
|
|
||||||
return false;
|
|
||||||
cl->write_op_pos--;
|
|
||||||
copy_ssl();
|
|
||||||
cl->ssl_handshake_pending &= ~MSGR_HSP_SEND;
|
|
||||||
if (!msgr->finalize_tls_handshake(cl))
|
|
||||||
{
|
|
||||||
if (cl->gcm_enabled)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
copy_ssl();
|
|
||||||
}
|
}
|
||||||
return true;
|
if (cl->send_list.size() >= IOV_MAX)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
copy_ssl();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool write(uint8_t *src, size_t src_len, int flags) override
|
bool write(uint8_t *src, size_t src_len, int flags) override
|
||||||
@@ -575,18 +528,16 @@ public:
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (flags & WR_GCM)
|
if (flags & WR_TLS)
|
||||||
{
|
{
|
||||||
if (cl->ssl_cli)
|
if (cl->ssl_cli)
|
||||||
{
|
{
|
||||||
if (cl->ssl_handshake_pending)
|
if (!cl->ssl_handshake_done)
|
||||||
{
|
{
|
||||||
if (!flush_ssl())
|
if (!msgr->ssl_do_handshake(cl))
|
||||||
return false;
|
return false;
|
||||||
if (cl->gcm_enabled)
|
|
||||||
goto try_gcm;
|
|
||||||
}
|
}
|
||||||
if (!cl->ssl_handshake_pending)
|
if (cl->ssl_handshake_done)
|
||||||
{
|
{
|
||||||
if (!ssl_op_writer_t::write_to_ssl(cl, src, src_len, flags, from))
|
if (!ssl_op_writer_t::write_to_ssl(cl, src, src_len, flags, from))
|
||||||
return false;
|
return false;
|
||||||
@@ -598,14 +549,13 @@ public:
|
|||||||
from = 0;
|
from = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
try_gcm:
|
else if (cl->enc_ctx)
|
||||||
if (cl->gcm_enabled)
|
|
||||||
{
|
{
|
||||||
// Encrypt data to client's temporary output buffer (all at once)
|
// Encrypt data to client's temporary output buffer (all at once)
|
||||||
size_t n = src_len-from;
|
size_t n = src_len-from;
|
||||||
ssl_extend_buf(n);
|
ssl_extend_buf(n);
|
||||||
#ifdef WITH_ISAL_CRYPTO
|
#ifdef WITH_ISAL_CRYPTO
|
||||||
int r = isal_aes_gcm_enc_256_update(&cl->my_key_isal, cl->enc_ctx, cl->ssl_out_buf+cl->ssl_out_buf_size, src+from, n);
|
int r = isal_aes_gcm_enc_256_update(&msgr->test_osd_aes_key_isal, cl->enc_ctx, cl->ssl_out_buf+cl->ssl_out_buf_size, src+from, n);
|
||||||
assert(!r);
|
assert(!r);
|
||||||
#else
|
#else
|
||||||
int actual_out;
|
int actual_out;
|
||||||
@@ -643,7 +593,6 @@ try_gcm:
|
|||||||
assert(enc_size > 0);
|
assert(enc_size > 0);
|
||||||
cl->write_op->enc_buf = (uint8_t*)malloc_or_die(enc_size);
|
cl->write_op->enc_buf = (uint8_t*)malloc_or_die(enc_size);
|
||||||
cl->send_list.push_back((iovec){ .iov_base = cl->write_op->enc_buf, .iov_len = enc_size });
|
cl->send_list.push_back((iovec){ .iov_base = cl->write_op->enc_buf, .iov_len = enc_size });
|
||||||
done += enc_size;
|
|
||||||
}
|
}
|
||||||
assert(enc_size > 0);
|
assert(enc_size > 0);
|
||||||
msgr->op_encrypted_copy_buf(cl, cl->write_op->enc_buf, enc_size, src, src_len, from, done_enc);
|
msgr->op_encrypted_copy_buf(cl, cl->write_op->enc_buf, enc_size, src, src_len, from, done_enc);
|
||||||
@@ -654,7 +603,6 @@ try_gcm:
|
|||||||
if (cl->write_csum_state && !(flags & WR_NO_CSUM))
|
if (cl->write_csum_state && !(flags & WR_NO_CSUM))
|
||||||
XXH3_64bits_update(cl->write_csum_state, src+from, src_len-from);
|
XXH3_64bits_update(cl->write_csum_state, src+from, src_len-from);
|
||||||
cl->send_list.push_back((iovec){ src+from, src_len-from });
|
cl->send_list.push_back((iovec){ src+from, src_len-from });
|
||||||
done += src_len-from;
|
|
||||||
cl->write_op_pos += src_len-from;
|
cl->write_op_pos += src_len-from;
|
||||||
}
|
}
|
||||||
from = 0;
|
from = 0;
|
||||||
@@ -681,11 +629,6 @@ try_gcm:
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t get_done()
|
|
||||||
{
|
|
||||||
return done;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void osd_messenger_t::outbox_push(osd_op_t *cur_op)
|
void osd_messenger_t::outbox_push(osd_op_t *cur_op)
|
||||||
@@ -797,6 +740,30 @@ void osd_messenger_t::measure_exec(osd_op_t *cur_op)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool osd_messenger_t::ssl_do_handshake(osd_client_t *cl)
|
||||||
|
{
|
||||||
|
if (cl->ssl_handshake_done)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int r = SSL_do_handshake(cl->ssl_cli);
|
||||||
|
if (r > 0)
|
||||||
|
{
|
||||||
|
cl->ssl_handshake_done = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = SSL_get_error(cl->ssl_cli, r);
|
||||||
|
if (r != 0 && r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Client %ju TLS handshake error: %s, stopping client\n", cl->client_id, ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
cl->io_error = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool osd_messenger_t::try_send(osd_client_t *cl)
|
bool osd_messenger_t::try_send(osd_client_t *cl)
|
||||||
{
|
{
|
||||||
if (cl->peer_state == PEER_STOPPED || cl->peer_fd < 0)
|
if (cl->peer_state == PEER_STOPPED || cl->peer_fd < 0)
|
||||||
@@ -808,11 +775,32 @@ bool osd_messenger_t::try_send(osd_client_t *cl)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
assert(cl->peer_state != PEER_RDMA);
|
assert(cl->peer_state != PEER_RDMA);
|
||||||
copy_ops_to_with<get_op_writer_t>(cl, NULL, 0);
|
get_op_writer_t wr(this, cl);
|
||||||
if (cl->io_error)
|
while ((cl->write_op || cl->write_ops.size()) && cl->send_list.size() < IOV_MAX)
|
||||||
{
|
{
|
||||||
stop_client(cl->client_id);
|
if (!cl->write_op)
|
||||||
return true;
|
{
|
||||||
|
next_write_op(cl);
|
||||||
|
wr.reset();
|
||||||
|
}
|
||||||
|
osd_op_t *op = cl->write_op;
|
||||||
|
if (!op_write_to(cl, wr))
|
||||||
|
{
|
||||||
|
if (cl->io_error)
|
||||||
|
{
|
||||||
|
stop_client(cl->client_id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!cl->write_op && op->op_type == OSD_OP_IN)
|
||||||
|
{
|
||||||
|
cl->send_free_ops.push_back(op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!cl->send_list.size() && cl->ssl_cli)
|
||||||
|
{
|
||||||
|
wr.flush_ssl();
|
||||||
}
|
}
|
||||||
if (!cl->send_list.size())
|
if (!cl->send_list.size())
|
||||||
{
|
{
|
||||||
@@ -878,12 +866,6 @@ bool osd_messenger_t::try_send(osd_client_t *cl)
|
|||||||
|
|
||||||
size_t osd_messenger_t::copy_ops_to(osd_client_t *cl, uint8_t *dst, size_t dst_len)
|
size_t osd_messenger_t::copy_ops_to(osd_client_t *cl, uint8_t *dst, size_t dst_len)
|
||||||
{
|
{
|
||||||
if (cl->ssl_cli)
|
|
||||||
{
|
|
||||||
size_t done = copy_ops_to_with<ssl_op_writer_t>(cl, dst, dst_len);
|
|
||||||
if (done > 0 || cl->ssl_cli || !cl->gcm_enabled)
|
|
||||||
return done;
|
|
||||||
}
|
|
||||||
if (cl->gcm_enabled)
|
if (cl->gcm_enabled)
|
||||||
{
|
{
|
||||||
return copy_ops_to_with<gcm_op_writer_t>(cl, dst, dst_len);
|
return copy_ops_to_with<gcm_op_writer_t>(cl, dst, dst_len);
|
||||||
@@ -915,13 +897,10 @@ size_t osd_messenger_t::copy_ops_to_with(osd_client_t *cl, uint8_t *dst, size_t
|
|||||||
cl->send_free_ops.push_back(op);
|
cl->send_free_ops.push_back(op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if constexpr (T::is_ssl)
|
/*FIXME if (!wr.get_done() && cl->ssl_cli)
|
||||||
{
|
{
|
||||||
if (!wr.get_done())
|
wr.flush_ssl();
|
||||||
{
|
}*/
|
||||||
wr.flush_ssl();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return wr.get_done();
|
return wr.get_done();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -933,10 +912,7 @@ void osd_messenger_t::next_write_op(osd_client_t *cl)
|
|||||||
{
|
{
|
||||||
if (!cl->write_csum_state)
|
if (!cl->write_csum_state)
|
||||||
cl->write_csum_state = XXH3_createState();
|
cl->write_csum_state = XXH3_createState();
|
||||||
if (cl->my_key.size() == AES_256_GCM_KEY_SIZE + AES_256_GCM_IV_SIZE + XXH_SECRET_DEFAULT_SIZE)
|
XXH3_64bits_reset(cl->write_csum_state);
|
||||||
XXH3_64bits_reset_withSecret(cl->write_csum_state, cl->my_key.data() + AES_256_GCM_KEY_SIZE + AES_256_GCM_IV_SIZE, XXH_SECRET_DEFAULT_SIZE);
|
|
||||||
else
|
|
||||||
XXH3_64bits_reset(cl->write_csum_state);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1081,7 +1057,7 @@ bool osd_messenger_t::op_write_to(osd_client_t *cl, msgr_op_writer_t & wr)
|
|||||||
osd_op_t *op = cl->write_op;
|
osd_op_t *op = cl->write_op;
|
||||||
// Header
|
// Header
|
||||||
if (!wr.write((op->op_type == OSD_OP_IN ? op->reply.buf : op->req.buf), OSD_PACKET_SIZE,
|
if (!wr.write((op->op_type == OSD_OP_IN ? op->reply.buf : op->req.buf), OSD_PACKET_SIZE,
|
||||||
WR_GCM | (cl->proto_csum_status == MSGR_CSUM_PAYLOAD ? WR_NO_CSUM : 0)))
|
WR_TLS | (cl->proto_csum_status == MSGR_CSUM_PAYLOAD ? WR_NO_CSUM : 0)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1090,17 +1066,17 @@ bool osd_messenger_t::op_write_to(osd_client_t *cl, msgr_op_writer_t & wr)
|
|||||||
{
|
{
|
||||||
if (op->req.hdr.opcode == OSD_OP_SEC_READ && op->reply.sec_rw.attr_len > 0)
|
if (op->req.hdr.opcode == OSD_OP_SEC_READ && op->reply.sec_rw.attr_len > 0)
|
||||||
{
|
{
|
||||||
if (!wr.write((uint8_t*)op->bitmap, op->reply.sec_rw.attr_len, WR_GCM))
|
if (!wr.write((uint8_t*)op->bitmap, op->reply.sec_rw.attr_len, WR_TLS))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (op->req.hdr.opcode == OSD_OP_SEC_READ_BMP && op->reply.hdr.retval > 0)
|
else if (op->req.hdr.opcode == OSD_OP_SEC_READ_BMP && op->reply.hdr.retval > 0)
|
||||||
{
|
{
|
||||||
if (!wr.write((uint8_t*)op->buf, (size_t)op->reply.hdr.retval, WR_GCM))
|
if (!wr.write((uint8_t*)op->buf, (size_t)op->reply.hdr.retval, WR_TLS))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (op->req.hdr.opcode == OSD_OP_READ && op->reply.rw.bitmap_len > 0)
|
else if (op->req.hdr.opcode == OSD_OP_READ && op->reply.rw.bitmap_len > 0)
|
||||||
{
|
{
|
||||||
if (!wr.write((uint8_t*)op->bitmap, op->reply.rw.bitmap_len, WR_GCM))
|
if (!wr.write((uint8_t*)op->bitmap, op->reply.rw.bitmap_len, WR_TLS))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1109,12 +1085,12 @@ bool osd_messenger_t::op_write_to(osd_client_t *cl, msgr_op_writer_t & wr)
|
|||||||
if ((op->req.hdr.opcode == OSD_OP_SEC_WRITE || op->req.hdr.opcode == OSD_OP_SEC_WRITE_STABLE) &&
|
if ((op->req.hdr.opcode == OSD_OP_SEC_WRITE || op->req.hdr.opcode == OSD_OP_SEC_WRITE_STABLE) &&
|
||||||
op->req.sec_rw.attr_len > 0)
|
op->req.sec_rw.attr_len > 0)
|
||||||
{
|
{
|
||||||
if (!wr.write((uint8_t*)op->bitmap, op->req.sec_rw.attr_len, WR_GCM))
|
if (!wr.write((uint8_t*)op->bitmap, op->req.sec_rw.attr_len, WR_TLS))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (op->req.hdr.opcode == OSD_OP_SEC_READ_BMP && op->req.sec_read_bmp.len > 0)
|
else if (op->req.hdr.opcode == OSD_OP_SEC_READ_BMP && op->req.sec_read_bmp.len > 0)
|
||||||
{
|
{
|
||||||
if (!wr.write((uint8_t*)op->buf, (size_t)op->req.sec_read_bmp.len, WR_GCM))
|
if (!wr.write((uint8_t*)op->buf, (size_t)op->req.sec_read_bmp.len, WR_TLS))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1124,7 +1100,7 @@ bool osd_messenger_t::op_write_to(osd_client_t *cl, msgr_op_writer_t & wr)
|
|||||||
for (int i = 0; i < cl->write_op->iov.count; i++)
|
for (int i = 0; i < cl->write_op->iov.count; i++)
|
||||||
{
|
{
|
||||||
auto & iov = cl->write_op->iov.buf[i];
|
auto & iov = cl->write_op->iov.buf[i];
|
||||||
if (!wr.write((uint8_t*)iov.iov_base, iov.iov_len, WR_GCM))
|
if (!wr.write((uint8_t*)iov.iov_base, iov.iov_len, WR_TLS))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1141,7 +1117,7 @@ bool osd_messenger_t::op_write_to(osd_client_t *cl, msgr_op_writer_t & wr)
|
|||||||
cl->proto_csum_status == MSGR_CSUM_PAYLOAD && cl->write_op_pos > OSD_PACKET_SIZE)
|
cl->proto_csum_status == MSGR_CSUM_PAYLOAD && cl->write_op_pos > OSD_PACKET_SIZE)
|
||||||
{
|
{
|
||||||
cl->write_op->csum = XXH3_64bits_digest(cl->write_csum_state);
|
cl->write_op->csum = XXH3_64bits_digest(cl->write_csum_state);
|
||||||
if (!wr.write((uint8_t*)&cl->write_op->csum, 8, WR_GCM|WR_NO_CSUM))
|
if (!wr.write((uint8_t*)&cl->write_op->csum, 8, WR_TLS|WR_NO_CSUM))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!wr.finish())
|
if (!wr.finish())
|
||||||
|
|||||||
@@ -121,7 +121,6 @@ static const char* help_text =
|
|||||||
" --logfile <FILE> log to the specified file\n"
|
" --logfile <FILE> log to the specified file\n"
|
||||||
" --enforce 1 enforce permissions at the server side (default is disabled)\n"
|
" --enforce 1 enforce permissions at the server side (default is disabled)\n"
|
||||||
" --foreground 1 stay in foreground, do not daemonize\n"
|
" --foreground 1 stay in foreground, do not daemonize\n"
|
||||||
" --trace trace all NFS requests\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"NFS proxy is stateless if you use immediate_commit=all in your cluster and if\n"
|
"NFS proxy is stateless if you use immediate_commit=all in your cluster and if\n"
|
||||||
"you do not use client_enable_writeback=true, so you can freely use multiple\n"
|
"you do not use client_enable_writeback=true, so you can freely use multiple\n"
|
||||||
@@ -159,7 +158,7 @@ json11::Json::object nfs_proxy_t::parse_args(int narg, const char *args[])
|
|||||||
{
|
{
|
||||||
const char *opt = args[i]+2;
|
const char *opt = args[i]+2;
|
||||||
cfg[str_replace(opt, "-", "_")] = !strcmp(opt, "json") || !strcmp(opt, "block") ||
|
cfg[str_replace(opt, "-", "_")] = !strcmp(opt, "json") || !strcmp(opt, "block") ||
|
||||||
!strcmp(opt, "dry-run") || !strcmp(opt, "recalc-stats") || !strcmp(opt, "trace") ||
|
!strcmp(opt, "dry-run") || !strcmp(opt, "recalc-stats") ||
|
||||||
!strcmp(opt, "include-empty") || !strcmp(opt, "no-rm") || i == narg-1 ? "1" : args[++i];
|
!strcmp(opt, "include-empty") || !strcmp(opt, "no-rm") || i == narg-1 ? "1" : args[++i];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -83,8 +83,6 @@ void osd_t::finish_op(osd_op_t *cur_op, int retval)
|
|||||||
rm_inflight(pg);
|
rm_inflight(pg);
|
||||||
}
|
}
|
||||||
assert(!cur_op->op_data->subops);
|
assert(!cur_op->op_data->subops);
|
||||||
free(cur_op->op_data);
|
|
||||||
cur_op->op_data = NULL;
|
|
||||||
}
|
}
|
||||||
cur_op->reply.hdr.magic = SECONDARY_OSD_REPLY_MAGIC;
|
cur_op->reply.hdr.magic = SECONDARY_OSD_REPLY_MAGIC;
|
||||||
cur_op->reply.hdr.id = cur_op->req.hdr.id;
|
cur_op->reply.hdr.id = cur_op->req.hdr.id;
|
||||||
|
|||||||
@@ -592,7 +592,7 @@ void test_msgr_encrypt()
|
|||||||
enc->start(key, 4096 * 114, 4096);
|
enc->start(key, 4096 * 114, 4096);
|
||||||
in_pos = out_pos = 0;
|
in_pos = out_pos = 0;
|
||||||
enc->update(src+4096, 4096, crypt2, 4095, in_pos, out_pos);
|
enc->update(src+4096, 4096, crypt2, 4095, in_pos, out_pos);
|
||||||
assert(in_pos == 4095);
|
assert(in_pos == 4096);
|
||||||
assert(out_pos == 4095);
|
assert(out_pos == 4095);
|
||||||
enc->update(src+4096+in_pos, 4096-in_pos, crypt2+out_pos, 4096-out_pos, in_pos, out_pos);
|
enc->update(src+4096+in_pos, 4096-in_pos, crypt2+out_pos, 4096-out_pos, in_pos, out_pos);
|
||||||
assert(in_pos == 4096);
|
assert(in_pos == 4096);
|
||||||
@@ -623,10 +623,10 @@ void test_msgr_encrypt()
|
|||||||
assert(in_pos == 3000);
|
assert(in_pos == 3000);
|
||||||
assert(out_pos == 0);
|
assert(out_pos == 0);
|
||||||
dec->update(crypt+4096+3000, 3000, decrypt, 500, in_pos, out_pos);
|
dec->update(crypt+4096+3000, 3000, decrypt, 500, in_pos, out_pos);
|
||||||
assert(in_pos == 4095);
|
assert(in_pos == 4096);
|
||||||
assert(out_pos == 500);
|
assert(out_pos == 500);
|
||||||
dec->update(crypt+4096+in_pos, 6000-in_pos, decrypt+out_pos, 3000, in_pos, out_pos);
|
dec->update(crypt+4096+in_pos, 6000-in_pos, decrypt+out_pos, 3000, in_pos, out_pos);
|
||||||
assert(in_pos == 4095);
|
assert(in_pos == 4096);
|
||||||
assert(out_pos == 3500);
|
assert(out_pos == 3500);
|
||||||
dec->update(crypt+4096+in_pos, 6000-in_pos, decrypt+out_pos, 1000, in_pos, out_pos);
|
dec->update(crypt+4096+in_pos, 6000-in_pos, decrypt+out_pos, 1000, in_pos, out_pos);
|
||||||
assert(in_pos == 4096);
|
assert(in_pos == 4096);
|
||||||
@@ -635,10 +635,10 @@ void test_msgr_encrypt()
|
|||||||
assert(in_pos == 6000);
|
assert(in_pos == 6000);
|
||||||
assert(out_pos == 4096);
|
assert(out_pos == 4096);
|
||||||
dec->update(crypt+4096+in_pos, 8192-in_pos, decrypt+out_pos, 4500-out_pos, in_pos, out_pos);
|
dec->update(crypt+4096+in_pos, 8192-in_pos, decrypt+out_pos, 4500-out_pos, in_pos, out_pos);
|
||||||
assert(in_pos == 8191);
|
assert(in_pos == 8192);
|
||||||
assert(out_pos == 4500);
|
assert(out_pos == 4500);
|
||||||
dec->update(crypt+4096+in_pos, 8192-in_pos, decrypt+out_pos, 7500-out_pos, in_pos, out_pos);
|
dec->update(crypt+4096+in_pos, 8192-in_pos, decrypt+out_pos, 7500-out_pos, in_pos, out_pos);
|
||||||
assert(in_pos == 8191);
|
assert(in_pos == 8192);
|
||||||
assert(out_pos == 7500);
|
assert(out_pos == 7500);
|
||||||
dec->update(crypt+4096+in_pos, 8192-in_pos, decrypt+out_pos, 8192-out_pos, in_pos, out_pos);
|
dec->update(crypt+4096+in_pos, 8192-in_pos, decrypt+out_pos, 8192-out_pos, in_pos, out_pos);
|
||||||
assert(in_pos == 8192);
|
assert(in_pos == 8192);
|
||||||
|
|||||||
@@ -1,119 +0,0 @@
|
|||||||
// Copyright (c) Vitaliy Filippov, 2019+
|
|
||||||
// License: VNPL-1.1 or GNU GPL-2.0+ (see README.md for details)
|
|
||||||
|
|
||||||
#include "openssl_util.h"
|
|
||||||
#include "str_util.h"
|
|
||||||
|
|
||||||
#include <openssl/ssl.h>
|
|
||||||
|
|
||||||
X509 *openssl_load_cert(const std::string & file_or_pem)
|
|
||||||
{
|
|
||||||
std::string pem;
|
|
||||||
BIO *bio = NULL;
|
|
||||||
if (file_or_pem.substr(0, 5) != "-----")
|
|
||||||
{
|
|
||||||
pem = read_file(file_or_pem);
|
|
||||||
bio = BIO_new_mem_buf(pem.data(), pem.size());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
bio = BIO_new_mem_buf(file_or_pem.data(), file_or_pem.size());
|
|
||||||
if (!bio)
|
|
||||||
return NULL;
|
|
||||||
X509 *x509 = PEM_read_bio_X509(bio, NULL, 0, NULL);
|
|
||||||
BIO_free(bio);
|
|
||||||
return x509;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool openssl_ctx_add_ca(SSL_CTX *ssl_ctx, const std::string & file_or_pem)
|
|
||||||
{
|
|
||||||
X509 *cert = openssl_load_cert(file_or_pem);
|
|
||||||
bool ok = !!cert;
|
|
||||||
if (cert)
|
|
||||||
{
|
|
||||||
X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
|
|
||||||
X509_STORE_add_cert(store, cert);
|
|
||||||
X509_free(cert);
|
|
||||||
}
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool openssl_ctx_use_ca(SSL_CTX *ssl_ctx, const std::string & file_or_pem)
|
|
||||||
{
|
|
||||||
if (file_or_pem.substr(0, 5) == "-----")
|
|
||||||
{
|
|
||||||
return openssl_ctx_add_ca(ssl_ctx, file_or_pem);
|
|
||||||
}
|
|
||||||
return file_or_pem.empty()
|
|
||||||
? !!SSL_CTX_set_default_verify_paths(ssl_ctx)
|
|
||||||
: !!SSL_CTX_load_verify_locations(ssl_ctx, file_or_pem.c_str(), NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
std::string contents;
|
|
||||||
if (file_or_pem.substr(0, 5) == "-----")
|
|
||||||
bio = BIO_new_mem_buf(file_or_pem.data(), file_or_pem.size());
|
|
||||||
else
|
|
||||||
{
|
|
||||||
contents = read_file(file_or_pem);
|
|
||||||
if (!contents.size())
|
|
||||||
return false;
|
|
||||||
bio = BIO_new_mem_buf(contents.data(), contents.size());
|
|
||||||
}
|
|
||||||
if (!bio)
|
|
||||||
return false;
|
|
||||||
X509 *x509 = PEM_read_bio_X509(bio, NULL, 0, NULL);
|
|
||||||
bool ok = !!x509;
|
|
||||||
if (x509)
|
|
||||||
{
|
|
||||||
ok = SSL_CTX_use_certificate(ssl_ctx, x509);
|
|
||||||
if (ok)
|
|
||||||
common_name = openssl_get_cn(x509);
|
|
||||||
X509_free(x509);
|
|
||||||
}
|
|
||||||
BIO_free(bio);
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool openssl_ctx_use_key(SSL_CTX *ssl_ctx, const std::string & file_or_pem)
|
|
||||||
{
|
|
||||||
if (file_or_pem.substr(0, 5) == "-----")
|
|
||||||
{
|
|
||||||
BIO *bio = BIO_new_mem_buf(file_or_pem.data(), file_or_pem.size());
|
|
||||||
if (!bio)
|
|
||||||
return false;
|
|
||||||
EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
|
|
||||||
bool ok = !!pkey;
|
|
||||||
if (pkey)
|
|
||||||
{
|
|
||||||
ok = SSL_CTX_use_PrivateKey(ssl_ctx, pkey);
|
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
}
|
|
||||||
BIO_free(bio);
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
return !!SSL_CTX_use_PrivateKey_file(ssl_ctx, file_or_pem.c_str(), SSL_FILETYPE_PEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool openssl_bio_nonempty(BIO *bio)
|
|
||||||
{
|
|
||||||
// SSL_ERROR_WANT_WRITE is absolutely non-informative with memory BIO, it basically never happens
|
|
||||||
// So we have to check memory BIO for outstanding data
|
|
||||||
char *bio_buf = NULL;
|
|
||||||
size_t bio_sz = BIO_get_mem_data(bio, &bio_buf);
|
|
||||||
return bio_sz > 0;
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
// Copyright (c) Vitaliy Filippov, 2019+
|
|
||||||
// License: VNPL-1.1 or GNU GPL-2.0+ (see README.md for details)
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#ifdef WITH_OPENSSL
|
|
||||||
#include <openssl/types.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
X509 *openssl_load_cert(const std::string & file_or_pem);
|
|
||||||
bool openssl_ctx_add_ca(SSL_CTX *ssl_ctx, const std::string & file_or_pem);
|
|
||||||
bool openssl_ctx_use_ca(SSL_CTX *ssl_ctx, const std::string & file_or_pem);
|
|
||||||
std::string openssl_get_cn(X509 *x509);
|
|
||||||
bool openssl_ctx_use_cert(SSL_CTX *ssl_ctx, const std::string & file_or_pem, std::string & common_name);
|
|
||||||
bool openssl_ctx_use_key(SSL_CTX *ssl_ctx, const std::string & file_or_pem);
|
|
||||||
bool openssl_bio_nonempty(BIO *bio);
|
|
||||||
@@ -535,12 +535,12 @@ std::string urldecode(const std::string & orig)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t fromhexstr(const char *from, size_t from_len, uint8_t *to, size_t to_len)
|
size_t fromhexstr(const std::string & from, size_t bytes, uint8_t *to)
|
||||||
{
|
{
|
||||||
if (to_len > from_len/2)
|
if (bytes > from.size()/2)
|
||||||
to_len = from_len/2;
|
bytes = from.size()/2;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
while (i < to_len)
|
while (i < bytes)
|
||||||
{
|
{
|
||||||
uint8_t x = fromhexchar(from[2*i], 16);
|
uint8_t x = fromhexchar(from[2*i], 16);
|
||||||
uint8_t y = fromhexchar(from[2*i+1], 16);
|
uint8_t y = fromhexchar(from[2*i+1], 16);
|
||||||
@@ -552,11 +552,6 @@ size_t fromhexstr(const char *from, size_t from_len, uint8_t *to, size_t to_len)
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t fromhexstr(const std::string & from, size_t bytes, uint8_t *to)
|
|
||||||
{
|
|
||||||
return fromhexstr(from.data(), from.size(), to, bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string tohexstr(const uint8_t *from, size_t bytes)
|
std::string tohexstr(const uint8_t *from, size_t bytes)
|
||||||
{
|
{
|
||||||
std::string res;
|
std::string res;
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ std::string realpath_str(std::string path, bool nofail = true);
|
|||||||
std::string format_datetime(uint64_t unixtime);
|
std::string format_datetime(uint64_t unixtime);
|
||||||
bool is_zero(void *buf, size_t size);
|
bool is_zero(void *buf, size_t size);
|
||||||
std::string urldecode(const std::string & orig);
|
std::string urldecode(const std::string & orig);
|
||||||
size_t fromhexstr(const char *from, size_t from_len, uint8_t *to, size_t to_len);
|
|
||||||
size_t fromhexstr(const std::string & from, size_t bytes, uint8_t *to);
|
size_t fromhexstr(const std::string & from, size_t bytes, uint8_t *to);
|
||||||
std::string tohexstr(const uint8_t *from, size_t bytes);
|
std::string tohexstr(const uint8_t *from, size_t bytes);
|
||||||
bool ishexstr(const std::string & str);
|
bool ishexstr(const std::string & str);
|
||||||
|
|||||||
@@ -34,8 +34,6 @@ extern "C" {
|
|||||||
# define XXH_NOESCAPE
|
# define XXH_NOESCAPE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define XXH_SECRET_DEFAULT_SIZE 192
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
XXH_OK = 0,
|
XXH_OK = 0,
|
||||||
XXH_ERROR
|
XXH_ERROR
|
||||||
|
|||||||
+2
-1
@@ -27,7 +27,7 @@ ETCD_COUNT=${ETCD_COUNT:-1}
|
|||||||
ANTIETCD=${ANTIETCD}
|
ANTIETCD=${ANTIETCD}
|
||||||
USE_RAMDISK=${USE_RAMDISK}
|
USE_RAMDISK=${USE_RAMDISK}
|
||||||
ETCD_SCHEME=${ETCD_SCHEME:-http}
|
ETCD_SCHEME=${ETCD_SCHEME:-http}
|
||||||
OSD_TLS=${OSD_TLS:-1}
|
OSD_TLS=${OSD_TLS}
|
||||||
|
|
||||||
RAMDISK=/run/user/$(id -u)
|
RAMDISK=/run/user/$(id -u)
|
||||||
findmnt $RAMDISK >/dev/null || (sudo mkdir -p $RAMDISK && sudo mount -t tmpfs tmpfs $RAMDISK)
|
findmnt $RAMDISK >/dev/null || (sudo mkdir -p $RAMDISK && sudo mount -t tmpfs tmpfs $RAMDISK)
|
||||||
@@ -142,6 +142,7 @@ if [[ "$OSD_TLS" = "1" ]]; then
|
|||||||
VITASTOR_CFG="$VITASTOR_CFG"',"tls_cert":"'$(pwd)'/testdata/cli.crt"'
|
VITASTOR_CFG="$VITASTOR_CFG"',"tls_cert":"'$(pwd)'/testdata/cli.crt"'
|
||||||
VITASTOR_CFG="$VITASTOR_CFG"',"tls_key":"'$(pwd)'/testdata/cli.key"'
|
VITASTOR_CFG="$VITASTOR_CFG"',"tls_key":"'$(pwd)'/testdata/cli.key"'
|
||||||
fi
|
fi
|
||||||
|
VITASTOR_CFG="$VITASTOR_CFG"',"test_osd_aes_key":"'$(openssl rand -hex 32)'"'
|
||||||
echo "{$VITASTOR_CFG}" > ./testdata/vitastor.conf
|
echo "{$VITASTOR_CFG}" > ./testdata/vitastor.conf
|
||||||
VITASTOR_CFG=./testdata/vitastor.conf
|
VITASTOR_CFG=./testdata/vitastor.conf
|
||||||
VITASTOR_CLI="build/src/cmd/vitastor-cli --config_path $VITASTOR_CFG"
|
VITASTOR_CLI="build/src/cmd/vitastor-cli --config_path $VITASTOR_CFG"
|
||||||
|
|||||||
Reference in New Issue
Block a user