add credential handling, add probe function, add better acquired cred function

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@22163 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Love Hörnquist Åstrand
2007-12-04 21:25:06 +00:00
parent 280b58bb08
commit 8ca9a4469c
7 changed files with 162 additions and 67 deletions

View File

@@ -43,7 +43,6 @@ OM_uint32
_gss_ntlm_allocate_ctx(OM_uint32 *minor_status, ntlm_ctx *ctx)
{
OM_uint32 maj_stat;
/* krb5_error_code ret; */
*ctx = calloc(1, sizeof(**ctx));
@@ -123,11 +122,20 @@ _gss_ntlm_accept_sec_context
}
if ((type1.flags & NTLM_NEG_UNICODE) == 0) {
heim_ntlm_free_type1(&type1);
_gss_ntlm_delete_sec_context(minor_status, context_handle, NULL);
*minor_status = EINVAL;
return GSS_S_FAILURE;
}
major_status = (*ctx->server->nsi_probe)(minor_status, ctx->ictx, NULL);
if (major_status) {
heim_ntlm_free_type1(&type1);
_gss_ntlm_delete_sec_context(minor_status, context_handle, NULL);
return major_status;
}
if (type1.flags & NTLM_NEG_SIGN)
ctx->gssflags |= GSS_C_CONF_FLAG;
if (type1.flags & NTLM_NEG_SIGN)

View File

