# smtpkn

> SMTP written from the specification so a Kotlin/Native service can send mail with no JVM in sight. TLS with the chain actually verified, seven SASL mechanisms.

Page: https://kotlin.website/smtpkn

## Why it exists

On the JVM this was solved twenty years ago. On Kotlin/Native there is nothing, and the two
workarounds fail the same way: shelling out to `sendmail` and wrapping libcurl both hide the
protocol exactly where it has to be visible.

## Three decisions worth knowing about

**Replies are matched by counting.** The specification forbids matching by code or text, and
it is right to: codes repeat and text is server-defined. Only order holds. With `PIPELINING`
negotiated and five commands in flight, a matcher that reads codes pairs the wrong reply with
the wrong command exactly when the session is busiest — silently.

**A partial refusal is a result, not an exception.** Three recipients accepted, two rejected:
if that throws, the caller has lost which three worked, and the only safe options left are to
give up or to retry all five and deliver three duplicates.

**Anything a rule forbids is refused, not sanitised.** A line break inside an address is a way
to append headers of somebody else's choosing. Refusing means the caller finds out where the
mistake was made.

## What you get

- Submission per RFC 6409: port 587 with `STARTTLS`, port 465 with implicit TLS.
- TLS with the certificate chain **and the host name** verified — OpenSSL on Kotlin/Native,
  `SSLEngine` on the JVM.
- Seven SASL mechanisms: `PLAIN`, `LOGIN`, `CRAM-MD5`, `SCRAM-SHA-1`, `SCRAM-SHA-256`,
  `XOAUTH2`, `OAUTHBEARER`.
- ESMTP: `PIPELINING`, `SIZE`, `8BITMIME`, `SMTPUTF8`, `DSN`, `ENHANCEDSTATUSCODES`,
  `CHUNKING`, plus punycode for internationalised domains.
- Message building: RFC 5322 headers, `multipart/alternative`, attachments, encoded words.

## Install

```kotlin
repositories { maven("https://reposilite.kotlin.website/snapshots") }
dependencies { implementation("io.github.youndie:smtp-client:<VERSION>") }
```

`linuxX64` is the platform this is built for and the only one it is claimed to work on — that
is where the whole suite runs, including TLS against a real server and end to end against
Mailpit and Postfix.
