tap: add credentials tap.

This new tap collects credentials (username and paassword)
from the dissectors.

So far, few dissectors have been instrumented:
- http (basic auth)
- http (header auth)
- ftp
Others can be instrumented as well using the same technique.

Tshark has a new option (-z credentials) and Wireshark a new
"tools" menu: the documentation has been updated accordingly.

Change-Id: I2d0d96598c85bb3ea4fb5ec090dd8dc28b481fc9
Reviewed-on: https://code.wireshark.org/review/33453
Reviewed-by: Gerald Combs <gerald@wireshark.org>
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot
Reviewed-by: Dario Lombardo <lomato@gmail.com>
This commit is contained in:
Dario Lombardo 2019-05-29 16:06:38 +02:00
parent 94d0e081c6
commit 1af6e1f860
20 changed files with 644 additions and 15 deletions

View File

@ -1635,6 +1635,7 @@ elseif(APPLE)
endif()
set(TSHARK_TAP_SRC
${CMAKE_SOURCE_DIR}/ui/cli/tap-credentials.c
${CMAKE_SOURCE_DIR}/ui/cli/tap-camelsrt.c
${CMAKE_SOURCE_DIR}/ui/cli/tap-diameter-avp.c
${CMAKE_SOURCE_DIR}/ui/cli/tap-expert.c

View File

@ -1583,6 +1583,13 @@ on those calls that match that filter.
Example: B<-z "mgcp,rtd,ip.addr==1.2.3.4"> will only collect stats for
MGCP packets exchanged by the host at IP address 1.2.3.4 .
=item B<-z> credentials
Collect credentials (username/passwords) from packets. The report includes
the packet number, the protocol that had that credential, the username and
the password. For protocols just using one sigle field as authentication,
this is provided as a password and a placeholder in place of the user.
=item B<-z> proto,colinfo,I<filter>,I<field>
Append all I<field> values for the packet to the Info column of the

View File

@ -41,6 +41,9 @@ since version 3.0.0:
bundled Speex resampler code is still provided as a fallback.
* WireGuard decryption can now be enabled through keys embedded in a pcapng in
addition to the existing key log preference (wsbuglink:15571[]).
* A new tap for extracting credentials from the capture file has been added.
It can be accessed through the "-z credentials" option in tshark or from the
"tools" menu in Wireshark.
// === Removed Features and Support

View File

@ -671,6 +671,7 @@ image::wsug_graphics/ws-tools-menu.png[{screenshot-attrs}]
It is assumed that the rules will be applied to an outside interface.
|menu:Lua[]|| These options allow you to work with the Lua interpreter optionally build into Wireshark. See the “Lua Support in Wireshark” in the Wireshark Developers Guide.
|menu:Credentials[]|| This allows you to extract credentials from the current capture file. Some of the dissectors have been instrumented to provide the module with usernames and passwords and more will be instrumented in te future. The window dialog provides you the packet number where the credentials have been found, the protocol that provided them, the username and the password.
|===============
[[ChUseHelpMenuSection]]

View File

@ -24,9 +24,14 @@
#include <epan/addr_resolv.h>
#include <epan/proto_data.h>
#include <tap.h>
#include <ui/tap-credentials.h>
void proto_register_ftp(void);
void proto_reg_handoff_ftp(void);
static int credentials_tap = -1;
static int proto_ftp = -1;
static int proto_ftp_data = -1;
static int hf_ftp_current_working_directory = -1;
@ -184,6 +189,8 @@ typedef struct ftp_conversation_t
wmem_strbuf_t *current_working_directory;
ftp_data_conversation_t *current_data_conv; /* Current data conversation (during first pass) */
guint32 current_data_setup_frame;
gchar *username;
guint username_pkt_num;
} ftp_conversation_t;
/* For a given packet, retrieve or initialise a new conversation, and return it */
@ -937,6 +944,23 @@ dissect_ftp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
*/
else if (strncmp(line, "EPRT", tokenlen) == 0)
is_eprt_request = TRUE;
else if (strncmp(line, "USER", tokenlen) == 0) {
if (p_ftp_conv) {
p_ftp_conv->username = wmem_strndup(wmem_file_scope(), line + tokenlen + 1, linelen - tokenlen - 1);
p_ftp_conv->username_pkt_num = pinfo->num;
}
} else if (strncmp(line, "PASS", tokenlen) == 0) {
if (p_ftp_conv && p_ftp_conv->username) {
tap_credential_t* auth = wmem_new0(wmem_file_scope(), tap_credential_t);
auth->num = pinfo->num;
auth->proto = "FTP";
auth->password_hf_id = hf_ftp_request_arg;
auth->username = p_ftp_conv->username;
auth->username_num = p_ftp_conv->username_pkt_num;
auth->info = wmem_strdup_printf(wmem_file_scope(), "Username in packet: %u", p_ftp_conv->username_pkt_num);
tap_queue_packet(credentials_tap, pinfo, auth);
}
}
}
/* If there is an ftp data conversation that doesn't have a
@ -1628,6 +1652,8 @@ proto_register_ftp(void)
register_init_routine(&ftp_init_protocol);
register_cleanup_routine(&ftp_cleanup_protocol);
credentials_tap = register_tap("credentials");
}
void

View File

@ -38,6 +38,8 @@
#include "packet-tcp.h"
#include "packet-tls.h"
#include <ui/tap-credentials.h>
void proto_register_http(void);
void proto_reg_handoff_http(void);
void proto_register_message_http(void);
@ -46,6 +48,7 @@ void proto_reg_handoff_message_http(void);
static int http_tap = -1;
static int http_eo_tap = -1;
static int http_follow_tap = -1;
static int credentials_tap = -1;
static int proto_http = -1;
static int proto_http2 = -1;
@ -316,7 +319,7 @@ static gint find_header_hf_value(tvbuff_t *tvb, int offset, guint header_len);
static gboolean check_auth_ntlmssp(proto_item *hdr_item, tvbuff_t *tvb,
packet_info *pinfo, gchar *value);
static gboolean check_auth_basic(proto_item *hdr_item, tvbuff_t *tvb,
gchar *value);
packet_info *pinfo, gchar *value);
static gboolean check_auth_citrixbasic(proto_item *hdr_item, tvbuff_t *tvb,
gchar *value, int offset);
static gboolean check_auth_kerberos(proto_item *hdr_item, tvbuff_t *tvb,
@ -2976,6 +2979,7 @@ process_header(tvbuff_t *tvb, int offset, int next_offset,
proto_item *hdr_item, *it;
int i;
int* hf_id;
tap_credential_t* auth;
len = next_offset - offset;
line_end_offset = offset + linelen;
@ -3156,11 +3160,18 @@ process_header(tvbuff_t *tvb, int offset, int next_offset,
case HDR_AUTHORIZATION:
if (check_auth_ntlmssp(hdr_item, tvb, pinfo, value))
break; /* dissected NTLMSSP */
if (check_auth_basic(hdr_item, tvb, value))
if (check_auth_basic(hdr_item, tvb, pinfo, value))
break; /* dissected basic auth */
if (check_auth_citrixbasic(hdr_item, tvb, value, offset))
break; /* dissected citrix basic auth */
check_auth_kerberos(hdr_item, tvb, pinfo, value);
if (check_auth_kerberos(hdr_item, tvb, pinfo, value))
break;
auth = wmem_new0(wmem_file_scope(), tap_credential_t);
auth->num = pinfo->num;
auth->password_hf_id = *headers[hf_index].hf;
auth->proto = wmem_strdup(wmem_file_scope(), "HTTP header auth");
auth->username = wmem_strdup(wmem_file_scope(), TAP_CREDENTIALS_PLACEHOLDER);
tap_queue_packet(credentials_tap, pinfo, auth);
break;
case HDR_AUTHENTICATE:
@ -3372,11 +3383,27 @@ check_auth_ntlmssp(proto_item *hdr_item, tvbuff_t *tvb, packet_info *pinfo, gcha
return FALSE;
}
static tap_credential_t*
basic_auth_credentials(gchar* str)
{
gchar **tokens = g_strsplit(str, ":", -1);
if (!tokens || !tokens[0] || !tokens[1])
return NULL;
tap_credential_t* auth = wmem_new0(wmem_file_scope(), tap_credential_t);
auth->username = tokens[0];
auth->proto = "HTTP basic auth";
return auth;
}
/*
* Dissect HTTP Basic authorization.
*/
static gboolean
check_auth_basic(proto_item *hdr_item, tvbuff_t *tvb, gchar *value)
check_auth_basic(proto_item *hdr_item, tvbuff_t *tvb, packet_info *pinfo, gchar *value)
{
static const char *basic_headers[] = {
"Basic ",
@ -3403,6 +3430,10 @@ check_auth_basic(proto_item *hdr_item, tvbuff_t *tvb, gchar *value)
}
proto_tree_add_string(hdr_tree, hf_http_basic, tvb,
0, 0, value);
tap_credential_t* auth = basic_auth_credentials(value);
auth->num = auth->username_num = pinfo->num;
auth->password_hf_id = hf_http_basic;
tap_queue_packet(credentials_tap, pinfo, auth);
return TRUE;
}
@ -4159,6 +4190,7 @@ proto_register_http(void)
*/
http_tap = register_tap("http"); /* HTTP statistics tap */
http_follow_tap = register_tap("http_follow"); /* HTTP Follow tap */
credentials_tap = register_tap("credentials"); /* credentials tap */
register_follow_stream(proto_http, "http_follow", tcp_follow_conv_filter, tcp_follow_index_filter, tcp_follow_address_filter,
tcp_port_to_display, follow_tvb_tap_listener);

