[libvirt] [PATCH v2 1/6] Add APIs to get at more client security data

Daniel P. Berrange berrange at redhat.com
Wed Mar 13 15:24:00 UTC 2013


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

A socket object has various pieces of security data associated
with it, such as the SELinux context, the SASL username and
the x509 distinguished name. Add new APIs to virNetServerClient
and related modules to access this data.

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 src/libvirt_gnutls.syms      |  2 ++
 src/libvirt_private.syms     |  3 +++
 src/libvirt_sasl.syms        |  1 +
 src/rpc/virnetserverclient.c | 46 ++++++++++++++++++++++++++++++++++++++++++++
 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 ++
 9 files changed, 125 insertions(+)

diff --git a/src/libvirt_gnutls.syms b/src/libvirt_gnutls.syms
index bd4f950..6eb6741 100644
--- a/src/libvirt_gnutls.syms
+++ b/src/libvirt_gnutls.syms
@@ -13,6 +13,7 @@ virNetServerSetTLSContext;
 
 # rpc/virnetserverclient.h
 virNetServerClientGetTLSKeySize;
+virNetServerClientGetTLSSession;
 virNetServerClientHasTLSSession;
 
 
@@ -33,6 +34,7 @@ virNetTLSContextNewServerPath;
 virNetTLSInit;
 virNetTLSSessionGetHandshakeStatus;
 virNetTLSSessionGetKeySize;
+virNetTLSSessionGetX509DName;
 virNetTLSSessionHandshake;
 virNetTLSSessionNew;
 virNetTLSSessionRead;
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index fbd540a..3243416 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -853,11 +853,13 @@ virNetServerClientGetAuth;
 virNetServerClientGetFD;
 virNetServerClientGetPrivateData;
 virNetServerClientGetReadonly;
+virNetServerClientGetSecurityContext;
 virNetServerClientGetUNIXIdentity;
 virNetServerClientImmediateClose;
 virNetServerClientInit;
 virNetServerClientInitKeepAlive;
 virNetServerClientIsClosed;
+virNetServerClientIsLocal;
 virNetServerClientIsSecure;
 virNetServerClientLocalAddrString;
 virNetServerClientNeedAuth;
@@ -922,6 +924,7 @@ virNetSocketClose;
 virNetSocketDupFD;
 virNetSocketGetFD;
 virNetSocketGetPort;
+virNetSocketGetSecurityContext;
 virNetSocketGetUNIXIdentity;
 virNetSocketHasCachedData;
 virNetSocketHasPassFD;
diff --git a/src/libvirt_sasl.syms b/src/libvirt_sasl.syms
index beb8825..1241884 100644
--- a/src/libvirt_sasl.syms
+++ b/src/libvirt_sasl.syms
@@ -26,6 +26,7 @@ virNetSASLSessionServerStep;
 
 
 # rpc/virnetserverclient.h
+virNetServerClientGetSASLSession;
 virNetServerClientSetSASLSession;
 
 
diff --git a/src/rpc/virnetserverclient.c b/src/rpc/virnetserverclient.c
index 9e519e6..40c8173 100644
--- a/src/rpc/virnetserverclient.c
+++ b/src/rpc/virnetserverclient.c
@@ -587,6 +587,16 @@ bool virNetServerClientHasTLSSession(virNetServerClientPtr client)
     return has;
 }
 
+
+virNetTLSSessionPtr virNetServerClientGetTLSSession(virNetServerClientPtr client)
+{
+    virNetTLSSessionPtr tls;
+    virObjectLock(client);
+    tls = client->tls;
+    virObjectUnlock(client);
+    return tls;
+}
+
 int virNetServerClientGetTLSKeySize(virNetServerClientPtr client)
 {
     int size = 0;
@@ -608,6 +618,18 @@ int virNetServerClientGetFD(virNetServerClientPtr client)
     return fd;
 }
 
