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.