Lucas Nussbaum's mod_auth_crypt migration script

Download, Add a comment, Back to main page
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-

# auth_crypt_conv.py - converts an XDB file from mod_auth_plain to mod_auth_crypt
# Copyright (C) 2003 Lucas Nussbaum <lnu@gnu.org>
# See http://www.lucas-nussbaum.net/jabauthcrypt.php for newest version
#
# 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

# This script converts a XDB file (fed via stdin) to remove :
# - the zerok node
# - the password node
# and to add
# - a crypt node
# To use it :
#   * make a backup of your files
#   * mkdir tmp
#   * for i in *.xml; do echo $i; /path/to/auth_crypt_conv.py < $i > tmp/$i ; done
#   * check the output, of course.
# After that, you can disable mod_auth_plain and mod_auth_digest from your jabber.xml

# Be sure to read http://jabberd.jabberstudio.org/1.4/doc/adminguide#security
# thoroughly. Typically, you DON'T want to use mod_auth_crypt, especially not
# without additionally enforcing SSL.

import sys
from xml.dom.minidom import parse, getDOMImplementation
import sha
import base64

# parse from stdin
dom = parse(sys.stdin)

xdb = dom.getElementsByTagName("xdb")[0]

# find the xdb.query[@xdbns="jabber:iq:register"].password node and delete it (if it exists)
for node in xdb.getElementsByTagName("query"):
   if node.getAttribute("xdbns") == "jabber:iq:register":
      if len(node.getElementsByTagName("password")) != 0:
         node.removeChild(xdb.getElementsByTagName("password")[0])
         break
   
# remove zerok node if it exists
if len(xdb.getElementsByTagName("zerok")) != 0:
   xdb.removeChild(xdb.getElementsByTagName("zerok")[0])

# remove password node if it exists, save the password
if len(xdb.getElementsByTagName("password")) != 0:
   password = xdb.getElementsByTagName("password")[0].firstChild.nodeValue
   xdb.removeChild(xdb.getElementsByTagName("password")[0])
   if len(xdb.getElementsByTagName("crypt"))==0:
      # no crypted password yet. We build a crypt node and add it.
      text = "{SHA}"+base64.encodestring(sha.new(password).digest())[:-1]
      # note: the funny stuff at the end of the preceding line isn't a smiley
      textnode = dom.createTextNode(text)
      cryptnode = dom.createElement("crypt")
      cryptnode.appendChild(textnode)
      xmlns = dom.createAttribute("xmlns")
      cryptnode.setAttribute("xmlns","jabber:iq:auth:crypt")
      cryptnode.setAttribute("xdbns","jabber:iq:auth:crypt")
      xdb.appendChild(cryptnode)

# output the document to stdout
# an xml header is added to the output file. jabberd doesn't seem to care about it.
print dom.toxml("utf-8")
# clean up, because the doc says we should
dom.unlink()