Exemple #1
0
    def test_web_api_auth(self):

        with EmailProviderServer(self, 20) as smtpsvc:

            # Authenticate over Web API
            validate = Validate(self.http_protocol, self.http_host,
                                self.http_port, self.http_username,
                                self.http_password)
            access_granted, validate_resp = validate.validate(user=self.username + "@" + self.realm_name,
                                                              password=self.email_token_pin)
            self.assertFalse(access_granted,
                             "Should return false because this request only triggers the challenge.")
            try:
                message = validate_resp['detail']['message']
            except KeyError:
                self.fail("detail.message should be present %r" %
                          validate_resp)
            self.assertEqual(message,
                             "e-mail sent successfully",
                             "Wrong validate response %r" % validate_resp)
            otp = smtpsvc.get_otp()

        access_granted, validate_resp = validate.validate(user=self.username + "@" + self.realm_name,
                                                          password=self.email_token_pin + otp)
        self.assertTrue(access_granted,
                        "Could not authenticate user %s %r" % (self.username, validate_resp))
Exemple #2
0
    def test_web_api_auth(self):

        with EmailProviderServer(self, 20) as smtpsvc:

            # Authenticate over Web API
            validate = Validate(self.http_protocol, self.http_host,
                                self.http_port, self.http_username,
                                self.http_password)
            access_granted, validate_resp = validate.validate(user=self.username + "@" + self.realm_name,
                                                              password=self.email_token_pin)
            self.assertFalse(access_granted,
                             "Should return false because this request only triggers the challenge.")
            try:
                message = validate_resp['detail']['message']
            except KeyError:
                self.fail("detail.message should be present %r" %
                          validate_resp)
            self.assertEqual(message,
                             "e-mail sent successfully",
                             "Wrong validate response %r" % validate_resp)
            otp = smtpsvc.get_otp()

        access_granted, validate_resp = validate.validate(user=self.username + "@" + self.realm_name,
                                                          password=self.email_token_pin + otp)
        self.assertTrue(access_granted,
                        "Could not authenticate user %s %r" % (self.username, validate_resp))
Exemple #3
0
    def setUp(self):
        """ Some test set up steps """

        # Initialize GUI attributes
        self.token_view = self.manage_ui.token_view
        self.user_view = self.manage_ui.user_view

        # Delete from previous tests:
        # - resolvers
        # - realms
        # - policies
        # - tokens

        self.reset_resolvers_and_realms()
        self.manage_ui.policy_view.clear_policies_via_api()
        self.token_view.clear_tokens_via_api()

        # Create LDAP UserIdResolver
        ldap_data = data.musicians_ldap_resolver
        self.ldap_resolver = self.useridresolver_manager.create_resolver(
            ldap_data)

        # Create SQL UserIdResolver
        sql_data = data.sql_resolver

        self.sql_resolver = self.useridresolver_manager.create_resolver(
            sql_data)
        self.useridresolver_manager.close()

        # Create realms
        self.two_resolvers_realm_name = "two_resolvers_realm"
        self.realm_manager.create(self.two_resolvers_realm_name, [self.ldap_resolver,
                                                                  self.sql_resolver])
        self.realm_manager.close()

        # Set seed of HMAC token
        self.seed_oath137332 = "ff06df50017d3b981cfbc4ec4d374040164d8d19"
        self.serial_oath137332 = "oath137332"

        # Import some test tokens
        self.import_tokens()

        # Create validate/check instance
        self.validate = Validate(self.http_protocol,
                                 self.http_host,
                                 self.http_port,
                                 self.http_username,
                                 self.http_password)
Exemple #4
0
    def test_web_api_auth(self):

        with EmailProviderServer(self.testcase, 20) as smtpsvc:

            # Authenticate over Web API
            validate = Validate(
                self.testcase.http_protocol,
                self.testcase.http_host,
                self.testcase.http_port,
                self.testcase.http_username,
                self.testcase.http_password,
            )
            access_granted, validate_resp = validate.validate(
                user=self.data["username"] + "@" + self.data["realm_name"],
                password=self.data["email_token_pin"],
            )
            assert (
                not access_granted
            ), "Should return false because this request only triggers the challenge."
            try:
                message = validate_resp["detail"]["message"]
            except KeyError as e:
                raise KeyError(e.message +
                               " | detail.message should be present %r" %
                               validate_resp)
            assert message == "e-mail sent successfully", (
                "Wrong validate response %r" % validate_resp)
            otp = smtpsvc.get_otp()

        access_granted, validate_resp = validate.validate(
            user=self.data["username"] + "@" + self.data["realm_name"],
            password=self.data["email_token_pin"] + otp,
        )
        assert access_granted, "Could not authenticate user %s %r" % (
            self.data["username"],
            validate_resp,
        )
Exemple #5
0
    def setUp(self):
        """ Some test set up steps """

        # Initialize GUI attributes
        self.token_view = self.manage_ui.token_view
        self.user_view = self.manage_ui.user_view

        # Delete from previous tests:
        # - resolvers
        # - realms
        # - policies
        # - tokens

        self.reset_resolvers_and_realms()
        self.manage_ui.policy_view.clear_policies_via_api()
        self.token_view.clear_tokens_via_api()

        # Create LDAP UserIdResolver
        ldap_data = data.musicians_ldap_resolver
        self.ldap_resolver = self.useridresolver_manager.create_resolver(
            ldap_data)

        # Create SQL UserIdResolver
        sql_data = data.sql_resolver

        self.sql_resolver = self.useridresolver_manager.create_resolver(
            sql_data)
        self.useridresolver_manager.close()

        # Create realms
        self.two_resolvers_realm_name = "two_resolvers_realm"
        self.realm_manager.create(self.two_resolvers_realm_name, [self.ldap_resolver,
                                                                  self.sql_resolver])
        self.realm_manager.close()

        # Set seed of HMAC token
        self.seed_oath137332 = "ff06df50017d3b981cfbc4ec4d374040164d8d19"
        self.serial_oath137332 = "oath137332"

        # Import some test tokens
        self.import_tokens()

        # Create validate/check instance
        self.validate = Validate(self.http_protocol,
                                 self.http_host,
                                 self.http_port,
                                 self.http_username,
                                 self.http_password)
Exemple #6
0
    def test_enroll(self):
        """
        Enroll sms token. After enrolling it verifies that the token info contains the
        correct sms. Then a user is authenticated using challenge response over RADIUS
        and Web API.
        """

        sms_provider_config = get_from_tconfig(['sms_token', 'sms_provider_config'])
        radius_server = get_from_tconfig(['radius', 'server'], default=self.http_host)
        radius_secret = get_from_tconfig(['radius', 'secret'], required=True)
        disable_radius = get_from_tconfig(['radius', 'disable'], default='False')

        driver = self.driver

        # Create Passwd UserIdResolver
        #
        # Expected content of /etc/se_mypasswd is:
        #
        # hans:x:42:0:Hans Müller,Room 22,+49(0)1234-22,+49(0)5678-22,[email protected]:x:x
        # susi:x:1336:0:Susanne Bauer,Room 23,+49(0)1234-24,+49(0)5678-23,[email protected]:x:x
        # rollo:x:21:0:Rollobert Fischer,Room 24,+49(0)1234-24,+49(0)5678-24,[email protected]:x:x
        #
        passwd_name = "SE_myPasswd"
        passwd_id_resolver = PasswdUserIdResolver(passwd_name, driver,
                                                  self.base_url, filename="/etc/se_mypasswd")
        time.sleep(1)

        # Create realm for all resolvers
        resolvers_realm = [passwd_id_resolver]
        realm_name = "SE_smstoken"
        realm = Realm(realm_name, resolvers_realm)
        realm.create(driver, self.base_url)
        time.sleep(1)

        # Set SMTP sms config
        if sms_provider_config:
            parameters = {
                'SMSProvider': 'smsprovider.SmtpSMSProvider.SmtpSMSProvider',
                'SMSProviderConfig': sms_provider_config
            }
            set_config = SetConfig(self.http_protocol, self.http_host, self.http_username,
                                   self.http_password)
            result = set_config.setConfig(parameters)
            self.assertTrue(result, "It was not possible to set the config")
        else:
            print "No sms_provider_config in testconfig file. Using LinOTP default."

        # Enroll sms token
        driver.get(self.base_url + "/manage/")
        time.sleep(2)
        user_view = UserView(driver, self.base_url, realm_name)
        username = "******"
        user_view.select_user(username)
        sms_token_pin = "1234"
        description = "Rolled out by Selenium"
        sms_token = SmsToken(driver=self.driver,
                             base_url=self.base_url,
                             pin=sms_token_pin,
                             description=description)
        token_view = TokenView(self.driver, self.base_url)
        token_info = token_view.get_token_info(sms_token.serial)
        expected_phone_number = "+49(0)1234-24"
        self.assertEqual(expected_phone_number, token_info['LinOtp.TokenInfo']['phone'],
                         "Wrong phone number was set for sms token.")

        # Authenticate with RADIUS
        if disable_radius.lower() == 'true':
            print "Testconfig option radius.disable is set to True. Skipping RADIUS test!"
        else:
            call_array = "linotp-auth-radius -f ../../../test.ini".split()
            call_array.extend(['-u', username + "@" + realm_name,
                               '-p', '1234',
                               '-s', radius_secret,
                               '-r', radius_server])
            rad1 = check_output(call_array)
            m = re.search(r"State:\['(\d+)'\]", rad1)
            self.assertTrue(m is not None,
                            "'State' not found in linotp-auth-radius output. %r" % rad1)
            state = m.group(1)
            print "State: %s" % state
            otp = self._get_otp()
            call_array = "linotp-auth-radius -f ../../../test.ini".split()
            call_array.extend(['-u', username + "@" + realm_name,
                               '-p', otp,
                               '-t', state,
                               '-s', radius_secret,
                               '-r', radius_server])
            rad2 = check_output(call_array)
            self.assertTrue("Access granted to user " + username in rad2,
                            "Access not granted to user. %r" % rad2)

        # Authenticate over Web API
        validate = Validate(self.http_protocol, self.http_host, self.http_username,
                            self.http_password)
        access_granted, validate_resp = validate.validate(user=username + "@" + realm_name,
                                            password=sms_token_pin)
        self.assertFalse(access_granted,
                         "Should return false because this request only triggers the challenge.")
        try:
            message = validate_resp['detail']['message']
        except KeyError:
            self.fail("detail.message should be present %r" % validate_resp)
        self.assertEqual(message,
                         "sms submitted",
                         "Wrong validate response %r" % validate_resp)
        otp = self._get_otp()
        access_granted, validate_resp = validate.validate(user=username + "@" + realm_name,
                                            password=sms_token_pin + otp)
        self.assertTrue(access_granted,
                        "Could not authenticate user %s %r" % (username, validate_resp))
Exemple #7
0
class TestPolicies(TestCase):
    """Test Policies"""

    # GUI attributes
    token_view = None
    user_view = None

    # Other testing data
    seed_oath137332 = None
    serial_oath137332 = None

    ldap_resolver = None
    sql_resolver = None

    two_resolvers_realm_name = None

    # validate/check instance
    validate = None

    @pytest.fixture(autouse=True)
    def setUp(self):
        """ Some test set up steps """

        # Initialize GUI attributes
        self.token_view = self.manage_ui.token_view
        self.user_view = self.manage_ui.user_view

        # Delete from previous tests:
        # - resolvers
        # - realms
        # - policies
        # - tokens

        self.reset_resolvers_and_realms()
        self.manage_ui.policy_view.clear_policies_via_api()
        self.token_view.clear_tokens_via_api()

        # Create LDAP UserIdResolver
        ldap_data = data.musicians_ldap_resolver
        self.ldap_resolver = self.useridresolver_manager.create_resolver(
            ldap_data)

        # Create SQL UserIdResolver
        sql_data = data.sql_resolver

        self.sql_resolver = self.useridresolver_manager.create_resolver(
            sql_data)
        self.useridresolver_manager.close()

        # Create realms
        self.two_resolvers_realm_name = "two_resolvers_realm"
        self.realm_manager.create(self.two_resolvers_realm_name, [self.ldap_resolver,
                                                                  self.sql_resolver])
        self.realm_manager.close()

        # Set seed of HMAC token
        self.seed_oath137332 = "ff06df50017d3b981cfbc4ec4d374040164d8d19"
        self.serial_oath137332 = "oath137332"

        # Import some test tokens
        self.import_tokens()

        # Create validate/check instance
        self.validate = Validate(self.http_protocol,
                                 self.http_host,
                                 self.http_port,
                                 self.http_username,
                                 self.http_password)

    def test_otppin_3(self):
        """
        Test policy otppin=3 (ignore_pin) : TestRail C1910

        First we do some authentications with user a with
        otppin=3.

        Then we change the policy, that only users from
        a specific resolver (user B) get through with otppin=3.
        """

        # Define user A
        user_a = "bach"
        user_a_pw = "Test123!"
        user_a_realm = self.two_resolvers_realm_name
        user_a_token_pin = "1234"

        # Define user B
        user_b = "kay"
        user_b_pw = "test123!"
        user_b_realm = self.two_resolvers_realm_name
        user_b_token_pin = ""
        user_b_token_key = "3132333435363738393031323334353637383930"

        # Unhexlify for hotp.generate method
        user_b_token_seed_bin = binascii.unhexlify(user_b_token_key)

        # Create Token
        self.user_view.select_user(user_b)
        self.manage_ui.token_enroll.create_hotp_token(
                  pin=user_b_token_pin,
                  hmac_key=user_b_token_key)

        ###############################
        ##
        # First some tests with user A
        ##
        ###############################

        # Create policy
        Policy(self.manage_ui, "otppin3", "authentication",
               "otppin=3",
               "*",
               "*")  # user = "******"

        # Create event based HMAC token
        # Tokens were imported by self.import_tokens()
        self.user_view.select_realm(user_a_realm)
        self.user_view.select_user(user_a)

        # Unhexlify for hotp.generate method
        seed_oath137332_bin = binascii.unhexlify(self.seed_oath137332)

        # Assign token to user
        # Set a pin
        self.token_view.assign_token(self.serial_oath137332,
                                     user_a_token_pin)

        # authentication tests
        # - PIN+OTP -> successfully
        # - PW+OTP -> successfully
        # - nonsense+OTP -> successfully
        # - OTP -> successfully
        # - wront OTP -> fails

        hotp_a = HmacOtp()

        # PIN+OTP -> success
        otp = user_a_token_pin + \
            hotp_a.generate(counter=0,
                            key=seed_oath137332_bin)

        access_granted, _ = self.validate.validate(user=user_a + "@" +
                                                   user_a_realm, password=otp)
        assert access_granted, "OTPPIN=3, PIN+OTP: " + otp + " for user " + \
                        user_a + "@" + user_a_realm + " returned False"

        # PW+OTP -> success
        otp = user_a_pw + \
            hotp_a.generate(counter=1,
                            key=seed_oath137332_bin)

        access_granted, _ = self.validate.validate(user=user_a + "@" +
                                                   user_a_realm, password=otp)
        assert access_granted, "OTPPIN=3, PW+OTP: " + otp + " for user " + \
                        user_a + "@" + user_a_realm + " returned False"

        # nonsense+OTP -> success
        otp = "nonsense" + \
            hotp_a.generate(counter=2,
                            key=seed_oath137332_bin)

        access_granted, _ = self.validate.validate(user=user_a + "@" +
                                                   user_a_realm, password=otp)
        assert access_granted, "OTPPIN=3, nonsense+OTP: " + otp + " for user " + \
                        user_a + "@" + user_a_realm + " returned False"

        # OTP -> success
        otp = hotp_a.generate(counter=3,
                              key=seed_oath137332_bin)

        access_granted, _ = self.validate.validate(user=user_a + "@" +
                                                   user_a_realm, password=otp)
        assert access_granted, "OTPPIN=3, OTP: " + otp + " for user " + \
                        user_a + "@" + user_a_realm + " returned False"

        # wrong OTP -> fails
        otp = "111111"

        access_denied, _ = self.validate.validate(user=user_a + "@" +
                                                  user_a_realm, password=otp)
        assert not access_denied, "OTPPIN=3, wrong OTP: " + otp + " for user " + \
                         user_a + "@" + user_a_realm + " returned True"

        ###########################
        #
        # Bring user B into game
        #
        # change policy
        #    user = resolverB:
        #
        # So the ignore_pin should
        # should only affect users
        # in resolverB
        #
        ###########################

        # Change policy
        Policy(self.manage_ui, "otppin3", "authentication",
               "otppin=3",
               "*",  # realm
               data.sql_resolver["name"] + ":")  # pick specific resolver

        hotp_b = HmacOtp()

        # PIN+OTP -> success
        otp = user_b_token_pin + \
            hotp_b.generate(counter=0,
                            key=user_b_token_seed_bin)

        access_granted, _ = self.validate.validate(user=user_b + "@" +
                                                   user_b_realm, password=otp)
        assert access_granted, "OTPPIN=3, PIN+OTP: " + otp + " for user " + \
                        user_b + "@" + user_b_realm + " returned False"

        # PW+OTP -> success
        otp = user_b_pw + \
            hotp_b.generate(counter=1,
                            key=user_b_token_seed_bin)

        access_granted, _ = self.validate.validate(user=user_b + "@" +
                                                   user_b_realm, password=otp)
        assert access_granted, "OTPPIN=3, PW+OTP: " + otp + " for user " + \
                        user_b + "@" + user_b_realm + " returned False"

        # OTP -> success
        otp = hotp_b.generate(counter=2,
                              key=user_b_token_seed_bin)

        access_granted, _ = self.validate.validate(user=user_b + "@" +
                                                   user_b_realm, password=otp)
        assert access_granted, "OTPPIN=3, OTP: " + otp + " for user " + \
                        user_b + "@" + user_b_realm + " returned False"

        # wrong OTP -> fails
        otp = "111111"

        access_denied, _ = self.validate.validate(user=user_b + "@" +
                                                  user_b_realm, password=otp)
        assert not access_denied, "OTPPIN=3, wrong OTP: " + otp + " for user " + \
                         user_b + "@" + user_b_realm + " returned False"

        # Back to user A and try to authenticate
        # with changed policy!

        # OTP -> fails
        otp = hotp_a.generate(counter=4,
                              inc_counter=False,
                              key=seed_oath137332_bin)

        access_denied, _ = self.validate.validate(user=user_a + "@" +
                                                  user_a_realm, password=otp)
        assert not access_denied, "OTPPIN=3, OTP: " + otp + " for user " + \
                         user_a + "@" + user_a_realm + " returned True"

        # PIN+OTP -> success
        otp = user_a_token_pin + \
            hotp_a.generate(counter=4,
                            key=seed_oath137332_bin)

        access_granted, _ = self.validate.validate(user=user_a + "@" +
                                                   user_a_realm, password=otp)
        assert access_granted, "OTPPIN=3, PIN+OTP: " + otp + " for user " + \
                        user_a + "@" + user_a_realm + " returned False"

    def import_tokens(self):
        """ Import some tokens """

        file_content = """<Tokens>
    <Token serial="00040008CFA5">
    <CaseModel>5</CaseModel>
    <Model>101</Model>
    <ProductionDate>02/19/2009</ProductionDate>
    <ProductName>Safeword Alpine</ProductName>
    <Applications>
    <Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb9}">
    <Seed>123412354</Seed>
    <MovingFactor>1</MovingFactor>
    </Application>
    </Applications>
    </Token>
    <Token serial="00040008CFA52">
    <CaseModel>5</CaseModel>
    <Model>101</Model>
    <ProductionDate>02/19/2009</ProductionDate>
    <ProductName>Safeword Alpine</ProductName>
    <Applications>
    <Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb9}">
    <Seed>123456</Seed>
    <MovingFactor>1</MovingFactor>
    </Application>
    </Applications>
    </Token>
    <Token serial="oath137332">
    <CaseModel>5</CaseModel>
    <Model>101</Model>
    <ProductionDate>02/19/2009</ProductionDate>
    <ProductName>Safeword Alpine</ProductName>
    <Applications>
    <Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb1}">
    <Seed>""" + self.seed_oath137332 + """</Seed>
    <MovingFactor>1</MovingFactor>
    </Application>
    </Applications>
    </Token>
    <Token serial="oath12482B">
    <CaseModel>5</CaseModel>
    <Model>101</Model>
    <ProductionDate>02/19/2009</ProductionDate>
    <ProductName>Safeword Alpine</ProductName>
    <Applications>
    <Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb2}">
    <Seed>6ec1d0e9915a2bebf84745b318e39e481249c1eb</Seed>
    <MovingFactor>1</MovingFactor>
    </Application>
    </Applications>
    </Token>
    </Tokens>"""

        token_import_aladdin = TokenImportAladdin(self.manage_ui)
        token_import_aladdin.do_import(file_content)
