def post(self):
        """
        Receipt login handler used by whistleblowers
        """
        request = self.validate_message(self.request.content.read(),
                                        requests.ReceiptAuthDesc)

        receipt = request['receipt']

        delay = random_login_delay()
        if delay:
            yield deferred_sleep(delay)

        user_id = yield login_whistleblower(receipt,
                                            self.request.client_using_tor)

        GLSessions.revoke_all_sessions(user_id)

        session = new_session(user_id, 'whistleblower', 'Enabled')

        returnValue({
            'session_id': session.id,
            'role': session.user_role,
            'user_id': session.user_id,
            'session_expiration': int(session.getTime())
        })
    def post(self):
        """
        Login
        """
        request = self.validate_message(self.request.content.read(),
                                        requests.AuthDesc)

        username = request['username']
        password = request['password']

        user_id, status, role, pcn = yield login(username, password,
                                                 self.request.client_using_tor)

        # Revoke all other sessions for the newly authenticated user
        GLSessions.revoke_all_sessions(user_id)

        session = new_session(user_id, role, status)

        returnValue({
            'session_id': session.id,
            'role': session.user_role,
            'user_id': session.user_id,
            'session_expiration': int(session.getTime()),
            'status': session.user_status,
            'password_change_needed': pcn
        })
Exemple #3
0
def login_whistleblower(session, tid, receipt, client_using_tor):
    """
    login_whistleblower returns a session
    """
    hashed_receipt = security.hash_password(
        receipt, State.tenant_cache[tid].receipt_salt)
    result = session.query(WhistleblowerTip, InternalTip) \
                    .filter(WhistleblowerTip.receipt_hash == text_type(hashed_receipt, 'utf-8'),
                            WhistleblowerTip.tid == tid,
                            InternalTip.id == WhistleblowerTip.id,
                            InternalTip.tid == WhistleblowerTip.tid).first()

    if result is None:
        log.debug("Whistleblower login: Invalid receipt")
        Settings.failed_login_attempts += 1
        raise errors.InvalidAuthentication

    wbtip, itip = result[0], result[1]

    if not client_using_tor and not State.tenant_cache[tid][
            'https_whistleblower']:
        log.err("Denied login request over clear Web for role 'whistleblower'")
        raise errors.TorNetworkRequired

    itip.wb_last_access = datetime_now()

    return new_session(tid, wbtip.id, 'whistleblower', False)
    def post(self):
        request = self.validate_message(self.request.content.read(),
                                        requests.AuthDesc)

        delay = random_login_delay()
        if delay:
            yield deferred_sleep(delay)

        user_id, status, role, pcn = yield login(self.request.tid,
                                                 request['username'],
                                                 request['password'],
                                                 self.request.client_using_tor,
                                                 self.request.client_ip,
                                                 request['token'])

        session = new_session(self.request.tid, user_id, role, status)

        returnValue({
            'session_id': session.id,
            'role': session.user_role,
            'user_id': session.user_id,
            'session_expiration': int(session.getTime()),
            'status': session.user_status,
            'password_change_needed': pcn
        })
Exemple #5
0
    def request(self,
                body='',
                uri=b'https://www.globaleaks.org/',
                user_id=None,
                role=None,
                multilang=False,
                headers=None,
                client_addr=None,
                method='GET',
                handler_cls=None,
                attached_file={},
                kwargs={}):
        """
        Constructs a handler for preforming mock requests using the bag of params described below.
        """
        from globaleaks.rest import api

        if handler_cls is None:
            handler_cls = self._handler

        request = forge_request(uri=uri,
                                headers=headers,
                                body=body,
                                client_addr=client_addr,
                                method=b'GET',
                                attached_file=attached_file)

        x = api.APIResourceWrapper()
        x.preprocess(request)

        if not getattr(handler_cls, 'decorated', False):
            for method in ['get', 'post', 'put', 'delete']:
                if getattr(handler_cls, method, None) is not None:
                    api.decorate_method(handler_cls, method)
                    handler_cls.decorated = True

        handler = handler_cls(self.state, request, **kwargs)

        if multilang:
            request.language = None

        if user_id is None and role is not None:
            if role == 'admin':
                user_id = self.dummyAdminUser['id']
            elif role == 'receiver':
                user_id = self.dummyReceiverUser_1['id']
            elif role == 'custodian':
                user_id = self.dummyCustodianUser['id']

        if role is not None:
            session = new_session(1, user_id, role, 'enabled')
            handler.request.headers[b'x-session'] = session.id.encode()

        if handler.upload_handler:
            handler.uploaded_file = self.get_dummy_file('upload.pdf')

        return handler
