diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2017-07-30 02:12:19 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2017-08-03 07:26:53 +0200 |
commit | f1264fc131378f618b30214612ccf6e7807d1e2f (patch) | |
tree | b9624b67a7571c300ba8b843f514ad1435f3f377 /src | |
parent | ba101a1aeb88d6cfbae6f8e81cc104bae0c6c9fe (diff) | |
download | gnutls-f1264fc131378f618b30214612ccf6e7807d1e2f.tar.gz |
gnutls-cli: introduced options to save client and server traces
This allows to easier obtain traces for use in fuzzers.
Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/cli-args.def | 14 | ||||
-rw-r--r-- | src/cli.c | 17 | ||||
-rw-r--r-- | src/socket.c | 55 | ||||
-rw-r--r-- | src/socket.h | 11 |
4 files changed, 90 insertions, 7 deletions
diff --git a/src/cli-args.def b/src/cli-args.def index 4642237c28..9a067ce78b 100644 --- a/src/cli-args.def +++ b/src/cli-args.def @@ -161,6 +161,20 @@ flag = { }; flag = { + name = save-server-trace; + arg-type = string; + descrip = "Save the server-side TLS message trace in the provided file"; + doc = ""; +}; + +flag = { + name = save-client-trace; + arg-type = string; + descrip = "Save the client-side TLS message trace in the provided file"; + doc = ""; +}; + +flag = { name = dh-bits; arg-type = number; descrip = "The minimum number of bits allowed for DH"; @@ -829,7 +829,8 @@ static int try_resume(socket_st * hd) if (udp) socket_flags |= SOCKET_FLAG_UDP; - socket_open(hd, hostname, service, OPT_ARG(STARTTLS_PROTO), socket_flags, CONNECT_MSG, &rdata); + socket_open(hd, hostname, service, OPT_ARG(STARTTLS_PROTO), + socket_flags, CONNECT_MSG, &rdata); printf("- Resume Handshake was completed\n"); if (gnutls_session_is_resumed(hd->session) != 0) @@ -1082,6 +1083,8 @@ int main(int argc, char **argv) inline_cmds_st inline_cmds; unsigned last_op_is_write = 0; int socket_flags = 0; + FILE *server_fp = NULL; + FILE *client_fp = NULL; #ifndef _WIN32 struct sigaction new_action; #endif @@ -1118,7 +1121,17 @@ int main(int argc, char **argv) else if (HAVE_OPT(STARTTLS_PROTO)) socket_flags |= SOCKET_FLAG_STARTTLS; - socket_open(&hd, hostname, service, OPT_ARG(STARTTLS_PROTO), socket_flags, CONNECT_MSG, NULL); + if (HAVE_OPT(SAVE_SERVER_TRACE)) { + server_fp = fopen(OPT_ARG(SAVE_SERVER_TRACE), "wb"); + } + if (HAVE_OPT(SAVE_CLIENT_TRACE)) { + client_fp = fopen(OPT_ARG(SAVE_CLIENT_TRACE), "wb"); + } + + socket_open2(&hd, hostname, service, OPT_ARG(STARTTLS_PROTO), + socket_flags, CONNECT_MSG, NULL, + server_fp, client_fp); + hd.verbose = verbose; if (hd.secure) { diff --git a/src/socket.c b/src/socket.c index 16ed40720f..4d90f2f5f5 100644 --- a/src/socket.c +++ b/src/socket.c @@ -387,6 +387,11 @@ void socket_bye(socket_st * socket, unsigned polite) gnutls_free(socket->rdata.data); socket->rdata.data = NULL; + if (socket->server_trace) + fclose(socket->server_trace); + if (socket->client_trace) + fclose(socket->client_trace); + socket->fd = -1; socket->secure = 0; } @@ -409,10 +414,45 @@ void canonicalize_host(char *hostname, char *service, unsigned service_size) snprintf(service, service_size, "%s", p+1); } +static ssize_t +wrap_pull(gnutls_transport_ptr_t ptr, void *data, size_t len) +{ + socket_st *hd = ptr; + ssize_t r; + + r = recv(hd->fd, data, len, 0); + if (r > 0 && hd->server_trace) { + fwrite(data, 1, len, hd->server_trace); + } + return r; +} + +static ssize_t +wrap_push(gnutls_transport_ptr_t ptr, const void *data, size_t len) +{ + socket_st *hd = ptr; + + if (hd->client_trace) { + fwrite(data, 1, len, hd->client_trace); + } + + return send(hd->fd, data, len, 0); +} + +/* inline is used to avoid a gcc warning if used in mini-eagain */ +inline static int wrap_pull_timeout_func(gnutls_transport_ptr_t ptr, + unsigned int ms) +{ + socket_st *hd = ptr; + + return gnutls_system_recv_timeout((gnutls_transport_ptr_t)(long)hd->fd, ms); +} + void -socket_open(socket_st * hd, const char *hostname, const char *service, - const char *app_proto, int flags, const char *msg, gnutls_datum_t *rdata) +socket_open2(socket_st * hd, const char *hostname, const char *service, + const char *app_proto, int flags, const char *msg, gnutls_datum_t *rdata, + FILE *server_trace, FILE *client_trace) { struct addrinfo hints, *res, *ptr; int sd, err = 0; @@ -523,7 +563,16 @@ socket_open(socket_st * hd, const char *hostname, const char *service, gnutls_session_set_data(hd->session, hd->rdata.data, hd->rdata.size); } - gnutls_transport_set_int(hd->session, sd); + if (server_trace) + hd->server_trace = server_trace; + + if (client_trace) + hd->client_trace = client_trace; + + gnutls_transport_set_push_function(hd->session, wrap_push); + gnutls_transport_set_pull_function(hd->session, wrap_pull); + gnutls_transport_set_pull_timeout_function(hd->session, wrap_pull_timeout_func); + gnutls_transport_set_ptr(hd->session, hd); } if (!(flags & SOCKET_FLAG_RAW) && !(flags & SOCKET_FLAG_SKIP_INIT)) { diff --git a/src/socket.h b/src/socket.h index cb5289a582..49aec0bf2b 100644 --- a/src/socket.h +++ b/src/socket.h @@ -25,6 +25,9 @@ typedef struct { struct sockaddr_storage connect_addr; socklen_t connect_addrlen; + FILE *server_trace; + FILE *client_trace; + /* resumption data */ gnutls_datum_t rdata; } socket_st; @@ -42,8 +45,12 @@ ssize_t socket_send(const socket_st * socket, const void *buffer, ssize_t socket_send_range(const socket_st * socket, const void *buffer, int buffer_size, gnutls_range_st * range); void -socket_open(socket_st * hd, const char *hostname, const char *service, - const char *app_proto, int flags, const char *msg, gnutls_datum_t *rdata); +socket_open2(socket_st * hd, const char *hostname, const char *service, + const char *app_proto, int flags, const char *msg, gnutls_datum_t *rdata, + FILE *server_trace, FILE *client_trace); + +#define socket_open(hd, host, service, app_proto, flags, msg, rdata) \ + socket_open2(hd, host, service, app_proto, flags, msg, rdata, NULL, NULL) void socket_bye(socket_st * socket, unsigned polite); |