예제 #1
0
def import_receivers(store, submission, receiver_id_list):
    context = submission.context

    if not len(receiver_id_list):
        raise errors.SubmissionValidationFailure(
            "needed almost one receiver selected [1]")

    if context.maximum_selectable_receivers and \
                    len(receiver_id_list) > context.maximum_selectable_receivers:
        raise errors.InvalidInputFormat(
            "provided an invalid number of receivers")

    for receiver in store.find(models.Receiver,
                               In(models.Receiver.id, receiver_id_list)):
        if context not in receiver.contexts:
            raise errors.InvalidInputFormat(
                "forged receiver selection, you fuzzer! <:")

        if not GLSettings.memory_copy.allow_unencrypted and receiver.user.pgp_key_status != u'enabled':
            raise errors.SubmissionValidationFailure(
                "the platform does not allow selection of receivers with encryption disabled"
            )
            continue

        submission.receivers.add(receiver)

        log.debug("+receiver [%s] In tip (%s) #%d" % \
                  (receiver.user.name, submission.id, submission.receivers.count() ))
    if submission.receivers.count() == 0:
        raise errors.SubmissionValidationFailure(
            "needed almost one receiver selected [2]")
예제 #2
0
def import_receivers(store, submission, receiver_id_list):
    context = submission.context

    if not len(receiver_id_list):
        log.err("Receivers required to be selected, not empty")
        raise errors.SubmissionValidationFailure("needed almost one receiver selected")

    if context.maximum_selectable_receivers and \
                    len(receiver_id_list) > context.maximum_selectable_receivers:
        raise errors.InvalidInputFormat("provided an invalid number of receivers")

    for receiver in store.find(Receiver, In(Receiver.id, receiver_id_list)):
        if context not in receiver.contexts:
            raise errors.InvalidInputFormat("forged receiver selection, you fuzzer! <:")

        try:
            if not GLSettings.memory_copy.allow_unencrypted and \
                            receiver.pgp_key_status != u'enabled':
                log.err("Encrypted only submissions are supported. Cannot select [%s]" % receiver.id)
                continue
            submission.receivers.add(receiver)
        except Exception as excep:
            log.err("Receiver %s can't be assigned to the tip [%s]" % (receiver.id, excep))
            continue

        log.debug("+receiver [%s] In tip (%s) #%d" % \
                  (receiver.name, submission.id, submission.receivers.count() ))
    if submission.receivers.count() == 0:
        log.err("Receivers required to be selected, not empty")
        raise errors.SubmissionValidationFailure("needed at least one receiver selected [2]")
예제 #3
0
def verify_fields_recursively(fields, wb_fields):
    for f in fields:
        if f not in wb_fields:
            raise errors.SubmissionValidationFailure(
                "missing field (no structure present): %s" % f)

        if fields[f]['required'] and ('value' not in wb_fields[f]
                                      or wb_fields[f]['value'] == ''):
            raise errors.SubmissionValidationFailure(
                "missing required field (no value provided): %s" % f)

        if isinstance(wb_fields[f]['value'], unicode):
            if len(wb_fields[f]
                   ['value']) > GLSettings.memory_copy.maximum_textsize:
                raise errors.InvalidInputFormat(
                    "field value overcomes size limitation")

        indexed_fields = {}
        for f_c in fields[f]['children']:
            indexed_fields[f_c['id']] = copy.deepcopy(f_c)

        indexed_wb_fields = {}
        for f_c in wb_fields[f]['children']:
            indexed_wb_fields[f_c['id']] = copy.deepcopy(f_c)

        verify_fields_recursively(indexed_fields, indexed_wb_fields)

    for wbf in wb_fields:
        if wbf not in fields:
            raise errors.SubmissionValidationFailure(
                "provided unexpected field %s" % wbf)
예제 #4
0
def db_create_submission(store, request, uploaded_files, client_using_tor,
                         language):
    answers = request['answers']

    context = store.find(models.Context,
                         models.Context.id == request['context_id']).one()
    if not context:
        raise errors.ContextIdNotFound

    submission = models.InternalTip()

    submission.progressive = db_assign_submission_progressive(store)

    if context.tip_timetolive > -1:
        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 tor2web is used to keep track of the security level adopted by the whistleblower
    submission.tor2web = 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
    submission.enable_whistleblower_identity = context.questionnaire.enable_whistleblower_identity

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

    try:
        questionnaire = db_get_context_steps(store, context.id, None)
        questionnaire_hash = unicode(sha256(json.dumps(questionnaire)))

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

        store.add(submission)

        db_archive_questionnaire_schema(store, questionnaire,
                                        questionnaire_hash)

        db_save_questionnaire_answers(store, submission.id, answers)
    except Exception as excep:
        log.err("Submission create: fields validation fail: %s" % excep)
        raise excep

    try:
        for filedesc in uploaded_files:
            new_file = models.InternalFile()
            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.file_path = filedesc['path']
            store.add(new_file)
            log.debug("=> file associated %s|%s (%d bytes)" %
                      (new_file.name, new_file.content_type, new_file.size))
    except Exception as excep:
        log.err("Submission create: unable to create db entry for files: %s" %
                excep)
        raise excep

    receipt, wbtip = db_create_whistleblowertip(store, submission)

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

    rtips = []
    for receiver in store.find(models.Receiver,
                               In(models.Receiver.id, request['receivers'])):
        if submission.context not in receiver.contexts:
            continue

        if not GLSettings.memory_copy.allow_unencrypted and len(
                receiver.user.pgp_key_public) == 0:
            continue

        rtips.append(db_create_receivertip(store, receiver, submission))

    if len(rtips) == 0:
        raise errors.SubmissionValidationFailure("need at least one recipient")

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

    submission_dict = serialize_usertip(store, wbtip, language)

    submission_dict.update({'receipt': receipt})

    return submission_dict
예제 #5
0
def db_create_submission(store, request, uploaded_files, client_using_tor):
    answers = request['answers']

    context, questionnaire = store.find(
        (models.Context, models.Questionnaire),
        models.Context.id == request['context_id'],
        models.Questionnaire.id == models.Context.questionnaire_id).one()
    if not context:
        raise errors.ModelNotFound(models.Context)

    steps = db_get_questionnaire(store, questionnaire.id, None)['steps']
    questionnaire_hash = unicode(sha256(json.dumps(steps)))

    submission = models.InternalTip()

    submission.progressive = db_assign_submission_progressive(store)

    if context.tip_timetolive > -1:
        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 tor2web is used to keep track of the security level adopted by the whistleblower
    submission.tor2web = 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
    submission.enable_whistleblower_identity = questionnaire.enable_whistleblower_identity

    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)

    store.add(submission)

    db_archive_questionnaire_schema(store, steps, questionnaire_hash)
    db_save_questionnaire_answers(store, submission.id, answers)

    for filedesc in uploaded_files:
        new_file = models.InternalFile()
        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.file_path = filedesc['path']
        store.add(new_file)
        log.debug("=> file associated %s|%s (%d bytes)", new_file.name,
                  new_file.content_type, new_file.size)

    receipt = db_create_whistleblowertip(store, submission)

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

    rtips_count = 0
    for receiver, user, in store.find(
        (models.Receiver, models.User),
            In(models.Receiver.id, request['receivers']),
            models.ReceiverContext.receiver_id == models.Receiver.id,
            models.ReceiverContext.context_id == context.id,
            models.User.id == models.Receiver.id):
        if user.pgp_key_public or GLSettings.memory_copy.allow_unencrypted:
            db_create_receivertip(store, receiver, submission)
            rtips_count += 1

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

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

    return {'receipt': receipt}