Annotation of 43BSDReno/kerberosIV/krb/sendauth.c, revision 1.1.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.