Ejemplo n.º 1
0
    def create_key(self):
        """
        Create the AES Key to encrypt uploaded file.
        """
        self.key = os.urandom(GLSetting.AES_key_size)

        self.key_id = xeger(GLSetting.AES_key_id_regexp)
        self.keypath = os.path.join(GLSetting.ramdisk_path, "%s%s" %
                                    (GLSetting.AES_keyfile_prefix, self.key_id))

        while os.path.isfile(self.keypath):
            self.key_id = xeger(GLSetting.AES_key_id_regexp)
            self.keypath = os.path.join(GLSetting.ramdisk_path, "%s%s" %
                                    (GLSetting.AES_keyfile_prefix, self.key_id))

        self.key_counter_nonce = os.urandom(GLSetting.AES_counter_nonce)
        self.initialize_cipher()

        saved_struct = {
            'key' : self.key,
            'key_counter_nonce' : self.key_counter_nonce
        }

        log.debug("Key initialization at %s" % self.keypath)

        with open(self.keypath, 'w') as kf:
           pickle.dump(saved_struct, kf)

        if not os.path.isfile(self.keypath):
            log.err("Unable to write keyfile %s" % self.keypath)
            raise Exception("Unable to write keyfile %s" % self.keypath)
Ejemplo n.º 2
0
    def create_key(self):
        """
        Create the AES Key to encrypt uploaded file.
        """
        self.key = os.urandom(GLSetting.AES_key_size)

        self.key_id = xeger(GLSetting.AES_key_id_regexp)
        self.keypath = os.path.join(
            GLSetting.ramdisk_path,
            "%s%s" % (GLSetting.AES_keyfile_prefix, self.key_id))

        while os.path.isfile(self.keypath):
            self.key_id = xeger(GLSetting.AES_key_id_regexp)
            self.keypath = os.path.join(
                GLSetting.ramdisk_path,
                "%s%s" % (GLSetting.AES_keyfile_prefix, self.key_id))

        self.key_counter_nonce = os.urandom(GLSetting.AES_counter_nonce)
        self.initialize_cipher()

        saved_struct = {
            'key': self.key,
            'key_counter_nonce': self.key_counter_nonce
        }

        log.debug("Key initialization at %s" % self.keypath)

        with open(self.keypath, 'w') as kf:
            pickle.dump(saved_struct, kf)

        if not os.path.isfile(self.keypath):
            log.err("Unable to write keyfile %s" % self.keypath)
            raise Exception("Unable to write keyfile %s" % self.keypath)
Ejemplo n.º 3
0
    def encrypt_file(self, key_fingerprint, plainpath, filestream, output_path):
        """
        @param pgp_key_public:
        @param plainpath:
        @return:
        """
        encrypt_obj = self.pgph.encrypt_file(filestream, str(key_fingerprint))

        if not encrypt_obj.ok:
            raise errors.PGPKeyInvalid

        log.debug("Encrypting for key %s file %s (%d bytes)" %
                  (key_fingerprint,
                   plainpath, len(str(encrypt_obj))))

        encrypted_path = os.path.join(os.path.abspath(output_path),
                                      "pgp_encrypted-%s" % xeger(r'[A-Za-z0-9]{16}'))

        try:
            with open(encrypted_path, "w+") as f:
                f.write(str(encrypt_obj))

            return encrypted_path, len(str(encrypt_obj))
        except Exception as excep:
            log.err("Error in writing PGP file output: %s (%s) bytes %d" %
                    (excep.message, encrypted_path, len(str(encrypt_obj)) ))
            raise errors.InternalServerError("Error in writing [%s]" % excep.message)
Ejemplo n.º 4
0
def db_create_whistleblower_tip(store, internaltip):
    """
    The plaintext receipt is returned only now, and then is
    stored hashed in the WBtip table
    """
    wbtip = WhistleblowerTip()

    node = store.find(Node).one()

    receipt = unicode(rstr.xeger(GLSettings.receipt_regexp))

    wbtip.receipt_hash = hash_password(receipt, node.receipt_salt)
    wbtip.access_counter = 0
    wbtip.internaltip_id = internaltip.id

    store.add(wbtip)

    created_rtips = []

    for receiver in internaltip.receivers:
        rtip_id = db_create_receivertip(store, receiver, internaltip)

    internaltip.new = False

    if len(created_rtips):
        log.debug("The finalized submissions had created %d ReceiverTip(s)" %
                  len(created_rtips))

    return receipt
Ejemplo n.º 5
0
def db_create_whistleblower_tip(store, internaltip):
    """
    The plaintext receipt is returned only now, and then is
    stored hashed in the WBtip table
    """
    wbtip = WhistleblowerTip()

    node = store.find(Node).one()

    receipt = unicode(rstr.xeger(GLSettings.receipt_regexp))

    wbtip.receipt_hash = hash_password(receipt, node.receipt_salt)
    wbtip.access_counter = 0
    wbtip.internaltip_id = internaltip.id

    store.add(wbtip)

    created_rtips = []

    for receiver in internaltip.receivers:
        rtip_id = db_create_receivertip(store, receiver, internaltip)

    internaltip.new = False

    if len(created_rtips):
        log.debug("The finalized submissions had created %d ReceiverTip(s)" % len(created_rtips))

    return receipt
Ejemplo n.º 6
0
    def encrypt_file(self, key_fingerprint, plainpath, filestream, output_path):
        """
        @param pgp_key_public:
        @param plainpath:
        @return:
        """
        encrypt_obj = self.pgph.encrypt_file(filestream, str(key_fingerprint))

        if not encrypt_obj.ok:
            raise errors.PGPKeyInvalid

        log.debug("Encrypting for key %s file %s (%d bytes)" %
                  (key_fingerprint,
                   plainpath, len(str(encrypt_obj))))

        encrypted_path = os.path.join(os.path.abspath(output_path),
                                      "pgp_encrypted-%s" % xeger(r'[A-Za-z0-9]{16}'))

        try:
            with open(encrypted_path, "w+") as f:
                f.write(str(encrypt_obj))

            return encrypted_path, len(str(encrypt_obj))
        except Exception as excep:
            log.err("Error in writing PGP file output: %s (%s) bytes %d" %
                    (excep.message, encrypted_path, len(str(encrypt_obj)) ))
            raise errors.InternalServerError("Error in writing [%s]" % excep.message)
Ejemplo n.º 7
0
def get_expirations(keylist):
    """
    This function is not implemented in GPG object class because need to operate
    on the whole keys
    """
    try:
        temp_gpgroot = os.path.join(
            GLSetting.gpgroot,
            "-expiration_check-%s" % xeger(r'[A-Za-z0-9]{8}'))
        os.makedirs(temp_gpgroot, mode=0700)
        gpexpire = GPG(gnupghome=temp_gpgroot,
                       options=['--trust-model', 'always'])
    except Exception as excep:
        log.err("Unable to setup expiration check environment: %s" % excep)
        raise excep

    try:
        for key in keylist:
            gpexpire.import_keys(key)
    except Exception as excep:
        log.err("Error in GPG import_keys: %s" % excep)
        raise excep

    try:
        all_keys = gpexpire.list_keys()
    except Exception as excep:
        log.err("Error in GPG list_keys: %s" % excep)
        raise excep

    expirations = {}
    for ak in all_keys:
        expirations.update({ak['fingerprint']: ak['date']})

    return expirations
Ejemplo n.º 8
0
def get_expirations(keylist):
    """
    This function is not implemented in GPG object class because need to operate
    on the whole keys
    """
    try:
        temp_gpgroot = os.path.join(GLSetting.gpgroot, "-expiration_check-%s" % xeger(r'[A-Za-z0-9]{8}'))
        os.makedirs(temp_gpgroot, mode=0700)
        gpexpire = GPG(gnupghome=temp_gpgroot, options=['--trust-model', 'always'])
    except Exception as excep:
        log.err("Unable to setup expiration check environment: %s" % excep)
        raise excep

    try:
        for key in keylist:
            gpexpire.import_keys(key)
    except Exception as excep:
        log.err("Error in GPG import_keys: %s" % excep)
        raise excep

    try:
        all_keys = gpexpire.list_keys()
    except Exception as excep:
        log.err("Error in GPG list_keys: %s" % excep)
        raise excep

    expirations = {}
    for ak in all_keys:
        expirations.update({ak['fingerprint']: ak['date']})

    return expirations
