00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00030 #define _GNU_SOURCE
00031
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <pthread.h>
00035 #include <string.h>
00036 #include <unistd.h>
00037 #include <syslog.h>
00038
00039 #include "httpd.h"
00040
00041 #include "safe.h"
00042 #include "debug.h"
00043 #include "conf.h"
00044 #include "auth.h"
00045 #include "firewall.h"
00046 #include "http.h"
00047 #include "httpd.h"
00048 #include "client_list.h"
00049 #include "common.h"
00050 #include "centralserver.h"
00051
00052 #include "util.h"
00053
00054 #include "../config.h"
00055
00056 extern pthread_mutex_t client_list_mutex;
00057
00059 void
00060 http_callback_404(httpd *webserver, request *r)
00061 {
00062 char *urlFragment,
00063 tmp_url[MAX_BUF],
00064 *url;
00065 s_config *config = config_get_config();
00066 t_auth_serv *auth_server = get_auth_server();
00067
00068 memset(tmp_url, 0, sizeof(tmp_url));
00069
00070
00071
00072
00073
00074 snprintf(tmp_url, (sizeof(tmp_url) - 1), "http://%s%s%s%s",
00075 r->request.host,
00076 r->request.path,
00077 r->request.query[0] ? "?" : "",
00078 r->request.query);
00079 url = httpdUrlEncode(tmp_url);
00080
00081 if (!is_online()) {
00082
00083 http_wifidog_header(r, "<h2>Uh oh! Internet access unavailable</h2>");
00084 httpdOutput(r, "<p>We apologize, but it seems that the internet connection that powers this hotspot is temporarily unavailable.</p>");
00085 httpdOutput(r, "<p>If at all possible, please notify the owners of this hotspot that the internet connection is out of service.</p>");
00086 httpdOutput(r, "<p>The maintainers of this network are aware of this disruption. We hope that this situation will be resolved soon.</p>");
00087 httpdPrintf(r, "<p>In a while please <a href='%s'>click here</a> to try your request again.</p>", tmp_url);
00088 http_wifidog_footer(r);
00089 debug(LOG_INFO, "Sent %s an apology since I am not online - no point sending them to auth server", r->clientAddr);
00090 }
00091 else if (!is_auth_online()) {
00092
00093 http_wifidog_header(r, "<h2>Uh oh! Login screen unavailable</h2>");
00094 httpdOutput(r, "<p>We apologize, but it seems that we are currently unable to re-direct you to the login screen.</p>");
00095 httpdOutput(r, "<p>The maintainers of this network are aware of this disruption. We hope that this situation will be resolved soon.</p>");
00096 httpdPrintf(r, "<p>In a couple of minutes please <a href='%s'>click here</a> to try your request again.</p>", tmp_url);
00097 http_wifidog_footer(r);
00098 debug(LOG_INFO, "Sent %s an apology since auth server not online - no point sending them to auth server", r->clientAddr);
00099 }
00100 else {
00101
00102 safe_asprintf(&urlFragment, "%sgw_address=%s&gw_port=%d&gw_id=%s&url=%s",
00103 auth_server->authserv_login_script_path_fragment,
00104 config->gw_address,
00105 config->gw_port,
00106 config->gw_id,
00107 url);
00108 debug(LOG_INFO, "Captured %s requesting [%s] and re-directing them to login page", r->clientAddr, url);
00109 http_send_redirect_to_auth(r, urlFragment, "Redirect to login page");
00110 free(urlFragment);
00111 }
00112 free(url);
00113 }
00114
00115 void
00116 http_callback_wifidog(httpd *webserver, request *r)
00117 {
00118 http_wifidog_header(r, "WiFiDog");
00119 httpdOutput(r, "Please use the menu to navigate the features of this WiFiDog installation.");
00120 http_wifidog_footer(r);
00121 }
00122
00123 void
00124 http_callback_about(httpd *webserver, request *r)
00125 {
00126 http_wifidog_header(r, "About WiFiDog");
00127 httpdOutput(r, "This is WiFiDog version <b>" VERSION "</b>");
00128 http_wifidog_footer(r);
00129 }
00130
00131 void
00132 http_callback_status(httpd *webserver, request *r)
00133 {
00134 char * status = NULL;
00135 status = get_status_text();
00136 http_wifidog_header(r, "WiFiDog Status");
00137 httpdOutput(r, "<pre>");
00138 httpdOutput(r, status);
00139 httpdOutput(r, "</pre>");
00140 http_wifidog_footer(r);
00141 free(status);
00142 }
00147 void http_send_redirect_to_auth(request *r, char *urlFragment, char *text)
00148 {
00149 char *protocol = NULL;
00150 int port = 80;
00151 t_auth_serv *auth_server = get_auth_server();
00152
00153 if (auth_server->authserv_use_ssl) {
00154 protocol = "https";
00155 port = auth_server->authserv_ssl_port;
00156 } else {
00157 protocol = "http";
00158 port = auth_server->authserv_http_port;
00159 }
00160
00161 char *url = NULL;
00162 safe_asprintf(&url, "%s://%s:%d%s%s",
00163 protocol,
00164 auth_server->authserv_hostname,
00165 port,
00166 auth_server->authserv_path,
00167 urlFragment
00168 );
00169 http_send_redirect(r, url, text);
00170 free(url);
00171 }
00172
00177 void http_send_redirect(request *r, char *url, char *text)
00178 {
00179 char *header = NULL;
00180 char *response = NULL;
00181
00182 debug(LOG_DEBUG, "Redirecting client browser to %s", url);
00183 safe_asprintf(&header, "Location: %s",
00184 url
00185 );
00186 if(text) {
00187 safe_asprintf(&response, "307 %s\n",
00188 text
00189 );
00190 }
00191 else {
00192 safe_asprintf(&response, "307 %s\n",
00193 "Redirecting"
00194 );
00195 }
00196 httpdSetResponse(r, response);
00197 httpdAddHeader(r, header);
00198 free(response);
00199 free(header);
00200 if(text) {
00201 http_wifidog_header(r, text);
00202 }
00203 else {
00204 http_wifidog_header(r, "Redirection to message");
00205 }
00206
00207 httpdPrintf(r, "Please <a href='%s'>click here</a>.",
00208 url
00209 );
00210 http_wifidog_footer(r);
00211 }
00212
00213 void
00214 http_callback_auth(httpd *webserver, request *r)
00215 {
00216 t_client *client;
00217 httpVar * token;
00218 char *mac;
00219 httpVar *logout = httpdGetVariableByName(r, "logout");
00220 if ((token = httpdGetVariableByName(r, "token"))) {
00221
00222 if (!(mac = arp_get(r->clientAddr))) {
00223
00224 debug(LOG_ERR, "Failed to retrieve MAC address for ip %s", r->clientAddr);
00225 http_wifidog_header(r, "WiFiDog Error");
00226 httpdOutput(r, "Failed to retrieve your MAC address");
00227 http_wifidog_footer(r);
00228 } else {
00229
00230
00231 LOCK_CLIENT_LIST();
00232
00233 if ((client = client_list_find(r->clientAddr, mac)) == NULL) {
00234 debug(LOG_DEBUG, "New client for %s", r->clientAddr);
00235 client_list_append(r->clientAddr, mac, token->value);
00236 } else if (logout) {
00237 t_authresponse authresponse;
00238 s_config *config = config_get_config();
00239 unsigned long long incoming = client->counters.incoming;
00240 unsigned long long outgoing = client->counters.outgoing;
00241 char *ip = safe_strdup(client->ip);
00242 char *urlFragment = NULL;
00243 t_auth_serv *auth_server = get_auth_server();
00244
00245 fw_deny(client->ip, client->mac, client->fw_connection_state);
00246 client_list_delete(client);
00247 debug(LOG_DEBUG, "Got logout from %s", client->ip);
00248
00249
00250 if (config->auth_servers != NULL) {
00251 UNLOCK_CLIENT_LIST();
00252 auth_server_request(&authresponse, REQUEST_TYPE_LOGOUT, ip, mac, token->value,
00253 incoming, outgoing);
00254 LOCK_CLIENT_LIST();
00255
00256
00257 debug(LOG_INFO, "Got manual logout from client ip %s, mac %s, token %s"
00258 "- redirecting them to logout message", client->ip, client->mac, client->token);
00259 safe_asprintf(&urlFragment, "%smessage=%s",
00260 auth_server->authserv_msg_script_path_fragment,
00261 GATEWAY_MESSAGE_ACCOUNT_LOGGED_OUT
00262 );
00263 http_send_redirect_to_auth(r, urlFragment, "Redirect to logout message");
00264 free(urlFragment);
00265 }
00266 free(ip);
00267 }
00268 else {
00269 debug(LOG_DEBUG, "Client for %s is already in the client list", client->ip);
00270 }
00271 UNLOCK_CLIENT_LIST();
00272 if (!logout) {
00273 authenticate_client(r);
00274 }
00275 free(mac);
00276 }
00277 } else {
00278
00279 http_wifidog_header(r, "WiFiDog Error");
00280 httpdOutput(r, "Invalid token");
00281 http_wifidog_footer(r);
00282 }
00283 }
00284
00285 void
00286 http_wifidog_header(request *r, char *title)
00287 {
00288 httpdOutput(r, "<html>\n");
00289 httpdOutput(r, "<head>\n");
00290 httpdPrintf(r, "<title>%s</title>\n", title);
00291 httpdOutput(r, "<meta HTTP-EQUIV='Pragma' CONTENT='no-cache'>\n");
00292
00293 httpdOutput(r, "<style>\n");
00294 httpdOutput(r, "body {\n");
00295 httpdOutput(r, " margin: 10px 60px 0 60px; \n");
00296 httpdOutput(r, " font-family : bitstream vera sans, sans-serif;\n");
00297 httpdOutput(r, " color: #46a43a;\n");
00298 httpdOutput(r, "}\n");
00299
00300 httpdOutput(r, "a {\n");
00301 httpdOutput(r, " color: #46a43a;\n");
00302 httpdOutput(r, "}\n");
00303
00304 httpdOutput(r, "a:active {\n");
00305 httpdOutput(r, " color: #46a43a;\n");
00306 httpdOutput(r, "}\n");
00307
00308 httpdOutput(r, "a:link {\n");
00309 httpdOutput(r, " color: #46a43a;\n");
00310 httpdOutput(r, "}\n");
00311
00312 httpdOutput(r, "a:visited {\n");
00313 httpdOutput(r, " color: #46a43a;\n");
00314 httpdOutput(r, "}\n");
00315
00316 httpdOutput(r, "#header {\n");
00317 httpdOutput(r, " height: 30px;\n");
00318 httpdOutput(r, " background-color: #B4F663;\n");
00319 httpdOutput(r, " padding: 20px;\n");
00320 httpdOutput(r, " font-size: 20pt;\n");
00321 httpdOutput(r, " text-align: center;\n");
00322 httpdOutput(r, " border: 2px solid #46a43a;\n");
00323 httpdOutput(r, " border-bottom: 0;\n");
00324 httpdOutput(r, "}\n");
00325
00326 httpdOutput(r, "#menu {\n");
00327 httpdOutput(r, " width: 200px;\n");
00328 httpdOutput(r, " float: right;\n");
00329 httpdOutput(r, " background-color: #B4F663;\n");
00330 httpdOutput(r, " border: 2px solid #46a43a;\n");
00331 httpdOutput(r, " font-size: 80%;\n");
00332 httpdOutput(r, " min-height: 300px;\n");
00333 httpdOutput(r, "}\n");
00334
00335 httpdOutput(r, "#menu h2 {\n");
00336 httpdOutput(r, " margin: 0;\n");
00337 httpdOutput(r, " background-color: #46a43a;\n");
00338 httpdOutput(r, " text-align: center;\n");
00339 httpdOutput(r, " color: #B4F663;\n");
00340 httpdOutput(r, "}\n");
00341
00342 httpdOutput(r, "#copyright {\n");
00343 httpdOutput(r, "}\n");
00344
00345 httpdOutput(r, "#content {\n");
00346 httpdOutput(r, " padding: 20px;\n");
00347 httpdOutput(r, " border: 2px solid #46a43a;\n");
00348 httpdOutput(r, " min-height: 300px;\n");
00349 httpdOutput(r, "}\n");
00350 httpdOutput(r, "</style>\n");
00351
00352 httpdOutput(r, "</head>\n");
00353
00354 httpdOutput(r, "<body\n");
00355
00356 httpdOutput(r, "<div id=\"header\">\n");
00357 httpdPrintf(r, " %s\n", title);
00358 httpdOutput(r, "</div>\n");
00359
00360 httpdOutput(r, "<div id=\"menu\">\n");
00361
00362
00363 httpdOutput(r, " <h2>Info</h2>\n");
00364 httpdOutput(r, " <ul>\n");
00365 httpdOutput(r, " <li>Version: " VERSION "\n");
00366 httpdPrintf(r, " <li>Node ID: %s\n", config_get_config()->gw_id);
00367 httpdOutput(r, " </ul>\n");
00368 httpdOutput(r, " <br>\n");
00369
00370 httpdOutput(r, " <h2>Menu</h2>\n");
00371 httpdOutput(r, " <ul>\n");
00372 httpdOutput(r, " <li><a href='/wifidog/status'>WiFiDog Status</a>\n");
00373 httpdOutput(r, " <li><a href='/wifidog/about'>About WiFiDog</a>\n");
00374 httpdOutput(r, " <li><a href='http://www.wifidog.org'>WiFiDog's homepage</a>\n");
00375 httpdOutput(r, " </ul>\n");
00376 httpdOutput(r, "</div>\n");
00377
00378 httpdOutput(r, "<div id=\"content\">\n");
00379 httpdPrintf(r, "<h2>%s</h2>\n", title);
00380 }
00381
00382 void
00383 http_wifidog_footer(request *r)
00384 {
00385 httpdOutput(r, "</div>\n");
00386
00387 httpdOutput(r, "<div id=\"copyright\">\n");
00388 httpdOutput(r, "Copyright (C) 2004-2005. This software is released under the GNU GPL license.\n");
00389 httpdOutput(r, "</div>\n");
00390
00391
00392 httpdOutput(r, "</body>\n");
00393 httpdOutput(r, "</html>\n");
00394 }