diff options
Diffstat (limited to 'auth2-pubkey.c')
-rw-r--r-- | auth2-pubkey.c | 68 |
1 files changed, 43 insertions, 25 deletions
diff --git a/auth2-pubkey.c b/auth2-pubkey.c index 8024b1d6a976..3d9f9af1f289 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-pubkey.c,v 1.77 2018/03/03 03:15:51 djm Exp $ */ +/* $OpenBSD: auth2-pubkey.c,v 1.84 2018/08/23 03:01:08 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -46,7 +46,7 @@ #include "ssh.h" #include "ssh2.h" #include "packet.h" -#include "buffer.h" +#include "sshbuf.h" #include "log.h" #include "misc.h" #include "servconf.h" @@ -89,19 +89,15 @@ userauth_pubkey(struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; struct passwd *pw = authctxt->pw; - struct sshbuf *b; + struct sshbuf *b = NULL; struct sshkey *key = NULL; - char *pkalg, *userstyle = NULL, *key_s = NULL, *ca_s = NULL; - u_char *pkblob, *sig, have_sig; + char *pkalg = NULL, *userstyle = NULL, *key_s = NULL, *ca_s = NULL; + u_char *pkblob = NULL, *sig = NULL, have_sig; size_t blen, slen; int r, pktype; int authenticated = 0; struct sshauthopt *authopts = NULL; - if (!authctxt->valid) { - debug2("%s: disabled because of invalid user", __func__); - return 0; - } if ((r = sshpkt_get_u8(ssh, &have_sig)) != 0 || (r = sshpkt_get_cstring(ssh, &pkalg, NULL)) != 0 || (r = sshpkt_get_string(ssh, &pkblob, &blen)) != 0) @@ -109,7 +105,7 @@ userauth_pubkey(struct ssh *ssh) pktype = sshkey_type_from_name(pkalg); if (pktype == KEY_UNSPEC) { /* this is perfectly legal */ - logit("%s: unsupported public key algorithm: %s", + verbose("%s: unsupported public key algorithm: %s", __func__, pkalg); goto done; } @@ -136,8 +132,7 @@ userauth_pubkey(struct ssh *ssh) logit("refusing previously-used %s key", sshkey_type(key)); goto done; } - if (match_pattern_list(sshkey_ssh_name(key), - options.pubkey_key_types, 0) != 1) { + if (match_pattern_list(pkalg, options.pubkey_key_types, 0) != 1) { logit("%s: key type %s not in PubkeyAcceptedKeyTypes", __func__, sshkey_ssh_name(key)); goto done; @@ -168,6 +163,11 @@ userauth_pubkey(struct ssh *ssh) fatal("%s: sshbuf_put_string session id: %s", __func__, ssh_err(r)); } + if (!authctxt->valid || authctxt->user == NULL) { + debug2("%s: disabled because of invalid user", + __func__); + goto done; + } /* reconstruct packet */ xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", @@ -184,16 +184,15 @@ userauth_pubkey(struct ssh *ssh) #ifdef DEBUG_PK sshbuf_dump(b, stderr); #endif - /* test for correct signature */ authenticated = 0; if (PRIVSEP(user_key_allowed(ssh, pw, key, 1, &authopts)) && - PRIVSEP(sshkey_verify(key, sig, slen, sshbuf_ptr(b), - sshbuf_len(b), NULL, ssh->compat)) == 0) { + PRIVSEP(sshkey_verify(key, sig, slen, + sshbuf_ptr(b), sshbuf_len(b), + (ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL, + ssh->compat)) == 0) { authenticated = 1; } - sshbuf_free(b); - free(sig); auth2_record_key(authctxt, authenticated, key); } else { debug("%s: test pkalg %s pkblob %s%s%s", @@ -204,6 +203,11 @@ userauth_pubkey(struct ssh *ssh) if ((r = sshpkt_get_end(ssh)) != 0) fatal("%s: %s", __func__, ssh_err(r)); + if (!authctxt->valid || authctxt->user == NULL) { + debug2("%s: disabled because of invalid user", + __func__); + goto done; + } /* XXX fake reply and always send PK_OK ? */ /* * XXX this allows testing whether a user is allowed @@ -217,9 +221,9 @@ userauth_pubkey(struct ssh *ssh) != 0 || (r = sshpkt_put_cstring(ssh, pkalg)) != 0 || (r = sshpkt_put_string(ssh, pkblob, blen)) != 0 || - (r = sshpkt_send(ssh)) != 0) + (r = sshpkt_send(ssh)) != 0 || + (r = ssh_packet_write_wait(ssh)) != 0) fatal("%s: %s", __func__, ssh_err(r)); - ssh_packet_write_wait(ssh); authctxt->postponed = 1; } } @@ -230,6 +234,7 @@ done: } debug2("%s: authenticated %d pkalg %s", __func__, authenticated, pkalg); + sshbuf_free(b); sshauthopt_free(authopts); sshkey_free(key); free(userstyle); @@ -237,6 +242,7 @@ done: free(pkblob); free(key_s); free(ca_s); + free(sig); return authenticated; } @@ -319,14 +325,16 @@ static int process_principals(struct ssh *ssh, FILE *f, const char *file, const struct sshkey_cert *cert, struct sshauthopt **authoptsp) { - char loc[256], line[SSH_MAX_PUBKEY_BYTES], *cp, *ep; + char loc[256], *line = NULL, *cp, *ep; + size_t linesize = 0; u_long linenum = 0; u_int found_principal = 0; if (authoptsp != NULL) *authoptsp = NULL; - while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { + while (getline(&line, &linesize, f) != -1) { + linenum++; /* Always consume entire input */ if (found_principal) continue; @@ -344,6 +352,7 @@ process_principals(struct ssh *ssh, FILE *f, const char *file, if (check_principals_line(ssh, cp, cert, loc, authoptsp) == 0) found_principal = 1; } + free(line); return found_principal; } @@ -387,7 +396,7 @@ match_principals_command(struct ssh *ssh, struct passwd *user_pw, pid_t pid; char *tmp, *username = NULL, *command = NULL, **av = NULL; char *ca_fp = NULL, *key_fp = NULL, *catext = NULL, *keytext = NULL; - char serial_s[16]; + char serial_s[16], uidstr[32]; void (*osigchld)(int); if (authoptsp != NULL) @@ -447,8 +456,11 @@ match_principals_command(struct ssh *ssh, struct passwd *user_pw, } snprintf(serial_s, sizeof(serial_s), "%llu", (unsigned long long)cert->serial); + snprintf(uidstr, sizeof(uidstr), "%llu", + (unsigned long long)user_pw->pw_uid); for (i = 1; i < ac; i++) { tmp = percent_expand(av[i], + "U", uidstr, "u", user_pw->pw_name, "h", user_pw->pw_dir, "t", sshkey_ssh_name(key), @@ -684,14 +696,16 @@ static int check_authkeys_file(struct ssh *ssh, struct passwd *pw, FILE *f, char *file, struct sshkey *key, struct sshauthopt **authoptsp) { - char *cp, line[SSH_MAX_PUBKEY_BYTES], loc[256]; + char *cp, *line = NULL, loc[256]; + size_t linesize = 0; int found_key = 0; u_long linenum = 0; if (authoptsp != NULL) *authoptsp = NULL; - while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { + while (getline(&line, &linesize, f) != -1) { + linenum++; /* Always consume entire file */ if (found_key) continue; @@ -705,6 +719,7 @@ check_authkeys_file(struct ssh *ssh, struct passwd *pw, FILE *f, if (check_authkey_line(ssh, pw, key, cp, loc, authoptsp) == 0) found_key = 1; } + free(line); return found_key; } @@ -852,7 +867,7 @@ user_key_command_allowed2(struct ssh *ssh, struct passwd *user_pw, int i, uid_swapped = 0, ac = 0; pid_t pid; char *username = NULL, *key_fp = NULL, *keytext = NULL; - char *tmp, *command = NULL, **av = NULL; + char uidstr[32], *tmp, *command = NULL, **av = NULL; void (*osigchld)(int); if (authoptsp != NULL) @@ -902,8 +917,11 @@ user_key_command_allowed2(struct ssh *ssh, struct passwd *user_pw, command); goto out; } + snprintf(uidstr, sizeof(uidstr), "%llu", + (unsigned long long)user_pw->pw_uid); for (i = 1; i < ac; i++) { tmp = percent_expand(av[i], + "U", uidstr, "u", user_pw->pw_name, "h", user_pw->pw_dir, "t", sshkey_ssh_name(key), |