Fix auth parameter passed to libvirt openAuth() method

The 'auth' parameter for the libvirt 'openAuth' method
should be a list of 3 values, a list of credential types,
a function callback and an opaque data value. For unknown
reasons the libvirt driver is passing the string 'root'
instead of the function callback.

This causes any attempt to invoke the callback to fail
with a python exception, which gets swallowed since it
is called asynchronously from libvirt. The upshot of
this is that it is not possible to connect Nova to a
libvirt instance that requires authentication.

Although Nova has no way to provide custom credentials
to libvirt, it is possible to rely on libvirt's client
auth file to provide credentials. ALl that is required
is for the auth callback to return '0' if no credentials
were asked for.

Fixing the Nova params for openAuth() thus enable use of
SASL or Kerberos auth+encryption with Nova eg for SASL

 # augtool -s set /files/etc/libvirt/libvirtd.conf/auth_unix_rw sasl
 Saved 1 file(s)

 # saslpasswd -a libvirt nova
 Password: XYZ
 Again (for verification): XYZ

 # su - nova -s /bin/sh
 $ mkdir -p $HOME/.config/libvirt
 $ cat > $HOME/.config/libvirt <<EOF
 [credentials-nova]
 authname=nova
 password=XYZ

 [auth-libvirt-localhost]
 credentials=nova
 EOF

Finally just restart libvirtd and nova compute services

Change-Id: I011b406e54728a01eb90a7851ae2b1f536674197
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrange 2012-09-10 14:42:33 +01:00
parent 7b3508942d
commit 5f9ae51f2f
3 changed files with 38 additions and 9 deletions

View File

@ -76,8 +76,15 @@ VIR_CPU_COMPARE_INCOMPATIBLE = 0
VIR_CPU_COMPARE_IDENTICAL = 1
VIR_CPU_COMPARE_SUPERSET = 2
VIR_CRED_USERNAME = 1
VIR_CRED_AUTHNAME = 2
VIR_CRED_LANGUAGE = 3
VIR_CRED_CNONCE = 4
VIR_CRED_PASSPHRASE = 5
VIR_CRED_ECHOPROMPT = 6
VIR_CRED_NOECHOPROMPT = 7
VIR_CRED_REALM = 8
VIR_CRED_EXTERNAL = 9
VIR_MIGRATE_PEER2PEER = 2
VIR_MIGRATE_UNDEFINE_SOURCE = 16
@ -828,11 +835,16 @@ def openAuth(uri, auth, flags):
raise Exception(_("Please extend mock libvirt module to support "
"flags"))
if auth != [[VIR_CRED_AUTHNAME, VIR_CRED_NOECHOPROMPT],
'root',
None]:
raise Exception(_("Please extend fake libvirt module to support "
"this auth method"))
if type(auth) != list:
raise Exception(_("Expected a list for 'auth' parameter"))
if type(auth[0]) != list:
raise Exception(
_("Expected a function in 'auth[0]' parameter"))
if not callable(auth[1]):
raise Exception(
_("Expected a function in 'auth[1]' parameter"))
return Connection(uri, readonly=False)

View File

@ -69,11 +69,13 @@ class FakeLibvirtTests(test.TestCase):
return lambda uri: libvirt.openReadOnly(uri)
def get_openAuth_curry_func(self):
def fake_cb(credlist):
return 0
return lambda uri: libvirt.openAuth(uri,
[[libvirt.VIR_CRED_AUTHNAME,
libvirt.VIR_CRED_NOECHOPROMPT],
'root',
None], 0)
fake_cb,
None], 0)
def _test_connect_method_accepts_None_uri_by_default(self, conn_method):
conn = conn_method(None)

View File

@ -376,8 +376,23 @@ class LibvirtDriver(driver.ComputeDriver):
@staticmethod
def _connect(uri, read_only):
auth = [[libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_NOECHOPROMPT],
'root',
def _connect_auth_cb(creds, opaque):
if len(creds) == 0:
return 0
LOG.warning(
_("Can not handle authentication request for %d credentials")
% len(creds))
raise exception.NovaException(
_("Can not handle authentication request for %d credentials")
% len(creds))
auth = [[libvirt.VIR_CRED_AUTHNAME,
libvirt.VIR_CRED_ECHOPROMPT,
libvirt.VIR_CRED_REALM,
libvirt.VIR_CRED_PASSPHRASE,
libvirt.VIR_CRED_NOECHOPROMPT,
libvirt.VIR_CRED_EXTERNAL],
_connect_auth_cb,
None]
if read_only: