Fixes netmask hba parsing (#452)

Fix netmask in hba parsing and tests.

Co-authored-by: Dmitry Vasiliev <dmitrivasilyev@ozon.ru>
This commit is contained in:
vadv 2022-08-08 10:56:28 +03:00 committed by GitHub
parent bdd86fc3ec
commit 174f5b6bf9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 80 additions and 17 deletions

View File

@ -2128,10 +2128,22 @@ void od_frontend(void *arg)
/* HBA check */
rc = od_hba_process(client);
char client_ip[64];
od_getpeername(client->io.io, client_ip, sizeof(client_ip), 1, 0);
/* client authentication */
if (rc == OK_RESPONSE) {
rc = od_auth_frontend(client);
od_log(&instance->logger, "auth", client, NULL,
"ip '%s' user '%s.%s': host based authentication allowed",
client_ip, client->startup.database.value,
client->startup.user.value);
} else {
od_error(
&instance->logger, "auth", client, NULL,
"ip '%s' user '%s.%s': host based authentication rejected",
client_ip, client->startup.database.value,
client->startup.user.value);
od_frontend_error(client, KIWI_INVALID_PASSWORD,
"host based authentication rejected");
}

View File

@ -190,34 +190,46 @@ static int od_hba_reader_address(struct sockaddr_storage *dest,
return -1;
}
static int od_hba_reader_prefix(od_hba_rule_t *hba, char *prefix)
static inline uint32 od_hba_bswap32(uint32 x)
{
return ((x << 24) & 0xff000000) | ((x << 8) & 0x00ff0000) |
((x >> 8) & 0x0000ff00) | ((x >> 24) & 0x000000ff);
}
int od_hba_reader_prefix(od_hba_rule_t *hba, char *prefix)
{
char *end = NULL;
unsigned long int len = strtoul(prefix, &end, 10);
long len = strtoul(prefix, &end, 10);
if (*prefix == '\0' || *end != '\0') {
return -1;
}
if (hba->addr.ss_family == AF_INET) {
if (len > 32)
return -1;
uint32_t mask = 0;
unsigned int i;
struct sockaddr_in *addr = (struct sockaddr_in *)&hba->mask;
for (i = 0; i < len / 8; ++i) {
mask = 0xff | (mask << 8);
}
if (len % 8 != 0)
mask = mask | ((len % 8) << (i * 8));
addr->sin_addr.s_addr = mask;
long mask;
if (len > 0)
mask = (0xffffffffUL << (32 - (int)len)) & 0xffffffffUL;
else
mask = 0;
addr->sin_addr.s_addr = od_hba_bswap32(mask);
return 0;
} else if (hba->addr.ss_family == AF_INET6) {
if (len > 128)
return -1;
unsigned int i;
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&hba->mask;
for (i = 0; i < len / 8; ++i) {
addr->sin6_addr.s6_addr[i] = 0xff;
int i;
for (i = 0; i < 16; i++) {
if (len <= 0)
addr->sin6_addr.s6_addr[i] = 0;
else if (len >= 8)
addr->sin6_addr.s6_addr[i] = 0xff;
else {
addr->sin6_addr.s6_addr[i] =
(0xff << (8 - (int)len)) & 0xff;
}
len -= 8;
}
if (len % 8 != 0)
addr->sin6_addr.s6_addr[i] = len & 7;
return 0;
}
@ -334,7 +346,8 @@ int od_hba_reader_parse(od_config_reader_t *reader)
if (mask)
*mask++ = 0;
if (od_hba_reader_address(&hba->addr, address) == -1) {
if (od_hba_reader_address(&hba->addr, address) ==
NOT_OK_RESPONSE) {
od_hba_reader_error(reader,
"invalid IP address");
goto error;

View File

@ -65,10 +65,14 @@ set(od_test_src
../sources/util.h
../sources/build.h
../sources/debugprintf.h
../sources/hba.c
../sources/hba_rule.c
../sources/hba_reader.c
odyssey/test_attribute.c
odyssey/test_tdigest.c
odyssey/test_util.c
odyssey/test_locks.c
odyssey/test_hba_parse.c
)
file(COPY machinarium/ca.crt DESTINATION machinarium)

View File

@ -0,0 +1,32 @@
#include "odyssey.h"
#include <odyssey_test.h>
void test_od_hba_reader_prefix(sa_family_t net, char *prefix, char *value)
{
od_hba_rule_t *hba = NULL;
char buffer[INET6_ADDRSTRLEN];
hba = od_hba_rule_create();
hba->addr.ss_family = net;
test(od_hba_reader_prefix(hba, prefix) == 0);
if (net == AF_INET) {
struct sockaddr_in *addr = (struct sockaddr_in *)&hba->mask;
inet_ntop(net, &addr->sin_addr, buffer, sizeof(buffer));
} else {
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&hba->mask;
inet_ntop(net, &addr->sin6_addr, buffer, sizeof(buffer));
}
test(memcmp(value, buffer, strlen(buffer)) == 0);
od_hba_rule_free(hba);
}
void odyssey_test_hba(void)
{
test_od_hba_reader_prefix(AF_INET, "31", "255.255.255.254");
test_od_hba_reader_prefix(AF_INET, "24", "255.255.255.0");
test_od_hba_reader_prefix(AF_INET, "12", "255.240.0.0");
test_od_hba_reader_prefix(AF_INET, "7", "254.0.0.0");
test_od_hba_reader_prefix(AF_INET6, "10", "ffc0::");
test_od_hba_reader_prefix(AF_INET6, "120",
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00");
}

View File

@ -79,6 +79,7 @@ extern void odyssey_test_tdigest(void);
extern void odyssey_test_attribute(void);
extern void odyssey_test_util(void);
extern void odyssey_test_lock(void);
extern void odyssey_test_hba(void);
int main(int argc, char *argv[])
{
@ -147,6 +148,7 @@ int main(int argc, char *argv[])
odyssey_test(odyssey_test_attribute);
odyssey_test(odyssey_test_util);
odyssey_test(odyssey_test_lock);
odyssey_test(odyssey_test_hba);
return 0;
}