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 */
125 #if defined(HAVE_KRB5) || defined(HAVE_KRB4)
127 ReadKerberosData(int fd, int *size, char **data, int *proto) {
134 for (i=0; i<20; i++) {
135 if (read(fd, &p[i], 1) != 1) {
137 syslog(LOG_WARNING,"ReadKerberosData: bad read reply len @%d (got \"%s\"", i, p);
147 syslog(LOG_WARNING, "ReadKerberosData: read reply len exceeds buffer");
151 if (!strncmp(p, "V5-", 3) && (len = atoi(p+3)) > 0)
153 else if ((len = atoi(p)) > 0)
156 if (*proto < 4 | *proto > 5) {
157 syslog(LOG_WARNING, "ReadKerberosData: error parsing authenticator length (\"%s\")", p);
162 syslog(LOG_WARNING, "ReadKerberosData: read reply len = %d", len);
168 syslog(LOG_WARNING, "ReadKerberosData: failure allocating %d bytes: %m", len);
173 for (i=0; i < len; i++) {
174 if (read(fd, dst++, 1) != 1) {
178 syslog(LOG_WARNING,"ReadKerberosData: bad read reply string");
189 GetKrb5Data(int fd, krb5_data *data) {
195 for (i=0; i<20; i++) {
196 if (read(fd, &p[i], 1) != 1) {
198 syslog(LOG_WARNING,"bad read reply len @%d (got \"%s\")", i, p);
206 if (i == 20 || strncmp(p, "V5-", 3) || !atoi(p+3)) {
207 syslog(LOG_WARNING,"bad reply len");
210 data->length = atoi(p+3);
211 data->data = malloc(data->length);
217 for (i=0; i < data->length; i++) {
218 if (read(fd, dst++, 1) != 1) {
220 memset((char *)data, 0, sizeof(krb5_data));
221 syslog(LOG_WARNING,"bad read reply string");
229 SendKrb5Data(int fd, krb5_data *data) {
231 int written, size_to_write;
232 sprintf(p, "V5-%d ", data->length);
233 size_to_write = strlen (p);
234 if (size_to_write != (written = write(fd, p, size_to_write)) ||
235 data->length != (written = write(fd, data->data, data->length))) {
236 return (written < 0) ? errno : ZSRV_PKSHORT;
243 ZCheckRealmAuthentication(notice, from, realm)
245 struct sockaddr_in *from;
250 char rlmprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4+1024];
251 krb5_principal princ;
255 krb5_error_code result;
256 krb5_principal server;
257 krb5_keytab keytabid = 0;
258 krb5_auth_context authctx;
259 krb5_keyblock *keyblock;
260 krb5_enctype enctype;
261 krb5_cksumtype cksumtype;
264 char *cksum0_base, *cksum1_base, *cksum2_base;
265 char *svcinst, *x, *y;
266 char *asn1_data, *key_data;
267 int asn1_len, key_len, cksum0_len, cksum1_len, cksum2_len;
268 #ifdef KRB5_AUTH_CON_GETAUTHENTICATOR_TAKES_DOUBLE_POINTER
269 krb5_authenticator *authenticator;
270 #define KRB5AUTHENT authenticator
272 krb5_authenticator authenticator;
273 #define KRB5AUTHENT &authenticator
280 /* Check for bogus authentication data length. */
281 if (notice->z_authent_len <= 0)
284 len = strlen(notice->z_ascii_authent)+1;
287 /* Read in the authentication data. */
288 if (ZReadZcode(notice->z_ascii_authent,
290 len, &len) == ZERR_BADFIELD) {
294 (void) sprintf(rlmprincipal, "%s/%s@%s", SERVER_SERVICE,
295 SERVER_INSTANCE, realm);
298 packet.data = authbuf;
300 result = krb5_kt_resolve(Z_krb5_ctx,
301 keytab_file, &keytabid);
307 /* HOLDING: authbuf, keytabid */
308 /* Create the auth context */
309 result = krb5_auth_con_init(Z_krb5_ctx, &authctx);
311 krb5_kt_close(Z_krb5_ctx, keytabid);
316 /* HOLDING: authbuf, authctx */
317 result = krb5_build_principal(Z_krb5_ctx, &server, strlen(__Zephyr_realm),
318 __Zephyr_realm, SERVER_SERVICE,
319 SERVER_INSTANCE, NULL);
321 result = krb5_rd_req(Z_krb5_ctx, &authctx, &packet, server,
323 krb5_free_principal(Z_krb5_ctx, server);
325 krb5_kt_close(Z_krb5_ctx, keytabid);
328 if (result == KRB5KRB_AP_ERR_REPEAT)
329 syslog(LOG_DEBUG, "ZCheckRealmAuthentication: k5 auth failed: %s", error_message(result));
331 syslog(LOG_WARNING,"ZCheckRealmAuthentication: k5 auth failed: %s", error_message(result));
333 krb5_auth_con_free(Z_krb5_ctx, authctx);
337 /* HOLDING: authbuf, authctx, tkt */
339 if (tkt == 0 || !Z_tktprincp(tkt)) {
341 krb5_free_ticket(Z_krb5_ctx, tkt);
343 krb5_auth_con_free(Z_krb5_ctx, authctx);
347 princ = Z_tktprinc(tkt);
350 krb5_free_ticket(Z_krb5_ctx, tkt);
352 krb5_auth_con_free(Z_krb5_ctx, authctx);
356 /* HOLDING: authbuf, authctx, tkt */
357 result = krb5_unparse_name(Z_krb5_ctx, princ, &name);
359 syslog(LOG_WARNING, "k5 unparse_name failed: %s",
360 error_message(result));
362 krb5_auth_con_free(Z_krb5_ctx, authctx);
363 krb5_free_ticket(Z_krb5_ctx, tkt);
367 krb5_free_ticket(Z_krb5_ctx, tkt);
369 /* HOLDING: authbuf, authctx, name */
370 if (strcmp(name, rlmprincipal)) {
371 syslog(LOG_WARNING, "k5 name mismatch: '%s' vs '%s'",
373 krb5_auth_con_free(Z_krb5_ctx, authctx);
381 /* HOLDING: authctx */
382 /* Get an authenticator so we can get the keyblock */
383 result = krb5_auth_con_getauthenticator (Z_krb5_ctx, authctx,
386 krb5_auth_con_free(Z_krb5_ctx, authctx);
390 /* HOLDING: authctx, authenticator */
391 result = krb5_auth_con_getkey(Z_krb5_ctx, authctx, &keyblock);
393 krb5_auth_con_free(Z_krb5_ctx, authctx);
394 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
395 return (ZAUTH_FAILED);
398 /* HOLDING: authctx, authenticator, keyblock */
399 /* Figure out what checksum type to use */
400 key_data = Z_keydata(keyblock);
401 key_len = Z_keylen(keyblock);
402 result = Z_ExtractEncCksum(keyblock, &enctype, &cksumtype);
404 krb5_free_keyblock(Z_krb5_ctx, keyblock);
405 krb5_auth_con_free(Z_krb5_ctx, authctx);
406 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
407 return (ZAUTH_FAILED);
409 /* HOLDING: authctx, authenticator, keyblock */
411 /* Assemble the things to be checksummed */
412 /* first part is from start of packet through z_default_format:
414 * - z_num_other_fields
428 cksum0_base = notice->z_packet;
429 x = notice->z_default_format;
430 cksum0_len = x + strlen(x) + 1 - cksum0_base;
431 /* second part is from z_multinotice through other fields:
436 cksum1_base = notice->z_multinotice;
437 if (notice->z_num_other_fields)
438 x = notice->z_other_fields[notice->z_num_other_fields];
440 x = cksum1_base + strlen(cksum1_base) + 1; /* multiuid */
441 cksum1_len = x + strlen(x) + 1 - cksum1_base;
443 /* last part is the message body */
444 cksum2_base = notice->z_message;
445 cksum2_len = notice->z_message_len;
447 if ((!notice->z_ascii_checksum || *notice->z_ascii_checksum != 'Z') &&
449 (enctype == ENCTYPE_DES_CBC_CRC ||
450 enctype == ENCTYPE_DES_CBC_MD4 ||
451 enctype == ENCTYPE_DES_CBC_MD5)) {
452 /* try old-format checksum (covers cksum0 only) */
454 ZChecksum_t our_checksum;
456 our_checksum = compute_rlm_checksum(notice, key_data);
458 krb5_free_keyblock(Z_krb5_ctx, keyblock);
459 krb5_auth_con_free(Z_krb5_ctx, authctx);
460 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
462 if (our_checksum == notice->z_checksum) {
468 /* HOLDING: authctx, authenticator */
470 cksumbuf.length = cksum0_len + cksum1_len + cksum2_len;
471 cksumbuf.data = malloc(cksumbuf.length);
472 if (!cksumbuf.data) {
473 krb5_free_keyblock(Z_krb5_ctx, keyblock);
474 krb5_auth_con_free(Z_krb5_ctx, authctx);
475 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
478 /* HOLDING: authctx, authenticator, cksumbuf.data */
480 memcpy(cksumbuf.data, cksum0_base, cksum0_len);
481 memcpy(cksumbuf.data + cksum0_len, cksum1_base, cksum1_len);
482 memcpy(cksumbuf.data + cksum0_len + cksum1_len,
483 cksum2_base, cksum2_len);
485 /* decode zcoded checksum */
486 /* The encoded form is always longer than the original */
487 asn1_len = strlen(notice->z_ascii_checksum) + 1;
488 asn1_data = malloc(asn1_len);
490 krb5_free_keyblock(Z_krb5_ctx, keyblock);
491 krb5_auth_con_free(Z_krb5_ctx, authctx);
492 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
496 /* HOLDING: authctx, authenticator, cksumbuf.data, asn1_data */
497 result = ZReadZcode(notice->z_ascii_checksum,
498 asn1_data, asn1_len, &asn1_len);
499 if (result != ZERR_NONE) {
500 krb5_free_keyblock(Z_krb5_ctx, keyblock);
501 krb5_auth_con_free(Z_krb5_ctx, authctx);
502 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
507 /* HOLDING: asn1_data, cksumbuf.data */
509 valid = Z_krb5_verify_cksum(keyblock, &cksumbuf, cksumtype, asn1_data, asn1_len);
512 krb5_auth_con_free(Z_krb5_ctx, authctx);
513 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
514 krb5_free_keyblock(Z_krb5_ctx, keyblock);
520 return (ZAUTH_FAILED);
522 return (notice->z_auth) ? ZAUTH_YES : ZAUTH_NO;
527 ZCheckAuthentication(notice, from)
529 struct sockaddr_in *from;
533 krb5_principal princ;
537 krb5_error_code result;
538 krb5_principal server;
539 krb5_keytab keytabid = 0;
540 krb5_auth_context authctx;
541 krb5_keyblock *keyblock;
542 krb5_enctype enctype;
543 krb5_cksumtype cksumtype;
546 char *cksum0_base, *cksum1_base, *cksum2_base;
547 char *svcinst, *x, *y;
548 char *asn1_data, *key_data;
549 int asn1_len, key_len, cksum0_len, cksum1_len, cksum2_len;
550 #ifdef KRB5_AUTH_CON_GETAUTHENTICATOR_TAKES_DOUBLE_POINTER
551 krb5_authenticator *authenticator;
552 #define KRB5AUTHENT authenticator
554 krb5_authenticator authenticator;
555 #define KRB5AUTHENT &authenticator
562 /* Check for bogus authentication data length. */
563 if (notice->z_authent_len <= 1)
567 if (notice->z_ascii_authent[0] != 'Z')
568 return ZCheckAuthentication4(notice, from);
571 len = strlen(notice->z_ascii_authent)+1;
574 /* Read in the authentication data. */
575 if (ZReadZcode(notice->z_ascii_authent,
577 len, &len) == ZERR_BADFIELD) {
582 packet.data = authbuf;
584 result = krb5_kt_resolve(Z_krb5_ctx,
585 keytab_file, &keytabid);
591 /* HOLDING: authbuf, keytabid */
592 /* Create the auth context */
593 result = krb5_auth_con_init(Z_krb5_ctx, &authctx);
595 krb5_kt_close(Z_krb5_ctx, keytabid);
600 /* HOLDING: authbuf, authctx */
601 result = krb5_build_principal(Z_krb5_ctx, &server, strlen(__Zephyr_realm),
602 __Zephyr_realm, SERVER_SERVICE,
603 SERVER_INSTANCE, NULL);
605 result = krb5_rd_req(Z_krb5_ctx, &authctx, &packet, server,
607 krb5_free_principal(Z_krb5_ctx, server);
609 krb5_kt_close(Z_krb5_ctx, keytabid);
612 if (result == KRB5KRB_AP_ERR_REPEAT)
613 syslog(LOG_DEBUG, "ZCheckAuthentication: k5 auth failed: %s", error_message(result));
615 syslog(LOG_WARNING,"ZCheckAuthentication: k5 auth failed: %s", error_message(result));
617 krb5_auth_con_free(Z_krb5_ctx, authctx);
621 /* HOLDING: authbuf, authctx, tkt */
623 if (tkt == 0 || !Z_tktprincp(tkt)) {
625 krb5_free_ticket(Z_krb5_ctx, tkt);
627 krb5_auth_con_free(Z_krb5_ctx, authctx);
630 princ = Z_tktprinc(tkt);
633 krb5_free_ticket(Z_krb5_ctx, tkt);
635 krb5_auth_con_free(Z_krb5_ctx, authctx);
639 /* HOLDING: authbuf, authctx, tkt */
640 result = krb5_unparse_name(Z_krb5_ctx, princ, &name);
642 syslog(LOG_WARNING, "k5 unparse_name failed: %s",
643 error_message(result));
645 krb5_auth_con_free(Z_krb5_ctx, authctx);
646 krb5_free_ticket(Z_krb5_ctx, tkt);
650 krb5_free_ticket(Z_krb5_ctx, tkt);
652 /* HOLDING: authbuf, authctx, name */
653 if (strcmp(name, notice->z_sender)) {
654 syslog(LOG_WARNING, "k5 name mismatch: '%s' vs '%s'",
655 name, notice->z_sender);
656 krb5_auth_con_free(Z_krb5_ctx, authctx);
664 /* HOLDING: authctx */
665 /* Get an authenticator so we can get the keyblock */
666 result = krb5_auth_con_getauthenticator (Z_krb5_ctx, authctx,
669 krb5_auth_con_free(Z_krb5_ctx, authctx);
673 /* HOLDING: authctx, authenticator */
674 result = krb5_auth_con_getkey(Z_krb5_ctx, authctx, &keyblock);
676 krb5_auth_con_free(Z_krb5_ctx, authctx);
677 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
678 return (ZAUTH_FAILED);
681 /* HOLDING: authctx, authenticator, keyblock */
682 /* Figure out what checksum type to use */
683 key_data = Z_keydata(keyblock);
684 key_len = Z_keylen(keyblock);
685 result = Z_ExtractEncCksum(keyblock, &enctype, &cksumtype);
687 krb5_free_keyblock(Z_krb5_ctx, keyblock);
688 krb5_auth_con_free(Z_krb5_ctx, authctx);
689 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
690 return (ZAUTH_FAILED);
692 /* HOLDING: authctx, authenticator, keyblock */
694 ZSetSession(keyblock);
696 /* Assemble the things to be checksummed */
697 /* first part is from start of packet through z_default_format:
699 * - z_num_other_fields
713 cksum0_base = notice->z_packet;
714 x = notice->z_default_format;
715 cksum0_len = x + strlen(x) + 1 - cksum0_base;
716 /* second part is from z_multinotice through other fields:
721 cksum1_base = notice->z_multinotice;
722 if (notice->z_num_other_fields)
723 x = notice->z_other_fields[notice->z_num_other_fields];
725 x = cksum1_base + strlen(cksum1_base) + 1; /* multiuid */
726 cksum1_len = x + strlen(x) + 1 - cksum1_base;
728 /* last part is the message body */
729 cksum2_base = notice->z_message;
730 cksum2_len = notice->z_message_len;
732 if ((!notice->z_ascii_checksum || *notice->z_ascii_checksum != 'Z') &&
734 (enctype == ENCTYPE_DES_CBC_CRC ||
735 enctype == ENCTYPE_DES_CBC_MD4 ||
736 enctype == ENCTYPE_DES_CBC_MD5)) {
737 /* try old-format checksum (covers cksum0 only) */
739 ZChecksum_t our_checksum;
741 our_checksum = compute_checksum(notice, key_data);
743 krb5_free_keyblock(Z_krb5_ctx, keyblock);
744 krb5_auth_con_free(Z_krb5_ctx, authctx);
745 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
747 if (our_checksum == notice->z_checksum)
753 /* HOLDING: authctx, authenticator */
755 cksumbuf.length = cksum0_len + cksum1_len + cksum2_len;
756 cksumbuf.data = malloc(cksumbuf.length);
757 if (!cksumbuf.data) {
758 krb5_free_keyblock(Z_krb5_ctx, keyblock);
759 krb5_auth_con_free(Z_krb5_ctx, authctx);
760 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
763 /* HOLDING: authctx, authenticator, cksumbuf.data */
765 memcpy(cksumbuf.data, cksum0_base, cksum0_len);
766 memcpy(cksumbuf.data + cksum0_len, cksum1_base, cksum1_len);
767 memcpy(cksumbuf.data + cksum0_len + cksum1_len,
768 cksum2_base, cksum2_len);
770 /* decode zcoded checksum */
771 /* The encoded form is always longer than the original */
772 asn1_len = strlen(notice->z_ascii_checksum) + 1;
773 asn1_data = malloc(asn1_len);
775 krb5_free_keyblock(Z_krb5_ctx, keyblock);
776 krb5_auth_con_free(Z_krb5_ctx, authctx);
777 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
781 /* HOLDING: authctx, authenticator, cksumbuf.data, asn1_data */
782 result = ZReadZcode(notice->z_ascii_checksum,
783 asn1_data, asn1_len, &asn1_len);
784 if (result != ZERR_NONE) {
785 krb5_free_keyblock(Z_krb5_ctx, keyblock);
786 krb5_auth_con_free(Z_krb5_ctx, authctx);
787 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
792 /* HOLDING: asn1_data, cksumbuf.data, authctx, authenticator */
794 valid = Z_krb5_verify_cksum(keyblock, &cksumbuf, cksumtype, asn1_data, asn1_len);
797 krb5_auth_con_free(Z_krb5_ctx, authctx);
798 krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
799 krb5_free_keyblock(Z_krb5_ctx, keyblock);
805 return (ZAUTH_FAILED);
807 return (notice->z_auth) ? ZAUTH_YES : ZAUTH_NO;
814 ZCheckAuthentication4(notice, from)
816 struct sockaddr_in *from;
820 char srcprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4];
821 KTEXT_ST authent, ticket;
823 ZChecksum_t checksum;
825 char instance[INST_SZ+1];
830 /* Check for bogus authentication data length. */
831 if (notice->z_authent_len <= 0)
834 /* Read in the authentication data. */
835 if (ZReadAscii(notice->z_ascii_authent,
836 strlen(notice->z_ascii_authent)+1,
837 (unsigned char *)authent.dat,
838 notice->z_authent_len) == ZERR_BADFIELD) {
841 authent.length = notice->z_authent_len;
843 strcpy(instance, SERVER_INSTANCE);
845 /* We don't have the session key cached; do it the long way. */
846 result = krb_rd_req(&authent, SERVER_SERVICE, instance,
847 from->sin_addr.s_addr, &dat, srvtab_file);
848 if (result == RD_AP_OK) {
849 ZSetSessionDES(&dat.session);
850 sprintf(srcprincipal, "%s%s%s@%s", dat.pname, dat.pinst[0] ? "." : "",
851 dat.pinst, dat.prealm);
852 if (strcmp(srcprincipal, notice->z_sender))
855 return ZAUTH_FAILED; /* didn't decode correctly */
858 /* Check the cryptographic checksum. */
862 checksum = compute_checksum(notice, dat.session);
864 if (checksum != notice->z_checksum)
869 #else /* !HAVE_KRB4 */
870 return (notice->z_auth) ? ZAUTH_YES : ZAUTH_NO;
876 static ZChecksum_t compute_checksum(notice, session_key)
883 ZChecksum_t checksum;
884 char *cstart, *cend, *hstart = notice->z_packet, *hend = notice->z_message;
886 cstart = notice->z_default_format + strlen(notice->z_default_format) + 1;
887 cend = cstart + strlen(cstart) + 1;
888 checksum = des_quad_cksum(hstart, NULL, cstart - hstart, 0, session_key);
889 checksum ^= des_quad_cksum(cend, NULL, hend - cend, 0, session_key);
890 checksum ^= des_quad_cksum(notice->z_message, NULL, notice->z_message_len,
896 static ZChecksum_t compute_rlm_checksum(notice, session_key)
903 ZChecksum_t checksum;
904 char *cstart, *cend, *hstart = notice->z_packet, *hend = notice->z_message;
906 cstart = notice->z_default_format + strlen(notice->z_default_format) + 1;
907 cend = cstart + strlen(cstart) + 1;
908 checksum = des_quad_cksum(hstart, NULL, cstart - hstart, 0, session_key);
915 Z_krb5_init_keyblock(krb5_context context,
920 #ifdef HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE
921 return krb5_init_keyblock(context, type, size, key);
924 krb5_keyblock *tmp, tmp_ss;
928 Z_enctype(tmp) = type;
929 Z_keylen(tmp) = size;
930 Z_keydata(tmp) = malloc(size);
933 ret = krb5_copy_keyblock(context, tmp, key);
934 free(Z_keydata(tmp));
940 void ZLogKey(char *label, krb5_keyblock *keyblock) {
944 buf = malloc(5 *Z_keylen(keyblock)+1);
946 k=Z_keydata(keyblock);
947 for (i=0,p=buf; i < Z_keylen(keyblock); i++,p+=strlen(p))
948 sprintf(p, " 0x%02x", k[i]);
949 syslog(LOG_ERR, "key %s is type %d, %d bytes, %s", label, Z_enctype(keyblock), Z_keylen(keyblock), buf);
955 ZSetSession(krb5_keyblock *keyblock) {
957 krb5_error_code result;
959 if (__Zephyr_keyblock) {
960 krb5_free_keyblock_contents(Z_krb5_ctx, __Zephyr_keyblock);
961 result = krb5_copy_keyblock_contents(Z_krb5_ctx, keyblock, __Zephyr_keyblock);
963 result = krb5_copy_keyblock(Z_krb5_ctx, keyblock, &__Zephyr_keyblock);
966 if (result) /*XXX we're out of memory? */
969 memcpy(__Zephyr_session, Z_keydata(keyblock), sizeof(C_Block));
975 ZSetSessionDES(C_Block *key) {
978 if (__Zephyr_keyblock) {
979 krb5_free_keyblock(Z_krb5_ctx, __Zephyr_keyblock);
980 __Zephyr_keyblock=NULL;
982 result = Z_krb5_init_keyblock(Z_krb5_ctx, ENCTYPE_DES_CBC_CRC,
985 if (result) /*XXX we're out of memory? */
988 memcpy(Z_keydata(__Zephyr_keyblock), key, sizeof(C_Block));
990 memcpy(__Zephyr_session, key, sizeof(C_Block));
995 #endif /* HAVE_KRB4 */