mirror of
https://github.com/kakwa/uts-server
synced 2025-04-12 09:41:36 +02:00
Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c7b3f47325 | ||
![]() |
4975f90af6 | ||
![]() |
86d9094cca | ||
![]() |
2b52ee9177 | ||
![]() |
411efc72d4 | ||
![]() |
82766a0200 | ||
![]() |
dd19915c91 | ||
![]() |
bd0a32221c | ||
![]() |
68ffb0f7e8 | ||
![]() |
cab605597b | ||
![]() |
8fefcbaf6b | ||
![]() |
0e0b11310d | ||
![]() |
1b97399694 | ||
![]() |
4d174251ff | ||
![]() |
d034fc727a | ||
![]() |
3e15083a31 | ||
![]() |
20b747565f | ||
![]() |
2a9aa85ec6 | ||
![]() |
5c180efee4 | ||
![]() |
03f9bfed56 | ||
![]() |
3de83303e1 | ||
![]() |
fbdc2d2e39 | ||
![]() |
70f54cfd11 |
@ -10,7 +10,7 @@ else ()
|
||||
set (CMAKE_C_STANDARD 99)
|
||||
endif ()
|
||||
|
||||
set(VERSION 0.1.9)
|
||||
set(VERSION 0.2.1)
|
||||
|
||||
option(DEBUG "compile with debug symbol" OFF)
|
||||
option(BUNDLE_CIVETWEB "bundle civetweb with uts-server" OFF)
|
||||
@ -21,11 +21,19 @@ option(CIVETWEB_CUST_ARGS "Custom args for civetweb (if civetweb is bundled)" ""
|
||||
option(LINK_PTHREAD "link pthread" OFF)
|
||||
|
||||
IF("$ENV{CIVETWEB_GITURL}" STREQUAL "")
|
||||
set(CIVETWEB_GITURL "https://github.com/kakwa/civetweb")
|
||||
set(CIVETWEB_GITURL "https://github.com/civetweb/civetweb")
|
||||
ELSE()
|
||||
set(CIVETWEB_GITURL "$ENV{CIVETWEB_GITURL}")
|
||||
ENDIF()
|
||||
|
||||
IF("$ENV{CIVETWEB_GITTAG}" STREQUAL "")
|
||||
set(CIVETWEB_GITTAG "v1.11")
|
||||
ELSE()
|
||||
set(CIVETWEB_GITTAG "$ENV{CIVETWEB_GITTAG}")
|
||||
ENDIF()
|
||||
|
||||
|
||||
|
||||
IF(STATIC)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
|
||||
@ -34,6 +42,12 @@ IF(STATIC)
|
||||
set(CIVETWEB_USE_STATIC_LIBS ON)
|
||||
ENDIF(STATIC)
|
||||
|
||||
IF(BUNDLE_CIVETWEB)
|
||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set(DL_LIBRARIES 'dl')
|
||||
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
ENDIF(BUNDLE_CIVETWEB)
|
||||
|
||||
IF(LINK_DL)
|
||||
set(DL_LIBRARIES 'dl')
|
||||
ENDIF(LINK_DL)
|
||||
@ -100,9 +114,12 @@ if(BUNDLE_CIVETWEB)
|
||||
MESSAGE(STATUS "Building Civetweb From: ${CIVETWEB_GITURL}")
|
||||
ExternalProject_Add( civetweb
|
||||
GIT_REPOSITORY ${CIVETWEB_GITURL}
|
||||
GIT_TAG ${CIVETWEB_GITTAG}
|
||||
PATCH_COMMAND sed -i ${SED_FREEBSD} s/__DATE__/"110973"/ src/main.c src/civetweb.c
|
||||
INSTALL_DIR /usr/local
|
||||
CMAKE_ARGS .. -DCMAKE_INSTALL_PREFIX=/usr
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
-DCIVETWEB_ENABLE_CXX=OFF
|
||||
-DBUILD_SHARED_LIBS=OFF
|
||||
-DCIVETWEB_DISABLE_CGI=ON
|
||||
@ -110,9 +127,11 @@ if(BUNDLE_CIVETWEB)
|
||||
-DCIVETWEB_ENABLE_IPV6=ON
|
||||
-DCIVETWEB_DISABLE_CACHING=ON
|
||||
-DBUILD_TESTING=OFF
|
||||
-DCIVETWEB_BUILD_TESTING=OFF
|
||||
-DCIVETWEB_SSL_OPENSSL_API_1_1=${OPENSSL_API_1_1}
|
||||
-DOPENSSL_USE_STATIC_LIBS=${OPENSSL_USE_STATIC_LIBS}
|
||||
-DCIVETWEB_ENABLE_SSL_DYNAMIC_LOADING=OFF
|
||||
-DCIVETWEB_ENABLE_SSL_DYNAMIC_LOADING=ON
|
||||
-DCIVETWEB_ALLOW_WARNINGS=ON
|
||||
${CIVETWEB_CUST_ARGS}
|
||||
INSTALL_COMMAND make install DESTDIR=${CMAKE_CURRENT_SOURCE_DIR}/vendor/
|
||||
)
|
||||
|
@ -1,6 +1,28 @@
|
||||
Changelogs
|
||||
==========
|
||||
|
||||
0.2.1
|
||||
-----
|
||||
|
||||
* [fix ] fix compilation for newer GCC (>10.2) (global variable definition issue
|
||||
|
||||
0.2.0
|
||||
-----
|
||||
|
||||
* [fix ] disable buffering when logging to stdout (it was causing issues when running in docker)
|
||||
* [impr] make the stdout logger an official logger (previously, it was only for debugging)
|
||||
* [impr] the 'log_to_syslog' and 'log_to_stdout' parameters to enable/disable logging to syslog/stdout
|
||||
* [impr] serve the CA and the signer certificate
|
||||
* [impr] better landing page with download links for the previous 2 files and some instructions
|
||||
|
||||
0.1.10
|
||||
------
|
||||
|
||||
* [fix ] point to upstream civetweb (forked civetweb now removed)
|
||||
* [fix ] using dynamic openssl loading for civetweb when bundling
|
||||
* [impr] add possibility to specify which tag used for civetweb bundling
|
||||
* [impr] use same compiler for uts-server and civetweb when bundling
|
||||
|
||||
0.1.9
|
||||
-----
|
||||
|
||||
|
11
README.rst
11
README.rst
@ -23,10 +23,15 @@ Micro `RFC 3161 Time-Stamp <https://www.ietf.org/rfc/rfc3161.txt>`_ server writt
|
||||
:Doc: `Uts-Server documentation on ReadTheDoc <http://uts-server.readthedocs.org/en/latest/>`_
|
||||
:Dev: `Uts-Server source code on GitHub <https://github.com/kakwa/uts-server>`_
|
||||
:License: MIT
|
||||
:Author: Pierre-Francois Carpentier - copyright © 2016
|
||||
:Author: Pierre-Francois Carpentier - copyright © 2019
|
||||
|
||||
----
|
||||
|
||||
Demo
|
||||
----
|
||||
|
||||
A demo is accessible here: https://uts-server.kakwalab.ovh/
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
@ -45,7 +50,7 @@ Roughly, it works as follow:
|
||||
|
||||
Then a client can verify the piece of data with the time-stamp using the Certificate Authority of the time-stamp key pair (X509 certificates).
|
||||
|
||||
It gives a cryptographic proof of a piece of data content, like a file, at a given time.
|
||||
It gives a cryptographic proof of a piece of data content, for example a file, at a given time.
|
||||
|
||||
Some use cases:
|
||||
|
||||
@ -55,7 +60,7 @@ Some use cases:
|
||||
Quick (and dirty) Testing
|
||||
-------------------------
|
||||
|
||||
Here a few steps to quickly trying out uts-server, for production setup, please compile civetweb externally and create proper CA and certificates:
|
||||
Here a few steps to quickly try out uts-server, for production setup, please compile civetweb externally and create proper CA and certificates:
|
||||
|
||||
.. sourcecode:: bash
|
||||
|
||||
|
1
_config.yml
Normal file
1
_config.yml
Normal file
@ -0,0 +1 @@
|
||||
theme: jekyll-theme-hacker
|
@ -103,6 +103,12 @@ tcp_nodelay = 0
|
||||
# Loglevel (debug, info, notice, warn, err, emerg, crit)
|
||||
log_level = info
|
||||
|
||||
# Enable logging to syslog (default: yes)
|
||||
log_to_syslog = yes
|
||||
|
||||
# Enable logging to stdout (default: no)
|
||||
#log_to_stdout = no
|
||||
|
||||
# TSA configuration parameters.
|
||||
[ tsa ]
|
||||
|
||||
|
25
docs/conf.py
25
docs/conf.py
@ -185,6 +185,31 @@ Configuration Parameters
|
||||
"""
|
||||
|
||||
foot = """
|
||||
.. warning::
|
||||
|
||||
The TSA signing certificate must have exactly one extended key usage assigned to it: **timeStamping**.
|
||||
|
||||
The extended key usage must also be **critical**, otherwise the certificate is going to be refused.
|
||||
|
||||
Here is a sample openssl.cfg configuration for creating such certificate:
|
||||
|
||||
.. sourcecode:: ini
|
||||
|
||||
[ tsa_cert ]
|
||||
|
||||
# TSA server cert is not a CA cert, disabling CA role
|
||||
basicConstraints=CA:FALSE
|
||||
|
||||
# The following key usage flags are mandatory for TSA server certificates.
|
||||
# This parameters set the main specificities of a TSA certificate
|
||||
keyUsage = nonRepudiation, digitalSignature
|
||||
extendedKeyUsage = critical,timeStamping
|
||||
|
||||
# PKIX recommendations harmless if included in all certificates.
|
||||
subjectKeyIdentifier=hash
|
||||
authorityKeyIdentifier=keyid,issuer:always
|
||||
|
||||
|
||||
Full Configuration File
|
||||
=======================
|
||||
|
||||
|
103
goodies/index.html
Normal file
103
goodies/index.html
Normal file
@ -0,0 +1,103 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>uts-server</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: 90%;
|
||||
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: 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;
|
||||
}
|
||||
.desc {
|
||||
text-decoration: underline;
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
margin-top: 20px
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
</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>" \<br/>
|
||||
-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 the signer cert, and run the following command:
|
||||
<div class="code">
|
||||
openssl ts -verify -in "<span class="var">$FILE_TIMESTAMP</span>" \<br/>
|
||||
-data "<span class="var">$FILE</span>" -CAfile ca.pem -untrusted tsa_cert.pem
|
||||
</div>
|
||||
<div class="center">
|
||||
<a href="./ca.pem" download><button class="button">Dowload CA file</button></a>
|
||||
<a href="./tsa_cert.pem" download><button class="button">Dowload tsa cert 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>
|
@ -1 +1 @@
|
||||
d /run/ldapcherryd 0755 ldapcherry ldapcherry -
|
||||
d /run/uts-server 0755 uts-server uts-server -
|
||||
|
@ -9,9 +9,14 @@
|
||||
|
||||
#define HTTP_OPTIONS 1
|
||||
#define LOGLEVEL_OPTIONS 2
|
||||
#define TSA_OPTIONS 3
|
||||
#define PATH_HTTP_OPTIONS 4
|
||||
#define LOGHANDLER_OPTIONS 3
|
||||
#define TSA_OPTIONS 4
|
||||
#define PATH_HTTP_OPTIONS 5
|
||||
|
||||
/* name of the configuration file section */
|
||||
#define MAIN_CONF_SECTION "main"
|
||||
#define OID_SECTION "oids"
|
||||
#define TSA_SECTION "tsa"
|
||||
|
||||
#define RFC3161_OPTIONS_LEN \
|
||||
sizeof(rfc3161_options) / sizeof(struct rfc3161_option)
|
||||
@ -26,6 +31,10 @@ typedef struct {
|
||||
uint64_t query_counter;
|
||||
// flag for debugging
|
||||
bool stdout_dbg;
|
||||
// flag for logging to stdout
|
||||
bool stdout_logging;
|
||||
// flag for logging to stdout
|
||||
bool syslog_logging;
|
||||
// log level
|
||||
int loglevel;
|
||||
// number of threads
|
||||
@ -37,6 +46,8 @@ typedef struct {
|
||||
// just to track for freeing later
|
||||
CONF *conf;
|
||||
char *cust_conf[20];
|
||||
char *ca_file;
|
||||
char *cert_file;
|
||||
} rfc3161_context;
|
||||
|
||||
// definition of structure to describe
|
||||
@ -64,6 +75,8 @@ static struct rfc3161_option rfc3161_options[] = {
|
||||
{"access_control_allow_origin", HTTP_OPTIONS, "*"},
|
||||
{"tcp_nodelay", HTTP_OPTIONS, "0"},
|
||||
{"log_level", LOGLEVEL_OPTIONS, "info"},
|
||||
{"log_to_syslog", LOGHANDLER_OPTIONS, "yes"},
|
||||
{"log_to_stdout", LOGHANDLER_OPTIONS, "no"},
|
||||
{"ssl_certificate", PATH_HTTP_OPTIONS, NULL},
|
||||
{"ssl_ca_path", PATH_HTTP_OPTIONS, NULL},
|
||||
{"ssl_ca_file", PATH_HTTP_OPTIONS, NULL},
|
||||
|
122
inc/http.h
122
inc/http.h
@ -6,3 +6,125 @@ 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" \
|
||||
"<html>" \
|
||||
"<head>" \
|
||||
" <meta charset=\"utf-8\">" \
|
||||
" <title>uts-server</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: 90%;" \
|
||||
" 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: 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;" \
|
||||
"}" \
|
||||
".desc {" \
|
||||
" text-decoration: underline;" \
|
||||
" text-align: center;" \
|
||||
" font-size: 20px;" \
|
||||
" margin-top: 20px" \
|
||||
"}" \
|
||||
".center {" \
|
||||
" text-align: center;" \
|
||||
"}" \
|
||||
".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;" \
|
||||
"}" \
|
||||
"</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>\" \\<br/>" \
|
||||
" -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 the " \
|
||||
"signer cert, and run the following command:" \
|
||||
" <div class=\"code\">" \
|
||||
" openssl ts -verify -in \"<span " \
|
||||
"class=\"var\">$FILE_TIMESTAMP</span>\" \\<br/>" \
|
||||
" -data \"<span class=\"var\">$FILE</span>\" " \
|
||||
"-CAfile ca.pem -untrusted tsa_cert.pem" \
|
||||
" </div>" \
|
||||
" <div class=\"center\">" \
|
||||
" <a href=\"./ca.pem\" download><button class=\"button\">Dowload CA " \
|
||||
"file</button></a>" \
|
||||
" <a href=\"./tsa_cert.pem\" download><button " \
|
||||
"class=\"button\">Dowload tsa cert 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
|
||||
|
||||
/* 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
|
||||
#define SERIAL_ID_SIZE 8
|
||||
|
||||
|
@ -7,6 +7,7 @@ typedef struct _code {
|
||||
|
||||
static void signal_handler_general(int sig_num);
|
||||
static void signal_handler_up(int sig_num);
|
||||
void set_sig_handler();
|
||||
void skeleton_daemon();
|
||||
int init_pid(char *pidfile_path);
|
||||
int write_pid(char *pidfile_path);
|
||||
@ -17,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;
|
||||
|
@ -101,6 +101,8 @@ int main(int argc, char **argv) {
|
||||
|
||||
if (args.daemonize)
|
||||
skeleton_daemon();
|
||||
else
|
||||
set_sig_handler();
|
||||
|
||||
syslog(LOG_NOTICE,
|
||||
"uts-server daemon starting with conf '%s' from working dir '%s'",
|
||||
|
115
src/lib/http.c
115
src/lib/http.c
@ -9,6 +9,9 @@
|
||||
#include <time.h>
|
||||
#include <unistd.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) {
|
||||
@ -92,31 +95,16 @@ void log_request(const struct mg_request_info *request_info, char *request_id,
|
||||
}
|
||||
}
|
||||
|
||||
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]",
|
||||
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));
|
||||
}
|
||||
|
||||
// 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) {
|
||||
// some timer stuff
|
||||
clock_t start = clock(), diff;
|
||||
@ -178,10 +166,11 @@ int rfc3161_handler(struct mg_connection *conn, void *context) {
|
||||
// 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",
|
||||
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,
|
||||
@ -206,11 +195,7 @@ 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, "HTTP/1.1 200 OK\r\n"
|
||||
"Content-Type: text/plain\r\n"
|
||||
"Content-Length: 46\r\n"
|
||||
"\r\n"
|
||||
"uts-server, a simple RFC 3161 timestamp server");
|
||||
mg_printf(conn, STATIC_PAGE);
|
||||
}
|
||||
// initialize a serial_id if not created by create_response
|
||||
if (serial_id == NULL) {
|
||||
@ -229,6 +214,71 @@ int rfc3161_handler(struct mg_connection *conn, void *context) {
|
||||
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 http_server_start(char *conffile, char *conf_wd, bool stdout_dbg) {
|
||||
struct mg_context *ctx;
|
||||
struct mg_callbacks callbacks;
|
||||
@ -241,10 +291,13 @@ int http_server_start(char *conffile, char *conf_wd, bool stdout_dbg) {
|
||||
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;
|
||||
|
||||
@ -252,12 +305,14 @@ 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, "/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);
|
||||
}
|
||||
// getchar();
|
||||
} else {
|
||||
uts_logger(ct, LOG_ERR, "Failed to start uts-server: %s",
|
||||
((user_data.first_message == NULL)
|
||||
|
@ -269,7 +269,7 @@ end:
|
||||
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
|
||||
@ -319,8 +319,9 @@ end:
|
||||
ret = 200;
|
||||
break;
|
||||
case TS_STATUS_GRANTED_WITH_MODS:
|
||||
uts_logger(ct, LOG_NOTICE, "timestamp request granted with "
|
||||
"modification",
|
||||
uts_logger(ct, LOG_NOTICE,
|
||||
"timestamp request granted with "
|
||||
"modification",
|
||||
*serial_id);
|
||||
ret = 200;
|
||||
break;
|
||||
|
@ -8,11 +8,14 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// 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;
|
||||
}
|
||||
@ -68,6 +71,17 @@ int write_pid(char *pidfile_path) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void set_sig_handler() {
|
||||
g_uts_sig_up = 0;
|
||||
g_uts_sig = 0;
|
||||
/* Catch, ignore and handle signals */
|
||||
// TODO: Implement a working signal handler */
|
||||
signal(SIGTERM, signal_handler_general);
|
||||
signal(SIGINT, signal_handler_general);
|
||||
signal(SIGHUP, signal_handler_up);
|
||||
signal(SIGCHLD, SIG_IGN);
|
||||
}
|
||||
|
||||
void skeleton_daemon() {
|
||||
pid_t pid;
|
||||
|
||||
@ -86,14 +100,7 @@ void skeleton_daemon() {
|
||||
if (setsid() < 0)
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
g_uts_sig_up = 0;
|
||||
g_uts_sig = 0;
|
||||
/* Catch, ignore and handle signals */
|
||||
// TODO: Implement a working signal handler */
|
||||
signal(SIGTERM, signal_handler_general);
|
||||
signal(SIGINT, signal_handler_general);
|
||||
signal(SIGHUP, signal_handler_up);
|
||||
signal(SIGCHLD, SIG_IGN);
|
||||
set_sig_handler();
|
||||
|
||||
/* Fork off for the second time*/
|
||||
pid = fork();
|
||||
@ -162,7 +169,7 @@ void uts_logger(rfc3161_context *ct, int priority, char *fmt, ...) {
|
||||
fclose(stream);
|
||||
|
||||
// if in debugging mode, also log to stdout
|
||||
if (ct->stdout_dbg) {
|
||||
if (ct->stdout_logging || ct->stdout_dbg) {
|
||||
switch (priority) {
|
||||
case LOG_EMERG:
|
||||
printf("LOG_EMER : %s\n", out);
|
||||
@ -197,7 +204,8 @@ void uts_logger(rfc3161_context *ct, int priority, char *fmt, ...) {
|
||||
;
|
||||
}
|
||||
}
|
||||
syslog(priority, "%s", out);
|
||||
if (ct->syslog_logging)
|
||||
syslog(priority, "%s", out);
|
||||
free(out);
|
||||
}
|
||||
|
||||
@ -301,6 +309,21 @@ int set_params(rfc3161_context *ct, char *conf_file, char *conf_wd) {
|
||||
}
|
||||
break;
|
||||
;
|
||||
case LOGHANDLER_OPTIONS:
|
||||
if (strcmp(name, "log_to_syslog") == 0) {
|
||||
if (strcmp(value, "yes"))
|
||||
ct->syslog_logging = 0;
|
||||
else
|
||||
ct->syslog_logging = 1;
|
||||
}
|
||||
if (strcmp(name, "log_to_stdout") == 0) {
|
||||
if (strcmp(value, "yes"))
|
||||
ct->stdout_logging = 0;
|
||||
else
|
||||
ct->stdout_logging = 1;
|
||||
}
|
||||
break;
|
||||
;
|
||||
}
|
||||
}
|
||||
// parse the options to get the civetweb options and a few other things
|
||||
@ -318,8 +341,8 @@ int set_params(rfc3161_context *ct, char *conf_file, char *conf_wd) {
|
||||
uts_logger(ct, LOG_DEBUG, "configuration param['%s'] = '%s'", name,
|
||||
null_undef(value));
|
||||
switch (type) {
|
||||
// if it's an http (civetweb) option, put it in the http_options buffer
|
||||
// like civetweb is expected it.
|
||||
// if it's an http (civetweb) option, put it in the http_options
|
||||
// buffer like civetweb is expected it.
|
||||
case HTTP_OPTIONS:
|
||||
if (value != NULL) {
|
||||
ct->http_options[http_counter] = name;
|
||||
@ -368,6 +391,13 @@ int set_params(rfc3161_context *ct, char *conf_file, char *conf_wd) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ct->ca_file = calloc(PATH_MAX, sizeof(char));
|
||||
realpath(NCONF_get_string(ct->conf, TSA_SECTION, "certs"), ct->ca_file);
|
||||
ct->cert_file = calloc(PATH_MAX, sizeof(char));
|
||||
realpath(NCONF_get_string(ct->conf, TSA_SECTION, "signer_cert"),
|
||||
ct->cert_file);
|
||||
|
||||
// like any good daemon, return to '/' once the configuration is loaded
|
||||
chdir("/");
|
||||
return ret;
|
||||
@ -386,6 +416,8 @@ void free_uts_context(rfc3161_context *ct) {
|
||||
free(ct->cust_conf[i]);
|
||||
}
|
||||
free(ct->ts_ctx_pool);
|
||||
free(ct->ca_file);
|
||||
free(ct->cert_file);
|
||||
NCONF_free(ct->conf);
|
||||
free(ct);
|
||||
}
|
||||
|
@ -78,6 +78,12 @@ tcp_nodelay = 0
|
||||
# debug, info, notice, warn, err, emerg, crit
|
||||
log_level = info
|
||||
|
||||
# Enable logging to syslog (default: yes)
|
||||
log_to_syslog = no
|
||||
|
||||
# Enable logging to stdout (default: no)
|
||||
#log_to_stdout = yes
|
||||
|
||||
####################################################################
|
||||
[ tsa ]
|
||||
|
||||
|
@ -78,6 +78,12 @@ tcp_nodelay = 0
|
||||
# debug, info, notice, warn, err, emerg, crit
|
||||
log_level = info
|
||||
|
||||
# Enable logging to syslog (default: yes)
|
||||
log_to_syslog = no
|
||||
|
||||
# Enable logging to stdout (default: no)
|
||||
#log_to_stdout = yes
|
||||
|
||||
####################################################################
|
||||
[ tsa ]
|
||||
|
||||
|
@ -32,6 +32,8 @@ kill `cat ./uts-server.pid`
|
||||
|
||||
sed "s/2020/$PORT/" tests/cfg/uts-server-ssl.cnf >$CFG
|
||||
|
||||
sleep 1
|
||||
|
||||
$TO ./uts-server -c $CFG -D -p ./uts-server.pid &
|
||||
|
||||
sleep 1
|
||||
|
Loading…
x
Reference in New Issue
Block a user