Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HBA support #276

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ RUN cd test_dir && make ODY_DIR=/test_dir BUILD_TEST_ASAN_DIR=build-asan clean b

COPY --from=base /ody-intergration-test/pkg/ody-intergration-test /ody-intergration-test
COPY docker/scram /scram
COPY docker/hba /hba
COPY test/shell-test /shell-test

COPY docker/entrypoint.sh /usr/local/bin/entrypoint.sh
Expand Down
4 changes: 2 additions & 2 deletions docker/bin/setup
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ if ! /usr/bin/pg_ctlcluster 13 main start && psql -h localhost -p 5432 -U postgr
fi

# Create databases
for database_name in db scram_db; do
for database_name in db hba_db scram_db; do
sudo -u postgres createdb $database_name >> "$SETUP_LOG" 2>&1 || {
echo "ERROR: 'createdb $database_name' failed, examine the log"
cat "$SETUP_LOG"
Expand All @@ -30,7 +30,7 @@ for database_name in db scram_db; do
done

# Create users
psql -h localhost -p 5432 -U postgres -c "set password_encryption = 'scram-sha-256'; create user scram_user password 'scram_user_password';" db >> $SETUP_LOG 2>&1 || {
psql -h localhost -p 5432 -U postgres -c "create user user_allow password 'correct_password'; create user user_reject password 'correct_password'; create user user_unknown password 'correct_password'; set password_encryption = 'scram-sha-256'; create user scram_user password 'scram_user_password';" db >> $SETUP_LOG 2>&1 || {
echo "ERROR: users creation failed, examine the log"
cat "$SETUP_LOG"
exit 1
Expand Down
8 changes: 8 additions & 0 deletions docker/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ setup
/scram/test_scram_frontend.sh
ody-stop

/usr/bin/odyssey /hba/unix.conf
/hba/test_hba_unix.sh
ody-stop

/usr/bin/odyssey /hba/host.conf
/hba/test_hba_host.sh
ody-stop

/ody-intergration-test

ody-stop
Expand Down
54 changes: 54 additions & 0 deletions docker/hba/common.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
storage "postgres_server" {
type "remote"

host "127.0.0.1"
port 5432
}

database "hba_db" {
user "user_allow" {
authentication "clear_text"
password "correct_password"

storage "postgres_server"
storage_db "hba_db"

pool "session"
}

user "user_reject" {
authentication "clear_text"
password "correct_password"

storage "postgres_server"
storage_db "hba_db"

pool "session"
}

user "user_unknown" {
authentication "clear_text"
password "correct_password"

storage "postgres_server"
storage_db "hba_db"

pool "session"
}
}

daemonize yes
pid_file "odyssey/data/odyssey.pid"

unix_socket_dir "/tmp"
unix_socket_mode "0644"

locks_dir "/tmp"

log_format ""
log_to_stdout no
log_config no
log_debug no
log_session no
log_stats no
log_query no
8 changes: 8 additions & 0 deletions docker/hba/host.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
include "/hba/common.conf"

hba_file "/hba/host_hba.conf"

listen {
host "127.0.0.1"
port 6432
}
2 changes: 2 additions & 0 deletions docker/hba/host_hba.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
host hba_db user_allow 127.0.0.0/24 trust
host hba_db user_reject 127.0.0.0/24 reject
22 changes: 22 additions & 0 deletions docker/hba/test_hba_host.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

PGPASSWORD=correct_password psql -h localhost -p 6432 -U user_allow -c "SELECT 1" hba_db > /dev/null 2>&1 || {
echo "ERROR: failed auth with hba trust, correct password and plain password in config"
exit 1
}

PGPASSWORD=incorrect_password psql -h localhost -p 6432 -U user_allow -c "SELECT 1" hba_db > /dev/null 2>&1 && {
echo "ERROR: successfully auth with hba trust, but incorrect password"
exit 1
}

PGPASSWORD=correct_password psql -h localhost -p 6432 -U user_reject -c "SELECT 1" hba_db > /dev/null 2>&1 && {
echo "ERROR: successfully auth with hba reject"
exit 1
}

PGPASSWORD=correct_password psql -h localhost -p 6432 -U user_unknown -c "SELECT 1" hba_db > /dev/null 2>&1 && {
echo "ERROR: successfully auth without hba rule"
exit 1
}

exit 0
12 changes: 12 additions & 0 deletions docker/hba/test_hba_unix.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

PGPASSWORD=correct_password psql -h /tmp -p 6432 -U user_allow -c "SELECT 1" hba_db > /dev/null 2>&1 || {
echo "ERROR: failed auth with hba trust, correct password and plain password in config"
exit 1
}

PGPASSWORD=correct_password psql -h /tmp -p 6432 -U user_reject -c "SELECT 1" hba_db > /dev/null 2>&1 && {
echo "ERROR: successfully auth with hba reject"
exit 1
}

exit 0
7 changes: 7 additions & 0 deletions docker/hba/unix.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
include "/hba/common.conf"

hba_file "hba/unix_hba.conf"

listen {
port 6432
}
2 changes: 2 additions & 0 deletions docker/hba/unix_hba.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
local hba_db user_allow trust
local hba_db user_reject reject
15 changes: 15 additions & 0 deletions documentation/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,21 @@ reply with 'too many connections'.

`client_max 100`

#### hba\_file *string*

Path to file containing host based authentication rules.
Omit this option to disable HBA.

`hba_file "path"`

HBA file format follows the format of the PostgreSQL `pg_hba.conf` file.
* Supported record types: `local`, `host`, `hostssl`, `hostnossl`.
* Database field: `all`, `sameuser`, multiple names.
* User field: `all`, multiple names.
* Address field: IPv4 or IPv6 range.
* Auth-method field: `reject`, which leads to immediate disconnection,
or `trust`, which means applying auth method specified in matching route.

### Listen

Listen section defines listening servers used for accepting
Expand Down
14 changes: 14 additions & 0 deletions odyssey.conf
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,20 @@ enable_online_restart no

bindwith_reuseport no

#
# Host based authentication rules file path.
# File format is similar to PostgreSQL pg_hba.conf with a few limitations.
# Supported record types: `local`, `host`, `hostssl`, `hostnossl`.
# Database field: `all`, `sameuser`, multiple names.
# User field: `all`, multiple names.
# Address field: IPv4 or IPv6 range.
# Auth-method field: `reject`, which leads to immediate disconnection,
# or `trust`, which means applying auth method specified in matching route.
#
# By default HBA is disabled. Uncomment and set value to enable.
#
# hba_file "path"

###
### LOGGING
###
Expand Down
4 changes: 4 additions & 0 deletions pg_hba-dev.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
local all all trust
host postgres user1,user2 127.0.0.0 255.255.255.0 trust
host other all 127.0.0.0/24 reject
host all all fe80::/64 reject
5 changes: 4 additions & 1 deletion sources/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ set(od_src
watchdog.c
ejection.c
thread_global.c
compression.c)
compression.c
hba.c
hba_reader.c
hba_rule.c)

if (PAM_FOUND)
list(APPEND od_src pam.c)
Expand Down
7 changes: 7 additions & 0 deletions sources/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ void od_config_init(od_config_t *config)
config->cache_coroutine = 0;
config->cache_msg_gc_size = 0;
config->coroutine_stack_size = 4;
config->hba_file = NULL;
od_list_init(&config->listen);
}

Expand Down Expand Up @@ -84,6 +85,8 @@ void od_config_free(od_config_t *config)
if (config->locks_dir) {
free(config->locks_dir);
}
if (config->hba_file)
free(config->hba_file);
}

