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