On 01/06/2015 03:26 AM, Nathaniel McCallum wrote:
On Thu, 2014-11-20 at 11:13 -0500, Nathaniel McCallum wrote:
>This tests the general workflow for OTP including most possible
>token combinations. This includes 5872 tests. Further optimization
>is possible to reduce the number of duplicate tests run.
>
>Things not yet tested:
>* ipa-kdb
>* ipa-otpd
>* otptoken-sync
>* RADIUS proxy
>* token self-management
>* type specific attributes
Attached is the latest iteration of the OTP test work. This now includes
all major cases except token self-management and RADIUS proxy (which
will come in its own patch). Token self-management is held up by the
fact that I can't get alternate ccaches to work with the API. I have
tried kinit-ing to an independent ccache and exporting KRB5CCNAME, but
this doesn't work for some reason I can't figure out.

I ended up creating my own fixture mechanism. I'm not in love with it,
but it is simple and at least gets the scoping correct. It also
generates individual tests for each parameterized state, so the output
is both correct and obvious.

I also implemented OTP myself. This isn't much code, but pyotp has a
major bug and is dead upstream. I'd like to migrate to
python-cryptography when it lands as a dependency of FreeIPA. But due to
timing issues, we can't land it now. This will be a small patch in the
future.

Even with the caveats above, I feel like the test coverage provided by
this test is worth review/merge. As a rough estimate, I think this is
about 70% code coverage. Of the remaining coverage, I see:
* RADIUS proxy - 10%
* token self-management - 10%
* misc testable - 5%
* misc untestable - 5%

All tests in this patch succeed on 4.1.2.

It doesn't work for me on the 4.2 branch, see the attached errors. Not sure what I'm doing wrong.

See some comments andnitpicks inline.



freeipa-npmccallum-0081.1-Add-initial-tests-for-OTP.patch


 From c7b01ea4415db3847110ffe51a9bb5193072d1a8 Mon Sep 17 00:00:00 2001
From: Nathaniel McCallum<npmccal...@redhat.com>
Date: Thu, 20 Nov 2014 11:02:00 -0500
Subject: [PATCH] Add initial tests for OTP

This tests the general workflow for OTP including most possible
token combinations. It includes tests for all token options,
enablement scenarios and token synchronization.
---
  ipatests/test_xmlrpc/test_otptoken_plugin.py | 536 +++++++++++++++++++++++++++
  1 file changed, 536 insertions(+)
  create mode 100644 ipatests/test_xmlrpc/test_otptoken_plugin.py

diff --git a/ipatests/test_xmlrpc/test_otptoken_plugin.py 
b/ipatests/test_xmlrpc/test_otptoken_plugin.py
new file mode 100644
index 
0000000000000000000000000000000000000000..7a27d720cb9789c648e45aece1ebd0b6b751e3d8
--- /dev/null
+++ b/ipatests/test_xmlrpc/test_otptoken_plugin.py
@@ -0,0 +1,536 @@
+# Authors:
+#   Nathaniel McCallum<npmccal...@redhat.com>
+#
+# Copyright (C) 2014  Red Hat
+# see file 'COPYING' for use and warranty information
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see<http://www.gnu.org/licenses/>.
+
+"""
+Test the `ipalib/plugins/otptoken.py` module.
+"""
+
+import abc
+import base64
+import hashlib
+import hmac
+import os
+import unittest
+import urlparse
+import uuid
+import random
+import string
+import struct
+import subprocess
+import time
+import types
+
+from datetime import datetime, timedelta
+
+from ipalib import api
+from xmlrpc_test import XMLRPC_test, Declarative

^ unused

+from ipatests.util import assert_deepequal, raises

I recommend nose.tools.assert_raises rather than ipatests.util.raises -- it's easier to debug if an unexpected error occurs.

+from ipapython.version import API_VERSION
+from ipapython.dn import DN
+import ldap
+
+
+class Fixture(object):
+    __metaclass__ = abc.ABCMeta
+
+    @property
+    def context(self):
+        try:
+            return self.__fixtures
+        except AttributeError:
+            return tuple()
+
+    @context.setter
+    def context(self, value):
+        self.__fixtures = value
+
+    @abc.abstractmethod
+    def __enter__(self):
+        raise NotImplementedError()
+
+    @abc.abstractmethod
+    def __exit__(self, type, value, traceback):
+        raise NotImplementedError()
+
+    def __repr__(self):
+        return '%s()' % self.__class__.__name__

It seems that this class could be written as:

    class Fixture(object):
        context = ()

and all the rest except __repr__ is unnecessary.
For documenting what subclasses should add/override, a mention in a docstring might be more helpful than ABC stubs.

