Skip to content

Commit

Permalink
refactor: enhance client authentication and timeout handling with imp…
Browse files Browse the repository at this point in the history
…roved documentation

Signed-off-by: Dengfeng Liu <[email protected]>
  • Loading branch information
liudf0716 committed Nov 18, 2024
1 parent f641247 commit 952caf3
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 56 deletions.
135 changes: 96 additions & 39 deletions src/auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include "safe.h"
#include "conf.h"
#include "debug.h"
#include "auth.h"
#include "centralserver.h"
#include "fw_iptables.h"
#include "firewall.h"
Expand All @@ -18,25 +17,27 @@
#include "wd_util.h"
#include "ping_thread.h"
#include "wd_client.h"
#include "auth.h"

static void client_timeout_check_cb(evutil_socket_t, short, void *);

/** Launches a thread that periodically checks if any of the connections has timed out
@param arg Must contain a pointer to a string containing the IP adress of the client to check to check
@todo Also pass MAC adress?
@todo This thread loops infinitely, need a watchdog to verify that it is still running?
*/
void
thread_client_timeout_check(const void *arg)
/**
* @brief Callback function for checking client timeouts and syncing with auth server
*
* This callback is triggered periodically to:
* 1. Check for client timeouts
* 2. Synchronize firewall rules with the authentication server
*
* @param fd The socket file descriptor (unused)
* @param event The event type that triggered this callback (unused)
* @param arg Pointer to the request context
*/
static void
client_timeout_check_cb(evutil_socket_t fd, short event, void *arg)
{
wd_request_loop(client_timeout_check_cb);
}
struct wd_request_context *context = (struct wd_request_context *)arg;

debug(LOG_DEBUG, "Starting client timeout check");

