upstream commit
switch auth2-pubkey.c to modern APIs; with & ok djm@ Upstream-ID: 8f08d4316eb1b0c4ffe4a206c05cdd45ed1daf07
This commit is contained in:
parent
54d90ace1d
commit
00ed75c92d
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: auth2-hostbased.c,v 1.27 2017/05/30 08:52:19 markus Exp $ */
|
/* $OpenBSD: auth2-hostbased.c,v 1.28 2017/05/30 14:10:53 markus Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||||
*
|
*
|
||||||
|
@ -138,8 +138,8 @@ userauth_hostbased(Authctxt *authctxt)
|
||||||
/* test for allowed key and correct signature */
|
/* test for allowed key and correct signature */
|
||||||
authenticated = 0;
|
authenticated = 0;
|
||||||
if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
|
if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
|
||||||
PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
|
PRIVSEP(sshkey_verify(key, sig, slen, buffer_ptr(&b),
|
||||||
buffer_len(&b))) == 1)
|
buffer_len(&b), 0)) == 0)
|
||||||
authenticated = 1;
|
authenticated = 1;
|
||||||
|
|
||||||
buffer_free(&b);
|
buffer_free(&b);
|
||||||
|
|
194
auth2-pubkey.c
194
auth2-pubkey.c
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: auth2-pubkey.c,v 1.63 2017/05/30 08:52:19 markus Exp $ */
|
/* $OpenBSD: auth2-pubkey.c,v 1.64 2017/05/30 14:10:53 markus Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||||
*
|
*
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "servconf.h"
|
#include "servconf.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "key.h"
|
#include "sshkey.h"
|
||||||
#include "hostfile.h"
|
#include "hostfile.h"
|
||||||
#include "auth.h"
|
#include "auth.h"
|
||||||
#include "pathnames.h"
|
#include "pathnames.h"
|
||||||
|
@ -77,40 +77,50 @@ extern u_int session_id2_len;
|
||||||
static int
|
static int
|
||||||
userauth_pubkey(Authctxt *authctxt)
|
userauth_pubkey(Authctxt *authctxt)
|
||||||
{
|
{
|
||||||
Buffer b;
|
struct ssh *ssh = active_state; /* XXX */
|
||||||
|
struct sshbuf *b;
|
||||||
struct sshkey *key = NULL;
|
struct sshkey *key = NULL;
|
||||||
char *pkalg, *userstyle, *fp = NULL;
|
char *pkalg, *userstyle = NULL, *fp = NULL;
|
||||||
u_char *pkblob, *sig;
|
u_char *pkblob, *sig, have_sig;
|
||||||
u_int alen, blen, slen;
|
size_t blen, slen;
|
||||||
int have_sig, pktype;
|
int r, pktype;
|
||||||
int authenticated = 0;
|
int authenticated = 0;
|
||||||
|
|
||||||
if (!authctxt->valid) {
|
if (!authctxt->valid) {
|
||||||
debug2("%s: disabled because of invalid user", __func__);
|
debug2("%s: disabled because of invalid user", __func__);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
have_sig = packet_get_char();
|
if ((r = sshpkt_get_u8(ssh, &have_sig)) != 0)
|
||||||
if (datafellows & SSH_BUG_PKAUTH) {
|
fatal("%s: sshpkt_get_u8 failed: %s", __func__, ssh_err(r));
|
||||||
|
if (ssh->compat & SSH_BUG_PKAUTH) {
|
||||||
debug2("%s: SSH_BUG_PKAUTH", __func__);
|
debug2("%s: SSH_BUG_PKAUTH", __func__);
|
||||||
|
if ((b = sshbuf_new()) == NULL)
|
||||||
|
fatal("%s: sshbuf_new failed", __func__);
|
||||||
/* no explicit pkalg given */
|
/* no explicit pkalg given */
|
||||||
pkblob = packet_get_string(&blen);
|
|
||||||
buffer_init(&b);
|
|
||||||
buffer_append(&b, pkblob, blen);
|
|
||||||
/* so we have to extract the pkalg from the pkblob */
|
/* so we have to extract the pkalg from the pkblob */
|
||||||
pkalg = buffer_get_string(&b, &alen);
|
/* XXX use sshbuf_from() */
|
||||||
buffer_free(&b);
|
if ((r = sshpkt_get_string(ssh, &pkblob, &blen)) != 0 ||
|
||||||
|
(r = sshbuf_put(b, pkblob, blen)) != 0 ||
|
||||||
|
(r = sshbuf_get_cstring(b, &pkalg, NULL)) != 0)
|
||||||
|
fatal("%s: failed: %s", __func__, ssh_err(r));
|
||||||
|
sshbuf_free(b);
|
||||||
} else {
|
} else {
|
||||||
pkalg = packet_get_string(&alen);
|
if ((r = sshpkt_get_cstring(ssh, &pkalg, NULL)) != 0 ||
|
||||||
pkblob = packet_get_string(&blen);
|
(r = sshpkt_get_string(ssh, &pkblob, &blen)) != 0)
|
||||||
|
fatal("%s: sshpkt_get_cstring failed: %s",
|
||||||
|
__func__, ssh_err(r));
|
||||||
}
|
}
|
||||||
pktype = key_type_from_name(pkalg);
|
pktype = sshkey_type_from_name(pkalg);
|
||||||
if (pktype == KEY_UNSPEC) {
|
if (pktype == KEY_UNSPEC) {
|
||||||
/* this is perfectly legal */
|
/* this is perfectly legal */
|
||||||
logit("%s: unsupported public key algorithm: %s",
|
logit("%s: unsupported public key algorithm: %s",
|
||||||
__func__, pkalg);
|
__func__, pkalg);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
key = key_from_blob(pkblob, blen);
|
if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) {
|
||||||
|
error("%s: could not parse key: %s", __func__, ssh_err(r));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
if (key == NULL) {
|
if (key == NULL) {
|
||||||
error("%s: cannot decode key: %s", __func__, pkalg);
|
error("%s: cannot decode key: %s", __func__, pkalg);
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -120,15 +130,15 @@ userauth_pubkey(Authctxt *authctxt)
|
||||||
"(received %d, expected %d)", __func__, key->type, pktype);
|
"(received %d, expected %d)", __func__, key->type, pktype);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (key_type_plain(key->type) == KEY_RSA &&
|
if (sshkey_type_plain(key->type) == KEY_RSA &&
|
||||||
(datafellows & SSH_BUG_RSASIGMD5) != 0) {
|
(ssh->compat & SSH_BUG_RSASIGMD5) != 0) {
|
||||||
logit("Refusing RSA key because client uses unsafe "
|
logit("Refusing RSA key because client uses unsafe "
|
||||||
"signature scheme");
|
"signature scheme");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT);
|
fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT);
|
||||||
if (auth2_userkey_already_used(authctxt, key)) {
|
if (auth2_userkey_already_used(authctxt, key)) {
|
||||||
logit("refusing previously-used %s key", key_type(key));
|
logit("refusing previously-used %s key", sshkey_type(key));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (match_pattern_list(sshkey_ssh_name(key),
|
if (match_pattern_list(sshkey_ssh_name(key),
|
||||||
|
@ -141,54 +151,68 @@ userauth_pubkey(Authctxt *authctxt)
|
||||||
if (have_sig) {
|
if (have_sig) {
|
||||||
debug3("%s: have signature for %s %s",
|
debug3("%s: have signature for %s %s",
|
||||||
__func__, sshkey_type(key), fp);
|
__func__, sshkey_type(key), fp);
|
||||||
sig = packet_get_string(&slen);
|
if ((r = sshpkt_get_string(ssh, &sig, &slen)) != 0 ||
|
||||||
packet_check_eom();
|
(r = sshpkt_get_end(ssh)) != 0)
|
||||||
buffer_init(&b);
|
fatal("%s: %s", __func__, ssh_err(r));
|
||||||
if (datafellows & SSH_OLD_SESSIONID) {
|
if ((b = sshbuf_new()) == NULL)
|
||||||
buffer_append(&b, session_id2, session_id2_len);
|
fatal("%s: sshbuf_new failed", __func__);
|
||||||
|
if (ssh->compat & SSH_OLD_SESSIONID) {
|
||||||
|
if ((r = sshbuf_put(b, session_id2,
|
||||||
|
session_id2_len)) != 0)
|
||||||
|
fatal("%s: sshbuf_put session id: %s",
|
||||||
|
__func__, ssh_err(r));
|
||||||
} else {
|
} else {
|
||||||
buffer_put_string(&b, session_id2, session_id2_len);
|
if ((r = sshbuf_put_string(b, session_id2,
|
||||||
|
session_id2_len)) != 0)
|
||||||
|
fatal("%s: sshbuf_put_string session id: %s",
|
||||||
|
__func__, ssh_err(r));
|
||||||
}
|
}
|
||||||
/* reconstruct packet */
|
/* reconstruct packet */
|
||||||
buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
|
|
||||||
xasprintf(&userstyle, "%s%s%s", authctxt->user,
|
xasprintf(&userstyle, "%s%s%s", authctxt->user,
|
||||||
authctxt->style ? ":" : "",
|
authctxt->style ? ":" : "",
|
||||||
authctxt->style ? authctxt->style : "");
|
authctxt->style ? authctxt->style : "");
|
||||||
buffer_put_cstring(&b, userstyle);
|
if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
|
||||||
free(userstyle);
|
(r = sshbuf_put_cstring(b, userstyle)) != 0 ||
|
||||||
buffer_put_cstring(&b,
|
(r = sshbuf_put_cstring(b, ssh->compat & SSH_BUG_PKSERVICE ?
|
||||||
datafellows & SSH_BUG_PKSERVICE ?
|
"ssh-userauth" : authctxt->service)) != 0)
|
||||||
"ssh-userauth" :
|
fatal("%s: build packet failed: %s",
|
||||||
authctxt->service);
|
__func__, ssh_err(r));
|
||||||
if (datafellows & SSH_BUG_PKAUTH) {
|
if (ssh->compat & SSH_BUG_PKAUTH) {
|
||||||
buffer_put_char(&b, have_sig);
|
if ((r = sshbuf_put_u8(b, have_sig)) != 0)
|
||||||
|
fatal("%s: build packet failed: %s",
|
||||||
|
__func__, ssh_err(r));
|
||||||
} else {
|
} else {
|
||||||
buffer_put_cstring(&b, "publickey");
|
if ((r = sshbuf_put_cstring(b, "publickey")) != 0 ||
|
||||||
buffer_put_char(&b, have_sig);
|
(r = sshbuf_put_u8(b, have_sig)) != 0 ||
|
||||||
buffer_put_cstring(&b, pkalg);
|
(r = sshbuf_put_cstring(b, pkalg) != 0))
|
||||||
|
fatal("%s: build packet failed: %s",
|
||||||
|
__func__, ssh_err(r));
|
||||||
}
|
}
|
||||||
buffer_put_string(&b, pkblob, blen);
|
if ((r = sshbuf_put_string(b, pkblob, blen)) != 0)
|
||||||
|
fatal("%s: build packet failed: %s",
|
||||||
|
__func__, ssh_err(r));
|
||||||
#ifdef DEBUG_PK
|
#ifdef DEBUG_PK
|
||||||
buffer_dump(&b);
|
sshbuf_dump(b, stderr);
|
||||||
#endif
|
#endif
|
||||||
pubkey_auth_info(authctxt, key, NULL);
|
pubkey_auth_info(authctxt, key, NULL);
|
||||||
|
|
||||||
/* test for correct signature */
|
/* test for correct signature */
|
||||||
authenticated = 0;
|
authenticated = 0;
|
||||||
if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) &&
|
if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) &&
|
||||||
PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
|
PRIVSEP(sshkey_verify(key, sig, slen, sshbuf_ptr(b),
|
||||||
buffer_len(&b))) == 1) {
|
sshbuf_len(b), ssh->compat)) == 0) {
|
||||||
authenticated = 1;
|
authenticated = 1;
|
||||||
/* Record the successful key to prevent reuse */
|
/* Record the successful key to prevent reuse */
|
||||||
auth2_record_userkey(authctxt, key);
|
auth2_record_userkey(authctxt, key);
|
||||||
key = NULL; /* Don't free below */
|
key = NULL; /* Don't free below */
|
||||||
}
|
}
|
||||||
buffer_free(&b);
|
sshbuf_free(b);
|
||||||
free(sig);
|
free(sig);
|
||||||
} else {
|
} else {
|
||||||
debug("%s: test whether pkalg/pkblob are acceptable for %s %s",
|
debug("%s: test whether pkalg/pkblob are acceptable for %s %s",
|
||||||
__func__, sshkey_type(key), fp);
|
__func__, sshkey_type(key), fp);
|
||||||
packet_check_eom();
|
if ((r = sshpkt_get_end(ssh)) != 0)
|
||||||
|
fatal("%s: %s", __func__, ssh_err(r));
|
||||||
|
|
||||||
/* XXX fake reply and always send PK_OK ? */
|
/* XXX fake reply and always send PK_OK ? */
|
||||||
/*
|
/*
|
||||||
|
@ -199,11 +223,13 @@ userauth_pubkey(Authctxt *authctxt)
|
||||||
* issue? -markus
|
* issue? -markus
|
||||||
*/
|
*/
|
||||||
if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0))) {
|
if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0))) {
|
||||||
packet_start(SSH2_MSG_USERAUTH_PK_OK);
|
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_PK_OK))
|
||||||
packet_put_string(pkalg, alen);
|
!= 0 ||
|
||||||
packet_put_string(pkblob, blen);
|
(r = sshpkt_put_cstring(ssh, pkalg)) != 0 ||
|
||||||
packet_send();
|
(r = sshpkt_put_string(ssh, pkblob, blen)) != 0 ||
|
||||||
packet_write_wait();
|
(r = sshpkt_send(ssh)) != 0)
|
||||||
|
fatal("%s: %s", __func__, ssh_err(r));
|
||||||
|
ssh_packet_write_wait(ssh);
|
||||||
authctxt->postponed = 1;
|
authctxt->postponed = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,7 +238,8 @@ userauth_pubkey(Authctxt *authctxt)
|
||||||
done:
|
done:
|
||||||
debug2("%s: authenticated %d pkalg %s", __func__, authenticated, pkalg);
|
debug2("%s: authenticated %d pkalg %s", __func__, authenticated, pkalg);
|
||||||
if (key != NULL)
|
if (key != NULL)
|
||||||
key_free(key);
|
sshkey_free(key);
|
||||||
|
free(userstyle);
|
||||||
free(pkalg);
|
free(pkalg);
|
||||||
free(pkblob);
|
free(pkblob);
|
||||||
free(fp);
|
free(fp);
|
||||||
|
@ -233,23 +260,23 @@ pubkey_auth_info(Authctxt *authctxt, const struct sshkey *key,
|
||||||
i = vasprintf(&extra, fmt, ap);
|
i = vasprintf(&extra, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
if (i < 0 || extra == NULL)
|
if (i < 0 || extra == NULL)
|
||||||
fatal("%s: vasprintf failed", __func__);
|
fatal("%s: vasprintf failed", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key_is_cert(key)) {
|
if (sshkey_is_cert(key)) {
|
||||||
fp = sshkey_fingerprint(key->cert->signature_key,
|
fp = sshkey_fingerprint(key->cert->signature_key,
|
||||||
options.fingerprint_hash, SSH_FP_DEFAULT);
|
options.fingerprint_hash, SSH_FP_DEFAULT);
|
||||||
auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s",
|
auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s",
|
||||||
key_type(key), key->cert->key_id,
|
sshkey_type(key), key->cert->key_id,
|
||||||
(unsigned long long)key->cert->serial,
|
(unsigned long long)key->cert->serial,
|
||||||
key_type(key->cert->signature_key),
|
sshkey_type(key->cert->signature_key),
|
||||||
fp == NULL ? "(null)" : fp,
|
fp == NULL ? "(null)" : fp,
|
||||||
extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
|
extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
|
||||||
free(fp);
|
free(fp);
|
||||||
} else {
|
} else {
|
||||||
fp = sshkey_fingerprint(key, options.fingerprint_hash,
|
fp = sshkey_fingerprint(key, options.fingerprint_hash,
|
||||||
SSH_FP_DEFAULT);
|
SSH_FP_DEFAULT);
|
||||||
auth_info(authctxt, "%s %s%s%s", key_type(key),
|
auth_info(authctxt, "%s %s%s%s", sshkey_type(key),
|
||||||
fp == NULL ? "(null)" : fp,
|
fp == NULL ? "(null)" : fp,
|
||||||
extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
|
extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
|
||||||
free(fp);
|
free(fp);
|
||||||
|
@ -762,16 +789,13 @@ match_principals_command(struct passwd *user_pw, const struct sshkey *key)
|
||||||
* returns 1 if the key is allowed or 0 otherwise.
|
* returns 1 if the key is allowed or 0 otherwise.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
check_authkeys_file(FILE *f, char *file, struct sshkey* key, struct passwd *pw)
|
check_authkeys_file(FILE *f, char *file, struct sshkey *key, struct passwd *pw)
|
||||||
{
|
{
|
||||||
char line[SSH_MAX_PUBKEY_BYTES];
|
char line[SSH_MAX_PUBKEY_BYTES];
|
||||||
int found_key = 0;
|
int found_key = 0;
|
||||||
u_long linenum = 0;
|
u_long linenum = 0;
|
||||||
struct sshkey *found;
|
struct sshkey *found = NULL;
|
||||||
|
|
||||||
found_key = 0;
|
|
||||||
|
|
||||||
found = NULL;
|
|
||||||
while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
|
while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
|
||||||
char *cp, *key_options = NULL, *fp = NULL;
|
char *cp, *key_options = NULL, *fp = NULL;
|
||||||
const char *reason = NULL;
|
const char *reason = NULL;
|
||||||
|
@ -780,8 +804,10 @@ check_authkeys_file(FILE *f, char *file, struct sshkey* key, struct passwd *pw)
|
||||||
if (found_key)
|
if (found_key)
|
||||||
continue;
|
continue;
|
||||||
if (found != NULL)
|
if (found != NULL)
|
||||||
key_free(found);
|
sshkey_free(found);
|
||||||
found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
|
found = sshkey_new(sshkey_is_cert(key) ? KEY_UNSPEC : key->type);
|
||||||
|
if (found == NULL)
|
||||||
|
goto done;
|
||||||
auth_clear_options();
|
auth_clear_options();
|
||||||
|
|
||||||
/* Skip leading whitespace, empty and comment lines. */
|
/* Skip leading whitespace, empty and comment lines. */
|
||||||
|
@ -790,7 +816,7 @@ check_authkeys_file(FILE *f, char *file, struct sshkey* key, struct passwd *pw)
|
||||||
if (!*cp || *cp == '\n' || *cp == '#')
|
if (!*cp || *cp == '\n' || *cp == '#')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (key_read(found, &cp) != 1) {
|
if (sshkey_read(found, &cp) != 0) {
|
||||||
/* no key? check if there are options for this key */
|
/* no key? check if there are options for this key */
|
||||||
int quoted = 0;
|
int quoted = 0;
|
||||||
debug2("user_key_allowed: check options: '%s'", cp);
|
debug2("user_key_allowed: check options: '%s'", cp);
|
||||||
|
@ -804,14 +830,14 @@ check_authkeys_file(FILE *f, char *file, struct sshkey* key, struct passwd *pw)
|
||||||
/* Skip remaining whitespace. */
|
/* Skip remaining whitespace. */
|
||||||
for (; *cp == ' ' || *cp == '\t'; cp++)
|
for (; *cp == ' ' || *cp == '\t'; cp++)
|
||||||
;
|
;
|
||||||
if (key_read(found, &cp) != 1) {
|
if (sshkey_read(found, &cp) != 0) {
|
||||||
debug2("user_key_allowed: advance: '%s'", cp);
|
debug2("user_key_allowed: advance: '%s'", cp);
|
||||||
/* still no key? advance to next line*/
|
/* still no key? advance to next line*/
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (key_is_cert(key)) {
|
if (sshkey_is_cert(key)) {
|
||||||
if (!key_equal(found, key->cert->signature_key))
|
if (!sshkey_equal(found, key->cert->signature_key))
|
||||||
continue;
|
continue;
|
||||||
if (auth_parse_options(pw, key_options, file,
|
if (auth_parse_options(pw, key_options, file,
|
||||||
linenum) != 1)
|
linenum) != 1)
|
||||||
|
@ -822,7 +848,7 @@ check_authkeys_file(FILE *f, char *file, struct sshkey* key, struct passwd *pw)
|
||||||
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
|
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
|
||||||
continue;
|
continue;
|
||||||
debug("matching CA found: file %s, line %lu, %s %s",
|
debug("matching CA found: file %s, line %lu, %s %s",
|
||||||
file, linenum, key_type(found), fp);
|
file, linenum, sshkey_type(found), fp);
|
||||||
/*
|
/*
|
||||||
* If the user has specified a list of principals as
|
* If the user has specified a list of principals as
|
||||||
* a key option, then prefer that list to matching
|
* a key option, then prefer that list to matching
|
||||||
|
@ -839,7 +865,7 @@ check_authkeys_file(FILE *f, char *file, struct sshkey* key, struct passwd *pw)
|
||||||
auth_debug_add("%s", reason);
|
auth_debug_add("%s", reason);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (key_cert_check_authority(key, 0, 0,
|
if (sshkey_cert_check_authority(key, 0, 0,
|
||||||
authorized_principals == NULL ? pw->pw_name : NULL,
|
authorized_principals == NULL ? pw->pw_name : NULL,
|
||||||
&reason) != 0)
|
&reason) != 0)
|
||||||
goto fail_reason;
|
goto fail_reason;
|
||||||
|
@ -848,11 +874,11 @@ check_authkeys_file(FILE *f, char *file, struct sshkey* key, struct passwd *pw)
|
||||||
verbose("Accepted certificate ID \"%s\" (serial %llu) "
|
verbose("Accepted certificate ID \"%s\" (serial %llu) "
|
||||||
"signed by %s CA %s via %s", key->cert->key_id,
|
"signed by %s CA %s via %s", key->cert->key_id,
|
||||||
(unsigned long long)key->cert->serial,
|
(unsigned long long)key->cert->serial,
|
||||||
key_type(found), fp, file);
|
sshkey_type(found), fp, file);
|
||||||
free(fp);
|
free(fp);
|
||||||
found_key = 1;
|
found_key = 1;
|
||||||
break;
|
break;
|
||||||
} else if (key_equal(found, key)) {
|
} else if (sshkey_equal(found, key)) {
|
||||||
if (auth_parse_options(pw, key_options, file,
|
if (auth_parse_options(pw, key_options, file,
|
||||||
linenum) != 1)
|
linenum) != 1)
|
||||||
continue;
|
continue;
|
||||||
|
@ -862,14 +888,15 @@ check_authkeys_file(FILE *f, char *file, struct sshkey* key, struct passwd *pw)
|
||||||
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
|
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
|
||||||
continue;
|
continue;
|
||||||
debug("matching key found: file %s, line %lu %s %s",
|
debug("matching key found: file %s, line %lu %s %s",
|
||||||
file, linenum, key_type(found), fp);
|
file, linenum, sshkey_type(found), fp);
|
||||||
free(fp);
|
free(fp);
|
||||||
found_key = 1;
|
found_key = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
done:
|
||||||
if (found != NULL)
|
if (found != NULL)
|
||||||
key_free(found);
|
sshkey_free(found);
|
||||||
if (!found_key)
|
if (!found_key)
|
||||||
debug2("key not found");
|
debug2("key not found");
|
||||||
return found_key;
|
return found_key;
|
||||||
|
@ -881,20 +908,20 @@ user_cert_trusted_ca(struct passwd *pw, struct sshkey *key)
|
||||||
{
|
{
|
||||||
char *ca_fp, *principals_file = NULL;
|
char *ca_fp, *principals_file = NULL;
|
||||||
const char *reason;
|
const char *reason;
|
||||||
int ret = 0, found_principal = 0, use_authorized_principals;
|
int r, ret = 0, found_principal = 0, use_authorized_principals;
|
||||||
|
|
||||||
if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL)
|
if (!sshkey_is_cert(key) || options.trusted_user_ca_keys == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ((ca_fp = sshkey_fingerprint(key->cert->signature_key,
|
if ((ca_fp = sshkey_fingerprint(key->cert->signature_key,
|
||||||
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
|
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (sshkey_in_file(key->cert->signature_key,
|
if ((r = sshkey_in_file(key->cert->signature_key,
|
||||||
options.trusted_user_ca_keys, 1, 0) != 0) {
|
options.trusted_user_ca_keys, 1, 0)) != 0) {
|
||||||
debug2("%s: CA %s %s is not listed in %s", __func__,
|
debug2("%s: CA %s %s is not listed in %s: %s", __func__,
|
||||||
key_type(key->cert->signature_key), ca_fp,
|
sshkey_type(key->cert->signature_key), ca_fp,
|
||||||
options.trusted_user_ca_keys);
|
options.trusted_user_ca_keys, ssh_err(r));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -919,7 +946,7 @@ user_cert_trusted_ca(struct passwd *pw, struct sshkey *key)
|
||||||
auth_debug_add("%s", reason);
|
auth_debug_add("%s", reason);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (key_cert_check_authority(key, 0, 1,
|
if (sshkey_cert_check_authority(key, 0, 1,
|
||||||
use_authorized_principals ? NULL : pw->pw_name, &reason) != 0)
|
use_authorized_principals ? NULL : pw->pw_name, &reason) != 0)
|
||||||
goto fail_reason;
|
goto fail_reason;
|
||||||
if (auth_cert_options(key, pw, &reason) != 0)
|
if (auth_cert_options(key, pw, &reason) != 0)
|
||||||
|
@ -928,7 +955,7 @@ user_cert_trusted_ca(struct passwd *pw, struct sshkey *key)
|
||||||
verbose("Accepted certificate ID \"%s\" (serial %llu) signed by "
|
verbose("Accepted certificate ID \"%s\" (serial %llu) signed by "
|
||||||
"%s CA %s via %s", key->cert->key_id,
|
"%s CA %s via %s", key->cert->key_id,
|
||||||
(unsigned long long)key->cert->serial,
|
(unsigned long long)key->cert->serial,
|
||||||
key_type(key->cert->signature_key), ca_fp,
|
sshkey_type(key->cert->signature_key), ca_fp,
|
||||||
options.trusted_user_ca_keys);
|
options.trusted_user_ca_keys);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
||||||
|
@ -1096,7 +1123,8 @@ user_key_allowed(struct passwd *pw, struct sshkey *key, int auth_attempt)
|
||||||
|
|
||||||
if (auth_key_is_revoked(key))
|
if (auth_key_is_revoked(key))
|
||||||
return 0;
|
return 0;
|
||||||
if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key))
|
if (sshkey_is_cert(key) &&
|
||||||
|
auth_key_is_revoked(key->cert->signature_key))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
success = user_cert_trusted_ca(pw, key);
|
success = user_cert_trusted_ca(pw, key);
|
||||||
|
|
41
monitor.c
41
monitor.c
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: monitor.c,v 1.168 2017/05/30 08:52:19 markus Exp $ */
|
/* $OpenBSD: monitor.c,v 1.169 2017/05/30 14:10:53 markus Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||||
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
||||||
|
@ -1330,25 +1330,25 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
mm_answer_keyverify(int sock, Buffer *m)
|
mm_answer_keyverify(int sock, struct sshbuf *m)
|
||||||
{
|
{
|
||||||
struct sshkey *key;
|
struct sshkey *key;
|
||||||
u_char *signature, *data, *blob;
|
u_char *signature, *data, *blob;
|
||||||
u_int signaturelen, datalen, bloblen;
|
size_t signaturelen, datalen, bloblen;
|
||||||
int verified = 0;
|
int r, ret, valid_data = 0, encoded_ret;
|
||||||
int valid_data = 0;
|
|
||||||
|
|
||||||
blob = buffer_get_string(m, &bloblen);
|
if ((r = sshbuf_get_string(m, &blob, &bloblen)) != 0 ||
|
||||||
signature = buffer_get_string(m, &signaturelen);
|
(r = sshbuf_get_string(m, &signature, &signaturelen)) != 0 ||
|
||||||
data = buffer_get_string(m, &datalen);
|
(r = sshbuf_get_string(m, &data, &datalen)) != 0)
|
||||||
|
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||||
|
|
||||||
if (hostbased_cuser == NULL || hostbased_chost == NULL ||
|
if (hostbased_cuser == NULL || hostbased_chost == NULL ||
|
||||||
!monitor_allowed_key(blob, bloblen))
|
!monitor_allowed_key(blob, bloblen))
|
||||||
fatal("%s: bad key, not previously allowed", __func__);
|
fatal("%s: bad key, not previously allowed", __func__);
|
||||||
|
|
||||||
key = key_from_blob(blob, bloblen);
|
/* XXX use sshkey_froms here; need to change key_blob, etc. */
|
||||||
if (key == NULL)
|
if ((r = sshkey_from_blob(blob, bloblen, &key)) != 0)
|
||||||
fatal("%s: bad public key blob", __func__);
|
fatal("%s: bad public key blob: %s", __func__, ssh_err(r));
|
||||||
|
|
||||||
switch (key_blobtype) {
|
switch (key_blobtype) {
|
||||||
case MM_USERKEY:
|
case MM_USERKEY:
|
||||||
|
@ -1365,15 +1365,16 @@ mm_answer_keyverify(int sock, Buffer *m)
|
||||||
if (!valid_data)
|
if (!valid_data)
|
||||||
fatal("%s: bad signature data blob", __func__);
|
fatal("%s: bad signature data blob", __func__);
|
||||||
|
|
||||||
verified = key_verify(key, signature, signaturelen, data, datalen);
|
ret = sshkey_verify(key, signature, signaturelen, data, datalen,
|
||||||
|
active_state->compat);
|
||||||
debug3("%s: key %p signature %s",
|
debug3("%s: key %p signature %s",
|
||||||
__func__, key, (verified == 1) ? "verified" : "unverified");
|
__func__, key, (ret == 0) ? "verified" : "unverified");
|
||||||
|
|
||||||
/* If auth was successful then record key to ensure it isn't reused */
|
/* If auth was successful then record key to ensure it isn't reused */
|
||||||
if (verified == 1 && key_blobtype == MM_USERKEY)
|
if (ret == 0 && key_blobtype == MM_USERKEY)
|
||||||
auth2_record_userkey(authctxt, key);
|
auth2_record_userkey(authctxt, key);
|
||||||
else
|
else
|
||||||
key_free(key);
|
sshkey_free(key);
|
||||||
|
|
||||||
free(blob);
|
free(blob);
|
||||||
free(signature);
|
free(signature);
|
||||||
|
@ -1383,11 +1384,15 @@ mm_answer_keyverify(int sock, Buffer *m)
|
||||||
|
|
||||||
monitor_reset_key_state();
|
monitor_reset_key_state();
|
||||||
|
|
||||||
buffer_clear(m);
|
sshbuf_reset(m);
|
||||||
buffer_put_int(m, verified);
|
|
||||||
|
/* encode ret != 0 as positive integer, since we're sending u32 */
|
||||||
|
encoded_ret = (ret != 0);
|
||||||
|
if ((r = sshbuf_put_u32(m, encoded_ret)) != 0)
|
||||||
|
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||||
mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m);
|
mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m);
|
||||||
|
|
||||||
return (verified == 1);
|
return ret == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: monitor_wrap.c,v 1.91 2017/05/30 08:52:19 markus Exp $ */
|
/* $OpenBSD: monitor_wrap.c,v 1.92 2017/05/30 14:10:53 markus Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||||
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
||||||
|
@ -436,13 +436,13 @@ mm_key_allowed(enum mm_keytype type, const char *user, const char *host,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
mm_key_verify(struct sshkey *key, u_char *sig, u_int siglen, u_char *data,
|
mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen,
|
||||||
u_int datalen)
|
const u_char *data, size_t datalen, u_int compat)
|
||||||
{
|
{
|
||||||
Buffer m;
|
Buffer m;
|
||||||
u_char *blob;
|
u_char *blob;
|
||||||
u_int len;
|
u_int len;
|
||||||
int verified = 0;
|
u_int encoded_ret = 0;
|
||||||
|
|
||||||
debug3("%s entering", __func__);
|
debug3("%s entering", __func__);
|
||||||
|
|
||||||
|
@ -461,11 +461,13 @@ mm_key_verify(struct sshkey *key, u_char *sig, u_int siglen, u_char *data,
|
||||||
debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__);
|
debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__);
|
||||||
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m);
|
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m);
|
||||||
|
|
||||||
verified = buffer_get_int(&m);
|
encoded_ret = buffer_get_int(&m);
|
||||||
|
|
||||||
buffer_free(&m);
|
buffer_free(&m);
|
||||||
|
|
||||||
return (verified);
|
if (encoded_ret != 0)
|
||||||
|
return SSH_ERR_SIGNATURE_INVALID;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: monitor_wrap.h,v 1.33 2017/05/30 08:52:19 markus Exp $ */
|
/* $OpenBSD: monitor_wrap.h,v 1.34 2017/05/30 14:10:53 markus Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||||
|
@ -51,7 +51,8 @@ int mm_key_allowed(enum mm_keytype, const char *, const char *, struct sshkey *,
|
||||||
int mm_user_key_allowed(struct passwd *, struct sshkey *, int);
|
int mm_user_key_allowed(struct passwd *, struct sshkey *, int);
|
||||||
int mm_hostbased_key_allowed(struct passwd *, const char *,
|
int mm_hostbased_key_allowed(struct passwd *, const char *,
|
||||||
const char *, struct sshkey *);
|
const char *, struct sshkey *);
|
||||||
int mm_key_verify(struct sshkey *, u_char *, u_int, u_char *, u_int);
|
int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t,
|
||||||
|
const u_char *, size_t, u_int);
|
||||||
|
|
||||||
#ifdef GSSAPI
|
#ifdef GSSAPI
|
||||||
OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
|
OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
|
||||||
|
|
Loading…
Reference in New Issue