1 /* This file is part of the Project Athena Zephyr Notification System.
2 * It contains functions for dealing with Kerberos functions in the server.
4 * Created by: John T Kohl
6 * Copyright (c) 1988 by the Massachusetts Institute of Technology.
7 * For copying and distribution information, see the file
11 * $Source: /afs/dev.mit.edu/source/repository/athena/lib/zephyr/server/kstuff.c,v $
12 * $Header: /afs/dev.mit.edu/source/repository/athena/lib/zephyr/server/kstuff.c,v 1.27 2004/02/29 06:34:04 zacheiss Exp $
19 static const char rcsid_kstuff_c[] = "$Id$";
25 static ZChecksum_t compute_checksum __P((ZNotice_t *, C_Block));
26 static ZChecksum_t compute_rlm_checksum __P((ZNotice_t *, C_Block));
31 * get ticket from file descriptor and decode it.
32 * Return KFAILURE if we barf on reading the ticket, else return
33 * the value of rd_ap_req() applied to the ticket.
36 GetKerberosData(fd, haddr, kdata, service, srvtab)
37 int fd; /* file descr. to read from */
38 struct in_addr haddr; /* address of foreign host on fd */
39 AUTH_DAT *kdata; /* kerberos data (returned) */
40 char *service; /* service principal desired */
41 char *srvtab; /* file to get keys from */
44 KTEXT_ST ticket; /* will get Kerberos ticket from client */
46 char instance[INST_SZ];
49 * Get the Kerberos ticket. The first few characters, terminated
50 * by a blank, should give us a length; then get than many chars
51 * which will be the ticket proper.
53 for (i=0; i<20; i++) {
54 if (read(fd, &p[i], 1) != 1) {
55 syslog(LOG_WARNING,"bad read tkt len");
63 ticket.length = atoi(p);
64 if ((i==20) || (ticket.length<=0) || (ticket.length>MAX_KTXT_LEN)) {
65 syslog(LOG_WARNING,"bad tkt len %d",ticket.length);
68 for (i=0; i<ticket.length; i++) {
69 if (read(fd, (caddr_t) &(ticket.dat[i]), 1) != 1) {
70 syslog(LOG_WARNING,"bad tkt read");
75 * now have the ticket. use it to get the authenticated
78 (void) strcpy(instance,"*"); /* let Kerberos fill it in */
80 return(krb_rd_req(&ticket, service, instance, haddr.s_addr,
81 kdata, srvtab ? srvtab : ""));
87 * create and transmit a ticket over the file descriptor for service.host
88 * return failure codes if appropriate, or 0 if we
89 * get the ticket and write it to the file descriptor
92 #if !defined(krb_err_base) && defined(ERROR_TABLE_BASE_krb)
93 #define krb_err_base ERROR_TABLE_BASE_krb
97 SendKerberosData(fd, ticket, service, host)
98 int fd; /* file descriptor to write onto */
99 KTEXT ticket; /* where to put ticket (return) */
100 char *service; /* service name, foreign host */
108 rem = krb_mk_req(ticket, service, host, ZGetRealm(), (u_long) 0);
110 return rem + krb_err_base;
112 (void) sprintf(p,"%d ",ticket->length);
113 size_to_write = strlen (p);
114 if ((written = write(fd, p, size_to_write)) != size_to_write)
115 return (written < 0) ? errno : ZSRV_PKSHORT;
116 if ((written = write(fd, (caddr_t) (ticket->dat), ticket->length))
118 return (written < 0) ? errno : ZSRV_PKSHORT;
123 #endif /* HAVE_KRB4 */
127 GetKrb5Data(int fd, krb5_data *data) {
133 for (i=0; i<20; i++) {
134 if (read(fd, &p[i], 1) != 1) {
136 syslog(LOG_WARNING,"bad read reply len @%d (got \"%s\")", i, p);
144 if (i == 20 || strncmp(p, "V5-", 3) || !atoi(p+3)) {
145 syslog(LOG_WARNING,"bad reply len");
148 data->length = atoi(p+3);
149 data->data = malloc(data->length);
155 for (i=0; i < data->length; i++) {
156 if (read(fd, dst++, 1) != 1) {
158 memset((char *)data, 0, sizeof(krb5_data));
159 syslog(LOG_WARNING,"bad read reply string");
166 SendKrb5Data(int fd, krb5_data *data) {
168 int written, size_to_write;
169 sprintf(p, "V5-%d ", data->length);
170 size_to_write = strlen (p);
171 if (size_to_write != (written = write(fd, p, size_to_write)) ||
172 data->length != (written = write(fd, data->data, data->length))) {
173 return (written < 0) ? errno : ZSRV_PKSHORT;
180 ZCheckRealmAuthentication(notice, from, realm)
182 struct sockaddr_in *from;
187 char rlmprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4+1024];
188 krb5_principal princ;
192 krb5_error_code result;
193 krb5_principal server;
194 krb5_keytab keytabid = 0;
195 krb5_auth_context authctx;
196 krb5_keyblock *keyblock;
197 krb5_enctype enctype;
198 krb5_cksumtype cksumtype;
201 char *cksum0_base, *cksum1_base, *cksum2_base;
202 char *svcinst, *x, *y;
203 char *asn1_data, *key_data;
204 int asn1_len, key_len, cksum0_len, cksum1_len, cksum2_len;
205 #ifdef KRB5_AUTH_CON_GETAUTHENTICATOR_TAKES_DOUBLE_POINTER
206 krb5_authenticator *authenticator;
207 #define KRB5AUTHENT authenticator
209 krb5_authenticator authenticator;
210 #define KRB5AUTHENT &authenticator
217 /* Check for bogus authentication data length. */
218 if (notice->z_authent_len <= 0)
221 len = strlen(notice->z_ascii_authent)+1;
224 /* Read in the authentication data. */
225 if (ZReadZcode(notice->z_ascii_authent,
227 len, &len) == ZERR_BADFIELD) {
231 (void) sprintf(rlmprincipal, "%s/%s@%s", SERVER_SERVICE,
232 SERVER_INSTANCE, realm);
235 packet.data = authbuf;
237 result = krb5_kt_resolve(Z_krb5_ctx,
238 keytab_file, &keytabid);
244 /* HOLDING: authbuf, keytabid */
245 /* Create the auth context */
246 result = krb5_auth_con_init(Z_krb5_ctx, &authctx);
248 krb5_kt_close(Z_krb5_ctx, keytabid);
253 /* HOLDING: authbuf, authctx */
254 result = krb5_build_principal(Z_krb5_ctx, &server, strlen(__Zephyr_realm),
255 __Zephyr_realm, SERVER_SERVICE,
256 SERVER_INSTANCE, NULL);
258 result = krb5_rd_req(Z_krb5_ctx, &authctx, &packet, server,
260 krb5_free_principal(Z_krb5_ctx, server);
262 krb5_kt_close(Z_krb5_ctx, keytabid);
265 if (result == KRB5KRB_AP_ERR_REPEAT)
266 syslog(LOG_DEBUG, "ZCheckRealmAuthentication: k5 auth failed: %s", error_message(result));
268 syslog(LOG_WARNING,"ZCheckRealmAuthentication: k5 auth failed: %s", error_message(result));
270 krb5_auth_con_free(Z_krb5_ctx, authctx);
274 /* HOLDING: authbuf, authctx, tkt */
276 if (tkt == 0 || !Z_tktprincp(tkt)) {
278 krb5_free_ticket(Z_krb5_ctx, tkt);
280 krb5_auth_con_free(Z_krb5_ctx, authctx);
284 princ = Z_tktprinc(tkt);
287 krb5_free_ticket(Z_krb5_ctx, tkt);
289 krb5_auth_con_free(Z_krb5_ctx, authctx);
293 /* HOLDING: authbuf, authctx, tkt */
294 result = krb5_unparse_name(Z_krb5_ctx, princ, &name);
296 syslog(LOG_WARNING, "k5 unparse_name failed: %s",
297 error_message(result));
299 krb5_auth_con_free(Z_krb5_ctx, authctx);
300 krb5_free_ticket(Z_krb5_ctx, tkt);
304 krb5_free_ticket(Z_krb5_ctx, tkt);
306 /* HOLDING: authbuf, authctx, name */
307 if (strcmp(name, rlmprincipal)) {
308 syslog(LOG_WARNING, "k5 name mismatch: '%s' vs '%s'",
310 krb5_auth_con_free(Z_krb5_ctx, authctx);
318 /* HOLDING: authctx */
319 /* Get an authenticator so we can get the keyblock */
320 result = krb5_auth_con_getauthenticator (Z_krb5_ctx, authctx,
323 krb5_auth_con_free(Z_krb5_ctx, authctx);
327 /* HOLDING: authctx, authenticator */
328 result = krb5_auth_con_getkey(Z_krb5_ctx, authctx, &keyblock);
330 krb5_auth_con_free(Z_krb5_ctx, authctx);
331 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
332 return (ZAUTH_FAILED);
335 /* HOLDING: authctx, authenticator, keyblock */
336 /* Figure out what checksum type to use */
337 key_data = Z_keydata(keyblock);
338 key_len = Z_keylen(keyblock);
339 result = Z_ExtractEncCksum(keyblock, &enctype, &cksumtype);
341 krb5_free_keyblock(Z_krb5_ctx, keyblock);
342 krb5_auth_con_free(Z_krb5_ctx, authctx);
343 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
344 return (ZAUTH_FAILED);
346 /* HOLDING: authctx, authenticator, keyblock */
348 /* Assemble the things to be checksummed */
349 /* first part is from start of packet through z_default_format:
351 * - z_num_other_fields
365 cksum0_base = notice->z_packet;
366 x = notice->z_default_format;
367 cksum0_len = x + strlen(x) + 1 - cksum0_base;
368 /* second part is from z_multinotice through other fields:
373 cksum1_base = notice->z_multinotice;
374 if (notice->z_num_other_fields)
375 x = notice->z_other_fields[notice->z_num_other_fields];
377 x = cksum1_base + strlen(cksum1_base) + 1; /* multiuid */
378 cksum1_len = x + strlen(x) + 1 - cksum1_base;
380 /* last part is the message body */
381 cksum2_base = notice->z_message;
382 cksum2_len = notice->z_message_len;
384 if ((!notice->z_ascii_checksum || *notice->z_ascii_checksum != 'Z') &&
386 (enctype == ENCTYPE_DES_CBC_CRC ||
387 enctype == ENCTYPE_DES_CBC_MD4 ||
388 enctype == ENCTYPE_DES_CBC_MD5)) {
389 /* try old-format checksum (covers cksum0 only) */
391 ZChecksum_t our_checksum;
393 our_checksum = compute_rlm_checksum(notice, key_data);
395 krb5_free_keyblock(Z_krb5_ctx, keyblock);
396 krb5_auth_con_free(Z_krb5_ctx, authctx);
397 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
399 if (our_checksum == notice->z_checksum) {
405 /* HOLDING: authctx, authenticator */
407 cksumbuf.length = cksum0_len + cksum1_len + cksum2_len;
408 cksumbuf.data = malloc(cksumbuf.length);
409 if (!cksumbuf.data) {
410 krb5_free_keyblock(Z_krb5_ctx, keyblock);
411 krb5_auth_con_free(Z_krb5_ctx, authctx);
412 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
415 /* HOLDING: authctx, authenticator, cksumbuf.data */
417 memcpy(cksumbuf.data, cksum0_base, cksum0_len);
418 memcpy(cksumbuf.data + cksum0_len, cksum1_base, cksum1_len);
419 memcpy(cksumbuf.data + cksum0_len + cksum1_len,
420 cksum2_base, cksum2_len);
422 /* decode zcoded checksum */
423 /* The encoded form is always longer than the original */
424 asn1_len = strlen(notice->z_ascii_checksum) + 1;
425 asn1_data = malloc(asn1_len);
427 krb5_free_keyblock(Z_krb5_ctx, keyblock);
428 krb5_auth_con_free(Z_krb5_ctx, authctx);
429 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
433 /* HOLDING: authctx, authenticator, cksumbuf.data, asn1_data */
434 result = ZReadZcode(notice->z_ascii_checksum,
435 asn1_data, asn1_len, &asn1_len);
436 if (result != ZERR_NONE) {
437 krb5_free_keyblock(Z_krb5_ctx, keyblock);
438 krb5_auth_con_free(Z_krb5_ctx, authctx);
439 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
444 /* HOLDING: asn1_data, cksumbuf.data */
446 valid = Z_krb5_verify_cksum(keyblock, &cksumbuf, cksumtype, asn1_data, asn1_len);
449 krb5_auth_con_free(Z_krb5_ctx, authctx);
450 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
451 krb5_free_keyblock(Z_krb5_ctx, keyblock);
457 return (ZAUTH_FAILED);
459 return (notice->z_auth) ? ZAUTH_YES : ZAUTH_NO;
464 ZCheckAuthentication(notice, from)
466 struct sockaddr_in *from;
470 krb5_principal princ;
474 krb5_error_code result;
475 krb5_principal server;
476 krb5_keytab keytabid = 0;
477 krb5_auth_context authctx;
478 krb5_keyblock *keyblock;
479 krb5_enctype enctype;
480 krb5_cksumtype cksumtype;
483 char *cksum0_base, *cksum1_base, *cksum2_base;
484 char *svcinst, *x, *y;
485 char *asn1_data, *key_data;
486 int asn1_len, key_len, cksum0_len, cksum1_len, cksum2_len;
487 #ifdef KRB5_AUTH_CON_GETAUTHENTICATOR_TAKES_DOUBLE_POINTER
488 krb5_authenticator *authenticator;
489 #define KRB5AUTHENT authenticator
491 krb5_authenticator authenticator;
492 #define KRB5AUTHENT &authenticator
499 /* Check for bogus authentication data length. */
500 if (notice->z_authent_len <= 1)
504 if (notice->z_ascii_authent[0] != 'Z')
505 return ZCheckAuthentication4(notice, from);
508 len = strlen(notice->z_ascii_authent)+1;
511 /* Read in the authentication data. */
512 if (ZReadZcode(notice->z_ascii_authent,
514 len, &len) == ZERR_BADFIELD) {
519 packet.data = authbuf;
521 result = krb5_kt_resolve(Z_krb5_ctx,
522 keytab_file, &keytabid);
528 /* HOLDING: authbuf, keytabid */
529 /* Create the auth context */
530 result = krb5_auth_con_init(Z_krb5_ctx, &authctx);
532 krb5_kt_close(Z_krb5_ctx, keytabid);
537 /* HOLDING: authbuf, authctx */
538 result = krb5_build_principal(Z_krb5_ctx, &server, strlen(__Zephyr_realm),
539 __Zephyr_realm, SERVER_SERVICE,
540 SERVER_INSTANCE, NULL);
542 result = krb5_rd_req(Z_krb5_ctx, &authctx, &packet, server,
544 krb5_free_principal(Z_krb5_ctx, server);
546 krb5_kt_close(Z_krb5_ctx, keytabid);
549 if (result == KRB5KRB_AP_ERR_REPEAT)
550 syslog(LOG_DEBUG, "ZCheckAuthentication: k5 auth failed: %s", error_message(result));
552 syslog(LOG_WARNING,"ZCheckAuthentication: k5 auth failed: %s", error_message(result));
554 krb5_auth_con_free(Z_krb5_ctx, authctx);
558 /* HOLDING: authbuf, authctx, tkt */
560 if (tkt == 0 || !Z_tktprincp(tkt)) {
562 krb5_free_ticket(Z_krb5_ctx, tkt);
564 krb5_auth_con_free(Z_krb5_ctx, authctx);
567 princ = Z_tktprinc(tkt);
570 krb5_free_ticket(Z_krb5_ctx, tkt);
572 krb5_auth_con_free(Z_krb5_ctx, authctx);
576 /* HOLDING: authbuf, authctx, tkt */
577 result = krb5_unparse_name(Z_krb5_ctx, princ, &name);
579 syslog(LOG_WARNING, "k5 unparse_name failed: %s",
580 error_message(result));
582 krb5_auth_con_free(Z_krb5_ctx, authctx);
583 krb5_free_ticket(Z_krb5_ctx, tkt);
587 krb5_free_ticket(Z_krb5_ctx, tkt);
589 /* HOLDING: authbuf, authctx, name */
590 if (strcmp(name, notice->z_sender)) {
591 syslog(LOG_WARNING, "k5 name mismatch: '%s' vs '%s'",
592 name, notice->z_sender);
593 krb5_auth_con_free(Z_krb5_ctx, authctx);
601 /* HOLDING: authctx */
602 /* Get an authenticator so we can get the keyblock */
603 result = krb5_auth_con_getauthenticator (Z_krb5_ctx, authctx,
606 krb5_auth_con_free(Z_krb5_ctx, authctx);
610 /* HOLDING: authctx, authenticator */
611 result = krb5_auth_con_getkey(Z_krb5_ctx, authctx, &keyblock);
613 krb5_auth_con_free(Z_krb5_ctx, authctx);
614 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
615 return (ZAUTH_FAILED);
618 /* HOLDING: authctx, authenticator, keyblock */
619 /* Figure out what checksum type to use */
620 key_data = Z_keydata(keyblock);
621 key_len = Z_keylen(keyblock);
622 result = Z_ExtractEncCksum(keyblock, &enctype, &cksumtype);
624 krb5_free_keyblock(Z_krb5_ctx, keyblock);
625 krb5_auth_con_free(Z_krb5_ctx, authctx);
626 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
627 return (ZAUTH_FAILED);
629 /* HOLDING: authctx, authenticator, keyblock */
631 ZSetSession(keyblock);
633 /* Assemble the things to be checksummed */
634 /* first part is from start of packet through z_default_format:
636 * - z_num_other_fields
650 cksum0_base = notice->z_packet;
651 x = notice->z_default_format;
652 cksum0_len = x + strlen(x) + 1 - cksum0_base;
653 /* second part is from z_multinotice through other fields:
658 cksum1_base = notice->z_multinotice;
659 if (notice->z_num_other_fields)
660 x = notice->z_other_fields[notice->z_num_other_fields];
662 x = cksum1_base + strlen(cksum1_base) + 1; /* multiuid */
663 cksum1_len = x + strlen(x) + 1 - cksum1_base;
665 /* last part is the message body */
666 cksum2_base = notice->z_message;
667 cksum2_len = notice->z_message_len;
669 if ((!notice->z_ascii_checksum || *notice->z_ascii_checksum != 'Z') &&
671 (enctype == ENCTYPE_DES_CBC_CRC ||
672 enctype == ENCTYPE_DES_CBC_MD4 ||
673 enctype == ENCTYPE_DES_CBC_MD5)) {
674 /* try old-format checksum (covers cksum0 only) */
676 ZChecksum_t our_checksum;
678 our_checksum = compute_checksum(notice, key_data);
680 krb5_free_keyblock(Z_krb5_ctx, keyblock);
681 krb5_auth_con_free(Z_krb5_ctx, authctx);
682 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
684 if (our_checksum == notice->z_checksum)
690 /* HOLDING: authctx, authenticator */
692 cksumbuf.length = cksum0_len + cksum1_len + cksum2_len;
693 cksumbuf.data = malloc(cksumbuf.length);
694 if (!cksumbuf.data) {
695 krb5_free_keyblock(Z_krb5_ctx, keyblock);
696 krb5_auth_con_free(Z_krb5_ctx, authctx);
697 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
700 /* HOLDING: authctx, authenticator, cksumbuf.data */
702 memcpy(cksumbuf.data, cksum0_base, cksum0_len);
703 memcpy(cksumbuf.data + cksum0_len, cksum1_base, cksum1_len);
704 memcpy(cksumbuf.data + cksum0_len + cksum1_len,
705 cksum2_base, cksum2_len);
707 /* decode zcoded checksum */
708 /* The encoded form is always longer than the original */
709 asn1_len = strlen(notice->z_ascii_checksum) + 1;
710 asn1_data = malloc(asn1_len);
712 krb5_free_keyblock(Z_krb5_ctx, keyblock);
713 krb5_auth_con_free(Z_krb5_ctx, authctx);
714 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
718 /* HOLDING: authctx, authenticator, cksumbuf.data, asn1_data */
719 result = ZReadZcode(notice->z_ascii_checksum,
720 asn1_data, asn1_len, &asn1_len);
721 if (result != ZERR_NONE) {
722 krb5_free_keyblock(Z_krb5_ctx, keyblock);
723 krb5_auth_con_free(Z_krb5_ctx, authctx);
724 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
729 /* HOLDING: asn1_data, cksumbuf.data, authctx, authenticator */
731 valid = Z_krb5_verify_cksum(keyblock, &cksumbuf, cksumtype, asn1_data, asn1_len);
734 krb5_auth_con_free(Z_krb5_ctx, authctx);
735 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
736 krb5_free_keyblock(Z_krb5_ctx, keyblock);
742 return (ZAUTH_FAILED);
744 return (notice->z_auth) ? ZAUTH_YES : ZAUTH_NO;
751 ZCheckAuthentication4(notice, from)
753 struct sockaddr_in *from;
757 char srcprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4];
758 KTEXT_ST authent, ticket;
760 ZChecksum_t checksum;
762 char instance[INST_SZ+1];
767 /* Check for bogus authentication data length. */
768 if (notice->z_authent_len <= 0)
771 /* Read in the authentication data. */
772 if (ZReadAscii(notice->z_ascii_authent,
773 strlen(notice->z_ascii_authent)+1,
774 (unsigned char *)authent.dat,
775 notice->z_authent_len) == ZERR_BADFIELD) {
778 authent.length = notice->z_authent_len;
780 strcpy(instance, SERVER_INSTANCE);
782 /* We don't have the session key cached; do it the long way. */
783 result = krb_rd_req(&authent, SERVER_SERVICE, instance,
784 from->sin_addr.s_addr, &dat, srvtab_file);
785 if (result == RD_AP_OK) {
786 ZSetSessionDES(&dat.session);
787 sprintf(srcprincipal, "%s%s%s@%s", dat.pname, dat.pinst[0] ? "." : "",
788 dat.pinst, dat.prealm);
789 if (strcmp(srcprincipal, notice->z_sender))
792 return ZAUTH_FAILED; /* didn't decode correctly */
795 /* Check the cryptographic checksum. */
799 checksum = compute_checksum(notice, dat.session);
801 if (checksum != notice->z_checksum)
806 #else /* !HAVE_KRB4 */
807 return (notice->z_auth) ? ZAUTH_YES : ZAUTH_NO;
813 static ZChecksum_t compute_checksum(notice, session_key)
820 ZChecksum_t checksum;
821 char *cstart, *cend, *hstart = notice->z_packet, *hend = notice->z_message;
823 cstart = notice->z_default_format + strlen(notice->z_default_format) + 1;
824 cend = cstart + strlen(cstart) + 1;
825 checksum = des_quad_cksum(hstart, NULL, cstart - hstart, 0, session_key);
826 checksum ^= des_quad_cksum(cend, NULL, hend - cend, 0, session_key);
827 checksum ^= des_quad_cksum(notice->z_message, NULL, notice->z_message_len,
833 static ZChecksum_t compute_rlm_checksum(notice, session_key)
840 ZChecksum_t checksum;
841 char *cstart, *cend, *hstart = notice->z_packet, *hend = notice->z_message;
843 cstart = notice->z_default_format + strlen(notice->z_default_format) + 1;
844 cend = cstart + strlen(cstart) + 1;
845 checksum = des_quad_cksum(hstart, NULL, cstart - hstart, 0, session_key);
852 Z_krb5_init_keyblock(krb5_context context,
857 #ifdef HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE
858 return krb5_init_keyblock(context, type, size, key);
861 krb5_keyblock *tmp, tmp_ss;
865 Z_enctype(tmp) = type;
866 Z_keylen(tmp) = size;
867 Z_keydata(tmp) = malloc(size);
870 ret = krb5_copy_keyblock(context, tmp, key);
871 free(Z_keydata(tmp));
877 void ZLogKey(char *label, krb5_keyblock *keyblock) {
881 buf = malloc(5 *Z_keylen(keyblock)+1);
883 k=Z_keydata(keyblock);
884 for (i=0,p=buf; i < Z_keylen(keyblock); i++,p+=strlen(p))
885 sprintf(p, " 0x%02x", k[i]);
886 syslog(LOG_ERR, "key %s is type %d, %d bytes, %s", label, Z_enctype(keyblock), Z_keylen(keyblock), buf);
892 ZSetSession(krb5_keyblock *keyblock) {
894 krb5_error_code result;
896 if (__Zephyr_keyblock) {
897 krb5_free_keyblock_contents(Z_krb5_ctx, __Zephyr_keyblock);
898 result = krb5_copy_keyblock_contents(Z_krb5_ctx, keyblock, __Zephyr_keyblock);
900 result = krb5_copy_keyblock(Z_krb5_ctx, keyblock, &__Zephyr_keyblock);
903 if (result) /*XXX we're out of memory? */
906 memcpy(__Zephyr_session, Z_keydata(keyblock), sizeof(C_Block));
912 ZSetSessionDES(C_Block *key) {
915 if (__Zephyr_keyblock) {
916 krb5_free_keyblock(Z_krb5_ctx, __Zephyr_keyblock);
917 __Zephyr_keyblock=NULL;
919 result = Z_krb5_init_keyblock(Z_krb5_ctx, ENCTYPE_DES_CBC_CRC,
922 if (result) /*XXX we're out of memory? */
925 memcpy(Z_keydata(__Zephyr_keyblock), key, sizeof(C_Block));
927 memcpy(__Zephyr_session, key, sizeof(C_Block));
932 #endif /* HAVE_KRB4 */