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

50 files changed:
captiveportal/index.php
phpconf/config.xml
phpconf/inc/config.inc
phpconf/inc/filter.inc
phpconf/inc/globals.inc
phpconf/inc/openvpn.inc
phpconf/inc/services.inc
phpconf/inc/system.inc
phpconf/inc/util.inc
phpconf/inc/xmlparse.inc
phpconf/rc.bootup
phpconf/rc.newwanip
webgui/diag_arp.php [new file with mode: 0644]
webgui/diag_ipfstat.php [new file with mode: 0644]
webgui/diag_logs.php
webgui/diag_logs_dhcp.php
webgui/diag_logs_filter.php
webgui/diag_logs_portal.php
webgui/diag_logs_vpn.php
webgui/diag_ping.php
webgui/diag_traceroute.php [new file with mode: 0644]
webgui/fbegin.inc
webgui/firewall_nat_1to1_edit.php
webgui/firewall_shaper_magic.php
webgui/firewall_shaper_queues_edit.php
webgui/guiconfig.inc
webgui/interfaces_assign.php
webgui/interfaces_lan.php
webgui/license.php
webgui/services_captiveportal_users.php
webgui/services_captiveportal_users_edit.php [new file with mode: 0644]
webgui/services_dhcp.php
webgui/services_dhcp_relay.php
webgui/services_dnsmasq.php
webgui/services_dnsmasq_domainoverride_edit.php [new file with mode: 0644]
webgui/services_dnsmasq_edit.php
webgui/services_dyndns.php
webgui/services_proxyarp_edit.php
webgui/services_wol.php
webgui/services_wol_edit.php
webgui/status.php
webgui/status_interfaces.php
webgui/status_ovpn.php [new file with mode: 0644]
webgui/system_advanced.php
webgui/vpn_ipsec_edit.php
webgui/vpn_openvpn.php [deleted file]
webgui/vpn_openvpn_cli.php
webgui/vpn_openvpn_cli_edit.php
webgui/vpn_openvpn_srv.php [new file with mode: 0644]
webgui/vpn_openvpn_srv_edit.php [new file with mode: 0644]

