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