我正在编写一个代码,用于通过ipc使用域套接字连接到客户端进程的服务器进程提取对等凭证。代码中没有错误,但在运行时我没有得到对等进程的euid和gid。
服务器进程代码是:
#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 :(得分: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)