Initial import from FreeBSD RELENG_4:
[dragonfly.git] / crypto / kerberosIV / lib / krb / rd_priv.c
1 /*
2  * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
3  * (Royal Institute of Technology, Stockholm, Sweden).
4  * All rights reserved.
5  * 
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 
17  * 3. Neither the name of the Institute nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  * 
21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 /* $FreeBSD: src/crypto/kerberosIV/lib/krb/rd_priv.c,v 1.1.1.3.2.1 2003/02/13 21:34:36 nectar Exp $ */
34
35 #include "krb_locl.h"
36
37 RCSID("$Id: rd_priv.c,v 1.27 1999/12/02 16:58:43 joda Exp $");
38
39 /* application include files */
40 #include "krb-archaeology.h"
41
42 /*
43  * krb_rd_priv() decrypts and checks the integrity of an
44  * AUTH_MSG_PRIVATE message.  Given the message received, "in",
45  * the length of that message, "in_length", the key "schedule"
46  * and "key", and the network addresses of the
47  * "sender" and "receiver" of the message, krb_rd_safe() returns
48  * RD_AP_OK if the message is okay, otherwise some error code.
49  *
50  * The message data retrieved from "in" are returned in the structure
51  * "m_data".  The pointer to the application data
52  * (m_data->app_data) refers back to the appropriate place in "in".
53  *
54  * See the file "mk_priv.c" for the format of the AUTH_MSG_PRIVATE
55  * message.  The structure containing the extracted message
56  * information, MSG_DAT, is defined in "krb.h".
57  */
58
59 int32_t
60 krb_rd_priv(void *in, u_int32_t in_length, 
61             des_key_schedule schedule, des_cblock *key, 
62             struct sockaddr_in *sender, struct sockaddr_in *receiver, 
63             MSG_DAT *m_data)
64 {
65     unsigned char *p = (unsigned char*)in;
66     int little_endian;
67     u_int32_t clen;
68     struct timeval tv;
69     u_int32_t src_addr;
70     int delta_t;
71
72     unsigned char pvno, type;
73
74     pvno = *p++;
75     if(pvno != KRB_PROT_VERSION)
76         return RD_AP_VERSION;
77     
78     type = *p++;
79     little_endian = type & 1;
80     type &= ~1;
81
82     p += krb_get_int(p, &clen, 4, little_endian);
83     
84     if(clen + 2 > in_length)
85         return RD_AP_MODIFIED;
86
87     des_pcbc_encrypt((des_cblock*)p, (des_cblock*)p, clen, 
88                      schedule, key, DES_DECRYPT);
89     
90     p += krb_get_int(p, &m_data->app_length, 4, little_endian);
91     if(m_data->app_length + 17 > in_length)
92         return RD_AP_MODIFIED;
93
94     m_data->app_data = p;
95     p += m_data->app_length;
96     
97     m_data->time_5ms = *p++;
98
99     p += krb_get_address(p, &src_addr);
100
101     if (!krb_equiv(src_addr, sender->sin_addr.s_addr))
102         return RD_AP_BADD;
103
104     p += krb_get_int(p, (u_int32_t *)&m_data->time_sec, 4, little_endian);
105
106     m_data->time_sec = lsb_time(m_data->time_sec, sender, receiver);
107     
108     gettimeofday(&tv, NULL);
109
110     /* check the time integrity of the msg */
111     delta_t = abs((int)((long) tv.tv_sec - m_data->time_sec));
112     if (delta_t > CLOCK_SKEW)
113         return RD_AP_TIME;
114     if (krb_debug)
115         krb_warning("delta_t = %d\n", (int) delta_t);
116
117     /*
118      * caller must check timestamps for proper order and
119      * replays, since server might have multiple clients
120      * each with its own timestamps and we don't assume
121      * tightly synchronized clocks.
122      */
123
124     return KSUCCESS;
125 }