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 1305 2007-11-01 20:04:20Z 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    *mac,
00099                 *token;
00100         char *urlFragment = NULL;
00101         s_config        *config = NULL;
00102         t_auth_serv     *auth_server = NULL;
00103 
00104         LOCK_CLIENT_LIST();
00105 
00106         client = client_list_find_by_ip(r->clientAddr);
00107 
00108         if (client == NULL) {
00109                 debug(LOG_ERR, "Could not find client for %s", r->clientAddr);
00110                 UNLOCK_CLIENT_LIST();
00111                 return;
00112         }
00113         
00114         mac = safe_strdup(client->mac);
00115         token = safe_strdup(client->token);
00116         
00117         UNLOCK_CLIENT_LIST();
00118         
00119         /* 
00120          * At this point we've released the lock while we do an HTTP request since it could
00121          * take multiple seconds to do and the gateway would effectively be frozen if we
00122          * kept the lock.
00123          */
00124         auth_server_request(&auth_response, REQUEST_TYPE_LOGIN, r->clientAddr, mac, token, 0, 0);
00125         
00126         LOCK_CLIENT_LIST();
00127         
00128         /* can't trust the client to still exist after n seconds have passed */
00129         client = client_list_find(r->clientAddr, mac);
00130         
00131         if (client == NULL) {
00132                 debug(LOG_ERR, "Could not find client node for %s (%s)", r->clientAddr, mac);
00133                 UNLOCK_CLIENT_LIST();
00134                 free(token);
00135                 free(mac);
00136                 return;
00137         }
00138         
00139         free(token);
00140         free(mac);
00141 
00142         /* Prepare some variables we'll need below */
00143         config = config_get_config();
00144         auth_server = get_auth_server();
00145 
00146         switch(auth_response.authcode) {
00147 
00148         case AUTH_ERROR:
00149                 /* Error talking to central server */
00150                 debug(LOG_ERR, "Got %d from central server authenticating token %s from %s at %s", auth_response, client->token, client->ip, client->mac);
00151                 http_wifidog_header(r, "Error!");
00152                 httpdOutput(r, "Error: We did not get a valid answer from the central server");
00153                 http_wifidog_footer(r);
00154                 break;
00155 
00156         case AUTH_DENIED:
00157                 /* Central server said invalid token */
00158                 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);
00159                 safe_asprintf(&urlFragment, "%smessage=%s",
00160                         auth_server->authserv_msg_script_path_fragment,
00161                         GATEWAY_MESSAGE_DENIED
00162                 );
00163                 http_send_redirect_to_auth(r, urlFragment, "Redirect to denied message");
00164                 free(urlFragment);
00165                 break;
00166 
00167     case AUTH_VALIDATION:
00168                 /* They just got validated for X minutes to check their email */
00169                 debug(LOG_INFO, "Got VALIDATION from central server authenticating token %s from %s at %s"
00170                                 "- adding to firewall and redirecting them to activate message", client->token,
00171                                 client->ip, client->mac);
00172                 client->fw_connection_state = FW_MARK_PROBATION;
00173                 fw_allow(client->ip, client->mac, FW_MARK_PROBATION);
00174                 safe_asprintf(&urlFragment, "%smessage=%s",
00175                         auth_server->authserv_msg_script_path_fragment,
00176                         GATEWAY_MESSAGE_ACTIVATE_ACCOUNT
00177                 );
00178                 http_send_redirect_to_auth(r, urlFragment, "Redirect to activate message");
00179                 free(urlFragment);
00180             break;
00181 
00182     case AUTH_ALLOWED:
00183                 /* Logged in successfully as a regular account */
00184                 debug(LOG_INFO, "Got ALLOWED from central server authenticating token %s from %s at %s - "
00185                                 "adding to firewall and redirecting them to portal", client->token, client->ip, client->mac);
00186                 client->fw_connection_state = FW_MARK_KNOWN;
00187                 fw_allow(client->ip, client->mac, FW_MARK_KNOWN);
00188         served_this_session++;
00189                 safe_asprintf(&urlFragment, "%sgw_id=%s",
00190                         auth_server->authserv_portal_script_path_fragment,
00191                         config->gw_id
00192                 );
00193                 http_send_redirect_to_auth(r, urlFragment, "Redirect to portal");
00194                 free(urlFragment);
00195             break;
00196 
00197     case AUTH_VALIDATION_FAILED:
00198                  /* Client had X minutes to validate account by email and didn't = too late */
00199                 debug(LOG_INFO, "Got VALIDATION_FAILED from central server authenticating token %s from %s at %s "
00200                                 "- redirecting them to failed_validation message", client->token, client->ip, client->mac);
00201                 safe_asprintf(&urlFragment, "%smessage=%s",
00202                         auth_server->authserv_msg_script_path_fragment,
00203                         GATEWAY_MESSAGE_ACCOUNT_VALIDATION_FAILED
00204                 );
00205                 http_send_redirect_to_auth(r, urlFragment, "Redirect to failed validation message");
00206                 free(urlFragment);
00207             break;
00208 
00209     default:
00210                 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);
00211                 http_wifidog_header(r, "Internal error");
00212                 httpdOutput(r, "We can not validate your request at this time");
00213                 http_wifidog_footer(r);
00214             break;
00215 
00216         }
00217 
00218         UNLOCK_CLIENT_LIST();
00219         return;
00220 }
00221 
00222 

Generated on Sun Apr 13 21:55:00 2008 for WifiDog by  doxygen 1.5.3