Code_t ZFormatAuthenticNoticeV5(ZNotice_t *notice, register char *buffer, register int buffer_len, int *len, krb5_keyblock *keyblock) { ZNotice_t newnotice; char *ptr; int retval, hdrlen, hdr_adj; krb5_enctype enctype; krb5_cksumtype cksumtype; #ifdef HAVE_KRB4 int key_len; #endif char *cksum_start, *cstart, *cend; int cksum_len; #ifdef HAVE_KRB4 key_len = Z_keylen(keyblock); #endif retval = Z_ExtractEncCksum(keyblock, &enctype, &cksumtype); if (retval) return (ZAUTH_FAILED); #ifdef HAVE_KRB4 if (key_len == 8 && (enctype == (krb5_enctype)ENCTYPE_DES_CBC_CRC || enctype == (krb5_enctype)ENCTYPE_DES_CBC_MD4 || enctype == (krb5_enctype)ENCTYPE_DES_CBC_MD5)) { C_Block tmp; memcpy(&tmp, Z_keydata(keyblock), key_len); return ZFormatAuthenticNotice(notice, buffer, buffer_len, len, tmp); } #endif newnotice = *notice; newnotice.z_auth = 1; newnotice.z_authent_len = 0; newnotice.z_ascii_authent = ""; if ((retval = Z_NewFormatRawHeader(&newnotice, buffer, buffer_len, &hdrlen, &cksum_start, &cksum_len, &cstart, &cend)) != ZERR_NONE) return (retval); /* we know this is only called by the server */ retval = Z_InsertZcodeChecksum(keyblock, &newnotice, buffer, cksum_start, cksum_len, cstart, cend, buffer_len, &hdr_adj, 1); if (retval) return retval; hdrlen += hdr_adj; ptr = buffer+hdrlen; if (newnotice.z_message_len+hdrlen > buffer_len) return (ZERR_PKTLEN); (void) memcpy(ptr, newnotice.z_message, newnotice.z_message_len); *len = hdrlen+newnotice.z_message_len; if (*len > Z_MAXPKTLEN) return (ZERR_PKTLEN); return (ZERR_NONE); }
Code_t Z_MakeZcodeAuthentication(register ZNotice_t *notice, char *buffer, int buffer_len, int *phdr_len, krb5_creds *creds) { krb5_error_code result = 0; krb5_keyblock *keyblock; krb5_auth_context authctx; krb5_data *authent; char *cksum_start, *cstart, *cend; int cksum_len, zcode_len = 0, phdr_adj = 0; notice->z_ascii_authent = NULL; keyblock = Z_credskey(creds); authent = (krb5_data *)malloc(sizeof(krb5_data)); if (authent == NULL) result = ENOMEM; authent->data = NULL; /* so that we can blithely krb5_fre_data_contents on the way out */ if (!result) result = krb5_auth_con_init(Z_krb5_ctx, &authctx); if (!result) { result = krb5_mk_req_extended(Z_krb5_ctx, &authctx, 0 /* options */, 0 /* in_data */, creds, authent); krb5_auth_con_free(Z_krb5_ctx, authctx); } if (!result || result == KRB5KRB_AP_ERR_TKT_EXPIRED) { notice->z_auth = 1; if (result == 0) { notice->z_authent_len = authent->length; } else { notice->z_authent_len = 0; result = 0; } zcode_len = notice->z_authent_len * 2 + 2; /* 2x growth plus Z and null */ notice->z_ascii_authent = (char *)malloc(zcode_len); if (notice->z_ascii_authent == NULL) result = ENOMEM; } if (!result) result = ZMakeZcode(notice->z_ascii_authent, zcode_len, (unsigned char *)authent->data, notice->z_authent_len); /* format the notice header, with a zero checksum */ if (!result) result = Z_NewFormatRawHeader(notice, buffer, buffer_len, phdr_len, &cksum_start, &cksum_len, &cstart, &cend); notice->z_authent_len = 0; if (!result) result = Z_InsertZcodeChecksum(keyblock, notice, buffer, cksum_start, cksum_len, cstart, cend, buffer_len, &phdr_adj, 0); if (!result) *phdr_len += phdr_adj; if (notice->z_ascii_authent != NULL) free(notice->z_ascii_authent); krb5_free_data_contents(Z_krb5_ctx, authent); if (authent != NULL) free(authent); return result; }