Code

client, sysdb: Let TCP connection use SSL.
authorSebastian Harl <sh@tokkee.org>
Wed, 28 Jan 2015 15:19:24 +0000 (16:19 +0100)
committerSebastian Harl <sh@tokkee.org>
Wed, 28 Jan 2015 15:19:24 +0000 (16:19 +0100)
src/Makefile.am
src/client/sock.c
src/tools/sysdb/main.c

index 6521e8463a5d6df15e1e5b75d8690ac79e0f8316..4c920ec0bfed4d2f94d8905b9009a46822a2641b 100644 (file)
@@ -57,12 +57,13 @@ libsysdbclient_la_SOURCES = \
                client/sock.c include/client/sock.h \
                utils/error.c include/utils/error.h \
                utils/proto.c include/utils/proto.h \
+               utils/ssl.c include/utils/ssl.h \
                utils/strbuf.c include/utils/strbuf.h
-libsysdbclient_la_CFLAGS = $(AM_CFLAGS)
+libsysdbclient_la_CFLAGS = $(AM_CFLAGS) @OPENSSL_CFLAGS@
 libsysdbclient_la_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL)
 libsysdbclient_la_LDFLAGS = $(AM_LDFLAGS) -version-info 0:0:0 \
                -pthread -lm -lrt
-libsysdbclient_la_LIBADD = $(LIBLTDL)
+libsysdbclient_la_LIBADD = $(LIBLTDL) @OPENSSL_LIBS@
 
 # don't use strict CFLAGS for flex code
 noinst_LTLIBRARIES += libsysdb_fe_parser.la
index f9929dacd3c63eedb3919400d210e77445f55771..330d656fb66d2f2c566ce8a36812c6ea83dca4e4 100644 (file)
@@ -34,6 +34,7 @@
 #include "utils/strbuf.h"
 #include "utils/proto.h"
 #include "utils/os.h"
+#include "utils/ssl.h"
 
 #include <arpa/inet.h>
 
@@ -62,6 +63,10 @@ struct sdb_client {
        int   fd;
        bool  eof;
 
+       /* optional SSL settings */
+       sdb_ssl_client_t *ssl;
+       sdb_ssl_session_t *ssl_session;
+
        ssize_t (*read)(sdb_client_t *, sdb_strbuf_t *, size_t);
        ssize_t (*write)(sdb_client_t *, const void *, size_t);
 };
@@ -70,6 +75,26 @@ struct sdb_client {
  * private helper functions
  */
 
+static ssize_t
+ssl_read(sdb_client_t *client, sdb_strbuf_t *buf, size_t n)
+{
+       char tmp[n];
+       ssize_t ret;
+
+       ret = sdb_ssl_session_read(client->ssl_session, tmp, n);
+       if (ret <= 0)
+               return ret;
+
+       sdb_strbuf_memappend(buf, tmp, ret);
+       return ret;
+} /* ssl_read */
+
+static ssize_t
+ssl_write(sdb_client_t *client, const void *buf, size_t n)
+{
+       return sdb_ssl_session_write(client->ssl_session, buf, n);
+} /* ssl_write */
+
 static ssize_t
 client_read(sdb_client_t *client, sdb_strbuf_t *buf, size_t n)
 {
@@ -142,6 +167,24 @@ connect_tcp(sdb_client_t *client, const char *address)
                break;
        }
        freeaddrinfo(ai_list);
+
+       if (client->fd < 0)
+               return -1;
+
+       /* TODO: make options configurable */
+       client->ssl = sdb_ssl_client_create(NULL);
+       if (! client->ssl) {
+               sdb_client_close(client);
+               return -1;
+       }
+       client->ssl_session = sdb_ssl_client_connect(client->ssl, client->fd);
+       if (! client->ssl_session) {
+               sdb_client_close(client);
+               return -1;
+       }
+
+       client->read = ssl_read;
+       client->write = ssl_write;
        return client->fd;
 } /* connect_tcp */
 
@@ -166,6 +209,7 @@ sdb_client_create(const char *address)
        client->fd = -1;
        client->eof = 1;
 
+       client->ssl = NULL;
        client->read = client_read;
        client->write = client_write;
 
@@ -289,6 +333,15 @@ sdb_client_close(sdb_client_t *client)
        if (! client)
                return;
 
+       if (client->ssl_session) {
+               sdb_ssl_session_destroy(client->ssl_session);
+               client->ssl_session = NULL;
+       }
+       if (client->ssl) {
+               sdb_ssl_client_destroy(client->ssl);
+               client->ssl = NULL;
+       }
+
        close(client->fd);
        client->fd = -1;
        client->eof = 1;
index e5f20ea4bbfbaf8c151ec11aa6d20f218c1daf35..20f37ae34791d2dbebd942066844a60ecdcd395c 100644 (file)
@@ -77,6 +77,9 @@
 #      endif
 #endif /* READLINEs */
 
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
 #ifndef DEFAULT_SOCKET
 #      define DEFAULT_SOCKET "unix:"LOCALSTATEDIR"/run/sysdbd.sock"
 #endif
@@ -278,6 +281,9 @@ main(int argc, char **argv)
        if (! input.user)
                exit(1);
 
+       SSL_load_error_strings();
+       OpenSSL_add_ssl_algorithms();
+
        input.client = sdb_client_create(host);
        if (! input.client) {
                sdb_log(SDB_LOG_ERR, "Failed to create client object");
@@ -342,6 +348,8 @@ main(int argc, char **argv)
 
        sdb_client_destroy(input.client);
        sdb_strbuf_destroy(input.input);
+
+       ERR_free_strings();
        return 0;
 } /* main */