On Jan 17, 2017, at 9:57 AM, Douglas E Engert <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.
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);
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