Exemple #8
0
    def test_enroll(self):
        """
        Enroll sms token. After enrolling it verifies that the token info contains the
        correct sms. Then a user is authenticated using challenge response over RADIUS
        and Web API.
        """

        sms_provider_config = get_from_tconfig(['sms_token', 'sms_provider_config'])
        radius_server = get_from_tconfig(
            ['radius', 'server'],
            default=self.http_host.split(':')[0],
            )
        radius_secret = get_from_tconfig(['radius', 'secret'], required=True)
        disable_radius = get_from_tconfig(['radius', 'disable'], default='False')

        driver = self.driver

        # Create Passwd UserIdResolver
        #
        # Expected content of /etc/se_mypasswd is:
        #
        # hans:x:42:0:Hans Müller,Room 22,+49(0)1234-22,+49(0)5678-22,[email protected]:x:x
        # susi:x:1336:0:Susanne Bauer,Room 23,+49(0)1234-24,+49(0)5678-23,[email protected]:x:x
        # rollo:x:21:0:Rollobert Fischer,Room 24,+49(0)1234-24,+49(0)5678-24,[email protected]:x:x
        #
        passwd_name = "SE_myPasswd"
        passwd_id_resolver = PasswdUserIdResolver(passwd_name, driver,
                                                  self.base_url, filename="/etc/se_mypasswd")
        time.sleep(1)

        # Create realm for all resolvers
        resolvers_realm = [passwd_id_resolver]
        realm_name = "SE_smstoken"
        realm = Realm(realm_name, resolvers_realm)
        realm.create(driver, self.base_url)
        time.sleep(1)

        # Set SMTP sms config
        if sms_provider_config:
            parameters = {
                'SMSProvider': 'smsprovider.SmtpSMSProvider.SmtpSMSProvider',
                'SMSProviderConfig': sms_provider_config
            }
            set_config = SetConfig(self.http_protocol, self.http_host, self.http_username,
                                   self.http_password)
            result = set_config.setConfig(parameters)
            self.assertTrue(result, "It was not possible to set the config")
        else:
            print "No sms_provider_config in testconfig file. Using LinOTP default."

        # Enroll sms token
        driver.get(self.base_url + "/manage/")
        time.sleep(2)
        user_view = UserView(driver, self.base_url, realm_name)
        username = "******"
        user_view.select_user(username)
        sms_token_pin = "1234"
        description = "Rolled out by Selenium"
        sms_token = SmsToken(driver=self.driver,
                             base_url=self.base_url,
                             pin=sms_token_pin,
                             description=description)
        token_view = TokenView(self.driver, self.base_url)
        token_info = token_view.get_token_info(sms_token.serial)
        expected_phone_number = "+49(0)1234-24"
        self.assertEqual(expected_phone_number, token_info['LinOtp.TokenInfo']['phone'],
                         "Wrong phone number was set for sms token.")

        # Authenticate with RADIUS
        if disable_radius.lower() == 'true':
            print "Testconfig option radius.disable is set to True. Skipping RADIUS test!"
        else:
            call_array = "linotp-auth-radius -f ../../../test.ini".split()
            call_array.extend(['-u', username + "@" + realm_name,
                               '-p', '1234',
                               '-s', radius_secret,
                               '-r', radius_server])
            rad1 = check_output(call_array)
            m = re.search(r"State:\['(\d+)'\]", rad1)
            self.assertTrue(m is not None,
                            "'State' not found in linotp-auth-radius output. %r" % rad1)
            state = m.group(1)
            print "State: %s" % state
            otp = self._get_otp()
            call_array = "linotp-auth-radius -f ../../../test.ini".split()
            call_array.extend(['-u', username + "@" + realm_name,
                               '-p', otp,
                               '-t', state,
                               '-s', radius_secret,
                               '-r', radius_server])
            rad2 = check_output(call_array)
            self.assertTrue("Access granted to user " + username in rad2,
                            "Access not granted to user. %r" % rad2)

        # Authenticate over Web API
        validate = Validate(self.http_protocol, self.http_host, self.http_username,
                            self.http_password)
        access_granted, validate_resp = validate.validate(user=username + "@" + realm_name,
                                            password=sms_token_pin)
        self.assertFalse(access_granted,
                         "Should return false because this request only triggers the challenge.")
        try:
            message = validate_resp['detail']['message']
        except KeyError:
            self.fail("detail.message should be present %r" % validate_resp)
        self.assertEqual(message,
                         "sms submitted",
                         "Wrong validate response %r" % validate_resp)
        otp = self._get_otp()
        access_granted, validate_resp = validate.validate(user=username + "@" + realm_name,
                                            password=sms_token_pin + otp)
        self.assertTrue(access_granted,
                        "Could not authenticate user %s %r" % (username, validate_resp))
Exemple #9
0
    def test_scenario01(self):
        """
        Scenario01 (https://wally/projects/linotp/wiki/TestingTest_Szenario_01)
        """

        driver = self.testcase.driver

        token_view = self.testcase.manage_ui.token_view
        user_view = self.testcase.manage_ui.user_view
        token_enroll = self.testcase.manage_ui.token_enroll

        selfservice = SelfService(self.testcase)

        # reset all views
        self.testcase.reset_resolvers_and_realms()
        self.testcase.manage_ui.policy_view.clear_policies()
        token_view.delete_all_tokens()

        self._announce_test("1. UserIdResolver anlegen")
        # Create LDAP UserIdResolver
        ldap_data = data.musicians_ldap_resolver
        ldap_resolver = self.testcase.useridresolver_manager.create_resolver(
            ldap_data)

        # Create SQL UserIdResolver
        sql_data = data.sql_resolver

        sql_resolver = self.testcase.useridresolver_manager.create_resolver(
            sql_data)
        self.testcase.useridresolver_manager.close()

        # Create realm for all resolvers
        realm_name1 = "SE_scenario01_realm1"
        realm_name2 = "SE_scenario01_realm2"

        self.testcase.realm_manager.create(realm_name1, [ldap_resolver])
        self.testcase.realm_manager.create(realm_name2, [sql_resolver])
        self.testcase.realm_manager.close()

        self._announce_test(
            "2. In Management Webinterface, check that all users are visible")

        self.check_users(realm_name1, ldap_data)
        self.check_users(realm_name2, sql_data)

        self._announce_test("3. eToken.xml ueber das Webinterface importieren")

        token_import_aladdin = TokenImportAladdin(self.testcase.manage_ui)

        aladdin_xml_path = os.path.join(self.testcase.manage_ui.test_data_dir,
                                        "aladdin.xml")
        token_import_aladdin.do_import(file_path=aladdin_xml_path)

        serial_token_bach = "oath137332"
        test1_realm = realm_name1.lower()

        self._announce_test(
            "4. Im Management Webinterface nun eine Policy anlegen")

        Policy(
            self.testcase.manage_ui,
            "SE_scenario01",
            "selfservice",
            "enrollMOTP, setOTPPIN, setMOTPPIN, resync, disable ",
            test1_realm,
        )

        self._announce_test("5. eToken zuweisen")

        user_view.select_realm(test1_realm)
        user_view.select_user("bach")

        token_view.assign_token(serial_token_bach, "1234")

        self._announce_test("6. Remote Token zuweisen")

        user_view.select_user("debussy")
        serial_token_debussy = token_enroll.create_remote_token(
            url="https://billybones",
            remote_serial="LSSP0002F653",
            pin="1234",
            remote_otp_length=6,
        )

        self._announce_test("7. Spass-Token zuweisen")

        user_view.select_user("beethoven")
        beethoven_token_password = "******"
        serial_token_beethoven = token_enroll.create_static_password_token(
            password=beethoven_token_password,
            description="Password Token enrolled with Selenium",
        )

        self._announce_test("8. Selfservice mOTP")

        motp_key = "1234123412341234"
        motp_pin = "1234"
        selfservice.open()
        selfservice.login("mozart", "Test123!", test1_realm)
        driver.find_element(By.ID, "motp_secret").clear()
        driver.find_element(By.ID, "motp_secret").send_keys(motp_key)
        driver.find_element(By.ID, "motp_s_pin1").clear()
        driver.find_element(By.ID, "motp_s_pin1").send_keys(motp_pin)
        driver.find_element(By.ID, "motp_s_pin2").clear()
        driver.find_element(By.ID, "motp_s_pin2").send_keys(motp_pin)
        driver.find_element(By.ID, "motp_self_desc").clear()
        driver.find_element(
            By.ID, "motp_self_desc").send_keys("Selenium self enrolled")
        driver.find_element(By.ID, "button_register_motp").click()
        alert_box_text = driver.find_element(By.ID, "alert_box_text").text
        m = re.match(
            r"""
                .*?
                Token\ enrolled\ successfully
                .*?
                [sS]erial(\ number)?:     # 'serial:' or 'Serial number:'
                \s*
                (?P<serial>\w+)           # For example: LSMO0001222C
                """,
            alert_box_text,
            re.DOTALL | re.VERBOSE,
        )
        assert m is not None, (
            "alert_box_text does not match regex. Possibly the token was not enrolled properly. %r"
            % alert_box_text)
        serial_token_mozart = m.group("serial")
        self.testcase.driver.find_element(
            By.XPATH,
            "//button[@type='button' and ancestor::div[@aria-describedby='alert_box']]",
        ).click()
        selfservice.logout()

        self._announce_test(
            "9. Alle 4 Benutzer melden sich im selfservice Portal an und setzen die PIN"
        )

        user_token_dict = {
            "bach": serial_token_bach,
            "debussy": serial_token_debussy,
            "mozart": serial_token_mozart,
            "beethoven": serial_token_beethoven,
        }

        for user, token in user_token_dict.items():
            selfservice.login(user, "Test123!", test1_realm)
            selfservice.set_pin(token, user + "newpin")
            selfservice.logout()

        self._announce_test("10. Authentisierung der 4 Benutzer ###")
        validate = Validate(
            self.testcase.http_protocol,
            self.testcase.http_host,
            self.testcase.http_port,
            self.testcase.http_username,
            self.testcase.http_password,
        )

        # seed is also set in testdata/aladdin.xml
        seed_oath137332 = "ff06df50017d3b981cfbc4ec4d374040164d8d19"
        seed_oath137332_bin = binascii.unhexlify(seed_oath137332)

        # Validate HOTP Token - bach
        hotp = HmacOtp()
        for counter in range(0, 4):
            otp = "bachnewpin" + hotp.generate(counter=counter,
                                               key=seed_oath137332_bin)
            access_granted, _ = validate.validate(user="******" + test1_realm,
                                                  password=otp)
            assert access_granted, ("OTP: " + otp + " for user " + "bach@" +
                                    test1_realm + " returned False")
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******")
        assert (not access_granted
                ), "OTP: 1234111111 should be False for user bach"

        # Validate Remote token - debussy

        # deactivated remote token test while no remote linotp integration
        # server is available
        '''
        remote_token_otp = "666666"
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******" + remote_token_otp)
        assert access_granted is True, "OTP: " + remote_token_otp + " for user " +
                        "debussy@" + test1_realm + " returned False"
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******")
        assert access_granted is False, "OTP: 1234111111 should be False for user debussy"'''

        # Validate Spass token - beethoven

        # Correct PIN + password = success
        access_granted, _ = validate.validate(
            user="******" + test1_realm,
            password="******" + beethoven_token_password,
        )
        assert access_granted, ("OTP: " + "beethovennewpin" + " for user " +
                                "beethoven@" + test1_realm + " returned False")
        # wrong PIN + empty password = fail
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******")
        assert (not access_granted
                ), "OTP: randominvalidpin should be False for user beethoven"
        # correct PIN + wrong password = fail
        access_granted, _ = validate.validate(
            user="******" + test1_realm,
            password="******" + "wrongpassword",
        )
        assert (not access_granted
                ), "beethoven should not auth with wrong token password"
        # Password without pin = fail
        access_granted, _ = validate.validate(
            user="******" + test1_realm, password=beethoven_token_password)
        assert (not access_granted
                ), "beethoven should not auth with password and old pin"
        # Correct PIN + password = success (again)
        access_granted, _ = validate.validate(
            user="******" + test1_realm,
            password="******" + beethoven_token_password,
        )
        assert access_granted, ("OTP: " + "beethovennewpin" + " for user " +
                                "beethoven@" + test1_realm + " returned False")

        time.sleep(2)

        # Validate mOTP token - mozart
        current_epoch = time.time()
        motp_otp = calculate_motp(epoch=current_epoch,
                                  key=motp_key,
                                  pin=motp_pin)

        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******" +
                                              motp_otp)
        time.sleep(1)
        assert access_granted, ("OTP: " + motp_otp + " for user " + "mozart@" +
                                test1_realm + " returned False")
        motp_otp = calculate_motp(epoch=current_epoch - 4000,
                                  key=motp_key,
                                  pin=motp_pin)
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******" +
                                              motp_otp)
        assert not access_granted, (
            "OTP: mozartnewpin%s should be False for user mozart" % motp_otp)

        self._announce_test("11. mOTP Pin im selfservice ändern")

        new_motp_pin = "5588"

        selfservice.open()
        selfservice.login("mozart", "Test123!", test1_realm)
        selfservice.set_motp_pin(serial_token_mozart, new_motp_pin)
        selfservice.logout()

        time.sleep(10)  # otherwise next mOTP value might not be valid

        current_epoch = time.time()
        motp_otp = calculate_motp(epoch=current_epoch,
                                  key=motp_key,
                                  pin=new_motp_pin)
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******" +
                                              motp_otp)
        assert access_granted, ("OTP: mozartnewpin" + motp_otp + " for user " +
                                "mozart@" + test1_realm + " returned False")

        self._announce_test("12. Token Resynchronisierung")

        # Bach 'presses' his token more than 10 times and fails to authenticate
        counter = 50  # was 19
        hotp = HmacOtp()
        otp = "bachnewpin" + hotp.generate(counter=counter,
                                           key=seed_oath137332_bin)
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password=otp)
        assert not access_granted, ("OTP: %s should be False for user bach" %
                                    otp)

        selfservice.login("bach", "Test123!", test1_realm)

        otp1 = hotp.generate(counter=counter + 1, key=seed_oath137332_bin)
        otp2 = hotp.generate(counter=counter + 2, key=seed_oath137332_bin)

        selfservice.resync_token(serial_token_bach, otp1, otp2)
        selfservice.logout()

        # Should be able to authenticate again
        otp = "bachnewpin" + hotp.generate(counter=counter + 3,
                                           key=seed_oath137332_bin)
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password=otp)
        assert access_granted, "OTP: %s should be True for user bach" % otp

        self._announce_test(
            "13. Benutzer beethoven deaktiviert seinen Token im Selfservice portal und versucht sich anzumelden."
        )

        selfservice.login("beethoven", "Test123!", test1_realm)
        selfservice.disable_token(serial_token_beethoven)
        selfservice.logout()

        # beethoven should be unable to authenticate
        access_granted, _ = validate.validate(
            user="******" + test1_realm,
            password="******" + beethoven_token_password,
        )
        assert (not access_granted
                ), "OTP: beethovennewpin should be False for user beethoven"

        self._announce_test(
            "14. Der Admin entsperrt diesen Token, der Benutzer beethoven kann sich wieder anmelden."
        )

        token_view.open()
        token_view.enable_token(serial_token_beethoven)

        # beethoven should be able to authenticate
        access_granted, _ = validate.validate(
            user="******" + test1_realm,
            password="******" + beethoven_token_password,
        )
        assert (
            access_granted
        ), "OTP: beethovennewpin should be able to authenticate after re-enabled token."
