Skip to content

Commit

Permalink
Merge pull request #168 from acv/refactor-auth
Browse files Browse the repository at this point in the history
Partial rewrite of fw_sync_with_auth
  • Loading branch information
mhaas committed Apr 1, 2015
2 parents 98fce11 + ff90b70 commit 1366520
Show file tree
Hide file tree
Showing 12 changed files with 1,035 additions and 878 deletions.
41 changes: 36 additions & 5 deletions src/auth.c
Expand Up @@ -81,6 +81,39 @@ thread_client_timeout_check(const void *arg)
}
}

/**
* @brief Logout a client and report to auth server.
*
* This function assumes it is being called with the client lock held! This
* function remove the client from the client list and free its memory, so
* client is no langer valid when this method returns.
*
* @param client Points to the client to be logged out
*/
void
logout_client(t_client *client)
{
t_authresponse authresponse;
const s_config *config = config_get_config();
fw_deny(client);
client_list_remove(client);

/* Advertise the logout if we have an auth server */
if (config->auth_servers != NULL) {
UNLOCK_CLIENT_LIST();
auth_server_request(&authresponse, REQUEST_TYPE_LOGOUT,
client->ip, client->mac, client->token,
client->counters.incoming,
client->counters.outgoing);

if (authresponse.authcode==AUTH_ERROR)
debug(LOG_WARNING, "Auth server error when reporting logout");
LOCK_CLIENT_LIST();
}

client_free_node(client);
}

