Bus authentication on Windows v2.0

LRN lrn1986 at gmail.com
Mon Jun 6 19:31:50 UTC 2016


On 06.06.2016 20:26, Simon McVittie wrote:
> If we're lucky, someone else might already have defined a generic way to
> do arbitrary SSPI authentication over SASL-supporting protocols;

Quick search for "SSPI" and "SASL" turned up nothing.

> or if
> not, you could define one with a DBUS_ prefix, perhaps
> DBUS_WINDOWS_SSPI, or a family of them, perhaps DBUS_WINDOWS_SSPI_NTLM
> and so on. Or you could use NTLM, KERBEROS_5 and/or GSSAPI if you can
> work out how to do that (preferably in an interoperable way).

In my hypothetical example i've used SSPI_ prefix (such as SSPI_NTLM), to
ensure that both parties understand that SSPI is being used (this can be
significant, for example, for Kerberos, which can have multiple
incompatible implementations; SSPI_Kerberos is, hopefully, unambiguous).
DBUS_WINDOWS_SSPI_* would work as well (there's no length limit on
mechanism name, is there? also, should it always be all all-caps?)

> 
> <https://en.wikipedia.org/wiki/Security_Support_Provider_Interface#Comparison>
> hints at SSPI being a Microsoft variant of GSSAPI, in fact; so if
> DBUS_WINDOWS_SSPI isn't the same as RFC 4752, it should probably be
> closely modelled on that RFC.

I should probably say upfront that i have neither understanding of
Kerberos, nor experience in using it. If i write anything, it'll be
primarily using NTLM, which would be sufficient for authenticating
processes on a single machine.

Judging by the things i've found on the internet, using Kerberos just
requires being more specific in passing arguments ("principal", "target")
to SSPI functions. Otherwise the flow is the same.

> 
> What we're ideally looking for is the best way for the client to prove
> to a trusted server that its SID (Windows equivalent of a uid) takes a
> particular claimed value.

Right. This was the goal.

> If we can also determine the process ID, which
> would mean the authenticated identity is a (SID, PID) pair analogous to
> the (primary UID, PID) pairs we get on many Unix platforms including
> Linux, that would be even better.

I haven't seen any provisions for PID in SSPI. I can imagine why - MS is
not too big on processes, but is big on threads. For example, many services
run within the same svchost.exe process, in different threads. In such
environment proving your PID does not carry any meaning. It might be more
meaningful to look at "Session ID" and "Integrity Level" (which say less
about "who" runs the client, and more about "where" the client is running).

Either way, i can't say i'm confident that PID will be available. Well,
there *is* the current dbus code that infers PID from socket table - that
isn't going anywhere, but it's obviously a (clever) hack.

>> 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.
> 
> In dbus, you'd store the security context object in the DBusCredentials
> object, replacing or accompanying the "char *windows_sid" that we
> already have.

Security context handle is useful for further SSPI API calls (to
[en|de]crypt and sign/verify), but for authentication purposes it can do
only three things, AFAICS:
1) Be queried for an access token
2) Be used for impersonation, which is as good as having an access token,
because once you've impersonated, you can query the access token you're
currently using for impersonation (i think that (2) is the same as doing
(1) and then calling ImpersonateLoggedOnUser(access_token))
3) Be queried for username. Again, you can query the access token and then
get user SID from it, then get username from SID (although stopping at SID
is probably wiser - not all users have usernames, but all users do have a
user SID); querying username from security context directly is only useful
for SSPs that do not provide an access token, and these are probably not
useful anyway.

> In GDBus, you'd probably put it in a GCredentials object.

Right now i'm leaning towards declaring GCredentials to be "*NIX only" API.
It (or maybe just the code that uses it) focuses too much on carrying
credentials as ancillary data for a nul byte sent over *NIX domain socket,
and verified by the kernel.
Plugging SSPI-based GCredentials negotiation (if i were to implement that)
into existing glib-based application (which by itself won't go without code
modifications, as GCredentials are currently sent over GUnixConnection
explicitly) will just violate the protocol (it does violate D-Bus protocol,
AFAIU).
And any platform-dependent code for comparing and managing identity
information obtained from access tokens (which is what you probably had in
mind when you suggested putting that info into GCredentials object) would
just go into GDbus SSPI-based authentication mechanism code, which will be
platform-dependent anyway.

>> 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)
> 
> What needs to be in a principal name? It would probably be possible to
> construct one from the SID, machine name, NT domain and bus GUID?

/me shrugs.
Maybe using NULL principal would also work. Some ML posts and documents
that i've found suggest that it *can* work for MS Kerberos SSP. Other blog
posts describe how principal name can be constructed from username/hostname
and realm, and how to query that info on Windows. Some other sources
indicate that principal name can be something custom, defined by domain
administrator.
Either way, i wouldn't have been able to test this even if i wanted to - i
don't have the proper infrastructure to do Kerberos authentication.

>> * 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?)
> 
> It should be possible for the client to send "DATA \r\n" to indicate
> that it has nothing more to say?

If D-bus allows that, then that's certainly a good thing to do. That way a
participant is "done" when it got the appropriate return value from the
SSPI function it's been calling *and* when the other party sent an empty DATA.

-- 
O< ascii ribbon - stop html email! - www.asciiribbon.org

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/dbus/attachments/20160606/7797f458/attachment.sig>


More information about the dbus mailing list