diff options
| author | Brian Potchik <brian@vector35.com> | 2025-10-10 09:34:08 -0400 |
|---|---|---|
| committer | Brian Potchik <brian@vector35.com> | 2025-10-10 09:34:08 -0400 |
| commit | 5c41155a46f93ead2b1d7feda8e6bc6f5b4f9549 (patch) | |
| tree | dda665f5ec8b8e92d490f6b1efea3e35868ee096 /ui | |
| parent | 47f5c67fd7f68dfd95392531431a3efca0ccda3c (diff) | |
Add password prompting for encrypted containers in Container Browser.
Diffstat (limited to 'ui')
| -rw-r--r-- | ui/containerbrowser.h | 57 | ||||
| -rw-r--r-- | ui/passworddialog.h | 34 | ||||
| -rw-r--r-- | ui/passwordedit.h | 6 |
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); }; |
