net: add PPTP, L2TP and PPPoE servers from base

This commit is contained in:
Franco Fichtner 2016-06-03 10:37:44 +02:00
parent d94d9fffa8
commit deafe3eb12
26 changed files with 3722 additions and 0 deletions

8
net/l2tp/Makefile Normal file
View file

@ -0,0 +1,8 @@
PLUGIN_NAME= l2tp
PLUGIN_PRIVATE= yes
PLUGIN_VERSION= 0.1
PLUGIN_DEPENDS= mpd5
PLUGIN_COMMENT= LT2P server based on MPD5
PLUGIN_MAINTAINER= franco@opnsense.org
.include "../../Mk/plugins.mk"

View file

@ -0,0 +1,275 @@
<?php
/*
* Coypright (C) 2016 Franco Fichtner <franco@opnsense.org>
* Copyright (C) 2008 Shrew Soft Inc
* Copyright (C) 2008 Ermal Luçi
* Copyright (C) 2004 Scott Ullrich
* Copyright (C) 2003-2004 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.
*/
function if_l2tp_configure()
{
return array('if_l2tp_configure_do');
}
function if_l2tp_services()
{
global $config;
$services = array();
if (isset($config['l2tp']['mode']) && $config['l2tp']['mode'] == 'server') {
$services[] = array(
'description' => gettext('L2TP Server'),
'pidfile' => '/var/run/l2tp-vpn.pid',
'php' => array(
'restart' => array('if_l2tp_configure_do'),
'start' => array('if_l2tp_configure_do'),
),
'name' => 'l2tpd',
);
}
return $services;
}
/**
* request syslog facilities for this plugin
* @return array
*/
function if_l2tp_syslog()
{
$logfacilities = array();
$logfacilities['l2tps'] = array('facility' => array('l2tps'), 'remote' => null);
return $logfacilities;
}
function if_l2tp_link_scripts($rootdir, $logtype = 'l2tp')
{
$up = <<<'EOD'
#!/bin/sh
/usr/bin/logger -p local3.info "login,%s,$4,$5"
EOD;
$down = <<<'EOD'
#!/bin/sh
/usr/bin/logger -p local3.info "logout,%s,$4,$5"
/sbin/pfctl -i $1 -Fs
/sbin/pfctl -K $4/32
EOD;
file_put_contents($rootdir . '/linkup', sprintf($up, $logtype));
file_put_contents($rootdir . '/linkdown', sprintf($down, $logtype));
chmod($rootdir . '/linkup', 0755);
chmod($rootdir . '/linkdown', 0755);
}
function if_l2tp_configure_do()
{
global $config;
killbypid('/var/run/l2tp-vpn.pid', 'TERM', true);
mwexec('rm -rf /var/etc/l2tp-vpn');
$syscfg = $config['system'];
if (isset($config['l2tp'])) {
$l2tpcfg = $config['l2tp'];
} else {
return 0;
}
if (!isset($l2tpcfg['mode']) || $l2tpcfg['mode'] != 'server') {
return 0;
}
if (file_exists('/var/run/booting')) {
echo gettext('Configuring L2TP VPN service...');
}
switch ($l2tpcfg['mode']) {
case 'server':
mkdir('/var/etc/l2tp-vpn');
if_l2tp_link_scripts('/var/etc/l2tp-vpn');
$fd = fopen("/var/etc/l2tp-vpn/mpd.conf", "w");
if (!$fd) {
printf(gettext("Error: cannot open mpd.conf in if_l2tp_configure().") . "\n");
return 1;
}
$iprange = $l2tpcfg['remoteip'] . ' ';
$iprange .= long2ip32(ip2long($l2tpcfg['remoteip']) + $l2tpcfg['n_l2tp_units'] - 1);
$iptype = "ippool pool1";
if (isset($l2tpcfg['radius']['enable']) && isset($l2tpcfg['radius']['radiusissueips'])) {
$iptype = "0.0.0.0/0";
}
$mpdconf = <<<EOD
startup:
l2tps:
set ippool add pool1 {$iprange}
create bundle template B
set iface disable on-demand
set iface enable proxy-arp
set iface up-script /var/etc/l2tp-vpn/linkup
set iface down-script /var/etc/l2tp-vpn/linkdown
set ipcp ranges {$l2tpcfg['localip']}/32 {$iptype}
set ipcp yes vjcomp
EOD;
if (is_ipaddr($l2tpcfg['wins'])) {
$mpdconf .= " set ipcp nbns {$l2tpcfg['wins']}\n";
}
if (is_ipaddr($l2tpcfg['dns1'])) {
$mpdconf .= " set ipcp dns " . $l2tpcfg['dns1'];
if (is_ipaddr($l2tpcfg['dns2'])) {
$mpdconf .= " " . $l2tpcfg['dns2'];
}
$mpdconf .= "\n";
} elseif (isset($config['dnsmasq']['enable']) || isset($config['unbound']['enable'])) {
$mpdconf .= " set ipcp dns " . get_interface_ip("lan");
if (isset($syscfg['dnsserver'][0])) {
$mpdconf .= " " . $syscfg['dnsserver'][0];
}
$mpdconf .= "\n";
} elseif (isset($syscfg['dnsserver'][0])) {
$mpdconf .= " set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
}
if ($l2tpcfg['paporchap'] == "chap") {
$paporchap = "set link enable chap";
} else {
$paporchap = "set link enable pap";
}
$mpdconf .= <<<EOD
set bundle enable crypt-reqd
set bundle enable compression
set ccp yes mppc
create link template L l2tp
set link action bundle B
set link enable multilink
set link yes acfcomp protocomp
set link no pap chap eap
{$paporchap}
set link keep-alive 10 60
set link mtu 1460
set l2tp self ${l2tpcfg['localip']}
set link enable incoming
EOD;
if (!empty($l2tpcfg['secret'])) {
$mpdconf .= " set l2tp secret {$l2tpcfg['secret']}\n";
}
if (isset($l2tpcfg['radius']['enable'])) {
$mpdconf .=<<<EOD
set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
set radius retries 3
set radius timeout 10
set auth enable radius-auth
EOD;
if (isset($l2tpcfg['radius']['accounting'])) {
$mpdconf .=<<<EOD
set auth enable radius-acct
EOD;
}
}
fwrite($fd, $mpdconf);
fclose($fd);
unset($mpdconf);
$fd = fopen("/var/etc/l2tp-vpn/mpd.secret", "w");
if (!$fd) {
printf(gettext("Error: cannot open mpd.secret in if_l2tp_configure().") . "\n");
return 1;
}
$mpdsecret = "\n\n";
if (is_array($l2tpcfg['user'])) {
foreach ($l2tpcfg['user'] as $user) {
$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
}
}
fwrite($fd, $mpdsecret);
fclose($fd);
unset($mpdsecret);
chmod('/var/etc/l2tp-vpn/mpd.secret', 0600);
legacy_netgraph_attach(get_real_interface($l2tpcfg['interface']));
mwexec('/usr/local/sbin/mpd5 -b -d /var/etc/l2tp-vpn -p /var/run/l2tp-vpn.pid -s l2tps l2tps');
break;
}
if (file_exists('/var/run/booting')) {
echo gettext("done") . "\n";
}
return 0;
}
function l2tp_interfaces()
{
global $config;
$interfaces = array();
if (isset($config['l2tp']['mode']) && $config['l2tp']['mode'] == 'server') {
$oic = array("enable" => true);
$oic['virtual'] = true;
$oic['networks'] = array();
$oic['if'] = 'l2tp';
$oic['descr'] = 'L2TP';
$mask = !empty($config['l2tp']['l2tp_subnet']) ? $config['l2tp']['l2tp_subnet'] : 32;
$oic['networks'][] = array("network" => gen_subnet($config['l2tp']['remoteip'], $mask), "mask" => $mask);
$interfaces['l2tp'] = $oic;
}
return $interfaces;
}

View file

@ -0,0 +1,31 @@
<acl>
<!-- unique acl key, must be globally unique for all acl's -->
<page-diagnostics-logs-l2tp>
<name>WebCfg - Diagnostics: Logs: L2TP page</name>
<description>Allow access to the 'Diagnostics: Logs: L2TP' page.</description>
<patterns>
<pattern>diag_logs_l2tp.php*</pattern>
</patterns>
</page-diagnostics-logs-l2tp>
<page-vpn-vpnl2tp>
<name>WebCfg - VPN: L2TP page</name>
<description>Allow access to the 'VPN: L2TP' page.</description>
<patterns>
<pattern>vpn_l2tp.php*</pattern>
</patterns>
</page-vpn-vpnl2tp>
<page-vpn-vpnl2tp-users-edit>
<name>WebCfg - VPN: L2TP: Users : Edit page</name>
<description>Allow access to the 'VPN: L2TP: Users : Edit' page.</description>
<patterns>
<pattern>vpn_l2tp_users_edit.php*</pattern>
</patterns>
</page-vpn-vpnl2tp-users-edit>
<page-vpn-vpnl2tp-users>
<name>WebCfg - VPN: L2TP: Users page</name>
<description>Allow access to the 'VPN: L2TP : Users' page.</description>
<patterns>
<pattern>vpn_l2tp_users.php*</pattern>
</patterns>
</page-vpn-vpnl2tp-users>
</acl>

View file

@ -0,0 +1,13 @@
<menu>
<VPN>
<L2TP cssClass="fa fa-unlock fa-fw" order="100">
<Settings order="10" url="/vpn_l2tp.php"/>
<Users order="20" url="/vpn_l2tp_users.php">
<Edit url="/vpn_l2tp_users_edit.php*" visibility="hidden"/>
</Users>
<LogFile order="30" VisibleName="Log File" url="/diag_logs_l2tp.php">
<Type url="/diag_logs_l2tp.php*" visibility="hidden"/>
</LogFile>
</L2TP>
</VPN>
</menu>

View file

