1
+ /* vim: set et sw=4 ts=4 sts=4 : */
1
2
/********************************************************************\
2
3
* This program is free software; you can redistribute it and/or *
3
4
* modify it under the terms of the GNU General Public License as *
48
49
#include "client_list.h"
49
50
#include "util.h"
50
51
51
-
52
52
/** Launches a thread that periodically checks if any of the connections has timed out
53
53
@param arg Must contain a pointer to a string containing the IP adress of the client to check to check
54
54
@todo Also pass MAC adress?
55
55
@todo This thread loops infinitely, need a watchdog to verify that it is still running?
56
- */
56
+ */
57
57
void
58
58
thread_client_timeout_check (const void * arg )
59
59
{
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
+ }
82
82
}
83
83
84
84
/**
@@ -91,9 +91,9 @@ thread_client_timeout_check(const void *arg)
91
91
* @param client Points to the client to be logged out
92
92
*/
93
93
void
94
- logout_client (t_client * client )
94
+ logout_client (t_client * client )
95
95
{
96
- t_authresponse authresponse ;
96
+ t_authresponse authresponse ;
97
97
const s_config * config = config_get_config ();
98
98
fw_deny (client );
99
99
client_list_remove (client );
@@ -102,11 +102,10 @@ logout_client(t_client *client)
102
102
if (config -> auth_servers != NULL ) {
103
103
UNLOCK_CLIENT_LIST ();
104
104
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 );
108
107
109
- if (authresponse .authcode == AUTH_ERROR )
108
+ if (authresponse .authcode == AUTH_ERROR )
110
109
debug (LOG_WARNING , "Auth server error when reporting logout" );
111
110
LOCK_CLIENT_LIST ();
112
111
}
@@ -119,140 +118,133 @@ logout_client(t_client *client)
119
118
@param r httpd request struct
120
119
*/
121
120
void
122
- authenticate_client (request * r )
121
+ authenticate_client (request * r )
123
122
{
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 ;
206
206
207
207
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 ;
220
217
221
218
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 );
226
223
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 ;
234
228
235
229
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 ;
246
238
247
239
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 ;
251
245
252
- }
246
+ }
253
247
254
- UNLOCK_CLIENT_LIST ();
255
- return ;
248
+ UNLOCK_CLIENT_LIST ();
249
+ return ;
256
250
}
257
-
258
-
0 commit comments