mirror of https://github.com/yandex/odyssey.git
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:
parent
bdd86fc3ec
commit
174f5b6bf9
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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");
|
||||
}
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue