summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2017-07-30 02:12:19 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2017-08-03 07:26:53 +0200
commitf1264fc131378f618b30214612ccf6e7807d1e2f (patch)
treeb9624b67a7571c300ba8b843f514ad1435f3f377 /src
parentba101a1aeb88d6cfbae6f8e81cc104bae0c6c9fe (diff)
downloadgnutls-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.def14
-rw-r--r--src/cli.c17
-rw-r--r--src/socket.c55
-rw-r--r--src/socket.h11
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";
diff --git a/src/cli.c b/src/cli.c
index 28acc92218..b2db7bc101 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -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);