Example #1
0
    def _auth_push_thread(self):
        info = {"Server": self.server.name}

        platform_name = None
        if self.platform == "linux":
            platform_name = "Linux"
        elif self.platform == "mac" or self.platform == "ios":
            platform_name = "Apple"
        elif self.platform == "win":
            platform_name = "Windows"
        elif self.platform == "chrome":
            platform_name = "Chrome OS"

        if self.device_name:
            info["Device"] = "%s (%s)" % (self.device_name, platform_name)

        if self.push_type == DUO_AUTH:
            allow, _ = sso.auth_duo(self.user.name, ipaddr=self.remote_ip, type="Connection", info=info)
        elif self.push_type == SAML_OKTA_AUTH:
            allow = sso.auth_okta(self.user.name, ipaddr=self.remote_ip, type="Connection", info=info)
        else:
            raise ValueError("Unkown push auth type")

        if not allow:
            self.user.audit_event(
                "user_connection",
                ('User connection to "%s" denied. ' + "Push authentication failed") % (self.server.name),
                remote_addr=self.remote_ip,
            )
            raise AuthError("User failed push authentication")
Example #2
0
                def duo_auth():
                    info = {
                        'Server': self.server.name,
                    }

                    platform_name = None
                    if platform == 'linux':
                        platform_name = 'Linux'
                    elif platform == 'mac':
                        platform_name = 'Apple'
                    elif platform == 'win':
                        platform_name = 'Windows'
                    elif platform == 'chrome':
                        platform_name = 'Chrome OS'

                    if device_name:
                        info['Device'] = '%s (%s)' % (device_name,
                                                      platform_name)

                    allow = False
                    try:
                        allow, _ = sso.auth_duo(
                            user.name,
                            ipaddr=remote_ip,
                            type='Connection',
                            info=info,
                        )
                    except:
                        logger.exception(
                            'Duo server error',
                            'server',
                            client_id=client_id,
                            user_id=user.id,
                            username=user.name,
                            server_id=self.server.id,
                        )
                        self.instance_com.push_output(
                            'ERROR Duo server error client_id=%s' % client_id)
                    try:
                        if allow:
                            self.allow_client(client, org, user)
                        else:
                            logger.LogEntry(message='User failed duo ' +
                                            'authentication "%s".' % user.name)
                            self.instance_com.send_client_deny(
                                client_id,
                                key_id,
                                'User failed duo authentication',
                            )
                    except:
                        logger.exception(
                            'Duo auth error',
                            'server',
                            client_id=client_id,
                            user_id=user.id,
                            server_id=self.server.id,
                        )
                        self.instance_com.push_output(
                            'ERROR Duo auth error client_id=%s' % client_id)
Example #3
0
                def duo_auth():
                    info={
                        'Server': self.server.name,
                    }

                    platform_name = None
                    if platform == 'linux':
                        platform_name = 'Linux'
                    elif platform == 'mac':
                        platform_name = 'Apple'
                    elif platform == 'win':
                        platform_name = 'Windows'
                    elif platform == 'chrome':
                        platform_name = 'Chrome OS'

                    if device_name:
                        info['Device'] = '%s (%s)' % (
                            device_name, platform_name)

                    allow = False
                    try:
                        allow, _ = sso.auth_duo(
                            user.name,
                            ipaddr=remote_ip,
                            type='Connection',
                            info=info,
                        )
                    except:
                        logger.exception('Duo server error', 'server',
                            client_id=client_id,
                            user_id=user.id,
                            username=user.name,
                            server_id=self.server.id,
                        )
                        self.instance_com.push_output(
                            'ERROR Duo server error client_id=%s' % client_id)
                    try:
                        if allow:
                            self.allow_client(client, org, user)
                        else:
                            logger.LogEntry(message='User failed duo ' +
                                'authentication "%s".' % user.name)
                            self.instance_com.send_client_deny(
                                client_id,
                                key_id,
                                'User failed duo authentication',
                            )
                    except:
                        logger.exception('Duo auth error', 'server',
                            client_id=client_id,
                            user_id=user.id,
                            server_id=self.server.id,
                        )
                        self.instance_com.push_output(
                            'ERROR Duo auth error client_id=%s' % client_id)