Exemple #10
0
    def test_scenario01(self):
        """
        Scenario01 (https://wally/projects/linotp/wiki/TestingTest_Szenario_01)
        """

        driver = self.driver

        token_view = self.manage_ui.token_view
        user_view = self.manage_ui.user_view

        selfservice = SelfService(self.driver, self.base_url)

        # reset all views
        self.reset_resolvers_and_realms()
        self.manage_ui.policy_view.clear_policies()
        token_view.delete_all_tokens()

        self._announce_test("1. UserIdResolver anlegen")
        # Create LDAP UserIdResolver
        ldap_data = data.musicians_ldap_resolver
        ldap_resolver = self.useridresolver_manager.create_resolver(ldap_data)

        # Create SQL UserIdResolver
        sql_data = data.sql_resolver

        sql_resolver = self.useridresolver_manager.create_resolver(sql_data)
        self.useridresolver_manager.close()

        # Create realm for all resolvers
        realm_name1 = "SE_scenario01_realm1"
        realm_name2 = "SE_scenario01_realm2"

        self.realm_manager.create(realm_name1, [ldap_resolver])
        self.realm_manager.create(realm_name2, [sql_resolver])
        self.realm_manager.close()

        self._announce_test(
            "2. In Management Webinterface, check that all users are visible")

        self.check_users(realm_name1, ldap_data)
        self.check_users(realm_name2, sql_data)

        self._announce_test("3. eToken.xml ueber das Webinterface importieren")

        token_import_aladdin = TokenImportAladdin(self.manage_ui)

        aladdin_xml_path = os.path.join(self.manage_ui.test_data_dir,
                                        'aladdin.xml')
        err_import = token_import_aladdin.do_import(file_content=None,
                                                    file_path=aladdin_xml_path)
        # There shouldn't raise an error
        self.assertFalse(err_import,
                         "Error during Aladdin token import!")

        token_import_aladdin = TokenImportAladdin(self.manage_ui)
        err_import = token_import_aladdin.do_import(
            file_path=os.path.join(self.manage_ui.test_data_dir,
                                   'wrong_token.xml'))
        # There shouldn't raise an error
        self.assertTrue(err_import,
                        "Successful import of wrong Aladdin token file!")

        serial_token_bach = "oath137332"
        test1_realm = realm_name1.lower()

        self._announce_test(
            "4. Im Management Webinterface nun eine Policy anlegen")

        Policy(self.manage_ui, "SE_scenario01", "selfservice",
               "enrollMOTP, setOTPPIN, setMOTPPIN, resync, disable ",
               test1_realm)

        self._announce_test("5. eToken zuweisen")

        user_view.select_realm(test1_realm)
        user_view.select_user("bach")

        token_view.assign_token(serial_token_bach, "1234")

        self._announce_test("6. Remote Token zuweisen")

        user_view.select_user("debussy")
        remote_token = RemoteToken(driver=self.driver,
                                   base_url=self.base_url,
                                   url="https://billybones",
                                   remote_serial="LSSP0002F653",
                                   pin="1234",
                                   remote_otp_length=6,
                                   )
        serial_token_debussy = remote_token.serial

        self._announce_test("7. Spass-Token zuweisen")

        user_view.select_user("beethoven")
        spass_token = SpassToken(
            driver=self.driver,
            base_url=self.base_url,
            pin=u"beethovenspass#ñô",
            description="SPass Token enrolled with Selenium"
        )
        serial_token_beethoven = spass_token.serial

        self._announce_test("8. Selfservice mOTP")

        motp_key = "1234123412341234"
        motp_pin = "1234"
        selfservice.login("mozart", "Test123!", test1_realm)
        driver.find_element_by_id("motp_secret").clear()
        driver.find_element_by_id("motp_secret").send_keys(motp_key)
        driver.find_element_by_id("motp_s_pin1").clear()
        driver.find_element_by_id("motp_s_pin1").send_keys(motp_pin)
        driver.find_element_by_id("motp_s_pin2").clear()
        driver.find_element_by_id("motp_s_pin2").send_keys(motp_pin)
        driver.find_element_by_id("motp_self_desc").clear()
        driver.find_element_by_id("motp_self_desc").send_keys(
            "Selenium self enrolled")
        driver.find_element_by_id("button_register_motp").click()
        alert_box_text = driver.find_element_by_id("alert_box_text").text
        m = re.match(
            r"""
                .*?
                Token\ enrolled\ successfully
                .*?
                [sS]erial(\ number)?:     # 'serial:' or 'Serial number:'
                \s*
                (?P<serial>\w+)           # For example: LSMO0001222C
                """,
            alert_box_text,
            re.DOTALL | re.VERBOSE
        )
        self.assertTrue(
            m is not None,
            "alert_box_text does not match regex. Possibly the token was not enrolled properly. %r" % alert_box_text
        )
        serial_token_mozart = m.group('serial')
        self.driver.find_element_by_xpath(
            "//button[@type='button' and ancestor::div[@aria-describedby='alert_box']]").click()
        driver.find_element_by_link_text("Logout").click()

        self._announce_test(
            "9. Alle 4 Benutzer melden sich im selfservice Portal an und setzen die PIN")

        user_token_dict = {
            "bach": serial_token_bach,
            "debussy": serial_token_debussy,
            "mozart": serial_token_mozart,
            "beethoven": serial_token_beethoven
        }

        for user, token in user_token_dict.iteritems():
            selfservice.login(user, "Test123!", test1_realm)
            selfservice.set_pin(token, user + "newpin")
            selfservice.logout()

        self._announce_test("10. Authentisierung der 4 Benutzer ###")
        validate = Validate(self.http_protocol,
                            self.http_host,
                            self.http_port,
                            self.http_username,
                            self.http_password)

        # seed is also set in testdata/aladdin.xml
        seed_oath137332 = "ff06df50017d3b981cfbc4ec4d374040164d8d19"
        seed_oath137332_bin = binascii.unhexlify(seed_oath137332)

        # Validate HOTP Token - bach
        hotp = HmacOtp()
        for counter in range(0, 20):
            otp = "bachnewpin" + \
                hotp.generate(counter=counter, key=seed_oath137332_bin)
            access_granted, _ = validate.validate(user="******" +
                                                  test1_realm, password=otp)
            self.assertTrue(access_granted, "OTP: " + otp + " for user " +
                            "bach@" + test1_realm + " returned False")
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******")
        self.assertFalse(
            access_granted, "OTP: 1234111111 should be False for user bach")

        # Validate Remote token - debussy

        # deactivated remote token test while no remote linotp integration
        # server is available
        '''
        remote_token_otp = "666666"
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******" + remote_token_otp)
        self.assertTrue(access_granted, "OTP: " + remote_token_otp + " for user " +
                        "debussy@" + test1_realm + " returned False")
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******")
        self.assertFalse(access_granted, "OTP: 1234111111 should be False for user debussy")'''

        # Validate Spass token - beethoven
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******")
        self.assertTrue(access_granted, "OTP: " + "beethovennewpin" + " for user " +
                        "beethoven@" + test1_realm + " returned False")
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******")
        self.assertFalse(
            access_granted, "OTP: randominvalidpin should be False for user beethoven")

        # Validate mOTP token - mozart
        current_epoch = time.time()
        motp_otp = calculate_motp(
            epoch=current_epoch,
            key=motp_key,
            pin=motp_pin
        )

        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******" + motp_otp)
        time.sleep(1)
        self.assertTrue(access_granted, "OTP: " + motp_otp + " for user " +
                        "mozart@" + test1_realm + " returned False")
        motp_otp = calculate_motp(
            epoch=current_epoch - 4000,
            key=motp_key,
            pin=motp_pin
        )
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******" + motp_otp)
        self.assertFalse(
            access_granted, "OTP: mozartnewpin%s should be False for user mozart" % motp_otp)

        self._announce_test("11. mOTP Pin im selfservice ändern")

        new_motp_pin = "5588"

        selfservice.login("mozart", "Test123!", test1_realm)
        selfservice.set_motp_pin(token, new_motp_pin)
        selfservice.logout()

        time.sleep(10)  # otherwise next mOTP value might not be valid

        current_epoch = time.time()
        motp_otp = calculate_motp(
            epoch=current_epoch,
            key=motp_key,
            pin=new_motp_pin
        )
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******" + motp_otp)
        self.assertTrue(access_granted, "OTP: mozartnewpin" + motp_otp + " for user " +
                        "mozart@" + test1_realm + " returned False")

        self._announce_test("12. Token Resynchronisierung")

        # Bach 'presses' his token more than 10 times and fails to authenticate
        counter = 50  # was 19
        hotp = HmacOtp()
        otp = "bachnewpin" + \
            hotp.generate(counter=counter, key=seed_oath137332_bin)
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password=otp)
        self.assertFalse(
            access_granted, "OTP: %s should be False for user bach" % otp)

        selfservice.login("bach", "Test123!", test1_realm)

        otp1 = hotp.generate(counter=counter + 1, key=seed_oath137332_bin)
        otp2 = hotp.generate(counter=counter + 2, key=seed_oath137332_bin)

        selfservice.resync_token(serial_token_bach, otp1, otp2)
        selfservice.logout()

        # Should be able to authenticate again
        otp = "bachnewpin" + \
            hotp.generate(counter=counter + 3, key=seed_oath137332_bin)
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password=otp)
        self.assertTrue(
            access_granted, "OTP: %s should be True for user bach" % otp)

        self._announce_test(
            "13. Benutzer beethoven deaktiviert seinen Token im Selfservice portal und versucht sich anzumelden.")

        selfservice.login("beethoven", "Test123!", test1_realm)
        selfservice.disable_token(serial_token_beethoven)
        selfservice.logout()

        # beethoven should be unable to authenticate
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******")
        self.assertFalse(
            access_granted, "OTP: beethovennewpin should be False for user beethoven")

        self._announce_test(
            "14. Der Admin entsperrt diesen Token, der Benutzer beethoven kann sich wieder anmelden.")

        token_view.open()
        token_view.select_token(serial_token_beethoven)
        driver.find_element_by_id("button_enable").click()

        time.sleep(1)
        # beethoven should be able to authenticate
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******")
        self.assertTrue(
            access_granted, "OTP: beethovennewpin should be able to authenticate after re-enabled token.")
Exemple #11
0
class TestPolicies(TestCase):
    """Test Policies"""

    # GUI attributes
    token_view = None
    user_view = None

    # Other testing data
    seed_oath137332 = None
    serial_oath137332 = None

    ldap_resolver = None
    sql_resolver = None

    two_resolvers_realm_name = None

    # validate/check instance
    validate = None

    def tearDown(self):
        """
        We clean up in front!
        see setUp()
        """

    def setUp(self):
        """ Some test set up steps """

        # Initialize GUI attributes
        self.token_view = self.manage_ui.token_view
        self.user_view = self.manage_ui.user_view

        # Delete from previous tests:
        # - resolvers
        # - realms
        # - policies
        # - tokens

        self.reset_resolvers_and_realms()
        self.manage_ui.policy_view.clear_policies_via_api()
        self.token_view.clear_tokens_via_api()

        # Create LDAP UserIdResolver
        ldap_data = data.musicians_ldap_resolver
        self.ldap_resolver = self.useridresolver_manager.create_resolver(
            ldap_data)

        # Create SQL UserIdResolver
        sql_data = data.sql_resolver

        self.sql_resolver = self.useridresolver_manager.create_resolver(
            sql_data)
        self.useridresolver_manager.close()

        # Create realms
        self.two_resolvers_realm_name = "two_resolvers_realm"
        self.realm_manager.create(self.two_resolvers_realm_name, [self.ldap_resolver,
                                                                  self.sql_resolver])
        self.realm_manager.close()

        # Set seed of HMAC token
        self.seed_oath137332 = "ff06df50017d3b981cfbc4ec4d374040164d8d19"
        self.serial_oath137332 = "oath137332"

        # Import some test tokens
        self.import_tokens()

        # Create validate/check instance
        self.validate = Validate(self.http_protocol,
                                 self.http_host,
                                 self.http_port,
                                 self.http_username,
                                 self.http_password)

    def test_otppin_3(self):
        """
        Test policy otppin=3 (ignore_pin) : TestRail C1910

        First we do some authentications with user a with
        otppin=3.

        Then we change the policy, that only users from
        a specific resolver (user B) get through with otppin=3.
        """

        # Define user A
        user_a = "bach"
        user_a_pw = "Test123!"
        user_a_realm = self.two_resolvers_realm_name
        user_a_token_pin = "1234"

        # Define user B
        user_b = "kay"
        user_b_pw = "test123!"
        user_b_realm = self.two_resolvers_realm_name
        user_b_token_pin = ""
        user_b_token_key = "3132333435363738393031323334353637383930"

        # Unhexlify for hotp.generate method
        user_b_token_seed_bin = binascii.unhexlify(user_b_token_key)

        # Create Token
        self.user_view.select_user(user_b)
        HotpToken(self.driver,
                  self.base_url,
                  pin=user_b_token_pin,
                  hmac_key=user_b_token_key)

        ###############################
        ##
        # First some tests with user A
        ##
        ###############################

        # Create policy
        Policy(self.manage_ui, "otppin3", "authentication",
               "otppin=3",
               "*",
               "*")  # user = "******"

        # Create event based HMAC token
        # Tokens were imported by self.import_tokens()
        self.user_view.select_realm(user_a_realm)
        self.user_view.select_user(user_a)

        # Unhexlify for hotp.generate method
        seed_oath137332_bin = binascii.unhexlify(self.seed_oath137332)

        # Assign token to user
        # Set a pin
        self.token_view.assign_token(self.serial_oath137332,
                                     user_a_token_pin)

        # authentication tests
        # - PIN+OTP -> successfully
        # - PW+OTP -> successfully
        # - nonsense+OTP -> successfully
        # - OTP -> successfully
        # - wront OTP -> fails

        hotp_a = HmacOtp()

        # PIN+OTP -> success
        otp = user_a_token_pin + \
            hotp_a.generate(counter=0,
                            key=seed_oath137332_bin)

        access_granted, _ = self.validate.validate(user=user_a + "@" +
                                                   user_a_realm, password=otp)
        self.assertTrue(access_granted, "OTPPIN=3, PIN+OTP: " + otp + " for user " +
                        user_a + "@" + user_a_realm + " returned False")

        # PW+OTP -> success
        otp = user_a_pw + \
            hotp_a.generate(counter=1,
                            key=seed_oath137332_bin)

        access_granted, _ = self.validate.validate(user=user_a + "@" +
                                                   user_a_realm, password=otp)
        self.assertTrue(access_granted, "OTPPIN=3, PW+OTP: " + otp + " for user " +
                        user_a + "@" + user_a_realm + " returned False")

        # nonsense+OTP -> success
        otp = "nonsense" + \
            hotp_a.generate(counter=2,
                            key=seed_oath137332_bin)

        access_granted, _ = self.validate.validate(user=user_a + "@" +
                                                   user_a_realm, password=otp)
        self.assertTrue(access_granted, "OTPPIN=3, nonsense+OTP: " + otp + " for user " +
                        user_a + "@" + user_a_realm + " returned False")

        # OTP -> success
        otp = hotp_a.generate(counter=3,
                              key=seed_oath137332_bin)

        access_granted, _ = self.validate.validate(user=user_a + "@" +
                                                   user_a_realm, password=otp)
        self.assertTrue(access_granted, "OTPPIN=3, OTP: " + otp + " for user " +
                        user_a + "@" + user_a_realm + " returned False")

        # wrong OTP -> fails
        otp = "111111"

        access_denied, _ = self.validate.validate(user=user_a + "@" +
                                                  user_a_realm, password=otp)
        self.assertFalse(access_denied, "OTPPIN=3, wrong OTP: " + otp + " for user " +
                         user_a + "@" + user_a_realm + " returned True")

        ###########################
        #
        # Bring user B into game
        #
        # change policy
        #    user = resolverB:
        #
        # So the ignore_pin should
        # should only affect users
        # in resolverB
        #
        ###########################

        # Change policy
        Policy(self.manage_ui, "otppin3", "authentication",
               "otppin=3",
               "*",  # realm
               data.sql_resolver["name"] + ":")  # pick specific resolver

        hotp_b = HmacOtp()

        # PIN+OTP -> success
        otp = user_b_token_pin + \
            hotp_b.generate(counter=0,
                            key=user_b_token_seed_bin)

        access_granted, _ = self.validate.validate(user=user_b + "@" +
                                                   user_b_realm, password=otp)
        self.assertTrue(access_granted, "OTPPIN=3, PIN+OTP: " + otp + " for user " +
                        user_b + "@" + user_b_realm + " returned False")

        # PW+OTP -> success
        otp = user_b_pw + \
            hotp_b.generate(counter=1,
                            key=user_b_token_seed_bin)

        access_granted, _ = self.validate.validate(user=user_b + "@" +
                                                   user_b_realm, password=otp)
        self.assertTrue(access_granted, "OTPPIN=3, PW+OTP: " + otp + " for user " +
                        user_b + "@" + user_b_realm + " returned False")

        # OTP -> success
        otp = hotp_b.generate(counter=2,
                              key=user_b_token_seed_bin)

        access_granted, _ = self.validate.validate(user=user_b + "@" +
                                                   user_b_realm, password=otp)
        self.assertTrue(access_granted, "OTPPIN=3, OTP: " + otp + " for user " +
                        user_b + "@" + user_b_realm + " returned False")

        # wrong OTP -> fails
        otp = "111111"

        access_denied, _ = self.validate.validate(user=user_b + "@" +
                                                  user_b_realm, password=otp)
        self.assertFalse(access_denied, "OTPPIN=3, wrong OTP: " + otp + " for user " +
                         user_b + "@" + user_b_realm + " returned False")

        # Back to user A and try to authenticate
        # with changed policy!

        # OTP -> fails
        otp = hotp_a.generate(counter=4,
                              inc_counter=False,
                              key=seed_oath137332_bin)

        access_denied, _ = self.validate.validate(user=user_a + "@" +
                                                  user_a_realm, password=otp)
        self.assertFalse(access_denied, "OTPPIN=3, OTP: " + otp + " for user " +
                         user_a + "@" + user_a_realm + " returned True")

        # PIN+OTP -> success
        otp = user_a_token_pin + \
            hotp_a.generate(counter=4,
                            key=seed_oath137332_bin)

        access_granted, _ = self.validate.validate(user=user_a + "@" +
                                                   user_a_realm, password=otp)
        self.assertTrue(access_granted, "OTPPIN=3, PIN+OTP: " + otp + " for user " +
                        user_a + "@" + user_a_realm + " returned False")

    def import_tokens(self):
        """ Import some tokens """

        file_content = """<Tokens>
    <Token serial="00040008CFA5">
    <CaseModel>5</CaseModel>
    <Model>101</Model>
    <ProductionDate>02/19/2009</ProductionDate>
    <ProductName>Safeword Alpine</ProductName>
    <Applications>
    <Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb9}">
    <Seed>123412354</Seed>
    <MovingFactor>1</MovingFactor>
    </Application>
    </Applications>
    </Token>
    <Token serial="00040008CFA52">
    <CaseModel>5</CaseModel>
    <Model>101</Model>
    <ProductionDate>02/19/2009</ProductionDate>
    <ProductName>Safeword Alpine</ProductName>
    <Applications>
    <Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb9}">
    <Seed>123456</Seed>
    <MovingFactor>1</MovingFactor>
    </Application>
    </Applications>
    </Token>
    <Token serial="oath137332">
    <CaseModel>5</CaseModel>
    <Model>101</Model>
    <ProductionDate>02/19/2009</ProductionDate>
    <ProductName>Safeword Alpine</ProductName>
    <Applications>
    <Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb1}">
    <Seed>""" + self.seed_oath137332 + """</Seed>
    <MovingFactor>1</MovingFactor>
    </Application>
    </Applications>
    </Token>
    <Token serial="oath12482B">
    <CaseModel>5</CaseModel>
    <Model>101</Model>
    <ProductionDate>02/19/2009</ProductionDate>
    <ProductName>Safeword Alpine</ProductName>
    <Applications>
    <Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb2}">
    <Seed>6ec1d0e9915a2bebf84745b318e39e481249c1eb</Seed>
    <MovingFactor>1</MovingFactor>
    </Application>
    </Applications>
    </Token>
    </Tokens>"""

        token_import_aladdin = TokenImportAladdin(self.manage_ui)
        error_raised = token_import_aladdin.do_import(file_content)
        # There shouldn't raise an error
        self.assertFalse(error_raised,
                         "Error during Aladdin token import!")
