ia64/xen-unstable

view tools/python/xen/xend/XendAuthSessions.py @ 13159:c3d84afbbb47

Implement the major part of the new error handling for the Xen-API.

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