Skip to content

Commit ec23a7b

Browse files
committed
Merge pull request #177 from acv/refactor-auth-c
Refactor auth.c
2 parents 87e6a11 + d29dff3 commit ec23a7b

File tree

3 files changed

+154
-155
lines changed

3 files changed

+154
-155
lines changed

src/auth.c

Lines changed: 146 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* vim: set et sw=4 ts=4 sts=4 : */
12
/********************************************************************\
23
* This program is free software; you can redistribute it and/or *
34
* modify it under the terms of the GNU General Public License as *
@@ -48,37 +49,36 @@
4849
#include "client_list.h"
4950
#include "util.h"
5051

51-
5252
/** Launches a thread that periodically checks if any of the connections has timed out
5353
@param arg Must contain a pointer to a string containing the IP adress of the client to check to check
5454
@todo Also pass MAC adress?
5555
@todo This thread loops infinitely, need a watchdog to verify that it is still running?
56-
*/
56+
*/
5757
void
5858
thread_client_timeout_check(const void *arg)
5959
{
60-
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
61-
pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER;
62-
struct timespec timeout;
63-
64-
while (1) {
65-
/* Sleep for config.checkinterval seconds... */
66-
timeout.tv_sec = time(NULL) + config_get_config()->checkinterval;
67-
timeout.tv_nsec = 0;
68-
69-
/* Mutex must be locked for pthread_cond_timedwait... */
70-
pthread_mutex_lock(&cond_mutex);
71-
72-
/* Thread safe "sleep" */
73-
pthread_cond_timedwait(&cond, &cond_mutex, &timeout);
74-
75-
/* No longer needs to be locked */
76-
pthread_mutex_unlock(&cond_mutex);
77-
78-
debug(LOG_DEBUG, "Running fw_counter()");
79-
80-
fw_sync_with_authserver();
81-
}
60+
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
61+
pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER;
62+
struct timespec timeout;
63+
64+
while (1) {
65+
/* Sleep for config.checkinterval seconds... */
66+
timeout.tv_sec = time(NULL) + config_get_config()->checkinterval;
67+
timeout.tv_nsec = 0;
68+
69+
/* Mutex must be locked for pthread_cond_timedwait... */
70+
pthread_mutex_lock(&cond_mutex);
71+
72+
/* Thread safe "sleep" */
73+
pthread_cond_timedwait(&cond, &cond_mutex, &timeout);
74+
75+
/* No longer needs to be locked */
76+
pthread_mutex_unlock(&cond_mutex);
77+
78+
debug(LOG_DEBUG, "Running fw_counter()");
79+
80+
fw_sync_with_authserver();
81+
}
8282
}
8383

