Visar inlägg med etikett gss-api. Visa alla inlägg
Visar inlägg med etikett gss-api. Visa alla inlägg

måndag 5 oktober 2009

The use of of gss_accept_sec_context (ASC)

This is continuation of the previous article about ISC.

The gssapi function ASC (gss_accept_sec_context) is also complicated,
function, one can argue ASC is simpler then ISC since ASC only takes
11 arguments.
OM_uint32
gss_accept_sec_context
(OM_uint32 * /*minor_status*/,
gss_ctx_id_t * /*context_handle*/,
const gss_cred_id_t /*acceptor_cred_handle*/,
const gss_buffer_t /*input_token_buffer*/,
const gss_channel_bindings_t /*input_chan_bindings*/,
gss_name_t * /*src_name*/,
gss_OID * /*mech_type*/,
gss_buffer_t /*output_token*/,
OM_uint32 * /*ret_flags*/,
OM_uint32 * /*time_rec*/,
gss_cred_id_t * /*delegated_cred_handle*/
);

Again, just like ISC the main problem is that consumers if this interface tries to pass in too much information, less is usually better.

Not passing in a credential


If consumers instead of passing a credential checked the name afterward it would work in more situations. For example, using the GSSAPI Kerberos mech as an acceptor: when the client connects the server doesn't know what name the client used, and if the server specifies a credential (thus an implicitly a name) the client have selected another name, ASC will fail.

Do when do server and client not patch up on names ? There are plent of examples, where: HTTP/www, http/www.example.com is the one to start with. Kerberos is case sensitive and client might expect aliases to work.

The logic flow for ASC


The flow of a server part of gss-api negotiation looks like this:
in = null;
do {
ret = gss_accept_sec_context(in, out);
if (GSS_ERROR(ret))
abort();
send_message(out);
if (ret == GSS_C_CONTINUE)
in = read_message();
} while (ret == GSS_C_CONTINUE);

if (check_return_flags())
abort();

if (check_that_name_is_ok(ctx))
abort();

/* done */

lördag 5 september 2009

The use of of gss_init_sec_context (ISC)

ISC


Lets start to dissect some of the GSS-API functions, first out in gss_init_sec_context (ISC for short).

The gssapi function ISC is a very complicated function, just look at the 13 arguments it takes, and for every round its call in an authentication some of them need to be same, and some need to change.
OM_uint32
gss_init_sec_context
(OM_uint32 * /*minor_status*/,
const gss_cred_id_t /*initiator_cred_handle*/,
gss_ctx_id_t * /*context_handle*/,
const gss_name_t /*target_name*/,
const gss_OID /*mech_type*/,
OM_uint32 /*req_flags*/,
OM_uint32 /*time_req*/,
const gss_channel_bindings_t /*input_chan_bindings*/,
const gss_buffer_t /*input_token*/,
gss_OID * /*actual_mech_type*/,
gss_buffer_t /*output_token*/,
OM_uint32 * /*ret_flags*/,
OM_uint32 * /*time_rec*/
);

In that 13 that lays the confusion, to make make ISC work you only need to pass in 7 arguments, you can leave the other 6 to a default values, in fact, this will probably make it work better in most cases.
gss_init_sec_context(&minor_status, GSS_C_NO_CREDENTIAL, &ctx, &target_name, GSS_C_NO_OID,
GSS_C_MUTUAL_FLAG, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, &in, NULL, &out, &ret_flags, NULL);

You need to check that ret_flags is what you wanted in flags, the reason is that the server might downgarde your security to a level you don't find acceptiable, like no encryption (leaving out GSS_C_CONF_FLAG).

The logic flow for ISC


The flow of a client part of gss-api negotiation looks like this:
name = gss_import_name("service@server", GSS_C_NT_HOSTBASED_SERVICE);

if (client_name && client_name_type) {
cname = gss_import_name(client_name, client_name_type);
cred = gss_acquire_cred(cname, GSS_C_INITIATE);
} else
cred = NULL;

in = null;
do {
ret = gss_init_sec_context(in, out);
if (GSS_ERROR(ret))
abort();
send_message(out);
if (ret == GSS_C_CONTINUE)
in = read_message();
} while (ret == GSS_C_CONTINUE);

if (check_return_flags())
abort();

/* done */

Next out is gss_accept_sec_context (ASC)


ASC is the awesome function, mostly every time we have to fix 3rd party code that uses ASC the resolution is mostly always to remove code

torsdag 25 december 2008

Fetching tickets over EAP

Or how to talk to the Kerberos KDC over your appliation protocol

Talking to the KDC with no network


