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

Daniel P. Berrange berrange at redhat.com
Thu Nov 29 17:20:52 UTC 2007


This adds a binding for the virConnectOpenAuth() api in the python
API. This allows a python function to be used as the callback.

This short example code illustrates the use of the API from a
python app which wants to support username/password credentials
only.

  from getpass import getpass
  mydata = "Hello"

  def getCred(creds, data):
      print "yes"
      print str(creds)
      for cred in creds:
          print cred[1] + ": ",
          if cred[0] == libvirt.VIR_CRED_AUTHNAME:
              data = sys.stdin.readline()
              data = data[0:len(data)-1]
              cred[4] = data
          elif cred[0] == libvirt.VIR_CRED_PASSPHRASE:
             cred[4] = getpass("")
          else:
             return -1
      return 0

  uri = "qemu+tcp://localhost/system"
  conn = libvirt.openAuth(uri,
                          [[libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_PASSPHRASE],
                           getCred,
                           mydata], 0)


  print str(conn.listDefinedDomains())


 python/libvir.c  |  119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 python/libvir.py |    6 ++
 src/qemu_conf.c  |    8 +--
 3 files changed, 129 insertions(+), 4 deletions(-)


diff -r 8a79678f789f python/libvir.c
--- a/python/libvir.c	Wed Nov 28 23:01:30 2007 -0500
+++ b/python/libvir.c	Wed Nov 28 23:29:40 2007 -0500
@@ -241,6 +241,124 @@ libvirt_virRegisterErrorHandler(ATTRIBUT
     return (py_retval);
 }
 
