summaryrefslogtreecommitdiff
path: root/sshconnect2.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshconnect2.c')
-rw-r--r--sshconnect2.c322
1 files changed, 316 insertions, 6 deletions
diff --git a/sshconnect2.c b/sshconnect2.c
index 389bec9e4..a762eec3b 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"
@@ -201,6 +203,7 @@ struct Authctxt {
201struct Authmethod { 203struct Authmethod {
202 char *name; /* string to compare against server's list */ 204 char *name; /* string to compare against server's list */
203 int (*userauth)(Authctxt *authctxt); 205 int (*userauth)(Authctxt *authctxt);
206 void (*cleanup)(Authctxt *authctxt);
204 int *enabled; /* flag in option struct that enables method */ 207 int *enabled; /* flag in option struct that enables method */
205 int *batch_flag; /* flag in option struct that disables method */ 208 int *batch_flag; /* flag in option struct that disables method */
206}; 209};
@@ -212,13 +215,18 @@ void input_userauth_error(int, u_int32_t, void *);
212void input_userauth_info_req(int, u_int32_t, void *); 215void input_userauth_info_req(int, u_int32_t, void *);
213void input_userauth_pk_ok(int, u_int32_t, void *); 216void input_userauth_pk_ok(int, u_int32_t, void *);
214void input_userauth_passwd_changereq(int, u_int32_t, void *); 217void input_userauth_passwd_changereq(int, u_int32_t, void *);
218void input_userauth_jpake_server_step1(int, u_int32_t, void *);
219void input_userauth_jpake_server_step2(int, u_int32_t, void *);
220void input_userauth_jpake_server_confirm(int, u_int32_t, void *);
215 221
216int userauth_none(Authctxt *); 222int userauth_none(Authctxt *);
217int userauth_pubkey(Authctxt *); 223int userauth_pubkey(Authctxt *);
218int userauth_passwd(Authctxt *); 224int userauth_passwd(Authctxt *);
219int userauth_kbdint(Authctxt *); 225int userauth_kbdint(Authctxt *);
220int userauth_hostbased(Authctxt *); 226int userauth_hostbased(Authctxt *);
221int userauth_kerberos(Authctxt *); 227int userauth_jpake(Authctxt *);
228
229void userauth_jpake_cleanup(Authctxt *);
222 230
223#ifdef GSSAPI 231#ifdef GSSAPI
224int userauth_gssapi(Authctxt *authctxt); 232int userauth_gssapi(Authctxt *authctxt);
@@ -244,30 +252,43 @@ Authmethod authmethods[] = {
244#ifdef GSSAPI 252#ifdef GSSAPI
245 {"gssapi-with-mic", 253 {"gssapi-with-mic",
246 userauth_gssapi, 254 userauth_gssapi,
255 NULL,
247 &options.gss_authentication, 256 &options.gss_authentication,
248 NULL}, 257 NULL},
249#endif 258#endif
250 {"hostbased", 259 {"hostbased",
251 userauth_hostbased, 260 userauth_hostbased,
261 NULL,
252 &options.hostbased_authentication, 262 &options.hostbased_authentication,
253 NULL}, 263 NULL},
254 {"publickey", 264 {"publickey",
255 userauth_pubkey, 265 userauth_pubkey,
266 NULL,
256 &options.pubkey_authentication, 267 &options.pubkey_authentication,
257 NULL}, 268 NULL},
269#ifdef JPAKE
270 {"jpake-01@openssh.com",
271 userauth_jpake,
272 userauth_jpake_cleanup,
273 &options.zero_knowledge_password_authentication,
274 &options.batch_mode},
275#endif
258 {"keyboard-interactive", 276 {"keyboard-interactive",
259 userauth_kbdint, 277 userauth_kbdint,
278 NULL,
260 &options.kbd_interactive_authentication, 279 &options.kbd_interactive_authentication,
261 &options.batch_mode}, 280 &options.batch_mode},
262 {"password", 281 {"password",
263 userauth_passwd, 282 userauth_passwd,
283 NULL,
264 &options.password_authentication, 284 &options.password_authentication,
265 &options.batch_mode}, 285 &options.batch_mode},
266 {"none", 286 {"none",
267 userauth_none, 287 userauth_none,
268 NULL, 288 NULL,
289 NULL,
269 NULL}, 290 NULL},
270 {NULL, NULL, NULL, NULL} 291 {NULL, NULL, NULL, NULL, NULL}
271}; 292};
272 293
273void 294void
@@ -335,6 +356,9 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
335void 356void
336userauth(Authctxt *authctxt, char *authlist) 357userauth(Authctxt *authctxt, char *authlist)
337{ 358{
359 if (authctxt->method != NULL && authctxt->method->cleanup != NULL)
360 authctxt->method->cleanup(authctxt);
361
338 if (authctxt->methoddata) { 362 if (authctxt->methoddata) {
339 xfree(authctxt->methoddata); 363 xfree(authctxt->methoddata);
340 authctxt->methoddata = NULL; 364 authctxt->methoddata = NULL;
@@ -367,6 +391,7 @@ userauth(Authctxt *authctxt, char *authlist)
367 } 391 }
368} 392}
369 393
394/* ARGSUSED */
370void 395void
371input_userauth_error(int type, u_int32_t seq, void *ctxt) 396input_userauth_error(int type, u_int32_t seq, void *ctxt)
372{ 397{
@@ -374,6 +399,7 @@ input_userauth_error(int type, u_int32_t seq, void *ctxt)
374 "type %d", type); 399 "type %d", type);
375} 400}
376 401
402/* ARGSUSED */
377void 403void
378input_userauth_banner(int type, u_int32_t seq, void *ctxt) 404input_userauth_banner(int type, u_int32_t seq, void *ctxt)
379{ 405{
@@ -383,11 +409,11 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt)
383 debug3("input_userauth_banner"); 409 debug3("input_userauth_banner");
384 raw = packet_get_string(&len); 410 raw = packet_get_string(&len);
385 lang = packet_get_string(NULL); 411 lang = packet_get_string(NULL);
386 if (options.log_level >= SYSLOG_LEVEL_INFO) { 412 if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO) {
387 if (len > 65536) 413 if (len > 65536)
388 len = 65536; 414 len = 65536;
389 msg = xmalloc(len * 4); /* max expansion from strnvis() */ 415 msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */
390 strnvis(msg, raw, len * 4, VIS_SAFE|VIS_OCTAL); 416 strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL);
391 fprintf(stderr, "%s", msg); 417 fprintf(stderr, "%s", msg);
392 xfree(msg); 418 xfree(msg);
393 } 419 }
@@ -395,6 +421,7 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt)
395 xfree(lang); 421 xfree(lang);
396} 422}
397 423
424/* ARGSUSED */
398void 425void
399input_userauth_success(int type, u_int32_t seq, void *ctxt) 426input_userauth_success(int type, u_int32_t seq, void *ctxt)
400{ 427{
@@ -412,6 +439,7 @@ input_userauth_success(int type, u_int32_t seq, void *ctxt)
412 authctxt->success = 1; /* break out */ 439 authctxt->success = 1; /* break out */
413} 440}
414 441
442/* ARGSUSED */
415void 443void
416input_userauth_failure(int type, u_int32_t seq, void *ctxt) 444input_userauth_failure(int type, u_int32_t seq, void *ctxt)
417{ 445{
@@ -432,6 +460,8 @@ input_userauth_failure(int type, u_int32_t seq, void *ctxt)
432 460
433 userauth(authctxt, authlist); 461 userauth(authctxt, authlist);
434} 462}
463
464/* ARGSUSED */
435void 465void
436input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) 466input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
437{ 467{
@@ -614,6 +644,7 @@ process_gssapi_token(void *ctxt, gss_buffer_t recv_tok)
614 return status; 644 return status;
615} 645}
616 646
647/* ARGSUSED */
617void 648void
618input_gssapi_response(int type, u_int32_t plen, void *ctxt) 649input_gssapi_response(int type, u_int32_t plen, void *ctxt)
619{ 650{
@@ -653,6 +684,7 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt)
653 } 684 }
654} 685}
655 686
687/* ARGSUSED */
656void 688void
657input_gssapi_token(int type, u_int32_t plen, void *ctxt) 689input_gssapi_token(int type, u_int32_t plen, void *ctxt)
658{ 690{
@@ -680,6 +712,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
680 } 712 }
681} 713}
682 714
715/* ARGSUSED */
683void 716void
684input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) 717input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
685{ 718{
@@ -709,6 +742,7 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
709 /* Server will be returning a failed packet after this one */ 742 /* Server will be returning a failed packet after this one */
710} 743}
711 744
745/* ARGSUSED */
712void 746void
713input_gssapi_error(int type, u_int32_t plen, void *ctxt) 747input_gssapi_error(int type, u_int32_t plen, void *ctxt)
714{ 748{
@@ -773,9 +807,11 @@ userauth_passwd(Authctxt *authctxt)
773 807
774 return 1; 808 return 1;
775} 809}
810
776/* 811/*
777 * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST 812 * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST
778 */ 813 */
814/* ARGSUSED */
779void 815void
780input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) 816input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
781{ 817{
@@ -840,6 +876,209 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
840 &input_userauth_passwd_changereq); 876 &input_userauth_passwd_changereq);
841} 877}
842 878
879#ifdef JPAKE
880static char *
881pw_encrypt(const char *password, const char *crypt_scheme, const char *salt)
882{
883 /* OpenBSD crypt(3) handles all of these */
884 if (strcmp(crypt_scheme, "crypt") == 0 ||
885 strcmp(crypt_scheme, "bcrypt") == 0 ||
886 strcmp(crypt_scheme, "md5crypt") == 0 ||
887 strcmp(crypt_scheme, "crypt-extended") == 0)
888 return xstrdup(crypt(password, salt));
889 error("%s: unsupported password encryption scheme \"%.100s\"",
890 __func__, crypt_scheme);
891 return NULL;
892}
893
894static BIGNUM *
895jpake_password_to_secret(Authctxt *authctxt, const char *crypt_scheme,
896 const char *salt)
897{
898 char prompt[256], *password, *crypted;
899 u_char *secret;
900 u_int secret_len;
901 BIGNUM *ret;
902
903 snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password (JPAKE): ",
904 authctxt->server_user, authctxt->host);
905 password = read_passphrase(prompt, 0);
906
907 if ((crypted = pw_encrypt(password, crypt_scheme, salt)) == NULL) {
908 logit("Disabling %s authentication", authctxt->method->name);
909 authctxt->method->enabled = NULL;
910 /* Continue with an empty password to fail gracefully */
911 crypted = xstrdup("");
912 }
913
914#ifdef JPAKE_DEBUG
915 debug3("%s: salt = %s", __func__, salt);
916 debug3("%s: scheme = %s", __func__, crypt_scheme);
917 debug3("%s: crypted = %s", __func__, crypted);
918#endif
919
920 if (hash_buffer(crypted, strlen(crypted), EVP_sha256(),
921 &secret, &secret_len) != 0)
922 fatal("%s: hash_buffer", __func__);
923
924 bzero(password, strlen(password));
925 bzero(crypted, strlen(crypted));
926 xfree(password);
927 xfree(crypted);
928
929 if ((ret = BN_bin2bn(secret, secret_len, NULL)) == NULL)
930 fatal("%s: BN_bin2bn (secret)", __func__);
931 bzero(secret, secret_len);
932 xfree(secret);
933
934 return ret;
935}
936
937/* ARGSUSED */
938void
939input_userauth_jpake_server_step1(int type, u_int32_t seq, void *ctxt)
940{
941 Authctxt *authctxt = ctxt;
942 struct jpake_ctx *pctx = authctxt->methoddata;
943 u_char *x3_proof, *x4_proof, *x2_s_proof;
944 u_int x3_proof_len, x4_proof_len, x2_s_proof_len;
945 char *crypt_scheme, *salt;
946
947 /* Disable this message */
948 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1, NULL);
949
950 if ((pctx->g_x3 = BN_new()) == NULL ||
951 (pctx->g_x4 = BN_new()) == NULL)
952 fatal("%s: BN_new", __func__);
953
954 /* Fetch step 1 values */
955 crypt_scheme = packet_get_string(NULL);
956 salt = packet_get_string(NULL);
957 pctx->server_id = packet_get_string(&pctx->server_id_len);
958 packet_get_bignum2(pctx->g_x3);
959 packet_get_bignum2(pctx->g_x4);
960 x3_proof = packet_get_string(&x3_proof_len);
961 x4_proof = packet_get_string(&x4_proof_len);
962 packet_check_eom();
963
964 JPAKE_DEBUG_CTX((pctx, "step 1 received in %s", __func__));
965
966 /* Obtain password and derive secret */
967 pctx->s = jpake_password_to_secret(authctxt, crypt_scheme, salt);
968 bzero(crypt_scheme, strlen(crypt_scheme));
969 bzero(salt, strlen(salt));
970 xfree(crypt_scheme);
971 xfree(salt);
972 JPAKE_DEBUG_BN((pctx->s, "%s: s = ", __func__));
973
974 /* Calculate step 2 values */
975 jpake_step2(pctx->grp, pctx->s, pctx->g_x1,
976 pctx->g_x3, pctx->g_x4, pctx->x2,
977 pctx->server_id, pctx->server_id_len,
978 pctx->client_id, pctx->client_id_len,
979 x3_proof, x3_proof_len,
980 x4_proof, x4_proof_len,
981 &pctx->a,
982 &x2_s_proof, &x2_s_proof_len);
983
984 bzero(x3_proof, x3_proof_len);
985 bzero(x4_proof, x4_proof_len);
986 xfree(x3_proof);
987 xfree(x4_proof);
988
989 JPAKE_DEBUG_CTX((pctx, "step 2 sending in %s", __func__));
990
991 /* Send values for step 2 */
992 packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2);
993 packet_put_bignum2(pctx->a);
994 packet_put_string(x2_s_proof, x2_s_proof_len);
995 packet_send();
996
997 bzero(x2_s_proof, x2_s_proof_len);
998 xfree(x2_s_proof);
999
1000 /* Expect step 2 packet from peer */
1001 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2,
1002 input_userauth_jpake_server_step2);
1003}
1004
1005/* ARGSUSED */
1006void
1007input_userauth_jpake_server_step2(int type, u_int32_t seq, void *ctxt)
1008{
1009 Authctxt *authctxt = ctxt;
1010 struct jpake_ctx *pctx = authctxt->methoddata;
1011 u_char *x4_s_proof;
1012 u_int x4_s_proof_len;
1013
1014 /* Disable this message */
1015 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2, NULL);
1016
1017 if ((pctx->b = BN_new()) == NULL)
1018 fatal("%s: BN_new", __func__);
1019
1020 /* Fetch step 2 values */
1021 packet_get_bignum2(pctx->b);
1022 x4_s_proof = packet_get_string(&x4_s_proof_len);
1023 packet_check_eom();
1024
1025 JPAKE_DEBUG_CTX((pctx, "step 2 received in %s", __func__));
1026
1027 /* Derive shared key and calculate confirmation hash */
1028 jpake_key_confirm(pctx->grp, pctx->s, pctx->b,
1029 pctx->x2, pctx->g_x1, pctx->g_x2, pctx->g_x3, pctx->g_x4,
1030 pctx->client_id, pctx->client_id_len,
1031 pctx->server_id, pctx->server_id_len,
1032 session_id2, session_id2_len,
1033 x4_s_proof, x4_s_proof_len,
1034 &pctx->k,
1035 &pctx->h_k_cid_sessid, &pctx->h_k_cid_sessid_len);
1036
1037 bzero(x4_s_proof, x4_s_proof_len);
1038 xfree(x4_s_proof);
1039
1040 JPAKE_DEBUG_CTX((pctx, "confirm sending in %s", __func__));
1041
1042 /* Send key confirmation proof */
1043 packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM);
1044 packet_put_string(pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len);
1045 packet_send();
1046
1047 /* Expect confirmation from peer */
1048 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM,
1049 input_userauth_jpake_server_confirm);
1050}
1051
1052/* ARGSUSED */
1053void
1054input_userauth_jpake_server_confirm(int type, u_int32_t seq, void *ctxt)
1055{
1056 Authctxt *authctxt = ctxt;
1057 struct jpake_ctx *pctx = authctxt->methoddata;
1058
1059 /* Disable this message */
1060 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM, NULL);
1061
1062 pctx->h_k_sid_sessid = packet_get_string(&pctx->h_k_sid_sessid_len);
1063 packet_check_eom();
1064
1065 JPAKE_DEBUG_CTX((pctx, "confirm received in %s", __func__));
1066
1067 /* Verify expected confirmation hash */
1068 if (jpake_check_confirm(pctx->k,
1069 pctx->server_id, pctx->server_id_len,
1070 session_id2, session_id2_len,
1071 pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len) == 1)
1072 debug("%s: %s success", __func__, authctxt->method->name);
1073 else {
1074 debug("%s: confirmation mismatch", __func__);
1075 /* XXX stash this so if auth succeeds then we can warn/kill */
1076 }
1077
1078 userauth_jpake_cleanup(authctxt);
1079}
1080#endif /* JPAKE */
1081
843static int 1082static int
844identity_sign(Identity *id, u_char **sigp, u_int *lenp, 1083identity_sign(Identity *id, u_char **sigp, u_int *lenp,
845 u_char *data, u_int datalen) 1084 u_char *data, u_int datalen)
@@ -1414,6 +1653,76 @@ userauth_hostbased(Authctxt *authctxt)
1414 return 1; 1653 return 1;
1415} 1654}
1416 1655
1656#ifdef JPAKE
1657int
1658userauth_jpake(Authctxt *authctxt)
1659{
1660 struct jpake_ctx *pctx;
1661 u_char *x1_proof, *x2_proof;
1662 u_int x1_proof_len, x2_proof_len;
1663 static int attempt = 0; /* XXX share with userauth_password's? */
1664
1665 if (attempt++ >= options.number_of_password_prompts)
1666 return 0;
1667 if (attempt != 1)
1668 error("Permission denied, please try again.");
1669
1670 if (authctxt->methoddata != NULL)
1671 fatal("%s: authctxt->methoddata already set (%p)",
1672 __func__, authctxt->methoddata);
1673
1674 authctxt->methoddata = pctx = jpake_new();
1675
1676 /*
1677 * Send request immediately, to get the protocol going while
1678 * we do the initial computations.
1679 */
1680 packet_start(SSH2_MSG_USERAUTH_REQUEST);
1681 packet_put_cstring(authctxt->server_user);
1682 packet_put_cstring(authctxt->service);
1683 packet_put_cstring(authctxt->method->name);
1684 packet_send();
1685 packet_write_wait();
1686
1687 jpake_step1(pctx->grp,
1688 &pctx->client_id, &pctx->client_id_len,
1689 &pctx->x1, &pctx->x2, &pctx->g_x1, &pctx->g_x2,
1690 &x1_proof, &x1_proof_len,
1691 &x2_proof, &x2_proof_len);
1692
1693 JPAKE_DEBUG_CTX((pctx, "step 1 sending in %s", __func__));
1694
1695 packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1);
1696 packet_put_string(pctx->client_id, pctx->client_id_len);
1697 packet_put_bignum2(pctx->g_x1);
1698 packet_put_bignum2(pctx->g_x2);
1699 packet_put_string(x1_proof, x1_proof_len);
1700 packet_put_string(x2_proof, x2_proof_len);
1701 packet_send();
1702
1703 bzero(x1_proof, x1_proof_len);
1704 bzero(x2_proof, x2_proof_len);
1705 xfree(x1_proof);
1706 xfree(x2_proof);
1707
1708 /* Expect step 1 packet from peer */
1709 dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1,
1710 input_userauth_jpake_server_step1);
1711
1712 return 1;
1713}
1714
1715void
1716userauth_jpake_cleanup(Authctxt *authctxt)
1717{
1718 debug3("%s: clean up", __func__);
1719 if (authctxt->methoddata != NULL) {
1720 jpake_free(authctxt->methoddata);
1721 authctxt->methoddata = NULL;
1722 }
1723}
1724#endif /* JPAKE */
1725
1417/* find auth method */ 1726/* find auth method */
1418 1727
1419/* 1728/*
@@ -1515,3 +1824,4 @@ authmethods_get(void)
1515 buffer_free(&b); 1824 buffer_free(&b);
1516 return list; 1825 return list;
1517} 1826}
1827