Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

I often use telnet or netcat to connect smtp servers to send an email as a test.

Does anyone know how you would send an email using telnet or netcat but attach a file as well? There are probably better ways, but I still want to know :-)

I would be happy with a solution that uses a little bash shell to accomplish the goal, but don't want to use any other tools...

share|improve this question
1  
ehlo, this will probably include creating a mime attachment in a file, encode it and then paste it into your window. While it can be very useful to be able to just telnet to an SMTP server, write a short mail and send it (and I can), sending a file like that just isn't very practical. Try 'sendfile' or 'mutt' (even if you don't like to use tools). –  Andrioid Jul 10 '09 at 14:10
    
Just after echo '.'; you might want to add this echo '.'; sleep 3; echo 'quit'; –  user65880 Jan 6 '11 at 12:26

8 Answers 8

Ick. You're going to have to base64 encode the attachment and create the MIME headers.

Rather than generating a new message "on the fly" each time, it would probably be easier just to email yourself a very short example message from a "real" email program (leveraging the work that the people who wrote it did to put the attachment into the proper encoding and creating the MIME headers).

Save that message off into a text file w/ its headers (removing the transport header, of course), and just modify / copy / paste it into telnet or netcat for future sessions.

share|improve this answer
up vote 8 down vote accepted

Okay, so using everyone's comments as a starting point I came up with this silly mess :-) ...

{ 
    sleep 5; 
    echo 'ehlo';
    sleep 3;
    echo 'MAIL FROM:<Test@test.com>';
    sleep 3; 
    echo 'RCPT TO: <kyle@test_dest.com>';
    sleep 3;
    echo 'DATA';
    sleep 3;
    echo -e 'To:kyle@testdest.com\nMIME-Version: 1.0 (mime-construct 1.9)\nContent-Type: application/zip\nContent-Transfer-Encoding: base64\n\n';
    dd if=/dev/urandom bs=4 count=10 2>/dev/null | openssl base64;
    echo '.';
} | telnet mx1.testdest.com 25
share|improve this answer
    
Although since I am just sending random data, not sure if the data is remaining intact ... –  Kyle Brandt Jul 10 '09 at 19:03
    
You have a higher tolerance for tedium than me! >smile< –  Evan Anderson Jul 11 '09 at 1:38

While hand testing SMTP servers by hand is possible and viable, using a tool designed for this will be much easier.

This article explains SWAKS. swaks is designed for smtp server testing. Supports attachments, authentication and encryption!

share|improve this answer
    
+1 Now that is something I am going to start using! :-) –  Kyle Brandt Jul 10 '09 at 19:20

This is what i'm doing to send email with bash. I use it to send me a log file and external IP adress, feel free to use it :

#!/bin/bash
# Send email from bash with attachment
# by Psirac - www.subk.org
from=myfromadress@test.com
to=mytoadress@test.com
mailserver=smtp.test.com
mylogin=`echo 'MYUSERNAME' | openssl base64`
mypassword=`echo 'MYPASSWORD' | openssl base64`
myip=`wget -qO- icanhazip.com`
myfile=`cat /tmp/mytest.log | openssl base64`
mydate=`date`

exec 9<>/dev/tcp/$mailserver/25
echo "HELO routeur.tripfiller" >&9
read -r temp <&9
#echo "$temp"
echo "auth login" >&9
read -r temp <&9
#echo "$temp"
echo "$mylogin=" >&9
read -r temp <&9
#echo "$temp"
echo "$mypasswd=" >&9
read -r temp <&9
#echo "$temp"
echo "Mail From: $from" >&9
read -r temp <&9
#echo "$temp"
echo "Rcpt To: $to" >&9
read -r temp <&9
#echo "$temp"
echo "Data" >&9
read -r temp <&9
#echo "$temp"
echo "To:$to" >&9
echo "MIME-Version: 1.0" >&9
echo "Subject: Test mail sended at $mydate" >&9
echo "From: $from" >&9
echo "To: $to" >&9
echo "Content-Type: multipart/mixed; boundary=sep" >&9
echo "--sep" >&9
echo "Content-Type: text/plain; charset=UTF-8" >&9
echo "Here your text..." >&9
echo "External IP adress: $myip" >&9
echo "--sep" >&9
echo "Content--Type: text/x-log; name=\"mytest.log\"" >&9
echo "Content-Disposition: attachment; filename=\"mytest.log\"" >&9
echo "Content-Transfer-Encoding: base64" >&9
echo "" >&9
echo "$myfile" >&9
echo "--sep--" >&9
echo "." >&9
read -r temp <&9
echo "$temp"
echo "quit" >&9
read -r temp <&9
echo "$temp"
9>&-
9<&-
#echo "All Done. See above for errors"
exit 0

Hope it was good for you ;)

psirac.

share|improve this answer

You'll need to review the SMTP protocol specification. It's a surprisingly light read for a technical specification, and will help you understand how the email process works.

Specifically, realize that attachments are converted into MIME types and encoded in text, so any attachments you'd like to send via telnet would have to be converted into text and transmitted as such via the telnet protocol.

