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

Generated on Sun Jun 24 00:29:52 2007 for WifiDog by  doxygen 1.5.1