[libvirt] [PATCH 04/12] Add APIs to get at more client security data

Daniel P. Berrange berrange at redhat.com
Wed May 2 11:44:11 UTC 2012


From: "Daniel P. Berrange" <berrange at redhat.com>

Add new APIs virNetServerClientGetTLSSession,
virNetServerClientIsLocal, virNetServerClientGetSecurityContext
virNetServerClientGetSASLSession, virNetSocketGetSecurityContext
and virNetTLSSessionGetX509DName
---
 src/rpc/virnetserverclient.c |   48 ++++++++++++++++++++++++++++++++++++++++++
 src/rpc/virnetserverclient.h |    7 ++++++
 src/rpc/virnetsocket.c       |   44 ++++++++++++++++++++++++++++++++++++++
 src/rpc/virnetsocket.h       |    2 ++
 src/rpc/virnettlscontext.c   |   18 ++++++++++++++++
 src/rpc/virnettlscontext.h   |    2 ++
 6 files changed, 121 insertions(+)

diff --git a/src/rpc/virnetserverclient.c b/src/rpc/virnetserverclient.c
index 81dbb32..1e9d3db 100644
--- a/src/rpc/virnetserverclient.c
+++ b/src/rpc/virnetserverclient.c
@@ -433,6 +433,16 @@ bool virNetServerClientHasTLSSession(virNetServerClientPtr client)
     return has;
 }
 
+
+virNetTLSSessionPtr virNetServerClientGetTLSSession(virNetServerClientPtr client)
+{
+    virNetTLSSessionPtr tls;
+    virNetServerClientLock(client);
+    tls = client->tls;
+    virNetServerClientUnlock(client);
+    return tls;
+}
+
 int virNetServerClientGetTLSKeySize(virNetServerClientPtr client)
 {
     int size = 0;
@@ -453,6 +463,18 @@ int virNetServerClientGetFD(virNetServerClientPtr client)
     return fd;
 }
 
