1 /*
2  *  sslproc.c: An interface to ssld
3  *  Copyright (C) 2007 Aaron Sethman <androsyn@ratbox.org>
4  *  Copyright (C) 2007-2012 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: sslproc.c 28755 2015-10-13 14:48:47Z androsyn $
22  */
23 
24 #include <ratbox_lib.h>
25 #include "stdinc.h"
26 
27 
28 #include "s_conf.h"
29 #include "s_log.h"
30 #include "listener.h"
31 #include "struct.h"
32 #include "sslproc.h"
33 #include "s_serv.h"
34 #include "ircd.h"
35 #include "hash.h"
36 #include "client.h"
37 #include "send.h"
38 #include "packet.h"
39 
40 #define ZIPSTATS_TIME           60
41 
42 static void collect_zipstats(void *unused);
43 static void ssl_read_ctl(rb_fde_t *F, void *data);
44 static int ssld_count;
45 
46 static char tmpbuf[READBUF_SIZE];
47 static char nul = '\0';
48 
49 #define MAXPASSFD 4
50 #define READSIZE 1024
51 typedef struct _ssl_ctl_buf
52 {
53 	rb_dlink_node node;
54 	char *buf;
55 	size_t buflen;
56 	rb_fde_t *F[MAXPASSFD];
57 	int nfds;
58 } ssl_ctl_buf_t;
59 
60 
61 struct _ssl_ctl
62 {
63 	rb_dlink_node node;
64 	int cli_count;
65 	rb_fde_t *F;
66 	rb_fde_t *P;
67 	pid_t pid;
68 	rb_dlink_list readq;
69 	rb_dlink_list writeq;
70 	uint8_t dead;
71 };
72 
73 static void send_new_ssl_certs_one(ssl_ctl_t * ctl, const char *ssl_cert,
74 				   const char *ssl_private_key, const char *ssl_dh_params);
75 static void send_init_prng(ssl_ctl_t * ctl, prng_seed_t seedtype, const char *path);
76 
77 
78 static rb_dlink_list ssl_daemons;
79 
80 static inline int32_t
buf_to_int32(char * buf)81 buf_to_int32(char *buf)
82 {
83 	int32_t x;
84 	memcpy(&x, buf, sizeof(x));
85 	return x;
86 }
87 
88 static inline void
int32_to_buf(char * buf,int32_t x)89 int32_to_buf(char *buf, int32_t x)
90 {
91 	memcpy(buf, &x, sizeof(x));
92 	return;
93 }
94 
95 
96 static inline uint16_t
buf_to_uint16(char * buf)97 buf_to_uint16(char *buf)
98 {
99 	uint16_t x;
100 	memcpy(&x, buf, sizeof(x));
101 	return x;
102 }
103 
104 static inline void
uint16_to_buf(char * buf,uint16_t x)105 uint16_to_buf(char *buf, uint16_t x)
106 {
107 	memcpy(buf, &x, sizeof(x));
108 	return;
109 }
110 
111 
112 static ssl_ctl_t *
allocate_ssl_daemon(rb_fde_t * F,rb_fde_t * P,int pid)113 allocate_ssl_daemon(rb_fde_t *F, rb_fde_t *P, int pid)
114 {
115 	ssl_ctl_t *ctl;
116 
117 	if(F == NULL || pid < 0)
118 		return NULL;
119 	ctl = rb_malloc(sizeof(ssl_ctl_t));
120 	ctl->F = F;
121 	ctl->P = P;
122 	ctl->pid = pid;
123 	ssld_count++;
124 	rb_dlinkAdd(ctl, &ctl->node, &ssl_daemons);
125 	return ctl;
126 }
127 
128 static void
free_ssl_daemon(ssl_ctl_t * ctl)129 free_ssl_daemon(ssl_ctl_t * ctl)
130 {
131 	rb_dlink_node *ptr;
132 	ssl_ctl_buf_t *ctl_buf;
133 	int x;
134 	if(ctl->cli_count)
135 		return;
136 
137 	RB_DLINK_FOREACH(ptr, ctl->readq.head)
138 	{
139 		ctl_buf = ptr->data;
140 		for(x = 0; x < ctl_buf->nfds; x++)
141 			rb_close(ctl_buf->F[x]);
142 
143 		rb_free(ctl_buf->buf);
144 		rb_free(ctl_buf);
145 	}
146 
147 	RB_DLINK_FOREACH(ptr, ctl->writeq.head)
148 	{
149 		ctl_buf = ptr->data;
150 		for(x = 0; x < ctl_buf->nfds; x++)
151 			rb_close(ctl_buf->F[x]);
152 
153 		rb_free(ctl_buf->buf);
154 		rb_free(ctl_buf);
155 	}
156 	rb_close(ctl->F);
157 	rb_close(ctl->P);
158 	rb_dlinkDelete(&ctl->node, &ssl_daemons);
159 	rb_free(ctl);
160 }
161 
162 static char *ssld_path;
163 
164 static int ssld_spin_count = 0;
165 static time_t last_spin;
166 static int ssld_wait = 0;
167 
168 
169 static void
ssl_killall(void)170 ssl_killall(void)
171 {
172 	rb_dlink_node *ptr, *next;
173 	ssl_ctl_t *ctl;
174 	RB_DLINK_FOREACH_SAFE(ptr, next, ssl_daemons.head)
175 	{
176 		ctl = ptr->data;
177 		if(ctl->dead)
178 			continue;
179 		ctl->dead = 1;
180 		ssld_count--;
181 		rb_kill(ctl->pid, SIGKILL);
182 	}
183 }
184 
185 static void
ssl_dead(ssl_ctl_t * ctl)186 ssl_dead(ssl_ctl_t * ctl)
187 {
188 	if(ctl->dead)
189 		return;
190 
191 	ctl->dead = 1;
192 	ssld_count--;
193 	rb_kill(ctl->pid, SIGKILL);	/* make sure the process is really gone */
194 	ilog(L_MAIN, "ssld helper died - attempting to restart");
195 	sendto_realops_flags(UMODE_ALL, L_ALL, "ssld helper died - attempting to restart");
196 	start_ssldaemon(1, ServerInfo.ssl_cert, ServerInfo.ssl_private_key,
197 			ServerInfo.ssl_dh_params);
198 }
199 
200 static void
ssl_do_pipe(rb_fde_t * F,void * data)201 ssl_do_pipe(rb_fde_t *F, void *data)
202 {
203 	int retlen;
204 	ssl_ctl_t *ctl = data;
205 	retlen = rb_write(F, "0", 1);
206 	if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
207 	{
208 		ssl_dead(ctl);
209 		return;
210 	}
211 	rb_setselect(F, RB_SELECT_READ, ssl_do_pipe, data);
212 }
213 
214 static void
restart_ssld_event(void * unused)215 restart_ssld_event(void *unused)
216 {
217 	ssld_spin_count = 0;
218 	last_spin = 0;
219 	ssld_wait = 0;
220 	if(ServerInfo.ssld_count > get_ssld_count())
221 	{
222 		int start = ServerInfo.ssld_count - get_ssld_count();
223 		ilog(L_MAIN, "Attempting to restart ssld processes");
224 		sendto_realops_flags(UMODE_ALL, L_ALL, "Attempt to restart ssld processes");
225 		start_ssldaemon(start, ServerInfo.ssl_cert, ServerInfo.ssl_private_key,
226 				ServerInfo.ssl_dh_params);
227 	}
228 }
229 
230 int
start_ssldaemon(int count,const char * ssl_cert,const char * ssl_private_key,const char * ssl_dh_params)231 start_ssldaemon(int count, const char *ssl_cert, const char *ssl_private_key,
232 		const char *ssl_dh_params)
233 {
234 	rb_fde_t *F1, *F2;
235 	rb_fde_t *P1, *P2;
236 #ifdef _WIN32
237 	const char *suffix = ".exe";
238 #else
239 	const char *suffix = "";
240 #endif
241 
242 	char fullpath[PATH_MAX + 1];
243 	char fdarg[6];
244 	const char *parv[2];
245 	char buf[128];
246 	char s_pid[10];
247 	pid_t pid;
248 	int started = 0, i;
249 
250 	if(ssld_wait)
251 		return 0;
252 
253 	if(ssld_spin_count > 20 && (rb_current_time() - last_spin < 5))
254 	{
255 		ilog(L_MAIN, "ssld helper is spinning - will attempt to restart in 1 minute");
256 		sendto_realops_flags(UMODE_ALL, L_ALL,
257 				     "ssld helper is spinning - will attempt to restart in 1 minute");
258 		rb_event_add("restart_ssld_event", restart_ssld_event, NULL, 60);
259 		ssld_wait = 1;
260 		return 0;
261 	}
262 
263 	ssld_spin_count++;
264 	last_spin = rb_current_time();
265 	if(ssld_path == NULL)
266 	{
267 		rb_snprintf(fullpath, sizeof(fullpath), "%s/ssld%s", LIBEXEC_DIR, suffix);
268 
269 		if(access(fullpath, X_OK) == -1)
270 		{
271 			rb_snprintf(fullpath, sizeof(fullpath), "%s/libexec/ircd-ratbox/ssld%s",
272 				    ConfigFileEntry.dpath, suffix);
273 			if(access(fullpath, X_OK) == -1)
274 			{
275 				ilog(L_MAIN,
276 				     "Unable to execute ssld%s in %s/libexec/ircd-ratbox or %s",
277 				     ConfigFileEntry.dpath, suffix, LIBEXEC_DIR);
278 				return 0;
279 			}
280 		}
281 		ssld_path = rb_strdup(fullpath);
282 	}
283 	rb_strlcpy(buf, "-ircd ssld daemon helper", sizeof(buf));
284 	parv[0] = buf;
285 	parv[1] = NULL;
286 
287 	for(i = 0; i < count; i++)
288 	{
289 		ssl_ctl_t *ctl;
290 		if(rb_socketpair(AF_UNIX, SOCK_DGRAM, 0, &F1, &F2, "SSL/TLS handle passing socket") == -1)
291 		{
292 			ilog(L_MAIN, "Unable to create ssld - rb_socketpair failed: %s", strerror(errno));
293 			return started;
294 		}
295 
296 		rb_set_buffers(F1, READBUF_SIZE);
297 		rb_set_buffers(F2, READBUF_SIZE);
298 		rb_snprintf(fdarg, sizeof(fdarg), "%d", rb_get_fd(F2));
299 		rb_setenv("CTL_FD", fdarg, 1);
300 		if(rb_pipe(&P1, &P2, "SSL/TLS pipe") == -1)
301 		{
302 			ilog(L_MAIN, "Unable to create ssld - rb_pipe failed: %s", strerror(errno));
303 			return started;
304 		}
305 		rb_snprintf(fdarg, sizeof(fdarg), "%d", rb_get_fd(P1));
306 		rb_setenv("CTL_PIPE", fdarg, 1);
307 		rb_snprintf(s_pid, sizeof(s_pid), "%d", (int)getpid());
308 		rb_setenv("CTL_PPID", s_pid, 1);
309 #ifdef _WIN32
310 		SetHandleInformation((HANDLE) rb_get_fd(F2), HANDLE_FLAG_INHERIT, 1);
311 		SetHandleInformation((HANDLE) rb_get_fd(P1), HANDLE_FLAG_INHERIT, 1);
312 #endif
313 
314 		pid = rb_spawn_process(ssld_path, (const char **)parv);
315 		if(pid == -1)
316 		{
317 			ilog(L_MAIN, "Unable to create ssld: %s\n", strerror(errno));
318 			rb_close(F1);
319 			rb_close(F2);
320 			rb_close(P1);
321 			rb_close(P2);
322 			return started;
323 		}
324 		started++;
325 		rb_close(F2);
326 		rb_close(P1);
327 		ctl = allocate_ssl_daemon(F1, P2, pid);
328 		if(ircd_ssl_ok)
329 		{
330 			send_init_prng(ctl, RB_PRNG_DEFAULT, NULL);
331 		}
332 		if(ircd_ssl_ok && ssl_cert != NULL && ssl_private_key != NULL)
333 			send_new_ssl_certs_one(ctl, ssl_cert, ssl_private_key,
334 					       ssl_dh_params != NULL ? ssl_dh_params : "");
335 		ssl_read_ctl(ctl->F, ctl);
336 		ssl_do_pipe(P2, ctl);
337 
338 	}
339 	return started;
340 }
341 
342 static void
ssl_process_zipstats(ssl_ctl_t * ctl,ssl_ctl_buf_t * ctl_buf)343 ssl_process_zipstats(ssl_ctl_t * ctl, ssl_ctl_buf_t * ctl_buf)
344 {
345 	struct Client *server;
346 	struct ZipStats *zips;
347 	int parc;
348 	char *parv[7];
349 	parc = rb_string_to_array(ctl_buf->buf, parv, 6);
350 	server = find_server(NULL, parv[1]);
351 	if(server == NULL || server->localClient == NULL || !IsCapable(server, CAP_ZIP))
352 		return;
353 	if(server->localClient->zipstats == NULL)
354 		server->localClient->zipstats = rb_malloc(sizeof(struct ZipStats));
355 
356 	zips = server->localClient->zipstats;
357 
358 	zips->in += strtoull(parv[2], NULL, 10);
359 	zips->in_wire += strtoull(parv[3], NULL, 10);
360 	zips->out += strtoull(parv[4], NULL, 10);
361 	zips->out_wire += strtoull(parv[5], NULL, 10);
362 
363 	if(zips->in > 0)
364 		zips->in_ratio = ((double)(zips->in - zips->in_wire) / (double)zips->in) * 100.00;
365 	else
366 		zips->in_ratio = 0;
367 
368 	if(zips->out > 0)
369 		zips->out_ratio =
370 			((double)(zips->out - zips->out_wire) / (double)zips->out) * 100.00;
371 	else
372 		zips->out_ratio = 0;
373 }
374 
375 static void
ssl_process_dead_fd(ssl_ctl_t * ctl,ssl_ctl_buf_t * ctl_buf)376 ssl_process_dead_fd(ssl_ctl_t * ctl, ssl_ctl_buf_t * ctl_buf)
377 {
378 	struct Client *client_p;
379 	char reason[256];
380 	int32_t fd;
381 
382 	if(ctl_buf->buflen < 6)
383 		return;		/* bogus message..drop it.. XXX should warn here */
384 
385 	fd = buf_to_int32(&ctl_buf->buf[1]);
386 	rb_strlcpy(reason, &ctl_buf->buf[5], sizeof(reason));
387 	client_p = find_cli_fd_hash(fd);
388 	if(client_p == NULL)
389 		return;
390 	if(IsAnyServer(client_p) || IsRegistered(client_p))
391 	{
392 		/* read any last moment ERROR, QUIT or the like -- jilles */
393 		if (!strcmp(reason, "Remote host closed the connection"))
394 			read_packet(client_p->localClient->F, client_p);
395 		if (IsAnyDead(client_p))
396 			return;
397 	}
398 	if(IsAnyServer(client_p))
399 	{
400 		sendto_realops_flags(UMODE_ALL, L_ALL, "ssld error for %s: %s", client_p->name,
401 				     reason);
402 		ilog(L_SERVER, "ssld error for %s: %s", log_client_name(client_p, SHOW_IP), reason);
403 	}
404 	exit_client(client_p, client_p, &me, reason);
405 }
406 
407 static void
ssl_process_cmd_recv(ssl_ctl_t * ctl)408 ssl_process_cmd_recv(ssl_ctl_t * ctl)
409 {
410 	static const char *cannot_setup_ssl =
411 		"ssld cannot setup ssl, check your certificates and private key";
412 	static const char *no_ssl_or_zlib =
413 		"ssld has neither SSL/TLS or zlib support killing all sslds";
414 	rb_dlink_node *ptr, *next;
415 	ssl_ctl_buf_t *ctl_buf;
416 	if(ctl->dead)
417 		return;
418 	RB_DLINK_FOREACH_SAFE(ptr, next, ctl->readq.head)
419 	{
420 		ctl_buf = ptr->data;
421 		switch (*ctl_buf->buf)
422 		{
423 		case 'N':
424 			ircd_ssl_ok = 0;	/* ssld says it can't do ssl/tls */
425 			break;
426 		case 'D':
427 			ssl_process_dead_fd(ctl, ctl_buf);
428 			break;
429 		case 'S':
430 			ssl_process_zipstats(ctl, ctl_buf);
431 			break;
432 		case 'I':
433 			ircd_ssl_ok = 0;
434 			ilog(L_MAIN, "%s", cannot_setup_ssl);
435 			sendto_realops_flags(UMODE_ALL, L_ALL, "%s", cannot_setup_ssl);
436 		case 'U':
437 			zlib_ok = 0;
438 			ircd_ssl_ok = 0;
439 			ilog(L_MAIN, "%s", no_ssl_or_zlib);
440 			sendto_realops_flags(UMODE_ALL, L_ALL, "%s", no_ssl_or_zlib);
441 			ssl_killall();
442 			break;
443 		case 'z':
444 			zlib_ok = 0;
445 			break;
446 		default:
447 			ilog(L_MAIN, "Received invalid command from ssld: %s", ctl_buf->buf);
448 			sendto_realops_flags(UMODE_ALL, L_ALL,
449 					     "Received invalid command from ssld");
450 			break;
451 		}
452 		rb_dlinkDelete(ptr, &ctl->readq);
453 		rb_free(ctl_buf->buf);
454 		rb_free(ctl_buf);
455 	}
456 
457 }
458 
459 
460 static void
ssl_read_ctl(rb_fde_t * F,void * data)461 ssl_read_ctl(rb_fde_t *F, void *data)
462 {
463 	ssl_ctl_buf_t *ctl_buf;
464 	ssl_ctl_t *ctl = data;
465 	int retlen;
466 
467 	if(ctl->dead)
468 		return;
469 	do
470 	{
471 		ctl_buf = rb_malloc(sizeof(ssl_ctl_buf_t));
472 		ctl_buf->buf = rb_malloc(READSIZE);
473 		retlen = rb_recv_fd_buf(ctl->F, ctl_buf->buf, READSIZE, ctl_buf->F, 4);
474 		ctl_buf->buflen = retlen;
475 		if(retlen <= 0)
476 		{
477 			rb_free(ctl_buf->buf);
478 			rb_free(ctl_buf);
479 		}
480 		else
481 			rb_dlinkAddTail(ctl_buf, &ctl_buf->node, &ctl->readq);
482 	}
483 	while(retlen > 0);
484 
485 	if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
486 	{
487 		ssl_dead(ctl);
488 		return;
489 	}
490 	ssl_process_cmd_recv(ctl);
491 	rb_setselect(ctl->F, RB_SELECT_READ, ssl_read_ctl, ctl);
492 }
493 
494 static ssl_ctl_t *
which_ssld(void)495 which_ssld(void)
496 {
497 	ssl_ctl_t *ctl, *lowest = NULL;
498 	rb_dlink_node *ptr;
499 
500 	RB_DLINK_FOREACH(ptr, ssl_daemons.head)
501 	{
502 		ctl = ptr->data;
503 		if(ctl->dead)
504 			continue;
505 		if(lowest == NULL)
506 		{
507 			lowest = ctl;
508 			continue;
509 		}
510 		if(ctl->cli_count < lowest->cli_count)
511 			lowest = ctl;
512 	}
513 	return (lowest);
514 }
515 
516 static void
ssl_write_ctl(rb_fde_t * F,void * data)517 ssl_write_ctl(rb_fde_t *F, void *data)
518 {
519 	ssl_ctl_t *ctl = data;
520 	ssl_ctl_buf_t *ctl_buf;
521 	rb_dlink_node *ptr, *next;
522 	int retlen, x;
523 
524 	if(ctl->dead)
525 		return;
526 
527 	RB_DLINK_FOREACH_SAFE(ptr, next, ctl->writeq.head)
528 	{
529 		ctl_buf = ptr->data;
530 		/* in theory unix sock_dgram shouldn't ever short write this.. */
531 		retlen = rb_send_fd_buf(ctl->F, ctl_buf->F, ctl_buf->nfds, ctl_buf->buf,
532 					ctl_buf->buflen, ctl->pid);
533 		if(retlen > 0)
534 		{
535 			rb_dlinkDelete(ptr, &ctl->writeq);
536 			for(x = 0; x < ctl_buf->nfds; x++)
537 				rb_close(ctl_buf->F[x]);
538 			rb_free(ctl_buf->buf);
539 			rb_free(ctl_buf);
540 
541 		}
542 		if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
543 		{
544 			ssl_dead(ctl);
545 			return;
546 		}
547 		else
548 		{
549 			rb_setselect(ctl->F, RB_SELECT_WRITE, ssl_write_ctl, ctl);
550 		}
551 	}
552 }
553 
554 static void
ssl_cmd_write_queue(ssl_ctl_t * ctl,rb_fde_t ** F,int count,const void * buf,size_t buflen)555 ssl_cmd_write_queue(ssl_ctl_t * ctl, rb_fde_t **F, int count, const void *buf, size_t buflen)
556 {
557 	ssl_ctl_buf_t *ctl_buf;
558 	int x;
559 
560 	/* don't bother */
561 	if(ctl->dead)
562 		return;
563 
564 	ctl_buf = rb_malloc(sizeof(ssl_ctl_buf_t));
565 	ctl_buf->buf = rb_malloc(buflen);
566 	memcpy(ctl_buf->buf, buf, buflen);
567 	ctl_buf->buflen = buflen;
568 
569 	for(x = 0; x < count && x < MAXPASSFD; x++)
570 	{
571 		ctl_buf->F[x] = F[x];
572 	}
573 	ctl_buf->nfds = count;
574 	rb_dlinkAddTail(ctl_buf, &ctl_buf->node, &ctl->writeq);
575 	ssl_write_ctl(ctl->F, ctl);
576 }
577 
578 
579 static void
send_new_ssl_certs_one(ssl_ctl_t * ctl,const char * ssl_cert,const char * ssl_private_key,const char * ssl_dh_params)580 send_new_ssl_certs_one(ssl_ctl_t * ctl, const char *ssl_cert, const char *ssl_private_key,
581 		       const char *ssl_dh_params)
582 {
583 	size_t len;
584 
585 	len = strlen(ssl_cert) + strlen(ssl_private_key) + strlen(ssl_dh_params) + 5;
586 	if(len > sizeof(tmpbuf))
587 	{
588 		sendto_realops_flags(UMODE_ALL, L_ALL,
589 				     "Parameters for send_new_ssl_certs_one too long (%zu > %zu) to pass to ssld, not sending...",
590 				     len, sizeof(tmpbuf));
591 		ilog(L_MAIN,
592 		     "Parameters for send_new_ssl_certs_one too long (%zu > %zu) to pass to ssld, not sending...",
593 		     len, sizeof(tmpbuf));
594 		return;
595 	}
596 	len = rb_snprintf(tmpbuf, sizeof(tmpbuf), "K%c%s%c%s%c%s%c", nul, ssl_cert, nul,
597 			  ssl_private_key, nul, ssl_dh_params, nul);
598 	ssl_cmd_write_queue(ctl, NULL, 0, tmpbuf, len);
599 }
600 
601 static void
send_init_prng(ssl_ctl_t * ctl,prng_seed_t seedtype,const char * path)602 send_init_prng(ssl_ctl_t * ctl, prng_seed_t seedtype, const char *path)
603 {
604 	size_t len;
605 	const char *s;
606 	uint8_t seed = (uint8_t)seedtype;
607 
608 	if(path == NULL)
609 		s = "";
610 	else
611 		s = path;
612 
613 	len = strlen(s) + 3;
614 	if(len > sizeof(tmpbuf))
615 	{
616 		sendto_realops_flags(UMODE_ALL, L_ALL,
617 				     "Parameters for send_init_prng too long (%zd > %zd) to pass to ssld, not sending...",
618 				     len, sizeof(tmpbuf));
619 		ilog(L_MAIN,
620 		     "Parameters for send_init_prng too long (%zd > %zd) to pass to ssld, not sending...",
621 		     len, sizeof(tmpbuf));
622 		return;
623 
624 	}
625 	len = rb_snprintf(tmpbuf, sizeof(tmpbuf), "I%c%s%c", seed, s, nul);
626 	ssl_cmd_write_queue(ctl, NULL, 0, tmpbuf, len);
627 }
628 
629 void
send_new_ssl_certs(const char * ssl_cert,const char * ssl_private_key,const char * ssl_dh_params)630 send_new_ssl_certs(const char *ssl_cert, const char *ssl_private_key, const char *ssl_dh_params)
631 {
632 	rb_dlink_node *ptr;
633 	if(ssl_cert == NULL || ssl_private_key == NULL || ssl_dh_params == NULL)
634 	{
635 		ircd_ssl_ok = 0;
636 		return;
637 	}
638 	RB_DLINK_FOREACH(ptr, ssl_daemons.head)
639 	{
640 		ssl_ctl_t *ctl = ptr->data;
641 		send_new_ssl_certs_one(ctl, ssl_cert, ssl_private_key, ssl_dh_params);
642 	}
643 }
644 
645 
646 ssl_ctl_t *
start_ssld_accept(rb_fde_t * sslF,rb_fde_t * plainF,int32_t id)647 start_ssld_accept(rb_fde_t *sslF, rb_fde_t *plainF, int32_t id)
648 {
649 	rb_fde_t *F[2];
650 	ssl_ctl_t *ctl;
651 	char buf[5];
652 	F[0] = sslF;
653 	F[1] = plainF;
654 
655 	buf[0] = 'A';
656 	int32_to_buf(&buf[1], id);
657 	ctl = which_ssld();
658 	ctl->cli_count++;
659 	ssl_cmd_write_queue(ctl, F, 2, buf, sizeof(buf));
660 	return ctl;
661 }
662 
663 ssl_ctl_t *
start_ssld_connect(rb_fde_t * sslF,rb_fde_t * plainF,int32_t id)664 start_ssld_connect(rb_fde_t *sslF, rb_fde_t *plainF, int32_t id)
665 {
666 	rb_fde_t *F[2];
667 	ssl_ctl_t *ctl;
668 	char buf[5];
669 	F[0] = sslF;
670 	F[1] = plainF;
671 
672 	buf[0] = 'C';
673 	int32_to_buf(&buf[1], id);
674 
675 	ctl = which_ssld();
676 	ctl->cli_count++;
677 	ssl_cmd_write_queue(ctl, F, 2, buf, sizeof(buf));
678 	return ctl;
679 }
680 
681 void
ssld_decrement_clicount(ssl_ctl_t * ctl)682 ssld_decrement_clicount(ssl_ctl_t * ctl)
683 {
684 	if(ctl == NULL)
685 		return;
686 
687 	ctl->cli_count--;
688 	if(ctl->dead && !ctl->cli_count)
689 	{
690 		free_ssl_daemon(ctl);
691 	}
692 }
693 
694 /*
695  * what we end up sending to the ssld process for ziplinks is the following
696  * Z[ourfd][level][RECVQ]
697  * Z = ziplinks command	= buf[0]
698  * ourfd = Our end of the socketpair = buf[1..4]
699  * level = zip level buf[5]
700  * recvqlen = our recvq len = buf[6-7]
701  * recvq = any data we read prior to starting ziplinks
702  */
703 void
start_zlib_session(void * data)704 start_zlib_session(void *data)
705 {
706 	struct Client *server = (struct Client *)data;
707 	uint16_t recvqlen;
708 	uint8_t level;
709 	void *xbuf;
710 
711 	rb_fde_t *F[2];
712 	rb_fde_t *xF1, *xF2;
713 	char *buf;
714 	char buf2[9];
715 	void *recvq_start;
716 
717 	size_t hdr = (sizeof(uint8_t) * 2) + sizeof(int32_t);
718 	size_t len;
719 	int cpylen, left;
720 
721 	server->localClient->event = NULL;
722 
723 	recvqlen = rb_linebuf_len(&server->localClient->buf_recvq);
724 
725 	len = recvqlen + hdr;
726 
727 	if(len > READBUF_SIZE)
728 	{
729 		sendto_realops_flags(UMODE_ALL, L_ALL,
730 				     "ssld - attempted to pass message of %zd len, max len %d, giving up",
731 				     len, READBUF_SIZE);
732 		ilog(L_MAIN, "ssld - attempted to pass message of %zd len, max len %d, giving up",
733 		     len, READBUF_SIZE);
734 		exit_client(server, server, server, "ssld readbuf exceeded");
735 		return;
736 	}
737 
738 	buf = rb_malloc(len);
739 	level = ConfigFileEntry.compression_level;
740 
741 	int32_to_buf(&buf[1], rb_get_fd(server->localClient->F));
742 
743 
744 	buf[5] = (char)level;
745 
746 	recvq_start = &buf[6];
747 	server->localClient->zipstats = rb_malloc(sizeof(struct ZipStats));
748 
749 	xbuf = recvq_start;
750 	left = recvqlen;
751 
752 	do
753 	{
754 		cpylen = rb_linebuf_get(&server->localClient->buf_recvq, xbuf, left,
755 					LINEBUF_PARTIAL, LINEBUF_RAW);
756 		left -= cpylen;
757 		xbuf = (void *) (((uintptr_t) xbuf) + cpylen);
758 	}
759 	while(cpylen > 0);
760 
761 	/* Pass the socket to ssld. */
762 	*buf = 'Z';
763 	if(rb_socketpair(AF_UNIX, SOCK_STREAM, 0, &xF1, &xF2, "Initial zlib socketpairs") == -1)
764 	{
765 		sendto_realops_flags(UMODE_ALL, L_ALL, "Error creating zlib socketpair - %s", strerror(errno));
766 		ilog(L_MAIN, "Error creating zlib socketpairs - %s", strerror(errno));
767 		exit_client(server, server, server, "Error creating zlib socketpair");
768 		return;
769 	}
770 
771 	if(IsSSL(server))
772 	{
773 		/* tell ssld the new connid for the ssl part*/
774 		buf2[0] = 'Y';
775 		int32_to_buf(&buf2[1], rb_get_fd(server->localClient->F));
776 		int32_to_buf(&buf2[5], rb_get_fd(xF2));
777 		ssl_cmd_write_queue(server->localClient->ssl_ctl, NULL, 0, buf2, sizeof(buf2));
778 	}
779 
780 
781 	F[0] = server->localClient->F;
782 	F[1] = xF1;
783 	del_from_cli_fd_hash(server);
784 	server->localClient->F = xF2;
785 
786 
787 	/* need to redo as what we did before isn't valid now */
788 	int32_to_buf(&buf[1], rb_get_fd(server->localClient->F));
789 	add_to_cli_fd_hash(server);
790 
791 	server->localClient->z_ctl = which_ssld();
792 	server->localClient->z_ctl->cli_count++;
793 	ssl_cmd_write_queue(server->localClient->z_ctl, F, 2, buf, len);
794 	rb_free(buf);
795 }
796 
797 static void
collect_zipstats(void * unused)798 collect_zipstats(void *unused)
799 {
800 	rb_dlink_node *ptr;
801 	struct Client *target_p;
802 	char buf[sizeof(uint8_t) + sizeof(int32_t) + HOSTLEN];
803 	void *odata;
804 	size_t len;
805 	int32_t id;
806 
807 	buf[0] = 'S';
808 	odata = buf + sizeof(uint8_t) + sizeof(int32_t);
809 
810 	RB_DLINK_FOREACH(ptr, serv_list.head)
811 	{
812 		target_p = ptr->data;
813 		if(IsCapable(target_p, CAP_ZIP))
814 		{
815 			len = sizeof(uint8_t) + sizeof(uint32_t);
816 
817 			id = rb_get_fd(target_p->localClient->F);
818 			int32_to_buf(&buf[1], rb_get_fd(target_p->localClient->F));
819 			rb_strlcpy(odata, target_p->name, (sizeof(buf) - len));
820 			len += strlen(odata) + 1;	/* Get the \0 as well */
821 			ssl_cmd_write_queue(target_p->localClient->z_ctl, NULL, 0, buf, len);
822 		}
823 	}
824 }
825 
826 static void
cleanup_dead_ssl(void * unused)827 cleanup_dead_ssl(void *unused)
828 {
829 	rb_dlink_node *ptr, *next;
830 	ssl_ctl_t *ctl;
831 	RB_DLINK_FOREACH_SAFE(ptr, next, ssl_daemons.head)
832 	{
833 		ctl = ptr->data;
834 		if(ctl->dead && !ctl->cli_count)
835 		{
836 			free_ssl_daemon(ctl);
837 		}
838 	}
839 }
840 
841 int
get_ssld_count(void)842 get_ssld_count(void)
843 {
844 	return ssld_count;
845 }
846 
847 void
init_ssld(void)848 init_ssld(void)
849 {
850 	rb_event_addish("collect_zipstats", collect_zipstats, NULL, ZIPSTATS_TIME);
851 	rb_event_addish("cleanup_dead_ssld", cleanup_dead_ssl, NULL, 1200);
852 }
853