diff -up openssh-5.8p1/auth2-pubkey.c.keycat2 openssh-5.8p1/auth2-pubkey.c --- openssh-5.8p1/auth2-pubkey.c.keycat2 2011-03-01 06:57:03.000000000 +0100 +++ openssh-5.8p1/auth2-pubkey.c 2011-03-01 07:25:04.000000000 +0100 @@ -579,6 +579,14 @@ user_key_via_command_allowed2(struct pas close(i); } +#ifdef WITH_SELINUX + if (ssh_selinux_setup_env_variables() < 0) { + error ("failed to copy environment: %s", + strerror(errno)); + _exit(127); + } +#endif + execl(options.authorized_keys_command, options.authorized_keys_command, pw->pw_name, NULL); /* if we got here, it didn't work */ diff -up openssh-5.8p1/openbsd-compat/port-linux.c.keycat2 openssh-5.8p1/openbsd-compat/port-linux.c --- openssh-5.8p1/openbsd-compat/port-linux.c.keycat2 2011-03-01 07:00:32.000000000 +0100 +++ openssh-5.8p1/openbsd-compat/port-linux.c 2011-03-01 07:23:13.000000000 +0100 @@ -309,7 +309,7 @@ ssh_selinux_getctxbyname(char *pwname, /* Setup environment variables for pam_selinux */ static int -ssh_selinux_setup_pam_variables(void) +ssh_selinux_setup_variables(int(*set_it)(const char *, const char *)) { const char *reqlvl; char *role; @@ -320,16 +320,16 @@ ssh_selinux_setup_pam_variables(void) ssh_selinux_get_role_level(&role, &reqlvl); - rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : ""); + rv = set_it("SELINUX_ROLE_REQUESTED", role ? role : ""); if (inetd_flag && !rexeced_flag) { use_current = "1"; } else { use_current = ""; - rv = rv || do_pam_putenv("SELINUX_LEVEL_REQUESTED", reqlvl ? reqlvl: ""); + rv = rv || set_it("SELINUX_LEVEL_REQUESTED", reqlvl ? reqlvl: ""); } - rv = rv || do_pam_putenv("SELINUX_USE_CURRENT_RANGE", use_current); + rv = rv || set_it("SELINUX_USE_CURRENT_RANGE", use_current); if (role != NULL) xfree(role); @@ -337,6 +337,24 @@ ssh_selinux_setup_pam_variables(void) return rv; } +static int +ssh_selinux_setup_pam_variables(void) +{ + return ssh_selinux_setup_variables(do_pam_putenv); +} + +static int +do_setenv(char *name, char *value) +{ + return setenv(name, value, 1); +} + +int +ssh_selinux_setup_env_variables(void) +{ + return ssh_selinux_setup_variables(do_setenv); +} + /* Set the execution context to the default for the specified user */ void ssh_selinux_setup_exec_context(char *pwname) diff -up openssh-5.8p1/ssh-keycat.c.keycat2 openssh-5.8p1/ssh-keycat.c --- openssh-5.8p1/ssh-keycat.c.keycat2 2011-03-01 06:56:02.000000000 +0100 +++ openssh-5.8p1/ssh-keycat.c 2011-03-01 06:56:02.000000000 +0100 @@ -65,6 +65,7 @@ #define ERR_FDOPEN 10 #define ERR_STAT 11 #define ERR_WRITE 12 +#define ERR_PAM_PUTENV 13 #define BUFLEN 4096 /* Just ignore the messages in the conversation function */ @@ -166,6 +167,34 @@ fail: return rv; } +static const char *env_names[] = { "SELINUX_ROLE_REQUESTED", + "SELINUX_LEVEL_REQUESTED", + "SELINUX_USE_CURRENT_RANGE" +}; + +extern char **environ; + +int +set_pam_environment(pam_handle_t *pamh) +{ + int i; + size_t j; + + for (j = 0; j < sizeof(env_names)/sizeof(env_names[0]); ++j) { + int len = strlen(env_names[j]); + + for (i = 0; environ[i] != NULL; ++i) { + if (strncmp(env_names[j], environ[i], len) == 0 && + environ[i][len] == '=') { + if (pam_putenv(pamh, environ[i]) != PAM_SUCCESS) + return ERR_PAM_PUTENV; + } + } + } + + return 0; +} + int main(int argc, char *argv[]) { @@ -183,6 +212,10 @@ main(int argc, char *argv[]) return ERR_PAM_START; } + ev = set_pam_environment(pamh); + if (ev != 0) + goto finish; + retval = pam_open_session(pamh, PAM_SILENT); if (retval != PAM_SUCCESS) { ev = ERR_OPEN_SESSION;