Tuesday, April 03, 2007

E-mails bouncing back with error "smtp;554 refused mailfrom because of SPF policy"

I have a contact form on my website that allows Internet users to generate an e-mail to a 3rd party user of my site. This results in my server sending e-mail from one domain to another domain, neither of which are my domain. (This is a really common scenario for things like evites, greeting cards, send-to-a-friends, etc).

I've recently been receiving reports e-mails sent in this fashion have been bouncing back with this type of error:

Final-Recipient: rfc822;john.doe@anotherdomain.com
Action: failed
Status: 5.5.0
Diagnostic-Code: smtp;554 refused mailfrom because of SPF policy

Thanks to some research and the Fanatical Support over at rackspace, I learned that "SPF" is a fairly new spam prevention technique (Sender Policy Framework). Basically the receiving server checks to see if the sending servers domain is the same as the "from" address domain. The goal is to prevent users from sending e-mails from "george.w.bush@whitehouse.gov" or whatever.

One workaround is to always have the "From" address be from your domain, but that's really not an option for most of these paradigms (You don't want to receive all the replies to someone else's evite)

Luckily openspf.org has a great page on how Web-Generated Emailers Can Avoid Looking Like Forgers. The solution is to tweak your e-mail headers to show that the sender is your domain, like this:

Return-Path: service@mydomain.com
Sender: service@mydomain.com
From: "Jane Doe" <jane.doe@hotmail.com>
Subject: Jane Doe has sent you an e-mail through my site!

In the above example, the e-mails you generate add the "Return-Path" and "Sender" header values to show that you are being honest about the source of the e-mails. One notable side-effect is that service@mydomain.com will now receive the bounce-backs instead of jane.doe@hotmail.com.

