def _get_otp(self): """Internal method to get the OTP, either interactively over the commandline or by checking a mailbox (mbox). """ interactive = get_from_tconfig(['sms_token', 'interactive'], required=True) mbox_filepath = get_from_tconfig(['sms_token', 'mbox_filepath'], default="/var/mail/jenkins") otp = None if interactive.lower() == 'true': otp = raw_input("OTP (check your e-mail): ") else: time.sleep(10) # Wait for sms to arrive mybox = mailbox.mbox(mbox_filepath) mybox.lock() try: print "Mailbox length: " + str(len(mybox)) def get_mail_delivery_date(key_mail_pair): mail = key_mail_pair[1] date_tuple = parsedate(mail['Delivery-date']) return time.mktime(date_tuple) newest_mail_key, newest_mail = max(mybox.iteritems(), key=get_mail_delivery_date) self.assertTrue(newest_mail is not None, "No sms in mbox") payload = newest_mail.get_payload() matches = re.search(r"\d{6}", payload) self.assertTrue(matches is not None, "No OTP in sms message %r" % newest_mail) otp = matches.group(0) mybox.remove(newest_mail_key) except Exception as exc: raise exc finally: mybox.close() mybox.unlock() return otp
class TestEmailTokenAuth(TestEmailToken): def setUp(self): TestEmailToken.setUp(self) self.enroll_email_token() @unittest.skipIf(is_radius_disabled(), True) def test_radius_auth(self): def radius_auth(username, realm_name, pin, radius_secret, radius_server, state=None): call_array = "python ../../../tools/linotp-auth-radius -f ../../../test.ini".split() call_array.extend(['-u', username + "@" + realm_name, '-p', pin, '-s', radius_secret, '-r', radius_server]) if state: call_array.extend('-t', state) logger.debug("Executing %s" % ' '.join(call_array)) try: return check_output(call_array) except CalledProcessError, e: assert e.returncode == 0, \ "radius auth process exit code %s. Command:%s Ouptut:%s" % \ (e.returncode, ' '.join(e.cmd), e.output) radius_server = get_from_tconfig( ['radius', 'server'], default=self.http_host.split(':')[0], ) radius_secret = get_from_tconfig(['radius', 'secret'], required=True) with EmailProviderServer(self, 20) as smtpsvc: # Authenticate with RADIUS rad1 = radius_auth( self.username, self.realm_name, self.email_token_pin, radius_secret, radius_server) 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) logger.debug("State: %s" % state) otp = smtpsvc.get_otp() rad2 = radius_auth( self.username, self.realm_name, otp, radius_secret, radius_server, state) self.assertTrue("Access granted to user " + self.username in rad2, "Access not granted to user. %r" % rad2)
def _get_otp(self): """Internal method to get the OTP, either interactively over the commandline or by checking a mailbox (mbox). """ interactive = get_from_tconfig(['email_token', 'interactive'], required=True) mbox_filepath = get_from_tconfig(['email_token', 'mbox_filepath'], default="/var/mail/jenkins") otp = None def get_mail_delivery_date(key_mail_pair): mail = key_mail_pair[1] date_tuple = parsedate(mail['Date']) return time.mktime(date_tuple) def check_mail(): mybox = mailbox.mbox(mbox_filepath) mybox.lock() try: mbox_len = len(mybox) print "Mailbox length: %s" % (mbox_len) self.assertGreater( len(mybox), 0, "Email box must contain at least one message") newest_mail_key, newest_mail = max(mybox.iteritems(), key=get_mail_delivery_date) self.assertTrue(newest_mail is not None, "No e-mail in mbox") payload = newest_mail.get_payload() matches = re.search(r"\d{6}", payload) self.assertTrue(matches is not None, "No OTP in e-mail message %r" % newest_mail) otp = matches.group(0) mybox.remove(newest_mail_key) finally: mybox.close() mybox.unlock() return otp if interactive.lower() == 'true': otp = raw_input("OTP (check your e-mail): ") else: wait_count = 10 while wait_count: time.sleep(1) # Wait for e-mail to arrive try: otp = check_mail() except AssertionError, mailbox.ExternalClashError: if wait_count == 0: raise wait_count -= 1
def set_email_config(self): self.email_provider_config = get_from_tconfig(["email_token", "email_provider_config"]) self.email_recipient = get_from_tconfig(["email_token", "recipient"], required=True) self.email_token_pin = "1234" # Set SMTP e-mail config if self.email_provider_config: parameters = {"EmailProviderConfig": self.email_provider_config} set_config = SetConfig( self.http_protocol, self.http_host, self.http_port, 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 email_provider_config in testconfig file. Using LinOTP default."
def set_email_config(self): self.email_provider_config = get_from_tconfig( ['email_token', 'email_provider_config']) self.email_recipient = get_from_tconfig(['email_token', 'recipient'], required=True) self.email_token_pin = "1234" # Set SMTP e-mail config if self.email_provider_config: parameters = {'EmailProviderConfig': self.email_provider_config} set_config = SetConfig(self.http_protocol, self.http_host, self.http_port, 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 email_provider_config in testconfig file. Using LinOTP default."
def _get_otp(self): """Internal method to get the OTP, either interactively over the commandline or by checking a mailbox (mbox). """ interactive = get_from_tconfig(["email_token", "interactive"], required=True) mbox_filepath = get_from_tconfig(["email_token", "mbox_filepath"], default="/var/mail/jenkins") otp = None def get_mail_delivery_date(key_mail_pair): mail = key_mail_pair[1] date_tuple = parsedate(mail["Date"]) return time.mktime(date_tuple) def check_mail(): mybox = mailbox.mbox(mbox_filepath) mybox.lock() try: mbox_len = len(mybox) print "Mailbox length: %s" % (mbox_len) self.assertGreater(len(mybox), 0, "Email box must contain at least one message") newest_mail_key, newest_mail = max(mybox.iteritems(), key=get_mail_delivery_date) self.assertTrue(newest_mail is not None, "No e-mail in mbox") payload = newest_mail.get_payload() matches = re.search(r"\d{6}", payload) self.assertTrue(matches is not None, "No OTP in e-mail message %r" % newest_mail) otp = matches.group(0) mybox.remove(newest_mail_key) finally: mybox.close() mybox.unlock() return otp if interactive.lower() == "true": otp = raw_input("OTP (check your e-mail): ") else: wait_count = 10 while wait_count: time.sleep(1) # Wait for e-mail to arrive try: otp = check_mail() except AssertionError, mailbox.ExternalClashError: if wait_count == 0: raise wait_count -= 1
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))
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))
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))
def is_sms_disabled(): disable_sms = get_from_tconfig(['sms_token', 'disable'], default='False') return disable_sms.lower() == 'true'
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))
def test_radius_auth(self): def radius_auth(username, realm_name, pin, radius_secret, radius_server, state=None): call_array = "python ../../../tools/linotp-auth-radius -f ../../../test.ini".split( ) call_array.extend([ "-u", username + "@" + realm_name, "-p", pin, "-s", radius_secret, "-r", radius_server, ]) if state: call_array.extend("-t", state) logger.debug("Executing %s", " ".join(call_array)) try: return check_output(call_array) except CalledProcessError as e: assert e.returncode == 0, ( "radius auth process exit code %s. Command:%s Ouptut:%s" % (e.returncode, " ".join(e.cmd), e.output)) radius_server = get_from_tconfig( ["radius", "server"], default=self.testcase.http_host.split(":")[0], ) radius_secret = get_from_tconfig(["radius", "secret"], required=True) with EmailProviderServer(self.testcase, 20) as smtpsvc: # Authenticate with RADIUS rad1 = radius_auth( self.data["username"], self.data["realm_name"], self.data["email_token_pin"], radius_secret, radius_server, ) m = re.search(r"State:\['(\d+)'\]", rad1) assert m is not None, ( "'State' not found in linotp-auth-radius output. %r" % rad1) state = m.group(1) logger.debug("State: %s", state) otp = smtpsvc.get_otp() rad2 = radius_auth( self.data["username"], self.data["realm_name"], otp, radius_secret, radius_server, state, ) assert "Access granted to user " + self.data["username"] in rad2, ( "Access not granted to user. %r" % rad2)