confparse.c 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189
  1. /* Copyright (c) 2001 Matej Pfajfar.
  2. * Copyright (c) 2001-2004, Roger Dingledine.
  3. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  4. * Copyright (c) 2007-2017, The Tor Project, Inc. */
  5. /* See LICENSE for licensing information */
  6. /**
  7. * \file confparse.c
  8. *
  9. * \brief Back-end for parsing and generating key-value files, used to
  10. * implement the torrc file format and the state file.
  11. *
  12. * This module is used by config.c to parse and encode torrc
  13. * configuration files, and by statefile.c to parse and encode the
  14. * $DATADIR/state file.
  15. *
  16. * To use this module, its callers provide an instance of
  17. * config_format_t to describe the mappings from a set of configuration
  18. * options to a number of fields in a C structure. With this mapping,
  19. * the functions here can convert back and forth between the C structure
  20. * specified, and a linked list of key-value pairs.
  21. */
  22. #include "or.h"
  23. #include "confparse.h"
  24. #include "routerset.h"
  25. static uint64_t config_parse_memunit(const char *s, int *ok);
  26. static int config_parse_msec_interval(const char *s, int *ok);
  27. static int config_parse_interval(const char *s, int *ok);
  28. static void config_reset(const config_format_t *fmt, void *options,
  29. const config_var_t *var, int use_defaults);
  30. /** Allocate an empty configuration object of a given format type. */
  31. void *
  32. config_new(const config_format_t *fmt)
  33. {
  34. void *opts = tor_malloc_zero(fmt->size);
  35. *(uint32_t*)STRUCT_VAR_P(opts, fmt->magic_offset) = fmt->magic;
  36. CONFIG_CHECK(fmt, opts);
  37. return opts;
  38. }
  39. /*
  40. * Functions to parse config options
  41. */
  42. /** If <b>option</b> is an official abbreviation for a longer option,
  43. * return the longer option. Otherwise return <b>option</b>.
  44. * If <b>command_line</b> is set, apply all abbreviations. Otherwise, only
  45. * apply abbreviations that work for the config file and the command line.
  46. * If <b>warn_obsolete</b> is set, warn about deprecated names. */
  47. const char *
  48. config_expand_abbrev(const config_format_t *fmt, const char *option,
  49. int command_line, int warn_obsolete)
  50. {
  51. int i;
  52. if (! fmt->abbrevs)
  53. return option;
  54. for (i=0; fmt->abbrevs[i].abbreviated; ++i) {
  55. /* Abbreviations are case insensitive. */
  56. if (!strcasecmp(option,fmt->abbrevs[i].abbreviated) &&
  57. (command_line || !fmt->abbrevs[i].commandline_only)) {
  58. if (warn_obsolete && fmt->abbrevs[i].warn) {
  59. log_warn(LD_CONFIG,
  60. "The configuration option '%s' is deprecated; "
  61. "use '%s' instead.",
  62. fmt->abbrevs[i].abbreviated,
  63. fmt->abbrevs[i].full);
  64. }
  65. /* Keep going through the list in case we want to rewrite it more.
  66. * (We could imagine recursing here, but I don't want to get the
  67. * user into an infinite loop if we craft our list wrong.) */
  68. option = fmt->abbrevs[i].full;
  69. }
  70. }
  71. return option;
  72. }
  73. /** If <b>key</b> is a deprecated configuration option, return the message
  74. * explaining why it is deprecated (which may be an empty string). Return NULL
  75. * if it is not deprecated. The <b>key</b> field must be fully expanded. */
  76. const char *
  77. config_find_deprecation(const config_format_t *fmt, const char *key)
  78. {
  79. if (BUG(fmt == NULL) || BUG(key == NULL))
  80. return NULL;
  81. if (fmt->deprecations == NULL)
  82. return NULL;
  83. const config_deprecation_t *d;
  84. for (d = fmt->deprecations; d->name; ++d) {
  85. if (!strcasecmp(d->name, key)) {
  86. return d->why_deprecated ? d->why_deprecated : "";
  87. }
  88. }
  89. return NULL;
  90. }
  91. /** As config_find_option, but return a non-const pointer. */
  92. config_var_t *
  93. config_find_option_mutable(config_format_t *fmt, const char *key)
  94. {
  95. int i;
  96. size_t keylen = strlen(key);
  97. if (!keylen)
  98. return NULL; /* if they say "--" on the command line, it's not an option */
  99. /* First, check for an exact (case-insensitive) match */
  100. for (i=0; fmt->vars[i].name; ++i) {
  101. if (!strcasecmp(key, fmt->vars[i].name)) {
  102. return &fmt->vars[i];
  103. }
  104. }
  105. /* If none, check for an abbreviated match */
  106. for (i=0; fmt->vars[i].name; ++i) {
  107. if (!strncasecmp(key, fmt->vars[i].name, keylen)) {
  108. log_warn(LD_CONFIG, "The abbreviation '%s' is deprecated. "
  109. "Please use '%s' instead",
  110. key, fmt->vars[i].name);
  111. return &fmt->vars[i];
  112. }
  113. }
  114. /* Okay, unrecognized option */
  115. return NULL;
  116. }
  117. /** If <b>key</b> is a configuration option, return the corresponding const
  118. * config_var_t. Otherwise, if <b>key</b> is a non-standard abbreviation,
  119. * warn, and return the corresponding const config_var_t. Otherwise return
  120. * NULL.
  121. */
  122. const config_var_t *
  123. config_find_option(const config_format_t *fmt, const char *key)
  124. {
  125. return config_find_option_mutable((config_format_t*)fmt, key);
  126. }
  127. /** Return the number of option entries in <b>fmt</b>. */
  128. static int
  129. config_count_options(const config_format_t *fmt)
  130. {
  131. int i;
  132. for (i=0; fmt->vars[i].name; ++i)
  133. ;
  134. return i;
  135. }
  136. /*
  137. * Functions to assign config options.
  138. */
  139. /** <b>c</b>-\>key is known to be a real key. Update <b>options</b>
  140. * with <b>c</b>-\>value and return 0, or return -1 if bad value.
  141. *
  142. * Called from config_assign_line() and option_reset().
  143. */
  144. static int
  145. config_assign_value(const config_format_t *fmt, void *options,
  146. config_line_t *c, char **msg)
  147. {
  148. int i, ok;
  149. const config_var_t *var;
  150. void *lvalue;
  151. CONFIG_CHECK(fmt, options);
  152. var = config_find_option(fmt, c->key);
  153. tor_assert(var);
  154. lvalue = STRUCT_VAR_P(options, var->var_offset);
  155. switch (var->type) {
  156. case CONFIG_TYPE_PORT:
  157. if (!strcasecmp(c->value, "auto")) {
  158. *(int *)lvalue = CFG_AUTO_PORT;
  159. break;
  160. }
  161. /* fall through */
  162. case CONFIG_TYPE_INT:
  163. case CONFIG_TYPE_UINT:
  164. i = (int)tor_parse_long(c->value, 10,
  165. var->type==CONFIG_TYPE_INT ? INT_MIN : 0,
  166. var->type==CONFIG_TYPE_PORT ? 65535 : INT_MAX,
  167. &ok, NULL);
  168. if (!ok) {
  169. tor_asprintf(msg,
  170. "Int keyword '%s %s' is malformed or out of bounds.",
  171. c->key, c->value);
  172. return -1;
  173. }
  174. *(int *)lvalue = i;
  175. break;
  176. case CONFIG_TYPE_CSV_INTERVAL: {
  177. /* We used to have entire smartlists here. But now that all of our
  178. * download schedules use exponential backoff, only the first part
  179. * matters. */
  180. const char *comma = strchr(c->value, ',');
  181. const char *val = c->value;
  182. char *tmp = NULL;
  183. if (comma) {
  184. tmp = tor_strndup(c->value, comma - c->value);
  185. val = tmp;
  186. }
  187. i = config_parse_interval(val, &ok);
  188. if (!ok) {
  189. tor_asprintf(msg,
  190. "Interval '%s %s' is malformed or out of bounds.",
  191. c->key, c->value);
  192. return -1;
  193. }
  194. *(int *)lvalue = i;
  195. tor_free(tmp);
  196. break;
  197. }
  198. case CONFIG_TYPE_INTERVAL: {
  199. i = config_parse_interval(c->value, &ok);
  200. if (!ok) {
  201. tor_asprintf(msg,
  202. "Interval '%s %s' is malformed or out of bounds.",
  203. c->key, c->value);
  204. return -1;
  205. }
  206. *(int *)lvalue = i;
  207. break;
  208. }
  209. case CONFIG_TYPE_MSEC_INTERVAL: {
  210. i = config_parse_msec_interval(c->value, &ok);
  211. if (!ok) {
  212. tor_asprintf(msg,
  213. "Msec interval '%s %s' is malformed or out of bounds.",
  214. c->key, c->value);
  215. return -1;
  216. }
  217. *(int *)lvalue = i;
  218. break;
  219. }
  220. case CONFIG_TYPE_MEMUNIT: {
  221. uint64_t u64 = config_parse_memunit(c->value, &ok);
  222. if (!ok) {
  223. tor_asprintf(msg,
  224. "Value '%s %s' is malformed or out of bounds.",
  225. c->key, c->value);
  226. return -1;
  227. }
  228. *(uint64_t *)lvalue = u64;
  229. break;
  230. }
  231. case CONFIG_TYPE_BOOL:
  232. i = (int)tor_parse_long(c->value, 10, 0, 1, &ok, NULL);
  233. if (!ok) {
  234. tor_asprintf(msg,
  235. "Boolean '%s %s' expects 0 or 1.",
  236. c->key, c->value);
  237. return -1;
  238. }
  239. *(int *)lvalue = i;
  240. break;
  241. case CONFIG_TYPE_AUTOBOOL:
  242. if (!strcmp(c->value, "auto"))
  243. *(int *)lvalue = -1;
  244. else if (!strcmp(c->value, "0"))
  245. *(int *)lvalue = 0;
  246. else if (!strcmp(c->value, "1"))
  247. *(int *)lvalue = 1;
  248. else {
  249. tor_asprintf(msg, "Boolean '%s %s' expects 0, 1, or 'auto'.",
  250. c->key, c->value);
  251. return -1;
  252. }
  253. break;
  254. case CONFIG_TYPE_STRING:
  255. case CONFIG_TYPE_FILENAME:
  256. tor_free(*(char **)lvalue);
  257. *(char **)lvalue = tor_strdup(c->value);
  258. break;
  259. case CONFIG_TYPE_DOUBLE:
  260. *(double *)lvalue = atof(c->value);
  261. break;
  262. case CONFIG_TYPE_ISOTIME:
  263. if (parse_iso_time(c->value, (time_t *)lvalue)) {
  264. tor_asprintf(msg,
  265. "Invalid time '%s' for keyword '%s'", c->value, c->key);
  266. return -1;
  267. }
  268. break;
  269. case CONFIG_TYPE_ROUTERSET:
  270. if (*(routerset_t**)lvalue) {
  271. routerset_free(*(routerset_t**)lvalue);
  272. }
  273. *(routerset_t**)lvalue = routerset_new();
  274. if (routerset_parse(*(routerset_t**)lvalue, c->value, c->key)<0) {
  275. tor_asprintf(msg, "Invalid exit list '%s' for option '%s'",
  276. c->value, c->key);
  277. return -1;
  278. }
  279. break;
  280. case CONFIG_TYPE_CSV:
  281. if (*(smartlist_t**)lvalue) {
  282. SMARTLIST_FOREACH(*(smartlist_t**)lvalue, char *, cp, tor_free(cp));
  283. smartlist_clear(*(smartlist_t**)lvalue);
  284. } else {
  285. *(smartlist_t**)lvalue = smartlist_new();
  286. }
  287. smartlist_split_string(*(smartlist_t**)lvalue, c->value, ",",
  288. SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  289. break;
  290. case CONFIG_TYPE_LINELIST:
  291. case CONFIG_TYPE_LINELIST_S:
  292. {
  293. config_line_t *lastval = *(config_line_t**)lvalue;
  294. if (lastval && lastval->fragile) {
  295. if (c->command != CONFIG_LINE_APPEND) {
  296. config_free_lines(lastval);
  297. *(config_line_t**)lvalue = NULL;
  298. } else {
  299. lastval->fragile = 0;
  300. }
  301. }
  302. config_line_append((config_line_t**)lvalue, c->key, c->value);
  303. }
  304. break;
  305. case CONFIG_TYPE_OBSOLETE:
  306. log_warn(LD_CONFIG, "Skipping obsolete configuration option '%s'", c->key);
  307. break;
  308. case CONFIG_TYPE_LINELIST_V:
  309. tor_asprintf(msg,
  310. "You may not provide a value for virtual option '%s'", c->key);
  311. return -1;
  312. default:
  313. tor_assert(0);
  314. break;
  315. }
  316. return 0;
  317. }
  318. /** Mark every linelist in <b>options</b> "fragile", so that fresh assignments
  319. * to it will replace old ones. */
  320. static void
  321. config_mark_lists_fragile(const config_format_t *fmt, void *options)
  322. {
  323. int i;
  324. tor_assert(fmt);
  325. tor_assert(options);
  326. for (i = 0; fmt->vars[i].name; ++i) {
  327. const config_var_t *var = &fmt->vars[i];
  328. config_line_t *list;
  329. if (var->type != CONFIG_TYPE_LINELIST &&
  330. var->type != CONFIG_TYPE_LINELIST_V)
  331. continue;
  332. list = *(config_line_t **)STRUCT_VAR_P(options, var->var_offset);
  333. if (list)
  334. list->fragile = 1;
  335. }
  336. }
  337. void
  338. warn_deprecated_option(const char *what, const char *why)
  339. {
  340. const char *space = (why && strlen(why)) ? " " : "";
  341. log_warn(LD_CONFIG, "The %s option is deprecated, and will most likely "
  342. "be removed in a future version of Tor.%s%s (If you think this is "
  343. "a mistake, please let us know!)",
  344. what, space, why);
  345. }
  346. /** If <b>c</b> is a syntactically valid configuration line, update
  347. * <b>options</b> with its value and return 0. Otherwise return -1 for bad
  348. * key, -2 for bad value.
  349. *
  350. * If <b>clear_first</b> is set, clear the value first. Then if
  351. * <b>use_defaults</b> is set, set the value to the default.
  352. *
  353. * Called from config_assign().
  354. */
  355. static int
  356. config_assign_line(const config_format_t *fmt, void *options,
  357. config_line_t *c, unsigned flags,
  358. bitarray_t *options_seen, char **msg)
  359. {
  360. const unsigned use_defaults = flags & CAL_USE_DEFAULTS;
  361. const unsigned clear_first = flags & CAL_CLEAR_FIRST;
  362. const unsigned warn_deprecations = flags & CAL_WARN_DEPRECATIONS;
  363. const config_var_t *var;
  364. CONFIG_CHECK(fmt, options);
  365. var = config_find_option(fmt, c->key);
  366. if (!var) {
  367. if (fmt->extra) {
  368. void *lvalue = STRUCT_VAR_P(options, fmt->extra->var_offset);
  369. log_info(LD_CONFIG,
  370. "Found unrecognized option '%s'; saving it.", c->key);
  371. config_line_append((config_line_t**)lvalue, c->key, c->value);
  372. return 0;
  373. } else {
  374. tor_asprintf(msg,
  375. "Unknown option '%s'. Failing.", c->key);
  376. return -1;
  377. }
  378. }
  379. /* Put keyword into canonical case. */
  380. if (strcmp(var->name, c->key)) {
  381. tor_free(c->key);
  382. c->key = tor_strdup(var->name);
  383. }
  384. const char *deprecation_msg;
  385. if (warn_deprecations &&
  386. (deprecation_msg = config_find_deprecation(fmt, var->name))) {
  387. warn_deprecated_option(var->name, deprecation_msg);
  388. }
  389. if (!strlen(c->value)) {
  390. /* reset or clear it, then return */
  391. if (!clear_first) {
  392. if ((var->type == CONFIG_TYPE_LINELIST ||
  393. var->type == CONFIG_TYPE_LINELIST_S) &&
  394. c->command != CONFIG_LINE_CLEAR) {
  395. /* We got an empty linelist from the torrc or command line.
  396. As a special case, call this an error. Warn and ignore. */
  397. log_warn(LD_CONFIG,
  398. "Linelist option '%s' has no value. Skipping.", c->key);
  399. } else { /* not already cleared */
  400. config_reset(fmt, options, var, use_defaults);
  401. }
  402. }
  403. return 0;
  404. } else if (c->command == CONFIG_LINE_CLEAR && !clear_first) {
  405. config_reset(fmt, options, var, use_defaults);
  406. }
  407. if (options_seen && (var->type != CONFIG_TYPE_LINELIST &&
  408. var->type != CONFIG_TYPE_LINELIST_S)) {
  409. /* We're tracking which options we've seen, and this option is not
  410. * supposed to occur more than once. */
  411. int var_index = (int)(var - fmt->vars);
  412. if (bitarray_is_set(options_seen, var_index)) {
  413. log_warn(LD_CONFIG, "Option '%s' used more than once; all but the last "
  414. "value will be ignored.", var->name);
  415. }
  416. bitarray_set(options_seen, var_index);
  417. }
  418. if (config_assign_value(fmt, options, c, msg) < 0)
  419. return -2;
  420. return 0;
  421. }
  422. /** Restore the option named <b>key</b> in options to its default value.
  423. * Called from config_assign(). */
  424. static void
  425. config_reset_line(const config_format_t *fmt, void *options,
  426. const char *key, int use_defaults)
  427. {
  428. const config_var_t *var;
  429. CONFIG_CHECK(fmt, options);
  430. var = config_find_option(fmt, key);
  431. if (!var)
  432. return; /* give error on next pass. */
  433. config_reset(fmt, options, var, use_defaults);
  434. }
  435. /** Return true iff value needs to be quoted and escaped to be used in
  436. * a configuration file. */
  437. static int
  438. config_value_needs_escape(const char *value)
  439. {
  440. if (*value == '\"')
  441. return 1;
  442. while (*value) {
  443. switch (*value)
  444. {
  445. case '\r':
  446. case '\n':
  447. case '#':
  448. /* Note: quotes and backspaces need special handling when we are using
  449. * quotes, not otherwise, so they don't trigger escaping on their
  450. * own. */
  451. return 1;
  452. default:
  453. if (!TOR_ISPRINT(*value))
  454. return 1;
  455. }
  456. ++value;
  457. }
  458. return 0;
  459. }
  460. /** Return newly allocated line or lines corresponding to <b>key</b> in the
  461. * configuration <b>options</b>. If <b>escape_val</b> is true and a
  462. * value needs to be quoted before it's put in a config file, quote and
  463. * escape that value. Return NULL if no such key exists. */
  464. config_line_t *
  465. config_get_assigned_option(const config_format_t *fmt, const void *options,
  466. const char *key, int escape_val)
  467. {
  468. const config_var_t *var;
  469. const void *value;
  470. config_line_t *result;
  471. tor_assert(options && key);
  472. CONFIG_CHECK(fmt, options);
  473. var = config_find_option(fmt, key);
  474. if (!var) {
  475. log_warn(LD_CONFIG, "Unknown option '%s'. Failing.", key);
  476. return NULL;
  477. }
  478. value = STRUCT_VAR_P(options, var->var_offset);
  479. result = tor_malloc_zero(sizeof(config_line_t));
  480. result->key = tor_strdup(var->name);
  481. switch (var->type)
  482. {
  483. case CONFIG_TYPE_STRING:
  484. case CONFIG_TYPE_FILENAME:
  485. if (*(char**)value) {
  486. result->value = tor_strdup(*(char**)value);
  487. } else {
  488. tor_free(result->key);
  489. tor_free(result);
  490. return NULL;
  491. }
  492. break;
  493. case CONFIG_TYPE_ISOTIME:
  494. if (*(time_t*)value) {
  495. result->value = tor_malloc(ISO_TIME_LEN+1);
  496. format_iso_time(result->value, *(time_t*)value);
  497. } else {
  498. tor_free(result->key);
  499. tor_free(result);
  500. }
  501. escape_val = 0; /* Can't need escape. */
  502. break;
  503. case CONFIG_TYPE_PORT:
  504. if (*(int*)value == CFG_AUTO_PORT) {
  505. result->value = tor_strdup("auto");
  506. escape_val = 0;
  507. break;
  508. }
  509. /* fall through */
  510. case CONFIG_TYPE_CSV_INTERVAL:
  511. case CONFIG_TYPE_INTERVAL:
  512. case CONFIG_TYPE_MSEC_INTERVAL:
  513. case CONFIG_TYPE_UINT:
  514. case CONFIG_TYPE_INT:
  515. /* This means every or_options_t uint or bool element
  516. * needs to be an int. Not, say, a uint16_t or char. */
  517. tor_asprintf(&result->value, "%d", *(int*)value);
  518. escape_val = 0; /* Can't need escape. */
  519. break;
  520. case CONFIG_TYPE_MEMUNIT:
  521. tor_asprintf(&result->value, U64_FORMAT,
  522. U64_PRINTF_ARG(*(uint64_t*)value));
  523. escape_val = 0; /* Can't need escape. */
  524. break;
  525. case CONFIG_TYPE_DOUBLE:
  526. tor_asprintf(&result->value, "%f", *(double*)value);
  527. escape_val = 0; /* Can't need escape. */
  528. break;
  529. case CONFIG_TYPE_AUTOBOOL:
  530. if (*(int*)value == -1) {
  531. result->value = tor_strdup("auto");
  532. escape_val = 0;
  533. break;
  534. }
  535. /* fall through */
  536. case CONFIG_TYPE_BOOL:
  537. result->value = tor_strdup(*(int*)value ? "1" : "0");
  538. escape_val = 0; /* Can't need escape. */
  539. break;
  540. case CONFIG_TYPE_ROUTERSET:
  541. result->value = routerset_to_string(*(routerset_t**)value);
  542. break;
  543. case CONFIG_TYPE_CSV:
  544. if (*(smartlist_t**)value)
  545. result->value =
  546. smartlist_join_strings(*(smartlist_t**)value, ",", 0, NULL);
  547. else
  548. result->value = tor_strdup("");
  549. break;
  550. case CONFIG_TYPE_OBSOLETE:
  551. log_fn(LOG_INFO, LD_CONFIG,
  552. "You asked me for the value of an obsolete config option '%s'.",
  553. key);
  554. tor_free(result->key);
  555. tor_free(result);
  556. return NULL;
  557. case CONFIG_TYPE_LINELIST_S:
  558. tor_free(result->key);
  559. tor_free(result);
  560. result = config_lines_dup_and_filter(*(const config_line_t **)value,
  561. key);
  562. break;
  563. case CONFIG_TYPE_LINELIST:
  564. case CONFIG_TYPE_LINELIST_V:
  565. tor_free(result->key);
  566. tor_free(result);
  567. result = config_lines_dup(*(const config_line_t**)value);
  568. break;
  569. default:
  570. tor_free(result->key);
  571. tor_free(result);
  572. log_warn(LD_BUG,"Unknown type %d for known key '%s'",
  573. var->type, key);
  574. return NULL;
  575. }
  576. if (escape_val) {
  577. config_line_t *line;
  578. for (line = result; line; line = line->next) {
  579. if (line->value && config_value_needs_escape(line->value)) {
  580. char *newval = esc_for_log(line->value);
  581. tor_free(line->value);
  582. line->value = newval;
  583. }
  584. }
  585. }
  586. return result;
  587. }
  588. /** Iterate through the linked list of requested options <b>list</b>.
  589. * For each item, convert as appropriate and assign to <b>options</b>.
  590. * If an item is unrecognized, set *msg and return -1 immediately,
  591. * else return 0 for success.
  592. *
  593. * If <b>clear_first</b>, interpret config options as replacing (not
  594. * extending) their previous values. If <b>clear_first</b> is set,
  595. * then <b>use_defaults</b> to decide if you set to defaults after
  596. * clearing, or make the value 0 or NULL.
  597. *
  598. * Here are the use cases:
  599. * 1. A non-empty AllowInvalid line in your torrc. Appends to current
  600. * if linelist, replaces current if csv.
  601. * 2. An empty AllowInvalid line in your torrc. Should clear it.
  602. * 3. "RESETCONF AllowInvalid" sets it to default.
  603. * 4. "SETCONF AllowInvalid" makes it NULL.
  604. * 5. "SETCONF AllowInvalid=foo" clears it and sets it to "foo".
  605. *
  606. * Use_defaults Clear_first
  607. * 0 0 "append"
  608. * 1 0 undefined, don't use
  609. * 0 1 "set to null first"
  610. * 1 1 "set to defaults first"
  611. * Return 0 on success, -1 on bad key, -2 on bad value.
  612. *
  613. * As an additional special case, if a LINELIST config option has
  614. * no value and clear_first is 0, then warn and ignore it.
  615. */
  616. /*
  617. There are three call cases for config_assign() currently.
  618. Case one: Torrc entry
  619. options_init_from_torrc() calls config_assign(0, 0)
  620. calls config_assign_line(0, 0).
  621. if value is empty, calls config_reset(0) and returns.
  622. calls config_assign_value(), appends.
  623. Case two: setconf
  624. options_trial_assign() calls config_assign(0, 1)
  625. calls config_reset_line(0)
  626. calls config_reset(0)
  627. calls option_clear().
  628. calls config_assign_line(0, 1).
  629. if value is empty, returns.
  630. calls config_assign_value(), appends.
  631. Case three: resetconf
  632. options_trial_assign() calls config_assign(1, 1)
  633. calls config_reset_line(1)
  634. calls config_reset(1)
  635. calls option_clear().
  636. calls config_assign_value(default)
  637. calls config_assign_line(1, 1).
  638. returns.
  639. */
  640. int
  641. config_assign(const config_format_t *fmt, void *options, config_line_t *list,
  642. unsigned config_assign_flags, char **msg)
  643. {
  644. config_line_t *p;
  645. bitarray_t *options_seen;
  646. const int n_options = config_count_options(fmt);
  647. const unsigned clear_first = config_assign_flags & CAL_CLEAR_FIRST;
  648. const unsigned use_defaults = config_assign_flags & CAL_USE_DEFAULTS;
  649. CONFIG_CHECK(fmt, options);
  650. /* pass 1: normalize keys */
  651. for (p = list; p; p = p->next) {
  652. const char *full = config_expand_abbrev(fmt, p->key, 0, 1);
  653. if (strcmp(full,p->key)) {
  654. tor_free(p->key);
  655. p->key = tor_strdup(full);
  656. }
  657. }
  658. /* pass 2: if we're reading from a resetting source, clear all
  659. * mentioned config options, and maybe set to their defaults. */
  660. if (clear_first) {
  661. for (p = list; p; p = p->next)
  662. config_reset_line(fmt, options, p->key, use_defaults);
  663. }
  664. options_seen = bitarray_init_zero(n_options);
  665. /* pass 3: assign. */
  666. while (list) {
  667. int r;
  668. if ((r=config_assign_line(fmt, options, list, config_assign_flags,
  669. options_seen, msg))) {
  670. bitarray_free(options_seen);
  671. return r;
  672. }
  673. list = list->next;
  674. }
  675. bitarray_free(options_seen);
  676. /** Now we're done assigning a group of options to the configuration.
  677. * Subsequent group assignments should _replace_ linelists, not extend
  678. * them. */
  679. config_mark_lists_fragile(fmt, options);
  680. return 0;
  681. }
  682. /** Reset config option <b>var</b> to 0, 0.0, NULL, or the equivalent.
  683. * Called from config_reset() and config_free(). */
  684. static void
  685. config_clear(const config_format_t *fmt, void *options,
  686. const config_var_t *var)
  687. {
  688. void *lvalue = STRUCT_VAR_P(options, var->var_offset);
  689. (void)fmt; /* unused */
  690. switch (var->type) {
  691. case CONFIG_TYPE_STRING:
  692. case CONFIG_TYPE_FILENAME:
  693. tor_free(*(char**)lvalue);
  694. break;
  695. case CONFIG_TYPE_DOUBLE:
  696. *(double*)lvalue = 0.0;
  697. break;
  698. case CONFIG_TYPE_ISOTIME:
  699. *(time_t*)lvalue = 0;
  700. break;
  701. case CONFIG_TYPE_CSV_INTERVAL:
  702. case CONFIG_TYPE_INTERVAL:
  703. case CONFIG_TYPE_MSEC_INTERVAL:
  704. case CONFIG_TYPE_UINT:
  705. case CONFIG_TYPE_INT:
  706. case CONFIG_TYPE_PORT:
  707. case CONFIG_TYPE_BOOL:
  708. *(int*)lvalue = 0;
  709. break;
  710. case CONFIG_TYPE_AUTOBOOL:
  711. *(int*)lvalue = -1;
  712. break;
  713. case CONFIG_TYPE_MEMUNIT:
  714. *(uint64_t*)lvalue = 0;
  715. break;
  716. case CONFIG_TYPE_ROUTERSET:
  717. if (*(routerset_t**)lvalue) {
  718. routerset_free(*(routerset_t**)lvalue);
  719. *(routerset_t**)lvalue = NULL;
  720. }
  721. break;
  722. case CONFIG_TYPE_CSV:
  723. if (*(smartlist_t**)lvalue) {
  724. SMARTLIST_FOREACH(*(smartlist_t **)lvalue, char *, cp, tor_free(cp));
  725. smartlist_free(*(smartlist_t **)lvalue);
  726. *(smartlist_t **)lvalue = NULL;
  727. }
  728. break;
  729. case CONFIG_TYPE_LINELIST:
  730. case CONFIG_TYPE_LINELIST_S:
  731. config_free_lines(*(config_line_t **)lvalue);
  732. *(config_line_t **)lvalue = NULL;
  733. break;
  734. case CONFIG_TYPE_LINELIST_V:
  735. /* handled by linelist_s. */
  736. break;
  737. case CONFIG_TYPE_OBSOLETE:
  738. break;
  739. }
  740. }
  741. /** Clear the option indexed by <b>var</b> in <b>options</b>. Then if
  742. * <b>use_defaults</b>, set it to its default value.
  743. * Called by config_init() and option_reset_line() and option_assign_line(). */
  744. static void
  745. config_reset(const config_format_t *fmt, void *options,
  746. const config_var_t *var, int use_defaults)
  747. {
  748. config_line_t *c;
  749. char *msg = NULL;
  750. CONFIG_CHECK(fmt, options);
  751. config_clear(fmt, options, var); /* clear it first */
  752. if (!use_defaults)
  753. return; /* all done */
  754. if (var->initvalue) {
  755. c = tor_malloc_zero(sizeof(config_line_t));
  756. c->key = tor_strdup(var->name);
  757. c->value = tor_strdup(var->initvalue);
  758. if (config_assign_value(fmt, options, c, &msg) < 0) {
  759. log_warn(LD_BUG, "Failed to assign default: %s", msg);
  760. tor_free(msg); /* if this happens it's a bug */
  761. }
  762. config_free_lines(c);
  763. }
  764. }
  765. /** Release storage held by <b>options</b>. */
  766. void
  767. config_free_(const config_format_t *fmt, void *options)
  768. {
  769. int i;
  770. if (!options)
  771. return;
  772. tor_assert(fmt);
  773. for (i=0; fmt->vars[i].name; ++i)
  774. config_clear(fmt, options, &(fmt->vars[i]));
  775. if (fmt->extra) {
  776. config_line_t **linep = STRUCT_VAR_P(options, fmt->extra->var_offset);
  777. config_free_lines(*linep);
  778. *linep = NULL;
  779. }
  780. tor_free(options);
  781. }
  782. /** Return true iff the option <b>name</b> has the same value in <b>o1</b>
  783. * and <b>o2</b>. Must not be called for LINELIST_S or OBSOLETE options.
  784. */
  785. int
  786. config_is_same(const config_format_t *fmt,
  787. const void *o1, const void *o2,
  788. const char *name)
  789. {
  790. config_line_t *c1, *c2;
  791. int r = 1;
  792. CONFIG_CHECK(fmt, o1);
  793. CONFIG_CHECK(fmt, o2);
  794. c1 = config_get_assigned_option(fmt, o1, name, 0);
  795. c2 = config_get_assigned_option(fmt, o2, name, 0);
  796. r = config_lines_eq(c1, c2);
  797. config_free_lines(c1);
  798. config_free_lines(c2);
  799. return r;
  800. }
  801. /** Copy storage held by <b>old</b> into a new or_options_t and return it. */
  802. void *
  803. config_dup(const config_format_t *fmt, const void *old)
  804. {
  805. void *newopts;
  806. int i;
  807. config_line_t *line;
  808. newopts = config_new(fmt);
  809. for (i=0; fmt->vars[i].name; ++i) {
  810. if (fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
  811. continue;
  812. if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE)
  813. continue;
  814. line = config_get_assigned_option(fmt, old, fmt->vars[i].name, 0);
  815. if (line) {
  816. char *msg = NULL;
  817. if (config_assign(fmt, newopts, line, 0, &msg) < 0) {
  818. log_err(LD_BUG, "config_get_assigned_option() generated "
  819. "something we couldn't config_assign(): %s", msg);
  820. tor_free(msg);
  821. tor_assert(0);
  822. }
  823. }
  824. config_free_lines(line);
  825. }
  826. return newopts;
  827. }
  828. /** Set all vars in the configuration object <b>options</b> to their default
  829. * values. */
  830. void
  831. config_init(const config_format_t *fmt, void *options)
  832. {
  833. int i;
  834. const config_var_t *var;
  835. CONFIG_CHECK(fmt, options);
  836. for (i=0; fmt->vars[i].name; ++i) {
  837. var = &fmt->vars[i];
  838. if (!var->initvalue)
  839. continue; /* defaults to NULL or 0 */
  840. config_reset(fmt, options, var, 1);
  841. }
  842. }
  843. /** Allocate and return a new string holding the written-out values of the vars
  844. * in 'options'. If 'minimal', do not write out any default-valued vars.
  845. * Else, if comment_defaults, write default values as comments.
  846. */
  847. char *
  848. config_dump(const config_format_t *fmt, const void *default_options,
  849. const void *options, int minimal,
  850. int comment_defaults)
  851. {
  852. smartlist_t *elements;
  853. const void *defaults = default_options;
  854. void *defaults_tmp = NULL;
  855. config_line_t *line, *assigned;
  856. char *result;
  857. int i;
  858. char *msg = NULL;
  859. if (defaults == NULL) {
  860. defaults = defaults_tmp = config_new(fmt);
  861. config_init(fmt, defaults_tmp);
  862. }
  863. /* XXX use a 1 here so we don't add a new log line while dumping */
  864. if (default_options == NULL) {
  865. if (fmt->validate_fn(NULL, defaults_tmp, defaults_tmp, 1, &msg) < 0) {
  866. log_err(LD_BUG, "Failed to validate default config: %s", msg);
  867. tor_free(msg);
  868. tor_assert(0);
  869. }
  870. }
  871. elements = smartlist_new();
  872. for (i=0; fmt->vars[i].name; ++i) {
  873. int comment_option = 0;
  874. if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE ||
  875. fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
  876. continue;
  877. /* Don't save 'hidden' control variables. */
  878. if (!strcmpstart(fmt->vars[i].name, "__"))
  879. continue;
  880. if (minimal && config_is_same(fmt, options, defaults, fmt->vars[i].name))
  881. continue;
  882. else if (comment_defaults &&
  883. config_is_same(fmt, options, defaults, fmt->vars[i].name))
  884. comment_option = 1;
  885. line = assigned =
  886. config_get_assigned_option(fmt, options, fmt->vars[i].name, 1);
  887. for (; line; line = line->next) {
  888. if (!strcmpstart(line->key, "__")) {
  889. /* This check detects "hidden" variables inside LINELIST_V structures.
  890. */
  891. continue;
  892. }
  893. smartlist_add_asprintf(elements, "%s%s %s\n",
  894. comment_option ? "# " : "",
  895. line->key, line->value);
  896. }
  897. config_free_lines(assigned);
  898. }
  899. if (fmt->extra) {
  900. line = *(config_line_t**)STRUCT_VAR_P(options, fmt->extra->var_offset);
  901. for (; line; line = line->next) {
  902. smartlist_add_asprintf(elements, "%s %s\n", line->key, line->value);
  903. }
  904. }
  905. result = smartlist_join_strings(elements, "", 0, NULL);
  906. SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
  907. smartlist_free(elements);
  908. if (defaults_tmp)
  909. config_free(fmt, defaults_tmp);
  910. return result;
  911. }
  912. /** Mapping from a unit name to a multiplier for converting that unit into a
  913. * base unit. Used by config_parse_unit. */
  914. struct unit_table_t {
  915. const char *unit; /**< The name of the unit */
  916. uint64_t multiplier; /**< How many of the base unit appear in this unit */
  917. };
  918. /** Table to map the names of memory units to the number of bytes they
  919. * contain. */
  920. static struct unit_table_t memory_units[] = {
  921. { "", 1 },
  922. { "b", 1<< 0 },
  923. { "byte", 1<< 0 },
  924. { "bytes", 1<< 0 },
  925. { "kb", 1<<10 },
  926. { "kbyte", 1<<10 },
  927. { "kbytes", 1<<10 },
  928. { "kilobyte", 1<<10 },
  929. { "kilobytes", 1<<10 },
  930. { "kilobits", 1<<7 },
  931. { "kilobit", 1<<7 },
  932. { "kbits", 1<<7 },
  933. { "kbit", 1<<7 },
  934. { "m", 1<<20 },
  935. { "mb", 1<<20 },
  936. { "mbyte", 1<<20 },
  937. { "mbytes", 1<<20 },
  938. { "megabyte", 1<<20 },
  939. { "megabytes", 1<<20 },
  940. { "megabits", 1<<17 },
  941. { "megabit", 1<<17 },
  942. { "mbits", 1<<17 },
  943. { "mbit", 1<<17 },
  944. { "gb", 1<<30 },
  945. { "gbyte", 1<<30 },
  946. { "gbytes", 1<<30 },
  947. { "gigabyte", 1<<30 },
  948. { "gigabytes", 1<<30 },
  949. { "gigabits", 1<<27 },
  950. { "gigabit", 1<<27 },
  951. { "gbits", 1<<27 },
  952. { "gbit", 1<<27 },
  953. { "tb", U64_LITERAL(1)<<40 },
  954. { "tbyte", U64_LITERAL(1)<<40 },
  955. { "tbytes", U64_LITERAL(1)<<40 },
  956. { "terabyte", U64_LITERAL(1)<<40 },
  957. { "terabytes", U64_LITERAL(1)<<40 },
  958. { "terabits", U64_LITERAL(1)<<37 },
  959. { "terabit", U64_LITERAL(1)<<37 },
  960. { "tbits", U64_LITERAL(1)<<37 },
  961. { "tbit", U64_LITERAL(1)<<37 },
  962. { NULL, 0 },
  963. };
  964. /** Table to map the names of time units to the number of seconds they
  965. * contain. */
  966. static struct unit_table_t time_units[] = {
  967. { "", 1 },
  968. { "second", 1 },
  969. { "seconds", 1 },
  970. { "minute", 60 },
  971. { "minutes", 60 },
  972. { "hour", 60*60 },
  973. { "hours", 60*60 },
  974. { "day", 24*60*60 },
  975. { "days", 24*60*60 },
  976. { "week", 7*24*60*60 },
  977. { "weeks", 7*24*60*60 },
  978. { "month", 2629728, }, /* about 30.437 days */
  979. { "months", 2629728, },
  980. { NULL, 0 },
  981. };
  982. /** Table to map the names of time units to the number of milliseconds
  983. * they contain. */
  984. static struct unit_table_t time_msec_units[] = {
  985. { "", 1 },
  986. { "msec", 1 },
  987. { "millisecond", 1 },
  988. { "milliseconds", 1 },
  989. { "second", 1000 },
  990. { "seconds", 1000 },
  991. { "minute", 60*1000 },
  992. { "minutes", 60*1000 },
  993. { "hour", 60*60*1000 },
  994. { "hours", 60*60*1000 },
  995. { "day", 24*60*60*1000 },
  996. { "days", 24*60*60*1000 },
  997. { "week", 7*24*60*60*1000 },
  998. { "weeks", 7*24*60*60*1000 },
  999. { NULL, 0 },
  1000. };
  1001. /** Parse a string <b>val</b> containing a number, zero or more
  1002. * spaces, and an optional unit string. If the unit appears in the
  1003. * table <b>u</b>, then multiply the number by the unit multiplier.
  1004. * On success, set *<b>ok</b> to 1 and return this product.
  1005. * Otherwise, set *<b>ok</b> to 0.
  1006. */
  1007. static uint64_t
  1008. config_parse_units(const char *val, struct unit_table_t *u, int *ok)
  1009. {
  1010. uint64_t v = 0;
  1011. double d = 0;
  1012. int use_float = 0;
  1013. char *cp;
  1014. tor_assert(ok);
  1015. v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp);
  1016. if (!*ok || (cp && *cp == '.')) {
  1017. d = tor_parse_double(val, 0, (double)UINT64_MAX, ok, &cp);
  1018. if (!*ok)
  1019. goto done;
  1020. use_float = 1;
  1021. }
  1022. if (!cp) {
  1023. *ok = 1;
  1024. v = use_float ? DBL_TO_U64(d) : v;
  1025. goto done;
  1026. }
  1027. cp = (char*) eat_whitespace(cp);
  1028. for ( ;u->unit;++u) {
  1029. if (!strcasecmp(u->unit, cp)) {
  1030. if (use_float)
  1031. v = (uint64_t)(u->multiplier * d);
  1032. else
  1033. v *= u->multiplier;
  1034. *ok = 1;
  1035. goto done;
  1036. }
  1037. }
  1038. log_warn(LD_CONFIG, "Unknown unit '%s'.", cp);
  1039. *ok = 0;
  1040. done:
  1041. if (*ok)
  1042. return v;
  1043. else
  1044. return 0;
  1045. }
  1046. /** Parse a string in the format "number unit", where unit is a unit of
  1047. * information (byte, KB, M, etc). On success, set *<b>ok</b> to true
  1048. * and return the number of bytes specified. Otherwise, set
  1049. * *<b>ok</b> to false and return 0. */
  1050. static uint64_t
  1051. config_parse_memunit(const char *s, int *ok)
  1052. {
  1053. uint64_t u = config_parse_units(s, memory_units, ok);
  1054. return u;
  1055. }
  1056. /** Parse a string in the format "number unit", where unit is a unit of
  1057. * time in milliseconds. On success, set *<b>ok</b> to true and return
  1058. * the number of milliseconds in the provided interval. Otherwise, set
  1059. * *<b>ok</b> to 0 and return -1. */
  1060. static int
  1061. config_parse_msec_interval(const char *s, int *ok)
  1062. {
  1063. uint64_t r;
  1064. r = config_parse_units(s, time_msec_units, ok);
  1065. if (r > INT_MAX) {
  1066. log_warn(LD_CONFIG, "Msec interval '%s' is too long", s);
  1067. *ok = 0;
  1068. return -1;
  1069. }
  1070. return (int)r;
  1071. }
  1072. /** Parse a string in the format "number unit", where unit is a unit of time.
  1073. * On success, set *<b>ok</b> to true and return the number of seconds in
  1074. * the provided interval. Otherwise, set *<b>ok</b> to 0 and return -1.
  1075. */
  1076. static int
  1077. config_parse_interval(const char *s, int *ok)
  1078. {
  1079. uint64_t r;
  1080. r = config_parse_units(s, time_units, ok);
  1081. if (r > INT_MAX) {
  1082. log_warn(LD_CONFIG, "Interval '%s' is too long", s);
  1083. *ok = 0;
  1084. return -1;
  1085. }
  1086. return (int)r;
  1087. }