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-08-07 12:18:35 +0100
commiteecddf8b72fcad83ccca43b1badb03782704f6b7 (patch)
treefd0046825c8d42bd267afa7839d5603b130cf847 /monitor.c
parenta8ed8d256b2e2c05b0c15565a7938028c5192277 (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-08-07 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 cb57bd066..05bb48a8e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -158,6 +158,8 @@ int mm_answer_gss_setup_ctx(int, Buffer *);
158int mm_answer_gss_accept_ctx(int, Buffer *); 158int mm_answer_gss_accept_ctx(int, Buffer *);
159int mm_answer_gss_userok(int, Buffer *); 159int mm_answer_gss_userok(int, Buffer *);
160int mm_answer_gss_checkmic(int, Buffer *); 160int mm_answer_gss_checkmic(int, Buffer *);
161int mm_answer_gss_sign(int, Buffer *);
162int mm_answer_gss_updatecreds(int, Buffer *);
161#endif 163#endif
162 164
163#ifdef SSH_AUDIT_EVENTS 165#ifdef SSH_AUDIT_EVENTS
@@ -235,11 +237,18 @@ struct mon_table mon_dispatch_proto20[] = {
235 {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, 237 {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
236 {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, 238 {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
237 {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, 239 {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
240 {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
238#endif 241#endif
239 {0, 0, NULL} 242 {0, 0, NULL}
240}; 243};
241 244
242struct mon_table mon_dispatch_postauth20[] = { 245struct mon_table mon_dispatch_postauth20[] = {
246#ifdef GSSAPI
247 {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx},
248 {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx},
249 {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign},
250 {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds},
251#endif
243#ifdef WITH_OPENSSL 252#ifdef WITH_OPENSSL
244 {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, 253 {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
245#endif 254#endif
@@ -354,6 +363,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
354 /* Permit requests for moduli and signatures */ 363 /* Permit requests for moduli and signatures */
355 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 364 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
356 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 365 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
366#ifdef GSSAPI
367 /* and for the GSSAPI key exchange */
368 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
369#endif
357 } else { 370 } else {
358 mon_dispatch = mon_dispatch_proto15; 371 mon_dispatch = mon_dispatch_proto15;
359 372
@@ -462,6 +475,10 @@ monitor_child_postauth(struct monitor *pmonitor)
462 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 475 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
463 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 476 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
464 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); 477 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
478#ifdef GSSAPI
479 /* and for the GSSAPI key exchange */
480 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
481#endif
465 } else { 482 } else {
466 mon_dispatch = mon_dispatch_postauth15; 483 mon_dispatch = mon_dispatch_postauth15;
467 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); 484 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
@@ -1876,6 +1893,13 @@ monitor_apply_keystate(struct monitor *pmonitor)
1876# endif 1893# endif
1877#endif /* WITH_OPENSSL */ 1894#endif /* WITH_OPENSSL */
1878 kex->kex[KEX_C25519_SHA256] = kexc25519_server; 1895 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
1896#ifdef GSSAPI
1897 if (options.gss_keyex) {
1898 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
1899 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
1900 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
1901 }
1902#endif
1879 kex->load_host_public_key=&get_hostkey_public_by_type; 1903 kex->load_host_public_key=&get_hostkey_public_by_type;
1880 kex->load_host_private_key=&get_hostkey_private_by_type; 1904 kex->load_host_private_key=&get_hostkey_private_by_type;
1881 kex->host_key_index=&get_hostkey_index; 1905 kex->host_key_index=&get_hostkey_index;
@@ -1975,6 +1999,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m)
1975 OM_uint32 major; 1999 OM_uint32 major;
1976 u_int len; 2000 u_int len;
1977 2001
2002 if (!options.gss_authentication && !options.gss_keyex)
2003 fatal("In GSSAPI monitor when GSSAPI is disabled");
2004
1978 goid.elements = buffer_get_string(m, &len); 2005 goid.elements = buffer_get_string(m, &len);
1979 goid.length = len; 2006 goid.length = len;
1980 2007
@@ -2002,6 +2029,9 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
2002 OM_uint32 flags = 0; /* GSI needs this */ 2029 OM_uint32 flags = 0; /* GSI needs this */
2003 u_int len; 2030 u_int len;
2004 2031
2032 if (!options.gss_authentication && !options.gss_keyex)
2033 fatal("In GSSAPI monitor when GSSAPI is disabled");
2034
2005 in.value = buffer_get_string(m, &len); 2035 in.value = buffer_get_string(m, &len);
2006 in.length = len; 2036 in.length = len;
2007 major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); 2037 major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags);
@@ -2019,6 +2049,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
2019 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); 2049 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
2020 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); 2050 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
2021 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); 2051 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
2052 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
2022 } 2053 }
2023 return (0); 2054 return (0);
2024} 2055}
@@ -2030,6 +2061,9 @@ mm_answer_gss_checkmic(int sock, Buffer *m)
2030 OM_uint32 ret; 2061 OM_uint32 ret;
2031 u_int len; 2062 u_int len;
2032 2063
2064 if (!options.gss_authentication && !options.gss_keyex)
2065 fatal("In GSSAPI monitor when GSSAPI is disabled");
2066
2033 gssbuf.value = buffer_get_string(m, &len); 2067 gssbuf.value = buffer_get_string(m, &len);
2034 gssbuf.length = len; 2068 gssbuf.length = len;
2035 mic.value = buffer_get_string(m, &len); 2069 mic.value = buffer_get_string(m, &len);
@@ -2056,7 +2090,11 @@ mm_answer_gss_userok(int sock, Buffer *m)
2056{ 2090{
2057 int authenticated; 2091 int authenticated;
2058 2092
2059 authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); 2093 if (!options.gss_authentication && !options.gss_keyex)
2094 fatal("In GSSAPI monitor when GSSAPI is disabled");
2095
2096 authenticated = authctxt->valid &&
2097 ssh_gssapi_userok(authctxt->user, authctxt->pw);
2060 2098
2061 buffer_clear(m); 2099 buffer_clear(m);
2062 buffer_put_int(m, authenticated); 2100 buffer_put_int(m, authenticated);
@@ -2069,5 +2107,73 @@ mm_answer_gss_userok(int sock, Buffer *m)
2069 /* Monitor loop will terminate if authenticated */ 2107 /* Monitor loop will terminate if authenticated */
2070 return (authenticated); 2108 return (authenticated);
2071} 2109}
2110
2111int
2112mm_answer_gss_sign(int socket, Buffer *m)
2113{
2114 gss_buffer_desc data;
2115 gss_buffer_desc hash = GSS_C_EMPTY_BUFFER;
2116 OM_uint32 major, minor;
2117 u_int len;
2118
2119 if (!options.gss_authentication && !options.gss_keyex)
2120 fatal("In GSSAPI monitor when GSSAPI is disabled");
2121
2122 data.value = buffer_get_string(m, &len);
2123 data.length = len;
2124 if (data.length != 20)
2125 fatal("%s: data length incorrect: %d", __func__,
2126 (int) data.length);
2127
2128 /* Save the session ID on the first time around */
2129 if (session_id2_len == 0) {
2130 session_id2_len = data.length;
2131 session_id2 = xmalloc(session_id2_len);
2132 memcpy(session_id2, data.value, session_id2_len);
2133 }
2134 major = ssh_gssapi_sign(gsscontext, &data, &hash);
2135
2136 free(data.value);
2137
2138 buffer_clear(m);
2139 buffer_put_int(m, major);
2140 buffer_put_string(m, hash.value, hash.length);
2141
2142 mm_request_send(socket, MONITOR_ANS_GSSSIGN, m);
2143
2144 gss_release_buffer(&minor, &hash);
2145
2146 /* Turn on getpwnam permissions */
2147 monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
2148
2149 /* And credential updating, for when rekeying */
2150 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1);
2151
2152 return (0);
2153}
2154
2155int
2156mm_answer_gss_updatecreds(int socket, Buffer *m) {
2157 ssh_gssapi_ccache store;
2158 int ok;
2159
2160 store.filename = buffer_get_string(m, NULL);
2161 store.envvar = buffer_get_string(m, NULL);
2162 store.envval = buffer_get_string(m, NULL);
2163
2164 ok = ssh_gssapi_update_creds(&store);
2165
2166 free(store.filename);
2167 free(store.envvar);
2168 free(store.envval);
2169
2170 buffer_clear(m);
2171 buffer_put_int(m, ok);
2172
2173 mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m);
2174
2175 return(0);
2176}
2177
2072#endif /* GSSAPI */ 2178#endif /* GSSAPI */
2073 2179