Re: Question on Kerberos (GSSAPI) auth

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

 





On 1/17/2017 3:18 PM, Ron Frederick wrote:
On Jan 17, 2017, at 9:57 AM, Douglas E Engert <deengert@xxxxxxxxx <mailto:deengert@xxxxxxxxx>> wrote:
On 1/16/2017 2:09 PM, Ron Frederick wrote:
I’m working on an implementation of “gssapi-with-mic” authentication for my AsyncSSH package and trying to get it to interoperate with OpenSSH. I’ve gotten it working, but there seems to be a
discrepancy between the OpenSSH implementation and RFC 4462. Specifically, RFC 4462 says the following in section 3.4:

  Since the user authentication process by its nature authenticates
  only the client, the setting of mutual_req_flag is not needed for
  this process.  This flag SHOULD be set to "false".

Note it says "SHOULD" not "MUST". Previous versions of SSH clients and mods to OpenSSH
have always set mutual_req_flag.

[Ron] Thanks - I did see that, but shouldn't that mean it should work correctly when my client is connecting to sshd whether or not I set the mutual auth flag? That doesn’t appear to be the case.

Are you saying that OpenSSH’s sshd is intentionally rejecting the request when it sees the mutual_auth flag is not set? I see some code in OpenSSH which suggests it might be trying to do that, but I’m
never actually getting an auth failure here. The connection just hangs.

When tracing it, it looks like OpenSSH’s sshd feeds the token I send into its accepting context and gets back no token to send (which would be correct), but then it never seems to complete the rest of
the state machine when I send the final message from the client.

It may have a token to send, input_gssapi_token() calls ssh_gssapi_accept_ctx(...,&send_tok,...)
then later in 2 places  if (send_tok.length != 0)  it sends a packet with the token.
The code is also setup to handle multiple tokens being exchanged.


The issue may be the way the code is structured:

        /* Now, if we're complete and we have the right flags, then
         * we flag the user as also having been authenticated
         */

        if (((flags == NULL) || ((*flags & GSS_C_MUTUAL_FLAG) &&
            (*flags & GSS_C_INTEG_FLAG))) && (ctx->major == GSS_S_COMPLETE)) {
                if (ssh_gssapi_getclient(ctx, &gssapi_client))
                        fatal("Couldn't convert client name");
        }

        return (status);

Yes it looks like it requires GSS_C_MUTUAL_FLAG and GSS_C_INTEG_FLAG
and if its not, then it never calls ssh_gssapi_getclient and does not give an error message either
so the connection hangs. I think you have uncovered a bug.

So I would recommend you have your client set GSS_C_MUTUAL_FLAG to avoid the issue.


The fatal() call there only happens when ssh_gssapi_getclient() fails, but not when one of the outer conditions fails. Normally, when the state is not complete, just returning here would be fine, but
if the context is already complete and it’s just the flags that are wrong, no error is returned. I would still expect some reaction when it later received the follow-on message from the client, though.


However, when I try to have my implementation not set this flag and just send a GSSAPI_TOKEN message immediately followed by a GSSAPI_MIC message without waiting for a server token (since the
authentication is complete as soon as the client token is sent when mutual auth is disabled), I get a failure from OpenSSH:


From the above comment, you are assuming that there will be no other tokens exchanged.

After the gss_init_sec_context, you need to send any token from gss_init_sec_context
and if the status in not complete (or not an error) wait to receive the next token and call gss_init_sec_context
in a loop.

GSS is not Kerberos specific and some other gss mechanisms will exchange multiple tokens.

[Ron] Understood. However, when I don’t set the mutual_auth flag, my client context initialized with gss_init_sec_context() sets the “complete” flag immediately after I create it and get the first
outbound token out of it. It does not return the “continue” result indicating that it wants a token back from the server. So, the only thing the code can do at that point is to send
either MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE or MSG_USERAUTH_GSSAPI_MIC, depending on whether the integrity flag ends up set in the completed context, and that doesn’t work with OpenSSH’s sshd. I’m
only able to get it to work if I set the mutual_auth flag. In that case, I get the outbound token and a “continue” result to wait for sshd’s token, which I do and then feed to the context. After that,
both sides return “complete” and I’m able to send MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE or MSG_USERAUTH_GSSAPI_MIC to finish the authentication.

Perhaps there's something else I’m missing when I create my client security context. However, if that’s the case, I haven’t figured out what it is.

When creating the client context, I’m also setting the integrity flag and have an option to set the delegate_creds flag (and it works both with & without that, properly forwarding the creds when it is
set), and I’m also explicitly setting the mechanism to the Kerberos OID.
--
Ron Frederick
ronf@xxxxxxxxxxxxx <mailto:ronf@xxxxxxxxxxxxx>




--

 Douglas E. Engert  <DEEngert@xxxxxxxxx>

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@xxxxxxxxxxx
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev




[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux