LOC-2 joinRoom now generates and returns a 1024 bit session key
LOC-2 joinRoom now generates and returns a 1024 bit session key

When the user successfully joins a room, a 1024 bit session key is generated and returned. The client stores this for use with later requests.

It's use isn't currently enforced (coming soon) and the table isn't currently tidied when a user leaves/is kicked (again coming soon).

The session key is prefixed by the room id, in the format

[roomid]-[sesskey]

The idea being that when a room is closed, it's trivial to remove all related sessions.

My concern here, though, is that it may leak how many rooms there are. If your session key starts 10 then you know there are (or have been) 10 rooms (including yours).

So, either we need to change the prefix to be the room name, or perhaps just have the server seed the room IDs with a random number at startup.

The problem with the latter is that we risk running out of IDs if the number's truly unbounded, and if it is bounded and we're near the upper bound you can still take an educated guess.

So it's probably better to switch using the room name in hindsight. Will change that next

--- a/client/LocalChatClient.py
+++ b/client/LocalChatClient.py
@@ -39,6 +39,7 @@
         self.server = SERVER
         self.room = False
         self.roompass = False
+        self.sesskey = False
         self.gpg = gnupg.GPG()
     
     
@@ -168,6 +169,7 @@
         self.user = user
         self.last = resp['last']
         self.roompass = p[0] # The room password is the first section of the password
+        self.sesskey = resp['session']
         return True
 
 

--- a/server/LocalChat.py
+++ b/server/LocalChat.py
@@ -20,6 +20,8 @@
 import os
 import json
 import bcrypt
+import random
+import string
 
 app = Flask(__name__)
 
@@ -84,6 +86,13 @@
             active INTEGER DEFAULT 0,
             passhash TEXT NOT NULL,
             PRIMARY KEY (username,room)
+        );
+        
+        
+        CREATE TABLE sessions (
+            username TEXT NOT NULL,
+            sesskey TEXT NOT NULL,
+            PRIMARY KEY(sesskey)
         );
         
         """
@@ -423,10 +432,14 @@
                 
         # Mark the user as active in the users table
         self.cursor.execute("UPDATE users set active=1 where username=? and room=?", (reqjson['payload']['user'],room))
-        self.conn.commit()
-        
-        
-        return {"status":"ok","last":last}
+        
+        
+        # Create a session for the user
+        sesskey = "%s-%s" % (room,self.genSessionKey())
+        self.cursor.execute("INSERT INTO sessions (username,sesskey) values (?,?)", (reqjson['payload']['user'],sesskey))
+        self.conn.commit()
+                
+        return {"status":"ok","last":last,"session":sesskey}
         
         
     def processleaveRoom(self,reqjson):
@@ -592,6 +605,9 @@
             self.conn.commit()
 
 
+    def genSessionKey(self,N=128):
+        return ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits).encode('utf-8') for _ in range(N))
+
 
     def test(self):
         return ['foo']