+Z_InsertZcodeChecksum(krb5_keyblock *keyblock, ZNotice_t *notice,
+ char *buffer, char *cksum_start, int cksum_len,
+ char *cstart, char *cend, int buffer_len,
+ int *length_adjust)
+{
+ int plain_len; /* length of part not to be checksummed */
+ int cksum0_len; /* length of part before checksum */
+ int cksum1_len; /* length of part after checksum */
+ krb5_data cksumbuf;
+ krb5_data cksum;
+ char *key_data;
+ int key_len;
+ krb5_enctype enctype;
+ krb5_cksumtype cksumtype;
+ Code_t result;
+
+ key_data = Z_keydata(keyblock);
+ key_len = Z_keylen(keyblock);
+ result = Z_ExtractEncCksum(keyblock, &enctype, &cksumtype);
+ if (result)
+ return (ZAUTH_FAILED);
+
+ /* Assemble the things to be checksummed */
+ plain_len = cksum_start - buffer;
+ cksum0_len = cstart - cksum_start;
+ cksum1_len = (cksum_start + cksum_len) - cend;
+ memset(&cksumbuf, 0, sizeof(cksumbuf));
+ cksumbuf.length = cksum0_len + cksum1_len + notice->z_message_len;
+ cksumbuf.data = malloc(cksumbuf.length);
+ if (!cksumbuf.data)
+ return ENOMEM;
+ memcpy(cksumbuf.data, cksum_start, cksum0_len);
+ memcpy(cksumbuf.data + cksum0_len, cend, cksum1_len);
+ memcpy(cksumbuf.data + cksum0_len + cksum1_len,
+ notice->z_message, notice->z_message_len);
+ /* compute the checksum */
+ result = Z_Checksum(&cksumbuf, keyblock, cksumtype,
+ (char **)&cksum.data, &cksum.length);
+ if (result) {
+ free(cksumbuf.data);
+ return result;
+ }
+
+ /*
+ * OK.... we can zcode to a space starting at 'cstart',
+ * with a length of buffer_len - (plain_len + cksum_len).
+ * Then we tack on the end part, which is located at
+ * cksumbuf.data + cksum0_len and has length cksum1_len
+ */
+
+ result = ZMakeZcode(cstart, buffer_len - (plain_len + cksum_len),
+ cksum.data, cksum.length);
+ free(cksum.data);
+ if (!result) {
+ int zcode_len = strlen(cstart) + 1;
+ memcpy(cstart + zcode_len, cksumbuf.data + cksum0_len, cksum1_len);
+ *length_adjust = zcode_len - cksum_len + (cksum0_len + cksum1_len);
+ }
+ free(cksumbuf.data);
+ return result;
+}
+
+Code_t
+Z_ExtractEncCksum(krb5_keyblock *keyblock, krb5_enctype *enctype,
+ krb5_cksumtype *cksumtype) {