IMAP ID extension support

This blog has been quiet since 2015, but VMime hasn’t. Here is some news!

VMime now supports the IMAP ID extension (RFC 2971), as requested in issue #222. This extension allows an IMAP client and server to exchange identification information, such as their name, version or vendor.

The extension is mostly used for statistics and troubleshooting, but some servers actually require it. For example, NetEase servers (163.com, 126.com) refuse to open a folder until the client has identified itself: the SELECT command fails with an “Unsafe Login” error. Until now, this made these accounts unusable with VMime.

Here is how to enable it:

// Create a new session
vmime::shared_ptr <vmime::net::session> sess = vmime::net::session::create();

vmime::shared_ptr <vmime::net::store> store =
    sess->getStore(vmime::utility::url("imaps://user:password@imap.163.com"));

// Send client identification to the server
store->setProperty("options.id", true);
store->setProperty("options.id.name", "MyMailClient");
store->setProperty("options.id.version", "1.0");
store->setProperty("options.id.vendor", "My Company");

store->connect();

// You can now open folders!

When the options.id property is set to true, VMime sends the ID command just after authentication, if the server supports it. This is done for every connection, including the ones VMime opens for folders. Each options.id.<field> property is sent as a field, so you can use any of the fields defined in RFC 2971 (name, version, os, vendor, support-url, etc.). If no field is set, VMime sends ID NIL.

Sending identification information discloses some details about your application, so it is disabled by default. Nothing is sent unless you enable it explicitly.

You can also get the identification sent back by the server:

#include "vmime/net/imap/IMAPStore.hpp"

vmime::shared_ptr <vmime::net::imap::IMAPStore> imapStore =
    vmime::dynamicCast <vmime::net::imap::IMAPStore>(store);

// Field names are converted to lower-case
const std::map <vmime::string, vmime::string> serverId =
    imapStore->getServerIdentification();

for (const auto& field : serverId) {
    std::cout << field.first << ": " << field.second << std::endl;
}

Leave a Reply

Your email address will not be published. Required fields are marked *