00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <stdlib.h>
00014 #include <stdio.h>
00015 #include <assert.h>
00016 #include <string.h>
00017 #include <syslog.h>
00018 #include <unistd.h>
00019
00020 #include "auth.h"
00021 #include "ha_config.h"
00022 #include "ha.h"
00023 #include "fileio.h"
00024 #include "util.h"
00025
00026 #define ASSERT assert
00027
00028 struct load_ha_data {
00029 struct ha_config *cfg;
00030 int process_spi_list;
00031 int process_authorized_list;
00032 int process_fa_spi_list;
00033 int process_interfaces;
00034 };
00035
00036 static int process_load_ha(void *voidptr, char *key, char *data);
00037 static int process_load_ha_spi_list(struct load_ha_data *ha, char *key,
00038 char *data);
00039 static int process_load_ha_authorized_list(struct load_ha_data *ha, char *key,
00040 char *data);
00041 static int process_load_fa_spi_list(struct load_ha_data *ha, char *key,
00042 char *data);
00043
00044
00045
00046 void
00047 cleanup_config(struct ha_config *cfg)
00048 {
00049 struct spi_entry *spi;
00050 struct fa_spi_entry *fa_spi;
00051 struct authorized_entry *auth;
00052 struct interface_entry *iface;
00053
00054 if (cfg == NULL) return;
00055
00056 spi = (struct spi_entry *) list_remove_first(&cfg->spi_list);
00057 while (spi != NULL) {
00058 free(spi);
00059 spi = (struct spi_entry *) list_remove_first(&cfg->spi_list);
00060 }
00061
00062
00063 auth = (struct authorized_entry *)
00064 list_remove_first(&cfg->authorized_list);
00065 while (auth != NULL) {
00066 free(auth);
00067 auth = (struct authorized_entry *)
00068 list_remove_first(&cfg->authorized_list);
00069 }
00070
00071 fa_spi = (struct fa_spi_entry *) list_remove_first(&cfg->fa_spi_list);
00072 while (fa_spi != NULL) {
00073 free(fa_spi);
00074 fa_spi = (struct fa_spi_entry *)
00075 list_remove_first(&cfg->fa_spi_list);
00076 }
00077
00078 iface = (struct interface_entry *)
00079 list_remove_first(&cfg->interfaces);
00080 while (iface != NULL) {
00081 if (iface->icmp_sock >= 0)
00082 close(iface->icmp_sock);
00083 if (iface->udp_sock >= 0)
00084 close(iface->udp_sock);
00085 if (iface->udp_bc_sock >= 0)
00086 close(iface->udp_bc_sock);
00087 if (iface->udp_bc_sock2 >= 0)
00088 close(iface->udp_bc_sock2);
00089 free(iface);
00090 iface = (struct interface_entry *)
00091 list_remove_first(&cfg->interfaces);
00092 }
00093 }
00094
00095
00096 int
00097 load_config(struct ha_config *cfg, char *program_name, char *config_file)
00098 {
00099 FILE *file;
00100 struct load_ha_data ha;
00101
00102 ASSERT(cfg);
00103 ha.cfg = cfg;
00104 memset(cfg, 0, sizeof(struct ha_config));
00105 ha.process_spi_list = FALSE;
00106 list_init(&cfg->spi_list);
00107 ha.process_authorized_list = FALSE;
00108 list_init(&cfg->authorized_list);
00109 ha.process_fa_spi_list = FALSE;
00110 list_init(&cfg->fa_spi_list);
00111 ha.process_interfaces = FALSE;
00112 list_init(&cfg->interfaces);
00113
00114
00115 cfg->max_bindings = HA_DEFAULT_MAX_BINDINGS;
00116 cfg->ha_default_tunnel_lifetime = HA_DEFAULT_TUNNEL_LIFETIME;
00117 cfg->reg_error_reply_interval = HA_DEFAULT_REG_ERROR_REPLY_INTERVAL;
00118 cfg->syslog_facility = HA_DEFAULT_SYSLOG_FACILITY;
00119 cfg->udpport = HA_DEFAULT_REG_PORT;
00120 cfg->socket_priority = -1;
00121 cfg->enable_triangle_tunneling = TRUE;
00122 cfg->enable_reverse_tunneling = TRUE;
00123 cfg->pubkey_hash_method = HASH_METHOD_CHECK;
00124
00125 file = fopen(config_file, "r");
00126 if (file == NULL) {
00127 fprintf(stderr,
00128 "%s: Could not open configuration file '%s'.\n",
00129 program_name, config_file);
00130 return FALSE;
00131 }
00132 if (load_data(&ha, file, process_load_ha) == FALSE) {
00133 fprintf(stderr,
00134 "%s: Error while interpreting file '%s'!\n",
00135 program_name, config_file);
00136 fclose(file);
00137 cleanup_config(cfg);
00138 return FALSE;
00139 }
00140 fclose(file);
00141
00142 openlog("home agent", LOG_PID | LOG_CONS, cfg->syslog_facility);
00143
00144 return TRUE;
00145 }
00146
00147
00148 static int
00149 process_interfaces(struct load_ha_data *ha, char *key, char *data)
00150 {
00151 struct ha_config *cfg;
00152 struct interface_entry *iface;
00153 char *pos;
00154
00155 if (strcmp(key, "INTERFACES_END") == 0) {
00156 assert(ha->process_interfaces == TRUE);
00157 ha->process_interfaces = FALSE;
00158 return 0;
00159 }
00160
00161 cfg = ha->cfg;
00162 iface = malloc(sizeof(struct interface_entry));
00163 if (iface == NULL) {
00164 fprintf(stderr,
00165 "process_interfaces: not enough memory for "
00166 "struct interface_entry\n");
00167 return -1;
00168 }
00169 memset(iface, 0, sizeof(iface));
00170 list_init_node(&iface->node);
00171
00172 dynamics_strlcpy(iface->dev, key, IFNAMSIZ);
00173
00174 pos = data;
00175 while (*pos == ' ' || *pos == '\t') pos++;
00176 if (*pos == '\0' || sscanf(pos, "%d", &iface->ha_disc) != 1 ||
00177 (iface->ha_disc < 0 || iface->ha_disc > 1)) {
00178 fprintf(stderr,
00179 "process_interfaces: invalid ha_disc (interface=%s)\n",
00180 iface->dev);
00181 free(iface);
00182 return -1;
00183 }
00184
00185 while (*pos != ' ' && *pos != '\t' && *pos != '\0') pos++;
00186 while (*pos == ' ' || *pos == '\t') pos++;
00187 if (*pos == '\0' || sscanf(pos, "%d", &iface->agentadv) != 1) {
00188 fprintf(stderr, "process_interfaces: invalid agentadv "
00189 "(interface=%s)\n", iface->dev);
00190 free(iface);
00191 return -1;
00192 }
00193
00194 while (*pos != ' ' && *pos != '\t' && *pos != '\0') pos++;
00195 while (*pos == ' ' || *pos == '\t') pos++;
00196 if (*pos == '\0' || sscanf(pos, "%d", &iface->interval) != 1) {
00197 fprintf(stderr, "process_interfaces: invalid interval "
00198 "(interface=%s)\n", iface->dev);
00199 free(iface);
00200 return -1;
00201 }
00202
00203 if (iface->interval < 1) {
00204 fprintf(stderr, "process_interfaces: advertisement interval "
00205 "too short (must be at least one second)\n");
00206 free(iface);
00207 return -1;
00208 }
00209
00210 while (*pos != ' ' && *pos != '\t' && *pos != '\0') pos++;
00211 while (*pos == ' ' || *pos == '\t') pos++;
00212 iface->force_addr.s_addr = 0;
00213 if (*pos != '\0' && load_ip_address(pos, &iface->force_addr) != TRUE) {
00214 fprintf(stderr, "process_interfaces: invalid IP address "
00215 "(interface=%s)\n", iface->dev);
00216 free(iface);
00217 return -1;
00218 }
00219
00220 iface->icmp_sock = -1;
00221 iface->udp_sock = -1;
00222 iface->udp_bc_sock = -1;
00223 iface->udp_bc_sock2 = -1;
00224 list_add_tail(&cfg->interfaces, &iface->node);
00225
00226 return 0;
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 static int process_load_ha(void *voidptr, char *key, char *data)
00242 {
00243 struct load_ha_data *ha;
00244 struct ha_config *cfg;
00245
00246 ha = voidptr;
00247 cfg = ha->cfg;
00248
00249 if (ha->process_spi_list == TRUE) {
00250 return process_load_ha_spi_list(ha, key, data);
00251 }
00252 if (ha->process_authorized_list == TRUE) {
00253 return process_load_ha_authorized_list(ha, key, data);
00254 }
00255 if (ha->process_fa_spi_list == TRUE) {
00256 return process_load_fa_spi_list(ha, key, data);
00257 }
00258 if (ha->process_interfaces == TRUE) {
00259 return process_interfaces(ha, key, data);
00260 }
00261 if (strcmp(key, "MaxBindings") == 0) {
00262 if (load_int(data, &cfg->max_bindings) == TRUE) return 0;
00263 return -1;
00264 }
00265 if (strcmp(key, "HADefaultTunnelLifetime") == 0) {
00266 if (load_int(data, &cfg->ha_default_tunnel_lifetime) == TRUE) {
00267 return 0;
00268 }
00269 return -1;
00270 }
00271 if (strcmp(key, "RegErrorReplyInterval") == 0) {
00272 if (load_int(data, &cfg->reg_error_reply_interval) == TRUE) {
00273 return 0;
00274 }
00275 return -1;
00276 }
00277 if (strcmp(key, "SECURITY_BEGIN") == 0) {
00278 if (ha->process_authorized_list ||
00279 ha->process_spi_list ||
00280 ha->process_fa_spi_list || ha->process_interfaces) {
00281 fprintf(stderr, "List processing error while handling "
00282 "SECURITY_BEGIN\n");
00283 return -1;
00284 }
00285 ha->process_spi_list = TRUE;
00286 return 0;
00287 }
00288 if (strcmp(key, "AUTHORIZEDLIST_BEGIN") == 0) {
00289 if (ha->process_authorized_list ||
00290 ha->process_spi_list ||
00291 ha->process_fa_spi_list || ha->process_interfaces) {
00292 fprintf(stderr, "List processing error while handling "
00293 "AUTHORIZEDLIST_BEGIN\n");
00294 return -1;
00295 }
00296 ha->process_authorized_list = TRUE;
00297 return 0;
00298 }
00299 if (strcmp(key, "FA_SECURITY_BEGIN") == 0) {
00300 if (ha->process_authorized_list ||
00301 ha->process_spi_list ||
00302 ha->process_fa_spi_list || ha->process_interfaces) {
00303 fprintf(stderr, "List processing error while handling "
00304 "FA_SECURITY_BEGIN\n");
00305 return -1;
00306 }
00307 ha->process_fa_spi_list = TRUE;
00308 return 0;
00309 }
00310 if (strcmp(key, "INTERFACES_BEGIN") == 0) {
00311 if (ha->process_authorized_list ||
00312 ha->process_spi_list ||
00313 ha->process_fa_spi_list || ha->process_interfaces) {
00314 fprintf(stderr, "List processing error while handling "
00315 "INTERFACES_BEGIN\n");
00316 return -1;
00317 }
00318 ha->process_interfaces = TRUE;
00319 return 0;
00320 }
00321 if (strcmp(key, "SyslogFacility") == 0) {
00322 if (load_syslog_facility(data,
00323 &cfg->syslog_facility) == TRUE) {
00324 return 0;
00325 }
00326 return -1;
00327 }
00328 if (strcmp(key, "HAAPIReadSocketPath") == 0) {
00329 if (load_char_table(data, cfg->ha_api_read_socket_path,
00330 MAXFILENAMELEN) == TRUE) {
00331 return 0;
00332 }
00333 return -1;
00334 }
00335
00336
00337 if (strcmp(key, "HAAPIReadSocketGroup") == 0) {
00338 if (load_char_table(data, cfg->ha_api_read_socket_group,
00339 MAXGROUPNAMELEN) == TRUE) {
00340 return 0;
00341 }
00342 return -1;
00343 }
00344 if (strcmp(key, "HAAPIReadSocketOwner") == 0) {
00345 if (load_char_table(data, cfg->ha_api_read_socket_owner,
00346 MAXOWNERNAMELEN) == TRUE) {
00347 return 0;
00348 }
00349 return -1;
00350 }
00351 if (strcmp(key, "HAAPIReadSocketPermissions") == 0) {
00352 if (load_int(data,
00353 &cfg->ha_api_read_socket_permissions) == TRUE) {
00354 return 0;
00355 }
00356 return -1;
00357 }
00358 if (strcmp(key, "HAAPIAdminSocketPath") == 0) {
00359 if (load_char_table(data, cfg->ha_api_admin_socket_path,
00360 MAXFILENAMELEN) == TRUE) {
00361 return 0;
00362 }
00363 return -1;
00364 }
00365 if (strcmp(key, "HAAPIAdminSocketGroup") == 0) {
00366 if (load_char_table(data, cfg->ha_api_admin_socket_group,
00367 MAXGROUPNAMELEN) == TRUE) {
00368 return 0;
00369 }
00370 return -1;
00371 }
00372 if (strcmp(key, "HAAPIAdminSocketOwner") == 0) {
00373 if (load_char_table(data, cfg->ha_api_admin_socket_owner,
00374 MAXOWNERNAMELEN) == TRUE) {
00375 return 0;
00376 }
00377 return -1;
00378 }
00379 if (strcmp(key, "HAAPIAdminSocketPermissions") == 0) {
00380 if (load_int(data,
00381 &cfg->ha_api_admin_socket_permissions) == TRUE) {
00382 return 0;
00383 }
00384 return -1;
00385 }
00386 if (strcmp(key, "UDPPort") == 0) {
00387 if (load_int(data, &cfg->udpport) == TRUE)
00388 return 0;
00389 return -1;
00390 }
00391 if (strcmp(key, "SocketPriority") == 0) {
00392 if (load_int(data, &cfg->socket_priority) == TRUE) {
00393 return 0;
00394 }
00395 return -1;
00396 }
00397 if (strcmp(key, "EnableTriangleTunneling") == 0) {
00398 if (load_bool(data, &cfg->enable_triangle_tunneling) == TRUE) {
00399 return 0;
00400 }
00401 return -1;
00402 }
00403 if (strcmp(key, "EnableReverseTunneling") == 0) {
00404 if (load_bool(data, &cfg->enable_reverse_tunneling) == TRUE) {
00405 return 0;
00406 }
00407 return -1;
00408 }
00409 if (strcmp(key, "PublicKeyHashMethod") == 0) {
00410 if (load_int(data, &cfg->pubkey_hash_method) == TRUE) {
00411 if (cfg->pubkey_hash_method != HASH_METHOD_NONE &&
00412 cfg->pubkey_hash_method != HASH_METHOD_CHECK &&
00413 cfg->pubkey_hash_method != HASH_METHOD_REQUIRE) {
00414 fprintf(stderr,
00415 "Invalid PublicKeyHashMethod %i\n",
00416 cfg->pubkey_hash_method);
00417 return -1;
00418 }
00419 return 0;
00420 }
00421 return -1;
00422 }
00423 if (strcmp(key, "SHAIPAddress") == 0) {
00424 if (load_ip_address(data, &cfg->sha_addr) == TRUE)
00425 return 0;
00426 return -1;
00427 }
00428 if (strcmp(key, "PrivateHAIdentifier") == 0) {
00429 if (load_int(data, (int *) &cfg->priv_ha) == TRUE)
00430 return 0;
00431 return -1;
00432 }
00433 if (strcmp(key, "NetworkAccessIdentifier") == 0) {
00434 if (load_nai(data, cfg->ha_nai, &cfg->ha_nai_len) == TRUE)
00435 return 0;
00436 return -1;
00437 }
00438
00439 if (strcmp(key, "dhcp") == 0) {
00440 if (load_char_table(data, cfg->dhcp_if,
00441 MAXFILENAMELEN) == TRUE) {
00442 return 0;
00443 }
00444 return -1;
00445 }
00446
00447 if (strcmp(key, "END") == 0) return 1;
00448 return -1;
00449 }
00450
00451
00452
00453 static int process_load_ha_spi_list(struct load_ha_data *ha, char *key,
00454 char *data)
00455 {
00456 struct ha_config *cfg;
00457 struct spi_entry *spi;
00458 char *pos;
00459 int res;
00460
00461 if (strcmp(key, "SECURITY_END") == 0) {
00462 ASSERT(ha->process_spi_list == TRUE);
00463 ha->process_spi_list = FALSE;
00464 return 0;
00465 }
00466
00467 cfg = ha->cfg;
00468 spi = malloc(sizeof(struct spi_entry));
00469 if (spi == NULL) {
00470 fprintf(stderr,
00471 "process_load_ha_spi_list: not enough memory for "
00472 "struct spi_entry\n");
00473 return -1;
00474 }
00475
00476 if (key[0] == '0' && key[1] == 'x')
00477 res = sscanf(key, "%x", &spi->spi);
00478 else
00479 res = sscanf(key, "%d", &spi->spi);
00480
00481 if (res != 1) {
00482 fprintf(stderr,
00483 "process_load_ha_spi_list: invalid SPI number\n");
00484 free(spi);
00485 return -1;
00486 }
00487 list_init_node(&spi->node);
00488
00489 pos = data;
00490
00491 while (*pos == ' ' || *pos == '\t') pos++;
00492 if (*pos == '\0' || sscanf(pos, "%d", &spi->auth_alg) != 1) {
00493 fprintf(stderr,
00494 "process_load_ha_spi_list: invalid authentication "
00495 "algorithm number\n");
00496 free(spi);
00497 return -1;
00498 }
00499 if (!auth_supported_auth_alg(spi->auth_alg)) {
00500 fprintf(stderr, "process_load_ha_spi_list: unsupported "
00501 "authentication algorithm %i\n", spi->auth_alg);
00502 free(spi);
00503 return -1;
00504 }
00505
00506 while (*pos != ' ' && *pos != '\t' && *pos != '\0') pos++;
00507 while (*pos == ' ' || *pos == '\t') pos++;
00508 if (*pos == '\0' || sscanf(pos, "%d", &spi->replay_method) != 1) {
00509 fprintf(stderr,
00510 "process_load_ha_spi_list: invalid replay method "
00511 "number\n");
00512 free(spi);
00513 return -1;
00514 }
00515 if (spi->replay_method < 0 || spi->replay_method > 2) {
00516 fprintf(stderr, "process_load_ha_spi_list: unsupported replay "
00517 "method %i\n", spi->replay_method);
00518 free(spi);
00519 return -1;
00520 }
00521
00522 while (*pos != ' ' && *pos != '\t' && *pos != '\0') pos++;
00523 while (*pos == ' ' || *pos == '\t') pos++;
00524 if (*pos == '\0' ||
00525 sscanf(pos, "%d", &spi->timestamp_tolerance) != 1) {
00526 fprintf(stderr,
00527 "process_load_ha_spi_list: invalid timestamp "
00528 "tolerance\n");
00529 free(spi);
00530 return -1;
00531 }
00532
00533 while (*pos != ' ' && *pos != '\t' && *pos != '\0') pos++;
00534 while (*pos == ' ' || *pos == '\t') pos++;
00535 if (*pos == '\0' || sscanf(pos, "%d", &spi->max_lifetime) != 1) {
00536 fprintf(stderr,
00537 "process_load_ha_spi_list: invalid maximum "
00538 "lifetime\n");
00539 free(spi);
00540 return -1;
00541 }
00542
00543 while (*pos != ' ' && *pos != '\t' && *pos != '\0') pos++;
00544 while (*pos == ' ' || *pos == '\t') pos++;
00545 if (*pos == '\0' || load_hex_table(pos, spi->shared_secret,
00546 MAXSHAREDSECRETLEN,
00547 &spi->shared_secret_len) == FALSE) {
00548 fprintf(stderr,
00549 "process_load_ha_spi_list: invalid shared secret\n");
00550 free(spi);
00551 return -1;
00552 }
00553
00554 ASSERT(spi->shared_secret_len >= 0);
00555 ASSERT(spi->shared_secret_len <= MAXSHAREDSECRETLEN);
00556 list_add_tail(&cfg->spi_list, &spi->node);
00557
00558 return 0;
00559 }
00560
00561
00562
00563 static int process_load_ha_authorized_list(struct load_ha_data *ha, char *key,
00564 char *data)
00565 {
00566 struct ha_config *cfg;
00567 struct authorized_entry *auth;
00568
00569 if (strcmp(key, "AUTHORIZEDLIST_END") == 0) {
00570 ASSERT(ha->process_authorized_list == TRUE);
00571 ha->process_authorized_list = FALSE;
00572 return 0;
00573 }
00574
00575 cfg = ha->cfg;
00576 auth = malloc(sizeof(struct authorized_entry));
00577 if (auth == NULL) {
00578 fprintf(stderr,
00579 "process_load_ha_authorized_list: not enough memory "
00580 "for struct authorized_entry\n");
00581 return -1;
00582 }
00583 list_init_node(&auth->node);
00584 if (sscanf(key, "%d-%d", &auth->spi_low, &auth->spi_high) == 2) {
00585 if (auth->spi_low > auth->spi_high) {
00586 fprintf(stderr,
00587 "process_load_ha_authorized_list: lower SPI "
00588 "greater than higher SPI\n");
00589 free(auth);
00590 return -1;
00591 }
00592 } else if (sscanf(key, "%d", &auth->spi_low) == 1) {
00593 auth->spi_high = auth->spi_low;
00594 } else {
00595 fprintf(stderr,
00596 "process_load_ha_authorized_list: invalid SPI '%s'\n",
00597 key);
00598 free(auth);
00599 return -1;
00600 }
00601 while(*data == ' ' || *data == '\t') {
00602 data++;
00603 }
00604 if (load_net_address(data, &auth->network, &auth->netmask) != TRUE) {
00605 printf("process_load_ha_authorized_list: invalid "
00606 "Mobile Node home IP network address\n");
00607 free(auth);
00608 return -1;
00609 }
00610
00611 list_add_tail(&cfg->authorized_list, &auth->node);
00612 return 0;
00613 }
00614
00615 static int process_load_fa_spi_list(struct load_ha_data *ha, char *key,
00616 char *data)
00617 {
00618 struct ha_config *cfg;
00619 struct fa_spi_entry *spi;
00620 char *pos;
00621 int res;
00622
00623 if (strcmp(key, "FA_SECURITY_END") == 0) {
00624 ASSERT(ha->process_fa_spi_list == TRUE);
00625 ha->process_fa_spi_list = FALSE;
00626 return 0;
00627 }
00628
00629 cfg = ha->cfg;
00630 spi = malloc(sizeof(struct fa_spi_entry));
00631 if (spi == NULL) {
00632 fprintf(stderr,
00633 "process_load_fa_spi_list: not enough memory for "
00634 "struct spi_entry\n");
00635 return -1;
00636 }
00637
00638 list_init_node(&spi->node);
00639
00640 if (key[0] == '0' && key[1] == 'x')
00641 res = sscanf(key, "%x", &spi->spi);
00642 else
00643 res = sscanf(key, "%d", &spi->spi);
00644
00645 if (res != 1) {
00646 fprintf(stderr,
00647 "process_load_fa_spi_list: invalid SPI number\n");
00648 free(spi);
00649 return -1;
00650 }
00651
00652 pos = data;
00653
00654 while (*pos == ' ' || *pos == '\t') pos++;
00655 if (load_ip_address(pos, &spi->addr) != TRUE) {
00656 fprintf(stderr,
00657 "process_load_fa_authorized_list: invalid "
00658 "IP address\n");
00659 free(spi);
00660 return -1;
00661 }
00662
00663 while (*pos != ' ' && *pos != '\t' && *pos != '\0') pos++;
00664 while (*pos == ' ' || *pos == '\t') pos++;
00665 if (*pos == '\0' || sscanf(pos, "%d", &spi->alg) != 1) {
00666 fprintf(stderr,
00667 "process_load_fa_spi_list: invalid algorithm "
00668 "number\n");
00669 free(spi);
00670 return -1;
00671 }
00672
00673 if (!auth_supported_auth_alg(spi->alg)) {
00674 fprintf(stderr, "process_load_fa_spi_list: unsupported "
00675 "algorithm %i\n", spi->alg);
00676 free(spi);
00677 return -1;
00678 }
00679
00680 while (*pos != ' ' && *pos != '\t' && *pos != '\0') pos++;
00681 while (*pos == ' ' || *pos == '\t') pos++;
00682 if (*pos == '\0' || load_hex_table(pos, spi->shared_secret,
00683 MAXSHAREDSECRETLEN,
00684 &spi->shared_secret_len) == FALSE) {
00685 fprintf(stderr,
00686 "process_load_fa_spi_list: invalid shared secret\n");
00687 free(spi);
00688 return -1;
00689 }
00690
00691 ASSERT(spi->shared_secret_len >= 0);
00692 ASSERT(spi->shared_secret_len <= MAXSHAREDSECRETLEN);
00693 list_add_tail(&cfg->fa_spi_list, &spi->node);
00694
00695 return 0;
00696 }