From 86d9094ccadc4d75e296d836d0946627ed29fe83 Mon Sep 17 00:00:00 2001 From: Carpentier Pierre-Francois Date: Fri, 12 Apr 2019 15:51:57 +0200 Subject: [PATCH 1/8] Update README.rst --- README.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.rst b/README.rst index 8f45419..eee3b8a 100644 --- a/README.rst +++ b/README.rst @@ -27,6 +27,11 @@ Micro `RFC 3161 Time-Stamp `_ server writt ---- +Demo +---- + +A demo is accessible here: https://uts-server.kakwalab.ovh/ + License ------- From 4975f90af65ffdf90c3ec9301c0eb64f5a5eba13 Mon Sep 17 00:00:00 2001 From: kakwa Date: Wed, 7 Apr 2021 15:23:54 +0200 Subject: [PATCH 2/8] fixing compilation errors and warnings --- inc/utils.h | 4 ---- src/lib/http.c | 3 +++ src/lib/rfc3161.c | 2 +- src/lib/utils.c | 4 ++++ 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/inc/utils.h b/inc/utils.h index a18e6bb..3b90e3f 100644 --- a/inc/utils.h +++ b/inc/utils.h @@ -18,7 +18,3 @@ int set_params(rfc3161_context *ct, char *conf_file, char *conf_wd); static char *rand_string(char *str, size_t size); void free_uts_context(rfc3161_context *ct); const char *null_undef(const char *in); - -// some global variable to handle signals -int g_uts_sig_up; -int g_uts_sig; diff --git a/src/lib/http.c b/src/lib/http.c index 60c2915..ea402e9 100644 --- a/src/lib/http.c +++ b/src/lib/http.c @@ -9,6 +9,9 @@ #include #include +extern int g_uts_sig_up; +extern int g_uts_sig; + static char *rand_string(char *str, size_t size) { const char charset[] = "1234567890ABCDEF"; if (size) { diff --git a/src/lib/rfc3161.c b/src/lib/rfc3161.c index e8b6865..3cf0cb2 100644 --- a/src/lib/rfc3161.c +++ b/src/lib/rfc3161.c @@ -269,7 +269,7 @@ int create_response(rfc3161_context *ct, char *query, int query_len, BN_free(serial_bn); } else { serial_hex = calloc(SERIAL_ID_SIZE, sizeof(char)); - strncpy(serial_hex, " NO ID ", SERIAL_ID_SIZE + 2); + strncpy(serial_hex, " NO ID ", SERIAL_ID_SIZE + 4); } #endif #ifdef OPENSSL_API_1_0 diff --git a/src/lib/utils.c b/src/lib/utils.c index cb18d66..5543c5b 100644 --- a/src/lib/utils.c +++ b/src/lib/utils.c @@ -12,6 +12,10 @@ #include #include +// some global variable to handle signals +int g_uts_sig_up; +int g_uts_sig; + static void signal_handler_general(int sig_num) { g_uts_sig = sig_num; } From c7b3f4732514b2a3bc8e1d5023c58a94f006568b Mon Sep 17 00:00:00 2001 From: kakwa Date: Wed, 7 Apr 2021 15:27:32 +0200 Subject: [PATCH 3/8] version bump --- CMakeLists.txt | 2 +- ChangeLog.rst | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 47f86ba..f86fbb6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ else () set (CMAKE_C_STANDARD 99) endif () -set(VERSION 0.2.0) +set(VERSION 0.2.1) option(DEBUG "compile with debug symbol" OFF) option(BUNDLE_CIVETWEB "bundle civetweb with uts-server" OFF) diff --git a/ChangeLog.rst b/ChangeLog.rst index b5afea4..4cb1789 100644 --- a/ChangeLog.rst +++ b/ChangeLog.rst @@ -1,6 +1,11 @@ Changelogs ========== +0.2.1 +----- + +* [fix ] fix compilation for newer GCC (>10.2) (global variable definition issue + 0.2.0 ----- From d3c6ab383ea2ca7345ec37c5d4ab422038f44a48 Mon Sep 17 00:00:00 2001 From: Joao Alves Date: Wed, 22 Sep 2021 08:50:49 +0100 Subject: [PATCH 4/8] Correction to static page length. Correction to static page HTML. Return 404 for favicon.ico. --- inc/http_staticpage.h | 117 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 inc/http_staticpage.h diff --git a/inc/http_staticpage.h b/inc/http_staticpage.h new file mode 100644 index 0000000..9ef05d2 --- /dev/null +++ b/inc/http_staticpage.h @@ -0,0 +1,117 @@ +const char *content_static_page = \ + "" \ + "" \ + "" \ + " " \ + " uts-server" \ + " " \ + " " \ + "" \ + "" \ + "" \ + "
" \ + " uts-server, a simple RFC 3161 timestamp server" \ + "
" \ + "
" \ + " For timestamping a file with OpenSSL and curl, run the following " \ + "commands" \ + " (setting the $UTS_SERVER_URL, $FILE and $FILE_TIMESTAMP variables):" \ + "
" \ + " openssl ts -query -data \"$FILE\" -out " \ + "\"ts_req.ts\";
" \ + " curl \"$UTS_SERVER_URL\" \\
" \ + "      -H \"Content-Type: " \ + "application/timestamp-query\" \\
" \ + "      -f -g --data-binary \"@ts_req.ts\" -o " \ + "\"$FILE_TIMESTAMP\"" \ + "
" \ + " For verifying the timestamp with OpenSSL, download the CA and the " \ + "signer cert, and run the following command:" \ + "
" \ + " openssl ts -verify -in \"$FILE_TIMESTAMP\" \\
" \ + "      -data \"$FILE\" " \ + "-CAfile ca.pem -untrusted tsa_cert.pem" \ + "
" \ + " " \ + "
" \ + "
" \ + "
" \ + " uts-server" \ + " • © 2019 • Pierre-François Carpentier • Released under the MIT " \ + "License" \ + "
" \ + "
" \ + "" \ + ""; From 84afefe39bbc65f4c8a9a89f6ebdc94b8ae88f24 Mon Sep 17 00:00:00 2001 From: Joao Alves Date: Wed, 22 Sep 2021 08:52:57 +0100 Subject: [PATCH 5/8] Correction to static page length. Correction to static page HTML. Return 404 for favicon.ico. --- inc/http.h | 122 ------------------------------------------------- src/lib/http.c | 22 ++++++++- 2 files changed, 21 insertions(+), 123 deletions(-) diff --git a/inc/http.h b/inc/http.h index ed2c7bd..e89e902 100644 --- a/inc/http.h +++ b/inc/http.h @@ -6,125 +6,3 @@ struct tuser_data { }; int http_server_start(char *conffile, char *conf_wd, bool stdout_dbg); - -#define STATIC_PAGE \ - "HTTP/1.1 200 OK\r\n" \ - "Content-Type: text/html\r\n" \ - "Content-Length: 2774\r\n" \ - "\r\n" \ - "" \ - "" \ - " " \ - " uts-server" \ - " " \ - " " \ - "" \ - "" \ - "" \ - "
" \ - " uts-server, a simple RFC 3161 timestamp server" \ - "
" \ - "
" \ - " For timestamping a file with OpenSSL and curl, run the following " \ - "commands" \ - " (setting the $UTS_SERVER_URL, $FILE and $FILE_TIMESTAMP variables):" \ - "
" \ - " openssl ts -query -data \"$FILE\" -out " \ - "\"ts_req.ts\";
" \ - " curl \"$UTS_SERVER_URL\" \\
" \ - "      -H \"Content-Type: " \ - "application/timestamp-query\" \\
" \ - "      -f -g --data-binary \"@ts_req.ts\" -o " \ - "\"$FILE_TIMESTAMP\"" \ - "
" \ - " For verifying the timestamp with OpenSSL, download the CA and the " \ - "signer cert, and run the following command:" \ - "
" \ - " openssl ts -verify -in \"$FILE_TIMESTAMP\" \\
" \ - "      -data \"$FILE\" " \ - "-CAfile ca.pem -untrusted tsa_cert.pem" \ - "
" \ - " " \ - "
" \ - "
" \ - "
" \ - " uts-server" \ - " • © 2019 • Pierre-François Carpentier • Released under the MIT " \ - "License" \ - "
" \ - "
" \ - "" \ - "" diff --git a/src/lib/http.c b/src/lib/http.c index ea402e9..ca810e8 100644 --- a/src/lib/http.c +++ b/src/lib/http.c @@ -8,6 +8,7 @@ #include #include #include +#include "http_staticpage.h" extern int g_uts_sig_up; extern int g_uts_sig; @@ -195,7 +196,17 @@ int rfc3161_handler(struct mg_connection *conn, void *context) { } else { // default reply if we don't have a time-stamp request resp_code = 200; - mg_printf(conn, STATIC_PAGE); + //char *content_static = calloc(4096, sizeof(char)); + //strncpy(content_static, STATIC_PAGE, 4096); + content_length = strlen(content_static_page); + mg_printf(conn, + "HTTP/1.1 200 OK\r\n" + "Content-Type: text/html\r\n" + "Content-Length: %d\r\n" + "\r\n", + (int)content_length); + mg_write(conn, content_static_page, content_length); + //free(content_static); } // initialize a serial_id if not created by create_response if (serial_id == NULL) { @@ -279,6 +290,14 @@ int cert_serve_handler(struct mg_connection *conn, void *context) { return 1; } +int notfound_handler(struct mg_connection *conn, void *context) { + /* In this handler, we ignore the req_info and send the file "filename". */ + const struct mg_request_info *request_info = mg_get_request_info(conn); + rfc3161_context *ct = (rfc3161_context *)context; + mg_send_http_error(conn, 404, ""); + return 1; +} + int http_server_start(char *conffile, char *conf_wd, bool stdout_dbg) { struct mg_context *ctx; struct mg_callbacks callbacks; @@ -305,6 +324,7 @@ int http_server_start(char *conffile, char *conf_wd, bool stdout_dbg) { ctx = mg_start(&callbacks, &user_data, ct->http_options); if (ctx != NULL) { mg_set_request_handler(ctx, "/", rfc3161_handler, (void *)ct); + mg_set_request_handler(ctx, "/favicon.ico", notfound_handler, (void *)ct); mg_set_request_handler(ctx, "/ca.pem", ca_serve_handler, (void *)ct); mg_set_request_handler(ctx, "/tsa_cert.pem", cert_serve_handler, (void *)ct); From b4ad63f96ecebbaa86619a701f81deadaecf3d54 Mon Sep 17 00:00:00 2001 From: Joao Alves Date: Wed, 22 Sep 2021 08:54:27 +0100 Subject: [PATCH 6/8] Removed commented code. --- http.c | 345 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 345 insertions(+) create mode 100644 http.c diff --git a/http.c b/http.c new file mode 100644 index 0000000..afabbd7 --- /dev/null +++ b/http.c @@ -0,0 +1,345 @@ +#include "http.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "http_staticpage.h" + +extern int g_uts_sig_up; +extern int g_uts_sig; + +static char *rand_string(char *str, size_t size) { + const char charset[] = "1234567890ABCDEF"; + if (size) { + --size; + for (size_t n = 0; n < size; n++) { + int key = rand() % (int)(sizeof charset - 1); + str[n] = charset[key]; + } + str[size] = '\0'; + } + return str; +} + +static char *sdup(const char *str) { + size_t len; + char *p; + + len = strlen(str) + 1; + if ((p = (char *)malloc(len)) != NULL) { + memcpy(p, str, len); + } + return p; +} + +static int log_civetweb(const struct mg_connection *conn, const char *message) { + const struct mg_context *ctx = mg_get_context(conn); + struct tuser_data *ud = (struct tuser_data *)mg_get_user_data(ctx); + + if (ud->first_message == NULL) { + ud->first_message = sdup(message); + } + + return 0; +} + +void log_request_debug(const struct mg_request_info *request_info, + char *request_id, rfc3161_context *context) { + if (LOG_DEBUG > context->loglevel && !context->stdout_dbg) + return; + + for (int i = 0; i < request_info->num_headers; i++) { + uts_logger(context, LOG_DEBUG, "Request[%s], Header[%s]: %s", + request_id, request_info->http_headers[i].name, + null_undef(request_info->http_headers[i].value)); + } + uts_logger(context, LOG_DEBUG, "Request[%s], request_method: %s", + request_id, null_undef(request_info->request_method)); + uts_logger(context, LOG_DEBUG, "Request[%s], request_uri: %s", request_id, + null_undef(request_info->request_uri)); + uts_logger(context, LOG_DEBUG, "Request[%s], local_uri: %s", request_id, + null_undef(request_info->local_uri)); + uts_logger(context, LOG_DEBUG, "Request[%s], http_version: %s", request_id, + null_undef(request_info->http_version)); + uts_logger(context, LOG_DEBUG, "Request[%s], query_string: %s", request_id, + null_undef(request_info->query_string)); + uts_logger(context, LOG_DEBUG, "Request[%s], remote_addr: %s", request_id, + null_undef(request_info->remote_addr)); + uts_logger(context, LOG_DEBUG, "Request[%s], is_ssl: %d", request_id, + request_info->is_ssl); + uts_logger(context, LOG_DEBUG, "Request[%s], content_length: %d", + request_id, request_info->content_length); + uts_logger(context, LOG_DEBUG, "Request[%s], remote_port: %d", request_id, + request_info->remote_port); +} + +void log_request(const struct mg_request_info *request_info, char *request_id, + rfc3161_context *context, int response_code, int timer) { + if (LOG_INFO > context->loglevel && !context->stdout_dbg) + return; + + const char *user_agent = NULL; + const char *content_type = NULL; + + for (int i = 0; i < request_info->num_headers; i++) { + if (strcasecmp(request_info->http_headers[i].name, "User-Agent") == 0) { + user_agent = request_info->http_headers[i].value; + } + if (strcasecmp(request_info->http_headers[i].name, "Content-Type") == + 0) { + content_type = request_info->http_headers[i].value; + } + } + + uts_logger(context, LOG_INFO, + "Request[%s], remote_addr[%s] ssl[%d] " + "uri[%s] http_resp_code[%d] duration[%d us] " + "user-agent[%s] content-type[%s]", + request_id, null_undef(request_info->remote_addr), + request_info->is_ssl, null_undef(request_info->local_uri), + response_code, timer, null_undef(user_agent), + null_undef(content_type)); +} + +int rfc3161_handler(struct mg_connection *conn, void *context) { + // some timer stuff + clock_t start = clock(), diff; + /* Handler may access the request info using mg_get_request_info */ + const struct mg_request_info *request_info = mg_get_request_info(conn); + rfc3161_context *ct = (rfc3161_context *)context; + int ret; + int resp_code; + ct->query_counter++; + uint64_t query_id = ct->query_counter; + + bool is_tsq = 0; + + // go through every headers to find Content-Type + // and check if it's set to "application/timestamp-query" + // if it's the case, set is_tsq (is time-stamp query) to True + for (int i = 0; i < request_info->num_headers; i++) { + const char *h_name = request_info->http_headers[i].name; + const char *h_value = request_info->http_headers[i].value; + if (strcasecmp(h_name, "Content-Type") == 0 && + strcasecmp(h_value, "application/timestamp-query") == 0) + is_tsq = 1; + } + + unsigned char *content = NULL; + size_t content_length = 0; + + char *serial_id = NULL; + + // Send HTTP reply to the client. + // + // If it's a time-stamp query. + if (is_tsq) { + // Recover query content from http request. + char *query = calloc(request_info->content_length, sizeof(char)); + int query_len = mg_read(conn, query, request_info->content_length); + + // Log the query as DEBUG log in hexadecimal format + log_hex(ct, LOG_DEBUG, "query hexdump content", (unsigned char *)query, + request_info->content_length); + // Get an OpenSSL TS_RESP_CTX (wrapped inside ts_resp_ctx_wrapper + // structure). + // get_ctxw recovers the first unused TS_RESP_CTX + // in the ct->ts_ctx_pool pool of TS_RESP_CTX. + // (TS_RESP_CTX are not thread safe) + ts_resp_ctx_wrapper *ctx_w = get_ctxw(ct); + if (ctx_w == NULL) { + resp_code = 500; + uts_logger(context, LOG_WARNING, + "Unable to get an OpenSSL ts_context in the pool"); + + } else { + // create the response + resp_code = create_response(ct, query, query_len, ctx_w->ts_ctx, + &content_length, &content, &serial_id); + // free the TS_RESP_CTX used + ctx_w->available = 1; + } + // respond according to create_response return code + switch (resp_code) { + case 200: + mg_printf(conn, + "HTTP/1.1 200 OK\r\n" + "Content-Type: application/timestamp-reply\r\n" + "Content-Length: %d\r\n" + "\r\n", + (int)content_length); + mg_write(conn, content, content_length); + log_hex(ct, LOG_DEBUG, "response hexdump content", content, + content_length); + break; + case 400: + mg_printf(conn, "HTTP/1.1 400 Bad Request\r\n" + "Content-Type: text/plain\r\n" + "Content-Length: 12\r\n" + "\r\n" + "client error"); + break; + default: + mg_printf(conn, "HTTP/1.1 500 Internal Server Error\r\n" + "Content-Type: text/plain\r\n" + "Content-Length: 17\r\n" + "\r\n" + "uts-server error"); + } + free(query); + free(content); + } else { + // default reply if we don't have a time-stamp request + content_length = strlen(content_static_page); + mg_printf(conn, + "HTTP/1.1 200 OK\r\n" + "Content-Type: text/html\r\n" + "Content-Length: %d\r\n" + "\r\n", + (int)content_length); + mg_write(conn, content_static_page, content_length); + } + // initialize a serial_id if not created by create_response + if (serial_id == NULL) { + serial_id = calloc(9, sizeof(char)); + serial_id = rand_string(serial_id, 8); + } + + // some debugging logs + log_request_debug(request_info, serial_id, ct); + // end of some timer stuff + diff = clock() - start; + // log the request + log_request(request_info, serial_id, ct, resp_code, + (diff * 1000000 / CLOCKS_PER_SEC)); + free(serial_id); + return 1; +} + +int ca_serve_handler(struct mg_connection *conn, void *context) { + /* In this handler, we ignore the req_info and send the file "filename". */ + const struct mg_request_info *request_info = mg_get_request_info(conn); + clock_t start = clock(), diff; + rfc3161_context *ct = (rfc3161_context *)context; + const char *filename = ct->ca_file; + if (strlen(filename) == 0) { + uts_logger(context, LOG_NOTICE, + "'certs' param in '[ tsa ]' section not filed"); + mg_send_http_error(conn, 404, "CA file not available"); + diff = clock() - start; + log_request(request_info, "CA_DL ", ct, 404, + (diff * 1000000 / CLOCKS_PER_SEC)); + return 1; + } + if (access(filename, F_OK) != -1) { + mg_send_file(conn, filename); + const struct mg_response_info *ri = mg_get_response_info(conn); + diff = clock() - start; + log_request(request_info, "CA_DL ", ct, 200, + (diff * 1000000 / CLOCKS_PER_SEC)); + + } else { + uts_logger(context, LOG_NOTICE, "CA file '%s' not available", filename); + mg_send_http_error(conn, 404, "CA file not available"); + diff = clock() - start; + log_request(request_info, "CA_DL ", ct, 404, + (diff * 1000000 / CLOCKS_PER_SEC)); + } + return 1; +} + +int cert_serve_handler(struct mg_connection *conn, void *context) { + /* In this handler, we ignore the req_info and send the file "filename". */ + const struct mg_request_info *request_info = mg_get_request_info(conn); + clock_t start = clock(), diff; + rfc3161_context *ct = (rfc3161_context *)context; + const char *filename = ct->cert_file; + if (strlen(filename) == 0) { + uts_logger(context, LOG_NOTICE, + "'signer_cert' param in '[ tsa ]' section not filed"); + mg_send_http_error(conn, 404, "CA file not available"); + diff = clock() - start; + log_request(request_info, "CERT_DL", ct, 404, + (diff * 1000000 / CLOCKS_PER_SEC)); + return 1; + } + if (access(filename, F_OK) != -1) { + mg_send_file(conn, filename); + const struct mg_response_info *ri = mg_get_response_info(conn); + diff = clock() - start; + log_request(request_info, "CERT_DL", ct, 200, + (diff * 1000000 / CLOCKS_PER_SEC)); + + } else { + uts_logger(context, LOG_NOTICE, + "signer certificate file '%s' not available", filename); + mg_send_http_error(conn, 404, "CA file not available"); + diff = clock() - start; + log_request(request_info, "CERT_DL", ct, 404, + (diff * 1000000 / CLOCKS_PER_SEC)); + } + return 1; +} + +int notfound_handler(struct mg_connection *conn, void *context) { + /* In this handler, we ignore the req_info and send the file "filename". */ + const struct mg_request_info *request_info = mg_get_request_info(conn); + rfc3161_context *ct = (rfc3161_context *)context; + mg_send_http_error(conn, 404, ""); + return 1; +} + +int http_server_start(char *conffile, char *conf_wd, bool stdout_dbg) { + struct mg_context *ctx; + struct mg_callbacks callbacks; + struct tuser_data user_data; + + rfc3161_context *ct = (rfc3161_context *)calloc(1, sizeof(rfc3161_context)); + ct->stdout_dbg = stdout_dbg; + ct->loglevel = 8; + init_ssl(); + if (!set_params(ct, conffile, conf_wd)) + return EXIT_FAILURE; + + // Disable stdout buffering if logging to stdout + if (ct->stdout_logging || ct->stdout_dbg) + setbuf(stdout, NULL); + + // Prepare callbacks structure. We have only one callback, the rest are + // NULL. + memset(&callbacks, 0, sizeof(callbacks)); + memset(&user_data, 0, sizeof(user_data)); + callbacks.log_message = &log_civetweb; + + // Start the web server. + ctx = mg_start(&callbacks, &user_data, ct->http_options); + if (ctx != NULL) { + mg_set_request_handler(ctx, "/", rfc3161_handler, (void *)ct); + mg_set_request_handler(ctx, "/favicon.ico", notfound_handler, (void *)ct); + mg_set_request_handler(ctx, "/ca.pem", ca_serve_handler, (void *)ct); + mg_set_request_handler(ctx, "/tsa_cert.pem", cert_serve_handler, + (void *)ct); + + // Wait until some signals are received + while (g_uts_sig == 0) { + sleep(1); + } + } else { + uts_logger(ct, LOG_ERR, "Failed to start uts-server: %s", + ((user_data.first_message == NULL) + ? "unknown reason" + : user_data.first_message)); + } + + // Stop the server. + mg_stop(ctx); + free_uts_context(ct); + free_ssl(); + + return 0; +} From 4c5e5b825197a63399b3116ac631e39040e35d00 Mon Sep 17 00:00:00 2001 From: Joao Alves Date: Wed, 22 Sep 2021 08:56:20 +0100 Subject: [PATCH 7/8] Moved file to proper location. --- http.c | 345 ------------------------------------------------- src/lib/http.c | 4 - 2 files changed, 349 deletions(-) delete mode 100644 http.c diff --git a/http.c b/http.c deleted file mode 100644 index afabbd7..0000000 --- a/http.c +++ /dev/null @@ -1,345 +0,0 @@ -#include "http.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "http_staticpage.h" - -extern int g_uts_sig_up; -extern int g_uts_sig; - -static char *rand_string(char *str, size_t size) { - const char charset[] = "1234567890ABCDEF"; - if (size) { - --size; - for (size_t n = 0; n < size; n++) { - int key = rand() % (int)(sizeof charset - 1); - str[n] = charset[key]; - } - str[size] = '\0'; - } - return str; -} - -static char *sdup(const char *str) { - size_t len; - char *p; - - len = strlen(str) + 1; - if ((p = (char *)malloc(len)) != NULL) { - memcpy(p, str, len); - } - return p; -} - -static int log_civetweb(const struct mg_connection *conn, const char *message) { - const struct mg_context *ctx = mg_get_context(conn); - struct tuser_data *ud = (struct tuser_data *)mg_get_user_data(ctx); - - if (ud->first_message == NULL) { - ud->first_message = sdup(message); - } - - return 0; -} - -void log_request_debug(const struct mg_request_info *request_info, - char *request_id, rfc3161_context *context) { - if (LOG_DEBUG > context->loglevel && !context->stdout_dbg) - return; - - for (int i = 0; i < request_info->num_headers; i++) { - uts_logger(context, LOG_DEBUG, "Request[%s], Header[%s]: %s", - request_id, request_info->http_headers[i].name, - null_undef(request_info->http_headers[i].value)); - } - uts_logger(context, LOG_DEBUG, "Request[%s], request_method: %s", - request_id, null_undef(request_info->request_method)); - uts_logger(context, LOG_DEBUG, "Request[%s], request_uri: %s", request_id, - null_undef(request_info->request_uri)); - uts_logger(context, LOG_DEBUG, "Request[%s], local_uri: %s", request_id, - null_undef(request_info->local_uri)); - uts_logger(context, LOG_DEBUG, "Request[%s], http_version: %s", request_id, - null_undef(request_info->http_version)); - uts_logger(context, LOG_DEBUG, "Request[%s], query_string: %s", request_id, - null_undef(request_info->query_string)); - uts_logger(context, LOG_DEBUG, "Request[%s], remote_addr: %s", request_id, - null_undef(request_info->remote_addr)); - uts_logger(context, LOG_DEBUG, "Request[%s], is_ssl: %d", request_id, - request_info->is_ssl); - uts_logger(context, LOG_DEBUG, "Request[%s], content_length: %d", - request_id, request_info->content_length); - uts_logger(context, LOG_DEBUG, "Request[%s], remote_port: %d", request_id, - request_info->remote_port); -} - -void log_request(const struct mg_request_info *request_info, char *request_id, - rfc3161_context *context, int response_code, int timer) { - if (LOG_INFO > context->loglevel && !context->stdout_dbg) - return; - - const char *user_agent = NULL; - const char *content_type = NULL; - - for (int i = 0; i < request_info->num_headers; i++) { - if (strcasecmp(request_info->http_headers[i].name, "User-Agent") == 0) { - user_agent = request_info->http_headers[i].value; - } - if (strcasecmp(request_info->http_headers[i].name, "Content-Type") == - 0) { - content_type = request_info->http_headers[i].value; - } - } - - uts_logger(context, LOG_INFO, - "Request[%s], remote_addr[%s] ssl[%d] " - "uri[%s] http_resp_code[%d] duration[%d us] " - "user-agent[%s] content-type[%s]", - request_id, null_undef(request_info->remote_addr), - request_info->is_ssl, null_undef(request_info->local_uri), - response_code, timer, null_undef(user_agent), - null_undef(content_type)); -} - -int rfc3161_handler(struct mg_connection *conn, void *context) { - // some timer stuff - clock_t start = clock(), diff; - /* Handler may access the request info using mg_get_request_info */ - const struct mg_request_info *request_info = mg_get_request_info(conn); - rfc3161_context *ct = (rfc3161_context *)context; - int ret; - int resp_code; - ct->query_counter++; - uint64_t query_id = ct->query_counter; - - bool is_tsq = 0; - - // go through every headers to find Content-Type - // and check if it's set to "application/timestamp-query" - // if it's the case, set is_tsq (is time-stamp query) to True - for (int i = 0; i < request_info->num_headers; i++) { - const char *h_name = request_info->http_headers[i].name; - const char *h_value = request_info->http_headers[i].value; - if (strcasecmp(h_name, "Content-Type") == 0 && - strcasecmp(h_value, "application/timestamp-query") == 0) - is_tsq = 1; - } - - unsigned char *content = NULL; - size_t content_length = 0; - - char *serial_id = NULL; - - // Send HTTP reply to the client. - // - // If it's a time-stamp query. - if (is_tsq) { - // Recover query content from http request. - char *query = calloc(request_info->content_length, sizeof(char)); - int query_len = mg_read(conn, query, request_info->content_length); - - // Log the query as DEBUG log in hexadecimal format - log_hex(ct, LOG_DEBUG, "query hexdump content", (unsigned char *)query, - request_info->content_length); - // Get an OpenSSL TS_RESP_CTX (wrapped inside ts_resp_ctx_wrapper - // structure). - // get_ctxw recovers the first unused TS_RESP_CTX - // in the ct->ts_ctx_pool pool of TS_RESP_CTX. - // (TS_RESP_CTX are not thread safe) - ts_resp_ctx_wrapper *ctx_w = get_ctxw(ct); - if (ctx_w == NULL) { - resp_code = 500; - uts_logger(context, LOG_WARNING, - "Unable to get an OpenSSL ts_context in the pool"); - - } else { - // create the response - resp_code = create_response(ct, query, query_len, ctx_w->ts_ctx, - &content_length, &content, &serial_id); - // free the TS_RESP_CTX used - ctx_w->available = 1; - } - // respond according to create_response return code - switch (resp_code) { - case 200: - mg_printf(conn, - "HTTP/1.1 200 OK\r\n" - "Content-Type: application/timestamp-reply\r\n" - "Content-Length: %d\r\n" - "\r\n", - (int)content_length); - mg_write(conn, content, content_length); - log_hex(ct, LOG_DEBUG, "response hexdump content", content, - content_length); - break; - case 400: - mg_printf(conn, "HTTP/1.1 400 Bad Request\r\n" - "Content-Type: text/plain\r\n" - "Content-Length: 12\r\n" - "\r\n" - "client error"); - break; - default: - mg_printf(conn, "HTTP/1.1 500 Internal Server Error\r\n" - "Content-Type: text/plain\r\n" - "Content-Length: 17\r\n" - "\r\n" - "uts-server error"); - } - free(query); - free(content); - } else { - // default reply if we don't have a time-stamp request - content_length = strlen(content_static_page); - mg_printf(conn, - "HTTP/1.1 200 OK\r\n" - "Content-Type: text/html\r\n" - "Content-Length: %d\r\n" - "\r\n", - (int)content_length); - mg_write(conn, content_static_page, content_length); - } - // initialize a serial_id if not created by create_response - if (serial_id == NULL) { - serial_id = calloc(9, sizeof(char)); - serial_id = rand_string(serial_id, 8); - } - - // some debugging logs - log_request_debug(request_info, serial_id, ct); - // end of some timer stuff - diff = clock() - start; - // log the request - log_request(request_info, serial_id, ct, resp_code, - (diff * 1000000 / CLOCKS_PER_SEC)); - free(serial_id); - return 1; -} - -int ca_serve_handler(struct mg_connection *conn, void *context) { - /* In this handler, we ignore the req_info and send the file "filename". */ - const struct mg_request_info *request_info = mg_get_request_info(conn); - clock_t start = clock(), diff; - rfc3161_context *ct = (rfc3161_context *)context; - const char *filename = ct->ca_file; - if (strlen(filename) == 0) { - uts_logger(context, LOG_NOTICE, - "'certs' param in '[ tsa ]' section not filed"); - mg_send_http_error(conn, 404, "CA file not available"); - diff = clock() - start; - log_request(request_info, "CA_DL ", ct, 404, - (diff * 1000000 / CLOCKS_PER_SEC)); - return 1; - } - if (access(filename, F_OK) != -1) { - mg_send_file(conn, filename); - const struct mg_response_info *ri = mg_get_response_info(conn); - diff = clock() - start; - log_request(request_info, "CA_DL ", ct, 200, - (diff * 1000000 / CLOCKS_PER_SEC)); - - } else { - uts_logger(context, LOG_NOTICE, "CA file '%s' not available", filename); - mg_send_http_error(conn, 404, "CA file not available"); - diff = clock() - start; - log_request(request_info, "CA_DL ", ct, 404, - (diff * 1000000 / CLOCKS_PER_SEC)); - } - return 1; -} - -int cert_serve_handler(struct mg_connection *conn, void *context) { - /* In this handler, we ignore the req_info and send the file "filename". */ - const struct mg_request_info *request_info = mg_get_request_info(conn); - clock_t start = clock(), diff; - rfc3161_context *ct = (rfc3161_context *)context; - const char *filename = ct->cert_file; - if (strlen(filename) == 0) { - uts_logger(context, LOG_NOTICE, - "'signer_cert' param in '[ tsa ]' section not filed"); - mg_send_http_error(conn, 404, "CA file not available"); - diff = clock() - start; - log_request(request_info, "CERT_DL", ct, 404, - (diff * 1000000 / CLOCKS_PER_SEC)); - return 1; - } - if (access(filename, F_OK) != -1) { - mg_send_file(conn, filename); - const struct mg_response_info *ri = mg_get_response_info(conn); - diff = clock() - start; - log_request(request_info, "CERT_DL", ct, 200, - (diff * 1000000 / CLOCKS_PER_SEC)); - - } else { - uts_logger(context, LOG_NOTICE, - "signer certificate file '%s' not available", filename); - mg_send_http_error(conn, 404, "CA file not available"); - diff = clock() - start; - log_request(request_info, "CERT_DL", ct, 404, - (diff * 1000000 / CLOCKS_PER_SEC)); - } - return 1; -} - -int notfound_handler(struct mg_connection *conn, void *context) { - /* In this handler, we ignore the req_info and send the file "filename". */ - const struct mg_request_info *request_info = mg_get_request_info(conn); - rfc3161_context *ct = (rfc3161_context *)context; - mg_send_http_error(conn, 404, ""); - return 1; -} - -int http_server_start(char *conffile, char *conf_wd, bool stdout_dbg) { - struct mg_context *ctx; - struct mg_callbacks callbacks; - struct tuser_data user_data; - - rfc3161_context *ct = (rfc3161_context *)calloc(1, sizeof(rfc3161_context)); - ct->stdout_dbg = stdout_dbg; - ct->loglevel = 8; - init_ssl(); - if (!set_params(ct, conffile, conf_wd)) - return EXIT_FAILURE; - - // Disable stdout buffering if logging to stdout - if (ct->stdout_logging || ct->stdout_dbg) - setbuf(stdout, NULL); - - // Prepare callbacks structure. We have only one callback, the rest are - // NULL. - memset(&callbacks, 0, sizeof(callbacks)); - memset(&user_data, 0, sizeof(user_data)); - callbacks.log_message = &log_civetweb; - - // Start the web server. - ctx = mg_start(&callbacks, &user_data, ct->http_options); - if (ctx != NULL) { - mg_set_request_handler(ctx, "/", rfc3161_handler, (void *)ct); - mg_set_request_handler(ctx, "/favicon.ico", notfound_handler, (void *)ct); - mg_set_request_handler(ctx, "/ca.pem", ca_serve_handler, (void *)ct); - mg_set_request_handler(ctx, "/tsa_cert.pem", cert_serve_handler, - (void *)ct); - - // Wait until some signals are received - while (g_uts_sig == 0) { - sleep(1); - } - } else { - uts_logger(ct, LOG_ERR, "Failed to start uts-server: %s", - ((user_data.first_message == NULL) - ? "unknown reason" - : user_data.first_message)); - } - - // Stop the server. - mg_stop(ctx); - free_uts_context(ct); - free_ssl(); - - return 0; -} diff --git a/src/lib/http.c b/src/lib/http.c index ca810e8..afabbd7 100644 --- a/src/lib/http.c +++ b/src/lib/http.c @@ -195,9 +195,6 @@ int rfc3161_handler(struct mg_connection *conn, void *context) { free(content); } else { // default reply if we don't have a time-stamp request - resp_code = 200; - //char *content_static = calloc(4096, sizeof(char)); - //strncpy(content_static, STATIC_PAGE, 4096); content_length = strlen(content_static_page); mg_printf(conn, "HTTP/1.1 200 OK\r\n" @@ -206,7 +203,6 @@ int rfc3161_handler(struct mg_connection *conn, void *context) { "\r\n", (int)content_length); mg_write(conn, content_static_page, content_length); - //free(content_static); } // initialize a serial_id if not created by create_response if (serial_id == NULL) { From 9b49e5578ff76b5abba07ea75f2e5c60a6d0f958 Mon Sep 17 00:00:00 2001 From: Joao Alves Date: Wed, 22 Sep 2021 09:05:59 +0100 Subject: [PATCH 8/8] Added lang to html. Lazy calculation of static page size. --- inc/http_staticpage.h | 5 +++-- src/lib/http.c | 8 +++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/inc/http_staticpage.h b/inc/http_staticpage.h index 9ef05d2..43f8e39 100644 --- a/inc/http_staticpage.h +++ b/inc/http_staticpage.h @@ -1,6 +1,6 @@ const char *content_static_page = \ "" \ - "" \ + "" \ "" \ " " \ " uts-server" \ @@ -45,7 +45,6 @@ const char *content_static_page = " border-radius: 2px;" \ " padding: 10px 24px;" \ " margin: 0 auto;" \ - " display: inline;" \ " box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, " \ "0, 0.19);" \ " margin: 0 auto;" \ @@ -115,3 +114,5 @@ const char *content_static_page = "" \ "" \ ""; + +int static_page_size = 0; diff --git a/src/lib/http.c b/src/lib/http.c index afabbd7..c1efd96 100644 --- a/src/lib/http.c +++ b/src/lib/http.c @@ -195,14 +195,16 @@ int rfc3161_handler(struct mg_connection *conn, void *context) { free(content); } else { // default reply if we don't have a time-stamp request - content_length = strlen(content_static_page); + if (static_page_size == 0) { + static_page_size = strlen(content_static_page); + } mg_printf(conn, "HTTP/1.1 200 OK\r\n" "Content-Type: text/html\r\n" "Content-Length: %d\r\n" "\r\n", - (int)content_length); - mg_write(conn, content_static_page, content_length); + (int)static_page_size); + mg_write(conn, content_static_page, static_page_size); } // initialize a serial_id if not created by create_response if (serial_id == NULL) {