actions.c 61 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990
  1. /*********************************************************************
  2. *
  3. * File : $Source: /cvsroot/ijbswa/current/actions.c,v $
  4. *
  5. * Purpose : Declares functions to work with actions files
  6. *
  7. * Copyright : Written by and Copyright (C) 2001-2016 the
  8. * Privoxy team. https://www.privoxy.org/
  9. *
  10. * Based on the Internet Junkbuster originally written
  11. * by and Copyright (C) 1997 Anonymous Coders and
  12. * Junkbusters Corporation. http://www.junkbusters.com
  13. *
  14. * This program is free software; you can redistribute it
  15. * and/or modify it under the terms of the GNU General
  16. * Public License as published by the Free Software
  17. * Foundation; either version 2 of the License, or (at
  18. * your option) any later version.
  19. *
  20. * This program is distributed in the hope that it will
  21. * be useful, but WITHOUT ANY WARRANTY; without even the
  22. * implied warranty of MERCHANTABILITY or FITNESS FOR A
  23. * PARTICULAR PURPOSE. See the GNU General Public
  24. * License for more details.
  25. *
  26. * The GNU General Public License should be included with
  27. * this file. If not, you can view it at
  28. * http://www.gnu.org/copyleft/gpl.html
  29. * or write to the Free Software Foundation, Inc., 59
  30. * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  31. *
  32. *********************************************************************/
  33. #include "config.h"
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <assert.h>
  37. #include <stdlib.h>
  38. #ifdef FEATURE_PTHREAD
  39. #include <pthread.h>
  40. #endif
  41. #include "project.h"
  42. #include "jcc.h"
  43. #include "list.h"
  44. #include "actions.h"
  45. #include "miscutil.h"
  46. #include "errlog.h"
  47. #include "loaders.h"
  48. #include "encode.h"
  49. #include "urlmatch.h"
  50. #include "cgi.h"
  51. #include "ssplit.h"
  52. #include "filters.h"
  53. /*
  54. * We need the main list of options.
  55. *
  56. * First, we need a way to tell between boolean, string, and multi-string
  57. * options. For string and multistring options, we also need to be
  58. * able to tell the difference between a "+" and a "-". (For bools,
  59. * the "+"/"-" information is encoded in "add" and "mask"). So we use
  60. * an enumerated type (well, the preprocessor equivalent). Here are
  61. * the values:
  62. */
  63. enum action_value_type {
  64. AV_NONE = 0, /* +opt -opt */
  65. AV_ADD_STRING = 1, /* +stropt{string} */
  66. AV_REM_STRING = 2, /* -stropt */
  67. AV_ADD_MULTI = 3, /* +multiopt{string} +multiopt{string2} */
  68. AV_REM_MULTI = 4 /* -multiopt{string} -multiopt */
  69. };
  70. /*
  71. * We need a structure to hold the name, flag changes,
  72. * type, and string index.
  73. */
  74. struct action_name
  75. {
  76. const char * name;
  77. unsigned long mask; /* a bit set to "0" = remove action */
  78. unsigned long add; /* a bit set to "1" = add action */
  79. enum action_value_type value_type; /* an AV_... constant */
  80. int index; /* index into strings[] or multi[] */
  81. };
  82. /*
  83. * And with those building blocks in place, here's the array.
  84. */
  85. static const struct action_name action_names[] =
  86. {
  87. /*
  88. * Well actually there's no data here - it's in actionlist.h
  89. * This keeps it together to make it easy to change.
  90. *
  91. * Here's the macros used to format it:
  92. */
  93. #define DEFINE_ACTION_MULTI(name,index) \
  94. { "+" name, ACTION_MASK_ALL, 0, AV_ADD_MULTI, index }, \
  95. { "-" name, ACTION_MASK_ALL, 0, AV_REM_MULTI, index },
  96. #define DEFINE_ACTION_STRING(name,flag,index) \
  97. { "+" name, ACTION_MASK_ALL, flag, AV_ADD_STRING, index }, \
  98. { "-" name, ~flag, 0, AV_REM_STRING, index },
  99. #define DEFINE_ACTION_BOOL(name,flag) \
  100. { "+" name, ACTION_MASK_ALL, flag }, \
  101. { "-" name, ~flag, 0 },
  102. #define DEFINE_ACTION_ALIAS 1 /* Want aliases please */
  103. #include "actionlist.h"
  104. #undef DEFINE_ACTION_MULTI
  105. #undef DEFINE_ACTION_STRING
  106. #undef DEFINE_ACTION_BOOL
  107. #undef DEFINE_ACTION_ALIAS
  108. { NULL, 0, 0 } /* End marker */
  109. };
  110. #ifndef FUZZ
  111. static
  112. #endif
  113. int load_one_actions_file(struct client_state *csp, int fileid);
  114. /*********************************************************************
  115. *
  116. * Function : merge_actions
  117. *
  118. * Description : Merge two actions together.
  119. * Similar to "dest += src".
  120. *
  121. * Parameters :
  122. * 1 : dest = Actions to modify.
  123. * 2 : src = Action to add.
  124. *
  125. * Returns : JB_ERR_OK or JB_ERR_MEMORY
  126. *
  127. *********************************************************************/
  128. jb_err merge_actions (struct action_spec *dest,
  129. const struct action_spec *src)
  130. {
  131. int i;
  132. jb_err err;
  133. dest->mask &= src->mask;
  134. dest->add &= src->mask;
  135. dest->add |= src->add;
  136. for (i = 0; i < ACTION_STRING_COUNT; i++)
  137. {
  138. char * str = src->string[i];
  139. if (str)
  140. {
  141. freez(dest->string[i]);
  142. dest->string[i] = strdup_or_die(str);
  143. }
  144. }
  145. for (i = 0; i < ACTION_MULTI_COUNT; i++)
  146. {
  147. if (src->multi_remove_all[i])
  148. {
  149. /* Remove everything from dest */
  150. list_remove_all(dest->multi_remove[i]);
  151. dest->multi_remove_all[i] = 1;
  152. err = list_duplicate(dest->multi_add[i], src->multi_add[i]);
  153. }
  154. else if (dest->multi_remove_all[i])
  155. {
  156. /*
  157. * dest already removes everything, so we only need to worry
  158. * about what we add.
  159. */
  160. list_remove_list(dest->multi_add[i], src->multi_remove[i]);
  161. err = list_append_list_unique(dest->multi_add[i], src->multi_add[i]);
  162. }
  163. else
  164. {
  165. /* No "remove all"s to worry about. */
  166. list_remove_list(dest->multi_add[i], src->multi_remove[i]);
  167. err = list_append_list_unique(dest->multi_remove[i], src->multi_remove[i]);
  168. if (!err) err = list_append_list_unique(dest->multi_add[i], src->multi_add[i]);
  169. }
  170. if (err)
  171. {
  172. return err;
  173. }
  174. }
  175. return JB_ERR_OK;
  176. }
  177. /*********************************************************************
  178. *
  179. * Function : copy_action
  180. *
  181. * Description : Copy an action_specs.
  182. * Similar to "dest = src".
  183. *
  184. * Parameters :
  185. * 1 : dest = Destination of copy.
  186. * 2 : src = Source for copy.
  187. *
  188. * Returns : JB_ERR_OK or JB_ERR_MEMORY
  189. *
  190. *********************************************************************/
  191. jb_err copy_action (struct action_spec *dest,
  192. const struct action_spec *src)
  193. {
  194. int i;
  195. jb_err err = JB_ERR_OK;
  196. free_action(dest);
  197. memset(dest, '\0', sizeof(*dest));
  198. dest->mask = src->mask;
  199. dest->add = src->add;
  200. for (i = 0; i < ACTION_STRING_COUNT; i++)
  201. {
  202. char * str = src->string[i];
  203. if (str)
  204. {
  205. str = strdup_or_die(str);
  206. dest->string[i] = str;
  207. }
  208. }
  209. for (i = 0; i < ACTION_MULTI_COUNT; i++)
  210. {
  211. dest->multi_remove_all[i] = src->multi_remove_all[i];
  212. err = list_duplicate(dest->multi_remove[i], src->multi_remove[i]);
  213. if (err)
  214. {
  215. return err;
  216. }
  217. err = list_duplicate(dest->multi_add[i], src->multi_add[i]);
  218. if (err)
  219. {
  220. return err;
  221. }
  222. }
  223. return err;
  224. }
  225. /*********************************************************************
  226. *
  227. * Function : free_action_spec
  228. *
  229. * Description : Frees an action_spec and the memory used by it.
  230. *
  231. * Parameters :
  232. * 1 : src = Source to free.
  233. *
  234. * Returns : N/A
  235. *
  236. *********************************************************************/
  237. void free_action_spec(struct action_spec *src)
  238. {
  239. free_action(src);
  240. freez(src);
  241. }
  242. /*********************************************************************
  243. *
  244. * Function : free_action
  245. *
  246. * Description : Destroy an action_spec. Frees memory used by it,
  247. * except for the memory used by the struct action_spec
  248. * itself.
  249. *
  250. * Parameters :
  251. * 1 : src = Source to free.
  252. *
  253. * Returns : N/A
  254. *
  255. *********************************************************************/
  256. void free_action (struct action_spec *src)
  257. {
  258. int i;
  259. if (src == NULL)
  260. {
  261. return;
  262. }
  263. for (i = 0; i < ACTION_STRING_COUNT; i++)
  264. {
  265. freez(src->string[i]);
  266. }
  267. for (i = 0; i < ACTION_MULTI_COUNT; i++)
  268. {
  269. destroy_list(src->multi_remove[i]);
  270. destroy_list(src->multi_add[i]);
  271. }
  272. memset(src, '\0', sizeof(*src));
  273. }
  274. /*********************************************************************
  275. *
  276. * Function : get_action_token
  277. *
  278. * Description : Parses a line for the first action.
  279. * Modifies its input array, doesn't allocate memory.
  280. * e.g. given:
  281. * *line=" +abc{def} -ghi "
  282. * Returns:
  283. * *line=" -ghi "
  284. * *name="+abc"
  285. * *value="def"
  286. *
  287. * Parameters :
  288. * 1 : line = [in] The line containing the action.
  289. * [out] Start of next action on line, or
  290. * NULL if we reached the end of line before
  291. * we found an action.
  292. * 2 : name = [out] Start of action name, null
  293. * terminated. NULL on EOL
  294. * 3 : value = [out] Start of action value, null
  295. * terminated. NULL if none or EOL.
  296. *
  297. * Returns : JB_ERR_OK => Ok
  298. * JB_ERR_PARSE => Mismatched {} (line was trashed anyway)
  299. *
  300. *********************************************************************/
  301. jb_err get_action_token(char **line, char **name, char **value)
  302. {
  303. char * str = *line;
  304. char ch;
  305. /* set default returns */
  306. *line = NULL;
  307. *name = NULL;
  308. *value = NULL;
  309. /* Eat any leading whitespace */
  310. while ((*str == ' ') || (*str == '\t'))
  311. {
  312. str++;
  313. }
  314. if (*str == '\0')
  315. {
  316. return 0;
  317. }
  318. if (*str == '{')
  319. {
  320. /* null name, just value is prohibited */
  321. return JB_ERR_PARSE;
  322. }
  323. *name = str;
  324. /* parse option */
  325. while (((ch = *str) != '\0') &&
  326. (ch != ' ') && (ch != '\t') && (ch != '{'))
  327. {
  328. if (ch == '}')
  329. {
  330. /* error, '}' without '{' */
  331. return JB_ERR_PARSE;
  332. }
  333. str++;
  334. }
  335. *str = '\0';
  336. if (ch != '{')
  337. {
  338. /* no value */
  339. if (ch == '\0')
  340. {
  341. /* EOL - be careful not to run off buffer */
  342. *line = str;
  343. }
  344. else
  345. {
  346. /* More to parse next time. */
  347. *line = str + 1;
  348. }
  349. return JB_ERR_OK;
  350. }
  351. str++;
  352. *value = str;
  353. /* The value ends with the first non-escaped closing curly brace */
  354. while ((str = strchr(str, '}')) != NULL)
  355. {
  356. if (str[-1] == '\\')
  357. {
  358. /* Overwrite the '\' so the action doesn't see it. */
  359. string_move(str-1, str);
  360. continue;
  361. }
  362. break;
  363. }
  364. if (str == NULL)
  365. {
  366. /* error */
  367. *value = NULL;
  368. return JB_ERR_PARSE;
  369. }
  370. /* got value */
  371. *str = '\0';
  372. *line = str + 1;
  373. chomp(*value);
  374. return JB_ERR_OK;
  375. }
  376. /*********************************************************************
  377. *
  378. * Function : action_used_to_be_valid
  379. *
  380. * Description : Checks if unrecognized actions were valid in earlier
  381. * releases.
  382. *
  383. * Parameters :
  384. * 1 : action = The string containing the action to check.
  385. *
  386. * Returns : True if yes, otherwise false.
  387. *
  388. *********************************************************************/
  389. static int action_used_to_be_valid(const char *action)
  390. {
  391. static const char * const formerly_valid_actions[] = {
  392. "inspect-jpegs",
  393. "kill-popups",
  394. "send-vanilla-wafer",
  395. "send-wafer",
  396. "treat-forbidden-connects-like-blocks",
  397. "vanilla-wafer",
  398. "wafer"
  399. };
  400. unsigned int i;
  401. for (i = 0; i < SZ(formerly_valid_actions); i++)
  402. {
  403. if (0 == strcmpic(action, formerly_valid_actions[i]))
  404. {
  405. return TRUE;
  406. }
  407. }
  408. return FALSE;
  409. }
  410. /*********************************************************************
  411. *
  412. * Function : get_actions
  413. *
  414. * Description : Parses a list of actions.
  415. *
  416. * Parameters :
  417. * 1 : line = The string containing the actions.
  418. * Will be written to by this function.
  419. * 2 : alias_list = Custom alias list, or NULL for none.
  420. * 3 : cur_action = Where to store the action. Caller
  421. * allocates memory.
  422. *
  423. * Returns : JB_ERR_OK => Ok
  424. * JB_ERR_PARSE => Parse error (line was trashed anyway)
  425. * nonzero => Out of memory (line was trashed anyway)
  426. *
  427. *********************************************************************/
  428. jb_err get_actions(char *line,
  429. struct action_alias * alias_list,
  430. struct action_spec *cur_action)
  431. {
  432. jb_err err;
  433. init_action(cur_action);
  434. cur_action->mask = ACTION_MASK_ALL;
  435. while (line)
  436. {
  437. char * option = NULL;
  438. char * value = NULL;
  439. err = get_action_token(&line, &option, &value);
  440. if (err)
  441. {
  442. return err;
  443. }
  444. if (option)
  445. {
  446. /* handle option in 'option' */
  447. /* Check for standard action name */
  448. const struct action_name * action = action_names;
  449. while ((action->name != NULL) && (0 != strcmpic(action->name, option)))
  450. {
  451. action++;
  452. }
  453. if (action->name != NULL)
  454. {
  455. /* Found it */
  456. cur_action->mask &= action->mask;
  457. cur_action->add &= action->mask;
  458. cur_action->add |= action->add;
  459. switch (action->value_type)
  460. {
  461. case AV_NONE:
  462. if (value != NULL)
  463. {
  464. log_error(LOG_LEVEL_ERROR,
  465. "Action %s does not take parameters but %s was given.",
  466. action->name, value);
  467. return JB_ERR_PARSE;
  468. }
  469. break;
  470. case AV_ADD_STRING:
  471. {
  472. /* add single string. */
  473. if ((value == NULL) || (*value == '\0'))
  474. {
  475. if (0 == strcmpic(action->name, "+block"))
  476. {
  477. /*
  478. * XXX: Temporary backwards compatibility hack.
  479. * XXX: should include line number.
  480. */
  481. value = "No reason specified.";
  482. log_error(LOG_LEVEL_ERROR,
  483. "block action without reason found. This may "
  484. "become a fatal error in future versions.");
  485. }
  486. else
  487. {
  488. return JB_ERR_PARSE;
  489. }
  490. }
  491. #ifdef FEATURE_EXTENDED_STATISTICS
  492. if (0 == strcmpic(action->name, "+block"))
  493. {
  494. register_block_reason_for_statistics(value);
  495. }
  496. #endif
  497. /* FIXME: should validate option string here */
  498. freez (cur_action->string[action->index]);
  499. cur_action->string[action->index] = strdup(value);
  500. if (NULL == cur_action->string[action->index])
  501. {
  502. return JB_ERR_MEMORY;
  503. }
  504. break;
  505. }
  506. case AV_REM_STRING:
  507. {
  508. /* remove single string. */
  509. freez (cur_action->string[action->index]);
  510. break;
  511. }
  512. case AV_ADD_MULTI:
  513. {
  514. /* append multi string. */
  515. struct list * remove_p = cur_action->multi_remove[action->index];
  516. struct list * add_p = cur_action->multi_add[action->index];
  517. if ((value == NULL) || (*value == '\0'))
  518. {
  519. return JB_ERR_PARSE;
  520. }
  521. list_remove_item(remove_p, value);
  522. err = enlist_unique(add_p, value, 0);
  523. if (err)
  524. {
  525. return err;
  526. }
  527. break;
  528. }
  529. case AV_REM_MULTI:
  530. {
  531. /* remove multi string. */
  532. struct list * remove_p = cur_action->multi_remove[action->index];
  533. struct list * add_p = cur_action->multi_add[action->index];
  534. if ((value == NULL) || (*value == '\0')
  535. || ((*value == '*') && (value[1] == '\0')))
  536. {
  537. /*
  538. * no option, or option == "*".
  539. *
  540. * Remove *ALL*.
  541. */
  542. list_remove_all(remove_p);
  543. list_remove_all(add_p);
  544. cur_action->multi_remove_all[action->index] = 1;
  545. }
  546. else
  547. {
  548. /* Valid option - remove only 1 option */
  549. if (!cur_action->multi_remove_all[action->index])
  550. {
  551. /* there isn't a catch-all in the remove list already */
  552. err = enlist_unique(remove_p, value, 0);
  553. if (err)
  554. {
  555. return err;
  556. }
  557. }
  558. list_remove_item(add_p, value);
  559. }
  560. break;
  561. }
  562. default:
  563. /* Shouldn't get here unless there's memory corruption. */
  564. assert(0);
  565. return JB_ERR_PARSE;
  566. }
  567. }
  568. else
  569. {
  570. /* try user aliases. */
  571. const struct action_alias * alias = alias_list;
  572. while ((alias != NULL) && (0 != strcmpic(alias->name, option)))
  573. {
  574. alias = alias->next;
  575. }
  576. if (alias != NULL)
  577. {
  578. /* Found it */
  579. merge_actions(cur_action, alias->action);
  580. }
  581. else if (((size_t)2 < strlen(option)) && action_used_to_be_valid(option+1))
  582. {
  583. log_error(LOG_LEVEL_ERROR, "Action '%s' is no longer valid "
  584. "in this Privoxy release. Ignored.", option+1);
  585. }
  586. else if (((size_t)2 < strlen(option)) && 0 == strcmpic(option+1, "hide-forwarded-for-headers"))
  587. {
  588. log_error(LOG_LEVEL_FATAL, "The action 'hide-forwarded-for-headers' "
  589. "is no longer valid in this Privoxy release. "
  590. "Use 'change-x-forwarded-for' instead.");
  591. }
  592. else
  593. {
  594. /* Bad action name */
  595. /*
  596. * XXX: This is a fatal error and Privoxy will later on exit
  597. * in load_one_actions_file() because of an "invalid line".
  598. *
  599. * It would be preferable to name the offending option in that
  600. * error message, but currently there is no way to do that and
  601. * we have to live with two error messages for basically the
  602. * same reason.
  603. */
  604. log_error(LOG_LEVEL_ERROR, "Unknown action or alias: %s", option);
  605. return JB_ERR_PARSE;
  606. }
  607. }
  608. }
  609. }
  610. return JB_ERR_OK;
  611. }
  612. /*********************************************************************
  613. *
  614. * Function : init_current_action
  615. *
  616. * Description : Zero out an action.
  617. *
  618. * Parameters :
  619. * 1 : dest = An uninitialized current_action_spec.
  620. *
  621. * Returns : N/A
  622. *
  623. *********************************************************************/
  624. void init_current_action (struct current_action_spec *dest)
  625. {
  626. memset(dest, '\0', sizeof(*dest));
  627. dest->flags = ACTION_MOST_COMPATIBLE;
  628. }
  629. /*********************************************************************
  630. *
  631. * Function : init_action
  632. *
  633. * Description : Zero out an action.
  634. *
  635. * Parameters :
  636. * 1 : dest = An uninitialized action_spec.
  637. *
  638. * Returns : N/A
  639. *
  640. *********************************************************************/
  641. void init_action (struct action_spec *dest)
  642. {
  643. memset(dest, '\0', sizeof(*dest));
  644. }
  645. /*********************************************************************
  646. *
  647. * Function : merge_current_action
  648. *
  649. * Description : Merge two actions together.
  650. * Similar to "dest += src".
  651. * Differences between this and merge_actions()
  652. * is that this one doesn't allocate memory for
  653. * strings (so "src" better be in memory for at least
  654. * as long as "dest" is, and you'd better free
  655. * "dest" using "free_current_action").
  656. * Also, there is no mask or remove lists in dest.
  657. * (If we're applying it to a URL, we don't need them)
  658. *
  659. * Parameters :
  660. * 1 : dest = Current actions, to modify.
  661. * 2 : src = Action to add.
  662. *
  663. * Returns 0 : no error
  664. * !=0 : error, probably JB_ERR_MEMORY.
  665. *
  666. *********************************************************************/
  667. jb_err merge_current_action (struct current_action_spec *dest,
  668. const struct action_spec *src)
  669. {
  670. int i;
  671. jb_err err = JB_ERR_OK;
  672. dest->flags &= src->mask;
  673. dest->flags |= src->add;
  674. for (i = 0; i < ACTION_STRING_COUNT; i++)
  675. {
  676. char * str = src->string[i];
  677. if (str)
  678. {
  679. str = strdup_or_die(str);
  680. freez(dest->string[i]);
  681. dest->string[i] = str;
  682. }
  683. }
  684. for (i = 0; i < ACTION_MULTI_COUNT; i++)
  685. {
  686. if (src->multi_remove_all[i])
  687. {
  688. /* Remove everything from dest, then add src->multi_add */
  689. err = list_duplicate(dest->multi[i], src->multi_add[i]);
  690. if (err)
  691. {
  692. return err;
  693. }
  694. }
  695. else
  696. {
  697. list_remove_list(dest->multi[i], src->multi_remove[i]);
  698. err = list_append_list_unique(dest->multi[i], src->multi_add[i]);
  699. if (err)
  700. {
  701. return err;
  702. }
  703. }
  704. }
  705. return err;
  706. }
  707. /*********************************************************************
  708. *
  709. * Function : update_action_bits_for_tag
  710. *
  711. * Description : Updates the action bits based on the action sections
  712. * whose tag patterns match a provided tag.
  713. *
  714. * Parameters :
  715. * 1 : csp = Current client state (buffers, headers, etc...)
  716. * 2 : tag = The tag on which the update should be based on
  717. *
  718. * Returns : 0 if no tag matched, or
  719. * 1 otherwise
  720. *
  721. *********************************************************************/
  722. int update_action_bits_for_tag(struct client_state *csp, const char *tag)
  723. {
  724. struct file_list *fl;
  725. struct url_actions *b;
  726. int updated = 0;
  727. int i;
  728. assert(tag);
  729. assert(list_contains_item(csp->tags, tag));
  730. /* Run through all action files, */
  731. for (i = 0; i < MAX_AF_FILES; i++)
  732. {
  733. if (((fl = csp->actions_list[i]) == NULL) || ((b = fl->f) == NULL))
  734. {
  735. /* Skip empty files */
  736. continue;
  737. }
  738. /* and through all the action patterns, */
  739. for (b = b->next; NULL != b; b = b->next)
  740. {
  741. /* skip everything but TAG patterns, */
  742. if (!(b->url->flags & PATTERN_SPEC_TAG_PATTERN))
  743. {
  744. continue;
  745. }
  746. /* and check if one of the tag patterns matches the tag, */
  747. if (0 == regexec(b->url->pattern.tag_regex, tag, 0, NULL, 0))
  748. {
  749. /* if it does, update the action bit map, */
  750. if (merge_current_action(csp->action, b->action))
  751. {
  752. log_error(LOG_LEVEL_ERROR,
  753. "Out of memory while changing action bits");
  754. }
  755. /* and signal the change. */
  756. updated = 1;
  757. }
  758. }
  759. }
  760. return updated;
  761. }
  762. /*********************************************************************
  763. *
  764. * Function : check_negative_tag_patterns
  765. *
  766. * Description : Updates the action bits based on NO-*-TAG patterns.
  767. *
  768. * Parameters :
  769. * 1 : csp = Current client state (buffers, headers, etc...)
  770. * 2 : flag = The tag pattern type
  771. *
  772. * Returns : JB_ERR_OK in case off success, or
  773. * JB_ERR_MEMORY on out-of-memory error.
  774. *
  775. *********************************************************************/
  776. jb_err check_negative_tag_patterns(struct client_state *csp, unsigned int flag)
  777. {
  778. struct list_entry *tag;
  779. struct file_list *fl;
  780. struct url_actions *b = NULL;
  781. int i;
  782. for (i = 0; i < MAX_AF_FILES; i++)
  783. {
  784. fl = csp->actions_list[i];
  785. if ((fl == NULL) || ((b = fl->f) == NULL))
  786. {
  787. continue;
  788. }
  789. for (b = b->next; NULL != b; b = b->next)
  790. {
  791. int tag_found = 0;
  792. if (0 == (b->url->flags & flag))
  793. {
  794. continue;
  795. }
  796. for (tag = csp->tags->first; NULL != tag; tag = tag->next)
  797. {
  798. if (0 == regexec(b->url->pattern.tag_regex, tag->str, 0, NULL, 0))
  799. {
  800. /*
  801. * The pattern matches at least one tag, thus the action
  802. * section doesn't apply and we don't need to look at the
  803. * other tags.
  804. */
  805. tag_found = 1;
  806. break;
  807. }
  808. }
  809. if (!tag_found)
  810. {
  811. /*
  812. * The pattern doesn't match any tags,
  813. * thus the action section applies.
  814. */
  815. if (merge_current_action(csp->action, b->action))
  816. {
  817. log_error(LOG_LEVEL_ERROR,
  818. "Out of memory while changing action bits");
  819. return JB_ERR_MEMORY;
  820. }
  821. log_error(LOG_LEVEL_HEADER, "Updated action bits based on: %s",
  822. b->url->spec);
  823. }
  824. }
  825. }
  826. return JB_ERR_OK;
  827. }
  828. /*********************************************************************
  829. *
  830. * Function : free_current_action
  831. *
  832. * Description : Free memory used by a current_action_spec.
  833. * Does not free the current_action_spec itself.
  834. *
  835. * Parameters :
  836. * 1 : src = Source to free.
  837. *
  838. * Returns : N/A
  839. *
  840. *********************************************************************/
  841. void free_current_action(struct current_action_spec *src)
  842. {
  843. int i;
  844. for (i = 0; i < ACTION_STRING_COUNT; i++)
  845. {
  846. freez(src->string[i]);
  847. }
  848. for (i = 0; i < ACTION_MULTI_COUNT; i++)
  849. {
  850. destroy_list(src->multi[i]);
  851. }
  852. memset(src, '\0', sizeof(*src));
  853. }
  854. static struct file_list *current_actions_file[MAX_AF_FILES] = {
  855. NULL, NULL, NULL, NULL, NULL,
  856. NULL, NULL, NULL, NULL, NULL
  857. };
  858. #ifdef FEATURE_GRACEFUL_TERMINATION
  859. /*********************************************************************
  860. *
  861. * Function : unload_current_actions_file
  862. *
  863. * Description : Unloads current actions file - reset to state at
  864. * beginning of program.
  865. *
  866. * Parameters : None
  867. *
  868. * Returns : N/A
  869. *
  870. *********************************************************************/
  871. void unload_current_actions_file(void)
  872. {
  873. int i;
  874. for (i = 0; i < MAX_AF_FILES; i++)
  875. {
  876. if (current_actions_file[i])
  877. {
  878. current_actions_file[i]->unloader = unload_actions_file;
  879. current_actions_file[i] = NULL;
  880. }
  881. }
  882. }
  883. #endif /* FEATURE_GRACEFUL_TERMINATION */
  884. /*********************************************************************
  885. *
  886. * Function : unload_actions_file
  887. *
  888. * Description : Unloads an actions module.
  889. *
  890. * Parameters :
  891. * 1 : file_data = the data structure associated with the
  892. * actions file.
  893. *
  894. * Returns : N/A
  895. *
  896. *********************************************************************/
  897. void unload_actions_file(void *file_data)
  898. {
  899. struct url_actions * next;
  900. struct url_actions * cur = (struct url_actions *)file_data;
  901. while (cur != NULL)
  902. {
  903. next = cur->next;
  904. free_pattern_spec(cur->url);
  905. if ((next == NULL) || (next->action != cur->action))
  906. {
  907. /*
  908. * As the action settings might be shared,
  909. * we can only free them if the current
  910. * url pattern is the last one, or if the
  911. * next one is using different settings.
  912. */
  913. free_action_spec(cur->action);
  914. }
  915. freez(cur);
  916. cur = next;
  917. }
  918. }
  919. /*********************************************************************
  920. *
  921. * Function : free_alias_list
  922. *
  923. * Description : Free memory used by a list of aliases.
  924. *
  925. * Parameters :
  926. * 1 : alias_list = Linked list to free.
  927. *
  928. * Returns : N/A
  929. *
  930. *********************************************************************/
  931. void free_alias_list(struct action_alias *alias_list)
  932. {
  933. while (alias_list != NULL)
  934. {
  935. struct action_alias * next = alias_list->next;
  936. alias_list->next = NULL;
  937. freez(alias_list->name);
  938. free_action(alias_list->action);
  939. free(alias_list);
  940. alias_list = next;
  941. }
  942. }
  943. /*********************************************************************
  944. *
  945. * Function : load_action_files
  946. *
  947. * Description : Read and parse all the action files and add to files
  948. * list.
  949. *
  950. * Parameters :
  951. * 1 : csp = Current client state (buffers, headers, etc...)
  952. *
  953. * Returns : 0 => Ok, everything else is an error.
  954. *
  955. *********************************************************************/
  956. int load_action_files(struct client_state *csp)
  957. {
  958. int i;
  959. int result;
  960. for (i = 0; i < MAX_AF_FILES; i++)
  961. {
  962. if (csp->config->actions_file[i])
  963. {
  964. result = load_one_actions_file(csp, i);
  965. if (result)
  966. {
  967. return result;
  968. }
  969. }
  970. else if (current_actions_file[i])
  971. {
  972. current_actions_file[i]->unloader = unload_actions_file;
  973. current_actions_file[i] = NULL;
  974. }
  975. }
  976. return 0;
  977. }
  978. /*********************************************************************
  979. *
  980. * Function : filter_type_to_string
  981. *
  982. * Description : Converts a filter type enum into a string.
  983. *
  984. * Parameters :
  985. * 1 : filter_type = filter_type as enum
  986. *
  987. * Returns : Pointer to static string.
  988. *
  989. *********************************************************************/
  990. static const char *filter_type_to_string(enum filter_type filter_type)
  991. {
  992. switch (filter_type)
  993. {
  994. case FT_CONTENT_FILTER:
  995. return "content filter";
  996. case FT_CLIENT_HEADER_FILTER:
  997. return "client-header filter";
  998. case FT_SERVER_HEADER_FILTER:
  999. return "server-header filter";
  1000. case FT_CLIENT_HEADER_TAGGER:
  1001. return "client-header tagger";
  1002. case FT_SERVER_HEADER_TAGGER:
  1003. return "server-header tagger";
  1004. #ifdef FEATURE_EXTERNAL_FILTERS
  1005. case FT_EXTERNAL_CONTENT_FILTER:
  1006. return "external content filter";
  1007. #endif
  1008. case FT_INVALID_FILTER:
  1009. return "invalid filter type";
  1010. }
  1011. return "unknown filter type";
  1012. }
  1013. /*********************************************************************
  1014. *
  1015. * Function : referenced_filters_are_missing
  1016. *
  1017. * Description : Checks if any filters of a certain type referenced
  1018. * in an action spec are missing.
  1019. *
  1020. * Parameters :
  1021. * 1 : csp = Current client state (buffers, headers, etc...)
  1022. * 2 : cur_action = The action spec to check.
  1023. * 3 : multi_index = The index where to look for the filter.
  1024. * 4 : filter_type = The filter type the caller is interested in.
  1025. *
  1026. * Returns : 0 => All referenced filters exist, everything else is an error.
  1027. *
  1028. *********************************************************************/
  1029. static int referenced_filters_are_missing(const struct client_state *csp,
  1030. const struct action_spec *cur_action, int multi_index, enum filter_type filter_type)
  1031. {
  1032. struct list_entry *filtername;
  1033. for (filtername = cur_action->multi_add[multi_index]->first;
  1034. filtername; filtername = filtername->next)
  1035. {
  1036. if (NULL == get_filter(csp, filtername->str, filter_type))
  1037. {
  1038. log_error(LOG_LEVEL_ERROR, "Missing %s '%s'",
  1039. filter_type_to_string(filter_type), filtername->str);
  1040. return 1;
  1041. }
  1042. }
  1043. return 0;
  1044. }
  1045. /*********************************************************************
  1046. *
  1047. * Function : action_spec_is_valid
  1048. *
  1049. * Description : Should eventually figure out if an action spec
  1050. * is valid, but currently only checks that the
  1051. * referenced filters are accounted for.
  1052. *
  1053. * Parameters :
  1054. * 1 : csp = Current client state (buffers, headers, etc...)
  1055. * 2 : cur_action = The action spec to check.
  1056. *
  1057. * Returns : 0 => No problems detected, everything else is an error.
  1058. *
  1059. *********************************************************************/
  1060. static int action_spec_is_valid(struct client_state *csp, const struct action_spec *cur_action)
  1061. {
  1062. struct {
  1063. int multi_index;
  1064. enum filter_type filter_type;
  1065. } filter_map[] = {
  1066. {ACTION_MULTI_FILTER, FT_CONTENT_FILTER},
  1067. {ACTION_MULTI_CLIENT_HEADER_FILTER, FT_CLIENT_HEADER_FILTER},
  1068. {ACTION_MULTI_SERVER_HEADER_FILTER, FT_SERVER_HEADER_FILTER},
  1069. {ACTION_MULTI_CLIENT_HEADER_TAGGER, FT_CLIENT_HEADER_TAGGER},
  1070. {ACTION_MULTI_SERVER_HEADER_TAGGER, FT_SERVER_HEADER_TAGGER}
  1071. };
  1072. int errors = 0;
  1073. int i;
  1074. for (i = 0; i < SZ(filter_map); i++)
  1075. {
  1076. errors += referenced_filters_are_missing(csp, cur_action,
  1077. filter_map[i].multi_index, filter_map[i].filter_type);
  1078. }
  1079. return errors;
  1080. }
  1081. /*********************************************************************
  1082. *
  1083. * Function : load_one_actions_file
  1084. *
  1085. * Description : Read and parse a action file and add to files
  1086. * list.
  1087. *
  1088. * Parameters :
  1089. * 1 : csp = Current client state (buffers, headers, etc...)
  1090. * 2 : fileid = File index to load.
  1091. *
  1092. * Returns : 0 => Ok, everything else is an error.
  1093. *
  1094. *********************************************************************/
  1095. #ifndef FUZZ
  1096. static
  1097. #endif
  1098. int load_one_actions_file(struct client_state *csp, int fileid)
  1099. {
  1100. /*
  1101. * Parser mode.
  1102. * Note: Keep these in the order they occur in the file, they are
  1103. * sometimes tested with <=
  1104. */
  1105. enum {
  1106. MODE_START_OF_FILE = 1,
  1107. MODE_SETTINGS = 2,
  1108. MODE_DESCRIPTION = 3,
  1109. MODE_ALIAS = 4,
  1110. MODE_ACTIONS = 5
  1111. } mode;
  1112. FILE *fp;
  1113. struct url_actions *last_perm;
  1114. struct url_actions *perm;
  1115. char *buf;
  1116. struct file_list *fs;
  1117. struct action_spec * cur_action = NULL;
  1118. int cur_action_used = 0;
  1119. struct action_alias * alias_list = NULL;
  1120. unsigned long linenum = 0;
  1121. mode = MODE_START_OF_FILE;
  1122. if (!check_file_changed(current_actions_file[fileid], csp->config->actions_file[fileid], &fs))
  1123. {
  1124. /* No need to load */
  1125. csp->actions_list[fileid] = current_actions_file[fileid];
  1126. return 0;
  1127. }
  1128. if (!fs)
  1129. {
  1130. log_error(LOG_LEVEL_FATAL, "can't load actions file '%s': %E. "
  1131. "Note that beginning with Privoxy 3.0.7, actions files have to be specified "
  1132. "with their complete file names.", csp->config->actions_file[fileid]);
  1133. return 1; /* never get here */
  1134. }
  1135. fs->f = last_perm = zalloc_or_die(sizeof(*last_perm));
  1136. if ((fp = fopen(csp->config->actions_file[fileid], "r")) == NULL)
  1137. {
  1138. log_error(LOG_LEVEL_FATAL, "can't load actions file '%s': error opening file: %E",
  1139. csp->config->actions_file[fileid]);
  1140. return 1; /* never get here */
  1141. }
  1142. log_error(LOG_LEVEL_INFO, "Loading actions file: %s", csp->config->actions_file[fileid]);
  1143. while (read_config_line(fp, &linenum, &buf) != NULL)
  1144. {
  1145. if (*buf == '{')
  1146. {
  1147. /* It's a header block */
  1148. if (buf[1] == '{')
  1149. {
  1150. /* It's {{settings}} or {{alias}} */
  1151. size_t len = strlen(buf);
  1152. char * start = buf + 2;
  1153. char * end = buf + len - 1;
  1154. if ((len < (size_t)5) || (*end-- != '}') || (*end-- != '}'))
  1155. {
  1156. /* too short */
  1157. fclose(fp);
  1158. log_error(LOG_LEVEL_FATAL,
  1159. "can't load actions file '%s': invalid line (%lu): %s",
  1160. csp->config->actions_file[fileid], linenum, buf);
  1161. return 1; /* never get here */
  1162. }
  1163. /* Trim leading and trailing whitespace. */
  1164. end[1] = '\0';
  1165. chomp(start);
  1166. if (*start == '\0')
  1167. {
  1168. /* too short */
  1169. fclose(fp);
  1170. log_error(LOG_LEVEL_FATAL,
  1171. "can't load actions file '%s': invalid line (%lu): {{ }}",
  1172. csp->config->actions_file[fileid], linenum);
  1173. return 1; /* never get here */
  1174. }
  1175. /*
  1176. * An actionsfile can optionally contain the following blocks.
  1177. * They *MUST* be in this order, to simplify processing:
  1178. *
  1179. * {{settings}}
  1180. * name=value...
  1181. *
  1182. * {{description}}
  1183. * ...free text, format TBD, but no line may start with a '{'...
  1184. *
  1185. * {{alias}}
  1186. * name=actions...
  1187. *
  1188. * The actual actions must be *after* these special blocks.
  1189. * None of these special blocks may be repeated.
  1190. *
  1191. */
  1192. if (0 == strcmpic(start, "settings"))
  1193. {
  1194. /* it's a {{settings}} block */
  1195. if (mode >= MODE_SETTINGS)
  1196. {
  1197. /* {{settings}} must be first thing in file and must only
  1198. * appear once.
  1199. */
  1200. fclose(fp);
  1201. log_error(LOG_LEVEL_FATAL,
  1202. "can't load actions file '%s': line %lu: {{settings}} must only appear once, and it must be before anything else.",
  1203. csp->config->actions_file[fileid], linenum);
  1204. }
  1205. mode = MODE_SETTINGS;
  1206. }
  1207. else if (0 == strcmpic(start, "description"))
  1208. {
  1209. /* it's a {{description}} block */
  1210. if (mode >= MODE_DESCRIPTION)
  1211. {
  1212. /* {{description}} is a singleton and only {{settings}} may proceed it
  1213. */
  1214. fclose(fp);
  1215. log_error(LOG_LEVEL_FATAL,
  1216. "can't load actions file '%s': line %lu: {{description}} must only appear once, and only a {{settings}} block may be above it.",
  1217. csp->config->actions_file[fileid], linenum);
  1218. }
  1219. mode = MODE_DESCRIPTION;
  1220. }
  1221. else if (0 == strcmpic(start, "alias"))
  1222. {
  1223. /* it's an {{alias}} block */
  1224. if (mode >= MODE_ALIAS)
  1225. {
  1226. /* {{alias}} must be first thing in file, possibly after
  1227. * {{settings}} and {{description}}
  1228. *
  1229. * {{alias}} must only appear once.
  1230. *
  1231. * Note that these are new restrictions introduced in
  1232. * v2.9.10 in order to make actionsfile editing simpler.
  1233. * (Otherwise, reordering actionsfile entries without
  1234. * completely rewriting the file becomes non-trivial)
  1235. */
  1236. fclose(fp);
  1237. log_error(LOG_LEVEL_FATAL,
  1238. "can't load actions file '%s': line %lu: {{alias}} must only appear once, and it must be before all actions.",
  1239. csp->config->actions_file[fileid], linenum);
  1240. }
  1241. mode = MODE_ALIAS;
  1242. }
  1243. else
  1244. {
  1245. /* invalid {{something}} block */
  1246. fclose(fp);
  1247. log_error(LOG_LEVEL_FATAL,
  1248. "can't load actions file '%s': invalid line (%lu): {{%s}}",
  1249. csp->config->actions_file[fileid], linenum, start);
  1250. return 1; /* never get here */
  1251. }
  1252. }
  1253. else
  1254. {
  1255. /* It's an actions block */
  1256. char *actions_buf;
  1257. char * end;
  1258. /* set mode */
  1259. mode = MODE_ACTIONS;
  1260. /* free old action */
  1261. if (cur_action)
  1262. {
  1263. if (!cur_action_used)
  1264. {
  1265. free_action_spec(cur_action);
  1266. }
  1267. cur_action = NULL;
  1268. }
  1269. cur_action_used = 0;
  1270. cur_action = zalloc_or_die(sizeof(*cur_action));
  1271. init_action(cur_action);
  1272. /*
  1273. * Copy the buffer before messing with it as we may need the
  1274. * unmodified version in for the fatal error messages. Given
  1275. * that this is not a common event, we could instead simply
  1276. * read the line again.
  1277. *
  1278. * buf + 1 to skip the leading '{'
  1279. */
  1280. actions_buf = end = strdup_or_die(buf + 1);
  1281. /* check we have a trailing } and then trim it */
  1282. if (strlen(actions_buf))
  1283. {
  1284. end += strlen(actions_buf) - 1;
  1285. }
  1286. if (*end != '}')
  1287. {
  1288. /* No closing } */
  1289. fclose(fp);
  1290. freez(actions_buf);
  1291. log_error(LOG_LEVEL_FATAL, "can't load actions file '%s': "
  1292. "Missing trailing '}' in action section starting at line (%lu): %s",
  1293. csp->config->actions_file[fileid], linenum, buf);
  1294. return 1; /* never get here */
  1295. }
  1296. *end = '\0';
  1297. /* trim any whitespace immediately inside {} */
  1298. chomp(actions_buf);
  1299. if (get_actions(actions_buf, alias_list, cur_action))
  1300. {
  1301. /* error */
  1302. fclose(fp);
  1303. freez(actions_buf);
  1304. log_error(LOG_LEVEL_FATAL, "can't load actions file '%s': "
  1305. "can't completely parse the action section starting at line (%lu): %s",
  1306. csp->config->actions_file[fileid], linenum, buf);
  1307. return 1; /* never get here */
  1308. }
  1309. if (action_spec_is_valid(csp, cur_action))
  1310. {
  1311. log_error(LOG_LEVEL_ERROR, "Invalid action section in file '%s', "
  1312. "starting at line %lu: %s",
  1313. csp->config->actions_file[fileid], linenum, buf);
  1314. }
  1315. freez(actions_buf);
  1316. }
  1317. }
  1318. else if (mode == MODE_SETTINGS)
  1319. {
  1320. /*
  1321. * Part of the {{settings}} block.
  1322. * For now only serves to check if the file's minimum Privoxy
  1323. * version requirement is met, but we may want to read & check
  1324. * permissions when we go multi-user.
  1325. */
  1326. if (!strncmp(buf, "for-privoxy-version=", 20))
  1327. {
  1328. char *version_string, *fields[3];
  1329. int num_fields;
  1330. version_string = strdup_or_die(buf + 20);
  1331. num_fields = ssplit(version_string, ".", fields, SZ(fields));
  1332. if (num_fields < 1 || atoi(fields[0]) == 0)
  1333. {
  1334. log_error(LOG_LEVEL_ERROR,
  1335. "While loading actions file '%s': invalid line (%lu): %s",
  1336. csp->config->actions_file[fileid], linenum, buf);
  1337. }
  1338. else if ( (atoi(fields[0]) > VERSION_MAJOR)
  1339. || ((num_fields > 1) && (atoi(fields[1]) > VERSION_MINOR))
  1340. || ((num_fields > 2) && (atoi(fields[2]) > VERSION_POINT)))
  1341. {
  1342. fclose(fp);
  1343. log_error(LOG_LEVEL_FATAL,
  1344. "Actions file '%s', line %lu requires newer Privoxy version: %s",
  1345. csp->config->actions_file[fileid], linenum, buf);
  1346. return 1; /* never get here */
  1347. }
  1348. free(version_string);
  1349. }
  1350. }
  1351. else if (mode == MODE_DESCRIPTION)
  1352. {
  1353. /*
  1354. * Part of the {{description}} block.
  1355. * Ignore for now.
  1356. */
  1357. }
  1358. else if (mode == MODE_ALIAS)
  1359. {
  1360. /*
  1361. * define an alias
  1362. */
  1363. char actions_buf[BUFFER_SIZE];
  1364. struct action_alias * new_alias;
  1365. char * start = strchr(buf, '=');
  1366. char * end = start;
  1367. if ((start == NULL) || (start == buf))
  1368. {
  1369. log_error(LOG_LEVEL_FATAL,
  1370. "can't load actions file '%s': invalid alias line (%lu): %s",
  1371. csp->config->actions_file[fileid], linenum, buf);
  1372. return 1; /* never get here */
  1373. }
  1374. new_alias = zalloc_or_die(sizeof(*new_alias));
  1375. /* Eat any the whitespace before the '=' */
  1376. end--;
  1377. while ((*end == ' ') || (*end == '\t'))
  1378. {
  1379. /*
  1380. * we already know we must have at least 1 non-ws char
  1381. * at start of buf - no need to check
  1382. */
  1383. end--;
  1384. }
  1385. end[1] = '\0';
  1386. /* Eat any the whitespace after the '=' */
  1387. start++;
  1388. while ((*start == ' ') || (*start == '\t'))
  1389. {
  1390. start++;
  1391. }
  1392. if (*start == '\0')
  1393. {
  1394. log_error(LOG_LEVEL_FATAL,
  1395. "can't load actions file '%s': invalid alias line (%lu): %s",
  1396. csp->config->actions_file[fileid], linenum, buf);
  1397. return 1; /* never get here */
  1398. }
  1399. new_alias->name = strdup_or_die(buf);
  1400. strlcpy(actions_buf, start, sizeof(actions_buf));
  1401. if (get_actions(actions_buf, alias_list, new_alias->action))
  1402. {
  1403. /* error */
  1404. fclose(fp);
  1405. log_error(LOG_LEVEL_FATAL,
  1406. "can't load actions file '%s': invalid alias line (%lu): %s = %s",
  1407. csp->config->actions_file[fileid], linenum, buf, start);
  1408. return 1; /* never get here */
  1409. }
  1410. /* add to list */
  1411. new_alias->next = alias_list;
  1412. alias_list = new_alias;
  1413. }
  1414. else if (mode == MODE_ACTIONS)
  1415. {
  1416. /* it's an URL pattern */
  1417. /* allocate a new node */
  1418. perm = zalloc_or_die(sizeof(*perm));
  1419. perm->action = cur_action;
  1420. cur_action_used = 1;
  1421. /* Save the URL pattern */
  1422. if (create_pattern_spec(perm->url, buf))
  1423. {
  1424. fclose(fp);
  1425. log_error(LOG_LEVEL_FATAL,
  1426. "can't load actions file '%s': line %lu: cannot create URL or TAG pattern from: %s",
  1427. csp->config->actions_file[fileid], linenum, buf);
  1428. return 1; /* never get here */
  1429. }
  1430. /* add it to the list */
  1431. last_perm->next = perm;
  1432. last_perm = perm;
  1433. }
  1434. else if (mode == MODE_START_OF_FILE)
  1435. {
  1436. /* oops - please have a {} line as 1st line in file. */
  1437. fclose(fp);
  1438. log_error(LOG_LEVEL_FATAL,
  1439. "can't load actions file '%s': line %lu should begin with a '{': %s",
  1440. csp->config->actions_file[fileid], linenum, buf);
  1441. return 1; /* never get here */
  1442. }
  1443. else
  1444. {
  1445. /* How did we get here? This is impossible! */
  1446. fclose(fp);
  1447. log_error(LOG_LEVEL_FATAL,
  1448. "can't load actions file '%s': INTERNAL ERROR - mode = %d",
  1449. csp->config->actions_file[fileid], mode);
  1450. return 1; /* never get here */
  1451. }
  1452. freez(buf);
  1453. }
  1454. fclose(fp);
  1455. if (!cur_action_used)
  1456. {
  1457. free_action_spec(cur_action);
  1458. }
  1459. free_alias_list(alias_list);
  1460. /* the old one is now obsolete */
  1461. if (current_actions_file[fileid])
  1462. {
  1463. current_actions_file[fileid]->unloader = unload_actions_file;
  1464. }
  1465. fs->next = files->next;
  1466. files->next = fs;
  1467. current_actions_file[fileid] = fs;
  1468. csp->actions_list[fileid] = fs;
  1469. return(0);
  1470. }
  1471. /*********************************************************************
  1472. *
  1473. * Function : actions_to_text
  1474. *
  1475. * Description : Converts a actionsfile entry from the internal
  1476. * structure into a text line. The output is split
  1477. * into one line for each action with line continuation.
  1478. *
  1479. * Parameters :
  1480. * 1 : action = The action to format.
  1481. *
  1482. * Returns : A string. Caller must free it.
  1483. * NULL on out-of-memory error.
  1484. *
  1485. *********************************************************************/
  1486. char * actions_to_text(const struct action_spec *action)
  1487. {
  1488. unsigned long mask = action->mask;
  1489. unsigned long add = action->add;
  1490. char *result = strdup_or_die("");
  1491. struct list_entry * lst;
  1492. /* sanity - prevents "-feature +feature" */
  1493. mask |= add;
  1494. #define DEFINE_ACTION_BOOL(__name, __bit) \
  1495. if (!(mask & __bit)) \
  1496. { \
  1497. string_append(&result, " -" __name " \\\n"); \
  1498. } \
  1499. else if (add & __bit) \
  1500. { \
  1501. string_append(&result, " +" __name " \\\n"); \
  1502. }
  1503. #define DEFINE_ACTION_STRING(__name, __bit, __index) \
  1504. if (!(mask & __bit)) \
  1505. { \
  1506. string_append(&result, " -" __name " \\\n"); \
  1507. } \
  1508. else if (add & __bit) \
  1509. { \
  1510. string_append(&result, " +" __name "{"); \
  1511. string_append(&result, action->string[__index]); \
  1512. string_append(&result, "} \\\n"); \
  1513. }
  1514. #define DEFINE_ACTION_MULTI(__name, __index) \
  1515. if (action->multi_remove_all[__index]) \
  1516. { \
  1517. string_append(&result, " -" __name " \\\n"); \
  1518. } \
  1519. else \
  1520. { \
  1521. lst = action->multi_remove[__index]->first; \
  1522. while (lst) \
  1523. { \
  1524. string_append(&result, " -" __name "{"); \
  1525. string_append(&result, lst->str); \
  1526. string_append(&result, "} \\\n"); \
  1527. lst = lst->next; \
  1528. } \
  1529. } \
  1530. lst = action->multi_add[__index]->first; \
  1531. while (lst) \
  1532. { \
  1533. string_append(&result, " +" __name "{"); \
  1534. string_append(&result, lst->str); \
  1535. string_append(&result, "} \\\n"); \
  1536. lst = lst->next; \
  1537. }
  1538. #define DEFINE_ACTION_ALIAS 0 /* No aliases for output */
  1539. #include "actionlist.h"
  1540. #undef DEFINE_ACTION_MULTI
  1541. #undef DEFINE_ACTION_STRING
  1542. #undef DEFINE_ACTION_BOOL
  1543. #undef DEFINE_ACTION_ALIAS
  1544. return result;
  1545. }
  1546. /*********************************************************************
  1547. *
  1548. * Function : actions_to_html
  1549. *
  1550. * Description : Converts a actionsfile entry from numeric form
  1551. * ("mask" and "add") to a <br>-separated HTML string
  1552. * in which each action is linked to its chapter in
  1553. * the user manual.
  1554. *
  1555. * Parameters :
  1556. * 1 : csp = Client state (for config)
  1557. * 2 : action = Action spec to be converted
  1558. *
  1559. * Returns : A string. Caller must free it.
  1560. * NULL on out-of-memory error.
  1561. *
  1562. *********************************************************************/
  1563. char * actions_to_html(const struct client_state *csp,
  1564. const struct action_spec *action)
  1565. {
  1566. unsigned long mask = action->mask;
  1567. unsigned long add = action->add;
  1568. char *result = strdup_or_die("");
  1569. struct list_entry * lst;
  1570. /* sanity - prevents "-feature +feature" */
  1571. mask |= add;
  1572. #define DEFINE_ACTION_BOOL(__name, __bit) \
  1573. if (!(mask & __bit)) \
  1574. { \
  1575. string_append(&result, "\n<br>-"); \
  1576. string_join(&result, add_help_link(__name, csp->config)); \
  1577. } \
  1578. else if (add & __bit) \
  1579. { \
  1580. string_append(&result, "\n<br>+"); \
  1581. string_join(&result, add_help_link(__name, csp->config)); \
  1582. }
  1583. #define DEFINE_ACTION_STRING(__name, __bit, __index) \
  1584. if (!(mask & __bit)) \
  1585. { \
  1586. string_append(&result, "\n<br>-"); \
  1587. string_join(&result, add_help_link(__name, csp->config)); \
  1588. } \
  1589. else if (add & __bit) \
  1590. { \
  1591. string_append(&result, "\n<br>+"); \
  1592. string_join(&result, add_help_link(__name, csp->config)); \
  1593. string_append(&result, "{"); \
  1594. string_join(&result, html_encode(action->string[__index])); \
  1595. string_append(&result, "}"); \
  1596. }
  1597. #define DEFINE_ACTION_MULTI(__name, __index) \
  1598. if (action->multi_remove_all[__index]) \
  1599. { \
  1600. string_append(&result, "\n<br>-"); \
  1601. string_join(&result, add_help_link(__name, csp->config)); \
  1602. } \
  1603. else \
  1604. { \
  1605. lst = action->multi_remove[__index]->first; \
  1606. while (lst) \
  1607. { \
  1608. string_append(&result, "\n<br>-"); \
  1609. string_join(&result, add_help_link(__name, csp->config)); \
  1610. string_append(&result, "{"); \
  1611. string_join(&result, html_encode(lst->str)); \
  1612. string_append(&result, "}"); \
  1613. lst = lst->next; \
  1614. } \
  1615. } \
  1616. lst = action->multi_add[__index]->first; \
  1617. while (lst) \
  1618. { \
  1619. string_append(&result, "\n<br>+"); \
  1620. string_join(&result, add_help_link(__name, csp->config)); \
  1621. string_append(&result, "{"); \
  1622. string_join(&result, html_encode(lst->str)); \
  1623. string_append(&result, "}"); \
  1624. lst = lst->next; \
  1625. }
  1626. #define DEFINE_ACTION_ALIAS 0 /* No aliases for output */
  1627. #include "actionlist.h"
  1628. #undef DEFINE_ACTION_MULTI
  1629. #undef DEFINE_ACTION_STRING
  1630. #undef DEFINE_ACTION_BOOL
  1631. #undef DEFINE_ACTION_ALIAS
  1632. /* trim leading <br> */
  1633. if (result && *result)
  1634. {
  1635. char * s = result;
  1636. result = strdup(result + 5);
  1637. free(s);
  1638. }
  1639. return result;
  1640. }
  1641. /*********************************************************************
  1642. *
  1643. * Function : current_actions_to_html
  1644. *
  1645. * Description : Converts a current action spec to a <br> separated HTML
  1646. * text in which each action is linked to its chapter in
  1647. * the user manual.
  1648. *
  1649. * Parameters :
  1650. * 1 : csp = Client state (for config)
  1651. * 2 : action = Current action spec to be converted
  1652. *
  1653. * Returns : A string. Caller must free it.
  1654. * NULL on out-of-memory error.
  1655. *
  1656. *********************************************************************/
  1657. char *current_action_to_html(const struct client_state *csp,
  1658. const struct current_action_spec *action)
  1659. {
  1660. unsigned long flags = action->flags;
  1661. struct list_entry * lst;
  1662. char *result = strdup_or_die("");
  1663. char *active = strdup_or_die("");
  1664. char *inactive = strdup_or_die("");
  1665. #define DEFINE_ACTION_BOOL(__name, __bit) \
  1666. if (flags & __bit) \
  1667. { \
  1668. string_append(&active, "\n<br>+"); \
  1669. string_join(&active, add_help_link(__name, csp->config)); \
  1670. } \
  1671. else \
  1672. { \
  1673. string_append(&inactive, "\n<br>-"); \
  1674. string_join(&inactive, add_help_link(__name, csp->config)); \
  1675. }
  1676. #define DEFINE_ACTION_STRING(__name, __bit, __index) \
  1677. if (flags & __bit) \
  1678. { \
  1679. string_append(&active, "\n<br>+"); \
  1680. string_join(&active, add_help_link(__name, csp->config)); \
  1681. string_append(&active, "{"); \
  1682. string_join(&active, html_encode(action->string[__index])); \
  1683. string_append(&active, "}"); \
  1684. } \
  1685. else \
  1686. { \
  1687. string_append(&inactive, "\n<br>-"); \
  1688. string_join(&inactive, add_help_link(__name, csp->config)); \
  1689. }
  1690. #define DEFINE_ACTION_MULTI(__name, __index) \
  1691. lst = action->multi[__index]->first; \
  1692. if (lst == NULL) \
  1693. { \
  1694. string_append(&inactive, "\n<br>-"); \
  1695. string_join(&inactive, add_help_link(__name, csp->config)); \
  1696. } \
  1697. else \
  1698. { \
  1699. while (lst) \
  1700. { \
  1701. string_append(&active, "\n<br>+"); \
  1702. string_join(&active, add_help_link(__name, csp->config)); \
  1703. string_append(&active, "{"); \
  1704. string_join(&active, html_encode(lst->str)); \
  1705. string_append(&active, "}"); \
  1706. lst = lst->next; \
  1707. } \
  1708. }
  1709. #define DEFINE_ACTION_ALIAS 0 /* No aliases for output */
  1710. #include "actionlist.h"
  1711. #undef DEFINE_ACTION_MULTI
  1712. #undef DEFINE_ACTION_STRING
  1713. #undef DEFINE_ACTION_BOOL
  1714. #undef DEFINE_ACTION_ALIAS
  1715. if (active != NULL)
  1716. {
  1717. string_append(&result, active);
  1718. freez(active);
  1719. }
  1720. string_append(&result, "\n<br>");
  1721. if (inactive != NULL)
  1722. {
  1723. string_append(&result, inactive);
  1724. freez(inactive);
  1725. }
  1726. return result;
  1727. }
  1728. /*********************************************************************
  1729. *
  1730. * Function : action_to_line_of_text
  1731. *
  1732. * Description : Converts a action spec to a single text line
  1733. * listing the enabled actions.
  1734. *
  1735. * Parameters :
  1736. * 1 : action = Current action spec to be converted
  1737. *
  1738. * Returns : A string. Caller must free it.
  1739. * Out-of-memory errors are fatal.
  1740. *
  1741. *********************************************************************/
  1742. char *actions_to_line_of_text(const struct current_action_spec *action)
  1743. {
  1744. char buffer[200];
  1745. struct list_entry *lst;
  1746. char *active;
  1747. const unsigned long flags = action->flags;
  1748. active = strdup_or_die("");
  1749. #define DEFINE_ACTION_BOOL(__name, __bit) \
  1750. if (flags & __bit) \
  1751. { \
  1752. snprintf(buffer, sizeof(buffer), "+%s ", __name); \
  1753. string_append(&active, buffer); \
  1754. } \
  1755. #define DEFINE_ACTION_STRING(__name, __bit, __index) \
  1756. if (flags & __bit) \
  1757. { \
  1758. snprintf(buffer, sizeof(buffer), "+%s{%s} ", \
  1759. __name, action->string[__index]); \
  1760. string_append(&active, buffer); \
  1761. } \
  1762. #define DEFINE_ACTION_MULTI(__name, __index) \
  1763. lst = action->multi[__index]->first; \
  1764. while (lst != NULL) \
  1765. { \
  1766. snprintf(buffer, sizeof(buffer), "+%s{%s} ", \
  1767. __name, lst->str); \
  1768. string_append(&active, buffer); \
  1769. lst = lst->next; \
  1770. } \
  1771. #define DEFINE_ACTION_ALIAS 0 /* No aliases for output */
  1772. #include "actionlist.h"
  1773. #undef DEFINE_ACTION_MULTI
  1774. #undef DEFINE_ACTION_STRING
  1775. #undef DEFINE_ACTION_BOOL
  1776. #undef DEFINE_ACTION_ALIAS
  1777. if (active == NULL)
  1778. {
  1779. log_error(LOG_LEVEL_FATAL, "Out of memory in action_to_line_of_text()");
  1780. }
  1781. return active;
  1782. }