diff options
Diffstat (limited to 'monitor.c')
-rw-r--r-- | monitor.c | 231 |
1 files changed, 229 insertions, 2 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; |
@@ -149,6 +150,11 @@ int mm_answer_rsa_challenge(int, Buffer *); | |||
149 | int mm_answer_rsa_response(int, Buffer *); | 150 | int mm_answer_rsa_response(int, Buffer *); |
150 | int mm_answer_sesskey(int, Buffer *); | 151 | int mm_answer_sesskey(int, Buffer *); |
151 | int mm_answer_sessid(int, Buffer *); | 152 | int mm_answer_sessid(int, Buffer *); |
153 | int mm_answer_jpake_get_pwdata(int, Buffer *); | ||
154 | int mm_answer_jpake_step1(int, Buffer *); | ||
155 | int mm_answer_jpake_step2(int, Buffer *); | ||
156 | int mm_answer_jpake_key_confirm(int, Buffer *); | ||
157 | int mm_answer_jpake_check_confirm(int, Buffer *); | ||
152 | 158 | ||
153 | #ifdef USE_PAM | 159 | #ifdef USE_PAM |
154 | int mm_answer_pam_start(int, Buffer *); | 160 | int mm_answer_pam_start(int, Buffer *); |
@@ -234,6 +240,13 @@ struct mon_table mon_dispatch_proto20[] = { | |||
234 | {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, | 240 | {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, |
235 | {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, | 241 | {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, |
236 | #endif | 242 | #endif |
243 | #ifdef JPAKE | ||
244 | {MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata}, | ||
245 | {MONITOR_REQ_JPAKE_STEP1, MON_ISAUTH, mm_answer_jpake_step1}, | ||
246 | {MONITOR_REQ_JPAKE_STEP2, MON_ONCE, mm_answer_jpake_step2}, | ||
247 | {MONITOR_REQ_JPAKE_KEY_CONFIRM, MON_ONCE, mm_answer_jpake_key_confirm}, | ||
248 | {MONITOR_REQ_JPAKE_CHECK_CONFIRM, MON_AUTH, mm_answer_jpake_check_confirm}, | ||
249 | #endif | ||
237 | {0, 0, NULL} | 250 | {0, 0, NULL} |
238 | }; | 251 | }; |
239 | 252 | ||
@@ -379,6 +392,15 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) | |||
379 | if (!authenticated) | 392 | if (!authenticated) |
380 | authctxt->failures++; | 393 | authctxt->failures++; |
381 | } | 394 | } |
395 | #ifdef JPAKE | ||
396 | /* Cleanup JPAKE context after authentication */ | ||
397 | if (ent->flags & MON_AUTHDECIDE) { | ||
398 | if (authctxt->jpake_ctx != NULL) { | ||
399 | jpake_free(authctxt->jpake_ctx); | ||
400 | authctxt->jpake_ctx = NULL; | ||
401 | } | ||
402 | } | ||
403 | #endif | ||
382 | } | 404 | } |
383 | 405 | ||
384 | if (!authctxt->valid) | 406 | if (!authctxt->valid) |
@@ -1478,7 +1500,9 @@ mm_answer_rsa_challenge(int sock, Buffer *m) | |||
1478 | fatal("%s: key type mismatch", __func__); | 1500 | fatal("%s: key type mismatch", __func__); |
1479 | if ((key = key_from_blob(blob, blen)) == NULL) | 1501 | if ((key = key_from_blob(blob, blen)) == NULL) |
1480 | fatal("%s: received bad key", __func__); | 1502 | fatal("%s: received bad key", __func__); |
1481 | 1503 | if (key->type != KEY_RSA) | |
1504 | fatal("%s: received bad key type %d", __func__, key->type); | ||
1505 | key->type = KEY_RSA1; | ||
1482 | if (ssh1_challenge) | 1506 | if (ssh1_challenge) |
1483 | BN_clear_free(ssh1_challenge); | 1507 | BN_clear_free(ssh1_challenge); |
1484 | ssh1_challenge = auth_rsa_generate_challenge(key); | 1508 | ssh1_challenge = auth_rsa_generate_challenge(key); |
@@ -1969,3 +1993,206 @@ mm_answer_gss_userok(int sock, Buffer *m) | |||
1969 | return (authenticated); | 1993 | return (authenticated); |
1970 | } | 1994 | } |
1971 | #endif /* GSSAPI */ | 1995 | #endif /* GSSAPI */ |
1996 | |||
1997 | #ifdef JPAKE | ||
1998 | int | ||
1999 | mm_answer_jpake_step1(int sock, Buffer *m) | ||
2000 | { | ||
2001 | struct jpake_ctx *pctx; | ||
2002 | u_char *x3_proof, *x4_proof; | ||
2003 | u_int x3_proof_len, x4_proof_len; | ||
2004 | |||
2005 | if (!options.zero_knowledge_password_authentication) | ||
2006 | fatal("zero_knowledge_password_authentication disabled"); | ||
2007 | |||
2008 | if (authctxt->jpake_ctx != NULL) | ||
2009 | fatal("%s: authctxt->jpake_ctx already set (%p)", | ||
2010 | __func__, authctxt->jpake_ctx); | ||
2011 | authctxt->jpake_ctx = pctx = jpake_new(); | ||
2012 | |||
2013 | jpake_step1(pctx->grp, | ||
2014 | &pctx->server_id, &pctx->server_id_len, | ||
2015 | &pctx->x3, &pctx->x4, &pctx->g_x3, &pctx->g_x4, | ||
2016 | &x3_proof, &x3_proof_len, | ||
2017 | &x4_proof, &x4_proof_len); | ||
2018 | |||
2019 | JPAKE_DEBUG_CTX((pctx, "step1 done in %s", __func__)); | ||
2020 | |||
2021 | buffer_clear(m); | ||
2022 | |||
2023 | buffer_put_string(m, pctx->server_id, pctx->server_id_len); | ||
2024 | buffer_put_bignum2(m, pctx->g_x3); | ||
2025 | buffer_put_bignum2(m, pctx->g_x4); | ||
2026 | buffer_put_string(m, x3_proof, x3_proof_len); | ||
2027 | buffer_put_string(m, x4_proof, x4_proof_len); | ||
2028 | |||
2029 | debug3("%s: sending step1", __func__); | ||
2030 | mm_request_send(sock, MONITOR_ANS_JPAKE_STEP1, m); | ||
2031 | |||
2032 | bzero(x3_proof, x3_proof_len); | ||
2033 | bzero(x4_proof, x4_proof_len); | ||
2034 | xfree(x3_proof); | ||
2035 | xfree(x4_proof); | ||
2036 | |||
2037 | monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_GET_PWDATA, 1); | ||
2038 | monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 0); | ||
2039 | |||
2040 | return 0; | ||
2041 | } | ||
2042 | |||
2043 | int | ||
2044 | mm_answer_jpake_get_pwdata(int sock, Buffer *m) | ||
2045 | { | ||
2046 | struct jpake_ctx *pctx = authctxt->jpake_ctx; | ||
2047 | char *hash_scheme, *salt; | ||
2048 | |||
2049 | if (pctx == NULL) | ||
2050 | fatal("%s: pctx == NULL", __func__); | ||
2051 | |||
2052 | auth2_jpake_get_pwdata(authctxt, &pctx->s, &hash_scheme, &salt); | ||
2053 | |||
2054 | buffer_clear(m); | ||
2055 | /* pctx->s is sensitive, not returned to slave */ | ||
2056 | buffer_put_cstring(m, hash_scheme); | ||
2057 | buffer_put_cstring(m, salt); | ||
2058 | |||
2059 | debug3("%s: sending pwdata", __func__); | ||
2060 | mm_request_send(sock, MONITOR_ANS_JPAKE_GET_PWDATA, m); | ||
2061 | |||
2062 | bzero(hash_scheme, strlen(hash_scheme)); | ||
2063 | bzero(salt, strlen(salt)); | ||
2064 | xfree(hash_scheme); | ||
2065 | xfree(salt); | ||
2066 | |||
2067 | monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP2, 1); | ||
2068 | |||
2069 | return 0; | ||
2070 | } | ||
2071 | |||
2072 | int | ||
2073 | mm_answer_jpake_step2(int sock, Buffer *m) | ||
2074 | { | ||
2075 | struct jpake_ctx *pctx = authctxt->jpake_ctx; | ||
2076 | u_char *x1_proof, *x2_proof, *x4_s_proof; | ||
2077 | u_int x1_proof_len, x2_proof_len, x4_s_proof_len; | ||
2078 | |||
2079 | if (pctx == NULL) | ||
2080 | fatal("%s: pctx == NULL", __func__); | ||
2081 | |||
2082 | if ((pctx->g_x1 = BN_new()) == NULL || | ||
2083 | (pctx->g_x2 = BN_new()) == NULL) | ||
2084 | fatal("%s: BN_new", __func__); | ||
2085 | buffer_get_bignum2(m, pctx->g_x1); | ||
2086 | buffer_get_bignum2(m, pctx->g_x2); | ||
2087 | pctx->client_id = buffer_get_string(m, &pctx->client_id_len); | ||
2088 | x1_proof = buffer_get_string(m, &x1_proof_len); | ||
2089 | x2_proof = buffer_get_string(m, &x2_proof_len); | ||
2090 | |||
2091 | jpake_step2(pctx->grp, pctx->s, pctx->g_x3, | ||
2092 | pctx->g_x1, pctx->g_x2, pctx->x4, | ||
2093 | pctx->client_id, pctx->client_id_len, | ||
2094 | pctx->server_id, pctx->server_id_len, | ||
2095 | x1_proof, x1_proof_len, | ||
2096 | x2_proof, x2_proof_len, | ||
2097 | &pctx->b, | ||
2098 | &x4_s_proof, &x4_s_proof_len); | ||
2099 | |||
2100 | JPAKE_DEBUG_CTX((pctx, "step2 done in %s", __func__)); | ||
2101 | |||
2102 | bzero(x1_proof, x1_proof_len); | ||
2103 | bzero(x2_proof, x2_proof_len); | ||
2104 | xfree(x1_proof); | ||
2105 | xfree(x2_proof); | ||
2106 | |||
2107 | buffer_clear(m); | ||
2108 | |||
2109 | buffer_put_bignum2(m, pctx->b); | ||
2110 | buffer_put_string(m, x4_s_proof, x4_s_proof_len); | ||
2111 | |||
2112 | debug3("%s: sending step2", __func__); | ||
2113 | mm_request_send(sock, MONITOR_ANS_JPAKE_STEP2, m); | ||
2114 | |||
2115 | bzero(x4_s_proof, x4_s_proof_len); | ||
2116 | xfree(x4_s_proof); | ||
2117 | |||
2118 | monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_KEY_CONFIRM, 1); | ||
2119 | |||
2120 | return 0; | ||
2121 | } | ||
2122 | |||
2123 | int | ||
2124 | mm_answer_jpake_key_confirm(int sock, Buffer *m) | ||
2125 | { | ||
2126 | struct jpake_ctx *pctx = authctxt->jpake_ctx; | ||
2127 | u_char *x2_s_proof; | ||
2128 | u_int x2_s_proof_len; | ||
2129 | |||
2130 | if (pctx == NULL) | ||
2131 | fatal("%s: pctx == NULL", __func__); | ||
2132 | |||
2133 | if ((pctx->a = BN_new()) == NULL) | ||
2134 | fatal("%s: BN_new", __func__); | ||
2135 | buffer_get_bignum2(m, pctx->a); | ||
2136 | x2_s_proof = buffer_get_string(m, &x2_s_proof_len); | ||
2137 | |||
2138 | jpake_key_confirm(pctx->grp, pctx->s, pctx->a, | ||
2139 | pctx->x4, pctx->g_x3, pctx->g_x4, pctx->g_x1, pctx->g_x2, | ||
2140 | pctx->server_id, pctx->server_id_len, | ||
2141 | pctx->client_id, pctx->client_id_len, | ||
2142 | session_id2, session_id2_len, | ||
2143 | x2_s_proof, x2_s_proof_len, | ||
2144 | &pctx->k, | ||
2145 | &pctx->h_k_sid_sessid, &pctx->h_k_sid_sessid_len); | ||
2146 | |||
2147 | JPAKE_DEBUG_CTX((pctx, "key_confirm done in %s", __func__)); | ||
2148 | |||
2149 | bzero(x2_s_proof, x2_s_proof_len); | ||
2150 | buffer_clear(m); | ||
2151 | |||
2152 | /* pctx->k is sensitive, not sent */ | ||
2153 | buffer_put_string(m, pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len); | ||
2154 | |||
2155 | debug3("%s: sending confirmation hash", __func__); | ||
2156 | mm_request_send(sock, MONITOR_ANS_JPAKE_KEY_CONFIRM, m); | ||
2157 | |||
2158 | monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_CHECK_CONFIRM, 1); | ||
2159 | |||
2160 | return 0; | ||
2161 | } | ||
2162 | |||
2163 | int | ||
2164 | mm_answer_jpake_check_confirm(int sock, Buffer *m) | ||
2165 | { | ||
2166 | int authenticated = 0; | ||
2167 | u_char *peer_confirm_hash; | ||
2168 | u_int peer_confirm_hash_len; | ||
2169 | struct jpake_ctx *pctx = authctxt->jpake_ctx; | ||
2170 | |||
2171 | if (pctx == NULL) | ||
2172 | fatal("%s: pctx == NULL", __func__); | ||
2173 | |||
2174 | peer_confirm_hash = buffer_get_string(m, &peer_confirm_hash_len); | ||
2175 | |||
2176 | authenticated = jpake_check_confirm(pctx->k, | ||
2177 | pctx->client_id, pctx->client_id_len, | ||
2178 | session_id2, session_id2_len, | ||
2179 | peer_confirm_hash, peer_confirm_hash_len) && authctxt->valid; | ||
2180 | |||
2181 | JPAKE_DEBUG_CTX((pctx, "check_confirm done in %s", __func__)); | ||
2182 | |||
2183 | bzero(peer_confirm_hash, peer_confirm_hash_len); | ||
2184 | xfree(peer_confirm_hash); | ||
2185 | |||
2186 | buffer_clear(m); | ||
2187 | buffer_put_int(m, authenticated); | ||
2188 | |||
2189 | debug3("%s: sending result %d", __func__, authenticated); | ||
2190 | mm_request_send(sock, MONITOR_ANS_JPAKE_CHECK_CONFIRM, m); | ||
2191 | |||
2192 | monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 1); | ||
2193 | |||
2194 | auth_method = "jpake-01@openssh.com"; | ||
2195 | return authenticated; | ||
2196 | } | ||
2197 | |||
2198 | #endif /* JPAKE */ | ||