Annotation of 43BSDReno/kerberosIV/krb/recvauth.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * $Source: /usr/src/kerberosIV/src/lib/krb/RCS/recvauth.c,v $
        !             3:  * $Author: kfall $
        !             4:  *
        !             5:  * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
        !             6:  *
        !             7:  * For copying and distribution information, please see the file
        !             8:  * <mit-copyright.h>.
        !             9:  */
        !            10: 
        !            11: #ifndef        lint
        !            12: static char rcsid_recvauth_c[] =
        !            13: "$Header: /usr/src/kerberosIV/src/lib/krb/RCS/recvauth.c,v 4.4 90/05/12 00:58:56 kfall Exp $";
        !            14: #endif lint
        !            15: 
        !            16: #include <mit-copyright.h>
        !            17: 
        !            18: #include <des.h>
        !            19: #include <krb.h>
        !            20: #include <sys/types.h>
        !            21: #include <netinet/in.h>
        !            22: #include <syslog.h>
        !            23: #include <errno.h>
        !            24: #include <stdio.h>
        !            25: #include <strings.h>
        !            26: 
        !            27: 
        !            28: #define        KRB_SENDAUTH_VERS       "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN
        !            29:                                              chars */
        !            30: 
        !            31: /*
        !            32:  * If the protocol changes, you will need to change the version string
        !            33:  * and make appropriate changes in krb_sendauth.c
        !            34:  * be sure to support old versions of krb_sendauth!
        !            35:  */
        !            36: 
        !            37: extern int errno;
        !            38: 
        !            39: /*
        !            40:  * krb_recvauth() reads (and optionally responds to) a message sent
        !            41:  * using krb_sendauth().  The "options" argument is a bit-field of
        !            42:  * selected options (see "sendauth.c" for options description).
        !            43:  * The only option relevant to krb_recvauth() is KOPT_DO_MUTUAL
        !            44:  * (mutual authentication requested).  The "fd" argument supplies
        !            45:  * a file descriptor to read from (and write to, if mutual authenti-
        !            46:  * cation is requested).
        !            47:  *
        !            48:  * Part of the received message will be a Kerberos ticket sent by the
        !            49:  * client; this is read into the "ticket" argument.  The "service" and
        !            50:  * "instance" arguments supply the server's Kerberos name.  If the
        !            51:  * "instance" argument is the string "*", it is treated as a wild card
        !            52:  * and filled in during the krb_rd_req() call (see read_service_key()).
        !            53:  *
        !            54:  * The "faddr" and "laddr" give the sending (client) and receiving
        !            55:  * (local server) network addresses.  ("laddr" may be left NULL unless
        !            56:  * mutual authentication is requested, in which case it must be set.)
        !            57:  *
        !            58:  * The authentication information extracted from the message is returned
        !            59:  * in "kdata".  The "filename" argument indicates the file where the
        !            60:  * server's key can be found.  (It is passed on to krb_rd_req().)  If
        !            61:  * left null, the default "/etc/srvtab" will be used.
        !            62:  *
        !            63:  * If mutual authentication is requested, the session key schedule must
        !            64:  * be computed in order to reply; this schedule is returned in the
        !            65:  * "schedule" argument.  A string containing the application version
        !            66:  * number from the received message is returned in "version", which
        !            67:  * should be large enough to hold a KRB_SENDAUTH_VLEN-character string.
        !            68:  *
        !            69:  * See krb_sendauth() for the format of the received client message.
        !            70:  *
        !            71:  * This routine supports another client format, for backward
        !            72:  * compatibility, consisting of:
        !            73:  *
        !            74:  * Size                        Variable                Field
        !            75:  * ----                        --------                -----
        !            76:  *
        !            77:  * string              tmp_buf, tkt_len        length of ticket, in
        !            78:  *                                             ascii
        !            79:  *
        !            80:  * char                        ' ' (space char)        separator
        !            81:  *
        !            82:  * tkt_len             ticket->dat             the ticket
        !            83:  *
        !            84:  * This old-style version does not support mutual authentication.
        !            85:  *
        !            86:  * krb_recvauth() first reads the protocol version string from the
        !            87:  * given file descriptor.  If it doesn't match the current protocol
        !            88:  * version (KRB_SENDAUTH_VERS), the old-style format is assumed.  In
        !            89:  * that case, the string of characters up to the first space is read
        !            90:  * and interpreted as the ticket length, then the ticket is read.
        !            91:  *
        !            92:  * If the first string did match KRB_SENDAUTH_VERS, krb_recvauth()
        !            93:  * next reads the application protocol version string.  Then the
        !            94:  * ticket length and ticket itself are read.
        !            95:  *
        !            96:  * The ticket is decrypted and checked by the call to krb_rd_req().
        !            97:  * If no mutual authentication is required, the result of the
        !            98:  * krb_rd_req() call is retured by this routine.  If mutual authenti-
        !            99:  * cation is required, a message in the following format is returned
        !           100:  * on "fd":
        !           101:  *
        !           102:  * Size                        Variable                Field
        !           103:  * ----                        --------                -----
        !           104:  *
        !           105:  * 4 bytes             tkt_len                 length of ticket or -1
        !           106:  *                                             if error occurred
        !           107:  *
        !           108:  * priv_len            tmp_buf                 "private" message created
        !           109:  *                                             by krb_mk_priv() which
        !           110:  *                                             contains the incremented
        !           111:  *                                             checksum sent by the client
        !           112:  *                                             encrypted in the session
        !           113:  *                                             key.  (This field is not
        !           114:  *                                             present in case of error.)
        !           115:  *
        !           116:  * If all goes well, KSUCCESS is returned; otherwise KFAILURE or some
        !           117:  * other error code is returned.
        !           118:  */
        !           119: 
        !           120: int
        !           121: krb_recvauth(options, fd, ticket, service, instance, faddr, laddr, kdata,
        !           122:             filename, schedule, version)
        !           123: long options;                   /* bit-pattern of options */
        !           124: int fd;                                 /* file descr. to read from */
        !           125: KTEXT ticket;                   /* storage for client's ticket */
        !           126: char *service;                  /* service expected */
        !           127: char *instance;                         /* inst expected (may be filled in) */
        !           128: struct sockaddr_in *faddr;      /* address of foreign host on fd */
        !           129: struct sockaddr_in *laddr;      /* local address */
        !           130: AUTH_DAT *kdata;                /* kerberos data (returned) */
        !           131: char *filename;                         /* name of file with service keys */
        !           132: Key_schedule schedule;          /* key schedule (return) */
        !           133: char *version;                  /* version string (filled in) */
        !           134: {
        !           135: 
        !           136:     int i, cc, old_vers = 0;
        !           137:     char krb_vers[KRB_SENDAUTH_VLEN + 1]; /* + 1 for the null terminator */
        !           138:     char *cp;
        !           139:     int rem;
        !           140:     long tkt_len, priv_len;
        !           141:     u_long cksum;
        !           142:     u_char tmp_buf[1024];
        !           143: 
        !           144:     /* read the protocol version number */
        !           145:     if (krb_net_read(fd, krb_vers, KRB_SENDAUTH_VLEN) !=
        !           146:        KRB_SENDAUTH_VLEN)
        !           147:            return(errno);
        !           148:     krb_vers[KRB_SENDAUTH_VLEN] = '\0';
        !           149: 
        !           150:     /* check version string */
        !           151:     if (strcmp(krb_vers,KRB_SENDAUTH_VERS)) {
        !           152:        /* Assume the old version of sendkerberosdata: send ascii
        !           153:           length, ' ', and ticket. */
        !           154:        if (options & KOPT_DO_MUTUAL)
        !           155:            return(KFAILURE);    /* XXX can't do old style with mutual auth */
        !           156:        old_vers = 1;
        !           157: 
        !           158:        /* copy what we have read into tmp_buf */
        !           159:        (void) bcopy(krb_vers, (char *) tmp_buf, KRB_SENDAUTH_VLEN);
        !           160: 
        !           161:        /* search for space, and make it a null */
        !           162:        for (i = 0; i < KRB_SENDAUTH_VLEN; i++)
        !           163:            if (tmp_buf[i]== ' ') {
        !           164:                tmp_buf[i] = '\0';
        !           165:                /* point cp to the beginning of the real ticket */
        !           166:                cp = (char *) &tmp_buf[i+1];
        !           167:                break;
        !           168:            }
        !           169: 
        !           170:        if (i == KRB_SENDAUTH_VLEN)
        !           171:            /* didn't find the space, keep reading to find it */
        !           172:            for (; i<20; i++) {
        !           173:                if (read(fd, (char *)&tmp_buf[i], 1) != 1) {
        !           174:                    return(KFAILURE);
        !           175:                }
        !           176:                if (tmp_buf[i] == ' ') {
        !           177:                    tmp_buf[i] = '\0';
        !           178:                    /* point cp to the beginning of the real ticket */
        !           179:                    cp = (char *) &tmp_buf[i+1];
        !           180:                    break;
        !           181:                }
        !           182:            }
        !           183: 
        !           184:        tkt_len = (long) atoi((char *) tmp_buf);
        !           185: 
        !           186:        /* sanity check the length */
        !           187:        if ((i==20)||(tkt_len<=0)||(tkt_len>MAX_KTXT_LEN))
        !           188:            return(KFAILURE);
        !           189: 
        !           190:        if (i < KRB_SENDAUTH_VLEN) {
        !           191:            /* since we already got the space, and part of the ticket,
        !           192:               we read fewer bytes to get the rest of the ticket */
        !           193:            if (krb_net_read(fd, (char *)(tmp_buf+KRB_SENDAUTH_VLEN),
        !           194:                             (int) (tkt_len - KRB_SENDAUTH_VLEN + 1 + i))
        !           195:                != (int)(tkt_len - KRB_SENDAUTH_VLEN + 1 + i))
        !           196:                return(errno);
        !           197:        } else {
        !           198:            if (krb_net_read(fd, (char *)(tmp_buf+i), (int)tkt_len) !=
        !           199:                (int) tkt_len)
        !           200:                return(errno);
        !           201:        }
        !           202:        ticket->length = tkt_len;
        !           203:        /* copy the ticket into the struct */
        !           204:        (void) bcopy(cp, (char *) ticket->dat, ticket->length);
        !           205: 
        !           206:     } else {
        !           207:        /* read the application version string */
        !           208:        if (krb_net_read(fd, version, KRB_SENDAUTH_VLEN) !=
        !           209:            KRB_SENDAUTH_VLEN)
        !           210:            return(errno);
        !           211:        version[KRB_SENDAUTH_VLEN] = '\0';
        !           212: 
        !           213:        /* get the length of the ticket */
        !           214:        if (krb_net_read(fd, (char *)&tkt_len, sizeof(tkt_len)) !=
        !           215:            sizeof(tkt_len))
        !           216:            return(errno);
        !           217:     
        !           218:        /* sanity check */
        !           219:        ticket->length = ntohl((unsigned long)tkt_len);
        !           220:        if ((ticket->length <= 0) || (ticket->length > MAX_KTXT_LEN)) {
        !           221:            if (options & KOPT_DO_MUTUAL) {
        !           222:                rem = KFAILURE;
        !           223:                goto mutual_fail;
        !           224:            } else
        !           225:                return(KFAILURE); /* XXX there may still be junk on the fd? */
        !           226:        }
        !           227: 
        !           228:        /* read the ticket */
        !           229:        if (krb_net_read(fd, (char *) ticket->dat, ticket->length)
        !           230:            != ticket->length)
        !           231:            return(errno);
        !           232:     }
        !           233:     /*
        !           234:      * now have the ticket.  decrypt it to get the authenticated
        !           235:      * data.
        !           236:      */
        !           237:     rem = krb_rd_req(ticket,service,instance,faddr->sin_addr.s_addr,
        !           238:                     kdata,filename);
        !           239: 
        !           240:     if (old_vers) return(rem);  /* XXX can't do mutual with old client */
        !           241: 
        !           242:     /* if we are doing mutual auth, compose a response */
        !           243:     if (options & KOPT_DO_MUTUAL) {
        !           244:        if (rem != KSUCCESS)
        !           245:            /* the krb_rd_req failed */
        !           246:            goto mutual_fail;
        !           247: 
        !           248:        /* add one to the (formerly) sealed checksum, and re-seal it
        !           249:           for return to the client */
        !           250:        cksum = kdata->checksum + 1;
        !           251:        cksum = htonl(cksum);
        !           252: #ifndef NOENCRYPTION
        !           253:        key_sched(kdata->session,schedule);
        !           254: #endif /* !NOENCRYPTION */
        !           255:        priv_len = krb_mk_priv((unsigned char *)&cksum,
        !           256:                               tmp_buf,
        !           257:                               (unsigned long) sizeof(cksum),
        !           258:                               schedule,
        !           259:                               kdata->session,
        !           260:                               laddr,
        !           261:                               faddr);
        !           262:        if (priv_len < 0) {
        !           263:            /* re-sealing failed; notify the client */
        !           264:            rem = KFAILURE;      /* XXX */
        !           265: mutual_fail:
        !           266:            priv_len = -1;
        !           267:            tkt_len = htonl((unsigned long) priv_len);
        !           268:            /* a length of -1 is interpreted as an authentication
        !           269:               failure by the client */
        !           270:            if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len)))
        !           271:                != sizeof(tkt_len))
        !           272:                return(cc);
        !           273:            return(rem);
        !           274:        } else {
        !           275:            /* re-sealing succeeded, send the private message */
        !           276:            tkt_len = htonl((unsigned long)priv_len);
        !           277:            if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len)))
        !           278:                 != sizeof(tkt_len))
        !           279:                return(cc);
        !           280:            if ((cc = krb_net_write(fd, (char *)tmp_buf, (int) priv_len))
        !           281:                != (int) priv_len)
        !           282:                return(cc);
        !           283:        }
        !           284:     }
        !           285:     return(rem);
        !           286: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.