Queer European MD passionate about IT
Browse Source

Send file while encrypting it

Davte 5 years ago
parent
commit
5f1c8fdf47
1 changed files with 40 additions and 19 deletions
  1. 40 19
      src/client.py

+ 40 - 19
src/client.py

@@ -21,6 +21,7 @@ class Client:
         self._file_path = None
         self._file_path = None
         self._working = False
         self._working = False
         self._ssl_context = None
         self._ssl_context = None
+        self._encryption_complete = False
 
 
     @property
     @property
     def host(self) -> str:
     def host(self) -> str:
@@ -62,6 +63,10 @@ class Client:
         """Password for file encryption or decryption."""
         """Password for file encryption or decryption."""
         return self._password
         return self._password
 
 
+    @property
+    def encryption_complete(self):
+        return self._encryption_complete
+
     async def run_sending_client(self, file_path='~/output.txt'):
     async def run_sending_client(self, file_path='~/output.txt'):
         self._file_path = file_path
         self._file_path = file_path
         reader, writer = await asyncio.open_connection(host=self.host,
         reader, writer = await asyncio.open_connection(host=self.host,
@@ -72,35 +77,51 @@ class Client:
         await reader.readline()  # Wait for server start signal
         await reader.readline()  # Wait for server start signal
         await self.send(writer=writer)
         await self.send(writer=writer)
 
 
+    async def encrypt_file(self, input_file, output_file):
+        self._encryption_complete = False
+        logging.info("Encrypting file...")
+        stdout, stderr = ''.encode(), ''.encode()
+        try:
+            _subprocess = await asyncio.create_subprocess_shell(
+                "openssl enc -aes-256-cbc "
+                "-md sha512 -pbkdf2 -iter 100000 -salt "
+                f"-in {input_file} -out {output_file} "
+                f"-pass pass:{self.password}"
+            )
+            stdout, stderr = await _subprocess.communicate()
+        except Exception as e:
+            logging.error(
+                "Exception {e}:\n{o}\n{er}".format(
+                    e=e,
+                    o=stdout.decode().strip(),
+                    er=stderr.decode().strip()
+                )
+            )
+        logging.info("Encryption completed.")
+        self._encryption_complete = True
+
     async def send(self, writer: asyncio.StreamWriter):
     async def send(self, writer: asyncio.StreamWriter):
         self._working = True
         self._working = True
         file_path = self.file_path
         file_path = self.file_path
         if self.password:
         if self.password:
-            logging.info("Encrypting file...")
             file_path = self.file_path + '.enc'
             file_path = self.file_path + '.enc'
-            stdout, stderr = ''.encode(), ''.encode()
-            try:
-                _subprocess = await asyncio.create_subprocess_shell(
-                    "openssl enc -aes-256-cbc "
-                    "-md sha512 -pbkdf2 -iter 100000 -salt "
-                    f"-in {self.file_path} -out {file_path} "
-                    f"-pass pass:{self.password}"
+            asyncio.ensure_future(
+                self.encrypt_file(
+                    input_file=self.file_path,
+                    output_file=file_path
                 )
                 )
-                stdout, stderr = await _subprocess.communicate()
-            except Exception as e:
-                logging.error(
-                    "Exception {e}:\n{o}\n{er}".format(
-                        e=e,
-                        o=stdout.decode().strip(),
-                        er=stderr.decode().strip()
-                    )
-                )
-
-            logging.info("Encryption completed. Sending file...")
+            )
+            while not os.path.isfile(file_path):
+                await asyncio.sleep(0.1)  # Let the encryption begin
+        logging.info("Sending file...")
         with open(file_path, 'rb') as file_to_send:
         with open(file_path, 'rb') as file_to_send:
             while not self.stopping:
             while not self.stopping:
                 output_data = file_to_send.read(self.buffer_chunk_size)
                 output_data = file_to_send.read(self.buffer_chunk_size)
                 if not output_data:
                 if not output_data:
+                    # If encryption is in progress, wait and read again later
+                    if self.password and not self.encryption_complete:
+                        await asyncio.sleep(1)
+                        continue
                     break
                     break
                 try:
                 try:
                     writer.write(output_data)
                     writer.write(output_data)