Exemple #6
0
    def test_session_management_sched(self):
        new_session('admin', 'admin', 'enabled')  # 1!
        new_session('admin', 'admin', 'enabled')  # 2!
        new_session('admin', 'admin', 'enabled')  # 3!

        self.assertEqual(len(GLSessions), 3)

        self.test_reactor.pump([1] * (GLSettings.authentication_lifetime - 1))

        self.assertEqual(len(GLSessions), 3)

        self.test_reactor.advance(1)

        self.assertEqual(len(GLSessions), 0)

        yield session_management_sched.SessionManagementSchedule().run()
Exemple #7
0
    def post(self):
        request = self.validate_message(self.request.content.read(),
                                        requests.AuthDesc)

        delay = random_login_delay()
        if delay:
            yield deferred_sleep(delay)

        user_id, status, role, pcn, login_step = yield login(
            self.request.tid, request['username'], request['password'],
            request['receiver_second_login'], request['receiver_auth_code'],
            self.request.client_using_tor, self.request.client_ip,
            request['token'])

        if role == 'receiver' and login_step == 'second_login_to_complete':
            session = new_session_rec_auth(self.request.tid, user_id, role,
                                           status, login_step)
            returnValue({
                'session_id': session.id,
                'role': session.user_role,
                'user_id': session.user_id,
                'session_expiration': 1,
                'status': session.user_status,
                'password_change_needed': pcn,
                'receiverLoginState': login_step
            })

        else:
            session = new_session(self.request.tid, user_id, role, status,
                                  login_step)
            returnValue({
                'session_id': session.id,
                'role': session.user_role,
                'user_id': session.user_id,
                'session_expiration': int(session.getTime()),
                'status': session.user_status,
                'password_change_needed': pcn,
                'receiverLoginState': login_step
            })
    def post(self):
        request = self.validate_message(self.request.content.read(), requests.AuthDesc)

        delay = random_login_delay()
        if delay:
            yield deferred_sleep(delay)

        tid = int(request['tid'])
        if tid == 0:
             tid = self.request.tid

        user_id, status, role, pcn = yield login(tid,
                                                 request['username'],
                                                 request['password'],
                                                 self.request.client_using_tor,
                                                 self.request.client_ip,
                                                 request['token'])
        if tid == self.request.tid:
            session = new_session(self.request.tid, user_id, role, status)

            returnValue({
                'session_id': session.id,
                'role': session.user_role,
                'user_id': session.user_id,
                'session_expiration': int(session.getTime()),
                'status': session.user_status,
                'password_change_needed': pcn
            })

        else:
            token = yield get_multitenant_auth_token(user_id, tid)

            if token:
                returnValue({
                    'redirect': 'https://%s/#/login?token=%s' % (State.tenant_cache[tid].hostname, token)
                })