Example #4
0
    def auth_check(self, password, otp_code=None, remote_addr=None):
        if not self.test_password(password):
            self.audit_event(
                'admin_auth',
                'Administrator login failed, invalid password',
                remote_addr=remote_addr,
            )
            return False

        if self.otp_auth and not self.verify_otp_code(otp_code):
            self.audit_event(
                'admin_auth',
                'Administrator login failed, ' +
                    'invalid two-factor authentication code',
                remote_addr=remote_addr,
            )
            return False

        if self.disabled:
            self.audit_event(
                'admin_auth',
                'Administrator login failed, administrator is disabled',
                remote_addr=remote_addr,
            )
            return False

        sso_admin = settings.app.sso_admin
        if settings.app.sso and DUO_AUTH in settings.app.sso and sso_admin:
            allow, _ = sso.auth_duo(
                sso_admin,
                strong=True,
                ipaddr=remote_addr,
                type='Administrator'
            )
            if not allow:
                self.audit_event(
                    'admin_auth',
                    'Administrator login failed, ' +
                        'failed secondary authentication',
                    remote_addr=remote_addr,
                )
                return False

        self.audit_event(
            'admin_auth',
            'Administrator login successful',
            remote_addr=remote_addr,
        )

        return True
Example #5
0
    def auth_check(self, password, otp_code=None, remote_addr=None):
        if not self.test_password(password):
            self.audit_event(
                'admin_auth',
                'Administrator login failed, invalid password',
                remote_addr=remote_addr,
            )
            return False

        if self.otp_auth and not self.verify_otp_code(otp_code):
            self.audit_event(
                'admin_auth',
                'Administrator login failed, ' +
                'invalid two-factor authentication code',
                remote_addr=remote_addr,
            )
            return False

        if self.disabled:
            self.audit_event(
                'admin_auth',
                'Administrator login failed, administrator is disabled',
                remote_addr=remote_addr,
            )
            return False

        sso_admin = settings.app.sso_admin
        if settings.app.sso and DUO_AUTH in settings.app.sso and sso_admin:
            allow, _ = sso.auth_duo(sso_admin,
                                    strong=True,
                                    ipaddr=remote_addr,
                                    type='Administrator')
            if not allow:
                self.audit_event(
                    'admin_auth',
                    'Administrator login failed, ' +
                    'failed secondary authentication',
                    remote_addr=remote_addr,
                )
                return False

        self.audit_event(
            'admin_auth',
            'Administrator login successful',
            remote_addr=remote_addr,
        )

        return True
Example #6
0
def check_auth(username, password, remote_addr=None):
    username = utils.filter_str(username).lower()

    if remote_addr:
        doc = Administrator.limiter_collection.find_and_modify(
            {
                '_id': remote_addr,
            }, {
                '$inc': {
                    'count': 1
                },
                '$setOnInsert': {
                    'timestamp': utils.now()
                },
            },
            new=True,
            upsert=True)

        if utils.now() > doc['timestamp'] + datetime.timedelta(minutes=1):
            doc = {
                'count': 1,
                'timestamp': utils.now(),
            }
            Administrator.limiter_collection.update({
                '_id': remote_addr,
            },
                                                    doc,
                                                    upsert=True)

        if doc['count'] > settings.app.auth_limiter_count_max:
            raise flask.abort(403)

    administrator = find_user(username=username)
    if not administrator:
        return
    if not administrator.test_password(password):
        return

    sso_admin = settings.app.sso_admin
    if settings.app.sso and DUO_AUTH in settings.app.sso and sso_admin:
        allow, _ = sso.auth_duo(sso_admin,
                                strong=True,
                                ipaddr=remote_addr,
                                type='Administrator')
        if not allow:
            return

    return administrator
Example #7
0
def sso_authenticate_post():
    if settings.app.sso != DUO_AUTH:
        return flask.abort(405)

    username = flask.request.json['username']
    usernames = [username]
    if '@' in username:
        usernames.append(username.split('@')[0])

    valid = False
    for username in usernames:
        try:
            valid, org_id = sso.auth_duo(
                username,
                strong=True,
                ipaddr=flask.request.remote_addr,
                type='Key',
            )
        except InvalidUser:
            pass

    if not valid:
        return flask.abort(401)

    if not org_id:
        org_id = settings.app.sso_org

    org = organization.get_by_id(org_id)
    if not org:
        return flask.abort(405)

    usr = org.find_user(name=username)
    if not usr:
        usr = org.new_user(name=username, type=CERT_CLIENT,
            auth_type=DUO_AUTH)
        event.Event(type=ORGS_UPDATED)
        event.Event(type=USERS_UPDATED, resource_id=org.id)
        event.Event(type=SERVERS_UPDATED)
    elif usr.auth_type != DUO_AUTH:
        usr.auth_type = DUO_AUTH
        usr.commit('auth_type')

    key_link = org.create_user_key_link(usr.id, one_time=True)

    return flask.request.url_root[:-1] + key_link['view_url']