@@ -46,6 +46,7 @@ OM_uint32 _gss_ntlm_acquire_cred
OM_uint32 * time_rec
)
{
ntlm_name name = (ntlm_name) desired_name;
OM_uint32 maj_stat;
ntlm_ctx ctx;
@@ -57,14 +58,30 @@ OM_uint32 _gss_ntlm_acquire_cred
if (time_rec)
*time_rec = GSS_C_INDEFINITE;
maj_stat = _gss_ntlm_allocate_ctx(min_stat, &ctx);
if (maj_stat != GSS_S_COMPLETE)
return maj_stat;
if (desired_name == NULL)
return GSS_S_NO_CRED;
{
gss_ctx_id_t context = (gss_ctx_id_t)ctx;
_gss_ntlm_delete_sec_context(min_stat, &context, NULL);
*min_stat = 0;
if (cred_usage == GSS_C_BOTH || cred_usage == GSS_C_ACCEPT) {
maj_stat = _gss_ntlm_allocate_ctx(min_stat, &ctx);
if (maj_stat != GSS_S_COMPLETE)
return maj_stat;
maj_stat = (*ctx->server->nsi_probe)(min_stat, ctx->ictx,
name->domain);
if (maj_stat)
return maj_stat;
{
gss_ctx_id_t context = (gss_ctx_id_t)ctx;
_gss_ntlm_delete_sec_context(min_stat, &context, NULL);
*min_stat = 0;
}
}
if (cred_usage == GSS_C_BOTH || cred_usage == GSS_C_INITIATE) {
/* check if cred exists XXX */
}
return (GSS_S_COMPLETE);

View File

@@ -43,17 +43,14 @@ OM_uint32 _gss_ntlm_delete_sec_context
{
if (context_handle) {
ntlm_ctx ctx = (ntlm_ctx)*context_handle;
gss_cred_id_t cred = (gss_cred_id_t)ctx->client;
*context_handle = GSS_C_NO_CONTEXT;
if (ctx->server)
(*ctx->server->nsi_destroy)(minor_status, ctx->ictx);
if (ctx->client.username)
free(ctx->client.username);
if (ctx->client.key.data) {
memset(ctx->client.key.data, 0, ctx->client.key.length);
free(ctx->client.key.data);
}
_gss_ntlm_release_cred(NULL, &cred);
memset(ctx, 0, sizeof(*ctx));
free(ctx);

View File

@@ -45,6 +45,7 @@ struct ntlmkrb5 {
krb5_realm kerberos_realm;
krb5_ccache id;
krb5_data opaque;
int destroy;
OM_uint32 flags;
struct ntlm_buf key;
krb5_data sessionkey;
@@ -58,11 +59,11 @@ static OM_uint32 kdc_destroy(OM_uint32 *, void *);
*/
static krb5_error_code
get_ccache(krb5_context context, krb5_ccache *id)
get_ccache(krb5_context context, int *destroy, krb5_ccache *id)
{
krb5_principal principal = NULL;
krb5_error_code ret;
krb5_keytab kt;
krb5_keytab kt = NULL;
*id = NULL;
@@ -85,7 +86,7 @@ get_ccache(krb5_context context, krb5_ccache *id)
ret = krb5_cc_cache_match(context, principal, NULL, id);
if (ret == 0)
goto out;
return 0;
/* did not find in default credcache, lets try default keytab */
ret = krb5_kt_default(context, &kt);
@@ -93,27 +94,55 @@ get_ccache(krb5_context context, krb5_ccache *id)
goto out;
/* XXX check in keytab */
#if 0
{
krb5_creds cred = NULL;
krb5_get_init_creds_opt *opt;
krb5_creds cred;
memset(&cred, 0, sizeof(cred));
ret = krb5_cc_new_unique(context, "MEMORY", NULL, id);
if (ret)
goto out;
*destroy = 1;
ret = krb5_get_init_creds_opt_alloc(context, &opt);
if (ret)
goto out;
ret = krb5_get_init_creds_keytab (context,
&cred,
principal,
kt,
0,
NULL,
NULL,
NULL);
opt);
krb5_get_init_creds_opt_free(context, opt);
if (ret)
goto out;
ret = krb5_cc_initialize (context, ccache, cred.client);
ret = krb5_cc_store_cred (context, ccache, &cred);
ret = krb5_cc_initialize (context, *id, cred.client);
if (ret) {
krb5_free_cred_contents (context, &cred);
goto out;
}
ret = krb5_cc_store_cred (context, *id, &cred);
krb5_free_cred_contents (context, &cred);
if (ret)
goto out;
}
#endif
krb5_kt_close(context, kt);
return 0;
out:
if (*destroy)
krb5_cc_destroy(context, *id);
else
krb5_cc_close(context, *id);
*id = NULL;
if (kt)
krb5_kt_close(context, kt);
if (principal)
krb5_free_principal(context, principal);
return ret;
@@ -143,7 +172,7 @@ kdc_alloc(OM_uint32 *minor, void **ctx)
return GSS_S_FAILURE;
}
ret = get_ccache(c->context, &c->id);
ret = get_ccache(c->context, &c->destroy, &c->id);
if (ret) {
kdc_destroy(&junk, c);
*minor = ret;
@@ -162,6 +191,23 @@ kdc_alloc(OM_uint32 *minor, void **ctx)
return GSS_S_COMPLETE;
}
static int
kdc_probe(OM_uint32 *minor, void *ctx, const char *realm)
{
struct ntlmkrb5 *c = ctx;
krb5_error_code ret;
unsigned flags;
ret = krb5_digest_probe(c->context, realm, c->id, &flags);
if (ret)
return ret;
if ((flags & (1|2|4)) == 0)
return EINVAL;
return 0;
}
/*
*
*/
@@ -174,8 +220,12 @@ kdc_destroy(OM_uint32 *minor, void *ctx)
krb5_data_free(&c->sessionkey);
if (c->ntlm)
krb5_ntlm_free(c->context, c->ntlm);
if (c->id)
krb5_cc_close(c->context, c->id);
if (c->id) {
if (c->destroy)
krb5_cc_destroy(c->context, c->id);
else
krb5_cc_close(c->context, c->id);
}
if (c->context)
krb5_free_context(c->context);
memset(c, 0, sizeof(*c));
@@ -378,6 +428,7 @@ kdc_free_buffer(struct ntlm_buf *sessionkey)
struct ntlm_server_interface ntlmsspi_kdc_digest = {
kdc_alloc,
kdc_destroy,
kdc_probe,
kdc_type2,
kdc_type3,
kdc_free_buffer

View File

@@ -166,15 +166,27 @@ out:
}
int
_gss_ntlm_get_user_info(const char *domain,
char **username,
struct ntlm_buf *key)
_gss_ntlm_get_user_cred(const char *domain,
ntlm_cred *rcred)
{
ntlm_cred cred;
int ret;
ret = get_user_file(domain, username, key);
cred = calloc(1, sizeof(*cred));
if (cred == NULL)
return ENOMEM;
ret = get_user_file(domain, &cred->username, &cred->key);
if (ret)
ret = get_user_ccache(domain, username, key);
ret = get_user_ccache(domain, &cred->username, &cred->key);
if (ret) {
free(cred);
return ret;
}
cred->domain = strdup(domain);
*rcred = cred;
return ret;
}
@@ -220,9 +232,7 @@ _gss_ntlm_init_sec_context
}
*context_handle = (gss_ctx_id_t)ctx;
ret = _gss_ntlm_get_user_info(name->domain,
&ctx->client.username,
&ctx->client.key);
ret = _gss_ntlm_get_user_cred(name->domain, &ctx->client);
if (ret) {
_gss_ntlm_delete_sec_context(minor_status, context_handle, NULL);
*minor_status = ret;
@@ -285,7 +295,7 @@ _gss_ntlm_init_sec_context
memset(&type3, 0, sizeof(type3));
type3.username = ctx->client.username;
type3.username = ctx->client->username;
type3.flags = type2.flags;
type3.targetname = type2.targetname;
type3.ws = rk_UNCONST("workstation");
@@ -309,12 +319,12 @@ _gss_ntlm_init_sec_context
ret = heim_ntlm_calculate_ntlm2_sess(nonce,
type2.challange,
ctx->client.key.data,
ctx->client->key.data,
&type3.lm,
&type3.ntlm);
} else {
ret = heim_ntlm_calculate_ntlm1(ctx->client.key.data,
ctx->client.key.length,
ret = heim_ntlm_calculate_ntlm1(ctx->client->key.data,
ctx->client->key.length,
type2.challange,
&type3.ntlm);
@@ -325,8 +335,8 @@ _gss_ntlm_init_sec_context
return GSS_S_FAILURE;
}
ret = heim_ntlm_build_ntlm1_master(ctx->client.key.data,
ctx->client.key.length,
ret = heim_ntlm_build_ntlm1_master(ctx->client->key.data,
ctx->client->key.length,
&sessionkey,
&type3.sessionkey);
if (ret) {
@@ -375,9 +385,9 @@ _gss_ntlm_init_sec_context
return GSS_S_FAILURE;
}
ret = heim_ntlm_calculate_ntlm2(ctx->client.key.data,
ctx->client.key.length,
ctx->client.username,
ret = heim_ntlm_calculate_ntlm2(ctx->client->key.data,
ctx->client->key.length,
ctx->client->username,
name->domain,
type2.challange,
&type2.targetinfo,

View File

@@ -63,20 +63,16 @@ typedef OM_uint32
typedef OM_uint32
(*ntlm_interface_destroy)(OM_uint32 *, void *);
typedef OM_uint32
(*ntlm_interface_type2)(OM_uint32 *minor_status,
void *ctx,
uint32_t flags,
const char *hostname,
const char *domain,
uint32_t *ret_flags,
struct ntlm_buf *type2);
typedef int
(*ntlm_interface_probe)(OM_uint32 *, void *, const char *);
typedef OM_uint32
(*ntlm_interface_type3)(OM_uint32 *minor_status,
void *ctx,
const struct ntlm_type3 *type3,
struct ntlm_buf *sessionkey);
(*ntlm_interface_type2)(OM_uint32 *, void *, uint32_t, const char *,
const char *, uint32_t *, struct ntlm_buf *);
typedef OM_uint32
(*ntlm_interface_type3)(OM_uint32 *, void *, const struct ntlm_type3 *,
struct ntlm_buf *);
typedef void
(*ntlm_interface_free_buffer)(struct ntlm_buf *);
@@ -84,6 +80,7 @@ typedef void
struct ntlm_server_interface {
ntlm_interface_init nsi_init;
ntlm_interface_destroy nsi_destroy;
ntlm_interface_probe nsi_probe;
ntlm_interface_type2 nsi_type2;
ntlm_interface_type3 nsi_type3;
ntlm_interface_free_buffer nsi_free_buffer;
@@ -99,13 +96,16 @@ struct ntlmv2_key {
extern struct ntlm_server_interface ntlmsspi_kdc_digest;
typedef struct ntlm_cred {
char *username;
char *domain;
struct ntlm_buf key;
} *ntlm_cred;
typedef struct {
struct ntlm_server_interface *server;
void *ictx;
struct {
char *username;
struct ntlm_buf key;
} client;
ntlm_cred client;
OM_uint32 gssflags;
uint32_t flags;
uint32_t status;
@@ -127,10 +127,6 @@ typedef struct {
} u;
} *ntlm_ctx;
typedef struct {
int foo;
} *ntlm_cred;
typedef struct {
char domain[1];
} *ntlm_name;

View File

@@ -40,10 +40,26 @@ OM_uint32 _gss_ntlm_release_cred
gss_cred_id_t * cred_handle
)
{
ntlm_cred cred;
if (minor_status)
*minor_status = 0;
if (cred_handle)
*cred_handle = GSS_C_NO_CREDENTIAL;
if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL)
return GSS_S_COMPLETE;
cred = (ntlm_cred)*cred_handle;
*cred_handle = GSS_C_NO_CREDENTIAL;
if (cred->username)
free(cred->username);
if (cred->domain)
free(cred->domain);
if (cred->key.data) {
memset(cred->key.data, 0, cred->key.length);
free(cred->key.data);
}
return GSS_S_COMPLETE;
}