繁体   English   中英

Unix 套接字凭证传入 Python

[英]Unix socket credential passing in Python

Unix socket凭证传递在Python是如何完成的?

关于这一主题的互联网搜索得出的结果令人惊讶。 我想我会在这里发布问题并回答其他对这个主题感兴趣的人。

以下客户端和服务器应用程序演示了如何使用标准python解释器在Linux上完成此任务。 不需要扩展,但由于使用了嵌入式常量,代码是特定于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的套接字模块导出,所以必须手动输入它们。 虽然这些值不太可能改变,但这是可能的。 任何使用此方法的应用程序都应考虑这一点。

这是 Rakis 的 server.py 的 Python 3 版本,它不使用硬编码 ID,还显示客户端的用户名和组名:

#!/usr/bin/env python
import os
import atexit
import grp
import pwd
import struct
from socket import socket, AF_UNIX, SOCK_STREAM, SOL_SOCKET, SO_PEERCRED

def remove_sock():
    try:
        os.unlink('/tmp/pass_cred')
    except FileNotFoundError:
        pass

remove_sock()
atexit.register(remove_sock)

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)

user_name = pwd.getpwuid(uid)[0]
group_name = grp.getgrgid(gid)[0]

print(f'pid={pid}, uid={uid}({user_name}), gid={gid}({group_name})')

还进行了更新以使其可重用(您不能将套接字绑定到已经存在的文件名,因此我们在绑定之前和正常进程退出之后都清理套接字)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM