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