2014-12-06 99 views
0

我正在編寫一個代碼,用於通過ipc使用域套接字連接到客戶機進程的服務器進程提取對等體憑證。代碼中沒有錯誤,但在運行時我沒有得到對等進程的euid和gid。通過unix域套接字ipc機制的對等憑證

代碼服務器進程:

#include <stdio.h> 
#include <sys/socket.h> 
#include <sys/un.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <string.h> 
//#include<ucred.h> 
#define SCM_CREDENTIALS 
# define UNIX_PATH_MAX 100 

int getpeereid(int connection_fd,uid_t euid,gid_t gid) 
{ 
struct ucred cred; 
socklen_t len = sizeof(cred); 

if (getsockopt(connection_fd, SOL_SOCKET, SO_PEERCRED, &cred, &len) < 0) 
     return (-1); 
    euid =cred.uid; 
    gid = cred.gid; 
//int passcred=1; 
//setsockopt(connection_fd,SOL_SOCKET,SO_PASSCRED,(void *)&passcred,sizeof(passcred)); 

printf("effective user id", euid); 
printf("effective group id",gid); 
return 0; 
} 

int connection_handler(int connection_fd) 
{ 
int nbytes; 
char buffer[1024]; 
char msg[256]; 
//while(cont=recv(connection_fd,buffer,sizeof(buffer),0)>0) 
//{ 
//write(1,buffer,cont) 

nbytes = read(connection_fd, buffer, 256); 
buffer[nbytes] = 0; 

printf("MESSAGE FROM CLIENT: %s\n", buffer); 
printf("enter the message"); 
scanf("%s",msg); 
nbytes = snprintf(buffer, 256,msg); 
write(connection_fd, buffer, nbytes); 
//} 
close(connection_fd); 
return 0; 

} 

int main(void) 
{ 
struct sockaddr_un address; 
int socket_fd, connection_fd,res; 
socklen_t address_length; 
pid_t child; 
uid_t eid; 
gid_t gid; 

socket_fd = socket(PF_UNIX, SOCK_STREAM, 0); 
if(socket_fd < 0) 
{ 
    printf("socket() failed\n"); 
    return 1; 
} 
printf("socket created\n"); 
unlink("./demo_socket"); 

/* start with a clean address structure */ 

memset(&address, 0, sizeof(struct sockaddr_un)); 

address.sun_family = AF_UNIX; 
snprintf(address.sun_path, UNIX_PATH_MAX, "./demo_socket"); 

if(bind(socket_fd, 
     (struct sockaddr *) &address, 
     sizeof(struct sockaddr_un)) != 0) 
{ 
    printf("bind() failed\n"); 
    return 1; 
} 

if(listen(socket_fd, 5) != 0) 
{ 
    printf("listen() failed\n"); 
    return 1; 
} 

while((connection_fd = accept(socket_fd, 
           (struct sockaddr *) &address, 
           &address_length)) > -1) 
{ 

// get the credentials 
res=getpeereid(connection_fd,geteuid(),getgid()); 
if (res==0) 
{ 
//if(res==0) 
//{ 


child = fork(); 
    if(child == 0) 
    { 

    /* now inside newly created connection handling process */ 
    return connection_handler(connection_fd); 
    } 
} 
    /* still inside server process */ 
    close(connection_fd); 
//} 
} 

close(socket_fd); 
unlink("./demo_socket"); 
return 0; 
} 

的代碼,客戶端

#include <stdio.h> 
#include <sys/socket.h> 
#include <sys/un.h> 
#include <unistd.h> 
#include <string.h> 
#define UNIX_PATH_MAX 100 

int connection_handler(int socket_fd) 
{ 
int nbytes; 
char buffer[1024]; 
char mesg[256]; 
printf("enter the message"); 
scanf("%s",mesg); 
//printf("message is %s",mesg); 
nbytes = snprintf(buffer, 256,mesg); 
//fgets(buffer,256,mesg); 
//i=atoi(mesg); 
write(socket_fd,buffer,nbytes); 
//send(socket_fd,mesg,sizeof(mesg),0); 
} 
//nbytes = read(socket_fd, buffer, 256); 
//buffer[nbytes] = 0; 

//printf("MESSAGE FROM SERVER: %s\n", buffer); 
//} 

