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>2020-06-07 10:24:45 +0100
commit79f9d21b406c172878896ef41cdc2502fc2f84a7 (patch)
tree71507aaefd925223b1543b10f4342f2df9ea0ee3 /monitor.c
parent202f5a676221c244cd450086c334c2b59f339e86 (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. Author: Simon Wilkinson <simon@sxw.org.uk> Author: Colin Watson <cjwatson@debian.org> Author: Jakub Jelen <jjelen@redhat.com> Origin: other, https://github.com/openssh-gsskex/openssh-gsskex/commits/debian/master Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1242 Last-Updated: 2020-06-07 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 b6e855d5d..5347e900d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -148,6 +148,8 @@ int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *);
148int mm_answer_gss_accept_ctx(struct ssh *, int, struct sshbuf *); 148int mm_answer_gss_accept_ctx(struct ssh *, int, struct sshbuf *);
149int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); 149int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *);
150int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); 150int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *);
151int mm_answer_gss_sign(struct ssh *, int, struct sshbuf *);
152int 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
227struct mon_table mon_dispatch_postauth20[] = { 230struct 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)
1897int 1926int
1898mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) 1927mm_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
1961int
1962mm_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
2012int
2013mm_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