Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IMAP Server Facade - how to make one?

I have implemented a custom email server and web client. The server is just a REST API (similar to google's gmail API) that uses a 3rd party (sendgrid) for sending and receiving. The emails are stored in a database. The web client just talks to the REST client for sending and receiving.

The problem with this approach is it doesn't implement IMAP anywhere, which makes it impossible for standard clients (outlook, iphone, etc.) to connect to and use our email API. This limits customers to using only our client for email.

What I need is some sort of IMAP Server "facade" that will manage the connections to clients and make calls to my REST API for actually handling the requests (get email, send email, etc.).

How can an IMAP facade be implemented? Is there maybe a way to take an existing MailServer and gut it and point all it's "events" to making calls to my API?

like image 835
richard Avatar asked Apr 15 '17 20:04

richard


People also ask

What is IMAP server example?

The incoming mail server for an IMAP account may also be called the IMAP server. For example, if your e-mail provider is example.com, the incoming mail server is likely imap.example.com.

How do I find out what my IMAP server is?

In the left side-bar, click on the Account for your email. Select Account Information towards the top. Find the field for Incoming Mail Server. This is your IMAP server name.

How do IMAP servers work?

As an incoming email protocol, IMAP functions as the intermediary between the email server and email client. When users read an email using IMAP, they read them off the server. They don't actually download or store the email on their local device.

How do I connect to an IMAP server?

Enter your name and email address. Select IMAP for the account type and enter imap.mail.com as incoming server and smtp.mail.com as outgoing server. Enter yourmail.com username and password. Uncheck Test Account Settings by clicking the Next button.


3 Answers

tl:dr; write your gateway in Perl; use Net::IMAP::Server; override Net::IMAP::Server::Mailbox; and use one of the many Perl REST clients to talk to your server.

Your best bet for doing this quickly, while maintaining a reasonable amount of code security, is with Perl. You'll need two Perl modules. The first is Net::IMAP::Server, and here is the Github repository for that module. This is a standards-compliant RFC 3501 server that was purposely designed to have a configurable mail store. You will override the default Net::IMAP::Server::Mailbox implementation with your own code that talks to your custom email backend.

For your second module, choose your favorite Perl module(s) to use to speak to your REST server. Your choice depends on how much fine grained control you want to have over the construction and delivery of the REST messages.

Fortunately, here you have tons of choices. One possibility is Eixo::REST, which has a Github repository here. Eixo::REST seems to deal well with asynchronous vs. synchronous REST API calls, but it doesn't provide a lot of control over X509 key management. Depending on how googley your API is, there's also the REST::Google module. Interestingly, this family also has a REST::Google::Apps::EmailSettings module, specifically for setting Gmail-specific funkiness like labels and languages. Lastly, the REST::Consumer module seems to encapsulate a lot of https-specific things like timeout and authentication as parameters to Perl object instantiation.

If you use these existing frameworks, then about 90% of the necessary code should already be done for you.

Don't do this by hacking Dovecot or any other mail server written in C or C++. If you hack together a mail server quickly using a compiled language, your server will sooner or later experience all the joy of buffer overflows and stack smashing and everything else that the Internet does to fuck over mail servers. Get it working safely first, then optimize later.

like image 64
johnwbyrd Avatar answered Oct 09 '22 07:10

johnwbyrd


(This is basically my comment again, but elaborated quite a bit more.)

Some IMAP servers, most notably Dovecot, are structured such that the file access is in a separate module with a defined interface. Dovecot isn't the only one, but it's by far the most popular and its backend interface is known to be appropriate, so I'd take that absent specific concerns.

There already exist non-file modules such as imapc, which proves that it can be done. When a client opens a mailbox backed by imapc, Dovecot parses IMAP commands, calls message access functions in imapc, imapc issues new IMAP commands, parses the server responses, returns C structs to Dovecot, Dovecot fashions new IMAP responses and returns them to the client.

I suggest that you take the dovecot source, look at src/lib-storage/inbox/index/imapc and the other backends in that directory, and implement one that speaks your REST API as a client.

like image 28
arnt Avatar answered Oct 09 '22 08:10

arnt


Since you're familiar with .NET, I would suggest hacking either of the following implementations of IMAPv4 servers to your liking:

  • Lumisoft Mail Server - a very old project indeed (let's call it "mature", huh?). Don't be too turned off by the decade-old website and the lack of a github link - the source is provided under "other downloads".
  • McNNTP - also an older project and with a major focus on NNTP (as the name says) but very close to what you're trying to achieve in terms of the IMAP component. Take a look, you'll probably find this a good starting point.
like image 35
vzwick Avatar answered Oct 09 '22 07:10

vzwick