Extraction de la requête SQL. Doc' d'installation et de test.
[progfou.git] / ejabberd / auth-mysql.py
1 #!/usr/bin/env python
2 # -*- coding: UTF-8 -*-
3 # Depends: python-mysqldb
4 # install -o root -g ejabberd -m 0750 -c auth-mysql.py /etc/ejabberd/
5 # install -o ejabberd -g adm -m 0640 -c /dev/null /var/log/ejabberd/auth-mysql.log
6 # Test: printf '\000\031isuser:moussa.nombre:test' | ./auth-mysql.py | hd
7
8 import sys
9 import traceback
10 import struct
11 import time
12 import MySQLdb
13 import crypt
14
15 # TODO: transformer toute la partie gestion de BdD en une classe
16 # TODO: connexion persistente et gérer les coupures de service MySQL
17
18 _host = 'nss'
19 _user = 'jabber'
20 _passwd = 'password'
21 _db = 'mail'
22 _timeout = 2
23 _query = "SELECT * FROM auforg_virtual WHERE source=%s AND LENGTH(password)>1"
24
25 def find_user(user, host):
26 global _host, _user, _passwd, _db
27 db = MySQLdb.connect(host=_host, user=_user, passwd=_passwd,
28 db=_db, connect_timeout=_timeout)
29 cur = db.cursor(MySQLdb.cursors.DictCursor)
30 nrows = cur.execute(_query, ('%s@%s' % (user,host), ))
31 del cur, db
32 return (nrows > 0)
33
34 def authenticate_user(user, host, password):
35 global _host, _user, _passwd, _db
36 db = MySQLdb.connect(host=_host, user=_user, passwd=_passwd,
37 db=_db, connect_timeout=_timeout)
38 cur = db.cursor(MySQLdb.cursors.DictCursor)
39 nrows = cur.execute(_query, ('%s@%s' % (user,host), ))
40 users = cur.fetchall()
41 del cur, db
42 if nrows < 1:
43 return False
44 for user in users:
45 if crypt.crypt(password, user['password']) == user['password']:
46 return True
47 return False
48
49 def main():
50 log_file = open('/var/log/ejabberd/auth-mysql.log', 'a')
51 while True:
52 try:
53 nread = sys.stdin.read(2)
54 if len(nread) == 0:
55 time.sleep(0.25)
56 continue
57 now = time.strftime('%Y/%m/%d %H:%M:%S', time.localtime())
58 if len(nread) < 2:
59 log_file.write('%s bytes_read=%d\n' % (now, len(nread)))
60 log_file.flush()
61 continue
62 size = struct.unpack('>h', nread)[0]
63 data = sys.stdin.read(size)
64 (operation, data) = data.split(':', 1)
65 if operation == 'auth':
66 (user, host, password) = data.split(':', 2)
67 log_file.write('%s operation=%s user=%s host=%s\n'
68 % (now, operation, user, host))
69 log_file.flush()
70 result = authenticate_user(user, host, password)
71 elif operation == 'isuser':
72 (user, host) = data.split(':', 1)
73 log_file.write('%s operation=%s user=%s host=%s\n'
74 % (now, operation, user, host))
75 log_file.flush()
76 result = find_user(user, host)
77 elif operation == 'setpass':
78 (user, host, password) = data.split(':', 2)
79 log_file.write('%s operation=%s user=%s host=%s\n'
80 % (now, operation, user, host))
81 log_file.flush()
82 #result = set_user_password(user, host, password)
83 result = False
84 else:
85 result = False
86 log_file.write('%s => result=%s\n' % (now, result))
87 log_file.flush()
88 sys.stdout.write(struct.pack('>hh', 2, result and 1 or 0))
89 sys.stdout.flush()
90 except:
91 traceback.print_exc(file=log_file)
92 #sys.exit()
93
94 if __name__ == '__main__':
95 main()