diff options
author | Peter Wu <peter@lekensteyn.nl> | 2018-11-17 22:43:14 +0100 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2018-11-20 05:13:37 +0000 |
commit | e2e0fd1dbdb07f2a1bd8822ab86bcd7144025f97 (patch) | |
tree | 5e27b55640158f83f9726c95d1976321d0bb7bb9 /editcap.c | |
parent | 52a667143929ace46929bfb6ad15b6a856cdbe77 (diff) |
editcap: add --inject-secrets option
Add a new option to insert decryption secrets into a pcapng file.
Change-Id: I0e024585cac9a8a328e88d32f9eb03d37d350e2a
Ping-Bug: 15252
Reviewed-on: https://code.wireshark.org/review/30693
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'editcap.c')
-rw-r--r-- | editcap.c | 103 |
1 files changed, 103 insertions, 0 deletions
@@ -43,6 +43,7 @@ #include <getopt.h> #endif +#include <wiretap/secrets-types.h> #include <wiretap/wtap.h> #include "epan/etypes.h" @@ -175,6 +176,13 @@ static int do_strict_time_adjustment = FALSE; static struct time_adjustment strict_time_adj = {NSTIME_INIT_ZERO, 0}; /* strict time adjustment */ static nstime_t previous_time = NSTIME_INIT_ZERO; /* previous time */ +static const struct { + const char *str; + guint32 id; +} secrets_types[] = { + { "tls", SECRETS_TYPE_TLS }, +}; + static int find_dct2000_real_data(guint8 *buf); static void handle_chopping(chop_t chop, wtap_packet_header *out_phdr, const wtap_packet_header *in_phdr, guint8 **buf, @@ -900,6 +908,25 @@ list_encap_types(FILE *stream) { g_free(encaps); } +static void +list_secrets_types(FILE *stream) +{ + for (guint i = 0; i < G_N_ELEMENTS(secrets_types); i++) { + fprintf(stream, " %s\n", secrets_types[i].str); + } +} + +static guint32 +lookup_secrets_type(const char *type) +{ + for (guint i = 0; i < G_N_ELEMENTS(secrets_types); i++) { + if (!strcmp(secrets_types[i].str, type)) { + return secrets_types[i].id; + } + } + return 0; +} + static int framenum_compare(gconstpointer a, gconstpointer b, gpointer user_data _U_) { @@ -965,6 +992,7 @@ real_main(int argc, char *argv[]) {"novlan", no_argument, NULL, 0x8100}, {"skip-radiotap-header", no_argument, NULL, 0x8101}, {"seed", required_argument, NULL, 0x8102}, + {"inject-secrets", required_argument, NULL, 0x8103}, {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'V'}, {0, 0, 0, 0 } @@ -992,6 +1020,8 @@ real_main(int argc, char *argv[]) gchar *fsuffix = NULL; guint32 change_offset = 0; guint max_packet_number = 0; + GArray *dsb_types = NULL; + GPtrArray *dsb_filenames = NULL; const wtap_rec *rec; wtap_rec temp_rec; wtap_dump_params params = WTAP_DUMP_PARAMS_INIT; @@ -1073,6 +1103,36 @@ real_main(int argc, char *argv[]) break; } + case 0x8103: /* --inject-secrets */ + { + guint32 secrets_type_id = 0; + const char *secrets_filename = NULL; + if (strcmp("help", optarg) == 0) { + list_secrets_types(stdout); + goto clean_exit; + } + gchar **splitted = g_strsplit(optarg, ",", 2); + if (splitted[0]) { + secrets_type_id = lookup_secrets_type(splitted[0]); + secrets_filename = splitted[1]; + } + + if (secrets_type_id == 0) { + fprintf(stderr, "editcap: \"%s\" isn't a valid secrets type\n", secrets_filename); + g_strfreev(splitted); + ret = INVALID_OPTION; + goto clean_exit; + } + if (!dsb_filenames) { + dsb_types = g_array_new(FALSE, FALSE, sizeof(guint32)); + dsb_filenames = g_ptr_array_new_with_free_func(g_free); + } + g_array_append_val(dsb_types, secrets_type_id); + g_ptr_array_add(dsb_filenames, g_strdup(secrets_filename)); + g_strfreev(splitted); + break; + } + case 'a': { guint frame_number; @@ -1400,6 +1460,45 @@ real_main(int argc, char *argv[]) wtap_dump_params_init(¶ms, wth); + if (dsb_filenames) { + for (guint k = 0; k < dsb_filenames->len; k++) { + guint32 secrets_type_id = g_array_index(dsb_types, guint32, k); + const char *secrets_filename = (const char *)g_ptr_array_index(dsb_filenames, k); + char *data; + gsize data_len; + wtap_block_t block; + wtapng_dsb_mandatory_t *dsb; + GError *err = NULL; + + if (!g_file_get_contents(secrets_filename, &data, &data_len, &err)) { + fprintf(stderr, "editcap: \"%s\" could not be read: %s\n", secrets_filename, err->message); + g_clear_error(&err); + ret = INVALID_OPTION; + goto clean_exit; + } + if (data_len == 0) { + fprintf(stderr, "editcap: \"%s\" is an empty file, ignoring\n", secrets_filename); + g_free(data); + continue; + } + if (data_len >= G_MAXINT) { + fprintf(stderr, "editcap: \"%s\" is too large, ignoring\n", secrets_filename); + g_free(data); + continue; + } + + block = wtap_block_create(WTAP_BLOCK_DSB); + dsb = (wtapng_dsb_mandatory_t *)wtap_block_get_mandatory_data(block); + dsb->secrets_type = secrets_type_id; + dsb->secrets_len = (guint)data_len; + dsb->secrets_data = data; + if (params.dsbs_initial == NULL) { + params.dsbs_initial = g_array_new(FALSE, FALSE, sizeof(wtap_block_t)); + } + g_array_append_val(params.dsbs_initial, block); + } + } + /* * If an encapsulation type was specified, override the encapsulation * type of the input file. @@ -1935,6 +2034,10 @@ real_main(int argc, char *argv[]) } clean_exit: + if (dsb_filenames) { + g_array_free(dsb_types, TRUE); + g_ptr_array_free(dsb_filenames, TRUE); + } g_free(params.idb_inf); wtap_dump_params_cleanup(¶ms); if (wth != NULL) |