| 
														
															@@ -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) 
														 |