+
+bool virNetServerClientIsLocal(virNetServerClientPtr client)
+{
+    bool local = false;
+    virNetServerClientLock(client);
+    if (client->sock)
+        local = virNetSocketIsLocal(client->sock);
+    virNetServerClientUnlock(client);
+    return local;
+}
+
+
 int virNetServerClientGetUNIXIdentity(virNetServerClientPtr client,
                                       uid_t *uid, gid_t *gid, pid_t *pid)
 {
@@ -464,6 +486,22 @@ int virNetServerClientGetUNIXIdentity(virNetServerClientPtr client,
     return ret;
 }
 
+
+int virNetServerClientGetSecurityContext(virNetServerClientPtr client,
+                                         char **context)
+{
+    int ret;
+    *context = NULL;
+    virNetServerClientLock(client);
+    if (client->sock)
+        ret = virNetSocketGetSecurityContext(client->sock, context);
+    else
+        ret = 0;
+    virNetServerClientUnlock(client);
+    return ret;
+}
+
+
 bool virNetServerClientIsSecure(virNetServerClientPtr client)
 {
     bool secure = false;
@@ -495,6 +533,16 @@ void virNetServerClientSetSASLSession(virNetServerClientPtr client,
     virNetSASLSessionRef(sasl);
     virNetServerClientUnlock(client);
 }
+
+
+virNetSASLSessionPtr virNetServerClientGetSASLSession(virNetServerClientPtr client)
+{
+    virNetSASLSessionPtr sasl;
+    virNetServerClientLock(client);
+    sasl = client->sasl;
+    virNetServerClientUnlock(client);
+    return sasl;
+}
 #endif
 
 
diff --git a/src/rpc/virnetserverclient.h b/src/rpc/virnetserverclient.h
index 633e9e1..a3b37a3 100644
--- a/src/rpc/virnetserverclient.h
+++ b/src/rpc/virnetserverclient.h
@@ -56,20 +56,27 @@ void virNetServerClientSetAuth(virNetServerClientPtr client, int auth);
 bool virNetServerClientGetReadonly(virNetServerClientPtr client);
 
 bool virNetServerClientHasTLSSession(virNetServerClientPtr client);
+virNetTLSSessionPtr virNetServerClientGetTLSSession(virNetServerClientPtr client);
 int virNetServerClientGetTLSKeySize(virNetServerClientPtr client);
 
 # ifdef HAVE_SASL
 void virNetServerClientSetSASLSession(virNetServerClientPtr client,
                                       virNetSASLSessionPtr sasl);
+virNetSASLSessionPtr virNetServerClientGetSASLSession(virNetServerClientPtr client);
 # endif
 
 int virNetServerClientGetFD(virNetServerClientPtr client);
 
 bool virNetServerClientIsSecure(virNetServerClientPtr client);
 
+bool virNetServerClientIsLocal(virNetServerClientPtr client);
+
 int virNetServerClientGetUNIXIdentity(virNetServerClientPtr client,
                                       uid_t *uid, gid_t *gid, pid_t *pid);
 
+int virNetServerClientGetSecurityContext(virNetServerClientPtr client,
+                                         char **context);
+
 void virNetServerClientRef(virNetServerClientPtr client);
 
 typedef void (*virNetServerClientFreeFunc)(void *data);
diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
index fa16d31..da2d961 100644
--- a/src/rpc/virnetsocket.c
+++ b/src/rpc/virnetsocket.c
@@ -35,6 +35,10 @@
 # include <netinet/tcp.h>
 #endif
 
+#ifdef HAVE_SELINUX
+# include <selinux/selinux.h>
+#endif
+
 #include "virnetsocket.h"
 #include "util.h"
 #include "memory.h"
@@ -860,6 +864,46 @@ int virNetSocketGetUNIXIdentity(virNetSocketPtr sock ATTRIBUTE_UNUSED,
 }
 #endif
 
+#ifdef HAVE_SELINUX
+int virNetSocketGetSecurityContext(virNetSocketPtr sock,
+                                   char **context)
+{
+    security_context_t seccon = NULL;
+    int ret = -1;
+
+    *context = NULL;
+
+    virMutexLock(&sock->lock);
+    if (getpeercon(sock->fd, &seccon) < 0) {
+        if (errno == ENOSYS) {
+            ret = 0;
+            goto cleanup;
+        }
+        virReportSystemError(errno, "%s",
+                             _("Unable to query peer security context"));
+        goto cleanup;
+    }
+
+    if (!(*context = strdup(seccon))) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    ret = 0;
+cleanup:
+    freecon(seccon);
+    virMutexUnlock(&sock->lock);
+    return ret;
+}
+#else
+int virNetSocketGetSecurityContext(virNetSocketPtr sock,
+                                   char **context)
+{
+    *context = NULL;
+    return 0;
+}
+#endif
+
 
 int virNetSocketSetBlocking(virNetSocketPtr sock,
                             bool blocking)
diff --git a/src/rpc/virnetsocket.h b/src/rpc/virnetsocket.h
index 5ba7c8f..de42e5c 100644
--- a/src/rpc/virnetsocket.h
+++ b/src/rpc/virnetsocket.h
@@ -90,6 +90,8 @@ int virNetSocketGetUNIXIdentity(virNetSocketPtr sock,
                                 uid_t *uid,
                                 gid_t *gid,
                                 pid_t *pid);
+int virNetSocketGetSecurityContext(virNetSocketPtr sock,
+                                   char **context);
 
 int virNetSocketSetBlocking(virNetSocketPtr sock,
                             bool blocking);
diff --git a/src/rpc/virnettlscontext.c b/src/rpc/virnettlscontext.c
index 7440c7a..b9970d9 100644
--- a/src/rpc/virnettlscontext.c
+++ b/src/rpc/virnettlscontext.c
@@ -77,6 +77,7 @@ struct _virNetTLSSession {
     virNetTLSSessionWriteFunc writeFunc;
     virNetTLSSessionReadFunc readFunc;
     void *opaque;
+    char *x509dname;
 };
 
 
@@ -1025,6 +1026,10 @@ static int virNetTLSContextValidCertificate(virNetTLSContextPtr ctxt,
                             "[session]", gnutls_strerror(ret));
                 goto authfail;
             }
+            if (!(sess->x509dname = strdup(dname))) {
+                virReportOOMError();
+                goto authfail;
+            }
             VIR_DEBUG("Peer DN is %s", dname);
 
             if (virNetTLSContextCheckCertDN(cert, "[session]", sess->hostname, dname,
@@ -1395,6 +1400,18 @@ cleanup:
     return ssf;
 }
 
+const char *virNetTLSSessionGetX509DName(virNetTLSSessionPtr sess)
+{
+    const char *ret = NULL;
+
+    virMutexLock(&sess->lock);
+
+    ret = sess->x509dname;
+
+    virMutexUnlock(&sess->lock);
+
+    return ret;
+}
 
 void virNetTLSSessionFree(virNetTLSSessionPtr sess)
 {
@@ -1411,6 +1428,7 @@ void virNetTLSSessionFree(virNetTLSSessionPtr sess)
         return;
     }
 
+    VIR_FREE(sess->x509dname);
     VIR_FREE(sess->hostname);
     gnutls_deinit(sess->session);
     virMutexUnlock(&sess->lock);
diff --git a/src/rpc/virnettlscontext.h b/src/rpc/virnettlscontext.h
index fdfce6d..0c45cb0 100644
--- a/src/rpc/virnettlscontext.h
+++ b/src/rpc/virnettlscontext.h
@@ -99,6 +99,8 @@ virNetTLSSessionGetHandshakeStatus(virNetTLSSessionPtr sess);
 
 int virNetTLSSessionGetKeySize(virNetTLSSessionPtr sess);
 
+const char *virNetTLSSessionGetX509DName(virNetTLSSessionPtr sess);
+
 void virNetTLSSessionFree(virNetTLSSessionPtr sess);
 
 
-- 
1.7.10




More information about the libvir-list mailing list