mirror of
https://github.com/openssh/openssh-portable.git
synced 2026-11-06 05:16:43 +00:00
upstream: make StrictModes apply to ~/.k5login and the home
directory that contains it, just like how it applies to other authn-critical files. Anthropic ANT-2026-W7F2ULDN OpenBSD-Commit-ID: 33363fe797e8628906840bbd29254a24f5925c48
This commit is contained in:
1 parent
a73db88df0
commit
2247550884
4 files changed
+60
-12
No files matched your search
+50
-4
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: gss-serv-krb5.c,v 1.10 2026/02/08 15:28:01 dtucker Exp $ */
|
||||
/* $OpenBSD: gss-serv-krb5.c,v 1.11 2026/10/30 04:52:11 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
|
||||
@@ -30,8 +30,11 @@
|
||||
#ifdef KRB5
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
@@ -76,13 +79,53 @@ ssh_gssapi_krb5_init(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* krb5_kuserok() consults the user's ~/.k5login but may check no more than
|
||||
* its owner, so when StrictModes is set subject it and the home directory
|
||||
* to the same ownership and mode checks as the user's other access lists
|
||||
* (authorized_keys, .shosts, etc).
|
||||
* Returns true if they are safe to use, otherwise returns 0
|
||||
*/
|
||||
|
||||
static int
|
||||
ssh_gssapi_krb5_k5login_ok(struct passwd *pw)
|
||||
{
|
||||
struct stat st;
|
||||
char *path, err[1024];
|
||||
int ok = 1;
|
||||
|
||||
if (!options.strict_modes)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Check the home directory first: anyone who can write to it can
|
||||
* supply a .k5login, and safe_path() does not see the directory a
|
||||
* symlink was planted in, only the one its target lives in.
|
||||
*/
|
||||
if (stat(pw->pw_dir, &st) == 0 &&
|
||||
((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
|
||||
(st.st_mode & 022) != 0)) {
|
||||
logit("Authentication refused for %.100s: bad ownership or "
|
||||
"modes for home directory %.200s", pw->pw_name, pw->pw_dir);
|
||||
return 0;
|
||||
}
|
||||
xasprintf(&path, "%s/.k5login", pw->pw_dir);
|
||||
if (stat(path, &st) == 0 && safe_path(path, &st, pw->pw_dir,
|
||||
pw->pw_uid, err, sizeof(err)) != 0) {
|
||||
logit("Authentication refused: %s", err);
|
||||
ok = 0;
|
||||
}
|
||||
free(path);
|
||||
return ok;
|
||||
}
|
||||
|
||||
/* Check if this user is OK to login. This only works with krb5 - other
|
||||
* GSSAPI mechanisms will need their own.
|
||||
* Returns true if the user is OK to log in, otherwise returns 0
|
||||
*/
|
||||
|
||||
static int
|
||||
ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
|
||||
ssh_gssapi_krb5_userok(ssh_gssapi_client *client, struct passwd *pw)
|
||||
{
|
||||
krb5_principal princ;
|
||||
int retval;
|
||||
@@ -91,6 +134,9 @@ ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
|
||||
if (ssh_gssapi_krb5_init() == 0)
|
||||
return 0;
|
||||
|
||||
if (!ssh_gssapi_krb5_k5login_ok(pw))
|
||||
return 0;
|
||||
|
||||
if ((retval = krb5_parse_name(krb_context, client->exportedname.value,
|
||||
&princ))) {
|
||||
errmsg = krb5_get_error_message(krb_context, retval);
|
||||
@@ -98,10 +144,10 @@ 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)) {
|
||||
if (krb5_kuserok(krb_context, princ, pw->pw_name)) {
|
||||
retval = 1;
|
||||
logit("Authorized to %s, krb5 principal %s (krb5_kuserok)",
|
||||
name, (char *)client->displayname.value);
|
||||
pw->pw_name, (char *)client->displayname.value);
|
||||
} else
|
||||
retval = 0;
|
||||
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: gss-serv.c,v 1.40 2026/10/07 09:00:11 robert Exp $ */
|
||||
/* $OpenBSD: gss-serv.c,v 1.41 2026/10/30 04:52:11 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
|
||||
@@ -380,7 +380,7 @@ ssh_gssapi_cleanup_global_client(void)
|
||||
|
||||
/* Privileged */
|
||||
int
|
||||
ssh_gssapi_userok(char *user)
|
||||
ssh_gssapi_userok(struct passwd *pw)
|
||||
{
|
||||
if (gssapi_client.exportedname.length == 0 ||
|
||||
gssapi_client.exportedname.value == NULL) {
|
||||
@@ -388,7 +388,7 @@ ssh_gssapi_userok(char *user)
|
||||
return 0;
|
||||
}
|
||||
if (gssapi_client.mech && gssapi_client.mech->userok)
|
||||
if ((*gssapi_client.mech->userok)(&gssapi_client, user)) {
|
||||
if ((*gssapi_client.mech->userok)(&gssapi_client, pw)) {
|
||||
gssapi_client.userok = 1;
|
||||
return 1;
|
||||
} else {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: monitor.c,v 1.262 2026/10/30 04:40:03 djm Exp $ */
|
||||
/* $OpenBSD: monitor.c,v 1.263 2026/10/30 04:52:11 djm Exp $ */
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
||||
@@ -2096,7 +2096,7 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m)
|
||||
if (!options.gss_authentication)
|
||||
fatal_f("GSSAPI authentication not enabled");
|
||||
|
||||
authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user);
|
||||
authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->pw);
|
||||
|
||||
sshbuf_reset(m);
|
||||
if ((r = sshbuf_put_u32(m, authenticated)) != 0)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ssh-gss.h,v 1.19 2026/10/07 09:00:11 robert Exp $ */
|
||||
/* $OpenBSD: ssh-gss.h,v 1.20 2026/10/30 04:52:11 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
|
||||
*
|
||||
@@ -61,6 +61,8 @@
|
||||
|
||||
#define SSH_GSS_OIDTYPE 0x06
|
||||
|
||||
struct passwd;
|
||||
|
||||
typedef struct {
|
||||
char *filename;
|
||||
char *envvar;
|
||||
@@ -82,7 +84,7 @@ typedef struct ssh_gssapi_mech_struct {
|
||||
char *name;
|
||||
gss_OID_desc oid;
|
||||
int (*dochild) (ssh_gssapi_client *);
|
||||
int (*userok) (ssh_gssapi_client *, char *);
|
||||
int (*userok) (ssh_gssapi_client *, struct passwd *);
|
||||
int (*localname) (ssh_gssapi_client *, char **);
|
||||
void (*storecreds) (ssh_gssapi_client *);
|
||||
} ssh_gssapi_mech;
|
||||
@@ -127,7 +129,7 @@ int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *);
|
||||
|
||||
/* In the server */
|
||||
OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
|
||||
int ssh_gssapi_userok(char *name);
|
||||
int ssh_gssapi_userok(struct passwd *);
|
||||
OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
|
||||
void ssh_gssapi_do_child(char ***, u_int *);
|
||||
void ssh_gssapi_cleanup_creds(void);
|
||||
|
||||
Reference in new issue
Block a user