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.26 2001/04/10 23:28:20 ghudson Exp $
19 static const char rcsid_kstuff_c[] = "$Id: kstuff.c,v 1.26 2001/04/10 23:28:20 ghudson Exp $";
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) {
135 syslog(LOG_WARNING,"bad read reply len");
143 if (i == 20 || strncmp(p, "V5-", 3) || !atoi(p+3)) {
144 syslog(LOG_WARNING,"bad reply len");
147 data->length = atoi(p+3);
148 data->data = malloc(data->length);
154 for (i=0; i < data->length; i++) {
155 if (read(fd, dst++, 1) != 1) {
157 memset((char *)data, 0, sizeof(krb5_data));
158 syslog(LOG_WARNING,"bad read reply string");
165 SendKrb5Data(int fd, krb5_data *data) {
167 int written, size_to_write;
168 sprintf(p, "V5-%d", data->length);
169 size_to_write = strlen (p);
170 if (size_to_write != (written = write(fd, p, size_to_write)) ||
171 data->length != (written = write(fd, data->data, data->length))) {
172 return (written < 0) ? errno : ZSRV_PKSHORT;
179 ZCheckRealmAuthentication(notice, from, realm)
181 struct sockaddr_in *from;
186 char rlmprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4+1024];
187 krb5_principal princ;
191 krb5_error_code result;
192 krb5_principal server;
193 krb5_keytab keytabid = 0;
194 krb5_auth_context authctx;
195 krb5_keyblock *keyblock;
196 krb5_enctype enctype;
197 krb5_cksumtype cksumtype;
200 char *cksum0_base, *cksum1_base, *cksum2_base;
201 char *svcinst, *x, *y;
202 char *asn1_data, *key_data;
203 int asn1_len, key_len, cksum0_len, cksum1_len, cksum2_len;
204 #ifdef KRB5_AUTH_CON_GETAUTHENTICATOR_TAKES_DOUBLE_POINTER
205 krb5_authenticator *authenticator;
206 #define KRB5AUTHENT authenticator
208 krb5_authenticator authenticator;
209 #define KRB5AUTHENT &authenticator
216 /* Check for bogus authentication data length. */
217 if (notice->z_authent_len <= 0)
220 len = strlen(notice->z_ascii_authent)+1;
223 /* Read in the authentication data. */
224 if (ZReadZcode(notice->z_ascii_authent,
226 len, &len) == ZERR_BADFIELD) {
230 (void) sprintf(rlmprincipal, "%s/%s@%s", SERVER_SERVICE,
231 SERVER_INSTANCE, realm);
234 packet.data = authbuf;
236 result = krb5_kt_resolve(Z_krb5_ctx,
237 keytab_file, &keytabid);
243 /* HOLDING: authbuf, keytabid */
244 /* Create the auth context */
245 result = krb5_auth_con_init(Z_krb5_ctx, &authctx);
247 krb5_kt_close(Z_krb5_ctx, keytabid);
252 /* HOLDING: authbuf, authctx */
253 result = krb5_build_principal(Z_krb5_ctx, &server, strlen(__Zephyr_realm),
254 __Zephyr_realm, SERVER_SERVICE,
255 SERVER_INSTANCE, NULL);
257 result = krb5_rd_req(Z_krb5_ctx, &authctx, &packet, server,
259 krb5_free_principal(Z_krb5_ctx, server);
261 krb5_kt_close(Z_krb5_ctx, keytabid);
264 if (result == KRB5KRB_AP_ERR_REPEAT)
265 syslog(LOG_DEBUG, "ZCheckRealmAuthentication: k5 auth failed: %s", error_message(result));
267 syslog(LOG_WARNING,"ZCheckRealmAuthentication: k5 auth failed: %s", error_message(result));
269 krb5_auth_con_free(Z_krb5_ctx, authctx);
273 /* HOLDING: authbuf, authctx, tkt */
275 if (tkt == 0 || !Z_tktprincp(tkt)) {
277 krb5_free_ticket(Z_krb5_ctx, tkt);
279 krb5_auth_con_free(Z_krb5_ctx, authctx);
283 princ = Z_tktprinc(tkt);
286 krb5_free_ticket(Z_krb5_ctx, tkt);
288 krb5_auth_con_free(Z_krb5_ctx, authctx);
292 /* HOLDING: authbuf, authctx, tkt */
293 result = krb5_unparse_name(Z_krb5_ctx, princ, &name);
295 syslog(LOG_WARNING, "k5 unparse_name failed: %s",
296 error_message(result));
298 krb5_auth_con_free(Z_krb5_ctx, authctx);
299 krb5_free_ticket(Z_krb5_ctx, tkt);
303 krb5_free_ticket(Z_krb5_ctx, tkt);
305 /* HOLDING: authbuf, authctx, name */
306 if (strcmp(name, rlmprincipal)) {
307 syslog(LOG_WARNING, "k5 name mismatch: '%s' vs '%s'",
309 krb5_auth_con_free(Z_krb5_ctx, authctx);
317 /* HOLDING: authctx */
318 /* Get an authenticator so we can get the keyblock */
319 result = krb5_auth_con_getauthenticator (Z_krb5_ctx, authctx,
322 krb5_auth_con_free(Z_krb5_ctx, authctx);
326 /* HOLDING: authctx, authenticator */
327 result = krb5_auth_con_getkey(Z_krb5_ctx, authctx, &keyblock);
329 krb5_auth_con_free(Z_krb5_ctx, authctx);
330 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
331 return (ZAUTH_FAILED);
334 /* HOLDING: authctx, authenticator, keyblock */
335 /* Figure out what checksum type to use */
336 key_data = Z_keydata(keyblock);
337 key_len = Z_keylen(keyblock);
338 result = Z_ExtractEncCksum(keyblock, &enctype, &cksumtype);
340 krb5_free_keyblock(Z_krb5_ctx, keyblock);
341 krb5_auth_con_free(Z_krb5_ctx, authctx);
342 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
343 return (ZAUTH_FAILED);
345 /* HOLDING: authctx, authenticator, keyblock */
347 /* Assemble the things to be checksummed */
348 /* first part is from start of packet through z_default_format:
350 * - z_num_other_fields
364 cksum0_base = notice->z_packet;
365 x = notice->z_default_format;
366 cksum0_len = x + strlen(x) + 1 - cksum0_base;
367 /* second part is from z_multinotice through other fields:
372 cksum1_base = notice->z_multinotice;
373 if (notice->z_num_other_fields)
374 x = notice->z_other_fields[notice->z_num_other_fields];
376 x = cksum1_base + strlen(cksum1_base) + 1; /* multiuid */
377 cksum1_len = x + strlen(x) + 1 - cksum1_base;
379 /* last part is the message body */
380 cksum2_base = notice->z_message;
381 cksum2_len = notice->z_message_len;
383 if ((!notice->z_ascii_checksum || *notice->z_ascii_checksum != 'Z') &&
385 (enctype == ENCTYPE_DES_CBC_CRC ||
386 enctype == ENCTYPE_DES_CBC_MD4 ||
387 enctype == ENCTYPE_DES_CBC_MD5)) {
388 /* try old-format checksum (covers cksum0 only) */
390 ZChecksum_t our_checksum;
392 our_checksum = compute_rlm_checksum(notice, key_data);
394 krb5_free_keyblock(Z_krb5_ctx, keyblock);
395 krb5_auth_con_free(Z_krb5_ctx, authctx);
396 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
398 if (our_checksum == notice->z_checksum) {
404 /* HOLDING: authctx, authenticator */
406 cksumbuf.length = cksum0_len + cksum1_len + cksum2_len;
407 cksumbuf.data = malloc(cksumbuf.length);
408 if (!cksumbuf.data) {
409 krb5_free_keyblock(Z_krb5_ctx, keyblock);
410 krb5_auth_con_free(Z_krb5_ctx, authctx);
411 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
414 /* HOLDING: authctx, authenticator, cksumbuf.data */
416 memcpy(cksumbuf.data, cksum0_base, cksum0_len);
417 memcpy(cksumbuf.data + cksum0_len, cksum1_base, cksum1_len);
418 memcpy(cksumbuf.data + cksum0_len + cksum1_len,
419 cksum2_base, cksum2_len);
421 /* decode zcoded checksum */
422 /* The encoded form is always longer than the original */
423 asn1_len = strlen(notice->z_ascii_checksum) + 1;
424 asn1_data = malloc(asn1_len);
426 krb5_free_keyblock(Z_krb5_ctx, keyblock);
427 krb5_auth_con_free(Z_krb5_ctx, authctx);
428 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
432 /* HOLDING: authctx, authenticator, cksumbuf.data, asn1_data */
433 result = ZReadZcode(notice->z_ascii_checksum,
434 asn1_data, asn1_len, &asn1_len);
435 if (result != ZERR_NONE) {
436 krb5_free_keyblock(Z_krb5_ctx, keyblock);
437 krb5_auth_con_free(Z_krb5_ctx, authctx);
438 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
443 /* HOLDING: asn1_data, cksumbuf.data */
445 valid = Z_krb5_verify_cksum(keyblock, &cksumbuf, cksumtype, asn1_data, asn1_len);
448 krb5_auth_con_free(Z_krb5_ctx, authctx);
449 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
450 krb5_free_keyblock(Z_krb5_ctx, keyblock);
456 return (ZAUTH_FAILED);
458 return (notice->z_auth) ? ZAUTH_YES : ZAUTH_NO;
463 ZCheckAuthentication(notice, from)
465 struct sockaddr_in *from;
469 krb5_principal princ;
473 krb5_error_code result;
474 krb5_principal server;
475 krb5_keytab keytabid = 0;
476 krb5_auth_context authctx;
477 krb5_keyblock *keyblock;
478 krb5_enctype enctype;
479 krb5_cksumtype cksumtype;
482 char *cksum0_base, *cksum1_base, *cksum2_base;
483 char *svcinst, *x, *y;
484 char *asn1_data, *key_data;
485 int asn1_len, key_len, cksum0_len, cksum1_len, cksum2_len;
486 #ifdef KRB5_AUTH_CON_GETAUTHENTICATOR_TAKES_DOUBLE_POINTER
487 krb5_authenticator *authenticator;
488 #define KRB5AUTHENT authenticator
490 krb5_authenticator authenticator;
491 #define KRB5AUTHENT &authenticator
498 /* Check for bogus authentication data length. */
499 if (notice->z_authent_len <= 1)
503 if (notice->z_ascii_authent[0] != 'Z')
504 return ZCheckAuthentication4(notice, from);
507 len = strlen(notice->z_ascii_authent)+1;
510 /* Read in the authentication data. */
511 if (ZReadZcode(notice->z_ascii_authent,
513 len, &len) == ZERR_BADFIELD) {
518 packet.data = authbuf;
520 result = krb5_kt_resolve(Z_krb5_ctx,
521 keytab_file, &keytabid);
527 /* HOLDING: authbuf, keytabid */
528 /* Create the auth context */
529 result = krb5_auth_con_init(Z_krb5_ctx, &authctx);
531 krb5_kt_close(Z_krb5_ctx, keytabid);
536 /* HOLDING: authbuf, authctx */
537 result = krb5_build_principal(Z_krb5_ctx, &server, strlen(__Zephyr_realm),
538 __Zephyr_realm, SERVER_SERVICE,
539 SERVER_INSTANCE, NULL);
541 result = krb5_rd_req(Z_krb5_ctx, &authctx, &packet, server,
543 krb5_free_principal(Z_krb5_ctx, server);
545 krb5_kt_close(Z_krb5_ctx, keytabid);
548 if (result == KRB5KRB_AP_ERR_REPEAT)
549 syslog(LOG_DEBUG, "ZCheckAuthentication: k5 auth failed: %s", error_message(result));
551 syslog(LOG_WARNING,"ZCheckAuthentication: k5 auth failed: %s", error_message(result));
553 krb5_auth_con_free(Z_krb5_ctx, authctx);
557 /* HOLDING: authbuf, authctx, tkt */
559 if (tkt == 0 || !Z_tktprincp(tkt)) {
561 krb5_free_ticket(Z_krb5_ctx, tkt);
563 krb5_auth_con_free(Z_krb5_ctx, authctx);
566 princ = Z_tktprinc(tkt);
569 krb5_free_ticket(Z_krb5_ctx, tkt);
571 krb5_auth_con_free(Z_krb5_ctx, authctx);
575 /* HOLDING: authbuf, authctx, tkt */
576 result = krb5_unparse_name(Z_krb5_ctx, princ, &name);
578 syslog(LOG_WARNING, "k5 unparse_name failed: %s",
579 error_message(result));
581 krb5_auth_con_free(Z_krb5_ctx, authctx);
582 krb5_free_ticket(Z_krb5_ctx, tkt);
586 krb5_free_ticket(Z_krb5_ctx, tkt);
588 /* HOLDING: authbuf, authctx, name */
589 if (strcmp(name, notice->z_sender)) {
590 syslog(LOG_WARNING, "k5 name mismatch: '%s' vs '%s'",
591 name, notice->z_sender);
592 krb5_auth_con_free(Z_krb5_ctx, authctx);
600 /* HOLDING: authctx */
601 /* Get an authenticator so we can get the keyblock */
602 result = krb5_auth_con_getauthenticator (Z_krb5_ctx, authctx,
605 krb5_auth_con_free(Z_krb5_ctx, authctx);
609 /* HOLDING: authctx, authenticator */
610 result = krb5_auth_con_getkey(Z_krb5_ctx, authctx, &keyblock);
612 krb5_auth_con_free(Z_krb5_ctx, authctx);
613 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
614 return (ZAUTH_FAILED);
617 /* HOLDING: authctx, authenticator, keyblock */
618 /* Figure out what checksum type to use */
619 key_data = Z_keydata(keyblock);
620 key_len = Z_keylen(keyblock);
621 result = Z_ExtractEncCksum(keyblock, &enctype, &cksumtype);
623 krb5_free_keyblock(Z_krb5_ctx, keyblock);
624 krb5_auth_con_free(Z_krb5_ctx, authctx);
625 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
626 return (ZAUTH_FAILED);
628 /* HOLDING: authctx, authenticator, keyblock */
630 ZSetSession(keyblock);
632 /* Assemble the things to be checksummed */
633 /* first part is from start of packet through z_default_format:
635 * - z_num_other_fields
649 cksum0_base = notice->z_packet;
650 x = notice->z_default_format;
651 cksum0_len = x + strlen(x) + 1 - cksum0_base;
652 /* second part is from z_multinotice through other fields:
657 cksum1_base = notice->z_multinotice;
658 if (notice->z_num_other_fields)
659 x = notice->z_other_fields[notice->z_num_other_fields];
661 x = cksum1_base + strlen(cksum1_base) + 1; /* multiuid */
662 cksum1_len = x + strlen(x) + 1 - cksum1_base;
664 /* last part is the message body */
665 cksum2_base = notice->z_message;
666 cksum2_len = notice->z_message_len;
668 if ((!notice->z_ascii_checksum || *notice->z_ascii_checksum != 'Z') &&
670 (enctype == ENCTYPE_DES_CBC_CRC ||
671 enctype == ENCTYPE_DES_CBC_MD4 ||
672 enctype == ENCTYPE_DES_CBC_MD5)) {
673 /* try old-format checksum (covers cksum0 only) */
675 ZChecksum_t our_checksum;
677 our_checksum = compute_checksum(notice, key_data);
679 krb5_free_keyblock(Z_krb5_ctx, keyblock);
680 krb5_auth_con_free(Z_krb5_ctx, authctx);
681 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
683 if (our_checksum == notice->z_checksum)
689 /* HOLDING: authctx, authenticator */
691 cksumbuf.length = cksum0_len + cksum1_len + cksum2_len;
692 cksumbuf.data = malloc(cksumbuf.length);
693 if (!cksumbuf.data) {
694 krb5_free_keyblock(Z_krb5_ctx, keyblock);
695 krb5_auth_con_free(Z_krb5_ctx, authctx);
696 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
699 /* HOLDING: authctx, authenticator, cksumbuf.data */
701 memcpy(cksumbuf.data, cksum0_base, cksum0_len);
702 memcpy(cksumbuf.data + cksum0_len, cksum1_base, cksum1_len);
703 memcpy(cksumbuf.data + cksum0_len + cksum1_len,
704 cksum2_base, cksum2_len);
706 /* decode zcoded checksum */
707 /* The encoded form is always longer than the original */
708 asn1_len = strlen(notice->z_ascii_checksum) + 1;
709 asn1_data = malloc(asn1_len);
711 krb5_free_keyblock(Z_krb5_ctx, keyblock);
712 krb5_auth_con_free(Z_krb5_ctx, authctx);
713 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
717 /* HOLDING: authctx, authenticator, cksumbuf.data, asn1_data */
718 result = ZReadZcode(notice->z_ascii_checksum,
719 asn1_data, asn1_len, &asn1_len);
720 if (result != ZERR_NONE) {
721 krb5_free_keyblock(Z_krb5_ctx, keyblock);
722 krb5_auth_con_free(Z_krb5_ctx, authctx);
723 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
728 /* HOLDING: asn1_data, cksumbuf.data, authctx, authenticator */
730 valid = Z_krb5_verify_cksum(keyblock, &cksumbuf, cksumtype, asn1_data, asn1_len);
733 krb5_auth_con_free(Z_krb5_ctx, authctx);
734 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
735 krb5_free_keyblock(Z_krb5_ctx, keyblock);
741 return (ZAUTH_FAILED);
743 return (notice->z_auth) ? ZAUTH_YES : ZAUTH_NO;
750 ZCheckAuthentication4(notice, from)
752 struct sockaddr_in *from;
756 char srcprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4];
757 KTEXT_ST authent, ticket;
759 ZChecksum_t checksum;
761 char instance[INST_SZ+1];
766 /* Check for bogus authentication data length. */
767 if (notice->z_authent_len <= 0)
770 /* Read in the authentication data. */
771 if (ZReadAscii(notice->z_ascii_authent,
772 strlen(notice->z_ascii_authent)+1,
773 (unsigned char *)authent.dat,
774 notice->z_authent_len) == ZERR_BADFIELD) {
777 authent.length = notice->z_authent_len;
779 strcpy(instance, SERVER_INSTANCE);
781 /* We don't have the session key cached; do it the long way. */
782 result = krb_rd_req(&authent, SERVER_SERVICE, instance,
783 from->sin_addr.s_addr, &dat, srvtab_file);
784 if (result == RD_AP_OK) {
785 ZSetSessionDES(&dat.session);
786 sprintf(srcprincipal, "%s%s%s@%s", dat.pname, dat.pinst[0] ? "." : "",
787 dat.pinst, dat.prealm);
788 if (strcmp(srcprincipal, notice->z_sender))
791 return ZAUTH_FAILED; /* didn't decode correctly */
794 /* Check the cryptographic checksum. */
798 checksum = compute_checksum(notice, dat.session);
800 if (checksum != notice->z_checksum)
805 #else /* !HAVE_KRB4 */
806 return (notice->z_auth) ? ZAUTH_YES : ZAUTH_NO;
812 static ZChecksum_t compute_checksum(notice, session_key)
819 ZChecksum_t checksum;
820 char *cstart, *cend, *hstart = notice->z_packet, *hend = notice->z_message;
822 cstart = notice->z_default_format + strlen(notice->z_default_format) + 1;
823 cend = cstart + strlen(cstart) + 1;
824 checksum = des_quad_cksum(hstart, NULL, cstart - hstart, 0, session_key);
825 checksum ^= des_quad_cksum(cend, NULL, hend - cend, 0, session_key);
826 checksum ^= des_quad_cksum(notice->z_message, NULL, notice->z_message_len,
832 static ZChecksum_t compute_rlm_checksum(notice, session_key)
839 ZChecksum_t checksum;
840 char *cstart, *cend, *hstart = notice->z_packet, *hend = notice->z_message;
842 cstart = notice->z_default_format + strlen(notice->z_default_format) + 1;
843 cend = cstart + strlen(cstart) + 1;
844 checksum = des_quad_cksum(hstart, NULL, cstart - hstart, 0, session_key);
851 ZSetSession(krb5_keyblock *keyblock) {
853 krb5_error_code result;
855 if (__Zephyr_keyblock) {
856 krb5_free_keyblock_contents(Z_krb5_ctx, __Zephyr_keyblock);
857 result = krb5_copy_keyblock_contents(Z_krb5_ctx, keyblock, __Zephyr_keyblock);
859 result = krb5_copy_keyblock(Z_krb5_ctx, keyblock, &__Zephyr_keyblock);
862 if (result) /*XXX we're out of memory? */
865 memcpy(__Zephyr_session, Z_keydata(keyblock), sizeof(C_Block));
871 ZSetSessionDES(C_Block *key) {
874 #ifdef HAVE_KRB5_INIT_KEYBLOCK
875 if (__Zephyr_keyblock) {
876 krb5_free_keyblock(__Zephyr_keyblock);
877 __Zephyr_keyblock=NULL;
879 result = krb5_init_keyblock(Z_krb5_ctx, ENCTYPE_DES_CBC_CRC,
882 if (result) /*XXX we're out of memory? */
885 memcpy(Z_keydata(__Zephyr_keyblock), key, sizeof(C_Block));
887 krb5_keyblock *tmp, tmp_ss;
889 Z_keylen(tmp)=sizeof(C_Block);
891 #if HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE
892 tmp->enctype = ENCTYPE_DES_CBC_CRC;
894 tmp->keytype = KEYTYPE_DES;
896 if (__Zephyr_keyblock) {
897 krb5_free_keyblock_contents(Z_krb5_ctx, __Zephyr_keyblock);
898 result = krb5_copy_keyblock_contents(Z_krb5_ctx, tmp,
901 result = krb5_copy_keyblock(Z_krb5_ctx, tmp, &__Zephyr_keyblock);
903 if (result) /*XXX we're out of memory? */
907 memcpy(__Zephyr_session, key, sizeof(C_Block));
912 #endif /* HAVE_KRB4 */