Cases represent speciffic scenarios that can be configured in JSON and executed as a test for end-to-end testing of MTA & WEB servers.
retry
- (Integer, Attempts) [default: 1] How many times to attempt connection.delay
- (Integer, Seconds) [default: 0] Delay between connection retries.timeout
- (Integer, Milliseconds) [default: Java] Socket timeout.
mx
- (List, String, IP, FQD) [default: 127.0.0.1] MX server list.port
- (Integer) [default: 25] MX port.route
- (String, Name) [default: none] Selects a preconfigured route by name from client.json5 routes if any.
tls
- (Boolean) [default: false] Allows the client to do TLS when STARTTLS is advertised.protocols
- (List, String) [default: Java] TLS protocols to support.ciphers
- (List, String) [default: Java] TLS ciphers to support.
auth
- (Boolean) [default: false] SMTP authentication.user
- (String) Authentication username.pass
- (String) Authentication password.
authBeforeTls
- (Boolean) [default: false] Send AUTH withot requireing TLS. Vulnerable behaviour.authLoginCombined
- (Boolean) [default: false] Send username and password in one line for AUTH LOGIN.authLoginRetry
- (Boolean) [default: false] Disable authLoginCombined and retry AUTH LOGIN.
ehlo
- (String, IP, FQD) [default: hostname] EHLO domain.
xclient
- (SMTP command) Special feature allowing enumation of client info:- addr - IP address.
- name - Reverse DNS.
- helo - HELO/EHLO domain.
-
mail
- (String, Email Address) [default: client.json5] Sender email address. -
rcpt
- (List, String, Email Address) [default: client.json5] Recipients list of email addresses. -
params
- Allows usage of custom parameters for special enviroments.
Will auto-inject list elements at the end of the MAIL or RCPT commands separated by space.
Example case config:
params: {
MAIL: [ "XOORG=example.com" ],
RCPT: [ "ACCEPT" ]
},
headers
- (List, String, String) List of headers to be injected by magic.
Handy for EJF automation and more.
Example case config:
This uses magic client variables. See magic.md.
headers: {
from: "{$mail}",
to: [ "{$rcpt}" ],
sender: "{$mail}",
recipient: [ "{$rcpt}" ]
},
Can be injected in the eml via {$HEADERS}
magic variable or selective by providing the key like {$HEADERS[FROM]}
.
chunkSize
- (Integer, Bytes) [default: 2048, min: 128] Enables CHUNKING if grater than minimum.chunkBdat
- (Boolean) [default: false] Writes BDAT command to socket along with the first chunk.chunkWrite
- (Boolean) [default: false] Writes to socket in uneven chunks between 1024 and 2048 bytes if chunkSize at least 2048.
Only one may be used at the same time (Order of priority).
terminateAfterBytes
- (Integer, Bytes) [default: 0, min: 1] Terminates connection after transfering given bytes of DATA when greater. Enables terminateBeforeDot.terminateBeforeDot
- (Boolean) [default: false] Terminates connection right before transfering DATA terminator <CRLF>.<CRLF>.terminateAfterDot
- (Boolean) [default: false] Terminates connection right after transfering DATA terminator <CRLF>.<CRLF>.
slowBytes
- (Integer, Bytes) [default: 1, min: 128] Write delay every n number of bytes.slowWait
- (Integer, Milliseconds) [default: 0, min: 100] Write delay wait time in milliseconds.
repeat
- (Integer, Times) [default: 0] How many times to resend the same envelope after the first time. Will stop if any delivery fails.
Every message should have either a file or a subject/message pair! If a file is not defined a MIME source will be generated from envelope date along with subject and message. Shile message is mandatory subject may be left blank.
file
- (String, Path) Path to eml file to be transmitted.folder
- (String, Path) Path to eml containing folder. A random eml file will be chosen for each DATA transmission.subject
- (String) Email subject.message
- (String) Email text/plain message.
Regex assertions to be run against SMTP transactions. There are session level and envelope level assertions.
-
SMTP - Initial connection response.
-
EHLO
-
STARTTLS
-
TLS - Successfull handshake protocol / cipher.
-
SHLO - Post STARTLS EHLO response.
-
XCLIENT
-
XHLO - Post XCLIENT EHLO response.
-
AUTH
-
RSET
-
HELP
-
QUIT
[ "SMTP", "^220" ], [ "EHLO", "STARTTLS" ], [ "STARTTLS", "^220" ], [ "TLS", "^TLSv1.2:TLS_RSA_WITH_AES_256_GCM_SHA384" ], [ "SHLO", "250 HELP" ] [ "AUTH", "^235" ] [ "QUIT", "^221" ]
-
MAIL
-
RCPT
-
DATA/BDAT - Mutully exclusive.
[ "MAIL", "^250" ], [ "RCPT", "^250" ], [ "DATA", "^250" ], [ "DATA", "Received OK$" ], [ "BDAT", "^250" ],
You may run assertions against your MTA logs from envelope level. A local logs client is provided to deemonstrate.
See LogsClient.java interface for implementation of external clients.
logPrecedence
- (String) Prepends provided string to the log filename which is otherwiseyyyyMMdd
.log.wait
- (Integer, Seconds) [default: 2, min: 2] Initial wait before calling the external client.retry
- (Integer, Attempts) [default: 1, min: 1] How many times to attempt if verify fails.delay
- (Integer, Attempts) [default: 2, min: 2] Delay between attempts.grep
- (List of Map, String, Regex) Grep sequence to match/exclude logs. Default:{$uid}
verifyNone
- (Boolean) Verify that no logs were found. Disables all below functionalities.verify
- (List, String, Regex) List of regex matches to verify bottom most needed logs received. Provides stability when MTA takes more time.match
- (List of List, String, Regex) Regex assertions to run against log lines. Multiple expressions can run on the same line. All must match.refuse
- (List of List, String, Regex) The opposite of match. Will stop and error on first match.magic
- (List of Map, String, Regex) Collect matching group 1 or whole patterns into magic variable.
type: "logs",
logPrecedence: "fast-",
wait: 10,
retry: 2,
delay: 5,
grep: [
{
// Default match on UID.
pattern: "{$uid}"
},
{
// Exclude DEBUG and TRACE log lines.
parameter: "-vE",
pattern: "DEBUG|TRACE"
}
]
verify: [ "MAPREDUCE:RCPT" ],
match: [
[ "250", "Sender OK" ]
[ "250", "Recipient OK" ]
[ "MAPREDUCE:RCPT", "Custody=true", "Storage=check" ]
[ "250", "Received OK" ]
],
refuse: [
[ "java.lang.NullPointerException" ]
]
type: "logs",
wait: 10,
grep: [
{
parameter: "-E",
pattern: "{$uid}"
},
]
verifyNone: true
With the addition of Humio plugin you can simply use type: "humio",
instead of logs to pull logs from configured Humio instance.
humio: {
auth: "YOUR_API_KEY",
url: "https://humio.example.com/"
}
{
// Magic variables.
$: { // Use the dollar sign to define a map to hold them.
fromAddress: "[email protected]",
toUser: "smoke",
toDomain: "mta11.goldcheesyfish.com",
toAddress: "{$toUser}@{$toDomain}" // Can be used immediatelly after defined above.
},
// MX list and port to attempt to deliver the email to.
mx: [
"example.com"
],
port: 25,
// How many times to try and establish a connection to remote server. First counts.
retry: 2,
// Delay between tries.
delay: 5,
// Enable TLS.
tls: true,
// Set supported protocols.
protocols: [
"TLSv1.2", "TLSv1.3"
],
// Set EHLO to use.
ehlo: "example.com",
// Enable authentication.
auth: true,
user: "[email protected]",
pass: "giveHerTheRing",
// Email envelopes.
envelopes: [
// Envelope one.
{
// Configure chunking parameters to use if CHUNKING supported by recipient server.
chunkSize: 20480,
chunkBdat: true,
chunkWrite: true,
// Magic sender and recipient.
mail: "{$fromAddress}",
rcpt: [
"{$toAddress}"
],
// Set custom params to send with MAIL and/or RCPT.
params: {
MAIL: [ "XOORG=example.com" ],
RCPT: [ "ACCEPT" ]
},
// Email eml file to transmit.
file: "src/test/resources/cases/sources/lipsum.eml",
// Configure early email transfer termination.
terminateAfterBytes: 1024,
terminateBeforeDot: true,
terminateAfterDot: true,
// Assertions to run against the envelope.
assertions: {
// Protocol assertions.
// Check SMTP responses match regular expressions.
protocol: [
[ "MAIL", "^250" ],
[ "RCPT", "^250" ],
[ "BDAT", "^250" ]
],
// External assertions.
external: [
{
// Assertion type logs for pulling logs from FFS.
type: "logs",
// How long to wait before asserting.
wait: 10,
// How many times to retry should no logs be found or valid.
retry: 2,
// Delay between log pulling attempts.
delay: 5,
// Grep command to use to fetch logs.
grep: [
{
// Default match on UID.
pattern: "{$uid}"
},
{
// Exclude DEBUG and TRACE log lines matched.
parameter: "-vE",
pattern: "DEBUG|TRACE"
}
],
// Verify regular expressions that would confirm logs fetched are complete.
verify: [ "MAPREDUCE:RCPT" ],
// Match regular expressions to run agaisnt logs to pass the test.
match: [
[ "250", "Sender OK" ]
[ "250", "Recipient OK" ]
[ "MAPREDUCE:RCPT", "Custody=true", "Storage=check" ]
[ "250", "Received OK" ]
]
// Magic regular expressions that will record data in Session magic for use in following assertions.
// This will record group 1 is there is one else full match.
magic: [
{
name: "ruid",
pattern: "Received OK \\[(.*)\\]"
}
]
}
]
}
}
],
// Assertions to run against the connection.
assertions: {
// Asserting configuration.
protocolFails: false, // If SMTP assertion fails, fail test/exit gracefully.
verifyFails: false, // If external verify checks fail, fail test/exit gracefully.
// Protocol assertions.
// Check SMTP responses match regular expressions.
protocol: [
[ "SMTP", "^220" ],
[ "EHLO", "STARTTLS" ],
[ "SHLO", "250 HELP" ]
]
}
}
Example commandline for running cases.
mvn clean -D test="cases.*" test