@ -0,0 +1,126 @@
<?php
/*
Copyright (C) 2014-2016 Deciso B.V.
Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
require_once("guiconfig.inc");
require_once("system.inc");
require_once('services.inc');
require_once('plugins.inc');
require_once("interfaces.inc");
if (empty($config['syslog']['nentries'])) {
$nentries = 50;
} else {
$nentries = $config['syslog']['nentries'];
}
if ($_POST['clear']) {
clear_clog($logfile);
}
function dump_clog_vpn($file, $tail, $type)
{
global $config;
$sort = isset($config['syslog']['reverse']) ? '-r' : '';
$logarr = array();
exec("/usr/local/sbin/clog " . escapeshellarg($file) . " | tail {$sort} -n " . escapeshellarg($tail), $logarr);
foreach ($logarr as $logent) {
$logent = preg_split('/\s+/', $logent, 6);
$llent = explode(',', $logent[5]);
if ($llent[1] !== $type) {
continue;
}
echo "<tr>\n";
echo "<td class=\"listlr nowrap\">" . htmlspecialchars(join(" ", array_slice($logent, 0, 3))) . "</td>\n";
if ($llent[0] == "login") {
echo "<td class=\"listr\"><span class=\"glyphicon glyphicon-arrow-right\" aria-hidden=\"true\" alt=\"in\"></span></td>\n";
} else {
echo "<td class=\"listr\"><span class=\"glyphicon glyphicon-arrow-left\" aria-hidden=\"true\" alt=\"out\"></span></td>\n";
}
echo "<td class=\"listr\">" . htmlspecialchars($llent[3]) . "</td>\n";
echo "<td class=\"listr\">" . htmlspecialchars($llent[2]) . "&nbsp;</td>\n";
echo "</tr>\n";
}
}
include("head.inc");
?>
<body>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<section class="col-xs-12">
<div class="tab-content content-box col-xs-12">
<div class="table-responsive">
<table class="table table-striped table-sort">
<tr>
<td colspan="4">
<ul class="nav nav-pills" role="tablist">
<?php foreach ($tab_array as $tab): ?>
<li role="presentation" <?php if (str_replace('amp;','', $tab[2]) == $_SERVER['REQUEST_URI']):?>class="active"<?php endif; ?>><a href="<?=$tab[2];?>"><?=$tab[0];?></a></li>
<?php endforeach; ?>
</ul>
</td>
</tr>
<?php if ($mode != "raw"): ?>
<tr>
<td class="listhdrr"><?=gettext("Time");?></td>
<td class="listhdrr"><?=gettext("Action");?></td>
<td class="listhdrr"><?=gettext("User");?></td>
<td class="listhdrr"><?=gettext("IP address");?></td>
</tr>
<?php dump_clog_vpn($logfile, $nentries, $logtype); ?>
<?php else:
dump_clog($logfile, $nentries);
endif; ?>
<tr>
<td colspan="4">
<form method="post">
<input type="hidden" name="mode" id="mode" value="<?=$mode;?>" />
<input name="clear" type="submit" class="btn" value="<?= gettext("Clear log");?>" />
</form>
</td>
</tr>
</table>
</div>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc"); ?>

View file

@ -0,0 +1,25 @@
<?php
if (htmlspecialchars($_POST['mode'])) {
$mode = htmlspecialchars($_POST['mode']);
} elseif (htmlspecialchars($_GET['mode'])) {
$mode = htmlspecialchars($_GET['mode']);
} else {
$mode = "login";
}
if ($mode != 'raw') {
$logfile = '/var/log/vpn.log';
} else {
$logfile = '/var/log/l2tps.log';
}
$logtype = 'l2tp';
$tab_array = array();
$tab_array[] = array(gettext("L2TP Logins"), $mode != "raw", "/diag_logs_l2tp.php");
$tab_array[] = array(gettext("L2TP Raw"), $mode == "raw", "/diag_logs_l2tp.php?mode=raw");
$service_hook = 'l2tpd';
require_once 'diag_logs_l2tp.inc';

View file

@ -0,0 +1,355 @@
<?php
/*
Copyright (C) 2014-2015 Deciso B.V.
Copyright (C) 2005 Scott Ullrich (sullrich@gmail.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.
*/
require_once("guiconfig.inc");
require_once("pfsense-utils.inc");
require_once("interfaces.inc");
require_once("services.inc");
require_once("system.inc");
require_once("plugins.inc");
require_once("plugins.inc.d/vpn.inc");
if (!isset($config['l2tp']['radius']) || !is_array($config['l2tp']['radius'])) {
$config['l2tp']['radius'] = array();
}
$l2tpcfg = &$config['l2tp'];
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$pconfig['remoteip'] = $l2tpcfg['remoteip'];
$pconfig['localip'] = $l2tpcfg['localip'];
$pconfig['mode'] = $l2tpcfg['mode'];
$pconfig['interface'] = $l2tpcfg['interface'];
$pconfig['l2tp_dns1'] = $l2tpcfg['dns1'];
$pconfig['l2tp_dns2'] = $l2tpcfg['dns2'];
$pconfig['wins'] = $l2tpcfg['wins'];
$pconfig['radiusenable'] = isset($l2tpcfg['radius']['enable']);
$pconfig['radacct_enable'] = isset($l2tpcfg['radius']['accounting']);
$pconfig['radiusserver'] = $l2tpcfg['radius']['server'];
$pconfig['radiussecret'] = $l2tpcfg['radius']['secret'];
$pconfig['radiusissueips'] = isset($l2tpcfg['radius']['radiusissueips']);
$pconfig['n_l2tp_units'] = $l2tpcfg['n_l2tp_units'];
$pconfig['paporchap'] = $l2tpcfg['paporchap'];
$pconfig['secret'] = $l2tpcfg['secret'];
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
unset($input_errors);
$pconfig = $_POST;
/* input validation */
if ($_POST['mode'] == "server") {
$reqdfields = explode(" ", "localip remoteip");
$reqdfieldsn = array(gettext("Server address"),gettext("Remote start address"));
if ($_POST['radiusenable']) {
$reqdfields = array_merge($reqdfields, explode(" ", "radiusserver radiussecret"));
$reqdfieldsn = array_merge(
$reqdfieldsn,
array(gettext("RADIUS server address"),gettext("RADIUS shared secret"))
);
}
do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
if ($_POST['localip'] && !is_ipaddr($_POST['localip'])) {
$input_errors[] = gettext("A valid server address must be specified.");
}
if ($_POST['localip'] && !is_ipaddr($_POST['remoteip'])) {
$input_errors[] = gettext("A valid remote start address must be specified.");
}
if ($_POST['radiusserver'] && !is_ipaddr($_POST['radiusserver'])) {
$input_errors[] = gettext("A valid RADIUS server address must be specified.");
}
if (!$input_errors) {
$subnet_start = ip2ulong($_POST['remoteip']);
$subnet_end = ip2ulong($_POST['remoteip']) + $_POST['n_l2tp_units'] - 1;
if ((ip2ulong($_POST['localip']) >= $subnet_start) &&
(ip2ulong($_POST['localip']) <= $subnet_end)) {
$input_errors[] = gettext("The specified server address lies in the remote subnet.");
}
}
}
if (!$input_errors) {
$l2tpcfg['remoteip'] = $_POST['remoteip'];
$l2tpcfg['localip'] = $_POST['localip'];
$l2tpcfg['mode'] = $_POST['mode'];
$l2tpcfg['interface'] = $_POST['interface'];
$l2tpcfg['n_l2tp_units'] = $_POST['n_l2tp_units'];
$l2tpcfg['radius']['server'] = $_POST['radiusserver'];
$l2tpcfg['radius']['secret'] = $_POST['radiussecret'];
$l2tpcfg['secret'] = $_POST['secret'];
if ($_POST['wins']) {
$l2tpcfg['wins'] = $_POST['wins'];
} else {
unset($l2tpcfg['wins']);
}
$l2tpcfg['paporchap'] = $_POST['paporchap'];
if ($_POST['l2tp_dns1'] == "") {
if (isset($l2tpcfg['dns1'])) {
unset($l2tpcfg['dns1']);
}
} else {
$l2tpcfg['dns1'] = $_POST['l2tp_dns1'];
}
if ($_POST['l2tp_dns2'] == "") {
if (isset($l2tpcfg['dns2'])) {
unset($l2tpcfg['dns2']);
}
} else {
$l2tpcfg['dns2'] = $_POST['l2tp_dns2'];
}
if ($_POST['radiusenable'] == "yes") {
$l2tpcfg['radius']['enable'] = true;
} else {
unset($l2tpcfg['radius']['enable']);
}
if ($_POST['radacct_enable'] == "yes") {
$l2tpcfg['radius']['accounting'] = true;
} else {
unset($l2tpcfg['radius']['accounting']);
}
if ($_POST['radiusissueips'] == "yes") {
$l2tpcfg['radius']['radiusissueips'] = true;
} else {
unset($l2tpcfg['radius']['radiusissueips']);
}
write_config();
vpn_l2tp_configure();
header("Location: vpn_l2tp.php");
exit;
}
}
$service_hook = 'l2tpd';
legacy_html_escape_form_data($pconfig);
include("head.inc");
?>
<body>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<?php if (isset($input_errors) && count($input_errors) > 0) {
print_input_errors($input_errors);
}
if (isset($savemsg)) {
print_info_box($savemsg);
}
?>
<section class="col-xs-12">
<div class="tab-content content-box col-xs-12">
<form method="post" name="iform" id="iform">
<div class="table-responsive">
<table class="table table-striped opnsense_standard_table_form">
<tr>
<td width="22%"><b><?=gettext("L2TP settings"); ?></b></td>
<td width="78%" align="right">
<small><?=gettext("full help"); ?> </small>
<i class="fa fa-toggle-off text-danger" style="cursor: pointer;" id="show_all_help_page" type="button"></i>
</td>
</tr>
<tr>
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Mode");?></td>
<td>
<input name="mode" type="radio" value="off" <?=($pconfig['mode'] != 'server') ? 'checked="checked"' : '';?>/>
<?=gettext("Off"); ?>
&nbsp;
<input type="radio" name="mode" value="server" <?=$pconfig['mode'] == 'server' ? 'checked="checked"' : '';?>/>
<?=gettext("Enable L2TP server"); ?></td>
</td>
</tr>
<tr>
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Interface");?></td>
<td>
<select name="interface" class="form-control" id="interface">
<?php
foreach (get_configured_interface_with_descr() as $iface => $ifacename) :?>
<option value="<?=$iface;?>" <?=$iface == $pconfig['interface'] ? "selected=\"selected\"" : "";?>>
<?=htmlspecialchars($ifacename);?>
</option>
<?php
endforeach; ?>
</select>
</td>
</tr>
<tr>
<td><a id="help_for_localip" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Server Address");?></td>
<td>
<input name="localip" type="text" id="localip" value="<?=$pconfig['localip'];?>" />
<div class="hidden" for="help_for_localip">
<?=gettext("Enter the IP address the L2TP server should give to clients for use as their \"gateway\"."); ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_remoteip" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Remote Address Range");?></td>
<td>
<input name="remoteip" type="text" id="remoteip" value="<?=$pconfig['remoteip'];?>" />
<div class="hidden" for="help_for_remoteip">
<?=gettext("Specify the starting address for the client IP address subnet.");?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_n_l2tp_units" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Number of L2TP users"); ?></td>
<td>
<select id="n_l2tp_units" name="n_l2tp_units">
<?php
$toselect = ($pconfig['n_l2tp_units'] > 0) ? $pconfig['n_l2tp_units'] : 16;
for ($x=1; $x<255; $x++) {
if ($x == $toselect) {
$SELECTED = " selected=\"selected\"";
} else {
$SELECTED = "";
}
echo "<option value=\"{$x}\"{$SELECTED}>{$x}</option>\n";
}
?>
</select>
<div class="hidden" for="help_for_n_l2tp_units">
<?=gettext("Hint: 10 is ten L2TP clients"); ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_secret" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Secret");?></td>
<td>
<input type="password" name="secret" id="secret" value="<?=$pconfig['secret']; ?>" />
<div class="hidden" for="help_for_secret">
<?=gettext("Specify optional secret shared between peers. Required on some devices/setups.");?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_paporchap" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Authentication Type");?></td>
<td>
<select name="paporchap" id="paporchap">
<option value='chap' <?=$pconfig['paporchap'] == "chap" ? " selected=\"selected\"" : "";?>>
<?=gettext("CHAP"); ?>
</option>
<option value='pap' <?=$pconfig['paporchap'] == "pap" ? " selected=\"selected\"" :"";?>>
<?=gettext("PAP"); ?>
</option>
</select>
<div class="hidden" for="help_for_paporchap">
<?=gettext("Specifies which protocol to use for authentication.");?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_l2tp_dns" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("L2TP DNS Servers"); ?></td>
<td>
<input name="l2tp_dns1" type="text" id="l2tp_dns1" value="<?=$pconfig['l2tp_dns1'];?>" /><br/>
<input name="l2tp_dns2" type="text" id="l2tp_dns2" value="<?=$pconfig['l2tp_dns2'];?>" />
<div class="hidden" for="help_for_l2tp_dns">
<?=gettext("primary and secondary DNS servers assigned to L2TP clients"); ?>
</div>
</td>
</tr>
<tr>
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("WINS Server"); ?></td>
<td>
<input type="text" name="wins" id="wins" value="<?=$pconfig['wins'];?>" />
</td>
</tr>
<tr>
<td><a id="help_for_radius" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("RADIUS"); ?></td>
<td>
<input name="radiusenable" type="checkbox" id="radiusenable" value="yes" <?=($pconfig['radiusenable']) ? "checked=\"checked\"" : "";?>/>
<strong> <?=gettext("Use a RADIUS server for authentication");?><br /></strong>
<div class="hidden" for="help_for_radius">
<?=gettext("When set, all users will be authenticated using the RADIUS server specified below. The local user database will not be used.");?>
</div>
<input name="radacct_enable" type="checkbox" id="radacct_enable" value="yes" <?=($pconfig['radacct_enable']) ? "checked=\"checked\"" : "";?>/>
<strong><?=gettext("Enable RADIUS accounting");?></strong><br />
<div class="hidden" for="help_for_radius">
<?=gettext("Sends accounting packets to the RADIUS server.");?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_radiusserver" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("RADIUS Server");?></td>
<td>
<input name="radiusserver" type="text" id="radiusserver" value="<?=$pconfig['radiusserver'];?>" />
<div class="hidden" for="help_for_radiusserver">
<?=gettext("Enter the IP address of the RADIUS server.");?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_radiussecret" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("RADIUS Shared Secret");?></td>
<td>
<input name="radiussecret" type="password" class="form-control pwd" id="radiussecret" value="<?=$pconfig['radiussecret'];?>" />
<div class="hidden" for="help_for_radiussecret">
<?=gettext("Enter the shared secret that will be used to authenticate to the RADIUS server.");?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_radiusissueips" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("RADIUS Issued IP's");?></td>
<td>
<input name="radiusissueips" value="yes" type="checkbox" class="form-control" id="radiusissueips"<?=$pconfig['radiusissueips'] ? " checked=\"checked\"" : "";?>>
<div class="hidden" for="help_for_radiusissueips">
<?=gettext("Issue IP Addresses via RADIUS server.");?>
</div>
</td>
</tr>
<tr>
<td></td>
<td width="78%">
<input id="submit" name="Submit" type="submit" class="btn btn-primary" value="<?=gettext("Save"); ?>" />
</td>
</tr>
<tr>
<td colspan="2">
<?=gettext("Don't forget to add a firewall rule to permit traffic from L2TP clients!");?>
</td>
</tr>
</table>
</div>
</form>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc");

View file

@ -0,0 +1,147 @@
<?php
/*
Copyright (C) 2014-2016 Deciso B.V.
Copyright (C) 2005 Scott Ullrich (sullrich@gmail.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.
*/
require_once("guiconfig.inc");
require_once("services.inc");
require_once("system.inc");
require_once("plugins.inc");
require_once("plugins.inc.d/vpn.inc");
if (!isset($config['l2tp']['user'])) {
$config['l2tp']['user'] = array();
}
$a_secret = &$config['l2tp']['user'];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// delete entry
if (isset($_POST['act']) && $_POST['act'] == "del" && isset($_POST['id'])) {
if (!empty($a_secret[$_POST['id']])) {
unset($a_secret[$_POST['id']]);
write_config();
}
exit;
} elseif (!empty($_POST['apply'])) {
vpn_l2tp_configure();
clear_subsystem_dirty('l2tpusers');
header("Location: vpn_l2tp_users.php");
exit;
}
}
$service_hook = 'l2tpd';
include("head.inc");
$main_buttons = array(
array('label'=>gettext("add user"), 'href'=>'vpn_l2tp_users_edit.php'),
);
?>
<body>
<script type="text/javascript">
$( document ).ready(function() {
// delete host action
$(".act_delete_user").click(function(event){
event.preventDefault();
var id = $(this).data("id");
// delete single
BootstrapDialog.show({
type:BootstrapDialog.TYPE_DANGER,
title: "<?=gettext("delete user"); ?>",
message: "<?=gettext("Do you really want to delete this user?");?>",
buttons: [{
label: "<?= gettext("No");?>",
action: function(dialogRef) {
dialogRef.close();
}}, {
label: "<?= gettext("Yes");?>",
action: function(dialogRef) {
$.post(window.location, {act: 'del', id:id}, function(data) {
location.reload();
});
}
}]
});
});
});
</script>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<?php
if (isset($savemsg)) {
print_info_box($savemsg);
}
if (isset($config['l2tp']['radius']['enable'])) {
print_info_box(gettext("Warning: RADIUS is enabled. The local user database will not be used."));
}
if (is_subsystem_dirty('l2tpusers')) :?><br/>
<?php print_info_box_apply(gettext("The l2tp user list has been modified") . ".<br />" . gettext("You must apply the changes in order for them to take effect") . ".<br /><b>" . gettext("Warning: this will terminate all current l2tp sessions!") . "</b>");?>
<?php
endif; ?>
<section class="col-xs-12">
<div class="tab-content content-box col-xs-12">
<form method="post" name="iform" id="iform">
<div class="table-responsive">
<table class="table table-striped">
<tr>
<td><?=gettext("Username");?></td>
<td><?=gettext("IP address");?></td>
<td></td>
</tr>
<?php
$i = 0;
foreach ($a_secret as $secretent) :?>
<tr>
<td><?=htmlspecialchars($secretent['name']);?></td>
<td>
<?php
if ($secretent['ip'] == "") {
$secretent['ip'] = "Dynamic";
} ?>
<?=htmlspecialchars($secretent['ip']);?>&nbsp;
</td>
<td>
<a href="vpn_l2tp_users_edit.php?id=<?=$i;?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-edit"></span></a>
<button data-id="<?=$i;?>" type="button" class="act_delete_user btn btn-xs btn-default"><span class="fa fa-trash text-muted"></span></button>
</td>
</tr>
<?php
$i++;
endforeach; ?>
</table>
</div>
</form>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc");

