Google
  Web www.spinics.net

[PATCH] virtinst: Use openAuth to support SASL and PolicyKit

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


The attached patch changes the virt-* cli tools to use the libvirt
openAuth function for opening connections. This allows using PolicyKit
and SASL auth with the tools.

polkit-auth is forced to run in cli mode, so no graphical dialog will be
launched. I've thought about having the --prompt flag play a role here,
but since the use cases this fulfills did not previously work, there
shouldn't be any chance of breaking existing uses.

Thanks,
Cole
# HG changeset patch
# User Cole Robinson <crobinso@xxxxxxxxxx>
# Date 1241723712 14400
# Node ID 0c58ccf22773e2906853f3ac95fb3cc9ceaa158d
# Parent  2ac98205eb469857ea4110125502eab23dd8e24f
Allow PolicyKit and SASL authentication.

Use openAuth when opening the initial connection: allows PolicyKit and
SASA username/password auth.

diff -r 2ac98205eb46 -r 0c58ccf22773 virtinst/cli.py
--- a/virtinst/cli.py	Thu May 07 13:47:49 2009 -0400
+++ b/virtinst/cli.py	Thu May 07 15:15:12 2009 -0400
@@ -117,6 +117,7 @@
     print _("Exiting at user request.")
     sys.exit(0)
 
+# Connection opening helper functions
 def getConnection(connect):
     if not User.current().has_priv(User.PRIV_CREATE_DOMAIN, connect):
         fail(_("Must be root to create Xen guests"))
@@ -124,7 +125,105 @@
         fail(_("Could not find usable default libvirt connection."))
 
     logging.debug("Using libvirt URI '%s'" % connect)
-    return libvirt.open(connect)
+    return open_connection(connect)
+
+def open_connection(uri):
+    open_flags = 0
+    valid_auth_options = [libvirt.VIR_CRED_AUTHNAME,
+                          libvirt.VIR_CRED_PASSPHRASE,
+                          libvirt.VIR_CRED_EXTERNAL]
+    authcb = do_creds
+    authcb_data = None
+
+    return libvirt.openAuth(uri, [valid_auth_options, authcb, authcb_data],
+                            open_flags)
+
+def do_creds(creds, cbdata):
+    try:
+        return _do_creds(creds, cbdata)
+    except:
+        _util.log_exception("Error in creds callback.")
+        raise
+
+def _do_creds(creds, cbdata_ignore):
+
+    if (len(creds) == 1 and
+        creds[0][0] == libvirt.VIR_CRED_EXTERNAL and
+        creds[0][2] == "PolicyKit"):
+        return _do_creds_polkit(creds[0][1])
+
+    for cred in creds:
+        if cred[0] == libvirt.VIR_CRED_EXTERNAL:
+            return -1
+
+    return _do_creds_authname(creds)
+
+# PolicyKit auth
+def _do_creds_polkit(action):
+    if os.getuid() == 0:
+        logging.debug("Skipping policykit check as root")
+        return 0 # Success
+    logging.debug("Doing policykit for %s" % action)
+
+    import subprocess
+    import commands
+
+    bin_path = "/usr/bin/polkit-auth"
+
+    if not os.path.exists(bin_path):
+        logging.debug("%s not present, skipping polkit auth." % bin_path)
+        return 0
+
+    cmdstr = "%s %s" % (bin_path, "--explicit")
+    output = commands.getstatusoutput(cmdstr)
+    if output[1].count(action):
+        logging.debug("User already authorized for %s." % action)
+        # Hide spurious output from polkit-auth
+        popen_stdout = subprocess.PIPE
+        popen_stderr = subprocess.PIPE
+    else:
+        popen_stdout = None
+        popen_stderr = None
+
+    # Force polkit prompting to be text mode. Not strictly required, but
+    # launching a dialog is overkill.
+    env = os.environ.copy()
+    env["POLKIT_AUTH_FORCE_TEXT"] = "set"
+
+    cmd = [bin_path, "--obtain", action]
+    proc = subprocess.Popen(cmd, env=env, stdout=popen_stdout,
+                            stderr=popen_stderr)
+    out, err = proc.communicate()
+
+    if out and popen_stdout:
+        logging.debug("polkit-auth stdout: %s" % out)
+    if err and popen_stderr:
+        logging.debug("polkit-auth stderr: %s" % err)
+
+    return 0
+
+# SASL username/pass auth
+def _do_creds_authname(creds):
+    retindex = 4
+
+    for cred in creds:
+        credtype, prompt, ignore, ignore, ignore = cred
+        prompt += ": "
+
+        res = cred[retindex]
+        if credtype == libvirt.VIR_CRED_AUTHNAME:
+            res = raw_input(prompt)
+        elif credtype == libvirt.VIR_CRED_PASSPHRASE:
+            import getpass
+            res = getpass.getpass(prompt)
+        else:
+            logging.debug("Unknown auth type in creds callback: %d" %
+                          credtype)
+            return -1
+
+        cred[retindex] = res
+
+    return 0
 
 #
 # Prompting
_______________________________________________
et-mgmt-tools mailing list
et-mgmt-tools@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/et-mgmt-tools

[Home]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Red Hat 9 Bible]     [Fedora Bible]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]

Powered by Linux

Google
  Web www.spinics.net