+def fixturize(*args):
+    def outer(func):
+        def inner(s, fixtures=args, ctx=()):
+            try:
+                fixture = fixtures[0]
+            except IndexError:
+                yield (lambda *a: func(s, *a),) + ctx
+            else:
+                for f in fixture if type(fixture) is tuple else (fixture,):
+                    if isinstance(f, Fixture):
+                        f.context = ctx
+
+                    if hasattr(f, "__enter__"):
+                        with f as tmp:
+                            for test in inner(s, fixtures[1:], ctx + (tmp,)):
+                                yield test
+                    else:
+                        for test in inner(s, fixtures[1:], ctx + (f,)):
+                            yield test
+
+        inner.__name__ = func.__name__
+        return inner
+    return outer

Well, that works. A docstring would be really nice though.

+def cmd(cmd, *args, **kwargs):
+    return api.Command[cmd](*args, version=API_VERSION, **kwargs)

This requires rpcclient to be connected. See the XMLRPC_test class for the necessary setup.


+class AuthenticationError(Exception):
+    pass
+
+
+class Login(object):
+    def __repr__(self):
+        return '%s()' % self.__class__.__name__
+
+    def __init__(self):
+        self.__fails = 0
+
+    def __call__(self, uid, pwd):
+        try:
+            self.login(uid, pwd)
+            self.__fails = 0
+        except:
+            self.__fails += 1
+            if self.__fails > 2:
+                cmd('user_unlock', uid)
+                self.__fails = 0
+            raise

I'm not sure what you're doing here.

+
+    def login(self, uid, pwd):
+        raise NotImplementedError()
+
+
+class LDAPLogin(Login):
+    def __init__(self):
+        super(LDAPLogin, self).__init__()
+
+        self.__conn = ldap.initialize('ldap://' + api.env.host)
+
+    def login(self, uid, pwd):
+        dn = DN(('uid', uid), api.env.container_user, api.env.basedn)
+        try:
+            self.__conn.simple_bind_s(str(dn), pwd)
+        except ldap.INVALID_CREDENTIALS as e:
+            raise AuthenticationError(e.message)
+
+
+class Krb5Login(Login):
+    def __init__(self):
+        super(Krb5Login, self).__init__()
+
+        self.__fast = subprocess.Popen(
+            ['/usr/bin/klist'],
+            stdout=subprocess.PIPE
+        ).communicate()[0].split('\n')[0].split(': ')[1]
+
+    def kinit(self, uid, pwd, newpwd=None, ccache="FILE:/dev/null"):
+        data = pwd + '\n'
+        if newpwd is not None:
+            data += newpwd + '\n' + newpwd + '\n'
+
+        p = subprocess.Popen(
+            ['/usr/bin/kinit',
+             '-T', self.__fast,
+             '-c', ccache,
+             uid + '@' + api.env.realm],
+            stdin=subprocess.PIPE,
+            stdout=subprocess.PIPE,
+            stderr=subprocess.PIPE
+        )
+        out, err = p.communicate(data)

Can you use ipautil.run here?

+        if p.returncode != 0:
+            raise AuthenticationError(out, err)
+
+    def login(self, uid, pwd):
+        self.kinit(uid, pwd)
+
+
+class User(Fixture):
+    def __init__(self, **kwargs):
+        self.username = u''.join(random.sample(string.lowercase, 20))
+        self.password = u''.join(random.sample(string.letters, 20))

Could you prefix the test user with `test`, so it's identifiable when it doesn't get deleted for some reason?

+        self.__kwargs = kwargs
+
+    def __enter__(self):
+        cmd('user_add', self.username,
+            userpassword=self.password,
+            givenname=self.username[:len(self.username) / 2],
+            sn=self.username[len(self.username) / 2:],
+            **self.__kwargs)
+
+        # Change password
+        Krb5Login().kinit(self.username, self.password, self.password)
+        return self
+
+    def __exit__(self, type, value, traceback):
+        cmd('user_del', self.username)
+
+
+class Enablement(Fixture):
+    def __repr__(self):
+        return "Enablement(%s)" % ("user" if self.user else "global")
+
+    def __set_authtype(self, authtype):
+        if self.user:
+            for fixture in self.context:
+                if isinstance(fixture, User):
+                    cmd('user_mod', fixture.username, ipauserauthtype=authtype)
+                    return
+            assert False
+        else:
+            cmd('config_mod', ipauserauthtype=authtype)
+            time.sleep(60)  # Work around cfg update hack in ipa-kdb

The config_mod might raise EmptyModList which you should ignore.

