Skip to content

Commit

Permalink
lindnermarek: tc rules to limit bandwidth per user; support forEnable…
Browse files Browse the repository at this point in the history
…Voucher, ForceVoucher and EnablePreAuth; also more little fixes and changes
  • Loading branch information
mwarning committed Aug 10, 2013
1 parent 06459df commit 73e5b8d
Show file tree
Hide file tree
Showing 12 changed files with 298 additions and 43 deletions.
4 changes: 2 additions & 2 deletions src/auth.c
Expand Up @@ -111,7 +111,7 @@ auth_client_action(char *ip, char *mac, t_authaction action)
case AUTH_MAKE_AUTHENTICATED:
if(client->fw_connection_state != FW_MARK_AUTHENTICATED) {
client->fw_connection_state = FW_MARK_AUTHENTICATED;
iptables_fw_access(AUTH_MAKE_AUTHENTICATED,client->ip,client->mac);
iptables_fw_access(AUTH_MAKE_AUTHENTICATED, client);
authenticated_since_start++;
} else {
debug(LOG_INFO, "Nothing to do, %s %s already authenticated", client->ip, client->mac);
Expand All @@ -120,7 +120,7 @@ auth_client_action(char *ip, char *mac, t_authaction action)

case AUTH_MAKE_DEAUTHENTICATED:
if(client->fw_connection_state == FW_MARK_AUTHENTICATED) {
iptables_fw_access(AUTH_MAKE_DEAUTHENTICATED, client->ip, client->mac);
iptables_fw_access(AUTH_MAKE_DEAUTHENTICATED, client);
}
client_list_delete(client);
break;
Expand Down
24 changes: 23 additions & 1 deletion src/client_list.c
Expand Up @@ -49,6 +49,7 @@

/** Client counter */
static int client_count = 0;
static t_client **client_arr;

/** Time last client added */
static unsigned long int last_client_time = 0;
Expand Down Expand Up @@ -83,8 +84,17 @@ client_get_first_client(void)
void
client_list_init(void)
{
s_config *config;
int i;

firstclient = NULL;
client_count = 0;

config = config_get_config();
client_arr = safe_malloc(config->maxclients * sizeof(t_client *));

for (i = 0; i < config->maxclients; i++)
client_arr[i] = NULL;
}

/** @internal
Expand All @@ -103,7 +113,7 @@ _client_list_append(const char *ip, const char *mac, const char *token)
{
t_client *client, *prevclient;
s_config *config;
int maxclients;
int maxclients, i;

config = config_get_config();
maxclients = config->maxclients;
Expand Down Expand Up @@ -133,6 +143,15 @@ _client_list_append(const char *ip, const char *mac, const char *token)
client->counters.last_updated = last_client_time;
client->added_time = last_client_time;

for (i = 0; i < maxclients; i++) {
if (client_arr[i])
continue;
break;
}

client_arr[i] = client;
client->idx = i;

debug(LOG_NOTICE, "Adding %s %s token %s to client list",
client->ip, client->mac, client->token ? client->token : "none");

Expand Down Expand Up @@ -301,6 +320,9 @@ _client_list_free_node(t_client * client)
if (client->token != NULL)
free(client->token);

if (client_arr[client->idx] == client)
client_arr[client->idx] = NULL;

free(client);
}

Expand Down
3 changes: 3 additions & 0 deletions src/client_list.h
Expand Up @@ -50,6 +50,9 @@ typedef struct _t_client {
t_counters counters; /**< @brief Counters for input/output of
the client. */
int attempts; /**< @brief Number of authentication attempts */
int download_limit; /**< @brief Download limit, kb/s */
int upload_limit; /**< @brief Upload limit, kb/s */
int idx;
} t_client;

