Esempio n. 1
0
    def test_valid_password(self):
        dummy_password = "******"

        hashed_once = hash_password(dummy_password, dummy_salt)
        hashed_twice = hash_password(dummy_password, dummy_salt)
        self.assertTrue(hashed_once, hashed_twice)

        self.assertTrue(check_password(dummy_password, dummy_salt,
                                       hashed_once))
Esempio n. 2
0
def db_admin_update_user(session, state, tid, user_id, request, language):
    """
    Updates the specified user.
    """
    fill_localized_keys(request, models.User.localized_keys, language)

    user = db_get_user(session, tid, user_id)

    if user.username != request['username']:
        check = session.query(models.User).filter(
            models.User.username == text_type(request['username']),
            models.UserTenant.user_id == models.User.id,
            models.UserTenant.tenant_id == tid).one_or_none()
        if check is not None:
            raise errors.InputValidationError('Username already in use')

    user.update(request)

    password = request['password']
    if password:
        user.password = security.hash_password(password, user.salt)
        user.password_change_date = datetime_now()

    # The various options related in manage PGP keys are used here.
    parse_pgp_options(state, user, request)

    if user.role == 'admin':
        db_refresh_memory_variables(session, [tid])

    return user
Esempio n. 3
0
def db_user_update_user(session, state, tid, user_id, request):
    """
    Updates the specified user.
    This version of the function is specific for users that with comparison with
    admins can change only few things:
      - real name
      - email address
      - preferred language
      - the password (with old password check)
      - pgp key
    raises: globaleaks.errors.ResourceNotFound` if the receiver does not exist.
    """
    from globaleaks.handlers.admin.notification import db_get_notification
    from globaleaks.handlers.admin.node import db_admin_serialize_node

    user = models.db_get(session,
                         models.User,
                         models.User.id == user_id)

    user.language = request.get('language', State.tenant_cache[tid].default_language)
    user.name = request['name']
    new_password = request['password']
    old_password = request['old_password']

    if new_password:
        if user.password_change_needed:
            user.password_change_needed = False
        else:
            if not check_password(old_password,
                                  user.salt,
                                  user.password):
                raise errors.InvalidOldPassword

        user.password = hash_password(new_password, user.salt)
        user.password_change_date = datetime_now()

    # If the email address changed, send a validation email
    if request['mail_address'] != user.mail_address:
        user.change_email_address = request['mail_address']
        user.change_email_date = datetime_now()
        user.change_email_token = generateRandomKey(32)

        user_desc = user_serialize_user(session, user, user.language)

        template_vars = {
            'type': 'email_validation',
            'user': user_desc,
            'new_email_address': request['mail_address'],
            'validation_token': user.change_email_token,
            'node': db_admin_serialize_node(session, 1, user.language),
            'notification': db_get_notification(session, tid, user.language)
        }

        state.format_and_send_mail(session, tid, user_desc, template_vars)

    # If the platform allows users to change PGP keys, process it
    if State.tenant_cache[tid]['enable_user_pgp_key_upload'] is True:
        parse_pgp_options(state, user, request)

    return user
Esempio n. 4
0
def db_get_wbtip_by_receipt(session, tid, receipt):
    hashed_receipt = security.hash_password(receipt, State.tenant_cache[tid].receipt_salt)
    return session.query(InternalTip) \
                  .filter(WhistleblowerTip.receipt_hash == text_type(hashed_receipt, 'utf-8'),
                          WhistleblowerTip.tid == tid,
                          InternalTip.id == WhistleblowerTip.id,
                          InternalTip.tid == WhistleblowerTip.tid).one_or_none()
Esempio n. 5
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)
Esempio n. 6
0
def db_create_user(session, state, tid, request, language):
    request['tid'] = tid

    fill_localized_keys(request, models.User.localized_keys, language)

    if request['username']:
        user = session.query(models.User).filter(
            models.User.username == text_type(request['username']),
            models.UserTenant.user_id == models.User.id,
            models.UserTenant.tenant_id == tid).one_or_none()
        if user is not None:
            raise errors.InputValidationError('Username already in use')

    user = models.User({
        'tid':
        tid,
        'username':
        request['username'],
        'role':
        request['role'],
        'state':
        u'enabled',
        'name':
        request['name'],
        'description':
        request['description'],
        'language':
        language,
        'password_change_needed':
        request['password_change_needed'],
        'mail_address':
        request['mail_address'],
        'can_edit_general_settings':
        request['can_edit_general_settings']
    })

    if not request['username']:
        user.username = user.id = uuid4()

    if request['password']:
        password = request['password']
    else:
        password = u'password'

    user.salt = security.generateRandomSalt()
    user.password = security.hash_password(password, user.salt)

    # The various options related in manage PGP keys are used here.
    parse_pgp_options(state, user, request)

    session.add(user)

    session.flush()

    db_create_usertenant_association(session, user.id, tid)

    return user
