From a9078737157f2162f395a61944ad712b79881d78 Mon Sep 17 00:00:00 2001 From: Dmitry Simonenko Date: Thu, 26 Apr 2018 16:02:18 +0300 Subject: [PATCH] odyssey: implement authenitcation "cert" --- odyssey.conf | 5 +++-- sources/auth.c | 30 ++++++++++++++++++++++++++++++ sources/config.c | 4 +++- sources/config.h | 3 ++- 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/odyssey.conf b/odyssey.conf index e8b641a6..3438b5c3 100644 --- a/odyssey.conf +++ b/odyssey.conf @@ -275,11 +275,11 @@ listen { # "verify_ca" - require valid client certificate # "verify_full" - require valid client ceritifcate # -# tls "disable" +# tls "disable" # tls_cert_file "" # tls_key_file "" # tls_ca_file "" -# tls_protocols "" +# tls_protocols "tlsv1.2" } ### @@ -346,6 +346,7 @@ database default { # "block" - block this user # "clear_text" - PostgreSQL clear text authentication # "md5" - PostgreSQL MD5 authentication +# "cert" - Compare client certificate CommonName with username # authentication "none" diff --git a/sources/auth.c b/sources/auth.c index 5adad025..f698e35d 100644 --- a/sources/auth.c +++ b/sources/auth.c @@ -258,6 +258,31 @@ od_auth_frontend_md5(od_client_t *client) return 0; } +static inline int +od_auth_frontend_cert(od_client_t *client) +{ + od_instance_t *instance = client->global->instance; + if (! client->startup.is_ssl_request) { + od_error(&instance->logger, "auth", client, NULL, + "TLS connection required"); + od_frontend_error(client, SHAPITO_INVALID_AUTHORIZATION_SPECIFICATION, + "TLS connection required"); + return -1; + } + /* compare client certificate common name with user name */ + od_route_t *route = client->route; + int rc; + rc = machine_io_verify(client->io, route->config->user_name); + if (rc == -1) { + od_error(&instance->logger, "auth", client, NULL, + "TLS certificate common name mismatch"); + od_frontend_error(client, SHAPITO_INVALID_PASSWORD, + "TLS certificate common name mismatch"); + return -1; + } + return 0; +} + static inline int od_auth_frontend_block(od_client_t *client) { @@ -288,6 +313,11 @@ int od_auth_frontend(od_client_t *client) if (rc == -1) return -1; break; + case OD_AUTH_CERT: + rc = od_auth_frontend_cert(client); + if (rc == -1) + return -1; + break; case OD_AUTH_BLOCK: od_auth_frontend_block(client); return -1; diff --git a/sources/config.c b/sources/config.c index c3bc0094..ea79cd7e 100644 --- a/sources/config.c +++ b/sources/config.c @@ -513,7 +513,6 @@ int od_config_validate(od_config_t *config, od_logger_t *logger) } else if (strcmp(route->auth, "clear_text") == 0) { route->auth_mode = OD_AUTH_CLEAR_TEXT; - if (route->password == NULL && route->auth_query == NULL) { od_error(logger, "config", NULL, NULL, "route '%s.%s': password is not set", @@ -529,6 +528,9 @@ int od_config_validate(od_config_t *config, od_logger_t *logger) route->db_name, route->user_name); return -1; } + } else + if (strcmp(route->auth, "cert") == 0) { + route->auth_mode = OD_AUTH_CERT; } else { od_error(logger, "config", NULL, NULL, "route '%s.%s': has unknown authentication mode", diff --git a/sources/config.h b/sources/config.h index add8ba27..71f20a8b 100644 --- a/sources/config.h +++ b/sources/config.h @@ -30,7 +30,8 @@ typedef enum OD_AUTH_NONE, OD_AUTH_BLOCK, OD_AUTH_CLEAR_TEXT, - OD_AUTH_MD5 + OD_AUTH_MD5, + OD_AUTH_CERT } od_auth_t; typedef enum