mirror of
https://github.com/kakwa/uts-server
synced 2024-12-04 23:15:54 +01:00
creating a nicer landing page + serve the ca file
* nicer landing page with a few instructions, and download link for the ca, and even some fancy CSS * add a download link for the CA file
This commit is contained in:
parent
68ffb0f7e8
commit
bd0a32221c
96
goodies/index.html
Normal file
96
goodies/index.html
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title></title>
|
||||||
|
<meta name="author" content="Pierre-Francois Carpentier">
|
||||||
|
<meta name="description" content="uts-server">
|
||||||
|
<style>
|
||||||
|
.rcorners {
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 2px solid #0080ff;
|
||||||
|
margin: 20px;
|
||||||
|
padding: 10px;
|
||||||
|
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: 40%;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
.code {
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 2px solid #000000;
|
||||||
|
margin: 20px;
|
||||||
|
padding: 10px;
|
||||||
|
width: 80%;
|
||||||
|
background: #404040;
|
||||||
|
color: #e6e6e6;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
.button {
|
||||||
|
background-color: #3366ff;
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 4px 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 2px;
|
||||||
|
padding: 10px 24px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: block;
|
||||||
|
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||||
|
}
|
||||||
|
.desc {
|
||||||
|
text-decoration: underline;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0px;
|
||||||
|
padding-top: 5px;
|
||||||
|
border-top: 1px solid gray;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.var {
|
||||||
|
color: #99ccff;
|
||||||
|
}
|
||||||
|
<span class="var">January 30, 2011</span>
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="desc">
|
||||||
|
uts-server, a simple RFC 3161 timestamp server
|
||||||
|
</div>
|
||||||
|
<div class="rcorners">
|
||||||
|
For timestamping a file with OpenSSL and curl, run the following commands
|
||||||
|
(setting the $UTS_SERVER_URL, $FILE and $FILE_TIMESTAMP variables):
|
||||||
|
<div class="code">
|
||||||
|
openssl ts -query -data "<span class="var">$FILE</span>" -out "ts_req.ts";<br/>
|
||||||
|
curl "<span class="var">$UTS_SERVER_URL</span>" -H "Content-Type: application/timestamp-query" \<br/>
|
||||||
|
-f -g --data-binary "@ts_req.ts" -o "<span class="var">$FILE_TIMESTAMP</span>"
|
||||||
|
</div>
|
||||||
|
For verifying the timestamp with OpenSSL, download the CA, and run the following command:
|
||||||
|
<div class="code">
|
||||||
|
openssl ts -verify -in "<span class="var">$FILE_TIMESTAMP</span>" -data "<span class="var">$FILE</span>" -CAfile ca.pem
|
||||||
|
</div>
|
||||||
|
<div class="centered">
|
||||||
|
<a href="/ca.pem" download><button class="button">Dowload CA file</button></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<div class="container">
|
||||||
|
<a href="http://uts-server.readthedocs.org" target="_blank">uts-server</a>
|
||||||
|
• © 2019 • Pierre-François Carpentier • Released under the MIT License
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -12,7 +12,11 @@
|
|||||||
#define LOGHANDLER_OPTIONS 3
|
#define LOGHANDLER_OPTIONS 3
|
||||||
#define TSA_OPTIONS 4
|
#define TSA_OPTIONS 4
|
||||||
#define PATH_HTTP_OPTIONS 5
|
#define PATH_HTTP_OPTIONS 5
|
||||||
|
|
||||||
|
/* name of the configuration file section */
|
||||||
#define MAIN_CONF_SECTION "main"
|
#define MAIN_CONF_SECTION "main"
|
||||||
|
#define OID_SECTION "oids"
|
||||||
|
#define TSA_SECTION "tsa"
|
||||||
|
|
||||||
#define RFC3161_OPTIONS_LEN \
|
#define RFC3161_OPTIONS_LEN \
|
||||||
sizeof(rfc3161_options) / sizeof(struct rfc3161_option)
|
sizeof(rfc3161_options) / sizeof(struct rfc3161_option)
|
||||||
@ -42,6 +46,7 @@ typedef struct {
|
|||||||
// just to track for freeing later
|
// just to track for freeing later
|
||||||
CONF *conf;
|
CONF *conf;
|
||||||
char *cust_conf[20];
|
char *cust_conf[20];
|
||||||
|
char *ca_file;
|
||||||
} rfc3161_context;
|
} rfc3161_context;
|
||||||
|
|
||||||
// definition of structure to describe
|
// definition of structure to describe
|
||||||
|
114
inc/http.h
114
inc/http.h
@ -6,3 +6,117 @@ struct tuser_data {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int http_server_start(char *conffile, char *conf_wd, bool stdout_dbg);
|
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: 2509\r\n" \
|
||||||
|
"\r\n" \
|
||||||
|
"<html>" \
|
||||||
|
"<head>" \
|
||||||
|
" <meta charset=\"utf-8\">" \
|
||||||
|
" <title></title>" \
|
||||||
|
" <meta name=\"author\" content=\"Pierre-Francois Carpentier\">" \
|
||||||
|
" <meta name=\"description\" content=\"uts-server\">" \
|
||||||
|
"<style>" \
|
||||||
|
".rcorners {" \
|
||||||
|
" border-radius: 10px;" \
|
||||||
|
" border: 2px solid #0080ff;" \
|
||||||
|
" margin: 20px;" \
|
||||||
|
" padding: 10px;" \
|
||||||
|
" box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, " \
|
||||||
|
"0, 0.19);" \
|
||||||
|
" margin-left: auto;" \
|
||||||
|
" margin-right: auto;" \
|
||||||
|
" width: 40%;" \
|
||||||
|
"}" \
|
||||||
|
"body {" \
|
||||||
|
" margin: 0px;" \
|
||||||
|
"}" \
|
||||||
|
".code {" \
|
||||||
|
" border-radius: 3px;" \
|
||||||
|
" border: 2px solid #000000;" \
|
||||||
|
" margin: 20px;" \
|
||||||
|
" padding: 10px;" \
|
||||||
|
" width: 80%;" \
|
||||||
|
" background: #404040;" \
|
||||||
|
" color: #e6e6e6;" \
|
||||||
|
" margin-left: auto;" \
|
||||||
|
" margin-right: auto;" \
|
||||||
|
"}" \
|
||||||
|
".button {" \
|
||||||
|
" background-color: #3366ff;" \
|
||||||
|
" border: none;" \
|
||||||
|
" color: white;" \
|
||||||
|
" text-align: center;" \
|
||||||
|
" text-decoration: none;" \
|
||||||
|
" display: inline-block;" \
|
||||||
|
" font-size: 14px;" \
|
||||||
|
" margin: 4px 2px;" \
|
||||||
|
" cursor: pointer;" \
|
||||||
|
" border-radius: 2px;" \
|
||||||
|
" padding: 10px 24px;" \
|
||||||
|
" margin: 0 auto;" \
|
||||||
|
" display: block;" \
|
||||||
|
" box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, " \
|
||||||
|
"0, 0.19);" \
|
||||||
|
"}" \
|
||||||
|
".desc {" \
|
||||||
|
" text-decoration: underline;" \
|
||||||
|
" text-align: center;" \
|
||||||
|
" font-size: 20px;" \
|
||||||
|
"}" \
|
||||||
|
".footer {" \
|
||||||
|
" position: fixed;" \
|
||||||
|
" bottom: 0px;" \
|
||||||
|
" padding-top: 5px;" \
|
||||||
|
" border-top: 1px solid gray;" \
|
||||||
|
" width: 100%;" \
|
||||||
|
" background-color: #f5f5f5;" \
|
||||||
|
" font-size: 14px;" \
|
||||||
|
" text-align: center;" \
|
||||||
|
"}" \
|
||||||
|
".var {" \
|
||||||
|
" color: #99ccff;" \
|
||||||
|
"}" \
|
||||||
|
"<span class=\"var\">January 30, 2011</span>" \
|
||||||
|
"</style>" \
|
||||||
|
"</head>" \
|
||||||
|
"<body>" \
|
||||||
|
"<div class=\"desc\">" \
|
||||||
|
" uts-server, a simple RFC 3161 timestamp server" \
|
||||||
|
"</div>" \
|
||||||
|
"<div class=\"rcorners\">" \
|
||||||
|
" For timestamping a file with OpenSSL and curl, run the following " \
|
||||||
|
"commands" \
|
||||||
|
" (setting the $UTS_SERVER_URL, $FILE and $FILE_TIMESTAMP variables):" \
|
||||||
|
" <div class=\"code\">" \
|
||||||
|
" openssl ts -query -data \"<span class=\"var\">$FILE</span>\" -out " \
|
||||||
|
"\"ts_req.ts\";<br/>" \
|
||||||
|
" curl \"<span class=\"var\">$UTS_SERVER_URL</span>\" -H " \
|
||||||
|
"\"Content-Type: application/timestamp-query\" \\<br/>" \
|
||||||
|
" -f -g --data-binary \"@ts_req.ts\" -o \"<span " \
|
||||||
|
"class=\"var\">$FILE_TIMESTAMP</span>\"" \
|
||||||
|
" </div>" \
|
||||||
|
" For verifying the timestamp with OpenSSL, download the CA, and run " \
|
||||||
|
"the following command:" \
|
||||||
|
" <div class=\"code\">" \
|
||||||
|
" openssl ts -verify -in \"<span " \
|
||||||
|
"class=\"var\">$FILE_TIMESTAMP</span>\" -data \"<span " \
|
||||||
|
"class=\"var\">$FILE</span>\" -CAfile ca.pem" \
|
||||||
|
" </div>" \
|
||||||
|
" <div class=\"centered\">" \
|
||||||
|
" <a href=\"/ca.pem\" download><button class=\"button\">Dowload CA " \
|
||||||
|
"file</button></a>" \
|
||||||
|
" </div>" \
|
||||||
|
"</div>" \
|
||||||
|
"<div class=\"footer\">" \
|
||||||
|
" <div class=\"container\">" \
|
||||||
|
" <a href=\"http://uts-server.readthedocs.org\" " \
|
||||||
|
"target=\"_blank\">uts-server</a>" \
|
||||||
|
" • © 2019 • Pierre-François Carpentier • Released under the MIT " \
|
||||||
|
"License" \
|
||||||
|
" </div>" \
|
||||||
|
"</div>" \
|
||||||
|
"</body>" \
|
||||||
|
"</html>"
|
||||||
|
@ -39,10 +39,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Name of config entry that defines the OID file. */
|
|
||||||
#define OID_SECTION "oids"
|
|
||||||
#define TSA_SECTION "tsa"
|
|
||||||
|
|
||||||
// number of char we get to log for the serial
|
// number of char we get to log for the serial
|
||||||
#define SERIAL_ID_SIZE 8
|
#define SERIAL_ID_SIZE 8
|
||||||
|
|
||||||
|
@ -102,22 +102,6 @@ void log_request(const struct mg_request_info *request_info, char *request_id,
|
|||||||
null_undef(content_type));
|
null_undef(content_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function will be called by civetweb on every new request.
|
|
||||||
static int begin_request_handler(struct mg_connection *conn) {
|
|
||||||
const struct mg_request_info *request_info = mg_get_request_info(conn);
|
|
||||||
|
|
||||||
mg_printf(conn,
|
|
||||||
"HTTP/1.1 200 OK\r\n"
|
|
||||||
"Content-Type: text/plain\r\n"
|
|
||||||
"Content-Length: 46\r\n" // Always set Content-Length
|
|
||||||
"\r\n"
|
|
||||||
"uts-server, a simple RFC 3161 timestamp server");
|
|
||||||
|
|
||||||
// Returning non-zero tells civetweb that our function has replied to
|
|
||||||
// the client, and civetweb should not send client any more data.
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int rfc3161_handler(struct mg_connection *conn, void *context) {
|
int rfc3161_handler(struct mg_connection *conn, void *context) {
|
||||||
// some timer stuff
|
// some timer stuff
|
||||||
clock_t start = clock(), diff;
|
clock_t start = clock(), diff;
|
||||||
@ -208,11 +192,7 @@ int rfc3161_handler(struct mg_connection *conn, void *context) {
|
|||||||
} else {
|
} else {
|
||||||
// default reply if we don't have a time-stamp request
|
// default reply if we don't have a time-stamp request
|
||||||
resp_code = 200;
|
resp_code = 200;
|
||||||
mg_printf(conn, "HTTP/1.1 200 OK\r\n"
|
mg_printf(conn, STATIC_PAGE);
|
||||||
"Content-Type: text/plain\r\n"
|
|
||||||
"Content-Length: 46\r\n"
|
|
||||||
"\r\n"
|
|
||||||
"uts-server, a simple RFC 3161 timestamp server");
|
|
||||||
}
|
}
|
||||||
// initialize a serial_id if not created by create_response
|
// initialize a serial_id if not created by create_response
|
||||||
if (serial_id == NULL) {
|
if (serial_id == NULL) {
|
||||||
@ -231,6 +211,37 @@ int rfc3161_handler(struct mg_connection *conn, void *context) {
|
|||||||
return 1;
|
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 http_server_start(char *conffile, char *conf_wd, bool stdout_dbg) {
|
int http_server_start(char *conffile, char *conf_wd, bool stdout_dbg) {
|
||||||
struct mg_context *ctx;
|
struct mg_context *ctx;
|
||||||
struct mg_callbacks callbacks;
|
struct mg_callbacks callbacks;
|
||||||
@ -250,7 +261,6 @@ int http_server_start(char *conffile, char *conf_wd, bool stdout_dbg) {
|
|||||||
// Prepare callbacks structure. We have only one callback, the rest are
|
// Prepare callbacks structure. We have only one callback, the rest are
|
||||||
// NULL.
|
// NULL.
|
||||||
memset(&callbacks, 0, sizeof(callbacks));
|
memset(&callbacks, 0, sizeof(callbacks));
|
||||||
|
|
||||||
memset(&user_data, 0, sizeof(user_data));
|
memset(&user_data, 0, sizeof(user_data));
|
||||||
callbacks.log_message = &log_civetweb;
|
callbacks.log_message = &log_civetweb;
|
||||||
|
|
||||||
@ -258,12 +268,12 @@ int http_server_start(char *conffile, char *conf_wd, bool stdout_dbg) {
|
|||||||
ctx = mg_start(&callbacks, &user_data, ct->http_options);
|
ctx = mg_start(&callbacks, &user_data, ct->http_options);
|
||||||
if (ctx != NULL) {
|
if (ctx != NULL) {
|
||||||
mg_set_request_handler(ctx, "/", rfc3161_handler, (void *)ct);
|
mg_set_request_handler(ctx, "/", rfc3161_handler, (void *)ct);
|
||||||
|
mg_set_request_handler(ctx, "/ca.pem", ca_serve_handler, (void *)ct);
|
||||||
|
|
||||||
// Wait until some signals are received
|
// Wait until some signals are received
|
||||||
while (g_uts_sig == 0) {
|
while (g_uts_sig == 0) {
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
// getchar();
|
|
||||||
} else {
|
} else {
|
||||||
uts_logger(ct, LOG_ERR, "Failed to start uts-server: %s",
|
uts_logger(ct, LOG_ERR, "Failed to start uts-server: %s",
|
||||||
((user_data.first_message == NULL)
|
((user_data.first_message == NULL)
|
||||||
|
@ -387,6 +387,9 @@ int set_params(rfc3161_context *ct, char *conf_file, char *conf_wd) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ct->ca_file = calloc(PATH_MAX, sizeof(char));
|
||||||
|
realpath(NCONF_get_string(ct->conf, TSA_SECTION, "certs"), ct->ca_file);
|
||||||
// like any good daemon, return to '/' once the configuration is loaded
|
// like any good daemon, return to '/' once the configuration is loaded
|
||||||
chdir("/");
|
chdir("/");
|
||||||
return ret;
|
return ret;
|
||||||
@ -405,6 +408,7 @@ void free_uts_context(rfc3161_context *ct) {
|
|||||||
free(ct->cust_conf[i]);
|
free(ct->cust_conf[i]);
|
||||||
}
|
}
|
||||||
free(ct->ts_ctx_pool);
|
free(ct->ts_ctx_pool);
|
||||||
|
free(ct->ca_file);
|
||||||
NCONF_free(ct->conf);
|
NCONF_free(ct->conf);
|
||||||
free(ct);
|
free(ct);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user