od_config_listen_t *od_config_listen_add(od_config_t *config)
Expand Down Expand Up @@ -295,6 +298,10 @@ void od_config_print(od_config_t *config, od_logger_t *logger)
od_log(logger, "config", NULL, NULL,
"socket bind with: SO_REUSEPORT");
}
if (config->hba_file) {
od_log(logger, "config", NULL, NULL,
"hba_file %s", config->hba_file);
}
#ifdef USE_SCRAM
od_log(logger, "config", NULL, NULL, "SCRAM auth metod: OK");
#endif
Expand Down
1 change: 1 addition & 0 deletions sources/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ struct od_config {
int cache_coroutine;
int cache_msg_gc_size;
int coroutine_stack_size;
char *hba_file;
od_list_t listen;
};

Expand Down
1 change: 1 addition & 0 deletions sources/config_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ typedef struct {
od_config_t *config;
od_rules_t *rules;
od_error_t *error;
od_hba_rules_t *hba_rules;
char *config_file;
char *data;
int data_size;
Expand Down
35 changes: 33 additions & 2 deletions sources/config_reader.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ enum { OD_LYES,
OD_LAUTH_QUERY_USER,
OD_LQUANTILES,
OD_LMODULE,
OD_LHBA_FILE,
};

static od_keyword_t od_config_keywords[] = {
Expand Down Expand Up @@ -181,6 +182,7 @@ static od_keyword_t od_config_keywords[] = {
od_keyword("auth_pam_service", OD_LAUTH_PAM_SERVICE),
od_keyword("quantiles", OD_LQUANTILES),
od_keyword("load_module", OD_LMODULE),
od_keyword("hba_file", OD_LHBA_FILE),
{ 0, 0, 0 }
};

Expand Down Expand Up @@ -961,6 +963,23 @@ static int od_config_reader_database(od_config_reader_t *reader,
return -1;
}

static int od_config_reader_hba_import(od_config_reader_t *config_reader)
{
od_config_reader_t reader;
memset(&reader, 0, sizeof(reader));
reader.config = config_reader->config;
reader.error = config_reader->error;
reader.hba_rules = config_reader->hba_rules;
int rc;
rc = od_config_reader_open(&reader, config_reader->config->hba_file);
if (rc == -1)
return -1;
rc = od_hba_reader_parse(&reader);
od_config_reader_close(&reader);

return rc;
}

static int od_config_reader_parse(od_config_reader_t *reader,
od_module_t *modules)
{
Expand Down Expand Up @@ -996,7 +1015,9 @@ static int od_config_reader_parse(od_config_reader_t *reader,
return -1;
rc = od_config_reader_import(reader->config,
reader->rules,
reader->error, modules,
reader->error,
modules,
reader->hba_rules,
config_file);
free(config_file);
if (rc == -1) {
Expand Down Expand Up @@ -1314,6 +1335,15 @@ static int od_config_reader_parse(od_config_reader_t *reader,
}
continue;
}
case OD_LHBA_FILE: {
rc = od_config_reader_string(reader, &config->hba_file);
if (rc == -1)
goto error;
rc = od_config_reader_hba_import(reader);
if (rc == -1)
goto error;
continue;
}
default:
od_config_reader_error(reader, &token,
"unexpected parameter");
Expand All @@ -1334,13 +1364,14 @@ static int od_config_reader_parse(od_config_reader_t *reader,

int od_config_reader_import(od_config_t *config, od_rules_t *rules,
od_error_t *error, od_module_t *modules,
char *config_file)
od_hba_rules_t *hba_rules, char *config_file)
{
od_config_reader_t reader;
memset(&reader, 0, sizeof(reader));
reader.error = error;
reader.config = config;
reader.rules = rules;
reader.hba_rules = hba_rules;
int rc;
rc = od_config_reader_open(&reader, config_file);
if (rc == -1) {
Expand Down
2 changes: 1 addition & 1 deletion sources/config_reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
*/

int od_config_reader_import(od_config_t *, od_rules_t *, od_error_t *,
od_module_t *, char *);
od_module_t *, od_hba_rules_t *, char *);

#endif /* ODYSSEY_CONFIG_READER_H */
10 changes: 9 additions & 1 deletion sources/frontend.c
Original file line number Diff line number Diff line change
Expand Up @@ -1252,8 +1252,16 @@ void od_frontend(void *arg)
}
}

/* HBA check */
rc = od_hba_process(client);

/* client authentication */
rc = od_auth_frontend(client);
if (rc == OK_RESPONSE) {
rc = od_auth_frontend(client);
} else {
od_frontend_error(client, KIWI_INVALID_PASSWORD,
"host based authentication rejected");
}

if (rc != OK_RESPONSE) {
goto cleanup;
Expand Down
4 changes: 3 additions & 1 deletion sources/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,20 @@ struct od_global {
void *cron;
void *worker_pool;
void *modules;
void *hba;
};

static inline void od_global_init(od_global_t *global, void *instance,
void *system, void *router, void *cron,
void *worker_pool, void *modules)
void *worker_pool, void *modules, void *hba)
{
global->instance = instance;
global->system = system;
global->router = router;
global->cron = cron;
global->worker_pool = worker_pool;
global->modules = modules;
global->hba = hba;
}

#endif /* ODYSSEY_GLOBAL_H */
Loading