【问题标题】:Python hashlib.md5 and ejabberdPython hashlib.md5 和 ejabberd
【发布时间】:2011-02-21 15:34:44
【问题描述】:

我在 ejabberd 2.1.6 中使用 python 脚本作为外部身份验证选项。

我想开始加密在 auth 验证中遇到的明文密码,这样它们就不会以纯文本形式存储在后端数据库中。当我将以下代码添加到我的 python 脚本并重新启动 ejabberd 时,它会挂起:

import hashlib

clear = "barfoo"
salt = "foobar"
hash = hashlib.md5( salt + clear ).hexdigest()

hashlib 是否需要特定的权限才能运行?

当我以普通用户 (ejabberd) 身份运行它时,它可以正常工作。当 python 脚本在 ejabberd 的外部身份验证中运行时,它会挂起。

我试图让它将“哈希”写入文件,但它永远不会到达那里......如果我以“ejabberd”用户身份运行它,它会很好地写入文件。

我试图找到有关在 ubuntu 上使用此库的限制信息,但没有成功。有什么想法吗?

-sd

** 22.02.2011:这是改编自 https://git.process-one.net/ejabberd/mainline/blobs/raw/2.1.x/doc/dev.html#htoc8 的完整脚本:

#!/usr/bin/python

import sys
from struct import *

import hashlib  

def from_ejabberd():
    input_length = sys.stdin.read(2)
    (size,) = unpack('>h', input_length)
    return sys.stdin.read(size).split(':')

def to_ejabberd(bool):
    answer = 0
    if bool:
        answer = 1
    token = pack('>hh', 2, answer)
    sys.stdout.write(token)
    sys.stdout.flush()

def auth(username, server, password):
    clear = "barfoo"
    salt = "foobar"
    hash = hashlib.md5( salt + clear ).hexdigest()
    if (password == hash): return True
    else: return False

def isuser(username, server):
    return True

def setpass(username, server, password):
    return True

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)

【问题讨论】:

  • 一个问题是上面粘贴的脚本包含一个错字:应该是if (password == hash): return True,因为条件中不允许赋值。
  • 如果我因为失踪等了 3 个月 = 我会发疯的。会检查它...!
  • 整个条件可以写成return password == hash

标签: python ejabberd


【解决方案1】:

我一直在处理同样的问题。我无法真正找到 _hashlib 中的 openssl binings 问题。无论问题是什么,我都必须修补 python 分发源。并不是真正可行的解决方案。所以我最终为在这种情况下不会阻塞的加密函数使用了 pycrypto 包装器。

点安装pycrypto 从 Crypto.Hash 导入 MD5 m = MD5.new() m.update("%s%s" % (salt ,clear)) h.hexdigest()

【讨论】:

    【解决方案2】:

    我查看了 hashlib source,虽然它似乎不需要太多,但它确实将 .so 文件作为模块导入,其中一个命中 openssl。这一切看起来都很安全,但是如果 ejabberd 试图保护自己免受对 3rd 方代码的调用(或者如果你有 SELinux 或其他类似的东西正在运行),那么事情可能会变得很奇怪。我在 REPL 中得到了这个:

    >>> import _md5
    >>> _md5.__file__
    '/usr/lib/python2.7/lib-dynload/_md5module.so'
    

    在你的盒子上试试这个,然后试着放

    _md5 = imp.load_dynamic('_md5', '/usr/lib/python2.7/lib-dynload/_md5module.so')
    

    或者只是

    import _md5
    

    (将适当的路径更新为您的)在违规行之前的代码中以及之后的一些跟踪语句。尝试使用 _hashlib 而不是 _md5 进行相同的操作(hashlib 默认为包装 openssl 的 _hashlib,但如果它没有加载或没有所需的哈希,它会回退到 _md5、_sha 等)。如果不是导入失败/挂起,那么您可以尝试调用 _md5.new(salt + clear) 和 _hashlib.openssl_md5(salt + clear) 并查看它是否是其中之一。

    如果是导入有问题,那么可能已经解决了类似的问题here 我不知道 ejabberd,所以很遗憾,我无法将他们的解决方案与您的问题联系起来。

    不过,我不得不说:在我知道的所有 python 实现中,= 而不是 == 在条件中会引发 SyntaxError,就是这样 - 程序甚至永远不会进入主 while 循环。

    【讨论】:

    • _hashlib 呢?此外,它是否在 ejabberd 或您的常规 python 解释器中失败?
    • 在常规 python 解释器中失败。今晚我会检查 _hashlib。 import hashlib 工作正常...
    【解决方案3】:

    hashlib 不需要任何特殊的东西。挂起是什么意思?它挂在哪里?使用 pdb.set_trace() 遍历代码或使用 'strace' 或 'ltrace' 调查 API 调用。

    【讨论】:

    • 谢谢安德烈亚斯。我会看一下 pdb.set_trace() .. 也许它可以将所有内容输出到文件中给我更多提示。
    • 在阅读了更多关于 pdb 的信息后,我意识到这无济于事。当我以用户身份运行 python 脚本时,它没有问题。只有从 ejabberd 运行时才会出现此问题。
    • 由于 ejabberd 输出的格式不符合您的要求,您的 read 语句更有可能挂起。我建议使用非阻塞 IO。
    【解决方案4】:

    尝试使用logging模块,它可以帮助您查看输入和输出数据,还可以检查脚本权限,让ejabberd用户执行,或者调试只需设置chmod 777 external.py

    【讨论】:

    • 因此,尽管这是一个很好的反馈,但对于确定问题的根本原因并没有太大帮助。我怀疑问题是因为 = 而不是 ==
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-07
    • 2011-07-05
    • 2014-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多