ia64/xen-unstable

annotate tools/python/xen/xend/XendAuthSessions.py @ 12725:36fe7ca48e54

Tidy up the creation of directories that Xend needs. This avoids potential
races in this creation.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author Ewan Mellor <ewan@xensource.com>
date Fri Dec 01 11:32:32 2006 +0000 (2006-12-01)
parents 81c9213b3d39
children c3d84afbbb47
rev   line source
acnt2@12077 1 #============================================================================
acnt2@12077 2 # This library is free software; you can redistribute it and/or
acnt2@12077 3 # modify it under the terms of version 2.1 of the GNU Lesser General Public
acnt2@12077 4 # License as published by the Free Software Foundation.
acnt2@12077 5 #
acnt2@12077 6 # This library is distributed in the hope that it will be useful,
acnt2@12077 7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
acnt2@12077 8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
acnt2@12077 9 # Lesser General Public License for more details.
acnt2@12077 10 #
acnt2@12077 11 # You should have received a copy of the GNU Lesser General Public
acnt2@12077 12 # License along with this library; if not, write to the Free Software
acnt2@12077 13 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
acnt2@12077 14 #============================================================================
acnt2@12077 15 # Copyright (C) 2006 XenSource Ltd.
acnt2@12077 16 #============================================================================
acnt2@12077 17
acnt2@12077 18 import time
acnt2@12077 19
acnt2@12077 20 from xen.xend import uuid
acnt2@12077 21 from xen.xend.XendError import *
acnt2@12077 22 from xen.xend.XendLogging import log
acnt2@12077 23
atse@12140 24 try:
atse@12140 25 import PAM
atse@12140 26 except ImportError:
atse@12140 27 log.warn("python-pam is required for XenAPI support.")
atse@12140 28
acnt2@12077 29 class XendAuthSessions:
atse@12140 30 """Keeps track of Xen API Login Sessions using PAM.
acnt2@12077 31
atse@12140 32 Note: Login sessions are not valid across instances of Xend.
atse@12140 33 """
acnt2@12077 34 def __init__(self):
acnt2@12077 35 self.sessions = {}
acnt2@12077 36
acnt2@12077 37 def init(self):
acnt2@12077 38 pass
acnt2@12077 39
ewan@12606 40 def login_unconditionally(self, username):
ewan@12606 41 """Returns a session UUID if valid.
ewan@12606 42
ewan@12606 43 @rtype: string
ewan@12606 44 @return: Session UUID
ewan@12606 45 """
ewan@12606 46 new_session = uuid.createString()
ewan@12606 47 self.sessions[new_session] = (username, time.time())
ewan@12606 48 return new_session
ewan@12606 49
acnt2@12077 50 def login_with_password(self, username, password):
atse@12140 51 """Returns a session UUID if valid, otherwise raises an error.
atse@12140 52
atse@12140 53 @raises XendError: If login fails.
atse@12140 54 @rtype: string
atse@12140 55 @return: Session UUID
atse@12140 56 """
acnt2@12077 57 if self.is_authorized(username, password):
ewan@12644 58 return self.login_unconditionally(username)
acnt2@12077 59
acnt2@12077 60 raise XendError("Login failed")
acnt2@12077 61
acnt2@12077 62 def logout(self, session):
atse@12140 63 """Delete session of it exists."""
acnt2@12077 64 if self.is_session_valid(session):
acnt2@12077 65 del self.sessions[session]
acnt2@12077 66
acnt2@12077 67 def is_session_valid(self, session):
atse@12140 68 """Returns true is session is valid."""
acnt2@12077 69 if type(session) == type(str()):
acnt2@12077 70 return (session in self.sessions)
acnt2@12077 71 return False
atse@12138 72
acnt2@12077 73 def is_authorized(self, username, password):
atse@12140 74 """Returns true is a user is authorised via PAM.
atse@12140 75
atse@12140 76 Note: We use the 'login' PAM stack rather than inventing
atse@12140 77 our own.
atse@12140 78
atse@12140 79 @rtype: boolean
atse@12140 80 """
atse@12140 81 pam_auth = None
atse@12140 82 try:
atse@12140 83 pam_auth = PAM.pam()
atse@12140 84 except NameError:
atse@12140 85 # if PAM doesn't exist, let's ignore it
atse@12140 86 return False
atse@12140 87
atse@12138 88 pam_auth.start("login")
atse@12138 89 pam_auth.set_item(PAM.PAM_USER, username)
atse@12138 90
atse@12138 91 def _pam_conv(auth, query_list, user_data):
atse@12138 92 resp = []
atse@12138 93 for i in range(len(query_list)):
atse@12138 94 query, qtype = query_list[i]
atse@12138 95 if qtype == PAM.PAM_PROMPT_ECHO_ON:
atse@12138 96 resp.append((username, 0))
atse@12138 97 elif qtype == PAM.PAM_PROMPT_ECHO_OFF:
atse@12138 98 resp.append((password, 0))
atse@12138 99 else:
atse@12138 100 return None
atse@12138 101 return resp
atse@12138 102
atse@12138 103 pam_auth.set_item(PAM.PAM_CONV, _pam_conv)
atse@12138 104
atse@12138 105 try:
atse@12138 106 pam_auth.authenticate()
atse@12138 107 pam_auth.acct_mgmt()
atse@12138 108 except PAM.error, resp:
atse@12138 109 return False
atse@12138 110 except Exception, e:
atse@12138 111 log.warn("Error with PAM: %s" % str(e))
atse@12138 112 return False
atse@12138 113 else:
acnt2@12077 114 return True
acnt2@12077 115
acnt2@12077 116 def get_user(self, session):
acnt2@12077 117 try:
acnt2@12077 118 return self.sessions[session][0]
acnt2@12077 119 except (KeyError, IndexError):
acnt2@12077 120 return None
acnt2@12077 121
acnt2@12077 122
acnt2@12077 123 def instance():
acnt2@12077 124 """Singleton constructor. Use this instead of the class constructor.
acnt2@12077 125 """
acnt2@12077 126 global inst
acnt2@12077 127 try:
acnt2@12077 128 inst
acnt2@12077 129 except:
acnt2@12077 130 inst = XendAuthSessions()
acnt2@12077 131 inst.init()
acnt2@12077 132 return inst
acnt2@12077 133
acnt2@12077 134 # Handy Authentication Decorators
acnt2@12077 135 # -------------------------------
acnt2@12077 136 def session_required(func):
acnt2@12077 137 def check_session(self, session, *args, **kwargs):
acnt2@12077 138 if instance().is_session_valid(session):
acnt2@12077 139 return func(self, session, *args, **kwargs)
acnt2@12077 140 else:
acnt2@12077 141 return {'Status': 'Failure',
acnt2@12077 142 'ErrorDescription': XEND_ERROR_SESSION_INVALID}
acnt2@12077 143 return check_session
acnt2@12077 144
acnt2@12077 145