diff --git a/cache.c b/cache.c index 05f945316..8f6e1eaa3 100644 --- a/cache.c +++ b/cache.c @@ -3,12 +3,16 @@ krb5_error_code krb5_cc_resolve(krb5_context context, - krb5_ccache *id, - const char *residual) + const char *residual, + krb5_ccache *id) { krb5_ccache p; krb5_fcache *f; + if(strncpy(residual, "FILE:", 5)){ + return -1; + } + p = ALLOC(1, krb5_ccache_data); if(!p) @@ -20,7 +24,7 @@ krb5_cc_resolve(krb5_context context, free(p); return ENOMEM; } - f->filename = strdup(residual); + f->filename = strdup(residual + 5); if(!f->filename){ free(f); free(p); @@ -36,20 +40,52 @@ krb5_cc_resolve(krb5_context context, return 0; } +#if 0 krb5_error_code krb5_cc_gen_new(krb5_context context, + krb5_cc_ops *ops, krb5_ccache *id) { } +krb5_error_code +krb5_cc_register(krb5_context context, + krb5_cc_ops *ops, + krb5_boolean override) +{ +} +#endif + +char* +krb5_cc_get_name(krb5_context context, + krb5_ccache id) +{ + return ((krb5_fcache*)(id->data.data))->filename; +} + +char* +krb5_cc_default_name(krb5_context context) +{ + static char name[1024]; + char *p; + p = getenv("KRB5CCNAME"); + if(p) + strcpy(name, p); + else + sprintf(name, "FILE:/tmp/krb5cc_%d", getuid()); + return name; +} + + + + krb5_error_code krb5_cc_default(krb5_context context, krb5_ccache *id) { - *id = malloc(sizeof(**id)); - if (*id == NULL) - return ENOMEM; - return krb5_cc_resolve (context, id, "/tmp/foo"); + return krb5_cc_resolve(context, + krb5_cc_default_name(context), + id); } static krb5_error_code @@ -60,6 +96,20 @@ store_int32(int fd, return write(fd, &value, sizeof(value)); } +static krb5_error_code +ret_int32(int fd, + int32_t *value) +{ + int32_t v; + int ret; + ret = read(fd, &v, sizeof(v)); + if(ret != sizeof(v)) + return (ret<0)?errno:-1; /* XXX */ + + *value = ntohl(v); + return 0; +} + static krb5_error_code store_int16(int fd, int16_t value) @@ -68,6 +118,20 @@ store_int16(int fd, return write(fd, &value, sizeof(value)); } +static krb5_error_code +ret_int16(int fd, + int16_t *value) +{ + int16_t v; + int ret; + ret = read(fd, &v, sizeof(v)); + if(ret != sizeof(v)) + return (ret<0)?errno:-1; /* XXX */ + + *value = ntohs(v); + return 0; +} + static krb5_error_code store_int8(int fd, int8_t value) @@ -75,15 +139,37 @@ store_int8(int fd, return write(fd, &value, sizeof(value)); } +static krb5_error_code +ret_int8(int fd, + int8_t *value) +{ + return read(fd, value, sizeof(*value)); +} + static krb5_error_code store_data(int fd, - krb5_data *data) + krb5_data data) { int ret; - ret = store_int32(fd, data->length); + ret = store_int32(fd, data.length); if(ret < 0) return ret; - return write(fd, data->data, data->length); + return write(fd, data.data, data.length); +} + +static krb5_error_code +ret_data(int fd, + krb5_data *data) +{ + int ret; + int size; + ret = ret_int32(fd, &size); + data->length = size; + data->data = malloc(size); + ret = read(fd, data->data, size); + if(ret != size) + return (ret < 0)? errno : -1; /* XXX */ + return 0; } static krb5_error_code @@ -93,9 +179,131 @@ store_principal(int fd, int i; store_int32(fd, p->type); store_int32(fd, p->ncomp); - store_data(fd, &p->realm); + store_data(fd, p->realm); for(i = 0; i < p->ncomp; i++) - store_data(fd, &p->comp[i]); + store_data(fd, p->comp[i]); + return 0; +} + +static krb5_error_code +ret_principal(int fd, + krb5_principal *princ) +{ + int i; + krb5_principal p; + + p = ALLOC(1, krb5_principal_data); + + ret_int32(fd, &p->type); + ret_int32(fd, &p->ncomp); + ret_data(fd, &p->realm); + p->comp = ALLOC(p->ncomp, krb5_data); + for(i = 0; i < p->ncomp; i++) + ret_data(fd, &p->comp[i]); + *princ = p; + return 0; +} + +static krb5_error_code +store_keyblock(int fd, krb5_keyblock p) +{ + store_int32(fd, p.keytype); + store_data(fd, p.contents); + return 0; +} + +static krb5_error_code +ret_keyblock(int fd, krb5_keyblock *p) +{ + ret_int32(fd, (int32_t*)&p->keytype); + ret_data(fd, &p->contents); + return 0; +} + +static krb5_error_code +store_times(int fd, krb5_times times) +{ + store_int32(fd, times.authtime); + store_int32(fd, times.starttime); + store_int32(fd, times.endtime); + store_int32(fd, times.renew_till); + return 0; +} + +static krb5_error_code +ret_times(int fd, krb5_times *times) +{ + ret_int32(fd, ×->authtime); + ret_int32(fd, ×->starttime); + ret_int32(fd, ×->endtime); + ret_int32(fd, ×->renew_till); + return 0; +} + +static krb5_error_code +store_address(int fd, krb5_address p) +{ + store_int32(fd, p.type); + store_data(fd, p.address); + return 0; +} + +static krb5_error_code +ret_address(int fd, krb5_address *adr) +{ + ret_int32(fd, (int32_t*)&adr->type); + ret_data(fd, &adr->address); + return 0; +} + +static krb5_error_code +store_addrs(int fd, krb5_addresses p) +{ + int i; + store_int32(fd, p.number); + for(i = 0; inumber); + adr->addrs = ALLOC(adr->number, krb5_address); + for(i = 0; i < adr->number; i++) + ret_address(fd, &adr->addrs[i]); + return 0; +} + +static krb5_error_code +store_ticket(int fd, krb5_ticket p) +{ + int i; + store_data(fd, p.enc_part); + return 0; +} + +static krb5_error_code +ret_ticket(int fd, krb5_ticket *tkt) +{ + int i; + ret_data(fd, &tkt->enc_part); + return 0; +} + +static krb5_error_code +store_authdata(int fd, krb5_data p) +{ + store_data(fd, p); + return 0; +} + +static krb5_error_code +ret_authdata(int fd, krb5_data *auth) +{ + ret_data(fd, auth); return 0; } @@ -167,30 +375,63 @@ krb5_error_code krb5_cc_close(krb5_context context, krb5_ccache id) { + free(id->data.data); + free(id->data); + free(id); + return 0; } krb5_error_code -krb5_cc_store(krb5_context context, - krb5_ccache id, - krb5_creds *creds) +krb5_cc_store_cred(krb5_context context, + krb5_ccache id, + krb5_creds *creds) +{ + int fd; + char *f; + + f = (char*)id->data.data; + fd = open(f, O_WRONLY | O_APPEND); + if(fd < 0) + return errno; + store_principal(fd, creds->client); + store_principal(fd, creds->server); + store_keyblock(fd, creds->session); + store_times(fd, creds->times); + store_int8(fd, 0); /* s/key */ + store_int32(fd, 0); /* flags */ + store_addrs(fd, creds->addresses); + store_authdata(fd, creds->authdata); + store_ticket(fd, creds->ticket); + store_ticket(fd, creds->second_ticket); + close(fd); +} + +krb5_error_code +krb5_cc_retrieve_cred(krb5_context context, + krb5_ccache id, + krb5_flags whichfields, + krb5_creds *mcreds, + krb5_creds *creds) { } krb5_error_code -krb5_cc_retrieve(krb5_context context, - krb5_ccache id, - krb5_flags whichfields, - krb5_creds *mcreds, - krb5_creds *creds) +krb5_cc_get_principal(krb5_context context, + krb5_ccache id, + krb5_principal *principal) { -} + int fd; + char *f; + int16_t tag; -krb5_error_code -krb5_cc_get_princ(krb5_context context, - krb5_ccache id, - krb5_principal *principal) -{ + fd = open(krb5_cc_get_name(context, id), O_RDONLY); + if(fd < 0) + return errno; + ret_int16(fd, &tag); + ret_principal(fd, principal); + close(fd); + return 0; } krb5_error_code diff --git a/cache.h b/cache.h new file mode 100644 index 000000000..5841acb61 --- /dev/null +++ b/cache.h @@ -0,0 +1,72 @@ +krb5_error_code +krb5_cc_resolve (krb5_context context, + char *residual, + krb5_ccache *id); + +char * +krb5_cc_get_name (krb5_context context, + krb5_ccache id); + +char * +krb5_cc_default_name (krb5_context context); + +krb5_error_code +krb5_cc_default (krb5_context context, + krb5_ccache *id); + +krb5_error_code +krb5_cc_initialize (krb5_context context, + krb5_ccache id, + krb5_principal primary_principal); + +krb5_error_code +krb5_cc_destroy (krb5_context context, + krb5_ccache id); + +krb5_error_code +krb5_cc_close (krb5_context context, + krb5_ccache id); + +krb5_error_code +krb5_cc_store_cred (krb5_context context, + krb5_ccache id, + krb5_creds *creds); + +krb5_error_code +krb5_cc_retrieve_cred (krb5_context context, + krb5_ccache id, + krb5_flags whichfields, + krb5_creds *mcreds, + krb5_creds *creds); + +krb5_error_code +krb5_cc_get_principal (krb5_context context, + krb5_ccache id, + krb5_principal *principal); + +krb5_error_code +krb5_cc_get_first (krb5_context context, + krb5_ccache id, + krb5_cc_cursor *cursor); + +krb5_error_code +krb5_cc_get_next (krb5_context context, + krb5_ccache id, + krb5_creds *creds, + krb5_cc_cursor *cursor); + +krb5_error_code +krb5_cc_end_get (krb5_context context, + krb5_ccache id, + krb5_cc_cursor *cursor); + +krb5_error_code +krb5_cc_remove_cred (krb5_context context, + krb5_ccache id, + krb5_flags which, + krb5_creds *cred); + +krb5_error_code +krb5_cc_set_flags (krb5_context context, + krb5_ccache id, + krb5_flags flags); diff --git a/krb5.h b/krb5.h index 652c0895c..aaf50f876 100644 --- a/krb5.h +++ b/krb5.h @@ -102,8 +102,9 @@ typedef krb5_context_data *krb5_context; typedef time_t krb5_time; typedef struct krb5_times{ - krb5_time endtime; + krb5_time authtime; krb5_time starttime; + krb5_time endtime; krb5_time renew_till; } krb5_times; @@ -149,6 +150,7 @@ typedef struct krb5_creds { krb5_ticket second_ticket; /* ? */ krb5_data authdata; /* ? */ + krb5_addresses addresses; } krb5_creds; diff --git a/lib/krb5/cache.c b/lib/krb5/cache.c index 05f945316..8f6e1eaa3 100644 --- a/lib/krb5/cache.c +++ b/lib/krb5/cache.c @@ -3,12 +3,16 @@ krb5_error_code krb5_cc_resolve(krb5_context context, - krb5_ccache *id, - const char *residual) + const char *residual, + krb5_ccache *id) { krb5_ccache p; krb5_fcache *f; + if(strncpy(residual, "FILE:", 5)){ + return -1; + } + p = ALLOC(1, krb5_ccache_data); if(!p) @@ -20,7 +24,7 @@ krb5_cc_resolve(krb5_context context, free(p); return ENOMEM; } - f->filename = strdup(residual); + f->filename = strdup(residual + 5); if(!f->filename){ free(f); free(p); @@ -36,20 +40,52 @@ krb5_cc_resolve(krb5_context context, return 0; } +#if 0 krb5_error_code krb5_cc_gen_new(krb5_context context, + krb5_cc_ops *ops, krb5_ccache *id) { } +krb5_error_code +krb5_cc_register(krb5_context context, + krb5_cc_ops *ops, + krb5_boolean override) +{ +} +#endif + +char* +krb5_cc_get_name(krb5_context context, + krb5_ccache id) +{ + return ((krb5_fcache*)(id->data.data))->filename; +} + +char* +krb5_cc_default_name(krb5_context context) +{ + static char name[1024]; + char *p; + p = getenv("KRB5CCNAME"); + if(p) + strcpy(name, p); + else + sprintf(name, "FILE:/tmp/krb5cc_%d", getuid()); + return name; +} + + + + krb5_error_code krb5_cc_default(krb5_context context, krb5_ccache *id) { - *id = malloc(sizeof(**id)); - if (*id == NULL) - return ENOMEM; - return krb5_cc_resolve (context, id, "/tmp/foo"); + return krb5_cc_resolve(context, + krb5_cc_default_name(context), + id); } static krb5_error_code @@ -60,6 +96,20 @@ store_int32(int fd, return write(fd, &value, sizeof(value)); } +static krb5_error_code +ret_int32(int fd, + int32_t *value) +{ + int32_t v; + int ret; + ret = read(fd, &v, sizeof(v)); + if(ret != sizeof(v)) + return (ret<0)?errno:-1; /* XXX */ + + *value = ntohl(v); + return 0; +} + static krb5_error_code store_int16(int fd, int16_t value) @@ -68,6 +118,20 @@ store_int16(int fd, return write(fd, &value, sizeof(value)); } +static krb5_error_code +ret_int16(int fd, + int16_t *value) +{ + int16_t v; + int ret; + ret = read(fd, &v, sizeof(v)); + if(ret != sizeof(v)) + return (ret<0)?errno:-1; /* XXX */ + + *value = ntohs(v); + return 0; +} + static krb5_error_code store_int8(int fd, int8_t value) @@ -75,15 +139,37 @@ store_int8(int fd, return write(fd, &value, sizeof(value)); } +static krb5_error_code +ret_int8(int fd, + int8_t *value) +{ + return read(fd, value, sizeof(*value)); +} + static krb5_error_code store_data(int fd, - krb5_data *data) + krb5_data data) { int ret; - ret = store_int32(fd, data->length); + ret = store_int32(fd, data.length); if(ret < 0) return ret; - return write(fd, data->data, data->length); + return write(fd, data.data, data.length); +} + +static krb5_error_code +ret_data(int fd, + krb5_data *data) +{ + int ret; + int size; + ret = ret_int32(fd, &size); + data->length = size; + data->data = malloc(size); + ret = read(fd, data->data, size); + if(ret != size) + return (ret < 0)? errno : -1; /* XXX */ + return 0; } static krb5_error_code @@ -93,9 +179,131 @@ store_principal(int fd, int i; store_int32(fd, p->type); store_int32(fd, p->ncomp); - store_data(fd, &p->realm); + store_data(fd, p->realm); for(i = 0; i < p->ncomp; i++) - store_data(fd, &p->comp[i]); + store_data(fd, p->comp[i]); + return 0; +} + +static krb5_error_code +ret_principal(int fd, + krb5_principal *princ) +{ + int i; + krb5_principal p; + + p = ALLOC(1, krb5_principal_data); + + ret_int32(fd, &p->type); + ret_int32(fd, &p->ncomp); + ret_data(fd, &p->realm); + p->comp = ALLOC(p->ncomp, krb5_data); + for(i = 0; i < p->ncomp; i++) + ret_data(fd, &p->comp[i]); + *princ = p; + return 0; +} + +static krb5_error_code +store_keyblock(int fd, krb5_keyblock p) +{ + store_int32(fd, p.keytype); + store_data(fd, p.contents); + return 0; +} + +static krb5_error_code +ret_keyblock(int fd, krb5_keyblock *p) +{ + ret_int32(fd, (int32_t*)&p->keytype); + ret_data(fd, &p->contents); + return 0; +} + +static krb5_error_code +store_times(int fd, krb5_times times) +{ + store_int32(fd, times.authtime); + store_int32(fd, times.starttime); + store_int32(fd, times.endtime); + store_int32(fd, times.renew_till); + return 0; +} + +static krb5_error_code +ret_times(int fd, krb5_times *times) +{ + ret_int32(fd, ×->authtime); + ret_int32(fd, ×->starttime); + ret_int32(fd, ×->endtime); + ret_int32(fd, ×->renew_till); + return 0; +} + +static krb5_error_code +store_address(int fd, krb5_address p) +{ + store_int32(fd, p.type); + store_data(fd, p.address); + return 0; +} + +static krb5_error_code +ret_address(int fd, krb5_address *adr) +{ + ret_int32(fd, (int32_t*)&adr->type); + ret_data(fd, &adr->address); + return 0; +} + +static krb5_error_code +store_addrs(int fd, krb5_addresses p) +{ + int i; + store_int32(fd, p.number); + for(i = 0; inumber); + adr->addrs = ALLOC(adr->number, krb5_address); + for(i = 0; i < adr->number; i++) + ret_address(fd, &adr->addrs[i]); + return 0; +} + +static krb5_error_code +store_ticket(int fd, krb5_ticket p) +{ + int i; + store_data(fd, p.enc_part); + return 0; +} + +static krb5_error_code +ret_ticket(int fd, krb5_ticket *tkt) +{ + int i; + ret_data(fd, &tkt->enc_part); + return 0; +} + +static krb5_error_code +store_authdata(int fd, krb5_data p) +{ + store_data(fd, p); + return 0; +} + +static krb5_error_code +ret_authdata(int fd, krb5_data *auth) +{ + ret_data(fd, auth); return 0; } @@ -167,30 +375,63 @@ krb5_error_code krb5_cc_close(krb5_context context, krb5_ccache id) { + free(id->data.data); + free(id->data); + free(id); + return 0; } krb5_error_code -krb5_cc_store(krb5_context context, - krb5_ccache id, - krb5_creds *creds) +krb5_cc_store_cred(krb5_context context, + krb5_ccache id, + krb5_creds *creds) +{ + int fd; + char *f; + + f = (char*)id->data.data; + fd = open(f, O_WRONLY | O_APPEND); + if(fd < 0) + return errno; + store_principal(fd, creds->client); + store_principal(fd, creds->server); + store_keyblock(fd, creds->session); + store_times(fd, creds->times); + store_int8(fd, 0); /* s/key */ + store_int32(fd, 0); /* flags */ + store_addrs(fd, creds->addresses); + store_authdata(fd, creds->authdata); + store_ticket(fd, creds->ticket); + store_ticket(fd, creds->second_ticket); + close(fd); +} + +krb5_error_code +krb5_cc_retrieve_cred(krb5_context context, + krb5_ccache id, + krb5_flags whichfields, + krb5_creds *mcreds, + krb5_creds *creds) { } krb5_error_code -krb5_cc_retrieve(krb5_context context, - krb5_ccache id, - krb5_flags whichfields, - krb5_creds *mcreds, - krb5_creds *creds) +krb5_cc_get_principal(krb5_context context, + krb5_ccache id, + krb5_principal *principal) { -} + int fd; + char *f; + int16_t tag; -krb5_error_code -krb5_cc_get_princ(krb5_context context, - krb5_ccache id, - krb5_principal *principal) -{ + fd = open(krb5_cc_get_name(context, id), O_RDONLY); + if(fd < 0) + return errno; + ret_int16(fd, &tag); + ret_principal(fd, principal); + close(fd); + return 0; } krb5_error_code diff --git a/lib/krb5/cache.h b/lib/krb5/cache.h new file mode 100644 index 000000000..5841acb61 --- /dev/null +++ b/lib/krb5/cache.h @@ -0,0 +1,72 @@ +krb5_error_code +krb5_cc_resolve (krb5_context context, + char *residual, + krb5_ccache *id); + +char * +krb5_cc_get_name (krb5_context context, + krb5_ccache id); + +char * +krb5_cc_default_name (krb5_context context); + +krb5_error_code +krb5_cc_default (krb5_context context, + krb5_ccache *id); + +krb5_error_code +krb5_cc_initialize (krb5_context context, + krb5_ccache id, + krb5_principal primary_principal); + +krb5_error_code +krb5_cc_destroy (krb5_context context, + krb5_ccache id); + +krb5_error_code +krb5_cc_close (krb5_context context, + krb5_ccache id); + +krb5_error_code +krb5_cc_store_cred (krb5_context context, + krb5_ccache id, + krb5_creds *creds); + +krb5_error_code +krb5_cc_retrieve_cred (krb5_context context, + krb5_ccache id, + krb5_flags whichfields, + krb5_creds *mcreds, + krb5_creds *creds); + +krb5_error_code +krb5_cc_get_principal (krb5_context context, + krb5_ccache id, + krb5_principal *principal); + +krb5_error_code +krb5_cc_get_first (krb5_context context, + krb5_ccache id, + krb5_cc_cursor *cursor); + +krb5_error_code +krb5_cc_get_next (krb5_context context, + krb5_ccache id, + krb5_creds *creds, + krb5_cc_cursor *cursor); + +krb5_error_code +krb5_cc_end_get (krb5_context context, + krb5_ccache id, + krb5_cc_cursor *cursor); + +krb5_error_code +krb5_cc_remove_cred (krb5_context context, + krb5_ccache id, + krb5_flags which, + krb5_creds *cred); + +krb5_error_code +krb5_cc_set_flags (krb5_context context, + krb5_ccache id, + krb5_flags flags); diff --git a/lib/krb5/krb5.h b/lib/krb5/krb5.h index 652c0895c..aaf50f876 100644 --- a/lib/krb5/krb5.h +++ b/lib/krb5/krb5.h @@ -102,8 +102,9 @@ typedef krb5_context_data *krb5_context; typedef time_t krb5_time; typedef struct krb5_times{ - krb5_time endtime; + krb5_time authtime; krb5_time starttime; + krb5_time endtime; krb5_time renew_till; } krb5_times; @@ -149,6 +150,7 @@ typedef struct krb5_creds { krb5_ticket second_ticket; /* ? */ krb5_data authdata; /* ? */ + krb5_addresses addresses; } krb5_creds;