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(ZNotice_t *, C_Block);
26 static ZChecksum_t compute_rlm_checksum(ZNotice_t *, C_Block);
27 static Code_t ZCheckAuthentication4(ZNotice_t *notice, struct sockaddr_in *from);
32 * get ticket from file descriptor and decode it.
33 * Return KFAILURE if we barf on reading the ticket, else return
34 * the value of rd_ap_req() applied to the ticket.
37 GetKerberosData(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(int fd, /* file descriptor to write onto */
98 KTEXT ticket, /* where to put ticket (return) */
99 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 */
125 #if defined(HAVE_KRB5) || defined(HAVE_KRB4)
127 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) {
193 for (i=0; i<20; i++) {
194 if (read(fd, &p[i], 1) != 1) {
196 syslog(LOG_WARNING,"bad read reply len @%d (got \"%s\")", i, p);
204 if (i == 20 || strncmp(p, "V5-", 3) || !atoi(p+3)) {
205 syslog(LOG_WARNING,"bad reply len");
208 data->length = atoi(p+3);
209 data->data = malloc(data->length);
215 for (i=0; i < data->length; i++) {
216 if (read(fd, dst++, 1) != 1) {
218 memset((char *)data, 0, sizeof(krb5_data));
219 syslog(LOG_WARNING,"bad read reply string");
227 SendKrb5Data(int fd, krb5_data *data) {
229 int written, size_to_write;
230 sprintf(p, "V5-%d ", data->length);
231 size_to_write = strlen (p);
232 if (size_to_write != (written = write(fd, p, size_to_write)) ||
233 data->length != (written = write(fd, data->data, data->length))) {
234 return (written < 0) ? errno : ZSRV_PKSHORT;
241 ZCheckRealmAuthentication(ZNotice_t *notice,
242 struct sockaddr_in *from,
247 char rlmprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4+1024];
248 krb5_principal princ;
252 krb5_error_code result;
253 krb5_principal server;
254 krb5_keytab keytabid = 0;
255 krb5_auth_context authctx;
256 krb5_keyblock *keyblock;
257 krb5_enctype enctype;
258 krb5_cksumtype cksumtype;
261 char *cksum0_base, *cksum1_base, *cksum2_base;
263 unsigned char *asn1_data;
264 unsigned char *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;
283 authbuf = malloc(len);
285 /* Read in the authentication data. */
286 if (ZReadZcode((unsigned char *)notice->z_ascii_authent,
287 (unsigned char *)authbuf,
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((unsigned char *)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)
529 unsigned char *authbuf;
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;
545 unsigned 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;
569 authbuf = malloc(len);
571 /* Read in the authentication data. */
572 if (ZReadZcode((unsigned char *)notice->z_ascii_authent,
574 len, &len) == ZERR_BADFIELD) {
579 packet.data = (char *)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((unsigned char *)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];
819 ZChecksum_t checksum;
820 char instance[INST_SZ+1];
825 /* Check for bogus authentication data length. */
826 if (notice->z_authent_len <= 0)
829 /* Read in the authentication data. */
830 if (ZReadAscii(notice->z_ascii_authent,
831 strlen(notice->z_ascii_authent)+1,
832 (unsigned char *)authent.dat,
833 notice->z_authent_len) == ZERR_BADFIELD) {
836 authent.length = notice->z_authent_len;
838 strcpy(instance, SERVER_INSTANCE);
840 /* We don't have the session key cached; do it the long way. */
841 result = krb_rd_req(&authent, SERVER_SERVICE, instance,
842 from->sin_addr.s_addr, &dat, srvtab_file);
843 if (result == RD_AP_OK) {
844 ZSetSessionDES(&dat.session);
845 sprintf(srcprincipal, "%s%s%s@%s", dat.pname, dat.pinst[0] ? "." : "",
846 dat.pinst, dat.prealm);
847 if (strcmp(srcprincipal, notice->z_sender))
850 return ZAUTH_FAILED; /* didn't decode correctly */
853 /* Check the cryptographic checksum. */
857 checksum = compute_checksum(notice, dat.session);
859 if (checksum != notice->z_checksum)
864 #else /* !HAVE_KRB4 */
865 return (notice->z_auth) ? ZAUTH_YES : ZAUTH_NO;
872 compute_checksum(ZNotice_t *notice,
878 ZChecksum_t checksum;
879 char *cstart, *cend, *hstart = notice->z_packet, *hend = notice->z_message;
881 cstart = notice->z_default_format + strlen(notice->z_default_format) + 1;
882 cend = cstart + strlen(cstart) + 1;
883 checksum = des_quad_cksum((unsigned char *)hstart, NULL, cstart - hstart, 0, session_key);
884 checksum ^= des_quad_cksum((unsigned char *)cend, NULL, hend - cend, 0, session_key);
885 checksum ^= des_quad_cksum((unsigned char *)notice->z_message, NULL, notice->z_message_len,
891 static ZChecksum_t compute_rlm_checksum(ZNotice_t *notice,
897 ZChecksum_t checksum;
898 char *cstart, *cend, *hstart = notice->z_packet;
900 cstart = notice->z_default_format + strlen(notice->z_default_format) + 1;
901 cend = cstart + strlen(cstart) + 1;
902 checksum = des_quad_cksum((unsigned char *)hstart, NULL, cstart - hstart, 0, session_key);
909 Z_krb5_init_keyblock(krb5_context context,
914 #ifdef HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE
915 return krb5_init_keyblock(context, type, size, key);
918 krb5_keyblock *tmp, tmp_ss;
922 Z_enctype(tmp) = type;
923 Z_keylen(tmp) = size;
924 Z_keydata(tmp) = malloc(size);
927 ret = krb5_copy_keyblock(context, tmp, key);
928 free(Z_keydata(tmp));
934 void ZLogKey(char *label, krb5_keyblock *keyblock) {
938 buf = malloc(5 *Z_keylen(keyblock)+1);
940 k=Z_keydata(keyblock);
941 for (i=0,p=buf; i < Z_keylen(keyblock); i++,p+=strlen(p))
942 sprintf(p, " 0x%02x", k[i]);
943 syslog(LOG_ERR, "key %s is type %d, %d bytes, %s", label, Z_enctype(keyblock), Z_keylen(keyblock), buf);
949 ZSetSession(krb5_keyblock *keyblock) {
951 krb5_error_code result;
953 if (__Zephyr_keyblock) {
954 krb5_free_keyblock_contents(Z_krb5_ctx, __Zephyr_keyblock);
955 result = krb5_copy_keyblock_contents(Z_krb5_ctx, keyblock, __Zephyr_keyblock);
957 result = krb5_copy_keyblock(Z_krb5_ctx, keyblock, &__Zephyr_keyblock);
960 if (result) /*XXX we're out of memory? */
963 memcpy(__Zephyr_session, Z_keydata(keyblock), sizeof(C_Block));
969 ZSetSessionDES(C_Block *key) {
972 if (__Zephyr_keyblock) {
973 krb5_free_keyblock(Z_krb5_ctx, __Zephyr_keyblock);
974 __Zephyr_keyblock=NULL;
976 result = Z_krb5_init_keyblock(Z_krb5_ctx, ENCTYPE_DES_CBC_CRC,
979 if (result) /*XXX we're out of memory? */
982 memcpy(Z_keydata(__Zephyr_keyblock), key, sizeof(C_Block));
984 memcpy(__Zephyr_session, key, sizeof(C_Block));
989 #endif /* HAVE_KRB4 */