How to send email through your Google account with Python

June 29, 2007

Seems like a pretty trivial task, yes?

Generally speaking, it is, but I ran into a few fun things that make this worth writing about.

Background:

I have a server-side process that I want to send a notice of completion to a customer (and his customer), so I can’t just send it from jobuser@server.example.com — I want it to look presentable.

On Solaris, the “mailx” command has the option to change the “From:” address, and that is usually enough to make an e-mail look decent and get past a lot of the relay blockers. I’ve not yet found a similar solution for Linux (although, I’m sure it’s there).

Instead, I wrote a small python script to do this for me. As a bonus, I want to send it through my Google Apps e-mail account (well, a special service account created for this purpose). Sending through Google has the other feature of it is less likely to get blacklisted by some random ISP as our corporate IPs get from time to time.

So, some code …

#
# Grab the smtp and mxDateTime (excellent Date/Time manipulation
# from eGenix) packages:
#
import smtplib
from mx.DateTime import *

#
# We want yesterday’s date
#
now = now() – RelativeDateTime(days=1)

YEAR = now.year
MONTH = now.month
DAY = now.day

#
# Define our GMail auth information
#
smtpuser = ‘service.account@example.com’
smtppass = ‘sekratpassword’

#
# We have to define the From, To, and BCC addresses
#
# Note the “toaddrs” needs to be set up with 2 different formats, depending
# where in the mail message it is used
#
fromaddr = ‘Service Account <service.account@example.com>’
toaddrs = ‘customer@customer.com, theircustomer@theircustomer.com’.split()
bccaddrs = ‘me@example.com’

#
# Build the subject line
#
subject = (“Report For %02d/%02d/%04d” % (MONTH, DAY, YEAR))

#
# Start building the message with the mail header … again, note the join() used
# on the toaddrs
#
# NOTE: the placement and number of “\r\n”s are important … if you do not follow
# the RFC, your e-mail won’t get very far!
#
msg = ("From: %s\r\nTo: %s\r\nBcc: %s\r\nSubject: %s\r\n\r\n" %
(fromaddr, ", ".join(toaddrs), bccaddrs, subject))

#
# Now append the body of the message.
#
msg += “Hello,\r\n\r\nYour report is available at:\r\n\r\n”
msg += ” http://www.example.com/report.php"
msg += "\r\n\r\nRespectfully,\r\n\r\nCustomer Name\r\n"

#
# Create an SMTP object with the server “smtp.gmail.com” (their outbound mailserver)
#
server = smtplib.SMTP(‘smtp.gmail.com’)

#
# Optional, but it gives you a nice view of the conversation for coding/debugging
# purposes
#
server.set_debuglevel(1)

#
# Start the conversation with EHLO
#
server.ehlo()
#
# Request STARTTLS
#
server.starttls()
#
# And say EHLO again
#
server.ehlo()
#
# Login to the server with SMTP AUTH now that we’re TLS’d and client identified
#
server.login(smtpuser, smtppass)
#
# Finally, send the mail!
#
server.sendmail(fromaddr, toaddrs, msg)
#
# Herein lies a hack to work around a bug in this version of python and the
# associated libs. Read more about it here and patch your version, or be lazy
# like me and just trap the Exception and move on with life. 🙂
#
try:
server.quit()
except:
pass

That’s it in a nutshell.

If I may go back and plug the mxDateTime package from eGenix again, and I may, it’s some nice stuff. They fill the gaps between what the standard python package starts to do and what you really want to do.

In our example above, to get yesterday’s date, it’s as simple as:

now = now() - RelativeDateTime(days=1)

Want the last Monday of the month?

LastMonday = now() + RelativeDateTime(day=28, weekday=(Monday,0))

Granted, that will give you the same time of day as when the line is run, but you can override that with adding the options to RelativeDateTime of:

hour=0, minute=0, second=0

or just use LastMonday.day

Fun stuff, I highly recommend their stuff (they have lots of fun packages)

add to del.icio.usDigg itStumble It!Add to Blinkslistadd to furladd to ma.gnoliaadd to simpyseed the vineTailRank

