From 29cc2a20e114d63475ab3cf1f9c9b442b1edfd59 Mon Sep 17 00:00:00 2001 From: djm Date: Sun, 19 Dec 2021 22:12:07 +0000 Subject: [PATCH] prepare for multiple names for authmethods allow authentication methods to have one additional name beyond their primary name. allow lookup by this synonym Use primary name for authentication decisions, e.g. for PermitRootLogin=publickey Pass actual invoked name to the authmethods, so they can tell whether they were requested via the their primary name or synonym. ok markus@ --- usr.bin/ssh/auth.h | 5 +++-- usr.bin/ssh/auth2-gss.c | 5 +++-- usr.bin/ssh/auth2-hostbased.c | 7 ++++--- usr.bin/ssh/auth2-kbdint.c | 5 +++-- usr.bin/ssh/auth2-none.c | 5 +++-- usr.bin/ssh/auth2-passwd.c | 5 +++-- usr.bin/ssh/auth2-pubkey.c | 7 ++++--- usr.bin/ssh/auth2.c | 28 +++++++++++++++++++--------- 8 files changed, 42 insertions(+), 25 deletions(-) diff --git a/usr.bin/ssh/auth.h b/usr.bin/ssh/auth.h index d1d9c8f8141..d9f129518b7 100644 --- a/usr.bin/ssh/auth.h +++ b/usr.bin/ssh/auth.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.h,v 1.101 2020/12/22 00:12:22 djm Exp $ */ +/* $OpenBSD: auth.h,v 1.102 2021/12/19 22:12:07 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -95,7 +95,8 @@ struct Authctxt { struct Authmethod { char *name; - int (*userauth)(struct ssh *); + char *synonym; + int (*userauth)(struct ssh *, const char *); int *enabled; }; diff --git a/usr.bin/ssh/auth2-gss.c b/usr.bin/ssh/auth2-gss.c index 245c5d9bb10..6501a260526 100644 --- a/usr.bin/ssh/auth2-gss.c +++ b/usr.bin/ssh/auth2-gss.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-gss.c,v 1.32 2021/01/27 10:15:08 djm Exp $ */ +/* $OpenBSD: auth2-gss.c,v 1.33 2021/12/19 22:12:07 djm Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -55,7 +55,7 @@ static int input_gssapi_errtok(int, u_int32_t, struct ssh *); * how to check local user kuserok and the like) */ static int -userauth_gssapi(struct ssh *ssh) +userauth_gssapi(struct ssh *ssh, const char *method) { Authctxt *authctxt = ssh->authctxt; gss_OID_desc goid = {0, NULL}; @@ -324,6 +324,7 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) Authmethod method_gssapi = { "gssapi-with-mic", + NULL, userauth_gssapi, &options.gss_authentication }; diff --git a/usr.bin/ssh/auth2-hostbased.c b/usr.bin/ssh/auth2-hostbased.c index cd9523954b2..f99f93e4616 100644 --- a/usr.bin/ssh/auth2-hostbased.c +++ b/usr.bin/ssh/auth2-hostbased.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-hostbased.c,v 1.47 2021/07/23 03:37:52 djm Exp $ */ +/* $OpenBSD: auth2-hostbased.c,v 1.48 2021/12/19 22:12:07 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -56,7 +56,7 @@ extern ServerOptions options; static int -userauth_hostbased(struct ssh *ssh) +userauth_hostbased(struct ssh *ssh, const char *method) { Authctxt *authctxt = ssh->authctxt; struct sshbuf *b; @@ -131,7 +131,7 @@ userauth_hostbased(struct ssh *ssh) (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || (r = sshbuf_put_cstring(b, authctxt->user)) != 0 || (r = sshbuf_put_cstring(b, authctxt->service)) != 0 || - (r = sshbuf_put_cstring(b, "hostbased")) != 0 || + (r = sshbuf_put_cstring(b, method)) != 0 || (r = sshbuf_put_string(b, pkalg, alen)) != 0 || (r = sshbuf_put_string(b, pkblob, blen)) != 0 || (r = sshbuf_put_cstring(b, chost)) != 0 || @@ -254,6 +254,7 @@ hostbased_key_allowed(struct ssh *ssh, struct passwd *pw, Authmethod method_hostbased = { "hostbased", + NULL, userauth_hostbased, &options.hostbased_authentication }; diff --git a/usr.bin/ssh/auth2-kbdint.c b/usr.bin/ssh/auth2-kbdint.c index 1bd12cd8666..034b6eacf60 100644 --- a/usr.bin/ssh/auth2-kbdint.c +++ b/usr.bin/ssh/auth2-kbdint.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-kbdint.c,v 1.13 2021/07/02 05:11:20 dtucker Exp $ */ +/* $OpenBSD: auth2-kbdint.c,v 1.14 2021/12/19 22:12:07 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -42,7 +42,7 @@ extern ServerOptions options; static int -userauth_kbdint(struct ssh *ssh) +userauth_kbdint(struct ssh *ssh, const char *method) { int r, authenticated = 0; char *lang, *devs; @@ -64,6 +64,7 @@ userauth_kbdint(struct ssh *ssh) Authmethod method_kbdint = { "keyboard-interactive", + NULL, userauth_kbdint, &options.kbd_interactive_authentication }; diff --git a/usr.bin/ssh/auth2-none.c b/usr.bin/ssh/auth2-none.c index 6e00b115568..77632030e97 100644 --- a/usr.bin/ssh/auth2-none.c +++ b/usr.bin/ssh/auth2-none.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-none.c,v 1.23 2020/10/18 11:32:01 djm Exp $ */ +/* $OpenBSD: auth2-none.c,v 1.24 2021/12/19 22:12:07 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -50,7 +50,7 @@ extern ServerOptions options; static int none_enabled = 1; static int -userauth_none(struct ssh *ssh) +userauth_none(struct ssh *ssh, const char *method) { int r; @@ -64,6 +64,7 @@ userauth_none(struct ssh *ssh) Authmethod method_none = { "none", + NULL, userauth_none, &none_enabled }; diff --git a/usr.bin/ssh/auth2-passwd.c b/usr.bin/ssh/auth2-passwd.c index 9ff2b20b81b..9c62de149d1 100644 --- a/usr.bin/ssh/auth2-passwd.c +++ b/usr.bin/ssh/auth2-passwd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-passwd.c,v 1.19 2020/10/18 11:32:01 djm Exp $ */ +/* $OpenBSD: auth2-passwd.c,v 1.20 2021/12/19 22:12:07 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -47,7 +47,7 @@ extern ServerOptions options; static int -userauth_passwd(struct ssh *ssh) +userauth_passwd(struct ssh *ssh, const char *method) { char *password; int authenticated = 0, r; @@ -70,6 +70,7 @@ userauth_passwd(struct ssh *ssh) Authmethod method_passwd = { "password", + NULL, userauth_passwd, &options.password_authentication }; diff --git a/usr.bin/ssh/auth2-pubkey.c b/usr.bin/ssh/auth2-pubkey.c index 0575ae6f808..54f6f043c36 100644 --- a/usr.bin/ssh/auth2-pubkey.c +++ b/usr.bin/ssh/auth2-pubkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-pubkey.c,v 1.110 2021/09/29 01:33:32 djm Exp $ */ +/* $OpenBSD: auth2-pubkey.c,v 1.111 2021/12/19 22:12:07 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -83,7 +83,7 @@ format_key(const struct sshkey *key) } static int -userauth_pubkey(struct ssh *ssh) +userauth_pubkey(struct ssh *ssh, const char *method) { Authctxt *authctxt = ssh->authctxt; struct passwd *pw = authctxt->pw; @@ -189,7 +189,7 @@ userauth_pubkey(struct ssh *ssh) if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || (r = sshbuf_put_cstring(b, userstyle)) != 0 || (r = sshbuf_put_cstring(b, authctxt->service)) != 0 || - (r = sshbuf_put_cstring(b, "publickey")) != 0 || + (r = sshbuf_put_cstring(b, method)) != 0 || (r = sshbuf_put_u8(b, have_sig)) != 0 || (r = sshbuf_put_cstring(b, pkalg)) != 0 || (r = sshbuf_put_string(b, pkblob, blen)) != 0) @@ -1064,6 +1064,7 @@ user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key, Authmethod method_pubkey = { "publickey", + NULL, userauth_pubkey, &options.pubkey_authentication }; diff --git a/usr.bin/ssh/auth2.c b/usr.bin/ssh/auth2.c index c21c2e1c1ac..d6cc3d78c8e 100644 --- a/usr.bin/ssh/auth2.c +++ b/usr.bin/ssh/auth2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2.c,v 1.161 2021/04/03 06:18:40 djm Exp $ */ +/* $OpenBSD: auth2.c,v 1.162 2021/12/19 22:12:07 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -314,7 +314,7 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) m = authmethod_lookup(authctxt, method); if (m != NULL && authctxt->failures < options.max_authtries) { debug2("input_userauth_request: try method %s", method); - authenticated = m->userauth(ssh); + authenticated = m->userauth(ssh, method); } if (!authctxt->authenticated) ensure_minimum_time_since(tstart, @@ -329,18 +329,26 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) } void -userauth_finish(struct ssh *ssh, int authenticated, const char *method, +userauth_finish(struct ssh *ssh, int authenticated, const char *packet_method, const char *submethod) { Authctxt *authctxt = ssh->authctxt; + Authmethod *m = NULL; + const char *method = packet_method; char *methods; int r, partial = 0; - if (!authctxt->valid && authenticated) - fatal("INTERNAL ERROR: authenticated invalid user %s", - authctxt->user); - if (authenticated && authctxt->postponed) - fatal("INTERNAL ERROR: authenticated and postponed"); + if (authenticated) { + if (!authctxt->valid) { + fatal("INTERNAL ERROR: authenticated invalid user %s", + authctxt->user); + } + if (authctxt->postponed) + fatal("INTERNAL ERROR: authenticated and postponed"); + if ((m = authmethod_lookup(authctxt, method)) == NULL) + fatal("INTERNAL ERROR: bad method %s", method); + method = m->name; /* prefer primary name to possible synonym */ + } /* Special handling for root */ if (authenticated && authctxt->pw->pw_uid == 0 && @@ -457,7 +465,9 @@ authmethod_lookup(Authctxt *authctxt, const char *name) for (i = 0; authmethods[i] != NULL; i++) if (authmethods[i]->enabled != NULL && *(authmethods[i]->enabled) != 0 && - strcmp(name, authmethods[i]->name) == 0 && + (strcmp(name, authmethods[i]->name) == 0 || + (authmethods[i]->synonym != NULL && + strcmp(name, authmethods[i]->synonym) == 0)) && auth2_method_allowed(authctxt, authmethods[i]->name, NULL)) return authmethods[i]; -- 2.20.1