diff options
Diffstat (limited to 'src/lib/krb4/recvauth.c')
-rw-r--r-- | src/lib/krb4/recvauth.c | 308 |
1 files changed, 0 insertions, 308 deletions
diff --git a/src/lib/krb4/recvauth.c b/src/lib/krb4/recvauth.c deleted file mode 100644 index c5f857e98..000000000 --- a/src/lib/krb4/recvauth.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * lib/krb4/recvauth.c - * - * Copyright 1987, 1988 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. Furthermore if you modify this software you must label - * your software as modified software and not distribute it in such a - * fashion that it might be confused with the original M.I.T. software. - * M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#include "krb.h" -#include <errno.h> -#include <stdio.h> -#include <string.h> -#include "autoconf.h" -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#include "port-sockets.h" - - -#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN - chars */ - -/* - * If the protocol changes, you will need to change the version string - * and make appropriate changes in krb_sendauth.c - * be sure to support old versions of krb_sendauth! - */ - -/* - * krb_recvauth() reads (and optionally responds to) a message sent - * using krb_sendauth(). The "options" argument is a bit-field of - * selected options (see "sendauth.c" for options description). - * The only option relevant to krb_recvauth() is KOPT_DO_MUTUAL - * (mutual authentication requested). The "fd" argument supplies - * a file descriptor to read from (and write to, if mutual authenti- - * cation is requested). - * - * Part of the received message will be a Kerberos ticket sent by the - * client; this is read into the "ticket" argument. The "service" and - * "instance" arguments supply the server's Kerberos name. If the - * "instance" argument is the string "*", it is treated as a wild card - * and filled in during the krb_rd_req() call (see read_service_key()). - * - * The "faddr" and "laddr" give the sending (client) and receiving - * (local server) network addresses. ("laddr" may be left NULL unless - * mutual authentication is requested, in which case it must be set.) - * - * The authentication information extracted from the message is returned - * in "kdata". The "filename" argument indicates the file where the - * server's key can be found. (It is passed on to krb_rd_req().) If - * left null, the default "/etc/srvtab" will be used. - * - * If mutual authentication is requested, the session key schedule must - * be computed in order to reply; this schedule is returned in the - * "schedule" argument. A string containing the application version - * number from the received message is returned in "version", which - * should be large enough to hold a KRB_SENDAUTH_VLEN-character string. - * - * See krb_sendauth() for the format of the received client message. - * - * This routine supports another client format, for backward - * compatibility, consisting of: - * - * Size Variable Field - * ---- -------- ----- - * - * string tmp_buf, tkt_len length of ticket, in - * ascii - * - * char ' ' (space char) separator - * - * tkt_len ticket->dat the ticket - * - * This old-style version does not support mutual authentication. - * - * krb_recvauth() first reads the protocol version string from the - * given file descriptor. If it doesn't match the current protocol - * version (KRB_SENDAUTH_VERS), the old-style format is assumed. In - * that case, the string of characters up to the first space is read - * and interpreted as the ticket length, then the ticket is read. - * - * If the first string did match KRB_SENDAUTH_VERS, krb_recvauth() - * next reads the application protocol version string. Then the - * ticket length and ticket itself are read. - * - * The ticket is decrypted and checked by the call to krb_rd_req(). - * If no mutual authentication is required, the result of the - * krb_rd_req() call is retured by this routine. If mutual authenti- - * cation is required, a message in the following format is returned - * on "fd": - * - * Size Variable Field - * ---- -------- ----- - * - * 4 bytes tkt_len length of ticket or -1 - * if error occurred - * - * priv_len tmp_buf "private" message created - * by krb_mk_priv() which - * contains the incremented - * checksum sent by the client - * encrypted in the session - * key. (This field is not - * present in case of error.) - * - * If all goes well, KSUCCESS is returned; otherwise KFAILURE or some - * other error code is returned. - */ - -#ifndef max -#define max(a,b) (((a) > (b)) ? (a) : (b)) -#endif /* max */ - -int KRB5_CALLCONV -krb_recvauth(options, fd, ticket, service, instance, faddr, laddr, kdata, - filename, schedule, version) - long options; /* bit-pattern of options */ - int fd; /* file descr. to read from */ - KTEXT ticket; /* storage for client's ticket */ - char *service; /* service expected */ - char *instance; /* inst expected (may be filled in) */ - struct sockaddr_in *faddr; /* address of foreign host on fd */ - struct sockaddr_in *laddr; /* local address */ - AUTH_DAT *kdata; /* kerberos data (returned) */ - char *filename; /* name of file with service keys */ - Key_schedule schedule; /* key schedule (return) */ - char *version; /* version string (filled in) */ -{ - - int i, cc, old_vers = 0; - char krb_vers[KRB_SENDAUTH_VLEN + 1]; /* + 1 for the null terminator */ - char *cp = NULL; - int rem; - KRB4_32 tkt_len, priv_len; - unsigned KRB4_32 cksum; - u_char tmp_buf[MAX_KTXT_LEN+max(KRB_SENDAUTH_VLEN+1,21)] = { 0 }; - - /* read the protocol version number */ - if (krb_net_read(fd, krb_vers, KRB_SENDAUTH_VLEN) != - KRB_SENDAUTH_VLEN) - return(errno); - krb_vers[KRB_SENDAUTH_VLEN] = '\0'; - - /* check version string */ - if (strcmp(krb_vers,KRB_SENDAUTH_VERS)) { - /* Assume the old version of sendkerberosdata: send ascii - length, ' ', and ticket. */ - if (options & KOPT_DO_MUTUAL) - return(KFAILURE); /* XXX can't do old style with mutual auth */ - old_vers = 1; - - /* copy what we have read into tmp_buf */ - (void) memcpy((char *) tmp_buf, krb_vers, KRB_SENDAUTH_VLEN); - - /* search for space, and make it a null */ - for (i = 0; i < KRB_SENDAUTH_VLEN; i++) - if (tmp_buf[i]== ' ') { - tmp_buf[i] = '\0'; - /* point cp to the beginning of the real ticket */ - cp = (char *) &tmp_buf[i+1]; - break; - } - - if (i == KRB_SENDAUTH_VLEN) - /* didn't find the space, keep reading to find it */ - for (; i<20; i++) { - if (read(fd, (char *)&tmp_buf[i], 1) != 1) { - return(KFAILURE); - } - if (tmp_buf[i] == ' ') { - tmp_buf[i] = '\0'; - /* point cp to the beginning of the real ticket */ - cp = (char *) &tmp_buf[i+1]; - break; - } - } - - if (i==20) - return(KFAILURE); - - tkt_len = (KRB4_32) atoi((char *) tmp_buf); - - /* sanity check the length */ - /* These conditions make sure that cp got initialized */ - if ((tkt_len<=0)||(tkt_len>MAX_KTXT_LEN)) - return(KFAILURE); - - if (i < KRB_SENDAUTH_VLEN) { - /* since we already got the space, and part of the ticket, - we read fewer bytes to get the rest of the ticket */ - int len_to_read = tkt_len - KRB_SENDAUTH_VLEN + 1 + i; - if (len_to_read <= 0) - return KFAILURE; - if (krb_net_read(fd, (char *)(tmp_buf+KRB_SENDAUTH_VLEN), - len_to_read) - != len_to_read) - return(errno); - } else { - if (krb_net_read(fd, (char *)(tmp_buf+i), (int)tkt_len) != - (int) tkt_len) - return(errno); - } - ticket->length = tkt_len; - /* copy the ticket into the struct */ - (void) memcpy((char *) ticket->dat, cp, ticket->length); - - } else { - /* read the application version string */ - if (krb_net_read(fd, version, KRB_SENDAUTH_VLEN) != - KRB_SENDAUTH_VLEN) - return(errno); - version[KRB_SENDAUTH_VLEN] = '\0'; - - /* get the length of the ticket */ - if (krb_net_read(fd, (char *)&tkt_len, sizeof(tkt_len)) != - sizeof(tkt_len)) - return(errno); - - /* sanity check */ - ticket->length = ntohl((unsigned KRB4_32)tkt_len); - if ((ticket->length <= 0) || (ticket->length > MAX_KTXT_LEN)) { - if (options & KOPT_DO_MUTUAL) { - rem = KFAILURE; - goto mutual_fail; - } else - return(KFAILURE); /* XXX there may still be junk on the fd? */ - } - - /* read the ticket */ - if (krb_net_read(fd, (char *) ticket->dat, ticket->length) - != ticket->length) - return(errno); - } - /* - * now have the ticket. decrypt it to get the authenticated - * data. - */ - rem = krb_rd_req(ticket,service,instance,faddr->sin_addr.s_addr, - kdata,filename); - - if (old_vers) return(rem); /* XXX can't do mutual with old client */ - - /* if we are doing mutual auth, compose a response */ - if (options & KOPT_DO_MUTUAL) { - if (rem != KSUCCESS) - /* the krb_rd_req failed */ - goto mutual_fail; - - /* add one to the (formerly) sealed checksum, and re-seal it - for return to the client */ - cksum = kdata->checksum + 1; - cksum = htonl(cksum); -#ifndef NOENCRYPTION - key_sched(kdata->session,schedule); -#endif /* !NOENCRYPTION */ - priv_len = krb_mk_priv((unsigned char *)&cksum, - tmp_buf, - (unsigned KRB4_32) sizeof(cksum), - schedule, - &kdata->session, - laddr, - faddr); - if (priv_len < 0) { - /* re-sealing failed; notify the client */ - rem = KFAILURE; /* XXX */ -mutual_fail: - priv_len = -1; - tkt_len = htonl((unsigned KRB4_32) priv_len); - /* a length of -1 is interpreted as an authentication - failure by the client */ - if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len))) - != sizeof(tkt_len)) - return(cc); - return(rem); - } else { - /* re-sealing succeeded, send the private message */ - tkt_len = htonl((unsigned KRB4_32)priv_len); - if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len))) - != sizeof(tkt_len)) - return(cc); - if ((cc = krb_net_write(fd, (char *)tmp_buf, (int) priv_len)) - != (int) priv_len) - return(cc); - } - } - return(rem); -} |