Code

client: Check the remote peer name.
[sysdb.git] / src / client / sock.c
index b67910efa4b5eb843504b825587e52a14367f465..ef4e007bc0b0bbec9ffaa65fe81ba5dd47d9bc58 100644 (file)
@@ -29,6 +29,7 @@
 #      include "config.h"
 #endif /* HAVE_CONFIG_H */
 
+#include "sysdb.h"
 #include "client/sock.h"
 #include "utils/error.h"
 #include "utils/strbuf.h"
@@ -138,7 +139,9 @@ connect_unixsock(sdb_client_t *client, const char *address)
 static int
 connect_tcp(sdb_client_t *client, const char *address)
 {
+       char host[SDB_MAX(strlen("localhost"), (address ? strlen(address) : 0)) + 1];
        struct addrinfo *ai, *ai_list = NULL;
+       char *peer, *tmp;
        int status;
 
        if ((status = sdb_resolve(SDB_NET_TCP, address, &ai_list))) {
@@ -157,12 +160,12 @@ connect_tcp(sdb_client_t *client, const char *address)
                }
 
                if (connect(client->fd, ai->ai_addr, ai->ai_addrlen)) {
-                       char host[1024], port[32], errbuf[1024];
+                       char h[1024], p[32], errbuf[1024];
                        sdb_client_close(client);
-                       getnameinfo(ai->ai_addr, ai->ai_addrlen, host, sizeof(host),
-                                       port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV);
+                       getnameinfo(ai->ai_addr, ai->ai_addrlen, h, sizeof(h),
+                                       p, sizeof(p), NI_NUMERICHOST | NI_NUMERICSERV);
                        sdb_log(SDB_LOG_ERR, "Failed to connect to '%s:%s': %s",
-                                       host, port, sdb_strerror(errno, errbuf, sizeof(errbuf)));
+                                       h, p, sdb_strerror(errno, errbuf, sizeof(errbuf)));
                        continue;
                }
                break;
@@ -183,25 +186,29 @@ connect_tcp(sdb_client_t *client, const char *address)
                return -1;
        }
 
+       strncpy(host, address, sizeof(host));
+       if ((tmp = strchr(host, (int)':')))
+               *tmp = '\0';
+       if (! host[0])
+               strncpy(host, "localhost", sizeof(host));
+       peer = sdb_ssl_session_peer(client->ssl_session);
+       if ((! peer) || strcasecmp(peer, host)) {
+               /* TODO: also check alt-name */
+               sdb_log(SDB_LOG_ERR, "Failed to connect to '%s': "
+                               "peer name '%s' does not match host address",
+                               address, peer);
+               sdb_client_close(client);
+               if (peer)
+                       free(peer);
+               return -1;
+       }
+       free(peer);
+
        client->read = ssl_read;
        client->write = ssl_write;
        return client->fd;
 } /* connect_tcp */
 
-static void
-free_ssl_options(sdb_ssl_options_t *opts)
-{
-       if (opts->ca_file)
-               free(opts->ca_file);
-       if (opts->key_file)
-               free(opts->key_file);
-       if (opts->cert_file)
-               free(opts->cert_file);
-       if (opts->crl_file)
-               free(opts->crl_file);
-       opts->ca_file = opts->key_file = opts->cert_file = opts->crl_file = NULL;
-} /* free_ssl_options */
-
 /*
  * public API
  */
@@ -249,7 +256,7 @@ sdb_client_destroy(sdb_client_t *client)
                free(client->address);
        client->address = NULL;
 
-       free_ssl_options(&client->ssl_opts);
+       sdb_ssl_free_options(&client->ssl_opts);
 
        free(client);
 } /* sdb_client_destroy */
@@ -262,7 +269,7 @@ sdb_client_set_ssl_options(sdb_client_t *client, const sdb_ssl_options_t *opts)
        if ((! client) || (! opts))
                return -1;
 
-       free_ssl_options(&client->ssl_opts);
+       sdb_ssl_free_options(&client->ssl_opts);
 
        if (opts->ca_file) {
                client->ssl_opts.ca_file = strdup(opts->ca_file);
@@ -286,7 +293,7 @@ sdb_client_set_ssl_options(sdb_client_t *client, const sdb_ssl_options_t *opts)
        }
 
        if (ret)
-               free_ssl_options(&client->ssl_opts);
+               sdb_ssl_free_options(&client->ssl_opts);
        return ret;
 } /* sdb_client_set_ssl_options */