Ejemplo n.º 9
0
    def __init__(self, receiver_desc):
        """
        every time is needed, a new keyring is created here.
        """
        if receiver_desc.has_key('gpg_key_status') and \
                        receiver_desc['gpg_key_status'] != Receiver._gpg_types[1]: # Enabled
            log.err(
                "Requested GPG initialization for a receiver without GPG configured! %s"
                % receiver_desc['username'])
            raise Exception("Requested GPG init for user without GPG [%s]" %
                            receiver_desc['username'])

        try:
            temp_gpgroot = os.path.join(GLSetting.gpgroot,
                                        "%s" % xeger(r'[A-Za-z0-9]{8}'))
            os.makedirs(temp_gpgroot, mode=0700)
            self.gpgh = GPG(gnupghome=temp_gpgroot,
                            options=['--trust-model', 'always'])
        except Exception as excep:
            log.err("Unable to instance GPG object: %s" % excep)
            raise excep

        self.receiver_desc = receiver_desc
        log.debug("GPG object initialized for receiver %s" %
                  receiver_desc['username'])
Ejemplo n.º 10
0
 def __init__(self, user_id, user_role):
     self.user_role = user_role
     self.user_id = user_id
     tempobj.TempObj.__init__(self,
                              GLSetting.sessions,
                              rstr.xeger(r'[A-Za-z0-9]{42}'),
                              GLSetting.defaults.lifetimes[user_role],
                              reactor)
Ejemplo n.º 11
0
def db_create_receiver(store, request, language):
    """
    Creates a new receiver.
    Returns:
        (dict) the configured receiver
    """

    fill_localized_keys(request, models.Receiver.localized_strings, language)

    password = request['password']
    if len(password) and password != GLSetting.default_password:
        security.check_password_format(password)
    else:
        password = GLSetting.default_password

    receiver_salt = security.get_salt(rstr.xeger('[A-Za-z0-9]{56}'))
    receiver_password = security.hash_password(password, receiver_salt)

    receiver_user_dict = {
        'username': uuid4(),
        'password': receiver_password,
        'salt': receiver_salt,
        'role': u'receiver',
        'state': u'enabled',
        'language': u"en",
        'timezone': 0,
        'password_change_needed': True,
    }

    receiver_user = models.User(receiver_user_dict)
    receiver_user.last_login = datetime_null()
    receiver_user.password_change_date = datetime_null()
    store.add(receiver_user)

    # ping_mail_address is duplicated at creation time from mail_address
    request.update({'ping_mail_address': request['mail_address']})

    receiver = models.Receiver(request)
    receiver.user = receiver_user

    # The various options related in manage GPG keys are used here.
    gpg_options_parse(receiver, request)

    log.debug("Creating receiver %s" % receiver.user.username)

    store.add(receiver)

    create_random_receiver_portrait(receiver.id)

    contexts = request.get('contexts', [])
    for context_id in contexts:
        context = models.Context.get(store, context_id)
        if not context:
            log.err("Creation error: invalid Context can't be associated")
            raise errors.ContextIdNotFound
        context.receivers.add(receiver)

    return admin_serialize_receiver(receiver, language)
Ejemplo n.º 12
0
def db_create_receiver(store, request, language):
    """
    Creates a new receiver.
    Returns:
        (dict) the configured receiver
    """
    fill_localized_keys(request, models.Receiver.localized_strings, language)

    password = request['password']
    if len(password) and password != GLSettings.default_password:
        security.check_password_format(password)
    else:
        password = GLSettings.default_password

    receiver_salt = security.get_salt(rstr.xeger('[A-Za-z0-9]{56}'))
    receiver_password = security.hash_password(password, receiver_salt)

    # ping_mail_address is duplicated at creation time from mail_address
    request.update({'ping_mail_address': request['mail_address']})

    receiver = models.Receiver(request)

    receiver_user_dict = {
        'username': uuid4(),
        'password': receiver_password,
        'salt': receiver_salt,
        'role': u'receiver',
        'state': u'enabled',
        'language': u'en',
        'timezone': 0,
        'password_change_needed': True,
        'mail_address': request['mail_address']
    }

    receiver_user = models.User(receiver_user_dict)

    # The various options related in manage PGP keys are used here.
    pgp_options_parse(receiver, request)

    # Set receiver.id = receiver.user.username = receiver.user.id
    receiver.id = receiver_user.username = receiver_user.id

    store.add(receiver_user)
    store.add(receiver)

    create_random_receiver_portrait(receiver.id)

    contexts = request.get('contexts', [])
    for context_id in contexts:
        context = models.Context.get(store, context_id)
        if not context:
            log.err("Creation error: invalid Context can't be associated")
            raise errors.ContextIdNotFound
        context.receivers.add(receiver)

    log.debug("Created receiver %s" % receiver.user.username)

    return admin_serialize_receiver(receiver, language)
Ejemplo n.º 13
0
 def __init__(self, user_id, user_role, user_status):
     self.user_role = user_role
     self.user_id = user_id
     self.user_role = user_role
     self.user_status = user_status
     tempobj.TempObj.__init__(self, GLSetting.sessions,
                              rstr.xeger(r'[A-Za-z0-9]{42}'),
                              GLSetting.defaults.lifetimes[user_role],
                              reactor)
Ejemplo n.º 14
0
 def __init__(self, user_id, user_role, user_status):
     self.user_role = user_role
     self.user_id = user_id
     self.user_role = user_role
     self.user_status = user_status
     tempobj.TempObj.__init__(self,
                              GLSettings.sessions,
                              rstr.xeger(r'[A-Za-z0-9]{42}'),
                              GLSettings.defaults.lifetimes[user_role],
                              reactor_override)
Ejemplo n.º 15
0
def generate_example_receipt(regexp):
    """
    @param regexp:
    @return:

    this function it's used to show to the Admin an example of the
    receipt_regexp configured, and if an error happen, it's
    works as validator.
    The exception is raised over and a default regexp is put
    """
    return unicode(rstr.xeger(regexp))
Ejemplo n.º 16
0
def generate_example_receipt(regexp):
    """
    @param regexp:
    @return:

    this function it's used to show to the Admin an example of the
    receipt_regexp configured, and if an error happen, it's
    works as validator.
    The exception is raised over and a default regexp is put
    """
    return unicode(rstr.xeger(regexp))
Ejemplo n.º 17
0
def init_db(store, result, node_dict, appdata_dict):
    """
    TODO refactor with languages the email_template, develop a dedicated
    function outside the node, and inquire f*****g YHWH about the
    callbacks existence/usage
    """

    node = models.Node(node_dict)
    node.languages_enabled = GLSetting.defaults.languages_enabled
    node.receipt_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}'))
    node.wizard_done = GLSetting.skip_wizard

    for k in appdata_dict['node']:
        setattr(node, k, appdata_dict['node'][k])

    store.add(node)

    admin_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}'))
    admin_password = hash_password(u"globaleaks", admin_salt)

    admin_dict = {
        'username': u'admin',
        'password': admin_password,
        'salt': admin_salt,
        'role': u'admin',
        'state': u'enabled',
        'language': u"en",
        'timezone': 0,
        'password_change_needed': False,
    }

    admin = models.User(admin_dict)
    store.add(admin)

    notification = models.Notification()
    for k in appdata_dict['templates']:
        setattr(notification, k, appdata_dict['templates'][k])

    store.add(notification)
Ejemplo n.º 18
0
 def __init__(self):
     """
     every time is needed, a new keyring is created here.
     """
     try:
         temp_gpgroot = os.path.join(GLSetting.gpgroot,
                                     "%s" % xeger(r'[A-Za-z0-9]{8}'))
         os.makedirs(temp_gpgroot, mode=0700)
         self.gpgh = GPG(gnupghome=temp_gpgroot,
                         options=['--trust-model', 'always'])
         self.gpgh.encoding = "UTF-8"
     except Exception as excep:
         log.err("Unable to instance GPG object: %s" % excep)
         raise excep
