wiretap,file.c: ensure DSBs are reapplied on redissection

After redissection, the TLS dissector did not remember the DSB secrets
anymore. Since the secrets callback is only invoked on the sequential
read in wtap, be sure to reapply the existing DSBs to the new session.

Bug: 15252
Change-Id: I125f095acb8d577c2439a10e3e65c8b3cfd976b9
Reviewed-on: https://code.wireshark.org/review/31584
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Peter Wu 2019-01-18 01:54:22 +01:00 committed by Anders Broman
parent ae394464df
commit e8f9ac3352
4 changed files with 42 additions and 7 deletions

12
file.c
View File

@ -1740,6 +1740,18 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item, gb
epan_dissect_init(&edt, cf->epan, create_proto_tree, FALSE);
if (redissect) {
/*
* Decryption secrets are read while sequentially processing records and
* then passed to the dissector. During redissection, the previous secrets
* are lost (see epan_free above), but they are not read again from the
* file as only packet records are re-read. Therefore reset the wtap secrets
* callback such that wtap resupplies the secrets callback with previously
* read secrets.
*/
wtap_set_cb_new_secrets(cf->provider.wth, secrets_wtap_callback);
}
for (framenum = 1; framenum <= frames_count; framenum++) {
fdata = frame_data_sequence_find(cf->provider.frames, framenum);

View File

@ -2646,11 +2646,7 @@ pcapng_process_idb(wtap *wth, pcapng_t *pcapng, wtapng_block_t *wblock)
static void
pcapng_process_dsb(wtap *wth, wtapng_block_t *wblock)
{
const wtapng_dsb_mandatory_t *dsb = (wtapng_dsb_mandatory_t*)wtap_block_get_mandatory_data(wblock->block);
if (wth->add_new_secrets) {
wth->add_new_secrets(dsb->secrets_type, dsb->secrets_data, dsb->secrets_len);
}
wtapng_process_dsb(wth, wblock->block);
/* Store DSB such that it can be saved by the dumper. */
g_array_append_val(wth->dsbs, wblock->block);

View File

@ -326,6 +326,12 @@ wtap_full_file_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset);
*/
gboolean
wtap_full_file_seek_read(wtap *wth, gint64 seek_off, wtap_rec *rec, Buffer *buf, int *err, gchar **err_info);
/**
* Invokes the callback with the given decryption secrets block.
*/
void
wtapng_process_dsb(wtap *wth, wtap_block_t dsb);
#endif /* __WTAP_INT_H__ */
/*

View File

@ -1266,8 +1266,29 @@ void wtap_set_cb_new_ipv6(wtap *wth, wtap_new_ipv6_callback_t add_new_ipv6) {
}
void wtap_set_cb_new_secrets(wtap *wth, wtap_new_secrets_callback_t add_new_secrets) {
if (wth)
wth->add_new_secrets = add_new_secrets;
/* Is a valid wth given that supports DSBs? */
if (!wth || !wth->dsbs)
return;
wth->add_new_secrets = add_new_secrets;
/*
* Send all DSBs that were read so far to the new callback. file.c
* relies on this to support redissection (during redissection, the
* previous secrets are lost and has to be resupplied).
*/
for (guint i = 0; i < wth->dsbs->len; i++) {
wtap_block_t dsb = g_array_index(wth->dsbs, wtap_block_t, i);
wtapng_process_dsb(wth, dsb);
}
}
void
wtapng_process_dsb(wtap *wth, wtap_block_t dsb)
{
const wtapng_dsb_mandatory_t *dsb_mand = (wtapng_dsb_mandatory_t*)wtap_block_get_mandatory_data(dsb);
if (wth->add_new_secrets)
wth->add_new_secrets(dsb_mand->secrets_type, dsb_mand->secrets_data, dsb_mand->secrets_len);
}
gboolean