]> xenbits.xensource.com Git - libvirt.git/commitdiff
virnetsocket: Provide socket address format in a more standard form
authorErik Skultety <eskultet@redhat.com>
Tue, 26 Apr 2016 11:39:06 +0000 (13:39 +0200)
committerErik Skultety <eskultet@redhat.com>
Tue, 3 May 2016 13:52:50 +0000 (15:52 +0200)
Our socket address format is in a rather non-standard format and that is
because sasl library requires the IP address and service to be delimited by a
semicolon. The string form is a completely internal matter, however once the
admin interfaces to retrieve client identity information are merged, we should
return the socket address string in a common format, e.g. format defined by
URI rfc-3986, i.e. the IP address and service are delimited by a colon and
in case of an IPv6 address, square brackets are added:

Examples:
    127.0.0.1:1234
    [::1]:1234

This patch changes our default format to the one described above, while adding
separate methods to request the non-standard SASL format using semicolon as a
delimiter.

Signed-off-by: Erik Skultety <eskultet@redhat.com>
daemon/remote.c
src/remote/remote_driver.c
src/rpc/virnetclient.c
src/rpc/virnetclient.h
src/rpc/virnetserverclient.c
src/rpc/virnetserverclient.h
src/rpc/virnetsocket.c
src/rpc/virnetsocket.h
src/util/virsocketaddr.c
tests/virnetsockettest.c

index fde029da21f2f52164d890466c18eeea65ad39f6..b2a420bc0021e937ed052e4aea19fbbb9d90a9f6 100644 (file)
@@ -2937,6 +2937,8 @@ remoteDispatchAuthSaslInit(virNetServerPtr server ATTRIBUTE_UNUSED,
     virNetSASLSessionPtr sasl = NULL;
     struct daemonClientPrivate *priv =
         virNetServerClientGetPrivateData(client);
+    char *localAddr = NULL;
+    char *remoteAddr = NULL;
 
     virMutexLock(&priv->lock);
 
@@ -2947,10 +2949,17 @@ remoteDispatchAuthSaslInit(virNetServerPtr server ATTRIBUTE_UNUSED,
         goto authfail;
     }
 
+    localAddr = virNetServerClientLocalAddrFormatSASL(client);
+    remoteAddr = virNetServerClientRemoteAddrFormatSASL(client);
+
     sasl = virNetSASLSessionNewServer(saslCtxt,
                                       "libvirt",
-                                      virNetServerClientLocalAddrString(client),
-                                      virNetServerClientRemoteAddrString(client));
+                                      localAddr,
+                                      remoteAddr);
+
+    VIR_FREE(localAddr);
+    VIR_FREE(remoteAddr);
+
     if (!sasl)
         goto authfail;
 
