auth.c

Go to the documentation of this file.
00001 /********************************************************************\
00002  * This program is free software; you can redistribute it and/or    *
00003  * modify it under the terms of the GNU General Public License as   *
00004  * published by the Free Software Foundation; either version 2 of   *
00005  * the License, or (at your option) any later version.              *
00006  *                                                                  *
00007  * This program is distributed in the hope that it will be useful,  *
00008  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
00009  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
00010  * GNU General Public License for more details.                     *
00011  *                                                                  *
00012  * You should have received a copy of the GNU General Public License*
00013  * along with this program; if not, contact:                        *
00014  *                                                                  *
00015  * Free Software Foundation           Voice:  +1-617-542-5942       *
00016  * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652       *
00017  * Boston, MA  02111-1307,  USA       gnu@gnu.org                   *
00018  *                                                                  *
00019 \********************************************************************/
00020 
00021 /* $Id: auth.c 1243 2007-06-28 01:48:01Z benoitg $ */
00027 #define _GNU_SOURCE
00028 
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <pthread.h>
00032 #include <string.h>
00033 #include <stdarg.h>
00034 #include <sys/types.h>
00035 #include <sys/socket.h>
00036 #include <unistd.h>
00037 #include <syslog.h>
00038 
00039 #include "httpd.h"
00040 #include "http.h"
00041 #include "safe.h"
00042 #include "conf.h"
00043 #include "debug.h"
00044 #include "auth.h"
00045 #include "centralserver.h"
00046 #include "fw_iptables.h"
00047 #include "firewall.h"
00048 #include "client_list.h"
00049 #include "util.h"
00050 
00051 /* Defined in clientlist.c */
00052 extern  pthread_mutex_t client_list_mutex;
00053 
00054 /* Defined in util.c */
00055 extern long served_this_session;
00056 
00062 void
00063 thread_client_timeout_check(void *arg)
00064 {
00065         pthread_cond_t          cond = PTHREAD_COND_INITIALIZER;
00066         pthread_mutex_t         cond_mutex = PTHREAD_MUTEX_INITIALIZER;
00067         struct  timespec        timeout;
00068         
00069         while (1) {
00070                 /* Sleep for config.checkinterval seconds... */
00071                 timeout.tv_sec = time(NULL) + config_get_config()->checkinterval;
00072                 timeout.tv_nsec = 0;
00073 
00074                 /* Mutex must be locked for pthread_cond_timedwait... */
00075                 pthread_mutex_lock(&cond_mutex);
00076                 
00077                 /* Thread safe "sleep" */
00078                 pthread_cond_timedwait(&cond, &cond_mutex, &timeout);
00079 
00080                 /* No longer needs to be locked */
00081                 pthread_mutex_unlock(&cond_mutex);
00082         
00083                 debug(LOG_DEBUG, "Running fw_counter()");
00084         
00085                 fw_sync_with_authserver();
00086         }
00087 }
00088 
00093 void
00094 authenticate_client(request *r)
00095 {
00096         t_client        *client;
00097         t_authresponse  auth_response;
00098         char    *ip,
00099                 *mac,
00100                 *token;
00101         char *urlFragment = NULL;
00102         s_config        *config = NULL;
00103         t_auth_serv     *auth_server = NULL;
00104 
00105         LOCK_CLIENT_LIST();
00106 
00107         client = client_list_find_by_ip(r->clientAddr);
00108 
00109         if (client == NULL) {
00110                 debug(LOG_ERR, "Could not find client for %s", ip);
00111                 UNLOCK_CLIENT_LIST();
00112                 return;
00113         }
00114         
00115         mac = safe_strdup(client->mac);
00116         token = safe_strdup(client->token);
00117         
00118         UNLOCK_CLIENT_LIST();
00119         
00120         /* 
00121          * At this point we've released the lock while we do an HTTP request since it could
00122          * take multiple seconds to do and the gateway would effectively be frozen if we
00123          * kept the lock.
00124          */
00125         auth_server_request(&auth_response, REQUEST_TYPE_LOGIN, r->clientAddr, mac, token, 0, 0);
00126         
00127         LOCK_CLIENT_LIST();
00128         
00129         /* can't trust the client to still exist after n seconds have passed */
00130         client = client_list_find(r->clientAddr, mac);
00131         
00132         if (client == NULL) {
00133                 debug(LOG_ERR, "Could not find client node for %s (%s)", r->clientAddr, mac);
00134                 UNLOCK_CLIENT_LIST();
00135                 free(token);
00136                 free(mac);
00137                 return;
00138         }
00139         
00140         free(token);
00141         free(mac);
00142 
00143         /* Prepare some variables we'll need below */
00144         config = config_get_config();
00145         auth_server = get_auth_server();
00146 
00147         switch(auth_response.authcode) {
00148 
00149         case AUTH_ERROR:
00150                 /* Error talking to central server */
00151                 debug(LOG_ERR, "Got %d from central server authenticating token %s from %s at %s", auth_response, client->token, client->ip, client->mac);
00152                 http_wifidog_header(r, "Error!");
00153                 httpdOutput(r, "Error: We did not get a valid answer from the central server");
00154                 http_wifidog_footer(r);
00155                 break;
00156 
00157         case AUTH_DENIED:
00158                 /* Central server said invalid token */
00159                 debug(LOG_INFO, "Got DENIED from central server authenticating token %s from %s at %s - redirecting them to denied message", client->token, client->ip, client->mac);
00160                 safe_asprintf(&urlFragment, "%smessage=%s",
00161                         auth_server->authserv_msg_script_path_fragment,
00162                         GATEWAY_MESSAGE_DENIED
00163                 );
00164                 http_send_redirect_to_auth(r, urlFragment, "Redirect to denied message");
00165                 free(urlFragment);
00166                 break;
00167 
00168     case AUTH_VALIDATION:
00169                 /* They just got validated for X minutes to check their email */
00170                 debug(LOG_INFO, "Got VALIDATION from central server authenticating token %s from %s at %s"
00171                                 "- adding to firewall and redirecting them to activate message", client->token,
00172                                 client->ip, client->mac);
00173                 client->fw_connection_state = FW_MARK_PROBATION;
00174                 fw_allow(client->ip, client->mac, FW_MARK_PROBATION);
00175                 safe_asprintf(&urlFragment, "%smessage=%s",
00176                         auth_server->authserv_msg_script_path_fragment,
00177                         GATEWAY_MESSAGE_ACTIVATE_ACCOUNT
00178                 );
00179                 http_send_redirect_to_auth(r, urlFragment, "Redirect to activate message");
00180                 free(urlFragment);
00181             break;
00182 
00183     case AUTH_ALLOWED:
00184                 /* Logged in successfully as a regular account */
00185                 debug(LOG_INFO, "Got ALLOWED from central server authenticating token %s from %s at %s - "
00186                                 "adding to firewall and redirecting them to portal", client->token, client->ip, client->mac);
00187                 client->fw_connection_state = FW_MARK_KNOWN;
00188                 fw_allow(client->ip, client->mac, FW_MARK_KNOWN);
00189         served_this_session++;
00190                 safe_asprintf(&urlFragment, "%sgw_id=%s",
00191                         auth_server->authserv_portal_script_path_fragment,
00192                         config->gw_id
00193                 );
00194                 http_send_redirect_to_auth(r, urlFragment, "Redirect to portal");
00195                 free(urlFragment);
00196             break;
00197 
00198     case AUTH_VALIDATION_FAILED:
00199                  /* Client had X minutes to validate account by email and didn't = too late */
00200                 debug(LOG_INFO, "Got VALIDATION_FAILED from central server authenticating token %s from %s at %s "
00201                                 "- redirecting them to failed_validation message", client->token, client->ip, client->mac);
00202                 safe_asprintf(&urlFragment, "%smessage=%s",
00203                         auth_server->authserv_msg_script_path_fragment,
00204                         GATEWAY_MESSAGE_ACCOUNT_VALIDATION_FAILED
00205                 );
00206                 http_send_redirect_to_auth(r, urlFragment, "Redirect to failed validation message");
00207                 free(urlFragment);
00208             break;
00209 
00210     default:
00211                 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);
00212                 http_wifidog_header(r, "Internal error");
00213                 httpdOutput(r, "We can not validate your request at this time");
00214                 http_wifidog_footer(r);
00215             break;
00216 
00217         }
00218 
00219         UNLOCK_CLIENT_LIST();
00220         return;
00221 }
00222 
00223 

Generated on Thu Oct 18 17:15:19 2007 for WifiDog by  doxygen 1.5.3