Using imtest and the IMAP protocol

It can be very useful to be able to interact with the IMAP server by manually writing commands, especially when troubleshooting problems. The imtest tool in the Cyrus distribution makes this technique even more useful, as you can authenticate using SASL to servers you might not otherwise be able to access due to security requirements and you can use SSL/TLS encrypted connections. You can also use a different authorization name to your authentication name, allowing you to authenticate using admin's credentials but then essentially "become" a user of your choice for the purposes of the rest of the session.

Much of this page refers to functionality and features that are not part of the IMAP4r1 standard or even specific to Cyrus IMAPd. Some may be useful for working with other IMAP implementations, some will not.

Connecting to the server

The first thing you'll want to do is connect to your IMAP server. I'm going to assume that imtest is on your PATH. If it is not, you can run it as /path/to/cyrus/installation/bin/imtest, or simply add /path/to/cyrus/installation/bin to your PATH. To log in as yourself on the local host, simply run imtest localhost and enter your password when prompted. You should see something like this:

S: * OK bucket.localnet Cyrus IMAP4 v2.1.14 server ready
C: C01 CAPABILITY
S: * CAPABILITY IMAP4 IMAP4rev1 ACL QUOTA LITERAL+ MAILBOX-REFERRALS 
NAMESPACE UIDPLUS ID NO_ATOMIC_RENAME UNSELECT CHILDREN MULTIAPPEND 
SORT THREAD=ORDEREDSUBJECT THREAD=REFERENCES IDLE X-NETSCAPE
S: C01 OK Completed
Please enter your password:
C: L01 LOGIN craig {9}
S: + go ahead
C: 
S: L01 OK User logged in
Authenticated.
Security strength factor: 0

If so, you're now able to send IMAP commands directly to the server. The one you'll probably need to know first is how to disconnect. Simply type =. logout = (yes, the full stop and space are required). You should see something like this:

. logout
* BYE LOGOUT received
. OK Completed
Connection closed.

You should now find yourself back at the prompt. In general, that's how you can interact with the IMAP server for testing, though normally you'll want to connect a bit differently.

Connection Options and Authentication

Some may not be able to connect using the basic command given above. Perhaps your server requires an encrypted connection, a hashed password, or doesn't listen on the normal port. For that matter, perhaps you're here because you're having trouble getting the server to authenticate users! There are a few command arguments to imtest that you'll need to use. The full list can be found by running imtest -h, and more extensive coverage can be found in the imtest man pages (which you should read).

The most command extra arguments you'll want to use are:

  • -p port to connect to an IMAP server listening on a different port (useful when testing settings changes on a production server, as you can have another imapd listen on a different port and use a different config file)
  • -s to use IMAP over SSL (imaps, usually tcp/993), which is not to be confused with negotiating SSL/TLS after connecting.
  • -u : the authorization name to use. Usually the same as the authentication name, so if you specify one you normally specify both.
  • -a : authentication name . See above.
  • -w : password to use. Should be the password associated with the authentication username. Warning this may be visible to other users in ps output, etc. You're usually better off entering the password interactively.

Authentication and Authorization

One handy trick you can do is to authenticate as an admin, but provide a different username for authorization. This lets you essentially 'become' that user, and is in concept somewhat similar to root using 'su - username' to "become" a different user. The main advantage is that you can act as any user, without needing to know or change their password. This is especially handy when troubleshooting user-specific problems and when performing batch tasks. You should read the AuthorizationAndAuthentication page for more information on this.

A typical command to authenticate as user 'cyrus' (an admin) but gain the priveleges and essentially the identity of user 'craig' (a normal user) would be:

imtest -s -u craig -a cyrus localhost

Note the use of ssl ( -s ). It is equally valid to use TLS or any other security layer. Note that you must use some sort of security layer to use the PLAIN SASL mechanism, and you must use a SASL mechanism that supports proxy authentication in order to have a different authorization identity from authentication identity.

When you've been authorized as a given user, it's just as if you authenticated as them too. You have all their priveleges (or lack thereof), when you subscribe to a mailbox you subscribe them to that mailbox, and when you flag messages as seen they show up as seen for that user. This is very handy, especially for batch-subscribing users to a new shared mailbox.

IMAP syntax

So, we've done the imtest command, logging in, and authentication to death. You still probably want some information about useful things you can do once connected.

