From: "Daniel P. Berrange" <berrange(a)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