Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: daixieit

INFO1910

Assignment 2

Due: Week 12 Semester 1 2023

This assignment is worth 20% of yourfinal assessment

Task Description

In this server you will be writing clients and servers for a decentralised, anonymous, but not encrypted chat protocol.

Servers consist of channels, each channel is a small chat stream. Clients may connect to the server and to channels on the server. They may post messages in the channel’s chat and receive messages posted to the channel’s chat.

If correctly implemented all clients and servers produced by this assignment should be interoperable - any client can connect to any server and any pair of servers can synchronise channels. Note that this assignment will not cover proper user authentication, end to end encryption or even point to point encryption. A proper discussion of the correct implementation of the cryptographic primitives required for this would take another thirteen weeks.

Implementation Details

There are three components to this assignment; the channels that handle chat, the server that handles connections and authentication, and the client that connects with the server and posts messages.

The prompt for the client should always be given as >  .

The Protocol

Each incoming and outgoing message from a user should contain the following fields in order. Not all messages will make use of all fields.

• A 2 byte channel ID

• A 32 byte nickname

• A 4 byte timestamp indicating when the message was sent

• A 2 byte message type (2 bits) and length (14 bits)

• A message of up to 8191 characters

The 2 bit message type field contains the following options.

•  00: Posts to a channel

•  01: Client/Server commands (connected to a server but have not joined a channel)

•  10: Channel linkage requests (in this case the channel ID is the channel to link to)

•  11: Cross server channel synchronisation

Servers

By default messages posted to a channel are displayed to everyone connected to that channel. Ad- ditionally channels come with a number of commands that may be executed by users without being displayed to the rest of the channel.

A server should be started using: python  server .py    .

•  /list - Displays a list of each of the channels currently on the server

•  /join     [password] - Joins a channel, the password field is optional

•  /create     [password] Creates and joins a new channel by that chan- nelname, the password field is optional

•  /info - Shows information about the server. Should print the server name, current number of channel, number of connected users and uptime.

•  /invite     - Invites a connected user to a channel

•  /motd - Posts the server’s message of the day. Contained in the config/MOTD .txt file.

•  /rules - Posts the server’s rules. Contained in the config/RULES .txt file.

•  /help - Shows the server’s helpfile. Contained in the config/HELP .txt file.

Server administration commands. These commands are part of the authentication marks.

•  /die - Instructs the sever to shut down. If a configuration file is being used then it should be updated. This command should be implemented even if you are not implementing the authen- tication component.

•  /op   [nickname] - Grants channel operator powers to the target nickname in the current channel

•  /deop   [nickname] - Removes channel operator powers from the target nickname in the current channel

•  /admin   [nickname] - Grants server administration powers to the target nickname

•  /deadmin   [nickname] - Removes server administration powers to the target nickname

Channels

A channel is a chat stream where each participant has a unique nickname.  Channels start with a maximum of 50 messages saved at at time. Each message is prefixed by the time that the message was received, then the nickname of the sender followed by the message. Server messages are prefixed by an * instead of a user name. An example follows:

[09:59:55] [10:05:16] [10:06:04]

* |  info1910_user  joined  the info1910_user   |  Hi  everyone!

pacman-s   |  Arent  you  supposed  to  be

channel!

in  class?

[10:06:04]  pacman-s  ->  info1910_user   :  I  can  see  you  in  the  back  row!

[10:06:04]

[10:06:07]

* |  info1910_user  looks  embarrassed

* |  info1910_user  has  quit   (Oops!)

Regular members of a channel should have access to the following commands. Each command should display locally but not be broadcast to the other users of the channel unless otherwise stated.  The output of each of these messages should be considered to be a server message.

•  /nick   Changes the nickname of the current user in the current channel

•  /list Lists users by nickname. Each user should be displayed on a new line.

•  /admin   Returns whether or not the target user is a channel operator. Prints ei-

ther   is  an  operator for channel operators or   is  a  regular.

•  /msg   Sends a private message to the target user. The message should take the form   ->     :   This is a special mes- sage that cannot be seen by other members of the channel.

