aboutsummaryrefslogtreecommitdiffstats
path: root/wiretap/merge.c
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2018-11-17 13:56:12 +0100
committerAnders Broman <a.broman58@gmail.com>2018-11-20 05:12:37 +0000
commit52a667143929ace46929bfb6ad15b6a856cdbe77 (patch)
tree97dfedc45dd07c47116ba06cb13457f04a5d48df /wiretap/merge.c
parentad21e3121f3307ee6cc2b4a2b296ef6dd83152ed (diff)
wiretap: add read/write support for Decryption Secrets Block (DSB)
Support reading and writing pcapng files with DSBs. A DSB may occur multiple times but should appear before packets that need those decryption secrets (so it cannot be moved to the end like NRB). The TLS dissector will be updated in the future to make use of these secrets. pcapng spec update: https://github.com/pcapng/pcapng/pull/54 As DSBs may be interleaved with packets, do not even try to read it in pcapng_open (as is done for IDBs). Instead process them during the sequential read, appending them to the 'wtap::dsbs' array. Writing is more complicated, secrets may initially not be available when 'wtap_dumper' is created. As they may become available in 'wtap::dsbs' as more packets are read, allow 'wtap_dumper::dsbs_growing' to reference this array. This saves every user from checking/dumping DSBs. If the wtap user needs to insert extra DSBs (while preserving existing DSBs), they can set the 'wtap_dumper::dsbs_initial' field. The test file was creating using a patched editcap (future patch) and combined using mergecap (which required a change to preserve the DSBs). Change-Id: I74e4ee3171bd852a89ea0f6fbae9e0f65ed6eda9 Ping-Bug: 15252 Reviewed-on: https://code.wireshark.org/review/30692 Reviewed-by: Peter Wu <peter@lekensteyn.nl> Petri-Dish: Peter Wu <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'wiretap/merge.c')
-rw-r--r--wiretap/merge.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/wiretap/merge.c b/wiretap/merge.c
index 1a1f56ffac..42aa35507d 100644
--- a/wiretap/merge.c
+++ b/wiretap/merge.c
@@ -25,6 +25,7 @@
#include "merge.h"
#include "wtap_opttypes.h"
#include "pcapng.h"
+#include "wtap-int.h"
#include <wsutil/filesystem.h>
#include "wsutil/os_version_info.h"
@@ -832,6 +833,7 @@ merge_process_packets(wtap_dumper *pdh, const int file_type,
merge_in_file_t *in_files, const guint in_file_count,
const gboolean do_append, guint snaplen,
merge_progress_callback_t* cb,
+ GArray *dsb_combined,
int *err, gchar **err_info, guint *err_fileno,
guint32 *err_framenum)
{
@@ -911,6 +913,18 @@ merge_process_packets(wtap_dumper *pdh, const int file_type,
}
}
}
+ /*
+ * If any DSBs were read before this record, be sure to pass those now
+ * such that wtap_dump can pick it up.
+ */
+ if (dsb_combined && in_file->wth->dsbs) {
+ GArray *in_dsb = in_file->wth->dsbs;
+ for (guint i = in_file->dsbs_seen; i < in_dsb->len; i++) {
+ wtap_block_t wblock = g_array_index(in_dsb, wtap_block_t, i);
+ g_array_append_val(dsb_combined, wblock);
+ in_file->dsbs_seen++;
+ }
+ }
if (!wtap_dump(pdh, rec, wtap_get_buf_ptr(in_file->wth), err, err_info)) {
status = MERGE_ERR_CANT_WRITE_OUTFILE;
@@ -921,8 +935,6 @@ merge_process_packets(wtap_dumper *pdh, const int file_type,
if (cb)
cb->callback_func(MERGE_EVENT_DONE, count, in_files, in_file_count, cb->data);
- merge_close_in_files(in_file_count, in_files);
-
if (status == MERGE_OK || status == MERGE_USER_ABORTED) {
if (!wtap_dump_close(pdh, err))
status = MERGE_ERR_CANT_CLOSE_OUTFILE;
@@ -937,6 +949,12 @@ merge_process_packets(wtap_dumper *pdh, const int file_type,
(void)wtap_dump_close(pdh, &close_err);
}
+ /* Close the input files after the output file in case the latter still
+ * holds references to blocks in the input file (such as the DSB). Even if
+ * those DSBs are only written when wtap_dump is called and nothing bad will
+ * happen now, let's keep all pointers in pdh valid for correctness sake. */
+ merge_close_in_files(in_file_count, in_files);
+
if (status == MERGE_OK || in_file == NULL) {
*err_fileno = 0;
*err_framenum = 0;
@@ -964,6 +982,7 @@ merge_files_common(const gchar* out_filename, /* normal output mode */
wtap_dumper *pdh;
GArray *shb_hdrs = NULL;
wtapng_iface_descriptions_t *idb_inf = NULL;
+ GArray *dsb_combined = NULL;
g_assert(in_file_count > 0);
g_assert(in_filenames != NULL);
@@ -1017,6 +1036,8 @@ merge_files_common(const gchar* out_filename, /* normal output mode */
/* XXX other blocks like NRB are now discarded. */
params.shb_hdrs = shb_hdrs;
params.idb_inf = idb_inf;
+ dsb_combined = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
+ params.dsbs_growing = dsb_combined;
}
if (out_filename) {
pdh = wtap_dump_open(out_filename, file_type, WTAP_UNCOMPRESSED, &params, err);
@@ -1031,6 +1052,9 @@ merge_files_common(const gchar* out_filename, /* normal output mode */
g_free(in_files);
wtap_block_array_free(shb_hdrs);
wtap_free_idb_info(idb_inf);
+ if (dsb_combined) {
+ g_array_free(dsb_combined, TRUE);
+ }
*err_framenum = 0;
return MERGE_ERR_CANT_OPEN_OUTFILE;
}
@@ -1039,12 +1063,15 @@ merge_files_common(const gchar* out_filename, /* normal output mode */
cb->callback_func(MERGE_EVENT_READY_TO_MERGE, 0, in_files, in_file_count, cb->data);
status = merge_process_packets(pdh, file_type, in_files, in_file_count,
- do_append, snaplen, cb, err, err_info,
+ do_append, snaplen, cb, dsb_combined, err, err_info,
err_fileno, err_framenum);
g_free(in_files);
wtap_block_array_free(shb_hdrs);
wtap_free_idb_info(idb_inf);
+ if (dsb_combined) {
+ g_array_free(dsb_combined, TRUE);
+ }
return status;
}