Exemple #1
0
    def test_ip_str_to_ip_networks(self):
        # This should return two objects, both in IPNetwork form
        ip_str = "192.168.1.1,10.0.0.0/8,::1,2001:db8::/32"
        ip_list = utility.parse_csv_ip_ranges_to_ip_networks(ip_str)
        self.assertEqual(len(ip_list), 4)
        self.assertIn(ipaddress.ip_network(u"192.168.1.1/32"), ip_list)
        self.assertIn(ipaddress.ip_network(u"10.0.0.0/8"), ip_list)
        self.assertIn(ipaddress.ip_network(u"::1/128"), ip_list)
        self.assertIn(ipaddress.ip_network(u"2001:db8::/32"), ip_list)

        # Now confirm we properly fail when garbage is appended
        ip_str = ip_str + ",abcdef"
        with self.assertRaises(errors.InputValidationError):
            utility.parse_csv_ip_ranges_to_ip_networks(ip_str)
def login(session, tid, username, password, client_using_tor, client_ip, token=''):
    """
    login returns a tuple (user_id, state, pcn)
    """
    user = None

    tenant_condition = or_(and_(UserTenant.user_id == User.id, UserTenant.tenant_id == tid),
                           and_(User.role == u'admin', UserTenant.user_id == User.id, UserTenant.tenant_id == 1))

    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

    log.debug("Login: Success (%s)" % user.role)

    user.last_login = datetime_now()

    return user.id, user.state, user.role, user.password_change_needed
def login(session, tid, username, password, client_using_tor, client_ip):
    """
    login returns a session
    """
    user = None

    users = session.query(User).filter(User.username == username,
                                       User.state != u'disabled',
                                       UserTenant.user_id == User.id,
                                       UserTenant.tenant_id == tid).distinct()
    for u in users:
        if GCE.check_password(u.hash_alg, password, u.salt, u.password):
            user = u
            break

    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()

    crypto_prv_key = ''
    if State.tenant_cache[1].encryption and user.crypto_prv_key:
        user_key = GCE.derive_key(password.encode('utf-8'), user.salt)
        crypto_prv_key = GCE.symmetric_decrypt(user_key, user.crypto_prv_key)

    return Sessions.new(tid, user.id, user.role, user.password_change_needed,
                        crypto_prv_key)
Exemple #4
0
def db_update_node(session, tid, request, language, config_node):
    """
    Update and serialize the node infos

    :param session: the session on which perform queries.
    :param language: the language in which to localize data
    :return: a dictionary representing the serialization of the node
    """
    node = ConfigFactory(session, tid, config_node)

    node.update(request)

    if 'basic_auth' in request:
        if request['basic_auth'] and request[
                'basic_auth_username'] and request['basic_auth_password']:
            node.set_val(u'basic_auth', True)
            node.set_val(u'basic_auth_username',
                         request['basic_auth_username'])
            node.set_val(u'basic_auth_password',
                         request['basic_auth_password'])
        else:
            node.set_val(u'basic_auth', False)

    # Validate that IP addresses/ranges we're getting are goo
    if 'ip_filter_authenticated' in request:
        if request['ip_filter_authenticated_enable'] and request[
                'ip_filter_authenticated']:
            # Make sure we can validate and parse the whole thing
            parse_csv_ip_ranges_to_ip_networks(
                request['ip_filter_authenticated'])

    if 'languages_enabled' in request and 'default_language' in request:
        db_update_enabled_languages(session, tid, request['languages_enabled'],
                                    request['default_language'])

    if language in models.EnabledLanguage.list(session, tid):
        node_l10n = NodeL10NFactory(session, tid)
        node_l10n.update(request, language)

    db_refresh_memory_variables(session, [tid])

    return db_admin_serialize_node(session, tid, language)