/** Authenticates a single client against the central server and returns when done
* Alters the firewall rules depending on what the auth server says
@param r httpd request struct
Expand Down Expand Up @@ -162,7 +195,7 @@ authenticate_client(request *r)
case AUTH_DENIED:
/* Central server said invalid token */
debug(LOG_INFO, "Got DENIED from central server authenticating token %s from %s at %s - deleting from firewall and redirecting them to denied message", client->token, client->ip, client->mac);
fw_deny(client->ip, client->mac, FW_MARK_KNOWN);
fw_deny(client);
safe_asprintf(&urlFragment, "%smessage=%s",
auth_server->authserv_msg_script_path_fragment,
GATEWAY_MESSAGE_DENIED
Expand All @@ -176,8 +209,7 @@ authenticate_client(request *r)
debug(LOG_INFO, "Got VALIDATION from central server authenticating token %s from %s at %s"
"- adding to firewall and redirecting them to activate message", client->token,
client->ip, client->mac);
client->fw_connection_state = FW_MARK_PROBATION;
fw_allow(client->ip, client->mac, FW_MARK_PROBATION);
fw_allow(client, FW_MARK_PROBATION);
safe_asprintf(&urlFragment, "%smessage=%s",
auth_server->authserv_msg_script_path_fragment,
GATEWAY_MESSAGE_ACTIVATE_ACCOUNT
Expand All @@ -190,8 +222,7 @@ authenticate_client(request *r)
/* Logged in successfully as a regular account */
debug(LOG_INFO, "Got ALLOWED from central server authenticating token %s from %s at %s - "
"adding to firewall and redirecting them to portal", client->token, client->ip, client->mac);
client->fw_connection_state = FW_MARK_KNOWN;
fw_allow(client->ip, client->mac, FW_MARK_KNOWN);
fw_allow(client, FW_MARK_KNOWN);
served_this_session++;
safe_asprintf(&urlFragment, "%sgw_id=%s",
auth_server->authserv_portal_script_path_fragment,
Expand Down
3 changes: 3 additions & 0 deletions src/auth.h
Expand Up @@ -28,6 +28,7 @@
#define _AUTH_H_

#include "httpd.h"
#include "client_list.h"

/**
* @brief Authentication codes returned by auth server.
Expand All @@ -51,6 +52,8 @@ typedef struct _t_authresponse {
t_authcode authcode; /**< Authentication code returned by the server */
} t_authresponse;

/** @brief Logout a client and report to auth server. */
void logout_client(t_client *);

/** @brief Authenticate a single client against the central server */
void authenticate_client(request *);
Expand Down
157 changes: 126 additions & 31 deletions src/client_list.c
Expand Up @@ -44,8 +44,18 @@

/** @internal
* Holds a pointer to the first element of the list
*/
static t_client *firstclient = NULL;
*/
static t_client *firstclient = NULL;

/** @internal
* Client ID
*/
static volatile unsigned long long client_id = 1;

/**
* Mutex to protect client_id and guarantee uniqueness.
*/
static pthread_mutex_t client_id_mutex = PTHREAD_MUTEX_INITIALIZER;

/** Global mutex to protect access to the client list */
pthread_mutex_t client_list_mutex = PTHREAD_MUTEX_INITIALIZER;
Expand Down Expand Up @@ -82,66 +92,135 @@ client_list_init(void)
* @param Pointer to t_client object.
*/
void
client_list_insert_client(t_client *client)
client_list_insert_client(t_client * client)
{
t_client *prev_head;

pthread_mutex_lock(&client_id_mutex);
client->id = client_id++;
pthread_mutex_unlock(&client_id_mutex);
prev_head = firstclient;
client->next = prev_head;
firstclient = client;
}


/** Based on the parameters it receives, this function creates a new entry
* in the connections list. All the memory allocation is done here.
* Client is inserted at the head of the list.
* @param ip IP address
* @param mac MAC address
* @param token Token
* @return Pointer to the client we just created
*/
t_client *
client_list_append(const char *ip, const char *mac, const char *token)
t_client *
client_list_add(const char *ip, const char *mac, const char *token)
{
t_client *curclient, *prevclient;

prevclient = NULL;
curclient = firstclient;

while (curclient != NULL) {
prevclient = curclient;
curclient = curclient->next;
}
t_client *curclient;

curclient = client_get_new();

curclient->ip = safe_strdup(ip);
curclient->mac = safe_strdup(mac);
curclient->token = safe_strdup(token);
curclient->counters.incoming = curclient->counters.incoming_history = curclient->counters.outgoing = curclient->counters.outgoing_history = 0;
curclient->counters.incoming = curclient->counters.incoming_history = curclient->counters.outgoing =
curclient->counters.outgoing_history = 0;
curclient->counters.last_updated = time(NULL);

if (prevclient == NULL) {
firstclient = curclient;
} else {
prevclient->next = curclient;
}
client_list_insert_client(curclient);

debug(LOG_INFO, "Added a new client to linked list: IP: %s Token: %s",
ip, token);
debug(LOG_INFO, "Added a new client to linked list: IP: %s Token: %s", ip, token);

return curclient;
}

/** Duplicate the whole client list to process in a thread safe way
* MUTEX MUST BE HELD.
* @param dest pointer TO A POINTER to a t_client (i.e.: t_client **ptr)
* @return int Number of clients copied
*/
int
client_list_dup(t_client ** dest)
{
t_client *new, *cur, *top, *prev;
int copied = 0;

cur = firstclient;
new = top = prev = NULL;

if (NULL == cur) {
*dest = new; /* NULL */
return copied;
}

while (NULL != cur) {
new = client_dup(cur);
if (NULL == top) {
/* first item */
top = new;
} else {
prev->next = new;
}
prev = new;
copied++;
cur = cur->next;
}

*dest = top;
return copied;
}

/** Create a duplicate of a client.
* @param src Original client
* @return duplicate client object with next == NULL
*/
t_client *
client_dup(const t_client * src)
{
t_client *new = client_get_new();

new->id = src->id;
new->ip = safe_strdup(src->ip);
new->mac = safe_strdup(src->mac);
new->token = safe_strdup(src->token);
new->counters.incoming = src->counters.incoming;
new->counters.incoming_history = src->counters.incoming_history;
new->counters.outgoing = src->counters.outgoing;
new->counters.outgoing_history = src->counters.outgoing_history;
new->counters.last_updated = src->counters.last_updated;
new->next = NULL;

return new;
}

/** Find a client in the list from a client struct, matching operates by id.
* This is useful from a copy of client to find the original.
* @param client Client to find
* @return pointer to the client in the list.
*/
t_client *
client_list_find_by_client(t_client * client)
{
t_client *c = firstclient;

while (NULL != c) {
if (c->id == client->id) {
return c;
}
c = c->next;
}
return NULL;
}

/** Finds a client by its IP and MAC, returns NULL if the client could not
* be found
* @param ip IP we are looking for in the linked list
* @param mac MAC we are looking for in the linked list
* @return Pointer to the client, or NULL if not found
*/
t_client *
t_client *
client_list_find(const char *ip, const char *mac)
{
t_client *ptr;
t_client *ptr;

ptr = firstclient;
while (NULL != ptr) {
Expand All @@ -159,10 +238,10 @@ client_list_find(const char *ip, const char *mac)
* @param ip IP we are looking for in the linked list
* @return Pointer to the client, or NULL if not found
*/
t_client *
t_client *
client_list_find_by_ip(const char *ip)
{
t_client *ptr;
t_client *ptr;

ptr = firstclient;
while (NULL != ptr) {
Expand All @@ -180,10 +259,10 @@ client_list_find_by_ip(const char *ip)
* @param mac Mac we are looking for in the linked list
* @return Pointer to the client, or NULL if not found
*/
t_client *
t_client *
client_list_find_by_mac(const char *mac)
{
t_client *ptr;
t_client *ptr;

ptr = firstclient;
while (NULL != ptr) {
Expand All @@ -202,7 +281,7 @@ client_list_find_by_mac(const char *mac)
t_client *
client_list_find_by_token(const char *token)
{
t_client *ptr;
t_client *ptr;

ptr = firstclient;
while (NULL != ptr) {
Expand All @@ -214,6 +293,22 @@ client_list_find_by_token(const char *token)
return NULL;
}

/** Destroy the client list. Including all free...
* DOES NOT UPDATE firstclient or anything else.
* @param list List to destroy (first item)
*/
void
client_list_destroy(t_client * list)
{
t_client *next;

while (NULL != list) {
next = list->next;
client_free_node(list);
list = next;
}
}

/** @internal
* @brief Frees the memory used by a t_client structure
* This function frees the memory used by the t_client structure in the
Expand Down Expand Up @@ -258,7 +353,7 @@ client_list_delete(t_client * client)
void
client_list_remove(t_client * client)
{
t_client *ptr;
t_client *ptr;

ptr = firstclient;

Expand Down

0 comments on commit 1366520

Please sign in to comment.