aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDario Lombardo <lomato@gmail.com>2019-05-29 16:06:38 +0200
committerDario Lombardo <lomato@gmail.com>2019-06-26 07:09:54 +0000
commit1af6e1f8603825d9781815c6cd25e7dca31ca147 (patch)
tree770a75a723b39ca17ead4c7b9245b5d3a9996985
parent94d0e081c6159f3002c2eb56807a5551d541948d (diff)
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>
-rw-r--r--CMakeLists.txt1
-rw-r--r--doc/tshark.pod7
-rw-r--r--docbook/release-notes.adoc3
-rw-r--r--docbook/wsug_src/WSUG_chapter_use.adoc1
-rw-r--r--epan/dissectors/packet-ftp.c26
-rw-r--r--epan/dissectors/packet-http.c40
-rw-r--r--ui/cli/tap-credentials.c92
-rw-r--r--ui/qt/CMakeLists.txt5
-rw-r--r--ui/qt/credentials_dialog.cpp104
-rw-r--r--ui/qt/credentials_dialog.h55
-rw-r--r--ui/qt/credentials_dialog.ui55
-rw-r--r--ui/qt/main_window.h1
-rw-r--r--ui/qt/main_window.ui6
-rw-r--r--ui/qt/main_window_slots.cpp6
-rw-r--r--ui/qt/models/credentials_model.cpp155
-rw-r--r--ui/qt/models/credentials_model.h57
-rw-r--r--ui/qt/models/url_link_delegate.h2
-rw-r--r--ui/qt/packet_list.cpp14
-rw-r--r--ui/qt/packet_list.h3
-rw-r--r--ui/tap-credentials.h26
20 files changed, 644 insertions, 15 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3f6ee1114f..7773fa8871 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -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
diff --git a/doc/tshark.pod b/doc/tshark.pod
index 296d7b65ea..5d22a9d06c 100644
--- a/doc/tshark.pod
+++ b/doc/tshark.pod
@@ -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
diff --git a/docbook/release-notes.adoc b/docbook/release-notes.adoc
index d577da4442..ad00091800 100644
--- a/docbook/release-notes.adoc
+++ b/docbook/release-notes.adoc
@@ -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
diff --git a/docbook/wsug_src/WSUG_chapter_use.adoc b/docbook/wsug_src/WSUG_chapter_use.adoc
index 4d32f6d627..1ccd8906f4 100644
--- a/docbook/wsug_src/WSUG_chapter_use.adoc
+++ b/docbook/wsug_src/WSUG_chapter_use.adoc
@@ -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 Developer’s 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]]
diff --git a/epan/dissectors/packet-ftp.c b/epan/dissectors/packet-ftp.c
index 2671ad6595..953007ec39 100644
--- a/epan/dissectors/packet-ftp.c
+++ b/epan/dissectors/packet-ftp.c
@@ -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
diff --git a/epan/dissectors/packet-http.c b/epan/dissectors/packet-http.c
index f48e898411..c37c408142 100644
--- a/epan/dissectors/packet-http.c
+++ b/epan/dissectors/packet-http.c
@@ -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);
diff --git a/ui/cli/tap-credentials.c b/ui/cli/tap-credentials.c
new file mode 100644
index 0000000000..ea50b9eddd
--- /dev/null
+++ b/ui/cli/tap-credentials.c
@@ -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:
+ */
diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt
index f9e3667606..4803ccf7e4 100644
--- a/ui/qt/CMakeLists.txt
+++ b/ui/qt/CMakeLists.txt
@@ -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
diff --git a/ui/qt/credentials_dialog.cpp b/ui/qt/credentials_dialog.cpp
new file mode 100644
index 0000000000..25ed4076e4
--- /dev/null
+++ b/ui/qt/credentials_dialog.cpp
@@ -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:
+ */
diff --git a/ui/qt/credentials_dialog.h b/ui/qt/credentials_dialog.h
new file mode 100644
index 0000000000..a2a881bd39
--- /dev/null
+++ b/ui/qt/credentials_dialog.h
@@ -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:
+ */
diff --git a/ui/qt/credentials_dialog.ui b/ui/qt/credentials_dialog.ui
new file mode 100644
index 0000000000..16e5b3361d
--- /dev/null
+++ b/ui/qt/credentials_dialog.ui
@@ -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>
diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h
index cba3ced572..5a5da269eb 100644
--- a/ui/qt/main_window.h
+++ b/ui/qt/main_window.h
@@ -673,6 +673,7 @@ private slots:
void on_actionBluetoothHCI_Summary_triggered();
void on_actionToolsFirewallAclRules_triggered();
+ void on_actionToolsCredentials_triggered();
void externalMenuItem_triggered();
diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui
index 4d2dcff706..d3d2b59dc2 100644
--- a/ui/qt/main_window.ui
+++ b/ui/qt/main_window.ui
@@ -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>
diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp
index 6fe9d83935..c7a6e8ac6b 100644
--- a/ui/qt/main_window_slots.cpp
+++ b/ui/qt/main_window_slots.cpp
@@ -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() {
diff --git a/ui/qt/models/credentials_model.cpp b/ui/qt/models/credentials_model.cpp
new file mode 100644
index 0000000000..8e954d2e61
--- /dev/null
+++ b/ui/qt/models/credentials_model.cpp
@@ -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:
+ */
diff --git a/ui/qt/models/credentials_model.h b/ui/qt/models/credentials_model.h
new file mode 100644
index 0000000000..63614a8628
--- /dev/null
+++ b/ui/qt/models/credentials_model.h
@@ -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:
+ */
diff --git a/ui/qt/models/url_link_delegate.h b/ui/qt/models/url_link_delegate.h
index 4167704f52..7bab83fe6c 100644
--- a/ui/qt/models/url_link_delegate.h
+++ b/ui/qt/models/url_link_delegate.h
@@ -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_;
diff --git a/ui/qt/packet_list.cpp b/ui/qt/packet_list.cpp
index 908f03f0aa..4563a605ca 100644
--- a/ui/qt/packet_list.cpp
+++ b/ui/qt/packet_list.cpp
@@ -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)) {
diff --git a/ui/qt/packet_list.h b/ui/qt/packet_list.h
index 2606146f04..437681c55d 100644
--- a/ui/qt/packet_list.h
+++ b/ui/qt/packet_list.h
@@ -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();
diff --git a/ui/tap-credentials.h b/ui/tap-credentials.h
new file mode 100644
index 0000000000..362ebca153
--- /dev/null
+++ b/ui/tap-credentials.h
@@ -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