ia64/xen-unstable

changeset 12606:ee70bf177981

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>
author Ewan Mellor <ewan@xensource.com>
date Tue Nov 28 11:31:46 2006 +0000 (2006-11-28)
parents 018af1c94a5e
children 7a5246955bef
files tools/examples/xend-config.sxp tools/python/xen/xend/XendAPI.py tools/python/xen/xend/XendAuthSessions.py tools/python/xen/xend/XendClient.py tools/python/xen/xend/server/SrvServer.py tools/python/xen/xend/server/XMLRPCServer.py
line diff
     1.1 --- a/tools/examples/xend-config.sxp	Tue Nov 28 10:24:52 2006 +0000
     1.2 +++ b/tools/examples/xend-config.sxp	Tue Nov 28 11:31:46 2006 +0000
     1.3 @@ -14,32 +14,42 @@
     1.4  #(logfile /var/log/xen/xend.log)
     1.5  #(loglevel DEBUG)
     1.6  
     1.7 -# The Xen-API server configuration.  (Please note that this server is available
     1.8 -# as an UNSUPPORTED PREVIEW in Xen 3.0.4, and should not be relied upon).
     1.9 +
    1.10 +# The Xen-API server configuration.  (Please note that this server is
    1.11 +# available as an UNSUPPORTED PREVIEW in Xen 3.0.4, and should not be relied
    1.12 +# upon).
    1.13  #
    1.14  # This value configures the ports, interfaces, and access controls for the
    1.15  # Xen-API server.  Each entry in the list starts with either unix, a port
    1.16  # number, or an address:port pair.  If this is "unix", then a UDP socket is
    1.17  # opened, and this entry applies to that.  If it is a port, then Xend will
    1.18 -# listen on all interfaces on that TCP port, and if it is an address:port pair,
    1.19 -# then Xend will listen on the specified port, using the interface with the
    1.20 -# specified address.
    1.21 +# listen on all interfaces on that TCP port, and if it is an address:port
    1.22 +# pair, then Xend will listen on the specified port, using the interface with
    1.23 +# the specified address.
    1.24  #
    1.25 -# The subsequent string gives the access control for the listener in question. 
    1.26 -# If this is missing or empty, then all connections are accepted.
    1.27 -# Otherwise, this should be a space-separated sequence of regular expressions;
    1.28 -# any host with a fully-qualified domain name or an IP address that matches one
    1.29 -# of these regular expressions will be accepted.
    1.30 +# The subsequent string configures the user-based access control for the
    1.31 +# listener in question.  This can be one of "none" or "pam", indicating either
    1.32 +# that users should be allowed access unconditionally, or that the local
    1.33 +# Pluggable Authentication Modules configuration should be used.  If this
    1.34 +# string is missing or empty, then "pam" is used.
    1.35  #
    1.36 -# Example:
    1.37 +# The final string gives the host-based access control for that listener. If
    1.38 +# this is missing or empty, then all connections are accepted.  Otherwise,
    1.39 +# this should be a space-separated sequence of regular expressions; any host
    1.40 +# with a fully-qualified domain name or an IP address that matches one of
    1.41 +# these regular expressions will be accepted.
    1.42  #
    1.43 -#  Listen on TCP port 9363 on all interfaces, accepting connections only from
    1.44 -#  machines in example.com or localhost.
    1.45 -#  (xen-api-server ((9363 '^localhost$ example\\.com$')))
    1.46 +# Example: listen on TCP port 9363 on all interfaces, accepting connections
    1.47 +# only from machines in example.com or localhost, and allow access through
    1.48 +# the unix domain socket unconditionally:
    1.49 +#
    1.50 +#   (xen-api-server ((9363 pam '^localhost$ example\\.com$')
    1.51 +#                    (unix none)))
    1.52  #
    1.53  # Default:
    1.54  #   (xen-api-server ((unix)))
    1.55  
    1.56 +
    1.57  #(xend-http-server no)
    1.58  #(xend-unix-server no)
    1.59  #(xend-tcp-xmlrpc-server no)
     2.1 --- a/tools/python/xen/xend/XendAPI.py	Tue Nov 28 10:24:52 2006 +0000
     2.2 +++ b/tools/python/xen/xend/XendAPI.py	Tue Nov 28 11:31:46 2006 +0000
     2.3 @@ -27,6 +27,9 @@ from xen.xend.XendLogging import log
     2.4  from xen.xend.XendAPIConstants import *
     2.5  from xen.util.xmlrpclib2 import stringify
     2.6  
     2.7 +AUTH_NONE = 'none'
     2.8 +AUTH_PAM = 'pam'
     2.9 +
    2.10  # ------------------------------------------
    2.11  # Utility Methods for Xen API Implementation
    2.12  # ------------------------------------------
    2.13 @@ -275,12 +278,13 @@ class XendAPI:
    2.14      is set to the XMLRPC function name which the method implements.
    2.15      """
    2.16  
    2.17 -    def __init__(self):
    2.18 +    def __init__(self, auth):
    2.19          """Initialised Xen API wrapper by making sure all functions
    2.20          have the correct validation decorators such as L{valid_host}
    2.21          and L{session_required}.
    2.22          """
    2.23 -        
    2.24 +        self.auth = auth
    2.25 +
    2.26          classes = {
    2.27              'session': (session_required,),
    2.28              'host': (valid_host, session_required),
    2.29 @@ -388,7 +392,9 @@ class XendAPI:
    2.30  
    2.31      def session_login_with_password(self, username, password):
    2.32          try:
    2.33 -            session = auth_manager().login_with_password(username, password)
    2.34 +            session = (self.auth == AUTH_NONE and
    2.35 +                       auth_manager().login_unconditionally(username) or
    2.36 +                       auth_manager().login_with_password(username, password))
    2.37              return xen_api_success(session)
    2.38          except XendError, e:
    2.39              return xen_api_error(XEND_ERROR_AUTHENTICATION_FAILED)
     3.1 --- a/tools/python/xen/xend/XendAuthSessions.py	Tue Nov 28 10:24:52 2006 +0000
     3.2 +++ b/tools/python/xen/xend/XendAuthSessions.py	Tue Nov 28 11:31:46 2006 +0000
     3.3 @@ -37,6 +37,16 @@ class XendAuthSessions:
     3.4      def init(self):
     3.5          pass
     3.6  
     3.7 +    def login_unconditionally(self, username):
     3.8 +        """Returns a session UUID if valid.
     3.9 +
    3.10 +        @rtype: string
    3.11 +        @return: Session UUID
    3.12 +        """
    3.13 +        new_session = uuid.createString()
    3.14 +        self.sessions[new_session] = (username, time.time())
    3.15 +        return new_session
    3.16 +
    3.17      def login_with_password(self, username, password):
    3.18          """Returns a session UUID if valid, otherwise raises an error.
    3.19  
    3.20 @@ -45,9 +55,7 @@ class XendAuthSessions:
    3.21          @return: Session UUID
    3.22          """
    3.23          if self.is_authorized(username, password):
    3.24 -            new_session = uuid.createString()
    3.25 -            self.sessions[new_session] = (username, time.time())
    3.26 -            return new_session
    3.27 +            return login_unconditionally(username)
    3.28  
    3.29          raise XendError("Login failed")
    3.30  
     4.1 --- a/tools/python/xen/xend/XendClient.py	Tue Nov 28 10:24:52 2006 +0000
     4.2 +++ b/tools/python/xen/xend/XendClient.py	Tue Nov 28 11:31:46 2006 +0000
     4.3 @@ -22,6 +22,7 @@ import os
     4.4  import sys
     4.5  
     4.6  XML_RPC_SOCKET = "/var/run/xend/xmlrpc.sock"
     4.7 +XEN_API_SOCKET = "/var/run/xend/xen-api.sock"
     4.8  
     4.9  ERROR_INTERNAL = 1
    4.10  ERROR_GENERIC = 2
     5.1 --- a/tools/python/xen/xend/server/SrvServer.py	Tue Nov 28 10:24:52 2006 +0000
     5.2 +++ b/tools/python/xen/xend/server/SrvServer.py	Tue Nov 28 11:31:46 2006 +0000
     5.3 @@ -48,9 +48,10 @@ from threading import Thread
     5.4  
     5.5  from xen.web.httpserver import HttpServer, UnixHttpServer
     5.6  
     5.7 -from xen.xend import XendRoot
     5.8 +from xen.xend import XendRoot, XendAPI
     5.9  from xen.xend import Vifctl
    5.10  from xen.xend.XendLogging import log
    5.11 +from xen.xend.XendClient import XEN_API_SOCKET
    5.12  from xen.web.SrvDir import SrvDir
    5.13  
    5.14  from SrvRoot import SrvRoot
    5.15 @@ -153,28 +154,38 @@ def create():
    5.16      if api_cfg:
    5.17          try:
    5.18              addrs = [(str(x[0]).split(':'),
    5.19 -                      len(x) > 1 and x[1] and map(re.compile, x[1].split(" "))
    5.20 +                      len(x) > 1 and x[1] or XendAPI.AUTH_NONE,
    5.21 +                      len(x) > 2 and x[2] and map(re.compile, x[2].split(" "))
    5.22                        or None)
    5.23                       for x in api_cfg]
    5.24 -            for addrport, allowed in addrs:
    5.25 +            for addrport, auth, allowed in addrs:
    5.26 +                if auth not in [XendAPI.AUTH_PAM, XendAPI.AUTH_NONE]:
    5.27 +                    log.error('Xen-API server configuration %s is invalid, ' +
    5.28 +                              'as %s is not a valid authentication type.',
    5.29 +                              api_cfg, auth)
    5.30 +                    break
    5.31 +
    5.32                  if len(addrport) == 1:
    5.33                      if addrport[0] == 'unix':
    5.34 -                        servers.add(XMLRPCServer(allowed = allowed))
    5.35 +                        servers.add(XMLRPCServer(auth,
    5.36 +                                                 path = XEN_API_SOCKET,
    5.37 +                                                 hosts_allowed = allowed))
    5.38                      else:
    5.39 -                        servers.add(XMLRPCServer(True, '', int(addrport[0]),
    5.40 -                                                 allowed = allowed))
    5.41 +                        servers.add(
    5.42 +                            XMLRPCServer(auth, True, '', int(addrport[0]),
    5.43 +                                         hosts_allowed = allowed))
    5.44                  else:
    5.45                      addr, port = addrport
    5.46 -                    servers.add(XMLRPCServer(True, addr, int(port),
    5.47 -                                             allowed = allowed))
    5.48 -        except ValueError:
    5.49 -            log.error('Xen-API server configuration %s is invalid' % api_cfg)
    5.50 -        except TypeError:
    5.51 -            log.error('Xen-API server configuration %s is invalid' % api_cfg)
    5.52 +                    servers.add(XMLRPCServer(auth, True, addr, int(port),
    5.53 +                                             hosts_allowed = allowed))
    5.54 +        except ValueError, exn:
    5.55 +            log.error('Xen-API server configuration %s is invalid.', api_cfg)
    5.56 +        except TypeError, exn:
    5.57 +            log.error('Xen-API server configuration %s is invalid.', api_cfg)
    5.58  
    5.59      if xroot.get_xend_tcp_xmlrpc_server():
    5.60 -        servers.add(XMLRPCServer(True))
    5.61 +        servers.add(XMLRPCServer(XendAPI.AUTH_PAM, True))
    5.62  
    5.63      if xroot.get_xend_unix_xmlrpc_server():
    5.64 -        servers.add(XMLRPCServer())
    5.65 +        servers.add(XMLRPCServer(XendAPI.AUTH_PAM))
    5.66      return servers
     6.1 --- a/tools/python/xen/xend/server/XMLRPCServer.py	Tue Nov 28 10:24:52 2006 +0000
     6.2 +++ b/tools/python/xen/xend/server/XMLRPCServer.py	Tue Nov 28 11:31:46 2006 +0000
     6.3 @@ -20,11 +20,10 @@ import types
     6.4  import xmlrpclib
     6.5  from xen.util.xmlrpclib2 import UnixXMLRPCServer, TCPXMLRPCServer
     6.6  
     6.7 -from xen.xend import XendDomain, XendDomainInfo, XendNode
     6.8 +from xen.xend import XendAPI, XendDomain, XendDomainInfo, XendNode
     6.9  from xen.xend import XendLogging, XendDmesg
    6.10  from xen.xend.XendClient import XML_RPC_SOCKET
    6.11  from xen.xend.XendLogging import log
    6.12 -from xen.xend.XendAPI import XendAPI
    6.13  from xen.xend.XendError import XendInvalidDomain
    6.14  
    6.15  # vcpu_avail is a long and is not needed by the clients.  It's far easier
    6.16 @@ -84,7 +83,7 @@ methods = ['device_create', 'device_conf
    6.17  exclude = ['domain_create', 'domain_restore']
    6.18  
    6.19  class XMLRPCServer:
    6.20 -    def __init__(self, use_tcp=False, host = "localhost", port = 8006,
    6.21 +    def __init__(self, auth, use_tcp=False, host = "localhost", port = 8006,
    6.22                   path = XML_RPC_SOCKET, hosts_allowed = None):
    6.23          self.use_tcp = use_tcp
    6.24          self.port = port
    6.25 @@ -94,23 +93,29 @@ class XMLRPCServer:
    6.26          
    6.27          self.ready = False        
    6.28          self.running = True
    6.29 -        self.xenapi = XendAPI()
    6.30 +        self.auth = auth
    6.31 +        self.xenapi = XendAPI.XendAPI(auth)
    6.32          
    6.33      def run(self):
    6.34 +        authmsg = (self.auth == XendAPI.AUTH_NONE and 
    6.35 +                   "; authentication has been disabled for this server." or
    6.36 +                   ".")
    6.37 +
    6.38          if self.use_tcp:
    6.39 -            log.info("Opening TCP XML-RPC server on %s%d.",
    6.40 +            log.info("Opening TCP XML-RPC server on %s%d%s",
    6.41                       self.host and '%s:' % self.host or
    6.42                       'all interfaces, port ',
    6.43 -                     self.port)
    6.44 +                     self.port, authmsg)
    6.45              self.server = TCPXMLRPCServer((self.host, self.port),
    6.46                                            self.hosts_allowed,
    6.47                                            logRequests = False)
    6.48          else:
    6.49 -            log.info("Opening Unix domain socket XML-RPC server on %s.",
    6.50 -                     self.path)
    6.51 +            log.info("Opening Unix domain socket XML-RPC server on %s%s",
    6.52 +                     self.path, authmsg)
    6.53              self.server = UnixXMLRPCServer(self.path, self.hosts_allowed,
    6.54                                             logRequests = False)
    6.55  
    6.56 +
    6.57          # Register Xen API Functions
    6.58          # -------------------------------------------------------------------
    6.59          # exportable functions are ones that do not begin with '_'