+
+    def __init__(self, user=True):
+        self.user = user
+
+    def __enter__(self):
+        self.__set_authtype((u'otp',))
+        return self
+
+    def __exit__(self, type, value, traceback):
+        self.__set_authtype(())
+
+
+class Token(dict, Fixture):

Why is Token a dict, as opposed to having a "params" dict?

+    @property
+    def type(self):
+        return self[u'type'].upper()
+
+    @property
+    def active(self):
+        if self.get(u'ipatokendisabled', False):
+            return False
+
+        nb = self.get(u'ipatokennotbefore', None)
+        if nb is not None and datetime.now() < nb:
+            return False
+
+        na = self.get(u'ipatokennotafter', None)
+        if na is not None and datetime.now() > na:
+            return False
+
+        return True
+
+    def __repr__(self):
+        prefixes = ['ipatoken' + x for x in ('totp', 'hotp', 'otp', '')]
+
+        args = {}
+        for k, v in self.items():
+            for prefix in prefixes:
+                if k.startswith(prefix):
+                    k = k[len(prefix):]
+                    break
+
+            if k in ('key', 'uniqueid', 'owner'):
+                continue
+
+            if isinstance(v, datetime):
+                v = v.strftime("%Y%m%d%H%M%SZ")
+
+            args[k] = v
+
+        return "%s(%s:%d|%d%s%s%r)" % (
+            args.pop('type').upper(),
+            args.pop('algorithm'),
+            args.pop('digits'),
+            args.pop('counter', args.pop('timestep', 0)),
+            ':' if self.type == 'TOTP' else '',
+            str(args.pop('clockoffset', '')),
+            args
+        )
+
+    def otp(self, at=0):
+        # I first attempted implementing this with pyotp. However, pyotp has
+        # a critical bug which appeared in testing. I fixed this bug and
+        # submitted it upstream:https://github.com/nathforge/pyotp/pull/9
+        #
+        # However, upstream pyotp appears to be dead. For now, I have
+        # implemented the algorithm myself. In the future, it would be nice
+        # to use python-cryptography here.
+
+        # If the token is time-based, calculate the counter from the time.
+        if self.type == u"TOTP":
+            intrvl = self[u'ipatokentotptimestep']
+            offset = self.get(u'ipatokentotpclockoffset', 0)
+            at = (time.time() + offset + intrvl * at) / intrvl
+
+        # Otherwise, just account for the specified counter offset.
+        elif self.type == u"HOTP":
+            if at < 0:  # Skip invalid test offsets.
+                raise unittest.SkipTest()
+            at += self.get(u'ipatokenhotpcounter', 0)
+
+        # Create the HMAC of the current counter
+        countr = struct.pack("!Q", at)
+        hasher = getattr(hashlib, self[u'ipatokenotpalgorithm'])

hashlib.new(self[u'ipatokenotpalgorithm']) should work

+        digest = hmac.HMAC(self[u'ipatokenotpkey'], countr, hasher).digest()
+
+        # Get the number of digits
+        digits = self[u'ipatokenotpdigits']
+
+        # Truncate the digest
+        offset = ord(digest[-1]) & 0xf
+        binary = (ord(digest[offset+0]) & 0x7f) << 0x18
+        binary |= (ord(digest[offset+1]) & 0xff) << 0x10
+        binary |= (ord(digest[offset+2]) & 0xff) << 0x08
+        binary |= (ord(digest[offset+3]) & 0xff) << 0x00
+        binary = binary % (10 ** digits)
+
+        return "0" * (digits - len(str(binary))) + str(binary)

str(binary).rjust(digits, '0')

+    def __init__(self, **kwargs):
+        super(Token, self).__init__(**kwargs)
+
+        # Add in default values.
+        self.setdefault(u'ipatokenuniqueid', unicode(uuid.uuid4()))
+        self.setdefault(u'ipatokenotpkey', os.urandom(20))
+        for i in range(len(api.Object['otptoken'].params)):
+            param = api.Object['otptoken'].params[i]
+            if param.default is not None and param.name:
+                self.setdefault(param.name, param.default)
+
+        # Remove defaults that don't apply.
+        types = {
+            "HOTP": (u'ipatokenhotpcounter',),
+            "TOTP": (u'ipatokentotptimestep', u'ipatokentotpclockoffset'),
+        }
+        for k, names in types.items():
+            if k != self.type:
+                for name in names:
+                    del self[name]
+
+    def __enter__(self):
+        kwargs = {}
+        kwargs.update(self)

kwargs = dict(self)

