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