int main(void) 
{ 
struct sockaddr_un address; 
int socket_fd, nbytes,i; 
pid_t child; 
char buffer[256]; 
//char mesg[100]; 
socket_fd = socket(PF_UNIX, SOCK_STREAM, 0); 
if(socket_fd < 0) 
{ 
    printf("socket() failed\n"); 
    return 1; 
} 
printf("socket created\n"); 
/* start with a clean address structure */ 
memset(&address, 0, sizeof(struct sockaddr_un)); 

address.sun_family = AF_UNIX; 
snprintf(address.sun_path, UNIX_PATH_MAX, "./demo_socket"); 

if(connect(socket_fd, 
      (struct sockaddr *) &address, 
      sizeof(struct sockaddr_un)) != 0) 
{ 
    printf("connect() failed\n"); 

return 1; 
} 


child=fork(); 
while(child==0) 
{ 
return connection_handler(socket_fd); 
//printf("connection established\n"); 
//printf("enter the message"); 
//scanf("%s",mesg); 
//printf("message is %s",mesg); 
//bytes = snprintf(buffer, 256,mesg); 
//fgets(buffer,256,mesg); 
//i=atoi(mesg); 
//write(socket_fd,buffer,nbytes); 
//send(socket_fd,mesg,sizeof(mesg),0); 
} 

nbytes = read(socket_fd, buffer, 256); 
buffer[nbytes] = 0; 

printf("MESSAGE FROM SERVER: %s\n", buffer); 

close(socket_fd); 
return 0; 
} 

回答

0

良好的概述見http://www.thomasstover.com/uds.html

如果服務器是Linux,則主要問題是缺少_GNU_SOURCE。下面是完整的補丁,它只是爲了擺脫gcc -Wall -Werror -pedantic -std=c99錯誤和警告而進行的一些小修改。

--- server.c.orig 2014-12-06 13:23:09.138472871 +0200 
+++ server.c 2014-12-06 13:21:31.962475754 +0200 
@@ -1,3 +1,4 @@ 
+#define _GNU_SOURCE 
#include <stdio.h> 
#include <sys/socket.h> 
#include <sys/un.h> 
@@ -5,7 +6,6 @@ 
#include <unistd.h> 
#include <string.h> 
//#include<ucred.h> 
-#define SCM_CREDENTIALS 
# define UNIX_PATH_MAX 100 

int getpeereid(int connection_fd,uid_t euid,gid_t gid) 
@@ -20,8 +20,8 @@ 
//int passcred=1; 
//setsockopt(connection_fd,SOL_SOCKET,SO_PASSCRED,(void *)&passcred,sizeof(passcred)); 

-printf("effective user id", euid); 
-printf("effective group id",gid); 
+printf("effective user id %d", euid); 
+printf("effective group id %d",gid); 
return 0; 
} 

@@ -40,7 +40,7 @@ 
printf("MESSAGE FROM CLIENT: %s\n", buffer); 
printf("enter the message"); 
scanf("%s",msg); 
-nbytes = snprintf(buffer, 256,msg); 
+nbytes = snprintf(buffer, 256, "%s", msg); 
write(connection_fd, buffer, nbytes); 
//} 
    close(connection_fd); 
@@ -54,8 +54,6 @@ 
    int socket_fd, connection_fd,res; 
    socklen_t address_length; 
pid_t child; 
-uid_t eid; 
-gid_t gid; 

    socket_fd = socket(PF_UNIX, SOCK_STREAM, 0); 
    if(socket_fd < 0) 
+0

你可能只是告訴他,他失蹤的格式選項爲'printf',這就是爲什麼他沒有看到任何'euid'或'gid'而不是這堵牆差異的。 – Petesh 2014-12-07 11:31:01

+0

我做了更改並執行。我錯過了格式選項!但執行後我得到相同的euid和gid,即euid = 1000和gid = 1000。這可能是什麼原因? – Neha 2014-12-07 13:20:31

+0

@Neha是不是用戶的1000個UID和GID,誰在運行客戶端?我試圖從2個不同的用戶運行客戶端(必須更改'。/ demo.socket'的權限才能連接),並且我得到了正確的結果。 – kestasx 2014-12-07 14:14:27