15 months agoLOC-23 - Shorten Session IDs and increase keyspace.
B Tasker []
LOC-23 - Shorten Session IDs and increase keyspace.

Changes the session ID from a 128 Uppercase/numeric char string (36^128) to a 48 char mixed character string (80^48).

Permitted characters are:

string.ascii_letters + string.digits + '/=?&@#%^()+,.<>:!'

15 months agoLOC-13 - Encrypt system message payloads.
B Tasker []
LOC-13 - Encrypt system message payloads.

This is done for two main reasons - firstly to minimise the amount of obvious plaintext in memory (though it is still base64 encoded, so limited effect there).

Secondly, and more importantly, it allows us to adjust the client so that it will never honour a plaintext JSON message payload.

15 months agoPartial implementation for LOC-21
B Tasker []
Partial implementation for LOC-21

Users within the same room can now send each other direct messages

/msg [username] [msg]

However, the message is currently encrypted with the room key. Other users won't (and shouldn't) receive DMs not addressed to them back from {{pollMsg}}, and old DMs will be cleared at the same interval as room-wide messages.

Messages really should be encrypted with a key that's specific to the addressed user, but that can't be implemented until Roster support has been added.

15 months agoLOC-14 - Move failuremessage pushing to function
B Tasker []
LOC-14 - Move failuremessage pushing to function

This is done as at some point we'll also want to push a "room has been closed" message. To do that though, we'll need to query all the users in the room, so leaving for now

15 months agoLOC-14 System will now push a failuremessage when a user is kicked from a room
B Tasker []
LOC-14 System will now push a failuremessage when a user is kicked from a room

The message will be returned to the client just once, and is valid for 5 minutes (though clearance hasn't been implemented yet)

15 months agoLOC-14 - Move error status code returning to a dedicated function
B Tasker []
LOC-14 - Move error status code returning to a dedicated function

This is as a precursor to checking for a stored message for that user

15 months agoUsed LOC-16 verb to assign colours to different system messages
B Tasker []
Used LOC-16 verb to assign colours to different system messages

System will set one of the following verbs along with it's messages, resulting in a different colour in the client

- sysinfo - magenta (as before)
- syswarn - Cyan
- sysalert - High contract reversed colours (grey background, black font)

15 months agoAdding {{/me}} functionality using verb from LOC-16
B Tasker []
Adding {{/me}} functionality using verb from LOC-16

Within a room, if a user types (for example)

/me returns again

The room will see a (yellow) message reading

** ben2 returns again **

15 months agoLOC-16 add "verb" to message payload
B Tasker []
LOC-16 add "verb" to message payload

It's not currently used by the client (and probably won't be until there's a need for it), but it's now available.

The default is 'say', and when sending a system message the server will use 'sysinfo'

15 months agoLOC-10 - Use server-validated username to define message sender
B Tasker []
LOC-10 - Use server-validated username to define message sender

We now use the username field that's authenticated by the server when displaying who the sender was. The "user" field has been removed from the encrypted message payload as being potentially dangerous (and no longer used in any case).

This means that it should no longer be possible to spoof the sender of messages. Instead you'd need to compromise an existing user's session or password.

The trade off of this is that there's a slightly increased level of metadata in memory on the server, but having weighed the options in LOC-10 this was deemed lower risk than the alternative.

15 months agoLOC-2 Clear user sessions when room is closed
B Tasker []
LOC-2 Clear user sessions when room is closed

15 months agoLOC-2 - Delete user's session token when they're kicked/banned or leave the room
B Tasker []
LOC-2 - Delete user's session token when they're kicked/banned or leave the room

15 months agoLOC-2 Session token is now checked and validity enforced
B Tasker []
LOC-2 Session token is now checked and validity enforced

15 months agoLOC-2 Client now sends session key with all relevant requests
B Tasker []
LOC-2 Client now sends session key with all relevant requests

Having joined a room, the client will now include {{sesskey}} in it's payload for

- {{pollMsg}}
- {{sendMsg}}
- {{leaveRoom}}
- {{closeRoom}}
- {{inviteUser}}
- {{kickUser}}
- {{banUser}}

And will clear the stored key when a user leaves the room.

15 months agoLOC-2 Switch to prefixing with Room Name so that we don't leak how many active rooms there are
B Tasker []
LOC-2 Switch to prefixing with Room Name so that we don't leak how many active rooms there are

15 months agoLOC-2 joinRoom now generates and returns a 1024 bit session key
B Tasker []
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

15 months agoLOC-2 Enforce user password when joining room
B Tasker []
LOC-2 Enforce user password when joining room

When {{joinRoom}} is called, we'll now check that the submitted password matches the hash in the database.

That's currently as far as the authentication mechanism goes at the moment though, so once a user's entered a room, other users could still submit messages with their name on it. Addressing that is up next.

15 months agoBUGFIX - allow a 500 error to be returned
B Tasker []
BUGFIX - allow a 500 error to be returned

15 months agoLOC-2 Implemented password generation when inviting users
B Tasker []
LOC-2 Implemented password generation when inviting users

Now, when a user is invited into a room the inviting user will be given output detailing how the invited user should join

User ben2 may now join room
To join the room, they should do /join BenTest7 0JF6LXE4Q23TFE7A:U2SNQORSY9NZWV7T ben2

That will obviously need to be communicated to the invited user securely, but there's already a need to securely communicate how to connect to the LocalChat instance anway, so it's effectively an extension of an existing need to do a key-exchange.

15 months agoLOC-2 Implemented user password storage
B Tasker []
LOC-2 Implemented user password storage

* The backend now stores a (bcrypt) hash of a user's password.
* When a room is created, a hash of the owner's password is also inserted into the invite table so that they can join the room

Currently, the password isn't actually needed to join (that's the next step)

