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>2016-03-10 13:00:39 +0000
commit6dfd41bb6858c6446c1da47449e2108fbabf220e (patch)
treeff5693073f78b4cc1ba6c92c8280f4ec80ced188 /monitor.c
parentf0329aac23c61e1a5197d6d57349a63f459bccb0 (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: 2016-01-04 Patch-Name: gssapi.patch
Diffstat (limited to 'monitor.c')
-rw-r--r--monitor.c108
1 files changed, 107 insertions, 1 deletions
diff --git a/monitor.c b/monitor.c
index ac7dd3099..6c8202325 100644
--- a/monitor.c
+++ b/monitor.c
@@ -156,6 +156,8 @@ int mm_answer_gss_setup_ctx(int, Buffer *);
156int mm_answer_gss_accept_ctx(int, Buffer *); 156int mm_answer_gss_accept_ctx(int, Buffer *);
157int mm_answer_gss_userok(int, Buffer *); 157int mm_answer_gss_userok(int, Buffer *);
158int mm_answer_gss_checkmic(int, Buffer *); 158int mm_answer_gss_checkmic(int, Buffer *);
159int mm_answer_gss_sign(int, Buffer *);
160int mm_answer_gss_updatecreds(int, Buffer *);
159#endif 161#endif
160 162
161#ifdef SSH_AUDIT_EVENTS 163#ifdef SSH_AUDIT_EVENTS
@@ -233,11 +235,18 @@ struct mon_table mon_dispatch_proto20[] = {
233 {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, 235 {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
234 {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, 236 {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
235 {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, 237 {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
238 {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
236#endif 239#endif
237 {0, 0, NULL} 240 {0, 0, NULL}
238}; 241};
239 242
240struct mon_table mon_dispatch_postauth20[] = { 243struct mon_table mon_dispatch_postauth20[] = {
244#ifdef GSSAPI
245 {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx},
246 {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx},
247 {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign},
248 {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds},
249#endif
241#ifdef WITH_OPENSSL 250#ifdef WITH_OPENSSL
242 {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, 251 {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
243#endif 252#endif
@@ -352,6 +361,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
352 /* Permit requests for moduli and signatures */ 361 /* Permit requests for moduli and signatures */
353 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 362 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
354 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 363 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
364#ifdef GSSAPI
365 /* and for the GSSAPI key exchange */
366 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
367#endif
355 } else { 368 } else {
356 mon_dispatch = mon_dispatch_proto15; 369 mon_dispatch = mon_dispatch_proto15;
357 370
@@ -460,6 +473,10 @@ monitor_child_postauth(struct monitor *pmonitor)
460 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 473 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
461 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 474 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
462 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); 475 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
476#ifdef GSSAPI
477 /* and for the GSSAPI key exchange */
478 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
479#endif
463 } else { 480 } else {
464 mon_dispatch = mon_dispatch_postauth15; 481 mon_dispatch = mon_dispatch_postauth15;
465 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); 482 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
@@ -1861,6 +1878,13 @@ monitor_apply_keystate(struct monitor *pmonitor)
1861# endif 1878# endif
1862#endif /* WITH_OPENSSL */ 1879#endif /* WITH_OPENSSL */
1863 kex->kex[KEX_C25519_SHA256] = kexc25519_server; 1880 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
1881#ifdef GSSAPI
1882 if (options.gss_keyex) {
1883 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
1884 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
1885 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
1886 }
1887#endif
1864 kex->load_host_public_key=&get_hostkey_public_by_type; 1888 kex->load_host_public_key=&get_hostkey_public_by_type;
1865 kex->load_host_private_key=&get_hostkey_private_by_type; 1889 kex->load_host_private_key=&get_hostkey_private_by_type;
1866 kex->host_key_index=&get_hostkey_index; 1890 kex->host_key_index=&get_hostkey_index;
@@ -1960,6 +1984,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m)
1960 OM_uint32 major; 1984 OM_uint32 major;
1961 u_int len; 1985 u_int len;
1962 1986
1987 if (!options.gss_authentication && !options.gss_keyex)
1988 fatal("In GSSAPI monitor when GSSAPI is disabled");
1989
1963 goid.elements = buffer_get_string(m, &len); 1990 goid.elements = buffer_get_string(m, &len);
1964 goid.length = len; 1991 goid.length = len;
1965 1992
@@ -1987,6 +2014,9 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
1987 OM_uint32 flags = 0; /* GSI needs this */ 2014 OM_uint32 flags = 0; /* GSI needs this */
1988 u_int len; 2015 u_int len;
1989 2016
2017 if (!options.gss_authentication && !options.gss_keyex)
2018 fatal("In GSSAPI monitor when GSSAPI is disabled");
2019
1990 in.value = buffer_get_string(m, &len); 2020 in.value = buffer_get_string(m, &len);
1991 in.length = len; 2021 in.length = len;
1992 major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); 2022 major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags);
@@ -2004,6 +2034,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
2004 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); 2034 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
2005 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); 2035 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
2006 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); 2036 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
2037 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
2007 } 2038 }
2008 return (0); 2039 return (0);
2009} 2040}
@@ -2015,6 +2046,9 @@ mm_answer_gss_checkmic(int sock, Buffer *m)
2015 OM_uint32 ret; 2046 OM_uint32 ret;
2016 u_int len; 2047 u_int len;
2017 2048
2049 if (!options.gss_authentication && !options.gss_keyex)
2050 fatal("In GSSAPI monitor when GSSAPI is disabled");
2051
2018 gssbuf.value = buffer_get_string(m, &len); 2052 gssbuf.value = buffer_get_string(m, &len);
2019 gssbuf.length = len; 2053 gssbuf.length = len;
2020 mic.value = buffer_get_string(m, &len); 2054 mic.value = buffer_get_string(m, &len);
@@ -2041,7 +2075,11 @@ mm_answer_gss_userok(int sock, Buffer *m)
2041{ 2075{
2042 int authenticated; 2076 int authenticated;
2043 2077
2044 authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); 2078 if (!options.gss_authentication && !options.gss_keyex)
2079 fatal("In GSSAPI monitor when GSSAPI is disabled");
2080
2081 authenticated = authctxt->valid &&
2082 ssh_gssapi_userok(authctxt->user, authctxt->pw);
2045 2083
2046 buffer_clear(m); 2084 buffer_clear(m);
2047 buffer_put_int(m, authenticated); 2085 buffer_put_int(m, authenticated);
@@ -2054,5 +2092,73 @@ mm_answer_gss_userok(int sock, Buffer *m)
2054 /* Monitor loop will terminate if authenticated */ 2092 /* Monitor loop will terminate if authenticated */
2055 return (authenticated); 2093 return (authenticated);
2056} 2094}
2095
2096int
2097mm_answer_gss_sign(int socket, Buffer *m)
2098{
2099 gss_buffer_desc data;
2100 gss_buffer_desc hash = GSS_C_EMPTY_BUFFER;
2101 OM_uint32 major, minor;
2102 u_int len;
2103
2104 if (!options.gss_authentication && !options.gss_keyex)
2105 fatal("In GSSAPI monitor when GSSAPI is disabled");
2106
2107 data.value = buffer_get_string(m, &len);
2108 data.length = len;
2109 if (data.length != 20)
2110 fatal("%s: data length incorrect: %d", __func__,
2111 (int) data.length);
2112
2113 /* Save the session ID on the first time around */
2114 if (session_id2_len == 0) {
2115 session_id2_len = data.length;
2116 session_id2 = xmalloc(session_id2_len);
2117 memcpy(session_id2, data.value, session_id2_len);
2118 }
2119 major = ssh_gssapi_sign(gsscontext, &data, &hash);
2120
2121 free(data.value);
2122
2123 buffer_clear(m);
2124 buffer_put_int(m, major);
2125 buffer_put_string(m, hash.value, hash.length);
2126
2127 mm_request_send(socket, MONITOR_ANS_GSSSIGN, m);
2128
2129 gss_release_buffer(&minor, &hash);
2130
2131 /* Turn on getpwnam permissions */
2132 monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
2133
2134 /* And credential updating, for when rekeying */
2135 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1);
2136
2137 return (0);
2138}
2139
2140int
2141mm_answer_gss_updatecreds(int socket, Buffer *m) {
2142 ssh_gssapi_ccache store;
2143 int ok;
2144
2145 store.filename = buffer_get_string(m, NULL);
2146 store.envvar = buffer_get_string(m, NULL);
2147 store.envval = buffer_get_string(m, NULL);
2148
2149 ok = ssh_gssapi_update_creds(&store);
2150
2151 free(store.filename);
2152 free(store.envvar);
2153 free(store.envval);
2154
2155 buffer_clear(m);
2156 buffer_put_int(m, ok);
2157
2158 mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m);
2159
2160 return(0);
2161}
2162
2057#endif /* GSSAPI */ 2163#endif /* GSSAPI */
2058 2164