Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Smart-Soft Proxy SSO plugin #266

Merged
merged 11 commits into from
Sep 25, 2017
Merged

Conversation

evbevz
Copy link
Member

@evbevz evbevz commented Sep 15, 2017

deps: msktutil, cyrus-sasl-gssapi.
MIT kerberos implementation.
When Web-proxy uses LDAP connectors for authentication, SSO plugin gets the first LDAP connector from proxy authentication settings and makes SSO available for that connector.
Use kerberos check-list tab for easy setup, resolve common configuration mistakes, generate/delete/show keytab and test SSO.

@fichtner fichtner self-assigned this Sep 15, 2017
Copy link
Member

@fabianfrz fabianfrz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fichtner If this takes longer, it might be impossible to do a re-review in time.

{% 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indent mismatch

{% if method != "Local Database" %}
{% for server in helpers.toList('system.authserver') %}
{% if server.type == 'ldap' and server.name == method %}
{% if ldap_method.append(server) %}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

empty if statement?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, see above.

e) ENCTYPES="$OPTARG" ;;
b) BASENAME="$OPTARG" ;;
u) USERNAME="$OPTARG" ;; # LDAP admin username
p) PASSWORD="$OPTARG" ;; # LDAP admin password
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indent issue

<button class="btn btn-primary" id="DeleteKeytab" type="button"><b>{{ lang._('Delete keytab') }}</b></button>
<button class="btn btn-primary" id="ShowKeytab" type="button"><b>{{ lang._('Show keytab') }}</b></button>
<br/>
<br/>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to keep the distance, it would be better to use CSS because br depends on many settings (like font size) while margin-bottom with a pixel distance will always stay the same.

$hostname = 'HTTP/' . $cnf['system']['hostname'];
$domain = $cnf['system']['domain'];
$kerbname = substr(strtoupper($cnf['system']['hostname']), 0, 13) . "-K";
$winver = !isset($cnf['OPNsense']['ProxySSO']['ADKerberosImplementation']) || $cnf['OPNsense']['ProxySSO']['ADKerberosImplementation'] == 'W2008' ? '2008' : '2003';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you not using your model for that?

$mdl = new ProxySSO();
$value = (string)$mdl->ADKerberosImplementation;

should work to access this field if the model is imported.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