Ejemplo n.º 19
0
    def __init__(self, token_kind, context_id):
        """
        token_kind assumes currently only value 'submission.

        we plan to add other kinds like 'file'.

        """

        if reactor_override:
            reactor = reactor_override
        else:
            reactor = None

        self.kind = token_kind

        # both 'validity' variables need to be expressed in seconds
        self.start_validity_secs = GLSettings.memory_copy.submission_minimum_delay
        self.end_validity_secs = GLSettings.memory_copy.submission_maximum_ttl

        # Remind: this is just for developers, because if a clean house
        # is a sign of a waste life, a Token object without shortcut
        # is a sign of a psycho life. (vecnish!)
        if GLSettings.devel_mode:
            self.start_validity_secs = 0

        self.remaining_allowed_attempts = Token.MAXIMUM_ATTEMPTS_PER_TOKEN

        # creation_date of token assignment
        self.creation_date = datetime.utcnow()

        # in the future, difficulty can be trimmed on context basis too
        self.context_associated = context_id

        # to keep track of the file uploaded associated
        self.uploaded_files = []

        self.token_id = rstr.xeger(r'[A-Za-z0-9]{42}')

        # initialization
        self.human_captcha = False
        self.graph_captcha = False
        self.proof_of_work = False

        TempObj.__init__(self,
                         TokenList.token_dict,
                         # token ID:
                         self.token_id,
                         # seconds of validity:
                         self.start_validity_secs + self.end_validity_secs,
                         reactor)
Ejemplo n.º 20
0
 def __init__(self):
     """
     every time is needed, a new keyring is created here.
     """
     try:
         temp_pgproot = os.path.join(GLSettings.pgproot, "%s" % xeger(r'[A-Za-z0-9]{8}'))
         os.makedirs(temp_pgproot, mode=0700)
         self.pgph = GPG(gnupghome=temp_pgproot, options=['--trust-model', 'always'])
         self.pgph.encoding = "UTF-8"
     except OSError as ose:
         log.err("Critical, OS error in operating with GnuPG home: %s" % ose)
         raise
     except Exception as excep:
         log.err("Unable to instance PGP object: %s" % excep)
         raise
Ejemplo n.º 21
0
def init_db(store, result, node_dict, appdata_dict):
    """
    """
    node = models.Node(node_dict)
    node.languages_enabled = GLSettings.defaults.languages_enabled
    node.receipt_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}'))
    node.wizard_done = GLSettings.skip_wizard

    for k in appdata_dict['node']:
        setattr(node, k, appdata_dict['node'][k])

    store.add(node)

    admin_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}'))
    admin_password = hash_password(u"globaleaks", admin_salt)

    admin_dict = {
        'username': u'admin',
        'password': admin_password,
        'salt': admin_salt,
        'role': u'admin',
        'state': u'enabled',
        'mail_address': u'',
        'language': u"en",
        'timezone': 0,
        'password_change_needed': False,
    }

    admin = models.User(admin_dict)
    store.add(admin)

    notification = models.Notification()
    for k in appdata_dict['templates']:
        setattr(notification, k, appdata_dict['templates'][k])

    store.add(notification)
Ejemplo n.º 22
0
def init_db(store, result, node_dict, appdata_dict):
    """
    """
    node = models.Node(node_dict)
    node.languages_enabled = GLSettings.defaults.languages_enabled
    node.receipt_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}'))
    node.wizard_done = GLSettings.skip_wizard

    for k in appdata_dict['node']:
        setattr(node, k, appdata_dict['node'][k])

    store.add(node)

    admin_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}'))
    admin_password = hash_password(u"globaleaks", admin_salt)

    admin_dict = {
        'username': u'admin',
        'password': admin_password,
        'salt': admin_salt,
        'role': u'admin',
        'state': u'enabled',
        'mail_address': u'',
        'language': u"en",
        'timezone': 0,
        'password_change_needed': False,
    }

    admin = models.User(admin_dict)
    store.add(admin)

    notification = models.Notification()
    for k in appdata_dict['templates']:
        setattr(notification, k, appdata_dict['templates'][k])

    store.add(notification)
Ejemplo n.º 23
0
 def __init__(self):
     """
     every time is needed, a new keyring is created here.
     """
     try:
         temp_pgproot = os.path.join(GLSettings.pgproot, "%s" % xeger(r'[A-Za-z0-9]{8}'))
         os.makedirs(temp_pgproot, mode=0700)
         self.pgph = GPG(gnupghome=temp_pgproot, options=['--trust-model', 'always'])
         self.pgph.encoding = "UTF-8"
     except OSError as ose:
         log.err("Critical, OS error in operating with GnuPG home: %s" % ose)
         raise
     except Exception as excep:
         log.err("Unable to instance PGP object: %s" % excep)
         raise
Ejemplo n.º 24
0
    def encrypt_file(self, plainpath, filestream, output_path):
        """
        @param gpg_key_armor:
        @param plainpath:
        @return:
        """
        if not self.validate_key(self.receiver_desc['gpg_key_armor']):
            raise errors.GPGKeyInvalid

        encrypt_obj = self.gpgh.encrypt_file(
            filestream, str(self.receiver_desc['gpg_key_fingerprint']))

        if not encrypt_obj.ok:
            # continue here if is not ok
            log.err("Falure in encrypting file %s %s (%s)" %
                    (plainpath, self.receiver_desc['username'],
                     self.receiver_desc['gpg_key_fingerprint']))
            log.err(encrypt_obj.stderr)
            raise errors.GPGKeyInvalid

        log.debug("Encrypting for %s (%s) file %s (%d bytes)" %
                  (self.receiver_desc['username'],
                   self.receiver_desc['gpg_key_fingerprint'], plainpath,
                   len(str(encrypt_obj))))

        encrypted_path = os.path.join(
            os.path.abspath(output_path),
            "gpg_encrypted-%s" % xeger(r'[A-Za-z0-9]{8}'))

        if os.path.isfile(encrypted_path):
            log.err("Unexpected unpredictable unbelievable error! %s" %
                    encrypted_path)
            raise errors.InternalServerError(
                "File conflict in GPG encrypted output")

        try:
            with open(encrypted_path, "w+") as f:
                f.write(str(encrypt_obj))

            return encrypted_path, len(str(encrypt_obj))

        except Exception as excep:
            log.err("Error in writing GPG file output: %s (%s) bytes %d" %
                    (excep.message, encrypted_path, len(str(encrypt_obj))))
            raise errors.InternalServerError("Error in writing [%s]" %
                                             excep.message)
Ejemplo n.º 25
0
    def __init__(self, token_kind, uses=MAX_USES):
        """
        token_kind assumes currently only value 'submission.

        we plan to add other kinds like 'file'.

        """

        if reactor_override:
            reactor = reactor_override
        else:
            reactor = None

        self.kind = token_kind

        # both 'validity' variables need to be expressed in seconds
        self.start_validity_secs = GLSettings.memory_copy.submission_minimum_delay
        self.end_validity_secs = GLSettings.memory_copy.submission_maximum_ttl

        # Remind: this is just for developers, because if a clean house
        # is a sign of a waste life, a Token object without shortcut
        # is a sign of a psycho life. (vecnish!)
        if GLSettings.devel_mode:
            self.start_validity_secs = 0

        self.remaining_uses = uses

        self.generate_token_challenge()

        # creation_date of token assignment
        self.creation_date = datetime.utcnow()

        # to keep track of the file uploaded associated
        self.uploaded_files = []

        self.id = rstr.xeger(r'[A-Za-z0-9]{42}')

        TempObj.__init__(
            self,
            TokenList.token_dict,
            # token ID:
            self.id,
            # seconds of validity:
            self.start_validity_secs + self.end_validity_secs,
            reactor)
Ejemplo n.º 26
0
def generate_example_receipt(regexp):
    """
    @param regexp:
    @return:

    this function it's used to show to the Admin an example of the
    receipt_regexp configured, and if an error happen, it's
    works as validator.
    """
    Random.atfork()

    try:
        return_value_receipt = unicode(rstr.xeger(regexp))
    except Exception as excep:
        log.err("Invalid receipt regexp: %s (%s)" % (regexp, excep) )
        raise errors.InvalidReceiptRegexp

    return return_value_receipt
