【发布时间】:2011-12-20 10:17:29
【问题描述】:
如何在 Python 中完成 Unix 套接字凭据传递?
【问题讨论】:
标签: python linux sockets credentials
如何在 Python 中完成 Unix 套接字凭据传递?
【问题讨论】:
标签: python linux sockets credentials
有关此主题的 Internet 搜索结果出奇地少。我想我会把问题和答案贴在这里给对这个主题感兴趣的其他人。
以下客户端和服务器应用程序演示了如何在 Linux 上使用标准 python 解释器完成此操作。不需要扩展,但由于使用了嵌入式常量,代码是特定于 Linux 的。
服务器:
#!/usr/bin/env python
import struct
from socket import socket, AF_UNIX, SOCK_STREAM, SOL_SOCKET
SO_PEERCRED = 17 # Pulled from /usr/include/asm-generic/socket.h
s = socket(AF_UNIX, SOCK_STREAM)
s.bind('/tmp/pass_cred')
s.listen(1)
conn, addr = s.accept()
creds = conn.getsockopt(SOL_SOCKET, SO_PEERCRED, struct.calcsize('3i'))
pid, uid, gid = struct.unpack('3i',creds)
print 'pid: %d, uid: %d, gid %d' % (pid, uid, gid)
客户:
#!/usr/bin/env python
from socket import socket, AF_UNIX, SOCK_STREAM, SOL_SOCKET
SO_PASSCRED = 16 # Pulled from /usr/include/asm-generic/socket.h
s = socket(AF_UNIX, SOCK_STREAM)
s.setsockopt(SOL_SOCKET, SO_PASSCRED, 1)
s.connect('/tmp/pass_cred')
s.close()
不幸的是,SO_PEERCRED 和 SO_PASSCRED 常量不是由 python 的套接字模块导出的,因此必须手动输入。尽管这些值不太可能改变它是可能的。任何使用这种方法的应用程序都应该考虑这一点。
【讨论】:
SO_PASSCRED 允许接收(而不是发送)凭据,但这些凭据是使用sendmsg 和辅助SCM_CREDENTIALS 消息发送的。您正在阅读 SO_PEERCRED,它不依赖于此,只是该套接字是 unix 域套接字或由 socketpair 创建。并且只获取当前凭据(root 可以发送与其他用户匹配的凭据消息)