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>2014-03-20 00:24:48 +0000
commit9dfcd1a0e691c1cad34b168e27b3ed31ab6986cd (patch)
tree3a19744ef1cf261141a522e13f75abbb3b7dba4b /monitor.c
parent796ba4fd011b5d0d9d78d592ba2f30fc9d5ed2e7 (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: 2014-03-19 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 531c4f9a8..291881493 100644
--- a/monitor.c
+++ b/monitor.c
@@ -175,6 +175,8 @@ int mm_answer_gss_setup_ctx(int, Buffer *);
175int mm_answer_gss_accept_ctx(int, Buffer *); 175int mm_answer_gss_accept_ctx(int, Buffer *);
176int mm_answer_gss_userok(int, Buffer *); 176int mm_answer_gss_userok(int, Buffer *);
177int mm_answer_gss_checkmic(int, Buffer *); 177int mm_answer_gss_checkmic(int, Buffer *);
178int mm_answer_gss_sign(int, Buffer *);
179int mm_answer_gss_updatecreds(int, Buffer *);
178#endif 180#endif
179 181
180#ifdef SSH_AUDIT_EVENTS 182#ifdef SSH_AUDIT_EVENTS
@@ -247,11 +249,18 @@ struct mon_table mon_dispatch_proto20[] = {
247 {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, 249 {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
248 {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, 250 {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
249 {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, 251 {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
252 {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
250#endif 253#endif
251 {0, 0, NULL} 254 {0, 0, NULL}
252}; 255};
253 256
254struct mon_table mon_dispatch_postauth20[] = { 257struct mon_table mon_dispatch_postauth20[] = {
258#ifdef GSSAPI
259 {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx},
260 {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx},
261 {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign},
262 {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds},
263#endif
255 {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, 264 {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
256 {MONITOR_REQ_SIGN, 0, mm_answer_sign}, 265 {MONITOR_REQ_SIGN, 0, mm_answer_sign},
257 {MONITOR_REQ_PTY, 0, mm_answer_pty}, 266 {MONITOR_REQ_PTY, 0, mm_answer_pty},
@@ -360,6 +369,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
360 /* Permit requests for moduli and signatures */ 369 /* Permit requests for moduli and signatures */
361 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 370 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
362 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 371 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
372#ifdef GSSAPI
373 /* and for the GSSAPI key exchange */
374 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
375#endif
363 } else { 376 } else {
364 mon_dispatch = mon_dispatch_proto15; 377 mon_dispatch = mon_dispatch_proto15;
365 378
@@ -465,6 +478,10 @@ monitor_child_postauth(struct monitor *pmonitor)
465 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 478 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
466 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 479 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
467 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); 480 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
481#ifdef GSSAPI
482 /* and for the GSSAPI key exchange */
483 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
484#endif
468 } else { 485 } else {
469 mon_dispatch = mon_dispatch_postauth15; 486 mon_dispatch = mon_dispatch_postauth15;
470 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); 487 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
@@ -1834,6 +1851,13 @@ mm_get_kex(Buffer *m)
1834 kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; 1851 kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
1835 kex->kex[KEX_ECDH_SHA2] = kexecdh_server; 1852 kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
1836 kex->kex[KEX_C25519_SHA256] = kexc25519_server; 1853 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
1854#ifdef GSSAPI
1855 if (options.gss_keyex) {
1856 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
1857 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
1858 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
1859 }
1860#endif
1837 kex->server = 1; 1861 kex->server = 1;
1838 kex->hostkey_type = buffer_get_int(m); 1862 kex->hostkey_type = buffer_get_int(m);
1839 kex->kex_type = buffer_get_int(m); 1863 kex->kex_type = buffer_get_int(m);
@@ -2041,6 +2065,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m)
2041 OM_uint32 major; 2065 OM_uint32 major;
2042 u_int len; 2066 u_int len;
2043 2067
2068 if (!options.gss_authentication && !options.gss_keyex)
2069 fatal("In GSSAPI monitor when GSSAPI is disabled");
2070
2044 goid.elements = buffer_get_string(m, &len); 2071 goid.elements = buffer_get_string(m, &len);
2045 goid.length = len; 2072 goid.length = len;
2046 2073
@@ -2068,6 +2095,9 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
2068 OM_uint32 flags = 0; /* GSI needs this */ 2095 OM_uint32 flags = 0; /* GSI needs this */
2069 u_int len; 2096 u_int len;
2070 2097
2098 if (!options.gss_authentication && !options.gss_keyex)
2099 fatal("In GSSAPI monitor when GSSAPI is disabled");
2100
2071 in.value = buffer_get_string(m, &len); 2101 in.value = buffer_get_string(m, &len);
2072 in.length = len; 2102 in.length = len;
2073 major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); 2103 major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags);
@@ -2085,6 +2115,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
2085 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); 2115 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
2086 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); 2116 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
2087 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); 2117 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
2118 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
2088 } 2119 }
2089 return (0); 2120 return (0);
2090} 2121}
@@ -2096,6 +2127,9 @@ mm_answer_gss_checkmic(int sock, Buffer *m)
2096 OM_uint32 ret; 2127 OM_uint32 ret;
2097 u_int len; 2128 u_int len;
2098 2129
2130 if (!options.gss_authentication && !options.gss_keyex)
2131 fatal("In GSSAPI monitor when GSSAPI is disabled");
2132
2099 gssbuf.value = buffer_get_string(m, &len); 2133 gssbuf.value = buffer_get_string(m, &len);
2100 gssbuf.length = len; 2134 gssbuf.length = len;
2101 mic.value = buffer_get_string(m, &len); 2135 mic.value = buffer_get_string(m, &len);
@@ -2122,7 +2156,11 @@ mm_answer_gss_userok(int sock, Buffer *m)
2122{ 2156{
2123 int authenticated; 2157 int authenticated;
2124 2158
2125 authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); 2159 if (!options.gss_authentication && !options.gss_keyex)
2160 fatal("In GSSAPI monitor when GSSAPI is disabled");
2161
2162 authenticated = authctxt->valid &&
2163 ssh_gssapi_userok(authctxt->user, authctxt->pw);
2126 2164
2127 buffer_clear(m); 2165 buffer_clear(m);
2128 buffer_put_int(m, authenticated); 2166 buffer_put_int(m, authenticated);
@@ -2135,5 +2173,73 @@ mm_answer_gss_userok(int sock, Buffer *m)
2135 /* Monitor loop will terminate if authenticated */ 2173 /* Monitor loop will terminate if authenticated */
2136 return (authenticated); 2174 return (authenticated);
2137} 2175}
2176
2177int
2178mm_answer_gss_sign(int socket, Buffer *m)
2179{
2180 gss_buffer_desc data;
2181 gss_buffer_desc hash = GSS_C_EMPTY_BUFFER;
2182 OM_uint32 major, minor;
2183 u_int len;
2184
2185 if (!options.gss_authentication && !options.gss_keyex)
2186 fatal("In GSSAPI monitor when GSSAPI is disabled");
2187
2188 data.value = buffer_get_string(m, &len);
2189 data.length = len;
2190 if (data.length != 20)
2191 fatal("%s: data length incorrect: %d", __func__,
2192 (int) data.length);
2193
2194 /* Save the session ID on the first time around */
2195 if (session_id2_len == 0) {
2196 session_id2_len = data.length;
2197 session_id2 = xmalloc(session_id2_len);
2198 memcpy(session_id2, data.value, session_id2_len);
2199 }
2200 major = ssh_gssapi_sign(gsscontext, &data, &hash);
2201
2202 free(data.value);
2203
2204 buffer_clear(m);
2205 buffer_put_int(m, major);
2206 buffer_put_string(m, hash.value, hash.length);
2207
2208 mm_request_send(socket, MONITOR_ANS_GSSSIGN, m);
2209
2210 gss_release_buffer(&minor, &hash);
2211
2212 /* Turn on getpwnam permissions */
2213 monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
2214
2215 /* And credential updating, for when rekeying */
2216 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1);
2217
2218 return (0);
2219}
2220
2221int
2222mm_answer_gss_updatecreds(int socket, Buffer *m) {
2223 ssh_gssapi_ccache store;
2224 int ok;
2225
2226 store.filename = buffer_get_string(m, NULL);
2227 store.envvar = buffer_get_string(m, NULL);
2228 store.envval = buffer_get_string(m, NULL);
2229
2230 ok = ssh_gssapi_update_creds(&store);
2231
2232 free(store.filename);
2233 free(store.envvar);
2234 free(store.envval);
2235
2236 buffer_clear(m);
2237 buffer_put_int(m, ok);
2238
2239 mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m);
2240
2241 return(0);
2242}
2243
2138#endif /* GSSAPI */ 2244#endif /* GSSAPI */
2139 2245