Exemple #12
0
    def test_yubico_mode(self):
        """
        Enrolls a Yubikey in YUBICO mode and verifies OTPs against it
        """
        # Enroll Yubikey
        lotpc = linotpclient(self.http_protocol,
                             self.http_host,
                             admin=self.http_username,
                             adminpw=self.http_password)
        serialnum = "01382015"
        yubi_slot = 1
        serial = "UBAM%s_%s" % (serialnum, yubi_slot)
        otpkey = "9163508031b20d2fbb1868954e041729"
        yubi_otplen = 48
        description = "Enrolled by TestYubikey"
        public_uid = "ecebeeejedecebeg"
        r1 = lotpc.inittoken({'type': 'yubikey',
                              'serial': serial,
                              'otpkey': otpkey,
                              'otplen': yubi_otplen,
                              'description': description})
        self.assertTrue(r1['result']['status'], "Error enrolling Yubikey")
        self.assertTrue(r1['result']['value'], "Error enrolling Yubikey")

        driver = self.driver
        driver.get(self.base_url + "/manage")

        user_view = UserView(driver, self.base_url, self.realm_name)
        user_view.select_user(self.user_name)
        token_view = TokenView(driver, self.base_url)
        token_view.select_token(serial)
        driver.find_element_by_id("button_assign").click()
        time.sleep(2)
        pin = "asdf1234"
        driver.find_element_by_id("pin1").clear()
        driver.find_element_by_id("pin1").send_keys(pin)
        driver.find_element_by_id("pin2").clear()
        driver.find_element_by_id("pin2").send_keys(pin)
        driver.find_element_by_id("button_setpin_setpin").click()
        time.sleep(1)

        validate = Validate(self.http_protocol, self.http_host, self.http_username,
                            self.http_password)

        valid_otps = [
            public_uid + "fcniufvgvjturjgvinhebbbertjnihit",
            public_uid + "tbkfkdhnfjbjnkcbtbcckklhvgkljifu",
            public_uid + "ktvkekfgufndgbfvctgfrrkinergbtdj",
            public_uid + "jbefledlhkvjjcibvrdfcfetnjdjitrn",
            public_uid + "druecevifbfufgdegglttghghhvhjcbh",
            public_uid + "nvfnejvhkcililuvhntcrrulrfcrukll",
            public_uid + "kttkktdergcenthdredlvbkiulrkftuk",
            public_uid + "hutbgchjucnjnhlcnfijckbniegbglrt",
            public_uid + "vneienejjnedbfnjnnrfhhjudjgghckl",
            public_uid + "krgevltjnujcnuhtngjndbhbiiufbnki",
            public_uid + "kehbefcrnlfejedfdulubuldfbhdlicc",
            public_uid + "ljlhjbkejkctubnejrhuvljkvglvvlbk",
        ]

        for otp in valid_otps:
            access_granted, _ = validate.validate(user=self.user_name + "@" +
                                                self.realm_name, password=pin + otp)
            self.assertTrue(access_granted, "OTP: " + pin + otp + " for user " +
                                         self.user_name + "@" + self.realm_name + " returned False")

        # validate/check_yubikey
        password = pin + public_uid + "eihtnehtetluntirtirrvblfkttbjuih"
        cy_auth = HTTPDigestAuth(self.http_username, self.http_password)
        cy_validate_url = self.http_protocol + "://" + self.http_host + "/validate/check_yubikey?"
        response = requests.get(cy_validate_url,
                                params={'pass': password},
                                auth=cy_auth,
                                verify=False)
        self.assertEqual(response.status_code, 200, "Invalid response %r" % response)
        return_json = response.json()
        self.assertTrue(return_json['result']['status'],
                        "Invalid return value: %r" % return_json)
        self.assertTrue(return_json['result']['value'],
                        "Invalid return value: %r" % return_json)
        self.assertEqual(return_json['detail']['user'],
                         self.user_name,
                         "Invalid return value: %r" % return_json)
        self.assertEqual(return_json['detail']['realm'],
                         self.realm_name,
                         "Invalid return value: %r" % return_json)

        # Repeat an old (therefore invalid) OTP value
        invalid_otp = public_uid + "fcniufvgvjturjgvinhebbbertjnihit"
        access_granted, _ = validate.validate(user=self.user_name + "@" +
                                            self.realm_name, password=pin + invalid_otp)
        self.assertFalse(access_granted,
                         "OTP: " + pin + invalid_otp + " for user " + self.user_name + "@" +
                             self.realm_name + " should be rejected.")

        # Repeat an old (therefore invalid) OTP value with validate/check_yubikey
        invalid_otp = pin + public_uid + "fcniufvgvjturjgvinhebbbertjnihit"
        response = requests.get(cy_validate_url,
                                params={'pass': password},
                                auth=cy_auth,
                                verify=False)
        self.assertEqual(response.status_code, 200, "Invalid response %r" % response)
        return_json = response.json()
        self.assertTrue(return_json['result']['status'],
                        "Invalid return value: %r" % return_json)
        self.assertFalse(return_json['result']['value'],
                         "Invalid return value: %r" % return_json)
        try:
            return_json['detail']['user']
            self.fail("Response should not contain detail.user %r" % return_json)
        except KeyError:
            pass
        try:
            return_json['detail']['realm']
            self.fail("Response should not contain detail.realm %r" % return_json)
        except KeyError:
            pass
Exemple #13
0
    def test_scenario01(self):
        """Tests Scenario 01 (https://wally/projects/linotp/wiki/TestingTest_Szenario_01)"""

        driver = self.driver

        ### 1. UserIdResolver anlegen ###
        CA001_cert = \
"""-----BEGIN CERTIFICATE-----
MIIDcjCCAtugAwIBAgIQVSU6NwMTmKNI6t3WcjY6uTANBgkqhkiG9w0BAQUFADBC
MRUwEwYKCZImiZPyLGQBGRYFbG9jYWwxGTAXBgoJkiaJk/IsZAEZFglsc2V4cGVy
dHMxDjAMBgNVBAMTBUNBMDAxMB4XDTA1MDQxMTE2NDgzOVoXDTQwMDQxMTE2NTY1
MFowQjEVMBMGCgmSJomT8ixkARkWBWxvY2FsMRkwFwYKCZImiZPyLGQBGRYJbHNl
eHBlcnRzMQ4wDAYDVQQDEwVDQTAwMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC
gYEAqlWLfYK+dExjG+Qa/jpYjSo3EQnweQ7azacosa+xsrTMfDV5wLgMBSclCTX2
i/35VRg282Bh7hKCZifOBnAxjCBIHMpHQmW9c0T/GpeWSOQ1x0KeKrZ4PRj5oHEv
/uDJ7q2HlWXgRQo6NR75yDGLpsAWk64TyQ/I4f2vlC+AtjMCAyPS46OCAWcwggFj
MBMGCSsGAQQBgjcUAgQGHgQAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTAD
AQH/MB0GA1UdDgQWBBTCY8rVNcU/NGvgZxaPmO+Kz8bG4TCB/AYDVR0fBIH0MIHx
MIHuoIHroIHohoGwbGRhcDovLy9DTj1DQTAwMSxDTj1sc2V4czAxLENOPUNEUCxD
Tj1QdWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxDTj1Db25maWd1
cmF0aW9uLERDPWxzZXhwZXJ0cyxEQz1sb2NhbD9jZXJ0aWZpY2F0ZVJldm9jYXRp
b25MaXN0P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnSGM2h0
dHA6Ly9sc2V4czAxLmxzZXhwZXJ0cy5sb2NhbC9DZXJ0RW5yb2xsL0NBMDAxLmNy
bDAQBgkrBgEEAYI3FQEEAwIBADANBgkqhkiG9w0BAQUFAAOBgQBa+RGoezCgJS5W
PFCPy9BWqZr7iRimfRGBDqHpYDCPDtgec2fKCZ+u4jfwuTisZ7UOoiM1iEvkw0hH
Z7R1pz4Yd6E074kS/fe6u7U+9L3dmSUjFvO3gkLKtHKbhQi0NA+EHMRrPsQQemLm
gYzNiYwtvAu74Q+eTC6R5Uf0hOlFig==
-----END CERTIFICATE-----"""

        # Create LDAP UserIdResolver
        ldap_name = "SE_scenario01_ldap"
        ldap_expected_users = ['bach', 'beethoven', 'berlioz', 'brahms', 'debussy', u'dvořák',
                               'haydn', 'mozart', u'حافظ', u'郎']
        ldap_num_expected_users = len(ldap_expected_users)
        ldap_id_resolver = LdapUserIdResolver(
            ldap_name,
            driver,
            self.base_url,
            uri="ldaps://blackdog",
            certificate=CA001_cert,
            basedn="ou=people,dc=blackdog,dc=office,dc=lsexperts,dc=de",
            # You may also use cn="Wolfgang Amadeus Mozart"
            binddn=u'cn="عبد الحليم حافظ",ou=people,dc=blackdog,dc=office,dc=lsexperts,dc=de',
            password="******",
            preset_ldap=True
        )
        time.sleep(1)

        # Create SQL UserIdResolver
        sql_name = "SE_scenario01_sql"
        sql_server = "blackdog"
        sql_database = "userdb"
        sql_user = "******"
        sql_password = "******"
        sql_table = "user"
        sql_limit = "500"
        sql_encoding = "latin1"
        sql_expected_users = ["corny", "kay", "eric", u"knöt"]
        sql_num_expected_users = len(sql_expected_users)
        sql_id_resolver = SqlUserIdResolver(sql_name, driver, self.base_url,
                                            sql_server, sql_database,
                                            sql_user, sql_password, sql_table,
                                            sql_limit, sql_encoding)
        time.sleep(1)

        # Create realm for all resolvers
        resolvers_realm1 = [ldap_id_resolver]
        realm_name1 = "SE_scenario01_realm1"
        realm1 = Realm(realm_name1, resolvers_realm1)
        realm1.create(driver, self.base_url)
        time.sleep(1)

        resolvers_realm2 = [sql_id_resolver]
        realm_name2 = "SE_scenario01_realm2"
        realm2 = Realm(realm_name2, resolvers_realm2)
        realm2.create(driver, self.base_url)
        time.sleep(1)

        ### 2. Im Management Webinterface testen, dass alle Benutzer sichtbar sind ###

        user_view = UserView(driver, self.base_url, realm_name1)
        self.assertEqual(ldap_num_expected_users, user_view.get_num_users(),
                         "Not the expected number of users")
        for user in ldap_expected_users:
            self.assertTrue(user_view.user_exists(user), "User '" + user +
                            "' should exist.")
        time.sleep(1)

        user_view = UserView(driver, self.base_url, realm_name2)
        self.assertEqual(sql_num_expected_users, user_view.get_num_users(),
                         "Not the expected number of users")
        for user in sql_expected_users:
            self.assertTrue(user_view.user_exists(user), "User '" + user +
                            "' should exist.")

        ### 3. eToken.xml ueber das Webinterface importieren  ###

        seed_oath137332 = "ff06df50017d3b981cfbc4ec4d374040164d8d19"
        seed_oath137332_bin = binascii.unhexlify(seed_oath137332)
        file_content = """<Tokens>
<Token serial="00040008CFA5">
<CaseModel>5</CaseModel>
<Model>101</Model>
<ProductionDate>02/19/2009</ProductionDate>
<ProductName>Safeword Alpine</ProductName>
<Applications>
<Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb9}">
<Seed>123412354</Seed>
<MovingFactor>1</MovingFactor>
</Application>
</Applications>
</Token>
<Token serial="00040008CFA52">
<CaseModel>5</CaseModel>
<Model>101</Model>
<ProductionDate>02/19/2009</ProductionDate>
<ProductName>Safeword Alpine</ProductName>
<Applications>
<Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb9}">
<Seed>123456</Seed>
<MovingFactor>1</MovingFactor>
</Application>
</Applications>
</Token>
<Token serial="oath137332">
<CaseModel>5</CaseModel>
<Model>101</Model>
<ProductionDate>02/19/2009</ProductionDate>
<ProductName>Safeword Alpine</ProductName>
<Applications>
<Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb1}">
<Seed>""" + seed_oath137332 + """</Seed>
<MovingFactor>1</MovingFactor>
</Application>
</Applications>
</Token>
<Token serial="oath12482B">
<CaseModel>5</CaseModel>
<Model>101</Model>
<ProductionDate>02/19/2009</ProductionDate>
<ProductName>Safeword Alpine</ProductName>
<Applications>
<Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb2}">
<Seed>6ec1d0e9915a2bebf84745b318e39e481249c1eb</Seed>
<MovingFactor>1</MovingFactor>
</Application>
</Applications>
</Token>
</Tokens>"""

        TokenImport(driver, self.base_url, "safenet", file_content, None)

        serial_token_bach = "oath137332"
        test1_realm = realm_name1.lower()

        ### 4. Im Management Webinterface nun eine Policy anlegen ###

        Policy(driver, self.base_url, "SE_scenario01", "selfservice",
               "enrollMOTP, setOTPPIN, setMOTPPIN, resync, disable ",
               test1_realm)

        ### 5. eToken zuweisen ###

        user_view = UserView(driver, self.base_url, test1_realm)
        user_view.select_user("bach")
        token_view = TokenView(driver, self.base_url)
        token_view.select_token(serial_token_bach)
        driver.find_element_by_id("button_assign").click()
        time.sleep(2)
        driver.find_element_by_id("pin1").clear()
        driver.find_element_by_id("pin1").send_keys("1234")
        driver.find_element_by_id("pin2").clear()
        driver.find_element_by_id("pin2").send_keys("1234")
        driver.find_element_by_id("button_setpin_setpin").click()
        time.sleep(1)

        ### 6. Remote Token zuweisen ###

        user_view = UserView(driver, self.base_url, test1_realm)
        user_view.select_user("debussy")
        remote_token = RemoteToken(driver=self.driver,
                                   base_url=self.base_url,
                                   url="https://billybones",
                                   remote_serial="LSSP0002F653",
                                   pin="1234",
                                   remote_otp_length=6,
                                   )
        serial_token_debussy = remote_token.serial
        remote_token_otp = "666666"
        time.sleep(1)

        ### 7. Spass-Token zuweisen ###

        user_view = UserView(driver, self.base_url, test1_realm)
        user_view.select_user("beethoven")
        spass_token = SpassToken(
            driver=self.driver,
            base_url=self.base_url,
            pin=u"beethovenspass#ñô",
            description="SPass Token enrolled with Selenium"
            )
        serial_token_beethoven = spass_token.serial
        time.sleep(1)

        ### 8. Selfservice mOTP ###

        motp_key = "1234123412341234"
        motp_pin = "1234"
        driver.get(self.base_url + "/account/login")
        driver.find_element_by_id("login").clear()
        driver.find_element_by_id("login").send_keys("mozart@" + test1_realm)
        driver.find_element_by_id("password").clear()
        driver.find_element_by_id("password").send_keys("Test123!")
        driver.find_element_by_id("password").submit() # Submits the form
        time.sleep(1)
        driver.find_element_by_id("motp_secret").clear()
        driver.find_element_by_id("motp_secret").send_keys(motp_key)
        driver.find_element_by_id("motp_s_pin1").clear()
        driver.find_element_by_id("motp_s_pin1").send_keys(motp_pin)
        driver.find_element_by_id("motp_s_pin2").clear()
        driver.find_element_by_id("motp_s_pin2").send_keys(motp_pin)
        driver.find_element_by_id("motp_self_desc").clear()
        driver.find_element_by_id("motp_self_desc").send_keys("Selenium self enrolled")
        driver.find_element_by_id("button_register_motp").click()
        time.sleep(1)
        alert_box_text = driver.find_element_by_id("alert_box_text").text
        m = re.match(
            r"""
                .*?
                Token\ enrolled\ successfully
                .*?
                [sS]erial(\ number)?:     # 'serial:' or 'Serial number:'
                \s*
                (?P<serial>\w+)           # For example: LSMO0001222C
                """,
            alert_box_text,
            re.DOTALL | re.VERBOSE
            )
        self.assertTrue(
            m is not None,
            "alert_box_text does not match regex. Possibly the token was not enrolled properly. %r" % alert_box_text
            )
        serial_token_mozart = m.group('serial')
        self.driver.find_element_by_xpath("//button[@type='button' and ancestor::div[@aria-describedby='alert_box']]").click()
        driver.find_element_by_link_text("Logout").click()

        ### 9. Alle 4 Benutzer melden sich im selfservice Portal an und setzen die PIN

        user_token_dict = {
            "bach": serial_token_bach,
            "debussy": serial_token_debussy,
            "mozart": serial_token_mozart,
            "beethoven": serial_token_beethoven
            }
        for user in user_token_dict:
            driver.get(self.base_url + "/account/login")
            driver.find_element_by_id("login").clear()
            driver.find_element_by_id("login").send_keys("%s@%s" % (user, test1_realm))
            driver.find_element_by_id("password").clear()
            driver.find_element_by_id("password").send_keys("Test123!")
            driver.find_element_by_id("password").submit()
            driver.find_element_by_xpath("//div[@id='tabs']/ul/li/a/span[text()='set PIN']").click()
            time.sleep(1)
            # driver.find_element_by_css_selector('#tokenDiv > ul > li > a').click()
            driver.find_element_by_id('tokenDiv').find_element_by_partial_link_text(user_token_dict[user]).click()
            driver.find_element_by_id("pin1").clear()
            driver.find_element_by_id("pin1").send_keys(user + "newpin")
            driver.find_element_by_id("pin2").clear()
            driver.find_element_by_id("pin2").send_keys(user + "newpin")
            driver.find_element_by_id("button_setpin").click()
            time.sleep(1)
            self.assertEqual("PIN set successfully", self.close_alert_and_get_its_text())
            driver.find_element_by_link_text("Logout").click()

        ### 10. Authentisierung der 4 Benutzer ###
        validate = Validate(self.http_protocol,
                            self.http_host,
                            self.http_username,
                            self.http_password)

        # Validate HOTP Token - bach
        hotp = HmacOtp()
        for counter in range(0, 20):
            otp = "bachnewpin" + hotp.generate(counter=counter, key=seed_oath137332_bin)
            access_granted, _ = validate.validate(user="******" +
                                                test1_realm, password=otp)
            self.assertTrue(access_granted, "OTP: " + otp + " for user " +
                            "bach@" + test1_realm + " returned False")
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******")
        self.assertFalse(access_granted, "OTP: 1234111111 should be False for user bach")

        # Validate Remote token - debussy
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******" + remote_token_otp)
        self.assertTrue(access_granted, "OTP: " + remote_token_otp + " for user " +
                        "debussy@" + test1_realm + " returned False")
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******")
        self.assertFalse(access_granted, "OTP: 1234111111 should be False for user debussy")

        # Validate Spass token - beethoven
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******")
        self.assertTrue(access_granted, "OTP: " + "beethovennewpin" + " for user " +
                        "beethoven@" + test1_realm + " returned False")
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******")
        self.assertFalse(access_granted, "OTP: randominvalidpin should be False for user beethoven")

        # Validate mOTP token - mozart
        current_epoch = time.time()
        motp_otp = calculate_motp(
            epoch=current_epoch,
            key=motp_key,
            pin=motp_pin
            )
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******" + motp_otp)
        self.assertTrue(access_granted, "OTP: " + motp_otp + " for user " +
                        "mozart@" + test1_realm + " returned False")
        motp_otp = calculate_motp(
            epoch=current_epoch - 4000,
            key=motp_key,
            pin=motp_pin
            )
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******" + motp_otp)
        self.assertFalse(access_granted, "OTP: mozartnewpin%s should be False for user mozart" % motp_otp)

        ### 11. mOTP Pin im selfservice ändern ###

        driver.get(self.base_url + "/account/login")
        driver.find_element_by_id("login").clear()
        driver.find_element_by_id("login").send_keys("%s@%s" % ("mozart", test1_realm))
        driver.find_element_by_id("password").clear()
        driver.find_element_by_id("password").send_keys("Test123!")
        driver.find_element_by_id("password").submit()
        driver.find_element_by_xpath("//div[@id='tabs']/ul/li/a/span[text()='set mOTP PIN']").click()
        time.sleep(1)
        driver.find_element_by_id('tokenDiv').find_element_by_link_text(serial_token_mozart).click()
        driver.find_element_by_id("mpin1").clear()
        new_motp_pin = "5588"
        driver.find_element_by_id("mpin1").send_keys(new_motp_pin)
        driver.find_element_by_id("mpin2").clear()
        driver.find_element_by_id("mpin2").send_keys(new_motp_pin)
        driver.find_element_by_id("button_setmpin").click()
        time.sleep(1)
        self.assertEqual("mOTP PIN set successfully", self.close_alert_and_get_its_text())
        driver.find_element_by_link_text("Logout").click()

        time.sleep(10) # otherwise next mOTP value might not be valid

        current_epoch = time.time()
        motp_otp = calculate_motp(
            epoch=current_epoch,
            key=motp_key,
            pin=new_motp_pin
            )
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******" + motp_otp)
        self.assertTrue(access_granted, "OTP: mozartnewpin" + motp_otp + " for user " +
                        "mozart@" + test1_realm + " returned False")

        ### 12. Token Resynchronisierung ###

        # Bach 'presses' his token more than 10 times and fails to authenticate
        counter = 50 # was 19
        hotp = HmacOtp()
        otp = "bachnewpin" + hotp.generate(counter=counter, key=seed_oath137332_bin)
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password=otp)
        self.assertFalse(access_granted, "OTP: %s should be False for user bach" % otp)

        driver.get(self.base_url + "/account/login")
        driver.find_element_by_id("login").clear()
        driver.find_element_by_id("login").send_keys("%s@%s" % ("bach", test1_realm))
        driver.find_element_by_id("password").clear()
        driver.find_element_by_id("password").send_keys("Test123!")
        driver.find_element_by_id("password").submit()
        driver.find_element_by_xpath("//div[@id='tabs']/ul/li/a/span[text()='Resync Token']").click()
        time.sleep(1)
        driver.find_element_by_id('tokenDiv').find_element_by_link_text(serial_token_bach).click()
        otp1 = hotp.generate(counter=counter + 1, key=seed_oath137332_bin)
        otp2 = hotp.generate(counter=counter + 2, key=seed_oath137332_bin)
        driver.find_element_by_id("otp1").clear()
        driver.find_element_by_id("otp1").send_keys(otp1)
        driver.find_element_by_id("otp2").clear()
        driver.find_element_by_id("otp2").send_keys(otp2)
        driver.find_element_by_id("button_resync").click()
        time.sleep(1)
        self.assertEqual("Token resynced successfully", self.close_alert_and_get_its_text())
        driver.find_element_by_link_text("Logout").click()

        # Should be able to authenticate again
        otp = "bachnewpin" + hotp.generate(counter=counter + 3, key=seed_oath137332_bin)
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password=otp)
        self.assertTrue(access_granted, "OTP: %s should be True for user bach" % otp)

        ### 13. Ein Benutzer debussy deaktiviert seinen Token im Selfservice portal und versucht sich anzumelden. ###

        driver.get(self.base_url + "/account/login")
        driver.find_element_by_id("login").clear()
        driver.find_element_by_id("login").send_keys("%s@%s" % ("debussy", test1_realm))
        driver.find_element_by_id("password").clear()
        driver.find_element_by_id("password").send_keys("Test123!")
        driver.find_element_by_id("password").submit()
        driver.find_element_by_xpath("//div[@id='tabs']/ul/li/a/span[text()='Disable Token']").click()
        time.sleep(1)
        driver.find_element_by_id('tokenDiv').find_element_by_link_text(serial_token_debussy).click()
        driver.find_element_by_id("button_disable").click()
        time.sleep(1)
        self.assertEqual("Token disabled successfully", self.close_alert_and_get_its_text())
        driver.find_element_by_link_text("Logout").click()

        # debussy should be unable to authenticate
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******" + remote_token_otp)
        self.assertFalse(access_granted, "OTP: debussynewpin" + remote_token_otp + "should be False for user debussy")

        ### 14. Der Admin entsperrt diesen Token, der Benutzer debussy kann sich wieder anmelden. ###

        driver.get(self.base_url + "/manage")
        time.sleep(1)
        token_view = TokenView(driver, self.base_url)
        token_view.select_token(serial_token_debussy)
        driver.find_element_by_id("button_enable").click()
        time.sleep(1)

        # debussy should be able to authenticate
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******" + remote_token_otp)
        self.assertTrue(access_granted, "OTP: debussynewpin" + remote_token_otp + "should be True for user debussy")
