I'm writing this currently for an assignment but years back I had the same problem and just gave up. Further searches had me try a variety of things and I cannot get past the login portion.
from socket import *
from ssl import *
msg = "\r\n I love computer networks!"
endmsg = "\r\n.\r\n"
clientSocket = socket(AF_INET, SOCK_STREAM)
mailserver = getaddrinfo('smtp.gmail.com',465, AF_INET, SOCK_STREAM, IPPROTO_TCP)[0][4]
clientSocket = wrap_socket(clientSocket)
clientSocket.connect(mailserver)
recv = clientSocket.recv(1024)
print recv
if recv[:3] != '220':
print '220 reply not received from server.'
clientSocket.send('EHLO Nolan\r\n')
recv = clientSocket.recv(1024)
print recv
if recv1[:3] != '250':
print '250 reply not received from server.'
clientSocket.send('AUTH LOGIN ' + 'my Google email'.encode('base64','strict'))
recv = clientSocket.recv(1024)
print recv
print recv.split()[1].decode('base64')
clientSocket.send("my password".encode('base64','strict'))
recv = clientSocket.recv(1024)
print recv
# And onto other tasks
I'm under the impression I don't need STARTTLS as I start the connection with SSL. If I change AUTH LOGIN to AUTH PLAIN it doesn't know how to decode it. If I use PLAIN but don't encode it my program just hangs. If I terminate it with "\n\r" (not encoded) I get a broken pipe. Using the code above I get the password request.
Then sending the password I get 535-5.7.8 Username and Password not excepted.It's the same password I sign in with?!? I already setup my account to allow less secure devices. 2-step verification... started the process seems to be orientated to mobile phones, not my python app.
I've changed EHLO to use my IP, as I believe RFC 5321 says that's how it should be. Didn't matter.
I've looked through RFC 4954...
I dug into smtplib to uncover "AUTH PLAIN " + encode_base64("\0%s\0%s" % (user,pass),eol='') Just hangs... waiting...
I have no clue.
Update
I changed the smtplib to output every string submitted. This confuses me even more:
ehlo [127.0.1.1]
AUTH PLAIN [almost forgot one can decode this base64]==
mail FROM:<[gmail account]>
rcpt TO:<[hotmail account]>
data
quit
My AUTH string is exactly the same but it hangs. And I am receiving the email at my hotmail account (using smtplib, not my code).
If you want a basic, non-SSL connection to Gmail, you can use this:
import smtplib
gmail = smtplib.SMTP("smtp.gmail.com",587)
gmail.ehlo() #open the connection
gmail.starttls()
gmail.login("gmaillogin","gmailpassword") #login*
gmail.quit() #close the connection
*Note: You will need to generate a gmail application password from your google account.
Edit:
If you want to use SSL encryption, use this (thanks to furas):
import smtplib
gmail = smtp.SMTP_SSL("smtp.gmail.com",465)
gmail.ehlo()
gmail.login("gmaillogin","gmailpassword")
gmail.quit()
As is typically my fashion, it's the simple things. I just spent hours looking over one program and Googling only to have one error pop out at me: the parameter order in my definition was not how I used it in my code.
Here... I changed my code to use AUTH PLAIN and the issue... I had been putting in '\n\r' not '\r\n' (if I had ended the command with anything, only omitted because '\n\r' produced errors on some commands and went through okay on others). Thank you for classical music to study by on your favorite streaming video site. It raised my intelligence briefly. :)
clientSocket.send('AUTH PLAIN ' + encode_base64("\0%s\0%s" % ([email],[password]), eol="") + '\r\n')
Related
i've a python script, run on a raspeberry pi that monitoring my server room and periodically send me an e-mail and make other stuff.
First time script is running it send a notification and works fine, then wait for a time (5 or 30 minutues) depending if an alarm is triggered, so i've write a for loop to wait. when the loop is finish, script make a call of the function for sending e-mail and python return an error.
Could someone help me ?
i test it also on debian 7.7.0 box and i've the same error.
Below a sample script and the error.
Thanks in advance.
Dom.
File "/usr/lib/python2.7/smtplib.py", line 361, in getreply
raise SMTPServerDisconnected("Connection unexpectedly closed")
smtplib.SMTPServerDisconnected: Connection unexpectedly closed
# Import
from time import sleep
import time
import smtplib
import sys
import string
smtp_server = "10.0.0.4" # mail server address
mail_from = "server#domain.com"
mail_to = "user#gmail.com"
mail_subj = "Server room notify"
server = smtplib.SMTP(smtp_server)
valore = 24 # value for the funtion
def SendAlertEmail(t_value):
log_t = time.strftime("%d/%m/%A %H:%M:%S ")
Text = string.join("Server room notify \n " + str(log_t) + str(t_value))
Body_email = string.join((
"From: %s" % mail_from,
"To: %s" % mail_to,
"Subject: %s" % mail_subj,
"",
Text
), "\r\n")
server.sendmail(mail_from,mail_to,Body_email)
return
SendAlertEmail(valore) # calling from here works fine
for i in range(0,500):
sleep(1)
print(str(i))
SendAlertEmail(valore) # after 500 secs goes in error. Test on debian 7.7.0 python 2.7.3 gcc 4.7.2
smtplib opens a TCP connection at the creation of the SMTP object. You try to reuse it after 500 seconds of inactivity when it is likely that a timeout has already closed the connection.
You should keep only the server name, an create a new SMTP object for each connection in your use case, because the delay between sending messages is too high.
As Serge Ballesta mentions, you should open and close the connection to the server for each one the sent e-mails.
Some months ago I programmed a class to send e-mails in Python, which you can find here: https://github.com/kmundnic/Habitus/blob/master/data_sender.py You create a DataSender object and it handles the connections to the server. Also, it calls a JSON file where the accounts and password is stored, so you don't save it in your code.
Feel free to use it. It was adapted from http://kutuma.blogspot.com/2007/08/sending-emails-via-gmail-with-python.html, as it's mentioned in the comments at the beginning of the source code.
I am trying to read the response or exception of pop3 hotmail server. its very simple question but i am beginner in python don't know how to read it? this is my code:
import poplib
import sys
host = 'pop3.live.com'
port = 995
email='123456#hotmail.com'
pwd='123456'
server = poplib.POP3_SSL(host, port)
try:
server.user(email)
server.pass_(pwd)
if('+OK'):
print 'Email: '+email+'password: '+pwd
server.quit()
sys.exit(1)
except poplib.error_proto:
if('POP+disabled'):
print 'Email: '+email+'password: '+pwd
server.quit()
sys.exit(1)
elif('authentication+failed'):
print "wronge user and pass. try again"
continue
continue
in exception "if ('POP+disabled')" used to eliminate that user login and password is correct but the account has not enabled POP3 in options.
when I run the above code then it also display email password whether i put wrong password...
Can any body help me please how to handle this problem?
You can use the server.getwelcome() method to check for the server response before proceeding into parsing messages.
The server object lets you request the list of messages after authentication and then you can call retr to retrieve each message.
welcomeresp = server.getwelcome()
if welcomeresp.find("+OK"):
numMessages = len(server.list()[1])
for i in range(numMessages):
for j in server.retr(i+1):
server_msg, body, octets = j
for line in body:
print line
Take a look at the documentation for the POP library for more information and an example:
https://docs.python.org/2/library/poplib.html
The Python logging library provides a class called "SMTPHandler" that will let me e-mail myself the outputs of logging commands. I've some pasted below some example code I found on a (possibly old) website for the library. I can modify it to get it to work with either gmail or my ISP as the SMTP server, but both cases require my password. I currently know of two possible solutions:
I can hardcode my password, which I'd prefer not to do, since this code finds its way onto a cloud revision control server.
I can file my password away in a text file on my machine and have my code read it, which seems ugly. With a more effort I may be able to store the password encrypted, rather than as plaintext.
I'm using a Mac, and I can e-mail myself by running mail on the command line and get the e-mail just fine. I don't know what mail is doing but it may be able to get my SMTP server details from the same place that Mac Mail reads them from and then use the external SMTP server. I tried setting MAILHOST="localhost" in the Python code below and that didn't work.
Is there a better way than #1 or #2 to get these e-mails to my gmail address?
import logging, logging.handlers
MAILHOST = 'beta'
FROM = 'log_test5#yourdomain.com'
TO = ['arkadi_renko']
SUBJECT = 'Test Logging email from Python logging module (non-buffering)'
def main():
log = logging.getLogger("")
log.setLevel(logging.DEBUG)
hdlr = logging.handlers.SMTPHandler(MAILHOST, FROM, TO, SUBJECT)
hdlr.setFormatter(logging.Formatter("%(asctime)s %(levelname)-5s %(message)s"))
log.addHandler(hdlr)
log.info("Test email contents")
log.removeHandler(hdlr)
if __name__ == "__main__":
main()
I needed to do the exact same thing. You can give smtplib a try. Something like
import smtplib
from email.mime.text import MIMEText
msg = MIMEText('YOUR_MESSAGE_BODY')
me = 'YOUR_SOURCE#EMAIL.COM'
you = 'YOUR_TARGET#EMAIL.COM'
msg['Subject'] = 'YOUR_MESSAGE_SUBJECT'
msg['From'] = me
msg['To'] = you
s = smtplib.SMTP('localhost')
s.sendmail(me, [you], msg.as_string())
s.quit()
No password is involved.
If you encounter errors like
...
error: [Errno 61] Connection refused
It probably means you don't have smtp server installed or enabled on your mac, installing postfix (say from macports) should fix that.
I'm trying to send an email in python. Here is my code.
import smtplib
if __name__ == '__main__':
SERVER = "localhost"
FROM = "sender#example.com"
TO = ["wmh1993#gmail.com"] # must be a list
SUBJECT = "Hello!"
TEXT = "This message was sent with Python's smtplib."
# Prepare actual message
message = """\
From: %s
To: %s
Subject: %s
%s
""" % (FROM, ", ".join(TO), SUBJECT, TEXT)
# Send the mail
server = smtplib.SMTP(SERVER)
server.sendmail(FROM, TO[0], message)
server.quit()
print "Message sent!"
This runs without error, but no email is sent to wmh1993#gmail.com.
Questions
One thing I don't understand about this code --- what restrictions do I have when setting the FROM field?
Do I somehow have to say that it was from my computer?
What is in place to prevent me from spoofing someone else's email?
Or am I at liberty to do that?
This runs without error, but no email is sent to wmh1993#gmail.com.
This usually means, the message was transferred to your MTA (mailserver) on 'localhost', but this server could not relay it to gmail. it probably tried to send a bounce message to "sender#example.com" and that failed as well. or it sent the message successfully but it landed in gmails spam folder (the message could trigger spam rules since it is missing a date header)
One thing I don't understand about this code --- what restrictions do I have when setting the FROM field?
it must be a syntactically valid email address
Do I somehow have to say that it was from my computer?
no. but that could be the problem why it was not delivered. is your computer on a home/dynamic/dial-up IP? gmail (and many many many other providers) don't accept mail from such IPs. the HELO of your mailserver might be wrong, DNS settings might be incorrect etc. you need to check the server logs. you probably have to configure your local mailserver to relay the message via a smarthost instead of trying to contact the target server directly.
What is in place to prevent me from spoofing someone else's email?
not much, that's why we have so much spam from forged adresses. things like SPF/DKIM can help a bit, but the SMTP protocol itself doesn't offer protection against spoofing.
Or am I at liberty to do that?
technically yes.
Well, since you don't specify exactly what kind of email server you are using and its settings, there are several things that might be wrong here.
First of all, you need to specify the HOST and the PORT of your server and connect to it.
Example:
HOST = "smtp.gmail.com"
PORT = "587"
SERVER = smtplib.SMTP()
SERVER.connect(HOST, PORT)
Then you need to specify an user and his password to this host.
Example:
USER = "myuser#gmail.com"
PASSWD = "123456"
Some servers require the TLS protocol.
Example:
SERVER.starttls()
Then you need to login.
Example:
SERVER.login(USER,PASSWD)
Only then you are able to send the email with your sendmail.
This example works pretty well in most common servers.
If you are using, as it seems, your own server, there aren't much changes you need to apply. But you need to know what kind of requirements this server has.
The "from" field in the email headers specifies the sender's email address. When using smtplib in Python to send an email, the "from" field can be set using the "from_address" argument in the smtplib.SMTP function. Here's an example:
import smtplib
sender_email = "sender#example.com"
recipient_email = "recipient#example.com"
message = "Subject: Example Email\n\nThis is an example email."
with smtplib.SMTP("smtp.example.com", 587) as smtp:
smtp.ehlo()
smtp.starttls()
smtp.login("sender#example.com", "password")
smtp.sendmail(sender_email, recipient_email, message)
Note that many email servers may reject emails that have a "from" address that doesn't match the login credentials.
First, let me say, I already know that this was asked at Forwarding an email with python smtplib already.
The reason that I am posting something so closely related to that question is that I have tried using the answers to that question, I have tried changing things, I have searched Google and relentlessly monkeyed with this for about 5 hours now, and I am willing to spend a lot more time on this
-- I just thought one of you might have the answer though :)
My problem is as follows, I am trying to forward an email from my gmail to another gmail, and in running as many python script as I can to try this simple task, I still cannot figure it out.
Here is the code that I am running(this is my modified version of what was posted in the other form):
import smtplib, imaplib, email, string
imap_host = "imap.gmail.com"
imap_port = 993
smtp_host = "smtp.gmail.com"
smtp_port = 587
user = "John.Michael.Dorian.4"
passwd = "mypassword"
msgid = 1
from_addr = "John.Michael.Dorian.4#gmail.com"
to_addr = "myotheremail#gmail.com"
# open IMAP connection and fetch message with id msgid
# store message data in email_data
client = imaplib.IMAP4_SSL(imap_host, imap_port)
client.login(user, passwd)
client.select()
typ, data = client.search(None, 'ALL')
for mail in data[0].split():
typ, data = client.fetch(msgid, "(RFC822)")
email_data = data[0][1]
client.close()
client.logout()
# create a Message instance from the email data
message = email.message_from_string(email_data)
# replace headers (could do other processing here)
message.replace_header("From", from_addr)
message.replace_header("To", to_addr)
print message.as_string()
# open authenticated SMTP connection and send message with
# specified envelope from and to addresses
smtp = smtplib.SMTP(smtp_host, smtp_port)
smtp.set_debuglevel(1)
smtp.ehlo()
smtp.starttls()
smtp.ehlo()
smtp.login(user, passwd)
smtp.sendmail(from_addr, to_addr, message.as_string())
smtp.quit()
The return from the SMTP debug says everything went okay, and I know that it is sending because I tried replacing the
smtp.sendmail(from_addr, to_addr, message.as_string())
With
smtp.sendmail(from_addr, to_addr, 'test')
And it worked fine. It prints the message.as_string() fine, and I am at a loss as how to get it to forward the email!
It doesn't have to be with SMTP or IMAP or any of this code(though it would be nice if it was) but I would really like to figure out how to do this.
I know its possible because I managed to do it yesterday, and the computer I was working on(running Windows of course) crashed and the file was gone.
For those of you who are wondering why I do not just set google to forward everything automatically, it is because I want a script that will eventually move a large amount of mail, once.
Thank you everyone!
More than likely, the Received: headers of the original email are causing gmail to drop the message. Try removing all of them before forwarding it.
If that doesn't fix it, print out the headers and code it to remove all of the ones that would not normally be there on a newly composed message.
However, why forward this way? It would be easier to just pull from one IMAP account and push it to another IMAP account directly.
In fact you could use Mozilla Thunderbird to add both accounts and just drag and drop the messages from one to the other.