aio-libs / aio-libs/aiosmtpd

Unexpected server response in "DATA_RECEIVED" state

Đang mở
#534 0 bình luận 0 reaction 0 người được giao Xem trên GitHub
Ngôn ngữ chính
Python
Star
373
Fork
105
Merge trung bình
4 phút
Pull request đã merge (30 ngày)
2

Mô tả

I am sending message requests to an SMTP server and analysing the response from the server.
I have the following setup for **aiosmtpd**.
**server.py**:
```
import asyncio
from aiosmtpd.controller import Controller

class CustomSMTPHandler:

async def handle_DATA(self, server, session, envelope):
print(f"Message from: {envelope.mail_from}")
print(f"Message to: {envelope.rcpt_tos}")
print(f"Message data:\n{envelope.content.decode('utf-8')}")
return '250 OK'

# Run the SMTP server
controller = Controller(CustomSMTPHandler(), hostname='127.0.0.1', port=8025)
controller.start()

print("SMTP server is running on port 8025...")

try:
asyncio.get_event_loop().run_forever()

except KeyboardInterrupt:
controller.stop()
print("SMTP server stopped.")
```
**client.py**:
```
import smtplib
import json
from tqdm import tqdm

def run_smtp_tests(server_address, port, tests_file, output_file):
# Load test cases from the JSON file
with open(tests_file, "r") as f:
test_cases = json.load(f)

results = []

count = 0
# Loop through each test case
for test in tqdm(test_cases):
count += 1
input_seq, state, test_input = test
print(f"Running test {count} for state: {state}, input: {test_input}")
print(f"test case: {test}\n")
total_input_seq = input_seq + [test_input]

try:
# Connect to the SMTP server
server = smtplib.SMTP(server_address, port)

# Execute input sequence to reach the desired state
for input in total_input_seq:
print(f"Input: {input}")
if input == "EHLO":
response = server.ehlo()
elif input == "HELO":
response = server.helo()
elif input == "MAIL FROM:":
response = server.mail("rathin.singha2012@gmail.com")
elif input == "RCPT TO:":
response = server.rcpt("rsingha@cs.ucla.edu")
elif input == "DATA":
response = server.docmd("DATA")
server.send("Hi\r\n.\r\n")
elif input == ".":
server.send("\r\n.\r\n")
response = server.getreply()
elif input == "QUIT":
response = server.quit()
else:
server.send(f"{input}\r\n")
response = server.getreply()

print(f"Response: {response}")

results.append((state, test_input, response))
except Exception as e:
results.append((state, test_input, str(e)))
finally:
# Quit the server connection
try:
server.quit()
except:
pass

# Save results to the output file
with open(output_file, "w") as f:
for result in results:
f.write(f"{result}\n")

# Example Usage
run_smtp_tests(
server_address="127.0.0.1",
port=8025,
tests_file="tests.json",
output_file="results.txt"
)
```
Save the following test case in **tests.json** in the same directory:
```
[
[
[
"HELO",
"MAIL FROM:",
"RCPT TO:",
"DATA"
],
"DATA_RECEIVED",
"."
]
]
```
I get the following responses from the **aiosmtpd** server:
```
Input: HELO
Response: (250, b'rajdeep')
Input: MAIL FROM:
Response: (250, b'OK')
Input: RCPT TO:
Response: (250, b'OK')
Input: DATA
Response: (354, b'End data with .')
Input: .
Response: (250, b'OK')
```

I also ran the test case on **opensmtpd** but got a different set of responses:
```
Input: HELO
Response: (250, b'rajdeep Hello [127.0.1.1] [127.0.0.1], pleased to meet you')
Input: MAIL FROM:
Response: (250, b'2.0.0 Ok')
Input: RCPT TO:
Response: (250, b'2.1.5 Destination address valid: Recipient ok')
Input: DATA
Response: (354, b'Enter mail, end with "." on a line by itself')
Input: .
Response: (550, b'5.7.1 Delivery not authorized, message refused: Message is not RFC 2822 compliant')
```

If you look at the final **opensmtpd** response, it returns an error code 550, but **aiosmtpd** accepts it. Why is there a discrepancy?

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.