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