Esempio n. 7
0
def db_create_user(session, state, tid, request, language):
    request['tid'] = tid

    fill_localized_keys(request, models.User.localized_keys, language)

    if request['username']:
        user = session.query(models.User).filter(
            models.User.tid == tid, models.User.username == text_type(
                request['username'])).one_or_none()
        if user is not None:
            raise errors.InputValidationError('Username already in use')

    user = models.User({
        'tid':
        tid,
        'username':
        request['username'],
        'role':
        request['role'],
        'state':
        u'enabled',
        'name':
        request['name'],
        'description':
        request['description'],
        'name':
        request['name'],
        'language':
        language,
        'password_change_needed':
        request['password_change_needed'],
        'mail_address':
        request['mail_address']
    })

    if request['password']:
        password = request['password']
    elif user.role == 'receiver':
        # code necessary because the user.role for recipient is receiver
        password = '******'
    else:
        password = user.role

    user.salt = security.generateRandomSalt()
    user.password = security.hash_password(password, user.salt)

    # The various options related in manage PGP keys are used here.
    parse_pgp_options(state, user, request)

    session.add(user)

    session.flush()

    if not request['username']:
        user.username = user.id

    return user
Esempio n. 8
0
    def test_pass_hash(self):
        dummy_password = "******"

        dummy_salt = generateRandomSalt()

        sure_bin = scrypt.hash(dummy_password, dummy_salt)
        sure = binascii.b2a_hex(sure_bin)
        not_sure = hash_password(dummy_password, dummy_salt)
        self.assertEqual(sure, not_sure)
Esempio n. 9
0
    def test_check_password(self):
        password = '******'
        password_hash = hash_password(password, dummy_salt)

        self.assertFalse(check_password('x', dummy_salt, password_hash))
        self.assertFalse(check_password(password, 'x', password_hash))
        self.assertFalse(check_password(password, dummy_salt, 'x'))

        self.assertTrue(check_password(password, dummy_salt, password_hash))
Esempio n. 10
0
    def get_internalfiles_by_receipt(self, session, receipt):
        hashed_receipt = security.hash_password(
            receipt, State.tenant_cache[1].receipt_salt)

        ifiles = session.query(models.InternalFile) \
                        .filter(models.InternalFile.internaltip_id == models.WhistleblowerTip.id,
                                models.WhistleblowerTip.receipt_hash == text_type(hashed_receipt, 'utf-8'))

        return [
            models.serializers.serialize_ifile(session, ifile)
            for ifile in ifiles
        ]
Esempio n. 11
0
def db_admin_update_user(session, state, tid, user_id, request, language):
    """
    Updates the specified user.
    """
    fill_localized_keys(request, models.User.localized_keys, language)

    user = models.db_get(session, models.User, models.User.tid == tid,
                         models.User.id == user_id)

    user.update(request)

    password = request['password']
    if password:
        user.password = security.hash_password(password, user.salt)
        user.password_change_date = datetime_now()

    # The various options related in manage PGP keys are used here.
    parse_pgp_options(state, user, request)

    if user.role == 'admin':
        db_refresh_memory_variables(session, [tid])

    return user
Esempio n. 12
0
from globaleaks.utils import security, tempdict, token, utility
from globaleaks.utils.securetempfile import SecureTemporaryFile
from globaleaks.utils.objectdict import ObjectDict
from globaleaks.utils.structures import fill_localized_keys
from globaleaks.utils.utility import datetime_null, datetime_now, datetime_to_ISO8601, \
    log, sum_dicts

from globaleaks.workers import process
from globaleaks.workers.supervisor import ProcessSupervisor

## constants
VALID_PASSWORD1 = u'ACollectionOfDiplomaticHistorySince_1966_ToThe_Pr esentDay#'
VALID_PASSWORD2 = VALID_PASSWORD1
VALID_SALT1 = security.generateRandomSalt()
VALID_SALT2 = security.generateRandomSalt()
VALID_HASH1 = security.hash_password(VALID_PASSWORD1, VALID_SALT1)
VALID_HASH2 = security.hash_password(VALID_PASSWORD2, VALID_SALT2)
VALID_BASE64_IMG = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQYV2NgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII='
INVALID_PASSWORD = u'antani'

PGPKEYS = {}

DATA_DIR = os.path.join(TEST_DIR, 'data')
kp = os.path.join(DATA_DIR, 'gpg')
for filename in os.listdir(kp):
    with open(os.path.join(kp, filename)) as pgp_file:
        PGPKEYS[filename] = text_type(pgp_file.read())


def deferred_sleep_mock(seconds):
    return