index 7b08eb83e31426b64e03ba0ae0327711ec1e9807..a6a35813d824247f4b93c24fb839d3cf561dbfe1 100644 (file)
@@ -94,14 +94,33 @@ if ($clientmac && portal_mac_fixed($clientmac)) {
 } else if ($_POST['accept'] && $config['captiveportal']['auth_method'] == "local") {
 
        //check against local usermanager
+       $userdb = &$config['captiveportal']['user'];
+
+       $loginok = false;
 
        //erase expired accounts
-       if(trim($config['users'][$_POST['auth_user']]['expirationdate'])!="" && strtotime("-1 day")>strtotime($config['users'][$_POST['auth_user']]['expirationdate'])){
-               unset($config['users'][$_POST['auth_user']]);
-               write_config();
+       if (is_array($userdb)) {
+               $moddb = false;
+               for ($i = 0; $i < count($userdb); $i++) {
+                       if ($userdb[$i]['expirationdate'] && (strtotime("-1 day") > strtotime($userdb[$i]['expirationdate']))) {
+                               unset($userdb[$i]);
+                               $moddb = true;
+                       }
+               }
+               if ($moddb)
+                       write_config();
+                       
+               $userdb = &$config['captiveportal']['user'];
+               
+               for ($i = 0; $i < count($userdb); $i++) {
+                       if (($userdb[$i]['name'] == $_POST['auth_user']) && ($userdb[$i]['password'] == md5($_POST['auth_pass']))) {
+                               $loginok = true;
+                               break;
+                       }
+               }
        }
 
-       if($config['users'][$_POST['auth_user']]['password']==md5($_POST['auth_pass'])){
+       if ($loginok){
                captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"LOGIN");
                portal_allow($clientip, $clientmac,$_POST['auth_user'],0,0);
        } else {
index 4726d6bcbe12a1de528ec772e6911e85b0e136b7..309e8a252fd766e72a8e3f1706f91d71b9a6e235 100644 (file)
@@ -1,7 +1,8 @@
 <?xml version="1.0"?>
 <!-- m0n0wall default system configuration -->
 <m0n0wall>
-       <version>1.4</version>
+       <version>1.5</version>
+       <lastchange></lastchange>
        <system>
                <hostname>m0n0wall</hostname>
                <domain>local</domain>
                        <certificate></certificate>
                        <private-key></private-key>
                        <noassigninterfaces/>
+                       <expanddiags/>
+                       <noantilockout></noantilockout>
                        -->
                </webgui>
                <!-- <disableconsolemenu/> -->
                <!-- <disablefirmwarecheck/> -->
                <!-- <shellcmd></shellcmd> -->
+               <!-- <earlyshellcmd></earlyshellcmd> -->
+               <!-- <harddiskstandby></harddiskstandby> -->
+               <!-- <polling/> -->
        </system>
        <interfaces>
                <lan>
                        <if>sis0</if>
                        <ipaddr>192.168.1.1</ipaddr>
                        <subnet>24</subnet>
+                       <media></media>
+                       <mediaopt></mediaopt>
                        <!--
                        <wireless>
                                *see below (opt[n])*
                        <gateway></gateway>
                        <blockpriv/>
                        <dhcphostname></dhcphostname>
+                       <media></media>
+                       <mediaopt></mediaopt>
                        <!--
+                       <ispointtopoint/>
                        <wireless>
                                *see below (opt[n])*
                        </wireless>
                        <if></if>
                        <ipaddr></ipaddr>
                        <subnet></subnet>
+                       <media></media>
+                       <mediaopt></mediaopt>
                        <bridge>lan|wan|opt[n]</bridge>
                        <wireless>
+                               <standard>11a|11b|11g</standard>
                                <mode>hostap *or* bss *or* ibss</mode>
                                <ssid></ssid>
                                <channel></channel>
                <username></username>
                <password></password>
                <provider></provider>
+               <!--
+               <ondemand/>
+               <timeout></timeout>
+               -->
        </pppoe>
        <pptp>
                <username></username>
                <local></local>
                <subnet></subnet>
                <remote></remote>
+               <!--
+               <ondemand/>
+               <timeout></timeout>
+               -->
        </pptp>
        <bigpond>
                <username></username>
                <host></host>
                <mx></mx>
                <!-- <wildcard/> -->
+               <server></server>
+               <port></port>
        </dyndns>
+       <dnsupdate>
+               <!--
+               <enable/>
+               <host></host>
+               <ttl></ttl>
+               <keyname></keyname>
+               <keydata></keydata>
+               </usetcp>
+               -->
+       </dnsupdate>
        <dhcpd>
                <lan>
                        <enable/>
                        <winsserver>xxx.xxx.xxx.xxx</winsserver>
                        <defaultleasetime></defaultleasetime>
                        <maxleasetime></maxleasetime>
+                       <gateway>xxx.xxx.xxx.xxx</gateway>
+                       <domain></domain>
+                       <dnsserver></dnsserver>
+                       <next-server></next-server>
+                       <filename></filename>
+                       <staticmap>
+                               <mac>xx:xx:xx:xx:xx:xx</mac>
+                               <ipaddr>xxx.xxx.xxx.xxx</ipaddr>
+                               <descr></descr>
+                       </staticmap>
                        -->
                </lan>
                <!--
                        ...
                </opt[n]>
                -->
-               <!--
-               <staticmap>
-                       <mac>xx:xx:xx:xx:xx:xx</mac>
-                       <ipaddr>xxx.xxx.xxx.xxx</ipaddr>
-                       <descr></descr>
-               </staticmap>
-               -->
        </dhcpd>
        <pptpd>
                <mode><!-- off *or* server *or* redir --></mode>
                <redir></redir>
                <localip></localip>
                <remoteip></remoteip>
+               <!-- <dnsserver></dnsserver> -->
+               <!-- <accounting/> -->
                <!--
                <user>
                        <name></name>
                </user>
                -->
        </pptpd>
+       <ovpn>
+               <!--
+               <server>
+                       <enable/>
+                       <ca_cert></ca_cert>
+                       <srv_cert></srv_cert>
+                       <srv_key></srv_key>
+                       <dh_param></dh_param>
+                       <verb></verb>
+                       <tun_iface></tun_iface>
+                       <port></port>
+                       <bind_iface></bind_iface>
+                       <cli2cli/>
+                       <maxcli></maxcli>
+                       <prefix></prefix>
+                       <ipblock></ipblock>
+                       <crypto></crypto>
+                       <dupcn/>
+                       <psh_options>
+                               <redir></redir>
+                               <redir_loc></redir_loc>
+                               <rte_delay></rte_delay>
+                               <ping></ping>
+                               <pingrst></pingrst>
+                               <pingexit></pingexit>
+                               <inact></inact>
+                       </psh_options>
+               </server>
+               <client>
+                       <tunnel></tunnel>
+                       <ca_cert></ca_cert>
+                       <cli_cert></cli_cert>
+                       <cli_key></cli_key>
+                       <type></type>
+                       <tunnel>
+                               <if></if>
+                               <proto></proto>
+                               <cport></cport>
+                               <saddr></saddr>
+                               <sport></sport>
+                               <crypto></crypto>
+                       </tunnel>
+               </client>
+               -->
+       </ovpn>
        <dnsmasq>
                <enable/>
                <!--
                        <ip></ip>
                        <descr></descr>
                </hosts>
+               <domainoverrides>
+                       <domain></domain>
+                       <ip></ip>
+                       <descr></descr>
+               </domainoverrides>
                -->
        </dnsmasq>
        <snmpd>
                        <!-- <enable/> -->
                        <ipaddr></ipaddr>
                </ipv6nat>
+               <!-- <ipfstatentries></ipfstatentries> -->
        </diag>
        <bridge>
                <!-- <filteringbridge/> -->
                <filter/>
                <dhcp/>
                <system/>
+               <portalauth/>
+               <vpn/>
                <nologdefaultblock/>
+               <resolve/>
                -->
        </syslog>
        <!--
                        <htmltext></htmltext>
                        <errtext></errtext>
                </page>
+               <httpslogin/>
+               <httpsname></httpsname>
+               <certificate></certificate>
+               <private-key></private-key>
+               <redirurl></redirurl>
+               <auth_method>none|radius|local</auth_method>
                <radiusip></radiusip>
                <radiusport></radiusport>
                <radiuskey></radiuskey>
+               <nomacfilter/>
+               <reauthenticate/>
+               <reauthenticateacct>stopstart|interimupdate</reauthenticateacct>
+               
+               <user>
+                       <name></name>
+                       <fullname></fullname>
+                       <password></password>
+                       <expirationdate></expirationdate>
+               </user>
        </captiveportal>
        -->
        <nat>
                -->
        </nat>
        <filter>
+               <!-- <tcpidletimeout></tcpidletimeout> -->
+               <!-- <bypassstaticroutes/> -->
                <rule>
                        <type>pass</type>
                        <descr>Default LAN -&gt; any</descr>
                        <descr>...</descr>
                        <interface>lan|opt[n]|wan|pptp</interface>
                        <protocol>tcp|udp|tcp/udp|...</protocol>
+                       <icmptype></icmptype>
                        <source>
                                <not/>
                                
        </shaper>
        <ipsec>
                <!-- <enable/> -->
+               <!-- <preferoldsa/> -->
                <!-- syntax:
                <tunnel>
                        <disabled/>
+                       <auto/>
                        <descr></descr>
                        <interface>lan|wan|opt[n]</interface>
                        <local-subnet>
index 5925ac787ffeeac5a00ade9d33b69fc2c0c2a8be..d49948cdcb01ff84afda80ee9ec101cd64d5350e 100644 (file)
@@ -422,6 +422,103 @@ function convert_config() {
                $config['version'] = "1.4";
        }
        
+       /* convert 1.4 -> 1.5 */
+       if ($config['version'] == "1.4") {
+               /* Remove old certs & keys */
+               unlink_if_exists("{$g['vardb_path']}/ovpn_ca_cert.pem");
+               unlink_if_exists("{$g['vardb_path']}/ovpn_srv_cert.pem");
+               unlink_if_exists("{$g['vardb_path']}/ovpn_srv_key.pem");
+               unlink_if_exists("{$g['vardb_path']}/ovpn_dh.pem");
+
+               /* convert openvpn tunnels */
+               if (isset($config['ovpn']['server'])) {
+                       $current = &$config['ovpn']['server'];
+
+                       /* construct new tunnel array */
+                       $config['ovpn']['server']['tunnel'] = array();
+
+                       /* make new pipe and associate with this rule */
+                       $newpipe = array();
+                       if (isset($current['enable']))
+                               $newpipe['enable'] = $current['enable'];
+                       $newpipe['descr'] = "";
+                       $newpipe['tun_iface'] = $current['tun_iface'];
+                       if (preg_match("/tun/", $current['tun_iface']))
+                               $newpipe['type'] = "tun";
+                       else
+                               $newpipe['type'] = "tap";
+                       $newpipe['psh_options'] = array();
+                       if (isset($current['psh_options']['redir']))
+                               $newpipe['psh_options']['redir'] = $current['psh_options']['redir'];
+                       if (isset($current['psh_options']['redir_loc']))
+                               $newpipe['psh_options']['redir_loc'] = $current['psh_options']['redir_loc'];
+
+                       if (isset($current['psh_options']['rtedelay'])) {
+                               $newpipe['psh_options']['rtedelay_int'] = $current['psh_options']['rtedelay'];
+                               $newpipe['psh_options']['rtedelay'] = true;
+                       }
+                       if (isset($current['psh_options']['inact'])) {
+                               $newpipe['psh_options']['inact_int'] = $current['psh_options']['inact'];
+                               $newpipe['psh_options']['inact'] = true;
+                       }
+                       if (isset($current['psh_options']['ping'])) {
+                               $newpipe['psh_options']['ping_int'] = $current['psh_options']['ping'];
+                               $newpipe['psh_options']['ping'] = true;
+                       }
+                       if (isset($current['psh_options']['pingexit'])) {
+                               $newpipe['psh_options']['pingexit_int'] = $current['psh_options']['pingexit'];
+                               $newpipe['psh_options']['pingexit'] = true;
+                       }
+                       if (isset($current['psh_options']['pingrst'])) {
+                               $newpipe['psh_options']['pingrst_int'] = $current['psh_options']['pingrst'];
+                               $newpipe['psh_options']['pingrst'] = true;
+                       }
+                       $newpipe['port'] = $current['port'];
+                       $newpipe['proto'] = strtolower($current['proto']);
+                       if (isset($current['maxcli']))
+                               $newpipe['maxcli'] = $current['maxcli'];
+                       $newpipe['crypto'] = $current['crypto'];
+                       if (isset($current['dupcn']))
+                               $newpipe['dupcn'] = $current['dupcn'];
+                       $newpipe['verb'] = $current['verb'];
+                       $newpipe['bind_iface'] = $current['bind_iface'];
+                       $newpipe['ipblock'] = $current['ipblock'];
+                       $newpipe['prefix'] = $current['prefix'];
+                       if (isset($current['cli2cli']))
+                               $newpipe['cli2cli'] = $current['cli2cli'];
+                       if (isset($current['dynip']))
+                               $newpipe['dynip'] = $current['dynip'];
+                       $newpipe['ca_cert'] = $current['ca_cert'];
+                       $newpipe['srv_key'] = $current['srv_key'];
+                       $newpipe['srv_cert'] = $current['srv_cert'];
+                       $newpipe['dh_param'] = $current['dh_param'];
+
+                       $config['ovpn']['server']['tunnel'][$i] = $newpipe;
+
+                       /* destroy old array */
+                       unset($current['enable']);
+                       unset($current['tun_iface']);
+                       unset($current['psh_options']);
+                       unset($current['port']);
+                       unset($current['proto']);
+                       unset($current['maxcli']);
+                       unset($current['crypto']);
+                       unset($current['dupcn']);
+                       unset($current['verb']);
+                       unset($current['bind_iface']);
+                       unset($current['ipblock']);
+                       unset($current['prefix']);
+                       unset($current['cli2cli']);
+                       unset($current['dynip']);
+                       unset($current['ca_cert']);
+                       unset($current['srv_key']);
+                       unset($current['srv_cert']);
+                       unset($current['dh_param']);
+               }
+
+               $config['version'] = "1.5";
+       }
+       
        write_config();
        
        if ($g['booting'])
index 8c26e547576b2965819f5414cac201a6f28b7bbf..b6fe7382b1104dca16822bcef8c0228ee110c37f 100644 (file)
@@ -195,7 +195,7 @@ function filter_nat_rules_generate() {
                for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
                        $optcfg = $config['interfaces']['opt' . $i];
                        
-                       if (isset($optcfg['enable']) && !$optcfg['bridge']) {
+                       if (isset($optcfg['enable']) && !$optcfg['bridge'] && !isset($optcfg['ovpn'])) {
                                $optsa = gen_subnet($optcfg['ipaddr'], $optcfg['subnet']);
                                $natrules .= filter_nat_rules_generate_if($wanif, 
                                        $optsa . "/" . $optcfg['subnet'], "", null);
@@ -300,6 +300,7 @@ function filter_rules_generate() {
                if (isset($oc['enable']) && $oc['if']) {
                        $oic = array();
                        $oic['if'] = $oc['if'];
+                       $oic['ovpn'] = $oc['ovpn'];
                        
                        if ($oc['bridge']) {
                                if (!strstr($oc['bridge'], "opt") || 
@@ -355,7 +356,9 @@ EOD;
 
        /* allow access to DHCP server on optional interfaces */
        foreach ($optcfg as $on => $oc) {
-               if (isset($config['dhcpd'][$on]['enable']) && (!$oc['bridge'])) {
+               if ((isset($config['dhcpd'][$on]['enable']) && !$oc['bridge']) ||
+                               ($oc['bridge'] && isset($config['dhcpd'][$oc['bridge_if']]['enable']))) {
+                                       
                        $ipfrules .= <<<EOD
 
 # allow access to DHCP server on {$on}
@@ -410,6 +413,11 @@ block in $log quick on $wanif from $lansa/$lansn to any
 EOD;
 
        foreach ($optcfg as $oc) {
+               if (isset($oc['ovpn'])) {
+                       /* exclude OpenVPN tunneling interfaces */
+                       /* $ovpnclient = true; */
+                       continue;
+               }
                if (!$oc['bridge'])
                        $ipfrules .= "block in $log quick on $wanif from {$oc['sa']}/{$oc['sn']} to any\n";
        }
@@ -455,7 +463,7 @@ EOD;
        /* OPT spoof check */
        foreach ($optcfg as $on => $oc) {
                /* omit for bridged interfaces when the filtering bridge is on */
-               if ($oc['ip'] && (!$oc['bridge'] || !isset($config['bridge']['filteringbridge'])))
+               if ($oc['ip'] && (!$oc['bridge'] || !isset($config['bridge']['filteringbridge'])) && $oc['sa'] != "0.0.0.0")
                        $ipfrules .= filter_rules_spoofcheck_generate($on, $oc['if'], $oc['sa'], $oc['sn'], $log);
        }
        
index bee57697951d5e090d39796166049adedc421cd2..f6db4170474a59b98135417c4f29a4a878f5e674 100644 (file)
@@ -47,7 +47,7 @@ $g = array(
     "n_pptp_units" => 16,
     "pptp_subnet" => 28,
     "debug" => false,
-    "latest_config" => "1.4",
+    "latest_config" => "1.5",
     "nopccard_platforms" => array("wrap", "net48xx"),
     "wireless_regex" => "/^(wi|ath|an)/"
 );
index 2414ae0d7839b31f8d17579429769a8e55b1f097..b39bd0321cea2e3b1190718ab41fd3fb0d0b878e 100644 (file)
@@ -32,10 +32,10 @@ require_once("globals.inc");
 require_once("config.inc");
 require_once("functions.inc");
 
-function ovpn_configure() {
+function ovpn_configure($reconfigure) {
        global $config;
        if (is_array($config['ovpn']['server']))
-               ovpn_config_server();
+               ovpn_config_server($reconfigure);
        if (is_array($config['ovpn']['client']))
                ovpn_config_client();
        return;
@@ -79,91 +79,180 @@ function ovpn_unlink_tap() {
 }
 
 /*****************************/        
-/*  Server-related functions */
+/*  Server related functions */
+/*****************************/
 
-/* Configure the server */
-function ovpn_config_server() {
-       global $config, $g;
-       
-       if (isset($config['ovpn']['server']['enable'])) {
-       
-               if ($g['booting'])
-                       echo "Starting OpenVPN server... ";
-               
-               /* kill any running openvpn daemon */
-               killbypid($g['varrun_path']."/ovpn_srv.pid");
-               
-               /* Remove old certs & keys */
-               unlink_if_exists("{$g['vardb_path']}/ovpn_ca_cert.pem");
-               unlink_if_exists("{$g['vardb_path']}/ovpn_srv_cert.pem");
-               unlink_if_exists("{$g['vardb_path']}/ovpn_srv_key.pem");
-               unlink_if_exists("{$g['vardb_path']}/ovpn_dh.pem");
-               
-               /* Copy the TLS-Server certs & keys to disk */
-               $fd = @fopen("{$g['vardb_path']}/ovpn_ca_cert.pem", "w");
-               if ($fd) {
-                       fwrite($fd, base64_decode($config['ovpn']['server']['ca_cert'])."\n");
-                       fclose($fd);    
-               }
-               $fd = @fopen("{$g['vardb_path']}/ovpn_srv_cert.pem", "w");
-               if ($fd) {
-                       fwrite($fd, base64_decode($config['ovpn']['server']['srv_cert'])."\n");
-                       fclose($fd);    
-               }
-               $fd = @fopen("{$g['vardb_path']}/ovpn_srv_key.pem", "w");
-               if ($fd) {
-                       fwrite($fd, base64_decode($config['ovpn']['server']['srv_key'])."\n");
-                       fclose($fd);    
+function getnxt_server_if($type) {
+       /* find the first available device of type $type */
+       global $config;
+       $a_server = $config['ovpn']['server']['tunnel'];
+       $max = ($type == 'tun') ? 17 : 4;
+       for ($i = 0; $i < $max ; $i++) {
+               $hit = false;
+               foreach ($a_server as $server) {
+                       if ($server['tun_iface'] == $type . $i) {
+                               $hit = true;
+                               break;
+                       }
                }
-               $fd = @fopen("{$g['vardb_path']}/ovpn_dh.pem", "w");
-               if ($fd) {
-                       fwrite($fd, base64_decode($config['ovpn']['server']['dh_param'])."\n");
-                       fclose($fd);    
+               if (!$hit)
+                       return $type . $i;
+       }
+       return false;
+}
+
+function getnxt_server_port() {
+       /* Get first unused port */
+       global $config;
+       $a_server = $config['ovpn']['server']['tunnel'];
+       $port = 1194;
+       while (true) {
+               $hit = false;
+               foreach ($a_server as $server) {
+                       if ($server['port'] == $port) {
+                               $hit = true;
+                               break;
+                       }
                }
-               
-               /* Start the openvpn daemon */
-               mwexec("/usr/local/sbin/openvpn " . ovpn_srv_config_generate());
-               
-               if ($g['booting'])
-                       /* Send the boot message */
-                       echo "done\n";
+               if (!$hit)
+                       if (!ovpn_port_inuse_client($port))
+                               return $port;
+               $port++;
        }
-       else {
-               if (!$g['booting']){
-                       /* stop any processes, unload the tap module */
+       return false; /* should never get here */
+}
+
+/* Configure the server */
+function ovpn_config_server($reconfigure) {
+       global $config, $g;
+
+       foreach ($config['ovpn']['server']['tunnel'] as $id => $server) {
+               /* get tunnel interface */
+               $tun = $server['tun_iface'];
+                       
+               /* kill any running openvpn daemon */
+               killbypid($g['varrun_path']."/ovpn_srv_{$tun}.pid");
+
+               if (isset($server['enable'])) {
+
+                       if ($g['booting'])
+                               echo "Starting OpenVPN server $id... ";
+
+                       /* send SIGUSR1 to running openvpn daemon */
+                       if ( $reconfigure == "true" && isset($server['dynip'])) {
+                               sigkillbypid($g['varrun_path']."/ovpn_srv_{$tun}.pid", "SIGUSR1");
+                               continue;
+                       }
+
                        /* Remove old certs & keys */
-                       unlink_if_exists("{$g['vardb_path']}/ovpn_ca_cert.pem");
-                       unlink_if_exists("{$g['vardb_path']}/ovpn_srv_cert.pem");
-                       unlink_if_exists("{$g['vardb_path']}/ovpn_srv_key.pem");
-                       unlink_if_exists("{$g['vardb_path']}/ovpn_dh.pem");
-                       killbypid("{$g['varrun_path']}/ovpn_srv.pid");
-                       if ($config['ovpn']['server']['tun_iface'] == 'tap0')
-                               ovpn_unlink_tap();
+                       unlink_if_exists("{$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem");
+                       unlink_if_exists("{$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem");
+                       unlink_if_exists("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem");
+                       unlink_if_exists("{$g['vardb_path']}/ovpn_dh_{$tun}.pem");
+                       unlink_if_exists("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem");
+                       unlink_if_exists("{$g['varetc_path']}/ovpn_srv_up_{$tun}.pem");
+                       unlink_if_exists("{$g['varetc_path']}/ovpn_cli_up_{$tun}.pem");
+
+                       /* Copy the TLS-Server certs & keys to disk */
+                       $fd = fopen("{$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem", "w");
+                       if ($fd) {
+                               fwrite($fd, base64_decode($server['ca_cert'])."\n");
+                               fclose($fd);    
+                       }
+                       $fd = fopen("{$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem", "w");
+                       if ($fd) {
+                               fwrite($fd, base64_decode($server['srv_cert'])."\n");
+                               fclose($fd);    
+                       }
+                       touch ("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem");
+                       chmod ("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem", 0600);
+                       $fd = fopen("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem", "w");
+                       if ($fd) {
+                               fwrite($fd, base64_decode($server['srv_key'])."\n");
+                               fclose($fd);    
+                       }
+                       $fd = fopen("{$g['vardb_path']}/ovpn_dh_{$tun}.pem", "w");
+                       if ($fd) {
+                               fwrite($fd, base64_decode($server['dh_param'])."\n");
+                               fclose($fd);    
+                       }
+
+                       touch ("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem");
+                       chmod ("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem", 0600);
+                       $fd = fopen("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem", "w");
+                       if ($fd) {
+                               fwrite($fd, base64_decode($server['pre-shared-key'])."\n");
+                               fclose($fd);    
+                       }
+
+                       /* Start the openvpn daemon */
+                       mwexec("/usr/local/sbin/openvpn " . ovpn_srv_config_generate($id));
+
+                       if ($g['booting'])
+                               /* Send the boot message */
+                               echo "done\n";
+               }
+               else {
+                       if (!$g['booting']){
+                               /* stop any processes, unload the tap module */
+                               /* Remove old certs & keys */
+                               ovpn_server_kill($tun);
+
+                               if ($server['type'] == "tap")
+                                       ovpn_unlink_tap();
+                       }
                }
        }
        return 0;
 }
 
+/* Kill off a running server process */
+function ovpn_server_kill($tun) {
+       global $g;
+       
+       killbypid("{$g['varrun_path']}/ovpn_srv_{$tun}.pid");
+
+       /* Remove old certs & keys */
+       unlink_if_exists("{$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem");
+       unlink_if_exists("{$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem");
+       unlink_if_exists("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem");
+       unlink_if_exists("{$g['vardb_path']}/ovpn_dh_{$tun}.pem");
+       unlink_if_exists("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem");
+
+       return 0;
+}
+
 /* Generate the config for a OpenVPN server */
-function ovpn_srv_config_generate() {
+function ovpn_srv_config_generate($id) {
        global $config, $g;
-       $server = $config['ovpn']['server'];
-       
+       $server = $config['ovpn']['server']['tunnel'][$id];
+
+       /* get tunnel interface */
+       $tun = $server['tun_iface'];
+
+       /* get optional interface name */
+       $iface = ovpn_get_opt_interface($tun);
+
        /* First the generic stuff:
                - We are a server
                - We are a TLS Server (for authentication)
                - We will run without privilege
        */
-       $ovpn_config = "--daemon --user nobody --group nobody --verb {$server['verb']} ";
-       
+       $ovpn_config = "--daemon --user nobody --group nobody --verb {$server['verb']} --persist-tun --persist-key --status /var/log/openvpn_{$tun}.log 60 ";
+
        /* pid file */
-       $ovpn_config .= "--writepid {$g['varrun_path']}/ovpn_srv.pid ";
+       $ovpn_config .= "--writepid {$g['varrun_path']}/ovpn_srv_{$tun}.pid ";
        
        /* interface */
        $ovpn_config .= "--dev {$server['tun_iface']} ";
        
        /* port */
        $ovpn_config .= "--port {$server['port']} ";
+
+       /* Set protocol being used (p = udp (default), tcp-server)
+       if ($server['proto'] == 'tcp') {
+               $ovpn_config .= "--proto tcp-server ";
+       }
        
        /* Interface binding - 1 or all */
        if ($server['bind_iface'] != 'all') {
@@ -171,9 +260,12 @@ function ovpn_srv_config_generate() {
                        $ovpn_config .= "--local $ipaddr ";
                else
                        return "Interface bridged";
-               
        }
-               
+
+       /* are we using dynamic ip addresses? */
+       if (isset($server['dynip']))
+               $ovpn_config .= "--persist-remote-ip ";
+       
        /* Client to client routing (off by default) */
        if (isset($server['cli2cli']))
                $ovpn_config .= "--client-to-client ";
@@ -181,15 +273,41 @@ function ovpn_srv_config_generate() {
        /* Set maximum simultaneous clients */
        $ovpn_config .= "--max-clients {$server['maxcli']} ";
         
-       /* New --server macro simplifies config */
-       $mask = ovpn_calc_mask($server['prefix']);
-       $ovpn_config .= "--server {$server['ipblock']} {$mask} ";
+       /* bridging enabled? */
+       if (($ifname = $config['interfaces'][$iface]['bridge']) && $server['type'] == "tap") {
+               $gateway = $config['interfaces'][$ifname]['ipaddr'];
+               $netmask = gen_subnet_mask($config['interfaces'][$ifname]['subnet']);
+               $poolstart = $server['ipblock'];
+               $poolend = gen_subnet_max($server['ipblock'], $server['prefix']);
+
+               $ovpn_config .= "--server-bridge $gateway $netmask $poolstart $poolend ";
+
+               $lastdigits = substr($tun, 3) + 2;
+               $ovpn_srv_up = "/sbin/ifconfig " . $tun . " 127.0.0." . $lastdigits . "/32\n";
+
+               $fd = fopen("{$g['varetc_path']}/ovpn_srv_up_{$tun}.sh", "w");
+               if ($fd) {
+                       fwrite($fd, $ovpn_srv_up);
+                       fclose($fd);    
+                       chmod ("{$g['varetc_path']}/ovpn_srv_up_{$tun}.sh", 0755);
+                       $ovpn_config .= "--up /var/etc/ovpn_srv_up_{$tun}.sh ";
+               }
+       } else {
+               /* New --server macro simplifies config */
+               $netmask = gen_subnet_mask($server['prefix']);
+
+               $ovpn_config .= "--server {$server['ipblock']} {$netmask} ";
+       }
        
        /* TLS-Server params */
-       $ovpn_config .= "--ca {$g['vardb_path']}/ovpn_ca_cert.pem ";
-       $ovpn_config .= "--cert {$g['vardb_path']}/ovpn_srv_cert.pem ";
-       $ovpn_config .= "--key {$g['vardb_path']}/ovpn_srv_key.pem ";
-       $ovpn_config .= "--dh {$g['vardb_path']}/ovpn_dh.pem ";
+       $ovpn_config .= "--ca {$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem ";
+       $ovpn_config .= "--cert {$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem ";
+       $ovpn_config .= "--key {$g['vardb_path']}/ovpn_srv_key_{$tun}.pem ";
+       $ovpn_config .= "--dh {$g['vardb_path']}/ovpn_dh_{$tun}.pem ";
+       
+       /* TLS auth */
+       if (isset($server['tlsauth']))
+               $ovpn_config .= "--tls-auth {$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem 0 ";
        
        /* Data channel encryption cipher*/
        $ovpn_config .= "--cipher {$server['crypto']} ";
@@ -201,40 +319,47 @@ function ovpn_srv_config_generate() {
        /* Client push - redirect gateway */
        if (isset($server['psh_options']['redir'])){
                if (isset($server['psh_options']['redir_loc']))
-                       $ovpn_config .= "--push \"redirect-gateway 'local'\" ";
+                       $ovpn_config .= "--push \"redirect-gateway local\" ";
                else
                        $ovpn_config .= "--push \"redirect-gateway\" ";
        }
                        
        /* Client push - route delay */
        if (isset($server['psh_options']['rte_delay']))
-               $ovpn_config .= "--push \"route-delay {$server['psh_options']['rte_delay']}\" ";
+               $ovpn_config .= "--push \"route-delay {$server['psh_options']['rte_delay_int']}\" ";
                
        /* Client push - ping (note we set both server and client) */
        if (isset ($server['psh_options']['ping'])){
-               $ovpn_config .= "--ping {$server['psh_options']['ping']} ";
-               $ovpn_config .= "--push \"ping {$server['psh_options']['ping']}\" ";
+               $conflict = true;
+               $interval = $server['psh_options']['ping_int'];
+               $ovpn_config .= "--ping {$server['psh_options']['ping_int']} ";
+               $ovpn_config .= "--push \"ping {$server['psh_options']['ping_int']}\" ";
        }
        
        /* Client push - ping-restart (note server uses 2 x client interval) */
        if (isset ($server['psh_options']['pingrst'])){
-               $interval = $server['psh_options']['pingrst'];
+               $conflict = true;
+               $interval = $server['psh_options']['pingrst_int'];
                $ovpn_config .= "--ping-restart " . ($interval * 2) . " ";
                $ovpn_config .= "--push \"ping-restart $interval\" ";
        }
        
        /* Client push - ping-exit (set on client) */
        if (isset ($server['psh_options']['pingexit'])){
-               $ovpn_config .= "--ping-exit {$server['psh_options']['pingexit']} ";
-               $ovpn_config .= "--push \"ping-exit {$server['psh_options']['pingexit']}\" ";
+               $conflict = true;
+               $ovpn_config .= "--ping-exit {$server['psh_options']['pingexit_int']} ";
+               $ovpn_config .= "--push \"ping-exit {$server['psh_options']['pingexit_int']}\" ";
        }
        
        /* Client push - inactive (set on client) */
        if (isset ($server['psh_options']['inact'])){
-               $ovpn_config .= "--inactive {$server['psh_options']['pingexit']} ";
-               $ovpn_config .= "--push \"inactive {$server['psh_options']['inact']}\" ";
+               $ovpn_config .= "--inactive {$server['psh_options']['inact_int']} ";
+               $ovpn_config .= "--push \"inactive {$server['psh_options']['inact_int']}\" ";
        }
        
+       if (!isset($conflict))
+               $ovpn_config .= "--keepalive 10 60 ";
+
        //trigger_error("OVPN: $ovpn_config", E_USER_NOTICE);
        return $ovpn_config;
 }
@@ -243,73 +368,175 @@ function ovpn_srv_config_generate() {
 function ovpn_server_iface(){
        global $config, $g;
        
-       $i = 1;
-       while (true) {
-               $ifname = 'opt' . $i;
-               if (is_array($config['interfaces'][$ifname])) {
-                       if ((isset($config['interfaces'][$ifname]['ovpn']))
-                            && ($config['interfaces'][$ifname]['ovpn'] == 'server'))
-                               /* Already an interface defined - overwrite */
-                               break;
+       foreach ($config['ovpn']['server']['tunnel'] as $id => $server) {
+               if (isset($server['enable'])) {
+
+                       /* get tunnel interface */
+                       $tun = $server['tun_iface'];
+                       
+                       $i = 1;
+                       while (true) {
+                               $ifname = 'opt' . $i;
+                               if (is_array($config['interfaces'][$ifname])) {
+                                       if ((isset($config['interfaces'][$ifname]['ovpn']))
+                                            && ($config['interfaces'][$ifname]['ovpn'] == "server_{$tun}"))
+                                               /* Already an interface defined - overwrite */
+                                               break;
+                               }
+                               else {
+                                       /* No existing entry, this is first unused */
+                                       $config['interfaces'][$ifname] = array();
+                                       break;
+                               }
+                               $i++;
+                       }
+                       $config['interfaces'][$ifname]['descr'] = strtoupper($ifname);
+                       $config['interfaces'][$ifname]['if'] = $server['tun_iface'];
+                       $config['interfaces'][$ifname]['ipaddr'] = long2ip( ip2long($server['ipblock']) + 1);
+                       $config['interfaces'][$ifname]['subnet'] = $server['prefix'];
+                       $config['interfaces'][$ifname]['enable'] = isset($server['enable']) ? true : false;
+                       $config['interfaces'][$ifname]['ovpn'] = "server_{$tun}";
+
+                       write_config();
                }
-               else {
-                       /* No existing entry, this is first unused */
-                       $config['interfaces'][$ifname] = array();
+       }
+       return "OpenVPN server interface defined";
+}
+
+/* Delete a server interface definition */
+function ovpn_server_iface_del($tun) {
+       global $config;
+
+       for ($i = 1; is_array($config['interfaces']['opt' . $i]); $i++) {
+               $ifname = 'opt' . $i;
+               if ((isset($config['interfaces'][$ifname]['ovpn']))
+                    && ($config['interfaces'][$ifname]['if'] == "$tun")) {
+                       unset($config['interfaces'][$ifname]);
                        break;
                }
+       }
+
+
+       /* shift down other OPTn interfaces to get rid of holes */
+       $i++;
+
+       /* look at the following OPTn ports */
+       while (is_array($config['interfaces']['opt' . $i])) {
+               $config['interfaces']['opt' . ($i - 1)] =
+                       $config['interfaces']['opt' . $i];
+
+               unset($config['interfaces']['opt' . $i]);
                $i++;
        }
-       $config['interfaces'][$ifname]['descr'] = "OVPN server";
-       $config['interfaces'][$ifname]['if'] = $config['ovpn']['server']['tun_iface'];
-       $config['interfaces'][$ifname]['ipaddr'] = long2ip( ip2long($config['ovpn']['server']['ipblock']) + 1);
-       $config['interfaces'][$ifname]['subnet'] = $config['ovpn']['server']['prefix'];
-       $config['interfaces'][$ifname]['enable'] = isset($config['ovpn']['server']['enable']) ? true : false;
-       $config['interfaces'][$ifname]['ovpn'] = 'server';
-                       
-       write_config();
-       
-       return "OpenVPN server interface defined";
 }
 
-/********************************************************/
+
+/****************************/
 /* Client related functions */
+/****************************/
+
+function getnxt_client_if($type) {
+       /* find the first available device of type $type */
+       global $config;
+       $max = ($type == 'tun') ? 17 : 4;
+       for ($i = 0; $i < $max; $i++) {
+               $hit = false;
+               foreach ($a_client as $client) {
+                       if ($client['if'] == $type . $i) {
+                               $hit = true;
+                               break;
+                       }
+               }
+               if (!$hit)
+                       return $type . $i;
+       }
+        return false;
+}
+
+function getnxt_client_port() {
+        /* Get first unused port */
+       global $config;
+       $a_client = $config['ovpn']['client']['tunnel'];
+       $port = 1194;
+       while (true) {
+               $hit = false;
+               foreach ($a_client as $client) {
+                       if ($client['port'] == $port) {
+                               $hit = true;
+                               break;
+                       }
+               }
+               if (!$hit)
+                       if (!ovpn_port_inuse_server($port))
+                               return $port;
+               $port++;
+       }
+       return false; /* should never get here */
+}
+
+/* Port in use */
+function ovpn_port_inuse_client($port){
+       global $config;
+       $a_client = $config['ovpn']['client']['tunnel'];
+       foreach ($a_client as $client) {
+               if ($client['port'] == $port) {
+                       return true;
+               }
+       }
+       return false;
+}
+
 function ovpn_config_client() {
        /* Boot time configuration */
        global $config, $g;
        
        foreach ($config['ovpn']['client']['tunnel'] as $id => $client) {
+
+               /* get tunnel interface */
+               $tun = $client['if'];
+
+               /* kill any running openvpn daemon */
+               killbypid($g['varrun_path']."/ovpn_cli_{$tun}.pid");
+
                if (isset($client['enable'])) {
        
                        if ($g['booting'])
                                echo "Starting OpenVPN client $id... ";
                
-                       /* kill any running openvpn daemon */
-                       killbypid("{$g['varrun_path']}/ovpn_client{$id}.pid");
-               
                        /* Remove old certs & keys */
-                       unlink_if_exists("{$g['vardb_path']}/ovpn_ca_cert_{$id}.pem");
-                       unlink_if_exists("{$g['vardb_path']}/ovpn_cli_cert_{$id}.pem");
-                       unlink_if_exists("{$g['vardb_path']}/ovpn_cli_key_{$id}.pem");
+                       unlink_if_exists("{$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem");
+                       unlink_if_exists("{$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem");
+                       unlink_if_exists("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem");
+                       unlink_if_exists("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem");
+                       unlink_if_exists("{$g['varetc_path']}/ovpn_cli_up_{$tun}.pem");
                
                        /* Copy the TLS-Client certs & keys to disk */
-                       /*$fd = @fopen("{$g['vardb_path']}/ovpn_ca_cert_{$id}.pem", "w");*/
-                       $fd = fopen("{$g['vardb_path']}/ovpn_ca_cert_{$id}.pem", "w");
+                       $fd = fopen("{$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem", "w");
                        if ($fd) {
                                fwrite($fd, base64_decode($client['ca_cert'])."\n");
                                fclose($fd);    
                        }
                        else
                                trigger_error("OVPN: No open for CA", E_USER_NOTICE);
-                       $fd = fopen($g['vardb_path']."/ovpn_cli_cert_".$id.".pem", "w");
+                       $fd = fopen("{$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem", "w");
                        if ($fd) {
                                fwrite($fd, base64_decode($client['cli_cert'])."\n");
                                fclose($fd);    
                        }
-                       $fd = fopen($g['vardb_path']."/ovpn_cli_key_".$id.".pem", "w");
+                       touch ("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem");
+                       chmod ("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem", 0600);
+                       $fd = fopen("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem", "w");
                        if ($fd) {
                                fwrite($fd, base64_decode($client['cli_key'])."\n");
                                fclose($fd);    
                        }
+                       touch ("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem");
+                       chmod ("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem", 0600);
+                       $fd = fopen("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem", "w");
+                       if ($fd) {
+                               fwrite($fd, base64_decode($client['pre-shared-key'])."\n");
+                               fclose($fd);    
+                       }
                                
                        /* Start openvpn for this client */
                        mwexec("/usr/local/sbin/openvpn " . ovpn_cli_config_generate($id));
@@ -322,10 +549,8 @@ function ovpn_config_client() {
                        if (!$g['booting']){
                                /* stop any processes, unload the tap module */
                                /* Remove old certs & keys */
-                               unlink_if_exists("{$g['vardb_path']}/ovpn_ca_cert_{$id}.pem");
-                               unlink_if_exists("{$g['vardb_path']}/ovpn_cli_cert_{$id}.pem");
-                               unlink_if_exists("{$g['vardb_path']}/ovpn_cli_key_{$id}.pem");
-                               killbypid("{$g['varrun_path']}/ovpn_client{$id}.pid");
+                               ovpn_client_kill($tun);
+
                                if ($client['type'] == "tap")
                                        ovpn_unlink_tap();
                        }
@@ -336,44 +561,78 @@ function ovpn_config_client() {
 }
 
 /* Kill off a running client process */
-function ovpn_client_kill($id) {
+function ovpn_client_kill($tun) {
        global $g;
        
-       killbypid("{$g['varrun_path']}/ovpn_client{$id}.pid");
+       killbypid("{$g['varrun_path']}/ovpn_cli_{$tun}.pid");
+       
+       /* Remove old certs & keys */
+       unlink_if_exists("{$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem");
+       unlink_if_exists("{$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem");
+       unlink_if_exists("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem");
+       unlink_if_exists("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem");
+
        return 0;
 }
 
+/* Generate the config for a OpenVPN client */
 function ovpn_cli_config_generate($id) {
        /* configure the named client */
        global $config, $g;
-       $client = $config['ovpn']['client']['tunnel'];
+       $client = $config['ovpn']['client']['tunnel'][$id];
+
+       /* get tunnel interface */
+       $tun = $client['if'];
        
+       /* get optional interface name */
+       $iface = ovpn_get_opt_interface($tun);
+
        /* Client support in 2.0 is very simple */
-       
-       $ovpn_config = "--client --daemon --verb 1 ";
+       $ovpn_config = "--client --daemon --verb 1 --status /var/log/openvpn_{$tun}.log 60 ";
        
        /* pid file */
-       $ovpn_config .= "--writepid {$g['varrun_path']}/ovpn_client{$id}.pid ";
+       $ovpn_config .= "--writepid {$g['varrun_path']}/ovpn_cli_{$tun}.pid ";
        
        /* interface */
-       $ovpn_config .= "--dev {$client[$id]['if']} ";
+       $ovpn_config .= "--dev {$client['if']} ";
        
        /* protocol */
-       $ovpn_config .= "--proto {$client[$id]['proto']} ";
+       /* Set protocol being used (p = udp (default), tcp-client)
+       if ($client['proto'] == 'tcp') {
+               $ovpn_config .= "--proto tcp-client ";
+       }
        
        /* port */
-       $ovpn_config .= "--lport {$client[$id]['cport']} ";
+       $ovpn_config .= "--lport {$client['port']} ";
        
        /* server location */
-       $ovpn_config .= "--remote {$client[$id]['saddr']} {$client[$id]['sport']} ";
+       $ovpn_config .= "--remote {$client['saddr']} {$client['sport']} ";
        
-       /* TLS-Server params */
-       $ovpn_config .= "--ca {$g['vardb_path']}/ovpn_ca_cert_{$id}.pem ";
-       $ovpn_config .= "--cert {$g['vardb_path']}/ovpn_cli_cert_{$id}.pem ";
-       $ovpn_config .= "--key {$g['vardb_path']}/ovpn_cli_key_{$id}.pem ";
-               
+       /* bridging enabled? */
+       if (($ifname = $config['interfaces'][$iface]['bridge']) && $client['type'] == "tap") {
+               $lastdigits = substr($tun, 3) + 2;
+               $ovpn_srv_up = "/sbin/ifconfig " . $tun . " 127.0.0." . $lastdigits . "/32\n";
+
+               $fd = fopen("{$g['varetc_path']}/ovpn_cli_up_{$tun}.sh", "w");
+               if ($fd) {
+                       fwrite($fd, $ovpn_cli_up);
+                       fclose($fd);    
+                       chmod ("{$g['varetc_path']}/ovpn_cli_up_{$tun}.sh", 0755);
+                       $ovpn_config .= "--up /var/etc/ovpn_cli_up_{$tun}.sh ";
+               }
+       }
+
+       /* TLS-Client params */
+       $ovpn_config .= "--ca {$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem ";
+       $ovpn_config .= "--cert {$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem ";
+       $ovpn_config .= "--key {$g['vardb_path']}/ovpn_cli_key_{$tun}.pem ";
+
+       /* TLS auth */
+       if (isset($client['tlsauth']))
+               $ovpn_config .= "--tls-auth {$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem 1 ";
+
        /* Data channel encryption cipher*/
-       $ovpn_config .= "--cipher {$client[$id]['crypto']} ";
+       $ovpn_config .= "--cipher {$client['crypto']} ";
        
        //trigger_error("OVPN: $ovpn_config", E_USER_NOTICE);
        return $ovpn_config;
@@ -385,12 +644,16 @@ function ovpn_client_iface(){
                
        foreach ($config['ovpn']['client']['tunnel'] as $id => $client) {
                if (isset($client['enable'])) {
+
+                       /* get tunnel interface */
+                       $tun = $client['if'];
+
                        $i = 1;
                        while (true) {
                                $ifname = 'opt' . $i;
                                if (is_array($config['interfaces'][$ifname])) {
                                        if ((isset($config['interfaces'][$ifname]['ovpn']))
-                                            && ($config['interfaces'][$ifname]['ovpn'] == "client{$id}"))
+                                            && ($config['interfaces'][$ifname]['ovpn'] == "client_{$tun}"))
                                                /* Already an interface defined - overwrite */
                                                break;
                                }
@@ -401,15 +664,12 @@ function ovpn_client_iface(){
                                }
                                $i++;
                        }
-                       if (isset($client['descr']))
-                               $config['interfaces'][$ifname]['descr'] = $client['descr'];
-                       else
-                               $config['interfaces'][$ifname]['descr'] = "OVPN client-{$id}";
+                       $config['interfaces'][$ifname]['descr'] = strtoupper($ifname);
                        $config['interfaces'][$ifname]['if'] = $client['if'];
                        $config['interfaces'][$ifname]['ipaddr'] = "0.0.0.0";
                        $config['interfaces'][$ifname]['subnet'] = "0";
                        $config['interfaces'][$ifname]['enable'] = isset($client['enable']) ? true : false;
-                       $config['interfaces'][$ifname]['ovpn'] = "client{$id}";
+                       $config['interfaces'][$ifname]['ovpn'] = "client_{$tun}";
                        write_config();
                }
        }
@@ -417,20 +677,33 @@ function ovpn_client_iface(){
 }
 
 /* Delete a client interface definition */
-function ovpn_client_iface_del($id) {
+function ovpn_client_iface_del($tun) {
        global $config;
-       
-       $i = 1;
-       while (true) {
+
+       for ($i = 1; is_array($config['interfaces']['opt' . $i]); $i++) {
                $ifname = 'opt' . $i;
-               if (is_array($config['interfaces'][$ifname])) {
-                       if ((isset($config['interfaces'][$ifname]['ovpn']))
-                            && ($config['interfaces'][$ifname]['ovpn'] == "client{$id}"))
-                            unset($config['interfaces'][$ifname]);
+               if ((isset($config['interfaces'][$ifname]['ovpn']))
+                    && ($config['interfaces'][$ifname]['if'] == "$tun")) {
+                       unset($config['interfaces'][$ifname]);
+                       break;
                }
        }
+
+
+       /* shift down other OPTn interfaces to get rid of holes */
+       $i++;
+
+       /* look at the following OPTn ports */
+       while (is_array($config['interfaces']['opt' . $i])) {
+               $config['interfaces']['opt' . ($i - 1)] =
+                       $config['interfaces']['opt' . $i];
+
+               unset($config['interfaces']['opt' . $i]);
+               $i++;
+       }
 }
 
+
 /******************/
 /* Misc functions */
 
@@ -448,6 +721,18 @@ function ovpn_calc_mask($prefix){
        return long2ip(ip2long("255.255.255.255") - (pow( 2, (32 - $prefix)) - 1));
 }
 
+/* Port in use */
+function ovpn_port_inuse_server($port){
+       global $config;
+       $a_server = $config['ovpn']['server']['tunnel'];
+       foreach ($a_server as $server) {
+               if ($server['port'] == $port) {
+                       return true;
+               }
+       }
+       return false;
+}
+
 /* Read in a file from the $_FILES array */
 function ovpn_get_file($file){
        global $g;
@@ -474,6 +759,7 @@ function ovpn_get_ip($iface){
        return $config['interfaces'][$iface]['ipaddr'];
 }
        
+       
 /* Get a list of the cipher options supported by OpenVPN */
 function ovpn_get_cipher_list(){
        
@@ -504,6 +790,23 @@ function ovpn_get_cipher_list(){
 }
                
        
+/* Get optional interface */
+/* needs tunneling interface (tun0, tun1, tap0, ...) */
+/* returns optional interface name (opt2, opt3, ...) */
+function ovpn_get_opt_interface($tun){
+       global $config;
+
+       for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+               $ifname = 'opt' . $i;
+
+               if (isset($config['interfaces']['opt' . $i]['ovpn']))
+                       if ($config['interfaces'][$ifname]['if'] == "$tun")
+                                return $ifname;
+       }
+       /* not found? */
+       return false;
+}
+
 /* Build a list of the current real interfaces */
 function ovpn_real_interface_list(){
        global $config;
@@ -533,7 +836,7 @@ function ovpn_lock() {
        $n = 0;
        while ($n < 10) {
                /* open the lock file in append mode to avoid race condition */
-               if ($fd = @fopen($lockfile, "x")) {
+               if ($fd = fopen($lockfile, "x")) {
                        /* succeeded */
                        fclose($fd);
                        return;
index 5151eca76d2b717015582a613713dcb9b1fd8ed5..5434c77dec61e428049c3018c16c80a457205256 100644 (file)
@@ -311,6 +311,14 @@ daemon
 
 EOD;
 
+               /* enable server[:port]? */
+               if ($dyndnscfg['server']) {
+                       if ($dyndnscfg['port'])
+                               $ezipupdateconf .= "server={$dyndnscfg['server']}:{$dyndnscfg['port']}\n";
+                       else
+                               $ezipupdateconf .= "server={$dyndnscfg['server']}\n";
+               }
+
                /* enable MX? */
                if ($dyndnscfg['mx']) {
                        $ezipupdateconf .= "mx={$dyndnscfg['mx']}\n";
@@ -364,6 +372,12 @@ function services_dnsmasq_configure() {
                        $args .= " -l {$g['vardb_path']}/dhcpd.leases" . 
                                " -s {$config['system']['domain']}";
                }
+               
+               if (isset($config['dnsmasq']['domainoverrides']) && is_array($config['dnsmasq']['domainoverrides'])) {
+                       foreach($config['dnsmasq']['domainoverrides'] as $override) {
+                               $args .= escapeshellarg(' --server=/' . $override['domain'] . '/' . $override['ip']);
+                       }
+               }
 
                /* run dnsmasq */
                mwexec("/usr/local/sbin/dnsmasq {$args}");
index 28b547239f1b9c6687bfd8cca336cc0449f0697d..32e3e447ad56ea75c9b2dc9707ecd93dfb4dac06 100644 (file)
@@ -543,7 +543,8 @@ function system_set_harddisk_standby() {
        if ($g['platform'] != "generic-pc")
                return;
 
-       if (isset($config['system']['harddiskstandby'])) {
+       if (isset($config['system']['harddiskstandby']) && 
+                       ($config['system']['harddiskstandby'] > 0)) {
                if ($g['booting']) {
                        echo 'Setting harddisk standby time... ';
                }
@@ -578,4 +579,76 @@ function system_polling_configure() {
        }
 }
 
+function system_set_termcap() {
+       global $config;
+       
+       if (isset($config['diag']['ipfstatentries'])) {
+               $lines = $config['diag']['ipfstatentries'] + 6;
+       }
+       else {
+               $lines = 306;
+       }
+       
+       $termcap = <<<EOD
+cons25w|ansiw|ansi80x25-raw:\
+       :am:bs:NP:ms:pt:AX:eo:bw:ut:km:\
+       :co#80:li#25:pa#64:Co#8:it#8:\
+       :al=\E[L:cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:\
+       :dc=\E[P:dl=\E[M:do=\E[B:bt=\E[Z:ho=\E[H:ic=\E[@:cb=\E[1K:\
+       :nd=\E[C:rs=\Ec:so=\E[7m:se=\E[27m:up=\E[A:cr=^M:ta=^I:\
+       :AF=\E[3%dm:AB=\E[4%dm:op=\E[39;49m:sc=\E7:rc=\E8:\
+       :k1=\E[M:k2=\E[N:k3=\E[O:k4=\E[P:k5=\E[Q:k6=\E[R:k7=\E[S:k8=\E[T:\
+       :k9=\E[U:k;=\E[V:F1=\E[W:F2=\E[X:K2=\E[E:nw=\E[E:ec=\E[%dX:\
+       :kb=^H:kh=\E[H:ku=\E[A:kd=\E[B:kl=\E[D:kr=\E[C:le=^H:sf=\E[S:sr=\E[T:\
+       :kN=\E[G:kP=\E[I:@7=\E[F:kI=\E[L:kD=\\177:kB=\E[Z:\
+       :IC=\E[%d@:DC=\E[%dP:SF=\E[%dS:SR=\E[%dT:AL=\E[%dL:DL=\E[%dM:\
+       :DO=\E[%dB:LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:cv=\E[%i%dd:ch=\E[%i%d`:\
+       :mb=\E[5m:md=\E[1m:mr=\E[7m:me=\E[m:bl=^G:\
+       :ve=\E[=S:vi=\E[=1S:vs=\E[=2S:
+cons25|ansis|ansi80x25:\
+       :ac=l\\332m\\300k\\277j\\331u\\264t\\303v\\301w\\302q\\304x\\263n\\305`^Da\\260f\\370g\\361~\\371.^Y-^Xh\\261i^U0\\333y\\363z\\362:\
+       :tc=cons25w:
+dumb|su|unknown:\
+       :am:co#132:li#$lines:do=^J:
+xterm-noapp|xterm with cursor keys in normal mode:\
+       :kl=\E[D:kd=\E[B:kr=\E[C:ku=\E[A:ks=\E=:ke=\E>:ti@:te@:tc=xterm:
+xterm|xterm-color|X11 terminal emulator:\
+       :ti@:te@:tc=xterm-xfree86:
+xterm-xfree86|XFree86 xterm:\
+       :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:\
+       :k5=\E[15~:k6=\E[17~:k7=\E[18~:k8=\E[19~:\
+       :k9=\E[20~:k;=\E[21~:F1=\E[23~:F2=\E[24~:\
+       :kH=\EOF:@7=\EOF:kI=\E[2~:\
+       :kh=\EOH:*6=\EOF:kP=\E[5~:kN=\E[6~:\
+       :ku=\EOA:kd=\EOB:kr=\EOC:kl=\EOD:Km=\E[M:tc=xterm-basic:
+xterm-basic|xterm common (XFree86):\
+       :li#24:co#80:am:kn#12:km:mi:ms:xn:bl=^G:\
+       :is=\E[!p\E[?3;4l\E[4l\E>:rs=\E[!p\E[?3;4l\E[4l\E>:le=^H:\
+       :AL=\E[%dL:DL=\E[%dM:DC=\E[%dP:al=\E[L:dc=\E[P:dl=\E[M:\
+       :UP=\E[%dA:DO=\E[%dB:LE=\E[%dD:RI=\E[%dC:\
+       :ho=\E[H:cd=\E[J:ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dH:cs=\E[%i%d;%dr:\
+       :im=\E[4h:ei=\E[4l:ks=\E[?1h\E=:ke=\E[?1l\E>:kD=\E[3~:kb=^H:\
+       :sf=\n:sr=\EM:st=\EH:ct=\E[3g:sc=\E7:rc=\E8:\
+       :eA=\E(B\E)0:as=^N:ae=^O:ml=\El:mu=\Em:up=\E[A:nd=\E[C:\
+       :md=\E[1m:me=\E[m^O:mr=\E[7m:so=\E[7m:se=\E[27m:us=\E[4m:ue=\E[24m:\
+       :ti=\E[?1049h:te=\E[?1049l:vi=\E[?25l:ve=\E[?25h:\
+       :ut:Co#8:pa#64:op=\E[39;49m:AB=\E[4%dm:AF=\E[3%dm:\
+
+EOD;
+
+       if (!file_exists("/usr/share/misc"))
+               mkdir("/usr/share/misc");
+
+       $fd = @fopen("/usr/share/misc/termcap", "w");
+       if (!$fd) {
+               printf("Error: cannot open termcap in system_set_termcap().\n");
+               return 1;
+       }
+       chmod("/usr/share/misc/termcap", 0644);
+       fwrite($fd, $termcap);
+       fclose($fd);
+       
+       return 0;
+}
+
 ?>
index 53d14de54fb76c3868a095ed26fabbe709a72414..bafc28f425d22765b0d523f8793457b07afbcbfb 100644 (file)
@@ -31,6 +31,7 @@
 /* kill a process by pid file */
 function killbypid($pidfile) {
        sigkillbypid($pidfile, "TERM");
+       unlink_if_exists($pidfile);
 }
 
 /* sigkill a process by pid file */
@@ -42,7 +43,7 @@ function sigkillbypid($pidfile, $sig) {
 
 /* kill a process by name */
 function killbyname($procname) {
-       mwexec("/usr/bin/killall " . escapeshellarg($procname));
+       return mwexec("/usr/bin/killall " . escapeshellarg($procname));
 }
 
 /* return the subnet address given a host address and a subnet bit count */
@@ -233,7 +234,7 @@ function get_interface_list() {
                if (substr($ifname, -1) == "*")
                        $ifname = substr($ifname, 0, strlen($ifname) - 1);
                
-               if (!preg_match("/^(ppp|sl|gif|faith|lo|ng|vlan)/", $ifname)) {
+               if (!preg_match("/^(ppp|sl|gif|faith|lo|ng|vlan|tun)/", $ifname)) {
                        $iflist[$ifname] = array();
                        
                        $iflist[$ifname]['mac'] = chop($alink[3]);
index 4cb37a96712f219fb5127bef49eef466609f2ceb..a6067b45ecb60a6dd92fadd6bbad68b6516c606a 100644 (file)
@@ -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");
+       "servernat proxyarpnet passthrumac allowedip wolentry vlan domainoverrides");
 
 function startElement($parser, $name, $attrs) {
        global $depth, $curpath, $config, $havedata, $listtags;
index 8a06cfbbedf6a24e843817f2aaa8b5a2adf3ec90..50dcfafbf3d0fe57eb97a7d9ffc781be231f6b8c 100644 (file)
@@ -89,7 +89,7 @@
        interfaces_optional_configure();
                
        /* start OpenVPN server & clients */
-       ovpn_configure();
+       ovpn_configure(false);
        
        /* resync ipfilter */
        filter_resync();
        /* start the captive portal */
        captiveportal_configure();
        
+       /* set up termcap (for the firewall states page) */
+       system_set_termcap();
+       
        /* execute the rc scripts of extensions */
        system_do_extensions();
        
index 6868cfdc171cdb4928664d0be758eee26ba607e7..93eab34a3fa23e97f7a0fcd1184bfd1f13e334be 100644 (file)
@@ -62,6 +62,9 @@
        
        /* reconfigure IPsec tunnels */
        vpn_ipsec_configure(true);
+       
+       /* reconfigure OpenVPN tunnels */
+       ovpn_configure(true);
        
        /* regenerate resolv.conf if DNS overrides are allowed or the BigPond
           client is enabled */
diff --git a/webgui/diag_arp.php b/webgui/diag_arp.php
new file mode 100644 (file)
index 0000000..57271f4
--- /dev/null
@@ -0,0 +1,199 @@
+#!/usr/local/bin/php
+<?php
+/*
+       diag_arp.php
+       part of m0n0wall (http://m0n0.ch/wall)
+
+       Copyright (C) 2005 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
+       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("Diagnostics", "ARP table");
+require("guiconfig.inc");
+
+?>
+<?php include("fbegin.inc"); ?>
+
+<?php
+
+$fp = @fopen("{$g['vardb_path']}/dhcpd.leases","r");
+
+if ($fp) {
+
+       $return = array();
+       
+       while ($line = fgets($fp)) {
+               $matches = "";
+       
+               // Sort out comments
+               // C-style comments not supported!
+               if (preg_match("/^\s*[\r|\n]/", $line, $matches[0]) ||
+                                       preg_match("/^([^\"#]*)#.*$/", $line, $matches[1]) ||
+                                       preg_match("/^([^\"]*)\/\/.*$/", $line, $matches[2]) ||
+                                       preg_match("/\s*#(.*)/", $line, $matches[3]) ||
+                                       preg_match("/\\\"\176/", $line, $matches[4])
+                       ) {
+                       $line = "";
+                       continue;
+               }
+       
+               if (preg_match("/(.*)#(.*)/", $line, $matches))
+                       $line = $matches[0];
+       
+               // Tokenize lines
+               do {
+                       if (preg_match("/^\s*\"([^\"]*)\"(.*)$/", $line, $matches)) {
+                               $line = $matches[2];
+                               $return[] = array($matches[1], 0);
+                       } else if (preg_match("/^\s*([{};])(.*)$/", $line, $matches)) {
+                               $line = $matches[2];
+                               $return[] = array($matches[0], 1);
+                       } else if (preg_match("/^\s*([^{}; \t]+)(.*)$/", $line, $matches)) {
+                               $line = $matches[2];
+                               $return[] = array($matches[1], 0);
+                       } else
+                               break;
+       
+               } while($line);
+       
+               $lines++;
+       }
+       
+       fclose($fp);
+       
+       $leases = array();
+       $i = 0;
+       
+       // Put everything together again
+       while ($data = array_shift($return)) {
+               if ($data[0] == "next") {
+                       $d = array_shift($return);
+               }
+               if ($data[0] == "lease") {
+                       $d = array_shift($return);
+                       $leases[$i]['ip'] = $d[0];
+               }
+               if ($data[0] == "client-hostname") {
+                       $d = array_shift($return);
+                       $leases[$i]['hostname'] = $d[0];
+               }
+               if ($data[0] == "hardware") {
+                       $d = array_shift($return);
+                       if ($d[0] == "ethernet") {
+                               $d = array_shift($return);
+                               $leases[$i]['mac'] = $d[0];
+                       }
+               } else if ($data[0] == "starts") {
+                       $d = array_shift($return);
+                       $d = array_shift($return);
+                       $leases[$i]['start'] = $d[0];
+                       $d = array_shift($return);
+                       $leases[$i]['start'] .= " " . $d[0];
+               } else if ($data[0] == "ends") {
+                       $d = array_shift($return);
+                       $d = array_shift($return);
+                       $leases[$i]['end'] = $d[0];
+                       $d = array_shift($return);
+                       $leases[$i]['end'] .= " " . $d[0];
+               } else if ($data[0] == "binding") {
+                       $d = array_shift($return);
+                       if ($d[0] == "state") {
+                               $d = array_shift($return);
+                               $leases[$i]['act'] = $d[0];
+                       }
+               } else if (($data[0] == "}") && ($data[1] == 1))                // End of group
+                       $i++;
+       }
+       
+       // Put this in an easy to use form
+       $dhcpmac = array();
+       $dhcpip = array();
+       
+       foreach ($leases as $value) {
+               $dhcpmac[$value['mac']] = $value['hostname'];   
+               $dhcpip[$value['ip']] = $value['hostname'];     
+       }
+       
+       unset($data);
+}
+
+exec("/usr/sbin/arp -an",$rawdata);
+
+$i = 0; 
+$ifdescrs = array('wan' => 'WAN', 'lan' => 'LAN');
+                                               
+for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
+       $ifdescrs['opt' . $j] = $config['interfaces']['opt' . $j]['descr'];
+}
+
+foreach ($ifdescrs as $key =>$interface) {
+       $hwif[$config['interfaces'][$key]['if']] = $interface;
+}
+
+$data = array();
+foreach ($rawdata as $line) {
+       $elements = explode(' ',$line);
+       
+       if ($elements[3] != "(incomplete)") {
+               $arpent = array();
+               $arpent['ip'] = trim(str_replace(array('(',')'),'',$elements[1]));
+               $arpent['mac'] = trim($elements[3]);
+               $arpent['interface'] = trim($elements[5]);
+               $data[] = $arpent;
+       }
+}
+
+function getHostName($mac,$ip)
+{
+       global $dhcpmac, $dhcpip;
+       
+       if ($dhcpmac[$mac])
+               return $dhcpmac[$mac];
+       else if ($dhcpip[$ip])
+               return $dhcpip[$ip];
+       else 
+               return "&nbsp;";        
+}
+
+?>
+
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr>
+    <td class="listhdrr">IP address</td>
+    <td class="listhdrr">MAC address</td>
+    <td class="listhdrr">Hostname</td>
+    <td class="listhdr">Interface</td>
+    <td class="list"></td>
+  </tr>
+<?php foreach ($data as $entry): ?>
+  <tr>
+    <td class="listlr"><?=$entry['ip'];?></td>
+    <td class="listr"><?=$entry['mac'];?></td>
+    <td class="listr"><?=getHostName($entry['mac'], $entry['ip']);?></td>
+    <td class="listr"><?=$hwif[$entry['interface']];?></td>
+  </tr>
+<?php endforeach; ?>
+</table>
+
+<?php include("fend.inc"); ?>
diff --git a/webgui/diag_ipfstat.php b/webgui/diag_ipfstat.php
new file mode 100644 (file)
index 0000000..808badf
--- /dev/null
@@ -0,0 +1,385 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       diag_ipfstat.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2005 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
+       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("Diagnostics", "Firewall states");
+require("guiconfig.inc");
+?>
+<?php
+
+flush();
+
+function natsort2d( &$arrIn, $index = null )
+{
+   
+   $arrTemp = array();
+   $arrOut = array();
+   
+   if (is_array($arrIn)) {
+          foreach ( $arrIn as $key=>$value ) {
+                  
+                  reset($value);
+                  $arrTemp[$key] = is_null($index)
+                                                          ? current($value)
+                                                          : $value[$index];
+          }
+   }
+   
+   natsort($arrTemp);
+   
+   foreach ( $arrTemp as $key=>$value ) {
+       $arrOut[$key] = $arrIn[$key];
+   }
+   
+   $arrIn = $arrOut;
+   
+}
+
+// sfilter and dfilter allow setting of source and dest IP filters
+// on the output.  $filterPassThru allows these source and dest 
+// filters to be passed on in the column sorting links.
+if (($_GET['sfilter']) or ($_GET['dfilter'])) {
+       
+       $filter = '';
+       if ($_GET['sfilter']) {
+               if (is_ipaddr($_GET['sfilter'])) {
+                       $filter = ' -S ' . $_GET['sfilter'];
+                       $filterPassThru = '&sfilter=' . $_GET['sfilter'];
+               }
+               else 
+                       unset ($_GET['sfilter']);
+       }
+       if ($_GET['dfilter']) {
+               if (is_ipaddr($_GET['dfilter']))
+               {
+                       $filter = ' -D ' . $_GET['dfilter'];
+                       $filterPassThru = '&dfilter=' . $_GET['dfilter'];
+               }
+               else 
+                       unset ($_GET['dfilter']);
+       }
+       
+}
+
+$rawdata = array();
+
+//         1         2         3         4         5         6         7         8
+//12345678901234567890123456789012345678901234567890123456789012345678901234567890
+exec("export TERM= && echo q | /sbin/ipfstat -t".$filter,$rawdata);
+// exporting TERM set to nothing gets you a "dumb" term.  echo q to ipfstat -t makes it
+// quit out after displaying the first page of data.
+
+// Get rid of the header data
+unset($rawdata[0],$rawdata[1],$rawdata[2],$rawdata[3]);
+
+// See if the user has set a limit to the number of entries...  
+if (isset($config['diag']['ipfstatentries'])) {
+       $linelimit = $config['diag']['ipfstatentries']; 
+}
+else {
+       $linelimit = 300;
+}
+
+
+if (isset($rawdata)) {
+       $count = 0;
+       foreach ($rawdata as $line) {
+               if (!strlen(trim($line)) < 70)
+               {
+//Source IP             Destination IP         ST   PR   #pkts    #bytes       ttl
+//68.16.26.144,1633     167.219.90.224,443    4/4  tcp  366724 370351656   2:30:00
+//      0                        1              2   3      4       5          6
+                       $split = preg_split("/\s+/", trim($line));                              
+                       $srcTmp = $split[0];
+                       $data[$count]['srcip'] = stripPort($srcTmp);
+                       $data[$count]['srcport'] = stripPort($srcTmp,true);
+                       $dstTmp = $split[1];;
+                       $data[$count]['dstip'] = stripPort($dstTmp);
+                       $data[$count]['dstport'] = stripPort($dstTmp,true);
+                       $data[$count]['protocol'] = $split[3];;
+                       $data[$count]['packets'] = $split[4];;
+                       $data[$count]['bytes'] = $split[5];;
+                       $timeTmp = $split[6];;
+                       $timeLen = strlen($timeTmp);
+                       switch ($timeLen) {
+                       case 4: 
+                               $data[$count]['ttl'] = strtotime("0:0".$timeTmp);
+                               break;
+                       case 5: 
+                               $data[$count]['ttl'] = strtotime("0:".$timeTmp);
+                               break;
+                       case 7: 
+                               $data[$count]['ttl'] = strtotime($timeTmp);
+                               break;
+                       default :
+                       // Debug logic, in case there is an unforseen issue
+                               echo $line . "<br>";
+                               echo $linelimit . "<br>";
+                               echo $timeTmp . "<br>";
+                               break;
+                       }
+                       $count++;
+                       if ($linelimit == $count) {
+                               // We've got all the data the user wanted to see - drop out of the foreach.
+                               break;
+                       }
+               }
+       }
+       
+       // Clear the statistics snapshot files, which track the packets and bytes of connections
+       if (isset($_GET['clear']))
+       {
+               if (file_exists('/tmp/packets'))
+                       unlink('/tmp/packets');
+               if (file_exists('/tmp/bytes'))
+                       unlink('/tmp/bytes');
+                       
+               // Redirect so we don't hit "clear" every time we refresh the screen.
+               header("Location: diag_ipfstat.php?".$filterPassThru);
+               exit;
+       }
+
+       // Create a new set of stats snapshot files
+       if (isset($_GET['new']))
+       {
+               $packets = array();
+               $bytes = array();
+               
+               // Create variables to let us later quickly access this data
+               if (is_array($data)) {
+                       foreach ($data as $row) {
+                               $packets[$row['srcip']][$row['srcport']][$row['dstip']][$row['dstport']][$row['protocol']] = $row['packets'];
+                               $bytes[$row['srcip']][$row['srcport']][$row['dstip']][$row['dstport']][$row['protocol']] = $row['bytes'];
+                       }
+               }
+
+               // Write the files out
+               writeStats("packets",$packets);
+               writeStats("bytes",$bytes);
+               
+               // If we're in view mode, pass that on.
+               if (isset($_GET['view']))
+                       $filterPassThru .= "&view=1";
+               
+               // Redirect so we don't hit "new" every time we refresh the screen.
+               header("Location: diag_ipfstat.php?&order=bytes&sort=des".$filterPassThru);
+               exit;
+       }
+               
+       // View the delta from the last snapshot against the current data.
+       if (isset($_GET['view']))
+       {
+
+               // Read the stats data files
+               readStats("packets",$packets);
+               readStats("bytes",$bytes);
+
+               if (is_array($data)) {
+                       foreach ($data as $key => $row) {
+                               if (isset($packets[$row['srcip']][$row['srcport']][$row['dstip']][$row['dstport']][$row['protocol']]))
+                               {
+                                       if (isset($bytes[$row['srcip']][$row['srcport']][$row['dstip']][$row['dstport']][$row['protocol']]))
+                                       {
+                                               $tempPackets = $data[$key]['packets'] - $packets[$row['srcip']][$row['srcport']][$row['dstip']][$row['dstport']][$row['protocol']];
+                                               $tempBytes = $data[$key]['bytes'] - $bytes[$row['srcip']][$row['srcport']][$row['dstip']][$row['dstport']][$row['protocol']];
+                                               if (($tempPackets > -1) && ($tempBytes > -1))
+                                               {
+                                                       $data[$key]['packets'] = $tempPackets;
+                                                       $data[$key]['bytes'] = $tempBytes;
+                                               }
+                                       }
+                               }
+                               
+                       }
+               }
+               
+               $filterPassThru .= "&view=1";
+               $viewPassThru = "&view=1";
+       }
+
+       // Sort it by the selected order
+       if ($_GET['order']) {
+               natsort2d($data,$_GET['order']);
+               if ($_GET['sort'])
+               {
+                       if ($_GET['sort'] == "des")
+                       $data = array_reverse($data);
+               }
+       }
+}
+
+
+
+function writeStats($fname, &$data) {
+       $fname = "/tmp/" . $fname;
+       if (file_exists($fname))
+               unlink($fname);
+       $file = fopen($fname, 'a');
+       fwrite($file, serialize($data)); 
+       fclose($file);
+}
+
+function readStats($fname, &$data) {
+       $fname = "/tmp/" . $fname;
+       if (file_exists($fname))
+       {
+               $file = fopen($fname,'r');
+               $data = unserialize(fread($file, filesize($fname)));
+               fclose($file);                  
+       }
+}
+
+function sortOrder($column) {
+       
+       if ($_GET['order'] == $column) {
+               if ($_GET['sort'] == 'des')
+                       return "&sort=asc";     
+               return "&sort=des";
+       }
+       else 
+               return "&sort=asc";     
+}
+
+function stripPort($ip, $showPort = false) {
+       if (!$showPort) {
+               if (strpos($ip,',') > 0)
+                       return substr($ip,0,strpos($ip,","));
+               else 
+                       return ($ip);
+       }
+       else {
+               if (strpos($ip,',') > 0) {
+                       return substr($ip,(strpos($ip,",")+1));
+               }
+               else 
+                       return "&nbsp;";
+       }
+}
+
+function displayIP($ip, $col) {
+       
+       global $viewPassThru;
+       
+       switch ($col) {
+               case 'srcip':
+                       if ($_GET['sfilter']) {
+                               if ($_GET['sfilter'] == $ip)
+                                       return $ip;
+                       }
+                       else {
+                               return '<a href="?sfilter='.$ip.$viewPassThru.'">'. $ip .'</a>';
+                       }
+                       break;
+       
+               case 'dstip':
+                       if ($_GET['dfilter']) {
+                               if ($_GET['dfilter'] == $ip)
+                                       return $ip;                             
+                       }
+                       else {
+                               return '<a href="?dfilter='.$ip.$viewPassThru.'">'. $ip .'</a>';
+                       }                       
+                       break;
+       }
+       
+}
+
+// Get timestamp of snapshot file, if it exists, for display later.
+if (!(file_exists('/tmp/packets'))) {
+       $lastSnapshot = "Never"; 
+}
+else { 
+       $lastSnapshot = strftime("%m/%d/%y %H:%M:%S",filectime('/tmp/packets'));
+}
+
+// Moved this down here due to the potential for redirects, up above.
+include("fbegin.inc");
+
+?>
+
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr>
+       <td class="listhdrr" colspan="8">Statistics snapshot control</td>
+  </tr>
+  <tr>
+    <?php if (($lastSnapshot!='Never') && (!isset($_GET['view']))) :?>  
+    <td class="listlr"><a href="?view=1&order=bytes&sort=des<?=$filterPassThru;?>">View delta</a></td>
+    <td class="listr"><a href="?new=1<?=$filterPassThru;?>">Start new</a></td>
+    <td class="listr"><a href="?clear=1">Clear snapshot</a></td>
+       <td class="listr" colspan="5" align="right">Last statistics snapshot: <?=$lastSnapshot;?></td>    
+    <?php endif ?>
+    <?php if (($lastSnapshot!='Never') && (isset($_GET['view']))) :?>  
+    <td class="listlr"><a href="?new=1<?=$filterPassThru;?>">Start new</a></td>
+    <td class="listr"><a href="?clear=1">Clear</a></td>
+       <td class="listr" colspan="6" align="right"><span class="red">Viewing delta of statistics snapshot: <?=$lastSnapshot;?></span></td>    
+    <?php endif ?>    
+    <?php if ($lastSnapshot=='Never') :?>
+    <td class="listlr"><a href="?new=1<?=$filterPassThru;?>">Start new</a></td>
+    <td class="listr" colspan="7" align="right">Last statistics snapshot: <?=$lastSnapshot;?></td>    
+    <?php endif ?>
+  </tr>
+  <tr>
+       <td colspan="8">&nbsp;</td>
+  </tr>
+  <tr>
+    <td class="listhdrr"><a href="?order=srcip<?=sortOrder('srcip');echo $filterPassThru;?>">Source</a></td>
+    <td class="listhdrr" align="right"><a href="?order=srcport<?=sortOrder('srcport');echo $filterPassThru;?>">Port</a></td>
+    <td class="listhdrr"><a href="?order=dstip<?=sortOrder('dstip');echo $filterPassThru;?>">Destination</a></td>
+    <td class="listhdrr" align="right"><a href="?order=dstport<?=sortOrder('dstport');echo $filterPassThru;?>">Port</a></td>
+    <td class="listhdrr"><a href="?order=protocol<?=sortOrder('protocol');echo $filterPassThru;?>">Protocol</a></td>
+    <td class="listhdrr" align="right"><a href="?order=packets<?=sortOrder('packets');echo $filterPassThru;?>">Packets</a></td>
+    <td class="listhdrr" align="right"><a href="?order=bytes<?=sortOrder('bytes');echo $filterPassThru;?>">Bytes</a></td>
+    <td class="listhdr" align="right"><a href="?order=ttl<?=sortOrder('ttl');echo $filterPassThru;?>">TTL</a></td>
+    <td class="list"></td>
+  </tr>
+<?php if (is_array($data)): foreach ($data as $entry): ?>
+  <tr>
+    <td class="listlr"><?=displayIP($entry['srcip'],'srcip');?></td>
+    <td class="listr"><?=$entry['srcport'];?></td>
+    <td class="listr"><?=displayIP($entry['dstip'],'dstip');?></td>
+    <td class="listr"><?=$entry['dstport'];?></td>
+    <td class="listr"><?=$entry['protocol'];?></td>
+    <td class="listr" align="right"><?=$entry['packets'];?></td>
+    <td class="listr" align="right"><?=$entry['bytes'];?></td>
+    <td class="listr" align="right"><?=preg_replace("/^((00:0)|(00:)|(0))/","",strftime('%H:%M:%S',$entry['ttl']));?></td>    
+  </tr>
+<?php endforeach; endif; ?>
+</table>
+<br><strong>Firewall connection states displayed: <?=count($data);?></strong>
+<?php if ($filterPassThru): ?>
+<p>
+<form action="diag_ipfstat.php" method="GET">
+<input type="hidden" name="order" value="bytes">
+<input type="hidden" name="sort" value="des">
+<input type="submit" class="formbtn" value="Unfilter View">
+</form>
+</p>
+<?php endif; ?>
+<?php include("fend.inc"); ?>
index a06cbab13be1b5be10391cf43c8543c303609eff..c566b9571bc2ede32f75f66267a38cd947d22077 100644 (file)
@@ -38,6 +38,9 @@ if (!$nentries)
 
 if ($_POST['clear']) {
        exec("/usr/sbin/clog -i -s 262144 /var/log/system.log");
+       /* redirect to avoid reposting form data on refresh */
+       header("Location: diag_logs.php");
+       exit;
 }
 
 function dump_clog($logfile, $tail, $withorig = true) {
@@ -66,7 +69,7 @@ function dump_clog($logfile, $tail, $withorig = true) {
 <table width="100%" border="0" cellpadding="0" cellspacing="0">
   <tr><td class="tabnavtbl">
   <ul id="tabnav">
-       <li class="tabact">System</li>
+       <li class="tabact"><a href="diag_logs.php" style="color:black" title="reload page">System</a></li>
     <li class="tabinact"><a href="diag_logs_filter.php">Firewall</a></li>
     <li class="tabinact"><a href="diag_logs_dhcp.php">DHCP</a></li>
     <li class="tabinact"><a href="diag_logs_portal.php">Captive portal</a></li>
index b08591524775df9378e85550db7e9214b27de41d..f43433c04021f08cb9991bac428cc54956e32812 100644 (file)
@@ -38,6 +38,9 @@ if (!$nentries)
 
 if ($_POST['clear']) {
        exec("/usr/sbin/clog -i -s 32768 /var/log/dhcpd.log");
+       /* redirect to avoid reposting form data on refresh */
+       header("Location: diag_logs_dhcp.php");
+       exit;
 }
 
 function dump_clog($logfile, $tail, $withorig = true) {
@@ -68,7 +71,7 @@ function dump_clog($logfile, $tail, $withorig = true) {
   <ul id="tabnav">
     <li class="tabinact1"><a href="diag_logs.php">System</a></li>
     <li class="tabinact"><a href="diag_logs_filter.php">Firewall</a></li>
-    <li class="tabact">DHCP</li>
+    <li class="tabact"><a href="diag_logs_dhcp.php" style="color:black" title="reload page">DHCP</a></li>
     <li class="tabinact"><a href="diag_logs_portal.php">Captive portal</a></li>
     <li class="tabinact"><a href="diag_logs_vpn.php">PPTP VPN</a></li>
     <li class="tabinact"><a href="diag_logs_settings.php">Settings</a></li>
index e8d37ed81391d13b59cb3f4a10398dc07caff788..d6b8ea39702f4a7ecbfbe61b1c0ee831eb4d6113 100644 (file)
@@ -35,13 +35,16 @@ require("guiconfig.inc");
 $protocols = explode(" ", "TCP UDP TCP/UDP ICMP ESP AH GRE IPv6 IGMP any");
 
 $nentries = $config['syslog']['nentries'];
-$resolve = $config['syslog']['resolve'];
+$resolve = isset($config['syslog']['resolve']);
 
 if (!$nentries)
        $nentries = 50;
 
 if ($_POST['clear']) {
        exec("/usr/sbin/clog -i -s 262144 /var/log/filter.log");
+       /* redirect to avoid reposting form data on refresh */
+       header("Location: diag_logs_filter.php");
+       exit;
 }
 
 
@@ -135,30 +138,38 @@ function conv_clog($logfile, $tail) {
                        $flent['count'] = substr($ipfa[$i], 0, -1);
                        $i++;
                }
-               if (!isset($iface) || ($iftable[$ipfa[$i]] && strstr($iface, $iftable[$ipfa[$i]])))
+               
+               if ($iftable[$ipfa[$i]])
                        $flent['interface'] = $iftable[$ipfa[$i]];
-               else if (!isset($iface) || strstr($iface, $ipfa[$i]))
+               else if (strpos($ipfa[$i], "ng") !== false)
+                       $flent['interface'] = "PPTP";
+               else
                        $flent['interface'] = $ipfa[$i];
-               else continue;
+               
+               if (isset($iface)) {
+                       if ($iface != $flent['interface'])
+                               continue;
+               }
+               
                $i += 2;
                if (!isset($action) || strstr($action, $ipfa[$i]))
                        $flent['act'] = $ipfa[$i];
-               else continue; 
+               else
+                       continue; 
                $i++;
                list($flent['src'], $flent['srcport']) = format_ipf_ip($ipfa[$i],$srcport);
-               if (!isset($flent['src'])) continue;
+               if (!isset($flent['src']))
+                       continue;
                $i += 2;
                list($flent['dst'], $flent['dstport']) = format_ipf_ip($ipfa[$i],$dstport);
-               if (!isset($flent['dst'])) continue;
+               if (!isset($flent['dst']))
+                       continue;
                $i += 2;
                $protocol = strtoupper($ipfa[$i]);
                if (!isset($proto) || ($proto == $protocol))
                        $flent['proto'] = $protocol;
-               else continue;
-               if (isset($resolve)) {
-                       $flent['dst'] = gethostbyaddr($flent['dst']);
-                       $flent['src'] = gethostbyaddr($flent['src']);
-               }
+               else
+                       continue;
                if ($protocol == "ICMP") {
                        $i += 5;
                        $flent['dst'] = $flent['dst'] . ", type " . $ipfa[$i];
@@ -170,13 +181,21 @@ function conv_clog($logfile, $tail) {
 }
 
 function format_ipf_ip($ipfip,$uport) {
+       global $resolve;
+
        list($ip,$port) = explode(",", $ipfip);
+       if ($resolve) {
+               if (!$port)
+                       return array(gethostbyaddr($ip), "");
+               if ($uport == "" || ($uport == $port))
+                       return array(gethostbyaddr($ip) . ", port " . $port, $port);
+               return;
+       }
+
        if (!$port)
                return array($ip, "");
-
        if ($uport == "" || ($uport == $port))
                return array($ip . ", port " . $port, $port);
-
        return;
 }
 ?>
index fce4b32d8fdfcd2c79684c4951fd1645e902bca0..6b66e57679ea2005815bcc063ca2cd73dd87f0cc 100644 (file)
@@ -38,6 +38,9 @@ if (!$nentries)
 
 if ($_POST['clear']) {
        exec("/usr/sbin/clog -i -s 32768 /var/log/portalauth.log");
+       /* redirect to avoid reposting form data on refresh */
+       header("Location: diag_logs_portal.php");
+       exit;
 }
 
 function dump_clog($logfile, $tail) {
@@ -64,7 +67,7 @@ function dump_clog($logfile, $tail) {
     <li class="tabinact1"><a href="diag_logs.php">System</a></li>
     <li class="tabinact"><a href="diag_logs_filter.php">Firewall</a></li>
     <li class="tabinact"><a href="diag_logs_dhcp.php">DHCP</a></li>
-    <li class="tabact">Captive portal</li>
+    <li class="tabact"><a href="diag_logs_portal.php" style="color:black" title="reload page">Captive portal</a></li>
     <li class="tabinact"><a href="diag_logs_vpn.php">PPTP VPN</a></li>
     <li class="tabinact"><a href="diag_logs_settings.php">Settings</a></li>
   </ul>
index 52d5bf1798fd6bb60cdc2620f8369cf853ccc512..22b881fb7a18f9e18776d8854b0f5efff55a93ed 100644 (file)
@@ -38,6 +38,9 @@ if (!$nentries)
 
 if ($_POST['clear']) {
        exec("/usr/sbin/clog -i -s 65536 /var/log/vpn.log");
+       /* redirect to avoid reposting form data on refresh */
+       header("Location: diag_logs_vpn.php");
+       exit;
 }
 
 function dump_clog($logfile, $tail) {
@@ -74,7 +77,7 @@ function dump_clog($logfile, $tail) {
     <li class="tabinact"><a href="diag_logs_filter.php">Firewall</a></li>
     <li class="tabinact"><a href="diag_logs_dhcp.php">DHCP</a></li>
     <li class="tabinact"><a href="diag_logs_portal.php">Captive portal</a></li>
-    <li class="tabact">PPTP VPN</li>
+    <li class="tabact"><a href="diag_logs_vpn.php" style="color:black" title="reload page">PPTP VPN</a></li>
     <li class="tabinact"><a href="diag_logs_settings.php">Settings</a></li>
   </ul>
   </td></tr>
index cbc5f27a841f9f9b54d6aad9fdbc86b5fbdf2ded..89ef3b448653e56156a1e2ffc1ce16cf4f390b6f 100644 (file)
@@ -51,8 +51,8 @@ if ($_POST) {
        if (!$input_errors) {
                $do_ping = true;
                $host = $_POST['host'];
+               $interface = $_POST['interface'];
                $count = $_POST['count'];
-
        }
 }
 if (!isset($do_ping)) {
@@ -60,6 +60,29 @@ if (!isset($do_ping)) {
        $host = '';
        $count = DEFAULT_COUNT;
 }
+
+function get_interface_addr($ifdescr) {
+       
+       global $config, $g;
+       
+       /* find out interface name */
+       if ($ifdescr == "wan")
+               $if = get_real_wan_interface();
+       else
+               $if = $config['interfaces'][$ifdescr]['if'];
+       
+       /* try to determine IP address and netmask with ifconfig */
+       unset($ifconfiginfo);
+       exec("/sbin/ifconfig " . $if, $ifconfiginfo);
+       
+       foreach ($ifconfiginfo as $ici) {
+               if (preg_match("/inet (\S+)/", $ici, $matches)) {
+                       return $matches[1];
+               }
+       }
+       
+       return false;
+}
 ?>
 <?php include("fbegin.inc"); ?>
 <?php if ($input_errors) print_input_errors($input_errors); ?>
@@ -70,6 +93,24 @@ if (!isset($do_ping)) {
                                  <td width="78%" class="vtable"> 
                     <?=$mandfldhtml;?><input name="host" type="text" class="formfld" id="host" size="20" value="<?=htmlspecialchars($host);?>"></td>
                                </tr>
+                               <tr>
+                                 <td width="22%" valign="top" class="vncellreq">Interface</td>
+                                 <td width="78%" class="vtable">
+                                 <select name="interface" class="formfld">
+                      <?php $interfaces = array('wan' => 'WAN', 'lan' => 'LAN');
+                                         for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+                                           if (isset($config['interfaces']['opt' . $i]['enable']) &&
+                                                       !$config['interfaces']['opt' . $i]['bridge'])
+                                                       $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
+                                         }
+                                         foreach ($interfaces as $iface => $ifacename): ?>
+                      <option value="<?=$iface;?>" <?php if ($iface == $interface) echo "selected"; ?>> 
+                      <?=htmlspecialchars($ifacename);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select>
+                                 </td>
+                               </tr>
                                <tr>
                                  <td width="22%" valign="top" class="vncellreq">Count</td>
                                  <td width="78%" class="vtable">
@@ -91,7 +132,11 @@ if (!isset($do_ping)) {
                                        echo("<strong>Ping output:</strong><br>");
                                        echo('<pre>');
                                        ob_end_flush();
-                                       system("/sbin/ping -c$count " . escapeshellarg($host));
+                                       $ifaddr = get_interface_addr($interface);
+                                       if ($ifaddr)
+                                               system("/sbin/ping -S$ifaddr -c$count " . escapeshellarg($host));
+                                       else
+                                               system("/sbin/ping -c$count " . escapeshellarg($host));
                                        echo('</pre>');
                                }
                                ?>
diff --git a/webgui/diag_traceroute.php b/webgui/diag_traceroute.php
new file mode 100644 (file)
index 0000000..8c36e23
--- /dev/null
@@ -0,0 +1,104 @@
+#!/usr/local/bin/php
+<?php
+/*
+       diag_traceroute.php
+       part of m0n0wall (http://m0n0.ch/wall)
+
+       Copyright (C) 2005 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
+       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("Diagnostics", "Traceroute");
+require("guiconfig.inc");
+
+
+define('MAX_TTL', 64);
+define('DEFAULT_TTL', 18);
+
+if ($_POST) {
+       unset($input_errors);
+       unset($do_traceroute);
+
+       /* input validation */
+       $reqdfields = explode(" ", "host ttl");
+       $reqdfieldsn = explode(",", "Host,ttl");
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+       if (($_POST['ttl'] < 1) || ($_POST['ttl'] > MAX_TTL)) {
+               $input_errors[] = "Maximum number of hops must be between 1 and {MAX_TTL}";
+       }
+
+       if (!$input_errors) {
+               $do_traceroute = true;
+               $host = $_POST['host'];
+               $ttl = $_POST['ttl'];
+
+       }
+}
+if (!isset($do_traceroute)) {
+       $do_traceroute = false;
+       $host = '';
+       $ttl = DEFAULT_TTL;
+}
+?>
+<?php include("fbegin.inc"); ?>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+                       <form action="diag_traceroute.php" method="post" name="iform" id="iform">
+                         <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr>
+                                 <td width="22%" valign="top" class="vncellreq">Host</td>
+                                 <td width="78%" class="vtable"> 
+                    <?=$mandfldhtml;?><input name="host" type="text" class="formfld" id="host" size="20" value="<?=htmlspecialchars($host);?>"></td>
+                               </tr>
+                               <tr>
+                                 <td width="22%" valign="top" class="vncellreq">Maximum number of hops</td>
+                                 <td width="78%" class="vtable">
+                                       <select name="ttl" class="formfld" id="ttl">
+                                       <?php for ($i = 1; $i <= MAX_TTL; $i++): ?>
+                                       <option value="<?=$i;?>" <?php if ($i == $ttl) echo "selected"; ?>><?=$i;?></option>
+                                       <?php endfor; ?>
+                                       </select></td>
+                               </tr>
+                               <tr>
+                                 <td width="22%" valign="top">&nbsp;</td>
+                                 <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Traceroute">
+                               </td>
+                               </tr>
+                               <tr>
+                               <td valign="top" colspan="2">
+                               <p><span class="vexpl"><span class="red"><strong>Note: </strong></span> Traceroute may take a while to complete.  You may hit the Stop button on your browser at any time to see the progress of failed traceroutes.<p>
+                               <? if ($do_traceroute) {
+                                       echo("<br><strong>Traceroute output:</strong><br>");
+                                       echo('<pre>');
+                                       ob_end_flush();
+                                       system("/usr/sbin/traceroute -w 2 -m " . escapeshellarg($ttl) . " " . escapeshellarg($host));
+                                       echo('</pre>');
+                               }
+                               ?>
+                               </td>
+                               </tr>
+                       </table>
+</form>
+<?php include("fend.inc"); ?>
index 039e50a3966f42ab2e8146a20f042a642cbf2a69..ff8d3c87565bb933343d5a0911e489918b24dde8 100644 (file)
@@ -82,9 +82,9 @@ function showhide(tspan, tri) {
                          <br>
               &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/interfaces_lan.php" class="navlnk">LAN</a><br>
               &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/interfaces_wan.php" class="navlnk">WAN</a><br>
-                         <?php for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++): if (!isset($config['interfaces']['opt' . $i]['ovpn'])): ?>
+                         <?php for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++): ?>
               &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/interfaces_opt.php?index=<?=$i;?>" class="navlnk"><?=htmlspecialchars($config['interfaces']['opt' . $i]['descr']);?></a><br>
-                         <?php endif; endfor; ?>
+                         <?php endfor; ?>
               <strong>Firewall</strong><br>
               &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/firewall_rules.php" class="navlnk">Rules</a><br>
               &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/firewall_nat.php" class="navlnk">NAT</a><br>
@@ -104,10 +104,13 @@ function showhide(tspan, tri) {
               <strong>VPN</strong><br>
               &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/vpn_ipsec.php" class="navlnk">IPsec</a><br>
               &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/vpn_pptp.php" class="navlnk">PPTP</a><br>
-              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/vpn_openvpn.php" class="navlnk">OpenVPN</a><br>
+              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/vpn_openvpn_srv.php" class="navlnk">OpenVPN</a><br>
               <strong>Status</strong><br>
               &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/index.php" class="navlnk">System</a><br>
               &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/status_interfaces.php" class="navlnk">Interfaces</a><br>
+                         <?php if (is_array($config['ovpn']['server']['tunnel'])): ?>
+              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/status_ovpn.php" class="navlnk">OpenVPN</a><br>
+                 <?php endif; ?>
               &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/status_graph.php" class="navlnk">Traffic graph</a><br>
               &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/status_wireless.php" class="navlnk">Wireless</a><br>
                          <?php if (isset($config['captiveportal']['enable'])): ?>
@@ -141,6 +144,9 @@ endif;
                                  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/diag_dhcp_leases.php" class="navlnk">DHCP leases</a><br>
                                  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/diag_ipsec_sad.php" class="navlnk">IPsec</a><br>
                                  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/diag_ping.php" class="navlnk">Ping</a><br>
+                                 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/diag_traceroute.php" class="navlnk">Traceroute</a><br>
+                                 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/diag_arp.php" class="navlnk">ARP table</a><br>
+                                 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/diag_ipfstat.php" class="navlnk">Firewall states</a><br>
                                  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/diag_resetstate.php" class="navlnk">Reset state</a><br>
                                  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/diag_backup.php" class="navlnk">Backup/Restore</a><br>
                                  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/diag_defaults.php" class="navlnk">Factory 
index 87758763e355bb831f40a44ddf905425744a5a8b..07c061b0a414a85dc64a1b495a5d8d498569a15d 100644 (file)
@@ -147,17 +147,17 @@ if ($_POST) {
                
                touch($d_natconfdirty_path);
 
-                if ($_POST['autoaddproxy']) {
-                        /* auto-generate a matching proxy arp entry */
-                        $arpent = array();           
-                        $arpent['interface'] = $_POST['interface'];
-                        $arpent['network'] = $_POST['external'] . "/" . $_POST['subnet'];
-                        $arpent['descr'] = "NAT " . $_POST['descr'];
-                        
-                        $config['proxyarp']['proxyarpnet'][] = $arpent;
-                        
-                        touch($d_proxyarpdirty_path);
-                }
+               if ($_POST['autoaddproxy']) {
+                       /* auto-generate a matching proxy arp entry */
+                       $arpent = array();           
+                       $arpent['interface'] = $_POST['interface'];
+                       $arpent['network'] = $_POST['external'] . "/" . $_POST['subnet'];
+                       $arpent['descr'] = "NAT " . $_POST['descr'];
+                       
+                       $config['proxyarp']['proxyarpnet'][] = $arpent;
+                       
+                       touch($d_proxyarpdirty_path);
+               }
                
                write_config();
                
index 59035ee575cd282b2b60242d7bf51d20ad4a2298..89e8c0ce421c4f5c7782f7c4347b3258ff29821b 100644 (file)
@@ -162,6 +162,16 @@ function create_magic ($maxup, $maxdown, $p2plow,$maskq) {
   if ($p2plow) 
     populate_p2p($rulei);
 
+  $config['shaper']['rule'][$rulei]['descr'] = "m_TCP ACK Upload";
+  $config['shaper']['rule'][$rulei]['targetqueue'] = 2;
+  $config['shaper']['rule'][$rulei]['interface'] = "wan";
+  $config['shaper']['rule'][$rulei]['direction'] = "out";
+  $config['shaper']['rule'][$rulei]['source']['any'] = TRUE;
+  $config['shaper']['rule'][$rulei]['destination']['any'] = TRUE;
+  $config['shaper']['rule'][$rulei]['iplen'] = "0-80";
+  $config['shaper']['rule'][$rulei]['protocol'] = "tcp";
+  $config['shaper']['rule'][$rulei]['tcpflags'] = "ack";
+  $rulei++; 
   $config['shaper']['rule'][$rulei]['descr'] = "m_Small Pkt Upload";
   $config['shaper']['rule'][$rulei]['targetqueue'] = 0;
   $config['shaper']['rule'][$rulei]['interface'] = "wan";
@@ -211,16 +221,6 @@ function create_magic ($maxup, $maxdown, $p2plow,$maskq) {
   $config['shaper']['rule'][$rulei]['destination']['any'] = TRUE;
   $config['shaper']['rule'][$rulei]['protocol'] = "icmp";
   $rulei++;
-  $config['shaper']['rule'][$rulei]['descr'] = "m_TCP ACK Upload";
-  $config['shaper']['rule'][$rulei]['targetqueue'] = 2;
-  $config['shaper']['rule'][$rulei]['interface'] = "wan";
-  $config['shaper']['rule'][$rulei]['direction'] = "out";
-  $config['shaper']['rule'][$rulei]['source']['any'] = TRUE;
-  $config['shaper']['rule'][$rulei]['destination']['any'] = TRUE;
-  $config['shaper']['rule'][$rulei]['iplen'] = "0-80";
-  $config['shaper']['rule'][$rulei]['protocol'] = "tcp";
-  $config['shaper']['rule'][$rulei]['tcpflags'] = "ack";
-  $rulei++; 
   $config['shaper']['rule'][$rulei]['descr'] = "m_Catch-All Upload";
   $config['shaper']['rule'][$rulei]['targetqueue'] = 3;
   $config['shaper']['rule'][$rulei]['interface'] = "wan";
index 94503b8ab7adfe1d4138c6e4395f5f4c6bdbfffd..b97d49daec62404e128eb4870c4af01a72ad1bf4 100644 (file)
@@ -125,8 +125,7 @@ if ($_POST) {
                     </select> <br> <span class="vexpl">If 'source' or 'destination' 
                     is chosen, a dynamic queue associated with the pipe and with 
                     the weight given above will be created for each source/destination 
-                    IP address encountered, respectively. This makes it possible 
-                    to easily specify bandwidth limits per host.</span></td>
+                    IP address encountered, respectively.</span></td>
                 </tr>
                 <tr> 
                   <td width="22%" valign="top" class="vncell">Description</td>
index 9764f45c9e0ae03829c5689f9d28141bcffb24d3..a1796eed3b3bd5f2813ea3021654f3e15362c777 100644 (file)
@@ -46,7 +46,7 @@ $d_filterconfdirty_path = $g['varrun_path'] . "/filter.conf.dirty";
 $d_ipsecconfdirty_path = $g['varrun_path'] . "/ipsec.conf.dirty";
 $d_shaperconfdirty_path = $g['varrun_path'] . "/shaper.conf.dirty";
 $d_pptpuserdirty_path = $g['varrun_path'] . "/pptpd.user.dirty";
-$d_hostsdirty_path = $g['varrun_path'] . "/hosts.dirty";
+$d_dnsmasqdirty_path = $g['varrun_path'] . "/dnsmasq.dirty";
 $d_staticmapsdirty_path = $g['varrun_path'] . "/staticmaps.dirty";
 $d_staticroutesdirty_path = $g['varrun_path'] . "/staticroutes.dirty";
 $d_aliasesdirty_path = $g['varrun_path'] . "/aliases.dirty";
@@ -57,6 +57,7 @@ $d_sysrebootreqd_path = $g['varrun_path'] . "/sysreboot.reqd";
 $d_passthrumacsdirty_path = $g['varrun_path'] . "/passthrumacs.dirty";
 $d_allowedipsdirty_path = $g['varrun_path'] . "/allowedips.dirty";
 $d_ovpnclidirty_path = $g['varrun_path'] . "/ovpnclient.dirty";
+$d_ovpnsrvdirty_path = $g['varrun_path'] . "/ovpnserver.dirty";
 
 if (file_exists($d_firmwarelock_path)) {
        if (!$d_isfwfile) {
@@ -330,6 +331,16 @@ function pptpd_users_sort() {
        usort($config['pptpd']['user'], "usercmp");
 }
 
+function captiveportal_users_sort() {
+       global $g, $config;
+       
+       function cpusercmp($a, $b) {
+               return strcasecmp($a['name'], $b['name']);
+       }
+       
+       usort($config['captiveportal']['user'], "cpusercmp");
+}
+
 function staticroutes_sort() {
        global $g, $config;
 
@@ -344,12 +355,25 @@ function hosts_sort() {
        global $g, $config;
 
        function hostcmp($a, $b) {
-               return strcasecmp($a['host'], $b['host']);
+               if (strcasecmp($a['domain'], $b['domain']) == 0)
+                       return strcasecmp($a['host'], $b['host']);
+               else
+                       return strcasecmp($a['domain'], $b['domain']);
        }
 
        usort($config['dnsmasq']['hosts'], "hostcmp");
 }
 
+function domainoverrides_sort() {
+       global $g, $config;
+
+       function domainoverridescmp($a, $b) {
+               return strcasecmp($a['domain'], $b['domain']);
+       }
+
+       usort($config['dnsmasq']['domainoverrides'], "domainoverridescmp");
+}
+
 function staticmaps_sort($if) {
        global $g, $config;
 
index e518ddaa44dac2e619f6c8bf78f4913ffa49bda7..53f1c2614e607fdcb4ae34c470e880042fbd394f 100644 (file)
@@ -197,7 +197,11 @@ if ($_GET['act'] == "add") {
        <td class="list">&nbsp;</td>
   </tr>
   <?php foreach ($config['interfaces'] as $ifname => $iface):
-       if ($iface['descr'])
+       /* we don't want to see the OpenVPN tun interfaces */
+       if (isset($iface['ovpn']))
+               continue;
+
+       if ($iface['descr'])
                $ifdescr = $iface['descr'];
        else
                $ifdescr = strtoupper($ifname);
index a65824bf52b24f333e1e841d54f14b85deee657e..e5b4c27a009482c5929e74480bc9b539ac5e9761 100644 (file)
@@ -123,7 +123,7 @@ function ipaddr_change() {
                 <tr> 
                   <td width="22%" valign="top" class="vncellreq">IP address</td>
                   <td width="78%" class="vtable"> 
-                    <?=$mandfldhtml;?><input name="ipaddr" type="text" class="formfld" id="hostname" size="20" value="<?=htmlspecialchars($pconfig['ipaddr']);?>" onchange="ipaddr_change()">
+                    <?=$mandfldhtml;?><input name="ipaddr" type="text" class="formfld" id="ipaddr" size="20" value="<?=htmlspecialchars($pconfig['ipaddr']);?>" onchange="ipaddr_change()">
                     / 
                     <select name="subnet" class="formfld" id="subnet">
                       <?php for ($i = 31; $i > 0; $i--): ?>
index 616e01d5e3279348352810b3749e40c10a1e3f68..812201e7977829183800433b692ea0f21a1090d1 100644 (file)
@@ -80,7 +80,7 @@ require("guiconfig.inc");
               <br>
               Peter Allgeyer (<a href="mailto:allgeyer@web.de">allgeyer@web.de</a>)<br>
               &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">&quot;reject&quot; type filter rules; dial-on-demand; WAN connect/disconnect; auto-add proxy ARP </font></em><br>
-              &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">firewall log filtering</font></em><br>
+              &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">firewall log filtering; DynDNS server/port; OpenVPN improvements</font></em><br>
               <br>
               Thierry Lechat (<a href="mailto:dev@lechat.org">dev@lechat.org</a>)<br>
               &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">SVG-based traffic grapher</font></em><br>
@@ -126,7 +126,16 @@ require("guiconfig.inc");
               &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">Captive portal logging</font></em><br>
                          <br>
               Enrique Maldonado (<a href="mailto:enrique@directemar.cl">enrique@directemar.cl</a>)<br>
-              &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">IPsec certificate support</font></em></p>
+              &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">IPsec certificate support</font></em><br>
+                         <br>
+              Ken Wiesner (<a href="mailto:ken.wiesner@clearshout.com">ken.wiesner@clearshout.com</a>)<br>
+              &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">Ping source interface selection</font></em><br>
+                         <br>
+              Joe Suhre (<a href="mailto:jsuhre@nullconcepts.com">jsuhre@nullconcepts.com</a>)<br>
+              &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">DNS forwarder domain overriding</font></em><br>
+                         <br>
+              Paul Taylor (<a href="mailto:paultaylor@winndixie.com">paultaylor@winndixie.com</a>)<br>
+              &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">ARP table, Traceroute and Filter state pages</font></em></p>
             <hr size="1">
             <p>m0n0wall is based upon/includes various free software packages, 
               listed below.<br>
index 78fcab2b1459ce414689588ceb9e15916c6248bc..370f5307f898a283036a664f64b85828a0cf4b70 100644 (file)
 */
 $pgtitle = array("Services", "Captive portal");
 require("guiconfig.inc");
-if(isset($_POST['save'])){
-       //value-checking
-       if(trim($_POST['password1'])!="********" && 
-          trim($_POST['password1'])!="" && 
-          trim($_POST['password1'])!=trim($_POST['password2'])){
-               //passwords are to be changed but don't match
-               $input_errors[]="passwords don't match";
-       }
-       if((trim($_POST['password1'])=="" || trim($_POST['password1'])=="********") && 
-          (trim($_POST['password2'])=="" || trim($_POST['password2'])=="********")){
-               //assume password should be left as is if a password is set already.
-               if(!empty($config['users'][$_POST['old_username']]['password'])){
-                       $_POST['password1']="********";
-                       $_POST['password2']="********";
-               } else {
-                       $input_errors[]="password must not be empty";
-               }
-       } else {
-               if(trim($_POST['password1'])!=trim($_POST['password2'])){
-                       //passwords are to be changed or set but don't match
-                       $input_errors[]="passwords don't match";
-               } else {
-                       //check password for invalid characters
-                       if(!preg_match('/^[a-zA-Z0-9_\-\.@\~\(\)\&\*\+§?!\$£°\%;:]*$/',$_POST['username'])){
-                               $input_errors[] = "password contains illegal characters, only  letters from A-Z and a-z, _, -, .,@,~,(,),&,*,+,§,?,!,$,£,°,%,;,: and numbers are allowed";
-                               //test pw: AZaz_-.@~()&*+§?!$£°%;:
-                       }
-               }
-       }
-       if($_POST['username']==""){
-               $input_errors[] = "username must not be empty!";
-       }
-       //check for a valid expirationdate if one is set at all (valid means, strtotime() puts out a time stamp
-       //so any strtotime compatible time format may be used. to keep it simple for the enduser, we only claim 
-       //to accept MM/DD/YYYY as inputs. advanced users may use inputs like "+1 day", which will be converted to 
-       //MM/DD/YYYY based on "now" since otherwhise such an entry would lead to a never expiring expirationdate
-       if(trim($_POST['expirationdate'])!=""){
-               if(strtotime($_POST['expirationdate'])>0){
-                       if(strtotime("-1 day")>strtotime(date("m/d/Y",strtotime($_POST['expirationdate'])))){
-                               $input_errors[] = "selected expiration date lies in the past";                  
-                       } else {
-                               //convert from any strtotime compatible date to MM/DD/YYYY
-                               $expdate = strtotime($_POST['expirationdate']);
-                               $_POST['expirationdate'] = date("m/d/Y",$expdate);
-                       }
-               } else {
-                       $input_errors[] = "invalid expiration date format, use MM/DD/YYYY instead";
-               }
-       }
-       //check username: only allow letters from A-Z and a-z, _, -, . and numbers from 0-9 (note: username can
-       //not contain characters which are not allowed in an xml-token. i.e. if you'd use @ in a username, config.xml
-       //could not be parsed anymore!
-       if(!preg_match('/^[a-zA-Z0-9_\-\.]*$/',$_POST['username'])){
-               $input_errors[] = "username contains illegal characters, only  letters from A-Z and a-z, _, -, . and numbers are allowed";
-       }
-       
-       if(!empty($input_errors)){
-               //there are illegal inputs --> print out error message and show formular again (and fill in all recently entered values
-               //except passwords
-               $_GET['act']="new";
-               $_POST['old_username']=($_POST['old_username'] ? $_POST['old_username'] : $_POST['username']);
-               $_GET['username']=$_POST['old_username'];
-               foreach(Array("username","fullname","expirationdate") as $field){
-                       $config['users'][$_POST['old_username']][$field]=$_POST[$field];
-               }
-       } else {
-               //all values are okay --> saving changes
-               $_POST['username']=trim($_POST['username']);
-               if($_POST['old_username']!="" && $_POST['old_username']!=$_POST['username']){
-                       //change the username (which is used as array-index)
-                       $config['users'][$_POST['username']]=$config['users'][$_POST['old_username']];
-                       unset($config['users'][$_POST['old_username']]);
-               }
-               foreach(Array('fullname','expirationdate') as $field){
-                       $config['users'][$_POST['username']][$field]=trim($_POST[$field]);
-               }
-               if(trim($_POST['password1'])!="********" && trim($_POST['password1'])!=""){
-                       $config['users'][$_POST['username']]['password']=md5(trim($_POST['password1']));
-               }
+
+if (!is_array($config['captiveportal']['user'])) {
+       $config['captiveportal']['user'] = array();
+}
+captiveportal_users_sort();
+$a_user = &$config['captiveportal']['user'];
+
+if ($_GET['act'] == "del") {
+       if ($a_user[$_GET['id']]) {
+               unset($a_user[$_GET['id']]);
                write_config();
-               $savemsg=$_POST['username']." successfully saved<br>";
+               header("Location: services_captiveportal_users.php");
+               exit;
        }
-} else if ($_GET['act']=="delete" && isset($_GET['username'])){
-       unset($config['users'][$_GET['username']]);
-       write_config();
-       $savemsg=$_GET['username']." successfully deleted<br>";
 }
+
 //erase expired accounts
-$changed=false;
-if(is_array($config['users'])){
-       foreach($config['users'] as $username => $user){
-               if(trim($user['expirationdate'])!="" && strtotime("-1 day")>strtotime($user['expirationdate']) && empty($input_errors)){
-                       unset($config['users'][$username]);
-                       $changed=true;
-                       $savemsg.="$username has expired --> $username was deleted<br>";
-               }
-       }
-       if($changed){
-               write_config();
+$changed = false;
+for ($i = 0; $i < count($a_user); $i++) {
+       if ($a_user[$i]['expirationdate'] && (strtotime("-1 day") > strtotime($a_user[$i]['expirationdate']))) {
+               unset($a_user[$i]);
+               $changed = true;
        }
 }
+if ($changed) {
+       write_config();
+       header("Location: services_captiveportal_users.php");
+       exit;
+}
 
 ?>
 <?php include("fbegin.inc"); ?>
-<script language="javascript" type="text/javascript" src="datetimepicker.js">
-//Date Time Picker script- by TengYong Ng of http://www.rainforestnet.com
-//Script featured on JavaScript Kit (http://www.javascriptkit.com)
-//For this script, visit http://www.javascriptkit.com
-</script>
-<?php if ($input_errors) print_input_errors($input_errors); ?>
-<?php if ($savemsg) print_info_box($savemsg); ?>
 <table width="100%" border="0" cellpadding="0" cellspacing="0">
   <tr><td>
   <ul id="tabnav">
@@ -155,54 +76,6 @@ if(is_array($config['users'])){
   </td></tr>
   <tr>
   <td class="tabcont">
-<?php
-if($_GET['act']=="new" || $_GET['act']=="edit"){
-       if($_GET['act']=="edit" && isset($_GET['username'])){
-               $user=$config['users'][$_GET['username']];
-       }
-?>
-       <form action="services_captiveportal_users.php" method="post" name="iform" id="iform">
-              <table width="100%" border="0" cellpadding="6" cellspacing="0">
-                <tr> 
-                  <td width="22%" valign="top" class="vncellreq">Username</td>
-                  <td width="78%" class="vtable"> 
-                    <input name="username" type="text" class="formfld" id="username" size="20" value="<?=$_GET['username'];?>"> 
-                    </td>
-                </tr>
-                <tr> 
-                  <td width="22%" valign="top" class="vncellreq">Password</td>
-                  <td width="78%" class="vtable"> 
-                    <input name="password1" type="password" class="formfld" id="password1" size="20" value="<?php echo ($_GET['act']=='edit' ? "********" : "" ); ?>"> <br>
-                                       <input name="password2" type="password" class="formfld" id="password2" size="20" value="<?php echo ($_GET['act']=='edit' ? "********" : "" ); ?>">
-&nbsp;(confirmation)                                   </td>
-                </tr>
-                <tr> 
-                  <td width="22%" valign="top" class="vncell">Full name</td>
-                  <td width="78%" class="vtable"> 
-                    <input name="fullname" type="text" class="formfld" id="fullname" size="20" value="<?=htmlspecialchars($user['fullname']);?>">
-                    <br>
-                    User's full name, for your own information only</td>
-                </tr>
-                <tr> 
-                  <td width="22%" valign="top" class="vncell">Expiration date</td>
-                  <td width="78%" class="vtable"> 
-                    <input name="expirationdate" type="text" class="formfld" id="expirationdate" size="10" value="<?=$user['expirationdate'];?>">
-                    <a href="javascript:NewCal('expirationdate','mmddyyyy')"><img src="cal.gif" width="16" height="16" border="0" alt="Pick a date"></a> 
-                    <br> 
-                    <span class="vexpl">Leave blank if the account shouldn't expire, otherwise enter the expiration date in the following format: mm/dd/yyyy</span></td>
-                </tr>
-                <tr> 
-                  <td width="22%" valign="top">&nbsp;</td>
-                  <td width="78%"> 
-                    <input name="save" type="submit" class="formbtn" value="Save"> 
-                    <input name="old_username" type="hidden" value="<?=$_GET['username'];?>">
-                  </td>
-                </tr>
-              </table>
-     </form>
-<?php
-} else {
-?>
      <table width="100%" border="0" cellpadding="0" cellspacing="0">
                 <tr>
                   <td width="35%" class="listhdrr">Username</td>
@@ -210,34 +83,27 @@ if($_GET['act']=="new" || $_GET['act']=="edit"){
                   <td width="35%" class="listhdr">Expires</td>
                   <td width="10%" class="list"></td>
                </tr>
-<?php
-       if(is_array($config['users'])){
-               foreach($config['users'] as $username => $user){
-?>
+       <?php $i = 0; foreach($a_user as $userent): ?>
                <tr>
                   <td class="listlr">
-                    <?=$username; ?>&nbsp;
+                    <?=htmlspecialchars($userent['name']); ?>&nbsp;
                   </td>
                   <td class="listr">
-                    <?=htmlspecialchars($user['fullname']);?>&nbsp;
+                    <?=htmlspecialchars($userent['fullname']);?>&nbsp;
                   </td>
                   <td class="listbg">
-                    <?=$user['expirationdate']; ?>&nbsp;
+                    <?=$userent['expirationdate']; ?>&nbsp;
                   </td>
-                  <td valign="middle" nowrap class="list"> <a href="services_captiveportal_users.php?act=edit&username=<?=$username; ?>"><img src="e.gif" title="edit user" width="17" height="17" border="0"></a>
-                     &nbsp;<a href="services_captiveportal_users.php?act=delete&username=<?=$username; ?>" onclick="return confirm('Do you really want to delete this User?')"><img src="x.gif" title="delete user" width="17" height="17" border="0"></a></td>
+                  <td valign="middle" nowrap class="list"> <a href="services_captiveportal_users_edit.php?id=<?=$i; ?>"><img src="e.gif" title="edit user" width="17" height="17" border="0"></a>
+                     &nbsp;<a href="services_captiveportal_users.php?act=del&id=<?=$i; ?>" onclick="return confirm('Do you really want to delete this user?')"><img src="x.gif" title="delete user" width="17" height="17" border="0"></a></td>
                </tr>
-<?php
-               }
-       } ?>
-       <tr> 
+       <?php $i++; endforeach; ?>
+               <tr> 
                          <td class="list" colspan="3"></td>
-                         <td class="list"> <a href="services_captiveportal_users.php?act=new"><img src="plus.gif" title="add user" width="17" height="17" border="0"></a></td>
+                         <td class="list"> <a href="services_captiveportal_users_edit.php"><img src="plus.gif" title="add user" width="17" height="17" border="0"></a></td>
                </tr>
- </table>
-<?php } ?>
-     
-  </td>
-  </tr>
-  </table>
+ </table>     
+</td>
+</tr>
+</table>
 <?php include("fend.inc"); ?>
diff --git a/webgui/services_captiveportal_users_edit.php b/webgui/services_captiveportal_users_edit.php
new file mode 100644 (file)
index 0000000..9607f26
--- /dev/null
@@ -0,0 +1,181 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       services_captiveportal_users_edit.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       Copyright (C) 2005 Pascal Suter <d-monodev@psuter.ch>.
+       All rights reserved. 
+       (files was created by Pascal based on the source code of services_captiveportal.php from Manuel)
+       
+       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", "Edit user");
+require("guiconfig.inc");
+
+if (!is_array($config['captiveportal']['user'])) {
+       $config['captiveportal']['user'] = array();
+}
+captiveportal_users_sort();
+$a_user = &$config['captiveportal']['user'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+       $id = $_POST['id'];
+
+if (isset($id) && $a_user[$id]) {
+       $pconfig['username'] = $a_user[$id]['name'];
+       $pconfig['fullname'] = $a_user[$id]['fullname'];
+       $pconfig['expirationdate'] = $a_user[$id]['expirationdate'];
+}
+
+if ($_POST) {
+       
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       if (isset($id) && ($a_user[$id])) {
+               $reqdfields = explode(" ", "username");
+               $reqdfieldsn = explode(",", "Username");
+       } else {
+               $reqdfields = explode(" ", "username password");
+               $reqdfieldsn = explode(",", "Username,Password");
+       }
+       
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       
+       if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['username']))
+               $input_errors[] = "The username contains invalid characters.";
+               
+       if (($_POST['password']) && ($_POST['password'] != $_POST['password2']))
+               $input_errors[] = "The passwords do not match.";
+
+       //check for a valid expirationdate if one is set at all (valid means, strtotime() puts out a time stamp
+       //so any strtotime compatible time format may be used. to keep it simple for the enduser, we only claim 
+       //to accept MM/DD/YYYY as inputs. advanced users may use inputs like "+1 day", which will be converted to 
+       //MM/DD/YYYY based on "now" since otherwhise such an entry would lead to a never expiring expirationdate
+       if ($_POST['expirationdate']){
+               if(strtotime($_POST['expirationdate']) > 0){
+                       if (strtotime("-1 day") > strtotime(date("m/d/Y",strtotime($_POST['expirationdate'])))){
+                               $input_errors[] = "The expiration date lies in the past.";                      
+                       } else {
+                               //convert from any strtotime compatible date to MM/DD/YYYY
+                               $expdate = strtotime($_POST['expirationdate']);
+                               $_POST['expirationdate'] = date("m/d/Y",$expdate);
+                       }
+               } else {
+                       $input_errors[] = "Invalid expiration date format; use MM/DD/YYYY instead.";
+               }
+       }
+       
+       if (!$input_errors && !(isset($id) && $a_user[$id])) {
+               /* make sure there are no dupes */
+               foreach ($a_user as $userent) {
+                       if ($userent['name'] == $_POST['username']) {
+                               $input_errors[] = "Another entry with the same username already exists.";
+                               break;
+                       }
+               }
+       }
+       
+       if (!$input_errors) {
+       
+               if (isset($id) && $a_user[$id])
+                       $userent = $a_user[$id];
+               
+               $userent['name'] = $_POST['username'];
+               $userent['fullname'] = $_POST['fullname'];
+               $userent['expirationdate'] = $_POST['expirationdate'];
+               
+               if ($_POST['password'])
+                       $userent['password'] = md5($_POST['password']);
+               
+               if (isset($id) && $a_user[$id])
+                       $a_user[$id] = $userent;
+               else
+                       $a_user[] = $userent;
+               
+               write_config();
+               
+               header("Location: services_captiveportal_users.php");
+               exit;
+       }
+}
+
+?>
+<?php include("fbegin.inc"); ?>
+<script language="javascript" type="text/javascript" src="datetimepicker.js">
+<!--
+//Date Time Picker script- by TengYong Ng of http://www.rainforestnet.com
+//Script featured on JavaScript Kit (http://www.javascriptkit.com)
+//For this script, visit http://www.javascriptkit.com
+// -->
+</script>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<form action="services_captiveportal_users_edit.php" method="post" name="iform" id="iform">
+  <table width="100%" border="0" cellpadding="6" cellspacing="0">
+       <tr> 
+         <td width="22%" valign="top" class="vncellreq">Username</td>
+         <td width="78%" class="vtable"> 
+               <?=$mandfldhtml;?><input name="username" type="text" class="formfld" id="username" size="20" value="<?=htmlspecialchars($pconfig['username']);?>"> 
+               </td>
+       </tr>
+       <tr> 
+         <td width="22%" valign="top" class="vncellreq">Password</td>
+         <td width="78%" class="vtable"> 
+               <?=$mandfldhtml;?><input name="password" type="password" class="formfld" id="password" size="20"><br>
+               <?=$mandfldhtml;?><input name="password2" type="password" class="formfld" id="password2" size="20">
+               &nbsp;(confirmation)<?php if (isset($id) && $a_user[$id]): ?><br>
+        <span class="vexpl">If you want to change the users' password, 
+        enter it here twice.</span><?php endif; ?>
+               </td>
+       </tr>
+       <tr> 
+         <td width="22%" valign="top" class="vncell">Full name</td>
+         <td width="78%" class="vtable"> 
+               <input name="fullname" type="text" class="formfld" id="fullname" size="20" value="<?=htmlspecialchars($pconfig['fullname']);?>">
+               <br>
+               <span class="vexpl">User's full name, for your own information only</span></td>
+       </tr>
+       <tr> 
+         <td width="22%" valign="top" class="vncell">Expiration date</td>
+         <td width="78%" class="vtable"> 
+               <input name="expirationdate" type="text" class="formfld" id="expirationdate" size="10" value="<?=$pconfig['expirationdate'];?>">
+               <a href="javascript:NewCal('expirationdate','mmddyyyy')"><img src="cal.gif" width="16" height="16" border="0" alt="Pick a date"></a> 
+               <br> 
+               <span class="vexpl">Leave blank if the account shouldn't expire, otherwise enter the expiration date in the following format: mm/dd/yyyy</span></td>
+       </tr>
+       <tr> 
+         <td width="22%" valign="top">&nbsp;</td>
+         <td width="78%"> 
+               <input name="Submit" type="submit" class="formbtn" value="Save"> 
+               <?php if (isset($id) && $a_user[$id]): ?>
+               <input name="id" type="hidden" value="<?=$id;?>">
+               <?php endif; ?>
+         </td>
+       </tr>
+  </table>
+ </form>
+<?php include("fend.inc"); ?>
index 4f1b60d025bd15ec2a6c130b8fa19c7b0f6a147f..d2b182e3bf023d18bd904f6a82135fac000206a0 100644 (file)
@@ -41,7 +41,7 @@ $iflist = array("lan" => "LAN");
 for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
        $oc = $config['interfaces']['opt' . $i];
        
-       if (isset($oc['enable']) && $oc['if'] && (!$oc['bridge'])) {
+       if (isset($oc['enable']) && $oc['if'] && (!$oc['bridge']) && (!$oc['ovpn'])) {
                $iflist['opt' . $i] = $oc['descr'];
        }
 }
index 337c0edfba49030734dcab7dc24178b0a9d0cbbd..22807d270559b0e5778fc373efb4d5af1a2f0b47 100644 (file)
@@ -62,7 +62,7 @@ $iflist = array("lan" => "LAN");
 for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
        $oc = $config['interfaces']['opt' . $i];
        
-       if (isset($oc['enable']) && $oc['if'] && (!$oc['bridge'])) {
+       if (isset($oc['enable']) && $oc['if'] && (!$oc['bridge']) && (!$oc['ovpn'])) {
                $iflist['opt' . $i] = $oc['descr'];
        }
 }
index 611342d38f2c57410e92cd832c313a9390faed87..b2d4c3ea5433af269fa6f13cdee967a3e270d437 100644 (file)
@@ -38,8 +38,13 @@ $pconfig['regdhcp'] = isset($config['dnsmasq']['regdhcp']);
 if (!is_array($config['dnsmasq']['hosts'])) {
        $config['dnsmasq']['hosts'] = array();
 }
+if (!is_array($config['dnsmasq']['domainoverrides'])) {
+       $config['dnsmasq']['domainoverrides'] = array();
+}
 hosts_sort();
+domainoverrides_sort();
 $a_hosts = &$config['dnsmasq']['hosts'];
+$a_domainOverrides = &$config['dnsmasq']['domainoverrides'];
 
 if ($_POST) {
 
@@ -59,25 +64,36 @@ if ($_POST) {
        $savemsg = get_std_save_message($retval);
 
        if ($retval == 0) {
-               if (file_exists($d_hostsdirty_path))
-                       unlink($d_hostsdirty_path);
+               if (file_exists($d_dnsmasqdirty_path))
+                       unlink($d_dnsmasqdirty_path);
        }
 }
 
 if ($_GET['act'] == "del") {
-       if ($a_hosts[$_GET['id']]) {
-               unset($a_hosts[$_GET['id']]);
-               write_config();
-               touch($d_hostsdirty_path);
-               header("Location: services_dnsmasq.php");
-               exit;
+       if ($_GET['type'] == 'host') {
+               if ($a_hosts[$_GET['id']]) {
+                       unset($a_hosts[$_GET['id']]);
+                       write_config();
+                       touch($d_dnsmasqdirty_path);
+                       header("Location: services_dnsmasq.php");
+                       exit;
+               }
        }
+       elseif ($_GET['type'] == 'doverride') {
+               if ($a_domainOverrides[$_GET['id']]) {
+                       unset($a_domainOverrides[$_GET['id']]);
+                       write_config();
+                       touch($d_dnsmasqdirty_path);
+                       header("Location: services_dnsmasq.php");
+                       exit;
+               }
+       }
 }
 ?>
 <?php include("fbegin.inc"); ?>
 <form action="services_dnsmasq.php" method="post">
 <?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_hostsdirty_path)): ?><p>
+<?php if (file_exists($d_dnsmasqdirty_path)): ?><p>
 <?php print_info_box_np("The DNS forwarder configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
 <input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
 <?php endif; ?>
@@ -143,7 +159,7 @@ if ($_GET['act'] == "del") {
                     <?=htmlspecialchars($hostent['descr']);?>&nbsp;
                   </td>
                   <td valign="middle" nowrap class="list"> <a href="services_dnsmasq_edit.php?id=<?=$i;?>"><img src="e.gif" title="edit host" width="17" height="17" border="0"></a>
-                     &nbsp;<a href="services_dnsmasq.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this host?')"><img src="x.gif" title="delete host" width="17" height="17" border="0"></a></td>
+                     &nbsp;<a href="services_dnsmasq.php?act=del&type=host&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this host?')"><img src="x.gif" title="delete host" width="17" height="17" border="0"></a></td>
                                </tr>
                          <?php $i++; endforeach; ?>
                 <tr> 
@@ -151,5 +167,38 @@ if ($_GET['act'] == "del") {
                   <td class="list"> <a href="services_dnsmasq_edit.php"><img src="plus.gif" title="add host" width="17" height="17" border="0"></a></td>
                                </tr>
               </table>
+                         <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td><p>Below you can override an entire domain by specifying an
+                         authoritative DNS server to be queried for that domain.</p></td>
+                </tr>
+              </table>
+              <table width="100%" border="0" cellpadding="0" cellspacing="0">
+                <tr>
+                  <td width="35%" class="listhdrr">Domain</td>
+                  <td width="20%" class="listhdrr">IP</td>
+                  <td width="35%" class="listhdr">Description</td>
+                  <td width="10%" class="list"></td>
+                               </tr>
+                         <?php $i = 0; foreach ($a_domainOverrides as $doment): ?>
+                <tr>
+                  <td class="listlr">
+                    <?=strtolower($doment['domain']);?>&nbsp;
+                  </td>
+                  <td class="listr">
+                    <?=$doment['ip'];?>&nbsp;
+                  </td>
+                  <td class="listbg">
+                    <?=htmlspecialchars($doment['descr']);?>&nbsp;
+                  </td>
+                  <td valign="middle" nowrap class="list"> <a href="services_dnsmasq_domainoverride_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+                     &nbsp;<a href="services_dnsmasq.php?act=del&type=doverride&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this domain override?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+                         <?php $i++; endforeach; ?>
+                <tr> 
+                  <td class="list" colspan="3"></td>
+                  <td class="list"> <a href="services_dnsmasq_domainoverride_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+                         </table>
             </form>
 <?php include("fend.inc"); ?>
diff --git a/webgui/services_dnsmasq_domainoverride_edit.php b/webgui/services_dnsmasq_domainoverride_edit.php
new file mode 100644 (file)
index 0000000..2fff172
--- /dev/null
@@ -0,0 +1,136 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       services_dnsmasq_domainoverride_edit.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2005 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.
+*/
+
+$pgtitle = array("Services", "DNS forwarder", "Edit Domain Override");
+require("guiconfig.inc");
+
+if (!is_array($config['dnsmasq']['domainoverrides'])) {
+       $config['dnsmasq']['domainoverrides'] = array();
+}
+domainoverrides_sort();
+$a_domainOverrides = &$config['dnsmasq']['domainoverrides'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+       $id = $_POST['id'];
+
+if (isset($id) && $a_domainOverrides[$id]) {
+       $pconfig['domain'] = $a_domainOverrides[$id]['domain'];
+       $pconfig['ip'] = $a_domainOverrides[$id]['ip'];
+       $pconfig['descr'] = $a_domainOverrides[$id]['descr'];
+}
+
+if ($_POST) {
+
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       $reqdfields = explode(" ", "domain ip");
+       $reqdfieldsn = explode(",", "Domain,IP address");
+       
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       
+       if (($_POST['domain'] && !is_domain($_POST['domain']))) {
+               $input_errors[] = "A valid domain must be specified.";
+       }
+       if (($_POST['ip'] && !is_ipaddr($_POST['ip']))) {
+               $input_errors[] = "A valid IP address must be specified.";
+       }
+
+       /* check for overlaps */
+       foreach ($a_domainOverrides as $doment) {
+               if (isset($id) && ($a_domainOverrides[$id]) && ($a_domainOverrides[$id] === $doment))
+                       continue;
+
+               if (($doment['host'] == $_POST['host']) && ($doment['domain'] == $_POST['domain'])) {
+                       $input_errors[] = "An override already exists for this domain.";
+                       break;
+               }
+       }
+
+       if (!$input_errors) {
+               $doment = array();
+               $doment['domain'] = $_POST['domain'];
+               $doment['ip'] = $_POST['ip'];
+               $doment['descr'] = $_POST['descr'];
+
+               if (isset($id) && $a_domainOverrides[$id])
+                       $a_domainOverrides[$id] = $doment;
+               else
+                       $a_domainOverrides[] = $doment;
+               
+               touch($d_dnsmasqdirty_path);
+               
+               write_config();
+               
+               header("Location: services_dnsmasq.php");
+               exit;
+       }
+}
+?>
+<?php include("fbegin.inc"); ?>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+            <form action="services_dnsmasq_domainoverride_edit.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                               <tr>
+                  <td width="22%" valign="top" class="vncellreq">Domain</td>
+                  <td width="78%" class="vtable"> 
+                    <?=$mandfldhtml;?><input name="domain" type="text" class="formfld" id="domain" size="40" value="<?=htmlspecialchars($pconfig['domain']);?>">
+                    <br> <span class="vexpl">Domain to override (note: this does not have to be a valid TLD)<br>
+                    e.g. <em>test</em></span></td>
+                </tr>
+                               <tr>
+                  <td width="22%" valign="top" class="vncellreq">IP address</td>
+                  <td width="78%" class="vtable"> 
+                    <?=$mandfldhtml;?><input name="ip" type="text" class="formfld" id="ip" size="40" value="<?=htmlspecialchars($pconfig['ip']);?>">
+                    <br><span class="vexpl">IP address of the authoritative DNS server for this domain
+                    </span></td>
+                </tr>
+                               <tr>
+                  <td width="22%" valign="top" class="vncell">Description</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+                    <br> <span class="vexpl">You may enter a description here
+                    for your reference (not parsed).</span></td>
+                </tr>
+                <tr>
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Save">
+                    <?php if (isset($id) && $a_domainOverrides[$id]): ?>
+                    <input name="id" type="hidden" value="<?=$id;?>">
+                    <?php endif; ?>
+                  </td>
+                </tr>
+              </table>
+</form>
+<?php include("fend.inc"); ?>
index 6701555eda03da4fd3a3bc864b044e3424439040..878ba8b7f95fb82346477301452b436239d5983d 100644 (file)
@@ -93,7 +93,7 @@ if ($_POST) {
                else
                        $a_hosts[] = $hostent;
                
-               touch($d_hostsdirty_path);
+               touch($d_dnsmasqdirty_path);
                
                write_config();
                
index 0ee1af7ee4ec5bcfceb8d1348a18c0d55326f6d8..e7cf037fa9c97635cc46a2e1c642bf22265bf8f7 100644 (file)
@@ -39,6 +39,8 @@ if (!is_array($config['dnsupdate'])) {
 $pconfig['username'] = $config['dyndns']['username'];
 $pconfig['password'] = $config['dyndns']['password'];
 $pconfig['host'] = $config['dyndns']['host'];
+$pconfig['server'] = $config['dyndns']['server'];
+$pconfig['port'] = $config['dyndns']['port'];
 $pconfig['mx'] = $config['dyndns']['mx'];
 $pconfig['type'] = $config['dyndns']['type'];
 $pconfig['enable'] = isset($config['dyndns']['enable']);
@@ -74,6 +76,12 @@ if ($_POST) {
        if (($_POST['host'] && !is_domain($_POST['host']))) {
                $input_errors[] = "The host name contains invalid characters.";
        }
+       if (($_POST['server'] && !is_domain($_POST['server']) && !is_ipaddr($_POST['server']))) {
+               $input_errors[] = "The server name contains invalid characters.";
+       }
+       if (($_POST['port'] && !is_port($_POST['port']))) {
+               $input_errors[] = "The server port must be an integer between 1 and 65535.";
+       }
        if (($_POST['mx'] && !is_domain($_POST['mx']))) {
                $input_errors[] = "The MX contains invalid characters.";
        }
@@ -96,6 +104,8 @@ if ($_POST) {
                $config['dyndns']['username'] = $_POST['username'];
                $config['dyndns']['password'] = $_POST['password'];
                $config['dyndns']['host'] = $_POST['host'];
+               $config['dyndns']['server'] = $_POST['server'];
+               $config['dyndns']['port'] = $_POST['port'];
                $config['dyndns']['mx'] = $_POST['mx'];
                $config['dyndns']['wildcard'] = $_POST['wildcard'] ? true : false;
                $config['dyndns']['enable'] = $_POST['enable'] ? true : false;
@@ -130,6 +140,8 @@ function enable_change(enable_change) {
        
        endis = !(document.iform.enable.checked || enable_change);
        document.iform.host.disabled = endis;
+       document.iform.server.disabled = endis;
+       document.iform.port.disabled = endis;
        document.iform.mx.disabled = endis;
        document.iform.type.disabled = endis;
        document.iform.wildcard.disabled = endis;
@@ -175,6 +187,19 @@ function enable_change(enable_change) {
                     <?=$mandfldhtml;?><input name="host" type="text" class="formfld" id="host" size="30" value="<?=htmlspecialchars($pconfig['host']);?>"> 
                   </td>
                                </tr>
+                 <tr> 
+                  <td width="22%" valign="top" class="vncell">Server</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="server" type="text" class="formfld" id="server" size="30" value="<?=htmlspecialchars($pconfig['server']);?>">
+                    <br>Special server to connect to. This can usually be left blank.</td>
+                               </tr>
+                <tr> 
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Port</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="port" type="text" class="formfld" id="port" size="5" value="<?=htmlspecialchars($pconfig['port']);?>">
+                    <br>Special server port to connect to. This can usually be left blank.</td>
+                               </tr>
                 <tr> 
                   <td width="22%" valign="top" class="vncell">MX</td>
                   <td width="78%" class="vtable"> 
index 09ceaeecd5aa671817b00763bf7ac06f63ae4873..033e2e1918ee23d9e9b34ac39a85b9a3ca7a1853 100644 (file)
@@ -168,7 +168,8 @@ function typesel_change() {
                                        <select name="interface" class="formfld">
                       <?php $interfaces = array('wan' => 'WAN', 'lan' => 'LAN');
                                          for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
-                                               $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
+                                               if (!isset($config['interfaces']['opt' . $i]['ovpn']))
+                                                       $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
                                          }
                                          foreach ($interfaces as $iface => $ifacename): ?>
                       <option value="<?=$iface;?>" <?php if ($iface == $pconfig['interface']) echo "selected"; ?>> 
index abcb16ac708d9bb05258a25cc252dc57556efbc9..ce0d735adf917db8311b9b51f1c3ba67d1ac8481 100644 (file)
@@ -88,7 +88,8 @@ if ($_GET['act'] == "del") {
                       <?php $interfaces = array('lan' => 'LAN');
                                          for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
                                            if (isset($config['interfaces']['opt' . $i]['enable']) &&
-                                                       !$config['interfaces']['opt' . $i]['bridge'])
+                                                       !$config['interfaces']['opt' . $i]['bridge'] &&
+                                                       !$config['interfaces']['opt' . $i]['ovpn'])
                                                        $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
                                          }
                                          foreach ($interfaces as $iface => $ifacename): ?>
index 3e25b04be7c6854daf39099ba3a6041602d8ce0b..99e17f05cceba034da5bc7dba99f55eb341da2a0 100644 (file)
@@ -94,7 +94,8 @@ if ($_POST) {
                       <?php $interfaces = array('lan' => 'LAN');
                                          for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
                                            if (isset($config['interfaces']['opt' . $i]['enable']) &&
-                                                       !$config['interfaces']['opt' . $i]['bridge'])
+                                                       !$config['interfaces']['opt' . $i]['bridge'] &&
+                                                       !$config['interfaces']['opt' . $i]['ovpn'])
                                                        $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
                                          }
                                          foreach ($interfaces as $iface => $ifacename): ?>
index 9ad8f98402a037ef9b1d7f721e765b92a45e6807..d160acc11fb76240fc5d35e2b5847b9bbe8422b0 100644 (file)
@@ -30,6 +30,8 @@ function doCmdT($title, $command, $isstr) {
                                        /* remove password tag contents */
                                        $line = preg_replace("/<password>.*?<\\/password>/", "<password>xxxxx</password>", $line);
                                        $line = preg_replace("/<pre-shared-key>.*?<\\/pre-shared-key>/", "<pre-shared-key>xxxxx</pre-shared-key>", $line);
+                                       $line = preg_replace("/<srv_key>.*?<\\/srv_key>/", "<srv_key>xxxxx</srv_key>", $line);
+                                       $line = preg_replace("/<cli_key>.*?<\\/cli_key>/", "<cli_key>xxxxx</cli_key>", $line);
                                        $line = str_replace("\t", "    ", $line);
                                        echo htmlspecialchars($line,ENT_NOQUOTES);
                                }
index 7c8ffc9f3f3402ea6df044437b0008ba58405579..138d6fa1a4ebef9b1a0959705e2a53dd2d48403d 100644 (file)
@@ -72,7 +72,7 @@ function get_interface_info($ifdescr) {
        unset($linkinfo);
        exec("/usr/bin/netstat -I " . $ifinfo['hwif'] . " -nWb -f link", $linkinfo);
        $linkinfo = preg_split("/\s+/", $linkinfo[1]);
-       if (preg_match("/\*$/", $linkinfo[0])) {
+       if (preg_match("/\*$/", $linkinfo[0]) || preg_match("/^$/", $linkinfo[0])) {
                $ifinfo['status'] = "down";
        } else {
                $ifinfo['status'] = "up";
diff --git a/webgui/status_ovpn.php b/webgui/status_ovpn.php
new file mode 100644 (file)
index 0000000..deebdb5
--- /dev/null
@@ -0,0 +1,120 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       status_ovpn.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>.
+       Copyright (C) 2005 Peter Allgeyer <allgeyer@web.de>.
+       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("Status", "OpenVPN");
+require("guiconfig.inc");
+
+$client_list = array();
+$virtip_list = array();
+
+function dump_log($type) {
+       global $g, $config;
+
+       unset($client_list);
+       $client_list = array();
+
+       unset($virtip_list);
+       $virtip_list = array();
+                       
+       $max = ($type == 'tun') ? 17 : 4;
+       for ($i = 0; $i < $max; $i++) {
+               if (file_exists("/var/log/openvpn_{$type}{$i}.log")) {
+
+                       unset($string);
+                       unset($logarr);
+                       
+                       exec("/bin/cat /var/log/openvpn_{$type}{$i}.log", $logarr);
+       
+                       foreach ($logarr as $logent) {
+                               $logent = preg_split("/,/", $logent, 5);
+                               $string = preg_split("/:/", $logent[1]);
+
+                               /* search for ip address in second column */
+                               if (isset($string[0]) && is_ipaddr($string[0]))
+                                       array_push($client_list, $logent);
+                               
+                               /* search for ip address in first column */
+                               else if (is_ipaddr($logent[0]))
+                                       array_push($virtip_list, $logent);
+                       }
+               }
+       }
+
+       if (count($client_list > 1)) {
+               foreach ($client_list as $cent) {
+                       echo "<tr>\n";
+                       echo "<td class=\"listlr\" nowrap>" . htmlspecialchars($cent[0]) . "</td>\n";
+                       echo "<td class=\"listr\">" . htmlspecialchars($cent[1]) . "</td>\n";
+
+                       unset($found);
+                       if (isset($virtip_list)) {
+                               foreach ($virtip_list as $vent) {
+                                       if ($cent[1] == $vent[2]) {
+                                               $found = 1;
+                                               echo "<td class=\"listr\">" . htmlspecialchars($vent[0]) . "&nbsp;</td>\n";
+                                       }
+                               }
+                       }
+                       if (!isset($found))
+                               echo "<td class=\"listr\" align=\"center\">--</td>\n";
+                               
+                       $date = preg_split("/\s+/", $cent[4]);
+                       echo "<td class=\"listr\">" . htmlspecialchars($date[1]) . " " . htmlspecialchars($date[2]) . " " . htmlspecialchars($date[3]) . "</td>\n";
+                       echo "<td class=\"listr\">" . htmlspecialchars($cent[2]) . "</td>\n";
+                       echo "<td class=\"listr\">" . htmlspecialchars($cent[3]) . "</td>\n";
+                       echo "</tr>\n";
+               }
+       }
+}
+
+?>
+<?php include("fbegin.inc"); ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0"><tr>
+  <td colspan="6" class="listtopic"> 
+           OpenVPN status entries</td>
+       </tr>
+        <tr>
+         <td class="listhdrr">Common Name</td>
+         <td class="listhdrr">Real Address</td>
+         <td class="listhdrr">Virtual Address</td>
+         <td class="listhdrr">Connected Since</td>
+         <td class="listhdrr">Bytes Received</td>
+         <td class="listhdr">Bytes Sent</td>
+       </tr>
+       <?php dump_log(tun); ?>
+       <?php dump_log(tap); ?>
+</table>
+<br>
+<strong class="red">Note:<br>
+</strong>Please note that status entries are updated once every minute only.
+So don't bother about entries on this page being possibly too old!
+<?php include("fend.inc"); ?>
index 8b791dc000980fea01ec4080e877fd520374caa0..e6083a99cd08039ca28fa46ae9f9361f85862861 100644 (file)
@@ -47,6 +47,7 @@ $pconfig['noantilockout'] = isset($config['system']['webgui']['noantilockout']);
 $pconfig['tcpidletimeout'] = $config['filter']['tcpidletimeout'];
 $pconfig['preferoldsa_enable'] = isset($config['ipsec']['preferoldsa']);
 $pconfig['polling_enable'] = isset($config['system']['polling']);
+$pconfig['ipfstatentries'] = $config['diag']['ipfstatentries'];
 
 if ($_POST) {
 
@@ -60,6 +61,9 @@ if ($_POST) {
        if ($_POST['tcpidletimeout'] && !is_numericint($_POST['tcpidletimeout'])) {
                $input_errors[] = "The TCP idle timeout must be an integer.";
        }
+       if ($_POST['ipfstatentries'] && !is_numericint($_POST['ipfstatentries'])) {
+               $input_errors[] = "The 'firewall states displayed' value must be an integer.";
+       }
        if (($_POST['cert'] && !$_POST['key']) || ($_POST['key'] && !$_POST['cert'])) {
                $input_errors[] = "Certificate and key must always be specified together.";
        } else if ($_POST['cert'] && $_POST['key']) {
@@ -90,7 +94,11 @@ if ($_POST) {
                $oldpreferoldsa = $config['ipsec']['preferoldsa'];
                $config['ipsec']['preferoldsa'] = $_POST['preferoldsa_enable'] ? true : false;
                $config['system']['polling'] = $_POST['polling_enable'] ? true : false;
-                       
+               if (!$_POST['ipfstatentries'])
+                       unset($config['diag']['ipfstatentries']);
+               else
+                       $config['diag']['ipfstatentries'] = $_POST['ipfstatentries'];   
+               
                write_config();
                
                if (($config['system']['webgui']['certificate'] != $oldcert)
@@ -115,6 +123,7 @@ if ($_POST) {
                        if ($config['ipsec']['preferoldsa'] != $oldpreferoldsa)
                                $retval |= vpn_ipsec_configure();
                        $retval |= system_polling_configure();
+                       $retval |= system_set_termcap();
                        config_unlock();
                }
                $savemsg = get_std_save_message($retval);
@@ -292,6 +301,15 @@ function enable_change(enable_over) {
                                        per second). Not all NICs support polling; see the m0n0wall homepage for a list of supported cards.
                                        </td>
                 </tr>
+                               <tr>
+                  <td valign="top" class="vncell">Firewall states displayed</td>
+                  <td class="vtable">
+                    <input name="ipfstatentries" type="text" class="formfld" id="ipfstatentries" size="8" value="<?=htmlspecialchars($pconfig['ipfstatentries']);?>">
+                    entries<br>
+                               <span class="vexpl">Maxmimum number of firewall state entries to be displayed on the <a href="diag_ipfstat.php">Diagnostics: Firewall state</a> page.
+                               Default is 300. Setting this to a very high value will cause a slowdown when viewing the
+                               firewall states page, depending on your system's processing power.</span></td>
+                           </tr>
                 <tr> 
                   <td width="22%" valign="top">&nbsp;</td>
                   <td width="78%"> 
@@ -300,7 +318,7 @@ function enable_change(enable_over) {
                 </tr>
               </table>
 </form>
-            <script language="JavaScript">
+<script language="JavaScript">
 <!--
 enable_change(false);
 //-->
index 3bd98bdc9fe30ac3c5925eb19ee88bb4b96f754e..e61df9e371aa1702b5f37bf39342fb61fdea1a37 100644 (file)
@@ -328,7 +328,8 @@ function methodsel_change() {
                   <td width="78%" class="vtable"><select name="interface" class="formfld">
                       <?php $interfaces = array('wan' => 'WAN', 'lan' => 'LAN');
                                          for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
-                                               $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
+                                               if (!$config['interfaces']['opt' . $i]['ovpn'])
+                                                       $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
                                          }
                                          foreach ($interfaces as $iface => $ifacename): ?>
                       <option value="<?=$iface;?>" <?php if ($iface == $pconfig['interface']) echo "selected"; ?>> 
diff --git a/webgui/vpn_openvpn.php b/webgui/vpn_openvpn.php
deleted file mode 100644 (file)
index 46f8953..0000000
+++ /dev/null
@@ -1,355 +0,0 @@
-#!/usr/local/bin/php
-<?php 
-/*
-       vpn_openvpn.php
-
-       Copyright (C) 2004 Peter Curran (peter@closeconsultants.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("VPN", "OpenVPN");
-require("guiconfig.inc");
-require_once("openvpn.inc");
-
-if (!is_array($config['ovpn']))
-       $config['ovpn'] = array();
-if (!is_array($config['ovpn']['server'])){
-       $config['ovpn']['server'] =  array();
-       $config['ovpn']['server']['tun_iface'] = "tun0";
-       $config['ovpn']['server']['psh_options'] = array();
-       /* Initialise with some sensible defaults */
-       $config['ovpn']['server']['port'] = 5000;
-       $config['ovpn']['server']['proto'] = 'UDP';
-       $config['ovpn']['server']['maxcli'] = 25;
-       $config['ovpn']['server']['crypto'] = 'BF-CBC';
-       $config['ovpn']['server']['dupcn'] = true;
-       $config['ovpn']['server']['verb'] = 1;
-}
-
-if ($_POST) {
-
-       unset($input_errors);
-
-       /* input validation */
-       if ($_POST['enable']) {
-               $reqdfields = explode(" ", "tun_iface bind_iface ipblock");
-               $reqdfieldsn = explode(",", "Tunnel type,Interface binding,IP address block start");
-
-               do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
-
-       }
-       
-       /* need a test here to make sure prefix and max_clients are coherent */
-       
-       /* Sort out the cert+key files */
-       if (is_null($_POST['ca_cert']))
-               $input_errors[] = "You must provide a CA certificate file";
-       elseif (!strstr($_POST['ca_cert'], "BEGIN CERTIFICATE") || !strstr($_POST['ca_cert'], "END CERTIFICATE"))
-               $input_errors[] = "The CA certificate does not appear to be valid.";
-               
-       if (is_null($_POST['srv_cert']))
-               $input_errors[] = "You must provide a server certificate file";
-       elseif (!strstr($_POST['srv_cert'], "BEGIN CERTIFICATE") || !strstr($_POST['srv_cert'], "END CERTIFICATE"))
-               $input_errors[] = "The server certificate does not appear to be valid.";
-               
-       if (is_null($_POST['srv_key']))
-               $input_errors[] = "You must provide a server key file";
-       elseif (!strstr($_POST['srv_key'], "BEGIN RSA PRIVATE KEY") || !strstr($_POST['srv_key'], "END RSA PRIVATE KEY"))
-               $input_errors[] = "The server key does not appear to be valid.";
-               
-       if (is_null($_POST['dh_param']))
-               $input_errors[] = "You must provide a DH parameters file";
-       elseif (!strstr($_POST['dh_param'], "BEGIN DH PARAMETERS") || !strstr($_POST['dh_param'], "END DH PARAMETERS"))
-               $input_errors[] = "The DH parameters do not appear to be valid.";
-                               
-       if (!$input_errors) {
-               $server =& $config['ovpn']['server'];
-               $server['enable'] = $_POST['enable'] ? true : false;
-               
-               /* Make sure that the tunnel interface type has not changed */
-               if ($server['tun_iface'] != $_POST['tun_iface']){ 
-                       $server['tun_iface'] = $_POST['tun_iface'];
-                       touch($d_sysrebootreqd_path);
-               }
-               
-               $server['bind_iface'] = $_POST['bind_iface'];
-               $server['port'] = $_POST['port'];
-               $server['proto'] = $_POST['proto'];
-               
-               /* Make sure the IP address and/or prefix have not changed */
-               if ($server['ipblock'] != $_POST['ipblock']){
-                       $server['ipblock'] = $_POST['ipblock'];
-                       touch($d_sysrebootreqd_path);
-               }
-               if ($server['prefix'] != $_POST['prefix']){
-                       $server['prefix'] = $_POST['prefix'];
-                       touch($d_sysrebootreqd_path);
-               }
-               
-               $server['maxcli'] = $_POST['maxcli'];
-               $server['crypto'] = $_POST['crypto'];
-               $server['cli2cli'] = $_POST['cli2cli'] ? true : false;
-               $server['dupcn'] = $_POST['dupcn'] ? true : false;
-               $server['psh_options']['redir'] = $_POST['psh_redir'] ? true : false;
-               $server['psh_options']['redir_loc'] = $_POST['psh_redir_loc'] ? true : false;
-               if ($_POST['psh_rtedelay'])
-                       $server['psh_options']['rtedelay'] = $_POST['psh_rtedelay_int'];
-               if ($_POST['psh_ping'])
-                       $server['psh_options']['ping'] = $_POST['psh_ping_int'];
-               if ($_POST['psh_pingexit'])
-                       $server['psh_options']['pingexit'] = $_POST['psh_pingexit_int'];
-               if ($_POST['psh_pingrst'])
-                       $server['psh_options']['pingrst'] = $_POST['psh_pingrst_int'];
-               if ($_POST['inact'])
-                       $server['psh_options']['inact'] = $_POST['psh_inact_int'];
-               $server['ca_cert'] = base64_encode($_POST['ca_cert']);
-               $server['srv_cert'] = base64_encode($_POST['srv_cert']);
-               $server['srv_key'] = base64_encode($_POST['srv_key']);
-               $server['dh_param'] = base64_encode($_POST['dh_param']);        
-                       
-               write_config();
-
-               $retval = 0;
-               if (file_exists($d_sysrebootreqd_path)) {
-                       /* Rewrite interface definitions */
-                       $retval = ovpn_server_iface();
-               }
-               else{
-                       ovpn_lock();
-                       $retval = ovpn_config_server();
-                       ovpn_unlock();
-               }
-               $savemsg = get_std_save_message($retval);
-       }
-}
-
-/* Simply take a copy of the array */
-$pconfig = $config['ovpn']['server'];
-
-?>
-<?php include("fbegin.inc"); ?>
-<?php if ($input_errors) print_input_errors($input_errors); ?>
-<?php if (file_exists($d_sysrebootreqd_path)) print_info_box(get_std_save_message(0)); ?>
-
-<form action="vpn_openvpn.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
-<table width="100%" border="0" cellpadding="0" cellspacing="0">
-  <tr><td>
-  <ul id="tabnav">             
-       <li class="tabact">Server</li>
-       <li class="tabinact"><a href="vpn_openvpn_cli.php">Client</a></li>
-  </ul>
-  </td></tr>
-  <tr>
-  <td class="tabcont">
-    <strong><span class="red">WARNING: This feature is experimental and modifies your optional interface configuration.
-  Backup your configuration before using OpenVPN, and restore it before upgrading.<br>
-&nbsp;  <br>
-    </span></strong><table width="100%" border="0" cellpadding="6" cellspacing="0">
-  <tr>
-    <td width="22%" valign="top" class="vtable">&nbsp;</td>
-    <td width="78%" class="vtable">
-      <input name="enable" type="checkbox" value="yes" <?php if (isset($pconfig['enable'])) echo "checked"; ?>>
-      <strong>Enable OpenVPN server </strong></td>
-   </tr>
-   
-   <tr>
-     <td width="22%" valign="top" class="vncellreq">Tunnel type</td>
-     <td width="78%" class="vtable">
-       <input type="radio" name="tun_iface" class="formfld" value="tun0" <?php if ($pconfig['tun_iface'] == 'tun0') echo "checked"; ?>>
-          TUN&nbsp;
-       <input type="radio" name="tun_iface" class="formfld" value="tap0" <?php if ($pconfig['tun_iface'] == 'tap0') echo "checked"; ?>>
-          TAP
-      </td>
-    </tr>
-    
-    <tr>
-      <td width="22%" valign="top" class="vncell">OpenVPN protocol/port</td>
-      <td width="78%" class="vtable">
-       <input type="radio" name="proto" class="formfld" value="UDP" <?php if ($pconfig['proto'] == 'UDP') echo "checked"; ?>>
-           UDP&nbsp;
-        <input type="radio" name="proto" class="formfld" value="TCP" <?php if ($pconfig['proto'] == 'TCP') echo "checked"; ?>>
-           TCP<br><br>
-        Port: 
-        <input name="port" type="text" class="formfld" size="5" maxlength="5" value="<?= $pconfig['port']; ?>"><br>
-        Enter the port number to use for the server (default is 5000).</td>
-    </tr>
-    
-    <tr>
-      <td width="22%" valign="top" class="vncellreq">Interface binding</td>
-      <td width="78%" class="vtable">
-       <select name="bind_iface" class="formfld">
-        <?php 
-       $interfaces = ovpn_real_interface_list();
-       foreach ($interfaces as $key => $iface):
-        ?>
-       <option value="<?=$key;?>" <?php if ($key == $pconfig['bind_iface']) echo "selected"; ?>> <?= $iface;?>
-        </option>
-        <?php endforeach;?>
-        </select>
-        <span class="vexpl"><br>
-        Choose an interface for the OpenVPN server to listen on.</span></td>
-    </tr>
-               
-    <tr> 
-      <td width="22%" valign="top" class="vncellreq">IP address block</td>
-      <td width="78%" class="vtable"> 
-        <input name="ipblock" type="text" class="formfld" size="20" value="<?=htmlspecialchars($pconfig['ipblock']);?>">
-        / 
-        <select name="prefix" class="formfld">
-          <?php for ($i = 29; $i > 19; $i--): ?>
-          <option value="<?=$i;?>" <?php if ($i == $pconfig['prefix']) echo "selected"; ?>>
-            <?=$i;?>
-          </option>
-          <?php endfor; ?>
-        </select>
-        <br>
-        Enter the IP address block for the OpenVPN server and clients to use.<br>
-        <br>
-       Maximum number of simultaneous clients: 
-       <input name="maxcli" type="text" class="formfld" size="3" maxlength="3" value="<?=htmlspecialchars($pconfig['maxcli']);?>">
-       </td>
-    </tr>
-    
-    <tr> 
-      <td width="22%" valign="top" class="vncellreq">CA certificate</td>
-      <td width="78%" class="vtable"> 
-      <textarea name="ca_cert" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['ca_cert']));?></textarea>
-      <br>
-      Paste a CA certificate in X.509 PEM format here.</td>
-    </tr>
-               
-    <tr> 
-      <td width="22%" valign="top" class="vncellreq">Server certificate</td>
-      <td width="78%" class="vtable">
-        <textarea name="srv_cert" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['srv_cert']));?></textarea>
-        <br>
-        Paste a server certificate in X.509 PEM format here.</td>
-     </tr>
-     
-     <tr> 
-       <td width="22%" valign="top" class="vncellreq">Server key</td>
-       <td width="78%" class="vtable"> 
-         <textarea name="srv_key" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['srv_key']));?></textarea>
-         <br>Paste the server RSA private key here.</td>
-      </tr>
-      
-      <tr> 
-        <td width="22%" valign="top" class="vncellreq">DH parameters</td>
-        <td width="78%" class="vtable"> 
-         <textarea name="dh_param" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['dh_param']));?></textarea>
-          <br>          
-          Paste the Diffie-Hellman parameters in PEM format here.</td>
-      </tr>
-      
-      <tr>
-        <td width="22%" valign="top" class="vncell">Crypto</td>
-        <td width="78%" class="vtable">
-          <select name="crypto" class="formfld">
-           <?php $cipher_list = ovpn_get_cipher_list();
-           foreach($cipher_list as $key => $value){
-           ?>
-             <option value="<?= $key ?>" <?php if ($pconfig['crypto'] == $key) echo "selected"; ?>>
-               <?= $value ?>
-             </option>
-           <?php
-           }
-           ?>
-         </select>
-         <br>
-         Select a data channel encryption cipher.</td>
-      </tr>
-      
-      <tr>
-        <td width="22%" valign="top" class="vncell">Internal routing mode</td>
-        <td width="78%" class="vtable">
-         <input name="cli2cli" type="checkbox" value="yes" <?php if (isset($pconfig['cli2cli'])) echo "checked"; ?>>
-          <strong>Enable client-to-client routing</strong><br>
-          If this option is on,  clients are allowed to talk to each other.</td>
-      </tr>
-      
-      <tr>
-        <td width="22%" valign="top" class="vncell">Client authentication</td>
-        <td width="78%" class="vtable">
-         <input name="dupcn" type="checkbox" value="yes" <?php if (isset($pconfig['dupcn'])) echo "checked"; ?>>
-          <strong>Permit duplicate client certificates</strong><br>
-         If this option is on, clients with duplicate certificates will not be disconnected.</td>
-      </tr>
-        
-      <tr>
-        <td width="22%" valign="top" class="vncell">Client-push options</td>
-        <td width="78%" class="vtable">
-             <table border="0" cellspacing="0" cellpadding="0">
-               <tr>
-              <td><input type="checkbox" name="psh_redir" value="yes" <?php if (isset($pconfig['psh_options']['redir'])) echo "checked"; ?>>
-              Redirect-gateway</td>
-              <td>&nbsp;</td>
-              <td><input type="checkbox" name="psh_redir_loc" value="yes" <?php if (isset($pconfig['psh_options']['redir_loc'])) echo "checked"; ?>>
-                Local</td>
-                 </tr>
-            <tr>
-              <td><input type="checkbox" name="psh_rtedelay" value="yes" <?php if (isset($pconfig['psh_options']['rtedelay'])) echo "checked"; ?>> Route-delay</td>
-              <td width="16">&nbsp;</td>
-              <td><input type="text" name="psh_rtedelay_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['rtedelay']?>"> seconds</td>
-            </tr>
-            <tr>
-              <td><input type="checkbox" name="psh_inact" value="yes" <?php if (isset($pconfig['psh_options']['inact'])) echo "checked"; ?>>
-    Inactive</td>
-              <td>&nbsp;</td>
-              <td><input type="text" name="psh_inact_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['inact']?>">
-    seconds</td>
-            </tr>
-            <tr>
-              <td><input type="checkbox" name="psh_ping" value="yes" <?php if (isset($pconfig['psh_options']['ping'])) echo "checked"; ?>> Ping</td>
-              <td>&nbsp;</td>
-              <td>Interval: <input type="text" name="psh_ping_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['ping']?>"> seconds</td>
-            </tr>
-            <tr>
-              <td><input type="checkbox" name="psh_pingexit" value="yes" <?php if (isset($pconfig['psh_options']['pingexit'])) echo "checked"; ?>> Ping-exit</td>
-              <td>&nbsp;</td>
-              <td>Interval: <input type="text" name="psh_pingexit_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['pingexit']?>"> seconds</td>
-            </tr>
-            <tr>
-              <td><input type="checkbox" name="psh_pingrst" value="yes" <?php if (isset($pconfig['psh_options']['pingrst'])) echo "checked"; ?>> Ping-restart</td>
-              <td>&nbsp;</td>
-              <td>Interval: <input type="text" name="psh_pingrst_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['pingrst']?>"> seconds</td>
-            </tr>
-          </table></td>
-      </tr>
-      <tr>
-        <td width="22%" valign="top">&nbsp;</td>
-        <td width="78%">
-          <input name="Submit" type="submit" class="formbtn" value="Save">
-        </td>
-      </tr>
-      <tr>
-        <td width="22%" valign="top">&nbsp;</td>
-        <td width="78%"><span class="vexpl"><span class="red"><strong>Note:<br>
-          </strong></span>Changing any settings on this page will disconnect all clients!</span>
-       </td>
-      </tr>
-    </table>  </td>
-</tr>
-</table>
-</form>
-<?php include("fend.inc"); ?>
index 229006782be6682d58fbd0c37337e82d438f001f..80786f3d121b235ffd1c4671c3c31b573f3ff47d 100644 (file)
@@ -39,6 +39,10 @@ if (!is_array($config['ovpn']['client'])){
        $config['ovpn']['client']['tunnel'] =  array();
 }
 
+$id = $_GET['id'];
+if (isset($_POST['id']))
+       $id = $_POST['id'];
+
 $ovpncli =& $config['ovpn']['client']['tunnel'];
 
 if ($_POST['apply']) {
@@ -58,11 +62,19 @@ if ($_POST['apply']) {
 }
 
 if ($_GET['act'] == "del") {
-       if ($ovpncli[$_GET['id']]) {
-               unset($ovpncli[$_GET['id']]);
+       if ($ovpncli[$id]) {
+               $ovpnent = $ovpncli[$id];
+               unset($ovpncli[$id]);
+
+               /* Kill running processes */
+               /* Remove old certs & keys */
+               ovpn_client_kill($ovpnent['if']);
+
+               /* Remove interface from list of optional interfaces */
+               ovpn_client_iface_del($ovpnent['if']);
+
                write_config();
-               ovpn_client_kill($_GET['id']);
-               touch($d_ovpnclidirty_path);
+               touch($d_sysrebootreqd_path);
                header("Location: vpn_openvpn_cli.php");
                exit;
        }
@@ -80,7 +92,7 @@ if ($_GET['act'] == "del") {
 <table width="100%" border="0" cellpadding="0" cellspacing="0">
   <tr><td>
   <ul id="tabnav">             
-       <li class="tabinact1"><a href="vpn_openvpn.php">Server</a></li>
+       <li class="tabinact1"><a href="vpn_openvpn_srv.php">Server</a></li>
        <li class="tabact">Client</li>
   </ul>
   </td></tr>
@@ -93,8 +105,10 @@ if ($_GET['act'] == "del") {
     <table width="100%" border="0" cellpadding="0" cellspacing="0">
        <tr>
          <td width="10%" class="listhdrr">Interface</td>
-         <td width="30%" class="listhdrr">Server address</td>
-         <td width="10%" class="listhdrr" align="middle">Version</td>
+         <td width="5%" class="listhdrr">Protocol</td>
+         <td width="15%" class="listhdrr">Socket</td>
+         <td width="15%" class="listhdrr">Server address</td>
+         <td width="5%" class="listhdrr" align="center">Version</td>
          <td width="40%" class="listhdr">Description</td>
          <td width="10%" class="list"></td>
        </tr>
@@ -110,7 +124,13 @@ if ($_GET['act'] == "del") {
        
        <tr>
          <td class="listlr"><?=$spans;?>
-               <?= $client['if'].":".$client['cport'];?>       
+               <?= $config['interfaces'][ovpn_get_opt_interface($client['if'])]['descr'] . " (" . $client['if'] . ")";?>
+         <?=$spane;?></td>
+         <td class="listr"><?=$spans;?>
+               <?= strtoupper($client['proto']);?>     
+          <?=$spane;?></td>
+         <td class="listr"><?=$spans;?>
+               <?= "0.0.0.0:" . $client['port'];?>     
          <?=$spane;?></td>
          <td class="listr"><?=$spans;?>
                <?= $client['saddr'].":".$client['sport'];?>
@@ -119,14 +139,14 @@ if ($_GET['act'] == "del") {
                <?= $client['ver'];?>
          <?=$spane;?></td>
           <td class="listbg"><?=$spans;?>
-               <?= $client['descr'];?>
+               <?= htmlspecialchars($client['descr']);?>&nbsp;
          <?=$spane;?></td>
          <td valign="middle" nowrap class="list"> <a href="vpn_openvpn_cli_edit.php?id=<?=$i;?>"><img src="e.gif" title="edit client configuration" width="17" height="17" border="0"></a>
                 &nbsp;<a href="vpn_openvpn_cli.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this client configuration?')"><img src="x.gif" title="delete client configuration" width="17" height="17" border="0"></a></td>
        </tr>
        <?php $i++; endforeach; ?>
        <tr> 
-         <td class="list" colspan="4">&nbsp;</td>
+         <td class="list" colspan="6">&nbsp;</td>
          <td class="list"> <a href="vpn_openvpn_cli_edit.php"><img src="plus.gif" title="add client configuration" width="17" height="17" border="0"></a></td>
        </tr>
     </table>
index a13b534f11d8698d96371b4a670205dcb112ae9b..fa7fa1267ca957b86bb68a9d5cb44075ba21a697 100644 (file)
@@ -39,47 +39,7 @@ if (!is_array($config['ovpn']['client'])){
        $config['ovpn']['client']['tunnel'] = array();
 }
 
-function getnxt_if($type) {
-       /* find the first available device of type $type */
-       global $config;
-       $a_client = $config['ovpn']['client']['tunnel'];
-       $max = ($type == 'tun') ? 17 : 4;
-       for ($i = 1; $i < $max ; $i++) {
-               $hit = false;
-               foreach ($a_client as $client) {
-                       if ($client['iface'] == $type . $i) {
-                               $hit = true;
-                               break;
-                       }
-               }
-               if (!$hit) 
-                       return $type . $i;
-       }
-       return false;
-}
 
-
-function getnxt_port() {
-       /* Get first unused port */
-       global $config;
-       $a_client = $config['ovpn']['client']['tunnel'];
-       $port = 5001;
-       while (true) {
-               $hit = false;
-               foreach ($a_client as $client) {
-                       if ($client['cport'] == $port) {
-                               $hit = true;
-                               break;
-                       }
-               }
-               if (!$hit) 
-                       return $port;
-               $port++;
-       }
-       return false; /* should never get here */
-}
-                       
-                
 $ovpncli =& $config['ovpn']['client']['tunnel'];
 
 $id = $_GET['id'];
@@ -96,7 +56,7 @@ else {
        $pconfig = array();
        $pconfig['type'] = 'tun';
        $pconfig['proto'] = 'udp';
-       $pconfig['sport'] = '5000';
+       $pconfig['sport'] = '1194';
        $pconfig['ver'] = '2';
        $pconfig['crypto'] = 'BF-CBC';
        $pconfig['pull'] = true;
@@ -104,8 +64,24 @@ else {
 }
 
 if (isset($_POST['pull'])) {
+
        /* Called from form */
        unset($input_errors);
+
+       /* input validation */
+       $reqdfields = explode(" ", "type saddr sport");
+       $reqdfieldsn = explode(",", "Tunnel type,Address,Port");
+
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       /* valid Port */
+       if (($_POST['sport'] && !is_port($_POST['sport'])))
+               $input_errors[] = "The server's port must be an integer between 1 and 65535 (default 1194).";
+
+       /* valid FQDN or IP address */
+       if (($_POST['saddr'] && !is_ipaddr($_POST['saddr']) && !is_domain($_POST['saddr'])))
+               $input_errors[] = "The server name contains invalid characters.";
+
        if (is_null($_POST['ca_cert']))
                $input_errors[] = "You must provide a CA certificate file";
        elseif (!strstr($_POST['ca_cert'], "BEGIN CERTIFICATE") || !strstr($_POST['ca_cert'], "END CERTIFICATE"))
@@ -120,59 +96,93 @@ if (isset($_POST['pull'])) {
                $input_errors[] = "You must provide a client key file";
        elseif (!strstr($_POST['cli_key'], "BEGIN RSA PRIVATE KEY") || !strstr($_POST['cli_key'], "END RSA PRIVATE KEY"))
                $input_errors[] = "The client key does not appear to be valid.";
-       
-       if (!$input_errors) {
-               if (isset($id)) {
-                       /* Editing an existing entry */
-                       $ovpnent = $ovpncli[$id];
-                       /* Test Server type hasn't changed */
-                       if ($ovpnent['type'] != $_POST['type']) {
-                               $nxt_if = getnxt_if($_POST['type']);
-                               if (!$nxt_if)
-                                       $input_errors[] = "Run out of devices for a tunnel of type {$_POST['type']}";
-                               else
-                                       $ovpnent['if'] = $nxt_if;
-                               /* Need to reboot in order to create interfaces cleanly */
-                               touch($d_sysrebootreqd_path);
-                       }
-                       /* Has the enable/disable state changed? */
-                       if (isset($ovpnent['enable']) && isset($_POST['disabled'])) {
-                               touch($d_sysrebootreqd_path);
-                               touch($d_ovpnclidirty_path);
-                               ovpn_client_kill($id);
-                               ovpn_client_iface_del($id);
-                       }
-                       if (!isset($ovpnent['enable']) && !isset($_POST['disabled'])) {
-                               touch($d_sysrebootreqd_path);
-                               touch($d_ovpnclidirty_path);
+
+       if (isset($_POST['tlsauth']) && empty($_POST['pre-shared-key']))
+               $input_errors[] = "You must provide a pre-shared secret file";
+       if (!empty($_POST['pre-shared-key']))
+               if (!strstr($_POST['pre-shared-key'], "BEGIN OpenVPN Static key") || !strstr($_POST['pre-shared-key'], "END OpenVPN Static key"))
+                       $input_errors[] = "Pre-shared secret does not appear to be valid.";
+                                
+       if (isset($id)) {
+               /* Editing an existing entry */
+               $ovpnent = $ovpncli[$id];
+
+               if ( $ovpncli[$id]['sport'] != $_POST['sport'] ||
+                       $ovpncli[$id]['proto'] != $_POST['proto'] ) {
+
+                       /* some entries changed */
+                       for ($i = 0; isset($config['ovpn']['client']['tunnel'][$i]); $i++) {
+                               $current = &$config['ovpn']['client']['tunnel'][$i];
+
+                               if ($current['sport'] == $_POST['sport'])
+                                       if ($current['proto'] == $_POST['proto'])
+                                               $input_errors[] = "You already have this combination for port and protocol settings. You can't use it twice";
                        }
                }
-               else {
-                       /* Creating a new entry */
-                       $ovpnent = array();
-                       $nxt_if = getnxt_if($_POST['type']);
-                       if (!$nxt_if)
-                               $input_errors[] = "Run out of devices for a tunnel of type {$_POST['type']}";
-                       else
-                               $ovpnent['if'] = $nxt_if;
-                       $ovpnent['cport'] = getnxt_port();
-                       /* I think we have to reboot to have the interface created cleanly */
-                       touch($d_sysrebootreqd_path);
+
+               /* Test Server type hasn't changed */
+               if ($ovpnent['type'] != $_POST['type']) {
+                       $input_errors[] = "Delete this interface first before changing the type of the tunnel to " . strtoupper($_POST['type']) .".";
+                       /* Temporarily disabled */
+                       /*
+                        * $nxt_if = getnxt_client_if($_POST['type']);
+                        * if (!$nxt_if)
+                        *      $input_errors[] = "Run out of devices for a tunnel of type {$_POST['type']}";
+                        * else
+                        *      $ovpnent['if'] = $nxt_if;
+                        */
+
+                       /* Need to reboot in order to create interfaces cleanly */
+                       /* touch($d_sysrebootreqd_path); */
                }
+               /* Has the enable/disable state changed? */
+               if (isset($ovpnent['enable']) && isset($_POST['disabled'])) {
+                       touch($d_ovpnclidirty_path);
+               }
+               if (!isset($ovpnent['enable']) && !isset($_POST['disabled'])) {
+                       touch($d_ovpnclidirty_path);
+               }
+       } else {
+               /* Creating a new entry */
+               $ovpnent = array();
+               $nxt_if = getnxt_client_if($_POST['type']);
+               if (!$nxt_if)
+                       $input_errors[] = "Run out of devices for a tunnel of type {$_POST['type']}";
+               else
+                       $ovpnent['if'] = $nxt_if;
+
+               $ovpnent['port'] = getnxt_client_port();
+
+               /* I think we have to reboot to have the interface created cleanly */
+               touch($d_sysrebootreqd_path);
+       }
+
+       if (!$input_errors) {
+
+               $ovpnent['enable'] = isset($_POST['disabled']) ? false : true;
                $ovpnent['type'] = $_POST['type'];
                $ovpnent['proto'] = $_POST['proto'];
                $ovpnent['sport'] = $_POST['sport'];
                $ovpnent['ver'] = $_POST['ver'];
                $ovpnent['saddr'] = $_POST['saddr'];
                $ovpnent['descr'] = $_POST['descr'];
+               $ovpnent['ca_cert'] = $pconfig['ca_cert'];
+               $ovpnent['cli_cert'] = $pconfig['cli_cert'];
+               $ovpnent['cli_key'] = $pconfig['cli_key'];
+               $ovpnent['crypto'] = $_POST['crypto'];
+               $ovpnent['pull'] = true; //This is a fixed config for this version
+               $ovpnent['tlsauth'] = false;
+
+               unset($ovpnent['pre-shared-key']);
+               if ($_POST['tlsauth']) {
+                       $ovpnent['tlsauth'] = true;
+                       $ovpnent['pre-shared-key'] = base64_encode($_POST['pre-shared-key']); 
+               }
+
                $ovpnent['ca_cert'] = base64_encode($_POST['ca_cert']);
                $ovpnent['cli_cert'] = base64_encode($_POST['cli_cert']);
                $ovpnent['cli_key'] = base64_encode($_POST['cli_key']);
-               $ovpnent['crypto'] = $_POST['crypto'];
-               $ovpnent['pull'] = true; //This is a fixed config for this version
-               $ovpnent['enable'] = isset($_POST['disabled']) ? false : true;
-               
-       
+
                if (isset($id) && $ovpncli[$id]){
                        $ovpncli[$id] = $ovpnent;
                }
@@ -182,13 +192,38 @@ if (isset($_POST['pull'])) {
                
                write_config();
                touch($d_ovpnclidirty_path);
+
                header("Location: vpn_openvpn_cli.php");
                exit;
+       } else {
+               $pconfig = $_POST;
+
+               $pconfig['enable'] = "true";
+               if (isset($_POST['disabled']))
+                       unset($pconfig['enable']);
+
+               if ($_POST['tlsauth'])
+                       $pconfig['pre-shared-key'] = base64_encode($_POST['pre-shared-key']); 
+
+               $pconfig['ca_cert'] = base64_encode($_POST['ca_cert']);
+               $pconfig['cli_cert'] = base64_encode($_POST['cli_cert']);
+               $pconfig['cli_key'] = base64_encode($_POST['cli_key']);
        }
 }
 
 ?>
 <?php include("fbegin.inc"); ?>
+<script language="JavaScript">
+function enable_change(enable_over) {
+       var endis;
+       endis = !(document.iform.tlsauth.checked || enable_over);
+
+       document.iform.psk.disabled = endis;
+}
+
+//-->
+</script>
+
 <?php if ($input_errors) print_input_errors($input_errors); ?>
 
 <form action="vpn_openvpn_cli_edit.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
@@ -228,7 +263,7 @@ if (isset($_POST['pull'])) {
       <td width="22%" valign="top" class="vncellreq">Port</td>
       <td width="78%" class="vtable">
         <input name="sport" type="text" class="formfld" size="5" maxlength="5" value="<?=htmlspecialchars($pconfig['sport']);?>"><br>
-        Enter the server's port number (default is 5000).</td>
+        Enter the server's port number (default is 1194).</td>
     </tr>
     
     <tr>
@@ -319,7 +354,23 @@ if (isset($_POST['pull'])) {
          Select the data channel encryption cipher.  This must match the setting on the server.
        </td>
       </tr>
-      
+
+      <tr>
+        <td width="22%" valign="top" class="vncell">TLS auth</td>
+        <td width="78%" class="vtable">
+         <input name="tlsauth" type="checkbox" value="yes" <?php if (isset($pconfig['tlsauth'])) echo "checked";?> onClick="enable_change(false)">
+         <strong>TLS auth</strong><br>
+          The tls-auth directive adds an additional HMAC signature to all SSL/TLS handshake packets for integrity verification.</td>
+      </tr>
+
+      <tr> 
+       <td width="22%" valign="top" class="vncell">Pre-shared secret</td>
+       <td width="78%" class="vtable">
+         <textarea name="pre-shared-key" id="psk" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['pre-shared-key']));?></textarea>
+         <br>
+         Paste your own pre-shared secret here.</td>
+      </tr>
+
      <tr>
        <td width="22%" valign="top" class="vncellreq">Options</td>
        <td width="78%" class="vtable">
@@ -338,5 +389,9 @@ if (isset($_POST['pull'])) {
      </tr>
    </table>
 </form>
-
+<script language="JavaScript">
+<!--
+enable_change(false);
+//-->
+</script>
 <?php include("fend.inc"); ?>
diff --git a/webgui/vpn_openvpn_srv.php b/webgui/vpn_openvpn_srv.php
new file mode 100644 (file)
index 0000000..2f4f9b7
--- /dev/null
@@ -0,0 +1,165 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       vpn_openvpn_srv.php
+
+       Copyright (C) 2004 Peter Curran (peter@closeconsultants.com).
+       Copyright (C) 2005 Peter Allgeyer (allgeyer@web.de).
+       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("VPN", "OpenVPN");
+require("guiconfig.inc");
+require_once("openvpn.inc");
+
+if (!is_array($config['ovpn']))
+       $config['ovpn'] = array();
+if (!is_array($config['ovpn']['server'])){
+       $config['ovpn']['server'] =  array();
+       $config['ovpn']['server']['tunnel'] =  array();
+}
+
+$ovpnsrv = &$config['ovpn']['server']['tunnel'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+        $id = $_POST['id'];
+
+
+if ($_POST['apply']) {
+               $retval = 0;
+               if (file_exists($d_sysrebootreqd_path)) {
+                       /* Rewrite interface definitions */
+                       $retval = ovpn_server_iface();
+               }
+               else{
+                       ovpn_lock();
+                       $retval = ovpn_server_iface();
+                       $retval = ovpn_config_server(false);
+                       ovpn_unlock();
+               }
+               if (file_exists($d_ovpnsrvdirty_path))
+                       unlink($d_ovpnsrvdirty_path);
+               $savemsg = get_std_save_message($retval);       
+}
+
+if ($_GET['act'] == "del") {
+       if ($ovpnsrv[$id]) {
+               $ovpnent = $ovpnsrv[$id];
+               unset($ovpnsrv[$id]);
+                                                                             
+               /* Kill running processes */
+               /* Remove old certs & keys */
+               ovpn_server_kill($ovpnent['tun_iface']);
+
+               /* Remove interface from list of optional interfaces */
+               ovpn_server_iface_del($ovpnent['tun_iface']);
+
+               write_config();
+               touch($d_sysrebootreqd_path);
+               header("Location: vpn_openvpn_srv.php");
+               exit;
+       }
+}
+?>
+<?php include("fbegin.inc"); ?>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if (file_exists($d_sysrebootreqd_path) && !file_exists($d_ovpnsrvdirty_path)) print_info_box(get_std_save_message(0)); ?>
+<form action="vpn_openvpn_srv.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+<?php if (file_exists($d_ovpnsrvdirty_path)): ?><p>
+<?php print_info_box_np("The OpenVPN server configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr><td>
+  <ul id="tabnav">             
+       <li class="tabact">Server</li>
+       <li class="tabinact"><a href="vpn_openvpn_cli.php">Client</a></li>
+  </ul>
+  </td></tr>
+  <tr>
+  <td class="tabcont">
+  <strong><span class="red">WARNING: This feature is experimental and modifies your optional interface configuration.
+  Backup your configuration before using OpenVPN, and restore it before upgrading.<br>
+&nbsp;  <br>
+    </span></strong>
+    <table width="100%" border="0" cellpadding="0" cellspacing="0">
+       <tr>
+         <td width="5%" class="listhdrr">Interface</td>
+         <td width="5%" class="listhdrr">Protocol</td>
+         <td width="5%" class="listhdrr">Socket</td>
+         <td width="25%" class="listhdrr">IP Block</td>
+         <td width="15%" class="listhdrr">Crypto</td>
+         <td width="35%" class="listhdr">Description</td>
+         <td width="10%" class="list"></td>
+       </tr>
+       
+       <?php $i = 0; foreach ($ovpnsrv as $server):
+                                       if (!isset($server['enable'])) {
+                                               $spans = "<span class=\"gray\">";
+                                               $spane = "</span>";
+                                       } else {
+                                               $spans = $spane = "";
+                                       }
+                                       
+               if ($server['bind_iface'] == 'all')
+                       $ipaddr = "0.0.0.0";
+               else
+                       $ipaddr = ovpn_get_ip($server['bind_iface']);
+       ?>
+       
+       <tr>
+         <td class="listlr"><?=$spans;?>
+               <?= $config['interfaces'][ovpn_get_opt_interface($server['tun_iface'])]['descr'] . " (" . $server['tun_iface'] . ")";?> 
+         <?=$spane;?></td>
+         <td class="listr"><?=$spans;?>
+               <?= strtoupper($server['proto']);?>     
+         <?=$spane;?></td>
+         <td class="listr"><?=$spans;?>
+               <?= $ipaddr.":".$server['port'];?>
+         <?=$spane;?></td>
+         <td class="listr"><?=$spans;?>
+               <?= $server['ipblock']."/".$server['prefix'];?> 
+         <?=$spane;?></td>
+         <td class="listr"><?=$spans;?>
+               <?= $server['crypto'];?>        
+         <?=$spane;?></td>
+          <td class="listbg"><?=$spans;?>
+               <?= htmlspecialchars($server['descr']);?>&nbsp;
+         <?=$spane;?></td>
+         <td valign="middle" nowrap class="list"> <a href="vpn_openvpn_srv_edit.php?id=<?=$i;?>"><img src="e.gif" title="edit server configuration" width="17" height="17" border="0"></a>
+                &nbsp;<a href="vpn_openvpn_srv.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this server configuration?')"><img src="x.gif" title="delete server configuration" width="17" height="17" border="0"></a></td>
+       </tr>
+       <?php $i++; endforeach; ?>
+       <tr> 
+         <td class="list" colspan="6">&nbsp;</td>
+         <td class="list"> <a href="vpn_openvpn_srv_edit.php"><img src="plus.gif" title="add server configuration" width="17" height="17" border="0"></a></td>
+       </tr>
+    </table>
+  </td>
+</tr>
+</table>
+</form>
+<?php include("fend.inc"); ?>
diff --git a/webgui/vpn_openvpn_srv_edit.php b/webgui/vpn_openvpn_srv_edit.php
new file mode 100644 (file)
index 0000000..d284390
--- /dev/null
@@ -0,0 +1,560 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       vpn_openvpn_srv_edit.php
+
+       Copyright (C) 2004 Peter Curran (peter@closeconsultants.com).
+       Copyright (C) 2005 Peter Allgeyer (allgeyer@web.de).
+       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("VPN", "OpenVPN", "Edit server");
+require("guiconfig.inc");
+require_once("openvpn.inc");
+
+if (!is_array($config['ovpn']))
+       $config['ovpn'] = array();
+if (!is_array($config['ovpn']['server'])){
+       $config['ovpn']['server'] =  array();
+       $config['ovpn']['server']['tunnel'] = array();
+}
+
+$ovpnsrv =& $config['ovpn']['server']['tunnel'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+       $id = $_POST['id'];
+
+if (isset($id) && $ovpnsrv[$id]) {
+       $pconfig = $config['ovpn']['server']['tunnel'][$id];
+       if (isset($ovpnsrv[$id]['enable']))
+               $pconfig['enable'] = true;
+} else {
+       /* creating - set defaults */
+       $pconfig = array();
+       $pconfig['type'] = "tun";
+       $pconfig['psh_options'] = array();
+       /* Initialise with some sensible defaults */
+       if ($config['ovpn']['server']['tunnel'])
+               $pconfig['port'] = getnxt_server_port();
+       else
+               $port = 1194;
+       $pconfig['proto'] = 'udp';
+       $pconfig['maxcli'] = 25;
+       $pconfig['crypto'] = 'BF-CBC';
+       $pconfig['dupcn'] = true;
+       $pconfig['verb'] = 1;
+       $pconfig['enable'] = true;
+}
+
+
+if ($_POST) {
+
+       unset($input_errors);
+
+       /* input validation */
+       $reqdfields = explode(" ", "type bind_iface ipblock");
+       $reqdfieldsn = explode(",", "Tunnel type,Interface binding,IP address block start");
+
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       
+       /* valid IP */
+       if (($_POST['ipblock'] && !is_ipaddr($_POST['ipblock'])))
+               $input_errors[] = "A valid IP address must be specified.";
+               
+       /* valid Port */
+       if (($_POST['port'] && !is_port($_POST['port'])))
+               $input_errors[] = "The server port must be an integer between 1 and 65535.";
+       
+       /* check if dynip is set correctly */
+       if ($_POST['dynip'] && $_POST['bind_iface'] != 'all')
+               $input_errors[] = "Dynamic IP address can only be set with interface binding set to ALL.";
+
+       /* Sort out the cert+key files */
+       if (empty($_POST['ca_cert']))
+               $input_errors[] = "You must provide a CA certificate file";
+       elseif (!strstr($_POST['ca_cert'], "BEGIN CERTIFICATE") || !strstr($_POST['ca_cert'], "END CERTIFICATE"))
+               $input_errors[] = "The CA certificate does not appear to be valid.";
+
+       if (empty($_POST['srv_cert']))
+               $input_errors[] = "You must provide a server certificate file";
+       elseif (!strstr($_POST['srv_cert'], "BEGIN CERTIFICATE") || !strstr($_POST['srv_cert'], "END CERTIFICATE"))
+               $input_errors[] = "The server certificate does not appear to be valid.";
+
+       if (empty($_POST['srv_key']))
+               $input_errors[] = "You must provide a server key file";
+       elseif (!strstr($_POST['srv_key'], "BEGIN RSA PRIVATE KEY") || !strstr($_POST['srv_key'], "END RSA PRIVATE KEY"))
+               $input_errors[] = "The server key does not appear to be valid.";
+
+       if (empty($_POST['dh_param']))
+               $input_errors[] = "You must provide a DH parameters file";
+       elseif (!strstr($_POST['dh_param'], "BEGIN DH PARAMETERS") || !strstr($_POST['dh_param'], "END DH PARAMETERS"))
+               $input_errors[] = "The DH parameters do not appear to be valid.";
+                               
+       if (isset($_POST['tlsauth']) && empty($_POST['pre-shared-key']))
+               $input_errors[] = "You must provide a pre-shared secret file";
+       if (!empty($_POST['pre-shared-key']))
+               if (!strstr($_POST['pre-shared-key'], "BEGIN OpenVPN Static key") || !strstr($_POST['pre-shared-key'], "END OpenVPN Static key"))
+                       $input_errors[] = "Pre-shared secret does not appear to be valid.";
+                               
+       if ($_POST['psh_pingrst'] && $_POST['psh_pingexit'])
+               $input_errors[] = "Ping-restart and Ping-exit are mutually exclusive and cannot be used together";
+
+       if ($_POST['psh_rtedelay'] && !is_numeric($_POST['psh_rtedelay_int']))
+               $input_errors[] = "Route-delay needs a numerical interval setting.";
+
+       if ($_POST['psh_inact'] && !is_numeric($_POST['psh_inact_int']))
+               $input_errors[] = "Inactive needs a numerical interval setting.";
+
+       if ($_POST['psh_ping'] && !is_numeric($_POST['psh_ping_int']))
+               $input_errors[] = "Ping needs a numerical interval setting.";
+                       
+       if ($_POST['psh_pingexit'] && !is_numeric($_POST['psh_pingexit_int']))
+               $input_errors[] = "Ping-exit needs a numerical interval setting.";
+
+       if ($_POST['psh_pingrst'] && !is_numeric($_POST['psh_pingrst_int']))
+               $input_errors[] = "Ping-restart needs a numerical interval setting.";
+
+
+       /* need a test here to make sure prefix and max_clients are coherent */
+
+       /* need a test here to make sure protocol:ip:port isn't used twice */
+
+       /* Editing an existing entry? */
+       if (isset($id) && $ovpnsrv[$id]) {
+               $ovpnent = $ovpnsrv[$id];
+
+               if ( $ovpnent['bind_iface'] != $_POST['bind_iface'] ||
+                    $ovpnent['port'] != $_POST['port'] ||
+                    $ovpnent['proto'] != $_POST['proto'] ) {
+
+                       /* some entries changed */
+                       for ($i = 0; isset($config['ovpn']['server']['tunnel'][$i]); $i++) {
+                               $current = &$config['ovpn']['server']['tunnel'][$i];
+
+                               if ($current['bind_iface'] == $_POST['bind_iface'] || $current['bind_iface'] == 'all')
+                                       if ($current['port'] == $_POST['port'])
+                                               if ($current['proto'] == $_POST['proto'])
+                                                       $input_errors[] = "You already have this combination for Interface binding, port and protocol settings. You can't use it twice";
+                       }
+               }
+
+               /* Test Server type hasn't changed */
+               if ($ovpnent['type'] != $_POST['type']) {
+                       $input_errors[] = "Delete this interface first before changing the type of the tunnel to " . strtoupper($_POST['type']) .".";
+
+                       /* Temporarily disabled */
+                       /*
+                        * $nxt_if = getnxt_server_if($_POST['type']);
+                        * if (!$nxt_if)
+                        *              $input_errors[] = "Run out of devices for a tunnel of type {$_POST['type']}";
+                        * else
+                        *      $ovpnent['tun_iface'] = $nxt_if;
+                        */
+                        /* Need to reboot in order to create interfaces cleanly */
+                        /* touch($d_sysrebootreqd_path); */
+               }
+               /* Has the enable/disable state changed? */
+               if (isset($ovpnent['enable']) && isset($_POST['disabled'])) {
+                       /* status changed to disabled */
+                       touch($d_ovpnsrvdirty_path);
+               }
+               if (!isset($ovpnent['enable']) && !isset($_POST['disabled'])) {
+                       /* status changed to enable */
+                       /* touch($d_sysrebootreqd_path); */
+                       touch($d_ovpnsrvdirty_path);
+               }
+       } else {
+               /* Creating a new entry */
+               $ovpnent = array();
+               $nxt_if = getnxt_server_if($_POST['type']);
+               if (!$nxt_if)
+                       $input_errors[] = "Run out of devices for a tunnel of type {$_POST['type']}";
+               else
+                       $ovpnent['tun_iface'] = $nxt_if;
+               $ovpnent['port'] = getnxt_server_port();
+               /* I think we have to reboot to have the interface created cleanly */
+               touch($d_sysrebootreqd_path);
+       }
+
+       if (!$input_errors) {
+
+               $ovpnent['enable'] = isset($_POST['disabled']) ? false : true;
+               $ovpnent['bind_iface'] = $_POST['bind_iface'];
+               $ovpnent['port'] = $_POST['port'];
+               $ovpnent['proto'] = $_POST['proto'];
+               $ovpnent['type'] = $_POST['type'];
+               
+               /* convert IP address block to a correct network IP address */
+               $ipblock = gen_subnet($_POST['ipblock'], $_POST['prefix']);
+               $ovpnent['ipblock'] = $ipblock;
+
+               $ovpnent['prefix'] = $_POST['prefix'];
+               $ovpnent['descr'] = $_POST['descr'];
+               $ovpnent['verb'] = $_POST['verb'];
+               $ovpnent['maxcli'] = $_POST['maxcli'];
+               $ovpnent['crypto'] = $_POST['crypto'];
+               $ovpnent['cli2cli'] = $_POST['cli2cli'] ? true : false;
+               $ovpnent['dupcn'] = $_POST['dupcn'] ? true : false;
+               $ovpnent['dynip'] = $_POST['dynip'] ? true : false;
+               $ovpnent['tlsauth'] = false;
+
+               unset($ovpnent['pre-shared-key']);
+               if ($_POST['tlsauth']) {
+                       $ovpnent['tlsauth'] = true;
+                       $ovpnent['pre-shared-key'] = base64_encode($_POST['pre-shared-key']);   
+               }
+
+               $ovpnent['psh_options']['redir'] = $_POST['psh_redir'] ? true : false;
+               $ovpnent['psh_options']['redir_loc'] = $_POST['psh_redir_loc'] ? true : false;
+               $ovpnent['psh_options']['rtedelay'] = $_POST['psh_rtedelay'] ? true : false;
+               $ovpnent['psh_options']['inact'] = $_POST['psh_inact'] ? true : false;
+               $ovpnent['psh_options']['ping'] = $_POST['psh_ping'] ? true : false;
+               $ovpnent['psh_options']['pingrst'] = $_POST['psh_pingrst'] ? true : false;
+               $ovpnent['psh_options']['pingexit'] = $_POST['psh_pingexit'] ? true : false;
+
+               unset($ovpnent['psh_options']['rtedelay_int']);
+               unset($ovpnent['psh_options']['inact_int']);
+               unset($ovpnent['psh_options']['ping_int']);
+               unset($ovpnent['psh_options']['pingrst_int']);
+               unset($ovpnent['psh_options']['pingexit_int']);
+
+               if ($_POST['psh_rtedelay_int'])
+                       $ovpnent['psh_options']['rtedelay_int'] = $_POST['psh_rtedelay_int'];
+               if ($_POST['psh_inact_int'])
+                       $ovpnent['psh_options']['inact_int'] = $_POST['psh_inact_int'];
+               if ($_POST['psh_ping_int'])
+                       $ovpnent['psh_options']['ping_int'] = $_POST['psh_ping_int'];
+               if ($_POST['psh_pingrst_int'])
+                       $ovpnent['psh_options']['pingrst_int'] = $_POST['psh_pingrst_int'];
+               if ($_POST['psh_pingexit_int'])
+                       $ovpnent['psh_options']['pingexit_int'] = $_POST['psh_pingexit_int'];
+               
+               $ovpnent['ca_cert'] = base64_encode($_POST['ca_cert']);
+               $ovpnent['srv_cert'] = base64_encode($_POST['srv_cert']);
+               $ovpnent['srv_key'] = base64_encode($_POST['srv_key']);
+               $ovpnent['dh_param'] = base64_encode($_POST['dh_param']);       
+
+               if (isset($id) && $ovpnsrv[$id])
+                       $ovpnsrv[$id] = $ovpnent;
+               else
+                       $ovpnsrv[] = $ovpnent;
+
+               write_config();
+               touch($d_ovpnsrvdirty_path);
+
+               header("Location: vpn_openvpn_srv.php");
+               exit;
+       } else {
+
+               $pconfig = $_POST;
+
+               $pconfig['enable'] = "true";
+               if (isset($_POST['disabled']))
+                       unset($pconfig['enable']);
+
+               if ($_POST['tlsauth'])
+                       $pconfig['pre-shared-key'] = base64_encode($_POST['pre-shared-key']);   
+
+               $pconfig['ca_cert'] = base64_encode($_POST['ca_cert']);
+               $pconfig['srv_cert'] = base64_encode($_POST['srv_cert']);
+               $pconfig['srv_key'] = base64_encode($_POST['srv_key']);
+               $pconfig['dh_param'] = base64_encode($_POST['dh_param']);
+
+               $pconfig['psh_options']['redir'] = $_POST['psh_redir'];
+               $pconfig['psh_options']['redir_loc'] = $_POST['psh_redir_loc'];
+               $pconfig['psh_options']['rtedelay'] = $_POST['psh_rtedelay'];
+               $pconfig['psh_options']['inact'] = $_POST['psh_inact'];
+               $pconfig['psh_options']['ping'] = $_POST['psh_ping'];
+               $pconfig['psh_options']['pingrst'] = $_POST['psh_pingrst'];
+               $pconfig['psh_options']['pingexit'] = $_POST['psh_pingexit'];
+
+               $pconfig['psh_options']['rtedelay_int'] = $_POST['psh_rtedelay_int'];
+               $pconfig['psh_options']['inact_int'] = $_POST['psh_inact_int'];
+               $pconfig['psh_options']['ping_int'] = $_POST['psh_ping_int'];
+               $pconfig['psh_options']['pingrst_int'] = $_POST['psh_pingrst_int'];
+               $pconfig['psh_options']['pingexit_int'] = $_POST['psh_pingexit_int'];
+       }
+}
+
+
+?>
+<?php include("fbegin.inc"); ?>
+<script language="JavaScript">
+function type_change() {
+       switch (document.iform.bind_iface.selectedIndex) {
+               /* ALL */
+               case 0:
+                       document.iform.dynip.disabled = 0;
+                       break;
+               default:
+                       document.iform.dynip.disabled = 1;
+       }
+}
+function enable_change(enable_over) {
+       var endis;
+       endis = !(document.iform.tlsauth.checked || enable_over);
+        
+        document.iform.psk.disabled = endis;
+}
+
+//-->
+</script>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if (file_exists($d_sysrebootreqd_path)) print_info_box(get_std_save_message(0)); ?>
+
+<form action="vpn_openvpn_srv_edit.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+<strong><span class="red">WARNING: This feature is experimental and modifies your optional interface configuration.
+  Backup your configuration before using OpenVPN, and restore it before upgrading.<br>&nbsp;<br>
+</span></strong>
+<table width="100%" border="0" cellpadding="6" cellspacing="0">
+  <tr>
+    <td width="22%" valign="top" class="vncellreq">Disabled</td>
+    <td width="78%" class="vtable">
+      <input name="disabled" type="checkbox" value="yes" <?php if (!isset($pconfig['enable'])) echo "checked"; ?>>
+      <strong>Disable this server</strong><br>
+        <span class="vexpl">Set this option to disable this server without removing it from the list.</span>
+    </td>
+   </tr>
+   
+   <tr>
+     <td width="22%" valign="top" class="vncellreq">Tunnel type</td>
+     <td width="78%" class="vtable">
+       <input type="radio" name="type" class="formfld" value="tun" <?php if ($pconfig['type'] == 'tun') echo "checked"; ?>>
+          TUN&nbsp;
+       <input type="radio" name="type" class="formfld" value="tap" <?php if ($pconfig['type'] == 'tap') echo "checked"; ?>>
+          TAP
+      </td>
+    </tr>
+
+    <tr>
+      <td width="22%" valign="top" class="vncell">OpenVPN protocol/port</td>
+      <td width="78%" class="vtable">
+       <input type="radio" name="proto" class="formfld" value="udp" <?php if ($pconfig['proto'] == 'udp') echo "checked"; ?>>
+           UDP&nbsp;
+        <input type="radio" name="proto" class="formfld" value="tcp" <?php if ($pconfig['proto'] == 'tcp') echo "checked"; ?>>
+           TCP<br><br>
+        Port: 
+        <input name="port" type="text" class="formfld" size="5" maxlength="5" value="<?= $pconfig['port']; ?>"><br>
+        Enter the port number to use for the server (default is 1194).</td>
+    </tr>
+    
+    <tr>
+      <td width="22%" valign="top" class="vncellreq">Interface binding</td>
+      <td width="78%" class="vtable">
+       <select name="bind_iface" class="formfld" onchange="type_change()">
+        <?php 
+       $interfaces = ovpn_real_interface_list();
+       foreach ($interfaces as $key => $iface):
+        ?>
+       <option value="<?=$key;?>" <?php if ($key == $pconfig['bind_iface']) echo "selected"; ?>> <?= $iface;?>
+        </option>
+        <?php endforeach;?>
+        </select>
+        <span class="vexpl"><br>
+        Choose an interface for the OpenVPN server to listen on.</span></td>
+    </tr>
+               
+    <tr>
+      <td width="22%" valign="top" class="vncell">Dynamic IP address</td>
+      <td width="78%" class="vtable">
+       <input name="dynip" type="checkbox" value="yes" <?php if (isset($pconfig['dynip'])) echo "checked"; ?>>
+       <strong>Dynamic IP address</strong><br>
+       Set this option to on, if your IP addresses are being assigned dynamically. Can only be used with interface binding set to ALL.</td>
+    </tr>
+        
+    <tr> 
+      <td width="22%" valign="top" class="vncellreq">VPN client address pool</td>
+      <td width="78%" class="vtable"> 
+        <input name="ipblock" type="text" class="formfld" size="20" value="<?=htmlspecialchars($pconfig['ipblock']);?>">
+        / 
+        <select name="prefix" class="formfld">
+          <?php for ($i = 29; $i > 19; $i--): ?>
+          <option value="<?=$i;?>" <?php if ($i == $pconfig['prefix']) echo "selected"; ?>>
+            <?=$i;?>
+          </option>
+          <?php endfor; ?>
+        </select>
+        <br>
+        Enter the IP address block for the OpenVPN server and clients to use.<br>
+        <br>
+       Maximum number of simultaneous clients: 
+       <input name="maxcli" type="text" class="formfld" size="3" maxlength="3" value="<?=htmlspecialchars($pconfig['maxcli']);?>">
+       </td>
+    </tr>
+
+    <tr> 
+      <td width="22%" valign="top" class="vncell">Description</td>
+      <td width="78%" class="vtable"> 
+        <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> 
+        <br> <span class="vexpl">You may enter a description here for your reference (not parsed).</span></td>
+    </tr>
+    
+    <tr> 
+      <td width="22%" valign="top" class="vncellreq">CA certificate</td>
+      <td width="78%" class="vtable"> 
+      <textarea name="ca_cert" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['ca_cert']));?></textarea>
+      <br>
+      Paste a CA certificate in X.509 PEM format here.</td>
+    </tr>
+               
+    <tr> 
+      <td width="22%" valign="top" class="vncellreq">Server certificate</td>
+      <td width="78%" class="vtable">
+        <textarea name="srv_cert" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['srv_cert']));?></textarea>
+        <br>
+        Paste a server certificate in X.509 PEM format here.</td>
+    </tr>
+     
+    <tr> 
+      <td width="22%" valign="top" class="vncellreq">Server key</td>
+      <td width="78%" class="vtable"> 
+        <textarea name="srv_key" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['srv_key']));?></textarea>
+        <br>Paste the server RSA private key here.</td>
+    </tr>
+      
+    <tr> 
+      <td width="22%" valign="top" class="vncellreq">DH parameters</td>
+      <td width="78%" class="vtable"> 
+       <textarea name="dh_param" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['dh_param']));?></textarea>
+       <br>          
+         Paste the Diffie-Hellman parameters in PEM format here.</td>
+    </tr>
+      
+    <tr>
+      <td width="22%" valign="top" class="vncell">Crypto</td>
+      <td width="78%" class="vtable">
+       <select name="crypto" class="formfld">
+         <?php $cipher_list = ovpn_get_cipher_list();
+               foreach($cipher_list as $key => $value){
+         ?>
+               <option value="<?= $key ?>" <?php if ($pconfig['crypto'] == $key) echo "selected"; ?>>
+               <?= $value ?>
+               </option>
+         <?php
+           }
+         ?>
+         </select>
+         <br>
+       Select a data channel encryption cipher.</td>
+    </tr>
+      
+    <tr>
+      <td width="22%" valign="top" class="vncell">TLS auth</td>
+      <td width="78%" class="vtable">
+       <input name="tlsauth" type="checkbox" value="yes" <?php if (isset($pconfig['tlsauth'])) echo "checked";?> onClick="enable_change(false)">
+       <strong>TLS auth</strong><br>
+       The tls-auth directive adds an additional HMAC signature to all SSL/TLS handshake packets for integrity verification.</td>
+    </tr>
+
+    <tr> 
+      <td width="22%" valign="top" class="vncell">Pre-shared secret</td>
+      <td width="78%" class="vtable">
+       <textarea name="pre-shared-key" id="psk" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['pre-shared-key']));?></textarea>
+       <br>
+       Paste your own pre-shared secret here.</td>
+    </tr>
+
+    <tr>
+      <td width="22%" valign="top" class="vncell">Internal routing mode</td>
+      <td width="78%" class="vtable">
+       <input name="cli2cli" type="checkbox" value="yes" <?php if (isset($pconfig['cli2cli'])) echo "checked"; ?>>
+       <strong>Enable client-to-client routing</strong><br>
+       If this option is on, clients are allowed to talk to each other.</td>
+    </tr>
+      
+    <tr>
+      <td width="22%" valign="top" class="vncell">Client authentication</td>
+      <td width="78%" class="vtable">
+       <input name="dupcn" type="checkbox" value="yes" <?php if (isset($pconfig['dupcn'])) echo "checked"; ?>>
+        <strong>Permit duplicate client certificates</strong><br>
+       If this option is on, clients with duplicate certificates will not be disconnected.</td>
+    </tr>
+        
+    <tr>
+      <td width="22%" valign="top" class="vncell">Client-push options</td>
+      <td width="78%" class="vtable">
+           <table border="0" cellspacing="0" cellpadding="0">
+             <tr>
+            <td><input type="checkbox" name="psh_redir" value="yes" <?php if (isset($pconfig['psh_options']['redir'])) echo "checked"; ?>>
+            Redirect-gateway</td>
+            <td>&nbsp;</td>
+            <td><input type="checkbox" name="psh_redir_loc" value="yes" <?php if (isset($pconfig['psh_options']['redir_loc'])) echo "checked"; ?>>
+              Local</td>
+               </tr>
+          <tr>
+            <td><input type="checkbox" name="psh_rtedelay" value="yes" <?php if (isset($pconfig['psh_options']['rtedelay'])) echo "checked"; ?>> Route-delay</td>
+            <td width="16">&nbsp;</td>
+            <td><input type="text" name="psh_rtedelay_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['rtedelay_int']?>"> seconds</td>
+          </tr>
+          <tr>
+            <td><input type="checkbox" name="psh_inact" value="yes" <?php if (isset($pconfig['psh_options']['inact'])) echo "checked"; ?>>
+    Inactive</td>
+            <td>&nbsp;</td>
+            <td><input type="text" name="psh_inact_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['inact_int']?>">
+    seconds</td>
+          </tr>
+          <tr>
+            <td><input type="checkbox" name="psh_ping" value="yes" <?php if (isset($pconfig['psh_options']['ping'])) echo "checked"; ?>> Ping</td>
+            <td>&nbsp;</td>
+            <td>Interval: <input type="text" name="psh_ping_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['ping_int']?>"> seconds</td>
+          </tr>
+          <tr>
+            <td><input type="checkbox" name="psh_pingexit" value="yes" <?php if (isset($pconfig['psh_options']['pingexit'])) echo "checked"; ?>> Ping-exit</td>
+            <td>&nbsp;</td>
+            <td>Interval: <input type="text" name="psh_pingexit_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['pingexit_int']?>"> seconds</td>
+          </tr>
+          <tr>
+            <td><input type="checkbox" name="psh_pingrst" value="yes" <?php if (isset($pconfig['psh_options']['pingrst'])) echo "checked"; ?>> Ping-restart</td>
+            <td>&nbsp;</td>
+            <td>Interval: <input type="text" name="psh_pingrst_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['pingrst_int']?>"> seconds</td>
+          </tr>
+        </table></td>
+    </tr>
+    <tr>
+      <td width="22%" valign="top">&nbsp;</td>
+      <td width="78%">
+        <input name="Submit" type="submit" class="formbtn" value="Save">
+        <input name="verb" type="hidden" value="<?=$pconfig['verb'];?>"> 
+        <?php if (isset($id)): ?>
+        <input name="id" type="hidden" value="<?=$id;?>"> 
+        <?php endif; ?>
+      </td>
+    </tr>
+    <tr>
+      <td width="22%" valign="top">&nbsp;</td>
+      <td width="78%"><span class="vexpl"><span class="red"><strong>Note:<br>
+        </strong></span>Changing any settings on this page will disconnect all clients!</span>
+      </td>
+    </tr>
+</table>
+</form>
+<script language="JavaScript">
+<!--
+type_change();
+enable_change(false);
+
+//-->
+</script>
+<?php include("fend.inc"); ?>