[libvirt] [PATCH v3 2/3] util: Introduce API's for Polkit text authentication

Daniel P. Berrange berrange at redhat.com
Thu Feb 25 14:25:38 UTC 2016


On Fri, Feb 12, 2016 at 12:12:32PM -0500, John Ferlan wrote:
> Introduce virPolkitAgentCreate and virPolkitAgentDestroy
> 
> virPolkitAgentCreate will run the polkit pkttyagent image as an asynchronous
> command in order to handle the local agent authentication via stdin/stdout.
> The code makes use of the pkttyagent --notify-fd mechanism to let it know
> when the agent is successfully registered.
> 
> virPolkitAgentDestroy will close the command effectively reaping our
> child process
> 
> Needed to move around or add the "#include vircommand.h" since,
> virpolkit.h now uses it.
> 
> Signed-off-by: John Ferlan <jferlan at redhat.com>
> ---
>  src/libvirt_private.syms |  2 ++
>  src/util/virpolkit.c     | 77 +++++++++++++++++++++++++++++++++++++++++++++++-
>  src/util/virpolkit.h     |  5 ++++
>  tests/virpolkittest.c    |  1 +
>  4 files changed, 84 insertions(+), 1 deletion(-)
> 
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 4cfaed5..8f2358f 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -2029,6 +2029,8 @@ virPidFileWritePath;
>  
>  
>  # util/virpolkit.h
> +virPolkitAgentCreate;
> +virPolkitAgentDestroy;
>  virPolkitCheckAuth;
>  
>  
> diff --git a/src/util/virpolkit.c b/src/util/virpolkit.c
> index df707f1..6941d74 100644
> --- a/src/util/virpolkit.c
> +++ b/src/util/virpolkit.c
> @@ -20,20 +20,22 @@
>   */
>  
>  #include <config.h>
> +#include <poll.h>
>  
>  #if WITH_POLKIT0
>  # include <polkit/polkit.h>
>  # include <polkit-dbus/polkit-dbus.h>
>  #endif
>  
> -#include "virpolkit.h"
>  #include "vircommand.h"
> +#include "virpolkit.h"
>  #include "virerror.h"
>  #include "virlog.h"
>  #include "virstring.h"
>  #include "virprocess.h"
>  #include "viralloc.h"
>  #include "virdbus.h"
> +#include "virfile.h"
>  
>  #define VIR_FROM_THIS VIR_FROM_POLKIT
>  
> @@ -136,6 +138,65 @@ int virPolkitCheckAuth(const char *actionid,
>  }
>  
>  
> +/* virPolkitAgentDestroy:
> + * @cmd: Pointer to the virCommandPtr created during virPolkitAgentCreate
> + *
> + * Destroy resources used by Polkit Agent
> + */
> +void
> +virPolkitAgentDestroy(virCommandPtr cmd)
> +{
> +    virCommandFree(cmd);
> +}
> +
> +/* virPolkitAgentCreate:
> + *
> + * Allocate and setup a polkit agent
> + *
> + * Returns a virCommandPtr on success and NULL on failure
> + */
> +virCommandPtr
> +virPolkitAgentCreate(void)
> +{
> +    virCommandPtr cmd = virCommandNewArgList(PKTTYAGENT, "--process", NULL);
> +    int pipe_fd[2] = {-1, -1};
> +    struct pollfd pollfd;
> +    int outfd = STDOUT_FILENO;
> +    int errfd = STDERR_FILENO;
> +
> +    if (!isatty(STDIN_FILENO))
> +        goto error;
> +
> +    if (pipe2(pipe_fd, 0) < 0)
> +        goto error;
> +
> +    virCommandAddArgFormat(cmd, "%lld", (long long int) getpid());
> +    virCommandAddArg(cmd, "--notify-fd");
> +    virCommandAddArgFormat(cmd, "%d", pipe_fd[1]);
> +    virCommandAddArg(cmd, "--fallback");
> +    virCommandSetInputFD(cmd, STDIN_FILENO);
> +    virCommandSetOutputFD(cmd, &outfd);
> +    virCommandSetErrorFD(cmd, &errfd);
> +    virCommandPassFD(cmd, pipe_fd[1], VIR_COMMAND_PASS_FD_CLOSE_PARENT);
> +    if (virCommandRunAsync(cmd, NULL) < 0)
> +        goto error;
> +
> +    pollfd.fd = pipe_fd[0];
> +    pollfd.events = POLLHUP;
> +
> +    if (poll(&pollfd, 1, -1) < 0)
> +        goto error;
> +
> +    return cmd;
> +
> + error:
> +    VIR_FORCE_CLOSE(pipe_fd[0]);
> +    VIR_FORCE_CLOSE(pipe_fd[1]);
> +    virCommandFree(cmd);
> +    return NULL;
> +}
> +
> +
>  #elif WITH_POLKIT0
>  int virPolkitCheckAuth(const char *actionid,
>                         pid_t pid,
> @@ -254,4 +315,18 @@ int virPolkitCheckAuth(const char *actionid ATTRIBUTE_UNUSED,
>  }
>  
>  
> +void
> +virPolkitAgentDestroy(virCommandPtr cmd ATTRIBUTE_UNUSED)
> +{
> +    return; /* do nothing */
> +}
> +
> +
> +virCommandPtr
> +virPolkitAgentCreate(void)
> +{
> +    virReportError(VIR_ERR_AUTH_FAILED, "%s",
> +                   _("polkit text authentication agent unavailable"));
> +    return NULL;
> +}
>  #endif /* WITH_POLKIT1 */
> diff --git a/src/util/virpolkit.h b/src/util/virpolkit.h
> index 36122d0..f0aea37 100644
> --- a/src/util/virpolkit.h
> +++ b/src/util/virpolkit.h
> @@ -24,6 +24,8 @@
>  
>  # include "internal.h"
>  
> +# define PKTTYAGENT "/usr/bin/pkttyagent"
> +
>  int virPolkitCheckAuth(const char *actionid,
>                         pid_t pid,
>                         unsigned long long startTime,
> @@ -31,4 +33,7 @@ int virPolkitCheckAuth(const char *actionid,
>                         const char **details,
>                         bool allowInteraction);
>  
> +void virPolkitAgentDestroy(virCommandPtr cmd);
> +virCommandPtr virPolkitAgentCreate(void);

Rather than exposing use of virCommand in the API, I'd
suggest you create a


 typedef struct virPolkitAgent virPolkitAgent;
 typedef virPolkitAgent *virPolkitAgentPtr;

in the header file here

and in the .c do

  struct virPolitAgent {
      virCommandPtr;
  };

so we hide use of virCommand


> diff --git a/tests/virpolkittest.c b/tests/virpolkittest.c
> index 73f001b..b46e65f 100644
> --- a/tests/virpolkittest.c
> +++ b/tests/virpolkittest.c
> @@ -27,6 +27,7 @@
>  # include <stdlib.h>
>  # include <dbus/dbus.h>
>  
> +# include "vircommand.h"

avoiding this


Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|




More information about the libvir-list mailing list