Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/heimdal/kdc/process.c
34876 views
1
/*
2
* Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
3
* (Royal Institute of Technology, Stockholm, Sweden).
4
*
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
*
11
* 1. Redistributions of source code must retain the above copyright
12
* notice, this list of conditions and the following disclaimer.
13
*
14
* 2. Redistributions in binary form must reproduce the above copyright
15
* notice, this list of conditions and the following disclaimer in the
16
* documentation and/or other materials provided with the distribution.
17
*
18
* 3. Neither the name of the Institute nor the names of its contributors
19
* may be used to endorse or promote products derived from this software
20
* without specific prior written permission.
21
*
22
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
23
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
26
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32
* SUCH DAMAGE.
33
*/
34
35
#include "kdc_locl.h"
36
37
/*
38
*
39
*/
40
41
void
42
krb5_kdc_update_time(struct timeval *tv)
43
{
44
if (tv == NULL)
45
gettimeofday(&_kdc_now, NULL);
46
else
47
_kdc_now = *tv;
48
}
49
50
static krb5_error_code
51
kdc_as_req(krb5_context context,
52
krb5_kdc_configuration *config,
53
krb5_data *req_buffer,
54
krb5_data *reply,
55
const char *from,
56
struct sockaddr *addr,
57
int datagram_reply,
58
int *claim)
59
{
60
krb5_error_code ret;
61
KDC_REQ req;
62
size_t len;
63
64
ret = decode_AS_REQ(req_buffer->data, req_buffer->length, &req, &len);
65
if (ret)
66
return ret;
67
68
*claim = 1;
69
70
ret = _kdc_as_rep(context, config, &req, req_buffer,
71
reply, from, addr, datagram_reply);
72
free_AS_REQ(&req);
73
return ret;
74
}
75
76
77
static krb5_error_code
78
kdc_tgs_req(krb5_context context,
79
krb5_kdc_configuration *config,
80
krb5_data *req_buffer,
81
krb5_data *reply,
82
const char *from,
83
struct sockaddr *addr,
84
int datagram_reply,
85
int *claim)
86
{
87
krb5_error_code ret;
88
KDC_REQ req;
89
size_t len;
90
91
ret = decode_TGS_REQ(req_buffer->data, req_buffer->length, &req, &len);
92
if (ret)
93
return ret;
94
95
*claim = 1;
96
97
ret = _kdc_tgs_rep(context, config, &req, reply,
98
from, addr, datagram_reply);
99
free_TGS_REQ(&req);
100
return ret;
101
}
102
103
#ifdef DIGEST
104
105
static krb5_error_code
106
kdc_digest(krb5_context context,
107
krb5_kdc_configuration *config,
108
krb5_data *req_buffer,
109
krb5_data *reply,
110
const char *from,
111
struct sockaddr *addr,
112
int datagram_reply,
113
int *claim)
114
{
115
DigestREQ digestreq;
116
krb5_error_code ret;
117
size_t len;
118
119
ret = decode_DigestREQ(req_buffer->data, req_buffer->length,
120
&digestreq, &len);
121
if (ret)
122
return ret;
123
124
*claim = 1;
125
126
ret = _kdc_do_digest(context, config, &digestreq, reply, from, addr);
127
free_DigestREQ(&digestreq);
128
return ret;
129
}
130
131
#endif
132
133
#ifdef KX509
134
135
static krb5_error_code
136
kdc_kx509(krb5_context context,
137
krb5_kdc_configuration *config,
138
krb5_data *req_buffer,
139
krb5_data *reply,
140
const char *from,
141
struct sockaddr *addr,
142
int datagram_reply,
143
int *claim)
144
{
145
Kx509Request kx509req;
146
krb5_error_code ret;
147
size_t len;
148
149
ret = _kdc_try_kx509_request(req_buffer->data, req_buffer->length,
150
&kx509req, &len);
151
if (ret)
152
return ret;
153
154
*claim = 1;
155
156
ret = _kdc_do_kx509(context, config, &kx509req, reply, from, addr);
157
free_Kx509Request(&kx509req);
158
return ret;
159
}
160
161
#endif
162
163
164
static struct krb5_kdc_service services[] = {
165
{ KS_KRB5, kdc_as_req },
166
{ KS_KRB5, kdc_tgs_req },
167
#ifdef DIGEST
168
{ 0, kdc_digest },
169
#endif
170
#ifdef KX509
171
{ 0, kdc_kx509 },
172
#endif
173
{ 0, NULL }
174
};
175
176
/*
177
* handle the request in `buf, len', from `addr' (or `from' as a string),
178
* sending a reply in `reply'.
179
*/
180
181
int
182
krb5_kdc_process_request(krb5_context context,
183
krb5_kdc_configuration *config,
184
unsigned char *buf,
185
size_t len,
186
krb5_data *reply,
187
krb5_boolean *prependlength,
188
const char *from,
189
struct sockaddr *addr,
190
int datagram_reply)
191
{
192
krb5_error_code ret;
193
unsigned int i;
194
krb5_data req_buffer;
195
int claim = 0;
196
197
req_buffer.data = buf;
198
req_buffer.length = len;
199
200
for (i = 0; services[i].process != NULL; i++) {
201
ret = (*services[i].process)(context, config, &req_buffer,
202
reply, from, addr, datagram_reply,
203
&claim);
204
if (claim) {
205
if (services[i].flags & KS_NO_LENGTH)
206
*prependlength = 0;
207
return ret;
208
}
209
}
210
211
return -1;
212
}
213
214
/*
215
* handle the request in `buf, len', from `addr' (or `from' as a string),
216
* sending a reply in `reply'.
217
*
218
* This only processes krb5 requests
219
*/
220
221
int
222
krb5_kdc_process_krb5_request(krb5_context context,
223
krb5_kdc_configuration *config,
224
unsigned char *buf,
225
size_t len,
226
krb5_data *reply,
227
const char *from,
228
struct sockaddr *addr,
229
int datagram_reply)
230
{
231
krb5_error_code ret;
232
unsigned int i;
233
krb5_data req_buffer;
234
int claim = 0;
235
236
req_buffer.data = buf;
237
req_buffer.length = len;
238
239
for (i = 0; services[i].process != NULL; i++) {
240
if ((services[i].flags & KS_KRB5) == 0)
241
continue;
242
ret = (*services[i].process)(context, config, &req_buffer,
243
reply, from, addr, datagram_reply,
244
&claim);
245
if (claim)
246
return ret;
247
}
248
249
return -1;
250
}
251
252
/*
253
*
254
*/
255
256
int
257
krb5_kdc_save_request(krb5_context context,
258
const char *fn,
259
const unsigned char *buf,
260
size_t len,
261
const krb5_data *reply,
262
const struct sockaddr *sa)
263
{
264
krb5_storage *sp;
265
krb5_address a;
266
int fd, ret;
267
uint32_t t;
268
krb5_data d;
269
270
memset(&a, 0, sizeof(a));
271
272
d.data = rk_UNCONST(buf);
273
d.length = len;
274
t = _kdc_now.tv_sec;
275
276
fd = open(fn, O_WRONLY|O_CREAT|O_APPEND, 0600);
277
if (fd < 0) {
278
int saved_errno = errno;
279
krb5_set_error_message(context, saved_errno, "Failed to open: %s", fn);
280
return saved_errno;
281
}
282
283
sp = krb5_storage_from_fd(fd);
284
close(fd);
285
if (sp == NULL) {
286
krb5_set_error_message(context, ENOMEM, "Storage failed to open fd");
287
return ENOMEM;
288
}
289
290
ret = krb5_sockaddr2address(context, sa, &a);
291
if (ret)
292
goto out;
293
294
krb5_store_uint32(sp, 1);
295
krb5_store_uint32(sp, t);
296
krb5_store_address(sp, a);
297
krb5_store_data(sp, d);
298
{
299
Der_class cl;
300
Der_type ty;
301
unsigned int tag;
302
ret = der_get_tag (reply->data, reply->length,
303
&cl, &ty, &tag, NULL);
304
if (ret) {
305
krb5_store_uint32(sp, 0xffffffff);
306
krb5_store_uint32(sp, 0xffffffff);
307
} else {
308
krb5_store_uint32(sp, MAKE_TAG(cl, ty, 0));
309
krb5_store_uint32(sp, tag);
310
}
311
}
312
313
krb5_free_address(context, &a);
314
out:
315
krb5_storage_free(sp);
316
317
return 0;
318
}
319
320