The final trick is to get your code to do this. In .NET, the following C# code function sends an SPF-safe e-mail.
static public bool Send(string to, string subject, string body,
string from, string cc, string bcc) { try { //Create your standard mail message MailMessage mail = new MailMessage(); mail.BodyFormat = MailFormat.Html; mail.To = to; mail.Cc = cc; mail.Bcc = bcc; mail.From = from; mail.Subject = subject; mail.Body = body; //Add the headers to avoid SPF errors. (Make sure to change this to your domain) mail.Headers["Sender"] = "service@mydomain.com"; mail.Headers["Return-Path"] = "service@mydomain.com"; //Send the message SmtpMail.SmtpServer = "localhost"; SmtpMail.Send(mail); } catch (Exception ex) { //Maybe log an error return false; } return true; }

You can check the success of this by viewing the original e-mail headers in the generated e-mails. Some receiving e-mail systems (like Gmail) will even append and SPF status to the header so you can see if you were successful.

The header line in my received e-mail went from this:

Received-SPF: neutral (google.com: is neither permitted nor denied by best guess record for domain of jane.doe@hotmail.com)

To this:

Received-SPF: pass (google.com: best guess record for domain of service@mydomain.com designates as permitted sender)

Wednesday, March 28, 2007

Hide form tag, but leave content

I often run into an issue in ASP.NET when I want to include a <form> on a page that posts to a 3rd party website. For example, I could have a PayPal button that posts directly to PayPal (as opposed to doing a "post-back") to the current page.

The problem is that a common practice in ASP.NET is to have a <form runat="server"> tag "high up" in the HTML, usually in the Master page. HTML doesn't allow overlapping <form> tags, so my PayPal button won't work. Since the higher level <form> is in the Master page, it makes removing it pretty messy. As far as I know, there's no built-in "hide this tag, but render the tag's contents" feature for controls. In the past I've maintained two master pages: the normal one and a "no form" version, but I've since discovered a more elegant solution.

I created a class called GhostForm that has a property RenderFormTag. When RenderFormTag is set to false, it doesn't render the <form> tag or closing tag, but does render all of the contents. This works perfectly so I can have my <form runat="server"> high up for most pages, but I can fine-tune it when I need forms posting to other sites or multiple forms.

Here's the code for GhostForm:
using System;
using System.Web.UI;
using System.Web.UI.HtmlControls;

/// <summary>
/// This is a special form that can _not_ render the actual form tag, but always render the contents
/// </summary>
public class GhostForm : System.Web.UI.HtmlControls.HtmlForm
  protected bool _render;

  public bool RenderFormTag
      get { return _render; }
      set { _render = value; }

  public GhostForm()
      //By default, show the form tag
      _render = true;

  protected override void RenderBeginTag(HtmlTextWriter writer)
      //Only render the tag when _render is set to true
      if (_render)

  protected override void RenderEndTag(HtmlTextWriter writer)
      //Only render the tag when _render is set to true
      if (_render)

Thursday, January 11, 2007


Here is a video from the first ruins we stopped at in Palenque, Mexico!

Wednesday, January 10, 2007

Walking in San Cristobal

Continuing our series "The Best of the Rest", here is a short video of walking through the streets of San Cristobal.

Also, I think the San Cristobal hotel room videos are good enough to merit editing and reposting here:

Tuesday, January 09, 2007

Home sweet home

After 26 consecutive days away from home I am finally back in Ann Arbor!

We left for the LAX airport at about 9:00am this morning and I arrived at the Detroit airport at about 7pm! That is why travelling East sucks. But I'm glad to be back, despite the cold and darkness that comes along with it.

We have tons of videos that haven't been posted, so I'm going to keep updating this bad boy for a while with all that never-before-seen content. Here is the "extreme wind noise" video that we tried to post earlier. Thanks to some brilliant video editing, it is now only the "moderately extreme wind noise" video.

Monday, January 08, 2007

Back in Los Angeles

We made it! We crossed the border (after a 2 1/2 hour wait in line) on Saturday and completed a 15 hour driving day by staying at Jessica and Jean's parent's house. Jessica's Mom had an AMAZING spread of food and drinks ready for us, including a Honey baked ham! I think I ate more in 2 hours that night, then the previous 3 weeks combined. But don't worry, because the following morning we went to the fanciest all-you-can-eat breakfast buffet in the world, including shrimp, fillet mignon, made-to-order omelettes, champagne and cheesecake. I am planning on coming back to visit soon and often.

Yesterday, Jess and I dropped Jean and Richard off at the airport and they are back at their respective schools! My flight leaves tomorrow so Jess and I will be hanging out around LA today.

All of our photos are finally online! I bought a flickr "pro" account so you can order prints, or download the original high-res versions of any of them. I uploaded all of our photos to my account so you can see them all in one place in chronological order. Here is the link:


There are nearly 1,000 pictures. I'm going to go through and try to label and rotate them when I get some time. Here are some of my favorites:





Caye Caulker Sharks


MexicoCentralAmerica06-07 387

Friday, January 05, 2007

Heading to the USA Tomorrow

We have spent the last day and a half in Guaymas, Mexico. Today we were on an absolutely amazing beach and have some really great pictures to show for it. We just rolled into this Internet cafe about 10 minutes before it is closing so I won't have time to post anything, but will post tons of photos and videos in the upcoming days when I'm on a good ol' USA Internet connection!

Wednesday, January 03, 2007

Back in Los Mochis

Today our plan was to drive to Los Mochis, then catch an overnight ferry to the Baja peninsula and drive up Baja from there. We had trouble getting in contact with the ferry company so we knew there was a chance that we would not be able to catch a ferry. UNFORTUNATELY, it turned out that all the ferrys are full until MONDAY, a day after our flights leave from Los Angeles, meaning we would have to drive negative infinity miles per hour up the coast in order to catch our flights. We dutifully checked the manual of our Toyota Corolla only to find out that the maxmimum speed is closer to 110mph, not negative infinity.

ANYWAY, our new plan is to spend a day in Guaymas, then drive back up the coast to LA on the 6th and stay at Jess and Jean's parents house (Surprise Elizabeth and Tom! We're coming to your house on the 6th!) If they're busy partying or something, we can just drive straight to Jess' place.

The Internet here is pretty sketchy so no photos or videos today. I'll post lots of uber-cool edited videos when we're back in the states.

Tuesday, January 02, 2007


We are in TEQUILA, Mexico! Yes, THAT Tequila. And I have some in me right now!

We made amazing time the last two days and made it all the way from the Guatemalan border to Tequila which is just West of Guadalajara. Sorry Mom, we drove through Mexico City like I told you we wouldn't, but it was the only way to make it back in time! But the good news is that I didn't tell you until after we made it so you had no reason to worry!

On the bright side, Mexico City and everywhere we have been in Mexico has been incredibly nice and I have never felt unsafe. I don't think Mexico City is any more dangerous than any other 25 million person city.

The city of Tequila is really nice. Lots of little shops and great food and hotel values as always! The restaurant we ate at gave everyone their first tequila drink on the house!

The Internet here is pretty slow again, so I may not get a video up. Below is a photo of the four of us at the temple ruins in Tikal, Guatemala!

Tikal Guatemala Temple Ruins

Monday, January 01, 2007

USC Can Suck My Balls

We're back online after some sparce Internet days in Belize and Guatemala. After spending New Year's Eve in Tapachula, Mexico, we made amazing time and drove close to 1000km to get to Cordoba, Mexico. We made it just in time to see Michigan get their ass kicked by USC in the second half of the Rose Bowl. I'd like to send a big "Eat shit and die" to all you USC fans out there. You too Ohio State.

We're planning to get to Guadalajara by tomorrow, then Los Mochis on the 3rd in time to take a ferry to the Baja peninsula and drive back up to LA. These driving days are pretty rough, but we had an awesome time in Central America and some great days to look forward to in Baja!

New Year's Eve in Tapachula, Mexico

We spent New Year's Eve in Tapachula, Mexico which is just across the border from Guatemala. Crossing the border at 7pm on New Year's Eve was a pain in the ass. The Guatemalan officials were giving us an extremely hard time, saying we can't leave until the next day because the computers were turned off or something. I personally think they were just waiting to be bribed, but our incredible tour guide Jessica wouldn't put up with that shit and started ranting and raving in Spanish until he finally decided that getting rid of her was bribe enough. I regret not having a video of that one! Hopefully we'll get a video of Jess flipping out in Spanish before the end of the trip.

Here is a video of some of the festivities of New Year's Eve!

Temple Ruins in Tikal, Guatemala

Jess planned a trip to some amazing temple ruins in Tikal, Guatemala. Man, do those Mayans like to build temples. There are a ton of them and they are really big. It would probably have been great to live back then, except for all the famine, sacrifices and eventual demise of the civilization. But at least the buildings were cool.

Caye Caulker in Belize!

We made it to Belize! The Internet is slow again so the videos may take a while.