Example #8
0
    def _auth_push_thread(self):
        info={
            'Server': self.server.name,
        }

        platform_name = None
        if self.platform == 'linux':
            platform_name = 'Linux'
        elif self.platform == 'mac' or self.platform == 'ios':
            platform_name = 'Apple'
        elif self.platform == 'win':
            platform_name = 'Windows'
        elif self.platform == 'chrome':
            platform_name = 'Chrome OS'

        if self.device_name:
            info['Device'] = '%s (%s)' % (self.device_name, platform_name)

        if self.push_type == DUO_AUTH:
            allow, _ = sso.auth_duo(
                self.user.name,
                ipaddr=self.remote_ip,
                type='Connection',
                info=info,
            )
        elif self.push_type == SAML_OKTA_AUTH:
            allow = sso.auth_okta_push(
                self.user.name,
                ipaddr=self.remote_ip,
                type='Connection',
                info=info,
            )
        else:
            raise ValueError('Unkown push auth type')

        if not allow:
            self.user.audit_event('user_connection',
                ('User connection to "%s" denied. ' +
                 'Push authentication failed') % (
                    self.server.name),
                remote_addr=self.remote_ip,
            )
            raise AuthError('User failed push authentication')
Example #9
0
    def _auth_push_thread(self):
        info = {
            'Server': self.server.name,
        }

        platform_name = None
        if self.platform == 'linux':
            platform_name = 'Linux'
        elif self.platform == 'mac' or self.platform == 'ios':
            platform_name = 'Apple'
        elif self.platform == 'win':
            platform_name = 'Windows'
        elif self.platform == 'chrome':
            platform_name = 'Chrome OS'

        if self.device_name:
            info['Device'] = '%s (%s)' % (self.device_name, platform_name)

        if self.push_type == DUO_AUTH:
            allow, _ = sso.auth_duo(
                self.user.name,
                ipaddr=self.remote_ip,
                type='Connection',
                info=info,
            )
        elif self.push_type == SAML_OKTA_AUTH:
            allow = sso.auth_okta_push(
                self.user.name,
                ipaddr=self.remote_ip,
                type='Connection',
                info=info,
            )
        else:
            raise ValueError('Unkown push auth type')

        if not allow:
            self.user.audit_event(
                'user_connection',
                ('User connection to "%s" denied. ' +
                 'Push authentication failed') % (self.server.name),
                remote_addr=self.remote_ip,
            )
            raise AuthError('User failed push authentication')
Example #10
0
def check_auth(username, password, remote_addr=None):
    username = utils.filter_str(username).lower()

    if remote_addr:
        doc = Administrator.limiter_collection.find_and_modify({
            '_id': remote_addr,
        }, {
            '$inc': {'count': 1},
            '$setOnInsert': {'timestamp': utils.now()},
        }, new=True, upsert=True)

        if utils.now() > doc['timestamp'] + datetime.timedelta(minutes=1):
            doc = {
                'count': 1,
                'timestamp': utils.now(),
            }
            Administrator.limiter_collection.update({
                '_id': remote_addr,
            }, doc, upsert=True)

        if doc['count'] > settings.app.auth_limiter_count_max:
            raise flask.abort(403)

    administrator = find_user(username=username)
    if not administrator:
        return
    if not administrator.test_password(password):
        return

    sso_admin = settings.app.sso_admin
    if settings.app.sso and DUO_AUTH in settings.app.sso and sso_admin:
        allow, _ = sso.auth_duo(
            sso_admin,
            strong=True,
            ipaddr=remote_addr,
            type='Administrator'
        )
        if not allow:
            return

    return administrator
