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 96d22b7e4..f517da482 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>
@@ -308,6 +308,8 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
308 partial = 0; 308 partial = 0;
309 auth_method = "unknown"; 309 auth_method = "unknown";
310 auth_submethod = NULL; 310 auth_submethod = NULL;
311 auth2_authctxt_reset_info(authctxt);
312
311 authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1); 313 authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1);
312 314
313 /* Special handling for multiple required authentications */ 315 /* Special handling for multiple required authentications */
@@ -347,6 +349,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
347 auth_method, auth_submethod); 349 auth_method, auth_submethod);
348 if (!partial && !authenticated) 350 if (!partial && !authenticated)
349 authctxt->failures++; 351 authctxt->failures++;
352 if (authenticated || partial) {
353 auth2_update_session_info(authctxt,
354 auth_method, auth_submethod);
355 }
350 } 356 }
351 } 357 }
352 358
@@ -754,10 +760,12 @@ mm_answer_pwnamallow(int sock, Buffer *m)
754 for (i = 0; i < options.nx; i++) \ 760 for (i = 0; i < options.nx; i++) \
755 buffer_put_cstring(m, options.x[i]); \ 761 buffer_put_cstring(m, options.x[i]); \
756 } while (0) 762 } while (0)
763#define M_CP_STRARRAYOPT_ALLOC(x, nx) M_CP_STRARRAYOPT(x, nx)
757 /* See comment in servconf.h */ 764 /* See comment in servconf.h */
758 COPY_MATCH_STRING_OPTS(); 765 COPY_MATCH_STRING_OPTS();
759#undef M_CP_STROPT 766#undef M_CP_STROPT
760#undef M_CP_STRARRAYOPT 767#undef M_CP_STRARRAYOPT
768#undef M_CP_STRARRAYOPT_ALLOC
761 769
762 /* Create valid auth method lists */ 770 /* Create valid auth method lists */
763 if (auth2_setup_methods_lists(authctxt) != 0) { 771 if (auth2_setup_methods_lists(authctxt) != 0) {
@@ -1119,7 +1127,7 @@ mm_answer_pam_free_ctx(int sock, Buffer *m)
1119int 1127int
1120mm_answer_keyallowed(int sock, Buffer *m) 1128mm_answer_keyallowed(int sock, Buffer *m)
1121{ 1129{
1122 Key *key; 1130 struct sshkey *key;
1123 char *cuser, *chost; 1131 char *cuser, *chost;
1124 u_char *blob; 1132 u_char *blob;
1125 u_int bloblen, pubkey_auth_attempt; 1133 u_int bloblen, pubkey_auth_attempt;
@@ -1147,12 +1155,11 @@ mm_answer_keyallowed(int sock, Buffer *m)
1147 switch (type) { 1155 switch (type) {
1148 case MM_USERKEY: 1156 case MM_USERKEY:
1149 allowed = options.pubkey_authentication && 1157 allowed = options.pubkey_authentication &&
1150 !auth2_userkey_already_used(authctxt, key) && 1158 !auth2_key_already_used(authctxt, key) &&
1151 match_pattern_list(sshkey_ssh_name(key), 1159 match_pattern_list(sshkey_ssh_name(key),
1152 options.pubkey_key_types, 0) == 1 && 1160 options.pubkey_key_types, 0) == 1 &&
1153 user_key_allowed(authctxt->pw, key, 1161 user_key_allowed(authctxt->pw, key,
1154 pubkey_auth_attempt); 1162 pubkey_auth_attempt);
1155 pubkey_auth_info(authctxt, key, NULL);
1156 auth_method = "publickey"; 1163 auth_method = "publickey";
1157 if (options.pubkey_authentication && 1164 if (options.pubkey_authentication &&
1158 (!pubkey_auth_attempt || allowed != 1)) 1165 (!pubkey_auth_attempt || allowed != 1))
@@ -1160,11 +1167,12 @@ mm_answer_keyallowed(int sock, Buffer *m)
1160 break; 1167 break;
1161 case MM_HOSTKEY: 1168 case MM_HOSTKEY:
1162 allowed = options.hostbased_authentication && 1169 allowed = options.hostbased_authentication &&
1170 !auth2_key_already_used(authctxt, key) &&
1163 match_pattern_list(sshkey_ssh_name(key), 1171 match_pattern_list(sshkey_ssh_name(key),
1164 options.hostbased_key_types, 0) == 1 && 1172 options.hostbased_key_types, 0) == 1 &&
1165 hostbased_key_allowed(authctxt->pw, 1173 hostbased_key_allowed(authctxt->pw,
1166 cuser, chost, key); 1174 cuser, chost, key);
1167 pubkey_auth_info(authctxt, key, 1175 auth2_record_info(authctxt,
1168 "client user \"%.100s\", client host \"%.100s\"", 1176 "client user \"%.100s\", client host \"%.100s\"",
1169 cuser, chost); 1177 cuser, chost);
1170 auth_method = "hostbased"; 1178 auth_method = "hostbased";
@@ -1175,11 +1183,10 @@ mm_answer_keyallowed(int sock, Buffer *m)
1175 } 1183 }
1176 } 1184 }
1177 1185
1178 debug3("%s: key %p is %s", 1186 debug3("%s: key is %s", __func__, allowed ? "allowed" : "not allowed");
1179 __func__, key, allowed ? "allowed" : "not allowed");
1180 1187
1181 if (key != NULL) 1188 auth2_record_key(authctxt, 0, key);
1182 key_free(key); 1189 sshkey_free(key);
1183 1190
1184 /* clear temporarily storage (used by verify) */ 1191 /* clear temporarily storage (used by verify) */
1185 monitor_reset_key_state(); 1192 monitor_reset_key_state();
@@ -1330,33 +1337,35 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser,
1330} 1337}
1331 1338
1332int 1339int
1333mm_answer_keyverify(int sock, Buffer *m) 1340mm_answer_keyverify(int sock, struct sshbuf *m)
1334{ 1341{
1335 Key *key; 1342 struct sshkey *key;
1336 u_char *signature, *data, *blob; 1343 u_char *signature, *data, *blob;
1337 u_int signaturelen, datalen, bloblen; 1344 size_t signaturelen, datalen, bloblen;
1338 int verified = 0; 1345 int r, ret, valid_data = 0, encoded_ret;
1339 int valid_data = 0;
1340 1346
1341 blob = buffer_get_string(m, &bloblen); 1347 if ((r = sshbuf_get_string(m, &blob, &bloblen)) != 0 ||
1342 signature = buffer_get_string(m, &signaturelen); 1348 (r = sshbuf_get_string(m, &signature, &signaturelen)) != 0 ||
1343 data = buffer_get_string(m, &datalen); 1349 (r = sshbuf_get_string(m, &data, &datalen)) != 0)
1350 fatal("%s: buffer error: %s", __func__, ssh_err(r));
1344 1351
1345 if (hostbased_cuser == NULL || hostbased_chost == NULL || 1352 if (hostbased_cuser == NULL || hostbased_chost == NULL ||
1346 !monitor_allowed_key(blob, bloblen)) 1353 !monitor_allowed_key(blob, bloblen))
1347 fatal("%s: bad key, not previously allowed", __func__); 1354 fatal("%s: bad key, not previously allowed", __func__);
1348 1355
1349 key = key_from_blob(blob, bloblen); 1356 /* XXX use sshkey_froms here; need to change key_blob, etc. */
1350 if (key == NULL) 1357 if ((r = sshkey_from_blob(blob, bloblen, &key)) != 0)
1351 fatal("%s: bad public key blob", __func__); 1358 fatal("%s: bad public key blob: %s", __func__, ssh_err(r));
1352 1359
1353 switch (key_blobtype) { 1360 switch (key_blobtype) {
1354 case MM_USERKEY: 1361 case MM_USERKEY:
1355 valid_data = monitor_valid_userblob(data, datalen); 1362 valid_data = monitor_valid_userblob(data, datalen);
1363 auth_method = "publickey";
1356 break; 1364 break;
1357 case MM_HOSTKEY: 1365 case MM_HOSTKEY:
1358 valid_data = monitor_valid_hostbasedblob(data, datalen, 1366 valid_data = monitor_valid_hostbasedblob(data, datalen,
1359 hostbased_cuser, hostbased_chost); 1367 hostbased_cuser, hostbased_chost);
1368 auth_method = "hostbased";
1360 break; 1369 break;
1361 default: 1370 default:
1362 valid_data = 0; 1371 valid_data = 0;
@@ -1365,29 +1374,28 @@ mm_answer_keyverify(int sock, Buffer *m)
1365 if (!valid_data) 1374 if (!valid_data)
1366 fatal("%s: bad signature data blob", __func__); 1375 fatal("%s: bad signature data blob", __func__);
1367 1376
1368 verified = key_verify(key, signature, signaturelen, data, datalen); 1377 ret = sshkey_verify(key, signature, signaturelen, data, datalen,
1369 debug3("%s: key %p signature %s", 1378 active_state->compat);
1370 __func__, key, (verified == 1) ? "verified" : "unverified"); 1379 debug3("%s: %s %p signature %s", __func__, auth_method, key,
1371 1380 (ret == 0) ? "verified" : "unverified");
1372 /* If auth was successful then record key to ensure it isn't reused */ 1381 auth2_record_key(authctxt, ret == 0, key);
1373 if (verified == 1 && key_blobtype == MM_USERKEY)
1374 auth2_record_userkey(authctxt, key);
1375 else
1376 key_free(key);
1377 1382
1378 free(blob); 1383 free(blob);
1379 free(signature); 1384 free(signature);
1380 free(data); 1385 free(data);
1381 1386
1382 auth_method = key_blobtype == MM_USERKEY ? "publickey" : "hostbased";
1383
1384 monitor_reset_key_state(); 1387 monitor_reset_key_state();
1385 1388
1386 buffer_clear(m); 1389 sshkey_free(key);
1387 buffer_put_int(m, verified); 1390 sshbuf_reset(m);
1391
1392 /* encode ret != 0 as positive integer, since we're sending u32 */
1393 encoded_ret = (ret != 0);
1394 if ((r = sshbuf_put_u32(m, encoded_ret)) != 0)
1395 fatal("%s: buffer error: %s", __func__, ssh_err(r));
1388 mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m); 1396 mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m);
1389 1397
1390 return (verified == 1); 1398 return ret == 0;
1391} 1399}
1392 1400
1393static void 1401static void
@@ -1513,13 +1521,14 @@ mm_answer_pty_cleanup(int sock, Buffer *m)
1513int 1521int
1514mm_answer_term(int sock, Buffer *req) 1522mm_answer_term(int sock, Buffer *req)
1515{ 1523{
1524 struct ssh *ssh = active_state; /* XXX */
1516 extern struct monitor *pmonitor; 1525 extern struct monitor *pmonitor;
1517 int res, status; 1526 int res, status;
1518 1527
1519 debug3("%s: tearing down sessions", __func__); 1528 debug3("%s: tearing down sessions", __func__);
1520 1529
1521 /* The child is terminating */ 1530 /* The child is terminating */
1522 session_destroy_all(&mm_session_close); 1531 session_destroy_all(ssh, &mm_session_close);
1523 1532
1524#ifdef USE_PAM 1533#ifdef USE_PAM
1525 if (options.use_pam) 1534 if (options.use_pam)
@@ -1579,6 +1588,17 @@ mm_answer_audit_command(int socket, Buffer *m)
1579#endif /* SSH_AUDIT_EVENTS */ 1588#endif /* SSH_AUDIT_EVENTS */
1580 1589
1581void 1590void
1591monitor_clear_keystate(struct monitor *pmonitor)
1592{
1593 struct ssh *ssh = active_state; /* XXX */
1594
1595 ssh_clear_newkeys(ssh, MODE_IN);
1596 ssh_clear_newkeys(ssh, MODE_OUT);
1597 sshbuf_free(child_state);
1598 child_state = NULL;
1599}
1600
1601void
1582monitor_apply_keystate(struct monitor *pmonitor) 1602monitor_apply_keystate(struct monitor *pmonitor)
1583{ 1603{
1584 struct ssh *ssh = active_state; /* XXX */ 1604 struct ssh *ssh = active_state; /* XXX */
@@ -1639,9 +1659,18 @@ static void
1639monitor_openfds(struct monitor *mon, int do_logfds) 1659monitor_openfds(struct monitor *mon, int do_logfds)
1640{ 1660{
1641 int pair[2]; 1661 int pair[2];
1662#ifdef SO_ZEROIZE
1663 int on = 1;
1664#endif
1642 1665
1643 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) 1666 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
1644 fatal("%s: socketpair: %s", __func__, strerror(errno)); 1667 fatal("%s: socketpair: %s", __func__, strerror(errno));
1668#ifdef SO_ZEROIZE
1669 if (setsockopt(pair[0], SOL_SOCKET, SO_ZEROIZE, &on, sizeof(on)) < 0)
1670 error("setsockopt SO_ZEROIZE(0): %.100s", strerror(errno));
1671 if (setsockopt(pair[1], SOL_SOCKET, SO_ZEROIZE, &on, sizeof(on)) < 0)
1672 error("setsockopt SO_ZEROIZE(1): %.100s", strerror(errno));
1673#endif
1645 FD_CLOSEONEXEC(pair[0]); 1674 FD_CLOSEONEXEC(pair[0]);
1646 FD_CLOSEONEXEC(pair[1]); 1675 FD_CLOSEONEXEC(pair[1]);
1647 mon->m_recvfd = pair[0]; 1676 mon->m_recvfd = pair[0];
@@ -1774,6 +1803,7 @@ int
1774mm_answer_gss_userok(int sock, Buffer *m) 1803mm_answer_gss_userok(int sock, Buffer *m)
1775{ 1804{
1776 int authenticated; 1805 int authenticated;
1806 const char *displayname;
1777 1807
1778 if (!options.gss_authentication) 1808 if (!options.gss_authentication)
1779 fatal("%s: GSSAPI authentication not enabled", __func__); 1809 fatal("%s: GSSAPI authentication not enabled", __func__);
@@ -1788,6 +1818,9 @@ mm_answer_gss_userok(int sock, Buffer *m)
1788 1818
1789 auth_method = "gssapi-with-mic"; 1819 auth_method = "gssapi-with-mic";
1790 1820
1821 if ((displayname = ssh_gssapi_displayname()) != NULL)
1822 auth2_record_info(authctxt, "%s", displayname);
1823
1791 /* Monitor loop will terminate if authenticated */ 1824 /* Monitor loop will terminate if authenticated */
1792 return (authenticated); 1825 return (authenticated);
1793} 1826}