Browse Source

Bugfixes on ram_session on sessions and on cookies

- webui fix in cookies handling
- ram_session fix in token generation (return an str : hex representation of os.urandom(n))
- more fixes in Client session handling
Yann Weber 8 years ago
parent
commit
611b01fd0e
4 changed files with 48 additions and 33 deletions
  1. 23
    8
      lodel/auth/client.py
  2. 1
    1
      plugins/ram_sessions/__init__.py
  3. 10
    12
      plugins/ram_sessions/main.py
  4. 14
    12
      plugins/webui/run.py

+ 23
- 8
lodel/auth/client.py View File

8
 from lodel import logger
8
 from lodel import logger
9
 from lodel.plugin.hooks import LodelHook
9
 from lodel.plugin.hooks import LodelHook
10
 from lodel.plugin import SessionHandlerPlugin as SessionHandler
10
 from lodel.plugin import SessionHandlerPlugin as SessionHandler
11
+from .exceptions import *
11
 
12
 
12
 ##@brief Class designed to handle sessions and its datas
13
 ##@brief Class designed to handle sessions and its datas
13
 class LodelSession(object):
14
 class LodelSession(object):
61
             raise ClientAuthenticationError("Trying to restore a session, but \
62
             raise ClientAuthenticationError("Trying to restore a session, but \
62
 a session is allready started !!!")
63
 a session is allready started !!!")
63
         self.__datas = SessionHandler.restore(token)
64
         self.__datas = SessionHandler.restore(token)
65
+        self.__token = token
64
         return self.datas
66
         return self.datas
65
 
67
 
66
     ##@brief Save the current session state
68
     ##@brief Save the current session state
68
         if not self.started:
70
         if not self.started:
69
             raise ClientAuthenticationError(
71
             raise ClientAuthenticationError(
70
                 "Trying to save a non started session")
72
                 "Trying to save a non started session")
71
-        SessionHandler.save(self.__token)
73
+        SessionHandler.save(self.__token, self.__datas)
72
     
74
     
73
     ##@brief Destroy a session
75
     ##@brief Destroy a session
74
     def destroy(self):
76
     def destroy(self):
185
         self.__session = LodelSession(session_token)
187
         self.__session = LodelSession(session_token)
186
         logger.debug("New client : %s" % self)
188
         logger.debug("New client : %s" % self)
187
     
189
     
190
+    def __del__(self):
191
+        del(self.__session)
192
+
188
     ##@brief Try to authenticate a user with a login and a password
193
     ##@brief Try to authenticate a user with a login and a password
189
     #@param login str : provided login
194
     #@param login str : provided login
190
     #@param password str : provided password (hash)
195
     #@param password str : provided password (hash)
227
     #@throw ClientAuthenticationFailure if token is not valid or not
232
     #@throw ClientAuthenticationFailure if token is not valid or not
228
     #existing
233
     #existing
229
     @classmethod
234
     @classmethod
230
-    def restore_session(self, token):
235
+    def restore_session(cls, token):
231
         cls._assert_instance()
236
         cls._assert_instance()
232
-        return self.__session.restore(token)
237
+        return Client._instance.__session.restore(token)
233
     
238
     
234
     ##@brief Return the current session token or None
239
     ##@brief Return the current session token or None
235
     #@return A session token or None
240
     #@return A session token or None
236
     @classmethod
241
     @classmethod
237
     def session_token(cls):
242
     def session_token(cls):
238
         cls._assert_instance()
243
         cls._assert_instance()
239
-        return cls._instance.__session.retrieve_token()
244
+        return Client._instance.__session.retrieve_token()
240
 
245
 
241
     @classmethod
246
     @classmethod
242
     def session(cls):
247
     def session(cls):
243
         cls._assert_instance()
248
         cls._assert_instance()
244
-        return cls._instance.__session
245
-
249
+        return Client._instance.__session
250
+    
251
+    ##@brief Delete current session
246
     @classmethod
252
     @classmethod
247
     def destroy(cls):
253
     def destroy(cls):
248
         cls._assert_instance()
254
         cls._assert_instance()
249
-        cls._instance.__session.destroy()
250
-
255
+        Client._instance.__session.destroy()
256
+    
257
+    ##@brief Delete current client and save its session
258
+    @classmethod
259
+    def clean(cls):
260
+        if Client._instance.__session.started:
261
+            Client._instance.__session.save()
262
+        if Client._instance is not None:
263
+            del(Client._instance)
264
+        Client._instance = None
265
+    
251
     ##@brief Test wether a client is anonymous or logged in
266
     ##@brief Test wether a client is anonymous or logged in
252
     #@return True if client is anonymous
267
     #@return True if client is anonymous
253
     @classmethod
268
     @classmethod

+ 1
- 1
plugins/ram_sessions/__init__.py View File

10
 CONFSPEC = {
10
 CONFSPEC = {
11
     'lodel2.sessions':{
11
     'lodel2.sessions':{
12
         'expiration': (900, SettingValidator('int')),
12
         'expiration': (900, SettingValidator('int')),
13
-        'token_size': (512, SettingValidator('int')),
13
+        'tokensize': (512, SettingValidator('int')),
14
     }
14
     }
15
 }
15
 }

+ 10
- 12
plugins/ram_sessions/main.py View File

1
 #-*- coding: utf-8 -*-
1
 #-*- coding: utf-8 -*-
2
 import os
2
 import os
3
 import copy
3
 import copy
4
+import binascii
4
 
5
 
5
 from lodel import logger
6
 from lodel import logger
6
 from lodel.settings import Settings
7
 from lodel.settings import Settings
8
 
9
 
9
 __sessions = dict()
10
 __sessions = dict()
10
 
11
 
12
+def __generate_token():
13
+    return binascii.hexlify(os.urandom(Settings.sessions.tokensize//2))
14
+
11
 def _check_token(token):
15
 def _check_token(token):
12
-    if len(token) != Settings.sessions.token_size:
16
+    if len(token) != Settings.sessions.tokensize:
13
         raise ClientAuthenticationFailure("Malformed session token")
17
         raise ClientAuthenticationFailure("Malformed session token")
14
     if token not in __sessions:
18
     if token not in __sessions:
15
         raise ClientAuthenticationFailure("No session with this token")
19
         raise ClientAuthenticationFailure("No session with this token")
16
 
20
 
17
 def start_session():
21
 def start_session():
18
-    token = os.urandom(Settings.sessions.token_size)
22
+    token = __generate_token()
19
     __sessions[token] = dict()
23
     __sessions[token] = dict()
24
+    _check_token(token)
25
+    logger.debug("New session created")
20
     return token
26
     return token
21
 
27
 
22
 def destroy_session(token):
28
 def destroy_session(token):
23
     _check_token(token)
29
     _check_token(token)
24
     del(__sessions[token])
30
     del(__sessions[token])
31
+    logger.debug("Session %s destroyed" % token)
25
 
32
 
26
 def restore_session(token):
33
 def restore_session(token):
27
     _check_token(token)
34
     _check_token(token)
31
 def save_session(token, datas):
38
 def save_session(token, datas):
32
     _check_token(token)
39
     _check_token(token)
33
     __sessions[token] = copy.copy(datas)
40
     __sessions[token] = copy.copy(datas)
34
-
35
-
36
-def get_value(token, name):
37
-    _check_token(token)
38
-    return __sessions[token][name]
39
-
40
-def del_value(token, name):
41
-    _check_token(token)
42
-    if name in __sessions[token]:
43
-        del(__sessions[token][name])
41
+    logger.debug("Session saved")
44
 
42
 

+ 14
- 12
plugins/webui/run.py View File

26
 
26
 
27
 COOKIE_SESSION_ID = 'toktoken'
27
 COOKIE_SESSION_ID = 'toktoken'
28
 COOKIE_SESSION_HASH = 'nekotkot'
28
 COOKIE_SESSION_HASH = 'nekotkot'
29
-COOKIE_SESSION_HASH_SALT = [ os.urandom(32) for _ in range(2) ] #Before and after salt (maybe useless)
29
+#COOKIE_SESSION_HASH_SALT = [ os.urandom(32) for _ in range(2) ] #Before and after salt (maybe useless)
30
+COOKIE_SESSION_HASH_SALT = ['salt1', 'salt2']
30
 COOKIE_SESSION_HASH_ALGO = hashlib.sha512
31
 COOKIE_SESSION_HASH_ALGO = hashlib.sha512
31
 
32
 
32
 ##@brief Return a salted hash of a cookie
33
 ##@brief Return a salted hash of a cookie
33
 def cookie_hash(token):
34
 def cookie_hash(token):
35
+    token = str(token)
36
+    return COOKIE_SESSION_HASH_ALGO(token.encode()).hexdigest()
34
     return COOKIE_SESSION_HASH_ALGO(
37
     return COOKIE_SESSION_HASH_ALGO(
35
-        COOKIE_SESSION_HASH_SALT[0]+token+COOKIE_SESSION_HASH_SALT[1]).hexdigest()
38
+        (COOKIE_SESSION_HASH_SALT[0]+token+COOKIE_SESSION_HASH_SALT[1]).encode()).hexdigest()
36
     
39
     
37
 
40
 
38
 ##@brief Load cookie from request
41
 ##@brief Load cookie from request
41
 #@return None or a session token
44
 #@return None or a session token
42
 def load_cookie(request):
45
 def load_cookie(request):
43
     token = request.cookies.get(COOKIE_SESSION_ID)
46
     token = request.cookies.get(COOKIE_SESSION_ID)
44
-    if token is None and token != '':
47
+    token=token.encode()
48
+    if token is None or len(token) == 0:
45
         return None
49
         return None
46
-    token = bytes(token, 'utf-8')
47
     hashtok = request.cookies.get(COOKIE_SESSION_HASH)
50
     hashtok = request.cookies.get(COOKIE_SESSION_HASH)
48
     if hashtok is None:
51
     if hashtok is None:
49
         raise ClientAuthenticationFailure(
52
         raise ClientAuthenticationFailure(
103
         #to log messages with client infos
106
         #to log messages with client infos
104
         client = WebUiClient(env['REMOTE_ADDR'], env['HTTP_USER_AGENT'], None)
107
         client = WebUiClient(env['REMOTE_ADDR'], env['HTTP_USER_AGENT'], None)
105
         session_token = load_cookie(request)
108
         session_token = load_cookie(request)
106
-
107
         if session_token is not None:
109
         if session_token is not None:
108
-            WebClient.restore_session(token)
110
+            WebUiClient.restore_session(session_token)
111
+            #next line is for testing purpose
112
+            print("ACCESS DATAS : ", WebUiClient['last_request'])
109
         session_token = None
113
         session_token = None
110
-        #test
114
+        #next line is for testing purpose
111
         WebUiClient['last_request'] = time.time()
115
         WebUiClient['last_request'] = time.time()
112
         try:
116
         try:
113
             controller = get_controller(request)
117
             controller = get_controller(request)
124
         if session_token is not None:
128
         if session_token is not None:
125
             save_cookie(response,session_token)
129
             save_cookie(response,session_token)
126
         session_token = None
130
         session_token = None
127
-            
128
-
129
     except (ClientError, ClientAuthenticationError):
131
     except (ClientError, ClientAuthenticationError):
130
-        response = HttpException(400).render(request)
132
+        response = HttpException(200).render(request)
131
         empty_cookie(response)
133
         empty_cookie(response)
132
     except ClientAuthenticationFailure:
134
     except ClientAuthenticationFailure:
133
-        response = HttpException(401).render(request)
135
+        response = HttpException(200).render(request)
134
         empty_cookie(response)
136
         empty_cookie(response)
135
     except Exception as e:
137
     except Exception as e:
136
         raise e
138
         raise e
137
 
139
 
138
     res = response(env, start_response)
140
     res = response(env, start_response)
139
 
141
 
140
-    WebUiClient.destroy()
142
+    WebUiClient.clean()
141
     return res
143
     return res

Loading…
Cancel
Save