/* * krb5_checksum_internalize() - Internalize the krb5_checksum. */ static krb5_error_code krb5_checksum_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain) { krb5_error_code kret; krb5_checksum *checksum; krb5_int32 ibuf; krb5_octet *bp; size_t remain; bp = *buffer; remain = *lenremain; kret = EINVAL; /* Read our magic number */ if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) ibuf = 0; if (ibuf == KV5M_CHECKSUM) { kret = ENOMEM; /* Get a checksum */ if ((remain >= (2*sizeof(krb5_int32))) && (checksum = (krb5_checksum *) calloc(1, sizeof(krb5_checksum)))) { /* Get the checksum_type */ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); checksum->checksum_type = (krb5_cksumtype) ibuf; /* Get the length */ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); checksum->length = (int) ibuf; /* Get the string */ if (!ibuf || ((checksum->contents = (krb5_octet *) malloc((size_t) (ibuf))) && !(kret = krb5_ser_unpack_bytes(checksum->contents, (size_t) ibuf, &bp, &remain)))) { /* Get the trailer */ kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); if (!kret && (ibuf == KV5M_CHECKSUM)) { checksum->magic = KV5M_CHECKSUM; *buffer = bp; *lenremain = remain; *argp = (krb5_pointer) checksum; } else kret = EINVAL; } if (kret) { if (checksum->contents) free(checksum->contents); free(checksum); } } } return(kret); }
/* * krb5_rcache_internalize() - Internalize the krb5_rcache. */ static krb5_error_code krb5_rcache_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain) { krb5_error_code kret; krb5_rcache rcache = NULL; krb5_int32 ibuf; krb5_octet *bp; size_t remain; char *rcname = NULL; bp = *buffer; remain = *lenremain; /* Read our magic number */ if (krb5_ser_unpack_int32(&ibuf, &bp, &remain) || ibuf != KV5M_RCACHE) return EINVAL; /* Get the length of the rcache name */ kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); if (kret) return kret; /* Get the rcache name. */ rcname = malloc(ibuf + 1); if (!rcname) return ENOMEM; kret = krb5_ser_unpack_bytes((krb5_octet*)rcname, (size_t) ibuf, &bp, &remain); if (kret) goto cleanup; rcname[ibuf] = '\0'; /* Resolve and recover the rcache. */ kret = krb5_rc_resolve_full(kcontext, &rcache, rcname); if (kret) goto cleanup; krb5_rc_recover(kcontext, rcache); /* Read our magic number again. */ kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); if (kret) goto cleanup; if (ibuf != KV5M_RCACHE) { kret = EINVAL; goto cleanup; } *buffer = bp; *lenremain = remain; *argp = (krb5_pointer) rcache; cleanup: free(rcname); if (kret != 0 && rcache) krb5_rc_close(kcontext, rcache); return kret; }
/* * krb5_authdata_internalize() - Internalize the krb5_authdata. */ static krb5_error_code krb5_authdata_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain) { krb5_error_code kret; krb5_authdata *authdata; krb5_int32 ibuf; krb5_octet *bp; size_t remain; bp = *buffer; remain = *lenremain; kret = EINVAL; /* Read our magic number */ if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) ibuf = 0; if (ibuf == KV5M_AUTHDATA) { kret = ENOMEM; /* Get a authdata */ if ((remain >= (2*sizeof(krb5_int32))) && (authdata = (krb5_authdata *) calloc(1, sizeof(krb5_authdata)))) { /* Get the ad_type */ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); authdata->ad_type = (krb5_authdatatype) ibuf; /* Get the length */ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); authdata->length = (int) ibuf; /* Get the string */ if ((authdata->contents = (krb5_octet *) malloc((size_t) (ibuf))) && !(kret = krb5_ser_unpack_bytes(authdata->contents, (size_t) ibuf, &bp, &remain))) { if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) ibuf = 0; if (ibuf == KV5M_AUTHDATA) { authdata->magic = KV5M_AUTHDATA; *buffer = bp; *lenremain = remain; *argp = (krb5_pointer) authdata; } else kret = EINVAL; } if (kret) { if (authdata->contents) free(authdata->contents); free(authdata); } } } return(kret); }
/* * krb5_keyblock_internalize() - Internalize the krb5_keyblock. */ static krb5_error_code krb5_keyblock_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain) { krb5_error_code kret; krb5_keyblock *keyblock; krb5_int32 ibuf; krb5_octet *bp; size_t remain; bp = *buffer; remain = *lenremain; kret = EINVAL; /* Read our magic number */ if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) ibuf = 0; if (ibuf == KV5M_KEYBLOCK) { kret = ENOMEM; /* Get a keyblock */ if ((remain >= (3*sizeof(krb5_int32))) && (keyblock = (krb5_keyblock *) calloc(1, sizeof(krb5_keyblock)))) { /* Get the enctype */ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); keyblock->enctype = (krb5_enctype) ibuf; /* Get the length */ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); keyblock->length = (int) ibuf; /* Get the string */ if ((keyblock->contents = (krb5_octet *) malloc((size_t) (ibuf)))&& !(kret = krb5_ser_unpack_bytes(keyblock->contents, (size_t) ibuf, &bp, &remain))) { kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); if (!kret && (ibuf == KV5M_KEYBLOCK)) { kret = 0; *buffer = bp; *lenremain = remain; keyblock->magic = KV5M_KEYBLOCK; *argp = (krb5_pointer) keyblock; } else kret = EINVAL; } if (kret) { if (keyblock->contents) free(keyblock->contents); free(keyblock); } } } return(kret); }
/* * krb5_principal_internalize() - Internalize the krb5_principal. */ static krb5_error_code krb5_principal_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain) { krb5_error_code kret; krb5_principal principal; krb5_int32 ibuf; krb5_octet *bp; size_t remain; char *tmpname; bp = *buffer; remain = *lenremain; kret = EINVAL; /* Read our magic number */ if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) ibuf = 0; if (ibuf == KV5M_PRINCIPAL) { kret = ENOMEM; /* See if we have enough data for the length */ if (!(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) { /* Get the string */ if ((tmpname = (char *) malloc((size_t) (ibuf+1))) && !(kret = krb5_ser_unpack_bytes((krb5_octet *) tmpname, (size_t) ibuf, &bp, &remain))) { tmpname[ibuf] = '\0'; /* Parse the name to a principal structure */ principal = (krb5_principal) NULL; kret = krb5_parse_name(kcontext, tmpname, &principal); if (!kret) { kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); if (!kret && (ibuf == KV5M_PRINCIPAL)) { *buffer = bp; *lenremain = remain; *argp = principal; } else kret = EINVAL; } if (kret && principal) krb5_free_principal(kcontext, principal); free(tmpname); } } } return(kret); }
/* * krb5_rcache_internalize() - Internalize the krb5_rcache. */ static krb5_error_code krb5_rcache_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain) { krb5_error_code kret; krb5_rcache rcache; krb5_int32 ibuf; krb5_octet *bp; size_t remain; char *rcname; bp = *buffer; remain = *lenremain; kret = EINVAL; /* Read our magic number */ if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) ibuf = 0; if (ibuf == KV5M_RCACHE) { kret = ENOMEM; /* Get the length of the rcache name */ kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); if (!kret && (rcname = (char *) malloc((size_t) (ibuf+1))) && !(kret = krb5_ser_unpack_bytes((krb5_octet *) rcname, (size_t) ibuf, &bp, &remain))) { rcname[ibuf] = '\0'; if (!(kret = krb5_rc_resolve_full(kcontext, &rcache, rcname))) { (void) krb5_rc_close(kcontext, rcache); (void) krb5_rc_recover(kcontext, rcache); if (!kret && !(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)) && (ibuf == KV5M_RCACHE)) { *buffer = bp; *lenremain = remain; *argp = (krb5_pointer) rcache; } else (void)krb5_rc_close(kcontext, rcache); } free(rcname); } } return(kret); }
/* * krb5_auth_context_internalize() - Internalize the krb5_auth_context. */ static krb5_error_code krb5_auth_context_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain) { krb5_error_code kret; krb5_auth_context auth_context; krb5_int32 ibuf; krb5_octet *bp; size_t remain; krb5_int32 ivlen; krb5_int32 tag; bp = *buffer; remain = *lenremain; kret = EINVAL; /* Read our magic number */ if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) ibuf = 0; if (ibuf == KV5M_AUTH_CONTEXT) { kret = ENOMEM; /* Get memory for the auth_context */ if ((remain >= (5*sizeof(krb5_int32))) && (auth_context = (krb5_auth_context) calloc(1, sizeof(struct _krb5_auth_context)))) { /* Get auth_context_flags */ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); auth_context->auth_context_flags = ibuf; /* Get remote_seq_number */ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); auth_context->remote_seq_number = ibuf; /* Get local_seq_number */ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); auth_context->local_seq_number = ibuf; /* Get req_cksumtype */ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); auth_context->req_cksumtype = (krb5_cksumtype) ibuf; /* Get safe_cksumtype */ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); auth_context->safe_cksumtype = (krb5_cksumtype) ibuf; /* Get length of i_vector */ (void) krb5_ser_unpack_int32(&ivlen, &bp, &remain); if (ivlen) { if ((auth_context->i_vector = (krb5_pointer) malloc((size_t)ivlen))) kret = krb5_ser_unpack_bytes(auth_context->i_vector, (size_t) ivlen, &bp, &remain); else kret = ENOMEM; } else kret = 0; /* Peek at next token */ tag = 0; if (!kret) kret = krb5_ser_unpack_int32(&tag, &bp, &remain); /* This is the remote_addr */ if (!kret && (tag == TOKEN_RADDR)) { if (!(kret = krb5_internalize_opaque(kcontext, KV5M_ADDRESS, (krb5_pointer *) &auth_context-> remote_addr, &bp, &remain))) kret = krb5_ser_unpack_int32(&tag, &bp, &remain); } /* This is the remote_port */ if (!kret && (tag == TOKEN_RPORT)) { if (!(kret = krb5_internalize_opaque(kcontext, KV5M_ADDRESS, (krb5_pointer *) &auth_context-> remote_port, &bp, &remain))) kret = krb5_ser_unpack_int32(&tag, &bp, &remain); } /* This is the local_addr */ if (!kret && (tag == TOKEN_LADDR)) { if (!(kret = krb5_internalize_opaque(kcontext, KV5M_ADDRESS, (krb5_pointer *) &auth_context-> local_addr, &bp, &remain))) kret = krb5_ser_unpack_int32(&tag, &bp, &remain); } /* This is the local_port */ if (!kret && (tag == TOKEN_LPORT)) { if (!(kret = krb5_internalize_opaque(kcontext, KV5M_ADDRESS, (krb5_pointer *) &auth_context-> local_port, &bp, &remain))) kret = krb5_ser_unpack_int32(&tag, &bp, &remain); } /* This is the keyblock */ if (!kret && (tag == TOKEN_KEYBLOCK)) { if (!(kret = krb5_internalize_opaque(kcontext, KV5M_KEYBLOCK, (krb5_pointer *) &auth_context->keyblock, &bp, &remain))) kret = krb5_ser_unpack_int32(&tag, &bp, &remain); } /* This is the send_subkey */ if (!kret && (tag == TOKEN_LSKBLOCK)) { if (!(kret = krb5_internalize_opaque(kcontext, KV5M_KEYBLOCK, (krb5_pointer *) &auth_context-> send_subkey, &bp, &remain))) kret = krb5_ser_unpack_int32(&tag, &bp, &remain); } /* This is the recv_subkey */ if (!kret) { if (tag == TOKEN_RSKBLOCK) { kret = krb5_internalize_opaque(kcontext, KV5M_KEYBLOCK, (krb5_pointer *) &auth_context-> recv_subkey, &bp, &remain); } else { /* * We read the next tag, but it's not of any use here, so * we effectively 'unget' it here. */ bp -= sizeof(krb5_int32); remain += sizeof(krb5_int32); } } /* Now find the authentp */ if (!kret) { if ((kret = krb5_internalize_opaque(kcontext, KV5M_AUTHENTICATOR, (krb5_pointer *) &auth_context->authentp, &bp, &remain))) { if (kret == EINVAL) kret = 0; } } /* Finally, find the trailer */ if (!kret) { kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); if (!kret && (ibuf != KV5M_AUTH_CONTEXT)) kret = EINVAL; } if (!kret) { *buffer = bp; *lenremain = remain; auth_context->magic = KV5M_AUTH_CONTEXT; *argp = (krb5_pointer) auth_context; } else krb5_auth_con_free(kcontext, auth_context); } } return(kret); }
/* * krb5_ccache_internalize() - Internalize the krb5_ccache. */ static krb5_error_code krb5_ccache_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain) { krb5_error_code kret; krb5_ccache ccache; krb5_int32 ibuf; krb5_octet *bp; size_t remain; char *ccname = NULL; *argp = NULL; bp = *buffer; remain = *lenremain; /* Read our magic number. */ kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); if (kret) return kret; if (ibuf != KV5M_CCACHE) return EINVAL; /* Unpack and validate the length of the ccache name. */ kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); if (kret) return kret; if (ibuf < 0 || (krb5_ui_4) ibuf > remain) return EINVAL; /* Allocate and unpack the name. */ ccname = malloc(ibuf + 1); if (!ccname) return ENOMEM; kret = krb5_ser_unpack_bytes((krb5_octet *) ccname, (size_t) ibuf, &bp, &remain); if (kret) goto cleanup; ccname[ibuf] = '\0'; /* Read the second magic number. */ kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); if (kret) goto cleanup; if (ibuf != KV5M_CCACHE) { kret = EINVAL; goto cleanup; } /* Resolve the named credential cache. */ kret = krb5_cc_resolve(kcontext, ccname, &ccache); if (kret) goto cleanup; *buffer = bp; *lenremain = remain; *argp = ccache; cleanup: free(ccname); return(kret); }
/*ARGSUSED*/ static krb5_error_code krb5_address_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain) { krb5_error_code kret; krb5_address *address; krb5_int32 ibuf; krb5_octet *bp; size_t remain; bp = *buffer; remain = *lenremain; kret = EINVAL; /* Read our magic number */ if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) ibuf = 0; if (ibuf == KV5M_ADDRESS) { kret = ENOMEM; /* Get a address */ if ((remain >= (2*sizeof(krb5_int32))) && (address = (krb5_address *) MALLOC(sizeof(krb5_address)))) { (void) memset(address, 0, sizeof(krb5_address)); address->magic = KV5M_ADDRESS; /* Get the addrtype */ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); address->addrtype = (krb5_addrtype) ibuf; /* Get the length */ (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); address->length = (int) ibuf; /* Get the string */ /* Solaris Kerberos */ address->contents = (krb5_octet *) MALLOC((size_t) (ibuf)); if ((address->contents) && !(kret = krb5_ser_unpack_bytes(address->contents, (size_t) ibuf, &bp, &remain))) { /* Get the trailer */ if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) ibuf = 0; if (!kret && (ibuf == KV5M_ADDRESS)) { address->magic = KV5M_ADDRESS; *buffer = bp; *lenremain = remain; *argp = (krb5_pointer) address; } else kret = EINVAL; } if (kret) { if (address->contents) FREE(address->contents, address->length); FREE(address, sizeof (krb5_address)); } } } return(kret); }
/* * krb5_context_internalize() - Internalize the krb5_context. */ static krb5_error_code krb5_context_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain) { krb5_error_code kret; krb5_context context; krb5_int32 ibuf; krb5_octet *bp; size_t remain; int i; bp = *buffer; remain = *lenremain; /* Read our magic number */ if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) return (EINVAL); if (ibuf != KV5M_CONTEXT) return (EINVAL); /* Get memory for the context */ context = (krb5_context) MALLOC(sizeof(struct _krb5_context)); if (!context) return (ENOMEM); (void) memset(context, 0, sizeof(struct _krb5_context)); /* Get the size of the default realm */ if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) goto cleanup; if (ibuf) { context->default_realm = (char *) MALLOC((size_t) ibuf+1); if (!context->default_realm) { kret = ENOMEM; goto cleanup; } kret = krb5_ser_unpack_bytes((krb5_octet *) context->default_realm, (size_t) ibuf, &bp, &remain); if (kret) goto cleanup; context->default_realm[ibuf] = '\0'; } /* Get the number of in_tkt_ktypes */ if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) goto cleanup; context->in_tkt_ktype_count = (int) ibuf; context->in_tkt_ktypes = (krb5_enctype *) MALLOC(sizeof(krb5_enctype) * (context->in_tkt_ktype_count+1)); if (!context->in_tkt_ktypes) { kret = ENOMEM; goto cleanup; } (void) memset(context->in_tkt_ktypes, 0, (sizeof(krb5_enctype) * (context->in_tkt_ktype_count + 1))); for (i=0; i<context->in_tkt_ktype_count; i++) { if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) goto cleanup; context->in_tkt_ktypes[i] = (krb5_enctype) ibuf; } /* Get the number of tgs_ktypes */ if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) goto cleanup; context->tgs_ktype_count = (int) ibuf; context->tgs_ktypes = (krb5_enctype *) MALLOC(sizeof(krb5_enctype) * (context->tgs_ktype_count+1)); if (!context->tgs_ktypes) { kret = ENOMEM; goto cleanup; } (void) memset(context->tgs_ktypes, 0, (sizeof(krb5_enctype) * (context->tgs_ktype_count + 1))); for (i=0; i<context->tgs_ktype_count; i++) { if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) goto cleanup; context->tgs_ktypes[i] = (krb5_enctype) ibuf; } /* Allowable checksum */ if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) goto cleanup; context->clockskew = (krb5_deltat) ibuf; /* kdc_req_sumtype */ if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) goto cleanup; context->kdc_req_sumtype = (krb5_cksumtype) ibuf; /* default ap_req_sumtype */ if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) goto cleanup; context->default_ap_req_sumtype = (krb5_cksumtype) ibuf; /* default_safe_sumtype */ if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) goto cleanup; context->default_safe_sumtype = (krb5_cksumtype) ibuf; /* kdc_default_options */ if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) goto cleanup; context->kdc_default_options = (krb5_flags) ibuf; /* library_options */ if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) goto cleanup; context->library_options = (krb5_flags) ibuf; /* profile_secure */ if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) goto cleanup; context->profile_secure = (krb5_boolean) ibuf; /* fcc_default_format */ if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) goto cleanup; context->fcc_default_format = (int) ibuf; /* scc_default_format */ if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) goto cleanup; context->scc_default_format = (int) ibuf; /* Attempt to read in the os_context. It's an array now, but we still treat it in most places as a separate object with a pointer. */ { krb5_os_context osp = 0; kret = krb5_internalize_opaque(kcontext, KV5M_OS_CONTEXT, (krb5_pointer *) &osp, &bp, &remain); if (kret && (kret != EINVAL) && (kret != ENOENT)) goto cleanup; /* Put the newly allocated data into the krb5_context structure where we're really keeping it these days. */ if (osp) *context->os_context = *osp; free(osp); } /* Attempt to read in the db_context */ kret = krb5_internalize_opaque(kcontext, KV5M_DB_CONTEXT, (krb5_pointer *) &context->db_context, &bp, &remain); if (kret && (kret != EINVAL) && (kret != ENOENT)) goto cleanup; #ifndef _KERNEL /* Attempt to read in the profile */ kret = krb5_internalize_opaque(kcontext, PROF_MAGIC_PROFILE, (krb5_pointer *) &context->profile, &bp, &remain); #endif if (kret && (kret != EINVAL) && (kret != ENOENT)) goto cleanup; /* Finally, find the trailer */ if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) goto cleanup; if (ibuf != KV5M_CONTEXT) { kret = EINVAL; goto cleanup; } context->magic = KV5M_CONTEXT; *buffer = bp; *lenremain = remain; *argp = (krb5_pointer) context; return 0; cleanup: if (context) krb5_free_context(context); return(kret); }