]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Add APIs to get at more client security data
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 20 Jan 2012 17:18:28 +0000 (17:18 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 19 Mar 2013 13:11:46 +0000 (13:11 +0000)
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@redhat.com>
src/libvirt_gnutls.syms
src/libvirt_private.syms
src/libvirt_sasl.syms
src/rpc/virnetserverclient.c
src/rpc/virnetserverclient.h
src/rpc/virnetsocket.c
src/rpc/virnetsocket.h
src/rpc/virnettlscontext.c
src/rpc/virnettlscontext.h

index bd4f950c81473d226267a434e9f61c10bc3927b3..6eb674101fb2fbaf0fa631b6513e0f2af165b528 100644 (file)
@@ -13,6 +13,7 @@ virNetServerSetTLSContext;
 
 # rpc/virnetserverclient.h
 virNetServerClientGetTLSKeySize;
+virNetServerClientGetTLSSession;
 virNetServerClientHasTLSSession;
 
 
@@ -33,6 +34,7 @@ virNetTLSContextNewServerPath;
 virNetTLSInit;
 virNetTLSSessionGetHandshakeStatus;
 virNetTLSSessionGetKeySize;
+virNetTLSSessionGetX509DName;
 virNetTLSSessionHandshake;
 virNetTLSSessionNew;
 virNetTLSSessionRead;
index 5cad9900763822eb0d141c303ab3bc6c81706cee..369701ee17d88d6042da5a212c4d94210f6d3ecc 100644 (file)
@@ -854,11 +854,13 @@ virNetServerClientGetAuth;
 virNetServerClientGetFD;
 virNetServerClientGetPrivateData;
 virNetServerClientGetReadonly;
+virNetServerClientGetSecurityContext;
 virNetServerClientGetUNIXIdentity;
 virNetServerClientImmediateClose;
 virNetServerClientInit;
 virNetServerClientInitKeepAlive;
 virNetServerClientIsClosed;
+virNetServerClientIsLocal;
 virNetServerClientIsSecure;
 virNetServerClientLocalAddrString;
 virNetServerClientNeedAuth;
@@ -923,6 +925,7 @@ virNetSocketClose;
 virNetSocketDupFD;
 virNetSocketGetFD;
 virNetSocketGetPort;
+virNetSocketGetSecurityContext;
 virNetSocketGetUNIXIdentity;
 virNetSocketHasCachedData;
 virNetSocketHasPassFD;
index beb8825a588c8b311a97ff0035f83802f4440b97..1241884b775386a28d8b736227d8d34c5031eaad 100644 (file)
@@ -26,6 +26,7 @@ virNetSASLSessionServerStep;
 
 
 # rpc/virnetserverclient.h
+virNetServerClientGetSASLSession;
 virNetServerClientSetSASLSession;
 
 
index 19063ef146bbfbe4ced84c7d72578f5b04edce90..3edcd3c3c1a33292f06b48c9b4d291102dbd3752 100644 (file)
@@ -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
 
 
index 31414bc4d5a6a2b3c6c28773c3ae3ce352c23eab..f8643f5873476abea229e0ed6c1f0e19328acc6e 100644 (file)
@@ -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);
index fe4ac715d3590eab928de62650a04de0dfc4a829..68aca1b2e9679f92390f9e5788f3f8d8563b62d2 100644 (file)
 #endif
 
 #include "c-ctype.h"
+#ifdef HAVE_SELINUX
+# include <selinux/selinux.h>
+#endif
+
 #include "virnetsocket.h"
 #include "virutil.h"
 #include "viralloc.h"
@@ -1156,6 +1160,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)
index 13583f846cb19494b4ce61afe3f4d380d0f037ea..7392c722bf33e9336d81e2acca7988fc9b2290fc 100644 (file)
@@ -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);
index ece46202977214f4544f7c5d663937612527b733..eed0439c3214167eb9bc770a217abd464be6a6f9 100644 (file)
@@ -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,
@@ -1364,6 +1369,18 @@ 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)
 {
@@ -1372,6 +1389,7 @@ void virNetTLSSessionDispose(void *obj)
     PROBE(RPC_TLS_SESSION_DISPOSE,
           "sess=%p", sess);
 
+    VIR_FREE(sess->x509dname);
     VIR_FREE(sess->hostname);
     gnutls_deinit(sess->session);
 }
index 5910ceb9e9e877835e2b4732508e573cb5aa5f63..21539adb99076cd484849b52943c539871a17996 100644 (file)
@@ -94,4 +94,6 @@ virNetTLSSessionGetHandshakeStatus(virNetTLSSessionPtr sess);
 
 int virNetTLSSessionGetKeySize(virNetTLSSessionPtr sess);
 
+const char *virNetTLSSessionGetX509DName(virNetTLSSessionPtr sess);
+
 #endif