View file

@ -0,0 +1,214 @@
<?php
/*
Copyright (C) 2014-2016 Deciso B.V.
Copyright (C) 2006 Scott Ullrich (sullrich@gmail.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.
*/
function l2tpusercmp($a, $b)
{
return strcasecmp($a['name'], $b['name']);
}
function l2tp_users_sort()
{
global $config;
if (!is_array($config['l2tp']['user'])) {
return;
}
usort($config['l2tp']['user'], "l2tpusercmp");
}
require_once("guiconfig.inc");
require_once("services.inc");
require_once("system.inc");
require_once("plugins.inc");
require_once("plugins.inc.d/vpn.inc");
if (empty($config['l2tp']['user']) || !is_array($config['l2tp']['user'])) {
$config['l2tp']['user'] = array();
}
$a_secret = &$config['l2tp']['user'];
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
if (isset($_GET['id']) && !empty($a_secret[$_GET['id']])) {
$id = $_GET['id'];
}
if (isset($id)) {
$pconfig['usernamefld'] = $a_secret[$id]['name'];
$pconfig['ip'] = $a_secret[$id]['ip'];
} else {
$pconfig['usernamefld'] = null;
$pconfig['ip'] = null;
}
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['id']) && !empty($a_secret[$_POST['id']])) {
$id = $_POST['id'];
}
unset($input_errors);
$pconfig = $_POST;
/* input validation */
if (isset($id) && ($a_secret[$id])) {
$reqdfields = explode(" ", "usernamefld");
$reqdfieldsn = array(gettext("Username"));
} else {
$reqdfields = explode(" ", "usernamefld passwordfld");
$reqdfieldsn = array(gettext("Username"),gettext("Password"));
}
do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['usernamefld'])) {
$input_errors[] = gettext("The username contains invalid characters.");
}
if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['passwordfld'])) {
$input_errors[] = gettext("The password contains invalid characters.");
}
if (($_POST['passwordfld']) && ($_POST['passwordfld'] != $_POST['password2'])) {
$input_errors[] = gettext("The passwords do not match.");
}
if (($_POST['ip'] && !is_ipaddr($_POST['ip']))) {
$input_errors[] = gettext("The IP address entered is not valid.");
}
if (!$input_errors && !(isset($id) && $a_secret[$id])) {
/* make sure there are no dupes */
foreach ($a_secret as $secretent) {
if ($secretent['name'] == $_POST['usernamefld']) {
$input_errors[] = gettext("Another entry with the same username already exists.");
break;
}
}
}
if (!$input_errors) {
if (isset($id) && $a_secret[$id]) {
$secretent = $a_secret[$id];
}
$secretent['name'] = $_POST['usernamefld'];
$secretent['ip'] = $_POST['ip'];
if ($_POST['passwordfld']) {
$secretent['password'] = $_POST['passwordfld'];
}
if (isset($id) && $a_secret[$id]) {
$a_secret[$id] = $secretent;
} else {
$a_secret[] = $secretent;
}
l2tp_users_sort();
write_config();
vpn_l2tp_configure();
header("Location: vpn_l2tp_users.php");
exit;
}
}
$service_hook = 'l2tpd';
legacy_html_escape_form_data($pconfig);
include("head.inc");
?>
<body>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<?php
if (isset($input_errors) && count($input_errors) > 0) {
print_input_errors($input_errors);
} ?>
<section class="col-xs-12">
<div class="tab-content content-box col-xs-12">
<form method="post" name="iform" id="iform">
<div class="table-responsive">
<table class="table table-striped opnsense_standard_table_form">
<tr>
<td width="22%">
<strong><?=gettext("Edit User");?></strong>
</td>
<td width="78%" align="right">
<small><?=gettext("full help"); ?> </small>
<i class="fa fa-toggle-off text-danger" style="cursor: pointer;" id="show_all_help_page"></i>
</td>
</tr>
<tr>
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Username");?></td>
<td>
<input name="usernamefld" type="text" value="<?=$pconfig['usernamefld'];?>" />
</td>
</tr>
<tr>
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Password");?></td>
<td>
<input name="passwordfld" type="password" /><br />
<input name="password2" type="password" />
&nbsp;(<?=gettext("confirmation");?>)
<?php if (isset($id)):?><br />
<div class="text-muted"><em><small><?=gettext("If you want to change the users password, enter it here twice.");?></small></em></div>
<?php endif; ?>
</td>
</tr>
<tr>
<td><a id="help_for_ip" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("IP address");?></td>
<td>
<input name="ip" type="text" value="<?=$pconfig['ip'];?>" />
<div class="hidden" for="help_for_ip">
<?=gettext("If you want the user to be assigned a specific IP address, enter it here.");?>
</div>
</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>
<input id="submit" name="Submit" type="submit" class="btn btn-primary" value="<?=gettext('Save');?>" />
<input type="button" class="btn btn-default" value="<?=gettext("Cancel");?>" onclick="window.location.href='<?=(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/vpn_l2tp_users.php');?>'" />
<?php if (isset($id)) :?>
<input name="id" type="hidden" value="<?=$id;?>" />
<?php endif; ?>
</td>
</tr>
</table>
</div>
</form>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc");

8
net/pppoe/Makefile Normal file
View file

@ -0,0 +1,8 @@
PLUGIN_NAME= pppoe
PLUGIN_PRIVATE= yes
PLUGIN_VERSION= 0.1
PLUGIN_DEPENDS= mpd5
PLUGIN_COMMENT= PPPoE server based on MPD5
PLUGIN_MAINTAINER= franco@opnsense.org
.include "../../Mk/plugins.mk"

View file

