Skip to content

Latest commit

 

History

History
384 lines (295 loc) · 12.8 KB

case.md

File metadata and controls

384 lines (295 loc) · 12.8 KB

E/SMTP Cases

Cases represent speciffic scenarios that can be configured in JSON and executed as a test for end-to-end testing of MTA & WEB servers.

Glossary

Session

Connection

  • 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.

Destination

  • 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.

Encryption

  • 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.

Authentication

  • auth - (Boolean) [default: false] SMTP authentication.
  • user - (String) Authentication username.
  • pass - (String) Authentication password.

Authentication Config

  • 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

  • ehlo - (String, IP, FQD) [default: hostname] EHLO domain.

XCLIENT

  • xclient - (SMTP command) Special feature allowing enumation of client info:
    • addr - IP address.
    • name - Reverse DNS.
    • helo - HELO/EHLO domain.

Envelope

  • 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]}.

Transfer

BDAT Config
  • 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.
DATA Config

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>.
Speed
  • 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.
Load
  • repeat - (Integer, Times) [default: 0] How many times to resend the same envelope after the first time. Will stop if any delivery fails.

Message (envelope)

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.

Protocol Assertions

Regex assertions to be run against SMTP transactions. There are session level and envelope level assertions.

Session

  • 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" ]
    

Envelope

  • MAIL

  • RCPT

  • DATA/BDAT - Mutully exclusive.

      [ "MAIL", "^250" ],
      [ "RCPT", "^250" ],
      [ "DATA", "^250" ],
      [ "DATA", "Received OK$" ],
      [ "BDAT", "^250" ],
    

MTA Assertions

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 otherwise yyyyMMdd.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.

Basic example.

    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" ]
    ]

Example for verify none.

    type: "logs",
    wait: 10,
    grep: [
      {
        parameter: "-E",
        pattern: "{$uid}"
      },
    ]
    verifyNone: true

Humio

With the addition of Humio plugin you can simply use type: "humio", instead of logs to pull logs from configured Humio instance.

Humio config in properties.json
    humio: {
        auth: "YOUR_API_KEY",
        url: "https://humio.example.com/"
    }

Case

{
    // 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" ]
        ]
    }
}

Maven execution

Example commandline for running cases.

mvn clean -D test="cases.*" test