diff options
Diffstat (limited to 'monitor.c')
-rw-r--r-- | monitor.c | 139 |
1 files changed, 128 insertions, 11 deletions
@@ -148,6 +148,8 @@ int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *); | |||
148 | int mm_answer_gss_accept_ctx(struct ssh *, int, struct sshbuf *); | 148 | int mm_answer_gss_accept_ctx(struct ssh *, int, struct sshbuf *); |
149 | int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); | 149 | int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); |
150 | int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); | 150 | int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); |
151 | int mm_answer_gss_sign(struct ssh *, int, struct sshbuf *); | ||
152 | int mm_answer_gss_updatecreds(struct ssh *, int, struct sshbuf *); | ||
151 | #endif | 153 | #endif |
152 | 154 | ||
153 | #ifdef SSH_AUDIT_EVENTS | 155 | #ifdef SSH_AUDIT_EVENTS |
@@ -220,11 +222,18 @@ struct mon_table mon_dispatch_proto20[] = { | |||
220 | {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, | 222 | {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, |
221 | {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, | 223 | {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, |
222 | {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, | 224 | {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, |
225 | {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, | ||
223 | #endif | 226 | #endif |
224 | {0, 0, NULL} | 227 | {0, 0, NULL} |
225 | }; | 228 | }; |
226 | 229 | ||
227 | struct mon_table mon_dispatch_postauth20[] = { | 230 | struct mon_table mon_dispatch_postauth20[] = { |
231 | #ifdef GSSAPI | ||
232 | {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, | ||
233 | {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, | ||
234 | {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, | ||
235 | {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, | ||
236 | #endif | ||
228 | #ifdef WITH_OPENSSL | 237 | #ifdef WITH_OPENSSL |
229 | {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, | 238 | {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, |
230 | #endif | 239 | #endif |
@@ -293,6 +302,10 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) | |||
293 | /* Permit requests for moduli and signatures */ | 302 | /* Permit requests for moduli and signatures */ |
294 | monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); | 303 | monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); |
295 | monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); | 304 | monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); |
305 | #ifdef GSSAPI | ||
306 | /* and for the GSSAPI key exchange */ | ||
307 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); | ||
308 | #endif | ||
296 | 309 | ||
297 | /* The first few requests do not require asynchronous access */ | 310 | /* The first few requests do not require asynchronous access */ |
298 | while (!authenticated) { | 311 | while (!authenticated) { |
@@ -406,6 +419,10 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor) | |||
406 | monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); | 419 | monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); |
407 | monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); | 420 | monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); |
408 | monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); | 421 | monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); |
422 | #ifdef GSSAPI | ||
423 | /* and for the GSSAPI key exchange */ | ||
424 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); | ||
425 | #endif | ||
409 | 426 | ||
410 | if (auth_opts->permit_pty_flag) { | 427 | if (auth_opts->permit_pty_flag) { |
411 | monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); | 428 | monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); |
@@ -1712,6 +1729,17 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) | |||
1712 | # ifdef OPENSSL_HAS_ECC | 1729 | # ifdef OPENSSL_HAS_ECC |
1713 | kex->kex[KEX_ECDH_SHA2] = kex_gen_server; | 1730 | kex->kex[KEX_ECDH_SHA2] = kex_gen_server; |
1714 | # endif | 1731 | # endif |
1732 | # ifdef GSSAPI | ||
1733 | if (options.gss_keyex) { | ||
1734 | kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; | ||
1735 | kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; | ||
1736 | kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; | ||
1737 | kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; | ||
1738 | kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server; | ||
1739 | kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server; | ||
1740 | kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server; | ||
1741 | } | ||
1742 | # endif | ||
1715 | #endif /* WITH_OPENSSL */ | 1743 | #endif /* WITH_OPENSSL */ |
1716 | kex->kex[KEX_C25519_SHA256] = kex_gen_server; | 1744 | kex->kex[KEX_C25519_SHA256] = kex_gen_server; |
1717 | kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_server; | 1745 | kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_server; |
@@ -1805,8 +1833,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) | |||
1805 | u_char *p; | 1833 | u_char *p; |
1806 | int r; | 1834 | int r; |
1807 | 1835 | ||
1808 | if (!options.gss_authentication) | 1836 | if (!options.gss_authentication && !options.gss_keyex) |
1809 | fatal("%s: GSSAPI authentication not enabled", __func__); | 1837 | fatal("%s: GSSAPI not enabled", __func__); |
1810 | 1838 | ||
1811 | if ((r = sshbuf_get_string(m, &p, &len)) != 0) | 1839 | if ((r = sshbuf_get_string(m, &p, &len)) != 0) |
1812 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 1840 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
@@ -1838,8 +1866,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) | |||
1838 | OM_uint32 flags = 0; /* GSI needs this */ | 1866 | OM_uint32 flags = 0; /* GSI needs this */ |
1839 | int r; | 1867 | int r; |
1840 | 1868 | ||
1841 | if (!options.gss_authentication) | 1869 | if (!options.gss_authentication && !options.gss_keyex) |
1842 | fatal("%s: GSSAPI authentication not enabled", __func__); | 1870 | fatal("%s: GSSAPI not enabled", __func__); |
1843 | 1871 | ||
1844 | if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0) | 1872 | if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0) |
1845 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 1873 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
@@ -1859,6 +1887,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) | |||
1859 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); | 1887 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); |
1860 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); | 1888 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); |
1861 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); | 1889 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); |
1890 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1); | ||
1862 | } | 1891 | } |
1863 | return (0); | 1892 | return (0); |
1864 | } | 1893 | } |
@@ -1870,8 +1899,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) | |||
1870 | OM_uint32 ret; | 1899 | OM_uint32 ret; |
1871 | int r; | 1900 | int r; |
1872 | 1901 | ||
1873 | if (!options.gss_authentication) | 1902 | if (!options.gss_authentication && !options.gss_keyex) |
1874 | fatal("%s: GSSAPI authentication not enabled", __func__); | 1903 | fatal("%s: GSSAPI not enabled", __func__); |
1875 | 1904 | ||
1876 | if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 || | 1905 | if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 || |
1877 | (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0) | 1906 | (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0) |
@@ -1897,13 +1926,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) | |||
1897 | int | 1926 | int |
1898 | mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) | 1927 | mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) |
1899 | { | 1928 | { |
1900 | int r, authenticated; | 1929 | int r, authenticated, kex; |
1901 | const char *displayname; | 1930 | const char *displayname; |
1902 | 1931 | ||
1903 | if (!options.gss_authentication) | 1932 | if (!options.gss_authentication && !options.gss_keyex) |
1904 | fatal("%s: GSSAPI authentication not enabled", __func__); | 1933 | fatal("%s: GSSAPI not enabled", __func__); |
1905 | 1934 | ||
1906 | authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); | 1935 | if ((r = sshbuf_get_u32(m, &kex)) != 0) |
1936 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1937 | |||
1938 | authenticated = authctxt->valid && | ||
1939 | ssh_gssapi_userok(authctxt->user, authctxt->pw, kex); | ||
1907 | 1940 | ||
1908 | sshbuf_reset(m); | 1941 | sshbuf_reset(m); |
1909 | if ((r = sshbuf_put_u32(m, authenticated)) != 0) | 1942 | if ((r = sshbuf_put_u32(m, authenticated)) != 0) |
@@ -1912,7 +1945,11 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) | |||
1912 | debug3("%s: sending result %d", __func__, authenticated); | 1945 | debug3("%s: sending result %d", __func__, authenticated); |
1913 | mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); | 1946 | mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); |
1914 | 1947 | ||
1915 | auth_method = "gssapi-with-mic"; | 1948 | if (kex) { |
1949 | auth_method = "gssapi-keyex"; | ||
1950 | } else { | ||
1951 | auth_method = "gssapi-with-mic"; | ||
1952 | } | ||
1916 | 1953 | ||
1917 | if ((displayname = ssh_gssapi_displayname()) != NULL) | 1954 | if ((displayname = ssh_gssapi_displayname()) != NULL) |
1918 | auth2_record_info(authctxt, "%s", displayname); | 1955 | auth2_record_info(authctxt, "%s", displayname); |
@@ -1920,5 +1957,85 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) | |||
1920 | /* Monitor loop will terminate if authenticated */ | 1957 | /* Monitor loop will terminate if authenticated */ |
1921 | return (authenticated); | 1958 | return (authenticated); |
1922 | } | 1959 | } |
1960 | |||
1961 | int | ||
1962 | mm_answer_gss_sign(struct ssh *ssh, int socket, struct sshbuf *m) | ||
1963 | { | ||
1964 | gss_buffer_desc data; | ||
1965 | gss_buffer_desc hash = GSS_C_EMPTY_BUFFER; | ||
1966 | OM_uint32 major, minor; | ||
1967 | size_t len; | ||
1968 | u_char *p = NULL; | ||
1969 | int r; | ||
1970 | |||
1971 | if (!options.gss_authentication && !options.gss_keyex) | ||
1972 | fatal("%s: GSSAPI not enabled", __func__); | ||
1973 | |||
1974 | if ((r = sshbuf_get_string(m, &p, &len)) != 0) | ||
1975 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1976 | data.value = p; | ||
1977 | data.length = len; | ||
1978 | /* Lengths of SHA-1, SHA-256 and SHA-512 hashes that are used */ | ||
1979 | if (data.length != 20 && data.length != 32 && data.length != 64) | ||
1980 | fatal("%s: data length incorrect: %d", __func__, | ||
1981 | (int) data.length); | ||
1982 | |||
1983 | /* Save the session ID on the first time around */ | ||
1984 | if (session_id2_len == 0) { | ||
1985 | session_id2_len = data.length; | ||
1986 | session_id2 = xmalloc(session_id2_len); | ||
1987 | memcpy(session_id2, data.value, session_id2_len); | ||
1988 | } | ||
1989 | major = ssh_gssapi_sign(gsscontext, &data, &hash); | ||
1990 | |||
1991 | free(data.value); | ||
1992 | |||
1993 | sshbuf_reset(m); | ||
1994 | |||
1995 | if ((r = sshbuf_put_u32(m, major)) != 0 || | ||
1996 | (r = sshbuf_put_string(m, hash.value, hash.length)) != 0) | ||
1997 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1998 | |||
1999 | mm_request_send(socket, MONITOR_ANS_GSSSIGN, m); | ||
2000 | |||
2001 | gss_release_buffer(&minor, &hash); | ||
2002 | |||
2003 | /* Turn on getpwnam permissions */ | ||
2004 | monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); | ||
2005 | |||
2006 | /* And credential updating, for when rekeying */ | ||
2007 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1); | ||
2008 | |||
2009 | return (0); | ||
2010 | } | ||
2011 | |||
2012 | int | ||
2013 | mm_answer_gss_updatecreds(struct ssh *ssh, int socket, struct sshbuf *m) { | ||
2014 | ssh_gssapi_ccache store; | ||
2015 | int r, ok; | ||
2016 | |||
2017 | if (!options.gss_authentication && !options.gss_keyex) | ||
2018 | fatal("%s: GSSAPI not enabled", __func__); | ||
2019 | |||
2020 | if ((r = sshbuf_get_string(m, (u_char **)&store.filename, NULL)) != 0 || | ||
2021 | (r = sshbuf_get_string(m, (u_char **)&store.envvar, NULL)) != 0 || | ||
2022 | (r = sshbuf_get_string(m, (u_char **)&store.envval, NULL)) != 0) | ||
2023 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
2024 | |||
2025 | ok = ssh_gssapi_update_creds(&store); | ||
2026 | |||
2027 | free(store.filename); | ||
2028 | free(store.envvar); | ||
2029 | free(store.envval); | ||
2030 | |||
2031 | sshbuf_reset(m); | ||
2032 | if ((r = sshbuf_put_u32(m, ok)) != 0) | ||
2033 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
2034 | |||
2035 | mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m); | ||
2036 | |||
2037 | return(0); | ||
2038 | } | ||
2039 | |||
1923 | #endif /* GSSAPI */ | 2040 | #endif /* GSSAPI */ |
1924 | 2041 | ||