]> git.gsnw.org Git - m0n0chwall.git/commitdiff
Import m0n0wall 1.21 files.
authormkasper <mkasper@e36fee2c-cc09-0410-a7cc-ebac5c6737de>
Sun, 8 Jan 2006 10:41:49 +0000 (10:41 +0000)
committermkasper <mkasper@e36fee2c-cc09-0410-a7cc-ebac5c6737de>
Sun, 8 Jan 2006 10:41:49 +0000 (10:41 +0000)
git-svn-id: https://svn.m0n0.ch/wall/trunk@27 e36fee2c-cc09-0410-a7cc-ebac5c6737de

114 files changed:
captiveportal/index.php
captiveportal/radius_accounting.inc
captiveportal/radius_authentication.inc
etc/rc.firmware
phpconf/config.xml
phpconf/inc/captiveportal.inc
phpconf/inc/config.inc
phpconf/inc/filter.inc
phpconf/inc/functions.inc
phpconf/inc/globals.inc
phpconf/inc/interfaces.inc
phpconf/inc/pear.inc [new file with mode: 0644]
phpconf/inc/radius.inc [new file with mode: 0644]
phpconf/inc/services.inc
phpconf/inc/shaper.inc
phpconf/inc/system.inc
phpconf/inc/util.inc
phpconf/inc/vpn.inc
phpconf/inc/xmlparse.inc
phpconf/rc.banner
phpconf/rc.bootup
phpconf/rc.cleanreboot [new file with mode: 0644]
phpconf/rc.initial.defaults
phpconf/rc.initial.password
phpconf/rc.initial.ping
phpconf/rc.initial.reboot
phpconf/rc.initial.setlanip
phpconf/rc.initial.setports
phpconf/rc.newwanip
phpconf/rc.prunecaptiveportal
webgui/diag_backup.php
webgui/diag_defaults.php
webgui/diag_ipfstat.php
webgui/diag_ipsec_sad.php
webgui/diag_ipsec_spd.php
webgui/diag_logs.php
webgui/diag_logs_dhcp.php
webgui/diag_logs_filter.php
webgui/diag_logs_portal.php
webgui/diag_logs_settings.php
webgui/diag_logs_vpn.php
webgui/diag_ping.php
webgui/diag_resetstate.php
webgui/diag_traceroute.php
webgui/exec_raw.php
webgui/fend.inc
webgui/firewall_aliases.php
webgui/firewall_aliases_edit.php
webgui/firewall_nat.php
webgui/firewall_nat_1to1.php
webgui/firewall_nat_1to1_edit.php
webgui/firewall_nat_edit.php
webgui/firewall_nat_out.php
webgui/firewall_nat_out_edit.php
webgui/firewall_nat_server.php
webgui/firewall_nat_server_edit.php
webgui/firewall_rules.php
webgui/firewall_rules_edit.php
webgui/firewall_shaper.php
webgui/firewall_shaper_edit.php
webgui/firewall_shaper_pipes.php
webgui/firewall_shaper_pipes_edit.php
webgui/firewall_shaper_queues.php
webgui/firewall_shaper_queues_edit.php
webgui/graph.php
webgui/graph_cpu.php
webgui/gui.css
webgui/guiconfig.inc
webgui/index.php
webgui/interfaces_assign.php
webgui/interfaces_lan.php
webgui/interfaces_opt.php
webgui/interfaces_vlan.php
webgui/interfaces_vlan_edit.php
webgui/interfaces_wan.php
webgui/interfaces_wlan.inc
webgui/license.php
webgui/reboot.php
webgui/services_captiveportal.php
webgui/services_captiveportal_filemanager.php [new file with mode: 0644]
webgui/services_captiveportal_ip.php
webgui/services_captiveportal_mac.php
webgui/services_captiveportal_users.php
webgui/services_captiveportal_users_edit.php
webgui/services_dhcp.php
webgui/services_dhcp_edit.php
webgui/services_dnsmasq_domainoverride_edit.php
webgui/services_dyndns.php
webgui/services_proxyarp.php
webgui/services_proxyarp_edit.php
webgui/services_snmp.php
webgui/services_wol.php
webgui/services_wol_edit.php
webgui/status_captiveportal.php
webgui/status_graph.php
webgui/status_graph_cpu.php
webgui/status_interfaces.php
webgui/status_wireless.php
webgui/system.php
webgui/system_advanced.php
webgui/system_firmware.php
webgui/system_routes.php
webgui/system_routes_edit.php
webgui/uploadconfig.php
webgui/vpn_ipsec.php
webgui/vpn_ipsec_ca.php
webgui/vpn_ipsec_ca_edit.php
webgui/vpn_ipsec_edit.php
webgui/vpn_ipsec_keys.php
webgui/vpn_ipsec_keys_edit.php
webgui/vpn_ipsec_mobile.php
webgui/vpn_pptp.php
webgui/vpn_pptp_users.php
webgui/vpn_pptp_users_edit.php

index a6a35813d824247f4b93c24fb839d3cf561dbfe1..daa2b16731824e9bef5aed1a30e9f09095401551 100644 (file)
@@ -4,7 +4,7 @@
        index.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
        POSSIBILITY OF SUCH DAMAGE.
 */
 
-require("globals.inc");
-require("util.inc");
-require("config.inc");
-require("radius_authentication.inc");
-require("radius_accounting.inc");
+require_once("functions.inc");
+require_once("radius_authentication.inc");
+require_once("radius_accounting.inc");
 
 header("Expires: 0");
 header("Cache-Control: no-store, no-cache, must-revalidate");
@@ -42,7 +40,6 @@ header("Pragma: no-cache");
 
 $orig_host = $_ENV['HTTP_HOST'];
 $orig_request = $_ENV['CAPTIVE_REQPATH'];
-$lockfile = "{$g['varrun_path']}/captiveportal.lock";
 $clientip = $_ENV['REMOTE_ADDR'];
 
 if (!$clientip) {
@@ -50,45 +47,87 @@ if (!$clientip) {
        exit;
 }
 
+if (isset($config['captiveportal']['httpslogin']))
+       $ourhostname = $config['captiveportal']['httpsname'] . ":8001";
+else
+       $ourhostname = $config['interfaces'][$config['captiveportal']['interface']]['ipaddr'] . ":8000";
+
+if ($orig_host != $ourhostname) {
+       /* the client thinks it's connected to the desired web server, but instead
+          it's connected to us. Issue a redirect... */
+         
+       if (isset($config['captiveportal']['httpslogin']))
+               header("Location: https://{$ourhostname}/?redirurl=" . urlencode("http://{$orig_host}{$orig_request}"));
+       else
+               header("Location: http://{$ourhostname}/?redirurl=" . urlencode("http://{$orig_host}{$orig_request}"));
+       
+       exit;
+}
+
+if (preg_match("/redirurl=(.*)/", $orig_request, $matches))
+       $redirurl = urldecode($matches[1]);
+if ($_POST['redirurl'])
+       $redirurl = $_POST['redirurl'];
+
+$macfilter = !isset($config['captiveportal']['nomacfilter']);
+
+if (file_exists("{$g['vardb_path']}/captiveportal_radius.db")) {
+       $radius_enable = TRUE;
+       if ($radius_enable && $macfilter && isset($config['captiveportal']['radmac_enable']))
+               $radmac_enable = TRUE;
+}
+
 /* find MAC address for client */
 $clientmac = arp_get_mac_by_ip($clientip);
-if (!$clientmac && !isset($config['captiveportal']['nomacfilter'])) {
+if (!$clientmac && $macfilter) {
        /* unable to find MAC address - shouldn't happen! - bail out */
+       captiveportal_logportalauth("unauthenticated","noclientmac",$clientip,"ERROR");
        exit;
 }
 
-if ($clientmac && portal_mac_fixed($clientmac)) {
+if ($_POST['logout_id']) {
+       disconnect_client($_POST['logout_id']);
+       echo <<<EOD
+<HTML>
+<HEAD><TITLE>Disconnecting...</TITLE></HEAD>
+<BODY BGCOLOR="#435370">
+<SPAN STYLE="color: #ffffff; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px;">
+<B>You've been disconnected.</B>
+</SPAN>
+<SCRIPT LANGUAGE="JavaScript">
+<!--
+setTimeout('window.close();',5000) ;
+-->
+</SCRIPT>
+</BODY>
+</HTML>
+
+EOD;
+} else if ($clientmac && $macfilter && portal_mac_fixed($clientmac)) {
        /* punch hole in ipfw for pass thru mac addresses */
        portal_allow($clientip, $clientmac, "unauthenticated");
+       exit;
 
-} else if ($_POST['accept'] && file_exists("{$g['vardb_path']}/captiveportal_radius.db")) {
+} else if ($clientmac && $radmac_enable && portal_mac_radius($clientmac,$clientip)) {
+       /* radius functions handle everything so we exit here since we're done */
+       exit;
+
+} else if ($_POST['accept'] && $radius_enable) {
 
-       /* authenticate against radius server */
-       $radiusservers = captiveportal_get_radius_servers();
-       
        if ($_POST['auth_user'] && $_POST['auth_pass']) {
-               $auth_val = RADIUS_AUTHENTICATION($_POST['auth_user'],
-                                                                                 $_POST['auth_pass'],
-                                                                                 $radiusservers[0]['ipaddr'],
-                                                                                 $radiusservers[0]['port'],
-                                                                                 $radiusservers[0]['key']);
-               if ($auth_val == 2) {
-                       captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"LOGIN");
-                       $sessionid = portal_allow($clientip, $clientmac, $_POST['auth_user'], $_POST['auth_pass']);
-                       if (isset($config['captiveportal']['radacct_enable']) && isset($radiusservers[0])) {
-                               $auth_val = RADIUS_ACCOUNTING_START($_POST['auth_user'],
-                                                                                                       $sessionid,
-                                                                                                       $radiusservers[0]['ipaddr'],
-                                                                                                       $radiusservers[0]['acctport'],
-                                                                                                       $radiusservers[0]['key'],
-                                                                                                       $clientip);
-                       }
-               } else {
-                       captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"FAILURE");
-                       readfile("{$g['varetc_path']}/captiveportal-error.html");
+               $auth_list = radius($_POST['auth_user'],$_POST['auth_pass'],$clientip,$clientmac,"USER LOGIN");
+
+               if ($auth_list['auth_val'] == 1) {
+                       captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"ERROR",$auth_list['error']);
+                       portal_reply_page($redirurl, "error", $auth_list['error']);
+               }
+               else if ($auth_list['auth_val'] == 3) {
+                       captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"FAILURE",$auth_list['reply_message']);
+                       portal_reply_page($redirurl, "error", $auth_list['reply_message']);
                }
        } else {
-               readfile("{$g['varetc_path']}/captiveportal-error.html");
+               captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"ERROR");
+               portal_reply_page($redirurl, "error");
        }
        
 } else if ($_POST['accept'] && $config['captiveportal']['auth_method'] == "local") {
@@ -122,55 +161,41 @@ if ($clientmac && portal_mac_fixed($clientmac)) {
 
        if ($loginok){
                captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"LOGIN");
-               portal_allow($clientip, $clientmac,$_POST['auth_user'],0,0);
+               portal_allow($clientip, $clientmac,$_POST['auth_user']);
        } else {
                captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"FAILURE");
-               readfile("{$g['varetc_path']}/captiveportal-error.html");
+               portal_reply_page($redirurl, "error");
        }
 } else if ($_POST['accept'] && $clientip) {
        portal_allow($clientip, $clientmac, "unauthenticated");
-} else if ($_POST['logout_id']) {
-       disconnect_client($_POST['logout_id']);
-       echo <<<EOD
-<HTML>
-<HEAD><TITLE>Disconnecting...</TITLE></HEAD>
-<BODY BGCOLOR="#435370">
-<SPAN STYLE="color: #ffffff; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px;">
-<B>You've been disconnected.</B>
-</SPAN>
-<SCRIPT LANGUAGE="JavaScript">
-<!--
-setTimeout('window.close();',5000) ;
--->
-</SCRIPT>
-</BODY>
-</HTML>
-
-EOD;
-} else if (($_ENV['SERVER_PORT'] != 8001) && isset($config['captiveportal']['httpslogin'])) {
-       /* redirect to HTTPS login page */
-       header("Location: https://{$config['captiveportal']['httpsname']}:8001/?redirurl=" . urlencode("http://{$orig_host}{$orig_request}"));
 } else {
        /* display captive portal page */
-       $htmltext = file_get_contents("{$g['varetc_path']}/captiveportal.html");
-       
-       /* substitute variables */
+       portal_reply_page($redirurl, "login");
+}
+
+exit;
+
+function portal_reply_page($redirurl, $type = null, $message = null) {
+       global $g, $config;
+
+       /* Get captive portal layout */
+       if ($type == "login") 
+               $htmltext = file_get_contents("{$g['varetc_path']}/captiveportal.html");
+       else 
+               $htmltext = file_get_contents("{$g['varetc_path']}/captiveportal-error.html");
+
+       /* substitute other variables */
        if (isset($config['captiveportal']['httpslogin']))
                $htmltext = str_replace("\$PORTAL_ACTION\$", "https://{$config['captiveportal']['httpsname']}:8001/", $htmltext);
        else
                $htmltext = str_replace("\$PORTAL_ACTION\$", "http://{$config['interfaces'][$config['captiveportal']['interface']]['ipaddr']}:8000/", $htmltext);
-       
-       if (preg_match("/redirurl=(.*)/", $orig_request, $matches))
-               $redirurl = urldecode($matches[1]);
-       else
-               $redirurl = "http://{$orig_host}{$orig_request}";
+
        $htmltext = str_replace("\$PORTAL_REDIRURL\$", htmlspecialchars($redirurl), $htmltext);
-       
+       $htmltext = str_replace("\$PORTAL_MESSAGE\$", htmlspecialchars($message), $htmltext);
+
        echo $htmltext;
 }
 
-exit;
-
 function portal_mac_fixed($clientmac) {
        global $g ;
        
@@ -192,21 +217,30 @@ function portal_mac_fixed($clientmac) {
        return FALSE ;
 }      
 
-function portal_allow($clientip,$clientmac,$clientuser,$password = "") {
+function portal_mac_radius($clientmac,$clientip) {
+       global $config ;
 
-       global $orig_host, $orig_request, $g, $config;
+       $radmac_secret = $config['captiveportal']['radmac_secret'];
 
-       /* user has accepted AUP - let him in */
-       portal_lock();
-       
-       /* get next ipfw rule number */
-       if (file_exists("{$g['vardb_path']}/captiveportal.nextrule"))
-               $ruleno = trim(file_get_contents("{$g['vardb_path']}/captiveportal.nextrule"));
-       if (!$ruleno)
-               $ruleno = 10000;        /* first rule number */
+       /* authentication against the radius server */
+       $auth_list = radius($clientmac,$radmac_secret,$clientip,$clientmac,"MACHINE LOGIN");
+       if ($auth_list['auth_val'] == 2) {
+               return TRUE;
+       }
+       return FALSE;
+}
+
+function portal_allow($clientip,$clientmac,$clientuser,$password = null, $session_timeout = null, $idle_timeout = null, $url_redirection = null, $session_terminate_time = null)  {
+
+       global $redirurl, $g, $config;
+
+       if ((isset($config['captiveportal']['noconcurrentlogins'])) && ($clientuser != 'unauthenticated'))
+               kick_concurrent_logins($clientuser);
 
-       $saved_ruleno = $ruleno;
+       captiveportal_lock();
        
+       $ruleno = get_next_ipfw_ruleno();
+
        /* generate unique session ID */
        $tod = gettimeofday();
        $sessionid = substr(md5(mt_rand() . $tod['sec'] . $tod['usec'] . $clientip . $clientmac), 0, 16);
@@ -223,18 +257,7 @@ function portal_allow($clientip,$clientmac,$clientuser,$password = "") {
        }
        
        /* read in client database */
-       $cpdb = array();
-
-       $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "r");
-       if ($fd) {
-               while (!feof($fd)) {
-                       $line = trim(fgets($fd)) ;
-                       if($line) {
-                               $cpdb[] = explode(",",$line);
-                       }       
-               }
-               fclose($fd);
-       }
+       $cpdb = captiveportal_read_db();
        
        $radiusservers = captiveportal_get_radius_servers();
 
@@ -249,7 +272,9 @@ function portal_allow($clientip,$clientmac,$clientuser,$password = "") {
                                                                           $radiusservers[0]['ipaddr'],
                                                                           $radiusservers[0]['acctport'],
                                                                           $radiusservers[0]['key'],
-                                                                          $clientip);
+                                                                          $cpdb[$i][2], // clientip
+                                                                          $cpdb[$i][3], // clientmac
+                                                                          13); // Port Preempted
                        }
                        mwexec("/sbin/ipfw delete " . $cpdb[$i][1] . " " . ($cpdb[$i][1]+10000));
                        unset($cpdb[$i]);
@@ -257,19 +282,13 @@ function portal_allow($clientip,$clientmac,$clientuser,$password = "") {
                }
        }       
 
+       /* encode password in Base64 just in case it contains commas */
+       $bpassword = base64_encode($password);
+       $cpdb[] = array(time(), $ruleno, $clientip, $clientmac, $clientuser, $sessionid, $bpassword, $session_timeout, $idle_timeout, $session_terminate_time);
+
        /* rewrite information to database */
-       $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "w");
-       if ($fd) {
-               foreach ($cpdb as $cpent) {
-                       fwrite($fd, join(",", $cpent) . "\n");
-               }
-               /* write in this new entry */
-               /* encode password in Base64 just in case it contains commas */
-               $bpassword = base64_encode($password);
-               fwrite($fd, time().",{$ruleno},{$clientip},{$clientmac},{$clientuser},{$sessionid},{$bpassword}\n") ;
-               fclose($fd);
-       }
-       
+       captiveportal_write_db($cpdb);
+
        /* write next rule number */
        $fd = @fopen("{$g['vardb_path']}/captiveportal.nextrule", "w");
        if ($fd) {
@@ -280,15 +299,15 @@ function portal_allow($clientip,$clientmac,$clientuser,$password = "") {
                fclose($fd);
        }
        
-       portal_unlock();
+       captiveportal_unlock();
        
        /* redirect user to desired destination */
-       if ($config['captiveportal']['redirurl'])
-               $redirurl = $config['captiveportal']['redirurl'];
-       else if ($_POST['redirurl'])
-               $redirurl = $_POST['redirurl'];
+       if ($url_redirection)
+               $my_redirurl = $url_redirection;
+       else if ($config['captiveportal']['redirurl'])
+               $my_redirurl = $config['captiveportal']['redirurl'];
        else
-               $redirurl = "http://{$orig_host}{$orig_request}";
+               $my_redirurl = $redirurl;
        
        if(isset($config['captiveportal']['logoutwin_enable'])) {
                
@@ -302,7 +321,7 @@ function portal_allow($clientip,$clientmac,$clientuser,$password = "") {
 <HEAD><TITLE>Redirecting...</TITLE></HEAD>
 <BODY>
 <SPAN STYLE="font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px;">
-<B>Redirecting to <A HREF="{$redirurl}">{$redirurl}</A>...</B>
+<B>Redirecting to <A HREF="{$my_redirurl}">{$my_redirurl}</A>...</B>
 </SPAN>
 <SCRIPT LANGUAGE="JavaScript">
 <!--
@@ -322,7 +341,7 @@ if (LogoutWin) {
        LogoutWin.document.close();
 }
 
-document.location.href="{$redirurl}";
+document.location.href="{$my_redirurl}";
 -->
 </SCRIPT>
 </BODY>
@@ -330,89 +349,46 @@ document.location.href="{$redirurl}";
 
 EOD;
        } else {
-               header("Location: " . $redirurl); 
+               header("Location: " . $my_redirurl); 
        }
        
        return $sessionid;
 }
 
-/* read RADIUS servers into array */
-function captiveportal_get_radius_servers() {
-       
-       global $g;
-       
-       if (file_exists("{$g['vardb_path']}/captiveportal_radius.db")) {
-               $fd = @fopen("{$g['vardb_path']}/captiveportal_radius.db","r");
-               if ($fd) {
-                       $radiusservers = array();
-                       while (!feof($fd)) {
-                               $line = trim(fgets($fd));
-                               if ($line) {
-                                       $radsrv = array();
-                                       list($radsrv['ipaddr'],$radsrv['port'],$radsrv['acctport'],$radsrv['key']) = explode(",",$line);
-                                       $radiusservers[] = $radsrv;
-                               }
-                       }
-                       fclose($fd);
-                       
-                       return $radiusservers;
-               }
-       }
-       
-       return false;
-}
+/* Ensure that only one username is used by one client at a time
+ * by Paul Taylor
+ */
+function kick_concurrent_logins($user) {
 
-/* lock captive portal information, decide that the lock file is stale after
-   10 seconds */
-function portal_lock() {
-       
-       global $lockfile;
-       
-       $n = 0;
-       while ($n < 10) {
-               /* open the lock file in append mode to avoid race condition */
-               if ($fd = @fopen($lockfile, "x")) {
-                       /* succeeded */
-                       fclose($fd);
-                       return;
-               } else {
-                       /* file locked, wait and try again */
-                       sleep(1);
-                       $n++;
+       captiveportal_lock();
+
+       /* read database */
+       $cpdb = captiveportal_read_db();
+
+       captiveportal_unlock();
+
+       if (isset($cpdb)) {
+               /* find duplicate entry */
+               for ($i = 0; $i < count($cpdb); $i++) {
+                       if ($cpdb[$i][4] == $user) {
+                               /* This user was already logged in */
+                               disconnect_client($cpdb[$i][5],"CONCURRENT LOGIN - TERMINATING OLD SESSION",13);
+                       }
                }
        }
 }
 
-/* unlock captive portal information file */
-function portal_unlock() {
-       
-       global $lockfile;
-       
-       if (file_exists($lockfile))
-               unlink($lockfile);
-}
-
 /* remove a single client by session ID
    by Dinesh Nair
  */
-function disconnect_client($sessionid) {
+function disconnect_client($sessionid, $logoutReason = "LOGOUT", $term_cause = 1) {
        
        global $g, $config;
        
-       portal_lock();
+       captiveportal_lock();
        
        /* read database */
-       $cpdb = array() ;
-       $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "r");
-       if ($fd) {
-               while (!feof($fd)) {
-                       $line = trim(fgets($fd)) ;
-                       if($line) {
-                               $cpdb[] = explode(",",$line);
-                       }       
-               }
-               fclose($fd);
-       }
+       $cpdb = captiveportal_read_db();
        
        $radiusservers = captiveportal_get_radius_servers();
        
@@ -428,35 +404,34 @@ function disconnect_client($sessionid) {
                                                                           $radiusservers[0]['ipaddr'],
                                                                           $radiusservers[0]['acctport'],
                                                                           $radiusservers[0]['key'],
-                                                                          $cpdb[$i][2]);
+                                                                          $cpdb[$i][2], // clientip
+                                                                          $cpdb[$i][3], // clientmac
+                                                                          $term_cause);
                        }
                        mwexec("/sbin/ipfw delete " . $cpdb[$i][1] . " " . ($cpdb[$i][1]+10000));
-                       captiveportal_logportalauth($cpdb[$i][4],$cpdb[$i][3],$cpdb[$i][2],"LOGOUT");
+                       captiveportal_logportalauth($cpdb[$i][4],$cpdb[$i][3],$cpdb[$i][2],$logoutReason);
                        unset($cpdb[$i]);
                        break;
                }
        }
        
        /* rewrite information to database */
-       $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "w");
-       if ($fd) {
-               foreach ($cpdb as $cpent) {
-                       fwrite($fd, join(",", $cpent) . "\n");
-               }
-               fclose($fd);
-       }
+       captiveportal_write_db($cpdb);
        
-       portal_unlock();
+       captiveportal_unlock();
 }
 
