From 7c856857607112a3dfe6414696bf4c7ab7fb0cb3 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Sat, 3 Mar 2018 03:15:51 +0000 Subject: upstream: switch over to the new authorized_keys options API and remove the legacy one. Includes a fairly big refactor of auth2-pubkey.c to retain less state between key file lines. feedback and ok markus@ OpenBSD-Commit-ID: dece6cae0f47751b9892080eb13d6625599573df --- monitor.c | 70 ++++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 25 deletions(-) (limited to 'monitor.c') diff --git a/monitor.c b/monitor.c index e4ac3ccfd..c68e1b0d9 100644 --- a/monitor.c +++ b/monitor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.c,v 1.179 2018/02/05 05:37:46 tb Exp $ */ +/* $OpenBSD: monitor.c,v 1.180 2018/03/03 03:15:51 djm Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -116,6 +116,7 @@ extern u_char session_id[]; extern Buffer auth_debug; extern int auth_debug_init; extern Buffer loginmsg; +extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */ /* State exported from the child */ static struct sshbuf *child_state; @@ -172,6 +173,7 @@ static Authctxt *authctxt; static u_char *key_blob = NULL; static u_int key_bloblen = 0; static int key_blobtype = MM_NOKEY; +static struct sshauthopt *key_opts = NULL; static char *hostbased_cuser = NULL; static char *hostbased_chost = NULL; static char *auth_method = "unknown"; @@ -252,7 +254,6 @@ struct mon_table mon_dispatch_postauth20[] = { struct mon_table *mon_dispatch; /* Specifies if a certain message is allowed at the moment */ - static void monitor_permit(struct mon_table *ent, enum monitor_reqtype type, int permit) { @@ -297,6 +298,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) authctxt = _authctxt; memset(authctxt, 0, sizeof(*authctxt)); + ssh->authctxt = authctxt; authctxt->loginmsg = &loginmsg; @@ -331,7 +333,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) fatal("%s: unexpected authentication from %d", __func__, ent->type); if (authctxt->pw->pw_uid == 0 && - !auth_root_allowed(auth_method)) + !auth_root_allowed(ssh, auth_method)) authenticated = 0; #ifdef USE_PAM /* PAM needs to perform account checks after auth */ @@ -365,6 +367,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) debug("%s: %s has been authenticated by privileged process", __func__, authctxt->user); + ssh->authctxt = NULL; ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user); mm_get_keystate(pmonitor); @@ -413,7 +416,7 @@ monitor_child_postauth(struct monitor *pmonitor) monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); - if (!no_pty_flag) { + if (auth_opts->permit_pty_flag) { monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1); } @@ -558,9 +561,11 @@ monitor_reset_key_state(void) free(key_blob); free(hostbased_cuser); free(hostbased_chost); + sshauthopt_free(key_opts); key_blob = NULL; key_bloblen = 0; key_blobtype = MM_NOKEY; + key_opts = NULL; hostbased_cuser = NULL; hostbased_chost = NULL; } @@ -828,6 +833,7 @@ mm_answer_authserv(int sock, Buffer *m) int mm_answer_authpassword(int sock, Buffer *m) { + struct ssh *ssh = active_state; /* XXX */ static int call_count; char *passwd; int authenticated; @@ -838,7 +844,7 @@ mm_answer_authpassword(int sock, Buffer *m) passwd = buffer_get_string(m, &plen); /* Only authenticate if the context is valid */ authenticated = options.password_authentication && - auth_password(authctxt, passwd); + auth_password(ssh, passwd); explicit_bzero(passwd, strlen(passwd)); free(passwd); @@ -1129,15 +1135,16 @@ mm_answer_pam_free_ctx(int sock, Buffer *m) int mm_answer_keyallowed(int sock, Buffer *m) { + struct ssh *ssh = active_state; /* XXX */ struct sshkey *key; char *cuser, *chost; u_char *blob; u_int bloblen, pubkey_auth_attempt; enum mm_keytype type = 0; - int allowed = 0; + int r, allowed = 0; + struct sshauthopt *opts = NULL; debug3("%s entering", __func__); - type = buffer_get_int(m); cuser = buffer_get_string(m, NULL); chost = buffer_get_string(m, NULL); @@ -1156,28 +1163,31 @@ mm_answer_keyallowed(int sock, Buffer *m) switch (type) { case MM_USERKEY: - allowed = options.pubkey_authentication && - !auth2_key_already_used(authctxt, key) && - match_pattern_list(sshkey_ssh_name(key), - options.pubkey_key_types, 0) == 1 && - user_key_allowed(authctxt->pw, key, - pubkey_auth_attempt); auth_method = "publickey"; - if (options.pubkey_authentication && - (!pubkey_auth_attempt || allowed != 1)) - auth_clear_options(); + if (!options.pubkey_authentication) + break; + if (auth2_key_already_used(authctxt, key)) + break; + if (match_pattern_list(sshkey_ssh_name(key), + options.pubkey_key_types, 0) != 1) + break; + allowed = user_key_allowed(ssh, authctxt->pw, key, + pubkey_auth_attempt, &opts); break; case MM_HOSTKEY: - allowed = options.hostbased_authentication && - !auth2_key_already_used(authctxt, key) && - match_pattern_list(sshkey_ssh_name(key), - options.hostbased_key_types, 0) == 1 && - hostbased_key_allowed(authctxt->pw, + auth_method = "hostbased"; + if (!options.hostbased_authentication) + break; + if (auth2_key_already_used(authctxt, key)) + break; + if (match_pattern_list(sshkey_ssh_name(key), + options.hostbased_key_types, 0) != 1) + break; + allowed = hostbased_key_allowed(authctxt->pw, cuser, chost, key); auth2_record_info(authctxt, "client user \"%.100s\", client host \"%.100s\"", cuser, chost); - auth_method = "hostbased"; break; default: fatal("%s: unknown key type %d", __func__, type); @@ -1185,7 +1195,10 @@ mm_answer_keyallowed(int sock, Buffer *m) } } - debug3("%s: key is %s", __func__, allowed ? "allowed" : "not allowed"); + debug3("%s: %s authentication%s: %s key is %s", __func__, + auth_method, pubkey_auth_attempt ? "" : " test", + (key == NULL || !authctxt->valid) ? "invalid" : sshkey_type(key), + allowed ? "allowed" : "not allowed"); auth2_record_key(authctxt, 0, key); sshkey_free(key); @@ -1198,6 +1211,7 @@ mm_answer_keyallowed(int sock, Buffer *m) key_blob = blob; key_bloblen = bloblen; key_blobtype = type; + key_opts = opts; hostbased_cuser = cuser; hostbased_chost = chost; } else { @@ -1210,10 +1224,13 @@ mm_answer_keyallowed(int sock, Buffer *m) buffer_clear(m); buffer_put_int(m, allowed); - buffer_put_int(m, forced_command != NULL); - + if (opts != NULL && (r = sshauthopt_serialise(opts, m, 1)) != 0) + fatal("%s: sshauthopt_serialise: %s", __func__, ssh_err(r)); mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m); + if (!allowed) + sshauthopt_free(opts); + return (0); } @@ -1336,6 +1353,7 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser, int mm_answer_keyverify(int sock, struct sshbuf *m) { + struct ssh *ssh = active_state; /* XXX */ struct sshkey *key; u_char *signature, *data, *blob; char *sigalg; @@ -1390,6 +1408,8 @@ mm_answer_keyverify(int sock, struct sshbuf *m) free(data); free(sigalg); + if (key_blobtype == MM_USERKEY) + auth_activate_options(ssh, key_opts); monitor_reset_key_state(); sshkey_free(key); -- cgit v1.2.3