diff options
Diffstat (limited to 'monitor.c')
-rw-r--r-- | monitor.c | 305 |
1 files changed, 18 insertions, 287 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor.c,v 1.161 2016/07/22 03:39:13 djm Exp $ */ | 1 | /* $OpenBSD: monitor.c,v 1.162 2016/08/13 17:47:41 markus 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> |
@@ -169,10 +169,6 @@ static int monitor_read_log(struct monitor *); | |||
169 | 169 | ||
170 | static Authctxt *authctxt; | 170 | static Authctxt *authctxt; |
171 | 171 | ||
172 | #ifdef WITH_SSH1 | ||
173 | static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ | ||
174 | #endif | ||
175 | |||
176 | /* local state for key verify */ | 172 | /* local state for key verify */ |
177 | static u_char *key_blob = NULL; | 173 | static u_char *key_blob = NULL; |
178 | static u_int key_bloblen = 0; | 174 | static u_int key_bloblen = 0; |
@@ -254,52 +250,6 @@ struct mon_table mon_dispatch_postauth20[] = { | |||
254 | {0, 0, NULL} | 250 | {0, 0, NULL} |
255 | }; | 251 | }; |
256 | 252 | ||
257 | struct mon_table mon_dispatch_proto15[] = { | ||
258 | #ifdef WITH_SSH1 | ||
259 | {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, | ||
260 | {MONITOR_REQ_SESSKEY, MON_ONCE, mm_answer_sesskey}, | ||
261 | {MONITOR_REQ_SESSID, MON_ONCE, mm_answer_sessid}, | ||
262 | {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, | ||
263 | {MONITOR_REQ_RSAKEYALLOWED, MON_ISAUTH|MON_ALOG, mm_answer_rsa_keyallowed}, | ||
264 | {MONITOR_REQ_KEYALLOWED, MON_ISAUTH|MON_ALOG, mm_answer_keyallowed}, | ||
265 | {MONITOR_REQ_RSACHALLENGE, MON_ONCE, mm_answer_rsa_challenge}, | ||
266 | {MONITOR_REQ_RSARESPONSE, MON_ONCE|MON_AUTHDECIDE, mm_answer_rsa_response}, | ||
267 | #ifdef BSD_AUTH | ||
268 | {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, | ||
269 | {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH, mm_answer_bsdauthrespond}, | ||
270 | #endif | ||
271 | #ifdef SKEY | ||
272 | {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery}, | ||
273 | {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond}, | ||
274 | #endif | ||
275 | #ifdef USE_PAM | ||
276 | {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, | ||
277 | {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, | ||
278 | {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, | ||
279 | {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, | ||
280 | {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, | ||
281 | {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx}, | ||
282 | #endif | ||
283 | #ifdef SSH_AUDIT_EVENTS | ||
284 | {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, | ||
285 | #endif | ||
286 | #endif /* WITH_SSH1 */ | ||
287 | {0, 0, NULL} | ||
288 | }; | ||
289 | |||
290 | struct mon_table mon_dispatch_postauth15[] = { | ||
291 | #ifdef WITH_SSH1 | ||
292 | {MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty}, | ||
293 | {MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup}, | ||
294 | {MONITOR_REQ_TERM, 0, mm_answer_term}, | ||
295 | #ifdef SSH_AUDIT_EVENTS | ||
296 | {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, | ||
297 | {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command}, | ||
298 | #endif | ||
299 | #endif /* WITH_SSH1 */ | ||
300 | {0, 0, NULL} | ||
301 | }; | ||
302 | |||
303 | struct mon_table *mon_dispatch; | 253 | struct mon_table *mon_dispatch; |
304 | 254 | ||
305 | /* Specifies if a certain message is allowed at the moment */ | 255 | /* Specifies if a certain message is allowed at the moment */ |
@@ -348,17 +298,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) | |||
348 | 298 | ||
349 | authctxt->loginmsg = &loginmsg; | 299 | authctxt->loginmsg = &loginmsg; |
350 | 300 | ||
351 | if (compat20) { | 301 | mon_dispatch = mon_dispatch_proto20; |
352 | mon_dispatch = mon_dispatch_proto20; | 302 | /* Permit requests for moduli and signatures */ |
353 | 303 | monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); | |
354 | /* Permit requests for moduli and signatures */ | 304 | monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); |
355 | monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); | ||
356 | monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); | ||
357 | } else { | ||
358 | mon_dispatch = mon_dispatch_proto15; | ||
359 | |||
360 | monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1); | ||
361 | } | ||
362 | 305 | ||
363 | /* The first few requests do not require asynchronous access */ | 306 | /* The first few requests do not require asynchronous access */ |
364 | while (!authenticated) { | 307 | while (!authenticated) { |
@@ -369,9 +312,6 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) | |||
369 | 312 | ||
370 | /* Special handling for multiple required authentications */ | 313 | /* Special handling for multiple required authentications */ |
371 | if (options.num_auth_methods != 0) { | 314 | if (options.num_auth_methods != 0) { |
372 | if (!compat20) | ||
373 | fatal("AuthenticationMethods is not supported" | ||
374 | "with SSH protocol 1"); | ||
375 | if (authenticated && | 315 | if (authenticated && |
376 | !auth2_update_methods_lists(authctxt, | 316 | !auth2_update_methods_lists(authctxt, |
377 | auth_method, auth_submethod)) { | 317 | auth_method, auth_submethod)) { |
@@ -455,17 +395,13 @@ monitor_child_postauth(struct monitor *pmonitor) | |||
455 | signal(SIGXFSZ, SIG_IGN); | 395 | signal(SIGXFSZ, SIG_IGN); |
456 | #endif | 396 | #endif |
457 | 397 | ||
458 | if (compat20) { | 398 | mon_dispatch = mon_dispatch_postauth20; |
459 | mon_dispatch = mon_dispatch_postauth20; | 399 | |
400 | /* Permit requests for moduli and signatures */ | ||
401 | monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); | ||
402 | monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); | ||
403 | monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); | ||
460 | 404 | ||
461 | /* Permit requests for moduli and signatures */ | ||
462 | monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); | ||
463 | monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); | ||
464 | monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); | ||
465 | } else { | ||
466 | mon_dispatch = mon_dispatch_postauth15; | ||
467 | monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); | ||
468 | } | ||
469 | if (!no_pty_flag) { | 405 | if (!no_pty_flag) { |
470 | monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); | 406 | monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); |
471 | monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1); | 407 | monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1); |
@@ -845,7 +781,7 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
845 | #undef M_CP_STRARRAYOPT | 781 | #undef M_CP_STRARRAYOPT |
846 | 782 | ||
847 | /* Create valid auth method lists */ | 783 | /* Create valid auth method lists */ |
848 | if (compat20 && auth2_setup_methods_lists(authctxt) != 0) { | 784 | if (auth2_setup_methods_lists(authctxt) != 0) { |
849 | /* | 785 | /* |
850 | * The monitor will continue long enough to let the child | 786 | * The monitor will continue long enough to let the child |
851 | * run to it's packet_disconnect(), but it must not allow any | 787 | * run to it's packet_disconnect(), but it must not allow any |
@@ -857,14 +793,10 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
857 | debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); | 793 | debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); |
858 | mm_request_send(sock, MONITOR_ANS_PWNAM, m); | 794 | mm_request_send(sock, MONITOR_ANS_PWNAM, m); |
859 | 795 | ||
860 | /* For SSHv1 allow authentication now */ | 796 | /* Allow service/style information on the auth context */ |
861 | if (!compat20) | 797 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); |
862 | monitor_permit_authentications(1); | 798 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); |
863 | else { | 799 | |
864 | /* Allow service/style information on the auth context */ | ||
865 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); | ||
866 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); | ||
867 | } | ||
868 | #ifdef USE_PAM | 800 | #ifdef USE_PAM |
869 | if (options.use_pam) | 801 | if (options.use_pam) |
870 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); | 802 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); |
@@ -991,11 +923,8 @@ mm_answer_bsdauthrespond(int sock, Buffer *m) | |||
991 | debug3("%s: sending authenticated: %d", __func__, authok); | 923 | debug3("%s: sending authenticated: %d", __func__, authok); |
992 | mm_request_send(sock, MONITOR_ANS_BSDAUTHRESPOND, m); | 924 | mm_request_send(sock, MONITOR_ANS_BSDAUTHRESPOND, m); |
993 | 925 | ||
994 | if (compat20) { | 926 | auth_method = "keyboard-interactive"; |
995 | auth_method = "keyboard-interactive"; | 927 | auth_submethod = "bsdauth"; |
996 | auth_submethod = "bsdauth"; | ||
997 | } else | ||
998 | auth_method = "bsdauth"; | ||
999 | 928 | ||
1000 | return (authok != 0); | 929 | return (authok != 0); |
1001 | } | 930 | } |
@@ -1205,10 +1134,6 @@ mm_answer_keyallowed(int sock, Buffer *m) | |||
1205 | 1134 | ||
1206 | key = key_from_blob(blob, bloblen); | 1135 | key = key_from_blob(blob, bloblen); |
1207 | 1136 | ||
1208 | if ((compat20 && type == MM_RSAHOSTKEY) || | ||
1209 | (!compat20 && type != MM_RSAHOSTKEY)) | ||
1210 | fatal("%s: key type and protocol mismatch", __func__); | ||
1211 | |||
1212 | debug3("%s: key_from_blob: %p", __func__, key); | 1137 | debug3("%s: key_from_blob: %p", __func__, key); |
1213 | 1138 | ||
1214 | if (key != NULL && authctxt->valid) { | 1139 | if (key != NULL && authctxt->valid) { |
@@ -1242,17 +1167,6 @@ mm_answer_keyallowed(int sock, Buffer *m) | |||
1242 | cuser, chost); | 1167 | cuser, chost); |
1243 | auth_method = "hostbased"; | 1168 | auth_method = "hostbased"; |
1244 | break; | 1169 | break; |
1245 | #ifdef WITH_SSH1 | ||
1246 | case MM_RSAHOSTKEY: | ||
1247 | key->type = KEY_RSA1; /* XXX */ | ||
1248 | allowed = options.rhosts_rsa_authentication && | ||
1249 | auth_rhosts_rsa_key_allowed(authctxt->pw, | ||
1250 | cuser, chost, key); | ||
1251 | if (options.rhosts_rsa_authentication && allowed != 1) | ||
1252 | auth_clear_options(); | ||
1253 | auth_method = "rsa"; | ||
1254 | break; | ||
1255 | #endif | ||
1256 | default: | 1170 | default: |
1257 | fatal("%s: unknown key type %d", __func__, type); | 1171 | fatal("%s: unknown key type %d", __func__, type); |
1258 | break; | 1172 | break; |
@@ -1289,9 +1203,6 @@ mm_answer_keyallowed(int sock, Buffer *m) | |||
1289 | 1203 | ||
1290 | mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m); | 1204 | mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m); |
1291 | 1205 | ||
1292 | if (type == MM_RSAHOSTKEY) | ||
1293 | monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed); | ||
1294 | |||
1295 | return (0); | 1206 | return (0); |
1296 | } | 1207 | } |
1297 | 1208 | ||
@@ -1600,186 +1511,6 @@ mm_answer_pty_cleanup(int sock, Buffer *m) | |||
1600 | return (0); | 1511 | return (0); |
1601 | } | 1512 | } |
1602 | 1513 | ||
1603 | #ifdef WITH_SSH1 | ||
1604 | int | ||
1605 | mm_answer_sesskey(int sock, Buffer *m) | ||
1606 | { | ||
1607 | BIGNUM *p; | ||
1608 | int rsafail; | ||
1609 | |||
1610 | /* Turn off permissions */ | ||
1611 | monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 0); | ||
1612 | |||
1613 | if ((p = BN_new()) == NULL) | ||
1614 | fatal("%s: BN_new", __func__); | ||
1615 | |||
1616 | buffer_get_bignum2(m, p); | ||
1617 | |||
1618 | rsafail = ssh1_session_key(p); | ||
1619 | |||
1620 | buffer_clear(m); | ||
1621 | buffer_put_int(m, rsafail); | ||
1622 | buffer_put_bignum2(m, p); | ||
1623 | |||
1624 | BN_clear_free(p); | ||
1625 | |||
1626 | mm_request_send(sock, MONITOR_ANS_SESSKEY, m); | ||
1627 | |||
1628 | /* Turn on permissions for sessid passing */ | ||
1629 | monitor_permit(mon_dispatch, MONITOR_REQ_SESSID, 1); | ||
1630 | |||
1631 | return (0); | ||
1632 | } | ||
1633 | |||
1634 | int | ||
1635 | mm_answer_sessid(int sock, Buffer *m) | ||
1636 | { | ||
1637 | int i; | ||
1638 | |||
1639 | debug3("%s entering", __func__); | ||
1640 | |||
1641 | if (buffer_len(m) != 16) | ||
1642 | fatal("%s: bad ssh1 session id", __func__); | ||
1643 | for (i = 0; i < 16; i++) | ||
1644 | session_id[i] = buffer_get_char(m); | ||
1645 | |||
1646 | /* Turn on permissions for getpwnam */ | ||
1647 | monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); | ||
1648 | |||
1649 | return (0); | ||
1650 | } | ||
1651 | |||
1652 | int | ||
1653 | mm_answer_rsa_keyallowed(int sock, Buffer *m) | ||
1654 | { | ||
1655 | BIGNUM *client_n; | ||
1656 | Key *key = NULL; | ||
1657 | u_char *blob = NULL; | ||
1658 | u_int blen = 0; | ||
1659 | int allowed = 0; | ||
1660 | |||
1661 | debug3("%s entering", __func__); | ||
1662 | |||
1663 | auth_method = "rsa"; | ||
1664 | if (options.rsa_authentication && authctxt->valid) { | ||
1665 | if ((client_n = BN_new()) == NULL) | ||
1666 | fatal("%s: BN_new", __func__); | ||
1667 | buffer_get_bignum2(m, client_n); | ||
1668 | allowed = auth_rsa_key_allowed(authctxt->pw, client_n, &key); | ||
1669 | BN_clear_free(client_n); | ||
1670 | } | ||
1671 | buffer_clear(m); | ||
1672 | buffer_put_int(m, allowed); | ||
1673 | buffer_put_int(m, forced_command != NULL); | ||
1674 | |||
1675 | /* clear temporarily storage (used by generate challenge) */ | ||
1676 | monitor_reset_key_state(); | ||
1677 | |||
1678 | if (allowed && key != NULL) { | ||
1679 | key->type = KEY_RSA; /* cheat for key_to_blob */ | ||
1680 | if (key_to_blob(key, &blob, &blen) == 0) | ||
1681 | fatal("%s: key_to_blob failed", __func__); | ||
1682 | buffer_put_string(m, blob, blen); | ||
1683 | |||
1684 | /* Save temporarily for comparison in verify */ | ||
1685 | key_blob = blob; | ||
1686 | key_bloblen = blen; | ||
1687 | key_blobtype = MM_RSAUSERKEY; | ||
1688 | } | ||
1689 | if (key != NULL) | ||
1690 | key_free(key); | ||
1691 | |||
1692 | mm_request_send(sock, MONITOR_ANS_RSAKEYALLOWED, m); | ||
1693 | |||
1694 | monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed); | ||
1695 | monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 0); | ||
1696 | return (0); | ||
1697 | } | ||
1698 | |||
1699 | int | ||
1700 | mm_answer_rsa_challenge(int sock, Buffer *m) | ||
1701 | { | ||
1702 | Key *key = NULL; | ||
1703 | u_char *blob; | ||
1704 | u_int blen; | ||
1705 | |||
1706 | debug3("%s entering", __func__); | ||
1707 | |||
1708 | if (!authctxt->valid) | ||
1709 | fatal("%s: authctxt not valid", __func__); | ||
1710 | blob = buffer_get_string(m, &blen); | ||
1711 | if (!monitor_allowed_key(blob, blen)) | ||
1712 | fatal("%s: bad key, not previously allowed", __func__); | ||
1713 | if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY) | ||
1714 | fatal("%s: key type mismatch", __func__); | ||
1715 | if ((key = key_from_blob(blob, blen)) == NULL) | ||
1716 | fatal("%s: received bad key", __func__); | ||
1717 | if (key->type != KEY_RSA) | ||
1718 | fatal("%s: received bad key type %d", __func__, key->type); | ||
1719 | key->type = KEY_RSA1; | ||
1720 | if (ssh1_challenge) | ||
1721 | BN_clear_free(ssh1_challenge); | ||
1722 | ssh1_challenge = auth_rsa_generate_challenge(key); | ||
1723 | |||
1724 | buffer_clear(m); | ||
1725 | buffer_put_bignum2(m, ssh1_challenge); | ||
1726 | |||
1727 | debug3("%s sending reply", __func__); | ||
1728 | mm_request_send(sock, MONITOR_ANS_RSACHALLENGE, m); | ||
1729 | |||
1730 | monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 1); | ||
1731 | |||
1732 | free(blob); | ||
1733 | key_free(key); | ||
1734 | return (0); | ||
1735 | } | ||
1736 | |||
1737 | int | ||
1738 | mm_answer_rsa_response(int sock, Buffer *m) | ||
1739 | { | ||
1740 | Key *key = NULL; | ||
1741 | u_char *blob, *response; | ||
1742 | u_int blen, len; | ||
1743 | int success; | ||
1744 | |||
1745 | debug3("%s entering", __func__); | ||
1746 | |||
1747 | if (!authctxt->valid) | ||
1748 | fatal("%s: authctxt not valid", __func__); | ||
1749 | if (ssh1_challenge == NULL) | ||
1750 | fatal("%s: no ssh1_challenge", __func__); | ||
1751 | |||
1752 | blob = buffer_get_string(m, &blen); | ||
1753 | if (!monitor_allowed_key(blob, blen)) | ||
1754 | fatal("%s: bad key, not previously allowed", __func__); | ||
1755 | if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY) | ||
1756 | fatal("%s: key type mismatch: %d", __func__, key_blobtype); | ||
1757 | if ((key = key_from_blob(blob, blen)) == NULL) | ||
1758 | fatal("%s: received bad key", __func__); | ||
1759 | response = buffer_get_string(m, &len); | ||
1760 | if (len != 16) | ||
1761 | fatal("%s: received bad response to challenge", __func__); | ||
1762 | success = auth_rsa_verify_response(key, ssh1_challenge, response); | ||
1763 | |||
1764 | free(blob); | ||
1765 | key_free(key); | ||
1766 | free(response); | ||
1767 | |||
1768 | auth_method = key_blobtype == MM_RSAUSERKEY ? "rsa" : "rhosts-rsa"; | ||
1769 | |||
1770 | /* reset state */ | ||
1771 | BN_clear_free(ssh1_challenge); | ||
1772 | ssh1_challenge = NULL; | ||
1773 | monitor_reset_key_state(); | ||
1774 | |||
1775 | buffer_clear(m); | ||
1776 | buffer_put_int(m, success); | ||
1777 | mm_request_send(sock, MONITOR_ANS_RSARESPONSE, m); | ||
1778 | |||
1779 | return (success); | ||
1780 | } | ||
1781 | #endif | ||
1782 | |||
1783 | int | 1514 | int |
1784 | mm_answer_term(int sock, Buffer *req) | 1515 | mm_answer_term(int sock, Buffer *req) |
1785 | { | 1516 | { |