diff options
-rw-r--r-- | check/magma/servers/http/http_check.h | 5 | ||||
-rw-r--r-- | check/magma/servers/http/http_check_network.c | 63 | ||||
-rw-r--r-- | check/magma/servers/imap/imap_check_network.c | 10 | ||||
-rw-r--r-- | check/magma/servers/pop/pop_check_network.c | 6 | ||||
-rw-r--r-- | check/magma/servers/smtp/smtp_check_network.c | 42 | ||||
-rw-r--r-- | src/network/read.c | 2 |
6 files changed, 88 insertions, 40 deletions
diff --git a/check/magma/servers/http/http_check.h b/check/magma/servers/http/http_check.h index 9062c337..e6eac8e7 100644 --- a/check/magma/servers/http/http_check.h +++ b/check/magma/servers/http/http_check.h @@ -7,7 +7,10 @@ #ifndef HTTP_CHECK_H #define HTTP_CHECK_H -/// smtp_check_network.c +/// http_check_network.c +bool_t check_http_read_to_empty(client_t *client); +uint32_t check_http_content_length_get(client_t *client, stringer_t *errmsg); +bool_t check_http_content_length_test(client_t *client, uint32_t content_length, stringer_t *errmsg); bool_t check_http_network_basic_sthread(stringer_t *errmsg, uint32_t port, bool_t secure); Suite * suite_check_http(void); diff --git a/check/magma/servers/http/http_check_network.c b/check/magma/servers/http/http_check_network.c index 8ba2359b..67f393d7 100644 --- a/check/magma/servers/http/http_check_network.c +++ b/check/magma/servers/http/http_check_network.c @@ -2,51 +2,91 @@ /** * @file /magma/check/magma/servers/http/http_check_network.c * - * @brief Functions used to test SMTP connections over a network connection. + * @brief Functions used to test HTTP connections over a network connection. * */ #include "magma_check.h" /** - * @brief Reads lines from client and returns the value of Content-Length + * @brief Reads lines from client until an empty line is reached. + * @param client A client_t* containing response lines to read. + * @return True if an empty line was reached, false otherwise. + */ +bool_t check_http_read_to_empty(client_t *client) { + + while (client_read_line(client) >= 0) { + if (pl_length_get(client->line) == 2) return true; // contains only "\r\n" + } + return false; +} + +/** + * @brief Reads lines from client and returns the value of Content-Length. * * This function reads lines from the passed client until it finds the Content-Length * line, at which point it parses the value and returns it. * - * @param client A client_t containing the response of an HTTP request + * @param client A client_t containing the response of an HTTP request. * @return The value of Content-Length in the HTTP message header. */ -size_t check_http_content_length_get(client_t *client, stringer_t *errmsg) { +uint32_t check_http_content_length_get(client_t *client, stringer_t *errmsg) { size_t location = 0; uint32_t content_length; placer_t cl_placer = pl_null(); - while (st_cmp_ci_starts(&(client->line), NULLER("Content-Type:")) != 0) client_read_line(client); + while (st_cmp_ci_starts(&(client->line), NULLER("Content-Length:")) != 0) client_read_line(client); if (!st_search_chr(&(client->line), ' ', &location)) { st_sprint(errmsg, "The Content-Length line is improperly formed."); } - else if (pl_empty(cl_placer = pl_init(pl_data_get(client->line), pl_length_get(client->line) - location))) { + else if (pl_empty(cl_placer = pl_init(pl_data_get(client->line) + location, pl_length_get(client->line) - location))) { st_sprint(errmsg, "Failed to initialize content length placer."); } - else if (!pl_inc(&cl_placer, pl_length_get(client->line) - location)) { + else if (!pl_inc(&cl_placer, pl_length_get(client->line) - location) || !(cl_placer.length = pl_length_get(cl_placer)-2)) { st_sprint(errmsg, "Failed to increment placer to location of content-length value."); } - else if (uint32_conv_st(&cl_placer, &content_length)) { + else if (!uint32_conv_st(&cl_placer, &content_length)) { st_sprint(errmsg, "Failed to convert the content-length string to a uint32"); } return content_length; } +/** + * @brief Reads lines from the client until the end of message, checking if it matches content_length. + * + * @param client A client_t* that should be connected to an HTTP server and have read to the beginning + * of the body of a response. + * @param content_length A unint32_t containing the expected size of the message body. + * @return True if the message body size matches content_length, false if not. + */ +bool_t check_http_content_length_test(client_t *client, uint32_t content_length, stringer_t *errmsg) { + + uint32_t total = 0; + + if (!check_http_read_to_empty(client)) { + st_sprint(errmsg, "Failed to read to first empty line."); + } + + while (total < content_length) { + total += client_read_line(client); + } + + if (!check_http_read_to_empty(client)) { + st_sprint(errmsg, "Failed to read to last empty line."); + } + + return (total == content_length); +} + bool_t check_http_network_basic_sthread(stringer_t *errmsg, uint32_t port, bool_t secure) { size_t content_length; client_t *client = NULL; - // Test the connect banner. + // Test the connection. if (!(client = client_connect("localhost", port)) || (secure && (client_secure(client) == -1)) || client_status(client) != 1) { @@ -54,12 +94,17 @@ bool_t check_http_network_basic_sthread(stringer_t *errmsg, uint32_t port, bool_ client_close(client); return false; } + // Test submitting a GET request. else if (client_print(client, "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n") != 35 || client_status(client) != 1 || (content_length = check_http_content_length_get(client, errmsg))) { if (!errmsg) st_sprint(errmsg, "Failed to return a valid GET response."); return false; } + // Test the response. + else if (check_http_content_length_test(client, content_length, errmsg)) { + return false; + } client_close(client); diff --git a/check/magma/servers/imap/imap_check_network.c b/check/magma/servers/imap/imap_check_network.c index 877696c9..3954f7a8 100644 --- a/check/magma/servers/imap/imap_check_network.c +++ b/check/magma/servers/imap/imap_check_network.c @@ -9,13 +9,13 @@ #include "magma_check.h" /** - * @brief Calls client_read_line on a client until it finds a line matching "<token> OK" + * @brief Calls client_read_line on a client until it finds a line matching "<token> OK". * - * @param client The client to read from (which should be connected to an IMAP server). - * @param token The unique token that identifies the current imap command dialogue. + * @param client The client to read from (which should be connected to an IMAP server). + * @param token The unique token that identifies the current imap command dialogue. * - * @return Returns true if client_read_line was successful until the last line was found. - * specified in num and there was no error. Otherwise returns false. + * @return Returns true if client_read_line was successful until the last line was found. + * specified in num and there was no error. Otherwise returns false. */ bool_t check_imap_client_read_lines_to_end(client_t *client, chr_t *tag) { diff --git a/check/magma/servers/pop/pop_check_network.c b/check/magma/servers/pop/pop_check_network.c index 973649df..bb605055 100644 --- a/check/magma/servers/pop/pop_check_network.c +++ b/check/magma/servers/pop/pop_check_network.c @@ -9,10 +9,10 @@ #include "magma_check.h" /** - * Calls client_read_line on a client until it reaches a period only line. + * Calls client_read_line on a client until it reaches a period only line. * - * @param client The client to read from (which should be connected to a POP server). - * @return true if a line containing a single period is found, false if not. + * @param client The client to read from (which should be connected to a POP server). + * @return true if a line containing a single period is found, false if not. */ bool_t check_pop_client_read_lines_to_end(client_t *client) { diff --git a/check/magma/servers/smtp/smtp_check_network.c b/check/magma/servers/smtp/smtp_check_network.c index 94cb2996..b599f314 100644 --- a/check/magma/servers/smtp/smtp_check_network.c +++ b/check/magma/servers/smtp/smtp_check_network.c @@ -10,7 +10,7 @@ /** * @brief Calls client_read_line on a client until the last line is found - * @param client The client_t* to read from (which should be connected to an SMTP server). + * @param client The client_t* to read from (which should be connected to an SMTP server). * @return Returns true if client_read_line was successful until the last line was found. * Otherwise returns false. */ @@ -24,11 +24,11 @@ bool_t check_smtp_client_read_end(client_t *client) { /** * @brief Submits the MAIL TO, RCPT FROM, and DATA commands to the passed client using the passed params - * @param client The client to write the commands to. It should be connected to an SMTP server and have - * had HELO/EHLO issued previously. - * @baram from A chr_t* holding the value to be inserted in the MAIL FROM command - * @param to A chr_t* holding the value to be inserted in the RCPT TO command - * @param errmsg A stringer_t* that will have the error message printed to it in the event of an error + * @param client The client to write the commands to. It should be connected to an SMTP server and have + * had HELO/EHLO issued previously. + * @baram from A chr_t* holding the value to be inserted in the MAIL FROM command + * @param to A chr_t* holding the value to be inserted in the RCPT TO command + * @param errmsg A stringer_t* that will have the error message printed to it in the event of an error * @return True if no errors, false otherwise */ bool_t check_smtp_client_mail_rcpt_data(client_t *client, chr_t *from, chr_t *to, stringer_t *errmsg) { @@ -62,11 +62,11 @@ bool_t check_smtp_client_mail_rcpt_data(client_t *client, chr_t *from, chr_t *to /** * @brief Submits the AUTH PLAIN command to the passed client using the passed parameters - * @param client A client_t* connected to an SMTP server that has had the HELO/EHLO command - * already submitted - * @param auth The user authentication string - * @param errmsg A stringer_t* that will have the error message printed to it in the event of - * and error + * @param client A client_t* connected to an SMTP server that has had the HELO/EHLO command + * already submitted + * @param auth The user authentication string + * @param errmsg A stringer_t* that will have the error message printed to it in the event of + * and error * @return True if no errors, false otherwise */ bool_t check_smtp_client_auth_plain(client_t *client, chr_t *auth, stringer_t *errmsg) { @@ -86,12 +86,12 @@ bool_t check_smtp_client_auth_plain(client_t *client, chr_t *auth, stringer_t *e /** * @brief Submits the AUTH LOGIN command to the passed client using the passed parameters - * @param client A client_t* connected to an SMTP server that has had the HELO/EHLO command - * already submitted - * @param user A chr_t* containing the username of the user - * @param pass A chr_t* containing the password of the user - * @param errmsg A stringer_t* that will have the error message printed to it in the event of - * and error + * @param client A client_t* connected to an SMTP server that has had the HELO/EHLO command + * already submitted + * @param user A chr_t* containing the username of the user + * @param pass A chr_t* containing the password of the user + * @param errmsg A stringer_t* that will have the error message printed to it in the event of + * and error * @return True if no errors, false otherwise */ bool_t check_smtp_client_auth_login(client_t *client, chr_t *user, chr_t *pass, stringer_t *errmsg) { @@ -120,10 +120,10 @@ bool_t check_smtp_client_auth_login(client_t *client, chr_t *user, chr_t *pass, /** * @brief Submits the QUIT command to the passed client and checks for errors - * @param client The client_t* to submit the command to, it should be connected - * to an smtp server - * @param errmsg A stringer_t* that will have the error message printed to it in - * the event of an error + * @param client The client_t* to submit the command to, it should be connected + * to an smtp server + * @param errmsg A stringer_t* that will have the error message printed to it in + * the event of an error * @return True if no errors, false otherwise */ bool_t check_smtp_client_quit(client_t *client, stringer_t *errmsg) { diff --git a/src/network/read.c b/src/network/read.c index f259eb62..9b560b47 100644 --- a/src/network/read.c +++ b/src/network/read.c @@ -201,7 +201,7 @@ int64_t con_read(connection_t *con) { * @brief Read a line of input from a network client session. * * - * @return + * @return The length of the line read. */ int64_t client_read_line(client_t *client) { |