Example #11
0
def sso_callback_get():
    sso_mode = settings.app.sso

    if sso_mode not in (GOOGLE_AUTH, GOOGLE_DUO_AUTH, SLACK_AUTH,
            SLACK_DUO_AUTH, SAML_AUTH, SAML_DUO_AUTH, SAML_OKTA_AUTH,
            SAML_OKTA_DUO_AUTH, SAML_ONELOGIN_AUTH, SAML_ONELOGIN_DUO_AUTH):
        return flask.abort(405)

    state = flask.request.args.get('state')
    sig = flask.request.args.get('sig')

    tokens_collection = mongo.get_collection('sso_tokens')
    doc = tokens_collection.find_and_modify(query={
        '_id': state,
    }, remove=True)

    if not doc:
        return flask.abort(404)

    query = flask.request.query_string.split('&sig=')[0]
    test_sig = base64.urlsafe_b64encode(hmac.new(str(doc['secret']),
        query, hashlib.sha512).digest())

    if sig != test_sig:
        return flask.abort(401)

    params = urlparse.parse_qs(query)

    if doc.get('type') == SAML_AUTH:
        username = params.get('username')[0]
        email = params.get('email', [None])[0]
        org_name = params.get('org', [None])[0]

        if not username:
            return flask.abort(406)

        valid, org_name = sso.verify_saml(username, email, org_name)
        if not valid:
            return flask.abort(401)

        org_id = settings.app.sso_org
        if org_name:
            org = organization.get_by_name(org_name, fields=('_id'))
            if org:
                org_id = org.id
    elif doc.get('type') == SLACK_AUTH:
        username = params.get('username')[0]
        email = None
        user_team = params.get('team')[0]
        org_names = params.get('orgs', [''])[0]
        org_names = org_names.split(',')

        valid, org_name = sso.verify_slack(username, user_team, org_names)
        if not valid:
            return flask.abort(401)

        if org_name:
            org_names = [org_name]

        org_id = settings.app.sso_org
        for org_name in org_names:
            org = organization.get_by_name(org_name, fields=('_id'))
            if org:
                org_id = org.id
                break
    else:
        username = params.get('username')[0]
        email = username

        valid, org_name = sso.verify_google(username)
        if not valid:
            return flask.abort(401)

        org_id = settings.app.sso_org
        if org_name:
            org = organization.get_by_name(org_name, fields=('_id'))
            if org:
                org_id = org.id
    if DUO_AUTH in sso_mode:
        valid, _ = sso.auth_duo(
            username,
            ipaddr=flask.request.remote_addr,
            type='Key',
        )
        if not valid:
            return flask.abort(401)

    org = organization.get_by_id(org_id)
    if not org:
        return flask.abort(405)

    usr = org.find_user(name=username)
    if not usr:
        usr = org.new_user(name=username, email=email, type=CERT_CLIENT,
            auth_type=sso_mode)
        usr.audit_event('user_created', 'User created with single sign-on',
            remote_addr=utils.get_remote_addr())

        event.Event(type=ORGS_UPDATED)
        event.Event(type=USERS_UPDATED, resource_id=org.id)
        event.Event(type=SERVERS_UPDATED)
    else:
        if usr.disabled:
            return flask.abort(403)

        if usr.auth_type != sso_mode:
            usr.auth_type = sso_mode
            usr.commit('auth_type')

    key_link = org.create_user_key_link(usr.id, one_time=True)

    usr.audit_event('user_profile',
        'User profile viewed from single sign-on',
        remote_addr=utils.get_remote_addr(),
    )

    return utils.redirect(utils.get_url_root()[:-1] + key_link['view_url'])
Example #12
0
    def _auth_push_thread(self):
        info = {
            'Server': self.server.name,
        }

        platform_name = None
        if self.platform == 'linux':
            platform_name = 'Linux'
        elif self.platform == 'mac' or self.platform == 'ios':
            platform_name = 'Apple'
        elif self.platform == 'win':
            platform_name = 'Windows'
        elif self.platform == 'chrome':
            platform_name = 'Chrome OS'

        if self.device_name:
            info['Device'] = '%s (%s)' % (self.device_name, platform_name)

        if self.push_type == DUO_AUTH:
            allow, _ = sso.auth_duo(
                self.user.name,
                ipaddr=self.remote_ip,
                type='Connection',
                info=info,
            )
        elif self.push_type == SAML_OKTA_AUTH:
            allow = sso.auth_okta_push(
                self.user.name,
                ipaddr=self.remote_ip,
                type='Connection',
                info=info,
            )
        else:
            raise ValueError('Unkown push auth type')

        if not allow:
            self.user.audit_event(
                'user_connection',
                ('User connection to "%s" denied. ' +
                 'Push authentication failed') % (self.server.name),
                remote_addr=self.remote_ip,
            )
            raise AuthError('User failed push authentication')

        if settings.app.sso_cache:
            self.sso_cache_collection.update(
                {
                    'user_id': self.user.id,
                    'server_id': self.server.id,
                    'remote_ip': self.remote_ip,
                    'mac_addr': self.mac_addr,
                    'platform': self.platform,
                    'device_id': self.device_id,
                    'device_name': self.device_name,
                }, {
                    'user_id': self.user.id,
                    'server_id': self.server.id,
                    'remote_ip': self.remote_ip,
                    'mac_addr': self.mac_addr,
                    'platform': self.platform,
                    'device_id': self.device_id,
                    'device_name': self.device_name,
                    'timestamp': utils.now(),
                },
                upsert=True)
