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@xxxxxxxxxx> > --- > 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 :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list