1 /* $OpenBSD: ike_phase_1.c,v 1.21 2000/12/12 01:45:45 niklas Exp $ */ 2 /* $EOM: ike_phase_1.c,v 1.31 2000/12/11 23:47:56 niklas Exp $ */ 3 4 /* 5 * Copyright (c) 1999, 2000 Niklas Hallqvist. All rights reserved. 6 * Copyright (c) 1999, 2000 Angelos D. Keromytis. 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 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Ericsson Radio Systems. 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * This code was written under funding by Ericsson Radio Systems. 36 */ 37 38 #include <sys/types.h> 39 #include <netinet/in.h> 40 #include <stdlib.h> 41 #include <string.h> 42 43 #include "sysdep.h" 44 45 #include "attribute.h" 46 #include "conf.h" 47 #include "constants.h" 48 #include "crypto.h" 49 #include "dh.h" 50 #include "doi.h" 51 #include "exchange.h" 52 #include "hash.h" 53 #include "ike_auth.h" 54 #include "ike_phase_1.h" 55 #include "ipsec.h" 56 #include "ipsec_doi.h" 57 #include "isakmp.h" 58 #include "log.h" 59 #include "math_group.h" 60 #include "message.h" 61 #include "prf.h" 62 #include "sa.h" 63 #include "transport.h" 64 #include "util.h" 65 66 static int attribute_unacceptable (u_int16_t, u_int8_t *, u_int16_t, void *); 67 static int ike_phase_1_validate_prop (struct exchange *, struct sa *, 68 struct sa *); 69 70 /* Offer a set of transforms to the responder in the MSG message. */ 71 int 72 ike_phase_1_initiator_send_SA (struct message *msg) 73 { 74 struct exchange *exchange = msg->exchange; 75 struct ipsec_exch *ie = exchange->data; 76 u_int8_t *proposal = 0, *sa_buf = 0, *saved_nextp, *attr; 77 u_int8_t **transform = 0; 78 size_t transforms_len = 0, proposal_len, sa_len; 79 size_t *transform_len = 0; 80 struct conf_list *conf, *life_conf; 81 struct conf_list_node *xf, *life; 82 int i, value, update_nextp; 83 struct payload *p; 84 struct proto *proto; 85 int group_desc = -1, new_group_desc; 86 87 /* Get the list of transforms. */ 88 conf = conf_get_list (exchange->policy, "Transforms"); 89 if (!conf) 90 return -1; 91 92 transform = calloc (conf->cnt, sizeof *transform); 93 if (!transform) 94 { 95 log_error ("ike_phase_1_initiator_send_SA: calloc (%d, %d) failed", 96 conf->cnt, sizeof *transform); 97 goto bail_out; 98 } 99 100 transform_len = calloc (conf->cnt, sizeof *transform_len); 101 if (!transform_len) 102 { 103 log_error ("ike_phase_1_initiator_send_SA: calloc (%d, %d) failed", 104 conf->cnt, sizeof *transform_len); 105 goto bail_out; 106 } 107 108 for (xf = TAILQ_FIRST (&conf->fields), i = 0; i < conf->cnt; 109 i++, xf = TAILQ_NEXT (xf, link)) 110 { 111 /* XXX The sizing needs to be dynamic. */ 112 transform[i] 113 = malloc (ISAKMP_TRANSFORM_SA_ATTRS_OFF + 16 * ISAKMP_ATTR_VALUE_OFF); 114 if (!transform[i]) 115 { 116 log_error ("ike_phase_1_initiator_send_SA: malloc (%d) failed", 117 ISAKMP_TRANSFORM_SA_ATTRS_OFF 118 + 16 * ISAKMP_ATTR_VALUE_OFF); 119 goto bail_out; 120 } 121 122 SET_ISAKMP_TRANSFORM_NO (transform[i], i); 123 SET_ISAKMP_TRANSFORM_ID (transform[i], IPSEC_TRANSFORM_KEY_IKE); 124 SET_ISAKMP_TRANSFORM_RESERVED (transform[i], 0); 125 126 attr = transform[i] + ISAKMP_TRANSFORM_SA_ATTRS_OFF; 127 128 if (attribute_set_constant (xf->field, "ENCRYPTION_ALGORITHM", 129 ike_encrypt_cst, 130 IKE_ATTR_ENCRYPTION_ALGORITHM, &attr)) 131 goto bail_out; 132 133 if (attribute_set_constant (xf->field, "HASH_ALGORITHM", ike_hash_cst, 134 IKE_ATTR_HASH_ALGORITHM, &attr)) 135 goto bail_out; 136 137 if (attribute_set_constant (xf->field, "AUTHENTICATION_METHOD", 138 ike_auth_cst, IKE_ATTR_AUTHENTICATION_METHOD, 139 &attr)) 140 goto bail_out; 141 142 if (attribute_set_constant (xf->field, "GROUP_DESCRIPTION", 143 ike_group_desc_cst, 144 IKE_ATTR_GROUP_DESCRIPTION, &attr)) 145 { 146 /* 147 * If no group description exists, try looking for a user-defined 148 * one. 149 */ 150 if (attribute_set_constant (xf->field, "GROUP_TYPE", ike_group_cst, 151 IKE_ATTR_GROUP_TYPE, &attr)) 152 goto bail_out; 153 154 #if 0 155 if (attribute_set_bignum (xf->field, "GROUP_PRIME", 156 IKE_ATTR_GROUP_PRIME, &attr)) 157 goto bail_out; 158 159 if (attribute_set_bignum (xf->field, "GROUP_GENERATOR_2", 160 IKE_ATTR_GROUP_GENERATOR_2, &attr)) 161 goto bail_out; 162 163 if (attribute_set_bignum (xf->field, "GROUP_GENERATOR_2", 164 IKE_ATTR_GROUP_GENERATOR_2, &attr)) 165 goto bail_out; 166 167 if (attribute_set_bignum (xf->field, "GROUP_CURVE_A", 168 IKE_ATTR_GROUP_CURVE_A, &attr)) 169 goto bail_out; 170 171 if (attribute_set_bignum (xf->field, "GROUP_CURVE_B", 172 IKE_ATTR_GROUP_CURVE_B, &attr)) 173 goto bail_out; 174 #endif 175 } 176 177 /* 178 * Life durations are special, we should be able to specify 179 * several, one per type. 180 */ 181 life_conf = conf_get_list (xf->field, "Life"); 182 if (life_conf) 183 { 184 for (life = TAILQ_FIRST (&life_conf->fields); life; 185 life = TAILQ_NEXT (life, link)) 186 { 187 attribute_set_constant (life->field, "LIFE_TYPE", 188 ike_duration_cst, IKE_ATTR_LIFE_TYPE, 189 &attr); 190 191 /* XXX Deals with 16 and 32 bit lifetimes only */ 192 value = conf_get_num (life->field, "LIFE_DURATION", 0); 193 if (value) 194 { 195 if (value <= 0xffff) 196 attr = attribute_set_basic (attr, IKE_ATTR_LIFE_DURATION, 197 value); 198 else 199 { 200 value = htonl (value); 201 attr = attribute_set_var (attr, IKE_ATTR_LIFE_DURATION, 202 (char *)&value, sizeof value); 203 } 204 } 205 } 206 conf_free_list (life_conf); 207 } 208 209 attribute_set_constant (xf->field, "PRF", ike_prf_cst, IKE_ATTR_PRF, 210 &attr); 211 212 value = conf_get_num (xf->field, "KEY_LENGTH", 0); 213 if (value) 214 attr = attribute_set_basic (attr, IKE_ATTR_KEY_LENGTH, value); 215 216 value = conf_get_num (xf->field, "FIELD_SIZE", 0); 217 if (value) 218 attr = attribute_set_basic (attr, IKE_ATTR_FIELD_SIZE, value); 219 220 value = conf_get_num (xf->field, "GROUP_ORDER", 0); 221 if (value) 222 attr = attribute_set_basic (attr, IKE_ATTR_GROUP_ORDER, value); 223 224 /* Record the real transform size. */ 225 transforms_len += transform_len[i] = attr - transform[i]; 226 227 /* XXX I don't like exchange-specific stuff in here. */ 228 if (exchange->type == ISAKMP_EXCH_AGGRESSIVE) 229 { 230 /* 231 * Make sure that if a group description is specified, it is 232 * specified for all transforms equally. 233 */ 234 attr = conf_get_str (xf->field, "GROUP_DESCRIPTION"); 235 new_group_desc 236 = attr ? constant_value (ike_group_desc_cst, attr) : 0; 237 if (group_desc == -1) 238 group_desc = new_group_desc; 239 else if (group_desc != new_group_desc) 240 { 241 log_print ("ike_phase_1_inititor_send_SA: " 242 "differing group descriptions in a proposal"); 243 goto bail_out; 244 } 245 } 246 247 /* We need to check that we actually support our configuration. */ 248 if (attribute_map (transform[i] + ISAKMP_TRANSFORM_SA_ATTRS_OFF, 249 transform_len[i] - ISAKMP_TRANSFORM_SA_ATTRS_OFF, 250 exchange->doi->is_attribute_incompatible, msg)) 251 { 252 log_print ("ike_phase_1_initiator_send_SA: " 253 "section [%s] has unsupported attribute(s)", 254 xf->field); 255 goto bail_out; 256 } 257 } 258 259 /* XXX I don't like exchange-specific stuff in here. */ 260 if (exchange->type == ISAKMP_EXCH_AGGRESSIVE) 261 ie->group = group_get (group_desc); 262 263 proposal_len = ISAKMP_PROP_SPI_OFF; 264 proposal = malloc (proposal_len); 265 if (!proposal) 266 { 267 log_error ("ike_phase_1_initiator_send_SA: malloc (%d) failed", 268 proposal_len); 269 goto bail_out; 270 } 271 272 SET_ISAKMP_PROP_NO (proposal, 1); 273 SET_ISAKMP_PROP_PROTO (proposal, ISAKMP_PROTO_ISAKMP); 274 SET_ISAKMP_PROP_SPI_SZ (proposal, 0); 275 SET_ISAKMP_PROP_NTRANSFORMS (proposal, conf->cnt); 276 277 /* XXX I would like to see this factored out. */ 278 proto = calloc (1, sizeof *proto); 279 if (!proto) 280 { 281 log_error ("ike_phase_1_initiator_send_SA: calloc (1, %d) failed", 282 sizeof *proto); 283 goto bail_out; 284 } 285 286 proto->no = 1; 287 proto->proto = ISAKMP_PROTO_ISAKMP; 288 proto->sa = TAILQ_FIRST (&exchange->sa_list); 289 TAILQ_INSERT_TAIL (&TAILQ_FIRST (&exchange->sa_list)->protos, proto, 290 link); 291 292 sa_len = ISAKMP_SA_SIT_OFF + IPSEC_SIT_SIT_LEN; 293 sa_buf = malloc (sa_len); 294 if (!sa_buf) 295 { 296 log_error ("ike_phase_1_initiator_send_SA: malloc (%d) failed", sa_len); 297 goto bail_out; 298 } 299 300 SET_ISAKMP_SA_DOI (sa_buf, IPSEC_DOI_IPSEC); 301 SET_IPSEC_SIT_SIT (sa_buf + ISAKMP_SA_SIT_OFF, IPSEC_SIT_IDENTITY_ONLY); 302 303 /* 304 * Add the payloads. As this is a SA, we need to recompute the 305 * lengths of the payloads containing others. 306 */ 307 if (message_add_payload (msg, ISAKMP_PAYLOAD_SA, sa_buf, sa_len, 1)) 308 goto bail_out; 309 SET_ISAKMP_GEN_LENGTH (sa_buf, 310 sa_len + proposal_len + transforms_len); 311 sa_buf = 0; 312 313 saved_nextp = msg->nextp; 314 if (message_add_payload (msg, ISAKMP_PAYLOAD_PROPOSAL, proposal, 315 proposal_len, 0)) 316 goto bail_out; 317 SET_ISAKMP_GEN_LENGTH (proposal, proposal_len + transforms_len); 318 proposal = 0; 319 320 update_nextp = 0; 321 for (i = 0; i < conf->cnt; i++) 322 { 323 if (message_add_payload (msg, ISAKMP_PAYLOAD_TRANSFORM, transform[i], 324 transform_len[i], update_nextp)) 325 goto bail_out; 326 update_nextp = 1; 327 transform[i] = 0; 328 } 329 msg->nextp = saved_nextp; 330 331 /* Save SA payload body in ie->sa_i_b, length ie->sa_i_b_len. */ 332 ie->sa_i_b_len = sa_len + proposal_len + transforms_len - ISAKMP_GEN_SZ; 333 ie->sa_i_b = malloc (ie->sa_i_b_len); 334 if (!ie->sa_i_b) 335 { 336 log_error ("ike_phase_1_initiator_send_SA: malloc (%d) failed", 337 ie->sa_i_b_len); 338 goto bail_out; 339 } 340 memcpy (ie->sa_i_b, 341 TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_SA])->p + ISAKMP_GEN_SZ, 342 sa_len - ISAKMP_GEN_SZ); 343 memcpy (ie->sa_i_b + sa_len - ISAKMP_GEN_SZ, 344 TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_PROPOSAL])->p, 345 proposal_len); 346 transforms_len = 0; 347 for (i = 0, p = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_TRANSFORM]); 348 i < conf->cnt; i++, p = TAILQ_NEXT (p, link)) 349 { 350 memcpy (ie->sa_i_b + sa_len + proposal_len + transforms_len 351 - ISAKMP_GEN_SZ, 352 p->p, transform_len[i]); 353 transforms_len += transform_len[i]; 354 } 355 356 conf_free_list (conf); 357 free (transform); 358 free (transform_len); 359 return 0; 360 361 bail_out: 362 if (sa_buf) 363 free (sa_buf); 364 if (proposal) 365 free (proposal); 366 if (transform) 367 { 368 for (i = 0; i < conf->cnt; i++) 369 if (transform[i]) 370 free (transform[i]); 371 free (transform); 372 } 373 if (transform_len) 374 free (transform_len); 375 conf_free_list (conf); 376 return -1; 377 } 378 379 /* Figure out what transform the responder chose. */ 380 int 381 ike_phase_1_initiator_recv_SA (struct message *msg) 382 { 383 struct exchange *exchange = msg->exchange; 384 struct sa *sa = TAILQ_FIRST (&exchange->sa_list); 385 struct ipsec_exch *ie = exchange->data; 386 struct ipsec_sa *isa = sa->data; 387 struct payload *sa_p = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_SA]); 388 struct payload *prop = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_PROPOSAL]); 389 struct payload *xf = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_TRANSFORM]); 390 391 /* 392 * IKE requires that only one SA with only one proposal exists and since 393 * we are getting an answer on our transform offer, only one transform. 394 */ 395 if (TAILQ_NEXT (sa_p, link) || TAILQ_NEXT (prop, link) 396 || TAILQ_NEXT (xf, link)) 397 { 398 log_print ("ike_phase_1_initiator_recv_SA: " 399 "multiple SA, proposal or transform payloads in phase 1"); 400 /* XXX Is there a better notification type? */ 401 message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0); 402 return -1; 403 } 404 405 /* Check that the chosen transform matches an offer. */ 406 if (message_negotiate_sa (msg, ike_phase_1_validate_prop) 407 || !TAILQ_FIRST (&sa->protos)) 408 return -1; 409 410 ipsec_decode_transform (msg, sa, TAILQ_FIRST (&sa->protos), xf->p); 411 412 /* XXX I don't like exchange-specific stuff in here. */ 413 if (exchange->type != ISAKMP_EXCH_AGGRESSIVE) 414 ie->group = group_get (isa->group_desc); 415 416 /* Mark the SA as handled. */ 417 sa_p->flags |= PL_MARK; 418 419 return 0; 420 } 421 422 /* Send our public DH value and a nonce to the responder. */ 423 int 424 ike_phase_1_initiator_send_KE_NONCE (struct message *msg) 425 { 426 struct ipsec_exch *ie = msg->exchange->data; 427 428 ie->g_x_len = dh_getlen (ie->group); 429 430 /* XXX I want a better way to specify the nonce's size. */ 431 return ike_phase_1_send_KE_NONCE (msg, 16); 432 } 433 434 /* Accept responder's public DH value and nonce. */ 435 int 436 ike_phase_1_initiator_recv_KE_NONCE (struct message *msg) 437 { 438 if (ike_phase_1_recv_KE_NONCE (msg)) 439 return -1; 440 441 return ike_phase_1_post_exchange_KE_NONCE (msg); 442 } 443 444 /* 445 * Accept a set of transforms offered by the initiator and chose one we can 446 * handle. 447 */ 448 int 449 ike_phase_1_responder_recv_SA (struct message *msg) 450 { 451 struct exchange *exchange = msg->exchange; 452 struct sa *sa = TAILQ_FIRST (&exchange->sa_list); 453 struct ipsec_sa *isa = sa->data; 454 struct payload *sa_p = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_SA]); 455 struct payload *prop = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_PROPOSAL]); 456 struct ipsec_exch *ie = exchange->data; 457 458 /* Mark the SA as handled. */ 459 sa_p->flags |= PL_MARK; 460 461 /* IKE requires that only one SA with only one proposal exists. */ 462 if (TAILQ_NEXT (sa_p, link) || TAILQ_NEXT (prop, link)) 463 { 464 log_print ("ike_phase_1_responder_recv_SA: " 465 "multiple SA or proposal payloads in phase 1"); 466 /* XXX Is there a better notification type? */ 467 message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0); 468 return -1; 469 } 470 471 /* Chose a transform from the SA. */ 472 if (message_negotiate_sa (msg, ike_phase_1_validate_prop) 473 || !TAILQ_FIRST (&sa->protos)) 474 return -1; 475 476 /* XXX Move into message_negotiate_sa? */ 477 ipsec_decode_transform (msg, sa, TAILQ_FIRST (&sa->protos), 478 TAILQ_FIRST (&sa->protos)->chosen->p); 479 480 ie->group = group_get (isa->group_desc); 481 482 /* 483 * Check that the mandatory attributes: encryption, hash, authentication 484 * method and Diffie-Hellman group description, has been supplied. 485 */ 486 if (!exchange->crypto || !ie->hash || !ie->ike_auth || !ie->group) 487 { 488 message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0); 489 return -1; 490 } 491 492 /* Save the body for later hash computation. */ 493 ie->sa_i_b_len = GET_ISAKMP_GEN_LENGTH (sa_p->p) - ISAKMP_GEN_SZ; 494 ie->sa_i_b = malloc (ie->sa_i_b_len); 495 if (!ie->sa_i_b) 496 { 497 /* XXX How to notify peer? */ 498 log_error ("ike_phase_1_responder_recv_SA: malloc (%d) failed", 499 ie->sa_i_b_len); 500 return -1; 501 } 502 memcpy (ie->sa_i_b, sa_p->p + ISAKMP_GEN_SZ, ie->sa_i_b_len); 503 504 return 0; 505 } 506 507 /* Reply with the transform we chose. */ 508 int 509 ike_phase_1_responder_send_SA (struct message *msg) 510 { 511 /* Add the SA payload with the transform that was chosen. */ 512 return message_add_sa_payload (msg); 513 } 514 515 /* Send our public DH value and a nonce to the peer. */ 516 int 517 ike_phase_1_send_KE_NONCE (struct message *msg, size_t nonce_sz) 518 { 519 /* Public DH key. */ 520 if (ipsec_gen_g_x (msg)) 521 { 522 /* XXX How to log and notify peer? */ 523 return -1; 524 } 525 526 /* Generate a nonce, and add it to the message. */ 527 if (exchange_gen_nonce (msg, nonce_sz)) 528 { 529 /* XXX Log? */ 530 return -1; 531 } 532 533 /* Try to add certificates which are acceptable for the CERTREQs */ 534 if (exchange_add_certs (msg)) 535 { 536 /* XXX Log? */ 537 return -1; 538 } 539 540 return 0; 541 } 542 543 /* Receive our peer's public DH value and nonce. */ 544 int 545 ike_phase_1_recv_KE_NONCE (struct message *msg) 546 { 547 /* Copy out the initiator's DH public value. */ 548 if (ipsec_save_g_x (msg)) 549 { 550 /* XXX How to log and notify peer? */ 551 return -1; 552 } 553 554 /* Copy out the initiator's nonce. */ 555 if (exchange_save_nonce (msg)) 556 { 557 /* XXX How to log and notify peer? */ 558 return -1; 559 } 560 561 /* Copy out the initiator's cert requests. */ 562 if (exchange_save_certreq (msg)) 563 { 564 /* XXX How to log and notify peer? */ 565 return -1; 566 } 567 568 return 0; 569 } 570 571 /* 572 * Compute DH values and key material. This is done in a post-send function 573 * as that means we can do parallel work in both the initiator and responder 574 * thus speeding up exchanges. 575 */ 576 int 577 ike_phase_1_post_exchange_KE_NONCE (struct message *msg) 578 { 579 struct exchange *exchange = msg->exchange; 580 struct ipsec_exch *ie = exchange->data; 581 struct prf *prf; 582 struct hash *hash = ie->hash; 583 enum cryptoerr err; 584 585 /* Compute Diffie-Hellman shared value. */ 586 ie->g_xy = malloc (ie->g_x_len); 587 if (!ie->g_xy) 588 { 589 /* XXX How to notify peer? */ 590 log_error ("ike_phase_1_post_exchange_KE_NONCE: malloc (%d) failed", 591 ie->g_x_len); 592 return -1; 593 } 594 if (dh_create_shared (ie->group, ie->g_xy, 595 exchange->initiator ? ie->g_xr : ie->g_xi)) 596 { 597 log_print ("ike_phase_1_post_exchange_KE_NONCE: " 598 "dh_create_shared failed"); 599 return -1; 600 } 601 LOG_DBG_BUF ((LOG_MISC, 80, "ike_phase_1_post_exchange_KE_NONCE: g^xy", 602 ie->g_xy, ie->g_x_len)); 603 604 /* Compute the SKEYID depending on the authentication method. */ 605 ie->skeyid = ie->ike_auth->gen_skeyid (exchange, &ie->skeyid_len); 606 if (!ie->skeyid) 607 { 608 /* XXX Log and teardown? */ 609 return -1; 610 } 611 LOG_DBG_BUF ((LOG_MISC, 80, "ike_phase_1_post_exchange_KE_NONCE: SKEYID", 612 ie->skeyid, ie->skeyid_len)); 613 614 /* SKEYID_d. */ 615 ie->skeyid_d = malloc (ie->skeyid_len); 616 if (!ie->skeyid_d) 617 { 618 /* XXX How to notify peer? */ 619 log_error ("ike_phase_1_post_exchange_KE_NONCE: malloc (%d) failed", 620 ie->skeyid_len); 621 return -1; 622 } 623 prf = prf_alloc (ie->prf_type, hash->type, ie->skeyid, ie->skeyid_len); 624 if (!prf) 625 { 626 /* XXX Log and teardown? */ 627 return -1; 628 } 629 prf->Init (prf->prfctx); 630 prf->Update (prf->prfctx, ie->g_xy, ie->g_x_len); 631 prf->Update (prf->prfctx, exchange->cookies, ISAKMP_HDR_COOKIES_LEN); 632 prf->Update (prf->prfctx, "\0", 1); 633 prf->Final (ie->skeyid_d, prf->prfctx); 634 LOG_DBG_BUF ((LOG_MISC, 80, "ike_phase_1_post_exchange_KE_NONCE: SKEYID_d", 635 ie->skeyid_d, ie->skeyid_len)); 636 637 /* SKEYID_a. */ 638 ie->skeyid_a = malloc (ie->skeyid_len); 639 if (!ie->skeyid_a) 640 { 641 log_error ("ike_phase_1_post_exchange_KE_NONCE: malloc (%d) failed", 642 ie->skeyid_len); 643 prf_free (prf); 644 return -1; 645 } 646 prf->Init (prf->prfctx); 647 prf->Update (prf->prfctx, ie->skeyid_d, ie->skeyid_len); 648 prf->Update (prf->prfctx, ie->g_xy, ie->g_x_len); 649 prf->Update (prf->prfctx, exchange->cookies, ISAKMP_HDR_COOKIES_LEN); 650 prf->Update (prf->prfctx, "\1", 1); 651 prf->Final (ie->skeyid_a, prf->prfctx); 652 LOG_DBG_BUF ((LOG_MISC, 80, "ike_phase_1_post_exchange_KE_NONCE: SKEYID_a", 653 ie->skeyid_a, ie->skeyid_len)); 654 655 /* SKEYID_e. */ 656 ie->skeyid_e = malloc (ie->skeyid_len); 657 if (!ie->skeyid_e) 658 { 659 /* XXX How to notify peer? */ 660 log_error ("ike_phase_1_post_exchange_KE_NONCE: malloc (%d) failed", 661 ie->skeyid_len); 662 prf_free (prf); 663 return -1; 664 } 665 prf->Init (prf->prfctx); 666 prf->Update (prf->prfctx, ie->skeyid_a, ie->skeyid_len); 667 prf->Update (prf->prfctx, ie->g_xy, ie->g_x_len); 668 prf->Update (prf->prfctx, exchange->cookies, ISAKMP_HDR_COOKIES_LEN); 669 prf->Update (prf->prfctx, "\2", 1); 670 prf->Final (ie->skeyid_e, prf->prfctx); 671 prf_free (prf); 672 LOG_DBG_BUF ((LOG_MISC, 80, "ike_phase_1_post_exchange_KE_NONCE: SKEYID_e", 673 ie->skeyid_e, ie->skeyid_len)); 674 675 /* Key length determination. */ 676 if (!exchange->key_length) 677 exchange->key_length = exchange->crypto->keymax; 678 679 /* Derive a longer key from skeyid_e */ 680 if (ie->skeyid_len < exchange->key_length) 681 { 682 u_int16_t len, keylen; 683 u_int8_t *key, *p; 684 685 prf = prf_alloc (ie->prf_type, hash->type, ie->skeyid_e, ie->skeyid_len); 686 if (!prf) 687 { 688 /* XXX - notify peer */ 689 return -1; 690 } 691 692 /* Make keylen a multiple of prf->blocksize */ 693 keylen = exchange->key_length; 694 if (keylen % prf->blocksize) 695 keylen += prf->blocksize - (keylen % prf->blocksize); 696 697 key = malloc (keylen); 698 if (!key) 699 { 700 /* XXX - Notify peer. */ 701 log_error ("ike_phase_1_post_exchange_KE_NONCE: malloc (%d) failed", 702 keylen); 703 return -1; 704 } 705 706 prf->Init (prf->prfctx); 707 prf->Update (prf->prfctx, "\0", 1); 708 prf->Final (key, prf->prfctx); 709 710 for (len = prf->blocksize, p = key; len < exchange->key_length; 711 len += prf->blocksize, p += prf->blocksize) 712 { 713 prf->Init (prf->prfctx); 714 prf->Update (prf->prfctx, p, prf->blocksize); 715 prf->Final (p + prf->blocksize, prf->prfctx); 716 } 717 prf_free (prf); 718 719 /* Setup our keystate using the derived encryption key. */ 720 exchange->keystate 721 = crypto_init (exchange->crypto, key, exchange->key_length, &err); 722 723 free (key); 724 } 725 else 726 /* Setup our keystate using the raw skeyid_e. */ 727 exchange->keystate = crypto_init (exchange->crypto, ie->skeyid_e, 728 exchange->key_length, &err); 729 730 /* Special handling for DES weak keys. */ 731 if (!exchange->keystate && err == EWEAKKEY 732 && (exchange->key_length << 1) <= ie->skeyid_len) 733 { 734 log_print ("ike_phase_1_post_exchange_KE_NONCE: " 735 "weak key, trying subseq. skeyid_e"); 736 exchange->keystate 737 = crypto_init (exchange->crypto, ie->skeyid_e + exchange->key_length, 738 exchange->key_length, &err); 739 } 740 741 if (!exchange->keystate) 742 { 743 log_print ("ike_phase_1_post_exchange_KE_NONCE: " 744 "exchange->crypto->init () failed: %d", err); 745 746 /* 747 * XXX We really need to know if problems are of transient nature 748 * or fatal (like failed assertions etc.) 749 */ 750 return -1; 751 } 752 753 /* Setup IV. XXX Only for CBC transforms, no? */ 754 hash->Init (hash->ctx); 755 hash->Update (hash->ctx, ie->g_xi, ie->g_x_len); 756 hash->Update (hash->ctx, ie->g_xr, ie->g_x_len); 757 hash->Final (hash->digest, hash->ctx); 758 crypto_init_iv (exchange->keystate, hash->digest, 759 exchange->crypto->blocksize); 760 761 return 0; 762 } 763 764 int 765 ike_phase_1_responder_send_ID_AUTH (struct message *msg) 766 { 767 if (ike_phase_1_send_ID (msg)) 768 return -1; 769 770 return ike_phase_1_send_AUTH (msg); 771 } 772 773 int 774 ike_phase_1_send_ID (struct message *msg) 775 { 776 struct exchange *exchange = msg->exchange; 777 u_int8_t *buf; 778 char header[80]; 779 ssize_t sz; 780 struct sockaddr *src; 781 int src_len; 782 int initiator = exchange->initiator; 783 u_int8_t **id; 784 size_t *id_len; 785 char *my_id = 0; 786 u_int8_t id_type; 787 788 /* Choose the right fields to fill-in. */ 789 id = initiator ? &exchange->id_i : &exchange->id_r; 790 id_len = initiator ? &exchange->id_i_len : &exchange->id_r_len; 791 792 if (exchange->name) 793 my_id = conf_get_str (exchange->name, "ID"); 794 795 if (!my_id) 796 my_id = conf_get_str ("General", "Default-phase-1-ID"); 797 798 sz = my_id ? ipsec_id_size (my_id, &id_type) : sizeof (in_addr_t); 799 if (sz == -1) 800 return -1; 801 802 sz += ISAKMP_ID_DATA_OFF; 803 buf = malloc (sz); 804 if (!buf) 805 { 806 log_error ("ike_phase_1_send_ID: malloc (%d) failed", sz); 807 return -1; 808 } 809 810 SET_IPSEC_ID_PROTO (buf + ISAKMP_ID_DOI_DATA_OFF, 0); 811 SET_IPSEC_ID_PORT (buf + ISAKMP_ID_DOI_DATA_OFF, 0); 812 if (my_id) 813 { 814 SET_ISAKMP_ID_TYPE (buf, id_type); 815 switch (id_type) 816 { 817 case IPSEC_ID_IPV4_ADDR: 818 msg->transport->vtbl->get_src (msg->transport, &src, &src_len); 819 820 /* Already in network byteorder. */ 821 memcpy (buf + ISAKMP_ID_DATA_OFF, 822 &((struct sockaddr_in *)src)->sin_addr.s_addr, 823 sizeof (in_addr_t)); 824 break; 825 case IPSEC_ID_FQDN: 826 case IPSEC_ID_USER_FQDN: 827 memcpy (buf + ISAKMP_ID_DATA_OFF, conf_get_str (my_id, "Name"), 828 sz - ISAKMP_ID_DATA_OFF); 829 break; 830 default: 831 log_print ("ike_phase_1_send_ID: unsupported ID type %d", id_type); 832 free (buf); 833 return -1; 834 } 835 } 836 else 837 { 838 msg->transport->vtbl->get_src (msg->transport, &src, &src_len); 839 /* XXX Assumes IPv4. */ 840 SET_ISAKMP_ID_TYPE (buf, IPSEC_ID_IPV4_ADDR); 841 /* Already in network byteorder. */ 842 memcpy (buf + ISAKMP_ID_DATA_OFF, 843 &((struct sockaddr_in *)src)->sin_addr.s_addr, 844 sizeof (in_addr_t)); 845 } 846 847 if (message_add_payload (msg, ISAKMP_PAYLOAD_ID, buf, sz, 1)) 848 { 849 free (buf); 850 return -1; 851 } 852 *id_len = sz - ISAKMP_GEN_SZ; 853 *id = malloc (*id_len); 854 if (!*id) 855 { 856 log_error ("ike_phase_1_send_ID: malloc (%d) failed", *id_len); 857 return -1; 858 } 859 memcpy (*id, buf + ISAKMP_GEN_SZ, *id_len); 860 snprintf (header, 80, "ike_phase_1_send_ID: %s", 861 constant_name (ipsec_id_cst, GET_ISAKMP_ID_TYPE (buf))); 862 LOG_DBG_BUF ((LOG_MISC, 40, header, buf + ISAKMP_ID_DATA_OFF, 863 sz - ISAKMP_ID_DATA_OFF)); 864 865 return 0; 866 } 867 868 int 869 ike_phase_1_send_AUTH (struct message *msg) 870 { 871 struct exchange *exchange = msg->exchange; 872 struct ipsec_exch *ie = exchange->data; 873 874 if (ie->ike_auth->encode_hash (msg)) 875 { 876 /* XXX Log? */ 877 return -1; 878 } 879 880 /* 881 * XXX Many people say the COMMIT flag is just junk, especially in Phase 1. 882 */ 883 #ifdef notyet 884 if ((exchange->flags & EXCHANGE_FLAG_COMMITTED) == 0) 885 exchange->flags |= EXCHANGE_FLAG_I_COMMITTED; 886 #endif 887 888 return 0; 889 } 890 891 /* Receive ID and HASH and check that the exchange has been consistent. */ 892 int 893 ike_phase_1_recv_ID_AUTH (struct message *msg) 894 { 895 if (ike_phase_1_recv_ID (msg)) 896 return -1; 897 898 return ike_phase_1_recv_AUTH (msg); 899 } 900 901 /* Receive ID. */ 902 int 903 ike_phase_1_recv_ID (struct message *msg) 904 { 905 struct exchange *exchange = msg->exchange; 906 struct payload *payload; 907 char header[80]; 908 int initiator = exchange->initiator; 909 u_int8_t **id; 910 size_t *id_len; 911 912 /* 913 * XXX Here, we could be checking that the received ID matches what 914 * we expect it to be (if anything). That information is contained 915 * in the [[exchange->name]:Remote-ID] section. 916 */ 917 918 /* Choose the right fields to fill in */ 919 id = initiator ? &exchange->id_r : &exchange->id_i; 920 id_len = initiator ? &exchange->id_r_len : &exchange->id_i_len; 921 922 /* XXX Do I really have to save the ID in the SA? */ 923 payload = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_ID]); 924 *id_len = GET_ISAKMP_GEN_LENGTH (payload->p) - ISAKMP_GEN_SZ; 925 *id = malloc (*id_len); 926 if (!*id) 927 { 928 log_error ("ike_phase_1_recv_ID: malloc (%d) failed", *id_len); 929 return -1; 930 } 931 memcpy (*id, payload->p + ISAKMP_GEN_SZ, *id_len); 932 snprintf (header, 80, "ike_phase_1_recv_ID: %s", 933 constant_name (ipsec_id_cst, GET_ISAKMP_ID_TYPE (payload->p))); 934 LOG_DBG_BUF ((LOG_MISC, 40, header, payload->p + ISAKMP_ID_DATA_OFF, 935 *id_len + ISAKMP_GEN_SZ - ISAKMP_ID_DATA_OFF)); 936 payload->flags |= PL_MARK; 937 938 return 0; 939 } 940 941 /* Receive HASH and check that the exchange has been consistent. */ 942 int 943 ike_phase_1_recv_AUTH (struct message *msg) 944 { 945 struct exchange *exchange = msg->exchange; 946 struct ipsec_exch *ie = exchange->data; 947 struct prf *prf; 948 struct hash *hash = ie->hash; 949 char header[80]; 950 size_t hashsize = hash->hashsize; 951 int initiator = exchange->initiator; 952 u_int8_t **hash_p, *id; 953 size_t id_len; 954 955 /* Choose the right fields to fill in */ 956 hash_p = initiator ? &ie->hash_r : &ie->hash_i; 957 id = initiator ? exchange->id_r : exchange->id_i; 958 id_len = initiator ? exchange->id_r_len : exchange->id_i_len; 959 960 /* The decoded hash will be in ie->hash_r or ie->hash_i */ 961 if (ie->ike_auth->decode_hash (msg)) 962 { 963 message_drop (msg, ISAKMP_NOTIFY_INVALID_ID_INFORMATION, 0, 1, 0); 964 return -1; 965 } 966 967 /* Allocate the prf and start calculating his HASH. */ 968 prf = prf_alloc (ie->prf_type, hash->type, ie->skeyid, ie->skeyid_len); 969 if (!prf) 970 { 971 /* XXX Log? */ 972 return -1; 973 } 974 prf->Init (prf->prfctx); 975 prf->Update (prf->prfctx, initiator ? ie->g_xr : ie->g_xi, ie->g_x_len); 976 prf->Update (prf->prfctx, initiator ? ie->g_xi : ie->g_xr, ie->g_x_len); 977 prf->Update (prf->prfctx, 978 exchange->cookies 979 + (initiator ? ISAKMP_HDR_RCOOKIE_OFF : ISAKMP_HDR_ICOOKIE_OFF), 980 ISAKMP_HDR_ICOOKIE_LEN); 981 prf->Update (prf->prfctx, 982 exchange->cookies 983 + (initiator ? ISAKMP_HDR_ICOOKIE_OFF : ISAKMP_HDR_RCOOKIE_OFF), 984 ISAKMP_HDR_ICOOKIE_LEN); 985 prf->Update (prf->prfctx, ie->sa_i_b, ie->sa_i_b_len); 986 prf->Update (prf->prfctx, id, id_len); 987 prf->Final (hash->digest, prf->prfctx); 988 prf_free (prf); 989 snprintf (header, 80, "ike_phase_1_recv_AUTH: computed HASH_%c", 990 initiator ? 'R' : 'I'); 991 LOG_DBG_BUF ((LOG_MISC, 80, header, hash->digest, hashsize)); 992 993 /* Check that the hash we got matches the one we computed. */ 994 if (memcmp (*hash_p, hash->digest, hashsize) != 0) 995 { 996 /* XXX Log? */ 997 return -1; 998 } 999 1000 return 0; 1001 } 1002 1003 struct attr_node { 1004 LIST_ENTRY (attr_node) link; 1005 u_int16_t type; 1006 }; 1007 1008 struct validation_state { 1009 struct conf_list_node *xf; 1010 LIST_HEAD (attr_head, attr_node) attrs; 1011 char *life; 1012 }; 1013 1014 /* Validate a proposal inside SA according to EXCHANGE's policy. */ 1015 static int 1016 ike_phase_1_validate_prop (struct exchange *exchange, struct sa *sa, 1017 struct sa *isakmp_sa) 1018 { 1019 struct conf_list *conf, *tags; 1020 struct conf_list_node *xf, *tag; 1021 struct proto *proto; 1022 struct validation_state vs; 1023 struct attr_node *node, *next_node; 1024 1025 /* Get the list of transforms. */ 1026 conf = conf_get_list (exchange->policy, "Transforms"); 1027 if (!conf) 1028 return 0; 1029 1030 for (xf = TAILQ_FIRST (&conf->fields); xf; xf = TAILQ_NEXT (xf, link)) 1031 { 1032 for (proto = TAILQ_FIRST (&sa->protos); proto; 1033 proto = TAILQ_NEXT (proto, link)) 1034 { 1035 /* Mark all attributes in our policy as unseen. */ 1036 LIST_INIT (&vs.attrs); 1037 vs.xf = xf; 1038 vs.life = 0; 1039 if (attribute_map (proto->chosen->p + ISAKMP_TRANSFORM_SA_ATTRS_OFF, 1040 GET_ISAKMP_GEN_LENGTH (proto->chosen->p) 1041 - ISAKMP_TRANSFORM_SA_ATTRS_OFF, 1042 attribute_unacceptable, &vs)) 1043 goto try_next; 1044 1045 /* Sweep over unseen tags in this section. */ 1046 tags = conf_get_tag_list (xf->field); 1047 if (tags) 1048 { 1049 for (tag = TAILQ_FIRST (&tags->fields); tag; 1050 tag = TAILQ_NEXT (tag, link)) 1051 /* 1052 * XXX Should we care about attributes we have, they do not 1053 * provide? 1054 */ 1055 for (node = LIST_FIRST (&vs.attrs); node; 1056 node = next_node) 1057 { 1058 next_node = LIST_NEXT (node, link); 1059 if (node->type 1060 == constant_value (ike_attr_cst, tag->field)) 1061 { 1062 LIST_REMOVE (node, link); 1063 free (node); 1064 } 1065 } 1066 conf_free_list (tags); 1067 } 1068 1069 /* Are there leftover tags in this section? */ 1070 node = LIST_FIRST (&vs.attrs); 1071 if (node) 1072 goto try_next; 1073 } 1074 1075 /* All protocols were OK, we succeeded. */ 1076 LOG_DBG ((LOG_MISC, 20, "ike_phase_1_validate_prop: success")); 1077 conf_free_list (conf); 1078 if (vs.life) 1079 free (vs.life); 1080 return 1; 1081 1082 try_next: 1083 /* Are there leftover tags in this section? */ 1084 node = LIST_FIRST (&vs.attrs); 1085 while (node) 1086 { 1087 LIST_REMOVE (node, link); 1088 free (node); 1089 node = LIST_FIRST (&vs.attrs); 1090 } 1091 if (vs.life) 1092 free (vs.life); 1093 } 1094 1095 LOG_DBG ((LOG_MISC, 20, "ike_phase_1_validate_prop: failure")); 1096 conf_free_list (conf); 1097 return 0; 1098 } 1099 1100 /* 1101 * Look at the attribute of type TYPE, located at VALUE for LEN bytes forward. 1102 * The VVS argument holds a validation state kept across invocations. 1103 * If the attribute is unacceptable to use, return non-zero, otherwise zero. 1104 */ 1105 static int 1106 attribute_unacceptable (u_int16_t type, u_int8_t *value, u_int16_t len, 1107 void *vvs) 1108 { 1109 struct validation_state *vs = vvs; 1110 struct conf_list *life_conf; 1111 struct conf_list_node *xf = vs->xf, *life; 1112 char *tag = constant_lookup (ike_attr_cst, type); 1113 char *str; 1114 struct constant_map *map; 1115 struct attr_node *node; 1116 int rv; 1117 1118 if (!tag) 1119 { 1120 log_print ("attribute_unacceptable: attribute type %d not known", type); 1121 return 1; 1122 } 1123 1124 switch (type) 1125 { 1126 case IKE_ATTR_ENCRYPTION_ALGORITHM: 1127 case IKE_ATTR_HASH_ALGORITHM: 1128 case IKE_ATTR_AUTHENTICATION_METHOD: 1129 case IKE_ATTR_GROUP_DESCRIPTION: 1130 case IKE_ATTR_GROUP_TYPE: 1131 case IKE_ATTR_PRF: 1132 str = conf_get_str (xf->field, tag); 1133 if (!str) 1134 { 1135 /* This attribute does not exist in this policy. */ 1136 log_print ("attribute_unacceptable: attr %s does not exist in %s", 1137 tag, xf->field); 1138 return 1; 1139 } 1140 1141 map = constant_link_lookup (ike_attr_cst, type); 1142 if (!map) 1143 return 1; 1144 1145 if ((constant_value (map, str) == decode_16 (value)) || 1146 (!strcmp (str, "ANY"))) 1147 { 1148 /* Mark this attribute as seen. */ 1149 node = malloc (sizeof *node); 1150 if (!node) 1151 { 1152 log_error ("attribute_unacceptable: malloc (%d) failed", 1153 sizeof *node); 1154 return 1; 1155 } 1156 node->type = type; 1157 LIST_INSERT_HEAD (&vs->attrs, node, link); 1158 return 0; 1159 } 1160 log_print ("attribute_unacceptable: %s: got %s, expected %s", 1161 tag, constant_lookup (map, decode_16 (value)), str); 1162 return 1; 1163 1164 case IKE_ATTR_GROUP_PRIME: 1165 case IKE_ATTR_GROUP_GENERATOR_1: 1166 case IKE_ATTR_GROUP_GENERATOR_2: 1167 case IKE_ATTR_GROUP_CURVE_A: 1168 case IKE_ATTR_GROUP_CURVE_B: 1169 /* XXX Bignums not handled yet. */ 1170 return 1; 1171 1172 case IKE_ATTR_LIFE_TYPE: 1173 case IKE_ATTR_LIFE_DURATION: 1174 life_conf = conf_get_list (xf->field, "Life"); 1175 if (life_conf && !strcmp (conf_get_str (xf->field, "Life"), "ANY")) 1176 return 0; 1177 1178 rv = 1; 1179 if (!life_conf) 1180 { 1181 /* Life attributes given, but not in our policy. */ 1182 log_print ("attribute_unacceptable: " 1183 "received unexpected life attribute"); 1184 return 1; 1185 } 1186 1187 /* 1188 * Each lifetime type must match, otherwise we turn the proposal down. 1189 * In order to do this we need to find the specific section of our 1190 * policy's "Life" list and match its duration 1191 */ 1192 switch (type) 1193 { 1194 case IKE_ATTR_LIFE_TYPE: 1195 for (life = TAILQ_FIRST (&life_conf->fields); life; 1196 life = TAILQ_NEXT (life, link)) 1197 { 1198 str = conf_get_str (life->field, "LIFE_TYPE"); 1199 if (!str) 1200 { 1201 log_print ("attribute_unacceptable: " 1202 "section [%s] has no LIFE_TYPE", life->field); 1203 continue; 1204 } 1205 1206 /* 1207 * If this is the type we are looking at, save a pointer 1208 * to this section in vs->life. 1209 */ 1210 if (constant_value (ike_duration_cst, str) == decode_16 (value)) 1211 { 1212 vs->life = strdup (life->field); 1213 rv = 0; 1214 goto bail_out; 1215 } 1216 } 1217 log_print ("attribute_unacceptable: unrecognized LIFE_TYPE %d", 1218 decode_16 (value)); 1219 vs->life = 0; 1220 break; 1221 1222 case IKE_ATTR_LIFE_DURATION: 1223 if (!vs->life) 1224 { 1225 log_print ("attribute_unacceptable: " 1226 "LIFE_DURATION without LIFE_TYPE"); 1227 rv = 1; 1228 goto bail_out; 1229 } 1230 1231 if (!strcmp (conf_get_str (vs->life, "LIFE_DURATION"), "ANY")) 1232 rv = 0; 1233 else 1234 rv = !conf_match_num (vs->life, "LIFE_DURATION", 1235 len == 4 ? decode_32 (value) : 1236 decode_16 (value)); 1237 free (vs->life); 1238 vs->life = 0; 1239 break; 1240 } 1241 1242 bail_out: 1243 conf_free_list (life_conf); 1244 return rv; 1245 1246 case IKE_ATTR_KEY_LENGTH: 1247 case IKE_ATTR_FIELD_SIZE: 1248 case IKE_ATTR_GROUP_ORDER: 1249 if (conf_match_num (xf->field, tag, decode_16 (value))) 1250 { 1251 /* Mark this attribute as seen. */ 1252 node = malloc (sizeof *node); 1253 if (!node) 1254 { 1255 log_error ("attribute_unacceptable: malloc (%d) failed", 1256 sizeof *node); 1257 return 1; 1258 } 1259 node->type = type; 1260 LIST_INSERT_HEAD (&vs->attrs, node, link); 1261 return 0; 1262 } 1263 return 1; 1264 } 1265 return 1; 1266 } 1267