mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
Added configuration for authentication through Xen-API -- it can now be set
to use PAM, or to be turned off entirely, on a listener by listener basis. Listen on a different unix domain socket for the Xen-API server, so that it can co-exist with the others. Signed-off-by: Ewan Mellor <ewan@xensource.com>
This commit is contained in:
1 parent
46873848fb
commit
2e873d3d17
6 files changed
+83
-42
No files matched your search
@@ -27,6 +27,9 @@ from xen.xend.XendLogging import log
|
||||
from xen.xend.XendAPIConstants import *
|
||||
from xen.util.xmlrpclib2 import stringify
|
||||
|
||||
AUTH_NONE = 'none'
|
||||
AUTH_PAM = 'pam'
|
||||
|
||||
# ------------------------------------------
|
||||
# Utility Methods for Xen API Implementation
|
||||
# ------------------------------------------
|
||||
@@ -275,12 +278,13 @@ class XendAPI:
|
||||
is set to the XMLRPC function name which the method implements.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, auth):
|
||||
"""Initialised Xen API wrapper by making sure all functions
|
||||
have the correct validation decorators such as L{valid_host}
|
||||
and L{session_required}.
|
||||
"""
|
||||
|
||||
self.auth = auth
|
||||
|
||||
classes = {
|
||||
'session': (session_required,),
|
||||
'host': (valid_host, session_required),
|
||||
@@ -388,7 +392,9 @@ class XendAPI:
|
||||
|
||||
def session_login_with_password(self, username, password):
|
||||
try:
|
||||
session = auth_manager().login_with_password(username, password)
|
||||
session = (self.auth == AUTH_NONE and
|
||||
auth_manager().login_unconditionally(username) or
|
||||
auth_manager().login_with_password(username, password))
|
||||
return xen_api_success(session)
|
||||
except XendError, e:
|
||||
return xen_api_error(XEND_ERROR_AUTHENTICATION_FAILED)
|
||||
|
||||
@@ -37,6 +37,16 @@ class XendAuthSessions:
|
||||
def init(self):
|
||||
pass
|
||||
|
||||
def login_unconditionally(self, username):
|
||||
"""Returns a session UUID if valid.
|
||||
|
||||
@rtype: string
|
||||
@return: Session UUID
|
||||
"""
|
||||
new_session = uuid.createString()
|
||||
self.sessions[new_session] = (username, time.time())
|
||||
return new_session
|
||||
|
||||
def login_with_password(self, username, password):
|
||||
"""Returns a session UUID if valid, otherwise raises an error.
|
||||
|
||||
@@ -45,9 +55,7 @@ class XendAuthSessions:
|
||||
@return: Session UUID
|
||||
"""
|
||||
if self.is_authorized(username, password):
|
||||
new_session = uuid.createString()
|
||||
self.sessions[new_session] = (username, time.time())
|
||||
return new_session
|
||||
return login_unconditionally(username)
|
||||
|
||||
raise XendError("Login failed")
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import os
|
||||
import sys
|
||||
|
||||
XML_RPC_SOCKET = "/var/run/xend/xmlrpc.sock"
|
||||
XEN_API_SOCKET = "/var/run/xend/xen-api.sock"
|
||||
|
||||
ERROR_INTERNAL = 1
|
||||
ERROR_GENERIC = 2
|
||||
|
||||
@@ -48,9 +48,10 @@ from threading import Thread
|
||||
|
||||
from xen.web.httpserver import HttpServer, UnixHttpServer
|
||||
|
||||
from xen.xend import XendRoot
|
||||
from xen.xend import XendRoot, XendAPI
|
||||
from xen.xend import Vifctl
|
||||
from xen.xend.XendLogging import log
|
||||
from xen.xend.XendClient import XEN_API_SOCKET
|
||||
from xen.web.SrvDir import SrvDir
|
||||
|
||||
from SrvRoot import SrvRoot
|
||||
@@ -153,28 +154,38 @@ def create():
|
||||
if api_cfg:
|
||||
try:
|
||||
addrs = [(str(x[0]).split(':'),
|
||||
len(x) > 1 and x[1] and map(re.compile, x[1].split(" "))
|
||||
len(x) > 1 and x[1] or XendAPI.AUTH_NONE,
|
||||
len(x) > 2 and x[2] and map(re.compile, x[2].split(" "))
|
||||
or None)
|
||||
for x in api_cfg]
|
||||
for addrport, allowed in addrs:
|
||||
for addrport, auth, allowed in addrs:
|
||||
if auth not in [XendAPI.AUTH_PAM, XendAPI.AUTH_NONE]:
|
||||
log.error('Xen-API server configuration %s is invalid, ' +
|
||||
'as %s is not a valid authentication type.',
|
||||
api_cfg, auth)
|
||||
break
|
||||
|
||||
if len(addrport) == 1:
|
||||
if addrport[0] == 'unix':
|
||||
servers.add(XMLRPCServer(allowed = allowed))
|
||||
servers.add(XMLRPCServer(auth,
|
||||
path = XEN_API_SOCKET,
|
||||
hosts_allowed = allowed))
|
||||
else:
|
||||
servers.add(XMLRPCServer(True, '', int(addrport[0]),
|
||||
allowed = allowed))
|
||||
servers.add(
|
||||
XMLRPCServer(auth, True, '', int(addrport[0]),
|
||||
hosts_allowed = allowed))
|
||||
else:
|
||||
addr, port = addrport
|
||||
servers.add(XMLRPCServer(True, addr, int(port),
|
||||
allowed = allowed))
|
||||
except ValueError:
|
||||
log.error('Xen-API server configuration %s is invalid' % api_cfg)
|
||||
except TypeError:
|
||||
log.error('Xen-API server configuration %s is invalid' % api_cfg)
|
||||
servers.add(XMLRPCServer(auth, True, addr, int(port),
|
||||
hosts_allowed = allowed))
|
||||
except ValueError, exn:
|
||||
log.error('Xen-API server configuration %s is invalid.', api_cfg)
|
||||
except TypeError, exn:
|
||||
log.error('Xen-API server configuration %s is invalid.', api_cfg)
|
||||
|
||||
if xroot.get_xend_tcp_xmlrpc_server():
|
||||
servers.add(XMLRPCServer(True))
|
||||
servers.add(XMLRPCServer(XendAPI.AUTH_PAM, True))
|
||||
|
||||
if xroot.get_xend_unix_xmlrpc_server():
|
||||
servers.add(XMLRPCServer())
|
||||
servers.add(XMLRPCServer(XendAPI.AUTH_PAM))
|
||||
return servers
|
||||
@@ -20,11 +20,10 @@ import types
|
||||
import xmlrpclib
|
||||
from xen.util.xmlrpclib2 import UnixXMLRPCServer, TCPXMLRPCServer
|
||||
|
||||
from xen.xend import XendDomain, XendDomainInfo, XendNode
|
||||
from xen.xend import XendAPI, XendDomain, XendDomainInfo, XendNode
|
||||
from xen.xend import XendLogging, XendDmesg
|
||||
from xen.xend.XendClient import XML_RPC_SOCKET
|
||||
from xen.xend.XendLogging import log
|
||||
from xen.xend.XendAPI import XendAPI
|
||||
from xen.xend.XendError import XendInvalidDomain
|
||||
|
||||
# vcpu_avail is a long and is not needed by the clients. It's far easier
|
||||
@@ -84,7 +83,7 @@ methods = ['device_create', 'device_configure',
|
||||
exclude = ['domain_create', 'domain_restore']
|
||||
|
||||
class XMLRPCServer:
|
||||
def __init__(self, use_tcp=False, host = "localhost", port = 8006,
|
||||
def __init__(self, auth, use_tcp=False, host = "localhost", port = 8006,
|
||||
path = XML_RPC_SOCKET, hosts_allowed = None):
|
||||
self.use_tcp = use_tcp
|
||||
self.port = port
|
||||
@@ -94,23 +93,29 @@ class XMLRPCServer:
|
||||
|
||||
self.ready = False
|
||||
self.running = True
|
||||
self.xenapi = XendAPI()
|
||||
self.auth = auth
|
||||
self.xenapi = XendAPI.XendAPI(auth)
|
||||
|
||||
def run(self):
|
||||
authmsg = (self.auth == XendAPI.AUTH_NONE and
|
||||
"; authentication has been disabled for this server." or
|
||||
".")
|
||||
|
||||
if self.use_tcp:
|
||||
log.info("Opening TCP XML-RPC server on %s%d.",
|
||||
log.info("Opening TCP XML-RPC server on %s%d%s",
|
||||
self.host and '%s:' % self.host or
|
||||
'all interfaces, port ',
|
||||
self.port)
|
||||
self.port, authmsg)
|
||||
self.server = TCPXMLRPCServer((self.host, self.port),
|
||||
self.hosts_allowed,
|
||||
logRequests = False)
|
||||
else:
|
||||
log.info("Opening Unix domain socket XML-RPC server on %s.",
|
||||
self.path)
|
||||
log.info("Opening Unix domain socket XML-RPC server on %s%s",
|
||||
self.path, authmsg)
|
||||
self.server = UnixXMLRPCServer(self.path, self.hosts_allowed,
|
||||
logRequests = False)
|
||||
|
||||
|
||||
# Register Xen API Functions
|
||||
# -------------------------------------------------------------------
|
||||
# exportable functions are ones that do not begin with '_'
|
||||
|
||||