Might a patch to ssh-agent to allow relaxing of peer euid check be accepted?

Matthew Miller mattdm at mattdm.org
Thu May 19 01:12:53 EST 2011


Hi everyone. I have a system where I'd like to give certain users
time-limited access to the use of certain SSH private keys without actually
exposing the keys. I have the idea of using ssh-agent to do this. The agent
would run as a "keyholder" user, and group permissions on the UNIX-domain
socket would allow read-write by both that account and the actual ssh user.

Right now, ssh-agent makes a check using getpeereid(), and declines access
if it fails. This is very sensible in general, but breaks this particular
case. Might a patch to allow an option to ssh-agent to relax the check be
accepted?

(Attached is a draft patch against 5.8p2.)



-- 
Matthew Miller           mattdm at mattdm.org          <http://mattdm.org/>
-------------- next part --------------
diff -ur openssh-5.8p2.orig/ssh-agent.1 openssh-5.8p2.dontbestrict//ssh-agent.1
--- openssh-5.8p2.orig/ssh-agent.1	2010-11-30 19:50:35.000000000 -0500
+++ openssh-5.8p2.dontbestrict//ssh-agent.1	2011-05-18 11:10:00.000000000 -0400
@@ -46,6 +46,7 @@
 .Op Fl d
 .Op Fl a Ar bind_address
 .Op Fl t Ar life
+.Op Fl U
 .Op Ar command Op Ar arg ...
 .Nm ssh-agent
 .Op Fl c | s
@@ -102,6 +103,13 @@
 .Xr ssh-add 1
 overrides this value.
 Without this option the default maximum lifetime is forever.
+.It Fl U
+Disables strict checking of the EUID of processes accessing the
+.Ux Ns -domain
+socket
+to which the agent is bound. This allows the user accessing
+the agent to be different from the account under which the
+agent runs, protected only by file permissions.
 .El
 .Pp
 If a commandline is given, this is executed as a subprocess of the agent.
diff -ur openssh-5.8p2.orig/ssh-agent.c openssh-5.8p2.dontbestrict//ssh-agent.c
--- openssh-5.8p2.orig/ssh-agent.c	2010-11-30 19:50:35.000000000 -0500
+++ openssh-5.8p2.dontbestrict//ssh-agent.c	2011-05-18 10:25:33.000000000 -0400
@@ -137,6 +137,9 @@
 /* Default lifetime (0 == forever) */
 static int lifetime = 0;
 
+/* Flag for allowing mismatched peer EUIDs */
+static int U_flag = 0;
+
 static void
 close_socket(SocketEntry *e)
 {
@@ -1023,11 +1026,18 @@
 					break;
 				}
 				if ((euid != 0) && (getuid() != euid)) {
-					error("uid mismatch: "
-					    "peer euid %u != uid %u",
-					    (u_int) euid, (u_int) getuid());
-					close(sock);
-					break;
+					if (U_flag) {
+						verbose("uid mismatch (permitted by -U): "
+						    "peer euid %u != uid %u",
+						    (u_int) euid, (u_int) getuid());
+				
+					} else {
+						error("uid mismatch: "
+						    "peer euid %u != uid %u",
+						    (u_int) euid, (u_int) getuid());
+						close(sock);
+						break;
+					}
 				}
 				new_socket(AUTH_CONNECTION, sock);
 			}
@@ -1116,6 +1126,7 @@
 	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");
+	fprintf(stderr, "  -U          Disable strict matching of peer EUID.\n");
 	exit(1);
 }
 
@@ -1157,7 +1168,7 @@
 	init_rng();
 	seed_rng();
 
-	while ((ch = getopt(ac, av, "cdksa:t:")) != -1) {
+	while ((ch = getopt(ac, av, "cdksa:t:U")) != -1) {
 		switch (ch) {
 		case 'c':
 			if (s_flag)
@@ -1186,6 +1197,9 @@
 				usage();
 			}
 			break;
+		case 'U':
+			U_flag++;
+			break;
 		default:
 			usage();
 		}
@@ -1193,7 +1207,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 || U_flag))
 		usage();
 
 	if (ac == 0 && !c_flag && !s_flag) {


More information about the openssh-unix-dev mailing list