Exemple #14
0
    def test_enroll(self):
        """
        Enroll sms token. After enrolling it verifies that the token info contains the
        correct sms. Then a user is authenticated using challenge response over RADIUS
        and Web API.
        """
        realm_name = self.realm_name

        radius_server = get_from_tconfig(
            ['radius', 'server'],
            default=self.http_host.split(':')[0],
        )
        radius_secret = get_from_tconfig(['radius', 'secret'], required=True)
        disable_radius = get_from_tconfig(
            ['radius', 'disable'], default='False')

        # Enroll sms token
        username = "******"
        sms_token_pin = "1234"
        phone_number = "+49(0)1234-24"
        description = "Rolled out by Selenium"

        user_view = self.manage_ui.user_view
        user_view.select_realm(realm_name)
        user_view.select_user(username)

        sms_token = SmsToken(driver=self.driver,
                             base_url=self.base_url,
                             pin=sms_token_pin,
                             phone=phone_number,
                             description=description)

        token_view = self.manage_ui.token_view
        token_info = token_view.get_token_info(sms_token.serial)
        self.assertEqual(phone_number, token_info['LinOtp.TokenInfo']['phone'],
                         "Wrong phone number was set for sms token.")

        # Authenticate with RADIUS
        if disable_radius.lower() == 'true':
            print "Testconfig option radius.disable is set to True. Skipping RADIUS test!"
        else:
            call_array = "linotp-auth-radius -f ../../../test.ini".split()
            call_array.extend(['-u', username + "@" + realm_name,
                               '-p', '1234',
                               '-s', radius_secret,
                               '-r', radius_server])
            with SMSProviderServer(self, 10) as smtpsvc:
                rad1 = check_output(call_array)
                m = re.search(r"State:\['(\d+)'\]", rad1)
                self.assertTrue(m is not None,
                                "'State' not found in linotp-auth-radius output. %r" % rad1)
                state = m.group(1)
                print "State: %s" % state
                otp = smtpsvc.get_otp()

            call_array = "linotp-auth-radius -f ../../../test.ini".split()
            call_array.extend(['-u', username + "@" + realm_name,
                               '-p', otp,
                               '-t', state,
                               '-s', radius_secret,
                               '-r', radius_server])
            rad2 = check_output(call_array)
            self.assertTrue("Access granted to user " + username in rad2,
                            "Access not granted to user. %r" % rad2)

        # Authenticate over Web API
        validate = Validate(self.http_protocol, self.http_host, self.http_port,
                            self.http_username, self.http_password)

        with SMSProviderServer(self, 10) as smtpsvc:
            access_granted, validate_resp = validate.validate(user=username + "@" + realm_name,
                                                              password=sms_token_pin)
            self.assertFalse(access_granted,
                             "Should return false because this request only triggers the challenge.")
            try:
                message = validate_resp['detail']['message']
            except KeyError:
                self.fail("detail.message should be present %r" %
                          validate_resp)
            self.assertEqual(message,
                             "sms submitted",
                             "Wrong validate response %r" % validate_resp)
            otp = smtpsvc.get_otp()

        access_granted, validate_resp = validate.validate(user=username + "@" + realm_name,
                                                          password=sms_token_pin + otp)
        self.assertTrue(access_granted,
                        "Could not authenticate user %s %r" % (username, validate_resp))
