enforce of IP banning was moved to main

This commit is contained in:
Nikos Mavrogiannopoulos
2015-02-25 13:16:56 +01:00
parent 3222cedb99
commit a617485232
14 changed files with 198 additions and 94 deletions
+9 -4
View File
@@ -211,11 +211,16 @@ auth-timeout = 40
# The time (in seconds) that a client is not allowed to reconnect after # The time (in seconds) that a client is not allowed to reconnect after
# a failed authentication attempt. # a failed authentication attempt.
min-reauth-time = 120 min-reauth-time = 300
# The maximum number of password retries before applying the min-reauth-time # Banning clients in ocserv works with a point system. IP addresses
# delay. Set to zero to disable. # that get a score over that configured number are banned for
max-password-retries = 5 # min-reauth-time seconds. A wrong password attempt is 5 points.
# Set to zero to disable.
max-ban-score = 30
# The time (in seconds) that all score kept for a client is reset.
ban-reset-time = 300
# Cookie timeout (in seconds) # Cookie timeout (in seconds)
# Once a client is authenticated he's provided a cookie with # Once a client is authenticated he's provided a cookie with
+2 -1
View File
@@ -74,7 +74,7 @@ ocserv_SOURCES = main.c main-auth.c worker-vpn.c worker-auth.c tlslib.c \
config.c worker-resume.c worker.h main-resume.c main.h \ config.c worker-resume.c worker.h main-resume.c main.h \
worker-extras.c html.c html.h worker-http.c \ worker-extras.c html.c html.h worker-http.c \
main-user.c worker-misc.c route-add.c route-add.h worker-privs.c \ main-user.c worker-misc.c route-add.c route-add.h worker-privs.c \
sec-mod.c sec-mod-db.c sec-mod-auth.c sec-mod-auth.h sec-mod.h sec-mod-ban.c \ sec-mod.c sec-mod-db.c sec-mod-auth.c sec-mod-auth.h sec-mod.h \
script-list.h $(COMMON_SOURCES) $(AUTH_SOURCES) $(ACCT_SOURCES) \ script-list.h $(COMMON_SOURCES) $(AUTH_SOURCES) $(ACCT_SOURCES) \
icmp-ping.c icmp-ping.h worker-kkdcp.c subconfig.c \ icmp-ping.c icmp-ping.h worker-kkdcp.c subconfig.c \
sec-mod-sup-config.c sec-mod-sup-config.h \ sec-mod-sup-config.c sec-mod-sup-config.h \
@@ -83,6 +83,7 @@ ocserv_SOURCES = main.c main-auth.c worker-vpn.c worker-auth.c tlslib.c \
worker-bandwidth.c worker-bandwidth.h ctl.h main-ctl.h \ worker-bandwidth.c worker-bandwidth.h ctl.h main-ctl.h \
vasprintf.c vasprintf.h lzs.c lzs.h cfg.h \ vasprintf.c vasprintf.h lzs.c lzs.h cfg.h \
proc-search.c proc-search.h http-heads.h \ proc-search.c proc-search.h http-heads.h \
main-ban.c main-ban.h \
str.c str.h gettime.h $(CCAN_SOURCES) $(HTTP_PARSER_SOURCES) \ str.c str.h gettime.h $(CCAN_SOURCES) $(HTTP_PARSER_SOURCES) \
$(PROTOBUF_SOURCES) kkdcp.asn kkdcp_asn1_tab.c sec-mod-acct.h $(PROTOBUF_SOURCES) kkdcp.asn kkdcp_asn1_tab.c sec-mod-acct.h
+10 -5
View File
@@ -80,7 +80,7 @@ static struct cfg_options available_options[] = {
{ .name = "compression", .type = OPTION_BOOLEAN, .mandatory = 0 }, { .name = "compression", .type = OPTION_BOOLEAN, .mandatory = 0 },
{ .name = "no-compress-limit", .type = OPTION_NUMERIC, .mandatory = 0 }, { .name = "no-compress-limit", .type = OPTION_NUMERIC, .mandatory = 0 },
{ .name = "tcp-port", .type = OPTION_NUMERIC, .mandatory = 0 }, { .name = "tcp-port", .type = OPTION_NUMERIC, .mandatory = 0 },
{ .name = "max-password-retries", .type = OPTION_NUMERIC, .mandatory = 0 }, { .name = "max-ban-score", .type = OPTION_NUMERIC, .mandatory = 0 },
{ .name = "udp-port", .type = OPTION_NUMERIC, .mandatory = 0 }, { .name = "udp-port", .type = OPTION_NUMERIC, .mandatory = 0 },
{ .name = "keepalive", .type = OPTION_NUMERIC, .mandatory = 0 }, { .name = "keepalive", .type = OPTION_NUMERIC, .mandatory = 0 },
{ .name = "dpd", .type = OPTION_NUMERIC, .mandatory = 0 }, { .name = "dpd", .type = OPTION_NUMERIC, .mandatory = 0 },
@@ -137,6 +137,7 @@ static struct cfg_options available_options[] = {
{ .name = "mobile-idle-timeout", .type = OPTION_NUMERIC, .mandatory = 0 }, { .name = "mobile-idle-timeout", .type = OPTION_NUMERIC, .mandatory = 0 },
{ .name = "max-clients", .type = OPTION_NUMERIC, .mandatory = 0 }, { .name = "max-clients", .type = OPTION_NUMERIC, .mandatory = 0 },
{ .name = "min-reauth-time", .type = OPTION_NUMERIC, .mandatory = 0 }, { .name = "min-reauth-time", .type = OPTION_NUMERIC, .mandatory = 0 },
{ .name = "ban-reset-time", .type = OPTION_NUMERIC, .mandatory = 0 },
{ .name = "max-same-clients", .type = OPTION_NUMERIC, .mandatory = 0 }, { .name = "max-same-clients", .type = OPTION_NUMERIC, .mandatory = 0 },
{ .name = "rx-data-per-sec", .type = OPTION_NUMERIC, .mandatory = 0 }, { .name = "rx-data-per-sec", .type = OPTION_NUMERIC, .mandatory = 0 },
@@ -818,11 +819,15 @@ unsigned urlfw_size = 0;
READ_NUMERIC("max-clients", config->max_clients); READ_NUMERIC("max-clients", config->max_clients);
READ_NUMERIC("min-reauth-time", config->min_reauth_time); READ_NUMERIC("min-reauth-time", config->min_reauth_time);
config->ban_reset_time = -1;
READ_NUMERIC("ban-reset-time", config->ban_reset_time);
if (config->ban_reset_time == -1)
config->ban_reset_time = DEFAULT_BAN_RESET_TIME;
config->max_password_retries = -1; config->max_ban_score = -1;
READ_NUMERIC("max-password-retries", config->max_password_retries); READ_NUMERIC("max-ban-score", config->max_ban_score);
if (config->max_password_retries == -1) if (config->max_ban_score == -1)
config->max_password_retries = MAX_PASSWORD_TRIES; config->max_ban_score = DEFAULT_MAX_BAN_SCORE;
READ_NUMERIC("max-same-clients", config->max_same_clients); READ_NUMERIC("max-same-clients", config->max_same_clients);
+7
View File
@@ -255,3 +255,10 @@ message sec_auth_session_reply_msg
optional string explicit_ipv6 = 27; optional string explicit_ipv6 = 27;
repeated string no_routes = 28; repeated string no_routes = 28;
} }
/* SEC_BAN_IP: sent from sec-mod to main */
message sec_auth_ban_ip
{
required string ip = 1;
required uint32 score = 2;
}
+41 -33
View File
@@ -38,14 +38,16 @@
#include <syslog.h> #include <syslog.h>
#include <vpn.h> #include <vpn.h>
#include <tlslib.h> #include <tlslib.h>
#include <sec-mod.h> #include <main.h>
#include <main-ban.h>
#include <ccan/hash/hash.h> #include <ccan/hash/hash.h>
#include <ccan/htable/htable.h> #include <ccan/htable/htable.h>
typedef struct ban_entry_st { typedef struct ban_entry_st {
char ip[MAX_IP_STR]; char ip[MAX_IP_STR];
unsigned failed_attempts; unsigned score;
time_t last_reset; /* the time its score counting started */
time_t expires; /* the time after the client is allowed to login */ time_t expires; /* the time after the client is allowed to login */
} ban_entry_st; } ban_entry_st;
@@ -70,21 +72,23 @@ static bool ban_entry_cmp(const void *_c1, void *_c2)
} }
void *sec_mod_ban_db_init(sec_mod_st *sec) void *main_ban_db_init(main_server_st *s)
{ {
struct htable *db = talloc(sec, struct htable); struct htable *db = talloc(s, struct htable);
if (db == NULL) if (db == NULL) {
return NULL; fprintf(stderr, "error initializing ban DB\n");
exit(1);
}
htable_init(db, rehash, NULL); htable_init(db, rehash, NULL);
sec->ban_db = db; s->ban_db = db;
return db; return db;
} }
void sec_mod_ban_db_deinit(sec_mod_st *sec) void main_ban_db_deinit(main_server_st *s)
{ {
struct htable *db = sec->ban_db; struct htable *db = s->ban_db;
if (db != NULL) { if (db != NULL) {
htable_clear(db); htable_clear(db);
@@ -92,9 +96,9 @@ struct htable *db = sec->ban_db;
} }
} }
unsigned sec_mod_ban_db_elems(sec_mod_st *sec) unsigned main_ban_db_elems(main_server_st *s)
{ {
struct htable *db = sec->ban_db; struct htable *db = s->ban_db;
if (db) if (db)
return db->elems; return db->elems;
@@ -102,12 +106,13 @@ struct htable *db = sec->ban_db;
return 0; return 0;
} }
void add_ip_to_ban_list(sec_mod_st *sec, const char *ip, unsigned attempts, time_t reset_time) void add_ip_to_ban_list(main_server_st *s, const char *ip, unsigned score)
{ {
struct htable *db = sec->ban_db; struct htable *db = s->ban_db;
struct ban_entry_st *e; struct ban_entry_st *e;
ban_entry_st t; ban_entry_st t;
time_t now = time(0); time_t now = time(0);
time_t reset_time = now + s->config->min_reauth_time;
if (db == NULL || ip == NULL || ip[0] == 0) if (db == NULL || ip == NULL || ip[0] == 0)
return; return;
@@ -124,24 +129,26 @@ void add_ip_to_ban_list(sec_mod_st *sec, const char *ip, unsigned attempts, time
} }
strlcpy(e->ip, ip, sizeof(e->ip)); strlcpy(e->ip, ip, sizeof(e->ip));
e->last_reset = now;
if (htable_add(db, rehash(e, NULL), e) == 0) { if (htable_add(db, rehash(e, NULL), e) == 0) {
seclog(sec, LOG_INFO, mslog(s, NULL, LOG_INFO,
"could not add ban entry to hash table"); "could not add ban entry to hash table");
goto fail; goto fail;
} }
} else { } else {
if (now > e->expires) { if (now > e->last_reset + s->config->ban_reset_time) {
e->failed_attempts = 0; e->score = 0;
e->last_reset = now;
} }
} }
e->failed_attempts += attempts; e->score += score;
e->expires = reset_time; e->expires = reset_time;
if (sec->config->max_password_retries > 0 && e->failed_attempts >= sec->config->max_password_retries) { if (s->config->max_ban_score > 0 && e->score >= s->config->max_ban_score) {
seclog(sec, LOG_INFO,"added IP '%s' (with failed attempts %d) to ban list, will be reset at: %s", ip, e->failed_attempts, ctime(&reset_time)); mslog(s, NULL, LOG_INFO,"added IP '%s' (with score %d) to ban list, will be reset at: %s", ip, e->score, ctime(&reset_time));
} else { } else {
seclog(sec, LOG_DEBUG,"added failed attempt for IP '%s' to ban list, will be reset at: %s", ip, ctime(&reset_time)); mslog(s, NULL, LOG_DEBUG,"added failed attempt for IP '%s' to ban list", ip);
} }
return; return;
@@ -150,9 +157,9 @@ void add_ip_to_ban_list(sec_mod_st *sec, const char *ip, unsigned attempts, time
return; return;
} }
void remove_ip_from_ban_list(sec_mod_st *sec, const char *ip) void remove_ip_from_ban_list(main_server_st *s, const char *ip)
{ {
struct htable *db = sec->ban_db; struct htable *db = s->ban_db;
struct ban_entry_st *e; struct ban_entry_st *e;
ban_entry_st t; ban_entry_st t;
@@ -165,41 +172,42 @@ void remove_ip_from_ban_list(sec_mod_st *sec, const char *ip)
e = htable_get(db, rehash(&t, NULL), ban_entry_cmp, &t); e = htable_get(db, rehash(&t, NULL), ban_entry_cmp, &t);
if (e != NULL) { /* new entry */ if (e != NULL) { /* new entry */
e->failed_attempts = 0; e->score = 0;
e->expires = 0; e->expires = 0;
} }
return; return;
} }
unsigned check_if_banned(sec_mod_st *sec, const char *ip) unsigned check_if_banned(main_server_st *s, struct sockaddr_storage *addr, socklen_t addr_size)
{ {
struct htable *db = sec->ban_db; struct htable *db = s->ban_db;
time_t now; time_t now;
ban_entry_st t, *e; ban_entry_st t, *e;
if (db == NULL || ip == NULL || ip[0] == 0) if (db == NULL)
return 0; return 0;
if (human_addr2((struct sockaddr*)addr, addr_size, t.ip, sizeof(t.ip), 0) != NULL) {
/* pass the current time somehow */ /* pass the current time somehow */
now = time(0); now = time(0);
strlcpy(t.ip, ip, sizeof(t.ip));
e = htable_get(db, rehash(&t, NULL), ban_entry_cmp, &t); e = htable_get(db, rehash(&t, NULL), ban_entry_cmp, &t);
if (e != NULL) { if (e != NULL) {
if (now > e->expires) if (now > e->expires)
return 0; return 0;
if (sec->config->max_password_retries > 0 && if (s->config->max_ban_score > 0 &&
e->failed_attempts >= sec->config->max_password_retries) e->score >= s->config->max_ban_score) {
return 1; return 1;
} }
}
}
return 0; return 0;
} }
void cleanup_banned_entries(sec_mod_st *sec) void cleanup_banned_entries(main_server_st *s)
{ {
struct htable *db = sec->ban_db; struct htable *db = s->ban_db;
ban_entry_st *t; ban_entry_st *t;
struct htable_iter iter; struct htable_iter iter;
time_t now = time(0); time_t now = time(0);
@@ -209,7 +217,7 @@ void cleanup_banned_entries(sec_mod_st *sec)
t = htable_first(db, &iter); t = htable_first(db, &iter);
while (t != NULL) { while (t != NULL) {
if (now >= t->expires) { if (now >= t->expires && now > t->last_reset + s->config->ban_reset_time) {
htable_delval(db, &iter); htable_delval(db, &iter);
talloc_free(t); talloc_free(t);
} }
+34
View File
@@ -0,0 +1,34 @@
/*
* Copyright (C) 2015 Nikos Mavrogiannopoulos
*
* Author: Nikos Mavrogiannopoulos
*
* This file is part of ocserv.
*
* The GnuTLS is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef MAIN_BAN_H
# define MAIN_BAN_H
# include "main.h"
void cleanup_banned_entries(main_server_st *s);
unsigned check_if_banned(main_server_st *s, struct sockaddr_storage *addr, socklen_t addr_size);
void add_ip_to_ban_list(main_server_st *s, const char *ip, unsigned score);
void remove_ip_from_ban_list(main_server_st *s, const char *ip);
unsigned main_ban_db_elems(main_server_st *s);
void main_ban_db_deinit(main_server_st *s);
void *main_ban_db_init(main_server_st *s);
#endif
+17 -3
View File
@@ -35,8 +35,6 @@
#include <gnutls/gnutls.h> #include <gnutls/gnutls.h>
#include <gnutls/crypto.h> #include <gnutls/crypto.h>
#include <tlslib.h> #include <tlslib.h>
#include <sys/un.h>
#include <cloexec.h>
#include "common.h" #include "common.h"
#include "str.h" #include "str.h"
#include "setproctitle.h" #include "setproctitle.h"
@@ -47,6 +45,7 @@
#include <vpn.h> #include <vpn.h>
#include <main.h> #include <main.h>
#include <main-ban.h>
#include <ccan/list/list.h> #include <ccan/list/list.h>
int handle_sec_mod_commands(main_server_st * s) int handle_sec_mod_commands(main_server_st * s)
@@ -58,7 +57,7 @@ int handle_sec_mod_commands(main_server_st * s)
uint8_t *raw; uint8_t *raw;
int ret, raw_len, e; int ret, raw_len, e;
void *pool = talloc_new(s); void *pool = talloc_new(s);
//PROTOBUF_ALLOCATOR(pa, pool); PROTOBUF_ALLOCATOR(pa, pool);
if (pool == NULL) if (pool == NULL)
return -1; return -1;
@@ -112,6 +111,21 @@ int handle_sec_mod_commands(main_server_st * s)
} }
switch (cmd) { switch (cmd) {
case SM_CMD_AUTH_BAN_IP:{
SecAuthBanIp *tmsg;
tmsg = sec_auth_ban_ip__unpack(&pa, raw_len, raw);
if (tmsg == NULL) {
mslog(s, NULL, LOG_ERR, "error unpacking sec-mod data");
ret = ERR_BAD_COMMAND;
goto cleanup;
}
add_ip_to_ban_list(s, tmsg->ip, tmsg->score);
sec_auth_ban_ip__free_unpacked(tmsg, &pa);
}
break;
default: default:
mslog(s, NULL, LOG_ERR, "unknown CMD from sec-mod 0x%x.", (unsigned)cmd); mslog(s, NULL, LOG_ERR, "unknown CMD from sec-mod 0x%x.", (unsigned)cmd);
ret = ERR_BAD_COMMAND; ret = ERR_BAD_COMMAND;
+12 -2
View File
@@ -52,6 +52,7 @@
#endif #endif
#include <main.h> #include <main.h>
#include <main-ctl.h> #include <main-ctl.h>
#include <main-ban.h>
#include <route-add.h> #include <route-add.h>
#include <worker.h> #include <worker.h>
#include <cookies.h> #include <cookies.h>
@@ -633,6 +634,7 @@ void clear_lists(main_server_st *s)
ip_lease_deinit(&s->ip_leases); ip_lease_deinit(&s->ip_leases);
proc_table_deinit(s); proc_table_deinit(s);
ctl_handler_deinit(s); ctl_handler_deinit(s);
main_ban_db_deinit(s);
} }
static void kill_children(main_server_st* s) static void kill_children(main_server_st* s)
@@ -863,11 +865,12 @@ unsigned total = 10;
exit(0); exit(0);
} }
/* Check if we need to expire any cookies */ /* Check if we need to expire any data */
if (need_maintenance != 0) { if (need_maintenance != 0) {
need_maintenance = 0; need_maintenance = 0;
mslog(s, NULL, LOG_DEBUG, "performing maintenance"); mslog(s, NULL, LOG_DEBUG, "performing maintenance (banned IPs: %d)", main_ban_db_elems(s));
expire_tls_sessions(s); expire_tls_sessions(s);
cleanup_banned_entries(s);
alarm(MAINTAINANCE_TIME(s)); alarm(MAINTAINANCE_TIME(s));
} }
} }
@@ -943,6 +946,7 @@ int main(int argc, char** argv)
tls_cache_init(s, &s->tls_db); tls_cache_init(s, &s->tls_db);
ip_lease_init(&s->ip_leases); ip_lease_init(&s->ip_leases);
proc_table_init(s); proc_table_init(s);
main_ban_db_init(s);
sigemptyset(&blockset); sigemptyset(&blockset);
sigemptyset(&emptyset); sigemptyset(&emptyset);
@@ -1156,6 +1160,12 @@ int main(int argc, char** argv)
break; break;
} }
if (check_if_banned(s, &ws->remote_addr, ws->remote_addr_len) != 0) {
close(fd);
mslog(s, NULL, LOG_INFO, "Rejected connection from banned IP");
break;
}
/* Create a command socket */ /* Create a command socket */
ret = socketpair(AF_UNIX, SOCK_STREAM, 0, cmd_fd); ret = socketpair(AF_UNIX, SOCK_STREAM, 0, cmd_fd);
if (ret < 0) { if (ret < 0) {
+2
View File
@@ -181,6 +181,8 @@ typedef struct main_server_st {
struct cookie_entry_db_st cookies; struct cookie_entry_db_st cookies;
tls_sess_db_st tls_db; tls_sess_db_st tls_db;
struct htable *ban_db;
tls_st *creds; tls_st *creds;
uint8_t cookie_key[COOKIE_KEY_SIZE]; uint8_t cookie_key[COOKIE_KEY_SIZE];
+8 -3
View File
@@ -288,9 +288,14 @@ auth-timeout = 40
# a failed authentication attempt. # a failed authentication attempt.
min-reauth-time = 120 min-reauth-time = 120
# The maximum number of password retries before applying the min-reauth-time # Banning clients in ocserv works with a point system. IP addresses
# delay. Set to zero to disable. # that get a score over that configured number are banned for
max-password-retries = 5 # min-reauth-time seconds. A wrong password attempt is 5 points.
# Set to zero to disable.
max-ban-score = 30
# The time (in seconds) that all score kept for a client is reset.
ban-reset-time = 300
# Cookie timeout (in seconds) # Cookie timeout (in seconds)
# Once a client is authenticated he's provided a cookie with # Once a client is authenticated he's provided a cookie with
+29 -15
View File
@@ -72,6 +72,33 @@ void sec_auth_init(sec_mod_st * sec, struct cfg_st *config)
config->acct.amod->global_init(sec, config->server_name, config->acct.additional); config->acct.amod->global_init(sec, config->server_name, config->acct.additional);
} }
static
void sec_mod_add_score_to_ip(sec_mod_st *sec, void *pool, const char *ip, unsigned points)
{
void *lpool;
int ret, e;
SecAuthBanIp msg = SEC_AUTH_BAN_IP__INIT;
msg.ip = (char*)ip;
msg.score = points;
lpool = talloc_new(pool);
if (lpool == NULL) {
return;
}
ret = send_msg(lpool, sec->cmd_fd, SM_CMD_AUTH_BAN_IP, &msg,
(pack_size_func) sec_auth_ban_ip__get_packed_size,
(pack_func) sec_auth_ban_ip__pack);
if (ret < 0) {
e = errno;
seclog(sec, LOG_WARNING, "error in sending BAN IP message: %s", strerror(e));
}
talloc_free(lpool);
return;
}
static int generate_cookie(sec_mod_st * sec, client_entry_st * entry) static int generate_cookie(sec_mod_st * sec, client_entry_st * entry)
{ {
int ret; int ret;
@@ -272,7 +299,7 @@ int handle_sec_auth_res(int cfd, sec_mod_st * sec, client_entry_st * e, int resu
if (result == ERR_AUTH_CONTINUE) { if (result == ERR_AUTH_CONTINUE) {
/* if the module allows multiple retries for the password */ /* if the module allows multiple retries for the password */
if (e->status != PS_AUTH_INIT && e->module && e->module->allows_retries) { if (e->status != PS_AUTH_INIT && e->module && e->module->allows_retries) {
add_ip_to_ban_list(sec, e->auth_info.remote_ip, 1, time(0) + sec->config->min_reauth_time); sec_mod_add_score_to_ip(sec, e, e->auth_info.remote_ip, PASSWORD_POINTS);
} }
ret = send_sec_auth_reply_msg(cfd, sec, e); ret = send_sec_auth_reply_msg(cfd, sec, e);
@@ -296,13 +323,12 @@ int handle_sec_auth_res(int cfd, sec_mod_st * sec, client_entry_st * e, int resu
seclog(sec, LOG_ERR, "could not send reply auth cmd."); seclog(sec, LOG_ERR, "could not send reply auth cmd.");
return ret; return ret;
} }
remove_ip_from_ban_list(sec, e->auth_info.remote_ip);
ret = 0; ret = 0;
} else { } else {
e->status = PS_AUTH_FAILED; e->status = PS_AUTH_FAILED;
add_ip_to_ban_list(sec, e->auth_info.remote_ip, 1, time(0) + sec->config->min_reauth_time); sec_mod_add_score_to_ip(sec, e, e->auth_info.remote_ip, PASSWORD_POINTS);
ret = send_sec_auth_reply(cfd, sec, e, AUTH__REP__FAILED); ret = send_sec_auth_reply(cfd, sec, e, AUTH__REP__FAILED);
if (ret < 0) { if (ret < 0) {
@@ -484,12 +510,6 @@ int handle_sec_auth_cont(int cfd, sec_mod_st * sec, const SecAuthContMsg * req)
client_entry_st *e; client_entry_st *e;
int ret; int ret;
if (check_if_banned(sec, req->ip) != 0) {
seclog(sec, LOG_INFO,
"IP '%s' is banned", req->ip);
return -1;
}
if (req->sid.len != SID_SIZE) { if (req->sid.len != SID_SIZE) {
seclog(sec, LOG_ERR, "auth cont but with illegal sid size (%d)!", seclog(sec, LOG_ERR, "auth cont but with illegal sid size (%d)!",
(int)req->sid.len); (int)req->sid.len);
@@ -569,12 +589,6 @@ int handle_sec_auth_init(int cfd, sec_mod_st * sec, const SecAuthInitMsg * req)
client_entry_st *e; client_entry_st *e;
unsigned need_continue = 0; unsigned need_continue = 0;
if (check_if_banned(sec, req->ip) != 0) {
seclog(sec, LOG_INFO,
"IP '%s' is banned", req->ip);
return -1;
}
e = new_client_entry(sec, req->ip); e = new_client_entry(sec, req->ip);
if (e == NULL) { if (e == NULL) {
seclog(sec, LOG_ERR, "cannot initialize memory"); seclog(sec, LOG_ERR, "cannot initialize memory");
+3 -10
View File
@@ -368,7 +368,6 @@ static void check_other_work(sec_mod_st *sec)
} }
sec_mod_client_db_deinit(sec); sec_mod_client_db_deinit(sec);
sec_mod_ban_db_deinit(sec);
talloc_free(sec); talloc_free(sec);
exit(0); exit(0);
} }
@@ -382,10 +381,8 @@ static void check_other_work(sec_mod_st *sec)
if (need_maintainance) { if (need_maintainance) {
seclog(sec, LOG_DEBUG, "performing maintenance"); seclog(sec, LOG_DEBUG, "performing maintenance");
cleanup_client_entries(sec); cleanup_client_entries(sec);
cleanup_banned_entries(sec); seclog(sec, LOG_DEBUG, "active sessions %d",
seclog(sec, LOG_DEBUG, "active sessions %d, banned entries %d", sec_mod_client_db_elems(sec));
sec_mod_client_db_elems(sec),
sec_mod_ban_db_elems(sec));
alarm(MAINTAINANCE_TIME); alarm(MAINTAINANCE_TIME);
need_maintainance = 0; need_maintainance = 0;
} }
@@ -492,7 +489,6 @@ void sec_mod_server(void *main_pool, struct cfg_st *config, const char *socket_f
#ifdef DEBUG_LEAKS #ifdef DEBUG_LEAKS
talloc_enable_leak_report_full(); talloc_enable_leak_report_full();
#endif #endif
sigemptyset(&blockset); sigemptyset(&blockset);
sigemptyset(&emptyset); sigemptyset(&emptyset);
sigaddset(&blockset, SIGALRM); sigaddset(&blockset, SIGALRM);
@@ -538,6 +534,7 @@ void sec_mod_server(void *main_pool, struct cfg_st *config, const char *socket_f
alarm(MAINTAINANCE_TIME); alarm(MAINTAINANCE_TIME);
sec_auth_init(sec, config); sec_auth_init(sec, config);
sec->cmd_fd = cmd_fd;
#ifdef HAVE_PKCS11 #ifdef HAVE_PKCS11
ret = gnutls_pkcs11_reinit(); ret = gnutls_pkcs11_reinit();
@@ -552,10 +549,6 @@ void sec_mod_server(void *main_pool, struct cfg_st *config, const char *socket_f
exit(1); exit(1);
} }
if (config->min_reauth_time > 0)
sec_mod_ban_db_init(sec);
sd = socket(AF_UNIX, SOCK_STREAM, 0); sd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sd == -1) { if (sd == -1) {
e = errno; e = errno;
+1 -9
View File
@@ -34,7 +34,7 @@ typedef struct sec_mod_st {
gnutls_privkey_t *key; gnutls_privkey_t *key;
unsigned key_size; unsigned key_size;
struct htable *client_db; struct htable *client_db;
struct htable *ban_db; int cmd_fd;
struct config_mod_st *config_module; struct config_mod_st *config_module;
} sec_mod_st; } sec_mod_st;
@@ -127,12 +127,4 @@ void sec_auth_user_deinit(sec_mod_st * sec, client_entry_st * e);
void sec_mod_server(void *main_pool, struct cfg_st *config, const char *socket_file, void sec_mod_server(void *main_pool, struct cfg_st *config, const char *socket_file,
uint8_t cookie_key[COOKIE_KEY_SIZE], int cmd_fd); uint8_t cookie_key[COOKIE_KEY_SIZE], int cmd_fd);
void cleanup_banned_entries(sec_mod_st *sec);
unsigned check_if_banned(sec_mod_st *sec, const char *ip);
void add_ip_to_ban_list(sec_mod_st *sec, const char *ip, unsigned attempts, time_t reset_time);
void remove_ip_from_ban_list(sec_mod_st *sec, const char *ip);
void *sec_mod_ban_db_init(sec_mod_st *sec);
void sec_mod_ban_db_deinit(sec_mod_st *sec);
unsigned sec_mod_ban_db_elems(sec_mod_st *sec);
#endif #endif
+16 -2
View File
@@ -32,6 +32,7 @@
#include <net/if.h> #include <net/if.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <minmax.h> #include <minmax.h>
#include <auth/common.h>
#ifdef __GNUC__ #ifdef __GNUC__
# define _OCSERV_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) # define _OCSERV_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
@@ -56,6 +57,14 @@ typedef enum {
OC_COMP_LZS, OC_COMP_LZS,
} comp_type_t; } comp_type_t;
/* Banning works with a point system. A wrong password
* attempt gives you PASSWORD_POINTS, and you are banned
* when the maximum ban score is reached.
*/
#define PASSWORD_POINTS 5
#define DEFAULT_MAX_BAN_SCORE (MAX_PASSWORD_TRIES*PASSWORD_POINTS)
#define DEFAULT_BAN_RESET_TIME 300
#define MIN_NO_COMPRESS_LIMIT 64 #define MIN_NO_COMPRESS_LIMIT 64
#define DEFAULT_NO_COMPRESS_LIMIT 256 #define DEFAULT_NO_COMPRESS_LIMIT 256
@@ -134,15 +143,19 @@ typedef enum {
CMD_SESSION_INFO = 13, CMD_SESSION_INFO = 13,
CMD_CLI_STATS = 15, CMD_CLI_STATS = 15,
/* from worker to sec-mod */
SM_CMD_AUTH_INIT = 120, SM_CMD_AUTH_INIT = 120,
SM_CMD_AUTH_CONT, SM_CMD_AUTH_CONT,
SM_CMD_AUTH_REP, SM_CMD_AUTH_REP,
SM_CMD_DECRYPT, SM_CMD_DECRYPT,
SM_CMD_SIGN, SM_CMD_SIGN,
SM_CMD_CLI_STATS,
/* from main to sec-mod and vice versa */
SM_CMD_AUTH_SESSION_OPEN, SM_CMD_AUTH_SESSION_OPEN,
SM_CMD_AUTH_SESSION_CLOSE, SM_CMD_AUTH_SESSION_CLOSE,
SM_CMD_AUTH_SESSION_REPLY, SM_CMD_AUTH_SESSION_REPLY,
SM_CMD_CLI_STATS, SM_CMD_AUTH_BAN_IP,
} cmd_request_t; } cmd_request_t;
#define MAX_IP_STR 46 #define MAX_IP_STR 46
@@ -307,7 +320,8 @@ struct cfg_st {
unsigned rekey_method; /* REKEY_METHOD_ */ unsigned rekey_method; /* REKEY_METHOD_ */
time_t min_reauth_time; /* after a failed auth, how soon one can reauthenticate -> in seconds */ time_t min_reauth_time; /* after a failed auth, how soon one can reauthenticate -> in seconds */
int max_password_retries; /* the number of retries allowed prior to applying min_reauth_time */ int max_ban_score; /* the score allowed before a user is banned (see vpn.h) */
int ban_reset_time;
unsigned isolate; /* whether seccomp should be enabled or not */ unsigned isolate; /* whether seccomp should be enabled or not */