store.c revision 78527
155682Smarkm/*
278527Sassar * Copyright (c) 1997-2001 Kungliga Tekniska H�gskolan
355682Smarkm * (Royal Institute of Technology, Stockholm, Sweden).
455682Smarkm * All rights reserved.
555682Smarkm *
655682Smarkm * Redistribution and use in source and binary forms, with or without
755682Smarkm * modification, are permitted provided that the following conditions
855682Smarkm * are met:
955682Smarkm *
1055682Smarkm * 1. Redistributions of source code must retain the above copyright
1155682Smarkm *    notice, this list of conditions and the following disclaimer.
1255682Smarkm *
1355682Smarkm * 2. Redistributions in binary form must reproduce the above copyright
1455682Smarkm *    notice, this list of conditions and the following disclaimer in the
1555682Smarkm *    documentation and/or other materials provided with the distribution.
1655682Smarkm *
1755682Smarkm * 3. Neither the name of the Institute nor the names of its contributors
1855682Smarkm *    may be used to endorse or promote products derived from this software
1955682Smarkm *    without specific prior written permission.
2055682Smarkm *
2155682Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
2255682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2455682Smarkm * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
2555682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2655682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2755682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2855682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2955682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3055682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3155682Smarkm * SUCH DAMAGE.
3255682Smarkm */
3355682Smarkm
3455682Smarkm#include "krb5_locl.h"
3555682Smarkm
3678527SassarRCSID("$Id: store.c,v 1.35 2001/05/11 13:01:43 joda Exp $");
3755682Smarkm
3878527Sassar#define BYTEORDER_IS(SP, V) (((SP)->flags & KRB5_STORAGE_BYTEORDER_MASK) == (V))
3978527Sassar#define BYTEORDER_IS_LE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_LE)
4078527Sassar#define BYTEORDER_IS_BE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_BE)
4178527Sassar#define BYTEORDER_IS_HOST(SP) (BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_HOST) || \
4278527Sassar			       krb5_storage_is_flags((SP), KRB5_STORAGE_HOST_BYTEORDER))
4378527Sassar
4455682Smarkmvoid
4555682Smarkmkrb5_storage_set_flags(krb5_storage *sp, krb5_flags flags)
4655682Smarkm{
4755682Smarkm    sp->flags |= flags;
4855682Smarkm}
4955682Smarkm
5055682Smarkmvoid
5155682Smarkmkrb5_storage_clear_flags(krb5_storage *sp, krb5_flags flags)
5255682Smarkm{
5355682Smarkm    sp->flags &= ~flags;
5455682Smarkm}
5555682Smarkm
5655682Smarkmkrb5_boolean
5755682Smarkmkrb5_storage_is_flags(krb5_storage *sp, krb5_flags flags)
5855682Smarkm{
5955682Smarkm    return (sp->flags & flags) == flags;
6055682Smarkm}
6155682Smarkm
6278527Sassarvoid
6378527Sassarkrb5_storage_set_byteorder(krb5_storage *sp, krb5_flags byteorder)
6478527Sassar{
6578527Sassar    sp->flags &= ~KRB5_STORAGE_BYTEORDER_MASK;
6678527Sassar    sp->flags |= byteorder;
6778527Sassar}
6878527Sassar
6978527Sassarkrb5_flags
7078527Sassarkrb5_storage_get_byteorder(krb5_storage *sp, krb5_flags byteorder)
7178527Sassar{
7278527Sassar    return sp->flags & KRB5_STORAGE_BYTEORDER_MASK;
7378527Sassar}
7478527Sassar
7578527Sassar
7655682Smarkmssize_t
7755682Smarkm_krb5_put_int(void *buffer, unsigned long value, size_t size)
7855682Smarkm{
7955682Smarkm    unsigned char *p = buffer;
8055682Smarkm    int i;
8155682Smarkm    for (i = size - 1; i >= 0; i--) {
8255682Smarkm	p[i] = value & 0xff;
8355682Smarkm	value >>= 8;
8455682Smarkm    }
8555682Smarkm    return size;
8655682Smarkm}
8755682Smarkm
8855682Smarkmssize_t
8955682Smarkm_krb5_get_int(void *buffer, unsigned long *value, size_t size)
9055682Smarkm{
9155682Smarkm    unsigned char *p = buffer;
9255682Smarkm    unsigned long v = 0;
9355682Smarkm    int i;
9455682Smarkm    for (i = 0; i < size; i++)
9555682Smarkm	v = (v << 8) + p[i];
9655682Smarkm    *value = v;
9755682Smarkm    return size;
9855682Smarkm}
9955682Smarkm
10055682Smarkmkrb5_error_code
10155682Smarkmkrb5_storage_free(krb5_storage *sp)
10255682Smarkm{
10355682Smarkm    if(sp->free)
10455682Smarkm	(*sp->free)(sp);
10555682Smarkm    free(sp->data);
10655682Smarkm    free(sp);
10755682Smarkm    return 0;
10855682Smarkm}
10955682Smarkm
11055682Smarkmkrb5_error_code
11155682Smarkmkrb5_storage_to_data(krb5_storage *sp, krb5_data *data)
11255682Smarkm{
11355682Smarkm    off_t pos;
11455682Smarkm    size_t size;
11555682Smarkm    krb5_error_code ret;
11655682Smarkm
11755682Smarkm    pos = sp->seek(sp, 0, SEEK_CUR);
11855682Smarkm    size = (size_t)sp->seek(sp, 0, SEEK_END);
11955682Smarkm    ret = krb5_data_alloc (data, size);
12055682Smarkm    if (ret) {
12155682Smarkm	sp->seek(sp, pos, SEEK_SET);
12255682Smarkm	return ret;
12355682Smarkm    }
12455682Smarkm    if (size) {
12555682Smarkm	sp->seek(sp, 0, SEEK_SET);
12655682Smarkm	sp->fetch(sp, data->data, data->length);
12755682Smarkm	sp->seek(sp, pos, SEEK_SET);
12855682Smarkm    }
12955682Smarkm    return 0;
13055682Smarkm}
13155682Smarkm
13255682Smarkmstatic krb5_error_code
13355682Smarkmkrb5_store_int(krb5_storage *sp,
13455682Smarkm	       int32_t value,
13555682Smarkm	       size_t len)
13655682Smarkm{
13755682Smarkm    int ret;
13878527Sassar    unsigned char v[16];
13955682Smarkm
14078527Sassar    if(len > sizeof(v))
14178527Sassar	return EINVAL;
14255682Smarkm    _krb5_put_int(v, value, len);
14355682Smarkm    ret = sp->store(sp, v, len);
14455682Smarkm    if (ret != len)
14555682Smarkm	return (ret<0)?errno:KRB5_CC_END;
14655682Smarkm    return 0;
14755682Smarkm}
14855682Smarkm
14955682Smarkmkrb5_error_code
15055682Smarkmkrb5_store_int32(krb5_storage *sp,
15155682Smarkm		 int32_t value)
15255682Smarkm{
15378527Sassar    if(BYTEORDER_IS_HOST(sp))
15455682Smarkm	value = htonl(value);
15578527Sassar    else if(BYTEORDER_IS_LE(sp))
15678527Sassar	value = bswap32(value);
15755682Smarkm    return krb5_store_int(sp, value, 4);
15855682Smarkm}
15955682Smarkm
16055682Smarkmstatic krb5_error_code
16155682Smarkmkrb5_ret_int(krb5_storage *sp,
16255682Smarkm	     int32_t *value,
16355682Smarkm	     size_t len)
16455682Smarkm{
16555682Smarkm    int ret;
16655682Smarkm    unsigned char v[4];
16755682Smarkm    unsigned long w;
16855682Smarkm    ret = sp->fetch(sp, v, len);
16955682Smarkm    if(ret != len)
17055682Smarkm	return (ret<0)?errno:KRB5_CC_END;
17155682Smarkm    _krb5_get_int(v, &w, len);
17255682Smarkm    *value = w;
17355682Smarkm    return 0;
17455682Smarkm}
17555682Smarkm
17655682Smarkmkrb5_error_code
17755682Smarkmkrb5_ret_int32(krb5_storage *sp,
17855682Smarkm	       int32_t *value)
17955682Smarkm{
18055682Smarkm    krb5_error_code ret = krb5_ret_int(sp, value, 4);
18155682Smarkm    if(ret)
18255682Smarkm	return ret;
18378527Sassar    if(BYTEORDER_IS_HOST(sp))
18478527Sassar	*value = htonl(*value);
18578527Sassar    else if(BYTEORDER_IS_LE(sp))
18678527Sassar	*value = bswap32(*value);
18755682Smarkm    return 0;
18855682Smarkm}
18955682Smarkm
19055682Smarkmkrb5_error_code
19155682Smarkmkrb5_store_int16(krb5_storage *sp,
19255682Smarkm		 int16_t value)
19355682Smarkm{
19478527Sassar    if(BYTEORDER_IS_HOST(sp))
19555682Smarkm	value = htons(value);
19678527Sassar    else if(BYTEORDER_IS_LE(sp))
19778527Sassar	value = bswap16(value);
19855682Smarkm    return krb5_store_int(sp, value, 2);
19955682Smarkm}
20055682Smarkm
20155682Smarkmkrb5_error_code
20255682Smarkmkrb5_ret_int16(krb5_storage *sp,
20355682Smarkm	       int16_t *value)
20455682Smarkm{
20555682Smarkm    int32_t v;
20655682Smarkm    int ret;
20755682Smarkm    ret = krb5_ret_int(sp, &v, 2);
20855682Smarkm    if(ret)
20955682Smarkm	return ret;
21055682Smarkm    *value = v;
21178527Sassar    if(BYTEORDER_IS_HOST(sp))
21278527Sassar	*value = htons(*value);
21378527Sassar    else if(BYTEORDER_IS_LE(sp))
21478527Sassar	*value = bswap16(*value);
21555682Smarkm    return 0;
21655682Smarkm}
21755682Smarkm
21855682Smarkmkrb5_error_code
21955682Smarkmkrb5_store_int8(krb5_storage *sp,
22055682Smarkm		int8_t value)
22155682Smarkm{
22255682Smarkm    int ret;
22355682Smarkm
22455682Smarkm    ret = sp->store(sp, &value, sizeof(value));
22555682Smarkm    if (ret != sizeof(value))
22655682Smarkm	return (ret<0)?errno:KRB5_CC_END;
22755682Smarkm    return 0;
22855682Smarkm}
22955682Smarkm
23055682Smarkmkrb5_error_code
23155682Smarkmkrb5_ret_int8(krb5_storage *sp,
23255682Smarkm	      int8_t *value)
23355682Smarkm{
23455682Smarkm    int ret;
23555682Smarkm
23655682Smarkm    ret = sp->fetch(sp, value, sizeof(*value));
23755682Smarkm    if (ret != sizeof(*value))
23855682Smarkm	return (ret<0)?errno:KRB5_CC_END;
23955682Smarkm    return 0;
24055682Smarkm}
24155682Smarkm
24255682Smarkmkrb5_error_code
24355682Smarkmkrb5_store_data(krb5_storage *sp,
24455682Smarkm		krb5_data data)
24555682Smarkm{
24655682Smarkm    int ret;
24755682Smarkm    ret = krb5_store_int32(sp, data.length);
24855682Smarkm    if(ret < 0)
24955682Smarkm	return ret;
25055682Smarkm    ret = sp->store(sp, data.data, data.length);
25155682Smarkm    if(ret != data.length){
25255682Smarkm	if(ret < 0)
25355682Smarkm	    return errno;
25455682Smarkm	return KRB5_CC_END;
25555682Smarkm    }
25655682Smarkm    return 0;
25755682Smarkm}
25855682Smarkm
25955682Smarkmkrb5_error_code
26055682Smarkmkrb5_ret_data(krb5_storage *sp,
26155682Smarkm	      krb5_data *data)
26255682Smarkm{
26355682Smarkm    int ret;
26455682Smarkm    int32_t size;
26555682Smarkm
26655682Smarkm    ret = krb5_ret_int32(sp, &size);
26755682Smarkm    if(ret)
26855682Smarkm	return ret;
26955682Smarkm    ret = krb5_data_alloc (data, size);
27055682Smarkm    if (ret)
27155682Smarkm	return ret;
27255682Smarkm    if (size) {
27355682Smarkm	ret = sp->fetch(sp, data->data, size);
27455682Smarkm	if(ret != size)
27555682Smarkm	    return (ret < 0)? errno : KRB5_CC_END;
27655682Smarkm    }
27755682Smarkm    return 0;
27855682Smarkm}
27955682Smarkm
28055682Smarkmkrb5_error_code
28155682Smarkmkrb5_store_string(krb5_storage *sp, const char *s)
28255682Smarkm{
28355682Smarkm    krb5_data data;
28455682Smarkm    data.length = strlen(s);
28555682Smarkm    data.data = (void*)s;
28655682Smarkm    return krb5_store_data(sp, data);
28755682Smarkm}
28855682Smarkm
28955682Smarkmkrb5_error_code
29055682Smarkmkrb5_ret_string(krb5_storage *sp,
29155682Smarkm		char **string)
29255682Smarkm{
29355682Smarkm    int ret;
29455682Smarkm    krb5_data data;
29555682Smarkm    ret = krb5_ret_data(sp, &data);
29655682Smarkm    if(ret)
29755682Smarkm	return ret;
29855682Smarkm    *string = realloc(data.data, data.length + 1);
29955682Smarkm    if(*string == NULL){
30055682Smarkm	free(data.data);
30155682Smarkm	return ENOMEM;
30255682Smarkm    }
30355682Smarkm    (*string)[data.length] = 0;
30455682Smarkm    return 0;
30555682Smarkm}
30655682Smarkm
30755682Smarkmkrb5_error_code
30872445Sassarkrb5_store_stringz(krb5_storage *sp, const char *s)
30955682Smarkm{
31055682Smarkm    size_t len = strlen(s) + 1;
31155682Smarkm    ssize_t ret;
31255682Smarkm
31355682Smarkm    ret = sp->store(sp, s, len);
31455682Smarkm    if(ret != len) {
31555682Smarkm	if(ret < 0)
31655682Smarkm	    return ret;
31755682Smarkm	else
31855682Smarkm	    return KRB5_CC_END;
31955682Smarkm    }
32055682Smarkm    return 0;
32155682Smarkm}
32255682Smarkm
32355682Smarkmkrb5_error_code
32455682Smarkmkrb5_ret_stringz(krb5_storage *sp,
32555682Smarkm		char **string)
32655682Smarkm{
32755682Smarkm    char c;
32855682Smarkm    char *s = NULL;
32955682Smarkm    size_t len = 0;
33055682Smarkm    ssize_t ret;
33155682Smarkm
33255682Smarkm    while((ret = sp->fetch(sp, &c, 1)) == 1){
33355682Smarkm	char *tmp;
33455682Smarkm
33555682Smarkm	len++;
33655682Smarkm	tmp = realloc (s, len);
33755682Smarkm	if (tmp == NULL) {
33855682Smarkm	    free (s);
33955682Smarkm	    return ENOMEM;
34055682Smarkm	}
34155682Smarkm	s = tmp;
34255682Smarkm	s[len - 1] = c;
34355682Smarkm	if(c == 0)
34455682Smarkm	    break;
34555682Smarkm    }
34655682Smarkm    if(ret != 1){
34755682Smarkm	free(s);
34855682Smarkm	if(ret == 0)
34955682Smarkm	    return KRB5_CC_END;
35055682Smarkm	return ret;
35155682Smarkm    }
35255682Smarkm    *string = s;
35355682Smarkm    return 0;
35455682Smarkm}
35555682Smarkm
35655682Smarkm
35755682Smarkmkrb5_error_code
35855682Smarkmkrb5_store_principal(krb5_storage *sp,
35955682Smarkm		     krb5_principal p)
36055682Smarkm{
36155682Smarkm    int i;
36255682Smarkm    int ret;
36355682Smarkm
36455682Smarkm    if(!krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) {
36555682Smarkm    ret = krb5_store_int32(sp, p->name.name_type);
36655682Smarkm    if(ret) return ret;
36755682Smarkm    }
36855682Smarkm    if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
36955682Smarkm	ret = krb5_store_int32(sp, p->name.name_string.len + 1);
37055682Smarkm    else
37155682Smarkm    ret = krb5_store_int32(sp, p->name.name_string.len);
37255682Smarkm
37355682Smarkm    if(ret) return ret;
37455682Smarkm    ret = krb5_store_string(sp, p->realm);
37555682Smarkm    if(ret) return ret;
37655682Smarkm    for(i = 0; i < p->name.name_string.len; i++){
37755682Smarkm	ret = krb5_store_string(sp, p->name.name_string.val[i]);
37855682Smarkm	if(ret) return ret;
37955682Smarkm    }
38055682Smarkm    return 0;
38155682Smarkm}
38255682Smarkm
38355682Smarkmkrb5_error_code
38455682Smarkmkrb5_ret_principal(krb5_storage *sp,
38555682Smarkm		   krb5_principal *princ)
38655682Smarkm{
38755682Smarkm    int i;
38855682Smarkm    int ret;
38955682Smarkm    krb5_principal p;
39055682Smarkm    int32_t type;
39155682Smarkm    int32_t ncomp;
39255682Smarkm
39355682Smarkm    p = calloc(1, sizeof(*p));
39455682Smarkm    if(p == NULL)
39555682Smarkm	return ENOMEM;
39655682Smarkm
39755682Smarkm    if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE))
39855682Smarkm	type = KRB5_NT_UNKNOWN;
39955682Smarkm    else 	if((ret = krb5_ret_int32(sp, &type))){
40055682Smarkm	free(p);
40155682Smarkm	return ret;
40255682Smarkm    }
40355682Smarkm    if((ret = krb5_ret_int32(sp, &ncomp))){
40455682Smarkm	free(p);
40555682Smarkm	return ret;
40655682Smarkm    }
40755682Smarkm    if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
40855682Smarkm	ncomp--;
40955682Smarkm    p->name.name_type = type;
41055682Smarkm    p->name.name_string.len = ncomp;
41155682Smarkm    ret = krb5_ret_string(sp, &p->realm);
41255682Smarkm    if(ret) return ret;
41355682Smarkm    p->name.name_string.val = calloc(ncomp, sizeof(*p->name.name_string.val));
41455682Smarkm    if(p->name.name_string.val == NULL){
41555682Smarkm	free(p->realm);
41655682Smarkm	return ENOMEM;
41755682Smarkm    }
41855682Smarkm    for(i = 0; i < ncomp; i++){
41955682Smarkm	ret = krb5_ret_string(sp, &p->name.name_string.val[i]);
42055682Smarkm	if(ret) return ret; /* XXX */
42155682Smarkm    }
42255682Smarkm    *princ = p;
42355682Smarkm    return 0;
42455682Smarkm}
42555682Smarkm
42655682Smarkmkrb5_error_code
42755682Smarkmkrb5_store_keyblock(krb5_storage *sp, krb5_keyblock p)
42855682Smarkm{
42955682Smarkm    int ret;
43055682Smarkm    ret = krb5_store_int16(sp, p.keytype);
43155682Smarkm    if(ret) return ret;
43255682Smarkm
43355682Smarkm    if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
43455682Smarkm	/* this should really be enctype, but it is the same as
43555682Smarkm           keytype nowadays */
43655682Smarkm    ret = krb5_store_int16(sp, p.keytype);
43755682Smarkm    if(ret) return ret;
43855682Smarkm    }
43955682Smarkm
44055682Smarkm    ret = krb5_store_data(sp, p.keyvalue);
44155682Smarkm    return ret;
44255682Smarkm}
44355682Smarkm
44455682Smarkmkrb5_error_code
44555682Smarkmkrb5_ret_keyblock(krb5_storage *sp, krb5_keyblock *p)
44655682Smarkm{
44755682Smarkm    int ret;
44855682Smarkm    int16_t tmp;
44955682Smarkm
45055682Smarkm    ret = krb5_ret_int16(sp, &tmp);
45155682Smarkm    if(ret) return ret;
45255682Smarkm    p->keytype = tmp;
45355682Smarkm
45455682Smarkm    if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
45555682Smarkm    ret = krb5_ret_int16(sp, &tmp);
45655682Smarkm    if(ret) return ret;
45755682Smarkm    }
45855682Smarkm
45955682Smarkm    ret = krb5_ret_data(sp, &p->keyvalue);
46055682Smarkm    return ret;
46155682Smarkm}
46255682Smarkm
46355682Smarkmkrb5_error_code
46455682Smarkmkrb5_store_times(krb5_storage *sp, krb5_times times)
46555682Smarkm{
46655682Smarkm    int ret;
46755682Smarkm    ret = krb5_store_int32(sp, times.authtime);
46855682Smarkm    if(ret) return ret;
46955682Smarkm    ret = krb5_store_int32(sp, times.starttime);
47055682Smarkm    if(ret) return ret;
47155682Smarkm    ret = krb5_store_int32(sp, times.endtime);
47255682Smarkm    if(ret) return ret;
47355682Smarkm    ret = krb5_store_int32(sp, times.renew_till);
47455682Smarkm    return ret;
47555682Smarkm}
47655682Smarkm
47755682Smarkmkrb5_error_code
47855682Smarkmkrb5_ret_times(krb5_storage *sp, krb5_times *times)
47955682Smarkm{
48055682Smarkm    int ret;
48155682Smarkm    int32_t tmp;
48255682Smarkm    ret = krb5_ret_int32(sp, &tmp);
48355682Smarkm    times->authtime = tmp;
48455682Smarkm    if(ret) return ret;
48555682Smarkm    ret = krb5_ret_int32(sp, &tmp);
48655682Smarkm    times->starttime = tmp;
48755682Smarkm    if(ret) return ret;
48855682Smarkm    ret = krb5_ret_int32(sp, &tmp);
48955682Smarkm    times->endtime = tmp;
49055682Smarkm    if(ret) return ret;
49155682Smarkm    ret = krb5_ret_int32(sp, &tmp);
49255682Smarkm    times->renew_till = tmp;
49355682Smarkm    return ret;
49455682Smarkm}
49555682Smarkm
49655682Smarkmkrb5_error_code
49755682Smarkmkrb5_store_address(krb5_storage *sp, krb5_address p)
49855682Smarkm{
49955682Smarkm    int ret;
50055682Smarkm    ret = krb5_store_int16(sp, p.addr_type);
50155682Smarkm    if(ret) return ret;
50255682Smarkm    ret = krb5_store_data(sp, p.address);
50355682Smarkm    return ret;
50455682Smarkm}
50555682Smarkm
50655682Smarkmkrb5_error_code
50755682Smarkmkrb5_ret_address(krb5_storage *sp, krb5_address *adr)
50855682Smarkm{
50955682Smarkm    int16_t t;
51055682Smarkm    int ret;
51155682Smarkm    ret = krb5_ret_int16(sp, &t);
51255682Smarkm    if(ret) return ret;
51355682Smarkm    adr->addr_type = t;
51455682Smarkm    ret = krb5_ret_data(sp, &adr->address);
51555682Smarkm    return ret;
51655682Smarkm}
51755682Smarkm
51855682Smarkmkrb5_error_code
51955682Smarkmkrb5_store_addrs(krb5_storage *sp, krb5_addresses p)
52055682Smarkm{
52155682Smarkm    int i;
52255682Smarkm    int ret;
52355682Smarkm    ret = krb5_store_int32(sp, p.len);
52455682Smarkm    if(ret) return ret;
52555682Smarkm    for(i = 0; i<p.len; i++){
52655682Smarkm	ret = krb5_store_address(sp, p.val[i]);
52755682Smarkm	if(ret) break;
52855682Smarkm    }
52955682Smarkm    return ret;
53055682Smarkm}
53155682Smarkm
53255682Smarkmkrb5_error_code
53355682Smarkmkrb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr)
53455682Smarkm{
53555682Smarkm    int i;
53655682Smarkm    int ret;
53755682Smarkm    int32_t tmp;
53855682Smarkm
53955682Smarkm    ret = krb5_ret_int32(sp, &tmp);
54055682Smarkm    if(ret) return ret;
54155682Smarkm    adr->len = tmp;
54255682Smarkm    ALLOC(adr->val, adr->len);
54355682Smarkm    for(i = 0; i < adr->len; i++){
54455682Smarkm	ret = krb5_ret_address(sp, &adr->val[i]);
54555682Smarkm	if(ret) break;
54655682Smarkm    }
54755682Smarkm    return ret;
54855682Smarkm}
54955682Smarkm
55055682Smarkmkrb5_error_code
55155682Smarkmkrb5_store_authdata(krb5_storage *sp, krb5_authdata auth)
55255682Smarkm{
55355682Smarkm    krb5_error_code ret;
55455682Smarkm    int i;
55555682Smarkm    ret = krb5_store_int32(sp, auth.len);
55655682Smarkm    if(ret) return ret;
55755682Smarkm    for(i = 0; i < auth.len; i++){
55855682Smarkm	ret = krb5_store_int16(sp, auth.val[i].ad_type);
55955682Smarkm	if(ret) break;
56055682Smarkm	ret = krb5_store_data(sp, auth.val[i].ad_data);
56155682Smarkm	if(ret) break;
56255682Smarkm    }
56355682Smarkm    return 0;
56455682Smarkm}
56555682Smarkm
56655682Smarkmkrb5_error_code
56755682Smarkmkrb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth)
56855682Smarkm{
56955682Smarkm    krb5_error_code ret;
57055682Smarkm    int32_t tmp;
57155682Smarkm    int16_t tmp2;
57255682Smarkm    int i;
57355682Smarkm    ret = krb5_ret_int32(sp, &tmp);
57455682Smarkm    if(ret) return ret;
57555682Smarkm    ALLOC_SEQ(auth, tmp);
57655682Smarkm    for(i = 0; i < tmp; i++){
57755682Smarkm	ret = krb5_ret_int16(sp, &tmp2);
57855682Smarkm	if(ret) break;
57955682Smarkm	auth->val[i].ad_type = tmp2;
58055682Smarkm	ret = krb5_ret_data(sp, &auth->val[i].ad_data);
58155682Smarkm	if(ret) break;
58255682Smarkm    }
58355682Smarkm    return ret;
58455682Smarkm}
58555682Smarkm
58672445Sassar/*
58772445Sassar * store `creds' on `sp' returning error or zero
58872445Sassar */
58972445Sassar
59055682Smarkmkrb5_error_code
59155682Smarkmkrb5_store_creds(krb5_storage *sp, krb5_creds *creds)
59255682Smarkm{
59372445Sassar    int ret;
59472445Sassar
59572445Sassar    ret = krb5_store_principal(sp, creds->client);
59672445Sassar    if (ret)
59772445Sassar	return ret;
59872445Sassar    ret = krb5_store_principal(sp, creds->server);
59972445Sassar    if (ret)
60072445Sassar	return ret;
60172445Sassar    ret = krb5_store_keyblock(sp, creds->session);
60272445Sassar    if (ret)
60372445Sassar	return ret;
60472445Sassar    ret = krb5_store_times(sp, creds->times);
60572445Sassar    if (ret)
60672445Sassar	return ret;
60772445Sassar    ret = krb5_store_int8(sp, 0);  /* this is probably the
60855682Smarkm				enc-tkt-in-skey bit from KDCOptions */
60972445Sassar    if (ret)
61072445Sassar	return ret;
61172445Sassar    ret = krb5_store_int32(sp, creds->flags.i);
61272445Sassar    if (ret)
61372445Sassar	return ret;
61472445Sassar    ret = krb5_store_addrs(sp, creds->addresses);
61572445Sassar    if (ret)
61672445Sassar	return ret;
61772445Sassar    ret = krb5_store_authdata(sp, creds->authdata);
61872445Sassar    if (ret)
61972445Sassar	return ret;
62072445Sassar    ret = krb5_store_data(sp, creds->ticket);
62172445Sassar    if (ret)
62272445Sassar	return ret;
62372445Sassar    ret = krb5_store_data(sp, creds->second_ticket);
62472445Sassar    if (ret)
62572445Sassar	return ret;
62655682Smarkm    return 0;
62755682Smarkm}
62855682Smarkm
62955682Smarkmkrb5_error_code
63055682Smarkmkrb5_ret_creds(krb5_storage *sp, krb5_creds *creds)
63155682Smarkm{
63255682Smarkm    krb5_error_code ret;
63355682Smarkm    int8_t dummy8;
63455682Smarkm    int32_t dummy32;
63555682Smarkm
63655682Smarkm    memset(creds, 0, sizeof(*creds));
63755682Smarkm    ret = krb5_ret_principal (sp,  &creds->client);
63855682Smarkm    if(ret) goto cleanup;
63955682Smarkm    ret = krb5_ret_principal (sp,  &creds->server);
64055682Smarkm    if(ret) goto cleanup;
64155682Smarkm    ret = krb5_ret_keyblock (sp,  &creds->session);
64255682Smarkm    if(ret) goto cleanup;
64355682Smarkm    ret = krb5_ret_times (sp,  &creds->times);
64455682Smarkm    if(ret) goto cleanup;
64555682Smarkm    ret = krb5_ret_int8 (sp,  &dummy8);
64655682Smarkm    if(ret) goto cleanup;
64755682Smarkm    ret = krb5_ret_int32 (sp,  &dummy32);
64855682Smarkm    if(ret) goto cleanup;
64955682Smarkm    creds->flags.i = dummy32;
65055682Smarkm    ret = krb5_ret_addrs (sp,  &creds->addresses);
65155682Smarkm    if(ret) goto cleanup;
65255682Smarkm    ret = krb5_ret_authdata (sp,  &creds->authdata);
65355682Smarkm    if(ret) goto cleanup;
65455682Smarkm    ret = krb5_ret_data (sp,  &creds->ticket);
65555682Smarkm    if(ret) goto cleanup;
65655682Smarkm    ret = krb5_ret_data (sp,  &creds->second_ticket);
65755682Smarkmcleanup:
65855682Smarkm    if(ret)
65955682Smarkm#if 0
66055682Smarkm	krb5_free_creds_contents(context, creds) /* XXX */
66155682Smarkm#endif
66255682Smarkm	    ;
66355682Smarkm    return ret;
66455682Smarkm}
665