Example #13
0
def sso_authenticate_post():
    if settings.app.sso != DUO_AUTH:
        return flask.abort(405)

    username = flask.request.json['username']
    usernames = [username]
    email = None
    if '@' in username:
        email = username
        usernames.append(username.split('@')[0])

    valid = False
    for i, username in enumerate(usernames):
        try:
            valid, org_id = sso.auth_duo(
                username,
                strong=True,
                ipaddr=flask.request.remote_addr,
                type='Key',
            )
            break
        except InvalidUser:
            if i == len(usernames) - 1:
                logger.error('Invalid duo username', 'sso',
                    username=username,
                )

    if not valid:
        logger.error('Invalid duo username', 'sso',
            username=username,
        )
        return flask.abort(401)

    if not org_id:
        org_id = settings.app.sso_org

    org = organization.get_by_id(org_id)
    if not org:
        logger.error('Organization for Duo sso does not exist', 'sso',
            org_id=org_id,
        )
        return flask.abort(405)

    usr = org.find_user(name=username)
    if not usr:
        usr = org.new_user(name=username, email=email, type=CERT_CLIENT,
            auth_type=DUO_AUTH)
        usr.audit_event('user_created', 'User created with single sign-on',
            remote_addr=utils.get_remote_addr())

        event.Event(type=ORGS_UPDATED)
        event.Event(type=USERS_UPDATED, resource_id=org.id)
        event.Event(type=SERVERS_UPDATED)
    else:
        if usr.disabled:
            return flask.abort(403)

        if usr.auth_type != DUO_AUTH:
            usr.auth_type = DUO_AUTH
            usr.commit('auth_type')
            event.Event(type=USERS_UPDATED, resource_id=org.id)

    key_link = org.create_user_key_link(usr.id, one_time=True)

    usr.audit_event('user_profile',
        'User profile viewed from single sign-on',
        remote_addr=utils.get_remote_addr(),
    )

    return utils.get_url_root()[:-1] + key_link['view_url']
