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.

2998 lines
83KB

  1. /*
  2. * kike.c: the experimental IRC daemon
  3. *
  4. * Copyright (c) 2014, Přemysl Janouch <p.janouch@gmail.com>
  5. * All rights reserved.
  6. *
  7. * Permission to use, copy, modify, and/or distribute this software for any
  8. * purpose with or without fee is hereby granted, provided that the above
  9. * copyright notice and this permission notice appear in all copies.
  10. *
  11. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  12. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  13. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  14. * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  15. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  16. * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  17. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  18. *
  19. */
  20. #define PROGRAM_NAME "kike"
  21. #define PROGRAM_VERSION "alpha"
  22. #include "common.c"
  23. #include <nl_types.h>
  24. // --- Configuration (application-specific) ------------------------------------
  25. static struct config_item g_config_table[] =
  26. {
  27. { "server_name", NULL, "Server name" },
  28. { "server_info", "My server", "Brief server description" },
  29. { "motd", NULL, "MOTD filename" },
  30. { "catalog", NULL, "catgets localization catalog" },
  31. { "bind_host", NULL, "Address of the IRC server" },
  32. { "bind_port", "6667", "Port of the IRC server" },
  33. { "ssl_cert", NULL, "Server SSL certificate (PEM)" },
  34. { "ssl_key", NULL, "Server SSL private key (PEM)" },
  35. { "operators", NULL, "IRCop SSL cert. fingerprints" },
  36. { "max_connections", "0", "Global connection limit" },
  37. { "ping_interval", "180", "Interval between PING's (sec)" },
  38. { NULL, NULL, NULL }
  39. };
  40. // --- Signals -----------------------------------------------------------------
  41. static int g_signal_pipe[2]; ///< A pipe used to signal... signals
  42. /// Program termination has been requested by a signal
  43. static volatile sig_atomic_t g_termination_requested;
  44. static void
  45. sigterm_handler (int signum)
  46. {
  47. (void) signum;
  48. g_termination_requested = true;
  49. int original_errno = errno;
  50. if (write (g_signal_pipe[1], "t", 1) == -1)
  51. soft_assert (errno == EAGAIN);
  52. errno = original_errno;
  53. }
  54. static void
  55. setup_signal_handlers (void)
  56. {
  57. if (pipe (g_signal_pipe) == -1)
  58. exit_fatal ("%s: %s", "pipe", strerror (errno));
  59. set_cloexec (g_signal_pipe[0]);
  60. set_cloexec (g_signal_pipe[1]);
  61. // So that the pipe cannot overflow; it would make write() block within
  62. // the signal handler, which is something we really don't want to happen.
  63. // The same holds true for read().
  64. set_blocking (g_signal_pipe[0], false);
  65. set_blocking (g_signal_pipe[1], false);
  66. signal (SIGPIPE, SIG_IGN);
  67. struct sigaction sa;
  68. sa.sa_flags = SA_RESTART;
  69. sigemptyset (&sa.sa_mask);
  70. sa.sa_handler = sigterm_handler;
  71. if (sigaction (SIGINT, &sa, NULL) == -1
  72. || sigaction (SIGTERM, &sa, NULL) == -1)
  73. exit_fatal ("%s: %s", "sigaction", strerror (errno));
  74. }
  75. // --- IRC token validation ----------------------------------------------------
  76. // Use the enum only if applicable and a simple boolean isn't sufficient.
  77. enum validation_result
  78. {
  79. VALIDATION_OK,
  80. VALIDATION_ERROR_EMPTY,
  81. VALIDATION_ERROR_TOO_LONG,
  82. VALIDATION_ERROR_INVALID
  83. };
  84. // Everything as per RFC 2812
  85. #define IRC_MAX_NICKNAME 9
  86. #define IRC_MAX_HOSTNAME 63
  87. #define IRC_MAX_CHANNEL_NAME 50
  88. #define IRC_MAX_MESSAGE_LENGTH 510
  89. static bool
  90. irc_regex_match (const char *regex, const char *s)
  91. {
  92. static struct str_map cache;
  93. static bool initialized;
  94. if (!initialized)
  95. {
  96. regex_cache_init (&cache);
  97. initialized = true;
  98. }
  99. struct error *e = NULL;
  100. bool result = regex_cache_match (&cache, regex,
  101. REG_EXTENDED | REG_NOSUB, s, &e);
  102. hard_assert (!e);
  103. return result;
  104. }
  105. static const char *
  106. irc_validate_to_str (enum validation_result result)
  107. {
  108. switch (result)
  109. {
  110. case VALIDATION_OK: return "success";
  111. case VALIDATION_ERROR_EMPTY: return "the value is empty";
  112. case VALIDATION_ERROR_INVALID: return "invalid format";
  113. case VALIDATION_ERROR_TOO_LONG: return "the value is too long";
  114. default: abort ();
  115. }
  116. }
  117. // Anything to keep it as short as possible
  118. #define SN "[0-9A-Za-z][-0-9A-Za-z]*[0-9A-Za-z]*"
  119. #define N4 "[0-9]{1,3}"
  120. #define N6 "[0-9ABCDEFabcdef]{1,}"
  121. #define LE "A-Za-z"
  122. #define SP "][\\\\`_^{|}"
  123. static enum validation_result
  124. irc_validate_hostname (const char *hostname)
  125. {
  126. if (!*hostname)
  127. return VALIDATION_ERROR_EMPTY;
  128. if (!irc_regex_match ("^" SN "(\\." SN ")*$", hostname))
  129. return VALIDATION_ERROR_INVALID;
  130. if (strlen (hostname) > IRC_MAX_HOSTNAME)
  131. return VALIDATION_ERROR_TOO_LONG;
  132. return VALIDATION_OK;
  133. }
  134. static bool
  135. irc_is_valid_hostaddr (const char *hostaddr)
  136. {
  137. if (irc_regex_match ("^" N4 "\\." N4 "\\." N4 "\\." N4 "$", hostaddr)
  138. || irc_regex_match ("^" N6 ":" N6 ":" N6 ":" N6 ":"
  139. N6 ":" N6 ":" N6 ":" N6 "$", hostaddr)
  140. || irc_regex_match ("^0:0:0:0:0:(0|[Ff]{4}):"
  141. N4 "\\." N4 "\\." N4 "\\." N4 "$", hostaddr))
  142. return true;
  143. return false;
  144. }
  145. static bool
  146. irc_is_valid_host (const char *host)
  147. {
  148. return irc_validate_hostname (host) == VALIDATION_OK
  149. || irc_is_valid_hostaddr (host);
  150. }
  151. static bool
  152. irc_is_valid_user (const char *user)
  153. {
  154. return irc_regex_match ("^[^\r\n @]+$", user);
  155. }
  156. static bool
  157. irc_validate_nickname (const char *nickname)
  158. {
  159. if (!*nickname)
  160. return VALIDATION_ERROR_EMPTY;
  161. if (!irc_regex_match ("^[" SP LE "][" SP LE "0-9-]*$", nickname))
  162. return VALIDATION_ERROR_INVALID;
  163. if (strlen (nickname) > IRC_MAX_NICKNAME)
  164. return VALIDATION_ERROR_TOO_LONG;
  165. return VALIDATION_OK;
  166. }
  167. static enum validation_result
  168. irc_validate_channel_name (const char *channel_name)
  169. {
  170. if (!*channel_name)
  171. return VALIDATION_ERROR_EMPTY;
  172. if (*channel_name != '#' || strpbrk (channel_name, "\7\r\n ,:"))
  173. return VALIDATION_ERROR_INVALID;
  174. if (strlen (channel_name) > IRC_MAX_CHANNEL_NAME)
  175. return VALIDATION_ERROR_TOO_LONG;
  176. return VALIDATION_OK;
  177. }
  178. static bool
  179. irc_is_valid_key (const char *key)
  180. {
  181. // XXX: should be 7-bit as well but whatever
  182. return irc_regex_match ("^[^\r\n\f\t\v ]{1,23}$", key);
  183. }
  184. #undef SN
  185. #undef N4
  186. #undef N6
  187. #undef LE
  188. #undef SP
  189. static bool
  190. irc_is_valid_fingerprint (const char *fp)
  191. {
  192. return irc_regex_match ("^[a-fA-F0-9]{2}(:[a-fA-F0-9]{2}){20}$", fp);
  193. }
  194. // --- Application data --------------------------------------------------------
  195. #define IRC_SUPPORTED_USER_MODES "aiwros"
  196. enum
  197. {
  198. IRC_USER_MODE_INVISIBLE = (1 << 0),
  199. IRC_USER_MODE_RX_WALLOPS = (1 << 1),
  200. IRC_USER_MODE_RESTRICTED = (1 << 2),
  201. IRC_USER_MODE_OPERATOR = (1 << 3),
  202. IRC_USER_MODE_RX_SERVER_NOTICES = (1 << 4)
  203. };
  204. struct client
  205. {
  206. LIST_HEADER (client)
  207. struct server_context *ctx; ///< Server context
  208. int socket_fd; ///< The TCP socket
  209. struct str read_buffer; ///< Unprocessed input
  210. struct str write_buffer; ///< Output yet to be sent out
  211. bool initialized; ///< Has any data been received yet?
  212. bool registered; ///< The user has registered
  213. bool closing_link; ///< Closing link
  214. bool ssl_rx_want_tx; ///< SSL_read() wants to write
  215. bool ssl_tx_want_rx; ///< SSL_write() wants to read
  216. SSL *ssl; ///< SSL connection
  217. char *ssl_cert_fingerprint; ///< Client certificate fingerprint
  218. char *nickname; ///< IRC nickname (main identifier)
  219. char *username; ///< IRC username
  220. char *realname; ///< IRC realname (e-mail)
  221. char *hostname; ///< Hostname shown to the network
  222. unsigned mode; ///< User's mode
  223. char *away_message; ///< Away message
  224. time_t last_active; ///< Last PRIVMSG, to get idle time
  225. };
  226. static void
  227. client_init (struct client *self)
  228. {
  229. memset (self, 0, sizeof *self);
  230. self->socket_fd = -1;
  231. str_init (&self->read_buffer);
  232. str_init (&self->write_buffer);
  233. }
  234. static void
  235. client_free (struct client *self)
  236. {
  237. if (!soft_assert (self->socket_fd == -1))
  238. xclose (self->socket_fd);
  239. if (self->ssl)
  240. SSL_free (self->ssl);
  241. str_free (&self->read_buffer);
  242. str_free (&self->write_buffer);
  243. free (self->nickname);
  244. free (self->username);
  245. free (self->realname);
  246. free (self->hostname);
  247. free (self->away_message);
  248. }
  249. static void
  250. client_mode_to_str (unsigned m, struct str *out)
  251. {
  252. if (m & IRC_USER_MODE_INVISIBLE) str_append_c (out, 'i');
  253. if (m & IRC_USER_MODE_RX_WALLOPS) str_append_c (out, 'w');
  254. if (m & IRC_USER_MODE_RESTRICTED) str_append_c (out, 'r');
  255. if (m & IRC_USER_MODE_OPERATOR) str_append_c (out, 'o');
  256. if (m & IRC_USER_MODE_RX_SERVER_NOTICES) str_append_c (out, 's');
  257. }
  258. static char *
  259. client_get_mode (struct client *self)
  260. {
  261. struct str mode;
  262. str_init (&mode);
  263. if (self->away_message)
  264. str_append_c (&mode, 'a');
  265. client_mode_to_str (self->mode, &mode);
  266. return str_steal (&mode);
  267. }
  268. #define IRC_SUPPORTED_CHAN_MODES "ov" "beI" "imnqpst" "kl"
  269. enum
  270. {
  271. IRC_CHAN_MODE_INVITE_ONLY = (1 << 0),
  272. IRC_CHAN_MODE_MODERATED = (1 << 1),
  273. IRC_CHAN_MODE_NO_OUTSIDE_MSGS = (1 << 2),
  274. IRC_CHAN_MODE_QUIET = (1 << 3),
  275. IRC_CHAN_MODE_PRIVATE = (1 << 4),
  276. IRC_CHAN_MODE_SECRET = (1 << 5),
  277. IRC_CHAN_MODE_PROTECTED_TOPIC = (1 << 6),
  278. IRC_CHAN_MODE_OPERATOR = (1 << 7),
  279. IRC_CHAN_MODE_VOICE = (1 << 8)
  280. };
  281. struct channel_user
  282. {
  283. LIST_HEADER (channel_user)
  284. unsigned modes;
  285. char nickname[];
  286. };
  287. struct channel
  288. {
  289. struct server_context *ctx; ///< Server context
  290. char *name; ///< Channel name
  291. unsigned modes; ///< Channel modes
  292. char *key; ///< Channel key
  293. long user_limit; ///< User limit or -1
  294. char *topic; ///< Channel topic
  295. struct channel_user *users; ///< Channel users
  296. struct str_vector ban_list; ///< Ban list
  297. struct str_vector exception_list; ///< Exceptions from bans
  298. struct str_vector invite_list; ///< Exceptions from +I
  299. };
  300. static void
  301. channel_init (struct channel *self)
  302. {
  303. memset (self, 0, sizeof *self);
  304. self->user_limit = -1;
  305. self->topic = xstrdup ("");
  306. str_vector_init (&self->ban_list);
  307. str_vector_init (&self->exception_list);
  308. str_vector_init (&self->invite_list);
  309. }
  310. static void
  311. channel_free (struct channel *self)
  312. {
  313. free (self->name);
  314. free (self->key);
  315. free (self->topic);
  316. struct channel_user *link, *tmp;
  317. for (link = self->users; link; link = tmp)
  318. {
  319. tmp = link->next;
  320. free (link);
  321. }
  322. str_vector_free (&self->ban_list);
  323. str_vector_free (&self->exception_list);
  324. str_vector_free (&self->invite_list);
  325. }
  326. static char *
  327. channel_get_mode (struct channel *self, bool disclose_secrets)
  328. {
  329. struct str mode;
  330. str_init (&mode);
  331. unsigned m = self->modes;
  332. if (m & IRC_CHAN_MODE_INVITE_ONLY) str_append_c (&mode, 'i');
  333. if (m & IRC_CHAN_MODE_MODERATED) str_append_c (&mode, 'm');
  334. if (m & IRC_CHAN_MODE_NO_OUTSIDE_MSGS) str_append_c (&mode, 'n');
  335. if (m & IRC_CHAN_MODE_QUIET) str_append_c (&mode, 'q');
  336. if (m & IRC_CHAN_MODE_PRIVATE) str_append_c (&mode, 'p');
  337. if (m & IRC_CHAN_MODE_SECRET) str_append_c (&mode, 's');
  338. if (m & IRC_CHAN_MODE_PROTECTED_TOPIC) str_append_c (&mode, 't');
  339. if (self->user_limit != -1) str_append_c (&mode, 'l');
  340. if (self->key) str_append_c (&mode, 'k');
  341. if (self->user_limit != -1)
  342. str_append_printf (&mode, " %ld", self->user_limit);
  343. // XXX: is this correct? Try it on an existing implementation.
  344. if (self->key && disclose_secrets)
  345. str_append_printf (&mode, " %s", self->key);
  346. return str_steal (&mode);
  347. }
  348. struct server_context
  349. {
  350. int listen_fd; ///< Listening socket FD
  351. struct client *clients; ///< Clients
  352. SSL_CTX *ssl_ctx; ///< SSL context
  353. unsigned n_clients; ///< Current number of connections
  354. struct str_map users; ///< Maps nicknames to clients
  355. struct str_map channels; ///< Maps channel names to data
  356. struct str_map handlers; ///< Message handlers
  357. struct poller poller; ///< Manages polled description
  358. bool quitting; ///< User requested quitting
  359. bool polling; ///< The event loop is running
  360. struct str_map config; ///< Server configuration
  361. char *server_name; ///< Our server name
  362. unsigned ping_interval; ///< Ping interval in seconds
  363. unsigned max_connections; ///< Max. connections allowed or 0
  364. struct str_vector motd; ///< MOTD (none if empty)
  365. nl_catd catalog; ///< Message catalog for server msgs
  366. struct str_map operators; ///< SSL cert. fingerprints for IRCops
  367. };
  368. static void
  369. server_context_init (struct server_context *self)
  370. {
  371. self->listen_fd = -1;
  372. self->clients = NULL;
  373. self->n_clients = 0;
  374. str_map_init (&self->users);
  375. self->users.key_xfrm = irc_strxfrm;
  376. // TODO: set channel_free() as the free function?
  377. str_map_init (&self->channels);
  378. self->channels.key_xfrm = irc_strxfrm;
  379. str_map_init (&self->handlers);
  380. self->handlers.key_xfrm = irc_strxfrm;
  381. poller_init (&self->poller);
  382. self->quitting = false;
  383. self->polling = false;
  384. str_map_init (&self->config);
  385. self->config.free = free;
  386. load_config_defaults (&self->config, g_config_table);
  387. self->server_name = NULL;
  388. self->ping_interval = 0;
  389. self->max_connections = 0;
  390. str_vector_init (&self->motd);
  391. self->catalog = (nl_catd) -1;
  392. str_map_init (&self->operators);
  393. // The regular irc_strxfrm() is sufficient for fingerprints
  394. self->operators.key_xfrm = irc_strxfrm;
  395. }
  396. static void
  397. server_context_free (struct server_context *self)
  398. {
  399. str_map_free (&self->config);
  400. if (self->listen_fd != -1)
  401. xclose (self->listen_fd);
  402. if (self->ssl_ctx)
  403. SSL_CTX_free (self->ssl_ctx);
  404. struct client *link, *tmp;
  405. for (link = self->clients; link; link = tmp)
  406. {
  407. tmp = link->next;
  408. client_free (link);
  409. free (link);
  410. }
  411. free (self->server_name);
  412. str_map_free (&self->users);
  413. str_map_free (&self->channels);
  414. str_map_free (&self->handlers);
  415. poller_free (&self->poller);
  416. str_vector_free (&self->motd);
  417. if (self->catalog != (nl_catd) -1)
  418. catclose (self->catalog);
  419. str_map_free (&self->operators);
  420. }
  421. static void
  422. irc_try_finish_quit (struct server_context *ctx)
  423. {
  424. if (!ctx->n_clients && ctx->quitting)
  425. ctx->polling = false;
  426. }
  427. static const char *
  428. irc_get_text (struct server_context *ctx, int id, const char *def)
  429. {
  430. if (!soft_assert (def != NULL))
  431. def = "";
  432. if (ctx->catalog == (nl_catd) -1)
  433. return def;
  434. return catgets (ctx->catalog, 1, id, def);
  435. }
  436. static int
  437. irc_fnmatch (const char *pattern, const char *string)
  438. {
  439. size_t pattern_size = strlen (pattern) + 1;
  440. size_t string_size = strlen (string) + 1;
  441. char x_pattern[pattern_size], x_string[string_size];
  442. irc_strxfrm (x_pattern, pattern, pattern_size);
  443. irc_strxfrm (x_string, string, string_size);
  444. return fnmatch (x_pattern, x_string, 0);
  445. }
  446. // --- Channels ----------------------------------------------------------------
  447. static struct channel_user *
  448. channel_get_user (const struct channel *chan, const struct client *c)
  449. {
  450. for (struct channel_user *iter = chan->users; iter; iter = iter->next)
  451. if (!irc_strcmp (iter->nickname, c->nickname))
  452. return iter;
  453. return NULL;
  454. }
  455. static struct channel_user *
  456. channel_add_user (struct channel *chan, const struct client *c)
  457. {
  458. size_t nick_len = strlen (c->nickname);
  459. struct channel_user *link = xcalloc (1, sizeof *link + nick_len + 1);
  460. memcpy (link->nickname, c->nickname, nick_len + 1);
  461. LIST_PREPEND (chan->users, link);
  462. return link;
  463. }
  464. static void
  465. channel_remove_user (struct channel *chan, struct channel_user *user)
  466. {
  467. LIST_UNLINK (chan->users, user);
  468. free (user);
  469. }
  470. static size_t
  471. channel_user_count (const struct channel *chan)
  472. {
  473. size_t result = 0;
  474. for (struct channel_user *iter = chan->users; iter; iter = iter->next)
  475. result++;
  476. return result;
  477. }
  478. static struct channel *
  479. channel_create (struct server_context *ctx, const char *name)
  480. {
  481. struct channel *chan = xcalloc (1, sizeof *chan);
  482. channel_init (chan);
  483. str_map_set (&ctx->channels, name, chan);
  484. chan->ctx = ctx;
  485. chan->name = xstrdup (name);
  486. return chan;
  487. }
  488. static void
  489. channel_destroy_if_empty (struct server_context *ctx, struct channel *chan)
  490. {
  491. if (!chan->users)
  492. {
  493. str_map_set (&ctx->channels, chan->name, NULL);
  494. channel_free (chan);
  495. free (chan);
  496. }
  497. }
  498. // --- Clients -----------------------------------------------------------------
  499. static void client_cancel_timers (struct client *);
  500. static void client_set_kill_timer (struct client *);
  501. static void client_update_poller (struct client *, const struct pollfd *);
  502. static void
  503. irc_send_str (struct client *c, const struct str *s)
  504. {
  505. hard_assert (c->initialized && !c->closing_link);
  506. // TODO: kill the connection above some "SendQ" threshold (careful!)
  507. str_append_data (&c->write_buffer, s->str,
  508. s->len > IRC_MAX_MESSAGE_LENGTH ? IRC_MAX_MESSAGE_LENGTH : s->len);
  509. str_append (&c->write_buffer, "\r\n");
  510. // XXX: we might want to move this elsewhere, so that it doesn't get called
  511. // as often; it's going to cause a lot of syscalls with epoll.
  512. client_update_poller (c, NULL);
  513. }
  514. static void irc_send (struct client *c,
  515. const char *format, ...) ATTRIBUTE_PRINTF (2, 3);
  516. static void
  517. irc_send (struct client *c, const char *format, ...)
  518. {
  519. struct str tmp;
  520. str_init (&tmp);
  521. va_list ap;
  522. va_start (ap, format);
  523. str_append_vprintf (&tmp, format, ap);
  524. va_end (ap);
  525. irc_send_str (c, &tmp);
  526. str_free (&tmp);
  527. }
  528. static void
  529. client_send_to_roommates (struct client *c, const char *message)
  530. {
  531. struct str_map targets;
  532. str_map_init (&targets);
  533. targets.key_xfrm = irc_strxfrm;
  534. struct str_map_iter iter;
  535. str_map_iter_init (&iter, &c->ctx->channels);
  536. struct channel *chan;
  537. while ((chan = str_map_iter_next (&iter)))
  538. {
  539. if (chan->modes & IRC_CHAN_MODE_QUIET
  540. || !channel_get_user (chan, c))
  541. continue;
  542. // When we're unregistering, the str_map_find() will return zero,
  543. // which will prevent sending the QUIT message to ourselves.
  544. for (struct channel_user *iter = chan->users; iter; iter = iter->next)
  545. str_map_set (&targets, iter->nickname,
  546. str_map_find (&c->ctx->users, iter->nickname));
  547. }
  548. str_map_iter_init (&iter, &targets);
  549. struct client *target;
  550. while ((target = str_map_iter_next (&iter)))
  551. irc_send (target, "%s", message);
  552. }
  553. static void
  554. client_unregister (struct client *c, const char *reason)
  555. {
  556. if (!c->registered)
  557. return;
  558. // Make the user effectively non-existent
  559. str_map_set (&c->ctx->users, c->nickname, NULL);
  560. char *message = xstrdup_printf (":%s!%s@%s QUIT :%s",
  561. c->nickname, c->username, c->hostname, reason);
  562. client_send_to_roommates (c, message);
  563. free (message);
  564. struct str_map_iter iter;
  565. str_map_iter_init (&iter, &c->ctx->channels);
  566. struct channel *chan;
  567. while ((chan = str_map_iter_next (&iter)))
  568. {
  569. struct channel_user *user;
  570. if (!(user = channel_get_user (chan, c)))
  571. continue;
  572. channel_remove_user (chan, user);
  573. channel_destroy_if_empty (c->ctx, chan);
  574. }
  575. free (c->nickname);
  576. c->nickname = NULL;
  577. c->registered = false;
  578. }
  579. static void
  580. client_kill (struct client *c, const char *reason)
  581. {
  582. client_unregister (c, reason ? reason : "Client exited");
  583. struct server_context *ctx = c->ctx;
  584. ssize_t i = poller_find_by_fd (&ctx->poller, c->socket_fd);
  585. if (i != -1)
  586. poller_remove_at_index (&ctx->poller, i);
  587. client_cancel_timers (c);
  588. if (c->ssl)
  589. (void) SSL_shutdown (c->ssl);
  590. xclose (c->socket_fd);
  591. c->socket_fd = -1;
  592. client_free (c);
  593. LIST_UNLINK (ctx->clients, c);
  594. ctx->n_clients--;
  595. free (c);
  596. irc_try_finish_quit (ctx);
  597. }
  598. static void
  599. irc_close_link (struct client *c, const char *reason)
  600. {
  601. if (!soft_assert (!c->closing_link))
  602. return;
  603. // We push an `ERROR' message to the write buffer and let the poller send
  604. // it, with some arbitrary timeout. The `closing_link' state makes sure
  605. // that a/ we ignore any successive messages, and b/ that the connection
  606. // is killed after the write buffer is transferred and emptied.
  607. irc_send (c, "ERROR :Closing Link: %s[%s] (%s)", c->nickname,
  608. c->hostname /* TODO host IP? */, reason);
  609. c->closing_link = true;
  610. client_unregister (c, reason);
  611. client_set_kill_timer (c);
  612. }
  613. static bool
  614. client_in_mask_list (const struct client *c, const struct str_vector *mask)
  615. {
  616. char *client = xstrdup_printf ("%s!%s@%s",
  617. c->nickname, c->username, c->hostname);
  618. bool result = false;
  619. for (size_t i = 0; i < mask->len; i++)
  620. if (!irc_fnmatch (client, mask->vector[i]))
  621. {
  622. result = true;
  623. break;
  624. }
  625. free (client);
  626. return result;
  627. }
  628. static void
  629. irc_initiate_quit (struct server_context *ctx)
  630. {
  631. print_status ("shutting down");
  632. for (struct client *iter = ctx->clients; iter; iter = iter->next)
  633. if (!iter->closing_link)
  634. irc_close_link (iter, "Shutting down");
  635. ssize_t i = poller_find_by_fd (&ctx->poller, ctx->listen_fd);
  636. if (soft_assert (i != -1))
  637. poller_remove_at_index (&ctx->poller, i);
  638. if (ctx->listen_fd != -1)
  639. xclose (ctx->listen_fd);
  640. ctx->listen_fd = -1;
  641. ctx->quitting = true;
  642. irc_try_finish_quit (ctx);
  643. }
  644. static char *
  645. client_get_ssl_cert_fingerprint (struct client *c)
  646. {
  647. if (!c->ssl)
  648. return NULL;
  649. X509 *peer_cert = SSL_get_peer_certificate (c->ssl);
  650. if (!peer_cert)
  651. return NULL;
  652. int cert_len = i2d_X509 (peer_cert, NULL);
  653. if (cert_len < 0)
  654. return NULL;
  655. unsigned char cert[cert_len], *p = cert;
  656. if (i2d_X509 (peer_cert, &p) < 0)
  657. return NULL;
  658. unsigned char hash[SHA_DIGEST_LENGTH];
  659. SHA1 (cert, cert_len, hash);
  660. struct str fingerprint;
  661. str_init (&fingerprint);
  662. str_append_printf (&fingerprint, "%02X", hash[0]);
  663. for (size_t i = 0; i < sizeof hash; i++)
  664. str_append_printf (&fingerprint, ":%02X", hash[i]);
  665. return str_steal (&fingerprint);
  666. }
  667. // --- Timers ------------------------------------------------------------------
  668. static void
  669. client_cancel_timers (struct client *c)
  670. {
  671. ssize_t i;
  672. struct poller_timers *timers = &c->ctx->poller.timers;
  673. while ((i = poller_timers_find_by_data (timers, c)) != -1)
  674. poller_timers_remove_at_index (timers, i);
  675. }
  676. static void
  677. client_set_timer (struct client *c, poller_timer_func fn, unsigned interval)
  678. {
  679. client_cancel_timers (c);
  680. poller_timers_add (&c->ctx->poller.timers, fn, c, interval * 1000);
  681. }
  682. static void
  683. on_irc_client_kill_timer (void *user_data)
  684. {
  685. struct client *c = user_data;
  686. hard_assert (!c->initialized || c->closing_link);
  687. client_kill (c, NULL);
  688. }
  689. static void
  690. client_set_kill_timer (struct client *c)
  691. {
  692. client_set_timer (c, on_irc_client_kill_timer, c->ctx->ping_interval);
  693. }
  694. static void
  695. on_irc_client_timeout_timer (void *user_data)
  696. {
  697. struct client *c = user_data;
  698. char *reason = xstrdup_printf
  699. ("Ping timeout: >%u seconds", c->ctx->ping_interval);
  700. irc_close_link (c, reason);
  701. free (reason);
  702. }
  703. static void
  704. on_irc_client_ping_timer (void *user_data)
  705. {
  706. struct client *c = user_data;
  707. hard_assert (!c->closing_link);
  708. irc_send (c, "PING :%s", c->ctx->server_name);
  709. client_set_timer (c, on_irc_client_timeout_timer, c->ctx->ping_interval);
  710. }
  711. static void
  712. client_set_ping_timer (struct client *c)
  713. {
  714. client_set_timer (c, on_irc_client_ping_timer, c->ctx->ping_interval);
  715. }
  716. // --- IRC command handling ----------------------------------------------------
  717. enum
  718. {
  719. IRC_RPL_WELCOME = 1,
  720. IRC_RPL_YOURHOST = 2,
  721. IRC_RPL_CREATED = 3,
  722. IRC_RPL_MYINFO = 4,
  723. IRC_RPL_UMODEIS = 221,
  724. IRC_RPL_LUSERCLIENT = 251,
  725. IRC_RPL_LUSEROP = 252,
  726. IRC_RPL_LUSERUNKNOWN = 253,
  727. IRC_RPL_LUSERCHANNELS = 254,
  728. IRC_RPL_LUSERME = 255,
  729. IRC_RPL_AWAY = 301,
  730. IRC_RPL_USERHOST = 302,
  731. IRC_RPL_ISON = 303,
  732. IRC_RPL_UNAWAY = 305,
  733. IRC_RPL_NOWAWAY = 306,
  734. IRC_RPL_WHOISUSER = 311,
  735. IRC_RPL_WHOISSERVER = 312,
  736. IRC_RPL_WHOISOPERATOR = 313,
  737. IRC_RPL_ENDOFWHO = 315,
  738. IRC_RPL_WHOISIDLE = 317,
  739. IRC_RPL_ENDOFWHOIS = 318,
  740. IRC_RPL_WHOISCHANNELS = 319,
  741. IRC_RPL_LIST = 322,
  742. IRC_RPL_LISTEND = 323,
  743. IRC_RPL_CHANNELMODEIS = 324,
  744. IRC_RPL_NOTOPIC = 331,
  745. IRC_RPL_TOPIC = 332,
  746. IRC_RPL_INVITELIST = 346,
  747. IRC_RPL_ENDOFINVITELIST = 347,
  748. IRC_RPL_EXCEPTLIST = 348,
  749. IRC_RPL_ENDOFEXCEPTLIST = 349,
  750. IRC_RPL_VERSION = 351,
  751. IRC_RPL_WHOREPLY = 352,
  752. IRC_RPL_NAMREPLY = 353,
  753. IRC_RPL_ENDOFNAMES = 366,
  754. IRC_RPL_BANLIST = 367,
  755. IRC_RPL_ENDOFBANLIST = 368,
  756. IRC_RPL_MOTD = 372,
  757. IRC_RPL_MOTDSTART = 375,
  758. IRC_RPL_ENDOFMOTD = 376,
  759. IRC_RPL_TIME = 391,
  760. IRC_ERR_NOSUCHNICK = 401,
  761. IRC_ERR_NOSUCHSERVER = 402,
  762. IRC_ERR_NOSUCHCHANNEL = 403,
  763. IRC_ERR_CANNOTSENDTOCHAN = 404,
  764. IRC_ERR_NOORIGIN = 409,
  765. IRC_ERR_NORECIPIENT = 411,
  766. IRC_ERR_NOTEXTTOSEND = 412,
  767. IRC_ERR_UNKNOWNCOMMAND = 421,
  768. IRC_ERR_NOMOTD = 422,
  769. IRC_ERR_NONICKNAMEGIVEN = 431,
  770. IRC_ERR_ERRONEOUSNICKNAME = 432,
  771. IRC_ERR_NICKNAMEINUSE = 433,
  772. IRC_ERR_USERNOTINCHANNEL = 441,
  773. IRC_ERR_NOTONCHANNEL = 442,
  774. IRC_ERR_SUMMONDISABLED = 445,
  775. IRC_ERR_USERSDISABLED = 446,
  776. IRC_ERR_NOTREGISTERED = 451,
  777. IRC_ERR_NEEDMOREPARAMS = 461,
  778. IRC_ERR_ALREADYREGISTERED = 462,
  779. IRC_ERR_CHANNELISFULL = 471,
  780. IRC_ERR_INVITEONLYCHAN = 473,
  781. IRC_ERR_BANNEDFROMCHAN = 474,
  782. IRC_ERR_BADCHANNELKEY = 475,
  783. IRC_ERR_BADCHANMASK = 476,
  784. IRC_ERR_NOPRIVILEGES = 481,
  785. IRC_ERR_CHANOPRIVSNEEDED = 482,
  786. IRC_ERR_UMODEUNKNOWNFLAG = 501,
  787. IRC_ERR_USERSDONTMATCH = 502
  788. };
  789. static const char *g_default_replies[] =
  790. {
  791. [IRC_RPL_WELCOME] = ":Welcome to the Internet Relay Network %s!%s@%s",
  792. [IRC_RPL_YOURHOST] = ":Your host is %s, running version %s",
  793. [IRC_RPL_CREATED] = ":This server was created %s",
  794. [IRC_RPL_MYINFO] = "%s %s %s %s",
  795. [IRC_RPL_UMODEIS] = "+%s",
  796. [IRC_RPL_LUSERCLIENT] = ":There are %d users and %d services on %d servers",
  797. [IRC_RPL_LUSEROP] = "%d :operator(s) online",
  798. [IRC_RPL_LUSERUNKNOWN] = "%d :unknown connection(s)",
  799. [IRC_RPL_LUSERCHANNELS] = "%d :channels formed",
  800. [IRC_RPL_LUSERME] = ":I have %d clients and %d servers",
  801. [IRC_RPL_AWAY] = "%s :%s",
  802. [IRC_RPL_USERHOST] = ":%s",
  803. [IRC_RPL_ISON] = ":%s",
  804. [IRC_RPL_UNAWAY] = ":You are no longer marked as being away",
  805. [IRC_RPL_NOWAWAY] = ":You have been marked as being away",
  806. [IRC_RPL_WHOISUSER] = "%s %s %s * :%s",
  807. [IRC_RPL_WHOISSERVER] = "%s %s :%s",
  808. [IRC_RPL_WHOISOPERATOR] = "%s :is an IRC operator",
  809. [IRC_RPL_ENDOFWHO] = "%s :End of WHO list",
  810. [IRC_RPL_WHOISIDLE] = "%s %d :seconds idle",
  811. [IRC_RPL_ENDOFWHOIS] = "%s :End of WHOIS list",
  812. [IRC_RPL_WHOISCHANNELS] = "%s :%s",
  813. [IRC_RPL_LIST] = "%s %d :%s",
  814. [IRC_RPL_LISTEND] = ":End of LIST",
  815. [IRC_RPL_CHANNELMODEIS] = "%s +%s",
  816. [IRC_RPL_NOTOPIC] = "%s :No topic is set",
  817. [IRC_RPL_TOPIC] = "%s :%s",
  818. [IRC_RPL_INVITELIST] = "%s %s",
  819. [IRC_RPL_ENDOFINVITELIST] = "%s :End of channel invite list",
  820. [IRC_RPL_EXCEPTLIST] = "%s %s",
  821. [IRC_RPL_ENDOFEXCEPTLIST] = "%s :End of channel exception list",
  822. [IRC_RPL_VERSION] = "%s.%d %s :%s",
  823. [IRC_RPL_WHOREPLY] = "%s %s %s %s %s %s :%d %s",
  824. [IRC_RPL_NAMREPLY] = "%c %s :%s",
  825. [IRC_RPL_ENDOFNAMES] = "%s :End of NAMES list",
  826. [IRC_RPL_BANLIST] = "%s %s",
  827. [IRC_RPL_ENDOFBANLIST] = "%s :End of channel ban list",
  828. [IRC_RPL_MOTD] = ":- %s",
  829. [IRC_RPL_MOTDSTART] = ":- %s Message of the day - ",
  830. [IRC_RPL_ENDOFMOTD] = ":End of MOTD command",
  831. [IRC_RPL_TIME] = "%s :%s",
  832. [IRC_ERR_NOSUCHNICK] = "%s :No such nick/channel",
  833. [IRC_ERR_NOSUCHSERVER] = "%s :No such server",
  834. [IRC_ERR_NOSUCHCHANNEL] = "%s :No such channel",
  835. [IRC_ERR_CANNOTSENDTOCHAN] = "%s :Cannot send to channel",
  836. [IRC_ERR_NOORIGIN] = ":No origin specified",
  837. [IRC_ERR_NORECIPIENT] = ":No recipient given (%s)",
  838. [IRC_ERR_NOTEXTTOSEND] = ":No text to send",
  839. [IRC_ERR_UNKNOWNCOMMAND] = "%s: Unknown command",
  840. [IRC_ERR_NOMOTD] = ":MOTD File is missing",
  841. [IRC_ERR_NONICKNAMEGIVEN] = ":No nickname given",
  842. [IRC_ERR_ERRONEOUSNICKNAME] = "%s :Erroneous nickname",
  843. [IRC_ERR_NICKNAMEINUSE] = "%s :Nickname is already in use",
  844. [IRC_ERR_USERNOTINCHANNEL] = "%s %s :They aren't on that channel",
  845. [IRC_ERR_NOTONCHANNEL] = "%s :You're not on that channel",
  846. [IRC_ERR_SUMMONDISABLED] = ":SUMMON has been disabled",
  847. [IRC_ERR_USERSDISABLED] = ":USERS has been disabled",
  848. [IRC_ERR_NOTREGISTERED] = ":You have not registered",
  849. [IRC_ERR_NEEDMOREPARAMS] = "%s :Not enough parameters",
  850. [IRC_ERR_ALREADYREGISTERED] = ":Unauthorized command (already registered)",
  851. [IRC_ERR_CHANNELISFULL] = "%s :Cannot join channel (+l)",
  852. [IRC_ERR_INVITEONLYCHAN] = "%s :Cannot join channel (+i)",
  853. [IRC_ERR_BANNEDFROMCHAN] = "%s :Cannot join channel (+b)",
  854. [IRC_ERR_BADCHANNELKEY] = "%s :Cannot join channel (+k)",
  855. [IRC_ERR_BADCHANMASK] = "%s :Bad Channel Mask",
  856. [IRC_ERR_NOPRIVILEGES] = ":Permission Denied- You're not an IRC operator",
  857. [IRC_ERR_CHANOPRIVSNEEDED] = "%s :You're not channel operator",
  858. [IRC_ERR_UMODEUNKNOWNFLAG] = ":Unknown MODE flag",
  859. [IRC_ERR_USERSDONTMATCH] = ":Cannot change mode for other users",
  860. };
  861. // XXX: this way we cannot typecheck the arguments, so we must be careful
  862. static void
  863. irc_send_reply (struct client *c, int id, ...)
  864. {
  865. struct str tmp;
  866. str_init (&tmp);
  867. va_list ap;
  868. va_start (ap, id);
  869. str_append_printf (&tmp, ":%s %03d %s ",
  870. c->ctx->server_name, id, c->nickname ? c->nickname : "");
  871. str_append_vprintf (&tmp,
  872. irc_get_text (c->ctx, id, g_default_replies[id]), ap);
  873. va_end (ap);
  874. irc_send_str (c, &tmp);
  875. str_free (&tmp);
  876. }
  877. #define RETURN_WITH_REPLY(c, ...) \
  878. BLOCK_START \
  879. irc_send_reply ((c), __VA_ARGS__); \
  880. return; \
  881. BLOCK_END
  882. static void
  883. irc_send_motd (struct client *c)
  884. {
  885. struct server_context *ctx = c->ctx;
  886. if (!ctx->motd.len)
  887. RETURN_WITH_REPLY (c, IRC_ERR_NOMOTD);
  888. irc_send_reply (c, IRC_RPL_MOTDSTART, ctx->server_name);
  889. for (size_t i = 0; i < ctx->motd.len; i++)
  890. irc_send_reply (c, IRC_RPL_MOTD, ctx->motd.vector[i]);
  891. irc_send_reply (c, IRC_RPL_ENDOFMOTD);
  892. }
  893. static void
  894. irc_send_lusers (struct client *c)
  895. {
  896. int n_users = 0, n_services = 0, n_opers = 0, n_unknown = 0;
  897. for (struct client *link = c->ctx->clients; link; link = link->next)
  898. {
  899. if (link->registered)
  900. n_users++;
  901. else
  902. n_unknown++;
  903. if (link->mode & IRC_USER_MODE_OPERATOR)
  904. n_opers++;
  905. }
  906. int n_channels = 0;
  907. struct str_map_iter iter;
  908. str_map_iter_init (&iter, &c->ctx->channels);
  909. struct channel *chan;
  910. while ((chan = str_map_iter_next (&iter)))
  911. if (!(chan->modes & IRC_CHAN_MODE_SECRET)
  912. || channel_get_user (chan, c))
  913. n_channels++;
  914. irc_send_reply (c, IRC_RPL_LUSERCLIENT,
  915. n_users, n_services, 1 /* servers total */);
  916. if (n_opers)
  917. irc_send_reply (c, IRC_RPL_LUSEROP, n_opers);
  918. if (n_unknown)
  919. irc_send_reply (c, IRC_RPL_LUSERUNKNOWN, n_unknown);
  920. if (n_channels)
  921. irc_send_reply (c, IRC_RPL_LUSERCHANNELS, n_channels);
  922. irc_send_reply (c, IRC_RPL_LUSERME,
  923. n_users + n_services + n_unknown, 0 /* peer servers */);
  924. }
  925. static bool
  926. irc_is_this_me (struct server_context *ctx, const char *target)
  927. {
  928. // Target servers can also be matched by their users
  929. return !irc_fnmatch (target, ctx->server_name)
  930. || str_map_find (&ctx->users, target);
  931. }
  932. static void
  933. irc_try_finish_registration (struct client *c)
  934. {
  935. struct server_context *ctx = c->ctx;
  936. if (!c->nickname || !c->username || !c->realname)
  937. return;
  938. c->registered = true;
  939. irc_send_reply (c, IRC_RPL_WELCOME, c->nickname, c->username, c->hostname);
  940. irc_send_reply (c, IRC_RPL_YOURHOST, ctx->server_name, PROGRAM_VERSION);
  941. // The purpose of this message eludes me
  942. irc_send_reply (c, IRC_RPL_CREATED, __DATE__);
  943. irc_send_reply (c, IRC_RPL_MYINFO, ctx->server_name, PROGRAM_VERSION,
  944. IRC_SUPPORTED_USER_MODES, IRC_SUPPORTED_CHAN_MODES);
  945. irc_send_lusers (c);
  946. irc_send_motd (c);
  947. char *mode = client_get_mode (c);
  948. if (*mode)
  949. irc_send (c, ":%s MODE %s :+%s", c->nickname, c->nickname, mode);
  950. free (mode);
  951. hard_assert (c->ssl_cert_fingerprint == NULL);
  952. if ((c->ssl_cert_fingerprint = client_get_ssl_cert_fingerprint (c)))
  953. irc_send (c, ":%s NOTICE %s :"
  954. "Your SSL client certificate fingerprint is %s",
  955. ctx->server_name, c->nickname, c->ssl_cert_fingerprint);
  956. }
  957. static void
  958. irc_handle_pass (const struct irc_message *msg, struct client *c)
  959. {
  960. if (c->registered)
  961. irc_send_reply (c, IRC_ERR_ALREADYREGISTERED);
  962. else if (msg->params.len < 1)
  963. irc_send_reply (c, IRC_ERR_NEEDMOREPARAMS, msg->command);
  964. // We have SSL client certificates for this purpose; ignoring
  965. }
  966. static void
  967. irc_handle_nick (const struct irc_message *msg, struct client *c)
  968. {
  969. struct server_context *ctx = c->ctx;
  970. if (msg->params.len < 1)
  971. RETURN_WITH_REPLY (c, IRC_ERR_NONICKNAMEGIVEN);
  972. const char *nickname = msg->params.vector[0];
  973. if (irc_validate_nickname (nickname) != VALIDATION_OK)
  974. RETURN_WITH_REPLY (c, IRC_ERR_ERRONEOUSNICKNAME, nickname);
  975. struct client *client = str_map_find (&ctx->users, nickname);
  976. if (client && client != c)
  977. RETURN_WITH_REPLY (c, IRC_ERR_NICKNAMEINUSE, nickname);
  978. if (c->registered)
  979. {
  980. char *message = xstrdup_printf (":%s!%s@%s NICK :%s",
  981. c->nickname, c->username, c->hostname, nickname);
  982. client_send_to_roommates (c, message);
  983. free (message);
  984. }
  985. // Release the old nickname and allocate a new one
  986. if (c->nickname)
  987. {
  988. str_map_set (&ctx->users, c->nickname, NULL);
  989. free (c->nickname);
  990. }
  991. c->nickname = xstrdup (nickname);
  992. str_map_set (&ctx->users, nickname, c);
  993. if (!c->registered)
  994. irc_try_finish_registration (c);
  995. }
  996. static void
  997. irc_handle_user (const struct irc_message *msg, struct client *c)
  998. {
  999. if (c->registered)
  1000. RETURN_WITH_REPLY (c, IRC_ERR_ALREADYREGISTERED);
  1001. if (msg->params.len < 4)
  1002. RETURN_WITH_REPLY (c, IRC_ERR_NEEDMOREPARAMS, msg->command);
  1003. const char *username = msg->params.vector[0];
  1004. const char *mode = msg->params.vector[1];
  1005. const char *realname = msg->params.vector[3];
  1006. // Unfortunately the protocol doesn't give us any means of rejecting it
  1007. if (!irc_is_valid_user (username))
  1008. username = "xxx";
  1009. free (c->username);
  1010. c->username = xstrdup (username);
  1011. free (c->realname);
  1012. c->realname = xstrdup (realname);
  1013. unsigned long m;
  1014. if (xstrtoul (&m, mode, 10))
  1015. {
  1016. if (m & 4) c->mode |= IRC_USER_MODE_RX_WALLOPS;
  1017. if (m & 8) c->mode |= IRC_USER_MODE_INVISIBLE;
  1018. }
  1019. irc_try_finish_registration (c);
  1020. }
  1021. static void
  1022. irc_handle_userhost (const struct irc_message *msg, struct client *c)
  1023. {
  1024. if (msg->params.len < 1)
  1025. RETURN_WITH_REPLY (c, IRC_ERR_NEEDMOREPARAMS, msg->command);
  1026. struct str reply;
  1027. str_init (&reply);
  1028. for (size_t i = 0; i < 5 && i < msg->params.len; i++)
  1029. {
  1030. const char *nick = msg->params.vector[i];
  1031. struct client *target = str_map_find (&c->ctx->users, nick);
  1032. if (!target)
  1033. continue;
  1034. if (i)
  1035. str_append_c (&reply, ' ');
  1036. str_append (&reply, nick);
  1037. if (target->mode & IRC_USER_MODE_OPERATOR)
  1038. str_append_c (&reply, '*');
  1039. str_append_printf (&reply, "=%c%s@%s",
  1040. target->away_message ? '-' : '+',
  1041. target->username, target->hostname);
  1042. }
  1043. irc_send_reply (c, IRC_RPL_USERHOST, reply.str);
  1044. str_free (&reply);
  1045. }
  1046. static void
  1047. irc_handle_lusers (const struct irc_message *msg, struct client *c)
  1048. {
  1049. if (msg->params.len > 1 && !irc_is_this_me (c->ctx, msg->params.vector[1]))
  1050. irc_send_reply (c, IRC_ERR_NOSUCHSERVER, msg->params.vector[1]);
  1051. else
  1052. irc_send_lusers (c);
  1053. }
  1054. static void
  1055. irc_handle_motd (const struct irc_message *msg, struct client *c)
  1056. {
  1057. if (msg->params.len > 0 && !irc_is_this_me (c->ctx, msg->params.vector[0]))
  1058. irc_send_reply (c, IRC_ERR_NOSUCHSERVER, msg->params.vector[0]);
  1059. else
  1060. irc_send_motd (c);
  1061. }
  1062. static void
  1063. irc_handle_ping (const struct irc_message *msg, struct client *c)
  1064. {
  1065. // XXX: the RFC is pretty incomprehensible about the exact usage
  1066. if (msg->params.len > 1 && !irc_is_this_me (c->ctx, msg->params.vector[1]))
  1067. irc_send_reply (c, IRC_ERR_NOSUCHSERVER, msg->params.vector[1]);
  1068. else if (msg->params.len < 1)
  1069. irc_send_reply (c, IRC_ERR_NOORIGIN);
  1070. else
  1071. irc_send (c, ":%s PONG :%s",
  1072. c->ctx->server_name, msg->params.vector[0]);
  1073. }
  1074. static void
  1075. irc_handle_pong (const struct irc_message *msg, struct client *c)
  1076. {
  1077. // We are the only server, so we don't have to care too much
  1078. if (msg->params.len < 1)
  1079. irc_send_reply (c, IRC_ERR_NOORIGIN);
  1080. else
  1081. // Set a new timer to send another PING
  1082. client_set_ping_timer (c);
  1083. }
  1084. static void
  1085. irc_handle_quit (const struct irc_message *msg, struct client *c)
  1086. {
  1087. char *reason = xstrdup_printf ("Quit: %s",
  1088. msg->params.len > 0 ? msg->params.vector[0] : c->nickname);
  1089. irc_close_link (c, reason);
  1090. free (reason);
  1091. }
  1092. static void
  1093. irc_handle_time (const struct irc_message *msg, struct client *c)
  1094. {
  1095. if (msg->params.len > 0 && !irc_is_this_me (c->ctx, msg->params.vector[0]))
  1096. RETURN_WITH_REPLY (c, IRC_ERR_NOSUCHSERVER, msg->params.vector[0]);
  1097. char buf[32];
  1098. time_t now = time (NULL);
  1099. struct tm tm;
  1100. strftime (buf, sizeof buf, "%a %b %d %Y %T", localtime_r (&now, &tm));
  1101. irc_send_reply (c, IRC_RPL_TIME, c->ctx->server_name, buf);
  1102. }
  1103. static void
  1104. irc_handle_version (const struct irc_message *msg, struct client *c)
  1105. {
  1106. if (msg->params.len > 0 && !irc_is_this_me (c->ctx, msg->params.vector[0]))
  1107. irc_send_reply (c, IRC_ERR_NOSUCHSERVER, msg->params.vector[0]);
  1108. else
  1109. irc_send_reply (c, IRC_RPL_VERSION, PROGRAM_VERSION, g_debug_mode,
  1110. c->ctx->server_name, PROGRAM_NAME " " PROGRAM_VERSION);
  1111. }
  1112. static void
  1113. irc_channel_multicast (struct channel *chan, const char *message,
  1114. struct client *except)
  1115. {
  1116. for (struct channel_user *iter = chan->users; iter; iter = iter->next)
  1117. {
  1118. struct client *c = str_map_find (&chan->ctx->users, iter->nickname);
  1119. if (c != except)
  1120. irc_send (c, "%s", message);
  1121. }
  1122. }
  1123. static void
  1124. irc_send_channel_list (struct client *c, const char *channel_name,
  1125. const struct str_vector *list, int reply, int end_reply)
  1126. {
  1127. for (size_t i = 0; i < list->len; i++)
  1128. irc_send_reply (c, reply, channel_name, list->vector[i]);
  1129. irc_send_reply (c, end_reply);
  1130. }
  1131. static bool
  1132. irc_maybe_send_channel_list (struct client *c, struct channel *chan,
  1133. const char *mode_string)
  1134. {
  1135. if (*mode_string == '+')
  1136. mode_string++;
  1137. if (!strcmp (mode_string, "b"))
  1138. irc_send_channel_list (c, chan->name, &chan->ban_list,
  1139. IRC_RPL_BANLIST, IRC_RPL_ENDOFBANLIST);
  1140. else if (!strcmp (mode_string, "e"))
  1141. irc_send_channel_list (c, chan->name, &chan->exception_list,
  1142. IRC_RPL_EXCEPTLIST, IRC_RPL_ENDOFEXCEPTLIST);
  1143. else if (!strcmp (mode_string, "I"))
  1144. irc_send_channel_list (c, chan->name, &chan->invite_list,
  1145. IRC_RPL_INVITELIST, IRC_RPL_ENDOFINVITELIST);
  1146. else
  1147. return false;
  1148. return true;
  1149. }
  1150. static void
  1151. irc_modify_mode (unsigned *mask, unsigned mode, bool add)
  1152. {
  1153. if (add)
  1154. *mask |= mode;
  1155. else
  1156. *mask &= ~mode;
  1157. }
  1158. static void
  1159. irc_update_user_mode (struct client *c, unsigned new_mode)
  1160. {
  1161. unsigned old_mode = c->mode;
  1162. c->mode = new_mode;
  1163. unsigned added = new_mode & ~old_mode;
  1164. unsigned removed = old_mode & ~new_mode;
  1165. struct str diff;
  1166. str_init (&diff);
  1167. if (added)
  1168. {
  1169. str_append_c (&diff, '+');
  1170. client_mode_to_str (added, &diff);
  1171. }
  1172. if (removed)
  1173. {
  1174. str_append_c (&diff, '-');
  1175. client_mode_to_str (removed, &diff);
  1176. }
  1177. if (diff.len)
  1178. irc_send (c, ":%s MODE %s :%s",
  1179. c->nickname, c->nickname, diff.str);
  1180. str_free (&diff);
  1181. }
  1182. static void
  1183. irc_handle_user_mode_change (struct client *c, const char *mode_string)
  1184. {
  1185. unsigned new_mode = c->mode;
  1186. bool adding = true;
  1187. while (*mode_string)
  1188. switch (*mode_string++)
  1189. {
  1190. case '+': adding = true; break;
  1191. case '-': adding = false; break;
  1192. case 'a':
  1193. // Ignore, the client should use AWAY
  1194. break;
  1195. case 'i':
  1196. irc_modify_mode (&new_mode, IRC_USER_MODE_INVISIBLE, adding);
  1197. break;
  1198. case 'w':
  1199. irc_modify_mode (&new_mode, IRC_USER_MODE_RX_WALLOPS, adding);
  1200. break;
  1201. case 'r':
  1202. if (adding)
  1203. irc_modify_mode (&new_mode, IRC_USER_MODE_RESTRICTED, true);
  1204. break;
  1205. case 'o':
  1206. if (!adding)
  1207. irc_modify_mode (&new_mode, IRC_USER_MODE_OPERATOR, false);
  1208. else if (c->ssl_cert_fingerprint
  1209. && str_map_find (&c->ctx->operators, c->ssl_cert_fingerprint))
  1210. irc_modify_mode (&new_mode, IRC_USER_MODE_OPERATOR, true);
  1211. else
  1212. irc_send (c, ":%s NOTICE %s :Either you're not using an SSL"
  1213. " client certificate, or the fingerprint doesn't match",
  1214. c->ctx->server_name, c->nickname);
  1215. break;
  1216. case 's':
  1217. irc_modify_mode (&new_mode, IRC_USER_MODE_RX_SERVER_NOTICES, adding);
  1218. break;
  1219. default:
  1220. RETURN_WITH_REPLY (c, IRC_ERR_UMODEUNKNOWNFLAG);
  1221. }
  1222. irc_update_user_mode (c, new_mode);
  1223. }
  1224. static void
  1225. irc_handle_mode (const struct irc_message *msg, struct client *c)
  1226. {
  1227. if (msg->params.len < 1)
  1228. RETURN_WITH_REPLY (c, IRC_ERR_NEEDMOREPARAMS, msg->command);
  1229. const char *target = msg->params.vector[0];
  1230. struct client *client = str_map_find (&c->ctx->users, target);
  1231. if (client)
  1232. {
  1233. if (irc_strcmp (target, c->nickname))
  1234. RETURN_WITH_REPLY (c, IRC_ERR_USERSDONTMATCH);
  1235. if (msg->params.len < 2)
  1236. {
  1237. char *mode = client_get_mode (client);
  1238. irc_send_reply (c, IRC_RPL_UMODEIS, mode);
  1239. free (mode);
  1240. }
  1241. else
  1242. irc_handle_user_mode_change (c, msg->params.vector[1]);
  1243. return;
  1244. }
  1245. struct channel *chan = str_map_find (&c->ctx->channels, target);
  1246. if (chan)
  1247. {
  1248. if (msg->params.len < 2)
  1249. {
  1250. char *mode = channel_get_mode (chan, channel_get_user (chan, c));
  1251. irc_send_reply (c, IRC_RPL_CHANNELMODEIS, target, mode);
  1252. free (mode);
  1253. return;
  1254. }
  1255. if (msg->params.len < 3
  1256. && irc_maybe_send_channel_list (c, chan, msg->params.vector[1]))
  1257. return;
  1258. // TODO: mode modification
  1259. return;
  1260. }
  1261. irc_send_reply (c, IRC_ERR_NOSUCHNICK, target);
  1262. }
  1263. static void
  1264. irc_handle_user_message (const struct irc_message *msg, struct client *c,
  1265. const char *command, bool allow_away_reply)
  1266. {
  1267. if (msg->params.len < 1)
  1268. RETURN_WITH_REPLY (c, IRC_ERR_NORECIPIENT, msg->command);
  1269. if (msg->params.len < 2 || !*msg->params.vector[1])
  1270. RETURN_WITH_REPLY (c, IRC_ERR_NOTEXTTOSEND);
  1271. const char *target = msg->params.vector[0];
  1272. const char *text = msg->params.vector[1];
  1273. struct client *client = str_map_find (&c->ctx->users, target);
  1274. if (client)
  1275. {
  1276. irc_send (client, ":%s!%s@%s %s %s :%s",
  1277. c->nickname, c->username, c->hostname, command, target, text);
  1278. if (allow_away_reply && client->away_message)
  1279. irc_send_reply (c, IRC_RPL_AWAY, target, client->away_message);
  1280. return;
  1281. }
  1282. struct channel *chan = str_map_find (&c->ctx->channels, target);
  1283. if (chan)
  1284. {
  1285. struct channel_user *user = channel_get_user (chan, c);
  1286. if ((chan->modes & IRC_CHAN_MODE_NO_OUTSIDE_MSGS) && !user)
  1287. RETURN_WITH_REPLY (c, IRC_ERR_CANNOTSENDTOCHAN, target);
  1288. if ((chan->modes & IRC_CHAN_MODE_MODERATED) && (!user ||
  1289. !(user->modes & (IRC_CHAN_MODE_VOICE | IRC_CHAN_MODE_OPERATOR))))
  1290. RETURN_WITH_REPLY (c, IRC_ERR_CANNOTSENDTOCHAN, target);
  1291. if (client_in_mask_list (c, &chan->ban_list)
  1292. && !client_in_mask_list (c, &chan->exception_list))
  1293. RETURN_WITH_REPLY (c, IRC_ERR_CANNOTSENDTOCHAN, target);
  1294. char *message = xstrdup_printf (":%s!%s@%s %s %s :%s",
  1295. c->nickname, c->username, c->hostname, command, target, text);
  1296. irc_channel_multicast (chan, message, c);
  1297. free (message);
  1298. return;
  1299. }
  1300. irc_send_reply (c, IRC_ERR_NOSUCHNICK, target);
  1301. }
  1302. static void
  1303. irc_handle_privmsg (const struct irc_message *msg, struct client *c)
  1304. {
  1305. irc_handle_user_message (msg, c, "PRIVMSG", true);
  1306. // Let's not care too much about success or failure
  1307. c->last_active = time (NULL);
  1308. }
  1309. static void
  1310. irc_handle_notice (const struct irc_message *msg, struct client *c)
  1311. {
  1312. irc_handle_user_message (msg, c, "NOTICE", false);
  1313. }
  1314. static void
  1315. irc_send_rpl_list (struct client *c, const struct channel *chan)
  1316. {
  1317. int visible = 0;
  1318. for (struct channel_user *user = chan->users;
  1319. user; user = user->next)
  1320. visible++;
  1321. irc_send_reply (c, IRC_RPL_LIST, chan->name, visible, chan->topic);
  1322. }
  1323. static void
  1324. irc_handle_list (const struct irc_message *msg, struct client *c)
  1325. {
  1326. if (msg->params.len > 1 && !irc_is_this_me (c->ctx, msg->params.vector[1]))
  1327. RETURN_WITH_REPLY (c, IRC_ERR_NOSUCHSERVER, msg->params.vector[1]);
  1328. struct channel *chan;
  1329. if (msg->params.len == 0)
  1330. {
  1331. struct str_map_iter iter;
  1332. str_map_iter_init (&iter, &c->ctx->channels);
  1333. while ((chan = str_map_iter_next (&iter)))
  1334. if (!(chan->modes & (IRC_CHAN_MODE_PRIVATE | IRC_CHAN_MODE_SECRET))
  1335. || channel_get_user (chan, c))
  1336. irc_send_rpl_list (c, chan);
  1337. }
  1338. else
  1339. {
  1340. struct str_vector channels;
  1341. str_vector_init (&channels);
  1342. split_str_ignore_empty (msg->params.vector[0], ',', &channels);
  1343. for (size_t i = 0; i < channels.len; i++)
  1344. if ((chan = str_map_find (&c->ctx->channels, channels.vector[i]))
  1345. && (!(chan->modes & IRC_CHAN_MODE_SECRET)
  1346. || channel_get_user (chan, c)))
  1347. irc_send_rpl_list (c, chan);
  1348. str_vector_free (&channels);
  1349. }
  1350. irc_send_reply (c, IRC_RPL_LISTEND);
  1351. }
  1352. static void
  1353. irc_send_rpl_namreply (struct client *c, const struct channel *chan)
  1354. {
  1355. struct str_vector nicks;
  1356. str_vector_init (&nicks);
  1357. char type = '=';
  1358. if (chan->modes & IRC_CHAN_MODE_SECRET)
  1359. type = '@';
  1360. else if (chan->modes & IRC_CHAN_MODE_PRIVATE)
  1361. type = '*';
  1362. bool on_channel = channel_get_user (chan, c);
  1363. for (struct channel_user *iter = chan->users; iter; iter = iter->next)
  1364. {
  1365. struct client *target = str_map_find (&c->ctx->users, iter->nickname);
  1366. if (!on_channel && (target->mode & IRC_USER_MODE_INVISIBLE))
  1367. continue;
  1368. struct str result;
  1369. str_init (&result);
  1370. if (iter->modes & IRC_CHAN_MODE_OPERATOR)
  1371. str_append_c (&result, '@');
  1372. else if (iter->modes & IRC_CHAN_MODE_VOICE)
  1373. str_append_c (&result, '+');
  1374. str_append (&result, target->nickname);
  1375. str_vector_add_owned (&nicks, str_steal (&result));
  1376. }
  1377. if (nicks.len)
  1378. {
  1379. char *reply = join_str_vector (&nicks, ' ');
  1380. irc_send_reply (c, IRC_RPL_NAMREPLY, type, chan->name, reply);
  1381. free (reply);
  1382. }
  1383. str_vector_free (&nicks);
  1384. }
  1385. static void
  1386. irc_handle_names (const struct irc_message *msg, struct client *c)
  1387. {
  1388. if (msg->params.len > 1 && !irc_is_this_me (c->ctx, msg->params.vector[1]))
  1389. RETURN_WITH_REPLY (c, IRC_ERR_NOSUCHSERVER, msg->params.vector[1]);
  1390. struct channel *chan;
  1391. if (msg->params.len == 0)
  1392. {
  1393. struct str_map_iter iter;
  1394. str_map_iter_init (&iter, &c->ctx->channels);
  1395. while ((chan = str_map_iter_next (&iter)))
  1396. if (!(chan->modes & (IRC_CHAN_MODE_PRIVATE | IRC_CHAN_MODE_SECRET))
  1397. || channel_get_user (chan, c))
  1398. irc_send_rpl_namreply (c, chan);
  1399. // TODO
  1400. // If no <channel> parameter is given, a list of all channels and their
  1401. // occupants is returned. At the end of this list, a list of users who
  1402. // are visible but either not on any channel or not on a visible channel
  1403. // are listed as being on `channel' "*".
  1404. irc_send_reply (c, IRC_RPL_ENDOFNAMES, "*");
  1405. }
  1406. else
  1407. {
  1408. struct str_vector channels;
  1409. str_vector_init (&channels);
  1410. split_str_ignore_empty (msg->params.vector[0], ',', &channels);
  1411. for (size_t i = 0; i < channels.len; i++)
  1412. if ((chan = str_map_find (&c->ctx->channels, channels.vector[i]))
  1413. && (!(chan->modes & IRC_CHAN_MODE_SECRET)
  1414. || channel_get_user (chan, c)))
  1415. {
  1416. irc_send_rpl_namreply (c, chan);
  1417. irc_send_reply (c, IRC_RPL_ENDOFNAMES, channels.vector[i]);
  1418. }
  1419. str_vector_free (&channels);
  1420. }
  1421. }
  1422. static void
  1423. irc_send_rpl_whoreply (struct client *c, const struct channel *chan,
  1424. const struct client *target)
  1425. {
  1426. struct str chars;
  1427. str_init (&chars);
  1428. str_append_c (&chars, target->away_message ? 'G' : 'H');
  1429. if (target->mode & IRC_USER_MODE_OPERATOR)
  1430. str_append_c (&chars, '*');
  1431. struct channel_user *user;
  1432. if (chan && (user = channel_get_user (chan, target)))
  1433. {
  1434. if (user->modes & IRC_CHAN_MODE_OPERATOR)
  1435. str_append_c (&chars, '@');
  1436. else if (user->modes & IRC_CHAN_MODE_VOICE)
  1437. str_append_c (&chars, '+');
  1438. }
  1439. irc_send_reply (c, IRC_RPL_WHOREPLY, chan ? chan->name : "*",
  1440. target->username, target->hostname, target->ctx->server_name,
  1441. target->nickname, chars.str, 0 /* hop count */, target->realname);
  1442. str_free (&chars);
  1443. }
  1444. static void
  1445. irc_match_send_rpl_whoreply (struct client *c, struct client *target,
  1446. const char *mask)
  1447. {
  1448. bool is_roommate = false;
  1449. struct str_map_iter iter;
  1450. str_map_iter_init (&iter, &c->ctx->channels);
  1451. struct channel *chan;
  1452. while ((chan = str_map_iter_next (&iter)))
  1453. if (channel_get_user (chan, target) && channel_get_user (chan, c))
  1454. {
  1455. is_roommate = true;
  1456. break;
  1457. }
  1458. if ((target->mode & IRC_USER_MODE_INVISIBLE) && !is_roommate)
  1459. return;
  1460. if (irc_fnmatch (mask, target->hostname)
  1461. && irc_fnmatch (mask, target->nickname)
  1462. && irc_fnmatch (mask, target->realname)
  1463. && irc_fnmatch (mask, c->ctx->server_name))
  1464. return;
  1465. // Try to find a channel they're on that's visible to us
  1466. struct channel *user_chan = NULL;
  1467. str_map_iter_init (&iter, &c->ctx->channels);
  1468. while ((chan = str_map_iter_next (&iter)))
  1469. if (channel_get_user (chan, target)
  1470. && (!(chan->modes & (IRC_CHAN_MODE_PRIVATE | IRC_CHAN_MODE_SECRET))
  1471. || channel_get_user (chan, c)))
  1472. {
  1473. user_chan = chan;
  1474. break;
  1475. }
  1476. irc_send_rpl_whoreply (c, user_chan, target);
  1477. }
  1478. static void
  1479. irc_handle_who (const struct irc_message *msg, struct client *c)
  1480. {
  1481. bool only_ops = msg->params.len > 1 && !strcmp (msg->params.vector[1], "o");
  1482. const char *shown_mask = msg->params.vector[0], *used_mask;
  1483. if (!shown_mask)
  1484. used_mask = shown_mask = "*";
  1485. else if (!strcmp (shown_mask, "0"))
  1486. used_mask = "*";
  1487. else
  1488. used_mask = shown_mask;
  1489. struct channel *chan;
  1490. if ((chan = str_map_find (&c->ctx->channels, used_mask)))
  1491. {
  1492. bool on_chan = !!channel_get_user (chan, c);
  1493. if (on_chan || !(chan->modes & IRC_CHAN_MODE_SECRET))
  1494. for (struct channel_user *iter = chan->users;
  1495. iter; iter = iter->next)
  1496. {
  1497. struct client *target =
  1498. str_map_find (&c->ctx->users, iter->nickname);
  1499. if ((on_chan || !(target->mode & IRC_USER_MODE_INVISIBLE))
  1500. && (!only_ops || (target->mode & IRC_USER_MODE_OPERATOR)))
  1501. irc_send_rpl_whoreply (c, chan, target);
  1502. }
  1503. }
  1504. else
  1505. {
  1506. struct str_map_iter iter;
  1507. str_map_iter_init (&iter, &c->ctx->users);
  1508. struct client *target;
  1509. while ((target = str_map_iter_next (&iter)))
  1510. if (!only_ops || (target->mode & IRC_USER_MODE_OPERATOR))
  1511. irc_match_send_rpl_whoreply (c, target, used_mask);
  1512. }
  1513. irc_send_reply (c, IRC_RPL_ENDOFWHO, shown_mask);
  1514. }
  1515. static void
  1516. irc_send_whois_reply (struct client *c, const struct client *target)
  1517. {
  1518. const char *nick = target->nickname;
  1519. irc_send_reply (c, IRC_RPL_WHOISUSER, nick, target->username,
  1520. target->hostname, target->realname);
  1521. irc_send_reply (c, IRC_RPL_WHOISSERVER, nick, target->ctx->server_name,
  1522. str_map_find (&c->ctx->config, "server_info"));
  1523. if (target->mode & IRC_USER_MODE_OPERATOR)
  1524. irc_send_reply (c, IRC_RPL_WHOISOPERATOR, nick);
  1525. irc_send_reply (c, IRC_RPL_WHOISIDLE, nick,
  1526. (int) (time (NULL) - target->last_active));
  1527. struct str_map_iter iter;
  1528. str_map_iter_init (&iter, &c->ctx->channels);
  1529. struct channel *chan;
  1530. struct channel_user *channel_user;
  1531. while ((chan = str_map_iter_next (&iter)))
  1532. if ((channel_user = channel_get_user (chan, target))
  1533. && (!(chan->modes & (IRC_CHAN_MODE_PRIVATE | IRC_CHAN_MODE_SECRET))
  1534. || channel_get_user (chan, c)))
  1535. {
  1536. struct str item;
  1537. str_init (&item);
  1538. if (channel_user->modes & IRC_CHAN_MODE_OPERATOR)
  1539. str_append_c (&item, '@');
  1540. else if (channel_user->modes & IRC_CHAN_MODE_VOICE)
  1541. str_append_c (&item, '+');
  1542. str_append (&item, chan->name);
  1543. str_append_c (&item, ' ');
  1544. // TODO: try to merge the results into as few messages as possible
  1545. irc_send_reply (c, IRC_RPL_WHOISCHANNELS, nick, item.str);
  1546. str_free (&item);
  1547. }
  1548. irc_send_reply (c, IRC_RPL_ENDOFWHOIS, nick);
  1549. }
  1550. static void
  1551. irc_handle_whois (const struct irc_message *msg, struct client *c)
  1552. {
  1553. if (msg->params.len < 1)
  1554. RETURN_WITH_REPLY (c, IRC_ERR_NEEDMOREPARAMS, msg->command);
  1555. if (msg->params.len > 1 && !irc_is_this_me (c->ctx, msg->params.vector[0]))
  1556. RETURN_WITH_REPLY (c, IRC_ERR_NOSUCHSERVER, msg->params.vector[0]);
  1557. struct str_vector masks;
  1558. str_vector_init (&masks);
  1559. const char *masks_str = msg->params.vector[msg->params.len > 1];
  1560. split_str_ignore_empty (masks_str, ',', &masks);
  1561. for (size_t i = 0; i < masks.len; i++)
  1562. {
  1563. const char *mask = masks.vector[i];
  1564. struct client *target;
  1565. if (!strpbrk (mask, "*?"))
  1566. {
  1567. if (!(target = str_map_find (&c->ctx->users, mask)))
  1568. irc_send_reply (c, IRC_ERR_NOSUCHNICK, mask);
  1569. else
  1570. irc_send_whois_reply (c, target);
  1571. }
  1572. else
  1573. {
  1574. struct str_map_iter iter;
  1575. str_map_iter_init (&iter, &c->ctx->users);
  1576. bool found = false;
  1577. while ((target = str_map_iter_next (&iter))
  1578. && !irc_fnmatch (mask, target->nickname))
  1579. {
  1580. irc_send_whois_reply (c, target);
  1581. found = true;
  1582. }
  1583. if (!found)
  1584. irc_send_reply (c, IRC_ERR_NOSUCHNICK, mask);
  1585. }
  1586. }
  1587. str_vector_free (&masks);
  1588. }
  1589. static void
  1590. irc_send_rpl_topic (struct client *c, struct channel *chan)
  1591. {
  1592. if (!*chan->topic)
  1593. irc_send_reply (c, IRC_RPL_NOTOPIC, chan->name);
  1594. else
  1595. irc_send_reply (c, IRC_RPL_TOPIC, chan->name, chan->topic);
  1596. }
  1597. static void
  1598. irc_handle_topic (const struct irc_message *msg, struct client *c)
  1599. {
  1600. if (msg->params.len < 1)
  1601. RETURN_WITH_REPLY (c, IRC_ERR_NEEDMOREPARAMS, msg->command);
  1602. const char *target = msg->params.vector[0];
  1603. struct channel *chan = str_map_find (&c->ctx->channels, target);
  1604. if (!chan)
  1605. RETURN_WITH_REPLY (c, IRC_ERR_NOSUCHCHANNEL, target);
  1606. if (msg->params.len < 2)
  1607. {
  1608. irc_send_rpl_topic (c, chan);
  1609. return;
  1610. }
  1611. struct channel_user *user = channel_get_user (chan, c);
  1612. if (!user)
  1613. RETURN_WITH_REPLY (c, IRC_ERR_NOTONCHANNEL, target);
  1614. if ((chan->modes & IRC_CHAN_MODE_PROTECTED_TOPIC)
  1615. && !(user->modes & IRC_CHAN_MODE_OPERATOR))
  1616. RETURN_WITH_REPLY (c, IRC_ERR_CHANOPRIVSNEEDED, target);
  1617. free (chan->topic);
  1618. chan->topic = xstrdup (msg->params.vector[1]);
  1619. char *message = xstrdup_printf (":%s!%s@%s TOPIC %s :%s",
  1620. c->nickname, c->username, c->hostname, target, chan->topic);
  1621. irc_channel_multicast (chan, message, NULL);
  1622. free (message);
  1623. }
  1624. static void
  1625. irc_try_part (struct client *c, const char *channel_name, const char *reason)
  1626. {
  1627. if (!reason)
  1628. reason = c->nickname;
  1629. struct channel *chan;
  1630. if (!(chan = str_map_find (&c->ctx->channels, channel_name)))
  1631. RETURN_WITH_REPLY (c, IRC_ERR_NOSUCHCHANNEL, channel_name);
  1632. struct channel_user *user;
  1633. if (!(user = channel_get_user (chan, c)))
  1634. RETURN_WITH_REPLY (c, IRC_ERR_NOTONCHANNEL, channel_name);
  1635. char *message = xstrdup_printf (":%s!%s@%s PART %s :%s",
  1636. c->nickname, c->username, c->hostname, channel_name, reason);
  1637. if (!(chan->modes & IRC_CHAN_MODE_QUIET))
  1638. irc_channel_multicast (chan, message, NULL);
  1639. else
  1640. irc_send (c, "%s", message);
  1641. free (message);
  1642. channel_remove_user (chan, user);
  1643. channel_destroy_if_empty (c->ctx, chan);
  1644. }
  1645. static void
  1646. irc_part_all_channels (struct client *c)
  1647. {
  1648. struct str_map_iter iter;
  1649. str_map_iter_init (&iter, &c->ctx->channels);
  1650. struct channel *chan = str_map_iter_next (&iter), *next;
  1651. while (chan)
  1652. {
  1653. // We have to be careful here, the channel might get destroyed
  1654. next = str_map_iter_next (&iter);
  1655. if (channel_get_user (chan, c))
  1656. irc_try_part (c, chan->name, NULL);
  1657. chan = next;
  1658. }
  1659. }
  1660. static void
  1661. irc_handle_part (const struct irc_message *msg, struct client *c)
  1662. {
  1663. if (msg->params.len < 1)
  1664. RETURN_WITH_REPLY (c, IRC_ERR_NEEDMOREPARAMS, msg->command);
  1665. const char *reason = msg->params.len > 1 ? msg->params.vector[1] : NULL;
  1666. struct str_vector channels;
  1667. str_vector_init (&channels);
  1668. split_str_ignore_empty (msg->params.vector[0], ',', &channels);
  1669. for (size_t i = 0; i < channels.len; i++)
  1670. irc_try_part (c, channels.vector[i], reason);
  1671. str_vector_free (&channels);
  1672. }
  1673. static void
  1674. irc_try_kick (struct client *c, const char *channel_name, const char *nick,
  1675. const char *reason)
  1676. {
  1677. struct channel *chan;
  1678. if (!(chan = str_map_find (&c->ctx->channels, channel_name)))
  1679. RETURN_WITH_REPLY (c, IRC_ERR_NOSUCHCHANNEL, channel_name);
  1680. struct channel_user *user;
  1681. if (!(user = channel_get_user (chan, c)))
  1682. RETURN_WITH_REPLY (c, IRC_ERR_NOTONCHANNEL, channel_name);
  1683. if (!(user->modes & IRC_CHAN_MODE_OPERATOR))
  1684. RETURN_WITH_REPLY (c, IRC_ERR_CHANOPRIVSNEEDED, channel_name);
  1685. struct client *client;
  1686. if (!(client = str_map_find (&c->ctx->users, nick))
  1687. || !(user = channel_get_user (chan, client)))
  1688. RETURN_WITH_REPLY (c, IRC_ERR_USERNOTINCHANNEL, nick, channel_name);
  1689. char *message = xstrdup_printf (":%s!%s@%s KICK %s %s :%s",
  1690. c->nickname, c->username, c->hostname, channel_name, nick, reason);
  1691. if (!(chan->modes & IRC_CHAN_MODE_QUIET))
  1692. irc_channel_multicast (chan, message, NULL);
  1693. else
  1694. irc_send (c, "%s", message);
  1695. free (message);
  1696. channel_remove_user (chan, user);
  1697. channel_destroy_if_empty (c->ctx, chan);
  1698. }
  1699. static void
  1700. irc_handle_kick (const struct irc_message *msg, struct client *c)
  1701. {
  1702. if (msg->params.len < 2)
  1703. RETURN_WITH_REPLY (c, IRC_ERR_NEEDMOREPARAMS, msg->command);
  1704. const char *reason = c->nickname;
  1705. if (msg->params.len > 2)
  1706. reason = msg->params.vector[2];
  1707. struct str_vector channels;
  1708. struct str_vector users;
  1709. str_vector_init (&channels);
  1710. str_vector_init (&users);
  1711. split_str_ignore_empty (msg->params.vector[0], ',', &channels);
  1712. split_str_ignore_empty (msg->params.vector[1], ',', &users);
  1713. if (channels.len == 1)
  1714. for (size_t i = 0; i < users.len; i++)
  1715. irc_try_kick (c, channels.vector[0], users.vector[i], reason);
  1716. else
  1717. for (size_t i = 0; i < channels.len && i < users.len; i++)
  1718. irc_try_kick (c, channels.vector[i], users.vector[i], reason);
  1719. str_vector_free (&channels);
  1720. str_vector_free (&users);
  1721. }
  1722. static void
  1723. irc_try_join (struct client *c, const char *channel_name, const char *key)
  1724. {
  1725. struct channel *chan = str_map_find (&c->ctx->channels, channel_name);
  1726. unsigned user_mode = 0;
  1727. if (!chan)
  1728. {
  1729. if (irc_validate_channel_name (channel_name) != VALIDATION_OK)
  1730. RETURN_WITH_REPLY (c, IRC_ERR_BADCHANMASK, channel_name);
  1731. chan = channel_create (c->ctx, channel_name);
  1732. user_mode = IRC_CHAN_MODE_OPERATOR;
  1733. }
  1734. else if (channel_get_user (chan, c))
  1735. return;
  1736. if ((chan->modes & IRC_CHAN_MODE_INVITE_ONLY)
  1737. && !client_in_mask_list (c, &chan->invite_list))
  1738. // TODO: exceptions caused by INVITE
  1739. RETURN_WITH_REPLY (c, IRC_ERR_INVITEONLYCHAN, channel_name);
  1740. if (chan->key && (!key || strcmp (key, chan->key)))
  1741. RETURN_WITH_REPLY (c, IRC_ERR_BADCHANNELKEY, channel_name);
  1742. if (chan->user_limit != -1
  1743. && channel_user_count (chan) >= (size_t) chan->user_limit)
  1744. RETURN_WITH_REPLY (c, IRC_ERR_CHANNELISFULL, channel_name);
  1745. if (client_in_mask_list (c, &chan->ban_list)
  1746. && !client_in_mask_list (c, &chan->exception_list))
  1747. RETURN_WITH_REPLY (c, IRC_ERR_BANNEDFROMCHAN, channel_name);
  1748. channel_add_user (chan, c)->modes = user_mode;
  1749. char *message = xstrdup_printf (":%s!%s@%s JOIN %s",
  1750. c->nickname, c->username, c->hostname, channel_name);
  1751. if (!(chan->modes & IRC_CHAN_MODE_QUIET))
  1752. irc_channel_multicast (chan, message, NULL);
  1753. else
  1754. irc_send (c, "%s", message);
  1755. free (message);
  1756. irc_send_rpl_topic (c, chan);
  1757. irc_send_rpl_namreply (c, chan);
  1758. irc_send_reply (c, IRC_RPL_ENDOFNAMES, chan->name);
  1759. }
  1760. static void
  1761. irc_handle_join (const struct irc_message *msg, struct client *c)
  1762. {
  1763. if (msg->params.len < 1)
  1764. RETURN_WITH_REPLY (c, IRC_ERR_NEEDMOREPARAMS, msg->command);
  1765. if (!strcmp (msg->params.vector[0], "0"))
  1766. {
  1767. irc_part_all_channels (c);
  1768. return;
  1769. }
  1770. struct str_vector channels;
  1771. struct str_vector keys;
  1772. str_vector_init (&channels);
  1773. str_vector_init (&keys);
  1774. split_str_ignore_empty (msg->params.vector[0], ',', &channels);
  1775. if (msg->params.len > 1)
  1776. split_str_ignore_empty (msg->params.vector[1], ',', &keys);
  1777. for (size_t i = 0; i < channels.len; i++)
  1778. irc_try_join (c, channels.vector[i],
  1779. i < keys.len ? keys.vector[i] : NULL);
  1780. str_vector_free (&channels);
  1781. str_vector_free (&keys);
  1782. }
  1783. static void
  1784. irc_handle_summon (const struct irc_message *msg, struct client *c)
  1785. {
  1786. (void) msg;
  1787. irc_send_reply (c, IRC_ERR_SUMMONDISABLED);
  1788. }
  1789. static void
  1790. irc_handle_users (const struct irc_message *msg, struct client *c)
  1791. {
  1792. (void) msg;
  1793. irc_send_reply (c, IRC_ERR_USERSDISABLED);
  1794. }
  1795. static void
  1796. irc_handle_away (const struct irc_message *msg, struct client *c)
  1797. {
  1798. if (msg->params.len < 1)
  1799. {
  1800. free (c->away_message);
  1801. c->away_message = NULL;
  1802. irc_send_reply (c, IRC_RPL_UNAWAY);
  1803. }
  1804. else
  1805. {
  1806. free (c->away_message);
  1807. c->away_message = xstrdup (msg->params.vector[0]);
  1808. irc_send_reply (c, IRC_RPL_NOWAWAY);
  1809. }
  1810. }
  1811. static void
  1812. irc_handle_ison (const struct irc_message *msg, struct client *c)
  1813. {
  1814. if (msg->params.len < 1)
  1815. RETURN_WITH_REPLY (c, IRC_ERR_NEEDMOREPARAMS, msg->command);
  1816. struct str result;
  1817. str_init (&result);
  1818. const char *nick;
  1819. if (str_map_find (&c->ctx->users, (nick = msg->params.vector[0])))
  1820. str_append (&result, nick);
  1821. for (size_t i = 1; i < msg->params.len; i++)
  1822. if (str_map_find (&c->ctx->users, (nick = msg->params.vector[i])))
  1823. str_append_printf (&result, " %s", nick);
  1824. irc_send_reply (c, IRC_RPL_ISON, result.str);
  1825. str_free (&result);
  1826. }
  1827. static void
  1828. irc_handle_kill (const struct irc_message *msg, struct client *c)
  1829. {
  1830. if (msg->params.len < 2)
  1831. RETURN_WITH_REPLY (c, IRC_ERR_NEEDMOREPARAMS, msg->command);
  1832. if (!(c->mode & IRC_USER_MODE_OPERATOR))
  1833. RETURN_WITH_REPLY (c, IRC_ERR_NOPRIVILEGES);
  1834. struct client *target;
  1835. if (!(target = str_map_find (&c->ctx->users, msg->params.vector[0])))
  1836. RETURN_WITH_REPLY (c, IRC_ERR_NOSUCHNICK, msg->params.vector[0]);
  1837. char *reason = xstrdup_printf ("Killed by %s: %s",
  1838. c->nickname, msg->params.vector[1]);
  1839. irc_close_link (target, reason);
  1840. free (reason);
  1841. }
  1842. static void
  1843. irc_handle_die (const struct irc_message *msg, struct client *c)
  1844. {
  1845. (void) msg;
  1846. if (!(c->mode & IRC_USER_MODE_OPERATOR))
  1847. RETURN_WITH_REPLY (c, IRC_ERR_NOPRIVILEGES);
  1848. if (!c->ctx->quitting)
  1849. irc_initiate_quit (c->ctx);
  1850. }
  1851. // -----------------------------------------------------------------------------
  1852. struct irc_command
  1853. {
  1854. const char *name;
  1855. bool requires_registration;
  1856. void (*handler) (const struct irc_message *, struct client *);
  1857. };
  1858. static void
  1859. irc_register_handlers (struct server_context *ctx)
  1860. {
  1861. // TODO: add an index for IRC_ERR_NOSUCHSERVER validation?
  1862. // TODO: add a minimal parameter count?
  1863. // TODO: add a field for oper-only commands?
  1864. static const struct irc_command message_handlers[] =
  1865. {
  1866. { "PASS", false, irc_handle_pass },
  1867. { "NICK", false, irc_handle_nick },
  1868. { "USER", false, irc_handle_user },
  1869. { "USERHOST", true, irc_handle_userhost },
  1870. { "LUSERS", true, irc_handle_lusers },
  1871. { "MOTD", true, irc_handle_motd },
  1872. { "PING", true, irc_handle_ping },
  1873. { "PONG", false, irc_handle_pong },
  1874. { "QUIT", false, irc_handle_quit },
  1875. { "TIME", true, irc_handle_time },
  1876. { "VERSION", true, irc_handle_version },
  1877. { "USERS", true, irc_handle_users },
  1878. { "SUMMON", true, irc_handle_summon },
  1879. { "AWAY", true, irc_handle_away },
  1880. { "MODE", true, irc_handle_mode },
  1881. { "PRIVMSG", true, irc_handle_privmsg },
  1882. { "NOTICE", true, irc_handle_notice },
  1883. { "JOIN", true, irc_handle_join },
  1884. { "PART", true, irc_handle_part },
  1885. { "KICK", true, irc_handle_kick },
  1886. { "TOPIC", true, irc_handle_topic },
  1887. { "LIST", true, irc_handle_list },
  1888. { "NAMES", true, irc_handle_names },
  1889. { "WHO", true, irc_handle_who },
  1890. { "WHOIS", true, irc_handle_whois },
  1891. { "ISON", true, irc_handle_ison },
  1892. { "KILL", true, irc_handle_kill },
  1893. { "DIE", true, irc_handle_die },
  1894. };
  1895. for (size_t i = 0; i < N_ELEMENTS (message_handlers); i++)
  1896. {
  1897. const struct irc_command *cmd = &message_handlers[i];
  1898. str_map_set (&ctx->handlers, cmd->name, (void *) cmd);
  1899. }
  1900. }
  1901. static void
  1902. irc_process_message (const struct irc_message *msg,
  1903. const char *raw, void *user_data)
  1904. {
  1905. (void) raw;
  1906. struct client *c = user_data;
  1907. if (c->closing_link)
  1908. return;
  1909. struct irc_command *cmd = str_map_find (&c->ctx->handlers, msg->command);
  1910. if (!cmd)
  1911. irc_send_reply (c, IRC_ERR_UNKNOWNCOMMAND, msg->command);
  1912. else if (cmd->requires_registration && !c->registered)
  1913. irc_send_reply (c, IRC_ERR_NOTREGISTERED);
  1914. else
  1915. cmd->handler (msg, c);
  1916. }
  1917. // --- Network I/O -------------------------------------------------------------
  1918. static bool
  1919. irc_try_read (struct client *c)
  1920. {
  1921. struct str *buf = &c->read_buffer;
  1922. ssize_t n_read;
  1923. while (true)
  1924. {
  1925. str_ensure_space (buf, 512);
  1926. n_read = recv (c->socket_fd, buf->str + buf->len,
  1927. buf->alloc - buf->len - 1 /* null byte */, 0);
  1928. if (n_read > 0)
  1929. {
  1930. buf->str[buf->len += n_read] = '\0';
  1931. // TODO: discard characters above the 512 character limit
  1932. irc_process_buffer (buf, irc_process_message, c);
  1933. continue;
  1934. }
  1935. if (n_read == 0)
  1936. {
  1937. client_kill (c, NULL);
  1938. return false;
  1939. }
  1940. if (errno == EAGAIN)
  1941. return true;
  1942. if (errno == EINTR)
  1943. continue;
  1944. print_debug ("%s: %s: %s", __func__, "recv", strerror (errno));
  1945. client_kill (c, strerror (errno));
  1946. return false;
  1947. }
  1948. }
  1949. static bool
  1950. irc_try_read_ssl (struct client *c)
  1951. {
  1952. if (c->ssl_tx_want_rx)
  1953. return true;
  1954. struct str *buf = &c->read_buffer;
  1955. c->ssl_rx_want_tx = false;
  1956. while (true)
  1957. {
  1958. str_ensure_space (buf, 512);
  1959. int n_read = SSL_read (c->ssl, buf->str + buf->len,
  1960. buf->alloc - buf->len - 1 /* null byte */);
  1961. const char *error_info = NULL;
  1962. switch (xssl_get_error (c->ssl, n_read, &error_info))
  1963. {
  1964. case SSL_ERROR_NONE:
  1965. buf->str[buf->len += n_read] = '\0';
  1966. // TODO: discard characters above the 512 character limit
  1967. irc_process_buffer (buf, irc_process_message, c);
  1968. continue;
  1969. case SSL_ERROR_ZERO_RETURN:
  1970. client_kill (c, NULL);
  1971. return false;
  1972. case SSL_ERROR_WANT_READ:
  1973. return true;
  1974. case SSL_ERROR_WANT_WRITE:
  1975. c->ssl_rx_want_tx = true;
  1976. return true;
  1977. case XSSL_ERROR_TRY_AGAIN:
  1978. continue;
  1979. default:
  1980. print_debug ("%s: %s: %s", __func__, "SSL_read", error_info);
  1981. client_kill (c, error_info);
  1982. return false;
  1983. }
  1984. }
  1985. }
  1986. static bool
  1987. irc_try_write (struct client *c)
  1988. {
  1989. struct str *buf = &c->write_buffer;
  1990. ssize_t n_written;
  1991. while (buf->len)
  1992. {
  1993. n_written = send (c->socket_fd, buf->str, buf->len, 0);
  1994. if (n_written >= 0)
  1995. {
  1996. str_remove_slice (buf, 0, n_written);
  1997. continue;
  1998. }
  1999. if (errno == EAGAIN)
  2000. return true;
  2001. if (errno == EINTR)
  2002. continue;
  2003. print_debug ("%s: %s: %s", __func__, "send", strerror (errno));
  2004. client_kill (c, strerror (errno));
  2005. return false;
  2006. }
  2007. return true;
  2008. }
  2009. static bool
  2010. irc_try_write_ssl (struct client *c)
  2011. {
  2012. if (c->ssl_rx_want_tx)
  2013. return true;
  2014. struct str *buf = &c->write_buffer;
  2015. c->ssl_tx_want_rx = false;
  2016. while (buf->len)
  2017. {
  2018. int n_written = SSL_write (c->ssl, buf->str, buf->len);
  2019. const char *error_info = NULL;
  2020. switch (xssl_get_error (c->ssl, n_written, &error_info))
  2021. {
  2022. case SSL_ERROR_NONE:
  2023. str_remove_slice (buf, 0, n_written);
  2024. continue;
  2025. case SSL_ERROR_ZERO_RETURN:
  2026. client_kill (c, NULL);
  2027. return false;
  2028. case SSL_ERROR_WANT_WRITE:
  2029. return true;
  2030. case SSL_ERROR_WANT_READ:
  2031. c->ssl_tx_want_rx = true;
  2032. return true;
  2033. case XSSL_ERROR_TRY_AGAIN:
  2034. continue;
  2035. default:
  2036. print_debug ("%s: %s: %s", __func__, "SSL_write", error_info);
  2037. client_kill (c, error_info);
  2038. return false;
  2039. }
  2040. }
  2041. return true;
  2042. }
  2043. static bool
  2044. irc_autodetect_ssl (struct client *c)
  2045. {
  2046. // Trivial SSL/TLS autodetection. The first block of data returned by
  2047. // recv() must be at least three bytes long for this to work reliably,
  2048. // but that should not pose a problem in practice.
  2049. //
  2050. // SSL2: 1xxx xxxx | xxxx xxxx | <1>
  2051. // (message length) (client hello)
  2052. // SSL3/TLS: <22> | <3> | xxxx xxxx
  2053. // (handshake)| (protocol version)
  2054. //
  2055. // Such byte sequences should never occur at the beginning of regular IRC
  2056. // communication, which usually begins with USER/NICK/PASS/SERVICE.
  2057. char buf[3];
  2058. start:
  2059. switch (recv (c->socket_fd, buf, sizeof buf, MSG_PEEK))
  2060. {
  2061. case 3:
  2062. if ((buf[0] & 0x80) && buf[2] == 1)
  2063. return true;
  2064. case 2:
  2065. if (buf[0] == 22 && buf[1] == 3)
  2066. return true;
  2067. break;
  2068. case 1:
  2069. if (buf[0] == 22)
  2070. return true;
  2071. break;
  2072. case 0:
  2073. break;
  2074. default:
  2075. if (errno == EINTR)
  2076. goto start;
  2077. }
  2078. return false;
  2079. }
  2080. static bool
  2081. client_initialize_ssl (struct client *c)
  2082. {
  2083. // SSL support not enabled
  2084. if (!c->ctx->ssl_ctx)
  2085. return false;
  2086. c->ssl = SSL_new (c->ctx->ssl_ctx);
  2087. if (!c->ssl)
  2088. goto error_ssl_1;
  2089. if (!SSL_set_fd (c->ssl, c->socket_fd))
  2090. goto error_ssl_2;
  2091. SSL_set_accept_state (c->ssl);
  2092. return true;
  2093. error_ssl_2:
  2094. SSL_free (c->ssl);
  2095. c->ssl = NULL;
  2096. error_ssl_1:
  2097. // XXX: these error strings are really nasty; also there could be
  2098. // multiple errors on the OpenSSL stack.
  2099. print_debug ("%s: %s: %s", "could not initialize SSL",
  2100. c->hostname, ERR_error_string (ERR_get_error (), NULL));
  2101. return false;
  2102. }
  2103. static void
  2104. on_irc_client_ready (const struct pollfd *pfd, void *user_data)
  2105. {
  2106. struct client *c = user_data;
  2107. if (!c->initialized)
  2108. {
  2109. hard_assert (pfd->events == POLLIN);
  2110. if (irc_autodetect_ssl (c) && !client_initialize_ssl (c))
  2111. {
  2112. client_kill (c, NULL);
  2113. return;
  2114. }
  2115. c->initialized = true;
  2116. client_set_ping_timer (c);
  2117. }
  2118. if (c->ssl)
  2119. {
  2120. // Reads may want to write, writes may want to read, poll() may
  2121. // return unexpected things in `revents'... let's try both
  2122. if (!irc_try_read_ssl (c) || !irc_try_write_ssl (c))
  2123. return;
  2124. }
  2125. else if (!irc_try_read (c) || !irc_try_write (c))
  2126. return;
  2127. client_update_poller (c, pfd);
  2128. // The purpose of the `closing_link' state is to transfer the `ERROR'
  2129. if (c->closing_link && !c->write_buffer.len)
  2130. client_kill (c, NULL);
  2131. }
  2132. static void
  2133. client_update_poller (struct client *c, const struct pollfd *pfd)
  2134. {
  2135. int new_events = POLLIN;
  2136. if (c->ssl)
  2137. {
  2138. if (c->write_buffer.len || c->ssl_rx_want_tx)
  2139. new_events |= POLLOUT;
  2140. // While we're waiting for an opposite event, we ignore the original
  2141. if (c->ssl_rx_want_tx) new_events &= ~POLLIN;
  2142. if (c->ssl_tx_want_rx) new_events &= ~POLLOUT;
  2143. }
  2144. else if (c->write_buffer.len)
  2145. new_events |= POLLOUT;
  2146. hard_assert (new_events != 0);
  2147. if (!pfd || pfd->events != new_events)
  2148. poller_set (&c->ctx->poller, c->socket_fd, new_events,
  2149. (poller_dispatcher_func) on_irc_client_ready, c);
  2150. }
  2151. static void
  2152. on_irc_client_available (const struct pollfd *pfd, void *user_data)
  2153. {
  2154. (void) pfd;
  2155. struct server_context *ctx = user_data;
  2156. while (true)
  2157. {
  2158. // XXX: `struct sockaddr_storage' is not the most portable thing
  2159. struct sockaddr_storage peer;
  2160. socklen_t peer_len = sizeof peer;
  2161. int fd = accept (ctx->listen_fd, (struct sockaddr *) &peer, &peer_len);
  2162. if (fd == -1)
  2163. {
  2164. if (errno == EAGAIN)
  2165. break;
  2166. if (errno == EINTR
  2167. || errno == ECONNABORTED)
  2168. continue;
  2169. // TODO: handle resource exhaustion (EMFILE, ENFILE) specially
  2170. // (stop accepting new connections and wait until we close some).
  2171. // FIXME: handle this better, bring the server down cleanly.
  2172. exit_fatal ("%s: %s", "accept", strerror (errno));
  2173. }
  2174. if (ctx->max_connections != 0 && ctx->n_clients >= ctx->max_connections)
  2175. {
  2176. print_debug ("connection limit reached, refusing connection");
  2177. close (fd);
  2178. continue;
  2179. }
  2180. char host[NI_MAXHOST] = "unknown", port[NI_MAXSERV] = "unknown";
  2181. int err = getnameinfo ((struct sockaddr *) &peer, peer_len,
  2182. host, sizeof host, port, sizeof port, NI_NUMERICSERV);
  2183. if (err)
  2184. print_debug ("%s: %s", "getnameinfo", gai_strerror (err));
  2185. print_debug ("accepted connection from %s:%s", host, port);
  2186. struct client *c = xmalloc (sizeof *c);
  2187. client_init (c);
  2188. c->ctx = ctx;
  2189. c->socket_fd = fd;
  2190. c->hostname = xstrdup (host);
  2191. c->last_active = time (NULL);
  2192. LIST_PREPEND (ctx->clients, c);
  2193. ctx->n_clients++;
  2194. set_blocking (fd, false);
  2195. client_update_poller (c, NULL);
  2196. client_set_kill_timer (c);
  2197. }
  2198. }
  2199. // -----------------------------------------------------------------------------
  2200. static int
  2201. irc_ssl_verify_callback (int verify_ok, X509_STORE_CTX *ctx)
  2202. {
  2203. (void) verify_ok;
  2204. (void) ctx;
  2205. // We only want to provide additional privileges based on the client's
  2206. // certificate, so let's not terminate the connection because of a failure.
  2207. return 1;
  2208. }
  2209. static bool
  2210. irc_initialize_ssl (struct server_context *ctx, struct error **e)
  2211. {
  2212. const char *ssl_cert = str_map_find (&ctx->config, "ssl_cert");
  2213. const char *ssl_key = str_map_find (&ctx->config, "ssl_key");
  2214. // Only try to enable SSL support if the user configures it; it is not
  2215. // a failure if no one has requested it.
  2216. if (!ssl_cert && !ssl_key)
  2217. return true;
  2218. if (!ssl_cert)
  2219. error_set (e, "no SSL certificate set");
  2220. else if (!ssl_key)
  2221. error_set (e, "no SSL private key set");
  2222. if (!ssl_cert || !ssl_key)
  2223. return false;
  2224. char *cert_path = resolve_config_filename (ssl_cert);
  2225. char *key_path = resolve_config_filename (ssl_key);
  2226. if (!cert_path)
  2227. error_set (e, "%s: %s", "cannot open file", ssl_cert);
  2228. else if (!key_path)
  2229. error_set (e, "%s: %s", "cannot open file", ssl_key);
  2230. if (!cert_path || !key_path)
  2231. return false;
  2232. ctx->ssl_ctx = SSL_CTX_new (SSLv23_server_method ());
  2233. if (!ctx->ssl_ctx)
  2234. {
  2235. // XXX: these error strings are really nasty; also there could be
  2236. // multiple errors on the OpenSSL stack.
  2237. error_set (e, "%s: %s", "could not initialize SSL",
  2238. ERR_error_string (ERR_get_error (), NULL));
  2239. goto error_ssl_1;
  2240. }
  2241. SSL_CTX_set_verify (ctx->ssl_ctx,
  2242. SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, irc_ssl_verify_callback);
  2243. // XXX: maybe we should call SSL_CTX_set_options() for some workarounds
  2244. const unsigned char session_id_context[SSL_MAX_SSL_SESSION_ID_LENGTH]
  2245. = PROGRAM_NAME;
  2246. (void) SSL_CTX_set_session_id_context (ctx->ssl_ctx,
  2247. session_id_context, sizeof session_id_context);
  2248. // XXX: perhaps we should read the files ourselves for better messages
  2249. if (!SSL_CTX_use_certificate_chain_file (ctx->ssl_ctx, cert_path))
  2250. {
  2251. error_set (e, "%s: %s", "setting the SSL client certificate failed",
  2252. ERR_error_string (ERR_get_error (), NULL));
  2253. goto error_ssl_2;
  2254. }
  2255. if (!SSL_CTX_use_PrivateKey_file (ctx->ssl_ctx, key_path, SSL_FILETYPE_PEM))
  2256. {
  2257. error_set (e, "%s: %s", "setting the SSL private key failed",
  2258. ERR_error_string (ERR_get_error (), NULL));
  2259. goto error_ssl_2;
  2260. }
  2261. // TODO: SSL_CTX_check_private_key()? It has probably already been checked
  2262. // by SSL_CTX_use_PrivateKey_file() above.
  2263. // Gah, spare me your awkward semantics, I just want to push data!
  2264. // XXX: do we want SSL_MODE_AUTO_RETRY as well? I guess not.
  2265. SSL_CTX_set_mode (ctx->ssl_ctx,
  2266. SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE);
  2267. return true;
  2268. error_ssl_2:
  2269. SSL_CTX_free (ctx->ssl_ctx);
  2270. ctx->ssl_ctx = NULL;
  2271. error_ssl_1:
  2272. return false;
  2273. }
  2274. static bool
  2275. irc_initialize_catalog (struct server_context *ctx, struct error **e)
  2276. {
  2277. hard_assert (ctx->catalog == (nl_catd) -1);
  2278. const char *catalog = str_map_find (&ctx->config, "catalog");
  2279. if (!catalog)
  2280. return true;
  2281. char *path = resolve_config_filename (catalog);
  2282. if (!path)
  2283. {
  2284. error_set (e, "%s: %s", "cannot open file", catalog);
  2285. return false;
  2286. }
  2287. ctx->catalog = catopen (path, NL_CAT_LOCALE);
  2288. free (path);
  2289. if (ctx->catalog == (nl_catd) -1)
  2290. {
  2291. error_set (e, "%s: %s",
  2292. "failed reading the message catalog file", strerror (errno));
  2293. return false;
  2294. }
  2295. return true;
  2296. }
  2297. static bool
  2298. irc_initialize_motd (struct server_context *ctx, struct error **e)
  2299. {
  2300. hard_assert (ctx->motd.len == 0);
  2301. const char *motd = str_map_find (&ctx->config, "motd");
  2302. if (!motd)
  2303. return true;
  2304. char *path = resolve_config_filename (motd);
  2305. if (!path)
  2306. {
  2307. error_set (e, "%s: %s", "cannot open file", motd);
  2308. return false;
  2309. }
  2310. FILE *fp = fopen (path, "r");
  2311. free (path);
  2312. if (!fp)
  2313. {
  2314. error_set (e, "%s: %s",
  2315. "failed reading the MOTD file", strerror (errno));
  2316. return false;
  2317. }
  2318. struct str line;
  2319. str_init (&line);
  2320. while (read_line (fp, &line))
  2321. str_vector_add_owned (&ctx->motd, str_steal (&line));
  2322. str_free (&line);
  2323. fclose (fp);
  2324. return true;
  2325. }
  2326. /// This function handles values that require validation before their first use,
  2327. /// or some kind of a transformation (such as conversion to an integer) needs
  2328. /// to be done before they can be used directly.
  2329. static bool
  2330. irc_parse_config (struct server_context *ctx, struct error **e)
  2331. {
  2332. unsigned long ul;
  2333. #define PARSE_UNSIGNED(name, min, max) \
  2334. const char *name = str_map_find (&ctx->config, #name); \
  2335. hard_assert (name != NULL); \
  2336. if (!xstrtoul (&ul, name, 10) || ul > max || ul < min) \
  2337. { \
  2338. error_set (e, "invalid configuration value for `%s': %s", \
  2339. #name, "the number is invalid or out of range"); \
  2340. return false; \
  2341. } \
  2342. ctx->name = ul
  2343. PARSE_UNSIGNED (ping_interval, 1, UINT_MAX);
  2344. PARSE_UNSIGNED (max_connections, 0, UINT_MAX);
  2345. bool result = true;
  2346. struct str_vector fingerprints;
  2347. str_vector_init (&fingerprints);
  2348. const char *operators = str_map_find (&ctx->config, "operators");
  2349. if (operators)
  2350. split_str_ignore_empty (operators, ',', &fingerprints);
  2351. for (size_t i = 0; i < fingerprints.len; i++)
  2352. {
  2353. const char *key = fingerprints.vector[i];
  2354. if (!irc_is_valid_fingerprint (key))
  2355. {
  2356. error_set (e, "invalid configuration value for `%s': %s",
  2357. "operators", "invalid fingerprint value");
  2358. result = false;
  2359. break;
  2360. }
  2361. str_map_set (&ctx->operators, key, (void *) 1);
  2362. }
  2363. str_vector_free (&fingerprints);
  2364. return result;
  2365. }
  2366. static bool
  2367. irc_initialize_server_name (struct server_context *ctx, struct error **e)
  2368. {
  2369. enum validation_result res;
  2370. const char *server_name = str_map_find (&ctx->config, "server_name");
  2371. if (server_name)
  2372. {
  2373. res = irc_validate_hostname (server_name);
  2374. if (res != VALIDATION_OK)
  2375. {
  2376. error_set (e, "invalid configuration value for `%s': %s",
  2377. "server_name", irc_validate_to_str (res));
  2378. return false;
  2379. }
  2380. ctx->server_name = xstrdup (server_name);
  2381. }
  2382. else
  2383. {
  2384. char hostname[HOST_NAME_MAX];
  2385. if (gethostname (hostname, sizeof hostname))
  2386. {
  2387. error_set (e, "%s: %s",
  2388. "getting the hostname failed", strerror (errno));
  2389. return false;
  2390. }
  2391. res = irc_validate_hostname (hostname);
  2392. if (res != VALIDATION_OK)
  2393. {
  2394. error_set (e,
  2395. "`%s' is not set and the hostname (`%s') cannot be used: %s",
  2396. "server_name", hostname, irc_validate_to_str (res));
  2397. return false;
  2398. }
  2399. ctx->server_name = xstrdup (hostname);
  2400. }
  2401. return true;
  2402. }
  2403. static bool
  2404. irc_listen (struct server_context *ctx, struct error **e)
  2405. {
  2406. const char *bind_host = str_map_find (&ctx->config, "bind_host");
  2407. const char *bind_port = str_map_find (&ctx->config, "bind_port");
  2408. hard_assert (bind_port != NULL); // We have a default value for this
  2409. struct addrinfo gai_hints, *gai_result, *gai_iter;
  2410. memset (&gai_hints, 0, sizeof gai_hints);
  2411. gai_hints.ai_socktype = SOCK_STREAM;
  2412. gai_hints.ai_flags = AI_PASSIVE;
  2413. int err = getaddrinfo (bind_host, bind_port, &gai_hints, &gai_result);
  2414. if (err)
  2415. {
  2416. error_set (e, "%s: %s: %s",
  2417. "network setup failed", "getaddrinfo", gai_strerror (err));
  2418. return false;
  2419. }
  2420. int sockfd;
  2421. char real_host[NI_MAXHOST], real_port[NI_MAXSERV];
  2422. for (gai_iter = gai_result; gai_iter; gai_iter = gai_iter->ai_next)
  2423. {
  2424. sockfd = socket (gai_iter->ai_family,
  2425. gai_iter->ai_socktype, gai_iter->ai_protocol);
  2426. if (sockfd == -1)
  2427. continue;
  2428. set_cloexec (sockfd);
  2429. int yes = 1;
  2430. soft_assert (setsockopt (sockfd, SOL_SOCKET, SO_KEEPALIVE,
  2431. &yes, sizeof yes) != -1);
  2432. soft_assert (setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR,
  2433. &yes, sizeof yes) != -1);
  2434. real_host[0] = real_port[0] = '\0';
  2435. err = getnameinfo (gai_iter->ai_addr, gai_iter->ai_addrlen,
  2436. real_host, sizeof real_host, real_port, sizeof real_port,
  2437. NI_NUMERICHOST | NI_NUMERICSERV);
  2438. if (err)
  2439. print_debug ("%s: %s", "getnameinfo", gai_strerror (err));
  2440. if (bind (sockfd, gai_iter->ai_addr, gai_iter->ai_addrlen))
  2441. print_error ("bind to %s:%s failed: %s",
  2442. real_host, real_port, strerror (errno));
  2443. else if (listen (sockfd, 16 /* arbitrary number */))
  2444. print_error ("listen at %s:%s failed: %s",
  2445. real_host, real_port, strerror (errno));
  2446. else
  2447. break;
  2448. xclose (sockfd);
  2449. }
  2450. freeaddrinfo (gai_result);
  2451. if (!gai_iter)
  2452. {
  2453. error_set (e, "network setup failed");
  2454. return false;
  2455. }
  2456. set_blocking (sockfd, false);
  2457. ctx->listen_fd = sockfd;
  2458. poller_set (&ctx->poller, ctx->listen_fd, POLLIN,
  2459. (poller_dispatcher_func) on_irc_client_available, ctx);
  2460. print_status ("listening at %s:%s", real_host, real_port);
  2461. return true;
  2462. }
  2463. static void
  2464. on_signal_pipe_readable (const struct pollfd *fd, struct server_context *ctx)
  2465. {
  2466. char *dummy;
  2467. (void) read (fd->fd, &dummy, 1);
  2468. if (g_termination_requested && !ctx->quitting)
  2469. irc_initiate_quit (ctx);
  2470. }
  2471. static void
  2472. daemonize (void)
  2473. {
  2474. // TODO: create and lock a PID file?
  2475. print_status ("daemonizing...");
  2476. if (chdir ("/"))
  2477. exit_fatal ("%s: %s", "chdir", strerror (errno));
  2478. pid_t pid;
  2479. if ((pid = fork ()) < 0)
  2480. exit_fatal ("%s: %s", "fork", strerror (errno));
  2481. else if (pid)
  2482. exit (EXIT_SUCCESS);
  2483. setsid ();
  2484. signal (SIGHUP, SIG_IGN);
  2485. if ((pid = fork ()) < 0)
  2486. exit_fatal ("%s: %s", "fork", strerror (errno));
  2487. else if (pid)
  2488. exit (EXIT_SUCCESS);
  2489. openlog (PROGRAM_NAME, LOG_NDELAY | LOG_NOWAIT | LOG_PID, 0);
  2490. g_log_message_real = log_message_syslog;
  2491. // XXX: we may close our own descriptors this way, crippling ourselves
  2492. for (int i = 0; i < 3; i++)
  2493. xclose (i);
  2494. int tty = open ("/dev/null", O_RDWR);
  2495. if (tty != 0 || dup (0) != 1 || dup (0) != 2)
  2496. exit_fatal ("failed to reopen FD's: %s", strerror (errno));
  2497. }
  2498. static void
  2499. print_usage (const char *program_name)
  2500. {
  2501. fprintf (stderr,
  2502. "Usage: %s [OPTION]...\n"
  2503. "Experimental IRC server.\n"
  2504. "\n"
  2505. " -d, --debug run in debug mode (do not daemonize)\n"
  2506. " -h, --help display this help and exit\n"
  2507. " -V, --version output version information and exit\n"
  2508. " --write-default-cfg [filename]\n"
  2509. " write a default configuration file and exit\n",
  2510. program_name);
  2511. }
  2512. int
  2513. main (int argc, char *argv[])
  2514. {
  2515. const char *invocation_name = argv[0];
  2516. static struct option opts[] =
  2517. {
  2518. { "debug", no_argument, NULL, 'd' },
  2519. { "help", no_argument, NULL, 'h' },
  2520. { "version", no_argument, NULL, 'V' },
  2521. { "write-default-cfg", optional_argument, NULL, 'w' },
  2522. { NULL, 0, NULL, 0 }
  2523. };
  2524. while (1)
  2525. {
  2526. int c, opt_index;
  2527. c = getopt_long (argc, argv, "dhV", opts, &opt_index);
  2528. if (c == -1)
  2529. break;
  2530. switch (c)
  2531. {
  2532. case 'd':
  2533. g_debug_mode = true;
  2534. break;
  2535. case 'h':
  2536. print_usage (invocation_name);
  2537. exit (EXIT_SUCCESS);
  2538. case 'V':
  2539. printf (PROGRAM_NAME " " PROGRAM_VERSION "\n");
  2540. exit (EXIT_SUCCESS);
  2541. case 'w':
  2542. call_write_default_config (optarg, g_config_table);
  2543. exit (EXIT_SUCCESS);
  2544. default:
  2545. print_error ("wrong options");
  2546. exit (EXIT_FAILURE);
  2547. }
  2548. }
  2549. print_status (PROGRAM_NAME " " PROGRAM_VERSION " starting");
  2550. setup_signal_handlers ();
  2551. SSL_library_init ();
  2552. atexit (EVP_cleanup);
  2553. SSL_load_error_strings ();
  2554. // XXX: ERR_load_BIO_strings()? Anything else?
  2555. atexit (ERR_free_strings);
  2556. struct server_context ctx;
  2557. server_context_init (&ctx);
  2558. irc_register_handlers (&ctx);
  2559. struct error *e = NULL;
  2560. if (!read_config_file (&ctx.config, &e))
  2561. {
  2562. print_error ("error loading configuration: %s", e->message);
  2563. error_free (e);
  2564. exit (EXIT_FAILURE);
  2565. }
  2566. poller_set (&ctx.poller, g_signal_pipe[0], POLLIN,
  2567. (poller_dispatcher_func) on_signal_pipe_readable, &ctx);
  2568. if (!irc_initialize_ssl (&ctx, &e)
  2569. || !irc_initialize_server_name (&ctx, &e)
  2570. || !irc_initialize_motd (&ctx, &e)
  2571. || !irc_initialize_catalog (&ctx, &e)
  2572. || !irc_parse_config (&ctx, &e)
  2573. || !irc_listen (&ctx, &e))
  2574. {
  2575. print_error ("%s", e->message);
  2576. error_free (e);
  2577. exit (EXIT_FAILURE);
  2578. }
  2579. if (!g_debug_mode)
  2580. daemonize ();
  2581. ctx.polling = true;
  2582. while (ctx.polling)
  2583. poller_run (&ctx.poller);
  2584. server_context_free (&ctx);
  2585. return EXIT_SUCCESS;
  2586. }