SWAKS(1) User Contributed Perl Documentation SWAKS(1)
NAME
swaks - SMTP transaction tester
USAGE
swaks [--help|--version] | (see description of options
below)
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 trans-
action 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 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 sepa-
rated 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. See also --copy-
routing.
-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 lit-
eral \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".
--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 mes-
sage 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 mul-
tiple 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 mes-
sage with the --attach option is encoded as applica-
tion/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, practi-
cally 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 lit-
eral '\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.
--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 identi-
cally 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 sec-
onds). 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 spec-
ify 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 --proto-
col 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 con-
nection, or prompt user if no argument given. Over-
ridden by the -l token INTERFACE. Argument can be an
IP or a hostname. Default action is to let OS choose
local interface.
--copy-routing
The argument is interpretted as the domain part of an
email address and it is used to find the destination
server using the same logic that would be used to look
up the destination server for a --to address.
-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). Use-
ful 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 pre-
sent 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 out-
put 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 recipi-
ents (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/ nor-
mal transaction if TLS unavailable.
-tlsos, --tls-optional-strict
Attempt to use STARTTLS if available. proceed if
available and succeeds or not advertised. If adver-
tised but TLS negotiations fail, error out.
-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 argu-
ment 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 sup-
plied on command line, swaks will prompt on STDIN.
SPA (NTLM/MSN) authentication is now supported.
Tested as a client against Exim and Stalker's Communi-
Gate, 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 incom-
plete or incorrect. Requires Digest::SHA1 module.
-ao, --auth-optional
Same as -a, but if authentication is unavailable or
fails, attempts to continue transaction.
-aos, --auth-optional-strict
This option is a compromise between --auth and --auth-
optional. If the server does not advertise AUTH or is
a specific AUTH type is requested of swaks but not
offered by the server, the auth request is skipped and
processing continues as if --auth-optional were speci-
fied. If swaks can't support the auth type requested
or non of the advertised auth types, or if auth is
attempted but fails, this option behaves as --auth
does and exits with an error
-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, oth-
erwise 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 getp-
wuid method will be used. This would happen if the
process was run from cron or some other headless dae-
mon.
--help
This screen.
--version
Version info.
EXAMPLES
swaks
prompt user for to address and send a default email.
cat mailfile | swaks -g -n -t user@example.com -tlso -a
-au user -ap password
send the contents of "mailfile" to user@example.com,
using TLS if available, requiring authentication,
using user/password as authentication information.
COMMENTS
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).
REQUIRES
swaks does not have any single requirement except the
standard module Getopt::Long. However, there may be mod-
ules 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 avail-
able"
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 spe-
cific 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 authentica-
tion 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 authentica-
tion is required, swaks will error if NTLM was the
specific authentication type requested, or if no spe-
cific 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 rec-
ommended 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. How-
ever, 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 avail-
able, 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 dis-
tribution) 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 avail-
able, 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 dis-
tribution, 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 mod-
ule. 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 rea-
sonable 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 functional-
ity on Windows using ActiveState's Perl. It has not
been fully tested. Known to work are basic SMTP func-
tionality 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.
EXIT CODES
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 follow-
ing 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 con-
nection, 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 imme-
diately 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
CONTACT
proj-swaks@jetmore.net
Please use this address for general contact, ques-
tions, patches, requests, etc.
updates-swaks@jetmore.net
If you would like to be put on a list to receive noti-
fications when a new version of swaks is released,
please send an email to this address.
jetmore.org/john/code/#swaks
Change logs, this help, and the latest version is
found at this link.
2007-12-11 perl v5.6.1 SWAKS(1)