Spaces:
Runtime error
Runtime error
File size: 11,108 Bytes
114ebf7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | import email
import os
import socket
import threading
import logging
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from queue import Queue
import pandas as pd
# Server configuration
SERVER_HOST = '0.0.0.0'
SERVER_PORT = 1234
saveMail_directory = os.getenv("SAVE_MAIL_DIRECTORY", "FlowSteering/ApplicationCode/EmailServer/EmailServerMailDatabase") # Change this to the directory where you want to save the emails inbox for each user
if not saveMail_directory:
raise ValueError("SAVE_MAIL_DIRECTORY environment variable is not set.")
message_queue = Queue()
default_image = 'FlowSteering/assets/PerturbatedImages/DjiPerturbClassForward.png'
# Server configuration
# Configure logging
logging.basicConfig(level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s')
def receive_complete_data(
client_socket): # This function is used to receive the complete data from the client, adjust the parameters as needed based on your network conditions
received_data = b""
count = 0
client_socket.settimeout(3.0)
try:
while True:
chunk = client_socket.recv(2 ** 16) # Adjust the buffer size as needed
if not chunk:
count += 1
else:
count = 0
received_data += chunk
if count >= 50:
break
except socket.timeout as e:
print('timeout')
print(e)
except Exception as e:
print(f"Error receiving data: {e}")
return received_data
def handle_messages(): # This function is used to handle the messages in the queue and process them accordingly based on the command received from the client (e.g., SEND_EMAIL, CHECK_INBOX)
while True:
if not message_queue.empty():
print('______________________________________________________________')
data, client_socket, client_address = message_queue.get()
msg = email.message_from_bytes(data)
Command, subject, sender, recipient = msg['Command'], msg["Subject"], msg["From"], msg["To"]
if Command == "CHECK_INBOX":
print("Checking Inbox")
Check_Inbox(client_socket,
sender) # This function is used to check the inbox of the user and send the email to the client
elif Command == "SEND_EMAIL": # This is the command to send the email to the recipient
print("Sending Email")
Save_Email_To_Recipient(client_socket, data, msg, Command, subject, sender,
recipient) # This function is used to save the email to the recipient's inbox
print('______________________________________________________________')
client_socket.close()
def Save_Email_To_Recipient(client_socket, data, msg, requests, subject, sender, recipient): # This function is used to save the email to the recipient's inbox
try:
recipient_directory = f"{saveMail_directory}/{recipient}" # This is the directory where the emails will be saved
os.makedirs(recipient_directory, exist_ok=True) # Create the directory if it doesn't exist
msg = email.message_from_bytes(data)
try:
if msg.is_multipart():
for part in msg.get_payload():
if part.get_content_type() == "text/plain":
body = part.get_payload()
else:
body = msg.get_payload()
except Exception as e:
logging.error(f"Error processing email message: {e}")
client_socket.sendall("Error processing email message".encode('utf-8'))
return
for part in msg.walk():
if part.get_content_maintype() == "multipart":
continue
if part.get("Content-Disposition") is None:
continue
# Get the filename
filename = part.get_filename()
# split the filename by "\" and take the last part of it
#filename = filename.split("\\")[-1]
filename = filename.split("/")[-1]
# Save the image file
try:
with open(os.path.join(recipient_directory, filename), "wb") as f:
f.write(part.get_payload(decode=True))
except Exception as e:
logging.error(f"Error saving email attachment: {e}")
client_socket.sendall("Error saving email attachment".encode('utf-8'))
return
print(f"From: {sender}")
print(f"To: {recipient}")
print(f"Subject: {subject}")
print(f"Attachment filename: {filename}")
print(f' Text body: {body}')
filepath = str(f"{recipient_directory}/{filename}")
email_data = [[sender, recipient, subject, body, filepath]]
MyColumns = ['Sender', 'Recipient', 'Subject', 'Body', 'FilePath']
if not os.path.isfile(f"{recipient_directory}/{recipient}_received_emails.csv") or (
os.stat(f"{recipient_directory}/{recipient}_received_emails.csv").st_size == 0): # If the file doesn't exist, then create the file and save the email to the file
df = pd.DataFrame(email_data, columns=MyColumns)
try:
df.to_csv(f"{recipient_directory}/{recipient}_received_emails.csv", mode='w', header=True, index=False) # Save the email to the recipient's inbox
df.to_csv(f"{recipient_directory}/{recipient}_received_emailsHistory.csv", mode='w', header=True, index=False) # Save the email to the recipient's inbox history
except Exception as e:
logging.error(f"Error saving email to CSV: {e}")
client_socket.sendall("Error saving email to CSV".encode('utf-8'))
return
else: # If the file already exists, then append the email to the file
try:
df = pd.read_csv(f"{recipient_directory}/{recipient}_received_emails.csv") # Read the csv file of the recipient
new_row_df = pd.DataFrame(email_data, columns=df.columns)
df = pd.concat([df, new_row_df], ignore_index=True)
df.to_csv(f"{recipient_directory}/{recipient}_received_emails.csv", mode='w', header=True, index=False)
df = pd.read_csv(f"{recipient_directory}/{recipient}_received_emailsHistory.csv")
df = pd.concat([df, new_row_df], ignore_index=True)
df.to_csv(f"{recipient_directory}/{recipient}_received_emailsHistory.csv", mode='w', header=True, index=False)
except Exception as e:
logging.error(f"Error appending email to CSV: {e}")
client_socket.sendall("Error appending email to CSV".encode('utf-8'))
return
# write back to the sender that the email was sent
client_socket.sendall("Email Sent".encode('utf-8'))
except Exception as e:
logging.error(f"Unhandled exception in Save_Email_To_Recipient: {e}")
client_socket.sendall("Unhandled exception in Save_Email_To_Recipient".encode('utf-8'))
def Check_Inbox(client_socket, sender): # This function is used to check the inbox of the user and send the email to the client
try:
print(f' A request ot check the inbox email from: {sender}')
sender_directory = f"{saveMail_directory}/{sender}"
os.makedirs(sender_directory, exist_ok=True)
if (not os.path.isfile(f"{sender_directory}/{sender}_received_emails.csv")) or (
os.stat(f"{sender_directory}/{sender}_received_emails.csv").st_size == 0):
client_socket.sendall("No Emails".encode('utf-8'))
return
df = pd.read_csv(f"{sender_directory}/{sender}_received_emails.csv")
rows = df.shape[0]
print(f'found {rows} emails in the inbox of {sender}')
if rows == 0: # If there are no emails in the inbox, then send "No Emails" to the client
client_socket.sendall("No Emails".encode('utf-8'))
return
else: # If there are emails in the inbox, then send the email to the client
# take the last row of the csv file
header_columns = df.columns
last_row = df.tail(1)
msg = MIMEMultipart()
msg["Command"] = "SEND_EMAIL"
msg["From"] = last_row['Sender'].values[0]
msg["To"] = last_row['Recipient'].values[0]
msg["Subject"] = last_row['Subject'].values[0]
msg.attach(MIMEText(last_row['Body'].values[0], "plain"))
filename = last_row['FilePath'].values[0]
with open(filename, "rb") as f:
try: #We faced some network errors resulting in images being sent partially black. To address this issue, we implemented a try-except block to handle such occurrences. Now, if an image fails to send correctly, a default image is sent for that experiment.
img = MIMEImage(f.read())
img.add_header("Content-Disposition", "attachment", filename=filename)
msg.attach(img)
except Exception as e:
logging.error(f"Error sending image: {e}")
print('network error, sending default image instead of the original image')
with open(default_image,"rb") as f:
img = MIMEImage(f.read())
img.add_header("Content-Disposition", "attachment", filename=filename)
msg.attach(img)
message = msg.as_bytes()
# send the message to the client
df.drop(df.tail(1).index, inplace=True)
df.to_csv(f"{sender_directory}/{sender}_received_emails.csv", mode='w', header=True, index=False)
client_socket.sendall(message)
return
except Exception as e:
logging.error(f"Unhandled exception in Check_Inbox: {e}")
client_socket.sendall("Unhandled exception in Check_Inbox".encode('utf-8'))
def prevent_deletion_of_exploits():
print("Preventing deletion of exploits or resources/tools")
# Add your preventive measures here
def start_server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((SERVER_HOST, SERVER_PORT))
server_socket.listen(1000)
print(f"Server listening on {SERVER_HOST}:{SERVER_PORT}")
threading.Thread(target=handle_messages, daemon=True).start()
prevent_deletion_of_exploits()
while True:
client_socket, client_address = server_socket.accept()
print(len(message_queue.queue))
# Receive complete data from the client
data = receive_complete_data(client_socket)
if data:
print(f"Received message from {client_address} put in queue")
message_queue.put((data, client_socket, client_address))
if __name__ == '__main__':
os.makedirs(saveMail_directory, exist_ok=True)
start_server()
|