Example #14
0
def _auth_radius(username, password):
    sso_mode = settings.app.sso

    valid, org_names, groups = sso.verify_radius(username, password)
    if not valid:
        return utils.jsonify({
            'error': AUTH_INVALID,
            'error_msg': AUTH_INVALID_MSG,
        }, 401)

    org_id = settings.app.sso_org
    if org_names:
        for org_name in org_names:
            org = organization.get_by_name(org_name, fields=('_id'))
            if org:
                org_id = org.id
                break

    valid, org_id_new, groups2 = sso.plugin_sso_authenticate(
        sso_type='radius',
        user_name=username,
        user_email=None,
        remote_ip=utils.get_remote_addr(),
    )
    if valid:
        org_id = org_id_new or org_id
    else:
        logger.error('Radius plugin authentication not valid', 'sso',
            username=username,
        )
        return utils.jsonify({
            'error': AUTH_INVALID,
            'error_msg': AUTH_INVALID_MSG,
        }, 401)

    groups = ((groups or set()) | (groups2 or set())) or None

    if DUO_AUTH in sso_mode:
        try:
            valid, _ = sso.auth_duo(
                username,
                ipaddr=utils.get_remote_addr(),
                type='Key',
            )
        except InvalidUser:
            logger.error('Duo authentication username not valid', 'sso',
                username=username,
            )
            return utils.jsonify({
                'error': AUTH_INVALID,
                'error_msg': AUTH_INVALID_MSG,
            }, 401)
        if valid:
            valid, org_id_new, groups2 = sso.plugin_sso_authenticate(
                sso_type='duo',
                user_name=username,
                user_email=None,
                remote_ip=utils.get_remote_addr(),
            )
            if valid:
                org_id = org_id_new or org_id
            else:
                logger.error('Duo plugin authentication not valid', 'sso',
                    username=username,
                )
                return utils.jsonify({
                    'error': AUTH_INVALID,
                    'error_msg': AUTH_INVALID_MSG,
                }, 401)

            groups = ((groups or set()) | (groups2 or set())) or None
        else:
            logger.error('Duo authentication not valid', 'sso',
                username=username,
            )
            return utils.jsonify({
                'error': AUTH_INVALID,
                'error_msg': AUTH_INVALID_MSG,
            }, 401)

    groups = ((groups or set()) | (groups2 or set())) or None

    org = organization.get_by_id(org_id)
    if not org:
        return flask.abort(405)

    usr = org.find_user(name=username)
    if not usr:
        usr = org.new_user(name=username, type=CERT_CLIENT,
            auth_type=sso_mode, groups=list(groups) if groups else None)

        usr.audit_event(
            'user_created',
            'User created with single sign-on',
            remote_addr=utils.get_remote_addr(),
        )

        event.Event(type=ORGS_UPDATED)
        event.Event(type=USERS_UPDATED, resource_id=org.id)
        event.Event(type=SERVERS_UPDATED)
    else:
        if usr.disabled:
            return utils.jsonify({
                'error': AUTH_DISABLED,
                'error_msg': AUTH_DISABLED_MSG,
            }, 403)

        if groups and groups - set(usr.groups or []):
            usr.groups = list(set(usr.groups or []) | groups)
            usr.commit('groups')

        if usr.auth_type != sso_mode:
            usr.auth_type = sso_mode
            usr.set_pin(None)
            usr.commit(('auth_type', 'pin'))

    key_link = org.create_user_key_link(usr.id, one_time=True)

    usr.audit_event('user_profile',
        'User profile viewed from single sign-on',
        remote_addr=utils.get_remote_addr(),
    )

    return utils.jsonify({
        'redirect': utils.get_url_root() + key_link['view_url'],
    }, 202)
Example #15
0
    def _auth_push_thread(self):
        info={
            'Server': self.server.name,
        }

        platform_name = None
        if self.platform == 'linux':
            platform_name = 'Linux'
        elif self.platform == 'mac' or self.platform == 'ios':
            platform_name = 'Apple'
        elif self.platform == 'win':
            platform_name = 'Windows'
        elif self.platform == 'chrome':
            platform_name = 'Chrome OS'

        if self.device_name:
            info['Device'] = '%s (%s)' % (self.device_name, platform_name)

        if self.push_type == DUO_AUTH:
            allow, _ = sso.auth_duo(
                self.user.name,
                ipaddr=self.remote_ip,
                type='Connection',
                info=info,
            )
        elif self.push_type == SAML_OKTA_AUTH:
            allow = sso.auth_okta_push(
                self.user.name,
                ipaddr=self.remote_ip,
                type='Connection',
                info=info,
            )
        else:
            raise ValueError('Unkown push auth type')

        if not allow:
            self.user.audit_event('user_connection',
                ('User connection to "%s" denied. ' +
                 'Push authentication failed') % (
                    self.server.name),
                remote_addr=self.remote_ip,
            )
            raise AuthError('User failed push authentication')

        if settings.app.sso_cache:
            self.sso_cache_collection.update({
                'user_id': self.user.id,
                'server_id': self.server.id,
                'remote_ip': self.remote_ip,
                'mac_addr': self.mac_addr,
                'platform': self.platform,
                'device_id': self.device_id,
                'device_name': self.device_name,
            }, {
                'user_id': self.user.id,
                'server_id': self.server.id,
                'remote_ip': self.remote_ip,
                'mac_addr': self.mac_addr,
                'platform': self.platform,
                'device_id': self.device_id,
                'device_name': self.device_name,
                'timestamp': utils.now(),
            }, upsert=True)
