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