@ -0,0 +1,325 @@
<?php
/*
* Coypright (C) 2016 Franco Fichtner <franco@opnsense.org>
* Copyright (C) 2008 Shrew Soft Inc
* Copyright (C) 2008 Ermal Luçi
* Copyright (C) 2004 Scott Ullrich
* Copyright (C) 2003-2004 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.
*/
function if_pppoe_configure()
{
return array('if_pppoe_configure_do');
}
function if_pppoe_services()
{
global $config;
$services = array();
if (isset($config['pppoes']['pppoe'])) {
foreach ($config['pppoes']['pppoe'] as $pppoecfg) {
if (isset($pppoecfg['mode']) && $pppoecfg['mode'] == 'server') {
$services[] = array(
/* XXX clean up name printing */
'description' => gettext('PPPoE Server') . ': ' . htmlspecialchars($pppoecfg['descr']),
'php' => array(
'restart' => array('if_pppoe_configure_by_id'),
'start' => array('if_pppoe_configure_by_id'),
'args' => array('id'),
),
'pidfile' => "/var/run/pppoe{$pppoecfg['pppoeid']}-vpn.pid",
'id' => $pppoecfg['pppoeid'],
'name' => 'pppoed',
);
}
}
}
return $services;
}
/**
* request syslog facilities for this plugin
* @return array
*/
function if_pppoe_syslog()
{
$logfacilities = array();
$logfacilities['poes'] = array('facility' => array('poes'), 'remote' => null);
return $logfacilities;
}
function if_pppoe_link_scripts($rootdir, $logtype = 'poes')
{
$up = <<<'EOD'
#!/bin/sh
/usr/bin/logger -p local3.info "login,%s,$4,$5"
EOD;
$down = <<<'EOD'
#!/bin/sh
/usr/bin/logger -p local3.info "logout,%s,$4,$5"
/sbin/pfctl -i $1 -Fs
/sbin/pfctl -K $4/32
EOD;
file_put_contents($rootdir . '/linkup', sprintf($up, $logtype));
file_put_contents($rootdir . '/linkdown', sprintf($down, $logtype));
chmod($rootdir . '/linkup', 0755);
chmod($rootdir . '/linkdown', 0755);
}
function if_pppoe_configure_do()
{
global $config;
if (isset($config['pppoes']['pppoe'])) {
foreach ($config['pppoes']['pppoe'] as $pppoe) {
if_pppoe_configure_single($pppoe);
}
}
}
function if_pppoe_configure_by_id($id)
{
global $config;
$found = null;
if (isset($config['pppoes']['pppoe'])) {
foreach ($config['pppoes']['pppoe'] as $pppoe) {
if ($id != 0 && $id == $pppoe['pppoeid']) {
$found = $pppoe;
break;
}
}
}
if ($found == null) {
return;
}
if_pppoe_configure_single($found);
}
function if_pppoe_configure_single(&$pppoecfg)
{
global $config;
$syscfg = $config['system'];
killbypid("/var/run/pppoe{$pppoecfg['pppoeid']}-vpn.pid", 'TERM', true);
mwexec("rm -rf /var/etc/pppoe{$pppoecfg['pppoeid']}-vpn");
if (!isset($pppoecfg['mode']) || $pppoecfg['mode'] != 'server') {
return 0;
}
if (file_exists('/var/run/booting')) {
echo gettext("Configuring PPPoE VPN service...");
}
switch ($pppoecfg['mode']) {
case 'server':
mkdir("/var/etc/pppoe{$pppoecfg['pppoeid']}-vpn");
if_pppoe_link_scripts("/var/etc/pppoe{$pppoecfg['pppoeid']}-vpn");
$pppoe_interface = get_real_interface($pppoecfg['interface']);
$fd = fopen("/var/etc/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
if (!$fd) {
printf(gettext("Error: cannot open mpd.conf in if_pppoe_configure().") . "\n");
return 1;
}
$iprange = $pppoecfg['remoteip'] . ' ';
$iprange .= long2ip32(ip2long($pppoecfg['remoteip']) + $pppoecfg['n_pppoe_units'] - 1);
$iptype = 'ippool pool1';
if (isset($pppoecfg['radius']['server']['enable']) && isset($pppoecfg['radius']['radiusissueips'])) {
$iptype = '0.0.0.0/0';
}
$mpdconf = <<<EOD
startup:
poes:
set ippool add pool1 {$iprange}
create bundle template B
set iface up-script /var/etc/pppoe{$pppoecfg['pppoeid']}-vpn/linkup
set iface down-script /var/etc/pppoe{$pppoecfg['pppoeid']}-vpn/linkdown
set iface idle 0
set iface disable on-demand
set iface disable proxy-arp
set iface enable tcpmssfix
set iface mtu 1500
set ipcp no vjcomp
set ipcp ranges {$pppoecfg['localip']}/32 {$iptype}
EOD;
if (!empty($pppoecfg['dns1'])) {
$mpdconf .= " set ipcp dns " . $pppoecfg['dns1'];
if (!empty($pppoecfg['dns2'])) {
$mpdconf .= " " . $pppoecfg['dns2'];
}
$mpdconf .= "\n";
} elseif (isset($config['dnsmasq']['enable']) || isset($config['unbound']['enable'])) {
$mpdconf .= " set ipcp dns " . get_interface_ip("lan");
if (isset($syscfg['dnsserver'][0])) {
$mpdconf .= " " . $syscfg['dnsserver'][0];
}
$mpdconf .= "\n";
} elseif (isset($syscfg['dnsserver'][0])) {
$mpdconf .= " set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
}
$mpdconf .= <<<EOD
set bundle enable compression
set ccp yes mppc
set mppc yes e40
set mppc yes e128
set mppc yes stateless
create link template L pppoe
set link action bundle B
set link no multilink
set link disable pap
set link disable eap
set link enable chap
set link keep-alive 10 60
set link max-redial -1
set link mtu 1492
set link mru 1492
set link latency 1
set pppoe service pppoe{$pppoecfg['pppoeid']}
set pppoe iface {$pppoe_interface}
set link enable incoming
set auth max-logins 1
EOD;
if (isset($pppoecfg['radius']['server']['enable'])) {
$radiusport = "";
$radiusacctport = "";
if (isset($pppoecfg['radius']['server']['port'])) {
$radiusport = $pppoecfg['radius']['server']['port'];
}
if (isset($pppoecfg['radius']['server']['acctport'])) {
$radiusacctport = $pppoecfg['radius']['server']['acctport'];
}
$mpdconf .=<<<EOD
set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
set radius retries 3
set radius timeout 10
set auth enable radius-auth
EOD;
if (isset($pppoecfg['radius']['accounting'])) {
$mpdconf .=<<<EOD
set auth enable radius-acct
EOD;
}
}
fwrite($fd, $mpdconf);
fclose($fd);
unset($mpdconf);
if ($pppoecfg['username']) {
$fd = fopen("/var/etc/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
if (!$fd) {
printf(gettext("Error: cannot open mpd.secret in if_pppoe_configure().") . "\n");
return 1;
}
$mpdsecret = "\n\n";
if (!empty($pppoecfg['username'])) {
$item = explode(" ", $pppoecfg['username']);
foreach ($item as $userdata) {
$data = explode(":", $userdata);
$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
}
}
fwrite($fd, $mpdsecret);
fclose($fd);
unset($mpdsecret);
chmod("/var/etc/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
}
legacy_netgraph_attach($pppoe_interface);
mwexec("/usr/local/sbin/mpd5 -b -d /var/etc/pppoe{$pppoecfg['pppoeid']}-vpn -p /var/run/pppoe{$pppoecfg['pppoeid']}-vpn.pid -s poes poes");
break;
}
if (file_exists('/var/run/booting')) {
echo gettext("done") . "\n";
}
return 0;
}
function if_pppoe_interfaces()
{
global $config;
$interfaces = array();
if (isset($config['pppoes']['pppoe'])) {
$pppoeifs = array('networks' => array());
foreach($config['pppoes']['pppoe'] as $pppoe) {
if ($pppoe['mode'] == "server") {
$mask = !empty($pppoe['pppoe_subnet']) ? $pppoe['pppoe_subnet'] : 32;
$pppoeifs['networks'][] = array("network" => gen_subnet($pppoe['remoteip'], $mask), "mask" => $mask);
}
}
if (count($pppoeifs['networks'])) {
$pppoeifs['enable'] = true;
$pppoeifs['virtual'] = true;
$pppoeifs['if'] = 'pppoe';
$pppoeifs['descr'] = 'pppoe';
$interfaces['pppoe'] = $pppoeifs;
}
}
return $interfaces;
}

View file

@ -0,0 +1,24 @@
<acl>
<!-- unique acl key, must be globally unique for all acl's -->
<page-diagnostics-logs-poes>
<name>WebCfg - Diagnostics: Logs: PPPoE page</name>
<description>Allow access to the 'Diagnostics: Logs: PPPoE' page.</description>
<patterns>
<pattern>diag_logs_poes.php*</pattern>
</patterns>
</page-diagnostics-logs-poes>
<page-services-pppoeserver>
<name>WebCfg - Services: PPPoE Server page</name>
<description>Allow access to the 'Services: PPPoE Server' page.</description>
<patterns>
<pattern>vpn_pppoe.php*</pattern>
</patterns>
</page-services-pppoeserver>
<page-services-pppoeserver-edit>
<name>WebCfg - Services: PPPoE Server: Edit page</name>
<description>Allow access to the 'Services: PPPoE Server: Edit' page.</description>
<patterns>
<pattern>vpn_pppoe_edit.php*</pattern>
</patterns>
</page-services-pppoeserver-edit>
</acl>

View file

@ -0,0 +1,12 @@
<menu>
<VPN>
<PPPoE cssClass="fa fa-tty fa-fw" order="110">
<Settings order="10" url="/vpn_pppoe.php">
<Edit url="/vpn_pppoe_edit.php*" visibility="hidden"/>
</Settings>
<LogFile order="20" VisibleName="Log File" url="/diag_logs_poes.php">
<Type url="/diag_logs_poes.php*" visibility="hidden"/>
</LogFile>
</PPPoE>
</VPN>
</menu>

View file

@ -0,0 +1,126 @@
<?php
/*
Copyright (C) 2014-2016 Deciso B.V.
Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
require_once("guiconfig.inc");
require_once("system.inc");
require_once('services.inc');
require_once('plugins.inc');
require_once("interfaces.inc");
if (empty($config['syslog']['nentries'])) {
$nentries = 50;
} else {
$nentries = $config['syslog']['nentries'];
}
if ($_POST['clear']) {
clear_clog($logfile);
}
function dump_clog_vpn($file, $tail, $type)
{
global $config;
$sort = isset($config['syslog']['reverse']) ? '-r' : '';
$logarr = array();
exec("/usr/local/sbin/clog " . escapeshellarg($file) . " | tail {$sort} -n " . escapeshellarg($tail), $logarr);
foreach ($logarr as $logent) {
$logent = preg_split('/\s+/', $logent, 6);
$llent = explode(',', $logent[5]);
if ($llent[1] !== $type) {
continue;
}
echo "<tr>\n";
echo "<td class=\"listlr nowrap\">" . htmlspecialchars(join(" ", array_slice($logent, 0, 3))) . "</td>\n";
if ($llent[0] == "login") {
echo "<td class=\"listr\"><span class=\"glyphicon glyphicon-arrow-right\" aria-hidden=\"true\" alt=\"in\"></span></td>\n";
} else {
echo "<td class=\"listr\"><span class=\"glyphicon glyphicon-arrow-left\" aria-hidden=\"true\" alt=\"out\"></span></td>\n";
}
echo "<td class=\"listr\">" . htmlspecialchars($llent[3]) . "</td>\n";
echo "<td class=\"listr\">" . htmlspecialchars($llent[2]) . "&nbsp;</td>\n";
echo "</tr>\n";
}
}
include("head.inc");
?>
<body>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<section class="col-xs-12">
<div class="tab-content content-box col-xs-12">
<div class="table-responsive">
<table class="table table-striped table-sort">
<tr>
<td colspan="4">
<ul class="nav nav-pills" role="tablist">
<?php foreach ($tab_array as $tab): ?>
<li role="presentation" <?php if (str_replace('amp;','', $tab[2]) == $_SERVER['REQUEST_URI']):?>class="active"<?php endif; ?>><a href="<?=$tab[2];?>"><?=$tab[0];?></a></li>
<?php endforeach; ?>
</ul>
</td>
</tr>
<?php if ($mode != "raw"): ?>
<tr>
<td class="listhdrr"><?=gettext("Time");?></td>
<td class="listhdrr"><?=gettext("Action");?></td>
<td class="listhdrr"><?=gettext("User");?></td>
<td class="listhdrr"><?=gettext("IP address");?></td>
</tr>
<?php dump_clog_vpn($logfile, $nentries, $logtype); ?>
<?php else:
dump_clog($logfile, $nentries);
endif; ?>
<tr>
<td colspan="4">
<form method="post">
<input type="hidden" name="mode" id="mode" value="<?=$mode;?>" />
<input name="clear" type="submit" class="btn" value="<?= gettext("Clear log");?>" />
</form>
</td>
</tr>
</table>
</div>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc"); ?>

View file

@ -0,0 +1,23 @@
<?php
if (htmlspecialchars($_POST['mode'])) {
$mode = htmlspecialchars($_POST['mode']);
} elseif (htmlspecialchars($_GET['mode'])) {
$mode = htmlspecialchars($_GET['mode']);
} else {
$mode = "login";
}
if ($mode != 'raw') {
$logfile = '/var/log/vpn.log';
} else {
$logfile = '/var/log/poes.log';
}
$logtype = 'poes';
$tab_array = array();
$tab_array[] = array(gettext("PPPoE Logins"), $mode != "raw", "/diag_logs_poes.php");
$tab_array[] = array(gettext("PPPoE Raw"), $mode == "raw", "/diag_logs_poes.php?mode=raw");
require_once 'diag_logs_poes.inc';

View file

@ -0,0 +1,160 @@
<?php
/*
Copyright (C) 2014-2016 Deciso B.V.
Copyright (C) 2010 Ermal Luci
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
require_once("guiconfig.inc");
require_once("filter.inc");
require_once("plugins.inc.d/vpn.inc");
require_once("interfaces.inc");
if (empty($config['pppoes']['pppoe']) || !is_array($config['pppoes']['pppoe'])) {
$config['pppoes'] = array();
$config['pppoes']['pppoe'] = array();
}
$a_pppoes = &$config['pppoes']['pppoe'];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!empty($_POST['apply'])) {
if (file_exists('/tmp/.vpn_pppoe.apply')) {
$toapplylist = unserialize(file_get_contents('/tmp/.vpn_pppoe.apply'));
foreach ($toapplylist as $pppoeid) {
if (!is_numeric($pppoeid)) {
continue;
}
if (isset($config['pppoes']['pppoe'])) {
foreach ($config['pppoes']['pppoe'] as $pppoe) {
if ($pppoe['pppoeid'] == $pppoeid) {
vpn_pppoe_configure($pppoe);
break;
}
}
}
}
@unlink('/tmp/.vpn_pppoe.apply');
}
filter_configure();
clear_subsystem_dirty('vpnpppoe');
header("Location: vpn_pppoe.php");
exit;
} elseif (!empty($_POST['act']) && $_POST['act'] == "del") {
if (!empty($a_pppoes[$_POST['id']])) {
killbypid("/var/run/pppoe{$a_pppoes[$_POST['id']]['pppoeid']}-vpn.pid");
mwexecf('/bin/rm -r %s', "/var/etc/pppoe{$a_pppoes[$_POST['id']]['pppoeid']}");
unset($a_pppoes[$_POST['id']]);
write_config();
exit;
}
}
}
include("head.inc");
legacy_html_escape_form_data($a_pppoes);
$main_buttons = array(
array('label'=>gettext("add a new pppoe instance"), 'href'=>'vpn_pppoe_edit.php'),
);
?>
<body>
<script type="text/javascript">
$( document ).ready(function() {
// delete pppoe action
$(".act_delete_pppoe").click(function(event){
event.preventDefault();
var id = $(this).data("id");
// delete single
BootstrapDialog.show({
type:BootstrapDialog.TYPE_DANGER,
title: "<?= gettext("PPPoE");?>",
message: "<?=gettext("Do you really want to delete this entry? All elements that still use it will become invalid (e.g. filter rules)!");?>",
buttons: [{
label: "<?= gettext("No");?>",
action: function(dialogRef) {
dialogRef.close();
}}, {
label: "<?= gettext("Yes");?>",
action: function(dialogRef) {
$.post(window.location, {act: 'del', id:id}, function(data) {
location.reload();
});
}
}]
});
});
});
</script>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<?php if (is_subsystem_dirty('vpnpppoe')) : ?><br/>
<?php print_info_box_apply(gettext("The PPPoE entry list has been changed") . ".<br />" . gettext("You must apply the changes in order for them to take effect."));?>
<?php endif; ?>
<section class="col-xs-12">
<div class="content-box">
<form method="post" name="iform" id="iform">
<div class="table-responsive">
<table class="table table-striped">
<tr>
<td><?=gettext("Interface");?></td>
<td><?=gettext("Local IP");?></td>
<td><?=gettext("Number of users");?></td>
<td><?=gettext("Description");?></td>
<td>
</td>
</tr>
<?php
$i = 0;
foreach ($a_pppoes as $pppoe) :?>
<tr>
<td><?=strtoupper($pppoe['interface']);?></td>
<td><?=$pppoe['localip'];?></td>
<td><?=$pppoe['n_pppoe_units'];?></td>
<td><?=$pppoe['descr'];?></td>
<td>
<a href="vpn_pppoe_edit.php?id=<?=$i;?>" title="<?=gettext("edit pppoe instance"); ?>" class="btn btn-default btn-xs">
<span class="glyphicon glyphicon-pencil"></span>
</a>
<button data-id="<?=$i;?>" type="button" class="act_delete_pppoe btn btn-xs btn-default"><span class="fa fa-trash text-muted"></span></button>
</td>
</tr>
<?php
$i++;
endforeach; ?>
</table>
</div>
</form>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc");

View file

@ -0,0 +1,564 @@
<?php
/*
Copyright (C) 2014-2016 Deciso B.V.
Copyright (C) 2005 Scott Ullrich (sullrich@gmail.com)
Copyright (C) 2010 Ermal Luçi
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
require_once("guiconfig.inc");
require_once("interfaces.inc");
function vpn_pppoe_get_id()
{
global $config;
$vpnid = 1;
if (isset($config['pppoes']['pppoe'])) {
foreach ($config['pppoes']['pppoe'] as $pppoe) {
if ($vpnid == $pppoe['pppoeid']) {
$vpnid++;
} else {
return $vpnid;
}
}
}
return $vpnid;
}
if (empty($config['pppoes']['pppoe']) || !is_array($config['pppoes']['pppoe'])) {
$config['pppoes'] = array();
$config['pppoes']['pppoe'] = array();
}
$a_pppoes = &$config['pppoes']['pppoe'];
$copy_fields = array('remoteip', 'localip', 'mode', 'interface', 'n_pppoe_units', 'pppoe_subnet', 'dns1', 'dns2', 'descr', 'pppoeid');
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
if (isset($_GET['id']) && !empty($a_pppoes[$_GET['id']])) {
$id = $_GET['id'];
}
$pconfig = array();
foreach ($copy_fields as $fieldname) {
if (isset($id) && !empty($a_pppoes[$id][$fieldname])) {
$pconfig[$fieldname] = $a_pppoes[$id][$fieldname];
} else {
$pconfig[$fieldname] = null;
}
}
// split username / password
$pconfig['users_username'] = array();
$pconfig['users_password'] = array();
$pconfig['users_ip'] = array();
if (isset($id) && !empty($a_pppoes[$id]['username'])) {
foreach (explode(' ', $a_pppoes[$id]['username']) as $userinfo) {
$parts = explode(':', $userinfo);
$pconfig['users_username'][] = $parts[0];
$pconfig['users_password'][] = base64_decode($parts[1]);
$pconfig['users_ip'][] = !empty($parts[2]) ? $parts[2] : "";
}
}
// radius properties
$pconfig['radacct_enable'] = isset($id) && isset($a_pppoes[$id]['radius']['accounting']);
$pconfig['radiusissueips'] = isset($id) && isset($a_pppoes[$id]['radius']['radiusissueips']);
$pconfig['radiusenable'] = isset($id) && isset($a_pppoes[$id]['radius']['server']['enable']);
$pconfig['radiusserver'] = isset($id) && isset($a_pppoes[$id]['radius']['server']['ip']) ? $a_pppoes[$id]['radius']['server']['ip'] : null;
$pconfig['radiusserverport'] = isset($id) && isset($a_pppoes[$id]['radius']['server']['port']) ? $a_pppoes[$id]['radius']['server']['port'] : null;
$pconfig['radiusserveracctport'] = isset($id) && isset($a_pppoes[$id]['radius']['server']['acctport']) ? $a_pppoes[$id]['radius']['server']['acctport'] : null;
$pconfig['radiussecret'] = isset($id) && isset($a_pppoes[$id]['radius']['server']['secret']) ? $a_pppoes[$id]['radius']['server']['secret'] : null;
$pconfig['radiussecenable'] = isset($id) && isset($a_pppoes[$id]['radius']['server2']['enable']);
$pconfig['radiusserver2'] = isset($id) && isset($a_pppoes[$id]['radius']['server2']['ip']) ? $a_pppoes[$id]['radius']['server2']['ip'] : null;
$pconfig['radiusserver2port'] = isset($id) && isset($a_pppoes[$id]['radius']['server2']['port']) ? $a_pppoes[$id]['radius']['server2']['port'] : null;
$pconfig['radiusserver2acctport'] = isset($id) && isset($a_pppoes[$id]['radius']['server2']['acctport']) ? $a_pppoes[$id]['radius']['server2']['acctport'] : null;
$pconfig['radiussecret2'] = isset($id) && isset($a_pppoes[$id]['radius']['server2']['secret2']) ? $a_pppoes[$id]['radius']['server2']['secret2'] : null;
$pconfig['radius_nasip'] = isset($id) && isset($a_pppoes[$id]['radius']['nasip']) ? $a_pppoes[$id]['radius']['nasip'] : null;
$pconfig['radius_acct_update'] = isset($id) && isset($a_pppoes[$id]['radius']['acct_update']) ? $a_pppoes[$id]['radius']['acct_update'] : null;
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['id']) && !empty($a_pppoes[$_POST['id']])) {
$id = $_POST['id'];
}
$input_errors = array();
$pconfig = $_POST;
/* input validation */
foreach ($pconfig['users_username'] as $item_idx => $usr) {
if (empty($pconfig['users_password'][$item_idx])) {
$input_errors[] = sprintf(gettext("No password specified for username %s"), $usr);
}
if ($pconfig['users_ip'][$item_idx] <> "" && !is_ipaddr($pconfig['users_ip'][$item_idx])) {
$input_errors[] = sprintf(gettext("Incorrect ip address specified for username %s"), $usr);
}
}
if ($pconfig['mode'] == "server") {
$reqdfields = explode(" ", "localip remoteip");
$reqdfieldsn = array(gettext("Server address"),gettext("Remote start address"));
if (!empty($pconfig['radiusenable'])) {
$reqdfields = array_merge($reqdfields, explode(" ", "radiusserver radiussecret"));
$reqdfieldsn = array_merge(
$reqdfieldsn,
array(gettext("RADIUS server address"),gettext("RADIUS shared secret"))
);
}
do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
if (!empty($pconfig['localip']) && !is_ipaddr($pconfig['localip'])) {
$input_errors[] = gettext("A valid server address must be specified.");
}
if (!empty($pconfig['pppoe_subnet']) && !is_ipaddr($pconfig['remoteip'])) {
$input_errors[] = gettext("A valid remote start address must be specified.");
}
if (!empty($pconfig['radiusserver']) && !is_ipaddr($pconfig['radiusserver'])) {
$input_errors[] = gettext("A valid RADIUS server address must be specified.");
}
$subnet_start = ip2ulong($pconfig['remoteip']);
$subnet_end = ip2ulong($pconfig['remoteip']) + $pconfig['pppoe_subnet'] - 1;
if ((ip2ulong($pconfig['localip']) >= $subnet_start) &&
(ip2ulong($pconfig['localip']) <= $subnet_end)) {
$input_errors[] = gettext("The specified server address lies in the remote subnet.");
}
}
if (!empty($pconfig['pppoeid']) && !is_numeric($_POST['pppoeid'])) {
$input_errors[] = gettext("Wrong data submitted");
}
if (count($input_errors) == 0) {
$pppoecfg = array();
// convert user/pass/ip combination
$pconfig['username'] = array();
foreach ($pconfig['users_username'] as $item_idx => $usr) {
$user_item = $usr . ":" . base64_encode($pconfig['users_password'][$item_idx]) ;
if (!empty($pconfig['users_ip'][$item_idx])) {
$user_item .= ":".$pconfig['users_ip'][$item_idx];
}
$pconfig['username'][] = $user_item ;
}
if (count($pconfig['username']) > 0) {
$pppoecfg['username'] = implode(' ', $pconfig['username']);
}
// copy simple fields
foreach ($copy_fields as $fieldname) {
if (isset($pconfig[$fieldname]) && $pconfig[$fieldname] != "") {
$pppoecfg[$fieldname] = $pconfig[$fieldname];
}
}
// radius settings (array)
if (!empty($pconfig['radiusserver']) || !empty($pconfig['radiusserver2'])) {
$pppoecfg['radius'] = array();
$pppoecfg['radius']['server']['enable'] = !empty($pconfig['radiusenable']);
$pppoecfg['radius']['server2']['enable'] = !empty($pconfig['radiussecenable']);
$pppoecfg['radius']['accounting'] = !empty($pconfig['radacct_enable']);
$pppoecfg['radius']['radiusissueips'] = !empty($pconfig['radiusissueips']);
$pppoecfg['radius']['nasip'] = $pconfig['radius_nasip'];
$pppoecfg['radius']['acct_update'] = $pconfig['radius_acct_update'];
}
if (!empty($pconfig['radiusserver'])) {
$pppoecfg['radius']['server'] = array();
$pppoecfg['radius']['server']['ip'] = $pconfig['radiusserver'];
$pppoecfg['radius']['server']['secret'] = $pconfig['radiussecret'];
$pppoecfg['radius']['server']['port'] = $pconfig['radiusserverport'];
$pppoecfg['radius']['server']['acctport'] = $pconfig['radiusserveracctport'];
}
if (!empty($pconfig['radiusserver2'])) {
$pppoecfg['radius']['server2'] = array();
$pppoecfg['radius']['server2']['ip'] = $pconfig['radiusserver2'];
$pppoecfg['radius']['server2']['secret2'] = $pconfig['radiussecret2'];
$pppoecfg['radius']['server2']['port'] = $pconfig['radiusserver2port'];
$pppoecfg['radius']['server2']['acctport'] = $pconfig['radiusserver2acctport'];
}
if (!isset($pconfig['pppoeid'])) {
$pppoecfg['pppoeid'] = vpn_pppoe_get_id();
}
if (file_exists('/tmp/.vpn_pppoe.apply')) {
$toapplylist = unserialize(file_get_contents('/tmp/.vpn_pppoe.apply'));
} else {
$toapplylist = array();
}
$toapplylist[] = $pppoecfg['pppoeid'];
if (!isset($id)) {
$a_pppoes[] = $pppoecfg;
} else {
$a_pppoes[$id] = $pppoecfg;
}
write_config();
mark_subsystem_dirty('vpnpppoe');
file_put_contents('/tmp/.vpn_pppoe.apply', serialize($toapplylist));
header("Location: vpn_pppoe.php");
exit;
}
}
include("head.inc");
legacy_html_escape_form_data($pconfig);
?>
<body>
<?php include("fbegin.inc"); ?>
<script type="text/javascript">
$( document ).ready(function() {
/**
* Aliases
*/
function removeRow() {
if ( $('#users_table > tbody > tr').length == 1 ) {
$('#users_table > tbody > tr:last > td > input').each(function(){
$(this).val("");
});
} else {
$(this).parent().parent().remove();
}
}
// add new detail record
$("#addNew").click(function(){
// copy last row and reset values
$('#users_table > tbody').append('<tr>'+$('#users_table > tbody > tr:last').html()+'</tr>');
$('#users_table > tbody > tr:last > td > input').each(function(){
$(this).val("");
});
$(".act-removerow").click(removeRow);
});
$(".act-removerow").click(removeRow);
});
</script>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<?php
if (isset($input_errors) && count($input_errors) > 0) {
print_input_errors($input_errors);
}?>
<section class="col-xs-12">
<div class="content-box">
<form method="post" name="iform" id="iform">
<div class="table-responsive">
<table class="table table-striped opnsense_standard_table_form">
<tr>
<td width="22%"><strong><?=gettext("PPPoE server configuration");?></strong></td>
<td width="78%" align="right">
<small><?=gettext("full help"); ?> </small>
<i class="fa fa-toggle-off text-danger" style="cursor: pointer;" id="show_all_help_page" type="button"></i>
</td>
</tr>
<tr>
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Mode");?></td>
<td>
<input name="mode" type="radio" value="off" <?=$pconfig['mode'] != 'server' ? 'checked="checked"' : '';?> />
<?=gettext("Off"); ?>
&nbsp;
<input type="radio" name="mode" value="server" <?=$pconfig['mode'] == 'server' ? 'checked="checked"' : '';?>/>
<?=gettext("Enable PPPoE server"); ?></td>
</td>
</tr>
<tr>
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Interface"); ?></td>
<td>
<select name="interface" class="selectpicker" id="interface">
<?php
foreach (get_configured_interface_with_descr() as $iface => $ifacename) :?>
<option value="<?=$iface;?>" <?= $iface == $pconfig['interface'] ? "selected=\"selected\"" : "";?>>
<?=htmlspecialchars($ifacename);?>
</option>
<?php
endforeach;?>
</select>
</td>
</tr>
<tr>
<td><a id="help_for_localip" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Server address"); ?></td>
<td>
<input name="localip" type="text" value="<?=$pconfig['localip'];?>" />
<div class="hidden" for="help_for_localip">
<?=gettext("Enter the IP address the PPPoE server should give to clients for use as their \"gateway\"."); ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_n_pppoe_units" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("No. PPPoE users"); ?></td>
<td>
<select id="n_pppoe_units" name="n_pppoe_units">
<?php
$toselect = ($pconfig['n_pppoe_units'] > 0) ? $pconfig['n_pppoe_units'] : 16;
for ($x=1; $x<255; $x++):?>
<option value="<?=$x;?>" <?=$x == $toselect ? "selected=\"selected\"" : "" ;?>>
<?=$x;?>
<?php
endfor;?>
</select>
<div class="hidden" for="help_for_n_pppoe_units">
<?=gettext("Hint: 10 is ten PPPoE clients"); ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_remoteip" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Remote address range"); ?></td>
<td>
<input name="remoteip" type="text" value="<?=$pconfig['remoteip'];?>" />
<div class="hidden" for="help_for_remoteip">
<?=gettext("Specify the starting address for the client IP address subnet."); ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_pppoe_subnet" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Subnet netmask"); ?></td>
<td>
<select id="pppoe_subnet" name="pppoe_subnet">
<?php
for ($x=0; $x<33; $x++):?>
<option value="<?=$x;?>" <?=$x == $pconfig['pppoe_subnet'] ? "selected=\"selected\"" : "" ;?>>
<?=$x;?>
<?php
endfor;?>
</select>
<div class="hidden" for="help_for_pppoe_subnet">
<?=gettext("Hint: 24 is 255.255.255.0"); ?>
</div>
</td>
</tr>
<tr>
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Description"); ?></td>
<td>
<input name="descr" type="text" value="<?=$pconfig['descr'];?>" />
</td>
</tr>
<tr>
<td><a id="help_for_dns" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("DNS servers"); ?></td>
<td>
<input name="dns1" type="text" value="<?=$pconfig['dns1'];?>" />
<br />
<input name="dns2" type="text" value="<?=$pconfig['dns2'];?>" />
<div class="hidden" for="help_for_dns">
<?=gettext("If entered they will be given to all PPPoE clients, else LAN DNS and one WAN DNS will go to all clients"); ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_radiusenable" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("RADIUS"); ?></td>
<td>
<input name="radiusenable" type="checkbox" value="yes" <?=!empty($pconfig['radiusenable']) ? "checked=\"checked\"" : ""; ?>/>
<strong><?=gettext("Use a RADIUS server for authentication"); ?></strong><br/>
<div class="hidden" for="help_for_radiusenable">
<?=gettext("When set, all users will be authenticated using " .
"the RADIUS server specified below. The local user database " .
"will not be used."); ?>
</div>
<input name="radacct_enable" type="checkbox" value="yes" <?=!empty($pconfig['radacct_enable']) ? "checked=\"checked\"" : "";?> />
<strong><?=gettext("Enable RADIUS accounting"); ?> <br /></strong>
<div class="hidden" for="help_for_radiusenable">
<?=gettext("Sends accounting packets to the RADIUS server"); ?>.
</div>
<input name="radiussecenable" type="checkbox" value="yes" <?=!empty($pconfig['radiussecenable']) ? "checked=\"checked\"" : "";?> />
<strong><?=gettext("Use Backup RADIUS Server"); ?></strong><br />
<div class="hidden" for="help_for_radiusenable">
<?=gettext("When set, if primary server fails all requests will be sent via backup server"); ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_radius_nasip" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("NAS IP Address"); ?></td>
<td>
<input name="radius_nasip" type="text" id="radius_nasip" value="<?=$pconfig['radius_nasip'];?>" />
<div class="hidden" for="help_for_radius_nasip">
<?=gettext("RADIUS server NAS IP Address"); ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_radius_acct_update" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("RADIUS Accounting Update"); ?></td>
<td>
<input name="radius_acct_update" type="text" value="<?=$pconfig['radius_acct_update'];?>" />
<div class="hidden" for="help_for_radius_acct_update">
<?=gettext("RADIUS accounting update period in seconds"); ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_radiusissueips" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("RADIUS issued IPs"); ?></td>
<td>
<input name="radiusissueips" value="yes" type="checkbox" <?=!empty($pconfig['radiusissueips']) ? "checked=\"checked\"" : "";?> />
<div class="hidden" for="help_for_radiusissueips">
<?=gettext("Issue IP Addresses via RADIUS server."); ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_radiusserver" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("RADIUS server Primary"); ?></td>
<td>
<table class="table table-condensed">
<thead>
<tr>
<th><?=gettext("Server");?></th>
<th><?=gettext("Port");?></th>
<th><?=gettext("AccPort");?></th>
</tr>
</thead>
<tbody>
<tr>
<td><input name="radiusserver" type="text" value="<?=$pconfig['radiusserver'];?>" /></td>
<td><input name="radiusserverport" type="text" value="<?=$pconfig['radiusserverport'];?>" /></td>
<td><input name="radiusserveracctport" type="text" value="<?=$pconfig['radiusserveracctport'];?>" /></td>
</tr>
</tbody>
</table>
<div class="hidden" for="help_for_radiusserver">
<?=gettext("Enter the IP address, authentication port and accounting port (optional) of the RADIUS server."); ?><br />
<br /> <?=gettext("standard port 1812 and 1813 accounting"); ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_radiussecret" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("RADIUS primary shared secret"); ?></td>
<td>
<input name="radiussecret" type="password" value="<?=$pconfig['radiussecret'];?>" />
<div class="hidden" for="help_for_radiussecret">
<?=gettext("Enter the shared secret that will be used to authenticate " .
"to the RADIUS server"); ?>.
</div>
</td>
</tr>
<tr>
<td><a id="help_for_radiusserver2" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("RADIUS server Secondary"); ?></td>
<td>
<table class="table table-condensed">
<thead>
<tr>
<th><?=gettext("Server");?></th>
<th><?=gettext("Port");?></th>
<th><?=gettext("AccPort");?></th>
</tr>
</thead>
<tbody>
<tr>
<td><input name="radiusserver2" type="text" value="<?=$pconfig['radiusserver2'];?>" /></td>
<td><input name="radiusserver2port" type="text" value="<?=$pconfig['radiusserver2port'];?>" /></td>
<td><input name="radiusserver2acctport" type="text" value="<?=$pconfig['radiusserver2acctport'];?>" /></td>
</tr>
</tbody>
</table>
<div class="hidden" for="help_for_radiusserver2">
<?=gettext("Enter the IP address, authentication port and accounting port (optional) of the backup RADIUS server."); ?><br />
<br /> <?=gettext("standard port 1812 and 1813 accounting"); ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_radiussecret2" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a><?=gettext("RADIUS secondary shared secret"); ?></td>
<td>
<input name="radiussecret2" type="password" id="radiussecret2" size="20" value="<?=htmlspecialchars($pconfig['radiussecret2']);?>" />
<div class="hidden" for="help_for_radiussecret2">
<?=gettext("Enter the shared secret that will be used to authenticate " ."to the RADIUS server"); ?>.
</div>
</td>
</tr>
<tr>
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("User (s)");?></td>
<td>
<table class="table table-striped table-condensed" id="users_table">
<thead>
<tr>
<th></th>
<th><?=gettext("Username");?></th>
<th><?=gettext("Password");?></th>
<th><?=gettext("IP");?></th>
</tr>
</thead>
<tbody>
<?php
if (count($pconfig['users_username']) == 0 ) {
$pconfig['users_username'][] = "";
$pconfig['users_password'][] = "";
$pconfig['users_ip'][] = "";
}
foreach($pconfig['users_username'] as $item_idx => $user):?>
<tr>
<td>
<div style="cursor:pointer;" class="act-removerow btn btn-default btn-xs" alt="remove"><span class="glyphicon glyphicon-minus"></span></div>
</td>
<td>
<input name="users_username[]" type="text" value="<?=$user;?>" />
</td>
<td>
<input name="users_password[]" type="password" value="<?=$pconfig['users_password'][$item_idx];?>" />
</td>
<td>
<input name="users_ip[]" type="text" value="<?=$pconfig['users_ip'][$item_idx];?>" />
</td>
</tr>
<?php
endforeach;?>
</tbody>
<tfoot>
<tr>
<td colspan="4">
<div id="addNew" style="cursor:pointer;" class="btn btn-default btn-xs" alt="add"><span class="glyphicon glyphicon-plus"></span></div>
</td>
</tr>
</tfoot>
</table>
</td>
</tr>
<tr>
<td width="22%" valign="top">&nbsp;</td>
<td width="78%">
<?php
if (isset($id)) {
echo "<input type=\"hidden\" name=\"id\" id=\"id\" value=\"" . htmlspecialchars($id, ENT_QUOTES | ENT_HTML401) . "\" />";
}
if (!empty($pconfig['pppoeid'])) {
echo "<input type=\"hidden\" name=\"pppoeid\" id=\"pppoeid\" value=\"{$pconfig['pppoeid']}\" />";
}
?>
<input name="Submit" type="submit" class="btn btn-primary" value="<?=gettext("Save"); ?>" />
<a href="vpn_pppoe.php"><input name="Cancel" type="button" class="btn btn-default" value="<?=gettext("Cancel"); ?>" /></a>
</td>
</tr>
<tr>
<td colspan="2">
<?=gettext("Don't forget to add a firewall rule to permit traffic from PPPoE clients."); ?>
</td>
</tr>
</table>
</div>
</form>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc");

