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-08-19 16:33:29 +0100
commit06879e71614170580ffa7568ec5c009f60a9d084 (patch)
tree2264e498417b1968891c6f8a3c3b560b2b3a4761 /monitor.c
parentbaccdb349b31c47cd76fb63211f754ed33a9707e (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-08-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 bab6ce87e..a2027e580 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);
@@ -1860,6 +1877,13 @@ monitor_apply_keystate(struct monitor *pmonitor)
1860# endif 1877# endif
1861#endif /* WITH_OPENSSL */ 1878#endif /* WITH_OPENSSL */
1862 kex->kex[KEX_C25519_SHA256] = kexc25519_server; 1879 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
1880#ifdef GSSAPI
1881 if (options.gss_keyex) {
1882 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
1883 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
1884 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
1885 }
1886#endif
1863 kex->load_host_public_key=&get_hostkey_public_by_type; 1887 kex->load_host_public_key=&get_hostkey_public_by_type;
1864 kex->load_host_private_key=&get_hostkey_private_by_type; 1888 kex->load_host_private_key=&get_hostkey_private_by_type;
1865 kex->host_key_index=&get_hostkey_index; 1889 kex->host_key_index=&get_hostkey_index;
@@ -1959,6 +1983,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m)
1959 OM_uint32 major; 1983 OM_uint32 major;
1960 u_int len; 1984 u_int len;
1961 1985
1986 if (!options.gss_authentication && !options.gss_keyex)
1987 fatal("In GSSAPI monitor when GSSAPI is disabled");
1988
1962 goid.elements = buffer_get_string(m, &len); 1989 goid.elements = buffer_get_string(m, &len);
1963 goid.length = len; 1990 goid.length = len;
1964 1991
@@ -1986,6 +2013,9 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
1986 OM_uint32 flags = 0; /* GSI needs this */ 2013 OM_uint32 flags = 0; /* GSI needs this */
1987 u_int len; 2014 u_int len;
1988 2015
2016 if (!options.gss_authentication && !options.gss_keyex)
2017 fatal("In GSSAPI monitor when GSSAPI is disabled");
2018
1989 in.value = buffer_get_string(m, &len); 2019 in.value = buffer_get_string(m, &len);
1990 in.length = len; 2020 in.length = len;
1991 major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); 2021 major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags);
@@ -2003,6 +2033,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m)
2003 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); 2033 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
2004 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); 2034 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
2005 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); 2035 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
2036 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
2006 } 2037 }
2007 return (0); 2038 return (0);
2008} 2039}
@@ -2014,6 +2045,9 @@ mm_answer_gss_checkmic(int sock, Buffer *m)
2014 OM_uint32 ret; 2045 OM_uint32 ret;
2015 u_int len; 2046 u_int len;
2016 2047
2048 if (!options.gss_authentication && !options.gss_keyex)
2049 fatal("In GSSAPI monitor when GSSAPI is disabled");
2050
2017 gssbuf.value = buffer_get_string(m, &len); 2051 gssbuf.value = buffer_get_string(m, &len);
2018 gssbuf.length = len; 2052 gssbuf.length = len;
2019 mic.value = buffer_get_string(m, &len); 2053 mic.value = buffer_get_string(m, &len);
@@ -2040,7 +2074,11 @@ mm_answer_gss_userok(int sock, Buffer *m)
2040{ 2074{
2041 int authenticated; 2075 int authenticated;
2042 2076
2043 authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); 2077 if (!options.gss_authentication && !options.gss_keyex)
2078 fatal("In GSSAPI monitor when GSSAPI is disabled");
2079
2080 authenticated = authctxt->valid &&
2081 ssh_gssapi_userok(authctxt->user, authctxt->pw);
2044 2082
2045 buffer_clear(m); 2083 buffer_clear(m);
2046 buffer_put_int(m, authenticated); 2084 buffer_put_int(m, authenticated);
@@ -2053,5 +2091,73 @@ mm_answer_gss_userok(int sock, Buffer *m)
2053 /* Monitor loop will terminate if authenticated */ 2091 /* Monitor loop will terminate if authenticated */
2054 return (authenticated); 2092 return (authenticated);
2055} 2093}
2094
2095int
2096mm_answer_gss_sign(int socket, Buffer *m)
2097{
2098 gss_buffer_desc data;
2099 gss_buffer_desc hash = GSS_C_EMPTY_BUFFER;
2100 OM_uint32 major, minor;
2101 u_int len;
2102
2103 if (!options.gss_authentication && !options.gss_keyex)
2104 fatal("In GSSAPI monitor when GSSAPI is disabled");
2105
2106 data.value = buffer_get_string(m, &len);
2107 data.length = len;
2108 if (data.length != 20)
2109 fatal("%s: data length incorrect: %d", __func__,
2110 (int) data.length);
2111
2112 /* Save the session ID on the first time around */
2113 if (session_id2_len == 0) {
2114 session_id2_len = data.length;
2115 session_id2 = xmalloc(session_id2_len);
2116 memcpy(session_id2, data.value, session_id2_len);
2117 }
2118 major = ssh_gssapi_sign(gsscontext, &data, &hash);
2119
2120 free(data.value);
2121
2122 buffer_clear(m);
2123 buffer_put_int(m, major);
2124 buffer_put_string(m, hash.value, hash.length);
2125
2126 mm_request_send(socket, MONITOR_ANS_GSSSIGN, m);
2127
2128 gss_release_buffer(&minor, &hash);
2129
2130 /* Turn on getpwnam permissions */
2131 monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
2132
2133 /* And credential updating, for when rekeying */
2134 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1);
2135
2136 return (0);
2137}
2138
2139int
2140mm_answer_gss_updatecreds(int socket, Buffer *m) {
2141 ssh_gssapi_ccache store;
2142 int ok;
2143
2144 store.filename = buffer_get_string(m, NULL);
2145 store.envvar = buffer_get_string(m, NULL);
2146 store.envval = buffer_get_string(m, NULL);
2147
2148 ok = ssh_gssapi_update_creds(&store);
2149
2150 free(store.filename);
2151 free(store.envvar);
2152 free(store.envval);
2153
2154 buffer_clear(m);
2155 buffer_put_int(m, ok);
2156
2157 mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m);
2158
2159 return(0);
2160}
2161
2056#endif /* GSSAPI */ 2162#endif /* GSSAPI */
2057 2163