aboutsummaryrefslogtreecommitdiff
path: root/crypto/openssh/monitor.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssh/monitor.c')
-rw-r--r--crypto/openssh/monitor.c103
1 files changed, 68 insertions, 35 deletions
diff --git a/crypto/openssh/monitor.c b/crypto/openssh/monitor.c
index 96d22b7e40e9..f517da482ce5 100644
--- a/crypto/openssh/monitor.c
+++ b/crypto/openssh/monitor.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.c,v 1.167 2017/02/03 23:05:57 djm Exp $ */
+/* $OpenBSD: monitor.c,v 1.174 2017/10/02 19:33:20 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -308,6 +308,8 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
partial = 0;
auth_method = "unknown";
auth_submethod = NULL;
+ auth2_authctxt_reset_info(authctxt);
+
authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1);
/* Special handling for multiple required authentications */
@@ -347,6 +349,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
auth_method, auth_submethod);
if (!partial && !authenticated)
authctxt->failures++;
+ if (authenticated || partial) {
+ auth2_update_session_info(authctxt,
+ auth_method, auth_submethod);
+ }
}
}
@@ -754,10 +760,12 @@ mm_answer_pwnamallow(int sock, Buffer *m)
for (i = 0; i < options.nx; i++) \
buffer_put_cstring(m, options.x[i]); \
} while (0)
+#define M_CP_STRARRAYOPT_ALLOC(x, nx) M_CP_STRARRAYOPT(x, nx)
/* See comment in servconf.h */
COPY_MATCH_STRING_OPTS();
#undef M_CP_STROPT
#undef M_CP_STRARRAYOPT
+#undef M_CP_STRARRAYOPT_ALLOC
/* Create valid auth method lists */
if (auth2_setup_methods_lists(authctxt) != 0) {
@@ -1119,7 +1127,7 @@ mm_answer_pam_free_ctx(int sock, Buffer *m)
int
mm_answer_keyallowed(int sock, Buffer *m)
{
- Key *key;
+ struct sshkey *key;
char *cuser, *chost;
u_char *blob;
u_int bloblen, pubkey_auth_attempt;
@@ -1147,12 +1155,11 @@ mm_answer_keyallowed(int sock, Buffer *m)
switch (type) {
case MM_USERKEY:
allowed = options.pubkey_authentication &&
- !auth2_userkey_already_used(authctxt, key) &&
+ !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);
- pubkey_auth_info(authctxt, key, NULL);
auth_method = "publickey";
if (options.pubkey_authentication &&
(!pubkey_auth_attempt || allowed != 1))
@@ -1160,11 +1167,12 @@ mm_answer_keyallowed(int sock, Buffer *m)
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,
cuser, chost, key);
- pubkey_auth_info(authctxt, key,
+ auth2_record_info(authctxt,
"client user \"%.100s\", client host \"%.100s\"",
cuser, chost);
auth_method = "hostbased";
@@ -1175,11 +1183,10 @@ mm_answer_keyallowed(int sock, Buffer *m)
}
}
- debug3("%s: key %p is %s",
- __func__, key, allowed ? "allowed" : "not allowed");
+ debug3("%s: key is %s", __func__, allowed ? "allowed" : "not allowed");
- if (key != NULL)
- key_free(key);
+ auth2_record_key(authctxt, 0, key);
+ sshkey_free(key);
/* clear temporarily storage (used by verify) */
monitor_reset_key_state();
@@ -1330,33 +1337,35 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser,
}
int
-mm_answer_keyverify(int sock, Buffer *m)
+mm_answer_keyverify(int sock, struct sshbuf *m)
{
- Key *key;
+ struct sshkey *key;
u_char *signature, *data, *blob;
- u_int signaturelen, datalen, bloblen;
- int verified = 0;
- int valid_data = 0;
+ size_t signaturelen, datalen, bloblen;
+ int r, ret, valid_data = 0, encoded_ret;
- blob = buffer_get_string(m, &bloblen);
- signature = buffer_get_string(m, &signaturelen);
- data = buffer_get_string(m, &datalen);
+ if ((r = sshbuf_get_string(m, &blob, &bloblen)) != 0 ||
+ (r = sshbuf_get_string(m, &signature, &signaturelen)) != 0 ||
+ (r = sshbuf_get_string(m, &data, &datalen)) != 0)
+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
if (hostbased_cuser == NULL || hostbased_chost == NULL ||
!monitor_allowed_key(blob, bloblen))
fatal("%s: bad key, not previously allowed", __func__);
- key = key_from_blob(blob, bloblen);
- if (key == NULL)
- fatal("%s: bad public key blob", __func__);
+ /* XXX use sshkey_froms here; need to change key_blob, etc. */
+ if ((r = sshkey_from_blob(blob, bloblen, &key)) != 0)
+ fatal("%s: bad public key blob: %s", __func__, ssh_err(r));
switch (key_blobtype) {
case MM_USERKEY:
valid_data = monitor_valid_userblob(data, datalen);
+ auth_method = "publickey";
break;
case MM_HOSTKEY:
valid_data = monitor_valid_hostbasedblob(data, datalen,
hostbased_cuser, hostbased_chost);
+ auth_method = "hostbased";
break;
default:
valid_data = 0;
@@ -1365,29 +1374,28 @@ mm_answer_keyverify(int sock, Buffer *m)
if (!valid_data)
fatal("%s: bad signature data blob", __func__);
- verified = key_verify(key, signature, signaturelen, data, datalen);
- debug3("%s: key %p signature %s",
- __func__, key, (verified == 1) ? "verified" : "unverified");
-
- /* If auth was successful then record key to ensure it isn't reused */
- if (verified == 1 && key_blobtype == MM_USERKEY)
- auth2_record_userkey(authctxt, key);
- else
- key_free(key);
+ ret = sshkey_verify(key, signature, signaturelen, data, datalen,
+ active_state->compat);
+ debug3("%s: %s %p signature %s", __func__, auth_method, key,
+ (ret == 0) ? "verified" : "unverified");
+ auth2_record_key(authctxt, ret == 0, key);
free(blob);
free(signature);
free(data);
- auth_method = key_blobtype == MM_USERKEY ? "publickey" : "hostbased";
-
monitor_reset_key_state();
- buffer_clear(m);
- buffer_put_int(m, verified);
+ sshkey_free(key);
+ sshbuf_reset(m);
+
+ /* 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);
- return (verified == 1);
+ return ret == 0;
}
static void
@@ -1513,13 +1521,14 @@ mm_answer_pty_cleanup(int sock, Buffer *m)
int
mm_answer_term(int sock, Buffer *req)
{
+ struct ssh *ssh = active_state; /* XXX */
extern struct monitor *pmonitor;
int res, status;
debug3("%s: tearing down sessions", __func__);
/* The child is terminating */
- session_destroy_all(&mm_session_close);
+ session_destroy_all(ssh, &mm_session_close);
#ifdef USE_PAM
if (options.use_pam)
@@ -1579,6 +1588,17 @@ mm_answer_audit_command(int socket, Buffer *m)
#endif /* SSH_AUDIT_EVENTS */
void
+monitor_clear_keystate(struct monitor *pmonitor)
+{
+ struct ssh *ssh = active_state; /* XXX */
+
+ ssh_clear_newkeys(ssh, MODE_IN);
+ ssh_clear_newkeys(ssh, MODE_OUT);
+ sshbuf_free(child_state);
+ child_state = NULL;
+}
+
+void
monitor_apply_keystate(struct monitor *pmonitor)
{
struct ssh *ssh = active_state; /* XXX */
@@ -1639,9 +1659,18 @@ static void
monitor_openfds(struct monitor *mon, int do_logfds)
{
int pair[2];
+#ifdef SO_ZEROIZE
+ int on = 1;
+#endif
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
fatal("%s: socketpair: %s", __func__, strerror(errno));
+#ifdef SO_ZEROIZE
+ if (setsockopt(pair[0], SOL_SOCKET, SO_ZEROIZE, &on, sizeof(on)) < 0)
+ error("setsockopt SO_ZEROIZE(0): %.100s", strerror(errno));
+ if (setsockopt(pair[1], SOL_SOCKET, SO_ZEROIZE, &on, sizeof(on)) < 0)
+ error("setsockopt SO_ZEROIZE(1): %.100s", strerror(errno));
+#endif
FD_CLOSEONEXEC(pair[0]);
FD_CLOSEONEXEC(pair[1]);
mon->m_recvfd = pair[0];
@@ -1774,6 +1803,7 @@ int
mm_answer_gss_userok(int sock, Buffer *m)
{
int authenticated;
+ const char *displayname;
if (!options.gss_authentication)
fatal("%s: GSSAPI authentication not enabled", __func__);
@@ -1788,6 +1818,9 @@ mm_answer_gss_userok(int sock, Buffer *m)
auth_method = "gssapi-with-mic";
+ if ((displayname = ssh_gssapi_displayname()) != NULL)
+ auth2_record_info(authctxt, "%s", displayname);
+
/* Monitor loop will terminate if authenticated */
return (authenticated);
}