Exemple #1
0
    def __str__(self):
        import base64
        from Publication import Publication

        general_flags_str = 'General flags: '
        if self.is_deadman_switch_file():
            general_flags_str += 'Deadman Switch File'
        elif self.is_deadman_switch_key():
            general_flags_str += 'Deadman Switch Key'
        else:
            general_flags_str += 'None'

        s = ''
        if self.temporal_key is not None:
            s = "Temporal Key: %s\n" % binascii.hexlify(
                self.temporal_key).decode('ascii')

        return "PartialFile:\n\tInitial TXID: %s\n\tSanitized filename: %s\n\tDescription: %s\n\tFile size: %d\n\tEncryption type: %s\n\tContent type: %s\n\tCompression type: %s\n\t%s\n\tFile hash: %s\n\tFile pointer: %d\n\tACK Window: %s\n\t%s\n\tInitial block number: %d\n\tFinal block number: %d\n\tSQL ID: %d\n\tIs deadman switch file: %s\n\tIs deadman switch key: %s\n\tIs complete deadman switch file: %r\n\tIs complete: %r\n" % (
            self.initial_txid, self.sanitized_filename, self.description,
            self.file_size, Publication.get_encryption_str(
                self.encryption_type),
            Publication.get_content_type_str(self.content_type),
            Publication.get_compression_type_str(
                self.compression_type), general_flags_str,
            binascii.hexlify(self.file_hash).decode('ascii'), self.file_ptr,
            self.block_acks, s,
            self.initial_block_num, self.final_block_num, self.sql_id,
            self.is_deadman_switch_file(), self.is_deadman_switch_key(),
            self.is_complete_deadman_switch_file(), self.is_complete())
Exemple #2
0
   def __str__(self):
      import base64
      from Publication import Publication

      general_flags_str = 'General flags: '
      if self.is_deadman_switch_file():
         general_flags_str += 'Deadman Switch File'
      elif self.is_deadman_switch_key():
         general_flags_str += 'Deadman Switch Key'
      else:
         general_flags_str += 'None'

      s = ''
      if self.temporal_key is not None:
         s = "Temporal Key: %s\n" % binascii.hexlify(self.temporal_key).decode('ascii')

      return "PartialFile:\n\tInitial TXID: %s\n\tSanitized filename: %s\n\tDescription: %s\n\tFile size: %d\n\tEncryption type: %s\n\tContent type: %s\n\tCompression type: %s\n\t%s\n\tFile hash: %s\n\tFile pointer: %d\n\tACK Window: %s\n\t%s\n\tInitial block number: %d\n\tFinal block number: %d\n\tSQL ID: %d\n\tIs deadman switch file: %s\n\tIs deadman switch key: %s\n\tIs complete deadman switch file: %r\n\tIs complete: %r\n" % (self.initial_txid, self.sanitized_filename, self.description, self.file_size, Publication.get_encryption_str(self.encryption_type), Publication.get_content_type_str(self.content_type), Publication.get_compression_type_str(self.compression_type), general_flags_str, binascii.hexlify(self.file_hash).decode('ascii'), self.file_ptr, self.block_acks, s, self.initial_block_num, self.final_block_num, self.sql_id, self.is_deadman_switch_file(), self.is_deadman_switch_key(), self.is_complete_deadman_switch_file(), self.is_complete())
