This patch contains:
-random bugfixes
-gcc -Wall "fixes"
-a few new constants for 4.x
-Implementation of virConnectAuth
-javah build fixes (One .class file can generate many .h files.)
It is NOT a full update for 4.x, the only major new feature is
authentication support.
I've attached the patch, and the new files. (Is there some way to
generate patches with new files?)
Please remove the
/src/jni/org_libvirt_VirDomain_CreateFlags.h
/src/jni/org_libvirt_VirDomain_MigrateFlags.h
files from the CVS, as these are auto-generated.
regards
István
? .project
? src/jni/VirConnectAuthCallbackBridge.c
? src/jni/VirConnectAuthCallbackBridge.h
? src/org/libvirt/VirConnectAuth.java
? src/org/libvirt/VirConnectAuthDefault.java
? src/org/libvirt/VirConnectCredential.java
Index: src/Makefile.am
===================================================================
RCS file: /data/cvs/libvirt-java/src/Makefile.am,v
retrieving revision 1.2
diff -u -p -r1.2 Makefile.am
--- src/Makefile.am 25 Jun 2008 13:02:30 -0000 1.2
+++ src/Makefile.am 29 Jun 2008 17:22:35 -0000
@@ -4,6 +4,9 @@ SUBDIRS=. jni
java_libvirt_source_files = \
org/libvirt/LibvirtException.java \
org/libvirt/VirConnect.java \
+ org/libvirt/VirConnectAuthDefault.java \
+ org/libvirt/VirConnectAuth.java \
+ org/libvirt/VirConnectCredential.java \
org/libvirt/VirDomainBlockStats.java \
org/libvirt/VirDomainInfo.java \
org/libvirt/VirDomainInterfaceStats.java \
Index: src/test.java
===================================================================
RCS file: /data/cvs/libvirt-java/src/test.java,v
retrieving revision 1.1
diff -u -p -r1.1 test.java
--- src/test.java 24 Jun 2008 16:32:24 -0000 1.1
+++ src/test.java 29 Jun 2008 17:22:35 -0000
@@ -16,6 +16,19 @@ public class test {
Integer.decode("0xc3"), Integer.decode("0x0f"),
Integer.decode("0x5a"), Integer.decode("0xa5"),
Integer.decode("0xf0"), Integer.decode("0x3c"),
Integer.decode("0x87"), Integer.decode("0xd2"),
Integer.decode("0x1e"), Integer.decode("0x69")} ;
+
+ //For testing the authentication
+ VirConnectAuth defaultAuth = new VirConnectAuthDefault();
+
+ //You need to configure your libvirtd for remote/authenticated connections, and adjust
the URL below
+ //for this to work. Otherwise, you'll get an error
+ try{
+ conn = new VirConnect("test+tcp://localhost/default", defaultAuth, 0);
+ System.out.println("Encrypted connection successful!");
+ } catch (LibvirtException e){
+ System.out.println("exception caught:"+e);
+ System.out.println(e.getVirError());
+ }
try{
conn = new VirConnect("test:///default", false);
Index: src/jni/Makefile.am
===================================================================
RCS file: /data/cvs/libvirt-java/src/jni/Makefile.am,v
retrieving revision 1.2
diff -u -p -r1.2 Makefile.am
--- src/jni/Makefile.am 25 Jun 2008 13:02:30 -0000 1.2
+++ src/jni/Makefile.am 29 Jun 2008 17:22:35 -0000
@@ -5,12 +5,17 @@ SOURCES = \
org_libvirt_VirConnect.c \
org_libvirt_VirDomain.c \
VirErrorHandler.c \
- VirErrorHandler.h
+ VirErrorHandler.h \
+ VirConnectAuthCallbackBridge.c \
+ VirConnectAuthCallbackBridge.h
GENERATED = \
org_libvirt_VirConnect.h \
org_libvirt_VirNetwork.h \
- org_libvirt_VirDomain.h
+ org_libvirt_VirDomain.h \
+ org_libvirt_VirDomain_CreateFlags.h \
+ org_libvirt_VirDomain_MigrateFlags.h \
+ org_libvirt_VirDomain_XMLFlags.h
BUILT_SOURCES = $(GENERATED)
@@ -20,7 +25,7 @@ org_libvirt_VirConnect.h : $(JAVA_CLASS_
org_libvirt_VirNetwork.h: $(JAVA_CLASS_ROOT)/org/libvirt/VirNetwork.class
$(JAVAH) -classpath $(JAVA_CLASS_ROOT) org.libvirt.VirNetwork
-org_libvirt_VirDomain.h: $(JAVA_CLASS_ROOT)/org/libvirt/VirDomain.class
+org_libvirt_VirDomain.h org_libvirt_VirDomain_CreateFlags.h
org_libvirt_VirDomain_MigrateFlags.h org_libvirt_VirDomain_XMLFlags.h :
$(JAVA_CLASS_ROOT)/org/libvirt/VirDomain.class
$(JAVAH) -classpath $(JAVA_CLASS_ROOT) org.libvirt.VirDomain
lib_LTLIBRARIES = libvirt_jni.la
@@ -31,4 +36,4 @@ libvirt_jni_la_LDFLAGS = -version-info
CLEANFILES = \
- $(GENERATED)
+ $(GENERATED) $(GENERATED_SUB_1)
Index: src/jni/org_libvirt_VirConnect.c
===================================================================
RCS file: /data/cvs/libvirt-java/src/jni/org_libvirt_VirConnect.c,v
retrieving revision 1.1
diff -u -p -r1.1 org_libvirt_VirConnect.c
--- src/jni/org_libvirt_VirConnect.c 24 Jun 2008 16:32:24 -0000 1.1
+++ src/jni/org_libvirt_VirConnect.c 29 Jun 2008 17:22:35 -0000
@@ -2,14 +2,20 @@
#include <libvirt/libvirt.h>
#include <stdlib.h>
#include "VirErrorHandler.h"
+#include "VirConnectAuthCallbackBridge.h"
+
+#include <assert.h>
+
+//TODO We are leaking UTFChars all over the place. We need to strcpy, then release every
string we get from JAVA, and not use them directly!
JNIEXPORT jint JNICALL Java_org_libvirt_VirConnect__1virInitialize
(JNIEnv *env, jclass cls){
int result;
result=virInitialize();
- //The connection-less errors go to the initializing thread as an aexception.
+ //The connection-less errors go to the initializing thread as an exception.
//Not ideal, but better than just dropping the errors.
virSetErrorFunc(env, virErrorHandler);
+ return result;
}
JNIEXPORT void JNICALL Java_org_libvirt_VirConnect__1close
@@ -22,7 +28,7 @@ JNIEXPORT jstring JNICALL Java_org_libvi
//All this gymnastics is so that we can free() the hostname string
jstring j_hostname=NULL;
char *hostname;
- if(hostname = virConnectGetHostname((virConnectPtr)VCP)){
+ if((hostname = virConnectGetHostname((virConnectPtr)VCP))){
j_hostname = (*env)->NewStringUTF(env, hostname);
free(hostname);
}
@@ -33,7 +39,7 @@ JNIEXPORT jstring JNICALL Java_org_libvi
(JNIEnv *env, jobject obj, jlong VCP){
jstring j_capabilities=NULL;
char *capabilities;
- if(capabilities = virConnectGetCapabilities((virConnectPtr)VCP)){
+ if((capabilities = virConnectGetCapabilities((virConnectPtr)VCP))){
j_capabilities = (*env)->NewStringUTF(env, capabilities);
free(capabilities);
}
@@ -49,7 +55,7 @@ JNIEXPORT jstring JNICALL Java_org_libvi
(JNIEnv *env, jobject obj, jlong VCP){
const char *type;
//Here we get a static string, no need to free()
- if(type=virConnectGetType((virConnectPtr)VCP)){
+ if((type=virConnectGetType((virConnectPtr)VCP))){
return (*env)->NewStringUTF(env, type);
} else {
return NULL;
@@ -60,7 +66,7 @@ JNIEXPORT jstring JNICALL Java_org_libvi
(JNIEnv *env, jobject obj, jlong VCP){
jstring j_uri=NULL;
char *uri;
- if(uri = virConnectGetURI((virConnectPtr)VCP)){
+ if((uri = virConnectGetURI((virConnectPtr)VCP))){
j_uri = (*env)->NewStringUTF(env, uri);
free(uri);
}
@@ -150,7 +156,7 @@ JNIEXPORT jlong JNICALL Java_org_libvirt
if(vc==NULL){
virCopyLastError(&error);
virErrorHandler(env, &error);
- return (long)NULL;
+ return (jlong)NULL;
}
//Initialized the error handler for this connection
@@ -170,7 +176,7 @@ JNIEXPORT jlong JNICALL Java_org_libvirt
if(vc==NULL){
virCopyLastError(&error);
virErrorHandler(env, &error);
- return (long)NULL;
+ return (jlong)NULL;
}
//Initialized the error handler for this connection
@@ -179,14 +185,67 @@ JNIEXPORT jlong JNICALL Java_org_libvirt
return (jlong)vc;
};
+JNIEXPORT jlong JNICALL Java_org_libvirt_VirConnect__1openAuth
+ (JNIEnv *env, jobject obj, jstring uri, jobject j_auth, jint flags){
+
+ virConnectPtr vc;
+ virError error;
+
+ virConnectAuth *auth = malloc(sizeof(virConnectAuth));
+
+ jobject j_credTypeElement;
+ int c;
+
+ //Prepare by computing the class and field IDs
+ jfieldID credTypeArray_id = (*env)->GetFieldID(env,
+ (*env)->FindClass(env, "org/libvirt/VirConnectAuth"),
+ "credType",
+ "[Lorg/libvirt/VirConnectCredential$VirConnectCredentialType;");
+ jmethodID credTypeMapToInt_id = (*env)->GetMethodID(env,
+ (*env)->FindClass(env,
"org/libvirt/VirConnectCredential$VirConnectCredentialType"),
+ "mapToInt",
+ "()I");
+
+ //Copy the array of credtypes with the helper function
+ jarray j_credTypeArray=(*env)->GetObjectField(env, j_auth, credTypeArray_id);
+ auth->ncredtype = (*env)->GetArrayLength(env, j_credTypeArray);
+
+ auth->credtype = calloc(auth->ncredtype, sizeof(int));
+ for(c=0; c< auth->ncredtype; c++){
+ j_credTypeElement = (*env)->GetObjectArrayElement(env, j_credTypeArray, c);
+ auth->credtype[c]=(*env)->CallIntMethod(env, j_credTypeElement,
credTypeMapToInt_id);
+ }
+
+ //The callback function is always VirConnectAuthCallbackBridge
+ auth->cb = &VirConnectAuthCallbackBridge;
+ //We pass the VirConnectAuth object and the JNI env in cdbata
+ CallBackStructType* cb_wrapper;
+ cb_wrapper = malloc(sizeof(CallBackStructType));
+ cb_wrapper->env = env;
+ cb_wrapper->auth = j_auth;
+ auth->cbdata=cb_wrapper;
+
+ vc=virConnectOpenAuth((*env)->GetStringUTFChars(env, uri, NULL), auth, flags);
+ if(vc==NULL){
+ virCopyLastError(&error);
+ virErrorHandler(env, &error);
+ return (jlong)NULL;
+ }
+
+ //Initialize the error handler for this connection
+ virConnSetErrorFunc(vc, env, virErrorHandler);
+
+ return (jlong)vc;
+}
+
JNIEXPORT jlong JNICALL Java_org_libvirt_VirConnect__1virNetworkCreateXML
(JNIEnv *env, jobject obj, jlong VCP, jstring xmlDesc){
- return(jlong)virNetworkCreateXML((virConnectPtr)VCP, (*env)->GetStringUTFChars(env,
xmlDesc, NULL));
+ return (jlong)virNetworkCreateXML((virConnectPtr)VCP, (*env)->GetStringUTFChars(env,
xmlDesc, NULL));
}
JNIEXPORT jlong JNICALL Java_org_libvirt_VirConnect__1virNetworkDefineXML
(JNIEnv *env, jobject obj, jlong VCP, jstring xmlDesc){
- return(jlong)virNetworkDefineXML((virConnectPtr)VCP, (*env)->GetStringUTFChars(env,
xmlDesc, NULL));
+ return (jlong)virNetworkDefineXML((virConnectPtr)VCP, (*env)->GetStringUTFChars(env,
xmlDesc, NULL));
}
JNIEXPORT jlong JNICALL Java_org_libvirt_VirConnect__1virNetworkLookupByName
@@ -202,7 +261,6 @@ JNIEXPORT jlong JNICALL Java_org_libvirt
//compact to bytes
for(c=0; c < VIR_UUID_BUFLEN; c++)
UUID[c]=UUID_int[c];
- (*env)->ExceptionDescribe(env);
return (jlong)virNetworkLookupByUUID((virConnectPtr)VCP, UUID);
}
@@ -266,8 +324,8 @@ JNIEXPORT jintArray JNICALL Java_org_lib
(JNIEnv *env, jobject obj, jlong VCP){
int maxids;
int *ids;
- int c;
jintArray j_ids=NULL;
+
if((maxids = virConnectNumOfDomains((virConnectPtr)VCP))<0)
return NULL;
ids= (int*)calloc(maxids, sizeof(int));
@@ -313,7 +371,7 @@ JNIEXPORT jlong JNICALL Java_org_libvirt
JNIEXPORT jlong JNICALL Java_org_libvirt_VirConnect__1virGetHypervisorVersion
(JNIEnv *env, jobject obj, jstring j_type){
- long libVer;
+ unsigned long libVer;
const char *type;
unsigned long typeVer;
Index: src/jni/org_libvirt_VirDomain.c
===================================================================
RCS file: /data/cvs/libvirt-java/src/jni/org_libvirt_VirDomain.c,v
retrieving revision 1.1
diff -u -p -r1.1 org_libvirt_VirDomain.c
--- src/jni/org_libvirt_VirDomain.c 24 Jun 2008 16:32:24 -0000 1.1
+++ src/jni/org_libvirt_VirDomain.c 29 Jun 2008 17:22:36 -0000
@@ -7,7 +7,7 @@ JNIEXPORT jstring JNICALL Java_org_libvi
(JNIEnv *env, jobject obj, jlong VDP, jint flags){
jstring j_xmlDesc;
char* xmlDesc = NULL;
- if(xmlDesc = virDomainGetXMLDesc((virDomainPtr)VDP, flags)){
+ if((xmlDesc = virDomainGetXMLDesc((virDomainPtr)VDP, flags))){
j_xmlDesc = (*env)->NewStringUTF(env, xmlDesc);
free(xmlDesc);
}
@@ -56,7 +56,7 @@ JNIEXPORT jstring JNICALL Java_org_libvi
jstring j_OSType;
char *OSType;
- if(OSType = virDomainGetOSType((virDomainPtr)VDP)){
+ if((OSType = virDomainGetOSType((virDomainPtr)VDP))){
j_OSType = (*env)->NewStringUTF(env, OSType);
free(OSType);
}
@@ -70,7 +70,7 @@ JNIEXPORT jobjectArray JNICALL Java_org_
int nparams;
//We don't return nparams
- if(schedulerType = virDomainGetSchedulerType((virDomainPtr)VDP, &nparams)){
+ if((schedulerType = virDomainGetSchedulerType((virDomainPtr)VDP, &nparams))){
j_schedulerType = (*env)->NewStringUTF(env, schedulerType);
free(schedulerType);
}
@@ -264,7 +264,6 @@ JNIEXPORT jobjectArray JNICALL Java_org_
jobject j_info;
jobjectArray j_infoArray=NULL;
- jobjectArray j_statusArray;
jfieldID number_id;
jfieldID state_id;
@@ -332,7 +331,7 @@ JNIEXPORT jintArray JNICALL Java_org_lib
int *i_cpumaps;
jintArray j_cpumaps;
int c;
- virNodeInfo nodeinfo;
+ virNodeInfoPtr nodeinfo;
virVcpuInfoPtr info;
//Check number of vcpus;
@@ -340,9 +339,9 @@ JNIEXPORT jintArray JNICALL Java_org_lib
return NULL;
//Get maplen
- if(VirNodeGetInfo( virDomainGetConnect( (virDomainPtr)VDP), nodeinfo )<0)
+ if(virNodeGetInfo( virDomainGetConnect( (virDomainPtr)VDP), nodeinfo )<0)
return NULL;
- maplen=VIR_CPU_MAPLEN( VIR_NODEINFO_MAXCPUS( nodeinfo ) );
+ maplen=VIR_CPU_MAPLEN( VIR_NODEINFO_MAXCPUS( *nodeinfo ) );
info=(virVcpuInfoPtr)calloc(maxinfo, sizeof(virVcpuInfo));
cpumaps=malloc(sizeof(int)*maxinfo*maplen);
@@ -368,6 +367,7 @@ JNIEXPORT jint JNICALL Java_org_libvirt_
unsigned char *cpumap;
jint *i_cpumap;
int c;
+ int retval;
//Get maplen
maplen=(*env)->GetArrayLength(env, j_cpumap);
@@ -382,10 +382,11 @@ JNIEXPORT jint JNICALL Java_org_libvirt_
cpumap[c]=i_cpumap[c];
//Call libvirt
- virDomainPinVcpu((virDomainPtr)VDP, vcpu, cpumap, maplen);
+ retval = virDomainPinVcpu((virDomainPtr)VDP, vcpu, cpumap, maplen);
free(cpumap);
free(i_cpumap);
+ return retval;
}
JNIEXPORT jint JNICALL Java_org_libvirt_VirDomain__1setVcpus
Index: src/jni/org_libvirt_VirNetwork.c
===================================================================
RCS file: /data/cvs/libvirt-java/src/jni/org_libvirt_VirNetwork.c,v
retrieving revision 1.1
diff -u -p -r1.1 org_libvirt_VirNetwork.c
--- src/jni/org_libvirt_VirNetwork.c 24 Jun 2008 16:32:24 -0000 1.1
+++ src/jni/org_libvirt_VirNetwork.c 29 Jun 2008 17:22:36 -0000
@@ -1,11 +1,12 @@
#include "org_libvirt_VirNetwork.h"
#include <libvirt/libvirt.h>
+#include <stdlib.h>
JNIEXPORT jstring JNICALL Java_org_libvirt_VirNetwork__1getXMLDesc
(JNIEnv *env, jobject obj, jlong VNP, jint flags){
jstring j_xmlDesc;
char* xmlDesc;
- if(xmlDesc = virNetworkGetXMLDesc((virNetworkPtr)VNP, flags)){
+ if((xmlDesc = virNetworkGetXMLDesc((virNetworkPtr)VNP, flags))){
j_xmlDesc = (*env)->NewStringUTF(env, xmlDesc);
free(xmlDesc);
}
@@ -36,15 +37,15 @@ JNIEXPORT jboolean JNICALL Java_org_libv
JNIEXPORT jint JNICALL Java_org_libvirt_VirNetwork__1setAutostart
(JNIEnv *env, jobject obj, jlong VNP, jboolean autostart){
- virNetworkSetAutostart((virNetworkPtr)VNP, autostart);
+ return virNetworkSetAutostart((virNetworkPtr)VNP, autostart);
}
JNIEXPORT jstring JNICALL Java_org_libvirt_VirNetwork__1getBridgeName
(JNIEnv *env, jobject obj, jlong VNP){
jstring j_bridgeName;
- char *bridgeName;
+ char *bridgeName=NULL;
- if(bridgeName = virNetworkGetBridgeName((virNetworkPtr)VNP)){
+ if((bridgeName = virNetworkGetBridgeName((virNetworkPtr)VNP))){
j_bridgeName = (*env)->NewStringUTF(env, bridgeName);
free(bridgeName);
}
Index: src/org/libvirt/VirConnect.java
===================================================================
RCS file: /data/cvs/libvirt-java/src/org/libvirt/VirConnect.java,v
retrieving revision 1.1
diff -u -p -r1.1 VirConnect.java
--- src/org/libvirt/VirConnect.java 24 Jun 2008 16:32:24 -0000 1.1
+++ src/org/libvirt/VirConnect.java 29 Jun 2008 17:22:36 -0000
@@ -49,16 +49,30 @@ public class VirConnect {
}
/**
+ * Constructs a VirConnect object from the supplied URI,
+ * using the supplied authentication callback
+ *
+ * @param uri The connection URI
+ * @param auth a VirConnectAuth object
+ * @param flags
+ * @throws LibvirtException
+ * @see <a
href="http://libvirt.org/uri.html">The URI
documentation</a>
+ */
+ public VirConnect(String uri, VirConnectAuth auth, int flags) throws LibvirtException
{
+ VCP = _openAuth(uri, auth, flags);
+ }
+
+ /**
* Constructs a read-write VirConnect object from the supplied URI.
*
- * @param uri
+ * @param uri The connection URI
* @throws LibvirtException
* @see <a
href="http://libvirt.org/uri.html">The URI
documentation</a>
*/
public VirConnect(String uri) throws LibvirtException {
VCP = _open(uri);
}
-
+
public void finalize() throws LibvirtException {
close();
}
@@ -307,6 +321,9 @@ public class VirConnect {
// openReadOnly
private native long _openReadOnly(String uri) throws LibvirtException;
+ // openAuth
+ private native long _openAuth(String uri, VirConnectAuth auth, int flags) throws
LibvirtException;
+
// virNetwork stuff
/**
Index: src/org/libvirt/VirDomain.java
===================================================================
RCS file: /data/cvs/libvirt-java/src/org/libvirt/VirDomain.java,v
retrieving revision 1.1
diff -u -p -r1.1 VirDomain.java
--- src/org/libvirt/VirDomain.java 24 Jun 2008 16:32:24 -0000 1.1
+++ src/org/libvirt/VirDomain.java 29 Jun 2008 17:22:36 -0000
@@ -7,9 +7,23 @@ public class VirDomain {
}
static final class MigrateFlags{
+ /**
+ * live migration
+ */
static final int VIR_MIGRATE_LIVE = 1;
}
+ static final class XMLFlags{
+ /**
+ * dump security sensitive information too
+ */
+ static final int VIR_DOMAIN_XML_SECURE = 1;
+ /**
+ * dump inactive domain information
+ */
+ static final int VIR_DOMAIN_XML_INACTIVE = 2;
+ }
+
/**
* the native virDomainPtr.
*/
Index: src/org/libvirt/VirError.java
===================================================================
RCS file: /data/cvs/libvirt-java/src/org/libvirt/VirError.java,v
retrieving revision 1.1
diff -u -p -r1.1 VirError.java
--- src/org/libvirt/VirError.java 24 Jun 2008 16:32:24 -0000 1.1
+++ src/org/libvirt/VirError.java 29 Jun 2008 17:22:37 -0000
@@ -59,7 +59,23 @@ public class VirError {
/**
* Error from OpenVZ driver
*/
- VIR_FROM_OPENVZ
+ VIR_FROM_OPENVZ,
+ /**
+ * Error at Xen XM layer
+ */
+ VIR_FROM_XENXM,
+ /**
+ * Error in the Linux Stats code
+ */
+ VIR_FROM_STATS_LINUX,
+ /**
+ * Error from Linux Container driver
+ */
+ VIR_FROM_LXC,
+ /**
+ * Error from storage driver
+ */
+ VIR_FROM_STORAGE
}
public static enum VirErrorLevel {
@@ -251,7 +267,31 @@ public class VirError {
/**
* invalid MAC adress
*/
- VIR_ERR_INVALID_MAC
+ VIR_ERR_INVALID_MAC,
+ /**
+ * authentication failed
+ */
+ VIR_ERR_AUTH_FAILED,
+ /**
+ * invalid storage pool object
+ */
+ VIR_ERR_INVALID_STORAGE_POOL,
+ /**
+ * invalid storage vol object
+ */
+ VIR_ERR_INVALID_STORAGE_VOL,
+ /**
+ * failed to start storage
+ */
+ VIR_WAR_NO_STORAGE,
+ /**
+ * storage pool not found
+ */
+ VIR_ERR_NO_STORAGE_POOL,
+ /**
+ * storage pool not found
+ */
+ VIR_ERR_NO_STORAGE_VOL
}
VirErrorNumber code;
@@ -328,7 +368,7 @@ public class VirError {
}
/**
- * Does this error has a valid Connection object atteched?
+ * Does this error has a valid Connection object attached?
* @return
*/
public boolean hasConn(){
@@ -416,7 +456,6 @@ public class VirError {
output.append("int1:" + int1 + "\n");
output.append("int2:" + int2 + "\n");
return output.toString();
-
}
}
Index: src/org/libvirt/VirSchedParameter.java
===================================================================
RCS file: /data/cvs/libvirt-java/src/org/libvirt/VirSchedParameter.java,v
retrieving revision 1.1
diff -u -p -r1.1 VirSchedParameter.java
--- src/org/libvirt/VirSchedParameter.java 24 Jun 2008 16:32:24 -0000 1.1
+++ src/org/libvirt/VirSchedParameter.java 29 Jun 2008 17:22:37 -0000
@@ -20,7 +20,7 @@ public abstract class VirSchedParameter
*/
public abstract String getValueAsString();
/**
- * Utility function for displayinf the type
+ * Utility function for displaying the type
*
* @return the Type of the parameter as string
*/
#include <jni.h>
#include <libvirt/libvirt.h>
#include <string.h>
#include "VirConnectAuthCallbackBridge.h"
#include <assert.h>
int VirConnectAuthCallbackBridge(virConnectCredentialPtr cred, unsigned int ncred, void *
cbdata){
//cbdata contains the java object that contains tha callback, as well as the JNI
environment
JNIEnv *env = ((CallBackStructType*)cbdata)->env;
jobject j_auth = ((CallBackStructType*)cbdata)->auth;
jclass j_auth_cls = (*env)->GetObjectClass(env, j_auth);
jmethodID j_auth_cb_id=(*env)->GetMethodID(env, (*env)->GetObjectClass(env,
j_auth), "callback", "([Lorg/libvirt/VirConnectCredential;)I");
jclass j_cred_cls = (*env)->FindClass(env,
"org/libvirt/VirConnectCredential");
jmethodID j_cred_constructor = (*env)->GetMethodID(env, j_cred_cls,
"<init>",
"(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
jfieldID j_cred_result_id = (*env)->GetFieldID(env, j_cred_cls, "result",
"Ljava/lang/String;");
jobjectArray j_credArray = (*env)->NewObjectArray(env, ncred, j_cred_cls, NULL);
//copy the credentials array to the Java object.
int c;
jobject j_cred;
for(c=0; c<ncred; c++){
j_cred=(*env)->NewObject(env,
j_cred_cls,
j_cred_constructor,
cred[c].type,
(*env)->NewStringUTF(env, cred[c].prompt),
(*env)->NewStringUTF(env, cred[c].challenge),
(*env)->NewStringUTF(env, cred[c].defresult));
(*env)->SetObjectArrayElement(env, j_credArray, c, j_cred);
}
//Time to call the actual java callback function
int retval = (*env)->CallNonvirtualIntMethod(env,
j_auth,
j_auth_cls,
j_auth_cb_id,
j_credArray);
if(retval){
//The java callback function has failed, so we fail as well.
return -1;
}
//If we are still here, the java callback returned sucessfully, so copy the results
back.
jstring j_cred_result;
const char* result;
for(c=0; c<ncred; c++){
j_cred = (*env)->GetObjectArrayElement(env, j_credArray, c);
j_cred_result = (*env)->GetObjectField(env, j_cred, j_cred_result_id);
//If this assert triggers, then the user-supplied VirConnectAuth.callback function is
broken
assert(j_cred_result);
result = (*env)->GetStringUTFChars(env,
j_cred_result,
NULL);
cred[c].result = strdup(result);
cred[c].resultlen = strlen(result);
(*env)->ReleaseStringUTFChars(env, j_cred_result, result);
}
//All done, back to libvirt
return 0;
}
#include <jni.h>
#include <libvirt/libvirt.h>
typedef struct {
JNIEnv *env;
jobject auth;
} CallBackStructType;
int VirConnectAuthCallbackBridge(virConnectCredentialPtr cred, unsigned int ncred, void *
cbdata);
package org.libvirt;
/**
* We diverge from the C implementation
* There is no explicit cbdata field, you should just add any extra data to the child
class's instance.
*
* @author stoty
*
*/
public abstract class VirConnectAuth {
/**
* List of supported VirConnectCredential.VirConnectCredentialType values
*/
public VirConnectCredential.VirConnectCredentialType credType[];
/**
* The callback function that fills the credentials in
* @param cred the array of credentials passed by libvirt
* @return 0 if the defresult field contains a vailde response, -1 otherwise
*/
public abstract int callback(VirConnectCredential[] cred);
}
package org.libvirt;
import java.io.BufferedReader;
import java.io.InputStreamReader;
/**
* @author stoty
* Implements virConnectAuthPtrDefault functionality from libvirt.c without the external
method support
* It's not officially a part of the libvirt API, but provided here for completeness,
testing, and as an example
*/
public final class VirConnectAuthDefault extends VirConnectAuth {
{
credType= new VirConnectCredential.VirConnectCredentialType[] {
VirConnectCredential.VirConnectCredentialType.VIR_CRED_AUTHNAME,
VirConnectCredential.VirConnectCredentialType.VIR_CRED_ECHOPROMPT,
VirConnectCredential.VirConnectCredentialType.VIR_CRED_REALM,
VirConnectCredential.VirConnectCredentialType.VIR_CRED_PASSPHRASE,
VirConnectCredential.VirConnectCredentialType.VIR_CRED_NOECHOPROMPT
};
}
@Override
public int callback(VirConnectCredential[] cred) {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
try{
for(VirConnectCredential c: cred){
String response="";
switch(c.type){
case VIR_CRED_USERNAME:
case VIR_CRED_AUTHNAME:
case VIR_CRED_ECHOPROMPT:
case VIR_CRED_REALM:
System.out.println(c.prompt);
response= in.readLine();
break;
case VIR_CRED_PASSPHRASE:
case VIR_CRED_NOECHOPROMPT:
System.out.println(c.prompt);
System.out.println("WARNING: THE ENTERED PASSWORD WILL NOT BE MASKED!");
response= in.readLine();
break;
}
if(response.equals("") && !c.defresult.equals("")){
c.result=c.defresult;
} else {
c.result=response;
}
if(c.result.equals("")){
return -1;
}
}
} catch (Exception e) {
return -1;
}
return 0;
}
}
package org.libvirt;
/**
* @author stoty
*
*/
public class VirConnectCredential {
public static enum VirConnectCredentialType {
//This is off by one, but we don't care, because we can't convert java Enum to C
enum in a sane way anyway
/**
* Identity to act as
*/
VIR_CRED_USERNAME,
/**
* Identify to authorize as
*/
VIR_CRED_AUTHNAME,
/**
* RFC 1766 languages, comma separated
*/
VIR_CRED_LANGUAGE,
/**
* client supplies a nonce
*/
VIR_CRED_CNONCE,
/**
* Passphrase secret
*/
VIR_CRED_PASSPHRASE,
/**
* Challenge response
*/
VIR_CRED_ECHOPROMPT,
/**
* Challenge response
*/
VIR_CRED_NOECHOPROMPT,
/**
* Authentication realm
*/
VIR_CRED_REALM,
/**
* Externally managed credential More may be added - expect the unexpected
*/
VIR_CRED_EXTERNAL;
/**
* Maps the java VirConnectCredentialType Enum to libvirt's integer constant
*
* @return The integer equivalent
*/
private int mapToInt(){
switch(this){
case VIR_CRED_USERNAME: return 1;
case VIR_CRED_AUTHNAME: return 2;
case VIR_CRED_LANGUAGE: return 3;
case VIR_CRED_CNONCE: return 4;
case VIR_CRED_PASSPHRASE: return 5;
case VIR_CRED_ECHOPROMPT: return 6;
case VIR_CRED_NOECHOPROMPT: return 7;
case VIR_CRED_REALM: return 8;
case VIR_CRED_EXTERNAL: return 9;
}
//We may never reach this point
assert(false);
return 0;
}
}
/**
* One of virConnectCredentialType constants
*/
public VirConnectCredentialType type;
/**
* Prompt to show to user
*/
public String prompt;
/**
* Additional challenge to show
*/
public String challenge;
/**
* Optional default result
*/
public String defresult;
/**
* Result to be filled with user response (or defresult)
*/
public String result;
/**
* Convenience constructor to be called from the JNI side
*
* @param type
* @param prompt
* @param challenge
* @param defresult
*/
VirConnectCredential(int type, String prompt, String challenge, String defresult){
switch(type){
case 1: this.type=VirConnectCredentialType.VIR_CRED_USERNAME; break;
case 2: this.type=VirConnectCredentialType.VIR_CRED_AUTHNAME; break;
case 3: this.type=VirConnectCredentialType.VIR_CRED_LANGUAGE; break;
case 4: this.type=VirConnectCredentialType.VIR_CRED_CNONCE; break;
case 5: this.type=VirConnectCredentialType.VIR_CRED_PASSPHRASE; break;
case 6: this.type=VirConnectCredentialType.VIR_CRED_ECHOPROMPT; break;
case 7: this.type=VirConnectCredentialType.VIR_CRED_NOECHOPROMPT; break;
case 8: this.type=VirConnectCredentialType.VIR_CRED_REALM; break;
case 9: this.type=VirConnectCredentialType.VIR_CRED_EXTERNAL; break;
default: assert(false);
}
this.prompt = prompt;
this.challenge = challenge;
this.defresult = defresult;
}
}