Exemple #5
0
def login(session,
          tid,
          username,
          password,
          receiver_second_login,
          receiver_auth_code,
          client_using_tor,
          client_ip,
          token=''):
    """
    login returns a tuple (user_id, state, role, pcn, authCodePrepared)
    """
    if token:
        user = session.query(User).filter(User.auth_token == token, \
                                          User.state != u'disabled', \
                                          User.tid == tid).one_or_none()
    else:
        user = session.query(User).filter(User.username == username, \
                                          User.state != u'disabled', \
                                          User.tid == tid).one_or_none()

    if user is None or (not token and not security.check_password(
            password, user.salt, user.password)):
        log.debug("Login: Invalid credentials")
        Settings.failed_login_attempts += 1
        raise errors.InvalidAuthentication

    if not client_using_tor and not mystate.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 mystate.tenant_cache[tid]['ip_filter_authenticated_enable']:
        ip_networks = parse_csv_ip_ranges_to_ip_networks(
            mystate.tenant_cache[tid]['ip_filter_authenticated'])
        client_ip = text_type(client_ip)
        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

    # se sono arrivato qui il primo login è andato a buon fine
    # il login (username, password) per un ricevente viene rieseguito anche al secondo passaggio
    # per motivi di sicurezza
    # A QUESTO PUNTO:
    # SE receiver2ndStepLoginState = 'N':
    # 1 - genero il codice
    # 2 - memorizzo record in ReceiverAuthCode
    # 3 - invio mail
    # ELSE:
    # verifico la correttenza del secondo codice
    if user.role == 'receiver':

        receiver = session.query(Receiver).filter(
            Receiver.id == user.id).one_or_none()

        if receiver.two_step_login_enabled and not user.password_change_needed:

            if receiver_second_login == 'first_login_to_complete':

                yyyy = str(datetime_now().year)
                mm = str(datetime_now().month).zfill(2)
                dd = str(datetime_now().day).zfill(2)
                result_query = session.query(ReceiverAuthCode).filter(
                    ReceiverAuthCode.receiver_id == user.id,
                    func.strftime("%Y-%m-%d",
                                  ReceiverAuthCode.creation_date) == yyyy +
                    '-' + mm + '-' + dd).all()

                # genero il codice
                #chiamo la funzione generate_authcode_password che genera la password con l'utilizzo della funzione os.urandom
                #randnum = ''.join(["%s" % SystemRandom().randint(0, 9) for num in range(0, 12)])
                randnum = generate_authcode_password(12)

                #print randnum
                log.debug(randnum[0:4] + ' ' + randnum[4:8] + ' ' +
                          randnum[8:12])

                # inserisco il record nel db
                newAuthCode = models.ReceiverAuthCode()
                newAuthCode.receiver_id = receiver.id

                newAuthCode.salt = security.generateRandomSalt()
                newAuthCode.auth_code = security.hash_password(
                    randnum, newAuthCode.salt)

                session.add(newAuthCode)
                session.flush()

                # invio i tre pezzi del codice alle tre mail specificate nel profilo del ricevente
                email_prg = str(len(result_query) + 1)
                day = dd + '/' + mm + '/' + yyyy
                mystate.sendmail(
                    1, receiver.control_mail_1,
                    "Receiver Auth Code #" + email_prg + " - " + day,
                    randnum[0:4])
                mystate.sendmail(
                    1, receiver.control_mail_2,
                    "Receiver Auth Code #" + email_prg + " - " + day,
                    randnum[4:8])
                mystate.sendmail(
                    1, receiver.control_mail_3,
                    "Receiver Auth Code #" + email_prg + " - " + day,
                    randnum[8:12])

                log.debug("Invio delle mail effettuato con successo")

                receiver_second_login = '******'

            elif receiver_second_login == 'second_login_to_complete':
                auth_code_item = session.query(ReceiverAuthCode).filter(ReceiverAuthCode.receiver_id == user.id) \
                                                                .order_by(ReceiverAuthCode.creation_date.desc()).first()

                # se non sono passati TOT minuti dall'ultimo codice emesso si può controllare la validità del codice
                if auth_code_item is not None and auth_code_item.is_valid and not is_expired(
                        auth_code_item.creation_date, 0,
                        AUTH_CODE_EXPIRATION_IN_MINUTES, 0, 0):

                    # qui devo verificare che il codice inviato dall'utente sia uguale a una delle permutazioni dei tre blocchi
                    # da quattro cifre che si ottengono dal codice salvato sul db
                    firstBlock = receiver_auth_code[0:4]
                    secondBlock = receiver_auth_code[4:8]
                    thirdBlock = receiver_auth_code[8:12]
                    combList = []
                    combList.insert(0, firstBlock + secondBlock + thirdBlock)
                    combList.insert(1, firstBlock + thirdBlock + secondBlock)
                    combList.insert(2, secondBlock + firstBlock + thirdBlock)
                    combList.insert(3, secondBlock + thirdBlock + firstBlock)
                    combList.insert(4, thirdBlock + firstBlock + secondBlock)
                    combList.insert(5, thirdBlock + secondBlock + firstBlock)

                    auth_code_match = False
                    for authCode in combList:
                        if security.check_password(authCode,
                                                   auth_code_item.salt,
                                                   auth_code_item.auth_code):
                            auth_code_match = True

                            # POSSO ANCHE FARE UNA UPDATE del campo is_valid PER IL RECORD UTILIZZATO NELLA VALIDAZIONE
                            auth_code_item.is_valid = False
                            session.add(auth_code_item)
                            session.flush()

                            #objs = session.query(ReceiverAuthCode).filter(ReceiverAuthCode.receiver_id == auth_code_item.receiver_id) \
                            #                                      .order_by(ReceiverAuthCode.creation_date.desc(), ReceiverAuthCode.daily_prg.desc())
                            #for obj in objs:
                            #    session.delete(obj)
                            #    session.flush()
                            #session.delete(auth_code_item)

                            receiver_second_login = '******'
                            break

                    if not auth_code_match:
                        log.debug("Login: Invalid authentication code")
                        Settings.failed_login_attempts += 1
                        raise errors.InvalidAuthentication

                else:
                    log.debug(
                        "Login: authentication code is expired. Please repeat login"
                    )
                    Settings.failed_login_attempts += 1
                    raise errors.InvalidAuthentication

            else:
                log.debug(
                    "receiver_auth_code diverso da first_login_to_complete e second_login_to_complete"
                )
                receiver_second_login = '******'
        else:
            receiver_second_login = '******'  #da tenere sotto controllo

    else:
        receiver_second_login = '******'  # da tenere sotto controllo

    log.debug("Login: Success (%s)" % user.role)

    user.last_login = datetime_now()

    return user.id, user.state, user.role, user.password_change_needed, receiver_second_login