ssh-agent for an entire unix group

Omri Bahumi omri.il at gmail.com
Tue Jun 12 06:46:46 EST 2012


Re attached
-------------- next part --------------
--- openssh-5.5p1/ssh-agent.c	2010-02-26 22:55:06.000000000 +0200
+++ openssh-5.5p1.new/ssh-agent.c	2012-06-11 22:12:09.000000000 +0300
@@ -120,6 +120,10 @@
 
 int max_fd = 0;
 
+/* instead of just effective uid checking, accept same effective gid as well
+   this is useful for sharing the same agent with the entire group without hacks */
+int accept_same_gid = 0;
+
 /* pid of shell == parent of agent */
 pid_t parent_pid = -1;
 u_int parent_alive_interval = 0;
@@ -960,10 +964,14 @@
 					close(sock);
 					break;
 				}
-				if ((euid != 0) && (getuid() != euid)) {
-					error("uid mismatch: "
-					    "peer euid %u != uid %u",
-					    (u_int) euid, (u_int) getuid());
+				if ((euid != 0) && 
+				((!accept_same_gid && getuid() != euid) ||
+				(accept_same_gid && getgid() != egid))) {
+					error("uid/gid mismatch: "
+					    "peer euid %u != uid %u, "
+					    "peer egid %u != gid %u",
+					    (u_int) euid, (u_int) getuid(),
+					    (u_int) egid, (u_int) getgid());
 					close(sock);
 					break;
 				}
@@ -1051,6 +1059,7 @@
 	fprintf(stderr, "  -c          Generate C-shell commands on stdout.\n");
 	fprintf(stderr, "  -s          Generate Bourne shell commands on stdout.\n");
 	fprintf(stderr, "  -k          Kill the current agent.\n");
+	fprintf(stderr, "  -g          Accept connections from same GID as well as the same UID\n");
 	fprintf(stderr, "  -d          Debug mode.\n");
 	fprintf(stderr, "  -a socket   Bind agent socket to given name.\n");
 	fprintf(stderr, "  -t life     Default identity lifetime (seconds).\n");
@@ -1060,7 +1069,7 @@
 int
 main(int ac, char **av)
 {
-	int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0;
+	int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0, g_flag = 0;
 	int sock, fd, ch, result, saved_errno;
 	u_int nalloc;
 	char *shell, *format, *pidstr, *agentsocket = NULL;
@@ -1095,7 +1104,7 @@
 	init_rng();
 	seed_rng();
 
-	while ((ch = getopt(ac, av, "cdksa:t:")) != -1) {
+	while ((ch = getopt(ac, av, "cdkgsa:t:")) != -1) {
 		switch (ch) {
 		case 'c':
 			if (s_flag)
@@ -1110,6 +1119,11 @@
 				usage();
 			s_flag++;
 			break;
+		case 'g':
+			if (g_flag)
+				usage();
+			g_flag++;
+			break;
 		case 'd':
 			if (d_flag)
 				usage();
@@ -1131,7 +1145,7 @@
 	ac -= optind;
 	av += optind;
 
-	if (ac > 0 && (c_flag || k_flag || s_flag || d_flag))
+	if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || g_flag))
 		usage();
 
 	if (ac == 0 && !c_flag && !s_flag) {
@@ -1168,6 +1182,10 @@
 	}
 	parent_pid = getpid();
 
+	if (g_flag) {
+		accept_same_gid = 1;
+	}
+
 	if (agentsocket == NULL) {
 		/* Create private directory for agent socket */
 		strlcpy(socket_dir, "/tmp/ssh-XXXXXXXXXX", sizeof socket_dir);
@@ -1175,6 +1193,12 @@
 			perror("mkdtemp: private socket dir");
 			exit(1);
 		}
+		if (accept_same_gid) {
+			if (chmod(socket_dir, 0750) != 0) {
+				perror("chmod: private socket dir");
+				exit(1);
+			}
+		}
 		snprintf(socket_name, sizeof socket_name, "%s/agent.%ld", socket_dir,
 		    (long)parent_pid);
 	} else {
@@ -1196,7 +1220,7 @@
 	memset(&sunaddr, 0, sizeof(sunaddr));
 	sunaddr.sun_family = AF_UNIX;
 	strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path));
-	prev_mask = umask(0177);
+	prev_mask = umask(accept_same_gid ? 0117 : 0177);
 	if (bind(sock, (struct sockaddr *) &sunaddr, sizeof(sunaddr)) < 0) {
 		perror("bind");
 		*socket_name = '\0'; /* Don't unlink any existing file */


More information about the openssh-unix-dev mailing list