8
net/pptp/Makefile Normal file
View file

@ -0,0 +1,8 @@
PLUGIN_NAME= pptp
PLUGIN_PRIVATE= yes
PLUGIN_VERSION= 0.1
PLUGIN_DEPENDS= mpd5
PLUGIN_COMMENT= PPTP server based on MPD5
PLUGIN_MAINTAINER= franco@opnsense.org
.include "../../Mk/plugins.mk"

View file

@ -0,0 +1,298 @@
<?php
/*
* Coypright (C) 2016 Franco Fichtner <franco@opnsense.org>
* Copyright (C) 2008 Shrew Soft Inc
* Copyright (C) 2008 Ermal Luçi
* Copyright (C) 2004 Scott Ullrich
* Copyright (C) 2003-2004 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.
*/
function if_pptp_configure()
{
return array('if_pptp_configure_do');
}
function if_pptp_services()
{
global $config;
$services = array();
if (isset($config['pptpd']['mode']) && $config['pptpd']['mode'] == 'server') {
$services[] = array(
'description' => gettext('PPTP Server'),
'pidfile' => '/var/run/pptp-vpn.pid',
'php' => array(
'restart' => array('if_pptp_configure_do'),
'start' => array('if_pptp_configure_do'),
),
'name' => 'pptpd',
);
}
return $services;
}
/**
* request syslog facilities for this plugin
* @return array
*/
function if_pptp_syslog()
{
$logfacilities = array();
$logfacilities['pptps'] = array('facility' => array('pptps'), 'remote' => null);
return $logfacilities;
}
function if_pptp_link_scripts($rootdir, $logtype = 'pptp')
{
$up = <<<'EOD'
#!/bin/sh
/usr/bin/logger -p local3.info "login,%s,$4,$5"
EOD;
$down = <<<'EOD'
#!/bin/sh
/usr/bin/logger -p local3.info "logout,%s,$4,$5"
/sbin/pfctl -i $1 -Fs
/sbin/pfctl -K $4/32
EOD;
file_put_contents($rootdir . '/linkup', sprintf($up, $logtype));
file_put_contents($rootdir . '/linkdown', sprintf($down, $logtype));
chmod($rootdir . '/linkup', 0755);
chmod($rootdir . '/linkdown', 0755);
}
function if_pptp_configure_do()
{
global $config;
$syscfg = $config['system'];
$pptpdcfg = $config['pptpd'];
killbypid('/var/run/pptp-vpn.pid', 'TERM', true);
mwexec('rm -rf /var/etc/pptp-vpn');
if (!isset($pptpdcfg['mode']) || $pptpdcfg['mode'] != 'server') {
return 0;
}
if (file_exists('/var/run/booting')) {
echo gettext("Configuring PPTP VPN service...");
}
switch ($pptpdcfg['mode']) {
case 'server':
mkdir('/var/etc/pptp-vpn');
if_pptp_link_scripts('/var/etc/pptp-vpn');
$fd = fopen('/var/etc/pptp-vpn/mpd.conf', 'w');
if (!$fd) {
printf(gettext("Error: cannot open mpd.conf in if_pptp_configure().") . "\n");
return 1;
}
$iprange = $pptpdcfg['remoteip'] . ' ';
$iprange .= long2ip32(ip2long($pptpdcfg['remoteip']) + $pptpdcfg['n_pptp_units'] - 1);
$mpdconf = <<<EOD
startup:
pptps:
set ippool add pool1 {$iprange}
create bundle template B
set iface disable on-demand
set iface enable proxy-arp
set iface enable tcpmssfix
set iface idle 1800
set iface up-script /var/etc/pptp-vpn/linkup
set iface down-script /var/etc/pptp-vpn/linkdown
set ipcp ranges {$pptpdcfg['localip']}/32 ippool pool1
set ipcp yes vjcomp
EOD;
if (isset($pptpdcfg["wins"]) && $pptpdcfg['wins'] != "") {
$mpdconf .= " set ipcp nbns {$pptpdcfg['wins']}\n";
}
if (!empty($pptpdcfg['dns1'])) {
$mpdconf .= " set ipcp dns " . $pptpdcfg['dns1'];
if (!empty($pptpdcfg['dns2'])) {
$mpdconf .= " " . $pptpdcfg['dns2'];
}
$mpdconf .= "\n";
} elseif (isset($config['dnsmasq']['enable']) || isset($config['unbound']['enable'])) {
$mpdconf .= " set ipcp dns " . get_interface_ip("lan");
if (isset($syscfg['dnsserver'][0])) {
$mpdconf .= " " . $syscfg['dnsserver'][0];
}
$mpdconf .= "\n";
} elseif (isset($syscfg['dnsserver'][0])) {
$mpdconf .= " set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
}
$mpdconf .= <<<EOD
set bundle enable crypt-reqd
set bundle enable compression
set ccp yes mppc
set mppc yes e128
set mppc yes stateless
EOD;
if (!isset($pptpdcfg['req128'])) {
$mpdconf .=<<<EOD
set mppc yes e40
set mppc yes e56
EOD;
}
$mpdconf .= <<<EOD
create link template L pptp
set link action bundle B
set link enable multilink
set link yes acfcomp protocomp
set link no pap chap eap
set link enable chap-msv2
set link mtu 1460
set link keep-alive 10 60
set pptp self {$pptpdcfg['localip']}
set link enable incoming
EOD;
if (isset($pptpdcfg['radius']['server']['enable'])) {
$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
$acctport = $authport + 1;
$mpdconf .=<<<EOD
set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
EOD;
if (isset($pptpdcfg['radius']['server2']['enable'])) {
$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
$acctport = $authport + 1;
$mpdconf .=<<<EOD
set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
EOD;
}
$mpdconf .=<<<EOD
set radius retries 3
set radius timeout 10
set auth enable radius-auth
EOD;
if (isset($pptpdcfg['radius']['accounting'])) {
$mpdconf .=<<<EOD
set auth enable radius-acct
set radius acct-update 300
EOD;
}
}
fwrite($fd, $mpdconf);
fclose($fd);
unset($mpdconf);
$fd = fopen('/var/etc/pptp-vpn/mpd.secret', 'w');
if (!$fd) {
printf(gettext("Error: cannot open mpd.secret in if_pptp_configure().") . "\n");
return 1;
}
$mpdsecret = "";
if (is_array($pptpdcfg['user'])) {
foreach ($pptpdcfg['user'] as $user) {
$pass = str_replace('\\', '\\\\', $user['password']);
$pass = str_replace('"', '\"', $pass);
$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
}
}
fwrite($fd, $mpdsecret);
fclose($fd);
unset($mpdsecret);
chmod('/var/etc/pptp-vpn/mpd.secret', 0600);
/* fixed to WAN elsewhere, no need to extend, but at least make it work */
legacy_netgraph_attach(get_real_interface('wan'));
mwexec('/usr/local/sbin/mpd5 -b -d /var/etc/pptp-vpn -p /var/run/pptp-vpn.pid -s pptps pptps');
break;
}
if (file_exists('/var/run/booting')) {
echo gettext("done") . "\n";
}
return 0;
}
function if_pptp_interfaces()
{
global $config;
$interfaces = array();
if (isset($config['pptpd']['mode']) && $config['pptpd']['mode'] == 'server') {
$oic = array("enable" => true);
$oic['networks'] = array();
$oic['virtual'] = true;
$oic['if'] = 'pptp';
$oic['descr'] = 'pptp';
$mask = !empty($config['pptpd']['pptp_subnet']) ? $config['pptpd']['pptp_subnet'] : 32;
if (isset($config['pptpd']['n_pptp_units']) && is_numeric($config['pptpd']['n_pptp_units'])) {
$pptp_subnets = ip_range_to_subnet_array($config['pptpd']['remoteip'],
long2ip32(ip2long($config['pptpd']['remoteip'])+($config['pptpd']['n_pptp_units']-1)));
} else {
$pptp_subnets = ip_range_to_subnet_array($config['pptpd']['remoteip'],
long2ip32(ip2long($config['pptpd']['remoteip'])));
}
foreach ($pptp_subnets as $pptp_subnet) {
$snparts = explode("/", $pptp_subnet);
$oic['networks'][] = array("network" => $snparts[0], "mask" => $snparts[1]);
}
$interfaces['pptp'] = $oic;
}
return $interfaces;
}

