summaryrefslogtreecommitdiffstats
path: root/etc
diff options
context:
space:
mode:
Diffstat (limited to 'etc')
-rw-r--r--etc/inc/config.inc17
-rwxr-xr-xetc/inc/openvpn.auth-user.php79
-rw-r--r--etc/inc/openvpn.inc219
3 files changed, 231 insertions, 84 deletions
diff --git a/etc/inc/config.inc b/etc/inc/config.inc
index 5a52611..0cd4476 100644
--- a/etc/inc/config.inc
+++ b/etc/inc/config.inc
@@ -1747,6 +1747,16 @@ endif;
$index++;
}
+ /* determine operational mode */
+ if ($server['auth_method'] == 'pki') {
+ if($server['nopool'])
+ $server['mode'] = "p2p_tls";
+ else
+ $server['mode'] = "server_tls";
+ } else
+ $server['mode'] = "p2p_shared_key";
+ unset($server['auth_method']);
+
/* modify configuration values */
unset($server['dh_params']);
if (!$server['interface'])
@@ -1829,6 +1839,13 @@ endif;
$index++;
}
+ /* determine operational mode */
+ if ($client['auth_method'] == 'pki')
+ $client['mode'] = "p2p_tls";
+ else
+ $client['mode'] = "p2p_shared_key";
+ unset($client['auth_method']);
+
/* modify configuration values */
if (!$client['interface'])
$client['interface'] = 'wan';
diff --git a/etc/inc/openvpn.auth-user.php b/etc/inc/openvpn.auth-user.php
new file mode 100755
index 0000000..275f54d
--- /dev/null
+++ b/etc/inc/openvpn.auth-user.php
@@ -0,0 +1,79 @@
+#!/usr/local/bin/php -f
+<?php
+/* $Id$ */
+/*
+ openvpn.auth-user.php
+
+ Copyright (C) 2008 Shrew Soft Inc
+ 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.
+*/
+
+/*
+ * OpenVPN calls this script to authenticate a user
+ * based on a username and password. We lookup these
+ * in our config.xml file and check the credentials.
+ */
+
+require_once("config.inc");
+
+function & lookup_user($name) {
+ global $config;
+
+ foreach($config['system']['user'] as & $userent)
+ if ($userent['name'] == $name)
+ return $userent;
+}
+
+/* setup syslog logging */
+openlog("openvpn", LOG_ODELAY, LOG_AUTH);
+
+/* read data from environment */
+$username = getenv("username");
+$password = getenv("password");
+
+if (!$username || !$password) {
+ syslog(LOG_ERROR, "invalid user authentication environment");
+ exit(-1);
+}
+
+/* lookup user object by name */
+$user =& lookup_user($username);
+
+if (!$user) {
+ syslog(LOG_WARNING, "user {$username} is unknown");
+ exit(-2);
+}
+
+/* authenticate the user */
+$password = crypt($password, $user['password']);
+
+if ($password != $user['password']) {
+ syslog(LOG_WARNING, "user {$username} supplied an invalid password\n");
+ exit(-3);
+}
+
+syslog(LOG_WARNING, "user {$username} authenticated\n");
+exit(0);
+
+?>
diff --git a/etc/inc/openvpn.inc b/etc/inc/openvpn.inc
index 8dda12e..abc2337 100644
--- a/etc/inc/openvpn.inc
+++ b/etc/inc/openvpn.inc
@@ -49,13 +49,45 @@ require_once('util.inc');
$openvpn_prots = array("UDP", "TCP");
-$openvpn_auth_methods = array(
- 'pki' => "Public Key Infrastructure",
- 'shared_key' => "Pre Shared Key");
+/*
+ * The User Auth mode below is disabled because
+ * OpenVPN erroneously requires that we provide
+ * a CA configuration parameter. In this mode,
+ * clients don't send a certificate so there is
+ * no need for a CA. If we require that admins
+ * provide one in the pfSense UI due to a bogus
+ * requirement imposed by OpenVPN, it could be
+ * considered very confusing ( I know I was ).
+ *
+ * -mgrooms
+ */
+
+$openvpn_server_modes = array(
+ 'p2p_tls' => "Peer to Peer ( SSL/TLS )",
+ 'p2p_shared_key' => "Peer to Peer ( Shared Key )",
+ 'server_tls' => "Remote Access ( SSL/TLS )",
+// 'server_user' => "Remote Access ( User Auth )",
+ 'server_tls_user' => "Remote Access ( SSL/TLS + User Auth )");
+
+$openvpn_client_modes = array(
+ 'p2p_tls' => "Peer to Peer ( SSL/TLS )",
+ 'p2p_shared_key' => "Peer to Peer ( Shared Key )" );
+
+function openvpn_create_key() {
+
+ $fp = popen("/usr/local/sbin/openvpn --genkey --secret /dev/stdout 2>/dev/null", "r");
+ if (!$fp)
+ return false;
+
+ $rslt = stream_get_contents($fp);
+ pclose($fp);
+
+ return $rslt;
+}
function openvpn_create_dhparams($bits) {
- $fp = popen("/usr/bin/openssl dhparam {$bits}", "r");
+ $fp = popen("/usr/bin/openssl dhparam {$bits} 2>/dev/null", "r");
if (!$fp)
return false;
@@ -268,61 +300,64 @@ function openvpn_reconfigure($mode,& $settings) {
$lines = explode(' ', trim(shell_exec("ifconfig {$iface} | grep inet | grep -v inet6")));
$iface_ip = $lines[1];
-$conf .= <<<EOD
-dev {$devname}
-dev-type tun
-dev-node /dev/{$tunname}
-writepid {$pfile}
-#user nobody
-#group nobody
-daemon
-keepalive 10 60
-ping-timer-rem
-persist-tun
-persist-key
-proto $proto
-cipher $cipher
-up /etc/rc.filter_configure
-down /etc/rc.filter_configure
-local {$iface_ip}
-
-EOD;
-
- // Mode specific stuff
+ $conf = "dev {$devname}\n";
+ $conf .= "dev-type tun\n";
+ $conf .= "dev-node /dev/{$tunname}\n";
+ $conf .= "writepid {$pfile}\n";
+ $conf .= "#user nobody\n";
+ $conf .= "#group nobody\n";
+ $conf .= "daemon\n";
+ $conf .= "keepalive 10 60\n";
+ $conf .= "ping-timer-rem\n";
+ $conf .= "persist-tun\n";
+ $conf .= "persist-key\n";
+ $conf .= "proto {$proto}\n";
+ $conf .= "cipher {$cipher}\n";
+ $conf .= "up /etc/rc.filter_configure\n";
+ $conf .= "down /etc/rc.filter_configure\n";
+ $conf .= "local {$iface_ip}\n";
+
+ // server specific settings
if ($mode == 'server') {
list($ip, $mask) = explode('/', $settings['tunnel_network']);
$mask = gen_subnet_mask($mask);
- // Using a shared key or not dynamically assigning IPs to the clients
- if (($settings['auth_method'] == 'shared_key') || (!$settings['pool_enable'] == 'on')) {
-
- if ($settings['auth_method'] == 'pki')
+ // configure tls modes
+ switch($settings['mode']) {
+ case 'p2p_tls':
+ case 'server_tls':
+ case 'server_tls_user':
$conf .= "tls-server\n";
-
- $baselong = ip2long($ip) & ip2long($mask);
- $ip1 = long2ip($baselong + 1);
- $ip2 = long2ip($baselong + 2);
- $conf .= "ifconfig $ip1 $ip2\n";
+ break;
}
- // Using a PKI
- else if ($settings['auth_method'] == 'pki') {
- if ($settings['client2client'])
- $conf .= "client-to-client\n";
-
- $conf .= "server $ip $mask\n";
- $csc_dir = "{$g['varetc_path']}/openvpn-csc";
- $conf .= "client-config-dir $csc_dir\n";
+ // configure p2p/server modes
+ switch($settings['mode']) {
+ case 'p2p_tls':
+ case 'p2p_shared_key':
+ $baselong = ip2long($ip) & ip2long($mask);
+ $ip1 = long2ip($baselong + 1);
+ $ip2 = long2ip($baselong + 2);
+ $conf .= "ifconfig $ip1 $ip2\n";
+ break;
+ case 'server_tls':
+ case 'server_user':
+ case 'server_tls_user':
+ $conf .= "server {$ip} {$mask}\n";
+ $conf .= "client-config-dir {$g['varetc_path']}/openvpn-csc\n";
+ break;
}
- // We can push routes
- if (!empty($settings['local_network'])) {
-
- list($ip, $mask) = explode('/', $settings['local_network']);
- $mask = gen_subnet_mask($mask);
- $conf .= "push \"route $ip $mask\"\n";
+ // configure user auth modes
+ switch($settings['mode']) {
+ case 'server_user':
+ $conf .= "client-cert-not-required\n";
+ case 'server_tls_user':
+ $conf .= "username-as-common-name\n";
+ $conf .= "auth-user-pass-verify /etc/inc/openvpn.auth-user.php via-env\n";
+ break;
}
// The local port to listen on
@@ -331,33 +366,52 @@ EOD;
// The management port to listen on
$conf .= "management 127.0.0.1 {$settings['local_port']}\n";
- if (!empty($settings['maxclients']))
+ if ($settings['maxclients'])
$conf .= "max-clients {$settings['maxclients']}\n";
- openvpn_add_dhcpopts($settings, $conf);
+ // Can we push routes
+ if ($settings['local_network']) {
+ list($ip, $mask) = explode('/', $settings['local_network']);
+ $mask = gen_subnet_mask($mask);
+ $conf .= "push \"route $ip $mask\"\n";
+ }
+
+ // Configure client dhcp options
+ switch($settings['mode']) {
+ case 'server_tls':
+ case 'server_user':
+ case 'server_tls_user':
+ openvpn_add_dhcpopts($settings, $conf);
+ break;
+ }
}
- if ($mode == 'client') {
+ // client specific settings
- // The remote server
- $conf .= "remote {$settings['server_addr']} {$settings['server_port']}\n";
+ if ($mode == 'client') {
- if ($settings['auth_method'] == 'pki')
- $conf .= "client\n";
+ // configure p2p mode
+ switch($settings['mode']) {
+ case 'p2p_tls':
+ $conf .= "tls-client\n";
+ case 'shared_key':
+ $conf .= "client\n";
+ break;
+ }
- // FIXME : This should be a gui option
// The port we'll listen at
if ($settings['local_port'])
$conf .= "lport {$settings['local_port']}\n";
else
$conf .= "nobind\n";
+ // The remote server
+ $conf .= "remote {$settings['server_addr']} {$settings['server_port']}\n";
+
if (!empty($settings['use_shaper']))
$conf .= "shaper {$settings['use_shaper']}\n";
if (!empty($settings['tunnel_network'])) {
-
- // Configure the IPs according to the address pool
list($ip, $mask) = explode('/', $settings['tunnel_network']);
$mask = gen_subnet_mask($mask);
$baselong = ip2long($ip) & ip2long($mask);
@@ -366,41 +420,38 @@ EOD;
$conf .= "ifconfig $ip2 $ip1\n";
}
- if ($settings['proxy_addr']) {
- /* ;http-proxy-retry # retry on connection failures */
+ if ($settings['proxy_addr'])
$conf .= "http-proxy {$settings['proxy_addr']} {$settings['proxy_port']}\n";
- }
}
- // Add the routes if they're set
- if (!empty($settings['remote_network'])) {
+ // Add a remote network route if set
+ if ($settings['remote_network']) {
list($ip, $mask) = explode('/', $settings['remote_network']);
$mask = gen_subnet_mask($mask);
$conf .= "route $ip $mask\n";
}
// Write the settings for the keys
- if ($settings['auth_method'] == 'shared_key')
- openvpn_add_keyfile($settings['shared_key'], $conf, $mode_id, "secret");
-
- if ($settings['auth_method'] == 'pki') {
-
- $ca = lookup_ca($settings['caref']);
- $cert = lookup_cert($settings['certref']);
-
- openvpn_add_keyfile($ca['crt'], $conf, $mode_id, "ca");
- openvpn_add_keyfile($cert['crt'], $conf, $mode_id, "cert");
- openvpn_add_keyfile($cert['prv'], $conf, $mode_id, "key");
-
- if ($mode == 'server') {
- $path_ovdh = $g['varetc_path']."/openvpn/dh-parameters";
- $conf .= "dh {$path_ovdh}\n";
- }
-
- if ($settings['crl'])
- openvpn_add_keyfile($settings['crl'], $conf, $mode_id, "crl-verify");
- if ($settings['tls'])
- openvpn_add_keyfile($settings['tls'], $conf, $mode_id, "tls-auth");
+ switch($settings['mode']) {
+ case 'p2p_shared_key':
+ openvpn_add_keyfile($settings['shared_key'], $conf, $mode_id, "secret");
+ break;
+ case 'p2p_tls':
+ case 'server_tls':
+ case 'server_tls_user':
+ $ca = lookup_ca($settings['caref']);
+ openvpn_add_keyfile($ca['crt'], $conf, $mode_id, "ca");
+ case 'server_user':
+ $cert = lookup_cert($settings['certref']);
+ openvpn_add_keyfile($cert['crt'], $conf, $mode_id, "cert");
+ openvpn_add_keyfile($cert['prv'], $conf, $mode_id, "key");
+ if ($mode == 'server')
+ $conf .= "dh {$g['varetc_path']}/openvpn/dh-parameters\n";
+ if ($settings['crl'])
+ openvpn_add_keyfile($settings['crl'], $conf, $mode_id, "crl-verify");
+ if ($settings['tls'])
+ openvpn_add_keyfile($settings['tls'], $conf, $mode_id, "tls-auth");
+ break;
}
if ($settings['compression'])
OpenPOWER on IntegriCloud