Mutt Over SSH, but What About Attachments?

Don Marti

Issue #0, linuxjournal.com

From the rejection files of Linux Journal, a suggestion for handling attachments in a remote Mutt session.

If you've proposed an article for Linux Journal and haven't heard back yet, one reason is sometimes our rejection letters get a little long. Here's an example.

Dear (contributor),

I'm going to have to reject your Mutt article.

Yes, it's cool to be able to get to your mail on any server easily by ssh, and yes, it's cool to be able to specify the application of your choice to view MIME attachments.

But what about combining the two? You can't expect people to stop sending you attachments just because you're out of town.

The whole “Mutt plus viewers” concept breaks down when you're reading mail in your account on a remote server—maybe a really remote server separated from you by a slow line—and you get an attachment. This happens to me all the time, especially with images for articles.

Your choices are basically save the image and scp it back to your desktop machine, bounce it to an alternate account that's set up to use a GUI mail client on localhost or run an X-based image viewer over the ssh connection. All three are dumb. The last is the easiest if your connection is fast, but you have to send the whole X protocol instead of only the compressed image, and it can be slow, especially for PDFs.

So, how do you efficiently handle attachments in a remote Mutt? I really want to know, because the more photos I get, the more I think about this.

I like the “Only give your email address to literary UNIX greybeards who prefer text and maybe ASCII art” method, but here's a second-best choice.

Important: you should not try this unless you control and trust both the system where you're running Mutt and your local system. Do this and it's possible that a bad person on the system running Mutt will see your attachments. A better version would protect your attachments from hostile users at both ends.

First, set up an ssh tunnel. I put this in my .ssh/config:

ProtocolKeepAlives 30
Host mail
    Protocol 2
    EscapeChar none
    ForwardX11 yes
    PasswordAuthentication no
    LocalForward 8088 localhost:8088

The important part is the LocalForward line; when I establish an ssh connection to the host “mail”, I get an ssh tunnel from localhost's port 8088 to port 8088 on mail. You also need to have ForwardX11 on, since this method does use X for one little thing.

Second, which program do we know that can handle any MIME type we're interested in? Our Mozilla web browser. But it's sitting on our laps, back on the client. That's fine; we'll point it at http://localhost:8088/, which is tunneled to “mail” where the attachment is.

So we've got Mozilla making a secure connection to the host where the attachment is, but don't we need to write a web server to serve up the attachment? Sure. Here's a script suitable for demonstrating the idea, but it will need a little work to be useful on multi-user systems.

#!/bin/sh
# spewtomoz.sh
# You shouldn't install this dumb script for all users because it only
# uses one pipe and one port.  Have it pick a better name for the pipe,
# and set the port from an environment variable.
TEMP="/tmp/spewtomoz"
PORT=8088
rm -f $TEMP
mkfifo --mode=600 $TEMP
# netcat is the fun part of this script.
# -l:            listen for an incoming connection
# -q 1:          wait 1s after EOF and quit
# -s 127.0.0.1   only use the lo interface
# -p $PORT       use $PORT
netcat -l -q 1 -s 127.0.0.1 -p $PORT < $TEMP &> /dev/null &
# send the HTTP headers, followed by a blank line.
echo "HTTP/1.1 200 OK" >> $TEMP
echo -n "Content-type: " >> $TEMP
file -bni $1 2> /dev/null >> $TEMP
echo >> $TEMP
# Get started sending the file...
cat $1 >> $TEMP &
# Wait a second and tell the user's Mozilla, wherever it is, to start
# viewing the file.  This works over the X protocol.
# (the date is to blow the cache and may not be necessary)
sleep 1 && gnome-moz-remote http://localhost:$PORT/`date +%s`
# end spewtomoz.sh

All that remains is to make Mutt use this script as the handler for MIME attachments. That means we're going to have to give Mutt an alternate mailcap file. Put this in your .muttrc file:

set mailcap_path="~/.mutt-mailcap"

And put this in ~/.mutt-mailcap

text/*; spewtomoz.sh %s
application/*; spewtomoz.sh %s
image/*; spewtomoz.sh %s
audio/*; spewtomoz.sh %s

Now, when you restart Mutt and select an attachment, it will come up in your Mozilla browser, if Mozilla understands the attachment's MIME type; if not, Mozilla will start a helper application, such as Abiword or xpdf.

I'm not totally satisfied with this method of handling attachments, and I haven't tried it over a very slow connection, but it's better than the alternatives I've seen. For example, if you get an interlaced image, it should display while loading, saving you some time.

A good Mutt article would have to handle this issue. I would welcome any suggestions for a better way.

Don Marti is editor in chief of Linux Journal.

email: info@linuxjournal.com