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