Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / crypto / kerberosIV / lib / krb / sendauth.c
1 /* 
2   Copyright (C) 1989 by the Massachusetts Institute of Technology
3
4    Export of this software from the United States of America is assumed
5    to require a specific license from the United States Government.
6    It is the responsibility of any person or organization contemplating
7    export to obtain such a license before exporting.
8
9 WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
10 distribute this software and its documentation for any purpose and
11 without fee is hereby granted, provided that the above copyright
12 notice appear in all copies and that both that copyright notice and
13 this permission notice appear in supporting documentation, and that
14 the name of M.I.T. not be used in advertising or publicity pertaining
15 to distribution of the software without specific, written prior
16 permission.  M.I.T. makes no representations about the suitability of
17 this software for any purpose.  It is provided "as is" without express
18 or implied warranty.
19
20   */
21 /* $FreeBSD: src/crypto/kerberosIV/lib/krb/sendauth.c,v 1.1.1.3.2.1 2003/02/13 21:34:36 nectar Exp $ */
22 /* $DragonFly: src/crypto/kerberosIV/lib/krb/Attic/sendauth.c,v 1.2 2003/06/17 04:24:36 dillon Exp $ */
23
24 #include "krb_locl.h"
25
26 RCSID("$Id: sendauth.c,v 1.18 1999/09/16 20:41:55 assar Exp $");
27
28 /*
29  * krb_sendauth() transmits a ticket over a file descriptor for a
30  * desired service, instance, and realm, doing mutual authentication
31  * with the server if desired.
32  */
33
34 /*
35  * The first argument to krb_sendauth() contains a bitfield of
36  * options (the options are defined in "krb.h"):
37  *
38  * KOPT_DONT_CANON      Don't canonicalize instance as a hostname.
39  *                      (If this option is not chosen, krb_get_phost()
40  *                      is called to canonicalize it.)
41  *
42  * KOPT_DONT_MK_REQ     Don't request server ticket from Kerberos.
43  *                      A ticket must be supplied in the "ticket"
44  *                      argument.
45  *                      (If this option is not chosen, and there
46  *                      is no ticket for the given server in the
47  *                      ticket cache, one will be fetched using
48  *                      krb_mk_req() and returned in "ticket".)
49  *
50  * KOPT_DO_MUTUAL       Do mutual authentication, requiring that the
51  *                      receiving server return the checksum+1 encrypted
52  *                      in the session key.  The mutual authentication
53  *                      is done using krb_mk_priv() on the other side
54  *                      (see "recvauth.c") and krb_rd_priv() on this
55  *                      side.
56  *
57  * The "fd" argument is a file descriptor to write to the remote
58  * server on.  The "ticket" argument is used to store the new ticket
59  * from the krb_mk_req() call. If the KOPT_DONT_MK_REQ options is
60  * chosen, the ticket must be supplied in the "ticket" argument.
61  * The "service", "inst", and "realm" arguments identify the ticket.
62  * If "realm" is null, the local realm is used.
63  *
64  * The following arguments are only needed if the KOPT_DO_MUTUAL option
65  * is chosen:
66  *
67  *   The "checksum" argument is a number that the server will add 1 to
68  *   to authenticate itself back to the client; the "msg_data" argument
69  *   holds the returned mutual-authentication message from the server
70  *   (i.e., the checksum+1); the "cred" structure is used to hold the
71  *   session key of the server, extracted from the ticket file, for use
72  *   in decrypting the mutual authentication message from the server;
73  *   and "schedule" holds the key schedule for that decryption.  The
74  *   the local and server addresses are given in "laddr" and "faddr".
75  *
76  * The application protocol version number (of up to KRB_SENDAUTH_VLEN
77  * characters) is passed in "version".
78  *
79  * If all goes well, KSUCCESS is returned, otherwise some error code.
80  *
81  * The format of the message sent to the server is:
82  *
83  * Size                 Variable                Field
84  * ----                 --------                -----
85  *
86  * KRB_SENDAUTH_VLEN    KRB_SENDAUTH_VER        sendauth protocol
87  * bytes                                        version number
88  *
89  * KRB_SENDAUTH_VLEN    version                 application protocol
90  * bytes                                        version number
91  *
92  * 4 bytes              ticket->length          length of ticket
93  *
94  * ticket->length       ticket->dat             ticket itself
95  */
96
97 int
98 krb_sendauth(int32_t options,   /* bit-pattern of options */
99              int fd,            /* file descriptor to write onto */
100              KTEXT ticket,      /* where to put ticket (return); or
101                                  * supplied in case of KOPT_DONT_MK_REQ */
102              char *service,     /* service name, instance, realm */
103              char *instance,
104              char *realm,
105              u_int32_t checksum, /* checksum to include in request */
106              MSG_DAT *msg_data, /* mutual auth MSG_DAT (return) */
107              CREDENTIALS *cred, /* credentials (return) */
108              des_key_schedule schedule, /* key schedule (return) */
109              struct sockaddr_in *laddr, /* local address */
110              struct sockaddr_in *faddr, /* address of foreign host on fd */
111              char *version)     /* version string */
112 {
113     int ret;
114     KTEXT_ST buf;
115     char realrealm[REALM_SZ];
116
117     if (realm == NULL) {
118         ret = krb_get_lrealm (realrealm, 1);
119         if (ret != KSUCCESS)
120             return ret;
121         realm = realrealm;
122     }
123     ret = krb_mk_auth (options, ticket, service, instance, realm, checksum,
124                        version, &buf);
125     if (ret != KSUCCESS)
126         return ret;
127     ret = krb_net_write(fd, buf.dat, buf.length);
128     if(ret < 0)
129         return -1;
130       
131     if (options & KOPT_DO_MUTUAL) {
132         char tmp[4];
133         u_int32_t len;
134         char inst[INST_SZ];
135         char *i;
136
137         ret = krb_net_read (fd, tmp, 4);
138         if (ret < 0)
139             return -1;
140
141         krb_get_int (tmp, &len, 4, 0);
142         if (len == 0xFFFFFFFF || len > sizeof(buf.dat))
143             return KFAILURE;
144         buf.length = len;
145         ret = krb_net_read (fd, buf.dat, len);
146         if (ret < 0)
147             return -1;
148
149         if (options & KOPT_DONT_CANON)
150             i = instance;
151         else
152             i = krb_get_phost(instance);
153         strlcpy (inst, i, sizeof(inst));
154
155         ret = krb_get_cred (service, inst, realm, cred);
156         if (ret != KSUCCESS)
157             return ret;
158
159         des_key_sched(&cred->session, schedule);
160
161         ret = krb_check_auth (&buf, checksum, msg_data, &cred->session, 
162                               schedule, laddr, faddr);
163         if (ret != KSUCCESS)
164             return ret;
165     }
166     return KSUCCESS;
167 }