49e861f75cc20178c5403d4bc9f39c281e7454b6
[ircu2.10.12-pk.git] / ircd / ssl.c
1 /*
2  * IRC - Internet Relay Chat, ircd/ssl.c
3  * Written by David Herrmann.
4  */
5
6
7 /* SSL module.
8  * This SSL module is created to be as generic as possible.
9  * That is, it is easy to add new backends. We currently support
10  * GnuTLS and OpenSSL.
11  *
12  * The module is built up to encrypt all kinds of network connections.
13  * You have to create your socket yourself and accept() or connect() it.
14  * The new connected socket has to be passed to this module which then
15  * initiates a secure connection. While initiating this connection the
16  * socket is kept in a separate queue inside this module. When the
17  * connection has been fully established, the client is passed back to
18  * the add_connection() function which then passes the client to the
19  * authentication module. You can handle the client equally to a normal
20  * unencrypted connection, however, the send()/recv() functions have
21  * to be changed to the functions provided by this module.
22  *
23  * The first part of this file defines the backend functions. Only one
24  * backend can be enabled at one time. Please add your own backends there.
25  *
26  * 2009/05/19 --gix
27  */
28
29
30 #include "config.h"
31 #include "ircd.h"
32 #include "ircd_defs.h"
33 #include "ircd_events.h"
34 #include "ircd_snprintf.h"
35 #include "ircd_osdep.h"
36 #include "ircd_alloc.h"
37 #include "ircd_log.h"
38 #include "msgq.h"
39 #include "s_debug.h"
40 #include "s_bsd.h"
41 #include "s_misc.h"
42 #include "client.h"
43 #include "listener.h"
44 #include "send.h"
45 #include "ssl.h"
46
47 #include <stdio.h>
48 #include <stdarg.h>
49 #include <string.h>
50 #include <unistd.h>
51 #include <errno.h>
52
53
54 /* Backend declarations.
55  * Please add your backend here. I recommend to leave GnuTLS as the first choice
56  * because it is tested most and works perfectly. You can change the backend with
57  * the configure script at compile time.
58  *
59  * Each backend has to declare the following functions:
60  * - ssl_be_init(): This is called when the SSL library should be initialized.
61  * - ssl_be_deinit(): This is called when the SSL library should be deinitialized.
62  * - ssl_be_cred_new(): This should create a new credentials structure.
63  * - ssl_be_cred_free(): This should free a previously allocated credentials structure.
64  * - ssl_be_session_new(): This should create a new session.
65  * - ssl_be_session_connect(): This connects a session with an FD.
66  * - ssl_be_session_shutdown(): This should shutdown the Write-Endpoint of a session.
67  * - ssl_be_session_free(): This should free a session.
68  * - ssl_be_handshake(): This should start/continue the protocol handshake.
69  * - ssl_be_send(): This should send data over the connection.
70  * - ssl_be_recv(): This should receive data from the connection.
71  * - ssl_be_cipherstr(): This should return a string representing the used cipher.
72  * - ssl_be_fingerprint(): Validates the peer's socket and returns the fingerprint on success.
73  *
74  * You should declare the backend specific functions at the end of this files. At this
75  * point, every backend has to define the ssl_be_cred_t and ssl_be_session_t structures which
76  * represent the credentials and session values used by the backend.
77  *
78  * Please use the namespace "ssl_be_" in your backend only! All other names may collide
79  * with other names.
80  * Furthermore look into the dummy to see which checks are already done by the main module
81  * and what you do not have to do in your backend.
82  */
83
84
85 #if defined(HAVE_GNUTLS)
86     /* GnuTLS backend.
87      * GnuTLS is licensed under the LGPL and developed by the GNU project.
88      * This backend is recommended and tested by the developers of this module.
89      */
90     #include <gnutls/gnutls.h>
91     typedef struct {
92         gnutls_certificate_credentials_t cred;
93         gnutls_dh_params_t dhparams;
94         gnutls_priority_t prio;
95     } ssl_be_cred_t;
96     typedef gnutls_session_t ssl_be_session_t;
97 #elif defined(HAVE_OPENSSL)
98     /* OpenSSL backend.
99      * OpenSSL is developed by independant people and a de-facto standard in the
100      * industry. However, the source is *bad* and it has had many bugs in the
101      * past. We do not recommend this module!
102      */
103     /* On some systems, these headers also include the OpenSSL md5 header
104      * which itself defines MD5_CTX. This is already defined in ircd_md5.h,
105      * hence, we prevent this inclusion here.
106      * This fix is really *BAD* but since OpenSSL does not use "namespaces"/
107      * "prefixes" there is currently no other solution.
108      */
109     #define HEADER_MD5_H
110     #include <openssl/ssl.h>
111     #include <openssl/err.h>
112     #include <openssl/rand.h>
113     typedef SSL_CTX* ssl_be_cred_t;
114     typedef SSL* ssl_be_session_t;
115     static signed int ssl_be_verify(signed int preverify_ok, X509_STORE_CTX *ctx);
116 #else
117     /* Dummy backend.
118      * No backend available. We simply declare fake structures here and handle
119      * the connections unencrypted.
120      */
121     typedef void* ssl_be_cred_t;
122     typedef void* ssl_be_session_t;
123 #endif
124
125
126 /* SSL credentials (cred).
127  * An SSL credential is a specific certificate which can be used in many SSL
128  * sessions. However, we want to allow to change the certificate at runtime,
129  * therefore, we allow several credentials at one time. A new credential is
130  * created on /rehash when the certificate changed and then the old creds are
131  * marked for removal. New clients are connected with the new credential so we
132  * can remove the old creds when there are no more connected clients with this
133  * credential.
134  * A cred can either be for accepting clients or for connecting yourself as
135  * client. We support both, that is, server<->server encryption is also supported.
136  * The global creds are stored separated in two single linked lists. If the lists
137  * are empty, then no credential has been loaded yet and a new one will be created
138  * when a client connects.
139  * Thus, only the first credential in this list should be used for new connections,
140  * all other credentials are marked for removal.
141  */
142 struct ssl_cred_t;
143 struct ssl_cred_t {
144     struct ssl_cred_t *next;
145     unsigned int ref;
146     unsigned int mode;
147     ssl_be_cred_t be;
148 };
149 struct ssl_cred_t *ssl_cli_credlist = NULL;
150 struct ssl_cred_t *ssl_srv_credlist = NULL;
151
152
153 /* SSL sessions.
154  * A session contains all data that is needed by the SSL backend. We also link
155  * the session to the used credentials to be able to modify the cred when we
156  * modify the session.
157  * \fingerprint is NULL when the peer's certificate is not trusted. If it is
158  * trusted, then \fingerprint points to a string containing the fingerprint of
159  * the peer's certificate.
160  */
161 struct ssl_session_t;
162 struct ssl_session_t {
163     struct ssl_cred_t *cred;
164     ssl_be_session_t be;
165     char *fingerprint;
166 };
167
168
169 /* Represents an SSL connection whose handshake is currently pending.
170  * If a client connects, it is accepted and then put into the handshake queue.
171  * If the handshake timeouts he is rejected, otherwise he is put into the
172  * usual user-queue and the auth module continues.
173  * This structure is only used in the handshake-queue of accepted SSL clients.
174  *
175  * ssl_conn_t is the pending outgoing connection. The handshake is performed
176  * in this state and then returned to the main module when done. This is handled
177  * separately to the client connections.
178  */
179 struct ssl_pending_t {
180     ssl_session_t *session;
181     struct Socket socket;
182     struct Timer timeout;
183     signed int fd;
184     struct Listener *listener;
185 };
186 struct ssl_conn_t {
187     ssl_session_t *session;
188     struct Timer timeout;
189     struct Client *cptr;
190     void *olddata;
191 };
192
193
194 /* Backend functions.
195  * See the comment near the top of this file for information on these functions.
196  */
197 unsigned int ssl_be_init();
198 void ssl_be_deinit();
199 unsigned int ssl_be_cred_new(unsigned int mode, char *cert, char **trusts, ssl_be_cred_t *cred);
200 void ssl_be_cred_free(ssl_be_cred_t *cred);
201 unsigned int ssl_be_session_new(unsigned int mode, ssl_be_cred_t *cred, ssl_be_session_t *session);
202 unsigned int ssl_be_session_connect(ssl_be_session_t *session, signed int fd);
203 void ssl_be_session_shutdown(ssl_be_session_t *session);
204 void ssl_be_session_free(ssl_be_session_t *session);
205 #define SSL_NEED_WR 0
206 #define SSL_NEED_RD 1
207 #define SSL_NEED_RDWR 2
208 #define SSL_FAILURE 3
209 #define SSL_SUCCESS 4
210 unsigned int ssl_be_handshake(unsigned int mode, ssl_be_session_t *session);
211 const char *ssl_be_cipherstr(ssl_be_session_t *session);
212 const char *ssl_be_fingerprint(ssl_be_session_t *session);
213 IOResult ssl_be_send(signed int fd, ssl_be_session_t *ssl, const char *buf, unsigned int *count_out);
214 IOResult ssl_be_recv(signed int fd, ssl_be_session_t *ssl, char *buf, unsigned int *count_out);
215
216
217 /* Path to the certificate to use. */
218 char *ssl_cert = NULL;
219 char **ssl_trusts = NULL;
220 void ssl_setcert(const char *cert) {
221     MyFree(ssl_cert);
222     ssl_cert = strdup(cert);
223 }
224 void ssl_clearcert() {
225     MyFree(ssl_cert);
226     ssl_cert = NULL;
227 }
228 void ssl_addtrust(const char *trust) {
229     unsigned int i;
230     char **tmp;
231     if(ssl_trusts) {
232         i = 0;
233         while(ssl_trusts[i]) ++i;
234         tmp = MyMalloc(sizeof(char*) * (i + 2));
235         i = 0;
236         while(ssl_trusts[i]) {
237             tmp[i] = ssl_trusts[i];
238             ++i;
239         }
240         tmp[i] = strdup(trust);
241         tmp[i + 1] = NULL;
242         MyFree(ssl_trusts);
243         ssl_trusts = tmp;
244     }
245     else {
246         tmp = MyMalloc(sizeof(char*) * 2);
247         tmp[0] = strdup(trust);
248         tmp[1] = NULL;
249         ssl_trusts = tmp;
250     }
251 }
252 void ssl_cleartrusts() {
253     unsigned int i;
254     if(ssl_trusts) {
255         i = 0;
256         while(ssl_trusts[i]) {
257             MyFree(ssl_trusts[i]);
258             ++i;
259         }
260         MyFree(ssl_trusts);
261         ssl_trusts = NULL;
262     }
263 }
264
265
266 /* This handles SSL messages.
267  * It writes the message to the logfile and prints it on the screen if debugmode is
268  * enabled.
269  */
270 #define SSL_NOTICE 0
271 #define SSL_ERROR 1
272 #define SSL_DEBUG 2
273 static void ssl_msg(unsigned int type, const char *msg, ...) {
274     va_list list;
275
276     va_start(list, msg);
277 #ifdef DEBUGMODE
278     #define SSL_DEBUGMSG(x, y, z) vdebug((x), (y), (z))
279 #else
280     #define SSL_DEBUGMSG(x, y, z)
281 #endif
282     switch(type) {
283         case SSL_NOTICE:
284             log_vwrite(LS_SYSTEM, L_NOTICE, 0, msg, list);
285             SSL_DEBUGMSG(DEBUG_NOTICE, msg, list);
286             break;
287         case SSL_ERROR:
288             log_vwrite(LS_SYSTEM, L_CRIT, 0, msg, list);
289             SSL_DEBUGMSG(DEBUG_FATAL, msg, list);
290             break;
291         case SSL_DEBUG:
292             SSL_DEBUGMSG(DEBUG_DEBUG, msg, list);
293             break;
294     }
295     va_end(list);
296 }
297
298
299 /* Initializes or Deinitializes the SSL module. */
300 static unsigned int ssl_loaded = 0;
301 void ssl_init() {
302     if(ssl_loaded) {
303         ssl_msg(SSL_ERROR, "SSL: ssl_init(): called twice");
304         return;
305     }
306     if(ssl_be_init()) {
307         ssl_loaded = 1;
308         ssl_msg(SSL_NOTICE, "SSL: ssl_init(): done");
309     }
310     else ssl_msg(SSL_ERROR, "SSL: ssl_be_deinit(): failed");
311 }
312 void ssl_deinit() {
313     if(!ssl_loaded) {
314         ssl_msg(SSL_ERROR, "SSL: ssl_deinit(): not initialized");
315         return;
316     }
317
318     /* Check whether there are active SSL connections.
319      * That is, the credentials-list must either be empty or contain only
320      * one credential with ZERO references which then is deleted.
321      */
322     if((ssl_srv_credlist && (ssl_srv_credlist->next || ssl_srv_credlist->ref)) ||
323        (ssl_cli_credlist && (ssl_cli_credlist->next || ssl_cli_credlist->ref))) {
324         ssl_msg(SSL_ERROR, "SSL: ssl_deinit(): still active sessions");
325         return;
326     }
327     if(ssl_srv_credlist) ssl_cred_free(ssl_srv_credlist);
328     if(ssl_cli_credlist) ssl_cred_free(ssl_cli_credlist);
329
330     ssl_be_deinit();
331     ssl_clearcert();
332     ssl_cleartrusts();
333
334     ssl_msg(SSL_NOTICE, "SSL: ssl_deinit(): done");
335     ssl_loaded = 0;
336 }
337
338
339 /* Creates/Frees a credential. */
340 ssl_cred_t *ssl_cred_new(unsigned int mode, char *cert, char **trusts) {
341     ssl_cred_t *cred;
342
343     cred = MyMalloc(sizeof(ssl_cred_t));
344     memset(cred, 0, sizeof(ssl_cred_t));
345
346     if(!ssl_be_cred_new(mode, cert, trusts, &cred->be)) {
347         ssl_msg(SSL_ERROR, "SSL: ssl_be_cred_new(): failed.");
348         MyFree(cred);
349         return NULL;
350     }
351
352     if(mode == SSL_CLIENT) {
353         if(ssl_cli_credlist && ssl_cli_credlist->ref == 0) ssl_cred_free(ssl_cli_credlist);
354         cred->next = ssl_cli_credlist;
355         ssl_cli_credlist = cred;
356     }
357     else {
358         if(ssl_srv_credlist && ssl_srv_credlist->ref == 0) ssl_cred_free(ssl_srv_credlist);
359         cred->next = ssl_srv_credlist;
360         ssl_srv_credlist = cred;
361     }
362     cred->mode = mode;
363     cred->ref = 0;
364     ssl_msg(SSL_NOTICE, "SSL: ssl_cred_new(%u, '%s'): done", mode, cert);
365     return cred;
366 }
367 void ssl_cred_free(ssl_cred_t *cred) {
368     ssl_cred_t *iter;
369
370     if(cred->ref) {
371         ssl_msg(SSL_ERROR, "SSL: ssl_cred_free(%u, %u): still active sessions", cred->mode, cred->ref);
372         return;
373     }
374
375     if(cred->mode == SSL_CLIENT) {
376         iter = ssl_cli_credlist;
377         if(iter == cred) {
378             ssl_cli_credlist = iter->next;
379             goto free_cred;
380         }
381         while(iter) {
382             if(iter->next == cred) {
383                 iter->next = cred->next;
384                 goto free_cred;
385             }
386         }
387         ssl_msg(SSL_ERROR, "SSL: ssl_cred_free(): invalid cred");
388         return;
389     }
390     else {
391         iter = ssl_srv_credlist;
392         if(iter == cred) {
393             ssl_srv_credlist = iter->next;
394             goto free_cred;
395         }
396         while(iter) {
397             if(iter->next == cred) {
398                 iter->next = cred->next;
399                 goto free_cred;
400             }
401         }
402         ssl_msg(SSL_ERROR, "SSL: ssl_cred_free(): invalid cred");
403         return;
404     }
405
406     free_cred:
407     ssl_be_cred_free(&cred->be);
408     ssl_msg(SSL_NOTICE, "SSL: ssl_cred_free(%u): done", cred->mode);
409     MyFree(cred);
410 }
411
412
413 /* Manipulates an SSL session. */
414 ssl_session_t *ssl_session_new(unsigned int mode) {
415     ssl_session_t *ssl;
416     char **trusts, *fallback[1] = { NULL };
417
418     /* If no SSL certificate is set, we stop.
419      * We also clear \ssl_cert when allocating the certificate fails.
420      * This prevents the ircd from reallocating the credentials everytime
421      * a client connects although the allocation is guaranteed to fail.
422      */
423     if(!ssl_cert) return NULL;
424     if(ssl_trusts) trusts = ssl_trusts;
425     else trusts = fallback;
426
427     ssl = MyMalloc(sizeof(ssl_session_t));
428     memset(ssl, 0, sizeof(ssl_session_t));
429     ssl->fingerprint = NULL;
430
431     if(mode == SSL_CLIENT) {
432         if(ssl_cli_credlist) ssl->cred = ssl_cli_credlist;
433         else if(!(ssl->cred = ssl_cred_new(SSL_CLIENT, ssl_cert, trusts))) {
434             MyFree(ssl_cert);
435             ssl_cert = NULL;
436             MyFree(ssl);
437             ssl_msg(SSL_ERROR, "SSL: ssl_session_new(%u): failed", mode);
438             return NULL;
439         }
440     }
441     else {
442         if(ssl_srv_credlist) ssl->cred = ssl_srv_credlist;
443         else if(!(ssl->cred = ssl_cred_new(SSL_SERVER, ssl_cert, trusts))) {
444             MyFree(ssl_cert);
445             ssl_cert = NULL;
446             MyFree(ssl);
447             ssl_msg(SSL_ERROR, "SSL: ssl_session_new(%u): failed", mode);
448             return NULL;
449         }
450     }
451
452     if(!ssl_be_session_new(mode, &ssl->cred->be, &ssl->be)) {
453         /* Keep credentials. They may be used later. */
454         MyFree(ssl);
455         ssl_msg(SSL_ERROR, "SSL: ssl_session_new(%u): failed", mode);
456         return NULL;
457     }
458
459     ++ssl->cred->ref;
460     ssl_msg(SSL_DEBUG, "SSL: ssl_session_new(%u): done", mode);
461     return ssl;
462 }
463 void ssl_session_shutdown(ssl_session_t *ssl) {
464     /* We do not care for the return value here. This might be implemented
465      * in future. This makes ssl_shutdown() totally useless but this is only
466      * a placeholder for future implementations.
467      */
468     ssl_be_session_shutdown(&ssl->be);
469 }
470 void ssl_session_free(ssl_session_t *ssl) {
471     ssl_be_session_free(&ssl->be);
472
473     /* Check whether to free the credentials. */
474     if(--ssl->cred->ref == 0) {
475         if(ssl_cli_credlist != ssl->cred && ssl_srv_credlist != ssl->cred) {
476             ssl_cred_free(ssl->cred);
477         }
478     }
479
480     ssl_msg(SSL_DEBUG, "SSL: ssl_session_free(%u): done", ssl->cred->mode);
481     MyFree(ssl->fingerprint);
482     MyFree(ssl);
483 }
484
485
486 /* This handles a new client connection. It puts the client into the SSL queue and
487  * performs the SSL handshake. It either disconnects the client or passes the client
488  * to add_connection() after the handshake has been performed.
489  *
490  * We use two callbacks. One for the timeout and one for the socket. To prevent that
491  * both callbacks remove the ssl_pending_t structure or that they remove it too early
492  * we remove the structure only when the socket has been set to -1. This security check
493  * is needed, you should *NEVER* remove it.
494  */
495 static void ssl_socket_callback(struct Event* ev) {
496     struct ssl_pending_t *pend;
497     unsigned int ret;
498
499     pend = s_data(ev_socket(ev));
500     switch(ev_type(ev)) {
501         case ET_DESTROY:
502             if(pend->fd == -1) MyFree(pend);
503             return;
504         case ET_ERROR:
505         case ET_EOF:
506             ssl_session_shutdown(pend->session);
507             close(pend->fd);
508             ssl_session_free(pend->session);
509             socket_del(&pend->socket);
510             timer_del(&pend->timeout);
511             /* Set fd to -1 to make ET_DESTROY free "pend". */
512             pend->fd = -1;
513             return;
514         case ET_READ:
515         case ET_WRITE:
516             /* Continue Handshake */
517             ret = ssl_be_handshake(pend->session->cred->mode, &pend->session->be);
518             if(ret == SSL_SUCCESS) {
519                 pend->session->fingerprint = strdup(ssl_be_fingerprint(&pend->session->be));
520                 timer_del(&pend->timeout);
521                 socket_del(&pend->socket);
522                 add_connection(pend->listener, pend->fd, pend->session);
523                 /* Set fd to -1 to make ET_DESTROY free "pend". */
524                 pend->fd = -1;
525                 return;
526             }
527             else if(ret == SSL_NEED_RD) {
528                 socket_events(&pend->socket, SOCK_ACTION_SET | SOCK_EVENT_READABLE);
529                 return;
530             }
531             else if(ret == SSL_NEED_WR || ret == SSL_NEED_RDWR) {
532                 socket_events(&pend->socket, SOCK_ACTION_SET | SOCK_EVENT_READABLE | SOCK_EVENT_WRITABLE);
533                 return;
534             }
535             else /* SSL_FAILURE */ {
536                 ssl_session_shutdown(pend->session);
537                 close(pend->fd);
538                 ssl_session_free(pend->session);
539                 socket_del(&pend->socket);
540                 timer_del(&pend->timeout);
541                 /* Set fd to -1 to make ET_DESTROY free "pend". */
542                 pend->fd = -1;
543                 return;
544             }
545         default:
546             return;
547     }
548 }
549 static void ssl_timer_callback(struct Event* ev) {
550     struct ssl_pending_t *pend;
551
552     pend = t_data(ev_timer(ev));
553     switch(ev_type(ev)) {
554         case ET_DESTROY:
555             /* Decrease refcount here because this is guaranteed to be called when the
556              * connection gets destructed in any way.
557              */
558             --pend->listener->ref_count;
559             /* Destruct \pend if required. */
560             if(pend->fd == -1) MyFree(pend);
561             return;
562         case ET_EXPIRE:
563             ssl_session_shutdown(pend->session);
564             close(pend->fd);
565             ssl_session_free(pend->session);
566             socket_del(&pend->socket);
567             timer_del(&pend->timeout);
568             /* Set fd to -1 to make ET_DESTROY free "pend". */
569             pend->fd = -1;
570             return;
571         default:
572             return;
573     }
574 }
575 void ssl_accept(struct Listener *listener, signed int fd) {
576     unsigned int ret;
577     struct ssl_pending_t *pend;
578
579     if(!os_set_nonblocking(fd)) {
580         close(fd);
581         return;
582     }
583     os_disable_options(fd);
584
585     pend = MyMalloc(sizeof(struct ssl_pending_t));
586     pend->listener = listener;
587     pend->fd = fd;
588     pend->session = ssl_session_new(SSL_SERVER);
589
590     if(!pend->session) {
591         MyFree(pend);
592         close(fd);
593         ssl_msg(SSL_ERROR, "SSL: ssl_accept(%d): failed", fd);
594         return;
595     }
596
597     if(!socket_add(&pend->socket, ssl_socket_callback, (void*)pend, SS_CONNECTED, SOCK_EVENT_READABLE, fd)) {
598         ssl_session_shutdown(pend->session);
599         close(fd);
600         ssl_session_free(pend->session);
601         MyFree(pend);
602         ssl_msg(SSL_ERROR, "SSL: ssl_accept(%d): failed", fd);
603         return;
604     }
605
606     if(!ssl_be_session_connect(&pend->session->be, fd)) {
607         socket_del(&pend->socket);
608         ssl_session_shutdown(pend->session);
609         close(fd);
610         ssl_session_free(pend->session);
611         MyFree(pend);
612         ssl_msg(SSL_ERROR, "SSL: ssl_accept(%d): failed", fd);
613         return;
614     }
615
616     ret = ssl_be_handshake(pend->session->cred->mode, &pend->session->be);
617     if(ret == SSL_SUCCESS) {
618         pend->session->fingerprint = strdup(ssl_be_fingerprint(&pend->session->be));
619         socket_del(&pend->socket);
620         add_connection(pend->listener, pend->fd, pend->session);
621         MyFree(pend);
622         return;
623     }
624     else if(ret == SSL_NEED_RD || ret == SSL_NEED_WR || ret == SSL_NEED_RDWR) {
625         if(ret != SSL_NEED_RD) {
626             socket_events(&pend->socket, SOCK_ACTION_SET | SOCK_EVENT_READABLE | SOCK_EVENT_WRITABLE);
627         }
628         timer_init(&pend->timeout);
629         timer_add(&pend->timeout, ssl_timer_callback, (void*)pend, TT_RELATIVE, 20);
630         ++listener->ref_count;
631         return;
632     }
633     else /* SSL_FAILURE */ {
634         socket_del(&pend->socket);
635         ssl_session_shutdown(pend->session);
636         close(fd);
637         ssl_session_free(pend->session);
638         MyFree(pend);
639         ssl_msg(SSL_DEBUG, "SSL: ssl_accept(%d): failed", fd);
640         return;
641     }
642 }
643 static void ssl_csocket_callback(struct Event* ev) {
644     struct ssl_conn_t *conn;
645     unsigned int ret;
646
647     conn = s_data(ev_socket(ev));
648     switch(ev_type(ev)) {
649         case ET_DESTROY:
650             return;
651         case ET_ERROR:
652         case ET_EOF:
653             cli_socket(conn->cptr).s_header.gh_call = client_sock_callback;
654             s_data(&(cli_socket(conn->cptr))) = conn->olddata;
655             ssl_session_free(conn->session);
656             cli_socket(conn->cptr).ssl = NULL;
657             exit_client_msg(conn->cptr, conn->cptr, &me, "SSL connection timedout.");
658             sendto_opmask_butone(0, SNO_OLDSNO, "Connection failed to %s: SSL timeout.", cli_name(conn->cptr));
659             conn->cptr = NULL;
660             timer_del(&conn->timeout);
661             return;
662         case ET_READ:
663         case ET_WRITE:
664             /* Continue Handshake */
665             ret = ssl_be_handshake(conn->session->cred->mode, &conn->session->be);
666             if(ret == SSL_SUCCESS) {
667                 cli_socket(conn->cptr).s_header.gh_call = client_sock_callback;
668                 s_data(&(cli_socket(conn->cptr))) = conn->olddata;
669                 conn->session->fingerprint = strdup(ssl_be_fingerprint(&conn->session->be));
670                 if(completed_connection(conn->cptr) == 0) {
671                     ssl_session_free(conn->session);
672                     cli_socket(conn->cptr).ssl = NULL;
673                     exit_client_msg(conn->cptr, conn->cptr, &me, "SSL handshake rejected.");
674                 }
675                 conn->cptr = NULL;
676                 timer_del(&conn->timeout);
677                 return;
678             }
679             else if(ret == SSL_NEED_RD) {
680                 socket_events(&cli_socket(conn->cptr), SOCK_ACTION_SET | SOCK_EVENT_READABLE);
681                 return;
682             }
683             else if(ret == SSL_NEED_WR || ret == SSL_NEED_RDWR) {
684                 socket_events(&cli_socket(conn->cptr), SOCK_ACTION_SET | SOCK_EVENT_READABLE | SOCK_EVENT_WRITABLE);
685                 return;
686             }
687             else /* SSL_FAILURE */ {
688                 cli_socket(conn->cptr).s_header.gh_call = client_sock_callback;
689                 s_data(&(cli_socket(conn->cptr))) = conn->olddata;
690                 ssl_session_free(conn->session);
691                 cli_socket(conn->cptr).ssl = NULL;
692                 exit_client_msg(conn->cptr, conn->cptr, &me, "SSL connection timedout.");
693                 sendto_opmask_butone(0, SNO_OLDSNO, "Connection failed to %s: SSL timeout.", cli_name(conn->cptr));
694                 conn->cptr = NULL;
695                 timer_del(&conn->timeout);
696                 return;
697             }
698         default:
699             return;
700     }
701 }
702 static void ssl_ctimer_callback(struct Event* ev) {
703     struct ssl_conn_t *conn;
704
705     conn = t_data(ev_timer(ev));
706     switch(ev_type(ev)) {
707         case ET_DESTROY:
708             if(conn->cptr == NULL) MyFree(conn);
709             return;
710         case ET_EXPIRE:
711             cli_socket(conn->cptr).s_header.gh_call = client_sock_callback;
712             s_data(&(cli_socket(conn->cptr))) = conn->olddata;
713             ssl_session_free(conn->session);
714             cli_socket(conn->cptr).ssl = NULL;
715             exit_client_msg(conn->cptr, conn->cptr, &me, "SSL connection timedout.");
716             sendto_opmask_butone(0, SNO_OLDSNO, "Connection failed to %s: SSL timeout.", cli_name(conn->cptr));
717             conn->cptr = NULL;
718             timer_del(&conn->timeout);
719             return;
720         default:
721             return;
722     }
723 }
724 signed int ssl_connect(struct Client *cptr) {
725     struct ssl_conn_t *conn;
726     unsigned int ret;
727     signed int tmp;
728
729     conn = MyMalloc(sizeof(struct ssl_conn_t));
730     memset(conn, 0, sizeof(struct ssl_conn_t));
731
732     conn->cptr = cptr;
733     conn->session = ssl_session_new(SSL_CLIENT);
734     cli_socket(cptr).ssl = conn->session;
735
736     if(!conn->session) {
737         cli_socket(cptr).ssl = NULL;
738         MyFree(conn);
739         ssl_msg(SSL_ERROR, "SSL: ssl_connect(): failed");
740         sendto_opmask_butone(0, SNO_OLDSNO, "Connection failed to %s: SSL session-creation failed.", cli_name(cptr));
741         return 0;
742     }
743
744     if(!ssl_be_session_connect(&conn->session->be, s_fd(&(cli_socket(cptr))))) {
745         cli_socket(cptr).ssl = NULL;
746         ssl_session_free(conn->session);
747         MyFree(conn);
748         ssl_msg(SSL_ERROR, "SSL: ssl_connect(): failed");
749         sendto_opmask_butone(0, SNO_OLDSNO, "Connection failed to %s: SSL fd-connect failed.", cli_name(cptr));
750         return 0;
751     }
752
753     ret = ssl_be_handshake(conn->session->cred->mode, &conn->session->be);
754     if(ret == SSL_SUCCESS) {
755         conn->session->fingerprint = strdup(ssl_be_fingerprint(&conn->session->be));
756         tmp = completed_connection(cptr);
757         MyFree(conn);
758         return tmp;
759     }
760     else if(ret == SSL_NEED_RD || ret == SSL_NEED_WR || ret == SSL_NEED_RDWR) {
761         if(ret == SSL_NEED_RD) {
762             socket_events(&cli_socket(cptr), SOCK_ACTION_SET | SOCK_EVENT_READABLE);
763         }
764         else {
765             socket_events(&cli_socket(cptr), SOCK_ACTION_SET | SOCK_EVENT_READABLE | SOCK_EVENT_WRITABLE);
766         }
767         /* Change callback temporarily to avoid ET_DESTROY on the old callback.
768          * We will change this back before ET_DESTROY is called.
769          */
770         cli_socket(cptr).s_header.gh_call = ssl_csocket_callback;
771         conn->olddata = s_data(&(cli_socket(cptr)));
772         s_data(&(cli_socket(cptr))) = conn;
773         timer_init(&conn->timeout);
774         timer_add(&conn->timeout, ssl_ctimer_callback, (void*)conn, TT_RELATIVE, 20);
775         return 1;
776     }
777     else /* SSL_FAILURE */ {
778         cli_socket(cptr).ssl = NULL;
779         ssl_session_free(conn->session);
780         MyFree(conn);
781         ssl_msg(SSL_ERROR, "SSL: ssl_connect(): failed");
782         sendto_opmask_butone(0, SNO_OLDSNO, "Connection failed to %s: SSL handshake failed.", cli_name(cptr));
783         return 0;
784     }
785     return 0;
786 }
787
788
789 /* Basic IO on SSL sockets. */
790 void ssl_close(signed int fd, ssl_session_t *ssl, const char *buf, unsigned int len) {
791     if(!ssl) {
792         write(fd, buf, len);
793         close(fd);
794     }
795     else {
796         ssl_be_send(fd, &ssl->be, buf, &len);
797         ssl_session_shutdown(ssl);
798         close(fd);
799         ssl_session_free(ssl);
800     }
801 }
802 signed int ssl_send(signed int fd, ssl_session_t *ssl, const char *buf, unsigned int len) {
803     if(!ssl) {
804         return write(fd, buf, len);
805     }
806     else {
807         ssl_be_send(fd, &ssl->be, buf, &len);
808         return len;
809     }
810 }
811 IOResult ssl_recv(signed int fd, ssl_session_t *ssl, char *buf, unsigned int len, unsigned int *count_out) {
812     if(!ssl) {
813         return os_recv_nonb(fd, buf, len, count_out);
814     }
815     *count_out = len;
816     return ssl_be_recv(fd, &ssl->be, buf, count_out);
817 }
818 IOResult ssl_sendv(signed int fd, ssl_session_t *ssl, struct MsgQ *buf, unsigned int *count_in, unsigned int *count_out) {
819     #ifndef IOV_MAX
820         #define IOV_MAX 16
821     #endif /* IOV_MAX */
822     signed int count;
823     unsigned int k, tmp;
824     struct iovec iov[IOV_MAX];
825     IOResult ret = IO_BLOCKED, res;
826
827     if(!ssl) {
828         return os_sendv_nonb(fd, buf, count_in, count_out);
829     }
830
831     *count_in = 0;
832     *count_out = 0;
833     count = msgq_mapiov(buf, iov, IOV_MAX, count_in);
834
835     for(k = 0; k < count; ++k) {
836         tmp = iov[k].iov_len;
837         res = ssl_be_send(fd, &ssl->be, iov[k].iov_base, &tmp);
838         if(res == IO_FAILURE) return IO_FAILURE;
839         else if(tmp == 0) return ret;
840         else {
841             *count_out += tmp;
842             ret = IO_SUCCESS;
843         }
844     }
845     return ret;
846 }
847 const char *ssl_cipherstr(ssl_session_t *ssl) {
848     return ssl_be_cipherstr(&ssl->be);
849 }
850
851
852
853
854 /*******************************************************************************/
855 /*******************************************************************************/
856 /*******************************************************************************/
857 /*******************************************************************************/
858 /*******************************************************************************/
859 /**********************            GnuTLS backend              *****************/
860 /*******************************************************************************/
861 /*******************************************************************************/
862 /*******************************************************************************/
863 /*******************************************************************************/
864 /*******************************************************************************/
865
866
867
868
869 #ifdef HAVE_GNUTLS
870     unsigned int ssl_be_init() {
871         signed int ret;
872         if((ret = gnutls_global_init()) != GNUTLS_E_SUCCESS) {
873             ssl_msg(SSL_ERROR, "SSL: gnutls_global_init(): failed (%d)", ret);
874             return 0;
875         }
876         else return 1;
877     }
878     void ssl_be_deinit() {
879         gnutls_global_deinit();
880     }
881     unsigned int ssl_be_cred_new(unsigned int mode, char *cert, char **trusts, ssl_be_cred_t *cred) {
882         signed int ret;
883         unsigned int i;
884         if((ret = gnutls_dh_params_init(&cred->dhparams)) != GNUTLS_E_SUCCESS) {
885             ssl_msg(SSL_ERROR, "SSL: gnutls_dh_params_init(): failed (%d)", ret);
886             return 0;
887         }
888         if((ret = gnutls_dh_params_generate2(cred->dhparams, SSL_DH_BITS)) != GNUTLS_E_SUCCESS) {
889             gnutls_dh_params_deinit(cred->dhparams);
890             ssl_msg(SSL_ERROR, "SSL: gnutls_dh_params_generate2(): failed (%d)", ret);
891             return 0;
892         }
893         if((ret = gnutls_certificate_allocate_credentials(&cred->cred)) != GNUTLS_E_SUCCESS) {
894             gnutls_dh_params_deinit(cred->dhparams);
895             ssl_msg(SSL_ERROR, "SSL: gnutls_certificate_allocate_credentials(): failed (%d)", ret);
896             return 0;
897         }
898         i = 0;
899         while(trusts[i]) {
900             if((ret = gnutls_certificate_set_x509_trust_file(cred->cred, trusts[i], GNUTLS_X509_FMT_PEM)) != GNUTLS_E_SUCCESS) {
901                 ssl_msg(SSL_NOTICE, "SSL: gnutls_certificate_set_x509_trust_file('%s'): failed (%d)", trusts[i], ret);
902                 /* ignore errors here */
903             }
904             ++i;
905         }
906         if((ret = gnutls_certificate_set_x509_key_file(cred->cred, cert, cert, GNUTLS_X509_FMT_PEM)) != GNUTLS_E_SUCCESS) {
907             gnutls_certificate_free_credentials(cred->cred);
908             gnutls_dh_params_deinit(cred->dhparams);
909             ssl_msg(SSL_NOTICE, "SSL: gnutls_certificate_set_x509_key_file('%s'): failed (%d)", cert, ret);
910             return 0;
911         }
912         gnutls_certificate_set_dh_params(cred->cred, cred->dhparams);
913         gnutls_priority_init(&cred->prio, "NORMAL", NULL);
914         return 1;
915     }
916     void ssl_be_cred_free(ssl_be_cred_t *cred) {
917         gnutls_certificate_free_credentials(cred->cred);
918         gnutls_priority_deinit(cred->prio);
919         gnutls_dh_params_deinit(cred->dhparams);
920     }
921     unsigned int ssl_be_session_new(unsigned int mode, ssl_be_cred_t *cred, ssl_be_session_t *session) {
922         signed int ret;
923         if(mode == SSL_CLIENT) {
924             if((ret = gnutls_init(session, GNUTLS_CLIENT)) != GNUTLS_E_SUCCESS) {
925                 ssl_msg(SSL_ERROR, "SSL: gnutls_init(): failed (%d)", ret);
926                 return 0;
927             }
928             gnutls_priority_set(*session, cred->prio);
929             /*if((ret = gnutls_priority_set_direct(*session, "NORMAL", NULL)) != GNUTLS_E_SUCCESS) {
930                 gnutls_deinit(*session);
931                 ssl_msg(SSL_ERROR, "SSL: gnutls_priority_set_direct(): failed (%d)", ret);
932                 return 0;
933             }*/
934             if((ret = gnutls_credentials_set(*session, GNUTLS_CRD_CERTIFICATE, cred->cred)) != GNUTLS_E_SUCCESS) {
935                 gnutls_deinit(*session);
936                 ssl_msg(SSL_ERROR, "SSL: gnutls_credentials_set(): failed (%d)", ret);
937                 return 0;
938             }
939             gnutls_dh_set_prime_bits(*session, SSL_DH_RBITS);
940         }
941         else {
942             if((ret = gnutls_init(session, GNUTLS_SERVER)) != GNUTLS_E_SUCCESS) {
943                 ssl_msg(SSL_ERROR, "SSL: gnutls_init(): failed (%d)", ret);
944                 return 0;
945             }
946             gnutls_priority_set(*session, cred->prio);
947             /*if((ret = gnutls_priority_set_direct(*session, "NORMAL", NULL)) != GNUTLS_E_SUCCESS) {
948                 gnutls_deinit(*session);
949                 ssl_msg(SSL_ERROR, "SSL: gnutls_priority_set_direct(): failed (%d)", ret);
950                 return 0;
951             }*/
952             if((ret = gnutls_credentials_set(*session, GNUTLS_CRD_CERTIFICATE, cred->cred)) != GNUTLS_E_SUCCESS) {
953                 gnutls_deinit(*session);
954                 ssl_msg(SSL_ERROR, "SSL: gnutls_credentials_set(): failed (%d)", ret);
955                 return 0;
956             }
957             gnutls_certificate_server_set_request(*session, GNUTLS_CERT_REQUEST);
958         }
959         return 1;
960     }
961     unsigned int ssl_be_session_connect(ssl_be_session_t *session, signed int fd) {
962         gnutls_transport_set_ptr(*session, (gnutls_transport_ptr_t)fd);
963         return 1;
964     }
965     void ssl_be_session_shutdown(ssl_be_session_t *session) {
966         gnutls_bye(*session, GNUTLS_SHUT_WR);
967     }
968     void ssl_be_session_free(ssl_be_session_t *session) {
969         gnutls_deinit(*session);
970     }
971     unsigned int ssl_be_handshake(unsigned int mode, ssl_be_session_t *session) {
972         signed int ret;
973         ret = gnutls_handshake(*session);
974         if(ret < 0) {
975             if(ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED) {
976                 if(gnutls_record_get_direction(*session) == 0) return SSL_NEED_RD;
977                 else return SSL_NEED_WR;
978             }
979             else {
980                 ssl_msg(SSL_DEBUG, "SSL: gnutls_handshake(): failed (%d)", ret);
981                 return SSL_FAILURE;
982             }
983         }
984         else return SSL_SUCCESS;
985     }
986     const char *ssl_be_cipherstr(ssl_be_session_t *session) {
987         static char buf[401];
988         const char *kx_name, *cipher_name, *mac_name;
989         unsigned int len, i;
990         char *dest;
991
992         kx_name = gnutls_kx_get_name(gnutls_kx_get(*session));
993         cipher_name = gnutls_cipher_get_name(gnutls_cipher_get(*session));
994         mac_name = gnutls_mac_get_name(gnutls_mac_get(*session));
995
996         if(!kx_name || !cipher_name || !mac_name) {
997             ssl_msg(SSL_ERROR, "SSL: gnutls_[kx,cipher,mac]_get_name(): failed");
998             return "<invalid>";
999         }
1000
1001         len = strlen(kx_name) + strlen(cipher_name) + strlen(mac_name);
1002         if(len > 395) {
1003             ssl_msg(SSL_ERROR, "SSL: gnutls_[kx,cipher,mac]_get_name(): too long");
1004             return "<invalid>";
1005         }
1006         else {
1007             dest = buf;
1008             i = 0;
1009             while((*dest++ = kx_name[i++])) /* empty */ ;
1010             *(dest - 1) = '-';
1011             i = 0;
1012             while((*dest++ = cipher_name[i++])) /* empty */ ;
1013             *(dest - 1) = '-';
1014             i = 0;
1015             while((*dest++ = mac_name[i++])) /* empty */ ;
1016             return buf;
1017         }
1018     }
1019     const char *ssl_be_fingerprint(ssl_be_session_t *session) {
1020         return "<invalid>";
1021     }
1022     IOResult ssl_be_send(signed int fd, ssl_be_session_t *ssl, const char *buf, unsigned int *count_out) {
1023         signed int res;
1024         res = gnutls_record_send(*ssl, buf, *count_out);
1025         *count_out = 0;
1026         if(res == 0) return IO_FAILURE;
1027         else if(res < 0) {
1028             if(res != GNUTLS_E_AGAIN && res != GNUTLS_E_INTERRUPTED) return IO_FAILURE;
1029             else return IO_BLOCKED;
1030         }
1031         else {
1032             *count_out = res;
1033             return IO_SUCCESS;
1034         }
1035     }
1036     IOResult ssl_be_recv(signed int fd, ssl_be_session_t *ssl, char *buf, unsigned int *count_out) {
1037         signed int res;
1038         res = gnutls_record_recv(*ssl, buf, *count_out);
1039         *count_out = 0;
1040         if(res == 0) return IO_FAILURE;
1041         else if(res < 0) {
1042             if(res == GNUTLS_E_AGAIN || res == GNUTLS_E_INTERRUPTED) return IO_BLOCKED;
1043             else return IO_FAILURE;
1044         }
1045         else {
1046             *count_out = res;
1047             return IO_SUCCESS;
1048         }
1049     }
1050
1051
1052
1053
1054 /*******************************************************************************/
1055 /*******************************************************************************/
1056 /*******************************************************************************/
1057 /*******************************************************************************/
1058 /*******************************************************************************/
1059 /**********************            OpenSSL backend             *****************/
1060 /*******************************************************************************/
1061 /*******************************************************************************/
1062 /*******************************************************************************/
1063 /*******************************************************************************/
1064 /*******************************************************************************/
1065
1066
1067
1068
1069 #elif defined(HAVE_OPENSSL)
1070     unsigned int ssl_be_init() {
1071         SSL_library_init();
1072         /* Load error strings; Returns void. */
1073         SSL_load_error_strings();
1074         /* Seed the random number generator. We do not care for errors here. */
1075         RAND_load_file("/dev/urandom", 4096);
1076         return 1;
1077     }
1078     void ssl_be_deinit() {
1079         ERR_free_strings();
1080     }
1081     unsigned int ssl_be_cred_new(unsigned int mode, char *cert, char **trusts, ssl_be_cred_t *cred) {
1082         if(mode == SSL_CLIENT) {
1083             *cred = SSL_CTX_new(SSLv23_client_method());
1084             if(!*cred) {
1085                 ssl_msg(SSL_ERROR, "SSL: SSL_CTX_new(): failed");
1086                 return 0;
1087             }
1088             if(*trusts) {
1089                 if(*(trusts + 1)) ssl_msg(SSL_NOTICE, "SSL: (OpenSSL) skipping further CA files");
1090                 if(!SSL_CTX_load_verify_locations(*cred, *trusts, NULL)) {
1091                     ssl_msg(SSL_NOTICE, "SSL: SSL_CTX_load_verify_locations('%s'): failed", *trusts);
1092                     /* ignore errors here */
1093                 }
1094                 else SSL_CTX_set_client_CA_list(*cred, SSL_load_client_CA_file(*trusts));
1095             }
1096             SSL_CTX_set_mode(*cred, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
1097             if(!SSL_CTX_use_certificate_file(*cred, cert, SSL_FILETYPE_PEM)) {
1098                 SSL_CTX_free(*cred);
1099                 ssl_msg(SSL_NOTICE, "SSL: SSL_CTX_use_certificate_file('%s'): failed", cert);
1100                 return 0;
1101             }
1102             if(!SSL_CTX_use_PrivateKey_file(*cred, cert, SSL_FILETYPE_PEM)) {
1103                 SSL_CTX_free(*cred);
1104                 ssl_msg(SSL_NOTICE, "SSL: SSL_CTX_use_PrivateKey_file('%s'): failed", cert);
1105                 return 0;
1106             }
1107             SSL_CTX_set_verify(*cred, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, ssl_be_verify);
1108         }
1109         else {
1110             *cred = SSL_CTX_new(SSLv23_server_method());
1111             if(!*cred) {
1112                 ssl_msg(SSL_ERROR, "SSL: SSL_CTX_new(): failed");
1113                 return 0;
1114             }
1115             SSL_CTX_set_mode(*cred, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
1116             if(!SSL_CTX_use_certificate_file(*cred, cert, SSL_FILETYPE_PEM)) {
1117                 SSL_CTX_free(*cred);
1118                 ssl_msg(SSL_NOTICE, "SSL: SSL_CTX_use_certificate_file('%s'): failed", cert);
1119                 return 0;
1120             }
1121             if(!SSL_CTX_use_PrivateKey_file(*cred, cert, SSL_FILETYPE_PEM)) {
1122                 SSL_CTX_free(*cred);
1123                 ssl_msg(SSL_NOTICE, "SSL: SSL_CTX_use_PrivateKey_file('%s'): failed", cert);
1124                 return 0;
1125             }
1126         }
1127         return 1;
1128     }
1129     void ssl_be_cred_free(ssl_be_cred_t *cred) {
1130         SSL_CTX_free(*cred);
1131     }
1132     unsigned int ssl_be_session_new(unsigned int mode, ssl_be_cred_t *cred, ssl_be_session_t *session) {
1133         *session = SSL_new(*cred);
1134         if(!*session) {
1135             ssl_msg(SSL_ERROR, "SSL: SSL_new(%u): failed", mode);
1136             return 0;
1137         }
1138         return 1;
1139     }
1140     unsigned int ssl_be_session_connect(ssl_be_session_t *session, signed int fd) {
1141         SSL_set_fd(*session, fd);
1142         return 1;
1143     }
1144     void ssl_be_session_shutdown(ssl_be_session_t *session) {
1145         SSL_shutdown(*session);
1146     }
1147     void ssl_be_session_free(ssl_be_session_t *session) {
1148         SSL_free(*session);
1149     }
1150     unsigned int ssl_be_handshake(unsigned int mode, ssl_be_session_t *session) {
1151         signed int ret;
1152         if(mode == SSL_CLIENT) ret = SSL_connect(*session);
1153         else ret = SSL_accept(*session);
1154         if(ret <= 0) {
1155             ret = SSL_get_error(*session, ret);
1156             if(ret == SSL_ERROR_WANT_READ || ret == SSL_ERROR_WANT_WRITE) {
1157                 if(ret == SSL_ERROR_WANT_READ) return SSL_NEED_RD;
1158                 else return SSL_NEED_WR;
1159             }
1160             else {
1161                 ssl_msg(SSL_DEBUG, "SSL: gnutls_handshake(): failed (%d)", ret);
1162                 return SSL_FAILURE;
1163             }
1164         }
1165         else return SSL_SUCCESS;
1166     }
1167     const char *ssl_be_cipherstr(ssl_be_session_t *session) {
1168         static char buf[400];
1169         char buf2[128];
1170         int bits;
1171         SSL_CIPHER *c;
1172
1173         buf[0] = '\0';
1174         strcpy(buf, SSL_get_version(*session));
1175         strcat(buf, "-");
1176         strcat(buf, SSL_get_cipher(*session));
1177         c = SSL_get_current_cipher(*session);
1178         SSL_CIPHER_get_bits(c, &bits);
1179         strcat(buf, "-");
1180         ircd_snprintf(0, buf2, sizeof(buf2), "%d", bits);
1181         strcat(buf, buf2);
1182         strcat(buf, "bits");
1183         return buf;
1184     }
1185     const char *ssl_be_fingerprint(ssl_be_session_t *session) {
1186         return "<invalid>";
1187     }
1188     IOResult ssl_be_send(signed int fd, ssl_be_session_t *ssl, const char *buf, unsigned int *count_out) {
1189         signed int res, merrno;
1190
1191 #ifdef SSL_EAGAIN_DEBUG
1192         signed int back, back_c;
1193         char buffer[4097];
1194 #endif
1195
1196         res = SSL_write(*ssl, buf, *count_out);
1197         merrno = errno;
1198
1199 #ifdef SSL_EAGAIN_DEBUG
1200         back_c = *count_out;
1201 #endif
1202
1203         *count_out = 0;
1204         if(res == 0) return IO_FAILURE;
1205         else if(res < 0) {
1206 #ifdef SSL_EAGAIN_DEBUG
1207             back = res;
1208 #endif
1209             res = SSL_get_error(*ssl, res);
1210             /* HACK HACK HACK!
1211              * OpenSSL sucks! This hack still returns IO_BLOCKED on special SYSCALL failures.
1212              * The ircd system is built that the user will be killed automatically when this
1213              * happens too often so we can safely return this here, however, the OpenSSL devs
1214              * should *REALLY* fix this. They're already noticed.
1215              * --gix
1216              */
1217             if(res != SSL_ERROR_WANT_READ && res != SSL_ERROR_WANT_WRITE && res != SSL_ERROR_WANT_X509_LOOKUP) {
1218                 if(merrno == EAGAIN || merrno == EINTR || merrno == EWOULDBLOCK || merrno == EBUSY) {
1219 #ifdef SSL_EAGAIN_DEBUG
1220                     snprintf(buffer, (back_c > 4096)?4096:back_c, "%s", buf);
1221                     buffer[4096] = 0;
1222                     ssl_msg(SSL_NOTICE, "OpenSSL: EAGAIN debug information: fd (%d) err (%d) serr (%d) "
1223                                         "derr1 (%lu) derr2 (%lu) back (%d) len (%u) buf (%s)",
1224                                         fd, merrno, res, ERR_peek_error(), ERR_peek_last_error(), back, back_c, buffer);
1225 #endif
1226                     return IO_BLOCKED;
1227                 }
1228                 return IO_FAILURE;
1229             }
1230             else return IO_BLOCKED;
1231         }
1232         else {
1233             *count_out = res;
1234             return IO_SUCCESS;
1235         }
1236     }
1237     IOResult ssl_be_recv(signed int fd, ssl_be_session_t *ssl, char *buf, unsigned int *count_out) {
1238         signed int res, merrno;
1239         res = SSL_read(*ssl, buf, *count_out);
1240         merrno = errno;
1241         *count_out = 0;
1242         if(res == 0) return IO_FAILURE;
1243         else if(res < 0) {
1244             res = SSL_get_error(*ssl, res);
1245             if(res == SSL_ERROR_WANT_READ || res == SSL_ERROR_WANT_WRITE || res == SSL_ERROR_WANT_X509_LOOKUP) return IO_BLOCKED;
1246             /* HACK HACK HACK!
1247              * OpenSSL sucks! This hack still returns IO_BLOCKED on special SYSCALL failures.
1248              * The ircd system is built that the user will be killed automatically when this
1249              * happens too often so we can safely return this here, however, the OpenSSL devs
1250              * should *REALLY* fix this. They're already noticed.
1251              * --gix
1252              */
1253             else if(merrno == EAGAIN || merrno == EINTR || merrno == EWOULDBLOCK || merrno == EBUSY) return IO_BLOCKED;
1254             else return IO_FAILURE;
1255         }
1256         else {
1257             *count_out = res;
1258             return IO_SUCCESS;
1259         }
1260     }
1261     static signed int ssl_be_verify(signed int preverify_ok, X509_STORE_CTX *ctx) {
1262         return 1;
1263     }
1264
1265
1266
1267
1268 /*******************************************************************************/
1269 /*******************************************************************************/
1270 /*******************************************************************************/
1271 /*******************************************************************************/
1272 /*******************************************************************************/
1273 /**********************             Dummy backend              *****************/
1274 /*******************************************************************************/
1275 /*******************************************************************************/
1276 /*******************************************************************************/
1277 /*******************************************************************************/
1278 /*******************************************************************************/
1279
1280
1281
1282
1283 #else
1284     unsigned int ssl_be_init() {
1285         return 1;
1286     }
1287     void ssl_be_deinit() {
1288         return;
1289     }
1290     unsigned int ssl_be_cred_new(unsigned int mode, char *cert, char **trusts, ssl_be_cred_t *cred) {
1291         *cred = NULL;
1292         return 1;
1293     }
1294     void ssl_be_cred_free(ssl_be_cred_t *cred) {
1295         return;
1296     }
1297     unsigned int ssl_be_session_new(unsigned int mode, ssl_be_cred_t *cred, ssl_be_session_t *session) {
1298         *session = NULL;
1299         return 1;
1300     }
1301     unsigned int ssl_be_session_connect(ssl_be_session_t *session, signed int fd) {
1302         return 1;
1303     }
1304     void ssl_be_session_shutdown(ssl_be_session_t *session) {
1305         return;
1306     }
1307     void ssl_be_session_free(ssl_be_session_t *session) {
1308         return;
1309     }
1310     unsigned int ssl_be_handshake(unsigned int mode, ssl_be_session_t *session) {
1311         return SSL_FAILURE;
1312     }
1313     const char *ssl_be_cipherstr(ssl_be_session_t *session) {
1314         return "PLAINTEXT";
1315     }
1316     const char *ssl_be_fingerprint(ssl_be_session_t *session) {
1317         return "<invalid>";
1318     }
1319     IOResult ssl_be_send(signed int fd, ssl_be_session_t *ssl, const char *buf, unsigned int *count_out) {
1320         return IO_FAILURE;
1321     }
1322     IOResult ssl_be_recv(signed int fd, ssl_be_session_t *ssl, char *buf, unsigned int *count_out) {
1323         return IO_FAILURE;
1324     }
1325 #endif
1326