share|improve this answer

If all you're testing is 'did the attachment deliver', you might possibly get away with using the pre-MIME standard of attachments: uuencode. Unlike MIME, it is a lot simpler to create messages. Unlike MIME it doesn't require any headers. However, not all mail clients recognize uuencoded files as attachments anymore so I suggest testing to see if you can use it. If it does, you've just saved yourself a lot of effort. If it doesn't, then pre-constructing your MIMEed message via perl or something and piping it through something like NetCat is probably the way to go.

Worth a look.

share|improve this answer
    
20 years ago this was a good answer. Not now. Use one of the many MIME libraries and create a MIME-compliant email, complete with Base64 encoding. –  james.garriss Aug 5 at 14:32

There is a wonderful Perl script to this job. You can find it here:

http://www.logix.cz/michal/devel/smtp-cli/

smtp-cli v2.9

Script is from author: Michal Ludvig (c) 2003-2011 http://smtp-cli.logix.cz

I use it myself and it is works great, thanks to Michal ;)

share|improve this answer

i sumbled upon this entry while i were searching for something of the same. and from the awnsers here and som additional research i managed to make this script.

#!/bin/sh

# Default reception
TOEMAIL="myEmail@domain.ltd";
# Default Subject
SUBJECT="You got mail - $DATE";
# Default Contents
MSGBODY="Hello, this is the default message body";
# Default Attachment
#ATTACHMENT="/tmp/testoutput"
# Default smtp server
mailserver="smtp.server.ltd"
mailserverPort="25"

showUsage() {
        echo "$0 -a /file/to/attach [-m /message/file] [-M \"Message string\"] -s \"subject\" -r receiver@domain.com"
        echo
        echo "The attachment (-a) is required, if no attachment is used then rather use sendmail directly."
}

fappend() {
    echo "$2">>$1;
}
DATE=`date`

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# This might need correction to work on more places, this is tested at a ubuntu 13.10 machine.  #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
domain=`grep search /etc/resolv.conf | awk '{print $2;}'`
computer=`hostname`
user=`whoami`
FREMAIL="$user@$computer.$domain"

while getopts "M:m:a:s:r:" opt; do
  case $opt in
        s)
          SUBJECT="$OPTARG - $DATE"
          ;;
        r)
          TOEMAIL="$OPTARG"
          ;;
        m)
          MSGBODY=`cat $OPTARG`
          ;;
        M)
          MSGBODY="$OPTARG"
          ;;
        a)
          ATTACHMENT="$OPTARG"
          ;;
        :)
          showUsage
          ;;
        \?)
          showUsage
          ;;
  esac
done

if [ "$ATTACHMENT" = "" ]; then
        showUsage
        exit 1
fi

MIMETYPE=`file --mime-type -b $ATTACHMENT`
TMP="/tmp/tmpmail_"`date +%N`;
BOUNDARY=`date +%s|md5sum|awk '{print $1;}'`
FILENAME=`basename $ATTACHMENT`

DATA=`cat $ATTACHMENT|base64`

rm $TMP 2> /dev/null

fappend $TMP "EHLO $computer.$domain"
fappend $TMP "MAIL FROM:<$FREMAIL>"
fappend $TMP "RCPT TO:<$TOEMAIL>"
fappend $TMP "DATA"
fappend $TMP "From: $FREMAIL"
fappend $TMP "To: $TOEMAIL"
fappend $TMP "Reply-To: $FREMAIL"
fappend $TMP "Subject: $SUBJECT"
fappend $TMP "Content-Type: multipart/mixed; boundary=\"$BOUNDARY\""
fappend $TMP ""
fappend $TMP "This is a MIME formatted message.  If you see this text it means that your"
fappend $TMP "email software does not support MIME formatted messages."
fappend $TMP ""
fappend $TMP "--$BOUNDARY"
fappend $TMP "Content-Type: text/plain; charset=UTF-8; format=flowed"
fappend $TMP "Content-Disposition: inline"
fappend $TMP ""
fappend $TMP "$MSGBODY"
fappend $TMP ""
fappend $TMP ""
fappend $TMP "--$BOUNDARY"
fappend $TMP "Content-Type: $MIMETYPE; name=\"$FILENAME\""
fappend $TMP "Content-Transfer-Encoding: base64"
fappend $TMP "Content-Disposition: attachment; filename=\"$FILENAME\";"
fappend $TMP ""
fappend $TMP "$DATA"
fappend $TMP ""
fappend $TMP ""
fappend $TMP "--$BOUNDARY--"
fappend $TMP ""
fappend $TMP "."
fappend $TMP "quit"

netcat $mailserver $mailserverPort < $TMP >> $TMP
rc="$?"
if [ "$rc" -ne "0" ]; then
    echo "Returncode: $rc"
    echo "Please inspect $TMP"
else
    rm $TMP;
fi

One thing you might want to add is authentication. i dont need it so i havent added it.

I think it only requires md5sum, netcat, file, awk and the base64 commands, id guess they are pretty standard in most systems.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.