Example #16
0
def sso_authenticate_post():
    if settings.app.sso != DUO_AUTH:
        return flask.abort(405)

    username = flask.request.json['username']
    usernames = [username]
    email = None
    if '@' in username:
        email = username
        usernames.append(username.split('@')[0])

    valid = False
    for i, username in enumerate(usernames):
        try:
            valid, org_id = sso.auth_duo(
                username,
                strong=True,
                ipaddr=flask.request.remote_addr,
                type='Key',
            )
            break
        except InvalidUser:
            if i == len(usernames) - 1:
                logger.error('Invalid duo username', 'sso',
                    username=username,
                )

    if not valid:
        logger.error('Invalid duo username', 'sso',
            username=username,
        )
        return flask.abort(401)

    if not org_id:
        org_id = settings.app.sso_org

    org = organization.get_by_id(org_id)
    if not org:
        logger.error('Organization for Duo sso does not exist', 'sso',
            org_id=org_id,
        )
        return flask.abort(405)

    usr = org.find_user(name=username)
    if not usr:
        usr = org.new_user(name=username, email=email, type=CERT_CLIENT,
            auth_type=DUO_AUTH)
        usr.audit_event('user_created', 'User created with single sign-on',
            remote_addr=utils.get_remote_addr())

        event.Event(type=ORGS_UPDATED)
        event.Event(type=USERS_UPDATED, resource_id=org.id)
        event.Event(type=SERVERS_UPDATED)
    else:
        if usr.disabled:
            return flask.abort(403)

        if usr.auth_type != DUO_AUTH:
            usr.auth_type = DUO_AUTH
            usr.commit('auth_type')
            event.Event(type=USERS_UPDATED, resource_id=org.id)

    key_link = org.create_user_key_link(usr.id, one_time=True)

    usr.audit_event('user_profile',
        'User profile viewed from single sign-on',
        remote_addr=utils.get_remote_addr(),
    )

    return flask.request.url_root[:-1] + key_link['view_url']
Example #17
0
        def auth_thread():
            info={
                'Server': self.server.name,
            }

            platform_name = None
            if platform == 'linux':
                platform_name = 'Linux'
            elif platform == 'mac':
                platform_name = 'Apple'
            elif platform == 'win':
                platform_name = 'Windows'
            elif platform == 'chrome':
                platform_name = 'Chrome OS'

            if device_name:
                info['Device'] = '%s (%s)' % (device_name, platform_name)

            allow = False
            try:
                if type == DUO_AUTH:
                    allow, _ = sso.auth_duo(
                        user.name,
                        ipaddr=remote_ip,
                        type='Connection',
                        info=info,
                    )
                elif type == SAML_OKTA_AUTH:
                    allow = sso.auth_okta(
                        user.name,
                        ipaddr=remote_ip,
                        type='Connection',
                        info=info,
                    )
                else:
                    raise ValueError('Unkown push auth type')
            except:
                logger.exception('Push auth server error', 'server',
                    client_id=client_id,
                    user_id=user.id,
                    username=user.name,
                    server_id=self.server.id,
                )
                self.instance_com.push_output(
                    'ERROR Push auth server error client_id=%s' % client_id)
            try:
                if allow:
                    self.allow_client(client, org, user, reauth)
                else:
                    logger.LogEntry(message='User failed push ' +
                        'authentication "%s".' % user.name)
                    user.audit_event('user_connection',
                        ('User connection to "%s" denied. ' +
                         'Push authentication failed') % (
                            self.server.name),
                        remote_addr=remote_ip,
                    )
                    self.instance_com.send_client_deny(
                        client_id,
                        key_id,
                        'User failed push authentication',
                    )
            except:
                logger.exception('Push auth error', 'server',
                    client_id=client_id,
                    user_id=user.id,
                    server_id=self.server.id,
                )
                self.instance_com.push_output(
                    'ERROR Push auth error client_id=%s' % client_id)
