diff options
Diffstat (limited to 'monitor.c')
-rw-r--r-- | monitor.c | 122 |
1 files changed, 113 insertions, 9 deletions
@@ -145,6 +145,8 @@ int mm_answer_gss_setup_ctx(int, struct sshbuf *); | |||
145 | int mm_answer_gss_accept_ctx(int, struct sshbuf *); | 145 | int mm_answer_gss_accept_ctx(int, struct sshbuf *); |
146 | int mm_answer_gss_userok(int, struct sshbuf *); | 146 | int mm_answer_gss_userok(int, struct sshbuf *); |
147 | int mm_answer_gss_checkmic(int, struct sshbuf *); | 147 | int mm_answer_gss_checkmic(int, struct sshbuf *); |
148 | int mm_answer_gss_sign(int, struct sshbuf *); | ||
149 | int mm_answer_gss_updatecreds(int, struct sshbuf *); | ||
148 | #endif | 150 | #endif |
149 | 151 | ||
150 | #ifdef SSH_AUDIT_EVENTS | 152 | #ifdef SSH_AUDIT_EVENTS |
@@ -215,11 +217,18 @@ struct mon_table mon_dispatch_proto20[] = { | |||
215 | {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, | 217 | {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, |
216 | {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, | 218 | {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, |
217 | {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, | 219 | {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, |
220 | {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, | ||
218 | #endif | 221 | #endif |
219 | {0, 0, NULL} | 222 | {0, 0, NULL} |
220 | }; | 223 | }; |
221 | 224 | ||
222 | struct mon_table mon_dispatch_postauth20[] = { | 225 | struct mon_table mon_dispatch_postauth20[] = { |
226 | #ifdef GSSAPI | ||
227 | {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, | ||
228 | {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, | ||
229 | {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, | ||
230 | {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, | ||
231 | #endif | ||
223 | #ifdef WITH_OPENSSL | 232 | #ifdef WITH_OPENSSL |
224 | {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, | 233 | {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, |
225 | #endif | 234 | #endif |
@@ -289,6 +298,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) | |||
289 | /* Permit requests for moduli and signatures */ | 298 | /* Permit requests for moduli and signatures */ |
290 | monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); | 299 | monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); |
291 | monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); | 300 | monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); |
301 | #ifdef GSSAPI | ||
302 | /* and for the GSSAPI key exchange */ | ||
303 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); | ||
304 | #endif | ||
292 | 305 | ||
293 | /* The first few requests do not require asynchronous access */ | 306 | /* The first few requests do not require asynchronous access */ |
294 | while (!authenticated) { | 307 | while (!authenticated) { |
@@ -401,6 +414,10 @@ monitor_child_postauth(struct monitor *pmonitor) | |||
401 | monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); | 414 | monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); |
402 | monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); | 415 | monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); |
403 | monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); | 416 | monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); |
417 | #ifdef GSSAPI | ||
418 | /* and for the GSSAPI key exchange */ | ||
419 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1); | ||
420 | #endif | ||
404 | 421 | ||
405 | if (auth_opts->permit_pty_flag) { | 422 | if (auth_opts->permit_pty_flag) { |
406 | monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); | 423 | monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); |
@@ -1666,6 +1683,13 @@ monitor_apply_keystate(struct monitor *pmonitor) | |||
1666 | # endif | 1683 | # endif |
1667 | #endif /* WITH_OPENSSL */ | 1684 | #endif /* WITH_OPENSSL */ |
1668 | kex->kex[KEX_C25519_SHA256] = kexc25519_server; | 1685 | kex->kex[KEX_C25519_SHA256] = kexc25519_server; |
1686 | #ifdef GSSAPI | ||
1687 | if (options.gss_keyex) { | ||
1688 | kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; | ||
1689 | kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; | ||
1690 | kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; | ||
1691 | } | ||
1692 | #endif | ||
1669 | kex->load_host_public_key=&get_hostkey_public_by_type; | 1693 | kex->load_host_public_key=&get_hostkey_public_by_type; |
1670 | kex->load_host_private_key=&get_hostkey_private_by_type; | 1694 | kex->load_host_private_key=&get_hostkey_private_by_type; |
1671 | kex->host_key_index=&get_hostkey_index; | 1695 | kex->host_key_index=&get_hostkey_index; |
@@ -1756,8 +1780,8 @@ mm_answer_gss_setup_ctx(int sock, struct sshbuf *m) | |||
1756 | u_char *p; | 1780 | u_char *p; |
1757 | int r; | 1781 | int r; |
1758 | 1782 | ||
1759 | if (!options.gss_authentication) | 1783 | if (!options.gss_authentication && !options.gss_keyex) |
1760 | fatal("%s: GSSAPI authentication not enabled", __func__); | 1784 | fatal("%s: GSSAPI not enabled", __func__); |
1761 | 1785 | ||
1762 | if ((r = sshbuf_get_string(m, &p, &len)) != 0) | 1786 | if ((r = sshbuf_get_string(m, &p, &len)) != 0) |
1763 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 1787 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
@@ -1789,8 +1813,8 @@ mm_answer_gss_accept_ctx(int sock, struct sshbuf *m) | |||
1789 | OM_uint32 flags = 0; /* GSI needs this */ | 1813 | OM_uint32 flags = 0; /* GSI needs this */ |
1790 | int r; | 1814 | int r; |
1791 | 1815 | ||
1792 | if (!options.gss_authentication) | 1816 | if (!options.gss_authentication && !options.gss_keyex) |
1793 | fatal("%s: GSSAPI authentication not enabled", __func__); | 1817 | fatal("%s: GSSAPI not enabled", __func__); |
1794 | 1818 | ||
1795 | if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0) | 1819 | if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0) |
1796 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 1820 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
@@ -1810,6 +1834,7 @@ mm_answer_gss_accept_ctx(int sock, struct sshbuf *m) | |||
1810 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); | 1834 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); |
1811 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); | 1835 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); |
1812 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); | 1836 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); |
1837 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1); | ||
1813 | } | 1838 | } |
1814 | return (0); | 1839 | return (0); |
1815 | } | 1840 | } |
@@ -1821,8 +1846,8 @@ mm_answer_gss_checkmic(int sock, struct sshbuf *m) | |||
1821 | OM_uint32 ret; | 1846 | OM_uint32 ret; |
1822 | int r; | 1847 | int r; |
1823 | 1848 | ||
1824 | if (!options.gss_authentication) | 1849 | if (!options.gss_authentication && !options.gss_keyex) |
1825 | fatal("%s: GSSAPI authentication not enabled", __func__); | 1850 | fatal("%s: GSSAPI not enabled", __func__); |
1826 | 1851 | ||
1827 | if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 || | 1852 | if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 || |
1828 | (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0) | 1853 | (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0) |
@@ -1851,10 +1876,11 @@ mm_answer_gss_userok(int sock, struct sshbuf *m) | |||
1851 | int r, authenticated; | 1876 | int r, authenticated; |
1852 | const char *displayname; | 1877 | const char *displayname; |
1853 | 1878 | ||
1854 | if (!options.gss_authentication) | 1879 | if (!options.gss_authentication && !options.gss_keyex) |
1855 | fatal("%s: GSSAPI authentication not enabled", __func__); | 1880 | fatal("%s: GSSAPI not enabled", __func__); |
1856 | 1881 | ||
1857 | authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); | 1882 | authenticated = authctxt->valid && |
1883 | ssh_gssapi_userok(authctxt->user, authctxt->pw); | ||
1858 | 1884 | ||
1859 | sshbuf_reset(m); | 1885 | sshbuf_reset(m); |
1860 | if ((r = sshbuf_put_u32(m, authenticated)) != 0) | 1886 | if ((r = sshbuf_put_u32(m, authenticated)) != 0) |
@@ -1871,5 +1897,83 @@ mm_answer_gss_userok(int sock, struct sshbuf *m) | |||
1871 | /* Monitor loop will terminate if authenticated */ | 1897 | /* Monitor loop will terminate if authenticated */ |
1872 | return (authenticated); | 1898 | return (authenticated); |
1873 | } | 1899 | } |
1900 | |||
1901 | int | ||
1902 | mm_answer_gss_sign(int socket, struct sshbuf *m) | ||
1903 | { | ||
1904 | gss_buffer_desc data; | ||
1905 | gss_buffer_desc hash = GSS_C_EMPTY_BUFFER; | ||
1906 | OM_uint32 major, minor; | ||
1907 | size_t len; | ||
1908 | u_char *p; | ||
1909 | int r; | ||
1910 | |||
1911 | if (!options.gss_authentication && !options.gss_keyex) | ||
1912 | fatal("%s: GSSAPI not enabled", __func__); | ||
1913 | |||
1914 | if ((r = sshbuf_get_string(m, &p, &len)) != 0) | ||
1915 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1916 | data.value = p; | ||
1917 | data.length = len; | ||
1918 | if (data.length != 20) | ||
1919 | fatal("%s: data length incorrect: %d", __func__, | ||
1920 | (int) data.length); | ||
1921 | |||
1922 | /* Save the session ID on the first time around */ | ||
1923 | if (session_id2_len == 0) { | ||
1924 | session_id2_len = data.length; | ||
1925 | session_id2 = xmalloc(session_id2_len); | ||
1926 | memcpy(session_id2, data.value, session_id2_len); | ||
1927 | } | ||
1928 | major = ssh_gssapi_sign(gsscontext, &data, &hash); | ||
1929 | |||
1930 | free(data.value); | ||
1931 | |||
1932 | sshbuf_reset(m); | ||
1933 | if ((r = sshbuf_put_u32(m, major)) != 0 || | ||
1934 | (r = sshbuf_put_string(m, hash.value, hash.length)) != 0) | ||
1935 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1936 | |||
1937 | mm_request_send(socket, MONITOR_ANS_GSSSIGN, m); | ||
1938 | |||
1939 | gss_release_buffer(&minor, &hash); | ||
1940 | |||
1941 | /* Turn on getpwnam permissions */ | ||
1942 | monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); | ||
1943 | |||
1944 | /* And credential updating, for when rekeying */ | ||
1945 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1); | ||
1946 | |||
1947 | return (0); | ||
1948 | } | ||
1949 | |||
1950 | int | ||
1951 | mm_answer_gss_updatecreds(int socket, struct sshbuf *m) { | ||
1952 | ssh_gssapi_ccache store; | ||
1953 | int r, ok; | ||
1954 | |||
1955 | if (!options.gss_authentication && !options.gss_keyex) | ||
1956 | fatal("%s: GSSAPI not enabled", __func__); | ||
1957 | |||
1958 | if ((r = sshbuf_get_cstring(m, &store.filename, NULL)) != 0 || | ||
1959 | (r = sshbuf_get_cstring(m, &store.envvar, NULL)) != 0 || | ||
1960 | (r = sshbuf_get_cstring(m, &store.envval, NULL)) != 0) | ||
1961 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1962 | |||
1963 | ok = ssh_gssapi_update_creds(&store); | ||
1964 | |||
1965 | free(store.filename); | ||
1966 | free(store.envvar); | ||
1967 | free(store.envval); | ||
1968 | |||
1969 | sshbuf_reset(m); | ||
1970 | if ((r = sshbuf_put_u32(m, ok)) != 0) | ||
1971 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1972 | |||
1973 | mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m); | ||
1974 | |||
1975 | return(0); | ||
1976 | } | ||
1977 | |||
1874 | #endif /* GSSAPI */ | 1978 | #endif /* GSSAPI */ |
1875 | 1979 | ||