Re: Bus authentication on Windows v2.0
LRN <[email protected]>
| Newsgroups | gmane.comp.freedesktop.dbus |
|---|---|
| Message-ID | <[email protected]> |
On 06.06.2016 14:46, Simon McVittie wrote: > On 03/06/16 20:30, LRN wrote: >> I think i can make SSPI-based authentication work. However, i'm unsure >> how >> to frame the data exchange between two processes. >> If implemented with no explicit leaning toward D-bus, it would have to >> exchange auth data in-band (in place of the single NUL byte, which on >> *nix >> is accompanied by ancillary auth data; Windows does not allow ancillary >> data for streaming TCP sockets). > > If there is already a SASL mechanism for SSPI, please use it. If not, > you're welcome to invent a DBUS_SSPI SASL mechanism with whatever > in-band data exchange you need. > The way i understand this is that SASL is a framework, and that any authentication mechanism that fits into this framework is a SASL mechanism (i think D-bus source code refers to such mechanisms as "SASL profiles"). SSPI seems to be roughly the same thing as SASL. SSPI provides a set of generic functions, which both the client and the server call to initialize the authentication state, then to generate opaque data buffers that they exchange until authentication either succeeds or fails. If it succeeds, SSPI can then be used to sign or encrypt further data. SSPI does have any specs on how the data buffers are exchanged - as long as both parties have an agreed-upon method of passing buffers to each other, SSPI will work just fine. This is how SSPI works in practice (NTLM is being used): SERVER: calls AcquireCredentialsHandle() to get its own credentials (or someone else's credentials, if name/password are provided or if SERVER is root). CLIENT: calls AcquireCredentialsHandle() to get its own credentials (or someone else's credentials, if name/password are provided or if CLIENT is root) CLIENT: calls InitializeSecurityContext(), giving it nothing; InitializeSecurityContext() says "keep authenticating" and generates 55 bytes of opaque data CLIENT: sends 55 bytes of opaque data to SERVER SERVER: receives 55 bytes of opaque data from the CLIENT SERVER: calls AcceptSecurityContext(), giving it 55 bytes of opaque data; AcceptSecurityContext() says "keep authenticating" and generates 148 bytes of opaque data SERVER: sends 148 bytes of opaque data to CLIENT CLIENT: receives 148 bytes of opaque data from SERVER CLIENT: calls InitializeSecurityContext(), giving it 148 bytes of opaque data; InitializeSecurityContext() says "authentication succeeded" and generates 88 bytes of opaque data CLIENT: sends 88 bytes of opaque data to SERVER SERVER: receives 88 bytes of opaque data from CLIENT SERVER: calls AcceptSecurityContext(), giving it 88 bytes of opaque data; AcceptSecurityContext() says "authentication succeeded" and generates 0 bytes of opaque data CLIENT is now authenticated (SERVER is also authenticated, if SSP supported server authentication) An SSPI mechanism is called "SSP". There can be any number of SSPs available (for example, a cryptographic dongle might provide an SSP), but most people seem to use MS SSPs that are guaranteed to be present - NTLM, Kerberos, Negotiate and Digest. There's also CredSSP, which, AFAIU, uses certificates. All SSPI calls (starting from AcquireCredentialsHandle()) take SSP name (a string) as an argument. Therefore, both parties must either use a pre-agganged SSP, or agree upon an SSP before they start authenticating. Once authentication succeeds, both parties can use the security context object (which gets created during the exchange) to do stuff or query information from it. I'm a bit unsure what kind of information can be queried from a security context that is created during Digest or CredSSP exchanges. I also don't know what kind of credentials Digest SSP uses (AcquireCredentialsHandle() accepts username, domain and password, but i don't know how it uses them). Digest SSP lean heavily towards HTTP, i'm not sure how they apply to D-bus. I'm more interested in NTLM and Kerberos SSPs. They use Windows access token objects as credentials (when doing NTLM authentication, the client calling AcquireCredentialsHandle() gives it NULL for most arguments, as all necessary authentication data is taken from its currently-used access token), and once security context object is created, server is able to query an access token object from it. Access tokens are the ultimate authentication objects in NT - one can query user SID from them (user SID uniquely identifies a user), for example, and (if the client allowed it) use them to impersonate the client (to either act in client's name, or ask the system whether the client has access to a particular system object). As a convenience, "Negotiate" SSP results in either NTLM or Kerberos SSP being used under the hood, depending on whether Kerberos is supported or not. This way client and server can use more secure Kerberos auth, if it's available, and fall back on NTLM, if it's not. In practice this requires some forethought, as Kerberos is rather picky (one needs to, for example, supply a "principal" name to AcquireCredentialsHandle(); NTLM doesn't really care about that). Kerberos supports mutual authentication (server must have valid credentials), NTLM does not (and is thus considered insecure when used over the network, as malicious 3rd party can steal real NTLM traffic and use it to authenticate to some other server). Here's how this could work with D-Bus: C: AUTH S: REJECTED SSPI_KERBEROS SSPI_NTLM EXTERNAL ANONYMOUS DBUS_COOKIE_SHA1 <C figures out that it supports SSPI_NTLM> <C calls: AcquireCredentialsHandleW (NULL, L"NTLM", SECPKG_CRED_OUTBOUND, 0, 0, 0, 0, &cred_object, &lifetime) > <C calls: InitializeSecurityContextW (&cred_object, 0, 0, ISC_REQ_IDENTIFY, 0, SECURITY_NATIVE_DREP, 0, &sec_context, &output_buffer, &attributes, &lifetime) > <C optionally (depends on what InitializeSecurtyContextW() returns) calls: CompleteAuthToken (&sec_context, &output_buffer) > C: AUTH SSPI_NTLM <U hex-encoded bytes from output_buffer> <S calls: AcquireCredentialsHandleW (NULL, L"NTLM", SECPKG_CRED_INBOUND, 0, 0, 0, 0, &cred_object, &lifetime) > <S calls: AcceptSecurityContext (&cred_object, 0, &input_buffer, 0, SECURITY_NATIVE_DREP, &sec_context, &output_buffer, &attributes, &lifetime) > <S optionally (depends on what AcceptSecurtyContext() returns) calls: CompleteAuthToken (&sec_context, &output_buffer) > S: DATA <Y hex-encoded bytes from output_buffer> <C calls: InitializeSecurityContextW (&cred_object, &sec_context, 0, ISC_REQ_IDENTIFY, 0, SECURITY_NATIVE_DREP, &input_buffer, &sec_context, &output_buffer, &attributes, &lifetime) > <C optionally (depends on what InitializeSecurtyContextW() returns) calls: CompleteAuthToken (&sec_context, &output_buffer) > <if output_buffer is not empty:> C: DATA <W hex-encoded bytes from output_buffer> <S calls: AcceptSecurityContext (&cred_object, &sec_context, &input_buffer, 0, SECURITY_NATIVE_DREP, &sec_context, &output_buffer, &attributes, &lifetime) > <S optionally (depends on what AcceptSecurtyContext() returns) calls: CompleteAuthToken (&sec_context, &output_buffer) > <if output_buffer is not empty:> C: DATA <Z hex-encoded bytes from output_buffer> ... S: OK 1234deadbeef C: BEGIN On the server side the exchange ends when the value returned by AcceptSecurityContext() does not have SEC_I_CONTINUE_NEEDED or SEC_I_COMPLETE_AND_CONTINUE bits set (server still needs to send any output_buffer back to the client, if it's not empty; for NTLM, it is empty though). On the client side the exchange ends when the value returned by InitializeSecurityContextW() does not have SEC_I_CONTINUE_NEEDED or SEC_I_COMPLETE_AND_CONTINUE bits set (client still needs to send any output_buffer back to the server, if it's not empty; for NTLM, it is not empty). For D-bus this means the following: * If the bits (see above) are not set, you're done. * If you're done, don't accept DATA anymore (whether it should be just discarded or it should be treated as protocol error, i'm not sure). * If there's a non-empty ouptut buffer, send it as DATA * If there's an empty output buffer, and you're server, send OK and proceed. * If there's an empty output buffer, and you're client, wait for OK (i guess?) -- O< ascii ribbon - stop html email! - www.asciiribbon.org _______________________________________________ dbus mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dbus
signature.asc
(application/pgp-signature, 473 B)
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQEcBAEBCAAGBQJXVX3qAAoJEOs4Jb6SI2Cw4NQIAN3rGyot3DVjuSRss4fGntRK mJ9e7LTERR/uoXtBMe66OVg2Y8sRUCEwGLrcp9ljZ62Ex3/GeskqcoTCZcW41UiD 518Nmito94NrYpKSk3/9i4ujlGi/+2D7m9pYDvfSY1GKtltTGMi4wr7ZTogfwlrz LW6dwAaLTnqB6TrPnNmvuBDA8YyuTqXfug3HZzcMfMtv9gwm/bxcc33GlVimeOD5 jnPaQm4JBoFUsLXvHA8YEZD68hRfqMp+x6Snu2b0qbqwqxljClMh+SdpyIr6vkbv 9iZw2vRBTZl2y0Y4Rw//YxnlidcLQSmtAKGp8UqmvXpediaB89KC80GWyDr310o= =32Qt -----END PGP SIGNATURE-----