From: Greg Hudson Date: Tue, 1 Jul 2014 16:13:15 +0000 (-0400) Subject: Adjust marshalling interfaces for KCM X-Git-Tag: krb5-1.13-alpha1~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8641f87bab24926688a91590040e5b8903e10897;p=thirdparty%2Fkrb5.git Adjust marshalling interfaces for KCM Make k5_marshal_cred and k5_marshal_princ write to an existing struct k5buf instead of allocating a new one, so that they can be marshalled before or after other data. --- diff --git a/src/lib/krb5/ccache/cc-int.h b/src/lib/krb5/ccache/cc-int.h index 1aa42bb3c9..ef08688817 100644 --- a/src/lib/krb5/ccache/cc-int.h +++ b/src/lib/krb5/ccache/cc-int.h @@ -139,13 +139,11 @@ krb5_error_code k5_unmarshal_princ(const unsigned char *data, size_t len, int version, krb5_principal *princ_out); -krb5_error_code -k5_marshal_cred(krb5_creds *creds, int version, unsigned char **bytes_out, - size_t *len_out); +void +k5_marshal_cred(struct k5buf *buf, int version, krb5_creds *creds); -krb5_error_code -k5_marshal_princ(krb5_principal princ, int version, unsigned char **bytes_out, - size_t *len_out); +void +k5_marshal_princ(struct k5buf *buf, int version, krb5_principal princ); /* * Per-type ccache cursor. diff --git a/src/lib/krb5/ccache/cc_file.c b/src/lib/krb5/ccache/cc_file.c index 2407851446..38c0400752 100644 --- a/src/lib/krb5/ccache/cc_file.c +++ b/src/lib/krb5/ccache/cc_file.c @@ -479,15 +479,15 @@ static krb5_error_code store_principal(krb5_context context, krb5_ccache id, krb5_principal princ) { krb5_error_code ret; - unsigned char *bytes; - size_t len; + struct k5buf buf; k5_cc_mutex_assert_locked(context, &((fcc_data *)id->data)->lock); - ret = k5_marshal_princ(princ, version(id), &bytes, &len); - if (ret) - return ret; - ret = write_bytes(context, id, bytes, len); - free(bytes); + k5_buf_init_dynamic(&buf); + k5_marshal_princ(&buf, version(id), princ); + if (k5_buf_status(&buf) != 0) + return ENOMEM; + ret = write_bytes(context, id, buf.data, buf.len); + k5_buf_free(&buf); return ret; } @@ -1331,8 +1331,7 @@ static krb5_error_code KRB5_CALLCONV fcc_store(krb5_context context, krb5_ccache id, krb5_creds *creds) { krb5_error_code ret; - unsigned char *bytes; - size_t len; + struct k5buf buf; k5_cc_mutex_lock(context, &((fcc_data *)id->data)->lock); @@ -1348,12 +1347,14 @@ fcc_store(krb5_context context, krb5_ccache id, krb5_creds *creds) return interpret_errno(context, errno); } - ret = k5_marshal_cred(creds, version(id), &bytes, &len); - if (ret == 0) { - ret = write_bytes(context, id, bytes, len); - free(bytes); - } + k5_buf_init_dynamic(&buf); + k5_marshal_cred(&buf, version(id), creds); + if (k5_buf_status(&buf) == 0) + ret = write_bytes(context, id, buf.data, buf.len); + else + ret = ENOMEM; + k5_buf_free(&buf); MAYBE_CLOSE(context, id, ret); k5_cc_mutex_unlock(context, &((fcc_data *)id->data)->lock); krb5_change_cache(); diff --git a/src/lib/krb5/ccache/cc_keyring.c b/src/lib/krb5/ccache/cc_keyring.c index 31be293db0..4fe3f0d6f1 100644 --- a/src/lib/krb5/ccache/cc_keyring.c +++ b/src/lib/krb5/ccache/cc_keyring.c @@ -1277,9 +1277,8 @@ krcc_store(krb5_context context, krb5_ccache id, krb5_creds *creds) { krb5_error_code ret; krcc_data *data = id->data; - unsigned char *payload = NULL; + struct k5buf buf = EMPTY_K5BUF; char *keyname = NULL; - size_t payloadlen; key_serial_t cred_key; krb5_timestamp now; @@ -1296,14 +1295,16 @@ krcc_store(krb5_context context, krb5_ccache id, krb5_creds *creds) goto errout; /* Serialize credential using the file ccache version 4 format. */ - ret = k5_marshal_cred(creds, 4, &payload, &payloadlen); + k5_buf_init_dynamic(&buf); + k5_marshal_cred(&buf, 4, creds); + ret = k5_buf_status(&buf); if (ret) goto errout; /* Add new key (credentials) into keyring */ DEBUG_PRINT(("krcc_store: adding new key '%s' to keyring %d\n", keyname, data->cache_id)); - ret = add_cred_key(keyname, payload, payloadlen, data->cache_id, + ret = add_cred_key(keyname, buf.data, buf.len, data->cache_id, data->is_legacy_type, &cred_key); if (ret) goto errout; @@ -1321,8 +1322,8 @@ krcc_store(krb5_context context, krb5_ccache id, krb5_creds *creds) update_keyring_expiration(context, id); errout: + k5_buf_free(&buf); krb5_free_unparsed_name(context, keyname); - free(payload); k5_cc_mutex_unlock(context, &data->lock); return ret; } @@ -1367,16 +1368,16 @@ save_principal(krb5_context context, krb5_ccache id, krb5_principal princ) { krcc_data *data = id->data; krb5_error_code ret; - unsigned char *payload = NULL; + struct k5buf buf; key_serial_t newkey; - size_t payloadsize; k5_cc_mutex_assert_locked(context, &data->lock); /* Serialize princ using the file ccache version 4 format. */ - ret = k5_marshal_princ(princ, 4, &payload, &payloadsize); - if (ret) - goto errout; + k5_buf_init_dynamic(&buf); + k5_marshal_princ(&buf, 4, princ); + if (k5_buf_status(&buf) != 0) + return ENOMEM; /* Add new key into keyring */ #ifdef KRCC_DEBUG @@ -1392,8 +1393,8 @@ save_principal(krb5_context context, krb5_ccache id, krb5_principal princ) krb5_free_unparsed_name(context, princname); } #endif - newkey = add_key(KRCC_KEY_TYPE_USER, KRCC_SPEC_PRINC_KEYNAME, payload, - payloadsize, data->cache_id); + newkey = add_key(KRCC_KEY_TYPE_USER, KRCC_SPEC_PRINC_KEYNAME, buf.data, + buf.len, data->cache_id); if (newkey < 0) { ret = errno; DEBUG_PRINT(("Error adding principal key: %s\n", strerror(ret))); @@ -1403,8 +1404,7 @@ save_principal(krb5_context context, krb5_ccache id, krb5_principal princ) krcc_update_change_time(data); } -errout: - free(payload); + k5_buf_free(&buf); return ret; } diff --git a/src/lib/krb5/ccache/ccmarshal.c b/src/lib/krb5/ccache/ccmarshal.c index d190577d77..57fcd82d35 100644 --- a/src/lib/krb5/ccache/ccmarshal.c +++ b/src/lib/krb5/ccache/ccmarshal.c @@ -370,8 +370,8 @@ put_data(struct k5buf *buf, int version, krb5_data *data) put_len_bytes(buf, version, data->data, data->length); } -static void -marshal_princ(struct k5buf *buf, int version, krb5_principal princ) +void +k5_marshal_princ(struct k5buf *buf, int version, krb5_principal princ) { int32_t i, ncomps; @@ -425,52 +425,23 @@ marshal_authdata(struct k5buf *buf, int version, krb5_authdata **authdata) /* Marshal a credential using the specified file ccache version (expressed as * an integer from 1 to 4). */ -krb5_error_code -k5_marshal_cred(krb5_creds *creds, int version, unsigned char **bytes_out, - size_t *len_out) +void +k5_marshal_cred(struct k5buf *buf, int version, krb5_creds *creds) { - struct k5buf buf; char is_skey; - *bytes_out = NULL; - *len_out = 0; - k5_buf_init_dynamic(&buf); - marshal_princ(&buf, version, creds->client); - marshal_princ(&buf, version, creds->server); - marshal_keyblock(&buf, version, &creds->keyblock); - put32(&buf, version, creds->times.authtime); - put32(&buf, version, creds->times.starttime); - put32(&buf, version, creds->times.endtime); - put32(&buf, version, creds->times.renew_till); + k5_marshal_princ(buf, version, creds->client); + k5_marshal_princ(buf, version, creds->server); + marshal_keyblock(buf, version, &creds->keyblock); + put32(buf, version, creds->times.authtime); + put32(buf, version, creds->times.starttime); + put32(buf, version, creds->times.endtime); + put32(buf, version, creds->times.renew_till); is_skey = creds->is_skey; - k5_buf_add_len(&buf, &is_skey, 1); - put32(&buf, version, creds->ticket_flags); - marshal_addrs(&buf, version, creds->addresses); - marshal_authdata(&buf, version, creds->authdata); - put_data(&buf, version, &creds->ticket); - put_data(&buf, version, &creds->second_ticket); - if (k5_buf_status(&buf) != 0) - return ENOMEM; - *bytes_out = buf.data; - *len_out = buf.len; - return 0; -} - -/* Marshal a principal using the specified file ccache version (expressed as an - * integer from 1 to 4). */ -krb5_error_code -k5_marshal_princ(krb5_principal princ, int version, unsigned char **bytes_out, - size_t *len_out) -{ - struct k5buf buf; - - *bytes_out = NULL; - *len_out = 0; - k5_buf_init_dynamic(&buf); - marshal_princ(&buf, version, princ); - if (k5_buf_status(&buf) != 0) - return ENOMEM; - *bytes_out = buf.data; - *len_out = buf.len; - return 0; + k5_buf_add_len(buf, &is_skey, 1); + put32(buf, version, creds->ticket_flags); + marshal_addrs(buf, version, creds->addresses); + marshal_authdata(buf, version, creds->authdata); + put_data(buf, version, &creds->ticket); + put_data(buf, version, &creds->second_ticket); } diff --git a/src/lib/krb5/ccache/t_marshal.c b/src/lib/krb5/ccache/t_marshal.c index d6908da165..bad8cfcefc 100644 --- a/src/lib/krb5/ccache/t_marshal.c +++ b/src/lib/krb5/ccache/t_marshal.c @@ -271,11 +271,10 @@ main(int argc, char **argv) krb5_creds cred1, cred2; krb5_cc_cursor cursor; const char *filename; - char *ccname, buf[256]; + char *ccname, filebuf[256]; int version, fd; const struct test *t; - unsigned char *bytes; - size_t len; + struct k5buf buf; if (argc != 2) abort(); @@ -293,31 +292,31 @@ main(int argc, char **argv) if (k5_unmarshal_princ(t->princ, t->princlen, version, &princ) != 0) abort(); verify_princ(princ); - if (k5_marshal_princ(princ, version, &bytes, &len) != 0) - abort(); - assert(len == t->princlen); - assert(memcmp(t->princ, bytes, len) == 0); - free(bytes); + k5_buf_init_dynamic(&buf); + k5_marshal_princ(&buf, version, princ); + assert(buf.len == t->princlen); + assert(memcmp(t->princ, buf.data, buf.len) == 0); + k5_buf_free(&buf); /* Test cred1 unmarshalling and marshalling. */ if (k5_unmarshal_cred(t->cred1, t->cred1len, version, &cred1) != 0) abort(); verify_cred1(&cred1); - if (k5_marshal_cred(&cred1, version, &bytes, &len) != 0) - abort(); - assert(len == t->cred1len); - assert(memcmp(t->cred1, bytes, len) == 0); - free(bytes); + k5_buf_init_dynamic(&buf); + k5_marshal_cred(&buf, version, &cred1); + assert(buf.len == t->cred1len); + assert(memcmp(t->cred1, buf.data, buf.len) == 0); + k5_buf_free(&buf); /* Test cred2 unmarshalling and marshalling. */ if (k5_unmarshal_cred(t->cred2, t->cred2len, version, &cred2) != 0) abort(); verify_cred2(&cred2); - if (k5_marshal_cred(&cred2, version, &bytes, &len) != 0) - abort(); - assert(len == t->cred2len); - assert(memcmp(t->cred2, bytes, len) == 0); - free(bytes); + k5_buf_init_dynamic(&buf); + k5_marshal_cred(&buf, version, &cred2); + assert(buf.len == t->cred2len); + assert(memcmp(t->cred2, buf.data, buf.len) == 0); + k5_buf_free(&buf); /* Write a ccache containing the principal and creds. Use the same * time offset as the version 4 test data used. */ @@ -340,18 +339,18 @@ main(int argc, char **argv) fd = open(filename, O_RDONLY); if (fd == -1) abort(); - if (read(fd, buf, t->headerlen) != (ssize_t)t->headerlen) + if (read(fd, filebuf, t->headerlen) != (ssize_t)t->headerlen) abort(); - assert(memcmp(buf, t->header, t->headerlen) == 0); - if (read(fd, buf, t->princlen) != (ssize_t)t->princlen) + assert(memcmp(filebuf, t->header, t->headerlen) == 0); + if (read(fd, filebuf, t->princlen) != (ssize_t)t->princlen) abort(); - assert(memcmp(buf, t->princ, t->princlen) == 0); - if (read(fd, buf, t->cred1len) != (ssize_t)t->cred1len) + assert(memcmp(filebuf, t->princ, t->princlen) == 0); + if (read(fd, filebuf, t->cred1len) != (ssize_t)t->cred1len) abort(); - assert(memcmp(buf, t->cred1, t->cred1len) == 0); - if (read(fd, buf, t->cred2len) != (ssize_t)t->cred2len) + assert(memcmp(filebuf, t->cred1, t->cred1len) == 0); + if (read(fd, filebuf, t->cred2len) != (ssize_t)t->cred2len) abort(); - assert(memcmp(buf, t->cred2, t->cred2len) == 0); + assert(memcmp(filebuf, t->cred2, t->cred2len) == 0); close(fd); krb5_free_principal(context, princ);