Ejemplo n.º 27
0
def db_create_whistleblower_tip(store, submission_desc):
    """
    The plaintext receipt is returned only now, and then is
    stored hashed in the WBtip table
    """
    wbtip = WhistleblowerTip()

    node = store.find(Node).one()

    return_value_receipt = unicode(rstr.xeger(node.receipt_regexp))
    wbtip.receipt_hash = security.hash_password(return_value_receipt,
                                                node.receipt_salt)

    wbtip.access_counter = 0
    wbtip.internaltip_id = submission_desc['id']
    store.add(wbtip)

    return return_value_receipt
Ejemplo n.º 28
0
def db_create_whistleblower_tip(store, submission_desc):
    """
    The plaintext receipt is returned only now, and then is
    stored hashed in the WBtip table
    """
    wbtip = WhistleblowerTip()

    node = store.find(Node).one()

    receipt = unicode(rstr.xeger(GLSetting.receipt_regexp))

    wbtip.receipt_hash = security.hash_password(receipt, node.receipt_salt)
    wbtip.access_counter = 0
    wbtip.internaltip_id = submission_desc['id']

    store.add(wbtip)

    return receipt
Ejemplo n.º 29
0
    def __init__(self, token_kind, uses = MAX_USES):
        """
        token_kind assumes currently only value 'submission.

        we plan to add other kinds like 'file'.

        """

        if reactor_override:
            reactor = reactor_override
        else:
            reactor = None

        self.kind = token_kind

        # both 'validity' variables need to be expressed in seconds
        self.start_validity_secs = GLSettings.memory_copy.submission_minimum_delay
        self.end_validity_secs = GLSettings.memory_copy.submission_maximum_ttl

        # Remind: this is just for developers, because if a clean house
        # is a sign of a waste life, a Token object without shortcut
        # is a sign of a psycho life. (vecnish!)
        if GLSettings.devel_mode:
            self.start_validity_secs = 0

        self.remaining_uses = uses

        self.generate_token_challenge()

        # creation_date of token assignment
        self.creation_date = datetime.utcnow()

        # to keep track of the file uploaded associated
        self.uploaded_files = []

        self.id = rstr.xeger(r'[A-Za-z0-9]{42}')

        TempObj.__init__(self,
                         TokenList.token_dict,
                         # token ID:
                         self.id,
                         # seconds of validity:
                         self.start_validity_secs + self.end_validity_secs,
                         reactor)
Ejemplo n.º 30
0
def create_whistleblower_tip(store, submission_desc):
    """
    The plaintext receipt is returned only now, and then is
    stored hashed in the WBtip table
    """
    assert submission_desc is not None and submission_desc.has_key("id")

    wbtip = WhistleblowerTip()

    node = store.find(Node).one()

    return_value_receipt = unicode(rstr.xeger(node.receipt_regexp))
    wbtip.receipt_hash = security.hash_password(return_value_receipt, node.receipt_salt)

    wbtip.access_counter = 0
    wbtip.internaltip_id = submission_desc["id"]
    store.add(wbtip)

    return return_value_receipt
Ejemplo n.º 31
0
    def __init__(self, receiver_desc):
        """
        every time is needed, a new keyring is created here.
        """
        if receiver_desc.has_key('gpg_key_status') and \
                        receiver_desc['gpg_key_status'] != Receiver._gpg_types[1]: # Enabled
            log.err("Requested GPG initialization for a receiver without GPG configured! %s" %
                    receiver_desc['username'])
            raise Exception("Requested GPG init for user without GPG [%s]" % receiver_desc['username'])

        try:
            temp_gpgroot = os.path.join(GLSetting.gpgroot, "%s" % xeger(r'[A-Za-z0-9]{8}'))
            os.makedirs(temp_gpgroot, mode=0700)
            self.gpgh = GPG(gnupghome=temp_gpgroot, options=['--trust-model', 'always'])
        except Exception as excep:
            log.err("Unable to instance GPG object: %s" % excep)
            raise excep

        self.receiver_desc = receiver_desc
        log.debug("GPG object initialized for receiver %s" % receiver_desc['username'])
Ejemplo n.º 32
0
    def encrypt_file(self, plainpath, filestream, output_path):
        """
        @param gpg_key_armor:
        @param plainpath:
        @return:
        """
        if not self.validate_key(self.receiver_desc['gpg_key_armor']):
            raise errors.GPGKeyInvalid

        encrypt_obj = self.gpgh.encrypt_file(filestream, str(self.receiver_desc['gpg_key_fingerprint']))

        if not encrypt_obj.ok:
            # continue here if is not ok
            log.err("Falure in encrypting file %s %s (%s)" % ( plainpath,
                                                               self.receiver_desc['username'],
                                                               self.receiver_desc['gpg_key_fingerprint']))
            log.err(encrypt_obj.stderr)
            raise errors.GPGKeyInvalid

        log.debug("Encrypting for %s (%s) file %s (%d bytes)" %
                  (self.receiver_desc['username'], self.receiver_desc['gpg_key_fingerprint'],
                   plainpath, len(str(encrypt_obj))))

        encrypted_path = os.path.join(os.path.abspath(output_path),
                                      "gpg_encrypted-%s" % xeger(r'[A-Za-z0-9]{8}'))

        if os.path.isfile(encrypted_path):
            log.err("Unexpected unpredictable unbelievable error! %s" % encrypted_path)
            raise errors.InternalServerError("File conflict in GPG encrypted output")

        try:
            with open(encrypted_path, "w+") as f:
                f.write(str(encrypt_obj))

            return encrypted_path, len(str(encrypt_obj))

        except Exception as excep:
            log.err("Error in writing GPG file output: %s (%s) bytes %d" %
                    (excep.message, encrypted_path, len(str(encrypt_obj)) ))
            raise errors.InternalServerError("Error in writing [%s]" % excep.message)
Ejemplo n.º 33
0
    def generate_session(self, role, user_id):
        """
        Args:
            role: can be either 'admin', 'wb' or 'receiver'

            user_id: will be in the case of the receiver the receiver.id in the
                case of an admin it will be set to 'admin', in the case of the
                'wb' it will be the whistleblower id.
        """
        self.session_id = rstr.xeger(r'[A-Za-z0-9]{42}')

        # This is the format to preserve sessions in memory
        # Key = session_id, values "last access" "id" "role"
        new_session = OD(
               refreshdate=utility.datetime_now(),
               id=self.session_id,
               role=role,
               user_id=user_id,
               expirydate=utility.get_future_epoch(seconds=GLSetting.defaults.lifetimes[role])
        )
        GLSetting.sessions[self.session_id] = new_session
        return self.session_id
Ejemplo n.º 34
0
def dump_file_fs(uploaded_file):
    """
    @param files: a file
    @return: three variables:
        #0 a filepath linking the filename with the random
             filename saved in the disk
        #1 SHA256 checksum of the file
        #3 size in bytes of the files
    """
    from Crypto.Random import atfork

    atfork()

    saved_name = rstr.xeger(r"[A-Za-z]{26}")
    filelocation = os.path.join(GLSetting.submission_path, saved_name)

    log.debug(
        "Start saving %d bytes from file [%s]" % (uploaded_file["body_len"], uploaded_file["filename"].encode("utf-8"))
    )

    # checksum is computed here, because don't slow down the operation
    # enough to postpone in a scheduled job.
    # https://github.com/globaleaks/GlobaLeaks/issues/600

    sha = SHA256.new()
    with open(filelocation, "w+") as fd:
        uploaded_file["body"].seek(0, 0)

        data = uploaded_file["body"].read()  # 4kb
        total_length = 0

        while data != "":
            total_length = total_length + len(data)
            sha.update(data)
            os.write(fd.fileno(), data)
            data = uploaded_file["body"].read(4096)  # 4kb

    return (saved_name, sha.hexdigest(), total_length)
