getsockopt SO_PEERCRED

SO_PEERCRED only works on AF_UNIX stream socket or AF_UNIX stream/datagram socket created by sockpair

 

sockpair

 

#define _GNU_SOURCE
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/*

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 <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#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 <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

/*
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;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值