summaryrefslogtreecommitdiff
path: root/sshconnect2.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshconnect2.c')
-rw-r--r--sshconnect2.c353
1 files changed, 336 insertions, 17 deletions
diff --git a/sshconnect2.c b/sshconnect2.c
index 185e7b204..bb72db5dd 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,6 +1,7 @@
1/* $OpenBSD: sshconnect2.c,v 1.166 2008/07/17 08:48:00 djm Exp $ */ 1/* $OpenBSD: sshconnect2.c,v 1.170 2008/11/04 08:22:13 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Damien Miller. All rights reserved.
4 * 5 *
5 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
@@ -67,6 +68,7 @@
67#include "msg.h" 68#include "msg.h"
68#include "pathnames.h" 69#include "pathnames.h"
69#include "uidswap.h" 70#include "uidswap.h"
71#include "jpake.h"
70 72
71#ifdef GSSAPI 73#ifdef GSSAPI
72#include "ssh-gss.h" 74#include "ssh-gss.h"
@@ -121,7 +123,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
121 else 123 else
122 gss_host = host; 124 gss_host = host;
123 125
124 gss = ssh_gssapi_client_mechanisms(gss_host); 126 gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity);
125 if (gss) { 127 if (gss) {
126 debug("Offering GSSAPI proposal: %s", gss); 128 debug("Offering GSSAPI proposal: %s", gss);
127 xasprintf(&myproposal[PROPOSAL_KEX_ALGS], 129 xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
@@ -164,6 +166,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
164 orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; 166 orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
165 xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], 167 xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],
166 "%s,null", orig); 168 "%s,null", orig);
169 xfree(gss);
167 } 170 }
168#endif 171#endif
169 172
@@ -177,18 +180,23 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
177 kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; 180 kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
178 kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; 181 kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
179#ifdef GSSAPI 182#ifdef GSSAPI
180 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client; 183 if (options.gss_keyex) {
181 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client; 184 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client;
182 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client; 185 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client;
186 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client;
187 }
183#endif 188#endif
184 kex->client_version_string=client_version_string; 189 kex->client_version_string=client_version_string;
185 kex->server_version_string=server_version_string; 190 kex->server_version_string=server_version_string;
186 kex->verify_host_key=&verify_host_key_callback; 191 kex->verify_host_key=&verify_host_key_callback;
187 192
188#ifdef GSSAPI 193#ifdef GSSAPI
189 kex->gss_deleg_creds = options.gss_deleg_creds; 194 if (options.gss_keyex) {
190 kex->gss_trust_dns = options.gss_trust_dns; 195 kex->gss_deleg_creds = options.gss_deleg_creds;
191 kex->gss_host = gss_host; 196 kex->gss_trust_dns = options.gss_trust_dns;
197 kex->gss_client = options.gss_client_identity;
198 kex->gss_host = gss_host;
199 }
192#endif 200#endif
193 201
194 xxx_kex = kex; 202 xxx_kex = kex;
@@ -247,6 +255,7 @@ struct Authctxt {
247struct Authmethod { 255struct Authmethod {
248 char *name; /* string to compare against server's list */ 256 char *name; /* string to compare against server's list */
249 int (*userauth)(Authctxt *authctxt); 257 int (*userauth)(Authctxt *authctxt);
258 void (*cleanup)(Authctxt *authctxt);
250 int *enabled; /* flag in option struct that enables method */ 259 int *enabled; /* flag in option struct that enables method */
251 int *batch_flag; /* flag in option struct that disables method */ 260 int *batch_flag; /* flag in option struct that disables method */
252}; 261};
@@ -258,13 +267,18 @@ void input_userauth_error(int, u_int32_t, void *);
258void input_userauth_info_req(int, u_int32_t, void *); 267void input_userauth_info_req(int, u_int32_t, void *);
259void input_userauth_pk_ok(int, u_int32_t, void *); 268void input_userauth_pk_ok(int, u_int32_t, void *);
260void input_userauth_passwd_changereq(int, u_int32_t, void *); 269void input_userauth_passwd_changereq(int, u_int32_t, void *);
270void input_userauth_jpake_server_step1(int, u_int32_t, void *);
271void input_userauth_jpake_server_step2(int, u_int32_t, void *);
272void input_userauth_jpake_server_confirm(int, u_int32_t, void *);
261 273
262int userauth_none(Authctxt *); 274int userauth_none(Authctxt *);
263int userauth_pubkey(Authctxt *); 275int userauth_pubkey(Authctxt *);
264int userauth_passwd(Authctxt *); 276int userauth_passwd(Authctxt *);
265int userauth_kbdint(Authctxt *); 277int userauth_kbdint(Authctxt *);
266int userauth_hostbased(Authctxt *); 278int userauth_hostbased(Authctxt *);
267int userauth_kerberos(Authctxt *); 279int userauth_jpake(Authctxt *);
280
281void userauth_jpake_cleanup(Authctxt *);
268 282
269#ifdef GSSAPI 283#ifdef GSSAPI
270int userauth_gssapi(Authctxt *authctxt); 284int userauth_gssapi(Authctxt *authctxt);
@@ -295,6 +309,7 @@ Authmethod authmethods[] = {
295 NULL}, 309 NULL},
296 {"gssapi-with-mic", 310 {"gssapi-with-mic",
297 userauth_gssapi, 311 userauth_gssapi,
312 NULL,
298 &options.gss_authentication, 313 &options.gss_authentication,
299 NULL}, 314 NULL},
300 {"gssapi", 315 {"gssapi",
@@ -304,25 +319,37 @@ Authmethod authmethods[] = {
304#endif 319#endif
305 {"hostbased", 320 {"hostbased",
306 userauth_hostbased, 321 userauth_hostbased,
322 NULL,
307 &options.hostbased_authentication, 323 &options.hostbased_authentication,
308 NULL}, 324 NULL},
309 {"publickey", 325 {"publickey",
310 userauth_pubkey, 326 userauth_pubkey,
327 NULL,
311 &options.pubkey_authentication, 328 &options.pubkey_authentication,
312 NULL}, 329 NULL},
330#ifdef JPAKE
331 {"jpake-01@openssh.com",
332 userauth_jpake,
333 userauth_jpake_cleanup,
334 &options.zero_knowledge_password_authentication,
335 &options.batch_mode},
336#endif
313 {"keyboard-interactive", 337 {"keyboard-interactive",
314 userauth_kbdint, 338 userauth_kbdint,
339 NULL,
315 &options.kbd_interactive_authentication, 340 &options.kbd_interactive_authentication,
316 &options.batch_mode}, 341 &options.batch_mode},
317 {"password", 342 {"password",
318 userauth_passwd, 343 userauth_passwd,
344 NULL,
319 &options.password_authentication, 345 &options.password_authentication,
320 &options.batch_mode}, 346 &options.batch_mode},
321 {"none", 347 {"none",
322 userauth_none, 348 userauth_none,
323 NULL, 349 NULL,
350 NULL,
324 NULL}, 351 NULL},
325 {NULL, NULL, NULL, NULL} 352 {NULL, NULL, NULL, NULL, NULL}
326}; 353};
327 354
328void 355void
@@ -390,6 +417,9 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
390void 417void
391userauth(Authctxt *authctxt, char *authlist) 418userauth(Authctxt *authctxt, char *authlist)
392{ 419{
420 if (authctxt->method != NULL && authctxt->method->cleanup != NULL)
421 authctxt->method->cleanup(authctxt);
422
393 if (authctxt->methoddata) { 423 if (authctxt->methoddata) {
394 xfree(authctxt->methoddata); 424 xfree(authctxt->methoddata);
395 authctxt->methoddata = NULL; 425 authctxt->methoddata = NULL;
@@ -422,6 +452,7 @@ userauth(Authctxt *authctxt, char *authlist)
422 } 452 }
423} 453}
424 454
455/* ARGSUSED */
425void 456void
426input_userauth_error(int type, u_int32_t seq, void *ctxt) 457input_userauth_error(int type, u_int32_t seq, void *ctxt)
427{ 458{
@@ -429,6 +460,7 @@ input_userauth_error(int type, u_int32_t seq, void *ctxt)
429 "type %d", type); 460 "type %d", type);
430} 461}
431 462
463/* ARGSUSED */
432void 464void
433input_userauth_banner(int type, u_int32_t seq, void *ctxt) 465input_userauth_banner(int type, u_int32_t seq, void *ctxt)
434{ 466{
@@ -438,12 +470,11 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt)
438 debug3("input_userauth_banner"); 470 debug3("input_userauth_banner");
439 raw = packet_get_string(&len); 471 raw = packet_get_string(&len);
440 lang = packet_get_string(NULL); 472 lang = packet_get_string(NULL);
441 if (options.log_level >= SYSLOG_LEVEL_INFO) { 473 if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO) {
442 if (len > 65536) 474 if (len > 65536)
443 len = 65536; 475 len = 65536;
444 msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */ 476 msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */
445 strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL); 477 strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL);
446 msg[len*4] = '\0';
447 fprintf(stderr, "%s", msg); 478 fprintf(stderr, "%s", msg);
448 xfree(msg); 479 xfree(msg);
449 } 480 }
@@ -451,6 +482,7 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt)
451 xfree(lang); 482 xfree(lang);
452} 483}
453 484
485/* ARGSUSED */
454void 486void
455input_userauth_success(int type, u_int32_t seq, void *ctxt) 487input_userauth_success(int type, u_int32_t seq, void *ctxt)
456{ 488{
@@ -468,6 +500,7 @@ input_userauth_success(int type, u_int32_t seq, void *ctxt)
468 authctxt->success = 1; /* break out */ 500 authctxt->success = 1; /* break out */
469} 501}
470 502
503/* ARGSUSED */
471void 504void
472input_userauth_failure(int type, u_int32_t seq, void *ctxt) 505input_userauth_failure(int type, u_int32_t seq, void *ctxt)
473{ 506{
@@ -488,6 +521,8 @@ input_userauth_failure(int type, u_int32_t seq, void *ctxt)
488 521
489 userauth(authctxt, authlist); 522 userauth(authctxt, authlist);
490} 523}
524
525/* ARGSUSED */
491void 526void
492input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) 527input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
493{ 528{
@@ -567,26 +602,30 @@ userauth_gssapi(Authctxt *authctxt)
567 static u_int mech = 0; 602 static u_int mech = 0;
568 OM_uint32 min; 603 OM_uint32 min;
569 int ok = 0; 604 int ok = 0;
570 char *gss_host = NULL; 605 const char *gss_host;
571 int old_gssapi_method; 606 int old_gssapi_method;
572 607
573 if (options.gss_trust_dns) 608 if (options.gss_trust_dns)
574 gss_host = (char *)get_canonical_hostname(1); 609 gss_host = get_canonical_hostname(1);
575 else 610 else
576 gss_host = (char *)authctxt->host; 611 gss_host = authctxt->host;
577 612
578 /* Try one GSSAPI method at a time, rather than sending them all at 613 /* Try one GSSAPI method at a time, rather than sending them all at
579 * once. */ 614 * once. */
580 615
581 if (gss_supported == NULL) 616 if (gss_supported == NULL)
582 gss_indicate_mechs(&min, &gss_supported); 617 if (GSS_ERROR(gss_indicate_mechs(&min, &gss_supported))) {
618 gss_supported = NULL;
619 return 0;
620 }
583 621
584 /* Check to see if the mechanism is usable before we offer it */ 622 /* Check to see if the mechanism is usable before we offer it */
585 while (mech < gss_supported->count && !ok) { 623 while (mech < gss_supported->count && !ok) {
586 /* My DER encoding requires length<128 */ 624 /* My DER encoding requires length<128 */
587 if (gss_supported->elements[mech].length < 128 && 625 if (gss_supported->elements[mech].length < 128 &&
588 ssh_gssapi_check_mechanism(&gssctxt, 626 ssh_gssapi_check_mechanism(&gssctxt,
589 &gss_supported->elements[mech], gss_host)) { 627 &gss_supported->elements[mech], gss_host,
628 options.gss_client_identity)) {
590 ok = 1; /* Mechanism works */ 629 ok = 1; /* Mechanism works */
591 } else { 630 } else {
592 mech++; 631 mech++;
@@ -691,6 +730,7 @@ process_gssapi_token(void *ctxt, gss_buffer_t recv_tok)
691 return status; 730 return status;
692} 731}
693 732
733/* ARGSUSED */
694void 734void
695input_gssapi_response(int type, u_int32_t plen, void *ctxt) 735input_gssapi_response(int type, u_int32_t plen, void *ctxt)
696{ 736{
@@ -736,6 +776,7 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt)
736 } 776 }
737} 777}
738 778
779/* ARGSUSED */
739void 780void
740input_gssapi_token(int type, u_int32_t plen, void *ctxt) 781input_gssapi_token(int type, u_int32_t plen, void *ctxt)
741{ 782{
@@ -763,6 +804,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
763 } 804 }
764} 805}
765 806
807/* ARGSUSED */
766void 808void
767input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) 809input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
768{ 810{
@@ -792,6 +834,7 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
792 /* Server will be returning a failed packet after this one */ 834 /* Server will be returning a failed packet after this one */
793} 835}
794 836
837/* ARGSUSED */
795void 838void
796input_gssapi_error(int type, u_int32_t plen, void *ctxt) 839input_gssapi_error(int type, u_int32_t plen, void *ctxt)
797{ 840{
@@ -898,9 +941,11 @@ userauth_passwd(Authctxt *authctxt)
898 941
899 return 1; 942 return 1;
900} 943}
944
901/* 945/*
902 * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST 946 * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST
903 */ 947 */
948/* ARGSUSED */
904void 949void
905input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) 950input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
906{ 951{
@@ -965,6 +1010,209 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
965 &input_userauth_passwd_changereq); 1010 &input_userauth_passwd_changereq);
966} 1011}
967 1012
1013#ifdef JPAKE
1014static char *
1015pw_encrypt(const char *password, const char *crypt_scheme, const char *salt)
1016{
1017 /* OpenBSD crypt(3) handles all of these */
1018 if (strcmp(crypt_scheme, "crypt") == 0 ||
1019 strcmp(crypt_scheme, "bcrypt") == 0 ||
1020 strcmp(crypt_scheme, "md5crypt") == 0 ||
1021 strcmp(crypt_scheme, "crypt-extended") == 0)
1022 return xstrdup(crypt(password, salt));
1023 error("%s: unsupported password encryption scheme \"%.100s\"",
1024 __func__, crypt_scheme);
1025 return NULL;
1026}
1027
1028static BIGNUM *
1029jpake_password_to_secret(Authctxt *authctxt, const char *crypt_scheme,
1030 const char *salt)
1031{
1032 char prompt[256], *password, *crypted;
1033 u_char *secret;
1034 u_int secret_len;
1035 BIGNUM *ret;
1036
1037 snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password (JPAKE): ",
1038 authctxt->server_user, authctxt->host);
1039 password = read_passphrase(prompt, 0);
1040
1041 if ((crypted = pw_encrypt(password, crypt_scheme, salt)) == NULL) {
1042 logit("Disabling %s authentication", authctxt->method->name);
1043 authctxt->method->enabled = NULL;
1044 /* Continue with an empty password to fail gracefully */
1045 crypted = xstrdup("");
1046 }
1047
1048#ifdef JPAKE_DEBUG
1049 debug3("%s: salt = %s", __func__, salt);
1050 debug3("%s: scheme = %s", __func__, crypt_scheme);
1051 debug3("%s: crypted = %s", __func__, crypted);
1052#endif
1053
1054 if (hash_buffer(crypted, strlen(crypted), EVP_sha256(),
1055 &secret, &secret_len) != 0)
1056 fatal("%s: hash_buffer", __func__);
1057
1058 bzero(password, strlen(password));
1059 bzero(crypted, strlen(crypted));
1060 xfree(password);
1061 xfree(crypted);
1062
1063 if ((ret = BN_bin2bn(secret, secret_len, NULL)) == NULL)
1064 fatal("%s: BN_bin2bn (secret)", __func__);
1065 bzero(secret, secret_len);
1066 xfree(secret);
1067
1068 return ret;
1069}
1070
1071/* ARGSUSED */
1072void
1073input_userauth_jpake_server_step1(int type, u_int32_t seq, void *ctxt)
1074{
1075 Authctxt *authctxt = ctxt;
1076 struct jpake_ctx *pctx = authctxt->methoddata;
1077 u_char *x3_proof, *x4_proof, *x2_s_proof;
1078 u_int x3_proof_len, x4_proof_len, x2_s_proof_len;
1079 char *crypt_scheme, *salt;
1080
1081 /* Disable this message */
1082 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1, NULL);
1083
1084 if ((pctx->g_x3 = BN_new()) == NULL ||
1085 (pctx->g_x4 = BN_new()) == NULL)
1086 fatal("%s: BN_new", __func__);
1087
1088 /* Fetch step 1 values */
1089 crypt_scheme = packet_get_string(NULL);
1090 salt = packet_get_string(NULL);
1091 pctx->server_id = packet_get_string(&pctx->server_id_len);
1092 packet_get_bignum2(pctx->g_x3);
1093 packet_get_bignum2(pctx->g_x4);
1094 x3_proof = packet_get_string(&x3_proof_len);
1095 x4_proof = packet_get_string(&x4_proof_len);
1096 packet_check_eom();
1097
1098 JPAKE_DEBUG_CTX((pctx, "step 1 received in %s", __func__));
1099
1100 /* Obtain password and derive secret */
1101 pctx->s = jpake_password_to_secret(authctxt, crypt_scheme, salt);
1102 bzero(crypt_scheme, strlen(crypt_scheme));
1103 bzero(salt, strlen(salt));
1104 xfree(crypt_scheme);
1105 xfree(salt);
1106 JPAKE_DEBUG_BN((pctx->s, "%s: s = ", __func__));
1107
1108 /* Calculate step 2 values */
1109 jpake_step2(pctx->grp, pctx->s, pctx->g_x1,
1110 pctx->g_x3, pctx->g_x4, pctx->x2,
1111 pctx->server_id, pctx->server_id_len,
1112 pctx->client_id, pctx->client_id_len,
1113 x3_proof, x3_proof_len,
1114 x4_proof, x4_proof_len,
1115 &pctx->a,
1116 &x2_s_proof, &x2_s_proof_len);
1117
1118 bzero(x3_proof, x3_proof_len);
1119 bzero(x4_proof, x4_proof_len);
1120 xfree(x3_proof);
1121 xfree(x4_proof);
1122
1123 JPAKE_DEBUG_CTX((pctx, "step 2 sending in %s", __func__));
1124
1125 /* Send values for step 2 */
1126 packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2);
1127 packet_put_bignum2(pctx->a);
1128 packet_put_string(x2_s_proof, x2_s_proof_len);
1129 packet_send();
1130
1131 bzero(x2_s_proof, x2_s_proof_len);
1132 xfree(x2_s_proof);
1133
1134 /* Expect step 2 packet from peer */
1135 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2,
1136 input_userauth_jpake_server_step2);
1137}
1138
1139/* ARGSUSED */
1140void
1141input_userauth_jpake_server_step2(int type, u_int32_t seq, void *ctxt)
1142{
1143 Authctxt *authctxt = ctxt;
1144 struct jpake_ctx *pctx = authctxt->methoddata;
1145 u_char *x4_s_proof;
1146 u_int x4_s_proof_len;
1147
1148 /* Disable this message */
1149 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2, NULL);
1150
1151 if ((pctx->b = BN_new()) == NULL)
1152 fatal("%s: BN_new", __func__);
1153
1154 /* Fetch step 2 values */
1155 packet_get_bignum2(pctx->b);
1156 x4_s_proof = packet_get_string(&x4_s_proof_len);
1157 packet_check_eom();
1158
1159 JPAKE_DEBUG_CTX((pctx, "step 2 received in %s", __func__));
1160
1161 /* Derive shared key and calculate confirmation hash */
1162 jpake_key_confirm(pctx->grp, pctx->s, pctx->b,
1163 pctx->x2, pctx->g_x1, pctx->g_x2, pctx->g_x3, pctx->g_x4,
1164 pctx->client_id, pctx->client_id_len,
1165 pctx->server_id, pctx->server_id_len,
1166 session_id2, session_id2_len,
1167 x4_s_proof, x4_s_proof_len,
1168 &pctx->k,
1169 &pctx->h_k_cid_sessid, &pctx->h_k_cid_sessid_len);
1170
1171 bzero(x4_s_proof, x4_s_proof_len);
1172 xfree(x4_s_proof);
1173
1174 JPAKE_DEBUG_CTX((pctx, "confirm sending in %s", __func__));
1175
1176 /* Send key confirmation proof */
1177 packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM);
1178 packet_put_string(pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len);
1179 packet_send();
1180
1181 /* Expect confirmation from peer */
1182 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM,
1183 input_userauth_jpake_server_confirm);
1184}
1185
1186/* ARGSUSED */
1187void
1188input_userauth_jpake_server_confirm(int type, u_int32_t seq, void *ctxt)
1189{
1190 Authctxt *authctxt = ctxt;
1191 struct jpake_ctx *pctx = authctxt->methoddata;
1192
1193 /* Disable this message */
1194 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM, NULL);
1195
1196 pctx->h_k_sid_sessid = packet_get_string(&pctx->h_k_sid_sessid_len);
1197 packet_check_eom();
1198
1199 JPAKE_DEBUG_CTX((pctx, "confirm received in %s", __func__));
1200
1201 /* Verify expected confirmation hash */
1202 if (jpake_check_confirm(pctx->k,
1203 pctx->server_id, pctx->server_id_len,
1204 session_id2, session_id2_len,
1205 pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len) == 1)
1206 debug("%s: %s success", __func__, authctxt->method->name);
1207 else {
1208 debug("%s: confirmation mismatch", __func__);
1209 /* XXX stash this so if auth succeeds then we can warn/kill */
1210 }
1211
1212 userauth_jpake_cleanup(authctxt);
1213}
1214#endif /* JPAKE */
1215
968static int 1216static int
969identity_sign(Identity *id, u_char **sigp, u_int *lenp, 1217identity_sign(Identity *id, u_char **sigp, u_int *lenp,
970 u_char *data, u_int datalen) 1218 u_char *data, u_int datalen)
@@ -1541,6 +1789,76 @@ userauth_hostbased(Authctxt *authctxt)
1541 return 1; 1789 return 1;
1542} 1790}
1543 1791
1792#ifdef JPAKE
1793int
1794userauth_jpake(Authctxt *authctxt)
1795{
1796 struct jpake_ctx *pctx;
1797 u_char *x1_proof, *x2_proof;
1798 u_int x1_proof_len, x2_proof_len;
1799 static int attempt = 0; /* XXX share with userauth_password's? */
1800
1801 if (attempt++ >= options.number_of_password_prompts)
1802 return 0;
1803 if (attempt != 1)
1804 error("Permission denied, please try again.");
1805
1806 if (authctxt->methoddata != NULL)
1807 fatal("%s: authctxt->methoddata already set (%p)",
1808 __func__, authctxt->methoddata);
1809
1810 authctxt->methoddata = pctx = jpake_new();
1811
1812 /*
1813 * Send request immediately, to get the protocol going while
1814 * we do the initial computations.
1815 */
1816 packet_start(SSH2_MSG_USERAUTH_REQUEST);
1817 packet_put_cstring(authctxt->server_user);
1818 packet_put_cstring(authctxt->service);
1819 packet_put_cstring(authctxt->method->name);
1820 packet_send();
1821 packet_write_wait();
1822
1823 jpake_step1(pctx->grp,
1824 &pctx->client_id, &pctx->client_id_len,
1825 &pctx->x1, &pctx->x2, &pctx->g_x1, &pctx->g_x2,
1826 &x1_proof, &x1_proof_len,
1827 &x2_proof, &x2_proof_len);
1828
1829 JPAKE_DEBUG_CTX((pctx, "step 1 sending in %s", __func__));
1830
1831 packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1);
1832 packet_put_string(pctx->client_id, pctx->client_id_len);
1833 packet_put_bignum2(pctx->g_x1);
1834 packet_put_bignum2(pctx->g_x2);
1835 packet_put_string(x1_proof, x1_proof_len);
1836 packet_put_string(x2_proof, x2_proof_len);
1837 packet_send();
1838
1839 bzero(x1_proof, x1_proof_len);
1840 bzero(x2_proof, x2_proof_len);
1841 xfree(x1_proof);
1842 xfree(x2_proof);
1843
1844 /* Expect step 1 packet from peer */
1845 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1,
1846 input_userauth_jpake_server_step1);
1847
1848 return 1;
1849}
1850
1851void
1852userauth_jpake_cleanup(Authctxt *authctxt)
1853{
1854 debug3("%s: clean up", __func__);
1855 if (authctxt->methoddata != NULL) {
1856 jpake_free(authctxt->methoddata);
1857 authctxt->methoddata = NULL;
1858 }
1859}
1860#endif /* JPAKE */
1861
1544/* find auth method */ 1862/* find auth method */
1545 1863
1546/* 1864/*
@@ -1642,3 +1960,4 @@ authmethods_get(void)
1642 buffer_free(&b); 1960 buffer_free(&b);
1643 return list; 1961 return list;
1644} 1962}
1963