Exemple #15
0
    def test_yubico_mode(self):
        """
        Enrolls a Yubikey in YUBICO mode and verifies OTPs against it
        """
        # Enroll Yubikey
        lotpc = linotpclient(self.http_protocol,
                             self.http_host,
                             admin=self.http_username,
                             adminpw=self.http_password)
        serialnum = "01382015"
        yubi_slot = 1
        serial = "UBAM%s_%s" % (serialnum, yubi_slot)
        otpkey = "9163508031b20d2fbb1868954e041729"
        yubi_otplen = 48
        description = "Enrolled by TestYubikey"
        public_uid = "ecebeeejedecebeg"
        r1 = lotpc.inittoken({
            'type': 'yubikey',
            'serial': serial,
            'otpkey': otpkey,
            'otplen': yubi_otplen,
            'description': description
        })
        self.assertTrue(r1['result']['status'], "Error enrolling Yubikey")
        self.assertTrue(r1['result']['value'], "Error enrolling Yubikey")

        driver = self.driver
        driver.get(self.base_url + "/manage")

        user_view = UserView(driver, self.base_url, self.realm_name)
        user_view.select_user(self.user_name)
        token_view = TokenView(driver, self.base_url)
        token_view.select_token(serial)
        driver.find_element_by_id("button_assign").click()
        time.sleep(2)
        pin = "asdf1234"
        driver.find_element_by_id("pin1").clear()
        driver.find_element_by_id("pin1").send_keys(pin)
        driver.find_element_by_id("pin2").clear()
        driver.find_element_by_id("pin2").send_keys(pin)
        driver.find_element_by_id("button_setpin_setpin").click()
        time.sleep(1)

        validate = Validate(self.http_protocol, self.http_host,
                            self.http_username, self.http_password)

        valid_otps = [
            public_uid + "fcniufvgvjturjgvinhebbbertjnihit",
            public_uid + "tbkfkdhnfjbjnkcbtbcckklhvgkljifu",
            public_uid + "ktvkekfgufndgbfvctgfrrkinergbtdj",
            public_uid + "jbefledlhkvjjcibvrdfcfetnjdjitrn",
            public_uid + "druecevifbfufgdegglttghghhvhjcbh",
            public_uid + "nvfnejvhkcililuvhntcrrulrfcrukll",
            public_uid + "kttkktdergcenthdredlvbkiulrkftuk",
            public_uid + "hutbgchjucnjnhlcnfijckbniegbglrt",
            public_uid + "vneienejjnedbfnjnnrfhhjudjgghckl",
            public_uid + "krgevltjnujcnuhtngjndbhbiiufbnki",
            public_uid + "kehbefcrnlfejedfdulubuldfbhdlicc",
            public_uid + "ljlhjbkejkctubnejrhuvljkvglvvlbk",
        ]

        for otp in valid_otps:
            access_granted, _ = validate.validate(user=self.user_name + "@" +
                                                  self.realm_name,
                                                  password=pin + otp)
            self.assertTrue(
                access_granted, "OTP: " + pin + otp + " for user " +
                self.user_name + "@" + self.realm_name + " returned False")

        # validate/check_yubikey
        password = pin + public_uid + "eihtnehtetluntirtirrvblfkttbjuih"
        cy_auth = HTTPDigestAuth(self.http_username, self.http_password)
        cy_validate_url = self.http_protocol + "://" + self.http_host + "/validate/check_yubikey?"
        response = requests.get(cy_validate_url,
                                params={'pass': password},
                                auth=cy_auth,
                                verify=False)
        self.assertEqual(response.status_code, 200,
                         "Invalid response %r" % response)
        return_json = response.json()
        self.assertTrue(return_json['result']['status'],
                        "Invalid return value: %r" % return_json)
        self.assertTrue(return_json['result']['value'],
                        "Invalid return value: %r" % return_json)
        self.assertEqual(return_json['detail']['user'], self.user_name,
                         "Invalid return value: %r" % return_json)
        self.assertEqual(return_json['detail']['realm'], self.realm_name,
                         "Invalid return value: %r" % return_json)

        # Repeat an old (therefore invalid) OTP value
        invalid_otp = public_uid + "fcniufvgvjturjgvinhebbbertjnihit"
        access_granted, _ = validate.validate(user=self.user_name + "@" +
                                              self.realm_name,
                                              password=pin + invalid_otp)
        self.assertFalse(
            access_granted, "OTP: " + pin + invalid_otp + " for user " +
            self.user_name + "@" + self.realm_name + " should be rejected.")

        # Repeat an old (therefore invalid) OTP value with validate/check_yubikey
        invalid_otp = pin + public_uid + "fcniufvgvjturjgvinhebbbertjnihit"
        response = requests.get(cy_validate_url,
                                params={'pass': password},
                                auth=cy_auth,
                                verify=False)
        self.assertEqual(response.status_code, 200,
                         "Invalid response %r" % response)
        return_json = response.json()
        self.assertTrue(return_json['result']['status'],
                        "Invalid return value: %r" % return_json)
        self.assertFalse(return_json['result']['value'],
                         "Invalid return value: %r" % return_json)
        try:
            return_json['detail']['user']
            self.fail("Response should not contain detail.user %r" %
                      return_json)
        except KeyError:
            pass
        try:
            return_json['detail']['realm']
            self.fail("Response should not contain detail.realm %r" %
                      return_json)
        except KeyError:
            pass
    def test_scenario01(self):
        """Tests Scenario 01 (https://wally/projects/linotp/wiki/TestingTest_Szenario_01)"""

        driver = self.driver

        self.reset_resolvers_and_realms()

        self._announce_test("1. UserIdResolver anlegen")
        # Create LDAP UserIdResolver
        ldap_data = data.musicians_ldap_resolver
        ldap_expected_users = ['bach', 'beethoven', 'berlioz', 'brahms', 'debussy', u'dvořák',
                               'haydn', 'mozart', u'حافظ', u'郎']
        ldap_num_expected_users = len(ldap_expected_users)
        ldap_resolver = self.useridresolver_manager.create_resolver(ldap_data)

        # Create SQL UserIdResolver
        sql_data = data.sql_resolver
        sql_resolver = self.useridresolver_manager.create_resolver(sql_data)
        sql_expected_users = ["corny", "kay", "eric", u"knöt"]
        sql_num_expected_users = len(sql_expected_users)

        # Create realm for all resolvers
        realm_name1 = "SE_scenario01_realm1"
        realm_name2 = "SE_scenario01_realm2"
        self.realm_manager.create(realm_name1, [ldap_resolver])
        self.realm_manager.create(realm_name2, [sql_resolver])

        self._announce_test("2. In Management Webinterface, check that all users are visible")

        user_view = UserView(driver, self.base_url, realm_name1)
        self.assertEqual(ldap_num_expected_users, user_view.get_num_users(),
                         "Not the expected number of users")
        for user in ldap_expected_users:
            self.assertTrue(user_view.user_exists(user), "User '" + user +
                            "' should exist.")

        user_view = UserView(driver, self.base_url, realm_name2)
        self.assertEqual(sql_num_expected_users, user_view.get_num_users(),
                         "Not the expected number of users")
        for user in sql_expected_users:
            self.assertTrue(user_view.user_exists(user), "User '" + user +
                            "' should exist.")

        self._announce_test("3. eToken.xml ueber das Webinterface importieren")

        seed_oath137332 = "ff06df50017d3b981cfbc4ec4d374040164d8d19"
        seed_oath137332_bin = binascii.unhexlify(seed_oath137332)
        file_content = """<Tokens>
<Token serial="00040008CFA5">
<CaseModel>5</CaseModel>
<Model>101</Model>
<ProductionDate>02/19/2009</ProductionDate>
<ProductName>Safeword Alpine</ProductName>
<Applications>
<Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb9}">
<Seed>123412354</Seed>
<MovingFactor>1</MovingFactor>
</Application>
</Applications>
</Token>
<Token serial="00040008CFA52">
<CaseModel>5</CaseModel>
<Model>101</Model>
<ProductionDate>02/19/2009</ProductionDate>
<ProductName>Safeword Alpine</ProductName>
<Applications>
<Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb9}">
<Seed>123456</Seed>
<MovingFactor>1</MovingFactor>
</Application>
</Applications>
</Token>
<Token serial="oath137332">
<CaseModel>5</CaseModel>
<Model>101</Model>
<ProductionDate>02/19/2009</ProductionDate>
<ProductName>Safeword Alpine</ProductName>
<Applications>
<Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb1}">
<Seed>""" + seed_oath137332 + """</Seed>
<MovingFactor>1</MovingFactor>
</Application>
</Applications>
</Token>
<Token serial="oath12482B">
<CaseModel>5</CaseModel>
<Model>101</Model>
<ProductionDate>02/19/2009</ProductionDate>
<ProductName>Safeword Alpine</ProductName>
<Applications>
<Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb2}">
<Seed>6ec1d0e9915a2bebf84745b318e39e481249c1eb</Seed>
<MovingFactor>1</MovingFactor>
</Application>
</Applications>
</Token>
</Tokens>"""

        TokenImport(driver, self.base_url, "safenet", file_content, None)

        serial_token_bach = "oath137332"
        test1_realm = realm_name1.lower()

        self._announce_test("4. Im Management Webinterface nun eine Policy anlegen")

        Policy(driver, self.base_url, "SE_scenario01", "selfservice",
               "enrollMOTP, setOTPPIN, setMOTPPIN, resync, disable ",
               test1_realm)

        self._announce_test("5. eToken zuweisen")

        user_view = UserView(driver, self.base_url, test1_realm)
        user_view.select_user("bach")
        token_view = TokenView(self)
        token_view.assign_token(serial_token_bach, "1234")

        self._announce_test("6. Remote Token zuweisen")

        user_view = UserView(driver, self.base_url, test1_realm)
        user_view.select_user("debussy")
        remote_token = RemoteToken(driver=self.driver,
                                   base_url=self.base_url,
                                   url="https://billybones",
                                   remote_serial="LSSP0002F653",
                                   pin="1234",
                                   remote_otp_length=6,
                                   )
        serial_token_debussy = remote_token.serial
        remote_token_otp = "666666"

        self._announce_test("7. Spass-Token zuweisen")

        user_view = UserView(driver, self.base_url, test1_realm)
        user_view.select_user("beethoven")
        spass_token = SpassToken(
            driver=self.driver,
            base_url=self.base_url,
            pin=u"beethovenspass#ñô",
            description="SPass Token enrolled with Selenium"
            )
        serial_token_beethoven = spass_token.serial

        self._announce_test("8. Selfservice mOTP")

        motp_key = "1234123412341234"
        motp_pin = "1234"
        driver.get(self.base_url + "/account/login")
        driver.find_element_by_id("login").clear()
        driver.find_element_by_id("login").send_keys("mozart@" + test1_realm)
        driver.find_element_by_id("password").clear()
        driver.find_element_by_id("password").send_keys("Test123!")
        driver.find_element_by_id("password").submit() # Submits the form
        driver.find_element_by_id("motp_secret").clear()
        driver.find_element_by_id("motp_secret").send_keys(motp_key)
        driver.find_element_by_id("motp_s_pin1").clear()
        driver.find_element_by_id("motp_s_pin1").send_keys(motp_pin)
        driver.find_element_by_id("motp_s_pin2").clear()
        driver.find_element_by_id("motp_s_pin2").send_keys(motp_pin)
        driver.find_element_by_id("motp_self_desc").clear()
        driver.find_element_by_id("motp_self_desc").send_keys("Selenium self enrolled")
        driver.find_element_by_id("button_register_motp").click()
        alert_box_text = driver.find_element_by_id("alert_box_text").text
        m = re.match(
            r"""
                .*?
                Token\ enrolled\ successfully
                .*?
                [sS]erial(\ number)?:     # 'serial:' or 'Serial number:'
                \s*
                (?P<serial>\w+)           # For example: LSMO0001222C
                """,
            alert_box_text,
            re.DOTALL | re.VERBOSE
            )
        self.assertTrue(
            m is not None,
            "alert_box_text does not match regex. Possibly the token was not enrolled properly. %r" % alert_box_text
            )
        serial_token_mozart = m.group('serial')
        self.driver.find_element_by_xpath("//button[@type='button' and ancestor::div[@aria-describedby='alert_box']]").click()
        driver.find_element_by_link_text("Logout").click()

        self._announce_test("9. Alle 4 Benutzer melden sich im selfservice Portal an und setzen die PIN")

        user_token_dict = {
            "bach": serial_token_bach,
            "debussy": serial_token_debussy,
            "mozart": serial_token_mozart,
            "beethoven": serial_token_beethoven
            }
        for user in user_token_dict:
            driver.get(self.base_url + "/account/login")
            driver.find_element_by_id("login").clear()
            driver.find_element_by_id("login").send_keys("%s@%s" % (user, test1_realm))
            driver.find_element_by_id("password").clear()
            driver.find_element_by_id("password").send_keys("Test123!")
            driver.find_element_by_id("password").submit()
            driver.find_element_by_xpath("//div[@id='tabs']/ul/li/a/span[text()='set PIN']").click()
            time.sleep(1)
            # driver.find_element_by_css_selector('#tokenDiv > ul > li > a').click()
            driver.find_element_by_id('tokenDiv').find_element_by_partial_link_text(user_token_dict[user]).click()
            driver.find_element_by_id("pin1").clear()
            driver.find_element_by_id("pin1").send_keys(user + "newpin")
            driver.find_element_by_id("pin2").clear()
            driver.find_element_by_id("pin2").send_keys(user + "newpin")
            driver.find_element_by_id("button_setpin").click()
            time.sleep(1)
            self.assertEqual("PIN set successfully", self.close_alert_and_get_its_text())
            driver.find_element_by_link_text("Logout").click()

        self._announce_test("10. Authentisierung der 4 Benutzer ###")
        validate = Validate(self.http_protocol,
                            self.http_host,
                            self.http_port,
                            self.http_username,
                            self.http_password)

        # Validate HOTP Token - bach
        hotp = HmacOtp()
        for counter in range(0, 20):
            otp = "bachnewpin" + hotp.generate(counter=counter, key=seed_oath137332_bin)
            access_granted, _ = validate.validate(user="******" +
                                                test1_realm, password=otp)
            self.assertTrue(access_granted, "OTP: " + otp + " for user " +
                            "bach@" + test1_realm + " returned False")
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******")
        self.assertFalse(access_granted, "OTP: 1234111111 should be False for user bach")

        # Validate Remote token - debussy
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******" + remote_token_otp)
        self.assertTrue(access_granted, "OTP: " + remote_token_otp + " for user " +
                        "debussy@" + test1_realm + " returned False")
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******")
        self.assertFalse(access_granted, "OTP: 1234111111 should be False for user debussy")

        # Validate Spass token - beethoven
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******")
        self.assertTrue(access_granted, "OTP: " + "beethovennewpin" + " for user " +
                        "beethoven@" + test1_realm + " returned False")
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******")
        self.assertFalse(access_granted, "OTP: randominvalidpin should be False for user beethoven")

        # Validate mOTP token - mozart
        current_epoch = time.time()
        motp_otp = calculate_motp(
            epoch=current_epoch,
            key=motp_key,
            pin=motp_pin
            )
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******" + motp_otp)
        self.assertTrue(access_granted, "OTP: " + motp_otp + " for user " +
                        "mozart@" + test1_realm + " returned False")
        motp_otp = calculate_motp(
            epoch=current_epoch - 4000,
            key=motp_key,
            pin=motp_pin
            )
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******" + motp_otp)
        self.assertFalse(access_granted, "OTP: mozartnewpin%s should be False for user mozart" % motp_otp)

        self._announce_test("11. mOTP Pin im selfservice ändern")

        driver.get(self.base_url + "/account/login")
        driver.find_element_by_id("login").clear()
        driver.find_element_by_id("login").send_keys("%s@%s" % ("mozart", test1_realm))
        driver.find_element_by_id("password").clear()
        driver.find_element_by_id("password").send_keys("Test123!")
        driver.find_element_by_id("password").submit()
        driver.find_element_by_xpath("//div[@id='tabs']/ul/li/a/span[text()='set mOTP PIN']").click()
        driver.find_element_by_id('tokenDiv').find_element_by_link_text(serial_token_mozart).click()
        driver.find_element_by_id("mpin1").clear()
        new_motp_pin = "5588"
        driver.find_element_by_id("mpin1").send_keys(new_motp_pin)
        driver.find_element_by_id("mpin2").clear()
        driver.find_element_by_id("mpin2").send_keys(new_motp_pin)
        driver.find_element_by_id("button_setmpin").click()
        self.assertEqual("mOTP PIN set successfully", self.close_alert_and_get_its_text())
        driver.find_element_by_link_text("Logout").click()

        time.sleep(10) # otherwise next mOTP value might not be valid

        current_epoch = time.time()
        motp_otp = calculate_motp(
            epoch=current_epoch,
            key=motp_key,
            pin=new_motp_pin
            )
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******" + motp_otp)
        self.assertTrue(access_granted, "OTP: mozartnewpin" + motp_otp + " for user " +
                        "mozart@" + test1_realm + " returned False")

        self._announce_test("12. Token Resynchronisierung")

        # Bach 'presses' his token more than 10 times and fails to authenticate
        counter = 50 # was 19
        hotp = HmacOtp()
        otp = "bachnewpin" + hotp.generate(counter=counter, key=seed_oath137332_bin)
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password=otp)
        self.assertFalse(access_granted, "OTP: %s should be False for user bach" % otp)

        driver.get(self.base_url + "/account/login")
        driver.find_element_by_id("login").clear()
        driver.find_element_by_id("login").send_keys("%s@%s" % ("bach", test1_realm))
        driver.find_element_by_id("password").clear()
        driver.find_element_by_id("password").send_keys("Test123!")
        driver.find_element_by_id("password").submit()
        driver.find_element_by_xpath("//div[@id='tabs']/ul/li/a/span[text()='Resync Token']").click()
        driver.find_element_by_id('tokenDiv').find_element_by_link_text(serial_token_bach).click()
        otp1 = hotp.generate(counter=counter + 1, key=seed_oath137332_bin)
        otp2 = hotp.generate(counter=counter + 2, key=seed_oath137332_bin)
        driver.find_element_by_id("otp1").clear()
        driver.find_element_by_id("otp1").send_keys(otp1)
        driver.find_element_by_id("otp2").clear()
        driver.find_element_by_id("otp2").send_keys(otp2)
        driver.find_element_by_id("button_resync").click()
        self.assertEqual("Token resynced successfully", self.close_alert_and_get_its_text())
        driver.find_element_by_link_text("Logout").click()

        # Should be able to authenticate again
        otp = "bachnewpin" + hotp.generate(counter=counter + 3, key=seed_oath137332_bin)
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password=otp)
        self.assertTrue(access_granted, "OTP: %s should be True for user bach" % otp)

        self._announce_test("13. Ein Benutzer debussy deaktiviert seinen Token im Selfservice portal und versucht sich anzumelden.")

        driver.get(self.base_url + "/account/login")
        driver.find_element_by_id("login").clear()
        driver.find_element_by_id("login").send_keys("%s@%s" % ("debussy", test1_realm))
        driver.find_element_by_id("password").clear()
        driver.find_element_by_id("password").send_keys("Test123!")
        driver.find_element_by_id("password").submit()
        driver.find_element_by_xpath("//div[@id='tabs']/ul/li/a/span[text()='Disable Token']").click()
        driver.find_element_by_id('tokenDiv').find_element_by_link_text(serial_token_debussy).click()
        driver.find_element_by_id("button_disable").click()
        self.assertEqual("Token disabled successfully", self.close_alert_and_get_its_text())
        driver.find_element_by_link_text("Logout").click()

        # debussy should be unable to authenticate
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******" + remote_token_otp)
        self.assertFalse(access_granted, "OTP: debussynewpin" + remote_token_otp + "should be False for user debussy")

        self._announce_test("14. Der Admin entsperrt diesen Token, der Benutzer debussy kann sich wieder anmelden.")

        driver.get(self.base_url + "/manage")
        token_view = TokenView(self)
        token_view.select_token(serial_token_debussy)
        driver.find_element_by_id("button_enable").click()

        # debussy should be able to authenticate
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******" + remote_token_otp)
        self.assertTrue(access_granted, "OTP: debussynewpin" + remote_token_otp + "should be True for user debussy")