Advertisements

How to make fetchmail happy with the server’s SSL cert

June 29, 2007

Have you tried running fetchmail against a POP3S server and gotten these messages over and over?

fetchmail: Server certificate verification error: unable to get local issuer certificate
fetchmail: Server certificate verification error: certificate not trusted
fetchmail: Server certificate verification error: unable to verify the first certificate

Congratulations, you are not alone. Looking around, I see a lot of people having this problem and the answers are usually not as clear as they could be. Let’s see if I can make it less clear, too.

  1. Make sure a recent openssl is installed and your fetchmail is linked against it, etc, etc
  2. Run “openssl s_client -connect pop.gmail.com:995 -showcerts” (hit enter after the output to exit)
    Cut and paste the stuff between the “—–BEGIN CERTIFICATE—–” and “—–END CERTIFICATE—–” lines (inclusive) into a file pop.gmail.com.pem
    Review the rest of the output for the “issuer=” line (in this case, “Equifax Secure Certificate Authority”)
    Go here and grab the “Base-64 encoded X.509” version of the cert for “Equifax Secure Certificate Authority”
    Rename that file with a “.pem” extension
    Make a certs directory somewhere (i.e. /usr/local/etc/fetchmail/certs) and put both files in it
    Run “c_rehash /usr/local/etc/fetchmail/certs”
    Add this to your .fetchmailrc under the “poll” section for this server: “sslcertck sslcertpath /usr/local/etc/fetchmail/certs”
    Run “fetchmail -v” and see if the warnings are gone!

    You will need to do this for each server that you poll with SSL (both the server and its issuer’s PEM).


SPF – Not just for sunscreen anymore!

June 29, 2007

Unless you are a spam generator (in which case, please go jump into a wood chipper), you want to do everything you can to help stop the spam onslaught.

One thing all domain owners can do is setup a SPF record in the DNS zone.
For all sorts of information, check out this link. They have a nice wizard for helping you create your SPF record, too. At first, it seem complicated, but trust me, it’s not.
A simple example is just:
IN TXT "v=spf1 mx ~all"
Which just means, “Accept mail from my domain from any of my MX servers (as listed in my DNS zone).”If you have someone else process your inbound mail (say an anti-spam/anti-virus filtering service like we provide), but it ends up on your own mail server, and you send your own mail directly, you might have something like:

IN TXT "v=spf1 mx a:mymailserver.example.com ~all"
Which means, “Accept mail from my domain from any of my MX servers as well as the server mymailserver.example.com.” The “a:” tells the receiving side to lookup an A record for mymailserver.example.com and if the IP of the connecting sender matches, all is good!If you send mail to a use of Google Mail, Google really appreciates your use of an SPF record and even puts a nice record in the header of the received email:

Received-SPF: pass (google.com: domain of user@example.com designates 1.2.3.4 as permitted sender)
This was sent from a customer directly from their Exchange server that we listed as an “a:” record in their DNS zone.So, that’s the sender’s side, how about being on the receiving side …

Some MTAs already support SPF natively, and almost all other current MTAs have patches or software plugins that provide SPF support. In fact, Ubuntu’s 7.04 release (Feisty Fawn) has announced support for their Postfix package. Have I mentioned yet that I like Ubuntu? 🙂 With luck, they will back port it into their LTS distribution … maybe.

If your MTA doesn’t already support SPF, there are a number of methods to stuff it in … I suggest to just start Googling around.

For Postfix on a non-7.04 Ubuntu server, check out this link. The worst part is getting all of the prereq perl modules in place.

If you want to skip all of this work, but want to keep your own mail server, feel free to contact us at info at officepcsupport.com — we can do the pre-filtering of anti-spam/anti-virus for you and then relay the mail to your server. We also do POP/IMAP/Webmail services for offsite email storage if that’s what you would prefer.

With luck, if more and more domains, servers, and relays implement SPF, at least the faked originator spam will loose ground, so put on your SPF already, will ya!?!

add to del.icio.usDigg itStumble It!Add to Blinkslistadd to furladd to ma.gnoliaadd to simpyseed the vineTailRank