(NOTE: Following needs checking by someone who knows better, I haven't had time to read the entire IMAP4r1 RFC in detail yet) In general, IMAP protocol commands take the form:

tag COMMAND [argument [argument [...]]

where tag is a user-chosen number or string. I usually just use '.' or numbers, counting up from 1, but others use a-z etc. Commands are case-insensitive (at least in Cyrus IMAPd) but the convention is to use UPPERCASE for all commands. Some other things, like mailbox and user names, are case sensitive. For example, these are all OK:

. SUBSCRIBE user.monty
a subscribe user.monty
1 Subscribe user.monty
b33p sUbScRiBe user.monty

... though the latter one might get you laughed to death if anyone caught you using it.

IMAP Commands

Here's a list of common IMAP commands. I've used 'a' to 'z' as the tags, but you can use whatever is appropriate. Non-literal arguments are shown in lower case, so where you see mailbox you would use, for example, user.jcleese or user.brian. Thanks to Ken Murchison for the basis of this summary. Please direct any flames or errors to me (see the bottom of the page). Note: All of the following examples assume that unixhierarchysep is set to no in your imapd.conf. If it is enabled, you need to use / instead of . in all the mailbox paths. A slightly more detailed description of the IMAP commands follows this summary.

  • a CAPABILITY: Print some information about what capabilities the mail server has, such as authentication options and ACL support.
  • b SELECT mailbox: Opens a mailbox and prints the number of messages flagged as unread.
  • c FETCH msgno BODY[HEADER]: Display the headers of message msgno. msgno is a number from 1 to the number of messages in the mailbox as reported by SELECT. Note that the [HEADER] is literal.
  • d FETCH msgno BODY[]: Display an entire message.
  • e FETCH msgno FLAGS: Display any flags, such as \Seen, \Deleted, and \Flagged that may be set on a message.
  • f STORE msgno [-+]FLAGS \FLAGNAME: Sets (with +) or unsets (with -) flag \Flagname on message msgno. A common flag is the \Deleted flag, which marks a message for deletion at the next EXPUNGE, and causes most clients to hide the message or otherwise indicate that it has been deleted.
  • g EXPUNGE: Actually delete any messages flagged as \Deleted.
  • h CREATE mailbox: Create mailbox
  • i DELETE mailbox: Delete . Unlike flagging individual messages as deleted, this is immediate and permanant.
  • j RENAME oldmailbox newmailbox: Rename (move) oldmailbox to newmailbox.

There are also some commands which are somewhat or entirely specific to Cyrus IMAPd. While normally run from cyradm, there are times it can be handy to run them via imtest (or telnet). This can be handy if you want to be able to set ACLs on some of your mailboxes without being the admin, for example.

  • w RECONSTRUCT mailbox: Attempts to reconstruct a mailbox, much like running reconstruct from the command line. Must be run by an admin(?).
  • x SETACL mailbox user acl: Sets acl for user on mailbox.
  • y GETACL mailbox: Lists ACLs on =mailbox.
  • z DELETEACL mailbox user Removes the ACL for user from mailbox entirely.

One issue that may occasionally confuse is when you issue an apparently valid command, only to have the server respond with BAD Unrecognised command:

SUBSCRIBE user.craig
SUBSCRIBE BAD Unrecognized command
Why? You've missed the command tag, so the server has used UNSUBSCRIBE as the command tag. It doesn't recognise user.craig as a command, so it reports BAD Unrecognised command. This example might clarify things:
x FETCH 1 FLAGS
* 1 FETCH (FLAGS (\Flagged \Seen))
x OK Completed
SUBSCRIBE FETCH 1 FLAGS
* 1 FETCH (FLAGS (\Flagged \Seen))
SUBSCRIBE OK Completed

CAPABILITY

The CAPABILITY command, unsurprisingly, prints a summary of server capabilities. Note the server may choose not to show some capabilities depending on whether or not you have authenticated yet, and what the security level of your connection is. A very common one is that Cyrus IMAPd is usually set not to advertise AUTH=PLAIN on unencrypted connections. This may mean that the capability is not present, or that the server simply chooses not to tell you about it.

Example:

a CAPABILITY
* 43 EXISTS
* 1 RECENT
* CAPABILITY IMAP4 IMAP4rev1 ACL QUOTA LITERAL+ MAILBOX-REFERRALS 
NAMESPACE UIDPLUS ID NO_ATOMIC_RENAME UNSELECT CHILDREN MULTIAPPEND
SORT THREAD=ORDEREDSUBJECT THREAD=REFERENCES IDLE LOGINDISABLED X-NETSCAPE
a OK Completed

SELECT

The SELECT command opens a mailbox, and prints a summary of its status. You can specify a mailbox relative to your INBOX, or to the global IMAP root. SELECT INBOX and SELECT user.username are equivalent, if username is your authorization name for this connection. Similarly, SELECT INBOX.Sent and SELECT user.username.Sent both select the same mailbox. You can SELECT any mailbox you have permission to see, but mailboxes outside your INBOX herirachy must be specified in names relative to the global IMAP namespace (eg user.someotheruser).

Example:

z SELECT INBOX
* FLAGS (\Answered \Flagged \Draft \Deleted \Seen NonJunk
$Label2 $Label1 $Label3 $Label4 $Label5 Junk $Forwarded $MDNSent)
* OK [PERMANENTFLAGS (\Answered \Flagged \Draft \Deleted
\Seen NonJunk $Label2 $Label1 $Label3 $Label4 $Label5 Junk
$Forwarded $MDNSent \*)]
* 42 EXISTS
* 0 RECENT
* OK [UNSEEN 41]
* OK [UIDVALIDITY 1060587836]
* OK [UIDNEXT 12645]
z OK [READ-WRITE] Completed

FETCH

Retrieves information about a message, or all or part of a message. a FETCH msgno BODY[HEADER] gets just the headers, a FETCH msgno BODY[] gets the entire message. a FETCH msgno FLAGS displays any flags, such as \Seen and \Deleted, that are set on the message. It is also possible to do things like fetch only part of a message - see the IMAP4r1 RFC for details.

Example:

a FETCH 1 FLAGS
* 1 FETCH (FLAGS (\Flagged \Seen))
a OK Completed
b FETCH 1 BODY[HEADER]
* 1 FETCH (BODY[HEADER] {1711}
Return-Path: 
Received: from mail.example.com ([202.0.58.20] helo=linda-1.paradise.net.nz)
        by mail.somewhere.net with esmtp
        for ; Thu, 29 Jan 2004 02:11:28 +0800
Date: Thu, 29 Jan 2004 07:11:17 +1300
From: Remote User 
Subject: Good news
To: Craig Ringer 
Message-id: <003x01x3e5cx$2489x8f0$d000x6x2@EXAMPLE>
MIME-version: 1.0
X-Spam-Flag: false
X-Scanned-By: MIMEDefang
X-Virus-Scanned: ClamAV

)
b OK Completed

STORE

The STORE command can be used to set flags on a message. A common use is to set the \DELETED flag, which marks a message as deleted so that it will be removed from the mailbox when EXPUNGE is next run. Messages flagged as \DELETED are normally hidden by mail clients, or displayed with some indication that they're tagged for deletion (an icon with a red x in it, for example). To set and unset flags with the STORE command, the syntax is: a STORE [+-]FLAGS \FLAGNAME . Use + to set a flag, and - to unset it.

Example:

a FETCH 1 FLAGS
* 1 FETCH (FLAGS (\Flagged \Seen))
a OK Completed
b STORE 1 +FLAGS \DELETED
* 1 FETCH (FLAGS (\Flagged \Deleted \Seen))
b OK Completed
c FETCH 1 FLAGS
* 1 FETCH (FLAGS (\Flagged \Deleted \Seen))
c OK Completed
d STORE 1 -FLAGS \DELETED
* 1 FETCH (FLAGS (\Flagged \Seen))
d OK Completed
e FETCH 1 FLAGS
* 1 FETCH (FLAGS (\Flagged \Seen))
e OK Completed

EXPUNGE

The EXPUNGE command permanantly deletes any messages with the \Deleted flag set from the mailbox. This will change the messsage numbers (but not their UID). It will also print an updated message count.

Example:

. EXPUNGE
* 45 EXISTS
* 1 RECENT
. OK Completed

CREATE and DELETE

Create and delete mailbox with a CREATE mailbox and a DELETE mailbox. mailbox may be specified relative to the INBOX of the logged in user, or relative to the IMAP root.

Example:

a CREATE INBOX.test
a OK Completed
a DELETE INBOX.test
a OK Completed
A CREATE INBOX.test
A OK Completed
a CREATE INBOX.test
a NO Mailbox already exists
a DELETE INBOX.test
a OK Completed

RENAME

Rename, or move, a mailbox. RENAME oldmailbox newmailbox.

Example:

k RENAME INBOX.test INBOX.blah
k OK Completed

RECONSTRUCT

Tells Cyrus IMAPd to attempt to rebuild the indexes of the specified mailbox. This is probably not especially useful, since cyradm and the reconstruct binary are probably much better interfaces. See "man reconstuct" for details.

GETACL, SETACL, DELETEACL

Manipulate ACLs on mailboxes. I won't cover ACL specifications here, as they're documented quite well enough in the docs shipped with Cyrus IMAPd. Again, cyradm is probably a better interface for these commands in normal use.

Example:

2 GETACL INBOX
* ACL INBOX craig lrswipcda
2 OK Completed
3 SETACL INBOX monty lrswipcda
3 OK Completed
4 GETACL INBOX
* ACL INBOX craig lrswipcda monty lrswipcda
4 OK Completed
5 DELETEACL INBOX monty
5 OK Completed
6 GETACL INBOX
* ACL INBOX craig lrswipcda
6 OK Completed

Others

This is not an exhaustive list of IMAP commands; far from it. See the Further Information section at the end of this page.

Telnet / netcat

You can also connect to an IMAP server directly using telnet or netcat - telnet localhost 143 (for example). As far as I know you won't be able to use SSL/TLS or a different authorization name to your authentication name, though. If you connect this way, you'll need to login manually. Warning - your login credentials will not be encrypted, so this is to be avoided in favour of using imtest whenever possible. The command to log in, which you need to send before you can do much on the server, is: . login username password . This will only work if you server permits plaintext logins over insecure links, which many do not.

Further information

It is strongly suggested that you read RFC2060, the IMAP4r1 RFC. The command summaries, in particular, are very, very useful.

References

RFC2060 - IMAP4r1

-- TWikiGuest (Craig Ringer, craig (at) postnewspapers d*t com dot au) - 13 Apr

Topic revision: r40 - 31 Aug 2005 - 14:19:45 - TWikiGuest
 
This site is powered by the TWiki collaboration platformCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback