Skip to content

Commit

Permalink
[#378] Vault Implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
ashu3103 committed Mar 9, 2024
1 parent d9f9253 commit efa0436
Show file tree
Hide file tree
Showing 19 changed files with 2,754 additions and 66 deletions.
2 changes: 1 addition & 1 deletion AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ Nikita Bugrovsky <[email protected]>
Lawrence Wu <[email protected]>
Yongting You <[email protected]>
Ashutosh Sharma <[email protected]>
Henrique de Carvalho <[email protected]>
Henrique de Carvalho <[email protected]>
1 change: 1 addition & 0 deletions doc/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ The available keys and their accepted values are reported in the table below.
| log_disconnections | `off` | Bool | No | Log disconnects |
| blocking_timeout | 30 | Int | No | The number of seconds the process will be blocking for a connection (disable = 0) |
| idle_timeout | 0 | Int | No | The number of seconds a connection is been kept alive (disable = 0) |
| rotate_frontend_password_timeout | 0 | Int | No | The number of seconds after which the passwords of frontend users updated periodically (disable = 0) |
| max_connection_age | 0 | Int | No | The maximum number of seconds that a connection will live (disable = 0) |
| validation | `off` | String | No | Should connection validation be performed. Valid options: `off`, `foreground` and `background` |
| background_interval | 300 | Int | No | The interval between background validation scans in seconds |
Expand Down
50 changes: 50 additions & 0 deletions doc/VAULT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# pgagroal-vault configuration

The configuration which is mandatory is loaded from either the path specified by the `-c` flag or `/etc/pgagroal/pgagroal_vault.conf`.

The configuration of `pgagroal-vault` is split into sections using the `[` and `]` characters.

The pgagroal-vault section, called `[pgagroal-vault]`, is where you configure the overall properties of the vault's server.

The other section provide configuration for the management port of pgagroal. For now there can be only one pgagroal management port to connect.
This section don't have any requirements to their naming so you can give them
meaningful names but generally named as `[main]`.

All properties within a section are in the format `key = value`.

The characters `#` and `;` can be used for comments. A line is totally ignored if the
very first non-space character is a comment one, but it is possible to put a comment at the end of a line.
The `Bool` data type supports the following values: `on`, `yes`, `1`, `true`, `off`, `no`, `0` and `false`.

See a more complete [sample](./etc/pgagroal_vault.conf) configuration for running `pgagroal-vault` on `localhost`.

## [pgagroal-vault]

This section is mandatory and the pooler will refuse to start if the configuration file does not specify one and only one. Usually this section is place on top of the configuration file, but its position within the file does not really matter.
The available keys and their accepted values are reported in the table below.

| Property | Default | Unit | Required | Description |
|----------|---------|------|----------|-------------|
| host | | String | Yes | The bind address for pgagroal-vault |
| port | | Int | Yes | The bind port for pgagroal-vault |
| tls | `off` | Bool | No | Enable Transport Layer Security (TLS) |
| tls_cert_file | | String | No | Certificate file for TLS. This file must be owned by either the user running pgagroal-vault or root. |
| tls_key_file | | String | No | Private key file for TLS. This file must be owned by either the user running pgagroal-vault or root. Additionally permissions must be at least `0640` when owned by root or `0600` otherwise. |
| tls_ca_file | | String | No | Certificate Authority (CA) file for TLS. This file must be owned by either the user running pgagroal-vault or root. |


## [main]

The section with a name different from `pgagroal-vault` will be treated as an main section.

| Property | Default | Unit | Required | Description |
|----------|---------|------|----------|-------------|
| host | | String | Yes | The address of the pgagroal running the management server |
| port | | Int | Yes | The management port of pgagroal |
| user | | String | Yes | The admin user of the pgagroal remote management service |
| tls | `off` | Bool | No | Enable Transport Layer Security (TLS) support (Experimental - no pooling) |
| tls_cert_file | | String | No | Certificate file for TLS. This file must be owned by either the user running pgagroal or root. |
| tls_key_file | | String | No | Private key file for TLS. This file must be owned by either the user running pgagroal or root. Additionally permissions must be at least `0640` when owned by root or `0600` otherwise. |
| tls_ca_file | | String | No | Certificate Authority (CA) file for TLS. This file must be owned by either the user running pgagroal or root. |

Note: For `pgagroal-vault` to function and connect properly to pgagroal, the remote server for management of the `pgagroal` should be enabled i.e. `management` should be greater than 0.
16 changes: 16 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -321,3 +321,19 @@ target_link_libraries(pgagroal-admin-bin pgagroal)

install(TARGETS pgagroal-admin-bin DESTINATION ${CMAKE_INSTALL_BINDIR})



#
# Build pgagroal-vault
#
add_executable(pgagroal-vault-bin vault.c ${RESOURCE_OBJECT})
if (CMAKE_C_LINK_PIE_SUPPORTED)
set_target_properties(pgagroal-vault-bin PROPERTIES LINKER_LANGUAGE C POSITION_INDEPENDENT_CODE TRUE OUTPUT_NAME pgagroal-vault)
else()
set_target_properties(pgagroal-vault-bin PROPERTIES LINKER_LANGUAGE C POSITION_INDEPENDENT_CODE FALSE OUTPUT_NAME pgagroal-vault)
endif()
target_link_libraries(pgagroal-vault-bin pgagroal)

install(TARGETS pgagroal-vault-bin DESTINATION ${CMAKE_INSTALL_BINDIR})


53 changes: 12 additions & 41 deletions src/admin.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,28 +45,18 @@
#include <sys/stat.h>
#include <err.h>

#define DEFAULT_PASSWORD_LENGTH 64
#define MIN_PASSWORD_LENGTH 8

#define ACTION_UNKNOWN 0
#define ACTION_MASTER_KEY 1
#define ACTION_ADD_USER 2
#define ACTION_UPDATE_USER 3
#define ACTION_REMOVE_USER 4
#define ACTION_LIST_USERS 5

static char CHARS[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '_', '=', '+', '[', '{', ']', '}', '\\', '|', ';', ':',
'\'', '\"', ',', '<', '.', '>', '/', '?'};

static int master_key(char* password, bool generate_pwd, int pwd_length);
static int add_user(char* users_path, char* username, char* password, bool generate_pwd, int pwd_length);
static int update_user(char* users_path, char* username, char* password, bool generate_pwd, int pwd_length);
static int remove_user(char* users_path, char* username);
static int list_users(char* users_path);
static char* generate_password(int pwd_length);

static void
version(void)
Expand Down Expand Up @@ -359,8 +349,10 @@ master_key(char* password, bool generate_pwd, int pwd_length)
}
else
{
password = generate_password(pwd_length);
do_free = false;
if(pgagroal_generate_password(pwd_length, &password)){
do_free = false;
goto error;
}
}
}
else
Expand Down Expand Up @@ -481,7 +473,10 @@ add_user(char* users_path, char* username, char* password, bool generate_pwd, in
password:
if (generate_pwd)
{
password = generate_password(pwd_length);
if(pgagroal_generate_password(pwd_length, &password)){
do_free = false;
goto error;
}
do_verify = false;
printf("Password : %s", password);
}
Expand Down Expand Up @@ -655,7 +650,10 @@ update_user(char* users_path, char* username, char* password, bool generate_pwd,
password:
if (generate_pwd)
{
password = generate_password(pwd_length);
if(pgagroal_generate_password(pwd_length, &password)){
do_free = false;
goto error;
}
do_verify = false;
printf("Password : %s", password);
}
Expand Down Expand Up @@ -903,30 +901,3 @@ list_users(char* users_path)

return 1;
}

static char*
generate_password(int pwd_length)
{
char* pwd;
size_t s;
time_t t;

s = pwd_length + 1;

pwd = calloc(1, s);
if (pwd == NULL)
{
pgagroal_log_fatal("Couldn't allocate memory while generating password");
return NULL;
}

srand((unsigned)time(&t));

for (int i = 0; i < s; i++)
{
*((char*)(pwd + i)) = CHARS[rand() % sizeof(CHARS)];
}
*((char*)(pwd + pwd_length)) = '\0';

return pwd;
}
73 changes: 73 additions & 0 deletions src/include/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ extern "C" {
* configuration file.
*/
#define PGAGROAL_MAIN_INI_SECTION "pgagroal"
/*
* The main section that must be present in the `pgagroal_vault.conf`
* configuration file.
*/
#define PGAGROAL_VAULT_INI_SECTION "pgagroal-vault"

/*
* The following constants are used to clearly identify
Expand Down Expand Up @@ -70,6 +75,14 @@ extern "C" {
int
pgagroal_init_configuration(void* shmem);

/**
* Initialize the vault configuration structure
* @param shmem The shared memory segment
* @return 0 upon success, otherwise 1
*/
int
pgagroal_vault_init_configuration(void* shmem);

/**
* Read the configuration from a file
* @param shmem The shared memory segment
Expand All @@ -96,6 +109,30 @@ pgagroal_read_configuration(void* shmem, char* filename, bool emitWarnings);
int
pgagroal_validate_configuration(void* shmem, bool has_unix_socket, bool has_main_sockets);

/**
* Read the configuration of vault from a file
* @param shmem The shared memory segment
* @param filename The file name
* @param emitWarnings true if unknown parameters have to
* reported on stderr
* @return 0 (i.e, PGAGROAL_CONFIGURATION_STATUS_OK) upon success, otherwise
* - PGAGROAL_CONFIGURATION_STATUS_FILE_NOT_FOUND if the file does not exists
* - PGAGROAL_CONFIGURATION_STATUS_FILE_TOO_BIG if the file contains too many sections
* - a positive value to indicate how many errors (with regard to sections) have been found
* - PGAGROAL_CONFIGURATION_STATUS_KO if the file has generic errors, most notably it lacks
* a [pgagroal-vault] section
*/
int
pgagroal_vault_read_configuration(void* shmem, char* filename, bool emitWarnings);

/**
* Validate the configuration of vault
* @param shmem The shared memory segment
* @return 0 upon success, otherwise 1
*/
int
pgagroal_vault_validate_configuration(void* shmem);

/**
* Read the HBA configuration from a file
* @param shmem The shared memory segment
Expand Down Expand Up @@ -193,6 +230,19 @@ pgagroal_validate_frontend_users_configuration(void* shmem);
int
pgagroal_read_admins_configuration(void* shmem, char* filename);

/**
* Read the USERS configuration of vault from a file
* @param shmem The shared memory segment
* @param filename The file name
* @return 0 (i.e, PGAGROAL_CONFIGURATION_STATUS_OK) upon success, otherwise
* - PGAGROAL_CONFIGURATION_STATUS_FILE_NOT_FOUND if the file does not exists
* - PGAGROAL_CONFIGURATION_STATUS_FILE_TOO_BIG if the file contains too many users
* (i.e., more users than the number defined in the limits)
* - PGAGROAL_CONFIGURATION_STATUS_CANNOT_DECRYPT to indicate a problem reading the content of the file
*/
int
pgagroal_vault_read_users_configuration(void* shmem, char* filename);

/**
* Validate the ADMINS configuration from a file
* @param shmem The shared memory segment
Expand Down Expand Up @@ -323,6 +373,29 @@ pgagroal_apply_main_configuration(struct configuration* config,
char* key,
char* value);

/**
* Function to apply a single configuration parameter.
*
* This is the backbone function used when parsing the main configuration file
* and is used to set any of the allowed parameters.
*
* @param config the configuration to apply values onto
* @param srv the server to which the configuration parameter refers to, if needed
* @param section the section of the file, main or server
* @param key the parameter name of the configuration
* @param value the value of the configuration
* @return 0 on success
*
* Examples of usage:
* pgagroal_apply_vault_configuration( config, NULL, PGAGROAL_VAULT_INI_SECTION, "log_level", "info" );
*/
int
pgagroal_apply_vault_configuration(struct vault_configuration* config,
struct vault_server* srv,
char* section,
char* key,
char* value);

/**
* Function to set a configuration value.
*
Expand Down
23 changes: 23 additions & 0 deletions src/include/management.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ extern "C" {
#define MANAGEMENT_CONFIG_GET 20
#define MANAGEMENT_CONFIG_SET 21
#define MANAGEMENT_CONFIG_LS 22
#define MANAGEMENT_GET_PASSWORD 23


/**
* Status for the 'ping' (i.e., is-alive) command
Expand All @@ -75,6 +77,27 @@ extern "C" {
#define COMMAND_OUTPUT_FORMAT_TEXT 'T'
#define COMMAND_OUTPUT_FORMAT_JSON 'J'


/**
* Get the frontend password of a user
* @param ssl The SSL connection
* @param socket The socket descriptor
* @param user The frontend user
* @param password The desired password
* @return 0 upon success, otherwise 1
*/
int
pgagroal_management_get_password(SSL* ssl, int socket, char* username, char* password);

/**
* Write the frontend password of a user to the socket
* @param socket The socket descriptor
* @param password The frontend user
* @return 0 upon success, otherwise 1
*/
int
pgagroal_management_write_get_password(int socket, char* password);

/**
* Read the management header
* @param socket The socket descriptor
Expand Down
20 changes: 20 additions & 0 deletions src/include/network.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ pgagroal_bind(const char* hostname, int port, int** fds, int* length);
int
pgagroal_bind_unix_socket(const char* directory, const char* file, int* fd);

/**
* Bind sockets for a host
* @param hostname The host name
* @param port The port number
* @param fd The resulting descriptor
* @return 0 upon success, otherwise 1
*/
int
pgagroal_vault_bind(const char* hostname, int port, int** fd);

/**
* Remove Unix Domain Socket directory
* @param directory The directory
Expand All @@ -76,6 +86,16 @@ pgagroal_remove_unix_socket(const char* directory, const char* file);
int
pgagroal_connect(const char* hostname, int port, int* fd);

/**
* Connect vault to pgagroal management port
* @param hostname The host name
* @param port The port number
* @param fd The resulting descriptor
* @return 0 upon success, otherwise 1
*/
int
pgagroal_vault_connect(const char* hostname, int port, int* fd);

/**
* Connect to a Unix Domain Socket
* @param directory The directory
Expand Down
Loading

0 comments on commit efa0436

Please sign in to comment.