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