2011-11-12 28 views
6

Tôi có một chương trình đang nghe Ổ cắm tên miền Unix.Xác định chương trình kết nối với Ổ cắm miền Unix

Khi khách hàng kết nối với ổ cắm, tôi muốn tìm chương trình nào được kết nối và sau đó quyết định xem tôi có cho phép kết nối hay không (dựa trên cài đặt người dùng/nhóm).

Điều này có thể thực hiện được dưới Linux hay không và nếu có thì làm cách nào?

Trả lời

8

Có, điều này là có thể trên Linux, nhưng nó sẽ không thể di chuyển được. Nó đạt được bằng cách sử dụng những gì được gọi là "dữ liệu phụ trợ" với sendmsg/recvmsg.

  • Sử dụng SO_PASSCRED với setsockopt
  • Sử dụng SCM_CREDENTIALSstruct ucred cấu trúc

Cấu trúc này được định nghĩa trong 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 */ 
}; 

Lưu ý bạn phải điền những trong msghdr.control của bạn, và hạt nhân sẽ kiểm tra xem chúng có đúng không.

Các tính di động trở ngại chính là cấu trúc này khác với trên Unixes khác - ví dụ trên FreeBSD đó là:

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 */ 
}; 
+0

Cảm ơn bạn rất nhiều. Chính xác những gì tôi đang tìm kiếm. Tính di động không phải là vấn đề. Mã sẽ chỉ chạy trên Android dưới dạng mã gốc. –

1

Có lẽ getpeername hoặc getsockname có thể trợ giúp. và tôi nghĩ rằng sự cho phép của bạn unix socket là hữu ích (không chắc chắn về điều đó). Và bạn có thể đọc các liên kết bên trong /proc/self/fd/12 nếu accept ổ cắm -ed của bạn là 12.

EDIT

sử dụng dữ liệu phụ trợ cho thông tin và sendmsg là tốt hơn nhiều, theo đề nghị của cnicutar dưới đây.

6

Tôi đã tìm kiếm cho điều này khá nhiều, vì vậy tôi sẽ cho bạn thấy ví dụ này về cách sử dụng SO_PEERCRED trên một ổ cắm sock để lấy pid/uid/gid của máy ngang hàng của một ổ cắm:

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); 
Các vấn đề liên quan