+        # Get the owner from the user fixture.
+        for fixture in self.context:
+            if isinstance(fixture, User):
+                kwargs[u'ipatokenowner'] = fixture.username
+                break
+
+        # Add the token.
+        result = cmd('otptoken_add', **kwargs)
+
+        try:
+            # Remove the URI and validate the rest of the return value.
+            uri = result.get('result', {}).pop('uri', None)
+            expected = {}
+            for k, v in kwargs.items():
+                if k == 'setattr':
+                    continue
+
+                if isinstance(v, bool):
+                    expected[k] = (unicode(v).upper(),)
+                elif isinstance(v, int):
+                    expected[k] = (unicode(v),)
+                else:
+                    expected[k] = (v,)
+            expected[u'type'] = expected[u'type'][0].upper()
+            expected[u'dn'] = u'ipatokenuniqueid=%s,cn=otp,dc=example,dc=com'
+            expected[u'dn'] %= self[u'ipatokenuniqueid']

That only works for dc=example,dc=com; use:
DN(('ipatokenuniqueid', self[u'ipatokenuniqueid']), 'cn=otp', api.env.basedn)


+            assert_deepequal({
+                u'summary': u'Added OTP token "%s"' % 
self[u'ipatokenuniqueid'],
+                u'result': expected,
+                u'value': self[u'ipatokenuniqueid'],
+            }, result)
+
+            # Validate the URI.
+            split = urlparse.urlsplit(uri)
+            assert split.scheme == u'otpauth'
+            assert split.netloc.upper() == self.type
+            assert split.path == '/%s@%s:%s' % (
+                kwargs[u'ipatokenowner'],
+                api.env.realm,
+                self[u'ipatokenuniqueid']
+            )
+
+            # Validate the query.
+            types = {
+                "HOTP": {u'counter': self.get(u'ipatokenhotpcounter')},
+                "TOTP": {u'period': self.get(u'ipatokentotptimestep')},
+            }
+            query = {
+                u'algorithm': self.get(u'ipatokenotpalgorithm'),
+                u'issuer': u'%s@%s' % (kwargs[u'ipatokenowner'], 
api.env.realm),
+                u'digits': self.get(u'ipatokenotpdigits'),
+                u'secret': base64.b32encode(self[u'ipatokenotpkey']),
+            }
+            query.update(types.get(self.type, {}))
+            assert_deepequal(
+                {k: (unicode(v),) for k, v in query.items()},
+                urlparse.parse_qs(split.query)
+            )
+        except:
+            cmd('otptoken_del', self[u'ipatokenuniqueid'])
+            raise
+
+        return self
+
+    def __exit__(self, type, value, traceback):
+        cmd('otptoken_del', self[u'ipatokenuniqueid'])
+
+
+def auth(success, login, user, token, pwd=None, at=0):
+    if pwd is None:
+        pwd = user.password
+
+    if isinstance(at, basestring):
+        code = at
+
+    else:
+        code = token.otp(at) if token else '123456'
+        if code is None:  # Skip invalid test offsets.
+            raise unittest.SkipTest()
+
+    if success:
+        login(user.username, pwd + code)
+    else:
+        raises(AuthenticationError, login, user.username, pwd + code)
+
+
+class TestEnablement:

Classes should derive from object. (Same for TestTokens, TestSync)