static void
client_timeout_check_cb(evutil_socket_t fd, short event, void *arg) {
struct wd_request_context *context = (struct wd_request_context *)arg;

debug(LOG_DEBUG, "client_timeout_check_cb begin");
#ifdef AUTHSERVER_V2
ev_fw_sync_with_authserver_v2(context);
#else
Expand All @@ -45,72 +46,128 @@ client_timeout_check_cb(evutil_socket_t fd, short event, void *arg) {
}

/**
* @brief Logout a client and report to auth server.
* @brief Initializes and runs the client timeout checking thread
*
* This function starts a loop that periodically checks for client timeouts
* and synchronizes the firewall state with the authentication server.
*
* @param context Points to request context
* @param client Points to the client to be logged out; the client will be free
* in this function
* @param arg Thread arguments (unused)
*/
void
thread_client_timeout_check(const void *arg)
{
wd_request_loop(client_timeout_check_cb);
}

/**
* @brief Logs out a client and notifies the authentication server
*
* This function handles the client logout process by:
* 1. Generating the logout URI for the auth server
* 2. Setting up the HTTP request
* 3. Sending the logout notification
*
* @param context The request context for the operation
* @param client The client to be logged out
*
* @note The client structure will be freed by the callback function
* @note context->data is modified to point to the client during the request
*/
void
ev_logout_client(struct wd_request_context *context, t_client *client)
{
assert(client);
if (!context || !client) {
debug(LOG_ERR, "Invalid parameters to ev_logout_client");
return;
}

// Generate logout URI for this client
char *uri = get_auth_uri(REQUEST_TYPE_LOGOUT, ONLINE_CLIENT, client);
if (!uri) {
debug(LOG_ERR, "Failed to generate logout URI");
return;
}

debug(LOG_DEBUG, "Processing logout request with URI [%s]", uri);

// Setup auth server request
struct evhttp_connection *evcon = NULL;
struct evhttp_request *req = NULL;
struct evhttp_request *req = NULL;

assert(context->data == NULL);
context->data = client;
if (!wd_make_request(context, &evcon, &req, process_auth_server_logout))

if (!wd_make_request(context, &evcon, &req, process_auth_server_logout)) {
evhttp_make_request(evcon, req, EVHTTP_REQ_GET, uri);
else {
debug(LOG_ERR, "wd_make_request failed");
} else {
debug(LOG_ERR, "Failed to create auth server request");
context->data = NULL;
}

free(uri);
}

/**
* @brief authenticate login clients
* @brief Authenticates a client against the central server
*
* Authenticates a single client against the central server and returns when done
* Alters the firewall rules depending on what the auth server says
* This function handles the authentication process for a single client by:
* 1. Generating the authentication URI
* 2. Setting up the HTTP request to the auth server
* 3. Processing the auth server's response via callback
*
* @param req evhttp_request to reply client
* @param context wd_request_context for http client request
* @param client client by authenticated
* @param req The client's original HTTP request to respond to
* @param context Request context containing connection state and callbacks
* @param client The client to be authenticated
*
* @note The function will free the client structure if authentication fails
* @note context->data and context->clt_req are modified by this function
*/
void
ev_authenticate_client(struct evhttp_request *req,
struct wd_request_context *context, t_client *client)
struct wd_request_context *context, t_client *client)
{
if (!req || !context || !client) {
debug(LOG_ERR, "Invalid parameters to ev_authenticate_client");
if (req) evhttp_send_error(req, HTTP_INTERNAL, "Internal Server Error");
if (client) safe_client_list_delete(client);
return;
}

// Generate authentication URI for this client
char *uri = get_auth_uri(REQUEST_TYPE_LOGIN, ONLINE_CLIENT, client);
if (!uri) {
debug(LOG_ERR, "get_auth_uri failed");
debug(LOG_ERR, "Failed to generate auth URI");
evhttp_send_error(req, HTTP_INTERNAL, "Internal Server Error");
safe_client_list_delete(client);
return;
}

debug(LOG_DEBUG, "client login request [%s]", uri);
debug(LOG_DEBUG, "Processing login request with URI [%s]", uri);

struct evhttp_connection *wd_evcon = NULL;
struct evhttp_request *wd_req = NULL;
assert(context->data == NULL);
// Validate context state
if (context->data != NULL) {
debug(LOG_WARNING, "Context data not NULL, potential memory leak");
context->data = NULL;
}

// Setup request context
context->data = client;
context->clt_req = req;
context->clt_req = req;

// Setup and send auth server request
struct evhttp_connection *wd_evcon = NULL;
struct evhttp_request *wd_req = NULL;

if (!wd_make_request(context, &wd_evcon, &wd_req, process_auth_server_login)) {
evhttp_make_request(wd_evcon, wd_req, EVHTTP_REQ_GET, uri);
} else {
debug(LOG_ERR, "wd_make_request failed");
debug(LOG_ERR, "Failed to create auth server request");
evhttp_send_error(req, HTTP_INTERNAL, "Internal Server Error");
safe_client_list_delete(client);
context->data = NULL;
context->clt_req = NULL;
}

free(uri);
}

52 changes: 35 additions & 17 deletions src/auth.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,34 +12,52 @@
/**
* @brief Authentication codes returned by auth server.
*
* Authentication result codes returned by auth_server_request() corresponding
* to result code from the central server itself.
* Defines possible authentication states returned by the authentication server,
* ranging from error conditions to successful authentication.
*/
typedef enum {
AUTH_ERROR = -1, /**< An error occured during the validation process*/
AUTH_DENIED = 0, /**< Client was denied by the auth server */
AUTH_ALLOWED = 1, /**< Client was granted access by the auth server */
AUTH_VALIDATION = 5, /**< A misnomer. Client is in 15 min probation to validate his new account */
AUTH_VALIDATION_FAILED = 6, /**< Client had X minutes to validate account by email and didn't = too late */
AUTH_LOCKED = 254 /**< Account has been locked */
AUTH_ERROR = -1, /**< Authentication process error */
AUTH_DENIED = 0, /**< Access denied by auth server */
AUTH_ALLOWED = 1, /**< Access granted by auth server */
AUTH_VALIDATION = 5, /**< Client in 15-minute probation period */
AUTH_VALIDATION_FAILED = 6, /**< Failed to validate account within time limit */
AUTH_LOCKED = 254 /**< Account is locked */
} t_authcode;

/**
* @brief This structure contains all the information returned by the authentication server
/**
* @brief Authentication response structure
*
* Contains the server's response data including authentication status
* and client identification.
*/
typedef struct _t_authresponse {
t_authcode authcode; /**< Authentication code returned by the server */
unsigned long long client_id;
t_authcode authcode; /**< Authentication result code */
unsigned long long client_id; /**< Unique client identifier */
} t_authresponse;

struct wd_request_context;

/** @brief Logout a client and report to auth server. */
void ev_logout_client(struct wd_request_context *, t_client *);
/** @brief Authenticate a single client against the central server */
void ev_authenticate_client(struct evhttp_request *, struct wd_request_context *, t_client *);
/**
* @brief Handles client logout process
* @param context Request context
* @param client Client to be logged out
*/
void ev_logout_client(struct wd_request_context *context, t_client *client);

/** @brief Periodically check if connections expired */
/**
* @brief Processes client authentication
* @param request HTTP request object
* @param context Request context
* @param client Client to authenticate
*/
void ev_authenticate_client(struct evhttp_request *request,
struct wd_request_context *context,
t_client *client);

/**
* @brief Periodic connection timeout checker
* @param arg Thread arguments
*/
void thread_client_timeout_check(const void *arg);

#endif

0 comments on commit 952caf3

Please sign in to comment.