2 * sslproc.c: An interface to ssld
3 * Copyright (C) 2007 Aaron Sethman <androsyn@ratbox.org>
4 * Copyright (C) 2007 ircd-ratbox development team
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.
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.
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
21 * $Id: sslproc.c 25179 2008-03-30 16:34:57Z androsyn $
24 #include <ratbox_lib.h>
37 #define ZIPSTATS_TIME 60
39 static void collect_zipstats(void *unused
);
40 static void ssl_read_ctl(rb_fde_t
*F
, void *data
);
41 static int ssld_count
;
43 static char tmpbuf
[READBUF_SIZE
];
44 static char nul
= '\0';
48 typedef struct _ssl_ctl_buf
53 rb_fde_t
*F
[MAXPASSFD
];
70 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
);
71 static void send_init_prng(ssl_ctl_t
*ctl
, prng_seed_t seedtype
, const char *path
);
74 static rb_dlink_list ssl_daemons
;
76 static inline rb_int32_t
buf_to_int32(char *buf
)
86 static inline void int32_to_buf(char *buf
, rb_int32_t x
)
88 *(buf
) = x
>> 24 & 0xFF;
89 *(++buf
) = x
>> 16 & 0xFF;
90 *(++buf
) = x
>> 8 & 0xFF;
96 static inline rb_uint16_t
buf_to_uint16(char *buf
)
104 static inline void uint16_to_buf(char *buf
, rb_uint16_t x
)
106 *(buf
) = x
>> 8 & 0xFF;
113 allocate_ssl_daemon(rb_fde_t
*F
, rb_fde_t
*P
, int pid
)
117 if(F
== NULL
|| pid
< 0)
119 ctl
= rb_malloc(sizeof(ssl_ctl_t
));
124 rb_dlinkAdd(ctl
, &ctl
->node
, &ssl_daemons
);
129 free_ssl_daemon(ssl_ctl_t
*ctl
)
132 ssl_ctl_buf_t
*ctl_buf
;
137 RB_DLINK_FOREACH(ptr
, ctl
->readq
.head
)
140 for(x
= 0; x
< ctl_buf
->nfds
; x
++)
141 rb_close(ctl_buf
->F
[x
]);
143 rb_free(ctl_buf
->buf
);
147 RB_DLINK_FOREACH(ptr
, ctl
->writeq
.head
)
150 for(x
= 0; x
< ctl_buf
->nfds
; x
++)
151 rb_close(ctl_buf
->F
[x
]);
153 rb_free(ctl_buf
->buf
);
158 rb_dlinkDelete(&ctl
->node
, &ssl_daemons
);
162 static char *ssld_path
;
164 static int ssld_spin_count
= 0;
165 static time_t last_spin
;
166 static int ssld_wait
= 0;
172 rb_dlink_node
*ptr
, *next
;
174 RB_DLINK_FOREACH_SAFE(ptr
, next
, ssl_daemons
.head
)
181 kill(ctl
->pid
, SIGKILL
);
186 ssl_dead(ssl_ctl_t
*ctl
)
193 kill(ctl
->pid
, SIGKILL
); /* make sure the process is really gone */
194 ilog(L_MAIN
, "ssld helper died - attempting to restart");
195 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "ssld helper died - attempting to restart");
196 start_ssldaemon(1, ServerInfo
.ssl_cert
, ServerInfo
.ssl_private_key
, ServerInfo
.ssl_dh_params
);
200 ssl_do_pipe(rb_fde_t
*F
, void *data
)
203 ssl_ctl_t
*ctl
= data
;
204 retlen
= rb_write(F
, "0", 1);
205 if(retlen
== 0 || (retlen
< 0 && !rb_ignore_errno(errno
)))
210 rb_setselect(F
, RB_SELECT_READ
, ssl_do_pipe
, data
);
214 restart_ssld_event(void *unused
)
219 if(ServerInfo
.ssld_count
> get_ssld_count())
221 int start
= ServerInfo
.ssld_count
- get_ssld_count();
222 ilog(L_MAIN
, "Attempting to restart ssld processes");
223 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "Attempt to restart ssld processes");
224 start_ssldaemon(start
, ServerInfo
.ssl_cert
, ServerInfo
.ssl_private_key
, ServerInfo
.ssl_dh_params
);
229 start_ssldaemon(int count
, const char *ssl_cert
, const char *ssl_private_key
, const char *ssl_dh_params
)
233 char fullpath
[PATH_MAX
+ 1];
243 if(ssld_spin_count
> 20 && (rb_current_time() - last_spin
< 5))
245 ilog(L_MAIN
, "ssld helper is spinning - will attempt to restart in 5 minutes");
246 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "ssld helper is spinning - will attempt to restart in 1 minute");
247 rb_event_add("restart_ssld_event", restart_ssld_event
, NULL
, 60);
253 last_spin
= rb_current_time();
254 if(ssld_path
== NULL
)
256 rb_snprintf(fullpath
, sizeof(fullpath
), "%s/ssld", BINPATH
);
258 if(access(fullpath
, X_OK
) == -1)
260 rb_snprintf(fullpath
, sizeof(fullpath
), "%s/bin/ssld", ConfigFileEntry
.dpath
);
261 if(access(fullpath
, X_OK
) == -1)
263 ilog(L_MAIN
, "Unable to execute ssld in %s/bin or %s", ConfigFileEntry
.dpath
, BINPATH
);
267 ssld_path
= rb_strdup(fullpath
);
270 rb_strlcpy(buf
, "-ircd ssld daemon helper", sizeof(buf
));
274 for(i
= 0; i
< count
; i
++)
277 rb_socketpair(AF_UNIX
, SOCK_DGRAM
, 0, &F1
, &F2
, "SSL/TLS handle passing socket");
278 rb_set_buffers(F1
, READBUF_SIZE
);
279 rb_set_buffers(F2
, READBUF_SIZE
);
280 rb_snprintf(fdarg
, sizeof(fdarg
), "%d", rb_get_fd(F2
));
281 setenv("CTL_FD", fdarg
, 1);
282 rb_pipe(&P1
, &P2
, "SSL/TLS pipe");
283 rb_snprintf(fdarg
, sizeof(fdarg
), "%d", rb_get_fd(P1
));
284 setenv("CTL_PIPE", fdarg
, 1);
286 pid
= rb_spawn_process(ssld_path
, (const char **)parv
);
289 ilog(L_MAIN
, "Unable to create ssld: %s\n", strerror(errno
));
299 ctl
= allocate_ssl_daemon(F1
, P2
, pid
);
302 if(ConfigFileEntry
.use_egd
&& (ConfigFileEntry
.egdpool_path
!= NULL
))
303 send_init_prng(ctl
, RB_PRNG_EGD
, ConfigFileEntry
.egdpool_path
);
305 send_init_prng(ctl
, RB_PRNG_DEFAULT
, NULL
);
307 if(ssl_ok
&& ssl_cert
!= NULL
&& ssl_private_key
!= NULL
)
308 send_new_ssl_certs_one(ctl
, ssl_cert
, ssl_private_key
, ssl_dh_params
!= NULL
? ssl_dh_params
: "");
309 ssl_read_ctl(ctl
->F
, ctl
);
310 ssl_do_pipe(P2
, ctl
);
316 ssl_process_zipstats(ssl_ctl_t
*ctl
, ssl_ctl_buf_t
*ctl_buf
)
318 struct Client
*server
;
319 struct ZipStats
*zips
;
322 parc
= rb_string_to_array(ctl_buf
->buf
, parv
, 6);
323 server
= find_server(NULL
, parv
[1]);
324 if(server
== NULL
|| server
->localClient
== NULL
|| !IsCapable(server
, CAP_ZIP
))
326 if(server
->localClient
->zipstats
== NULL
)
327 server
->localClient
->zipstats
= rb_malloc(sizeof(struct ZipStats
));
329 zips
= server
->localClient
->zipstats
;
331 zips
->in
+= strtoull(parv
[2], NULL
, 10);
332 zips
->in_wire
+= strtoull(parv
[3], NULL
, 10);
333 zips
->out
+= strtoull(parv
[4], NULL
, 10);
334 zips
->out_wire
+= strtoull(parv
[5], NULL
, 10);
337 zips
->in_ratio
= ((double)(zips
->in
- zips
->in_wire
) / (double) zips
->in
) * 100.00;
342 zips
->out_ratio
= ((double)(zips
->out
- zips
->out_wire
) / (double) zips
->out
) * 100.00;
348 ssl_process_dead_fd(ssl_ctl_t
*ctl
, ssl_ctl_buf_t
*ctl_buf
)
350 struct Client
*client_p
;
354 if(ctl_buf
->buflen
< 6)
355 return; /* bogus message..drop it.. XXX should warn here */
357 fd
= buf_to_int32(&ctl_buf
->buf
[1]);
358 rb_strlcpy(reason
, &ctl_buf
->buf
[5], sizeof(reason
));
359 client_p
= find_cli_fd_hash(fd
);
362 if(IsAnyServer(client_p
))
364 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
);
365 ilog(L_SERVER
, "ssld error for %s: %s", log_client_name(client_p
, SHOW_IP
), reason
);
367 exit_client(client_p
, client_p
, &me
, reason
);
372 ssl_process_zip_ready(ssl_ctl_t
*ctl
, ssl_ctl_buf_t
*ctl_buf
)
374 struct Client
*client_p
;
377 if(ctl_buf
->buflen
< 5)
378 return; /* bogus message..drop it.. XXX should warn here */
380 fd
= buf_to_int32(&ctl_buf
->buf
[1]);
381 client_p
= find_cli_fd_hash(fd
);
385 /* Now start sending the data that should be compressed. */
386 // ClearCork(client_p);
387 send_pop_queue(client_p
);
388 /* Start reading uncompressed data. */
389 read_packet(client_p
->localClient
->F
, client_p
);
394 ssl_process_cmd_recv(ssl_ctl_t
*ctl
)
396 static const char *cannot_setup_ssl
= "ssld cannot setup ssl, check your certificates and private key";
397 static const char *no_ssl_or_zlib
= "ssld has neither SSL/TLS or zlib support killing all sslds";
398 rb_dlink_node
*ptr
, *next
;
399 ssl_ctl_buf_t
*ctl_buf
;
402 RB_DLINK_FOREACH_SAFE(ptr
, next
, ctl
->readq
.head
)
405 switch(*ctl_buf
->buf
)
408 ssl_ok
= 0; /* ssld says it can't do ssl/tls */
411 ssl_process_dead_fd(ctl
, ctl_buf
);
414 ssl_process_zipstats(ctl
, ctl_buf
);
418 ilog(L_MAIN
, cannot_setup_ssl
);
419 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, cannot_setup_ssl
);
423 ilog(L_MAIN
, no_ssl_or_zlib
);
424 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, no_ssl_or_zlib
);
428 ssl_process_zip_ready(ctl
, ctl_buf
);
434 ilog(L_MAIN
, "Received invalid command from ssld: %s", ctl_buf
->buf
);
435 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "Received invalid command from ssld");
438 rb_dlinkDelete(ptr
, &ctl
->readq
);
439 rb_free(ctl_buf
->buf
);
447 ssl_read_ctl(rb_fde_t
*F
, void *data
)
449 ssl_ctl_buf_t
*ctl_buf
;
450 ssl_ctl_t
*ctl
= data
;
457 ctl_buf
= rb_malloc(sizeof(ssl_ctl_buf_t
));
458 ctl_buf
->buf
= rb_malloc(READSIZE
);
459 retlen
= rb_recv_fd_buf(ctl
->F
, ctl_buf
->buf
, READSIZE
, ctl_buf
->F
, 4);
460 ctl_buf
->buflen
= retlen
;
462 rb_free(ctl_buf
->buf
);
466 rb_dlinkAddTail(ctl_buf
, &ctl_buf
->node
, &ctl
->readq
);
469 if(retlen
== 0 || (retlen
< 0 && !rb_ignore_errno(errno
)))
474 ssl_process_cmd_recv(ctl
);
475 rb_setselect(ctl
->F
, RB_SELECT_READ
, ssl_read_ctl
, ctl
);
481 ssl_ctl_t
*ctl
, *lowest
= NULL
;
484 RB_DLINK_FOREACH(ptr
, ssl_daemons
.head
)
493 if(ctl
->cli_count
< lowest
->cli_count
)
500 ssl_write_ctl(rb_fde_t
*F
, void *data
)
502 ssl_ctl_t
*ctl
= data
;
503 ssl_ctl_buf_t
*ctl_buf
;
504 rb_dlink_node
*ptr
, *next
;
510 RB_DLINK_FOREACH_SAFE(ptr
, next
, ctl
->writeq
.head
)
513 /* in theory unix sock_dgram shouldn't ever short write this.. */
514 retlen
= rb_send_fd_buf(ctl
->F
, ctl_buf
->F
, ctl_buf
->nfds
, ctl_buf
->buf
, ctl_buf
->buflen
);
517 rb_dlinkDelete(ptr
, &ctl
->writeq
);
518 for(x
= 0; x
< ctl_buf
->nfds
; x
++)
519 rb_close(ctl_buf
->F
[x
]);
520 rb_free(ctl_buf
->buf
);
524 if(retlen
== 0 || (retlen
< 0 && !rb_ignore_errno(errno
)))
529 rb_setselect(ctl
->F
, RB_SELECT_WRITE
, ssl_write_ctl
, ctl
);
535 ssl_cmd_write_queue(ssl_ctl_t
*ctl
, rb_fde_t
**F
, int count
, const void *buf
, size_t buflen
)
537 ssl_ctl_buf_t
*ctl_buf
;
544 ctl_buf
= rb_malloc(sizeof(ssl_ctl_buf_t
));
545 ctl_buf
->buf
= rb_malloc(buflen
);
546 memcpy(ctl_buf
->buf
, buf
, buflen
);
547 ctl_buf
->buflen
= buflen
;
549 for(x
= 0; x
< count
&& x
< MAXPASSFD
; x
++)
551 ctl_buf
->F
[x
] = F
[x
];
553 ctl_buf
->nfds
= count
;
554 rb_dlinkAddTail(ctl_buf
, &ctl_buf
->node
, &ctl
->writeq
);
555 ssl_write_ctl(ctl
->F
, ctl
);
560 send_new_ssl_certs_one(ssl_ctl_t
*ctl
, const char *ssl_cert
, const char *ssl_private_key
, const char *ssl_dh_params
)
564 len
= strlen(ssl_cert
) + strlen(ssl_private_key
) + strlen(ssl_dh_params
) + 5;
565 if(len
> sizeof(tmpbuf
))
567 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
568 "Parameters for send_new_ssl_certs_one too long (%zu > %zu) to pass to ssld, not sending...",
569 len
, sizeof(tmpbuf
));
570 ilog(L_MAIN
, "Parameters for send_new_ssl_certs_one too long (%zu > %zu) to pass to ssld, not sending...",
571 len
, sizeof(tmpbuf
));
574 len
= rb_snprintf(tmpbuf
, sizeof(tmpbuf
), "K%c%s%c%s%c%s%c", nul
, ssl_cert
, nul
, ssl_private_key
, nul
, ssl_dh_params
, nul
);
575 ssl_cmd_write_queue(ctl
, NULL
, 0, tmpbuf
, len
);
579 send_init_prng(ssl_ctl_t
*ctl
, prng_seed_t seedtype
, const char *path
)
583 rb_uint8_t seed
= (rb_uint8_t
) seedtype
;
591 if(len
> sizeof(tmpbuf
))
593 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
594 "Parameters for send_init_prng too long (%zd > %zd) to pass to ssld, not sending...",
595 len
, sizeof(tmpbuf
));
596 ilog(L_MAIN
, "Parameters for send_init_prng too long (%zd > %zd) to pass to ssld, not sending...",
597 len
, sizeof(tmpbuf
));
601 len
= rb_snprintf(tmpbuf
, sizeof(tmpbuf
), "I%c%s%c", seed
, s
, nul
);
602 ssl_cmd_write_queue(ctl
, NULL
, 0, tmpbuf
, len
);
606 send_new_ssl_certs(const char *ssl_cert
, const char *ssl_private_key
, const char *ssl_dh_params
)
609 if(ssl_cert
== NULL
|| ssl_private_key
== NULL
|| ssl_dh_params
== NULL
)
614 RB_DLINK_FOREACH(ptr
, ssl_daemons
.head
)
616 ssl_ctl_t
*ctl
= ptr
->data
;
617 send_new_ssl_certs_one(ctl
, ssl_cert
, ssl_private_key
, ssl_dh_params
);
623 start_ssld_accept(rb_fde_t
*sslF
, rb_fde_t
*plainF
, rb_int32_t id
)
632 int32_to_buf(&buf
[1], id
);
635 ssl_cmd_write_queue(ctl
, F
, 2, buf
, sizeof(buf
));
640 start_ssld_connect(rb_fde_t
*sslF
, rb_fde_t
*plainF
, rb_int32_t id
)
649 int32_to_buf(&buf
[1], id
);
653 ssl_cmd_write_queue(ctl
, F
, 2, buf
, sizeof(buf
));
658 ssld_decrement_clicount(ssl_ctl_t
*ctl
)
664 if(ctl
->dead
&& !ctl
->cli_count
)
666 free_ssl_daemon(ctl
);
671 * what we end up sending to the ssld process for ziplinks is the following
672 * Z[ourfd][level][RECVQ]
673 * Z = ziplinks command = buf[0]
674 * ourfd = Our end of the socketpair = buf[1..4]
675 * level = zip level buf[5]
676 * recvqlen = our recvq len = buf[6-7]
677 * recvq = any data we read prior to starting ziplinks
680 start_zlib_session(void *data
)
682 struct Client
*server
= (struct Client
*)data
;
683 rb_uint16_t recvqlen
;
692 size_t hdr
= (sizeof(rb_uint8_t
) * 2) + sizeof(rb_int32_t
);
696 server
->localClient
->event
= NULL
;
698 recvqlen
= rb_linebuf_len(&server
->localClient
->buf_recvq
);
700 len
= recvqlen
+ hdr
;
702 if(len
> READBUF_SIZE
)
705 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "ssld - attempted to pass message of %zd len, max len %d, giving up", len
, READBUF_SIZE
);
706 ilog(L_MAIN
, "ssld - attempted to pass message of %zd len, max len %d, giving up", len
, READBUF_SIZE
);
707 exit_client(server
, server
, server
, "ssld readbuf exceeded");
711 buf
= rb_malloc(len
);
712 level
= ConfigFileEntry
.compression_level
;
714 int32_to_buf(&buf
[1], rb_get_fd(server
->localClient
->F
));
715 buf
[5] = (char)level
;
717 recvq_start
= &buf
[6];
718 server
->localClient
->zipstats
= rb_malloc(sizeof(struct ZipStats
));
725 cpylen
= rb_linebuf_get(&server
->localClient
->buf_recvq
, xbuf
, left
, LINEBUF_PARTIAL
, LINEBUF_RAW
);
730 /* Pass the socket to ssld. */
732 rb_socketpair(AF_UNIX
, SOCK_STREAM
, 0, &xF1
, &xF2
, "Initial zlib socketpairs");
734 F
[0] = server
->localClient
->F
;
736 del_from_cli_fd_hash(server
);
737 server
->localClient
->F
= xF2
;
738 /* need to redo as what we did before isn't valid now */
739 int32_to_buf(&buf
[1], rb_get_fd(server
->localClient
->F
));
740 add_to_cli_fd_hash(server
);
741 server
->localClient
->ssl_ctl
= which_ssld();
742 server
->localClient
->ssl_ctl
->cli_count
++;
743 ssl_cmd_write_queue(server
->localClient
->ssl_ctl
, F
, 2, buf
, len
);
748 collect_zipstats(void *unused
)
751 struct Client
*target_p
;
752 char buf
[sizeof(rb_uint8_t
) + sizeof(rb_int32_t
) + HOSTLEN
];
758 odata
= buf
+ sizeof(rb_uint8_t
) + sizeof(rb_int32_t
);
760 RB_DLINK_FOREACH(ptr
, serv_list
.head
)
762 target_p
= ptr
->data
;
763 if(IsCapable(target_p
, CAP_ZIP
))
765 len
= sizeof(rb_uint8_t
) + sizeof(rb_uint32_t
);
767 id
= rb_get_fd(target_p
->localClient
->F
);
768 int32_to_buf(&buf
[1], rb_get_fd(target_p
->localClient
->F
));
769 rb_strlcpy(odata
, target_p
->name
, (sizeof(buf
)-len
));
770 len
+= strlen(odata
) + 1; /* Get the \0 as well */
771 ssl_cmd_write_queue(target_p
->localClient
->ssl_ctl
, NULL
, 0, buf
, len
);
777 cleanup_dead_ssl(void *unused
)
779 rb_dlink_node
*ptr
, *next
;
781 RB_DLINK_FOREACH_SAFE(ptr
, next
, ssl_daemons
.head
)
784 if(ctl
->dead
&& !ctl
->cli_count
)
786 free_ssl_daemon(ctl
);
799 rb_event_addish("collect_zipstats", collect_zipstats
, NULL
, ZIPSTATS_TIME
);
800 rb_event_addish("cleanup_dead_ssld", cleanup_dead_ssl
, NULL
, 1200);