Ejemplo n.º 35
0
def create_whistleblower_tip(store, submission_desc):
    """
    The plaintext receipt is returned only now, and then is
    stored hashed in the WBtip table
    """
    from Crypto import Random
    Random.atfork()

    assert submission_desc is not None and submission_desc.has_key('id')

    wbtip = WhistleblowerTip()

    context = store.find(Context, Context.id == submission_desc['context_gus']).one()

    return_value_receipt = unicode( rstr.xeger(context.receipt_regexp) )
    node = store.find(Node).one()
    wbtip.receipt_hash = security.hash_password(return_value_receipt, node.receipt_salt)

    wbtip.access_counter = 0
    wbtip.internaltip_id = submission_desc['id']
    store.add(wbtip)

    return return_value_receipt
Ejemplo n.º 36
0
    def migrate_InternalFile(self):
        print "%s InternalFile migration assistant" % self.std_fancy

        old_objs = self.store_old.find(self.get_right_model(
            "InternalFile", 22))

        for old_obj in old_objs:
            new_obj = self.get_right_model("InternalFile", 23)()
            for _, v in new_obj._storm_columns.iteritems():
                if v.name == 'processing_attempts':
                    new_obj.processing_attempts = 0
                    continue

                if v.name == 'file_path':
                    new_obj.file_path = os.path.join(
                        GLSettings.submission_path,
                        "%s.aes" % xeger(r'[A-Za-z0-9]{16}'))
                    continue

                setattr(new_obj, v.name, getattr(old_obj, v.name))

            self.store_new.add(new_obj)

        self.store_new.commit()
Ejemplo n.º 37
0
def initialize_node(store, results, only_node, appdata):
    """
    TODO refactor with languages the email_template, develop a dedicated
    function outside the node, and inquire f*****g YHWH about the
    callbacks existence/usage
    """

    node = models.Node(only_node)

    log.debug("Inizializing ApplicationData")

    new_appdata = ApplicationData()
    new_appdata.fields = appdata['fields']
    new_appdata.version = appdata['version']
    store.add(new_appdata)

    for k in appdata['node']:
        setattr(node, k, appdata['node'][k])

    node.languages_enabled = GLSetting.defaults.languages_enabled

    node.receipt_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}'))

    node.wizard_done = GLSetting.skip_wizard

    node.creation_date = datetime_now()

    store.add(node)

    admin_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}'))
    admin_password = hash_password(u"globaleaks", admin_salt)

    admin_dict = {
        'username': u'admin',
        'password': admin_password,
        'salt': admin_salt,
        'role': u'admin',
        'state': u'enabled',
        'language': u"en",
        'timezone': 0,
        'password_change_needed': False,
    }

    admin = models.User(admin_dict)

    admin.last_login = datetime_null()
    admin.password_change_date = datetime_null()

    store.add(admin)

    notification = models.Notification()

    # our defaults for free, because we're like Gandhi of the mail accounts.
    notification.server = "mail.headstrong.de"
    notification.port = 587
    # port 587/SMTP-TLS or 465/SMTPS
    notification.username = "******"
    notification.password = "******"
    notification.security = "TLS"

    notification.source_name = "Default GlobaLeaks sender"
    notification.source_email = notification.username

    # Those fields are sets as default in order to show to the Admin the various
    # 'variables' used in the template.

    for k in appdata['templates']:

        # Todo handle pgp_expiration_alert and pgp_expiration_notice already included in client/app/data/txt
        # and internationalized with right support on backend db.
        if k in appdata['templates']:
            setattr(notification, k, appdata['templates'][k])

    # Todo handle pgp_expiration_alert and pgp_expiration_notice already included in client/app/data/txt
    # and internationalized with right support on backend db.

    store.add(notification)
Ejemplo n.º 38
0
def initialize_node(store, results, only_node, templates, appdata):
    """
    TODO refactor with languages the email_template, develop a dedicated
    function outside the node, and inquire f*****g YHWH about the
    callbacks existence/usage
    """

    node = models.Node(only_node)

    log.debug("Inizializing ApplicationData")

    new_appdata = ApplicationData()
    new_appdata.fields = appdata['fields']
    new_appdata.version = appdata['version']
    store.add(new_appdata)

    if 'node_presentation' in appdata:
        node.presentation = appdata['node_presentation']

    if 'node_footer' in appdata:
        node.footer = appdata['node_footer']

    if 'node_subtitle' in appdata:
        node.subtitle = appdata['node_subtitle']

    node.languages_enabled = GLSetting.defaults.languages_enabled

    node.receipt_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}'))

    node.wizard_done = GLSetting.skip_wizard

    node.creation_date = datetime_now()

    store.add(node)

    admin_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}'))
    admin_password = hash_password(u"globaleaks", admin_salt)

    admin_dict = {
        'username': u'admin',
        'password': admin_password,
        'salt': admin_salt,
        'role': u'admin',
        'state': u'enabled',
    }

    admin = models.User(admin_dict)

    admin.last_login = datetime_null()

    store.add(admin)

    notification = models.Notification()

    # our defaults for free, because we're like Gandhi of the mail accounts.
    notification.server = "mail.headstrong.de"
    notification.port = 587
    # port 587/SMTP-TLS or 465/SMTPS
    notification.username = "******"
    notification.password = "******"
    notification.security = "TLS"

    notification.source_name = "Default GlobaLeaks sender"
    notification.source_email = notification.username

    # Those fields are sets as default in order to show to the Admin the various
    # 'variables' used in the template.
    notification.encrypted_tip_template = {
        GLSetting.memory_copy.default_language: templates['encrypted_tip']
    }
    notification.encrypted_tip_mail_title = {
        GLSetting.memory_copy.default_language:
        "[Tip %TipNum%] for %ReceiverName% in %ContextName%: new Tip (Encrypted)"
    }

    notification.plaintext_tip_template = {
        GLSetting.memory_copy.default_language: templates['plaintext_tip']
    }
    notification.plaintext_tip_mail_title = {
        GLSetting.memory_copy.default_language:
        "[Tip %TipNum%] for %ReceiverName% in %ContextName%: new ClearText"
    }

    notification.encrypted_message_template = {
        GLSetting.memory_copy.default_language: templates['encrypted_message']
    }
    notification.encrypted_message_mail_title = {
        GLSetting.memory_copy.default_language:
        "[Tip %TipNum%] for %ReceiverName% in %ContextName%: New message (Encrypted)"
    }

    notification.plaintext_message_template = {
        GLSetting.memory_copy.default_language: templates['plaintext_message']
    }
    notification.plaintext_message_mail_title = {
        GLSetting.memory_copy.default_language:
        "[Tip %TipNum%] for %ReceiverName% in %ContextName%: New message"
    }

    notification.encrypted_file_template = {
        GLSetting.memory_copy.default_language: templates['encrypted_file']
    }
    notification.encrypted_file_mail_title = {
        GLSetting.memory_copy.default_language:
        "[Tip %TipNum%] for %ReceiverName% in %ContextName%: File attached (Encrypted)"
    }

    notification.plaintext_file_template = {
        GLSetting.memory_copy.default_language: templates['plaintext_file']
    }
    notification.plaintext_file_mail_title = {
        GLSetting.memory_copy.default_language:
        "[Tip %TipNum%] for %ReceiverName% in %ContextName%: File attached"
    }

    notification.encrypted_comment_template = {
        GLSetting.memory_copy.default_language: templates['encrypted_comment']
    }
    notification.encrypted_comment_mail_title = {
        GLSetting.memory_copy.default_language:
        "[Tip %TipNum%] for %ReceiverName% in %ContextName%: New comment (Encrypted)"
    }

    notification.plaintext_comment_template = {
        GLSetting.memory_copy.default_language: templates['plaintext_comment']
    }
    notification.plaintext_comment_mail_title = {
        GLSetting.memory_copy.default_language:
        "[Tip %TipNum%] for %ReceiverName% in %ContextName%: New comment"
    }

    notification.zip_description = {
        GLSetting.memory_copy.default_language: templates['zip_collection']
    }

    store.add(notification)