+    # This describes the success conditions for authentication.
+    #   1. If user-auth-type does not include otp: password-only.
+    #   2. Otherwise, if no token exists: password-only.
+    #   3. Otherwise: password AND code.
+    #
+    # All states not accounted for here MUST fail.
+    #
+    # Format: (enabled, token created, pwd given, token given): success
+    EXPECTATIONS = {
+        (False, False, True, False): True,  # Condition 1
+        (False, True,  True, False): True,  # Condition 1
+        (True,  False, True, False): True,  # Condition 2
+        (True,  True,  True, True):  True,  # Condition 3
+    }
+
+    @fixturize(Krb5Login(), User(), (
+            None,
+            Enablement(True),
+            Enablement(False)
+        ), (
+            None,
+            Token()
+        ), (
+            (True,  None, ''),        # Password-only
+            (True,  None, 0),         # Both
+            (False, '', 1),           # Code-only
+            (False, '', ''),          # Neither
+            (False, 'xxx', 2),        # Bad password
+            (False, None, '123456'),  # Bad code
+        )
+    )
+    def test(self, login, user, enablement, token, params):
+        success, pwd, at = params
+
+        if success:
+            success = self.EXPECTATIONS.get((
+                enablement is not None,
+                token is not None,
+                pwd is None,
+                isinstance(at, int)
+            ), False)
+
+        auth(success, login, user, token, pwd, at)
+
+
+class TestTokens:
+    TODAY = datetime.now().replace(microsecond=0)
+    TOMORROW = TODAY + timedelta(1)
+    YESTERDAY = TODAY - timedelta(1)
+
+    @fixturize(
+        Krb5Login(),
+        User(ipauserauthtype=(u'otp')), (
+            Token(type=u'hotp'),
+            Token(type=u'HOTP'),
+            Token(type=u'HOTP', ipatokenhotpcounter=1000),
+
+            Token(type=u'totp'),
+            Token(type=u'TOTP'),
+            Token(type=u'TOTP', ipatokentotptimestep=60),
+            Token(type=u'TOTP', ipatokentotpclockoffset=30000),
+
+            Token(ipatokenotpalgorithm=u'sha1'),
+            Token(ipatokenotpalgorithm=u'sha256'),
+            Token(ipatokenotpalgorithm=u'sha384'),
+            Token(ipatokenotpalgorithm=u'sha512'),
+
+            Token(ipatokenotpdigits=6),
+            Token(ipatokenotpdigits=8),
+
+            Token(ipatokendisabled=False),
+            Token(ipatokennotbefore=YESTERDAY),
+            Token(ipatokennotafter=TOMORROW),
+
+            Token(ipatokendisabled=True),
+            Token(ipatokennotbefore=TOMORROW),
+            Token(ipatokennotafter=YESTERDAY),
+        ), (
+            (False, -1000),  # Check distant past OTP
+            (True,  -2),     # Check past OTP
+            (True,   0),     # Check current OTP
+            (False,  0),     # Check duplicate OTP
+            (True,   1),     # Check next OTP
+            (True,   3),     # Check future OTP
+            (False,  1000),  # Check distant future OTP
+        )
+    )
+    def test(self, login, user, token, params):
+        auth(params[0] and token.active, login, user, token, None, params[1])
+
+
+class TestSync:
+    """NOTE: this test requires ca.crt in your confdir so that the client can
+validate the server's certificate."""
+
+    @fixturize(Krb5Login(), User(ipauserauthtype=(u'otp')), (
+            Token(type=u'hotp'),
+            Token(type=u'totp')
+        ), (
+            (False, True, 0),   # Normal token operation
+            (False, False, 7),  # Skip-ahead failure
+            (True, True, 7),    # Skip-ahead success after sync
+        )
+    )
+    def test(self, login, user, token, params):
+        sync, success, at = params
+
+        if sync:
+            cmd('otptoken_sync',
+                user=user.username,
+                password=user.password,
+                first_code=unicode(token.otp(at)),
+                second_code=unicode(token.otp(at + 1)))
+            at += 2
+
+        auth(success, login, user, token, None, at)
-- 2.1.0




--
PetrĀ³
======================================================================
ERROR: ipatests.test_xmlrpc.test_otptoken_plugin.TestSync.test(Krb5Login(), 
<ipatests.test_xmlrpc.test_otptoken_plugin.User object at 0x7f0e5181d990>, 
HOTP(sha1:6|0{}), (False, False, 7))
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 59, in <lambda>
    yield (lambda *a: func(s, *a),) + ctx
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 513, in test
    auth(success, login, user, token, None, at)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 394, in auth
    raises(AuthenticationError, login, user.username, pwd + code)
  File "/home/pviktori/freeipa/ipatests/util.py", line 367, in raises
    raise ExceptionNotRaised(exception)
ExceptionNotRaised: expected AuthenticationError

======================================================================
ERROR: ipatests.test_xmlrpc.test_otptoken_plugin.TestSync.test(Krb5Login(), 
<ipatests.test_xmlrpc.test_otptoken_plugin.User object at 0x7f0e5181d990>, 
HOTP(sha1:6|0{}), (True, True, 7))
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 59, in <lambda>
    yield (lambda *a: func(s, *a),) + ctx
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 510, in test
    second_code=unicode(token.otp(at + 1)))
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 79, in cmd
    return api.Command[cmd](*args, version=API_VERSION, **kwargs)
  File "/home/pviktori/freeipa/ipalib/frontend.py", line 439, in __call__
    ret = self.run(*args, **options)
  File "/home/pviktori/freeipa/ipalib/frontend.py", line 1118, in run
    return self.forward(*args, **options)
  File "/home/pviktori/freeipa/ipalib/plugins/otptoken.py", line 540, in forward
    rsp = urllib2.build_opener(handler).open(sync_uri, query)
  File "/usr/lib64/python2.7/urllib2.py", line 404, in open
    response = self._open(req, data)
  File "/usr/lib64/python2.7/urllib2.py", line 422, in _open
    '_open', req)
  File "/usr/lib64/python2.7/urllib2.py", line 382, in _call_chain
    result = func(*args)
  File "/home/pviktori/freeipa/ipalib/plugins/otptoken.py", line 499, in 
