]> jfr.im git - irc/DALnet/libd.git/commitdiff
Integrate SSL components into the read/write flow.
authorepiphani <redacted>
Wed, 20 May 2009 21:18:21 +0000 (17:18 -0400)
committerepiphani <redacted>
Wed, 20 May 2009 21:18:21 +0000 (17:18 -0400)
include/sockeng.h
include/wrap_ssl.h [new file with mode: 0644]
src/client.c
src/listener.c
src/wrap_ssl.c

index 20200b9a741d7a6cbf4bdc33d0c926efc7efd88e..bdfc103b2556f196f225845d8ff091178449cc22 100644 (file)
@@ -128,6 +128,10 @@ struct _client {
        unsigned short  port;                   /* the remote port */
        int             type;                   /* the type of this connection (tcp/udp/raw) */
 
+#ifdef USE_SSL
+       SSL             *sslid;                 /* ssl handle for this client */
+#endif
+
        Listener        *listener;              /* listener this client came in on (optional) */
        SockEng         *sockeng;               /* socket engine for this client */
 
@@ -148,6 +152,9 @@ struct _client {
 /*
  * The listener structure provides all necessary details in order to build and maintain a listener
  */
+
+#define LISTEN_SSL 0x01
+
 struct _listener {
        myfd            fdp;            /* file descriptor abstraction */
        unsigned short  port;           /* port of the descriptor */
diff --git a/include/wrap_ssl.h b/include/wrap_ssl.h
new file mode 100644 (file)
index 0000000..5cd18f8
--- /dev/null
@@ -0,0 +1,18 @@
+/* wrap_ssl.h
+ * external definitions of SSL wrapping functions
+ */
+
+#ifdef USE_SSL
+#ifndef WRAP_SSL_H
+#define WRAP_SSL_H
+
+#include "sockeng.h"
+
+extern int ssl_init(SockEng *s, char *certpath, char *keypath);
+extern int sslread(SSL *id, void *buf, int sz);
+extern int sslwrite(SSL *id, void *buf, int sz);
+extern int sslaccept(Client *c);
+extern void sslshut(SSL *id);
+
+#endif
+#endif
index c73f86531b451e44dbe790f9e996cf53d74be391..9197458d6b62a75dedc1834549826eb793b28026 100644 (file)
@@ -4,6 +4,7 @@
 
 #include "sockeng.h"
 #include "mfd.h"
+#include "wrap_ssl.h"
 
 static int client_send(Client *c, char *msg, int len)
 {
@@ -20,6 +21,10 @@ static int client_close(Client *c)
        ebuf_delete(&c->recvQ, eBufLength(&c->recvQ));
        ebuf_delete(&c->sendQ, eBufLength(&c->sendQ));
        mfd_del(c->sockeng, &c->fdp);
+#ifdef USE_SSL
+       if(c->sslid)
+               sslshut(c->sslid);
+#endif
        close(c->fdp.fd);
        free(c);
        return RET_OK;
@@ -71,7 +76,14 @@ static void client_doread(Client *c)
        static char readbuf[BUFSIZE];
        int len, plen;
 
+#ifdef USE_SSL
+       if(c->sslid)
+               len = sslread(c->sslid, readbuf, sizeof(readbuf));
+       else
+               len = recv(c->fdp.fd, readbuf, sizeof(readbuf), 0);
+#else
        len = recv(c->fdp.fd, readbuf, sizeof(readbuf), 0);
+#endif
        if(len < 0) {
                if(errno == EWOULDBLOCK || errno == EAGAIN)
                        return;
@@ -108,7 +120,15 @@ static void client_dowrite(Client *c)
                return;
        }
        num = ebuf_mapiov(&c->sendQ, v);
+#ifdef USE_SSL
+       /* FIXME:  revisit this - maybe we should try to do mulitple sslwrite() calls here to flush buffers faster */
+       if(c->sslid)
+               ret = sslwrite(c->sslid, v->iov_base, v->iov_len);
+       else
+               ret = writev(c->fdp.fd, v, num);
+#else
        ret = writev(c->fdp.fd, v, num);
+#endif
        if(ret > 0)
                ebuf_delete(&c->sendQ, ret);
        if(!(eBufLength(&c->sendQ) > 0))
index 513043091ae74e8193e92c8e6bd4ff604b48b5e3..3c69c06ba56c3f2fcf963a4b7ed280baa8ba581b 100644 (file)
@@ -4,6 +4,7 @@
 
 #include "sockeng.h"
 #include "mfd.h"
+#include "wrap_ssl.h"
 
 #include <unistd.h>
 #include <fcntl.h>
@@ -16,6 +17,7 @@ extern Client *create_client_t(Listener *);
 
 static int listener_qopts(Listener *l, int opts)
 {
+       l->flags = opts;
        return RET_OK;
 }
 
@@ -119,6 +121,10 @@ static void accept_tcp6_connect(SockEng *s, void *in, int rr, int rw)
                new->addr.type = TYPE_IPV6;
                memcpy(&new->addr.ip, &addr.sin6_addr, sizeof(struct in6_addr));
                new->port = ntohs(addr.sin6_port);
+#ifdef USE_SSL
+               if((l->flags & LISTEN_SSL) && sslaccept(new))
+                       new->close(new);        /* failed SSL negotiation, drop it */
+#endif
                if(l->onconnect != NULL && (*l->onconnect)(new)) {
                        new->close(new);
                        continue;
@@ -148,6 +154,10 @@ static void accept_tcp4_connect(SockEng *s, void *in, int rr, int rw)
                new->addr.type = TYPE_IPV4;
                memcpy(&new->addr.ip, &addr.sin_addr, sizeof(struct in_addr));
                new->port = ntohs(addr.sin_port);
+#ifdef USE_SSL
+               if((l->flags & LISTEN_SSL) && sslaccept(new))
+                       new->close(new);        /* failed SSL negotation, drop it */
+#endif
                if(l->onconnect != NULL && (*l->onconnect)(new)) {
                        new->close(new);
                        continue;
index cb4ae1fe37613389e5c949bd6afb1c8d908c731e..c332b786ce9b2f6f52c8b576edeab67f6fc21aa8 100644 (file)
@@ -65,14 +65,29 @@ int sslwrite(SSL *id, void *buf, int sz)
        return call_ssl(CALL_SSLWRITE, id,  buf, sz);
 }
 
-int sslaccept(SSL *id)
+int sslaccept(Client *c)
 {
-       return call_ssl(CALL_SSLACCEPT, id, NULL, 0);
+       int ret;
+       SSL *id;
+
+       id = SSL_new(c->sockeng->sslctx);
+       if(!id)
+               return -1;
+       SSL_set_fd(id, c->fdp.fd);
+       ret = call_ssl(CALL_SSLACCEPT, id, NULL, 0);
+       if(ret) {
+               call_ssl(CALL_SSLSHUT, id, NULL, 0);
+               SSL_free(id);
+               return -1;
+       }
+       c->sslid = id;
+       return ret;
 }
 
-int sslshut(SSL *id) 
+void sslshut(SSL *id) 
 {
-       return call_ssl(CALL_SSLSHUT, id, NULL, 0);
+       call_ssl(CALL_SSLSHUT, id, NULL, 0);
+       SSL_free(id);
 }