Ejemplo n.º 39
0
    def migrate_InternalFile(self):
        print "%s InternalFile migration assistant" % self.std_fancy

        old_objs = self.store_old.find(self.get_right_model("InternalFile", 22))

        for old_obj in old_objs:
            new_obj = self.get_right_model("InternalFile", 23)()
            for _, v in new_obj._storm_columns.iteritems():
                if v.name == 'processing_attempts':
                    new_obj.processing_attempts = 0
                    continue

                if v.name == 'file_path':
                    new_obj.file_path = os.path.join(GLSettings.submission_path, "%s.aes" % xeger(r'[A-Za-z0-9]{16}'))
                    continue

                setattr(new_obj, v.name, getattr(old_obj, v.name))

            self.store_new.add(new_obj)

        self.store_new.commit()
Ejemplo n.º 40
0
def initialize_node(store, results, only_node, email_templates):
    """
    TODO refactor with languages the email_template, develop a dedicated
    function outside the node, and inquire f*****g YHWH about the
    callbacks existence/usage
    """
    from Crypto import Random

    Random.atfork()

    node = models.Node(only_node)

    # by default, only english is the surely present language
    node.languages_enabled = GLSetting.defaults.languages_enabled

    node.receipt_salt = get_salt(rstr.xeger("[A-Za-z0-9]{56}"))

    node.creation_date = datetime_now()
    store.add(node)

    admin_salt = get_salt(rstr.xeger("[A-Za-z0-9]{56}"))
    admin_password = hash_password(u"globaleaks", admin_salt)

    admin_dict = {
        "username": u"admin",
        "password": admin_password,
        "salt": admin_salt,
        "role": u"admin",
        "state": u"enabled",
        "failed_login_count": 0,
    }

    admin = models.User(admin_dict)

    admin.last_login = datetime_null()

    store.add(admin)

    notification = models.Notification()

    # our defaults for free, because we're like Gandhi of the mail accounts.
    notification.server = "mail.headstrong.de"
    notification.port = 587
    # port 587/SMTP-TLS or 465/SMTPS
    notification.username = "******"
    notification.password = "******"
    notification.security = "TLS"

    notification.source_name = "Default GlobaLeaks sender"
    notification.source_email = notification.username

    # Those fields are sets as default in order to show to the Admin the various 'variables'
    # used in the template.
    notification.tip_template = {GLSetting.memory_copy.default_language: email_templates["tip"]}
    notification.tip_mail_title = {GLSetting.memory_copy.default_language: "From %NodeName% a new Tip"}
    notification.file_template = {GLSetting.memory_copy.default_language: email_templates["file"]}
    notification.file_mail_title = {
        GLSetting.memory_copy.default_language: "From %NodeName% a new file appended to a tip"
    }
    notification.comment_template = {GLSetting.memory_copy.default_language: email_templates["comment"]}
    notification.comment_mail_title = {GLSetting.memory_copy.default_language: "From %NodeName% a new comment"}
    notification.activation_template = {GLSetting.memory_copy.default_language: "*Not Yet implemented*"}
    notification.activation_mail_title = {GLSetting.memory_copy.default_language: "**Not Yet implemented"}

    store.add(notification)
Ejemplo n.º 41
0
def db_create_receiver(store, request, language=GLSetting.memory_copy.default_language):
    """
    Creates a new receiver.
    Returns:
        (dict) the configured receiver
    """

    mo = structures.Rosetta()
    mo.acquire_request(language, request, Receiver)
    for attr in mo.get_localized_attrs():
        request[attr] = mo.get_localized_dict(attr)

    mail_address = request['mail_address']

    # Pretend that username is unique:
    homonymous = store.find(User, User.username == mail_address).count()
    if homonymous:
        log.err("Creation error: already present receiver with the requested username: %s" % mail_address)
        raise errors.ExpectedUniqueField('mail_address', mail_address)

    password = request.get('password')

    security.check_password_format(password)
    receiver_salt = security.get_salt(rstr.xeger('[A-Za-z0-9]{56}'))
    receiver_password = security.hash_password(password, receiver_salt)

    receiver_user_dict = {
            'username': mail_address,
            'password': receiver_password,
            'salt': receiver_salt,
            'role': u'receiver',
            'state': u'enabled',
    }

    receiver_user = models.User(receiver_user_dict)
    receiver_user.last_login = datetime_null()
    store.add(receiver_user)

    receiver = Receiver(request)
    receiver.user = receiver_user

    receiver.mail_address = mail_address
    receiver.tags = request['tags']

    # The various options related in manage GPG keys are used here.
    gpg_options_parse(receiver, request)

    log.debug("Creating receiver %s" % receiver.user.username)

    store.add(receiver)

    create_random_receiver_portrait(receiver.id)

    contexts = request.get('contexts', [])
    for context_id in contexts:
        context = store.find(Context, Context.id == context_id).one()
        if not context:
            log.err("Creation error: invalid Context can't be associated")
            raise errors.ContextIdNotFound
        context.receivers.add(receiver)

    return admin_serialize_receiver(receiver, language)
Ejemplo n.º 42
0
    def operation(self):
        """
        Goal of this function is to process/validate files, compute their checksums and
        apply the configured delivery method.
        """
        try:
            # ==> Submission && Escalation
            info_created_tips = yield tip_creation()
            if info_created_tips:
                log.debug("Delivery job: created %d tips" %
                          len(info_created_tips))
        except Exception as excep:
            log.err("Exception in asyncronous delivery job: %s" % excep)
            sys.excepthook(*sys.exc_info())

        # ==> Files && Files update,
        #     InternalFile is set as 'locked' status
        #     and would be unlocked at the end.
        # TODO xxx limit of file number per operation
        filemap = yield receiverfile_planning()
        # the function returns a dict of lists with dicts:
        # {
        #     'ifile_path' : [
        #       { 'receiver' : receiver_desc, 'path': file_path,
        #                           'size' : file_size, 'status': XXX },
        #       { 'receiver' : receiver_desc, 'path': file_path,
        #                           'size' : file_size, 'status': YYY }, ... ]
        # },  { }, ...
        #

        if not filemap:
            return

        # Here the files received are encrypted (if the receiver has PGP key)
        log.debug("Delivery task: Iterate over %d ReceiverFile(s)" %
                  len(filemap.keys()))

        for ifile_path, receivermap in filemap.iteritems():

            plain_path = os.path.join(GLSetting.submission_path,
                                      "%s.plain" % xeger(r'[A-Za-z0-9]{16}'))

            create_plaintextfile = encrypt_where_available(receivermap)

            for rfileinfo in receivermap:

                if not create_plaintextfile and rfileinfo[
                        'status'] == u'reference':
                    rfileinfo['path'] = plain_path

                try:
                    yield receiverfile_create(ifile_path, rfileinfo['path'],
                                              rfileinfo['status'],
                                              rfileinfo['size'],
                                              rfileinfo['receiver'])
                except Exception as excep:
                    log.err(
                        "Unable to create ReceiverFile from %s for %s: %s" %
                        (ifile_path, rfileinfo['receiver']['name'], excep))
                    continue

            if not create_plaintextfile:
                log.debug(
                    ":( NOT all receivers support PGP and the system allows plaintext version of files: %s saved in plaintext file %s"
                    % (ifile_path, plain_path))

                try:
                    with open(plain_path, "wb") as plain_f_is_sad_f, \
                         GLSecureFile(ifile_path) as encrypted_file:

                        chunk_size = 4096
                        while True:
                            chunk = encrypted_file.read(chunk_size)
                            if len(chunk) == 0:
                                break
                            plain_f_is_sad_f.write(chunk)

                    yield do_final_internalfile_update(ifile_path, u'ready',
                                                       plain_path)

                except Exception as excep:
                    log.err("Unable to create plaintext file %s: %s" %
                            (plain_path, excep))

            else:  # create_plaintextfile
                log.debug(
                    "All Receivers support PGP or the system denys plaintext version of files: marking internalfile as removed"
                )
                yield do_final_internalfile_update(ifile_path,
                                                   u'delivered')  # Removed

            # the original AES file need always to be deleted
            log.debug("Deleting the submission AES encrypted file: %s" %
                      ifile_path)
            try:
                os.remove(ifile_path)
            except OSError as ose:
                log.err("Unable to remove %s: %s" % (ifile_path, ose.message))

            try:
                key_id = os.path.basename(ifile_path).split('.')[0]
                keypath = os.path.join(
                    GLSetting.ramdisk_path,
                    ("%s%s" % (GLSetting.AES_keyfile_prefix, key_id)))
                os.remove(keypath)
            except Exception as excep:
                log.err("Unable to remove keyfile associated with %s: %s" %
                        (ifile_path, excep))
