Table of Contents ----------------- 1. Introduction 2. Release notes 3. Project status 4. License and source code 5. Dependencies 6. libaprutil versions 7. Python versions 8. Limitations and known bugs 9. Examples Introduction ------------ python-aprmd5 is a Python extension written in C that wraps the MD5 routines of the Apache Portable Runtime (APR) Utility Library (libaprutil) and exposes them to the Python interpreter as the module aprmd5. The main purpose of writing python-aprmd5 in the first place has been to expose the function apr_md5_encode(), which generates salted crypt-style hashes using a version of the MD5 hash algorithm that was modified especially for the APR project. The resulting hashes always start with the prefix characters "$apr1$" in order to distinguish them from the result of various other crypt() variants, which use other prefixes. For instance, for input "foo" and salt "mYJd83wW", apr_md5_encode() produces the following hash: $apr1$mYJd83wW$IO.6aK3G0d4mHxcImhPX50 Hashes like this are typically generated by the command line utility htpasswd, which is part of the Apache HTTP server project. The hashes encrypt user passwords that are used by the Apache HTTP server for basic user authentication. For completeness sake, python-aprmd5 exposes not only apr_md5_encode() but most of the other functions of libaprutil's MD5 routines as well. Where those functions are concerned with the original, unmodified MD5 algorithm, this is mostly a duplication of effort as that algorithm can be easily obtained through the Python Standard Library module "hashlib". In fact I advise against using python-aprmd5 if you are interested in the original MD5 algorithm only. Release notes ------------- This is python-aprmd5 0.2. Changes in this release: - [feature] replace wrappers related to original MD5 by md5 object [fixes #70] - [bugfix] fixed a few incompatibilities with Python 2.6 and earlier For more details see the ChangeLog document. Project status -------------- As of version 0.2, I consider python-aprmd5 to be feature complete. Unless a change in libaprutil breaks python-aprmd5, it is therefore rather unlikely that there will ever be a version 0.3. Maintenance releases 0.2.x will occur only if bugs are detected, or if I can be motivated to fix the crappy build process. License and source code ----------------------- python-aprmd5 is licensed under the GNU General Public License (GPLv3). You should have received a copy of the license along with the python-aprmd5 module distribution (see the file COPYING inside the distribution). If not, see . The source code for python-aprmd5 can be downloaded from its website http://www.herzbube.ch/python-aprmd5/. The source files are packaged into a tar ball using the Distutils Python module. Alternatively you may also get the source code (including project files to hack python-aprmd5 in Eclipse) from this git respository: http://herzbube.ch/git/python-aprmd5/ Dependencies ------------ Obviously, python-aprmd5 depends on the presence of libaprutil. At compile time, both the headers and the library file must be present. At runtime, the library file is sufficient. libaprutil versions ------------------- No formal tests for compatibility with certain versions of libaprutil have been performed. The earliest version that I have casually used on my system at home (a Mac OS X box) is libaprutil 0.9. Another version that I have used for casual testing on a Debian virtual box is libaprutil 1.3.5. As the interface of the MD5 routines has not changed for a long time, and even across major versions of libaprutil, it is reasonable to expect that python-aprmd5 will work with pretty much all versions of libaprutil. See the INSTALL document for details on how to build python-aprmd5 against different versions of libaprutil. Python versions --------------- python-aprmd5 implements both the 2.x and the 3.x versions of Python's C-API, so in theory it should work with all versions of Python 2.x and 3.x. In practice, no formal tests have been performed to verify this statement. The earliest version of Python that I have used to build python-aprmd5 with has been 2.5.1, and the latest version has been 3.1.1 (both on Mac OS X 10.5). Limitations and known bugs -------------------------- On some platforms, password_validate() incorrectly returns True if it is fed with an empty hash, regardless of the password that is being validated. This is probably a bug in the system's crypt() function, exposed by the way how libaprutil calls that function. I have found this behaviour on Debian lenny, the issue is reported here: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=550360. Examples -------- Example 1: Usage of apr_md5_encode(). from aprmd5 import md5_encode password = "foo" salt = "mYJd83wW" # result will be "$apr1$mYJd83wW$IO.6aK3G0d4mHxcImhPX50" result = md5_encode(password, salt) Example 2: Usage of password_validate(). from aprmd5 import password_validate password = "foo" hash = "$apr1$mYJd83wW$IO.6aK3G0d4mHxcImhPX50" # result will be True result = password_validate(password, hash) Example 3: Usage of regular MD5 algorithm. The example uses the b"" notation from Python 3. from aprmd5 import md5 m1 = md5(b"foo") m2 = md5() m2.update(b"foo") # result1 and result2 will both be "acbd18db4cc2f85cedef654fccc4a4d8" result1 = m1.hexdigest() result2 = m2.hexdigest()