Example #18
0
def sso_callback_get():
    sso_mode = settings.app.sso

    if sso_mode not in (GOOGLE_AUTH, GOOGLE_DUO_AUTH, SLACK_AUTH,
            SLACK_DUO_AUTH, SAML_AUTH, SAML_DUO_AUTH, SAML_OKTA_AUTH,
            SAML_OKTA_DUO_AUTH, SAML_ONELOGIN_AUTH, SAML_ONELOGIN_DUO_AUTH):
        return flask.abort(405)

    state = flask.request.args.get('state')
    sig = flask.request.args.get('sig')

    tokens_collection = mongo.get_collection('sso_tokens')
    doc = tokens_collection.find_and_modify(query={
        '_id': state,
    }, remove=True)

    if not doc:
        return flask.abort(404)

    query = flask.request.query_string.split('&sig=')[0]
    test_sig = base64.urlsafe_b64encode(hmac.new(str(doc['secret']),
        query, hashlib.sha512).digest())

    if sig != test_sig:
        return flask.abort(401)

    params = urlparse.parse_qs(query)

    if doc.get('type') == SAML_AUTH:
        username = params.get('username')[0]
        email = params.get('email', [None])[0]
        org_name = params.get('org', [None])[0]

        if not username:
            return flask.abort(406)

        valid, org_name = sso.verify_saml(username, email, org_name)
        if not valid:
            return flask.abort(401)

        org_id = settings.app.sso_org
        if org_name:
            org = organization.get_by_name(org_name, fields=('_id'))
            if org:
                org_id = org.id
    elif doc.get('type') == SLACK_AUTH:
        username = params.get('username')[0]
        email = None
        user_team = params.get('team')[0]
        org_names = params.get('orgs', [''])[0]
        org_names = org_names.split(',')

        valid, org_name = sso.verify_slack(username, user_team, org_names)
        if not valid:
            return flask.abort(401)

        if org_name:
            org_names = [org_name]

        org_id = settings.app.sso_org
        for org_name in org_names:
            org = organization.get_by_name(org_name, fields=('_id'))
            if org:
                org_id = org.id
                break
    else:
        username = params.get('username')[0]
        email = username

        valid, org_name = sso.verify_google(username)
        if not valid:
            return flask.abort(401)

        org_id = settings.app.sso_org
        if org_name:
            org = organization.get_by_name(org_name, fields=('_id'))
            if org:
                org_id = org.id
    if DUO_AUTH in sso_mode:
        valid, _ = sso.auth_duo(
            username,
            ipaddr=flask.request.remote_addr,
            type='Key',
        )
        if not valid:
            return flask.abort(401)

    org = organization.get_by_id(org_id)
    if not org:
        return flask.abort(405)

    usr = org.find_user(name=username)
    if not usr:
        usr = org.new_user(name=username, email=email, type=CERT_CLIENT,
            auth_type=sso_mode)
        usr.audit_event('user_created', 'User created with single sign-on',
            remote_addr=utils.get_remote_addr())

        event.Event(type=ORGS_UPDATED)
        event.Event(type=USERS_UPDATED, resource_id=org.id)
        event.Event(type=SERVERS_UPDATED)
    else:
        if usr.disabled:
            return flask.abort(403)

        if usr.auth_type != sso_mode:
            usr.auth_type = sso_mode
            usr.commit('auth_type')

    key_link = org.create_user_key_link(usr.id, one_time=True)

    usr.audit_event('user_profile',
        'User profile viewed from single sign-on',
        remote_addr=utils.get_remote_addr(),
    )

    return flask.redirect(flask.request.url_root[:-1] + key_link['view_url'])
Example #19
0
def sso_callback_get():
    sso_mode = settings.app.sso

    if sso_mode not in (GOOGLE_AUTH, GOOGLE_DUO_AUTH):
        return flask.abort(405)

    state = flask.request.args.get('state')
    user = flask.request.args.get('user')
    sig = flask.request.args.get('sig')

    tokens_collection = mongo.get_collection('sso_tokens')
    doc = tokens_collection.find_and_modify(query={
        '_id': state,
    }, remove=True)

    if not doc:
        return flask.abort(404)

    test_sig = base64.urlsafe_b64encode(hmac.new(str(doc['secret']),
        str(state + user), hashlib.sha256).digest())

    if sig != test_sig:
        return flask.abort(401)

    valid, org_id = sso.verify_google(user)
    if not valid:
        return flask.abort(401)

    if sso_mode == GOOGLE_DUO_AUTH:
        valid, _ = sso.auth_duo(
            user,
            ipaddr=flask.request.remote_addr,
            type='Key',
        )
        if not valid:
            return flask.abort(401)

    if not org_id:
        org_id = settings.app.sso_org

    org = organization.get_by_id(org_id)
    if not org:
        return flask.abort(405)

    if sso_mode == GOOGLE_DUO_AUTH:
        auth_type = DUO_AUTH
    else:
        auth_type = GOOGLE_AUTH

    usr = org.find_user(name=user)
    if not usr:
        usr = org.new_user(name=user, email=user, type=CERT_CLIENT,
            auth_type=auth_type)
        event.Event(type=ORGS_UPDATED)
        event.Event(type=USERS_UPDATED, resource_id=org.id)
        event.Event(type=SERVERS_UPDATED)
    elif usr.auth_type != auth_type:
        usr.auth_type = auth_type
        usr.commit('auth_type')

    key_link = org.create_user_key_link(usr.id, one_time=True)

    return flask.redirect(flask.request.url_root[:-1] + key_link['view_url'])