summaryrefslogtreecommitdiff
path: root/monitor.c
diff options
context:
space:
mode:
Diffstat (limited to 'monitor.c')
-rw-r--r--monitor.c103
1 files changed, 68 insertions, 35 deletions
diff --git a/monitor.c b/monitor.c
index 7452e20e2..510e3496e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor.c,v 1.167 2017/02/03 23:05:57 djm Exp $ */ 1/* $OpenBSD: monitor.c,v 1.174 2017/10/02 19:33:20 djm Exp $ */
2/* 2/*
3 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 3 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4 * Copyright 2002 Markus Friedl <markus@openbsd.org> 4 * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -323,6 +323,8 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
323 partial = 0; 323 partial = 0;
324 auth_method = "unknown"; 324 auth_method = "unknown";
325 auth_submethod = NULL; 325 auth_submethod = NULL;
326 auth2_authctxt_reset_info(authctxt);
327
326 authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1); 328 authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1);
327 329
328 /* Special handling for multiple required authentications */ 330 /* Special handling for multiple required authentications */
@@ -362,6 +364,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
362 auth_method, auth_submethod); 364 auth_method, auth_submethod);
363 if (!partial && !authenticated) 365 if (!partial && !authenticated)
364 authctxt->failures++; 366 authctxt->failures++;
367 if (authenticated || partial) {
368 auth2_update_session_info(authctxt,
369 auth_method, auth_submethod);
370 }
365 } 371 }
366 } 372 }
367 373
@@ -773,10 +779,12 @@ mm_answer_pwnamallow(int sock, Buffer *m)
773 for (i = 0; i < options.nx; i++) \ 779 for (i = 0; i < options.nx; i++) \
774 buffer_put_cstring(m, options.x[i]); \ 780 buffer_put_cstring(m, options.x[i]); \
775 } while (0) 781 } while (0)
782#define M_CP_STRARRAYOPT_ALLOC(x, nx) M_CP_STRARRAYOPT(x, nx)
776 /* See comment in servconf.h */ 783 /* See comment in servconf.h */
777 COPY_MATCH_STRING_OPTS(); 784 COPY_MATCH_STRING_OPTS();
778#undef M_CP_STROPT 785#undef M_CP_STROPT
779#undef M_CP_STRARRAYOPT 786#undef M_CP_STRARRAYOPT
787#undef M_CP_STRARRAYOPT_ALLOC
780 788
781 /* Create valid auth method lists */ 789 /* Create valid auth method lists */
782 if (auth2_setup_methods_lists(authctxt) != 0) { 790 if (auth2_setup_methods_lists(authctxt) != 0) {
@@ -1162,7 +1170,7 @@ mm_answer_pam_free_ctx(int sock, Buffer *m)
1162int 1170int
1163mm_answer_keyallowed(int sock, Buffer *m) 1171mm_answer_keyallowed(int sock, Buffer *m)
1164{ 1172{
1165 Key *key; 1173 struct sshkey *key;
1166 char *cuser, *chost; 1174 char *cuser, *chost;
1167 u_char *blob; 1175 u_char *blob;
1168 u_int bloblen, pubkey_auth_attempt; 1176 u_int bloblen, pubkey_auth_attempt;
@@ -1190,12 +1198,11 @@ mm_answer_keyallowed(int sock, Buffer *m)
1190 switch (type) { 1198 switch (type) {
1191 case MM_USERKEY: 1199 case MM_USERKEY:
1192 allowed = options.pubkey_authentication && 1200 allowed = options.pubkey_authentication &&
1193 !auth2_userkey_already_used(authctxt, key) && 1201 !auth2_key_already_used(authctxt, key) &&
1194 match_pattern_list(sshkey_ssh_name(key), 1202 match_pattern_list(sshkey_ssh_name(key),
1195 options.pubkey_key_types, 0) == 1 && 1203 options.pubkey_key_types, 0) == 1 &&
1196 user_key_allowed(authctxt->pw, key, 1204 user_key_allowed(authctxt->pw, key,
1197 pubkey_auth_attempt); 1205 pubkey_auth_attempt);
1198 pubkey_auth_info(authctxt, key, NULL);
1199 auth_method = "publickey"; 1206 auth_method = "publickey";
1200 if (options.pubkey_authentication && 1207 if (options.pubkey_authentication &&
1201 (!pubkey_auth_attempt || allowed != 1)) 1208 (!pubkey_auth_attempt || allowed != 1))
@@ -1203,11 +1210,12 @@ mm_answer_keyallowed(int sock, Buffer *m)
1203 break; 1210 break;
1204 case MM_HOSTKEY: 1211 case MM_HOSTKEY:
1205 allowed = options.hostbased_authentication && 1212 allowed = options.hostbased_authentication &&
1213 !auth2_key_already_used(authctxt, key) &&
1206 match_pattern_list(sshkey_ssh_name(key), 1214 match_pattern_list(sshkey_ssh_name(key),
1207 options.hostbased_key_types, 0) == 1 && 1215 options.hostbased_key_types, 0) == 1 &&
1208 hostbased_key_allowed(authctxt->pw, 1216 hostbased_key_allowed(authctxt->pw,
1209 cuser, chost, key); 1217 cuser, chost, key);
1210 pubkey_auth_info(authctxt, key, 1218 auth2_record_info(authctxt,
1211 "client user \"%.100s\", client host \"%.100s\"", 1219 "client user \"%.100s\", client host \"%.100s\"",
1212 cuser, chost); 1220 cuser, chost);
1213 auth_method = "hostbased"; 1221 auth_method = "hostbased";
@@ -1218,11 +1226,10 @@ mm_answer_keyallowed(int sock, Buffer *m)
1218 } 1226 }
1219 } 1227 }
1220 1228
1221 debug3("%s: key %p is %s", 1229 debug3("%s: key is %s", __func__, allowed ? "allowed" : "not allowed");
1222 __func__, key, allowed ? "allowed" : "not allowed");
1223 1230
1224 if (key != NULL) 1231 auth2_record_key(authctxt, 0, key);
1225 key_free(key); 1232 sshkey_free(key);
1226 1233
1227 /* clear temporarily storage (used by verify) */ 1234 /* clear temporarily storage (used by verify) */
1228 monitor_reset_key_state(); 1235 monitor_reset_key_state();
@@ -1373,33 +1380,35 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser,
1373} 1380}
1374 1381
1375int 1382int
1376mm_answer_keyverify(int sock, Buffer *m) 1383mm_answer_keyverify(int sock, struct sshbuf *m)
1377{ 1384{
1378 Key *key; 1385 struct sshkey *key;
1379 u_char *signature, *data, *blob; 1386 u_char *signature, *data, *blob;
1380 u_int signaturelen, datalen, bloblen; 1387 size_t signaturelen, datalen, bloblen;
1381 int verified = 0; 1388 int r, ret, valid_data = 0, encoded_ret;
1382 int valid_data = 0;
1383 1389
1384 blob = buffer_get_string(m, &bloblen); 1390 if ((r = sshbuf_get_string(m, &blob, &bloblen)) != 0 ||
1385 signature = buffer_get_string(m, &signaturelen); 1391 (r = sshbuf_get_string(m, &signature, &signaturelen)) != 0 ||
1386 data = buffer_get_string(m, &datalen); 1392 (r = sshbuf_get_string(m, &data, &datalen)) != 0)
1393 fatal("%s: buffer error: %s", __func__, ssh_err(r));
1387 1394
1388 if (hostbased_cuser == NULL || hostbased_chost == NULL || 1395 if (hostbased_cuser == NULL || hostbased_chost == NULL ||
1389 !monitor_allowed_key(blob, bloblen)) 1396 !monitor_allowed_key(blob, bloblen))
1390 fatal("%s: bad key, not previously allowed", __func__); 1397 fatal("%s: bad key, not previously allowed", __func__);
1391 1398
1392 key = key_from_blob(blob, bloblen); 1399 /* XXX use sshkey_froms here; need to change key_blob, etc. */
1393 if (key == NULL) 1400 if ((r = sshkey_from_blob(blob, bloblen, &key)) != 0)
1394 fatal("%s: bad public key blob", __func__); 1401 fatal("%s: bad public key blob: %s", __func__, ssh_err(r));
1395 1402
1396 switch (key_blobtype) { 1403 switch (key_blobtype) {
1397 case MM_USERKEY: 1404 case MM_USERKEY:
1398 valid_data = monitor_valid_userblob(data, datalen); 1405 valid_data = monitor_valid_userblob(data, datalen);
1406 auth_method = "publickey";
1399 break; 1407 break;
1400 case MM_HOSTKEY: 1408 case MM_HOSTKEY:
1401 valid_data = monitor_valid_hostbasedblob(data, datalen, 1409 valid_data = monitor_valid_hostbasedblob(data, datalen,
1402 hostbased_cuser, hostbased_chost); 1410 hostbased_cuser, hostbased_chost);
1411 auth_method = "hostbased";
1403 break; 1412 break;
1404 default: 1413 default:
1405 valid_data = 0; 1414 valid_data = 0;
@@ -1408,29 +1417,28 @@ mm_answer_keyverify(int sock, Buffer *m)
1408 if (!valid_data) 1417 if (!valid_data)
1409 fatal("%s: bad signature data blob", __func__); 1418 fatal("%s: bad signature data blob", __func__);
1410 1419
1411 verified = key_verify(key, signature, signaturelen, data, datalen); 1420 ret = sshkey_verify(key, signature, signaturelen, data, datalen,
1412 debug3("%s: key %p signature %s", 1421 active_state->compat);
1413 __func__, key, (verified == 1) ? "verified" : "unverified"); 1422 debug3("%s: %s %p signature %s", __func__, auth_method, key,
1414 1423 (ret == 0) ? "verified" : "unverified");
1415 /* If auth was successful then record key to ensure it isn't reused */ 1424 auth2_record_key(authctxt, ret == 0, key);
1416 if (verified == 1 && key_blobtype == MM_USERKEY)
1417 auth2_record_userkey(authctxt, key);
1418 else
1419 key_free(key);
1420 1425
1421 free(blob); 1426 free(blob);
1422 free(signature); 1427 free(signature);
1423 free(data); 1428 free(data);
1424 1429
1425 auth_method = key_blobtype == MM_USERKEY ? "publickey" : "hostbased";
1426
1427 monitor_reset_key_state(); 1430 monitor_reset_key_state();
1428 1431
1429 buffer_clear(m); 1432 sshkey_free(key);
1430 buffer_put_int(m, verified); 1433 sshbuf_reset(m);
1434
1435 /* encode ret != 0 as positive integer, since we're sending u32 */
1436 encoded_ret = (ret != 0);
1437 if ((r = sshbuf_put_u32(m, encoded_ret)) != 0)
1438 fatal("%s: buffer error: %s", __func__, ssh_err(r));
1431 mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m); 1439 mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m);
1432 1440
1433 return (verified == 1); 1441 return ret == 0;
1434} 1442}
1435 1443
1436static void 1444static void
@@ -1556,13 +1564,14 @@ mm_answer_pty_cleanup(int sock, Buffer *m)
1556int 1564int
1557mm_answer_term(int sock, Buffer *req) 1565mm_answer_term(int sock, Buffer *req)
1558{ 1566{
1567 struct ssh *ssh = active_state; /* XXX */
1559 extern struct monitor *pmonitor; 1568 extern struct monitor *pmonitor;
1560 int res, status; 1569 int res, status;
1561 1570
1562 debug3("%s: tearing down sessions", __func__); 1571 debug3("%s: tearing down sessions", __func__);
1563 1572
1564 /* The child is terminating */ 1573 /* The child is terminating */
1565 session_destroy_all(&mm_session_close); 1574 session_destroy_all(ssh, &mm_session_close);
1566 1575
1567#ifdef USE_PAM 1576#ifdef USE_PAM
1568 if (options.use_pam) 1577 if (options.use_pam)
@@ -1622,6 +1631,17 @@ mm_answer_audit_command(int socket, Buffer *m)
1622#endif /* SSH_AUDIT_EVENTS */ 1631#endif /* SSH_AUDIT_EVENTS */
1623 1632
1624void 1633void
1634monitor_clear_keystate(struct monitor *pmonitor)
1635{
1636 struct ssh *ssh = active_state; /* XXX */
1637
1638 ssh_clear_newkeys(ssh, MODE_IN);
1639 ssh_clear_newkeys(ssh, MODE_OUT);
1640 sshbuf_free(child_state);
1641 child_state = NULL;
1642}
1643
1644void
1625monitor_apply_keystate(struct monitor *pmonitor) 1645monitor_apply_keystate(struct monitor *pmonitor)
1626{ 1646{
1627 struct ssh *ssh = active_state; /* XXX */ 1647 struct ssh *ssh = active_state; /* XXX */
@@ -1689,9 +1709,18 @@ static void
1689monitor_openfds(struct monitor *mon, int do_logfds) 1709monitor_openfds(struct monitor *mon, int do_logfds)
1690{ 1710{
1691 int pair[2]; 1711 int pair[2];
1712#ifdef SO_ZEROIZE
1713 int on = 1;
1714#endif
1692 1715
1693 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) 1716 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
1694 fatal("%s: socketpair: %s", __func__, strerror(errno)); 1717 fatal("%s: socketpair: %s", __func__, strerror(errno));
1718#ifdef SO_ZEROIZE
1719 if (setsockopt(pair[0], SOL_SOCKET, SO_ZEROIZE, &on, sizeof(on)) < 0)
1720 error("setsockopt SO_ZEROIZE(0): %.100s", strerror(errno));
1721 if (setsockopt(pair[1], SOL_SOCKET, SO_ZEROIZE, &on, sizeof(on)) < 0)
1722 error("setsockopt SO_ZEROIZE(1): %.100s", strerror(errno));
1723#endif
1695 FD_CLOSEONEXEC(pair[0]); 1724 FD_CLOSEONEXEC(pair[0]);
1696 FD_CLOSEONEXEC(pair[1]); 1725 FD_CLOSEONEXEC(pair[1]);
1697 mon->m_recvfd = pair[0]; 1726 mon->m_recvfd = pair[0];
@@ -1825,6 +1854,7 @@ int
1825mm_answer_gss_userok(int sock, Buffer *m) 1854mm_answer_gss_userok(int sock, Buffer *m)
1826{ 1855{
1827 int authenticated; 1856 int authenticated;
1857 const char *displayname;
1828 1858
1829 if (!options.gss_authentication && !options.gss_keyex) 1859 if (!options.gss_authentication && !options.gss_keyex)
1830 fatal("%s: GSSAPI not enabled", __func__); 1860 fatal("%s: GSSAPI not enabled", __func__);
@@ -1840,6 +1870,9 @@ mm_answer_gss_userok(int sock, Buffer *m)
1840 1870
1841 auth_method = "gssapi-with-mic"; 1871 auth_method = "gssapi-with-mic";
1842 1872
1873 if ((displayname = ssh_gssapi_displayname()) != NULL)
1874 auth2_record_info(authctxt, "%s", displayname);
1875
1843 /* Monitor loop will terminate if authenticated */ 1876 /* Monitor loop will terminate if authenticated */
1844 return (authenticated); 1877 return (authenticated);
1845} 1878}