index 6bed2c5389f54dce9d94fd5d5b8a4177505b467e..e3cf5fbead36ed81a0a8927a2dbaa8d7b2a7add9 100644 (file)
@@ -3684,6 +3684,8 @@ remoteAuthSASL(virConnectPtr conn, struct private_data *priv,
     sasl_callback_t *saslcb = NULL;
     int ret = -1;
     const char *mechlist;
+    char *localAddr = NULL;
+    char *remoteAddr = NULL;
     virNetSASLContextPtr saslCtxt;
     virNetSASLSessionPtr sasl = NULL;
     struct remoteAuthInteractState state;
@@ -3702,6 +3704,9 @@ remoteAuthSASL(virConnectPtr conn, struct private_data *priv,
         saslcb = NULL;
     }
 
+    localAddr = virNetClientLocalAddrFormatSASL(priv->client);
+    remoteAddr = virNetClientRemoteAddrFormatSASL(priv->client);
+
     /* Setup a handle for being a client */
     if (!(sasl = virNetSASLSessionNewClient(saslCtxt,
                                             "libvirt",
@@ -3889,6 +3894,8 @@ remoteAuthSASL(virConnectPtr conn, struct private_data *priv,
 
  cleanup:
     VIR_FREE(serverin);
+    VIR_FREE(localAddr);
+    VIR_FREE(remoteAddr);
 
     remoteAuthInteractStateClear(&state, true);
     VIR_FREE(saslcb);
index d8ed15b7e2c77dbaa261d40e27b267a1cb637fca..26b02fa94484c6d3018f1929805dba6dc9b50dd2 100644 (file)
@@ -954,6 +954,16 @@ const char *virNetClientRemoteAddrString(virNetClientPtr client)
     return virNetSocketRemoteAddrString(client->sock);
 }
 
+char *virNetClientLocalAddrFormatSASL(virNetClientPtr client)
+{
+    return virNetSocketLocalAddrFormatSASL(client->sock);
+}
+
+char *virNetClientRemoteAddrFormatSASL(virNetClientPtr client)
+{
+    return virNetSocketRemoteAddrFormatSASL(client->sock);
+}
+
 #if WITH_GNUTLS
 int virNetClientGetTLSKeySize(virNetClientPtr client)
 {
index 38f929ca558353b859e278cd46f0cedb20f90abc..4b786775cb22d2e8949515efd9232b4fc5812130 100644 (file)
@@ -123,6 +123,8 @@ bool virNetClientIsOpen(virNetClientPtr client);
 
 const char *virNetClientLocalAddrString(virNetClientPtr client);
 const char *virNetClientRemoteAddrString(virNetClientPtr client);
+char *virNetClientLocalAddrFormatSASL(virNetClientPtr client);
+char *virNetClientRemoteAddrFormatSASL(virNetClientPtr client);
 
 # ifdef WITH_GNUTLS
 int virNetClientGetTLSKeySize(virNetClientPtr client);
index a9d70e1738445cea20fd572e0455df38c5213b81..a7b3b1562292ddb066d67c585cdb3a6adb0a80f3 100644 (file)
@@ -911,6 +911,19 @@ const char *virNetServerClientRemoteAddrString(virNetServerClientPtr client)
     return virNetSocketRemoteAddrString(client->sock);
 }
 
+char *virNetServerClientLocalAddrFormatSASL(virNetServerClientPtr client)
+{
+    if (!client->sock)
+        return NULL;
+    return virNetSocketLocalAddrFormatSASL(client->sock);
+}
+
+char *virNetServerClientRemoteAddrFormatSASL(virNetServerClientPtr client)
+{
+    if (!client->sock)
+        return NULL;
+    return virNetSocketRemoteAddrFormatSASL(client->sock);
+}
 
 void virNetServerClientDispose(void *obj)
 {
index 1318fa2410c9ffa2bffb1746133ae487827027bf..f44b7caba02a384c1f0a789f7d112dbf3c057f96 100644 (file)
@@ -139,6 +139,8 @@ int virNetServerClientStartKeepAlive(virNetServerClientPtr client);
 
 const char *virNetServerClientLocalAddrString(virNetServerClientPtr client);
 const char *virNetServerClientRemoteAddrString(virNetServerClientPtr client);
+char *virNetServerClientLocalAddrFormatSASL(virNetServerClientPtr client);
+char *virNetServerClientRemoteAddrFormatSASL(virNetServerClientPtr client);
 
 int virNetServerClientSendMessage(virNetServerClientPtr client,
                                   virNetMessagePtr msg);
index d909b94d0fb5e437c15a0082245fbd13115adf28..a90cc55ada3a16e887c60a3024b81afddc08aadc 100644 (file)
@@ -262,11 +262,11 @@ static virNetSocketPtr virNetSocketNew(virSocketAddrPtr localAddr,
 
 
     if (localAddr &&
-        !(sock->localAddrStr = virSocketAddrFormatFull(localAddr, true, ";")))
+        !(sock->localAddrStr = virSocketAddrFormatFull(localAddr, true, NULL)))
         goto error;
 
     if (remoteAddr &&
-        !(sock->remoteAddrStr = virSocketAddrFormatFull(remoteAddr, true, ";")))
+        !(sock->remoteAddrStr = virSocketAddrFormatFull(remoteAddr, true, NULL)))
         goto error;
 
     sock->client = isClient;
@@ -1465,6 +1465,19 @@ const char *virNetSocketRemoteAddrString(virNetSocketPtr sock)
     return sock->remoteAddrStr;
 }
 
+/* These helper functions return a SASL-formatted socket addr string,
+ * caller is responsible for freeing the string.
+ */
+char *virNetSocketLocalAddrFormatSASL(virNetSocketPtr sock)
+{
+    return virSocketAddrFormatFull(&sock->localAddr, true, ";");
+}
+
+char *virNetSocketRemoteAddrFormatSASL(virNetSocketPtr sock)
+{
+    return virSocketAddrFormatFull(&sock->remoteAddr, true, ";");
+}
+
 
 #if WITH_GNUTLS
 static ssize_t virNetSocketTLSSessionWrite(const char *buf,
index 5de3d926315ddb8fc1e2ee6799965eda1175cafc..4eb7187b2306b727469a03013f496ae59a805e71 100644 (file)
@@ -150,6 +150,8 @@ bool virNetSocketHasPendingData(virNetSocketPtr sock);
 
 const char *virNetSocketLocalAddrString(virNetSocketPtr sock);
 const char *virNetSocketRemoteAddrString(virNetSocketPtr sock);
+char *virNetSocketLocalAddrFormatSASL(virNetSocketPtr sock);
+char *virNetSocketRemoteAddrFormatSASL(virNetSocketPtr sock);
 
 int virNetSocketListen(virNetSocketPtr sock, int backlog);
 int virNetSocketAccept(virNetSocketPtr sock,
index 4b456819b1363efd1d1efc279a5a4d05de41e9b9..a0c92ea6093e85c8fdb46f379faae23a5bd61cb2 100644 (file)
@@ -339,9 +339,11 @@ virSocketAddrFormat(const virSocketAddr *addr)
  * @withService: if true, then service info is appended
  * @separator: separator between hostname & service.
  *
- * Returns a string representation of the given address
- * Returns NULL on any error
- * Caller must free the returned string
+ * Returns a string representation of the given address. If a format conforming
+ * to URI specification is required, NULL should be passed to separator.
+ * Set @separator only if non-URI format is required, e.g. passing ';' for
+ * @separator if the address should be used with SASL.
+ * Caller must free the returned string.
  */
 char *
 virSocketAddrFormatFull(const virSocketAddr *addr,
@@ -383,8 +385,22 @@ virSocketAddrFormatFull(const virSocketAddr *addr,
     }
 
     if (withService) {
-        if (virAsprintf(&addrstr, "%s%s%s", host, separator, port) == -1)
+        char *ipv6_host = NULL;
+        /* sasl_new_client demands the socket address to be in an odd format:
+         * a.b.c.d;port or e:f:g:h:i:j:k:l;port, so use square brackets for
+         * IPv6 only if no separator is passed to the function
+         */
+        if (!separator && VIR_SOCKET_ADDR_FAMILY(addr) == AF_INET6) {
+            if (virAsprintf(&ipv6_host, "[%s]", host) < 0)
+                goto error;
+        }
+
+        if (virAsprintf(&addrstr, "%s%s%s",
+                        ipv6_host ? ipv6_host : host,
+                        separator ? separator : ":", port) == -1)
             goto error;
+
+        VIR_FREE(ipv6_host);
     } else {
         if (VIR_STRDUP(addrstr, host) < 0)
             goto error;
index 5786870a82ef292bf7d7a168f71b0e41a31cf74b..c2bc4e739c9501ac938e822135157be292272d49 100644 (file)
@@ -249,7 +249,7 @@ static int testSocketUNIXAddrs(const void *data ATTRIBUTE_UNUSED)
     if (virNetSocketNewListenUNIX(path, 0700, -1, getegid(), &lsock) < 0)
         goto cleanup;
 
-    if (STRNEQ(virNetSocketLocalAddrString(lsock), "127.0.0.1;0")) {
+    if (STRNEQ(virNetSocketLocalAddrString(lsock), "127.0.0.1:0")) {
         VIR_DEBUG("Unexpected local address");
         goto cleanup;
     }
@@ -265,12 +265,12 @@ static int testSocketUNIXAddrs(const void *data ATTRIBUTE_UNUSED)
     if (virNetSocketNewConnectUNIX(path, false, NULL, &csock) < 0)
         goto cleanup;
 
-    if (STRNEQ(virNetSocketLocalAddrString(csock), "127.0.0.1;0")) {
+    if (STRNEQ(virNetSocketLocalAddrString(csock), "127.0.0.1:0")) {
         VIR_DEBUG("Unexpected local address");
         goto cleanup;
     }
 
-    if (STRNEQ(virNetSocketRemoteAddrString(csock), "127.0.0.1;0")) {
+    if (STRNEQ(virNetSocketRemoteAddrString(csock), "127.0.0.1:0")) {
         VIR_DEBUG("Unexpected local address");
         goto cleanup;
     }
@@ -282,12 +282,12 @@ static int testSocketUNIXAddrs(const void *data ATTRIBUTE_UNUSED)
     }
 
 
-    if (STRNEQ(virNetSocketLocalAddrString(ssock), "127.0.0.1;0")) {
+    if (STRNEQ(virNetSocketLocalAddrString(ssock), "127.0.0.1:0")) {
         VIR_DEBUG("Unexpected local address");
         goto cleanup;
     }
 
-    if (STRNEQ(virNetSocketRemoteAddrString(ssock), "127.0.0.1;0")) {
+    if (STRNEQ(virNetSocketRemoteAddrString(ssock), "127.0.0.1:0")) {
         VIR_DEBUG("Unexpected local address");
         goto cleanup;
     }