View file

@ -0,0 +1,31 @@
<acl>
<!-- unique acl key, must be globally unique for all acl's -->
<page-diagnostics-logs-pptp>
<name>WebCfg - Diagnostics: Logs: PPTP page</name>
<description>Allow access to the 'Diagnostics: Logs: PPTP' page.</description>
<patterns>
<pattern>diag_logs_pptp.php*</pattern>
</patterns>
</page-diagnostics-logs-pptp>
<page-vpn-vpnpptp>
<name>WebCfg - VPN: PPTP page</name>
<description>Allow access to the 'VPN: PPTP' page.</description>
<patterns>
<pattern>vpn_pptp.php*</pattern>
</patterns>
</page-vpn-vpnpptp>
<page-vpn-vpnpptp-user-edit>
<name>WebCfg - VPN: PPTP: User: Edit page</name>
<description>Allow access to the 'VPN: PPTP: User: Edit' page.</description>
<patterns>
<pattern>vpn_pptp_users_edit.php*</pattern>
</patterns>
</page-vpn-vpnpptp-user-edit>
<page-vpn-vpnpptp-users>
<name>WebCfg - VPN: PPTP: Users page</name>
<description>Allow access to the 'VPN: PPTP: Users' page.</description>
<patterns>
<pattern>vpn_pptp_users.php*</pattern>
</patterns>
</page-vpn-vpnpptp-users>
</acl>

View file

@ -0,0 +1,13 @@
<menu>
<VPN>
<PPTP cssClass="fa fa-unlock fa-fw" order="120">
<Settings order="10" url="/vpn_pptp.php"/>
<Users order="20" url="/vpn_pptp_users.php">
<Edit url="/vpn_pptp_users_edit.php*" visibility="hidden"/>
</Users>
<LogFile order="30" VisibleName="Log File" url="/diag_logs_pptp.php">
<Type url="/diag_logs_pptp.php*" visibility="hidden"/>
</LogFile>
</PPTP>
</VPN>
</menu>

View file

