]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
upstream: Fix multiple RFC 4462 (GSSAPIAuthentication) compliance
authordjm@openbsd.org <djm@openbsd.org>
Mon, 6 Jul 2026 07:53:30 +0000 (07:53 +0000)
committerDamien Miller <djm@mindrot.org>
Mon, 6 Jul 2026 07:55:32 +0000 (17:55 +1000)
problems

1) Remove an early failure return for GSSAPI authentication attempts
made for invalid accounts that yielded different behaviour for
valid vs invalid accounts.

2) Fix a situation where some GSSAPI requestes were not correctly
subjected to MaxAuthTries.

3) Fix a moderate pre-authentication resource DoS related to #2.

Add missing logging for error cases.

Report and fixes from Manfred Kaiser, milCERT AT

OpenBSD-Commit-ID: ca0acdd64eea435d6f89534538a9eb404a5629d3

auth2-gss.c

index 355926afcd6e1307a0cf022036afd4e77fdaa899..85251b7d0b5721b3d2cb875d171d400cad9ec415 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-gss.c,v 1.40 2026/07/06 07:44:48 djm Exp $ */
+/* $OpenBSD: auth2-gss.c,v 1.41 2026/07/06 07:53:30 djm Exp $ */
 
 /*
  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -111,12 +111,6 @@ userauth_gssapi(struct ssh *ssh, const char *method)
                return (0);
        }
 
-       if (!authctxt->valid || authctxt->user == NULL) {
-               debug2_f("disabled because of invalid user");
-               free(doid);
-               return (0);
-       }
-
        if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&ctxt, &goid))) {
                if (ctxt != NULL)
                        ssh_gssapi_delete_ctx(&ctxt);
@@ -178,8 +172,14 @@ input_gssapi_token(int type, uint32_t plen, struct ssh *ssh)
                            (r = sshpkt_send(ssh)) != 0)
                                fatal_fr(r, "send ERRTOK packet");
                }
+               logit("Failed gssapi-with-mic for %s%.100s "
+                   "from %.200s port %d ssh2",
+                   authctxt->valid ? "" : "invalid user ",
+                   authctxt->user,
+                   ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
                authctxt->postponed = 0;
                ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
+               ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
                userauth_finish(ssh, 0, "gssapi-with-mic", NULL);
        } else {
                if (send_tok.length != 0) {
@@ -191,14 +191,18 @@ input_gssapi_token(int type, uint32_t plen, struct ssh *ssh)
                                fatal_fr(r, "send TOKEN packet");
                }
                if (maj_status == GSS_S_COMPLETE) {
-                       ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
-                       if (flags & GSS_C_INTEG_FLAG)
-                               ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_MIC,
+                       ssh_dispatch_set(ssh,
+                           SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
+                       /* note: keep ERRTOK handler as per RFC 4462 s3.4 */
+                       if (flags & GSS_C_INTEG_FLAG) {
+                               ssh_dispatch_set(ssh,
+                                   SSH2_MSG_USERAUTH_GSSAPI_MIC,
                                    &input_gssapi_mic);
-                       else
+                       } else {
                                ssh_dispatch_set(ssh,
                                    SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
                                    &input_gssapi_exchange_complete);
+                       }
                }
        }
 
@@ -210,10 +214,6 @@ static int
 input_gssapi_errtok(int type, uint32_t plen, struct ssh *ssh)
 {
        Authctxt *authctxt = ssh->authctxt;
-       Gssctxt *gssctxt;
-       gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
-       gss_buffer_desc recv_tok;
-       OM_uint32 maj_status;
        int r;
        u_char *p;
        size_t len;
@@ -221,26 +221,21 @@ input_gssapi_errtok(int type, uint32_t plen, struct ssh *ssh)
        if (authctxt == NULL)
                fatal("No authentication or GSSAPI context");
 
-       gssctxt = authctxt->methoddata;
-       if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 ||
+       /* Minimal error handling - just cancel auth and return FAILURE */
+       if ((r = sshpkt_get_string_direct(ssh, NULL, NULL)) != 0 ||
            (r = sshpkt_get_end(ssh)) != 0)
                fatal_fr(r, "parse packet");
-       recv_tok.value = p;
-       recv_tok.length = len;
-
-       /* Push the error token into GSSAPI to see what it says */
-       maj_status = mm_ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
-           &send_tok, NULL);
-
-       free(recv_tok.value);
 
-       /* We can't return anything to the client, even if we wanted to */
+       logit("Failed gssapi-with-mic for %s%.100s from %.200s port %d ssh2",
+           authctxt->valid ? "" : "invalid user ",
+           authctxt->user,
+           ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
+       authctxt->postponed = 0;
        ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
        ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
-
-       /* The client will have already moved on to the next auth */
-
-       gss_release_buffer(&maj_status, &send_tok);
+       ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
+       ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
+       userauth_finish(ssh, 0, "gssapi-with-mic", NULL);
        return 0;
 }