+static int virConnectCredCallbackWrapper(virConnectCredentialPtr cred,
+                                         unsigned int ncred,
+                                         void *cbdata) {
+    PyObject *list;
+    PyObject *pycred;
+    PyObject *pyauth = (PyObject *)cbdata;
+    PyObject *pycbdata;
+    PyObject *pycb;
+    PyObject *pyret;
+    int ret = -1, i;
+
+    LIBVIRT_ENSURE_THREAD_STATE;
+
+    pycb = PyList_GetItem(pyauth, 1);
+    pycbdata = PyList_GetItem(pyauth, 2);
+
+    list = PyTuple_New(2);
+    pycred = PyTuple_New(ncred);
+    for (i = 0 ; i < ncred ; i++) {
+        PyObject *pycreditem;
+        pycreditem = PyList_New(5);
+        Py_INCREF(Py_None);
+        PyTuple_SetItem(pycred, i, pycreditem);
+        PyList_SetItem(pycreditem, 0, PyInt_FromLong((long) cred[i].type));
+        PyList_SetItem(pycreditem, 1, PyString_FromString(cred[i].prompt));
+        if (cred[i].challenge) {
+            PyList_SetItem(pycreditem, 2, PyString_FromString(cred[i].challenge));
+        } else {
+            Py_INCREF(Py_None);
+            PyList_SetItem(pycreditem, 2, Py_None);
+        }
+        if (cred[i].defresult) {
+            PyList_SetItem(pycreditem, 3, PyString_FromString(cred[i].defresult));
+        } else {
+            Py_INCREF(Py_None);
+            PyList_SetItem(pycreditem, 3, Py_None);
+        }
+        PyList_SetItem(pycreditem, 4, Py_None);
+    }
+
+    PyTuple_SetItem(list, 0, pycred);
+    Py_XINCREF(pycbdata);
+    PyTuple_SetItem(list, 1, pycbdata);
+
+    PyErr_Clear();
+    pyret = PyEval_CallObject(pycb, list);
+    if (PyErr_Occurred())
+        goto cleanup;
+
+    ret = PyLong_AsLong(pyret);
+    if (ret == 0) {
+        for (i = 0 ; i < ncred ; i++) {
+            PyObject *pycreditem;
+            PyObject *pyresult;
+            char *result = NULL;
+            pycreditem = PyTuple_GetItem(pycred, i);
+            pyresult = PyList_GetItem(pycreditem, 4);
+            if (pyresult != Py_None)
+                result = PyString_AsString(pyresult);
+            if (result != NULL) {
+                cred[i].result = strdup(result);
+                cred[i].resultlen = strlen(result);
+            } else {
+                cred[i].result = NULL;
+                cred[i].resultlen = 0;
+            }
+        }
+    }
+
+ cleanup:
+    Py_XDECREF(list);
+    Py_XDECREF(pyret);
+
+    LIBVIRT_RELEASE_THREAD_STATE;
+
+    return ret;
+}
+
+
+static PyObject *
+libvirt_virConnectOpenAuth(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
+    PyObject *py_retval;
+    virConnectPtr c_retval;
+    char * name;
+    int flags;
+    PyObject *pyauth;
+    PyObject *pycredcb;
+    PyObject *pycredtype;
+    virConnectAuth auth;
+
+    if (!PyArg_ParseTuple(args, (char *)"zOi:virConnectOpenAuth", &name, &pyauth, &flags))
+        return(NULL);
+
+    pycredtype = PyList_GetItem(pyauth, 0);
+    pycredcb = PyList_GetItem(pyauth, 1);
+
+    auth.ncredtype = PyList_Size(pycredtype);
+    if (auth.ncredtype) {
+        int i;
+        auth.credtype = malloc(sizeof(int) * auth.ncredtype);
+        for (i = 0 ; i < auth.ncredtype ; i++) {
+            PyObject *val;
+            val = PyList_GetItem(pycredtype, i);
+            auth.credtype[i] = (int)PyLong_AsLong(val);
+        }
+    }
+    auth.cb = pycredcb ? virConnectCredCallbackWrapper : NULL;
+    auth.cbdata = pyauth;
+
+    LIBVIRT_BEGIN_ALLOW_THREADS;
+
+    c_retval = virConnectOpenAuth(name, &auth, flags);
+    LIBVIRT_END_ALLOW_THREADS;
+    py_retval = libvirt_virConnectPtrWrap((virConnectPtr) c_retval);
+    return(py_retval);
+}
+
+
 /************************************************************************
  *									*
  *		Wrappers for functions where generator fails		*
@@ -729,6 +847,7 @@ static PyMethodDef libvirtMethods[] = {
 #include "libvirt-export.c"
     {(char *) "virGetVersion", libvirt_virGetVersion, METH_VARARGS, NULL},
     {(char *) "virDomainFree", libvirt_virDomainFree, METH_VARARGS, NULL},
+    {(char *) "virConnectOpenAuth", libvirt_virConnectOpenAuth, METH_VARARGS, NULL},
     {(char *) "virConnectClose", libvirt_virConnectClose, METH_VARARGS, NULL},
     {(char *) "virConnectListDomainsID", libvirt_virConnectListDomainsID, METH_VARARGS, NULL},
     {(char *) "virConnectListDefinedDomains", libvirt_virConnectListDefinedDomains, METH_VARARGS, NULL},
diff -r 8a79678f789f python/libvir.py
--- a/python/libvir.py	Wed Nov 28 23:01:30 2007 -0500
+++ b/python/libvir.py	Wed Nov 28 23:29:40 2007 -0500
@@ -83,6 +83,12 @@ def registerErrorHandler(f, ctx):
        Returns 1 in case of success."""
     return libvirtmod.virRegisterErrorHandler(f,ctx)
 
+def openAuth(uri, auth, flags):
+    ret = libvirtmod.virConnectOpenAuth(uri, auth, flags)
+    if ret is None:raise libvirtError('virConnectOpenAuth() failed')
+    return virConnect(_obj=ret)
+
+
 #
 # Return library version.
 #
diff -r 8a79678f789f src/qemu_conf.c
--- a/src/qemu_conf.c	Wed Nov 28 23:01:30 2007 -0500
+++ b/src/qemu_conf.c	Wed Nov 28 23:29:40 2007 -0500
@@ -2667,7 +2667,7 @@ checkLinkPointsTo(const char *checkLink,
         char *p;
 
         strncpy(dir, checkLink, PATH_MAX);
-        dir[PATH_MAX] = '\0';
+        dir[PATH_MAX-1] = '\0';
 
         if (!(p = strrchr(dir, '/'))) {
             qemudLog(QEMUD_WARN, "Symlink path '%s' is not absolute", checkLink);
@@ -2685,7 +2685,7 @@ checkLinkPointsTo(const char *checkLink,
         }
 
         strncpy(dest, tmp, PATH_MAX);
-        dest[PATH_MAX] = '\0';
+        dest[PATH_MAX-1] = '\0';
     }
 
     /* canonicalize both paths */
@@ -2693,14 +2693,14 @@ checkLinkPointsTo(const char *checkLink,
         qemudLog(QEMUD_WARN, "Failed to expand path '%s' :%s",
                  dest, strerror(errno));
         strncpy(real, dest, PATH_MAX);
-        real[PATH_MAX] = '\0';
+        real[PATH_MAX-1] = '\0';
     }
 
     if (!realpath(checkDest, checkReal)) {
         qemudLog(QEMUD_WARN, "Failed to expand path '%s' :%s",
                  checkDest, strerror(errno));
         strncpy(checkReal, checkDest, PATH_MAX);
-        checkReal[PATH_MAX] = '\0';
+        checkReal[PATH_MAX-1] = '\0';
     }
 
     /* compare */

-- 
|=- 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  -=| 




More information about the libvir-list mailing list