$("#CreateKeytab").click(function() {
ajaxCall(url="/api/proxysso/service/createkeytab", sendData={
"admin_login":$("#admin_username").val(),
"admin_password":$("#admin_password").val()}, callback=function(data,status) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

too large indent

$("#TestKerbLogin").click(function() {
ajaxCall(url="/api/proxysso/service/testkerblogin", sendData={
"login":$("#username").val(),
"password":$("#password").val()}, callback=function(data,status) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

{{ partial("layout_partials/base_form",['fields':testingCreateForm,'id':'frm_TestingCreate'])}}
<button class="btn btn-primary" id="CreateKeytab" type="button"><b>{{ lang._('Create keytab') }}</b></button>
<button class="btn btn-primary" id="DeleteKeytab" type="button"><b>{{ lang._('Delete keytab') }}</b></button>
<button class="btn btn-primary" id="ShowKeytab" type="button"><b>{{ lang._('Show keytab') }}</b></button>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the frontend, if possible try clean english here (Key Table for example). This is important for translation and for end users.

PASSWORD="${PASSWORD%\'}"
echo "${PASSWORD}" | sed 's/\\//g' > ${PASS_TMP}

/usr/local/bin/kinit ${USERNAME} < ${PASS_TMP}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is that safe against RCE?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so.
Password escaped before this action call:

$pass = escapeshellarg($this->request->getPost("password"));

And additional quoting performed in script (%\').

{% for method in OPNsense.proxy.forward.authentication.method.split(",") %}
{% for server in helpers.toList('system.authserver') %}
{% if server.type == 'ldap' and server.name == method %}
{% if ldap.append(server) %}{% endif %}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

empty if?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is a way to provide value changes from inner loop to outer variable (ldap) in jinja2.
ldap.append(server) makes it working.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes you are right.

@evbevz
Copy link
Member Author

evbevz commented Sep 18, 2017

@fabianfrz all items are fixed.

@@ -0,0 +1,5 @@
rm /usr/local/etc/squid/pre-auth/20-negotiate.auth.conf
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have time for a full review yet, but this needs "rm -f" in case the file is not there

I have this on my TODO to provide a proper revoke of templates on deinstall for automation: #46

@@ -0,0 +1,5 @@
rm /usr/local/etc/squid/pre-auth/20-negotiate.auth.conf
if [ -f /var/run/squid/squid.pid ]; then
service squid reload
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know what it's trying to achieve, but it's tricky as it doesn't work on a stock FreeBSD, it would kill the service. In OPNsense it works, maybe we need some type of reload command embedding in the package Makefile to signal reverse dependencies of base plugins?

PLUGIN_USES= squid

pointing to the squid.inc plugin file and doing a reload if possible?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in any case, a configd call would be far safer here, preferably in the background

PLUGIN_COMMENT= Kerberos authentication module
PLUGIN_DEPENDS= msktutil cyrus-sasl-gssapi
PLUGIN_MAINTAINER= evbevz@gmail.com
PLUGIN_WWW= http://smart-soft.ru
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should upgrade to HTTPS if possible ;)

@@ -0,0 +1,8 @@
PLUGIN_NAME= proxy-sso
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are you ok with replacing the old plugin? the name would be web-proxy-sso or web-proxy-sso2, although that gets confusing...

Copy link
Member Author

@evbevz evbevz Sep 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no problem, as you wish )

@@ -0,0 +1,8 @@
PLUGIN_NAME= proxy-sso
PLUGIN_VERSION= 1.3
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we replace the old one, can this be 2.0 instead? what do you think?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great. I can do this post merge, no need to shuffle it all around now :)

function proxy_sso_configure()
{
return [
'webproxy_reconfigure' => ['proxy_sso_squid_reconfigure'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this work in the core or do we need to merge a pr? I vaguely remember something

Copy link
Member Author

@evbevz evbevz Sep 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs opnsense/core#1627
Without this pull-request, administrator should reconfigure proxy-sso manually after reconfiguring proxy.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this changes slightly with the merge: the facility is "webproxy" and in reconfigure you need to check for "reconfigure" argument, it looks like this:

https://github.com/opnsense/core/blob/master/src/etc/inc/plugins.inc.d/openvpn.inc#L37

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some changes have to be done in connection with acceptance of opnsense/core#1627

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done: 651ce70

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in that case the line now reads something like:

'webproxy' => ['proxy_sso_squid_reconfigure:2'],

but the second argument to the function is the "reconfigure" statement like

https://github.com/opnsense/core/blob/master/src/etc/inc/plugins.inc.d/openvpn.inc#L1172

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? I don't understand why I need set count of parameters to 2 when function proxy_sso_squid_reconfigure() has no parameters.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because the plugin configure endpoint was simplified. we can pass all kinds of arguments here, we don't have to encode the type of the call in the name of the endpoint, so "webproxy_reconfigure" becomes "webproxy":

opnsense/core@b769f35#diff-7ab5c46a2101377cc2113c978d5a9676R34

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aha, understood )

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done!

message:create keytab

[deletekeytab]
command:( [ ! -f /usr/local/etc/squid/squid.keytab ] && echo "No keytab file" ) || rm /usr/local/etc/squid/squid.keytab
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ideally this should be like a wrapper shell script for keytab operations to avoid bouncing every tweak / change through the service configuration. but this is only a recommendation from my side :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not want to produce more essences, than minimum.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's fine for now. if it grows more complex we need to reconsider

Copy link
Member

@fabianfrz fabianfrz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like its almost OK and may be merged as soon as the change requests of @fichtner are in.

@fichtner
Copy link
Member

opnsense/core#1627 was merged with a tiny bit of changes...

use \OPNsense\Core\Config;
use \OPNsense\ProxySSO\ProxySSO;

class ServiceController extends \OPNsense\Proxy\Api\ServiceController
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this base controller still an requirement?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

@fabianfrz fabianfrz added the feature Adding new functionality label Sep 22, 2017
@fichtner fichtner merged commit e2a42db into opnsense:master Sep 25, 2017
@fichtner
Copy link
Member

Merged, thanks! Will fix up remaining issues post-merged.

fichtner pushed a commit that referenced this pull request Sep 25, 2017
(cherry picked from commit e2a42db)
(cherry picked from commit 7416607)
(cherry picked from commit 94df25e)
(cherry picked from commit c75320e)
(cherry picked from commit 2d603f3)
(cherry picked from commit 14e1595)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Adding new functionality
Development

Successfully merging this pull request may close these issues.

3 participants