【问题标题】:Identify program that connects to a Unix Domain Socket识别连接到 Unix 域套接字的程序
【发布时间】:2011-12-27 15:23:38
【问题描述】:

我有一个程序正在侦听 Unix 域套接字。

当客户端连接到套接字时,我想找出连接的程序,然后决定是否允许连接(基于用户/组设置)。

这在 Linux 下是否可行,如果可以,如何实现?

【问题讨论】:

    标签: linux unix-socket


    【解决方案1】:

    是的,这在 Linux 上是可能的,但它的可移植性不是很好。它是通过sendmsg / recvmsg 使用所谓的“辅助数据”来实现的。

    • 使用SO_PASSCREDsetsockopt
    • 使用SCM_CREDENTIALSstruct ucred 结构

    这个结构是在Linux中定义的:

    struct ucred {
        pid_t pid;    /* process ID of the sending process */
        uid_t uid;    /* user ID of the sending process */
        gid_t gid;    /* group ID of the sending process */
    };
    

    请注意,您必须在msghdr.control 中填写这些内容,内核将检查它们是否正确。

    主要的可移植性障碍是这种结构在其他 Unix 上有所不同 - 例如在 FreeBSD 上:

    struct cmsgcred {
        pid_t   cmcred_pid;          /* PID of sending process */
        uid_t   cmcred_uid;          /* real UID of sending process */
        uid_t   cmcred_euid;         /* effective UID of sending process */
        gid_t   cmcred_gid;          /* real GID of sending process */
        short   cmcred_ngroups;      /* number or groups */
        gid_t   cmcred_groups[CMGROUP_MAX];     /* groups */
    };
    

    【讨论】:

    • 非常感谢。正是我想要的。便携性不是问题。无论如何,该代码只会作为原生代码在 Android 上运行。
    【解决方案2】:

    我对此进行了相当多的搜索,因此我将向您展示如何在套接字sock 上使用 SO_PEERCRED 来获取套接字对等方的 pid/uid/gid:

    int len;
    struct ucred ucred;
    
    len = sizeof(struct ucred);
    
    if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1) {
        //getsockopt failed
    }
    
    printf("Credentials from SO_PEERCRED: pid=%ld, euid=%ld, egid=%ld\n",
        (long) ucred.pid, (long) ucred.uid, (long) ucred.gid);
    

    【讨论】:

    • 我也搜索了很多,能找到这个答案感到非常幸运!大多数其他消息来源坚持认为您需要使用sendmsgrecvmsg,而这根本不属实。我将补充一点,给出的示例中的sock 参数将是您要识别的客户端进程的文件描述符,并且我发现我需要从客户端执行至少一个read() 的数据,否则我得到ucred 结构中的未定义值。
    • glibc 自 2.8.0 (2009) 起需要定义 _GNU_SOURCE。临时来源:github.com/apple/cups/issues/2860
    【解决方案3】:

    也许getpeernamegetsockname 会有所帮助。而且我认为您的unix socket 的许可很有用(不确定)。如果您的 accept-ed 套接字是 12,您可能会阅读 /proc/self/fd/12 中的链接。

    编辑

    使用辅助数据作为凭据和sendmsg 会更好,如下cnicutar 所建议。

    【讨论】:

      猜你喜欢
      • 2012-08-07
      • 1970-01-01
      • 1970-01-01
      • 2017-02-06
      • 2014-06-02
      • 1970-01-01
      • 2015-07-20
      • 1970-01-01
      • 2016-09-02
      相关资源
      最近更新 更多