Remove unnecessary files

This commit is contained in:
Jan F. Chadima 2010-05-03 13:46:41 +00:00
parent 3fdf10cdb4
commit 395eb16df8
4 changed files with 0 additions and 3920 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,446 +0,0 @@
diff -up openssh-5.4p1/configure.ac.mls openssh-5.4p1/configure.ac
--- openssh-5.4p1/configure.ac.mls 2010-03-01 15:24:27.000000000 +0100
+++ openssh-5.4p1/configure.ac 2010-03-01 15:24:28.000000000 +0100
@@ -3360,6 +3360,7 @@ AC_ARG_WITH(selinux,
SSHDLIBS="$SSHDLIBS $LIBSELINUX"
LIBS="$LIBS $LIBSELINUX"
AC_CHECK_FUNCS(getseuserbyname get_default_context_with_level)
+ AC_CHECK_FUNCS(setkeycreatecon)
LIBS="$save_LIBS"
fi ]
)
diff -up openssh-5.4p1/misc.c.mls openssh-5.4p1/misc.c
--- openssh-5.4p1/misc.c.mls 2010-01-10 00:31:12.000000000 +0100
+++ openssh-5.4p1/misc.c 2010-03-01 15:24:28.000000000 +0100
@@ -423,6 +423,7 @@ char *
colon(char *cp)
{
int flag = 0;
+ int start = 1;
if (*cp == ':') /* Leading colon is part of file name. */
return (0);
@@ -436,8 +437,13 @@ colon(char *cp)
return (cp+1);
if (*cp == ':' && !flag)
return (cp);
- if (*cp == '/')
- return (0);
+ if (start) {
+ /* Slash on beginning or after dots only denotes file name. */
+ if (*cp == '/')
+ return (0);
+ if (*cp != '.')
+ start = 0;
+ }
}
return (0);
}
diff -up openssh-5.4p1/openbsd-compat/port-linux.c.mls openssh-5.4p1/openbsd-compat/port-linux.c
--- openssh-5.4p1/openbsd-compat/port-linux.c.mls 2010-03-01 15:24:27.000000000 +0100
+++ openssh-5.4p1/openbsd-compat/port-linux.c 2010-03-01 15:25:50.000000000 +0100
@@ -35,13 +35,24 @@
#include "key.h"
#include "hostfile.h"
#include "auth.h"
+#include "xmalloc.h"
#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#include <selinux/flask.h>
+#include <selinux/context.h>
#include <selinux/get_context_list.h>
+#include <selinux/get_default_type.h>
+#include <selinux/av_permissions.h>
+
+#ifdef HAVE_LINUX_AUDIT
+#include <libaudit.h>
+#include <unistd.h>
+#endif
extern Authctxt *the_authctxt;
+extern int inetd_flag;
+extern int rexeced_flag;
/* Wrapper around is_selinux_enabled() to log its return value once only */
int
@@ -57,17 +68,173 @@ ssh_selinux_enabled(void)
return (enabled);
}
+/* Send audit message */
+static int
+send_audit_message(int success, security_context_t default_context,
+ security_context_t selected_context)
+{
+ int rc=0;
+#ifdef HAVE_LINUX_AUDIT
+ char *msg = NULL;
+ int audit_fd = audit_open();
+ security_context_t default_raw=NULL;
+ security_context_t selected_raw=NULL;
+ rc = -1;
+ if (audit_fd < 0) {
+ if (errno == EINVAL || errno == EPROTONOSUPPORT ||
+ errno == EAFNOSUPPORT)
+ return 0; /* No audit support in kernel */
+ error("Error connecting to audit system.");
+ return rc;
+ }
+ if (selinux_trans_to_raw_context(default_context, &default_raw) < 0) {
+ error("Error translating default context.");
+ default_raw = NULL;
+ }
+ if (selinux_trans_to_raw_context(selected_context, &selected_raw) < 0) {
+ error("Error translating selected context.");
+ selected_raw = NULL;
+ }
+ if (asprintf(&msg, "sshd: default-context=%s selected-context=%s",
+ default_raw ? default_raw : (default_context ? default_context: "?"),
+ selected_context ? selected_raw : (selected_context ? selected_context :"?")) < 0) {
+ error("Error allocating memory.");
+ goto out;
+ }
+ if (audit_log_user_message(audit_fd, AUDIT_USER_ROLE_CHANGE,
+ msg, NULL, NULL, NULL, success) <= 0) {
+ error("Error sending audit message.");
+ goto out;
+ }
+ rc = 0;
+ out:
+ free(msg);
+ freecon(default_raw);
+ freecon(selected_raw);
+ close(audit_fd);
+#endif
+ return rc;
+}
+
+static int
+mls_range_allowed(security_context_t src, security_context_t dst)
+{
+ struct av_decision avd;
+ int retval;
+ unsigned int bit = CONTEXT__CONTAINS;
+
+ debug("%s: src:%s dst:%s", __func__, src, dst);
+ retval = security_compute_av(src, dst, SECCLASS_CONTEXT, bit, &avd);
+ if (retval || ((bit & avd.allowed) != bit))
+ return 0;
+
+ return 1;
+}
+
+static int
+get_user_context(const char *sename, const char *role, const char *lvl,
+ security_context_t *sc) {
+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
+ if (lvl == NULL || lvl[0] == '\0' || get_default_context_with_level(sename, lvl, NULL, sc) != 0) {
+ /* User may have requested a level completely outside of his
+ allowed range. We get a context just for auditing as the
+ range check below will certainly fail for default context. */
+#endif
+ if (get_default_context(sename, NULL, sc) != 0) {
+ *sc = NULL;
+ return -1;
+ }
+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
+ }
+#endif
+ if (role != NULL && role[0]) {
+ context_t con;
+ char *type=NULL;
+ if (get_default_type(role, &type) != 0) {
+ error("get_default_type: failed to get default type for '%s'",
+ role);
+ goto out;
+ }
+ con = context_new(*sc);
+ if (!con) {
+ goto out;
+ }
+ context_role_set(con, role);
+ context_type_set(con, type);
+ freecon(*sc);
+ *sc = strdup(context_str(con));
+ context_free(con);
+ if (!*sc)
+ return -1;
+ }
+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
+ if (lvl != NULL && lvl[0]) {
+ /* verify that the requested range is obtained */
+ context_t con;
+ security_context_t obtained_raw;
+ security_context_t requested_raw;
+ con = context_new(*sc);
+ if (!con) {
+ goto out;
+ }
+ context_range_set(con, lvl);
+ if (selinux_trans_to_raw_context(*sc, &obtained_raw) < 0) {
+ context_free(con);
+ goto out;
+ }
+ if (selinux_trans_to_raw_context(context_str(con), &requested_raw) < 0) {
+ freecon(obtained_raw);
+ context_free(con);
+ goto out;
+ }
+
+ debug("get_user_context: obtained context '%s' requested context '%s'",
+ obtained_raw, requested_raw);
+ if (strcmp(obtained_raw, requested_raw)) {
+ /* set the context to the real requested one but fail */
+ freecon(requested_raw);
+ freecon(obtained_raw);
+ freecon(*sc);
+ *sc = strdup(context_str(con));
+ context_free(con);
+ return -1;
+ }
+ freecon(requested_raw);
+ freecon(obtained_raw);
+ context_free(con);
+ }
+#endif
+ return 0;
+ out:
+ freecon(*sc);
+ *sc = NULL;
+ return -1;
+}
+
/* Return the default security context for the given username */
-static security_context_t
-ssh_selinux_getctxbyname(char *pwname)
+static int
+ssh_selinux_getctxbyname(char *pwname,
+ security_context_t *default_sc, security_context_t *user_sc)
{
- security_context_t sc = NULL;
char *sename, *lvl;
+ const char *reqlvl = NULL;
char *role = NULL;
- int r = 0;
+ int r = -1;
+ context_t con = NULL;
+
+ *default_sc = NULL;
+ *user_sc = NULL;
+ if (the_authctxt) {
+ if (the_authctxt->role != NULL) {
+ char *slash;
+ role = xstrdup(the_authctxt->role);
+ if ((slash = strchr(role, '/')) != NULL) {
+ *slash = '\0';
+ reqlvl = slash + 1;
+ }
+ }
+ }
- if (the_authctxt)
- role=the_authctxt->role;
#ifdef HAVE_GETSEUSERBYNAME
if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) {
sename = NULL;
@@ -75,38 +242,63 @@ ssh_selinux_getctxbyname(char *pwname)
}
#else
sename = pwname;
- lvl = NULL;
+ lvl = "";
#endif
if (r == 0) {
#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
- if (role != NULL && role[0])
- r = get_default_context_with_rolelevel(sename, role, lvl, NULL, &sc);
- else
- r = get_default_context_with_level(sename, lvl, NULL, &sc);
+ r = get_default_context_with_level(sename, lvl, NULL, default_sc);
#else
- if (role != NULL && role[0])
- r = get_default_context_with_role(sename, role, NULL, &sc);
- else
- r = get_default_context(sename, NULL, &sc);
+ r = get_default_context(sename, NULL, default_sc);
#endif
}
- if (r != 0) {
- switch (security_getenforce()) {
- case -1:
- fatal("%s: ssh_selinux_getctxbyname: "
- "security_getenforce() failed", __func__);
- case 0:
- error("%s: Failed to get default SELinux security "
- "context for %s", __func__, pwname);
- break;
- default:
- fatal("%s: Failed to get default SELinux security "
- "context for %s (in enforcing mode)",
- __func__, pwname);
+ if (r == 0) {
+ /* If launched from xinetd, we must use current level */
+ if (inetd_flag && !rexeced_flag) {
+ security_context_t sshdsc=NULL;
+
+ if (getcon_raw(&sshdsc) < 0)
+ fatal("failed to allocate security context");
+
+ if ((con=context_new(sshdsc)) == NULL)
+ fatal("failed to allocate selinux context");
+ reqlvl = context_range_get(con);
+ freecon(sshdsc);
+ if (reqlvl !=NULL && lvl != NULL && strcmp(reqlvl, lvl) == 0)
+ /* we actually don't change level */
+ reqlvl = "";
+
+ debug("%s: current connection level '%s'", __func__, reqlvl);
+ }
+
+ if ((reqlvl != NULL && reqlvl[0]) || (role != NULL && role[0])) {
+ r = get_user_context(sename, role, reqlvl, user_sc);
+
+ if (r == 0 && reqlvl != NULL && reqlvl[0]) {
+ security_context_t default_level_sc = *default_sc;
+ if (role != NULL && role[0]) {
+ if (get_user_context(sename, role, lvl, &default_level_sc) < 0)
+ default_level_sc = *default_sc;
+ }
+ /* verify that the requested range is contained in the user range */
+ if (mls_range_allowed(default_level_sc, *user_sc)) {
+ logit("permit MLS level %s (user range %s)", reqlvl, lvl);
+ } else {
+ r = -1;
+ error("deny MLS level %s (user range %s)", reqlvl, lvl);
+ }
+ if (default_level_sc != *default_sc)
+ freecon(default_level_sc);
+ }
+ } else {
+ *user_sc = *default_sc;
}
}
+ if (r != 0) {
+ error("%s: Failed to get default SELinux security "
+ "context for %s", __func__, pwname);
+ }
#ifdef HAVE_GETSEUSERBYNAME
if (sename != NULL)
@@ -114,14 +306,20 @@ ssh_selinux_getctxbyname(char *pwname)
if (lvl != NULL)
xfree(lvl);
#endif
+ if (role != NULL)
+ xfree(role);
+ if (con)
+ context_free(con);
- return (sc);
+ return (r);
}
/* Set the execution context to the default for the specified user */
void
ssh_selinux_setup_exec_context(char *pwname)
{
+ int r = 0;
+ security_context_t default_ctx = NULL;
security_context_t user_ctx = NULL;
if (!ssh_selinux_enabled())
@@ -129,22 +327,45 @@ ssh_selinux_setup_exec_context(char *pwn
debug3("%s: setting execution context", __func__);
- user_ctx = ssh_selinux_getctxbyname(pwname);
- if (setexeccon(user_ctx) != 0) {
+ r = ssh_selinux_getctxbyname(pwname, &default_ctx, &user_ctx);
+ if (r >= 0) {
+ r = setexeccon(user_ctx);
+ if (r < 0) {
+ error("%s: Failed to set SELinux execution context %s for %s",
+ __func__, user_ctx, pwname);
+ }
+#ifdef HAVE_SETKEYCREATECON
+ else if (setkeycreatecon(user_ctx) < 0) {
+ error("%s: Failed to set SELinux keyring creation context %s for %s",
+ __func__, user_ctx, pwname);
+ }
+#endif
+ }
+ if (user_ctx == NULL) {
+ user_ctx = default_ctx;
+ }
+ if (r < 0 || user_ctx != default_ctx) {
+ /* audit just the case when user changed a role or there was
+ a failure */
+ send_audit_message(r >= 0, default_ctx, user_ctx);
+ }
+ if (r < 0) {
switch (security_getenforce()) {
case -1:
fatal("%s: security_getenforce() failed", __func__);
case 0:
- error("%s: Failed to set SELinux execution "
- "context for %s", __func__, pwname);
+ error("%s: SELinux failure. Continuing in permissive mode.",
+ __func__);
break;
default:
- fatal("%s: Failed to set SELinux execution context "
- "for %s (in enforcing mode)", __func__, pwname);
+ fatal("%s: SELinux failure. Aborting connection.",
+ __func__);
}
}
- if (user_ctx != NULL)
+ if (user_ctx != NULL && user_ctx != default_ctx)
freecon(user_ctx);
+ if (default_ctx != NULL)
+ freecon(default_ctx);
debug3("%s: done", __func__);
}
@@ -162,7 +383,10 @@ ssh_selinux_setup_pty(char *pwname, cons
debug3("%s: setting TTY context on %s", __func__, tty);
- user_ctx = ssh_selinux_getctxbyname(pwname);
+ if (getexeccon(&user_ctx) < 0) {
+ error("%s: getexeccon: %s", __func__, strerror(errno));
+ goto out;
+ }
/* XXX: should these calls fatal() upon failure in enforcing mode? */
diff -up openssh-5.4p1/session.c.mls openssh-5.4p1/session.c
--- openssh-5.4p1/session.c.mls 2010-01-12 09:51:48.000000000 +0100
+++ openssh-5.4p1/session.c 2010-03-01 15:24:28.000000000 +0100
@@ -1559,10 +1559,6 @@ do_setusercontext(struct passwd *pw)
if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
-
-#ifdef WITH_SELINUX
- ssh_selinux_setup_exec_context(pw->pw_name);
-#endif
}
static void
diff -up openssh-5.4p1/sshd.c.mls openssh-5.4p1/sshd.c
--- openssh-5.4p1/sshd.c.mls 2010-03-01 15:24:27.000000000 +0100
+++ openssh-5.4p1/sshd.c 2010-03-01 15:24:28.000000000 +0100
@@ -1987,6 +1987,9 @@ main(int ac, char **av)
restore_uid();
}
#endif
+#ifdef WITH_SELINUX
+ ssh_selinux_setup_exec_context(authctxt->pw->pw_name);
+#endif
#ifdef USE_PAM
if (options.use_pam) {
do_pam_setcred(1);

View File

@ -1,384 +0,0 @@
diff -up openssh-5.4p1/auth2-pubkey.c.pka openssh-5.4p1/auth2-pubkey.c
--- openssh-5.4p1/auth2-pubkey.c.pka 2010-03-09 08:01:05.000000000 +0100
+++ openssh-5.4p1/auth2-pubkey.c 2010-03-09 08:07:15.000000000 +0100
@@ -187,27 +187,15 @@ done:
/* return 1 if user allows given key */
static int
-user_key_allowed2(struct passwd *pw, Key *key, char *file)
+user_search_key_in_file(FILE *f, char *file, Key* key, struct passwd *pw)
{
char line[SSH_MAX_PUBKEY_BYTES];
const char *reason;
int found_key = 0;
- FILE *f;
u_long linenum = 0;
Key *found;
char *fp;
- /* Temporarily use the user's uid. */
- temporarily_use_uid(pw);
-
- debug("trying public key file %s", file);
- f = auth_openkeyfile(file, pw, options.strict_modes);
-
- if (!f) {
- restore_uid();
- return 0;
- }
-
found_key = 0;
found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
@@ -278,8 +266,6 @@ user_key_allowed2(struct passwd *pw, Key
break;
}
}
- restore_uid();
- fclose(f);
key_free(found);
if (!found_key)
debug2("key not found");
@@ -327,13 +313,153 @@ user_cert_trusted_ca(struct passwd *pw,
return ret;
}
-/* check whether given key is in .ssh/authorized_keys* */
+/* return 1 if user allows given key */
+static int
+user_key_allowed2(struct passwd *pw, Key *key, char *file)
+{
+ FILE *f;
+ int found_key = 0;
+
+ /* Temporarily use the user's uid. */
+ temporarily_use_uid(pw);
+
+ debug("trying public key file %s", file);
+ f = auth_openkeyfile(file, pw, options.strict_modes);
+
+ if (f) {
+ found_key = user_search_key_in_file (f, file, key, pw);
+ fclose(f);
+ }
+
+ restore_uid();
+ return found_key;
+}
+
+#ifdef WITH_PUBKEY_AGENT
+
+#define WHITESPACE " \t\r\n"
+
+/* return 1 if user allows given key */
+static int
+user_key_via_agent_allowed2(struct passwd *pw, Key *key)
+{
+ FILE *f;
+ int found_key = 0;
+ char *pubkey_agent_string = NULL;
+ char *tmp_pubkey_agent_string = NULL;
+ char *progname;
+ char *cp;
+ struct passwd *runas_pw;
+ struct stat st;
+
+ if (options.pubkey_agent == NULL || options.pubkey_agent[0] != '/')
+ return -1;
+
+ /* get the run as identity from config */
+ runas_pw = (options.pubkey_agent_runas == NULL)? pw
+ : getpwnam (options.pubkey_agent_runas);
+ if (!runas_pw) {
+ error("%s: getpwnam(\"%s\"): %s", __func__,
+ options.pubkey_agent_runas, strerror(errno));
+ return 0;
+ }
+
+ /* Temporarily use the specified uid. */
+ if (runas_pw->pw_uid != 0)
+ temporarily_use_uid(runas_pw);
+
+ pubkey_agent_string = percent_expand(options.pubkey_agent,
+ "h", pw->pw_dir, "u", pw->pw_name, (char *)NULL);
+
+ /* Test whether agent can be modified by non root user */
+ tmp_pubkey_agent_string = xstrdup (pubkey_agent_string);
+ progname = strtok (tmp_pubkey_agent_string, WHITESPACE);
+
+ debug3("%s: checking program '%s'", __func__, progname);
+
+ if (stat (progname, &st) < 0) {
+ error("%s: stat(\"%s\"): %s", __func__,
+ progname, strerror(errno));
+ goto go_away;
+ }
+
+ if (st.st_uid != 0 || (st.st_mode & 022) != 0) {
+ error("bad ownership or modes for pubkey agent \"%s\"",
+ progname);
+ goto go_away;
+ }
+
+ if (!S_ISREG(st.st_mode)) {
+ error("pubkey agent \"%s\" is not a regular file",
+ progname);
+ goto go_away;
+ }
+
+ /*
+ * Descend the path, checking that each component is a
+ * root-owned directory with strict permissions.
+ */
+ do {
+ if ((cp = strrchr(progname, '/')) == NULL)
+ break;
+ else
+ *cp = '\0';
+
+ debug3("%s: checking component '%s'", __func__, progname);
+
+ if (stat(progname, &st) != 0) {
+ error("%s: stat(\"%s\"): %s", __func__,
+ progname, strerror(errno));
+ goto go_away;
+ }
+ if (st.st_uid != 0 || (st.st_mode & 022) != 0) {
+ error("bad ownership or modes for pubkey agent path component \"%s\"",
+ progname);
+ goto go_away;
+ }
+ if (!S_ISDIR(st.st_mode)) {
+ error("pubkey agent path component \"%s\" is not a directory",
+ progname);
+ goto go_away;
+ }
+ } while (0);
+
+ /* open the pipe and read the keys */
+ f = popen (pubkey_agent_string, "r");
+ if (!f) {
+ error("%s: popen (\"%s\", \"r\"): %s", __func__,
+ pubkey_agent_string, strerror (errno));
+ goto go_away;
+ }
+
+ found_key = user_search_key_in_file (f, options.pubkey_agent, key, pw);
+ pclose (f);
+
+go_away:
+ if (tmp_pubkey_agent_string)
+ xfree (tmp_pubkey_agent_string);
+ if (pubkey_agent_string)
+ xfree (pubkey_agent_string);
+
+ if (runas_pw->pw_uid != 0)
+ restore_uid();
+ return found_key;
+}
+#endif
+
+/* check whether given key is in <pkey_agent or .ssh/authorized_keys* */
int
user_key_allowed(struct passwd *pw, Key *key)
{
int success;
char *file;
+#ifdef WITH_PUBKEY_AGENT
+ success = user_key_via_agent_allowed2(pw, key);
+ if (success >= 0)
+ return success;
+#endif
+
if (auth_key_is_revoked(key))
return 0;
if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key))
diff -up openssh-5.4p1/configure.ac.pka openssh-5.4p1/configure.ac
--- openssh-5.4p1/configure.ac.pka 2010-03-09 08:01:04.000000000 +0100
+++ openssh-5.4p1/configure.ac 2010-03-09 08:01:05.000000000 +0100
@@ -1323,6 +1323,18 @@ AC_ARG_WITH(audit,
esac ]
)
+# Check whether user wants pubkey agent support
+PKA_MSG="no"
+AC_ARG_WITH(pka,
+ [ --with-pka Enable pubkey agent support],
+ [
+ if test "x$withval" != "xno" ; then
+ AC_DEFINE([WITH_PUBKEY_AGENT], 1, [Enable pubkey agent support])
+ PKA_MSG="yes"
+ fi
+ ]
+)
+
dnl Checks for library functions. Please keep in alphabetical order
AC_CHECK_FUNCS( \
arc4random \
@@ -4206,6 +4218,7 @@ echo " Linux audit support
echo " Smartcard support: $SCARD_MSG"
echo " S/KEY support: $SKEY_MSG"
echo " TCP Wrappers support: $TCPW_MSG"
+echo " PKA support: $PKA_MSG"
echo " MD5 password support: $MD5_MSG"
echo " libedit support: $LIBEDIT_MSG"
echo " Solaris process contract support: $SPC_MSG"
diff -up openssh-5.4p1/servconf.c.pka openssh-5.4p1/servconf.c
--- openssh-5.4p1/servconf.c.pka 2010-03-09 08:01:04.000000000 +0100
+++ openssh-5.4p1/servconf.c 2010-03-09 09:04:57.000000000 +0100
@@ -129,6 +129,8 @@ initialize_server_options(ServerOptions
options->num_permitted_opens = -1;
options->adm_forced_command = NULL;
options->chroot_directory = NULL;
+ options->pubkey_agent = NULL;
+ options->pubkey_agent_runas = NULL;
options->zero_knowledge_password_authentication = -1;
options->revoked_keys_file = NULL;
options->trusted_user_ca_keys = NULL;
@@ -315,6 +317,7 @@ typedef enum {
sUsePrivilegeSeparation, sAllowAgentForwarding,
sZeroKnowledgePasswordAuthentication, sHostCertificate,
sRevokedKeys, sTrustedUserCAKeys,
+ sPubkeyAgent, sPubkeyAgentRunAs,
sDeprecated, sUnsupported
} ServerOpCodes;
@@ -437,6 +440,13 @@ static struct {
{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
+#ifdef WITH_PUBKEY_AGENT
+ { "pubkeyagent", sPubkeyAgent, SSHCFG_ALL },
+ { "pubkeyagentrunas", sPubkeyAgentRunAs, SSHCFG_ALL },
+#else
+ { "pubkeyagent", sUnsupported, SSHCFG_ALL },
+ { "pubkeyagentrunas", sUnsupported, SSHCFG_ALL },
+#endif
{ NULL, sBadOption, 0 }
};
@@ -1345,6 +1355,20 @@ process_server_config_line(ServerOptions
charptr = &options->revoked_keys_file;
goto parse_filename;
+ case sPubkeyAgent:
+ len = strspn(cp, WHITESPACE);
+ if (*activep && options->pubkey_agent == NULL)
+ options->pubkey_agent = xstrdup(cp + len);
+ return 0;
+
+ case sPubkeyAgentRunAs:
+ charptr = &options->pubkey_agent_runas;
+
+ arg = strdelim(&cp);
+ if (*activep && *charptr == NULL)
+ *charptr = xstrdup(arg);
+ break;
+
case sDeprecated:
logit("%s line %d: Deprecated option %s",
filename, linenum, arg);
@@ -1438,6 +1462,8 @@ copy_set_server_options(ServerOptions *d
M_CP_INTOPT(gss_authentication);
M_CP_INTOPT(rsa_authentication);
M_CP_INTOPT(pubkey_authentication);
+ M_CP_STROPT(pubkey_agent);
+ M_CP_STROPT(pubkey_agent_runas);
M_CP_INTOPT(kerberos_authentication);
M_CP_INTOPT(hostbased_authentication);
M_CP_INTOPT(kbd_interactive_authentication);
@@ -1683,6 +1709,8 @@ dump_config(ServerOptions *o)
dump_cfg_string(sChrootDirectory, o->chroot_directory);
dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
+ dump_cfg_string(sPubkeyAgent, o->pubkey_agent);
+ dump_cfg_string(sPubkeyAgentRunAs, o->pubkey_agent_runas);
/* string arguments requiring a lookup */
dump_cfg_string(sLogLevel, log_level_name(o->log_level));
diff -up openssh-5.4p1/servconf.h.pka openssh-5.4p1/servconf.h
--- openssh-5.4p1/servconf.h.pka 2010-03-09 08:01:04.000000000 +0100
+++ openssh-5.4p1/servconf.h 2010-03-09 09:05:29.000000000 +0100
@@ -157,6 +157,8 @@ typedef struct {
char *chroot_directory;
char *revoked_keys_file;
char *trusted_user_ca_keys;
+ char *pubkey_agent;
+ char *pubkey_agent_runas;
} ServerOptions;
void initialize_server_options(ServerOptions *);
diff -up openssh-5.4p1/sshd_config.0.pka openssh-5.4p1/sshd_config.0
--- openssh-5.4p1/sshd_config.0.pka 2010-03-09 08:01:04.000000000 +0100
+++ openssh-5.4p1/sshd_config.0 2010-03-09 09:07:35.000000000 +0100
@@ -352,7 +352,8 @@ DESCRIPTION
KbdInteractiveAuthentication, KerberosAuthentication,
MaxAuthTries, MaxSessions, PasswordAuthentication,
PermitEmptyPasswords, PermitOpen, PermitRootLogin,
- PubkeyAuthentication, RhostsRSAAuthentication, RSAAuthentication,
+ PubkeyAuthentication, PubkeyAgent, PubkeyAgentRunAs,
+ RhostsRSAAuthentication, RSAAuthentication,
X11DisplayOffset, X11Forwarding and X11UseLocalHost.
MaxAuthTries
@@ -467,6 +468,17 @@ DESCRIPTION
this file is not readable, then public key authentication will be
refused for all users.
+ PubkeyAgent
+ Specifies which agent is used for lookup of the user's public
+ keys. Empty string means to use the authorized_keys file. By
+ default there is no PubkeyAgent set. Note that this option has
+ an effect only with PubkeyAuthentication switched on.
+
+ PubkeyAgentRunAs
+ Specifies the user under whose account the PubkeyAgent is run.
+ Empty string (the default value) means the user being authorized
+ is used.
+
RhostsRSAAuthentication
Specifies whether rhosts or /etc/hosts.equiv authentication to-
gether with successful RSA host authentication is allowed. The
diff -up openssh-5.4p1/sshd_config.5.pka openssh-5.4p1/sshd_config.5
--- openssh-5.4p1/sshd_config.5.pka 2010-03-09 08:01:04.000000000 +0100
+++ openssh-5.4p1/sshd_config.5 2010-03-09 09:06:40.000000000 +0100
@@ -618,6 +618,9 @@ Available keywords are
.Cm KerberosAuthentication ,
.Cm MaxAuthTries ,
.Cm MaxSessions ,
+.Cm PubkeyAuthentication ,
+.Cm PubkeyAgent ,
+.Cm PubkeyAgentRunAs ,
.Cm PasswordAuthentication ,
.Cm PermitEmptyPasswords ,
.Cm PermitOpen ,
@@ -819,6 +822,16 @@ Specifies a list of revoked public keys.
Keys listed in this file will be refused for public key authentication.
Note that if this file is not readable, then public key authentication will
be refused for all users.
++.It Cm PubkeyAgent
++Specifies which agent is used for lookup of the user's public
++keys. Empty string means to use the authorized_keys file.
++By default there is no PubkeyAgent set.
++Note that this option has an effect only with PubkeyAuthentication
++switched on.
++.It Cm PubkeyAgentRunAs
++Specifies the user under whose account the PubkeyAgent is run. Empty
++string (the default value) means the user being authorized is used.
++.Dq
.It Cm RhostsRSAAuthentication
Specifies whether rhosts or /etc/hosts.equiv authentication together
with successful RSA host authentication is allowed.
diff -up openssh-5.4p1/sshd_config.pka openssh-5.4p1/sshd_config
--- openssh-5.4p1/sshd_config.pka 2010-03-09 08:01:04.000000000 +0100
+++ openssh-5.4p1/sshd_config 2010-03-09 08:01:06.000000000 +0100
@@ -45,6 +45,8 @@ SyslogFacility AUTHPRIV
#RSAAuthentication yes
#PubkeyAuthentication yes
#AuthorizedKeysFile .ssh/authorized_keys
+#PubkeyAgent none
+#PubkeyAgentRunAs nobody
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#RhostsRSAAuthentication no

View File

@ -1,157 +0,0 @@
diff -up openssh-5.5p1/session.c.stderr openssh-5.5p1/session.c
--- openssh-5.5p1/session.c.stderr 2010-04-26 10:35:35.000000000 +0200
+++ openssh-5.5p1/session.c 2010-04-26 10:41:11.000000000 +0200
@@ -47,6 +47,7 @@
#include <arpa/inet.h>
#include <errno.h>
+#include <fcntl.h>
#include <grp.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
@@ -447,6 +448,9 @@ do_exec_no_pty(Session *s, const char *c
#ifdef USE_PIPES
int pin[2], pout[2], perr[2];
+ if (s == NULL)
+ fatal("do_exec_no_pty: no session");
+
/* Allocate pipes for communicating with the program. */
if (pipe(pin) < 0) {
error("%s: pipe in: %.100s", __func__, strerror(errno));
@@ -458,33 +462,59 @@ do_exec_no_pty(Session *s, const char *c
close(pin[1]);
return -1;
}
- if (pipe(perr) < 0) {
- error("%s: pipe err: %.100s", __func__, strerror(errno));
- close(pin[0]);
- close(pin[1]);
- close(pout[0]);
- close(pout[1]);
- return -1;
+ if (s->is_subsystem) {
+ if ((perr[1] = open(_PATH_DEVNULL, O_WRONLY)) == -1) {
+ error("%s: open(%s): %s", __func__, _PATH_DEVNULL,
+ strerror(errno));
+ close(pin[0]);
+ close(pin[1]);
+ close(pout[0]);
+ close(pout[1]);
+ return -1;
+ }
+ perr[0] = -1;
+ } else {
+ if (pipe(perr) < 0) {
+ error("%s: pipe err: %.100s", __func__,
+ strerror(errno));
+ close(pin[0]);
+ close(pin[1]);
+ close(pout[0]);
+ close(pout[1]);
+ return -1;
+ }
}
#else
int inout[2], err[2];
+ if (s == NULL)
+ fatal("do_exec_no_pty: no session");
+
/* Uses socket pairs to communicate with the program. */
if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0) {
error("%s: socketpair #1: %.100s", __func__, strerror(errno));
return -1;
}
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0) {
- error("%s: socketpair #2: %.100s", __func__, strerror(errno));
- close(inout[0]);
- close(inout[1]);
- return -1;
+ if (s->is_subsystem) {
+ if ((err[0] = open(_PATH_DEVNULL, O_WRONLY)) == -1) {
+ error("%s: open(%s): %s", __func__, _PATH_DEVNULL,
+ strerror(errno));
+ close(inout[0]);
+ close(inout[1]);
+ return -1;
+ }
+ err[1] = -1;
+ } else {
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0) {
+ error("%s: socketpair #2: %.100s", __func__,
+ strerror(errno));
+ close(inout[0]);
+ close(inout[1]);
+ return -1;
+ }
}
#endif
- if (s == NULL)
- fatal("do_exec_no_pty: no session");
-
session_proctitle(s);
/* Fork the child. */
@@ -496,13 +526,15 @@ do_exec_no_pty(Session *s, const char *c
close(pin[1]);
close(pout[0]);
close(pout[1]);
- close(perr[0]);
+ if (perr[0] != -1)
+ close(perr[0]);
close(perr[1]);
#else
close(inout[0]);
close(inout[1]);
close(err[0]);
- close(err[1]);
+ if (err[1] != -1)
+ close(err[1]);
#endif
return -1;
case 0:
@@ -536,7 +568,8 @@ do_exec_no_pty(Session *s, const char *c
close(pout[1]);
/* Redirect stderr. */
- close(perr[0]);
+ if (perr[0] != -1)
+ close(perr[0]);
if (dup2(perr[1], 2) < 0)
perror("dup2 stderr");
close(perr[1]);
@@ -547,7 +580,8 @@ do_exec_no_pty(Session *s, const char *c
* seem to depend on it.
*/
close(inout[1]);
- close(err[1]);
+ if (err[1] != -1)
+ close(err[1]);
if (dup2(inout[0], 0) < 0) /* stdin */
perror("dup2 stdin");
if (dup2(inout[0], 1) < 0) /* stdout (same as stdin) */
@@ -595,10 +629,6 @@ do_exec_no_pty(Session *s, const char *c
close(perr[1]);
if (compat20) {
- if (s->is_subsystem) {
- close(perr[0]);
- perr[0] = -1;
- }
session_set_fds(s, pin[1], pout[0], perr[0], 0);
} else {
/* Enter the interactive session. */
@@ -615,10 +645,7 @@ do_exec_no_pty(Session *s, const char *c
* handle the case that fdin and fdout are the same.
*/
if (compat20) {
- session_set_fds(s, inout[1], inout[1],
- s->is_subsystem ? -1 : err[1], 0);
- if (s->is_subsystem)
- close(err[1]);
+ session_set_fds(s, inout[1], inout[1], err[1], 0);
} else {
server_loop(pid, inout[1], inout[1], err[1]);
/* server_loop has closed inout[1] and err[1]. */