-
-
Notifications
You must be signed in to change notification settings - Fork 3
swaks.1
swaks - SMTP transaction tester
swaks [--help|--version] | OPTIONS
--pipe
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.
--socket
This option takes as its argument a unix domain socket file. If this
option is present, swaks enters an SMTP transaction over the unix
domains socket rather than over an internet domain socket. I think this
option has uses when combined with a (yet unwritten) LMTP mode, but to
be honest at this point I just implemented it because I could.
-l, --input-file
Argument to -l must be a path to a file containing TOKEN- > VALUE
pairs. The TOKEN and VALUE must be separated by whitespace. These tokens
set values which would otherwise be set by command line arguments. See
the description of the corresponding command line argument for details
of each token. Valid tokens are FROM (-f), TO (-t), SERVER (-s), DATA
(-d), HELO (-h), PORT (-p), INTERFACE (-li), and TIMEOUT (-to).
-t, --to
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 .
-f, --from
Use argument as " MAIL FROM " address, or prompt user if no argument
specified. Overridden by -l token FROM . If no from address is
specified, default is user@host, where user is the best guess at user
currently running program, and host is best guess at DNS hostname of
local host. The string <> can be supplied to mean the null sender.
-s, --server
Use argument as mail server to which to connect, or prompt user if no
argument specified. Overridden by -l token SERVER . If unspecified,
swaks tries to determine primary MX of destination address. If Net::DNS
module is not available, tries to connect to A record for recipient's
domain.
-p, --port
Use argument as port to connect to on server, or prompt user if no
argument is specified. This can be either a port number or a service
name. Overridden by -l token PORT . If unspecified, swaks will use
service lmtp if --protocol is LMTP , service smtps if --tls-on-connect
is used, and smtp otherwise.
-h, --helo, --ehlo
Use argument as argument to SMTP EHLO/HELO command, or prompt use if no
argument is specified. Overridden by -l token HELO. If unspecified,
swaks uses best guess at DNS hostname of local host.
-d, --data
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: %Do: %Trom: %Fubject: test %D-Mailer:
swaks v$p_version jetmore.org/john/code/#swaksHn%B.
--body
Specify the body of the email. The default is "This is a test mailing".
If no argument to --body, you will be prompted to supply one. If '-' is
supplied, body will be read from standard input. If any other text is
provided and the text represents an openable file, the content of that
file is used as the body. If it does not respresent an openable file,
the text itself is used as the body.
--attach
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.
--attach-type
By default, content that gets MIME attached to a message with the
--attach option is encoded as application/octet-stream. --attach-type
changes the mime type for every --attach option which follows it. It can
be specified multiple times.
-ah, --add-header
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 ' string. So, "--add-header 'Foo: bar' --add-header 'Baz: foo'" and "--add-header 'Foo: baraz: foo'" end up adding the same two headers.
--header, --h-Header
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.
--timeout
Use argument as the SMTP transaction timeout, or prompt user if no
argument given. Overridden by the -l token TIMEOUT. Argument can either
be a pure digit, which will be interpretted as seconds, or can have a
specifier s or m (5s = 5 seconds, 3m = 180 seconds). As a special case,
0 means don't timeout the transactions. Default value is 30s.
--protocol
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 |
-li, --local-interface
Use argument as the local interface for the SMTP connection, or prompt
user if no argument given. Overridden by the -l token INTERFACE .
Argument can be an IP or a hostname. Default action is to let OS choose
local interface.
-g
If specified, swaks will read the DATA value for the mail from STDIN .
If there is a From_ line in the email, it will be removed (but see -nsf
option). Useful for delivering real message (stored in files) instead of
using example messages.
-nsf, --no-strip-from
Don't strip the From_ line from the DATA portion, if present.
-n, --suppress-data
If this option is specified, swaks summarizes the DATA portion of the
SMTP transaction instead of printing every line.
-q, --quit-after
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.
-m
Emulate Mail command. Least used option in swaks.
--support
Cause swaks to print its capabilities and exit. Certain features require
non-standard perl modules. This options evaluates whether these modules
are present and lets you know which functionality is present.
-S, --silent
Cause swaks to be silent. "-S" causes swaks to print no output until an
error occurs, after which all output is shown. "-S -S" causes swaks to
only show error conditions. "-S -S -S" shows no output.
--pipeline
If the remote server supports it, attempt SMTP PIPELINING ( RFC 2920).
This is a younger option, if you experience problems with it please
notify the author. Potential problem areas include servers accepting
DATA even though there were no valid recipients (swaks should send empty
body in that case, not QUIT ) and deadlocks caused by sending packets
outside the tcp window size.
-tls
Require connection to use STARTTLS . Exit if TLS not available for any
reason (not advertised, negotiations failed, etc).
-tlso, --tls-optional
Attempt to use STARTTLS if possible, continue t/ normal transaction if
TLS unavailable.
-tlsc, --tls-on-connect
Initiate a TLS connection immediately on connection. Use to test
smtps/ssmtp servers. If this options is specified, the default port
changes from 25 to 465, though this can still be overridden with the -p
option.
-a, --auth
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.
-ao, --auth-optional
Same as -a, but if authentication is unavailable or fails, attempts to
continue transaction.
-au, --auth-user
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 user@example.com%NTDOM" is passed, "user@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.
-ap, --auth-password
Supply the password for authentication. The string <> can be supplied
to mean an empty password.
-am, --auth-map
Provides a way to map alternate names onto base authentication types.
Useful for any sites that use alternate names for common types. This
functionality is actually used internally to map types SPA and MSN onto
the base type NTLM . The command line argument to simulate this would be
"--auth-map SPA=NTLM,MSN=NTLM". The base types supported are LOGIN ,
PLAIN , CRAM-MD5 , DIGEST-MD5 , and NTLM . SPA and MSN are mapped on to
NTLM automatically.
-apt, --auth-plaintext
Instead of showing AUTH strings literally (in base64), translate them to
plaintext before printing on screen.
-nth, --no-hints
Don't show transaction hints. (Useful in conjunction with -hr to create
copy/paste-able transactions
-hr, --hide-receive
Don't display reception lines
-hs, --hide-send
Don't display sending lines
-stl, --show-time-lapse
Display time lapse between send/receive pairs. If 'i' is provided as
argument or the Time::HiRes module is unavailable the time lapse will be
integer only, otherwise it will be to the thousandth of a second.
--force-getpwuid
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.
--help
This screen.
--version
Version info.
prompt user for to address and send a default email. send the contents of "mailfile" to user@example.com, using TLS if available, requiring authentication, using user/password as authentication information.
cat mailfile | swaks -g -n -t user@example.com -tlso -a -au user -ap password
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"
AUTH CRAM-MD5
CRAM-MD5 authentication requires the Digest::MD5 perl module. If this is
unavailable and authentication is required, swaks will error if CRAM-MD5
was the specific authentication type requested, or if no specific auth
type was requested but CRAM-MD5 was the only type advertised by the
server.
AUTH CRAM-SHA1
CRAM-SHA1 authentication requires the Digest::SHA1 perl module. If this
is unavailable and authentication is required, swaks will error if
CRAM-SHA1 was the specific authentication type requested, or if no
specific auth type was requested but CRAM-SHA1 was the only type
advertised by the server.
AUTH DIGEST-MD5
DIGEST-MD5 authentication requires the Authen::DigestMD5 perl module. If
this is unavailable and authentication is required, swaks will error if
DIGEST-MD5 was the specific authentication type requested, or if no
specific auth type was requested but DIGEST-MD5 was the only type
advertised by the server.
AUTH NTLM
NTLM/SPA/MSN authentication requires the Authen::NTLM perl module. If
this is unavailable and authentication is required, swaks will error if
NTLM was the specific authentication type requested, or if no specific
auth type was requested but NTLM was the only type advertised by the
server. Note that there are two modules using the Authen::NTLM namespace
on CPAN . The Mark Bush implementation (Authen/NTLM-1.02.tar.gz) is the
version required here.
Basic AUTH
All authentication types require base64 encoding and decoding. If
possible, swaks uses the MIME::Base64 perl module to perform these
actions. However, if MIME::Base64 is not available swaks will use its
own onboard base64 routines. These are slower than the MIME::Base64
routines and less reviewed, though they have been tested thoroughly.
When possible it is recommended that you install MIME::Base64.
Date Manipulation
swaks generates an RFC compliant date string when it interpolates the %D
token in message bodies. In order to build the GMT offset in this
string, it needs the Time::Local module. It would be very odd for this
module not to be available because it has been included in the perl
distribution for some time. However, if it is not loadable for some
reason and swaks interpolates a %D token (as it would when using the
default body), the date string is in GMT instead of your local timezone.
High Resolution Timing
When diagnosing SMTP delays using --show-time-lapse, by default high
resolution timing is attempted using the Time::HiRes module. If this
module is not available, swaks uses a much poorer timing source with one
second granularity.
Local Hostname Detection
swaks uses your local machine's hostname to build the HELO string and
sending email address when they are not specified on the command line.
If the Sys::Hostname module (which is a part of the base distribution)
is not available for some reason, the user is prompted interactively for
the HELO and sender strings. Note that Sys::Hostname can sometimes fail
to find the local hostname even when the module is available, which has
the same behaviour.
MX Routing
If the destination mail server is not specified using the --server
option, swaks attempts to use DNS to route the message based on the
recipient email address. If the Net::DNS perl module is not available,
swaks uses 'localhost' as the outbound mail server.
Pipe Transport
The IPC::Open2 module is required to deliver a message to a spawned
subprocess using the --pipe option. If this module, which is included in
the base perl distribution, in not available, attempting to call swaks
with the --pipe option will result in an error.
Socket Transport
The IO::Socket module is required to deliver a message to an internet
domain socket (the default behaviour of swaks) and to a unix domain
socket (specified with the --socket option). If this module, which is
included in the base perl distribution, is not available, attempting to
call swaks with the --server or --socket options (or none of the
--socket, --server, and --pipe options) will result in an error.
TLS
TLS functionality requires the Net::SSLeay perl module. If this module
is not available and TLS was required (using the --tls-on-connect or
--tls options), the session will error out. If TLS was requested but not
required (using the --tls-optional option), swaks will continue but not
attempt a TLS session.
Portability
Operating Systems 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 .
Mail Servers
This program was almost exclusively developed against Exim mail servers.
It was been used casually by the author, though not thoroughly tested,
with sendmail, smail, and Communigate. Because all functionality in
swaks is based off of known standards it should work with any fairly
modern mail server. If a problem is found, please alert the author at
the address below.
0
no errors occurred
1
error parsing command line options
2
error connecting to remote server
3
unknown connection type
4
while running with connection type of "pipe", fatal problem writing to
or reading from the child process
5
while running with connection type of "pipe", child process died
unexpectedly. This can mean that the program specified with --pipe
doesn't exist.
6
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.
10
error in prerequisites (needed module not available)
21
error reading initial banner from server
22
error in HELO transaction
23
error in MAIL transaction
24
no RCPTs accepted
25
server returned error to DATA request
26
server did not accept mail following data
27
server returned error after normal-session quit request
28
error in AUTH transaction
29
error in TLS transaction
32
error in EHLO following TLS negotiation
Deliver a standard test email to user@example.com on port 25 of
test-server.example.net:
swaks --to user@example.com --server test-server.example.net
Deliver a standard test email, requiring CRAM-MD5 authentication as user
me@example.com. An "X-Test" header will be added to the email body. The
authentication password will be prompted for.
swaks --to user@example.com --from me@example.com --auth CRAM-MD5 \
--auth-user me@example.com --header-X-Test "test email"
Test a virus scanner using EICAR in an attachment. Don't show the
message DATA part.:
swaks -t user@example.com --attach - --server \
test-server.example.com --suppress-data </path/to/eicar.txt
Test a spam scanner using GTUBE in the body of an email, routed via the
MX records for example.com:
swaks --to user@example.com --body /path/to/gtube/file
Deliver a standard test email to user@example.com using the LMTP
protocol via a UNIX domain socket file
swaks --to user@example.com --socket /var/lda.sock --protocol LMTP
Report all the recipients in a text file that are non-verifyiable on a
test server:
for E in `cat /path/to/email/file`
do
swaks --to $E --server test-server.example.com \
--quit-after RCPT --hide-all
[ $? -ne 0 ] && echo $E
done
proj-swaks@jetmore.net
Please use this address for general contact, questions, patches,
requests, etc
updates-swaks@jetmore.net
If you would like to be put on a list to receive notifications when a
new version of swaks is released, please send an email to this address
jetmore.org/john/code/#swaks
Change logs, help manual, and the latest version is found at this link