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(int fd, /* file descr. to read from */
37 struct in_addr haddr, /* address of foreign host on fd */
38 AUTH_DAT *kdata, /* kerberos data (returned) */
39 char *service, /* service principal desired */
40 char *srvtab) /* file to get keys from */
43 KTEXT_ST ticket; /* will get Kerberos ticket from client */
45 char instance[INST_SZ];
48 * Get the Kerberos ticket. The first few characters, terminated
49 * by a blank, should give us a length; then get than many chars
50 * which will be the ticket proper.
52 for (i=0; i<20; i++) {
53 if (read(fd, &p[i], 1) != 1) {
54 syslog(LOG_WARNING,"bad read tkt len");
62 ticket.length = atoi(p);
63 if ((i==20) || (ticket.length<=0) || (ticket.length>MAX_KTXT_LEN)) {
64 syslog(LOG_WARNING,"bad tkt len %d",ticket.length);
67 for (i=0; i<ticket.length; i++) {
68 if (read(fd, (caddr_t) &(ticket.dat[i]), 1) != 1) {
69 syslog(LOG_WARNING,"bad tkt read");
74 * now have the ticket. use it to get the authenticated
77 (void) strcpy(instance,"*"); /* let Kerberos fill it in */
79 return(krb_rd_req(&ticket, service, instance, haddr.s_addr,
80 kdata, srvtab ? srvtab : ""));
86 * create and transmit a ticket over the file descriptor for service.host
87 * return failure codes if appropriate, or 0 if we
88 * get the ticket and write it to the file descriptor
91 #if !defined(krb_err_base) && defined(ERROR_TABLE_BASE_krb)
92 #define krb_err_base ERROR_TABLE_BASE_krb
96 SendKerberosData(int fd, /* file descriptor to write onto */
97 KTEXT ticket, /* where to put ticket (return) */
98 char *service, /* service name, foreign host */
107 rem = krb_mk_req(ticket, service, host, ZGetRealm(), (u_long) 0);
109 return rem + krb_err_base;
111 (void) sprintf(p,"%d ",ticket->length);
112 size_to_write = strlen (p);
113 if ((written = write(fd, p, size_to_write)) != size_to_write)
114 return (written < 0) ? errno : ZSRV_PKSHORT;
115 if ((written = write(fd, (caddr_t) (ticket->dat), ticket->length))
117 return (written < 0) ? errno : ZSRV_PKSHORT;
122 #endif /* HAVE_KRB4 */
124 #if defined(HAVE_KRB5) || defined(HAVE_KRB4)
126 ReadKerberosData(int fd, int *size, char **data, int *proto) {
133 for (i=0; i<20; i++) {
134 if (read(fd, &p[i], 1) != 1) {
136 syslog(LOG_WARNING,"ReadKerberosData: bad read reply len @%d (got \"%s\"", i, p);
146 syslog(LOG_WARNING, "ReadKerberosData: read reply len exceeds buffer");
150 if (!strncmp(p, "V5-", 3) && (len = atoi(p+3)) > 0)
152 else if ((len = atoi(p)) > 0)
155 if (*proto < 4 | *proto > 5) {
156 syslog(LOG_WARNING, "ReadKerberosData: error parsing authenticator length (\"%s\")", p);
161 syslog(LOG_WARNING, "ReadKerberosData: read reply len = %d", len);
167 syslog(LOG_WARNING, "ReadKerberosData: failure allocating %d bytes: %m", len);
172 for (i=0; i < len; i++) {
173 if (read(fd, dst++, 1) != 1) {
177 syslog(LOG_WARNING,"ReadKerberosData: bad read reply string");
188 GetKrb5Data(int fd, krb5_data *data) {
194 for (i=0; i<20; i++) {
195 if (read(fd, &p[i], 1) != 1) {
197 syslog(LOG_WARNING,"bad read reply len @%d (got \"%s\")", i, p);
205 if (i == 20 || strncmp(p, "V5-", 3) || !atoi(p+3)) {
206 syslog(LOG_WARNING,"bad reply len");
209 data->length = atoi(p+3);
210 data->data = malloc(data->length);
216 for (i=0; i < data->length; i++) {
217 if (read(fd, dst++, 1) != 1) {
219 memset((char *)data, 0, sizeof(krb5_data));
220 syslog(LOG_WARNING,"bad read reply string");
228 SendKrb5Data(int fd, krb5_data *data) {
230 int written, size_to_write;
231 sprintf(p, "V5-%d ", data->length);
232 size_to_write = strlen (p);
233 if (size_to_write != (written = write(fd, p, size_to_write)) ||
234 data->length != (written = write(fd, data->data, data->length))) {
235 return (written < 0) ? errno : ZSRV_PKSHORT;
242 ZCheckRealmAuthentication(ZNotice_t *notice,
243 struct sockaddr_in *from,
248 char rlmprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4+1024];
249 krb5_principal princ;
253 krb5_error_code result;
254 krb5_principal server;
255 krb5_keytab keytabid = 0;
256 krb5_auth_context authctx;
257 krb5_keyblock *keyblock;
258 krb5_enctype enctype;
259 krb5_cksumtype cksumtype;
262 char *cksum0_base, *cksum1_base, *cksum2_base;
263 char *svcinst, *x, *y;
264 char *asn1_data, *key_data;
265 int asn1_len, key_len, cksum0_len, cksum1_len, cksum2_len;
266 #ifdef KRB5_AUTH_CON_GETAUTHENTICATOR_TAKES_DOUBLE_POINTER
267 krb5_authenticator *authenticator;
268 #define KRB5AUTHENT authenticator
270 krb5_authenticator authenticator;
271 #define KRB5AUTHENT &authenticator
278 /* Check for bogus authentication data length. */
279 if (notice->z_authent_len <= 0)
282 len = strlen(notice->z_ascii_authent)+1;
285 /* Read in the authentication data. */
286 if (ZReadZcode(notice->z_ascii_authent,
288 len, &len) == ZERR_BADFIELD) {
292 (void) sprintf(rlmprincipal, "%s/%s@%s", SERVER_SERVICE,
293 SERVER_INSTANCE, realm);
296 packet.data = authbuf;
298 result = krb5_kt_resolve(Z_krb5_ctx,
299 keytab_file, &keytabid);
305 /* HOLDING: authbuf, keytabid */
306 /* Create the auth context */
307 result = krb5_auth_con_init(Z_krb5_ctx, &authctx);
309 krb5_kt_close(Z_krb5_ctx, keytabid);
314 /* HOLDING: authbuf, authctx */
315 result = krb5_build_principal(Z_krb5_ctx, &server, strlen(__Zephyr_realm),
316 __Zephyr_realm, SERVER_SERVICE,
317 SERVER_INSTANCE, NULL);
319 result = krb5_rd_req(Z_krb5_ctx, &authctx, &packet, server,
321 krb5_free_principal(Z_krb5_ctx, server);
323 krb5_kt_close(Z_krb5_ctx, keytabid);
326 if (result == KRB5KRB_AP_ERR_REPEAT)
327 syslog(LOG_DEBUG, "ZCheckRealmAuthentication: k5 auth failed: %s", error_message(result));
329 syslog(LOG_WARNING,"ZCheckRealmAuthentication: k5 auth failed: %s", error_message(result));
331 krb5_auth_con_free(Z_krb5_ctx, authctx);
335 /* HOLDING: authbuf, authctx, tkt */
337 if (tkt == 0 || !Z_tktprincp(tkt)) {
339 krb5_free_ticket(Z_krb5_ctx, tkt);
341 krb5_auth_con_free(Z_krb5_ctx, authctx);
345 princ = Z_tktprinc(tkt);
348 krb5_free_ticket(Z_krb5_ctx, tkt);
350 krb5_auth_con_free(Z_krb5_ctx, authctx);
354 /* HOLDING: authbuf, authctx, tkt */
355 result = krb5_unparse_name(Z_krb5_ctx, princ, &name);
357 syslog(LOG_WARNING, "k5 unparse_name failed: %s",
358 error_message(result));
360 krb5_auth_con_free(Z_krb5_ctx, authctx);
361 krb5_free_ticket(Z_krb5_ctx, tkt);
365 krb5_free_ticket(Z_krb5_ctx, tkt);
367 /* HOLDING: authbuf, authctx, name */
368 if (strcmp(name, rlmprincipal)) {
369 syslog(LOG_WARNING, "k5 name mismatch: '%s' vs '%s'",
371 krb5_auth_con_free(Z_krb5_ctx, authctx);
379 /* HOLDING: authctx */
380 /* Get an authenticator so we can get the keyblock */
381 result = krb5_auth_con_getauthenticator (Z_krb5_ctx, authctx,
384 krb5_auth_con_free(Z_krb5_ctx, authctx);
388 /* HOLDING: authctx, authenticator */
389 result = krb5_auth_con_getkey(Z_krb5_ctx, authctx, &keyblock);
391 krb5_auth_con_free(Z_krb5_ctx, authctx);
392 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
393 return (ZAUTH_FAILED);
396 /* HOLDING: authctx, authenticator, keyblock */
397 /* Figure out what checksum type to use */
398 key_data = Z_keydata(keyblock);
399 key_len = Z_keylen(keyblock);
400 result = Z_ExtractEncCksum(keyblock, &enctype, &cksumtype);
402 krb5_free_keyblock(Z_krb5_ctx, keyblock);
403 krb5_auth_con_free(Z_krb5_ctx, authctx);
404 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
405 return (ZAUTH_FAILED);
407 /* HOLDING: authctx, authenticator, keyblock */
409 /* Assemble the things to be checksummed */
410 /* first part is from start of packet through z_default_format:
412 * - z_num_other_fields
426 cksum0_base = notice->z_packet;
427 x = notice->z_default_format;
428 cksum0_len = x + strlen(x) + 1 - cksum0_base;
429 /* second part is from z_multinotice through other fields:
434 cksum1_base = notice->z_multinotice;
435 if (notice->z_num_other_fields)
436 x = notice->z_other_fields[notice->z_num_other_fields];
438 x = cksum1_base + strlen(cksum1_base) + 1; /* multiuid */
439 cksum1_len = x + strlen(x) + 1 - cksum1_base;
441 /* last part is the message body */
442 cksum2_base = notice->z_message;
443 cksum2_len = notice->z_message_len;
445 if ((!notice->z_ascii_checksum || *notice->z_ascii_checksum != 'Z') &&
447 (enctype == ENCTYPE_DES_CBC_CRC ||
448 enctype == ENCTYPE_DES_CBC_MD4 ||
449 enctype == ENCTYPE_DES_CBC_MD5)) {
450 /* try old-format checksum (covers cksum0 only) */
452 ZChecksum_t our_checksum;
454 our_checksum = compute_rlm_checksum(notice, key_data);
456 krb5_free_keyblock(Z_krb5_ctx, keyblock);
457 krb5_auth_con_free(Z_krb5_ctx, authctx);
458 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
460 if (our_checksum == notice->z_checksum) {
466 /* HOLDING: authctx, authenticator */
468 cksumbuf.length = cksum0_len + cksum1_len + cksum2_len;
469 cksumbuf.data = malloc(cksumbuf.length);
470 if (!cksumbuf.data) {
471 krb5_free_keyblock(Z_krb5_ctx, keyblock);
472 krb5_auth_con_free(Z_krb5_ctx, authctx);
473 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
476 /* HOLDING: authctx, authenticator, cksumbuf.data */
478 memcpy(cksumbuf.data, cksum0_base, cksum0_len);
479 memcpy(cksumbuf.data + cksum0_len, cksum1_base, cksum1_len);
480 memcpy(cksumbuf.data + cksum0_len + cksum1_len,
481 cksum2_base, cksum2_len);
483 /* decode zcoded checksum */
484 /* The encoded form is always longer than the original */
485 asn1_len = strlen(notice->z_ascii_checksum) + 1;
486 asn1_data = malloc(asn1_len);
488 krb5_free_keyblock(Z_krb5_ctx, keyblock);
489 krb5_auth_con_free(Z_krb5_ctx, authctx);
490 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
494 /* HOLDING: authctx, authenticator, cksumbuf.data, asn1_data */
495 result = ZReadZcode(notice->z_ascii_checksum,
496 asn1_data, asn1_len, &asn1_len);
497 if (result != ZERR_NONE) {
498 krb5_free_keyblock(Z_krb5_ctx, keyblock);
499 krb5_auth_con_free(Z_krb5_ctx, authctx);
500 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
505 /* HOLDING: asn1_data, cksumbuf.data */
507 valid = Z_krb5_verify_cksum(keyblock, &cksumbuf, cksumtype, asn1_data, asn1_len);
510 krb5_auth_con_free(Z_krb5_ctx, authctx);
511 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
512 krb5_free_keyblock(Z_krb5_ctx, keyblock);
518 return (ZAUTH_FAILED);
520 return (notice->z_auth) ? ZAUTH_YES : ZAUTH_NO;
525 ZCheckAuthentication(ZNotice_t *notice,
526 struct sockaddr_in *from)
530 krb5_principal princ;
534 krb5_error_code result;
535 krb5_principal server;
536 krb5_keytab keytabid = 0;
537 krb5_auth_context authctx;
538 krb5_keyblock *keyblock;
539 krb5_enctype enctype;
540 krb5_cksumtype cksumtype;
543 char *cksum0_base, *cksum1_base, *cksum2_base;
544 char *svcinst, *x, *y;
545 char *asn1_data, *key_data;
546 int asn1_len, key_len, cksum0_len, cksum1_len, cksum2_len;
547 #ifdef KRB5_AUTH_CON_GETAUTHENTICATOR_TAKES_DOUBLE_POINTER
548 krb5_authenticator *authenticator;
549 #define KRB5AUTHENT authenticator
551 krb5_authenticator authenticator;
552 #define KRB5AUTHENT &authenticator
559 /* Check for bogus authentication data length. */
560 if (notice->z_authent_len <= 1)
564 if (notice->z_ascii_authent[0] != 'Z')
565 return ZCheckAuthentication4(notice, from);
568 len = strlen(notice->z_ascii_authent)+1;
571 /* Read in the authentication data. */
572 if (ZReadZcode(notice->z_ascii_authent,
574 len, &len) == ZERR_BADFIELD) {
579 packet.data = authbuf;
581 result = krb5_kt_resolve(Z_krb5_ctx,
582 keytab_file, &keytabid);
588 /* HOLDING: authbuf, keytabid */
589 /* Create the auth context */
590 result = krb5_auth_con_init(Z_krb5_ctx, &authctx);
592 krb5_kt_close(Z_krb5_ctx, keytabid);
597 /* HOLDING: authbuf, authctx */
598 result = krb5_build_principal(Z_krb5_ctx, &server, strlen(__Zephyr_realm),
599 __Zephyr_realm, SERVER_SERVICE,
600 SERVER_INSTANCE, NULL);
602 result = krb5_rd_req(Z_krb5_ctx, &authctx, &packet, server,
604 krb5_free_principal(Z_krb5_ctx, server);
606 krb5_kt_close(Z_krb5_ctx, keytabid);
609 if (result == KRB5KRB_AP_ERR_REPEAT)
610 syslog(LOG_DEBUG, "ZCheckAuthentication: k5 auth failed: %s", error_message(result));
612 syslog(LOG_WARNING,"ZCheckAuthentication: k5 auth failed: %s", error_message(result));
614 krb5_auth_con_free(Z_krb5_ctx, authctx);
618 /* HOLDING: authbuf, authctx, tkt */
620 if (tkt == 0 || !Z_tktprincp(tkt)) {
622 krb5_free_ticket(Z_krb5_ctx, tkt);
624 krb5_auth_con_free(Z_krb5_ctx, authctx);
627 princ = Z_tktprinc(tkt);
630 krb5_free_ticket(Z_krb5_ctx, tkt);
632 krb5_auth_con_free(Z_krb5_ctx, authctx);
636 /* HOLDING: authbuf, authctx, tkt */
637 result = krb5_unparse_name(Z_krb5_ctx, princ, &name);
639 syslog(LOG_WARNING, "k5 unparse_name failed: %s",
640 error_message(result));
642 krb5_auth_con_free(Z_krb5_ctx, authctx);
643 krb5_free_ticket(Z_krb5_ctx, tkt);
647 krb5_free_ticket(Z_krb5_ctx, tkt);
649 /* HOLDING: authbuf, authctx, name */
650 if (strcmp(name, notice->z_sender)) {
651 syslog(LOG_WARNING, "k5 name mismatch: '%s' vs '%s'",
652 name, notice->z_sender);
653 krb5_auth_con_free(Z_krb5_ctx, authctx);
661 /* HOLDING: authctx */
662 /* Get an authenticator so we can get the keyblock */
663 result = krb5_auth_con_getauthenticator (Z_krb5_ctx, authctx,
666 krb5_auth_con_free(Z_krb5_ctx, authctx);
670 /* HOLDING: authctx, authenticator */
671 result = krb5_auth_con_getkey(Z_krb5_ctx, authctx, &keyblock);
673 krb5_auth_con_free(Z_krb5_ctx, authctx);
674 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
675 return (ZAUTH_FAILED);
678 /* HOLDING: authctx, authenticator, keyblock */
679 /* Figure out what checksum type to use */
680 key_data = Z_keydata(keyblock);
681 key_len = Z_keylen(keyblock);
682 result = Z_ExtractEncCksum(keyblock, &enctype, &cksumtype);
684 krb5_free_keyblock(Z_krb5_ctx, keyblock);
685 krb5_auth_con_free(Z_krb5_ctx, authctx);
686 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
687 return (ZAUTH_FAILED);
689 /* HOLDING: authctx, authenticator, keyblock */
691 ZSetSession(keyblock);
693 /* Assemble the things to be checksummed */
694 /* first part is from start of packet through z_default_format:
696 * - z_num_other_fields
710 cksum0_base = notice->z_packet;
711 x = notice->z_default_format;
712 cksum0_len = x + strlen(x) + 1 - cksum0_base;
713 /* second part is from z_multinotice through other fields:
718 cksum1_base = notice->z_multinotice;
719 if (notice->z_num_other_fields)
720 x = notice->z_other_fields[notice->z_num_other_fields];
722 x = cksum1_base + strlen(cksum1_base) + 1; /* multiuid */
723 cksum1_len = x + strlen(x) + 1 - cksum1_base;
725 /* last part is the message body */
726 cksum2_base = notice->z_message;
727 cksum2_len = notice->z_message_len;
729 if ((!notice->z_ascii_checksum || *notice->z_ascii_checksum != 'Z') &&
731 (enctype == ENCTYPE_DES_CBC_CRC ||
732 enctype == ENCTYPE_DES_CBC_MD4 ||
733 enctype == ENCTYPE_DES_CBC_MD5)) {
734 /* try old-format checksum (covers cksum0 only) */
736 ZChecksum_t our_checksum;
738 our_checksum = compute_checksum(notice, key_data);
740 krb5_free_keyblock(Z_krb5_ctx, keyblock);
741 krb5_auth_con_free(Z_krb5_ctx, authctx);
742 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
744 if (our_checksum == notice->z_checksum)
750 /* HOLDING: authctx, authenticator */
752 cksumbuf.length = cksum0_len + cksum1_len + cksum2_len;
753 cksumbuf.data = malloc(cksumbuf.length);
754 if (!cksumbuf.data) {
755 krb5_free_keyblock(Z_krb5_ctx, keyblock);
756 krb5_auth_con_free(Z_krb5_ctx, authctx);
757 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
760 /* HOLDING: authctx, authenticator, cksumbuf.data */
762 memcpy(cksumbuf.data, cksum0_base, cksum0_len);
763 memcpy(cksumbuf.data + cksum0_len, cksum1_base, cksum1_len);
764 memcpy(cksumbuf.data + cksum0_len + cksum1_len,
765 cksum2_base, cksum2_len);
767 /* decode zcoded checksum */
768 /* The encoded form is always longer than the original */
769 asn1_len = strlen(notice->z_ascii_checksum) + 1;
770 asn1_data = malloc(asn1_len);
772 krb5_free_keyblock(Z_krb5_ctx, keyblock);
773 krb5_auth_con_free(Z_krb5_ctx, authctx);
774 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
778 /* HOLDING: authctx, authenticator, cksumbuf.data, asn1_data */
779 result = ZReadZcode(notice->z_ascii_checksum,
780 asn1_data, asn1_len, &asn1_len);
781 if (result != ZERR_NONE) {
782 krb5_free_keyblock(Z_krb5_ctx, keyblock);
783 krb5_auth_con_free(Z_krb5_ctx, authctx);
784 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
789 /* HOLDING: asn1_data, cksumbuf.data, authctx, authenticator */
791 valid = Z_krb5_verify_cksum(keyblock, &cksumbuf, cksumtype, asn1_data, asn1_len);
794 krb5_auth_con_free(Z_krb5_ctx, authctx);
795 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
796 krb5_free_keyblock(Z_krb5_ctx, keyblock);
802 return (ZAUTH_FAILED);
804 return (notice->z_auth) ? ZAUTH_YES : ZAUTH_NO;
811 ZCheckAuthentication4(ZNotice_t *notice,
812 struct sockaddr_in *from)
816 char srcprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4];
817 KTEXT_ST authent, ticket;
819 ZChecksum_t checksum;
821 char instance[INST_SZ+1];
826 /* Check for bogus authentication data length. */
827 if (notice->z_authent_len <= 0)
830 /* Read in the authentication data. */
831 if (ZReadAscii(notice->z_ascii_authent,
832 strlen(notice->z_ascii_authent)+1,
833 (unsigned char *)authent.dat,
834 notice->z_authent_len) == ZERR_BADFIELD) {
837 authent.length = notice->z_authent_len;
839 strcpy(instance, SERVER_INSTANCE);
841 /* We don't have the session key cached; do it the long way. */
842 result = krb_rd_req(&authent, SERVER_SERVICE, instance,
843 from->sin_addr.s_addr, &dat, srvtab_file);
844 if (result == RD_AP_OK) {
845 ZSetSessionDES(&dat.session);
846 sprintf(srcprincipal, "%s%s%s@%s", dat.pname, dat.pinst[0] ? "." : "",
847 dat.pinst, dat.prealm);
848 if (strcmp(srcprincipal, notice->z_sender))
851 return ZAUTH_FAILED; /* didn't decode correctly */
854 /* Check the cryptographic checksum. */
858 checksum = compute_checksum(notice, dat.session);
860 if (checksum != notice->z_checksum)
865 #else /* !HAVE_KRB4 */
866 return (notice->z_auth) ? ZAUTH_YES : ZAUTH_NO;
873 compute_checksum(ZNotice_t *notice,
879 ZChecksum_t checksum;
880 char *cstart, *cend, *hstart = notice->z_packet, *hend = notice->z_message;
882 cstart = notice->z_default_format + strlen(notice->z_default_format) + 1;
883 cend = cstart + strlen(cstart) + 1;
884 checksum = des_quad_cksum(hstart, NULL, cstart - hstart, 0, session_key);
885 checksum ^= des_quad_cksum(cend, NULL, hend - cend, 0, session_key);
886 checksum ^= des_quad_cksum(notice->z_message, NULL, notice->z_message_len,
892 static ZChecksum_t compute_rlm_checksum(ZNotice_t *notice,
898 ZChecksum_t checksum;
899 char *cstart, *cend, *hstart = notice->z_packet, *hend = notice->z_message;
901 cstart = notice->z_default_format + strlen(notice->z_default_format) + 1;
902 cend = cstart + strlen(cstart) + 1;
903 checksum = des_quad_cksum(hstart, NULL, cstart - hstart, 0, session_key);
910 Z_krb5_init_keyblock(krb5_context context,
915 #ifdef HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE
916 return krb5_init_keyblock(context, type, size, key);
919 krb5_keyblock *tmp, tmp_ss;
923 Z_enctype(tmp) = type;
924 Z_keylen(tmp) = size;
925 Z_keydata(tmp) = malloc(size);
928 ret = krb5_copy_keyblock(context, tmp, key);
929 free(Z_keydata(tmp));
935 void ZLogKey(char *label, krb5_keyblock *keyblock) {
939 buf = malloc(5 *Z_keylen(keyblock)+1);
941 k=Z_keydata(keyblock);
942 for (i=0,p=buf; i < Z_keylen(keyblock); i++,p+=strlen(p))
943 sprintf(p, " 0x%02x", k[i]);
944 syslog(LOG_ERR, "key %s is type %d, %d bytes, %s", label, Z_enctype(keyblock), Z_keylen(keyblock), buf);
950 ZSetSession(krb5_keyblock *keyblock) {
952 krb5_error_code result;
954 if (__Zephyr_keyblock) {
955 krb5_free_keyblock_contents(Z_krb5_ctx, __Zephyr_keyblock);
956 result = krb5_copy_keyblock_contents(Z_krb5_ctx, keyblock, __Zephyr_keyblock);
958 result = krb5_copy_keyblock(Z_krb5_ctx, keyblock, &__Zephyr_keyblock);
961 if (result) /*XXX we're out of memory? */
964 memcpy(__Zephyr_session, Z_keydata(keyblock), sizeof(C_Block));
970 ZSetSessionDES(C_Block *key) {
973 if (__Zephyr_keyblock) {
974 krb5_free_keyblock(Z_krb5_ctx, __Zephyr_keyblock);
975 __Zephyr_keyblock=NULL;
977 result = Z_krb5_init_keyblock(Z_krb5_ctx, ENCTYPE_DES_CBC_CRC,
980 if (result) /*XXX we're out of memory? */
983 memcpy(Z_keydata(__Zephyr_keyblock), key, sizeof(C_Block));
985 memcpy(__Zephyr_session, key, sizeof(C_Block));
990 #endif /* HAVE_KRB4 */