[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