On 2007-01-03, at 1436, Joshua Megerman wrote:
look at the 5.4.18 source code for the call_onchange() function (at the end of vpopmail.c), see how it works, and how it gets called from various places in the code. then consider writing a call_onauth() function similar to that, and then calling it from the appropriate place(s?) in vchkpw.c.Will do (once it's out :))
it's out. i'm running it now.wait- rick, did you forget to announce it on this list, or is it not for general consumption yet? i downloaded it from sourceforge and it works fine, including the onchange stuff.
- I'm a little busy working on a couple ofother things, like releasing my Uber-Mega-qmail patch set (the patches aredone, but documenting them takes time... :), but I'll add this to the queue. Since the patch isn't going into 5.4.18 anyway, there's time.
so you've got a qmail mega-patch as well? i'm starting to wonder who DOESN'T have one anymore...
mine: http://qmail.jms1.net/patches/combined-details.shtml
the only thing to keep in mind is that the "onauth" script itself needs to run as quickly as possible, because whatever service the user is logging into, is waiting for it to finish. this is why my own "onchange" script simply sends its command line arguments to a named pipe, where an "update-qmail" service is waiting for the data... that service actually does all of the work while the script exits and vpopmail lets the user get back to what they were doing.Alternatively, vpopmail could just write to the pipe itself, but theonauth script is a cleaner method. Basically, I'd send 4 tokens to theservice: user, domain, IP, timestamp. It can handle the rest.
if you want to split user and domain apart like that, sure... my preference would be to keep them together, as one opaque item- that way if you have a hybrid mixed system of vpopmail and system accounts, the API doesn't need to change to support "no such thing as a domain"... and if you do need them separately, it's easy enough to split the one datum on the "@" character.
as for vpopmail writing the pipe directly... that was suggested for the onchange patch as well- and shot down very quickly, by myself and by tom. the argument is/was that most people understand how shell scripts work, but very few people understand named pipes- and while anybody can write a shell script, not everybody will be doing anything complex enough to need to involve pipes. some people may do things with unix sockets, TCP or UDP sockets, semaphores, mutices (plural of "mutex"), or any number of other things... running a shell script leaves people with the ability to choose their own IPC mechanism, rather than forcing them to run a named pipe watcher service. it's all about flexibility.
and then you could write a dedicated service, to run under daemontools, which would track which IP's are authorized and their timeout values, and would rebuild the smtp access control file whenever it needs to be changed... it could even run as root if needed (which it probably would, if it's going to be updating the smtp service's access control file.)It should be able to run as vpopmail, since the tcp.smtp.cdb file is ownedby vpopmail, and that's what gets used by qmail-smtpd. vchkpw runs asvpopmail, and it handles it all now, so I don't see a need for root accesshere.
not everybody runs their entire mail system as the vpopmail user (in fact i don't run ANY of it as the vpopmail user- for clients who use vchkpw to handle SMTP AUTH, i have the vchkpw binary setuid/setgid to the vpopmail user, but that's it.)
and since other programs (qmailadmin, vpopmaild, or some as-yet- unknown program in the future) might also end up calling this function, i think it's safer to not assume anything about what userid will be running the "onauth" script itself. if the script is signalling a service, obviously run the service as the userid which makes the most sense for the situation- but the "onauth" script itself needs to be executable by any userid on the system.
I'd appreciate the help on the daemon, although just giving me the sampecode of your daemon would probably be good enough. I have a very longhistory of looking at other peoples' code and taking just the parts I need for whatever I happen to be working on - it's how I learned C in the firstplace 15 years ago... :)
it's actually written in perl, believe it or not... but it should translate to C easily enough, if you're so inclined.
i can see keeping a hash in memory, the IP pointing to an expire time, and every time an IP authenticates, the expire time is replaced with "now plus 30 minutes"... it would periodically build a new list, leaving out any expired IPs, and if the new list of IPs (not their timeout values) is different from the old list, it would write out new files and call "tcprules" as needed. part of writing out new files would be writing a cache to the disk, so that if the service stops, it can read the cache back into memory and know the status of the authorized IPs.
http://qmail.jms1.net/scripts/qmail-updater.shtmlor maybe keep a directory full of "IP as the filename" empty files, with the mtime of each file holding the last time they auth'd... and a reaper process would periodically delete any files which haven't been touched in more than 20 minutes (or whatever timeout you want to use)... and a third script would be called whenever an IP which didn't already exist is added, or whenever the reaper deletes something, and that third script would rebuild the cdb files... this is basically how my greylisting program keeps track of things, although it uses both the "atime" and "mtime" timestamps (to hold the "first" and "most recent" time each IP appeared.)
http://qmail.jms1.net/scripts/jgreylist.shtmlnow i'm really interested in seeing where you take this... again, feel free to bounce questions or ideas off of me.
---------------------------------------------------------------- | John M. Simpson --- KG4ZOW --- Programmer At Large | | http://www.jms1.net/ <[EMAIL PROTECTED]> | ---------------------------------------------------------------- | http://video.google.com/videoplay?docid=-4312730277175242198 | ----------------------------------------------------------------
PGP.sig
Description: This is a digitally signed message part