/** @brief Get the first element of the list of connected clients
Expand Down
21 changes: 21 additions & 0 deletions src/conf.c
Expand Up @@ -75,6 +75,9 @@ typedef enum {
oGatewayAddress,
oGatewayPort,
oRemoteAuthenticatorAction,
oEnablePreAuth,
oEnableVoucher,
oForceVoucher,
oPasswordAuthentication,
oUsernameAuthentication,
oPasswordAttempts,
Expand Down Expand Up @@ -131,6 +134,9 @@ static const struct {
{ "gatewayaddress", oGatewayAddress },
{ "gatewayport", oGatewayPort },
{ "remoteauthenticatoraction", oRemoteAuthenticatorAction },
{ "enablepreauth", oEnablePreAuth },
{ "enablevoucher", oEnableVoucher },
{ "forcevoucher", oForceVoucher },
{ "passwordauthentication", oPasswordAuthentication },
{ "usernameauthentication", oUsernameAuthentication },
{ "passwordattempts", oPasswordAttempts },
Expand Down Expand Up @@ -743,6 +749,21 @@ config_read(const char *filename)
case oRemoteAuthenticatorAction:
config.remote_auth_action = safe_strdup(p1);
break;
case oEnablePreAuth:
value = parse_boolean_value(p1);
if (value != - 1)
config.enable_preauth = value;
break;
case oEnableVoucher:
value = parse_boolean_value(p1);
if (value != - 1)
config.enable_voucher = value;
break;
case oForceVoucher:
value = parse_boolean_value(p1);
if (value != - 1)
config.force_voucher = value;
break;
case oFirewallRuleSet:
parse_firewall_ruleset(p1, fd, filename, &linenum);
break;
Expand Down
3 changes: 3 additions & 0 deletions src/conf.h
Expand Up @@ -144,6 +144,9 @@ typedef struct {
char *gw_address; /**< @brief Internal IP address for our web server */
unsigned int gw_port; /**< @brief Port the webserver will run on */
char *remote_auth_action; /**< @brief Path for remote auth */
char enable_preauth; /**< @brief enable pre-authentication support */
char enable_voucher; /**< @brief enable voucher support */
char force_voucher; /**< @brief force voucher */
char *webroot; /**< @brief Directory containing splash pages, etc. */
char *splashpage; /**< @brief Name of main splash page */
char *infoskelpage; /**< @brief Name of info skeleton page */
Expand Down
6 changes: 3 additions & 3 deletions src/firewall.c
Expand Up @@ -67,10 +67,10 @@
#include "safe.h"
#include "debug.h"
#include "conf.h"
#include "client_list.h"
#include "firewall.h"
#include "fw_iptables.h"
#include "auth.h"
#include "client_list.h"


extern pthread_mutex_t client_list_mutex;
Expand Down Expand Up @@ -215,7 +215,7 @@ fw_refresh_client_list(void)
cp1->ip, cp1->mac, config->checkinterval * config->clienttimeout,
cp1->counters.incoming/1000, cp1->counters.outgoing/1000);
if(cp1->fw_connection_state == FW_MARK_AUTHENTICATED) {
iptables_fw_access(AUTH_MAKE_DEAUTHENTICATED, cp1->ip, cp1->mac);
iptables_fw_access(AUTH_MAKE_DEAUTHENTICATED, cp1);
}
client_list_delete(cp1);
} else if (added_time + (config->checkinterval * config->clientforceout) <= now) {
Expand All @@ -224,7 +224,7 @@ fw_refresh_client_list(void)
cp1->ip, cp1->mac, config->checkinterval * config->clientforceout,
cp1->counters.incoming/1000, cp1->counters.outgoing/1000);
if(cp1->fw_connection_state == FW_MARK_AUTHENTICATED) {
iptables_fw_access(AUTH_MAKE_DEAUTHENTICATED, cp1->ip, cp1->mac);
iptables_fw_access(AUTH_MAKE_DEAUTHENTICATED, cp1);
}
client_list_delete(cp1);
}
Expand Down
42 changes: 30 additions & 12 deletions src/fw_iptables.c
Expand Up @@ -44,11 +44,11 @@
#include "safe.h"
#include "conf.h"
#include "auth.h"
#include "client_list.h"
#include "fw_iptables.h"
#include "firewall.h"
#include "debug.h"
#include "util.h"
#include "client_list.h"
#include "tc.h"

static char * _iptables_compile(const char *, char *, t_firewall_rule *);
Expand Down Expand Up @@ -410,7 +410,7 @@ iptables_fw_init(void)
*/

/* packets coming in on gw_interface jump to CHAIN_OUTGOING */
rc |= iptables_do_command("-t nat -I PREROUTING -i %s -s %s -j " CHAIN_OUTGOING, gw_interface, gw_iprange);
rc |= iptables_do_command("-t nat -A PREROUTING -i %s -s %s -j " CHAIN_OUTGOING, gw_interface, gw_iprange);
/* CHAIN_OUTGOING, packets marked TRUSTED ACCEPT */
rc |= iptables_do_command("-t nat -A " CHAIN_OUTGOING " -m mark --mark 0x%x%s -j ACCEPT", FW_MARK_TRUSTED, markmask);
/* CHAIN_OUTGOING, packets marked AUTHENTICATED ACCEPT */
Expand Down Expand Up @@ -501,7 +501,7 @@ iptables_fw_init(void)
*/

