1 /*
2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 /*
7 * kdc/dispatch.c
8 *
9 * Copyright 1990 by the Massachusetts Institute of Technology.
10 *
11 * Export of this software from the United States of America may
12 * require a specific license from the United States Government.
13 * It is the responsibility of any person or organization contemplating
14 * export to obtain such a license before exporting.
15 *
16 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
17 * distribute this software and its documentation for any purpose and
18 * without fee is hereby granted, provided that the above copyright
19 * notice appear in all copies and that both that copyright notice and
20 * this permission notice appear in supporting documentation, and that
21 * the name of M.I.T. not be used in advertising or publicity pertaining
22 * to distribution of the software without specific, written prior
23 * permission. Furthermore if you modify this software you must label
24 * your software as modified software and not distribute it in such a
25 * fashion that it might be confused with the original M.I.T. software.
26 * M.I.T. makes no representations about the suitability of
27 * this software for any purpose. It is provided "as is" without express
28 * or implied warranty.
29 *
30 *
31 * Dispatch an incoming packet.
32 */
33
34
35 #include "k5-int.h"
36 #include <syslog.h>
37 #include "kdc_util.h"
38 #include "extern.h"
39 #include "adm_proto.h"
40 #include <netinet/in.h>
41 #include <arpa/inet.h>
42 #include <string.h>
43
44 static krb5_int32 last_usec = 0, last_os_random = 0;
45
46 krb5_error_code
dispatch(krb5_data * pkt,const krb5_fulladdr * from,krb5_data ** response)47 dispatch(krb5_data *pkt, const krb5_fulladdr *from, krb5_data **response)
48 {
49
50 krb5_error_code retval;
51 krb5_kdc_req *as_req;
52 krb5_int32 now, now_usec;
53
54 /* decode incoming packet, and dispatch */
55
56 #ifndef NOCACHE
57 /* try the replay lookaside buffer */
58 if (kdc_check_lookaside(pkt, response)) {
59 /* a hit! */
60 const char *name = 0;
61 char buf[46];
62
63 name = (char *) inet_ntop (ADDRTYPE2FAMILY (from->address->addrtype),
64 from->address->contents, buf, sizeof (buf));
65 if (name == 0)
66 name = "[unknown address type]";
67 krb5_klog_syslog(LOG_INFO,
68 "DISPATCH: repeated (retransmitted?) request from %s, resending previous response",
69 name);
70 return 0;
71 }
72 #endif
73 /* SUNW14resync XXX */
74 #if 0
75 retval = krb5_crypto_us_timeofday(&now, &now_usec);
76 if (retval == 0) {
77 krb5_int32 usec_difference = now_usec-last_usec;
78 krb5_data data;
79 if(last_os_random == 0)
80 last_os_random = now;
81 /* Grab random data from OS every hour*/
82 if(now-last_os_random >= 60*60) {
83 krb5_c_random_os_entropy(kdc_context, 0, NULL);
84 last_os_random = now;
85 }
86
87 data.length = sizeof(krb5_int32);
88 data.data = (void *) &usec_difference;
89
90 krb5_c_random_add_entropy(kdc_context,
91 KRB5_C_RANDSOURCE_TIMING, &data);
92 last_usec = now_usec;
93 }
94 #endif
95 /* try TGS_REQ first; they are more common! */
96
97 if (krb5_is_tgs_req(pkt)) {
98 retval = process_tgs_req(pkt, from, response);
99 } else if (krb5_is_as_req(pkt)) {
100 if (!(retval = decode_krb5_as_req(pkt, &as_req))) {
101 /*
102 * setup_server_realm() sets up the global realm-specific data
103 * pointer.
104 */
105 if (!(retval = setup_server_realm(as_req->server))) {
106 retval = process_as_req(as_req, pkt, from, response);
107 }
108 krb5_free_kdc_req(kdc_context, as_req);
109 }
110 }
111 #ifdef KRB5_KRB4_COMPAT
112 else if (pkt->data[0] == 4) /* old version */
113 retval = process_v4(pkt, from, response);
114 #endif
115 else
116 retval = KRB5KRB_AP_ERR_MSG_TYPE;
117 #ifndef NOCACHE
118 /* put the response into the lookaside buffer */
119 if (!retval)
120 kdc_insert_lookaside(pkt, *response);
121 #endif
122
123 return retval;
124 }
125