+
+bool virNetServerClientIsLocal(virNetServerClientPtr client)
+{
+    bool local = false;
+    virObjectLock(client);
+    if (client->sock)
+        local = virNetSocketIsLocal(client->sock);
+    virObjectUnlock(client);
+    return local;
+}
+
+
 int virNetServerClientGetUNIXIdentity(virNetServerClientPtr client,
                                       uid_t *uid, gid_t *gid, pid_t *pid)
 {
@@ -619,6 +641,20 @@ int virNetServerClientGetUNIXIdentity(virNetServerClientPtr client,
     return ret;
 }
 
+
+int virNetServerClientGetSecurityContext(virNetServerClientPtr client,
+                                         char **context)
+{
+    int ret = 0;
+    *context = NULL;
+    virObjectLock(client);
+    if (client->sock)
+        ret = virNetSocketGetSecurityContext(client->sock, context);
+    virObjectUnlock(client);
+    return ret;
+}
+
+
 bool virNetServerClientIsSecure(virNetServerClientPtr client)
 {
     bool secure = false;
@@ -651,6 +687,16 @@ void virNetServerClientSetSASLSession(virNetServerClientPtr client,
     client->sasl = virObjectRef(sasl);
     virObjectUnlock(client);
 }
+
+
+virNetSASLSessionPtr virNetServerClientGetSASLSession(virNetServerClientPtr client)
+{
+    virNetSASLSessionPtr sasl;
+    virObjectLock(client);
+    sasl = client->sasl;
+    virObjectUnlock(client);
+    return sasl;
+}
 #endif
 
 
diff --git a/src/rpc/virnetserverclient.h b/src/rpc/virnetserverclient.h
index 31414bc..f8643f5 100644
--- a/src/rpc/virnetserverclient.h
+++ b/src/rpc/virnetserverclient.h
@@ -81,21 +81,28 @@ bool virNetServerClientGetReadonly(virNetServerClientPtr client);
 
 # ifdef WITH_GNUTLS
 bool virNetServerClientHasTLSSession(virNetServerClientPtr client);
+virNetTLSSessionPtr virNetServerClientGetTLSSession(virNetServerClientPtr client);
 int virNetServerClientGetTLSKeySize(virNetServerClientPtr client);
 # endif
 
 # ifdef WITH_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 *virNetServerClientGetPrivateData(virNetServerClientPtr client);
 
 typedef void (*virNetServerClientCloseFunc)(virNetServerClientPtr client);
diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
index 93980d6..af63975 100644
--- a/src/rpc/virnetsocket.c
+++ b/src/rpc/virnetsocket.c
@@ -40,6 +40,10 @@
 #endif
 
 #include "c-ctype.h"
+#ifdef HAVE_SELINUX
+# include <selinux/selinux.h>
+#endif
+
 #include "virnetsocket.h"
 #include "virutil.h"
 #include "viralloc.h"
@@ -1154,6 +1158,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 ATTRIBUTE_UNUSED,
+                                   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 13583f8..7392c72 100644
--- a/src/rpc/virnetsocket.h
+++ b/src/rpc/virnetsocket.h
@@ -114,6 +114,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 6665268..aa7ba49 100644
--- a/src/rpc/virnettlscontext.c
+++ b/src/rpc/virnettlscontext.c
@@ -71,6 +71,7 @@ struct _virNetTLSSession {
     virNetTLSSessionWriteFunc writeFunc;
     virNetTLSSessionReadFunc readFunc;
     void *opaque;
+    char *x509dname;
 };
 
 static virClassPtr virNetTLSContextClass;
@@ -1026,6 +1027,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,
@@ -1361,11 +1366,24 @@ cleanup:
     return ssf;
 }
 
+const char *virNetTLSSessionGetX509DName(virNetTLSSessionPtr sess)
+{
+    const char *ret = NULL;
+
+    virObjectLock(sess);
+
+    ret = sess->x509dname;
+
+    virObjectUnlock(sess);
+
+    return ret;
+}
 
 void virNetTLSSessionDispose(void *obj)
 {
     virNetTLSSessionPtr sess = obj;
 
+    VIR_FREE(sess->x509dname);
     VIR_FREE(sess->hostname);
     gnutls_deinit(sess->session);
 }
diff --git a/src/rpc/virnettlscontext.h b/src/rpc/virnettlscontext.h
index 5910ceb..21539ad 100644
--- a/src/rpc/virnettlscontext.h
+++ b/src/rpc/virnettlscontext.h
@@ -94,4 +94,6 @@ virNetTLSSessionGetHandshakeStatus(virNetTLSSessionPtr sess);
 
 int virNetTLSSessionGetKeySize(virNetTLSSessionPtr sess);
 
+const char *virNetTLSSessionGetX509DName(virNetTLSSessionPtr sess);
+
 #endif
-- 
1.8.1.4




More information about the libvir-list mailing list