Question on Kerberos (GSSAPI) auth

Douglas E Engert deengert at gmail.com
Wed Jan 18 13:01:31 AEDT 2017



On 1/17/2017 3:18 PM, Ron Frederick wrote:
> On Jan 17, 2017, at 9:57 AM, Douglas E Engert <deengert at gmail.com <mailto:deengert at gmail.com>> 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 at timeheart.net <mailto:ronf at timeheart.net>
>
>
>

-- 

  Douglas E. Engert  <DEEngert at gmail.com>



More information about the openssh-unix-dev mailing list