summaryrefslogtreecommitdiff
path: root/openssh-6.6p1-force_krb.patch
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2023-10-02 04:02:17 +0000
committerCoprDistGit <infra@openeuler.org>2023-10-02 04:02:17 +0000
commit24b6ed9bc1ef1538b8f3e254b30b1006f5e4d78f (patch)
treee2725d205951345a1c853965086be06d6a6cbf59 /openssh-6.6p1-force_krb.patch
parentc7ba49a1e66ed27d507eafa4da2b81838a2afa64 (diff)
automatic import of openssh
Diffstat (limited to 'openssh-6.6p1-force_krb.patch')
-rw-r--r--openssh-6.6p1-force_krb.patch280
1 files changed, 280 insertions, 0 deletions
diff --git a/openssh-6.6p1-force_krb.patch b/openssh-6.6p1-force_krb.patch
new file mode 100644
index 0000000..90f8322
--- /dev/null
+++ b/openssh-6.6p1-force_krb.patch
@@ -0,0 +1,280 @@
+diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
+index 413b845..54dd383 100644
+--- a/gss-serv-krb5.c
++++ b/gss-serv-krb5.c
+@@ -32,7 +32,9 @@
+ #include <sys/types.h>
+
+ #include <stdarg.h>
++#include <stdio.h>
+ #include <string.h>
++#include <unistd.h>
+
+ #include "xmalloc.h"
+ #include "sshkey.h"
+@@ -45,6 +47,7 @@
+
+ #include "ssh-gss.h"
+
++extern Authctxt *the_authctxt;
+ extern ServerOptions options;
+
+ #ifdef HEIMDAL
+@@ -56,6 +59,13 @@ extern ServerOptions options;
+ # include <gssapi/gssapi_krb5.h>
+ #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 */
+@@ -88,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;
+@@ -99,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;
+
+@@ -110,6 +133,137 @@ 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 = NULL;
++ 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 = 0;
++ size_t linesize = 0;
++
++ 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. */
++ while (!allcommands && getline(&line, &linesize, fp) != -1) {
++ linenum++;
++ 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 =
++ xreallocarray(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 =
++ xreallocarray(k5users_allowed_cmds, ++ncommands,
++ sizeof(*k5users_allowed_cmds));
++ token = strtok(NULL, " \t\n");
++ }
++ }
++ }
++ free(line);
++ 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 28659ec..9c94d8e 100644
+--- a/session.c
++++ b/session.c
+@@ -789,6 +789,29 @@ do_exec(Session *s, const char *command)
+ command = auth_opts->force_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
++
+ s->forced = 0;
+ if (forced != NULL) {
+ s->forced = 1;
+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 adcaaf9..824163b 100644
+--- a/sshd.8
++++ b/sshd.8
+@@ -324,6 +324,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.