Exemple #17
0
    def test_yubico_mode(self):
        """
        Enrolls a Yubikey in YUBICO mode and verifies OTPs against it
        """
        url = self.http_host
        if self.http_port:
            url = '%s:%s' % (self.http_host, self.http_port)
        # Enroll Yubikey
        serialnum = "01382015"
        yubi_slot = 1
        serial = "UBAM%s_%s" % (serialnum, yubi_slot)
        otpkey = "9163508031b20d2fbb1868954e041729"
        yubi_otplen = 48
        description = "Enrolled by TestYubikey"
        public_uid = "ecebeeejedecebeg"

        inittoken_response = self.manage_ui.admin_api_call(
            "admin/init",
            {
                "type": "yubikey",
                "serial": serial,
                "otpkey": otpkey,
                "otplen": yubi_otplen,
                "description": description,
            },
        )
        assert inittoken_response, "Error enrolling Yubikey"

        self.user_view.select_user(self.user_name)
        pin = "asdf1234"
        self.manage_ui.token_view.assign_token(serial, pin)

        validate = Validate(self.http_protocol, self.http_host, self.http_port,
                            self.http_username, self.http_password)

        valid_otps = [
            public_uid + "fcniufvgvjturjgvinhebbbertjnihit",
            public_uid + "tbkfkdhnfjbjnkcbtbcckklhvgkljifu",
            public_uid + "ktvkekfgufndgbfvctgfrrkinergbtdj",
            public_uid + "jbefledlhkvjjcibvrdfcfetnjdjitrn",
            public_uid + "druecevifbfufgdegglttghghhvhjcbh",
            public_uid + "nvfnejvhkcililuvhntcrrulrfcrukll",
            public_uid + "kttkktdergcenthdredlvbkiulrkftuk",
            public_uid + "hutbgchjucnjnhlcnfijckbniegbglrt",
            public_uid + "vneienejjnedbfnjnnrfhhjudjgghckl",
            public_uid + "krgevltjnujcnuhtngjndbhbiiufbnki",
            public_uid + "kehbefcrnlfejedfdulubuldfbhdlicc",
            public_uid + "ljlhjbkejkctubnejrhuvljkvglvvlbk",
        ]

        for otp in valid_otps:
            access_granted, _ = validate.validate(user=self.user_name + "@" +
                                                  self.realm_name,
                                                  password=pin + otp)
            assert access_granted, "OTP: " + pin + otp + " for user " + \
                            self.user_name + "@" + self.realm_name + " returned False"

        # validate/check_yubikey
        password = pin + public_uid + "eihtnehtetluntirtirrvblfkttbjuih"
        cy_auth = HTTPDigestAuth(self.http_username, self.http_password)
        cy_validate_url = self.http_protocol + \
            "://" + url + "/validate/check_yubikey?"
        response = requests.get(cy_validate_url,
                                params={'pass': password},
                                auth=cy_auth,
                                verify=False)
        assert response.status_code == 200, "Invalid response %r" % response
        return_json = response.json()
        assert return_json['result']['status'], \
                        "Invalid return value: %r" % return_json
        assert return_json['result']['value'], \
                        "Invalid return value: %r" % return_json
        assert return_json['detail']['user'] == \
                         self.user_name, \
                         "Invalid return value: %r" % return_json
        assert return_json['detail']['realm'] == \
                         self.realm_name, \
                         "Invalid return value: %r" % return_json

        # Repeat an old (therefore invalid) OTP value
        invalid_otp = public_uid + "fcniufvgvjturjgvinhebbbertjnihit"
        access_granted, _ = validate.validate(user=self.user_name + "@" +
                                              self.realm_name,
                                              password=pin + invalid_otp)
        assert not access_granted, \
                         "OTP: " + pin + invalid_otp + " for user " + self.user_name + "@" + \
                         self.realm_name + " should be rejected."

        # Repeat an old (therefore invalid) OTP value with
        # validate/check_yubikey
        invalid_otp = pin + public_uid + "fcniufvgvjturjgvinhebbbertjnihit"
        response = requests.get(cy_validate_url,
                                params={'pass': password},
                                auth=cy_auth,
                                verify=False)
        assert response.status_code == 200, "Invalid response %r" % response
        return_json = response.json()
        assert return_json['result']['status'], \
                        "Invalid return value: %r" % return_json
        assert not return_json['result']['value'], \
                         "Invalid return value: %r" % return_json
        try:
            return_json['detail']['user']
            self.fail("Response should not contain detail.user %r" %
                      return_json)
        except KeyError:
            pass
        try:
            return_json['detail']['realm']
            self.fail("Response should not contain detail.realm %r" %
                      return_json)
        except KeyError:
            pass
    def test_scenario01(self):
        """Tests Scenario 01 (https://wally/projects/linotp/wiki/TestingTest_Szenario_01)"""

        driver = self.driver

        token_view = self.manage_ui.token_view
        user_view = self.manage_ui.user_view

        selfservice = SelfService(self.driver, self.base_url)

        # reset all views
        self.reset_resolvers_and_realms()
        self.manage_ui.policy_view.clear_policies()
        token_view.delete_all_tokens()

        self._announce_test("1. UserIdResolver anlegen")
        # Create LDAP UserIdResolver
        ldap_data = data.musicians_ldap_resolver
        ldap_resolver = self.useridresolver_manager.create_resolver(ldap_data)

        # Create SQL UserIdResolver
        sql_data = data.sql_resolver

        sql_resolver = self.useridresolver_manager.create_resolver(sql_data)
        self.useridresolver_manager.close()

        # Create realm for all resolvers
        realm_name1 = "SE_scenario01_realm1"
        realm_name2 = "SE_scenario01_realm2"

        self.realm_manager.create(realm_name1, [ldap_resolver])
        self.realm_manager.create(realm_name2, [sql_resolver])
        self.realm_manager.close()

        self._announce_test(
            "2. In Management Webinterface, check that all users are visible")

        self.check_users(realm_name1, ldap_data)
        self.check_users(realm_name2, sql_data)

        self._announce_test("3. eToken.xml ueber das Webinterface importieren")

        seed_oath137332 = "ff06df50017d3b981cfbc4ec4d374040164d8d19"
        seed_oath137332_bin = binascii.unhexlify(seed_oath137332)
        file_content = """<Tokens>
<Token serial="00040008CFA5">
<CaseModel>5</CaseModel>
<Model>101</Model>
<ProductionDate>02/19/2009</ProductionDate>
<ProductName>Safeword Alpine</ProductName>
<Applications>
<Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb9}">
<Seed>123412354</Seed>
<MovingFactor>1</MovingFactor>
</Application>
</Applications>
</Token>
<Token serial="00040008CFA52">
<CaseModel>5</CaseModel>
<Model>101</Model>
<ProductionDate>02/19/2009</ProductionDate>
<ProductName>Safeword Alpine</ProductName>
<Applications>
<Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb9}">
<Seed>123456</Seed>
<MovingFactor>1</MovingFactor>
</Application>
</Applications>
</Token>
<Token serial="oath137332">
<CaseModel>5</CaseModel>
<Model>101</Model>
<ProductionDate>02/19/2009</ProductionDate>
<ProductName>Safeword Alpine</ProductName>
<Applications>
<Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb1}">
<Seed>""" + seed_oath137332 + """</Seed>
<MovingFactor>1</MovingFactor>
</Application>
</Applications>
</Token>
<Token serial="oath12482B">
<CaseModel>5</CaseModel>
<Model>101</Model>
<ProductionDate>02/19/2009</ProductionDate>
<ProductName>Safeword Alpine</ProductName>
<Applications>
<Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb2}">
<Seed>6ec1d0e9915a2bebf84745b318e39e481249c1eb</Seed>
<MovingFactor>1</MovingFactor>
</Application>
</Applications>
</Token>
</Tokens>"""

        TokenImport(driver, self.base_url, "safenet", file_content, None)

        serial_token_bach = "oath137332"
        test1_realm = realm_name1.lower()

        self._announce_test(
            "4. Im Management Webinterface nun eine Policy anlegen")

        Policy(self.manage_ui, "SE_scenario01", "selfservice",
               "enrollMOTP, setOTPPIN, setMOTPPIN, resync, disable ",
               test1_realm)

        self._announce_test("5. eToken zuweisen")

        user_view.select_realm(test1_realm)
        user_view.select_user("bach")

        token_view.assign_token(serial_token_bach, "1234")

        self._announce_test("6. Remote Token zuweisen")

        user_view.select_user("debussy")
        remote_token = RemoteToken(
            driver=self.driver,
            base_url=self.base_url,
            url="https://billybones",
            remote_serial="LSSP0002F653",
            pin="1234",
            remote_otp_length=6,
        )
        serial_token_debussy = remote_token.serial

        self._announce_test("7. Spass-Token zuweisen")

        user_view.select_user("beethoven")
        spass_token = SpassToken(
            driver=self.driver,
            base_url=self.base_url,
            pin=u"beethovenspass#ñô",
            description="SPass Token enrolled with Selenium")
        serial_token_beethoven = spass_token.serial

        self._announce_test("8. Selfservice mOTP")

        motp_key = "1234123412341234"
        motp_pin = "1234"
        selfservice.login("mozart", "Test123!", test1_realm)
        driver.find_element_by_id("motp_secret").clear()
        driver.find_element_by_id("motp_secret").send_keys(motp_key)
        driver.find_element_by_id("motp_s_pin1").clear()
        driver.find_element_by_id("motp_s_pin1").send_keys(motp_pin)
        driver.find_element_by_id("motp_s_pin2").clear()
        driver.find_element_by_id("motp_s_pin2").send_keys(motp_pin)
        driver.find_element_by_id("motp_self_desc").clear()
        driver.find_element_by_id("motp_self_desc").send_keys(
            "Selenium self enrolled")
        driver.find_element_by_id("button_register_motp").click()
        alert_box_text = driver.find_element_by_id("alert_box_text").text
        m = re.match(
            r"""
                .*?
                Token\ enrolled\ successfully
                .*?
                [sS]erial(\ number)?:     # 'serial:' or 'Serial number:'
                \s*
                (?P<serial>\w+)           # For example: LSMO0001222C
                """, alert_box_text, re.DOTALL | re.VERBOSE)
        self.assertTrue(
            m is not None,
            "alert_box_text does not match regex. Possibly the token was not enrolled properly. %r"
            % alert_box_text)
        serial_token_mozart = m.group('serial')
        self.driver.find_element_by_xpath(
            "//button[@type='button' and ancestor::div[@aria-describedby='alert_box']]"
        ).click()
        driver.find_element_by_link_text("Logout").click()

        self._announce_test(
            "9. Alle 4 Benutzer melden sich im selfservice Portal an und setzen die PIN"
        )

        user_token_dict = {
            "bach": serial_token_bach,
            "debussy": serial_token_debussy,
            "mozart": serial_token_mozart,
            "beethoven": serial_token_beethoven
        }
        for user, token in user_token_dict.iteritems():
            selfservice.login(user, "Test123!", test1_realm)
            selfservice.set_pin(token, user + "newpin")
            selfservice.logout()

        self._announce_test("10. Authentisierung der 4 Benutzer ###")
        validate = Validate(self.http_protocol, self.http_host, self.http_port,
                            self.http_username, self.http_password)

        # Validate HOTP Token - bach
        hotp = HmacOtp()
        for counter in range(0, 20):
            otp = "bachnewpin" + \
                hotp.generate(counter=counter, key=seed_oath137332_bin)
            access_granted, _ = validate.validate(user="******" + test1_realm,
                                                  password=otp)
            self.assertTrue(
                access_granted, "OTP: " + otp + " for user " + "bach@" +
                test1_realm + " returned False")
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******")
        self.assertFalse(access_granted,
                         "OTP: 1234111111 should be False for user bach")

        # Validate Remote token - debussy

        # deactivated remote token test while no remote linotp integration
        # server is available
        '''
        remote_token_otp = "666666"
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******" + remote_token_otp)
        self.assertTrue(access_granted, "OTP: " + remote_token_otp + " for user " +
                        "debussy@" + test1_realm + " returned False")
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                            password="******")
        self.assertFalse(access_granted, "OTP: 1234111111 should be False for user debussy")'''

        # Validate Spass token - beethoven
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******")
        self.assertTrue(
            access_granted, "OTP: " + "beethovennewpin" + " for user " +
            "beethoven@" + test1_realm + " returned False")
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******")
        self.assertFalse(
            access_granted,
            "OTP: randominvalidpin should be False for user beethoven")

        # Validate mOTP token - mozart
        current_epoch = time.time()
        motp_otp = calculate_motp(epoch=current_epoch,
                                  key=motp_key,
                                  pin=motp_pin)

        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******" +
                                              motp_otp)
        time.sleep(1)
        self.assertTrue(
            access_granted, "OTP: " + motp_otp + " for user " + "mozart@" +
            test1_realm + " returned False")
        motp_otp = calculate_motp(epoch=current_epoch - 4000,
                                  key=motp_key,
                                  pin=motp_pin)
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******" +
                                              motp_otp)
        self.assertFalse(
            access_granted,
            "OTP: mozartnewpin%s should be False for user mozart" % motp_otp)

        self._announce_test("11. mOTP Pin im selfservice ändern")

        new_motp_pin = "5588"

        selfservice.login("mozart", "Test123!", test1_realm)
        selfservice.set_motp_pin(token, new_motp_pin)
        selfservice.logout()

        time.sleep(10)  # otherwise next mOTP value might not be valid

        current_epoch = time.time()
        motp_otp = calculate_motp(epoch=current_epoch,
                                  key=motp_key,
                                  pin=new_motp_pin)
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******" +
                                              motp_otp)
        self.assertTrue(
            access_granted, "OTP: mozartnewpin" + motp_otp + " for user " +
            "mozart@" + test1_realm + " returned False")

        self._announce_test("12. Token Resynchronisierung")

        # Bach 'presses' his token more than 10 times and fails to authenticate
        counter = 50  # was 19
        hotp = HmacOtp()
        otp = "bachnewpin" + \
            hotp.generate(counter=counter, key=seed_oath137332_bin)
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password=otp)
        self.assertFalse(access_granted,
                         "OTP: %s should be False for user bach" % otp)

        selfservice.login("bach", "Test123!", test1_realm)

        otp1 = hotp.generate(counter=counter + 1, key=seed_oath137332_bin)
        otp2 = hotp.generate(counter=counter + 2, key=seed_oath137332_bin)

        selfservice.resync_token(serial_token_bach, otp1, otp2)
        selfservice.logout()

        # Should be able to authenticate again
        otp = "bachnewpin" + \
            hotp.generate(counter=counter + 3, key=seed_oath137332_bin)
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password=otp)
        self.assertTrue(access_granted,
                        "OTP: %s should be True for user bach" % otp)

        self._announce_test(
            "13. Benutzer beethoven deaktiviert seinen Token im Selfservice portal und versucht sich anzumelden."
        )

        selfservice.login("beethoven", "Test123!", test1_realm)
        selfservice.disable_token(serial_token_beethoven)
        selfservice.logout()

        # beethoven should be unable to authenticate
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******")
        self.assertFalse(
            access_granted,
            "OTP: beethovennewpin should be False for user beethoven")

        self._announce_test(
            "14. Der Admin entsperrt diesen Token, der Benutzer beethoven kann sich wieder anmelden."
        )

        token_view.open()
        token_view.select_token(serial_token_beethoven)
        driver.find_element_by_id("button_enable").click()

        time.sleep(1)
        # beethoven should be able to authenticate
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******")
        self.assertTrue(
            access_granted,
            "OTP: beethovennewpin should be able to authenticate after re-enabled token."
        )
Exemple #19
0
    def test_scenario01(self):
        """Tests Scenario 01 (https://wally/projects/linotp/wiki/TestingTest_Szenario_01)"""

        driver = self.driver

        ### 1. UserIdResolver anlegen ###
        CA001_cert = \
