Sending remote IP to dovecot
I’ve been digging through the z-push imap code trying to find a good spot for this, and after a while, I figured I should probably post here
I’m looking to implement something like the ‘dovecot_ident’ module in roundcube. This sends a command right after authentication to dovecot:
. x-originating-ip <the ip address>
This allows dovecot to know the remote IP of the client, instead of seeing it just as the IP of the local application (e.g. roundcube) talking to IMAP. It’s nice for logging and very nice for using with the new dovecot authentication policy stuff.
Is there any feature like that kicking around somewhere in z-push that I haven’t found? If not, can someone give me a hint (as I’m failing miserably so far) where I could patch something like that in? I’m thinking somewhere in ‘autodiscover/autodiscover.php’, but I also don’t see a function in the imap backend to send arbitrary strings to IMAP (vs using the built-in php imap commands). Anybody implement this already?
And, duh, left out: using z-push 2.3.8 out of the ‘trusty’ repo, talking to the imap backend, which is talking to a localhost dovecot instance.
The obvious place to put that would be in the IMAP login function… I run Dovecot here and can give an attempt to hack that in a shot (with an appropriate config parameter in case your IMAP server doesn’t support it.)
Am I missing the capability required for this to work? I get this back and there’s no indication that a “.dot command” would be accepted (and it isn’t.)
a OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS BINARY MOVE COMPRESS=DEFLATE] Logged in
If you have a pointer to where to look I’ll see if I can put this into the authentication exchange that Z-push’s IMAP module performs.
The dot is just the imap tag. And you seem to have the ID capability. Did you try it after you’d logged in?
Actually, I re-tcpdump’d that and realized I’m an idiot and didn’t put the whole thing. It should actually look like this:
A0001 ID (“x-originating-ip” “188.8.131.52”)
(or with whatever imap tag, e.g. ‘.’)
And, yeah, my first thought was to drop this in the z-push imap backend logon function, but then saw that it’s all so layered (so that it can function as a plugin) that it’s not clear if that’s the right spot. I also couldn’t find any php imap function that lets you send strings directly (as opposed to being a wrapper). Did you have something in mind for that?
Aha… Yes, but didn’t know the syntax and wasn’t sure what IMAP command was being used (it wasn’t clear from your original post.)
The IMAP interface is done via a call to a PHP library; I’ll dig around in there and see if there’s an exported way to inject an arbitrary command…
(Update: Looks like not, at least not in the standard php library. That would mean extending it. Let me do a bit of noodling on whether I can figure out a rational way to do it.)
After digging around the code some the obvious (and “most-correct”) way to do this is to enhance the IMAP php library so that when it is sent an “open” it checks for the capability and, if present and the environment variable with the remote IP is set (which it will be if it was called an upstream “thing” that sets it, such as a web server) it then sends that stanza down after the password is accepted.
This would cause the IMAP php module to log it to Dovecot (or any other compatible IMAP server) for all users of it, not just Z-push, and it requires no code changes in the Z-push codebase itself. I run FreeBSD and haven’t dug into the php development community at all, so while I can certainly grab the FreeBSD port and do it in there that doesn’t help anyone except possibly FreeBSD users if I sent the patch back into their system, and it’s subject to rot there over time. The “right” approach to go after this is in the php upstream of course; I’ll stick a note in my “list of things to look at”, but I can’t commit to a when I’ll get to it.