1 /* 2 * Copyright 2006 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 #pragma ident "%Z%%M% %I% %E% SMI" 35 36 #define NEED_SOCKETS 37 #include "k5-int.h" 38 #include <syslog.h> 39 #include "kdc_util.h" 40 #include "extern.h" 41 #include "adm_proto.h" 42 #include <netinet/in.h> 43 #include <arpa/inet.h> 44 #include <string.h> 45 46 extern krb5_error_code setup_server_realm(krb5_principal); 47 static krb5_int32 last_usec = 0, last_os_random = 0; 48 49 krb5_error_code 50 dispatch(krb5_data *pkt, const krb5_fulladdr *from, krb5_data **response) 51 { 52 53 krb5_error_code retval; 54 krb5_kdc_req *as_req; 55 krb5_int32 now, now_usec; 56 57 /* decode incoming packet, and dispatch */ 58 59 #ifndef NOCACHE 60 /* try the replay lookaside buffer */ 61 if (kdc_check_lookaside(pkt, from, response)) { 62 /* a hit! */ 63 const char *name = 0; 64 char buf[46]; 65 66 name = (char *) inet_ntop (ADDRTYPE2FAMILY (from->address->addrtype), 67 from->address->contents, buf, sizeof (buf)); 68 if (name == 0) 69 name = "[unknown address type]"; 70 krb5_klog_syslog(LOG_INFO, 71 "DISPATCH: repeated (retransmitted?) request from %s, resending previous response", 72 name); 73 return 0; 74 } 75 #endif 76 /* SUNW14resync XXX */ 77 #if 0 78 retval = krb5_crypto_us_timeofday(&now, &now_usec); 79 if (retval == 0) { 80 krb5_int32 usec_difference = now_usec-last_usec; 81 krb5_data data; 82 if(last_os_random == 0) 83 last_os_random = now; 84 /* Grab random data from OS every hour*/ 85 if(now-last_os_random >= 60*60) { 86 krb5_c_random_os_entropy(kdc_context, 0, NULL); 87 last_os_random = now; 88 } 89 90 data.length = sizeof(krb5_int32); 91 data.data = (void *) &usec_difference; 92 93 krb5_c_random_add_entropy(kdc_context, 94 KRB5_C_RANDSOURCE_TIMING, &data); 95 last_usec = now_usec; 96 } 97 #endif 98 /* try TGS_REQ first; they are more common! */ 99 100 if (krb5_is_tgs_req(pkt)) { 101 retval = process_tgs_req(pkt, from, response); 102 } else if (krb5_is_as_req(pkt)) { 103 if (!(retval = decode_krb5_as_req(pkt, &as_req))) { 104 /* 105 * setup_server_realm() sets up the global realm-specific data 106 * pointer. 107 */ 108 if (!(retval = setup_server_realm(as_req->server))) { 109 retval = process_as_req(as_req, from, response); 110 } 111 krb5_free_kdc_req(kdc_context, as_req); 112 } 113 } 114 #ifdef KRB5_KRB4_COMPAT 115 else if (pkt->data[0] == 4) /* old version */ 116 retval = process_v4(pkt, from, response); 117 #endif 118 else 119 retval = KRB5KRB_AP_ERR_MSG_TYPE; 120 #ifndef NOCACHE 121 /* put the response into the lookaside buffer */ 122 if (!retval) 123 kdc_insert_lookaside(pkt, from, *response); 124 #endif 125 126 return retval; 127 } 128