« A note to French waiters | Main | Tabbed dialog boxes with CFLAYOUT »

CF through a command-line interface part 2: programmatic calls

In a previous post, I noted Ashwin Matthew's technique of calling CF from a command-line interface with the use of cURL. This idea got me thinking. Using cURL to pass URL parameters to a script is well and good if you are manually typing the calls, but... what if you want to automate the process and and pass dynamic data whenever a certain event happens on your server?

For instance, I often write PHP scripts to automatically handle responses to certain emails that have been sent in to our company. Emails containing unsubscribe requests are processed so that the corresponding email is removed from our newsletter list; support requests get an autoresponse and are passed on to certain personnel; and I've even written a script for a web-based project management site that redistributed any email it received to a dynamic list of project members. All of these tasks happened automatically, as soon as our mail server received an email. Now I've figured out how to do the same thing with ColdFusion-- and this will work without event gateways and even if your mail server is separate from your web server.

The script I've written is meant for passing data from QMail with the use of cURL. There are probably ways of doing the same thing in a Windows environment, but I'll leave that up for others.

First, we need to tell our mail server to pass the email to a script instead of delivering it normally. For QMail, we do that with a ".qmail" file. The name of the file starts with .qmail, has a dash, and then has the name of the user portion of the email address. For example, if we were to intercept emails sent to cli@example.com, our .qmail file would be named ".qmail-cli". Inside the file, we tell the mail server to pass information with a pipe "|" and then the full path of the script we're going to write, like so:

.qmail-cli

| /path/to/callCF.sh

Now for the contents of our script, callCF.sh. Our script is going to read the email from stdin (that's "standard input" for those of you who don't know), then URL-encode it, and then finally use cURL to post it to a ColdFusion page:

callCF.sh

#!/bin/sh

# Function to URL-encode a string
urlencode() {
    # Read the URL encoding in from the urlencode.sed file
    echo "$1" | sed -f urlencode.sed
}

# Gather data from stdin
while read line
do
  data="$data$line%0A"
done < /dev/stdin

# URL-encode the data
data=`urlencode "$data"`

# Use cURL to send the data to ColdFusion
curl "http://[your server]/[your CF script].cfm" -d data=$data

cURL posts the email to your CF script, with a form variable named "data". After that, you've got the power of good old ColdFusion to process it however you like. In a follow-up post, I'll explain my technique for parsing through emails, including how to forward them with the mime-type and attachments intact, and how to do it while preventing email loops.

So, what are the security implications of using this kind of technique? At first, it's tempting to think that this opens several security holes, but after some consideration I'm not sure that it's any less secure than any other method of processing emails. After all, this doesn't change whether or not anyone can send an email to your mail server or post to your web server. You just need to rely on common security practices to ensure that no-one abuses your CF script. For instance, you can code your script so that it only processes posts sent with a password or a user-agent that you configure in cURL.

You may note that the script relies on an external file that contains all of the URL-encoding transformations (it's easier than having them all in the script). Here's what that file looks like:

urlencode.sed

s/%/%25/g
s/ /%20/g
s/ /%09/g
s/!/%21/g
s/"/%22/g
s/#/%23/g
s/\$/%24/g
s/\&/%26/g
s/'\''/%27/g
s/(/%28/g
s/)/%29/g
s/\*/%2a/g
s/+/%2b/g
s/,/%2c/g
s/-/%2d/g
s/\./%2e/g
s/\//%2f/g
s/:/%3a/g
s/;/%3b/g
s//%3e/g
s/?/%3f/g
s/@/%40/g
s/\[/%5b/g
s/\\/%5c/g
s/\]/%5d/g
s/\^/%5e/g
s/_/%5f/g
s/`/%60/g
s/{/%7b/g
s/|/%7c/g
s/}/%7d/g
s/~/%7e/g
s/	/%09/g

I'm curious to know whether anyone else has used this technique in the past, or would consider using it. Does anyone care to comment on the security of this code?

Download the .qmail, shell script, and sed files.

Comments (4)

nice work thanks

You might not need the sed entries for - and .

See here

Thank You !

Some even say that reduced mobility in sperm also decreases the fertility of a man. On top of that, the list goes on and on.