mirror of
https://github.com/netbirdio/plugins.git
synced 2026-05-22 18:44:07 -07:00
Smart-Soft Proxy SSO plugin (#266)
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
rm -f /usr/local/etc/squid/pre-auth/20-negotiate.auth.conf
|
||||
if [ -f /var/run/squid/squid.pid ]; then
|
||||
configctl proxy reconfigure
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
PLUGIN_NAME= proxy-sso
|
||||
PLUGIN_VERSION= 1.3
|
||||
PLUGIN_COMMENT= Kerberos authentication module
|
||||
PLUGIN_DEPENDS= msktutil cyrus-sasl-gssapi
|
||||
PLUGIN_MAINTAINER= evbevz@gmail.com
|
||||
PLUGIN_WWW= http://smart-soft.ru
|
||||
|
||||
.include "../../Mk/plugins.mk"
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
function proxy_sso_configure()
|
||||
{
|
||||
return [
|
||||
'webproxy' => ['proxy_sso_squid_hook:2'],
|
||||
];
|
||||
}
|
||||
|
||||
function proxy_sso_squid_hook($verbose, $action)
|
||||
{
|
||||
if($action == "reconfigure") {
|
||||
configd_run('template reload OPNsense/ProxySSO');
|
||||
}
|
||||
}
|
||||
+262
@@ -0,0 +1,262 @@
|
||||
<?php
|
||||
|
||||
namespace OPNsense\ProxySSO\Api;
|
||||
|
||||
use \OPNsense\Core\Backend;
|
||||
use \OPNsense\Core\Config;
|
||||
use \OPNsense\ProxySSO\ProxySSO;
|
||||
|
||||
class ServiceController extends \OPNsense\Proxy\Api\ServiceController
|
||||
{
|
||||
|
||||
/**
|
||||
* show Kerberos keytab for Proxy
|
||||
* @return array
|
||||
*/
|
||||
public function showkeytabAction()
|
||||
{
|
||||
$backend = new Backend();
|
||||
|
||||
$response = $backend->configdRun("proxysso showkeytab");
|
||||
return array("response" => $response,"status" => "ok");
|
||||
}
|
||||
|
||||
/**
|
||||
* delete Kerberos keytab for Proxy
|
||||
* @return array
|
||||
*/
|
||||
public function deletekeytabAction()
|
||||
{
|
||||
$backend = new Backend();
|
||||
|
||||
$response = $backend->configdRun("proxysso deletekeytab");
|
||||
return array("response" => $response,"status" => "ok");
|
||||
}
|
||||
|
||||
/**
|
||||
* create Kerberos keytab for Proxy
|
||||
* @return array
|
||||
*/
|
||||
public function createkeytabAction()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$backend = new Backend();
|
||||
$mdl = new ProxySSO();
|
||||
$cnf = Config::getInstance()->toArray();
|
||||
$hostname = 'HTTP/' . $cnf['system']['hostname'];
|
||||
$domain = $cnf['system']['domain'];
|
||||
$kerbname = substr(strtoupper($cnf['system']['hostname']), 0, 13) . "-K";
|
||||
$winver = (string)$mdl->ADKerberosImplementation == 'W2008' ? '2008' : '2003';
|
||||
$username = escapeshellarg($this->request->getPost("admin_login"));
|
||||
$pass = escapeshellarg($this->request->getPost("admin_password"));
|
||||
|
||||
$response = $backend->configdRun("proxysso createkeytab {$hostname} {$domain} {$kerbname} {$winver} {$username} {$pass}");
|
||||
parent::reconfigureAction();
|
||||
return array("response" => $response,"status" => "ok");
|
||||
}
|
||||
|
||||
return array("response" => array());
|
||||
}
|
||||
|
||||
/**
|
||||
* test Kerberos login
|
||||
* @return array
|
||||
*/
|
||||
public function testkerbloginAction()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$backend = new Backend();
|
||||
$cnf = Config::getInstance()->toArray();
|
||||
$fqdn = $cnf['system']['hostname'].'.'.$cnf['system']['domain'];
|
||||
$username = escapeshellarg($this->request->getPost("login"));
|
||||
$pass = escapeshellarg($this->request->getPost("password"));
|
||||
|
||||
$response = $backend->configdRun("proxysso testkerblogin {$username} {$pass} {$fqdn}");
|
||||
return array("response" => $response,"status" => "ok");
|
||||
}
|
||||
|
||||
return array("response" => array());
|
||||
}
|
||||
|
||||
/**
|
||||
* get checklist data
|
||||
* @return array
|
||||
*/
|
||||
public function getCheckListAction()
|
||||
{
|
||||
$backend = new Backend();
|
||||
$cnf = Config::getInstance()->object();
|
||||
$hostname = $cnf->system->hostname .'.'.$cnf->system->domain;
|
||||
|
||||
// LDAP
|
||||
$methods = explode(',', $cnf->OPNsense->proxy->forward->authentication->method);
|
||||
foreach($methods as $method) {
|
||||
$xpath = $cnf->xpath("//system/authserver[name=\"$method\" and type=\"ldap\"]");
|
||||
if(count($xpath)) {
|
||||
$ldap_server = $xpath[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
$ldap_ip = null;
|
||||
$ldap_fqdn = null;
|
||||
$ldap_server_ping = [ "status" => "failure"];
|
||||
if(isset($ldap_server) && !empty($ldap_server->host)) {
|
||||
if(filter_var($ldap_server->host, FILTER_VALIDATE_IP)) {
|
||||
$ldap_ip = $ldap_server->host;
|
||||
}
|
||||
else {
|
||||
$ldap_fqdn = $ldap_server->host;
|
||||
}
|
||||
|
||||
$host_esc = escapeshellarg("{$ldap_server->host}");
|
||||
$output = array("# ping -c 1 -W 1 {$host_esc}");
|
||||
$retval = 0;
|
||||
exec("ping -c 1 -W 1 {$host_esc}", $output, $retval);
|
||||
$ldap_server_ping = [ "status" => $retval == 0 ? "ok" : "failure"];
|
||||
$ldap_server_ping["dump"] = implode("\n", $output);
|
||||
}
|
||||
|
||||
// DNS
|
||||
$dns_server = array();
|
||||
$nameservers = preg_grep('/^nameserver/', file('/etc/resolv.conf'));
|
||||
$dns_servers = array();
|
||||
foreach($nameservers as $key => $record) {
|
||||
$parts = explode(' ', $record);
|
||||
$dns_servers[] = trim($parts[1]);
|
||||
}
|
||||
$dns_server = [ "status" => count($dns_servers) ? "ok" : "failure"];
|
||||
if(!count($dns_servers)) {
|
||||
$dns_server["message"] = gettext("DNS server not found");
|
||||
}
|
||||
$output = "# cat /etc/resolv.conf\n";
|
||||
$output .= file_get_contents('/etc/resolv.conf');
|
||||
$dns_server["dump"] = $output;
|
||||
|
||||
// DNS: hostname
|
||||
$resolv_direct = chop(shell_exec("drill {$hostname} | grep -A 1 'ANSWER SECTION' | tail -n 1 | awk '{print \$5}'"));
|
||||
$dns_hostname_resolution = [ "status" => !empty($resolv_direct) && filter_var($resolv_direct, FILTER_VALIDATE_IP) ? "ok" : "failure"];
|
||||
$output = array("# drill {$hostname}");
|
||||
exec("drill {$hostname}", $output);
|
||||
$dns_hostname_resolution["dump"] = implode("\n", $output);
|
||||
|
||||
$resolv_reverse = null;
|
||||
$dns_hostname_reverse_resolution = array();
|
||||
$output = array();
|
||||
if(!empty($resolv_direct) && filter_var($resolv_direct, FILTER_VALIDATE_IP)) {
|
||||
$output[] = "# drill -x {$resolv_direct}";
|
||||
exec("drill -x {$resolv_direct}", $output);
|
||||
$resolv_reverse = chop(shell_exec("drill -x {$resolv_direct} | grep -A 1 'ANSWER SECTION' | tail -n 1 | awk '{print \$5}'"));
|
||||
if(strtolower($resolv_reverse) != strtolower("{$hostname}.")) {
|
||||
$dns_hostname_reverse_resolution["message"] = gettext("Hostname doesn't resolved to host IP.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
$dns_hostname_reverse_resolution["message"] = gettext("Hostname doesn't resolved to IP.");
|
||||
}
|
||||
$dns_hostname_reverse_resolution["status"] = strtolower($resolv_reverse) == strtolower("{$hostname}.") ? "ok" : "failure";
|
||||
$dns_hostname_reverse_resolution["dump"] = implode("\n", $output);
|
||||
|
||||
|
||||
// DNS: LDAP server
|
||||
ldap_dns:
|
||||
$dns_ldap_reverse_resolution = array( "status" => "failure" );
|
||||
if(empty($ldap_ip)) {
|
||||
$dns_ldap_reverse_resolution["message"] = gettext("Unknown LDAP server IP.");
|
||||
}
|
||||
else {
|
||||
$ldap_ip_esc = escapeshellarg($ldap_ip);
|
||||
$resolv_reverse = chop(shell_exec("drill -x {$ldap_ip_esc} | grep -A 1 'ANSWER SECTION' | tail -n 1 | awk '{print \$5}'"));
|
||||
if(empty($resolv_reverse)) {
|
||||
$dns_ldap_reverse_resolution["message"] = gettext('LDAP server IP reverse lookup error. ');
|
||||
}elseif (!empty($ldap_fqdn) && $resolv_reverse != "{$ldap_fqdn}.") {
|
||||
$dns_ldap_reverse_resolution["message"] = gettext('LDAP server reverse DNS lookup is not equal to LDAP server FQDN. ');
|
||||
}
|
||||
else {
|
||||
$dns_ldap_reverse_resolution["status"] = "ok";
|
||||
$ldap_fqdn = substr($resolv_reverse, 0, strlen($resolv_reverse) - 1);
|
||||
}
|
||||
$output = array("# drill -x {$ldap_ip_esc}");
|
||||
exec("drill -x {$ldap_ip_esc}", $output);
|
||||
$dns_ldap_reverse_resolution["dump"] = implode("\n", $output);
|
||||
}
|
||||
|
||||
$dns_ldap_resolution = array( "status" => "failure" );
|
||||
if(empty($ldap_fqdn)) {
|
||||
$dns_ldap_resolution["message"] = gettext('Unknown LDAP server FQDN.');
|
||||
}
|
||||
else {
|
||||
$ldap_fqdn_esc = escapeshellarg($ldap_fqdn);
|
||||
$resolv = chop(shell_exec("drill {$ldap_fqdn_esc} | grep -A 1 'ANSWER SECTION' | tail -n 1 | awk '{print \$5}'"));
|
||||
if(empty($resolv)) {
|
||||
$dns_ldap_resolution["message"] = gettext('LDAP server DNS lookup error. ');
|
||||
}
|
||||
elseif (!empty($ldap_ip) && $resolv != $ldap_ip) {
|
||||
$dns_ldap_resolution["message"] = gettext('LDAP server DNS lookup is not equal to LDAP IP. ');
|
||||
}
|
||||
else {
|
||||
$dns_ldap_resolution["status"] = "ok";
|
||||
if(empty($ldap_ip)) {
|
||||
$ldap_ip = $resolv;
|
||||
goto ldap_dns;
|
||||
}
|
||||
}
|
||||
$output = array("# drill {$ldap_fqdn_esc}");
|
||||
exec("drill {$ldap_fqdn_esc}", $output);
|
||||
$dns_ldap_resolution["dump"] = implode("\n", $output);
|
||||
}
|
||||
|
||||
|
||||
// KERBEROS
|
||||
$krb5_conf = '/etc/krb5.conf';
|
||||
$kerberos_config = array();
|
||||
$kerberos_config["status"] = "failure";
|
||||
if(!file_exists($krb5_conf)) {
|
||||
$kerberos_config["message"] = sprintf(gettext('File %s does not exists.'), $krb5_conf);
|
||||
}
|
||||
else{
|
||||
$domainstr = preg_quote($cnf->system->domain);
|
||||
$config_valid = preg_grep("/$domainstr/", file($krb5_conf));
|
||||
$kerberos_config["status"] = file_exists($krb5_conf) && !empty($config_valid) ? "ok" : "failure";
|
||||
if (empty($config_valid)) {
|
||||
$kerberos_config["message"] = gettext('SSO is not enabled or kerberos configuration file has invalid content');
|
||||
}
|
||||
$output = "# cat $krb5_conf\n";
|
||||
$output .= file_get_contents($krb5_conf);
|
||||
$kerberos_config["dump"] = $output;
|
||||
}
|
||||
|
||||
$keytab_file = '/usr/local/etc/squid/squid.keytab';
|
||||
$keytab = array();
|
||||
$keytab["status"] = file_exists($keytab_file) ? "ok" : "failure";
|
||||
if(!file_exists($keytab_file)) {
|
||||
$keytab["message"] = sprintf(gettext('File %s does not exists.'), $keytab_file);
|
||||
}
|
||||
$keytab["dump"] = $backend->configdRun("proxysso showkeytab");
|
||||
|
||||
|
||||
// and two more DNS check
|
||||
if(!empty($ldap_ip) && !in_array($ldap_ip, $dns_servers)) {
|
||||
$dns_server["status"] = "failure";
|
||||
$dns_server["message"] = gettext("LDAP server is not in DNS servers list.");
|
||||
}
|
||||
elseif(in_array("127.0.0.1", $dns_servers) || in_array("::1", $dns_servers)) {
|
||||
$dns_server["status"] = "failure";
|
||||
$dns_server["message"] = gettext("Do not set localhost as DNS server.");
|
||||
}
|
||||
|
||||
|
||||
return [
|
||||
"hostname" => $hostname,
|
||||
"ldap_server_config" => isset($ldap_server) ? $ldap_server->name->__toString() : array("status" => "failure", "message" => gettext("LDAP server is not set in Web Proxy - Authentication Settings")),
|
||||
"ldap_server" => isset($ldap_server) ? $ldap_server->host->__toString() : "",
|
||||
"ldap_server_ping" => $ldap_server_ping,
|
||||
"dns_server" => $dns_server,
|
||||
"dns_hostname_resolution" => $dns_hostname_resolution,
|
||||
"dns_hostname_reverse_resolution" => $dns_hostname_reverse_resolution,
|
||||
"dns_ldap_resolution" => $dns_ldap_resolution,
|
||||
"dns_ldap_reverse_resolution" => $dns_ldap_reverse_resolution,
|
||||
"kerberos_config" => $kerberos_config,
|
||||
"keytab" => $keytab,
|
||||
];
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2017 Smart-Soft
|
||||
*
|
||||
* 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\ProxySSO\Api;
|
||||
|
||||
use \OPNsense\Base\ApiMutableModelControllerBase;
|
||||
use \OPNsense\Core\Config;
|
||||
|
||||
/**
|
||||
* Class SettingsController Handles settings related API actions for the ProxySSO
|
||||
* @package OPNsense\ProxySSO
|
||||
*/
|
||||
class SettingsController extends ApiMutableModelControllerBase
|
||||
{
|
||||
static protected $internalModelName = "ProxySSO";
|
||||
static protected $internalModelClass = "\OPNsense\ProxySSO\ProxySSO";
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace OPNsense\ProxySSO;
|
||||
|
||||
class IndexController extends \OPNsense\Base\IndexController
|
||||
{
|
||||
public function indexAction()
|
||||
{
|
||||
$this->view->title = gettext("Web Proxy Single Sign-On");
|
||||
$this->view->pick('OPNsense/ProxySSO/index');
|
||||
$this->view->generalForm = $this->getForm("general");
|
||||
$this->view->testingCreateForm = $this->getForm("testing_create");
|
||||
$this->view->testingTestForm = $this->getForm("testing_test");
|
||||
$this->view->checkListForm = $this->getForm("checklist");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
<form>
|
||||
<field>
|
||||
<label>Kerberos authentication check-list</label>
|
||||
<type>header</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>hostname</id>
|
||||
<label>Hostname</label>
|
||||
<type>info</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>ldap_server_config</id>
|
||||
<label>LDAP Server configuration</label>
|
||||
<type>info</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>ldap_server</id>
|
||||
<label>LDAP Server</label>
|
||||
<type>info</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>ldap_server_ping</id>
|
||||
<label>LDAP Server accessible</label>
|
||||
<type>info</type>
|
||||
<help>LDAP server ping check.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>dns_server</id>
|
||||
<label>DNS Server</label>
|
||||
<type>info</type>
|
||||
<help>DNS server address from resolver configuration. <![CDATA[See <a href="/system_general.php">DNS settings</a>]]>.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>dns_hostname_resolution</id>
|
||||
<label>Hostname DNS lookup</label>
|
||||
<type>info</type>
|
||||
<help>DNS IP resolution for hostname.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>dns_hostname_reverse_resolution</id>
|
||||
<label>Hostname DNS reverse lookup</label>
|
||||
<type>info</type>
|
||||
<help>Reverse DNS resolution for host IP.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>dns_ldap_resolution</id>
|
||||
<label>LDAP server DNS lookup</label>
|
||||
<type>info</type>
|
||||
<help>DNS IP resolution for LDAP server name.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>dns_ldap_reverse_resolution</id>
|
||||
<label>LDAP server DNS reverse lookup</label>
|
||||
<type>info</type>
|
||||
<help>Reverse DNS resolution for LDAP server IP.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>kerberos_config</id>
|
||||
<label>Kerberos configuration</label>
|
||||
<type>info</type>
|
||||
<help>Kerberos configuration must exist and be valid.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>keytab</id>
|
||||
<label>Keytab file</label>
|
||||
<type>info</type>
|
||||
<help>Keytab file must exist and be valid.</help>
|
||||
</field>
|
||||
</form>
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<form>
|
||||
<field>
|
||||
<id>ProxySSO.EnableSSO</id>
|
||||
<label>Enable Single Sign-On</label>
|
||||
<type>checkbox</type>
|
||||
<help>Enable Kerberos based Single Sign-On</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>ProxySSO.ADKerberosImplementation</id>
|
||||
<label>AD Kerberos implementation</label>
|
||||
<type>dropdown</type>
|
||||
<help>Select Windows Server version for AD controller</help>
|
||||
</field>
|
||||
</form>
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
<form>
|
||||
<field>
|
||||
<label>Key Table creation</label>
|
||||
<type>header</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>admin_username</id>
|
||||
<label>AD admin login</label>
|
||||
<type>text</type>
|
||||
<help>Active Directory user name with administrator rights (this value is not stored in configuration).</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>admin_password</id>
|
||||
<label>AD admin password</label>
|
||||
<type>password</type>
|
||||
<help>Active Directory user password (this value is not stored in configuration).</help>
|
||||
</field>
|
||||
</form>
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
<form>
|
||||
<field>
|
||||
<id>username</id>
|
||||
<label>Username</label>
|
||||
<type>text</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>password</id>
|
||||
<label>Password</label>
|
||||
<type>password</type>
|
||||
</field>
|
||||
</form>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<menu>
|
||||
<Services>
|
||||
<WebProxy>
|
||||
<ProxySSO VisibleName="Single Sign-On" cssClass="fa fa-shield fa-fw" order="26" url="/ui/proxysso/" />
|
||||
</WebProxy>
|
||||
</Services>
|
||||
</menu>
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace OPNsense\ProxySSO;
|
||||
|
||||
use OPNsense\Base\BaseModel;
|
||||
|
||||
class ProxySSO extends BaseModel
|
||||
{
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<model>
|
||||
<mount>//OPNsense/ProxySSO</mount>
|
||||
<description>
|
||||
Web-proxy Single Sign-On plugin
|
||||
</description>
|
||||
<items>
|
||||
<EnableSSO type="BooleanField">
|
||||
<default>0</default>
|
||||
<Required>Y</Required>
|
||||
</EnableSSO>
|
||||
<ADKerberosImplementation type="OptionField">
|
||||
<default>W2008</default>
|
||||
<Required>Y</Required>
|
||||
<OptionValues>
|
||||
<W2003>Windows 2003</W2003>
|
||||
<W2008>Windows 2008 with AES</W2008>
|
||||
</OptionValues>
|
||||
</ADKerberosImplementation>
|
||||
</items>
|
||||
</model>
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
<script type="text/javascript">
|
||||
$( document ).ready(function() {
|
||||
|
||||
/*************************************************************************************************************
|
||||
* link general actions
|
||||
*************************************************************************************************************/
|
||||
|
||||
var data_get_map = {'frm_GeneralSettings':"/api/proxysso/settings/get"};
|
||||
|
||||
// load initial data
|
||||
mapDataToFormUI(data_get_map).done(function(){
|
||||
formatTokenizersUI();
|
||||
$('.selectpicker').selectpicker('refresh');
|
||||
});
|
||||
|
||||
// load checklist data
|
||||
updateKerberosChecklist();
|
||||
|
||||
$("#RefreshCheckList").click(function() {
|
||||
updateKerberosChecklist();
|
||||
});
|
||||
|
||||
$("#ShowKeytab").click(function() {
|
||||
ajaxCall(url="/api/proxysso/service/showkeytab", sendData={}, callback=function(data,status) {
|
||||
$("#kerberos_output").html(data['response']);
|
||||
});
|
||||
});
|
||||
|
||||
$("#DeleteKeytab").click(function() {
|
||||
ajaxCall(url="/api/proxysso/service/deletekeytab", sendData={}, callback=function(data,status) {
|
||||
$("#kerberos_output").html(data['response']);
|
||||
});
|
||||
});
|
||||
|
||||
$("#CreateKeytab").click(function() {
|
||||
ajaxCall(
|
||||
url="/api/proxysso/service/createkeytab",
|
||||
sendData={"admin_login":$("#admin_username").val(), "admin_password":$("#admin_password").val()},
|
||||
callback=function(data,status) { $("#kerberos_output").html(data['response']); }
|
||||
);
|
||||
});
|
||||
|
||||
$("#TestKerbLogin").click(function() {
|
||||
ajaxCall(
|
||||
url="/api/proxysso/service/testkerblogin",
|
||||
sendData={"login":$("#username").val(), "password":$("#password").val()},
|
||||
callback=function(data,status) { $("#kerberos_output").html(data['response']); });
|
||||
});
|
||||
|
||||
// link save button to API set action
|
||||
$("#applyAct").click(function(){
|
||||
$("#responseMsg").html('');
|
||||
$("#applyAct_progress").addClass("fa fa-spinner fa-pulse");
|
||||
$("#applyAct").addClass("disabled");
|
||||
saveFormToEndpoint(url="/api/proxysso/settings/set",formid='frm_GeneralSettings',callback_ok=function(){
|
||||
|
||||
ajaxCall(url="/api/proxy/service/reconfigure", sendData={},callback=function(data,status) {
|
||||
if(data.status == "ok") {
|
||||
$("#responseMsg").html("{{lang._('Proxy reconfigured')}}");
|
||||
$("#responseMsg").removeClass("hidden");
|
||||
}
|
||||
|
||||
$("#applyAct_progress").removeClass("fa fa-spinner fa-pulse");
|
||||
$("#applyAct").removeClass("disabled");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function showDump(fieldname)
|
||||
{
|
||||
$("#kerberos_output").html($("#" + fieldname + "_dump").html());
|
||||
$("#kerberos_output")[0].scrollIntoView(true);
|
||||
}
|
||||
|
||||
function updateKerberosChecklist()
|
||||
{
|
||||
$("#refresh_progress").addClass("fa fa-spinner fa-pulse");
|
||||
$("#RefreshCheckList").addClass("disabled");
|
||||
|
||||
var checklist_get_map = {'frm_CheckList':"/api/proxysso/service/getchecklist"};
|
||||
mapDataToFormUI(checklist_get_map).done(function(data){
|
||||
|
||||
$("#refresh_progress").removeClass("fa fa-spinner fa-pulse");
|
||||
$("#RefreshCheckList").removeClass("disabled");
|
||||
|
||||
$.each(data.frm_CheckList, function(index, value){
|
||||
|
||||
// clear data
|
||||
$("#" + index).html("");
|
||||
$(".help-block[for='" + index + "']").html("");
|
||||
|
||||
if(value.status == "ok") {
|
||||
jQuery('<div/>', {
|
||||
id: index + '_indicator',
|
||||
class: 'fa fa-check-circle text-success',
|
||||
}).appendTo("#" + index);
|
||||
if(value.message) {
|
||||
$(".help-block[for='" + index + "']").html(value.message);
|
||||
}
|
||||
}
|
||||
else if(value.status == "failure") {
|
||||
jQuery('<div/>', {
|
||||
id: index + '_indicator',
|
||||
class: 'fa fa-times-circle text-danger',
|
||||
}).appendTo("#" + index);
|
||||
if(value.message) {
|
||||
$(".help-block[for='" + index + "']").html(value.message);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$("#" + index).html(value);
|
||||
}
|
||||
|
||||
if(value.dump) {
|
||||
jQuery('<div/>', {
|
||||
id: index + '_dump',
|
||||
text: htmlDecode(value.dump),
|
||||
class: 'hidden',
|
||||
}).appendTo(".help-block[for='" + index + "']");
|
||||
jQuery('<a/>', {
|
||||
text: "{{ lang._('Show dump') }}",
|
||||
href: 'javascript:showDump("' + index + '");',
|
||||
style: 'padding-left: 20px;',
|
||||
}).appendTo("#" + index);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div class="alert alert-info hidden" role="alert" id="responseMsg">
|
||||
</div>
|
||||
|
||||
<ul class="nav nav-tabs" role="tablist" id="maintabs">
|
||||
<li class="active"><a data-toggle="tab" href="#general"><b>{{ lang._('General') }}</b></a></li>
|
||||
<li><a data-toggle="tab" href="#testing"><b>{{ lang._('Kerberos Authentication') }}</b></a></li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content content-box">
|
||||
|
||||
<div class="tab-pane fade in active" id="general">
|
||||
{{ partial("layout_partials/base_form",['fields':generalForm,'id':'frm_GeneralSettings'])}}
|
||||
|
||||
<hr/>
|
||||
<button class="btn btn-primary __mb" id="applyAct" type="button"><b>{{ lang._('Apply') }}</b> <i id="applyAct_progress" class=""></i></button>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="testing">
|
||||
|
||||
{{ partial("layout_partials/base_form",['fields':checkListForm,'id':'frm_CheckList'])}}
|
||||
<hr/>
|
||||
<button class="btn btn-primary __mb" id="RefreshCheckList" type="button"><b>{{ lang._('Refresh') }}</b> <i id="refresh_progress" class=""></i></button>
|
||||
|
||||
<div class="__mb">
|
||||
{{ partial("layout_partials/base_form",['fields':testingCreateForm,'id':'frm_TestingCreate'])}}
|
||||
<button class="btn btn-primary" id="CreateKeytab" type="button"><b>{{ lang._('Create Key Table') }}</b></button>
|
||||
<button class="btn btn-primary" id="DeleteKeytab" type="button"><b>{{ lang._('Delete Key Table') }}</b></button>
|
||||
<button class="btn btn-primary" id="ShowKeytab" type="button"><b>{{ lang._('Show Key Table') }}</b></button>
|
||||
</div>
|
||||
|
||||
{{ partial("layout_partials/base_form",['fields':testingTestForm,'id':'frm_TestingTest'])}}
|
||||
<button class="btn btn-primary" id="TestKerbLogin" type="button"><b>{{ lang._('Test Kerberos login') }}</b></button>
|
||||
|
||||
<hr/>
|
||||
<p><b>{{ lang._('Output') }}</b></p>
|
||||
<pre id="kerberos_output"></pre>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/bin/sh
|
||||
|
||||
PASS_TMP=/tmp/__tmp_kerb_pass
|
||||
|
||||
while getopts :f:u:p: name
|
||||
do
|
||||
case $name in
|
||||
f) FQDN="$OPTARG" ;; # aka TING.tingnet.local
|
||||
u) USERNAME="$OPTARG" ;; # username
|
||||
p) PASSWORD="$OPTARG" ;; # password
|
||||
esac
|
||||
done
|
||||
|
||||
[ "$USERNAME" == "" ] && echo "No account name" && exit 0;
|
||||
[ "$PASSWORD" == "" ] && echo "No account password" && exit 0;
|
||||
[ "$FQDN" == "" ] && echo "No FQDN" && exit 0;
|
||||
|
||||
PASSWORD="${PASSWORD%\'}"
|
||||
echo "${PASSWORD}" | sed 's/\\//g' > ${PASS_TMP}
|
||||
|
||||
/usr/local/bin/kinit ${USERNAME} < ${PASS_TMP}
|
||||
TICKET=$?
|
||||
rm ${PASS_TMP}
|
||||
|
||||
/usr/local/libexec/squid/negotiate_kerberos_auth_test ${FQDN} | awk '{sub(/Token:/,"YR"); print $0}END{print "QQ"}' | /usr/local/libexec/squid/negotiate_kerberos_auth -s GSS_C_NO_NAME
|
||||
|
||||
/usr/local/bin/kdestroy
|
||||
@@ -0,0 +1,41 @@
|
||||
#!/bin/sh
|
||||
|
||||
KEYTAB=/usr/local/etc/squid/squid.keytab
|
||||
PASS_TMP=/tmp/__tmp_kerb_pass
|
||||
|
||||
while getopts :d:n:k:e:b:u:p: name
|
||||
do
|
||||
case $name in
|
||||
d) DOMAIN="$OPTARG" ;; # aka opnsense.local
|
||||
n) PRINCIPAL="$OPTARG" ;; # aka HTTP/OPNSENSE
|
||||
k) KERB_COMPUTER_NAME="$OPTARG" ;; # aka OPNSENSE-K
|
||||
e) ENCTYPES="$OPTARG" ;;
|
||||
b) BASENAME="$OPTARG" ;;
|
||||
u) USERNAME="$OPTARG" ;; # LDAP admin username
|
||||
p) PASSWORD="$OPTARG" ;; # LDAP admin password
|
||||
esac
|
||||
done
|
||||
|
||||
[ "$USERNAME" == "" ] && echo "No administrator account name" && exit 0;
|
||||
[ "$PASSWORD" == "" ] && echo "No administrator account password" && exit 0;
|
||||
[ "$BASENAME" == "" ] && BASENAME="CN=Computers";
|
||||
[ "$PRINCIPAL" == "" ] && echo "No principal name" && exit 0;
|
||||
[ "$DOMAIN" == "" ] && echo "No domain name" && exit 0;
|
||||
[ "$KERB_COMPUTER_NAME" == "" ] && echo "No Kerberos name for host" && exit 0;
|
||||
[ "$ENCTYPES" == "2008" ] && ENCTYPES_PARAM="--enctypes 28";
|
||||
|
||||
|
||||
PASSWORD="${PASSWORD%\'}"
|
||||
echo "${PASSWORD}" | sed 's/\\//g' > ${PASS_TMP}
|
||||
|
||||
#/usr/local/bin/kinit --password-file=${PASS_TMP} ${USERNAME}
|
||||
/usr/local/bin/kinit ${USERNAME} < ${PASS_TMP}
|
||||
TICKET=$?
|
||||
rm ${PASS_TMP}
|
||||
[ $TICKET != 0 ] && echo "No ticket" && exit 0;
|
||||
|
||||
/usr/local/sbin/msktutil -c --verbose -b "${BASENAME}" -s ${PRINCIPAL}.${DOMAIN} -k ${KEYTAB} --computer-name ${KERB_COMPUTER_NAME} --upn ${PRINCIPAL}.${DOMAIN} ${ENCTYPES_PARAM} 2>&1
|
||||
|
||||
chmod +r ${KEYTAB}
|
||||
|
||||
/usr/local/bin/kdestroy
|
||||
@@ -0,0 +1,23 @@
|
||||
[showkeytab]
|
||||
command:( [ ! -f /usr/local/etc/squid/squid.keytab ] && echo "No keytab /usr/local/etc/squid/squid.keytab") || /usr/local/bin/klist -k /usr/local/etc/squid/squid.keytab
|
||||
parameters:
|
||||
type:script_output
|
||||
message:show kerberos keytab
|
||||
|
||||
[createkeytab]
|
||||
command:/usr/local/opnsense/scripts/OPNsense/ProxySSO/squid-gen-keytab.sh
|
||||
parameters:-n %s -d %s -k %s -e %s -u %s -p %s
|
||||
type:script_output
|
||||
message:create keytab
|
||||
|
||||
[deletekeytab]
|
||||
command:( [ ! -f /usr/local/etc/squid/squid.keytab ] && echo "No keytab file" ) || rm /usr/local/etc/squid/squid.keytab
|
||||
parameters:
|
||||
type:script_output
|
||||
message:delete keytab
|
||||
|
||||
[testkerblogin]
|
||||
command:/usr/local/opnsense/scripts/OPNsense/ProxySSO/kerberos_test.sh
|
||||
parameters:-u %s -p %s -f %s
|
||||
type:script_output
|
||||
message:test kerberos login
|
||||
@@ -0,0 +1,3 @@
|
||||
rc.conf.d:/etc/rc.conf.d/squid_krb5
|
||||
krb5.conf:/etc/krb5.conf
|
||||
kerberos.sso.conf:/usr/local/etc/squid/pre-auth/20-negotiate.auth.conf
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
{% set ldap_method = [] %}
|
||||
{% if helpers.exists('OPNsense.proxy.forward.authentication.method') and OPNsense.proxy.forward.authentication.method != '' %}
|
||||
{% for method in OPNsense.proxy.forward.authentication.method.split(",") %}
|
||||
{% if method != "Local Database" %}
|
||||
{% for server in helpers.toList('system.authserver') %}
|
||||
{% if server.type == 'ldap' and server.name == method %}
|
||||
{% do ldap_method.append(server) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if ldap_method|length > 0 and helpers.exists('OPNsense.ProxySSO.EnableSSO') and OPNsense.ProxySSO.EnableSSO == '1' %}
|
||||
auth_param negotiate program /usr/local/libexec/squid/negotiate_kerberos_auth -d -i -s HTTP/{{system.hostname}}.{{system.domain}}@{{system.domain|upper}}
|
||||
auth_param negotiate keep_alive on
|
||||
{% if helpers.exists('OPNsense.proxy.forward.authentication.children') %}
|
||||
auth_param negotiate children {{OPNsense.proxy.forward.authentication.children}}
|
||||
{% endif %}
|
||||
{% endif%}
|
||||
{% endif %}
|
||||
@@ -0,0 +1,38 @@
|
||||
# Autogenerated config. Do not edit manualy.
|
||||
|
||||
{% set ldap = [] %}
|
||||
{% if helpers.exists('OPNsense.proxy.forward.authentication.method') %}
|
||||
{% for method in OPNsense.proxy.forward.authentication.method.split(",") %}
|
||||
{% for server in helpers.toList('system.authserver') %}
|
||||
{% if server.type == 'ldap' and server.name == method %}
|
||||
{% do ldap.append(server) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if ldap|length > 0 and helpers.exists('OPNsense.ProxySSO.EnableSSO') and OPNsense.ProxySSO.EnableSSO|default('0') == '1' %}
|
||||
[libdefaults]
|
||||
default_realm = {{ system.domain|upper }}
|
||||
dns_lookup_kdc = no
|
||||
dns_lookup_realm = no
|
||||
ticket_lifetime = 24h
|
||||
default_keytab_name = /usr/local/etc/squid/squid.keytab
|
||||
{% if helpers.exists('OPNsense.ProxySSO.ADKerberosImplementation') and OPNsense.ProxySSO.ADKerberosImplementation == 'W2003' %}
|
||||
default_tgs_enctypes = rc4-hmac des-cbc-crc des-cbc-md5
|
||||
default_tkt_enctypes = rc4-hmac des-cbc-crc des-cbc-md5
|
||||
permitted_enctypes = rc4-hmac des-cbc-crc des-cbc-md5
|
||||
{% else %}
|
||||
default_tgs_enctypes = aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5
|
||||
default_tkt_enctypes = aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5
|
||||
permitted_enctypes = aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5
|
||||
{% endif %}
|
||||
[realms]
|
||||
{{ system.domain|upper }} = {
|
||||
kdc = {{ ldap[0].host }}
|
||||
admin_server = {{ ldap[0].host }}
|
||||
default_domain = {{ system.domain }}
|
||||
}
|
||||
[domain_realm]
|
||||
.{{ system.domain }} = {{ system.domain|upper }}
|
||||
{{ system.domain }} = {{ system.domain|upper }}
|
||||
{% endif %}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user