summaryrefslogtreecommitdiff
path: root/ui
diff options
context:
space:
mode:
authorBrian Potchik <brian@vector35.com>2025-10-10 09:34:08 -0400
committerBrian Potchik <brian@vector35.com>2025-10-10 09:34:08 -0400
commit5c41155a46f93ead2b1d7feda8e6bc6f5b4f9549 (patch)
treedda665f5ec8b8e92d490f6b1efea3e35868ee096 /ui
parent47f5c67fd7f68dfd95392531431a3efca0ccda3c (diff)
Add password prompting for encrypted containers in Container Browser.
Diffstat (limited to 'ui')
-rw-r--r--ui/containerbrowser.h57
-rw-r--r--ui/passworddialog.h34
-rw-r--r--ui/passwordedit.h6
3 files changed, 68 insertions, 29 deletions
diff --git a/ui/containerbrowser.h b/ui/containerbrowser.h
index 08e04b2b..515a2836 100644
--- a/ui/containerbrowser.h
+++ b/ui/containerbrowser.h
@@ -19,12 +19,31 @@ class ContainerTreeModel : public QAbstractItemModel
{
Q_OBJECT
+ struct Node
+ {
+ QString displayName; // GetFileName() (or synthesized for root)
+ QString type; // GetTransformName() or "Leaf"/"Root"
+ QString breadcrumb; // human-readable path "a ▸ b ▸ c"
+ QStringList pathSegments; // list of filenames from root to this node
+ QString size;
+ TransformContextRef ctx;
+ Node* parent = nullptr;
+ std::vector<std::unique_ptr<Node>> children;
+ };
+
+ TransformSessionRef m_session;
+ std::unique_ptr<Node> m_root;
+ QLocale m_locale;
+
+ const Node* nodeFromIndex(const QModelIndex& index) const;
+ static QString joinBreadcrumb(const QStringList& segments);
+ void createChildren(Node* parentNode, const std::vector<TransformContextRef>& children, const QStringList& parentSegments = {});
+
public:
enum Columns { ColName, ColType, ColSize, ColPath, ColCount };
- explicit ContainerTreeModel(TransformSessionRef session, QObject* parent = nullptr);
+ ContainerTreeModel(TransformSessionRef session, QObject* parent = nullptr);
- // QAbstractItemModel interface
int columnCount(const QModelIndex& parent = {}) const override;
QModelIndex index(int row, int column, const QModelIndex& parent = {}) const override;
QModelIndex parent(const QModelIndex& child) const override;
@@ -33,33 +52,12 @@ public:
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
Qt::ItemFlags flags(const QModelIndex& index) const override;
- // Public helpers for the dialog
- bool isLeaf(const QModelIndex& index) const;
+ QString getDisplayName(const QModelIndex& index) const;
+ TransformContextRef getTransformContext(const QModelIndex& index) const;
+
QStringList pathFor(const QModelIndex& index) const;
void selectNode(const QModelIndex& index);
void rebuild();
-
-private:
- struct Node
- {
- QString displayName; // GetFileName() (or synthesized for root)
- QString type; // GetTransformName() or "Leaf"/"Root"
- QString breadcrumb; // human-readable path "a ▸ b ▸ c"
- QStringList pathSegments; // list of filenames from root to this node
- quint64 size = 0; // not exposed (kept for future metadata)
- bool isLeaf = false;
- bool selectable = true; // we allow selection only on leaves
- TransformContextRef ctx;
- Node* parent = nullptr;
- std::vector<std::unique_ptr<Node>> children;
- };
-
- const Node* nodeFromIndex(const QModelIndex& index) const;
- static QString joinBreadcrumb(const QStringList& segments);
- void buildChildren(Node* parentNode, const TransformContextRef& ctx, const QStringList& parentSegments);
-
- TransformSessionRef m_session;
- std::unique_ptr<Node> m_root;
};
@@ -87,15 +85,20 @@ class BINARYNINJAUIAPI ContainerBrowser : public QDialog
QTreeView* m_tree = nullptr;
QPlainTextEdit* m_preview = nullptr;
QLabel* m_status = nullptr;
+ QLabel* m_extractionStatus = nullptr;
QDialogButtonBox* m_buttons = nullptr;
AllColumnsFilterProxyModel* m_proxy = nullptr;
+ QStringList m_pendingSelectionPath;
QStringList m_selectedPaths;
void connectSignals();
- void loadRoot();
void updatePreviewForIndex(const QModelIndex& proxyIndex);
+ bool requiresPassword(TransformContextRef context);
+ void promptForPassword(TransformContextRef context, bool tryCachedPassword = false);
+ void showContextMenu(const QPoint& position);
static QString toHexDump(const QByteArray& data, int bytesPerLine = 16);
+ QModelIndex findNodeByPath(const QStringList& path);
public:
ContainerBrowser(TransformSessionRef session, QWidget* parent = nullptr);
diff --git a/ui/passworddialog.h b/ui/passworddialog.h
new file mode 100644
index 00000000..9f1f01b4
--- /dev/null
+++ b/ui/passworddialog.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <QDialog>
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QPushButton>
+#include <QCheckBox>
+#include <QDialogButtonBox>
+#include "uitypes.h"
+#include "passwordedit.h"
+
+
+class BINARYNINJAUIAPI PasswordDialog : public QDialog
+{
+ Q_OBJECT
+
+ PasswordEdit* m_passwordEdit = nullptr;
+ QDialogButtonBox* m_buttons = nullptr;
+ QCheckBox* m_saveCheckBox = nullptr;
+
+public:
+ PasswordDialog(QWidget* parent, const QString& resource, bool showSaveOption = false);
+
+ QString password() const;
+ bool shouldSavePassword() const;
+ void notifyInvalid();
+
+signals:
+ void validate(const QString& password, bool shouldSave);
+
+private slots:
+ void onTextChanged();
+};
diff --git a/ui/passwordedit.h b/ui/passwordedit.h
index 7c34c49e..f919803b 100644
--- a/ui/passwordedit.h
+++ b/ui/passwordedit.h
@@ -5,9 +5,11 @@
class BINARYNINJAUIAPI PasswordEdit: public QLineEdit
{
+ Q_OBJECT
+
public:
PasswordEdit(QWidget* parent = nullptr);
- virtual void focusInEvent(QFocusEvent* e) override;
- virtual void focusOutEvent(QFocusEvent* e) override;
+private slots:
+ void showContextMenu(const QPoint& pos);
};