diff --git a/openssh-6.3p1-force_krb.patch b/openssh-6.3p1-force_krb.patch deleted file mode 100644 index 695c0eb..0000000 --- a/openssh-6.3p1-force_krb.patch +++ /dev/null @@ -1,279 +0,0 @@ -diff -up openssh-6.3p1/gss-serv-krb5.c.force_krb openssh-6.3p1/gss-serv-krb5.c ---- openssh-6.3p1/gss-serv-krb5.c.force_krb 2013-10-11 18:58:51.553948159 +0200 -+++ openssh-6.3p1/gss-serv-krb5.c 2013-10-11 21:40:49.972337025 +0200 -@@ -32,7 +32,9 @@ - #include - - #include -+#include - #include -+#include - - #include "xmalloc.h" - #include "key.h" -@@ -40,10 +42,12 @@ - #include "auth.h" - #include "log.h" - #include "servconf.h" -+#include "misc.h" - - #include "buffer.h" - #include "ssh-gss.h" - -+extern Authctxt *the_authctxt; - extern ServerOptions options; - - #ifdef HEIMDAL -@@ -55,6 +59,13 @@ extern ServerOptions options; - # include - #endif - -+/* all commands are allowed by default */ -+char **k5users_allowed_cmds = NULL; -+ -+static int ssh_gssapi_k5login_exists(); -+static int ssh_gssapi_krb5_cmdok(krb5_principal, const char *, const char *, -+ int); -+ - static krb5_context krb_context = NULL; - - /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ -@@ -87,6 +98,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client - krb5_principal princ; - int retval; - const char *errmsg; -+ int k5login_exists; - - if (ssh_gssapi_krb5_init() == 0) - return 0; -@@ -98,10 +110,22 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client - krb5_free_error_message(krb_context, errmsg); - return 0; - } -- if (krb5_kuserok(krb_context, princ, name)) { -+ /* krb5_kuserok() returns 1 if .k5login DNE and this is self-login. -+ * We have to make sure to check .k5users in that case. */ -+ k5login_exists = ssh_gssapi_k5login_exists(); -+ /* NOTE: .k5login and .k5users must opened as root, not the user, -+ * because if they are on a krb5-protected filesystem, user credentials -+ * to access these files aren't available yet. */ -+ if (krb5_kuserok(krb_context, princ, name) && k5login_exists) { - retval = 1; - logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", - name, (char *)client->displayname.value); -+ } else if (ssh_gssapi_krb5_cmdok(princ, client->exportedname.value, -+ name, k5login_exists)) { -+ retval = 1; -+ logit("Authorized to %s, krb5 principal %s " -+ "(ssh_gssapi_krb5_cmdok)", -+ name, (char *)client->displayname.value); - } else - retval = 0; - -@@ -109,6 +133,135 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client - return retval; - } - -+/* Test for existence of .k5login. -+ * We need this as part of our .k5users check, because krb5_kuserok() -+ * returns success if .k5login DNE and user is logging in as himself. -+ * With .k5login absent and .k5users present, we don't want absence -+ * of .k5login to authorize self-login. (absence of both is required) -+ * Returns 1 if .k5login is available, 0 otherwise. -+ */ -+static int -+ssh_gssapi_k5login_exists() -+{ -+ char file[MAXPATHLEN]; -+ struct passwd *pw = the_authctxt->pw; -+ -+ snprintf(file, sizeof(file), "%s/.k5login", pw->pw_dir); -+ return access(file, F_OK) == 0; -+} -+ -+/* check .k5users for login or command authorization -+ * Returns 1 if principal is authorized, 0 otherwise. -+ * If principal is authorized, (global) k5users_allowed_cmds may be populated. -+ */ -+static int -+ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, -+ const char *luser, int k5login_exists) -+{ -+ FILE *fp; -+ char file[MAXPATHLEN]; -+ char line[BUFSIZ]; -+ char kuser[65]; /* match krb5_kuserok() */ -+ struct stat st; -+ struct passwd *pw = the_authctxt->pw; -+ int found_principal = 0; -+ int ncommands = 0, allcommands = 0; -+ u_long linenum; -+ -+ snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir); -+ /* If both .k5login and .k5users DNE, self-login is ok. */ -+ if (!k5login_exists && (access(file, F_OK) == -1)) { -+ return (krb5_aname_to_localname(krb_context, principal, -+ sizeof(kuser), kuser) == 0) && -+ (strcmp(kuser, luser) == 0); -+ } -+ if ((fp = fopen(file, "r")) == NULL) { -+ int saved_errno = errno; -+ /* 2nd access check to ease debugging if file perms are wrong. -+ * But we don't want to report this if .k5users simply DNE. */ -+ if (access(file, F_OK) == 0) { -+ logit("User %s fopen %s failed: %s", -+ pw->pw_name, file, strerror(saved_errno)); -+ } -+ return 0; -+ } -+ /* .k5users must be owned either by the user or by root */ -+ if (fstat(fileno(fp), &st) == -1) { -+ /* can happen, but very wierd error so report it */ -+ logit("User %s fstat %s failed: %s", -+ pw->pw_name, file, strerror(errno)); -+ fclose(fp); -+ return 0; -+ } -+ if (!(st.st_uid == pw->pw_uid || st.st_uid == 0)) { -+ logit("User %s %s is not owned by root or user", -+ pw->pw_name, file); -+ fclose(fp); -+ return 0; -+ } -+ /* .k5users must be a regular file. krb5_kuserok() doesn't do this -+ * check, but we don't want to be deficient if they add a check. */ -+ if (!S_ISREG(st.st_mode)) { -+ logit("User %s %s is not a regular file", pw->pw_name, file); -+ fclose(fp); -+ return 0; -+ } -+ /* file exists; initialize k5users_allowed_cmds (to none!) */ -+ k5users_allowed_cmds = xcalloc(++ncommands, -+ sizeof(*k5users_allowed_cmds)); -+ -+ /* Check each line. ksu allows unlimited length lines. We don't. */ -+ while (!allcommands && read_keyfile_line(fp, file, line, sizeof(line), -+ &linenum) != -1) { -+ char *token; -+ -+ /* we parse just like ksu, even though we could do better */ -+ if ((token = strtok(line, " \t\n")) == NULL) -+ continue; -+ if (strcmp(name, token) == 0) { -+ /* we matched on client principal */ -+ found_principal = 1; -+ if ((token = strtok(NULL, " \t\n")) == NULL) { -+ /* only shell is allowed */ -+ k5users_allowed_cmds[ncommands-1] = -+ xstrdup(pw->pw_shell); -+ k5users_allowed_cmds = -+ xrealloc(k5users_allowed_cmds, ++ncommands, -+ sizeof(*k5users_allowed_cmds)); -+ break; -+ } -+ /* process the allowed commands */ -+ while (token) { -+ if (strcmp(token, "*") == 0) { -+ allcommands = 1; -+ break; -+ } -+ k5users_allowed_cmds[ncommands-1] = -+ xstrdup(token); -+ k5users_allowed_cmds = -+ xrealloc(k5users_allowed_cmds, ++ncommands, -+ sizeof(*k5users_allowed_cmds)); -+ token = strtok(NULL, " \t\n"); -+ } -+ } -+ } -+ if (k5users_allowed_cmds) { -+ /* terminate vector */ -+ k5users_allowed_cmds[ncommands-1] = NULL; -+ /* if all commands are allowed, free vector */ -+ if (allcommands) { -+ int i; -+ for (i = 0; i < ncommands; i++) { -+ free(k5users_allowed_cmds[i]); -+ } -+ free(k5users_allowed_cmds); -+ k5users_allowed_cmds = NULL; -+ } -+ } -+ fclose(fp); -+ return found_principal; -+} -+ - - /* This writes out any forwarded credentials from the structure populated - * during userauth. Called after we have setuid to the user */ -diff -up openssh-6.3p1/session.c.force_krb openssh-6.3p1/session.c ---- openssh-6.3p1/session.c.force_krb 2013-10-11 18:58:51.487948468 +0200 -+++ openssh-6.3p1/session.c 2013-10-11 18:58:51.563948112 +0200 -@@ -823,6 +823,29 @@ do_exec(Session *s, const char *command) - debug("Forced command (key option) '%.900s'", command); - } - -+#ifdef GSSAPI -+#ifdef KRB5 /* k5users_allowed_cmds only available w/ GSSAPI+KRB5 */ -+ else if (k5users_allowed_cmds) { -+ const char *match = command; -+ int allowed = 0, i = 0; -+ -+ if (!match) -+ match = s->pw->pw_shell; -+ while (k5users_allowed_cmds[i]) { -+ if (strcmp(match, k5users_allowed_cmds[i++]) == 0) { -+ debug("Allowed command '%.900s'", match); -+ allowed = 1; -+ break; -+ } -+ } -+ if (!allowed) { -+ debug("command '%.900s' not allowed", match); -+ return 1; -+ } -+ } -+#endif -+#endif -+ - #ifdef SSH_AUDIT_EVENTS - if (s->command != NULL || s->command_handle != -1) - fatal("do_exec: command already set"); -diff -up openssh-6.3p1/ssh-gss.h.force_krb openssh-6.3p1/ssh-gss.h ---- openssh-6.3p1/ssh-gss.h.force_krb 2013-10-11 18:58:51.558948136 +0200 -+++ openssh-6.3p1/ssh-gss.h 2013-10-11 18:58:51.563948112 +0200 -@@ -49,6 +49,10 @@ - # endif /* !HAVE_DECL_GSS_C_NT_... */ - - # endif /* !HEIMDAL */ -+ -+/* .k5users support */ -+extern char **k5users_allowed_cmds; -+ - #endif /* KRB5 */ - - /* draft-ietf-secsh-gsskeyex-06 */ -diff -up openssh-6.3p1/sshd.8.force_krb openssh-6.3p1/sshd.8 ---- openssh-6.3p1/sshd.8.force_krb 2013-10-11 18:58:51.537948234 +0200 -+++ openssh-6.3p1/sshd.8 2013-10-11 18:58:51.563948112 +0200 -@@ -326,6 +326,7 @@ Finally, the server and the client enter - The client tries to authenticate itself using - host-based authentication, - public key authentication, -+GSSAPI authentication, - challenge-response authentication, - or password authentication. - .Pp -@@ -797,6 +798,12 @@ This file is used in exactly the same wa - but allows host-based authentication without permitting login with - rlogin/rsh. - .Pp -+.It Pa ~/.k5login -+.It Pa ~/.k5users -+These files enforce GSSAPI/Kerberos authentication access control. -+Further details are described in -+.Xr ksu 1 . -+.Pp - .It Pa ~/.ssh/ - This directory is the default location for all user-specific configuration - and authentication information. diff --git a/openssh-6.3p1-increase-size-of-DF-groups.patch b/openssh-6.3p1-increase-size-of-DF-groups.patch deleted file mode 100644 index 941aa72..0000000 --- a/openssh-6.3p1-increase-size-of-DF-groups.patch +++ /dev/null @@ -1,65 +0,0 @@ -diff -U0 openssh-6.3p1/ChangeLog.df openssh-6.3p1/ChangeLog ---- openssh-6.3p1/ChangeLog.df 2013-10-23 22:38:03.476272461 +0200 -+++ openssh-6.3p1/ChangeLog 2013-10-23 22:39:46.051788366 +0200 -@@ -0,0 +1,8 @@ -+20131010 -+ - dtucker@cvs.openbsd.org 2013/10/08 11:42:13 -+ [dh.c dh.h] -+ Increase the size of the Diffie-Hellman groups requested for a each -+ symmetric key size. New values from NIST Special Publication 800-57 with -+ the upper limit specified by RFC4419. Pointed out by Peter Backes, ok -+ djm@. -+ -diff -up openssh-6.3p1/dh.c.df openssh-6.3p1/dh.c ---- openssh-6.3p1/dh.c.df 2013-07-18 08:12:07.000000000 +0200 -+++ openssh-6.3p1/dh.c 2013-10-23 22:38:03.476272461 +0200 -@@ -1,4 +1,4 @@ --/* $OpenBSD: dh.c,v 1.51 2013/07/02 12:31:43 markus Exp $ */ -+/* $OpenBSD: dh.c,v 1.52 2013/10/08 11:42:13 dtucker Exp $ */ - /* - * Copyright (c) 2000 Niels Provos. All rights reserved. - * -@@ -352,17 +352,20 @@ dh_new_group14(void) - - /* - * Estimates the group order for a Diffie-Hellman group that has an -- * attack complexity approximately the same as O(2**bits). Estimate -- * with: O(exp(1.9223 * (ln q)^(1/3) (ln ln q)^(2/3))) -+ * attack complexity approximately the same as O(2**bits). -+ * Values from NIST Special Publication 800-57: Recommendation for Key -+ * Management Part 1 (rev 3) limited by the recommended maximum value -+ * from RFC4419 section 3. - */ - - int - dh_estimate(int bits) - { -- -+ if (bits <= 112) -+ return 2048; - if (bits <= 128) -- return (1024); /* O(2**86) */ -+ return 3072; - if (bits <= 192) -- return (2048); /* O(2**116) */ -- return (4096); /* O(2**156) */ -+ return 7680; -+ return 8192; - } -diff -up openssh-6.3p1/dh.h.df openssh-6.3p1/dh.h ---- openssh-6.3p1/dh.h.df 2008-06-29 14:47:04.000000000 +0200 -+++ openssh-6.3p1/dh.h 2013-10-23 22:38:03.476272461 +0200 -@@ -1,4 +1,4 @@ --/* $OpenBSD: dh.h,v 1.10 2008/06/26 09:19:40 djm Exp $ */ -+/* $OpenBSD: dh.h,v 1.11 2013/10/08 11:42:13 dtucker Exp $ */ - - /* - * Copyright (c) 2000 Niels Provos. All rights reserved. -@@ -43,6 +43,7 @@ int dh_pub_is_valid(DH *, BIGNUM *); - - int dh_estimate(int); - -+/* Min and max values from RFC4419. */ - #define DH_GRP_MIN 1024 - #define DH_GRP_MAX 8192 - diff --git a/openssh-6.3p1-kuserok.patch b/openssh-6.3p1-kuserok.patch deleted file mode 100644 index 60688db..0000000 --- a/openssh-6.3p1-kuserok.patch +++ /dev/null @@ -1,167 +0,0 @@ -diff -up openssh-6.3p1/auth-krb5.c.kuserok openssh-6.3p1/auth-krb5.c ---- openssh-6.3p1/auth-krb5.c.kuserok 2013-10-11 21:41:42.889087613 +0200 -+++ openssh-6.3p1/auth-krb5.c 2013-10-11 21:41:42.905087537 +0200 -@@ -55,6 +55,20 @@ - - extern ServerOptions options; - -+int -+ssh_krb5_kuserok(krb5_context krb5_ctx, krb5_principal krb5_user, const char *client) -+{ -+ if (options.use_kuserok) -+ return krb5_kuserok(krb5_ctx, krb5_user, client); -+ else { -+ char kuser[65]; -+ -+ if (krb5_aname_to_localname(krb5_ctx, krb5_user, sizeof(kuser), kuser)) -+ return 0; -+ return strcmp(kuser, client) == 0; -+ } -+} -+ - static int - krb5_init(void *context) - { -@@ -159,7 +173,7 @@ auth_krb5_password(Authctxt *authctxt, c - if (problem) - goto out; - -- if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) { -+ if (!ssh_krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) { - problem = -1; - goto out; - } -diff -up openssh-6.3p1/gss-serv-krb5.c.kuserok openssh-6.3p1/gss-serv-krb5.c ---- openssh-6.3p1/gss-serv-krb5.c.kuserok 2013-10-11 21:41:42.901087556 +0200 -+++ openssh-6.3p1/gss-serv-krb5.c 2013-10-11 21:46:42.898673597 +0200 -@@ -67,6 +67,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_pr - int); - - static krb5_context krb_context = NULL; -+extern int ssh_krb5_kuserok(krb5_context, krb5_principal, const char *); - - /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ - -@@ -116,7 +117,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client - /* NOTE: .k5login and .k5users must opened as root, not the user, - * because if they are on a krb5-protected filesystem, user credentials - * to access these files aren't available yet. */ -- if (krb5_kuserok(krb_context, princ, name) && k5login_exists) { -+ if (ssh_krb5_kuserok(krb_context, princ, name) && k5login_exists) { - retval = 1; - logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", - name, (char *)client->displayname.value); -diff -up openssh-6.3p1/servconf.c.kuserok openssh-6.3p1/servconf.c ---- openssh-6.3p1/servconf.c.kuserok 2013-10-11 21:41:42.896087580 +0200 -+++ openssh-6.3p1/servconf.c 2013-10-11 21:48:24.664194016 +0200 -@@ -157,6 +157,7 @@ initialize_server_options(ServerOptions - options->ip_qos_interactive = -1; - options->ip_qos_bulk = -1; - options->version_addendum = NULL; -+ options->use_kuserok = -1; - } - - void -@@ -310,6 +311,8 @@ fill_default_server_options(ServerOption - options->version_addendum = xstrdup(""); - if (options->show_patchlevel == -1) - options->show_patchlevel = 0; -+ if (options->use_kuserok == -1) -+ options->use_kuserok = 1; - - /* Turn privilege separation on by default */ - if (use_privsep == -1) -@@ -336,7 +339,7 @@ typedef enum { - sPermitRootLogin, sLogFacility, sLogLevel, - sRhostsRSAAuthentication, sRSAAuthentication, - sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, -- sKerberosGetAFSToken, -+ sKerberosGetAFSToken, sKerberosUseKuserok, - sKerberosTgtPassing, sChallengeResponseAuthentication, - sPasswordAuthentication, sKbdInteractiveAuthentication, - sListenAddress, sAddressFamily, -@@ -409,11 +412,13 @@ static struct { - #else - { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, - #endif -+ { "kerberosusekuserok", sKerberosUseKuserok, SSHCFG_ALL }, - #else - { "kerberosauthentication", sUnsupported, SSHCFG_ALL }, - { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, - { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, - { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, -+ { "kerberosusekuserok", sUnsupported, SSHCFG_ALL }, - #endif - { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, - { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, -@@ -1515,6 +1520,10 @@ process_server_config_line(ServerOptions - *activep = value; - break; - -+ case sKerberosUseKuserok: -+ intptr = &options->use_kuserok; -+ goto parse_flag; -+ - case sPermitOpen: - arg = strdelim(&cp); - if (!arg || *arg == '\0') -@@ -1815,6 +1824,7 @@ copy_set_server_options(ServerOptions *d - M_CP_INTOPT(max_authtries); - M_CP_INTOPT(ip_qos_interactive); - M_CP_INTOPT(ip_qos_bulk); -+ M_CP_INTOPT(use_kuserok); - M_CP_INTOPT(rekey_limit); - M_CP_INTOPT(rekey_interval); - -@@ -2055,6 +2065,7 @@ dump_config(ServerOptions *o) - dump_cfg_fmtint(sUseDNS, o->use_dns); - dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); - dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); -+ dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); - - /* string arguments */ - dump_cfg_string(sPidFile, o->pid_file); -diff -up openssh-6.3p1/servconf.h.kuserok openssh-6.3p1/servconf.h ---- openssh-6.3p1/servconf.h.kuserok 2013-10-11 21:41:42.896087580 +0200 -+++ openssh-6.3p1/servconf.h 2013-10-11 21:41:42.907087528 +0200 -@@ -174,6 +174,7 @@ typedef struct { - - int num_permitted_opens; - -+ int use_kuserok; - char *chroot_directory; - char *revoked_keys_file; - char *trusted_user_ca_keys; -diff -up openssh-6.3p1/sshd_config.5.kuserok openssh-6.3p1/sshd_config.5 ---- openssh-6.3p1/sshd_config.5.kuserok 2013-10-11 21:41:42.898087571 +0200 -+++ openssh-6.3p1/sshd_config.5 2013-10-11 21:41:42.907087528 +0200 -@@ -675,6 +675,10 @@ Specifies whether to automatically destr - file on logout. - The default is - .Dq yes . -+.It Cm KerberosUseKuserok -+Specifies whether to look at .k5login file for user's aliases. -+The default is -+.Dq yes . - .It Cm KexAlgorithms - Specifies the available KEX (Key Exchange) algorithms. - Multiple algorithms must be comma-separated. -@@ -833,6 +837,7 @@ Available keywords are - .Cm HostbasedUsesNameFromPacketOnly , - .Cm KbdInteractiveAuthentication , - .Cm KerberosAuthentication , -+.Cm KerberosUseKuserok , - .Cm MaxAuthTries , - .Cm MaxSessions , - .Cm PasswordAuthentication , -diff -up openssh-6.3p1/sshd_config.kuserok openssh-6.3p1/sshd_config ---- openssh-6.3p1/sshd_config.kuserok 2013-10-11 21:41:42.898087571 +0200 -+++ openssh-6.3p1/sshd_config 2013-10-11 21:41:42.907087528 +0200 -@@ -86,6 +86,7 @@ ChallengeResponseAuthentication no - #KerberosOrLocalPasswd yes - #KerberosTicketCleanup yes - #KerberosGetAFSToken no -+#KerberosUseKuserok yes - - # GSSAPI options - #GSSAPIAuthentication no diff --git a/openssh-6.4p1-ignore-bad-env-var.patch b/openssh-6.4p1-ignore-bad-env-var.patch deleted file mode 100644 index 3bb49c2..0000000 --- a/openssh-6.4p1-ignore-bad-env-var.patch +++ /dev/null @@ -1,37 +0,0 @@ -diff -U0 openssh-6.4p1/ChangeLog.bad-env-var openssh-6.4p1/ChangeLog ---- openssh-6.4p1/ChangeLog.bad-env-var 2014-03-19 21:37:36.270509907 +0100 -+++ openssh-6.4p1/ChangeLog 2014-03-19 21:37:36.276509878 +0100 -@@ -0,0 +1,7 @@ -+20140304 -+ - OpenBSD CVS Sync -+ - djm@cvs.openbsd.org 2014/03/03 22:22:30 -+ [session.c] -+ ignore enviornment variables with embedded '=' or '\0' characters; -+ spotted by Jann Horn; ok deraadt@ -+ -diff -up openssh-6.4p1/session.c.bad-env-var openssh-6.4p1/session.c ---- openssh-6.4p1/session.c.bad-env-var 2014-03-19 21:37:36.233510090 +0100 -+++ openssh-6.4p1/session.c 2014-03-19 21:37:36.277509873 +0100 -@@ -990,6 +990,11 @@ child_set_env(char ***envp, u_int *envsi - u_int envsize; - u_int i, namelen; - -+ if (strchr(name, '=') != NULL) { -+ error("Invalid environment variable \"%.100s\"", name); -+ return; -+ } -+ - /* - * If we're passed an uninitialized list, allocate a single null - * entry before continuing. -@@ -2255,8 +2260,8 @@ session_env_req(Session *s) - char *name, *val; - u_int name_len, val_len, i; - -- name = packet_get_string(&name_len); -- val = packet_get_string(&val_len); -+ name = packet_get_cstring(&name_len); -+ val = packet_get_cstring(&val_len); - packet_check_eom(); - - /* Don't set too many environment variables */ diff --git a/openssh-6.6p1-force_krb.patch b/openssh-6.6p1-force_krb.patch new file mode 100644 index 0000000..a242394 --- /dev/null +++ b/openssh-6.6p1-force_krb.patch @@ -0,0 +1,283 @@ +diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c +index 42de994..60de320 100644 +--- a/gss-serv-krb5.c ++++ b/gss-serv-krb5.c +@@ -32,7 +32,9 @@ + #include + + #include ++#include + #include ++#include + + #include "xmalloc.h" + #include "key.h" +@@ -40,10 +42,12 @@ + #include "auth.h" + #include "log.h" + #include "servconf.h" ++#include "misc.h" + + #include "buffer.h" + #include "ssh-gss.h" + ++extern Authctxt *the_authctxt; + extern ServerOptions options; + + #ifdef HEIMDAL +@@ -55,6 +59,13 @@ extern ServerOptions options; + # include + #endif + ++/* all commands are allowed by default */ ++char **k5users_allowed_cmds = NULL; ++ ++static int ssh_gssapi_k5login_exists(); ++static int ssh_gssapi_krb5_cmdok(krb5_principal, const char *, const char *, ++ int); ++ + static krb5_context krb_context = NULL; + + /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ +@@ -87,6 +98,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) + krb5_principal princ; + int retval; + const char *errmsg; ++ int k5login_exists; + + if (ssh_gssapi_krb5_init() == 0) + return 0; +@@ -98,10 +110,22 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) + krb5_free_error_message(krb_context, errmsg); + return 0; + } +- if (krb5_kuserok(krb_context, princ, name)) { ++ /* krb5_kuserok() returns 1 if .k5login DNE and this is self-login. ++ * We have to make sure to check .k5users in that case. */ ++ k5login_exists = ssh_gssapi_k5login_exists(); ++ /* NOTE: .k5login and .k5users must opened as root, not the user, ++ * because if they are on a krb5-protected filesystem, user credentials ++ * to access these files aren't available yet. */ ++ if (krb5_kuserok(krb_context, princ, name) && k5login_exists) { + retval = 1; + logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", + name, (char *)client->displayname.value); ++ } else if (ssh_gssapi_krb5_cmdok(princ, client->exportedname.value, ++ name, k5login_exists)) { ++ retval = 1; ++ logit("Authorized to %s, krb5 principal %s " ++ "(ssh_gssapi_krb5_cmdok)", ++ name, (char *)client->displayname.value); + } else + retval = 0; + +@@ -109,6 +133,135 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) + return retval; + } + ++/* Test for existence of .k5login. ++ * We need this as part of our .k5users check, because krb5_kuserok() ++ * returns success if .k5login DNE and user is logging in as himself. ++ * With .k5login absent and .k5users present, we don't want absence ++ * of .k5login to authorize self-login. (absence of both is required) ++ * Returns 1 if .k5login is available, 0 otherwise. ++ */ ++static int ++ssh_gssapi_k5login_exists() ++{ ++ char file[MAXPATHLEN]; ++ struct passwd *pw = the_authctxt->pw; ++ ++ snprintf(file, sizeof(file), "%s/.k5login", pw->pw_dir); ++ return access(file, F_OK) == 0; ++} ++ ++/* check .k5users for login or command authorization ++ * Returns 1 if principal is authorized, 0 otherwise. ++ * If principal is authorized, (global) k5users_allowed_cmds may be populated. ++ */ ++static int ++ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name, ++ const char *luser, int k5login_exists) ++{ ++ FILE *fp; ++ char file[MAXPATHLEN]; ++ char line[BUFSIZ]; ++ char kuser[65]; /* match krb5_kuserok() */ ++ struct stat st; ++ struct passwd *pw = the_authctxt->pw; ++ int found_principal = 0; ++ int ncommands = 0, allcommands = 0; ++ u_long linenum; ++ ++ snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir); ++ /* If both .k5login and .k5users DNE, self-login is ok. */ ++ if (!k5login_exists && (access(file, F_OK) == -1)) { ++ return (krb5_aname_to_localname(krb_context, principal, ++ sizeof(kuser), kuser) == 0) && ++ (strcmp(kuser, luser) == 0); ++ } ++ if ((fp = fopen(file, "r")) == NULL) { ++ int saved_errno = errno; ++ /* 2nd access check to ease debugging if file perms are wrong. ++ * But we don't want to report this if .k5users simply DNE. */ ++ if (access(file, F_OK) == 0) { ++ logit("User %s fopen %s failed: %s", ++ pw->pw_name, file, strerror(saved_errno)); ++ } ++ return 0; ++ } ++ /* .k5users must be owned either by the user or by root */ ++ if (fstat(fileno(fp), &st) == -1) { ++ /* can happen, but very wierd error so report it */ ++ logit("User %s fstat %s failed: %s", ++ pw->pw_name, file, strerror(errno)); ++ fclose(fp); ++ return 0; ++ } ++ if (!(st.st_uid == pw->pw_uid || st.st_uid == 0)) { ++ logit("User %s %s is not owned by root or user", ++ pw->pw_name, file); ++ fclose(fp); ++ return 0; ++ } ++ /* .k5users must be a regular file. krb5_kuserok() doesn't do this ++ * check, but we don't want to be deficient if they add a check. */ ++ if (!S_ISREG(st.st_mode)) { ++ logit("User %s %s is not a regular file", pw->pw_name, file); ++ fclose(fp); ++ return 0; ++ } ++ /* file exists; initialize k5users_allowed_cmds (to none!) */ ++ k5users_allowed_cmds = xcalloc(++ncommands, ++ sizeof(*k5users_allowed_cmds)); ++ ++ /* Check each line. ksu allows unlimited length lines. We don't. */ ++ while (!allcommands && read_keyfile_line(fp, file, line, sizeof(line), ++ &linenum) != -1) { ++ char *token; ++ ++ /* we parse just like ksu, even though we could do better */ ++ if ((token = strtok(line, " \t\n")) == NULL) ++ continue; ++ if (strcmp(name, token) == 0) { ++ /* we matched on client principal */ ++ found_principal = 1; ++ if ((token = strtok(NULL, " \t\n")) == NULL) { ++ /* only shell is allowed */ ++ k5users_allowed_cmds[ncommands-1] = ++ xstrdup(pw->pw_shell); ++ k5users_allowed_cmds = ++ xrealloc(k5users_allowed_cmds, ++ncommands, ++ sizeof(*k5users_allowed_cmds)); ++ break; ++ } ++ /* process the allowed commands */ ++ while (token) { ++ if (strcmp(token, "*") == 0) { ++ allcommands = 1; ++ break; ++ } ++ k5users_allowed_cmds[ncommands-1] = ++ xstrdup(token); ++ k5users_allowed_cmds = ++ xrealloc(k5users_allowed_cmds, ++ncommands, ++ sizeof(*k5users_allowed_cmds)); ++ token = strtok(NULL, " \t\n"); ++ } ++ } ++ } ++ if (k5users_allowed_cmds) { ++ /* terminate vector */ ++ k5users_allowed_cmds[ncommands-1] = NULL; ++ /* if all commands are allowed, free vector */ ++ if (allcommands) { ++ int i; ++ for (i = 0; i < ncommands; i++) { ++ free(k5users_allowed_cmds[i]); ++ } ++ free(k5users_allowed_cmds); ++ k5users_allowed_cmds = NULL; ++ } ++ } ++ fclose(fp); ++ return found_principal; ++} ++ + + /* This writes out any forwarded credentials from the structure populated + * during userauth. Called after we have setuid to the user */ +diff --git a/session.c b/session.c +index b5dc144..ba4589b 100644 +--- a/session.c ++++ b/session.c +@@ -806,6 +806,29 @@ do_exec(Session *s, const char *command) + command = forced_command; + forced = "(key-option)"; + } ++#ifdef GSSAPI ++#ifdef KRB5 /* k5users_allowed_cmds only available w/ GSSAPI+KRB5 */ ++ else if (k5users_allowed_cmds) { ++ const char *match = command; ++ int allowed = 0, i = 0; ++ ++ if (!match) ++ match = s->pw->pw_shell; ++ while (k5users_allowed_cmds[i]) { ++ if (strcmp(match, k5users_allowed_cmds[i++]) == 0) { ++ debug("Allowed command '%.900s'", match); ++ allowed = 1; ++ break; ++ } ++ } ++ if (!allowed) { ++ debug("command '%.900s' not allowed", match); ++ return 1; ++ } ++ } ++#endif ++#endif ++ + if (forced != NULL) { + if (IS_INTERNAL_SFTP(command)) { + s->is_subsystem = s->is_subsystem ? +diff --git a/ssh-gss.h b/ssh-gss.h +index 0374c88..509109a 100644 +--- a/ssh-gss.h ++++ b/ssh-gss.h +@@ -49,6 +49,10 @@ + # endif /* !HAVE_DECL_GSS_C_NT_... */ + + # endif /* !HEIMDAL */ ++ ++/* .k5users support */ ++extern char **k5users_allowed_cmds; ++ + #endif /* KRB5 */ + + /* draft-ietf-secsh-gsskeyex-06 */ +diff --git a/sshd.8 b/sshd.8 +index 058d37a..5c4f15b 100644 +--- a/sshd.8 ++++ b/sshd.8 +@@ -327,6 +327,7 @@ Finally, the server and the client enter an authentication dialog. + The client tries to authenticate itself using + host-based authentication, + public key authentication, ++GSSAPI authentication, + challenge-response authentication, + or password authentication. + .Pp +@@ -800,6 +801,12 @@ This file is used in exactly the same way as + but allows host-based authentication without permitting login with + rlogin/rsh. + .Pp ++.It Pa ~/.k5login ++.It Pa ~/.k5users ++These files enforce GSSAPI/Kerberos authentication access control. ++Further details are described in ++.Xr ksu 1 . ++.Pp + .It Pa ~/.ssh/ + This directory is the default location for all user-specific configuration + and authentication information. diff --git a/openssh-6.6p1-kuserok.patch b/openssh-6.6p1-kuserok.patch new file mode 100644 index 0000000..d2d07b6 --- /dev/null +++ b/openssh-6.6p1-kuserok.patch @@ -0,0 +1,168 @@ +diff -up openssh-6.6p1/auth-krb5.c.kuserok openssh-6.6p1/auth-krb5.c +--- openssh-6.6p1/auth-krb5.c.kuserok 2013-10-24 01:53:02.000000000 +0200 ++++ openssh-6.6p1/auth-krb5.c 2014-05-07 10:42:00.883534478 +0200 +@@ -54,6 +54,20 @@ + + extern ServerOptions options; + ++int ++ssh_krb5_kuserok(krb5_context krb5_ctx, krb5_principal krb5_user, const char *client) ++{ ++ if (options.use_kuserok) ++ return krb5_kuserok(krb5_ctx, krb5_user, client); ++ else { ++ char kuser[65]; ++ ++ if (krb5_aname_to_localname(krb5_ctx, krb5_user, sizeof(kuser), kuser)) ++ return 0; ++ return strcmp(kuser, client) == 0; ++ } ++} ++ + static int + krb5_init(void *context) + { +@@ -157,8 +171,7 @@ auth_krb5_password(Authctxt *authctxt, c + if (problem) + goto out; + +- if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, +- authctxt->pw->pw_name)) { ++ if (!ssh_krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, authctxt->pw->pw_name)) { + problem = -1; + goto out; + } +diff -up openssh-6.6p1/gss-serv-krb5.c.kuserok openssh-6.6p1/gss-serv-krb5.c +--- openssh-6.6p1/gss-serv-krb5.c.kuserok 2014-05-07 10:35:30.792053846 +0200 ++++ openssh-6.6p1/gss-serv-krb5.c 2014-05-07 10:35:30.801053812 +0200 +@@ -67,6 +67,7 @@ static int ssh_gssapi_krb5_cmdok(krb5_pr + int); + + static krb5_context krb_context = NULL; ++extern int ssh_krb5_kuserok(krb5_context, krb5_principal, const char *); + + /* Initialise the krb5 library, for the stuff that GSSAPI won't do */ + +@@ -116,7 +117,7 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client + /* NOTE: .k5login and .k5users must opened as root, not the user, + * because if they are on a krb5-protected filesystem, user credentials + * to access these files aren't available yet. */ +- if (krb5_kuserok(krb_context, princ, name) && k5login_exists) { ++ if (ssh_krb5_kuserok(krb_context, princ, name) && k5login_exists) { + retval = 1; + logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", + name, (char *)client->displayname.value); +diff -up openssh-6.6p1/servconf.c.kuserok openssh-6.6p1/servconf.c +--- openssh-6.6p1/servconf.c.kuserok 2014-05-07 10:35:30.783053881 +0200 ++++ openssh-6.6p1/servconf.c 2014-05-07 10:39:13.133189061 +0200 +@@ -157,6 +157,7 @@ initialize_server_options(ServerOptions + options->ip_qos_interactive = -1; + options->ip_qos_bulk = -1; + options->version_addendum = NULL; ++ options->use_kuserok = -1; + } + + void +@@ -312,6 +313,8 @@ fill_default_server_options(ServerOption + options->version_addendum = xstrdup(""); + if (options->show_patchlevel == -1) + options->show_patchlevel = 0; ++ if (options->use_kuserok == -1) ++ options->use_kuserok = 0; + + /* Turn privilege separation on by default */ + if (use_privsep == -1) +@@ -338,7 +341,7 @@ typedef enum { + sPermitRootLogin, sLogFacility, sLogLevel, + sRhostsRSAAuthentication, sRSAAuthentication, + sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, +- sKerberosGetAFSToken, ++ sKerberosGetAFSToken, sKerberosUseKuserok, + sKerberosTgtPassing, sChallengeResponseAuthentication, + sPasswordAuthentication, sKbdInteractiveAuthentication, + sListenAddress, sAddressFamily, +@@ -410,11 +413,13 @@ static struct { + #else + { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, + #endif ++ { "kerberosusekuserok", sKerberosUseKuserok, SSHCFG_ALL }, + #else + { "kerberosauthentication", sUnsupported, SSHCFG_ALL }, + { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, + { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, + { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, ++ { "kerberosusekuserok", sUnsupported, SSHCFG_ALL }, + #endif + { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, + { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, +@@ -1526,6 +1531,10 @@ process_server_config_line(ServerOptions + *activep = value; + break; + ++ case sKerberosUseKuserok: ++ intptr = &options->use_kuserok; ++ goto parse_flag; ++ + case sPermitOpen: + arg = strdelim(&cp); + if (!arg || *arg == '\0') +@@ -1811,6 +1820,7 @@ copy_set_server_options(ServerOptions *d + M_CP_INTOPT(max_authtries); + M_CP_INTOPT(ip_qos_interactive); + M_CP_INTOPT(ip_qos_bulk); ++ M_CP_INTOPT(use_kuserok); + M_CP_INTOPT(rekey_limit); + M_CP_INTOPT(rekey_interval); + +@@ -2062,6 +2072,7 @@ dump_config(ServerOptions *o) + dump_cfg_fmtint(sUseDNS, o->use_dns); + dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); + dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); ++ dump_cfg_fmtint(sKerberosUseKuserok, o->use_kuserok); + + /* string arguments */ + dump_cfg_string(sPidFile, o->pid_file); +diff -up openssh-6.6p1/servconf.h.kuserok openssh-6.6p1/servconf.h +--- openssh-6.6p1/servconf.h.kuserok 2014-05-07 10:35:30.783053881 +0200 ++++ openssh-6.6p1/servconf.h 2014-05-07 10:35:30.802053808 +0200 +@@ -173,6 +173,7 @@ typedef struct { + + int num_permitted_opens; + ++ int use_kuserok; + char *chroot_directory; + char *revoked_keys_file; + char *trusted_user_ca_keys; +diff -up openssh-6.6p1/sshd_config.5.kuserok openssh-6.6p1/sshd_config.5 +--- openssh-6.6p1/sshd_config.5.kuserok 2014-05-07 10:35:30.786053870 +0200 ++++ openssh-6.6p1/sshd_config.5 2014-05-07 10:43:04.784285016 +0200 +@@ -697,6 +697,10 @@ Specifies whether to automatically destr + file on logout. + The default is + .Dq yes . ++.It Cm KerberosUseKuserok ++Specifies whether to look at .k5login file for user's aliases. ++The default is ++.Dq no . + .It Cm KexAlgorithms + Specifies the available KEX (Key Exchange) algorithms. + Multiple algorithms must be comma-separated. +@@ -862,6 +866,7 @@ Available keywords are + .Cm HostbasedUsesNameFromPacketOnly , + .Cm KbdInteractiveAuthentication , + .Cm KerberosAuthentication , ++.Cm KerberosUseKuserok , + .Cm MaxAuthTries , + .Cm MaxSessions , + .Cm PasswordAuthentication , +diff -up openssh-6.6p1/sshd_config.kuserok openssh-6.6p1/sshd_config +--- openssh-6.6p1/sshd_config.kuserok 2014-05-07 10:35:30.803053804 +0200 ++++ openssh-6.6p1/sshd_config 2014-05-07 10:38:30.735354431 +0200 +@@ -87,6 +87,7 @@ ChallengeResponseAuthentication no + #KerberosOrLocalPasswd yes + #KerberosTicketCleanup yes + #KerberosGetAFSToken no ++#KerberosUseKuserok no + + # GSSAPI options + GSSAPIAuthentication yes