Beispiel #1
0
def test_parser():
    """
  Tests PasswordHashParser implementation.
  """
    PWD_LENGTH = 64
    password = misc_utils.generate_random_string(PWD_LENGTH)
    wrong_password = misc_utils.generate_random_string(PWD_LENGTH)
    assert password != wrong_password

    # Test pbkdf2_sha256(md5(password)).
    md5_salt = auth_utils.generate_salt()
    pbkdf2_sha256_salt = auth_utils.generate_salt()
    pbkdf2_sha256_rounds = 100000

    password_hash = auth_utils.hash_password(password, md5_salt, None, 'md5')
    password_hash = auth_utils.hash_password(password_hash, pbkdf2_sha256_salt,
                                             pbkdf2_sha256_rounds,
                                             'pbkdf2_sha256')

    hash_string = "$md5|pbkdf2_sha256$|{}${}|{}${}".format(
        pbkdf2_sha256_rounds, md5_salt, pbkdf2_sha256_salt, password_hash)

    parser = auth_utils.PasswordHashParser()
    parser.parse(hash_string)

    assert parser.verify_password(password) == True
    assert parser.verify_password(wrong_password) == False
    assert str(parser) == hash_string
Beispiel #2
0
def test_compare_secure_strings():
    """
  Tests that compare_secure_strings() returns True when the strings are equal
  and False otherwise. Does not test if the function actually mitigates timing
  side channel attacks.
  """
    LENGTH = 128
    string1 = misc_utils.generate_random_string(LENGTH)
    string2 = misc_utils.generate_random_string(LENGTH)
    assert string1 != string2

    # Make sure compare_secure_strings returns True and False when expected.
    assert misc_utils.compare_secure_strings(string1, string1) == True
    assert misc_utils.compare_secure_strings(string1, string2) == False
Beispiel #3
0
def generate_create_account_key():
    """
  Generates a random account creation key. Implementation is very similar to
  generate_reset_key().
  """
    chars = string.ascii_lowercase + string.digits
    return misc_utils.generate_random_string(
        constants.CREATE_ACCOUNT_KEY_LENGTH, chars=chars)
Beispiel #4
0
def generate_reset_key():
    """
  Generates a random reset key. We use only digits and lowercase letters since
  the database string comparison is case insensitive (if more entropy is
  needed, just make the string longer).
  """
    chars = string.ascii_lowercase + string.digits
    return misc_utils.generate_random_string(
        constants.PWD_RESET_KEY_LENGTH, chars=chars)
Beispiel #5
0
def test_hash_password():
    """
  Tests each hash algorithm implemented by hash_password().
  """
    PWD_LENGTH = 64
    password = misc_utils.generate_random_string(PWD_LENGTH)
    salt = auth_utils.generate_salt()

    # PBKDF2_SHA256
    rounds = 100000
    expected_result = binascii.hexlify(
        hashlib.pbkdf2_hmac('sha256', password.encode(), salt.encode(),
                            rounds)).decode()
    result = auth_utils.hash_password(password, salt, rounds, 'pbkdf2_sha256')
    assert result == expected_result

    # MD5
    expected_result = hashlib.md5((salt + password).encode()).hexdigest()
    result = auth_utils.hash_password(password, salt, None, 'md5')
    assert result == expected_result
Beispiel #6
0
def generate_salt():
    """Generates a pseudorandom salt."""
    return misc_utils.generate_random_string(constants.SALT_SIZE)
Beispiel #7
0
def process_params_request(editing, survey_id=None, access_key=None):
    if not check_permission(
            flask.session.get('username'), Permissions.SURVEYS):
        flask.abort(403)

    form = flask.request.form

    def creation_error(message):
        flask.flash(message)
        return flask.render_template(
            'survey_params.html',
            editing=editing,
            access_key=access_key,
            groups=get_groups(),
            title=form.get('title'),
            description=form.get('description'),
            start_date=form.get('start_date'),
            start_hour=form.get('start_hour'),
            start_minute=form.get('start_minute'),
            start_period=form.get('start_period'),
            end_date=form.get('end_date'),
            end_hour=form.get('end_hour'),
            end_minute=form.get('end_minute'),
            end_period=form.get('end_period'),
            public='public' in form,
            group_id=form.get('group'))

    validations = [
        validate_exists(form, 'title'),
        validate_exists(form, 'description'),
        validate_exists(form, 'start_date')
        and validate_date(form['start_date']),
        validate_exists(form, 'start_hour')
        and validate_int(form['start_hour'], 1, 12),
        validate_exists(form, 'start_minute')
        and validate_int(form['start_minute'], 0, 59),
        validate_exists(form, 'start_period')
        and validate_in(form['start_period'], AM_OR_PM),
        validate_exists(form, 'end_date') and validate_date(form['end_date']),
        validate_exists(form, 'end_hour')
        and validate_int(form['end_hour'], 1, 12),
        validate_exists(form, 'end_minute')
        and validate_int(form['end_minute'], 0, 59),
        validate_exists(form, 'end_period')
        and validate_in(form['end_period'], AM_OR_PM),
        validate_exists(form, 'group')
        and (not form['group'] or validate_int(form['group']))
    ]
    if not all(validations):
        #Should only happen if a malicious request is sent,
        #so error message is not important
        return creation_error('Invalid form data')

    start_day = datetime.strptime(form['start_date'], YYYY_MM_DD)
    start_hour = int(form['start_hour']) % 12
    if form['start_period'] == 'P': start_hour += 12
    start_minute = int(form['start_minute'])
    start = datetime(start_day.year, start_day.month, start_day.day,
                     start_hour, start_minute)
    end_day = datetime.strptime(form['end_date'], YYYY_MM_DD)
    end_hour = int(form['end_hour']) % 12
    if form['end_period'] == 'P': end_hour += 12
    end_minute = int(form['end_minute'])
    end = datetime(end_day.year, end_day.month, end_day.day, end_hour,
                   end_minute)
    if start >= end:
        return creation_error('Start must be before end')

    group = form['group']
    group = int(group) if group else None

    params = {
        'title': form['title'].strip(),
        'description': form['description'].strip() or None,
        'start_time': start,
        'end_time': end,
        'public': 'public' in form,
        'group_id': group
    }
    if survey_id:
        update_survey_params(survey_id, params)
    else:
        access_key = generate_random_string(ACCESS_KEY_LENGTH)
        params['access_key'] = access_key
        params['creator'] = get_user_id(flask.session['username'])
        query = 'INSERT INTO surveys (' + ', '.join(
            params) + ') VALUES (' + ', '.join(['%s'] * len(params)) + ')'
        with flask.g.pymysql_db.cursor() as cursor:
            cursor.execute(query, list(params.values()))
    return flask.redirect(
        flask.url_for('voting.edit_questions', access_key=access_key))