What is IMAP and how does it work?

What is protocol?

A protocol is a set of rules and conventions that govern the communication and interaction between different entities, such as computers, devices, or software applications. 1

What is IMAP?

IMAP - Internet Message Access Protocol - was designed by Mark Crispin in 1986 as a remote access mailbox protocol, in contrast to the widely used POP, a protocol for simply retrieving the contents of a mailbox. 2

IMAP is protocol that is used for accessing e-mail on server. IMAP allow user to access email from different locations at the same time, which means that you can access you email with computer, and mobile at the same time. This couldn’t be done with POP (Post Office Protocol) which would download email at the one place from where we access it and delete from server.

IMAP versions

There is five versions of IMAP so far.

  • First version IMAP Original was released in 1986.
  • IMAP2
  • IMAP3
  • IMAP2bis
  • IMAP4

In this post, we will explore IMAP version 4 rev1. Request for comment (RFC) can be found here{:target="_blank"}

Client-server architecture

IMAP protocol is based on client-server architecture. Client is one who is starting communication. Each command between client and server is prefixed with identifier, called “tag”, for example short string A0001. Except string command can be prefixed with + or * character. Character + means that the instance is ready to get more data from source, and * tag means that the response is untagged. This means that this data doesn’t have specific command associate with it. If server needs to send update for mailbox to the client it can use * for tag part of message, since it’s not associate with any client command.

But, more real scenario would looks something like this, with more clients contacting one server.

Server completion response can be:

  • OK - success
  • NO - failure
  • BAD - protocol error

Connection between client and server can be in four states:

  • NOT AUTHENTICATED
  • AUTHENTICATE
  • SELECTED
  • LOGOUT

Based on this state there is different set of commands that can be used by client and server. For example client command CAPABILITY can be used in ANY connection state.

1
2
3
4
5
CAPABILITY command
Arguments:	none
Response:	REQUIRED untagged response: CAPABILITY 
Result:		OK - success
		BAD - command unknown or arguments invalid

Example of IMAPv4rev1 connection between client and server

Text below represent simple exchange between client and server using IMAPv4rev1 protocol.3

S:   * OK IMAP4rev1 Service Ready
C:   a001 login mrc secret
S:   a001 OK LOGIN completed
C:   a002 select inbox
S:   * 18 EXISTS
S:   * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
S:   * 2 RECENT
S:   * OK [UNSEEN 17] Message 17 is the first unseen message
S:   * OK [UIDVALIDITY 3857529045] UIDs valid
S:   a002 OK [READ-WRITE] SELECT completed
C:   a003 fetch 12 full
S:   * 12 FETCH (FLAGS (\Seen) INTERNALDATE "17-Jul-1996 02:44:25 -0700"
      RFC822.SIZE 4286 ENVELOPE ("Wed, 17 Jul 1996 02:23:25 -0700 (PDT)"
      "IMAP4rev1 WG mtg summary and minutes"
      (("Terry Gray" NIL "gray" "cac.washington.edu"))
      (("Terry Gray" NIL "gray" "cac.washington.edu"))
      (("Terry Gray" NIL "gray" "cac.washington.edu"))
      ((NIL NIL "imap" "cac.washington.edu"))
      ((NIL NIL "minutes" "CNRI.Reston.VA.US")
      ("John Klensin" NIL "KLENSIN" "MIT.EDU")) NIL NIL
      "<B27397-0100000@cac.washington.edu>")
       BODY ("TEXT" "PLAIN" ("CHARSET" "US-ASCII") NIL NIL "7BIT" 3028
       92))
S:    a003 OK FETCH completed
C:    a004 fetch 12 body[header]
S:    * 12 FETCH (BODY[HEADER] {342}
S:    Date: Wed, 17 Jul 1996 02:23:25 -0700 (PDT)
S:    From: Terry Gray <gray@cac.washington.edu>
S:    Subject: IMAP4rev1 WG mtg summary and minutes
S:    To: imap@cac.washington.edu
S:    cc: minutes@CNRI.Reston.VA.US, John Klensin <KLENSIN@MIT.EDU>
S:    Message-Id: <B27397-0100000@cac.washington.edu>
S:    MIME-Version: 1.0
S:    Content-Type: TEXT/PLAIN; CHARSET=US-ASCII
S:
S:    )
S:    a004 OK FETCH completed
C:    a005 store 12 +flags \deleted
S:    * 12 FETCH (FLAGS (\Seen \Deleted))
S:    a005 OK +FLAGS completed
C:    a006 logout
S:    * BYE IMAP4rev1 server terminating connection
S:    a006 OK LOGOUT completed

Cool, let’s now analyze part by part of this connection between client and server.

