[libvirt] [PATCH 04/12] Add APIs to get at more client security data
Michal Privoznik
mprivozn at redhat.com
Wed May 2 15:23:07 UTC 2012
On 02.05.2012 13:44, Daniel P. Berrange wrote:
> 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;
= 0;
> + *context = NULL;
> + virNetServerClientLock(client);
> + if (client->sock)
> + ret = virNetSocketGetSecurityContext(client->sock, context);
> + else
> + ret = 0;
leave out this else branch.
> + 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
> +
sock needs to be ATTRIBUTE_UNUSED here.
>
> 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);
>
>
ACK
Michal
(I have to stop here. Will continue tomorrow.)
More information about the libvir-list
mailing list