swaks - SMTP transaction tester
swaks [--help|--version] | (see description of options below)
This option takes as its argument a program and the program's arguments. If this option is present, swaks opens a pipe to the program and enters an SMTP transaction over that pipe rather than connecting to a remote server. Some MTAs have testing modes using stdin/stdout. This option allows you to tie into those options. For example, if you implemented DNSBL checking with exim and you wanted to make sure it was working, you could run 'swaks --pipe "exim -bh 127.0.0.2"'.
In an ideal world the process you are talking to should behave exactly like an SMTP server on stdin and stdout. Any debugging should be sent to stderr, which will be directed to your terminal. In the real world swaks can generally handle some debug on the child's stdout, but there are no guarantees on how much it can handle.
Use argument as "RCPT TO" address, or prompt user if no argument specified. Overridden by -l token TO. Multiple recipients can be specified by supplying as one comma-delimited argument.
There is no default for this option. If no to addess is specified with -t or TO token, user will be prompted for To: address on STDIN.
Use argument as DATA portion of SMTP transaction, or prompt user if no argument specified. Overridden by -l token DATA.
This string should be on one single line, with a literal \n representing where line breaks should be placed. Leading dots will be quoted. Closing dot is not required but is allowed. Very basic token parsing is done. %F is replaced with the value that will be used for "MAIL FROM", %T is replaced with "RCPT TO" values, %D is replaced with a timestamp, %H is replaced with the contents of --add-header, and %B is replaced with the message body. See the --body option for the default body text.
Default value for this option is "Date: %D\nTo: %T\nFrom: %F\nSubject: test %D\nX-Mailer: swaks v$p_version jetmore.org/john/code/#swaks\n%H\n\n%B\n".
When one or more --attach option is supplied, the message is changed into a multipart/mixed MIME message. The arguments to --attach are processed the same as --body with regard to stdin, file contents, etc. --attach can be supplie multiple times to create multiple attachments. By default each attachment is attached as a application/octet-stream file. See --attach-type for changing this behaviour.
When the message changes to MIME format, the previous body (%B) is attached as a text/plain type as the first attachment. --body can still be used to specify the contents of this body attachment.
It is legal for '-' (STDIN) to be specified as an argument multiple times (once for --body and multiple times for --attach). In this case, the same content will be attached each time it is specified. This is useful for attaching the same content with multiple MIME types.
In the strictest sense, all this does is provide a value that replaces the %H token in the data. Because of where %H is located in the default DATA, practically it is used to add custom headers without having to recraft the entire body.
The option can either be specified multiple times or a single time with multiple headers seperated by a literal '\n' string. So, "--add-header 'Foo: bar' --add-header 'Baz: foo'" and "--add-header 'Foo: bar\nBaz: foo'" end up adding the same two headers.
These options allow a way to change headers that already exist in the DATA. These two calls do the same thing:
--header "Subject: foo" --h-Subject foo
Subject is the example used. If the header does not exist in the body already, these calls behave identically to --add-header. The purpose of this option it to provide a fast way to change the nature of the default DATA for specific tests. For instance if you wanted to test a subject filer in a mail system, you could use --h-Subject "SPAM STRING" to test rather than having to craft and entire new DATA string to pass to --data.
Specify which protocol to use in the transaction. Valid options are shown in the table below. Currently the 'core' protocols are SMTP, ESMTP, and LMTP. By using variations of these protocol types one can specify default ports, whether authentication should be attempted, and the type of TLS connection that should be attempted. The default protocol is ESMTP. This table demonstrates the available arguments to --protocol and the options each sets as a side effect:
HELO AUTH TLS PORT -------------------------------------------------- SMTP HELO smtp / 25 SSMTP EHLO->HELO -tlsc smtps / 465 SSMTPA EHLO->HELO -a -tlsc smtps / 465 SMTPS HELO -tlsc smtps / 465 ESMTP EHLO->HELO smtp / 25 ESMTPA EHLO->HELO -a smtp / 25 ESMTPS EHLO->HELO -tls smtp / 25 ESMTPSA EHLO->HELO -a -tls smtp / 25 LMTP LHLO lmtp / 24 LMTPA LHLO -a lmtp / 24 LMTPS LHLO -tls lmtp / 24 LMTPSA LHLO -a -tls lmtp / 24
The argument to this option is used as an indicator of where to quit the SMTP transaction. It can be thought of as "quit after", with valid arguments CONNECT, FISRT-HELO, TLS, HELO, AUTH, MAIL, and RCPT. In a non-STARTTLS session, FIRST-HELO and HELO behave the same way. In a STARTTLS session, FIRST-HELO quits after the first HELO sent, while HELO quits after the second HELO is sent.
For convenience, LHLO and EHLO are synonyms for HELO, FIRST-EHLO and FIRST-LHLO for FIRST-HELO, FROM for MAIL, and TO for RCPT.
Require authentication. If Authentication fails or is unavailable, stop transaction. -a can take an argument specifying which type(s) of authentication to try. If multiple, comma-delimited arguments are given, each specified auth type is tried in order until one succeeds or they all fail. swaks currently supports PLAIN, LOGIN, and CRAM-MD5. If no argument is given any available authentication type is used. If neither password (-ap) or username (-au) is supplied on command line, swaks will prompt on STDIN.
SPA (NTLM/MSN) authentication is now supported. Tested as a client against Exim and Stalker's CommuniGate, but implementation may be incomplete. Authen::NTLM is currently required. Note that CPAN hosts two different Authen::NTLM modules. Current implementation requires Mark Bush's implementation (Authen/NTLM-1.02.tar.gz). Plan to reimplement directly at some point to avoid confusion.
DIGEST-MD5 is now supported. Tested as a client only against Stalker's Communigate, so implementation may be incomplete. Requires Authen::DigestMD5 module.
CRAM-SHA1 is now supported. Only tested against a hacked server implementation in Exim, so may be incomplete or incorrect. Requires Digest::SHA1 module.
Supply the username for authentication. The string <> can be supplied to mean an empty username.
For SPA authentication, a "domain" can be specified after the regular username with a % seperator. For instance, if "-ap firstname.lastname@example.org%NTDOM" is passed, "email@example.com" is the username and "NTDOM" is the domain. NOTE: I don't actually have access to a mail server where the domain isn't ignored, so this may be implemented incorrectly.
In releases 20050709.1 and earlier of swaks the local_part of an automatically generated sender email address would be found using the getpwuid system call on the euid of the current process. Depending on the users' desires, this may be confusing. Following the 20050709.1 release the local_part is not looked up via the getlogin() funtion which attempts to look up the actual username of the logged in user, regardless of the euid of the process they are currently running.
An example of where this might be an issue is running swaks under sudo for testing reasons when interacting with --pipe or --socket. It makes sense that you need to run the process as a specific username but you would prefer your email to be from your real username. You could always do this manually using the -s option, but this is an attempt to make it easier.
--force-getpwuid forces the old behaviour for anyone who prefered that behaviour. Also, if there is no "real" user for getlogin() to look up, the old getpwuid method will be used. This would happen if the process was run from cron or some other headless daemon.
This program was written because I was testing a new MTA on an alternate port. I did so much testing that using interactive telnet grew tiresome. Over the next several years this program was fleshed out and every single option was added as a direct need of some testing I was doing as the mail admin of a medium sized ISP, with the exception of TLS support which was added on a whim. As such, all options are reasonably well thought out and fairly well tested (though TLS could use more testing).
swaks does not have any single requirement except the standard module Getopt::Long. However, there may be modules that are required for a given invocation of swaks. The following list details the features reported by the --support option, what is actually being tested, and the consequences of the feature being reported as "not available"
This program was primarily intended for use on unix-like operating systems, and it should work on any reasonable version thereof. It has been developed and tested on Solaris, Linux, and Mac OS X and is feature complete on all of these.
This program is known to demonstrate basic functionality on Windows using ActiveState's Perl. It has not been fully tested. Known to work are basic SMTP functionality and the LOGIN, PLAIN, and CRAM-MD5 auth types. Unknown is any TLS functionality and the NTLM/SPA and Digest-MD5 auth types.
Because this program should work anywhere Perl works, I would appreciate knowing about any new operating systems you've thoroughly used swaks on as well as any problems encountered on a new OS.
Connection closed unexpectedly. If the close is detected in response to the 'QUIT' swaks sends following an unexpected response, the error code for that unexpected response is used instead.
For instance, if a mail server returns a 550 response to a MAIL FROM: and then immediately closes the connection, swaks detects that the connection is closed, but uses the more specific exit code 23 to detail the nature of the failure.
If instead the server return a 250 code and then immediately closes the connection, swaks will use the exit code 6 because there is not a more specific exit code.