1 /* ccapi/common/cci_cred_union.c */
3 * Copyright 2006 Massachusetts Institute of Technology.
6 * Export of this software from the United States of America may
7 * require a specific license from the United States Government.
8 * It is the responsibility of any person or organization contemplating
9 * export to obtain such a license before exporting.
11 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
12 * distribute this software and its documentation for any purpose and
13 * without fee is hereby granted, provided that the above copyright
14 * notice appear in all copies and that both that copyright notice and
15 * this permission notice appear in supporting documentation, and that
16 * the name of M.I.T. not be used in advertising or publicity pertaining
17 * to distribution of the software without specific, written prior
18 * permission. Furthermore if you modify this software you must label
19 * your software as modified software and not distribute it in such a
20 * fashion that it might be confused with the original M.I.T. software.
21 * M.I.T. makes no representations about the suitability of
22 * this software for any purpose. It is provided "as is" without express
23 * or implied warranty.
26 #include "cci_common.h"
28 /* ------------------------------------------------------------------------ */
30 static cc_uint32 cci_cc_data_contents_release (cc_data *io_ccdata)
32 cc_int32 err = ccNoError;
34 if (!io_ccdata && io_ccdata->data) { err = ccErrBadParam; }
37 if (io_ccdata->length) {
38 memset (io_ccdata->data, 0, io_ccdata->length);
40 free (io_ccdata->data);
46 /* ------------------------------------------------------------------------ */
48 static cc_uint32 cci_cc_data_release (cc_data *io_ccdata)
50 cc_int32 err = ccNoError;
52 if (!io_ccdata) { err = ccErrBadParam; }
55 cci_cc_data_contents_release (io_ccdata);
62 /* ------------------------------------------------------------------------ */
64 static cc_uint32 cci_cc_data_read (cc_data *io_ccdata,
65 k5_ipc_stream io_stream)
67 cc_int32 err = ccNoError;
72 if (!io_stream) { err = cci_check_error (ccErrBadParam); }
73 if (!io_ccdata) { err = cci_check_error (ccErrBadParam); }
76 err = krb5int_ipc_stream_read_uint32 (io_stream, &type);
80 err = krb5int_ipc_stream_read_uint32 (io_stream, &length);
83 if (!err && length > 0) {
84 data = malloc (length);
85 if (!data) { err = cci_check_error (ccErrNoMem); }
88 err = krb5int_ipc_stream_read (io_stream, data, length);
93 io_ccdata->type = type;
94 io_ccdata->length = length;
95 io_ccdata->data = data;
101 return cci_check_error (err);
104 /* ------------------------------------------------------------------------ */
106 static cc_uint32 cci_cc_data_write (cc_data *in_ccdata,
107 k5_ipc_stream io_stream)
109 cc_int32 err = ccNoError;
111 if (!io_stream) { err = cci_check_error (ccErrBadParam); }
112 if (!in_ccdata) { err = cci_check_error (ccErrBadParam); }
115 err = krb5int_ipc_stream_write_uint32 (io_stream, in_ccdata->type);
119 err = krb5int_ipc_stream_write_uint32 (io_stream, in_ccdata->length);
122 if (!err && in_ccdata->length > 0) {
123 err = krb5int_ipc_stream_write (io_stream, in_ccdata->data, in_ccdata->length);
126 return cci_check_error (err);
133 /* ------------------------------------------------------------------------ */
135 static cc_uint32 cci_cc_data_array_release (cc_data **io_ccdata_array)
137 cc_int32 err = ccNoError;
139 if (!io_ccdata_array) { err = ccErrBadParam; }
144 for (i = 0; io_ccdata_array && io_ccdata_array[i]; i++) {
145 cci_cc_data_release (io_ccdata_array[i]);
147 free (io_ccdata_array);
153 /* ------------------------------------------------------------------------ */
155 static cc_uint32 cci_cc_data_array_read (cc_data ***io_ccdata_array,
156 k5_ipc_stream io_stream)
158 cc_int32 err = ccNoError;
160 cc_data **array = NULL;
163 if (!io_stream ) { err = cci_check_error (ccErrBadParam); }
164 if (!io_ccdata_array) { err = cci_check_error (ccErrBadParam); }
167 err = krb5int_ipc_stream_read_uint32 (io_stream, &count);
170 if (!err && count > 0) {
171 array = malloc ((count + 1) * sizeof (*array));
173 for (i = 0; i <= count; i++) { array[i] = NULL; }
175 err = cci_check_error (ccErrNoMem);
180 for (i = 0; !err && i < count; i++) {
181 array[i] = malloc (sizeof (cc_data));
182 if (!array[i]) { err = cci_check_error (ccErrNoMem); }
185 err = cci_cc_data_read (array[i], io_stream);
191 *io_ccdata_array = array;
195 cci_cc_data_array_release (array);
197 return cci_check_error (err);
200 /* ------------------------------------------------------------------------ */
202 static cc_uint32 cci_cc_data_array_write (cc_data **in_ccdata_array,
203 k5_ipc_stream io_stream)
205 cc_int32 err = ccNoError;
208 if (!io_stream) { err = cci_check_error (ccErrBadParam); }
209 /* in_ccdata_array may be NULL */
212 for (count = 0; in_ccdata_array && in_ccdata_array[count]; count++);
214 err = krb5int_ipc_stream_write_uint32 (io_stream, count);
220 for (i = 0; !err && i < count; i++) {
221 err = cci_cc_data_write (in_ccdata_array[i], io_stream);
225 return cci_check_error (err);
232 /* ------------------------------------------------------------------------ */
234 cc_credentials_v5_t cci_credentials_v5_initializer = {
245 /* ------------------------------------------------------------------------ */
247 static cc_uint32 cci_credentials_v5_release (cc_credentials_v5_t *io_v5creds)
249 cc_int32 err = ccNoError;
251 if (!io_v5creds) { err = ccErrBadParam; }
254 free (io_v5creds->client);
255 free (io_v5creds->server);
256 cci_cc_data_contents_release (&io_v5creds->keyblock);
257 cci_cc_data_array_release (io_v5creds->addresses);
258 cci_cc_data_contents_release (&io_v5creds->ticket);
259 cci_cc_data_contents_release (&io_v5creds->second_ticket);
260 cci_cc_data_array_release (io_v5creds->authdata);
267 /* ------------------------------------------------------------------------ */
269 static cc_uint32 cci_credentials_v5_read (cc_credentials_v5_t **out_v5creds,
270 k5_ipc_stream io_stream)
272 cc_int32 err = ccNoError;
273 cc_credentials_v5_t *v5creds = NULL;
275 if (!io_stream ) { err = cci_check_error (ccErrBadParam); }
276 if (!out_v5creds) { err = cci_check_error (ccErrBadParam); }
279 v5creds = malloc (sizeof (*v5creds));
281 *v5creds = cci_credentials_v5_initializer;
283 err = cci_check_error (ccErrNoMem);
288 err = krb5int_ipc_stream_read_string (io_stream, &v5creds->client);
292 err = krb5int_ipc_stream_read_string (io_stream, &v5creds->server);
296 err = cci_cc_data_read (&v5creds->keyblock, io_stream);
300 err = krb5int_ipc_stream_read_time (io_stream, &v5creds->authtime);
304 err = krb5int_ipc_stream_read_time (io_stream, &v5creds->starttime);
308 err = krb5int_ipc_stream_read_time (io_stream, &v5creds->endtime);
312 err = krb5int_ipc_stream_read_time (io_stream, &v5creds->renew_till);
316 err = krb5int_ipc_stream_read_uint32 (io_stream, &v5creds->is_skey);
320 err = krb5int_ipc_stream_read_uint32 (io_stream, &v5creds->ticket_flags);
324 err = cci_cc_data_array_read (&v5creds->addresses, io_stream);
328 err = cci_cc_data_read (&v5creds->ticket, io_stream);
332 err = cci_cc_data_read (&v5creds->second_ticket, io_stream);
336 err = cci_cc_data_array_read (&v5creds->authdata, io_stream);
340 *out_v5creds = v5creds;
344 cci_credentials_v5_release (v5creds);
346 return cci_check_error (err);
349 /* ------------------------------------------------------------------------ */
351 static cc_uint32 cci_credentials_v5_write (cc_credentials_v5_t *in_v5creds,
352 k5_ipc_stream io_stream)
354 cc_int32 err = ccNoError;
356 if (!io_stream ) { err = cci_check_error (ccErrBadParam); }
357 if (!in_v5creds) { err = cci_check_error (ccErrBadParam); }
360 err = krb5int_ipc_stream_write_string (io_stream, in_v5creds->client);
364 err = krb5int_ipc_stream_write_string (io_stream, in_v5creds->server);
368 err = cci_cc_data_write (&in_v5creds->keyblock, io_stream);
372 err = krb5int_ipc_stream_write_time (io_stream, in_v5creds->authtime);
376 err = krb5int_ipc_stream_write_time (io_stream, in_v5creds->starttime);
380 err = krb5int_ipc_stream_write_time (io_stream, in_v5creds->endtime);
384 err = krb5int_ipc_stream_write_time (io_stream, in_v5creds->renew_till);
388 err = krb5int_ipc_stream_write_uint32 (io_stream, in_v5creds->is_skey);
392 err = krb5int_ipc_stream_write_uint32 (io_stream, in_v5creds->ticket_flags);
396 err = cci_cc_data_array_write (in_v5creds->addresses, io_stream);
400 err = cci_cc_data_write (&in_v5creds->ticket, io_stream);
404 err = cci_cc_data_write (&in_v5creds->second_ticket, io_stream);
408 err = cci_cc_data_array_write (in_v5creds->authdata, io_stream);
412 return cci_check_error (err);
419 /* ------------------------------------------------------------------------ */
421 cc_uint32 cci_credentials_union_release (cc_credentials_union *io_cred_union)
423 cc_int32 err = ccNoError;
425 if (!io_cred_union) { err = ccErrBadParam; }
428 if (io_cred_union->version == cc_credentials_v5) {
429 cci_credentials_v5_release (io_cred_union->credentials.credentials_v5);
431 free (io_cred_union);
437 /* ------------------------------------------------------------------------ */
439 cc_uint32 cci_credentials_union_read (cc_credentials_union **out_credentials_union,
440 k5_ipc_stream io_stream)
442 cc_int32 err = ccNoError;
443 cc_credentials_union *credentials_union = NULL;
445 if (!io_stream ) { err = cci_check_error (ccErrBadParam); }
446 if (!out_credentials_union) { err = cci_check_error (ccErrBadParam); }
449 credentials_union = calloc (1, sizeof (*credentials_union));
450 if (!credentials_union) { err = cci_check_error (ccErrNoMem); }
454 err = krb5int_ipc_stream_read_uint32 (io_stream, &credentials_union->version);
458 if (credentials_union->version == cc_credentials_v5) {
459 err = cci_credentials_v5_read (&credentials_union->credentials.credentials_v5,
464 err = ccErrBadCredentialsVersion;
469 *out_credentials_union = credentials_union;
470 credentials_union = NULL;
473 if (credentials_union) { cci_credentials_union_release (credentials_union); }
475 return cci_check_error (err);
478 /* ------------------------------------------------------------------------ */
480 cc_uint32 cci_credentials_union_write (const cc_credentials_union *in_credentials_union,
481 k5_ipc_stream io_stream)
483 cc_int32 err = ccNoError;
485 if (!io_stream ) { err = cci_check_error (ccErrBadParam); }
486 if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); }
489 err = krb5int_ipc_stream_write_uint32 (io_stream, in_credentials_union->version);
493 if (in_credentials_union->version == cc_credentials_v5) {
494 err = cci_credentials_v5_write (in_credentials_union->credentials.credentials_v5,
498 err = ccErrBadCredentialsVersion;
502 return cci_check_error (err);
507 #pragma mark -- CCAPI v2 Compat --
510 /* ------------------------------------------------------------------------ */
512 cc_credentials_v5_compat cci_credentials_v5_compat_initializer = {
523 /* ------------------------------------------------------------------------ */
525 cc_uint32 cci_cred_union_release (cred_union *io_cred_union)
527 cc_int32 err = ccNoError;
529 if (!io_cred_union) { err = ccErrBadParam; }
532 if (io_cred_union->cred_type == CC_CRED_V5) {
533 free (io_cred_union->cred.pV5Cred->client);
534 free (io_cred_union->cred.pV5Cred->server);
535 cci_cc_data_contents_release (&io_cred_union->cred.pV5Cred->keyblock);
536 cci_cc_data_array_release (io_cred_union->cred.pV5Cred->addresses);
537 cci_cc_data_contents_release (&io_cred_union->cred.pV5Cred->ticket);
538 cci_cc_data_contents_release (&io_cred_union->cred.pV5Cred->second_ticket);
539 cci_cc_data_array_release (io_cred_union->cred.pV5Cred->authdata);
540 free (io_cred_union->cred.pV5Cred);
542 free (io_cred_union);
548 /* ------------------------------------------------------------------------ */
550 static cc_uint32 cci_cc_data_copy_contents (cc_data *io_ccdata,
553 cc_int32 err = ccNoError;
556 if (!io_ccdata) { err = cci_check_error (ccErrBadParam); }
557 if (!in_ccdata) { err = cci_check_error (ccErrBadParam); }
559 if (!err && in_ccdata->length > 0) {
560 data = malloc (in_ccdata->length);
562 memcpy (data, in_ccdata->data, in_ccdata->length);
564 err = cci_check_error (ccErrNoMem);
569 io_ccdata->type = in_ccdata->type;
570 io_ccdata->length = in_ccdata->length;
571 io_ccdata->data = data;
577 return cci_check_error (err);
580 /* ------------------------------------------------------------------------ */
582 static cc_uint32 cci_cc_data_array_copy (cc_data ***io_ccdata_array,
583 cc_data **in_ccdata_array)
585 cc_int32 err = ccNoError;
587 cc_data **array = NULL;
590 if (!io_ccdata_array) { err = cci_check_error (ccErrBadParam); }
593 for (count = 0; in_ccdata_array && in_ccdata_array[count]; count++);
596 if (!err && count > 0) {
597 array = malloc ((count + 1) * sizeof (*array));
599 for (i = 0; i <= count; i++) { array[i] = NULL; }
601 err = cci_check_error (ccErrNoMem);
606 for (i = 0; !err && i < count; i++) {
607 array[i] = malloc (sizeof (cc_data));
608 if (!array[i]) { err = cci_check_error (ccErrNoMem); }
611 err = cci_cc_data_copy_contents (array[i], in_ccdata_array[i]);
617 *io_ccdata_array = array;
621 cci_cc_data_array_release (array);
623 return cci_check_error (err);
626 /* ------------------------------------------------------------------------ */
628 cc_uint32 cci_credentials_union_to_cred_union (const cc_credentials_union *in_credentials_union,
629 cred_union **out_cred_union)
631 cc_int32 err = ccNoError;
632 cred_union *compat_cred_union = NULL;
634 if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); }
635 if (!out_cred_union ) { err = cci_check_error (ccErrBadParam); }
638 compat_cred_union = calloc (1, sizeof (*compat_cred_union));
639 if (!compat_cred_union) { err = cci_check_error (ccErrNoMem); }
643 if (in_credentials_union->version == cc_credentials_v5) {
644 cc_credentials_v5_t *v5creds = in_credentials_union->credentials.credentials_v5;
645 cc_credentials_v5_compat *compat_v5creds = NULL;
647 compat_v5creds = malloc (sizeof (*compat_v5creds));
648 if (compat_v5creds) {
649 *compat_v5creds = cci_credentials_v5_compat_initializer;
651 err = cci_check_error (ccErrNoMem);
655 if (!v5creds->client) {
656 err = cci_check_error (ccErrBadParam);
658 compat_v5creds->client = strdup (v5creds->client);
659 if (!compat_v5creds->client) { err = cci_check_error (ccErrNoMem); }
664 if (!v5creds->server) {
665 err = cci_check_error (ccErrBadParam);
667 compat_v5creds->server = strdup (v5creds->server);
668 if (!compat_v5creds->server) { err = cci_check_error (ccErrNoMem); }
673 err = cci_cc_data_copy_contents (&compat_v5creds->keyblock, &v5creds->keyblock);
677 err = cci_cc_data_array_copy (&compat_v5creds->addresses, v5creds->addresses);
681 err = cci_cc_data_copy_contents (&compat_v5creds->ticket, &v5creds->ticket);
685 err = cci_cc_data_copy_contents (&compat_v5creds->second_ticket, &v5creds->second_ticket);
689 err = cci_cc_data_array_copy (&compat_v5creds->authdata, v5creds->authdata);
693 compat_cred_union->cred_type = CC_CRED_V5;
694 compat_cred_union->cred.pV5Cred = compat_v5creds;
696 compat_v5creds->keyblock = v5creds->keyblock;
697 compat_v5creds->authtime = v5creds->authtime;
698 compat_v5creds->starttime = v5creds->starttime;
699 compat_v5creds->endtime = v5creds->endtime;
700 compat_v5creds->renew_till = v5creds->renew_till;
701 compat_v5creds->is_skey = v5creds->is_skey;
702 compat_v5creds->ticket_flags = v5creds->ticket_flags;
705 err = cci_check_error (ccErrBadCredentialsVersion);
710 *out_cred_union = compat_cred_union;
711 compat_cred_union = NULL;
714 if (compat_cred_union) { cci_cred_union_release (compat_cred_union); }
716 return cci_check_error (err);
719 /* ------------------------------------------------------------------------ */
721 cc_uint32 cci_cred_union_to_credentials_union (const cred_union *in_cred_union,
722 cc_credentials_union **out_credentials_union)
724 cc_int32 err = ccNoError;
725 cc_credentials_union *creds_union = NULL;
727 if (!in_cred_union ) { err = cci_check_error (ccErrBadParam); }
728 if (!out_credentials_union) { err = cci_check_error (ccErrBadParam); }
731 creds_union = calloc (1, sizeof (*creds_union));
732 if (!creds_union) { err = cci_check_error (ccErrNoMem); }
736 if (in_cred_union->cred_type == CC_CRED_V5) {
737 cc_credentials_v5_compat *compat_v5creds = in_cred_union->cred.pV5Cred;
738 cc_credentials_v5_t *v5creds = NULL;
741 v5creds = malloc (sizeof (*v5creds));
743 *v5creds = cci_credentials_v5_initializer;
745 err = cci_check_error (ccErrNoMem);
750 if (!compat_v5creds->client) {
751 err = cci_check_error (ccErrBadParam);
753 v5creds->client = strdup (compat_v5creds->client);
754 if (!v5creds->client) { err = cci_check_error (ccErrNoMem); }
759 if (!compat_v5creds->server) {
760 err = cci_check_error (ccErrBadParam);
762 v5creds->server = strdup (compat_v5creds->server);
763 if (!v5creds->server) { err = cci_check_error (ccErrNoMem); }
768 err = cci_cc_data_copy_contents (&v5creds->keyblock, &compat_v5creds->keyblock);
772 err = cci_cc_data_array_copy (&v5creds->addresses, compat_v5creds->addresses);
776 err = cci_cc_data_copy_contents (&v5creds->ticket, &compat_v5creds->ticket);
780 err = cci_cc_data_copy_contents (&v5creds->second_ticket, &compat_v5creds->second_ticket);
784 err = cci_cc_data_array_copy (&v5creds->authdata, compat_v5creds->authdata);
788 creds_union->version = cc_credentials_v5;
789 creds_union->credentials.credentials_v5 = v5creds;
791 v5creds->authtime = compat_v5creds->authtime;
792 v5creds->starttime = compat_v5creds->starttime;
793 v5creds->endtime = compat_v5creds->endtime;
794 v5creds->renew_till = compat_v5creds->renew_till;
795 v5creds->is_skey = compat_v5creds->is_skey;
796 v5creds->ticket_flags = compat_v5creds->ticket_flags;
800 err = cci_check_error (ccErrBadCredentialsVersion);
805 *out_credentials_union = creds_union;
809 if (creds_union) { cci_credentials_union_release (creds_union); }
811 return cci_check_error (err);
814 /* ------------------------------------------------------------------------ */
816 cc_uint32 cci_cred_union_compare_to_credentials_union (const cred_union *in_cred_union_compat,
817 const cc_credentials_union *in_credentials_union,
818 cc_uint32 *out_equal)
820 cc_int32 err = ccNoError;
823 if (!in_cred_union_compat) { err = cci_check_error (ccErrBadParam); }
824 if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); }
825 if (!out_equal ) { err = cci_check_error (ccErrBadParam); }
828 if (in_cred_union_compat->cred_type == CC_CRED_V5 &&
829 in_credentials_union->version == cc_credentials_v5) {
830 cc_credentials_v5_compat *old_creds_v5 = in_cred_union_compat->cred.pV5Cred;
831 cc_credentials_v5_t *new_creds_v5 = in_credentials_union->credentials.credentials_v5;
833 /* Really should use krb5_parse_name and krb5_principal_compare */
834 if (old_creds_v5 && new_creds_v5 &&
835 !strcmp (old_creds_v5->client, new_creds_v5->client) &&
836 !strcmp (old_creds_v5->server, new_creds_v5->server) &&
837 (old_creds_v5->starttime == new_creds_v5->starttime)) {
847 return cci_check_error (err);