8484
/**
@@ -91,9 +91,9 @@ thread_client_timeout_check(const void *arg)
9191
* @param client Points to the client to be logged out
9292
*/
9393
void
94-
logout_client(t_client *client)
94+
logout_client(t_client * client)
9595
{
96-
t_authresponse authresponse;
96+
t_authresponse authresponse;
9797
const s_config *config = config_get_config();
9898
fw_deny(client);
9999
client_list_remove(client);
@@ -102,11 +102,10 @@ logout_client(t_client *client)
102102
if (config->auth_servers != NULL) {
103103
UNLOCK_CLIENT_LIST();
104104
auth_server_request(&authresponse, REQUEST_TYPE_LOGOUT,
105-
client->ip, client->mac, client->token,
106-
client->counters.incoming,
107-
client->counters.outgoing);
105+
client->ip, client->mac, client->token,
106+
client->counters.incoming, client->counters.outgoing);
108107

109-
if (authresponse.authcode==AUTH_ERROR)
108+
if (authresponse.authcode == AUTH_ERROR)
110109
debug(LOG_WARNING, "Auth server error when reporting logout");
111110
LOCK_CLIENT_LIST();
112111
}
@@ -119,140 +118,133 @@ logout_client(t_client *client)
119118
@param r httpd request struct
120119
*/
121120
void
122-
authenticate_client(request *r)
121+
authenticate_client(request * r)
123122
{
124-
t_client *client;
125-
t_authresponse auth_response;
126-
char *mac,
127-
*token;
128-
httpVar *var;
129-
char *urlFragment = NULL;
130-
s_config *config = NULL;
131-
t_auth_serv *auth_server = NULL;
132-
133-
LOCK_CLIENT_LIST();
134-
135-
client = client_list_find_by_ip(r->clientAddr);
136-
137-
if (client == NULL) {
138-
debug(LOG_ERR, "authenticate_client(): Could not find client for %s", r->clientAddr);
139-
UNLOCK_CLIENT_LIST();
140-
return;
141-
}
142-
143-
mac = safe_strdup(client->mac);
144-
145-
/* Users could try to log in(so there is a valid token in
146-
* request) even after they have logged in, try to deal with
147-
* this */
148-
if ((var = httpdGetVariableByName(r, "token")) != NULL) {
149-
if (client->token)
150-
free(client->token);
151-
152-
client->token = safe_strdup(var->value);
153-
token = safe_strdup(var->value);
154-
} else {
155-
token = safe_strdup(client->token);
156-
}
157-
158-
UNLOCK_CLIENT_LIST();
159-
160-
/*
161-
* At this point we've released the lock while we do an HTTP request since it could
162-
* take multiple seconds to do and the gateway would effectively be frozen if we
163-
* kept the lock.
164-
*/
165-
auth_server_request(&auth_response, REQUEST_TYPE_LOGIN, r->clientAddr, mac, token, 0, 0);
166-
167-
LOCK_CLIENT_LIST();
168-
169-
/* can't trust the client to still exist after n seconds have passed */
170-
client = client_list_find(r->clientAddr, mac);
171-
172-
if (client == NULL) {
173-
debug(LOG_ERR, "authenticate_client(): Could not find client node for %s (%s)", r->clientAddr, mac);
174-
UNLOCK_CLIENT_LIST();
175-
free(token);
176-
free(mac);
177-
return;
178-
}
179-
180-
free(token);
181-
free(mac);
182-
183-
/* Prepare some variables we'll need below */
184-
config = config_get_config();
185-
auth_server = get_auth_server();
186-
187-
switch(auth_response.authcode) {
188-
189-
case AUTH_ERROR:
190-
/* Error talking to central server */
191-
debug(LOG_ERR, "Got ERROR from central server authenticating token %s from %s at %s", client->token, client->ip, client->mac);
192-
send_http_page(r, "Error!", "Error: We did not get a valid answer from the central server");
193-
break;
194-
195-
case AUTH_DENIED:
196-
/* Central server said invalid token */
197-
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);
198-
fw_deny(client);
199-
safe_asprintf(&urlFragment, "%smessage=%s",
200-
auth_server->authserv_msg_script_path_fragment,
201-
GATEWAY_MESSAGE_DENIED
202-
);
203-
http_send_redirect_to_auth(r, urlFragment, "Redirect to denied message");
204-
free(urlFragment);
205-
break;
123+
t_client *client, *tmp;
124+
t_authresponse auth_response;
125+
char *token;
126+
httpVar *var;
127+
char *urlFragment = NULL;
128+
s_config *config = NULL;
129+
t_auth_serv *auth_server = NULL;
130+
131+
LOCK_CLIENT_LIST();
132+
133+
client = client_dup(client_list_find_by_ip(r->clientAddr));
134+
135+
UNLOCK_CLIENT_LIST();
136+
137+
if (client == NULL) {
138+
debug(LOG_ERR, "authenticate_client(): Could not find client for %s", r->clientAddr);
139+
return;
140+
}
141+
142+
/* Users could try to log in(so there is a valid token in
143+
* request) even after they have logged in, try to deal with
144+
* this */
145+
if ((var = httpdGetVariableByName(r, "token")) != NULL) {
146+
token = safe_strdup(var->value);
147+
} else {
148+
token = safe_strdup(client->token);
149+
}
150+
151+
/*
152+
* At this point we've released the lock while we do an HTTP request since it could
153+
* take multiple seconds to do and the gateway would effectively be frozen if we
154+
* kept the lock.
155+
*/
156+
auth_server_request(&auth_response, REQUEST_TYPE_LOGIN, client->ip, client->mac, token, 0, 0);
157+
158+
LOCK_CLIENT_LIST();
159+
160+
/* can't trust the client to still exist after n seconds have passed */
161+
tmp = client_list_find_by_client(client);
162+
163+
if (NULL == tmp) {
164+
debug(LOG_ERR, "authenticate_client(): Could not find client node for %s (%s)", client->ip, client->mac);
165+
UNLOCK_CLIENT_LIST();
166+
client_list_destroy(client); /* Free the cloned client */
167+
free(token);
168+
return;
169+
}
170+
171+
client_list_destroy(client); /* Free the cloned client */
172+
client = tmp;
173+
174+
if (strcmp(token, client->token) != 0) {
175+
/* If token changed, save it. */
176+
free(client->token);
177+
client->token = token;
178+
} else {
179+
free(token);
180+
}
181+
182+
/* Prepare some variables we'll need below */
183+
config = config_get_config();
184+
auth_server = get_auth_server();
185+
186+
switch (auth_response.authcode) {
187+
188+
case AUTH_ERROR:
189+
/* Error talking to central server */
190+
debug(LOG_ERR, "Got ERROR from central server authenticating token %s from %s at %s", client->token, client->ip,
191+
client->mac);
192+
send_http_page(r, "Error!", "Error: We did not get a valid answer from the central server");
193+
break;
194+
195+
case AUTH_DENIED:
196+
/* Central server said invalid token */
197+
debug(LOG_INFO,
198+
"Got DENIED from central server authenticating token %s from %s at %s - deleting from firewall and redirecting them to denied message",
199+
client->token, client->ip, client->mac);
200+
fw_deny(client);
201+
safe_asprintf(&urlFragment, "%smessage=%s",
202+
auth_server->authserv_msg_script_path_fragment, GATEWAY_MESSAGE_DENIED);
203+
http_send_redirect_to_auth(r, urlFragment, "Redirect to denied message");
204+
free(urlFragment);
205+
break;
206206

207207
case AUTH_VALIDATION:
208-
/* They just got validated for X minutes to check their email */
209-
debug(LOG_INFO, "Got VALIDATION from central server authenticating token %s from %s at %s"
210-
"- adding to firewall and redirecting them to activate message", client->token,
211-
client->ip, client->mac);
212-
fw_allow(client, FW_MARK_PROBATION);
213-
safe_asprintf(&urlFragment, "%smessage=%s",
214-
auth_server->authserv_msg_script_path_fragment,
215-
GATEWAY_MESSAGE_ACTIVATE_ACCOUNT
216-
);
217-
http_send_redirect_to_auth(r, urlFragment, "Redirect to activate message");
218-
free(urlFragment);
219-
break;
208+
/* They just got validated for X minutes to check their email */
209+
debug(LOG_INFO, "Got VALIDATION from central server authenticating token %s from %s at %s"
210+
"- adding to firewall and redirecting them to activate message", client->token, client->ip, client->mac);
211+
fw_allow(client, FW_MARK_PROBATION);
212+
safe_asprintf(&urlFragment, "%smessage=%s",
213+
auth_server->authserv_msg_script_path_fragment, GATEWAY_MESSAGE_ACTIVATE_ACCOUNT);
214+
http_send_redirect_to_auth(r, urlFragment, "Redirect to activate message");
215+
free(urlFragment);
216+
break;
220217

221218
case AUTH_ALLOWED:
222-
/* Logged in successfully as a regular account */
223-
debug(LOG_INFO, "Got ALLOWED from central server authenticating token %s from %s at %s - "
224-
"adding to firewall and redirecting them to portal", client->token, client->ip, client->mac);
225-
fw_allow(client, FW_MARK_KNOWN);
219+
/* Logged in successfully as a regular account */
220+
debug(LOG_INFO, "Got ALLOWED from central server authenticating token %s from %s at %s - "
221+
"adding to firewall and redirecting them to portal", client->token, client->ip, client->mac);
222+
fw_allow(client, FW_MARK_KNOWN);
226223
served_this_session++;
227-
safe_asprintf(&urlFragment, "%sgw_id=%s",
228-
auth_server->authserv_portal_script_path_fragment,
229-
config->gw_id
230-
);
231-
http_send_redirect_to_auth(r, urlFragment, "Redirect to portal");
232-
free(urlFragment);
233-
break;
224+
safe_asprintf(&urlFragment, "%sgw_id=%s", auth_server->authserv_portal_script_path_fragment, config->gw_id);
225+
http_send_redirect_to_auth(r, urlFragment, "Redirect to portal");
226+
free(urlFragment);
227+
break;
234228

235229
case AUTH_VALIDATION_FAILED:
236-
/* Client had X minutes to validate account by email and didn't = too late */
237-
debug(LOG_INFO, "Got VALIDATION_FAILED from central server authenticating token %s from %s at %s "
238-
"- redirecting them to failed_validation message", client->token, client->ip, client->mac);
239-
safe_asprintf(&urlFragment, "%smessage=%s",
240-
auth_server->authserv_msg_script_path_fragment,
241-
GATEWAY_MESSAGE_ACCOUNT_VALIDATION_FAILED
242-
);
243-
http_send_redirect_to_auth(r, urlFragment, "Redirect to failed validation message");
244-
free(urlFragment);
245-
break;
230+
/* Client had X minutes to validate account by email and didn't = too late */
231+
debug(LOG_INFO, "Got VALIDATION_FAILED from central server authenticating token %s from %s at %s "
232+
"- redirecting them to failed_validation message", client->token, client->ip, client->mac);
233+
safe_asprintf(&urlFragment, "%smessage=%s",
234+
auth_server->authserv_msg_script_path_fragment, GATEWAY_MESSAGE_ACCOUNT_VALIDATION_FAILED);
235+
http_send_redirect_to_auth(r, urlFragment, "Redirect to failed validation message");
236+
free(urlFragment);
237+
break;
246238

247239
default:
248-
debug(LOG_WARNING, "I don't know what the validation code %d means for token %s from %s at %s - sending error message", auth_response.authcode, client->token, client->ip, client->mac);
249-
send_http_page(r, "Internal Error", "We can not validate your request at this time");
250-
break;
240+
debug(LOG_WARNING,
241+
"I don't know what the validation code %d means for token %s from %s at %s - sending error message",
242+
auth_response.authcode, client->token, client->ip, client->mac);
243+
send_http_page(r, "Internal Error", "We can not validate your request at this time");
244+
break;
251245

252-
}
246+
}
253247

254-
UNLOCK_CLIENT_LIST();
255-
return;
248+
UNLOCK_CLIENT_LIST();
249+
return;
256250
}
257-
258-

src/auth.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* vim: set et sw=4 ts=4 sts=4 : */
12
/********************************************************************\
23
* This program is free software; you can redistribute it and/or *
34
* modify it under the terms of the GNU General Public License as *

src/client_list.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,13 @@ client_list_dup(t_client ** dest)
176176
t_client *
177177
client_dup(const t_client * src)
178178
{
179-
t_client *new = client_get_new();
179+
t_client *new = NULL;
180+
181+
if (NULL == src) {
182+
return NULL;
183+
}
184+
185+
new = client_get_new();
180186

181187
new->id = src->id;
182188
new->ip = safe_strdup(src->ip);

0 commit comments

Comments
 (0)