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-10-07 14:26:43 +0100
commit1c1b6fa17982eb622e2c4e8f4a279f2113f57413 (patch)
treea67e7472f48242904e6a45732508822af63fd331 /monitor.c
parent487bdb3a5ef6075887b830ccb8a0b14f6da78e93 (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-10-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 dbe29f128..b0896ef7f 100644
--- a/monitor.c
+++ b/monitor.c
@@ -178,6 +178,8 @@ int mm_answer_gss_setup_ctx(int, Buffer *);
178int mm_answer_gss_accept_ctx(int, Buffer *); 178int mm_answer_gss_accept_ctx(int, Buffer *);
179int mm_answer_gss_userok(int, Buffer *); 179int mm_answer_gss_userok(int, Buffer *);
180int mm_answer_gss_checkmic(int, Buffer *); 180int mm_answer_gss_checkmic(int, Buffer *);
181int mm_answer_gss_sign(int, Buffer *);
182int mm_answer_gss_updatecreds(int, Buffer *);
181#endif 183#endif
182 184
183#ifdef SSH_AUDIT_EVENTS 185#ifdef SSH_AUDIT_EVENTS
@@ -255,11 +257,18 @@ struct mon_table mon_dispatch_proto20[] = {
255 {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, 257 {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
256 {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, 258 {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
257 {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, 259 {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
260 {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
258#endif 261#endif
259 {0, 0, NULL} 262 {0, 0, NULL}
260}; 263};
261 264
262struct mon_table mon_dispatch_postauth20[] = { 265struct mon_table mon_dispatch_postauth20[] = {
266#ifdef GSSAPI
267 {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx},
268 {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx},
269 {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign},
270 {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds},
271#endif
263#ifdef WITH_OPENSSL 272#ifdef WITH_OPENSSL
264 {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, 273 {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
265#endif 274#endif
@@ -374,6 +383,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
374 /* Permit requests for moduli and signatures */ 383 /* Permit requests for moduli and signatures */
375 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 384 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
376 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 385 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
386#ifdef GSSAPI
387 /* and for the GSSAPI key exchange */
388 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
389#endif
377 } else { 390 } else {
378 mon_dispatch = mon_dispatch_proto15; 391 mon_dispatch = mon_dispatch_proto15;
379 392
@@ -482,6 +495,10 @@ monitor_child_postauth(struct monitor *pmonitor)
482 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 495 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
483 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 496 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
484 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); 497 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
498#ifdef GSSAPI
499 /* and for the GSSAPI key exchange */
500 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
501#endif
485 } else { 502 } else {
486 mon_dispatch = mon_dispatch_postauth15; 503 mon_dispatch = mon_dispatch_postauth15;
487 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); 504 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
@@ -1861,6 +1878,13 @@ mm_get_kex(Buffer *m)
1861 kex->kex[KEX_ECDH_SHA2] = kexecdh_server; 1878 kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
1862#endif 1879#endif
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->server = 1; 1888 kex->server = 1;
1865 kex->hostkey_type = buffer_get_int(m); 1889 kex->hostkey_type = buffer_get_int(m);
1866 kex->kex_type = buffer_get_int(m); 1890 kex->kex_type = buffer_get_int(m);
@@ -2068,6 +2092,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m)
2068 OM_uint32 major; 2092 OM_uint32 major;
2069 u_int len; 2093 u_int len;
2070 2094
2095 if (!options.gss_authentication && !options.gss_keyex)
2096 fatal("In GSSAPI monitor when GSSAPI is disabled");
2097
2071 goid.elements = buffer_get_string(m, &len); 2098 goid.elements = buffer_get_string(m, &len);
2072 goid.length = len; 2099 goid.length = len;
2073 2100
@@ -2095,6 +2122,9 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
2095 OM_uint32 flags = 0; /* GSI needs this */ 2122 OM_uint32 flags = 0; /* GSI needs this */
2096 u_int len; 2123 u_int len;
2097 2124
2125 if (!options.gss_authentication && !options.gss_keyex)
2126 fatal("In GSSAPI monitor when GSSAPI is disabled");
2127
2098 in.value = buffer_get_string(m, &len); 2128 in.value = buffer_get_string(m, &len);
2099 in.length = len; 2129 in.length = len;
2100 major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); 2130 major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags);
@@ -2112,6 +2142,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
2112 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); 2142 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
2113 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); 2143 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
2114 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); 2144 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
2145 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
2115 } 2146 }
2116 return (0); 2147 return (0);
2117} 2148}
@@ -2123,6 +2154,9 @@ mm_answer_gss_checkmic(int sock, Buffer *m)
2123 OM_uint32 ret; 2154 OM_uint32 ret;
2124 u_int len; 2155 u_int len;
2125 2156
2157 if (!options.gss_authentication && !options.gss_keyex)
2158 fatal("In GSSAPI monitor when GSSAPI is disabled");
2159
2126 gssbuf.value = buffer_get_string(m, &len); 2160 gssbuf.value = buffer_get_string(m, &len);
2127 gssbuf.length = len; 2161 gssbuf.length = len;
2128 mic.value = buffer_get_string(m, &len); 2162 mic.value = buffer_get_string(m, &len);
@@ -2149,7 +2183,11 @@ mm_answer_gss_userok(int sock, Buffer *m)
2149{ 2183{
2150 int authenticated; 2184 int authenticated;
2151 2185
2152 authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); 2186 if (!options.gss_authentication && !options.gss_keyex)
2187 fatal("In GSSAPI monitor when GSSAPI is disabled");
2188
2189 authenticated = authctxt->valid &&
2190 ssh_gssapi_userok(authctxt->user, authctxt->pw);
2153 2191
2154 buffer_clear(m); 2192 buffer_clear(m);
2155 buffer_put_int(m, authenticated); 2193 buffer_put_int(m, authenticated);
@@ -2162,5 +2200,73 @@ mm_answer_gss_userok(int sock, Buffer *m)
2162 /* Monitor loop will terminate if authenticated */ 2200 /* Monitor loop will terminate if authenticated */
2163 return (authenticated); 2201 return (authenticated);
2164} 2202}
2203
2204int
2205mm_answer_gss_sign(int socket, Buffer *m)
2206{
2207 gss_buffer_desc data;
2208 gss_buffer_desc hash = GSS_C_EMPTY_BUFFER;
2209 OM_uint32 major, minor;
2210 u_int len;
2211
2212 if (!options.gss_authentication && !options.gss_keyex)
2213 fatal("In GSSAPI monitor when GSSAPI is disabled");
2214
2215 data.value = buffer_get_string(m, &len);
2216 data.length = len;
2217 if (data.length != 20)
2218 fatal("%s: data length incorrect: %d", __func__,
2219 (int) data.length);
2220
2221 /* Save the session ID on the first time around */
2222 if (session_id2_len == 0) {
2223 session_id2_len = data.length;
2224 session_id2 = xmalloc(session_id2_len);
2225 memcpy(session_id2, data.value, session_id2_len);
2226 }
2227 major = ssh_gssapi_sign(gsscontext, &data, &hash);
2228
2229 free(data.value);
2230
2231 buffer_clear(m);
2232 buffer_put_int(m, major);
2233 buffer_put_string(m, hash.value, hash.length);
2234
2235 mm_request_send(socket, MONITOR_ANS_GSSSIGN, m);
2236
2237 gss_release_buffer(&minor, &hash);
2238
2239 /* Turn on getpwnam permissions */
2240 monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
2241
2242 /* And credential updating, for when rekeying */
2243 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1);
2244
2245 return (0);
2246}
2247
2248int
2249mm_answer_gss_updatecreds(int socket, Buffer *m) {
2250 ssh_gssapi_ccache store;
2251 int ok;
2252
2253 store.filename = buffer_get_string(m, NULL);
2254 store.envvar = buffer_get_string(m, NULL);
2255 store.envval = buffer_get_string(m, NULL);
2256
2257 ok = ssh_gssapi_update_creds(&store);
2258
2259 free(store.filename);
2260 free(store.envvar);
2261 free(store.envval);
2262
2263 buffer_clear(m);
2264 buffer_put_int(m, ok);
2265
2266 mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m);
2267
2268 return(0);
2269}
2270
2165#endif /* GSSAPI */ 2271#endif /* GSSAPI */
2166 2272