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 int done, nfds;
00069 fd_set readfds;
00070 struct timeval timeout;
00071
00072
00073 authresponse->authcode = AUTH_ERROR;
00074
00075 sockfd = connect_auth_server();
00076 if (sockfd == -1) {
00077
00078 return (AUTH_ERROR);
00079 }
00080
00085 memset(buf, 0, sizeof(buf));
00086 snprintf(buf, (sizeof(buf) - 1), "GET %sauth/?stage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu HTTP/1.0\r\n"
00087 "User-Agent: WiFiDog %s\r\n"
00088 "Host: %s\r\n"
00089 "\r\n",
00090 config_get_config()->auth_servers->authserv_path, request_type, ip, mac, token, incoming, outgoing,
00091 VERSION,
00092 config_get_config()->auth_servers->authserv_hostname
00093 );
00094
00095 debug(LOG_DEBUG, "Sending HTTP request to auth server: [%s]\n", buf);
00096 send(sockfd, buf, strlen(buf), 0);
00097
00098 debug(LOG_DEBUG, "Reading response");
00099 numbytes = totalbytes = 0;
00100 done = 0;
00101 do {
00102 FD_ZERO(&readfds);
00103 FD_SET(sockfd, &readfds);
00104 timeout.tv_sec = 30;
00105 timeout.tv_usec = 0;
00106 nfds = sockfd + 1;
00107
00108 nfds = select(nfds, &readfds, NULL, NULL, &timeout);
00109
00110 if (nfds > 0) {
00113 numbytes = read(sockfd, buf + totalbytes, MAX_BUF - (totalbytes + 1));
00114 if (numbytes < 0) {
00115 debug(LOG_ERR, "An error occurred while reading from auth server: %s", strerror(errno));
00116
00117 close(sockfd);
00118 return (AUTH_ERROR);
00119 }
00120 else if (numbytes == 0) {
00121 done = 1;
00122 }
00123 else {
00124 totalbytes += numbytes;
00125 debug(LOG_DEBUG, "Read %d bytes, total now %d", numbytes, totalbytes);
00126 }
00127 }
00128 else if (nfds == 0) {
00129 debug(LOG_ERR, "Timed out reading data via select() from auth server");
00130
00131 close(sockfd);
00132 return (AUTH_ERROR);
00133 }
00134 else if (nfds < 0) {
00135 debug(LOG_ERR, "Error reading data via select() from auth server: %s", strerror(errno));
00136
00137 close(sockfd);
00138 return (AUTH_ERROR);
00139 }
00140 } while (!done);
00141
00142 close(sockfd);
00143
00144 buf[totalbytes] = '\0';
00145 debug(LOG_DEBUG, "HTTP Response from Server: [%s]", buf);
00146
00147 if ((tmp = strstr(buf, "Auth: "))) {
00148 if (sscanf(tmp, "Auth: %d", (int *)&authresponse->authcode) == 1) {
00149 debug(LOG_INFO, "Auth server returned authentication code %d", authresponse->authcode);
00150 return(authresponse->authcode);
00151 } else {
00152 debug(LOG_WARNING, "Auth server did not return expected authentication code");
00153 return(AUTH_ERROR);
00154 }
00155 }
00156 else {
00157 return(AUTH_ERROR);
00158 }
00159
00160 return(AUTH_ERROR);
00161 }
00162
00163
00164
00165 int connect_auth_server() {
00166 int sockfd;
00167
00168 LOCK_CONFIG();
00169 sockfd = _connect_auth_server(0);
00170 UNLOCK_CONFIG();
00171
00172 if (sockfd == -1) {
00173 debug(LOG_ERR, "Failed to connect to any of the auth servers");
00174 mark_auth_offline();
00175 }
00176 else {
00177 debug(LOG_DEBUG, "Connected to auth server");
00178 mark_auth_online();
00179 }
00180 return (sockfd);
00181 }
00182
00183
00184
00185
00186 int _connect_auth_server(int level) {
00187 s_config *config = config_get_config();
00188 t_auth_serv *auth_server = NULL;
00189 struct in_addr *h_addr;
00190 int num_servers = 0;
00191 char * hostname = NULL;
00192 char * popular_servers[] = {
00193 "www.google.com"
00194 , "www.yahoo.com"
00195 , NULL
00196 };
00197 char ** popularserver;
00198 char * ip;
00199 struct sockaddr_in their_addr;
00200 int sockfd;
00201
00202 level++;
00203
00204
00205
00206
00207 for (auth_server = config->auth_servers; auth_server; auth_server = auth_server->next) {
00208 num_servers++;
00209 }
00210 debug(LOG_DEBUG, "Level %d: Calculated %d auth servers in list", level, num_servers);
00211
00212 if (level > num_servers) {
00213
00214
00215
00216
00217 return (-1);
00218 }
00219
00220
00221
00222
00223 auth_server = config->auth_servers;
00224 hostname = auth_server->authserv_hostname;
00225 debug(LOG_DEBUG, "Level %d: Resolving auth server [%s]", level, hostname);
00226 h_addr = wd_gethostbyname(hostname);
00227 if (!h_addr) {
00228
00229
00230
00231
00232
00233 debug(LOG_DEBUG, "Level %d: Resolving auth server [%s] failed", level, hostname);
00234
00235 for (popularserver = popular_servers; *popularserver; popularserver++) {
00236 debug(LOG_DEBUG, "Level %d: Resolving popular server [%s]", level, *popularserver);
00237 h_addr = wd_gethostbyname(*popularserver);
00238 if (h_addr) {
00239 debug(LOG_DEBUG, "Level %d: Resolving popular server [%s] succeeded = [%s]", level, *popularserver, inet_ntoa(*h_addr));
00240 break;
00241 }
00242 else {
00243 debug(LOG_DEBUG, "Level %d: Resolving popular server [%s] failed", level, *popularserver);
00244 }
00245 }
00246
00247 if (h_addr) {
00248 free (h_addr);
00249
00250
00251
00252
00253
00254 debug(LOG_DEBUG, "Level %d: Marking auth server [%s] as bad and trying next if possible", level, hostname);
00255 if (auth_server->last_ip) {
00256 free(auth_server->last_ip);
00257 auth_server->last_ip = NULL;
00258 }
00259 mark_auth_server_bad(auth_server);
00260 return _connect_auth_server(level);
00261 }
00262 else {
00263
00264
00265
00266
00267
00268
00269 mark_offline();
00270 debug(LOG_DEBUG, "Level %d: Failed to resolve auth server and all popular servers. The internet connection is probably down", level);
00271 return(-1);
00272 }
00273 }
00274 else {
00275
00276
00277
00278 ip = safe_strdup(inet_ntoa(*h_addr));
00279 debug(LOG_DEBUG, "Level %d: Resolving auth server [%s] succeeded = [%s]", level, hostname, ip);
00280
00281 if (!auth_server->last_ip || strcmp(auth_server->last_ip, ip) != 0) {
00282
00283
00284
00285
00286 debug(LOG_DEBUG, "Level %d: Updating last_ip IP of server [%s] to [%s]", level, hostname, ip);
00287 if (auth_server->last_ip) free(auth_server->last_ip);
00288 auth_server->last_ip = ip;
00289
00290
00291 fw_clear_authservers();
00292 fw_set_authservers();
00293 }
00294 else {
00295
00296
00297
00298 free(ip);
00299 }
00300
00301
00302
00303
00304 debug(LOG_DEBUG, "Level %d: Connecting to auth server %s:%d", level, hostname, auth_server->authserv_http_port);
00305 their_addr.sin_family = AF_INET;
00306 their_addr.sin_port = htons(auth_server->authserv_http_port);
00307 their_addr.sin_addr = *h_addr;
00308 memset(&(their_addr.sin_zero), '\0', sizeof(their_addr.sin_zero));
00309 free (h_addr);
00310
00311 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
00312 debug(LOG_ERR, "Level %d: Failed to create a new SOCK_STREAM socket: %s", strerror(errno));
00313 return(-1);
00314 }
00315
00316 if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) {
00317
00318
00319
00320
00321 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));
00322 close(sockfd);
00323 mark_auth_server_bad(auth_server);
00324 return _connect_auth_server(level);
00325 }
00326 else {
00327
00328
00329
00330 debug(LOG_DEBUG, "Level %d: Successfully connected to auth server %s:%d", level, hostname, auth_server->authserv_http_port);
00331 return sockfd;
00332 }
00333 }
00334 }