diff options
Diffstat (limited to 'crypto/heimdal/lib/kafs/afskrb5.c')
-rw-r--r-- | crypto/heimdal/lib/kafs/afskrb5.c | 163 |
1 files changed, 155 insertions, 8 deletions
diff --git a/crypto/heimdal/lib/kafs/afskrb5.c b/crypto/heimdal/lib/kafs/afskrb5.c index fe5f96a..d415db6 100644 --- a/crypto/heimdal/lib/kafs/afskrb5.c +++ b/crypto/heimdal/lib/kafs/afskrb5.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1995-2003 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "kafs_locl.h" -RCSID("$Id: afskrb5.c,v 1.14 2001/06/18 13:11:32 assar Exp $"); +RCSID("$Id: afskrb5.c,v 1.18.2.1 2003/04/22 14:25:43 joda Exp $"); struct krb5_kafs_data { krb5_context context; @@ -41,9 +41,126 @@ struct krb5_kafs_data { krb5_const_realm realm; }; +enum { + KAFS_RXKAD_2B_KVNO = 213, + KAFS_RXKAD_K5_KVNO = 256 +}; + +static int +v5_to_kt(krb5_creds *cred, uid_t uid, struct kafs_token *kt, int local524) +{ + int kvno, ret; + + kt->ticket = NULL; + + /* check if des key */ + if (cred->session.keyvalue.length != 8) + return EINVAL; + + if (local524) { + Ticket t; + unsigned char *buf; + size_t buf_len; + size_t len; + + kvno = KAFS_RXKAD_2B_KVNO; + + ret = decode_Ticket(cred->ticket.data, cred->ticket.length, &t, &len); + if (ret) + return ret; + if (t.tkt_vno != 5) + return -1; + + ASN1_MALLOC_ENCODE(EncryptedData, buf, buf_len, &t.enc_part, + &len, ret); + free_Ticket(&t); + if (ret) + return ret; + if(buf_len != len) { + free(buf); + return KRB5KRB_ERR_GENERIC; + } + + kt->ticket = buf; + kt->ticket_len = buf_len; + + } else { + kvno = KAFS_RXKAD_K5_KVNO; + kt->ticket = malloc(cred->ticket.length); + if (kt->ticket == NULL) + return ENOMEM; + kt->ticket_len = cred->ticket.length; + memcpy(kt->ticket, cred->ticket.data, kt->ticket_len); + + ret = 0; + } + + + /* + * Build a struct ClearToken + */ + + kt->ct.AuthHandle = kvno; + memcpy(kt->ct.HandShakeKey, cred->session.keyvalue.data, 8); + kt->ct.ViceId = uid; + kt->ct.BeginTimestamp = cred->times.starttime; + kt->ct.EndTimestamp = cred->times.endtime; + + _kafs_fixup_viceid(&kt->ct, uid); + + return 0; +} + +static krb5_error_code +v5_convert(krb5_context context, krb5_ccache id, + krb5_creds *cred, uid_t uid, + const char *cell, + struct kafs_token *kt) +{ + krb5_error_code ret; + char *c, *val; + + c = strdup(cell); + if (c == NULL) + return ENOMEM; + _kafs_foldup(c, c); + krb5_appdefault_string (context, "libkafs", + c, + "afs-use-524", "yes", &val); + free(c); + + if (strcasecmp(val, "local") == 0 || + strcasecmp(val, "2b") == 0) + ret = v5_to_kt(cred, uid, kt, 1); + else if(strcasecmp(val, "yes") == 0 || + strcasecmp(val, "true") == 0 || + atoi(val)) { + struct credentials c; + + if (id == NULL) + ret = krb524_convert_creds_kdc(context, cred, &c); + else + ret = krb524_convert_creds_kdc_ccache(context, id, cred, &c); + if (ret) + goto out; + + ret = _kafs_v4_to_kt(&c, uid, kt); + } else + ret = v5_to_kt(cred, uid, kt, 0); + + out: + free(val); + return ret; +} + + +/* + * + */ + static int get_cred(kafs_data *data, const char *name, const char *inst, - const char *realm, CREDENTIALS *c) + const char *realm, uid_t uid, struct kafs_token *kt) { krb5_error_code ret; krb5_creds in_creds, *out_creds; @@ -65,8 +182,11 @@ get_cred(kafs_data *data, const char *name, const char *inst, krb5_free_principal(d->context, in_creds.client); if(ret) return ret; - ret = krb524_convert_creds_kdc_ccache(d->context, d->id, out_creds, c); + + ret = v5_convert(d->context, d->id, out_creds, uid, + (inst != NULL && inst[0] != '\0') ? inst : realm, kt); krb5_free_creds(d->context, out_creds); + return ret; } @@ -75,7 +195,7 @@ afslog_uid_int(kafs_data *data, const char *cell, const char *rh, uid_t uid, const char *homedir) { krb5_error_code ret; - CREDENTIALS c; + struct kafs_token kt; krb5_principal princ; krb5_realm *trealm; /* ticket realm */ struct krb5_kafs_data *d = data->data; @@ -94,12 +214,15 @@ afslog_uid_int(kafs_data *data, const char *cell, const char *rh, uid_t uid, krb5_free_principal (d->context, princ); } - ret = _kafs_get_cred(data, cell, d->realm, *trealm, &c); + kt.ticket = NULL; + ret = _kafs_get_cred(data, cell, d->realm, *trealm, uid, &kt); if(trealm) krb5_free_principal (d->context, princ); - if(ret == 0) - ret = kafs_settoken(cell, uid, &c); + if(ret == 0) { + ret = kafs_settoken_rxkad(cell, &kt.ct, kt.ticket, kt.ticket_len); + free(kt.ticket); + } return ret; } @@ -126,6 +249,7 @@ krb5_afslog_uid_home(krb5_context context, { kafs_data kd; struct krb5_kafs_data d; + kd.name = "krb5"; kd.afslog_uid = afslog_uid_int; kd.get_cred = get_cred; kd.get_realm = get_realm; @@ -174,6 +298,29 @@ krb5_realm_of_cell(const char *cell, char **realm) { kafs_data kd; + kd.name = "krb5"; kd.get_realm = get_realm; return _kafs_realm_of_cell(&kd, cell, realm); } + +/* + * + */ + +int +kafs_settoken5(krb5_context context, const char *cell, uid_t uid, + krb5_creds *cred) +{ + struct kafs_token kt; + int ret; + + ret = v5_convert(context, NULL, cred, uid, cell, &kt); + if (ret) + return ret; + + ret = kafs_settoken_rxkad(cell, &kt.ct, kt.ticket, kt.ticket_len); + + free(kt.ticket); + + return ret; +} |