📄 confread.c
字号:
/* allocate the string */ s = (*the_strings)[field]; s = xrealloc(s, len); strncat(s, " ", len); strncat(s, kw->string, len); (*the_strings)[field] = s; } (*set_strings)[field] = TRUE; break; case kt_rsakey: case kt_loose_enum: assert(field < KEY_STRINGS_MAX); assert(field < KEY_NUMERIC_MAX); if((*set_options)[field]) { if(!permitreplace) { starter_log(LOG_LEVEL_INFO , "duplicate key '%s' in conn %s while processing def %s" , kw->keyword.keydef->keyname , conn->name , sl->name); /* only fatal if we try to change values */ if((*the_options)[field] != kw->number || !((*the_options)[field] == LOOSE_ENUM_OTHER && kw->number == LOOSE_ENUM_OTHER && kw->keyword.string != NULL && (*the_strings)[field] != NULL && strcmp(kw->keyword.string, (*the_strings)[field])==0)) { err++; break; } } } (*the_options)[field] = kw->number; if(kw->number == LOOSE_ENUM_OTHER) { assert(kw->keyword.string != NULL); if((*the_strings)[field]) free((*the_strings)[field]); (*the_strings)[field] = xstrdup(kw->keyword.string); } (*set_options)[field] = TRUE; break; case kt_list: case kt_bool: case kt_invertbool: case kt_enum: case kt_number: case kt_time: case kt_percent: /* all treated as a number for now */ assert(field < KEY_NUMERIC_MAX); if((*set_options)[field]) { if(!permitreplace) { starter_log(LOG_LEVEL_INFO , "duplicate key '%s' in conn %s while processing def %s" , kw->keyword.keydef->keyname , conn->name , sl->name); if((*the_options)[field] != kw->number) { err++; break; } } } (*the_options)[field] = kw->number; (*set_options)[field] = TRUE; break; } } return err;}static int load_conn_basic(struct starter_conn *conn , struct section_list *sl){ int err; memset(conn->strings_set, 0, sizeof(conn->strings_set)); memset(conn->options_set, 0, sizeof(conn->options_set)); memset(conn->left.strings_set, 0, sizeof(conn->left.strings_set)); memset(conn->left.options_set, 0, sizeof(conn->left.options_set)); memset(conn->right.strings_set, 0, sizeof(conn->left.strings_set)); memset(conn->right.options_set, 0, sizeof(conn->left.options_set)); /* turn all of the keyword/value pairs into options/strings in left/right */ err = translate_conn(conn, sl, TRUE); /* now, process the also's */ if (conn->alsos) free_list(conn->alsos); conn->alsos = new_list(conn->strings[KSF_ALSO]); return err;}static int load_conn (struct starter_config *cfg , struct starter_conn *conn , struct config_parsed *cfgp , struct section_list *sl , bool alsoprocessing , char **perr){ unsigned int err; char **alsos; char **newalsos; int newalsoplace; int alsoplace; int alsosize; struct section_list *sl1; err = 0; err += load_conn_basic(conn, sl); if(err) return err; if(conn->strings[KSF_ALSO] != NULL && !alsoprocessing) { starter_log(LOG_LEVEL_INFO , "also= is not valid in section '%s'" , sl->name); return 1; } /* now, process the also's */ if (conn->alsos) free_list(conn->alsos); conn->alsos = new_list(conn->strings[KSF_ALSO]); if(alsoprocessing && conn->alsos) { /* reset all of the "beenhere" flags */ for(sl1 = cfgp->sections.tqh_first; sl1 != NULL; sl1 = sl1->link.tqe_next) { sl1->beenhere = FALSE; } sl->beenhere = TRUE; /* count them */ alsos = conn->alsos; conn->alsos = NULL; for(alsosize=0; alsos[alsosize]!=NULL; alsosize++); alsoplace = 0; while(alsos != NULL && alsos[alsoplace] != NULL && alsoplace < alsosize && alsoplace < ALSO_LIMIT) { /* * for each also= listed, go find this section's keyword list, and * load it as well. This may extend the also= list (and the end), * which we handle by zeroing the also list, and adding to it after * checking for duplicates. */ for(sl1 = cfgp->sections.tqh_first; sl1 != NULL && strcasecmp(alsos[alsoplace], sl1->name) != 0; sl1 = sl1->link.tqe_next); starter_log(LOG_LEVEL_DEBUG, "\twhile loading conn '%s' processing %s" , conn->name, alsos[alsoplace]); /* * if we found something that matches by name, and we haven't be there, then * process it. */ if(sl1 && !sl1->beenhere) { conn->strings_set[KSF_ALSO]=FALSE; if(conn->strings[KSF_ALSO]) free(conn->strings[KSF_ALSO]); conn->strings[KSF_ALSO]=NULL; sl1->beenhere = TRUE; /* translate things, but do not replace earlier settings */ err += translate_conn(conn, sl1, FALSE); if(conn->strings[KSF_ALSO]) { /* now, check out the KSF_ALSO, and extend list if we need to */ newalsos = new_list(conn->strings[KSF_ALSO]); if(newalsos && newalsos[0]!=NULL) { /* count them */ for(newalsoplace=0; newalsos[newalsoplace]!=NULL; newalsoplace++); /* extend conn->alsos */ alsos = xrealloc(alsos, (alsosize+newalsoplace) * sizeof(char *)); for(newalsoplace=0; newalsos[newalsoplace]!=NULL; newalsoplace++) { assert(conn != NULL); assert(conn->name != NULL); starter_log(LOG_LEVEL_DEBUG , "\twhile processing section '%s' added also=%s" , sl1->name, newalsos[newalsoplace]); alsos[alsosize++]=xstrdup(newalsos[newalsoplace]); } } free_list(newalsos); } } alsoplace++; } if(alsoplace >= ALSO_LIMIT) { starter_log(LOG_LEVEL_INFO , "while loading conn '%s', too many also= used at section %s. Limit is %d" , conn->name , conn->alsos[alsoplace] , ALSO_LIMIT); return 1; } if(conn->alsos != alsos && conn->alsos != NULL) { free_list(conn->alsos); } conn->alsos = alsos; } /* preview of getting rid of transport mode */ if(conn->options[KBF_TYPE] == KS_TRANSPORT) { extern struct keyword_enum_values kw_type_list; starter_log(LOG_LEVEL_INFO, "conn %s - only tunnel mode is supported, not %s" , conn->name , keyword_name(&kw_type_list, conn->options[KBF_TYPE])); POLICY_ONLY_CONN(conn); } KW_POLICY_FLAG(KBF_TYPE, POLICY_TUNNEL); KW_POLICY_FLAG(KBF_COMPRESS, POLICY_COMPRESS); KW_POLICY_FLAG(KBF_PFS, POLICY_PFS); /* reset authby flags */ conn->policy &= ~(POLICY_ID_AUTH_MASK); conn->policy |= conn->options[KBF_AUTHBY]; KW_POLICY_FLAG(KBF_REKEY, POLICY_DONT_REKEY); KW_POLICY_FLAG(KBF_COMPRESS, POLICY_COMPRESS); err += validate_end(conn, &conn->left, TRUE, perr); err += validate_end(conn, &conn->right, FALSE,perr); conn->desired_state = conn->options[KBF_AUTO]; return err;} static void conn_default (struct starter_conn *conn, struct starter_conn *def){ int i; /* structure copy to start */ *conn = *def; /* unlink it */ memset(&conn->link, 0, sizeof(conn->link));#define CONN_STR(v) if (v) v=xstrdup(v) CONN_STR(conn->left.iface); CONN_STR(conn->left.id); CONN_STR(conn->left.rsakey1); CONN_STR(conn->left.rsakey2); CONN_STR(conn->right.iface); CONN_STR(conn->right.id); CONN_STR(conn->right.rsakey1); CONN_STR(conn->right.rsakey2); for(i=0; i<KSCF_MAX; i++) { CONN_STR(conn->left.strings[i]); CONN_STR(conn->right.strings[i]); } for(i=0; i<KNCF_MAX; i++) { conn->left.options[i] = def->left.options[i]; conn->right.options[i]= def->right.options[i]; } for(i=0 ;i<KSF_MAX; i++) { CONN_STR(conn->strings[i]); } for(i=0 ;i<KBF_MAX; i++) { conn->options[i] = def->options[i]; } CONN_STR(conn->esp); CONN_STR(conn->ike);#undef CONN_STR}struct starter_config *confread_load(const char *file, char **perr){ struct starter_config *cfg = NULL; struct config_parsed *cfgp; struct section_list *sconn; struct starter_conn *conn; unsigned int err = 0; /** * Load file */ cfgp = parser_load_conf(file, perr); if (!cfgp) return NULL; cfg = (struct starter_config *)malloc(sizeof(struct starter_config)); if (!cfg) { if (perr) *perr = xstrdup("can't allocate mem in confread_load()"); parser_free_conf(cfgp); return NULL; } /** * Set default values */ default_values(cfg); /** * Load setup */ err += load_setup(cfg, cfgp, perr); if(err) {return NULL;} /** * Find %default conn * */ for(sconn = cfgp->sections.tqh_first; (!err) && sconn != NULL; sconn = sconn->link.tqe_next) { if (strcmp(sconn->name,"%default")==0) { starter_log(LOG_LEVEL_DEBUG, "Loading default conn"); err += load_conn (cfg, &cfg->conn_default, cfgp, sconn, FALSE, perr); if(err == 0) { cfg->got_default = TRUE; } } } /** * Load other conns */ for(sconn = cfgp->sections.tqh_first; (!err) && sconn != NULL; sconn = sconn->link.tqe_next) { if (strcmp(sconn->name,"%default")==0) continue; starter_log(LOG_LEVEL_DEBUG, "Loading conn %s", sconn->name); conn = (struct starter_conn *)malloc(sizeof(struct starter_conn)); memset(conn, 0, sizeof(struct starter_conn)); if (!conn) { if (perr) *perr = xstrdup("can't allocate mem in confread_load()"); parser_free_conf(cfgp); confread_free(cfg); return NULL; } if(cfg->got_default) { conn_default(conn, &cfg->conn_default); } conn->name = xstrdup(sconn->name); conn->desired_state = STARTUP_NO; conn->state = STATE_IGNORE; TAILQ_INSERT_TAIL(&cfg->conns, conn, link); err += load_conn (cfg, conn, cfgp, sconn, TRUE, perr); if(err == 0) { conn->state = STATE_LOADED; } } parser_free_conf(cfgp); if (err) { confread_free(cfg); cfg = NULL; } return cfg;}#define FREE_STR(v) { if (v) { free(v); v=NULL; } }#define FREE_LST(v) { if (v) { free_list(v); v=NULL; } }static void confread_free_conn(struct starter_conn *conn){ int i; FREE_STR(conn->left.iface); FREE_STR(conn->left.id); FREE_STR(conn->left.rsakey1); FREE_STR(conn->left.rsakey2); FREE_STR(conn->right.iface); FREE_STR(conn->right.id); FREE_STR(conn->right.rsakey1); FREE_STR(conn->right.rsakey2); for(i=0; i<KSCF_MAX; i++) { FREE_STR(conn->left.strings[i]); FREE_STR(conn->right.strings[i]); } for(i=0 ;i<KSF_MAX; i++) { FREE_STR(conn->strings[i]); }#ifdef ALG_PATCH FREE_STR(conn->esp); FREE_STR(conn->ike);#endif#ifdef VIRTUAL_IP FREE_STR(conn->left.virt); FREE_STR(conn->right.virt);#endif}void confread_free(struct starter_config *cfg){ int i; struct starter_conn *conn, *c; FREE_LST(cfg->setup.interfaces);#ifdef VIRTUAL_IP FREE_STR(cfg->setup.virtual_private);#endif for(i=0 ;i<KSF_MAX; i++) { FREE_STR(cfg->setup.strings[i]); } confread_free_conn(&(cfg->conn_default)); for(conn = cfg->conns.tqh_first; conn != NULL; ) { c = conn; conn = conn->link.tqe_next; confread_free_conn(c); free(c); } free(cfg);}#undef FREE_STR/* * Local Variables: * c-basic-offset:4 * c-style: pluto * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -