← Back to blog
CodeElinoLinuxPython

ejabber users from postfixadmin (python,mysql,md5crypt)

10 January 2014

So Im running my emails with postfix and have postfix admin to manager my users and domains. But now it should be nice to have i jabber server running and to have the same user and password for both email and jabber.

Ejabber support custom auth plugins and with some python i now have a working plugin.

 

First install python packages

yum install MySQL-python
yum install python-passlib

 

Add this script to you ejabber folder

#!/usr/bin/python
import os 
import datetime
import sys, logging, struct, hashlib, MySQLdb
from passlib.hash import *
from passlib.hash import md5_crypt
from struct import *
########################################################################
#DB Settings
#Just put your settings here.
########################################################################
db_name="mail"
db_user="root"
db_pass="password"
db_host="localhost"
db_table="mailbox"
db_username_field="username"
db_password_field="password"
try:
 database=MySQLdb.connect(db_host, db_user, db_pass, db_name)
except:
 logging.debug("Unable to initialize database, check settings!")
dbcur=database.cursor()
def log(string):
 with open('/var/log/ejabberd/sso-auth.log', 'a') as f:
 f.write(str(datetime.datetime.now()) + ': ' + string + '\n')
def from_ejabberd():
 input_length = sys.stdin.read(2)
 (size,) = unpack('>h', input_length)
 input = sys.stdin.read(size)
 return input.split(':')
def to_ejabberd(bool):
 answer = 0
 if bool:
 answer = 1
 token = pack('>hh', 2, answer)
 log('writing token ' + str(token) + ' to stdout')
 sys.stdout.write(token)
 sys.stdout.flush()
def auth(username, server, password):
 log('doing auth:' + username + ':' + server + ':' + "********")
 dbcur.execute("SELECT %s,%s FROM %s WHERE %s ='%s@%s'"%(db_username_field,db_password_field , db_table, db_username_field, username,server))
 data=dbcur.fetchone()
 out=False #defaut to O preventing mistake
 if data==None:
 out=False
 #logging.debug("Wrong username: %s"%(in_user))
 if username+"@"+server==data[0]:
 if md5_crypt.verify(password, data[1]):
 log("Inlogged")
 out=True
 else:
 log("Wrong password for user: %s"%(in_user))
 out=False
 else:
 log("Sending false from auth")
 out=False
 return out
def isuser(username, server):
 dbcur.execute("SELECT %s,%s FROM %s WHERE %s ='%s@%s'"%(db_username_field,db_password_field , db_table, db_username_field, username,server))
 data=dbcur.fetchone() 
 out=False #defaut to O preventing mistake
 if data==None:
 out=False
 log("Wrong username: %s"%(in_user))
 if username+"@"+server==data[0]:
 log("Is user")
 out=True
 return out
def setpass(username, server, password):
 return False
while True:
 data = from_ejabberd()
 success = False
 if data[0] == "auth":
 success = auth(data[1], data[2], data[3])
 elif data[0] == "isuser":
 success = isuser(data[1], data[2])
 elif data[0] == "setpass":
 success = setpass(data[1], data[2], data[3])
 to_ejabberd(success)

 

Make your script user ejabberd user and group and execute

chown ejabberd:ejabberd /etc/ejabberd/auth/check_mysql_python.py
chmod 775 /etc/ejabberd/auth/check_mysql_python.py

And at last the following to ejbber to use the script

{auth_method, external}.
{extauth_program, "/etc/ejabberd/auth/check_mysql_python.py"}.

Links and readmore

http://pythonhosted.org/passlib/lib/passlib.hash.md5_crypt.html

http://stackoverflow.com/questions/4070601/use-python-to-create-compatible-ldap-password-md5crypt-on-windows

http://www.ejabberd.im/check_mysql_python

http://www.ejabberd.im/extauth