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>2015-11-29 17:36:18 +0000
commit09c4d9b7d41ab3c9973f07e0109e931f57c59c43 (patch)
tree238d7d86bfd8c0080d01fb55cef2ad37df46bd2e /monitor.c
parent651211fd4a199b299540c00c54a46e27fadb04be (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: 2015-11-29 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 a91420983..2658aaa53 100644
--- a/monitor.c
+++ b/monitor.c
@@ -157,6 +157,8 @@ int mm_answer_gss_setup_ctx(int, Buffer *);
157int mm_answer_gss_accept_ctx(int, Buffer *); 157int mm_answer_gss_accept_ctx(int, Buffer *);
158int mm_answer_gss_userok(int, Buffer *); 158int mm_answer_gss_userok(int, Buffer *);
159int mm_answer_gss_checkmic(int, Buffer *); 159int mm_answer_gss_checkmic(int, Buffer *);
160int mm_answer_gss_sign(int, Buffer *);
161int mm_answer_gss_updatecreds(int, Buffer *);
160#endif 162#endif
161 163
162#ifdef SSH_AUDIT_EVENTS 164#ifdef SSH_AUDIT_EVENTS
@@ -234,11 +236,18 @@ struct mon_table mon_dispatch_proto20[] = {
234 {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, 236 {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
235 {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, 237 {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
236 {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, 238 {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
239 {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
237#endif 240#endif
238 {0, 0, NULL} 241 {0, 0, NULL}
239}; 242};
240 243
241struct mon_table mon_dispatch_postauth20[] = { 244struct mon_table mon_dispatch_postauth20[] = {
245#ifdef GSSAPI
246 {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx},
247 {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx},
248 {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign},
249 {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds},
250#endif
242#ifdef WITH_OPENSSL 251#ifdef WITH_OPENSSL
243 {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, 252 {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
244#endif 253#endif
@@ -353,6 +362,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
353 /* Permit requests for moduli and signatures */ 362 /* Permit requests for moduli and signatures */
354 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 363 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
355 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 364 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
365#ifdef GSSAPI
366 /* and for the GSSAPI key exchange */
367 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
368#endif
356 } else { 369 } else {
357 mon_dispatch = mon_dispatch_proto15; 370 mon_dispatch = mon_dispatch_proto15;
358 371
@@ -461,6 +474,10 @@ monitor_child_postauth(struct monitor *pmonitor)
461 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 474 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
462 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 475 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
463 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); 476 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
477#ifdef GSSAPI
478 /* and for the GSSAPI key exchange */
479 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
480#endif
464 } else { 481 } else {
465 mon_dispatch = mon_dispatch_postauth15; 482 mon_dispatch = mon_dispatch_postauth15;
466 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); 483 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
@@ -1864,6 +1881,13 @@ monitor_apply_keystate(struct monitor *pmonitor)
1864# endif 1881# endif
1865#endif /* WITH_OPENSSL */ 1882#endif /* WITH_OPENSSL */
1866 kex->kex[KEX_C25519_SHA256] = kexc25519_server; 1883 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
1884#ifdef GSSAPI
1885 if (options.gss_keyex) {
1886 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
1887 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
1888 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
1889 }
1890#endif
1867 kex->load_host_public_key=&get_hostkey_public_by_type; 1891 kex->load_host_public_key=&get_hostkey_public_by_type;
1868 kex->load_host_private_key=&get_hostkey_private_by_type; 1892 kex->load_host_private_key=&get_hostkey_private_by_type;
1869 kex->host_key_index=&get_hostkey_index; 1893 kex->host_key_index=&get_hostkey_index;
@@ -1963,6 +1987,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m)
1963 OM_uint32 major; 1987 OM_uint32 major;
1964 u_int len; 1988 u_int len;
1965 1989
1990 if (!options.gss_authentication && !options.gss_keyex)
1991 fatal("In GSSAPI monitor when GSSAPI is disabled");
1992
1966 goid.elements = buffer_get_string(m, &len); 1993 goid.elements = buffer_get_string(m, &len);
1967 goid.length = len; 1994 goid.length = len;
1968 1995
@@ -1990,6 +2017,9 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
1990 OM_uint32 flags = 0; /* GSI needs this */ 2017 OM_uint32 flags = 0; /* GSI needs this */
1991 u_int len; 2018 u_int len;
1992 2019
2020 if (!options.gss_authentication && !options.gss_keyex)
2021 fatal("In GSSAPI monitor when GSSAPI is disabled");
2022
1993 in.value = buffer_get_string(m, &len); 2023 in.value = buffer_get_string(m, &len);
1994 in.length = len; 2024 in.length = len;
1995 major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); 2025 major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags);
@@ -2007,6 +2037,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
2007 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); 2037 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
2008 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); 2038 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
2009 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); 2039 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
2040 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
2010 } 2041 }
2011 return (0); 2042 return (0);
2012} 2043}
@@ -2018,6 +2049,9 @@ mm_answer_gss_checkmic(int sock, Buffer *m)
2018 OM_uint32 ret; 2049 OM_uint32 ret;
2019 u_int len; 2050 u_int len;
2020 2051
2052 if (!options.gss_authentication && !options.gss_keyex)
2053 fatal("In GSSAPI monitor when GSSAPI is disabled");
2054
2021 gssbuf.value = buffer_get_string(m, &len); 2055 gssbuf.value = buffer_get_string(m, &len);
2022 gssbuf.length = len; 2056 gssbuf.length = len;
2023 mic.value = buffer_get_string(m, &len); 2057 mic.value = buffer_get_string(m, &len);
@@ -2044,7 +2078,11 @@ mm_answer_gss_userok(int sock, Buffer *m)
2044{ 2078{
2045 int authenticated; 2079 int authenticated;
2046 2080
2047 authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); 2081 if (!options.gss_authentication && !options.gss_keyex)
2082 fatal("In GSSAPI monitor when GSSAPI is disabled");
2083
2084 authenticated = authctxt->valid &&
2085 ssh_gssapi_userok(authctxt->user, authctxt->pw);
2048 2086
2049 buffer_clear(m); 2087 buffer_clear(m);
2050 buffer_put_int(m, authenticated); 2088 buffer_put_int(m, authenticated);
@@ -2057,5 +2095,73 @@ mm_answer_gss_userok(int sock, Buffer *m)
2057 /* Monitor loop will terminate if authenticated */ 2095 /* Monitor loop will terminate if authenticated */
2058 return (authenticated); 2096 return (authenticated);
2059} 2097}
2098
2099int
2100mm_answer_gss_sign(int socket, Buffer *m)
2101{
2102 gss_buffer_desc data;
2103 gss_buffer_desc hash = GSS_C_EMPTY_BUFFER;
2104 OM_uint32 major, minor;
2105 u_int len;
2106
2107 if (!options.gss_authentication && !options.gss_keyex)
2108 fatal("In GSSAPI monitor when GSSAPI is disabled");
2109
2110 data.value = buffer_get_string(m, &len);
2111 data.length = len;
2112 if (data.length != 20)
2113 fatal("%s: data length incorrect: %d", __func__,
2114 (int) data.length);
2115
2116 /* Save the session ID on the first time around */
2117 if (session_id2_len == 0) {
2118 session_id2_len = data.length;
2119 session_id2 = xmalloc(session_id2_len);
2120 memcpy(session_id2, data.value, session_id2_len);
2121 }
2122 major = ssh_gssapi_sign(gsscontext, &data, &hash);
2123
2124 free(data.value);
2125
2126 buffer_clear(m);
2127 buffer_put_int(m, major);
2128 buffer_put_string(m, hash.value, hash.length);
2129
2130 mm_request_send(socket, MONITOR_ANS_GSSSIGN, m);
2131
2132 gss_release_buffer(&minor, &hash);
2133
2134 /* Turn on getpwnam permissions */
2135 monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
2136
2137 /* And credential updating, for when rekeying */
2138 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1);
2139
2140 return (0);
2141}
2142
2143int
2144mm_answer_gss_updatecreds(int socket, Buffer *m) {
2145 ssh_gssapi_ccache store;
2146 int ok;
2147
2148 store.filename = buffer_get_string(m, NULL);
2149 store.envvar = buffer_get_string(m, NULL);
2150 store.envval = buffer_get_string(m, NULL);
2151
2152 ok = ssh_gssapi_update_creds(&store);
2153
2154 free(store.filename);
2155 free(store.envvar);
2156 free(store.envval);
2157
2158 buffer_clear(m);
2159 buffer_put_int(m, ok);
2160
2161 mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m);
2162
2163 return(0);
2164}
2165
2060#endif /* GSSAPI */ 2166#endif /* GSSAPI */
2061 2167