Matthew Miller
2011-May-18 15:12 UTC
Might a patch to ssh-agent to allow relaxing of peer euid check be accepted?
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) {
Peter Stuge
2011-May-19 00:30 UTC
Might a patch to ssh-agent to allow relaxing of peer euid check be accepted?
Matthew Miller wrote:> 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?I doubt it. I would suggest that you implement an ssh-agent proxy to sit in front of the actual agent, running as keyholder, where you implement policy. //Peter
Matthew Miller
2011-May-19 13:25 UTC
Might a patch to ssh-agent to allow relaxing of peer euid check be accepted?
Peter Stuge wrote:>> 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? > I doubt it. I would suggest that you implement an ssh-agent proxy to sit > in front of the actual agent, running as keyholder, where you implement > policy.That's an interesting idea. However, for this case, that introduces complication without particular benefit, as we're not wanting to implement any particular policy but rather have ssh-agent _refrain_ from enforcing a hard-coded one. Without the check, simple policy can be implemented at the filesystem level (or through various security modules). It's worth noting that sshd itself doesn't implement the policy that ssh-agent does. If you forward your ssh-agent connection to a remote machine, there is no similar check. So, I do hope the simple patch can be considered. -- Matthew Miller mattdm at mattdm.org <http://mattdm.org/>