Use follow_record_t in SSL follow stream.

... rather than a structure (SslDecryptedRecord) which looks (mostly) like a
follow_record_t.  (The biggest different is the former carries its data in a
StringInfo while the latter uses a GByteArray.)

With this change following SSL no longer needs its own special code.

This also fixes a crash after saving a followed SSL stream (in the Qt UI).

Bug: 12616
Change-Id: Ibdb2b85f8a6a30712743a5da420be1e6b78f5b92
Reviewed-on: https://code.wireshark.org/review/16516
Petri-Dish: Jeff Morriss <jeff.morriss.ws@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
This commit is contained in:
Jeff Morriss 2016-07-17 15:24:55 -04:00 committed by Peter Wu
parent 752ba1abad
commit 468a5e2725
4 changed files with 16 additions and 149 deletions

View File

@ -403,12 +403,6 @@ typedef struct _SslDecryptSession {
} SslDecryptSession;
typedef struct {
gboolean is_from_server;
guint32 packet_num;
StringInfo data;
} SslDecryptedRecord;
/* User Access Table */
typedef struct _ssldecrypt_assoc_t {
char* ipaddr;

View File

@ -460,7 +460,7 @@ static gboolean
ssl_follow_tap_listener(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, const void *ssl)
{
follow_info_t * follow_info = (follow_info_t*) tapdata;
SslDecryptedRecord * rec = NULL;
follow_record_t * follow_record = NULL;
const SslDataInfo * appl_data = NULL;
const SslPacketInfo * pi = (const SslPacketInfo*)ssl;
show_stream_t from = FROM_CLIENT;
@ -491,23 +491,27 @@ ssl_follow_tap_listener(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _
already been processed and must be skipped. */
if (appl_data->seq < follow_info->bytes_written[from]) continue;
/* Allocate a SslDecryptedRecord to hold the current appl_data
/* Allocate a follow_record_t to hold the current appl_data
instance's decrypted data. Even though it would be possible to
consolidate multiple appl_data instances into a single rec, it is
consolidate multiple appl_data instances into a single record, it is
beneficial to use a one-to-one mapping. This affords the Follow
Stream dialog view modes (ASCII, EBCDIC, Hex Dump, C Arrays, Raw)
the opportunity to accurately reflect SSL PDU boundaries. Currently
the Hex Dump view does by starting a new line, and the C Arrays
view does by starting a new array declaration. */
rec = (SslDecryptedRecord*) g_malloc(sizeof(SslDecryptedRecord) + appl_data->plain_data.data_len);
rec->is_from_server = from == FROM_SERVER;
rec->data.data = (guchar*) (rec + 1);
rec->data.data_len = appl_data->plain_data.data_len;
memcpy(rec->data.data, appl_data->plain_data.data, appl_data->plain_data.data_len);
follow_record = g_new(follow_record_t,1);
follow_record->is_server = (from == FROM_SERVER);
follow_record->packet_num = pinfo->num;
follow_record->data = g_byte_array_sized_new(appl_data->plain_data.data_len);
follow_record->data = g_byte_array_append(follow_record->data,
appl_data->plain_data.data,
appl_data->plain_data.data_len);
/* Append the record to the follow_info structure. */
follow_info->payload = g_list_append(follow_info->payload, rec);
follow_info->bytes_written[from] += rec->data.data_len;
follow_info->payload = g_list_append(follow_info->payload, follow_record);
follow_info->bytes_written[from] += appl_data->plain_data.data_len;
}
return FALSE;

View File

@ -36,7 +36,6 @@
#include <epan/tap.h>
#include <epan/print.h>
#include <epan/dissectors/packet-ssl-utils.h>
#include <ui/alert_box.h>
#include <ui/last_open_dir.h>
@ -1235,66 +1234,6 @@ follow_http_stream_cb(GtkWidget * w _U_, gpointer data _U_)
follow_stream_cb(follower, follow_common_read_stream, w, data);
}
/*
* XXX - the routine pointed to by "print_line_fcn_p" doesn't get handed lines,
* it gets handed bufferfuls. That's fine for "follow_write_raw()"
* and "follow_add_to_gtk_text()", but, as "follow_print_text()" calls
* the "print_line()" routine from "print.c", and as that routine might
* genuinely expect to be handed a line (if, for example, it's using
* some OS or desktop environment's printing API, and that API expects
* to be handed lines), "follow_print_text()" should probably accumulate
* lines in a buffer and hand them "print_line()". (If there's a
* complete line in a buffer - i.e., there's nothing of the line in
* the previous buffer or the next buffer - it can just hand that to
* "print_line()" after filtering out non-printables, as an
* optimization.)
*
* This might or might not be the reason why C arrays display
* correctly but get extra blank lines very other line when printed.
*/
static frs_return_t
follow_read_ssl_stream(follow_info_t *follow_info,
follow_print_line_func follow_print,
void *arg)
{
guint32 global_client_pos = 0, global_server_pos = 0;
guint32 server_packet_count = 0;
guint32 client_packet_count = 0;
guint32 * global_pos;
GList * cur;
frs_return_t frs_return;
for (cur = follow_info->payload; cur; cur = g_list_next(cur)) {
SslDecryptedRecord * rec = (SslDecryptedRecord*) cur->data;
gboolean include_rec = FALSE;
if (rec->is_from_server) {
global_pos = &global_server_pos;
include_rec = (follow_info->show_stream == BOTH_HOSTS) ||
(follow_info->show_stream == FROM_SERVER);
} else {
global_pos = &global_client_pos;
include_rec = (follow_info->show_stream == BOTH_HOSTS) ||
(follow_info->show_stream == FROM_CLIENT);
}
if (include_rec) {
size_t nchars = rec->data.data_len;
gchar *buffer = (gchar *)g_memdup(rec->data.data, (guint) nchars);
frs_return = follow_show(follow_info, follow_print, buffer, nchars,
rec->is_from_server, arg, global_pos,
&server_packet_count, &client_packet_count);
g_free(buffer);
if (frs_return == FRS_PRINT_ERROR)
return frs_return;
}
}
return FRS_OK;
}
/* Follow the SSL stream, if any, to which the last packet that we called
a dissection routine on belongs (this might be the most recently
selected packet, or it might be the last packet in the file). */
@ -1303,7 +1242,7 @@ follow_ssl_stream_cb(GtkWidget * w _U_, gpointer data _U_)
{
register_follow_t* follower = get_follow_by_name("SSL");
follow_stream_cb(follower, follow_read_ssl_stream, w, data);
follow_stream_cb(follower, follow_common_read_stream, w, data);
}
static void

View File

@ -28,7 +28,6 @@
#include "epan/follow.h"
#include "epan/dissectors/packet-tcp.h"
#include "epan/dissectors/packet-udp.h"
#include "epan/dissectors/packet-ssl-utils.h"
#include "epan/prefs.h"
#include "epan/addr_resolv.h"
#include "epan/charsets.h"
@ -427,11 +426,8 @@ FollowStreamDialog::readStream()
case FOLLOW_TCP :
case FOLLOW_UDP :
case FOLLOW_HTTP :
ret = readFollowStream();
break;
case FOLLOW_SSL :
ret = readSslStream();
ret = readFollowStream();
break;
default :
@ -443,72 +439,6 @@ FollowStreamDialog::readStream()
return ret;
}
/*
* XXX - the routine pointed to by "print_line_fcn_p" doesn't get handed lines,
* it gets handed bufferfuls. That's fine for "follow_write_raw()"
* and "follow_add_to_gtk_text()", but, as "follow_print_text()" calls
* the "print_line()" routine from "print.c", and as that routine might
* genuinely expect to be handed a line (if, for example, it's using
* some OS or desktop environment's printing API, and that API expects
* to be handed lines), "follow_print_text()" should probably accumulate
* lines in a buffer and hand them "print_line()". (If there's a
* complete line in a buffer - i.e., there's nothing of the line in
* the previous buffer or the next buffer - it can just hand that to
* "print_line()" after filtering out non-printables, as an
* optimization.)
*
* This might or might not be the reason why C arrays display
* correctly but get extra blank lines very other line when printed.
*/
frs_return_t
FollowStreamDialog::readSslStream()
{
guint32 global_client_pos = 0, global_server_pos = 0;
guint32 * global_pos;
GList * cur;
frs_return_t frs_return;
QElapsedTimer elapsed_timer;
elapsed_timer.start();
for (cur = follow_info_.payload; cur; cur = g_list_next(cur)) {
if (dialogClosed()) break;
SslDecryptedRecord * rec = (SslDecryptedRecord*) cur->data;
gboolean include_rec = FALSE;
if (rec->is_from_server) {
global_pos = &global_server_pos;
include_rec = (follow_info_.show_stream == BOTH_HOSTS) ||
(follow_info_.show_stream == FROM_SERVER);
} else {
global_pos = &global_client_pos;
include_rec = (follow_info_.show_stream == BOTH_HOSTS) ||
(follow_info_.show_stream == FROM_CLIENT);
}
QByteArray buffer;
if (include_rec) {
size_t nchars = rec->data.data_len;
// We want a deep copy.
buffer.clear();
buffer.append((const char *) rec->data.data, (int)nchars);
frs_return = showBuffer(buffer.data(), nchars,
rec->is_from_server, rec->packet_num, global_pos);
if (frs_return == FRS_PRINT_ERROR)
return frs_return;
if (elapsed_timer.elapsed() > info_update_freq_) {
fillHintLabel(ui->teStreamContent->textCursor().position());
wsApp->processEvents();
elapsed_timer.start();
}
}
}
return FRS_OK;
}
void
FollowStreamDialog::followStream()
{