Ejemplo n.º 43
0
def init_db(store, result, node_dict, appdata_dict):
    """
    TODO refactor with languages the email_template, develop a dedicated
    function outside the node, and inquire f*****g YHWH about the
    callbacks existence/usage
    """

    node = models.Node(node_dict)

    for k in appdata_dict['node']:
        setattr(node, k, appdata_dict['node'][k])

    node.languages_enabled = GLSetting.defaults.languages_enabled

    node.receipt_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}'))

    node.wizard_done = GLSetting.skip_wizard

    node.creation_date = datetime_now()

    store.add(node)

    admin_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}'))
    admin_password = hash_password(u"globaleaks", admin_salt)

    admin_dict = {
        'username': u'admin',
        'password': admin_password,
        'salt': admin_salt,
        'role': u'admin',
        'state': u'enabled',
        'language': u"en",
        'timezone': 0,
        'password_change_needed': False,
    }

    admin = models.User(admin_dict)

    admin.last_login = datetime_null()
    admin.password_change_date = datetime_null()

    store.add(admin)

    notification = models.Notification()

    # our defaults for free, because we're like Gandhi of the mail accounts.
    notification.server = "mail.headstrong.de"
    notification.port = 587
    # port 587/SMTP-TLS or 465/SMTPS
    notification.username = "******"
    notification.password = "******"
    notification.security = "TLS"

    notification.source_name = "Default GlobaLeaks sender"
    notification.source_email = notification.username

    # Those fields are sets as default in order to show to the Admin the various
    # 'variables' used in the template.

    for k in appdata_dict['templates']:
        setattr(notification, k, appdata_dict['templates'][k])

    store.add(notification)
Ejemplo n.º 44
0
    def operation(self):
        """
        Goal of this function is to process/validate files, compute their checksums and
        apply the configured delivery method.
        """
        try:
            # ==> Submission && Escalation
            info_created_tips = yield tip_creation()
            if info_created_tips:
                log.debug("Delivery job: created %d tips" % len(info_created_tips))
        except Exception as excep:
            log.err("Exception in asyncronous delivery job: %s" % excep )
            sys.excepthook(*sys.exc_info())

        # ==> Files && Files update,
        #     InternalFile is set as 'locked' status
        #     and would be unlocked at the end.
        # TODO xxx limit of file number per operation
        filemap = yield receiverfile_planning()
        # the function returns a dict of lists with dicts:
        # {
        #     'ifile_path' : [
        #       { 'receiver' : receiver_desc, 'path': file_path,
        #                           'size' : file_size, 'status': XXX },
        #       { 'receiver' : receiver_desc, 'path': file_path,
        #                           'size' : file_size, 'status': YYY }, ... ]
        # },  { }, ...
        #

        if not filemap:
            return

        # Here the files received are encrypted (if the receiver has PGP key)
        log.debug("Delivery task: Iterate over %d ReceiverFile(s)" % len(filemap.keys()) )

        for ifile_path, receivermap in filemap.iteritems():

            plain_path = os.path.join(GLSetting.submission_path, "%s.plain" % xeger(r'[A-Za-z0-9]{16}') )

            create_plaintextfile = encrypt_where_available(receivermap)

            for rfileinfo in receivermap:

                if not create_plaintextfile and rfileinfo['status'] == u'reference':
                    rfileinfo['path'] = plain_path

                try:
                    yield receiverfile_create(ifile_path, rfileinfo['path'], rfileinfo['status'],
                                              rfileinfo['size'], rfileinfo['receiver'])
                except Exception as excep:
                    log.err("Unable to create ReceiverFile from %s for %s: %s" %
                            (ifile_path, rfileinfo['receiver']['name'], excep))
                    continue

            if not create_plaintextfile:
                log.debug(":( NOT all receivers support PGP and the system allows plaintext version of files: %s saved in plaintext file %s" %
                          (ifile_path, plain_path)
                )

                try:
                    with open(plain_path, "wb") as plain_f_is_sad_f, \
                         GLSecureFile(ifile_path) as encrypted_file:

                        chunk_size = 4096
                        while True:
                            chunk = encrypted_file.read(chunk_size)
                            if len(chunk) == 0:
                                break
                            plain_f_is_sad_f.write(chunk)

                    yield do_final_internalfile_update(ifile_path, u'ready', plain_path)

                except Exception as excep:
                    log.err("Unable to create plaintext file %s: %s" % (plain_path, excep))

            else: # create_plaintextfile
                log.debug("All Receivers support PGP or the system denys plaintext version of files: marking internalfile as removed")
                yield do_final_internalfile_update(ifile_path, u'delivered') # Removed

            # the original AES file need always to be deleted
            log.debug("Deleting the submission AES encrypted file: %s" % ifile_path)
            try:
                os.remove(ifile_path)
            except OSError as ose:
                log.err("Unable to remove %s: %s" % (ifile_path, ose.message))

            try:
                key_id = os.path.basename(ifile_path).split('.')[0]
                keypath = os.path.join(GLSetting.ramdisk_path, ("%s%s" % (GLSetting.AES_keyfile_prefix, key_id)))
                os.remove(keypath)
            except Exception as excep:
                log.err("Unable to remove keyfile associated with %s: %s" % (ifile_path, excep))
Ejemplo n.º 45
0
 def test_xeger(self):
     assert re.match(r'^foo[\d]{10}bar$', rstr.xeger('^foo[\d]{10}bar$'))
Ejemplo n.º 46
0
from globaleaks.jobs import statistics_sched, mailflush_sched
from globaleaks.models import db_forge_obj, ReceiverTip, ReceiverFile, WhistleblowerTip, InternalTip
from globaleaks.rest.apicache import GLApiCache
from globaleaks.settings import GLSettings, transact, transact_ro
from globaleaks.security import GLSecureTemporaryFile
from globaleaks.third_party import rstr
from globaleaks.utils import token
from globaleaks.utils.structures import fill_localized_keys
from globaleaks.utils.utility import datetime_null, log

from . import TEST_DIR

## constants
VALID_PASSWORD1 = u'justapasswordwithaletterandanumberandbiggerthan8chars'
VALID_PASSWORD2 = u'justap455w0rdwithaletterandanumberandbiggerthan8chars'
VALID_SALT1 = security.get_salt(rstr.xeger(r'[A-Za-z0-9]{56}'))
VALID_SALT2 = security.get_salt(rstr.xeger(r'[A-Za-z0-9]{56}'))
VALID_HASH1 = security.hash_password(VALID_PASSWORD1, VALID_SALT1)
VALID_HASH2 = security.hash_password(VALID_PASSWORD2, VALID_SALT2)
INVALID_PASSWORD = u'antani'

FIXTURES_PATH = os.path.join(TEST_DIR, 'fixtures')

with open(os.path.join(TEST_DIR, 'keys/valid_pgp_key1.txt')) as pgp_file:
    VALID_PGP_KEY1 = unicode(pgp_file.read())

with open(os.path.join(TEST_DIR, 'keys/valid_pgp_key2.txt')) as pgp_file:
    VALID_PGP_KEY2 = unicode(pgp_file.read())

with open(os.path.join(TEST_DIR, 'keys/expired_pgp_key.txt')) as pgp_file:
    EXPIRED_PGP_KEY = unicode(pgp_file.read())
 def test_xeger(self):
     assert re.match(r'^foo[\d]{10}bar$', rstr.xeger('^foo[\d]{10}bar$'))
