Confused about Python SMTP client - python

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

Related

Gmail blocks python code trying to login from amazon server

I have a python code which crawls some websites and send me some emails.
The code is working fine on my computer. Now I am trying to run the same code on an Amazon web server. However, google blocks the code. Is there any workaround?
import smtplib
# Send email to my personal email address
def send_email(subject, msg):
try:
server = smtplib.SMTP('smtp.gmail.com:587')
server.ehlo()
server.starttls()
server.login('e******#gmail.com', 'S****')
message = 'Subject: {}\n\n{}'.format(subject, msg)
server.sendmail('e*#gmail.com', 'e*#gmail.com', message)
server.quit()
print("Success: Email sent!")
except:
print("Email failed to send.")
As answered in the comment section by Furas, Gmail may blocks access from untrusted programs and the programmer may have to create a separated password for these programs. Allow less secure apps to access your Gmail account

Python freezes on smtplib.SMTP("smtp.gmail.com", 587)

I am attempting to create a script that send an email, using Gmail. However, my code freezes when the line below is ran:
smtplib.SMTP("smtp.gmail.com", 587)
It is before my username and password are entered, so it is nothing to do with my Gmail account. Why is this happening? I am using Python 3.6.3
The full code is below:
import smtplib
# Specifying the from and to addresses
fromaddr = 'XXX#gmail.com'
toaddrs = 'YYY#gmail.com'
# Writing the message (this message will appear in the email)
msg = 'Enter you message here'
# Gmail Login
username = 'XXX#gmail.com'
password = 'PPP'
# Sending the mail
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(username,password)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()
It is most likely a firewall or similar issue. On the machine having the issue, try running this on the command line:
ping smtp.gmail.com
Assuming that works, then try:
telnet smtp.gmail.com 587
I'm assuming a Linux machine with this command. You'll need to adapt for others. If that connects, type ehlo list and the command should show some info. Type quit to exit.
If that doesn't work, then check your iptables.
sudo iptables -L
This will either show something like ACCEPT all under Chain INPUT or if not, you'll need to ensure that you are accepting established connections with something like:
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
The output chain is often open, but you should check that too.
If you are on AWS, check your security group isn't blocking outgoing connections.
If it's hanging in the call to smtplib.SMTP, and the server requires SSL, then most likely the issue is that you need to call smtplib.SMTP_SSL() (note the _SSL) instead of calling smtplib.SMTP() with a subsequent call to server.starttls() after the ehlo. See SMTPLib docs for SMTP_SSL for more details.
This fixed the issue for me.
Use server.ehlo() in your code.
Code Snippet:
server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls()
For authentication error:
http://joequery.me/guides/python-smtp-authenticationerror/
Add following code snippet and run again.
try:
server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls()
server.login(username,password)
server.sendmail(fromaddr, toaddrs, msg)
server.close()
print 'successfully sent the mail'
except:
print "failed to send mail"
You don't need the ehlo call. These days, you do need an app password with Gmail. And crucially, you need the right server address. I stupidly copied smtp.google.com from some bad instructions, and the call hung. Changing to smtp.gmail.com fixed it. Duh.

How to making the smtlib.SMTP synchronous functions

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.

python SMTP - socket error

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

STARTTLS extension not supported by server

This maybe a repeated question but I'm still facing issues on this, hope there's a solution around. Thanks in advance.
I'm trying to send mail through the company's server
I'm currently using Python version 2.6 and Ubuntu 10.04
This is the error message I got
Traceback (most recent call last):
File "hxmass-mail-edit.py", line 227, in <module>
server.starttls()
File "/usr/lib/python2.6/smtplib.py", line 611, in starttls
raise SMTPException("STARTTLS extension not supported by server.") smtplib.SMTPException: STARTTLS extension not supported by server.
Here goes part of the code
server = smtplib.SMTP('smtp.abc.com', 587)
server.set_debuglevel(1)
server.ehlo()
server.starttls()
server.ehlo()
server.login('sales#abc.com', 'abc123')
addressbook=sys.argv[1]
Remove the ehlo() before starttls().
starttls() + ehlo() results in two HELLO messages, which cause the server remove the STARTTLS in the reply message.
server = smtplib.SMTP('smtp.abc.com', 587)
server.starttls()
server.ehlo()
server.login('sales#abc.com', 'abc123')
I had a similar issue trying to send a mail through the company's server (without autentication needed)
I solved removing the server.ehlo and removing the port number:
server = smtplib.SMTP("smtp.mycompany.com")
server.sendmail(fromaddr, toaddr, text)
removing server.ehlo() before server.starttls() helped me get my code working! Thank you, Leonard!
my code:
s = smtplib.SMTP("smtp.gmail.com",587)
s.starttls()
s.ehlo
try:
s.login(gmail_user, gmail_psw)
except SMTPAuthenticationError:
print 'SMTPAuthenticationError'
s.sendmail(gmail_user, to, msg.as_string())
s.quit()
The error says it all, it seems the SMTP server sou are using doesn't support STARTTLS and you aru issuing server.starttls(). Try using the server without calling server.starttls().
Without more info is the only I can say.
I am able to resolve the issue with below code, by adding port number with server name:
server = smtplib.SMTP('smtp.abc.com:587')
from smtplib import SMTP_SSL, SMTP, SMTPAuthenticationError
from ssl import create_default_context
from email.message import EmailMessage
sender = 'aaa#bbb.com'
description = "This is the test description supposed to be in body of the email."
msg = EmailMessage()
msg.set_content(description)
msg['Subject'] = 'This is a test title'
msg['From'] = f"Python SMTP <{sender}>"
msg['To'] = 'bbb#ccc.com'
def using_ssl():
try:
server = SMTP_SSL(host='smtp.gmail.com', port=465, context=create_default_context())
server.login(sender, password)
server.send_message(msg=msg)
server.quit()
server.close()
except SMTPAuthenticationError:
print('Login Failed')
def using_tls():
try:
server = SMTP(host='smtp.gmail.com', port=587)
server.starttls(context=create_default_context())
server.ehlo()
server.login(sender, password)
server.send_message(msg=msg)
server.quit()
server.close()
except SMTPAuthenticationError:
print('Login Failed')
By testing and researching myself, I found out that the gmail servers do not use tls connections with python anymore.
You must not use service.startttls(). Gmail service do not support this type of connection anymore.
Also remember to use the SMTP ports (mail reserved ports) for sending emails.
POP3 and IMAP ports for receiving email.
s_u = "Test"
service = smtplib.SMTP_SSL("smtp.gmail.com", 465)
service.ehlo()
service.sendmail("SENDER_EMAIL","RECEIVER_EMAIL","MESSAGE")
You can't send the email even if you put the correct credentials,
look at this: Login credentials not working with Gmail SMTP
Are you sure that you want to encrypt (StartTLS) the connection to the mail server? I would contact someone who knows the insides of that server to see what protocol/encryption to use.
You say that upon removing the call to server.starttls(), you get a different series of error messages. Could you please post those messages as well?
Also, you might want to read up on StartTLS so you understand what it is and why you would want to use it. It seems you're writing a Serious Business program, in which case you'll probably want to understand what you are doing, security-wise.
Yes putting server.starttls() above server.ehlo() solved this.

Categories

Resources