[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