version 1.128, 2013/11/04 11:51:16 |
version 1.129, 2014/01/29 06:18:35 |
|
|
#include "misc.h" |
#include "misc.h" |
#include "compat.h" |
#include "compat.h" |
#include "ssh2.h" |
#include "ssh2.h" |
#include "jpake.h" |
|
#include "roaming.h" |
#include "roaming.h" |
#include "authfd.h" |
#include "authfd.h" |
|
|
|
|
int mm_answer_rsa_response(int, Buffer *); |
int mm_answer_rsa_response(int, Buffer *); |
int mm_answer_sesskey(int, Buffer *); |
int mm_answer_sesskey(int, Buffer *); |
int mm_answer_sessid(int, Buffer *); |
int mm_answer_sessid(int, Buffer *); |
int mm_answer_jpake_get_pwdata(int, Buffer *); |
|
int mm_answer_jpake_step1(int, Buffer *); |
|
int mm_answer_jpake_step2(int, Buffer *); |
|
int mm_answer_jpake_key_confirm(int, Buffer *); |
|
int mm_answer_jpake_check_confirm(int, Buffer *); |
|
|
|
#ifdef GSSAPI |
#ifdef GSSAPI |
int mm_answer_gss_setup_ctx(int, Buffer *); |
int mm_answer_gss_setup_ctx(int, Buffer *); |
|
|
{MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, |
{MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, |
{MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, |
{MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, |
#endif |
#endif |
#ifdef JPAKE |
|
{MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata}, |
|
{MONITOR_REQ_JPAKE_STEP1, MON_ISAUTH, mm_answer_jpake_step1}, |
|
{MONITOR_REQ_JPAKE_STEP2, MON_ONCE, mm_answer_jpake_step2}, |
|
{MONITOR_REQ_JPAKE_KEY_CONFIRM, MON_ONCE, mm_answer_jpake_key_confirm}, |
|
{MONITOR_REQ_JPAKE_CHECK_CONFIRM, MON_AUTH, mm_answer_jpake_check_confirm}, |
|
#endif |
|
{0, 0, NULL} |
{0, 0, NULL} |
}; |
}; |
|
|
|
|
if (!authenticated) |
if (!authenticated) |
authctxt->failures++; |
authctxt->failures++; |
} |
} |
#ifdef JPAKE |
|
/* Cleanup JPAKE context after authentication */ |
|
if (ent->flags & MON_AUTHDECIDE) { |
|
if (authctxt->jpake_ctx != NULL) { |
|
jpake_free(authctxt->jpake_ctx); |
|
authctxt->jpake_ctx = NULL; |
|
} |
|
} |
|
#endif |
|
} |
} |
|
|
if (!authctxt->valid) |
if (!authctxt->valid) |
|
|
} |
} |
#endif /* GSSAPI */ |
#endif /* GSSAPI */ |
|
|
#ifdef JPAKE |
|
int |
|
mm_answer_jpake_step1(int sock, Buffer *m) |
|
{ |
|
struct jpake_ctx *pctx; |
|
u_char *x3_proof, *x4_proof; |
|
u_int x3_proof_len, x4_proof_len; |
|
|
|
if (!options.zero_knowledge_password_authentication) |
|
fatal("zero_knowledge_password_authentication disabled"); |
|
|
|
if (authctxt->jpake_ctx != NULL) |
|
fatal("%s: authctxt->jpake_ctx already set (%p)", |
|
__func__, authctxt->jpake_ctx); |
|
authctxt->jpake_ctx = pctx = jpake_new(); |
|
|
|
jpake_step1(pctx->grp, |
|
&pctx->server_id, &pctx->server_id_len, |
|
&pctx->x3, &pctx->x4, &pctx->g_x3, &pctx->g_x4, |
|
&x3_proof, &x3_proof_len, |
|
&x4_proof, &x4_proof_len); |
|
|
|
JPAKE_DEBUG_CTX((pctx, "step1 done in %s", __func__)); |
|
|
|
buffer_clear(m); |
|
|
|
buffer_put_string(m, pctx->server_id, pctx->server_id_len); |
|
buffer_put_bignum2(m, pctx->g_x3); |
|
buffer_put_bignum2(m, pctx->g_x4); |
|
buffer_put_string(m, x3_proof, x3_proof_len); |
|
buffer_put_string(m, x4_proof, x4_proof_len); |
|
|
|
debug3("%s: sending step1", __func__); |
|
mm_request_send(sock, MONITOR_ANS_JPAKE_STEP1, m); |
|
|
|
bzero(x3_proof, x3_proof_len); |
|
bzero(x4_proof, x4_proof_len); |
|
free(x3_proof); |
|
free(x4_proof); |
|
|
|
monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_GET_PWDATA, 1); |
|
monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 0); |
|
|
|
return 0; |
|
} |
|
|
|
int |
|
mm_answer_jpake_get_pwdata(int sock, Buffer *m) |
|
{ |
|
struct jpake_ctx *pctx = authctxt->jpake_ctx; |
|
char *hash_scheme, *salt; |
|
|
|
if (pctx == NULL) |
|
fatal("%s: pctx == NULL", __func__); |
|
|
|
auth2_jpake_get_pwdata(authctxt, &pctx->s, &hash_scheme, &salt); |
|
|
|
buffer_clear(m); |
|
/* pctx->s is sensitive, not returned to slave */ |
|
buffer_put_cstring(m, hash_scheme); |
|
buffer_put_cstring(m, salt); |
|
|
|
debug3("%s: sending pwdata", __func__); |
|
mm_request_send(sock, MONITOR_ANS_JPAKE_GET_PWDATA, m); |
|
|
|
bzero(hash_scheme, strlen(hash_scheme)); |
|
bzero(salt, strlen(salt)); |
|
free(hash_scheme); |
|
free(salt); |
|
|
|
monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP2, 1); |
|
|
|
return 0; |
|
} |
|
|
|
int |
|
mm_answer_jpake_step2(int sock, Buffer *m) |
|
{ |
|
struct jpake_ctx *pctx = authctxt->jpake_ctx; |
|
u_char *x1_proof, *x2_proof, *x4_s_proof; |
|
u_int x1_proof_len, x2_proof_len, x4_s_proof_len; |
|
|
|
if (pctx == NULL) |
|
fatal("%s: pctx == NULL", __func__); |
|
|
|
if ((pctx->g_x1 = BN_new()) == NULL || |
|
(pctx->g_x2 = BN_new()) == NULL) |
|
fatal("%s: BN_new", __func__); |
|
buffer_get_bignum2(m, pctx->g_x1); |
|
buffer_get_bignum2(m, pctx->g_x2); |
|
pctx->client_id = buffer_get_string(m, &pctx->client_id_len); |
|
x1_proof = buffer_get_string(m, &x1_proof_len); |
|
x2_proof = buffer_get_string(m, &x2_proof_len); |
|
|
|
jpake_step2(pctx->grp, pctx->s, pctx->g_x3, |
|
pctx->g_x1, pctx->g_x2, pctx->x4, |
|
pctx->client_id, pctx->client_id_len, |
|
pctx->server_id, pctx->server_id_len, |
|
x1_proof, x1_proof_len, |
|
x2_proof, x2_proof_len, |
|
&pctx->b, |
|
&x4_s_proof, &x4_s_proof_len); |
|
|
|
JPAKE_DEBUG_CTX((pctx, "step2 done in %s", __func__)); |
|
|
|
bzero(x1_proof, x1_proof_len); |
|
bzero(x2_proof, x2_proof_len); |
|
free(x1_proof); |
|
free(x2_proof); |
|
|
|
buffer_clear(m); |
|
|
|
buffer_put_bignum2(m, pctx->b); |
|
buffer_put_string(m, x4_s_proof, x4_s_proof_len); |
|
|
|
debug3("%s: sending step2", __func__); |
|
mm_request_send(sock, MONITOR_ANS_JPAKE_STEP2, m); |
|
|
|
bzero(x4_s_proof, x4_s_proof_len); |
|
free(x4_s_proof); |
|
|
|
monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_KEY_CONFIRM, 1); |
|
|
|
return 0; |
|
} |
|
|
|
int |
|
mm_answer_jpake_key_confirm(int sock, Buffer *m) |
|
{ |
|
struct jpake_ctx *pctx = authctxt->jpake_ctx; |
|
u_char *x2_s_proof; |
|
u_int x2_s_proof_len; |
|
|
|
if (pctx == NULL) |
|
fatal("%s: pctx == NULL", __func__); |
|
|
|
if ((pctx->a = BN_new()) == NULL) |
|
fatal("%s: BN_new", __func__); |
|
buffer_get_bignum2(m, pctx->a); |
|
x2_s_proof = buffer_get_string(m, &x2_s_proof_len); |
|
|
|
jpake_key_confirm(pctx->grp, pctx->s, pctx->a, |
|
pctx->x4, pctx->g_x3, pctx->g_x4, pctx->g_x1, pctx->g_x2, |
|
pctx->server_id, pctx->server_id_len, |
|
pctx->client_id, pctx->client_id_len, |
|
session_id2, session_id2_len, |
|
x2_s_proof, x2_s_proof_len, |
|
&pctx->k, |
|
&pctx->h_k_sid_sessid, &pctx->h_k_sid_sessid_len); |
|
|
|
JPAKE_DEBUG_CTX((pctx, "key_confirm done in %s", __func__)); |
|
|
|
bzero(x2_s_proof, x2_s_proof_len); |
|
buffer_clear(m); |
|
|
|
/* pctx->k is sensitive, not sent */ |
|
buffer_put_string(m, pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len); |
|
|
|
debug3("%s: sending confirmation hash", __func__); |
|
mm_request_send(sock, MONITOR_ANS_JPAKE_KEY_CONFIRM, m); |
|
|
|
monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_CHECK_CONFIRM, 1); |
|
|
|
return 0; |
|
} |
|
|
|
int |
|
mm_answer_jpake_check_confirm(int sock, Buffer *m) |
|
{ |
|
int authenticated = 0; |
|
u_char *peer_confirm_hash; |
|
u_int peer_confirm_hash_len; |
|
struct jpake_ctx *pctx = authctxt->jpake_ctx; |
|
|
|
if (pctx == NULL) |
|
fatal("%s: pctx == NULL", __func__); |
|
|
|
peer_confirm_hash = buffer_get_string(m, &peer_confirm_hash_len); |
|
|
|
authenticated = jpake_check_confirm(pctx->k, |
|
pctx->client_id, pctx->client_id_len, |
|
session_id2, session_id2_len, |
|
peer_confirm_hash, peer_confirm_hash_len) && authctxt->valid; |
|
|
|
JPAKE_DEBUG_CTX((pctx, "check_confirm done in %s", __func__)); |
|
|
|
bzero(peer_confirm_hash, peer_confirm_hash_len); |
|
free(peer_confirm_hash); |
|
|
|
buffer_clear(m); |
|
buffer_put_int(m, authenticated); |
|
|
|
debug3("%s: sending result %d", __func__, authenticated); |
|
mm_request_send(sock, MONITOR_ANS_JPAKE_CHECK_CONFIRM, m); |
|
|
|
monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 1); |
|
|
|
auth_method = "jpake-01@openssh.com"; |
|
return authenticated; |
|
} |
|
|
|
#endif /* JPAKE */ |
|