"""-----BEGIN CERTIFICATE-----
MIIDcjCCAtugAwIBAgIQVSU6NwMTmKNI6t3WcjY6uTANBgkqhkiG9w0BAQUFADBC
MRUwEwYKCZImiZPyLGQBGRYFbG9jYWwxGTAXBgoJkiaJk/IsZAEZFglsc2V4cGVy
dHMxDjAMBgNVBAMTBUNBMDAxMB4XDTA1MDQxMTE2NDgzOVoXDTQwMDQxMTE2NTY1
MFowQjEVMBMGCgmSJomT8ixkARkWBWxvY2FsMRkwFwYKCZImiZPyLGQBGRYJbHNl
eHBlcnRzMQ4wDAYDVQQDEwVDQTAwMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC
gYEAqlWLfYK+dExjG+Qa/jpYjSo3EQnweQ7azacosa+xsrTMfDV5wLgMBSclCTX2
i/35VRg282Bh7hKCZifOBnAxjCBIHMpHQmW9c0T/GpeWSOQ1x0KeKrZ4PRj5oHEv
/uDJ7q2HlWXgRQo6NR75yDGLpsAWk64TyQ/I4f2vlC+AtjMCAyPS46OCAWcwggFj
MBMGCSsGAQQBgjcUAgQGHgQAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTAD
AQH/MB0GA1UdDgQWBBTCY8rVNcU/NGvgZxaPmO+Kz8bG4TCB/AYDVR0fBIH0MIHx
MIHuoIHroIHohoGwbGRhcDovLy9DTj1DQTAwMSxDTj1sc2V4czAxLENOPUNEUCxD
Tj1QdWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxDTj1Db25maWd1
cmF0aW9uLERDPWxzZXhwZXJ0cyxEQz1sb2NhbD9jZXJ0aWZpY2F0ZVJldm9jYXRp
b25MaXN0P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnSGM2h0
dHA6Ly9sc2V4czAxLmxzZXhwZXJ0cy5sb2NhbC9DZXJ0RW5yb2xsL0NBMDAxLmNy
bDAQBgkrBgEEAYI3FQEEAwIBADANBgkqhkiG9w0BAQUFAAOBgQBa+RGoezCgJS5W
PFCPy9BWqZr7iRimfRGBDqHpYDCPDtgec2fKCZ+u4jfwuTisZ7UOoiM1iEvkw0hH
Z7R1pz4Yd6E074kS/fe6u7U+9L3dmSUjFvO3gkLKtHKbhQi0NA+EHMRrPsQQemLm
gYzNiYwtvAu74Q+eTC6R5Uf0hOlFig==
-----END CERTIFICATE-----"""

        # Create LDAP UserIdResolver
        ldap_name = "SE_scenario01_ldap"
        ldap_expected_users = [
            'bach', 'beethoven', 'berlioz', 'brahms', 'debussy', u'dvořák',
            'haydn', 'mozart', u'حافظ', u'郎'
        ]
        ldap_num_expected_users = len(ldap_expected_users)
        ldap_id_resolver = LdapUserIdResolver(
            ldap_name,
            driver,
            self.base_url,
            uri="ldaps://blackdog",
            certificate=CA001_cert,
            basedn="ou=people,dc=blackdog,dc=office,dc=lsexperts,dc=de",
            # You may also use cn="Wolfgang Amadeus Mozart"
            binddn=
            u'cn="عبد الحليم حافظ",ou=people,dc=blackdog,dc=office,dc=lsexperts,dc=de',
            password="******",
            preset_ldap=True)
        time.sleep(1)

        # Create SQL UserIdResolver
        sql_name = "SE_scenario01_sql"
        sql_server = "blackdog"
        sql_database = "userdb"
        sql_user = "******"
        sql_password = "******"
        sql_table = "user"
        sql_limit = "500"
        sql_encoding = "latin1"
        sql_expected_users = ["corny", "kay", "eric", u"knöt"]
        sql_num_expected_users = len(sql_expected_users)
        sql_id_resolver = SqlUserIdResolver(sql_name, driver, self.base_url,
                                            sql_server, sql_database, sql_user,
                                            sql_password, sql_table, sql_limit,
                                            sql_encoding)
        time.sleep(1)

        # Create realm for all resolvers
        resolvers_realm1 = [ldap_id_resolver]
        realm_name1 = "SE_scenario01_realm1"
        realm1 = Realm(realm_name1, resolvers_realm1)
        realm1.create(driver, self.base_url)
        time.sleep(1)

        resolvers_realm2 = [sql_id_resolver]
        realm_name2 = "SE_scenario01_realm2"
        realm2 = Realm(realm_name2, resolvers_realm2)
        realm2.create(driver, self.base_url)
        time.sleep(1)

        ### 2. Im Management Webinterface testen, dass alle Benutzer sichtbar sind ###

        user_view = UserView(driver, self.base_url, realm_name1)
        self.assertEqual(ldap_num_expected_users, user_view.get_num_users(),
                         "Not the expected number of users")
        for user in ldap_expected_users:
            self.assertTrue(user_view.user_exists(user),
                            "User '" + user + "' should exist.")
        time.sleep(1)

        user_view = UserView(driver, self.base_url, realm_name2)
        self.assertEqual(sql_num_expected_users, user_view.get_num_users(),
                         "Not the expected number of users")
        for user in sql_expected_users:
            self.assertTrue(user_view.user_exists(user),
                            "User '" + user + "' should exist.")

        ### 3. eToken.xml ueber das Webinterface importieren  ###

        seed_oath137332 = "ff06df50017d3b981cfbc4ec4d374040164d8d19"
        seed_oath137332_bin = binascii.unhexlify(seed_oath137332)
        file_content = """<Tokens>
<Token serial="00040008CFA5">
<CaseModel>5</CaseModel>
<Model>101</Model>
<ProductionDate>02/19/2009</ProductionDate>
<ProductName>Safeword Alpine</ProductName>
<Applications>
<Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb9}">
<Seed>123412354</Seed>
<MovingFactor>1</MovingFactor>
</Application>
</Applications>
</Token>
<Token serial="00040008CFA52">
<CaseModel>5</CaseModel>
<Model>101</Model>
<ProductionDate>02/19/2009</ProductionDate>
<ProductName>Safeword Alpine</ProductName>
<Applications>
<Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb9}">
<Seed>123456</Seed>
<MovingFactor>1</MovingFactor>
</Application>
</Applications>
</Token>
<Token serial="oath137332">
<CaseModel>5</CaseModel>
<Model>101</Model>
<ProductionDate>02/19/2009</ProductionDate>
<ProductName>Safeword Alpine</ProductName>
<Applications>
<Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb1}">
<Seed>""" + seed_oath137332 + """</Seed>
<MovingFactor>1</MovingFactor>
</Application>
</Applications>
</Token>
<Token serial="oath12482B">
<CaseModel>5</CaseModel>
<Model>101</Model>
<ProductionDate>02/19/2009</ProductionDate>
<ProductName>Safeword Alpine</ProductName>
<Applications>
<Application ConnectorID="{ab1397d2-ddb6-4705-b66e-9f83f322deb2}">
<Seed>6ec1d0e9915a2bebf84745b318e39e481249c1eb</Seed>
<MovingFactor>1</MovingFactor>
</Application>
</Applications>
</Token>
</Tokens>"""

        TokenImport(driver, self.base_url, "safenet", file_content, None)

        serial_token_bach = "oath137332"
        test1_realm = realm_name1.lower()

        ### 4. Im Management Webinterface nun eine Policy anlegen ###

        Policy(driver, self.base_url, "SE_scenario01", "selfservice",
               "enrollMOTP, setOTPPIN, setMOTPPIN, resync, disable ",
               test1_realm)

        ### 5. eToken zuweisen ###

        user_view = UserView(driver, self.base_url, test1_realm)
        user_view.select_user("bach")
        token_view = TokenView(driver, self.base_url)
        token_view.select_token(serial_token_bach)
        driver.find_element_by_id("button_assign").click()
        time.sleep(2)
        driver.find_element_by_id("pin1").clear()
        driver.find_element_by_id("pin1").send_keys("1234")
        driver.find_element_by_id("pin2").clear()
        driver.find_element_by_id("pin2").send_keys("1234")
        driver.find_element_by_id("button_setpin_setpin").click()
        time.sleep(1)

        ### 6. Remote Token zuweisen ###

        user_view = UserView(driver, self.base_url, test1_realm)
        user_view.select_user("debussy")
        remote_token = RemoteToken(
            driver=self.driver,
            base_url=self.base_url,
            url="https://billybones",
            remote_serial="LSSP0002F653",
            pin="1234",
            remote_otp_length=6,
        )
        serial_token_debussy = remote_token.serial
        remote_token_otp = "666666"
        time.sleep(1)

        ### 7. Spass-Token zuweisen ###

        user_view = UserView(driver, self.base_url, test1_realm)
        user_view.select_user("beethoven")
        spass_token = SpassToken(
            driver=self.driver,
            base_url=self.base_url,
            pin=u"beethovenspass#ñô",
            description="SPass Token enrolled with Selenium")
        serial_token_beethoven = spass_token.serial
        time.sleep(1)

        ### 8. Selfservice mOTP ###

        motp_key = "1234123412341234"
        motp_pin = "1234"
        driver.get(self.base_url + "/account/login")
        driver.find_element_by_id("login").clear()
        driver.find_element_by_id("login").send_keys("mozart@" + test1_realm)
        driver.find_element_by_id("password").clear()
        driver.find_element_by_id("password").send_keys("Test123!")
        driver.find_element_by_id("password").submit()  # Submits the form
        time.sleep(1)
        driver.find_element_by_id("motp_secret").clear()
        driver.find_element_by_id("motp_secret").send_keys(motp_key)
        driver.find_element_by_id("motp_s_pin1").clear()
        driver.find_element_by_id("motp_s_pin1").send_keys(motp_pin)
        driver.find_element_by_id("motp_s_pin2").clear()
        driver.find_element_by_id("motp_s_pin2").send_keys(motp_pin)
        driver.find_element_by_id("motp_self_desc").clear()
        driver.find_element_by_id("motp_self_desc").send_keys(
            "Selenium self enrolled")
        driver.find_element_by_id("button_register_motp").click()
        time.sleep(1)
        alert_box_text = driver.find_element_by_id("alert_box_text").text
        m = re.match(
            r"""
                .*?
                Token\ enrolled\ successfully
                .*?
                [sS]erial(\ number)?:     # 'serial:' or 'Serial number:'
                \s*
                (?P<serial>\w+)           # For example: LSMO0001222C
                """, alert_box_text, re.DOTALL | re.VERBOSE)
        self.assertTrue(
            m is not None,
            "alert_box_text does not match regex. Possibly the token was not enrolled properly. %r"
            % alert_box_text)
        serial_token_mozart = m.group('serial')
        self.driver.find_element_by_xpath(
            "//button[@type='button' and ancestor::div[@aria-describedby='alert_box']]"
        ).click()
        driver.find_element_by_link_text("Logout").click()

        ### 9. Alle 4 Benutzer melden sich im selfservice Portal an und setzen die PIN

        user_token_dict = {
            "bach": serial_token_bach,
            "debussy": serial_token_debussy,
            "mozart": serial_token_mozart,
            "beethoven": serial_token_beethoven
        }
        for user in user_token_dict:
            driver.get(self.base_url + "/account/login")
            driver.find_element_by_id("login").clear()
            driver.find_element_by_id("login").send_keys("%s@%s" %
                                                         (user, test1_realm))
            driver.find_element_by_id("password").clear()
            driver.find_element_by_id("password").send_keys("Test123!")
            driver.find_element_by_id("password").submit()
            driver.find_element_by_xpath(
                "//div[@id='tabs']/ul/li/a/span[text()='set PIN']").click()
            time.sleep(1)
            # driver.find_element_by_css_selector('#tokenDiv > ul > li > a').click()
            driver.find_element_by_id(
                'tokenDiv').find_element_by_partial_link_text(
                    user_token_dict[user]).click()
            driver.find_element_by_id("pin1").clear()
            driver.find_element_by_id("pin1").send_keys(user + "newpin")
            driver.find_element_by_id("pin2").clear()
            driver.find_element_by_id("pin2").send_keys(user + "newpin")
            driver.find_element_by_id("button_setpin").click()
            time.sleep(1)
            self.assertEqual("PIN set successfully",
                             self.close_alert_and_get_its_text())
            driver.find_element_by_link_text("Logout").click()

        ### 10. Authentisierung der 4 Benutzer ###
        validate = Validate(self.http_protocol, self.http_host,
                            self.http_username, self.http_password)

        # Validate HOTP Token - bach
        hotp = HmacOtp()
        for counter in range(0, 20):
            otp = "bachnewpin" + hotp.generate(counter=counter,
                                               key=seed_oath137332_bin)
            access_granted, _ = validate.validate(user="******" + test1_realm,
                                                  password=otp)
            self.assertTrue(
                access_granted, "OTP: " + otp + " for user " + "bach@" +
                test1_realm + " returned False")
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******")
        self.assertFalse(access_granted,
                         "OTP: 1234111111 should be False for user bach")

        # Validate Remote token - debussy
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******" +
                                              remote_token_otp)
        self.assertTrue(
            access_granted, "OTP: " + remote_token_otp + " for user " +
            "debussy@" + test1_realm + " returned False")
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******")
        self.assertFalse(access_granted,
                         "OTP: 1234111111 should be False for user debussy")

        # Validate Spass token - beethoven
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******")
        self.assertTrue(
            access_granted, "OTP: " + "beethovennewpin" + " for user " +
            "beethoven@" + test1_realm + " returned False")
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******")
        self.assertFalse(
            access_granted,
            "OTP: randominvalidpin should be False for user beethoven")

        # Validate mOTP token - mozart
        current_epoch = time.time()
        motp_otp = calculate_motp(epoch=current_epoch,
                                  key=motp_key,
                                  pin=motp_pin)
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******" +
                                              motp_otp)
        self.assertTrue(
            access_granted, "OTP: " + motp_otp + " for user " + "mozart@" +
            test1_realm + " returned False")
        motp_otp = calculate_motp(epoch=current_epoch - 4000,
                                  key=motp_key,
                                  pin=motp_pin)
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******" +
                                              motp_otp)
        self.assertFalse(
            access_granted,
            "OTP: mozartnewpin%s should be False for user mozart" % motp_otp)

        ### 11. mOTP Pin im selfservice ändern ###

        driver.get(self.base_url + "/account/login")
        driver.find_element_by_id("login").clear()
        driver.find_element_by_id("login").send_keys("%s@%s" %
                                                     ("mozart", test1_realm))
        driver.find_element_by_id("password").clear()
        driver.find_element_by_id("password").send_keys("Test123!")
        driver.find_element_by_id("password").submit()
        driver.find_element_by_xpath(
            "//div[@id='tabs']/ul/li/a/span[text()='set mOTP PIN']").click()
        time.sleep(1)
        driver.find_element_by_id('tokenDiv').find_element_by_link_text(
            serial_token_mozart).click()
        driver.find_element_by_id("mpin1").clear()
        new_motp_pin = "5588"
        driver.find_element_by_id("mpin1").send_keys(new_motp_pin)
        driver.find_element_by_id("mpin2").clear()
        driver.find_element_by_id("mpin2").send_keys(new_motp_pin)
        driver.find_element_by_id("button_setmpin").click()
        time.sleep(1)
        self.assertEqual("mOTP PIN set successfully",
                         self.close_alert_and_get_its_text())
        driver.find_element_by_link_text("Logout").click()

        time.sleep(10)  # otherwise next mOTP value might not be valid

        current_epoch = time.time()
        motp_otp = calculate_motp(epoch=current_epoch,
                                  key=motp_key,
                                  pin=new_motp_pin)
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******" +
                                              motp_otp)
        self.assertTrue(
            access_granted, "OTP: mozartnewpin" + motp_otp + " for user " +
            "mozart@" + test1_realm + " returned False")

        ### 12. Token Resynchronisierung ###

        # Bach 'presses' his token more than 10 times and fails to authenticate
        counter = 50  # was 19
        hotp = HmacOtp()
        otp = "bachnewpin" + hotp.generate(counter=counter,
                                           key=seed_oath137332_bin)
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password=otp)
        self.assertFalse(access_granted,
                         "OTP: %s should be False for user bach" % otp)

        driver.get(self.base_url + "/account/login")
        driver.find_element_by_id("login").clear()
        driver.find_element_by_id("login").send_keys("%s@%s" %
                                                     ("bach", test1_realm))
        driver.find_element_by_id("password").clear()
        driver.find_element_by_id("password").send_keys("Test123!")
        driver.find_element_by_id("password").submit()
        driver.find_element_by_xpath(
            "//div[@id='tabs']/ul/li/a/span[text()='Resync Token']").click()
        time.sleep(1)
        driver.find_element_by_id('tokenDiv').find_element_by_link_text(
            serial_token_bach).click()
        otp1 = hotp.generate(counter=counter + 1, key=seed_oath137332_bin)
        otp2 = hotp.generate(counter=counter + 2, key=seed_oath137332_bin)
        driver.find_element_by_id("otp1").clear()
        driver.find_element_by_id("otp1").send_keys(otp1)
        driver.find_element_by_id("otp2").clear()
        driver.find_element_by_id("otp2").send_keys(otp2)
        driver.find_element_by_id("button_resync").click()
        time.sleep(1)
        self.assertEqual("Token resynced successfully",
                         self.close_alert_and_get_its_text())
        driver.find_element_by_link_text("Logout").click()

        # Should be able to authenticate again
        otp = "bachnewpin" + hotp.generate(counter=counter + 3,
                                           key=seed_oath137332_bin)
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password=otp)
        self.assertTrue(access_granted,
                        "OTP: %s should be True for user bach" % otp)

        ### 13. Ein Benutzer debussy deaktiviert seinen Token im Selfservice portal und versucht sich anzumelden. ###

        driver.get(self.base_url + "/account/login")
        driver.find_element_by_id("login").clear()
        driver.find_element_by_id("login").send_keys("%s@%s" %
                                                     ("debussy", test1_realm))
        driver.find_element_by_id("password").clear()
        driver.find_element_by_id("password").send_keys("Test123!")
        driver.find_element_by_id("password").submit()
        driver.find_element_by_xpath(
            "//div[@id='tabs']/ul/li/a/span[text()='Disable Token']").click()
        time.sleep(1)
        driver.find_element_by_id('tokenDiv').find_element_by_link_text(
            serial_token_debussy).click()
        driver.find_element_by_id("button_disable").click()
        time.sleep(1)
        self.assertEqual("Token disabled successfully",
                         self.close_alert_and_get_its_text())
        driver.find_element_by_link_text("Logout").click()

        # debussy should be unable to authenticate
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******" +
                                              remote_token_otp)
        self.assertFalse(
            access_granted, "OTP: debussynewpin" + remote_token_otp +
            "should be False for user debussy")

        ### 14. Der Admin entsperrt diesen Token, der Benutzer debussy kann sich wieder anmelden. ###

        driver.get(self.base_url + "/manage")
        time.sleep(1)
        token_view = TokenView(driver, self.base_url)
        token_view.select_token(serial_token_debussy)
        driver.find_element_by_id("button_enable").click()
        time.sleep(1)

        # debussy should be able to authenticate
        access_granted, _ = validate.validate(user="******" + test1_realm,
                                              password="******" +
                                              remote_token_otp)
        self.assertTrue(
            access_granted, "OTP: debussynewpin" + remote_token_otp +
            "should be True for user debussy")
Exemple #20
0
    def test_enroll(self):
        """
        Enroll sms token. After enrolling it verifies that the token info contains the
        correct sms. Then a user is authenticated using challenge response over RADIUS
        and Web API.
        """
        realm_name = self.realm_name

        radius_server = get_from_tconfig(
            ['radius', 'server'],
            default=self.http_host.split(':')[0],
        )
        radius_secret = get_from_tconfig(['radius', 'secret'], required=True)
        disable_radius = get_from_tconfig(['radius', 'disable'],
                                          default='False')

        # Enroll sms token
        username = "******"
        sms_token_pin = "1234"
        phone_number = "+49(0)1234-24"
        description = "Rolled out by Selenium"

        user_view = self.manage_ui.user_view
        user_view.select_realm(realm_name)
        user_view.select_user(username)

        sms_token = SmsToken(driver=self.driver,
                             base_url=self.base_url,
                             pin=sms_token_pin,
                             phone=phone_number,
                             description=description)

        token_view = self.manage_ui.token_view
        token_info = token_view.get_token_info(sms_token.serial)
        self.assertEqual(phone_number, token_info['LinOtp.TokenInfo']['phone'],
                         "Wrong phone number was set for sms token.")

        # Authenticate with RADIUS
        if disable_radius.lower() == 'true':
            print "Testconfig option radius.disable is set to True. Skipping RADIUS test!"
        else:
            call_array = "linotp-auth-radius -f ../../../test.ini".split()
            call_array.extend([
                '-u', username + "@" + realm_name, '-p', '1234', '-s',
                radius_secret, '-r', radius_server
            ])
            with SMSProviderServer(self, 10) as smtpsvc:
                rad1 = check_output(call_array)
                m = re.search(r"State:\['(\d+)'\]", rad1)
                self.assertTrue(
                    m is not None,
                    "'State' not found in linotp-auth-radius output. %r" %
                    rad1)
                state = m.group(1)
                print "State: %s" % state
                otp = smtpsvc.get_otp()

            call_array = "linotp-auth-radius -f ../../../test.ini".split()
            call_array.extend([
                '-u', username + "@" + realm_name, '-p', otp, '-t', state,
                '-s', radius_secret, '-r', radius_server
            ])
            rad2 = check_output(call_array)
            self.assertTrue("Access granted to user " + username in rad2,
                            "Access not granted to user. %r" % rad2)

        # Authenticate over Web API
        validate = Validate(self.http_protocol, self.http_host, self.http_port,
                            self.http_username, self.http_password)

        with SMSProviderServer(self, 10) as smtpsvc:
            access_granted, validate_resp = validate.validate(
                user=username + "@" + realm_name, password=sms_token_pin)
            self.assertFalse(
                access_granted,
                "Should return false because this request only triggers the challenge."
            )
            try:
                message = validate_resp['detail']['message']
            except KeyError:
                self.fail("detail.message should be present %r" %
                          validate_resp)
            self.assertEqual(message, "sms submitted",
                             "Wrong validate response %r" % validate_resp)
            otp = smtpsvc.get_otp()

        access_granted, validate_resp = validate.validate(
            user=username + "@" + realm_name, password=sms_token_pin + otp)
        self.assertTrue(
            access_granted,
            "Could not authenticate user %s %r" % (username, validate_resp))
Exemple #21
0
    def test_usage_timestamp(self):
        """Test the option for storing the last Authentication info of Tokens"""

        # note: how should we add the initial users before this test?
        # open config box and set the option
        pasw = "12345"
        otp = "1234"

        with self.system_config:
            self.system_config.set_last_access_option(True)
            self.system_config.save()

        # check if it is saved
        with self.system_config:
            assert (self.system_config.get_last_access_option(
            )), "token_last_access_check option should have been selected"

        self.manage_ui.token_view.clear_tokens_via_api()
        tokenserial = self.manage_ui.token_enroll.create_static_password_token(
            pasw)
        # assign token
        username = "******"
        self.manage_ui.user_view.select_user(username)
        self.manage_ui.token_view.assign_token(tokenserial, otp)

        validate = Validate(
            self.testcase.http_protocol,
            self.testcase.http_host,
            self.testcase.http_port,
            self.testcase.http_username,
            self.testcase.http_password,
        )

        # 1-successful authentication
        tvar = timedelta(seconds=2)
        validation_result = validate.validate(username, otp + pasw)
        assert (
            validation_result[0] == True
        ), "unexpected behavior: validation of user with password failed"
        validationtime = datetime.now()
        tokeninfo = self.manage_ui.token_view.get_token_info(tokenserial)
        last_authentication = datetime.strptime(
            tokeninfo["LinOtp.LastAuthSuccess"], DEFAULT_TIMEFORMAT)
        last_authentication_try = datetime.strptime(
            tokeninfo["LinOtp.LastAuthMatch"], DEFAULT_TIMEFORMAT)
        assert last_authentication <= validationtime + tvar
        assert last_authentication_try <= validationtime + tvar

        # 2-failing authentication
        time.sleep(tvar.seconds)
        validation_result = validate.validate(username, "wrong pass")

        assert (
            validation_result[0] == False
        ), "unexpected behavior: critical! validation of user should have failed here"

        validationtime = datetime.now()
        tokeninfo = self.manage_ui.token_view.get_token_info(tokenserial)
        last_authentication = datetime.strptime(
            tokeninfo["LinOtp.LastAuthSuccess"], DEFAULT_TIMEFORMAT)
        last_authentication_try = datetime.strptime(
            tokeninfo["LinOtp.LastAuthMatch"], DEFAULT_TIMEFORMAT)

        assert last_authentication < validationtime
        assert last_authentication_try <= validationtime + tvar