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 89 : 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 0 : krb5_error_code ret;
44 0 : KRB_PRIV priv;
45 0 : EncKrbPrivPart part;
46 0 : size_t len;
47 0 : krb5_data plain;
48 0 : krb5_keyblock *key;
49 0 : krb5_crypto crypto;
50 :
51 89 : krb5_data_zero(outbuf);
52 :
53 89 : 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 89 : memset(&priv, 0, sizeof(priv));
66 89 : ret = decode_KRB_PRIV (inbuf->data, inbuf->length, &priv, &len);
67 89 : if (ret) {
68 0 : krb5_clear_error_message (context);
69 0 : goto failure;
70 : }
71 89 : if (priv.pvno != 5) {
72 0 : krb5_clear_error_message (context);
73 0 : ret = KRB5KRB_AP_ERR_BADVERSION;
74 0 : goto failure;
75 : }
76 89 : 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 89 : if (auth_context->remote_subkey)
83 60 : key = auth_context->remote_subkey;
84 29 : else if (auth_context->local_subkey)
85 29 : key = auth_context->local_subkey;
86 : else
87 0 : key = auth_context->keyblock;
88 :
89 89 : ret = krb5_crypto_init(context, key, 0, &crypto);
90 89 : if (ret)
91 0 : goto failure;
92 89 : ret = krb5_decrypt_EncryptedData(context,
93 : crypto,
94 : KRB5_KU_KRB_PRIV,
95 : &priv.enc_part,
96 : &plain);
97 89 : krb5_crypto_destroy(context, crypto);
98 89 : if (ret)
99 0 : goto failure;
100 :
101 89 : ret = decode_EncKrbPrivPart (plain.data, plain.length, &part, &len);
102 89 : krb5_data_free (&plain);
103 89 : if (ret) {
104 0 : krb5_clear_error_message (context);
105 0 : goto failure;
106 : }
107 :
108 : /* check sender address */
109 :
110 89 : if (part.s_address
111 89 : && 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 89 : 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 89 : if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_TIME) {
134 0 : 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 89 : if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) {
153 89 : if ((part.seq_number == NULL
154 3 : && auth_context->remote_seqnumber != 0)
155 87 : || (part.seq_number != NULL
156 86 : && *part.seq_number != auth_context->remote_seqnumber)) {
157 2 : krb5_clear_error_message (context);
158 2 : ret = KRB5KRB_AP_ERR_BADORDER;
159 2 : goto failure_part;
160 : }
161 87 : auth_context->remote_seqnumber++;
162 : }
163 :
164 87 : ret = krb5_data_copy (outbuf, part.user_data.data, part.user_data.length);
165 87 : if (ret)
166 0 : goto failure_part;
167 :
168 87 : 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 87 : failure_part:
179 89 : free_EncKrbPrivPart (&part);
180 :
181 89 : failure:
182 89 : free_KRB_PRIV (&priv);
183 89 : return ret;
184 : }
|