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>2019-06-05 07:06:44 +0100
commit7ce79be85036c4b36937f1b1ba85f6094068412c (patch)
treec964917d8395ef5605cff9513aad4458b222beae /monitor.c
parent102062f825fb26a74295a1c089c00c4c4c76b68a (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. Origin: other, https://github.com/openssh-gsskex/openssh-gsskex/commits/debian/master Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1242 Last-Updated: 2019-06-05 Patch-Name: gssapi.patch
Diffstat (limited to 'monitor.c')
-rw-r--r--monitor.c139
1 files changed, 128 insertions, 11 deletions
diff --git a/monitor.c b/monitor.c
index 60e529444..0766d6ef5 100644
--- a/monitor.c
+++ b/monitor.c
@@ -147,6 +147,8 @@ int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *);
147int mm_answer_gss_accept_ctx(struct ssh *, int, struct sshbuf *); 147int mm_answer_gss_accept_ctx(struct ssh *, int, struct sshbuf *);
148int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); 148int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *);
149int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); 149int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *);
150int mm_answer_gss_sign(struct ssh *, int, struct sshbuf *);
151int mm_answer_gss_updatecreds(struct ssh *, int, struct sshbuf *);
150#endif 152#endif
151 153
152#ifdef SSH_AUDIT_EVENTS 154#ifdef SSH_AUDIT_EVENTS
@@ -219,11 +221,18 @@ struct mon_table mon_dispatch_proto20[] = {
219 {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, 221 {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx},
220 {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, 222 {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok},
221 {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, 223 {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic},
224 {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
222#endif 225#endif
223 {0, 0, NULL} 226 {0, 0, NULL}
224}; 227};
225 228
226struct mon_table mon_dispatch_postauth20[] = { 229struct mon_table mon_dispatch_postauth20[] = {
230#ifdef GSSAPI
231 {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx},
232 {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx},
233 {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign},
234 {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds},
235#endif
227#ifdef WITH_OPENSSL 236#ifdef WITH_OPENSSL
228 {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, 237 {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
229#endif 238#endif
@@ -292,6 +301,10 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor)
292 /* Permit requests for moduli and signatures */ 301 /* Permit requests for moduli and signatures */
293 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 302 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
294 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 303 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
304#ifdef GSSAPI
305 /* and for the GSSAPI key exchange */
306 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
307#endif
295 308
296 /* The first few requests do not require asynchronous access */ 309 /* The first few requests do not require asynchronous access */
297 while (!authenticated) { 310 while (!authenticated) {
@@ -405,6 +418,10 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor)
405 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 418 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
406 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 419 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
407 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); 420 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
421#ifdef GSSAPI
422 /* and for the GSSAPI key exchange */
423 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
424#endif
408 425
409 if (auth_opts->permit_pty_flag) { 426 if (auth_opts->permit_pty_flag) {
410 monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); 427 monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1);
@@ -1687,6 +1704,17 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor)
1687# ifdef OPENSSL_HAS_ECC 1704# ifdef OPENSSL_HAS_ECC
1688 kex->kex[KEX_ECDH_SHA2] = kex_gen_server; 1705 kex->kex[KEX_ECDH_SHA2] = kex_gen_server;
1689# endif 1706# endif
1707# ifdef GSSAPI
1708 if (options.gss_keyex) {
1709 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
1710 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
1711 kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server;
1712 kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server;
1713 kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server;
1714 kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server;
1715 kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server;
1716 }
1717# endif
1690#endif /* WITH_OPENSSL */ 1718#endif /* WITH_OPENSSL */
1691 kex->kex[KEX_C25519_SHA256] = kex_gen_server; 1719 kex->kex[KEX_C25519_SHA256] = kex_gen_server;
1692 kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_server; 1720 kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_server;
@@ -1780,8 +1808,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m)
1780 u_char *p; 1808 u_char *p;
1781 int r; 1809 int r;
1782 1810
1783 if (!options.gss_authentication) 1811 if (!options.gss_authentication && !options.gss_keyex)
1784 fatal("%s: GSSAPI authentication not enabled", __func__); 1812 fatal("%s: GSSAPI not enabled", __func__);
1785 1813
1786 if ((r = sshbuf_get_string(m, &p, &len)) != 0) 1814 if ((r = sshbuf_get_string(m, &p, &len)) != 0)
1787 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1815 fatal("%s: buffer error: %s", __func__, ssh_err(r));
@@ -1813,8 +1841,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m)
1813 OM_uint32 flags = 0; /* GSI needs this */ 1841 OM_uint32 flags = 0; /* GSI needs this */
1814 int r; 1842 int r;
1815 1843
1816 if (!options.gss_authentication) 1844 if (!options.gss_authentication && !options.gss_keyex)
1817 fatal("%s: GSSAPI authentication not enabled", __func__); 1845 fatal("%s: GSSAPI not enabled", __func__);
1818 1846
1819 if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0) 1847 if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0)
1820 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1848 fatal("%s: buffer error: %s", __func__, ssh_err(r));
@@ -1834,6 +1862,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m)
1834 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); 1862 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
1835 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); 1863 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
1836 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); 1864 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
1865 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
1837 } 1866 }
1838 return (0); 1867 return (0);
1839} 1868}
@@ -1845,8 +1874,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m)
1845 OM_uint32 ret; 1874 OM_uint32 ret;
1846 int r; 1875 int r;
1847 1876
1848 if (!options.gss_authentication) 1877 if (!options.gss_authentication && !options.gss_keyex)
1849 fatal("%s: GSSAPI authentication not enabled", __func__); 1878 fatal("%s: GSSAPI not enabled", __func__);
1850 1879
1851 if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 || 1880 if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 ||
1852 (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0) 1881 (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0)
@@ -1872,13 +1901,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m)
1872int 1901int
1873mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) 1902mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m)
1874{ 1903{
1875 int r, authenticated; 1904 int r, authenticated, kex;
1876 const char *displayname; 1905 const char *displayname;
1877 1906
1878 if (!options.gss_authentication) 1907 if (!options.gss_authentication && !options.gss_keyex)
1879 fatal("%s: GSSAPI authentication not enabled", __func__); 1908 fatal("%s: GSSAPI not enabled", __func__);
1880 1909
1881 authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); 1910 if ((r = sshbuf_get_u32(m, &kex)) != 0)
1911 fatal("%s: buffer error: %s", __func__, ssh_err(r));
1912
1913 authenticated = authctxt->valid &&
1914 ssh_gssapi_userok(authctxt->user, authctxt->pw, kex);
1882 1915
1883 sshbuf_reset(m); 1916 sshbuf_reset(m);
1884 if ((r = sshbuf_put_u32(m, authenticated)) != 0) 1917 if ((r = sshbuf_put_u32(m, authenticated)) != 0)
@@ -1887,7 +1920,11 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m)
1887 debug3("%s: sending result %d", __func__, authenticated); 1920 debug3("%s: sending result %d", __func__, authenticated);
1888 mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); 1921 mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m);
1889 1922
1890 auth_method = "gssapi-with-mic"; 1923 if (kex) {
1924 auth_method = "gssapi-keyex";
1925 } else {
1926 auth_method = "gssapi-with-mic";
1927 }
1891 1928
1892 if ((displayname = ssh_gssapi_displayname()) != NULL) 1929 if ((displayname = ssh_gssapi_displayname()) != NULL)
1893 auth2_record_info(authctxt, "%s", displayname); 1930 auth2_record_info(authctxt, "%s", displayname);
@@ -1895,5 +1932,85 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m)
1895 /* Monitor loop will terminate if authenticated */ 1932 /* Monitor loop will terminate if authenticated */
1896 return (authenticated); 1933 return (authenticated);
1897} 1934}
1935
1936int
1937mm_answer_gss_sign(struct ssh *ssh, int socket, struct sshbuf *m)
1938{
1939 gss_buffer_desc data;
1940 gss_buffer_desc hash = GSS_C_EMPTY_BUFFER;
1941 OM_uint32 major, minor;
1942 size_t len;
1943 u_char *p = NULL;
1944 int r;
1945
1946 if (!options.gss_authentication && !options.gss_keyex)
1947 fatal("%s: GSSAPI not enabled", __func__);
1948
1949 if ((r = sshbuf_get_string(m, &p, &len)) != 0)
1950 fatal("%s: buffer error: %s", __func__, ssh_err(r));
1951 data.value = p;
1952 data.length = len;
1953 /* Lengths of SHA-1, SHA-256 and SHA-512 hashes that are used */
1954 if (data.length != 20 && data.length != 32 && data.length != 64)
1955 fatal("%s: data length incorrect: %d", __func__,
1956 (int) data.length);
1957
1958 /* Save the session ID on the first time around */
1959 if (session_id2_len == 0) {
1960 session_id2_len = data.length;
1961 session_id2 = xmalloc(session_id2_len);
1962 memcpy(session_id2, data.value, session_id2_len);
1963 }
1964 major = ssh_gssapi_sign(gsscontext, &data, &hash);
1965
1966 free(data.value);
1967
1968 sshbuf_reset(m);
1969
1970 if ((r = sshbuf_put_u32(m, major)) != 0 ||
1971 (r = sshbuf_put_string(m, hash.value, hash.length)) != 0)
1972 fatal("%s: buffer error: %s", __func__, ssh_err(r));
1973
1974 mm_request_send(socket, MONITOR_ANS_GSSSIGN, m);
1975
1976 gss_release_buffer(&minor, &hash);
1977
1978 /* Turn on getpwnam permissions */
1979 monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
1980
1981 /* And credential updating, for when rekeying */
1982 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1);
1983
1984 return (0);
1985}
1986
1987int
1988mm_answer_gss_updatecreds(struct ssh *ssh, int socket, struct sshbuf *m) {
1989 ssh_gssapi_ccache store;
1990 int r, ok;
1991
1992 if (!options.gss_authentication && !options.gss_keyex)
1993 fatal("%s: GSSAPI not enabled", __func__);
1994
1995 if ((r = sshbuf_get_string(m, (u_char **)&store.filename, NULL)) != 0 ||
1996 (r = sshbuf_get_string(m, (u_char **)&store.envvar, NULL)) != 0 ||
1997 (r = sshbuf_get_string(m, (u_char **)&store.envval, NULL)) != 0)
1998 fatal("%s: buffer error: %s", __func__, ssh_err(r));
1999
2000 ok = ssh_gssapi_update_creds(&store);
2001
2002 free(store.filename);
2003 free(store.envvar);
2004 free(store.envval);
2005
2006 sshbuf_reset(m);
2007 if ((r = sshbuf_put_u32(m, ok)) != 0)
2008 fatal("%s: buffer error: %s", __func__, ssh_err(r));
2009
2010 mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m);
2011
2012 return(0);
2013}
2014
1898#endif /* GSSAPI */ 2015#endif /* GSSAPI */
1899 2016