http.c

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: http.c 1104 2006-10-09 00:58:46Z acv $ */
00027 #define _GNU_SOURCE
00028 
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <pthread.h>
00032 #include <string.h>
00033 #include <unistd.h>
00034 #include <syslog.h>
00035 
00036 #include "httpd.h"
00037 
00038 #include "safe.h"
00039 #include "debug.h"
00040 #include "conf.h"
00041 #include "auth.h"
00042 #include "firewall.h"
00043 #include "http.h"
00044 #include "httpd.h"
00045 #include "client_list.h"
00046 #include "common.h"
00047 
00048 #include "util.h"
00049 
00050 #include "../config.h"
00051 
00052 extern pthread_mutex_t  client_list_mutex;
00053 
00055 void
00056 http_callback_404(httpd *webserver, request *r)
00057 {
00058         char            *newlocation,
00059                         *protocol,
00060                         tmp_url[MAX_BUF],
00061                         *url;
00062         int             port;
00063         s_config        *config = config_get_config();
00064         t_auth_serv     *auth_server = get_auth_server();
00065 
00066         if (auth_server->authserv_use_ssl) {
00067                 protocol = "https";
00068                 port = auth_server->authserv_ssl_port;
00069         } else {
00070                 protocol = "http";
00071                 port = auth_server->authserv_http_port;
00072         }
00073 
00074         memset(tmp_url, 0, sizeof(tmp_url));
00075         /* 
00076          * XXX Note the code belows assume that the client's request is a plain
00077          * http request to a standard port. At any rate, this handler is called only
00078          * if the internet/auth server is down so it's not a huge loss, but still.
00079          */
00080         snprintf(tmp_url, (sizeof(tmp_url) - 1), "http://%s%s",
00081                         r->request.host,
00082                         r->request.path);
00083         url = httpdUrlEncode(tmp_url);
00084 
00085         if (!is_online()) {
00086                 /* The internet connection is down at the moment  - apologize and do not redirect anywhere */
00087                 http_wifidog_header(r, "<h2>Uh oh! Internet access unavailable</h2>");
00088                 httpdOutput(r, "<p>We apologize, but it seems that the internet connection that powers this hotspot is temporarily unavailable.</p>");
00089                 httpdOutput(r, "<p>If at all possible, please notify the owners of this hotspot that the internet connection is out of service.</p>");
00090                 httpdOutput(r, "<p>The maintainers of this network are aware of this disruption.  We hope that this situation will be resolved soon.</p>");
00091                 httpdPrintf(r, "<p>In a while please <a href='%s'>click here</a> to try your request again.</p>", tmp_url);
00092                 http_wifidog_footer(r);
00093                 debug(LOG_INFO, "Sent %s an apology since I am not online - no point sending them to auth server", r->clientAddr);
00094         }
00095         else if (!is_auth_online()) {
00096                 /* The auth server is down at the moment - apologize and do not redirect anywhere */
00097                 http_wifidog_header(r, "<h2>Uh oh! Login screen unavailable</h2>");
00098                 httpdOutput(r, "<p>We apologize, but it seems that we are currently unable to re-direct you to the login screen.</p>");
00099                 httpdOutput(r, "<p>The maintainers of this network are aware of this disruption.  We hope that this situation will be resolved soon.</p>");
00100                 httpdPrintf(r, "<p>In a couple of minutes please <a href='%s'>click here</a> to try your request again.</p>", tmp_url);
00101                 http_wifidog_footer(r);
00102                 debug(LOG_INFO, "Sent %s an apology since auth server not online - no point sending them to auth server", r->clientAddr);
00103         }
00104         else {
00105                 /* Re-direct them to auth server */
00106                 safe_asprintf(&newlocation, "Location: %s://%s:%d%slogin?gw_address=%s&gw_port=%d&gw_id=%s&url=%s",
00107                         protocol,
00108                         auth_server->authserv_hostname,
00109                         port,
00110                         auth_server->authserv_path,
00111                         config->gw_address,
00112                         config->gw_port, 
00113                         config->gw_id,
00114                         url);
00115                 httpdSetResponse(r, "307 Please authenticate yourself here\n");
00116                 httpdAddHeader(r, newlocation);
00117                 http_wifidog_header(r, "Redirection");
00118                 httpdPrintf(r, "Please <a href='%s://%s:%d%slogin?gw_address=%s&gw_port=%d&gw_id=%s&url=%s'>click here</a> to login",
00119                                 protocol,
00120                                 auth_server->authserv_hostname,
00121                                 port,
00122                                 auth_server->authserv_path,
00123                                 config->gw_address, 
00124                                 config->gw_port,
00125                                 config->gw_id,
00126                                 url);
00127                 http_wifidog_footer(r);
00128                 debug(LOG_INFO, "Captured %s requesting [%s] and re-directed them to login page", r->clientAddr, url);
00129                 free(newlocation);
00130         }
00131 
00132         free(url);
00133 }
00134 
00135 void 
00136 http_callback_wifidog(httpd *webserver, request *r)
00137 {
00138         http_wifidog_header(r, "WiFiDog");
00139         httpdOutput(r, "Please use the menu to navigate the features of this WiFiDog installation.");
00140         http_wifidog_footer(r);
00141 }
00142 
00143 void 
00144 http_callback_about(httpd *webserver, request *r)
00145 {
00146         http_wifidog_header(r, "About WiFiDog");
00147         httpdOutput(r, "This is WiFiDog version <b>" VERSION "</b>");
00148         http_wifidog_footer(r);
00149 }
00150 
00151 void 
00152 http_callback_status(httpd *webserver, request *r)
00153 {
00154         char * status = NULL;
00155         status = get_status_text();
00156         http_wifidog_header(r, "WiFiDog Status");
00157         httpdOutput(r, "<pre>");
00158         httpdOutput(r, status);
00159         httpdOutput(r, "</pre>");
00160         http_wifidog_footer(r);
00161         free(status);
00162 }
00163 
00164 void 
00165 http_callback_auth(httpd *webserver, request *r)
00166 {
00167         t_client        *client;
00168         httpVar * token;
00169         char    *mac;
00170 
00171         if ((token = httpdGetVariableByName(r, "token"))) {
00172                 /* They supplied variable "token" */
00173                 if (!(mac = arp_get(r->clientAddr))) {
00174                         /* We could not get their MAC address */
00175                         debug(LOG_ERR, "Failed to retrieve MAC address for ip %s", r->clientAddr);
00176                         http_wifidog_header(r, "WiFiDog Error");
00177                         httpdOutput(r, "Failed to retrieve your MAC address");
00178                         http_wifidog_footer(r);
00179                 } else {
00180                         /* We have their MAC address */
00181 
00182                         LOCK_CLIENT_LIST();
00183                         
00184                         if ((client = client_list_find(r->clientAddr, mac)) == NULL) {
00185                                 debug(LOG_DEBUG, "New client for %s", r->clientAddr);
00186                                 client_list_append(r->clientAddr, mac, token->value);
00187                         } else {
00188                                 debug(LOG_DEBUG, "Node for %s already exists", client->ip);
00189                         }
00190 
00191                         UNLOCK_CLIENT_LIST();
00192 
00193                         authenticate_client(r);
00194                         free(mac);
00195                 }
00196         } else {
00197                 /* They did not supply variable "token" */
00198                 http_wifidog_header(r, "WiFiDog Error");
00199                 httpdOutput(r, "Invalid token");
00200                 http_wifidog_footer(r);
00201         }
00202 }
00203 
00204 void
00205 http_wifidog_header(request *r, char *title)
00206 {
00207     httpdOutput(r, "<html>\n");
00208     httpdOutput(r, "<head>\n");
00209     httpdPrintf(r, "<title>%s</title>\n", title);
00210     httpdOutput(r, "<meta HTTP-EQUIV='Pragma' CONTENT='no-cache'>\n");
00211 
00212     httpdOutput(r, "<style>\n");
00213     httpdOutput(r, "body {\n");
00214     httpdOutput(r, "  margin: 10px 60px 0 60px; \n");
00215     httpdOutput(r, "  font-family : bitstream vera sans, sans-serif;\n");
00216     httpdOutput(r, "  color: #46a43a;\n");
00217     httpdOutput(r, "}\n");
00218 
00219     httpdOutput(r, "a {\n");
00220     httpdOutput(r, "  color: #46a43a;\n");
00221     httpdOutput(r, "}\n");
00222 
00223     httpdOutput(r, "a:active {\n");
00224     httpdOutput(r, "  color: #46a43a;\n");
00225     httpdOutput(r, "}\n");
00226 
00227     httpdOutput(r, "a:link {\n");
00228     httpdOutput(r, "  color: #46a43a;\n");
00229     httpdOutput(r, "}\n");
00230 
00231     httpdOutput(r, "a:visited {\n");
00232     httpdOutput(r, "  color: #46a43a;\n");
00233     httpdOutput(r, "}\n");
00234 
00235     httpdOutput(r, "#header {\n");
00236     httpdOutput(r, "  height: 30px;\n");
00237     httpdOutput(r, "  background-color: #B4F663;\n");
00238     httpdOutput(r, "  padding: 20px;\n");
00239     httpdOutput(r, "  font-size: 20pt;\n");
00240     httpdOutput(r, "  text-align: center;\n");
00241     httpdOutput(r, "  border: 2px solid #46a43a;\n");
00242     httpdOutput(r, "  border-bottom: 0;\n");
00243     httpdOutput(r, "}\n");
00244 
00245     httpdOutput(r, "#menu {\n");
00246     httpdOutput(r, "  width: 200px;\n");
00247     httpdOutput(r, "  float: right;\n");
00248     httpdOutput(r, "  background-color: #B4F663;\n");
00249     httpdOutput(r, "  border: 2px solid #46a43a;\n");
00250     httpdOutput(r, "  font-size: 80%;\n");
00251     httpdOutput(r, "  min-height: 300px;\n");
00252     httpdOutput(r, "}\n");
00253 
00254     httpdOutput(r, "#menu h2 {\n");
00255     httpdOutput(r, "  margin: 0;\n");
00256     httpdOutput(r, "  background-color: #46a43a;\n");
00257     httpdOutput(r, "  text-align: center;\n");
00258     httpdOutput(r, "  color: #B4F663;\n");
00259     httpdOutput(r, "}\n");
00260 
00261     httpdOutput(r, "#copyright {\n");
00262     httpdOutput(r, "}\n");
00263 
00264     httpdOutput(r, "#content {\n");
00265     httpdOutput(r, "  padding: 20px;\n");
00266     httpdOutput(r, "  border: 2px solid #46a43a;\n");
00267     httpdOutput(r, "  min-height: 300px;\n");
00268     httpdOutput(r, "}\n");
00269     httpdOutput(r, "</style>\n");
00270 
00271     httpdOutput(r, "</head>\n");
00272 
00273     httpdOutput(r, "<body\n");
00274 
00275     httpdOutput(r, "<div id=\"header\">\n");
00276     httpdPrintf(r, "    %s\n", title);
00277     httpdOutput(r, "</div>\n");
00278 
00279     httpdOutput(r, "<div id=\"menu\">\n");
00280 
00281 
00282     httpdOutput(r, "    <h2>Info</h2>\n");
00283     httpdOutput(r, "    <ul>\n");
00284     httpdOutput(r, "    <li>Version: " VERSION "\n");
00285     httpdPrintf(r, "    <li>Node ID: %s\n", config_get_config()->gw_id);
00286     httpdOutput(r, "    </ul>\n");
00287     httpdOutput(r, "    <br>\n");
00288 
00289     httpdOutput(r, "    <h2>Menu</h2>\n");
00290     httpdOutput(r, "    <ul>\n");
00291     httpdOutput(r, "    <li><a href='/wifidog/status'>WiFiDog Status</a>\n");
00292     httpdOutput(r, "    <li><a href='/wifidog/about'>About WiFiDog</a>\n");
00293     httpdOutput(r, "    <li><a href='http://www.wifidog.org'>WiFiDog's homepage</a>\n");
00294     httpdOutput(r, "    </ul>\n");
00295     httpdOutput(r, "</div>\n");
00296 
00297     httpdOutput(r, "<div id=\"content\">\n");
00298     httpdPrintf(r, "<h2>%s</h2>\n", title);
00299 }
00300 
00301 void
00302 http_wifidog_footer(request *r)
00303 {
00304         httpdOutput(r, "</div>\n");
00305 
00306     httpdOutput(r, "<div id=\"copyright\">\n");
00307     httpdOutput(r, "Copyright (C) 2004-2005.  This software is released under the GNU GPL license.\n");
00308     httpdOutput(r, "</div>\n");
00309 
00310 
00311         httpdOutput(r, "</body>\n");
00312         httpdOutput(r, "</html>\n");
00313 }

Generated on Sat Jan 6 18:51:44 2007 for WifiDog by  doxygen 1.5.1