https_open
    return self.do_open(self.__inner, req)
  File "/usr/lib64/python2.7/urllib2.py", line 1186, in do_open
    raise URLError(err)
URLError: <urlopen error [Errno 185090050] _ssl.c:344: error:0B084002:x509 
certificate routines:X509_load_cert_crl_file:system lib>

======================================================================
ERROR: ipatests.test_xmlrpc.test_otptoken_plugin.TestSync.test(Krb5Login(), 
<ipatests.test_xmlrpc.test_otptoken_plugin.User object at 0x7f0e5181d990>, 
TOTP(sha1:6|30:0{}), (False, False, 7))
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 59, in <lambda>
    yield (lambda *a: func(s, *a),) + ctx
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 513, in test
    auth(success, login, user, token, None, at)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 394, in auth
    raises(AuthenticationError, login, user.username, pwd + code)
  File "/home/pviktori/freeipa/ipatests/util.py", line 367, in raises
    raise ExceptionNotRaised(exception)
ExceptionNotRaised: expected AuthenticationError

======================================================================
ERROR: ipatests.test_xmlrpc.test_otptoken_plugin.TestSync.test(Krb5Login(), 
<ipatests.test_xmlrpc.test_otptoken_plugin.User object at 0x7f0e5181d990>, 
TOTP(sha1:6|30:0{}), (True, True, 7))
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 59, in <lambda>
    yield (lambda *a: func(s, *a),) + ctx
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 510, in test
    second_code=unicode(token.otp(at + 1)))
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 79, in cmd
    return api.Command[cmd](*args, version=API_VERSION, **kwargs)
  File "/home/pviktori/freeipa/ipalib/frontend.py", line 439, in __call__
    ret = self.run(*args, **options)
  File "/home/pviktori/freeipa/ipalib/frontend.py", line 1118, in run
    return self.forward(*args, **options)
  File "/home/pviktori/freeipa/ipalib/plugins/otptoken.py", line 540, in forward
    rsp = urllib2.build_opener(handler).open(sync_uri, query)
  File "/usr/lib64/python2.7/urllib2.py", line 404, in open
    response = self._open(req, data)
  File "/usr/lib64/python2.7/urllib2.py", line 422, in _open
    '_open', req)
  File "/usr/lib64/python2.7/urllib2.py", line 382, in _call_chain
    result = func(*args)
  File "/home/pviktori/freeipa/ipalib/plugins/otptoken.py", line 499, in 
https_open
    return self.do_open(self.__inner, req)
  File "/usr/lib64/python2.7/urllib2.py", line 1186, in do_open
    raise URLError(err)
URLError: <urlopen error [Errno 185090050] _ssl.c:344: error:0B084002:x509 
certificate routines:X509_load_cert_crl_file:system lib>