-/* log successful captive portal authentication to syslog */
-/* part of this code from php.net */
-function captiveportal_logportalauth($user,$mac,$ip,$status) {
-       define_syslog_variables();
-       openlog("logportalauth", LOG_PID, LOG_LOCAL4);
-       // Log it
-       syslog(LOG_INFO, "$status: $user, $mac, $ip");
-       closelog();
+function get_next_ipfw_ruleno() {
+
+       global $g;
+
+       /* get next ipfw rule number */
+       if (file_exists("{$g['vardb_path']}/captiveportal.nextrule"))
+               $ruleno = trim(file_get_contents("{$g['vardb_path']}/captiveportal.nextrule"));
+       if (!$ruleno)
+               $ruleno = 10000;        /* first rule number */
+
+       return $ruleno;
 }
 
 ?>
index 3459efd1a84cdead7a2fcfd38beeadfae9aca122..3003233d69e2df559e543b6728eea7003c6a9346 100644 (file)
        // - RFC2869 (Radius Extensions)
        // * now sends Acct-Input-Gigawords
        // * now sends Acct-Output-Gigawords
+       // * full implementation of nas-ip/nas_mac and called/calling-station ids
 
 */
 
-function RADIUS_ACCOUNTING_START($username,$sessionid,$radiusip,$radiusport,$radiuskey,$clientip) {
-       $sharedsecret=$radiuskey ;
+function RADIUS_ACCOUNTING_START($ruleno,$username,$sessionid,$radiusip,$radiusport,$radiuskey,$clientip,$clientmac) {
        # $debug = 1 ;
+       global $config;
 
        exec("/bin/hostname", $nasHostname) ;
        if(!$nasHostname[0])
@@ -56,13 +57,22 @@ function RADIUS_ACCOUNTING_START($username,$sessionid,$radiusip,$radiusport,$rad
        /* set 5 second timeout on socket i/o */
        stream_set_timeout($fd, 5) ;
 
-       $nas_ip_address = get_nas_ip();
+       $nas_mac = get_interface_mac($config['interfaces']['wan']['if']); // This function is defined in radius_authentication.inc
+       $nas_port = $ruleno - 10000;
+       $ip_exp=explode(".",$clientip);
+       $radiusvendor = $config['captiveportal']['radiusvendor'] ? $config['captiveportal']['radiusvendor'] : null;
+
+        switch($radiusvendor) {
 
-       if(!isset($clientip)) {
-               //if there's no client ip, we'll need to use the NAS ip
-               $clientip=$nas_ip_address;
+        case 'cisco':
+        $calledstationid = $clientmac;
+        $callingstationid = $clientip;
+        break;
+
+        default:
+       $calledstationid = $nas_mac;
+        $callingstationid = $clientmac;
        }
-       $ip_exp=explode(".",$clientip);
 
        if ($debug)
            echo "<br>radius-port: $radiusport<br>radius-host: $radiusip<br>username: $username<hr>\n";
@@ -82,21 +92,25 @@ function RADIUS_ACCOUNTING_START($username,$sessionid,$radiusip,$radiusport,$rad
                6+                              // Acct Status Type
                6+                              // Acct RADIUS Authenticated
                2+strlen($sessionid)+   // Acct SessionID
+                2+strlen($calledstationid)+              //Called-Station-ID
+                2+strlen($callingstationid)+    //Calling-Station-ID
                6;                              // Framed-IP-Address
 
        //          v   v   v     v   v   v     v     v     v     1   v
        // Line #   1   2   3     4   5   6     7     8     9     0   E
-       $data=pack("CCCCNNNNCCCCCCCCa*CCa*CCCCCCCCCCCCCCCCCCCCCCCCCCa*CCCCCC",
+       $data=pack("CCCCNNNNCCCCCCCCa*CCa*CCCCCCCCCCCCCCCCCCCCCCCCCCa*CCa*CCa*CCCCCC",
            4,$thisidentifier,$length/256,$length%256,          // header
            0,0,0,0,                                            // authcode
            6,6,0,0,0,1,                                        // service type
            1,2+strlen($username),$username,                    // username
            32,2+strlen($nasHostname[0]),$nasHostname[0],       // nasIdentifier
-           5,6,0,0,0,0,                                                // nasPort
+           5,6,0,0,0,$nas_port,                                        // nasPort
            61,6,0,0,0,15,                                              // nasPortType = Ethernet
                40,6,0,0,0,1,                                           // Acct Status Type = Start
                45,6,0,0,0,1,                                           // Acct RADIUS Authenticated
                44,2+strlen($sessionid),$sessionid,     // Acct Session ID
+                30,2+strlen($calledstationid),$calledstationid, //Called-Station-ID
+                31,2+strlen($callingstationid),$callingstationid,                               //Calling-Station-ID
                8,6,$ip_exp[0],$ip_exp[1],$ip_exp[2],$ip_exp[3] //Framed-IP-Address
            );
 
@@ -105,17 +119,19 @@ function RADIUS_ACCOUNTING_START($username,$sessionid,$radiusip,$radiusport,$rad
 
        //          v   v v     v   v   v     v     v     v     1   v
        // Line #   1   2 3     4   5   6     7     8     9     0   E
-       $data=pack("CCCCH*CCCCCCCCa*CCa*CCCCCCCCCCCCCCCCCCCCCCCCCCa*CCCCCC",
+       $data=pack("CCCCH*CCCCCCCCa*CCa*CCCCCCCCCCCCCCCCCCCCCCCCCCa*CCa*CCa*CCCCCC",
            4,$thisidentifier,$length/256,$length%256,          // header
            $RA,                                                // authcode
            6,6,0,0,0,1,                                        // service type
            1,2+strlen($username),$username,                    // username
            32,2+strlen($nasHostname[0]),$nasHostname[0],       // nasIdentifier
-           5,6,0,0,0,0,                                                // nasPort
+           5,6,0,0,0,$nas_port,                                                // nasPort
            61,6,0,0,0,15,                                              // nasPortType = Ethernet
                40,6,0,0,0,1,                                           // Acct Status Type = Start
                45,6,0,0,0,1,                                           // Acct RADIUS Authenticated
                44,2+strlen($sessionid),$sessionid,     // Acct Session ID
+                30,2+strlen($calledstationid),$calledstationid, //Called-Station-ID
+                31,2+strlen($callingstationid),$callingstationid,                               //Calling-Station-ID
                8,6,$ip_exp[0],$ip_exp[1],$ip_exp[2],$ip_exp[3] //Framed-IP-Address
            );
 
@@ -145,9 +161,11 @@ function RADIUS_ACCOUNTING_START($username,$sessionid,$radiusip,$radiusport,$rad
        // See RFC2866 for this.
 }
 
-function RADIUS_ACCOUNTING_STOP($ruleno,$username,$sessionid,$start_time,$radiusip,$radiusport,$radiuskey,$clientip,$interimupdate=false, $radius_term_cause = 1) {
-       $sharedsecret=$radiuskey ;
+function RADIUS_ACCOUNTING_STOP($ruleno,$username,$sessionid,$start_time,$radiusip,$radiusport,$radiuskey,$clientip,$clientmac, $term_cause = 1, $interimupdate=false,$stop_time = null) {
        # $debug = 1 ;
+       global $config;
+
+       $stop_time = (empty($stop_time)) ? time() : $stop_time;
 
        exec("/bin/hostname", $nasHostname) ;
        if(!$nasHostname[0])
@@ -174,13 +192,23 @@ function RADIUS_ACCOUNTING_STOP($ruleno,$username,$sessionid,$start_time,$radius
        /* set 5 second timeout on socket i/o */
        stream_set_timeout($fd, 5) ;
 
-       $nas_ip_address = get_nas_ip();
+       $nas_port = $ruleno - 10000;
+       $nas_mac = get_interface_mac($config['interfaces']['wan']['if']);
+       $ip_exp=explode(".",$clientip);
+       $session_time = $stop_time - $start_time;
+       $radiusvendor = $config['captiveportal']['radiusvendor'] ? $config['captiveportal']['radiusvendor'] : null;
+
+        switch($radiusvendor) {
 
-       if(!isset($clientip)) {
-               //if there's no client ip, we'll need to use the NAS ip
-               $clientip=$nas_ip_address;
+        case 'cisco':
+        $calledstationid = $clientmac;
+        $callingstationid = $clientip;
+        break;
+
+        default:
+        $calledstationid = $nas_mac;
+        $callingstationid = $clientmac;
        }
-       $ip_exp=explode(".",$clientip);
 
        if ($debug)
            echo "<br>radius-port: $radiusport<br>radius-host: $radiusip<br>username: $username<hr>\n";
@@ -208,9 +236,8 @@ function RADIUS_ACCOUNTING_STOP($ruleno,$username,$sessionid,$start_time,$radius
                6+                              // output bytes
                6+                              // output packets
                6+                              // output gigawords
-               2+strlen($nas_ip_address)+              //Called-Station-ID
-               2+strlen($clientip)+    //Calling-Station-ID
-
+               2+strlen($calledstationid)+             //Called-Station-ID
+               2+strlen($callingstationid)+    //Calling-Station-ID
                6;                      //Framed-IP-Address
 
        if ($interimupdate)
@@ -226,22 +253,21 @@ function RADIUS_ACCOUNTING_STOP($ruleno,$username,$sessionid,$start_time,$radius
            6,6,0,0,0,1,                                        // service type
            1,2+strlen($username),$username,                    // username
            32,2+strlen($nasHostname[0]),$nasHostname[0],       // nasIdentifier
-           5,6,0,0,0,0,                                                // nasPort
+           5,6,0,0,0,$nas_port,                                        // nasPort
            61,6,0,0,0,15,                                              // nasPortType = Ethernet
                40,6,0,0,0,$acctstatustype,                     // Acct Status Type
                45,6,0,0,0,1,                                           // Acct RADIUS Authenticated
                44,2+strlen($sessionid),$sessionid,     // Acct Session ID
-               49,6,$radius_term_cause,                // Acct Terminate = User Request
-               46,6,time() - $start_time,                      // Session Time
+               49,6,$term_cause,               // Acct Terminate
+               46,6,$session_time,                     // Session Time
                42,6,$input_bytes,      // Input Octets
                47,6,$input_pkts,       // Input Packets
                52,6,$input_gigawords,  // Input Gigawords
                43,6,$output_bytes, // Output Octets
                48,6,$output_pkts,      // Output Packets
                53,6,$output_gigawords, // Output Gigawords
-               30,2+strlen($nas_ip_address),$nas_ip_address,   //Called-Station-ID
-               31,2+strlen($clientip),$clientip,                               //Calling-Station-ID
-
+               30,2+strlen($calledstationid),$calledstationid, //Called-Station-ID
+               31,2+strlen($callingstationid),$callingstationid,                               //Calling-Station-ID
                8,6,$ip_exp[0],$ip_exp[1],$ip_exp[2],$ip_exp[3] //Framed-IP-Address
            );
 
@@ -256,22 +282,21 @@ function RADIUS_ACCOUNTING_STOP($ruleno,$username,$sessionid,$start_time,$radius
            6,6,0,0,0,1,                                        // service type
            1,2+strlen($username),$username,                    // username
            32,2+strlen($nasHostname[0]),$nasHostname[0],       // nasIdentifier
-           5,6,0,0,0,0,                                                // nasPort
+           5,6,0,0,0,$nas_port,                                        // nasPort
            61,6,0,0,0,15,                                              // nasPortType = Ethernet
                40,6,0,0,0,$acctstatustype,                     // Acct Status Type
                45,6,0,0,0,1,                                           // Acct RADIUS Authenticated
                44,2+strlen($sessionid),$sessionid,     // Acct Session ID
-               49,6,$radius_term_cause,                // Acct Terminate = User Request
-               46,6,time() - $start_time,                      // Session Time
+               49,6,$term_cause,               // Acct Terminate = User Request
+               46,6,$session_time,                     // Session Time
                42,6,$input_bytes,      // Input Octets
                47,6,$input_pkts,       // Input Packets
                52,6,$input_gigawords,  // Input Gigawords
                43,6,$output_bytes, // Output Octets
                48,6,$output_pkts,      // Output Packets
                53,6,$output_gigawords, // Output Gigawords
-               30,2+strlen($nas_ip_address),$nas_ip_address,   //Called-Station-ID
-               31,2+strlen($clientip),$clientip,                               //Calling-Station-ID
-
+               30,2+strlen($calledstationid),$calledstationid, //Called-Station-ID
+               31,2+strlen($callingstationid),$callingstationid,                               //Calling-Station-ID
                8,6,$ip_exp[0],$ip_exp[1],$ip_exp[2],$ip_exp[3] //Framed-IP-Address
            );
 
@@ -301,13 +326,6 @@ function RADIUS_ACCOUNTING_STOP($ruleno,$username,$sessionid,$start_time,$radius
        // See RFC2866 for this.
 }
 
-function get_nas_ip() {
-       global $config;
-       
-       /* static WAN IP address */
-       return $config['interfaces']['wan']['ipaddr'];
-}
-
 function gigawords($bytes) {
 
        /* We use BCMath functions since normal integers don't work with so large numbers */
index af30df176a323f08f188d58330e2bf21e876ec18..28ef14c9ed0e5e9ce2147bafef147ddfda317d82 100644 (file)
 <?php
-    //
-    // $Id: radius_authentication.inc,v 1.3 2002/01/23 23:21:20 mavetju Exp $
-    //
-    // radius authentication v1.0 by Edwin Groothuis (edwin@mavetju.org)
-    //
-    // If you didn't get this file via http://www.mavetju.org, please
-    // check for the availability of newer versions.
-    //
-    // See LICENSE for distribution issues. If this file isn't in
-    // the distribution, please inform me about it.
-    //
-    // If you want to use this script, fill in the configuration in
-    // radius_authentication.conf and call the function
-    // RADIUS_AUTHENTICATION() with the username and password
-    // provided by the user. If it returns a 2, the authentication
-    // was successfull!
-
-    // If you want to use this, make sure that you have raw sockets
-    // enabled during compile-time: "./configure --enable-sockets".
-
-       // This version has been modified by Dinesh Nair <dinesh@alphaque.com>
-       // for use in the m0n0wall distribution http://m0n0.ch/wall/
-       //
-       // Changes include moving from raw sockets to fsockopen
-       // and the removal of dependency on external conf file
-       // An existing bug which resulted in a malformed RADIUS packet
-       // was also fixed and patches submitted to Edwin. This bug would
-       // have caused authentication to fail on every access.
-
-function RADIUS_AUTHENTICATION($username,$password,$radiusip,$radiusport,$radiuskey) {
-       $sharedsecret=$radiuskey ;
-       # $debug = 1 ;
-
-       exec("/bin/hostname", $nasHostname) ;
-       if(!$nasHostname[0])
-               $nasHostname[0] = "m0n0wall" ;
-
-       $fd = @fsockopen("udp://$radiusip",$radiusport,$errno,$errstr,3) ;
-       if(!$fd) 
-               return 1 ; /* error return */
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+/*
+Copyright (c) 2005, Jonathan De Graeve <jonathan.de.graeve@imelda.be>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without 
+modification, are permitted provided that the following conditions 
+are met:
+
+1. Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in the 
+   documentation and/or other materials provided with the distribution.
+3. The names of the authors may not be used to endorse or promote products 
+   derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This code cannot simply be copied and put under the GNU Public License or 
+any other GPL-like (LGPL, GPL2) License.
+
+    This code is made possible thx to samples made by Michael Bretterklieber <michael@bretterklieber.com>
+    author of the PHP PECL Radius package
+
+    Changes made include:
+    * Support for multiple radius servers
+    * Error Message and Reply Message
+    * Called-Station-Id,Calling-Station-Id,NAS-Port,NAS-Port-Type
+    * Different Authentication Methods
+
+*/
+
+require_once("radius.inc");
+
+/*
+RADIUS AUTHENTICATION
+---------------------
+*/
+
+function RADIUS_AUTHENTICATION($username,$password,$radiusservers,$clientip,$clientmac,$ruleno) {
+       global $config;
+
+       /* Initialisation of variables - Constructor */
+       $retvalue = array();
+       $retvalue['error'] = $retvalue['reply_message'] = $retvalue['url_redirection'] = $retvalue['session_timeout'] = $retvalue['idle_timeout'] = $retvalue['session_terminate_time'] = null;
+       $nas_mac = get_interface_mac($config['interfaces']['wan']['if']);
+       $nas_port = $ruleno - 10000;
+       $radiusvendor = $config['captiveportal']['radiusvendor'] ? $config['captiveportal']['radiusvendor'] : null;
+
+    exec("/bin/hostname", $nasHostname) ;
+    if(!$nasHostname[0])
+    $nasHostname[0] = "m0n0wall" ;
+    
+$rauth = new Auth_RADIUS_PAP($username, $password);
+
+/*
+Add support for more then one radiusserver. 
+At most 10 servers may be specified. 
+When multiple servers are given, they are tried in round-robin fashion until a valid response is received 
+*/
+
+foreach ($radiusservers as $radsrv) {
+
+       // Add a new server to our instance
+       $rauth->addServer($radsrv['ipaddr'], $radsrv['port'], $radsrv['key']);
        
-       /* set 5 second timeout on socket i/o */
-       stream_set_timeout($fd, 5) ;
-
-       if ($debug)
-           echo "<br>radius-port: $radiusport<br>radius-host: $radiusip<br>username: $username<hr>\n";
-
-       $RA=pack("CCCCCCCCCCCCCCCC",                            // auth code
-           1+rand()%255, 1+rand()%255, 1+rand()%255, 1+rand()%255,
-           1+rand()%255, 1+rand()%255, 1+rand()%255, 1+rand()%255,
-           1+rand()%255, 1+rand()%255, 1+rand()%255, 1+rand()%255,
-           1+rand()%255, 1+rand()%255, 1+rand()%255, 1+rand()%255);
-
-       $encryptedpassword=Encrypt($password,$sharedsecret,$RA);
-
-       $length=4+                              // header
-               16+                             // auth code
-               6+                              // service type
-               2+strlen($username)+            // username
-               2+strlen($encryptedpassword)+   // userpassword
-               2+strlen($nasHostname[0])+                      // nasIdentifier
-               6+                              // nasPort
-               6;                              // nasPortType
-
-       $thisidentifier=rand()%256;
-       //          v   v v     v   v   v   v     v     v
-       // Line #   1   2 3     4   5   6   7     8     E
-       $data=pack("CCCCa*CCCCCCCCa*CCa*CCa*CCCCCCCCCCCC",
-           1,$thisidentifier,$length/256,$length%256,          // header
-           $RA,                                                // authcode
-           6,6,0,0,0,1,                                        // service type
-           1,2+strlen($username),$username,                    // username
-           2,2+strlen($encryptedpassword),$encryptedpassword,  // userpassword
-           32,2+strlen($nasHostname[0]),$nasHostname[0],       // nasIdentifier
-           5,6,0,0,0,0,                                                // nasPort
-           61,6,0,0,0,15                                               // nasPortType = Ethernet
-           );
-
-       if($debug) {
-               echo "username is $username with len " . strlen($username) ."\n" ;
-               echo "encryptedpassword is $encryptedpassword with len " . strlen($encryptedpassword) ."\n" ;
-               echo "nasHostname is {$nasHostname[0]} with len " . strlen($nasHostname[0]) ."\n" ;
-       }       
-
-       $ret = fwrite($fd,$data) ;
-       if( !$ret || ($ret != $length) ) 
-               return 1; /* error return */
-
-       if ($debug)
-           echo "<br>writing $length bytes<hr>\n";
-
-       $readdata = fgets($fd,2) ; /* read 1 byte */
-       $status = socket_get_status($fd) ;
-       fclose($fd) ;
-
-       if($status['timed_out'])
-               $retvalue = 1 ;
-       else
-               $retvalue = ord($readdata) ;
-
-       return $retvalue ;
+}
+
+$rauth->username = $username;
+$rauth->password = $password;
+
+
+if (!$rauth->start()) {
+    $retvalue['auth_val'] = 1;
+    $retvalue['error'] = $rauth->getError(); 
+    if ($debug)
+    printf("Radius start: %s<br>\n", $retvalue['error']);
+}
+else {
+
+       // 1 -> Access-Request => We will use this value as an error indicator since we can't get a 1 back from the radius
        // 2 -> Access-Accept
        // 3 -> Access-Reject
        // See RFC2865 for this.
-}
 
-function Encrypt($password,$key,$RA) {
-       global $debug;
+       /*
+        * We put our attributes in here
+        */
 
-       $keyRA=$key.$RA;
+       switch($radiusvendor) {
 
-       if ($debug)
-           echo "<br>key: $key<br>password: $password<hr>\n";
+        case 'cisco':
+        $rauth->putAttribute(RADIUS_CALLED_STATION_ID, $clientmac);
+        $rauth->putAttribute(RADIUS_CALLING_STATION_ID, $clientip);
+        break;
 
-       $md5checksum=md5($keyRA);
-       $output="";
+        default:
+       $rauth->putAttribute(RADIUS_CALLED_STATION_ID, $nas_mac);
+        $rauth->putAttribute(RADIUS_CALLING_STATION_ID, $clientmac);
+       }
+
+       // Default attributes
+       $rauth->putAttribute(RADIUS_NAS_PORT, $nas_port);
+
+       // Send request
+
+       $result = $rauth->send();
+       if (PEAR::isError($result)) {
+           $retvalue['auth_val'] = 1;
+           $retvalue['error'] = $result->getMessage();
+           if ($debug)
+           printf("Radius send failed: %s<br>\n", $retvalue['error']);
+       } else if ($result === true) {
+           $retvalue['auth_val'] = 2;
+           if ($debug)
+           printf("Radius Auth succeeded<br>\n");
+       } else {
+           $retvalue['auth_val'] = 3;
+           if ($debug)
+           printf("Radius Auth rejected<br>\n");
+       }
 
-       for ($i=0;$i<=15;$i++) {
-           if (2*$i>strlen($md5checksum)) $m=0; else $m=hexdec(substr($md5checksum,2*$i,2));
-           if ($i>strlen($keyRA)) $k=0; else $k=ord(substr($keyRA,$i,1));
-           if ($i>strlen($password)) $p=0; else $p=ord(substr($password,$i,1));
-           $c=$m^$p;
-           $output.=chr($c);
+       // Get attributes, even if auth failed.
+       // We will push the results in the retvalue array
+       if (!$rauth->getAttributes()) {
+           $retvalue['error'] = $rauth->getError();
+           if ($debug)
+           printf("Radius getAttributes: No attributes<br>\n", $retvalue['error']);
+       } else {
+           $retvalue = array_merge($retvalue,$rauth->listAttributes());
+           if ($debug) {
+               if (!$rauth->listAttributes())
+                   printf("No Attributes<br>\n");
+               else
+               print_r($rauth->listAttributes());
+           }
+           // We convert the session_terminate_time to unixtimestamp if its set before returning the whole array to our caller
+           if (!empty($retvalue['session_terminate_time'])) {
+               $stt = &$retvalue['session_terminate_time'];
+               $stt = strtotime(preg_replace("/\+(\d+):(\d+)$/", " +\${1}\${2}", preg_replace("/(\d+)T(\d+)/", "\${1} \${2}",$stt)));
+           }
        }
-       return $output;
+     }
+
+     // close OO RADIUS_AUTHENTICATION
+     $rauth->close();
+
+     return $retvalue;
+
 }
+
 ?>
index 2b28070c890f7866af866d1f141381690baed407..6a8fea2a7a83aa5530900371b7a2383e08136007 100644 (file)
@@ -49,7 +49,14 @@ upgrade)
        /sbin/umount -f /cf
        /sbin/mount -r /cf
 
-       echo "Done - rebooting system..."       
-       /sbin/reboot
+       echo "Done - rebooting system..."
+
+       # unset CGI environment variables so as not to confuse PHP
+       unset CONTENT_TYPE GATEWAY_INTERFACE REMOTE_USER REMOTE_ADDR AUTH_TYPE
+       unset HTTP_USER_AGENT CONTENT_LENGTH SCRIPT_FILENAME HTTP_HOST
+       unset SERVER_SOFTWARE HTTP_REFERER SERVER_PROTOCOL REQUEST_METHOD
+       unset SERVER_PORT SCRIPT_NAME SERVER_NAME
+
+       /etc/rc.cleanreboot
        ;;
 esac
index 85a1c12e3643f05465d8fdd0ec3ad28ce3109c7a..ed62beec14c3915a255e07d45dd16fa1bc6bbcb4 100644 (file)
@@ -30,6 +30,7 @@
                <!-- <earlyshellcmd></earlyshellcmd> -->
                <!-- <harddiskstandby></harddiskstandby> -->
                <!-- <polling/> -->
+               <!-- <notes></notes> -->
        </system>
        <interfaces>
                <lan>
                <syslocation></syslocation>
                <syscontact></syscontact>
                <rocommunity>public</rocommunity>
+               <!-- <bindlan/> -->
        </snmpd>
        <diag>
                <ipv6nat>
                <redirurl></redirurl>
                <auth_method>none|radius|local</auth_method>
                <radiusip></radiusip>
+               <radiusip2></radiusip2>
                <radiusport></radiusport>
+               <radiusport2></radiusport2>
                <radiuskey></radiuskey>
+               <radiuskey2></radiuskey2>
+               <radiussession_timeout></radiussession_timeout>
                <nomacfilter/>
                <reauthenticate/>
                <reauthenticateacct>stopstart|interimupdate</reauthenticateacct>
+               <maxproc></maxproc>
+               <maxprocperip></maxprocperip>
+               <croninterval></croninterval>
                
                <user>
                        <name></name>
                        <password></password>
                        <expirationdate></expirationdate>
                </user>
+               
+               <element>
+                       <name></name>
+                       <size></size>
+                       <content></content>
+               </element>
        </captiveportal>
        -->
        <nat>
index 52e878d415e164fed4760f16b4b39db83092fe01..2cbe6232a2b6ad41955052b1f9bf2dfc49779fc3 100644 (file)
@@ -3,7 +3,7 @@
        captiveportal.inc
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
@@ -37,7 +37,9 @@
 /* include all configuration functions */
 require_once("functions.inc");
 require_once("radius_authentication.inc");
-require_once("radius_accounting.inc") ;
+require_once("radius_accounting.inc");
+
+$lockfile = "{$g['varrun_path']}/captiveportal.lock";
 
 function captiveportal_configure() {
        global $config, $g;
@@ -65,6 +67,12 @@ function captiveportal_configure() {
                /* stop accounting on all clients */
                captiveportal_radius_stop_all();
 
+               /* initialize minicron interval value */
+               $croninterval = $config['captiveportal']['croninterval'] ? $config['captiveportal']['croninterval'] : 60;
+
+               /* double check if the $croninterval is numeric and at least 10 seconds. If not we set it to 60 to avoid problems */
+               if ((!is_numeric($croninterval)) || ($croninterval < 10)) { $croninterval = 60; }
+
                /* remove old information */
                unlink_if_exists("{$g['vardb_path']}/captiveportal.nextrule");
                unlink_if_exists("{$g['vardb_path']}/captiveportal.db");
@@ -129,6 +137,9 @@ EOD;
                        fwrite($fd, $errtext);
                        fclose($fd);    
                }
+               
+               /* write elements */
+               captiveportal_write_elements();
 
                /* load rules */
                mwexec("/sbin/ipfw -f delete set 1");
@@ -155,9 +166,25 @@ EOD;
                
                chdir($g['captiveportal_path']);
                
+               if ($config['captiveportal']['maxproc'])
+                       $maxproc = $config['captiveportal']['maxproc'];
+               else
+                       $maxproc = 16;
+                       
+               if (isset($config['captiveportal']['maxprocperip']) &&
+                               $config['captiveportal']['maxprocperip'] !== "") {
+                       if ($config['captiveportal']['maxprocperip'] == 0)
+                               $maxperiparg = "";
+                       else
+                               $maxperiparg = "-maxperip " . $config['captiveportal']['maxprocperip'];
+               } else
+                       $maxperiparg = "-maxperip 4";
+               
                /* start web server */
-               mwexec("/usr/local/sbin/mini_httpd -a -M 0 -u root -maxproc 16" .
-                       " -p 8000 -i {$g['varrun_path']}/mini_httpd.cp.pid");
+               $cpip = $config['interfaces'][$config['captiveportal']['interface']]['ipaddr'];
+               mwexec("/usr/local/sbin/mini_httpd -a -M 0 -u root -maxproc $maxproc $maxperiparg" .
+                       " -p 8000 -i {$g['varrun_path']}/mini_httpd.cp.pid" .
+                       " -cpelement {$g['captiveportal_element_path']} $cpip:8000");
                
                /* fire up another one for HTTPS if requested */
                if (isset($config['captiveportal']['httpslogin']) &&
@@ -176,14 +203,17 @@ EOD;
                        fwrite($fd, "\n");
                        fwrite($fd, $key);
                        fclose($fd);
-                       
+
+                       $httpsname = ($config['captiveportal']['httpsname']) ? $config['captiveportal']['httpsname'] : $cpip;
+
                        mwexec("/usr/local/sbin/mini_httpd -S -a -M 0 -E {$g['varetc_path']}/cert-portal.pem" .
-                               " -u root -maxproc 16 -p 8001" .
-                               " -i {$g['varrun_path']}/mini_httpd.cps.pid");
+                               " -u root -maxproc $maxproc $maxperiparg -p 8001" .
+                               " -i {$g['varrun_path']}/mini_httpd.cps.pid" .
+                               " -cpelement {$g['captiveportal_element_path']} $httpsname:8001");
                }
                        
-               /* start pruning process (interval = 60 seconds) */
-               mwexec("/usr/local/bin/minicron 60 {$g['varrun_path']}/minicron.pid " .
+               /* start pruning process (interval defaults to 60 seconds) */
+               mwexec("/usr/local/bin/minicron $croninterval {$g['varrun_path']}/minicron.pid " .
                        "/etc/rc.prunecaptiveportal");
                
                /* generate passthru mac database */
@@ -195,6 +225,7 @@ EOD;
                if ($config['captiveportal']['radiusip'] && (!isset($config['captiveportal']['auth_method']) ||
                                ($config['captiveportal']['auth_method'] == "radius"))) {
                        $radiusip = $config['captiveportal']['radiusip'];
+                       $radiusip2 = ($config['captiveportal']['radiusip2']) ? $config['captiveportal']['radiusip2'] : null;
 
                        if ($config['captiveportal']['radiusport'])
                                $radiusport = $config['captiveportal']['radiusport'];
@@ -206,12 +237,21 @@ EOD;
                        else
                                $radiusacctport = 1813;
 
+                       if ($config['captiveportal']['radiusport2'])
+                               $radiusport2 = $config['captiveportal']['radiusport2'];
+                       else
+                               $radiusport2 = 1812;
+
                        $radiuskey = $config['captiveportal']['radiuskey'];
+                       $radiuskey2 = ($config['captiveportal']['radiuskey2']) ? $config['captiveportal']['radiuskey2'] : null;
 
                        $fd = @fopen("{$g['vardb_path']}/captiveportal_radius.db", "w");
                        if (!$fd) {
                                printf("Error: cannot open radius DB file in captiveportal_configure().\n");
                                return 1;
+                       } else if (isset($radiusip2, $radiuskey2)) {
+                               fwrite($fd,$radiusip . "," . $radiusport . "," . $radiusacctport . "," . $radiuskey . "\n"
+                                        . $radiusip2 . "," . $radiusport2 . "," . $radiusacctport . "," . $radiuskey2);
                        } else {
                                fwrite($fd,$radiusip . "," . $radiusport . "," . $radiusacctport . "," . $radiuskey);
                        }
@@ -326,12 +366,14 @@ EOD;
 }
 
 /* remove clients that have been around for longer than the specified amount of time */
-/* db file structure: timestamp,ipfw_rule_no,clientip,clientmac,username,sessionid,password */
+/* db file structure: 
+timestamp,ipfw_rule_no,clientip,clientmac,username,sessionid,password,session_timeout,idle_timeout,session_terminate_time */
+
 /* (password is in Base64 and only saved when reauthentication is enabled) */
 function captiveportal_prune_old() {
        
        global $g, $config;
-       
+
        /* check for expired entries */
        if ($config['captiveportal']['timeout'])
                $timeout = $config['captiveportal']['timeout'] * 60;
@@ -356,22 +398,46 @@ function captiveportal_prune_old() {
        for ($i = 0; $i < count($cpdb); $i++) {
                
                $timedout = false;
+               $term_cause = 1;
                
                /* hard timeout? */
                if ($timeout) {
-                       if ((time() - $cpdb[$i][0]) >= $timeout)
-                               $timedout = true;       
+                       if ((time() - $cpdb[$i][0]) >= $timeout) {
+                               $timedout = true;
+                               $term_cause = 5; // Session-Timeout
+                       }
+               }
+
+               /* Session-Terminate-Time */
+               if (!$timedout && !empty($cpdb[$i][9])) {
+                       if (time() >= $cpdb[$i][9]) {
+                               $timedout = true;
+                               $term_cause = 5; // Session-Timeout
+                       }
                }
                
+               /* check if the radius idle_timeout attribute has been set and if its set change the idletimeout to this value */
+               $idletimeout = (is_numeric($cpdb[$i][8])) ? $cpdb[$i][8] : $idletimeout;
                /* if an idle timeout is specified, get last activity timestamp from ipfw */
                if (!$timedout && $idletimeout) {
                        $lastact = captiveportal_get_last_activity($cpdb[$i][1]);
-                       if ($lastact && ((time() - $lastact) >= $idletimeout))
+                       if ($lastact && ((time() - $lastact) >= $idletimeout)) {
                                $timedout = true;
+                               $term_cause = 4; // Idle-Timeout
+                               $stop_time = $lastact; // Entry added to comply with WISPr
+                       }
+               }
+
+               /* if radius session_timeout is enabled and the session_timeout is not null, then check if the user should be logged out */
+               if (!$timedout && isset($config['captiveportal']['radiussession_timeout']) && !empty($cpdb[$i][7])) {
+                       if (time() >= ($cpdb[$i][0] + $cpdb[$i][7])) {
+                               $timedout = true;
+                               $term_cause = 5; // Session-Timeout
+                       }
                }
                
                if ($timedout) {
-                       captiveportal_disconnect($cpdb[$i], $radiusservers);
+                       captiveportal_disconnect($cpdb[$i], $radiusservers,$term_cause,$stop_time);
                        captiveportal_logportalauth($cpdb[$i][4], $cpdb[$i][3], $cpdb[$i][2], "TIMEOUT");
                        unset($cpdb[$i]);
                }
@@ -390,14 +456,18 @@ function captiveportal_prune_old() {
                                                                                   $radiusservers[0]['ipaddr'],
                                                                                   $radiusservers[0]['acctport'],
                                                                                   $radiusservers[0]['key'],
-                                                                                  $cpdb[$i][2]); //clientip
+                                                                                  $cpdb[$i][2], // clientip
+                                                                                  $cpdb[$i][3], // clientmac
+                                                                                  10); // NAS Request
                                        exec("/sbin/ipfw zero {$cpdb[$i][1]}");
-                                       RADIUS_ACCOUNTING_START($cpdb[$i][4],
-                                                                                       $cpdb[$i][5],
+                                       RADIUS_ACCOUNTING_START($cpdb[$i][1], // ruleno
+                                                                                       $cpdb[$i][4], // username
+                                                                                       $cpdb[$i][5], // sessionid
                                                                                        $radiusservers[0]['ipaddr'],
                                                                                        $radiusservers[0]['acctport'],
                                                                                        $radiusservers[0]['key'],
-                                                                                       $cpdb[$i][2]);
+                                                                                       $cpdb[$i][2], // clientip
+                                                                                       $cpdb[$i][3]); // clientmac
                                } else if ($config['captiveportal']['reauthenticateacct'] == "interimupdate") {
                                        RADIUS_ACCOUNTING_STOP($cpdb[$i][1], // ruleno
                                                                                   $cpdb[$i][4], // username
@@ -406,21 +476,24 @@ function captiveportal_prune_old() {
                                                                                   $radiusservers[0]['ipaddr'],
                                                                                   $radiusservers[0]['acctport'],
                                                                                   $radiusservers[0]['key'],
-                                                                                  $cpdb[$i][2], //clientip
-                                                                                  true);
+                                                                                  $cpdb[$i][2], // clientip
+                                                                                  $cpdb[$i][3], // clientmac
+                                                                                  10, // NAS Request
+                                                                                  true); // Interim Updates
                                }
                        }
                
                        /* check this user against RADIUS again */
-                       $auth_val = RADIUS_AUTHENTICATION($cpdb[$i][4],
-                                                                                 base64_decode($cpdb[$i][6]),
-                                                                                 $radiusservers[0]['ipaddr'],
-                                                                                 $radiusservers[0]['port'],
-                                                                                 $radiusservers[0]['key']);
+                       $auth_list = RADIUS_AUTHENTICATION($cpdb[$i][4], // username
+                                                                                 base64_decode($cpdb[$i][6]), // password
+                                                                                 $radiusservers,
+                                                                                 $cpdb[$i][2], // clientip
+                                                                                 $cpdb[$i][3], // clientmac
+                                                                                 $cpdb[$i][1]); // ruleno
                        
-                       if ($auth_val == 3) {
-                               captiveportal_disconnect($cpdb[$i], $radiusservers);
-                               captiveportal_logportalauth($cpdb[$i][4], $cpdb[$i][3], $cpdb[$i][2], "RADIUS_DISCONNECT");
+                       if ($auth_list['auth_val'] == 3) {
+                               captiveportal_disconnect($cpdb[$i], $radiusservers, 17);
+                               captiveportal_logportalauth($cpdb[$i][4], $cpdb[$i][3], $cpdb[$i][2], "RADIUS_DISCONNECT", $auth_list['reply_message']);
                                unset($cpdb[$i]);
                        }
                }
@@ -433,9 +506,11 @@ function captiveportal_prune_old() {
 }
 
 /* remove a single client according to the DB entry */
-function captiveportal_disconnect($dbent, $radiusservers) {
+function captiveportal_disconnect($dbent, $radiusservers,$term_cause = 1,$stop_time = null) {
        
        global $g, $config;
+
+       $stop_time = (empty($stop_time)) ? time() : $stop_time;
        
        /* this client needs to be deleted - remove ipfw rules */
        if (isset($config['captiveportal']['radacct_enable']) && isset($radiusservers[0])) {
@@ -446,7 +521,11 @@ function captiveportal_disconnect($dbent, $radiusservers) {
                                                           $radiusservers[0]['ipaddr'],
                                                           $radiusservers[0]['acctport'],
                                                           $radiusservers[0]['key'],
-                                                          $dbent[2]); //clientip
+                                                          $dbent[2], // clientip
+                                                          $dbent[3], // clientmac
+                                                          $term_cause, // Acct-Terminate-Cause
+                                                          false,
+                                                          $stop_time);
        }
        
        mwexec("/sbin/ipfw delete " . $dbent[1] . " " . ($dbent[1]+10000));
@@ -461,7 +540,7 @@ function captiveportal_disconnect($dbent, $radiusservers) {
 }
 
 /* remove a single client by ipfw rule number */
-function captiveportal_disconnect_client($id) {
+function captiveportal_disconnect_client($id,$term_cause = 1) {
        
        global $g, $config;
        
@@ -474,7 +553,7 @@ function captiveportal_disconnect_client($id) {
        /* find entry */        
        for ($i = 0; $i < count($cpdb); $i++) {
                if ($cpdb[$i][1] == $id) {
-                       captiveportal_disconnect($cpdb[$i], $radiusservers);
+                       captiveportal_disconnect($cpdb[$i], $radiusservers, $term_cause);
                        captiveportal_logportalauth($cpdb[$i][4], $cpdb[$i][3], $cpdb[$i][2], "DISCONNECT");
                        unset($cpdb[$i]);
                        break;
@@ -490,6 +569,9 @@ function captiveportal_disconnect_client($id) {
 /* send RADIUS acct stop for all current clients */
 function captiveportal_radius_stop_all() {
        global $g, $config;
+       
+       if (!isset($config['captiveportal']['radacct_enable']))
+               return;
 
        captiveportal_lock();
        $cpdb = captiveportal_read_db();
@@ -505,7 +587,9 @@ function captiveportal_radius_stop_all() {
                                                                   $radiusservers[0]['ipaddr'],
                                                                   $radiusservers[0]['acctport'],
                                                                   $radiusservers[0]['key'],
-                                                                  $cpdb[$i][2]); //clientip
+                                                                  $cpdb[$i][2], // clientip
+                                                                  $cpdb[$i][3], // clientmac
+                                                                  7); // Admin Reboot
                }
        }
        captiveportal_unlock();
@@ -625,107 +709,182 @@ function captiveportal_get_last_activity($ruleno) {
        return 0;
 }
 
-/* read captive portal DB into array */
-function captiveportal_read_db() {
-       
-       global $g;
-       
-       $cpdb = array();
-       $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "r");
-       if ($fd) {
-               while (!feof($fd)) {
-                       $line = trim(fgets($fd));
-                       if ($line) {
-                               $cpdb[] = explode(",", $line);
-                       }       
-               }
-               fclose($fd);
-       }
-       return $cpdb;
-}
-
-/* write captive portal DB */
-function captiveportal_write_db($cpdb) {
-       
-       global $g;
-       
-       $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "w");
-       if ($fd) {
-               foreach ($cpdb as $cpent) {
-                       fwrite($fd, join(",", $cpent) . "\n");
-               }
-               fclose($fd);
-       }
-}
-
 /* read RADIUS servers into array */
 function captiveportal_get_radius_servers() {
-       
-       global $g;
-       
-       if (file_exists("{$g['vardb_path']}/captiveportal_radius.db")) {
-               $fd = @fopen("{$g['vardb_path']}/captiveportal_radius.db","r");
-               if ($fd) {
-                       $radiusservers = array();
-                       while (!feof($fd)) {
-                               $line = trim(fgets($fd));
-                               if ($line) {
-                                       $radsrv = array();
-                                       list($radsrv['ipaddr'],$radsrv['port'],$radsrv['acctport'],$radsrv['key']) = explode(",",$line);
-                                       $radiusservers[] = $radsrv;
-                               }
-                       }
-                       fclose($fd);
-                       
-                       return $radiusservers;
-               }
-       }
-       
-       return false;
+
+        global $g;
+
+        if (file_exists("{$g['vardb_path']}/captiveportal_radius.db")) {
+                $fd = @fopen("{$g['vardb_path']}/captiveportal_radius.db","r");
+                if ($fd) {
+                        $radiusservers = array();
+                        while (!feof($fd)) {
+                                $line = trim(fgets($fd));
+                                if ($line) {
+                                        $radsrv = array();
+                                        list($radsrv['ipaddr'],$radsrv['port'],$radsrv['acctport'],$radsrv['key']) = explode(",",$line);
+                                        $radiusservers[] = $radsrv;
+                                }
+                        }
+                        fclose($fd);
+
+                        return $radiusservers;
+                }
+        }
+
+        return false;
 }
 
 /* lock captive portal information, decide that the lock file is stale after
    10 seconds */
 function captiveportal_lock() {
-       
-       global $g;
-       
-       $lockfile = "{$g['varrun_path']}/captiveportal.lock";
-       
-       $n = 0;
-       while ($n < 10) {
-               /* open the lock file in append mode to avoid race condition */
-               if ($fd = @fopen($lockfile, "x")) {
-                       /* succeeded */
-                       fclose($fd);
-                       return;
-               } else {
-                       /* file locked, wait and try again */
-                       sleep(1);
-                       $n++;
-               }
-       }
+
+        global $lockfile;
+
+        $n = 0;
+        while ($n < 10) {
+                /* open the lock file in append mode to avoid race condition */
+                if ($fd = @fopen($lockfile, "x")) {
+                        /* succeeded */
+                        fclose($fd);
+                        return;
+                } else {
+                        /* file locked, wait and try again */
+                        sleep(1);
+                        $n++;
+                }
+        }
 }
 
-/* unlock configuration file */
+/* unlock captive portal information file */
 function captiveportal_unlock() {
-       
-       global $g;
-       
-       $lockfile = "{$g['varrun_path']}/captiveportal.lock";
-       
-       if (file_exists($lockfile))
-               unlink($lockfile);
+
+        global $lockfile;
+
+        if (file_exists($lockfile))
+                unlink($lockfile);
 }
 
 /* log successful captive portal authentication to syslog */
 /* part of this code from php.net */
-function captiveportal_logportalauth($user,$mac,$ip,$status) {
+function captiveportal_logportalauth($user,$mac,$ip,$status, $message = null) {
        define_syslog_variables();
+       $message = trim($message);
        openlog("logportalauth", LOG_PID, LOG_LOCAL4);
        // Log it
+       if (!$message)
        syslog(LOG_INFO, "$status: $user, $mac, $ip");
+       else
+       syslog(LOG_INFO, "$status: $user, $mac, $ip, $message");
        closelog();
 }
 
+function radius($username,$password,$clientip,$clientmac,$type) {
+       global $g, $config;
+
+       $next_ruleno = get_next_ipfw_ruleno();
+       $radiusservers = captiveportal_get_radius_servers();
+       $radacct_enable = isset($config['captiveportal']['radacct_enable']);
+
+       $auth_list = RADIUS_AUTHENTICATION($username,
+                                       $password,
+                                       $radiusservers,
+                                       $clientip,
+                                       $clientmac,
+                                       $next_ruleno);
+
+       if ($auth_list['auth_val'] == 2) {
+               captiveportal_logportalauth($username,$clientmac,$clientip,$type);
+               $sessionid = portal_allow($clientip,
+                                       $clientmac,
+                                       $username,
+                                       $password,
+                                       $auth_list['session_timeout'],
+                                       $auth_list['idle_timeout'],
+                                       $auth_list['url_redirection'],
+                                       $auth_list['session_terminate_time']);
+
+               if ($radacct_enable) {
+                       $auth_list['acct_val'] = RADIUS_ACCOUNTING_START($next_ruleno,
+                                                                       $username,
+                                                                       $sessionid,
+                                                                       $radiusservers[0]['ipaddr'],
+                                                                       $radiusservers[0]['acctport'],
+                                                                       $radiusservers[0]['key'],
+                                                                       $clientip,
+                                                                       $clientmac);
+                       if ($auth_list['acct_val'] == 1) 
+                               captiveportal_logportalauth($username,$clientmac,$clientip,$type,"RADIUS ACCOUNTING FAILED");
+               }
+       }
+
+       return $auth_list;
+
+}
+
+/* read captive portal DB into array */
+function captiveportal_read_db() {
+
+        global $g;
+
+        $cpdb = array();
+        $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "r");
+        if ($fd) {
+                while (!feof($fd)) {
+                        $line = trim(fgets($fd));
+                        if ($line) {
+                                $cpdb[] = explode(",", $line);
+                        }
+                }
+                fclose($fd);
+        }
+        return $cpdb;
+}
+
+/* write captive portal DB */
+function captiveportal_write_db($cpdb) {
+                 
+        global $g;
+                
+        $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "w");
+        if ($fd) { 
+                foreach ($cpdb as $cpent) {
+                        fwrite($fd, join(",", $cpent) . "\n");
+                }       
+                fclose($fd);
+        }       
+}
+
+function captiveportal_write_elements() {
+       global $g, $config;
+       
+       /* delete any existing elements */
+       if (is_dir($g['captiveportal_element_path'])) {
+               $dh = opendir($g['captiveportal_element_path']);
+               while (($file = readdir($dh)) !== false) {
+                       if ($file != "." && $file != "..")
+                               unlink($g['captiveportal_element_path'] . "/" . $file);
+               }
+               closedir($dh);
+       } else {
+               mkdir($g['captiveportal_element_path']);
+       }
+       
+       if (is_array($config['captiveportal']['element'])) {
+       
+               foreach ($config['captiveportal']['element'] as $data) {
+                       $fd = @fopen($g['captiveportal_element_path'] . '/' . $data['name'], "wb");
+                       if (!$fd) {
+                               printf("Error: cannot open '{$data['name']}' in captiveportal_write_elements().\n");
+                               return 1;
+                       }
+                       $decoded = base64_decode($data['content']);
+                       fwrite($fd,$decoded);
+                       fclose($fd);
+               }
+       }
+       
+       return 0;
+}
+
 ?>
index 71f4b264f7c005cf294f8acd1088ffc411ca5525..e6636ac00d581efa7c2ac805af481382aa814f95 100644 (file)
@@ -3,7 +3,7 @@
        config.inc
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
@@ -634,6 +634,9 @@ function config_install($conffile) {
        if (!file_exists($conffile))
                return 1;
 
+       if (!config_validate($conffile))
+               return 1;
+
        config_lock();
        conf_mount_rw();
        
@@ -645,6 +648,32 @@ function config_install($conffile) {
        return 0;
 }
 
+function config_validate($conffile) {
+
+       global $g, $xmlerr;
+
+       $xml_parser = xml_parser_create();
+       
+       if (!($fp = fopen($conffile, "r"))) {
+               $xmlerr = "XML error: unable to open file";
+               return false;
+       }
+       
+       while ($data = fread($fp, 4096)) {
+               if (!xml_parse($xml_parser, $data, feof($fp))) {
+                       $xmlerr = sprintf("%s at line %d",
+                                               xml_error_string(xml_get_error_code($xml_parser)),
+                                               xml_get_current_line_number($xml_parser));
+                       return false;
+               }
+       }
+       xml_parser_free($xml_parser);
+       
+       fclose($fp);
+       
+       return true;
+}
+
 /* lock configuration file, decide that the lock file is stale after
    10 seconds */
 function config_lock() {
index a85da2e5743e6ebe768ab8b90c4b715b14691f27..d08a1e125e3fbd3c81a252b43b93cfde20bad391 100644 (file)
@@ -3,7 +3,7 @@
        filter.inc
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index a23a37a2b7b8db669070c123521f687038db5c80..863d8286b5c8f932fb9017cd283649582480fab5 100644 (file)
@@ -3,7 +3,7 @@
     functions.inc
     part of m0n0wall (http://m0n0.ch/wall)
     
-    Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+    Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
     All rights reserved.
     
     Redistribution and use in source and binary forms, with or without
@@ -29,6 +29,8 @@
 */
 
 /* include all configuration functions */
+require_once("globals.inc");
+require_once("config.inc");
 require_once("system.inc");
 require_once("interfaces.inc");
 require_once("services.inc");
@@ -36,5 +38,6 @@ require_once("filter.inc");
 require_once("shaper.inc");
 require_once("vpn.inc");
 require_once("captiveportal.inc");
+require_once("util.inc");
 
 ?>
index 14be2c81fab3370d321ebb469cb209049f78527f..01027396137f38c46d4b42572d1a3e67336575e8 100644 (file)
@@ -3,7 +3,7 @@
     globals.inc
     part of m0n0wall (http://m0n0.ch/wall)
     
-    Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+    Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
     All rights reserved.
     
     Redistribution and use in source and binary forms, with or without
@@ -42,6 +42,8 @@ $g = array(
     "cf_conf_path" => "/cf/conf",
     "www_path" => "/usr/local/www",
     "captiveportal_path" => "/usr/local/captiveportal",
+    "captiveportal_element_path" => "/var/db/cpelements",
+    "captiveportal_element_sizelimit" => 262144,
     "xml_rootobj" => "m0n0wall",
     "pppoe_interface" => "ng0",
     "n_pptp_units" => 16,
index 0dc5e5e5bdc7b71932831883c4a540216b02b394..a928fe90771ca991d70f3d4014812fb28fccd165 100644 (file)
@@ -3,7 +3,7 @@
        interfaces.inc
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
@@ -826,4 +826,14 @@ function get_current_wan_address() {
        }
 }
 
+function get_interface_mac($interface) {
+  
+        /* build interface list with netstat */
+        exec("/usr/bin/netstat -I $interface -nW -f link", $linkinfo);
+        array_shift($linkinfo);
+        $alink = preg_split("/\s+/", $linkinfo[0]);
+        $mac = chop($alink[3]);
+        return $mac;
+}
+
 ?>
diff --git a/phpconf/inc/pear.inc b/phpconf/inc/pear.inc
new file mode 100644 (file)
index 0000000..a1967b8
--- /dev/null
@@ -0,0 +1,1055 @@
+<?php
+//
+// +--------------------------------------------------------------------+
+// | PEAR, the PHP Extension and Application Repository                 |
+// +--------------------------------------------------------------------+
+// | Copyright (c) 1997-2004 The PHP Group                              |
+// +--------------------------------------------------------------------+
+// | This source file is subject to version 3.0 of the PHP license,     |
+// | that is bundled with this package in the file LICENSE, and is      |
+// | available through the world-wide-web at the following url:         |
+// | http://www.php.net/license/3_0.txt.                                |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to        |
+// | license@php.net so we can mail you a copy immediately.             |
+// +--------------------------------------------------------------------+
+// | Authors: Sterling Hughes <sterling@php.net>                        |
+// |          Stig Bakken <ssb@php.net>                                 |
+// |          Tomas V.V.Cox <cox@idecnet.com>                           |
+// +--------------------------------------------------------------------+
+//
+// $Id: PEAR.php,v 1.50.2.19 2005/03/28 16:56:58 cellog Exp $
+//
+
+define('PEAR_ERROR_RETURN',     1);
+define('PEAR_ERROR_PRINT',      2);
+define('PEAR_ERROR_TRIGGER',    4);
+define('PEAR_ERROR_DIE',        8);
+define('PEAR_ERROR_CALLBACK',  16);
+/**
+ * WARNING: obsolete
+ * @deprecated
+ */
+define('PEAR_ERROR_EXCEPTION', 32);
+define('PEAR_ZE2', (function_exists('version_compare') &&
+                    version_compare(zend_version(), "2-dev", "ge")));
+
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+    define('OS_WINDOWS', true);
+    define('OS_UNIX',    false);
+    define('PEAR_OS',    'Windows');
+} else {
+    define('OS_WINDOWS', false);
+    define('OS_UNIX',    true);
+    define('PEAR_OS',    'Unix'); // blatant assumption
+}
+
+// instant backwards compatibility
+if (!defined('PATH_SEPARATOR')) {
+    if (OS_WINDOWS) {
+        define('PATH_SEPARATOR', ';');
+    } else {
+        define('PATH_SEPARATOR', ':');
+    }
+}
+
+$GLOBALS['_PEAR_default_error_mode']     = PEAR_ERROR_RETURN;
+$GLOBALS['_PEAR_default_error_options']  = E_USER_NOTICE;
+$GLOBALS['_PEAR_destructor_object_list'] = array();
+$GLOBALS['_PEAR_shutdown_funcs']         = array();
+$GLOBALS['_PEAR_error_handler_stack']    = array();
+
+@ini_set('track_errors', true);
+
+/**
+ * Base class for other PEAR classes.  Provides rudimentary
+ * emulation of destructors.
+ *
+ * If you want a destructor in your class, inherit PEAR and make a
+ * destructor method called _yourclassname (same name as the
+ * constructor, but with a "_" prefix).  Also, in your constructor you
+ * have to call the PEAR constructor: $this->PEAR();.
+ * The destructor method will be called without parameters.  Note that
+ * at in some SAPI implementations (such as Apache), any output during
+ * the request shutdown (in which destructors are called) seems to be
+ * discarded.  If you need to get any debug information from your
+ * destructor, use error_log(), syslog() or something similar.
+ *
+ * IMPORTANT! To use the emulated destructors you need to create the
+ * objects by reference: $obj =& new PEAR_child;
+ *
+ * @since PHP 4.0.2
+ * @author Stig Bakken <ssb@php.net>
+ * @see http://pear.php.net/manual/
+ */
+class PEAR
+{
+    // {{{ properties
+
+    /**
+     * Whether to enable internal debug messages.
+     *
+     * @var     bool
+     * @access  private
+     */
+    var $_debug = false;
+
+    /**
+     * Default error mode for this object.
+     *
+     * @var     int
+     * @access  private
+     */
+    var $_default_error_mode = null;
+
+    /**
+     * Default error options used for this object when error mode
+     * is PEAR_ERROR_TRIGGER.
+     *
+     * @var     int
+     * @access  private
+     */
+    var $_default_error_options = null;
+
+    /**
+     * Default error handler (callback) for this object, if error mode is
+     * PEAR_ERROR_CALLBACK.
+     *
+     * @var     string
+     * @access  private
+     */
+    var $_default_error_handler = '';
+
+    /**
+     * Which class to use for error objects.
+     *
+     * @var     string
+     * @access  private
+     */
+    var $_error_class = 'PEAR_Error';
+
+    /**
+     * An array of expected errors.
+     *
+     * @var     array
+     * @access  private
+     */
+    var $_expected_errors = array();
+
+    // }}}
+
+    // {{{ constructor
+
+    /**
+     * Constructor.  Registers this object in
+     * $_PEAR_destructor_object_list for destructor emulation if a
+     * destructor object exists.
+     *
+     * @param string $error_class  (optional) which class to use for
+     *        error objects, defaults to PEAR_Error.
+     * @access public
+     * @return void
+     */
+    function PEAR($error_class = null)
+    {
+        $classname = strtolower(get_class($this));
+        if ($this->_debug) {
+            print "PEAR constructor called, class=$classname\n";
+        }
+        if ($error_class !== null) {
+            $this->_error_class = $error_class;
+        }
+        while ($classname && strcasecmp($classname, "pear")) {
+            $destructor = "_$classname";
+            if (method_exists($this, $destructor)) {
+                global $_PEAR_destructor_object_list;
+                $_PEAR_destructor_object_list[] = &$this;
+                if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
+                    register_shutdown_function("_PEAR_call_destructors");
+                    $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
+                }
+                break;
+            } else {
+                $classname = get_parent_class($classname);
+            }
+        }
+    }
+
+    // }}}
+    // {{{ destructor
+
+    /**
+     * Destructor (the emulated type of...).  Does nothing right now,
+     * but is included for forward compatibility, so subclass
+     * destructors should always call it.
+     *
+     * See the note in the class desciption about output from
+     * destructors.
+     *
+     * @access public
+     * @return void
+     */
+    function _PEAR() {
+        if ($this->_debug) {
+            printf("PEAR destructor called, class=%s\n", strtolower(get_class($this)));
+        }
+    }
+
+    // }}}
+    // {{{ getStaticProperty()
+
+    /**
+    * If you have a class that's mostly/entirely static, and you need static
+    * properties, you can use this method to simulate them. Eg. in your method(s)
+    * do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar');
+    * You MUST use a reference, or they will not persist!
+    *
+    * @access public
+    * @param  string $class  The calling classname, to prevent clashes
+    * @param  string $var    The variable to retrieve.
+    * @return mixed   A reference to the variable. If not set it will be
+    *                 auto initialised to NULL.
+    */
+    function &getStaticProperty($class, $var)
+    {
+        static $properties;
+        return $properties[$class][$var];
+    }
+
+    // }}}
+    // {{{ registerShutdownFunc()
+
+    /**
+    * Use this function to register a shutdown method for static
+    * classes.
+    *
+    * @access public
+    * @param  mixed $func  The function name (or array of class/method) to call
+    * @param  mixed $args  The arguments to pass to the function
+    * @return void
+    */
+    function registerShutdownFunc($func, $args = array())
+    {
+        $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);
+    }
+
+    // }}}
+    // {{{ isError()
+
+    /**
+     * Tell whether a value is a PEAR error.
+     *
+     * @param   mixed $data   the value to test
+     * @param   int   $code   if $data is an error object, return true
+     *                        only if $code is a string and
+     *                        $obj->getMessage() == $code or
+     *                        $code is an integer and $obj->getCode() == $code
+     * @access  public
+     * @return  bool    true if parameter is an error
+     */
+    function isError($data, $code = null)
+    {
+        if (is_a($data, 'PEAR_Error')) {
+            if (is_null($code)) {
+                return true;
+            } elseif (is_string($code)) {
+                return $data->getMessage() == $code;
+            } else {
+                return $data->getCode() == $code;
+            }
+        }
+        return false;
+    }
+
+    // }}}
+    // {{{ setErrorHandling()
+
+    /**
+     * Sets how errors generated by this object should be handled.
+     * Can be invoked both in objects and statically.  If called
+     * statically, setErrorHandling sets the default behaviour for all
+     * PEAR objects.  If called in an object, setErrorHandling sets
+     * the default behaviour for that object.
+     *
+     * @param int $mode
+     *        One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
+     *        PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
+     *        PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION.
+     *
+     * @param mixed $options
+     *        When $mode is PEAR_ERROR_TRIGGER, this is the error level (one
+     *        of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
+     *
+     *        When $mode is PEAR_ERROR_CALLBACK, this parameter is expected
+     *        to be the callback function or method.  A callback
+     *        function is a string with the name of the function, a
+     *        callback method is an array of two elements: the element
+     *        at index 0 is the object, and the element at index 1 is
+     *        the name of the method to call in the object.
+     *
+     *        When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is
+     *        a printf format string used when printing the error
+     *        message.
+     *
+     * @access public
+     * @return void
+     * @see PEAR_ERROR_RETURN
+     * @see PEAR_ERROR_PRINT
+     * @see PEAR_ERROR_TRIGGER
+     * @see PEAR_ERROR_DIE
+     * @see PEAR_ERROR_CALLBACK
+     * @see PEAR_ERROR_EXCEPTION
+     *
+     * @since PHP 4.0.5
+     */
+
+    function setErrorHandling($mode = null, $options = null)
+    {
+        if (isset($this) && is_a($this, 'PEAR')) {
+            $setmode     = &$this->_default_error_mode;
+            $setoptions  = &$this->_default_error_options;
+        } else {
+            $setmode     = &$GLOBALS['_PEAR_default_error_mode'];
+            $setoptions  = &$GLOBALS['_PEAR_default_error_options'];
+        }
+
+        switch ($mode) {
+            case PEAR_ERROR_EXCEPTION:
+            case PEAR_ERROR_RETURN:
+            case PEAR_ERROR_PRINT:
+            case PEAR_ERROR_TRIGGER:
+            case PEAR_ERROR_DIE:
+            case null:
+                $setmode = $mode;
+                $setoptions = $options;
+                break;
+
+            case PEAR_ERROR_CALLBACK:
+                $setmode = $mode;
+                // class/object method callback
+                if (is_callable($options)) {
+                    $setoptions = $options;
+                } else {
+                    trigger_error("invalid error callback", E_USER_WARNING);
+                }
+                break;
+
+            default:
+                trigger_error("invalid error mode", E_USER_WARNING);
+                break;
+        }
+    }
+
+    // }}}
+    // {{{ expectError()
+
+    /**
+     * This method is used to tell which errors you expect to get.
+     * Expected errors are always returned with error mode
+     * PEAR_ERROR_RETURN.  Expected error codes are stored in a stack,
+     * and this method pushes a new element onto it.  The list of
+     * expected errors are in effect until they are popped off the
+     * stack with the popExpect() method.
+     *
+     * Note that this method can not be called statically
+     *
+     * @param mixed $code a single error code or an array of error codes to expect
+     *
+     * @return int     the new depth of the "expected errors" stack
+     * @access public
+     */
+    function expectError($code = '*')
+    {
+        if (is_array($code)) {
+            array_push($this->_expected_errors, $code);
+        } else {
+            array_push($this->_expected_errors, array($code));
+        }
+        return sizeof($this->_expected_errors);
+    }
+
+    // }}}
+    // {{{ popExpect()
+
+    /**
+     * This method pops one element off the expected error codes
+     * stack.
+     *
+     * @return array   the list of error codes that were popped
+     */
+    function popExpect()
+    {
+        return array_pop($this->_expected_errors);
+    }
+
+    // }}}
+    // {{{ _checkDelExpect()
+
+    /**
+     * This method checks unsets an error code if available
+     *
+     * @param mixed error code
+     * @return bool true if the error code was unset, false otherwise
+     * @access private
+     * @since PHP 4.3.0
+     */
+    function _checkDelExpect($error_code)
+    {
+        $deleted = false;
+
+        foreach ($this->_expected_errors AS $key => $error_array) {
+            if (in_array($error_code, $error_array)) {
+                unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);
+                $deleted = true;
+            }
+
+            // clean up empty arrays
+            if (0 == count($this->_expected_errors[$key])) {
+                unset($this->_expected_errors[$key]);
+            }
+        }
+        return $deleted;
+    }
+
+    // }}}
+    // {{{ delExpect()
+
+    /**
+     * This method deletes all occurences of the specified element from
+     * the expected error codes stack.
+     *
+     * @param  mixed $error_code error code that should be deleted
+     * @return mixed list of error codes that were deleted or error
+     * @access public
+     * @since PHP 4.3.0
+     */
+    function delExpect($error_code)
+    {
+        $deleted = false;
+
+        if ((is_array($error_code) && (0 != count($error_code)))) {
+            // $error_code is a non-empty array here;
+            // we walk through it trying to unset all
+            // values
+            foreach($error_code as $key => $error) {
+                if ($this->_checkDelExpect($error)) {
+                    $deleted =  true;
+                } else {
+                    $deleted = false;
+                }
+            }
+            return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
+        } elseif (!empty($error_code)) {
+            // $error_code comes alone, trying to unset it
+            if ($this->_checkDelExpect($error_code)) {
+                return true;
+            } else {
+                return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
+            }
+        } else {
+            // $error_code is empty
+            return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME
+        }
+    }
+
+    // }}}
+    // {{{ raiseError()
+
+    /**
+     * This method is a wrapper that returns an instance of the
+     * configured error class with this object's default error
+     * handling applied.  If the $mode and $options parameters are not
+     * specified, the object's defaults are used.
+     *
+     * @param mixed $message a text error message or a PEAR error object
+     *
+     * @param int $code      a numeric error code (it is up to your class
+     *                  to define these if you want to use codes)
+     *
+     * @param int $mode      One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
+     *                  PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
+     *                  PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION.
+     *
+     * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter
+     *                  specifies the PHP-internal error level (one of
+     *                  E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
+     *                  If $mode is PEAR_ERROR_CALLBACK, this
+     *                  parameter specifies the callback function or
+     *                  method.  In other error modes this parameter
+     *                  is ignored.
+     *
+     * @param string $userinfo If you need to pass along for example debug
+     *                  information, this parameter is meant for that.
+     *
+     * @param string $error_class The returned error object will be
+     *                  instantiated from this class, if specified.
+     *
+     * @param bool $skipmsg If true, raiseError will only pass error codes,
+     *                  the error message parameter will be dropped.
+     *
+     * @access public
+     * @return object   a PEAR error object
+     * @see PEAR::setErrorHandling
+     * @since PHP 4.0.5
+     */
+    function raiseError($message = null,
+                         $code = null,
+                         $mode = null,
+                         $options = null,
+                         $userinfo = null,
+                         $error_class = null,
+                         $skipmsg = false)
+    {
+        // The error is yet a PEAR error object
+        if (is_object($message)) {
+            $code        = $message->getCode();
+            $userinfo    = $message->getUserInfo();
+            $error_class = $message->getType();
+            $message->error_message_prefix = '';
+            $message     = $message->getMessage();
+        }
+
+        if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) {
+            if ($exp[0] == "*" ||
+                (is_int(reset($exp)) && in_array($code, $exp)) ||
+                (is_string(reset($exp)) && in_array($message, $exp))) {
+                $mode = PEAR_ERROR_RETURN;
+            }
+        }
+        // No mode given, try global ones
+        if ($mode === null) {
+            // Class error handler
+            if (isset($this) && isset($this->_default_error_mode)) {
+                $mode    = $this->_default_error_mode;
+                $options = $this->_default_error_options;
+            // Global error handler
+            } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) {
+                $mode    = $GLOBALS['_PEAR_default_error_mode'];
+                $options = $GLOBALS['_PEAR_default_error_options'];
+            }
+        }
+
+        if ($error_class !== null) {
+            $ec = $error_class;
+        } elseif (isset($this) && isset($this->_error_class)) {
+            $ec = $this->_error_class;
+        } else {
+            $ec = 'PEAR_Error';
+        }
+        if ($skipmsg) {
+            return new $ec($code, $mode, $options, $userinfo);
+        } else {
+            return new $ec($message, $code, $mode, $options, $userinfo);
+        }
+    }
+
+    // }}}
+    // {{{ throwError()
+
+    /**
+     * Simpler form of raiseError with fewer options.  In most cases
+     * message, code and userinfo are enough.
+     *
+     * @param string $message
+     *
+     */
+    function throwError($message = null,
+                         $code = null,
+                         $userinfo = null)
+    {
+        if (isset($this) && is_a($this, 'PEAR')) {
+            return $this->raiseError($message, $code, null, null, $userinfo);
+        } else {
+            return PEAR::raiseError($message, $code, null, null, $userinfo);
+        }
+    }
+
+    // }}}
+    function staticPushErrorHandling($mode, $options = null)
+    {
+        $stack = &$GLOBALS['_PEAR_error_handler_stack'];
+        $def_mode    = &$GLOBALS['_PEAR_default_error_mode'];
+        $def_options = &$GLOBALS['_PEAR_default_error_options'];
+        $stack[] = array($def_mode, $def_options);
+        switch ($mode) {
+            case PEAR_ERROR_EXCEPTION:
+            case PEAR_ERROR_RETURN:
+            case PEAR_ERROR_PRINT:
+            case PEAR_ERROR_TRIGGER:
+            case PEAR_ERROR_DIE:
+            case null:
+                $def_mode = $mode;
+                $def_options = $options;
+                break;
+
+            case PEAR_ERROR_CALLBACK:
+                $def_mode = $mode;
+                // class/object method callback
+                if (is_callable($options)) {
+                    $def_options = $options;
+                } else {
+                    trigger_error("invalid error callback", E_USER_WARNING);
+                }
+                break;
+
+            default:
+                trigger_error("invalid error mode", E_USER_WARNING);
+                break;
+        }
+        $stack[] = array($mode, $options);
+        return true;
+    }
+
+    function staticPopErrorHandling()
+    {
+        $stack = &$GLOBALS['_PEAR_error_handler_stack'];
+        $setmode     = &$GLOBALS['_PEAR_default_error_mode'];
+        $setoptions  = &$GLOBALS['_PEAR_default_error_options'];
+        array_pop($stack);
+        list($mode, $options) = $stack[sizeof($stack) - 1];
+        array_pop($stack);
+        switch ($mode) {
+            case PEAR_ERROR_EXCEPTION:
+            case PEAR_ERROR_RETURN:
+            case PEAR_ERROR_PRINT:
+            case PEAR_ERROR_TRIGGER:
+            case PEAR_ERROR_DIE:
+            case null:
+                $setmode = $mode;
+                $setoptions = $options;
+                break;
+
+            case PEAR_ERROR_CALLBACK:
+                $setmode = $mode;
+                // class/object method callback
+                if (is_callable($options)) {
+                    $setoptions = $options;
+                } else {
+                    trigger_error("invalid error callback", E_USER_WARNING);
+                }
+                break;
+
+            default:
+                trigger_error("invalid error mode", E_USER_WARNING);
+                break;
+        }
+        return true;
+    }
+
+    // {{{ pushErrorHandling()
+
+    /**
+     * Push a new error handler on top of the error handler options stack. With this
+     * you can easily override the actual error handler for some code and restore
+     * it later with popErrorHandling.
+     *
+     * @param mixed $mode (same as setErrorHandling)
+     * @param mixed $options (same as setErrorHandling)
+     *
+     * @return bool Always true
+     *
+     * @see PEAR::setErrorHandling
+     */
+    function pushErrorHandling($mode, $options = null)
+    {
+        $stack = &$GLOBALS['_PEAR_error_handler_stack'];
+        if (isset($this) && is_a($this, 'PEAR')) {
+            $def_mode    = &$this->_default_error_mode;
+            $def_options = &$this->_default_error_options;
+        } else {
+            $def_mode    = &$GLOBALS['_PEAR_default_error_mode'];
+            $def_options = &$GLOBALS['_PEAR_default_error_options'];
+        }
+        $stack[] = array($def_mode, $def_options);
+
+        if (isset($this) && is_a($this, 'PEAR')) {
+            $this->setErrorHandling($mode, $options);
+        } else {
+            PEAR::setErrorHandling($mode, $options);
+        }
+        $stack[] = array($mode, $options);
+        return true;
+    }
+
+    // }}}
+    // {{{ popErrorHandling()
+
+    /**
+    * Pop the last error handler used
+    *
+    * @return bool Always true
+    *
+    * @see PEAR::pushErrorHandling
+    */
+    function popErrorHandling()
+    {
+        $stack = &$GLOBALS['_PEAR_error_handler_stack'];
+        array_pop($stack);
+        list($mode, $options) = $stack[sizeof($stack) - 1];
+        array_pop($stack);
+        if (isset($this) && is_a($this, 'PEAR')) {
+            $this->setErrorHandling($mode, $options);
+        } else {
+            PEAR::setErrorHandling($mode, $options);
+        }
+        return true;
+    }
+
+    // }}}
+    // {{{ loadExtension()
+
+    /**
+    * OS independant PHP extension load. Remember to take care
+    * on the correct extension name for case sensitive OSes.
+    *
+    * @param string $ext The extension name
+    * @return bool Success or not on the dl() call
+    */
+    function loadExtension($ext)
+    {
+        if (!extension_loaded($ext)) {
+            // if either returns true dl() will produce a FATAL error, stop that
+            if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) {
+                return false;
+            }
+            if (OS_WINDOWS) {
+                $suffix = '.dll';
+            } elseif (PHP_OS == 'HP-UX') {
+                $suffix = '.sl';
+            } elseif (PHP_OS == 'AIX') {
+                $suffix = '.a';
+            } elseif (PHP_OS == 'OSX') {
+                $suffix = '.bundle';
+            } else {
+                $suffix = '.so';
+            }
+            return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
+        }
+        return true;
+    }
+
+    // }}}
+}
+
+// {{{ _PEAR_call_destructors()
+
+function _PEAR_call_destructors()
+{
+    global $_PEAR_destructor_object_list;
+    if (is_array($_PEAR_destructor_object_list) &&
+        sizeof($_PEAR_destructor_object_list))
+    {
+        reset($_PEAR_destructor_object_list);
+        if (@PEAR::getStaticProperty('PEAR', 'destructlifo')) {
+            $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);
+        }
+        while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
+            $classname = get_class($objref);
+            while ($classname) {
+                $destructor = "_$classname";
+                if (method_exists($objref, $destructor)) {
+                    $objref->$destructor();
+                    break;
+                } else {
+                    $classname = get_parent_class($classname);
+                }
+            }
+        }
+        // Empty the object list to ensure that destructors are
+        // not called more than once.
+        $_PEAR_destructor_object_list = array();
+    }
+
+    // Now call the shutdown functions
+    if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) {
+        foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {
+            call_user_func_array($value[0], $value[1]);
+        }
+    }
+}
+
+// }}}
+
+class PEAR_Error
+{
+    // {{{ properties
+
+    var $error_message_prefix = '';
+    var $mode                 = PEAR_ERROR_RETURN;
+    var $level                = E_USER_NOTICE;
+    var $code                 = -1;
+    var $message              = '';
+    var $userinfo             = '';
+    var $backtrace            = null;
+
+    // }}}
+    // {{{ constructor
+
+    /**
+     * PEAR_Error constructor
+     *
+     * @param string $message  message
+     *
+     * @param int $code     (optional) error code
+     *
+     * @param int $mode     (optional) error mode, one of: PEAR_ERROR_RETURN,
+     * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER,
+     * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION
+     *
+     * @param mixed $options   (optional) error level, _OR_ in the case of
+     * PEAR_ERROR_CALLBACK, the callback function or object/method
+     * tuple.
+     *
+     * @param string $userinfo (optional) additional user/debug info
+     *
+     * @access public
+     *
+     */
+    function PEAR_Error($message = 'unknown error', $code = null,
+                        $mode = null, $options = null, $userinfo = null)
+    {
+        if ($mode === null) {
+            $mode = PEAR_ERROR_RETURN;
+        }
+        $this->message   = $message;
+        $this->code      = $code;
+        $this->mode      = $mode;
+        $this->userinfo  = $userinfo;
+        if (function_exists("debug_backtrace")) {
+            if (@!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) {
+                $this->backtrace = debug_backtrace();
+            }
+        }
+        if ($mode & PEAR_ERROR_CALLBACK) {
+            $this->level = E_USER_NOTICE;
+            $this->callback = $options;
+        } else {
+            if ($options === null) {
+                $options = E_USER_NOTICE;
+            }
+            $this->level = $options;
+            $this->callback = null;
+        }
+        if ($this->mode & PEAR_ERROR_PRINT) {
+            if (is_null($options) || is_int($options)) {
+                $format = "%s";
+            } else {
+                $format = $options;
+            }
+            printf($format, $this->getMessage());
+        }
+        if ($this->mode & PEAR_ERROR_TRIGGER) {
+            trigger_error($this->getMessage(), $this->level);
+        }
+        if ($this->mode & PEAR_ERROR_DIE) {
+            $msg = $this->getMessage();
+            if (is_null($options) || is_int($options)) {
+                $format = "%s";
+                if (substr($msg, -1) != "\n") {
+                    $msg .= "\n";
+                }
+            } else {
+                $format = $options;
+            }
+            die(sprintf($format, $msg));
+        }
+        if ($this->mode & PEAR_ERROR_CALLBACK) {
+            if (is_callable($this->callback)) {
+                call_user_func($this->callback, $this);
+            }
+        }
+        if ($this->mode & PEAR_ERROR_EXCEPTION) {
+            trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_ErrorStack for exceptions", E_USER_WARNING);
+            eval('$e = new Exception($this->message, $this->code);$e->PEAR_Error = $this;throw($e);');
+        }
+    }
+
+    // }}}
+    // {{{ getMode()
+
+    /**
+     * Get the error mode from an error object.
+     *
+     * @return int error mode
+     * @access public
+     */
+    function getMode() {
+        return $this->mode;
+    }
+
+    // }}}
+    // {{{ getCallback()
+
+    /**
+     * Get the callback function/method from an error object.
+     *
+     * @return mixed callback function or object/method array
+     * @access public
+     */
+    function getCallback() {
+        return $this->callback;
+    }
+
+    // }}}
+    // {{{ getMessage()
+
+
+    /**
+     * Get the error message from an error object.
+     *
+     * @return  string  full error message
+     * @access public
+     */
+    function getMessage()
+    {
+        return ($this->error_message_prefix . $this->message);
+    }
+
+
+    // }}}
+    // {{{ getCode()
+
+    /**
+     * Get error code from an error object
+     *
+     * @return int error code
+     * @access public
+     */
+     function getCode()
+     {
+        return $this->code;
+     }
+
+    // }}}
+    // {{{ getType()
+
+    /**
+     * Get the name of this error/exception.
+     *
+     * @return string error/exception name (type)
+     * @access public
+     */
+    function getType()
+    {
+        return get_class($this);
+    }
+
+    // }}}
+    // {{{ getUserInfo()
+
+    /**
+     * Get additional user-supplied information.
+     *
+     * @return string user-supplied information
+     * @access public
+     */
+    function getUserInfo()
+    {
+        return $this->userinfo;
+    }
+
+    // }}}
+    // {{{ getDebugInfo()
+
+    /**
+     * Get additional debug information supplied by the application.
+     *
+     * @return string debug information
+     * @access public
+     */
+    function getDebugInfo()
+    {
+        return $this->getUserInfo();
+    }
+
+    // }}}
+    // {{{ getBacktrace()
+
+    /**
+     * Get the call backtrace from where the error was generated.
+     * Supported with PHP 4.3.0 or newer.
+     *
+     * @param int $frame (optional) what frame to fetch
+     * @return array Backtrace, or NULL if not available.
+     * @access public
+     */
+    function getBacktrace($frame = null)
+    {
+        if ($frame === null) {
+            return $this->backtrace;
+        }
+        return $this->backtrace[$frame];
+    }
+
+    // }}}
+    // {{{ addUserInfo()
+
+    function addUserInfo($info)
+    {
+        if (empty($this->userinfo)) {
+            $this->userinfo = $info;
+        } else {
+            $this->userinfo .= " ** $info";
+        }
+    }
+
+    // }}}
+    // {{{ toString()
+
+    /**
+     * Make a string representation of this object.
+     *
+     * @return string a string with an object summary
+     * @access public
+     */
+    function toString() {
+        $modes = array();
+        $levels = array(E_USER_NOTICE  => 'notice',
+                        E_USER_WARNING => 'warning',
+                        E_USER_ERROR   => 'error');
+        if ($this->mode & PEAR_ERROR_CALLBACK) {
+            if (is_array($this->callback)) {
+                $callback = (is_object($this->callback[0]) ?
+                    strtolower(get_class($this->callback[0])) :
+                    $this->callback[0]) . '::' .
+                    $this->callback[1];
+            } else {
+                $callback = $this->callback;
+            }
+            return sprintf('[%s: message="%s" code=%d mode=callback '.
+                           'callback=%s prefix="%s" info="%s"]',
+                           strtolower(get_class($this)), $this->message, $this->code,
+                           $callback, $this->error_message_prefix,
+                           $this->userinfo);
+        }
+        if ($this->mode & PEAR_ERROR_PRINT) {
+            $modes[] = 'print';
+        }
+        if ($this->mode & PEAR_ERROR_TRIGGER) {
+            $modes[] = 'trigger';
+        }
+        if ($this->mode & PEAR_ERROR_DIE) {
+            $modes[] = 'die';
+        }
+        if ($this->mode & PEAR_ERROR_RETURN) {
+            $modes[] = 'return';
+        }
+        return sprintf('[%s: message="%s" code=%d mode=%s level=%s '.
+                       'prefix="%s" info="%s"]',
+                       strtolower(get_class($this)), $this->message, $this->code,
+                       implode("|", $modes), $levels[$this->level],
+                       $this->error_message_prefix,
+                       $this->userinfo);
+    }
+
+    // }}}
+}
+
+/*
+ * Local Variables:
+ * mode: php
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
+?>
diff --git a/phpconf/inc/radius.inc b/phpconf/inc/radius.inc
new file mode 100644 (file)
index 0000000..842cd2a
--- /dev/null
@@ -0,0 +1,1094 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+/*
+Copyright (c) 2003, Michael Bretterklieber <michael@bretterklieber.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without 
+modification, are permitted provided that the following conditions 
+are met:
+
+1. Redistributions of source code must retain the above copyright 
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright 
+   notice, this list of conditions and the following disclaimer in the 
+   documentation and/or other materials provided with the distribution.
+3. The names of the authors may not be used to endorse or promote products 
+   derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This code cannot simply be copied and put under the GNU Public License or 
+any other GPL-like (LGPL, GPL2) License.
+
+    $Id: RADIUS.php,v 1.5 2004/03/25 15:48:40 mbretter Exp $
+
+    This version of RADIUS.php has been modified by
+    Jonathan De Graeve <jonathan@imelda.be> to integrate with M0n0wall <http://www.m0n0.ch/wall>
+
+    $Id_jdg: 2005/12/22 14:22:42
+
+    Changes made include:
+    * StandardAttributes for M0n0wall use
+    * Removed internal Session-Id creation
+    * Adding of ReplyMessage to getAttributes()
+    * Adding of listAttributes()
+    * Adding of VENDOR Bay Networks (Nortel)
+    * Adding of VENDOR Nomadix
+    * Adding of VENDOR WISPr (Wi-Fi Alliance)
+    
+*/
+
+require_once("pear.inc");
+
+/**
+* Client implementation of RADIUS. This are wrapper classes for
+* the RADIUS PECL. 
+* Provides RADIUS Authentication (RFC2865) and RADIUS Accounting (RFC2866).
+*
+* @package Auth_RADIUS
+* @author  Michael Bretterklieber <michael@bretterklieber.com>
+* @access  public
+* @version $Revision: 1.5 $
+*/
+
+PEAR::loadExtension('radius');
+
+/**
+ * class Auth_RADIUS
+ *
+ * Abstract base class for RADIUS
+ *
+ * @package Auth_RADIUS 
+ */
+class Auth_RADIUS extends PEAR {
+
+    /**
+     * List of RADIUS servers.
+     * @var  array
+     * @see  addServer(), putServer()
+     */
+    var $_servers  = array();
+    
+    /**
+     * Path to the configuration-file.
+     * @var  string
+     * @see  setConfigFile()
+     */
+    var $_configfile = null;
+    
+    /**
+     * Resource.
+     * @var  resource
+     * @see  open(), close()
+     */
+    var $res = null;
+    
+    /**
+     * Username for authentication and accounting requests.
+     * @var  string
+     */
+    var $username = null;
+
+    /**
+     * Password for plaintext-authentication (PAP).
+     * @var  string
+     */
+    var $password = null;
+
+    /**
+     * List of known attributes.
+     * @var  array
+     * @see  dumpAttributes(), getAttributes()
+     */
+    var $attributes = array();
+    
+    /**
+     * List of raw attributes.
+     * @var  array
+     * @see  dumpAttributes(), getAttributes()
+     */
+    var $rawAttributes = array();
+
+    /**
+     * List of raw vendor specific attributes.
+     * @var  array
+     * @see  dumpAttributes(), getAttributes()
+     */
+    var $rawVendorAttributes = array();    
+    
+    /**
+     * Constructor
+     *
+     * Loads the RADIUS PECL/extension
+     *
+     * @return void
+     */
+    function Auth_RADIUS() 
+    {
+        $this->PEAR();
+    }
+    
+    /**
+     * Adds a RADIUS server to the list of servers for requests.
+     *
+     * At most 10 servers may be specified.    When multiple servers 
+     * are given, they are tried in round-robin fashion until a 
+     * valid response is received
+     *
+     * @access public
+     * @param  string  $servername   Servername or IP-Address
+     * @param  integer $port         Portnumber
+     * @param  string  $sharedSecret Shared secret
+     * @param  integer $timeout      Timeout for each request
+     * @param  integer $maxtries     Max. retries for each request          
+     * @return void
+     */
+    function addServer($servername = 'localhost', $port = 0, $sharedSecret = 'testing123', $timeout = 5, $maxtries = 3) 
+    {
+        $this->_servers[] = array($servername, $port, $sharedSecret, $timeout, $maxtries);    
+    }
+    
+    /**
+     * Returns an error message, if an error occurred.
+     *
+     * @access public
+     * @return string
+     */
+    function getError() 
+    {
+        return radius_strerror($this->res);
+    }
+    
+    /**
+     * Sets the configuration-file.
+     *
+     * @access public
+     * @param  string  $file Path to the configuration file    
+     * @return void
+     */    
+    function setConfigfile($file) 
+    {
+        $this->_configfile = $file;
+    }
+
+    /**
+     * Puts an attribute.
+     *
+     * @access public
+     * @param  integer $attrib       Attribute-number
+     * @param  mixed   $port         Attribute-value
+     * @param  type    $type         Attribute-type
+     * @return bool  true on success, false on error
+     */    
+    function putAttribute($attrib, $value, $type = null) 
+    {
+        if ($type == null) {
+            $type = gettype($value);
+        }
+
+        switch ($type) {
+        case 'integer':
+            return radius_put_int($this->res, $attrib, $value);
+        
+        case 'addr':
+            return radius_put_addr($this->res, $attrib, $value);
+            
+        case 'string':
+        default:
+            return radius_put_attr($this->res, $attrib, $value);
+        }
+
+    }
+    
+    /**
+     * Puts a vendor-specific attribute.
+     *
+     * @access public
+     * @param  integer $vendor       Vendor (MSoft, Cisco, ...)
+     * @param  integer $attrib       Attribute-number
+     * @param  mixed   $port         Attribute-value
+     * @param  type    $type         Attribute-type
+     * @return bool  true on success, false on error
+     */ 
+    function putVendorAttribute($vendor, $attrib, $value, $type = null) 
+    {
+        
+        if ($type == null) {
+            $type = gettype($value);
+        }
+        
+        switch ($type) {
+        case 'integer':
+            return radius_put_vendor_int($this->res, $vendor, $attrib, $value);
+        
+        case 'addr':
+            return radius_put_vendor_addr($this->res, $vendor,$attrib, $value);
+            
+        case 'string':
+        default:
+            return radius_put_vendor_attr($this->res, $vendor, $attrib, $value);
+        }
+        
+    }    
+
+    /**
+     * Prints known attributes received from the server.
+     *
+     * @access public
+     */     
+    function dumpAttributes()
+    {
+        foreach ($this->attributes as $name => $data) {
+            echo "$name:$data<br>\n";
+        }
+    }
+
+    /**
+     * Return our know attributes array received from the server.
+     *
+     * @access public
+     */
+    function listAttributes()
+    {
+        return $this->attributes;
+    }
+
+    /**
+     * Overwrite this. 
+     *
+     * @access public
+     */         
+    function open() 
+    {
+    }
+
+    /**
+     * Overwrite this.
+     *
+     * @access public
+     */         
+    function createRequest()
+    {
+    }
+    
+    /**
+     * Puts standard attributes.
+     *
+     * @access public
+     */ 
+    function putStandardAttributes()
+    {
+        $this->putAttribute(RADIUS_NAS_PORT_TYPE, RADIUS_ETHERNET);
+        $this->putAttribute(RADIUS_SERVICE_TYPE, RADIUS_LOGIN);
+    }
+    
+    /**
+     * Puts custom attributes.
+     *
+     * @access public
+     */ 
+    function putAuthAttributes()
+    {
+        if (isset($this->username)) {
+            $this->putAttribute(RADIUS_USER_NAME, $this->username);        
+        }
+    }
+    
+    /**
+     * Configures the radius library.
+     *
+     * @access public
+     * @param  string  $servername   Servername or IP-Address
+     * @param  integer $port         Portnumber
+     * @param  string  $sharedSecret Shared secret
+     * @param  integer $timeout      Timeout for each request
+     * @param  integer $maxtries     Max. retries for each request          
+     * @return bool  true on success, false on error
+     * @see addServer()
+     */      
+    function putServer($servername, $port = 0, $sharedsecret = 'testing123', $timeout = 3, $maxtries = 3) 
+    {
+        if (!radius_add_server($this->res, $servername, $port, $sharedsecret, $timeout, $maxtries)) {
+            return false;
+        }
+        return true;
+    }
+    
+    /**
+     * Configures the radius library via external configurationfile
+     *
+     * @access public
+     * @param  string  $servername   Servername or IP-Address
+     * @return bool  true on success, false on error
+     */      
+    function putConfigfile($file) 
+    {
+        if (!radius_config($this->res, $file)) {
+            return false;
+        }
+        return true;
+    }    
+        
+    /**
+     * Initiates a RADIUS request. 
+     *
+     * @access public
+     * @return bool  true on success, false on errors     
+     */ 
+    function start()
+    {
+        if (!$this->open()) {
+            return false;
+        }
+        
+        foreach ($this->_servers as $s) {
+               // Servername, port, sharedsecret, timeout, retries
+            if (!$this->putServer($s[0], $s[1], $s[2], $s[3], $s[4])) {
+                return false;
+            }
+        }
+        
+        if (!empty($this->_configfile)) {
+            if (!$this->putConfigfile($this->_configfile)) {
+                return false;
+            }
+        }
+        
+        $this->createRequest();
+       $this->putStandardAttributes();
+        $this->putAuthAttributes();
+        return true;
+    }
+    
+    /**
+     * Sends a prepared RADIUS request and waits for a response
+     *
+     * @access public
+     * @return mixed  true on success, false on reject, PEAR_Error on error
+     */ 
+    function send()
+    {
+        $req = radius_send_request($this->res);
+        if (!$req) {
+            return $this->raiseError('Error sending request: ' . $this->getError());
+        }
+
+        switch($req) {
+        case RADIUS_ACCESS_ACCEPT:
+            if (is_subclass_of($this, 'auth_radius_acct')) {
+                return $this->raiseError('RADIUS_ACCESS_ACCEPT is unexpected for accounting');
+            }
+            return true;
+
+        case RADIUS_ACCESS_REJECT:
+            return false;
+            
+        case RADIUS_ACCOUNTING_RESPONSE:
+            if (is_subclass_of($this, 'auth_radius_pap')) {
+                return $this->raiseError('RADIUS_ACCOUNTING_RESPONSE is unexpected for authentication');
+            }
+            return true;
+
+        default:
+            return $this->raiseError("Unexpected return value: $req");
+        }    
+        
+    }
+
+    /**
+     * Reads all received attributes after sending the request.
+     *
+     * This methos stores know attributes in the property attributes, 
+     * all attributes (including known attibutes) are stored in rawAttributes 
+     * or rawVendorAttributes.
+     * NOTE: call this functio also even if the request was rejected, because the 
+     * Server returns usualy an errormessage
+     *
+     * @access public
+     * @return bool   true on success, false on error
+     */     
+    function getAttributes()
+    {
+
+        while ($attrib = radius_get_attr($this->res)) {
+
+            if (!is_array($attrib)) {
+                return false;
+            }        
+
+            $attr = $attrib['attr'];
+            $data = $attrib['data'];
+
+            $this->rawAttributes[$attr] = $data;
+
+            switch ($attr) {
+            case RADIUS_FRAMED_IP_ADDRESS:
+                $this->attributes['framed_ip'] = radius_cvt_addr($data);
+                break;
+
+            case RADIUS_FRAMED_IP_NETMASK:
+                $this->attributes['framed_mask'] = radius_cvt_addr($data);
+                break;
+
+            case RADIUS_FRAMED_MTU:
+                $this->attributes['framed_mtu'] = radius_cvt_int($data);
+                break;
+
+            case RADIUS_FRAMED_COMPRESSION:
+                $this->attributes['framed_compression'] = radius_cvt_int($data);
+                break;
+
+            case RADIUS_SESSION_TIMEOUT:
+                $this->attributes['session_timeout'] = radius_cvt_int($data);
+                break;
+
+            case RADIUS_IDLE_TIMEOUT:
+                $this->attributes['idle_timeout'] = radius_cvt_int($data);
+                break;
+
+            case RADIUS_SERVICE_TYPE:
+                $this->attributes['service_type'] = radius_cvt_int($data);
+                break;
+
+            case RADIUS_CLASS:
+                $this->attributes['class'] = radius_cvt_int($data);
+                break;
+
+            case RADIUS_FRAMED_PROTOCOL:
+                $this->attributes['framed_protocol'] = radius_cvt_int($data);
+                break;
+
+            case RADIUS_FRAMED_ROUTING:
+                $this->attributes['framed_routing'] = radius_cvt_int($data);
+                break;
+
+            case RADIUS_FILTER_ID:
+                $this->attributes['filter_id'] = radius_cvt_string($data);
+                break;
+
+            case RADIUS_REPLY_MESSAGE:
+                $this->attributes['reply_message'] = radius_cvt_string($data);
+                break;
+
+            case RADIUS_VENDOR_SPECIFIC:
+                $attribv = radius_get_vendor_attr($data);
+                if (!is_array($attribv)) {
+                    return false;
+                }
+                    
+                $vendor = $attribv['vendor'];
+                $attrv = $attribv['attr'];
+                $datav = $attribv['data'];
+                
+                $this->rawVendorAttributes[$vendor][$attrv] = $datav;
+
+                if ($vendor == RADIUS_VENDOR_MICROSOFT) {
+
+                    switch ($attrv) {
+                    case RADIUS_MICROSOFT_MS_CHAP2_SUCCESS:
+                        $this->attributes['ms_chap2_success'] = radius_cvt_string($datav);
+                        break;
+
+                    case RADIUS_MICROSOFT_MS_CHAP_ERROR:
+                        $this->attributes['ms_chap_error'] = radius_cvt_string(substr($datav,1));
+                        break;
+
+                    case RADIUS_MICROSOFT_MS_CHAP_DOMAIN:
+                        $this->attributes['ms_chap_domain'] = radius_cvt_string($datav);
+                        break;
+
+                    case RADIUS_MICROSOFT_MS_MPPE_ENCRYPTION_POLICY:
+                        $this->attributes['ms_mppe_encryption_policy'] = radius_cvt_int($datav);
+                        break;
+
+                    case RADIUS_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES:
+                        $this->attributes['ms_mppe_encryption_types'] = radius_cvt_int($datav);
+                        break;
+
+                    case RADIUS_MICROSOFT_MS_CHAP_MPPE_KEYS:
+                        $demangled = radius_demangle($this->res, $datav);
+                        $this->attributes['ms_chap_mppe_lm_key'] = substr($demangled, 0, 8);
+                        $this->attributes['ms_chap_mppe_nt_key'] = substr($demangled, 8, RADIUS_MPPE_KEY_LEN);
+                        break;
+
+                    case RADIUS_MICROSOFT_MS_MPPE_SEND_KEY:
+                        $this->attributes['ms_chap_mppe_send_key'] = radius_demangle_mppe_key($this->res, $datav);
+                        break;
+
+                    case RADIUS_MICROSOFT_MS_MPPE_RECV_KEY:
+                        $this->attributes['ms_chap_mppe_recv_key'] = radius_demangle_mppe_key($this->res, $datav);
+                        break;
+
+                    case RADIUS_MICROSOFT_MS_PRIMARY_DNS_SERVER:
+                        $this->attributes['ms_primary_dns_server'] = radius_cvt_string($datav);
+                        break;
+                    }
+                }
+
+                if ($vendor == RADIUS_VENDOR_BAY) {
+
+                    switch ($attrv) {
+                    case RADIUS_BAY_CES_GROUP:
+                        $this->attributes['ces_group'] = radius_cvt_string($datav);
+                        break;
+                    }
+                }
+
+                if ($vendor == 3309) { /* RADIUS_VENDOR_NOMADIX */
+
+                    switch ($attrv) {
+                    case 1: /* RADIUS_NOMADIX_BW_UP */
+                        $this->attributes['bw_up'] = radius_cvt_int($datav);
+                        break;
+                    case 2: /* RADIUS_NOMADIX_BW_DOWN */
+                        $this->attributes['bw_down'] = radius_cvt_int($datav);
+                        break;
+                    case 3: /* RADIUS_NOMADIX_URL_REDIRECTION */
+                        $this->attributes['url_redirection'] = radius_cvt_string($datav);
+                        break;
+                    case 5: /* RADIUS_NOMADIX_EXPIRATION */
+                        $this->attributes['expiration'] = radius_cvt_string($datav);
+                        break;
+                    case 7: /* RADIUS_NOMADIX_MAXBYTESUP */
+                        $this->attributes['maxbytesup'] = radius_cvt_int($datav);
+                        break;
+                    case 8: /* RADIUS_NOMADIX_MAXBYTESDOWN */
+                        $this->attributes['maxbytesdown'] = radius_cvt_int($datav);
+                        break;
+                    case 10: /* RADIUS_NOMADIX_LOGOFF_URL */
+                        $this->attributes['url_logoff'] = radius_cvt_string($datav);
+                        break;
+                    }
+                } 
+
+               if ($vendor == 14122) { /* RADIUS_VENDOR_WISPr Wi-Fi Alliance */
+
+                   switch ($attrv) {
+                   case 1: /* WISPr-Location-ID */
+                       $this->attributes['location_id'] = radius_cvt_string($datav);
+                       break;
+                   case 2: /* WISPr-Location-Name */
+                       $this->attributes['location_name'] = radius_cvt_string($datav);
+                       break;
+                   case 3: /* WISPr-Logoff-URL */
+                       $this->attributes['url_logoff'] = radius_cvt_string($datav);
+                       break;
+                   case 4: /* WISPr-Redirection-URL */
+                       $this->attributes['url_redirection'] = radius_cvt_string($datav);
+                       break;
+                   case 5: /* WISPr-Bandwidth-Min-Up */
+                       $this->attributes['bw_minbytesup'] = radius_cvt_int($datav);
+                       break;
+                   case 6: /* WISPr-Bandwidth-Min-Down */
+                       $this->attributes['bw_minbytesdown'] = radius_cvt_int($datav);
+                       break;
+                   case 7: /* WIPSr-Bandwidth-Max-Up */
+                       $this->attributes['bw_maxbytesup'] = radius_cvt_int($datav);
+                       break;
+                   case 8: /* WISPr-Bandwidth-Max-Down */
+                       $this->attributes['bw_maxbytesdown'] = radius_cvt_int($datav);
+                       break;
+                   case 9: /* WISPr-Session-Terminate-Time */
+                       $this->attributes['session_terminate_time'] = radius_cvt_string($datav);
+                       break;
+                   case 10: /* WISPr-Session-Terminate-End-Of-Day */
+                       $this->attributes['session_terminate_endofday'] = radius_cvt_int($datav);
+                       break;
+                   case 11: /* WISPr-Billing-Class-Of-Service */
+                       $this->attributes['billing_class_of_service'] = radius_cvt_string($datav);
+                       break;
+                  }
+               }
+
+                break;
+                
+            }
+        }    
+
+        return true;
+    }
+    
+    /**
+     * Frees resources.
+     *
+     * Calling this method is always a good idea, because all security relevant
+     * attributes are filled with Nullbytes to leave nothing in the mem.
+     *
+     * @access public
+     */   
+    function close()
+    {
+        if ($this->res != null) {
+            radius_close($this->res);
+            $this->res = null;
+        }
+        $this->username = str_repeat("\0", strlen($this->username));
+        $this->password = str_repeat("\0", strlen($this->password));
+    }
+    
+}
+
+/**
+ * class Auth_RADIUS_PAP
+ *
+ * Class for authenticating using PAP (Plaintext)
+ * 
+ * @package Auth_RADIUS 
+ */
+class Auth_RADIUS_PAP extends Auth_RADIUS 
+{
+
+    /**
+     * Constructor
+     *
+     * @param  string  $username   Username
+     * @param  string  $password   Password
+     * @return void
+     */
+    function Auth_RADIUS_PAP($username = null, $password = null)
+    {
+        $this->Auth_RADIUS();
+        $this->username = $username;
+        $this->password = $password;
+    }
+    
+    /**
+     * Creates a RADIUS resource
+     *
+     * Creates a RADIUS resource for authentication. This should be the first
+     * call before you make any other things with the library.
+     *
+     * @return bool   true on success, false on error
+     */
+    function open() 
+    {
+        $this->res = radius_auth_open();
+        if (!$this->res) {
+            return false;
+        }
+        return true;
+    }
+    
+    /**
+     * Creates an authentication request 
+     *
+     * Creates an authentication request.
+     * You MUST call this method before you can put any attribute
+     *
+     * @return bool   true on success, false on error
+     */
+    function createRequest()
+    {
+        if (!radius_create_request($this->res, RADIUS_ACCESS_REQUEST)) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Put authentication specific attributes 
+     *
+     * @return void
+     */
+    function putAuthAttributes()
+    {
+        if (isset($this->username)) {
+            $this->putAttribute(RADIUS_USER_NAME, $this->username);        
+        }
+        if (isset($this->password)) {
+            $this->putAttribute(RADIUS_USER_PASSWORD, $this->password);
+        }
+    }
+
+}
+
+/**
+ * class Auth_RADIUS_CHAP_MD5
+ *
+ * Class for authenticating using CHAP-MD5 see RFC1994.
+ * Instead og the plaintext password the challenge and 
+ * the response are needed.
+ * 
+ * @package Auth_RADIUS 
+ */
+class Auth_RADIUS_CHAP_MD5 extends Auth_RADIUS_PAP
+{
+    /**
+     * 8 Bytes binary challenge
+     * @var  string
+     */
+    var $challenge = null;
+
+    /**
+     * 16 Bytes MD5 response binary
+     * @var  string
+     */
+    var $response = null;
+    
+    /**
+     * Id of the authentication request. Should incremented after every request.
+     * @var  integer
+     */
+    var $chapid = 1;
+    
+    /**
+     * Constructor
+     *
+     * @param  string  $username   Username
+     * @param  string  $challenge  8 Bytes Challenge (binary)
+     * @param  integer $chapid     Requestnumber
+     * @return void
+     */
+    function Auth_RADIUS_CHAP_MD5($username = null, $challenge = null, $chapid = 1)
+    {
+        $this->Auth_RADIUS_PAP();
+        $this->username = $username;
+        $this->challenge = $challenge;
+        $this->chapid = $chapid;
+    }
+    
+    /**
+     * Put CHAP-MD5 specific attributes
+     *
+     * For authenticating using CHAP-MD5 via RADIUS you have to put the challenge 
+     * and the response. The chapid is inserted in the first byte of the response.
+     *
+     * @return void
+     */
+    function putAuthAttributes()
+    {
+        if (isset($this->username)) {
+            $this->putAttribute(RADIUS_USER_NAME, $this->username);        
+        }
+        if (isset($this->response)) {
+            $response = pack('C', $this->chapid) . $this->response;
+            $this->putAttribute(RADIUS_CHAP_PASSWORD, $response);
+        }
+        if (isset($this->challenge)) {
+            $this->putAttribute(RADIUS_CHAP_CHALLENGE, $this->challenge);
+        }
+    }
+    
+    /**
+     * Frees resources.
+     *
+     * Calling this method is always a good idea, because all security relevant
+     * attributes are filled with Nullbytes to leave nothing in the mem.
+     *
+     * @access public
+     */   
+    function close()
+    {
+        Auth_RADIUS_PAP::close();
+        $this->challenge =  str_repeat("\0", strlen($this->challenge));
+        $this->response =  str_repeat("\0", strlen($this->response));
+    }    
+    
+}
+
+/**
+ * class Auth_RADIUS_MSCHAPv1
+ *
+ * Class for authenticating using MS-CHAPv1 see RFC2433
+ * 
+ * @package Auth_RADIUS 
+ */
+class Auth_RADIUS_MSCHAPv1 extends Auth_RADIUS_CHAP_MD5 
+{
+    /**
+     * LAN-Manager-Response
+     * @var  string
+     */
+    var $lmResponse = null;
+
+    /**
+     * Wether using deprecated LM-Responses or not.
+     * 0 = use LM-Response, 1 = use NT-Response
+     * @var  bool
+     */
+    var $flags = 1;
+    
+    /**
+     * Put MS-CHAPv1 specific attributes 
+     *
+     * For authenticating using MS-CHAPv1 via RADIUS you have to put the challenge 
+     * and the response. The response has this structure:
+     * struct rad_mschapvalue {
+     *   u_char ident;
+     *   u_char flags;
+     *   u_char lm_response[24];
+     *   u_char response[24];
+     * };
+     * 
+     * @return void
+     */
+    function putAuthAttributes()
+    {
+        if (isset($this->username)) {
+            $this->putAttribute(RADIUS_USER_NAME, $this->username);        
+        }
+        if (isset($this->response) || isset($this->lmResponse)) {
+            $lmResp = isset($this->lmResponse) ? $this->lmResponse : str_repeat ("\0", 24);
+            $ntResp = isset($this->response)   ? $this->response :   str_repeat ("\0", 24);
+            $resp = pack('CC', $this->chapid, $this->flags) . $lmResp . $ntResp;
+            $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_RESPONSE, $resp);
+        }
+        if (isset($this->challenge)) {        
+            $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_CHALLENGE, $this->challenge);
+        }
+    }    
+}
+
+/**
+ * class Auth_RADIUS_MSCHAPv2
+ *
+ * Class for authenticating using MS-CHAPv2 see RFC2759
+ * 
+ * @package Auth_RADIUS 
+ */
+class Auth_RADIUS_MSCHAPv2 extends Auth_RADIUS_MSCHAPv1 
+{
+    /**
+     * 16 Bytes binary challenge
+     * @var  string
+     */
+    var $challenge = null;
+    
+    /**
+     * 16 Bytes binary Peer Challenge
+     * @var  string
+     */
+    var $peerChallenge = null;
+
+  /**
+     * Put MS-CHAPv2 specific attributes 
+     *
+     * For authenticating using MS-CHAPv1 via RADIUS you have to put the challenge 
+     * and the response. The response has this structure:
+     * struct rad_mschapv2value {
+     *   u_char ident;
+     *   u_char flags;
+     *   u_char pchallenge[16];
+     *   u_char reserved[8];
+     *   u_char response[24];
+     * };
+     * where pchallenge is the peer challenge. Like for MS-CHAPv1 we set the flags field to 1.
+     * @return void
+     */    
+    function putAuthAttributes()
+    {
+        if (isset($this->username)) {
+            $this->putAttribute(RADIUS_USER_NAME, $this->username);        
+        }
+        if (isset($this->response) && isset($this->peerChallenge)) {
+            // Response: chapid, flags (1 = use NT Response), Peer challenge, reserved, Response        
+            $resp = pack('CCa16a8a24',$this->chapid , 1, $this->peerChallenge, str_repeat("\0", 8), $this->response);        
+            $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP2_RESPONSE, $resp);
+        }
+        if (isset($this->challenge)) {
+            $this->putVendorAttribute(RADIUS_VENDOR_MICROSOFT, RADIUS_MICROSOFT_MS_CHAP_CHALLENGE, $this->challenge);
+        }
+    }    
+    
+    /**
+     * Frees resources.
+     *
+     * Calling this method is always a good idea, because all security relevant
+     * attributes are filled with Nullbytes to leave nothing in the mem.
+     *
+     * @access public
+     */   
+    function close()
+    {
+        Auth_RADIUS_MSCHAPv1::close();
+        $this->peerChallenge = str_repeat("\0", strlen($this->peerChallenge));
+    }       
+}
+
+/**
+ * class Auth_RADIUS_Acct
+ *
+ * Class for RADIUS accounting
+ * 
+ * @package Auth_RADIUS 
+ */
+class Auth_RADIUS_Acct extends Auth_RADIUS 
+{
+    /**
+     * Defines where the Authentication was made, possible values are:
+     * RADIUS_AUTH_RADIUS, RADIUS_AUTH_LOCAL, RADIUS_AUTH_REMOTE
+     * @var  integer
+     */
+    var $authentic = null;
+
+   /**
+     * Defines the type of the accounting request, on of:
+     * RADIUS_START, RADIUS_STOP, RADIUS_ACCOUNTING_ON, RADIUS_ACCOUNTING_OFF
+     * @var  integer
+     */    
+    var $status_type = null;
+
+   /**
+     * The time the user was logged in in seconds
+     * @var  integer
+     */    
+    var $session_time = null;
+
+   /**
+     * A uniq identifier for the session of the user, maybe the PHP-Session-Id
+     * @var  string
+     */    
+    var $session_id = null;
+    
+    /**
+     * Constructor
+     *
+     * This function is disabled for M0n0wall since we use our own session_id
+     *
+     * Generates a predefined session_id. We use the Remote-Address, the PID, and the Current user.
+     * @return void
+     *
+    function Auth_RADIUS_Acct()
+    {
+        $this->Auth_RADIUS();
+        
+        if (isset($_SERVER)) {
+            $var = &$_SERVER;
+        } else {
+            $var = &$GLOBALS['HTTP_SERVER_VARS'];
+        }
+
+        $this->session_id = sprintf("%s:%d-%s", isset($var['REMOTE_ADDR']) ? $var['REMOTE_ADDR'] : '127.0.0.1' , getmypid(), get_current_user());
+    }
+    */
+
+    /**
+     * Constructor
+     *
+     */
+
+    function Auth_RADIUS_Acct()
+    {
+        $this->Auth_RADIUS();
+    }
+
+    /**
+     * Creates a RADIUS resource
+     *
+     * Creates a RADIUS resource for accounting. This should be the first
+     * call before you make any other things with the library.
+     *
+     * @return bool   true on success, false on error
+     */
+    function open() 
+    {
+        $this->res = radius_acct_open();
+        if (!$this->res) {
+            return false;
+        }
+        return true;
+    }
+
+   /**
+     * Creates an accounting request 
+     *
+     * Creates an accounting request.
+     * You MUST call this method before you can put any attribute.
+     *
+     * @return bool   true on success, false on error
+     */
+    function createRequest()
+    {
+        if (!radius_create_request($this->res, RADIUS_ACCOUNTING_REQUEST)) {
+            return false;
+        }
+        return true;
+    }   
+   
+  /**
+     * Put attributes for accounting.
+     *
+     * Here we put some accounting values. There many more attributes for accounting, 
+     * but for web-applications only certain attributes make sense.
+     * @return void
+     */ 
+    function putAuthAttributes()
+    {
+        $this->putAttribute(RADIUS_ACCT_SESSION_ID, $this->session_id);
+        $this->putAttribute(RADIUS_ACCT_STATUS_TYPE, $this->status_type);
+        if (isset($this->session_time) && $this->status_type == RADIUS_STOP) {
+            $this->putAttribute(RADIUS_ACCT_SESSION_TIME, $this->session_time);
+        }
+        if (isset($this->authentic)) {
+            $this->putAttribute(RADIUS_ACCT_AUTHENTIC, $this->authentic);
+        }
+        
+    }    
+    
+}
+
+/**
+ * class Auth_RADIUS_Acct_Start
+ *
+ * Class for RADIUS accounting. Its usualy used, after the user has logged in.
+ * 
+ * @package Auth_RADIUS
+ */
+class Auth_RADIUS_Acct_Start extends Auth_RADIUS_Acct 
+{
+   /**
+     * Defines the type of the accounting request.
+     * It is set to RADIUS_START by default in this class.
+     * @var  integer
+     */    
+    var $status_type = RADIUS_START;
+}
+
+/**
+ * class Auth_RADIUS_Acct_Start
+ *
+ * Class for RADIUS accounting. Its usualy used, after the user has logged out.
+ *
+ * @package Auth_RADIUS
+ */
+class Auth_RADIUS_Acct_Stop extends Auth_RADIUS_Acct
+{
+   /**
+     * Defines the type of the accounting request.
+     * It is set to RADIUS_STOP by default in this class.
+     * @var  integer
+     */
+    var $status_type = RADIUS_STOP;
+}
+
+if (!defined('RADIUS_UPDATE'))
+    define('RADIUS_UPDATE', 3);
+
+/**
+ * class Auth_RADIUS_Acct_Update
+ *
+ * Class for interim RADIUS accounting updates.
+ *
+ * @package Auth_RADIUS
+ */
+class Auth_RADIUS_Acct_Update extends Auth_RADIUS_Acct
+{
+   /**
+     * Defines the type of the accounting request.
+     * It is set to RADIUS_UPDATE by default in this class.
+     * @var  integer
+     */
+    var $status_type = RADIUS_UPDATE;
+}
+
+?>
index d27fe6a9cdd6a01588e483cd99e4d488a9606781..94f1ed83441b9321a44b07f4af48679c1c358405 100644 (file)
@@ -3,7 +3,7 @@
        services.inc
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
@@ -418,6 +418,10 @@ rocommunity "{$config['snmpd']['rocommunity']}"
 
 EOD;
 
+               if (isset($config['snmpd']['bindlan'])) {
+                       $snmpdconf .= "agentaddress udp:161@{$config['interfaces']['lan']['ipaddr']}\n";
+               }
+
                fwrite($fd, $snmpdconf);
                fclose($fd);
 
index 9a75edf043f0b588870582d18c54ee57db00a794..30ea1528739f08bfbfbf74e8d6422e0ff69f0e52 100644 (file)
@@ -3,7 +3,7 @@
        shaper.inc
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 4c397b122a70e40b7bd000921a8b0d299f9de2c3..24636d4857cde2da871893a60a31ace51af2715c 100644 (file)
@@ -3,7 +3,7 @@
        system.inc
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index bafc28f425d22765b0d523f8793457b07afbcbfb..ed8f4dd49938b660d53e10f018171b093c0d5c16 100644 (file)
@@ -3,7 +3,7 @@
        util.inc
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
@@ -46,6 +46,11 @@ function killbyname($procname) {
        return mwexec("/usr/bin/killall " . escapeshellarg($procname));
 }
 
+/* kill a process by name */
+function sigkillbyname($procname, $sig) {
+       return mwexec("/usr/bin/killall -{$sig} " . escapeshellarg($procname));
+}
+
 /* return the subnet address given a host address and a subnet bit count */
 function gen_subnet($ipaddr, $bits) {
        if (!is_ipaddr($ipaddr) || !is_numeric($bits))
index b89f2392363b9a2e266a12189a06fdc4e2f99d91..6716485819a7c071f95f79073eb3b76410209f4d 100644 (file)
@@ -3,7 +3,7 @@
        vpn.inc
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
@@ -50,13 +50,13 @@ function vpn_ipsec_configure($ipchg = false) {
                echo "Configuring IPsec VPN... ";
        } else {
                /* kill racoon */
-               killbypid("{$g['varrun_path']}/racoon.pid");
+               killbyname("racoon");
                
                /* wait for process to die */
                sleep(2);
                
                /* send a SIGKILL to be sure */
-               sigkillbypid("{$g['varrun_path']}/racoon.pid", "KILL");
+               sigkillbyname("racoon", "KILL");
        }
        
        /* flush SPD and SAD */
index a6067b45ecb60a6dd92fadd6bbad68b6516c606a..e66b65661b1bcf8a337bc1b4a9322f55a57916bf 100644 (file)
@@ -4,7 +4,7 @@
        functions to parse/dump configuration files in XML format
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
@@ -33,7 +33,7 @@
 $listtags = explode(" ", "rule user key dnsserver winsserver " .
        "encryption-algorithm-option hash-algorithm-option hosts tunnel onetoone " .
        "staticmap route alias pipe queue shellcmd cacert earlyshellcmd mobilekey " .
-       "servernat proxyarpnet passthrumac allowedip wolentry vlan domainoverrides");
+       "servernat proxyarpnet passthrumac allowedip wolentry vlan domainoverrides element");
 
 function startElement($parser, $name, $attrs) {
        global $depth, $curpath, $config, $havedata, $listtags;
@@ -139,6 +139,8 @@ function parse_xml_config($cffile, $rootobj) {
                die("XML error: no $rootobj object found!\n");
        }
        
+       fclose($fp);
+       
        return $config[$rootobj];
 }
 
index 6fc23f5f7b4b100b6f6f234d2e124c5c068e789e..d1df62b16fbf2c6588340ec4fbbbc4c956edee9e 100644 (file)
@@ -4,7 +4,7 @@
        rc.banner
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
@@ -41,7 +41,7 @@
 
 *** This is m0n0wall, version {$version}
     built on {$buildtime} for {$g['fullplatform']}
-    Copyright (C) 2002-2005 by Manuel Kasper. All rights reserved.
+    Copyright (C) 2002-2006 by Manuel Kasper. All rights reserved.
     Visit http://m0n0.ch/wall for updates.
     
     
index f3ef1d9b2b03f7b05074f1301d09a3f325f75907..f5ab3e7e7d3b7522d209391d816792e1de230653 100644 (file)
@@ -4,7 +4,7 @@
        rc.bootup
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
diff --git a/phpconf/rc.cleanreboot b/phpconf/rc.cleanreboot
new file mode 100644 (file)
index 0000000..c7051b3
--- /dev/null
@@ -0,0 +1,37 @@
+#!/usr/local/bin/php -f
+<?php
+/*
+       rc.cleanreboot
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require_once("config.inc");
+require_once("functions.inc");
+
+system_reboot_sync();
+
+?>
index c3c30c716fe13f81517587fe16fefaf8407f75b5..2ef0cbf2d6f2ba99d198125af99b4ffb617fe0dc 100644 (file)
@@ -4,7 +4,7 @@
        rc.initial.defaults
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 9d7981155bac04e78e2965ffb95cb2eea4b1d3a9..fb0d1806c70ecc31a1b51bfe5770e110939fec4a 100644 (file)
@@ -4,7 +4,7 @@
        rc.initial.password
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 760a16c48bfcbcad1c22a89311df2323ce2d7bb8..3cca87452373a83ddd6241e8e648d34b2ca5a605 100644 (file)
@@ -4,7 +4,7 @@
        rc.initial.ping
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 5c3b9ef10c51c74313df7c2d44db92eff29e2897..a19d32f53cf1ba63c888d367e5689f35aea9b9fd 100644 (file)
@@ -4,7 +4,7 @@
        rc.initial.reboot
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index a5196ee8cab56ad91b66a52620efac72a8cf6f95..95be1656ea01900798d46c5b7c051ac1f8a7da09 100644 (file)
@@ -4,7 +4,7 @@
        rc.initial.setlanip
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index e08b5746d7878512fb248eab4bac1bd7b7d43bad..edfddc8a8effc380ec96d11cee93ae4d95b8eb52 100644 (file)
@@ -4,7 +4,7 @@
        rc.initial.setports
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 6868cfdc171cdb4928664d0be758eee26ba607e7..28dfb6ab42be4b07d947e3592628d7654052fd6e 100644 (file)
@@ -4,7 +4,7 @@
        rc.newwanip
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 39e7b7e86a3034a775b6b6a52121a8736a8dd0cb..b207a5bc88843e223fe24338c95f1177f8e836c1 100644 (file)
@@ -4,7 +4,7 @@
        rc.prunecaptiveportal
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 0ebe1207d82eabb779290c183d9dfdba171cb3e8..0332d8f34cd81a6b66e40fc097ab1398e8ba18e0 100644 (file)
@@ -4,7 +4,7 @@
        diag_backup.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
@@ -64,7 +64,10 @@ if ($_POST) {
                                        system_reboot();
                                        $savemsg = "The configuration has been restored. The firewall is now rebooting.";
                                } else {
-                                       $input_errors[] = "The configuration could not be restored.";
+                                       $errstr = "The configuration could not be restored.";
+                                       if ($xmlerr)
+                                               $errstr .= " (XML error: $xmlerr)";
+                                       $input_errors[] = $errstr;
                                }
                        } else {
                                $input_errors[] = "The configuration could not be restored (file upload error).";
index cd923021f16a9aa0e6cc5805296ce356a6da2b76..f29d1c57e75af2113d4578e032619b7b9a790418 100644 (file)
@@ -4,7 +4,7 @@
        diag_defaults.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 808badfdeaaa995ddb7111439c4a9e26b1366ec3..62735de8d513e48a1528abef961a6c2a41af2385 100644 (file)
@@ -4,7 +4,7 @@
        diag_ipfstat.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2005 Paul Taylor (paultaylor@winndixie.com) and Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2005-2006 Paul Taylor (paultaylor@winndixie.com) and Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 45377be7897716849c49c3c7bd094267b379743f..266992e5b54260f56d26eda4cc03399216b8783b 100644 (file)
@@ -4,7 +4,7 @@
        diag_ipsec_sad.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 74db3997fa9c77edda9d3ace23d24fe0c3582de9..7e591ca4f72f5ffcf5fc2e219370093832117098 100644 (file)
@@ -4,7 +4,7 @@
        diag_ipsec_spd.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index c566b9571bc2ede32f75f66267a38cd947d22077..20b40e3f55c658ffafb9a3df056a29410f94dac6 100644 (file)
@@ -4,7 +4,7 @@
        diag_logs.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index f43433c04021f08cb9991bac428cc54956e32812..5d13c2af213d8903af7853ab638dc486fd36adac 100644 (file)
@@ -4,7 +4,7 @@
        diag_logs_dhcp.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index d6b8ea39702f4a7ecbfbe61b1c0ee831eb4d6113..a04b56e5ce0f250dee09f51adba48eb2ee23e86e 100644 (file)
@@ -4,7 +4,7 @@
        diag_logs_filter.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 6b66e57679ea2005815bcc063ca2cd73dd87f0cc..bec712c9d6c303ee405f5e022d9081c08b98ad90 100644 (file)
@@ -4,7 +4,7 @@
        diag_logs_portal.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index c60f5d09f4dc1d1a4e553d5d5570deba4d54dbbe..10ff40b4b3042007737cc4da46461b7cdab33f6c 100644 (file)
@@ -4,7 +4,7 @@
        diag_logs_settings.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 22b881fb7a18f9e18776d8854b0f5efff55a93ed..470da4afdcb78f82eec82455ac2ef7388586cdf9 100644 (file)
@@ -4,7 +4,7 @@
        diag_logs_vpn.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index f4e6c0a3c3af655d8853bfbaecea7ade4a6a2fc2..56ce8cb5621ccc212a35a43e9bb61496a32e94e0 100644 (file)
@@ -4,7 +4,7 @@
        diag_ping.php
        part of m0n0wall (http://m0n0.ch/wall)
 
-       Copyright (C) 2003-2005 Bob Zoller (bob@kludgebox.com) and Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Bob Zoller (bob@kludgebox.com) and Manuel Kasper <mk@neon1.net>.
        All rights reserved.
 
        Redistribution and use in source and binary forms, with or without
index f55b0afe9f9beb079d4cd27863d34cb832c9acf3..5d4d830ad4c1277fe374e822c32dff196a80fa96 100644 (file)
@@ -4,7 +4,7 @@
        diag_resetstate.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 69a534dbdbd95f7127a9b1fa438416ecbe602706..4be1d9289a19ed345159709bbc83b635c79226ce 100644 (file)
@@ -4,7 +4,7 @@
        diag_traceroute.php
        part of m0n0wall (http://m0n0.ch/wall)
 
-       Copyright (C) 2005 Paul Taylor (paultaylor@winndixie.com) and Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2005-2006 Paul Taylor (paultaylor@winndixie.com) and Manuel Kasper <mk@neon1.net>.
        All rights reserved.
 
        Redistribution and use in source and binary forms, with or without
index bccdc23e9de131b9d86e6e9c4e32e7d6b2df1756..cf97345b7358372563b502e5970005f3b25c61f7 100644 (file)
@@ -4,7 +4,7 @@
        exec_raw.php
        part of m0n0wall (http://m0n0.ch/wall)
 
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
 
        Redistribution and use in source and binary forms, with or without
index c88a50ccb6de4d0d50bf14115fdd4d62953c8b1c..2d9652754f2cf1b2d8735e1078b15474b31607f0 100644 (file)
@@ -1,7 +1,7 @@
 </td></tr></table></td>
   </tr>
   <tr align="center" valign="top" bgcolor="#435370"> 
-    <td colspan="2" class="cpline">m0n0wall is &copy; 2002-2005 by Manuel Kasper. 
+    <td colspan="2" class="cpline">m0n0wall is &copy; 2002-2006 by Manuel Kasper. 
       All rights reserved.&nbsp; [<a href="/license.php" class="tblnk">view license</a>]</td>
   </tr>
 </table>
index 24294214241331f5c5b69e71c52f34012958df1a..e1e644794d27e6db160ccb76bd18f48c3729fb1d 100644 (file)
@@ -4,7 +4,7 @@
        firewall_aliases.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 81c27a3478323d357de819d862f0ef157c0c308b..f2c3d0ecf55fc250584bb45874c75cfc5b295565 100644 (file)
@@ -4,7 +4,7 @@
        firewall_aliases_edit.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 9c084e25b2a25800fe2903e410ac389682483278..1af50e40e30d24c141f735fd2b9c8d5478ac4187 100644 (file)
@@ -4,7 +4,7 @@
        firewall_nat.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 9aa91d72661340873a3ba735031f8d9df51c54fa..511bcc6387f4bb1928ecd3717cc713d006ca7d78 100644 (file)
@@ -4,7 +4,7 @@
        firewall_nat_1to1.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 07c061b0a414a85dc64a1b495a5d8d498569a15d..e6d675403b498aab5ef1555032d74dd61d6ced70 100644 (file)
@@ -4,7 +4,7 @@
        firewall_nat_1to1_edit.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index a5731db82f40de3fbef0f6d6aa1e42eab0dde235..059d8b9308fc2f9da7594a909b0861b8f9826a3f 100644 (file)
@@ -4,7 +4,7 @@
        firewall_nat_edit.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index e4a5da552ddc09f0fc295b097cc5a222c154511b..fdd875c181d9997944b97e8e34977d1adbf2c33a 100644 (file)
@@ -4,7 +4,7 @@
     firewall_nat_out.php
     part of m0n0wall (http://m0n0.ch/wall)
     
-    Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+    Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
     All rights reserved.
     
     Redistribution and use in source and binary forms, with or without
index d4468221d68a7eca9bbd9ae2288d18115b260368..61b6386c4026c995c79b8f0c57f4eb0066144577 100644 (file)
@@ -4,7 +4,7 @@
     firewall_nat_out_edit.php
     part of m0n0wall (http://m0n0.ch/wall)
     
-    Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+    Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
     All rights reserved.
     
     Redistribution and use in source and binary forms, with or without
index 9c0998fadd2bb7559aab0a7bd01b1dcd6f1d5b50..45f21eb50521f5555a844978bcd3c175d38b064f 100644 (file)
@@ -4,7 +4,7 @@
        firewall_nat_server.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 67e4c05ba8cd188c2c408ae5ad3ff8300ab00ece..e0594850af8f1d802c34ce1264afe04a162e3b1f 100644 (file)
@@ -4,7 +4,7 @@
        firewall_nat_server_edit.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 31739863446917ab3c6a1272a3f5a2661ad6ccfe..bbd0af928258637fc49330c950847f9ff6d862bd 100644 (file)
@@ -4,7 +4,7 @@
        firewall_rules.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 43139af786d65def51d6b3f830418bd175069aa8..5d6829e7fcacd23560f3e1432df51873c4c2b2ff 100644 (file)
@@ -4,7 +4,7 @@
        firewall_rules_edit.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index c5e48be5d44ef5120fcc5915307d9546833092e5..7037cd882bd6438de35f9e9a0bdd940dc66540b7 100644 (file)
@@ -4,7 +4,7 @@
        firewall_shaper.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 305ca9c3a85d6ac9c04094bc08aeb04c1b7e597b..1248b3540fd754eef0658d623f1793ecf7a373eb 100644 (file)
@@ -4,7 +4,7 @@
        firewall_shaper_edit.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 75aea79630c4af80ca60bef1f9c97fbe491c1275..fdaf27180c2e2078c255432bd557fa90c8fad738 100644 (file)
@@ -4,7 +4,7 @@
        firewall_shaper_pipes.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 4248de03c4c8348f53867d495424e5ad7192a258..2b6cf72cdf57cb7b47fe65f4b89f374fd50fc83b 100644 (file)
@@ -4,7 +4,7 @@
        firewall_shaper_pipes_edit.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 11306d2fd040eda3e15a40db277f752dd8adff5e..9389a2e9c16da3aa47c23a016833df09393d1e61 100644 (file)
@@ -4,7 +4,7 @@
        firewall_shaper_queues.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index b97d49daec62404e128eb4870c4af01a72ad1bf4..564b4678014fe1e75651ef0bf97b1aa91b583f5a 100644 (file)
@@ -4,7 +4,7 @@
        firewall_shaper_queues_edit.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 2703a69db8680e69008e07521cc050f534d8e69e..f7ff104cde54aca5df7971f33fd7b67b6a308cb4 100644 (file)
@@ -4,7 +4,8 @@
        graph.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2004-2005 T. Lechat <dev@lechat.org> and Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2004-2006 T. Lechat <dev@lechat.org>, Manuel Kasper <mk@neon1.net>
+       and Jonathan Watt <jwatt@jwatt.org>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
        POSSIBILITY OF SUCH DAMAGE.
 */
 
-// VERSION 1.0.4
+header("Content-type: image/svg+xml");
 
 /********** HTTP GET Based Conf ***********/
-$ifnum=@$_GET["ifnum"];                                                        //BSD / SNMP interface name / number
-$ifname=@$_GET["ifname"]?$_GET["ifname"]:"Interface $ifnum";           //Interface name that will be showed on top right of graph
+$ifnum=@$_GET["ifnum"];  // BSD / SNMP interface name / number
+$ifname=@$_GET["ifname"]?$_GET["ifname"]:"Interface $ifnum";  //Interface name that will be showed on top right of graph
 
 /********* Other conf *******/
-$scale_type="up";              //Autoscale default setup : "up" = only increase scale; "follow" = increase and decrease scale according to current graphed datas
-$nb_plot=120;                  //NB plot in graph
+$scale_type="up";               //Autoscale default setup : "up" = only increase scale; "follow" = increase and decrease scale according to current graphed datas
+$nb_plot=120;                   //NB plot in graph
 $time_interval=1;              //Refresh time Interval
-$first_stage_time_interval=2;  //First stage time Intervall
-
-$urldata=@$_SERVER["SCRIPT_NAME"];
 $fetch_link = "stats.cgi?$ifnum";
 
-//Style
-$style['bg']="fill:white;stroke:none;stroke-width:0;opacity:1;";
-$style['axis']="fill:black;stroke:black;stroke-width:1;";
-$style['in']="fill:#435370; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:7;";
-$style['out']="fill:#8092B3; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:7;";
-$style['graph_in']="fill:none;stroke:#435370;stroke-width:1;opacity:0.8;";
-$style['graph_out']="fill:none;stroke:#8092B3;stroke-width:1;opacity:0.8;";
-$style['legend']="fill:black; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4;";
-$style['graphname']="fill:#435370; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:8;";
-$style['grid_txt']="fill:gray; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:6;";
-$style['grid']="stroke:gray;stroke-width:1;opacity:0.5;";
-$style['switch_unit']="fill:#435370; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4; text-decoration:underline;";
-$style['switch_scale']="fill:#435370; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4; text-decoration:underline;";
-$style['error']="fill:blue; font-family:Arial; font-size:4;";
-$style['collect_initial']="fill:gray; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4;";
+//SVG attributes
+$attribs['axis']='fill="black" stroke="black"';
+$attribs['in']='fill="#435370" font-family="Tahoma, Verdana, Arial, Helvetica, sans-serif" font-size="7"';
+$attribs['out']='fill="#8092B3" font-family="Tahoma, Verdana, Arial, Helvetica, sans-serif" font-size="7"';
+$attribs['graph_in']='fill="none" stroke="#435370" stroke-opacity="0.8"';
+$attribs['graph_out']='fill="none" stroke="#8092B3" stroke-opacity="0.8"';
+$attribs['legend']='fill="black" font-family="Tahoma, Verdana, Arial, Helvetica, sans-serif" font-size="4"';
+$attribs['graphname']='fill="#435370" font-family="Tahoma, Verdana, Arial, Helvetica, sans-serif" font-size="8"';
+$attribs['grid_txt']='fill="gray" font-family="Tahoma, Verdana, Arial, Helvetica, sans-serif" font-size="6"';
+$attribs['grid']='stroke="gray" stroke-opacity="0.5"';
+$attribs['switch_unit']='fill="#435370" font-family="Tahoma, Verdana, Arial, Helvetica, sans-serif" font-size="4" text-decoration="underline"';
+$attribs['switch_scale']='fill="#435370" font-family="Tahoma, Verdana, Arial, Helvetica, sans-serif" font-size="4" text-decoration="underline"';
+$attribs['error']='fill="blue" font-family="Arial" font-size="4"';
+$attribs['collect_initial']='fill="gray" font-family="Tahoma, Verdana, Arial, Helvetica, sans-serif" font-size="4"';
 
 //Error text if we cannot fetch data : depends on which method is used
 $error_text = "Cannot get data about interface $ifnum";
 
-$height=100;           //SVG internal height : do not modify
-$width=200;            //SVG internal width : do not modify
+$height=100;            //SVG internal height : do not modify
+$width=200;             //SVG internal width : do not modify
 
 /********* Graph DATA **************/
-header("Content-type: image/svg+xml");
-print('<?xml version="1.0" encoding="iso-8859-1"?>' . "\n");?><svg width="100%" height="100%" viewBox="0 0 <?=$width?> <?=$height?>" preserveAspectRatio="none" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="init(evt)">
-<g id="graph" style="visibility:visible">
-       <rect id="bg" x1="0" y1="0" x2="<?=$width?>" y2="<?=$height?>" style="<?=$style['bg']?>"/>
-       <line id="axis_x" x1="0" y1="0" x2="0" y2="<?=$height?>" style="<?=$style['axis']?>"/>
-       <line id="axis_y" x1="0" y1="<?=$height?>" x2="<?=$width?>" y2="<?=$height?>" style="<?=$style['axis']?>"/>
-       <path id="graph_out" d="M0 <?=$height?> L 0 <?=$height?>" style="<?=$style['graph_out']?>"/>
-       <path id="graph_in"  d="M0 <?=$height?> L 0 <?=$height?>" style="<?=$style['graph_in']?>"/>
-       <path id="grid"  d="M0 <?=$height/4*1?> L <?=$width?> <?=$height/4*1?> M0 <?=$height/4*2?> L <?=$width?> <?=$height/4*2?> M0 <?=$height/4*3?> L <?=$width?> <?=$height/4*3?>" style="<?=$style[grid]?>"/>
-       <text id="grid_txt1" x="<?=$width?>" y="<?=$height/4*1?>" style="<?=$style['grid_txt']?> text-anchor:end"> </text>
-       <text id="grid_txt2" x="<?=$width?>" y="<?=$height/4*2?>" style="<?=$style['grid_txt']?> text-anchor:end"> </text>
-       <text id="grid_txt3" x="<?=$width?>" y="<?=$height/4*3?>" style="<?=$style['grid_txt']?> text-anchor:end"> </text>
-       <text id="graph_in_lbl" x="5" y="8" style="<?=$style['in']?>">In</text>
-       <text id="graph_out_lbl" x="5" y="16" style="<?=$style['out']?> ">Out</text>
-       <text id="graph_in_txt" x="20" y="8" style="<?=$style['in']?>"> </text>
-       <text id="graph_out_txt" x="20" y="16" style="<?=$style['out']?> "> </text>
-       <text id="ifname" x="<?=$width?>" y="8" style="<?=$style['graphname']?> text-anchor:end"><?=$ifname?></text>
-       <text id="switch_unit" x="<?=$width*0.55?>" y="5" style="<?=$style['switch_unit']?>">Switch to bytes/s</text>
-       <text id="switch_scale" x="<?=$width*0.55?>" y="11" style="<?=$style['switch_scale']?>">AutoScale (<?=$scale_type?>)</text>
-       <text id="datetime" x="<?=$width*0.33?>" y="5" style="<?=$style['legend']?>"> </text>
-       <text id="graphlast" x="<?=$width*0.55?>" y="17" style="<?=$style['legend']?>">Graph shows last <?=$time_interval*$nb_plot?> seconds</text>
-       <polygon id="axis_arrow_x" style="<?=$style['axis']?>" points="<?=($width) . "," . ($height)?> <?=($width-2) . "," . ($height-2)?> <?=($width-2) . "," . $height?>"/>
-       <text id="error" x="<?=$width*0.5?>" y="<?=$height*0.5?>"  style="visibility:hidden;<?=$style['error']?> text-anchor:middle"><?=$error_text?></text>
-       <text id="collect_initial" x="<?=$width*0.5?>" y="<?=$height*0.5?>"  style="visibility:hidden;<?=$style['collect_initial']?> text-anchor:middle">Collecting initial data, please wait...</text>
-</g>
-
-<script type="text/ecmascript"><![CDATA[
-var SVGDoc;
-var last_ifin=0;
-var last_ifout=0;
-var last_ugmt=0;
-var diff_ugmt=0;
-var diff_ifin=0;
-var diff_ifout=0;
+print('<?xml version="1.0" encoding="iso-8859-1"?>' . "\n");?>
+<svg width="100%" height="100%" viewBox="0 0 <?=$width?> <?=$height?>" preserveAspectRatio="none" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="init(evt)">
+  <g id="graph">
+    <rect id="bg" x1="0" y1="0" width="100%" height="100%" fill="white"/>
+    <line id="axis_x" x1="0" y1="0" x2="0" y2="100%" <?=$attribs['axis']?>/>
+    <line id="axis_y" x1="0" y1="100%" x2="100%" y2="100%" <?=$attribs['axis']?>/>
+    <path id="graph_out" d="M0 <?=$height?> L 0 <?=$height?>" <?=$attribs['graph_out']?>/>
+    <path id="graph_in"  d="M0 <?=$height?> L 0 <?=$height?>" <?=$attribs['graph_in']?>/>
+    <path id="grid"  d="M0 <?=$height/4*1?> L <?=$width?> <?=$height/4*1?> M0 <?=$height/4*2?> L <?=$width?> <?=$height/4*2?> M0 <?=$height/4*3?> L <?=$width?> <?=$height/4*3?>" <?=$attribs['grid']?>/>
+    <text id="grid_txt1" x="<?=$width?>" y="<?=$height/4*1?>" <?=$attribs['grid_txt']?> text-anchor="end"> </text>
+    <text id="grid_txt2" x="<?=$width?>" y="<?=$height/4*2?>" <?=$attribs['grid_txt']?> text-anchor="end"> </text>
+    <text id="grid_txt3" x="<?=$width?>" y="<?=$height/4*3?>" <?=$attribs['grid_txt']?> text-anchor="end"> </text>
+    <text id="graph_in_lbl" x="5" y="8" <?=$attribs['in']?>>In</text>
+    <text id="graph_out_lbl" x="5" y="16" <?=$attribs['out']?>>Out</text>
+    <text id="graph_in_txt" x="20" y="8" <?=$attribs['in']?>> </text>
+    <text id="graph_out_txt" x="20" y="16" <?=$attribs['out']?>> </text>
+    <text id="ifname" x="<?=$width?>" y="8" <?=$attribs['graphname']?> text-anchor="end"><?=$ifname?></text>
+    <text id="switch_unit" x="<?=$width*0.55?>" y="5" <?=$attribs['switch_unit']?>>Switch to bytes/s</text>
+    <text id="switch_scale" x="<?=$width*0.55?>" y="11" <?=$attribs['switch_scale']?>>AutoScale (<?=$scale_type?>)</text>
+    <text id="datetime" x="<?=$width*0.33?>" y="5" <?=$attribs['legend']?>> </text>
+    <text id="graphlast" x="<?=$width*0.55?>" y="17" <?=$attribs['legend']?>>Graph shows last <?=$time_interval*$nb_plot?> seconds</text>
+    <polygon id="axis_arrow_x" <?=$attribs['axis']?> points="<?=($width) . "," . ($height)?> <?=($width-2) . "," . ($height-2)?> <?=($width-2) . "," . $height?>"/>
+    <text id="error" x="<?=$width*0.5?>" y="<?=$height*0.5?>"  visibility="hidden" <?=$attribs['error']?> text-anchor="middle"><?=$error_text?></text>
+    <text id="collect_initial" x="<?=$width*0.5?>" y="<?=$height*0.5?>"  visibility="hidden" <?=$attribs['collect_initial']?> text-anchor="middle">Collecting initial data, please wait...</text>
+  </g>
+  <script type="text/ecmascript">
+    <![CDATA[
+
+/**
+ * getURL is a proprietary Adobe function, but it's simplicity has made it very
+ * popular. If getURL is undefined we spin our own by wrapping XMLHttpRequest.
+ */
+if (typeof getURL == 'undefined') {
+  getURL = function(url, callback) {
+    if (!url)
+      throw 'No URL for getURL';
+
+    try {
+      if (typeof callback.operationComplete == 'function')
+        callback = callback.operationComplete;
+    } catch (e) {}
+    if (typeof callback != 'function')
+      throw 'No callback function for getURL';
+
+    var http_request = null;
+    if (typeof XMLHttpRequest != 'undefined') {
+      http_request = new XMLHttpRequest();
+    }
+    else if (typeof ActiveXObject != 'undefined') {
+      try {
+        http_request = new ActiveXObject('Msxml2.XMLHTTP');
+      } catch (e) {
+        try {
+          http_request = new ActiveXObject('Microsoft.XMLHTTP');
+        } catch (e) {}
+      }
+    }
+    if (!http_request)
+      throw 'Both getURL and XMLHttpRequest are undefined';
+
+    http_request.onreadystatechange = function() {
+      if (http_request.readyState == 4) {
+        callback( { success : true,
+                    content : http_request.responseText,
+                    contentType : http_request.getResponseHeader("Content-Type") } );
+      }
+    }
+    http_request.open('GET', url, true);
+    http_request.send(null);
+  }
+}
+
+var SVGDoc = null;
+var last_ifin = 0;
+var last_ifout = 0;
+var last_ugmt = 0;
 var max = 0;
-plot_in=new Array();
-plot_out=new Array();
+var plot_in = new Array();
+var plot_out = new Array();
 
-var isfirst=1;
-var index_plot=0;
-var step = <?=$width?> / <?=$nb_plot?> ;
+var max_num_points = <?=$nb_plot?>;  // maximum number of plot data points
+var step = <?=$width?> / max_num_points ;
 var unit = 'bits';
 var scale_type = '<?=$scale_type?>';
 
 function init(evt) {
-       SVGDoc = evt.getTarget().getOwnerDocument();
-       SVGDoc.getElementById("switch_unit").addEventListener("mousedown", switch_unit, false);
-       SVGDoc.getElementById("switch_scale").addEventListener("mousedown", switch_scale, false);
+  SVGDoc = evt.target.ownerDocument;
+  SVGDoc.getElementById("switch_unit").addEventListener("mousedown", switch_unit, false);
+  SVGDoc.getElementById("switch_scale").addEventListener("mousedown", switch_scale, false);
 
-       go();
+  fetch_data();
 }
 
 function switch_unit(event)
 {
-       SVGDoc.getElementById('switch_unit').getFirstChild().setData('Switch to ' + unit + '/s');
-       if(unit=='bits') unit='bytes';else unit='bits';
+  SVGDoc.getElementById('switch_unit').firstChild.data = 'Switch to ' + unit + '/s';
+  unit = (unit == 'bits') ? 'bytes' : 'bits';
 }
 
 function switch_scale(event)
 {
-       if(scale_type=='up') scale_type='follow';else scale_type='up';
-       SVGDoc.getElementById('switch_scale').getFirstChild().setData('AutoScale (' + scale_type + ')');
+  scale_type = (scale_type == 'up') ? 'follow' : 'up';
+  SVGDoc.getElementById('switch_scale').firstChild.data = 'AutoScale (' + scale_type + ')';
 }
 
-function go() {
-       getURL('<?=$fetch_link?>',urlcallback);
+function fetch_data() {
+  getURL('<?=$fetch_link?>', plot_data);
 }
 
-function urlcallback(obj) {
-       var error = 0;
-       now = new Date();
-
-       //Show datetimelegend
-       var datetime = (now.getMonth()+1) + "/" + now.getDate() + "/" + now.getFullYear() + ' ' + 
-               LZ(now.getHours()) + ":" + LZ(now.getMinutes()) + ":" + LZ(now.getSeconds());
-       SVGDoc.getElementById('datetime').getFirstChild().setData(datetime);
-
-       //shift plot to left if nb_plot is already completed
-       var i=0;
-       if(index_plot > <?=$nb_plot?>)
-       {
-               while (i <= <?=$nb_plot?>)
-               {
-                       var a=i+1;
-                       plot_in[i]=plot_in[a];
-                       plot_out[i]=plot_out[a];
-                       i=i+1;
-               }
-               index_plot = <?=$nb_plot?>;
-               plot_in[index_plot]=0;
-               plot_out[index_plot]=0;
-       }
-
-       //if Geturl returns something
-       if (obj.success){
-               var t=obj.content.split("|");
-               var ugmt = parseFloat(t[0]);//ugmt is an unixtimestamp style
-               var ifin = parseInt(t[1]);//ifin must be in bytes
-               var ifout = parseInt(t[2]);//ifout must be in bytes
-               var scale;
-
-               if(!isNumber(ifin) || !isNumber(ifout)) {
-                       goerror();
-                       return;
-               } else {
-                       SVGDoc.getElementById("error").getStyle().setProperty ('visibility', 'hidden');
-               }
-
-               diff_ugmt  = ugmt - last_ugmt;
-               diff_ifin  = ifin - last_ifin;
-               diff_ifout = ifout - last_ifout;
-               
-               if (diff_ugmt == 0)
-                       diff_ugmt = 1;  /* avoid division by zero */
-
-               last_ugmt = ugmt;
-               last_ifin = ifin;
-               last_ifout = ifout;
-
-               if(isfirst) {
-                       SVGDoc.getElementById("collect_initial").getStyle().setProperty ('visibility', 'visible');
-                       setTimeout('go()',<?=1000*$first_stage_time_interval?>);
-                       isfirst=0;
-                       return;
-               } else SVGDoc.getElementById("collect_initial").getStyle().setProperty ('visibility', 'hidden');
-
-               plot_in[index_plot] = diff_ifin / diff_ugmt;
-               plot_out[index_plot]= diff_ifout / diff_ugmt;
-
-               SVGDoc.getElementById('graph_in_txt').getFirstChild().setData(formatSpeed(plot_in[index_plot],unit));
-               SVGDoc.getElementById('graph_out_txt').getFirstChild().setData(formatSpeed(plot_out[index_plot],unit));
-
-               /* determine peak for sensible scaling */               
-               if (scale_type == 'up') {
-                       if (plot_in[index_plot] > max)
-                               max = plot_in[index_plot];
-                       if (plot_out[index_plot] > max)
-                               max = plot_out[index_plot];             
-               } else if (scale_type == 'follow') {
-                       i = 0;
-                       max = 0;
-                       while (i <= <?=$nb_plot?>) {
-                               if (plot_in[i] > max)
-                                       max = plot_in[i];
-                               if (plot_out[i] > max)
-                                       max = plot_out[i];
-                               i++;
-                       }
+function plot_data(obj) {
+  // Show datetimelegend
+  var now = new Date();
+  var datetime = (now.getMonth()+1) + "/" + now.getDate() + "/" + now.getFullYear() + ' ' + 
+    LZ(now.getHours()) + ":" + LZ(now.getMinutes()) + ":" + LZ(now.getSeconds());
+  SVGDoc.getElementById('datetime').firstChild.data = datetime;
+
+  if (!obj.success)
+    return handle_error();  // getURL failed to get data
+
+  var t = obj.content.split("|");
+  var ugmt = parseFloat(t[0]);  // ugmt is an unixtimestamp style
+  var ifin = parseInt(t[1]);    // number of bytes received by the interface
+  var ifout = parseInt(t[2]);   // number of bytes sent by the interface
+  var scale;
+
+  if (!isNumber(ifin) || !isNumber(ifout))
+    return handle_error();
+
+  var diff_ugmt  = ugmt - last_ugmt;
+  var diff_ifin  = ifin - last_ifin;
+  var diff_ifout = ifout - last_ifout;
+
+  if (diff_ugmt == 0)
+    diff_ugmt = 1;  /* avoid division by zero */
+
+  last_ugmt = ugmt;
+  last_ifin = ifin;
+  last_ifout = ifout;
+  
+  switch (plot_in.length) {
+       case 0:
+               SVGDoc.getElementById("collect_initial").setAttributeNS(null, 'visibility', 'visible');
+               plot_in[0] = diff_ifin / diff_ugmt;
+               plot_out[0] = diff_ifout / diff_ugmt;
+               setTimeout('fetch_data()',<?=1000*$time_interval?>);
+               return;
+       case 1:
+       SVGDoc.getElementById("collect_initial").setAttributeNS(null, 'visibility', 'hidden');
+       break;
+    case max_num_points:
+               // shift plot to left if the maximum number of plot points has been reached
+               var i = 0;
+               while (i < max_num_points) {
+                 plot_in[i] = plot_in[i+1];
+                 plot_out[i] = plot_out[++i];
                }
-
-               var rmax;
-               
-               if (unit == 'bits') {
-                       /* round up max, such that
-                               100 kbps -> 200 kbps -> 400 kbps -> 800 kbps -> 1 Mbps -> 2 Mbps -> ... */
-                       rmax = 12500;
-                       i = 0;
-                       while (max > rmax) {
-                               i++;
-                               if (i && (i % 4 == 0))
-                                       rmax *= 1.25;
-                               else
-                                       rmax *= 2;
-                       }
-               } else {
-                       /* round up max, such that
-                               10 KB/s -> 20 KB/s -> 40 KB/s -> 80 KB/s -> 100 KB/s -> 200 KB/s -> 400 KB/s -> 800 KB/s -> 1 MB/s ... */
-                       rmax = 10240;
-                       i = 0;
-                       while (max > rmax) {
-                               i++;
-                               if (i && (i % 4 == 0))
-                                       rmax *= 1.25;
-                               else
-                                       rmax *= 2;
-                               
-                               if (i == 8)
-                                       rmax *= 1.024;
-                       }
-               }
-               
-               scale = <?=$height?> / rmax;
-               
-               /* change labels accordingly */
-               SVGDoc.getElementById('grid_txt1').getFirstChild().setData(formatSpeed(3*rmax/4,unit));
-               SVGDoc.getElementById('grid_txt2').getFirstChild().setData(formatSpeed(2*rmax/4,unit));
-               SVGDoc.getElementById('grid_txt3').getFirstChild().setData(formatSpeed(rmax/4,unit));
-               
-               i = 0;
-               
-               while (i <= index_plot)
-               {
-                       var x = step * i;
-                       var y_in= <?=$height?> - (plot_in[i] * scale);
-                       var y_out= <?=$height?> - (plot_out[i] * scale);
-                       if(i==0) {
-                               var path_in = "M" + x + " " + y_in;
-                               var path_out = "M" + x + " " + y_out;
-                       }
-                       else
-                       {
-                               var path_in = path_in + " L" + x + " " + y_in;
-                               var path_out = path_out + " L" + x + " " + y_out;
-                       }
-                       i = i + 1;
-               }
-
-               index_plot = index_plot+1;
-               SVGDoc.getElementById('graph_in').setAttribute("d", path_in);
-               SVGDoc.getElementById('graph_out').setAttribute("d", path_out);
-
-               setTimeout('go()',<?=1000*$time_interval?>);
-       }
-       else
-       { //In case of Geturl fails
-               goerror();
-       }
+               plot_in.length--;
+               plot_out.length--;
+  }
+
+  plot_in[plot_in.length] = diff_ifin / diff_ugmt;
+  plot_out[plot_out.length]= diff_ifout / diff_ugmt;
+  var index_plot = plot_in.length - 1;
+
+  SVGDoc.getElementById('graph_in_txt').firstChild.data = formatSpeed(plot_in[index_plot], unit);
+  SVGDoc.getElementById('graph_out_txt').firstChild.data = formatSpeed(plot_out[index_plot], unit);
+
+  /* determine peak for sensible scaling */
+  if (scale_type == 'up') {
+    if (plot_in[index_plot] > max)
+      max = plot_in[index_plot];
+    if (plot_out[index_plot] > max)
+      max = plot_out[index_plot];
+  }
+  else if (scale_type == 'follow') {
+    i = 0;
+    max = 0;
+    while (i < plot_in.length) {
+      if (plot_in[i] > max)
+        max = plot_in[i];
+      if (plot_out[i] > max)
+        max = plot_out[i];
+      i++;
+    }
+  }
+
+  var rmax;  // max, rounded up
+
+  if (unit == 'bits') {
+    /* round up max, such that
+         100 kbps -> 200 kbps -> 400 kbps -> 800 kbps -> 1 Mbps -> 2 Mbps -> ... */
+    rmax = 12500;
+    i = 0;
+    while (max > rmax) {
+      i++;
+      if (i && (i % 4 == 0))
+        rmax *= 1.25;
+      else
+        rmax *= 2;
+    }
+  } else {
+    /* round up max, such that
+         10 KB/s -> 20 KB/s -> 40 KB/s -> 80 KB/s -> 100 KB/s -> 200 KB/s -> 400 KB/s -> 800 KB/s -> 1 MB/s ... */
+    rmax = 10240;
+    i = 0;
+    while (max > rmax) {
+      i++;
+      if (i && (i % 4 == 0))
+        rmax *= 1.25;
+      else
+        rmax *= 2;
+      
+      if (i == 8)
+        rmax *= 1.024;
+    }
+  }
+
+  scale = <?=$height?> / rmax;
+
+  /* change labels accordingly */
+  SVGDoc.getElementById('grid_txt1').firstChild.data = formatSpeed(3*rmax/4,unit);
+  SVGDoc.getElementById('grid_txt2').firstChild.data = formatSpeed(2*rmax/4,unit);
+  SVGDoc.getElementById('grid_txt3').firstChild.data = formatSpeed(rmax/4,unit);
+
+  var path_in = "M 0 " + (<?=$height?> - (plot_in[0] * scale));
+  var path_out = "M 0 " + (<?=$height?> - (plot_out[0] * scale));
+  for (i = 1; i < plot_in.length; i++)
+  {
+    var x = step * i;
+    var y_in = <?=$height?> - (plot_in[i] * scale);
+    var y_out = <?=$height?> - (plot_out[i] * scale);
+    path_in += " L" + x + " " + y_in;
+    path_out += " L" + x + " " + y_out;
+  }
+
+  SVGDoc.getElementById('error').setAttributeNS(null, 'visibility', 'hidden');
+  SVGDoc.getElementById('graph_in').setAttributeNS(null, 'd', path_in);
+  SVGDoc.getElementById('graph_out').setAttributeNS(null, 'd', path_out);
+
+  setTimeout('fetch_data()',<?=1000*$time_interval?>);
 }
 
-function goerror() {
-       SVGDoc.getElementById("error").getStyle().setProperty ('visibility', 'visible');
-       setTimeout('go()',<?=1000*$time_interval?>);
+function handle_error() {
+  SVGDoc.getElementById("error").setAttributeNS(null, 'visibility', 'visible');
+  setTimeout('fetch_data()',<?=1000*$time_interval?>);
 }
 
 function isNumber(a) {
-    return typeof a == 'number' && isFinite(a);
+  return typeof a == 'number' && isFinite(a);
 }
 
-function formatSpeed(speed,unit){
-       if(unit=='bits') return formatSpeedBits(speed);
-       else if(unit=='bytes') return formatSpeedBytes(speed);
+function formatSpeed(speed, unit) {
+  if (unit == 'bits')
+    return formatSpeedBits(speed);
+  if (unit == 'bytes')
+    return formatSpeedBytes(speed);
 }
 
 function formatSpeedBits(speed) {
-       // format speed in bits/sec, input: bytes/sec
-       if (speed <     125000)
-               return Math.round(speed / 125) + " Kbps";
-       else if (speed < 125000000)
-               return Math.round(speed / 1250)/100 + " Mbps";
-       else
-               return Math.round(speed / 1250000)/100 + " Gbps";       /* wow! */
+  // format speed in bits/sec, input: bytes/sec
+  if (speed < 125000)
+    return Math.round(speed / 125) + " Kbps";
+  if (speed < 125000000)
+    return Math.round(speed / 1250)/100 + " Mbps";
+  // else
+  return Math.round(speed / 1250000)/100 + " Gbps";  /* wow! */
 }
+
 function formatSpeedBytes(speed) {
-       // format speed in bytes/sec, input:  bytes/sec
-       if (speed <     1048576)
-               return Math.round(speed / 10.24)/100 + " KB/s";
-       else if (speed < 1073741824)
-               return Math.round(speed / 10485.76)/100 + " MB/s";
-       else
-               return Math.round(speed / 10737418.24)/100 + " GB/s";   /* wow! */
+  // format speed in bytes/sec, input:  bytes/sec
+  if (speed < 1048576)
+    return Math.round(speed / 10.24)/100 + " KB/s";
+  if (speed < 1073741824)
+    return Math.round(speed / 10485.76)/100 + " MB/s";
+  // else
+  return Math.round(speed / 10737418.24)/100 + " GB/s";  /* wow! */
 }
+
 function LZ(x) {
-       return (x < 0 || x > 9 ? "" : "0") + x
+  return (x < 0 || x > 9 ? "" : "0") + x;
 }
-]]></script>
-</svg>
\ No newline at end of file
+
+    ]]>
+  </script>
+</svg>
index b87504da11b2b7d415ae3f8b189cafbea49d5a57..a7d1101966c53ed448d608779b7ea0954fd9ed76 100644 (file)
@@ -4,7 +4,8 @@
        graph_cpu.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2004-2005 T. Lechat <dev@lechat.org> and Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2004-2005 T. Lechat <dev@lechat.org>, Manuel Kasper <mk@neon1.net>
+       and Jonathan Watt <jwatt@jwatt.org>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
        POSSIBILITY OF SUCH DAMAGE.
 */
 
+header("Content-type: image/svg+xml");
+
 /********* Other conf *******/
-$nb_plot=120;                  //NB plot in graph
 
+$nb_plot = 120;  // maximum number of data points to plot in the graph
 $fetch_link = "stats.cgi?cpu";
 
-//Style
-$style['bg']="fill:white;stroke:none;stroke-width:0;opacity:1;";
-$style['axis']="fill:black;stroke:black;stroke-width:1;";
-$style['cpu']="fill:#435370; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:7;";
-$style['graph_cpu']="fill:none;stroke:#435370;stroke-width:1;opacity:0.8;";
-$style['legend']="fill:black; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4;";
-$style['grid_txt']="fill:gray; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:6;";
-$style['grid']="stroke:gray;stroke-width:1;opacity:0.5;";
-$style['error']="fill:blue; font-family:Arial; font-size:4;";
-$style['collect_initial']="fill:gray; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4;";
+//SVG attributes
+$attribs['axis']='fill="black" stroke="black"';
+$attribs['cpu']='fill="#435370" font-family="Tahoma, Verdana, Arial, Helvetica, sans-serif" font-size="7"';
+$attribs['graph_cpu']='fill="none" stroke="#435370" stroke-opacity="0.8"';
+$attribs['legend']='fill="black" font-family="Tahoma, Verdana, Arial, Helvetica, sans-serif" font-size="4"';
+$attribs['grid_txt']='fill="gray" font-family="Tahoma, Verdana, Arial, Helvetica, sans-serif" font-size="6"';
+$attribs['grid']='stroke="gray" stroke-opacity="0.5"';
+$attribs['error']='fill="blue" font-family="Arial" font-size="4"';
+$attribs['collect_initial']='fill="gray" font-family="Tahoma, Verdana, Arial, Helvetica, sans-serif" font-size="4"';
 
-$error_text = "Cannot get CPU load";
-
-$height=100;           //SVG internal height : do not modify
-$width=200;            //SVG internal width : do not modify
+$height=100;  // SVG internal height : do not modify
+$width=200;   // SVG internal width  : do not modify
 
 /********* Graph DATA **************/
-header("Content-type: image/svg+xml");
-print('<?xml version="1.0" encoding="iso-8859-1"?>' . "\n");?><svg width="100%" height="100%" viewBox="0 0 <?=$width?> <?=$height?>" preserveAspectRatio="none" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="init(evt)">
-<g id="graph" style="visibility:visible">
-       <rect id="bg" x1="0" y1="0" x2="<?=$width?>" y2="<?=$height?>" style="<?=$style['bg']?>"/>
-       <line id="axis_x" x1="0" y1="0" x2="0" y2="<?=$height?>" style="<?=$style['axis']?>"/>
-       <line id="axis_y" x1="0" y1="<?=$height?>" x2="<?=$width?>" y2="<?=$height?>" style="<?=$style['axis']?>"/>
-       <path id="graph_cpu"  d="M0 <?=$height?> L 0 <?=$height?>" style="<?=$style['graph_cpu']?>"/>
-       <path id="grid"  d="M0 <?=$height/4*1?> L <?=$width?> <?=$height/4*1?> M0 <?=$height/4*2?> L <?=$width?> <?=$height/4*2?> M0 <?=$height/4*3?> L <?=$width?> <?=$height/4*3?>" style="<?=$style[grid]?>"/>
-       <text id="grid_txt1" x="<?=$width?>" y="<?=$height/4*1?>" style="<?=$style['grid_txt']?> text-anchor:end">75%</text>
-       <text id="grid_txt2" x="<?=$width?>" y="<?=$height/4*2?>" style="<?=$style['grid_txt']?> text-anchor:end">50%</text>
-       <text id="grid_txt3" x="<?=$width?>" y="<?=$height/4*3?>" style="<?=$style['grid_txt']?> text-anchor:end">25%</text>
-       <text id="graph_cpu_txt" x="4" y="8" style="<?=$style['cpu']?>"> </text>
-       <polygon id="axis_arrow_x" style="<?=$style['axis']?>" points="<?=($width) . "," . ($height)?> <?=($width-2) . "," . ($height-2)?> <?=($width-2) . "," . $height?>"/>
-       <text id="error" x="<?=$width*0.5?>" y="<?=$height*0.5?>"  style="visibility:hidden;<?=$style['error']?> text-anchor:middle"><?=$error_text?></text>
-       <text id="collect_initial" x="<?=$width*0.5?>" y="<?=$height*0.5?>"  style="visibility:hidden;<?=$style['collect_initial']?> text-anchor:middle">Collecting initial data, please wait...</text>
-</g>
-
-<script type="text/ecmascript"><![CDATA[
-var SVGDoc;
-var last_cpu_total=0;
-var last_cpu_idle=0;
-var diff_cpu_total=0;
-var diff_cpu_idle=0;
-plot_cpu = new Array();
-
-var isfirst=1;
-var index_plot=0;
-var step = <?=$width?> / <?=$nb_plot?> ;
+print('<?xml version="1.0" encoding="iso-8859-1"?>' . "\n");?>
+<svg width="100%" height="100%" viewBox="0 0 <?=$width?> <?=$height?>" preserveAspectRatio="none" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="init(evt);">
+  <g id="graph">
+    <rect id="bg" x1="0" y1="0" width="100%" height="100%" fill="white"/>
+    <line id="axis_x" x1="0" y1="0" x2="0" y2="100%" <?=$attribs['axis']?>/>
+    <line id="axis_y" x1="0" y1="100%" x2="100%" y2="100%" <?=$attribs['axis']?>/>
+    <polygon id="axis_arrow_x" <?=$attribs['axis']?> points="<?=($width) . "," . ($height)?> <?=($width-2) . "," . ($height-2)?> <?=($width-2) . "," . $height?>"/>
+    <path id="graph_cpu" d="" <?=$attribs['graph_cpu']?>/>
+    <path id="grid" d="M0 <?=$height/4*1?> L <?=$width?> <?=$height/4*1?> M0 <?=$height/4*2?> L <?=$width?> <?=$height/4*2?> M0 <?=$height/4*3?> L <?=$width?> <?=$height/4*3?>" <?=$attribs['grid']?>/>
+    <text id="grid_txt1" x="100%" y="25%" <?=$attribs['grid_txt']?> text-anchor="end">75%</text>
+    <text id="grid_txt2" x="100%" y="50%" <?=$attribs['grid_txt']?> text-anchor="end">50%</text>
+    <text id="grid_txt3" x="100%" y="75%" <?=$attribs['grid_txt']?> text-anchor="end">25%</text>
+    <text id="graph_cpu_txt" x="4" y="8" <?=$attribs['cpu']?>> </text>
+    <text id="error" x="50%" y="50%"  visibility="hidden" <?=$attribs['error']?> text-anchor="middle">Cannot get CPU load</text>
+    <text id="collect_initial" x="50%" y="50%"  visibility="hidden" <?=$attribs['collect_initial']?> text-anchor="middle">Collecting initial data, please wait...</text>
+  </g>
+  <script type="text/ecmascript">
+    <![CDATA[
+
+/**
+ * getURL is a proprietary Adobe function, but it's simplicity has made it very
+ * popular. If getURL is undefined we spin our own by wrapping XMLHttpRequest.
+ */
+if (typeof getURL == 'undefined') {
+  getURL = function(url, callback) {
+    if (!url)
+      throw 'No URL for getURL';
+
+    try {
+      if (typeof callback.operationComplete == 'function')
+        callback = callback.operationComplete;
+    } catch (e) {}
+    if (typeof callback != 'function')
+      throw 'No callback function for getURL';
+
+    var http_request = null;
+    if (typeof XMLHttpRequest != 'undefined') {
+      http_request = new XMLHttpRequest();
+    }
+    else if (typeof ActiveXObject != 'undefined') {
+      try {
+        http_request = new ActiveXObject('Msxml2.XMLHTTP');
+      } catch (e) {
+        try {
+          http_request = new ActiveXObject('Microsoft.XMLHTTP');
+        } catch (e) {}
+      }
+    }
+    if (!http_request)
+      throw 'Both getURL and XMLHttpRequest are undefined';
+
+    http_request.onreadystatechange = function() {
+      if (http_request.readyState == 4) {
+        callback( { success : true,
+                    content : http_request.responseText,
+                    contentType : http_request.getResponseHeader("Content-Type") } );
+      }
+    }
+    http_request.open('GET', url, true);
+    http_request.send(null);
+  }
+}
+
+var SVGDoc = null;
+var last_cpu_total = 0;
+var last_cpu_idle = 0;
+var diff_cpu_total = 0;
+var diff_cpu_idle = 0;
+var cpu_data = new Array();
+
+var max_num_points = <?=$nb_plot?>;  // maximum number of plot data points
+var step = <?=$width?> / max_num_points;  // plot X division size
+var scale = <?=$height?> / 100;
 
 function init(evt) {
-       SVGDoc = evt.getTarget().getOwnerDocument();
-       go();
+  SVGDoc = evt.target.ownerDocument;
+  fetch_data();
 }
 
-function go() {
-       getURL('<?=$fetch_link?>',urlcallback);
+function fetch_data() {
+  getURL('<?=$fetch_link?>', plot_cpu_data);
 }
 
-function urlcallback(obj) {
-       var error = 0;
-
-       //shift plot to left if nb_plot is already completed
-       var i=0;
-       if(index_plot > <?=$nb_plot?>)
-       {
-               while (i <= <?=$nb_plot?>)
-               {
-                       var a=i+1;
-                       plot_cpu[i]=plot_cpu[a];
-                       i=i+1;
-               }
-               index_plot = <?=$nb_plot?>;
-               plot_cpu[index_plot]=0;
-       }
-
-       //if Geturl returns something
-       if (obj.success){
-               var cpu = parseInt(obj.content);
-               var scale;
-
-               if(!isNumber(cpu)) {
-                       goerror();
-                       return;
-               } else {
-                       SVGDoc.getElementById("error").getStyle().setProperty ('visibility', 'hidden');
-               }
-
-               if(isfirst) {
-                       SVGDoc.getElementById("collect_initial").getStyle().setProperty ('visibility', 'visible');
-                       go();
-                       isfirst=0;
-                       return;
-               } else SVGDoc.getElementById("collect_initial").getStyle().setProperty ('visibility', 'hidden');
-
-               plot_cpu[index_plot] = cpu;
-
-               SVGDoc.getElementById('graph_cpu_txt').getFirstChild().setData(plot_cpu[index_plot] + '%');
-               
-               scale = <?=$height?> / 100;
-               
-               i = 0;
-               
-               while (i <= index_plot)
-               {
-                       var x = step * i;
-                       var y_cpu= <?=$height?> - (plot_cpu[i] * scale);
-                       if(i==0) {
-                               var path_cpu = "M" + x + " " + y_cpu;
-                       }
-                       else
-                       {
-                               var path_cpu = path_cpu + " L" + x + " " + y_cpu;
-                       }
-                       i = i + 1;
-               }
-
-               index_plot = index_plot+1;
-               SVGDoc.getElementById('graph_cpu').setAttribute("d", path_cpu);
-
-               go();
-       }
-       else
-       { //In case of Geturl fails
-               goerror();
-       }
+function plot_cpu_data(obj) {
+  if (!obj.success)
+    return handle_error();  // getURL failed to get current CPU load data
+
+  var cpu = parseInt(obj.content);
+  if (!isNumber(cpu))
+    return handle_error();
+
+  switch (cpu_data.length) {
+  case 0:
+    SVGDoc.getElementById("collect_initial").setAttributeNS(null, 'visibility', 'visible');
+    cpu_data[0] = cpu;
+    fetch_data();
+    return;
+  case 1:
+    SVGDoc.getElementById("collect_initial").setAttributeNS(null, 'visibility', 'hidden');
+    break;
+  case max_num_points:
+    // shift plot to left if the maximum number of plot points has been reached
+    var i = 0;
+    while (i < max_num_points) {
+      cpu_data[i] = cpu_data[++i];
+    }
+    --cpu_data.length;
+  }
+
+  cpu_data[cpu_data.length] = cpu;
+
+  var path_data = "M 0 " + (<?=$height?> - (cpu_data[0] * scale));
+  for (var i = 1; i < cpu_data.length; ++i) {
+    var x = step * i;
+    var y_cpu = <?=$height?> - (cpu_data[i] * scale);
+    path_data += " L" + x + " " + y_cpu;
+  }
+
+  SVGDoc.getElementById("error").setAttributeNS(null, 'visibility', 'hidden');
+  SVGDoc.getElementById('graph_cpu_txt').firstChild.data = cpu + '%';
+  SVGDoc.getElementById('graph_cpu').setAttributeNS(null, "d", path_data);
+
+  fetch_data();
 }
 
-function goerror() {
-       SVGDoc.getElementById("error").getStyle().setProperty ('visibility', 'visible');
-       go();
+function handle_error() {
+  SVGDoc.getElementById("error").setAttributeNS(null, 'visibility', 'visible');
+  fetch_data();
 }
 
 function isNumber(a) {
-    return typeof a == 'number' && isFinite(a);
+  return typeof a == 'number' && isFinite(a);
 }
 
-function LZ(x) {
-       return (x < 0 || x > 9 ? "" : "0") + x
-}
-]]></script>
-</svg>
\ No newline at end of file
+    ]]>
+  </script>
+</svg>
index e18b205ae27f6fa9332b0a54fb64b31dd5d1e280..ba8827a8ec59dd0e1b4685bbac5b317e4fef3b40 100644 (file)
@@ -44,6 +44,15 @@ p {
        font-size: 10px;
        font-weight: bold;
 }
+.formbtns {
+       font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;
+       font-size: 9px;
+       font-weight: bold;
+}
+textarea.notes {
+       font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;
+       font-size: 11px;
+}
 .vvcell {
        background-color: #FFFFC6;
 }
@@ -254,6 +263,17 @@ a {
        padding-top: 2px;
        padding-bottom: 2px;
 }
+.optsect_t2 {
+       border-right: 1px solid #999999;
+       background-color: #435370;
+       padding-right: 6px;
+       padding-left: 6px;
+       padding-top: 5px;
+       padding-bottom: 5px;
+       font-size: 11px;
+       color: #FFFFFF;
+       font-weight: bold;
+}
 .optsect_s {
        font-size: 11px;
        color: #FFFFFF;
index 24e61bd17efc81e98b8f42b443fdd412604a96de..8bbd52a728e6b34d344aefd78d89739fa3fc9658 100644 (file)
@@ -3,7 +3,7 @@
        guiconfig.inc
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
@@ -447,6 +447,16 @@ function allowedips_sort() {
        usort($config['captiveportal']['allowedip'],"allowedipscmp");
 }
 
+function cpelements_sort() {
+       global $g, $config;
+
+       function cpelementscmp($a, $b) {
+               return strcasecmp($a['name'], $b['name']);
+       }
+       
+       usort($config['captiveportal']['element'],"cpelementscmp");
+}
+
 function wol_sort() {
        global $g, $config;
 
index 21b9b97612586ebeeb9c23e837305b78a43fbc91..45844511b3751b22d81576d005b4b06f5714f972 100644 (file)
@@ -4,7 +4,7 @@
        index.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
@@ -47,8 +47,16 @@ if ($fd) {
        fclose($fd);
 }
 
+if ($_POST) {
+       $config['system']['notes'] = base64_encode($_POST['notes']);
+       write_config();
+       header("Location: index.php");
+       exit;
+}
+
 ?>
 <?php include("fbegin.inc"); ?>
+<form action="" method="POST">
             <table width="100%" border="0" cellspacing="0" cellpadding="0">
               <tr align="center" valign="top"> 
                 <td height="10" colspan="2">&nbsp;</td>
@@ -145,5 +153,13 @@ echo $memUsage . "%";
 ?>
                 </td>
               </tr>
+              <tr> 
+                <td width="25%" class="vncellt" valign="top">Notes</td>
+                <td width="75%" class="listr">
+                  <textarea name="notes" cols="75" rows="7" id="notes" class="notes"><?=htmlspecialchars(base64_decode($config['system']['notes']));?></textarea><br>
+                  <input name="Submit" type="submit" class="formbtns" value="Save">
+                </td>
+              </tr>
             </table>
+</form>
             <?php include("fend.inc"); ?>
index 578f4277aedcde58438e92dfc42de99cfd30fc91..9c8dd69d9b2f526c6be916302a5a5d1b365603f0 100644 (file)
@@ -5,7 +5,7 @@
        part of m0n0wall (http://m0n0.ch/wall)
        Written by Jim McBeath based on existing m0n0wall files
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index e5b4c27a009482c5929e74480bc9b539ac5e9761..d42689f8d0f2b8cb3136e030800858ff7f5ebc4c 100644 (file)
@@ -4,7 +4,7 @@
        interfaces_lan.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 58c6aa73cc1663c225c1fe2f6593aa86adbff945..3ae74c2f5e80127d3891feea176aae4a470b9a72 100644 (file)
@@ -4,7 +4,7 @@
        interfaces_opt.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index a896fc9e05ca01f86cb0baaf1eda9be596c827ee..0258f4b0669f9e03f452998484bac6f8ca563f45 100644 (file)
@@ -4,7 +4,7 @@
        interfaces_vlan.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 4d9cf4b313c1cd916162f9e5eee820a114cda8b8..f1d724b801edeb67faa6be64ba15340f1243dddb 100644 (file)
@@ -4,7 +4,7 @@
        interfaces_vlan_edit.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index bf9d389188ab9c74c2dad432c58fab9fb6ed86c3..93232c89d5112454aa9841ed5cfae841436adaac 100644 (file)
@@ -4,7 +4,7 @@
        interfaces_wan.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 57f50dab51b4b944f427d3e9ca2316b3abd67b1f..3c481b55f1ac0a6540f2dd2827c677f47e78bb60 100644 (file)
@@ -3,7 +3,7 @@
        interfaces_wlan.inc
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 6138d5bcbf47b530a1356638cf081ed5a0aa5453..1eda7d522bbde59896448a19170a43743a146519 100644 (file)
@@ -4,7 +4,7 @@ $pgtitle = array("License");
 require("guiconfig.inc"); 
 ?>
 <?php include("fbegin.inc"); ?>
-            <p><strong>m0n0wall is Copyright &copy; 2002-2005 by Manuel Kasper 
+            <p><strong>m0n0wall is Copyright &copy; 2002-2006 by Manuel Kasper 
               (<a href="mailto:mk@neon1.net">mk@neon1.net</a>).<br>
               All rights reserved.</strong></p>
             <p> Redistribution and use in source and binary forms, with or without<br>
@@ -133,9 +133,10 @@ require("guiconfig.inc");
                          <br>
               Paul Taylor (<a href="mailto:paultaylor@winn-dixie.com">paultaylor@winn-dixie.com</a>)<br>
               &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">ARP table, Traceroute and Filter state pages</font></em><br>
+              &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">captive portal: disable concurrent logins, file manager</font></em><br>
                          <br>
               Jonathan De Graeve (<a href="mailto:Jonathan.De.Graeve@imelda.be">Jonathan.De.Graeve@imelda.be</a>)<br>
-              &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">captive portal RADIUS accounting gigawords</font></em></p>
+              &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">complete captive portal RADIUS overhaul; file manager</font></em></p>
             <hr size="1">
             <p>m0n0wall is based upon/includes various free software packages, 
               listed below.<br>
@@ -200,5 +201,8 @@ All rights reserved.<br>
                          This product includes software developed by Edwin Groothuis.<br>
                          <br>
                          wol (<a href="http://ahh.sourceforge.net/wol" target="_blank">http://ahh.sourceforge.net/wol</a>)<br>
-                         Copyright &copy; 2000,2001,2002,2003,2004 Thomas Krennwallner &lt;krennwallner@aon.at&gt;
+                         Copyright &copy; 2000,2001,2002,2003,2004 Thomas Krennwallner &lt;krennwallner@aon.at&gt;<br>
+              <br>
+              PHP RADIUS PECL package<br>
+              Copyright (c) 2003, Michael Bretterklieber &lt;michael@bretterklieber.com&gt;. All rights reserved.
 <?php include("fend.inc"); ?>
index 9723275cf464ea7343d7b4185e8ab43cc4ee0473..11b9f882b312429a9ef80a984fd5f335e82f6382 100644 (file)
@@ -4,7 +4,7 @@
        reboot.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 72332933f323c0053b295a4a3f09525b5c998fe3..b9ffdee513d0e29356a8ed45969a2acebdeb68f6 100644 (file)
@@ -4,7 +4,7 @@
        services_captiveportal.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
@@ -47,11 +47,15 @@ if ($_GET['act'] == "viewhtml") {
 }
 
 $pconfig['cinterface'] = $config['captiveportal']['interface'];
+$pconfig['maxproc'] = $config['captiveportal']['maxproc'];
+$pconfig['maxprocperip'] = $config['captiveportal']['maxprocperip'];
 $pconfig['timeout'] = $config['captiveportal']['timeout'];
 $pconfig['idletimeout'] = $config['captiveportal']['idletimeout'];
 $pconfig['enable'] = isset($config['captiveportal']['enable']);
 $pconfig['auth_method'] = $config['captiveportal']['auth_method'];
 $pconfig['radacct_enable'] = isset($config['captiveportal']['radacct_enable']);
+$pconfig['radmac_enable'] = isset($config['captiveportal']['radmac_enable']);
+$pconfig['radmac_secret'] = $config['captiveportal']['radmac_secret'];
 $pconfig['reauthenticate'] = isset($config['captiveportal']['reauthenticate']);
 $pconfig['reauthenticateacct'] = $config['captiveportal']['reauthenticateacct'];
 $pconfig['httpslogin_enable'] = isset($config['captiveportal']['httpslogin']);
@@ -60,11 +64,17 @@ $pconfig['cert'] = base64_decode($config['captiveportal']['certificate']);
 $pconfig['key'] = base64_decode($config['captiveportal']['private-key']);
 $pconfig['logoutwin_enable'] = isset($config['captiveportal']['logoutwin_enable']);
 $pconfig['nomacfilter'] = isset($config['captiveportal']['nomacfilter']);
+$pconfig['noconcurrentlogins'] = isset($config['captiveportal']['noconcurrentlogins']);
 $pconfig['redirurl'] = $config['captiveportal']['redirurl'];
 $pconfig['radiusip'] = $config['captiveportal']['radiusip'];
+$pconfig['radiusip2'] = $config['captiveportal']['radiusip2'];
 $pconfig['radiusport'] = $config['captiveportal']['radiusport'];
+$pconfig['radiusport2'] = $config['captiveportal']['radiusport2'];
 $pconfig['radiusacctport'] = $config['captiveportal']['radiusacctport'];
 $pconfig['radiuskey'] = $config['captiveportal']['radiuskey'];
+$pconfig['radiuskey2'] = $config['captiveportal']['radiuskey2'];
+$pconfig['radiusvendor'] = $config['captiveportal']['radiusvendor'];
+$pconfig['radiussession_timeout'] = isset($config['captiveportal']['radiussession_timeout']);
 
 if ($_POST) {
 
@@ -112,21 +122,38 @@ if ($_POST) {
        if (($_POST['radiusip'] && !is_ipaddr($_POST['radiusip']))) {
                $input_errors[] = "A valid IP address must be specified. [".$_POST['radiusip']."]";
        }
+       if (($_POST['radiusip2'] && !is_ipaddr($_POST['radiusip2']))) {
+               $input_errors[] = "A valid IP address must be specified. [".$_POST['radiusip2']."]";
+       }
        if (($_POST['radiusport'] && !is_port($_POST['radiusport']))) {
                $input_errors[] = "A valid port number must be specified. [".$_POST['radiusport']."]";
        }
+       if (($_POST['radiusport2'] && !is_port($_POST['radiusport2']))) {
+               $input_errors[] = "A valid port number must be specified. [".$_POST['radiusport2']."]";
+       }
        if (($_POST['radiusacctport'] && !is_port($_POST['radiusacctport']))) {
-               $input_errors[] = "A valid port number must be specified. [".$_POST['radiusport']."]";
+               $input_errors[] = "A valid port number must be specified. [".$_POST['radiusacctport']."]";
+       }
+       if ($_POST['maxproc'] && (!is_numeric($_POST['maxproc']) || ($_POST['maxproc'] < 4) || ($_POST['maxproc'] > 100))) {
+               $input_errors[] = "The total maximum number of concurrent connections must be between 4 and 100.";
+       }
+       $mymaxproc = $_POST['maxproc'] ? $_POST['maxproc'] : 16;
+       if ($_POST['maxprocperip'] && (!is_numeric($_POST['maxprocperip']) || ($_POST['maxprocperip'] > $mymaxproc))) {
+               $input_errors[] = "The maximum number of concurrent connections per client IP address may not be larger than the global maximum.";
        }
 
        if (!$input_errors) {
                $config['captiveportal']['interface'] = $_POST['cinterface'];
+               $config['captiveportal']['maxproc'] = $_POST['maxproc'];
+               $config['captiveportal']['maxprocperip'] = $_POST['maxprocperip'] ? $_POST['maxprocperip'] : false;
                $config['captiveportal']['timeout'] = $_POST['timeout'];
                $config['captiveportal']['idletimeout'] = $_POST['idletimeout'];
                $config['captiveportal']['enable'] = $_POST['enable'] ? true : false;
                $config['captiveportal']['auth_method'] = $_POST['auth_method'];
                $config['captiveportal']['radacct_enable'] = $_POST['radacct_enable'] ? true : false;
                $config['captiveportal']['reauthenticate'] = $_POST['reauthenticate'] ? true : false;
+               $config['captiveportal']['radmac_enable'] = $_POST['radmac_enable'] ? true : false;
+               $config['captiveportal']['radmac_secret'] = $_POST['radmac_secret'] ? $_POST['radmac_secret'] : false;
                $config['captiveportal']['reauthenticateacct'] = $_POST['reauthenticateacct'];
                $config['captiveportal']['httpslogin'] = $_POST['httpslogin_enable'] ? true : false;
                $config['captiveportal']['httpsname'] = $_POST['httpsname'];
@@ -134,11 +161,17 @@ if ($_POST) {
                $config['captiveportal']['private-key'] = base64_encode($_POST['key']);
                $config['captiveportal']['logoutwin_enable'] = $_POST['logoutwin_enable'] ? true : false;
                $config['captiveportal']['nomacfilter'] = $_POST['nomacfilter'] ? true : false;
+               $config['captiveportal']['noconcurrentlogins'] = $_POST['noconcurrentlogins'] ? true : false;
                $config['captiveportal']['redirurl'] = $_POST['redirurl'];
                $config['captiveportal']['radiusip'] = $_POST['radiusip'];
+               $config['captiveportal']['radiusip2'] = $_POST['radiusip2'];
                $config['captiveportal']['radiusport'] = $_POST['radiusport'];
+               $config['captiveportal']['radiusport2'] = $_POST['radiusport2'];
                $config['captiveportal']['radiusacctport'] = $_POST['radiusacctport'];
                $config['captiveportal']['radiuskey'] = $_POST['radiuskey'];
+               $config['captiveportal']['radiuskey2'] = $_POST['radiuskey2'];
+               $config['captiveportal']['radiusvendor'] = $_POST['radiusvendor'] ? $_POST['radiusvendor'] : false;
+               $config['captiveportal']['radiussession_timeout'] = $_POST['radiussession_timeout'] ? true : false;
                
                /* file upload? */
                if (is_uploaded_file($_FILES['htmlfile']['tmp_name']))
@@ -162,31 +195,48 @@ if ($_POST) {
 <script language="JavaScript">
 <!--
 function enable_change(enable_change) {
-       var endis;
+       var endis, radius_endis;
        endis = !(document.iform.enable.checked || enable_change);
+       radius_endis = !((!endis && document.iform.auth_method[2].checked) || enable_change);
        
        document.iform.cinterface.disabled = endis;
+       document.iform.maxproc.disabled = endis;
+       document.iform.maxprocperip.disabled = endis;
        document.iform.idletimeout.disabled = endis;
        document.iform.timeout.disabled = endis;
        document.iform.redirurl.disabled = endis;
-       document.iform.radiusip.disabled = endis;
-       document.iform.radiusport.disabled = endis;
-       document.iform.radiuskey.disabled = endis;
-       document.iform.radacct_enable.disabled = endis;
-       document.iform.radiusacctport.disabled = endis;
-       document.iform.reauthenticate.disabled = endis;
-       document.iform.reauthenticateacct.disabled = endis;
+       document.iform.radiusip.disabled = radius_endis;
+       document.iform.radiusip2.disabled = radius_endis;
+       document.iform.radiusport.disabled = radius_endis;
+       document.iform.radiusport2.disabled = radius_endis;
+       document.iform.radiuskey.disabled = radius_endis;
+       document.iform.radiuskey2.disabled = radius_endis;
+       document.iform.radacct_enable.disabled = radius_endis;
+       document.iform.reauthenticate.disabled = radius_endis;
        document.iform.auth_method[0].disabled = endis;
        document.iform.auth_method[1].disabled = endis;
        document.iform.auth_method[2].disabled = endis;
+       document.iform.radmac_enable.disabled = radius_endis;
        document.iform.httpslogin_enable.disabled = endis;
        document.iform.httpsname.disabled = endis;
        document.iform.cert.disabled = endis;
        document.iform.key.disabled = endis;
        document.iform.logoutwin_enable.disabled = endis;
        document.iform.nomacfilter.disabled = endis;
+       document.iform.noconcurrentlogins.disabled = endis;
+       document.iform.radiusvendor.disabled = radius_endis;
+       document.iform.radiussession_timeout.disabled = radius_endis;
        document.iform.htmlfile.disabled = endis;
        document.iform.errfile.disabled = endis;
+       
+       document.iform.radiusacctport.disabled = (radius_endis || !document.iform.radacct_enable.checked) && !enable_change;
+       
+       document.iform.radmac_secret.disabled = (radius_endis || !document.iform.radmac_enable.checked) && !enable_change;
+       
+       var reauthenticate_dis = (radius_endis || !document.iform.reauthenticate.checked) && !enable_change;
+       document.iform.reauthenticateacct[0].disabled = reauthenticate_dis;
+       document.iform.reauthenticateacct[1].disabled = reauthenticate_dis;
+       document.iform.reauthenticateacct[2].disabled = reauthenticate_dis;
 }
 //-->
 </script>
@@ -200,6 +250,7 @@ function enable_change(enable_change) {
        <li class="tabinact"><a href="services_captiveportal_mac.php">Pass-through MAC</a></li>
        <li class="tabinact"><a href="services_captiveportal_ip.php">Allowed IP addresses</a></li>
        <li class="tabinact"><a href="services_captiveportal_users.php">Users</a></li>
+       <li class="tabinact"><a href="services_captiveportal_filemanager.php">File manager</a></li>
   </ul>
   </td></tr>
   <tr>
@@ -228,6 +279,21 @@ function enable_change(enable_change) {
                </select> <br>
                <span class="vexpl">Choose which interface to run the captive portal on.</span></td>
        </tr>
+       <tr>
+         <td valign="top" class="vncell">Maximum concurrent connections</td>
+         <td class="vtable">
+               <table cellpadding="0" cellspacing="0">
+                 <tr>
+           <td><input name="maxprocperip" type="text" class="formfld" id="maxprocperip" size="5" value="<?=htmlspecialchars($pconfig['maxprocperip']);?>"> per client IP address (0 = no limit)</td>
+                 </tr>
+                 <tr>
+           <td><input name="maxproc" type="text" class="formfld" id="maxproc" size="5" value="<?=htmlspecialchars($pconfig['maxproc']);?>"> total</td>
+                 </tr>
+               </table>
+This setting limits the number of concurrent connections to the captive portal HTTP(S) server. This does not set how many users can be logged in
+to the captive portal, but rather how many users can load the portal page or authenticate at the same time!
+Default is 4 connections per client IP address, with a total maximum of 16 connections.</td>
+       </tr>
        <tr>
          <td valign="top" class="vncell">Idle timeout</td>
          <td class="vtable">
@@ -258,69 +324,169 @@ If you provide a URL here, clients will be redirected to that URL instead of the
 to access after they've authenticated.</td>
        </tr>
        <tr>
+      <td valign="top" class="vncell">Concurrent user logins</td>
+      <td class="vtable">
+       <input name="noconcurrentlogins" type="checkbox" class="formfld" id="noconcurrentlogins" value="yes" <?php if ($pconfig['noconcurrentlogins']) echo "checked"; ?>>
+       <strong>Disable concurrent logins</strong><br>
+       If this option is set, only the most recent login per username will be active. Subsequent logins will cause machines previously logged in with the same username to be disconnected.</td>
+       </tr>
+       <tr>
       <td valign="top" class="vncell">MAC filtering </td>
       <td class="vtable">
         <input name="nomacfilter" type="checkbox" class="formfld" id="nomacfilter" value="yes" <?php if ($pconfig['nomacfilter']) echo "checked"; ?>>
         <strong>Disable MAC filtering</strong><br>
-    If this option is set, no attempts will be made to ensure that the MAC address of clients stays the same while they're logged in. This is required when the MAC address of cannot be determined (usually because there are routers between m0n0wall and the clients).</td>
+    If this option is set, no attempts will be made to ensure that the MAC address of clients stays the same while they're logged in.
+    This is required when the MAC address of the client cannot be determined (usually because there are routers between m0n0wall and the clients).
+    If this is enabled, RADIUS MAC authentication cannot be used.</td>
          </tr>
        <tr> 
          <td width="22%" valign="top" class="vncell">Authentication</td>
          <td width="78%" class="vtable"> 
                <table cellpadding="0" cellspacing="0">
                <tr>
-                 <td colspan="2"><input name="auth_method" type="radio" id="auth_method" value="none" <?php if($pconfig['auth_method']!="local" && $pconfig['auth_method']!="radius") echo "checked"; ?>>
+                 <td colspan="2"><input name="auth_method" type="radio" id="auth_method" value="none" onClick="enable_change(false)" <?php if($pconfig['auth_method']!="local" && $pconfig['auth_method']!="radius") echo "checked"; ?>>
   No authentication</td>  
                  </tr>
                <tr>
-                 <td colspan="2"><input name="auth_method" type="radio" id="auth_method" value="local" <?php if($pconfig['auth_method']=="local") echo "checked"; ?>>
+                 <td colspan="2"><input name="auth_method" type="radio" id="auth_method" value="local" onClick="enable_change(false)" <?php if($pconfig['auth_method']=="local") echo "checked"; ?>>
   Local <a href="services_captiveportal_users.php">user manager</a></td>  
                  </tr>
                <tr>
-                 <td colspan="2"><input name="auth_method" type="radio" id="auth_method" value="radius" <?php if($pconfig['auth_method']=="radius") echo "checked"; ?>>
+                 <td colspan="2"><input name="auth_method" type="radio" id="auth_method" value="radius" onClick="enable_change(false)" <?php if($pconfig['auth_method']=="radius") echo "checked"; ?>>
   RADIUS authentication</td>  
                  </tr><tr>
                  <td>&nbsp;</td>
                  <td>&nbsp;</td>
                  </tr>
-               <tr>
-               <td>IP address:</td>
-               <td><input name="radiusip" type="text" class="formfld" id="radiusip" size="20" value="<?=htmlspecialchars($pconfig['radiusip']);?>"></td>
-               </tr><tr>
-               <td>Port:</td>
-               <td><input name="radiusport" type="text" class="formfld" id="radiusport" size="5" value="<?=htmlspecialchars($pconfig['radiusport']);?>"></td>
-               </tr><tr>
-               <td>Shared secret:&nbsp;&nbsp;</td>
-               <td><input name="radiuskey" type="text" class="formfld" id="radiuskey" size="16" value="<?=htmlspecialchars($pconfig['radiuskey']);?>"> </td>
-               </tr>
-               <tr>
-          <td>Accounting:&nbsp;&nbsp;</td>
-          <td><input name="radacct_enable" type="checkbox" id="radacct_enable" value="yes" <?php if($pconfig['radacct_enable']) echo "checked"; ?>>
-          send RADIUS accounting packets</td>
-                 </tr>
-               <tr>
-          <td>Accounting port:&nbsp;&nbsp;</td>
-          <td><input name="radiusacctport" type="text" class="formfld" id="radiusacctport" size="5" value="<?=htmlspecialchars($pconfig['radiusacctport']);?>"></td>
-                 </tr>
-               <tr>
-          <td valign="top">Reauthentication:&nbsp;&nbsp;</td>
-          <td><input name="reauthenticate" type="checkbox" id="reauthenticate" value="yes" <?php if($pconfig['reauthenticate']) echo "checked"; ?>>
-          reauthenticate connected users every minute<br><br>
-          <input name="reauthenticateacct" type="radio" value="" <?php if(!$pconfig['reauthenticateacct']) echo "checked"; ?>> no accounting updates<br>
-          <input name="reauthenticateacct" type="radio" value="stopstart" <?php if($pconfig['reauthenticateacct'] == "stopstart") echo "checked"; ?>> stop/start accounting<br>
-          <input name="reauthenticateacct" type="radio" value="interimupdate" <?php if($pconfig['reauthenticateacct'] == "interimupdate") echo "checked"; ?>> interim update</td>
-                 </tr>
                </table>
-               <br>
-       When using RADIUS authentication, enter the IP address and port of the RADIUS server which users of the captive portal have to authenticate against.  Leave port number blank to use the default port (1812). Leave the RADIUS shared secret blank to not use a RADIUS shared secret. RADIUS accounting packets will also be sent to the RADIUS server if  accounting is enabled (default port is 1813).
-       <br><br>If reauthentication is enabled, Access-Requests will be sent to the RADIUS server for each user that is logged in every minute. If an Access-Reject is received for a user, that user is disconnected from the captive portal immediately.
+               <table width="100%" border="0" cellpadding="6" cellspacing="0">
+               <tr> 
+               <td colspan="2" valign="top" class="optsect_t2">Primary RADIUS server</td>
+                       </tr>
+                       <tr>
+                               <td class="vncell" valign="top">IP address</td>
+                               <td class="vtable"><input name="radiusip" type="text" class="formfld" id="radiusip" size="20" value="<?=htmlspecialchars($pconfig['radiusip']);?>"><br>
+                               Enter the IP address of the RADIUS server which users of the captive portal have to authenticate against.</td>
+                       </tr>
+                       <tr>
+                               <td class="vncell" valign="top">Port</td>
+                               <td class="vtable"><input name="radiusport" type="text" class="formfld" id="radiusport" size="5" value="<?=htmlspecialchars($pconfig['radiusport']);?>"><br>
+                                Leave this field blank to use the default port (1812).</td>
+                       </tr>
+                       <tr>
+                               <td class="vncell" valign="top">Shared secret&nbsp;&nbsp;</td>
+                               <td class="vtable"><input name="radiuskey" type="text" class="formfld" id="radiuskey" size="16" value="<?=htmlspecialchars($pconfig['radiuskey']);?>"><br>
+                               Leave this field blank to not use a RADIUS shared secret (not recommended).</td>
+                       </tr>
+                       <tr> 
+                         <td colspan="2" class="list" height="12"></td>
+                       </tr>
+                       <tr>
+                               <td colspan="2" valign="top" class="optsect_t2">Secondary RADIUS server</td>
+                       </tr>
+                       <tr>
+                               <td class="vncell" valign="top">IP address</td>
+                               <td class="vtable"><input name="radiusip2" type="text" class="formfld" id="radiusip2" size="20" value="<?=htmlspecialchars($pconfig['radiusip2']);?>"><br>
+                               If you have a second RADIUS server, you can activate it by entering its IP address here.</td>
+                       </tr>
+                       <tr>
+                               <td class="vncell" valign="top">Port</td>
+                               <td class="vtable"><input name="radiusport2" type="text" class="formfld" id="radiusport2" size="5" value="<?=htmlspecialchars($pconfig['radiusport2']);?>"></td>
+                       </tr>
+                       <tr>
+                               <td class="vncell" valign="top">Shared secret&nbsp;&nbsp;</td>
+                               <td class="vtable"><input name="radiuskey2" type="text" class="formfld" id="radiuskey2" size="16" value="<?=htmlspecialchars($pconfig['radiuskey2']);?>"></td>
+                       </tr>
+                       <tr> 
+                         <td colspan="2" class="list" height="12"></td>
+                       </tr>
+                       <tr>
+                               <td colspan="2" valign="top" class="optsect_t2">Accounting</td>
+                       </tr>
+                       <tr>
+                               <td class="vncell">&nbsp;</td>
+                               <td class="vtable"><input name="radacct_enable" type="checkbox" id="radacct_enable" value="yes" onClick="enable_change(false)" <?php if($pconfig['radacct_enable']) echo "checked"; ?>>
+                               <strong>send RADIUS accounting packets</strong><br>
+                               If this is enabled, RADIUS accounting packets will be sent to the primary RADIUS server.</td>
+                       </tr>
+                       <tr>
+                         <td class="vncell" valign="top">Accounting port</td>
+                         <td class="vtable"><input name="radiusacctport" type="text" class="formfld" id="radiusacctport" size="5" value="<?=htmlspecialchars($pconfig['radiusacctport']);?>"><br>
+                         Leave blank to use the default port (1813).</td>
+                         </tr>
+                       <tr>
+                         <td colspan="2" class="list" height="12"></td>
+                       </tr>
+                       <tr>
+                               <td colspan="2" valign="top" class="optsect_t2">Reauthentication</td>
+                       </tr>
+                       <tr>
+                               <td class="vncell">&nbsp;</td>
+                               <td class="vtable"><input name="reauthenticate" type="checkbox" id="reauthenticate" value="yes" onClick="enable_change(false)" <?php if($pconfig['reauthenticate']) echo "checked"; ?>>
+                         <strong>Reauthenticate connected users every minute</strong><br>
+                         If reauthentication is enabled, Access-Requests will be sent to the RADIUS server for each user that is
+                         logged in every minute. If an Access-Reject is received for a user, that user is disconnected from the captive portal immediately.</td>
+                       </tr>
+                       <tr>
+                         <td class="vncell" valign="top">Accounting updates</td>
+                         <td class="vtable">
+                         <input name="reauthenticateacct" type="radio" value="" <?php if(!$pconfig['reauthenticateacct']) echo "checked"; ?>> no accounting updates<br>
+                         <input name="reauthenticateacct" type="radio" value="stopstart" <?php if($pconfig['reauthenticateacct'] == "stopstart") echo "checked"; ?>> stop/start accounting<br>
+                         <input name="reauthenticateacct" type="radio" value="interimupdate" <?php if($pconfig['reauthenticateacct'] == "interimupdate") echo "checked"; ?>> interim update
+                         </td>
+                       </tr>
+                       <tr>
+                         <td colspan="2" class="list" height="12"></td>
+                       </tr>
+                       <tr>
+                               <td colspan="2" valign="top" class="optsect_t2">RADIUS MAC authentication</td>
+                       </tr>
+                       <tr>
+                               <td class="vncell">&nbsp;</td>
+                               <td class="vtable">
+                               <input name="radmac_enable" type="checkbox" id="radmac_enable" value="yes" onClick="enable_change(false)" <?php if ($pconfig['radmac_enable']) echo "checked"; ?>><strong>Enable RADIUS MAC authentication</strong><br>
+                               If this option is enabled, the captive portal will try to authenticate users by sending their MAC address as the username and the password
+                               entered below to the RADIUS server.</td>
+                       </tr>
+                       <tr>
+                               <td class="vncell">Shared secret</td>
+                               <td class="vtable"><input name="radmac_secret" type="text" class="formfld" id="radmac_secret" size="16" value="<?=htmlspecialchars($pconfig['radmac_secret']);?>"></td>
+                       </tr>
+                       <tr>
+                         <td colspan="2" class="list" height="12"></td>
+                       </tr>
+                       <tr>
+                               <td colspan="2" valign="top" class="optsect_t2">RADIUS options</td>
+                       </tr>
+                       <tr>
+                               <td class="vncell" valign="top">Session-Timeout</td>
+                               <td class="vtable"><input name="radiussession_timeout" type="checkbox" id="radiussession_timeout" value="yes" <?php if ($pconfig['radiussession_timeout']) echo "checked"; ?>><strong>Use RADIUS Session-Timeout attributes</strong><br>
+                               When this is enabled, clients will be disconnected after the amount of time retrieved from the RADIUS Session-Timeout attribute.</td>
+                       </tr>
+                       <tr>
+                               <td class="vncell" valign="top">Type</td>
+                               <td class="vtable"><select name="radiusvendor" id="radiusvendor">
+                               <option>default</option>
+                               <?php 
+                               $radiusvendors = array("cisco");
+                               foreach ($radiusvendors as $radiusvendor){
+                                       if ($pconfig['radiusvendor'] == $radiusvendor)
+                                               echo "<option selected value=\"$radiusvendor\">$radiusvendor</option>\n";
+                                       else
+                                               echo "<option value=\"$radiusvendor\">$radiusvendor</option>\n";
+                               }
+                               ?></select><br>
+                               If RADIUS type is set to Cisco, in Access-Requests the value of Calling-Station-Id will be set to the client's IP address and
+                               the Called-Station-Id to the client's MAC address. Default behaviour is Calling-Station-Id = client's MAC address and Called-Station-Id = m0n0wall's WAN IP address.</td>
+                       </tr>
+               </table>
        </tr>
        <tr>
       <td valign="top" class="vncell">HTTPS login</td>
       <td class="vtable">
         <input name="httpslogin_enable" type="checkbox" class="formfld" id="httpslogin_enable" value="yes" <?php if($pconfig['httpslogin_enable']) echo "checked"; ?>>
         <strong>Enable HTTPS login</strong><br>
-    If enabled, the username and password will be transmitted over an HTTPS connection to protect against eavesdroppers. This option only applies when RADIUS authentication is used. A server name, certificate and matching private key must also be specified below.</td>
+    If enabled, the username and password will be transmitted over an HTTPS connection to protect against eavesdroppers. A server name, certificate and matching private key must also be specified below.</td>
          </tr>
        <tr>
       <td valign="top" class="vncell">HTTPS server name </td>
@@ -352,7 +518,9 @@ to access after they've authenticated.</td>
                  <br>
                <?php endif; ?>
                  Upload an HTML file for the portal page here (leave blank to keep the current one). Make sure to include a form (POST to &quot;$PORTAL_ACTION$&quot;)
-with a submit button (name=&quot;accept&quot;) and a hidden field with name=&quot;redirurl&quot; and value=&quot;$PORTAL_REDIRURL$&quot;. Include the &quot;auth_user&quot; and &quot;auth_pass&quot; input elements if RADIUS authentication is enabled. If RADIUS is enabled and no &quot;auth_user&quot; is present, authentication will always fail. If RADIUS is not enabled, you can omit both of these input elements. Example code for the form:<br>
+with a submit button (name=&quot;accept&quot;) and a hidden field with name=&quot;redirurl&quot; and value=&quot;$PORTAL_REDIRURL$&quot;.
+Include the &quot;auth_user&quot; and &quot;auth_pass&quot; input fields if authentication is enabled, otherwise it will always fail.
+Example code for the form:<br>
                  <br>
                  <tt>&lt;form method=&quot;post&quot; action=&quot;$PORTAL_ACTION$&quot;&gt;<br>
                  &nbsp;&nbsp;&nbsp;&lt;input name=&quot;auth_user&quot; type=&quot;text&quot;&gt;<br>
@@ -372,7 +540,8 @@ with a submit button (name=&quot;accept&quot;) and a hidden field with name=&quo
                  <br>
                  <br>
                <?php endif; ?>
-The contents of the HTML file that you upload here are displayed when a RADIUS authentication error occurs.</td>
+The contents of the HTML file that you upload here are displayed when an authentication error occurs.
+You may include &quot;$PORTAL_MESSAGE$&quot;, which will be replaced by the error or reply messages from the RADIUS server, if any.</td>
        </tr>
        <tr> 
          <td width="22%" valign="top">&nbsp;</td>
diff --git a/webgui/services_captiveportal_filemanager.php b/webgui/services_captiveportal_filemanager.php
new file mode 100644 (file)
index 0000000..cb0a7de
--- /dev/null
@@ -0,0 +1,165 @@
+#!/usr/local/bin/php
+<?php
+/*
+       services_captiveportal_filemanager.php
+       part of m0n0wall (http://m0n0.ch/wall)
+
+       Copyright (C) 2005-2006 Jonathan De Graeve (jonathan.de.graeve@imelda.be)
+       and Paul Taylor (paultaylor@winn-dixie.com).
+       All rights reserved.
+
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+$pgtitle = array("Services", "Captive portal");
+
+require_once("guiconfig.inc");
+
+if (!is_array($config['captiveportal']['element']))
+       $config['captiveportal']['element'] = array();
+
+cpelements_sort();
+$a_element = &$config['captiveportal']['element'];
+
+// Calculate total size of all files
+$total_size = 0;
+foreach ($a_element as $element) {
+       $total_size += $element['size'];
+}
+
+if ($_POST) {
+    unset($input_errors);
+    
+    if (is_uploaded_file($_FILES['new']['tmp_name'])) {
+       
+       $name = $_FILES['new']['name'];
+       $size = filesize($_FILES['new']['tmp_name']);
+       
+       // is there already a file with that name?
+       foreach ($a_element as $element) {
+                       if ($element['name'] == $name) {
+                               $input_errors[] = "A file with the name '$name' already exists.";
+                               break;
+                       }
+               }
+               
+               // check total file size
+               if (($total_size + $size) > $g['captiveportal_element_sizelimit']) {
+                       $input_errors[] = "The total size of all files uploaded may not exceed " .
+                               format_bytes($g['captiveportal_element_sizelimit']) . ".";
+               }
+               
+               if (!$input_errors) {
+                       $element = array();
+                       $element['name'] = $name;
+                       $element['size'] = $size;
+                       $element['content'] = base64_encode(file_get_contents($_FILES['new']['tmp_name']));
+                       
+                       $a_element[] = $element;
+                       
+                       write_config();
+                       captiveportal_write_elements();
+                       header("Location: services_captiveportal_filemanager.php");
+                       exit;
+               }
+    }
+} else {
+       if (($_GET['act'] == "del") && $a_element[$_GET['id']]) {
+               unset($a_element[$_GET['id']]);
+               write_config();
+               captiveportal_write_elements();
+               header("Location: services_captiveportal_filemanager.php");
+               exit;
+       }
+}
+
+?>
+<?php include("fbegin.inc"); ?>
+<form action="services_captiveportal_filemanager.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr><td class="tabnavtbl">
+  <ul id="tabnav">
+        <li class="tabinact"><a href="services_captiveportal.php">Captive portal</a></li>
+        <li class="tabinact"><a href="services_captiveportal_mac.php">Pass-through MAC</a></li>
+        <li class="tabinact"><a href="services_captiveportal_ip.php">Allowed IP addresses</a></li>
+        <li class="tabinact"><a href="services_captiveportal_users.php">Users</a></li>
+        <li class="tabact">File manager</li>
+        </ul>
+  </td></tr>
+  <tr>
+    <td class="tabcont">
+       <table width="80%" border="0" cellpadding="0" cellspacing="0">
+      <tr>
+        <td width="70%" class="listhdrr">Name</td>
+        <td width="20%" class="listhdr">Size</td>
+        <td width="10%" class="list"></td>
+      </tr>
+  <?php $i = 0; foreach ($a_element as $element): ?>
+         <tr>
+               <td class="listlr"><?=htmlspecialchars($element['name']);?></td>
+               <td class="listr" align="right"><?=format_bytes($element['size']);?></td>
+               <td valign="middle" nowrap class="list">
+               <a href="services_captiveportal_filemanager.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this file?')"><img src="x.gif" title="delete file" width="17" height="17" border="0"></a>
+               </td>
+         </tr>
+  <?php $i++; endforeach; ?>
+  
+  <?php if (count($a_element) > 0): ?>
+         <tr>
+               <td class="listlr" style="background-color: #eee"><strong>TOTAL</strong></td>
+               <td class="listr" style="background-color: #eee" align="right"><strong><?=format_bytes($total_size);?></strong></td>
+               <td valign="middle" nowrap class="list"></td>
+         </tr>
+  <?php endif; ?>
+  
+  <?php if ($_GET['act'] == 'add'): ?>
+         <tr>
+               <td class="listlr" colspan="2"><input type="file" name="new" class="formfld" size="40" id="new"> 
+               <input name="Submit" type="submit" class="formbtn" value="Upload"></td>
+               <td valign="middle" nowrap class="list">
+               <a href="services_captiveportal_filemanager.php"><img src="x.gif" title="cancel" width="17" height="17" border="0"></a>
+               </td>
+         </tr>
+  <?php else: ?>
+         <tr>
+               <td class="list" colspan="2"></td>
+               <td class="list"> <a href="services_captiveportal_filemanager.php?act=add"><img src="plus.gif" title="add file" width="17" height="17" border="0"></a></td>
+         </tr>
+  <?php endif; ?>
+       </table>
+       <span class="vexpl"><span class="red"><strong>
+       Note:<br>
+       </strong></span>
+       Any files that you upload here will be made available in the root directory
+       of the captive portal HTTP(S) server. You may reference them directly from
+       your portal page HTML code using relative paths. Example: you've uploaded
+       an image with the name 'test.jpg' using the file manager. Then you can
+       include it in your portal page like this:<br><br>
+       <tt>&lt;img src=&quot;test.jpg&quot; width=... height=...&gt;</tt>
+       <br><br>
+       The total size limit for all files is <?=format_bytes($g['captiveportal_element_sizelimit']);?>.</span>
+</td>
+</tr>
+</table>
+</form>
+<?php include("fend.inc"); ?>  
index 22664969ec51bec5094adf9b07d763bcf69e097e..e827b4cbd91a8f7cd6a42aa7ff9641eae0f8e843 100644 (file)
@@ -82,6 +82,7 @@ if ($_GET['act'] == "del") {
        <li class="tabinact"><a href="services_captiveportal_mac.php">Pass-through MAC</a></li>
        <li class="tabact">Allowed IP addresses</li>
        <li class="tabinact"><a href="services_captiveportal_users.php">Users</a></li>
+       <li class="tabinact"><a href="services_captiveportal_filemanager.php">File manager</a></li>
   </ul>
   </td></tr>
   <tr>
index 056b90fd0b10ce76143bf1c955bb700ad093cbc8..9f3f2db7bb9b9b59be7c872bc9d12ba04cfef776 100644 (file)
@@ -82,6 +82,7 @@ if ($_GET['act'] == "del") {
        <li class="tabact">Pass-through MAC</li>
        <li class="tabinact"><a href="services_captiveportal_ip.php">Allowed IP addresses</a></li>
        <li class="tabinact"><a href="services_captiveportal_users.php">Users</a></li>
+       <li class="tabinact"><a href="services_captiveportal_filemanager.php">File manager</a></li>
   </ul>
   </td></tr>
   <tr>
index 370f5307f898a283036a664f64b85828a0cf4b70..ca7fcd61f74eb0a9424308d70ab624195586bea2 100644 (file)
@@ -4,7 +4,7 @@
        services_captiveportal_users.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        Copyright (C) 2005 Pascal Suter <d-monodev@psuter.ch>.
        All rights reserved. 
@@ -72,6 +72,7 @@ if ($changed) {
        <li class="tabinact"><a href="services_captiveportal_mac.php">Pass-through MAC</a></li>
        <li class="tabinact"><a href="services_captiveportal_ip.php">Allowed IP addresses</a></li>
        <li class="tabact">Users</li>
+       <li class="tabinact"><a href="services_captiveportal_filemanager.php">File manager</a></li>
   </ul>
   </td></tr>
   <tr>
index 9607f266d4035f9cbd798477cf11dc14915e9dc2..d8fea4e637c1ae2d8ed064e7d987c749ae351490 100644 (file)
@@ -4,7 +4,7 @@
        services_captiveportal_users_edit.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        Copyright (C) 2005 Pascal Suter <d-monodev@psuter.ch>.
        All rights reserved. 
index 4f1b60d025bd15ec2a6c130b8fa19c7b0f6a147f..ba001cc91549aabb99c3cacb4c47f49437c2ef03 100644 (file)
@@ -4,7 +4,7 @@
        services_dhcp.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index e531b6e67de59508d38254034079dff1f5eaf94c..2ad3117b56880e901d92544136065e369c8cffa4 100644 (file)
@@ -4,7 +4,7 @@
        services_dhcp_edit.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 2fff1727a766d54c32303243bbd6a67887e00acf..f618ed0efb979c98dc0190292468496f18167bb9 100644 (file)
@@ -4,7 +4,7 @@
        services_dnsmasq_domainoverride_edit.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index e7cf037fa9c97635cc46a2e1c642bf22265bf8f7..0cdfe30fe1749e95d52a18754284950701598e0d 100644 (file)
@@ -4,7 +4,7 @@
        services_dyndns.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 13a3dad4d2444e7e9e36e0da3a375cb80287cdf4..7eeb5ddf69bccaa6724070da1708e4b870e7519c 100644 (file)
@@ -4,7 +4,7 @@
        services_proxyarp.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index d5a08835c0270f635a12204bcc611dada5fcb025..7bcbe8e549b55ac8191d8c586bf8e685dfb9c641 100644 (file)
@@ -4,7 +4,7 @@
        services_proxyarp_edit.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 28e294ffb4d2fb444e85f413167583fdb1af1997..7243a2c3351ac1e66a98c321e96752583614af64 100644 (file)
@@ -4,7 +4,7 @@
        services_snmp.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
@@ -41,6 +41,7 @@ $pconfig['syslocation'] = $config['snmpd']['syslocation'];
 $pconfig['syscontact'] = $config['snmpd']['syscontact'];
 $pconfig['rocommunity'] = $config['snmpd']['rocommunity'];
 $pconfig['enable'] = isset($config['snmpd']['enable']);
+$pconfig['bindlan'] = isset($config['snmpd']['bindlan']);
 
 if ($_POST) {
 
@@ -60,6 +61,7 @@ if ($_POST) {
                $config['snmpd']['syscontact'] = $_POST['syscontact'];
                $config['snmpd']['rocommunity'] = $_POST['rocommunity'];
                $config['snmpd']['enable'] = $_POST['enable'] ? true : false;
+               $config['snmpd']['bindlan'] = $_POST['bindlan'] ? true : false;
                        
                write_config();
                
@@ -82,6 +84,7 @@ function enable_change(enable_change) {
        document.iform.syslocation.disabled = endis;
        document.iform.syscontact.disabled = endis;
        document.iform.rocommunity.disabled = endis;
+       document.iform.bindlan.disabled = endis;
 }
 //-->
 </script>
@@ -114,6 +117,14 @@ function enable_change(enable_change) {
                     <br>
                     In most cases, &quot;public&quot; is used here</td>
                 </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vtable"></td>
+                  <td width="78%" class="vtable"> 
+                    <input name="bindlan" type="checkbox" value="yes" <?php if ($pconfig['bindlan']) echo "checked"; ?>> <strong>Bind to LAN interface only</strong>
+                    <br>
+                    This option can be useful when trying to access the SNMP agent
+                    by the LAN interface's IP address through a VPN tunnel terminated on the WAN interface.</td>
+                </tr>
                 <tr> 
                   <td width="22%" valign="top">&nbsp;</td>
                   <td width="78%"> 
index abcb16ac708d9bb05258a25cc252dc57556efbc9..f2d8f8e7172cad7494a4966a30f045641a3bb783 100644 (file)
@@ -4,7 +4,7 @@
        services_wol.php
        part of m0n0wall (http://m0n0.ch/wall)
 
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
 
        Redistribution and use in source and binary forms, with or without
index 3e25b04be7c6854daf39099ba3a6041602d8ce0b..e66a3ccbfb4a1593eb6f6ed69d1baefae336a220 100644 (file)
@@ -4,7 +4,7 @@
        services_wol_edit.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 21cb03a80f21332bdf5b6220fd90c53482f40f0f..42f709c1011a20ca9339404e9814f051aa662f2d 100644 (file)
@@ -4,7 +4,7 @@
        status_captiveportal.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
@@ -36,7 +36,7 @@ require("guiconfig.inc");
 <?php
 
 if ($_GET['act'] == "del") {
-       captiveportal_disconnect_client($_GET['id']);
+       captiveportal_disconnect_client($_GET['id'],6);
 }
 
 flush();
index dfd928db35d6c76e64e5912ab1c167fd94f6676d..70fcca4b45b0f22d30c6d9a264143519ac275554 100644 (file)
@@ -4,7 +4,7 @@
        status_graph.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index b44d8a09e3dadf942fa3784dce576b17a594f6f8..04c6fa3ed0dc51adf71281a38e6ca261b29e00f3 100644 (file)
@@ -4,7 +4,7 @@
        status_graph_cpu.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 138d6fa1a4ebef9b1a0959705e2a53dd2d48403d..b9a4d5cc346c4e2dead7ae1ada71b4f3f05b500e 100644 (file)
@@ -4,7 +4,7 @@
        status_interfaces.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index f8771bb7a9b603519722ceeec7349f674f5fd354..1f11a7ff9ea3bc33566eadda9c7e209efc3991c9 100644 (file)
@@ -4,7 +4,7 @@
        status_wireless.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index a75ebf22ec54ddfb1f083662a8517c1b6fd8fc1b..739b5427458a79a3e8ad505f9210f450775fd7cd 100644 (file)
@@ -4,7 +4,7 @@
        system.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index e6083a99cd08039ca28fa46ae9f9361f85862861..26c1694c16a4b7feb8ca42090906fe68ed3db278 100644 (file)
@@ -4,7 +4,7 @@
        system_advanced.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index dc7edf4d3f4a842f0682c6d717648574db5bebb1..de14d3e911f3d366c7338400795f965a41a2a8bd 100644 (file)
@@ -4,7 +4,7 @@
        system_firmware.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index a6fb970e2982a498d881d8bd4834e8f71b2110f9..2bbfd4884e884958e7aaa350bf094cb71925f1ed 100644 (file)
@@ -4,7 +4,7 @@
        system_routes.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 76519e384af755a8af786f34c064152d5e475ae7..3b8394a860d2b02a5ca5cc74b64f0a3bd693e8fc 100644 (file)
@@ -4,7 +4,7 @@
        system_routes_edit.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index a86b56b310eed2d20ec66b8b750a9febd1265be6..364cbfe46dcf23f579d1c319c413899a3b976d73 100644 (file)
@@ -4,7 +4,7 @@
        uploadconfig.php
        part of m0n0wall (http://m0n0.ch/wall)
 
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
 
        Redistribution and use in source and binary forms, with or without
index 9a52898b8d55d138dee3435f7e2d286213cfca64..2fc3d4161f34d289f84bd8fc38c26e952be41739 100644 (file)
@@ -4,7 +4,7 @@
        vpn_ipsec.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index bb54ac729c31d9262b92953282f441acb5832146..2cad319cccf0f3bcd96ade7199a045afa99d189f 100644 (file)
@@ -4,7 +4,7 @@
        vpn_ipsec_ca.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 687d3401901d0cba07a251b72bac7dc0dd607526..20046c35a5987f8b0c2b1d02cdc2f72338dfd379 100644 (file)
@@ -4,7 +4,7 @@
        vpn_ipsec_ca_edit.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index cb1a302395adc4c3e55f6926787394a1bf374a81..adbe310d2d19f1f747d948a4c5fc5d04b69836c4 100644 (file)
@@ -4,7 +4,7 @@
        vpn_ipsec_edit.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 676e569a56fd701217a70d52219c24d080c8e517..c108653968ea1ab254ed7c99d3fded655fd759ac 100644 (file)
@@ -4,7 +4,7 @@
        vpn_ipsec_keys.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 349158560c1b293ba6d670106d11ad8c2a7cb4af..a037d8eb5af21b60a674de3e46a3f106699d7c45 100644 (file)
@@ -4,7 +4,7 @@
        vpn_ipsec_keys_edit.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 0a1097751a65dbef03d0bd4249f6a3430fa1a64c..b1f7e9365d87bbaa5a2c2dec0c6fade278abb595 100644 (file)
@@ -4,7 +4,7 @@
        vpn_ipsec_mobile.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 43a19e5ef31a93888614f74392af43fe4c13d9a9..12ffa53c92299cc9ce37317acce398d375a06381 100644 (file)
@@ -4,7 +4,7 @@
        vpn_pptp.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index 2e4c47a72e95f865273ab50a618900401c874841..56a6c4283590c230653a496b07f8b2187a35ae6a 100644 (file)
@@ -4,7 +4,7 @@
        vpn_pptp_users.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
index bbeddc1385917aa586d0fee7706e03a5568d6aaa..323fddc3e0b7aa30e8d0cde31d4ea7ec989994e7 100644 (file)
@@ -4,7 +4,7 @@
        vpn_pptp_users_edit.php
        part of m0n0wall (http://m0n0.ch/wall)
        
-       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>.
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without