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 8024b1d6a9760..3d9f9af1f2890 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), | 