======================================================================
ERROR: ipatests.test_xmlrpc.test_otptoken_plugin.TestTokens.test(Krb5Login(), 
<ipatests.test_xmlrpc.test_otptoken_plugin.User object at 0x7f0e517e6e90>, 
TOTP(sha1:6|30:0{}), (True, -2))
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 59, in <lambda>
    yield (lambda *a: func(s, *a),) + ctx
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 486, in test
    auth(params[0] and token.active, login, user, token, None, params[1])
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 392, in auth
    login(user.username, pwd + code)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 95, in __call__
    self.login(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 150, in login
    self.kinit(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 147, in kinit
    raise AuthenticationError(out, err)
AuthenticationError: ('Enter OTP Token Value: \n', 'kinit: Preauthentication 
failed while getting initial credentials\n')

======================================================================
ERROR: ipatests.test_xmlrpc.test_otptoken_plugin.TestTokens.test(Krb5Login(), 
<ipatests.test_xmlrpc.test_otptoken_plugin.User object at 0x7f0e517e6e90>, 
TOTP(sha1:6|30:0{}), (True, -2))
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 59, in <lambda>
    yield (lambda *a: func(s, *a),) + ctx
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 486, in test
    auth(params[0] and token.active, login, user, token, None, params[1])
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 392, in auth
    login(user.username, pwd + code)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 95, in __call__
    self.login(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 150, in login
    self.kinit(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 147, in kinit
    raise AuthenticationError(out, err)
AuthenticationError: ('Enter OTP Token Value: \n', 'kinit: Preauthentication 
failed while getting initial credentials\n')

======================================================================
ERROR: ipatests.test_xmlrpc.test_otptoken_plugin.TestTokens.test(Krb5Login(), 
<ipatests.test_xmlrpc.test_otptoken_plugin.User object at 0x7f0e517e6e90>, 
TOTP(sha1:6|60:0{}), (True, -2))
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 59, in <lambda>
    yield (lambda *a: func(s, *a),) + ctx
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 486, in test
    auth(params[0] and token.active, login, user, token, None, params[1])
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 392, in auth
    login(user.username, pwd + code)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 95, in __call__
    self.login(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 150, in login
    self.kinit(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 147, in kinit
    raise AuthenticationError(out, err)
AuthenticationError: ('Enter OTP Token Value: \n', 'kinit: Preauthentication 
failed while getting initial credentials\n')

======================================================================
ERROR: ipatests.test_xmlrpc.test_otptoken_plugin.TestTokens.test(Krb5Login(), 
<ipatests.test_xmlrpc.test_otptoken_plugin.User object at 0x7f0e517e6e90>, 
TOTP(sha1:6|30:30000{}), (True, -2))
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 59, in <lambda>
    yield (lambda *a: func(s, *a),) + ctx
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 486, in test
    auth(params[0] and token.active, login, user, token, None, params[1])
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 392, in auth
    login(user.username, pwd + code)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 95, in __call__
    self.login(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 150, in login
    self.kinit(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 147, in kinit
    raise AuthenticationError(out, err)
AuthenticationError: ('Enter OTP Token Value: \n', 'kinit: Preauthentication 
failed while getting initial credentials\n')

======================================================================
ERROR: ipatests.test_xmlrpc.test_otptoken_plugin.TestTokens.test(Krb5Login(), 
<ipatests.test_xmlrpc.test_otptoken_plugin.User object at 0x7f0e517e6e90>, 
TOTP(sha1:6|30:0{}), (True, -2))
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 59, in <lambda>
    yield (lambda *a: func(s, *a),) + ctx
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 486, in test
    auth(params[0] and token.active, login, user, token, None, params[1])
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 392, in auth
    login(user.username, pwd + code)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 95, in __call__
    self.login(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 150, in login
    self.kinit(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 147, in kinit
    raise AuthenticationError(out, err)
AuthenticationError: ('Enter OTP Token Value: \n', 'kinit: Preauthentication 
failed while getting initial credentials\n')

======================================================================
ERROR: ipatests.test_xmlrpc.test_otptoken_plugin.TestTokens.test(Krb5Login(), 
<ipatests.test_xmlrpc.test_otptoken_plugin.User object at 0x7f0e517e6e90>, 
TOTP(sha256:6|30:0{}), (True, -2))
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 59, in <lambda>
    yield (lambda *a: func(s, *a),) + ctx
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 486, in test
    auth(params[0] and token.active, login, user, token, None, params[1])
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 392, in auth
    login(user.username, pwd + code)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 95, in __call__
    self.login(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 150, in login
    self.kinit(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 147, in kinit
    raise AuthenticationError(out, err)
AuthenticationError: ('Enter OTP Token Value: \n', 'kinit: Preauthentication 
failed while getting initial credentials\n')

======================================================================
ERROR: ipatests.test_xmlrpc.test_otptoken_plugin.TestTokens.test(Krb5Login(), 
<ipatests.test_xmlrpc.test_otptoken_plugin.User object at 0x7f0e517e6e90>, 
TOTP(sha384:6|30:0{}), (True, -2))
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 59, in <lambda>
    yield (lambda *a: func(s, *a),) + ctx
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 486, in test
    auth(params[0] and token.active, login, user, token, None, params[1])
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 392, in auth
    login(user.username, pwd + code)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 95, in __call__
    self.login(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 150, in login
    self.kinit(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 147, in kinit
    raise AuthenticationError(out, err)
AuthenticationError: ('Enter OTP Token Value: \n', 'kinit: Preauthentication 
failed while getting initial credentials\n')

======================================================================
ERROR: ipatests.test_xmlrpc.test_otptoken_plugin.TestTokens.test(Krb5Login(), 
<ipatests.test_xmlrpc.test_otptoken_plugin.User object at 0x7f0e517e6e90>, 
TOTP(sha512:6|30:0{}), (True, -2))
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 59, in <lambda>
    yield (lambda *a: func(s, *a),) + ctx
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 486, in test
    auth(params[0] and token.active, login, user, token, None, params[1])
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 392, in auth
    login(user.username, pwd + code)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 95, in __call__
    self.login(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 150, in login
    self.kinit(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 147, in kinit
    raise AuthenticationError(out, err)
AuthenticationError: ('Enter OTP Token Value: \n', 'kinit: Preauthentication 
failed while getting initial credentials\n')

======================================================================
ERROR: ipatests.test_xmlrpc.test_otptoken_plugin.TestTokens.test(Krb5Login(), 
<ipatests.test_xmlrpc.test_otptoken_plugin.User object at 0x7f0e517e6e90>, 
TOTP(sha1:6|30:0{}), (True, -2))
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 59, in <lambda>
    yield (lambda *a: func(s, *a),) + ctx
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 486, in test
    auth(params[0] and token.active, login, user, token, None, params[1])
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 392, in auth
    login(user.username, pwd + code)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 95, in __call__
    self.login(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 150, in login
    self.kinit(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 147, in kinit
    raise AuthenticationError(out, err)
AuthenticationError: ('Enter OTP Token Value: \n', 'kinit: Preauthentication 
failed while getting initial credentials\n')

======================================================================
ERROR: ipatests.test_xmlrpc.test_otptoken_plugin.TestTokens.test(Krb5Login(), 
<ipatests.test_xmlrpc.test_otptoken_plugin.User object at 0x7f0e517e6e90>, 
TOTP(sha1:8|30:0{}), (True, -2))
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 59, in <lambda>
    yield (lambda *a: func(s, *a),) + ctx
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 486, in test
    auth(params[0] and token.active, login, user, token, None, params[1])
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 392, in auth
    login(user.username, pwd + code)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 95, in __call__
    self.login(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 150, in login
    self.kinit(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 147, in kinit
    raise AuthenticationError(out, err)
AuthenticationError: ('Enter OTP Token Value: \n', 'kinit: Preauthentication 
failed while getting initial credentials\n')

======================================================================
ERROR: ipatests.test_xmlrpc.test_otptoken_plugin.TestTokens.test(Krb5Login(), 
<ipatests.test_xmlrpc.test_otptoken_plugin.User object at 0x7f0e517e6e90>, 
TOTP(sha1:6|30:0{'disabled': False}), (True, -2))
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 59, in <lambda>
    yield (lambda *a: func(s, *a),) + ctx
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 486, in test
    auth(params[0] and token.active, login, user, token, None, params[1])
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 392, in auth
    login(user.username, pwd + code)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 95, in __call__
    self.login(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 150, in login
    self.kinit(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 147, in kinit
    raise AuthenticationError(out, err)
AuthenticationError: ('Enter OTP Token Value: \n', 'kinit: Preauthentication 
failed while getting initial credentials\n')

======================================================================
ERROR: ipatests.test_xmlrpc.test_otptoken_plugin.TestTokens.test(Krb5Login(), 
<ipatests.test_xmlrpc.test_otptoken_plugin.User object at 0x7f0e517e6e90>, 
TOTP(sha1:6|30:0{'notbefore': '20150111151851Z'}), (True, -2))
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 59, in <lambda>
    yield (lambda *a: func(s, *a),) + ctx
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 486, in test
    auth(params[0] and token.active, login, user, token, None, params[1])
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 392, in auth
    login(user.username, pwd + code)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 95, in __call__
    self.login(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 150, in login
    self.kinit(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 147, in kinit
    raise AuthenticationError(out, err)
AuthenticationError: ('Enter OTP Token Value: \n', 'kinit: Preauthentication 
failed while getting initial credentials\n')

======================================================================
ERROR: ipatests.test_xmlrpc.test_otptoken_plugin.TestTokens.test(Krb5Login(), 
<ipatests.test_xmlrpc.test_otptoken_plugin.User object at 0x7f0e517e6e90>, 
TOTP(sha1:6|30:0{'notafter': '20150113151851Z'}), (True, -2))
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 59, in <lambda>
    yield (lambda *a: func(s, *a),) + ctx
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 486, in test
    auth(params[0] and token.active, login, user, token, None, params[1])
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 392, in auth
    login(user.username, pwd + code)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 95, in __call__
    self.login(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 150, in login
    self.kinit(uid, pwd)
  File "/home/pviktori/freeipa/ipatests/test_xmlrpc/test_otptoken_plugin.py", 
line 147, in kinit
    raise AuthenticationError(out, err)
AuthenticationError: ('Enter OTP Token Value: \n', 'kinit: Preauthentication 
failed while getting initial credentials\n')

----------------------------------------------------------------------
Ran 175 tests in 174.086s

FAILED (SKIP=6, errors=17)
======================================================================
FAILED under '/usr/bin/python2.7'

** FAIL **
_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to