I’m currently working on a personal project where I want to access my Cyrus IMAP-Server using Perl. Hence I looked at CPAN and there are two major modules dealing with IMAP: <!–break–>

I’ve chosen the first one, because it seems to make less effort to get into it and everything I need should be supported. I followed the example in the POD:

1
2
3
4
5
6
7
8
9
10
11
12
13
my $imap = new IMAP::Client();
    $imap->connect(PeerAddr => $server,
                  ConnectMethod => 'SSL STARTTLS PLAIN',
                  )
    or die "Unable to connect to [$server]: ".$imap->error();

    $imap->onfail('ERROR');
    $imap->errorstyle('STACK');
    $imap->debuglevel(1);
    $imap->capability_checking(1);

    $imap->authenticate($user,$pass)
        or die "Unable to authenticate as $user ".$imap->error()."\n";

Unfortunately I always got the nasty little error driving my insane (well, ok, most people think I am already insane anyway):

“`<< * OK odin Cyrus IMAP4 v2.1.18-IPv6-Debian-2.1.18-5.1 server ready

0001 NOOP << 0001 OK Completed << * OK odin Cyrus IMAP4 v2.1.18-IPv6-Debian-2.1.18-5.1 server ready 0002 NOOP << 0002 OK Completed 0003 CAPABILITY << * CAPABILITY IMAP4 IMAP4rev1 ACL QUOTA LITERAL+ MAILBOX-REFERRALS NAMESPACE UIDPLUS ID NOATOMICRENAME UNSELECT CHILDREN MULTIAPPEND SORT THREAD=ORDEREDSUBJECT THREAD=REFERENCES IDLE STARTTLS ANNOTATEMORE << 0003 OK Completed 0004 STARTTLS << 0004 OK Begin TLS negotiation now 0005 CAPABILITY << * CAPABILITY IMAP4 IMAP4rev1 ACL QUOTA LITERAL+ MAILBOX-REFERRALS NAMESPACE UIDPLUS ID NOATOMICRENAME UNSELECT CHILDREN MULTIAPPEND SORT THREAD=ORDEREDSUBJECT THREAD=REFERENCES IDLE AUTH=PLAIN ANNOTATEMORE << 0005 OK Completed 0006 AUTHENTICATE PLAIN PO1X4hc2RmkXdlmg== << 0006 BAD Unexpected extra arguments to Authenticate ”`

I wasn’t able to find anything on the net, but reading the docs more carefully again, I found another option that works now:

1
2
3
4
5
6
7
8
9
10
11
12
13
my $imap = new IMAP::Client();
    $imap->connect(PeerAddr => $server,
                  ConnectMethod => 'SSL STARTTLS PLAIN',
                  )
    or die "Unable to connect to [$server]: ".$imap->error();

    $imap->onfail('ERROR');
    $imap->errorstyle('STACK');
    $imap->debuglevel(1);
    $imap->capability_checking(1);

    $imap->authenticate2($user,$pass)
        or die "Unable to authenticate as $user ".$imap->error()."\n";

The authenticate2() method uses a multi-line login sequence as you can see below:

1
2
3
4
5
>> 0006 AUTHENTICATE PLAIN
<< + 
>> PO1X4hc2RmkXdlmg==

<< 0006 OK Success (tls protection)

P.S.: Just to make absolutely sure, I changed the password hash you’ll see in the examples, I may be insane, but not that stupid ;)