Experimental IRC client, daemon and bot
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2096 lines
54KB

  1. /*
  2. * common.c: common functionality
  3. *
  4. * Copyright (c) 2014 - 2015, Přemysl Janouch <p.janouch@gmail.com>
  5. *
  6. * Permission to use, copy, modify, and/or distribute this software for any
  7. * purpose with or without fee is hereby granted, provided that the above
  8. * copyright notice and this permission notice appear in all copies.
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  13. * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  15. * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  16. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17. *
  18. */
  19. #define LIBERTY_WANT_SSL
  20. #define LIBERTY_WANT_POLLER
  21. #define LIBERTY_WANT_PROTO_IRC
  22. #ifdef WANT_SYSLOG_LOGGING
  23. #define print_fatal_data ((void *) LOG_ERR)
  24. #define print_error_data ((void *) LOG_ERR)
  25. #define print_warning_data ((void *) LOG_WARNING)
  26. #define print_status_data ((void *) LOG_INFO)
  27. #define print_debug_data ((void *) LOG_DEBUG)
  28. #endif // WANT_SYSLOG_LOGGING
  29. #include "liberty/liberty.c"
  30. #include <setjmp.h>
  31. #include <inttypes.h>
  32. #include <arpa/inet.h>
  33. /// Shorthand to set an error and return failure from the function
  34. #define FAIL(...) \
  35. BLOCK_START \
  36. error_set (e, __VA_ARGS__); \
  37. return 0; \
  38. BLOCK_END
  39. #define CONTAINER_OF(pointer, type, member) \
  40. (type *) ((char *) pointer - offsetof (type, member))
  41. // --- To be moved to liberty --------------------------------------------------
  42. static void
  43. split_str (const char *s, const char *delimiters, struct str_vector *out)
  44. {
  45. const char *begin = s, *end;
  46. while ((end = strpbrk (begin, delimiters)))
  47. {
  48. str_vector_add_owned (out, xstrndup (begin, end - begin));
  49. begin = ++end;
  50. }
  51. str_vector_add (out, begin);
  52. }
  53. static ssize_t
  54. str_vector_find (const struct str_vector *v, const char *s)
  55. {
  56. for (size_t i = 0; i < v->len; i++)
  57. if (!strcmp (v->vector[i], s))
  58. return i;
  59. return -1;
  60. }
  61. // --- Logging -----------------------------------------------------------------
  62. static void
  63. log_message_syslog (void *user_data, const char *quote, const char *fmt,
  64. va_list ap)
  65. {
  66. int prio = (int) (intptr_t) user_data;
  67. va_list va;
  68. va_copy (va, ap);
  69. int size = vsnprintf (NULL, 0, fmt, va);
  70. va_end (va);
  71. if (size < 0)
  72. return;
  73. char buf[size + 1];
  74. if (vsnprintf (buf, sizeof buf, fmt, ap) >= 0)
  75. syslog (prio, "%s%s", quote, buf);
  76. }
  77. // --- SOCKS 5/4a --------------------------------------------------------------
  78. // Asynchronous SOCKS connector. Adds more stuff on top of the regular one.
  79. // Note that the `username' is used differently in SOCKS 4a and 5. In the
  80. // former version, it is the username that you can get ident'ed against.
  81. // In the latter version, it forms a pair with the password field and doesn't
  82. // need to be an actual user on your machine.
  83. struct socks_addr
  84. {
  85. enum socks_addr_type
  86. {
  87. SOCKS_IPV4 = 1, ///< IPv4 address
  88. SOCKS_DOMAIN = 3, ///< Domain name to be resolved
  89. SOCKS_IPV6 = 4 ///< IPv6 address
  90. }
  91. type; ///< The type of this address
  92. union
  93. {
  94. uint8_t ipv4[4]; ///< IPv4 address, network octet order
  95. char *domain; ///< Domain name
  96. uint8_t ipv6[16]; ///< IPv6 address, network octet order
  97. }
  98. data; ///< The address itself
  99. };
  100. static void
  101. socks_addr_free (struct socks_addr *self)
  102. {
  103. if (self->type == SOCKS_DOMAIN)
  104. free (self->data.domain);
  105. }
  106. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  107. struct socks_target
  108. {
  109. LIST_HEADER (struct socks_target)
  110. char *address_str; ///< Target address as a string
  111. struct socks_addr address; ///< Target address
  112. uint16_t port; ///< Target service port
  113. };
  114. enum socks_protocol
  115. {
  116. SOCKS_5, ///< SOCKS5
  117. SOCKS_4A, ///< SOCKS4A
  118. SOCKS_MAX ///< End of protocol
  119. };
  120. static inline const char *
  121. socks_protocol_to_string (enum socks_protocol self)
  122. {
  123. switch (self)
  124. {
  125. case SOCKS_5: return "SOCKS5";
  126. case SOCKS_4A: return "SOCKS4A";
  127. default: return NULL;
  128. }
  129. }
  130. struct socks_connector
  131. {
  132. struct connector *connector; ///< Proxy server iterator (effectively)
  133. enum socks_protocol protocol_iter; ///< Protocol iterator
  134. struct socks_target *targets_iter; ///< Targets iterator
  135. // Negotiation:
  136. struct poller_timer timeout; ///< Timeout timer
  137. int socket_fd; ///< Current socket file descriptor
  138. struct poller_fd socket_event; ///< Socket can be read from/written to
  139. struct str read_buffer; ///< Read buffer
  140. struct str write_buffer; ///< Write buffer
  141. bool done; ///< Tunnel succesfully established
  142. uint8_t bound_address_len; ///< Length of domain name
  143. size_t data_needed; ///< How much data "on_data" needs
  144. /// Process incoming data if there's enough of it available
  145. bool (*on_data) (struct socks_connector *, struct msg_unpacker *);
  146. // Configuration:
  147. char *hostname; ///< SOCKS server hostname
  148. char *service; ///< SOCKS server service name or port
  149. char *username; ///< Username for authentication
  150. char *password; ///< Password for authentication
  151. struct socks_target *targets; ///< Targets
  152. struct socks_target *targets_tail; ///< Tail of targets
  153. void *user_data; ///< User data for callbacks
  154. // Additional results:
  155. struct socks_addr bound_address; ///< Bound address at the server
  156. uint16_t bound_port; ///< Bound port at the server
  157. // You may destroy the connector object in these two main callbacks:
  158. /// Connection has been successfully established
  159. void (*on_connected) (void *user_data, int socket);
  160. /// Failed to establish a connection to either target
  161. void (*on_failure) (void *user_data);
  162. // Optional:
  163. /// Connecting to a new address
  164. void (*on_connecting) (void *user_data,
  165. const char *address, const char *via, const char *version);
  166. /// Connecting to the last address has failed
  167. void (*on_error) (void *user_data, const char *error);
  168. };
  169. // I've tried to make the actual protocol handlers as simple as possible
  170. #define SOCKS_FAIL(...) \
  171. BLOCK_START \
  172. char *error = xstrdup_printf (__VA_ARGS__); \
  173. if (self->on_error) \
  174. self->on_error (self->user_data, error); \
  175. free (error); \
  176. return false; \
  177. BLOCK_END
  178. #define SOCKS_DATA_CB(name) static bool name \
  179. (struct socks_connector *self, struct msg_unpacker *unpacker)
  180. #define SOCKS_GO(name, data_needed_) \
  181. self->on_data = name; \
  182. self->data_needed = data_needed_; \
  183. return true
  184. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  185. SOCKS_DATA_CB (socks_4a_finish)
  186. {
  187. uint8_t null, status;
  188. hard_assert (msg_unpacker_u8 (unpacker, &null));
  189. hard_assert (msg_unpacker_u8 (unpacker, &status));
  190. if (null != 0)
  191. SOCKS_FAIL ("protocol error");
  192. switch (status)
  193. {
  194. case 90:
  195. self->done = true;
  196. return false;
  197. case 91:
  198. SOCKS_FAIL ("request rejected or failed");
  199. case 92:
  200. SOCKS_FAIL ("%s: %s", "request rejected",
  201. "SOCKS server cannot connect to identd on the client");
  202. case 93:
  203. SOCKS_FAIL ("%s: %s", "request rejected",
  204. "identd reports different user-id");
  205. default:
  206. SOCKS_FAIL ("protocol error");
  207. }
  208. }
  209. static bool
  210. socks_4a_start (struct socks_connector *self)
  211. {
  212. struct socks_target *target = self->targets_iter;
  213. const void *dest_ipv4 = "\x00\x00\x00\x01";
  214. const char *dest_domain = NULL;
  215. char buf[INET6_ADDRSTRLEN];
  216. switch (target->address.type)
  217. {
  218. case SOCKS_IPV4:
  219. dest_ipv4 = target->address.data.ipv4;
  220. break;
  221. case SOCKS_IPV6:
  222. // About the best thing we can do, not sure if it works anywhere at all
  223. if (!inet_ntop (AF_INET6, &target->address.data.ipv6, buf, sizeof buf))
  224. SOCKS_FAIL ("%s: %s", "inet_ntop", strerror (errno));
  225. dest_domain = buf;
  226. break;
  227. case SOCKS_DOMAIN:
  228. dest_domain = target->address.data.domain;
  229. }
  230. struct str *wb = &self->write_buffer;
  231. str_init (wb);
  232. str_pack_u8 (wb, 4); // version
  233. str_pack_u8 (wb, 1); // connect
  234. str_pack_u16 (wb, target->port); // port
  235. str_append_data (wb, dest_ipv4, 4); // destination address
  236. if (self->username)
  237. str_append (wb, self->username);
  238. str_append_c (wb, '\0');
  239. if (dest_domain)
  240. {
  241. str_append (wb, dest_domain);
  242. str_append_c (wb, '\0');
  243. }
  244. SOCKS_GO (socks_4a_finish, 8);
  245. }
  246. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  247. SOCKS_DATA_CB (socks_5_request_port)
  248. {
  249. hard_assert (msg_unpacker_u16 (unpacker, &self->bound_port));
  250. self->done = true;
  251. return false;
  252. }
  253. SOCKS_DATA_CB (socks_5_request_ipv4)
  254. {
  255. memcpy (self->bound_address.data.ipv4, unpacker->data, unpacker->len);
  256. SOCKS_GO (socks_5_request_port, 2);
  257. }
  258. SOCKS_DATA_CB (socks_5_request_ipv6)
  259. {
  260. memcpy (self->bound_address.data.ipv6, unpacker->data, unpacker->len);
  261. SOCKS_GO (socks_5_request_port, 2);
  262. }
  263. SOCKS_DATA_CB (socks_5_request_domain_data)
  264. {
  265. self->bound_address.data.domain = xstrndup (unpacker->data, unpacker->len);
  266. SOCKS_GO (socks_5_request_port, 2);
  267. }
  268. SOCKS_DATA_CB (socks_5_request_domain)
  269. {
  270. hard_assert (msg_unpacker_u8 (unpacker, &self->bound_address_len));
  271. SOCKS_GO (socks_5_request_domain_data, self->bound_address_len);
  272. }
  273. SOCKS_DATA_CB (socks_5_request_finish)
  274. {
  275. uint8_t version, status, reserved, type;
  276. hard_assert (msg_unpacker_u8 (unpacker, &version));
  277. hard_assert (msg_unpacker_u8 (unpacker, &status));
  278. hard_assert (msg_unpacker_u8 (unpacker, &reserved));
  279. hard_assert (msg_unpacker_u8 (unpacker, &type));
  280. if (version != 0x05)
  281. SOCKS_FAIL ("protocol error");
  282. switch (status)
  283. {
  284. case 0x00:
  285. break;
  286. case 0x01: SOCKS_FAIL ("general SOCKS server failure");
  287. case 0x02: SOCKS_FAIL ("connection not allowed by ruleset");
  288. case 0x03: SOCKS_FAIL ("network unreachable");
  289. case 0x04: SOCKS_FAIL ("host unreachable");
  290. case 0x05: SOCKS_FAIL ("connection refused");
  291. case 0x06: SOCKS_FAIL ("TTL expired");
  292. case 0x07: SOCKS_FAIL ("command not supported");
  293. case 0x08: SOCKS_FAIL ("address type not supported");
  294. default: SOCKS_FAIL ("protocol error");
  295. }
  296. switch ((self->bound_address.type = type))
  297. {
  298. case SOCKS_IPV4:
  299. SOCKS_GO (socks_5_request_ipv4, sizeof self->bound_address.data.ipv4);
  300. case SOCKS_IPV6:
  301. SOCKS_GO (socks_5_request_ipv6, sizeof self->bound_address.data.ipv6);
  302. case SOCKS_DOMAIN:
  303. SOCKS_GO (socks_5_request_domain, 1);
  304. default:
  305. SOCKS_FAIL ("protocol error");
  306. }
  307. }
  308. static bool
  309. socks_5_request_start (struct socks_connector *self)
  310. {
  311. struct socks_target *target = self->targets_iter;
  312. struct str *wb = &self->write_buffer;
  313. str_pack_u8 (wb, 0x05); // version
  314. str_pack_u8 (wb, 0x01); // connect
  315. str_pack_u8 (wb, 0x00); // reserved
  316. str_pack_u8 (wb, target->address.type);
  317. switch (target->address.type)
  318. {
  319. case SOCKS_IPV4:
  320. str_append_data (wb,
  321. target->address.data.ipv4, sizeof target->address.data.ipv4);
  322. break;
  323. case SOCKS_DOMAIN:
  324. {
  325. size_t dlen = strlen (target->address.data.domain);
  326. if (dlen > 255)
  327. dlen = 255;
  328. str_pack_u8 (wb, dlen);
  329. str_append_data (wb, target->address.data.domain, dlen);
  330. break;
  331. }
  332. case SOCKS_IPV6:
  333. str_append_data (wb,
  334. target->address.data.ipv6, sizeof target->address.data.ipv6);
  335. break;
  336. }
  337. str_pack_u16 (wb, target->port);
  338. SOCKS_GO (socks_5_request_finish, 4);
  339. }
  340. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  341. SOCKS_DATA_CB (socks_5_userpass_finish)
  342. {
  343. uint8_t version, status;
  344. hard_assert (msg_unpacker_u8 (unpacker, &version));
  345. hard_assert (msg_unpacker_u8 (unpacker, &status));
  346. if (version != 0x01)
  347. SOCKS_FAIL ("protocol error");
  348. if (status != 0x00)
  349. SOCKS_FAIL ("authentication failure");
  350. return socks_5_request_start (self);
  351. }
  352. static bool
  353. socks_5_userpass_start (struct socks_connector *self)
  354. {
  355. size_t ulen = strlen (self->username);
  356. if (ulen > 255)
  357. ulen = 255;
  358. size_t plen = strlen (self->password);
  359. if (plen > 255)
  360. plen = 255;
  361. struct str *wb = &self->write_buffer;
  362. str_pack_u8 (wb, 0x01); // version
  363. str_pack_u8 (wb, ulen); // username length
  364. str_append_data (wb, self->username, ulen);
  365. str_pack_u8 (wb, plen); // password length
  366. str_append_data (wb, self->password, plen);
  367. SOCKS_GO (socks_5_userpass_finish, 2);
  368. }
  369. SOCKS_DATA_CB (socks_5_auth_finish)
  370. {
  371. uint8_t version, method;
  372. hard_assert (msg_unpacker_u8 (unpacker, &version));
  373. hard_assert (msg_unpacker_u8 (unpacker, &method));
  374. if (version != 0x05)
  375. SOCKS_FAIL ("protocol error");
  376. bool can_auth = self->username && self->password;
  377. switch (method)
  378. {
  379. case 0x02:
  380. if (!can_auth)
  381. SOCKS_FAIL ("protocol error");
  382. return socks_5_userpass_start (self);
  383. case 0x00:
  384. return socks_5_request_start (self);
  385. case 0xFF:
  386. SOCKS_FAIL ("no acceptable authentication methods");
  387. default:
  388. SOCKS_FAIL ("protocol error");
  389. }
  390. }
  391. static bool
  392. socks_5_auth_start (struct socks_connector *self)
  393. {
  394. bool can_auth = self->username && self->password;
  395. struct str *wb = &self->write_buffer;
  396. str_pack_u8 (wb, 0x05); // version
  397. str_pack_u8 (wb, 1 + can_auth); // number of authentication methods
  398. str_pack_u8 (wb, 0x00); // no authentication required
  399. if (can_auth)
  400. str_pack_u8 (wb, 0x02); // username/password
  401. SOCKS_GO (socks_5_auth_finish, 2);
  402. }
  403. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  404. static void socks_connector_start (struct socks_connector *self);
  405. static void
  406. socks_connector_destroy_connector (struct socks_connector *self)
  407. {
  408. if (self->connector)
  409. {
  410. connector_free (self->connector);
  411. free (self->connector);
  412. self->connector = NULL;
  413. }
  414. }
  415. static void
  416. socks_connector_cancel_events (struct socks_connector *self)
  417. {
  418. // Before calling the final callbacks, we should cancel events that
  419. // could potentially fire; caller should destroy us immediately, though
  420. poller_fd_reset (&self->socket_event);
  421. poller_timer_reset (&self->timeout);
  422. }
  423. static void
  424. socks_connector_fail (struct socks_connector *self)
  425. {
  426. socks_connector_cancel_events (self);
  427. self->on_failure (self->user_data);
  428. }
  429. static bool
  430. socks_connector_step_iterators (struct socks_connector *self)
  431. {
  432. // At the lowest level we iterate over all addresses for the SOCKS server
  433. // and just try to connect; this is done automatically by the connector
  434. // Then we iterate over available protocols
  435. if (++self->protocol_iter != SOCKS_MAX)
  436. return true;
  437. // At the highest level we iterate over possible targets
  438. self->protocol_iter = 0;
  439. if (self->targets_iter && (self->targets_iter = self->targets_iter->next))
  440. return true;
  441. return false;
  442. }
  443. static void
  444. socks_connector_step (struct socks_connector *self)
  445. {
  446. if (self->socket_fd != -1)
  447. {
  448. poller_fd_reset (&self->socket_event);
  449. xclose (self->socket_fd);
  450. self->socket_fd = -1;
  451. }
  452. socks_connector_destroy_connector (self);
  453. if (socks_connector_step_iterators (self))
  454. socks_connector_start (self);
  455. else
  456. socks_connector_fail (self);
  457. }
  458. static void
  459. socks_connector_on_timeout (struct socks_connector *self)
  460. {
  461. if (self->on_error)
  462. self->on_error (self->user_data, "timeout");
  463. socks_connector_destroy_connector (self);
  464. socks_connector_fail (self);
  465. }
  466. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  467. static void
  468. socks_connector_on_connected (void *user_data, int socket_fd)
  469. {
  470. set_blocking (socket_fd, false);
  471. struct socks_connector *self = user_data;
  472. self->socket_fd = socket_fd;
  473. self->socket_event.fd = socket_fd;
  474. poller_fd_set (&self->socket_event, POLLIN | POLLOUT);
  475. str_reset (&self->read_buffer);
  476. str_reset (&self->write_buffer);
  477. if (!(self->protocol_iter == SOCKS_5 && socks_5_auth_start (self))
  478. && !(self->protocol_iter == SOCKS_4A && socks_4a_start (self)))
  479. socks_connector_fail (self);
  480. }
  481. static void
  482. socks_connector_on_failure (void *user_data)
  483. {
  484. struct socks_connector *self = user_data;
  485. // TODO: skip SOCKS server on connection failure
  486. socks_connector_step (self);
  487. }
  488. static void
  489. socks_connector_on_connecting (void *user_data, const char *via)
  490. {
  491. struct socks_connector *self = user_data;
  492. if (!self->on_connecting)
  493. return;
  494. struct socks_target *target = self->targets_iter;
  495. char *port = xstrdup_printf ("%u", target->port);
  496. char *address = format_host_port_pair (target->address_str, port);
  497. free (port);
  498. self->on_connecting (self->user_data, address, via,
  499. socks_protocol_to_string (self->protocol_iter));
  500. free (address);
  501. }
  502. static void
  503. socks_connector_on_error (void *user_data, const char *error)
  504. {
  505. struct socks_connector *self = user_data;
  506. // TODO: skip protocol on protocol failure
  507. if (self->on_error)
  508. self->on_error (self->user_data, error);
  509. }
  510. static void
  511. socks_connector_start (struct socks_connector *self)
  512. {
  513. hard_assert (!self->connector);
  514. struct connector *connector =
  515. self->connector = xcalloc (1, sizeof *connector);
  516. connector_init (connector, self->socket_event.poller);
  517. connector->user_data = self;
  518. connector->on_connected = socks_connector_on_connected;
  519. connector->on_connecting = socks_connector_on_connecting;
  520. connector->on_error = socks_connector_on_error;
  521. connector->on_failure = socks_connector_on_failure;
  522. struct error *e = NULL;
  523. if (!connector_add_target (connector, self->hostname, self->service, &e))
  524. {
  525. if (self->on_error)
  526. self->on_error (self->user_data, e->message);
  527. error_free (e);
  528. socks_connector_destroy_connector (self);
  529. socks_connector_fail (self);
  530. return;
  531. }
  532. poller_timer_set (&self->timeout, 60 * 1000);
  533. connector_step (connector);
  534. self->done = false;
  535. self->bound_port = 0;
  536. socks_addr_free (&self->bound_address);
  537. memset (&self->bound_address, 0, sizeof self->bound_address);
  538. }
  539. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  540. static bool
  541. socks_try_fill_read_buffer (struct socks_connector *self, size_t n)
  542. {
  543. ssize_t remains = (ssize_t) n - (ssize_t) self->read_buffer.len;
  544. if (remains <= 0)
  545. return true;
  546. ssize_t received;
  547. str_ensure_space (&self->read_buffer, remains);
  548. do
  549. received = recv (self->socket_fd,
  550. self->read_buffer.str + self->read_buffer.len, remains, 0);
  551. while ((received == -1) && errno == EINTR);
  552. if (received == 0)
  553. SOCKS_FAIL ("%s: %s", "protocol error", "unexpected EOF");
  554. if (received == -1 && errno != EAGAIN)
  555. SOCKS_FAIL ("%s: %s", "recv", strerror (errno));
  556. if (received > 0)
  557. self->read_buffer.len += received;
  558. return true;
  559. }
  560. static bool
  561. socks_call_on_data (struct socks_connector *self)
  562. {
  563. size_t to_consume = self->data_needed;
  564. if (!socks_try_fill_read_buffer (self, to_consume))
  565. return false;
  566. if (self->read_buffer.len < to_consume)
  567. return true;
  568. struct msg_unpacker unpacker;
  569. msg_unpacker_init (&unpacker, self->read_buffer.str, self->read_buffer.len);
  570. bool result = self->on_data (self, &unpacker);
  571. str_remove_slice (&self->read_buffer, 0, to_consume);
  572. return result;
  573. }
  574. static bool
  575. socks_try_flush_write_buffer (struct socks_connector *self)
  576. {
  577. struct str *wb = &self->write_buffer;
  578. ssize_t n_written;
  579. while (wb->len)
  580. {
  581. n_written = send (self->socket_fd, wb->str, wb->len, 0);
  582. if (n_written >= 0)
  583. {
  584. str_remove_slice (wb, 0, n_written);
  585. continue;
  586. }
  587. if (errno == EAGAIN)
  588. break;
  589. if (errno == EINTR)
  590. continue;
  591. SOCKS_FAIL ("%s: %s", "send", strerror (errno));
  592. }
  593. return true;
  594. }
  595. static void
  596. socks_connector_on_ready
  597. (const struct pollfd *pfd, struct socks_connector *self)
  598. {
  599. (void) pfd;
  600. if (socks_call_on_data (self) && socks_try_flush_write_buffer (self))
  601. {
  602. poller_fd_set (&self->socket_event,
  603. self->write_buffer.len ? (POLLIN | POLLOUT) : POLLIN);
  604. }
  605. else if (self->done)
  606. {
  607. socks_connector_cancel_events (self);
  608. int fd = self->socket_fd;
  609. self->socket_fd = -1;
  610. set_blocking (fd, true);
  611. self->on_connected (self->user_data, fd);
  612. }
  613. else
  614. // We've failed this target, let's try to move on
  615. socks_connector_step (self);
  616. }
  617. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  618. static void
  619. socks_connector_init (struct socks_connector *self, struct poller *poller)
  620. {
  621. memset (self, 0, sizeof *self);
  622. poller_fd_init (&self->socket_event, poller, (self->socket_fd = -1));
  623. self->socket_event.dispatcher = (poller_fd_fn) socks_connector_on_ready;
  624. self->socket_event.user_data = self;
  625. poller_timer_init (&self->timeout, poller);
  626. self->timeout.dispatcher = (poller_timer_fn) socks_connector_on_timeout;
  627. self->timeout.user_data = self;
  628. str_init (&self->read_buffer);
  629. str_init (&self->write_buffer);
  630. }
  631. static void
  632. socks_connector_free (struct socks_connector *self)
  633. {
  634. socks_connector_destroy_connector (self);
  635. socks_connector_cancel_events (self);
  636. if (self->socket_fd != -1)
  637. xclose (self->socket_fd);
  638. str_free (&self->read_buffer);
  639. str_free (&self->write_buffer);
  640. free (self->hostname);
  641. free (self->service);
  642. free (self->username);
  643. free (self->password);
  644. LIST_FOR_EACH (struct socks_target, iter, self->targets)
  645. {
  646. socks_addr_free (&iter->address);
  647. free (iter->address_str);
  648. free (iter);
  649. }
  650. socks_addr_free (&self->bound_address);
  651. }
  652. static bool
  653. socks_connector_add_target (struct socks_connector *self,
  654. const char *host, const char *service, struct error **e)
  655. {
  656. unsigned long port;
  657. const struct servent *serv;
  658. if ((serv = getservbyname (service, "tcp")))
  659. port = (uint16_t) ntohs (serv->s_port);
  660. else if (!xstrtoul (&port, service, 10) || !port || port > UINT16_MAX)
  661. {
  662. error_set (e, "invalid port number");
  663. return false;
  664. }
  665. struct socks_target *target = xcalloc (1, sizeof *target);
  666. if (inet_pton (AF_INET, host, &target->address.data.ipv4) == 1)
  667. target->address.type = SOCKS_IPV4;
  668. else if (inet_pton (AF_INET6, host, &target->address.data.ipv6) == 1)
  669. target->address.type = SOCKS_IPV6;
  670. else
  671. {
  672. target->address.type = SOCKS_DOMAIN;
  673. target->address.data.domain = xstrdup (host);
  674. }
  675. target->port = port;
  676. target->address_str = xstrdup (host);
  677. LIST_APPEND_WITH_TAIL (self->targets, self->targets_tail, target);
  678. return true;
  679. }
  680. static void
  681. socks_connector_run (struct socks_connector *self,
  682. const char *host, const char *service,
  683. const char *username, const char *password)
  684. {
  685. hard_assert (self->targets);
  686. hard_assert (host && service);
  687. self->hostname = xstrdup (host);
  688. self->service = xstrdup (service);
  689. if (username) self->username = xstrdup (username);
  690. if (password) self->password = xstrdup (password);
  691. self->targets_iter = self->targets;
  692. self->protocol_iter = 0;
  693. // XXX: this can fail immediately from an error creating the connector
  694. socks_connector_start (self);
  695. }
  696. // --- CTCP decoding -----------------------------------------------------------
  697. #define CTCP_M_QUOTE '\020'
  698. #define CTCP_X_DELIM '\001'
  699. #define CTCP_X_QUOTE '\\'
  700. struct ctcp_chunk
  701. {
  702. LIST_HEADER (struct ctcp_chunk)
  703. bool is_extended; ///< Is this a tagged extended message?
  704. bool is_partial; ///< Unterminated extended message
  705. struct str tag; ///< The tag, if any
  706. struct str text; ///< Message contents
  707. };
  708. static struct ctcp_chunk *
  709. ctcp_chunk_new (void)
  710. {
  711. struct ctcp_chunk *self = xcalloc (1, sizeof *self);
  712. str_init (&self->tag);
  713. str_init (&self->text);
  714. return self;
  715. }
  716. static void
  717. ctcp_chunk_destroy (struct ctcp_chunk *self)
  718. {
  719. str_free (&self->tag);
  720. str_free (&self->text);
  721. free (self);
  722. }
  723. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  724. static void
  725. ctcp_low_level_decode (const char *message, struct str *output)
  726. {
  727. bool escape = false;
  728. for (const char *p = message; *p; p++)
  729. {
  730. if (escape)
  731. {
  732. switch (*p)
  733. {
  734. case '0': str_append_c (output, '\0'); break;
  735. case 'r': str_append_c (output, '\r'); break;
  736. case 'n': str_append_c (output, '\n'); break;
  737. default: str_append_c (output, *p);
  738. }
  739. escape = false;
  740. }
  741. else if (*p == CTCP_M_QUOTE)
  742. escape = true;
  743. else
  744. str_append_c (output, *p);
  745. }
  746. }
  747. static void
  748. ctcp_intra_decode (const char *chunk, size_t len, struct str *output)
  749. {
  750. bool escape = false;
  751. for (size_t i = 0; i < len; i++)
  752. {
  753. char c = chunk[i];
  754. if (escape)
  755. {
  756. if (c == 'a')
  757. str_append_c (output, CTCP_X_DELIM);
  758. else
  759. str_append_c (output, c);
  760. escape = false;
  761. }
  762. else if (c == CTCP_X_QUOTE)
  763. escape = true;
  764. else
  765. str_append_c (output, c);
  766. }
  767. }
  768. static void
  769. ctcp_parse_tagged (const char *chunk, size_t len, struct ctcp_chunk *output)
  770. {
  771. // We may search for the space before doing the higher level decoding,
  772. // as it doesn't concern space characters at all
  773. size_t tag_end = len;
  774. for (size_t i = 0; i < len; i++)
  775. if (chunk[i] == ' ')
  776. {
  777. tag_end = i;
  778. break;
  779. }
  780. output->is_extended = true;
  781. ctcp_intra_decode (chunk, tag_end, &output->tag);
  782. if (tag_end++ != len)
  783. ctcp_intra_decode (chunk + tag_end, len - tag_end, &output->text);
  784. }
  785. static struct ctcp_chunk *
  786. ctcp_parse (const char *message)
  787. {
  788. struct str m;
  789. str_init (&m);
  790. ctcp_low_level_decode (message, &m);
  791. struct ctcp_chunk *result = NULL, *result_tail = NULL;
  792. // According to the original CTCP specification we should use
  793. // ctcp_intra_decode() on all parts, however no one seems to
  794. // use that and it breaks normal text with backslashes
  795. size_t start = 0;
  796. bool in_ctcp = false;
  797. for (size_t i = 0; i < m.len; i++)
  798. {
  799. char c = m.str[i];
  800. if (c != CTCP_X_DELIM)
  801. continue;
  802. // Remember the current state
  803. size_t my_start = start;
  804. bool my_is_ctcp = in_ctcp;
  805. start = i + 1;
  806. in_ctcp = !in_ctcp;
  807. // Skip empty chunks
  808. if (my_start == i)
  809. continue;
  810. struct ctcp_chunk *chunk = ctcp_chunk_new ();
  811. if (my_is_ctcp)
  812. ctcp_parse_tagged (m.str + my_start, i - my_start, chunk);
  813. else
  814. str_append_data (&chunk->text, m.str + my_start, i - my_start);
  815. LIST_APPEND_WITH_TAIL (result, result_tail, chunk);
  816. }
  817. // Finish the last part. Unended tagged chunks are marked as such.
  818. if (start != m.len)
  819. {
  820. struct ctcp_chunk *chunk = ctcp_chunk_new ();
  821. if (in_ctcp)
  822. {
  823. ctcp_parse_tagged (m.str + start, m.len - start, chunk);
  824. chunk->is_partial = true;
  825. }
  826. else
  827. str_append_data (&chunk->text, m.str + start, m.len - start);
  828. LIST_APPEND_WITH_TAIL (result, result_tail, chunk);
  829. }
  830. str_free (&m);
  831. return result;
  832. }
  833. static void
  834. ctcp_destroy (struct ctcp_chunk *list)
  835. {
  836. LIST_FOR_EACH (struct ctcp_chunk, iter, list)
  837. ctcp_chunk_destroy (iter);
  838. }
  839. // --- Advanced configuration --------------------------------------------------
  840. // This is a new configuration format, superseding the one currently present
  841. // in liberty. It's just a lot more complicated and allows key-value maps.
  842. // We need it in degesch to provide non-sucking user experience.
  843. enum config_item_type
  844. {
  845. CONFIG_ITEM_NULL, ///< No value
  846. CONFIG_ITEM_OBJECT, ///< Key-value map
  847. CONFIG_ITEM_BOOLEAN, ///< Truth value
  848. CONFIG_ITEM_INTEGER, ///< Integer
  849. CONFIG_ITEM_STRING, ///< Arbitrary string of characters
  850. CONFIG_ITEM_STRING_ARRAY ///< Comma-separated list of strings
  851. };
  852. struct config_item
  853. {
  854. enum config_item_type type; ///< Type of the item
  855. union
  856. {
  857. struct str_map object; ///< Key-value data
  858. bool boolean; ///< Boolean data
  859. int64_t integer; ///< Integer data
  860. struct str string; ///< String data
  861. }
  862. value; ///< The value of this item
  863. struct config_schema *schema; ///< Schema describing this value
  864. void *user_data; ///< User value attached by schema owner
  865. };
  866. struct config_schema
  867. {
  868. const char *name; ///< Name of the item
  869. const char *comment; ///< User-readable description
  870. enum config_item_type type; ///< Required type
  871. const char *default_; ///< Default as a configuration snippet
  872. /// Check if the new value can be accepted.
  873. /// In addition to this, "type" and having a default is considered.
  874. bool (*validate) (const struct config_item *, struct error **e);
  875. /// The value has changed
  876. void (*on_change) (struct config_item *);
  877. };
  878. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  879. static const char *
  880. config_item_type_name (enum config_item_type type)
  881. {
  882. switch (type)
  883. {
  884. case CONFIG_ITEM_NULL: return "null";
  885. case CONFIG_ITEM_BOOLEAN: return "boolean";
  886. case CONFIG_ITEM_INTEGER: return "integer";
  887. case CONFIG_ITEM_STRING: return "string";
  888. case CONFIG_ITEM_STRING_ARRAY: return "string array";
  889. default:
  890. hard_assert (!"invalid config item type value");
  891. return NULL;
  892. }
  893. }
  894. static bool
  895. config_item_type_is_string (enum config_item_type type)
  896. {
  897. return type == CONFIG_ITEM_STRING
  898. || type == CONFIG_ITEM_STRING_ARRAY;
  899. }
  900. static void
  901. config_item_free (struct config_item *self)
  902. {
  903. switch (self->type)
  904. {
  905. case CONFIG_ITEM_STRING:
  906. case CONFIG_ITEM_STRING_ARRAY:
  907. str_free (&self->value.string);
  908. break;
  909. case CONFIG_ITEM_OBJECT:
  910. str_map_free (&self->value.object);
  911. default:
  912. break;
  913. }
  914. }
  915. static void
  916. config_item_destroy (struct config_item *self)
  917. {
  918. config_item_free (self);
  919. free (self);
  920. }
  921. /// Doesn't do any validations or handle schemas, just moves source data
  922. /// to the target item and destroys the source item
  923. static void
  924. config_item_move (struct config_item *self, struct config_item *source)
  925. {
  926. // Not quite sure how to handle that
  927. hard_assert (!source->schema);
  928. config_item_free (self);
  929. self->type = source->type;
  930. memcpy (&self->value, &source->value, sizeof source->value);
  931. free (source);
  932. }
  933. static struct config_item *
  934. config_item_new (enum config_item_type type)
  935. {
  936. struct config_item *self = xcalloc (1, sizeof *self);
  937. self->type = type;
  938. return self;
  939. }
  940. static struct config_item *
  941. config_item_null (void)
  942. {
  943. return config_item_new (CONFIG_ITEM_NULL);
  944. }
  945. static struct config_item *
  946. config_item_boolean (bool b)
  947. {
  948. struct config_item *self = config_item_new (CONFIG_ITEM_BOOLEAN);
  949. self->value.boolean = b;
  950. return self;
  951. }
  952. static struct config_item *
  953. config_item_integer (int64_t i)
  954. {
  955. struct config_item *self = config_item_new (CONFIG_ITEM_INTEGER);
  956. self->value.integer = i;
  957. return self;
  958. }
  959. static struct config_item *
  960. config_item_string (const struct str *s)
  961. {
  962. struct config_item *self = config_item_new (CONFIG_ITEM_STRING);
  963. str_init (&self->value.string);
  964. hard_assert (utf8_validate
  965. (self->value.string.str, self->value.string.len));
  966. if (s) str_append_str (&self->value.string, s);
  967. return self;
  968. }
  969. static struct config_item *
  970. config_item_string_from_cstr (const char *s)
  971. {
  972. struct str tmp;
  973. str_init (&tmp);
  974. str_append (&tmp, s);
  975. struct config_item *self = config_item_string (&tmp);
  976. str_free (&tmp);
  977. return self;
  978. }
  979. static struct config_item *
  980. config_item_string_array (const struct str *s)
  981. {
  982. struct config_item *self = config_item_string (s);
  983. self->type = CONFIG_ITEM_STRING_ARRAY;
  984. return self;
  985. }
  986. static struct config_item *
  987. config_item_object (void)
  988. {
  989. struct config_item *self = config_item_new (CONFIG_ITEM_OBJECT);
  990. str_map_init (&self->value.object);
  991. self->value.object.free = (void (*)(void *)) config_item_destroy;
  992. return self;
  993. }
  994. static bool
  995. config_schema_accepts_type
  996. (struct config_schema *self, enum config_item_type type)
  997. {
  998. if (self->type == type)
  999. return true;
  1000. // This is a bit messy but it has its purpose
  1001. if (config_item_type_is_string (self->type)
  1002. && config_item_type_is_string (type))
  1003. return true;
  1004. return !self->default_ && type == CONFIG_ITEM_NULL;
  1005. }
  1006. static bool
  1007. config_item_validate_by_schema (struct config_item *self,
  1008. struct config_schema *schema, struct error **e)
  1009. {
  1010. struct error *error = NULL;
  1011. if (!config_schema_accepts_type (schema, self->type))
  1012. error_set (e, "invalid type of value, expected: %s%s",
  1013. config_item_type_name (schema->type),
  1014. !schema->default_ ? " (or null)" : "");
  1015. else if (schema->validate && !schema->validate (self, &error))
  1016. {
  1017. error_set (e, "%s: %s", "invalid value", error->message);
  1018. error_free (error);
  1019. }
  1020. else
  1021. return true;
  1022. return false;
  1023. }
  1024. static bool
  1025. config_item_set_from (struct config_item *self, struct config_item *source,
  1026. struct error **e)
  1027. {
  1028. struct config_schema *schema = self->schema;
  1029. if (!schema)
  1030. {
  1031. // Easy, we don't know what this item is
  1032. config_item_move (self, source);
  1033. return true;
  1034. }
  1035. if (!config_item_validate_by_schema (source, schema, e))
  1036. return false;
  1037. // Make sure the string subtype fits the schema
  1038. if (config_item_type_is_string (source->type)
  1039. && config_item_type_is_string (schema->type))
  1040. source->type = schema->type;
  1041. config_item_move (self, source);
  1042. // Notify owner about the change so that they can apply it
  1043. if (schema->on_change)
  1044. schema->on_change (self);
  1045. return true;
  1046. }
  1047. static struct config_item *
  1048. config_item_get (struct config_item *self, const char *path, struct error **e)
  1049. {
  1050. hard_assert (self->type == CONFIG_ITEM_OBJECT);
  1051. struct str_vector v;
  1052. str_vector_init (&v);
  1053. split_str (path, ".", &v);
  1054. struct config_item *result = NULL;
  1055. size_t i = 0;
  1056. while (true)
  1057. {
  1058. const char *key = v.vector[i];
  1059. if (!*key)
  1060. error_set (e, "empty path element");
  1061. else if (!(self = str_map_find (&self->value.object, key)))
  1062. error_set (e, "`%s' not found in object", key);
  1063. else if (++i == v.len)
  1064. result = self;
  1065. else if (self->type != CONFIG_ITEM_OBJECT)
  1066. error_set (e, "`%s' is not an object", key);
  1067. else
  1068. continue;
  1069. break;
  1070. }
  1071. str_vector_free (&v);
  1072. return result;
  1073. }
  1074. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1075. struct config_writer
  1076. {
  1077. struct str *output;
  1078. unsigned indent;
  1079. };
  1080. static void config_item_write_object_innards
  1081. (struct config_writer *self, struct config_item *object);
  1082. static void
  1083. config_item_write_string (struct str *output, const struct str *s)
  1084. {
  1085. str_append_c (output, '"');
  1086. for (size_t i = 0; i < s->len; i++)
  1087. {
  1088. unsigned char c = s->str[i];
  1089. if (c == '\n') str_append (output, "\\n");
  1090. else if (c == '\r') str_append (output, "\\r");
  1091. else if (c == '\t') str_append (output, "\\t");
  1092. else if (c == '\\') str_append (output, "\\\\");
  1093. else if (c == '"') str_append (output, "\\\"");
  1094. else if (c < 32) str_append_printf (output, "\\x%02x", c);
  1095. else str_append_c (output, c);
  1096. }
  1097. str_append_c (output, '"');
  1098. }
  1099. static void
  1100. config_item_write_object
  1101. (struct config_writer *self, struct config_item *value)
  1102. {
  1103. char indent[self->indent + 1];
  1104. memset (indent, '\t', self->indent);
  1105. indent[self->indent] = 0;
  1106. str_append_c (self->output, '{');
  1107. if (value->value.object.len)
  1108. {
  1109. self->indent++;
  1110. str_append_c (self->output, '\n');
  1111. config_item_write_object_innards (self, value);
  1112. self->indent--;
  1113. str_append (self->output, indent);
  1114. }
  1115. str_append_c (self->output, '}');
  1116. }
  1117. static void
  1118. config_item_write_value (struct config_writer *self, struct config_item *value)
  1119. {
  1120. switch (value->type)
  1121. {
  1122. case CONFIG_ITEM_NULL:
  1123. str_append (self->output, "null");
  1124. break;
  1125. case CONFIG_ITEM_BOOLEAN:
  1126. str_append (self->output, value->value.boolean ? "on" : "off");
  1127. break;
  1128. case CONFIG_ITEM_INTEGER:
  1129. str_append_printf (self->output, "%" PRIi64, value->value.integer);
  1130. break;
  1131. case CONFIG_ITEM_STRING:
  1132. case CONFIG_ITEM_STRING_ARRAY:
  1133. config_item_write_string (self->output, &value->value.string);
  1134. break;
  1135. case CONFIG_ITEM_OBJECT:
  1136. config_item_write_object (self, value);
  1137. break;
  1138. default:
  1139. hard_assert (!"invalid item type");
  1140. }
  1141. }
  1142. static void
  1143. config_item_write_kv_pair (struct config_writer *self,
  1144. const char *key, struct config_item *value)
  1145. {
  1146. char indent[self->indent + 1];
  1147. memset (indent, '\t', self->indent);
  1148. indent[self->indent] = 0;
  1149. if (value->schema && value->schema->comment)
  1150. str_append_printf (self->output,
  1151. "%s# %s\n", indent, value->schema->comment);
  1152. str_append_printf (self->output, "%s%s = ", indent, key);
  1153. config_item_write_value (self, value);
  1154. str_append_c (self->output, '\n');
  1155. }
  1156. static void
  1157. config_item_write_object_innards
  1158. (struct config_writer *self, struct config_item *object)
  1159. {
  1160. hard_assert (object->type == CONFIG_ITEM_OBJECT);
  1161. struct str_map_iter iter;
  1162. str_map_iter_init (&iter, &object->value.object);
  1163. struct config_item *value;
  1164. while ((value = str_map_iter_next (&iter)))
  1165. config_item_write_kv_pair (self, iter.link->key, value);
  1166. }
  1167. static void
  1168. config_item_write (struct config_item *value,
  1169. bool object_innards, struct str *output)
  1170. {
  1171. struct config_writer writer = { .output = output, .indent = 0 };
  1172. if (object_innards)
  1173. config_item_write_object_innards (&writer, value);
  1174. else
  1175. config_item_write_value (&writer, value);
  1176. }
  1177. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1178. enum config_token
  1179. {
  1180. CONFIG_T_ABORT, ///< EOF or error
  1181. CONFIG_T_WORD, ///< [a-zA-Z0-9_]+
  1182. CONFIG_T_EQUALS, ///< Equal sign
  1183. CONFIG_T_LBRACE, ///< Left curly bracket
  1184. CONFIG_T_RBRACE, ///< Right curly bracket
  1185. CONFIG_T_NEWLINE, ///< New line
  1186. CONFIG_T_NULL, ///< CONFIG_ITEM_NULL
  1187. CONFIG_T_BOOLEAN, ///< CONFIG_ITEM_BOOLEAN
  1188. CONFIG_T_INTEGER, ///< CONFIG_ITEM_INTEGER
  1189. CONFIG_T_STRING ///< CONFIG_ITEM_STRING{,_LIST}
  1190. };
  1191. static const char *
  1192. config_token_name (enum config_token token)
  1193. {
  1194. switch (token)
  1195. {
  1196. case CONFIG_T_ABORT: return "end of input";
  1197. case CONFIG_T_WORD: return "word";
  1198. case CONFIG_T_EQUALS: return "equal sign";
  1199. case CONFIG_T_LBRACE: return "left brace";
  1200. case CONFIG_T_RBRACE: return "right brace";
  1201. case CONFIG_T_NEWLINE: return "newline";
  1202. case CONFIG_T_NULL: return "null value";
  1203. case CONFIG_T_BOOLEAN: return "boolean";
  1204. case CONFIG_T_INTEGER: return "integer";
  1205. case CONFIG_T_STRING: return "string";
  1206. default:
  1207. hard_assert (!"invalid token value");
  1208. return NULL;
  1209. }
  1210. }
  1211. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1212. struct config_tokenizer
  1213. {
  1214. const char *p; ///< Current position in input
  1215. size_t len; ///< How many bytes of input are left
  1216. bool report_line; ///< Whether to count lines at all
  1217. unsigned line; ///< Current line
  1218. unsigned column; ///< Current column
  1219. int64_t integer; ///< Parsed boolean or integer value
  1220. struct str string; ///< Parsed string value
  1221. };
  1222. /// Input has to be null-terminated anyway
  1223. static void
  1224. config_tokenizer_init (struct config_tokenizer *self, const char *p, size_t len)
  1225. {
  1226. memset (self, 0, sizeof *self);
  1227. self->p = p;
  1228. self->len = len;
  1229. self->report_line = true;
  1230. str_init (&self->string);
  1231. }
  1232. static void
  1233. config_tokenizer_free (struct config_tokenizer *self)
  1234. {
  1235. str_free (&self->string);
  1236. }
  1237. static bool
  1238. config_tokenizer_is_word_char (int c)
  1239. {
  1240. return isalnum_ascii (c) || c == '_';
  1241. }
  1242. static int
  1243. config_tokenizer_advance (struct config_tokenizer *self)
  1244. {
  1245. int c = *self->p++;
  1246. if (c == '\n' && self->report_line)
  1247. {
  1248. self->column = 0;
  1249. self->line++;
  1250. }
  1251. else
  1252. self->column++;
  1253. self->len--;
  1254. return c;
  1255. }
  1256. static void config_tokenizer_error (struct config_tokenizer *self,
  1257. struct error **e, const char *format, ...) ATTRIBUTE_PRINTF (3, 4);
  1258. static void
  1259. config_tokenizer_error (struct config_tokenizer *self,
  1260. struct error **e, const char *format, ...)
  1261. {
  1262. struct str description;
  1263. str_init (&description);
  1264. va_list ap;
  1265. va_start (ap, format);
  1266. str_append_vprintf (&description, format, ap);
  1267. va_end (ap);
  1268. if (self->report_line)
  1269. error_set (e, "near line %u, column %u: %s",
  1270. self->line + 1, self->column + 1, description.str);
  1271. else if (self->len)
  1272. error_set (e, "near character %u: %s",
  1273. self->column + 1, description.str);
  1274. else
  1275. error_set (e, "near end: %s", description.str);
  1276. str_free (&description);
  1277. }
  1278. static bool
  1279. config_tokenizer_hexa_escape (struct config_tokenizer *self, struct str *output)
  1280. {
  1281. int i;
  1282. unsigned char code = 0;
  1283. for (i = 0; self->len && i < 2; i++)
  1284. {
  1285. unsigned char c = tolower_ascii (*self->p);
  1286. if (c >= '0' && c <= '9')
  1287. code = (code << 4) | (c - '0');
  1288. else if (c >= 'a' && c <= 'f')
  1289. code = (code << 4) | (c - 'a' + 10);
  1290. else
  1291. break;
  1292. config_tokenizer_advance (self);
  1293. }
  1294. if (!i)
  1295. return false;
  1296. str_append_c (output, code);
  1297. return true;
  1298. }
  1299. static bool
  1300. config_tokenizer_octal_escape
  1301. (struct config_tokenizer *self, struct str *output)
  1302. {
  1303. int i;
  1304. unsigned char code = 0;
  1305. for (i = 0; self->len && i < 3; i++)
  1306. {
  1307. unsigned char c = *self->p;
  1308. if (c >= '0' && c <= '7')
  1309. code = (code << 3) | (c - '0');
  1310. else
  1311. break;
  1312. config_tokenizer_advance (self);
  1313. }
  1314. if (!i)
  1315. return false;
  1316. str_append_c (output, code);
  1317. return true;
  1318. }
  1319. static bool
  1320. config_tokenizer_escape_sequence
  1321. (struct config_tokenizer *self, struct str *output, struct error **e)
  1322. {
  1323. if (!self->len)
  1324. {
  1325. config_tokenizer_error (self, e, "premature end of escape sequence");
  1326. return false;
  1327. }
  1328. unsigned char c;
  1329. switch ((c = *self->p))
  1330. {
  1331. case '"': break;
  1332. case '\\': break;
  1333. case 'a': c = '\a'; break;
  1334. case 'b': c = '\b'; break;
  1335. case 'f': c = '\f'; break;
  1336. case 'n': c = '\n'; break;
  1337. case 'r': c = '\r'; break;
  1338. case 't': c = '\t'; break;
  1339. case 'v': c = '\v'; break;
  1340. case 'x':
  1341. case 'X':
  1342. config_tokenizer_advance (self);
  1343. if (config_tokenizer_hexa_escape (self, output))
  1344. return true;
  1345. config_tokenizer_error (self, e, "invalid hexadecimal escape");
  1346. return false;
  1347. default:
  1348. if (config_tokenizer_octal_escape (self, output))
  1349. return true;
  1350. config_tokenizer_error (self, e, "unknown escape sequence");
  1351. return false;
  1352. }
  1353. str_append_c (output, c);
  1354. config_tokenizer_advance (self);
  1355. return true;
  1356. }
  1357. static bool
  1358. config_tokenizer_string
  1359. (struct config_tokenizer *self, struct str *output, struct error **e)
  1360. {
  1361. unsigned char c;
  1362. while (self->len)
  1363. {
  1364. if ((c = config_tokenizer_advance (self)) == '"')
  1365. return true;
  1366. if (c != '\\')
  1367. str_append_c (output, c);
  1368. else if (!config_tokenizer_escape_sequence (self, output, e))
  1369. return false;
  1370. }
  1371. config_tokenizer_error (self, e, "premature end of string");
  1372. return false;
  1373. }
  1374. static enum config_token
  1375. config_tokenizer_next (struct config_tokenizer *self, struct error **e)
  1376. {
  1377. // Skip over any whitespace between tokens
  1378. while (self->len && isspace_ascii (*self->p) && *self->p != '\n')
  1379. config_tokenizer_advance (self);
  1380. if (!self->len)
  1381. return CONFIG_T_ABORT;
  1382. switch (*self->p)
  1383. {
  1384. case '\n': config_tokenizer_advance (self); return CONFIG_T_NEWLINE;
  1385. case '=': config_tokenizer_advance (self); return CONFIG_T_EQUALS;
  1386. case '{': config_tokenizer_advance (self); return CONFIG_T_LBRACE;
  1387. case '}': config_tokenizer_advance (self); return CONFIG_T_RBRACE;
  1388. case '#':
  1389. // Comments go until newline
  1390. while (self->len)
  1391. if (config_tokenizer_advance (self) == '\n')
  1392. return CONFIG_T_NEWLINE;
  1393. return CONFIG_T_ABORT;
  1394. case '"':
  1395. config_tokenizer_advance (self);
  1396. str_reset (&self->string);
  1397. if (!config_tokenizer_string (self, &self->string, e))
  1398. return CONFIG_T_ABORT;
  1399. if (!utf8_validate (self->string.str, self->string.len))
  1400. {
  1401. config_tokenizer_error (self, e, "not a valid UTF-8 string");
  1402. return CONFIG_T_ABORT;
  1403. }
  1404. return CONFIG_T_STRING;
  1405. }
  1406. char *end;
  1407. errno = 0;
  1408. self->integer = strtoll (self->p, &end, 10);
  1409. if (errno == ERANGE)
  1410. {
  1411. config_tokenizer_error (self, e, "integer out of range");
  1412. return CONFIG_T_ABORT;
  1413. }
  1414. if (end != self->p)
  1415. {
  1416. self->len -= end - self->p;
  1417. self->p = end;
  1418. return CONFIG_T_INTEGER;
  1419. }
  1420. if (!config_tokenizer_is_word_char (*self->p))
  1421. {
  1422. config_tokenizer_error (self, e, "invalid input");
  1423. return CONFIG_T_ABORT;
  1424. }
  1425. str_reset (&self->string);
  1426. do
  1427. str_append_c (&self->string, config_tokenizer_advance (self));
  1428. while (config_tokenizer_is_word_char (*self->p));
  1429. if (!strcmp (self->string.str, "null"))
  1430. return CONFIG_T_NULL;
  1431. bool boolean;
  1432. if (!set_boolean_if_valid (&boolean, self->string.str))
  1433. return CONFIG_T_WORD;
  1434. self->integer = boolean;
  1435. return CONFIG_T_BOOLEAN;
  1436. }
  1437. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1438. struct config_parser
  1439. {
  1440. struct config_tokenizer tokenizer; ///< Tokenizer
  1441. struct error *error; ///< Tokenizer error
  1442. enum config_token token; ///< Current token in the tokenizer
  1443. bool replace_token; ///< Replace the token
  1444. };
  1445. static void
  1446. config_parser_init (struct config_parser *self, const char *script, size_t len)
  1447. {
  1448. memset (self, 0, sizeof *self);
  1449. config_tokenizer_init (&self->tokenizer, script, len);
  1450. // As reading in tokens may cause exceptions, we wait for the first peek()
  1451. // to replace the initial CONFIG_T_ABORT.
  1452. self->replace_token = true;
  1453. }
  1454. static void
  1455. config_parser_free (struct config_parser *self)
  1456. {
  1457. config_tokenizer_free (&self->tokenizer);
  1458. if (self->error)
  1459. error_free (self->error);
  1460. }
  1461. static enum config_token
  1462. config_parser_peek (struct config_parser *self, jmp_buf out)
  1463. {
  1464. if (self->replace_token)
  1465. {
  1466. self->token = config_tokenizer_next (&self->tokenizer, &self->error);
  1467. if (self->error)
  1468. longjmp (out, 1);
  1469. self->replace_token = false;
  1470. }
  1471. return self->token;
  1472. }
  1473. static bool
  1474. config_parser_accept
  1475. (struct config_parser *self, enum config_token token, jmp_buf out)
  1476. {
  1477. return self->replace_token = (config_parser_peek (self, out) == token);
  1478. }
  1479. static void
  1480. config_parser_expect
  1481. (struct config_parser *self, enum config_token token, jmp_buf out)
  1482. {
  1483. if (config_parser_accept (self, token, out))
  1484. return;
  1485. config_tokenizer_error (&self->tokenizer, &self->error,
  1486. "unexpected `%s', expected `%s'",
  1487. config_token_name (self->token),
  1488. config_token_name (token));
  1489. longjmp (out, 1);
  1490. }
  1491. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1492. // We don't need no generator, but a few macros will come in handy.
  1493. // From time to time C just doesn't have the right features.
  1494. #define PEEK() config_parser_peek (self, err)
  1495. #define ACCEPT(token) config_parser_accept (self, token, err)
  1496. #define EXPECT(token) config_parser_expect (self, token, err)
  1497. #define SKIP_NL() do {} while (ACCEPT (CONFIG_T_NEWLINE))
  1498. static struct config_item *config_parser_parse_object
  1499. (struct config_parser *self, jmp_buf out);
  1500. static struct config_item *
  1501. config_parser_parse_value (struct config_parser *self, jmp_buf out)
  1502. {
  1503. struct config_item *volatile result = NULL;
  1504. jmp_buf err;
  1505. if (setjmp (err))
  1506. {
  1507. if (result)
  1508. config_item_destroy (result);
  1509. longjmp (out, 1);
  1510. }
  1511. if (ACCEPT (CONFIG_T_LBRACE))
  1512. {
  1513. result = config_parser_parse_object (self, out);
  1514. SKIP_NL ();
  1515. EXPECT (CONFIG_T_RBRACE);
  1516. return result;
  1517. }
  1518. if (ACCEPT (CONFIG_T_NULL))
  1519. return config_item_null ();
  1520. if (ACCEPT (CONFIG_T_BOOLEAN))
  1521. return config_item_boolean (self->tokenizer.integer);
  1522. if (ACCEPT (CONFIG_T_INTEGER))
  1523. return config_item_integer (self->tokenizer.integer);
  1524. if (ACCEPT (CONFIG_T_STRING))
  1525. return config_item_string (&self->tokenizer.string);
  1526. config_tokenizer_error (&self->tokenizer, &self->error,
  1527. "unexpected `%s', expected a value",
  1528. config_token_name (self->token));
  1529. longjmp (out, 1);
  1530. }
  1531. /// Parse a single "key = value" assignment into @a object
  1532. static bool
  1533. config_parser_parse_kv_pair (struct config_parser *self,
  1534. struct config_item *object, jmp_buf out)
  1535. {
  1536. char *volatile key = NULL;
  1537. jmp_buf err;
  1538. if (setjmp (err))
  1539. {
  1540. free (key);
  1541. longjmp (out, 1);
  1542. }
  1543. SKIP_NL ();
  1544. // Either this object's closing right brace if called recursively,
  1545. // or end of file when called on a whole configuration file
  1546. if (PEEK () == CONFIG_T_RBRACE
  1547. || PEEK () == CONFIG_T_ABORT)
  1548. return false;
  1549. EXPECT (CONFIG_T_WORD);
  1550. key = xstrdup (self->tokenizer.string.str);
  1551. SKIP_NL ();
  1552. EXPECT (CONFIG_T_EQUALS);
  1553. SKIP_NL ();
  1554. str_map_set (&object->value.object, key,
  1555. config_parser_parse_value (self, err));
  1556. free (key);
  1557. key = NULL;
  1558. if (PEEK () == CONFIG_T_RBRACE
  1559. || PEEK () == CONFIG_T_ABORT)
  1560. return false;
  1561. EXPECT (CONFIG_T_NEWLINE);
  1562. return true;
  1563. }
  1564. /// Parse the inside of an object definition
  1565. static struct config_item *
  1566. config_parser_parse_object (struct config_parser *self, jmp_buf out)
  1567. {
  1568. struct config_item *volatile object = config_item_object ();
  1569. jmp_buf err;
  1570. if (setjmp (err))
  1571. {
  1572. config_item_destroy (object);
  1573. longjmp (out, 1);
  1574. }
  1575. while (config_parser_parse_kv_pair (self, object, err))
  1576. ;
  1577. return object;
  1578. }
  1579. #undef PEEK
  1580. #undef ACCEPT
  1581. #undef EXPECT
  1582. #undef SKIP_NL
  1583. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1584. /// Parse a configuration snippet either as an object or a bare value.
  1585. /// If it's the latter (@a single_value_only), no newlines may follow.
  1586. static struct config_item *
  1587. config_item_parse (const char *script, size_t len,
  1588. bool single_value_only, struct error **e)
  1589. {
  1590. struct config_parser parser;
  1591. config_parser_init (&parser, script, len);
  1592. struct config_item *volatile object = NULL;
  1593. jmp_buf err;
  1594. if (setjmp (err))
  1595. {
  1596. if (object)
  1597. {
  1598. config_item_destroy (object);
  1599. object = NULL;
  1600. }
  1601. error_propagate (e, parser.error);
  1602. parser.error = NULL;
  1603. goto end;
  1604. }
  1605. if (single_value_only)
  1606. {
  1607. // This is really only intended for in-program configuration
  1608. // and telling the line number would look awkward
  1609. parser.tokenizer.report_line = false;
  1610. object = config_parser_parse_value (&parser, err);
  1611. }
  1612. else
  1613. object = config_parser_parse_object (&parser, err);
  1614. config_parser_expect (&parser, CONFIG_T_ABORT, err);
  1615. end:
  1616. config_parser_free (&parser);
  1617. return object;
  1618. }
  1619. /// Clone an item. Schema assignments aren't retained.
  1620. struct config_item *
  1621. config_item_clone (struct config_item *self)
  1622. {
  1623. // Oh well, it saves code
  1624. struct str tmp;
  1625. str_init (&tmp);
  1626. config_item_write (self, false, &tmp);
  1627. struct config_item *result =
  1628. config_item_parse (tmp.str, tmp.len, true, NULL);
  1629. str_free (&tmp);
  1630. return result;
  1631. }
  1632. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1633. static void
  1634. config_schema_initialize_item (struct config_schema *schema,
  1635. struct config_item *parent, void *user_data)
  1636. {
  1637. struct config_item *item =
  1638. str_map_find (&parent->value.object, schema->name);
  1639. bool replace = true;
  1640. if (item)
  1641. {
  1642. // FIXME: either do this silently or tell about it via a callback
  1643. // or just store it in an output vector; don't print it directly
  1644. struct error *e = NULL;
  1645. replace = !config_item_validate_by_schema (item, schema, &e);
  1646. if (e)
  1647. {
  1648. print_error ("resetting configuration item "
  1649. "`%s' to default: %s", schema->name, e->message);
  1650. error_free (e);
  1651. }
  1652. }
  1653. if (replace)
  1654. {
  1655. struct error *e = NULL;
  1656. if (schema->default_)
  1657. item = config_item_parse
  1658. (schema->default_, strlen (schema->default_), true, &e);
  1659. else
  1660. item = config_item_null ();
  1661. if (e || !config_item_validate_by_schema (item, schema, &e))
  1662. exit_fatal ("invalid default for `%s': %s",
  1663. schema->name, e->message);
  1664. // This will free the old item if there was any
  1665. str_map_set (&parent->value.object, schema->name, item);
  1666. }
  1667. // Make sure the string subtype fits the schema
  1668. if (config_item_type_is_string (item->type)
  1669. && config_item_type_is_string (schema->type))
  1670. item->type = schema->type;
  1671. item->schema = schema;
  1672. item->user_data = user_data;
  1673. }
  1674. static void
  1675. config_schema_apply_to_object (struct config_schema *schema_array,
  1676. struct config_item *object, void *user_data)
  1677. {
  1678. hard_assert (object->type == CONFIG_ITEM_OBJECT);
  1679. while (schema_array->name)
  1680. config_schema_initialize_item (schema_array++, object, user_data);
  1681. }
  1682. static void
  1683. config_schema_call_changed (struct config_item *item)
  1684. {
  1685. if (item->type == CONFIG_ITEM_OBJECT)
  1686. {
  1687. struct str_map_iter iter;
  1688. str_map_iter_init (&iter, &item->value.object);
  1689. struct config_item *child;
  1690. while ((child = str_map_iter_next (&iter)))
  1691. config_schema_call_changed (child);
  1692. }
  1693. else if (item->schema && item->schema->on_change)
  1694. item->schema->on_change (item);
  1695. }
  1696. // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1697. // XXX: this doesn't necessarily have to be well designed at all
  1698. typedef void (*config_module_load_fn)
  1699. (struct config_item *subtree, void *user_data);
  1700. struct config_module
  1701. {
  1702. char *name; ///< Name of the subtree
  1703. config_module_load_fn loader; ///< Module config subtree loader
  1704. void *user_data; ///< User data
  1705. };
  1706. static struct config_module *
  1707. config_module_new ()
  1708. {
  1709. struct config_module *self = xcalloc (1, sizeof *self);
  1710. return self;
  1711. }
  1712. static void
  1713. config_module_destroy (struct config_module *self)
  1714. {
  1715. free (self->name);
  1716. free (self);
  1717. }
  1718. struct config
  1719. {
  1720. struct str_map modules; ///< Toplevel modules
  1721. struct config_item *root; ///< CONFIG_ITEM_OBJECT
  1722. };
  1723. static void
  1724. config_init (struct config *self)
  1725. {
  1726. memset (self, 0, sizeof *self);
  1727. str_map_init (&self->modules);
  1728. self->modules.free = (void (*) (void *)) config_module_destroy;
  1729. }
  1730. static void
  1731. config_free (struct config *self)
  1732. {
  1733. str_map_free (&self->modules);
  1734. if (self->root)
  1735. config_item_destroy (self->root);
  1736. }
  1737. static void
  1738. config_register_module (struct config *self,
  1739. const char *name, config_module_load_fn loader, void *user_data)
  1740. {
  1741. struct config_module *module = config_module_new ();
  1742. module->name = xstrdup (name);
  1743. module->loader = loader;
  1744. module->user_data = user_data;
  1745. str_map_set (&self->modules, name, module);
  1746. }
  1747. static void
  1748. config_load (struct config *self, struct config_item *root)
  1749. {
  1750. hard_assert (root->type == CONFIG_ITEM_OBJECT);
  1751. self->root = root;
  1752. struct str_map_iter iter;
  1753. str_map_iter_init (&iter, &self->modules);
  1754. struct config_module *module;
  1755. while ((module = str_map_iter_next (&iter)))
  1756. {
  1757. struct config_item *subtree = str_map_find
  1758. (&root->value.object, module->name);
  1759. // Silently fix inputs that only a lunatic user could create
  1760. if (!subtree || subtree->type != CONFIG_ITEM_OBJECT)
  1761. {
  1762. subtree = config_item_object ();
  1763. str_map_set (&root->value.object, module->name, subtree);
  1764. }
  1765. if (module->loader)
  1766. module->loader (subtree, module->user_data);
  1767. }
  1768. }