[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[pysieved] Dovecot auth/userdb files for pysieved
- From: Koen Vermeer <koen at vermeer dot tv>
- Subject: [pysieved] Dovecot auth/userdb files for pysieved
- Date: Sun, 22 Apr 2007 16:06:07 +0200
Hi,
I managed to get both the auth and the userdb working with the dovecot
sockets. There is one issue with the userdb, though: To retrieve the
uid, gid and home, I have to pass the password to dovecot again. So, I
needed to change the interface to the userdb class. It's trivial to
modify the other userdb files to ignore this, but I haven't done that
yet.
Anyway, it seems to work on my system, but may simply delete all files
on yours. Don't let that keep you from testing it! The patch should be
applied to the current (3 days old) pysieved snapshot.
Koen
diff -urN -x '*.pyc' pysieved.git/auth/dovecot.py pysieved.new/auth/dovecot.py
--- pysieved.git/auth/dovecot.py 1970-01-01 01:00:00.000000000 +0100
+++ pysieved.new/auth/dovecot.py 2007-04-22 15:57:43.000000000 +0200
@@ -0,0 +1,60 @@
+#! /usr/bin/python
+
+## dovecot - Dovecot socket authentication for pysieved
+## Copyright (C) 2007 Neale Pickett, Koen Vermeer
+## Based on auth.py, part of pysieved, copyright Neale Pickett
+
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or (at
+## your option) any later version.
+
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+## USA
+
+import __init__
+import socket
+import base64
+import os
+
+class new(__init__.Auth):
+ def init(self, config):
+ self.mux = config.get('Dovecot', 'authsocket', '/var/run/saslauthd/mux')
+ self.service = config.get('Dovecot', 'service', 'pysieved')
+ self.pid = os.getpid()
+
+ def sasl(self, username, password):
+ s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ s.connect(self.mux)
+ handshake_string = s.recv(8192)
+ s.sendall('VERSION\t1\t0\nCPID\t%d\n' % self.pid)
+ auth_string = 'AUTH\t1\tPLAIN\tservice=%s\tresp=%s' % (self.service, base64.b64encode(username + '\0' + username + '\0' + password))
+ s.sendall(auth_string + '\n')
+ r = s.recv(8192)
+ s.close()
+ return r
+
+ def auth(self, username, passwd):
+ ret = self.sasl(username, passwd)
+ self.log(2, 'Auth returns %r' % ret)
+ if ret.startswith('OK'):
+ return True
+ return False
+
+
+if __name__ == '__main__':
+ import sys
+
+ class C:
+ def get(self, section, key, default):
+ return default
+
+ n = new(C())
+ print n.auth(*sys.argv[1:])
diff -urN -x '*.pyc' pysieved.git/managesieve.py pysieved.new/managesieve.py
--- pysieved.git/managesieve.py 2007-04-19 07:48:32.000000000 +0200
+++ pysieved.new/managesieve.py 2007-04-22 15:35:42.000000000 +0200
@@ -233,7 +233,7 @@
_, user, passwd = args[0].decode('base64').split('\0', 2)
if not self.authenticate(user, passwd):
return self.no(reason='Bad username or password')
- home = self.get_homedir(user)
+ home = self.get_homedir(user, passwd)
self.storage = self.new_storage(home)
return self.ok()
diff -urN -x '*.pyc' pysieved.git/pysieved.ini pysieved.new/pysieved.ini
--- pysieved.git/pysieved.ini 2007-04-19 07:48:32.000000000 +0200
+++ pysieved.new/pysieved.ini 2007-04-22 15:56:49.000000000 +0200
@@ -1,9 +1,9 @@
[main]
# Authentication back-end to use
-auth = SASL
+auth = Dovecot
# User DB back-end to use
-userdb = passwd
+userdb = Dovecot
# Storage back-end to use
storage = Dovecot
@@ -59,6 +59,9 @@
# Where in user directory to store scripts
scripts = .pysieved
+service = pysieved
+authsocket = /var/spool/postfix/private/auth
+userdbsocket = /var/run/dovecot/auth-master
[Dovecot Single]
# What should your single script be called?
diff -urN -x '*.pyc' pysieved.git/pysieved.py pysieved.new/pysieved.py
--- pysieved.git/pysieved.py 2007-04-19 07:48:32.000000000 +0200
+++ pysieved.new/pysieved.py 2007-04-22 15:36:27.000000000 +0200
@@ -75,8 +75,8 @@
def authenticate(self, username, passwd):
return authenticate.auth(username, passwd)
- def get_homedir(self, username):
- return homedir.lookup(username)
+ def get_homedir(self, username, passwd):
+ return homedir.lookup(username, passwd)
def new_storage(self, homedir):
return store.create(homedir)
diff -urN -x '*.pyc' pysieved.git/userdb/dovecot.py pysieved.new/userdb/dovecot.py
--- pysieved.git/userdb/dovecot.py 1970-01-01 01:00:00.000000000 +0100
+++ pysieved.new/userdb/dovecot.py 2007-04-22 15:58:25.000000000 +0200
@@ -0,0 +1,71 @@
+#! /usr/bin/python
+
+## dovecot - Dovecot userdb plugin for pysieved
+## Copyright (C) 2007 Neale Pickett, Koen Vermeer
+## Based on auth.py, part of pysieved, copyright Neale Pickett
+
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or (at
+## your option) any later version.
+
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## General Public License for more details.
+
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+## USA
+
+import __init__
+import socket
+import base64
+import os
+
+class new(__init__.UserDB):
+ def init(self, config):
+ self.mux = config.get('Dovecot', 'userdbsocket', '/var/run/dovecot/auth-master')
+ self.service = config.get('Dovecot', 'service', 'pysieved')
+
+ def sasl(self, username, password):
+ s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ s.connect(self.mux)
+ handshake_string = s.recv(8192)
+ s.sendall('VERSION\t1\t0\n')
+ user_string = 'USER\t1\t%s\tservice=%s\tresp=%s' % (username, self.service, base64.b64encode(username + '\0' + username + '\0' + password))
+ s.sendall(user_string + '\n')
+ user_reply = s.recv(8192)
+ s.close()
+ if user_reply.startswith('USER\t'):
+ uid = user_reply[user_reply.find('\tuid=')+5:]
+ uid = uid[:uid.find('\t')]
+ gid = user_reply[user_reply.find('\tgid=')+5:]
+ gid = gid[:gid.find('\t')]
+ home = user_reply[user_reply.find('\thome=')+6:]
+ home = home[:home.find('\t')]
+# print 'uid: %s gid: %s home: %s' % (uid,gid,user_reply)
+ return (home, int(uid), int(gid))
+ else:
+ return (None, -1, -1)
+
+ def lookup(self, username, password):
+ (home, uid, gid) = self.sasl(username, password)
+ self.log(2, 'Home: %s, uid: %d, gid: %d' % (home,uid,gid))
+ if gid >= 0:
+ os.setgid(gid)
+ if uid >= 0:
+ os.setuid(uid)
+ return home
+
+
+if __name__ == '__main__':
+ import sys
+
+ class C:
+ def get(self, section, key, default):
+ return default
+
+ n = new(C())
+ print n.auth(*sys.argv[1:])
diff -urN -x '*.pyc' pysieved.git/userdb/__init__.py pysieved.new/userdb/__init__.py
--- pysieved.git/userdb/__init__.py 2007-04-19 07:48:32.000000000 +0200
+++ pysieved.new/userdb/__init__.py 2007-04-22 15:42:42.000000000 +0200
@@ -25,7 +25,7 @@
def log(self, lvl, msg):
if lvl <= self.debug:
- print 'AUTH: %s' % msg
+ print 'USERDB: %s' % msg
def init(self, config):
# Override this