summaryrefslogtreecommitdiff
path: root/sshconnect2.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2019-02-11 09:44:42 +0000
committerDamien Miller <djm@mindrot.org>2019-02-11 20:48:16 +1100
commit5c68ea8da790d711e6dd5f4c30d089c54032c59a (patch)
tree954417129df7d64e39781ba826652b7988c1f48d /sshconnect2.c
parenta8c807f1956f81a92a758d3d0237d0ff06d0be5d (diff)
upstream: cleanup GSSAPI authentication context after completion of the
authmethod. Move function-static GSSAPI state to the client Authctxt structure. Make static a bunch of functions that aren't used outside this file. Based on patch from Markus Schmidt <markus@blueflash.cc>; ok markus@ OpenBSD-Commit-ID: 497fb792c0ddb4f1ba631b6eed526861f115dbe5
Diffstat (limited to 'sshconnect2.c')
-rw-r--r--sshconnect2.c155
1 files changed, 88 insertions, 67 deletions
diff --git a/sshconnect2.c b/sshconnect2.c
index 2aa7b9933..6d37e92f7 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect2.c,v 1.301 2019/01/21 10:38:54 djm Exp $ */ 1/* $OpenBSD: sshconnect2.c,v 1.302 2019/02/11 09:44:42 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 * Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -265,6 +265,11 @@ struct cauthctxt {
265 struct cauthmethod *method; 265 struct cauthmethod *method;
266 sig_atomic_t success; 266 sig_atomic_t success;
267 char *authlist; 267 char *authlist;
268#ifdef GSSAPI
269 /* gssapi */
270 gss_OID_set gss_supported_mechs;
271 u_int mech_tried;
272#endif
268 /* pubkey */ 273 /* pubkey */
269 struct idlist keys; 274 struct idlist keys;
270 int agent_fd; 275 int agent_fd;
@@ -289,37 +294,36 @@ struct cauthmethod {
289 int *batch_flag; /* flag in option struct that disables method */ 294 int *batch_flag; /* flag in option struct that disables method */
290}; 295};
291 296
292int input_userauth_service_accept(int, u_int32_t, struct ssh *); 297static int input_userauth_service_accept(int, u_int32_t, struct ssh *);
293int input_userauth_ext_info(int, u_int32_t, struct ssh *); 298static int input_userauth_ext_info(int, u_int32_t, struct ssh *);
294int input_userauth_success(int, u_int32_t, struct ssh *); 299static int input_userauth_success(int, u_int32_t, struct ssh *);
295int input_userauth_success_unexpected(int, u_int32_t, struct ssh *); 300static int input_userauth_failure(int, u_int32_t, struct ssh *);
296int input_userauth_failure(int, u_int32_t, struct ssh *); 301static int input_userauth_banner(int, u_int32_t, struct ssh *);
297int input_userauth_banner(int, u_int32_t, struct ssh *); 302static int input_userauth_error(int, u_int32_t, struct ssh *);
298int input_userauth_error(int, u_int32_t, struct ssh *); 303static int input_userauth_info_req(int, u_int32_t, struct ssh *);
299int input_userauth_info_req(int, u_int32_t, struct ssh *); 304static int input_userauth_pk_ok(int, u_int32_t, struct ssh *);
300int input_userauth_pk_ok(int, u_int32_t, struct ssh *); 305static int input_userauth_passwd_changereq(int, u_int32_t, struct ssh *);
301int input_userauth_passwd_changereq(int, u_int32_t, struct ssh *); 306
302 307static int userauth_none(struct ssh *);
303int userauth_none(struct ssh *); 308static int userauth_pubkey(struct ssh *);
304int userauth_pubkey(struct ssh *); 309static void userauth_pubkey_cleanup(struct ssh *);
305int userauth_passwd(struct ssh *); 310static int userauth_passwd(struct ssh *);
306int userauth_kbdint(struct ssh *); 311static int userauth_kbdint(struct ssh *);
307int userauth_hostbased(struct ssh *); 312static int userauth_hostbased(struct ssh *);
308 313
309#ifdef GSSAPI 314#ifdef GSSAPI
310int userauth_gssapi(struct ssh *); 315static int userauth_gssapi(struct ssh *);
311int input_gssapi_response(int type, u_int32_t, struct ssh *); 316static void userauth_gssapi_cleanup(struct ssh *);
312int input_gssapi_token(int type, u_int32_t, struct ssh *); 317static int input_gssapi_response(int type, u_int32_t, struct ssh *);
313int input_gssapi_hash(int type, u_int32_t, struct ssh *); 318static int input_gssapi_token(int type, u_int32_t, struct ssh *);
314int input_gssapi_error(int, u_int32_t, struct ssh *); 319static int input_gssapi_error(int, u_int32_t, struct ssh *);
315int input_gssapi_errtok(int, u_int32_t, struct ssh *); 320static int input_gssapi_errtok(int, u_int32_t, struct ssh *);
316#endif 321#endif
317 322
318void userauth(struct ssh *, char *); 323void userauth(struct ssh *, char *);
319 324
320static int sign_and_send_pubkey(struct ssh *ssh, Identity *); 325static int sign_and_send_pubkey(struct ssh *ssh, Identity *);
321static void pubkey_prepare(Authctxt *); 326static void pubkey_prepare(Authctxt *);
322static void pubkey_cleanup(Authctxt *);
323static void pubkey_reset(Authctxt *); 327static void pubkey_reset(Authctxt *);
324static struct sshkey *load_identity_file(Identity *); 328static struct sshkey *load_identity_file(Identity *);
325 329
@@ -331,7 +335,7 @@ Authmethod authmethods[] = {
331#ifdef GSSAPI 335#ifdef GSSAPI
332 {"gssapi-with-mic", 336 {"gssapi-with-mic",
333 userauth_gssapi, 337 userauth_gssapi,
334 NULL, 338 userauth_gssapi_cleanup,
335 &options.gss_authentication, 339 &options.gss_authentication,
336 NULL}, 340 NULL},
337#endif 341#endif
@@ -342,7 +346,7 @@ Authmethod authmethods[] = {
342 NULL}, 346 NULL},
343 {"publickey", 347 {"publickey",
344 userauth_pubkey, 348 userauth_pubkey,
345 NULL, 349 userauth_pubkey_cleanup,
346 &options.pubkey_authentication, 350 &options.pubkey_authentication,
347 NULL}, 351 NULL},
348 {"keyboard-interactive", 352 {"keyboard-interactive",
@@ -390,6 +394,10 @@ ssh_userauth2(struct ssh *ssh, const char *local_user,
390 authctxt.info_req_seen = 0; 394 authctxt.info_req_seen = 0;
391 authctxt.attempt_kbdint = 0; 395 authctxt.attempt_kbdint = 0;
392 authctxt.attempt_passwd = 0; 396 authctxt.attempt_passwd = 0;
397#if GSSAPI
398 authctxt.gss_supported_mechs = NULL;
399 authctxt.mech_tried = 0;
400#endif
393 authctxt.agent_fd = -1; 401 authctxt.agent_fd = -1;
394 pubkey_prepare(&authctxt); 402 pubkey_prepare(&authctxt);
395 if (authctxt.method == NULL) { 403 if (authctxt.method == NULL) {
@@ -409,7 +417,6 @@ ssh_userauth2(struct ssh *ssh, const char *local_user,
409 ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt.success); /* loop until success */ 417 ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt.success); /* loop until success */
410 ssh->authctxt = NULL; 418 ssh->authctxt = NULL;
411 419
412 pubkey_cleanup(&authctxt);
413 ssh_dispatch_range(ssh, SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL); 420 ssh_dispatch_range(ssh, SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL);
414 421
415 if (!authctxt.success) 422 if (!authctxt.success)
@@ -418,7 +425,7 @@ ssh_userauth2(struct ssh *ssh, const char *local_user,
418} 425}
419 426
420/* ARGSUSED */ 427/* ARGSUSED */
421int 428static int
422input_userauth_service_accept(int type, u_int32_t seq, struct ssh *ssh) 429input_userauth_service_accept(int type, u_int32_t seq, struct ssh *ssh)
423{ 430{
424 int r; 431 int r;
@@ -450,7 +457,7 @@ input_userauth_service_accept(int type, u_int32_t seq, struct ssh *ssh)
450} 457}
451 458
452/* ARGSUSED */ 459/* ARGSUSED */
453int 460static int
454input_userauth_ext_info(int type, u_int32_t seqnr, struct ssh *ssh) 461input_userauth_ext_info(int type, u_int32_t seqnr, struct ssh *ssh)
455{ 462{
456 return kex_input_ext_info(type, seqnr, ssh); 463 return kex_input_ext_info(type, seqnr, ssh);
@@ -495,7 +502,7 @@ userauth(struct ssh *ssh, char *authlist)
495} 502}
496 503
497/* ARGSUSED */ 504/* ARGSUSED */
498int 505static int
499input_userauth_error(int type, u_int32_t seq, struct ssh *ssh) 506input_userauth_error(int type, u_int32_t seq, struct ssh *ssh)
500{ 507{
501 fatal("%s: bad message during authentication: type %d", __func__, type); 508 fatal("%s: bad message during authentication: type %d", __func__, type);
@@ -503,7 +510,7 @@ input_userauth_error(int type, u_int32_t seq, struct ssh *ssh)
503} 510}
504 511
505/* ARGSUSED */ 512/* ARGSUSED */
506int 513static int
507input_userauth_banner(int type, u_int32_t seq, struct ssh *ssh) 514input_userauth_banner(int type, u_int32_t seq, struct ssh *ssh)
508{ 515{
509 char *msg = NULL; 516 char *msg = NULL;
@@ -523,7 +530,7 @@ input_userauth_banner(int type, u_int32_t seq, struct ssh *ssh)
523} 530}
524 531
525/* ARGSUSED */ 532/* ARGSUSED */
526int 533static int
527input_userauth_success(int type, u_int32_t seq, struct ssh *ssh) 534input_userauth_success(int type, u_int32_t seq, struct ssh *ssh)
528{ 535{
529 Authctxt *authctxt = ssh->authctxt; 536 Authctxt *authctxt = ssh->authctxt;
@@ -540,7 +547,8 @@ input_userauth_success(int type, u_int32_t seq, struct ssh *ssh)
540 return 0; 547 return 0;
541} 548}
542 549
543int 550#if 0
551static int
544input_userauth_success_unexpected(int type, u_int32_t seq, struct ssh *ssh) 552input_userauth_success_unexpected(int type, u_int32_t seq, struct ssh *ssh)
545{ 553{
546 Authctxt *authctxt = ssh->authctxt; 554 Authctxt *authctxt = ssh->authctxt;
@@ -552,9 +560,10 @@ input_userauth_success_unexpected(int type, u_int32_t seq, struct ssh *ssh)
552 authctxt->method->name); 560 authctxt->method->name);
553 return 0; 561 return 0;
554} 562}
563#endif
555 564
556/* ARGSUSED */ 565/* ARGSUSED */
557int 566static int
558input_userauth_failure(int type, u_int32_t seq, struct ssh *ssh) 567input_userauth_failure(int type, u_int32_t seq, struct ssh *ssh)
559{ 568{
560 Authctxt *authctxt = ssh->authctxt; 569 Authctxt *authctxt = ssh->authctxt;
@@ -609,7 +618,7 @@ format_identity(Identity *id)
609} 618}
610 619
611/* ARGSUSED */ 620/* ARGSUSED */
612int 621static int
613input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) 622input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh)
614{ 623{
615 Authctxt *authctxt = ssh->authctxt; 624 Authctxt *authctxt = ssh->authctxt;
@@ -680,35 +689,36 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh)
680} 689}
681 690
682#ifdef GSSAPI 691#ifdef GSSAPI
683int 692static int
684userauth_gssapi(struct ssh *ssh) 693userauth_gssapi(struct ssh *ssh)
685{ 694{
686 Authctxt *authctxt = (Authctxt *)ssh->authctxt; 695 Authctxt *authctxt = (Authctxt *)ssh->authctxt;
687 Gssctxt *gssctxt = NULL; 696 Gssctxt *gssctxt = NULL;
688 static gss_OID_set gss_supported = NULL;
689 static u_int mech = 0;
690 OM_uint32 min; 697 OM_uint32 min;
691 int r, ok = 0; 698 int r, ok = 0;
699 gss_OID mech = NULL;
692 700
693 /* Try one GSSAPI method at a time, rather than sending them all at 701 /* Try one GSSAPI method at a time, rather than sending them all at
694 * once. */ 702 * once. */
695 703
696 if (gss_supported == NULL) 704 if (authctxt->gss_supported_mechs == NULL)
697 gss_indicate_mechs(&min, &gss_supported); 705 gss_indicate_mechs(&min, &authctxt->gss_supported_mechs);
698 706
699 /* Check to see if the mechanism is usable before we offer it */ 707 /* Check to see whether the mechanism is usable before we offer it */
700 while (mech < gss_supported->count && !ok) { 708 while (authctxt->mech_tried < authctxt->gss_supported_mechs->count &&
709 !ok) {
710 mech = &authctxt->gss_supported_mechs->
711 elements[authctxt->mech_tried];
701 /* My DER encoding requires length<128 */ 712 /* My DER encoding requires length<128 */
702 if (gss_supported->elements[mech].length < 128 && 713 if (mech->length < 128 && ssh_gssapi_check_mechanism(&gssctxt,
703 ssh_gssapi_check_mechanism(&gssctxt, 714 mech, authctxt->host)) {
704 &gss_supported->elements[mech], authctxt->host)) {
705 ok = 1; /* Mechanism works */ 715 ok = 1; /* Mechanism works */
706 } else { 716 } else {
707 mech++; 717 authctxt->mech_tried++;
708 } 718 }
709 } 719 }
710 720
711 if (!ok) 721 if (!ok || mech == NULL)
712 return 0; 722 return 0;
713 723
714 authctxt->methoddata=(void *)gssctxt; 724 authctxt->methoddata=(void *)gssctxt;
@@ -718,14 +728,10 @@ userauth_gssapi(struct ssh *ssh)
718 (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || 728 (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
719 (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || 729 (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 ||
720 (r = sshpkt_put_u32(ssh, 1)) != 0 || 730 (r = sshpkt_put_u32(ssh, 1)) != 0 ||
721 (r = sshpkt_put_u32(ssh, 731 (r = sshpkt_put_u32(ssh, (mech->length) + 2)) != 0 ||
722 (gss_supported->elements[mech].length) + 2)) != 0 ||
723 (r = sshpkt_put_u8(ssh, SSH_GSS_OIDTYPE)) != 0 || 732 (r = sshpkt_put_u8(ssh, SSH_GSS_OIDTYPE)) != 0 ||
724 (r = sshpkt_put_u8(ssh, 733 (r = sshpkt_put_u8(ssh, mech->length)) != 0 ||
725 gss_supported->elements[mech].length)) != 0 || 734 (r = sshpkt_put(ssh, mech->elements, mech->length)) != 0 ||
726 (r = sshpkt_put(ssh,
727 gss_supported->elements[mech].elements,
728 gss_supported->elements[mech].length)) != 0 ||
729 (r = sshpkt_send(ssh)) != 0) 735 (r = sshpkt_send(ssh)) != 0)
730 fatal("%s: %s", __func__, ssh_err(r)); 736 fatal("%s: %s", __func__, ssh_err(r));
731 737
@@ -734,11 +740,24 @@ userauth_gssapi(struct ssh *ssh)
734 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error); 740 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error);
735 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok); 741 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok);
736 742
737 mech++; /* Move along to next candidate */ 743 authctxt->mech_tried++; /* Move along to next candidate */
738 744
739 return 1; 745 return 1;
740} 746}
741 747
748static void
749userauth_gssapi_cleanup(struct ssh *ssh)
750{
751 Authctxt *authctxt = (Authctxt *)ssh->authctxt;
752 Gssctxt *gssctxt = (Gssctxt *)authctxt->methoddata;
753
754 ssh_gssapi_delete_ctx(&gssctxt);
755 authctxt->methoddata = NULL;
756
757 free(authctxt->gss_supported_mechs);
758 authctxt->gss_supported_mechs = NULL;
759}
760
742static OM_uint32 761static OM_uint32
743process_gssapi_token(struct ssh *ssh, gss_buffer_t recv_tok) 762process_gssapi_token(struct ssh *ssh, gss_buffer_t recv_tok)
744{ 763{
@@ -806,7 +825,7 @@ process_gssapi_token(struct ssh *ssh, gss_buffer_t recv_tok)
806} 825}
807 826
808/* ARGSUSED */ 827/* ARGSUSED */
809int 828static int
810input_gssapi_response(int type, u_int32_t plen, struct ssh *ssh) 829input_gssapi_response(int type, u_int32_t plen, struct ssh *ssh)
811{ 830{
812 Authctxt *authctxt = ssh->authctxt; 831 Authctxt *authctxt = ssh->authctxt;
@@ -851,7 +870,7 @@ input_gssapi_response(int type, u_int32_t plen, struct ssh *ssh)
851} 870}
852 871
853/* ARGSUSED */ 872/* ARGSUSED */
854int 873static int
855input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh) 874input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh)
856{ 875{
857 Authctxt *authctxt = ssh->authctxt; 876 Authctxt *authctxt = ssh->authctxt;
@@ -884,7 +903,7 @@ input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh)
884} 903}
885 904
886/* ARGSUSED */ 905/* ARGSUSED */
887int 906static int
888input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh) 907input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh)
889{ 908{
890 Authctxt *authctxt = ssh->authctxt; 909 Authctxt *authctxt = ssh->authctxt;
@@ -919,7 +938,7 @@ input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh)
919} 938}
920 939
921/* ARGSUSED */ 940/* ARGSUSED */
922int 941static int
923input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) 942input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh)
924{ 943{
925 char *msg = NULL; 944 char *msg = NULL;
@@ -940,7 +959,7 @@ input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh)
940} 959}
941#endif /* GSSAPI */ 960#endif /* GSSAPI */
942 961
943int 962static int
944userauth_none(struct ssh *ssh) 963userauth_none(struct ssh *ssh)
945{ 964{
946 Authctxt *authctxt = (Authctxt *)ssh->authctxt; 965 Authctxt *authctxt = (Authctxt *)ssh->authctxt;
@@ -956,7 +975,7 @@ userauth_none(struct ssh *ssh)
956 return 1; 975 return 1;
957} 976}
958 977
959int 978static int
960userauth_passwd(struct ssh *ssh) 979userauth_passwd(struct ssh *ssh)
961{ 980{
962 Authctxt *authctxt = (Authctxt *)ssh->authctxt; 981 Authctxt *authctxt = (Authctxt *)ssh->authctxt;
@@ -997,7 +1016,7 @@ userauth_passwd(struct ssh *ssh)
997 * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST 1016 * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST
998 */ 1017 */
999/* ARGSUSED */ 1018/* ARGSUSED */
1000int 1019static int
1001input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh) 1020input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh)
1002{ 1021{
1003 Authctxt *authctxt = ssh->authctxt; 1022 Authctxt *authctxt = ssh->authctxt;
@@ -1619,8 +1638,10 @@ pubkey_prepare(Authctxt *authctxt)
1619} 1638}
1620 1639
1621static void 1640static void
1622pubkey_cleanup(Authctxt *authctxt) 1641userauth_pubkey_cleanup(struct ssh *ssh)
1623{ 1642{
1643 Authctxt *authctxt = (Authctxt *)ssh->authctxt;
1644
1624 Identity *id; 1645 Identity *id;
1625 1646
1626 if (authctxt->agent_fd != -1) { 1647 if (authctxt->agent_fd != -1) {
@@ -1659,7 +1680,7 @@ try_identity(Identity *id)
1659 return 1; 1680 return 1;
1660} 1681}
1661 1682
1662int 1683static int
1663userauth_pubkey(struct ssh *ssh) 1684userauth_pubkey(struct ssh *ssh)
1664{ 1685{
1665 Authctxt *authctxt = (Authctxt *)ssh->authctxt; 1686 Authctxt *authctxt = (Authctxt *)ssh->authctxt;
@@ -1707,7 +1728,7 @@ userauth_pubkey(struct ssh *ssh)
1707/* 1728/*
1708 * Send userauth request message specifying keyboard-interactive method. 1729 * Send userauth request message specifying keyboard-interactive method.
1709 */ 1730 */
1710int 1731static int
1711userauth_kbdint(struct ssh *ssh) 1732userauth_kbdint(struct ssh *ssh)
1712{ 1733{
1713 Authctxt *authctxt = (Authctxt *)ssh->authctxt; 1734 Authctxt *authctxt = (Authctxt *)ssh->authctxt;
@@ -1740,7 +1761,7 @@ userauth_kbdint(struct ssh *ssh)
1740/* 1761/*
1741 * parse INFO_REQUEST, prompt user and send INFO_RESPONSE 1762 * parse INFO_REQUEST, prompt user and send INFO_RESPONSE
1742 */ 1763 */
1743int 1764static int
1744input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh) 1765input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh)
1745{ 1766{
1746 Authctxt *authctxt = ssh->authctxt; 1767 Authctxt *authctxt = ssh->authctxt;
@@ -1920,7 +1941,7 @@ ssh_keysign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp,
1920 return 0; 1941 return 0;
1921} 1942}
1922 1943
1923int 1944static int
1924userauth_hostbased(struct ssh *ssh) 1945userauth_hostbased(struct ssh *ssh)
1925{ 1946{
1926 Authctxt *authctxt = (Authctxt *)ssh->authctxt; 1947 Authctxt *authctxt = (Authctxt *)ssh->authctxt;