Within the client, when a room is created output is generated to show how to join the room. This commit amends that output to include the admin user's password, for example

To join the room, do /join BenTest123 SD8WXY1OKC39CI0Y:QCVN7CEPUCHAQU2S ben

The first section (i.e. before :) of that password is the room password (so will be used for the E2E encryption). The second half is the users password.

When invites are generated (this doesn't yet happen) the generated output will differ only in the second half of the password and the username to sign in as.

15 months agoLOC-8 Do not throw exception if message cannot be decrypted
B Tasker []
LOC-8 Do not throw exception if message cannot be decrypted

If a user connects into a room using a different encryption key to everyone else, do not let them effectively DoS the room by causing exceptions in everyone else's clients.

If we receive a message that cannot be decrypted, we simply print a warning to that effect and carry on.

Because the sending user's name is in the encrypted payload, we can't ascertain who sent it - but as soon as someone else replies, that sending user will also get an error message.

15 months agoLOC-2 Removed room password from submission and from input format of /room create
B Tasker []
LOC-2 Removed room password from submission and from input format of /room create

New syntax is

/room create [roomname] [owner]

The client will then generate _client side_ a password to use as the room password. It's perfectly fine to use a different value, so long as all other users in the room are using the same one.

What _will_ need to happen when creating a room, though, is for us to submit a password hash for the owning user so that they can actually enter the room to invite others.

15 months agoLOC-2 - Removed Room password from API and from table
B Tasker []
LOC-2 - Removed Room password from API and from table

It's used as a crypto key, so we don't really want any aspect of it going anywhere near the server.

15 months agoLOC-7 - Implemented ability to close a room
B Tasker []
LOC-7 - Implemented ability to close a room

The room owner can now close the room with

/room close [roompass]

The pass is only required to prevent additional triggering and isn't used for any form of validation.

15 months agoRemove excess whitespace
B Tasker []
Remove excess whitespace

15 months agoLOC-5 - Prevent SYSTEM from joining rooms, and warn if users try to invite it
B Tasker []
LOC-5 - Prevent SYSTEM from joining rooms, and warn if users try to invite it

We prevent anyone from joining with the name SYSTEM, and warn the entire room if someone tries to authorise SYSTEM to log in (because they're almost certainly up to no good)

15 months agoSwitch to using ad-hoc SSL
B Tasker []
Switch to using ad-hoc SSL

We do this so that messaging metadata isn't leaked quite so much on the loopback interface

15 months agoImplement msg payload encryption in the client - LOC-4
B Tasker []
Implement msg payload encryption in the client - LOC-4

Message payloads are now PGP encrypted using the room password as the encryption passphrase.

It'd be nice to be able to use something like OTR, but it adds a lot of overhead in a Multi-User-Chat environment (as you'd need to address a copy to each user, encrypted with their own key, or trust the server to see the messages).

15 months agoLOC-1 - forgot to include the server component in the earlier commit
B Tasker []
LOC-1 - forgot to include the server component in the earlier commit

15 months agoUpdate help text
B Tasker []
Update help text

15 months agoLOC-1 Only users authorised on a room may grant access to others
B Tasker []
LOC-1 Only users authorised on a room may grant access to others

Was originally going to make it admin only, but decided it was better to push a notification in instead.

15 months agoLOC-3 Room Owners can now kick (and ban) users from the room
B Tasker []
LOC-3 Room Owners can now kick (and ban) users from the room

To kick a user out of the room, the owner can do

/kick [user]

To kick them and remove their ability to return, do

/ban [user]

15 months agoAdding help output. SC-2 v0.0.1a
B Tasker []
Adding help output. SC-2

This brings us (more or less) up to the point of a PoC for SC-2.

Although there's currently no E2E encryption and the auto-room purging isn't in place (apart from when a new user joins a room), messages can now flow back and forth.

It's not currently possible to close a room either, that needs to come soon.

But, there's enough functionality in place that it seems worth setting up a JIRA project for future adjustments/improvements. Auth is going to need doing at some point soon and it'd be good to have the decisions made on that properly documented.

This commit will be tagged as being v0.0.1a

15 months agoAdded the ability to invite users into room.
B Tasker []
Added the ability to invite users into room.

/room invite [roomname] [roompass] [[user]]

There's a known issue here where the backend will allow anyone to invite anyone into a room, even if the original user *isn't* actually invited into the room themselves.

That should be considered a big TODO

15 months agoClient can now create room
B Tasker []
Client can now create room

/room create [roomname] [roompass] [[user]]

If the user is currently in another room and they don't explicity set a user to be used as owner, then whatever username they're using in the current room will be re-used for the new room

15 months agoDo not re-use message IDs
B Tasker []
Do not re-use message IDs

Without this, polling breaks as we look for IDs > our last. When key re-use is permitted the latest ID may well be less than the most recent one we've seen

15 months agoImplement ability to leave room
B Tasker []
Implement ability to leave room

Room will get a message to note the user left

Command is /leave

15 months agoDon't repeatedly spam server went away messages
B Tasker []
Don't repeatedly spam server went away messages

15 months agoFix colouring.
B Tasker []
Fix colouring.

Messages sent by the local user should appear blue, whilst from other users should be green.

Had left the check using a global though, so the deciding factor for blue was - is the upstream user called "ben2"?

15 months agoOnly allow a user to poll for messages, or send messages for a room after they've actually joined it
B Tasker []
Only allow a user to poll for messages, or send messages for a room after they've actually joined it

15 months agoOlder messages will now be purged when a user joins the room
B Tasker []
Older messages will now be purged when a user joins the room

The aim of this is to prevent the new user from dumping out the entire stored history of a chat. Although the client will honour "last" they could conceivably override it to 0 and grab everything.

So, when they join, we now remove any messages older than 10 seconds.

At the moment, it's a little meaningless as you don't need to join in order to do pollMsg. That will obviously need to change.

15 months agoClient is no longer in a room by default, and must join by supplying username, roomname and room password
B Tasker []
Client is no longer in a room by default, and must join by supplying username, roomname and room password

Command format is

/join [user] [roomname] [password]

The password isn't currently used at all on either the front-end or the backend.

Backend component will, however, ensure that the user given is permitted to connect to the specified room.

If the user joins successfully a system message will be pushed into the room.

15 months agoSending a message from the client now works.
B Tasker []
Sending a message from the client now works.

Own messages will appear blue, whilst messages from other users are green.

Next step is probably to look at building in the join room functionality

15 months agoRegular poll now prints the messages as they should appear.
B Tasker []
Regular poll now prints the messages as they should appear.

What's missing at the moment is upstream user data - it's not in the current test payloads I'm using, so haven't put anything in to extract it yet. Once I've built the send message functionality into the interface I'll look at updating

15 months agoInterface now polls for new messages in the background
B Tasker []
Interface now polls for new messages in the background

With it running, if the following are run (in a seperate terminal) it correctly displays the expected output

curl -v -X POST http://127.0.0.1:8090/ -H "Content-Type: application/json" --data '{"action":"sendMsg","payload":"{\"roomName\":\"BenTest\", \"msg\":\"ENCRYPTED-DATA3\",\"user\":\"ben2\"}"}'
curl -v -X POST http://127.0.0.1:8090/ -H "Content-Type: application/json" --data '{"action":"sendMsg","payload":"{\"roomName\":\"BenTest\", \"msg\":\"ENCRYPTED-DATA4\",\"user\":\"ben2\"}"}'
curl -v -X POST http://127.0.0.1:8090/ -H "Content-Type: application/json" --data '{"action":"sendMsg","payload":"{\"roomName\":\"BenTest\", \"msg\":\"ENCRYPTED-DATA5\",\"user\":\"ben2\"}"}'

However, the caveat is that the test curls do not contain a JSON structure within the msg payload, so there's currently no functionality implemented to show time and sending user.

15 months agoAdding a poached urwid template to create the client interface
B Tasker []
Adding a poached urwid template to create the client interface

15 months agoImplemented ability to fetch all messages since last check.
B Tasker []
Implemented ability to fetch all messages since last check.

If you setup a room and stage some messages with the following:

# Create Room
curl -v -X POST http://127.0.0.1:8090/ -H "Content-Type: application/json" --data '{"action":"createRoom","payload":"{\"roomName\":\"BenTest\",\"owner\":\"ben\",\"passhash\":\"abcdefg\"}"}'

# Subscribe User
curl -v -X POST http://127.0.0.1:8090/ -H "Content-Type: application/json" --data '{"action":"inviteUser","payload":"{\"roomName\":\"BenTest\",\"user\":\"ben2\"}"}'

# Send a message
curl -v -X POST http://127.0.0.1:8090/ -H "Content-Type: application/json" --data '{"action":"sendMsg","payload":"{\"roomName\":\"BenTest\", \"msg\":\"ENCRYPTED-DATA\",\"user\":\"ben2\"}"}'

# Send another
curl -v -X POST http://127.0.0.1:8090/ -H "Content-Type: application/json" --data '{"action":"sendMsg","payload":"{\"roomName\":\"BenTest\", \"msg\":\"ENCRYPTED-DATA2\",\"user\":\"ben2\"}"}'

You can then fetch those messages with the following call

curl -v -X POST http://127.0.0.1:8090/ -H "Content-Type: application/json" --data '{"action":"pollMsg","payload":"{\"roomName\":\"BenTest\", \"mylast\":0,\"user\":\"ben2\"}"}'

This means we now have the basic components in place:

* Rooms can be created
* Users can be subscribed to the room
* Messages can be sent
* Clients can check for updated messages

Course, there's no auth yet, but it's probably better to try and build a working client first (as debugging is easier without a complex auth system in the way)

15 months agoImplemented ability to push messages into room.
B Tasker []
Implemented ability to push messages into room.

So the following flow will now create a room, add a user to it and then push a message by that user into the rooms table

curl -v -X POST http://127.0.0.1:8090/ -H "Content-Type: application/json" --data '{"action":"createRoom","payload":"{\"roomName\":\"BenTest\",\"owner\":\"ben\",\"passhash\":\"abcdefg\"}"}'

curl -v -X POST http://127.0.0.1:8090/ -H "Content-Type: application/json" --data '{"action":"inviteUser","payload":"{\"roomName\":\"BenTest\",\"user\":\"ben2\"}"}'

curl -v -X POST http://127.0.0.1:8090/ -H "Content-Type: application/json" --data '{"action":"sendMsg","payload":"{\"roomName\":\"BenTest\", \"msg\":\"ENCRYPTED-DATA\",\"user\":\"ben2\"}"}'

15 months agoOwner is now automatically subscribed into the room
B Tasker []
Owner is now automatically subscribed into the room

15 months agoImplemented the ability to link a user into a room
B Tasker []
Implemented the ability to link a user into a room

Means you can essentially do the following

curl -v -X POST http://127.0.0.1:8090/ -H "Content-Type: application/json" --data '{"action":"createRoom","payload":"{\"roomName\":\"BenTest\",\"owner\":\"ben\",\"passhash\":\"abcdefg\"}"}'
curl -v -X POST http://127.0.0.1:8090/ -H "Content-Type: application/json" --data '{"action":"inviteUser","payload":"{\"roomName\":\"BenTest\",\"user\":\"ben2\"}"}'

Which would allow user "ben2" to enter the room "BenTest"

What is missing, at the moment, is automatically linking the owner into the room at creation time. Will add that next

15 months agoImplemented basic schema for creating a room
B Tasker []
Implemented basic schema for creating a room

15 months agoCreating basic flask template as a starting point
B Tasker []
Creating basic flask template as a starting point