@ -0,0 +1,126 @@
<?php
/*
Copyright (C) 2014-2016 Deciso B.V.
Copyright (C) 2003-2006 Manuel Kasper <mk@neon1.net>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
require_once("guiconfig.inc");
require_once("system.inc");
require_once('services.inc');
require_once('plugins.inc');
require_once("interfaces.inc");
if (empty($config['syslog']['nentries'])) {
$nentries = 50;
} else {
$nentries = $config['syslog']['nentries'];
}
if ($_POST['clear']) {
clear_clog($logfile);
}
function dump_clog_vpn($file, $tail, $type)
{
global $config;
$sort = isset($config['syslog']['reverse']) ? '-r' : '';
$logarr = array();
exec("/usr/local/sbin/clog " . escapeshellarg($file) . " | tail {$sort} -n " . escapeshellarg($tail), $logarr);
foreach ($logarr as $logent) {
$logent = preg_split('/\s+/', $logent, 6);
$llent = explode(',', $logent[5]);
if ($llent[1] !== $type) {
continue;
}
echo "<tr>\n";
echo "<td class=\"listlr nowrap\">" . htmlspecialchars(join(" ", array_slice($logent, 0, 3))) . "</td>\n";
if ($llent[0] == "login") {
echo "<td class=\"listr\"><span class=\"glyphicon glyphicon-arrow-right\" aria-hidden=\"true\" alt=\"in\"></span></td>\n";
} else {
echo "<td class=\"listr\"><span class=\"glyphicon glyphicon-arrow-left\" aria-hidden=\"true\" alt=\"out\"></span></td>\n";
}
echo "<td class=\"listr\">" . htmlspecialchars($llent[3]) . "</td>\n";
echo "<td class=\"listr\">" . htmlspecialchars($llent[2]) . "&nbsp;</td>\n";
echo "</tr>\n";
}
}
include("head.inc");
?>
<body>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<section class="col-xs-12">
<div class="tab-content content-box col-xs-12">
<div class="table-responsive">
<table class="table table-striped table-sort">
<tr>
<td colspan="4">
<ul class="nav nav-pills" role="tablist">
<?php foreach ($tab_array as $tab): ?>
<li role="presentation" <?php if (str_replace('amp;','', $tab[2]) == $_SERVER['REQUEST_URI']):?>class="active"<?php endif; ?>><a href="<?=$tab[2];?>"><?=$tab[0];?></a></li>
<?php endforeach; ?>
</ul>
</td>
</tr>
<?php if ($mode != "raw"): ?>
<tr>
<td class="listhdrr"><?=gettext("Time");?></td>
<td class="listhdrr"><?=gettext("Action");?></td>
<td class="listhdrr"><?=gettext("User");?></td>
<td class="listhdrr"><?=gettext("IP address");?></td>
</tr>
<?php dump_clog_vpn($logfile, $nentries, $logtype); ?>
<?php else:
dump_clog($logfile, $nentries);
endif; ?>
<tr>
<td colspan="4">
<form method="post">
<input type="hidden" name="mode" id="mode" value="<?=$mode;?>" />
<input name="clear" type="submit" class="btn" value="<?= gettext("Clear log");?>" />
</form>
</td>
</tr>
</table>
</div>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc"); ?>

View file

@ -0,0 +1,25 @@
<?php
if (htmlspecialchars($_POST['mode'])) {
$mode = htmlspecialchars($_POST['mode']);
} elseif (htmlspecialchars($_GET['mode'])) {
$mode = htmlspecialchars($_GET['mode']);
} else {
$mode = "login";
}
if ($mode != 'raw') {
$logfile = '/var/log/vpn.log';
} else {
$logfile = '/var/log/pptps.log';
}
$logtype = 'pptp';
$tab_array = array();
$tab_array[] = array(gettext("PPTP Logins"), $mode != "raw", "/diag_logs_pptp.php");
$tab_array[] = array(gettext("PPTP Raw"), $mode == "raw", "/diag_logs_pptp.php?mode=raw");
$service_hook = 'pptpd';
require_once 'diag_logs_pptp.inc';

View file

@ -0,0 +1,426 @@
<?php
/*
Copyright (C) 2014-2016 Deciso B.V.
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.
*/
require_once('guiconfig.inc');
require_once('interfaces.inc');
require_once('filter.inc');
require_once('services.inc');
require_once("system.inc");
require_once("plugins.inc");
require_once("pfsense-utils.inc");
require_once('plugins.inc.d/vpn.inc');
if (!is_array($config['pptpd']['radius'])) {
$config['pptpd']['radius'] = array();
}
$pptpcfg = &$config['pptpd'];
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$pconfig['remoteip'] = $pptpcfg['remoteip'];
$pconfig['localip'] = $pptpcfg['localip'];
$pconfig['mode'] = $pptpcfg['mode'];
$pconfig['wins'] = $pptpcfg['wins'];
$pconfig['req128'] = isset($pptpcfg['req128']);
$pconfig['n_pptp_units'] = $pptpcfg['n_pptp_units'];
$pconfig['pptp_dns1'] = $pptpcfg['dns1'];
$pconfig['pptp_dns2'] = $pptpcfg['dns2'];
$pconfig['radiusenable'] = isset($pptpcfg['radius']['server']['enable']);
$pconfig['radiusissueips'] = isset($pptpcfg['radius']['radiusissueips']);
$pconfig['radiussecenable'] = isset($pptpcfg['radius']['server2']['enable']);
$pconfig['radacct_enable'] = isset($pptpcfg['radius']['accounting']);
$pconfig['radiusserver'] = $pptpcfg['radius']['server']['ip'];
$pconfig['radiusserverport'] = $pptpcfg['radius']['server']['port'];
$pconfig['radiusserveracctport'] = $pptpcfg['radius']['server']['acctport'];
$pconfig['radiussecret'] = $pptpcfg['radius']['server']['secret'];
$pconfig['radiusserver2'] = $pptpcfg['radius']['server2']['ip'];
$pconfig['radiusserver2port'] = $pptpcfg['radius']['server2']['port'];
$pconfig['radiusserver2acctport'] = $pptpcfg['radius']['server2']['acctport'];
$pconfig['radiussecret2'] = $pptpcfg['radius']['server2']['secret2'];
$pconfig['radius_acct_update'] = $pptpcfg['radius']['acct_update'];
$pconfig['radius_nasip'] = $pptpcfg['radius']['nasip'];
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($input_errors) && count($input_errors) > 0) {
unset($input_errors);
}
$pconfig = $_POST;
/* input validation */
if ($_POST['mode'] == "server") {
$reqdfields = explode(" ", "localip remoteip");
$reqdfieldsn = array(gettext("Server address"),gettext("Remote start address"));
if ($_POST['radiusenable']) {
$reqdfields = array_merge($reqdfields, explode(" ", "radiusserver radiussecret"));
$reqdfieldsn = array_merge(
$reqdfieldsn,
array(gettext("RADIUS server address"),gettext("RADIUS shared secret"))
);
}
do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
if ($_POST['localip'] && !is_ipaddr($_POST['localip'])) {
$input_errors[] = gettext("A valid server address must be specified.");
}
if ($_POST['remoteip'] && !is_ipaddr($_POST['remoteip'])) {
$input_errors[] = gettext("A valid remote start address must be specified.");
}
if (($_POST['radiusserver'] && !is_ipaddr($_POST['radiusserver']))) {
$input_errors[] = gettext("A valid RADIUS server address must be specified.");
}
if (!$input_errors) {
$subnet_start = ip2ulong($_POST['remoteip']);
$subnet_end = ip2ulong($_POST['remoteip']) + $_POST['n_pptp_units'] - 1;
if ((ip2ulong($_POST['localip']) >= $subnet_start) &&
(ip2ulong($_POST['localip']) <= $subnet_end)) {
$input_errors[] = gettext("The specified server address lies in the remote subnet.");
}
}
} elseif (isset($config['pptpd']['mode'])) {
unset($config['pptpd']['mode']);
}
if (!$input_errors) {
$pptpcfg['remoteip'] = $_POST['remoteip'];
$pptpcfg['localip'] = $_POST['localip'];
$pptpcfg['mode'] = $_POST['mode'];
$pptpcfg['wins'] = $_POST['wins'];
$pptpcfg['n_pptp_units'] = $_POST['n_pptp_units'];
$pptpcfg['radius']['server']['ip'] = $_POST['radiusserver'];
$pptpcfg['radius']['server']['port'] = $_POST['radiusserverport'];
$pptpcfg['radius']['server']['acctport'] = $_POST['radiusserveracctport'];
$pptpcfg['radius']['server']['secret'] = $_POST['radiussecret'];
$pptpcfg['radius']['server2']['ip'] = $_POST['radiusserver2'];
$pptpcfg['radius']['server2']['port'] = $_POST['radiusserver2port'];
$pptpcfg['radius']['server2']['acctport'] = $_POST['radiusserver2acctport'];
$pptpcfg['radius']['server2']['secret2'] = $_POST['radiussecret2'];
$pptpcfg['radius']['nasip'] = $_POST['radius_nasip'];
$pptpcfg['radius']['acct_update'] = $_POST['radius_acct_update'];
if ($_POST['pptp_dns1'] == "") {
if (isset($pptpcfg['dns1'])) {
unset($pptpcfg['dns1']);
}
} else {
$pptpcfg['dns1'] = $_POST['pptp_dns1'];
}
if ($_POST['pptp_dns2'] == "") {
if (isset($pptpcfg['dns2'])) {
unset($pptpcfg['dns2']);
}
} else {
$pptpcfg['dns2'] = $_POST['pptp_dns2'];
}
if ($_POST['req128'] == "yes") {
$pptpcfg['req128'] = true;
} elseif (isset($pptpcfg['req128'])) {
unset($pptpcfg['req128']);
}
if ($_POST['radiusenable'] == "yes") {
$pptpcfg['radius']['server']['enable'] = true;
} elseif (isset($pptpcfg['radius']['server']['enable'])) {
unset($pptpcfg['radius']['server']['enable']);
}
if ($_POST['radiussecenable'] == "yes") {
$pptpcfg['radius']['server2']['enable'] = true;
} elseif (isset($pptpcfg['radius']['server2']['enable'])) {
unset($pptpcfg['radius']['server2']['enable']);
}
if ($_POST['radacct_enable'] == "yes") {
$pptpcfg['radius']['accounting'] = true;
} elseif (isset($pptpcfg['radius']['accounting'])) {
unset($pptpcfg['radius']['accounting']);
}
if ($_POST['radiusissueips'] == "yes") {
$pptpcfg['radius']['radiusissueips'] = true;
} elseif (isset($pptpcfg['radius']['radiusissueips'])) {
unset($pptpcfg['radius']['radiusissueips']);
}
write_config();
$savemsg = get_std_save_message();
vpn_pptpd_configure();
filter_configure();
}
}
$service_hook = 'pptpd';
legacy_html_escape_form_data($pconfig);
include("head.inc");
?>
<body>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<?php if (isset($input_errors) && count($input_errors) > 0) {
print_input_errors($input_errors);
} ?>
<?php if (isset($savemsg)) {
print_info_box($savemsg);
} ?>
<?php print_alert_box(
gettext(
'PPTP is not considered a secure VPN technology, because it relies upon ' .
'the compromised MS-CHAPv2 protocol. If you choose to use PPTP, be aware ' .
'that your traffic can be decrypted by virtually any third party. ' .
'It should be considered an unencrypted tunneling protocol.'
) . ' <a href="https://isc.sans.edu/diary/End+of+Days+for+MS-CHAPv2/13807">' .
gettext('Read more') . '</a>.',
'warning'
); ?>
<section class="col-xs-12">
<div class="tab-content content-box col-xs-12">
<form method="post" name="iform" id="iform">
<div class="table-responsive">
<table class="table table-striped opnsense_standard_table_form">
<tr>
<td width="22%"><b><?=gettext("PPTP settings"); ?></b></td>
<td width="78%" align="right">
<small><?=gettext("full help"); ?> </small>
<i class="fa fa-toggle-off text-danger" style="cursor: pointer;" id="show_all_help_page" type="button"></i>
</td>
</tr>
<tr>
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Mode");?></td>
<td>
<input name="mode" type="radio" value="off" <?=($pconfig['mode'] != 'server') ? 'checked="checked"' : '';?>/>
<?=gettext("Off"); ?>
&nbsp;
<input type="radio" name="mode" value="server" <?=($pconfig['mode'] == 'server') ? 'checked="checked"' : '';?>/>
<?=gettext("Enable PPTP server"); ?>
</td>
</tr>
<tr>
<td><a id="help_for_n_pptp_units" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("No. PPTP users"); ?></td>
<td>
<select id="n_pptp_units" name="n_pptp_units">
<?php
$toselect = ($pconfig['n_pptp_units'] > 0) ? $pconfig['n_pptp_units'] : 16;
for ($x=1; $x<255; $x++) {
if ($x == $toselect) {
$SELECTED = " selected=\"selected\"";
} else {
$SELECTED = "";
}
echo "<option value=\"{$x}\"{$SELECTED}>{$x}</option>\n";
}
?>
</select>
<div class="hidden" for="help_for_n_pptp_units">
<?=gettext("Hint: 10 is ten PPTP clients"); ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_localip" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Server address"); ?></td>
<td>
<input name="localip" type="text" id="localip" value="<?=$pconfig['localip'];?>" />
<div class="hidden" for="help_for_localip">
<?=gettext("Enter the IP address the PPTP server should give to clients for use as their \"gateway\"."); ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_remoteip" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Remote address range"); ?></td>
<td>
<input name="remoteip" type="text" id="remoteip" value="<?=htmlspecialchars($pconfig['remoteip']);?>" />
<div class="hidden" for="help_for_remoteip">
<?=gettext("Specify the starting address for the client IP address subnet."); ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_pptp_dns" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("PPTP DNS Servers"); ?></td>
<td>
<input name="pptp_dns1" type="text" id="pptp_dns1" value="<?=$pconfig['pptp_dns1'];?>" /><br />
<input name="pptp_dns2" type="text" id="pptp_dns2" value="<?=$pconfig['pptp_dns2'];?>" />
<div class="hidden" for="help_for_pptp_dns">
<?=gettext("primary and secondary DNS servers assigned to PPTP clients"); ?>
</div>
</td>
</tr>
<tr>
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("WINS Server"); ?></td>
<td>
<input name="wins" type="text" id="wins" value="<?=htmlspecialchars($pconfig['wins']);?>" />
</td>
</tr>
<tr>
<td><a id="help_for_radius" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("RADIUS"); ?></td>
<td>
<input name="radiusenable" type="checkbox" id="radiusenable" value="yes" <?=($pconfig['radiusenable']) ? "checked=\"checked\"" : "";?>/>
<strong><?=gettext("Use a RADIUS server for authentication"); ?></strong><br/>
<div class="hidden" for="help_for_radius">
<?=gettext("When set, all users will be authenticated using " .
"the RADIUS server specified below. The local user database " .
"will not be used."); ?>
</div>
<input name="radacct_enable" type="checkbox" id="radacct_enable" value="yes" <?=($pconfig['radacct_enable']) ? "checked=\"checked\"" : "";?>/>
<strong><?=gettext("Enable RADIUS accounting"); ?></strong><br/>
<div class="hidden" for="help_for_radius">
<?=gettext("Sends accounting packets to the RADIUS server."); ?>
</div>
<input name="radiussecenable" type="checkbox" id="radiussecenable" value="yes" <?=($pconfig['radiussecenable']) ? "checked=\"checked\"" : "";?>/>
<strong><?=gettext("Secondary RADIUS server for failover authentication"); ?></strong><br />
<div class="hidden" for="help_for_radius">
<?=gettext("When set, all requests will go to the secondary server when primary fails"); ?>
</div>
<input name="radiusissueips" value="yes" type="checkbox" id="radiusissueips"<?=($pconfig['radiusissueips']) ? " checked=\"checked\"" : "";?>/>
<strong><?=gettext("RADIUS issued IPs"); ?></strong>
<div class="hidden" for="help_for_radius">
<?=gettext("Issue IP addresses via RADIUS server."); ?>
</div>
</td>
</tr>
<tr>
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("RADIUS NAS IP"); ?></td>
<td>
<input name="radius_nasip" type="text" id="radius_nasip" value="<?=$pconfig['radius_nasip'];?>" />
</td>
</tr>
<tr>
<td><a id="help_for_radius_acct_update" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("RADIUS Accounting Update"); ?></td>
<td>
<input name="radius_acct_update" type="text" id="radius_acct_update" value="<?=$pconfig['radius_acct_update'];?>" />
<div class="hidden" for="help_for_radius_acct_update">
<?=gettext("RADIUS accounting update period in seconds"); ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_radiusserver" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("RADIUS server Primary"); ?></td>
<td>
<table class="table table-condensed">
<thead>
<tr>
<th><?=gettext("Server");?></th>
<th><?=gettext("Port");?></th>
<th><?=gettext("AccPort");?></th>
</tr>
</thead>
<tbody>
<tr>
<td><input name="radiusserver" type="text" value="<?=$pconfig['radiusserver'];?>" /></td>
<td><input name="radiusserverport" type="text" value="<?=$pconfig['radiusserverport'];?>" /></td>
<td><input name="radiusserveracctport" type="text" value="<?=$pconfig['radiusserveracctport'];?>" /></td>
</tr>
</tbody>
</table>
<div class="hidden" for="help_for_radiusserver">
<?=gettext("Enter the IP address, authentication port and accounting port (optional) of the RADIUS server."); ?><br />
<br /> <?=gettext("standard port 1812 and 1813 accounting"); ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_radiussecret" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("RADIUS primary shared secret"); ?></td>
<td>
<input name="radiussecret" type="password" value="<?=$pconfig['radiussecret'];?>" />
<div class="hidden" for="help_for_radiussecret">
<?=gettext("Enter the shared secret that will be used to authenticate " .
"to the RADIUS server"); ?>.
</div>
</td>
</tr>
<tr>
<td><a id="help_for_radiusserver2" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("RADIUS server Secondary"); ?></td>
<td>
<table class="table table-condensed">
<thead>
<tr>
<th><?=gettext("Server");?></th>
<th><?=gettext("Port");?></th>
<th><?=gettext("AccPort");?></th>
</tr>
</thead>
<tbody>
<tr>
<td><input name="radiusserver2" type="text" value="<?=$pconfig['radiusserver2'];?>" /></td>
<td><input name="radiusserver2port" type="text" value="<?=$pconfig['radiusserver2port'];?>" /></td>
<td><input name="radiusserver2acctport" type="text" value="<?=$pconfig['radiusserver2acctport'];?>" /></td>
</tr>
</tbody>
</table>
<div class="hidden" for="help_for_radiusserver2">
<?=gettext("Enter the IP address, authentication port and accounting port (optional) of the backup RADIUS server."); ?><br />
<br /> <?=gettext("standard port 1812 and 1813 accounting"); ?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_radiussecret2" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("RADIUS secondary shared secret"); ?></td>
<td>
<input name="radiussecret2" type="password" id="radiussecret2" size="20" value="<?=htmlspecialchars($pconfig['radiussecret2']);?>" />
<div class="hidden" for="help_for_radiussecret2">
<?=gettext("Enter the shared secret that will be used to authenticate " ."to the RADIUS server"); ?>.
</div>
</td>
</tr>
<tr>
<td><a id="help_for_req128" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Security");?></td>
<td>
<input name="req128" type="checkbox" id="req128" value="yes" <?=($pconfig['req128']) ? "checked=\"checked\"" : "";?> />
<strong><?=gettext("Require 128-bit encryption"); ?></strong>
<div class="hidden" for="help_for_req128">
<?=gettext("When set, only 128-bit encryption will be accepted. Otherwise " .
"40-bit and 56-bit encryption will be accepted as well. Note that " .
"encryption will always be forced on PPTP connections (i.e. " .
"unencrypted connections will not be accepted)."); ?>
</div>
</td>
</tr>
<tr>
<td></td>
<td>
<input name="Submit" type="submit" class="btn btn-primary" value="<?=gettext("Save"); ?>" />
</td>
</tr>
<tr>
<td colspan="2"><?= gettext("Don't forget to add a firewall rule to permit traffic from PPTP clients.") ?></td>
</tr>
</table>
</div>
</form>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc");