/* packets coming in on gw_interface jump to CHAIN_TO_INTERNET */
rc |= iptables_do_command("-t filter -I FORWARD -i %s -s %s -j " CHAIN_TO_INTERNET, gw_interface, gw_iprange);
rc |= iptables_do_command("-t filter -A FORWARD -i %s -s %s -j " CHAIN_TO_INTERNET, gw_interface, gw_iprange);
/* CHAIN_TO_INTERNET packets marked BLOCKED DROP */
rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x%s -j DROP", FW_MARK_BLOCKED, markmask);
/* CHAIN_TO_INTERNET, invalid packets DROP */
Expand Down Expand Up @@ -716,31 +716,49 @@ iptables_fw_destroy_mention(
/** Insert or delete firewall mangle rules marking a client's packets.
*/
int
iptables_fw_access(t_authaction action, const char *ip, const char *mac)
{
int rc;
iptables_fw_access(t_authaction action, t_client *client) {
int rc = 0, download_limit, upload_limit;
s_config *config;
char *download_imqname, *upload_imqname;

fw_quiet = 0;

config = config_get_config();
safe_asprintf(&download_imqname,"imq%d",config->download_imq); /* must free */
safe_asprintf(&upload_imqname,"imq%d",config->upload_imq); /* must free */

download_limit = config->download_limit;
upload_limit = config->upload_limit;

if ((client->download_limit > 0) && (client->upload_limit > 0)) {
download_limit = client->download_limit;
upload_limit = client->upload_limit;
}

switch(action) {
case AUTH_MAKE_AUTHENTICATED:
debug(LOG_NOTICE, "Authenticating %s %s", ip, mac);
debug(LOG_NOTICE, "Authenticating %s %s", client->ip, client->mac);
/* This rule is for marking upload (outgoing) packets, and for upload byte counting */
rc = iptables_do_command("-t mangle -A " CHAIN_OUTGOING " -s %s -m mac --mac-source %s -j MARK %s 0x%x", ip, mac, markop, FW_MARK_AUTHENTICATED);
rc |= iptables_do_command("-t mangle -I " CHAIN_OUTGOING " -s %s -m mac --mac-source %s -j MARK %s 0x%x%x", client->ip, client->mac, markop, client->idx + 10, FW_MARK_AUTHENTICATED);
rc |= iptables_do_command("-t mangle -I " CHAIN_INCOMING " -d %s -j MARK %s 0x%x%x", client->ip, markop, client->idx + 10, FW_MARK_AUTHENTICATED);
/* This rule is just for download (incoming) byte counting, see iptables_fw_counters_update() */
rc = iptables_do_command("-t mangle -A " CHAIN_INCOMING " -d %s -j ACCEPT", ip);
rc |= iptables_do_command("-t mangle -A " CHAIN_INCOMING " -d %s -j ACCEPT", client->ip);
rc |= tc_attach_client(download_imqname, download_limit, upload_imqname, upload_limit, client->idx, FW_MARK_AUTHENTICATED);
break;
case AUTH_MAKE_DEAUTHENTICATED:
/* Remove the authentication rules. */
debug(LOG_NOTICE, "Deauthenticating %s %s", ip, mac);
rc = iptables_do_command("-t mangle -D " CHAIN_OUTGOING " -s %s -m mac --mac-source %s -j MARK %s 0x%x", ip, mac, markop, FW_MARK_AUTHENTICATED);
rc = iptables_do_command("-t mangle -D " CHAIN_INCOMING " -d %s -j ACCEPT", ip);
debug(LOG_NOTICE, "Deauthenticating %s %s", client->ip, client->mac);
rc |= iptables_do_command("-t mangle -D " CHAIN_OUTGOING " -s %s -m mac --mac-source %s -j MARK %s 0x%x%x", client->ip, client->mac, markop, client->idx + 10, FW_MARK_AUTHENTICATED);
rc |= iptables_do_command("-t mangle -D " CHAIN_INCOMING " -d %s -j ACCEPT", client->ip);
rc |= tc_detach_client(download_imqname, upload_imqname, client->idx);
break;
default:
rc = -1;
break;
}

free(upload_imqname);
free(download_imqname);
return rc;
}

Expand Down
2 changes: 1 addition & 1 deletion src/fw_iptables.h
Expand Up @@ -55,7 +55,7 @@ int iptables_fw_destroy(void);
int iptables_fw_destroy_mention( const char * table, const char * chain, const char * mention);

/** @brief Define the access of a specific client */
int iptables_fw_access(t_authaction action, const char *ip, const char *mac);
int iptables_fw_access(t_authaction action, t_client *client);

/** @brief Return the total download usage in bytes */
unsigned long long int iptables_fw_total_download();
Expand Down

0 comments on commit 73e5b8d

Please sign in to comment.