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