From 943924c0ff41c774726357a577c6935a1df98dc4 Mon Sep 17 00:00:00 2001
From: clanto007 <44651109+clanto007@users.noreply.github.com>
Date: Tue, 15 Nov 2022 08:34:13 +0100
Subject: [PATCH] net/freeradius: Proxy Configuration Page (#3142)
---
net/freeradius/Makefile | 5 +-
net/freeradius/pkg-descr | 3 +
.../Freeradius/Api/ProxyController.php | 409 ++++++++++++++++++
.../OPNsense/Freeradius/ProxyController.php | 40 ++
.../forms/dialogEditFreeRADIUSHomeserver.xml | 140 ++++++
.../dialogEditFreeRADIUSHomeserverpool.xml | 40 ++
.../forms/dialogEditFreeRADIUSRealm.xml | 32 ++
.../OPNsense/Freeradius/forms/general.xml | 7 +
.../OPNsense/Freeradius/forms/ldap.xml | 2 +-
.../models/OPNsense/Freeradius/General.xml | 4 +
.../app/models/OPNsense/Freeradius/Ldap.xml | 2 +-
.../models/OPNsense/Freeradius/Menu/Menu.xml | 5 +
.../app/models/OPNsense/Freeradius/Proxy.php | 22 +
.../app/models/OPNsense/Freeradius/Proxy.xml | 191 ++++++++
.../app/views/OPNsense/Freeradius/proxy.volt | 237 ++++++++++
.../templates/OPNsense/Freeradius/+TARGETS | 1 +
.../templates/OPNsense/Freeradius/proxy.conf | 126 ++++++
17 files changed, 1261 insertions(+), 5 deletions(-)
create mode 100644 net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/Api/ProxyController.php
create mode 100644 net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/ProxyController.php
create mode 100644 net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/dialogEditFreeRADIUSHomeserver.xml
create mode 100644 net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/dialogEditFreeRADIUSHomeserverpool.xml
create mode 100644 net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/dialogEditFreeRADIUSRealm.xml
create mode 100644 net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Proxy.php
create mode 100644 net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Proxy.xml
create mode 100644 net/freeradius/src/opnsense/mvc/app/views/OPNsense/Freeradius/proxy.volt
create mode 100644 net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/proxy.conf
diff --git a/net/freeradius/Makefile b/net/freeradius/Makefile
index e425cc542..0d9e54433 100644
--- a/net/freeradius/Makefile
+++ b/net/freeradius/Makefile
@@ -1,8 +1,7 @@
PLUGIN_NAME= freeradius
-PLUGIN_VERSION= 1.9.21
-PLUGIN_REVISION= 1
+PLUGIN_VERSION= 1.9.22
PLUGIN_COMMENT= RADIUS Authentication, Authorization and Accounting Server
PLUGIN_DEPENDS= freeradius3
PLUGIN_MAINTAINER= m.muenz@gmail.com
-.include "../../Mk/plugins.mk"
+.include "../../Mk/plugins.mk"
\ No newline at end of file
diff --git a/net/freeradius/pkg-descr b/net/freeradius/pkg-descr
index 5b5df9231..98dabe097 100644
--- a/net/freeradius/pkg-descr
+++ b/net/freeradius/pkg-descr
@@ -14,6 +14,9 @@ The server is fast, feature-rich, modular, and scalable.
Plugin Changelog
================
+1.9.22
+
+* Add Proxy configuration page: HomeServer, HomeServerPool, Realm
1.9.21
diff --git a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/Api/ProxyController.php b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/Api/ProxyController.php
new file mode 100644
index 000000000..24baa94c6
--- /dev/null
+++ b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/Api/ProxyController.php
@@ -0,0 +1,409 @@
+
+ * 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.
+ */
+
+namespace OPNsense\Freeradius\Api;
+
+use OPNsense\Freeradius\Proxy;
+use OPNsense\Core\Config;
+use OPNsense\Base\ApiMutableModelControllerBase;
+use OPNsense\Base\UIModelGrid;
+
+class ProxyController extends ApiMutableModelControllerBase
+{
+ protected static $internalModelName = 'Proxy';
+ protected static $internalModelClass = '\OPNsense\Freeradius\Proxy';
+
+ public function getAction()
+ {
+ // define list of configurable settings
+ $result = array();
+ if ($this->request->isGet()) {
+ $mdlProxy = new Proxy();
+ $result['proxy'] = $mdlProxy->getNodes();
+ }
+ return $result;
+ }
+
+ public function setAction()
+ {
+ $result = array("result" => "failed");
+ if ($this->request->isPost()) {
+ // load model and update with provided data
+ $mdlProxy = new Proxy();
+ $mdlProxy->setNodes($this->request->getPost("proxy"));
+ // perform validation
+ $valMsgs = $mdlProxy->performValidation();
+ foreach ($valMsgs as $field => $msg) {
+ if (!array_key_exists("validations", $result)) {
+ $result["validations"] = array();
+ }
+ $result["validations"]["proxy." . $msg->getField()] = $msg->getMessage();
+ }
+ // serialize model to config and save
+ if ($valMsgs->count() == 0) {
+ $mdlProxy->serializeToConfig();
+ Config::getInstance()->save();
+ $result["result"] = "saved";
+ }
+ }
+ return $result;
+ }
+
+
+ public function searchRealmAction()
+ {
+ $this->sessionClose();
+ $mdlRealm = $this->getModel();
+ $grid = new UIModelGrid($mdlRealm->realms->realm);
+ return $grid->fetchBindRequest(
+ $this->request,
+ array("enabled", "name", "auth_pool", "acct_pool", "nostrip" )
+ );
+ }
+
+ public function getRealmAction($uuid = null)
+ {
+ $mdlRealm = $this->getModel();
+ if ($uuid != null) {
+ $node = $mdlRealm->getNodeByReference('realms.realm.' . $uuid);
+ if ($node != null) {
+ // return node
+ return array("realm" => $node->getNodes());
+ }
+ } else {
+ $node = $mdlRealm->realms->realm->add();
+ return array("realm" => $node->getNodes());
+ }
+ return array();
+ }
+
+ public function addRealmAction()
+ {
+ $result = array("result" => "failed");
+ if ($this->request->isPost() && $this->request->hasPost("realm")) {
+ $result = array("result" => "failed", "validations" => array());
+ $mdlRealm = $this->getModel();
+ $node = $mdlRealm->realms->realm->Add();
+ $node->setNodes($this->request->getPost("realm"));
+ $valMsgs = $mdlRealm->performValidation();
+ foreach ($valMsgs as $field => $msg) {
+ $fieldnm = str_replace($node->__reference, "realm", $msg->getField());
+ $result["validations"][$fieldnm] = $msg->getMessage();
+ }
+ if (count($result['validations']) == 0) {
+ unset($result['validations']);
+ // save config if validated correctly
+ $mdlRealm->serializeToConfig();
+ Config::getInstance()->save();
+ unset($result['validations']);
+ $result["result"] = "saved";
+ }
+ }
+ return $result;
+ }
+
+ public function delRealmAction($uuid)
+ {
+ $result = array("result" => "failed");
+ if ($this->request->isPost()) {
+ $mdlRealm = $this->getModel();
+ if ($uuid != null) {
+ if ($mdlRealm->realms->realm->del($uuid)) {
+ $mdlRealm->serializeToConfig();
+ Config::getInstance()->save();
+ $result['result'] = 'deleted';
+ } else {
+ $result['result'] = 'not found';
+ }
+ }
+ }
+ return $result;
+ }
+
+ public function setRealmAction($uuid)
+ {
+ if ($this->request->isPost() && $this->request->hasPost("realm")) {
+ $mdlSetting = $this->getModel();
+ if ($uuid != null) {
+ $node = $mdlSetting->getNodeByReference('realms.realm.' . $uuid);
+ if ($node != null) {
+ $result = array("result" => "failed", "validations" => array());
+ $clientInfo = $this->request->getPost("realm");
+ $node->setNodes($clientInfo);
+ $valMsgs = $mdlSetting->performValidation();
+ foreach ($valMsgs as $field => $msg) {
+ $fieldnm = str_replace($node->__reference, "realm", $msg->getField());
+ $result["validations"][$fieldnm] = $msg->getMessage();
+ }
+ if (count($result['validations']) == 0) {
+ // save config if validated correctly
+ $mdlSetting->serializeToConfig();
+ Config::getInstance()->save();
+ $result = array("result" => "saved");
+ }
+ return $result;
+ }
+ }
+ }
+ return array("result" => "failed");
+ }
+
+ public function toggle_handler($uuid, $elements, $element)
+ {
+ $result = array("result" => "failed");
+ if ($this->request->isPost()) {
+ $mdlSetting = $this->getModel();
+ if ($uuid != null) {
+ $node = $mdlSetting->getNodeByReference($elements . '.' . $element . '.' . $uuid);
+ if ($node != null) {
+ if ($node->enabled->__toString() == "1") {
+ $result['result'] = "Disabled";
+ $node->enabled = "0";
+ } else {
+ $result['result'] = "Enabled";
+ $node->enabled = "1";
+ }
+ // if item has toggled, serialize to config and save
+ $mdlSetting->serializeToConfig();
+ Config::getInstance()->save();
+ }
+ }
+ }
+ return $result;
+ }
+
+ public function toggleRealmAction($uuid)
+ {
+ return $this->toggle_handler($uuid, 'realms', 'realm');
+ }
+ public function searchHomeserverAction()
+ {
+ $this->sessionClose();
+ $mdlHomeserver = $this->getModel();
+ $grid = new UIModelGrid($mdlHomeserver->homeservers->homeserver);
+ return $grid->fetchBindRequest(
+ $this->request,
+ array("enabled", "name", "type", "addresstype", "ipaddr", "ipaddr6", "ipaddr6", "virtualserver", "port", "proto", "secret", "sourceip", "response_window", "no_response_fail", "zombieperiod", "reviveinterval", "statuscheck", "checkinterval", "numanswersalive", "max_outstanding", "limit_maxconnections", "limit_maxrequests", "limit_lifetime", "limit_idletimeout" )
+ );
+ }
+
+ public function getHomeserverAction($uuid = null)
+ {
+ $mdlHomeserver = $this->getModel();
+ if ($uuid != null) {
+ $node = $mdlHomeserver->getNodeByReference('homeservers.homeserver.' . $uuid);
+ if ($node != null) {
+ // return node
+ return array("homeserver" => $node->getNodes());
+ }
+ } else {
+ $node = $mdlHomeserver->homeservers->homeserver->add();
+ return array("homeserver" => $node->getNodes());
+ }
+ return array();
+ }
+
+ public function addHomeserverAction()
+ {
+ $result = array("result" => "failed");
+ if ($this->request->isPost() && $this->request->hasPost("homeserver")) {
+ $result = array("result" => "failed", "validations" => array());
+ $mdlHomeserver = $this->getModel();
+ $node = $mdlHomeserver->homeservers->homeserver->Add();
+ $node->setNodes($this->request->getPost("homeserver"));
+ $valMsgs = $mdlHomeserver->performValidation();
+ foreach ($valMsgs as $field => $msg) {
+ $fieldnm = str_replace($node->__reference, "homeserver", $msg->getField());
+ $result["validations"][$fieldnm] = $msg->getMessage();
+ }
+ if (count($result['validations']) == 0) {
+ unset($result['validations']);
+ // save config if validated correctly
+ $mdlHomeserver->serializeToConfig();
+ Config::getInstance()->save();
+ unset($result['validations']);
+ $result["result"] = "saved";
+ }
+ }
+ return $result;
+ }
+
+ public function delHomeserverAction($uuid)
+ {
+ $result = array("result" => "failed");
+ if ($this->request->isPost()) {
+ $mdlHomeserver = $this->getModel();
+ if ($uuid != null) {
+ if ($mdlHomeserver->homeservers->homeserver->del($uuid)) {
+ $mdlHomeserver->serializeToConfig();
+ Config::getInstance()->save();
+ $result['result'] = 'deleted';
+ } else {
+ $result['result'] = 'not found';
+ }
+ }
+ }
+ return $result;
+ }
+
+ public function setHomeserverAction($uuid)
+ {
+ if ($this->request->isPost() && $this->request->hasPost("homeserver")) {
+ $mdlSetting = $this->getModel();
+ if ($uuid != null) {
+ $node = $mdlSetting->getNodeByReference('homeservers.homeserver.' . $uuid);
+ if ($node != null) {
+ $result = array("result" => "failed", "validations" => array());
+ $clientInfo = $this->request->getPost("homeserver");
+ $node->setNodes($clientInfo);
+ $valMsgs = $mdlSetting->performValidation();
+ foreach ($valMsgs as $field => $msg) {
+ $fieldnm = str_replace($node->__reference, "homeserver", $msg->getField());
+ $result["validations"][$fieldnm] = $msg->getMessage();
+ }
+ if (count($result['validations']) == 0) {
+ // save config if validated correctly
+ $mdlSetting->serializeToConfig();
+ Config::getInstance()->save();
+ $result = array("result" => "saved");
+ }
+ return $result;
+ }
+ }
+ }
+ return array("result" => "failed");
+ }
+
+ public function toggleHomeserverAction($uuid)
+ {
+ return $this->toggle_handler($uuid, 'homeservers', 'homeserver');
+ }
+ public function searchHomeserverpoolAction()
+ {
+ $this->sessionClose();
+ $mdlHomeserverpool = $this->getModel();
+ $grid = new UIModelGrid($mdlHomeserverpool->homeserverpools->homeserverpool);
+ return $grid->fetchBindRequest(
+ $this->request,
+ array("enabled", "name", "type", "virtualserver", "virtualserver", "homeservers", "fallback" )
+ );
+ }
+
+ public function getHomeserverpoolAction($uuid = null)
+ {
+ $mdlHomeserverpool = $this->getModel();
+ if ($uuid != null) {
+ $node = $mdlHomeserverpool->getNodeByReference('homeserverpools.homeserverpool.' . $uuid);
+ if ($node != null) {
+ // return node
+ return array("homeserverpool" => $node->getNodes());
+ }
+ } else {
+ $node = $mdlHomeserverpool->homeserverpools->homeserverpool->add();
+ return array("homeserverpool" => $node->getNodes());
+ }
+ return array();
+ }
+
+ public function addHomeserverpoolAction()
+ {
+ $result = array("result" => "failed");
+ if ($this->request->isPost() && $this->request->hasPost("homeserverpool")) {
+ $result = array("result" => "failed", "validations" => array());
+ $mdlHomeserverpool = $this->getModel();
+ $node = $mdlHomeserverpool->homeserverpools->homeserverpool->Add();
+ $node->setNodes($this->request->getPost("homeserverpool"));
+ $valMsgs = $mdlHomeserverpool->performValidation();
+ foreach ($valMsgs as $field => $msg) {
+ $fieldnm = str_replace($node->__reference, "homeserverpool", $msg->getField());
+ $result["validations"][$fieldnm] = $msg->getMessage();
+ }
+ if (count($result['validations']) == 0) {
+ unset($result['validations']);
+ // save config if validated correctly
+ $mdlHomeserverpool->serializeToConfig();
+ Config::getInstance()->save();
+ unset($result['validations']);
+ $result["result"] = "saved";
+ }
+ }
+ return $result;
+ }
+
+ public function delHomeserverpoolAction($uuid)
+ {
+ $result = array("result" => "failed");
+ if ($this->request->isPost()) {
+ $mdlHomeserverpool = $this->getModel();
+ if ($uuid != null) {
+ if ($mdlHomeserverpool->homeserverpools->homeserverpool->del($uuid)) {
+ $mdlHomeserverpool->serializeToConfig();
+ Config::getInstance()->save();
+ $result['result'] = 'deleted';
+ } else {
+ $result['result'] = 'not found';
+ }
+ }
+ }
+ return $result;
+ }
+
+ public function setHomeserverpoolAction($uuid)
+ {
+ if ($this->request->isPost() && $this->request->hasPost("homeserverpool")) {
+ $mdlSetting = $this->getModel();
+ if ($uuid != null) {
+ $node = $mdlSetting->getNodeByReference('homeserverpools.homeserverpool.' . $uuid);
+ if ($node != null) {
+ $result = array("result" => "failed", "validations" => array());
+ $clientInfo = $this->request->getPost("homeserverpool");
+ $node->setNodes($clientInfo);
+ $valMsgs = $mdlSetting->performValidation();
+ foreach ($valMsgs as $field => $msg) {
+ $fieldnm = str_replace($node->__reference, "homeserverpool", $msg->getField());
+ $result["validations"][$fieldnm] = $msg->getMessage();
+ }
+ if (count($result['validations']) == 0) {
+ // save config if validated correctly
+ $mdlSetting->serializeToConfig();
+ Config::getInstance()->save();
+ $result = array("result" => "saved");
+ }
+ return $result;
+ }
+ }
+ }
+ return array("result" => "failed");
+ }
+
+ public function toggleHomeserverpoolAction($uuid)
+ {
+ return $this->toggle_handler($uuid, 'homeserverpools', 'homeserverpool');
+ }
+}
\ No newline at end of file
diff --git a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/ProxyController.php b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/ProxyController.php
new file mode 100644
index 000000000..a117df243
--- /dev/null
+++ b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/ProxyController.php
@@ -0,0 +1,40 @@
+
+ * 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.
+ */
+
+namespace OPNsense\Freeradius;
+
+class ProxyController extends \OPNsense\Base\IndexController
+{
+ public function indexAction()
+ {
+ $this->view->formDialogEditFreeRADIUSHomeserver = $this->getForm("dialogEditFreeRADIUSHomeserver");
+ $this->view->formDialogEditFreeRADIUSHomeserverpool = $this->getForm("dialogEditFreeRADIUSHomeserverpool");
+ $this->view->formDialogEditFreeRADIUSRealm = $this->getForm("dialogEditFreeRADIUSRealm");
+ $this->view->pick('OPNsense/Freeradius/proxy');
+ }
+}
\ No newline at end of file
diff --git a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/dialogEditFreeRADIUSHomeserver.xml b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/dialogEditFreeRADIUSHomeserver.xml
new file mode 100644
index 000000000..dc4db8680
--- /dev/null
+++ b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/dialogEditFreeRADIUSHomeserver.xml
@@ -0,0 +1,140 @@
+
\ No newline at end of file
diff --git a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/dialogEditFreeRADIUSHomeserverpool.xml b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/dialogEditFreeRADIUSHomeserverpool.xml
new file mode 100644
index 000000000..b96dd32c4
--- /dev/null
+++ b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/dialogEditFreeRADIUSHomeserverpool.xml
@@ -0,0 +1,40 @@
+
\ No newline at end of file
diff --git a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/dialogEditFreeRADIUSRealm.xml b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/dialogEditFreeRADIUSRealm.xml
new file mode 100644
index 000000000..5a682b543
--- /dev/null
+++ b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/dialogEditFreeRADIUSRealm.xml
@@ -0,0 +1,32 @@
+
\ No newline at end of file
diff --git a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/general.xml b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/general.xml
index c97af703e..13272db6f 100644
--- a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/general.xml
+++ b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/general.xml
@@ -145,4 +145,11 @@
true
Set database name of remote MySQL server.
+
+ general.fallbackproxy
+
+ checkbox
+ true
+ Fallback for proxy server. Default disabled.
+
diff --git a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/ldap.xml b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/ldap.xml
index be7d1affd..46bbb3613 100644
--- a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/ldap.xml
+++ b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/ldap.xml
@@ -65,4 +65,4 @@
text
Filter for group objects, should match all available group objects a user might be a member of.
-
+
\ No newline at end of file
diff --git a/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/General.xml b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/General.xml
index a0aa11792..49590e8f7 100644
--- a/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/General.xml
+++ b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/General.xml
@@ -148,5 +148,9 @@
radius
Y
+
+ 0
+ Y
+
diff --git a/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Ldap.xml b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Ldap.xml
index 0ee417c47..7ca43fdba 100644
--- a/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Ldap.xml
+++ b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Ldap.xml
@@ -48,4 +48,4 @@
N
-
+
\ No newline at end of file
diff --git a/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Menu/Menu.xml b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Menu/Menu.xml
index ac2850744..979d54e3e 100644
--- a/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Menu/Menu.xml
+++ b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Menu/Menu.xml
@@ -8,6 +8,11 @@
+
+
+
+
+
diff --git a/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Proxy.php b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Proxy.php
new file mode 100644
index 000000000..40ccc778b
--- /dev/null
+++ b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Proxy.php
@@ -0,0 +1,22 @@
+settings->main->enabled === "1") {
+ return true;
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Proxy.xml b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Proxy.xml
new file mode 100644
index 000000000..9eddba73d
--- /dev/null
+++ b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Proxy.xml
@@ -0,0 +1,191 @@
+
+ //OPNsense/freeradius/proxy
+ Proxy configuration
+ 0.1
+
+
+
+
+ 1
+ Y
+
+
+ Y
+
+
+ 1
+ Y
+
+ auth
+ acct
+ auth+acct
+ coa
+
+
+
+ ipv4
+ Y
+
+ ipv4
+ ipv6
+ virtual_server
+
+
+
+ 172.0.0.1
+ N
+
+
+ ::1
+ N
+
+
+ foo
+ N
+
+
+ 1812
+ Y
+ 1
+ 65535
+
+
+ udp
+ Y
+
+ udp
+ tcp
+
+
+
+ testing123
+ N
+
+
+ N
+
+
+ 20
+ Y
+ 5
+ 60
+
+
+ N
+
+
+ 40
+ Y
+ 20
+ 120
+
+
+ 120
+ Y
+ 60
+ 3600
+
+
+ status-server
+ Y
+
+ none
+ status-server
+ request
+
+
+
+ 30
+ Y
+ 6
+ 120
+
+
+ 3
+ Y
+ 3
+ 10
+
+
+ 65536
+ Y
+
+
+ 16
+ Y
+
+
+ 0
+ Y
+
+
+ 0
+ Y
+
+
+ 0
+ Y
+
+
+
+
+
+
+ 1
+ Y
+
+
+ Y
+
+
+ fail-over
+ Y
+
+ fail-over
+ load-balance
+ client-balance
+ client-port-balance
+ keyed-balance
+
+
+
+ N
+
+
+ localhost
+ Y
+ Y
+ /^([a-zA-Z0-9\.:\[\]\-\/]*?,)*([a-zA-Z0-9\.:\[\]\-\/]*)$/
+ lower
+ Please provide valid server addresses, i.e. radius.example.com, 10.0.0.2 or 10.0.0.0/24.
+
+
+
+ N
+
+
+
+
+
+
+ 1
+ Y
+
+
+ Y
+
+
+
+ N
+
+
+
+ N
+
+
+ N
+
+
+
+
+
\ No newline at end of file
diff --git a/net/freeradius/src/opnsense/mvc/app/views/OPNsense/Freeradius/proxy.volt b/net/freeradius/src/opnsense/mvc/app/views/OPNsense/Freeradius/proxy.volt
new file mode 100644
index 000000000..a68126faf
--- /dev/null
+++ b/net/freeradius/src/opnsense/mvc/app/views/OPNsense/Freeradius/proxy.volt
@@ -0,0 +1,237 @@
+{#
+
+OPNsense® is Copyright © 2014 – 2016 by Deciso B.V.
+Copyright (C) 2017 Michael Muenz
+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.
+
+#}
+
+
+
+
+
+
+
+ {# manually add tab content #}
+
+
+
+
+
+ | {{ lang._('Enabled') }} |
+ {{ lang._('Name') }} |
+ {{ lang._('Type') }} |
+ {{ lang._('Commands') }} |
+
+
+
+
+
+
+ |
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+ | {{ lang._('Enabled') }} |
+ {{ lang._('Name') }} |
+ {{ lang._('Type') }} |
+ {{ lang._('Virtual Server') }} |
+ {{ lang._('Commands') }} |
+
+
+
+
+
+
+ |
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+ | {{ lang._('Enabled') }} |
+ {{ lang._('Name') }} |
+ {{ lang._('Authentication Pool') }} |
+ {{ lang._('Commands') }} |
+
+
+
+
+
+
+ |
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+{# include dialogs #}
+{{ partial("layout_partials/base_dialog",['fields':formDialogEditFreeRADIUSHomeserver,'id':'dialogEditFreeRADIUSHomeserver','label':lang._('Edit Homeservers')])}}
+{{ partial("layout_partials/base_dialog",['fields':formDialogEditFreeRADIUSHomeserverpool,'id':'dialogEditFreeRADIUSHomeserverpool','label':lang._('Edit Homeserverpools')])}}
+{{ partial("layout_partials/base_dialog",['fields':formDialogEditFreeRADIUSRealm,'id':'dialogEditFreeRADIUSRealm','label':lang._('Edit Realms')])}}
\ No newline at end of file
diff --git a/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/+TARGETS b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/+TARGETS
index 815e084f2..6d14b91c8 100644
--- a/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/+TARGETS
+++ b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/+TARGETS
@@ -1,4 +1,5 @@
clients.conf:/usr/local/etc/raddb/clients.conf
+proxy.conf:/usr/local/etc/raddb/proxy.conf
dictionary:/usr/local/etc/raddb/dictionary
mac2ip:/usr/local/etc/raddb/mods-config/passwd/mac2ip
mods-enabled-counter:/usr/local/etc/raddb/mods-enabled/counter
diff --git a/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/proxy.conf b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/proxy.conf
new file mode 100644
index 000000000..51234474f
--- /dev/null
+++ b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/proxy.conf
@@ -0,0 +1,126 @@
+proxy server {
+{% if helpers.exists('OPNsense.freeradius.general.fallbackproxy') and OPNsense.freeradius.general.fallbackproxy == '1' %}
+ default_fallback = yes
+{% else %}
+ default_fallback = no
+{% endif %}
+}
+{% if helpers.exists('OPNsense.freeradius.proxy.homeservers.homeserver') %}
+{% for homeserver_list in helpers.toList('OPNsense.freeradius.proxy.homeservers.homeserver') %}
+{% if homeserver_list.enabled == '1' %}
+home_server {{ homeserver_list.name }} {
+ type = {{ homeserver_list.type }}
+{% if homeserver_list.addresstype == 'ipv4' %}
+ ipaddr = {{ homeserver_list.ipaddr }}
+{% endif %}
+{% if homeserver_list.addresstype == 'ipv6' %}
+ ipv6addr = {{ homeserver_list.ipaddr6 }}
+{% endif %}
+{% if homeserver_list.addresstype == 'virtual_server' %}
+ virtual_server = {{ homeserver_list.virtualserver }}
+{% endif %}
+ port = {{ homeserver_list.port }}
+ proto = {{ homeserver_list.proto }}
+ secret = {{ homeserver_list.secret }}
+{% if homeserver_list.sourceip != '' %}
+ src_ipaddr = {{ homeserver_list.sourceip }}
+{% endif %}
+ response_window = {{ homeserver_list.response_window }}
+{% if homeserver_list.no_response_fail == '1' %}
+ no_response_fail = yes
+{% else %}
+ no_response_fail = no
+{% endif %}
+ zombie_period = {{ homeserver_list.zombieperiod }}
+ revive_interval = {{ homeserver_list.reviveinterval }}
+ status_check = {{ homeserver_list.statuscheck }}
+ check_interval = {{ homeserver_list.checkinterval }}
+ num_answers_to_alive = {{ homeserver_list.numanswersalive }}
+ max_outstanding = {{ homeserver_list.max_outstanding }}
+ coa {
+ irt = 2
+ mrt = 16
+ mrc = 5
+ mrd = 30
+ }
+ limit {
+ max_connections = {{ homeserver_list.limit_maxconnections }}
+ max_requests = {{ homeserver_list.limit_maxrequests }}
+ lifetime = {{ homeserver_list.limit_lifetime }}
+ idle_timeout = {{ homeserver_list.limit_idletimeout }}
+ }
+}
+{% endif %}
+{% endfor %}
+{% else %}
+home_server localhost {
+ type = auth
+ ipaddr = 127.0.0.1
+ port = 1812
+ secret = testing123
+ response_window = 20
+ zombie_period = 40
+ revive_interval = 120
+ status_check = status-server
+ check_interval = 30
+ num_answers_to_alive = 3
+ max_outstanding = 65536
+ coa {
+ irt = 2
+ mrt = 16
+ mrc = 5
+ mrd = 30
+ }
+ limit {
+ max_connections = 16
+ max_requests = 0
+ lifetime = 0
+ idle_timeout = 0
+ }
+}
+{% endif %}
+{% if helpers.exists('OPNsense.freeradius.proxy.homeserverpools.homeserverpool') %}
+{% for homeserverpool_list in helpers.toList('OPNsense.freeradius.proxy.homeserverpools.homeserverpool') %}
+{% if homeserverpool_list.enabled == '1' %}
+home_server_pool {{ homeserverpool_list.name }} {
+ type = {{ homeserverpool_list.type }}
+{% if homeserverpool_list.virtualserver != '' %}
+ virtual_server = {{ homeserverpool_list.virtualserver }}
+{% endif %}
+{% if homeserverpool_list.homeservers is defined %}
+{% for network in homeserverpool_list.homeservers.split(',') %}
+ home_server = {{ network }}
+{% endfor %}
+{% endif %}
+{% if homeserverpool_list.fallback is defined %}
+ fallback = {{ homeserverpool_list.fallback }}
+{% endif %}
+}
+{% endif %}
+{% endfor %}
+{% else %}
+home_server_pool my_auth_failover {
+ type = fail-over
+ home_server = localhost
+}
+{% endif %}
+{% if helpers.exists('OPNsense.freeradius.proxy.realms.realm') %}
+{% for realm_list in helpers.toList('OPNsense.freeradius.proxy.realms.realm') %}
+{% if realm_list.enabled == '1' %}
+realm {{ realm_list.name }} {
+{% if realm_list.auth_pool is defined %}
+ auth_pool = {{ realm_list.auth_pool }}
+{% endif %}
+{% if realm_list.acct_pool is defined %}
+ acct_pool = {{ realm_list.acct_pool }}
+{% endif %}
+{% if realm_list.nostrip == '1' %}
+ nostrip
+{% endif %}
+}
+{% endif %}
+{% endfor %}
+{% else %}
+realm LOCAL {
+}
+{% endif %}
\ No newline at end of file