]> jfr.im git - solanum.git/blob - ssld/ssld.c
Add new constants for presence key/value lengths
[solanum.git] / ssld / ssld.c
1 /*
2 * ssld.c: The ircd-ratbox ssl/zlib helper daemon thingy
3 * Copyright (C) 2007 Aaron Sethman <androsyn@ratbox.org>
4 * Copyright (C) 2007 ircd-ratbox development team
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 * USA
20 *
21 * $Id$
22 */
23
24
25 #include "stdinc.h"
26
27 #ifdef HAVE_LIBZ
28 #include <zlib.h>
29 #endif
30
31 #define MAXPASSFD 4
32 #ifndef READBUF_SIZE
33 #define READBUF_SIZE 16384
34 #endif
35
36 static void setup_signals(void);
37 static pid_t ppid;
38
39 static inline int32_t
40 buf_to_int32(char *buf)
41 {
42 int32_t x;
43 memcpy(&x, buf, sizeof(x));
44 return x;
45 }
46
47 static inline void
48 int32_to_buf(char *buf, int32_t x)
49 {
50 memcpy(buf, &x, sizeof(x));
51 return;
52 }
53
54 static inline uint16_t
55 buf_to_uint16(char *buf)
56 {
57 uint16_t x;
58 memcpy(&x, buf, sizeof(x));
59 return x;
60 }
61
62 static inline void
63 uint16_to_buf(char *buf, uint16_t x)
64 {
65 memcpy(buf, &x, sizeof(x));
66 return;
67 }
68
69
70 static char inbuf[READBUF_SIZE];
71 #ifdef HAVE_LIBZ
72 static char outbuf[READBUF_SIZE];
73 #endif
74
75 typedef struct _mod_ctl_buf
76 {
77 rb_dlink_node node;
78 char *buf;
79 size_t buflen;
80 rb_fde_t *F[MAXPASSFD];
81 int nfds;
82 } mod_ctl_buf_t;
83
84 typedef struct _mod_ctl
85 {
86 rb_dlink_node node;
87 int cli_count;
88 rb_fde_t *F;
89 rb_fde_t *F_pipe;
90 rb_dlink_list readq;
91 rb_dlink_list writeq;
92 } mod_ctl_t;
93
94 static mod_ctl_t *mod_ctl;
95
96
97 #ifdef HAVE_LIBZ
98 typedef struct _zlib_stream
99 {
100 z_stream instream;
101 z_stream outstream;
102 } zlib_stream_t;
103 #endif
104
105 typedef struct _conn
106 {
107 rb_dlink_node node;
108 mod_ctl_t *ctl;
109 rawbuf_head_t *modbuf_out;
110 rawbuf_head_t *plainbuf_out;
111
112 int32_t id;
113
114 rb_fde_t *mod_fd;
115 rb_fde_t *plain_fd;
116 unsigned long long mod_out;
117 unsigned long long mod_in;
118 unsigned long long plain_in;
119 unsigned long long plain_out;
120 uint8_t flags;
121 void *stream;
122 } conn_t;
123
124 #define FLAG_SSL 0x01
125 #define FLAG_ZIP 0x02
126 #define FLAG_CORK 0x04
127 #define FLAG_DEAD 0x08
128 #define FLAG_SSL_W_WANTS_R 0x10 /* output needs to wait until input possible */
129 #define FLAG_SSL_R_WANTS_W 0x20 /* input needs to wait until output possible */
130 #define FLAG_ZIPSSL 0x40
131
132 #define IsSSL(x) ((x)->flags & FLAG_SSL)
133 #define IsZip(x) ((x)->flags & FLAG_ZIP)
134 #define IsCork(x) ((x)->flags & FLAG_CORK)
135 #define IsDead(x) ((x)->flags & FLAG_DEAD)
136 #define IsSSLWWantsR(x) ((x)->flags & FLAG_SSL_W_WANTS_R)
137 #define IsSSLRWantsW(x) ((x)->flags & FLAG_SSL_R_WANTS_W)
138 #define IsZipSSL(x) ((x)->flags & FLAG_ZIPSSL)
139
140 #define SetSSL(x) ((x)->flags |= FLAG_SSL)
141 #define SetZip(x) ((x)->flags |= FLAG_ZIP)
142 #define SetCork(x) ((x)->flags |= FLAG_CORK)
143 #define SetDead(x) ((x)->flags |= FLAG_DEAD)
144 #define SetSSLWWantsR(x) ((x)->flags |= FLAG_SSL_W_WANTS_R)
145 #define SetSSLRWantsW(x) ((x)->flags |= FLAG_SSL_R_WANTS_W)
146 #define SetZipSSL(x) ((x)->flags |= FLAG_ZIPSSL)
147
148 #define ClearSSL(x) ((x)->flags &= ~FLAG_SSL)
149 #define ClearZip(x) ((x)->flags &= ~FLAG_ZIP)
150 #define ClearCork(x) ((x)->flags &= ~FLAG_CORK)
151 #define ClearDead(x) ((x)->flags &= ~FLAG_DEAD)
152 #define ClearSSLWWantsR(x) ((x)->flags &= ~FLAG_SSL_W_WANTS_R)
153 #define ClearSSLRWantsW(x) ((x)->flags &= ~FLAG_SSL_R_WANTS_W)
154 #define ClearZipSSL(x) ((x)->flags &= ~FLAG_ZIPSSL)
155
156 #define NO_WAIT 0x0
157 #define WAIT_PLAIN 0x1
158
159 #define HASH_WALK_SAFE(i, max, ptr, next, table) for(i = 0; i < max; i++) { RB_DLINK_FOREACH_SAFE(ptr, next, table[i].head)
160 #define HASH_WALK_END }
161 #define CONN_HASH_SIZE 2000
162 #define connid_hash(x) (&connid_hash_table[(x % CONN_HASH_SIZE)])
163
164
165
166 static rb_dlink_list connid_hash_table[CONN_HASH_SIZE];
167 static rb_dlink_list dead_list;
168
169 static void conn_mod_read_cb(rb_fde_t *fd, void *data);
170 static void conn_mod_write_sendq(rb_fde_t *, void *data);
171 static void conn_plain_write_sendq(rb_fde_t *, void *data);
172 static void mod_write_ctl(rb_fde_t *, void *data);
173 static void conn_plain_read_cb(rb_fde_t *fd, void *data);
174 static void mod_cmd_write_queue(mod_ctl_t * ctl, const void *data, size_t len);
175 static const char *remote_closed = "Remote host closed the connection";
176 static int ssl_ok;
177 #ifdef HAVE_LIBZ
178 static int zlib_ok = 1;
179 #else
180 static int zlib_ok = 0;
181 #endif
182
183
184 #ifdef HAVE_LIBZ
185 static void *
186 ssld_alloc(void *unused, size_t count, size_t size)
187 {
188 return rb_malloc(count * size);
189 }
190
191 static void
192 ssld_free(void *unused, void *ptr)
193 {
194 rb_free(ptr);
195 }
196 #endif
197
198 static conn_t *
199 conn_find_by_id(int32_t id)
200 {
201 rb_dlink_node *ptr;
202 conn_t *conn;
203
204 RB_DLINK_FOREACH(ptr, (connid_hash(id))->head)
205 {
206 conn = ptr->data;
207 if(conn->id == id && !IsDead(conn))
208 return conn;
209 }
210 return NULL;
211 }
212
213 static void
214 conn_add_id_hash(conn_t * conn, int32_t id)
215 {
216 conn->id = id;
217 rb_dlinkAdd(conn, &conn->node, connid_hash(id));
218 }
219
220 static void
221 free_conn(conn_t * conn)
222 {
223 rb_free_rawbuffer(conn->modbuf_out);
224 rb_free_rawbuffer(conn->plainbuf_out);
225 #ifdef HAVE_LIBZ
226 if(IsZip(conn))
227 {
228 zlib_stream_t *stream = conn->stream;
229 inflateEnd(&stream->instream);
230 deflateEnd(&stream->outstream);
231 }
232 #endif
233 rb_free(conn);
234 }
235
236 static void
237 clean_dead_conns(void *unused)
238 {
239 conn_t *conn;
240 rb_dlink_node *ptr, *next;
241 RB_DLINK_FOREACH_SAFE(ptr, next, dead_list.head)
242 {
243 conn = ptr->data;
244 free_conn(conn);
245 }
246 dead_list.tail = dead_list.head = NULL;
247 }
248
249
250 static void
251 close_conn(conn_t * conn, int wait_plain, const char *fmt, ...)
252 {
253 va_list ap;
254 char reason[128]; /* must always be under 250 bytes */
255 char buf[256];
256 int len;
257 if(IsDead(conn))
258 return;
259
260 rb_rawbuf_flush(conn->modbuf_out, conn->mod_fd);
261 rb_rawbuf_flush(conn->plainbuf_out, conn->plain_fd);
262 rb_close(conn->mod_fd);
263 SetDead(conn);
264
265 if(!wait_plain || fmt == NULL)
266 {
267 rb_close(conn->plain_fd);
268
269 if(conn->id >= 0 && !IsZipSSL(conn))
270 rb_dlinkDelete(&conn->node, connid_hash(conn->id));
271 rb_dlinkAdd(conn, &conn->node, &dead_list);
272 return;
273 }
274 rb_setselect(conn->plain_fd, RB_SELECT_WRITE | RB_SELECT_READ, NULL, NULL);
275 va_start(ap, fmt);
276 rb_vsnprintf(reason, sizeof(reason), fmt, ap);
277 va_end(ap);
278
279 buf[0] = 'D';
280 int32_to_buf(&buf[1], conn->id);
281 strcpy(&buf[5], reason);
282 len = (strlen(reason) + 1) + 5;
283 mod_cmd_write_queue(conn->ctl, buf, len);
284 }
285
286 static conn_t *
287 make_conn(mod_ctl_t * ctl, rb_fde_t *mod_fd, rb_fde_t *plain_fd)
288 {
289 conn_t *conn = rb_malloc(sizeof(conn_t));
290 conn->ctl = ctl;
291 conn->modbuf_out = rb_new_rawbuffer();
292 conn->plainbuf_out = rb_new_rawbuffer();
293 conn->mod_fd = mod_fd;
294 conn->plain_fd = plain_fd;
295 conn->id = -1;
296 conn->stream = NULL;
297 rb_set_nb(mod_fd);
298 rb_set_nb(plain_fd);
299 return conn;
300 }
301
302 static void
303 check_handshake_flood(void *unused)
304 {
305 conn_t *conn;
306 rb_dlink_node *ptr, *next;
307 unsigned int count;
308 int i;
309 HASH_WALK_SAFE(i, CONN_HASH_SIZE, ptr, next, connid_hash_table)
310 {
311 conn = ptr->data;
312 if(!IsSSL(conn))
313 continue;
314
315 count = rb_ssl_handshake_count(conn->mod_fd);
316 /* nothing needs to do this more than twice in ten seconds i don't think */
317 if(count > 2)
318 close_conn(conn, WAIT_PLAIN, "Handshake flooding");
319 else
320 rb_ssl_clear_handshake_count(conn->mod_fd);
321 }
322 HASH_WALK_END}
323
324 static void
325 conn_mod_write_sendq(rb_fde_t *fd, void *data)
326 {
327 conn_t *conn = data;
328 const char *err;
329 int retlen;
330 if(IsDead(conn))
331 return;
332
333 if(IsSSLWWantsR(conn))
334 {
335 ClearSSLWWantsR(conn);
336 conn_mod_read_cb(conn->mod_fd, conn);
337 if(IsDead(conn))
338 return;
339 }
340
341 while((retlen = rb_rawbuf_flush(conn->modbuf_out, fd)) > 0)
342 conn->mod_out += retlen;
343
344 if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
345 {
346 if(retlen == 0)
347 close_conn(conn, WAIT_PLAIN, "%s", remote_closed);
348 if(IsSSL(conn) && retlen == RB_RW_SSL_ERROR)
349 err = rb_get_ssl_strerror(conn->mod_fd);
350 else
351 err = strerror(errno);
352 close_conn(conn, WAIT_PLAIN, "Write error: %s", err);
353 return;
354 }
355 if(rb_rawbuf_length(conn->modbuf_out) > 0)
356 {
357 if(retlen != RB_RW_SSL_NEED_READ)
358 rb_setselect(conn->mod_fd, RB_SELECT_WRITE, conn_mod_write_sendq, conn);
359 else
360 {
361 rb_setselect(conn->mod_fd, RB_SELECT_READ, conn_mod_write_sendq, conn);
362 rb_setselect(conn->mod_fd, RB_SELECT_WRITE, NULL, NULL);
363 SetSSLWWantsR(conn);
364 }
365 }
366 else
367 rb_setselect(conn->mod_fd, RB_SELECT_WRITE, NULL, NULL);
368
369 if(IsCork(conn) && rb_rawbuf_length(conn->modbuf_out) == 0)
370 {
371 ClearCork(conn);
372 conn_plain_read_cb(conn->plain_fd, conn);
373 }
374
375 }
376
377 static void
378 conn_mod_write(conn_t * conn, void *data, size_t len)
379 {
380 if(IsDead(conn)) /* no point in queueing to a dead man */
381 return;
382 rb_rawbuf_append(conn->modbuf_out, data, len);
383 }
384
385 static void
386 conn_plain_write(conn_t * conn, void *data, size_t len)
387 {
388 if(IsDead(conn)) /* again no point in queueing to dead men */
389 return;
390 rb_rawbuf_append(conn->plainbuf_out, data, len);
391 }
392
393 static void
394 mod_cmd_write_queue(mod_ctl_t * ctl, const void *data, size_t len)
395 {
396 mod_ctl_buf_t *ctl_buf;
397 ctl_buf = rb_malloc(sizeof(mod_ctl_buf_t));
398 ctl_buf->buf = rb_malloc(len);
399 ctl_buf->buflen = len;
400 memcpy(ctl_buf->buf, data, len);
401 ctl_buf->nfds = 0;
402 rb_dlinkAddTail(ctl_buf, &ctl_buf->node, &ctl->writeq);
403 mod_write_ctl(ctl->F, ctl);
404 }
405
406 #ifdef HAVE_LIBZ
407 static void
408 common_zlib_deflate(conn_t * conn, void *buf, size_t len)
409 {
410 int ret, have;
411 z_stream *outstream = &((zlib_stream_t *) conn->stream)->outstream;
412 outstream->next_in = buf;
413 outstream->avail_in = len;
414 outstream->next_out = (Bytef *) outbuf;
415 outstream->avail_out = sizeof(outbuf);
416
417 ret = deflate(outstream, Z_SYNC_FLUSH);
418 if(ret != Z_OK)
419 {
420 /* deflate error */
421 close_conn(conn, WAIT_PLAIN, "Deflate failed: %s", zError(ret));
422 return;
423 }
424 if(outstream->avail_out == 0)
425 {
426 /* avail_out empty */
427 close_conn(conn, WAIT_PLAIN, "error compressing data, avail_out == 0");
428 return;
429 }
430 if(outstream->avail_in != 0)
431 {
432 /* avail_in isn't empty... */
433 close_conn(conn, WAIT_PLAIN, "error compressing data, avail_in != 0");
434 return;
435 }
436 have = sizeof(outbuf) - outstream->avail_out;
437 conn_mod_write(conn, outbuf, have);
438 }
439
440 static void
441 common_zlib_inflate(conn_t * conn, void *buf, size_t len)
442 {
443 int ret, have = 0;
444 ((zlib_stream_t *) conn->stream)->instream.next_in = buf;
445 ((zlib_stream_t *) conn->stream)->instream.avail_in = len;
446 ((zlib_stream_t *) conn->stream)->instream.next_out = (Bytef *) outbuf;
447 ((zlib_stream_t *) conn->stream)->instream.avail_out = sizeof(outbuf);
448
449 while(((zlib_stream_t *) conn->stream)->instream.avail_in)
450 {
451 ret = inflate(&((zlib_stream_t *) conn->stream)->instream, Z_NO_FLUSH);
452 if(ret != Z_OK)
453 {
454 if(!strncmp("ERROR ", buf, 6))
455 {
456 close_conn(conn, WAIT_PLAIN, "Received uncompressed ERROR");
457 return;
458 }
459 close_conn(conn, WAIT_PLAIN, "Inflate failed: %s", zError(ret));
460 return;
461 }
462 have = sizeof(outbuf) - ((zlib_stream_t *) conn->stream)->instream.avail_out;
463
464 if(((zlib_stream_t *) conn->stream)->instream.avail_in)
465 {
466 conn_plain_write(conn, outbuf, have);
467 have = 0;
468 ((zlib_stream_t *) conn->stream)->instream.next_out = (Bytef *) outbuf;
469 ((zlib_stream_t *) conn->stream)->instream.avail_out = sizeof(outbuf);
470 }
471 }
472 if(have == 0)
473 return;
474
475 conn_plain_write(conn, outbuf, have);
476 }
477 #endif
478
479 static int
480 plain_check_cork(conn_t * conn)
481 {
482 if(rb_rawbuf_length(conn->modbuf_out) >= 4096)
483 {
484 /* if we have over 4k pending outbound, don't read until
485 * we've cleared the queue */
486 SetCork(conn);
487 rb_setselect(conn->plain_fd, RB_SELECT_READ, NULL, NULL);
488 /* try to write */
489 conn_mod_write_sendq(conn->mod_fd, conn);
490 return 1;
491 }
492 return 0;
493 }
494
495
496 static void
497 conn_plain_read_cb(rb_fde_t *fd, void *data)
498 {
499 conn_t *conn = data;
500 int length = 0;
501 if(conn == NULL)
502 return;
503
504 if(IsDead(conn))
505 return;
506
507 if(plain_check_cork(conn))
508 return;
509
510 while(1)
511 {
512 if(IsDead(conn))
513 return;
514
515 length = rb_read(conn->plain_fd, inbuf, sizeof(inbuf));
516
517 if(length == 0 || (length < 0 && !rb_ignore_errno(errno)))
518 {
519 close_conn(conn, NO_WAIT, NULL);
520 return;
521 }
522
523 if(length < 0)
524 {
525 rb_setselect(conn->plain_fd, RB_SELECT_READ, conn_plain_read_cb, conn);
526 conn_mod_write_sendq(conn->mod_fd, conn);
527 return;
528 }
529 conn->plain_in += length;
530
531 #ifdef HAVE_LIBZ
532 if(IsZip(conn))
533 common_zlib_deflate(conn, inbuf, length);
534 else
535 #endif
536 conn_mod_write(conn, inbuf, length);
537 if(IsDead(conn))
538 return;
539 if(plain_check_cork(conn))
540 return;
541 }
542 }
543
544 static void
545 conn_mod_read_cb(rb_fde_t *fd, void *data)
546 {
547 conn_t *conn = data;
548 const char *err = remote_closed;
549 int length;
550 if(conn == NULL)
551 return;
552 if(IsDead(conn))
553 return;
554
555 if(IsSSLRWantsW(conn))
556 {
557 ClearSSLRWantsW(conn);
558 conn_mod_write_sendq(conn->mod_fd, conn);
559 if(IsDead(conn))
560 return;
561 }
562
563 while(1)
564 {
565 if(IsDead(conn))
566 return;
567
568 length = rb_read(conn->mod_fd, inbuf, sizeof(inbuf));
569
570 if(length == 0 || (length < 0 && !rb_ignore_errno(errno)))
571 {
572 if(length == 0)
573 {
574 close_conn(conn, WAIT_PLAIN, "%s", remote_closed);
575 return;
576 }
577
578 if(IsSSL(conn) && length == RB_RW_SSL_ERROR)
579 err = rb_get_ssl_strerror(conn->mod_fd);
580 else
581 err = strerror(errno);
582 close_conn(conn, WAIT_PLAIN, "Read error: %s", err);
583 return;
584 }
585 if(length < 0)
586 {
587 if(length != RB_RW_SSL_NEED_WRITE)
588 rb_setselect(conn->mod_fd, RB_SELECT_READ, conn_mod_read_cb, conn);
589 else
590 {
591 rb_setselect(conn->mod_fd, RB_SELECT_READ, NULL, NULL);
592 rb_setselect(conn->mod_fd, RB_SELECT_WRITE, conn_mod_read_cb, conn);
593 SetSSLRWantsW(conn);
594 }
595 conn_plain_write_sendq(conn->plain_fd, conn);
596 return;
597 }
598 conn->mod_in += length;
599 #ifdef HAVE_LIBZ
600 if(IsZip(conn))
601 common_zlib_inflate(conn, inbuf, length);
602 else
603 #endif
604 conn_plain_write(conn, inbuf, length);
605 }
606 }
607
608 static void
609 conn_plain_write_sendq(rb_fde_t *fd, void *data)
610 {
611 conn_t *conn = data;
612 int retlen;
613
614 if(IsDead(conn))
615 return;
616
617 while((retlen = rb_rawbuf_flush(conn->plainbuf_out, fd)) > 0)
618 {
619 conn->plain_out += retlen;
620 }
621 if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
622 {
623 close_conn(data, NO_WAIT, NULL);
624 return;
625 }
626
627
628 if(rb_rawbuf_length(conn->plainbuf_out) > 0)
629 rb_setselect(conn->plain_fd, RB_SELECT_WRITE, conn_plain_write_sendq, conn);
630 else
631 rb_setselect(conn->plain_fd, RB_SELECT_WRITE, NULL, NULL);
632 }
633
634 static int
635 maxconn(void)
636 {
637 #if defined(RLIMIT_NOFILE) && defined(HAVE_SYS_RESOURCE_H)
638 struct rlimit limit;
639
640 if(!getrlimit(RLIMIT_NOFILE, &limit))
641 {
642 return limit.rlim_cur;
643 }
644 #endif /* RLIMIT_FD_MAX */
645 return MAXCONNECTIONS;
646 }
647
648 static void
649 ssl_process_accept_cb(rb_fde_t *F, int status, struct sockaddr *addr, rb_socklen_t len, void *data)
650 {
651 conn_t *conn = data;
652 if(status == RB_OK)
653 {
654 conn_mod_read_cb(conn->mod_fd, conn);
655 conn_plain_read_cb(conn->plain_fd, conn);
656 return;
657 }
658 /* ircd doesn't care about the reason for this */
659 close_conn(conn, NO_WAIT, 0);
660 return;
661 }
662
663 static void
664 ssl_process_connect_cb(rb_fde_t *F, int status, void *data)
665 {
666 conn_t *conn = data;
667 if(status == RB_OK)
668 {
669 conn_mod_read_cb(conn->mod_fd, conn);
670 conn_plain_read_cb(conn->plain_fd, conn);
671 }
672 else if(status == RB_ERR_TIMEOUT)
673 close_conn(conn, WAIT_PLAIN, "SSL handshake timed out");
674 else if(status == RB_ERROR_SSL)
675 close_conn(conn, WAIT_PLAIN, "%s", rb_get_ssl_strerror(conn->mod_fd));
676 else
677 close_conn(conn, WAIT_PLAIN, "SSL handshake failed");
678 }
679
680
681 static void
682 ssl_process_accept(mod_ctl_t * ctl, mod_ctl_buf_t * ctlb)
683 {
684 conn_t *conn;
685 int32_t id;
686
687 conn = make_conn(ctl, ctlb->F[0], ctlb->F[1]);
688
689 id = buf_to_int32(&ctlb->buf[1]);
690
691 if(id >= 0)
692 conn_add_id_hash(conn, id);
693 SetSSL(conn);
694
695 if(rb_get_type(conn->mod_fd) & RB_FD_UNKNOWN)
696 {
697
698 rb_set_type(conn->mod_fd, RB_FD_SOCKET);
699 }
700 if(rb_get_type(conn->mod_fd) == RB_FD_UNKNOWN)
701 rb_set_type(conn->plain_fd, RB_FD_SOCKET);
702
703 rb_ssl_start_accepted(ctlb->F[0], ssl_process_accept_cb, conn, 10);
704 }
705
706 static void
707 ssl_process_connect(mod_ctl_t * ctl, mod_ctl_buf_t * ctlb)
708 {
709 conn_t *conn;
710 int32_t id;
711 conn = make_conn(ctl, ctlb->F[0], ctlb->F[1]);
712
713 id = buf_to_int32(&ctlb->buf[1]);
714
715 if(id >= 0)
716 conn_add_id_hash(conn, id);
717 SetSSL(conn);
718
719 if(rb_get_type(conn->mod_fd) == RB_FD_UNKNOWN)
720 rb_set_type(conn->mod_fd, RB_FD_SOCKET);
721
722 if(rb_get_type(conn->mod_fd) == RB_FD_UNKNOWN)
723 rb_set_type(conn->plain_fd, RB_FD_SOCKET);
724
725
726 rb_ssl_start_connected(ctlb->F[0], ssl_process_connect_cb, conn, 10);
727 }
728
729 static void
730 process_stats(mod_ctl_t * ctl, mod_ctl_buf_t * ctlb)
731 {
732 char outstat[512];
733 conn_t *conn;
734 const char *odata;
735 int32_t id;
736
737 id = buf_to_int32(&ctlb->buf[1]);
738
739 if(id < 0)
740 return;
741
742 odata = &ctlb->buf[5];
743 conn = conn_find_by_id(id);
744
745 if(conn == NULL)
746 return;
747
748 rb_snprintf(outstat, sizeof(outstat), "S %s %llu %llu %llu %llu", odata,
749 conn->plain_out, conn->mod_in, conn->plain_in, conn->mod_out);
750 conn->plain_out = 0;
751 conn->plain_in = 0;
752 conn->mod_in = 0;
753 conn->mod_out = 0;
754 mod_cmd_write_queue(ctl, outstat, strlen(outstat) + 1); /* +1 is so we send the \0 as well */
755 }
756
757 static void
758 change_connid(mod_ctl_t *ctl, mod_ctl_buf_t *ctlb)
759 {
760 int32_t id = buf_to_int32(&ctlb->buf[1]);
761 int32_t newid = buf_to_int32(&ctlb->buf[5]);
762 conn_t *conn = conn_find_by_id(id);
763 if(conn->id >= 0)
764 rb_dlinkDelete(&conn->node, connid_hash(conn->id));
765 SetZipSSL(conn);
766 conn->id = newid;
767 }
768
769 #ifdef HAVE_LIBZ
770 static void
771 zlib_process(mod_ctl_t * ctl, mod_ctl_buf_t * ctlb)
772 {
773 uint8_t level;
774 size_t recvqlen;
775 size_t hdr = (sizeof(uint8_t) * 2) + sizeof(int32_t);
776 void *recvq_start;
777 z_stream *instream, *outstream;
778 conn_t *conn;
779 int32_t id;
780
781 conn = make_conn(ctl, ctlb->F[0], ctlb->F[1]);
782 if(rb_get_type(conn->mod_fd) == RB_FD_UNKNOWN)
783 rb_set_type(conn->mod_fd, RB_FD_SOCKET);
784
785 if(rb_get_type(conn->plain_fd) == RB_FD_UNKNOWN)
786 rb_set_type(conn->plain_fd, RB_FD_SOCKET);
787
788 id = buf_to_int32(&ctlb->buf[1]);
789 conn_add_id_hash(conn, id);
790
791 level = (uint8_t)ctlb->buf[5];
792
793 recvqlen = ctlb->buflen - hdr;
794 recvq_start = &ctlb->buf[6];
795
796 SetZip(conn);
797 conn->stream = rb_malloc(sizeof(zlib_stream_t));
798 instream = &((zlib_stream_t *) conn->stream)->instream;
799 outstream = &((zlib_stream_t *) conn->stream)->outstream;
800
801 instream->total_in = 0;
802 instream->total_out = 0;
803 instream->zalloc = (alloc_func) ssld_alloc;
804 instream->zfree = (free_func) ssld_free;
805 instream->data_type = Z_ASCII;
806 inflateInit(&((zlib_stream_t *) conn->stream)->instream);
807
808 outstream->total_in = 0;
809 outstream->total_out = 0;
810 outstream->zalloc = (alloc_func) ssld_alloc;
811 outstream->zfree = (free_func) ssld_free;
812 outstream->data_type = Z_ASCII;
813
814 if(level > 9)
815 level = Z_DEFAULT_COMPRESSION;
816
817 deflateInit(&((zlib_stream_t *) conn->stream)->outstream, level);
818 if(recvqlen > 0)
819 common_zlib_inflate(conn, recvq_start, recvqlen);
820
821 conn_mod_read_cb(conn->mod_fd, conn);
822 conn_plain_read_cb(conn->plain_fd, conn);
823 return;
824
825 }
826 #endif
827
828 static void
829 init_prng(mod_ctl_t * ctl, mod_ctl_buf_t * ctl_buf)
830 {
831 char *path;
832 prng_seed_t seed_type;
833
834 seed_type = (prng_seed_t) ctl_buf->buf[1];
835 path = &ctl_buf->buf[2];
836 rb_init_prng(path, seed_type);
837 }
838
839
840 static void
841 ssl_new_keys(mod_ctl_t * ctl, mod_ctl_buf_t * ctl_buf)
842 {
843 char *buf;
844 char *cert, *key, *dhparam;
845
846 buf = &ctl_buf->buf[2];
847 cert = buf;
848 buf += strlen(cert) + 1;
849 key = buf;
850 buf += strlen(key) + 1;
851 dhparam = buf;
852 if(strlen(dhparam) == 0)
853 dhparam = NULL;
854
855 if(!rb_setup_ssl_server(cert, key, dhparam))
856 {
857 const char *invalid = "I";
858 mod_cmd_write_queue(ctl, invalid, strlen(invalid));
859 return;
860 }
861 }
862
863 static void
864 send_nossl_support(mod_ctl_t * ctl, mod_ctl_buf_t * ctlb)
865 {
866 static const char *nossl_cmd = "N";
867 conn_t *conn;
868 int32_t id;
869
870 if(ctlb != NULL)
871 {
872 conn = make_conn(ctl, ctlb->F[0], ctlb->F[1]);
873 id = buf_to_int32(&ctlb->buf[1]);
874
875 if(id >= 0)
876 conn_add_id_hash(conn, id);
877 close_conn(conn, WAIT_PLAIN, "libratbox reports no SSL/TLS support");
878 }
879 mod_cmd_write_queue(ctl, nossl_cmd, strlen(nossl_cmd));
880 }
881
882 static void
883 send_i_am_useless(mod_ctl_t * ctl)
884 {
885 static const char *useless = "U";
886 mod_cmd_write_queue(ctl, useless, strlen(useless));
887 }
888
889 static void
890 send_nozlib_support(mod_ctl_t * ctl, mod_ctl_buf_t * ctlb)
891 {
892 static const char *nozlib_cmd = "z";
893 conn_t *conn;
894 int32_t id;
895 if(ctlb != NULL)
896 {
897 conn = make_conn(ctl, ctlb->F[0], ctlb->F[1]);
898 id = buf_to_int32(&ctlb->buf[1]);
899
900 if(id >= 0)
901 conn_add_id_hash(conn, id);
902 close_conn(conn, WAIT_PLAIN, "libratbox reports no zlib support");
903 }
904 mod_cmd_write_queue(ctl, nozlib_cmd, strlen(nozlib_cmd));
905 }
906
907 static void
908 mod_process_cmd_recv(mod_ctl_t * ctl)
909 {
910 rb_dlink_node *ptr, *next;
911 mod_ctl_buf_t *ctl_buf;
912
913 RB_DLINK_FOREACH_SAFE(ptr, next, ctl->readq.head)
914 {
915 ctl_buf = ptr->data;
916
917 switch (*ctl_buf->buf)
918 {
919 case 'A':
920 {
921 if(!ssl_ok)
922 {
923 send_nossl_support(ctl, ctl_buf);
924 break;
925 }
926 ssl_process_accept(ctl, ctl_buf);
927 break;
928 }
929 case 'C':
930 {
931 if(!ssl_ok)
932 {
933 send_nossl_support(ctl, ctl_buf);
934 break;
935 }
936 ssl_process_connect(ctl, ctl_buf);
937 break;
938 }
939
940 case 'K':
941 {
942 if(!ssl_ok)
943 {
944 send_nossl_support(ctl, ctl_buf);
945 break;
946 }
947 ssl_new_keys(ctl, ctl_buf);
948 break;
949 }
950 case 'I':
951 init_prng(ctl, ctl_buf);
952 break;
953 case 'S':
954 {
955 process_stats(ctl, ctl_buf);
956 break;
957 }
958 case 'Y':
959 {
960 change_connid(ctl, ctl_buf);
961 break;
962 }
963
964 #ifdef HAVE_LIBZ
965 case 'Z':
966 {
967 /* just zlib only */
968 zlib_process(ctl, ctl_buf);
969 break;
970 }
971 #else
972
973 case 'Z':
974 send_nozlib_support(ctl, ctl_buf);
975 break;
976
977 #endif
978 default:
979 break;
980 /* Log unknown commands */
981 }
982 rb_dlinkDelete(ptr, &ctl->readq);
983 rb_free(ctl_buf->buf);
984 rb_free(ctl_buf);
985 }
986
987 }
988
989
990
991 static void
992 mod_read_ctl(rb_fde_t *F, void *data)
993 {
994 mod_ctl_buf_t *ctl_buf;
995 mod_ctl_t *ctl = data;
996 int retlen;
997
998 do
999 {
1000 ctl_buf = rb_malloc(sizeof(mod_ctl_buf_t));
1001 ctl_buf->buf = rb_malloc(READBUF_SIZE);
1002 ctl_buf->buflen = READBUF_SIZE;
1003 retlen = rb_recv_fd_buf(ctl->F, ctl_buf->buf, ctl_buf->buflen, ctl_buf->F,
1004 MAXPASSFD);
1005 if(retlen <= 0)
1006 {
1007 rb_free(ctl_buf->buf);
1008 rb_free(ctl_buf);
1009 }
1010 else
1011 {
1012 ctl_buf->buflen = retlen;
1013 rb_dlinkAddTail(ctl_buf, &ctl_buf->node, &ctl->readq);
1014 }
1015 }
1016 while(retlen > 0);
1017
1018 if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
1019 exit(0);
1020
1021 mod_process_cmd_recv(ctl);
1022 rb_setselect(ctl->F, RB_SELECT_READ, mod_read_ctl, ctl);
1023 }
1024
1025 static void
1026 mod_write_ctl(rb_fde_t *F, void *data)
1027 {
1028 mod_ctl_t *ctl = data;
1029 mod_ctl_buf_t *ctl_buf;
1030 rb_dlink_node *ptr, *next;
1031 int retlen, x;
1032
1033 RB_DLINK_FOREACH_SAFE(ptr, next, ctl->writeq.head)
1034 {
1035 ctl_buf = ptr->data;
1036 retlen = rb_send_fd_buf(ctl->F, ctl_buf->F, ctl_buf->nfds, ctl_buf->buf,
1037 ctl_buf->buflen, ppid);
1038 if(retlen > 0)
1039 {
1040 rb_dlinkDelete(ptr, &ctl->writeq);
1041 for(x = 0; x < ctl_buf->nfds; x++)
1042 rb_close(ctl_buf->F[x]);
1043 rb_free(ctl_buf->buf);
1044 rb_free(ctl_buf);
1045
1046 }
1047 if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
1048 exit(0);
1049
1050 }
1051 if(rb_dlink_list_length(&ctl->writeq) > 0)
1052 rb_setselect(ctl->F, RB_SELECT_WRITE, mod_write_ctl, ctl);
1053 }
1054
1055
1056 static void
1057 read_pipe_ctl(rb_fde_t *F, void *data)
1058 {
1059 int retlen;
1060 while((retlen = rb_read(F, inbuf, sizeof(inbuf))) > 0)
1061 {
1062 ;; /* we don't do anything with the pipe really, just care if the other process dies.. */
1063 }
1064 if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
1065 exit(0);
1066 rb_setselect(F, RB_SELECT_READ, read_pipe_ctl, NULL);
1067
1068 }
1069
1070 int
1071 main(int argc, char **argv)
1072 {
1073 const char *s_ctlfd, *s_pipe, *s_pid;
1074 int ctlfd, pipefd, x, maxfd;
1075 maxfd = maxconn();
1076
1077 s_ctlfd = getenv("CTL_FD");
1078 s_pipe = getenv("CTL_PIPE");
1079 s_pid = getenv("CTL_PPID");
1080
1081 if(s_ctlfd == NULL || s_pipe == NULL || s_pid == NULL)
1082 {
1083 fprintf(stderr,
1084 "This is ircd-ratbox ssld. You know you aren't supposed to run me directly?\n");
1085 fprintf(stderr,
1086 "You get an Id tag for this: $Id$\n");
1087 fprintf(stderr, "Have a nice life\n");
1088 exit(1);
1089 }
1090
1091 ctlfd = atoi(s_ctlfd);
1092 pipefd = atoi(s_pipe);
1093 ppid = atoi(s_pid);
1094 x = 0;
1095 #ifndef _WIN32
1096 for(x = 0; x < maxfd; x++)
1097 {
1098 if(x != ctlfd && x != pipefd && x > 2)
1099 close(x);
1100 }
1101 x = open("/dev/null", O_RDWR);
1102
1103 if(x >= 0)
1104 {
1105 if(ctlfd != 0 && pipefd != 0)
1106 dup2(x, 0);
1107 if(ctlfd != 1 && pipefd != 1)
1108 dup2(x, 1);
1109 if(ctlfd != 2 && pipefd != 2)
1110 dup2(x, 2);
1111 if(x > 2)
1112 close(x);
1113 }
1114 #endif
1115 setup_signals();
1116 rb_lib_init(NULL, NULL, NULL, 0, maxfd, 1024, 4096);
1117 rb_init_rawbuffers(1024);
1118 ssl_ok = rb_supports_ssl();
1119 mod_ctl = rb_malloc(sizeof(mod_ctl_t));
1120 mod_ctl->F = rb_open(ctlfd, RB_FD_SOCKET, "ircd control socket");
1121 mod_ctl->F_pipe = rb_open(pipefd, RB_FD_PIPE, "ircd pipe");
1122 rb_set_nb(mod_ctl->F);
1123 rb_set_nb(mod_ctl->F_pipe);
1124 rb_event_addish("clean_dead_conns", clean_dead_conns, NULL, 10);
1125 rb_event_add("check_handshake_flood", check_handshake_flood, NULL, 10);
1126 read_pipe_ctl(mod_ctl->F_pipe, NULL);
1127 mod_read_ctl(mod_ctl->F, mod_ctl);
1128 if(!zlib_ok && !ssl_ok)
1129 {
1130 /* this is really useless... */
1131 send_i_am_useless(mod_ctl);
1132 /* sleep until the ircd kills us */
1133 rb_sleep(2 << 30, 0);
1134 exit(1);
1135 }
1136
1137 if(!zlib_ok)
1138 send_nozlib_support(mod_ctl, NULL);
1139 if(!ssl_ok)
1140 send_nossl_support(mod_ctl, NULL);
1141 rb_lib_loop(0);
1142 return 0;
1143 }
1144
1145
1146 #ifndef _WIN32
1147 static void
1148 dummy_handler(int sig)
1149 {
1150 return;
1151 }
1152 #endif
1153
1154 static void
1155 setup_signals()
1156 {
1157 #ifndef _WIN32
1158 struct sigaction act;
1159
1160 act.sa_flags = 0;
1161 act.sa_handler = SIG_IGN;
1162 sigemptyset(&act.sa_mask);
1163 sigaddset(&act.sa_mask, SIGPIPE);
1164 sigaddset(&act.sa_mask, SIGALRM);
1165 #ifdef SIGTRAP
1166 sigaddset(&act.sa_mask, SIGTRAP);
1167 #endif
1168
1169 #ifdef SIGWINCH
1170 sigaddset(&act.sa_mask, SIGWINCH);
1171 sigaction(SIGWINCH, &act, 0);
1172 #endif
1173 sigaction(SIGPIPE, &act, 0);
1174 #ifdef SIGTRAP
1175 sigaction(SIGTRAP, &act, 0);
1176 #endif
1177
1178 act.sa_handler = dummy_handler;
1179 sigaction(SIGALRM, &act, 0);
1180 #endif
1181 }