summaryrefslogtreecommitdiff
path: root/debian/patches/gssapi.patch
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2018-08-24 12:49:36 +0100
committerColin Watson <cjwatson@debian.org>2018-08-30 00:57:27 +0100
commit816386e17654ca36834bebbf351419e460fad8f6 (patch)
tree3dc79d831cb73bc25b92f5a4d18f8e328c0c570a /debian/patches/gssapi.patch
parent3e6f76c7039d3df22b1d0a3a5f30150efb09b69d (diff)
parent16a47fc4b04977a14f44dd433c8da1499fa80671 (diff)
New upstream release (7.8p1)
Closes: #907534
Diffstat (limited to 'debian/patches/gssapi.patch')
-rw-r--r--debian/patches/gssapi.patch565
1 files changed, 293 insertions, 272 deletions
diff --git a/debian/patches/gssapi.patch b/debian/patches/gssapi.patch
index d47b0a796..25edd5cbe 100644
--- a/debian/patches/gssapi.patch
+++ b/debian/patches/gssapi.patch
@@ -1,4 +1,4 @@
1From cb427e23bf78d65407c78d868c4ef525dbfaa68f Mon Sep 17 00:00:00 2001 1From e6c7c11ac2576ac62334616bd4408bf64140bba7 Mon Sep 17 00:00:00 2001
2From: Simon Wilkinson <simon@sxw.org.uk> 2From: Simon Wilkinson <simon@sxw.org.uk>
3Date: Sun, 9 Feb 2014 16:09:48 +0000 3Date: Sun, 9 Feb 2014 16:09:48 +0000
4Subject: GSSAPI key exchange support 4Subject: GSSAPI key exchange support
@@ -17,7 +17,7 @@ have it merged into the main openssh package rather than having separate
17security history. 17security history.
18 18
19Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1242 19Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1242
20Last-Updated: 2017-10-04 20Last-Updated: 2018-08-24
21 21
22Patch-Name: gssapi.patch 22Patch-Name: gssapi.patch
23--- 23---
@@ -25,23 +25,23 @@ Patch-Name: gssapi.patch
25 Makefile.in | 3 +- 25 Makefile.in | 3 +-
26 auth-krb5.c | 17 ++- 26 auth-krb5.c | 17 ++-
27 auth.c | 96 +------------- 27 auth.c | 96 +-------------
28 auth2-gss.c | 49 ++++++- 28 auth2-gss.c | 54 +++++++-
29 auth2.c | 2 + 29 auth2.c | 2 +
30 canohost.c | 93 +++++++++++++ 30 canohost.c | 93 +++++++++++++
31 canohost.h | 3 + 31 canohost.h | 3 +
32 clientloop.c | 15 ++- 32 clientloop.c | 15 ++-
33 config.h.in | 6 + 33 config.h.in | 6 +
34 configure.ac | 24 ++++ 34 configure.ac | 24 ++++
35 gss-genr.c | 275 +++++++++++++++++++++++++++++++++++++- 35 gss-genr.c | 277 +++++++++++++++++++++++++++++++++++++-
36 gss-serv-krb5.c | 85 +++++++++++- 36 gss-serv-krb5.c | 85 +++++++++++-
37 gss-serv.c | 184 ++++++++++++++++++++++++-- 37 gss-serv.c | 184 ++++++++++++++++++++++++--
38 kex.c | 19 +++ 38 kex.c | 19 +++
39 kex.h | 14 ++ 39 kex.h | 14 ++
40 kexgssc.c | 338 +++++++++++++++++++++++++++++++++++++++++++++++ 40 kexgssc.c | 338 +++++++++++++++++++++++++++++++++++++++++++++++
41 kexgsss.c | 295 +++++++++++++++++++++++++++++++++++++++++ 41 kexgsss.c | 295 +++++++++++++++++++++++++++++++++++++++++
42 monitor.c | 115 ++++++++++++++-- 42 monitor.c | 122 +++++++++++++++--
43 monitor.h | 3 + 43 monitor.h | 3 +
44 monitor_wrap.c | 47 ++++++- 44 monitor_wrap.c | 53 +++++++-
45 monitor_wrap.h | 4 +- 45 monitor_wrap.h | 4 +-
46 readconf.c | 43 ++++++ 46 readconf.c | 43 ++++++
47 readconf.h | 5 + 47 readconf.h | 5 +
@@ -50,13 +50,13 @@ Patch-Name: gssapi.patch
50 ssh-gss.h | 41 +++++- 50 ssh-gss.h | 41 +++++-
51 ssh_config | 2 + 51 ssh_config | 2 +
52 ssh_config.5 | 32 +++++ 52 ssh_config.5 | 32 +++++
53 sshconnect2.c | 131 +++++++++++++++++- 53 sshconnect2.c | 133 ++++++++++++++++++-
54 sshd.c | 112 +++++++++++++++- 54 sshd.c | 112 +++++++++++++++-
55 sshd_config | 2 + 55 sshd_config | 2 +
56 sshd_config.5 | 10 ++ 56 sshd_config.5 | 10 ++
57 sshkey.c | 3 +- 57 sshkey.c | 3 +-
58 sshkey.h | 1 + 58 sshkey.h | 1 +
59 35 files changed, 2063 insertions(+), 147 deletions(-) 59 35 files changed, 2087 insertions(+), 145 deletions(-)
60 create mode 100644 ChangeLog.gssapi 60 create mode 100644 ChangeLog.gssapi
61 create mode 100644 kexgssc.c 61 create mode 100644 kexgssc.c
62 create mode 100644 kexgsss.c 62 create mode 100644 kexgsss.c
@@ -181,7 +181,7 @@ index 000000000..f117a336a
181+ (from jbasney AT ncsa.uiuc.edu) 181+ (from jbasney AT ncsa.uiuc.edu)
182+ <gssapi-with-mic support is Bugzilla #1008> 182+ <gssapi-with-mic support is Bugzilla #1008>
183diff --git a/Makefile.in b/Makefile.in 183diff --git a/Makefile.in b/Makefile.in
184index 04e1c8e53..6f3f042b1 100644 184index 2385c62a8..6175c6063 100644
185--- a/Makefile.in 185--- a/Makefile.in
186+++ b/Makefile.in 186+++ b/Makefile.in
187@@ -100,6 +100,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ 187@@ -100,6 +100,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
@@ -193,7 +193,7 @@ index 04e1c8e53..6f3f042b1 100644
193 193
194 SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ 194 SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
195@@ -113,7 +114,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \ 195@@ -113,7 +114,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \
196 auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ 196 auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \
197 auth2-none.o auth2-passwd.o auth2-pubkey.o \ 197 auth2-none.o auth2-passwd.o auth2-pubkey.o \
198 monitor.o monitor_wrap.o auth-krb5.o \ 198 monitor.o monitor_wrap.o auth-krb5.o \
199- auth2-gss.o gss-serv.o gss-serv-krb5.o \ 199- auth2-gss.o gss-serv.o gss-serv-krb5.o \
@@ -202,7 +202,7 @@ index 04e1c8e53..6f3f042b1 100644
202 sftp-server.o sftp-common.o \ 202 sftp-server.o sftp-common.o \
203 sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ 203 sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
204diff --git a/auth-krb5.c b/auth-krb5.c 204diff --git a/auth-krb5.c b/auth-krb5.c
205index a5a81ed2e..38e7fee21 100644 205index 3096f1c8e..204752e1b 100644
206--- a/auth-krb5.c 206--- a/auth-krb5.c
207+++ b/auth-krb5.c 207+++ b/auth-krb5.c
208@@ -182,8 +182,13 @@ auth_krb5_password(Authctxt *authctxt, const char *password) 208@@ -182,8 +182,13 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
@@ -253,10 +253,10 @@ index a5a81ed2e..38e7fee21 100644
253 return (krb5_cc_resolve(ctx, ccname, ccache)); 253 return (krb5_cc_resolve(ctx, ccname, ccache));
254 } 254 }
255diff --git a/auth.c b/auth.c 255diff --git a/auth.c b/auth.c
256index 63366768a..76d586e31 100644 256index 9a3bc96f1..80eb78c48 100644
257--- a/auth.c 257--- a/auth.c
258+++ b/auth.c 258+++ b/auth.c
259@@ -396,7 +396,8 @@ auth_root_allowed(struct ssh *ssh, const char *method) 259@@ -395,7 +395,8 @@ auth_root_allowed(struct ssh *ssh, const char *method)
260 case PERMIT_NO_PASSWD: 260 case PERMIT_NO_PASSWD:
261 if (strcmp(method, "publickey") == 0 || 261 if (strcmp(method, "publickey") == 0 ||
262 strcmp(method, "hostbased") == 0 || 262 strcmp(method, "hostbased") == 0 ||
@@ -266,7 +266,7 @@ index 63366768a..76d586e31 100644
266 return 1; 266 return 1;
267 break; 267 break;
268 case PERMIT_FORCED_ONLY: 268 case PERMIT_FORCED_ONLY:
269@@ -728,99 +729,6 @@ fakepw(void) 269@@ -733,99 +734,6 @@ fakepw(void)
270 return (&fake); 270 return (&fake);
271 } 271 }
272 272
@@ -367,11 +367,11 @@ index 63366768a..76d586e31 100644
367 * Return the canonical name of the host in the other side of the current 367 * Return the canonical name of the host in the other side of the current
368 * connection. The host name is cached, so it is efficient to call this 368 * connection. The host name is cached, so it is efficient to call this
369diff --git a/auth2-gss.c b/auth2-gss.c 369diff --git a/auth2-gss.c b/auth2-gss.c
370index 589283b72..fd411d3a7 100644 370index 9351e0428..1f12bb113 100644
371--- a/auth2-gss.c 371--- a/auth2-gss.c
372+++ b/auth2-gss.c 372+++ b/auth2-gss.c
373@@ -1,7 +1,7 @@ 373@@ -1,7 +1,7 @@
374 /* $OpenBSD: auth2-gss.c,v 1.26 2017/06/24 06:34:38 djm Exp $ */ 374 /* $OpenBSD: auth2-gss.c,v 1.29 2018/07/31 03:10:27 djm Exp $ */
375 375
376 /* 376 /*
377- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. 377- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -379,7 +379,7 @@ index 589283b72..fd411d3a7 100644
379 * 379 *
380 * Redistribution and use in source and binary forms, with or without 380 * Redistribution and use in source and binary forms, with or without
381 * modification, are permitted provided that the following conditions 381 * modification, are permitted provided that the following conditions
382@@ -53,6 +53,41 @@ static int input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh); 382@@ -54,6 +54,46 @@ static int input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh);
383 static int input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh); 383 static int input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh);
384 static int input_gssapi_errtok(int, u_int32_t, struct ssh *); 384 static int input_gssapi_errtok(int, u_int32_t, struct ssh *);
385 385
@@ -390,21 +390,26 @@ index 589283b72..fd411d3a7 100644
390+userauth_gsskeyex(struct ssh *ssh) 390+userauth_gsskeyex(struct ssh *ssh)
391+{ 391+{
392+ Authctxt *authctxt = ssh->authctxt; 392+ Authctxt *authctxt = ssh->authctxt;
393+ int authenticated = 0; 393+ int r, authenticated = 0;
394+ Buffer b; 394+ struct sshbuf *b;
395+ gss_buffer_desc mic, gssbuf; 395+ gss_buffer_desc mic, gssbuf;
396+ u_int len; 396+ u_char *p;
397+ 397+ size_t len;
398+ mic.value = packet_get_string(&len); 398+
399+ if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 ||
400+ (r = sshpkt_get_end(ssh)) != 0)
401+ fatal("%s: %s", __func__, ssh_err(r));
402+ if ((b = sshbuf_new()) == NULL)
403+ fatal("%s: sshbuf_new failed", __func__);
404+ mic.value = p;
399+ mic.length = len; 405+ mic.length = len;
400+ 406+
401+ packet_check_eom(); 407+ ssh_gssapi_buildmic(b, authctxt->user, authctxt->service,
402+
403+ ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service,
404+ "gssapi-keyex"); 408+ "gssapi-keyex");
405+ 409+
406+ gssbuf.value = buffer_ptr(&b); 410+ if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL)
407+ gssbuf.length = buffer_len(&b); 411+ fatal("%s: sshbuf_mutable_ptr failed", __func__);
412+ gssbuf.length = sshbuf_len(b);
408+ 413+
409+ /* gss_kex_context is NULL with privsep, so we can't check it here */ 414+ /* gss_kex_context is NULL with privsep, so we can't check it here */
410+ if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, 415+ if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context,
@@ -412,7 +417,7 @@ index 589283b72..fd411d3a7 100644
412+ authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, 417+ authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user,
413+ authctxt->pw)); 418+ authctxt->pw));
414+ 419+
415+ buffer_free(&b); 420+ sshbuf_free(b);
416+ free(mic.value); 421+ free(mic.value);
417+ 422+
418+ return (authenticated); 423+ return (authenticated);
@@ -421,9 +426,9 @@ index 589283b72..fd411d3a7 100644
421 /* 426 /*
422 * We only support those mechanisms that we know about (ie ones that we know 427 * We only support those mechanisms that we know about (ie ones that we know
423 * how to check local user kuserok and the like) 428 * how to check local user kuserok and the like)
424@@ -240,7 +275,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) 429@@ -260,7 +300,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh)
425 430 if ((r = sshpkt_get_end(ssh)) != 0)
426 packet_check_eom(); 431 fatal("%s: %s", __func__, ssh_err(r));
427 432
428- authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); 433- authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
429+ authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, 434+ authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user,
@@ -431,8 +436,8 @@ index 589283b72..fd411d3a7 100644
431 436
432 if ((!use_privsep || mm_is_monitor()) && 437 if ((!use_privsep || mm_is_monitor()) &&
433 (displayname = ssh_gssapi_displayname()) != NULL) 438 (displayname = ssh_gssapi_displayname()) != NULL)
434@@ -281,7 +317,8 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) 439@@ -306,7 +347,8 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
435 gssbuf.length = buffer_len(&b); 440 gssbuf.length = sshbuf_len(b);
436 441
437 if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) 442 if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))))
438- authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); 443- authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
@@ -441,7 +446,7 @@ index 589283b72..fd411d3a7 100644
441 else 446 else
442 logit("GSSAPI MIC check failed"); 447 logit("GSSAPI MIC check failed");
443 448
444@@ -301,6 +338,12 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) 449@@ -326,6 +368,12 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
445 return 0; 450 return 0;
446 } 451 }
447 452
@@ -455,10 +460,10 @@ index 589283b72..fd411d3a7 100644
455 "gssapi-with-mic", 460 "gssapi-with-mic",
456 userauth_gssapi, 461 userauth_gssapi,
457diff --git a/auth2.c b/auth2.c 462diff --git a/auth2.c b/auth2.c
458index e0034229a..c34f58c45 100644 463index ab8795895..96efe164c 100644
459--- a/auth2.c 464--- a/auth2.c
460+++ b/auth2.c 465+++ b/auth2.c
461@@ -72,6 +72,7 @@ extern Authmethod method_passwd; 466@@ -74,6 +74,7 @@ extern Authmethod method_passwd;
462 extern Authmethod method_kbdint; 467 extern Authmethod method_kbdint;
463 extern Authmethod method_hostbased; 468 extern Authmethod method_hostbased;
464 #ifdef GSSAPI 469 #ifdef GSSAPI
@@ -466,7 +471,7 @@ index e0034229a..c34f58c45 100644
466 extern Authmethod method_gssapi; 471 extern Authmethod method_gssapi;
467 #endif 472 #endif
468 473
469@@ -79,6 +80,7 @@ Authmethod *authmethods[] = { 474@@ -81,6 +82,7 @@ Authmethod *authmethods[] = {
470 &method_none, 475 &method_none,
471 &method_pubkey, 476 &method_pubkey,
472 #ifdef GSSAPI 477 #ifdef GSSAPI
@@ -593,7 +598,7 @@ index 26d62855a..0cadc9f18 100644
593 int get_peer_port(int); 598 int get_peer_port(int);
594 char *get_local_ipaddr(int); 599 char *get_local_ipaddr(int);
595diff --git a/clientloop.c b/clientloop.c 600diff --git a/clientloop.c b/clientloop.c
596index 7bcf22e38..ef803e985 100644 601index ad35cb7ba..e69c5141f 100644
597--- a/clientloop.c 602--- a/clientloop.c
598+++ b/clientloop.c 603+++ b/clientloop.c
599@@ -112,6 +112,10 @@ 604@@ -112,6 +112,10 @@
@@ -607,7 +612,7 @@ index 7bcf22e38..ef803e985 100644
607 /* import options */ 612 /* import options */
608 extern Options options; 613 extern Options options;
609 614
610@@ -1335,9 +1339,18 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, 615@@ -1357,9 +1361,18 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
611 break; 616 break;
612 617
613 /* Do channel operations unless rekeying in progress. */ 618 /* Do channel operations unless rekeying in progress. */
@@ -628,10 +633,10 @@ index 7bcf22e38..ef803e985 100644
628 client_process_net_input(readset); 633 client_process_net_input(readset);
629 634
630diff --git a/config.h.in b/config.h.in 635diff --git a/config.h.in b/config.h.in
631index 572087407..4c9545c78 100644 636index 7940b4c86..93295da07 100644
632--- a/config.h.in 637--- a/config.h.in
633+++ b/config.h.in 638+++ b/config.h.in
634@@ -1746,6 +1746,9 @@ 639@@ -1749,6 +1749,9 @@
635 /* Use btmp to log bad logins */ 640 /* Use btmp to log bad logins */
636 #undef USE_BTMP 641 #undef USE_BTMP
637 642
@@ -641,7 +646,7 @@ index 572087407..4c9545c78 100644
641 /* Use libedit for sftp */ 646 /* Use libedit for sftp */
642 #undef USE_LIBEDIT 647 #undef USE_LIBEDIT
643 648
644@@ -1761,6 +1764,9 @@ 649@@ -1764,6 +1767,9 @@
645 /* Use PIPES instead of a socketpair() */ 650 /* Use PIPES instead of a socketpair() */
646 #undef USE_PIPES 651 #undef USE_PIPES
647 652
@@ -652,10 +657,10 @@ index 572087407..4c9545c78 100644
652 #undef USE_SOLARIS_PRIVS 657 #undef USE_SOLARIS_PRIVS
653 658
654diff --git a/configure.ac b/configure.ac 659diff --git a/configure.ac b/configure.ac
655index 663062bef..1cd5eab6c 100644 660index 83e530750..82428b241 100644
656--- a/configure.ac 661--- a/configure.ac
657+++ b/configure.ac 662+++ b/configure.ac
658@@ -664,6 +664,30 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) 663@@ -673,6 +673,30 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
659 [Use tunnel device compatibility to OpenBSD]) 664 [Use tunnel device compatibility to OpenBSD])
660 AC_DEFINE([SSH_TUN_PREPEND_AF], [1], 665 AC_DEFINE([SSH_TUN_PREPEND_AF], [1],
661 [Prepend the address family to IP tunnel traffic]) 666 [Prepend the address family to IP tunnel traffic])
@@ -687,11 +692,11 @@ index 663062bef..1cd5eab6c 100644
687 AC_CHECK_DECL([AU_IPv4], [], 692 AC_CHECK_DECL([AU_IPv4], [],
688 AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records]) 693 AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records])
689diff --git a/gss-genr.c b/gss-genr.c 694diff --git a/gss-genr.c b/gss-genr.c
690index 62559ed9e..0b3ae073c 100644 695index d56257b4a..285fc29a5 100644
691--- a/gss-genr.c 696--- a/gss-genr.c
692+++ b/gss-genr.c 697+++ b/gss-genr.c
693@@ -1,7 +1,7 @@ 698@@ -1,7 +1,7 @@
694 /* $OpenBSD: gss-genr.c,v 1.24 2016/09/12 01:22:38 deraadt Exp $ */ 699 /* $OpenBSD: gss-genr.c,v 1.26 2018/07/10 09:13:30 djm Exp $ */
695 700
696 /* 701 /*
697- * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. 702- * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
@@ -699,12 +704,11 @@ index 62559ed9e..0b3ae073c 100644
699 * 704 *
700 * Redistribution and use in source and binary forms, with or without 705 * Redistribution and use in source and binary forms, with or without
701 * modification, are permitted provided that the following conditions 706 * modification, are permitted provided that the following conditions
702@@ -40,12 +40,167 @@ 707@@ -41,12 +41,34 @@
703 #include "buffer.h" 708 #include "sshbuf.h"
704 #include "log.h" 709 #include "log.h"
705 #include "ssh2.h" 710 #include "ssh2.h"
706+#include "cipher.h" 711+#include "cipher.h"
707+#include "key.h"
708+#include "kex.h" 712+#include "kex.h"
709+#include <openssl/evp.h> 713+#include <openssl/evp.h>
710 714
@@ -732,6 +736,13 @@ index 62559ed9e..0b3ae073c 100644
732+ return (gss_enc2oid != NULL); 736+ return (gss_enc2oid != NULL);
733+} 737+}
734+ 738+
739 /* sshbuf_get for gss_buffer_desc */
740 int
741 ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g)
742@@ -62,6 +84,141 @@ ssh_gssapi_get_buffer_desc(struct sshbuf *b, gss_buffer_desc *g)
743 return 0;
744 }
745
735+/* 746+/*
736+ * Return a list of the gss-group1-sha1 mechanisms supported by this program 747+ * Return a list of the gss-group1-sha1 mechanisms supported by this program
737+ * 748+ *
@@ -754,9 +765,9 @@ index 62559ed9e..0b3ae073c 100644
754+char * 765+char *
755+ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check, 766+ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check,
756+ const char *host, const char *client) { 767+ const char *host, const char *client) {
757+ Buffer buf; 768+ struct sshbuf *buf;
758+ size_t i; 769+ size_t i;
759+ int oidpos, enclen; 770+ int r, oidpos, enclen;
760+ char *mechs, *encoded; 771+ char *mechs, *encoded;
761+ u_char digest[EVP_MAX_MD_SIZE]; 772+ u_char digest[EVP_MAX_MD_SIZE];
762+ char deroid[2]; 773+ char deroid[2];
@@ -772,7 +783,8 @@ index 62559ed9e..0b3ae073c 100644
772+ gss_enc2oid = xmalloc(sizeof(ssh_gss_kex_mapping) * 783+ gss_enc2oid = xmalloc(sizeof(ssh_gss_kex_mapping) *
773+ (gss_supported->count + 1)); 784+ (gss_supported->count + 1));
774+ 785+
775+ buffer_init(&buf); 786+ if ((buf = sshbuf_new()) == NULL)
787+ fatal("%s: sshbuf_new failed", __func__);
776+ 788+
777+ oidpos = 0; 789+ oidpos = 0;
778+ for (i = 0; i < gss_supported->count; i++) { 790+ for (i = 0; i < gss_supported->count; i++) {
@@ -793,20 +805,25 @@ index 62559ed9e..0b3ae073c 100644
793+ enclen = __b64_ntop(digest, EVP_MD_size(evp_md), 805+ enclen = __b64_ntop(digest, EVP_MD_size(evp_md),
794+ encoded, EVP_MD_size(evp_md) * 2); 806+ encoded, EVP_MD_size(evp_md) * 2);
795+ 807+
796+ if (oidpos != 0) 808+ if (oidpos != 0) {
797+ buffer_put_char(&buf, ','); 809+ if ((r = sshbuf_put_u8(buf, ',')) != 0)
798+ 810+ fatal("%s: buffer error: %s",
799+ buffer_append(&buf, KEX_GSS_GEX_SHA1_ID, 811+ __func__, ssh_err(r));
800+ sizeof(KEX_GSS_GEX_SHA1_ID) - 1); 812+ }
801+ buffer_append(&buf, encoded, enclen); 813+
802+ buffer_put_char(&buf, ','); 814+ if ((r = sshbuf_put(buf, KEX_GSS_GEX_SHA1_ID,
803+ buffer_append(&buf, KEX_GSS_GRP1_SHA1_ID, 815+ sizeof(KEX_GSS_GEX_SHA1_ID) - 1)) != 0 ||
804+ sizeof(KEX_GSS_GRP1_SHA1_ID) - 1); 816+ (r = sshbuf_put(buf, encoded, enclen)) != 0 ||
805+ buffer_append(&buf, encoded, enclen); 817+ (r = sshbuf_put_u8(buf, ',')) != 0 ||
806+ buffer_put_char(&buf, ','); 818+ (r = sshbuf_put(buf, KEX_GSS_GRP1_SHA1_ID,
807+ buffer_append(&buf, KEX_GSS_GRP14_SHA1_ID, 819+ sizeof(KEX_GSS_GRP1_SHA1_ID) - 1)) != 0 ||
808+ sizeof(KEX_GSS_GRP14_SHA1_ID) - 1); 820+ (r = sshbuf_put(buf, encoded, enclen)) != 0 ||
809+ buffer_append(&buf, encoded, enclen); 821+ (r = sshbuf_put_u8(buf, ',')) != 0 ||
822+ (r = sshbuf_put(buf, KEX_GSS_GRP14_SHA1_ID,
823+ sizeof(KEX_GSS_GRP14_SHA1_ID) - 1)) != 0 ||
824+ (r = sshbuf_put(buf, encoded, enclen)) != 0)
825+ fatal("%s: buffer error: %s",
826+ __func__, ssh_err(r));
810+ 827+
811+ gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]); 828+ gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]);
812+ gss_enc2oid[oidpos].encoded = encoded; 829+ gss_enc2oid[oidpos].encoded = encoded;
@@ -816,11 +833,8 @@ index 62559ed9e..0b3ae073c 100644
816+ gss_enc2oid[oidpos].oid = NULL; 833+ gss_enc2oid[oidpos].oid = NULL;
817+ gss_enc2oid[oidpos].encoded = NULL; 834+ gss_enc2oid[oidpos].encoded = NULL;
818+ 835+
819+ buffer_put_char(&buf, '\0'); 836+ if ((mechs = sshbuf_dup_string(buf)) == NULL)
820+ 837+ fatal("%s: sshbuf_dup_string failed", __func__);
821+ mechs = xmalloc(buffer_len(&buf));
822+ buffer_get(&buf, mechs, buffer_len(&buf));
823+ buffer_free(&buf);
824+ 838+
825+ if (strlen(mechs) == 0) { 839+ if (strlen(mechs) == 0) {
826+ free(mechs); 840+ free(mechs);
@@ -867,7 +881,7 @@ index 62559ed9e..0b3ae073c 100644
867 /* Check that the OID in a data stream matches that in the context */ 881 /* Check that the OID in a data stream matches that in the context */
868 int 882 int
869 ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) 883 ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len)
870@@ -198,7 +353,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, 884@@ -218,7 +375,7 @@ ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok,
871 } 885 }
872 886
873 ctx->major = gss_init_sec_context(&ctx->minor, 887 ctx->major = gss_init_sec_context(&ctx->minor,
@@ -876,7 +890,7 @@ index 62559ed9e..0b3ae073c 100644
876 GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, 890 GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag,
877 0, NULL, recv_tok, NULL, send_tok, flags, NULL); 891 0, NULL, recv_tok, NULL, send_tok, flags, NULL);
878 892
879@@ -227,9 +382,43 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) 893@@ -247,9 +404,43 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host)
880 return (ctx->major); 894 return (ctx->major);
881 } 895 }
882 896
@@ -920,7 +934,7 @@ index 62559ed9e..0b3ae073c 100644
920 if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context, 934 if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context,
921 GSS_C_QOP_DEFAULT, buffer, hash))) 935 GSS_C_QOP_DEFAULT, buffer, hash)))
922 ssh_gssapi_error(ctx); 936 ssh_gssapi_error(ctx);
923@@ -237,6 +426,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) 937@@ -257,6 +448,19 @@ ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash)
924 return (ctx->major); 938 return (ctx->major);
925 } 939 }
926 940
@@ -938,9 +952,9 @@ index 62559ed9e..0b3ae073c 100644
938+} 952+}
939+ 953+
940 void 954 void
941 ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service, 955 ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service,
942 const char *context) 956 const char *context)
943@@ -250,11 +452,16 @@ ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service, 957@@ -273,11 +477,16 @@ ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service,
944 } 958 }
945 959
946 int 960 int
@@ -958,7 +972,7 @@ index 62559ed9e..0b3ae073c 100644
958 972
959 /* RFC 4462 says we MUST NOT do SPNEGO */ 973 /* RFC 4462 says we MUST NOT do SPNEGO */
960 if (oid->length == spnego_oid.length && 974 if (oid->length == spnego_oid.length &&
961@@ -264,6 +471,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) 975@@ -287,6 +496,10 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host)
962 ssh_gssapi_build_ctx(ctx); 976 ssh_gssapi_build_ctx(ctx);
963 ssh_gssapi_set_oid(*ctx, oid); 977 ssh_gssapi_set_oid(*ctx, oid);
964 major = ssh_gssapi_import_name(*ctx, host); 978 major = ssh_gssapi_import_name(*ctx, host);
@@ -969,7 +983,7 @@ index 62559ed9e..0b3ae073c 100644
969 if (!GSS_ERROR(major)) { 983 if (!GSS_ERROR(major)) {
970 major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, 984 major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token,
971 NULL); 985 NULL);
972@@ -273,10 +484,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) 986@@ -296,10 +509,66 @@ ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host)
973 GSS_C_NO_BUFFER); 987 GSS_C_NO_BUFFER);
974 } 988 }
975 989
@@ -1038,11 +1052,11 @@ index 62559ed9e..0b3ae073c 100644
1038+ 1052+
1039 #endif /* GSSAPI */ 1053 #endif /* GSSAPI */
1040diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c 1054diff --git a/gss-serv-krb5.c b/gss-serv-krb5.c
1041index 795992d9f..fd8b37183 100644 1055index a151bc1e4..90f8692f5 100644
1042--- a/gss-serv-krb5.c 1056--- a/gss-serv-krb5.c
1043+++ b/gss-serv-krb5.c 1057+++ b/gss-serv-krb5.c
1044@@ -1,7 +1,7 @@ 1058@@ -1,7 +1,7 @@
1045 /* $OpenBSD: gss-serv-krb5.c,v 1.8 2013/07/20 01:55:13 djm Exp $ */ 1059 /* $OpenBSD: gss-serv-krb5.c,v 1.9 2018/07/09 21:37:55 markus Exp $ */
1046 1060
1047 /* 1061 /*
1048- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. 1062- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -1050,7 +1064,7 @@ index 795992d9f..fd8b37183 100644
1050 * 1064 *
1051 * Redistribution and use in source and binary forms, with or without 1065 * Redistribution and use in source and binary forms, with or without
1052 * modification, are permitted provided that the following conditions 1066 * modification, are permitted provided that the following conditions
1053@@ -121,8 +121,8 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) 1067@@ -120,8 +120,8 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
1054 krb5_error_code problem; 1068 krb5_error_code problem;
1055 krb5_principal princ; 1069 krb5_principal princ;
1056 OM_uint32 maj_status, min_status; 1070 OM_uint32 maj_status, min_status;
@@ -1060,7 +1074,7 @@ index 795992d9f..fd8b37183 100644
1060 1074
1061 if (client->creds == NULL) { 1075 if (client->creds == NULL) {
1062 debug("No credentials stored"); 1076 debug("No credentials stored");
1063@@ -181,11 +181,16 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) 1077@@ -180,11 +180,16 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
1064 return; 1078 return;
1065 } 1079 }
1066 1080
@@ -1081,7 +1095,7 @@ index 795992d9f..fd8b37183 100644
1081 1095
1082 #ifdef USE_PAM 1096 #ifdef USE_PAM
1083 if (options.use_pam) 1097 if (options.use_pam)
1084@@ -197,6 +202,71 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) 1098@@ -196,6 +201,71 @@ ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client)
1085 return; 1099 return;
1086 } 1100 }
1087 1101
@@ -1153,7 +1167,7 @@ index 795992d9f..fd8b37183 100644
1153 ssh_gssapi_mech gssapi_kerberos_mech = { 1167 ssh_gssapi_mech gssapi_kerberos_mech = {
1154 "toWM5Slw5Ew8Mqkay+al2g==", 1168 "toWM5Slw5Ew8Mqkay+al2g==",
1155 "Kerberos", 1169 "Kerberos",
1156@@ -204,7 +274,8 @@ ssh_gssapi_mech gssapi_kerberos_mech = { 1170@@ -203,7 +273,8 @@ ssh_gssapi_mech gssapi_kerberos_mech = {
1157 NULL, 1171 NULL,
1158 &ssh_gssapi_krb5_userok, 1172 &ssh_gssapi_krb5_userok,
1159 NULL, 1173 NULL,
@@ -1164,11 +1178,11 @@ index 795992d9f..fd8b37183 100644
1164 1178
1165 #endif /* KRB5 */ 1179 #endif /* KRB5 */
1166diff --git a/gss-serv.c b/gss-serv.c 1180diff --git a/gss-serv.c b/gss-serv.c
1167index 6cae720e5..967c6cfbc 100644 1181index ab3a15f0f..6c087a1b1 100644
1168--- a/gss-serv.c 1182--- a/gss-serv.c
1169+++ b/gss-serv.c 1183+++ b/gss-serv.c
1170@@ -1,7 +1,7 @@ 1184@@ -1,7 +1,7 @@
1171 /* $OpenBSD: gss-serv.c,v 1.30 2017/06/24 06:34:38 djm Exp $ */ 1185 /* $OpenBSD: gss-serv.c,v 1.31 2018/07/09 21:37:55 markus Exp $ */
1172 1186
1173 /* 1187 /*
1174- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. 1188- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -1176,7 +1190,7 @@ index 6cae720e5..967c6cfbc 100644
1176 * 1190 *
1177 * Redistribution and use in source and binary forms, with or without 1191 * Redistribution and use in source and binary forms, with or without
1178 * modification, are permitted provided that the following conditions 1192 * modification, are permitted provided that the following conditions
1179@@ -45,17 +45,22 @@ 1193@@ -44,17 +44,22 @@
1180 #include "session.h" 1194 #include "session.h"
1181 #include "misc.h" 1195 #include "misc.h"
1182 #include "servconf.h" 1196 #include "servconf.h"
@@ -1201,7 +1215,7 @@ index 6cae720e5..967c6cfbc 100644
1201 1215
1202 #ifdef KRB5 1216 #ifdef KRB5
1203 extern ssh_gssapi_mech gssapi_kerberos_mech; 1217 extern ssh_gssapi_mech gssapi_kerberos_mech;
1204@@ -141,6 +146,28 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) 1218@@ -140,6 +145,28 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid)
1205 return (ssh_gssapi_acquire_cred(*ctx)); 1219 return (ssh_gssapi_acquire_cred(*ctx));
1206 } 1220 }
1207 1221
@@ -1230,7 +1244,7 @@ index 6cae720e5..967c6cfbc 100644
1230 /* Unprivileged */ 1244 /* Unprivileged */
1231 void 1245 void
1232 ssh_gssapi_supported_oids(gss_OID_set *oidset) 1246 ssh_gssapi_supported_oids(gss_OID_set *oidset)
1233@@ -151,7 +178,9 @@ ssh_gssapi_supported_oids(gss_OID_set *oidset) 1247@@ -150,7 +177,9 @@ ssh_gssapi_supported_oids(gss_OID_set *oidset)
1234 gss_OID_set supported; 1248 gss_OID_set supported;
1235 1249
1236 gss_create_empty_oid_set(&min_status, oidset); 1250 gss_create_empty_oid_set(&min_status, oidset);
@@ -1241,7 +1255,7 @@ index 6cae720e5..967c6cfbc 100644
1241 1255
1242 while (supported_mechs[i]->name != NULL) { 1256 while (supported_mechs[i]->name != NULL) {
1243 if (GSS_ERROR(gss_test_oid_set_member(&min_status, 1257 if (GSS_ERROR(gss_test_oid_set_member(&min_status,
1244@@ -277,8 +306,48 @@ OM_uint32 1258@@ -276,8 +305,48 @@ OM_uint32
1245 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) 1259 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
1246 { 1260 {
1247 int i = 0; 1261 int i = 0;
@@ -1291,7 +1305,7 @@ index 6cae720e5..967c6cfbc 100644
1291 1305
1292 client->mech = NULL; 1306 client->mech = NULL;
1293 1307
1294@@ -293,6 +362,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) 1308@@ -292,6 +361,13 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
1295 if (client->mech == NULL) 1309 if (client->mech == NULL)
1296 return GSS_S_FAILURE; 1310 return GSS_S_FAILURE;
1297 1311
@@ -1305,7 +1319,7 @@ index 6cae720e5..967c6cfbc 100644
1305 if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, 1319 if ((ctx->major = gss_display_name(&ctx->minor, ctx->client,
1306 &client->displayname, NULL))) { 1320 &client->displayname, NULL))) {
1307 ssh_gssapi_error(ctx); 1321 ssh_gssapi_error(ctx);
1308@@ -310,6 +386,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) 1322@@ -309,6 +385,8 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
1309 return (ctx->major); 1323 return (ctx->major);
1310 } 1324 }
1311 1325
@@ -1314,7 +1328,7 @@ index 6cae720e5..967c6cfbc 100644
1314 /* We can't copy this structure, so we just move the pointer to it */ 1328 /* We can't copy this structure, so we just move the pointer to it */
1315 client->creds = ctx->client_creds; 1329 client->creds = ctx->client_creds;
1316 ctx->client_creds = GSS_C_NO_CREDENTIAL; 1330 ctx->client_creds = GSS_C_NO_CREDENTIAL;
1317@@ -357,7 +435,7 @@ ssh_gssapi_do_child(char ***envp, u_int *envsizep) 1331@@ -356,7 +434,7 @@ ssh_gssapi_do_child(char ***envp, u_int *envsizep)
1318 1332
1319 /* Privileged */ 1333 /* Privileged */
1320 int 1334 int
@@ -1323,7 +1337,7 @@ index 6cae720e5..967c6cfbc 100644
1323 { 1337 {
1324 OM_uint32 lmin; 1338 OM_uint32 lmin;
1325 1339
1326@@ -367,9 +445,11 @@ ssh_gssapi_userok(char *user) 1340@@ -366,9 +444,11 @@ ssh_gssapi_userok(char *user)
1327 return 0; 1341 return 0;
1328 } 1342 }
1329 if (gssapi_client.mech && gssapi_client.mech->userok) 1343 if (gssapi_client.mech && gssapi_client.mech->userok)
@@ -1337,7 +1351,7 @@ index 6cae720e5..967c6cfbc 100644
1337 /* Destroy delegated credentials if userok fails */ 1351 /* Destroy delegated credentials if userok fails */
1338 gss_release_buffer(&lmin, &gssapi_client.displayname); 1352 gss_release_buffer(&lmin, &gssapi_client.displayname);
1339 gss_release_buffer(&lmin, &gssapi_client.exportedname); 1353 gss_release_buffer(&lmin, &gssapi_client.exportedname);
1340@@ -383,14 +463,90 @@ ssh_gssapi_userok(char *user) 1354@@ -382,14 +462,90 @@ ssh_gssapi_userok(char *user)
1341 return (0); 1355 return (0);
1342 } 1356 }
1343 1357
@@ -1435,7 +1449,7 @@ index 6cae720e5..967c6cfbc 100644
1435 1449
1436 /* Privileged */ 1450 /* Privileged */
1437diff --git a/kex.c b/kex.c 1451diff --git a/kex.c b/kex.c
1438index 15ea28b07..6cc2935fe 100644 1452index 25f9f66f6..fb5bfaea5 100644
1439--- a/kex.c 1453--- a/kex.c
1440+++ b/kex.c 1454+++ b/kex.c
1441@@ -54,6 +54,10 @@ 1455@@ -54,6 +54,10 @@
@@ -1475,7 +1489,7 @@ index 15ea28b07..6cc2935fe 100644
1475 return NULL; 1489 return NULL;
1476 } 1490 }
1477 1491
1478@@ -599,6 +615,9 @@ kex_free(struct kex *kex) 1492@@ -653,6 +669,9 @@ kex_free(struct kex *kex)
1479 sshbuf_free(kex->peer); 1493 sshbuf_free(kex->peer);
1480 sshbuf_free(kex->my); 1494 sshbuf_free(kex->my);
1481 free(kex->session_id); 1495 free(kex->session_id);
@@ -1486,10 +1500,10 @@ index 15ea28b07..6cc2935fe 100644
1486 free(kex->server_version_string); 1500 free(kex->server_version_string);
1487 free(kex->failed_choice); 1501 free(kex->failed_choice);
1488diff --git a/kex.h b/kex.h 1502diff --git a/kex.h b/kex.h
1489index 01bb3986a..a708e4868 100644 1503index 593de1208..4e5ead839 100644
1490--- a/kex.h 1504--- a/kex.h
1491+++ b/kex.h 1505+++ b/kex.h
1492@@ -99,6 +99,9 @@ enum kex_exchange { 1506@@ -100,6 +100,9 @@ enum kex_exchange {
1493 KEX_DH_GEX_SHA256, 1507 KEX_DH_GEX_SHA256,
1494 KEX_ECDH_SHA2, 1508 KEX_ECDH_SHA2,
1495 KEX_C25519_SHA256, 1509 KEX_C25519_SHA256,
@@ -1499,7 +1513,7 @@ index 01bb3986a..a708e4868 100644
1499 KEX_MAX 1513 KEX_MAX
1500 }; 1514 };
1501 1515
1502@@ -147,6 +150,12 @@ struct kex { 1516@@ -148,6 +151,12 @@ struct kex {
1503 u_int flags; 1517 u_int flags;
1504 int hash_alg; 1518 int hash_alg;
1505 int ec_nid; 1519 int ec_nid;
@@ -1512,7 +1526,7 @@ index 01bb3986a..a708e4868 100644
1512 char *client_version_string; 1526 char *client_version_string;
1513 char *server_version_string; 1527 char *server_version_string;
1514 char *failed_choice; 1528 char *failed_choice;
1515@@ -197,6 +206,11 @@ int kexecdh_server(struct ssh *); 1529@@ -198,6 +207,11 @@ int kexecdh_server(struct ssh *);
1516 int kexc25519_client(struct ssh *); 1530 int kexc25519_client(struct ssh *);
1517 int kexc25519_server(struct ssh *); 1531 int kexc25519_server(struct ssh *);
1518 1532
@@ -1526,7 +1540,7 @@ index 01bb3986a..a708e4868 100644
1526 const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *); 1540 const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *);
1527diff --git a/kexgssc.c b/kexgssc.c 1541diff --git a/kexgssc.c b/kexgssc.c
1528new file mode 100644 1542new file mode 100644
1529index 000000000..10447f2b0 1543index 000000000..953c0a248
1530--- /dev/null 1544--- /dev/null
1531+++ b/kexgssc.c 1545+++ b/kexgssc.c
1532@@ -0,0 +1,338 @@ 1546@@ -0,0 +1,338 @@
@@ -1566,9 +1580,9 @@ index 000000000..10447f2b0
1566+#include <string.h> 1580+#include <string.h>
1567+ 1581+
1568+#include "xmalloc.h" 1582+#include "xmalloc.h"
1569+#include "buffer.h" 1583+#include "sshbuf.h"
1570+#include "ssh2.h" 1584+#include "ssh2.h"
1571+#include "key.h" 1585+#include "sshkey.h"
1572+#include "cipher.h" 1586+#include "cipher.h"
1573+#include "kex.h" 1587+#include "kex.h"
1574+#include "log.h" 1588+#include "log.h"
@@ -1805,8 +1819,8 @@ index 000000000..10447f2b0
1805+ ssh->kex->hash_alg, 1819+ ssh->kex->hash_alg,
1806+ ssh->kex->client_version_string, 1820+ ssh->kex->client_version_string,
1807+ ssh->kex->server_version_string, 1821+ ssh->kex->server_version_string,
1808+ buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), 1822+ sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my),
1809+ buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), 1823+ sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer),
1810+ (serverhostkey ? serverhostkey : empty), slen, 1824+ (serverhostkey ? serverhostkey : empty), slen,
1811+ dh->pub_key, /* e */ 1825+ dh->pub_key, /* e */
1812+ dh_server_pub, /* f */ 1826+ dh_server_pub, /* f */
@@ -1819,8 +1833,8 @@ index 000000000..10447f2b0
1819+ ssh->kex->hash_alg, 1833+ ssh->kex->hash_alg,
1820+ ssh->kex->client_version_string, 1834+ ssh->kex->client_version_string,
1821+ ssh->kex->server_version_string, 1835+ ssh->kex->server_version_string,
1822+ buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), 1836+ sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my),
1823+ buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), 1837+ sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer),
1824+ (serverhostkey ? serverhostkey : empty), slen, 1838+ (serverhostkey ? serverhostkey : empty), slen,
1825+ min, nbits, max, 1839+ min, nbits, max,
1826+ dh->p, dh->g, 1840+ dh->p, dh->g,
@@ -1870,7 +1884,7 @@ index 000000000..10447f2b0
1870+#endif /* GSSAPI */ 1884+#endif /* GSSAPI */
1871diff --git a/kexgsss.c b/kexgsss.c 1885diff --git a/kexgsss.c b/kexgsss.c
1872new file mode 100644 1886new file mode 100644
1873index 000000000..38ca082ba 1887index 000000000..31ec6a890
1874--- /dev/null 1888--- /dev/null
1875+++ b/kexgsss.c 1889+++ b/kexgsss.c
1876@@ -0,0 +1,295 @@ 1890@@ -0,0 +1,295 @@
@@ -1908,9 +1922,9 @@ index 000000000..38ca082ba
1908+#include <openssl/bn.h> 1922+#include <openssl/bn.h>
1909+ 1923+
1910+#include "xmalloc.h" 1924+#include "xmalloc.h"
1911+#include "buffer.h" 1925+#include "sshbuf.h"
1912+#include "ssh2.h" 1926+#include "ssh2.h"
1913+#include "key.h" 1927+#include "sshkey.h"
1914+#include "cipher.h" 1928+#include "cipher.h"
1915+#include "kex.h" 1929+#include "kex.h"
1916+#include "log.h" 1930+#include "log.h"
@@ -2096,8 +2110,8 @@ index 000000000..38ca082ba
2096+ kex_dh_hash( 2110+ kex_dh_hash(
2097+ ssh->kex->hash_alg, 2111+ ssh->kex->hash_alg,
2098+ ssh->kex->client_version_string, ssh->kex->server_version_string, 2112+ ssh->kex->client_version_string, ssh->kex->server_version_string,
2099+ buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), 2113+ sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer),
2100+ buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), 2114+ sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my),
2101+ NULL, 0, /* Change this if we start sending host keys */ 2115+ NULL, 0, /* Change this if we start sending host keys */
2102+ dh_client_pub, dh->pub_key, shared_secret, 2116+ dh_client_pub, dh->pub_key, shared_secret,
2103+ hash, &hashlen 2117+ hash, &hashlen
@@ -2107,8 +2121,8 @@ index 000000000..38ca082ba
2107+ kexgex_hash( 2121+ kexgex_hash(
2108+ ssh->kex->hash_alg, 2122+ ssh->kex->hash_alg,
2109+ ssh->kex->client_version_string, ssh->kex->server_version_string, 2123+ ssh->kex->client_version_string, ssh->kex->server_version_string,
2110+ buffer_ptr(ssh->kex->peer), buffer_len(ssh->kex->peer), 2124+ sshbuf_ptr(ssh->kex->peer), sshbuf_len(ssh->kex->peer),
2111+ buffer_ptr(ssh->kex->my), buffer_len(ssh->kex->my), 2125+ sshbuf_ptr(ssh->kex->my), sshbuf_len(ssh->kex->my),
2112+ NULL, 0, 2126+ NULL, 0,
2113+ min, nbits, max, 2127+ min, nbits, max,
2114+ dh->p, dh->g, 2128+ dh->p, dh->g,
@@ -2170,19 +2184,19 @@ index 000000000..38ca082ba
2170+} 2184+}
2171+#endif /* GSSAPI */ 2185+#endif /* GSSAPI */
2172diff --git a/monitor.c b/monitor.c 2186diff --git a/monitor.c b/monitor.c
2173index c68e1b0d9..868fb0d2d 100644 2187index d4b4b0471..4e574a2ae 100644
2174--- a/monitor.c 2188--- a/monitor.c
2175+++ b/monitor.c 2189+++ b/monitor.c
2176@@ -158,6 +158,8 @@ int mm_answer_gss_setup_ctx(int, Buffer *); 2190@@ -143,6 +143,8 @@ int mm_answer_gss_setup_ctx(int, struct sshbuf *);
2177 int mm_answer_gss_accept_ctx(int, Buffer *); 2191 int mm_answer_gss_accept_ctx(int, struct sshbuf *);
2178 int mm_answer_gss_userok(int, Buffer *); 2192 int mm_answer_gss_userok(int, struct sshbuf *);
2179 int mm_answer_gss_checkmic(int, Buffer *); 2193 int mm_answer_gss_checkmic(int, struct sshbuf *);
2180+int mm_answer_gss_sign(int, Buffer *); 2194+int mm_answer_gss_sign(int, struct sshbuf *);
2181+int mm_answer_gss_updatecreds(int, Buffer *); 2195+int mm_answer_gss_updatecreds(int, struct sshbuf *);
2182 #endif 2196 #endif
2183 2197
2184 #ifdef SSH_AUDIT_EVENTS 2198 #ifdef SSH_AUDIT_EVENTS
2185@@ -232,11 +234,18 @@ struct mon_table mon_dispatch_proto20[] = { 2199@@ -213,11 +215,18 @@ struct mon_table mon_dispatch_proto20[] = {
2186 {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, 2200 {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx},
2187 {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, 2201 {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok},
2188 {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, 2202 {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic},
@@ -2201,7 +2215,7 @@ index c68e1b0d9..868fb0d2d 100644
2201 #ifdef WITH_OPENSSL 2215 #ifdef WITH_OPENSSL
2202 {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, 2216 {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
2203 #endif 2217 #endif
2204@@ -306,6 +315,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) 2218@@ -287,6 +296,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
2205 /* Permit requests for moduli and signatures */ 2219 /* Permit requests for moduli and signatures */
2206 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 2220 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
2207 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 2221 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
@@ -2212,7 +2226,7 @@ index c68e1b0d9..868fb0d2d 100644
2212 2226
2213 /* The first few requests do not require asynchronous access */ 2227 /* The first few requests do not require asynchronous access */
2214 while (!authenticated) { 2228 while (!authenticated) {
2215@@ -415,6 +428,10 @@ monitor_child_postauth(struct monitor *pmonitor) 2229@@ -399,6 +412,10 @@ monitor_child_postauth(struct monitor *pmonitor)
2216 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 2230 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
2217 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 2231 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
2218 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); 2232 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
@@ -2223,7 +2237,7 @@ index c68e1b0d9..868fb0d2d 100644
2223 2237
2224 if (auth_opts->permit_pty_flag) { 2238 if (auth_opts->permit_pty_flag) {
2225 monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); 2239 monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1);
2226@@ -1652,6 +1669,13 @@ monitor_apply_keystate(struct monitor *pmonitor) 2240@@ -1662,6 +1679,13 @@ monitor_apply_keystate(struct monitor *pmonitor)
2227 # endif 2241 # endif
2228 #endif /* WITH_OPENSSL */ 2242 #endif /* WITH_OPENSSL */
2229 kex->kex[KEX_C25519_SHA256] = kexc25519_server; 2243 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
@@ -2237,29 +2251,29 @@ index c68e1b0d9..868fb0d2d 100644
2237 kex->load_host_public_key=&get_hostkey_public_by_type; 2251 kex->load_host_public_key=&get_hostkey_public_by_type;
2238 kex->load_host_private_key=&get_hostkey_private_by_type; 2252 kex->load_host_private_key=&get_hostkey_private_by_type;
2239 kex->host_key_index=&get_hostkey_index; 2253 kex->host_key_index=&get_hostkey_index;
2240@@ -1740,8 +1764,8 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m) 2254@@ -1752,8 +1776,8 @@ mm_answer_gss_setup_ctx(int sock, struct sshbuf *m)
2241 OM_uint32 major; 2255 u_char *p;
2242 u_int len; 2256 int r;
2243 2257
2244- if (!options.gss_authentication) 2258- if (!options.gss_authentication)
2245- fatal("%s: GSSAPI authentication not enabled", __func__); 2259- fatal("%s: GSSAPI authentication not enabled", __func__);
2246+ if (!options.gss_authentication && !options.gss_keyex) 2260+ if (!options.gss_authentication && !options.gss_keyex)
2247+ fatal("%s: GSSAPI not enabled", __func__); 2261+ fatal("%s: GSSAPI not enabled", __func__);
2248 2262
2249 goid.elements = buffer_get_string(m, &len); 2263 if ((r = sshbuf_get_string(m, &p, &len)) != 0)
2250 goid.length = len; 2264 fatal("%s: buffer error: %s", __func__, ssh_err(r));
2251@@ -1770,8 +1794,8 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m) 2265@@ -1785,8 +1809,8 @@ mm_answer_gss_accept_ctx(int sock, struct sshbuf *m)
2252 OM_uint32 flags = 0; /* GSI needs this */ 2266 OM_uint32 flags = 0; /* GSI needs this */
2253 u_int len; 2267 int r;
2254 2268
2255- if (!options.gss_authentication) 2269- if (!options.gss_authentication)
2256- fatal("%s: GSSAPI authentication not enabled", __func__); 2270- fatal("%s: GSSAPI authentication not enabled", __func__);
2257+ if (!options.gss_authentication && !options.gss_keyex) 2271+ if (!options.gss_authentication && !options.gss_keyex)
2258+ fatal("%s: GSSAPI not enabled", __func__); 2272+ fatal("%s: GSSAPI not enabled", __func__);
2259 2273
2260 in.value = buffer_get_string(m, &len); 2274 if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0)
2261 in.length = len; 2275 fatal("%s: buffer error: %s", __func__, ssh_err(r));
2262@@ -1790,6 +1814,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m) 2276@@ -1806,6 +1830,7 @@ mm_answer_gss_accept_ctx(int sock, struct sshbuf *m)
2263 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); 2277 monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
2264 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); 2278 monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
2265 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); 2279 monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
@@ -2267,19 +2281,19 @@ index c68e1b0d9..868fb0d2d 100644
2267 } 2281 }
2268 return (0); 2282 return (0);
2269 } 2283 }
2270@@ -1801,8 +1826,8 @@ mm_answer_gss_checkmic(int sock, Buffer *m) 2284@@ -1817,8 +1842,8 @@ mm_answer_gss_checkmic(int sock, struct sshbuf *m)
2271 OM_uint32 ret; 2285 OM_uint32 ret;
2272 u_int len; 2286 int r;
2273 2287
2274- if (!options.gss_authentication) 2288- if (!options.gss_authentication)
2275- fatal("%s: GSSAPI authentication not enabled", __func__); 2289- fatal("%s: GSSAPI authentication not enabled", __func__);
2276+ if (!options.gss_authentication && !options.gss_keyex) 2290+ if (!options.gss_authentication && !options.gss_keyex)
2277+ fatal("%s: GSSAPI not enabled", __func__); 2291+ fatal("%s: GSSAPI not enabled", __func__);
2278 2292
2279 gssbuf.value = buffer_get_string(m, &len); 2293 if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 ||
2280 gssbuf.length = len; 2294 (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0)
2281@@ -1831,10 +1856,11 @@ mm_answer_gss_userok(int sock, Buffer *m) 2295@@ -1847,10 +1872,11 @@ mm_answer_gss_userok(int sock, struct sshbuf *m)
2282 int authenticated; 2296 int r, authenticated;
2283 const char *displayname; 2297 const char *displayname;
2284 2298
2285- if (!options.gss_authentication) 2299- if (!options.gss_authentication)
@@ -2291,25 +2305,29 @@ index c68e1b0d9..868fb0d2d 100644
2291+ authenticated = authctxt->valid && 2305+ authenticated = authctxt->valid &&
2292+ ssh_gssapi_userok(authctxt->user, authctxt->pw); 2306+ ssh_gssapi_userok(authctxt->user, authctxt->pw);
2293 2307
2294 buffer_clear(m); 2308 sshbuf_reset(m);
2295 buffer_put_int(m, authenticated); 2309 if ((r = sshbuf_put_u32(m, authenticated)) != 0)
2296@@ -1850,5 +1876,76 @@ mm_answer_gss_userok(int sock, Buffer *m) 2310@@ -1867,5 +1893,83 @@ mm_answer_gss_userok(int sock, struct sshbuf *m)
2297 /* Monitor loop will terminate if authenticated */ 2311 /* Monitor loop will terminate if authenticated */
2298 return (authenticated); 2312 return (authenticated);
2299 } 2313 }
2300+ 2314+
2301+int 2315+int
2302+mm_answer_gss_sign(int socket, Buffer *m) 2316+mm_answer_gss_sign(int socket, struct sshbuf *m)
2303+{ 2317+{
2304+ gss_buffer_desc data; 2318+ gss_buffer_desc data;
2305+ gss_buffer_desc hash = GSS_C_EMPTY_BUFFER; 2319+ gss_buffer_desc hash = GSS_C_EMPTY_BUFFER;
2306+ OM_uint32 major, minor; 2320+ OM_uint32 major, minor;
2307+ u_int len; 2321+ size_t len;
2322+ u_char *p;
2323+ int r;
2308+ 2324+
2309+ if (!options.gss_authentication && !options.gss_keyex) 2325+ if (!options.gss_authentication && !options.gss_keyex)
2310+ fatal("%s: GSSAPI not enabled", __func__); 2326+ fatal("%s: GSSAPI not enabled", __func__);
2311+ 2327+
2312+ data.value = buffer_get_string(m, &len); 2328+ if ((r = sshbuf_get_string(m, &p, &len)) != 0)
2329+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
2330+ data.value = p;
2313+ data.length = len; 2331+ data.length = len;
2314+ if (data.length != 20) 2332+ if (data.length != 20)
2315+ fatal("%s: data length incorrect: %d", __func__, 2333+ fatal("%s: data length incorrect: %d", __func__,
@@ -2325,9 +2343,10 @@ index c68e1b0d9..868fb0d2d 100644
2325+ 2343+
2326+ free(data.value); 2344+ free(data.value);
2327+ 2345+
2328+ buffer_clear(m); 2346+ sshbuf_reset(m);
2329+ buffer_put_int(m, major); 2347+ if ((r = sshbuf_put_u32(m, major)) != 0 ||
2330+ buffer_put_string(m, hash.value, hash.length); 2348+ (r = sshbuf_put_string(m, hash.value, hash.length)) != 0)
2349+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
2331+ 2350+
2332+ mm_request_send(socket, MONITOR_ANS_GSSSIGN, m); 2351+ mm_request_send(socket, MONITOR_ANS_GSSSIGN, m);
2333+ 2352+
@@ -2343,16 +2362,17 @@ index c68e1b0d9..868fb0d2d 100644
2343+} 2362+}
2344+ 2363+
2345+int 2364+int
2346+mm_answer_gss_updatecreds(int socket, Buffer *m) { 2365+mm_answer_gss_updatecreds(int socket, struct sshbuf *m) {
2347+ ssh_gssapi_ccache store; 2366+ ssh_gssapi_ccache store;
2348+ int ok; 2367+ int r, ok;
2349+ 2368+
2350+ if (!options.gss_authentication && !options.gss_keyex) 2369+ if (!options.gss_authentication && !options.gss_keyex)
2351+ fatal("%s: GSSAPI not enabled", __func__); 2370+ fatal("%s: GSSAPI not enabled", __func__);
2352+ 2371+
2353+ store.filename = buffer_get_string(m, NULL); 2372+ if ((r = sshbuf_get_cstring(m, &store.filename, NULL)) != 0 ||
2354+ store.envvar = buffer_get_string(m, NULL); 2373+ (r = sshbuf_get_cstring(m, &store.envvar, NULL)) != 0 ||
2355+ store.envval = buffer_get_string(m, NULL); 2374+ (r = sshbuf_get_cstring(m, &store.envval, NULL)) != 0)
2375+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
2356+ 2376+
2357+ ok = ssh_gssapi_update_creds(&store); 2377+ ok = ssh_gssapi_update_creds(&store);
2358+ 2378+
@@ -2360,8 +2380,9 @@ index c68e1b0d9..868fb0d2d 100644
2360+ free(store.envvar); 2380+ free(store.envvar);
2361+ free(store.envval); 2381+ free(store.envval);
2362+ 2382+
2363+ buffer_clear(m); 2383+ sshbuf_reset(m);
2364+ buffer_put_int(m, ok); 2384+ if ((r = sshbuf_put_u32(m, ok)) != 0)
2385+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
2365+ 2386+
2366+ mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m); 2387+ mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m);
2367+ 2388+
@@ -2371,10 +2392,10 @@ index c68e1b0d9..868fb0d2d 100644
2371 #endif /* GSSAPI */ 2392 #endif /* GSSAPI */
2372 2393
2373diff --git a/monitor.h b/monitor.h 2394diff --git a/monitor.h b/monitor.h
2374index d68f67458..ec41404c7 100644 2395index 16047299f..44fbed589 100644
2375--- a/monitor.h 2396--- a/monitor.h
2376+++ b/monitor.h 2397+++ b/monitor.h
2377@@ -65,6 +65,9 @@ enum monitor_reqtype { 2398@@ -63,6 +63,9 @@ enum monitor_reqtype {
2378 MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, 2399 MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111,
2379 MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113, 2400 MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113,
2380 2401
@@ -2385,19 +2406,19 @@ index d68f67458..ec41404c7 100644
2385 2406
2386 struct monitor { 2407 struct monitor {
2387diff --git a/monitor_wrap.c b/monitor_wrap.c 2408diff --git a/monitor_wrap.c b/monitor_wrap.c
2388index 9666bda4b..e749efc18 100644 2409index 732fb3476..1865a122a 100644
2389--- a/monitor_wrap.c 2410--- a/monitor_wrap.c
2390+++ b/monitor_wrap.c 2411+++ b/monitor_wrap.c
2391@@ -943,7 +943,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) 2412@@ -984,7 +984,7 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
2392 } 2413 }
2393 2414
2394 int 2415 int
2395-mm_ssh_gssapi_userok(char *user) 2416-mm_ssh_gssapi_userok(char *user)
2396+mm_ssh_gssapi_userok(char *user, struct passwd *pw) 2417+mm_ssh_gssapi_userok(char *user, struct passwd *pw)
2397 { 2418 {
2398 Buffer m; 2419 struct sshbuf *m;
2399 int authenticated = 0; 2420 int r, authenticated = 0;
2400@@ -960,5 +960,50 @@ mm_ssh_gssapi_userok(char *user) 2421@@ -1003,4 +1003,55 @@ mm_ssh_gssapi_userok(char *user)
2401 debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); 2422 debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
2402 return (authenticated); 2423 return (authenticated);
2403 } 2424 }
@@ -2405,21 +2426,23 @@ index 9666bda4b..e749efc18 100644
2405+OM_uint32 2426+OM_uint32
2406+mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) 2427+mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash)
2407+{ 2428+{
2408+ Buffer m; 2429+ struct sshbuf *m;
2409+ OM_uint32 major; 2430+ OM_uint32 major;
2410+ u_int len; 2431+ int r;
2411+ 2432+
2412+ buffer_init(&m); 2433+ if ((m = sshbuf_new()) == NULL)
2413+ buffer_put_string(&m, data->value, data->length); 2434+ fatal("%s: sshbuf_new failed", __func__);
2435+ if ((r = sshbuf_put_string(m, data->value, data->length)) != 0)
2436+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
2414+ 2437+
2415+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSIGN, &m); 2438+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSIGN, m);
2416+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSIGN, &m); 2439+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSIGN, m);
2417+ 2440+
2418+ major = buffer_get_int(&m); 2441+ if ((r = sshbuf_get_u32(m, &major)) != 0 ||
2419+ hash->value = buffer_get_string(&m, &len); 2442+ (r = ssh_gssapi_get_buffer_desc(m, hash)) != 0)
2420+ hash->length = len; 2443+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
2421+ 2444+
2422+ buffer_free(&m); 2445+ sshbuf_free(m);
2423+ 2446+
2424+ return(major); 2447+ return(major);
2425+} 2448+}
@@ -2427,29 +2450,32 @@ index 9666bda4b..e749efc18 100644
2427+int 2450+int
2428+mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *store) 2451+mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *store)
2429+{ 2452+{
2430+ Buffer m; 2453+ struct sshbuf *m;
2431+ int ok; 2454+ int r, ok;
2432+ 2455+
2433+ buffer_init(&m); 2456+ if ((m = sshbuf_new()) == NULL)
2434+ 2457+ fatal("%s: sshbuf_new failed", __func__);
2435+ buffer_put_cstring(&m, store->filename ? store->filename : ""); 2458+ if ((r = sshbuf_put_cstring(m,
2436+ buffer_put_cstring(&m, store->envvar ? store->envvar : ""); 2459+ store->filename ? store->filename : "")) != 0 ||
2437+ buffer_put_cstring(&m, store->envval ? store->envval : ""); 2460+ (r = sshbuf_put_cstring(m,
2438+ 2461+ store->envvar ? store->envvar : "")) != 0 ||
2439+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUPCREDS, &m); 2462+ (r = sshbuf_put_cstring(m,
2440+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUPCREDS, &m); 2463+ store->envval ? store->envval : "")) != 0)
2464+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
2465+
2466+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUPCREDS, m);
2467+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUPCREDS, m);
2468+
2469+ if ((r = sshbuf_get_u32(m, &ok)) != 0)
2470+ fatal("%s: buffer error: %s", __func__, ssh_err(r));
2471+ sshbuf_free(m);
2441+ 2472+
2442+ ok = buffer_get_int(&m);
2443+
2444+ buffer_free(&m);
2445+
2446+ return (ok); 2473+ return (ok);
2447+} 2474+}
2448+ 2475+
2449 #endif /* GSSAPI */ 2476 #endif /* GSSAPI */
2450
2451diff --git a/monitor_wrap.h b/monitor_wrap.h 2477diff --git a/monitor_wrap.h b/monitor_wrap.h
2452index 762332704..0970d1f87 100644 2478index 644da081d..7f93144ff 100644
2453--- a/monitor_wrap.h 2479--- a/monitor_wrap.h
2454+++ b/monitor_wrap.h 2480+++ b/monitor_wrap.h
2455@@ -60,8 +60,10 @@ int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, 2481@@ -60,8 +60,10 @@ int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t,
@@ -2465,19 +2491,19 @@ index 762332704..0970d1f87 100644
2465 2491
2466 #ifdef USE_PAM 2492 #ifdef USE_PAM
2467diff --git a/readconf.c b/readconf.c 2493diff --git a/readconf.c b/readconf.c
2468index 88051db57..c8e792991 100644 2494index db5f2d547..4ad3c75fe 100644
2469--- a/readconf.c 2495--- a/readconf.c
2470+++ b/readconf.c 2496+++ b/readconf.c
2471@@ -160,6 +160,8 @@ typedef enum { 2497@@ -161,6 +161,8 @@ typedef enum {
2472 oClearAllForwardings, oNoHostAuthenticationForLocalhost, 2498 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
2473 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, 2499 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
2474 oAddressFamily, oGssAuthentication, oGssDelegateCreds, 2500 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
2475+ oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey, 2501+ oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey,
2476+ oGssServerIdentity, 2502+ oGssServerIdentity,
2477 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, 2503 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
2478 oSendEnv, oControlPath, oControlMaster, oControlPersist, 2504 oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist,
2479 oHashKnownHosts, 2505 oHashKnownHosts,
2480@@ -199,10 +201,20 @@ static struct { 2506@@ -201,10 +203,20 @@ static struct {
2481 /* Sometimes-unsupported options */ 2507 /* Sometimes-unsupported options */
2482 #if defined(GSSAPI) 2508 #if defined(GSSAPI)
2483 { "gssapiauthentication", oGssAuthentication }, 2509 { "gssapiauthentication", oGssAuthentication },
@@ -2498,7 +2524,7 @@ index 88051db57..c8e792991 100644
2498 #endif 2524 #endif
2499 #ifdef ENABLE_PKCS11 2525 #ifdef ENABLE_PKCS11
2500 { "smartcarddevice", oPKCS11Provider }, 2526 { "smartcarddevice", oPKCS11Provider },
2501@@ -950,10 +962,30 @@ parse_time: 2527@@ -973,10 +985,30 @@ parse_time:
2502 intptr = &options->gss_authentication; 2528 intptr = &options->gss_authentication;
2503 goto parse_flag; 2529 goto parse_flag;
2504 2530
@@ -2529,7 +2555,7 @@ index 88051db57..c8e792991 100644
2529 case oBatchMode: 2555 case oBatchMode:
2530 intptr = &options->batch_mode; 2556 intptr = &options->batch_mode;
2531 goto parse_flag; 2557 goto parse_flag;
2532@@ -1765,7 +1797,12 @@ initialize_options(Options * options) 2558@@ -1817,7 +1849,12 @@ initialize_options(Options * options)
2533 options->pubkey_authentication = -1; 2559 options->pubkey_authentication = -1;
2534 options->challenge_response_authentication = -1; 2560 options->challenge_response_authentication = -1;
2535 options->gss_authentication = -1; 2561 options->gss_authentication = -1;
@@ -2542,7 +2568,7 @@ index 88051db57..c8e792991 100644
2542 options->password_authentication = -1; 2568 options->password_authentication = -1;
2543 options->kbd_interactive_authentication = -1; 2569 options->kbd_interactive_authentication = -1;
2544 options->kbd_interactive_devices = NULL; 2570 options->kbd_interactive_devices = NULL;
2545@@ -1906,8 +1943,14 @@ fill_default_options(Options * options) 2571@@ -1962,8 +1999,14 @@ fill_default_options(Options * options)
2546 options->challenge_response_authentication = 1; 2572 options->challenge_response_authentication = 1;
2547 if (options->gss_authentication == -1) 2573 if (options->gss_authentication == -1)
2548 options->gss_authentication = 0; 2574 options->gss_authentication = 0;
@@ -2558,10 +2584,10 @@ index 88051db57..c8e792991 100644
2558 options->password_authentication = 1; 2584 options->password_authentication = 1;
2559 if (options->kbd_interactive_authentication == -1) 2585 if (options->kbd_interactive_authentication == -1)
2560diff --git a/readconf.h b/readconf.h 2586diff --git a/readconf.h b/readconf.h
2561index f4d9e2b26..f469daaff 100644 2587index c56887816..5ea0c296b 100644
2562--- a/readconf.h 2588--- a/readconf.h
2563+++ b/readconf.h 2589+++ b/readconf.h
2564@@ -42,7 +42,12 @@ typedef struct { 2590@@ -40,7 +40,12 @@ typedef struct {
2565 int challenge_response_authentication; 2591 int challenge_response_authentication;
2566 /* Try S/Key or TIS, authentication. */ 2592 /* Try S/Key or TIS, authentication. */
2567 int gss_authentication; /* Try GSS authentication */ 2593 int gss_authentication; /* Try GSS authentication */
@@ -2575,10 +2601,10 @@ index f4d9e2b26..f469daaff 100644
2575 * authentication. */ 2601 * authentication. */
2576 int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ 2602 int kbd_interactive_authentication; /* Try keyboard-interactive auth. */
2577diff --git a/servconf.c b/servconf.c 2603diff --git a/servconf.c b/servconf.c
2578index 0f0d09068..cbbea05bf 100644 2604index c0f6af0be..e1ae07fb7 100644
2579--- a/servconf.c 2605--- a/servconf.c
2580+++ b/servconf.c 2606+++ b/servconf.c
2581@@ -123,8 +123,10 @@ initialize_server_options(ServerOptions *options) 2607@@ -124,8 +124,10 @@ initialize_server_options(ServerOptions *options)
2582 options->kerberos_ticket_cleanup = -1; 2608 options->kerberos_ticket_cleanup = -1;
2583 options->kerberos_get_afs_token = -1; 2609 options->kerberos_get_afs_token = -1;
2584 options->gss_authentication=-1; 2610 options->gss_authentication=-1;
@@ -2589,7 +2615,7 @@ index 0f0d09068..cbbea05bf 100644
2589 options->password_authentication = -1; 2615 options->password_authentication = -1;
2590 options->kbd_interactive_authentication = -1; 2616 options->kbd_interactive_authentication = -1;
2591 options->challenge_response_authentication = -1; 2617 options->challenge_response_authentication = -1;
2592@@ -315,10 +317,14 @@ fill_default_server_options(ServerOptions *options) 2618@@ -333,10 +335,14 @@ fill_default_server_options(ServerOptions *options)
2593 options->kerberos_get_afs_token = 0; 2619 options->kerberos_get_afs_token = 0;
2594 if (options->gss_authentication == -1) 2620 if (options->gss_authentication == -1)
2595 options->gss_authentication = 0; 2621 options->gss_authentication = 0;
@@ -2604,15 +2630,15 @@ index 0f0d09068..cbbea05bf 100644
2604 if (options->password_authentication == -1) 2630 if (options->password_authentication == -1)
2605 options->password_authentication = 1; 2631 options->password_authentication = 1;
2606 if (options->kbd_interactive_authentication == -1) 2632 if (options->kbd_interactive_authentication == -1)
2607@@ -461,6 +467,7 @@ typedef enum { 2633@@ -481,6 +487,7 @@ typedef enum {
2608 sHostKeyAlgorithms, 2634 sHostKeyAlgorithms,
2609 sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, 2635 sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
2610 sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, 2636 sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
2611+ sGssKeyEx, sGssStoreRekey, 2637+ sGssKeyEx, sGssStoreRekey,
2612 sAcceptEnv, sPermitTunnel, 2638 sAcceptEnv, sSetEnv, sPermitTunnel,
2613 sMatch, sPermitOpen, sForceCommand, sChrootDirectory, 2639 sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
2614 sUsePrivilegeSeparation, sAllowAgentForwarding, 2640 sUsePrivilegeSeparation, sAllowAgentForwarding,
2615@@ -535,12 +542,20 @@ static struct { 2641@@ -555,12 +562,20 @@ static struct {
2616 #ifdef GSSAPI 2642 #ifdef GSSAPI
2617 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, 2643 { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
2618 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, 2644 { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
@@ -2633,7 +2659,7 @@ index 0f0d09068..cbbea05bf 100644
2633 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, 2659 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
2634 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, 2660 { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
2635 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, 2661 { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
2636@@ -1407,6 +1422,10 @@ process_server_config_line(ServerOptions *options, char *line, 2662@@ -1459,6 +1474,10 @@ process_server_config_line(ServerOptions *options, char *line,
2637 intptr = &options->gss_authentication; 2663 intptr = &options->gss_authentication;
2638 goto parse_flag; 2664 goto parse_flag;
2639 2665
@@ -2644,7 +2670,7 @@ index 0f0d09068..cbbea05bf 100644
2644 case sGssCleanupCreds: 2670 case sGssCleanupCreds:
2645 intptr = &options->gss_cleanup_creds; 2671 intptr = &options->gss_cleanup_creds;
2646 goto parse_flag; 2672 goto parse_flag;
2647@@ -1415,6 +1434,10 @@ process_server_config_line(ServerOptions *options, char *line, 2673@@ -1467,6 +1486,10 @@ process_server_config_line(ServerOptions *options, char *line,
2648 intptr = &options->gss_strict_acceptor; 2674 intptr = &options->gss_strict_acceptor;
2649 goto parse_flag; 2675 goto parse_flag;
2650 2676
@@ -2655,7 +2681,7 @@ index 0f0d09068..cbbea05bf 100644
2655 case sPasswordAuthentication: 2681 case sPasswordAuthentication:
2656 intptr = &options->password_authentication; 2682 intptr = &options->password_authentication;
2657 goto parse_flag; 2683 goto parse_flag;
2658@@ -2453,7 +2476,10 @@ dump_config(ServerOptions *o) 2684@@ -2551,7 +2574,10 @@ dump_config(ServerOptions *o)
2659 #endif 2685 #endif
2660 #ifdef GSSAPI 2686 #ifdef GSSAPI
2661 dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); 2687 dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
@@ -2667,10 +2693,10 @@ index 0f0d09068..cbbea05bf 100644
2667 dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); 2693 dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
2668 dump_cfg_fmtint(sKbdInteractiveAuthentication, 2694 dump_cfg_fmtint(sKbdInteractiveAuthentication,
2669diff --git a/servconf.h b/servconf.h 2695diff --git a/servconf.h b/servconf.h
2670index 37a0fb1a3..5dfc9bc02 100644 2696index 557521d73..9b117fe27 100644
2671--- a/servconf.h 2697--- a/servconf.h
2672+++ b/servconf.h 2698+++ b/servconf.h
2673@@ -130,8 +130,10 @@ typedef struct { 2699@@ -124,8 +124,10 @@ typedef struct {
2674 int kerberos_get_afs_token; /* If true, try to get AFS token if 2700 int kerberos_get_afs_token; /* If true, try to get AFS token if
2675 * authenticated with Kerberos. */ 2701 * authenticated with Kerberos. */
2676 int gss_authentication; /* If true, permit GSSAPI authentication */ 2702 int gss_authentication; /* If true, permit GSSAPI authentication */
@@ -2682,11 +2708,11 @@ index 37a0fb1a3..5dfc9bc02 100644
2682 * authentication. */ 2708 * authentication. */
2683 int kbd_interactive_authentication; /* If true, permit */ 2709 int kbd_interactive_authentication; /* If true, permit */
2684diff --git a/ssh-gss.h b/ssh-gss.h 2710diff --git a/ssh-gss.h b/ssh-gss.h
2685index 6593e422d..919660a03 100644 2711index 36180d07a..350ce7882 100644
2686--- a/ssh-gss.h 2712--- a/ssh-gss.h
2687+++ b/ssh-gss.h 2713+++ b/ssh-gss.h
2688@@ -1,6 +1,6 @@ 2714@@ -1,6 +1,6 @@
2689 /* $OpenBSD: ssh-gss.h,v 1.12 2017/06/24 06:34:38 djm Exp $ */ 2715 /* $OpenBSD: ssh-gss.h,v 1.14 2018/07/10 09:13:30 djm Exp $ */
2690 /* 2716 /*
2691- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. 2717- * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
2692+ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. 2718+ * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
@@ -2749,10 +2775,10 @@ index 6593e422d..919660a03 100644
2749 2775
2750 int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); 2776 int ssh_gssapi_check_oid(Gssctxt *, void *, size_t);
2751 void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); 2777 void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t);
2752@@ -119,17 +136,33 @@ void ssh_gssapi_build_ctx(Gssctxt **); 2778@@ -123,17 +140,33 @@ void ssh_gssapi_delete_ctx(Gssctxt **);
2753 void ssh_gssapi_delete_ctx(Gssctxt **);
2754 OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); 2779 OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t);
2755 void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *); 2780 void ssh_gssapi_buildmic(struct sshbuf *, const char *,
2781 const char *, const char *);
2756-int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *); 2782-int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *);
2757+int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *, const char *); 2783+int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *, const char *);
2758+OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *); 2784+OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *);
@@ -2799,10 +2825,10 @@ index c12f5ef52..bcb9f153d 100644
2799 # CheckHostIP yes 2825 # CheckHostIP yes
2800 # AddressFamily any 2826 # AddressFamily any
2801diff --git a/ssh_config.5 b/ssh_config.5 2827diff --git a/ssh_config.5 b/ssh_config.5
2802index 71705cabd..66826aa70 100644 2828index f499396a3..5b99921b4 100644
2803--- a/ssh_config.5 2829--- a/ssh_config.5
2804+++ b/ssh_config.5 2830+++ b/ssh_config.5
2805@@ -727,10 +727,42 @@ The default is 2831@@ -718,10 +718,42 @@ The default is
2806 Specifies whether user authentication based on GSSAPI is allowed. 2832 Specifies whether user authentication based on GSSAPI is allowed.
2807 The default is 2833 The default is
2808 .Cm no . 2834 .Cm no .
@@ -2846,7 +2872,7 @@ index 71705cabd..66826aa70 100644
2846 Indicates that 2872 Indicates that
2847 .Xr ssh 1 2873 .Xr ssh 1
2848diff --git a/sshconnect2.c b/sshconnect2.c 2874diff --git a/sshconnect2.c b/sshconnect2.c
2849index 1f4a74cf4..83562c688 100644 2875index 10e4f0a08..c6a1b1271 100644
2850--- a/sshconnect2.c 2876--- a/sshconnect2.c
2851+++ b/sshconnect2.c 2877+++ b/sshconnect2.c
2852@@ -162,6 +162,11 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) 2878@@ -162,6 +162,11 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
@@ -2861,7 +2887,7 @@ index 1f4a74cf4..83562c688 100644
2861 xxx_host = host; 2887 xxx_host = host;
2862 xxx_hostaddr = hostaddr; 2888 xxx_hostaddr = hostaddr;
2863 2889
2864@@ -192,6 +197,35 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) 2890@@ -194,6 +199,35 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
2865 order_hostkeyalgs(host, hostaddr, port)); 2891 order_hostkeyalgs(host, hostaddr, port));
2866 } 2892 }
2867 2893
@@ -2897,7 +2923,7 @@ index 1f4a74cf4..83562c688 100644
2897 if (options.rekey_limit || options.rekey_interval) 2923 if (options.rekey_limit || options.rekey_interval)
2898 packet_set_rekey_limits(options.rekey_limit, 2924 packet_set_rekey_limits(options.rekey_limit,
2899 options.rekey_interval); 2925 options.rekey_interval);
2900@@ -213,15 +247,41 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) 2926@@ -215,15 +249,41 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
2901 # endif 2927 # endif
2902 #endif 2928 #endif
2903 kex->kex[KEX_C25519_SHA256] = kexc25519_client; 2929 kex->kex[KEX_C25519_SHA256] = kexc25519_client;
@@ -2939,7 +2965,7 @@ index 1f4a74cf4..83562c688 100644
2939 if ((r = kex_prop2buf(kex->my, myproposal)) != 0) 2965 if ((r = kex_prop2buf(kex->my, myproposal)) != 0)
2940 fatal("kex_prop2buf: %s", ssh_err(r)); 2966 fatal("kex_prop2buf: %s", ssh_err(r));
2941 2967
2942@@ -311,6 +371,7 @@ int input_gssapi_token(int type, u_int32_t, struct ssh *); 2968@@ -314,6 +374,7 @@ int input_gssapi_token(int type, u_int32_t, struct ssh *);
2943 int input_gssapi_hash(int type, u_int32_t, struct ssh *); 2969 int input_gssapi_hash(int type, u_int32_t, struct ssh *);
2944 int input_gssapi_error(int, u_int32_t, struct ssh *); 2970 int input_gssapi_error(int, u_int32_t, struct ssh *);
2945 int input_gssapi_errtok(int, u_int32_t, struct ssh *); 2971 int input_gssapi_errtok(int, u_int32_t, struct ssh *);
@@ -2947,7 +2973,7 @@ index 1f4a74cf4..83562c688 100644
2947 #endif 2973 #endif
2948 2974
2949 void userauth(Authctxt *, char *); 2975 void userauth(Authctxt *, char *);
2950@@ -327,6 +388,11 @@ static char *authmethods_get(void); 2976@@ -330,6 +391,11 @@ static char *authmethods_get(void);
2951 2977
2952 Authmethod authmethods[] = { 2978 Authmethod authmethods[] = {
2953 #ifdef GSSAPI 2979 #ifdef GSSAPI
@@ -2959,10 +2985,10 @@ index 1f4a74cf4..83562c688 100644
2959 {"gssapi-with-mic", 2985 {"gssapi-with-mic",
2960 userauth_gssapi, 2986 userauth_gssapi,
2961 NULL, 2987 NULL,
2962@@ -643,25 +709,40 @@ userauth_gssapi(Authctxt *authctxt) 2988@@ -657,25 +723,40 @@ userauth_gssapi(Authctxt *authctxt)
2963 static u_int mech = 0; 2989 static u_int mech = 0;
2964 OM_uint32 min; 2990 OM_uint32 min;
2965 int ok = 0; 2991 int r, ok = 0;
2966+ char *gss_host; 2992+ char *gss_host;
2967+ 2993+
2968+ if (options.gss_server_identity) 2994+ if (options.gss_server_identity)
@@ -2987,9 +3013,9 @@ index 1f4a74cf4..83562c688 100644
2987 while (mech < gss_supported->count && !ok) { 3013 while (mech < gss_supported->count && !ok) {
2988 /* My DER encoding requires length<128 */ 3014 /* My DER encoding requires length<128 */
2989 if (gss_supported->elements[mech].length < 128 && 3015 if (gss_supported->elements[mech].length < 128 &&
2990 ssh_gssapi_check_mechanism(&gssctxt, 3016 ssh_gssapi_check_mechanism(&gssctxt,
2991- &gss_supported->elements[mech], authctxt->host)) { 3017- &gss_supported->elements[mech], authctxt->host)) {
2992+ &gss_supported->elements[mech], gss_host, 3018+ &gss_supported->elements[mech], gss_host,
2993+ options.gss_client_identity)) { 3019+ options.gss_client_identity)) {
2994 ok = 1; /* Mechanism works */ 3020 ok = 1; /* Mechanism works */
2995 } else { 3021 } else {
@@ -3002,29 +3028,20 @@ index 1f4a74cf4..83562c688 100644
3002 if (!ok) 3028 if (!ok)
3003 return 0; 3029 return 0;
3004 3030
3005@@ -752,8 +833,8 @@ input_gssapi_response(int type, u_int32_t plen, struct ssh *ssh) 3031@@ -906,6 +987,54 @@ input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh)
3006 {
3007 Authctxt *authctxt = ssh->authctxt;
3008 Gssctxt *gssctxt;
3009- int oidlen;
3010- char *oidv;
3011+ u_int oidlen;
3012+ u_char *oidv;
3013
3014 if (authctxt == NULL)
3015 fatal("input_gssapi_response: no authentication context");
3016@@ -866,6 +947,48 @@ input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh)
3017 free(lang); 3032 free(lang);
3018 return 0; 3033 return r;
3019 } 3034 }
3020+ 3035+
3021+int 3036+int
3022+userauth_gsskeyex(Authctxt *authctxt) 3037+userauth_gsskeyex(Authctxt *authctxt)
3023+{ 3038+{
3024+ Buffer b; 3039+ struct ssh *ssh = active_state; /* XXX */
3040+ struct sshbuf *b;
3025+ gss_buffer_desc gssbuf; 3041+ gss_buffer_desc gssbuf;
3026+ gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; 3042+ gss_buffer_desc mic = GSS_C_EMPTY_BUFFER;
3027+ OM_uint32 ms; 3043+ OM_uint32 ms;
3044+ int r;
3028+ 3045+
3029+ static int attempt = 0; 3046+ static int attempt = 0;
3030+ if (attempt++ >= 1) 3047+ if (attempt++ >= 1)
@@ -3035,25 +3052,29 @@ index 1f4a74cf4..83562c688 100644
3035+ return (0); 3052+ return (0);
3036+ } 3053+ }
3037+ 3054+
3038+ ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service, 3055+ if ((b = sshbuf_new()) == NULL)
3056+ fatal("%s: sshbuf_new failed", __func__);
3057+ ssh_gssapi_buildmic(b, authctxt->server_user, authctxt->service,
3039+ "gssapi-keyex"); 3058+ "gssapi-keyex");
3040+ 3059+
3041+ gssbuf.value = buffer_ptr(&b); 3060+ if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL)
3042+ gssbuf.length = buffer_len(&b); 3061+ fatal("%s: sshbuf_mutable_ptr failed", __func__);
3062+ gssbuf.length = sshbuf_len(b);
3043+ 3063+
3044+ if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) { 3064+ if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) {
3045+ buffer_free(&b); 3065+ sshbuf_free(b);
3046+ return (0); 3066+ return (0);
3047+ } 3067+ }
3048+ 3068+
3049+ packet_start(SSH2_MSG_USERAUTH_REQUEST); 3069+ if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
3050+ packet_put_cstring(authctxt->server_user); 3070+ (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||
3051+ packet_put_cstring(authctxt->service); 3071+ (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
3052+ packet_put_cstring(authctxt->method->name); 3072+ (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 ||
3053+ packet_put_string(mic.value, mic.length); 3073+ (r = sshpkt_put_string(ssh, mic.value, mic.length)) != 0 ||
3054+ packet_send(); 3074+ (r = sshpkt_send(ssh)) != 0)
3075+ fatal("%s: %s", __func__, ssh_err(r));
3055+ 3076+
3056+ buffer_free(&b); 3077+ sshbuf_free(b);
3057+ gss_release_buffer(&ms, &mic); 3078+ gss_release_buffer(&ms, &mic);
3058+ 3079+
3059+ return (1); 3080+ return (1);
@@ -3063,7 +3084,7 @@ index 1f4a74cf4..83562c688 100644
3063 3084
3064 int 3085 int
3065diff --git a/sshd.c b/sshd.c 3086diff --git a/sshd.c b/sshd.c
3066index fd95b681b..e88185efa 100644 3087index a738c3ab6..2e453cdf8 100644
3067--- a/sshd.c 3088--- a/sshd.c
3068+++ b/sshd.c 3089+++ b/sshd.c
3069@@ -123,6 +123,10 @@ 3090@@ -123,6 +123,10 @@
@@ -3077,7 +3098,7 @@ index fd95b681b..e88185efa 100644
3077 /* Re-exec fds */ 3098 /* Re-exec fds */
3078 #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) 3099 #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1)
3079 #define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) 3100 #define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2)
3080@@ -531,7 +535,7 @@ privsep_preauth_child(void) 3101@@ -536,7 +540,7 @@ privsep_preauth_child(void)
3081 3102
3082 #ifdef GSSAPI 3103 #ifdef GSSAPI
3083 /* Cache supported mechanism OIDs for later use */ 3104 /* Cache supported mechanism OIDs for later use */
@@ -3086,10 +3107,10 @@ index fd95b681b..e88185efa 100644
3086 ssh_gssapi_prepare_supported_oids(); 3107 ssh_gssapi_prepare_supported_oids();
3087 #endif 3108 #endif
3088 3109
3089@@ -1753,10 +1757,13 @@ main(int ac, char **av) 3110@@ -1811,10 +1815,13 @@ main(int ac, char **av)
3090 key ? "private" : "agent", i, sshkey_ssh_name(pubkey), fp);
3091 free(fp); 3111 free(fp);
3092 } 3112 }
3113 accumulate_host_timing_secret(cfg, NULL);
3093+#ifndef GSSAPI 3114+#ifndef GSSAPI
3094+ /* The GSSAPI key exchange can run without a host key */ 3115+ /* The GSSAPI key exchange can run without a host key */
3095 if (!sensitive_data.have_ssh2_key) { 3116 if (!sensitive_data.have_ssh2_key) {
@@ -3100,7 +3121,7 @@ index fd95b681b..e88185efa 100644
3100 3121
3101 /* 3122 /*
3102 * Load certificates. They are stored in an array at identical 3123 * Load certificates. They are stored in an array at identical
3103@@ -2047,6 +2054,60 @@ main(int ac, char **av) 3124@@ -2105,6 +2112,60 @@ main(int ac, char **av)
3104 rdomain == NULL ? "" : "\""); 3125 rdomain == NULL ? "" : "\"");
3105 free(laddr); 3126 free(laddr);
3106 3127
@@ -3161,7 +3182,7 @@ index fd95b681b..e88185efa 100644
3161 /* 3182 /*
3162 * We don't want to listen forever unless the other side 3183 * We don't want to listen forever unless the other side
3163 * successfully authenticates itself. So we set up an alarm which is 3184 * successfully authenticates itself. So we set up an alarm which is
3164@@ -2234,6 +2295,48 @@ do_ssh2_kex(void) 3185@@ -2288,6 +2349,48 @@ do_ssh2_kex(void)
3165 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( 3186 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
3166 list_hostkey_types()); 3187 list_hostkey_types());
3167 3188
@@ -3210,7 +3231,7 @@ index fd95b681b..e88185efa 100644
3210 /* start key exchange */ 3231 /* start key exchange */
3211 if ((r = kex_setup(active_state, myproposal)) != 0) 3232 if ((r = kex_setup(active_state, myproposal)) != 0)
3212 fatal("kex_setup: %s", ssh_err(r)); 3233 fatal("kex_setup: %s", ssh_err(r));
3213@@ -2251,6 +2354,13 @@ do_ssh2_kex(void) 3234@@ -2305,6 +2408,13 @@ do_ssh2_kex(void)
3214 # endif 3235 # endif
3215 #endif 3236 #endif
3216 kex->kex[KEX_C25519_SHA256] = kexc25519_server; 3237 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
@@ -3225,7 +3246,7 @@ index fd95b681b..e88185efa 100644
3225 kex->client_version_string=client_version_string; 3246 kex->client_version_string=client_version_string;
3226 kex->server_version_string=server_version_string; 3247 kex->server_version_string=server_version_string;
3227diff --git a/sshd_config b/sshd_config 3248diff --git a/sshd_config b/sshd_config
3228index 3109d5d73..86263d713 100644 3249index 19b7c91a1..2c48105f8 100644
3229--- a/sshd_config 3250--- a/sshd_config
3230+++ b/sshd_config 3251+++ b/sshd_config
3231@@ -69,6 +69,8 @@ AuthorizedKeysFile .ssh/authorized_keys 3252@@ -69,6 +69,8 @@ AuthorizedKeysFile .ssh/authorized_keys
@@ -3238,10 +3259,10 @@ index 3109d5d73..86263d713 100644
3238 # Set this to 'yes' to enable PAM authentication, account processing, 3259 # Set this to 'yes' to enable PAM authentication, account processing,
3239 # and session processing. If this is enabled, PAM authentication will 3260 # and session processing. If this is enabled, PAM authentication will
3240diff --git a/sshd_config.5 b/sshd_config.5 3261diff --git a/sshd_config.5 b/sshd_config.5
3241index e3c7c3936..c4a3f3cb2 100644 3262index e1b54ba20..a0ac717c7 100644
3242--- a/sshd_config.5 3263--- a/sshd_config.5
3243+++ b/sshd_config.5 3264+++ b/sshd_config.5
3244@@ -636,6 +636,11 @@ The default is 3265@@ -637,6 +637,11 @@ The default is
3245 Specifies whether user authentication based on GSSAPI is allowed. 3266 Specifies whether user authentication based on GSSAPI is allowed.
3246 The default is 3267 The default is
3247 .Cm no . 3268 .Cm no .
@@ -3253,7 +3274,7 @@ index e3c7c3936..c4a3f3cb2 100644
3253 .It Cm GSSAPICleanupCredentials 3274 .It Cm GSSAPICleanupCredentials
3254 Specifies whether to automatically destroy the user's credentials cache 3275 Specifies whether to automatically destroy the user's credentials cache
3255 on logout. 3276 on logout.
3256@@ -655,6 +660,11 @@ machine's default store. 3277@@ -656,6 +661,11 @@ machine's default store.
3257 This facility is provided to assist with operation on multi homed machines. 3278 This facility is provided to assist with operation on multi homed machines.
3258 The default is 3279 The default is
3259 .Cm yes . 3280 .Cm yes .
@@ -3264,20 +3285,20 @@ index e3c7c3936..c4a3f3cb2 100644
3264+.Cm no . 3285+.Cm no .
3265 .It Cm HostbasedAcceptedKeyTypes 3286 .It Cm HostbasedAcceptedKeyTypes
3266 Specifies the key types that will be accepted for hostbased authentication 3287 Specifies the key types that will be accepted for hostbased authentication
3267 as a comma-separated pattern list. 3288 as a list of comma-separated patterns.
3268diff --git a/sshkey.c b/sshkey.c 3289diff --git a/sshkey.c b/sshkey.c
3269index 7712fba23..088872860 100644 3290index 72c08c7e0..91e99a262 100644
3270--- a/sshkey.c 3291--- a/sshkey.c
3271+++ b/sshkey.c 3292+++ b/sshkey.c
3272@@ -122,6 +122,7 @@ static const struct keytype keytypes[] = { 3293@@ -140,6 +140,7 @@ static const struct keytype keytypes[] = {
3273 # endif /* OPENSSL_HAS_NISTP521 */ 3294 # endif /* OPENSSL_HAS_NISTP521 */
3274 # endif /* OPENSSL_HAS_ECC */ 3295 # endif /* OPENSSL_HAS_ECC */
3275 #endif /* WITH_OPENSSL */ 3296 #endif /* WITH_OPENSSL */
3276+ { "null", "null", KEY_NULL, 0, 0, 0 }, 3297+ { "null", "null", NULL, KEY_NULL, 0, 0, 0 },
3277 { NULL, NULL, -1, -1, 0, 0 } 3298 { NULL, NULL, NULL, -1, -1, 0, 0 }
3278 }; 3299 };
3279 3300
3280@@ -210,7 +211,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) 3301@@ -228,7 +229,7 @@ sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep)
3281 const struct keytype *kt; 3302 const struct keytype *kt;
3282 3303
3283 for (kt = keytypes; kt->type != -1; kt++) { 3304 for (kt = keytypes; kt->type != -1; kt++) {
@@ -3287,7 +3308,7 @@ index 7712fba23..088872860 100644
3287 if (!include_sigonly && kt->sigonly) 3308 if (!include_sigonly && kt->sigonly)
3288 continue; 3309 continue;
3289diff --git a/sshkey.h b/sshkey.h 3310diff --git a/sshkey.h b/sshkey.h
3290index 155cd45ae..4e89049f1 100644 3311index 9060b2ecb..0cbdcfd74 100644
3291--- a/sshkey.h 3312--- a/sshkey.h
3292+++ b/sshkey.h 3313+++ b/sshkey.h
3293@@ -63,6 +63,7 @@ enum sshkey_types { 3314@@ -63,6 +63,7 @@ enum sshkey_types {