diff --git a/doc/ARCHITECTURE.md b/doc/ARCHITECTURE.md index 9896a051..568b5964 100644 --- a/doc/ARCHITECTURE.md +++ b/doc/ARCHITECTURE.md @@ -151,6 +151,7 @@ struct worker_io int server_fd; /* The server descriptor */ int slot; /* The slot */ SSL* client_ssl; /* The client SSL context */ + SSL* server_ssl; /* The server SSL context */ void* shmem; /* The shared memory segment */ void* pipeline_shmem; /* The shared memory segment for the pipeline */ }; diff --git a/src/include/pgagroal.h b/src/include/pgagroal.h index dacf8d56..4ed6d28f 100644 --- a/src/include/pgagroal.h +++ b/src/include/pgagroal.h @@ -48,9 +48,10 @@ extern "C" { #define MAIN_UDS ".s.pgagroal" -#define MAX_BUFFER_SIZE 65535 -#define DEFAULT_BUFFER_SIZE 65535 -#define SECURITY_BUFFER_SIZE 512 +#define MAX_BUFFER_SIZE 65535 +#define DEFAULT_BUFFER_SIZE 65535 +#define SECURITY_BUFFER_SIZE 512 +#define SSL_SESSION_BUFFER_SIZE 2048 #define MAX_USERNAME_LENGTH 128 #define MAX_DATABASE_LENGTH 256 @@ -175,6 +176,9 @@ struct connection ssize_t security_lengths[NUMBER_OF_SECURITY_MESSAGES]; /**< The lengths of the security messages */ char security_messages[NUMBER_OF_SECURITY_MESSAGES][SECURITY_BUFFER_SIZE]; /**< The security messages */ + int ssl_session_length; /**< The length of the SSL session */ + char ssl_session[SSL_SESSION_BUFFER_SIZE]; /**< The SSL session (ASN.1) */ + signed char limit_rule; /**< The limit rule used */ time_t timestamp; /**< The last used timestamp */ pid_t pid; /**< The associated process id */ diff --git a/src/include/pool.h b/src/include/pool.h index 6dbb8c2b..6aa2948b 100644 --- a/src/include/pool.h +++ b/src/include/pool.h @@ -37,6 +37,7 @@ extern "C" { #include #include +#include /** * Get a connection @@ -45,27 +46,30 @@ extern "C" { * @param reuse Should a slot be reused * @param transaction_mode Obtain a connection in transaction mode * @param slot The resulting slot + * @param ssl The resulting SSL (can be NULL) * @return 0 upon success, 1 if pool is full, otherwise 2 */ int -pgagroal_get_connection(char* username, char* database, bool reuse, bool transaction_mode, int* slot); +pgagroal_get_connection(char* username, char* database, bool reuse, bool transaction_mode, int* slot, SSL** ssl); /** * Return a connection * @param slot The slot + * @param ssl The SSL connection (can be NULL) * @param transaction_mode Is the connection returned in transaction mode * @return 0 upon success, otherwise 1 */ int -pgagroal_return_connection(int slot, bool transaction_mode); +pgagroal_return_connection(int slot, SSL* ssl, bool transaction_mode); /** * Kill a connection * @param slot The slot + * @param ssl The SSL connection (can be NULL) * @return 0 upon success, otherwise 1 */ int -pgagroal_kill_connection(int slot); +pgagroal_kill_connection(int slot, SSL* ssl); /** * Perform idle timeout diff --git a/src/include/security.h b/src/include/security.h index d3542203..96e8b73f 100644 --- a/src/include/security.h +++ b/src/include/security.h @@ -45,10 +45,11 @@ extern "C" { * @param address The client address * @param slot The resulting slot * @param client_ssl The client SSL context + * @param server_ssl The server SSL context * @return 0 upon success, otherwise 1 */ int -pgagroal_authenticate(int client_fd, char* address, int* slot, SSL** client_ssl); +pgagroal_authenticate(int client_fd, char* address, int* slot, SSL** client_ssl, SSL** server_ssl); /** * Authenticate a prefill connection @@ -56,10 +57,11 @@ pgagroal_authenticate(int client_fd, char* address, int* slot, SSL** client_ssl) * @param password The password * @param database The database * @param slot The resulting slot + * @param server_ssl The server SSL context * @return 0 upon success, otherwise 1 */ int -pgagroal_prefill_auth(char* username, char* password, char* database, int* slot); +pgagroal_prefill_auth(char* username, char* password, char* database, int* slot, SSL** server_ssl); /** * Authenticate a remote management user @@ -136,6 +138,24 @@ pgagroal_user_known(char* user); int pgagroal_tls_valid(void); +/** + * Load a SSL connection from a slot + * @param slot The slot + * @param ssl The resulting SSL connection (can be NULL) + * @return 0 upon success, otherwise 1 + */ +int +pgagroal_load_tls_connection(int slot, SSL** ssl); + +/** + * Save a TLS connection to a slot + * @param ssl The SSL connection + * @param slot The slot + * @return 0 upon success, otherwise 1 + */ +int +pgagroal_save_tls_connection(SSL* ssl, int slot); + #ifdef __cplusplus } #endif diff --git a/src/include/server.h b/src/include/server.h index c712ac9b..50932862 100644 --- a/src/include/server.h +++ b/src/include/server.h @@ -36,6 +36,7 @@ extern "C" { #include #include +#include /** * Get the primary server @@ -49,10 +50,11 @@ pgagroal_get_primary(int* server); * Update the server state * @param slot The slot * @param socket The descriptor + * @param ssl The SSL connection * @return 0 upon success, otherwise 1 */ int -pgagroal_update_server_state(int slot, int socket); +pgagroal_update_server_state(int slot, int socket, SSL* ssl); /** * Print the state of the servers diff --git a/src/include/worker.h b/src/include/worker.h index c4c0f4e8..ebddfdd3 100644 --- a/src/include/worker.h +++ b/src/include/worker.h @@ -56,6 +56,7 @@ struct worker_io int server_fd; /**< The server descriptor */ int slot; /**< The slot */ SSL* client_ssl; /**< The client SSL context */ + SSL* server_ssl; /**< The server SSL context */ }; extern volatile int running; diff --git a/src/libpgagroal/management.c b/src/libpgagroal/management.c index b87bcf89..e8e720ad 100644 --- a/src/libpgagroal/management.c +++ b/src/libpgagroal/management.c @@ -255,7 +255,8 @@ pgagroal_management_transfer_connection(int32_t slot) if (cmptr) free(cmptr); pgagroal_disconnect(fd); - pgagroal_kill_connection(slot); + /* TODO - server_ssl */ + pgagroal_kill_connection(slot, NULL); return 1; } @@ -1105,7 +1106,8 @@ pgagroal_management_client_fd(int32_t slot, pid_t pid) error: free(cmptr); pgagroal_disconnect(fd); - pgagroal_kill_connection(slot); + /* TODO - server_ssl */ + pgagroal_kill_connection(slot, NULL); return 1; } diff --git a/src/libpgagroal/pipeline_perf.c b/src/libpgagroal/pipeline_perf.c index bf021f55..b3432712 100644 --- a/src/libpgagroal/pipeline_perf.c +++ b/src/libpgagroal/pipeline_perf.c @@ -121,7 +121,14 @@ performance_client(struct ev_loop *loop, struct ev_io *watcher, int revents) { if (likely(msg->kind != 'X')) { - status = pgagroal_write_socket_message(wi->server_fd, msg); + if (wi->server_ssl == NULL) + { + status = pgagroal_write_socket_message(wi->server_fd, msg); + } + else + { + status = pgagroal_write_ssl_message(wi->server_ssl, msg); + } if (unlikely(status != MESSAGE_STATUS_OK)) { goto server_error; @@ -195,7 +202,14 @@ performance_server(struct ev_loop *loop, struct ev_io *watcher, int revents) wi = (struct worker_io*)watcher; - status = pgagroal_read_socket_message(wi->server_fd, &msg); + if (wi->server_ssl == NULL) + { + status = pgagroal_read_socket_message(wi->server_fd, &msg); + } + else + { + status = pgagroal_read_ssl_message(wi->server_ssl, &msg); + } if (likely(status == MESSAGE_STATUS_OK)) { status = pgagroal_write_socket_message(wi->client_fd, msg); diff --git a/src/libpgagroal/pipeline_session.c b/src/libpgagroal/pipeline_session.c index 8e8bbaa4..258d909c 100644 --- a/src/libpgagroal/pipeline_session.c +++ b/src/libpgagroal/pipeline_session.c @@ -300,7 +300,14 @@ session_client(struct ev_loop *loop, struct ev_io *watcher, int revents) } } - status = pgagroal_write_socket_message(wi->server_fd, msg); + if (wi->server_ssl == NULL) + { + status = pgagroal_write_socket_message(wi->server_fd, msg); + } + else + { + status = pgagroal_write_ssl_message(wi->server_ssl, msg); + } if (unlikely(status == MESSAGE_STATUS_ERROR)) { if (config->failover) @@ -401,7 +408,14 @@ session_server(struct ev_loop *loop, struct ev_io *watcher, int revents) client_active(wi->slot); - status = pgagroal_read_socket_message(wi->server_fd, &msg); + if (wi->server_ssl == NULL) + { + status = pgagroal_read_socket_message(wi->server_fd, &msg); + } + else + { + status = pgagroal_read_ssl_message(wi->server_ssl, &msg); + } if (likely(status == MESSAGE_STATUS_OK)) { pgagroal_prometheus_network_received_add(msg->length); diff --git a/src/libpgagroal/pipeline_transaction.c b/src/libpgagroal/pipeline_transaction.c index ea48cbce..3ec2f19f 100644 --- a/src/libpgagroal/pipeline_transaction.c +++ b/src/libpgagroal/pipeline_transaction.c @@ -134,10 +134,11 @@ transaction_start(struct ev_loop* loop, struct worker_io* w) pgagroal_tracking_event_slot(TRACKER_TX_RETURN_CONNECTION_START, w->slot); is_new = config->connections[w->slot].new; - pgagroal_return_connection(w->slot, true); + pgagroal_return_connection(w->slot, w->server_ssl, true); w->server_fd = -1; w->slot = -1; + /* TODO - server_ssl */ if (is_new) { @@ -176,7 +177,7 @@ transaction_stop(struct ev_loop* loop, struct worker_io* w) ev_io_stop(loop, (struct ev_io*)&server_io); pgagroal_tracking_event_slot(TRACKER_TX_RETURN_CONNECTION_STOP, w->slot); - pgagroal_return_connection(slot, true); + pgagroal_return_connection(slot, w->server_ssl, true); slot = -1; } @@ -197,6 +198,7 @@ static void transaction_client(struct ev_loop* loop, struct ev_io* watcher, int revents) { int status = MESSAGE_STATUS_ERROR; + SSL* server_ssl = NULL; struct worker_io* wi = NULL; struct message* msg = NULL; struct configuration* config = NULL; @@ -208,14 +210,16 @@ transaction_client(struct ev_loop* loop, struct ev_io* watcher, int revents) if (slot == -1) { pgagroal_tracking_event_basic(TRACKER_TX_GET_CONNECTION, &username[0], &database[0]); - if (pgagroal_get_connection(&username[0], &database[0], true, true, &slot)) + if (pgagroal_get_connection(&username[0], &database[0], true, true, &slot, &server_ssl)) { pgagroal_write_pool_full(wi->client_ssl, wi->client_fd); goto get_error; } wi->server_fd = config->connections[slot].fd; + /* TODO - server_ssl */ wi->slot = slot; + wi->server_ssl = server_ssl; memcpy(&config->connections[slot].appname[0], &appname[0], MAX_APPLICATION_NAME); @@ -224,6 +228,7 @@ transaction_client(struct ev_loop* loop, struct ev_io* watcher, int revents) server_io.server_fd = config->connections[slot].fd; server_io.slot = slot; server_io.client_ssl = wi->client_ssl; + server_io.server_ssl = wi->server_ssl; fatal = false; @@ -292,7 +297,14 @@ transaction_client(struct ev_loop* loop, struct ev_io* watcher, int revents) } } - status = pgagroal_write_socket_message(wi->server_fd, msg); + if (wi->server_ssl == NULL) + { + status = pgagroal_write_socket_message(wi->server_fd, msg); + } + else + { + status = pgagroal_write_ssl_message(wi->server_ssl, msg); + } if (unlikely(status == MESSAGE_STATUS_ERROR)) { if (config->failover) @@ -392,6 +404,7 @@ transaction_server(struct ev_loop *loop, struct ev_io *watcher, int revents) /* We can't use the information from wi except from client_fd/client_ssl */ wi->server_fd = config->connections[slot].fd; + /* TODO - server_ssl */ wi->slot = slot; if (!pgagroal_socket_isvalid(wi->client_fd)) @@ -399,7 +412,14 @@ transaction_server(struct ev_loop *loop, struct ev_io *watcher, int revents) goto client_error; } - status = pgagroal_read_socket_message(wi->server_fd, &msg); + if (wi->server_ssl == NULL) + { + status = pgagroal_read_socket_message(wi->server_fd, &msg); + } + else + { + status = pgagroal_read_ssl_message(wi->server_ssl, &msg); + } if (likely(status == MESSAGE_STATUS_OK)) { pgagroal_prometheus_network_received_add(msg->length); @@ -474,12 +494,13 @@ transaction_server(struct ev_loop *loop, struct ev_io *watcher, int revents) if (deallocate) { + /* TODO - server_ssl */ pgagroal_write_deallocate_all(NULL, wi->server_fd); deallocate = false; } pgagroal_tracking_event_slot(TRACKER_TX_RETURN_CONNECTION, slot); - if (pgagroal_return_connection(slot, true)) + if (pgagroal_return_connection(slot, wi->server_ssl, true)) { goto return_error; } diff --git a/src/libpgagroal/pool.c b/src/libpgagroal/pool.c index cf511968..1fd17692 100644 --- a/src/libpgagroal/pool.c +++ b/src/libpgagroal/pool.c @@ -58,7 +58,7 @@ static void connection_details(int slot); static bool do_prefill(char* username, char* database, int size); int -pgagroal_get_connection(char* username, char* database, bool reuse, bool transaction_mode, int* slot) +pgagroal_get_connection(char* username, char* database, bool reuse, bool transaction_mode, int* slot, SSL** ssl) { bool do_init; bool has_lock; @@ -87,6 +87,7 @@ pgagroal_get_connection(char* username, char* database, bool reuse, bool transac start: *slot = -1; + *ssl = NULL; do_init = false; has_lock = false; @@ -222,8 +223,16 @@ pgagroal_get_connection(char* username, char* database, bool reuse, bool transac } else { + SSL* s = NULL; bool kill = false; + if (pgagroal_load_tls_connection(*slot, &s)) + { + kill = true; + } + + /* TODO - ssl */ + /* Verify the socket for the slot */ if (!pgagroal_socket_isvalid(config->connections[*slot].fd)) { @@ -249,7 +258,8 @@ pgagroal_get_connection(char* username, char* database, bool reuse, bool transac pgagroal_log_debug("pgagroal_get_connection: Slot %d FD %d - Error", *slot, config->connections[*slot].fd); pgagroal_tracking_event_slot(TRACKER_BAD_CONNECTION, *slot); - status = pgagroal_kill_connection(*slot); + status = pgagroal_kill_connection(*slot, s); + s = NULL; if (config->number_of_users > 0 && config->number_of_limits > 0) { @@ -268,6 +278,8 @@ pgagroal_get_connection(char* username, char* database, bool reuse, bool transac goto timeout; } } + + *ssl = s; } config->connections[*slot].timestamp = time(NULL); @@ -369,7 +381,7 @@ pgagroal_get_connection(char* username, char* database, bool reuse, bool transac } int -pgagroal_return_connection(int slot, bool transaction_mode) +pgagroal_return_connection(int slot, SSL* ssl, bool transaction_mode) { int state; struct configuration* config; @@ -398,12 +410,27 @@ pgagroal_return_connection(int slot, bool transaction_mode) if (!transaction_mode) { - if (pgagroal_write_discard_all(NULL, config->connections[slot].fd)) + if (pgagroal_write_discard_all(ssl, config->connections[slot].fd)) { goto kill_connection; } } + if (pgagroal_save_tls_connection(ssl, slot)) + { + goto kill_connection; + } + + /* TODO - SSL_shutdown */ + if (ssl != NULL) + { + SSL_CTX* ctx; + + ctx = SSL_get_SSL_CTX(ssl); + SSL_free(ssl); + SSL_CTX_free(ctx); + } + pgagroal_tracking_event_slot(TRACKER_RETURN_CONNECTION_SUCCESS, slot); config->connections[slot].timestamp = time(NULL); @@ -413,6 +440,7 @@ pgagroal_return_connection(int slot, bool transaction_mode) pgagroal_management_transfer_connection(slot); } + /* TODO - ? */ pgagroal_management_return_connection(slot); if (config->connections[slot].limit_rule >= 0) @@ -433,7 +461,7 @@ pgagroal_return_connection(int slot, bool transaction_mode) } else if (state == STATE_GRACEFULLY) { - pgagroal_write_terminate(NULL, config->connections[slot].fd); + pgagroal_write_terminate(ssl, config->connections[slot].fd); } } @@ -441,12 +469,14 @@ pgagroal_return_connection(int slot, bool transaction_mode) pgagroal_tracking_event_slot(TRACKER_RETURN_CONNECTION_KILL, slot); - return pgagroal_kill_connection(slot); + return pgagroal_kill_connection(slot, ssl); } int -pgagroal_kill_connection(int slot) +pgagroal_kill_connection(int slot, SSL* ssl) { + SSL_CTX* ctx; + int ssl_shutdown; int result = 0; int fd; struct configuration* config; @@ -463,6 +493,19 @@ pgagroal_kill_connection(int slot) if (fd != -1) { pgagroal_management_kill_connection(slot, fd); + + if (ssl != NULL) + { + ctx = SSL_get_SSL_CTX(ssl); + ssl_shutdown = SSL_shutdown(ssl); + if (ssl_shutdown == 0) + { + SSL_shutdown(ssl); + } + SSL_free(ssl); + SSL_CTX_free(ctx); + } + if (!pgagroal_socket_has_error(fd)) { pgagroal_disconnect(fd); @@ -498,6 +541,9 @@ pgagroal_kill_connection(int slot) memset(&config->connections[slot].security_messages[i], 0, SECURITY_BUFFER_SIZE); } + config->connections[slot].ssl_session_length = 0; + memset(&config->connections[slot].ssl_session, 0, sizeof(config->connections[slot].ssl_session)); + config->connections[slot].limit_rule = -1; config->connections[slot].timestamp = -1; config->connections[slot].fd = -1; @@ -541,7 +587,8 @@ pgagroal_idle_timeout(void) { pgagroal_prometheus_connection_idletimeout(); pgagroal_tracking_event_slot(TRACKER_IDLE_TIMEOUT, i); - pgagroal_kill_connection(i); + /* TODO - ssl */ + pgagroal_kill_connection(i, NULL); prefill = true; } else @@ -550,7 +597,8 @@ pgagroal_idle_timeout(void) { pgagroal_prometheus_connection_idletimeout(); pgagroal_tracking_event_slot(TRACKER_IDLE_TIMEOUT, i); - pgagroal_kill_connection(i); + /* TODO - ssl */ + pgagroal_kill_connection(i, NULL); prefill = true; } } @@ -626,7 +674,8 @@ pgagroal_validation(void) { pgagroal_prometheus_connection_invalid(); pgagroal_tracking_event_slot(TRACKER_INVALID_CONNECTION, i); - pgagroal_kill_connection(i); + /* TODO - ssl */ + pgagroal_kill_connection(i, NULL); prefill = true; } else @@ -635,7 +684,8 @@ pgagroal_validation(void) { pgagroal_prometheus_connection_invalid(); pgagroal_tracking_event_slot(TRACKER_INVALID_CONNECTION, i); - pgagroal_kill_connection(i); + /* TODO - ssl */ + pgagroal_kill_connection(i, NULL); prefill = true; } } @@ -700,7 +750,8 @@ pgagroal_flush(int mode) } pgagroal_prometheus_connection_flush(); pgagroal_tracking_event_slot(TRACKER_FLUSH, i); - pgagroal_kill_connection(i); + /* TODO - ssl */ + pgagroal_kill_connection(i, NULL); prefill = true; } else if (mode == FLUSH_ALL || mode == FLUSH_GRACEFULLY) @@ -712,7 +763,8 @@ pgagroal_flush(int mode) kill(config->connections[i].pid, SIGQUIT); pgagroal_prometheus_connection_flush(); pgagroal_tracking_event_slot(TRACKER_FLUSH, i); - pgagroal_kill_connection(i); + /* TODO - ssl */ + pgagroal_kill_connection(i, NULL); prefill = true; } else if (mode == FLUSH_GRACEFULLY) @@ -734,7 +786,8 @@ pgagroal_flush(int mode) atomic_store(&config->states[i], STATE_GRACEFULLY); pgagroal_prometheus_connection_flush(); pgagroal_tracking_event_slot(TRACKER_FLUSH, i); - pgagroal_kill_connection(i); + /* TODO - ssl */ + pgagroal_kill_connection(i, NULL); prefill = true; break; case STATE_IN_USE: @@ -812,9 +865,10 @@ pgagroal_prefill(bool initial) while (do_prefill(config->users[user].username, config->limits[i].database, size)) { int32_t slot = -1; + SSL* ssl = NULL; if (pgagroal_prefill_auth(config->users[user].username, config->users[user].password, - config->limits[i].database, &slot) != AUTH_SUCCESS) + config->limits[i].database, &slot, &ssl) != AUTH_SUCCESS) { pgagroal_log_warn("Invalid data for user '%s' using limit entry (%d)", config->limits[i].username, i + 1); @@ -828,7 +882,7 @@ pgagroal_prefill(bool initial) } } pgagroal_tracking_event_slot(TRACKER_PREFILL_KILL, slot); - pgagroal_kill_connection(slot); + pgagroal_kill_connection(slot, ssl); } break; @@ -839,7 +893,7 @@ pgagroal_prefill(bool initial) if (config->connections[slot].has_security != SECURITY_INVALID) { pgagroal_tracking_event_slot(TRACKER_PREFILL_RETURN, slot); - pgagroal_return_connection(slot, false); + pgagroal_return_connection(slot, ssl, false); } else { @@ -852,7 +906,7 @@ pgagroal_prefill(bool initial) } } pgagroal_tracking_event_slot(TRACKER_PREFILL_KILL, slot); - pgagroal_kill_connection(slot); + pgagroal_kill_connection(slot, ssl); break; } } @@ -1036,14 +1090,16 @@ remove_connection(char* username, char* database) { pgagroal_prometheus_connection_remove(); pgagroal_tracking_event_slot(TRACKER_REMOVE_CONNECTION, i); - pgagroal_kill_connection(i); + /* TODO - ssl */ + pgagroal_kill_connection(i, NULL); } } else { pgagroal_prometheus_connection_remove(); pgagroal_tracking_event_slot(TRACKER_REMOVE_CONNECTION, i); - pgagroal_kill_connection(i); + /* TODO - ssl */ + pgagroal_kill_connection(i, NULL); } return true; @@ -1099,6 +1155,8 @@ connection_details(int slot) pgagroal_log_trace(" Size: %zd", connection.security_lengths[i]); pgagroal_log_mem(&connection.security_messages[i], connection.security_lengths[i]); } + pgagroal_log_trace(" Session length: %d", connection.ssl_session_length); + pgagroal_log_mem(&connection.ssl_session, connection.ssl_session_length); break; case STATE_IN_USE: pgagroal_log_debug("pgagroal_pool_status: State: IN_USE"); @@ -1117,6 +1175,8 @@ connection_details(int slot) pgagroal_log_trace(" Size: %zd", connection.security_lengths[i]); pgagroal_log_mem(&connection.security_messages[i], connection.security_lengths[i]); } + pgagroal_log_trace(" Session length: %d", connection.ssl_session_length); + pgagroal_log_mem(&connection.ssl_session, connection.ssl_session_length); break; case STATE_GRACEFULLY: pgagroal_log_debug("pgagroal_pool_status: State: GRACEFULLY"); @@ -1135,6 +1195,8 @@ connection_details(int slot) pgagroal_log_trace(" Size: %zd", connection.security_lengths[i]); pgagroal_log_mem(&connection.security_messages[i], connection.security_lengths[i]); } + pgagroal_log_trace(" Session length: %d", connection.ssl_session_length); + pgagroal_log_mem(&connection.ssl_session, connection.ssl_session_length); break; case STATE_FLUSH: pgagroal_log_debug("pgagroal_pool_status: State: FLUSH"); @@ -1153,6 +1215,8 @@ connection_details(int slot) pgagroal_log_trace(" Size: %zd", connection.security_lengths[i]); pgagroal_log_mem(&connection.security_messages[i], connection.security_lengths[i]); } + pgagroal_log_trace(" Session length: %d", connection.ssl_session_length); + pgagroal_log_mem(&connection.ssl_session, connection.ssl_session_length); break; case STATE_IDLE_CHECK: pgagroal_log_debug("pgagroal_pool_status: State: IDLE CHECK"); @@ -1171,6 +1235,8 @@ connection_details(int slot) pgagroal_log_trace(" Size: %zd", connection.security_lengths[i]); pgagroal_log_mem(&connection.security_messages[i], connection.security_lengths[i]); } + pgagroal_log_trace(" Session length: %d", connection.ssl_session_length); + pgagroal_log_mem(&connection.ssl_session, connection.ssl_session_length); break; case STATE_VALIDATION: pgagroal_log_debug("pgagroal_pool_status: State: VALIDATION"); @@ -1189,6 +1255,8 @@ connection_details(int slot) pgagroal_log_trace(" Size: %zd", connection.security_lengths[i]); pgagroal_log_mem(&connection.security_messages[i], connection.security_lengths[i]); } + pgagroal_log_trace(" Session length: %d", connection.ssl_session_length); + pgagroal_log_mem(&connection.ssl_session, connection.ssl_session_length); break; case STATE_REMOVE: pgagroal_log_debug("pgagroal_pool_status: State: REMOVE"); @@ -1207,6 +1275,8 @@ connection_details(int slot) pgagroal_log_trace(" Size: %zd", connection.security_lengths[i]); pgagroal_log_mem(&connection.security_messages[i], connection.security_lengths[i]); } + pgagroal_log_trace(" Session length: %d", connection.ssl_session_length); + pgagroal_log_mem(&connection.ssl_session, connection.ssl_session_length); break; default: pgagroal_log_debug("pgagroal_pool_status: State %d Slot %d FD %d", state, slot, connection.fd); diff --git a/src/libpgagroal/security.c b/src/libpgagroal/security.c index a6c7927f..0499a551 100644 --- a/src/libpgagroal/security.c +++ b/src/libpgagroal/security.c @@ -62,9 +62,9 @@ static int get_auth_type(struct message* msg, int* auth_type); static int compare_auth_response(struct message* orig, struct message* response, int auth_type); -static int use_pooled_connection(SSL* c_ssl, int client_fd, int slot, char* username, char* database, int hba_method); +static int use_pooled_connection(SSL* c_ssl, int client_fd, int slot, char* username, char* database, int hba_method, SSL** server_ssl); static int use_unpooled_connection(struct message* msg, SSL* c_ssl, int client_fd, int slot, - char* username, int hba_method); + char* username, int hba_method, SSL** server_ssl); static int client_trust(SSL* c_ssl, int client_fd, char* username, char* password, int slot); static int client_password(SSL* c_ssl, int client_fd, char* username, char* password, int slot); static int client_md5(SSL* c_ssl, int client_fd, char* username, char* password, int slot); @@ -72,11 +72,11 @@ static int client_scram256(SSL* c_ssl, int client_fd, char* username, char* pass static int client_ok(SSL* c_ssl, int client_fd, int slot); static int server_passthrough(struct message* msg, int auth_type, SSL* c_ssl, int client_fd, int slot); static int server_authenticate(struct message* msg, int auth_type, char* username, char* password, - int slot); -static int server_trust(int slot); -static int server_password(char* username, char* password, int slot); -static int server_md5(char* username, char* password, int slot); -static int server_scram256(char* username, char* password, int slot); + int slot, SSL* server_ssl); +static int server_trust(int slot, SSL* server_ssl); +static int server_password(char* username, char* password, int slot, SSL* server_ssl); +static int server_md5(char* username, char* password, int slot, SSL* server_ssl); +static int server_scram256(char* username, char* password, int slot, SSL* server_ssl); static bool is_allowed(char* username, char* database, char* address, int* hba_method); static bool is_allowed_username(char* username, char* entry); @@ -124,6 +124,8 @@ static bool is_tls_user(char* username, char* database); static int create_ssl_ctx(bool client, SSL_CTX** ctx); static int create_ssl_client(SSL_CTX* ctx, char* key, char* cert, char* root, int socket, SSL** ssl); static int create_ssl_server(SSL_CTX* ctx, int socket, SSL** ssl); +static int establish_client_tls_connection(int slot, SSL** ssl); +static int create_client_tls_connection(int slot, SSL** ssl); static int auth_query(SSL* c_ssl, int client_fd, int slot, char* username, char* database, int hba_method); static int auth_query_get_connection(char* username, char* password, char* database, int* server_fd); @@ -134,7 +136,7 @@ static int auth_query_client_md5(SSL* c_ssl, int client_fd, char* username, char static int auth_query_client_scram256(SSL* c_ssl, int client_fd, char* username, char* shadow, int slot); int -pgagroal_authenticate(int client_fd, char* address, int* slot, SSL** client_ssl) +pgagroal_authenticate(int client_fd, char* address, int* slot, SSL** client_ssl, SSL** server_ssl) { int status = MESSAGE_STATUS_ERROR; int ret; @@ -154,6 +156,7 @@ pgagroal_authenticate(int client_fd, char* address, int* slot, SSL** client_ssl) *slot = -1; *client_ssl = NULL; + *server_ssl = NULL; /* Receive client calls - at any point if client exits return AUTH_ERROR */ status = pgagroal_read_timeout_message(NULL, client_fd, config->authentication_timeout, &msg); @@ -355,7 +358,7 @@ pgagroal_authenticate(int client_fd, char* address, int* slot, SSL** client_ssl) /* Get connection */ pgagroal_tracking_event_basic(TRACKER_AUTHENTICATE, username, database); - ret = pgagroal_get_connection(username, database, true, false, slot); + ret = pgagroal_get_connection(username, database, true, false, slot, server_ssl); if (ret != 0) { if (ret == 1) @@ -388,7 +391,7 @@ pgagroal_authenticate(int client_fd, char* address, int* slot, SSL** client_ssl) pgagroal_log_debug("authenticate: getting pooled connection"); pgagroal_free_message(msg); - ret = use_pooled_connection(c_ssl, client_fd, *slot, username, database, hba_method); + ret = use_pooled_connection(c_ssl, client_fd, *slot, username, database, hba_method, server_ssl); if (ret == AUTH_BAD_PASSWORD) { goto bad_password; @@ -404,7 +407,7 @@ pgagroal_authenticate(int client_fd, char* address, int* slot, SSL** client_ssl) { pgagroal_log_debug("authenticate: creating pooled connection"); - ret = use_unpooled_connection(request_msg, c_ssl, client_fd, *slot, username, hba_method); + ret = use_unpooled_connection(request_msg, c_ssl, client_fd, *slot, username, hba_method, server_ssl); if (ret == AUTH_BAD_PASSWORD) { goto bad_password; @@ -467,7 +470,7 @@ pgagroal_authenticate(int client_fd, char* address, int* slot, SSL** client_ssl) } int -pgagroal_prefill_auth(char* username, char* password, char* database, int* slot) +pgagroal_prefill_auth(char* username, char* password, char* database, int* slot, SSL** server_ssl) { int server_fd = -1; int auth_type = -1; @@ -480,28 +483,39 @@ pgagroal_prefill_auth(char* username, char* password, char* database, int* slot) config = (struct configuration*)shmem; + *slot = -1; + *server_ssl = NULL; + /* Get connection */ pgagroal_tracking_event_basic(TRACKER_PREFILL, username, database); - ret = pgagroal_get_connection(username, database, false, false, slot); + ret = pgagroal_get_connection(username, database, false, false, slot, server_ssl); if (ret != 0) { goto error; } server_fd = config->connections[*slot].fd; + if (config->servers[config->connections[*slot].server].host[0] != '/') + { + if (establish_client_tls_connection(*slot, server_ssl) != AUTH_SUCCESS) + { + goto error; + } + } + status = pgagroal_create_startup_message(username, database, &startup_msg); if (status != MESSAGE_STATUS_OK) { goto error; } - status = pgagroal_write_message(NULL, server_fd, startup_msg); + status = pgagroal_write_message(*server_ssl, server_fd, startup_msg); if (status != MESSAGE_STATUS_OK) { goto error; } - status = pgagroal_read_block_message(NULL, server_fd, &msg); + status = pgagroal_read_block_message(*server_ssl, server_fd, &msg); if (status != MESSAGE_STATUS_OK) { goto error; @@ -524,7 +538,7 @@ pgagroal_prefill_auth(char* username, char* password, char* database, int* slot) goto error; } - if (server_authenticate(msg, auth_type, username, password, *slot)) + if (server_authenticate(msg, auth_type, username, password, *slot, *server_ssl)) { goto error; } @@ -533,7 +547,7 @@ pgagroal_prefill_auth(char* username, char* password, char* database, int* slot) if (server_state == SERVER_NOTINIT || server_state == SERVER_NOTINIT_PRIMARY) { pgagroal_log_debug("Verify server mode: %d", config->connections[*slot].server); - pgagroal_update_server_state(*slot, server_fd); + pgagroal_update_server_state(*slot, server_fd, *server_ssl); pgagroal_server_status(); } @@ -552,10 +566,11 @@ pgagroal_prefill_auth(char* username, char* password, char* database, int* slot) if (*slot != -1) { pgagroal_tracking_event_slot(TRACKER_PREFILL_KILL, *slot); - pgagroal_kill_connection(*slot); + pgagroal_kill_connection(*slot, *server_ssl); } *slot = -1; + *server_ssl = NULL; pgagroal_free_copy_message(startup_msg); pgagroal_free_message(msg); @@ -920,6 +935,8 @@ pgagroal_remote_management_scram_sha256(char* username, char* password, int serv } } + /* TODO - establish_client_tls_connection */ + status = pgagroal_create_startup_message(username, "admin", &startup_msg); if (status != MESSAGE_STATUS_OK) { @@ -1249,7 +1266,7 @@ compare_auth_response(struct message* orig, struct message* response, int auth_t } static int -use_pooled_connection(SSL* c_ssl, int client_fd, int slot, char* username, char* database, int hba_method) +use_pooled_connection(SSL* c_ssl, int client_fd, int slot, char* username, char* database, int hba_method, SSL** server_ssl) { int status = MESSAGE_STATUS_ERROR; struct configuration* config = NULL; @@ -1410,7 +1427,7 @@ use_pooled_connection(SSL* c_ssl, int client_fd, int slot, char* username, char* static int use_unpooled_connection(struct message* request_msg, SSL* c_ssl, int client_fd, int slot, - char* username, int hba_method) + char* username, int hba_method, SSL** server_ssl) { int status = MESSAGE_STATUS_ERROR; int server_fd; @@ -1546,7 +1563,7 @@ use_unpooled_connection(struct message* request_msg, SSL* c_ssl, int client_fd, goto error; } - if (server_authenticate(auth_msg, auth_type, username, get_password(username), slot)) + if (server_authenticate(auth_msg, auth_type, username, get_password(username), slot, *server_ssl)) { if (pgagroal_socket_isvalid(client_fd)) { @@ -1567,7 +1584,7 @@ use_unpooled_connection(struct message* request_msg, SSL* c_ssl, int client_fd, if (server_state == SERVER_NOTINIT || server_state == SERVER_NOTINIT_PRIMARY) { pgagroal_log_debug("Verify server mode: %d", config->connections[slot].server); - pgagroal_update_server_state(slot, server_fd); + pgagroal_update_server_state(slot, server_fd, *server_ssl); pgagroal_server_status(); } @@ -2249,7 +2266,7 @@ server_passthrough(struct message* msg, int auth_type, SSL* c_ssl, int client_fd } static int -server_authenticate(struct message* msg, int auth_type, char* username, char* password, int slot) +server_authenticate(struct message* msg, int auth_type, char* username, char* password, int slot, SSL* server_ssl) { struct configuration* config = NULL; @@ -2271,19 +2288,19 @@ server_authenticate(struct message* msg, int auth_type, char* username, char* pa if (auth_type == SECURITY_TRUST) { - return server_trust(slot); + return server_trust(slot, server_ssl); } else if (auth_type == SECURITY_PASSWORD) { - return server_password(username, password, slot); + return server_password(username, password, slot, server_ssl); } else if (auth_type == SECURITY_MD5) { - return server_md5(username, password, slot); + return server_md5(username, password, slot, server_ssl); } else if (auth_type == SECURITY_SCRAM256) { - return server_scram256(username, password, slot); + return server_scram256(username, password, slot, server_ssl); } error: @@ -2294,7 +2311,7 @@ server_authenticate(struct message* msg, int auth_type, char* username, char* pa } static int -server_trust(int slot) +server_trust(int slot, SSL* server_ssl) { struct configuration* config = NULL; @@ -2308,7 +2325,7 @@ server_trust(int slot) } static int -server_password(char* username, char* password, int slot) +server_password(char* username, char* password, int slot, SSL* server_ssl) { int status = MESSAGE_STATUS_ERROR; int auth_index = 1; @@ -2329,7 +2346,7 @@ server_password(char* username, char* password, int slot) goto error; } - status = pgagroal_write_message(NULL, server_fd, password_msg); + status = pgagroal_write_message(server_ssl, server_fd, password_msg); if (status != MESSAGE_STATUS_OK) { goto error; @@ -2339,7 +2356,7 @@ server_password(char* username, char* password, int slot) memcpy(&config->connections[slot].security_messages[auth_index], password_msg->data, password_msg->length); auth_index++; - status = pgagroal_read_block_message(NULL, server_fd, &auth_msg); + status = pgagroal_read_block_message(server_ssl, server_fd, &auth_msg); if (auth_msg->length > SECURITY_BUFFER_SIZE) { pgagroal_log_error("Security message too large: %ld", auth_msg->length); @@ -2390,7 +2407,7 @@ server_password(char* username, char* password, int slot) } static int -server_md5(char* username, char* password, int slot) +server_md5(char* username, char* password, int slot, SSL* server_ssl) { int status = MESSAGE_STATUS_ERROR; int auth_index = 1; @@ -2447,7 +2464,7 @@ server_md5(char* username, char* password, int slot) goto error; } - status = pgagroal_write_message(NULL, server_fd, md5_msg); + status = pgagroal_write_message(server_ssl, server_fd, md5_msg); if (status != MESSAGE_STATUS_OK) { goto error; @@ -2457,7 +2474,7 @@ server_md5(char* username, char* password, int slot) memcpy(&config->connections[slot].security_messages[auth_index], md5_msg->data, md5_msg->length); auth_index++; - status = pgagroal_read_block_message(NULL, server_fd, &auth_msg); + status = pgagroal_read_block_message(server_ssl, server_fd, &auth_msg); if (auth_msg->length > SECURITY_BUFFER_SIZE) { pgagroal_log_error("Security message too large: %ld", auth_msg->length); @@ -2526,7 +2543,7 @@ server_md5(char* username, char* password, int slot) } static int -server_scram256(char* username, char* password, int slot) +server_scram256(char* username, char* password, int slot, SSL* server_ssl) { int status = MESSAGE_STATUS_ERROR; int auth_index = 1; @@ -2581,13 +2598,13 @@ server_scram256(char* username, char* password, int slot) memcpy(&config->connections[slot].security_messages[auth_index], sasl_response->data, sasl_response->length); auth_index++; - status = pgagroal_write_message(NULL, server_fd, sasl_response); + status = pgagroal_write_message(server_ssl, server_fd, sasl_response); if (status != MESSAGE_STATUS_OK) { goto error; } - status = pgagroal_read_block_message(NULL, server_fd, &msg); + status = pgagroal_read_block_message(server_ssl, server_fd, &msg); if (msg->length > SECURITY_BUFFER_SIZE) { pgagroal_log_error("Security message too large: %ld", msg->length); @@ -2645,13 +2662,13 @@ server_scram256(char* username, char* password, int slot) memcpy(&config->connections[slot].security_messages[auth_index], sasl_continue_response->data, sasl_continue_response->length); auth_index++; - status = pgagroal_write_message(NULL, server_fd, sasl_continue_response); + status = pgagroal_write_message(server_ssl, server_fd, sasl_continue_response); if (status != MESSAGE_STATUS_OK) { goto error; } - status = pgagroal_read_block_message(NULL, server_fd, &msg); + status = pgagroal_read_block_message(server_ssl, server_fd, &msg); if (msg->length > SECURITY_BUFFER_SIZE) { pgagroal_log_error("Security message too large: %ld", msg->length); @@ -3325,6 +3342,58 @@ pgagroal_tls_valid(void) return 1; } +int +pgagroal_load_tls_connection(int slot, SSL** ssl) +{ + int result = 0; + struct configuration* config; + + config = (struct configuration*)shmem; + + if (config->connections[slot].ssl_session_length > 0) + { + result = create_client_tls_connection(slot, ssl); + } + + return result; +} + +int +pgagroal_save_tls_connection(SSL* ssl, int slot) +{ + int length; + SSL_SESSION* session = NULL; + unsigned char* p = NULL; + struct configuration* config; + + config = (struct configuration*)shmem; + + config->connections[slot].ssl_session_length = 0; + memset(&config->connections[slot].ssl_session, 0, SSL_SESSION_BUFFER_SIZE); + + if (ssl != NULL) + { + p = (unsigned char*)config->connections[slot].ssl_session; + + session = SSL_get_session(ssl); + + length = i2d_SSL_SESSION(session, NULL); + if (length > SSL_SESSION_BUFFER_SIZE) + { + pgagroal_log_error("Could not save TLS session: %d (%d)", length, SSL_SESSION_BUFFER_SIZE); + goto error; + } + + config->connections[slot].ssl_session_length = i2d_SSL_SESSION(session, &p); + } + + return 0; + +error: + + return 1; +} + static int derive_key_iv(char *password, unsigned char *key, unsigned char *iv) { @@ -4312,7 +4381,7 @@ create_ssl_ctx(bool client, SSL_CTX** ctx) SSL_CTX_set_mode(c, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); SSL_CTX_set_options(c, SSL_OP_NO_TICKET); - SSL_CTX_set_session_cache_mode(c, SSL_SESS_CACHE_OFF); + SSL_CTX_set_session_cache_mode(c, SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE); *ctx = c; @@ -4335,7 +4404,7 @@ create_ssl_client(SSL_CTX* ctx, char* key, char* cert, char* root, int socket, S bool have_cert = false; bool have_rootcert = false; - if (strlen(root) > 0) + if (root != NULL && strlen(root) > 0) { if (SSL_CTX_load_verify_locations(ctx, root, NULL) != 1) { @@ -4350,7 +4419,7 @@ create_ssl_client(SSL_CTX* ctx, char* key, char* cert, char* root, int socket, S have_rootcert = true; } - if (strlen(cert) > 0) + if (cert != NULL && strlen(cert) > 0) { if (SSL_CTX_use_certificate_chain_file(ctx, cert) != 1) { @@ -4717,6 +4786,8 @@ auth_query_get_connection(char* username, char* password, char* database, int* s pgagroal_log_debug("connect: %s:%d using fd %d", config->servers[server].host, config->servers[server].port, *server_fd); + /* TODO - establish_client_tls_connection */ + /* Startup message */ status = pgagroal_create_startup_message(username, database, &startup_msg); if (status != MESSAGE_STATUS_OK) @@ -5613,3 +5684,168 @@ auth_query_client_scram256(SSL* c_ssl, int client_fd, char* username, char* shad return AUTH_ERROR; } + +static int +establish_client_tls_connection(int slot, SSL** ssl) +{ + int fd = -1; + struct configuration* config = NULL; + struct message* ssl_msg = NULL; + struct message* msg = NULL; + int status = -1; + + config = (struct configuration*)shmem; + + fd = config->connections[slot].fd; + + status = pgagroal_create_ssl_message(&ssl_msg); + if (status != MESSAGE_STATUS_OK) + { + goto error; + } + + status = pgagroal_write_message(NULL, fd, ssl_msg); + if (status != MESSAGE_STATUS_OK) + { + goto error; + } + + status = pgagroal_read_block_message(NULL, fd, &msg); + if (status != MESSAGE_STATUS_OK) + { + goto error; + } + + if (msg->kind == 'S') + { + create_client_tls_connection(slot, ssl); + } + + pgagroal_free_copy_message(ssl_msg); + pgagroal_free_message(msg); + + return AUTH_SUCCESS; + +error: + + pgagroal_log_error("establish_client_tls_connection: ERROR"); + + pgagroal_free_copy_message(ssl_msg); + pgagroal_free_message(msg); + + return AUTH_ERROR; +} + +static int +create_client_tls_connection(int slot, SSL** ssl) +{ + bool connect = true; + SSL_CTX* ctx = NULL; + SSL* s = NULL; + SSL_SESSION* session = NULL; + int fd = -1; + int status = -1; + unsigned char* p = NULL; + struct configuration* config; + + config = (struct configuration*)shmem; + + fd = config->connections[slot].fd; + + /* We are acting as a client against the server */ + if (create_ssl_ctx(true, &ctx)) + { + pgagroal_log_error("CTX failed"); + goto error; + } + + /* Create SSL structure */ + if (create_ssl_client(ctx, NULL, NULL, NULL, fd, &s)) + { + pgagroal_log_error("Client failed"); + goto error; + } + + /* If we have an existing session then load it */ + if (config->connections[slot].ssl_session_length > 0) + { + p = (unsigned char*)config->connections[slot].ssl_session; + + session = d2i_SSL_SESSION(NULL, (const unsigned char**)&p, config->connections[slot].ssl_session_length); + + pgagroal_log_error("SSL: %p", s); + pgagroal_log_error("SESSION: %p", session); + + if (session == NULL) + { + goto error; + } + + if (SSL_set_session(s, session) != 1) + { + goto error; + } + + if (SSL_set_fd(s, fd) != 1) + { + goto error; + } + + connect = false; + } + + if (connect) + { + do + { + status = SSL_connect(s); + /* status = SSL_do_handshake(s); */ + + if (status != 1) + { + int err = SSL_get_error(s, status); + switch (err) + { + case SSL_ERROR_ZERO_RETURN: + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + case SSL_ERROR_WANT_CONNECT: + case SSL_ERROR_WANT_ACCEPT: + case SSL_ERROR_WANT_X509_LOOKUP: + case SSL_ERROR_WANT_ASYNC: + case SSL_ERROR_WANT_ASYNC_JOB: + case SSL_ERROR_WANT_CLIENT_HELLO_CB: + break; + case SSL_ERROR_SYSCALL: + pgagroal_log_error("SSL_ERROR_SYSCALL: %s (%d)", strerror(errno), fd); + errno = 0; + goto error; + break; + case SSL_ERROR_SSL: + pgagroal_log_error("SSL_ERROR_SSL: %s (%d) Slot: %d", strerror(errno), fd, slot); + pgagroal_log_error("%s", ERR_error_string(err, NULL)); + pgagroal_log_error("%s", ERR_lib_error_string(err)); + pgagroal_log_error("%s", ERR_reason_error_string(err)); + errno = 0; + goto error; + break; + } + ERR_clear_error(); + } + } while (status != 1); + } + + *ssl = s; + + pgagroal_log_error("create_client_tls_connection: SUCCESS"); + + return AUTH_SUCCESS; + +error: + + pgagroal_log_error("create_client_tls_connection: ERROR"); + + *ssl = s; + + return AUTH_ERROR; +} diff --git a/src/libpgagroal/server.c b/src/libpgagroal/server.c index abbc9ce8..c50ef7ce 100644 --- a/src/libpgagroal/server.c +++ b/src/libpgagroal/server.c @@ -104,7 +104,7 @@ pgagroal_get_primary(int* server) } int -pgagroal_update_server_state(int slot, int socket) +pgagroal_update_server_state(int slot, int socket, SSL* ssl) { int status; int server; @@ -129,13 +129,13 @@ pgagroal_update_server_state(int slot, int socket) qmsg.length = size; qmsg.data = &is_recovery; - status = pgagroal_write_message(NULL, socket, &qmsg); + status = pgagroal_write_message(ssl, socket, &qmsg); if (status != MESSAGE_STATUS_OK) { goto error; } - status = pgagroal_read_block_message(NULL, socket, &tmsg); + status = pgagroal_read_block_message(ssl, socket, &tmsg); if (status != MESSAGE_STATUS_OK) { goto error; diff --git a/src/libpgagroal/worker.c b/src/libpgagroal/worker.c index ebf27ba9..e65e73b1 100644 --- a/src/libpgagroal/worker.c +++ b/src/libpgagroal/worker.c @@ -68,6 +68,7 @@ pgagroal_worker(int client_fd, char* address, char** argv) bool tx_pool = false; int32_t slot = -1; SSL* client_ssl = NULL; + SSL* server_ssl = NULL; pgagroal_start_logging(); pgagroal_memory_init(); @@ -87,7 +88,7 @@ pgagroal_worker(int client_fd, char* address, char** argv) pgagroal_prometheus_client_wait_add(); /* Authentication */ - auth_status = pgagroal_authenticate(client_fd, address, &slot, &client_ssl); + auth_status = pgagroal_authenticate(client_fd, address, &slot, &client_ssl, &server_ssl); if (auth_status == AUTH_SUCCESS) { pgagroal_log_debug("pgagroal_worker: Slot %d (%d -> %d)", slot, client_fd, config->connections[slot].fd); @@ -128,6 +129,7 @@ pgagroal_worker(int client_fd, char* address, char** argv) client_io.server_fd = config->connections[slot].fd; client_io.slot = slot; client_io.client_ssl = client_ssl; + client_io.server_ssl = server_ssl; if (config->pipeline != PIPELINE_TRANSACTION) { @@ -136,6 +138,7 @@ pgagroal_worker(int client_fd, char* address, char** argv) server_io.server_fd = config->connections[slot].fd; server_io.slot = slot; server_io.client_ssl = client_ssl; + server_io.server_ssl = server_ssl; } loop = ev_loop_new(pgagroal_libev(config->libev)); @@ -205,14 +208,14 @@ pgagroal_worker(int client_fd, char* address, char** argv) if (config->pipeline != PIPELINE_TRANSACTION) { pgagroal_tracking_event_slot(TRACKER_WORKER_RETURN1, slot); - pgagroal_return_connection(slot, tx_pool); + pgagroal_return_connection(slot, server_ssl, tx_pool); } } else if (exit_code == WORKER_SERVER_FAILURE || exit_code == WORKER_SERVER_FATAL || exit_code == WORKER_SHUTDOWN || exit_code == WORKER_FAILOVER || (exit_code == WORKER_FAILURE && config->connections[slot].has_security == SECURITY_INVALID)) { pgagroal_tracking_event_slot(TRACKER_WORKER_KILL1, slot); - pgagroal_kill_connection(slot); + pgagroal_kill_connection(slot, server_ssl); } else { @@ -221,12 +224,12 @@ pgagroal_worker(int client_fd, char* address, char** argv) config->connections[slot].has_security != SECURITY_INVALID) { pgagroal_tracking_event_slot(TRACKER_WORKER_RETURN2, slot); - pgagroal_return_connection(slot, tx_pool); + pgagroal_return_connection(slot, server_ssl, tx_pool); } else { pgagroal_tracking_event_slot(TRACKER_WORKER_KILL2, slot); - pgagroal_kill_connection(slot); + pgagroal_kill_connection(slot, server_ssl); } } }