diff options
author | CoprDistGit <infra@openeuler.org> | 2023-10-02 04:02:17 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2023-10-02 04:02:17 +0000 |
commit | 24b6ed9bc1ef1538b8f3e254b30b1006f5e4d78f (patch) | |
tree | e2725d205951345a1c853965086be06d6a6cbf59 /openssh-6.6p1-force_krb.patch | |
parent | c7ba49a1e66ed27d507eafa4da2b81838a2afa64 (diff) |
automatic import of openssh
Diffstat (limited to 'openssh-6.6p1-force_krb.patch')
-rw-r--r-- | openssh-6.6p1-force_krb.patch | 280 |
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. |