From a5cd467f1bf72245e01d33972a6d8c007894fdc1 Mon Sep 17 00:00:00 2001 From: Karl Ramm Date: Sun, 26 Jul 2009 21:25:27 +0000 Subject: Remove the chock wedging things into DES mode and hopefully redo the keyusage stuff such that it actually works. --- h/internal.h | 20 +-- lib/ZCkZAut.c | 34 ++--- lib/ZFmtAuth.c | 59 ++++---- lib/ZMkAuth.c | 17 +-- lib/Zinternal.c | 138 +++++++++--------- server/kstuff.c | 424 ++++++++++++++++++++++++++++--------------------------- server/zserver.h | 18 +-- 7 files changed, 357 insertions(+), 353 deletions(-) diff --git a/h/internal.h b/h/internal.h index 7cc1844..84da0e0 100644 --- a/h/internal.h +++ b/h/internal.h @@ -126,9 +126,9 @@ Code_t Z_WaitForNotice (ZNotice_t *notice, Code_t Z_NewFormatHeader (ZNotice_t *, char *, int, int *, Z_AuthProc); Code_t Z_NewFormatAuthHeader (ZNotice_t *, char *, int, int *, Z_AuthProc); -Code_t Z_NewFormatRawHeader (ZNotice_t *, char *, int, int *, char **, +Code_t Z_NewFormatRawHeader (ZNotice_t *, char *, int, int *, char **, int *, char **, char **); -Code_t Z_AsciiFormatRawHeader (ZNotice_t *, char *, int, int *, char **, +Code_t Z_AsciiFormatRawHeader (ZNotice_t *, char *, int, int *, char **, int *, char **, char **); void Z_gettimeofday(struct _ZTimeval *ztv, struct timezone *tz); @@ -137,20 +137,21 @@ void Z_gettimeofday(struct _ZTimeval *ztv, struct timezone *tz); int ZGetCreds(krb5_creds **creds_out); int ZGetCredsRealm(krb5_creds **creds_out, char *realm); Code_t Z_Checksum(krb5_data *cksumbuf, krb5_keyblock *keyblock, - krb5_cksumtype cksumtype, char **asn1_data, - unsigned int *asn1_len); + krb5_cksumtype cksumtype, krb5_keyusage cksumusage, + char **asn1_data, unsigned int *asn1_len); Code_t Z_ExtractEncCksum(krb5_keyblock *keyblock, krb5_enctype *enctype, krb5_cksumtype *cksumtype); int Z_krb5_verify_cksum(krb5_keyblock *keyblock, krb5_data *cksumbuf, - krb5_cksumtype cksumtype, unsigned char *asn1_data, - int asn1_len); -Code_t Z_InsertZcodeChecksum(krb5_keyblock *keyblock, ZNotice_t *notice, + krb5_cksumtype cksumtype, krb5_keyusage cksumusage, + unsigned char *asn1_data, int asn1_len); +Code_t Z_InsertZcodeChecksum(krb5_keyblock *keyblock, ZNotice_t *notice, char *buffer, - char *cksum_start, int cksum_len, + char *cksum_start, int cksum_len, char *cstart, char *cend, int buffer_len, - int *length_ajdust); + int *length_ajdust, int from_server); unsigned long z_quad_cksum(const unsigned char *, uint32_t *, long, int, unsigned char *); +Code_t ZFormatAuthenticNoticeV5(ZNotice_t*, char*, int, int*, krb5_keyblock *); #endif #ifdef HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE @@ -174,4 +175,3 @@ unsigned long z_quad_cksum(const unsigned char *, uint32_t *, long, #endif #endif /* __INTERNAL_H__ */ - diff --git a/lib/ZCkZAut.c b/lib/ZCkZAut.c index dac17e9..bc2e88f 100644 --- a/lib/ZCkZAut.c +++ b/lib/ZCkZAut.c @@ -8,7 +8,7 @@ * * Copyright (c) 1987,1991 by the Massachusetts Institute of Technology. * For copying and distribution information, see the file - * "mit-copyright.h". + * "mit-copyright.h". */ /* $Header$ */ @@ -33,7 +33,7 @@ static const char rcsid_ZCheckAuthentication_c[] = */ Code_t ZCheckZcodeAuthentication(ZNotice_t *notice, struct sockaddr_in *from) -{ +{ #ifdef HAVE_KRB5 krb5_error_code result; krb5_creds *creds; @@ -47,7 +47,7 @@ Code_t ZCheckZcodeAuthentication(ZNotice_t *notice, unsigned char *asn1_data, *key_data; int asn1_len, key_len, cksum0_len = 0, cksum1_len = 0, cksum2_len = 0; #endif - + /* If the value is already known, return it. */ if (notice->z_checked_auth != ZAUTH_UNSET) return (notice->z_checked_auth); @@ -61,11 +61,11 @@ Code_t ZCheckZcodeAuthentication(ZNotice_t *notice, #ifdef HAVE_KRB5 result = ZGetCreds(&creds); - + if (result) return (ZAUTH_NO); /* HOLDING: creds */ - + /* Figure out what checksum type to use */ keyblock = Z_credskey(creds); key_data = Z_keydata(keyblock); @@ -76,7 +76,7 @@ Code_t ZCheckZcodeAuthentication(ZNotice_t *notice, return (ZAUTH_FAILED); } /* HOLDING: creds */ - + /* Assemble the things to be checksummed */ /* first part is from start of packet through z_default_format: * - z_version @@ -120,11 +120,11 @@ Code_t ZCheckZcodeAuthentication(ZNotice_t *notice, } cksum1_len = x + strlen(x) + 1 - cksum1_base; /* charset / extra field */ } - + /* last part is the message body */ cksum2_base = notice->z_message; cksum2_len = notice->z_message_len; - + /* The following code checks for old-style checksums, which will go away once Kerberos 4 does. */ if ((!notice->z_ascii_checksum || *notice->z_ascii_checksum != 'Z') && @@ -133,9 +133,9 @@ Code_t ZCheckZcodeAuthentication(ZNotice_t *notice, enctype == ENCTYPE_DES_CBC_MD4 || enctype == ENCTYPE_DES_CBC_MD5)) { /* try old-format checksum (covers cksum0 only) */ - + ZChecksum_t our_checksum; - + our_checksum = z_quad_cksum((unsigned char *)cksum0_base, NULL, cksum0_len, 0, key_data); if (our_checksum == notice->z_checksum) { @@ -144,7 +144,7 @@ Code_t ZCheckZcodeAuthentication(ZNotice_t *notice, } } /* HOLDING: creds */ - + cksumbuf.length = cksum0_len + cksum1_len + cksum2_len; cksumbuf.data = malloc(cksumbuf.length); if (!cksumbuf.data) { @@ -152,13 +152,13 @@ Code_t ZCheckZcodeAuthentication(ZNotice_t *notice, return ZAUTH_NO; } /* HOLDING: creds, cksumbuf.data */ - + memcpy(cksumbuf.data, cksum0_base, cksum0_len); if (cksum1_len) memcpy(cksumbuf.data + cksum0_len, cksum1_base, cksum1_len); memcpy(cksumbuf.data + cksum0_len + cksum1_len, cksum2_base, cksum2_len); - + /* decode zcoded checksum */ /* The encoded form is always longer than the original */ asn1_len = strlen(notice->z_ascii_checksum) + 1; @@ -178,14 +178,14 @@ Code_t ZCheckZcodeAuthentication(ZNotice_t *notice, return ZAUTH_FAILED; } /* HOLDING: creds, asn1_data, cksumbuf.data */ - + valid = Z_krb5_verify_cksum(keyblock, &cksumbuf, cksumtype, - asn1_data, asn1_len); - + Z_KEYUSAGE_SRV_CKSUM, asn1_data, asn1_len); + free(asn1_data); krb5_free_creds(Z_krb5_ctx, creds); free(cksumbuf.data); - + if (valid) return ZAUTH_YES; else diff --git a/lib/ZFmtAuth.c b/lib/ZFmtAuth.c index 92fb3c6..50e4073 100644 --- a/lib/ZFmtAuth.c +++ b/lib/ZFmtAuth.c @@ -7,7 +7,7 @@ * * Copyright (c) 1987,1988 by the Massachusetts Institute of Technology. * For copying and distribution information, see the file - * "mit-copyright.h". + * "mit-copyright.h". */ #ifndef lint @@ -76,14 +76,14 @@ ZFormatAuthenticNoticeV5(ZNotice_t *notice, int key_len; char *cksum_start, *cstart, *cend; int cksum_len; - + key_len = Z_keylen(keyblock); retval = Z_ExtractEncCksum(keyblock, &enctype, &cksumtype); if (retval) - return (ZAUTH_FAILED); + return (ZAUTH_FAILED); #ifdef HAVE_KRB4 - if (key_len == 8 && (enctype == ENCTYPE_DES_CBC_CRC || + if (key_len == 8 && (enctype == ENCTYPE_DES_CBC_CRC || enctype == ENCTYPE_DES_CBC_MD4 || enctype == ENCTYPE_DES_CBC_MD5)) { C_Block tmp; @@ -92,38 +92,39 @@ ZFormatAuthenticNoticeV5(ZNotice_t *notice, tmp); } #endif - + newnotice = *notice; newnotice.z_auth = 1; newnotice.z_authent_len = 0; newnotice.z_ascii_authent = ""; if ((retval = Z_NewFormatRawHeader(&newnotice, buffer, buffer_len, - &hdrlen, - &cksum_start, &cksum_len, &cstart, + &hdrlen, + &cksum_start, &cksum_len, &cstart, &cend)) != ZERR_NONE) return (retval); - - retval = Z_InsertZcodeChecksum(keyblock, &newnotice, buffer, - cksum_start, cksum_len, cstart, cend, - buffer_len, &hdr_adj); - if (retval) - return retval; - - hdrlen += hdr_adj; - - ptr = buffer+hdrlen; - - if (newnotice.z_message_len+hdrlen > buffer_len) - return (ZERR_PKTLEN); - - (void) memcpy(ptr, newnotice.z_message, newnotice.z_message_len); - - *len = hdrlen+newnotice.z_message_len; - - if (*len > Z_MAXPKTLEN) - return (ZERR_PKTLEN); - - return (ZERR_NONE); + + /* we know this is only called by the server */ + retval = Z_InsertZcodeChecksum(keyblock, &newnotice, buffer, + cksum_start, cksum_len, cstart, cend, + buffer_len, &hdr_adj, 1); + if (retval) + return retval; + + hdrlen += hdr_adj; + + ptr = buffer+hdrlen; + + if (newnotice.z_message_len+hdrlen > buffer_len) + return (ZERR_PKTLEN); + + (void) memcpy(ptr, newnotice.z_message, newnotice.z_message_len); + + *len = hdrlen+newnotice.z_message_len; + + if (*len > Z_MAXPKTLEN) + return (ZERR_PKTLEN); + + return (ZERR_NONE); } #endif diff --git a/lib/ZMkAuth.c b/lib/ZMkAuth.c index b9a6990..6e8984d 100644 --- a/lib/ZMkAuth.c +++ b/lib/ZMkAuth.c @@ -98,6 +98,7 @@ ZMakeAuthentication(register ZNotice_t *notice, #endif } +/* only used by server? */ Code_t ZMakeZcodeAuthentication(register ZNotice_t *notice, char *buffer, @@ -110,10 +111,10 @@ ZMakeZcodeAuthentication(register ZNotice_t *notice, Code_t ZMakeZcodeRealmAuthentication(register ZNotice_t *notice, - char *buffer, - int buffer_len, - int *phdr_len, - char *realm) + char *buffer, + int buffer_len, + int *phdr_len, + char *realm) { #ifdef HAVE_KRB5 krb5_error_code result; @@ -184,7 +185,7 @@ ZMakeZcodeRealmAuthentication(register ZNotice_t *notice, } result = Z_InsertZcodeChecksum(keyblock, notice, buffer, cksum_start, cksum_len, cstart, cend, buffer_len, - &phdr_adj); + &phdr_adj, 0); krb5_free_creds(Z_krb5_ctx, creds); if (result) { return result; @@ -234,12 +235,6 @@ ZGetCredsRealm(krb5_creds **creds_out, return result; } -#ifdef HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE - creds_in.keyblock.enctype = ENCTYPE_DES_CBC_CRC; /* XXX? */ -#else - creds_in.session.keytype = KEYTYPE_DES; /* XXX? */ -#endif - result = krb5_get_credentials(Z_krb5_ctx, 0, ccache, &creds_in, creds_out); krb5_cc_close(Z_krb5_ctx, ccache); krb5_free_cred_contents(Z_krb5_ctx, &creds_in); /* I also hope this is ok */ diff --git a/lib/Zinternal.c b/lib/Zinternal.c index cd29e59..d121026 100644 --- a/lib/Zinternal.c +++ b/lib/Zinternal.c @@ -8,7 +8,7 @@ * Copyright (c) 1987,1988,1991 by the Massachusetts Institute of * Technology. * For copying and distribution information, see the file - * "mit-copyright.h". + * "mit-copyright.h". */ #include @@ -56,10 +56,10 @@ static struct cksum_map_s { { ENCTYPE_DES_CBC_MD4, CKSUMTYPE_RSA_MD4_DES }, { ENCTYPE_DES_CBC_MD5, CKSUMTYPE_RSA_MD5_DES }, - /* + /* * The implementors hate us, and are inconsistent with names for * most things defined after RFC1510. Note that des3-cbc-sha1 - * and des3-cbc-sha1-kd are listed by number to avoid confusion + * and des3-cbc-sha1-kd are listed by number to avoid confusion * caused by inconsistency between the names used in the specs * and those used by implementations. * -- jhutz, 30-Nov-2002 @@ -109,7 +109,7 @@ void *__Z_debug_print_closure; static int Z_AddField(char **ptr, char *field, char *end); static int find_or_insert_uid(ZUnique_Id_t *uid, ZNotice_Kind_t kind); -static Code_t Z_ZcodeFormatRawHeader(ZNotice_t *, char *, int, int *, char **, +static Code_t Z_ZcodeFormatRawHeader(ZNotice_t *, char *, int, int *, char **, int *, char **, char **, int cksumtype); /* Find or insert uid in the old uids buffer. The buffer is a sorted @@ -197,7 +197,7 @@ Z_PacketWaiting(void) FD_ZERO(&read); FD_SET(ZGetFD(), &read); return (select(ZGetFD() + 1, &read, NULL, NULL, &tv)); -} +} /* Wait for a complete notice to become available */ @@ -227,7 +227,7 @@ Z_ReadEnqueue(void) if (ZGetFD() < 0) return (ZERR_NOPORT); - + while (Z_PacketWaiting()) if ((retval = Z_ReadWait()) != ZERR_NONE) return (retval); @@ -289,7 +289,7 @@ Z_ReadWait(void) if (ZGetFD() < 0) return (ZERR_NOPORT); - + FD_ZERO(&fds); FD_SET(ZGetFD(), &fds); tv.tv_sec = 60; @@ -302,7 +302,7 @@ Z_ReadWait(void) from_len = sizeof(struct sockaddr_in); - packet_len = recvfrom(ZGetFD(), packet, sizeof(packet), 0, + packet_len = recvfrom(ZGetFD(), packet, sizeof(packet), 0, (struct sockaddr *)&from, &from_len); if (packet_len < 0) @@ -316,7 +316,7 @@ Z_ReadWait(void) if (packet_len < zvlen || memcmp(packet, ZVERSIONHDR, zvlen) != 0) { Z_discarded_packets++; return (ZERR_NONE); - } + } /* Parse the notice */ if ((retval = ZParseNotice(packet, packet_len, ¬ice)) != ZERR_NONE) @@ -444,13 +444,13 @@ Z_ReadWait(void) if (!__Q_Head) __Q_Head = qptr; - + /* Copy the from field, multiuid, kind, and checked authentication. */ qptr->from = from; qptr->uid = notice.z_multiuid; qptr->kind = notice.z_kind; qptr->auth = notice.z_checked_auth; - + /* * If this is the first part of the notice, we take the header * from it. We only take it if this is the first fragment so that @@ -542,7 +542,7 @@ Z_AddNoticeToEntry(struct _Z_InputQ *qptr, (void) gettimeofday(&tv, (struct timezone *)0); qptr->timep = tv.tv_sec; - + last = part+notice->z_message_len-1; hole = qptr->holelist; @@ -634,7 +634,7 @@ Z_AddNoticeToEntry(struct _Z_InputQ *qptr, (void) memcpy(qptr->packet+qptr->header_len, qptr->msg, qptr->msg_len); } - + return (ZERR_NONE); } @@ -676,11 +676,11 @@ Z_FormatHeader(ZNotice_t *notice, } notice->z_multinotice = ""; - + (void) Z_gettimeofday(¬ice->z_uid.tv, (struct timezone *)0); notice->z_uid.tv.tv_sec = htonl((u_long) notice->z_uid.tv.tv_sec); notice->z_uid.tv.tv_usec = htonl((u_long) notice->z_uid.tv.tv_usec); - + (void) memcpy(¬ice->z_uid.zuid_addr, &__My_addr, sizeof(__My_addr)); if (notice->z_sender_sockaddr.ip4.sin_family == 0) { @@ -689,7 +689,7 @@ Z_FormatHeader(ZNotice_t *notice, notice->z_sender_sockaddr.ip4.sin_port = notice->z_port; (void) memcpy(¬ice->z_sender_sockaddr.ip4.sin_addr, &__My_addr, sizeof(__My_addr)); } - + notice->z_multiuid = notice->z_uid; if (!version[0]) @@ -729,11 +729,11 @@ Z_NewFormatHeader(ZNotice_t *notice, } notice->z_multinotice = ""; - + (void) gettimeofday(&tv, (struct timezone *)0); notice->z_uid.tv.tv_sec = htonl((u_long) tv.tv_sec); notice->z_uid.tv.tv_usec = htonl((u_long) tv.tv_usec); - + (void) memcpy(¬ice->z_uid.zuid_addr, &__My_addr, sizeof(__My_addr)); (void) memset(¬ice->z_sender_sockaddr, 0, sizeof(notice->z_sender_sockaddr)); @@ -766,7 +766,7 @@ Z_FormatAuthHeader(ZNotice_t *notice, return (Z_FormatRawHeader(notice, buffer, buffer_len, len, NULL, NULL)); } - + return ((*cert_routine)(notice, buffer, buffer_len, len)); } @@ -785,10 +785,10 @@ Z_NewFormatAuthHeader(ZNotice_t *notice, return (Z_FormatRawHeader(notice, buffer, buffer_len, len, NULL, NULL)); } - + return ((*cert_routine)(notice, buffer, buffer_len, len)); -} - +} + Code_t Z_NewFormatRawHeader(ZNotice_t *notice, char *buffer, @@ -878,7 +878,7 @@ Z_ZcodeFormatRawHeader(ZNotice_t *notice, return (ZERR_HEADERLEN); ptr += strlen(ptr)+1; - if (ZMakeAscii(ptr, end-ptr, (unsigned char *)¬ice->z_uid, + if (ZMakeAscii(ptr, end-ptr, (unsigned char *)¬ice->z_uid, sizeof(ZUnique_Id_t)) == ZERR_FIELDLEN) return (ZERR_HEADERLEN); ptr += strlen(ptr)+1; @@ -916,7 +916,7 @@ Z_ZcodeFormatRawHeader(ZNotice_t *notice, (void) sprintf(newrecip, "%s@%s", notice->z_recipient, __Zephyr_realm); if (Z_AddField(&ptr, newrecip, end)) return (ZERR_HEADERLEN); - } + } if (Z_AddField(&ptr, notice->z_default_format, end)) return (ZERR_HEADERLEN); @@ -942,7 +942,7 @@ Z_ZcodeFormatRawHeader(ZNotice_t *notice, if (Z_AddField(&ptr, notice->z_multinotice, end)) return (ZERR_HEADERLEN); - if (ZMakeAscii(ptr, end-ptr, (unsigned char *)¬ice->z_multiuid, + if (ZMakeAscii(ptr, end-ptr, (unsigned char *)¬ice->z_multiuid, sizeof(ZUnique_Id_t)) == ZERR_FIELDLEN) return (ZERR_HEADERLEN); ptr += strlen(ptr)+1; @@ -966,11 +966,11 @@ Z_ZcodeFormatRawHeader(ZNotice_t *notice, return ZERR_HEADERLEN; ptr += strlen(ptr) + 1; } - + for (i=0;iz_num_other_fields;i++) if (Z_AddField(&ptr, notice->z_other_fields[i], end)) return (ZERR_HEADERLEN); - + if (cksum_len) *cksum_len = ptr-*cksum_start; @@ -1030,7 +1030,7 @@ Z_FormatRawHeader(ZNotice_t *notice, return (ZERR_HEADERLEN); ptr += strlen(ptr)+1; - if (ZMakeAscii(ptr, end-ptr, (unsigned char *)¬ice->z_uid, + if (ZMakeAscii(ptr, end-ptr, (unsigned char *)¬ice->z_uid, sizeof(ZUnique_Id_t)) == ZERR_FIELDLEN) return (ZERR_HEADERLEN); ptr += strlen(ptr)+1; @@ -1068,7 +1068,7 @@ Z_FormatRawHeader(ZNotice_t *notice, (void) sprintf(newrecip, "%s@%s", notice->z_recipient, __Zephyr_realm); if (Z_AddField(&ptr, newrecip, end)) return (ZERR_HEADERLEN); - } + } if (Z_AddField(&ptr, notice->z_default_format, end)) return (ZERR_HEADERLEN); @@ -1084,7 +1084,7 @@ Z_FormatRawHeader(ZNotice_t *notice, if (Z_AddField(&ptr, notice->z_multinotice, end)) return (ZERR_HEADERLEN); - if (ZMakeAscii(ptr, end-ptr, (unsigned char *)¬ice->z_multiuid, + if (ZMakeAscii(ptr, end-ptr, (unsigned char *)¬ice->z_multiuid, sizeof(ZUnique_Id_t)) == ZERR_FIELDLEN) return (ZERR_HEADERLEN); ptr += strlen(ptr)+1; @@ -1105,13 +1105,13 @@ Z_FormatRawHeader(ZNotice_t *notice, if (ZMakeAscii16(ptr, end-ptr, ntohs(notice->z_charset)) == ZERR_FIELDLEN) return ZERR_HEADERLEN; ptr += strlen(ptr) + 1; - + for (i=0;iz_num_other_fields;i++) if (Z_AddField(&ptr, notice->z_other_fields[i], end)) return (ZERR_HEADERLEN); - + *len = ptr-buffer; - + return (ZERR_NONE); } @@ -1168,39 +1168,39 @@ void Z_RemQueue(struct _Z_InputQ *qptr) { struct _Z_Hole *hole, *nexthole; - + if (qptr->complete) __Q_CompleteLength--; __Q_Size -= qptr->msg_len; - + if (qptr->header) free(qptr->header); if (qptr->msg) free(qptr->msg); if (qptr->packet) free(qptr->packet); - + hole = qptr->holelist; while (hole) { nexthole = hole->next; free((char *)hole); hole = nexthole; } - + if (qptr == __Q_Head && __Q_Head == __Q_Tail) { free ((char *)qptr); __Q_Head = (struct _Z_InputQ *)0; __Q_Tail = (struct _Z_InputQ *)0; return; } - + if (qptr == __Q_Head) { __Q_Head = qptr->next; __Q_Head->prev = (struct _Z_InputQ *)0; free ((char *)qptr); return; - } + } if (qptr == __Q_Tail) { __Q_Tail = qptr->prev; __Q_Tail->next = (struct _Z_InputQ *)0; @@ -1224,15 +1224,15 @@ Z_SendFragmentedNotice(ZNotice_t *notice, char multi[64]; int offset, hdrsize, fragsize, ret_len, message_len, waitforack; Code_t retval; - + hdrsize = len-notice->z_message_len; fragsize = Z_MAXPKTLEN-hdrsize-Z_FRAGFUDGE; - + offset = 0; waitforack = ((notice->z_kind == UNACKED || notice->z_kind == ACKED) && !__Zephyr_server); - + partnotice = *notice; while (offset < notice->z_message_len || !notice->z_message_len) { @@ -1245,7 +1245,7 @@ Z_SendFragmentedNotice(ZNotice_t *notice, htonl((u_long) partnotice.z_uid.tv.tv_sec); partnotice.z_uid.tv.tv_usec = htonl((u_long) partnotice.z_uid.tv.tv_usec); - (void) memcpy((char *)&partnotice.z_uid.zuid_addr, &__My_addr, + (void) memcpy((char *)&partnotice.z_uid.zuid_addr, &__My_addr, sizeof(__My_addr)); (void) memset(¬ice->z_sender_sockaddr, 0, sizeof(notice->z_sender_sockaddr)); notice->z_sender_sockaddr.ip4.sin_family = AF_INET; /*XXX*/ @@ -1329,8 +1329,9 @@ ZSetDebug(void (*proc) __P((const char *, va_list, void *)), #ifdef HAVE_KRB5 Code_t Z_Checksum(krb5_data *cksumbuf, - krb5_keyblock *keyblock, - krb5_cksumtype cksumtype, + krb5_keyblock *keyblock, + krb5_cksumtype cksumtype, + krb5_keyusage cksumusage, char **asn1_data, unsigned int *asn1_len) { @@ -1343,11 +1344,11 @@ Z_Checksum(krb5_data *cksumbuf, Checksum checksum; krb5_crypto cryptctx; #endif - + #ifndef HAVE_KRB5_CRYPTO_INIT /* Create the checksum -- MIT crypto API */ result = krb5_c_make_checksum(Z_krb5_ctx, cksumtype, - keyblock, Z_KEYUSAGE_CLT_CKSUM, + keyblock, cksumusage, cksumbuf, &checksum); if (result) return result; @@ -1357,14 +1358,14 @@ Z_Checksum(krb5_data *cksumbuf, len = checksum.length; #else /* Create the checksum -- heimdal crypto API */ - result = krb5_crypto_init(Z_krb5_ctx, keyblock, keyblock->keytype, + result = krb5_crypto_init(Z_krb5_ctx, keyblock, keyblock->keytype, &cryptctx); if (result) return result; /* HOLDING: cryptctx */ result = krb5_create_checksum(Z_krb5_ctx, cryptctx, - Z_KEYUSAGE_CLT_CKSUM, cksumtype, + cksumusage, cksumtype, cksumbuf->data, cksumbuf->length, &checksum); krb5_crypto_destroy(Z_krb5_ctx, cryptctx); @@ -1393,14 +1394,15 @@ Z_Checksum(krb5_data *cksumbuf, Code_t Z_InsertZcodeChecksum(krb5_keyblock *keyblock, - ZNotice_t *notice, + ZNotice_t *notice, char *buffer, char *cksum_start, - int cksum_len, + int cksum_len, char *cstart, char *cend, - int buffer_len, - int *length_adjust) + int buffer_len, + int *length_adjust, + int from_server) { int plain_len; /* length of part not to be checksummed */ int cksum0_len; /* length of part before checksum */ @@ -1412,13 +1414,13 @@ Z_InsertZcodeChecksum(krb5_keyblock *keyblock, krb5_enctype enctype; krb5_cksumtype cksumtype; Code_t result; - + key_data = Z_keydata(keyblock); key_len = Z_keylen(keyblock); result = Z_ExtractEncCksum(keyblock, &enctype, &cksumtype); if (result) return (ZAUTH_FAILED); - + /* Assemble the things to be checksummed */ plain_len = cksum_start - buffer; cksum0_len = cstart - cksum_start; @@ -1433,20 +1435,22 @@ Z_InsertZcodeChecksum(krb5_keyblock *keyblock, memcpy(cksumbuf.data + cksum0_len + cksum1_len, notice->z_message, notice->z_message_len); /* compute the checksum */ - result = Z_Checksum(&cksumbuf, keyblock, cksumtype, + result = Z_Checksum(&cksumbuf, keyblock, cksumtype, + from_server ? Z_KEYUSAGE_SRV_CKSUM + : Z_KEYUSAGE_CLT_CKSUM, (char **)&cksum.data, &cksum.length); if (result) { free(cksumbuf.data); return result; } - + /* * OK.... we can zcode to a space starting at 'cstart', * with a length of buffer_len - (plain_len + cksum_len). * Then we tack on the end part, which is located at * cksumbuf.data + cksum0_len and has length cksum1_len */ - + result = ZMakeZcode(cstart, buffer_len - (plain_len + cksum_len), (unsigned char *)cksum.data, cksum.length); free(cksum.data); @@ -1461,11 +1465,11 @@ Z_InsertZcodeChecksum(krb5_keyblock *keyblock, Code_t Z_ExtractEncCksum(krb5_keyblock *keyblock, - krb5_enctype *enctype, + krb5_enctype *enctype, krb5_cksumtype *cksumtype) { - *enctype = Z_enctype(keyblock); - return Z_krb5_lookup_cksumtype(*enctype, cksumtype); + *enctype = Z_enctype(keyblock); + return Z_krb5_lookup_cksumtype(*enctype, cksumtype); } #endif @@ -1473,9 +1477,10 @@ Z_ExtractEncCksum(krb5_keyblock *keyblock, /* returns 0 if invalid or losing, 1 if valid, *sigh* */ int Z_krb5_verify_cksum(krb5_keyblock *keyblock, - krb5_data *cksumbuf, + krb5_data *cksumbuf, krb5_cksumtype cksumtype, - unsigned char *asn1_data, + krb5_keyusage cksumusage, + unsigned char *asn1_data, int asn1_len) { krb5_error_code result; @@ -1495,7 +1500,7 @@ Z_krb5_verify_cksum(krb5_keyblock *keyblock, checksum.contents = asn1_data; checksum.checksum_type = cksumtype; result = krb5_c_verify_checksum(Z_krb5_ctx, - keyblock, Z_KEYUSAGE_SRV_CKSUM, + keyblock, cksumusage, cksumbuf, &checksum, &valid); if (!result && valid) return 1; @@ -1509,10 +1514,9 @@ Z_krb5_verify_cksum(krb5_keyblock *keyblock, result = krb5_crypto_init(Z_krb5_ctx, keyblock, keyblock->keytype, &cryptctx); if (result) return result; - + /* HOLDING: cryptctx */ - result = krb5_verify_checksum(Z_krb5_ctx, cryptctx, - Z_KEYUSAGE_SRV_CKSUM, + result = krb5_verify_checksum(Z_krb5_ctx, cryptctx, cksumusage, cksumbuf->data, cksumbuf->length, &checksum); krb5_crypto_destroy(Z_krb5_ctx, cryptctx); diff --git a/server/kstuff.c b/server/kstuff.c index c5a030a..fcb3218 100644 --- a/server/kstuff.c +++ b/server/kstuff.c @@ -5,7 +5,7 @@ * * Copyright (c) 1988 by the Massachusetts Institute of Technology. * For copying and distribution information, see the file - * "mit-copyright.h". + * "mit-copyright.h". */ /* * $Source$ @@ -86,7 +86,7 @@ GetKerberosData(int fd, /* file descr. to read from */ /* * SendKerberosData - * + * * create and transmit a ticket over the file descriptor for service.host * return failure codes if appropriate, or 0 if we * get the ticket and write it to the file descriptor @@ -101,7 +101,7 @@ SendKerberosData(int fd, /* file descriptor to write onto */ KTEXT ticket, /* where to put ticket (return) */ char *service, /* service name, foreign host */ char *host) - + { int rem; char p[32]; @@ -170,7 +170,7 @@ ReadKerberosData(int fd, int *size, char **data, int *proto) { syslog(LOG_WARNING, "ReadKerberosData: failure allocating %d bytes: %m", len); return errno; } - + dst=*data; for (i=0; i < len; i++) { if (read(fd, dst++, 1) != 1) { @@ -234,8 +234,8 @@ SendKrb5Data(int fd, krb5_data *data) { size_to_write = strlen (p); if (size_to_write != (written = write(fd, p, size_to_write)) || data->length != (written = write(fd, data->data, data->length))) { - return (written < 0) ? errno : ZSRV_PKSHORT; - } + return (written < 0) ? errno : ZSRV_PKSHORT; + } return 0; } #endif @@ -244,7 +244,7 @@ Code_t ZCheckRealmAuthentication(ZNotice_t *notice, struct sockaddr_in *from, char *realm) -{ +{ #ifdef HAVE_KRB5 char *authbuf; char rlmprincipal[MAX_PRINCIPAL_SIZE]; @@ -256,15 +256,15 @@ ZCheckRealmAuthentication(ZNotice_t *notice, krb5_principal server; krb5_keytab keytabid = 0; krb5_auth_context authctx; - krb5_keyblock *keyblock; - krb5_enctype enctype; - krb5_cksumtype cksumtype; + krb5_keyblock *keyblock; + krb5_enctype enctype; + krb5_cksumtype cksumtype; krb5_data cksumbuf; int valid; - char *cksum0_base, *cksum1_base = NULL, *cksum2_base; - char *x; + char *cksum0_base, *cksum1_base = NULL, *cksum2_base; + char *x; unsigned char *asn1_data; - unsigned char *key_data; + unsigned char *key_data; int asn1_len, key_len, cksum0_len = 0, cksum1_len = 0, cksum2_len = 0; krb5_flags acflags; #ifdef KRB5_AUTH_CON_GETAUTHENTICATOR_TAKES_DOUBLE_POINTER @@ -287,7 +287,7 @@ ZCheckRealmAuthentication(ZNotice_t *notice, authbuf = malloc(len); /* Read in the authentication data. */ - if (ZReadZcode((unsigned char *)notice->z_ascii_authent, + if (ZReadZcode((unsigned char *)notice->z_ascii_authent, (unsigned char *)authbuf, len, &len) == ZERR_BADFIELD) { return ZAUTH_FAILED; @@ -299,7 +299,7 @@ ZCheckRealmAuthentication(ZNotice_t *notice, packet.length = len; packet.data = authbuf; - result = krb5_kt_resolve(Z_krb5_ctx, + result = krb5_kt_resolve(Z_krb5_ctx, keytab_file, &keytabid); if (result) { free(authbuf); @@ -332,11 +332,11 @@ ZCheckRealmAuthentication(ZNotice_t *notice, } /* HOLDING: authbuf, authctx */ - result = krb5_build_principal(Z_krb5_ctx, &server, strlen(__Zephyr_realm), - __Zephyr_realm, SERVER_SERVICE, + result = krb5_build_principal(Z_krb5_ctx, &server, strlen(__Zephyr_realm), + __Zephyr_realm, SERVER_SERVICE, SERVER_INSTANCE, NULL); if (!result) { - result = krb5_rd_req(Z_krb5_ctx, &authctx, &packet, server, + result = krb5_rd_req(Z_krb5_ctx, &authctx, &packet, server, keytabid, NULL, &tkt); krb5_free_principal(Z_krb5_ctx, server); } @@ -356,7 +356,7 @@ ZCheckRealmAuthentication(ZNotice_t *notice, } /* HOLDING: authbuf, authctx, tkt */ - + if (tkt == 0 || !Z_tktprincp(tkt)) { if (tkt) krb5_free_ticket(Z_krb5_ctx, tkt); @@ -415,7 +415,7 @@ ZCheckRealmAuthentication(ZNotice_t *notice, krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT); return (ZAUTH_FAILED); } - + /* HOLDING: authctx, authenticator, keyblock */ /* Figure out what checksum type to use */ key_data = Z_keydata(keyblock); @@ -428,43 +428,43 @@ ZCheckRealmAuthentication(ZNotice_t *notice, return (ZAUTH_FAILED); } /* HOLDING: authctx, authenticator, keyblock */ - - /* Assemble the things to be checksummed */ - /* first part is from start of packet through z_default_format: - * - z_version - * - z_num_other_fields - * - z_kind - * - z_uid - * - z_port - * - z_auth - * - z_authent_len - * - z_ascii_authent - * - z_class - * - z_class_inst - * - z_opcode - * - z_sender - * - z_recipient - * - z_default_format - */ - cksum0_base = notice->z_packet; - x = notice->z_default_format; - cksum0_len = x + strlen(x) + 1 - cksum0_base; - /* second part is from z_multinotice through other fields: - * - z_multinotice + + /* Assemble the things to be checksummed */ + /* first part is from start of packet through z_default_format: + * - z_version + * - z_num_other_fields + * - z_kind + * - z_uid + * - z_port + * - z_auth + * - z_authent_len + * - z_ascii_authent + * - z_class + * - z_class_inst + * - z_opcode + * - z_sender + * - z_recipient + * - z_default_format + */ + cksum0_base = notice->z_packet; + x = notice->z_default_format; + cksum0_len = x + strlen(x) + 1 - cksum0_base; + /* second part is from z_multinotice through other fields: + * - z_multinotice * - z_multiuid * - z_sender_(sock)addr * - z_charset - * - z_other_fields[] + * - z_other_fields[] */ if (notice->z_num_hdr_fields > 15 ) { - cksum1_base = notice->z_multinotice; - if (notice->z_num_other_fields) - x = notice->z_other_fields[notice->z_num_other_fields - 1]; + cksum1_base = notice->z_multinotice; + if (notice->z_num_other_fields) + x = notice->z_other_fields[notice->z_num_other_fields - 1]; else { - /* see also ZCheckAuthentication and + /* see also ZCheckSrvAuthentication and lib/ZCkZaut.c:ZCheckZcodeAuthentication */ /* XXXXXXXXXXXXXXXXXXXXXXX */ - if (notice->z_num_hdr_fields > 16) + if (notice->z_num_hdr_fields > 16) x = cksum1_base + strlen(cksum1_base) + 1; /* multinotice */ if (notice->z_num_hdr_fields > 17) x = x + strlen(x) + 1; /* multiuid */ @@ -473,95 +473,97 @@ ZCheckRealmAuthentication(ZNotice_t *notice, } cksum1_len = x + strlen(x) + 1 - cksum1_base; /* charset / extra field */ } - - /* last part is the message body */ - cksum2_base = notice->z_message; - cksum2_len = notice->z_message_len; - - if ((!notice->z_ascii_checksum || *notice->z_ascii_checksum != 'Z') && - key_len == 8 && - (enctype == ENCTYPE_DES_CBC_CRC || - enctype == ENCTYPE_DES_CBC_MD4 || - enctype == ENCTYPE_DES_CBC_MD5)) { - /* try old-format checksum (covers cksum0 only) */ - - ZChecksum_t our_checksum; + + /* last part is the message body */ + cksum2_base = notice->z_message; + cksum2_len = notice->z_message_len; + + if ((!notice->z_ascii_checksum || *notice->z_ascii_checksum != 'Z') && + key_len == 8 && + (enctype == ENCTYPE_DES_CBC_CRC || + enctype == ENCTYPE_DES_CBC_MD4 || + enctype == ENCTYPE_DES_CBC_MD5)) { + /* try old-format checksum (covers cksum0 only) */ + + ZChecksum_t our_checksum; our_checksum = compute_rlm_checksum(notice, key_data); krb5_free_keyblock(Z_krb5_ctx, keyblock); krb5_auth_con_free(Z_krb5_ctx, authctx); krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT); - - if (our_checksum == notice->z_checksum) { - return ZAUTH_YES; + + if (our_checksum == notice->z_checksum) { + return ZAUTH_YES; } else return ZAUTH_FAILED; } /* HOLDING: authctx, authenticator */ - - cksumbuf.length = cksum0_len + cksum1_len + cksum2_len; - cksumbuf.data = malloc(cksumbuf.length); - if (!cksumbuf.data) { + + cksumbuf.length = cksum0_len + cksum1_len + cksum2_len; + cksumbuf.data = malloc(cksumbuf.length); + if (!cksumbuf.data) { krb5_free_keyblock(Z_krb5_ctx, keyblock); krb5_auth_con_free(Z_krb5_ctx, authctx); krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT); - return ZAUTH_FAILED; - } - /* HOLDING: authctx, authenticator, cksumbuf.data */ - + return ZAUTH_FAILED; + } + /* HOLDING: authctx, authenticator, cksumbuf.data */ + memcpy(cksumbuf.data, cksum0_base, cksum0_len); if (cksum1_len) - memcpy(cksumbuf.data + cksum0_len, cksum1_base, cksum1_len); - memcpy(cksumbuf.data + cksum0_len + cksum1_len, - cksum2_base, cksum2_len); - - /* decode zcoded checksum */ - /* The encoded form is always longer than the original */ - asn1_len = strlen(notice->z_ascii_checksum) + 1; - asn1_data = malloc(asn1_len); - if (!asn1_data) { + memcpy(cksumbuf.data + cksum0_len, cksum1_base, cksum1_len); + memcpy(cksumbuf.data + cksum0_len + cksum1_len, + cksum2_base, cksum2_len); + + /* decode zcoded checksum */ + /* The encoded form is always longer than the original */ + asn1_len = strlen(notice->z_ascii_checksum) + 1; + asn1_data = malloc(asn1_len); + if (!asn1_data) { krb5_free_keyblock(Z_krb5_ctx, keyblock); krb5_auth_con_free(Z_krb5_ctx, authctx); krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT); - free(cksumbuf.data); - return ZAUTH_FAILED; - } - /* HOLDING: authctx, authenticator, cksumbuf.data, asn1_data */ - result = ZReadZcode((unsigned char *)notice->z_ascii_checksum, - asn1_data, asn1_len, &asn1_len); - if (result != ZERR_NONE) { + free(cksumbuf.data); + return ZAUTH_FAILED; + } + /* HOLDING: authctx, authenticator, cksumbuf.data, asn1_data */ + result = ZReadZcode((unsigned char *)notice->z_ascii_checksum, + asn1_data, asn1_len, &asn1_len); + if (result != ZERR_NONE) { krb5_free_keyblock(Z_krb5_ctx, keyblock); krb5_auth_con_free(Z_krb5_ctx, authctx); krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT); - free(asn1_data); - free(cksumbuf.data); - return ZAUTH_FAILED; - } - /* HOLDING: asn1_data, cksumbuf.data */ + free(asn1_data); + free(cksumbuf.data); + return ZAUTH_FAILED; + } + /* HOLDING: asn1_data, cksumbuf.data */ - valid = Z_krb5_verify_cksum(keyblock, &cksumbuf, cksumtype, asn1_data, asn1_len); + valid = Z_krb5_verify_cksum(keyblock, &cksumbuf, cksumtype, + Z_KEYUSAGE_CLT_CKSUM, + asn1_data, asn1_len); - free(asn1_data); + free(asn1_data); krb5_auth_con_free(Z_krb5_ctx, authctx); krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT); krb5_free_keyblock(Z_krb5_ctx, keyblock); - free(cksumbuf.data); - - if (valid) - return (ZAUTH_YES); - else - return (ZAUTH_FAILED); + free(cksumbuf.data); + + if (valid) + return (ZAUTH_YES); + else + return (ZAUTH_FAILED); #else return (notice->z_auth) ? ZAUTH_YES : ZAUTH_NO; #endif } Code_t -ZCheckAuthentication(ZNotice_t *notice, - struct sockaddr_in *from) -{ +ZCheckSrvAuthentication(ZNotice_t *notice, + struct sockaddr_in *from) +{ #ifdef HAVE_KRB5 unsigned char *authbuf; krb5_principal princ; @@ -572,14 +574,14 @@ ZCheckAuthentication(ZNotice_t *notice, krb5_principal server; krb5_keytab keytabid = 0; krb5_auth_context authctx; - krb5_keyblock *keyblock; - krb5_enctype enctype; - krb5_cksumtype cksumtype; + krb5_keyblock *keyblock; + krb5_enctype enctype; + krb5_cksumtype cksumtype; krb5_data cksumbuf; int valid; - char *cksum0_base, *cksum1_base = NULL, *cksum2_base; - char *x; - unsigned char *asn1_data, *key_data; + char *cksum0_base, *cksum1_base = NULL, *cksum2_base; + char *x; + unsigned char *asn1_data, *key_data; int asn1_len, key_len, cksum0_len = 0, cksum1_len = 0, cksum2_len = 0; krb5_flags acflags; #ifdef KRB5_AUTH_CON_GETAUTHENTICATOR_TAKES_DOUBLE_POINTER @@ -602,12 +604,12 @@ ZCheckAuthentication(ZNotice_t *notice, if (notice->z_ascii_authent[0] != 'Z') return ZCheckAuthentication4(notice, from); #endif - + len = strlen(notice->z_ascii_authent)+1; authbuf = malloc(len); /* Read in the authentication data. */ - if (ZReadZcode((unsigned char *)notice->z_ascii_authent, + if (ZReadZcode((unsigned char *)notice->z_ascii_authent, authbuf, len, &len) == ZERR_BADFIELD) { return ZAUTH_FAILED; @@ -616,7 +618,7 @@ ZCheckAuthentication(ZNotice_t *notice, packet.length = len; packet.data = (char *)authbuf; - result = krb5_kt_resolve(Z_krb5_ctx, + result = krb5_kt_resolve(Z_krb5_ctx, keytab_file, &keytabid); if (result) { free(authbuf); @@ -649,11 +651,11 @@ ZCheckAuthentication(ZNotice_t *notice, } /* HOLDING: authbuf, authctx */ - result = krb5_build_principal(Z_krb5_ctx, &server, strlen(__Zephyr_realm), - __Zephyr_realm, SERVER_SERVICE, + result = krb5_build_principal(Z_krb5_ctx, &server, strlen(__Zephyr_realm), + __Zephyr_realm, SERVER_SERVICE, SERVER_INSTANCE, NULL); if (!result) { - result = krb5_rd_req(Z_krb5_ctx, &authctx, &packet, server, + result = krb5_rd_req(Z_krb5_ctx, &authctx, &packet, server, keytabid, NULL, &tkt); krb5_free_principal(Z_krb5_ctx, server); } @@ -661,10 +663,10 @@ ZCheckAuthentication(ZNotice_t *notice, if (result) { if (result == KRB5KRB_AP_ERR_REPEAT) - syslog(LOG_DEBUG, "ZCheckAuthentication: k5 auth failed: %s", + syslog(LOG_DEBUG, "ZCheckSrvAuthentication: k5 auth failed: %s", error_message(result)); else - syslog(LOG_WARNING,"ZCheckAuthentication: k5 auth failed: %s", + syslog(LOG_WARNING,"ZCheckSrvAuthentication: k5 auth failed: %s", error_message(result)); free(authbuf); krb5_auth_con_free(Z_krb5_ctx, authctx); @@ -730,51 +732,51 @@ ZCheckAuthentication(ZNotice_t *notice, krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT); return (ZAUTH_FAILED); } - + /* HOLDING: authctx, authenticator, keyblock */ /* Figure out what checksum type to use */ key_data = Z_keydata(keyblock); key_len = Z_keylen(keyblock); result = Z_ExtractEncCksum(keyblock, &enctype, &cksumtype); - if (result) { + if (result) { krb5_free_keyblock(Z_krb5_ctx, keyblock); krb5_auth_con_free(Z_krb5_ctx, authctx); krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT); - return (ZAUTH_FAILED); - } + return (ZAUTH_FAILED); + } /* HOLDING: authctx, authenticator, keyblock */ ZSetSession(keyblock); - - /* Assemble the things to be checksummed */ - /* first part is from start of packet through z_default_format: - * - z_version - * - z_num_other_fields - * - z_kind - * - z_uid - * - z_port - * - z_auth - * - z_authent_len - * - z_ascii_authent - * - z_class - * - z_class_inst - * - z_opcode - * - z_sender - * - z_recipient - * - z_default_format - */ - cksum0_base = notice->z_packet; - x = notice->z_default_format; - cksum0_len = x + strlen(x) + 1 - cksum0_base; - /* second part is from z_multinotice through other fields: - * - z_multinotice - * - z_multiuid - * - z_other_fields[] - */ + + /* Assemble the things to be checksummed */ + /* first part is from start of packet through z_default_format: + * - z_version + * - z_num_other_fields + * - z_kind + * - z_uid + * - z_port + * - z_auth + * - z_authent_len + * - z_ascii_authent + * - z_class + * - z_class_inst + * - z_opcode + * - z_sender + * - z_recipient + * - z_default_format + */ + cksum0_base = notice->z_packet; + x = notice->z_default_format; + cksum0_len = x + strlen(x) + 1 - cksum0_base; + /* second part is from z_multinotice through other fields: + * - z_multinotice + * - z_multiuid + * - z_other_fields[] + */ if (notice->z_num_hdr_fields > 15 ) { - cksum1_base = notice->z_multinotice; - if (notice->z_num_other_fields) - x = notice->z_other_fields[notice->z_num_other_fields - 1]; + cksum1_base = notice->z_multinotice; + if (notice->z_num_other_fields) + x = notice->z_other_fields[notice->z_num_other_fields - 1]; else { /* see also ZCheckRealmAuthentication and lib/ZCkZaut.c:ZCheckZcodeAuthentication */ @@ -788,88 +790,90 @@ ZCheckAuthentication(ZNotice_t *notice, } cksum1_len = x + strlen(x) + 1 - cksum1_base; /* charset / extra field */ } - - /* last part is the message body */ - cksum2_base = notice->z_message; + + /* last part is the message body */ + cksum2_base = notice->z_message; cksum2_len = notice->z_message_len; #ifdef HAVE_KRB4 /*XXX*/ - if ((!notice->z_ascii_checksum || *notice->z_ascii_checksum != 'Z') && - key_len == 8 && - (enctype == ENCTYPE_DES_CBC_CRC || - enctype == ENCTYPE_DES_CBC_MD4 || - enctype == ENCTYPE_DES_CBC_MD5)) { - /* try old-format checksum (covers cksum0 only) */ - - ZChecksum_t our_checksum; - + if ((!notice->z_ascii_checksum || *notice->z_ascii_checksum != 'Z') && + key_len == 8 && + (enctype == ENCTYPE_DES_CBC_CRC || + enctype == ENCTYPE_DES_CBC_MD4 || + enctype == ENCTYPE_DES_CBC_MD5)) { + /* try old-format checksum (covers cksum0 only) */ + + ZChecksum_t our_checksum; + our_checksum = compute_checksum(notice, key_data); - + krb5_free_keyblock(Z_krb5_ctx, keyblock); krb5_auth_con_free(Z_krb5_ctx, authctx); krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT); if (our_checksum == notice->z_checksum) - return ZAUTH_YES; + return ZAUTH_YES; else return ZAUTH_FAILED; } #endif /* HOLDING: authctx, authenticator */ - - cksumbuf.length = cksum0_len + cksum1_len + cksum2_len; - cksumbuf.data = malloc(cksumbuf.length); - if (!cksumbuf.data) { + + cksumbuf.length = cksum0_len + cksum1_len + cksum2_len; + cksumbuf.data = malloc(cksumbuf.length); + if (!cksumbuf.data) { krb5_free_keyblock(Z_krb5_ctx, keyblock); krb5_auth_con_free(Z_krb5_ctx, authctx); krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT); - return ZAUTH_FAILED; - } - /* HOLDING: authctx, authenticator, cksumbuf.data */ - + return ZAUTH_FAILED; + } + /* HOLDING: authctx, authenticator, cksumbuf.data */ + memcpy(cksumbuf.data, cksum0_base, cksum0_len); if (cksum1_len) - memcpy(cksumbuf.data + cksum0_len, cksum1_base, cksum1_len); - memcpy(cksumbuf.data + cksum0_len + cksum1_len, - cksum2_base, cksum2_len); - - /* decode zcoded checksum */ - /* The encoded form is always longer than the original */ - asn1_len = strlen(notice->z_ascii_checksum) + 1; - asn1_data = malloc(asn1_len); - if (!asn1_data) { + memcpy(cksumbuf.data + cksum0_len, cksum1_base, cksum1_len); + memcpy(cksumbuf.data + cksum0_len + cksum1_len, + cksum2_base, cksum2_len); + + /* decode zcoded checksum */ + /* The encoded form is always longer than the original */ + asn1_len = strlen(notice->z_ascii_checksum) + 1; + asn1_data = malloc(asn1_len); + if (!asn1_data) { krb5_free_keyblock(Z_krb5_ctx, keyblock); krb5_auth_con_free(Z_krb5_ctx, authctx); krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT); - free(cksumbuf.data); - return ZAUTH_FAILED; - } - /* HOLDING: authctx, authenticator, cksumbuf.data, asn1_data */ - result = ZReadZcode((unsigned char *)notice->z_ascii_checksum, - asn1_data, asn1_len, &asn1_len); - if (result != ZERR_NONE) { + free(cksumbuf.data); + return ZAUTH_FAILED; + } + /* HOLDING: authctx, authenticator, cksumbuf.data, asn1_data */ + result = ZReadZcode((unsigned char *)notice->z_ascii_checksum, + asn1_data, asn1_len, &asn1_len); + if (result != ZERR_NONE) { krb5_free_keyblock(Z_krb5_ctx, keyblock); krb5_auth_con_free(Z_krb5_ctx, authctx); krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT); - free(asn1_data); - free(cksumbuf.data); - return ZAUTH_FAILED; - } - /* HOLDING: asn1_data, cksumbuf.data, authctx, authenticator */ + free(asn1_data); + free(cksumbuf.data); + return ZAUTH_FAILED; + } + /* HOLDING: asn1_data, cksumbuf.data, authctx, authenticator */ - valid = Z_krb5_verify_cksum(keyblock, &cksumbuf, cksumtype, asn1_data, asn1_len); + valid = Z_krb5_verify_cksum(keyblock, &cksumbuf, cksumtype, + Z_KEYUSAGE_CLT_CKSUM, + asn1_data, asn1_len); - free(asn1_data); + free(asn1_data); krb5_auth_con_free(Z_krb5_ctx, authctx); krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT); krb5_free_keyblock(Z_krb5_ctx, keyblock); - free(cksumbuf.data); - - if (valid) - return (ZAUTH_YES); - else - return (ZAUTH_FAILED); + free(cksumbuf.data); + + if (valid) + return (ZAUTH_YES); + else + return (ZAUTH_FAILED); #else return (notice->z_auth) ? ZAUTH_YES : ZAUTH_NO; #endif @@ -881,7 +885,7 @@ ZCheckAuthentication(ZNotice_t *notice, static Code_t ZCheckAuthentication4(ZNotice_t *notice, struct sockaddr_in *from) -{ +{ int result; char srcprincipal[ANAME_SZ+INST_SZ+REALM_SZ+4]; KTEXT_ST authent; @@ -897,9 +901,9 @@ ZCheckAuthentication4(ZNotice_t *notice, return ZAUTH_FAILED; /* Read in the authentication data. */ - if (ZReadAscii(notice->z_ascii_authent, - strlen(notice->z_ascii_authent)+1, - (unsigned char *)authent.dat, + if (ZReadAscii(notice->z_ascii_authent, + strlen(notice->z_ascii_authent)+1, + (unsigned char *)authent.dat, notice->z_authent_len) == ZERR_BADFIELD) { return ZAUTH_FAILED; } @@ -966,7 +970,7 @@ static ZChecksum_t compute_rlm_checksum(ZNotice_t *notice, #endif #ifdef HAVE_KRB5 -krb5_error_code +krb5_error_code Z_krb5_init_keyblock(krb5_context context, krb5_enctype type, size_t size, @@ -1001,7 +1005,7 @@ ZSetSession(krb5_keyblock *keyblock) { } else { result = krb5_copy_keyblock(Z_krb5_ctx, keyblock, &__Zephyr_keyblock); } - + if (result) /*XXX we're out of memory? */ ; } @@ -1015,7 +1019,7 @@ ZSetSessionDES(C_Block *key) { krb5_free_keyblock(Z_krb5_ctx, __Zephyr_keyblock); __Zephyr_keyblock=NULL; } - result = Z_krb5_init_keyblock(Z_krb5_ctx, ENCTYPE_DES_CBC_CRC, + result = Z_krb5_init_keyblock(Z_krb5_ctx, ENCTYPE_DES_CBC_CRC, sizeof(C_Block), &__Zephyr_keyblock); if (result) /*XXX we're out of memory? */ diff --git a/server/zserver.h b/server/zserver.h index ae71838..c0c84fc 100644 --- a/server/zserver.h +++ b/server/zserver.h @@ -9,7 +9,7 @@ * * Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology. * For copying and distribution information, see the file - * "mit-copyright.h". + * "mit-copyright.h". */ #include @@ -34,7 +34,6 @@ extern krb5_keyblock *__Zephyr_keyblock; #define ZGetSession() (__Zephyr_keyblock) void ZSetSession(krb5_keyblock *keyblock); -Code_t ZFormatAuthenticNoticeV5(ZNotice_t*, char*, int, int*, krb5_keyblock *); krb5_error_code Z_krb5_init_keyblock(krb5_context, krb5_enctype, size_t, krb5_keyblock **); #endif @@ -104,7 +103,7 @@ struct _ZRealm { int idx; /* which server we are connected to */ Destlist *subs; /* what their clients sub to */ Destlist *remsubs; /* our subs on their end */ - Client *client; + Client *client; int child_pid; int have_tkt; ZRealm_state state; @@ -220,7 +219,7 @@ struct _Statistic { (*head) = (elem); \ (elem)->prev_p = (head); \ } - + #define MAKE_LIST_DELETE(type) inline static void type##_delete(type *elem) \ {\ *(elem)->prev_p = (elem)->next; \ @@ -229,10 +228,10 @@ struct _Statistic { MAKE_LIST_INSERT(Destlist); MAKE_LIST_DELETE(Destlist); -MAKE_LIST_INSERT(Client); -MAKE_LIST_DELETE(Client); -MAKE_LIST_INSERT(Triplet); -MAKE_LIST_DELETE(Triplet); +MAKE_LIST_INSERT(Client); +MAKE_LIST_DELETE(Client); +MAKE_LIST_INSERT(Triplet); +MAKE_LIST_DELETE(Triplet); MAKE_LIST_INSERT(Unacked); MAKE_LIST_DELETE(Unacked); @@ -293,6 +292,7 @@ Code_t xmit_frag(ZNotice_t *notice, char *buf, int len, int waitforack); void hostm_shutdown(void); /* found in kstuff.c */ +Code_t ZCheckSrvAuthentication(ZNotice_t *notice, struct sockaddr_in *from); Code_t ZCheckRealmAuthentication(ZNotice_t *, struct sockaddr_in *, char *); #if defined(HAVE_KRB4) || defined(HAVE_KRB5) Code_t ReadKerberosData(int, int *, char **, int *); @@ -306,7 +306,7 @@ Code_t SendKerberosData (int, KTEXT, char *, char *); Code_t SendKrb5Data(int, krb5_data *); Code_t GetKrb5Data(int, krb5_data *); #endif - + /* found in server.c */ void server_timo(void *which); void server_dump_servers(FILE *fp); -- cgit v1.2.3