sockpair
#define _GNU_SOURCE
#include
#include
#include
#include
#include
/*
SO_PEERCRED only works on AF_UNIX stream socket or AF_UNIX stream/datagram socket created by sockpair
Credentials from SO_PEERCRED: pid=21107, uid=1000, gid=1000, len=12
*/
int main(int argc, char *argv[])
{
int fd[2];
struct ucred cred;
socklen_t len;
printf("pid=%d\n", getpid());
// if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) < 0) {
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fd) < 0) {
perror("socketpair");
exit(EXIT_FAILURE);
}
memset(&cred, 0, sizeof(struct ucred));
len = sizeof(struct ucred);
if (getsockopt(fd[0], SOL_SOCKET, SO_PEERCRED, &cred, &len) < 0) {
perror("getsockopt");
exit(EXIT_FAILURE);
}
printf("Credentials from SO_PEERCRED: pid=%d, uid=%d, gid=%d, len=%d\n", cred.pid, cred.uid, cred.gid, len);
return 0;
}
stream socket
#define _GNU_SOURCE
#include
#include
#include
#include
#include
#define SOCKET_PATH_S "/tmp/oases_sock_server"
/*
struct ucred {
__u32 pid;
__u32 uid;
__u32 gid;
};
struct ucred {
pid_t pid;
uid_t uid;
gid_t gid;
};
*/
int main(int argc, char *argv[])
{
int skt, conn;
struct sockaddr_un cli_addr, serv_addr;
struct ucred cred;
socklen_t len;
unlink(SOCKET_PATH_S);
printf("server pid=%d\n", getpid());
skt = socket(AF_LOCAL, SOCK_STREAM, 0);
if (skt < 0) {
perror("socket");
close(skt);
exit(EXIT_FAILURE);
}
memset(&serv_addr, 0, sizeof(struct sockaddr_un));
serv_addr.sun_family = AF_LOCAL;
snprintf(serv_addr.sun_path, sizeof(serv_addr.sun_path), SOCKET_PATH_S);
if (bind(skt, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr_un)) < 0) {
perror("bind");
close(skt);
exit(EXIT_FAILURE);
}
if (listen(skt, 5) < 0) {
perror("listen");
close(skt);
exit(EXIT_FAILURE);
}
for (;;) {
len = sizeof(struct sockaddr_un);
/* TODO: handle signal here */
conn = accept(skt, (struct sockaddr *)&cli_addr, &len);
if (conn < 0) {
perror("accept");
close(skt);
exit(EXIT_FAILURE);
}
printf("cli_addr.sun_path=%s\n", cli_addr.sun_path);
if (getsockopt(conn, SOL_SOCKET, SO_PEERCRED, &cred, &len) < 0) {
perror("getsockopt");
exit(EXIT_FAILURE);
}
printf("Credentials from SO_PEERCRED: pid=%d, uid=%d, gid=%d, len=%d\n", cred.pid, cred.uid, cred.gid, len);
close(conn);
}
return 0;
}
client.c /
#define _GNU_SOURCE
#include
#include
#include
#include
#include
/*
struct ucred {
__u32 pid;
__u32 uid;
__u32 gid;
};
struct ucred {
pid_t pid;
uid_t uid;
gid_t gid;
};
*/
#define SOCKET_PATH_C "/tmp/oases_sock_client"
#define SOCKET_PATH_S "/tmp/oases_sock_server"
#define MSG "123456789"
int main(int argc, char *argv[])
{
int skt;
struct ucred cred;
struct sockaddr_un cli_addr, serv_addr;
socklen_t len;
printf("client pid=%d\n", getpid());
unlink(SOCKET_PATH_C);
skt = socket(AF_UNIX, SOCK_STREAM, 0);
if (skt < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
memset(&cli_addr, 0, sizeof(struct sockaddr_un));
cli_addr.sun_family = AF_UNIX;
snprintf(cli_addr.sun_path, sizeof(cli_addr.sun_path), SOCKET_PATH_C);
memset(&serv_addr, 0, sizeof(struct sockaddr_un));
serv_addr.sun_family = AF_UNIX;
snprintf(serv_addr.sun_path, sizeof(serv_addr.sun_path), SOCKET_PATH_S);
if (bind(skt, (struct sockaddr *)&cli_addr, sizeof(struct sockaddr_un)) < 0) {
perror("bind");
exit(EXIT_FAILURE);
}
if (connect(skt, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr_un)) < 0) {
perror("connect");
exit(EXIT_FAILURE);
}
memset(&cred, 0, sizeof(struct ucred));
len = sizeof(struct ucred);
if (getsockopt(skt, SOL_SOCKET, SO_PEERCRED, &cred, &len) < 0) {
perror("getsockopt");
exit(EXIT_FAILURE);
}
printf("Credentials from SO_PEERCRED: pid=%d, uid=%d, gid=%d, len=%d\n", cred.pid, cred.uid, cred.gid, len);
return 0;
}