[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Problem sasl2-sql.



On Sun, Jun 03, 2007 at 01:37:57AM +0300, Semih Gokalp wrote:
> Thanks Roberto for reply.
> 
> >Is encrypt a MySQL data type?
> 
> I am sorry.its my fault.Encrypt not mysql data type.Password field type
> varchar but password field type function is encrypt and postfix use TLS.
> 
> for example: Assuming that password is abc,it has been stored like
> oZBhlIb1J0iH. in password field.If i dont use encrypt function,"abc" store
> like "abc" in password field..
> 
OK.  So you mean that the password is being encrypted with something
like a call to crypt(1)?

> if i dont use encrypt function for password field type(varchar),sasl2
> authentication ok but courier has configured like below;
> 
> MYSQL_CRYPT_PWFIELD    password
> 
> so couirer doesnt work without encrypt function to password field type.
> 
> if i change courier configuration like below:
> 
> MYSQL_CLEAR_PWFIELD     password
> 
> everything is ok but i dont want to directly see password on password field.
> 
Right.  I know what you mean.  I use the PGSQL_CRYPT_PWFIELD on my
server (in /etc/courier/authpgsqlrc).  However, in my case, I have the
passwords stored in the database in md5 format.  I use the attached
python script to generate those passwords.  I found it on the Internet
somewhere and I have been able to use it successfully without any
issues.

Regards,

-Roberto

-- 
Roberto C. Sánchez
http://people.connexer.com/~roberto
http://www.connexer.com
#!/usr/bin/env python
"""Reimplementation of MD5-based crypt(), based on glibc 2.2.4."""
import md5
import string

def md5crypt(key, salt):
    assert salt.startswith('$1$')
    assert salt.endswith('$')
    salt = salt[3:-1]
    assert len(salt) <= 8

    hash = md5.new()
    hash.update(key)
    hash.update('$1$')
    hash.update(salt)

    second_hash = md5.new()
    second_hash.update(key)
    second_hash.update(salt)
    second_hash.update(key)
    second_hash = second_hash.digest()
    q, r = divmod(len(key), len(second_hash))
    second_hash = second_hash*q + second_hash[:r]
    assert len(second_hash) == len(key)
    hash.update(second_hash)
    del second_hash, q, r

    # Comment in glibc 2.2.4 source:

    # "The original implementation now does something weird: for every 1
    # bit in the key the first 0 is added to the buffer, for every 0
    # bit the first character of the key.  This does not seem to be
    # what was intended but we have to follow this to be compatible."

    # But this is *not* what their code does.  The code alternates
    # between '\0' and key[0] based *not* on the bits of the key,
    # but on the bits of the representation of the *length* of the
    # key.  Weirdness on top of weirdness.

    i = len(key)
    while i > 0:
        if i & 1:
            hash.update('\0')
        else:
            hash.update(key[0])
        i >>= 1

    hash = hash.digest()

    for i in xrange(1000):
        nth_hash = md5.new()
        if i % 2:
            nth_hash.update(key)
        else:
            nth_hash.update(hash)
        if i % 3:
            nth_hash.update(salt)
        if i % 7:
            nth_hash.update(key)
        if i % 2:
            nth_hash.update(hash)
        else:
            nth_hash.update(key)
        hash = nth_hash.digest()

    # a different base64 than the MIME one
    base64 = './0123456789' \
        'ABCDEFGHIJKLMNOPQRSTUVWXYZ' \
        'abcdefghijklmnopqrstuvwxyz'
    def b64_three_char(char2, char1, char0, n):
        byte2, byte1, byte0 = map(ord, [char2, char1, char0])
        w = (byte2 << 16) | (byte1 << 8) | byte0
        s = []
        for _ in range(n):
            s.append(base64[w & 0x3f])
            w >>= 6
        return s

    result = ['$1$', salt, '$']
    result.extend(b64_three_char(hash[0], hash[6], hash[12], 4))
    result.extend(b64_three_char(hash[1], hash[7], hash[13], 4))
    result.extend(b64_three_char(hash[2], hash[8], hash[14], 4))
    result.extend(b64_three_char(hash[3], hash[9], hash[15], 4))
    result.extend(b64_three_char(hash[4], hash[10], hash[5], 4))
    result.extend(b64_three_char('\0', '\0', hash[11], 2))

    return ''.join(result)

def _test():
    assert md5crypt('bob', '$1$TR8v8QBY$') == \
        '$1$TR8v8QBY$/RuCh8wlK.aHczufkXFbZ/'

if __name__ == '__main__':
    _test()
    print md5crypt('secret', '$1$abcdefgh$')

Attachment: signature.asc
Description: Digital signature


Reply to: