Assessment Details: You are required to build a simple client-server application that can be used to monitor several characteristics of a set of systems. The client functions as an agent that
collects data about the resources in the environment (system) that it is executing on. It stores the data locally and also sends it to a server application. Meanwhile, the server application receives collected data from agents over the network, securely stores a summary of them per client, and performs a basic analysis to determine whether a set of thresholds have been reached. More specifically, the client and server behaviour should be implemented, as follows: Server: 1. Start the program. 2. Ask the user for a port number to listen for TCP connections. This could also be passed as an argument to the program, as you prefer. Open a TCP server socket locally on the port that was specified by the user. 3. 4. Wait for a connection to be established on the server. 5. If a connection is made, establish a secure channel that includes using a SHA256 HMAC and AES256 CBC cryptography. For simplicity, any necessary key material can be hardcoded. Receive a message from the client application - the message content is defined below- which involves decrypting the message and creating an instance of a class (that you should write) that represents a client record with the details received. 6. 7. If there is no existing record of the client: a. Display the formatted contents of the message to the command line. Note in the display this is a new client. b. Write the contents of the message to a file that has been created for that specific client using AFS256 CBC encryption. Choose an appropriate file name format, e.g., based on a unique identifier of the client. 8. If there is a record of the client: a. Retrieve the existing record for the client from the disk and create an instance of a class that represents the client record. b. Update the data about the client that has been retrieved from the file with the new information from the client (see below). c. Check whether any thresholds have been met (see below), given the new information from the client; if they have, display an appropriate message to the command line. Write the updated information about the client to its file, overwriting the previous information. d. 9. Close the connection to the client in case the client has not done so. 10. Return to Step 4 and wait for a new connection to be established with the server./nClient: 1. Start the program. 2. Ask the user the following information: a. An IP address and port number of a server to send data to. b. The frequency, in seconds, they would like to collect data about the system. (These could also be passed as arguments to the program, as you prefer.) 3. Create an identifier, e.g., a timestamp that is concatenated with the machine name, which represents this client instance; this will be communicated to the server. 4. Create a file on the local disk that will be used to store the data that is collected from the system; if a file with the same name exists, it should be overwritten. Choose an appropriate file name format. 5. Perform the following tasks in a loop: a. Collect data about the local system using various functions from the Python psutil library (see below). b. Create an instance of a class that represents the data that has been collected from the system. c. Make a TCP connection to the specified server and establish a secure channel that includes using a SHA256 HMAC and AES256 CBC cryptography. For simplicity, any necessary key material can be hardcoded. d. Securely send the data that was collected from the system to the server. e. Close the connection. f. Display the data that has been collected to the command line, nicely formatted. g. Record the data that has been collected and ensure the integrity of the data in the file: i. Open the file for recording the collected data that was created in Step 4. ii. If the file is empty add the new data to it and create a hash of the file content (i.e., the newly collected data). Store the hash in the program's memory, i.e., don't write it to disk. iii. If the file is not empty: roport 1. Verify the integrity of the contents of the file on disk using the previously created hash. 2. If the integrity of the file has been compromised: a. Terminate the program gracefully and display a message to the user. 3. If the integrity of the file has not been compromised: a. Append the new collected data to the file. b. Recalculate the hash of the file's content. iv. Close the file. h. Wait for the period specified by the user. 6. When the user sends a SIGINT (i.e., they press Ctrl+C to end the program), the program should cleanly close any open files and the TCP connection to the server.