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". 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: Failed gssapi-with-mic for ronf from 74.93.13.193 port 64645 ssh2 If I turn on mutual authentication in my client context (going against the recommendation in the RFC) and wait for a token to come back from the server before I send the GSSAPI_MIC message, the authentication succeeds. Looking at the OpenSSH source code, I see that it always unconditionally enables mutual authentication in the client contexts it allocates. In ssh_gssapi_init_ctx, it does the following: ctx->major = gss_init_sec_context(&ctx->minor, GSS_C_NO_CREDENTIAL, &ctx->context, ctx->name, ctx->oid, GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, 0, NULL, recv_tok, NULL, send_tok, flags, NULL); I don?t see anything in the RFC 4462 errata about this recommendation having changed. Does anyone know why OpenSSH enables this? It makes sense for GSSAPI key exchange (which OpenSSH doesn?t seem to implement), but not for GSSAPI authentication. -- Ron Frederick ronf at timeheart.net
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.> > 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.> Failed gssapi-with-mic for ronf from 74.93.13.193 port 64645 ssh2 > > If I turn on mutual authentication in my client context (going against the recommendation in the RFC) and wait for a token to come back from the server before I send the GSSAPI_MIC message, the authentication succeeds. > > Looking at the OpenSSH source code, I see that it always unconditionally enables mutual authentication in the client contexts it allocates. In ssh_gssapi_init_ctx, it does the following: > > ctx->major = gss_init_sec_context(&ctx->minor, > GSS_C_NO_CREDENTIAL, &ctx->context, ctx->name, ctx->oid, > GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, > 0, NULL, recv_tok, NULL, send_tok, flags, NULL); > > I don?t see anything in the RFC 4462 errata about this recommendation having changed. Does anyone know why OpenSSH enables this? It makes sense for GSSAPI key exchange (which OpenSSH doesn?t seem to implement), but not for GSSAPI authentication. >-- Douglas E. Engert <DEEngert at gmail.com>
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
Apparently Analagous Threads
- Question on Kerberos (GSSAPI) auth
- Pending OpenSSH release: contains Kerberos/GSSAPI changes
- auth problems with samba 4.4.6 (winbind) *(suppected bug)
- Upgrade from 4.11.6 to 4.12.2 created authentication issues
- [samba4] crash of winbind after "ls -l /usr/local/samba/var/locks/sysvol"