[ARVADOS] updated: 982a80e54bef92b3c942a1e7f6924980b74d1ef4
git at public.curoverse.com
git at public.curoverse.com
Tue Aug 11 02:27:27 EDT 2015
Summary of changes:
sdk/pam/Dockerfile | 27 +++++++++++++++++++----
sdk/pam/arvados_pam/__init__.py | 14 +++++++-----
sdk/pam/pam-configs/arvados | 4 ++--
sdk/pam/tests/integration_test.pl | 46 +++++++++++++++++++++++++++++++++++++++
sdk/pam/tests/test_integration.py | 19 ++++++++++------
5 files changed, 92 insertions(+), 18 deletions(-)
create mode 100755 sdk/pam/tests/integration_test.pl
via 982a80e54bef92b3c942a1e7f6924980b74d1ef4 (commit)
from 9a3fd168b3819c2682960193606110fdddffcb97 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
commit 982a80e54bef92b3c942a1e7f6924980b74d1ef4
Author: Tom Clegg <tom at curoverse.com>
Date: Tue Aug 11 02:26:51 2015 -0400
6934: Put wrapper in /lib/security/ instead of writing dist-packages path in config file. Make integration test work.
diff --git a/sdk/pam/Dockerfile b/sdk/pam/Dockerfile
index c5e83f8..76b08b9 100644
--- a/sdk/pam/Dockerfile
+++ b/sdk/pam/Dockerfile
@@ -1,8 +1,8 @@
# Manual integration test:
# 0. python setup.py sdist rotate --keep=1 --match .tar.gz
-# 1. docker build -name arvados:pam_test .
-# 2. docker run -it arvados:pam_test
-# 3. container# edit /etc/pam.d/login # set api host and shell VM name
+# 1. replace 53015 below with your api server's port number
+# 2. docker build -name arvados:pam_test .
+# 3. docker run -it --add-host zzzzz.arvadosapi.com:"$(hostname -I |awk '{print $1}')" arvados:pam_test
# 4. container# useradd testusername
# 5. container# login # enter username and token
@@ -12,9 +12,28 @@ RUN apt-get -qy dist-upgrade
RUN apt-get -qy install python python-virtualenv libpam-python rsyslog
# Packages required by pycurl, ciso8601
RUN apt-get -qy install libcurl4-gnutls-dev python2.7-dev
+
+# for jessie (which also has other snags)
+# RUN apt-get -qy install python-pip libgnutls28-dev
+
RUN pip install --upgrade setuptools
RUN pip install python-pam
ADD dist /dist
RUN pip install /dist/arvados-pam-*.tar.gz
+
+# Configure and enable the module (hopefully vendor packages will offer a neater way)
+RUN perl -pi -e 's{api.example}{zzzzz.arvadosapi.com:53015}; s{shell\.example}{testvm2.shell insecure};' /usr/share/pam-configs/arvados
RUN DEBIAN_FRONTEND=noninteractive pam-auth-update arvados --remove unix
-CMD rsyslogd & tail -F /var/log/auth.log & bash
+
+# Add a user account matching the fixture
+RUN useradd -ms /bin/bash active
+
+# Test with python (SIGSEGV during tests)
+#ADD . /pam
+#WORKDIR /pam
+#CMD rsyslogd & tail -F /var/log/auth.log & python setup.py test
+
+# Test with perl (SIGSEGV when program exits)
+RUN apt-get install -qy libauthen-pam-perl
+ADD tests/integration_test.pl /integration_test.pl
+CMD rsyslogd & tail -F /var/log/auth.log & sleep 1 && /integration_test.pl
diff --git a/sdk/pam/arvados_pam/__init__.py b/sdk/pam/arvados_pam/__init__.py
index 920a364..1ec6a3a 100644
--- a/sdk/pam/arvados_pam/__init__.py
+++ b/sdk/pam/arvados_pam/__init__.py
@@ -28,7 +28,9 @@ class AuthEvent(object):
ok = False
try:
self.api_host = self.config['arvados_api_host']
- self.arv = arvados.api('v1', host=self.api_host, token=self.token, cache=None)
+ self.arv = arvados.api('v1', host=self.api_host, token=self.token,
+ insecure=self.config.get('insecure'),
+ cache=False)
vmname = self.config['virtual_machine_hostname']
vms = self.arv.virtual_machines().list(filters=[['hostname','=',vmname]]).execute()
@@ -94,18 +96,20 @@ def pam_sm_authenticate(pamh, flags, argv):
config = {}
config['arvados_api_host'] = argv[1]
config['virtual_machine_hostname'] = argv[2]
- config['noprompt'] = (len(argv) > 3 and argv[3] == 'noprompt')
+ if len(argv) > 3:
+ for k in argv[3:]:
+ config[k] = True
try:
- username = pamh.get_user()
- except pamh.exception as e:
+ username = pamh.get_user(None)
+ except pamh.exception, e:
return e.pam_result
if not username:
return pamh.PAM_USER_UNKNOWN
try:
- prompt = '' if config['noprompt'] else 'Arvados API token: '
+ prompt = '' if config.get('noprompt') else 'Arvados API token: '
token = pamh.conversation(pamh.Message(pamh.PAM_PROMPT_ECHO_OFF, prompt)).resp
except pamh.exception as e:
return e.pam_result
diff --git a/sdk/pam/pam-configs/arvados b/sdk/pam/pam-configs/arvados
index 3d245f0..6972a39 100644
--- a/sdk/pam/pam-configs/arvados
+++ b/sdk/pam/pam-configs/arvados
@@ -9,6 +9,6 @@ Default: yes
Priority: 256
Auth-Type: Primary
Auth:
- [success=end default=ignore] pam_python.so /usr/local/lib/python2.7/dist-packages/arvados_pam/__init__.py api.example shell.example
+ [success=end default=ignore] pam_python.so /lib/security/libpam_arvados.py api.example shell.example
Auth-Initial:
- [success=end default=ignore] pam_python.so /usr/local/lib/python2.7/dist-packages/arvados_pam/__init__.py api.example shell.example
+ [success=end default=ignore] pam_python.so /lib/security/libpam_arvados.py api.example shell.example
diff --git a/sdk/pam/tests/integration_test.pl b/sdk/pam/tests/integration_test.pl
new file mode 100755
index 0000000..e5dff1e
--- /dev/null
+++ b/sdk/pam/tests/integration_test.pl
@@ -0,0 +1,46 @@
+#!/usr/bin/env perl
+
+$ENV{ARVADOS_API_HOST_INSECURE} = 1;
+use Authen::PAM qw(:constants);
+
+for my $case (['good', 1, 'active', '3kg6k6lzmp9kj5cpkcoxie963cmvjahbt2fod9zru30k1jqdmi'],
+ ['badtoken', 0, 'active', 'badtokenmp9kj5cpkcoxie963cmvjahbt2fod9zru30k1jqdmi'],
+ ['badusername', 0, 'baduser', '3kg6k6lzmp9kj5cpkcoxie963cmvjahbt2fod9zru30k1jqdmi']) {
+ dotest(@$case);
+}
+print "=== OK ===\n";
+
+sub dotest {
+ my ($label, $expect_ok, $user, $token) = @_;
+ print "$label: ";
+ my $service_name = 'login';
+ $main::Token = $token;
+ my $pamh = new Authen::PAM($service_name, $user, \&token_conv_func);
+ ref($pamh) || die "Error code $pamh during PAM init!";
+ $pamh->pam_set_item(PAM_RHOST(), '::1');
+ $pamh->pam_set_item(PAM_RUSER(), 'none');
+ $pamh->pam_set_item(PAM_TTY(), '/dev/null');
+ my $flags = PAM_SILENT();
+ $res = $pamh->pam_authenticate($flags);
+ $msg = $pamh->pam_strerror($res);
+ print "Result (code $res): $msg\n";
+ if (($res == 0) != ($expect_ok == 1)) {
+ die "*** FAIL ***\n";
+ }
+}
+
+sub token_conv_func {
+ my @res;
+ while ( @_ ) {
+ my $code = shift;
+ my $msg = shift;
+ my $ans;
+ print "Message (type $code): $msg\n";
+ if ($code == PAM_PROMPT_ECHO_OFF() || $code == PAM_PROMPT_ECHO_ON()) {
+ $ans = $main::Token;
+ }
+ push @res, (0,$ans);
+ }
+ push @res, PAM_SUCCESS();
+ return @res;
+}
diff --git a/sdk/pam/tests/test_integration.py b/sdk/pam/tests/test_integration.py
index 2728bcd..53ef0ea 100644
--- a/sdk/pam/tests/test_integration.py
+++ b/sdk/pam/tests/test_integration.py
@@ -1,8 +1,13 @@
import os
-if os.path.exists('/etc/pam.d/arvados-pam-test'):
+if os.path.exists('/usr/share/pam-configs/arvados') and os.getuid() == 0:
+ """These tests assume we are running (in a docker container) with
+ arvados_pam configured and a test API server running.
+ """
import pam
import unittest
+ # From services/api/test/fixtures/api_client_authorizations.yml
+ # because that file is not available during integration tests:
ACTIVE_TOKEN = '3kg6k6lzmp9kj5cpkcoxie963cmvjahbt2fod9zru30k1jqdmi'
SPECTATOR_TOKEN = 'zw2f4gwx8hw8cjre7yp6v1zylhrhn3m5gvjq73rtpwhmknrybu'
@@ -11,13 +16,13 @@ if os.path.exists('/etc/pam.d/arvados-pam-test'):
self.p = pam.pam()
def test_allow(self):
- self.assertTrue(self.p.authenticate('active', ACTIVE_TOKEN, service='arvados-pam-test'))
+ self.assertTrue(self.p.authenticate('active', ACTIVE_TOKEN, service='login'))
- def test_deny_service(self):
- self.assertFalse(self.p.authenticate('active', ACTIVE_TOKEN, service='login'))
+ def test_deny_bad_token(self):
+ self.assertFalse(self.p.authenticate('active', 'thisisaverybadtoken', service='login'))
- def test_deny_token(self):
- self.assertFalse(self.p.authenticate('active', 'bogustoken', service='arvados-pam-test'))
+ def test_deny_empty_token(self):
+ self.assertFalse(self.p.authenticate('active', '', service='login'))
def test_deny_permission(self):
- self.assertFalse(self.p.authenticate('spectator', SPECTATOR_TOKEN, service='arvados-pam-test'))
+ self.assertFalse(self.p.authenticate('spectator', SPECTATOR_TOKEN, service='login'))
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list