92
ui/cli/tap-credentials.c Normal file
View File

@ -0,0 +1,92 @@
/*
* tap-credentials.c
* Copyright 2019 Dario Lombardo <lomato@gmail.com>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <epan/packet_info.h>
#include <epan/tap.h>
#include <epan/stat_tap_ui.h>
#include <ui/cmdarg_err.h>
#include <ui/tap-credentials.h>
void register_tap_listener_credentials(void);
wmem_array_t* credentials = NULL;
static tap_packet_status credentials_packet(void *p _U_, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *pri)
{
wmem_array_append(credentials, (void*)pri, 1);
return TAP_PACKET_REDRAW;
}
static void credentials_draw(void *p _U_)
{
printf("===================================================================\n");
printf("%-10s %-16s %-16s %-16s\n", "Packet", "Protocol", "Username", "Info");
printf("------ -------- -------- --------\n");
for (guint i = 0; i < wmem_array_get_count(credentials); i++) {
tap_credential_t* auth = (tap_credential_t*)wmem_array_index(credentials, i);
printf("%-10u %-16s %-16s %-16s\n", auth->num, auth->proto, auth->username, auth->info ? auth->info : "");
}
printf("===================================================================\n");
}
static void credentials_init(const char *opt_arg _U_, void *userdata _U_)
{
GString* error_string;
error_string = register_tap_listener("credentials", NULL, NULL, TL_REQUIRES_NOTHING,
NULL, credentials_packet, credentials_draw, NULL);
if (error_string) {
/* error, we failed to attach to the tap. clean up */
cmdarg_err("Couldn't register credentials tap: %s", error_string->str);
g_string_free(error_string, TRUE);
exit(1);
}
credentials = wmem_array_new(wmem_file_scope(), sizeof(tap_credential_t));
}
static stat_tap_ui credentials_ui = {
REGISTER_TOOLS_GROUP_UNSORTED,
"Username and passwords",
"credentials",
credentials_init,
0,
NULL
};
void
register_tap_listener_credentials(void)
{
register_stat_tap_ui(&credentials_ui, NULL);
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: t
* End:
*
* vi: set shiftwidth=8 tabstop=8 noexpandtab:
* :indentSize=8:tabSize=8:noTabs=false:
*/

View File

@ -83,6 +83,7 @@ set(WIRESHARK_MODEL_HEADERS
models/packet_list_model.h
models/packet_list_record.h
models/path_chooser_delegate.h
models/credentials_model.h
models/percent_bar_delegate.h
models/pref_delegate.h
models/pref_models.h
@ -177,6 +178,7 @@ set(WIRESHARK_QT_HEADERS
packet_format_group_box.h
packet_list.h
packet_range_group_box.h
credentials_dialog.h
preference_editor_frame.h
preferences_dialog.h
print_dialog.h
@ -303,6 +305,7 @@ set(WIRESHARK_MODEL_SRCS
models/numeric_value_chooser_delegate.cpp
models/packet_list_model.cpp
models/packet_list_record.cpp
models/credentials_model.cpp
models/path_chooser_delegate.cpp
models/percent_bar_delegate.cpp
models/pref_delegate.cpp
@ -390,6 +393,7 @@ set(WIRESHARK_QT_SRC
packet_format_group_box.cpp
packet_list.cpp
packet_range_group_box.cpp
credentials_dialog.cpp
preference_editor_frame.cpp
preferences_dialog.cpp
print_dialog.cpp
@ -520,6 +524,7 @@ set(WIRESHARK_QT_UI
packet_dialog.ui
packet_format_group_box.ui
packet_range_group_box.ui
credentials_dialog.ui
preference_editor_frame.ui
preferences_dialog.ui
print_dialog.ui

View File

@ -0,0 +1,104 @@
/*
* credentials_dialog.c
*
* Copyright 2019 - Dario Lombardo <lomato@gmail.com>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config.h>
#include "file.h"
#include "credentials_dialog.h"
#include <ui_credentials_dialog.h>
#include <ui/tap-credentials.h>
#include "wireshark_application.h"
#include "ui/qt/widgets/wireshark_file_dialog.h"
#include "ui/qt/models/credentials_model.h"
#include <ui/qt/models/url_link_delegate.h>
#include <QClipboard>
#include <QMessageBox>
#include <QPushButton>
#include <QTextCursor>
#include <QDebug>
class CredentialsUrlDelegate : public UrlLinkDelegate
{
public:
CredentialsUrlDelegate(QObject * parent) : UrlLinkDelegate(parent) {}
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
bool ok = false;
int val = index.data(Qt::UserRole).toInt(&ok);
if (!ok || val <= 0)
QStyledItemDelegate::paint(painter, option, index);
else
UrlLinkDelegate::paint(painter, option, index);
}
};
CredentialsDialog::CredentialsDialog(QWidget &parent, CaptureFile &cf, PacketList *packet_list) :
WiresharkDialog(parent, cf),
ui(new Ui::CredentialsDialog)
{
ui->setupUi(this);
packet_list_ = packet_list;
CredentialsModel* model = new CredentialsModel(this, cf);
ui->auths->setModel(model);
setWindowSubtitle(tr("Credentials"));
ui->auths->setRootIsDecorated(false);
ui->auths->setItemDelegateForColumn(CredentialsModel::COL_NUM, new CredentialsUrlDelegate(this));
ui->auths->setItemDelegateForColumn(CredentialsModel::COL_USERNAME, new CredentialsUrlDelegate(this));
ui->auths->resizeColumnToContents(CredentialsModel::COL_NUM);
ui->auths->resizeColumnToContents(CredentialsModel::COL_PROTO);
ui->auths->resizeColumnToContents(CredentialsModel::COL_USERNAME);
ui->auths->setSortingEnabled(true);
connect(ui->auths, SIGNAL(clicked(const QModelIndex&)), this, SLOT(actionGoToPacket(const QModelIndex&)));
}
CredentialsDialog::~CredentialsDialog()
{
delete ui;
}
void CredentialsDialog::actionGoToPacket(const QModelIndex& idx)
{
if (!idx.isValid())
return;
QVariant packet_data = idx.data(Qt::UserRole);
QVariant hf_id = idx.data(CredentialsModel::ColumnHFID);
if (!hf_id.canConvert(QVariant::Int))
hf_id = qVariantFromValue(0);
if (packet_data.canConvert(QVariant::Int))
packet_list_->goToPacket(packet_data.toInt(), hf_id.toInt());
}
/*
* Editor modelines
*
* Local Variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* ex: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/

View File

@ -0,0 +1,55 @@
/*
* credentials_dialog.h
*
* Copyright 2019 - Dario Lombardo <lomato@gmail.com>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef CREDENTIALS_DIALOG_H
#define CREDENTIALS_DIALOG_H
#include "config.h"
#include <wireshark_dialog.h>
#include "packet_list.h"
#include <ui/tap-credentials.h>
namespace Ui {
class CredentialsDialog;
}
class CredentialsDialog : public WiresharkDialog
{
Q_OBJECT
public:
explicit CredentialsDialog(QWidget &parent, CaptureFile &cf, PacketList *packet_list);
~CredentialsDialog();
private slots:
void actionGoToPacket(const QModelIndex&);
private:
Ui::CredentialsDialog *ui;
PacketList *packet_list_;
};
#endif // CREDENTIALS_DIALOG_H
/*
* Editor modelines
*
* Local Variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* ex: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/

View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CredentialsDialog</class>
<widget class="QDialog" name="CredentialsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>634</width>
<height>454</height>
</rect>
</property>
<property name="windowTitle">
<string>Wireshark - Credentials</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTreeView" name="auths">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>clicked(QAbstractButton*)</signal>
<receiver>CredentialsDialog</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -673,6 +673,7 @@ private slots:
void on_actionBluetoothHCI_Summary_triggered();
void on_actionToolsFirewallAclRules_triggered();
void on_actionToolsCredentials_triggered();
void externalMenuItem_triggered();

View File

@ -679,6 +679,7 @@
<string>&amp;Tools</string>
</property>
<addaction name="actionToolsFirewallAclRules"/>
<addaction name="actionToolsCredentials"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuEdit"/>
@ -2973,6 +2974,11 @@
<string>&amp;Full Screen</string>
</property>
</action>
<action name="actionToolsCredentials">
<property name="text">
<string>Credentials</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>

View File

@ -129,6 +129,7 @@ DIAG_ON(frame-larger-than=)
#include "packet_comment_dialog.h"
#include "packet_dialog.h"
#include "packet_list.h"
#include "credentials_dialog.h"
#include "preferences_dialog.h"
#include "print_dialog.h"
#include "profile_dialog.h"
@ -3363,6 +3364,11 @@ void MainWindow::on_actionToolsFirewallAclRules_triggered()
firewall_rules_dialog->show();
}
void MainWindow::on_actionToolsCredentials_triggered()
{
CredentialsDialog *credentials_dialog = new CredentialsDialog(*this, capture_file_, packet_list_);
credentials_dialog->show();
}
// Help Menu
void MainWindow::on_actionHelpContents_triggered() {

View File

@ -0,0 +1,155 @@
/*
* credentials_model.h
*
* Copyright 2019 - Dario Lombardo <lomato@gmail.com>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "credentials_model.h"
#include <file.h>
#include <log.h>
CredentialsModel::CredentialsModel(QObject *parent, CaptureFile& cf)
:QAbstractListModel(parent)
{
GString* error_string = register_tap_listener("credentials", this, NULL, TL_REQUIRES_NOTHING,
NULL, credentialsPacket, NULL, NULL);
if (error_string) {
g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_ERROR, "Error registering credentials tap: %s", error_string->str);
return;
}
cf_retap_packets(cf.capFile());
remove_tap_listener(this);
}
int CredentialsModel::rowCount(const QModelIndex &) const
{
return credentials_.count();
}
int CredentialsModel::columnCount(const QModelIndex &) const
{
return COL_INFO + 1;
}
QVariant CredentialsModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
tap_credential_t * auth = credentials_.at(index.row());
if (!auth)
return QVariant();
if (role == Qt::DisplayRole) {
switch (index.column()) {
case COL_NUM:
return qVariantFromValue(auth->num);
case COL_PROTO:
return QString(auth->proto);
case COL_USERNAME:
return QString(auth->username);
case COL_INFO:
return QString(auth->info);
default:
return QVariant();
}
}
if (role == Qt::UserRole) {
switch (index.column()) {
case COL_NUM:
if (auth->num > 0)
return qVariantFromValue(auth->num);
break;
case COL_USERNAME:
if (auth->username_num > 0)
return qVariantFromValue(auth->username_num);
break;
default:
return QVariant();
}
}
if (role == CredentialsModel::ColumnHFID)
return qVariantFromValue(auth->password_hf_id);
if (role == Qt::ToolTipRole) {
const QString select_msg(tr("Click to select the packet"));
switch (index.column()) {
case COL_NUM:
if (auth->num > 0)
return select_msg;
break;
case COL_USERNAME:
if (auth->username_num > 0) {
if (auth->username_num != auth->num)
return QString(tr("Click to select the packet with username"));
else
return select_msg;
} else {
return QString(tr("Username not available"));
}
break;
default:
return QVariant();
}
}
return QVariant();
}
tap_packet_status CredentialsModel::credentialsPacket(void *p, packet_info *, epan_dissect_t *, const void *pri)
{
CredentialsModel* model = (CredentialsModel*)p;
model->addRecord((tap_credential_t*)pri);
return TAP_PACKET_REDRAW;
}
void CredentialsModel::addRecord(tap_credential_t* auth)
{
credentials_.append(auth);
}
QVariant CredentialsModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole)
return QVariant();
if (orientation == Qt::Horizontal) {
switch (section) {
case COL_NUM:
return QString(tr("Packet No."));
case COL_PROTO:
return QString(tr("Protocol"));
case COL_USERNAME:
return QString(tr("Username"));
case COL_INFO:
return QString(tr("Additional Info"));
}
}
return QVariant();
}
/*
* Editor modelines
*
* Local Variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* ex: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/

View File

@ -0,0 +1,57 @@
/*
* credentials_model.h
*
* Copyright 2019 - Dario Lombardo <lomato@gmail.com>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <QAbstractListModel>
#include <QList>
#include <epan/tap.h>
#include <capture_file.h>
#include <ui/tap-credentials.h>
class CredentialsModel : public QAbstractListModel
{
Q_OBJECT
public:
CredentialsModel(QObject *parent, CaptureFile& cf);
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const ;
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
enum {
COL_NUM,
COL_PROTO,
COL_USERNAME,
COL_INFO
};
enum {
ColumnHFID = Qt::UserRole + 1
};
private:
QList<tap_credential_t*> credentials_;
static tap_packet_status credentialsPacket(void *p, packet_info *, epan_dissect_t *, const void *pri);
void addRecord(tap_credential_t* rec);
};
/*
* Editor modelines
*
* Local Variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* ex: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/

View File

@ -29,7 +29,7 @@ public:
void setColCheck(int column, QString &pattern);
protected:
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
private:
int re_col_;

View File

@ -1316,22 +1316,20 @@ void PacketList::goLastPacket(void) {
}
// XXX We can jump to the wrong packet if a display filter is applied
void PacketList::goToPacket(int packet) {
if (!cf_goto_frame(cap_file_, packet)) return;
void PacketList::goToPacket(int packet, int hf_id)
{
if (!cf_goto_frame(cap_file_, packet))
return;
int row = packet_list_model_->packetNumberToRow(packet);
if (row >= 0) {
setCurrentIndex(packet_list_model_->index(row, 0));
proto_tree_->goToHfid(hf_id);
}
scrollViewChanged(false);
}
void PacketList::goToPacket(int packet, int hf_id)
{
goToPacket(packet);
proto_tree_->goToHfid(hf_id);
}
void PacketList::goNextHistoryPacket()
{
if (haveNextHistory(true)) {

View File

@ -143,8 +143,7 @@ public slots:
void goPreviousPacket();
void goFirstPacket(bool user_selected = true);
void goLastPacket();
void goToPacket(int packet);
void goToPacket(int packet, int hf_id);
void goToPacket(int packet, int hf_id = -1);
void goNextHistoryPacket();
void goPreviousHistoryPacket();
void markFrame();

26
ui/tap-credentials.h Normal file
View File

@ -0,0 +1,26 @@
/* tap-credentials.h
* Tap credentials data structure
* Copyright 2019 - Dario Lombardo <lomato@gmail.com>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef __TAP_CREDENTIALS_H__
#define __TAP_CREDENTIALS_H__
#define TAP_CREDENTIALS_PLACEHOLDER "n.a."
typedef struct tap_credential {
guint num;
guint username_num;
guint password_hf_id;
gchar* username;
gchar* proto;
gchar* info;
} tap_credential_t;
#endif