•  /emote   Posts a message in the third person of the form  .

The creator of a channel is the channel operator, they have access to the following commands. These first two commands should be implemented even if you are not performing authentication.

•  /message_limit   Changes the message limit of the channel. Defaults to 50.

•  /pass   [password] Sets the password for the channel. If the password field is empty then removes the password on the channel.

These commands are part of the authentication marks.

•  /op   Promotes a user to a channel operator

•  /deop   Demotes a user to a non-channel administrator.  The creator of the channel cannot be demoted.

•  /destroy Deletes the channel and boots all users back to the server.

•  /kick     [reason] Boots a user from the channel.  Cannot boot adminis- trators. Displays an optional final message to the user and the rest of the channel. The kick message should take the form   has  been  kicked   ()

The Client

The client will be a simple text interface. The client is a separate process that can join dechat servers and pass user input to and from them. Upon joining a server the client should receive and display the current server message history (you should implement this on your server side as part of the /join command).

>  /nick  info1910_user

>  /connect  localhost:9999

Connecting  to  server . . .

>  /join  info1910

Clients also have a set of special commands, If these are issued then whatever the rest of the string is should be read locally rather than sent to whatever server the client is connected to.

•  /connect   - Connects to a new server on a new channel number starting at 0 and incrementing. Prints Connecting  to  server . . . while attempting to connect and either Failed  to  connect  to  server  : if the connec- tion failed or prints the server’s MOTD if the connection succeeds.

•  /quit   [message]- Disconnects from the current channel or server, posts the message to the channel as the user exits. Prints Disconnecting  from  server . . ..  If the user is not connected to any server then this closes the client. An example can be seen in the channel section.

•  /nick   - Sets a new default nickname for this client.  If the user is already connected to a server then this command is in abeyance.

•  /reply Sends a private message to the last nickname that sent a private message to the client.

This message should take the form   ->     :  . An example can be seen in the channel section.

Optional Components

The following components are options you can select between. Each is worth up to 15%. You may implement multiple options for a potential final mark in excess of 100%. Some of these options are highly nontrivial and may have complex interactions.  You are encouraged to use your best judge- ment to resolve any conflicts in these cases. Testing of optional components will not be covered by automatic test cases.

Option: Synchronisation

As an extension of our server we will add some simple decentralisation. Servers may now additionally communicate with each other and channels may be hosted across servers. We will be ignoring some of the more alarming concerns about this model in favour of focusing on getting it working.

Each channel on a server may have a set of linked channels.  Whenever a message is sent to that channel it should be broadcast to all linked channels. To prevent infinite loops your server should try to ensure that messages that have already been received are not broadcast again. If messages arrive out of order it is fine for them to be displayed out of order, however the timestamps should still display the time that the message was sent.

As you can guess from this model it is highly non-robust. To see more robust models of decentralised negotiation I would wait for the study of distributed systems.

So supplement this synchronisation you should implement the following server commands, if you are also implementing authentication then please make these administrative commands that requires administrative control across both servers.

•  /link    : Sends a link request to the target server to synchronise a room of the same name between the two servers.

•  /unlink    : Unlinks the channel from the target server.

•  /migrate    : Migrates the channel to a new linked server, connected users should be migrated by receiving the same command.

You will be tested on migration and synchronisation between copies of your own server implementa- tions. You should make use of the 10 and 11 message types for this option.

Option: Authentication

Authentication commands are a bit special. To authenticate a user the server needs a copy of a public key from that user.

When a user is oped or admined the server should request a public key from their client.  Each subsequent time that the user ops themselves the server should post a challenge to their client. If the challenge passes then they gain those permissions. If it fails then they don’t. The code for creating keys, posing and passing challenges can be found in the auth .py file. Auth messages should use the‘client to server’message types.

To implement this section you should ensure that the commands listed as being exclusively for the operators and administrators require authentication.

Option: Client multi connection

