summaryrefslogtreecommitdiffstats
path: root/py-bin
diff options
context:
space:
mode:
authormh@immerda.ch <mh@immerda.ch>2012-05-22 22:44:08 +0200
committeralice <alice@immerda.ch>2012-10-19 15:15:57 +0200
commitffee421f411898fdacd7102313f236a8ab75b49f (patch)
treea90941f4f64e97e8cb0f1828e9b2c31807855c05 /py-bin
parenta10f07258b1620049cc3ae62193c84062c20b3cc (diff)
add an external auth script
Diffstat (limited to 'py-bin')
-rw-r--r--py-bin/ejabber_auth.py133
1 files changed, 133 insertions, 0 deletions
diff --git a/py-bin/ejabber_auth.py b/py-bin/ejabber_auth.py
new file mode 100644
index 0000000..8acb10d
--- /dev/null
+++ b/py-bin/ejabber_auth.py
@@ -0,0 +1,133 @@
+#!/usr/bin/python
+
+# this is an extauth script for use with ejabberd.
+# it uses a binary protocol for communicating via stdin/stdout
+# see ejabberd.jabber.ru/extauth for more examples
+# this script uses the iwebjabber-database from for authentification
+
+
+import sys, logging, os
+import config
+sys.stderr = open(config.authlog_path, 'a')
+from struct import *
+from jabberman import JabberDB
+
+class EjabberdInputError(Exception):
+ def __init__(self, value):
+ self.value = value
+ def __str__(self):
+ return repr(self.value)
+
+class EjabberAuth:
+ """
+ ejabberd starts one instance for each domain it's serving
+ """
+ def __init__(self):
+ self.jadb = JabberDB()
+ logging.basicConfig(level=logging.INFO,
+ format='%(asctime)s %(levelname)s %(message)s',
+ filename=config.authlog_path,
+ filemode='a')
+ logging.info('extauth script started, waiting for ejabberd requests')
+
+ def ejabberd_in(self):
+ """
+ Read from stdin, this is what ejabberd sends us
+ """
+ logging.debug("trying to read 2 bytes from ejabberd:")
+ try:
+ input_length = sys.stdin.read(2)
+ except IOError:
+ logging.debug("ioerror")
+ if len(input_length) is not 2:
+ logging.debug("ejabberd sent us wrong things!")
+ raise EjabberdInputError('Wrong input from ejabberd!')
+ logging.debug('got 2 bytes via stdin')
+
+ (size,) = unpack('>h', input_length)
+ return sys.stdin.read(size).split(':')
+
+ def genanswer(self, bool):
+ answer = 0
+ if bool:
+ answer = 1
+ return pack('>hh', 2, answer)
+
+ def ejabberd_out(self, bool):
+ logging.debug("Ejabberd gets: %s" % bool)
+ token = genanswer(bool)
+ logging.debug("sent bytes: %#x %#x %#x %#x" % (ord(token[0]), ord(token[1]), ord(token[2]), ord(token[3])))
+ sys.stdout.write(token)
+ sys.stdout.flush()
+
+ def log_success(self, method, jid, success):
+ if success:
+ logging.debug("%s successful for %s" % (method, jid))
+ else:
+ logging.debug("%s unsuccessful for %s" % (method, jid))
+
+ def validate_jid(self, jid, password):
+ logging.debug("%s wants authentication ..." % (jid))
+ return self.jadb.validate_jid(jid, password)
+
+ def is_jid(self, jid):
+ logging.debug("do we know %s?" % (jid))
+ return self.jadb.is_jid(jid)
+
+ def update_jid(self, jid, new_password):
+ logging.debug("update_jid for %s" % (jid))
+
+ if self.jabdb.update_jid(jid, new_password):
+ logging.debug("password change for %s successful" % (jid))
+ return True
+ else:
+ logging.debug("password change for %s not successful" % (jid))
+ return False
+
+ def run(self):
+ """
+ Loop the auth script forever
+ """
+ while True:
+ logging.debug("start of infinite loop")
+
+ try:
+ data = self.ejabberd_in()
+ except EjabberdInputError, inst:
+ logging.info("Exception occured: %s", inst)
+ break
+
+ logging.debug('Method: %s' % data[0])
+ success = False
+
+ jid = "%s@%s" % (data[1], data[2])
+
+ if data[0] == "auth":
+ success = self.validate_jid(jid, data[3])
+ self.ejabberd_out(success)
+ self.log_success("auth", jid, success)
+
+ elif data[0] == "isuser":
+ success = self.is_jid(jid)
+ self.ejabberd_out(success)
+ self.log_success("is_jid", jid, success)
+
+ elif data[0] == "setpass":
+ success = self.update_jid(jid, data[3])
+ self.ejabberd_out(success)
+ self.log_success("update_jid", jid, success)
+
+ logging.debug("end of infinite loop")
+
+ logging.info('extauth script terminating')
+
+
+auth = EjabberAuth()
+auth.run()
+
+
+
+
+
+
+