1
2
3
S:   * OK IMAP4rev1 Service Ready
C:   a001 login mrc secret
S:   a001 OK LOGIN completed
  • First, server send untagged information that it is ready to accept commands from client. The version of protocol being used is IMAP4rev1. Next command is LOGIN command which has general form something like this tag LOGIN username password. As we can see IMAP uses plain text for authentication. Since this is huge security risk there is AUTHENTICATE command which supports mechanisms like DIGEST-MD5 or CRAM-MD5. Then server respond that command with tag a001 is successful.
1
2
3
4
5
6
7
C:   a002 select inbox
S:   * 18 EXISTS
S:   * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
S:   * 2 RECENT
S:   * OK [UNSEEN 17] Message 17 is the first unseen message
S:   * OK [UIDVALIDITY 3857529045] UIDs valid
S:   a002 OK [READ-WRITE] SELECT completed

Now client initiate communication with server, with new client command SELECT with parameter inbox, and command tag. This command tells the server that client wants to select mailbox named “inbox”. Then server respond, with untagged response, that there exist 18 messages in selected mailbox. After that, server respond with list of possible flags that can be set for messages in this mailbox. Then server send that there are two recent messages. Recent messages are those that have arrived since our last connection or since our client last checked for new mail. Next part specifies that messages 17 is the first unseen message.

Last message tells that the SELECT command is completed, and now client has read-write access to selected mailbox.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
C:   a003 fetch 12 full
S:   * 12 FETCH (FLAGS (\Seen) INTERNALDATE "17-Jul-1996 02:44:25 -0700"
	RFC822.SIZE 4286 ENVELOPE
	("Wed, 17 Jul 1996 02:23:25 -0700 (PDT)" // Date
	"IMAP4rev1 WG mtg summary and minutes"	// Subject
	(("Terry Gray" NIL "gray" "cac.washington.edu"))	// Sender
	(("Terry Gray" NIL "gray" "cac.washington.edu"))	// Recipients
	(("Terry Gray" NIL "gray" "cac.washington.edu"))
	((NIL NIL "imap" "cac.washington.edu"))
	((NIL NIL "minutes" "CNRI.Reston.VA.US")
	("John Klensin" NIL "KLENSIN" "MIT.EDU")) NIL NIL
	"<B27397-0100000@cac.washington.edu>")	// Message ID
	BODY ("TEXT" "PLAIN" ("CHARSET" "US-ASCII") NIL NIL "7BIT" 3028	92))
S:    a003 OK FETCH completed

Next part of sequence, fetch all parts of message number 12. After request server responds with flag \Seen which indicates that this message is marked as seen, and send detailed infromation about email message (ENVELOPE part). Envelope information contains Date, Subject, Sender, list of Recipients, and Message ID. Next part tells client some information about email message. Here we have, plain text, with US-ASCII characters, using 7BIT transfer encoding scheme. It contains 3028 bytes and spans across 92 lines.

At the end, server confirms successful completion of FETCH request.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
C:    a004 fetch 12 body[header]
S:    * 12 FETCH (BODY[HEADER] {342}
S:    Date: Wed, 17 Jul 1996 02:23:25 -0700 (PDT)
S:    From: Terry Gray <gray@cac.washington.edu>
S:    Subject: IMAP4rev1 WG mtg summary and minutes
S:    To: imap@cac.washington.edu
S:    cc: minutes@CNRI.Reston.VA.US, John Klensin <KLENSIN@MIT.EDU>
S:    Message-Id: <B27397-0100000@cac.washington.edu>
S:    MIME-Version: 1.0
S:    Content-Type: TEXT/PLAIN; CHARSET=US-ASCII
S:
S:    )
S:    a004 OK FETCH completed

Here we have client that send command to retrieve only the header section of message with number 12. Next lines contains specific fields from the email’s header. Then empty line from server which means represents end of header data. And finally, server sends tagged message to client that FETCH is completed.

1
2
3
4
5
6
C:    a005 store 12 +flags \deleted
S:    * 12 FETCH (FLAGS (\Seen \Deleted))
S:    a005 OK +FLAGS completed
C:    a006 logout
S:    * BYE IMAP4rev1 server terminating connection
S:    a006 OK LOGOUT completed

Now our client try to add new flag to the message with number 12. +flags means that we want only to add flag without removing any existing ones. Then server responds with updated flags for message number 12, and list them (\Seen \Deleted). After that server confirms successful completion of adding the \Deleted flag.

Then, our client initiate logout with command tag a006, to which the server responds with BYE and OK LOGOUT



    • Internet
     ↩︎
  1.  ↩︎
    • This example can be found in RFC 3501, Chapter 8
     ↩︎