Mixing standard input and output in the terminal is ugly. If you are implementing this option then you should modify your client to use ANSI escape characters to ensure that the io text streams are displayed in a separate region of the terminal to the user’s prompt.

As a part of this we can begin to implement multiple displays, the client should be able to connect to multiple channels simultaneously and swap between which channel is displayed in the client using the /display command.

Additionally you should implement the following commands:

•  /connect     [#display] Connects to a server on a numbered display

•  /display   [#] Swaps the current display to the number listed

•  /list_displays Lists the currently connected displays along with their associated servers and room names

These options should be enabled using a command line argument for the client: --ui.

Option: Persistent Configuration

Setting all options and authentications up every time the server is rebooted is a hassle.  As part of this option you should implement a simple set of plaintext configuration files for your server and channels. Servers should reboot using the configuration file back into the state with the same rooms and permissions as when the server was shutdown.

You should additionally implement a /flush_config   [filename] server command that up- dates the configuration file. If a name is provided then the config should be saved to the new filename

Running the Sample Code

You have been provided with a sample server, client, protocol and an authentication file to use as the basis of this task. Your code should run using python  server .py and client .py.

To test the samples start the server, then connect as many clients as you wish to the server and confirm that they are able to communicate with the server and hear echoes from the server.

Marking Details

This assignment will be subjected to manual marking. Not all test cases will not be released before the due date, you should write and implement your own tests. Given the complexity of end to end testing over multiple processes, a sample test harness will be provided. You may still perform unit testing without the harness.

The following marks add to more than 100%, this is intentional and you may complete additional optional components for a mark of greater than 100%.

• Code style and quality will account for 20% of your mark.  This will encompass code style, readability and your solution approach. Please follow PEP8 and the style guide provided. You should additionally provide documentation of how to use your code in a README .md file with correct markdown styling.

• Auto marking will account for 50% of your mark, test cases will be visible, hidden, or only assessed after the due date.

• Test cases will account for 15% of your mark. Please write thorough unit and end to end tests to be included with your submission.  Provide instructions on how to run the tests in your README .md.

Optional components:

• Persistent configuration will account for 5% of your mark (this is the easier option).

• Server to server synchronisation will account for 15% of your mark. Your server synchronisa- tion may be tested against a standard solution along with copies of itself.

• User authentication will account for 15% of your mark.

• Multi-connection clients will account for 15% of your mark.

You are strongly encouraged to comment your code and follow PEP8 style guidelines for Python. Meaningful variable names will greatly improve the readability of your program.

Restrictions

You may not use any Python libraries outside of socket, threading, time and Pycryptodome. Failure to abide by this restriction will result in a zero for this assessment.

Submission and Testing

You will be submitting your code via ed.

After the assignment is released, a number of pyunit test files will be made available. You may write your own test cases to extend on this, (and this is strongly encouraged). You should put these tests in the‘tests’directory in your repository.

Academic declaration

By submitting this assignment you declare the following:

I declare that I have read and understood the University of Sydney Student Plagiarism: Coursework Policy and Procedure, and except where specifically acknowledged, the work contained in this assignment/project is my own work, and has not been copiedfrom other sources or been previously submitted for award or assessment.

I understand that failure to comply with the Student Plagiarism: Coursework Policy and Procedure can lead to severe penalties as outlined under Chapter 8 of the University of Sydney By-Law 1999 (as amended). These penalties may be imposed in cases where any significant portion of my submitted work has been copied without proper acknowledgment from other sources, including published works, the Internet, existing programs, the work of other students, or work previously submittedfor other awards or assessments. I realise that I may be asked to identify those portions of the work contributed by me and required to demonstrate my knowledge of the relevant material by answering oral questions or by undertaking supplementary work, either written or in the laboratory, in order to arrive at the final assessment mark. I acknowledge that the School of Computer Science, in assessing this assignment, may reproduce it entirely, may provide a copy to another member of faculty, and/or communicate a copy of this assignment to a plagiarism checking service or in-house computer program, and that a copy of the assignment may be maintained by the service or the School of Computer Science for the purpose of future plagiarism checking.