I am a newbie to python programming. I am writing small smtp client for testing the POSTFIX smtp server implementation. I have used python smtplib for the same. Here is the code snippet.
import smtplib
def smtpTest(serverStr, mode=1):
servername = serverStr
server = smtplib.SMTP(servername, 25)
try:
server.set_debuglevel(True)
server.ehlo()
# If we can encrypt this session, do it
if server.has_extn('STARTTLS'):
server.docmd('STARTTLS\r\n RSET')
finally:
print "Closing the smtp session ...."
server.quit()
if __name__ == "__main__":
print "Closing the session now ..."
smtpTest(<ip address of smtp server>, 1)`
I am using the docmd() which should for the smtp server response. I am trying to check the smtp server behavior for the command 'STARTTLS\r\n RSET'.
Response details:-
My expectation is that the smtp server, if vulnerable, should give 2 response codes in sequence. One for the STARTTLS and other for RSET commands. My observation is that the server gets ready with tls tunnel and then the code enters in the finally block to close the session. So my conclusion is that the server is not vulnerable to STARTTLS.
My query:-
If I reverse the command string as 'RSET\r\n STARTTLS', I get the 2 response codes. With the reverse string of resetting and then starting tls, the quit function call ends the session and the command display for starttls appears after the client sends the quit command. I wanted to synchronize the call of quit only after I get the complete response from the server. In this case, the first being for RSET and then for STARTTLS.
Any pointers will be of great help.
Related
This question already has an answer here:
aiosmtpd - python smtp server
(1 answer)
Closed 3 months ago.
I had "successfully" made an SMTP server. The code works fine connecting to SMTP clients. But it is neither able to recieve emails nor send it. I tried with various test servers and also the standard gmail/yahoo etc.
Here is the code:
# Copyright 2014-2021 The aiosmtpd Developers
# SPDX-License-Identifier: Apache-2.0
import asyncio
from asyncio.base_events import Server
import logging
import aiosmtpd
from aiosmtpd.controller import DEFAULT_READY_TIMEOUT, Controller
import ssl
from aiosmtpd.smtp import Envelope, Session
from smtplib import SMTP as SMTPCLient
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain('cert.pem', 'privkey.pem')
class ExampleHandler():
async def handle_RCPT(self, server, session, envelope, address, rcpt_options):
if address.endswith('#example.com'):
print('not relaying to that domain bro :(')
return '550 not relaying to that domain'
envelope.rcpt_tos.append(address)
print(address+" "+"is added to rcpt_tos")
# Make an envelope for the recipient with the same content.
return '250 OK'
# async def handle_EHLO(self, server, session, envelope):
# print('EHLO from %s' % envelope.mail_from)
# return '250-Hello, how are you?\n250-I am fine\n250 HELP'
async def handle_DATA(self, server, session, envelope):
print('Message from %s' % envelope.mail_from)
print('Message for %s' % envelope.rcpt_tos)
print('Message data:\n')
for ln in envelope.content.decode('utf8', errors='replace').splitlines():
print(f'> {ln}'.strip())
print()
print('End of message')
# Dump the contents of envelope.content to a file.
fi=open('./mailbox/firstletter.txt','w')
fi.write(envelope.content.decode('utf8', errors='replace'))
fi.close()
# print everything in DATA.
# Send the envelope to the recipient.
return '250 Message will be delivered'
#Define Relay server.
async def amain(loop):
cont = Controller(ExampleHandler(),hostname='x.x.x.x', port=25, server_hostname='Galam Limited',ready_timeout=5000)
# Combining ExampleHandler and Controller into a single Controller.
cont.start()
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG)
loop = asyncio.get_event_loop()
loop.create_task(amain(loop=loop))
try:
loop.run_forever()
except KeyboardInterrupt:
pass
You can test the server reachability . I am stuck and spent 2 whole days to no avail. The issue is definetely not connectivity, I put the port 25 open. Made sure there are no external issues with godaddy either. Any help will be appreicated.
Edit:1
A quick peak at the wire shark data shows absolutely no packet is being transmitted to the outside when I run the client script.
Here is the clinet script I used for testing.
from smtplib import SMTP as Client
from aiosmtpd.controller import Controller
class controller:
hostname='192.168.1.33'
port=25
client = Client(controller.hostname, controller.port)
r = client.sendmail('a#galam.in', ['tester#192.168.1.200'], """\
From: Anne Person <anne#galam.in>
To: Bart Person <tester#192.168.1.200>
Subject: A test
Message-ID: <ant>
Hi Bart, this is Anne.
""")
SMTP 250 code means that a successful connection has been established however the remote host you are sending mails to might have categorized the domain the mail is being sent from as not legitimate.
This can happen if your domain is not authenticated/verified.
You can relay your messages through a trusted SMTP service like sendgrid
You can also check if your domain is verified by sending a mail from your service to check-auth#verifier.port25.com. Port25 is an automated tool that verified your DNS records, SPF records etc.
Hope this works for you!
I made a python socket server recently that listens on port 9777 the server is suppose to accept connections and once it does will allow you to send information to the client. The client will then print out whatever it received. However, I found that after I sent some data the server would hang until i reinitialized a new connection. Is there a reason for this and if so how can I prevent it from happening
The code of the server is :
import socket
import sys
host='0.0.0.0'
port=9777
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind((host,port))
s.listen(10)
c,a=s.accept()
while True:
command=raw_input('[input>] ')
if 'data' in command:
c.send('continue')
data=c.recv(1024)
print data
else:
continue
the code will only send data if the word data is in the string. Here is the code for the client:
import socket
import sys
host='192.168.0.13'
port=9777
while True:
try:
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((host,port))
except:
continue
while True:
d=s.recv(9999)
print d
s.send('received')
My goal is to setup a connection between server and client. I want the server to be able to accept input from a user in a while loop and send the input to the client. The client needs to be able to receive information and when it does it will send a response to the server. Then the user can continue sending data to the server until they decide to terminate the program. However the server keeps hanging after sending data once to the client. Can anyone tell me how I can prevent that?
I try this code in my computer it's work fine , maybe you need to change host='192.168.0.13' to host='localhost'
and host='0.0.0.0' to host='localhost'
look at this picture
and if this problem stay maybe your ip address is the same of other device in the network for that try to run this command ipconfig /renew
For a class assignment I need to use the socket API to build a file transfer application. For this project there two connections with the client and server, one is called the control and is used to send error messages and the other is used to send data. My question is, on the client side how can I keep the control socket open and waiting for any possible error messages to be received from the server while not blocking the rest of the program from running?
Example code (removed some elements)
#Create the socket to bind to the server
clientSocket = socket(AF_INET,SOCK_STREAM)
clientSocket.connect((serverName,portNum))
clientSocket.send(sendCommand) # Send to the server in the control connection contains either the list or get command
(If command is valid server makes a data connection and waits for client to connect)
clientData = socket(AF_INET,SOCK_STREAM)
clientData.connect((serverName,dataport)) #Client connects
recCommand = clientData.recv(2000) #Receive the data from server if command is successful
badCommand = clientSocket.recv(2000) #But if there is an error then I need to skip the clientData.recv and catch the error message in bad Command
when there is an error, the data-socket should be closed by the server, so recv ends automatically.
I have a python script to run a SMTP server in localhost. This is my very simple code:
import smtpd
import asyncore
class CustomSMTPServer (smtpd.SMTPServer):
def process_message(self, peer, mailfrom, rcpttos, data):
print 'Receiving message from:', peer
print 'Message addressed from:', mailfrom
print 'Message addressed to :', rcpttos
print 'Message length :', len(data)
server = CustomSMTPServer(('127.0.0.1', 25), None)
asyncore.loop()
If I send an email from an email client running on localhost the email arrives successfully in the STMP server. However, if I send an email from an email client running in a computer located in the same local network (192.168.1.1/24), it doesn't succeed. Here below the error I get from Outlook Express:
The connection to the server has failed. Account 'localhost', Server '192.168.1.115'.
Protocol SMTP, Port: 25, Secure(SSL): No, Socket Error: 10061, Error Number: 0x800CCC0E
Just in case, I deactivated McAfee firewall in both PCs but I still get the same error.
Where can be the problem? Does it have anything to do with the asyncore.loop() method? Thanks!
Your server is running on the loopback interface:
server = CustomSMTPServer(('127.0.0.1', 25), None)
That interface is not reachable from any external network, only from the local machine.
You will need to start your email server on a real network interface (such as 192.168.1.115, based on the error message).
Also, I doubt you'll be able to retrieve any message anyway. You are running an SMTP server: it accepts messages over SMTP but will not provided POP3 / IMAP services, so you can't retrieve messages using a remote email client. The SMTP server can be used to store messages in a local file-based message store though (and en email client running on the same machine could retrieve messages from the file, if correctly formatted).
I am trying to learn about how to send emails using Python. Using scripts from Tutorial's Point, and Stack Overflow I have created a basic script which can send emails using Gmail. I have a few questions about several lines of code. They appear to be communicating with the Gmail Server.
server = smtplib.SMTP('smtp.gmail.com:587')
server.ehlo()
What does server.ehlo mean? Is it specific to gmail?
server.starttls()
What does this mean?
server.login(username,password)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()
What is server.quit()?
ehlo is part of the protocol exchange between the client side and server side
ehlo gives the name of the client side to the server
starttls starts up the encryption and authentication for the SSL socket layer
login sends credentials as described in the SMTP spec
sendmail does the other SMTP protocol commands, mail from, rcpt to and data
quit sends a command to close the connection from the server end