Esempio n. 13
0
def db_create_submission(session, tid, request, uploaded_files, client_using_tor):
    answers = request['answers']

    context, questionnaire = session.query(models.Context, models.Questionnaire) \
                                    .filter(models.Context.id == request['context_id'],
                                            models.Questionnaire.id == models.Context.questionnaire_id,
                                            models.Questionnaire.tid.in_(set([1, tid]))).one_or_none()
    if not context:
        raise errors.ModelNotFound(models.Context)

    steps = db_get_questionnaire(session, tid, questionnaire.id, None)['steps']
    questionnaire_hash = text_type(sha256(json.dumps(steps)))
    db_archive_questionnaire_schema(session, steps, questionnaire_hash)

    submission = models.InternalTip()
    submission.tid = tid
    submission.status = db_get_id_for_system_status(session, tid, 'new')

    submission.progressive = db_assign_submission_progressive(session, tid)

    if context.tip_timetolive > 0:
        submission.expiration_date = get_expiration(context.tip_timetolive)
    else:
        submission.expiration_date = datetime_never()

    # this is get from the client as it the only possibility possible
    # that would fit with the end to end submission.
    # the score is only an indicator and not a critical information so we can accept to
    # be fooled by the malicious user.
    submission.total_score = request['total_score']

    # The status https is used to keep track of the security level adopted by the whistleblower
    submission.https = not client_using_tor

    submission.context_id = context.id
    submission.enable_two_way_comments = context.enable_two_way_comments
    submission.enable_two_way_messages = context.enable_two_way_messages
    submission.enable_attachments = context.enable_attachments

    whistleblower_identity = session.query(models.Field) \
                                    .filter(models.Field.template_id == u'whistleblower_identity',
                                            models.Field.step_id == models.Step.id,
                                            models.Step.questionnaire_id == context.questionnaire_id).one_or_none()

    submission.enable_whistleblower_identity = whistleblower_identity is not None

    if submission.enable_whistleblower_identity and request['identity_provided']:
        submission.identity_provided = True
        submission.identity_provided_date = datetime_now()

    submission.questionnaire_hash = questionnaire_hash
    submission.preview = extract_answers_preview(steps, answers)

    session.add(submission)
    session.flush()

    receipt = text_type(generateRandomReceipt())

    wbtip = models.WhistleblowerTip()
    wbtip.id = submission.id
    wbtip.tid = submission.tid
    wbtip.receipt_hash = hash_password(receipt, State.tenant_cache[tid].receipt_salt)
    session.add(wbtip)

    db_save_questionnaire_answers(session, tid, submission.id, answers)

    for filedesc in uploaded_files:
        new_file = models.InternalFile()
        new_file.tid = tid
        new_file.name = filedesc['name']
        new_file.description = ""
        new_file.content_type = filedesc['type']
        new_file.size = filedesc['size']
        new_file.internaltip_id = submission.id
        new_file.submission = filedesc['submission']
        new_file.filename = filedesc['filename']
        session.add(new_file)
        log.debug("=> file associated %s|%s (%d bytes)",
                  new_file.name, new_file.content_type, new_file.size)

    if context.maximum_selectable_receivers > 0 and \
                    len(request['receivers']) > context.maximum_selectable_receivers:
        raise errors.InputValidationError("selected an invalid number of recipients")

    rtips_count = 0
    for receiver, user in session.query(models.Receiver, models.User) \
                                 .filter(models.Receiver.id.in_(request['receivers']),
                                         models.ReceiverContext.receiver_id == models.Receiver.id,
                                         models.ReceiverContext.context_id == context.id,
                                         models.User.id == models.Receiver.id,
                                         models.UserTenant.user_id == models.User.id,
                                         models.UserTenant.tenant_id == tid):
        if user.pgp_key_public or State.tenant_cache[tid].allow_unencrypted:
            db_create_receivertip(session, receiver, submission)
            rtips_count += 1

    if rtips_count == 0:
        raise errors.InputValidationError("need at least one recipient")

    log.debug("The finalized submission had created %d models.ReceiverTip(s)", rtips_count)

    return {'receipt': receipt}
Esempio n. 14
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
Esempio n. 15
0
    def test_pass_hash(self):
        dummy_password = "******"

        sure = hash_password(dummy_password, dummy_salt)
        not_sure = hash_password(dummy_password, dummy_salt)
        self.assertEqual(sure, not_sure)
Esempio n. 16
0
def db_get_wbtip_by_receipt(session, tid, receipt):
    hashed_receipt = security.hash_password(receipt, State.tenant_cache[tid].receipt_salt)
    return session.query(InternalTip) \
                  .filter(InternalTip.receipt_hash == unicode(hashed_receipt),
                          InternalTip.tid == tid).one_or_none()