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