Pass auth information to server after recieving it from auth_query

This should fix #291 for MD5
This commit is contained in:
Andrey Borodin 2021-04-19 17:27:19 +05:00
parent e532cacca0
commit 8dace7befe
8 changed files with 60 additions and 43 deletions

View File

@ -77,12 +77,10 @@ static inline int od_auth_frontend_cleartext(od_client_t *client)
/* use remote or local password source */
kiwi_password_t client_password;
kiwi_password_init(&client_password);
if (client->rule->auth_query) {
char peer[128];
od_getpeername(client->io.io, peer, sizeof(peer), 1, 0);
rc = od_auth_query(client->global, client->rule, peer,
&client->startup.user, &client_password);
rc = od_auth_query(client, peer);
if (rc == -1) {
od_error(&instance->logger, "auth", client, NULL,
"failed to make auth_query");
@ -91,12 +89,11 @@ static inline int od_auth_frontend_cleartext(od_client_t *client)
KIWI_INVALID_AUTHORIZATION_SPECIFICATION,
"failed to make auth query");
kiwi_password_free(&client_token);
kiwi_password_free(&client_password);
machine_msg_free(msg);
return -1;
}
if (client_password.password == NULL) {
if (client->password.password == NULL) {
od_log(&instance->logger, "auth", client, NULL,
"user '%s.%s' incorrect user from %s",
client->startup.database.value,
@ -107,6 +104,7 @@ static inline int od_auth_frontend_cleartext(od_client_t *client)
machine_msg_free(msg);
return -1;
}
client_password = client->password;
} else {
client_password.password_len = client->rule->password_len + 1;
client_password.password = client->rule->password;
@ -116,8 +114,6 @@ static inline int od_auth_frontend_cleartext(od_client_t *client)
int check = kiwi_password_compare(&client_password, &client_token);
kiwi_password_free(&client_token);
machine_msg_free(msg);
if (client->rule->auth_query)
kiwi_password_free(&client_password);
if (check)
return 0;
@ -188,13 +184,11 @@ static inline int od_auth_frontend_md5(od_client_t *client)
kiwi_password_init(&client_password);
kiwi_password_t query_password;
kiwi_password_init(&query_password);
if (client->rule->auth_query) {
char peer[128];
od_getpeername(client->io.io, peer, sizeof(peer), 1, 0);
rc = od_auth_query(client->global, client->rule, peer,
&client->startup.user, &query_password);
rc = od_auth_query(client, peer);
if (rc == -1) {
od_error(&instance->logger, "auth", client, NULL,
"failed to make auth_query");
@ -208,7 +202,7 @@ static inline int od_auth_frontend_md5(od_client_t *client)
return -1;
}
if (query_password.password == NULL) {
if (client->password.password == NULL) {
od_log(&instance->logger, "auth", client, NULL,
"user '%s.%s' incorrect user from %s",
client->startup.database.value,
@ -219,7 +213,9 @@ static inline int od_auth_frontend_md5(od_client_t *client)
machine_msg_free(msg);
return -1;
}
query_password.password_len--;
query_password = client->password;
query_password.password_len = client->password.password_len - 1;
} else {
query_password.password_len = client->rule->password_len;
query_password.password = client->rule->password;
@ -246,8 +242,6 @@ static inline int od_auth_frontend_md5(od_client_t *client)
kiwi_password_free(&client_password);
kiwi_password_free(&client_token);
machine_msg_free(msg);
if (client->rule->auth_query)
kiwi_password_free(&query_password);
if (!check) {
od_log(&instance->logger, "auth", client, NULL,
@ -334,8 +328,7 @@ static inline int od_auth_frontend_scram_sha_256(od_client_t *client)
if (client->rule->auth_query) {
char peer[128];
od_getpeername(client->io.io, peer, sizeof(peer), 1, 0);
rc = od_auth_query(client->global, client->rule, peer,
&client->startup.user, &query_password);
rc = od_auth_query(client, peer);
if (rc == -1) {
od_error(&instance->logger, "auth", client, NULL,
"failed to make auth_query");
@ -348,7 +341,7 @@ static inline int od_auth_frontend_scram_sha_256(od_client_t *client)
return -1;
}
if (query_password.password == NULL) {
if (client->password.password == NULL) {
od_log(&instance->logger, "auth", client, NULL,
"user '%s.%s' incorrect user from %s",
client->startup.database.value,
@ -358,7 +351,8 @@ static inline int od_auth_frontend_scram_sha_256(od_client_t *client)
machine_msg_free(msg);
return -1;
}
query_password.password_len--;
query_password = client->password;
} else {
query_password.password_len = client->rule->password_len;
query_password.password = client->rule->password;
@ -637,7 +631,8 @@ int od_auth_frontend(od_client_t *client)
return 0;
}
static inline int od_auth_backend_cleartext(od_server_t *server)
static inline int od_auth_backend_cleartext(od_server_t *server,
od_client_t *client)
{
od_instance_t *instance = server->global->instance;
od_route_t *route = server->route;
@ -649,7 +644,11 @@ static inline int od_auth_backend_cleartext(od_server_t *server)
/* use storage or user password */
char *password;
int password_len;
if (route->rule->storage_password) {
if (client != NULL && client->password.password != NULL) {
password = client->password.password;
password_len = client->password.password_len - 1;
} else if (route->rule->storage_password) {
password = route->rule->storage_password;
password_len = route->rule->storage_password_len;
} else if (route->rule->password) {
@ -680,7 +679,8 @@ static inline int od_auth_backend_cleartext(od_server_t *server)
return 0;
}
static inline int od_auth_backend_md5(od_server_t *server, char salt[4])
static inline int od_auth_backend_md5(od_server_t *server, char salt[4],
od_client_t *client)
{
od_instance_t *instance = server->global->instance;
od_route_t *route = server->route;
@ -703,7 +703,10 @@ static inline int od_auth_backend_md5(od_server_t *server, char salt[4])
/* use storage or user password */
char *password;
int password_len;
if (route->rule->storage_password) {
if (client != NULL && client->password.password != NULL) {
password = client->password.password;
password_len = client->password.password_len - 1;
} else if (route->rule->storage_password) {
password = route->rule->storage_password;
password_len = route->rule->storage_password_len;
} else if (route->rule->password) {
@ -750,7 +753,7 @@ static inline int od_auth_backend_md5(od_server_t *server, char salt[4])
#ifdef USE_SCRAM
static inline int od_auth_backend_sasl(od_server_t *server)
static inline int od_auth_backend_sasl(od_server_t *server, od_client_t *client)
{
od_instance_t *instance = server->global->instance;
od_route_t *route = server->route;
@ -768,7 +771,8 @@ static inline int od_auth_backend_sasl(od_server_t *server)
od_debug(&instance->logger, "auth", NULL, server,
"requested SASL authentication");
if (!route->rule->storage_password && !route->rule->password) {
if (!route->rule->storage_password && !route->rule->password &&
(client == NULL || client->password.password == NULL)) {
od_error(&instance->logger, "auth", NULL, server,
"password required for route '%s.%s'",
route->rule->db_name, route->rule->user_name);
@ -798,7 +802,8 @@ static inline int od_auth_backend_sasl(od_server_t *server)
}
static inline int od_auth_backend_sasl_continue(od_server_t *server,
char *auth_data,
size_t auth_data_size)
size_t auth_data_size,
od_client_t *client)
{
od_instance_t *instance = server->global->instance;
od_route_t *route = server->route;
@ -824,7 +829,13 @@ static inline int od_auth_backend_sasl_continue(od_server_t *server,
/* use storage or user password */
char *password;
if (route->rule->storage_password) {
if (client != NULL && client->password.password != NULL) {
od_error(&instance->logger, "auth", NULL, server,
"cannot authenticate with SCRAM secret from auth_query",
route->rule->db_name, route->rule->user_name);
return -1;
} else if (route->rule->storage_password) {
password = route->rule->storage_password;
} else if (route->rule->password) {
password = route->rule->password;
@ -895,7 +906,8 @@ static inline int od_auth_backend_sasl_final(od_server_t *server,
#endif
int od_auth_backend(od_server_t *server, machine_msg_t *msg)
int od_auth_backend(od_server_t *server, machine_msg_t *msg,
od_client_t *client)
{
od_instance_t *instance = server->global->instance;
assert(*(char *)machine_msg_data(msg) == KIWI_BE_AUTHENTICATION);
@ -920,24 +932,24 @@ int od_auth_backend(od_server_t *server, machine_msg_t *msg)
return 0;
/* AuthenticationCleartextPassword */
case 3:
rc = od_auth_backend_cleartext(server);
rc = od_auth_backend_cleartext(server, client);
if (rc == -1)
return -1;
break;
/* AuthenticationMD5Password */
case 5:
rc = od_auth_backend_md5(server, salt);
rc = od_auth_backend_md5(server, salt, client);
if (rc == -1)
return -1;
break;
#ifdef USE_SCRAM
/* AuthenticationSASL */
case 10:
return od_auth_backend_sasl(server);
return od_auth_backend_sasl(server, client);
/* AuthenticationSASLContinue */
case 11:
return od_auth_backend_sasl_continue(server, auth_data,
auth_data_size);
auth_data_size, client);
/* AuthenticationSASLContinue */
case 12:
return od_auth_backend_sasl_final(server, auth_data,

View File

@ -8,6 +8,6 @@
*/
int od_auth_frontend(od_client_t *);
int od_auth_backend(od_server_t *, machine_msg_t *);
int od_auth_backend(od_server_t *, machine_msg_t *, od_client_t *);
#endif /* ODYSSEY_AUTH_H */

View File

@ -177,9 +177,12 @@ od_auth_query_format(od_rule_t *rule, kiwi_var_t *user, char *peer,
return dst_pos - output;
}
int od_auth_query(od_global_t *global, od_rule_t *rule, char *peer,
kiwi_var_t *user, kiwi_password_t *password)
int od_auth_query(od_client_t *client, char *peer)
{
od_global_t *global = client->global;
od_rule_t *rule = client->rule;
kiwi_var_t *user = &client->startup.user;
kiwi_password_t *password = &client->password;
od_instance_t *instance = global->instance;
od_router_t *router = global->router;
@ -223,7 +226,7 @@ int od_auth_query(od_global_t *global, od_rule_t *rule, char *peer,
/* connect to server, if necessary */
int rc;
if (server->io.io == NULL) {
rc = od_backend_connect(server, "auth_query", NULL);
rc = od_backend_connect(server, "auth_query", NULL, NULL);
if (rc == -1) {
od_router_close(router, auth_client);
od_router_unroute(router, auth_client);

View File

@ -7,7 +7,6 @@
* Scalable PostgreSQL connection pooler.
*/
int od_auth_query(od_global_t *, od_rule_t *, char *, kiwi_var_t *,
kiwi_password_t *);
int od_auth_query(od_client_t *, char *);
#endif /* ODYSSEY_AUTH_QUERY_H */

View File

@ -101,7 +101,7 @@ int od_backend_ready(od_server_t *server, char *data, uint32_t size)
}
static inline int od_backend_startup(od_server_t *server,
kiwi_params_t *route_params)
kiwi_params_t *route_params, od_client_t *client)
{
od_instance_t *instance = server->global->instance;
od_route_t *route = server->route;
@ -157,7 +157,7 @@ static inline int od_backend_startup(od_server_t *server,
machine_msg_free(msg);
return 0;
case KIWI_BE_AUTHENTICATION:
rc = od_auth_backend(server, msg);
rc = od_auth_backend(server, msg, client);
machine_msg_free(msg);
if (rc == -1)
return -1;
@ -385,7 +385,7 @@ static inline int od_backend_connect_to(od_server_t *server, char *context,
}
int od_backend_connect(od_server_t *server, char *context,
kiwi_params_t *route_params)
kiwi_params_t *route_params, od_client_t *client)
{
od_route_t *route = server->route;
assert(route != NULL);
@ -400,7 +400,7 @@ int od_backend_connect(od_server_t *server, char *context,
return -1;
/* send startup and do initial configuration */
rc = od_backend_startup(server, route_params);
rc = od_backend_startup(server, route_params, client);
return rc;
}

View File

@ -7,7 +7,7 @@
* Scalable PostgreSQL connection pooler.
*/
int od_backend_connect(od_server_t *, char *, kiwi_params_t *);
int od_backend_connect(od_server_t *, char *, kiwi_params_t *, od_client_t*);
int od_backend_connect_cancel(od_server_t *, od_rule_storage_t *, kiwi_key_t *);
void od_backend_close_connection(od_server_t *);
void od_backend_close(od_server_t *);

View File

@ -43,6 +43,7 @@ struct od_client {
kiwi_key_t key;
od_server_t *server;
void *route;
kiwi_password_t password;
od_global_t *global;
od_list_t link_pool;
od_list_t link;
@ -68,6 +69,7 @@ static inline void od_client_init(od_client_t *client)
kiwi_key_init(&client->key);
od_io_init(&client->io);
od_relay_init(&client->relay, &client->io);
kiwi_password_init(&client->password);
od_list_init(&client->link_pool);
od_list_init(&client->link);
}
@ -87,6 +89,7 @@ static inline void od_client_free(od_client_t *client)
od_io_free(&client->io);
if (client->cond)
machine_cond_free(client->cond);
kiwi_password_free(&client->password);
free(client);
}

View File

@ -220,7 +220,7 @@ od_frontend_attach(od_client_t *client, char *context,
int rc;
od_atomic_u32_inc(&router->servers_routing);
rc = od_backend_connect(server, context, route_params);
rc = od_backend_connect(server, context, route_params, client);
od_atomic_u32_dec(&router->servers_routing);
if (rc == -1) {
/* In case of 'too many connections' error, retry attach attempt by