【发布时间】:2015-12-19 18:06:06
【问题描述】:
我正在编写一个代码,用于通过使用域套接字通过 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;
}
【问题讨论】: