Пример #1
0
 def test_003_temporary_file_avoid_delete(self):
     a = GLSecureTemporaryFile(GLSetting.tmp_upload_path)
     a.avoid_delete()
     antani = "0123456789" * 10000
     a.write(antani)
     a.close()
     self.assertTrue(os.path.exists(a.filepath))
     b = GLSecureFile(a.filepath)
     self.assertTrue(antani == b.read())
Пример #2
0
def fsops_pgp_encrypt(fpath, recipient_pgp):
    """
    return
        path of encrypted file,
        length of the encrypted file

    this function is used to encrypt a file for a specific recipient.
    commonly 'receiver_desc' is expected as second argument;
    anyhow a simpler dict can be used.

    required keys are checked on top
    """
    gpoj = GLBPGP()

    try:
        gpoj.load_key(recipient_pgp['pgp_key_public'])

        filepath = os.path.join(GLSettings.submission_path, fpath)

        with GLSecureFile(filepath) as f:
            encrypted_file_path = os.path.join(os.path.abspath(GLSettings.submission_path), "pgp_encrypted-%s" % generateRandomKey(16))
            _, encrypted_file_size = gpoj.encrypt_file(recipient_pgp['pgp_key_fingerprint'], f, encrypted_file_path)

    except:
        raise

    finally:
        # the finally statement is always called also if
        # except contains a return or a raise
        gpoj.destroy_environment()

    return encrypted_file_path, encrypted_file_size
Пример #3
0
def fsops_gpg_encrypt(fpath, recipient_gpg):
    """
    return
        path of encrypted file,
        length of the encrypted file

    this function is used to encrypt a file for a specific recipient.
    commonly 'receiver_desc' is expected as second argument;
    anyhow a simpler dict can be used.

    required keys are checked on top

    """
    gpoj = GLBGPG()

    try:
        gpoj.load_key(recipient_gpg['gpg_key_armor'])

        filepath = os.path.join(GLSetting.submission_path, fpath)

        with GLSecureFile(filepath) as f:
            encrypted_file_path, encrypted_file_size = \
                gpoj.encrypt_file(recipient_gpg['gpg_key_fingerprint'], filepath, f, GLSetting.submission_path)

    except:
        raise

    finally:
        # the finally statement is always called also if
        # except contains a return or a raise
        gpoj.destroy_environment()

    return encrypted_file_path, encrypted_file_size
Пример #4
0
def fsops_gpg_encrypt(fpath, recipient_gpg):
    """
    return
        path of encrypted file,
        length of the encrypted file

    this function is used to encrypt a file for a specific recipient.
    commonly 'receiver_desc' is expected as second argument;
    anyhow a simpler dict can be used.

    required keys are checked on top

    """
    assert isinstance(recipient_gpg, dict), "invalid recipient"
    assert recipient_gpg.has_key('gpg_key_armor'), "missing key"
    assert recipient_gpg.has_key('gpg_key_status'), "missing status"
    assert recipient_gpg['gpg_key_status'] == u'Enabled', "GPG not enabled"
    assert recipient_gpg.has_key('name'), "missing recipient Name"

    gpoj = GLBGPG(recipient_gpg)

    if not gpoj.validate_key(recipient_gpg['gpg_key_armor']):
        raise Exception("Unable to validate key")

    filepath = os.path.join(GLSetting.submission_path, fpath)

    with GLSecureFile(filepath) as f:
        encrypted_file_path, encrypted_file_size = \
            gpoj.encrypt_file(filepath, f, GLSetting.submission_path)

    gpoj.destroy_environment()

    assert (encrypted_file_size > 1), "File generated is empty or size is 0"
    assert os.path.isfile(
        encrypted_file_path), "Output generated is not a file!"

    return encrypted_file_path, encrypted_file_size
Пример #5
0
def process_files(receiverfiles_maps):
    """
    @param receiverfiles_maps: the mapping of ifile/rfiles to be created on filesystem
    @return: return None
    """
    for ifile_id, receiverfiles_map in receiverfiles_maps.iteritems():
        ifile_path = receiverfiles_map['ifile_path']
        ifile_name = os.path.basename(ifile_path).split('.')[0]
        plain_path = os.path.join(GLSettings.submission_path, "%s.plain" % ifile_name)

        receiverfiles_map['plaintext_file_needed'] = False
        for rcounter, rfileinfo in enumerate(receiverfiles_map['rfiles']):
            if len(rfileinfo['receiver']['pgp_key_public']):
                try:
                    new_path, new_size = fsops_pgp_encrypt(rfileinfo['path'], rfileinfo['receiver'])

                    log.debug("%d# Switch on Receiver File for %s path %s => %s size %d => %d" %
                              (rcounter,  rfileinfo['receiver']['name'], rfileinfo['path'],
                               new_path, rfileinfo['size'], new_size))

                    rfileinfo['path'] = new_path
                    rfileinfo['size'] = new_size
                    rfileinfo['status'] = u'encrypted'
                except Exception as excep:
                    log.err("%d# Unable to complete PGP encrypt for %s on %s: %s. marking the file as unavailable." % (
                            rcounter, rfileinfo['receiver']['name'], rfileinfo['path'], excep)
                    )
                    rfileinfo['status'] = u'unavailable'
            elif GLSettings.memory_copy.allow_unencrypted:
                receiverfiles_map['plaintext_file_needed'] = True
                rfileinfo['status'] = u'reference'
                rfileinfo['path'] = plain_path
            else:
                rfileinfo['status'] = u'nokey'

        if receiverfiles_map['plaintext_file_needed']:
            log.debug(":( NOT all receivers support PGP and the system allows plaintext version of files: %s saved as plaintext file %s" %
                      (ifile_path, plain_path))

            try:
                with open(plain_path, "wb") as plaintext_f, GLSecureFile(ifile_path) as encrypted_file:
                    chunk_size = 4096
                    written_size = 0
                    while True:
                        chunk = encrypted_file.read(chunk_size)
                        if len(chunk) == 0:
                            if written_size != receiverfiles_map['ifile_size']:
                                log.err("Integrity error on rfile write for ifile %s; ifile_size(%d), rfile_size(%d)" %
                                        (ifile_id, receiverfiles_map['ifile_size'], written_size))
                            break
                        written_size += len(chunk)
                        plaintext_f.write(chunk)

                receiverfiles_map['ifile_path'] = plain_path
            except Exception as excep:
                log.err("Unable to create plaintext file %s: %s" % (plain_path, excep))
        else:
            log.debug("All Receivers support PGP or the system denies plaintext version of files: marking internalfile as removed")

        # the original AES file should always be deleted
        log.debug("Deleting the submission AES encrypted file: %s" % ifile_path)

        # Remove the AES file
        try:
            os.remove(ifile_path)
        except OSError as ose:
            log.err("Unable to remove %s: %s" % (ifile_path, ose.message))

        # Remove the AES file key
        try:
            os.remove(os.path.join(GLSettings.ramdisk_path, ("%s%s" % (GLSettings.AES_keyfile_prefix, ifile_name))))
        except OSError as ose:
            log.err("Unable to remove keyfile associated with %s: %s" % (ifile_path, ose.message))
Пример #6
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))