Exemple #3
0
    def finalize(self, temporal_key, block_num):
        from Publication import Publication
        from Utils import Utils

        # If not all bytes were received, this is a failure.
        if (not self.is_complete()) and (
                not self.is_complete_deadman_switch_file()):
            self.d("Cannot finalize because file is not complete!")
            return False

        # Update the temporal key, if there is one.
        if (self.encryption_type != Publication.ENCRYPTION_TYPE_NONE) and \
           (temporal_key != (b'\x00' * 32)):
            self.temporal_key = temporal_key

        # If file is in plaintext, the hash is in the temporal key field.
        if self.encryption_type == Publication.ENCRYPTION_TYPE_NONE:
            self.file_hash = temporal_key
            self.temporal_key = b'\x00' * 32

        # Read the file we extracted.
        file_bytes = None
        with open(self.file_path, 'rb') as f:
            file_bytes = f.read()

        # Calculate the hash of the file we extracted.
        calculated_hash = hashlib.sha256(file_bytes).digest()

        # Check that the hash in the publication header matches what we have.
        if self.file_hash != calculated_hash:
            self.d("Hashes do not match!:\n%s\n%s" %
                   (binascii.hexlify(self.file_hash).decode('ascii'),
                    binascii.hexlify(calculated_hash).decode('ascii')))
            return False

        # If this file is a deadman switch, don't try to decrypt, since we don't
        # have the real key here.
        if self.is_deadman_switch_file() and (temporal_key == (b'\xff' * 32)):
            # Save the num_parallel_txs and encryption_type so that when the key
            # is found in the future, we know how to decrypt this.
            self.final_block_num = block_num
            self.save_state()
            return True

        # Get a unique filename in the output directory.
        new_file_path = PartialFile.get_unique_filepath(
            self.initial_txid, self.output_dir, self.sanitized_filename)

        # Decrypt the file, if necessary.
        if self.encryption_type == Publication.ENCRYPTION_TYPE_GPG2_AES256_SHA512:
            self.d("File is encrypted with type %s.  Decrypting..." %
                   Publication.get_encryption_str(self.encryption_type))
            file_bytes = Utils.decrypt(file_bytes, self.temporal_key)
            if len(file_bytes) == 0:
                self.d("Decryption of file yielded zero bytes!")
                return False

            # Write the plaintext bytes into the output directory.
            with open(new_file_path, 'wb') as f:
                f.write(file_bytes)

            # Remove the encrypted file.
            try:
                os.unlink(self.file_path)
            except FileNotFoundError:
                pass

        else:
            # Move file out of partial directory into output directory.
            os.rename(self.file_path, new_file_path)

        # Update the file_path with its final destination.
        self.file_path = new_file_path

        # Delete the state file.
        try:
            os.unlink(self.state_file)
        except FileNotFoundError:
            pass

        # Update the final block number.
        self.final_block_num = block_num

        # Mark as finalized and return success.
        self.finalized = True
        return True
Exemple #4
0
   def finalize(self, temporal_key, block_num):
      from Publication import Publication
      from Utils import Utils

      # If not all bytes were received, this is a failure.
      if (not self.is_complete()) and (not self.is_complete_deadman_switch_file()):
         self.d("Cannot finalize because file is not complete!")
         return False

      # Update the temporal key, if there is one.
      if (self.encryption_type != Publication.ENCRYPTION_TYPE_NONE) and \
         (temporal_key != (b'\x00' * 32)):
         self.temporal_key = temporal_key

      # If file is in plaintext, the hash is in the temporal key field.
      if self.encryption_type == Publication.ENCRYPTION_TYPE_NONE:
         self.file_hash = temporal_key
         self.temporal_key = b'\x00' * 32

      # Read the file we extracted.
      file_bytes = None
      with open(self.file_path, 'rb') as f:
         file_bytes = f.read()

      # Calculate the hash of the file we extracted.
      calculated_hash = hashlib.sha256(file_bytes).digest()

      # Check that the hash in the publication header matches what we have.
      if self.file_hash != calculated_hash:
         self.d("Hashes do not match!:\n%s\n%s" % (binascii.hexlify(self.file_hash).decode('ascii'), binascii.hexlify(calculated_hash).decode('ascii')))
         return False

      # If this file is a deadman switch, don't try to decrypt, since we don't
      # have the real key here.
      if self.is_deadman_switch_file() and (temporal_key == (b'\xff' * 32)):
         # Save the num_parallel_txs and encryption_type so that when the key
         # is found in the future, we know how to decrypt this.
         self.final_block_num = block_num
         self.save_state()
         return True

      # Get a unique filename in the output directory.
      new_file_path = PartialFile.get_unique_filepath(self.initial_txid, self.output_dir, self.sanitized_filename)

      # Decrypt the file, if necessary.
      if self.encryption_type == Publication.ENCRYPTION_TYPE_GPG2_AES256_SHA512:
         self.d("File is encrypted with type %s.  Decrypting..." % Publication.get_encryption_str(self.encryption_type))
         file_bytes = Utils.decrypt(file_bytes, self.temporal_key)
         if len(file_bytes) == 0:
            self.d("Decryption of file yielded zero bytes!")
            return False

         # Write the plaintext bytes into the output directory.
         with open(new_file_path, 'wb') as f:
            f.write(file_bytes)

         # Remove the encrypted file.
         try:
            os.unlink(self.file_path)
         except FileNotFoundError:
            pass

      else:
         # Move file out of partial directory into output directory.
         os.rename(self.file_path, new_file_path)

      # Update the file_path with its final destination.
      self.file_path = new_file_path

      # Delete the state file.
      try:
         os.unlink(self.state_file)
      except FileNotFoundError:
         pass

      # Update the final block number.
      self.final_block_num = block_num

      # Mark as finalized and return success.
      self.finalized = True
      return True