aboutsummaryrefslogtreecommitdiff
path: root/auth2-pubkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'auth2-pubkey.c')
-rw-r--r--auth2-pubkey.c68
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),