AH HA!
A night of testing & debugging, and I finally got it!
exim4.31 / courier imap 3.02 / redhat 9
plain authenticator (adapt to login and other formats)
server_condition = \
${if eq \
{${substr{0}{4}{${readsocket\
{/var/run/authdaemon.courier-imap/socket}\
{AUTH
${strlen:imap\nlogin\n${quote:$2}\n$3\n}\nimap\nlogin\n$2\n$3\n\n\n}\
{5s}\
{\n}\
{socket failure}\
}\
}\
}\
}\
{USER} \
{yes}\
{no}\
}
the magic is in the AUTH string
AUTH
${strlen:imap\nlogin\n${quote:$2}\n$3\n}\nimap\nlogin\n$2\n$3\n\n\n
Note the following:
${quote:$2} -- the username is put in quotes, because virtual mail
systems often use localpart@domain as the login -- not just localpart.
if an '@' appears in the auth mechanism, then exim stops reading the
strlen at the @ -- which means the authdaemon is told to ignore the 2nd
half of the email address AND the password. In that scenario, it
always fails
The workaround, is to have exim read in the email address into strlen
using quotes
BUT you can't pass authdaemon qoutes, because its not built to handle
them
So
1- you don't put the second $2 in quotes (that one is sent to the
socket as-is)
2 - you add "\n\n" to the end of the AUTH string (\n becomes \n\n\n),
to make up for the missing quotes (exim calculates the strlen including
the quotes, so you have 2 chars to account for). if you don't do this,
then the socket is likely to hang
Hope this helps others!