[Libvir] PATCH: 7/10: python auth callback API

Daniel P. Berrange berrange at redhat.com
Thu Nov 29 17:24:16 UTC 2007


This patch against current virt-manager illustrates how the python API is
used in a real world application to support Kerberos, Username/Password,
and PolicyKit authentication

Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 
-------------- next part --------------
diff -r 562150b337ba src/virt-manager.py.in
--- a/src/virt-manager.py.in	Wed Nov 28 17:58:19 2007 -0500
+++ b/src/virt-manager.py.in	Thu Nov 29 12:21:59 2007 -0500
@@ -172,12 +172,9 @@ def show_engine(engine, show, uri, uuid)
         if engine.config.get_connections() is None or len(engine.config.get_connections()) == 0:
             tryuri = None
             if os.path.exists("/var/lib/xend") and os.path.exists("/proc/xen"):
-                tryuri = "xen"
+                tryuri = "xen:///"
             elif os.path.exists("/usr/bin/qemu"):
-                if os.getuid() == 0:
-                    tryuri = "qemu:///system"
-                else:
-                    tryuri = "qemu:///session"
+                tryuri = "qemu:///system"
             if tryuri is not None:
                 conn = engine.add_connection(tryuri)
         engine.show_manager()
diff -r 562150b337ba src/virtManager/connect.py
--- a/src/virtManager/connect.py	Wed Nov 28 17:58:19 2007 -0500
+++ b/src/virtManager/connect.py	Thu Nov 29 12:21:59 2007 -0500
@@ -28,8 +28,9 @@ HV_QEMU = 1
 HV_QEMU = 1
 
 CONN_LOCAL = 0
