Esempio n. 1
0
    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
Esempio n. 2
0
    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
Esempio n. 4
0
    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
Esempio n. 5
0
    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
Esempio n. 6
0
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
Esempio n. 7
0
    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
Esempio n. 8
0
    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
Esempio n. 9
0
    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:"))
Esempio n. 11
0
    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
Esempio n. 13
0
    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
Esempio n. 14
0
    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
Esempio n. 15
0
    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
Esempio n. 16
0
    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
Esempio n. 17
0
    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
Esempio n. 18
0
    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
Esempio n. 19
0
    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
Esempio n. 20
0
    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
Esempio n. 21
0
    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
Esempio n. 22
0
    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
Esempio n. 23
0
        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
Esempio n. 24
0
    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
Esempio n. 25
0
    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
Esempio n. 26
0
    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
Esempio n. 27
0
    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
        
Esempio n. 28
0
    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
Esempio n. 30
0
    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
Esempio n. 31
0
    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
Esempio n. 32
0
    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
Esempio n. 33
0
    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
Esempio n. 34
0
    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
Esempio n. 35
0
    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])
Esempio n. 37
0
    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
Esempio n. 38
0
    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
Esempio n. 39
0
    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
Esempio n. 40
0
    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
Esempio n. 41
0
    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
Esempio n. 42
0
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)
Esempio n. 43
0
    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")
Esempio n. 45
0
    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
Esempio n. 46
0
    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")
Esempio n. 47
0
    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
Esempio n. 48
0
 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
Esempio n. 49
0
    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
Esempio n. 50
0
    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
Esempio n. 51
0
    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
Esempio n. 52
0
    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
Esempio n. 53
0
    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
Esempio n. 54
0
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
Esempio n. 55
0
    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
Esempio n. 56
0
    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
Esempio n. 57
0
 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