Wednesday, November 12, 2014

Testing SMTP MSA from Command Line

Sometimes there is a need to test a Simple Mail Transfer Protocol (SMTP) Mail Submission Agent (MSA) from the command line in a terminal window instead of running a mail client. Wikipedia shows an SMTP converstational example. However, you may not run the example as is from the command line in a terminal window on most SMTP servers today since they typically require a secure connection and proper authentication to improve security and reduce SPAMs.

This post demonstrates a procedure to test SMTP transport from a terminal window using Gmail's SMTP server. The idea, of course can be applied to other SMTP servers.

Gmail's SMTP server's setting on the client side at present is as follows,

Outgoing Mail (SMTP) Server - Requires TLS
    Port: 465 or 587
    Requires SSL: Yes
    Requires authentication: Yes

This server is Gmail's SMTP MSA. Based on the setting above,  we shall do the following.
  • First, we need to be able to communicate with the server at using TLS, for which we will use OpenSSL.
  • Second, we will have to be able to authenticate with the SMTP server, for which we will use SASL.

The above are availalbe in most Linux distributions. The following steps are tested on a Ubuntu 14.04 machine.

  1. Open a Linux terminal.
  2. Install OpenSSL and SASL-bin packages
        sudo apt-get install openssl sasl2-bin
  3. Select an authentication method and generate an authentication string. Assume your Gmail e-mail address is with password secretestring and your choose the PLAIN authentication method. We can use the gen-auth tool in the SASL-bin package to generate the authentication string as follows,
       gen-auth PLAIN secretestring
    The output is a hash string as shown below,
       Auth String: AGdyYXkuY2hlbmh1aUBnbWFpbC5jb20Ac3Q5OTg4IUAj
    This hash string will be used in next step.

    By the way, you can actually find out what authentication method a SMTP server supports in the steps follows. You can always run the steps to find it out and then generate the authentication string.
  4. Using openssl to establish a secure connection to Gmail's SMTP server at at port 465
        openssl s_client -crlf -connect
    The last line of the output of the above operation will be something as follows,
        220 ESMTP e23sm3343567vdk.23 - gsmtp
    At this point, we will send a EHLO message to the SMTP server. In the following, we assume that your domain is somesubdomain.somedomain and your IP address is
        EHLO somesubdomain.somedomain
    The output will resemble something below,
    at your service, []
        250-SIZE 35882577
        250 SMTPUTF8
    The message contains the line
    which indicates what authentication method you may use. As discussed above, we use the PLAIN method and have already obtained the authentication string. We can now authenticate with the SMTP server using the authentication string.
  5. We now authenticate with the server by sending an AUTH message as follows,
        AUTH PLAIN AGdyYXkuY2hlbmh1aUBnbWFpbC5jb20Ac3Q5OTg4IUAj
    At this point, you should be successfully authenticated as indicated by the acknowledgement from the SMTP server below,
        235 2.7.0 Accepted
    You can now start a converstation with the SMTP server similar to the Wikipedia example.
  6. Below is a converstation with the SMTP server to send a short e-mail to friend.of.somebody@somesubdomain.somedomain and copy the email to another.friend.of.somebody@somesubdomain.somedomain. Note that the lines starting with "C:" are what you, a client of the SMTP server would enter and the lines starting with "S:" are what the SMTP server would output. Obviously, "C:" should not be part of your input.
       C: mail from:<>
       S: 250 2.1.0 OK ki9sm3203907vdb.16 - gsmtp
       C: rcpt to:<friend.of.somebody@somesubdomain.somedomain>
       S: 250 2.1.5 OK ki9sm3203907vdb.16 - gsmtp
       C: data
       S: 354  Go ahead ki8sm3602907vdb.16 - gsmtp
       C: From: "foo somebody" <>
       C: To: "Friend of Somebody" <friend.of.somebody@somesubdomain.somedomain>
       C: Cc: "Another Friend" <other.friend.of.somebody@somesubdomain.somedomain>
       C: Date: Wed, 12 November 2014 17:29:43 -0500
       C: Subject: Test Message from Command Line
       C: hello friend,
       C: reply me please. I am testing smtp server.
       C: thanks.
       C: your friend
       C: .
       S: 250 2.0.0 OK 1415831485 ki9sm3203907vdb.16 - gsmtp
       C: quit
       S: 221 2.0.0 closing connection ki9sm3203907vdb.16 - gsmtp
       OpenSSL: read:errno=0
    Note in the above,
    • "read:errno=0" is an output from openssl rather than an output from the SMTP server.
    • The blank lines above, i.e, the lines of "C:" indicate that you will enter a new line.
    • The end of conversation is marked with "<CRLF>.<CRLF>". See the last "." in the above converstation. The "-crlf" provided in the "openssl s_client" command line is to convert a line feed to a <CRLF>, a carriage return followed by a line feed.
    • An important item to note is that the "openssl s_client" has the following behavior as described in the manual page of "s_client" that you may view using "man s_client" as follows,
      If a connection is established with an SSL server then any data received from the server is displayed and any key presses will be sent to the server. When used interactively (which means neither -quiet nor -ign_eof have been given), the session will be renegotiated if the line begins with an R, and if the line begins with a Q or if end of file is reached, the connection will be closed down.
      which means that you cannot use letter R and Q in the entire interactive openssl session. If you use R, such as type RCPT TO: ... instead of what is shown in the above, you will encounter an error as follows even though SMTP treats the same.
         C: RCPT TO:<friend.of.somebody@somesubdomain.somedomain>
         OpenSSL: 3073996476:error:1409E0E5:SSL 
           routines:SSL3_WRITE_BYTES:ssl handshake failure:s3_pkt.c:596:


The following web posts  were excellent references for writing this post,
  • The post here led me to SASL and subsequently the SASL-bin package for the generation of authentication strings.
  • The posts here and here helped me figure out the "RENEGOTIATING" feature of "openssl s_client

No comments:

Post a Comment