diff options
author | Colin Watson <cjwatson@debian.org> | 2010-01-01 23:53:30 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2010-01-01 23:53:30 +0000 |
commit | df03186a4f9e0c2ece398b5c0571cb6263d7a752 (patch) | |
tree | 1aab079441dff9615274769b19f2d734ddf508dd /monitor.c | |
parent | 6ad6994c288662fca6949f42bf91fec2aff00bca (diff) | |
parent | 99b402ea4c8457b0a3cafff37f5b3410a8dc6476 (diff) |
* New upstream release (closes: #536182). Yes, I know 5.3p1 has been out
for a while, but there's no GSSAPI patch available for it yet.
- Change the default cipher order to prefer the AES CTR modes and the
revised "arcfour256" mode to CBC mode ciphers that are susceptible to
CPNI-957037 "Plaintext Recovery Attack Against SSH".
- Add countermeasures to mitigate CPNI-957037-style attacks against the
SSH protocol's use of CBC-mode ciphers. Upon detection of an invalid
packet length or Message Authentication Code, ssh/sshd will continue
reading up to the maximum supported packet length rather than
immediately terminating the connection. This eliminates most of the
known differences in behaviour that leaked information about the
plaintext of injected data which formed the basis of this attack
(closes: #506115, LP: #379329).
- ForceCommand directive now accepts commandline arguments for the
internal-sftp server (closes: #524423, LP: #362511).
- Add AllowAgentForwarding to available Match keywords list (closes:
#540623).
- Make ssh(1) send the correct channel number for
SSH2_MSG_CHANNEL_SUCCESS and SSH2_MSG_CHANNEL_FAILURE messages to
avoid triggering 'Non-public channel' error messages on sshd(8) in
openssh-5.1.
- Avoid printing 'Non-public channel' warnings in sshd(8), since the
ssh(1) has sent incorrect channel numbers since ~2004 (this reverts a
behaviour introduced in openssh-5.1; closes: #496017).
* Update to GSSAPI patch from
http://www.sxw.org.uk/computing/patches/openssh-5.2p1-gsskex-all-20090726.patch,
including cascading credentials support (LP: #416958).
Diffstat (limited to 'monitor.c')
-rw-r--r-- | monitor.c | 288 |
1 files changed, 281 insertions, 7 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor.c,v 1.99 2008/07/10 18:08:11 markus Exp $ */ | 1 | /* $OpenBSD: monitor.c,v 1.101 2009/02/12 03:26:22 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | 3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> |
4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> | 4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> |
@@ -87,6 +87,7 @@ | |||
87 | #include "misc.h" | 87 | #include "misc.h" |
88 | #include "compat.h" | 88 | #include "compat.h" |
89 | #include "ssh2.h" | 89 | #include "ssh2.h" |
90 | #include "jpake.h" | ||
90 | 91 | ||
91 | #ifdef GSSAPI | 92 | #ifdef GSSAPI |
92 | static Gssctxt *gsscontext = NULL; | 93 | static Gssctxt *gsscontext = NULL; |
@@ -150,6 +151,11 @@ int mm_answer_rsa_challenge(int, Buffer *); | |||
150 | int mm_answer_rsa_response(int, Buffer *); | 151 | int mm_answer_rsa_response(int, Buffer *); |
151 | int mm_answer_sesskey(int, Buffer *); | 152 | int mm_answer_sesskey(int, Buffer *); |
152 | int mm_answer_sessid(int, Buffer *); | 153 | int mm_answer_sessid(int, Buffer *); |
154 | int mm_answer_jpake_get_pwdata(int, Buffer *); | ||
155 | int mm_answer_jpake_step1(int, Buffer *); | ||
156 | int mm_answer_jpake_step2(int, Buffer *); | ||
157 | int mm_answer_jpake_key_confirm(int, Buffer *); | ||
158 | int mm_answer_jpake_check_confirm(int, Buffer *); | ||
153 | 159 | ||
154 | #ifdef USE_PAM | 160 | #ifdef USE_PAM |
155 | int mm_answer_pam_start(int, Buffer *); | 161 | int mm_answer_pam_start(int, Buffer *); |
@@ -166,6 +172,7 @@ int mm_answer_gss_accept_ctx(int, Buffer *); | |||
166 | int mm_answer_gss_userok(int, Buffer *); | 172 | int mm_answer_gss_userok(int, Buffer *); |
167 | int mm_answer_gss_checkmic(int, Buffer *); | 173 | int mm_answer_gss_checkmic(int, Buffer *); |
168 | int mm_answer_gss_sign(int, Buffer *); | 174 | int mm_answer_gss_sign(int, Buffer *); |
175 | int mm_answer_gss_updatecreds(int, Buffer *); | ||
169 | #endif | 176 | #endif |
170 | 177 | ||
171 | #ifdef SSH_AUDIT_EVENTS | 178 | #ifdef SSH_AUDIT_EVENTS |
@@ -238,6 +245,13 @@ struct mon_table mon_dispatch_proto20[] = { | |||
238 | {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, | 245 | {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, |
239 | {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, | 246 | {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign}, |
240 | #endif | 247 | #endif |
248 | #ifdef JPAKE | ||
249 | {MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata}, | ||
250 | {MONITOR_REQ_JPAKE_STEP1, MON_ISAUTH, mm_answer_jpake_step1}, | ||
251 | {MONITOR_REQ_JPAKE_STEP2, MON_ONCE, mm_answer_jpake_step2}, | ||
252 | {MONITOR_REQ_JPAKE_KEY_CONFIRM, MON_ONCE, mm_answer_jpake_key_confirm}, | ||
253 | {MONITOR_REQ_JPAKE_CHECK_CONFIRM, MON_AUTH, mm_answer_jpake_check_confirm}, | ||
254 | #endif | ||
241 | {0, 0, NULL} | 255 | {0, 0, NULL} |
242 | }; | 256 | }; |
243 | 257 | ||
@@ -246,6 +260,7 @@ struct mon_table mon_dispatch_postauth20[] = { | |||
246 | {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, | 260 | {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx}, |
247 | {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, | 261 | {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, |
248 | {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, | 262 | {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign}, |
263 | {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds}, | ||
249 | #endif | 264 | #endif |
250 | {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, | 265 | {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, |
251 | {MONITOR_REQ_SIGN, 0, mm_answer_sign}, | 266 | {MONITOR_REQ_SIGN, 0, mm_answer_sign}, |
@@ -392,6 +407,15 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) | |||
392 | if (!authenticated) | 407 | if (!authenticated) |
393 | authctxt->failures++; | 408 | authctxt->failures++; |
394 | } | 409 | } |
410 | #ifdef JPAKE | ||
411 | /* Cleanup JPAKE context after authentication */ | ||
412 | if (ent->flags & MON_AUTHDECIDE) { | ||
413 | if (authctxt->jpake_ctx != NULL) { | ||
414 | jpake_free(authctxt->jpake_ctx); | ||
415 | authctxt->jpake_ctx = NULL; | ||
416 | } | ||
417 | } | ||
418 | #endif | ||
395 | } | 419 | } |
396 | 420 | ||
397 | if (!authctxt->valid) | 421 | if (!authctxt->valid) |
@@ -1519,7 +1543,9 @@ mm_answer_rsa_challenge(int sock, Buffer *m) | |||
1519 | fatal("%s: key type mismatch", __func__); | 1543 | fatal("%s: key type mismatch", __func__); |
1520 | if ((key = key_from_blob(blob, blen)) == NULL) | 1544 | if ((key = key_from_blob(blob, blen)) == NULL) |
1521 | fatal("%s: received bad key", __func__); | 1545 | fatal("%s: received bad key", __func__); |
1522 | 1546 | if (key->type != KEY_RSA) | |
1547 | fatal("%s: received bad key type %d", __func__, key->type); | ||
1548 | key->type = KEY_RSA1; | ||
1523 | if (ssh1_challenge) | 1549 | if (ssh1_challenge) |
1524 | BN_clear_free(ssh1_challenge); | 1550 | BN_clear_free(ssh1_challenge); |
1525 | ssh1_challenge = auth_rsa_generate_challenge(key); | 1551 | ssh1_challenge = auth_rsa_generate_challenge(key); |
@@ -1717,9 +1743,11 @@ mm_get_kex(Buffer *m) | |||
1717 | kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; | 1743 | kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; |
1718 | kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; | 1744 | kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; |
1719 | #ifdef GSSAPI | 1745 | #ifdef GSSAPI |
1720 | kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; | 1746 | if (options.gss_keyex) { |
1721 | kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; | 1747 | kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; |
1722 | kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; | 1748 | kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; |
1749 | kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; | ||
1750 | } | ||
1723 | #endif | 1751 | #endif |
1724 | kex->server = 1; | 1752 | kex->server = 1; |
1725 | kex->hostkey_type = buffer_get_int(m); | 1753 | kex->hostkey_type = buffer_get_int(m); |
@@ -1920,6 +1948,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m) | |||
1920 | OM_uint32 major; | 1948 | OM_uint32 major; |
1921 | u_int len; | 1949 | u_int len; |
1922 | 1950 | ||
1951 | if (!options.gss_authentication && !options.gss_keyex) | ||
1952 | fatal("In GSSAPI monitor when GSSAPI is disabled"); | ||
1953 | |||
1923 | goid.elements = buffer_get_string(m, &len); | 1954 | goid.elements = buffer_get_string(m, &len); |
1924 | goid.length = len; | 1955 | goid.length = len; |
1925 | 1956 | ||
@@ -1947,6 +1978,9 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m) | |||
1947 | OM_uint32 flags = 0; /* GSI needs this */ | 1978 | OM_uint32 flags = 0; /* GSI needs this */ |
1948 | u_int len; | 1979 | u_int len; |
1949 | 1980 | ||
1981 | if (!options.gss_authentication && !options.gss_keyex) | ||
1982 | fatal("In GSSAPI monitor when GSSAPI is disabled"); | ||
1983 | |||
1950 | in.value = buffer_get_string(m, &len); | 1984 | in.value = buffer_get_string(m, &len); |
1951 | in.length = len; | 1985 | in.length = len; |
1952 | major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); | 1986 | major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); |
@@ -1976,6 +2010,9 @@ mm_answer_gss_checkmic(int sock, Buffer *m) | |||
1976 | OM_uint32 ret; | 2010 | OM_uint32 ret; |
1977 | u_int len; | 2011 | u_int len; |
1978 | 2012 | ||
2013 | if (!options.gss_authentication && !options.gss_keyex) | ||
2014 | fatal("In GSSAPI monitor when GSSAPI is disabled"); | ||
2015 | |||
1979 | gssbuf.value = buffer_get_string(m, &len); | 2016 | gssbuf.value = buffer_get_string(m, &len); |
1980 | gssbuf.length = len; | 2017 | gssbuf.length = len; |
1981 | mic.value = buffer_get_string(m, &len); | 2018 | mic.value = buffer_get_string(m, &len); |
@@ -2002,7 +2039,11 @@ mm_answer_gss_userok(int sock, Buffer *m) | |||
2002 | { | 2039 | { |
2003 | int authenticated; | 2040 | int authenticated; |
2004 | 2041 | ||
2005 | authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); | 2042 | if (!options.gss_authentication && !options.gss_keyex) |
2043 | fatal("In GSSAPI monitor when GSSAPI is disabled"); | ||
2044 | |||
2045 | authenticated = authctxt->valid && | ||
2046 | ssh_gssapi_userok(authctxt->user, authctxt->pw); | ||
2006 | 2047 | ||
2007 | buffer_clear(m); | 2048 | buffer_clear(m); |
2008 | buffer_put_int(m, authenticated); | 2049 | buffer_put_int(m, authenticated); |
@@ -2024,10 +2065,14 @@ mm_answer_gss_sign(int socket, Buffer *m) | |||
2024 | OM_uint32 major, minor; | 2065 | OM_uint32 major, minor; |
2025 | u_int len; | 2066 | u_int len; |
2026 | 2067 | ||
2068 | if (!options.gss_authentication && !options.gss_keyex) | ||
2069 | fatal("In GSSAPI monitor when GSSAPI is disabled"); | ||
2070 | |||
2027 | data.value = buffer_get_string(m, &len); | 2071 | data.value = buffer_get_string(m, &len); |
2028 | data.length = len; | 2072 | data.length = len; |
2029 | if (data.length != 20) | 2073 | if (data.length != 20) |
2030 | fatal("%s: data length incorrect: %d", __func__, data.length); | 2074 | fatal("%s: data length incorrect: %d", __func__, |
2075 | (int) data.length); | ||
2031 | 2076 | ||
2032 | /* Save the session ID on the first time around */ | 2077 | /* Save the session ID on the first time around */ |
2033 | if (session_id2_len == 0) { | 2078 | if (session_id2_len == 0) { |
@@ -2049,8 +2094,237 @@ mm_answer_gss_sign(int socket, Buffer *m) | |||
2049 | 2094 | ||
2050 | /* Turn on getpwnam permissions */ | 2095 | /* Turn on getpwnam permissions */ |
2051 | monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); | 2096 | monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); |
2097 | |||
2098 | /* And credential updating, for when rekeying */ | ||
2099 | monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1); | ||
2052 | 2100 | ||
2053 | return (0); | 2101 | return (0); |
2054 | } | 2102 | } |
2055 | 2103 | ||
2104 | int | ||
2105 | mm_answer_gss_updatecreds(int socket, Buffer *m) { | ||
2106 | ssh_gssapi_ccache store; | ||
2107 | int ok; | ||
2108 | |||
2109 | store.filename = buffer_get_string(m, NULL); | ||
2110 | store.envvar = buffer_get_string(m, NULL); | ||
2111 | store.envval = buffer_get_string(m, NULL); | ||
2112 | |||
2113 | ok = ssh_gssapi_update_creds(&store); | ||
2114 | |||
2115 | xfree(store.filename); | ||
2116 | xfree(store.envvar); | ||
2117 | xfree(store.envval); | ||
2118 | |||
2119 | buffer_clear(m); | ||
2120 | buffer_put_int(m, ok); | ||
2121 | |||
2122 | mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m); | ||
2123 | |||
2124 | return(0); | ||
2125 | } | ||
2126 | |||
2056 | #endif /* GSSAPI */ | 2127 | #endif /* GSSAPI */ |
2128 | |||
2129 | #ifdef JPAKE | ||
2130 | int | ||
2131 | mm_answer_jpake_step1(int sock, Buffer *m) | ||
2132 | { | ||
2133 | struct jpake_ctx *pctx; | ||
2134 | u_char *x3_proof, *x4_proof; | ||
2135 | u_int x3_proof_len, x4_proof_len; | ||
2136 | |||
2137 | if (!options.zero_knowledge_password_authentication) | ||
2138 | fatal("zero_knowledge_password_authentication disabled"); | ||
2139 | |||
2140 | if (authctxt->jpake_ctx != NULL) | ||
2141 | fatal("%s: authctxt->jpake_ctx already set (%p)", | ||
2142 | __func__, authctxt->jpake_ctx); | ||
2143 | authctxt->jpake_ctx = pctx = jpake_new(); | ||
2144 | |||
2145 | jpake_step1(pctx->grp, | ||
2146 | &pctx->server_id, &pctx->server_id_len, | ||
2147 | &pctx->x3, &pctx->x4, &pctx->g_x3, &pctx->g_x4, | ||
2148 | &x3_proof, &x3_proof_len, | ||
2149 | &x4_proof, &x4_proof_len); | ||
2150 | |||
2151 | JPAKE_DEBUG_CTX((pctx, "step1 done in %s", __func__)); | ||
2152 | |||
2153 | buffer_clear(m); | ||
2154 | |||
2155 | buffer_put_string(m, pctx->server_id, pctx->server_id_len); | ||
2156 | buffer_put_bignum2(m, pctx->g_x3); | ||
2157 | buffer_put_bignum2(m, pctx->g_x4); | ||
2158 | buffer_put_string(m, x3_proof, x3_proof_len); | ||
2159 | buffer_put_string(m, x4_proof, x4_proof_len); | ||
2160 | |||
2161 | debug3("%s: sending step1", __func__); | ||
2162 | mm_request_send(sock, MONITOR_ANS_JPAKE_STEP1, m); | ||
2163 | |||
2164 | bzero(x3_proof, x3_proof_len); | ||
2165 | bzero(x4_proof, x4_proof_len); | ||
2166 | xfree(x3_proof); | ||
2167 | xfree(x4_proof); | ||
2168 | |||
2169 | monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_GET_PWDATA, 1); | ||
2170 | monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 0); | ||
2171 | |||
2172 | return 0; | ||
2173 | } | ||
2174 | |||
2175 | int | ||
2176 | mm_answer_jpake_get_pwdata(int sock, Buffer *m) | ||
2177 | { | ||
2178 | struct jpake_ctx *pctx = authctxt->jpake_ctx; | ||
2179 | char *hash_scheme, *salt; | ||
2180 | |||
2181 | if (pctx == NULL) | ||
2182 | fatal("%s: pctx == NULL", __func__); | ||
2183 | |||
2184 | auth2_jpake_get_pwdata(authctxt, &pctx->s, &hash_scheme, &salt); | ||
2185 | |||
2186 | buffer_clear(m); | ||
2187 | /* pctx->s is sensitive, not returned to slave */ | ||
2188 | buffer_put_cstring(m, hash_scheme); | ||
2189 | buffer_put_cstring(m, salt); | ||
2190 | |||
2191 | debug3("%s: sending pwdata", __func__); | ||
2192 | mm_request_send(sock, MONITOR_ANS_JPAKE_GET_PWDATA, m); | ||
2193 | |||
2194 | bzero(hash_scheme, strlen(hash_scheme)); | ||
2195 | bzero(salt, strlen(salt)); | ||
2196 | xfree(hash_scheme); | ||
2197 | xfree(salt); | ||
2198 | |||
2199 | monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP2, 1); | ||
2200 | |||
2201 | return 0; | ||
2202 | } | ||
2203 | |||
2204 | int | ||
2205 | mm_answer_jpake_step2(int sock, Buffer *m) | ||
2206 | { | ||
2207 | struct jpake_ctx *pctx = authctxt->jpake_ctx; | ||
2208 | u_char *x1_proof, *x2_proof, *x4_s_proof; | ||
2209 | u_int x1_proof_len, x2_proof_len, x4_s_proof_len; | ||
2210 | |||
2211 | if (pctx == NULL) | ||
2212 | fatal("%s: pctx == NULL", __func__); | ||
2213 | |||
2214 | if ((pctx->g_x1 = BN_new()) == NULL || | ||
2215 | (pctx->g_x2 = BN_new()) == NULL) | ||
2216 | fatal("%s: BN_new", __func__); | ||
2217 | buffer_get_bignum2(m, pctx->g_x1); | ||
2218 | buffer_get_bignum2(m, pctx->g_x2); | ||
2219 | pctx->client_id = buffer_get_string(m, &pctx->client_id_len); | ||
2220 | x1_proof = buffer_get_string(m, &x1_proof_len); | ||
2221 | x2_proof = buffer_get_string(m, &x2_proof_len); | ||
2222 | |||
2223 | jpake_step2(pctx->grp, pctx->s, pctx->g_x3, | ||
2224 | pctx->g_x1, pctx->g_x2, pctx->x4, | ||
2225 | pctx->client_id, pctx->client_id_len, | ||
2226 | pctx->server_id, pctx->server_id_len, | ||
2227 | x1_proof, x1_proof_len, | ||
2228 | x2_proof, x2_proof_len, | ||
2229 | &pctx->b, | ||
2230 | &x4_s_proof, &x4_s_proof_len); | ||
2231 | |||
2232 | JPAKE_DEBUG_CTX((pctx, "step2 done in %s", __func__)); | ||
2233 | |||
2234 | bzero(x1_proof, x1_proof_len); | ||
2235 | bzero(x2_proof, x2_proof_len); | ||
2236 | xfree(x1_proof); | ||
2237 | xfree(x2_proof); | ||
2238 | |||
2239 | buffer_clear(m); | ||
2240 | |||
2241 | buffer_put_bignum2(m, pctx->b); | ||
2242 | buffer_put_string(m, x4_s_proof, x4_s_proof_len); | ||
2243 | |||
2244 | debug3("%s: sending step2", __func__); | ||
2245 | mm_request_send(sock, MONITOR_ANS_JPAKE_STEP2, m); | ||
2246 | |||
2247 | bzero(x4_s_proof, x4_s_proof_len); | ||
2248 | xfree(x4_s_proof); | ||
2249 | |||
2250 | monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_KEY_CONFIRM, 1); | ||
2251 | |||
2252 | return 0; | ||
2253 | } | ||
2254 | |||
2255 | int | ||
2256 | mm_answer_jpake_key_confirm(int sock, Buffer *m) | ||
2257 | { | ||
2258 | struct jpake_ctx *pctx = authctxt->jpake_ctx; | ||
2259 | u_char *x2_s_proof; | ||
2260 | u_int x2_s_proof_len; | ||
2261 | |||
2262 | if (pctx == NULL) | ||
2263 | fatal("%s: pctx == NULL", __func__); | ||
2264 | |||
2265 | if ((pctx->a = BN_new()) == NULL) | ||
2266 | fatal("%s: BN_new", __func__); | ||
2267 | buffer_get_bignum2(m, pctx->a); | ||
2268 | x2_s_proof = buffer_get_string(m, &x2_s_proof_len); | ||
2269 | |||
2270 | jpake_key_confirm(pctx->grp, pctx->s, pctx->a, | ||
2271 | pctx->x4, pctx->g_x3, pctx->g_x4, pctx->g_x1, pctx->g_x2, | ||
2272 | pctx->server_id, pctx->server_id_len, | ||
2273 | pctx->client_id, pctx->client_id_len, | ||
2274 | session_id2, session_id2_len, | ||
2275 | x2_s_proof, x2_s_proof_len, | ||
2276 | &pctx->k, | ||
2277 | &pctx->h_k_sid_sessid, &pctx->h_k_sid_sessid_len); | ||
2278 | |||
2279 | JPAKE_DEBUG_CTX((pctx, "key_confirm done in %s", __func__)); | ||
2280 | |||
2281 | bzero(x2_s_proof, x2_s_proof_len); | ||
2282 | buffer_clear(m); | ||
2283 | |||
2284 | /* pctx->k is sensitive, not sent */ | ||
2285 | buffer_put_string(m, pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len); | ||
2286 | |||
2287 | debug3("%s: sending confirmation hash", __func__); | ||
2288 | mm_request_send(sock, MONITOR_ANS_JPAKE_KEY_CONFIRM, m); | ||
2289 | |||
2290 | monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_CHECK_CONFIRM, 1); | ||
2291 | |||
2292 | return 0; | ||
2293 | } | ||
2294 | |||
2295 | int | ||
2296 | mm_answer_jpake_check_confirm(int sock, Buffer *m) | ||
2297 | { | ||
2298 | int authenticated = 0; | ||
2299 | u_char *peer_confirm_hash; | ||
2300 | u_int peer_confirm_hash_len; | ||
2301 | struct jpake_ctx *pctx = authctxt->jpake_ctx; | ||
2302 | |||
2303 | if (pctx == NULL) | ||
2304 | fatal("%s: pctx == NULL", __func__); | ||
2305 | |||
2306 | peer_confirm_hash = buffer_get_string(m, &peer_confirm_hash_len); | ||
2307 | |||
2308 | authenticated = jpake_check_confirm(pctx->k, | ||
2309 | pctx->client_id, pctx->client_id_len, | ||
2310 | session_id2, session_id2_len, | ||
2311 | peer_confirm_hash, peer_confirm_hash_len) && authctxt->valid; | ||
2312 | |||
2313 | JPAKE_DEBUG_CTX((pctx, "check_confirm done in %s", __func__)); | ||
2314 | |||
2315 | bzero(peer_confirm_hash, peer_confirm_hash_len); | ||
2316 | xfree(peer_confirm_hash); | ||
2317 | |||
2318 | buffer_clear(m); | ||
2319 | buffer_put_int(m, authenticated); | ||
2320 | |||
2321 | debug3("%s: sending result %d", __func__, authenticated); | ||
2322 | mm_request_send(sock, MONITOR_ANS_JPAKE_CHECK_CONFIRM, m); | ||
2323 | |||
2324 | monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 1); | ||
2325 | |||
2326 | auth_method = "jpake-01@openssh.com"; | ||
2327 | return authenticated; | ||
2328 | } | ||
2329 | |||
2330 | #endif /* JPAKE */ | ||