00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <sys/types.h>
00030 #include <sys/socket.h>
00031 #include <sys/stat.h>
00032 #include <netinet/in.h>
00033 #include <arpa/inet.h>
00034 #include <errno.h>
00035 #include <unistd.h>
00036 #include <string.h>
00037 #include <syslog.h>
00038 
00039 #include "httpd.h"
00040 
00041 #include "common.h"
00042 #include "safe.h"
00043 #include "util.h"
00044 #include "auth.h"
00045 #include "conf.h"
00046 #include "debug.h"
00047 #include "centralserver.h"
00048 #include "../config.h"
00049 
00050 extern pthread_mutex_t  config_mutex;
00051 
00061 t_authcode
00062 auth_server_request(t_authresponse *authresponse, char *request_type, char *ip, char *mac, char *token, unsigned long long int incoming, unsigned long long int outgoing)
00063 {
00064         int sockfd;
00065         size_t  numbytes, totalbytes;
00066         char buf[MAX_BUF];
00067         char *tmp;
00068 
00069         
00070         authresponse->authcode = AUTH_ERROR;
00071         
00072         sockfd = connect_auth_server();
00073         if (sockfd == -1) {
00074                 
00075                 return (AUTH_ERROR);
00076         }
00077 
00082         memset(buf, 0, sizeof(buf));
00083         snprintf(buf, (sizeof(buf) - 1), "GET %sauth/?stage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu HTTP/1.0\n"
00084                 "User-Agent: WiFiDog %s\n"
00085                 "Host: %s\n"
00086                 "\n",
00087             config_get_config()->auth_servers->authserv_path, request_type, ip, mac, token, incoming, outgoing,
00088                                 VERSION, 
00089             config_get_config()->auth_servers->authserv_hostname
00090                  );
00091 
00092         debug(LOG_DEBUG, "Sending HTTP request to auth server: [%s]\n", buf);
00093         send(sockfd, buf, strlen(buf), 0);
00094 
00095         numbytes = totalbytes = 0;
00096         while ((numbytes = read(sockfd, buf + totalbytes, MAX_BUF - (totalbytes + 1))) > 0)
00097                 totalbytes += numbytes;
00098         
00099         if (numbytes == -1) {
00100                 debug(LOG_ERR, "Error reading from auth server: %s", strerror(errno));
00101                 close(sockfd);
00102                 return(AUTH_ERROR);
00103         }
00104         close(sockfd);
00105 
00106         buf[totalbytes] = '\0';
00107         debug(LOG_DEBUG, "HTTP Response from Server: [%s]", buf);
00108         
00109         if ((tmp = strstr(buf, "Auth: "))) {
00110                 if (sscanf(tmp, "Auth: %d", (int *)&authresponse->authcode) == 1) {
00111                         debug(LOG_INFO, "Auth server returned authentication code %d", authresponse->authcode);
00112                         return(authresponse->authcode);
00113                 } else {
00114                         debug(LOG_WARNING, "Auth server did not return expected authentication code");
00115                         return(AUTH_ERROR);
00116                 }
00117         }
00118         else {
00119                 return(AUTH_ERROR);
00120         }
00121 
00122         return(AUTH_ERROR);
00123 }
00124 
00125 
00126 
00127 int connect_auth_server() {
00128         int sockfd;
00129 
00130         LOCK_CONFIG();
00131         sockfd = _connect_auth_server(0);
00132         UNLOCK_CONFIG();
00133 
00134         if (sockfd == -1) {
00135                 debug(LOG_ERR, "Failed to connect to any of the auth servers");
00136                 mark_auth_offline();
00137         }
00138         else {
00139                 debug(LOG_DEBUG, "Connected to auth server");
00140                 mark_auth_online();
00141         }
00142         return (sockfd);
00143 }
00144 
00145 
00146 
00147 
00148 int _connect_auth_server(int level) {
00149         s_config *config = config_get_config();
00150         t_auth_serv *auth_server = NULL;
00151         struct in_addr *h_addr;
00152         int num_servers = 0;
00153         char * hostname = NULL;
00154         char * popular_servers[] = {
00155                   "www.google.com"
00156                 , "www.yahoo.com"
00157                 , NULL
00158         };
00159         char ** popularserver;
00160         char * ip;
00161         struct sockaddr_in their_addr;
00162         int sockfd;
00163 
00164         level++;
00165 
00166         
00167 
00168 
00169         for (auth_server = config->auth_servers; auth_server; auth_server = auth_server->next) {
00170                 num_servers++;
00171         }
00172         debug(LOG_DEBUG, "Level %d: Calculated %d auth servers in list", level, num_servers);
00173 
00174         if (level > num_servers) {
00175                 
00176 
00177 
00178 
00179                 return (-1);
00180         }
00181 
00182         
00183 
00184 
00185         auth_server = config->auth_servers;
00186         hostname = auth_server->authserv_hostname;
00187         debug(LOG_DEBUG, "Level %d: Resolving auth server [%s]", level, hostname);
00188         h_addr = wd_gethostbyname(hostname);
00189         if (!h_addr) {
00190                 
00191 
00192 
00193 
00194 
00195                 debug(LOG_DEBUG, "Level %d: Resolving auth server [%s] failed", level, hostname);
00196 
00197                 for (popularserver = popular_servers; *popularserver; popularserver++) {
00198                         debug(LOG_DEBUG, "Level %d: Resolving popular server [%s]", level, *popularserver);
00199                         h_addr = wd_gethostbyname(*popularserver);
00200                         if (h_addr) {
00201                                 debug(LOG_DEBUG, "Level %d: Resolving popular server [%s] succeeded = [%s]", level, *popularserver, inet_ntoa(*h_addr));
00202                                 break;
00203                         }
00204                         else {
00205                                 debug(LOG_DEBUG, "Level %d: Resolving popular server [%s] failed", level, *popularserver);
00206                         }
00207                 }
00208 
00209                 if (h_addr) {
00210                         free (h_addr);
00211                         
00212 
00213 
00214 
00215 
00216                         debug(LOG_DEBUG, "Level %d: Marking auth server [%s] as bad and trying next if possible", level, hostname);
00217                         if (auth_server->last_ip) {
00218                                 free(auth_server->last_ip);
00219                                 auth_server->last_ip = NULL;
00220                         }
00221                         mark_auth_server_bad(auth_server);
00222                         return _connect_auth_server(level);
00223                 }
00224                 else {
00225                         
00226 
00227 
00228 
00229 
00230 
00231                         mark_offline();
00232                         debug(LOG_DEBUG, "Level %d: Failed to resolve auth server and all popular servers. The internet connection is probably down", level);
00233                         return(-1);
00234                 }
00235         }
00236         else {
00237                 
00238 
00239 
00240                 ip = safe_strdup(inet_ntoa(*h_addr));
00241                 debug(LOG_DEBUG, "Level %d: Resolving auth server [%s] succeeded = [%s]", level, hostname, ip);
00242 
00243                 if (!auth_server->last_ip || strcmp(auth_server->last_ip, ip) != 0) {
00244                         
00245 
00246 
00247 
00248                         debug(LOG_DEBUG, "Level %d: Updating last_ip IP of server [%s] to [%s]", level, hostname, ip);
00249                         if (auth_server->last_ip) free(auth_server->last_ip);
00250                         auth_server->last_ip = ip;
00251 
00252                         
00253                         fw_clear_authservers();
00254                         fw_set_authservers();
00255                 }
00256                 else {
00257                         
00258 
00259 
00260                         free(ip);
00261                 }
00262 
00263                 
00264 
00265 
00266                 debug(LOG_DEBUG, "Level %d: Connecting to auth server %s:%d", level, hostname, auth_server->authserv_http_port);
00267                 their_addr.sin_family = AF_INET;
00268                 their_addr.sin_port = htons(auth_server->authserv_http_port);
00269                 their_addr.sin_addr = *h_addr;
00270                 memset(&(their_addr.sin_zero), '\0', sizeof(their_addr.sin_zero));
00271                 free (h_addr);
00272 
00273                 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
00274                         debug(LOG_ERR, "Level %d: Failed to create a new SOCK_STREAM socket: %s", strerror(errno));
00275                         return(-1);
00276                 }
00277 
00278                 if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) {
00279                         
00280 
00281 
00282 
00283                         debug(LOG_DEBUG, "Level %d: Failed to connect to auth server %s:%d (%s). Marking it as bad and trying next if possible", level, hostname, auth_server->authserv_http_port, strerror(errno));
00284                         close(sockfd);
00285                         mark_auth_server_bad(auth_server);
00286                         return _connect_auth_server(level);
00287                 }
00288                 else {
00289                         
00290 
00291 
00292                         debug(LOG_DEBUG, "Level %d: Successfully connected to auth server %s:%d", level, hostname, auth_server->authserv_http_port);
00293                         return sockfd;
00294                 }
00295         }
00296 }
00297 
00298