-CONN_TLS = 1
-CONN_SSH = 2
+CONN_TCP = 1
+CONN_TLS = 2
+CONN_SSH = 3
 
 class vmmConnect(gobject.GObject):
     __gsignals__ = {
@@ -95,23 +96,22 @@ class vmmConnect(gobject.GObject):
             pass
         elif hv == HV_XEN:
             if conn == CONN_LOCAL:
-                uri = "xen"
-                if os.getuid() != 0:
-                    readOnly = True
+                uri = "xen:///"
             elif conn == CONN_TLS:
                 uri = "xen+tls://" + host + "/"
             elif conn == CONN_SSH:
                 uri = "xen+ssh://root@" + host + "/"
+            elif conn == CONN_TCP:
+                uri = "xen+tcp://" + host + "/"
         else:
             if conn == CONN_LOCAL:
-                if os.getuid() == 0:
-                    uri = "qemu:///system"
-                else:
-                    uri = "qemu:///session"
+                uri = "qemu:///system"
             elif conn == CONN_TLS:
                 uri = "qemu+tls://" + host + "/system"
             elif conn == CONN_SSH:
                 uri = "qemu+ssh://root@" + host + "/system"
+            elif conn == CONN_TCP:
+                uri = "qemu+tcp://" + host + "/system"
 
         logging.debug("Connection to open is %s" % uri)
         self.close()
diff -r 562150b337ba src/virtManager/connection.py
--- a/src/virtManager/connection.py	Wed Nov 28 17:58:19 2007 -0500
+++ b/src/virtManager/connection.py	Thu Nov 29 12:21:59 2007 -0500
@@ -294,22 +294,97 @@ class vmmConnection(gobject.GObject):
         self.connectThread.setDaemon(True)
         self.connectThread.start()
 
+    def _do_creds_polkit(self, action):
+        logging.debug("Doing policykit for %s" % action)
+        bus = dbus.SessionBus()
+        obj = bus.get_object("org.gnome.PolicyKit", "/org/gnome/PolicyKit/Manager")
+        pkit = dbus.Interface(obj, "org.gnome.PolicyKit.Manager")
+        pkit.ShowDialog(action, 0)
+        return 0
+
+    def _do_creds_dialog(self, creds):
+        try:
+            gtk.gdk.threads_enter()
+            return self._do_creds_dialog_main(creds)
+        finally:
+            gtk.gdk.threads_leave()
+
+    def _do_creds_dialog_main(self, creds):
+        dialog = gtk.Dialog("Authentication required", None, 0, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK))
+        label = []
+        entry = []
+
+        box = gtk.Table(2, len(creds))
+
+        row = 0
+        for cred in creds:
+            if cred[0] == libvirt.VIR_CRED_AUTHNAME or cred[0] == libvirt.VIR_CRED_PASSPHRASE:
+                label.append(gtk.Label(cred[1]))
+            else:
+                return -1
+
+            ent = gtk.Entry()
+            if cred[0] == libvirt.VIR_CRED_PASSPHRASE:
+                ent.set_visibility(False)
+            entry.append(ent)
+
+            box.attach(label[row], 0, 1, row, row+1, 0, 0, 3, 3)
+            box.attach(entry[row], 1, 2, row, row+1, 0, 0, 3, 3)
+            row = row + 1
+
+        vbox = dialog.get_child()
+        vbox.add(box)
+
+        dialog.show_all()
+        res = dialog.run()
+        dialog.hide()
+
+        if res == gtk.RESPONSE_OK:
+            row = 0
+            for cred in creds:
+                cred[4] = entry[row].get_text()
+                row = row + 1
+            dialog.destroy()
+            return 0
+        else:
+            dialog.destroy()
+            return -1
+
+    def _do_creds(self, creds, cbdata):
+        try:
+            if len(creds) == 1 and creds[0][0] == libvirt.VIR_CRED_EXTERNAL and creds[0][2] == "PolicyKit":
+                return self._do_creds_polkit(creds[0][1])
+
+            for cred in creds:
+                if creds[0] == libvirt.VIR_CRED_EXTERNAL:
+                    return -1
+
+            return self._do_creds_dialog(creds)
+        except:
+            (type, value, stacktrace) = sys.exc_info ()
+            # Detailed error message, in English so it can be Googled.
+            self.connectError = \
+                ("Failed to get credentials '%s':\n" %
+                 str(self.uri)) + \
+                 str(type) + " " + str(value) + "\n" + \
+                 traceback.format_exc (stacktrace)
+            logging.error(self.connectError)
+            return -1
 
     def _open_thread(self):
         logging.debug("Background thread is running")
         try:
-            if self.readOnly is None:
-                try:
-                    self.vmm = libvirt.open(self.uri)
-                    self.readOnly = False
-                except:
-                    self.vmm = libvirt.openReadOnly(self.uri)
-                    self.readOnly = True
-            else:
-                if self.readOnly:
-                    self.vmm = libvirt.openReadOnly(self.uri)
-                else:
-                    self.vmm = libvirt.open(self.uri)
+            flags = 0
+            if self.readOnly:
+                flags = libvirt.VIR_CONNECT_RO
+
+            self.vmm = libvirt.openAuth(self.uri,
+                                        [[libvirt.VIR_CRED_AUTHNAME,
+                                          libvirt.VIR_CRED_PASSPHRASE,
+                                          libvirt.VIR_CRED_EXTERNAL],
+                                         self._do_creds,
+                                         None], flags)
+
             self.state = self.STATE_ACTIVE
         except:
             self.state = self.STATE_DISCONNECTED
diff -r 562150b337ba src/vmm-open-connection.glade
--- a/src/vmm-open-connection.glade	Wed Nov 28 17:58:19 2007 -0500
+++ b/src/vmm-open-connection.glade	Thu Nov 29 12:21:59 2007 -0500
@@ -180,6 +180,7 @@
 	    <widget class="GtkComboBox" id="connection">
 	      <property name="visible">True</property>
 	      <property name="items" translatable="yes">Local
+Remote Password or Kerberos
 Remote SSL/TLS with x509 certificate
 Remote tunnel over SSH</property>
 	      <property name="add_tearoffs">False</property>


More information about the libvir-list mailing list