Skip to content

Commit

Permalink
[agroal#70] TLS support: pgagroal - PostgreSQL
Browse files Browse the repository at this point in the history
  • Loading branch information
jesperpedersen committed Nov 9, 2021
1 parent 2d80588 commit 86515e8
Show file tree
Hide file tree
Showing 14 changed files with 483 additions and 91 deletions.
1 change: 1 addition & 0 deletions doc/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
};
Expand Down
10 changes: 7 additions & 3 deletions src/include/pgagroal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 */
Expand Down
10 changes: 7 additions & 3 deletions src/include/pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ extern "C" {

#include <stdbool.h>
#include <stdlib.h>
#include <openssl/ssl.h>

/**
* Get a connection
Expand All @@ -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
Expand Down
24 changes: 22 additions & 2 deletions src/include/security.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,23 @@ 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
* @param username The user name
* @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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion src/include/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ extern "C" {
#include <pgagroal.h>

#include <stdlib.h>
#include <openssl/ssl.h>

/**
* Get the primary server
Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/include/worker.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 4 additions & 2 deletions src/libpgagroal/management.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
18 changes: 16 additions & 2 deletions src/libpgagroal/pipeline_perf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
18 changes: 16 additions & 2 deletions src/libpgagroal/pipeline_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down
33 changes: 27 additions & 6 deletions src/libpgagroal/pipeline_transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
Expand All @@ -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);

Expand All @@ -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;

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -392,14 +404,22 @@ 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))
{
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);
Expand Down Expand Up @@ -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;
}
Expand Down
Loading

0 comments on commit 86515e8

Please sign in to comment.