marshall.c revision 1.2
1/* $NetBSD: marshall.c,v 1.2 2017/01/28 21:31:49 christos Exp $ */ 2 3/* 4 * Copyright (c) 1997 - 1999 Kungliga Tekniska H��gskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36#include "kadm5_locl.h" 37 38__RCSID("$NetBSD: marshall.c,v 1.2 2017/01/28 21:31:49 christos Exp $"); 39 40int 41kadm5_some_keys_are_bogus(size_t n_keys, krb5_key_data *keys) 42{ 43 size_t i; 44 45 for (i = 0; i < n_keys; i++) { 46 krb5_key_data *key = &keys[i]; 47 if (key->key_data_length[0] == sizeof(KADM5_BOGUS_KEY_DATA) - 1 && 48 ct_memcmp(key->key_data_contents[1], KADM5_BOGUS_KEY_DATA, 49 key->key_data_length[0]) == 0) 50 return 1; 51 } 52 return 0; 53} 54 55int 56kadm5_all_keys_are_bogus(size_t n_keys, krb5_key_data *keys) 57{ 58 size_t i; 59 60 if (n_keys == 0) 61 return 0; 62 63 for (i = 0; i < n_keys; i++) { 64 krb5_key_data *key = &keys[i]; 65 if (key->key_data_length[0] != sizeof(KADM5_BOGUS_KEY_DATA) - 1 || 66 ct_memcmp(key->key_data_contents[1], KADM5_BOGUS_KEY_DATA, 67 key->key_data_length[0]) != 0) 68 return 0; 69 } 70 return 1; 71} 72 73kadm5_ret_t 74kadm5_store_key_data(krb5_storage *sp, 75 krb5_key_data *key) 76{ 77 krb5_data c; 78 krb5_store_int32(sp, key->key_data_ver); 79 krb5_store_int32(sp, key->key_data_kvno); 80 krb5_store_int32(sp, key->key_data_type[0]); 81 c.length = key->key_data_length[0]; 82 c.data = key->key_data_contents[0]; 83 krb5_store_data(sp, c); 84 krb5_store_int32(sp, key->key_data_type[1]); 85 c.length = key->key_data_length[1]; 86 c.data = key->key_data_contents[1]; 87 krb5_store_data(sp, c); 88 return 0; 89} 90 91kadm5_ret_t 92kadm5_store_fake_key_data(krb5_storage *sp, 93 krb5_key_data *key) 94{ 95 krb5_data c; 96 97 krb5_store_int32(sp, key->key_data_ver); 98 krb5_store_int32(sp, key->key_data_kvno); 99 krb5_store_int32(sp, key->key_data_type[0]); 100 101 /* 102 * This is the key contents. We want it to be obvious to the client 103 * (if it really did want the keys) that the key won't work. 104 * 32-bit keys are no good for any enctype, so that should do. 105 * Clients that didn't need keys will ignore this, and clients that 106 * did want keys will either fail or they'll, say, create bogus 107 * keytab entries that will subsequently fail to be useful. 108 */ 109 c.length = sizeof (KADM5_BOGUS_KEY_DATA) - 1; 110 c.data = KADM5_BOGUS_KEY_DATA; 111 krb5_store_data(sp, c); 112 113 /* This is the salt -- no need to send garbage */ 114 krb5_store_int32(sp, key->key_data_type[1]); 115 c.length = key->key_data_length[1]; 116 c.data = key->key_data_contents[1]; 117 krb5_store_data(sp, c); 118 return 0; 119} 120 121kadm5_ret_t 122kadm5_ret_key_data(krb5_storage *sp, 123 krb5_key_data *key) 124{ 125 krb5_data c; 126 int32_t tmp; 127 krb5_ret_int32(sp, &tmp); 128 key->key_data_ver = tmp; 129 krb5_ret_int32(sp, &tmp); 130 key->key_data_kvno = tmp; 131 krb5_ret_int32(sp, &tmp); 132 key->key_data_type[0] = tmp; 133 krb5_ret_data(sp, &c); 134 key->key_data_length[0] = c.length; 135 key->key_data_contents[0] = c.data; 136 krb5_ret_int32(sp, &tmp); 137 key->key_data_type[1] = tmp; 138 krb5_ret_data(sp, &c); 139 key->key_data_length[1] = c.length; 140 key->key_data_contents[1] = c.data; 141 return 0; 142} 143 144kadm5_ret_t 145kadm5_store_tl_data(krb5_storage *sp, 146 krb5_tl_data *tl) 147{ 148 krb5_data c; 149 krb5_store_int32(sp, tl->tl_data_type); 150 c.length = tl->tl_data_length; 151 c.data = tl->tl_data_contents; 152 krb5_store_data(sp, c); 153 return 0; 154} 155 156kadm5_ret_t 157kadm5_ret_tl_data(krb5_storage *sp, 158 krb5_tl_data *tl) 159{ 160 krb5_data c; 161 int32_t tmp; 162 krb5_ret_int32(sp, &tmp); 163 tl->tl_data_type = tmp; 164 krb5_ret_data(sp, &c); 165 tl->tl_data_length = c.length; 166 tl->tl_data_contents = c.data; 167 return 0; 168} 169 170static kadm5_ret_t 171store_principal_ent(krb5_storage *sp, 172 kadm5_principal_ent_t princ, 173 uint32_t mask, int wkeys) 174{ 175 int i; 176 177 if (mask & KADM5_PRINCIPAL) 178 krb5_store_principal(sp, princ->principal); 179 if (mask & KADM5_PRINC_EXPIRE_TIME) 180 krb5_store_int32(sp, princ->princ_expire_time); 181 if (mask & KADM5_PW_EXPIRATION) 182 krb5_store_int32(sp, princ->pw_expiration); 183 if (mask & KADM5_LAST_PWD_CHANGE) 184 krb5_store_int32(sp, princ->last_pwd_change); 185 if (mask & KADM5_MAX_LIFE) 186 krb5_store_int32(sp, princ->max_life); 187 if (mask & KADM5_MOD_NAME) { 188 krb5_store_int32(sp, princ->mod_name != NULL); 189 if(princ->mod_name) 190 krb5_store_principal(sp, princ->mod_name); 191 } 192 if (mask & KADM5_MOD_TIME) 193 krb5_store_int32(sp, princ->mod_date); 194 if (mask & KADM5_ATTRIBUTES) 195 krb5_store_int32(sp, princ->attributes); 196 if (mask & KADM5_KVNO) 197 krb5_store_int32(sp, princ->kvno); 198 if (mask & KADM5_MKVNO) 199 krb5_store_int32(sp, princ->mkvno); 200 if (mask & KADM5_POLICY) { 201 krb5_store_int32(sp, princ->policy != NULL); 202 if(princ->policy) 203 krb5_store_string(sp, princ->policy); 204 } 205 if (mask & KADM5_AUX_ATTRIBUTES) 206 krb5_store_int32(sp, princ->aux_attributes); 207 if (mask & KADM5_MAX_RLIFE) 208 krb5_store_int32(sp, princ->max_renewable_life); 209 if (mask & KADM5_LAST_SUCCESS) 210 krb5_store_int32(sp, princ->last_success); 211 if (mask & KADM5_LAST_FAILED) 212 krb5_store_int32(sp, princ->last_failed); 213 if (mask & KADM5_FAIL_AUTH_COUNT) 214 krb5_store_int32(sp, princ->fail_auth_count); 215 if (mask & KADM5_KEY_DATA) { 216 krb5_store_int32(sp, princ->n_key_data); 217 for(i = 0; i < princ->n_key_data; i++) { 218 if (wkeys) 219 kadm5_store_key_data(sp, &princ->key_data[i]); 220 else 221 kadm5_store_fake_key_data(sp, &princ->key_data[i]); 222 } 223 } 224 if (mask & KADM5_TL_DATA) { 225 krb5_tl_data *tp; 226 227 krb5_store_int32(sp, princ->n_tl_data); 228 for(tp = princ->tl_data; tp; tp = tp->tl_data_next) 229 kadm5_store_tl_data(sp, tp); 230 } 231 return 0; 232} 233 234 235kadm5_ret_t 236kadm5_store_principal_ent(krb5_storage *sp, 237 kadm5_principal_ent_t princ) 238{ 239 return store_principal_ent (sp, princ, ~0, 1); 240} 241 242kadm5_ret_t 243kadm5_store_principal_ent_nokeys(krb5_storage *sp, 244 kadm5_principal_ent_t princ) 245{ 246 return store_principal_ent (sp, princ, ~0, 0); 247} 248 249kadm5_ret_t 250kadm5_store_principal_ent_mask(krb5_storage *sp, 251 kadm5_principal_ent_t princ, 252 uint32_t mask) 253{ 254 krb5_store_int32(sp, mask); 255 return store_principal_ent (sp, princ, mask, 1); 256} 257 258static kadm5_ret_t 259ret_principal_ent(krb5_storage *sp, 260 kadm5_principal_ent_t princ, 261 uint32_t mask) 262{ 263 int i; 264 int32_t tmp; 265 266 if (mask & KADM5_PRINCIPAL) 267 krb5_ret_principal(sp, &princ->principal); 268 269 if (mask & KADM5_PRINC_EXPIRE_TIME) { 270 krb5_ret_int32(sp, &tmp); 271 princ->princ_expire_time = tmp; 272 } 273 if (mask & KADM5_PW_EXPIRATION) { 274 krb5_ret_int32(sp, &tmp); 275 princ->pw_expiration = tmp; 276 } 277 if (mask & KADM5_LAST_PWD_CHANGE) { 278 krb5_ret_int32(sp, &tmp); 279 princ->last_pwd_change = tmp; 280 } 281 if (mask & KADM5_MAX_LIFE) { 282 krb5_ret_int32(sp, &tmp); 283 princ->max_life = tmp; 284 } 285 if (mask & KADM5_MOD_NAME) { 286 krb5_ret_int32(sp, &tmp); 287 if(tmp) 288 krb5_ret_principal(sp, &princ->mod_name); 289 else 290 princ->mod_name = NULL; 291 } 292 if (mask & KADM5_MOD_TIME) { 293 krb5_ret_int32(sp, &tmp); 294 princ->mod_date = tmp; 295 } 296 if (mask & KADM5_ATTRIBUTES) { 297 krb5_ret_int32(sp, &tmp); 298 princ->attributes = tmp; 299 } 300 if (mask & KADM5_KVNO) { 301 krb5_ret_int32(sp, &tmp); 302 princ->kvno = tmp; 303 } 304 if (mask & KADM5_MKVNO) { 305 krb5_ret_int32(sp, &tmp); 306 princ->mkvno = tmp; 307 } 308 if (mask & KADM5_POLICY) { 309 krb5_ret_int32(sp, &tmp); 310 if(tmp) 311 krb5_ret_string(sp, &princ->policy); 312 else 313 princ->policy = NULL; 314 } 315 if (mask & KADM5_AUX_ATTRIBUTES) { 316 krb5_ret_int32(sp, &tmp); 317 princ->aux_attributes = tmp; 318 } 319 if (mask & KADM5_MAX_RLIFE) { 320 krb5_ret_int32(sp, &tmp); 321 princ->max_renewable_life = tmp; 322 } 323 if (mask & KADM5_LAST_SUCCESS) { 324 krb5_ret_int32(sp, &tmp); 325 princ->last_success = tmp; 326 } 327 if (mask & KADM5_LAST_FAILED) { 328 krb5_ret_int32(sp, &tmp); 329 princ->last_failed = tmp; 330 } 331 if (mask & KADM5_FAIL_AUTH_COUNT) { 332 krb5_ret_int32(sp, &tmp); 333 princ->fail_auth_count = tmp; 334 } 335 if (mask & KADM5_KEY_DATA) { 336 krb5_ret_int32(sp, &tmp); 337 princ->n_key_data = tmp; 338 princ->key_data = malloc(princ->n_key_data * sizeof(*princ->key_data)); 339 if (princ->key_data == NULL && princ->n_key_data != 0) 340 return ENOMEM; 341 for(i = 0; i < princ->n_key_data; i++) 342 kadm5_ret_key_data(sp, &princ->key_data[i]); 343 } 344 if (mask & KADM5_TL_DATA) { 345 krb5_ret_int32(sp, &tmp); 346 princ->n_tl_data = tmp; 347 princ->tl_data = NULL; 348 for(i = 0; i < princ->n_tl_data; i++){ 349 krb5_tl_data *tp = malloc(sizeof(*tp)); 350 if (tp == NULL) 351 return ENOMEM; 352 kadm5_ret_tl_data(sp, tp); 353 tp->tl_data_next = princ->tl_data; 354 princ->tl_data = tp; 355 } 356 } 357 return 0; 358} 359 360kadm5_ret_t 361kadm5_ret_principal_ent(krb5_storage *sp, 362 kadm5_principal_ent_t princ) 363{ 364 return ret_principal_ent (sp, princ, ~0); 365} 366 367kadm5_ret_t 368kadm5_ret_principal_ent_mask(krb5_storage *sp, 369 kadm5_principal_ent_t princ, 370 uint32_t *mask) 371{ 372 int32_t tmp; 373 374 krb5_ret_int32 (sp, &tmp); 375 *mask = tmp; 376 return ret_principal_ent (sp, princ, *mask); 377} 378 379kadm5_ret_t 380_kadm5_marshal_params(krb5_context context, 381 kadm5_config_params *params, 382 krb5_data *out) 383{ 384 krb5_storage *sp = krb5_storage_emem(); 385 386 krb5_store_int32(sp, params->mask & (KADM5_CONFIG_REALM)); 387 388 if(params->mask & KADM5_CONFIG_REALM) 389 krb5_store_string(sp, params->realm); 390 krb5_storage_to_data(sp, out); 391 krb5_storage_free(sp); 392 393 return 0; 394} 395 396kadm5_ret_t 397_kadm5_unmarshal_params(krb5_context context, 398 krb5_data *in, 399 kadm5_config_params *params) 400{ 401 krb5_error_code ret; 402 krb5_storage *sp; 403 int32_t mask; 404 405 sp = krb5_storage_from_data(in); 406 if (sp == NULL) 407 return ENOMEM; 408 409 ret = krb5_ret_int32(sp, &mask); 410 if (ret) 411 goto out; 412 params->mask = mask; 413 414 if(params->mask & KADM5_CONFIG_REALM) 415 ret = krb5_ret_string(sp, ¶ms->realm); 416 out: 417 krb5_storage_free(sp); 418 419 return ret; 420} 421