loaders.c 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526
  1. /*********************************************************************
  2. *
  3. * File : $Source: /cvsroot/ijbswa/current/loaders.c,v $
  4. *
  5. * Purpose : Functions to load and unload the various
  6. * configuration files. Also contains code to manage
  7. * the list of active loaders, and to automatically
  8. * unload files that are no longer in use.
  9. *
  10. * Copyright : Written by and Copyright (C) 2001-2014 the
  11. * Privoxy team. https://www.privoxy.org/
  12. *
  13. * Based on the Internet Junkbuster originally written
  14. * by and Copyright (C) 1997 Anonymous Coders and
  15. * Junkbusters Corporation. http://www.junkbusters.com
  16. *
  17. * This program is free software; you can redistribute it
  18. * and/or modify it under the terms of the GNU General
  19. * Public License as published by the Free Software
  20. * Foundation; either version 2 of the License, or (at
  21. * your option) any later version.
  22. *
  23. * This program is distributed in the hope that it will
  24. * be useful, but WITHOUT ANY WARRANTY; without even the
  25. * implied warranty of MERCHANTABILITY or FITNESS FOR A
  26. * PARTICULAR PURPOSE. See the GNU General Public
  27. * License for more details.
  28. *
  29. * The GNU General Public License should be included with
  30. * this file. If not, you can view it at
  31. * http://www.gnu.org/copyleft/gpl.html
  32. * or write to the Free Software Foundation, Inc., 59
  33. * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  34. *
  35. *********************************************************************/
  36. #include "config.h"
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <sys/types.h>
  40. #include <string.h>
  41. #include <errno.h>
  42. #include <sys/stat.h>
  43. #include <ctype.h>
  44. #include <assert.h>
  45. #if !defined(_WIN32)
  46. #include <unistd.h>
  47. #endif
  48. #include "project.h"
  49. #include "list.h"
  50. #include "loaders.h"
  51. #include "filters.h"
  52. #include "parsers.h"
  53. #include "jcc.h"
  54. #include "miscutil.h"
  55. #include "errlog.h"
  56. #include "actions.h"
  57. #include "urlmatch.h"
  58. #include "encode.h"
  59. /*
  60. * Currently active files.
  61. * These are also entered in the main linked list of files.
  62. */
  63. #ifdef FEATURE_TRUST
  64. static struct file_list *current_trustfile = NULL;
  65. #endif /* def FEATURE_TRUST */
  66. #ifndef FUZZ
  67. static int load_one_re_filterfile(struct client_state *csp, int fileid);
  68. #endif
  69. static struct file_list *current_re_filterfile[MAX_AF_FILES] = {
  70. NULL, NULL, NULL, NULL, NULL,
  71. NULL, NULL, NULL, NULL, NULL
  72. };
  73. /*********************************************************************
  74. *
  75. * Function : free_csp_resources
  76. *
  77. * Description : Frees memory referenced by the csp that isn't
  78. * shared with other csps.
  79. *
  80. * Parameters :
  81. * 1 : csp = Current client state (buffers, headers, etc...)
  82. *
  83. * Returns : N/A
  84. *
  85. *********************************************************************/
  86. void free_csp_resources(struct client_state *csp)
  87. {
  88. freez(csp->ip_addr_str);
  89. #ifdef FEATURE_CLIENT_TAGS
  90. freez(csp->client_address);
  91. #endif
  92. freez(csp->listen_addr_str);
  93. freez(csp->client_iob->buf);
  94. freez(csp->iob->buf);
  95. freez(csp->error_message);
  96. if (csp->action->flags & ACTION_FORWARD_OVERRIDE &&
  97. NULL != csp->fwd)
  98. {
  99. unload_forward_spec(csp->fwd);
  100. }
  101. free_http_request(csp->http);
  102. destroy_list(csp->headers);
  103. #ifdef FEATURE_HTTPS_INSPECTION
  104. destroy_list(csp->https_headers);
  105. #endif
  106. destroy_list(csp->tags);
  107. #ifdef FEATURE_CLIENT_TAGS
  108. destroy_list(csp->client_tags);
  109. #endif
  110. free_current_action(csp->action);
  111. }
  112. /*********************************************************************
  113. *
  114. * Function : sweep
  115. *
  116. * Description : Basically a mark and sweep garbage collector, it is run
  117. * (by the parent thread) every once in a while to reclaim memory.
  118. *
  119. * It uses a mark and sweep strategy:
  120. * 1) mark all files as inactive
  121. *
  122. * 2) check with each client:
  123. * if it is active, mark its files as active
  124. * if it is inactive, free its resources
  125. *
  126. * 3) free the resources of all of the files that
  127. * are still marked as inactive (and are obsolete).
  128. *
  129. * N.B. files that are not obsolete don't have an unloader defined.
  130. *
  131. * Parameters : None
  132. *
  133. * Returns : The number of threads that are still active.
  134. *
  135. *********************************************************************/
  136. unsigned int sweep(void)
  137. {
  138. struct file_list *fl, *nfl;
  139. struct client_state *csp;
  140. struct client_states *last_active, *client_list;
  141. int i;
  142. unsigned int active_threads = 0;
  143. /* clear all of the file's active flags */
  144. for (fl = files->next; NULL != fl; fl = fl->next)
  145. {
  146. fl->active = 0;
  147. }
  148. last_active = clients;
  149. client_list = clients->next;
  150. while (NULL != client_list)
  151. {
  152. csp = &client_list->csp;
  153. if (csp->flags & CSP_FLAG_ACTIVE)
  154. {
  155. /* Mark this client's files as active */
  156. /*
  157. * Always have a configuration file.
  158. * (Also note the slightly non-standard extra
  159. * indirection here.)
  160. */
  161. csp->config->config_file_list->active = 1;
  162. /*
  163. * Actions files
  164. */
  165. for (i = 0; i < MAX_AF_FILES; i++)
  166. {
  167. if (csp->actions_list[i])
  168. {
  169. csp->actions_list[i]->active = 1;
  170. }
  171. }
  172. /*
  173. * Filter files
  174. */
  175. for (i = 0; i < MAX_AF_FILES; i++)
  176. {
  177. if (csp->rlist[i])
  178. {
  179. csp->rlist[i]->active = 1;
  180. }
  181. }
  182. /*
  183. * Trust file
  184. */
  185. #ifdef FEATURE_TRUST
  186. if (csp->tlist)
  187. {
  188. csp->tlist->active = 1;
  189. }
  190. #endif /* def FEATURE_TRUST */
  191. active_threads++;
  192. last_active = client_list;
  193. client_list = client_list->next;
  194. }
  195. else
  196. /*
  197. * This client is not active. Free its resources.
  198. */
  199. {
  200. last_active->next = client_list->next;
  201. #ifdef FEATURE_STATISTICS
  202. urls_read++;
  203. if (csp->flags & CSP_FLAG_REJECTED)
  204. {
  205. urls_rejected++;
  206. }
  207. #endif /* def FEATURE_STATISTICS */
  208. freez(client_list);
  209. client_list = last_active->next;
  210. }
  211. }
  212. nfl = files;
  213. fl = files->next;
  214. while (fl != NULL)
  215. {
  216. if ((0 == fl->active) && (NULL != fl->unloader))
  217. {
  218. nfl->next = fl->next;
  219. (fl->unloader)(fl->f);
  220. freez(fl->filename);
  221. freez(fl);
  222. fl = nfl->next;
  223. }
  224. else
  225. {
  226. nfl = fl;
  227. fl = fl->next;
  228. }
  229. }
  230. return active_threads;
  231. }
  232. /*********************************************************************
  233. *
  234. * Function : check_file_changed
  235. *
  236. * Description : Helper function to check if a file needs reloading.
  237. * If "current" is still current, return it. Otherwise
  238. * allocates a new (zeroed) "struct file_list", fills
  239. * in the disk file name and timestamp, and returns it.
  240. *
  241. * Parameters :
  242. * 1 : current = The file_list currently being used - will
  243. * be checked to see if it is out of date.
  244. * May be NULL (which is treated as out of
  245. * date).
  246. * 2 : filename = Name of file to check.
  247. * 3 : newfl = New file list. [Output only]
  248. * This will be set to NULL, OR a struct
  249. * file_list newly allocated on the
  250. * heap, with the filename and lastmodified
  251. * fields filled, and all others zeroed.
  252. *
  253. * Returns : If file unchanged: 0 (and sets newfl == NULL)
  254. * If file changed: 1 and sets newfl != NULL
  255. * On error: 1 and sets newfl == NULL
  256. *
  257. *********************************************************************/
  258. int check_file_changed(const struct file_list * current,
  259. const char * filename,
  260. struct file_list ** newfl)
  261. {
  262. struct file_list *fs;
  263. struct stat statbuf[1];
  264. *newfl = NULL;
  265. if (stat(filename, statbuf) < 0)
  266. {
  267. /* Error, probably file not found. */
  268. return 1;
  269. }
  270. if (current
  271. && (current->lastmodified == statbuf->st_mtime)
  272. && (0 == strcmp(current->filename, filename)))
  273. {
  274. return 0;
  275. }
  276. fs = zalloc_or_die(sizeof(struct file_list));
  277. fs->filename = strdup_or_die(filename);
  278. fs->lastmodified = statbuf->st_mtime;
  279. *newfl = fs;
  280. return 1;
  281. }
  282. /*********************************************************************
  283. *
  284. * Function : simple_read_line
  285. *
  286. * Description : Read a single line from a file and return it.
  287. * This is basically a version of fgets() that malloc()s
  288. * it's own line buffer. Note that the buffer will
  289. * always be a multiple of BUFFER_SIZE bytes long.
  290. * Therefore if you are going to keep the string for
  291. * an extended period of time, you should probably
  292. * strdup() it and free() the original, to save memory.
  293. *
  294. *
  295. * Parameters :
  296. * 1 : dest = destination for newly malloc'd pointer to
  297. * line data. Will be set to NULL on error.
  298. * 2 : fp = File to read from
  299. * 3 : newline = Standard for newlines in the file.
  300. * Will be unchanged if it's value on input is not
  301. * NEWLINE_UNKNOWN.
  302. * On output, may be changed from NEWLINE_UNKNOWN to
  303. * actual convention in file.
  304. *
  305. * Returns : JB_ERR_OK on success
  306. * JB_ERR_MEMORY on out-of-memory
  307. * JB_ERR_FILE on EOF.
  308. *
  309. *********************************************************************/
  310. jb_err simple_read_line(FILE *fp, char **dest, int *newline)
  311. {
  312. size_t len = 0;
  313. size_t buflen = BUFFER_SIZE;
  314. char * buf;
  315. char * p;
  316. int ch;
  317. int realnewline = NEWLINE_UNKNOWN;
  318. if (NULL == (buf = malloc(buflen)))
  319. {
  320. return JB_ERR_MEMORY;
  321. }
  322. p = buf;
  323. /*
  324. * Character codes. If you have a weird compiler and the following are
  325. * incorrect, you also need to fix NEWLINE() in loaders.h
  326. */
  327. #define CHAR_CR '\r' /* ASCII 13 */
  328. #define CHAR_LF '\n' /* ASCII 10 */
  329. for (;;)
  330. {
  331. ch = getc(fp);
  332. if (ch == EOF)
  333. {
  334. if (len > 0)
  335. {
  336. *p = '\0';
  337. *dest = buf;
  338. return JB_ERR_OK;
  339. }
  340. else
  341. {
  342. free(buf);
  343. *dest = NULL;
  344. return JB_ERR_FILE;
  345. }
  346. }
  347. else if (ch == CHAR_CR)
  348. {
  349. ch = getc(fp);
  350. if (ch == CHAR_LF)
  351. {
  352. if (*newline == NEWLINE_UNKNOWN)
  353. {
  354. *newline = NEWLINE_DOS;
  355. }
  356. }
  357. else
  358. {
  359. if (ch != EOF)
  360. {
  361. ungetc(ch, fp);
  362. }
  363. if (*newline == NEWLINE_UNKNOWN)
  364. {
  365. *newline = NEWLINE_MAC;
  366. }
  367. }
  368. *p = '\0';
  369. *dest = buf;
  370. if (*newline == NEWLINE_UNKNOWN)
  371. {
  372. *newline = realnewline;
  373. }
  374. return JB_ERR_OK;
  375. }
  376. else if (ch == CHAR_LF)
  377. {
  378. *p = '\0';
  379. *dest = buf;
  380. if (*newline == NEWLINE_UNKNOWN)
  381. {
  382. *newline = NEWLINE_UNIX;
  383. }
  384. return JB_ERR_OK;
  385. }
  386. else if (ch == 0)
  387. {
  388. /* XXX: Why do we allow this anyway? */
  389. *p = '\0';
  390. *dest = buf;
  391. return JB_ERR_OK;
  392. }
  393. *p++ = (char)ch;
  394. if (++len >= buflen)
  395. {
  396. buflen += BUFFER_SIZE;
  397. if (NULL == (p = realloc(buf, buflen)))
  398. {
  399. free(buf);
  400. return JB_ERR_MEMORY;
  401. }
  402. buf = p;
  403. p = buf + len;
  404. }
  405. }
  406. }
  407. /*********************************************************************
  408. *
  409. * Function : edit_read_line
  410. *
  411. * Description : Read a single non-empty line from a file and return
  412. * it. Trims comments, leading and trailing whitespace
  413. * and respects escaping of newline and comment char.
  414. * Provides the line in 2 alternative forms: raw and
  415. * preprocessed.
  416. * - raw is the raw data read from the file. If the
  417. * line is not modified, then this should be written
  418. * to the new file.
  419. * - prefix is any comments and blank lines that were
  420. * read from the file. If the line is modified, then
  421. * this should be written out to the file followed
  422. * by the modified data. (If this string is non-empty
  423. * then it will have a newline at the end).
  424. * - data is the actual data that will be parsed
  425. * further by appropriate routines.
  426. * On EOF, the 3 strings will all be set to NULL and
  427. * 0 will be returned.
  428. *
  429. * Parameters :
  430. * 1 : fp = File to read from
  431. * 2 : raw_out = destination for newly malloc'd pointer to
  432. * raw line data. May be NULL if you don't want it.
  433. * 3 : prefix_out = destination for newly malloc'd pointer to
  434. * comments. May be NULL if you don't want it.
  435. * 4 : data_out = destination for newly malloc'd pointer to
  436. * line data with comments and leading/trailing spaces
  437. * removed, and line continuation performed. May be
  438. * NULL if you don't want it.
  439. * 5 : newline = Standard for newlines in the file.
  440. * On input, set to value to use or NEWLINE_UNKNOWN.
  441. * On output, may be changed from NEWLINE_UNKNOWN to
  442. * actual convention in file. May be NULL if you
  443. * don't want it.
  444. * 6 : line_number = Line number in file. In "lines" as
  445. * reported by a text editor, not lines containing data.
  446. *
  447. * Returns : JB_ERR_OK on success
  448. * JB_ERR_MEMORY on out-of-memory
  449. * JB_ERR_FILE on EOF.
  450. *
  451. *********************************************************************/
  452. jb_err edit_read_line(FILE *fp,
  453. char **raw_out,
  454. char **prefix_out,
  455. char **data_out,
  456. int *newline,
  457. unsigned long *line_number)
  458. {
  459. char *p; /* Temporary pointer */
  460. char *linebuf; /* Line read from file */
  461. char *linestart; /* Start of linebuf, usually first non-whitespace char */
  462. int contflag = 0; /* Nonzero for line continuation - i.e. line ends '\' */
  463. int is_empty = 1; /* Flag if not got any data yet */
  464. char *raw = NULL; /* String to be stored in raw_out */
  465. char *prefix = NULL; /* String to be stored in prefix_out */
  466. char *data = NULL; /* String to be stored in data_out */
  467. int scrapnewline; /* Used for (*newline) if newline==NULL */
  468. jb_err rval = JB_ERR_OK;
  469. assert(fp);
  470. assert(raw_out || data_out);
  471. assert(newline == NULL
  472. || *newline == NEWLINE_UNKNOWN
  473. || *newline == NEWLINE_UNIX
  474. || *newline == NEWLINE_DOS
  475. || *newline == NEWLINE_MAC);
  476. if (newline == NULL)
  477. {
  478. scrapnewline = NEWLINE_UNKNOWN;
  479. newline = &scrapnewline;
  480. }
  481. /* Set output parameters to NULL */
  482. if (raw_out)
  483. {
  484. *raw_out = NULL;
  485. }
  486. if (prefix_out)
  487. {
  488. *prefix_out = NULL;
  489. }
  490. if (data_out)
  491. {
  492. *data_out = NULL;
  493. }
  494. /* Set string variables to new, empty strings. */
  495. if (raw_out)
  496. {
  497. raw = strdup_or_die("");
  498. }
  499. if (prefix_out)
  500. {
  501. prefix = strdup_or_die("");
  502. }
  503. if (data_out)
  504. {
  505. data = strdup_or_die("");
  506. }
  507. /* Main loop. Loop while we need more data & it's not EOF. */
  508. while ((contflag || is_empty)
  509. && (JB_ERR_OK == (rval = simple_read_line(fp, &linebuf, newline))))
  510. {
  511. if (line_number)
  512. {
  513. (*line_number)++;
  514. }
  515. if (raw)
  516. {
  517. string_append(&raw,linebuf);
  518. if (string_append(&raw,NEWLINE(*newline)))
  519. {
  520. freez(prefix);
  521. freez(data);
  522. free(linebuf);
  523. return JB_ERR_MEMORY;
  524. }
  525. }
  526. /* Line continuation? Trim escape and set flag. */
  527. p = linebuf + strlen(linebuf) - 1;
  528. contflag = ((*linebuf != '\0') && (*p == '\\'));
  529. if (contflag)
  530. {
  531. *p = '\0';
  532. }
  533. /* Trim leading spaces if we're at the start of the line */
  534. linestart = linebuf;
  535. assert(NULL != data);
  536. if (*data == '\0')
  537. {
  538. /* Trim leading spaces */
  539. while (*linestart && isspace((int)(unsigned char)*linestart))
  540. {
  541. linestart++;
  542. }
  543. }
  544. /* Handle comment characters. */
  545. p = linestart;
  546. while ((p = strchr(p, '#')) != NULL)
  547. {
  548. /* Found a comment char.. */
  549. if ((p != linebuf) && (*(p-1) == '\\'))
  550. {
  551. /* ..and it's escaped, left-shift the line over the escape. */
  552. char *q = p - 1;
  553. while ((*q = *(q + 1)) != '\0')
  554. {
  555. q++;
  556. }
  557. /* Now scan from just after the "#". */
  558. }
  559. else
  560. {
  561. /* Real comment. Save it... */
  562. if (p == linestart)
  563. {
  564. /* Special case: Line only contains a comment, so all the
  565. * previous whitespace is considered part of the comment.
  566. * Undo the whitespace skipping, if any.
  567. */
  568. linestart = linebuf;
  569. p = linestart;
  570. }
  571. if (prefix)
  572. {
  573. string_append(&prefix,p);
  574. if (string_append(&prefix, NEWLINE(*newline)))
  575. {
  576. freez(raw);
  577. freez(data);
  578. free(linebuf);
  579. return JB_ERR_MEMORY;
  580. }
  581. }
  582. /* ... and chop off the rest of the line */
  583. *p = '\0';
  584. }
  585. } /* END while (there's a # character) */
  586. /* Write to the buffer */
  587. if (*linestart)
  588. {
  589. is_empty = 0;
  590. if (string_append(&data, linestart))
  591. {
  592. freez(raw);
  593. freez(prefix);
  594. free(linebuf);
  595. return JB_ERR_MEMORY;
  596. }
  597. }
  598. free(linebuf);
  599. } /* END while(we need more data) */
  600. /* Handle simple_read_line() errors - ignore EOF */
  601. if ((rval != JB_ERR_OK) && (rval != JB_ERR_FILE))
  602. {
  603. freez(raw);
  604. freez(prefix);
  605. freez(data);
  606. return rval;
  607. }
  608. if (raw ? (*raw == '\0') : is_empty)
  609. {
  610. /* EOF and no data there. (Definition of "data" depends on whether
  611. * the caller cares about "raw" or just "data").
  612. */
  613. freez(raw);
  614. freez(prefix);
  615. freez(data);
  616. return JB_ERR_FILE;
  617. }
  618. else
  619. {
  620. /* Got at least some data */
  621. /* Remove trailing whitespace */
  622. chomp(data);
  623. if (raw_out)
  624. {
  625. *raw_out = raw;
  626. }
  627. else
  628. {
  629. freez(raw);
  630. }
  631. if (prefix_out)
  632. {
  633. *prefix_out = prefix;
  634. }
  635. else
  636. {
  637. freez(prefix);
  638. }
  639. if (data_out)
  640. {
  641. *data_out = data;
  642. }
  643. else
  644. {
  645. freez(data);
  646. }
  647. return JB_ERR_OK;
  648. }
  649. }
  650. /*********************************************************************
  651. *
  652. * Function : read_config_line
  653. *
  654. * Description : Read a single non-empty line from a file and return
  655. * it. Trims comments, leading and trailing whitespace
  656. * and respects escaping of newline and comment char.
  657. *
  658. * Parameters :
  659. * 1 : fp = File to read from
  660. * 2 : linenum = linenumber in file
  661. * 3 : buf = Pointer to a pointer to set to the data buffer.
  662. *
  663. * Returns : NULL on EOF or error
  664. * Otherwise, returns buf.
  665. *
  666. *********************************************************************/
  667. char *read_config_line(FILE *fp, unsigned long *linenum, char **buf)
  668. {
  669. jb_err err;
  670. err = edit_read_line(fp, NULL, NULL, buf, NULL, linenum);
  671. if (err)
  672. {
  673. if (err == JB_ERR_MEMORY)
  674. {
  675. log_error(LOG_LEVEL_FATAL, "Out of memory loading a config file");
  676. }
  677. *buf = NULL;
  678. }
  679. return *buf;
  680. }
  681. #ifdef FEATURE_TRUST
  682. /*********************************************************************
  683. *
  684. * Function : unload_trustfile
  685. *
  686. * Description : Unloads a trustfile.
  687. *
  688. * Parameters :
  689. * 1 : f = the data structure associated with the trustfile.
  690. *
  691. * Returns : N/A
  692. *
  693. *********************************************************************/
  694. static void unload_trustfile(void *f)
  695. {
  696. struct block_spec *cur = (struct block_spec *)f;
  697. struct block_spec *next;
  698. while (cur != NULL)
  699. {
  700. next = cur->next;
  701. free_pattern_spec(cur->url);
  702. free(cur);
  703. cur = next;
  704. }
  705. }
  706. #ifdef FEATURE_GRACEFUL_TERMINATION
  707. /*********************************************************************
  708. *
  709. * Function : unload_current_trust_file
  710. *
  711. * Description : Unloads current trust file - reset to state at
  712. * beginning of program.
  713. *
  714. * Parameters : None
  715. *
  716. * Returns : N/A
  717. *
  718. *********************************************************************/
  719. void unload_current_trust_file(void)
  720. {
  721. if (current_trustfile)
  722. {
  723. current_trustfile->unloader = unload_trustfile;
  724. current_trustfile = NULL;
  725. }
  726. }
  727. #endif /* FEATURE_GRACEFUL_TERMINATION */
  728. /*********************************************************************
  729. *
  730. * Function : load_trustfile
  731. *
  732. * Description : Read and parse a trustfile and add to files list.
  733. *
  734. * Parameters :
  735. * 1 : csp = Current client state (buffers, headers, etc...)
  736. *
  737. * Returns : 0 => Ok, everything else is an error.
  738. *
  739. *********************************************************************/
  740. int load_trustfile(struct client_state *csp)
  741. {
  742. FILE *fp;
  743. struct block_spec *b, *bl;
  744. struct pattern_spec **tl;
  745. char *buf = NULL;
  746. int reject, trusted;
  747. struct file_list *fs;
  748. unsigned long linenum = 0;
  749. int trusted_referrers = 0;
  750. if (!check_file_changed(current_trustfile, csp->config->trustfile, &fs))
  751. {
  752. /* No need to load */
  753. csp->tlist = current_trustfile;
  754. return(0);
  755. }
  756. if (!fs)
  757. {
  758. goto load_trustfile_error;
  759. }
  760. fs->f = bl = zalloc_or_die(sizeof(*bl));
  761. if ((fp = fopen(csp->config->trustfile, "r")) == NULL)
  762. {
  763. goto load_trustfile_error;
  764. }
  765. log_error(LOG_LEVEL_INFO, "Loading trust file: %s", csp->config->trustfile);
  766. tl = csp->config->trust_list;
  767. while (read_config_line(fp, &linenum, &buf) != NULL)
  768. {
  769. trusted = 0;
  770. reject = 1;
  771. if (*buf == '+')
  772. {
  773. trusted = 1;
  774. *buf = '~';
  775. }
  776. if (*buf == '~')
  777. {
  778. char *p;
  779. char *q;
  780. reject = 0;
  781. p = buf;
  782. q = p+1;
  783. while ((*p++ = *q++) != '\0')
  784. {
  785. /* nop */
  786. }
  787. }
  788. /* skip blank lines */
  789. if (*buf == '\0')
  790. {
  791. freez(buf);
  792. continue;
  793. }
  794. /* allocate a new node */
  795. b = zalloc_or_die(sizeof(*b));
  796. /* add it to the list */
  797. b->next = bl->next;
  798. bl->next = b;
  799. b->reject = reject;
  800. /* Save the URL pattern */
  801. if (create_pattern_spec(b->url, buf))
  802. {
  803. fclose(fp);
  804. goto load_trustfile_error;
  805. }
  806. /*
  807. * save a pointer to URL's spec in the list of trusted URL's, too
  808. */
  809. if (trusted)
  810. {
  811. if (++trusted_referrers < MAX_TRUSTED_REFERRERS)
  812. {
  813. *tl++ = b->url;
  814. }
  815. }
  816. freez(buf);
  817. }
  818. if (trusted_referrers >= MAX_TRUSTED_REFERRERS)
  819. {
  820. /*
  821. * FIXME: ... after Privoxy 3.0.4 is out.
  822. */
  823. log_error(LOG_LEVEL_ERROR, "Too many trusted referrers. Current limit is %d, you are using %d.\n"
  824. " Additional trusted referrers are treated like ordinary trusted URLs.\n"
  825. " (You can increase this limit by changing MAX_TRUSTED_REFERRERS in project.h and recompiling).",
  826. MAX_TRUSTED_REFERRERS, trusted_referrers);
  827. }
  828. *tl = NULL;
  829. fclose(fp);
  830. /* the old one is now obsolete */
  831. if (current_trustfile)
  832. {
  833. current_trustfile->unloader = unload_trustfile;
  834. }
  835. fs->next = files->next;
  836. files->next = fs;
  837. current_trustfile = fs;
  838. csp->tlist = fs;
  839. return(0);
  840. load_trustfile_error:
  841. log_error(LOG_LEVEL_FATAL, "can't load trustfile '%s': %E",
  842. csp->config->trustfile);
  843. freez(buf);
  844. return(-1);
  845. }
  846. #endif /* def FEATURE_TRUST */
  847. /*********************************************************************
  848. *
  849. * Function : unload_re_filterfile
  850. *
  851. * Description : Unload the re_filter list by freeing all chained
  852. * re_filterfile specs and their data.
  853. *
  854. * Parameters :
  855. * 1 : f = the data structure associated with the filterfile.
  856. *
  857. * Returns : N/A
  858. *
  859. *********************************************************************/
  860. static void unload_re_filterfile(void *f)
  861. {
  862. struct re_filterfile_spec *a, *b = (struct re_filterfile_spec *)f;
  863. while (b != NULL)
  864. {
  865. a = b->next;
  866. destroy_list(b->patterns);
  867. pcrs_free_joblist(b->joblist);
  868. freez(b->name);
  869. freez(b->description);
  870. freez(b);
  871. b = a;
  872. }
  873. return;
  874. }
  875. /*********************************************************************
  876. *
  877. * Function : unload_forward_spec
  878. *
  879. * Description : Unload the forward spec settings by freeing all
  880. * memory referenced by members and the memory for
  881. * the spec itself.
  882. *
  883. * Parameters :
  884. * 1 : fwd = the forward spec.
  885. *
  886. * Returns : N/A
  887. *
  888. *********************************************************************/
  889. void unload_forward_spec(struct forward_spec *fwd)
  890. {
  891. free_pattern_spec(fwd->url);
  892. freez(fwd->gateway_host);
  893. freez(fwd->forward_host);
  894. freez(fwd->auth_username);
  895. freez(fwd->auth_password);
  896. free(fwd);
  897. return;
  898. }
  899. #ifdef FEATURE_GRACEFUL_TERMINATION
  900. /*********************************************************************
  901. *
  902. * Function : unload_current_re_filterfile
  903. *
  904. * Description : Unloads current re_filter file - reset to state at
  905. * beginning of program.
  906. *
  907. * Parameters : None
  908. *
  909. * Returns : N/A
  910. *
  911. *********************************************************************/
  912. void unload_current_re_filterfile(void)
  913. {
  914. int i;
  915. for (i = 0; i < MAX_AF_FILES; i++)
  916. {
  917. if (current_re_filterfile[i])
  918. {
  919. current_re_filterfile[i]->unloader = unload_re_filterfile;
  920. current_re_filterfile[i] = NULL;
  921. }
  922. }
  923. }
  924. #endif
  925. /*********************************************************************
  926. *
  927. * Function : load_re_filterfiles
  928. *
  929. * Description : Loads all the filterfiles.
  930. * Generate a chained list of re_filterfile_spec's from
  931. * the "FILTER: " blocks, compiling all their substitutions
  932. * into chained lists of pcrs_job structs.
  933. *
  934. * Parameters :
  935. * 1 : csp = Current client state (buffers, headers, etc...)
  936. *
  937. * Returns : 0 => Ok, everything else is an error.
  938. *
  939. *********************************************************************/
  940. int load_re_filterfiles(struct client_state *csp)
  941. {
  942. int i;
  943. int result;
  944. for (i = 0; i < MAX_AF_FILES; i++)
  945. {
  946. if (csp->config->re_filterfile[i])
  947. {
  948. result = load_one_re_filterfile(csp, i);
  949. if (result)
  950. {
  951. return result;
  952. }
  953. }
  954. else if (current_re_filterfile[i])
  955. {
  956. current_re_filterfile[i]->unloader = unload_re_filterfile;
  957. current_re_filterfile[i] = NULL;
  958. }
  959. }
  960. return 0;
  961. }
  962. /*********************************************************************
  963. *
  964. * Function : load_one_re_filterfile
  965. *
  966. * Description : Load a re_filterfile.
  967. * Generate a chained list of re_filterfile_spec's from
  968. * the "FILTER: " blocks, compiling all their substitutions
  969. * into chained lists of pcrs_job structs.
  970. *
  971. * Parameters :
  972. * 1 : csp = Current client state (buffers, headers, etc...)
  973. *
  974. * Returns : 0 => Ok, everything else is an error.
  975. *
  976. *********************************************************************/
  977. int load_one_re_filterfile(struct client_state *csp, int fileid)
  978. {
  979. FILE *fp;
  980. struct re_filterfile_spec *new_bl, *bl = NULL;
  981. struct file_list *fs;
  982. char *buf = NULL;
  983. unsigned long linenum = 0;
  984. pcrs_job *dummy, *lastjob = NULL;
  985. /*
  986. * No need to reload if unchanged
  987. */
  988. if (!check_file_changed(current_re_filterfile[fileid], csp->config->re_filterfile[fileid], &fs))
  989. {
  990. csp->rlist[fileid] = current_re_filterfile[fileid];
  991. return(0);
  992. }
  993. if (!fs)
  994. {
  995. goto load_re_filterfile_error;
  996. }
  997. /*
  998. * Open the file or fail
  999. */
  1000. if ((fp = fopen(csp->config->re_filterfile[fileid], "r")) == NULL)
  1001. {
  1002. goto load_re_filterfile_error;
  1003. }
  1004. log_error(LOG_LEVEL_INFO, "Loading filter file: %s", csp->config->re_filterfile[fileid]);
  1005. /*
  1006. * Read line by line
  1007. */
  1008. while (read_config_line(fp, &linenum, &buf) != NULL)
  1009. {
  1010. enum filter_type new_filter = FT_INVALID_FILTER;
  1011. if (strncmp(buf, "FILTER:", 7) == 0)
  1012. {
  1013. new_filter = FT_CONTENT_FILTER;
  1014. }
  1015. else if (strncmp(buf, "SERVER-HEADER-FILTER:", 21) == 0)
  1016. {
  1017. new_filter = FT_SERVER_HEADER_FILTER;
  1018. }
  1019. else if (strncmp(buf, "CLIENT-HEADER-FILTER:", 21) == 0)
  1020. {
  1021. new_filter = FT_CLIENT_HEADER_FILTER;
  1022. }
  1023. else if (strncmp(buf, "CLIENT-HEADER-TAGGER:", 21) == 0)
  1024. {
  1025. new_filter = FT_CLIENT_HEADER_TAGGER;
  1026. }
  1027. else if (strncmp(buf, "SERVER-HEADER-TAGGER:", 21) == 0)
  1028. {
  1029. new_filter = FT_SERVER_HEADER_TAGGER;
  1030. }
  1031. #ifdef FEATURE_EXTERNAL_FILTERS
  1032. else if (strncmp(buf, "EXTERNAL-FILTER:", 16) == 0)
  1033. {
  1034. new_filter = FT_EXTERNAL_CONTENT_FILTER;
  1035. }
  1036. #endif
  1037. /*
  1038. * If this is the head of a new filter block, make it a
  1039. * re_filterfile spec of its own and chain it to the list:
  1040. */
  1041. if (new_filter != FT_INVALID_FILTER)
  1042. {
  1043. new_bl = zalloc_or_die(sizeof(*bl));
  1044. if (new_filter == FT_CONTENT_FILTER)
  1045. {
  1046. new_bl->name = chomp(buf + 7);
  1047. }
  1048. #ifdef FEATURE_EXTERNAL_FILTERS
  1049. else if (new_filter == FT_EXTERNAL_CONTENT_FILTER)
  1050. {
  1051. new_bl->name = chomp(buf + 16);
  1052. }
  1053. #endif
  1054. else
  1055. {
  1056. new_bl->name = chomp(buf + 21);
  1057. }
  1058. new_bl->type = new_filter;
  1059. /*
  1060. * If a filter description is available,
  1061. * encode it to HTML and save it.
  1062. */
  1063. if (NULL != (new_bl->description = strpbrk(new_bl->name, " \t")))
  1064. {
  1065. *new_bl->description++ = '\0';
  1066. new_bl->description = html_encode(chomp(new_bl->description));
  1067. if (NULL == new_bl->description)
  1068. {
  1069. new_bl->description = strdup_or_die("Out of memory while "
  1070. "encoding filter description to HTML");
  1071. }
  1072. }
  1073. else
  1074. {
  1075. new_bl->description = strdup_or_die("No description available");
  1076. }
  1077. new_bl->name = strdup_or_die(chomp(new_bl->name));
  1078. /*
  1079. * If this is the first filter block, chain it
  1080. * to the file_list rather than its (nonexistent)
  1081. * predecessor
  1082. */
  1083. if (fs->f == NULL)
  1084. {
  1085. fs->f = new_bl;
  1086. }
  1087. else
  1088. {
  1089. assert(NULL != bl);
  1090. bl->next = new_bl;
  1091. }
  1092. bl = new_bl;
  1093. log_error(LOG_LEVEL_RE_FILTER, "Reading in filter \"%s\" (\"%s\")", bl->name, bl->description);
  1094. #ifdef FEATURE_EXTENDED_STATISTICS
  1095. register_filter_for_statistics(bl->name);
  1096. #endif
  1097. freez(buf);
  1098. continue;
  1099. }
  1100. #ifdef FEATURE_EXTERNAL_FILTERS
  1101. if ((bl != NULL) && (bl->type == FT_EXTERNAL_CONTENT_FILTER))
  1102. {
  1103. jb_err jb_error;
  1104. /* Save the code as "pattern", but do not compile anything. */
  1105. if (bl->patterns->first != NULL)
  1106. {
  1107. log_error(LOG_LEVEL_FATAL, "External filter '%s' contains several jobs. "
  1108. "Did you forget to escape a line break?",
  1109. bl->name);
  1110. }
  1111. jb_error = enlist(bl->patterns, buf);
  1112. if (JB_ERR_MEMORY == jb_error)
  1113. {
  1114. log_error(LOG_LEVEL_FATAL,
  1115. "Out of memory while enlisting external filter code \'%s\' for filter %s.",
  1116. buf, bl->name);
  1117. }
  1118. freez(buf);
  1119. continue;
  1120. }
  1121. #endif
  1122. if (bl != NULL)
  1123. {
  1124. int pcrs_error;
  1125. jb_err jb_error;
  1126. /*
  1127. * Save the expression, make it a pcrs_job
  1128. * and chain it into the current filter's joblist
  1129. */
  1130. jb_error = enlist(bl->patterns, buf);
  1131. if (JB_ERR_MEMORY == jb_error)
  1132. {
  1133. log_error(LOG_LEVEL_FATAL,
  1134. "Out of memory while enlisting re_filter job \'%s\' for filter %s.", buf, bl->name);
  1135. }
  1136. assert(JB_ERR_OK == jb_error);
  1137. if (pcrs_job_is_dynamic(buf))
  1138. {
  1139. /*
  1140. * Dynamic pattern that might contain variables
  1141. * and has to be recompiled for every request
  1142. */
  1143. if (bl->joblist != NULL)
  1144. {
  1145. pcrs_free_joblist(bl->joblist);
  1146. bl->joblist = NULL;
  1147. }
  1148. bl->dynamic = 1;
  1149. log_error(LOG_LEVEL_RE_FILTER,
  1150. "Adding dynamic re_filter job \'%s\' to filter %s succeeded.", buf, bl->name);
  1151. freez(buf);
  1152. continue;
  1153. }
  1154. else if (bl->dynamic)
  1155. {
  1156. /*
  1157. * A previous job was dynamic and as we
  1158. * recompile the whole filter anyway, it
  1159. * makes no sense to compile this job now.
  1160. */
  1161. log_error(LOG_LEVEL_RE_FILTER,
  1162. "Adding static re_filter job \'%s\' to dynamic filter %s succeeded.", buf, bl->name);
  1163. freez(buf);
  1164. continue;
  1165. }
  1166. if ((dummy = pcrs_compile_command(buf, &pcrs_error)) == NULL)
  1167. {
  1168. log_error(LOG_LEVEL_ERROR,
  1169. "Adding re_filter job \'%s\' to filter %s failed: %s",
  1170. buf, bl->name, pcrs_strerror(pcrs_error));
  1171. freez(buf);
  1172. continue;
  1173. }
  1174. else
  1175. {
  1176. if (bl->joblist == NULL)
  1177. {
  1178. bl->joblist = dummy;
  1179. }
  1180. else if (NULL != lastjob)
  1181. {
  1182. lastjob->next = dummy;
  1183. }
  1184. lastjob = dummy;
  1185. log_error(LOG_LEVEL_RE_FILTER, "Adding re_filter job \'%s\' to filter %s succeeded.", buf, bl->name);
  1186. }
  1187. }
  1188. else
  1189. {
  1190. log_error(LOG_LEVEL_ERROR,
  1191. "Ignoring job %s outside filter block in %s, line %lu",
  1192. buf, csp->config->re_filterfile[fileid], linenum);
  1193. }
  1194. freez(buf);
  1195. }
  1196. fclose(fp);
  1197. /*
  1198. * Schedule the now-obsolete old data for unloading
  1199. */
  1200. if (NULL != current_re_filterfile[fileid])
  1201. {
  1202. current_re_filterfile[fileid]->unloader = unload_re_filterfile;
  1203. }
  1204. /*
  1205. * Chain this file into the global list of loaded files
  1206. */
  1207. fs->next = files->next;
  1208. files->next = fs;
  1209. current_re_filterfile[fileid] = fs;
  1210. csp->rlist[fileid] = fs;
  1211. return(0);
  1212. load_re_filterfile_error:
  1213. log_error(LOG_LEVEL_FATAL, "can't load re_filterfile '%s': %E",
  1214. csp->config->re_filterfile[fileid]);
  1215. return(-1);
  1216. }
  1217. /*********************************************************************
  1218. *
  1219. * Function : add_loader
  1220. *
  1221. * Description : Called from `load_config'. Called once for each input
  1222. * file found in config.
  1223. *
  1224. * Parameters :
  1225. * 1 : loader = pointer to a function that can parse and load
  1226. * the appropriate config file.
  1227. * 2 : config = The configuration_spec to add the loader to.
  1228. *
  1229. * Returns : N/A
  1230. *
  1231. *********************************************************************/
  1232. void add_loader(int (*loader)(struct client_state *),
  1233. struct configuration_spec * config)
  1234. {
  1235. int i;
  1236. for (i = 0; i < NLOADERS; i++)
  1237. {
  1238. if (config->loaders[i] == NULL)
  1239. {
  1240. config->loaders[i] = loader;
  1241. break;
  1242. }
  1243. }
  1244. }
  1245. /*********************************************************************
  1246. *
  1247. * Function : run_loader
  1248. *
  1249. * Description : Called from `load_config' and `listen_loop'. This
  1250. * function keeps the "csp" current with any file mods
  1251. * since the last loop. If a file is unchanged, the
  1252. * loader functions do NOT reload the file.
  1253. *
  1254. * Parameters :
  1255. * 1 : csp = Current client state (buffers, headers, etc...)
  1256. * Must be non-null. Reads: "csp->config"
  1257. * Writes: various data members.
  1258. *
  1259. * Returns : 0 => Ok, everything else is an error.
  1260. *
  1261. *********************************************************************/
  1262. int run_loader(struct client_state *csp)
  1263. {
  1264. int ret = 0;
  1265. int i;
  1266. for (i = 0; i < NLOADERS; i++)
  1267. {
  1268. if (csp->config->loaders[i] == NULL)
  1269. {
  1270. break;
  1271. }
  1272. ret |= (csp->config->loaders[i])(csp);
  1273. }
  1274. return(ret);
  1275. }
  1276. /*********************************************************************
  1277. *
  1278. * Function : file_has_been_modified
  1279. *
  1280. * Description : Helper function to check if a file has been changed
  1281. *
  1282. * Parameters :
  1283. * 1 : filename = The name of the file to check
  1284. * 2 : last_known_modification = The time of the last known
  1285. * modification
  1286. *
  1287. * Returns : TRUE if the file has been changed,
  1288. * FALSE otherwise.
  1289. *
  1290. *********************************************************************/
  1291. static int file_has_been_modified(const char *filename, time_t last_know_modification)
  1292. {
  1293. struct stat statbuf[1];
  1294. if (stat(filename, statbuf) < 0)
  1295. {
  1296. /* Error, probably file not found which counts as change. */
  1297. return 1;
  1298. }
  1299. return (last_know_modification != statbuf->st_mtime);
  1300. }
  1301. /*********************************************************************
  1302. *
  1303. * Function : any_loaded_file_changed
  1304. *
  1305. * Description : Helper function to check if any loaded file has been
  1306. * changed since the time it has been loaded.
  1307. *
  1308. * XXX: Should we cache the return value for x seconds?
  1309. *
  1310. * Parameters :
  1311. * 1 : files_to_check = List of files to check
  1312. *
  1313. * Returns : TRUE if any file has been changed,
  1314. * FALSE otherwise.
  1315. *
  1316. *********************************************************************/
  1317. int any_loaded_file_changed(const struct client_state *csp)
  1318. {
  1319. const struct file_list *file_to_check = csp->config->config_file_list;
  1320. int i;
  1321. if (file_has_been_modified(file_to_check->filename, file_to_check->lastmodified))
  1322. {
  1323. return TRUE;
  1324. }
  1325. for (i = 0; i < MAX_AF_FILES; i++)
  1326. {
  1327. if (csp->actions_list[i])
  1328. {
  1329. file_to_check = csp->actions_list[i];
  1330. if (file_has_been_modified(file_to_check->filename, file_to_check->lastmodified))
  1331. {
  1332. return TRUE;
  1333. }
  1334. }
  1335. }
  1336. for (i = 0; i < MAX_AF_FILES; i++)
  1337. {
  1338. if (csp->rlist[i])
  1339. {
  1340. file_to_check = csp->rlist[i];
  1341. if (file_has_been_modified(file_to_check->filename, file_to_check->lastmodified))
  1342. {
  1343. return TRUE;
  1344. }
  1345. }
  1346. }
  1347. #ifdef FEATURE_TRUST
  1348. if (csp->tlist)
  1349. {
  1350. if (file_has_been_modified(csp->tlist->filename, csp->tlist->lastmodified))
  1351. {
  1352. return TRUE;
  1353. }
  1354. }
  1355. #endif /* def FEATURE_TRUST */
  1356. return FALSE;
  1357. }
  1358. /*
  1359. Local Variables:
  1360. tab-width: 3
  1361. end:
  1362. */