summaryrefslogtreecommitdiff
path: root/monitor.c
diff options
context:
space:
mode:
authorSimon Wilkinson <simon@sxw.org.uk>2014-02-09 16:09:48 +0000
committerColin Watson <cjwatson@debian.org>2018-10-20 22:54:00 +0100
commit72b1d308e6400194ef6e4e7dd45bfa48fa39b5e6 (patch)
tree2a3b57ae5446f4273804064ccc42659adfc2a3b2 /monitor.c
parent3d246f10429fc9a37b98eabef94fe8dc7c61002b (diff)
GSSAPI key exchange support
This patch has been rejected upstream: "None of the OpenSSH developers are in favour of adding this, and this situation has not changed for several years. This is not a slight on Simon's patch, which is of fine quality, but just that a) we don't trust GSSAPI implementations that much and b) we don't like adding new KEX since they are pre-auth attack surface. This one is particularly scary, since it requires hooks out to typically root-owned system resources." However, quite a lot of people rely on this in Debian, and it's better to have it merged into the main openssh package rather than having separate -krb5 packages (as we used to have). It seems to have a generally good security history. Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1242 Last-Updated: 2018-10-20 Patch-Name: gssapi.patch
Diffstat (limited to 'monitor.c')
-rw-r--r--monitor.c122
1 files changed, 113 insertions, 9 deletions
diff --git a/monitor.c b/monitor.c
index 531b2993a..eabc1e89b 100644
--- a/monitor.c
+++ b/monitor.c
@@ -145,6 +145,8 @@ int mm_answer_gss_setup_ctx(int, struct sshbuf *);
145int mm_answer_gss_accept_ctx(int, struct sshbuf *); 145int mm_answer_gss_accept_ctx(int, struct sshbuf *);
146int mm_answer_gss_userok(int, struct sshbuf *); 146int mm_answer_gss_userok(int, struct sshbuf *);
147int mm_answer_gss_checkmic(int, struct sshbuf *); 147int mm_answer_gss_checkmic(int, struct sshbuf *);
148int mm_answer_gss_sign(int, struct sshbuf *);
149int 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
222struct mon_table mon_dispatch_postauth20[] = { 225struct 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
1901int
1902mm_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
1950int
1951mm_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