Определите программу, которая подключается к Unix Domain Socket - PullRequest
9 голосов
/ 12 ноября 2011

У меня есть программа, которая прослушивает Unix Domain Socket.

Когда клиент подключается к сокету, я хотел бы узнать, какая программа подключена, а затем решить, разрешить ли мне подключение или нет (на основе настроек пользователя / группы).

Возможно ли это в Linux, и если да, то как?

Ответы [ 3 ]

12 голосов
/ 12 ноября 2011

Да, это возможно в Linux, но оно не будет очень переносимым.Это достигается с помощью так называемых «вспомогательных данных» с sendmsg / recvmsg.

  • Использование SO_PASSCRED с setsockopt
  • Использование SCM_CREDENTIALS и struct 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 */
};
9 голосов
/ 06 марта 2016

Я искал это совсем немного, поэтому я покажу вам этот пример того, как использовать SO_PEERCRED для сокета sock, чтобы получить 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);
2 голосов
/ 12 ноября 2011

Возможно getpeername или getsockname может помочь. и я думаю, что разрешение вашего unix socket полезно (не уверен в этом). И вы можете прочитать ссылку внутри /proc/self/fd/12, если ваш accept -ed сокет равен 12.

EDIT

с использованием вспомогательных данных для учетных данных, а sendmsg намного лучше, как предложено cnicutar ниже.

...