aboutsummaryrefslogtreecommitdiff
Ememo - Internet Mail Architecture implementation

Ememo is an implementation of the Internet Mail Architecture.  The
Internet Mail Architecture is documented in the Git repository
https://git.andrewyu.org/andrew/ima.git/.

The protocol itself, and thus any implementation (including this one),
is very incomplete.  By no means shall this be considered a reliable way
to communicate.  This specific implementation is also used as the
testing ground for ideas that haven't entered the protocol yet.

As of the time of updating this file, the implementation code hasn't
been updated to meet the description here.  Help is appreciated.  

Suggestions, comments, and other discussions may be sent to ememo hyphen
general at andrewyu dot org by regular SMTP mail.  A native IMA mailing
list may be created in the future once the technology stabalizes.

Ememo consists of a server implementation and a client implementation.
The server handles receiving mail from other servers, sending mail,
accepting submission from clients, helping clients fetch incoming mail,
and mail format translations in the process.  The client handles
preparing mail for submission, submitting mail, and fetching mail.  Both
the server and the client consists of multiple programs, which form a
complete IMA implementation as a whole, but may also be used seperately.
Each program is configured seperately, simply through a python script
unde the same name but "_config.py" appended.  All configuration options
are documented there.

SERVER IMPLEMENTATION
=====================

The server implementation consists of several programs.  They are
designed to work with each other, but will also work with replaced
parts, additional scripts, and other additions, as they are fairly
modular with simple interfaces.

server-receive listens for incoming connections from other IMA servers.
If the "other IMA server" is also Ememo, then the program that
server-receive accepts connections from is server-sendmail.  After a TCP
connection is established, it validates the other side's client
certificate while performing a TLS handshake.  If the client certificate
is not valid in the X.509 public key infrastructure according to the
OS's  certificate authority certificates, the connection is dropped;
otherwise the connection continues.  After receiving the headers
provided by the sending server, it validates the "mailer" or "from"
header against the domains of the TLS client certificate, compares the
total data size to the max acceptable size, and rejects the message keeping
the connection open for new messages or accepts the message.  Accepted
messages are sent to the standard input of a configured command, which
is usually server-handle-incoming-mail.  It replies the standard output
of said command as each line becomes available.  After the handler
command exits, it sends an "OK" (for return value 0) or "FAIL" (for
return value 1) back or "PARTIAL" (for return value 2), and listens for
more mail, closing once the sending server says "DONE".  If the return
value is 3, the connection is dropped immediatly.

server-handle-incoming-mail reads incoming IMA messages from standard
input or a file specified in an argument.  The "to", "cc", and "bcc"
headers are parsed.  If any of the addresses doesn't have an entry in
the local routig table but has the hostpart of this server, 1 is
returned after all such erroneous addresses are reported in a
"NORECIPIENT %s..." reply.  For each address in "to", "cc", and "bcc"
that have table entries, it looks up the address in the routing table,
and sends the IMA message's data to the standard input to the command
for the address, looked up in the routing table, with the address as the
argument, which is usually server-give-recipient or a mailing list
manager (do note that the mailing list manager must be IMA-compatible;
SMTP mailing list managers will not work).  The command's standard
output is given to standard output as each line becomes available.  If
the command returns 0, "OK %s" where %s is the recipient address is
written to standard output.  If 1 is returned, "FAIL %s" is written.
server-handle-incoming-mail returns 0 if all commands executed return 0,
returns 1 if all commands executed return 1, and returns 2 for a mixture
of 0's and 1's.

(I haven't had time to document everything below, so everything below
are just stubs that need expansion.)

server-give-recipient takes a IMA-message from standard input or the
file indicated in the second command-line argument.  The IMA-message is
parsed, converted to the IMA mailbox format (e.g. attachments are
seperated), and placed in the inbox directory as specified by the first
command-line argument.

server-post-office listens on the user agent fetch mail port and accepts
TLS connections.  Once connected, it authenticates the user with a
provided username and a TLS client certificate or the provided username
and a password, depending on the configuration options for that user.
(PAM authentication is currently unavailable but may be provided in the
future.)  Using the Internet Mail Retreival Protocol, it processes
commands sent by the user agent, and gives the user agent relevant mail
data, according to the contents of the user's mailbox directories which
should conform to the IMA mailbox format.

server-send-mail takes an IMA-message from standard input or the file
specified in the first command-line argument.  The headers are parsed,
Each remote mail server (i.e. hostparts) from the recipient list is
contacted via the Internet Mail Delivery Protocol, sending the headers
to make sure that the message could be delivered.  If all receiving
servers respond indicating that the message could be delivered, the
message will then be delivered.  If not, server-send-mail returns 1
after reporting errors.  At that point, no data is sent to the receiving
servers.

CLIENT IMPLEMENTATION
=====================

The client implementation also consists of several programs which may be
used independently.

make-ima-message take message text, attachments, and metadata,
outputting an IMA message ready for server-sendmail.

fetch-mail literally fetches a IMA mailbox into a local directory.

The user may also wish to use a user agent to help with the reading,
composing and sending of mail, but this is outside of the scope of this
implementation.

AUTHORS AND ACKNOWLEDGEMENTS
============================

The author of this implementation is Andrew Yu, andrew at andrewyu dot
org by both SMTP mail and IMA.  Note that IMA is extremely unstable and
should not be consideredareliable means of communication.

Special thanks to Noisytoot, Luke, and Test_User for ideas used in the
protocol and this implementation.

COPYRIGHT
=========

Copyright (c) 2022  Andrew Yu <andrew at andrewyu dot org>

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice, this permission notice and the following disclaimer
appears in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

TODO
====
* Use commonName too.
* Clarify and expand stubs.
* Support for SRV records.
* Seperate things into program-specific man pages, and have this file
  contain the general structural workflow.