Sometimes you want to talk to the KDC when there is limited or direct network. Or your application simply knows better how to communicate with the KDC.

For example, if it was possible to use EAP with GSS-API so it run Kerberos initial ticket fetching over the EAP channel, this is not so far off given the new IAKERB gss-api mechanism that Larry Zhu is proposing (currently in last call). With his mechanism you can talk to the KDC and get initial and service tickets for a service over a gss-api channel.

First the when you login to the network using EAP the network topology looks like this:
Client ---[EAP over wavelan]---> Wavelan access point ---[radius]---> Radius server

First you authenticate to the radius server, and the radius server tells the access point to let you out on the network, and then you get a IP address from the DHCP server. So why doesn't this fit together with the Kerberos stack.

In the classial appliation the world looks like this:
Application -> GSS-API -> Kerberos mechanism <--[Kerberos protocol]--> KDC
|
[token]
|
appl <---------/
|
|
\
------[application protocol]----> server

But when you are in an about to use EAP to login to the network, theKerberos mechanism have no way to talk to the KDC, the only channel you have EAP the channel to the Radius server.

So the obvious solution is to let the Kerberos mechanism talk though the EAP channel over the the Radius server, and have the radius server forward over the packets over the the KDC.

The problem with Kerberos krb5_get_init_creds()


The Kerberos function krb5_get_init_creds() is that it expect to be able to resolve the DNS information to the KDC and then talk to the KDC to get initial tickets, so deep inside the function there is a function that will send of a packet the the KDC.

As described above, this wont work since the Kerberos library have no network connection to the KDC, it have to talk to the KDC thought the GSS-API layer.

The replacement function, krb5_init_creds()


So the new function krb5_init_creds() and krb5_init_creds_step() instead of sending of the packet to the KDC, return the packet that is supposed to be sent off to the KDC, and the expect the caller to call
krb5_init_creds_step() with whatever the KDC returned. There is a helper function that does all this: krb5_init_creds_get().

So krb5_get_init_creds_password() is now implmented in terms of the new functions. And is as described below.
krb5_get_init_creds_password()
{
krb5_init_creds_init(&ctx);
krb5_init_creds_get(ctx);
krb5_init_creds_free(ctx);
}

krb5_init_creds_get(ctx)
{
while(1) {
ret = krb5_init_creds_step(ctx,inpacket, &outpacket);
if (ret != CONTINUE)
break;
krb5_send_to_kdc(outnpacket, &inpacket);
}
}

GSS-API usage of krb5_init_creds_step()


This way GSS-API mech can take advantage of the split stack and instead of sending the packet to the KDC, send of the packet over to GSS-API peer and when it get back the reply, stuff the answer back into krb5_init_creds_step() to continue the dance. 

Application -> GSS-API <--> Kerberos mechanism
                 |
[token]
|
appl <---------/
|
|
\
------[application protocol]----> server <--[Kerberos protocol]--> KDC

Now, someone just need to implement IAKERB to use this functionallity.

söndag 19 oktober 2008

ok-as-delegate and GSS-API

Background


To forward your Kerberos credential from a gss-api client to a server you turn on the flag GSS_C_DELEG_FLAG. This will, as part of the authentication, forward your tickets to the server.

The problem is that you don't want to turn on this just for every server your what to authenticate to, because most of them should probably not be trusted with your tickets.

To solve this Microsoft added an extention to the Kerberos, that was added to RFC4120 (The Kerberos protocol RFC). The extention is called ok-as-delegate and is a ticket flag. Using the flag the client can determine that the system administrator thinks about the host, if it should be delegated too or not.

Non Microsoft sites have been using GSS-API implementations that doesn't honor the flag ok-as-delegate and most of them never has set the ok-as-delegate flag. In some cases the sites are using Kerberos implementations that doesn't even support setting the ok-as-delegate flag in the Kerberos database.

Users at these sites have grown accustomed to the behavior ok GSS_C_DELEG_FLAG and changing the GSS-API implementation behind them to make GSS_C_DELEG_FLAG honor the ok-as-delegate flag will only make people upset.

New flag


What we can do it introduce a new flag GSS_C_DELEG_POLICY_FLAG that is defined to honor the flag ok-as-delegate.

The flag GSS_C_DELEG_POLICY_FLAG is a local flag that is never seen on the wire. And, its only used by the initator, the acceptor never see the flag.

