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