Test a SASL Mechanism Safely with sasl-sample-client

sasl-sample-client lets you exercise a Cyrus SASL client without touching a real service. It is a test harness, not a general purpose SMTP, IMAP or LDAP client, and it shows the exact failure you get when no compatible peer is listening. Allow about 15 minutes for a local smoke test, longer if you need to configure a mechanism or credentials.

The examples use Ubuntu's sasl2-bin package version 2.1.28+dfsg1-5ubuntu3.1. The installed client is /usr/bin/sasl-sample-client. You need a shell and a test environment where a failed authentication attempt is acceptable. Do not point this at a production service or use a real password while learning the options.

1. Confirm the installed client

Check the executable and package version before interpreting output. This command only reads local package metadata:

$ command -v sasl-sample-client
/usr/bin/sasl-sample-client
$ dpkg-query -W -f='${Package} ${Version}\n' sasl2-bin
sasl2-bin 2.1.28+dfsg1-5ubuntu3.1

The Debian manual page is intentionally brief. Its synopsis is the reliable list of client options for this installed build. In particular, the client has no positional host, port or password argument. It exchanges test data with the sample server through its standard input and standard output.

Checkpoint: Stop here if you expected a network client. Use the real application that owns the SASL connection for an end-to-end service test. This sample program is useful for the SASL negotiation layer itself.

2. Run the client without a peer

Run the client with end-of-file on standard input and a short timeout:

$ timeout 5s sasl-sample-client </dev/null
Waiting for mechanism list from server...
sasl-sample-client: Unable to parse input

The client exits non-zero because it expected the sample server's mechanism list and received end-of-file instead. That output is a useful diagnostic, not evidence that a SASL mechanism has failed. The timeout is a safety boundary for experiments; it prevents a test process from waiting indefinitely for a peer.

Do not add sudo to this command. Reading the executable and loading the SASL plugins normally require no elevated privileges. Capture the status immediately if a script needs it:

$ timeout 5s sasl-sample-client </dev/null
$ status=$?
$ printf 'client exit status: %s\n' "$status"
client exit status: 1

3. Understand the client controls

Each option changes the negotiation properties passed to the SASL library. Values use the form shown in the manual page, and comma-separated fields belong to the same option.

OptionPurposeExample
-mForce one mechanism.-m SCRAM-SHA-256
-sSet the service name passed to mechanisms.-s imap
-nSet the server fully-qualified domain name.-n auth.example.test
-aSet the authentication identity.-a alice
-uRequest an authorisation identity.-u alice
-rSet the SASL realm.-r example.test
-pSet a colon-separated mechanism search path.-p /usr/lib/x86_64-linux-gnu/sasl2

Start with the smallest set of values that describes the test. A service name is not a hostname: it identifies the application service to the mechanism. The FQDN option is separate. Likewise, -a and -u are distinct identities, so do not swap them just because they contain the same text in a simple test.

4. Apply security requirements deliberately

Use -b to constrain encryption strength. For example, -b min=1,max=128 asks for at least one bit and no more than 128 bits. The manual documents one bit as integrity protection. A value of zero is not a shortcut for "no security" in the documented syntax, so do not invent one when testing policy.

Use -f for security flags. The available names are noplain, noactive, nodict, forwardsec, maximum and passcred. For example:

$ sasl-sample-client -m SCRAM-SHA-256 -f noplain,noactive
Waiting for mechanism list from server...

This command will still wait for the sample server, so do not run it against an unknown peer. The flags express requirements; they do not upgrade a weak mechanism or provide transport encryption.

Use -e only when an external layer really supplied encryption and authentication. Its fields are ssf=N and id=ID. Claiming external security when none exists weakens the meaning of the test and can make an unsuitable mechanism appear acceptable.

5. Supply addresses only when the mechanism needs them

Some mechanisms need local and remote addresses. The documented syntax is an IP address followed by a semicolon and port, inside the comma-separated option:

In an interactive shell, the semicolons terminate commands unless they are quoted. Use this form when copying the example:

$ sasl-sample-client \
    -i 'local=127.0.0.1;45678,remote=127.0.0.1;45679' \
    -s test -n localhost -m SCRAM-SHA-256

The addresses describe the SASL security context; they do not make this program listen on either port. If you are not testing a mechanism that requires them, leave -i out.

6. Test with the matching sample server

The package also installs sasl-sample-server. The two programs are complementary, but they communicate through standard input and output rather than opening a TCP connection. Each process must therefore be connected to the other process's input and output by your test harness or terminal arrangement. A one-way pipe is not enough: sasl-sample-server | sasl-sample-client only sends the server's output one way and leaves the server unable to receive the client's replies.

Start by checking the server independently, also with a timeout:

$ timeout 5s sasl-sample-server
Generating client mechanism list...
Sending list of 11 mechanism(s)
Waiting for client mechanism...

The exact mechanism count depends on the installed plugin set. The important checkpoint is that the server generates a list and then waits for its peer. If it reports an input parsing error, the process received an incomplete or malformed exchange. Fix the process wiring before changing SASL policy.

When building a two-process harness, keep the timeout and capture both output streams. Use test identities and a disposable environment. Do not treat a successful negotiation as proof that a production service is correctly configured: service-specific configuration, TLS, authorisation rules and credential storage are outside this sample program.

7. Diagnose the common traps

Recovering from a failed run normally means stopping the test processes and removing only temporary capture files you created. The client does not modify system configuration. If you changed a SASL configuration file while preparing a test, restore the previous copy before retesting a service, and restart that service only when its own documentation requires it.

Done means