通过unix域套接字ipc机制的对等凭据

通过unix域套接字ipc机制的对等凭据,unix,ipc,Unix,Ipc,我正在编写一个代码,用于通过ipc使用域套接字连接到客户端进程的服务器进程提取对等凭据。代码中没有错误,但在运行它时,我没有获得对等进程的euid和gid 服务器进程的代码为: #include <stdio.h> #include <sys/socket.h> #include <sys/un.h> #include <sys/types.h> #include <unistd.h> #include <string.h>

我正在编写一个代码,用于通过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;
}
请参阅以获得良好的概述

如果服务器是Linux,主要问题是缺少GNU源代码。在下面的完整补丁中,它有一些小改动,只是为了消除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)

你可以告诉他,他丢失了printf的格式选项,这就是为什么他没有看到任何euid或gid,而不是这个差异墙。我做了更改并执行了。我的坏朋友错过了格式选项!但在执行之后,我得到了相同的euid和gid,即euid=1000和gid=1000。原因可能是什么?@Neha不是运行客户端的用户的1000 UID和GID?我尝试从两个不同的用户运行客户端,必须更改./demo.socket的权限才能连接,并且我得到了正确的结果。@Petesh问题不仅仅是格式化:没有_GNU_SOURCE_uquo; cred未定义。好的!知道了。谢谢你的帮助。感激