The University of Queensland School of Information Technology and Electrical Engineering CSSE2310/CSSE7231 — Semester 1, 2023 Assignment 4 (version 1.0) Marks: 75 (for CSSE2310), 85 (for CSSE7231) Weighting: 15% Due: 4:00pm Friday 26 May, 2023 Introduction 1 The goal of this assignment is to further develop your C programming skills, and to demonstrate your un- 2 derstanding of networking and multithreaded programming. You are to create two programs which together 3 implement a brute-force password cracking system. One program – crackserver – is a network server which 4 accepts connections from clients (including crackclient which you will implement). Clients connect, and pro- 5 vide encrypted passphrases that the server will attempt to crack (recover the original unencrypted passphrase). 6 Clients may also request the server to encrypt passwords for later analysis. Communication between the 7 crackclient and crackserver is over TCP using a newline-terminated text command protocol. Advanced 8 functionality such as connection limiting, signal handling and statistics reporting are also required for full 9 marks. CSSE7231 students shall also implement a simple HTTP interface to crackserver. 10 The assignment will also test your ability to code to a particular programming style guide and to use a 11 revision control system appropriately. 12 Student Conduct 13 This is an individual assignment. You should feel free to discuss general aspects of C programming and 14 the assignment specification with fellow students, including on the discussion forum. In general, questions like 15 “How should the program behave if 〈this happens〉?” would be safe, if they are seeking clarification on the 16 specification. 17 You must not actively help (or seek help from) other students or other people with the actual design, structure 18 and/or coding of your assignment solution. It is cheating to look at another student’s assignment code 19 and it is cheating to allow your code to be seen or shared in printed or electronic form by others. 20 All submitted code will be subject to automated checks for plagiarism and collusion. If we detect plagiarism or 21 collusion, formal misconduct actions will be initiated against you, and those you cheated with. That’s right, if 22 you share your code with a friend, even inadvertently, then both of you are in trouble. Do not post your 23 code to a public place such as the course discussion forum or a public code repository. (Code in private posts 24 to the discussion forum is permitted.) You must assume that some students in the course may have very long 25 extensions so do not post your code to any public repository until at least three months after the result release 26 date for the course (or check with the course coordinator if you wish to post it sooner). Do not allow others to 27 access your computer – you must keep your code secure. Never leave your work unattended. 28 You must follow the following code referencing rules for all code committed to your SVN repository 29 (not just the version that you submit): 30 Code Origin Usage/Referencing Code provided to you in writing this semester by CSSE2310/7231 teaching staff (e.g. code hosted on Black- board, found in /local/courses/csse2310/resources on moss, posted on the discussion forum by teaching staff, pro- vided in Ed Lessons, or shown in class). May be used freely without reference. (You must be able to point to the source if queried about it – so you may find it easier to reference the code.) Code you have personally written this semester for CSSE2310/7231 (e.g. code written for A1 reused in A3) – provided you have not shared or published it. May be used freely without reference. (This assumes that no reference was required for the original use.) Code examples found in man pages on moss. May be used provided you understand the code AND the source of the code is referenced in a comment adjacent to that code (in the required format – see the style guide). If such code is used without appropriate referencing then this will be considered misconduct. Code you have personally written in a previous enrolment in this course or in another ITEE course and where that code has not been shared or published. Code (in any programming language) that you have taken inspiration from but have not copied1. 1Code you have taken inspiration from must not be directly copied or just converted from one programming language to another. 1 Version 1.0 Code Origin Usage/Referencing Code written by or obtained from, or based on code written by or obtained from, a code generation tool (including any artificial intelligence tool) that you personally have inter- acted with, without the assistance of another person. May be used provided you understand that code AND the source of the code is referenced in a comment ad- jacent to that code (in the required format) AND an ASCII text file (named toolHistory.txt) is included in your repository and with your submission that describes in detail how the tool was used. If such code is used without appropriate referencing and without inclusion of the toolHistory.txt file then this will be considered misconduct. Other code – includes (but may not be limited to): code provided by teaching staff only in a previous offering of this course (e.g. previous assignment one solution); code from public or private repositories; code from websites; code from textbooks; any code written or partially written or provided by or written with the assistance of someone else; and any code you have written that is available to other students. May not be used. If the source of the code is referenced adjacent to the code then this will be considered code without academic merit (not misconduct) and will be removed from your assignment prior to marking (which may cause compilation to fail and zero marks to be awarded). Copied code without adjacent referencing will be considered misconduct and action will be taken. Uploading or otherwise providing the assignment specification or part of it to a third party including online 31 tutorial and contract cheating websites is considered misconduct. The university is aware of these sites and 32 many cooperate with us in misconduct investigations. 33 The teaching staff will conduct interviews with a subset of students about their submissions, for the purposes 34 of establishing genuine authorship. If you write your own code, you have nothing to fear from this process. If 35 you legitimately use code from other sources (following the usage/referencing requirements in the table above) 36 then you are expected to understand that code. If you are not able to adequately explain the design of your 37 solution and/or adequately explain your submitted code (and/or earlier versions in your repository) and/or 38 be able to make simple modifications to it as requested at the interview, then your assignment mark will be 39 scaled down based on the level of understanding you are able to demonstrate and/or your submission may be 40 subject to a misconduct investigation where your interview responses form part of the evidence. Failure to 41 attend a scheduled interview will result in zero marks for the assignment. The use of referenced code in your 42 submission (particularly from artificial intelligence tools) is likely to increase the probability of your selection 43 for an interview. 44 In short - Don’t risk it! If you’re having trouble, seek help early from a member of the teaching staff. 45 Don’t be tempted to copy another student’s code or to use an online cheating service. Don’t help another 46 CSSE2310/7231 student with their code no matter how desperate they may be and no matter how close your 47 relationship. You should read and understand the statements on student misconduct in the course profile and 48 on the school website: https://www.itee.uq.edu.au/itee-student-misconduct-including-plagiarism. 49 Simple encryption and salting 50 Hashing is a common method of protecting sensitive data such as passwords. Instead of storing or transmitting 51 the password itself (plaintext) where it is at risk of interception, the password is first transformed by passing 52 it through a one-way function called a hash, yielding the ciphertext. A one-way function is one that is easy to 53 apply in one direction (plaintext to ciphertext), but impossible to apply in the reverse. 54 Because hash functions are deterministic, identical passwords encrypted with a hash function yield identical 55 ciphertext, which can assist an adversary in compromising a system. For this reason, the hashing scheme is 56 usually extended with a method called salting. The plaintext is extended with a random value, or salt, prior 57 to applying the hash function. The salt is stored along with the encrypted password, as both are required to 58 verify a given password and its hash. 59 With a sufficiently large possible range of salt values, this helps prevent attackers from building tables that 60 store the hash results of every possible (salted) password, increasing security by making the cracking more 61 challenging. 62 libcrypt is a POSIX library that supports a wide range of hashing functions and salting schemes – in this 63 assignment you will use it in its simplest mode. Note that this mode is now considered obsolete, and should 64 not be used for protecting data in modern systems. 65 The crypt() function is all that is required. In the simplest mode it is used as follows: 66 char *cipher = crypt(plaintext, salt) 2 Version 1.0 where plaintext is a pointer to a string containing the plaintext password, and salt is a pointer to a string 67 containing the salt. Only the first 8 characters of plaintext are used, and only the first two characters of salt 68 are used. Any additional characters are ignored. 69 Additionally, the salt must only contain characters from the following character set: 70 a b c d e f g h i j k l m n o p q r s t u v w x y z 71 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 72 0 1 2 3 4 5 6 7 8 9 . / 73 The return value from crypt() is a pointer to a static buffer, so the caller must copy this before making 74 any further calls to crypt(). A reentrant version of crypt() called crypt_r() is also available – refer to the 75 man page for details and usage. 76 Here are some examples: 77 • plaintext "foobar", salt "AA" → ciphertext "AAZk9Aj5/Ue0E" 78 • plaintext "dinosaur", salt "0z" → ciphertext "0zD1fV.Yez8RI" 79 Notice how the supplied salt characters always form the first two characters of the encrypted string. 80 81 The crypt() family of functions is declared in
, and you will need to link your crackserver with 82 the -lcrypt argument to use them in your programs. 83 Specification – crackclient 84 The crackclient program provides a command line interface that allows you to interact with crackserver as 85 a client – connecting to the server, sending crack and encryption requests, and displaying the results. 86 To implement this functionality, crackclient will only require a single thread. 87 Command Line Arguments 88 Your crackclient program is to accept command line arguments as follows: 89 ./crackclient portnum [jobfile] 90 • The mandatory portnum argument indicates which localhost port crackserver is listening on – either 91 numerical or the name of a service. 92 • The optional jobfile argument specifies the name of a file to be used as input commands. If not specified, 93 then crackclient is to read input from stdin. 94 crackclient behaviour 95 If an incorrect number of command line arguments are provided then crackclient should emit the following 96 message (terminated by a newline) to stderr and exit with status 1: 97 Usage: crackclient portnum [jobfile] If the correct number of arguments is provided, then further errors are checked for in the order below. 98 Job file error 99 If a job file is specified, and crackclient is unable to open it for reading, crackclient shall emit the following 100 message (terminated by newline) to stderr and exit with status 2: 101 crackclient: unable to open job file "jobfile" where jobfile is replaced by the name of the specified file. Note that the file name is enclosed in double quote 102 characters. 103 3 Version 1.0 Connection error 104 If crackclient is unable to connect to the server on the specified port (or service name) of localhost, it shall 105 emit the following message (terminated by a newline) to stderr and exit with status 3: 106 crackclient: unable to connect to port N where N should be replaced by the argument given on the command line. (This may be a non-numerical string.) 107 crackclient runtime behaviour 108 Assuming that the commandline arguments are without errors, crackclient is to perform the following actions, 109 in this order, immediately upon starting: 110 • connect to the server on the specified port number (or service name) – see above for how to handle a 111 connection error; 112 • read commands either from the jobfile, or stdin, and process them as described below; and 113 • when EOF is received on the input stream (job file or stdin), crackclient shall close any open network 114 connections, and terminate with exit status 0. 115 If the network connection to the server is closed (e.g. crackclient detects EOF on the socket), then 116 crackclient shall emit the following message to stderr and terminate with exit status 4: 117 crackclient: server connection terminated crackclient shall interpret its input commands as follows: 118 • Blank lines, and those beginning with the # character, shall be ignored 119 • All other lines shall be sent unaltered to the server (no error checking is required or to be performed) 120 Upon sending a command to the server, crackclient shall wait for a single line reply, and interpret it as follows: 121 • Response ":invalid" → emit the following text to stdout: 122 Error in command • Response ":failed" → emit the following text to stdout: 123 Unable to decrypt • Otherwise, the raw output received from the server shall be output to stdout. 124 Your crackclient program is not to register any signal handers nor attempt to mask or block any signals. 125 crackclient example usage 126 The following is an example of an interactive session with crackclient (assuming the crackserver is listening 127 on port 49152). Lines in bold face are typed interactively on the console, they are not part of the output of 128 the program: 129 $ ./crackclient 49152 # A comment line - ignored # A blank line - ignored # A malformed crypt request (no salt) crypt chicken Error in command # A malformed crypt request (bad salt) crypt chicken %% Error in command # Valid crypt requests crypt dog K9 4 Version 1.0 K930xTkdzhuMg crypt foobar zZ zZT8RjNYjMLz2 # Invalid crack request - no thread count specified crack zZT8RjNYjMLz2 Error in command # Failed crack request - the plaintext is not in the dictionary crack zZT8RjNYjMLz2 10 Unable to decrypt # Successful crack request, 1 thread crack K930xTkdzhuMg 1 dog # Successful crack request, 10 threads crack K930xTkdzhuMg 10 dog # Misc invalid crack requests crack K930xTkdzhuMg 0 Error in command crack K930xTkdzhuMg -1 Error in command crack K930xTkdzhuMg 100 Error in command crack K930xTkdzhuMg 1X Error in command Note that not all possible error conditions are present in this example. 130 The following is an example of a file driven session with crackclient (assuming the crackserver is listening 131 on port 49152). Lines in bold face are typed interactively on the console, they are not part of the output of 132 the program, given that cmd.in has the following contents: 133 1 # this is cmd.in - a list of commands to input to crackclient 2 # A comment line - ignored 3 # A blank line - ignored 4 5 # A malformed crypt request (no salt) 6 crypt chicken 7 # A malformed crypt request (bad salt) 8 crypt chicken \%\% 9 # Valid crypt requests 10 crypt dog K9 11 crypt foobar zZ 12 # Invalid crack request - no thread count specified 13 crack zZT8RjNYjMLz2 14 # Failed crack request - the plaintext is not in the dictionary 15 crack zZT8RjNYjMLz2 10 16 # Successful crack request, 1 thread 17 crack K930xTkdzhuMg 1 18 # Successful crack request, 10 threads 19 crack K930xTkdzhuMg 10 20 # Misc invalid crack requests 21 crack K930xTkdzhuMg 0 22 crack K930xTkdzhuMg -1 23 crack K930xTkdzhuMg 100 24 crack K930xTkdzhuMg 1X $ ./crackclient 49152 cmd.in Error in command Error in command K930xTkdzhuMg 5 Version 1.0 zZT8RjNYjMLz2 Error in command Unable to decrypt dog dog Error in command Error in command Error in command Error in command Specification – crackserver 134 crackserver is a networked, multithreaded password cracking server, allowing clients to connect and provide 135 encrypted ciphertext for cracking, and also allows clients to provide plaintext passwords for encrypting. All 136 communication between clients and the server is over TCP using a simple command protocol that will be 137 described in a later section. 138 Command Line Arguments 139 Your crackserver program is to accept command line arguments as follows: 140 ./crackserver [--maxconn connections] [--port portnum] [--dictionary filename] 141 In other words, your program should accept up to three optional arguments – which can be in any order. 142 The connections argument, if specified, indicates the maximum number of simultaneous client connections 143 to be permitted. If this is zero, then there is no limit to how many clients may connect (other than operating 144 system limits which we will not test). 145 Important: Even if you do not implement the connection limiting functionality, your program must correctly 146 handle command lines which include that argument (after which it can ignore any provided value – you will 147 simply not receive any marks for that feature). 148 The portnum argument, if specified, indicates which localhost port crackserver is to listen on. If the port 149 number is absent or zero, then crackserver is to use an ephemeral port. 150 The dictionary filename argument, if specified, indicates the path to a plain text file containing one word 151 or string per line, which represents the dictionary that crackserver will search when attempting to crack 152 passwords. If not specified, crackserver shall use the system dictionary file /usr/share/dict/words. 153 Program Operation 154 The crackserver program is to operate as follows: 155 • If the program receives an invalid command line then it must print the message: 156 Usage: crackserver [--maxconn connections] [--port portnum] [--dictionary filename] to stderr, and exit with an exit status of 1. 157 Invalid command lines include (but may not be limited to) any of the following: 158 – any of --maxconn, --port or --dict does not have an associated value argument 159 – the maximum connections argument (if present) is not a non-negative integer 160 – the port number argument (if present) is not an integer value, or is an integer value and is not either 161 zero, or in the range of 1024 to 65535 inclusive 162 – any of the arguments is specified more than once 163 – any additional arguments are supplied 164 • If the dictionary filename argument refers to a file that does not exist or cannot be opened for reading, 165 crackserver shall emit the following error message to stderr and terminate with exit status 2: 166 crackserver: unable to open dictionary file "filename" 6 Version 1.0 where filename is replaced by the name of the dictionary file provided on the command line. Note that 167 the double quote characters must be present. 168 • The dictionary words must be read into memory. Lines in the dictionary are terminated by newline 169 characters (except possibly the last line) and each line (excluding that newline character) is considered 170 to be a word. Any words longer than 8 characters should be discarded, i.e. not saved into memory, as 171 the crypt() family of functions only considers at most 8 characters of any supplied plain text. The order 172 of words must be preserved. It is possible the dictionary may contain duplicate words and these should 173 be preserved also. You may assume that words in the dictionary are no longer than 50 characters. Your 174 crackserver must read the dictionary only once. 175 • If the dictionary contains no words that are 8 characters long or shorter, then crackserver shall emit the 176 following error message to stderr and terminate with exit status 3: 177 crackserver: no plain text words to test • If portnum is missing or zero, then crackserver shall attempt to open an ephemeral localhost port for 178 listening. Otherwise, it shall attempt to open the specified port number. If crackserver is unable to listen 179 on either the ephemeral or specified port, it shall emit the following message to stderr and terminate 180 with exit status 4: 181 crackserver: unable to open socket for listening • Once the port is opened for listening, crackserver shall print to stderr the port number followed by a 182 single newline character and then flush the output. In the case of ephemeral ports, the actual port 183 number obtained shall be printed, not zero. 184 • Upon receiving an incoming client connection on the port, crackserver shall spawn a new thread to 185 handle that client (see below for client thread handling). 186 • If specified (and implemented), crackserver must keep track of how many active client connections exist, 187 and must not let that number exceed the connections parameter. See below on client handling threads 188 for more details on how this limit is to be implemented. 189 • Note that all error messages above must be terminated by a single newline character. 190 • The crackserver program should not terminate under normal circumstances, nor should it block or 191 otherwise attempt to handle SIGINT. 192 • Note that your crackserver must be able to deal with any clients using the correct communication 193 protocol, not just crackclient. Testing with netcat is highly recommended. 194 Client handling threads 195 A client handler thread is spawned for each incoming connection. This client thread must then wait for commands 196 from the client, one per line, over the socket. The exact format of the requests is described in the Communication 197 protocol section below. 198 As each client sends crack requests to crackserver, it shall spawn threads to perform the brute-force 199 password cracking action against the dictionary. 200 crypt requests from the client may be handled directly in the client handling thread if you wish – it is not 201 computationally expensive and there is no need to spawn an additional thread for this operation. 202 Due to the simultaneous nature of the multiple client connections, your crackserver will need to ensure 203 mutual exclusion around any shared data structure(s) to ensure that these do not get corrupted. 204 Once the client disconnects or there is a communication error on the socket then the client handler thread 205 is to close the connection, clean up and terminate. Other client threads and the crackserver program itself 206 must continue uninterrupted. 207 7 Version 1.0 Password cracking 208 crackserver is to use a brute-force method for cracking passwords as follows: 209 210 For each received ciphertext password 211 • Extract the password salt (the first two characters of the ciphertext) 212 • For each word saved from the dictionary 213 – encrypt the word with the salt using crypt() or crypt_r() 214 – compare the sample ciphertext with the encrypted dictionary word 215 – if the two ciphertexts are the same, terminate the search and return the plaintext dictionary word 216 Note – with just over 200,000 words of the right length in the default dictionary on moss and 642 possible 217 salt strings, it is not feasible to pre-calculate and store all possible salt+word combinations. Your program is 218 expected to use the brute-force method described above, trading CPU work for memory storage. 219 The above brute-force algorithm is trivially parallelised across multiple threads. If you implement it, and the 220 client requests more than one thread be used for cracking, you must distribute the dictionary roughly equally 221 across all threads as described below: 222 If the dictionary contains D words and N threads are requested then: 223 • if D < N or N = 1 then only one thread must be used 224 • if D ≥ N and N ≥ 2 then N − 1 threads must each cover bD/Nc words (i.e. D divided by N rounded 225 down if necessary to the nearest integer) and the remaining thread must cover the remaining words 226 Words must be allocated in groups based on the order they are present in the dictionary, i.e., the first bD/Nc 227 words saved from the dictionary must be allocated to one thread, the next bD/Nc words to another thread, etc. 228 For example, if there are 100,000 words saved from the dictionary spread across 7 threads – one thread will 229 get the first b100000/7c = 14285 words, the next thread will be allocated the next 14285 words, etc., and the 230 last (seventh) thread gets the last 14290 words saved from the dictionary. 231 Each thread must check its allocated words in the same order as they are present in the dictionary. 232 If a match is found then the thread that found the match must (a) indicate to the other threads in the job 233 that they should stop work immediately, and (b) not check any further of its own words. You must not use 234 pthread_cancel() to terminate other threads2. It is recommended that you set a (volatile) flag variable that 235 is checked in other threads before each word is processed. 236 Note that even though /usr/share/dict/words is sorted, the supplied dictionary may not be sorted. 237 Note also that it is possible that multiple threads may find matches because the same word may be present 238 multiple times in the dictionary. 239 SIGHUP handling (Advanced) 240 Upon receiving SIGHUP, crackserver is to emit (and flush) to stderr statistics reflecting the program’s oper- 241 ation to-date, specifically 242 • Total number of clients connected (at this instant) 243 • The total number of clients that have connected and disconnected since program start 244 • The total number of crack requests received (since program start), including invalid requests 245 • The total number of valid but unsuccessful crack requests completed (since program start) 246 • The total number of valid but successful crack requests completed (since program start) 247 • The total number of crypt requests received (since program start), including invalid requests 248 • The total number of calls to crypt() and/or crypt_r() (since program start) – including for both crack 249 and crypt requests3. 250 2As discussed in lectures, pthread_cancel() is not reliable. 3Note that this value will not be predictable if your tests include multi-threaded crack requests that are successful. This is because you can’t predict where other threads are up to when they stop work after a match is found. 8 Version 1.0 Unsuccessful crack requests include those that fail to find a matching dictionary word. Successful crack 251 requests are those that are valid and for which a matching dictionary word is found. Invalid crack requests 252 are those that have the correct command word (crack) but are otherwise invalid (e.g. have invalid arguments). 253 Note also that the number of crack requests received may include requests that are still in progress – i.e. it is 254 not yet known whether the request is successful or unsuccessful. (See the Communication protocol section for 255 details.) 256 All crypt requests should be counted, including those that are invalid e.g. due to an invalid salt string. 257 The required format is illustrated below. Each of the six lines is terminated by a single newline. You can 258 assume that all numbers will fit in a 32-bit unsigned integer, i.e. you do not have to consider numbers larger 259 than 4,294,967,295. 260 Listing 1: crackserver SIGHUP stderr output sample 1 Connected clients: 4 2 Completed clients: 20 3 Crack requests: 37 4 Failed crack requests: 15 5 Successful crack requests: 19 6 Crypt requests: 34 7 crypt()/crypt_r() calls: 34873425 Note that to accurately gather these statistics and avoid race conditions, you will need some sort of mutual 261 exclusion protecting the variables holding these statistics. 262 Global variables are not to be used to implement signal handling. See the Hints section below for how you 263 can implement this. 264 Client connection limiting (Advanced) 265 If the connections feature is implemented and a non-zero command line argument is provided, then crackserver 266 must not permit more than that number of simultaneous client connections to the server. crackserver shall 267 maintain a connected client count, and if a client beyond that limit attempts to connect, it shall block, in- 268 definitely if required, until another client leaves and this new client’s connection request can be accept()ed. 269 Clients in this waiting state are not to be counted in statistics reporting – they are only counted once they have 270 properly connected. 271 HTTP connection handling (CSSE7231 students only) 272 CSSE7231 students shall, in addition, implement a simple HTTP server in their crackserver implementa- 273 tion. Upon startup, crackserver shall check the value of the environment variable A4_HTTP_PORT. If set, then 274 crackserver shall also listen for connections on that port number (or service name). 275 If crackserver is unable to listen on that port or service name then it shall emit the following message to 276 stderr and terminate with exit status 5: 277 crackserver: unable to open HTTP socket for listening The ability to listen on this port is checked after the ability to listen on the “main” port (i.e. the one given 278 on the command line). If the A4_HTTP_PORT environment variable is not set then crackserver shall not listen 279 on any additional ports and shall not handle these HTTP connections. 280 The communication protocol uses HTTP. The connecting program (e.g. netcat, or a web browser) shall 281 send HTTP requests and crackserver shall send HTTP responses as described below. The connection between 282 client and server is kept alive between requests. Multiple HTTP clients may be connected simultaneously. 283 Additional HTTP header lines beyond those specified may be present in requests or responses and must 284 be ignored by the respective server/client. Note that interaction between a client on the HTTP port and 285 crackserver is synchronous – any one client can only have a single request underway at any one time. This 286 greatly simplifies the implementation of the crackserver HTTP connection handling threads. 287 The only supported request method is a GET request in the following format: 288 • Request: GET /stats HTTP/1.1 289 – Description: the client is requesting statistics from crackserver 290 – Request 291 9 Version 1.0 ∗ Request Headers: none expected, any headers present will be ignored by crackserver. 292 ∗ Request Body: none, any request body will be ignored 293 – Response 294 ∗ Response Status: 200 (OK). 295 ∗ Response Headers: the Content-Length header with correct value is required (number of bytes 296 in the response body), other headers are optional. 297 ∗ Response Body: the ASCII text containing the same crackserver statistics information de- 298 scribed in the SIGHUP handling section above. 299 If crackserver receives an invalid HTTP request then it should close the connection to that requestor (and 300 terminate the thread associated with that connection). Similarly, if a HTTP client disconnects, crackserver should 301 handle this gracefully and terminate the thread associated with the connection. 302 Program output 303 Other than error messages, the listening port number, and SIGHUP-initiated statistics output, crackserver is 304 not to emit any output to stdout or stderr. 305 Communication protocol 306 The communication protocol between clients and crackserver uses simple newline-terminated text message 307 strings as described below. Messages from client to server are space delimited. Messages from server to client 308 are colon delimited. Note that the angle brackets are used to represent placeholders, and are not part of 309 the command syntax. 310 Supported messages from crackclient to crackserver are: 311 • crack – the client is requesting the string be cracked, 312 using the specified number of threads. 313 314 IMPORTANT: even if you do not implement multi-threaded parallel password cracking functional- 315 ity, your crackserver must still accept and parse/validate the field - it will simply be 316 ignored during the cracking process. 317 • crypt – the client is requesting the server to encrypt the supplied using the 318 specified . 319 Single spaces are used as separators between fields, which implies that and fields 320 must not contain spaces. 321 Supported messages from crackserver to crackclient are 322 • :invalid – sent by the server to a client if the server receives an invalid command from that client (see 323 below) 324 • :failed – sent by the server to a client if the server is unable to crack the supplied ciphertext 325 • – if the server is able to decrypt the ciphertext, then the decrypted plaintext is sent back 326 on a single line. 327 • – the ciphertext result of a crypt operation is sent back on a single line 328 Invalid commands that might be received by crackserver from a client include: 329 • Invalid command word – an empty string or a command word which is not crack or crypt 330 • Invalid arguments such as 331 – empty strings (for any field) 332 – ciphertext not exactly 13 characters in length (including the two salt characters at the beginning) 333 – missing or invalid integer for the argument. The number of threads requested must 334 be greater than or equal to 1, and less than or equal to 50. 335 10 Version 1.0 • Invalid salt string provided for the crypt command 336 • Too few or too many arguments 337 • Any other kind of malformed message 338 Provided Libraries 339 libcsse2310a4 340 A split_by_char() function is available to break a line up into multiple parts, e.g. based on spaces. This is 341 similar to the split_line() function from libcsse2310a3 though allows a maximum number of fields to be 342 specified. 343 Several additional library functions have been provided to aid CSSE7231 students in parsing/construction 344 of HTTP requests/responses. The functions in this library are: 345 char** split_by_char(char* str, char split, unsigned int maxFields); int get_HTTP_request(FILE *f, char **method, char **address, HttpHeader ***headers, char **body); char* construct_HTTP_response(int status, char* statusExplanation, HttpHeader** headers, char* body); int get_HTTP_response(FILE *f, int* httpStatus, char** statusExplain, HttpHeader*** headers, char** body); void free_header(HttpHeader* header); void free_array_of_headers(HttpHeader** headers); These functions and the HttpHeader type are declared in /local/courses/csse2310/include/csse2310a4.h 346 on moss and their behaviour is described in man pages on moss – see split_by_char(3), get_HTTP_request(3), 347 and free_header(3). 348 To use these library functions, you will need to add #include to your code and use the 349 compiler flag -I/local/courses/csse2310/include when compiling your code so that the compiler can find 350 the include file. You will also need to link with the library containing these functions. To do this, use the 351 compiler arguments -L/local/courses/csse2310/lib -lcsse2310a4 352 libcsse2310a3 353 You are also welcome to use the "libcsse2310a3" library from Assignment 3 if you wish. This can be linked with 354 -L/local/courses/csse2310/lib -lcsse2310a3. Note that split_space_not_quote() is not appropriate for 355 use in this assignment – quotes have no particular meaning in the communication protocol for crackserver. 356 Style 357 Your program must follow version 2.3 of the CSSE2310/CSSE7231 C programming style guide available on the 358 course Blackboard site. 359 Hints 360 1. Review the lectures related to network clients, threads and synchronisation and multi-threaded network 361 servers (and HTTP for CSSE7231 students). This assignment builds on all of these concepts. 362 2. You should test crackclient and crackserver independently using netcat as demonstrated in the 363 lectures. You can also use the provided demo programs demo-crackclient and demo-crackserver. 364 3. The read_line() function from libcsse2310a3 may be useful in both crackclient and crackserver. 365 11 Version 1.0 4. The multithreaded network server example from the lectures can form the basis of crackserver. 366 5. Use the provided library functions (see above). 367 6. Consider a dedicated signal handling thread for SIGHUP. pthread_sigmask() can be used to mask signal 368 delivery to threads, and sigwait() can be used in a thread to block until a signal is received. You will 369 need to do some research and experimentation to get this working. Be sure to properly reference any code 370 samples or inspiration you find online or via generative AI such as ChatGPT. 371 Possible Approach 372 1. Try implementing crackclient first. (The programs are independent so this is not a requirement, but when 373 you test it with demo-crackserver it may give you a better understanding of how crackserver works.) 374 2. For crackserver, try writing a simple non-networked cracking program first to ensure you understand 375 the algorithm and use of libcrypt. 376 3. Once you can do single threaded cracking, work out how to split it across multiple threads. 377 4. Finally, integrate your cracking algorithm into the multi-threaded network server. 378 Forbidden Functions 379 You must not use any of the following C statements/directives/etc. If you do so, you will get zero (0) marks for 380 the assignment. 381 • goto 382 • #pragma 383 • gcc attributes 384 You must not use any of the following C functions. If you do so, you will get zero (0) marks for any test case 385 that calls the function. 386 • longjmp() and equivalent functions 387 • system() 388 • mkfifo() or mkfifoat() 389 • fork(), pipe(), popen(), execl(), execvp() and other exec family members. 390 • pthread_cancel() 391 Submission 392 Your submission must include all source and any other required files (in particular you must submit a Makefile). 393 Do not submit compiled files (eg .o, compiled programs) or test files. 394 Your programs (named crackclient and crackserver ) must build on moss.labs.eait.uq.edu.au with: 395 make 396 If you only implement one of the programs then it is acceptable for make to just build that program – and 397 we will only test that program. 398 Your programs must be compiled with gcc with at least the following switches (plus applicable -I options 399 etc. – see Provided Libraries above): 400 -pedantic -Wall -std=gnu99 401 You are not permitted to disable warnings or use pragmas or other methods to hide them. You may not use 402 source files other than .c and .h files as part of the build process – such files will be removed before building 403 your program. 404 12 Version 1.0 If any errors result from the make command (e.g. an executable can not be created) then you will receive 405 0 marks for functionality (see below). Any code without academic merit will be removed from your program 406 before compilation is attempted (and if compilation fails, you will receive 0 marks for functionality). 407 Your program must not invoke other programs or use non-standard headers/libraries (besides those we have 408 provided for you to use). 409 Your assignment submission must be committed to your subversion repository under 410 https://source.eait.uq.edu.au/svn/csse2310-sem1-sXXXXXXX/trunk/a4 411 where sXXXXXXX is your moss/UQ login ID. Only files at this top level will be marked so do not put source 412 files in subdirectories. You may create subdirectories for other purposes (e.g. your own test files) but these 413 will not be considered in marking – they will not be checked out of your repository. 414 You must ensure that all files needed to compile and use your assignment (including a Makefile) are commit- 415 ted and within the trunk/a4 directory in your repository (and not within a subdirectory) and not just sitting 416 in your working directory. Do not commit compiled files or binaries. You are strongly encouraged to check out 417 a clean copy for testing purposes – the reptesta4.sh script will do this for you. 418 To submit your assignment, you must run the command 419 2310createzip a4 420 on moss and then submit the resulting zip file on Blackboard (a GradeScope submission link will be made 421 available in the Assessment area on the CSSE2310/7231 Blackboard site)4. The zip file will be named 422 sXXXXXXX_csse2310_a4_timestamp.zip 423 where sXXXXXXX is replaced by your moss/UQ login ID and timestamp is replaced by a timestamp indicating 424 the time that the zip file was created. 425 The 2310createzip tool will check out the latest version of your assignment from the Subversion repository, 426 ensure it builds with the command ‘make’, and if so, will create a zip file that contains those files and your 427 Subversion commit history and a checksum of the zip file contents. You may be asked for your password as part 428 of this process in order to check out your submission from your repository. 429 You must not create the zip file using some other mechanism and you must not modify the zip file prior 430 to submission. If you do so, you will receive zero marks. Your submission time will be the time that the file 431 is submitted via GradeScope on Blackboard, and not the time of your last repository commit nor the time of 432 creation of your submission zip file. 433 We will mark your last submission, even if that is after the deadline and you made submissions before the 434 deadline. Any submissions after the deadline5 will incur a late penalty – see the CSSE2310/7231 course profile 435 for details. 436 Note that Gradescope will run the test suite immediately after you submit. When complete6 you will be 437 able to see the results of the “public” tests. 438 Marks 439 Marks will be awarded for functionality and style and documentation. Marks may be reduced if you are asked 440 to attend an interview about your assignment and you are unable to adequately respond to questions – see the 441 Student conduct section above. 442 Functionality (60 marks CSSE2310/ 70 marks CSSE7231) 443 Provided your code compiles (see above) and does not use any prohibited statements/functions (see above), 444 and your zip file has not been modified prior to submission, then you will earn functionality marks based on 445 the number of features your program correctly implements, as outlined below. Partial marks will be awarded 446 for partially meeting the functionality requirements. Not all features are of equal difficulty. If your program 447 does not allow a feature to be tested then you will receive 0 marks for that feature, even if you 448 claim to have implemented it. Reasonable time limits will be applied to all tests. If your program takes longer 449 4You may need to use scp or a graphical equivalent such as WinSCP, Filezilla or Cyberduck in order to download the zip file to your local computer and then upload it to the submission site. 5or your extended deadline if you are granted an extension. 6Gradescope marking may take only a few minutes or more than 30 minutes depending on the functionality/efficiency of your code. 13 Version 1.0 than this limit, then it will be terminated and you will earn no marks for the functionality associated with that 450 test. 451 Exact text matching of files and output (stdout and stderr) and communication messages is 452 used for functionality marking. Strict adherence to the formats in this specification is critical to 453 earn functionality marks. 454 The markers will make no alterations to your code (other than to remove code without academic merit). 455 Note that your client and server will be tested independently. 456 Marks will be assigned in the following categories. There are 10 marks for crackclient and 50 marks (CSSE2310) 457 or 60 marks (CSSE7231) for crackserver . 458 1. crackclient correctly handles invalid command lines (2 marks) 459 2. crackclient connects to server and also handles inability to connect to server (2 marks) 460 3. crackclient correctly handles input from stdin or a job file (2 marks) 461 4. crackclient correctly displays lines received from the server and sends input lines 462 to the server (2 marks) 463 5. crackclient correctly handles communication failure and EOF on stdin (2 marks) 464 6. crackserver correctly handles invalid command lines (3 marks) 465 7. crackserver correctly listens for connections and reports the port 466 (including inability to listen for connections) (3 marks) 467 8. crackserver correctly handles invalid command messages (5 marks) 468 9. crackserver correctly handles single-threaded crack requests (with at most 469 one client connected at a time) (5 marks) 470 10. crackserver correctly handles multi-threaded crack requests (with at most 471 one client connected at a time) (5 marks) 472 11. crackserver correctly handles crypt requests (with at most one client connected 473 at a time) (4 marks) 474 12. crackserver correctly handles multiple simultaneous client connections (using threads) (8 marks) 475 13. crackserver correctly handles disconnecting clients and communication failure (3 marks) 476 14. crackserver correctly implements client connection limiting (4 marks) 477 15. crackserver correctly implements early termination of threads when a match is found (3 marks) 478 16. crackserver correctly implements SIGHUP statistics reporting (including protecting 479 data structures with mutexes or semaphores) (7 marks) 480 17. (CSSE7231 only) crackserver correctly listens on the port specified by A4_HTTP_PORT 481 (and handles inability to listen or environment variable not set) (3 marks) 482 18. (CSSE7231 only) crackserver correctly responds to HTTP requests (including invalid requests) 483 from a single client issuing one request per connection (4 marks) 484 19. (CSSE7231 only) crackserver supports multiple simultaneous HTTP clients and multiple 485 sequential requests over each connection (3 marks) 486 Some functionality may be assessed in multiple categories. The ability to support multiple simultaneous clients 487 will be covered in multiple categories (12 to 16). 488 14 Version 1.0 Style Marking 489 Style marking is based on the number of style guide violations, i.e. the number of violations of version 2.3 of 490 the CSSE2310/CSSE7231 C Programming Style Guide (found on Blackboard). Style marks will be made up of 491 two components – automated style marks and human style marks. These are detailed below. 492 You should pay particular attention to commenting so that others can understand your code. The marker’s 493 decision with respect to commenting violations is final – it is the marker who has to understand your code. To 494 satisfy layout related guidelines, you may wish to consider the indent(1) tool. Your style marks can never be 495 more than your functionality mark – this prevents the submission of well styled programs which don’t meet at 496 least a minimum level of required functionality. 497 You are encouraged to use the style.sh tool installed on moss to style check your code before submission. 498 This does not check all style requirements, but it will determine your automated style mark (see below). Other 499 elements of the style guide are checked by humans. 500 All .c and .h files in your submission will be subject to style marking. This applies whether they are 501 compiled/linked into your executable or not7. 502 Automated Style Marking (5 marks) 503 Automated style marks will be calculated over all of your .c and .h files as follows. If any of your submitted 504 .c and/or .h files are unable to be compiled by themselves then your automated style mark will be zero (0). 505 (Automated style marking can only be undertaken on code that compiles. The provided style.sh script checks 506 this for you.) 507 If your code does compile then your automated style mark will be determined as follows: Let 508 • W be the total number of distinct compilation warnings recorded when your .c files are individually built 509 (using the correct compiler arguments) 510 • A be the total number of style violations detected by style.sh when it is run over each of your .c and 511 .h files individually8. 512 Your automated style mark S will be 513 S = 5− (W +A) 514 If W +A ≥ 5 then S will be zero (0) – no negative marks will be awarded. Note that in some cases style.sh 515 may erroneously report style violations when correct style has been followed. If you believe that you have been 516 penalised incorrectly then please bring this to the attention of the course coordinator and your mark can be 517 updated if this is the case. Note also that when style.sh is run for marking purposes it may detect style 518 errors not picked up when you run style.sh on moss. This will not be considered a marking error – it is your 519 responsibility to ensure that all of your code follows the style guide, even if styling errors are not detected 520 in some runs of style.sh. You can check the result of Gradescope style marking soon after your Gradescope 521 submission – when its test suite completes running. 522 Human Style Marking (5 marks) 523 The human style mark (out of 5 marks) will be based on the criteria/standards below for “comments”, “naming” 524 and “other”. The meanings of words like appropriate and required are determined by the requirements in the 525 style guide. Note that functions longer than 50 lines will be penalised in the automated style marking. Functions 526 that are also longer than 100 lines will be further penalised here. 527 7Make sure you remove any unneeded files from your repository, or they will be subject to style marking. 8Every .h file in your submission must make sense without reference to any other files, e.g., it must #include any .h files that contain declarations or definitions used in that .h file. 15 Version 1.0 Comments (2.5 marks) 528 Mark Description 0 The majority (50%+) of comments present are inappropriate OR there are many required commentsmissing 0.5 The majority of comments present are appropriate AND the majority of required comments arepresent 1.0 The vast majority (80%+) of comments present are appropriate AND there are at most a few missingcomments 1.5 All or almost all comments present are appropriate AND there are at most a few missing comments 2.0 Almost all comments present are appropriate AND there are no missing comments 2.5 All comments present are appropriate AND there are no missing comments 529 Naming (1 mark) 530 Mark Description 0 At least a few names used are inappropriate 0.5 Almost all names used are appropriate 1.0 All names used are appropriate 531 Other (1.5 marks) 532 Mark Description 0 One or more functions is longer than 100 lines of code OR there is more than one global/static variable present inappropriately OR there is a global struct variable present inappropriately OR there are more than a few instances of poor modularity (e.g. repeated code) 0.5 All functions are 100 lines or shorter AND there is at most one inappropriate non-struct global/staticvariable AND there are at most a few instances of poor modularity 1.0 All functions are 100 lines or shorter AND there are no instances of inappropriate global/static variables AND there is no or very limited use of magic numbers AND there is at most one instance or poor modularity 1.5 All functions are 100 lines or shorter AND there are no instances of inappropriate global/staticvariables AND there is no use of magic numbers AND there are no instances of poor modularity 533 SVN Commit History Marking (5 marks) 534 Markers will review your SVN commit history for your assignment up to your submission time. This element 535 will be graded according to the following principles: 536 • Appropriate use and frequency of commits (e.g. a single monolithic commit of your entire assignment will 537 yield a score of zero for this section) 538 • Appropriate use of log messages to capture the changes represented by each commit. (Meaningful messages 539 explain briefly what has changed in the commit (e.g. in terms of functionality) and/or why the change 540 has been made and will be usually be more detailed for significant changes.) 541 The standards expected are outlined in the following rubric: 542 Mark (out of 5) Description 0 Minimal commit history – only one or two commits ORall commit messages are meaningless. 1 Some progressive development evident (three or more commits) ANDat least one commit message is meaningful. 2 Progressive development is evident (multiple commits) ANDat least half the commit messages are meaningful. 3 Multiple commits that show progressive development of ALL functionality (e.g. no large com-mits with multiple features in them) AND at least half the commit messages are meaningful. 4 Multiple commits that show progressive development of ALL functionality ANDmeaningful messages for all but one or two of the commits. 5 Multiple commits that show progressive development of ALL functionality ANDmeaningful messages for ALL commits. 543 16 Version 1.0 Total Mark 544 Let 545 • F be the functionality mark for your assignment (out of 60 for CSSE2310 students or out of 70 for 546 CSSE7231 students). 547 • S be the automated style mark for your assignment (out of 5). 548 • H be the human style mark for your assignment (out of 5). 549 • C be the SVN commit history mark (out of 5). 550 • V is the scaling factor (0 to 1) determined after interview(s) (if applicable – see the Student Conduct 551 section above) – or 0 if you fail to attend a scheduled interview without having evidence of exceptional 552 circumstances impacting your ability to attend. 553 Your total mark for the assignment will be: 554 M = (F + min{F, S +H} + min{F,C})× V 555 out of 75 (for CSSE2310 students) or out of 85 (for CSSE7231 students). 556 In other words, you can’t get more marks for style or SVN commit history than you do for functionality. 557 Pretty code that doesn’t work will not be rewarded! 558 Late Penalties 559 Late penalties will apply as outlined in the course profile. 560 Specification Updates 561 Any errors or omissions discovered in the assignment specification will be added here, and new versions released 562 with adequate time for students to respond prior to due date. Potential specification errors or omissions can be 563 discussed on the discussion forum or emailed to csse2310@uq.edu.au. 564 17 Version 1.0 学霸联盟