package org.libvirt;
import org.libvirt.jna.Libvirt;
import org.libvirt.jna.virConnectCredential;
import com.sun.jna.Pointer;
/**
* 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 ConnectAuth implements Libvirt.VirConnectAuthCallback {
public class Credential {
/**
* One of virConnectCredentialType constants
*/
public CredentialType 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
*/
Credential(int type, String prompt, String challenge, String defresult) {
switch (type) {
case 1:
this.type = CredentialType.VIR_CRED_USERNAME;
break;
case 2:
this.type = CredentialType.VIR_CRED_AUTHNAME;
break;
case 3:
this.type = CredentialType.VIR_CRED_LANGUAGE;
break;
case 4:
this.type = CredentialType.VIR_CRED_CNONCE;
break;
case 5:
this.type = CredentialType.VIR_CRED_PASSPHRASE;
break;
case 6:
this.type = CredentialType.VIR_CRED_ECHOPROMPT;
break;
case 7:
this.type = CredentialType.VIR_CRED_NOECHOPROMPT;
break;
case 8:
this.type = CredentialType.VIR_CRED_REALM;
break;
case 9:
this.type = CredentialType.VIR_CRED_EXTERNAL;
break;
default:
assert (false);
}
this.prompt = prompt;
this.challenge = challenge;
this.defresult = defresult;
}
}
/**
* @author stoty
*
*/
public static enum CredentialType {
/**
* Fake credential so that the ordinal value equls the c value.
*/
VIR_CRED_NONE,
/**
* 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 CredentialType Enum to libvirt's integer constant
*
* @return The integer equivalent
*/
@SuppressWarnings("all")
public 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;
}
}
/**
* List of supported ConnectCredential.CredentialType values
*/
public CredentialType credType[];
@Override
public int authCallback(virConnectCredential cred, int ncred, Pointer cbdata) {
virConnectCredential[] nativeCreds = (virConnectCredential[]) cred.toArray(ncred);
Credential[] creds = new Credential[ncred];
for (int x = 0; x < ncred; x++) {
virConnectCredential vCred = nativeCreds[x];
creds[x] = new Credential(vCred.type, vCred.prompt, vCred.challenge, vCred.defresult);
}
int returnValue = callback(creds);
for (int x = 0; x < ncred; x++) {
virConnectCredential vCred = nativeCreds[x];
String result = creds[x].result;
vCred.result = result;
vCred.resultlen = result.length();
vCred.write();
}
return returnValue;
}
/**
* 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(Credential[] cred);
}