View file

@ -0,0 +1,141 @@
<?php
/*
Copyright (C) 2014-2016 Deciso B.V.
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.
*/
require_once('guiconfig.inc');
require_once('services.inc');
require_once("system.inc");
require_once("plugins.inc");
require_once('plugins.inc.d/vpn.inc');
if (!is_array($config['pptpd']['user'])) {
$config['pptpd']['user'] = array();
}
$a_secret = &$config['pptpd']['user'];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// delete entry
if (isset($_POST['act']) && $_POST['act'] == "del" && isset($_POST['id'])) {
if (!empty($a_secret[$_POST['id']])) {
unset($a_secret[$_POST['id']]);
mark_subsystem_dirty('pptpusers');
write_config();
}
exit;
} elseif (!empty($_POST['apply'])) {
vpn_pptpd_configure();
clear_subsystem_dirty('pptpusers');
header("Location: vpn_pptp_users.php");
exit;
}
}
$service_hook = 'pptpd';
include("head.inc");
$main_buttons = array(
array('label'=>gettext("add user"), 'href'=>'vpn_pptp_users_edit.php'),
);
?>
<body>
<script type="text/javascript">
$( document ).ready(function() {
// delete host action
$(".act_delete_user").click(function(event){
event.preventDefault();
var id = $(this).data("id");
// delete single
BootstrapDialog.show({
type:BootstrapDialog.TYPE_DANGER,
title: "<?=gettext("delete user"); ?>",
message: "<?=gettext("Do you really want to delete this user?");?>",
buttons: [{
label: "<?= gettext("No");?>",
action: function(dialogRef) {
dialogRef.close();
}}, {
label: "<?= gettext("Yes");?>",
action: function(dialogRef) {
$.post(window.location, {act: 'del', id:id}, function(data) {
location.reload();
});
}
}]
});
});
});
</script>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<?php
if (isset($config['pptpd']['radius']['enable'])) {
print_info_box(gettext("Warning: RADIUS is enabled. The local user database will not be used."));
}
if (is_subsystem_dirty('pptpusers')) :?><br/>
<?php print_info_box_apply(gettext("The PPTP user list has been modified").".<br />".gettext("You must apply the changes in order for them to take effect").".<br /></b><b>".gettext("Warning: this will terminate all current PPTP sessions")."!");?></b><br />
<?php
endif; ?>
<section class="col-xs-12">
<div class="tab-content content-box col-xs-12">
<form method="post" name="iform" id="iform">
<div class="table-responsive">
<table class="table table-striped table-sort">
<tr>
<td><?=gettext("Username");?></td>
<td><?=gettext("IP address");?></td>
<td></td>
</tr>
<?php
$i = 0;
foreach ($a_secret as $secretent) :?>
<tr>
<td><?=htmlspecialchars($secretent['name']);?></td>
<td><?=htmlspecialchars($secretent['ip']);?></td>
<td>
<a href="vpn_pptp_users_edit.php?id=<?=$i;?>" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-edit"></span></a>
<button data-id="<?=$i;?>" type="button" class="act_delete_user btn btn-xs btn-default"><span class="fa fa-trash text-muted"></span></button>
</td>
</tr>
<?php
$i++;
endforeach; ?>
</table>
</div>
</form>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc");

View file

@ -0,0 +1,218 @@
<?php
/*
Copyright (C) 2014-2016 Deciso B.V.
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.
*/
function pptpusercmp($a, $b)
{
return strcasecmp($a['name'], $b['name']);
}
function pptpd_users_sort()
{
global $config;
if (!is_array($config['ppptpd']['user'])) {
return;
}
usort($config['pptpd']['user'], "pptpusercmp");
}
require_once('guiconfig.inc');
require_once('services.inc');
require_once("system.inc");
require_once("plugins.inc");
require_once('plugins.inc.d/vpn.inc');
if (!is_array($config['pptpd']['user'])) {
$config['pptpd']['user'] = array();
}
$a_secret = &$config['pptpd']['user'];
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
if (isset($_GET['id']) && !empty($a_secret[$_GET['id']])) {
$id = $_GET['id'];
}
if (isset($id)) {
$pconfig['username'] = $a_secret[$id]['name'];
$pconfig['ip'] = $a_secret[$id]['ip'];
} else {
$pconfig['username'] = null;
$pconfig['ip'] = null;
}
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['id']) && !empty($a_secret[$_POST['id']])) {
$id = $_POST['id'];
}
unset($input_errors);
$pconfig = $_POST;
/* input validation */
if (isset($id) && ($a_secret[$id])) {
$reqdfields = explode(" ", "username");
$reqdfieldsn = array(gettext("Username"));
} else {
$reqdfields = explode(" ", "username password");
$reqdfieldsn = array(gettext("Username"),gettext("Password"));
}
do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['username'])) {
$input_errors[] = gettext("The username contains invalid characters.");
}
if (preg_match("/^!/", $_POST['password'])) {
$input_errors[] = gettext("The password cannot start with '!'.");
}
if (!preg_match("/^[\x20-\x7E]*$/", $_POST['password'])) {
$input_errors[] = gettext("The password contains invalid characters.");
}
if (($_POST['password']) && ($_POST['password'] != $_POST['password2'])) {
$input_errors[] = gettext("The passwords do not match.");
}
if (($_POST['ip'] && !is_ipaddr($_POST['ip']))) {
$input_errors[] = gettext("The IP address entered is not valid.");
}
if (!$input_errors && !(isset($id) && $a_secret[$id])) {
/* make sure there are no dupes */
foreach ($a_secret as $secretent) {
if ($secretent['name'] == $_POST['username']) {
$input_errors[] = gettext("Another entry with the same username already exists.");
break;
}
}
}
if (!$input_errors) {
if (isset($id) && $a_secret[$id]) {
$secretent = $a_secret[$id];
}
$secretent['name'] = $_POST['username'];
$secretent['ip'] = $_POST['ip'];
if ($_POST['password']) {
$secretent['password'] = $_POST['password'];
}
if (isset($id) && $a_secret[$id]) {
$a_secret[$id] = $secretent;
} else {
$a_secret[] = $secretent;
}
pptpd_users_sort();
write_config();
vpn_pptpd_configure();
header("Location: vpn_pptp_users.php");
exit;
}
}
$service_hook = 'pptpd';
legacy_html_escape_form_data($pconfig);
include("head.inc");
?>
<body>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<?php if (isset($input_errors) && count($input_errors) > 0) {
print_input_errors($input_errors);
} ?>
<section class="col-xs-12">
<div class="tab-content content-box col-xs-12">
<form method="post" name="iform" id="iform">
<div class="table-responsive">
<table class="table table-striped opnsense_standard_table_form">
<tr>
<td width="22%">
<strong><?=gettext("Edit User");?></strong>
</td>
<td width="78%" align="right">
<small><?=gettext("full help"); ?> </small>
<i class="fa fa-toggle-off text-danger" style="cursor: pointer;" id="show_all_help_page"></i>
</td>
</tr>
<tr>
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Username");?></td>
<td>
<input name="username" type="text" id="username" value="<?=$pconfig['username'];?>" />
</td>
</tr>
<tr>
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Password");?></td>
<td>
<input name="password" type="password" class="form-control pwd" id="password" />
<br /><input name="password2" type="password" class="form-control pwd" id="password2" />
&nbsp;(<?=gettext("confirmation");?>)
<?php
if (isset($id)) :?><br />
<?=gettext("If you want to change the users' password, ".
"enter it here twice.");?>
<?php
endif; ?>
</td>
</tr>
<tr>
<td><a id="help_for_ip" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("IP address");?></td>
<td>
<input name="ip" type="text" class="form-control unknown" id="ip" value="<?=htmlspecialchars($pconfig['ip']);?>" />
<div class="hidden" for="help_for_ip">
<?=gettext("If you want the user to be assigned a specific IP address, enter it here.");?>
</div>
</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>
<input name="Submit" type="submit" class="btn btn-primary" value="<?=gettext("Save");?>" />
<?php
if (isset($id)) :?>
<input name="id" type="hidden" value="<?=$id;?>" />
<?php
endif; ?>
</td>
</tr>
</table>
</div>
</form>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc");