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-19 16:39:52 +0000
commit429c595dbaff7f7c2b3a53fe4235211f6d788025 (patch)
tree085cf7273c133b74238c968c9c9f591f8fb0308e /monitor.c
parent9a975a9faed7c4f334e8c8490db3e77e102f2b21 (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 03baf1ea9..a777c4c03 100644
--- a/monitor.c
+++ b/monitor.c
@@ -181,6 +181,8 @@ int mm_answer_gss_setup_ctx(int, Buffer *);
181int mm_answer_gss_accept_ctx(int, Buffer *); 181int mm_answer_gss_accept_ctx(int, Buffer *);
182int mm_answer_gss_userok(int, Buffer *); 182int mm_answer_gss_userok(int, Buffer *);
183int mm_answer_gss_checkmic(int, Buffer *); 183int mm_answer_gss_checkmic(int, Buffer *);
184int mm_answer_gss_sign(int, Buffer *);
185int mm_answer_gss_updatecreds(int, Buffer *);
184#endif 186#endif
185 187
186#ifdef SSH_AUDIT_EVENTS 188#ifdef SSH_AUDIT_EVENTS
@@ -253,6 +255,7 @@ struct mon_table mon_dispatch_proto20[] = {
253 {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, 255 {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
254 {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, 256 {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
255 {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, 257 {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
258 {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
256#endif 259#endif
257#ifdef JPAKE 260#ifdef JPAKE
258 {MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata}, 261 {MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata},
@@ -265,6 +268,12 @@ struct mon_table mon_dispatch_proto20[] = {
265}; 268};
266 269
267struct mon_table mon_dispatch_postauth20[] = { 270struct mon_table mon_dispatch_postauth20[] = {
271#ifdef GSSAPI
272 {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx},
273 {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx},
274 {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign},
275 {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds},
276#endif
268 {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, 277 {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
269 {MONITOR_REQ_SIGN, 0, mm_answer_sign}, 278 {MONITOR_REQ_SIGN, 0, mm_answer_sign},
270 {MONITOR_REQ_PTY, 0, mm_answer_pty}, 279 {MONITOR_REQ_PTY, 0, mm_answer_pty},
@@ -373,6 +382,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
373 /* Permit requests for moduli and signatures */ 382 /* Permit requests for moduli and signatures */
374 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 383 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
375 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 384 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
385#ifdef GSSAPI
386 /* and for the GSSAPI key exchange */
387 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
388#endif
376 } else { 389 } else {
377 mon_dispatch = mon_dispatch_proto15; 390 mon_dispatch = mon_dispatch_proto15;
378 391
@@ -487,6 +500,10 @@ monitor_child_postauth(struct monitor *pmonitor)
487 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 500 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
488 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 501 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
489 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); 502 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
503#ifdef GSSAPI
504 /* and for the GSSAPI key exchange */
505 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
506#endif
490 } else { 507 } else {
491 mon_dispatch = mon_dispatch_postauth15; 508 mon_dispatch = mon_dispatch_postauth15;
492 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); 509 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
@@ -1856,6 +1873,13 @@ mm_get_kex(Buffer *m)
1856 kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; 1873 kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
1857 kex->kex[KEX_ECDH_SHA2] = kexecdh_server; 1874 kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
1858 kex->kex[KEX_C25519_SHA256] = kexc25519_server; 1875 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
1876#ifdef GSSAPI
1877 if (options.gss_keyex) {
1878 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
1879 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
1880 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
1881 }
1882#endif
1859 kex->server = 1; 1883 kex->server = 1;
1860 kex->hostkey_type = buffer_get_int(m); 1884 kex->hostkey_type = buffer_get_int(m);
1861 kex->kex_type = buffer_get_int(m); 1885 kex->kex_type = buffer_get_int(m);
@@ -2063,6 +2087,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m)
2063 OM_uint32 major; 2087 OM_uint32 major;
2064 u_int len; 2088 u_int len;
2065 2089
2090 if (!options.gss_authentication && !options.gss_keyex)
2091 fatal("In GSSAPI monitor when GSSAPI is disabled");
2092
2066 goid.elements = buffer_get_string(m, &len); 2093 goid.elements = buffer_get_string(m, &len);
2067 goid.length = len; 2094 goid.length = len;
2068 2095
@@ -2090,6 +2117,9 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
2090 OM_uint32 flags = 0; /* GSI needs this */ 2117 OM_uint32 flags = 0; /* GSI needs this */
2091 u_int len; 2118 u_int len;
2092 2119
2120 if (!options.gss_authentication && !options.gss_keyex)
2121 fatal("In GSSAPI monitor when GSSAPI is disabled");
2122
2093 in.value = buffer_get_string(m, &len); 2123 in.value = buffer_get_string(m, &len);
2094 in.length = len; 2124 in.length = len;
2095 major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); 2125 major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags);
@@ -2107,6 +2137,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
2107 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); 2137 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
2108 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); 2138 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
2109 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); 2139 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
2140 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
2110 } 2141 }
2111 return (0); 2142 return (0);
2112} 2143}
@@ -2118,6 +2149,9 @@ mm_answer_gss_checkmic(int sock, Buffer *m)
2118 OM_uint32 ret; 2149 OM_uint32 ret;
2119 u_int len; 2150 u_int len;
2120 2151
2152 if (!options.gss_authentication && !options.gss_keyex)
2153 fatal("In GSSAPI monitor when GSSAPI is disabled");
2154
2121 gssbuf.value = buffer_get_string(m, &len); 2155 gssbuf.value = buffer_get_string(m, &len);
2122 gssbuf.length = len; 2156 gssbuf.length = len;
2123 mic.value = buffer_get_string(m, &len); 2157 mic.value = buffer_get_string(m, &len);
@@ -2144,7 +2178,11 @@ mm_answer_gss_userok(int sock, Buffer *m)
2144{ 2178{
2145 int authenticated; 2179 int authenticated;
2146 2180
2147 authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); 2181 if (!options.gss_authentication && !options.gss_keyex)
2182 fatal("In GSSAPI monitor when GSSAPI is disabled");
2183
2184 authenticated = authctxt->valid &&
2185 ssh_gssapi_userok(authctxt->user, authctxt->pw);
2148 2186
2149 buffer_clear(m); 2187 buffer_clear(m);
2150 buffer_put_int(m, authenticated); 2188 buffer_put_int(m, authenticated);
@@ -2157,6 +2195,74 @@ mm_answer_gss_userok(int sock, Buffer *m)
2157 /* Monitor loop will terminate if authenticated */ 2195 /* Monitor loop will terminate if authenticated */
2158 return (authenticated); 2196 return (authenticated);
2159} 2197}
2198
2199int
2200mm_answer_gss_sign(int socket, Buffer *m)
2201{
2202 gss_buffer_desc data;
2203 gss_buffer_desc hash = GSS_C_EMPTY_BUFFER;
2204 OM_uint32 major, minor;
2205 u_int len;
2206
2207 if (!options.gss_authentication && !options.gss_keyex)
2208 fatal("In GSSAPI monitor when GSSAPI is disabled");
2209
2210 data.value = buffer_get_string(m, &len);
2211 data.length = len;
2212 if (data.length != 20)
2213 fatal("%s: data length incorrect: %d", __func__,
2214 (int) data.length);
2215
2216 /* Save the session ID on the first time around */
2217 if (session_id2_len == 0) {
2218 session_id2_len = data.length;
2219 session_id2 = xmalloc(session_id2_len);
2220 memcpy(session_id2, data.value, session_id2_len);
2221 }
2222 major = ssh_gssapi_sign(gsscontext, &data, &hash);
2223
2224 free(data.value);
2225
2226 buffer_clear(m);
2227 buffer_put_int(m, major);
2228 buffer_put_string(m, hash.value, hash.length);
2229
2230 mm_request_send(socket, MONITOR_ANS_GSSSIGN, m);
2231
2232 gss_release_buffer(&minor, &hash);
2233
2234 /* Turn on getpwnam permissions */
2235 monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
2236
2237 /* And credential updating, for when rekeying */
2238 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1);
2239
2240 return (0);
2241}
2242
2243int
2244mm_answer_gss_updatecreds(int socket, Buffer *m) {
2245 ssh_gssapi_ccache store;
2246 int ok;
2247
2248 store.filename = buffer_get_string(m, NULL);
2249 store.envvar = buffer_get_string(m, NULL);
2250 store.envval = buffer_get_string(m, NULL);
2251
2252 ok = ssh_gssapi_update_creds(&store);
2253
2254 free(store.filename);
2255 free(store.envvar);
2256 free(store.envval);
2257
2258 buffer_clear(m);
2259 buffer_put_int(m, ok);
2260
2261 mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m);
2262
2263 return(0);
2264}
2265
2160#endif /* GSSAPI */ 2266#endif /* GSSAPI */
2161 2267
2162#ifdef JPAKE 2268#ifdef JPAKE