diff options
Diffstat (limited to 'monitor.c')
-rw-r--r-- | monitor.c | 108 |
1 files changed, 107 insertions, 1 deletions
@@ -175,6 +175,8 @@ int mm_answer_gss_setup_ctx(int, Buffer *); | |||
175 | int mm_answer_gss_accept_ctx(int, Buffer *); | 175 | int mm_answer_gss_accept_ctx(int, Buffer *); |
176 | int mm_answer_gss_userok(int, Buffer *); | 176 | int mm_answer_gss_userok(int, Buffer *); |
177 | int mm_answer_gss_checkmic(int, Buffer *); | 177 | int mm_answer_gss_checkmic(int, Buffer *); |
178 | int mm_answer_gss_sign(int, Buffer *); | ||
179 | int 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 | ||
254 | struct mon_table mon_dispatch_postauth20[] = { | 257 | struct 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 | |||
2177 | int | ||
2178 | mm_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 | |||
2221 | int | ||
2222 | mm_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 | ||