There are four cases where GSS_C_DELEG_POLICY_FLAG and GSS_C_DELEG_FLAG interact with each other and the resulting return flags.

  • Neither flag set
    do nothing with regard to delegation

  • GSS_C_DELEG_FLAG set
    always try go delegate and set GSS_C_DELEG_FLAG in the return flags if successful

  • GSS_C_DELEG_POLIY_FLAG set
    try to delegate if ok-as-delegate is set, delegate and set GSS_C_DELEG_FLAG and GSS_C_DELEG_POLICY_FLAG in the return flags if successful

  • GSS_C_DELEG_FLAG and GSS_C_DELEG_POLIY_FLAG setalways try to delegate, set GSS_C_DELEG_FLAG if successful in the return flags if successful. Also, if successful and ok-as-delegate was set on the service ticket, set GSS_C_DELEG_POLICY_FLAG in the return flags.


Cross realm ?


What is missing is how ok-as-delegate and GSS_C_DELEG_POLICY_FLAG should work in the cross realm case. RFC4120 is quiet on this issue, the flag on ok-as-delegate doesn't mean anything on the cross realm tgt. The question is how this should be dealt with.

The obvious answer is define a meaning on the cross realm tgt ticket for ok-as-delegate, but how will that interact with existing deployments.

Current behavior is for released MIT and heimdal is that the flag is ignored. For Microsoft clients is that they honor the flag for windows domains, and to external realms they allow delegation is a flag is set on the realm configuration on the client.

Any good ideas out there ?

söndag 5 oktober 2008

Adding support for referrals in GSS-API

We can implement referrals support for Kerberos mk_req API or do it for GSS-API. For me its an easy choice, most consumers uses GSS-API, lets go for that.

DNS canonicalition happens when we pass in a GSS_C_NT_HOSTBASED_SERVICE based name into gss_import_name(), so its only that case we really need to care about. DNS canonlisation is done by krb5_sname_to_principal(), see documentation in Heimdal trunk.

The simple solution is that in gss_import_name() we the hostname to krb5_sname_to_principal(), instead we mark up the principal as magic-unresolved. Now there are some places where we should return the name in its native form, and that is after gss_init_sec_context() is done by gss_inquire_context(), and gss_canonicalize_name(). We also need to deal with these magic-unresolved names in gss_acquire_cred() and gss_export_name().

So lets go over the four cases when we have a magic-unresolved.

gss_init_sec_context(), we try first to get Kerberos credentials using TGS-REQ using the sort name and hope that its an valid alias, if no, we call back to the old way with krb5_sname_to_principal(). Right, we update the name in the context to what we used.

gss_acquire_cred() same thing here, first try literal, then krb5_sname_to_principal().

gss_inquire_context(), this is simple gss_init_sec_context() will have solve the problem for us, just copy out the string.

gss_canonicalize_name() here we don't have a chance, so I guess, we want to have the canonicalized name, so I used the krb5_sname_to_principal() to canonicalize the name.

So where to store this magic-unresolved bit ? Well it happens to be so that the Kerberos gss-api mech uses Kerberos principals (krb5_principal) so there no extra bit where we can save the info. So, instead we hook the krb5_principal name type field and misuse that. Any time we will export or use the principal, we'll convert back to KRB5_NT_SRV_HST that it would have been if we used krb5_sname_to_principal().

måndag 15 september 2008

GSS_C_DELEG_POLICY_FLAG and cross realm

I've been working on the draft for GSS_C_DELEG_POLICY_FLAG lately. One thing I have added is th reason why we need this document. This was requested by reviewers.

Its for legacy deployments that can't update Kerberos today and can't/don't want to change behavior.

Getting the flag defined and the behavior clarified is only the first step of this process. The second is to make sure it works in the cross realm case too. The proposal I have is to make it an MUST that all intermediate cross realm tgt tickets also have ok-as-delegate flag set. It seems Microsoft does it that was and I've asked them if I've read their spec is correctly.

fredag 21 september 2007

gssmaestro

I have started to merge the Samba GSS-API change from Andrew Bartlet and Stefan Metzmacher. As part of that work I have completed most of the basic work of my clone of gssmaggot/gssmaster that David Christansson (Microsoft) have written.

 The problem with gssmaster is that its not released in source-code format, so I wrote my own client (gssmask) and server (gssmaestro). gssmaestro is not as complete that I wish, but test most of the context and token functionallity in the gss-space.

I plan to use gssmask/gssmaestro to test with gssmaggot, this way I can make sure I don't break anything, and at the same time still work with Microsofts and MIT gssapi implementations. This is what we do for the interrop events, but usually with new and shiny code.

There is also a new regression test that uses the gssmask/gssmaestro test program in heimdal/tests/gss directory and its hooked up to the regular automake regression tests, so hopefully I wont break the basic gss-api functions ever again.