Exemple #9
0
    def request(self,
                jbody=None,
                user_id=None,
                role=None,
                headers=None,
                body='',
                path=None,
                remote_ip='0.0.0.0',
                method='MOCK',
                handler_cls=None,
                attached_file={},
                kwargs={}):
        """
        Constructs a handler for preforming mock requests using the bag of params described below.

        Args:

            jbody:
                The body of the request as a dict (it will be automatically
                converted to string)

            body:
                The body of the request as a string

            user_id:
                when simulating authentication the session should be bound
                to a certain user_id.

            role:
                when simulating authentication the session should be bound
                to a certain role.

            method:
                HTTP method, e.g. "GET" or "POST"

            headers:
                Dict of headers to pass on the request

            remote_ip:
                If a particular remote_ip should be set.

            handler_cls:
                The type of handler that will respond to the request. If this is not set self._handler is used.

            attached_file:
                A dict to place in the request.args.files obj
        """
        if jbody and not body:
            body = json.dumps(jbody)
        elif body and jbody:
            raise ValueError('jbody and body in conflict')

        if handler_cls is None:
            handler_cls = self._handler

        request = DummyRequest([''])

        def getResponseBody():
            return ''.join(request.written)

        request.path = ''
        request.code = 200
        request.language = 'en'
        request.client_ip = '127.0.0.1'
        request.client_proto = 'https'
        request.client_using_tor = False

        request.getResponseBody = getResponseBody

        request.client = IPv4Address('TCP', '1.2.3.4', 12345)

        request.args = {}
        if attached_file is not None:
            request.args = {'file': [attached_file]}

        if headers is not None:
            for k, v in headers.iteritems():
                request.requestHeaders.setRawHeaders(bytes(k), [bytes(v)])

        request.headers = request.getAllHeaders()

        from globaleaks.rest import api
        x = api.APIResourceWrapper()
        x.preprocess(request)

        if path is not None:
            if not path.startswith('/'):
                raise ValueError('Must pass a valid url path')
            request.path = path

        class fakeBody(object):
            def read(self):
                return body

            def close(self):
                pass

        request.content = fakeBody()

        from globaleaks.rest.api import decorate_method
        if not getattr(handler_cls, 'decorated', False):
            for method in ['get', 'post', 'put', 'delete']:
                if getattr(handler_cls, method, None) is not None:
                    decorate_method(handler_cls, method)
                    handler_cls.decorated = True

        handler = handler_cls(request, **kwargs)

        if user_id is None and role is not None:
            if role == 'admin':
                user_id = self.dummyAdminUser['id']
            elif role == 'receiver':
                user_id = self.dummyReceiverUser_1['id']
            elif role == 'custodian':
                user_id = self.dummyCustodianUser['id']

        if role is not None:
            session = new_session(user_id, role, 'enabled')
            handler.request.headers['x-session'] = session.id

        return handler
Exemple #10
0
def login(session,
          tid,
          username,
          password,
          client_using_tor,
          client_ip,
          token=''):
    """
    login returns a session
    """
    user = None

    tenant_condition = and_(UserTenant.user_id == User.id,
                            UserTenant.tenant_id == tid)

    if token:
        user = session.query(User).filter(User.auth_token == token,
                                          User.state != u'disabled',
                                          tenant_condition).one_or_none()
    else:
        users = session.query(User).filter(User.username == username,
                                           User.state != u'disabled',
                                           tenant_condition).distinct()
        for u in users:
            if security.check_password(password, u.salt, u.password):
                user = u

    if user is None:
        log.debug("Login: Invalid credentials")
        Settings.failed_login_attempts += 1
        raise errors.InvalidAuthentication

    if not client_using_tor and not State.tenant_cache[tid]['https_' +
                                                            user.role]:
        log.err("Denied login request over Web for role '%s'" % user.role)
        raise errors.TorNetworkRequired

    # Check if we're doing IP address checks today
    if State.tenant_cache[tid]['ip_filter_authenticated_enable']:
        ip_networks = parse_csv_ip_ranges_to_ip_networks(
            State.tenant_cache[tid]['ip_filter_authenticated'])

        if isinstance(client_ip, binary_type):
            client_ip = client_ip.decode()

        client_ip_obj = ipaddress.ip_address(client_ip)

        # Safety check, we always allow localhost to log in
        success = False
        if client_ip_obj.is_loopback is True:
            success = True

        for ip_network in ip_networks:
            if client_ip_obj in ip_network:
                success = True

        if success is not True:
            raise errors.AccessLocationInvalid

    user.last_login = datetime_now()

    return new_session(tid, user.id, user.role, user.password_change_needed)