Line data Source code
1 : /*
2 : * Copyright (c) 1997-2007 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 :
34 : #include "krb5_locl.h"
35 :
36 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
37 63 : krb5_rd_priv(krb5_context context,
38 : krb5_auth_context auth_context,
39 : const krb5_data *inbuf,
40 : krb5_data *outbuf,
41 : krb5_replay_data *outdata)
42 : {
43 : krb5_error_code ret;
44 : KRB_PRIV priv;
45 : EncKrbPrivPart part;
46 : size_t len;
47 : krb5_data plain;
48 : krb5_keyblock *key;
49 : krb5_crypto crypto;
50 :
51 63 : krb5_data_zero(outbuf);
52 :
53 63 : if ((auth_context->flags &
54 : (KRB5_AUTH_CONTEXT_RET_TIME | KRB5_AUTH_CONTEXT_RET_SEQUENCE)))
55 : {
56 0 : if (outdata == NULL) {
57 0 : krb5_clear_error_message (context);
58 0 : return KRB5_RC_REQUIRED; /* XXX better error, MIT returns this */
59 : }
60 : /* if these fields are not present in the priv-part, silently
61 : return zero */
62 0 : memset(outdata, 0, sizeof(*outdata));
63 : }
64 :
65 63 : memset(&priv, 0, sizeof(priv));
66 63 : ret = decode_KRB_PRIV (inbuf->data, inbuf->length, &priv, &len);
67 63 : if (ret) {
68 0 : krb5_clear_error_message (context);
69 0 : goto failure;
70 : }
71 63 : if (priv.pvno != 5) {
72 0 : krb5_clear_error_message (context);
73 0 : ret = KRB5KRB_AP_ERR_BADVERSION;
74 0 : goto failure;
75 : }
76 63 : if (priv.msg_type != krb_priv) {
77 0 : krb5_clear_error_message (context);
78 0 : ret = KRB5KRB_AP_ERR_MSG_TYPE;
79 0 : goto failure;
80 : }
81 :
82 63 : if (auth_context->remote_subkey)
83 32 : key = auth_context->remote_subkey;
84 31 : else if (auth_context->local_subkey)
85 31 : key = auth_context->local_subkey;
86 : else
87 0 : key = auth_context->keyblock;
88 :
89 63 : ret = krb5_crypto_init(context, key, 0, &crypto);
90 63 : if (ret)
91 0 : goto failure;
92 63 : ret = krb5_decrypt_EncryptedData(context,
93 : crypto,
94 : KRB5_KU_KRB_PRIV,
95 : &priv.enc_part,
96 : &plain);
97 63 : krb5_crypto_destroy(context, crypto);
98 63 : if (ret)
99 0 : goto failure;
100 :
101 63 : ret = decode_EncKrbPrivPart (plain.data, plain.length, &part, &len);
102 63 : krb5_data_free (&plain);
103 63 : if (ret) {
104 0 : krb5_clear_error_message (context);
105 0 : goto failure;
106 : }
107 :
108 : /* check sender address */
109 :
110 63 : if (part.s_address
111 63 : && auth_context->remote_address
112 0 : && !krb5_address_compare (context,
113 0 : auth_context->remote_address,
114 0 : part.s_address)) {
115 0 : krb5_clear_error_message (context);
116 0 : ret = KRB5KRB_AP_ERR_BADADDR;
117 0 : goto failure_part;
118 : }
119 :
120 : /* check receiver address */
121 :
122 63 : if (part.r_address
123 0 : && auth_context->local_address
124 0 : && !krb5_address_compare (context,
125 0 : auth_context->local_address,
126 0 : part.r_address)) {
127 0 : krb5_clear_error_message (context);
128 0 : ret = KRB5KRB_AP_ERR_BADADDR;
129 0 : goto failure_part;
130 : }
131 :
132 : /* check timestamp */
133 63 : if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_TIME) {
134 : krb5_timestamp sec;
135 :
136 0 : krb5_timeofday (context, &sec);
137 0 : if (part.timestamp == NULL ||
138 0 : part.usec == NULL ||
139 0 : krb5_time_abs(*part.timestamp, sec) > context->max_skew) {
140 0 : krb5_clear_error_message (context);
141 0 : ret = KRB5KRB_AP_ERR_SKEW;
142 0 : goto failure_part;
143 : }
144 : }
145 :
146 : /* XXX - check replay cache */
147 :
148 : /* check sequence number. since MIT krb5 cannot generate a sequence
149 : number of zero but instead generates no sequence number, we accept that
150 : */
151 :
152 63 : if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) {
153 63 : if ((part.seq_number == NULL
154 1 : && auth_context->remote_seqnumber != 0)
155 63 : || (part.seq_number != NULL
156 62 : && *part.seq_number != auth_context->remote_seqnumber)) {
157 0 : krb5_clear_error_message (context);
158 0 : ret = KRB5KRB_AP_ERR_BADORDER;
159 0 : goto failure_part;
160 : }
161 63 : auth_context->remote_seqnumber++;
162 : }
163 :
164 63 : ret = krb5_data_copy (outbuf, part.user_data.data, part.user_data.length);
165 63 : if (ret)
166 0 : goto failure_part;
167 :
168 63 : if ((auth_context->flags &
169 : (KRB5_AUTH_CONTEXT_RET_TIME | KRB5_AUTH_CONTEXT_RET_SEQUENCE))) {
170 0 : if(part.timestamp)
171 0 : outdata->timestamp = *part.timestamp;
172 0 : if(part.usec)
173 0 : outdata->usec = *part.usec;
174 0 : if(part.seq_number)
175 0 : outdata->seq = *part.seq_number;
176 : }
177 :
178 126 : failure_part:
179 63 : free_EncKrbPrivPart (&part);
180 :
181 63 : failure:
182 63 : free_KRB_PRIV (&priv);
183 63 : return ret;
184 : }
|