Ejemplo n.º 48
0
def db_create_receiver(store,
                       request,
                       language=GLSetting.memory_copy.default_language):
    """
    Creates a new receiver.
    Returns:
        (dict) the configured receiver
    """

    mo = structures.Rosetta()
    mo.acquire_request(language, request, Receiver)
    for attr in mo.get_localized_attrs():
        request[attr] = mo.get_localized_dict(attr)

    mail_address = request['mail_address']

    # Pretend that username is unique:
    homonymous = store.find(User, User.username == mail_address).count()
    if homonymous:
        log.err(
            "Creation error: already present receiver with the requested username: %s"
            % mail_address)
        raise errors.ExpectedUniqueField('mail_address', mail_address)

    password = request.get('password')

    security.check_password_format(password)
    receiver_salt = security.get_salt(rstr.xeger('[A-Za-z0-9]{56}'))
    receiver_password = security.hash_password(password, receiver_salt)

    receiver_user_dict = {
        'username': mail_address,
        'password': receiver_password,
        'salt': receiver_salt,
        'role': u'receiver',
        'state': u'enabled',
    }

    receiver_user = models.User(receiver_user_dict)
    receiver_user.last_login = datetime_null()
    store.add(receiver_user)

    receiver = Receiver(request)
    receiver.user = receiver_user

    receiver.mail_address = mail_address
    receiver.tags = request['tags']

    # The various options related in manage GPG keys are used here.
    gpg_options_parse(receiver, request)

    log.debug("Creating receiver %s" % receiver.user.username)

    store.add(receiver)

    create_random_receiver_portrait(receiver.id)

    contexts = request.get('contexts', [])
    for context_id in contexts:
        context = store.find(Context, Context.id == context_id).one()
        if not context:
            log.err("Creation error: invalid Context can't be associated")
            raise errors.ContextIdNotFound
        context.receivers.add(receiver)

    return admin_serialize_receiver(receiver, language)
Ejemplo n.º 49
0
def initialize_node(store, results, only_node, templates, appdata):
    """
    TODO refactor with languages the email_template, develop a dedicated
    function outside the node, and inquire f*****g YHWH about the
    callbacks existence/usage
    """

    node = models.Node(only_node)

    log.debug("Inizializing ApplicationData")

    new_appdata = ApplicationData()
    new_appdata.fields = appdata['fields']
    new_appdata.version = appdata['version']
    store.add(new_appdata)

    if 'node_presentation' in appdata:
        node.presentation = appdata['node_presentation']

    if 'node_footer' in appdata:
        node.footer = appdata['node_footer']

    if 'node_subtitle' in appdata:
        node.subtitle = appdata['node_subtitle']

    node.languages_enabled = GLSetting.defaults.languages_enabled

    node.receipt_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}'))

    node.wizard_done = GLSetting.skip_wizard

    node.creation_date = datetime_now()

    store.add(node)

    admin_salt = get_salt(rstr.xeger('[A-Za-z0-9]{56}'))
    admin_password = hash_password(u"globaleaks", admin_salt)

    admin_dict = {
        'username': u'admin',
        'password': admin_password,
        'salt': admin_salt,
        'role': u'admin',
        'state': u'enabled',
        }

    admin = models.User(admin_dict)

    admin.last_login = datetime_null()

    store.add(admin)

    notification = models.Notification()

    # our defaults for free, because we're like Gandhi of the mail accounts.
    notification.server = "mail.headstrong.de"
    notification.port = 587
    # port 587/SMTP-TLS or 465/SMTPS
    notification.username = "******"
    notification.password = "******"
    notification.security = "TLS"

    notification.source_name = "Default GlobaLeaks sender"
    notification.source_email = notification.username

    # Those fields are sets as default in order to show to the Admin the various
    # 'variables' used in the template.
    notification.encrypted_tip_template = { GLSetting.memory_copy.default_language:
                                            templates['encrypted_tip'] }
    notification.encrypted_tip_mail_title = { GLSetting.memory_copy.default_language:
                                              "[Tip %TipNum%] for %ReceiverName% in %ContextName%: new Tip (Encrypted)" }

    notification.plaintext_tip_template= { GLSetting.memory_copy.default_language:
                                           templates['plaintext_tip'] }
    notification.plaintext_tip_mail_title = { GLSetting.memory_copy.default_language:
                                              "[Tip %TipNum%] for %ReceiverName% in %ContextName%: new ClearText" }

    notification.encrypted_message_template = { GLSetting.memory_copy.default_language: templates['encrypted_message'] }
    notification.encrypted_message_mail_title = { GLSetting.memory_copy.default_language:
                                                  "[Tip %TipNum%] for %ReceiverName% in %ContextName%: New message (Encrypted)" }

    notification.plaintext_message_template = { GLSetting.memory_copy.default_language: templates['plaintext_message'] }
    notification.plaintext_message_mail_title = { GLSetting.memory_copy.default_language:
                                                  "[Tip %TipNum%] for %ReceiverName% in %ContextName%: New message" }

    notification.encrypted_file_template = { GLSetting.memory_copy.default_language: templates['encrypted_file'] }
    notification.encrypted_file_mail_title = { GLSetting.memory_copy.default_language:
                                               "[Tip %TipNum%] for %ReceiverName% in %ContextName%: File attached (Encrypted)" }

    notification.plaintext_file_template = { GLSetting.memory_copy.default_language: templates['plaintext_file'] }
    notification.plaintext_file_mail_title = { GLSetting.memory_copy.default_language:
                                               "[Tip %TipNum%] for %ReceiverName% in %ContextName%: File attached" }

    notification.encrypted_comment_template = { GLSetting.memory_copy.default_language: templates['encrypted_comment'] }
    notification.encrypted_comment_mail_title = { GLSetting.memory_copy.default_language:
                                                  "[Tip %TipNum%] for %ReceiverName% in %ContextName%: New comment (Encrypted)" }

    notification.plaintext_comment_template = { GLSetting.memory_copy.default_language: templates['plaintext_comment'] }
    notification.plaintext_comment_mail_title = { GLSetting.memory_copy.default_language:
                                                  "[Tip %TipNum%] for %ReceiverName% in %ContextName%: New comment" }

    notification.zip_description = { GLSetting.memory_copy.default_language:
                                     templates['zip_collection'] }

    store.add(notification)
Ejemplo n.º 50
0
def db_create_receiver(store, request, language=GLSetting.memory_copy.default_language):
    """
    Creates a new receiver.
    Returns:
        (dict) the configured receiver
    """

    fill_localized_keys(request, models.Receiver.localized_strings, language)

    mail_address = request['mail_address']

    # Pretend that username is unique:
    homonymous = store.find(models.User, models.User.username == mail_address).count()
    if homonymous:
        log.err("Creation error: already present receiver with the requested username: %s" % mail_address)
        raise errors.ExpectedUniqueField('mail_address', mail_address)

    password = request['password']
    if len(password) and password != GLSetting.default_password:
        security.check_password_format(password)
    else:
        password = GLSetting.default_password

    receiver_salt = security.get_salt(rstr.xeger('[A-Za-z0-9]{56}'))
    receiver_password = security.hash_password(password, receiver_salt)

    receiver_user_dict = {
        'username': mail_address,
        'password': receiver_password,
        'salt': receiver_salt,
        'role': u'receiver',
        'state': u'enabled',
        'language': u"en",
        'timezone': 0,
        'password_change_needed': True,
    }

    receiver_user = models.User(receiver_user_dict)
    receiver_user.last_login = datetime_null()
    receiver_user.password_change_needed = request['password_change_needed']
    receiver_user.password_change_date = datetime_null()
    store.add(receiver_user)

    receiver = models.Receiver(request)
    receiver.user = receiver_user

    receiver.mail_address = mail_address

    # The various options related in manage GPG keys are used here.
    gpg_options_parse(receiver, request)

    log.debug("Creating receiver %s" % receiver.user.username)

    store.add(receiver)

    create_random_receiver_portrait(receiver.id)

    contexts = request.get('contexts', [])
    for context_id in contexts:
        context = models.Context.get(store, context_id)
        if not context:
            log.err("Creation error: invalid Context can't be associated")
            raise errors.ContextIdNotFound
        context.receivers.add(receiver)

    return admin_serialize_receiver(receiver, language)