jay*_*y_t 5 python authentication pam
我正在寻找一种让我的python程序通过pam处理身份验证的方法.我正在使用http://code.google.com/p/web2py/source/browse/gluon/contrib/pam.py这个,只要我的python程序以root身份运行就不太理想了我的看法.
如何在不需要root权限的情况下使用pam进行用户名/密码验证?
你不需要是root,你只需要能够阅读/etc/shadow.该文件通常shadow具有只读访问权限的组.因此,您只需添加PAM在shadow组中运行检查的用户.
groupadd <user> shadow 应该做的伎俩.
我认为该pam模块是您的最佳选择,但您不必直接将其嵌入到您的程序中.您可以编写一个绑定到localhost上的端口的简单服务,或者侦听UNIX域套接字,并为同一主机上的其他进程填充PAM请求.然后让您的web2py应用程序连接到它以进行用户/密码验证.
例如:
import asyncore
import pam
import socket
class Client(asyncore.dispatcher_with_send):
def __init__(self, sock):
asyncore.dispatcher_with_send.__init__(self, sock)
self._buf = ''
def handle_read(self):
data = self._buf + self.recv(1024)
if not data:
self.close()
return
reqs, data = data.rsplit('\r\n', 1)
self._buf = data
for req in reqs.split('\r\n'):
try:
user, passwd = req.split()
except:
self.send('bad\r\n')
else:
if pam.authenticate(user, passwd):
self.send('ok\r\n')
else:
self.send('fail\r\n')
def handle_close(self):
self.close()
class Service(asyncore.dispatcher_with_send):
def __init__(self, addr):
asyncore.dispatcher_with_send.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind(addr)
self.listen(1)
def handle_accept(self):
conn, _ = self.accept()
Client(conn)
def main():
addr = ('localhost', 8317)
Service(addr)
try:
asyncore.loop()
except KeyboardInterrupt:
pass
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
用法:
% telnet localhost 8317
bob abc123
ok
larry badpass
fail
incomplete
bad
Run Code Online (Sandbox Code Playgroud)
最后,我最终使用pexpect并尝试su - 用户名.它有点慢,但效果还不错.下面的例子没有打磨,但你会得到这个想法.
干杯,
松鸦
#!/usr/bin/python
import pexpect
def pam(username, password):
'''Accepts username and password and tried to use PAM for authentication'''
try:
child = pexpect.spawn('/bin/su - %s'%(username))
child.expect('Password:')
child.sendline(password)
result=child.expect(['su: Authentication failure',username])
child.close()
except Exception as err:
child.close()
print ("Error authenticating. Reason: "%(err))
return False
if result == 0:
print ("Authentication failed for user %s."%(username))
return False
else:
print ("Authentication succeeded for user %s."%(username))
return True
if __name__ == '__main__':
print pam(username='default',password='chandgeme')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11369 次 |
| 最近记录: |