def parameters(cls): """ Return a dictionary, that describes the parameters and options for the Firebase Provider Parameters are required keys to values. :return: dict """ params = {"options_allowed": False, "headers_allowed": False, "parameters": { FIREBASE_CONFIG.REGISTRATION_URL: { "required": True, "description": _('The URL the Push App should contact in the second enrollment step.' ' Usually it is the endpoint /ttype/push of the privacyIDEA server.')}, FIREBASE_CONFIG.TTL: { "required": True, "description": _('The second enrollment step must be completed within this time (in minutes).') }, FIREBASE_CONFIG.PROJECT_ID: { "required": True, "description": _("The project ID, that the client should use. Get it from your Firebase console.") }, FIREBASE_CONFIG.PROJECT_NUMBER: { "required": True, "description": _( "The project number, that the client should use. Get it from your Firebase console.") }, FIREBASE_CONFIG.APP_ID: { "required": False, "description": _( "The App ID, that the Android client should use. Get it from your Firebase console.") }, FIREBASE_CONFIG.API_KEY: { "required": False, "description": _( "The API Key, that the Android client should use. Get it from your Firebase console.") }, FIREBASE_CONFIG.APP_ID_IOS:{ "required": False, "description": _( "The App ID, that the iOS client should use. Get it from your Firebase console.") }, FIREBASE_CONFIG.API_KEY_IOS: { "required": False, "description": _( "The API Key, that the iOS client should use. Get it from your Firebase console.") }, FIREBASE_CONFIG.JSON_CONFIG: { "required": True, "description": _("The filename of the JSON config file, that allows privacyIDEA to talk" " to the Firebase REST API.") }, FIREBASE_CONFIG.HTTPS_PROXY: { "required": False, "description": _("Proxy setting for HTTPS connections to googleapis.com.") } } } return params
def get_class_info(key=None, ret='all'): """ returns all or a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype : s.o. """ res = { 'type': 'sms', 'title': _('SMS Token'), 'description': _('SMS: Send a One Time Password to the users mobile ' 'phone.'), 'user': ['enroll'], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin", "user"], 'policy': { SCOPE.AUTH: { SMSACTION.SMSTEXT: { 'type': 'str', 'desc': _('The text that will be send via SMS for' ' an SMS token. Use <otp> and <serial> ' 'as parameters.') }, SMSACTION.SMSAUTO: { 'type': 'bool', 'desc': _('If set, a new SMS OTP will be sent ' 'after successful authentication with ' 'one SMS OTP.') }, ACTION.CHALLENGETEXT: { 'type': 'str', 'desc': _('Use an alternate challenge text for telling the ' 'user to enter the code from the SMS.') } } }, } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def parameters(cls): """ Return a dictionary, that describes the parameters and options for the SMS provider. Parameters are required keys to values. :return: dict """ params = { "options_allowed": False, "parameters": { "script": { "required": True, "description": _("The script in script directory PI_SCRIPT_SMSPROVIDER_DIRECTORY to call. " "Expects phone as the parameter and the message from stdin." ) }, "background": { "required": True, "description": _("Wait for script to complete or run script in background. This will " "either return the HTTP request early or could also block the request." ), "values": [SCRIPT_BACKGROUND, SCRIPT_WAIT] } } } return params
def actions(cls): """ This method returns a dictionary of allowed actions and possible options in this handler module. :return: dict with actions """ actions = {"increase_counter": { "counter_name": { "type": "str", "description": _("The identifier/key of the counter.")} }, "decrease_counter": { "counter_name": { "type": "str", "description": _("The identifier/key of the counter.")}, 'allow_negative_values': { "type": "bool", "description": _("Don't stop counter if it reaches zero.")} }, "reset_counter": { "counter_name": { "type": "str", "description": _("The identifier/key of the counter.")} }} return actions
def get_class_info(key=None, ret='all'): """ returns all or a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype : s.o. """ res = { 'type': 'email', 'title': _('EMail Token'), 'description': _('EMail: Send a One Time Password to the users email ' 'address.'), 'user': ['enroll'], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin", "user"], 'policy': { SCOPE.AUTH: { EMAILACTION.EMAILTEXT: { 'type': 'str', 'desc': _('The text that will be send via EMail for' ' an EMail token. Use <otp> and <serial> ' 'as parameters.') }, EMAILACTION.EMAILSUBJECT: { 'type': 'str', 'desc': _('The subject of the EMail for' ' an EMail token. Use <otp> and <serial> ' 'as parameters.') }, EMAILACTION.EMAILAUTO: { 'type': 'bool', 'desc': _('If set, a new EMail OTP will be sent ' 'after successful authentication with ' 'one EMail OTP.') }, } } } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def verify_auth_token(auth_token, required_role=None): """ Check if a given auth token is valid. Return a dictionary describing the authenticated user. :param auth_token: The Auth Token :param required_role: list of "user" and "admin" :return: dict with authtype, realm, rights, role, username, exp, nonce """ if required_role is None: required_role = ["admin", "user"] if auth_token is None: raise AuthError(_("Authentication failure. Missing Authorization header."), id=ERROR.AUTHENTICATE_AUTH_HEADER) try: r = jwt.decode(auth_token, current_app.secret_key) except jwt.DecodeError as err: raise AuthError(_("Authentication failure. Error during decoding your token: {0!s}").format(err), id=ERROR.AUTHENTICATE_DECODING_ERROR) except jwt.ExpiredSignature as err: raise AuthError(_("Authentication failure. Your token has expired: {0!s}").format(err), id=ERROR.AUTHENTICATE_TOKEN_EXPIRED) if required_role and r.get("role") not in required_role: # If we require a certain role like "admin", but the users role does # not match raise AuthError(_("Authentication failure. " "You do not have the necessary role ({0!s}) to access " "this resource!").format(required_role), id=ERROR.AUTHENTICATE_MISSING_RIGHT) return r
def actions(cls): """ This method returns a dictionary of allowed actions and possible options in this handler module. :return: dict with actions """ actions = { "increase_counter": { "counter_name": { "type": "str", "description": _("The identifier/key of the counter.") } }, "decrease_counter": { "counter_name": { "type": "str", "description": _("The identifier/key of the counter.") }, 'allow_negative_values': { "type": "bool", "description": _("Don't stop counter if it reaches zero.") } }, "reset_counter": { "counter_name": { "type": "str", "description": _("The identifier/key of the counter.") } } } return actions
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict or scalar """ res = {'type': 'u2f', 'title': 'U2F Token', 'description': 'U2F: Enroll a U2F token.', 'init': {}, 'config': {}, 'user': ['enroll'], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin", "user"], 'policy': { SCOPE.AUTH: { U2FACTION.FACETS: { 'type': 'str', 'desc': _("This is a list of FQDN hostnames " "trusting the registered U2F tokens.")}, ACTION.CHALLENGETEXT: { 'type': 'str', 'desc': _('Use an alternate challenge text for telling the ' 'user to confirm with his U2F device.') } }, SCOPE.AUTHZ: { U2FACTION.REQ: { 'type': 'str', 'desc': _("Only specified U2F tokens are " "authorized.") } }, SCOPE.ENROLL: { U2FACTION.REQ: { 'type': 'str', 'desc': _("Only specified U2F tokens are allowed " "to be registered."), 'group': GROUP.TOKEN}, U2FACTION.NO_VERIFY_CERT: { 'type': 'bool', 'desc': _("Do not verify the U2F attestation certificate."), 'group': GROUP.TOKEN } } } } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict or scalar """ res = {'type': 'u2f', 'title': 'U2F Token', 'description': 'U2F: Enroll a U2F token.', 'init': {}, 'config': {}, 'user': ['enroll'], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin", "user"], 'policy': { SCOPE.AUTH: { U2FACTION.FACETS: { 'type': 'str', 'desc': _("This is a list of FQDN hostnames " "trusting the registered U2F tokens.")}, ACTION.CHALLENGETEXT: { 'type': 'str', 'desc': _('Use an alternate challenge text for telling the ' 'user to confirm with his U2F device.') } }, SCOPE.AUTHZ: { U2FACTION.REQ: { 'type': 'str', 'desc': _("Only specified U2F tokens are " "authorized.") } }, SCOPE.ENROLL: { U2FACTION.REQ: { 'type': 'str', 'desc': _("Only specified U2F tokens are allowed " "to be registered."), 'group': GROUP.TOKEN}, U2FACTION.NO_VERIFY_CERT: { 'type': 'bool', 'desc': _("Do not verify the U2F attestation certificate."), 'group': GROUP.TOKEN } } } } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def test_19_emailtext(self): # create a EMAILTEXT policy: p = set_policy(name="emailtext", action="{0!s}={1!s}".format(EMAILACTION.EMAILTEXT, "'Your <otp>'"), scope=SCOPE.AUTH) self.assertTrue(p > 0) g = FakeFlaskG() P = PolicyClass() g.policy_object = P options = {"g": g} smtpmock.setdata(response={"*****@*****.**": (200, "OK")}) transactionid = "123456098713" db_token = Token.query.filter_by(serial=self.serial1).first() token = EmailTokenClass(db_token) c = token.create_challenge(transactionid, options=options) self.assertTrue(c[0], c) display_message = c[1] self.assertTrue(c[3].get("state"), transactionid) self.assertEqual(display_message, _("Enter the OTP from the Email:")) _n, mimetype = token._get_email_text_or_subject(options, EMAILACTION.EMAILTEXT) self.assertEqual(mimetype, "plain") # Test AUTOEMAIL p = set_policy(name="autoemail", action=EMAILACTION.EMAILAUTO, scope=SCOPE.AUTH) self.assertTrue(p > 0) g = FakeFlaskG() P = PolicyClass() g.policy_object = P options = {"g": g} r = token.check_otp("287922", options=options) self.assertTrue(r > 0, r) # create a EMAILTEXT policy with template p = set_policy(name="emailtext", action="{0!s}=file:{1!s}".format(EMAILACTION.EMAILTEXT, TEMPLATE_FILE), scope=SCOPE.AUTH) self.assertTrue(p > 0) g = FakeFlaskG() P = PolicyClass() g.policy_object = P options = {"g": g} smtpmock.setdata(response={"*****@*****.**": (200, "OK")}) transactionid = "123456098714" db_token = Token.query.filter_by(serial=self.serial1).first() token = EmailTokenClass(db_token) email_text, mimetype = token._get_email_text_or_subject(options, EMAILACTION.EMAILTEXT) self.assertTrue("<p>Hello,</p>" in email_text) self.assertEqual(mimetype, "html") c = token.create_challenge(transactionid, options=options) self.assertTrue(c[0], c) display_message = c[1] self.assertTrue(c[3].get("state"), transactionid) self.assertEqual(display_message, _("Enter the OTP from the Email:"))
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict or scalar """ res = { 'type': 'paper', 'title': 'Paper Token', 'description': 'PPR: One Time Passwords printed on a sheet ' 'of paper.', 'init': {}, 'config': {}, 'user': ['enroll'], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin", "user"], 'policy': { SCOPE.ENROLL: { PAPERACTION.PAPERTOKEN_COUNT: { "type": "int", "desc": _("The number of OTP values, which are " "printed on the paper.") }, ACTION.MAXTOKENUSER: { 'type': 'int', 'desc': _("The user may only have this maximum number of paper tokens assigned." ), 'group': GROUP.TOKEN }, ACTION.MAXACTIVETOKENUSER: { 'type': 'int', 'desc': _("The user may only have this maximum number of active paper tokens assigned." ), 'group': GROUP.TOKEN } } } } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def actions(cls): """ This method returns a dictionary of allowed actions and possible options in this handler module. :return: dict with actions """ actions = { ACTION_TYPE.SET_CUSTOM_USER_ATTRIBUTES: { "user": { 'type': 'str', 'required': True, 'description': _('The user for whom the custom attribute should be set.'), "value": [ USER_TYPE.TOKENOWNER, USER_TYPE.LOGGED_IN_USER, ] }, "attrkey": { 'type': 'str', 'description': _('The key of the custom user attribute that should be set.' ) }, "attrvalue": { 'type': 'str', 'description': _('The value of the custom user attribute.') } }, ACTION_TYPE.DELETE_CUSTOM_USER_ATTRIBUTES: { "user": { 'type': 'str', 'required': True, 'description': _('The user from which the custom attribute should be deleted.' ), "value": [ USER_TYPE.TOKENOWNER, USER_TYPE.LOGGED_IN_USER, ] }, "attrkey": { 'type': 'str', 'description': _('The key of the custom user attribute that should be deleted.' ) } } } return actions
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict or scalar """ res = { 'type': 'pw', 'title': 'Password Token', 'description': _('A token with a fixed password. Can be ' 'combined with the OTP PIN. Is used for the ' 'lost token scenario.'), 'init': {}, 'config': {}, 'user': [], # This tokentype is enrollable in the UI for... 'ui_enroll': [], 'policy': { SCOPE.ENROLL: { ACTION.MAXTOKENUSER: { 'type': 'int', 'desc': _("The user may only have this maximum number of password tokens assigned." ), 'group': GROUP.TOKEN }, ACTION.MAXACTIVETOKENUSER: { 'type': 'int', 'desc': _("The user may only have this maximum number of active password tokens assigned." ), 'group': GROUP.TOKEN } } }, } # I don't think we need to define the lost token policies here... if key: ret = res.get(key) else: if ret == 'all': ret = res return ret
def get_init_detail(self, params=None, user=None): """ to complete the token initialization some additional details should be returned, which are displayed at the end of the token initialization. This is the e.g. the enrollment URL for a Google Authenticator. """ response_detail = TokenClass.get_init_detail(self, params, user) params = params or {} tokenlabel = params.get("tokenlabel", "<s>") tokenissuer = params.get("tokenissuer", "privacyIDEA") # If the init_details contain an OTP key the OTP key # should be displayed as an enrollment URL otpkey = self.init_details.get('otpkey') if otpkey: tok_type = self.type.lower() if user is not None: try: goo_url = cr_google(key=otpkey, user=user.login, realm=user.realm, tokentype=tok_type.lower(), serial=self.get_serial(), tokenlabel=tokenlabel, hash_algo=params.get( "hashlib", "sha1"), digits=params.get("otplen", 6), period=params.get("timeStep", 30), issuer=tokenissuer, user_obj=user) response_detail["googleurl"] = { "description": _("URL for google " "Authenticator"), "value": goo_url, "img": create_img(goo_url, width=250) } oath_url = cr_oath(otpkey=otpkey, user=user.login, realm=user.realm, type=tok_type, serial=self.get_serial(), tokenlabel=tokenlabel) response_detail["oathurl"] = { "description": _("URL for" " OATH " "token"), "value": oath_url, "img": create_img(oath_url, width=250) } except Exception as ex: # pragma: no cover log.error("{0!s}".format((traceback.format_exc()))) log.error( 'failed to set oath or google url: {0!r}'.format(ex)) return response_detail
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict or scalar """ res = { 'type': 'registration', 'title': 'Registration Code Token', 'description': _('Registration: A token that creates a ' 'registration code that ' 'can be used as a second factor once.'), 'init': {}, 'config': {}, 'user': [], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin"], 'policy': { SCOPE.ENROLL: { ACTION.MAXTOKENUSER: { 'type': 'int', 'desc': _("The user may only have this maximum number of registration tokens assigned." ), 'group': GROUP.TOKEN }, ACTION.MAXACTIVETOKENUSER: { 'type': 'int', 'desc': _("The user may only have this maximum number of active registration tokens assigned." ), 'group': GROUP.TOKEN } } }, } if key: ret = res.get(key) else: if ret == 'all': ret = res return ret
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict or scalar """ res = { 'type': 'u2f', 'title': 'U2F Token', 'description': 'U2F: Enroll a U2F token.', 'init': {}, 'config': {}, 'user': ['enroll'], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin", "user"], 'policy': { SCOPE.AUTH: { U2FACTION.FACETS: { 'type': 'str', 'desc': _("This is a list of FQDN hostnames " "trusting the registered U2F tokens.") } }, SCOPE.AUTHZ: { U2FACTION.REQ: { 'type': 'str', 'desc': _("Only specified U2F tokens are " "authorized.") } }, SCOPE.ENROLL: { U2FACTION.REQ: { 'type': 'str', 'desc': _("Only specified U2F tokens are allowed " "to be registered.") } } } } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def parameters(cls): """ Return a dictionary, that describes the parameters and options for the SMS provider. Parameters are required keys to values. :return: dict """ params = {"options_allowed": False, "parameters": { "SMSC_HOST": { "required": True, "description": _("SMSC Host IP")}, "SMSC_PORT": { "required": True, "description": _("SMSC Port")}, "SYSTEM_ID": { "description": _("SMSC Service ID")}, "PASSWORD": { "description": _("Password for authentication on SMSC")}, "S_ADDR_TON": { "description": _("SOURCE_ADDR_TON Special Flag")}, "S_ADDR_NPI": { "description": _("S_ADDR_NPI Special Flag")}, "S_ADDR": { "description": _("Source address (SMS sender)")}, "D_ADDR_TON": {"description": _("DESTINATION_ADDR_TON Special Flag")}, "D_ADDR_NPI": {"description": _("D_ADDR_NPI Special Flag")} } } return params
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: s.o. """ res = { 'type': 'yubikey', 'title': 'Yubikey in AES mode', 'description': _('Yubikey AES mode: One Time Passwords with ' 'Yubikey.'), 'user': ['enroll'], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin", "user"], 'policy': { SCOPE.ENROLL: { ACTION.MAXTOKENUSER: { 'type': 'int', 'desc': _("The user may only have this maximum number of Yubikey tokens assigned." ), 'group': GROUP.TOKEN }, ACTION.MAXACTIVETOKENUSER: { 'type': 'int', 'desc': _("The user may only have this maximum number of active Yubikey tokens assigned." ), 'group': GROUP.TOKEN } } } } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def get_init_detail(self, params=None, user=None): """ to complete the token initialization some additional details should be returned, which are displayed at the end of the token initialization. This is the e.g. the enrollment URL for a Google Authenticator. """ response_detail = TokenClass.get_init_detail(self, params, user) params = params or {} tokenlabel = params.get("tokenlabel", "<s>") tokenissuer = params.get("tokenissuer", "privacyIDEA") # If the init_details contain an OTP key the OTP key # should be displayed as an enrollment URL otpkey = self.init_details.get('otpkey') if otpkey: tok_type = self.type.lower() if user is not None: try: goo_url = cr_google(key=otpkey, user=user.login, realm=user.realm, tokentype=tok_type.lower(), serial=self.get_serial(), tokenlabel=tokenlabel, hash_algo=params.get("hashlib", "sha1"), digits=params.get("otplen", 6), period=params.get("timeStep", 30), issuer=tokenissuer, user_obj=user) response_detail["googleurl"] = {"description": _("URL for google " "Authenticator"), "value": goo_url, "img": create_img(goo_url, width=250) } oath_url = cr_oath(otpkey=otpkey, user=user.login, realm=user.realm, type=tok_type, serial=self.get_serial(), tokenlabel=tokenlabel) response_detail["oathurl"] = {"description": _("URL for" " OATH " "token"), "value": oath_url, "img": create_img(oath_url, width=250) } except Exception as ex: # pragma: no cover log.error("{0!s}".format((traceback.format_exc()))) log.error('failed to set oath or google url: {0!r}'.format(ex)) return response_detail
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict or scalar """ res = { 'type': '4eyes', 'title': '4Eyes Token', 'description': _('4Eyes Token: Use tokens of two or more users ' 'to authenticate'), 'init': {}, 'config': {}, 'user': [], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin"], 'policy': { SCOPE.ENROLL: { ACTION.MAXTOKENUSER: { 'type': 'int', 'desc': _("The user may only have this maximum number of 4eyes tokens assigned." ), 'group': GROUP.TOKEN }, ACTION.MAXACTIVETOKENUSER: { 'type': 'int', 'desc': _("The user may only have this maximum number of active 4eyes tokens assigned." ), 'group': GROUP.TOKEN } } }, } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition Is used by lib.token.get_token_info :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict """ res = { 'type': 'spass', 'title': 'Simple Pass Token', 'description': _('SPass: Simple Pass token. Static passwords.'), 'config': {}, 'user': ['enroll'], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin", "user"], # SPASS token can have specific PIN policies in the scopes # admin and user 'pin_scopes': [SCOPE.ADMIN, SCOPE.USER], 'policy': { SCOPE.ENROLL: { ACTION.MAXTOKENUSER: { 'type': 'int', 'desc': _("The user may only have this maximum number of SPASS tokens assigned." ), 'group': GROUP.TOKEN }, ACTION.MAXACTIVETOKENUSER: { 'type': 'int', 'desc': _("The user may only have this maximum number of active SPASS tokens assigned." ), 'group': GROUP.TOKEN } } } } # do we need to define the lost token policies here... if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict or string """ res = { 'type': 'radius', 'title': 'RADIUS Token', 'description': _('RADIUS: Forward authentication request to a ' 'RADIUS server.'), 'user': ['enroll'], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin", "user"], 'policy': { SCOPE.ENROLL: { ACTION.MAXTOKENUSER: { 'type': 'int', 'desc': _("The user may only have this maximum number of RADIUS tokens assigned." ), 'group': GROUP.TOKEN }, ACTION.MAXACTIVETOKENUSER: { 'type': 'int', 'desc': _("The user may only have this maximum number of active RADIUS tokens assigned." ), 'group': GROUP.TOKEN } } }, } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def check_user_or_serial_in_request_wrapper(*args, **kwds): user = self.request.all_data.get("user", "").strip() serial = self.request.all_data.get("serial", "").strip() if not serial and not user: raise ParameterError(_("You need to specify a serial or a user.")) if "*" in serial: raise ParameterError(_("Invalid serial number.")) if "%" in user: raise ParameterError(_("Invalid user.")) f_result = func(*args, **kwds) return f_result
def actions(cls): """ This method returns a dictionary of allowed actions and possible options in this handler module. :return: dict with actions """ pi_servers = [x.config.identifier for x in get_privacyideaservers()] actions = { ACTION_TYPE.FORWARD: { "privacyIDEA": { "type": "str", "required": True, "value": pi_servers, "description": _("The remote/child privacyIDEA " "Server.") }, "realm": { "type": "str", "description": _("Change the realm name to a " "realm on the child privacyIDEA " "system.") }, "resolver": { "type": "str", "description": _("Change the resolver name to a " "resolver on the child " "privacyIDEA system.") }, "forward_client_ip": { "type": "bool", "description": _("Forward the client IP to the " "child privacyIDEA server. " "Otherwise this server will " "be the client.") }, "forward_authorization_token": { "type": "bool", "description": _("Forward the authorization header. " "This allows to also forward request like " "token- and system-requests.") } } } return actions
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition Is used by lib.token.get_token_info :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict """ desc_self1 = _('Specify the hashlib to be used. ' 'Can be sha1 (1) or sha2-256 (2).') desc_self2 = _('Specify the otplen to be used. Can be 6 or 8 digits.') res = {'type': 'hotp', 'title': 'HOTP Event Token', 'description': _('HOTP: Event based One Time Passwords.'), 'user': ['enroll'], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin", "user"], 'policy': { SCOPE.ENROLL: { 'yubikey_access_code': { 'type': 'str', 'desc': _("The Yubikey access code used to initialize Yubikeys.") } }, SCOPE.USER: { 'hotp_hashlib': {'type': 'str', 'value': ["sha1", "sha256", "sha512"], 'desc': desc_self1}, 'hotp_otplen': {'type': 'int', 'value': [6, 8], 'desc': desc_self2}, 'hotp_force_server_generate': {'type': 'bool', 'desc': _("Force the key to " "be generated on " "the server.")} } } } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def actions(cls): """ This method returns a dictionary of allowed actions and possible options in this handler module. :return: dict with actions """ scripts = os.listdir(cls.script_directory) actions = {} for script in scripts: actions[script] = { "serial": { "type": "bool", "description": _("Add '--serial <serial number>' as script " "parameter.") }, "user": { "type": "bool", "description": _("Add '--user <username>' as script " "parameter.") }, "realm": { "type": "bool", "description": _("Add '--realm <realm>' as script " "parameter.") }, "logged_in_user": { "type": "bool", "description": _("Add the username of the logged in user " "as script parameter like " "'--logged_in_user <username>'.") }, "logged_in_role": { "type": "bool", "description": _("Add the role (either admin or user) of " "the logged in user as script parameter " "like '--logged_in_role <role>'.") } } return actions
def parameters(cls): """ Return a dictionary, that describes the parameters and options for the Firebase Provider Parameters are required keys to values. :return: dict """ params = {"options_allowed": False, "parameters": { FIREBASE_CONFIG.REGISTRATION_URL: { "required": True, "description": _('The URL the Push App should contact in the second enrollment step.' ' Usually it is the endpoint /ttype/push of the privacyIDEA server.')}, FIREBASE_CONFIG.TTL: { "required": True, "description": _('The second enrollment step must be completed within this time (in minutes).') }, FIREBASE_CONFIG.PROJECT_ID: { "required": True, "description": _("The project ID, that the client should use. Get it from your Firebase console.") }, FIREBASE_CONFIG.PROJECT_NUMBER: { "required": True, "description": _( "The project number, that the client should use. Get it from your Firebase console.") }, FIREBASE_CONFIG.APP_ID: { "required": False, "description": _( "The App ID, that the Android client should use. Get it from your Firebase console.") }, FIREBASE_CONFIG.API_KEY: { "required": False, "description": _( "The API Key, that the Android client should use. Get it from your Firebase console.") }, FIREBASE_CONFIG.APP_ID_IOS:{ "required": False, "description": _( "The App ID, that the iOS client should use. Get it from your Firebase console.") }, FIREBASE_CONFIG.API_KEY_IOS: { "required": False, "description": _( "The API Key, that the iOS client should use. Get it from your Firebase console.") }, FIREBASE_CONFIG.JSON_CONFIG: { "required": True, "description": _("The filename of the JSON config file, that allows privacyIDEA to talk" " to the Firebase REST API.") } } } return params
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition Is used by lib.token.get_token_info :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict """ desc_self1 = _('Specify the hashlib to be used. ' 'Can be sha1 (1) or sha2-256 (2).') desc_self2 = _('Specify the otplen to be used. Can be 6 or 8 digits.') res = {'type': 'hotp', 'title': 'HOTP Event Token', 'description': _('HOTP: Event based One Time Passwords.'), 'user': ['enroll'], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin", "user"], 'policy': { SCOPE.ENROLL: { 'yubikey_access_code': { 'type': 'str', 'desc': _("The Yubikey access code used to initialize Yubikeys.") } }, SCOPE.USER: { 'hotp_hashlib': {'type': 'str', 'value': ["sha1", "sha256", "sha512"], 'desc': desc_self1}, 'hotp_otplen': {'type': 'int', 'value': [6, 8], 'desc': desc_self2}, 'hotp_force_server_generate': {'type': 'bool', 'desc': _("Force the key to " "be generated on " "the server.")} } } } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def get_class_info(cls, key=None, ret='all'): """ returns a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict or scalar """ res = {'type': cls.get_class_type(), 'title': 'Questionnaire Token', 'description': _('Questionnaire: Enroll Questions for the ' 'user.'), 'init': {}, 'config': {}, 'user': ['enroll'], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin", "user"], 'policy': { SCOPE.AUTH: { QUESTACTION.NUM_QUESTIONS: { 'type': 'int', 'desc': _("The user has to answer this number of questions during authentication."), 'group': GROUP.TOKEN, 'value': list(range(1, 31)) } }, SCOPE.ENROLL: { ACTION.MAXTOKENUSER: { 'type': 'int', 'desc': _("The user may only have this maximum number of questionaire tokens assigned."), 'group': GROUP.TOKEN }, ACTION.MAXACTIVETOKENUSER: { 'type': 'int', 'desc': _("The user may only have this maximum number of active questionaire tokens assigned."), 'group': GROUP.TOKEN } } }, } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def actions(cls): """ This method returns a dictionary of allowed actions and possible options in this handler module. :return: dict with actions """ actions = { ACTION_TYPE.DELETE: { "parameter": { "type": "str", "required": True, "description": _("The parameter that should be deleted.") } }, ACTION_TYPE.SET: { "parameter": { "type": "str", "required": True, "description": _("The parameter that should be added or modified.") }, "value": { "type": "str", "required": True, "description": _("The new value of the parameter. Can contain tags like {0}, {1} for " "the matched sub strings.") }, "match_parameter": { "type": "str", "description": _("The parameter, that should match some values.") }, "match_pattern": { "type": "str", "description": _("The value of the match_parameter. It can contain a regular " "expression and '()' to transfer values to the new parameter." ) } } } return actions
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict or scalar """ res = {'type': 'u2f', 'title': 'U2F Token', 'description': 'U2F: Enroll a U2F token.', 'init': {}, 'config': {}, 'user': ['enroll'], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin", "user"], 'policy': { SCOPE.AUTH: { U2FACTION.FACETS: { 'type': 'str', 'desc': _("This is a list of FQDN hostnames " "trusting the registered U2F tokens.")} }, SCOPE.AUTHZ: { U2FACTION.REQ: { 'type': 'str', 'desc': _("Only specified U2F tokens are " "authorized.") } }, SCOPE.ENROLL: { U2FACTION.REQ: { 'type': 'str', 'desc': _("Only specified U2F tokens are allowed " "to be registered.") } } } } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dictionary """ res = { 'type': 'sshkey', 'title': 'SSHkey Token', 'description': _('SSH Public Key: The public SSH key.'), 'config': {}, 'user': ['enroll'], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin", "user"], 'policy': { SCOPE.ENROLL: { ACTION.MAXTOKENUSER: { 'type': 'int', 'desc': _("The user may only have this maximum number of SSH keys assigned." ), 'group': GROUP.TOKEN }, ACTION.MAXACTIVETOKENUSER: { 'type': 'int', 'desc': _("The user may only have this maximum number of active SSH keys assigned." ), 'group': GROUP.TOKEN } } }, } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def get_class_info(key=None, ret='all'): """ returns all or a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype : s.o. """ res = {'type': 'sms', 'title': _('SMS Token'), 'description': _('SMS: Send a One Time Password to the users mobile ' 'phone.'), 'user': ['enroll'], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin", "user"], 'policy': { SCOPE.AUTH: { SMSACTION.SMSTEXT: { 'type': 'str', 'desc': _('The text that will be send via SMS for' ' an SMS token. Use <otp> and <serial> ' 'as parameters.')}, SMSACTION.SMSAUTO: { 'type': 'bool', 'desc': _('If set, a new SMS OTP will be sent ' 'after successful authentication with ' 'one SMS OTP.')}, ACTION.CHALLENGETEXT: { 'type': 'str', 'desc': _('Use an alternate challenge text for telling the ' 'user to enter the code from the SMS.') } } }, } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict or string """ res = { 'type': 'daplug', 'title': 'Daplug Event Token', 'description': _("event based OTP token using " "the HOTP algorithm"), 'policy': { SCOPE.ENROLL: { ACTION.MAXTOKENUSER: { 'type': 'int', 'desc': _("The user may only have this maximum number of daplug tokens assigned." ), 'group': GROUP.TOKEN }, ACTION.MAXACTIVETOKENUSER: { 'type': 'int', 'desc': _("The user may only have this maximum number of active daplug tokens assigned." ), 'group': GROUP.TOKEN } } } } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dictionary """ res = {'type': 'sshkey', 'title': 'SSHkey Token', 'description': _('SSH Public Key: The public SSH key.'), 'config': {}, 'user': ['enroll'], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin", "user"], 'policy': {}, } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def _test_create_token(self, user): pin = "test" token = init_token({"type": "tiqr", "pin": pin, "serial": "TIQR1"}, User(user, self.realm1)) self.assertEqual(token.type, "tiqr") prefix = TiqrTokenClass.get_class_prefix() self.assertEqual(prefix, "TiQR") info = TiqrTokenClass.get_class_info() self.assertEqual(info.get("type"), "tiqr") info = TiqrTokenClass.get_class_info("type") self.assertEqual(info, "tiqr") idetail = token.get_init_detail() self.assertTrue("TiQR" in idetail.get("tiqrenroll").get("description")) self.assertTrue("serial" in idetail, idetail) self.assertTrue("img" in idetail.get("tiqrenroll"), idetail) self.assertTrue("value" in idetail.get("tiqrenroll"), idetail) # Check the challenge request r = token.is_challenge_request(pin) self.assertEqual(r, True) r = token.is_challenge_request(pin + "123456") self.assertEqual(r, False) # Check create_challenge r = token.create_challenge() self.assertEqual(r[0], True) self.assertEqual(r[1], _("Please scan the QR Code")) self.assertTrue("img" in r[3], r[3]) self.assertTrue("value" in r[3], r[3])
def get_init_detail(self, params=None, user=None): """ This returns the init details during enrollment. In the 1st step the QR Code is returned. """ response_detail = TokenClass.get_init_detail(self, params, user) if "otpkey" in response_detail: del response_detail["otpkey"] params = params or {} user = user or User() tokenlabel = params.get("tokenlabel", "<s>") tokenissuer = params.get("tokenissuer", "privacyIDEA") sslverify = getParam(params, PUSH_ACTION.SSL_VERIFY, allowed_values=["0", "1"], default="1") # Add rollout state the response response_detail['rollout_state'] = self.token.rollout_state extra_data = {"enrollment_credential": self.get_tokeninfo("enrollment_credential")} imageurl = params.get("appimageurl") if imageurl: extra_data.update({"image": imageurl}) if self.token.rollout_state == "clientwait": # Get the values from the configured PUSH config fb_identifier = params.get(PUSH_ACTION.FIREBASE_CONFIG) firebase_configs = get_smsgateway(identifier=fb_identifier, gwtype=GWTYPE) if len(firebase_configs) != 1: raise ParameterError("Unknown Firebase configuration!") fb_options = firebase_configs[0].option_dict for k in [FIREBASE_CONFIG.PROJECT_NUMBER, FIREBASE_CONFIG.PROJECT_ID, FIREBASE_CONFIG.APP_ID, FIREBASE_CONFIG.API_KEY, FIREBASE_CONFIG.APP_ID_IOS, FIREBASE_CONFIG.API_KEY_IOS]: extra_data[k] = fb_options.get(k) # this allows to upgrade our crypto extra_data["v"] = 1 extra_data["serial"] = self.get_serial() extra_data["sslverify"] = sslverify # We display this during the first enrollment step! qr_url = create_push_token_url(url=fb_options.get(FIREBASE_CONFIG.REGISTRATION_URL), user=user.login, realm=user.realm, serial=self.get_serial(), tokenlabel=tokenlabel, issuer=tokenissuer, user_obj=user, extra_data=extra_data, ttl=fb_options.get(FIREBASE_CONFIG.TTL)) response_detail["pushurl"] = {"description": _("URL for privacyIDEA Push Token"), "value": qr_url, "img": create_img(qr_url, width=250) } self.add_tokeninfo(FIREBASE_CONFIG.PROJECT_ID, fb_options.get(FIREBASE_CONFIG.PROJECT_ID)) response_detail["enrollment_credential"] = self.get_tokeninfo("enrollment_credential") elif self.token.rollout_state == "enrolled": # in the second enrollment step we return the public key of the server to the smartphone. pubkey = strip_key(self.get_tokeninfo(PUBLIC_KEY_SERVER)) response_detail["public_key"] = pubkey return response_detail
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict or scalar """ res = {'type': 'registration', 'title': 'Registration Code Token', 'description': _('Registration: A token that creates a ' 'registration code that ' 'can be used as a second factor once.'), 'init': {}, 'config': {}, 'user': [], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin"], 'policy': {}, } if key: ret = res.get(key) else: if ret == 'all': ret = res return ret
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: s.o. """ res = {'type': 'yubikey', 'title': 'Yubikey in AES mode', 'description': _('Yubikey AES mode: One Time Passwords with ' 'Yubikey.'), 'user': ['enroll'], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin", "user"], 'policy': {} } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict or scalar """ res = {'type': 'pw', 'title': 'Password Token', 'description': _('A token with a fixed password. Can be ' 'combined with the OTP PIN. Is used for the ' 'lost token scenario.'), 'init': {}, 'config': {}, 'user': [], # This tokentype is enrollable in the UI for... 'ui_enroll': [], 'policy': {}, } # I don't think we need to define the lost token policies here... if key: ret = res.get(key) else: if ret == 'all': ret = res return ret
def get_class_info(key=None, ret='all'): """ :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict or string """ res = {'type': 'yubico', 'title': 'Yubico Token', 'description': _('Yubikey Cloud mode: Forward authentication ' 'request to YubiCloud.'), 'user': ['enroll'], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin", "user"], 'policy' : {}, } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def test_radius(identifier, server, secret, user, password, port=1812, description="", dictionary='/etc/privacyidea/dictionary', retries=3, timeout=5): """ This tests a RADIUS server configuration by sending an access request. :param identifier: The identifier or the name of the RADIUSServer definition :type identifier: basestring :param server: The FQDN or IP address of the RADIUS server :type server: basestring :param secret: The RADIUS secret :param user: the username to send :param password: the password to send :param port: the radius port :type port: int :param description: Human readable description of the RADIUS server definition :param dictionary: The RADIUS dictionary :return: The result of the access request """ cryptedSecret = encryptPassword(secret) if len(cryptedSecret) > 255: raise privacyIDEAError(description=_("The RADIUS secret is too long"), id=2234) s = RADIUSServerDB(identifier=identifier, server=server, port=port, secret=cryptedSecret, dictionary=dictionary, retries=retries, timeout=timeout, description=description) return RADIUSServer.request(s, user, password)
def get_init_detail(self, params=None, user=None): """ At the end of the initialization we ask the user to press the button """ response_detail = {} if self.init_step == 1: # This is the first step of the init request app_id = get_from_config("u2f.appId", "").strip("/") from privacyidea.lib.error import TokenAdminError if not app_id: raise TokenAdminError( _("You need to define the appId in the " "token config!")) nonce = url_encode(geturandom(32)) response_detail = TokenClass.get_init_detail(self, params, user) register_request = { "version": U2F_Version, "challenge": nonce, "appId": app_id } response_detail["u2fRegisterRequest"] = register_request self.add_tokeninfo("appId", app_id) elif self.init_step == 2: # This is the second step of the init request response_detail["u2fRegisterResponse"] = { "subject": self.token.description } return response_detail
def test_01_challenge(self): set_policy("chalresp", scope=SCOPE.AUTHZ, action="{0!s}=hotp".format(ACTION.CHALLENGERESPONSE)) token = init_token({"genkey": 1, "serial": "CHAL1", "pin": "pin"}) from privacyidea.lib.token import check_serial_pass r = check_serial_pass(token.token.serial, "pin") # The OTP PIN is correct self.assertEqual(r[0], False) self.assertEqual(r[1].get("message"), _("please enter otp: ")) transaction_id = r[1].get("transaction_id") chals = get_challenges() self.assertEqual(len(chals), 1) self.assertEqual(chals[0].transaction_id, transaction_id) # get challenge for this serial chals = get_challenges(serial="CHAL1") self.assertEqual(len(chals), 1) self.assertEqual(chals[0].transaction_id, transaction_id) # get challenge for another seial chals = get_challenges(serial="CHAL2") self.assertEqual(len(chals), 0) delete_policy("chalresp")
def get_class_info(key=None, ret='all'): """ :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict or string """ res = {'type': 'vasco', 'title': 'VASCO Token', 'description': _('VASCO Token: Authentication using VASCO tokens'), # If this was set, the user could enroll a Vasco token via the API #'user': ["enroll"], # only administrators can enroll the token in the UI 'ui_enroll': ["admin"], 'policy': {}, } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def test_01_challenge(self): set_policy("chalresp", scope=SCOPE.AUTHZ, action="{0!s}=hotp".format(ACTION.CHALLENGERESPONSE)) token = init_token({"genkey": 1, "serial": "CHAL1", "pin": "pin"}) from privacyidea.lib.token import check_serial_pass r = check_serial_pass(token.token.serial, "pin") # The OTP PIN is correct self.assertEqual(r[0], False) self.assertEqual(r[1].get("message"), _("please enter otp: ")) transaction_id = r[1].get("transaction_id") chals = get_challenges() self.assertEqual(len(chals), 1) self.assertEqual(chals[0].transaction_id, transaction_id) # get challenge for this serial chals = get_challenges(serial="CHAL1") self.assertEqual(len(chals), 1) self.assertEqual(chals[0].transaction_id, transaction_id) # get challenge for another seial chals = get_challenges(serial="CHAL2") self.assertEqual(len(chals), 0) delete_policy("chalresp")
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict or scalar """ res = {'type': 'certificate', 'title': 'Certificate Token', 'description': _('Certificate: Enroll an x509 Certificate ' 'Token.'), 'init': {}, 'config': {}, 'user': ['enroll'], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin", "user"], 'policy': {}, } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def get_init_detail(self, params=None, user=None): """ to complete the token normalisation, the response of the initialization should be build by the token specific method, the getInitDetails """ response_detail = TokenClass.get_init_detail(self, params, user) otpkey = self.init_details.get('otpkey') if otpkey: tok_type = self.type.lower() if user is not None: try: motp_url = create_motp_url(otpkey, user.login, user.realm, serial=self.get_serial()) response_detail["motpurl"] = {"description": _("URL for MOTP " "token"), "value": motp_url, "img": create_img(motp_url, width=250) } except Exception as ex: # pragma: no cover log.debug("{0!s}".format(traceback.format_exc())) log.error('failed to set motp url: {0!r}'.format(ex)) return response_detail
def get_init_detail(self, params=None, user=None): """ At the end of the initialization we ask the user to press the button """ response_detail = {} if self.init_step == 1: # This is the first step of the init request app_id = get_from_config("u2f.appId", "").strip("/") from privacyidea.lib.error import TokenAdminError if not app_id: raise TokenAdminError(_("You need to define the appId in the " "token config!")) nonce = urlsafe_b64encode_and_unicode(geturandom(32)) response_detail = TokenClass.get_init_detail(self, params, user) register_request = {"version": U2F_Version, "challenge": nonce, "appId": app_id} response_detail["u2fRegisterRequest"] = register_request self.add_tokeninfo("appId", app_id) elif self.init_step == 2: # This is the second step of the init request response_detail["u2fRegisterResponse"] = {"subject": self.token.description} return response_detail
def get_class_info(key=None, ret='all'): """ :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict or string """ res = { 'type': 'remote', 'title': 'Remote Token', 'description': _('Remote Token: Forward authentication request ' 'to another server.'), 'user': [], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin"], 'policy': {}, } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict or string """ res = {'type': 'radius', 'title': 'RADIUS Token', 'description': _('RADIUS: Forward authentication request to a ' 'RADIUS server.'), 'user': ['enroll'], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin", "user"], 'policy': {}, } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict or string """ res = {'type': 'daplug', 'title': 'Daplug Event Token', 'description': _("event based OTP token using " "the HOTP algorithm"), } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict or scalar """ res = {'type': '4eyes', 'title': '4Eyes Token', 'description': _('4Eyes Token: Use tokens of two or more users ' 'to authenticate'), 'init': {}, 'config': {}, 'user': [], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin"], 'policy': {}, } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def add_radius(identifier, server, secret, port=1812, description="", dictionary='/etc/privacyidea/dictionary', retries=3, timeout=5): """ This adds a RADIUS server to the RADIUSServer database table. If the "identifier" already exists, the database entry is updated. :param identifier: The identifier or the name of the RADIUSServer definition. As the identifier is unique, providing an identifier will return a list with either one or no radius server :type identifier: basestring :param server: The FQDN or IP address of the RADIUS server :type server: basestring :param secret: The RADIUS secret :param port: the radius port :type port: int :param description: Human readable description of the RADIUS server definition :param dictionary: The RADIUS dictionary :return: The Id of the database object """ cryptedSecret = encryptPassword(secret) if len(cryptedSecret) > 255: raise privacyIDEAError(description=_("The RADIUS secret is too long"), id=2234) r = RADIUSServerDB(identifier=identifier, server=server, port=port, secret=cryptedSecret, description=description, dictionary=dictionary, retries=retries, timeout=timeout).save() return r
def get_class_info(key=None, ret='all'): """ returns a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype: dict or scalar """ res = {'type': 'totp', 'title': 'HMAC Time Token', 'description': _('TOTP: Time based One Time Passwords.'), 'user': ['enroll'], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin", "user"], 'policy': {'user': { 'totp_timestep': {'type': 'int', 'value': [30, 60], 'desc': 'Specify the time step of ' 'the timebased OTP token.'}, 'totp_hashlib': {'type': 'str', 'value': ["sha1", "sha256", "sha512"], 'desc': 'Specify the hashlib to be used. ' 'Can be SHA1, SHA256 or SHA512.'}, 'totp_otplen': {'type': 'int', 'value': [6, 8], 'desc': "Specify the OTP length to be " "used."}, 'totp_force_server_generate': {'type': 'bool', 'desc': _("Force the key to " "be generated on " "the server.")} }, }, } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def get_class_info(key=None, ret='all'): """ returns all or a subtree of the token definition :param key: subsection identifier :type key: string :param ret: default return value, if nothing is found :type ret: user defined :return: subsection if key exists or user defined :rtype : s.o. """ res = {'type': 'email', 'title': _('EMail Token'), 'description': _('EMail: Send a One Time Password to the users email ' 'address.'), 'user': ['enroll'], # This tokentype is enrollable in the UI for... 'ui_enroll': ["admin", "user"], 'policy': {SCOPE.AUTH: { EMAILACTION.EMAILTEXT: { 'type': 'str', 'desc': _('The text that will be send via EMail for' ' an EMail token. Use <otp> and <serial> ' 'as parameters.')}, EMAILACTION.EMAILSUBJECT: { 'type': 'str', 'desc': _('The subject of the EMail for' ' an EMail token. Use <otp> and <serial> ' 'as parameters.')}, EMAILACTION.EMAILAUTO: { 'type': 'bool', 'desc': _('If set, a new EMail OTP will be sent ' 'after successful authentication with ' 'one EMail OTP.')}, } } } if key: ret = res.get(key, {}) else: if ret == 'all': ret = res return ret
def token_locked_wrapper(*args, **kwds): # The token object token = args[0] if token.is_locked(): raise TokenAdminError(_("This action is not possible, since the " "token is locked"), id=1007) f_result = func(*args, **kwds) return f_result