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 RCSID("$Id: process.c 20959 2007-06-07 04:46:06Z lha $"); 38 39 /* 40 * 41 */ 42 43 void 44 krb5_kdc_update_time(struct timeval *tv) 45 { 46 if (tv == NULL) 47 gettimeofday(&_kdc_now, NULL); 48 else 49 _kdc_now = *tv; 50 } 51 52 /* 53 * handle the request in `buf, len', from `addr' (or `from' as a string), 54 * sending a reply in `reply'. 55 */ 56 57 int 58 krb5_kdc_process_request(krb5_context context, 59 krb5_kdc_configuration *config, 60 unsigned char *buf, 61 size_t len, 62 krb5_data *reply, 63 krb5_boolean *prependlength, 64 const char *from, 65 struct sockaddr *addr, 66 int datagram_reply) 67 { 68 KDC_REQ req; 69 Ticket ticket; 70 DigestREQ digestreq; 71 Kx509Request kx509req; 72 krb5_error_code ret; 73 size_t i; 74 75 if(decode_AS_REQ(buf, len, &req, &i) == 0){ 76 krb5_data req_buffer; 77 78 req_buffer.data = buf; 79 req_buffer.length = len; 80 81 ret = _kdc_as_rep(context, config, &req, &req_buffer, 82 reply, from, addr, datagram_reply); 83 free_AS_REQ(&req); 84 return ret; 85 }else if(decode_TGS_REQ(buf, len, &req, &i) == 0){ 86 ret = _kdc_tgs_rep(context, config, &req, reply, from, addr, datagram_reply); 87 free_TGS_REQ(&req); 88 return ret; 89 }else if(decode_Ticket(buf, len, &ticket, &i) == 0){ 90 ret = _kdc_do_524(context, config, &ticket, reply, from, addr); 91 free_Ticket(&ticket); 92 return ret; 93 }else if(decode_DigestREQ(buf, len, &digestreq, &i) == 0){ 94 ret = _kdc_do_digest(context, config, &digestreq, reply, from, addr); 95 free_DigestREQ(&digestreq); 96 return ret; 97 } else if (_kdc_try_kx509_request(buf, len, &kx509req, &i) == 0) { 98 ret = _kdc_do_kx509(context, config, &kx509req, reply, from, addr); 99 free_Kx509Request(&kx509req); 100 return ret; 101 } else if(_kdc_maybe_version4(buf, len)){ 102 *prependlength = FALSE; /* elbitapmoc sdrawkcab XXX */ 103 _kdc_do_version4(context, config, buf, len, reply, from, 104 (struct sockaddr_in*)addr); 105 return 0; 106 } else if (config->enable_kaserver) { 107 ret = _kdc_do_kaserver(context, config, buf, len, reply, from, 108 (struct sockaddr_in*)addr); 109 return ret; 110 } 111 112 return -1; 113 } 114 115 /* 116 * handle the request in `buf, len', from `addr' (or `from' as a string), 117 * sending a reply in `reply'. 118 * 119 * This only processes krb5 requests 120 */ 121 122 int 123 krb5_kdc_process_krb5_request(krb5_context context, 124 krb5_kdc_configuration *config, 125 unsigned char *buf, 126 size_t len, 127 krb5_data *reply, 128 const char *from, 129 struct sockaddr *addr, 130 int datagram_reply) 131 { 132 KDC_REQ req; 133 krb5_error_code ret; 134 size_t i; 135 136 if(decode_AS_REQ(buf, len, &req, &i) == 0){ 137 krb5_data req_buffer; 138 139 req_buffer.data = buf; 140 req_buffer.length = len; 141 142 ret = _kdc_as_rep(context, config, &req, &req_buffer, 143 reply, from, addr, datagram_reply); 144 free_AS_REQ(&req); 145 return ret; 146 }else if(decode_TGS_REQ(buf, len, &req, &i) == 0){ 147 ret = _kdc_tgs_rep(context, config, &req, reply, from, addr, datagram_reply); 148 free_TGS_REQ(&req); 149 return ret; 150 } 151 return -1; 152 } 153 154 /* 155 * 156 */ 157 158 int 159 krb5_kdc_save_request(krb5_context context, 160 const char *fn, 161 const unsigned char *buf, 162 size_t len, 163 const krb5_data *reply, 164 const struct sockaddr *sa) 165 { 166 krb5_storage *sp; 167 krb5_address a; 168 int fd, ret; 169 uint32_t t; 170 krb5_data d; 171 172 memset(&a, 0, sizeof(a)); 173 174 d.data = rk_UNCONST(buf); 175 d.length = len; 176 t = _kdc_now.tv_sec; 177 178 fd = open(fn, O_WRONLY|O_CREAT|O_APPEND, 0600); 179 if (fd < 0) { 180 krb5_set_error_string(context, "Failed to open: %s", fn); 181 return errno; 182 } 183 184 sp = krb5_storage_from_fd(fd); 185 close(fd); 186 if (sp == NULL) { 187 krb5_set_error_string(context, "Storage failed to open fd"); 188 return ENOMEM; 189 } 190 191 ret = krb5_sockaddr2address(context, sa, &a); 192 if (ret) 193 goto out; 194 195 krb5_store_uint32(sp, 1); 196 krb5_store_uint32(sp, t); 197 krb5_store_address(sp, a); 198 krb5_store_data(sp, d); 199 { 200 Der_class cl; 201 Der_type ty; 202 unsigned int tag; 203 ret = der_get_tag (reply->data, reply->length, 204 &cl, &ty, &tag, NULL); 205 if (ret) { 206 krb5_store_uint32(sp, 0xffffffff); 207 krb5_store_uint32(sp, 0xffffffff); 208 } else { 209 krb5_store_uint32(sp, MAKE_TAG(cl, ty, 0)); 210 krb5_store_uint32(sp, tag); 211 } 212 } 213 214 krb5_free_address(context, &a); 215 out: 216 krb5_storage_free(sp); 217 218 return 0; 219 } 220