diff --git a/src/libvirt_gnutls.syms b/src/libvirt_gnutls.syms index bd4f950c81..6eb674101f 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 5cad990076..369701ee17 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -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; diff --git a/src/libvirt_sasl.syms b/src/libvirt_sasl.syms index beb8825a58..1241884b77 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 19063ef146..3edcd3c3c1 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 31414bc4d5..f8643f5873 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 fe4ac715d3..68aca1b2e9 100644 --- a/src/rpc/virnetsocket.c +++ b/src/rpc/virnetsocket.c @@ -40,6 +40,10 @@ #endif #include "c-ctype.h" +#ifdef HAVE_SELINUX +# include +#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) diff --git a/src/rpc/virnetsocket.h b/src/rpc/virnetsocket.h index 13583f846c..7392c722bf 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 ece4620297..eed0439c32 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, @@ -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); } diff --git a/src/rpc/virnettlscontext.h b/src/rpc/virnettlscontext.h index 5910ceb9e9..21539adb99 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