Ajout d'une authentification MySQL pour ejabberd.
authorProgfou <jean-christophe.andre@auf.org>
Wed, 25 Mar 2009 08:37:37 +0000 (15:37 +0700)
committerProgfou <jean-christophe.andre@auf.org>
Wed, 25 Mar 2009 08:37:37 +0000 (15:37 +0700)
ejabberd/auth-mysql.py [new file with mode: 0755]

diff --git a/ejabberd/auth-mysql.py b/ejabberd/auth-mysql.py
new file mode 100755 (executable)
index 0000000..277425c
--- /dev/null
@@ -0,0 +1,92 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+# Depends: python-mysqldb
+import sys
+import traceback
+import struct
+import time
+import MySQLdb
+import crypt
+
+# TODO: transformer toute la partie gestion de BdD en une classe
+# TODO: connexion persistente et gérer les coupures de service MySQL
+
+_host = 'nss'
+_user = 'jabber'
+_passwd = 'password'
+_db = 'auth'
+
+def find_user(user):
+    global _host, _user, _passwd, _db
+    db = MySQLdb.connect(host=_host, user=_user, passwd=_passwd,
+                         db=_db, connect_timeout=1)
+    cur = db.cursor(MySQLdb.cursors.DictCursor)
+    nrows = cur.execute(
+        """SELECT uid FROM users WHERE source=0 AND username=%s""", (user, ))
+    del cur, db
+    return (nrows > 0)
+
+def authenticate_user(user, password):
+    global _host, _user, _passwd, _db
+    db = MySQLdb.connect(host=_host, user=_user, passwd=_passwd,
+                         db=_db, connect_timeout=1)
+    cur = db.cursor(MySQLdb.cursors.DictCursor)
+    nrows = cur.execute(
+        """SELECT password FROM users WHERE source=0 AND username=%s"""
+        """ AND LENGTH(password)>1""", (user, ))
+    users = cur.fetchall()
+    del cur, db
+    if nrows < 1:
+        return False
+    for user in users:
+        if crypt.crypt(password, user['password']) == user['password']:
+            return True
+    return False
+
+def main():
+    log_file = open('/var/log/ejabberd/auth-mysql.log', 'a')
+    while True:
+        try:
+            nread = sys.stdin.read(2)
+            if len(nread) == 0:
+                time.sleep(0.25)
+                continue
+            now = time.strftime('%Y/%m/%d %H:%M:%S', time.localtime())
+            if len(nread) < 2:
+                log_file.write('%s bytes_read=%d\n' % (now, len(nread)))
+                log_file.flush()
+                continue
+            size = struct.unpack('>h', nread)[0]
+            data = sys.stdin.read(size)
+            (operation, data) = data.split(':', 1)
+            if operation == 'auth':
+                (user, host, password) = data.split(':', 2)
+                log_file.write('%s operation=%s user=%s host=%s\n'
+                               % (now, operation, user, host))
+                log_file.flush()
+                result = authenticate_user(user, password)
+            elif operation == 'isuser':
+                (user, host) = data.split(':', 1)
+                log_file.write('%s operation=%s user=%s host=%s\n'
+                               % (now, operation, user, host))
+                log_file.flush()
+                result = find_user(user)
+            elif operation == 'setpass':
+                (user, host, password) = data.split(':', 2)
+                log_file.write('%s operation=%s user=%s host=%s\n'
+                               % (now, operation, user, host))
+                log_file.flush()
+                #result = set_user_password(user, password)
+                result = False
+            else:
+                result = False
+            log_file.write('%s => result=%s\n' % (now, result))
+            log_file.flush()
+            sys.stdout.write(struct.pack('>hh', 2, result and 1 or 0))
+            sys.stdout.flush()
+        except:
+            traceback.print_exc(file=log_file)
+        #sys.exit()
+
+if __name__ == '__main__':
+    main()