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

1.1     ! root        1: /*
        !             2:  * $Source: /usr/src/kerberosIV/krb/RCS/sendauth.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: 
        !            12: #ifndef        lint
        !            13: static char rcsid_sendauth_c[] =
        !            14: "$Header: /usr/src/kerberosIV/krb/RCS/sendauth.c,v 4.5 90/06/25 20:57:24 kfall Exp $";
        !            15: #endif lint
        !            16: 
        !            17: #include <mit-copyright.h>
        !            18: 
        !            19: #include <des.h>
        !            20: #include <krb.h>
        !            21: #include <sys/types.h>
        !            22: #include <netinet/in.h>
        !            23: #include <syslog.h>
        !            24: #include <errno.h>
        !            25: #include <stdio.h>
        !            26: #include <strings.h>
        !            27: 
        !            28: #define        KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN chars */
        !            29: /*
        !            30:  * If the protocol changes, you will need to change the version string
        !            31:  * and make appropriate changes in krb_recvauth.c
        !            32:  */
        !            33: 
        !            34: extern int errno;
        !            35: 
        !            36: extern char *krb_get_phost();
        !            37: 
        !            38: /*
        !            39:  * This file contains two routines: krb_sendauth() and krb_sendsrv().
        !            40:  *
        !            41:  * krb_sendauth() transmits a ticket over a file descriptor for a
        !            42:  * desired service, instance, and realm, doing mutual authentication
        !            43:  * with the server if desired.
        !            44:  *
        !            45:  * krb_sendsvc() sends a service name to a remote knetd server.
        !            46:  */
        !            47: 
        !            48: /*
        !            49:  * The first argument to krb_sendauth() contains a bitfield of
        !            50:  * options (the options are defined in "krb.h"):
        !            51:  *
        !            52:  * KOPT_DONT_CANON     Don't canonicalize instance as a hostname.
        !            53:  *                     (If this option is not chosen, krb_get_phost()
        !            54:  *                     is called to canonicalize it.)
        !            55:  *
        !            56:  * KOPT_DONT_MK_REQ    Don't request server ticket from Kerberos.
        !            57:  *                     A ticket must be supplied in the "ticket"
        !            58:  *                     argument.
        !            59:  *                     (If this option is not chosen, and there
        !            60:  *                     is no ticket for the given server in the
        !            61:  *                     ticket cache, one will be fetched using
        !            62:  *                     krb_mk_req() and returned in "ticket".)
        !            63:  *
        !            64:  * KOPT_DO_MUTUAL      Do mutual authentication, requiring that the
        !            65:  *                     receiving server return the checksum+1 encrypted
        !            66:  *                     in the session key.  The mutual authentication
        !            67:  *                     is done using krb_mk_priv() on the other side
        !            68:  *                     (see "recvauth.c") and krb_rd_priv() on this
        !            69:  *                     side.
        !            70:  *
        !            71:  * The "fd" argument is a file descriptor to write to the remote
        !            72:  * server on.  The "ticket" argument is used to store the new ticket
        !            73:  * from the krb_mk_req() call. If the KOPT_DONT_MK_REQ options is
        !            74:  * chosen, the ticket must be supplied in the "ticket" argument.
        !            75:  * The "service", "inst", and "realm" arguments identify the ticket.
        !            76:  * If "realm" is null, the local realm is used.
        !            77:  *
        !            78:  * The following arguments are only needed if the KOPT_DO_MUTUAL option
        !            79:  * is chosen:
        !            80:  *
        !            81:  *   The "checksum" argument is a number that the server will add 1 to
        !            82:  *   to authenticate itself back to the client; the "msg_data" argument
        !            83:  *   holds the returned mutual-authentication message from the server
        !            84:  *   (i.e., the checksum+1); the "cred" structure is used to hold the
        !            85:  *   session key of the server, extracted from the ticket file, for use
        !            86:  *   in decrypting the mutual authentication message from the server;
        !            87:  *   and "schedule" holds the key schedule for that decryption.  The
        !            88:  *   the local and server addresses are given in "laddr" and "faddr".
        !            89:  *
        !            90:  * The application protocol version number (of up to KRB_SENDAUTH_VLEN
        !            91:  * characters) is passed in "version".
        !            92:  *
        !            93:  * If all goes well, KSUCCESS is returned, otherwise some error code.
        !            94:  *
        !            95:  * The format of the message sent to the server is:
        !            96:  *
        !            97:  * Size                        Variable                Field
        !            98:  * ----                        --------                -----
        !            99:  *
        !           100:  * KRB_SENDAUTH_VLEN   KRB_SENDAUTH_VER        sendauth protocol
        !           101:  * bytes                                       version number
        !           102:  *
        !           103:  * KRB_SENDAUTH_VLEN   version                 application protocol
        !           104:  * bytes                                       version number
        !           105:  *
        !           106:  * 4 bytes             ticket->length          length of ticket
        !           107:  *
        !           108:  * ticket->length      ticket->dat             ticket itself
        !           109:  */
        !           110: 
        !           111: /*
        !           112:  * XXX: Note that krb_rd_priv() is coded in such a way that
        !           113:  * "msg_data->app_data" will be pointing into "priv_buf", which
        !           114:  * will disappear when krb_sendauth() returns.
        !           115:  */
        !           116: 
        !           117: int
        !           118: krb_sendauth(options, fd, ticket, service, inst, realm, checksum,
        !           119:        msg_data, cred, schedule, laddr, faddr, version)
        !           120: long options;                   /* bit-pattern of options */
        !           121: int fd;                                 /* file descriptor to write onto */
        !           122: KTEXT ticket;                   /* where to put ticket (return); or
        !           123:                                  * supplied in case of KOPT_DONT_MK_REQ */
        !           124: char *service, *inst, *realm;   /* service name, instance, realm */
        !           125: u_long checksum;                /* checksum to include in request */
        !           126: MSG_DAT *msg_data;              /* mutual auth MSG_DAT (return) */
        !           127: CREDENTIALS *cred;              /* credentials (return) */
        !           128: Key_schedule schedule;          /* key schedule (return) */
        !           129: struct sockaddr_in *laddr;      /* local address */
        !           130: struct sockaddr_in *faddr;      /* address of foreign host on fd */
        !           131: char *version;                  /* version string */
        !           132: {
        !           133:     int rem, i, cc;
        !           134:     char srv_inst[INST_SZ];
        !           135:     char krb_realm[REALM_SZ];
        !           136:     char buf[BUFSIZ];
        !           137:     long tkt_len;
        !           138:     u_char priv_buf[1024];
        !           139:     u_long cksum;
        !           140: 
        !           141:     rem=KSUCCESS;
        !           142: 
        !           143:     /* get current realm if not passed in */
        !           144:     if (!realm) {
        !           145:        rem = krb_get_lrealm(krb_realm,1);
        !           146:        if (rem != KSUCCESS)
        !           147:            return(rem);
        !           148:        realm = krb_realm;
        !           149:     }
        !           150: 
        !           151:     /* copy instance into local storage, canonicalizing if desired */
        !           152:     if (options & KOPT_DONT_CANON)
        !           153:        (void) strncpy(srv_inst, inst, INST_SZ);
        !           154:     else
        !           155:        (void) strncpy(srv_inst, krb_get_phost(inst), INST_SZ);
        !           156: 
        !           157:     /* get the ticket if desired */
        !           158:     if (!(options & KOPT_DONT_MK_REQ)) {
        !           159:        rem = krb_mk_req(ticket, service, srv_inst, realm, checksum);
        !           160:        if (rem != KSUCCESS)
        !           161:            return(rem);
        !           162:     }
        !           163: 
        !           164: #ifdef ATHENA_COMPAT
        !           165:     /* this is only for compatibility with old servers */
        !           166:     if (options & KOPT_DO_OLDSTYLE) {
        !           167:        (void) sprintf(buf,"%d ",ticket->length);
        !           168:        (void) write(fd, buf, strlen(buf));
        !           169:        (void) write(fd, (char *) ticket->dat, ticket->length);
        !           170:        return(rem);
        !           171:     }
        !           172: #endif ATHENA_COMPAT
        !           173:     /* if mutual auth, get credentials so we have service session
        !           174:        keys for decryption below */
        !           175:     if (options & KOPT_DO_MUTUAL)
        !           176:        if (cc = krb_get_cred(service, srv_inst, realm, cred))
        !           177:            return(cc);
        !           178: 
        !           179:     /* zero the buffer */
        !           180:     (void) bzero(buf, BUFSIZ);
        !           181: 
        !           182:     /* insert version strings */
        !           183:     (void) strncpy(buf, KRB_SENDAUTH_VERS, KRB_SENDAUTH_VLEN);
        !           184:     (void) strncpy(buf+KRB_SENDAUTH_VLEN, version, KRB_SENDAUTH_VLEN);
        !           185: 
        !           186:     /* increment past vers strings */
        !           187:     i = 2*KRB_SENDAUTH_VLEN;
        !           188: 
        !           189:     /* put ticket length into buffer */
        !           190:     tkt_len = htonl((unsigned long) ticket->length);
        !           191:     (void) bcopy((char *) &tkt_len, buf+i, sizeof(tkt_len));
        !           192:     i += sizeof(tkt_len);
        !           193: 
        !           194:     /* put ticket into buffer */
        !           195:     (void) bcopy((char *) ticket->dat, buf+i, ticket->length);
        !           196:     i += ticket->length;
        !           197: 
        !           198:     /* write the request to the server */
        !           199:     if ((cc = krb_net_write(fd, buf, i)) != i)
        !           200:        return(cc);
        !           201: 
        !           202:     /* mutual authentication, if desired */
        !           203:     if (options & KOPT_DO_MUTUAL) {
        !           204:        /* get the length of the reply */
        !           205:        if (krb_net_read(fd, (char *) &tkt_len, sizeof(tkt_len)) !=
        !           206:            sizeof(tkt_len))
        !           207:            return(errno);
        !           208:        tkt_len = ntohl((unsigned long)tkt_len);
        !           209: 
        !           210:        /* if the length is negative, the server failed to recognize us. */
        !           211:        if (tkt_len < 0)
        !           212:            return(KFAILURE);    /* XXX */
        !           213:        /* read the reply... */
        !           214:        if (krb_net_read(fd, (char *)priv_buf, (int) tkt_len) != (int) tkt_len)
        !           215:            return(errno);
        !           216: 
        !           217:        /* ...and decrypt it */
        !           218: #ifndef NOENCRYPTION
        !           219:        key_sched(cred->session, schedule);
        !           220: #endif /* !NOENCRYPTION */
        !           221:        if (cc = krb_rd_priv(priv_buf,(unsigned long) tkt_len, schedule,
        !           222:                             cred->session, faddr, laddr, msg_data))
        !           223:            return(cc);
        !           224: 
        !           225:        /* fetch the (modified) checksum */
        !           226:        (void) bcopy((char *)msg_data->app_data, (char *)&cksum,
        !           227:                     sizeof(cksum));
        !           228:        cksum = ntohl(cksum);
        !           229: 
        !           230:        /* if it doesn't match, fail */
        !           231:        if (cksum != checksum + 1)
        !           232:            return(KFAILURE);    /* XXX */
        !           233:     }
        !           234:     return(KSUCCESS);
        !           235: }
        !           236: 
        !           237: #ifdef ATHENA_COMPAT
        !           238: /*
        !           239:  * krb_sendsvc
        !           240:  */
        !           241: 
        !           242: int
        !           243: krb_sendsvc(fd, service)
        !           244: int fd;
        !           245: char *service;
        !           246: {
        !           247:     /* write the service name length and then the service name to
        !           248:        the fd */
        !           249:     long serv_length;
        !           250:     int cc;
        !           251: 
        !           252:     serv_length = htonl((unsigned long)strlen(service));
        !           253:     if ((cc = krb_net_write(fd, (char *) &serv_length,
        !           254:        sizeof(serv_length)))
        !           255:        != sizeof(serv_length))
        !           256:        return(cc);
        !           257:     if ((cc = krb_net_write(fd, service, strlen(service)))
        !           258:        != strlen(service))
        !           259:        return(cc);
        !           260:     return(KSUCCESS);
        !           261: }
        !           262: #endif ATHENA_COMPAT

unix.superglobalmegacorp.com

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