From 509fca3c9b7a5e7f222755f70d323fcf7908930a Mon Sep 17 00:00:00 2001 From: Tamir Suliman Date: Sat, 6 Jun 2026 14:00:04 +0200 Subject: [PATCH] Fix #12 #13 - delete confirmation, rename mislabeled button, remove dead code Issue #12: IDC_BTN_SHOW_SELECTED executed a -delete command silently with no confirmation. Renamed the ID to IDC_BTN_DELETE_PASSKEY in Resource.h and the case label to reflect the actual behaviour. Added a MB_YESNO confirmation dialog showing the credential ID before any delete is executed. MB_DEFBUTTON2 makes No the default so pressing Enter cannot accidentally destroy a passkey. Issue #13: Removed all dead code accumulated during development: - 20+ commented-out MessageBox debug calls and their orphaned '// Debug:' label comments throughout the file - 6 for-loops whose entire body was a commented-out MessageBox (loops in GetDomains, GetResidentKeysWithDomains, PasskeysDialogProc refresh handler, and the WM_COMMAND passkeys handler) - Empty else{} block in FingerprintDialogProc that held only a debug comment - #include which was never used - 5 redundant forward declarations (RunCommandAndGetOutput, PopulateComboBox, PopulateListView, ResizeControls, RefreshData) whose definitions all appear before any call site; WindowProc forward declaration kept as it is genuinely needed Fixes #12 Fixes #13 --- FIDO2.1 Manager.cpp | 112 +++++++------------------------------------- Resource.h | 2 +- 2 files changed, 17 insertions(+), 97 deletions(-) diff --git a/FIDO2.1 Manager.cpp b/FIDO2.1 Manager.cpp index 2d552e1..91a18c3 100644 --- a/FIDO2.1 Manager.cpp +++ b/FIDO2.1 Manager.cpp @@ -139,16 +139,8 @@ std::vector GetDomains(const std::wstring& deviceNumber, const std // Command for the first run std::wstring command = L".\\fido2-manage.exe -residentkeys -device " + deviceNumber + L" -pin " + globalPin; - // Debug: Show the command being executed - //MessageBox(NULL, command.c_str(), L"Debug: Command Being Executed", MB_OK); - std::vector output = RunCommandAndGetOutput(command); - // Debug: Check the raw output - for (const auto& line : output) { - // MessageBox(NULL, line.c_str(), L"Debug: First Run Output", MB_OK); - } - // Extract domains (Users) from the output std::vector domains; for (const auto& line : output) { @@ -172,11 +164,6 @@ std::vector GetResidentKeysWithDomains(const std::wstring& deviceNu L" -domain " + domain + L" -pin " + globalPin; std::vector output = RunCommandAndGetOutput(command); - // Debug: Check the raw output - for (const auto& line : output) { - //MessageBox(NULL, line.c_str(), L"Debug: Second Run Output", MB_OK); - } - // Parse the results and add them to the list std::vector parsedPasskeys = ParseResidentKeys(output); for (auto& key : parsedPasskeys) { @@ -316,11 +303,6 @@ INT_PTR CALLBACK PasskeysDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPAR } } - // Debug: Display the parsed domains - for (const auto& domain : domains) { - // MessageBox(hDlg, domain.c_str(), L"Debug: Parsed Domain", MB_OK); - } - // Step 2: Second Run - Fetch resident keys for each domain std::vector refreshedPasskeys; for (const auto& domain : domains) { @@ -337,11 +319,6 @@ INT_PTR CALLBACK PasskeysDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPAR refreshedPasskeys.insert(refreshedPasskeys.end(), parsedPasskeys.begin(), parsedPasskeys.end()); } - // Debug: Display parsed passkeys - for (const auto& pk : refreshedPasskeys) { - // MessageBox(hDlg, (L"Credential ID: " + pk.credentialId + L"\nUser: " + pk.user).c_str(), L"Debug: Parsed Passkey", MB_OK); - } - // Step 3: Populate the ListView with the complete data PopulatePasskeysList(hListView, refreshedPasskeys); @@ -355,8 +332,7 @@ INT_PTR CALLBACK PasskeysDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPAR return TRUE; } - case IDC_BTN_SHOW_SELECTED: { - // Existing logic to handle the selected row + case IDC_BTN_DELETE_PASSKEY: { int selectedRow = ListView_GetNextItem(hListView, -1, LVNI_SELECTED); if (selectedRow == -1) { MessageBox(hDlg, L"No row selected.", L"Error", MB_OK | MB_ICONERROR); @@ -366,13 +342,21 @@ INT_PTR CALLBACK PasskeysDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPAR wchar_t buffer[256] = { 0 }; LVITEM lvItem = { 0 }; lvItem.iItem = selectedRow; - lvItem.iSubItem = 0; // First column + lvItem.iSubItem = 0; lvItem.pszText = buffer; lvItem.cchTextMax = 256; if (SendMessage(hListView, LVM_GETITEMTEXT, selectedRow, (LPARAM)&lvItem) > 0) { - std::wstring command = L".\\fido2-manage.exe -delete -device " + deviceNumber + L" -credential " + buffer; - ShellExecute(NULL, L"open", L"cmd.exe", (L"/k " + command).c_str(), NULL, SW_SHOW); + std::wstring confirmMsg = + L"Are you sure you want to delete this passkey?\n\n" + L"Credential ID: " + std::wstring(buffer) + + L"\n\nThis action cannot be undone."; + int confirm = MessageBox(hDlg, confirmMsg.c_str(), L"Confirm Delete", + MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2); + if (confirm == IDYES) { + std::wstring command = L".\\fido2-manage.exe -delete -device " + deviceNumber + L" -credential " + buffer; + ShellExecute(NULL, L"open", L"cmd.exe", (L"/k " + command).c_str(), NULL, SW_SHOW); + } } else { MessageBox(hDlg, L"Failed to retrieve row content.", L"Error", MB_OK | MB_ICONERROR); @@ -474,9 +458,6 @@ INT_PTR CALLBACK FingerprintDialogProc(HWND hDlg, UINT message, WPARAM wParam, L // Extract Fingerprint ID and Description (combined into second column) std::wstring fingerprintID_And_Description = line.substr(colonPos + 2); // From after ':' - // Debug: Display the parsed data - // MessageBox(hDlg, (L"Index: " + index + L"\nData: " + fingerprintID_And_Description).c_str(), L"Debug: Parsed Data", MB_OK); - // Add to the ListView LVITEM lvItem = { 0 }; lvItem.mask = LVIF_TEXT; @@ -495,10 +476,6 @@ INT_PTR CALLBACK FingerprintDialogProc(HWND hDlg, UINT message, WPARAM wParam, L lvItem.pszText = dataBuffer; SendMessage(hListView, LVM_SETITEM, 0, (LPARAM)&lvItem); } - else { - // Debug: Show lines that failed to parse - // MessageBox(hDlg, line.c_str(), L"Debug: Unparsed Line", MB_OK); - } } return TRUE; @@ -559,16 +536,8 @@ INT_PTR CALLBACK FingerprintDialogProc(HWND hDlg, UINT message, WPARAM wParam, L -// Function declarations LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); - -std::vector RunCommandAndGetOutput(const std::wstring& command); -void PopulateComboBox(); -void PopulateListView(const std::wstring& deviceNumber); -void ResizeControls(HWND hwnd); -void RefreshData(); - // Entry point int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { hInst = hInstance; @@ -616,8 +585,6 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCm return (int)msg.wParam; } -#include - // Function to execute a command with a timeout std::vector RunCommandAndGetOutputWithTimeout(const std::wstring& command, DWORD timeoutMs) { std::vector lines; @@ -777,78 +744,41 @@ void PopulateListView(HWND hwnd, const std::wstring& deviceNumber) { name = L"remaining passkeys"; } if (name == L"existing passkeys") { - // MessageBox(hwnd, (L"Name: " + name + L", Value: " + value).c_str(), L"Debug: Existing Passkeys", MB_OK); - try { int count = std::stoi(value); - - // MessageBox(hwnd, (L"Count: " + std::to_wstring(count)).c_str(), L"Debug: Conversion Success", MB_OK); - if (count > 0) { - // MessageBox(hwnd, L"Enabling Passkeys Button", L"Debug: Button Enabled", MB_OK); - HWND hButton = GetDlgItem(hwnd, ID_BTN_PASSKEYS); if (hButton) { - EnableWindow(hButton, TRUE); // Enable the button - - // Force a redraw to ensure the UI updates + EnableWindow(hButton, TRUE); RedrawWindow(hButton, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); } - else { - // MessageBox(hwnd, L"Button handle is null!", L"Debug: Button Error", MB_OK); - } } } catch (...) { - // MessageBox(hwnd, L"Exception during conversion!", L"Debug: Conversion Failed", MB_OK); } } if (name == L"version strings") { - // Debug: Show the version strings value - // MessageBox(hwnd, (L"Version Strings: " + value).c_str(), L"Debug: Version Strings", MB_OK); - - // Search for "FIDO_2_1" size_t posFIDO_2_1 = value.find(L"FIDO_2_1"); - // Check if "FIDO_2_1" exists and is not followed by "_" + // FIDO_2_1 without a trailing underscore indicates FIDO 2.1 (not a pre-release variant) if (posFIDO_2_1 != std::wstring::npos && (posFIDO_2_1 + 8 >= value.length() || value[posFIDO_2_1 + 8] != L'_')) { - // MessageBox(hwnd, L"Enabling Enforce UV Button", L"Debug: Button Enabled", MB_OK); - HWND hButton = GetDlgItem(hwnd, ID_BTN_ENFORCEUV); if (hButton) { - EnableWindow(hButton, TRUE); // Enable the button + EnableWindow(hButton, TRUE); RedrawWindow(hButton, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); } - else { - // MessageBox(hwnd, L"Enforce UV Button handle is null!", L"Debug: Button Error", MB_OK); - } - } - else { - // MessageBox(hwnd, L"Conditions not met: Button will not be enabled", L"Debug: Button Not Enabled", MB_OK); } } if (name == L"options") { - // Debug: Show the options value - // MessageBox(hwnd, (L"Options: " + value).c_str(), L"Debug: Options", MB_OK); - - // Check if "bioEnroll" exists in the options if (value.find(L"bioEnroll") != std::wstring::npos) { - // MessageBox(hwnd, L"Enabling Fingerprints Button", L"Debug: Button Enabled", MB_OK); - HWND hButton = GetDlgItem(hwnd, ID_BTN_FINGERPRINT); if (hButton) { - EnableWindow(hButton, TRUE); // Enable the Fingerprints button + EnableWindow(hButton, TRUE); RedrawWindow(hButton, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); } - else { - // MessageBox(hwnd, L"Fingerprints Button handle is null!", L"Debug: Button Error", MB_OK); - } - } - else { - // MessageBox(hwnd, L"bioEnroll not found in options", L"Debug: Button Not Enabled", MB_OK); } } @@ -1044,19 +974,9 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) // Step 1: Get domains from the first run std::vector domains = GetDomains(deviceNumber, globalPin); - // Debug: Check the extracted domains - for (const auto& domain : domains) { - //MessageBox(hwnd, domain.c_str(), L"Debug: Extracted Domain", MB_OK); - } - // Step 2: Get resident keys with domains std::vector passkeys = GetResidentKeysWithDomains(deviceNumber, globalPin, domains); - // Debug: Check the parsed results from the second run - for (const auto& pk : passkeys) { - // MessageBox(hwnd, (L"Credential ID: " + pk.credentialId + L"\nUser: " + pk.user).c_str(), L"Debug: Parsed Passkey", MB_OK); - } - // Restore the default cursor HCURSOR hArrowCursor = LoadCursor(NULL, IDC_ARROW); SetCursor(hArrowCursor); diff --git a/Resource.h b/Resource.h index a707180..5442278 100644 --- a/Resource.h +++ b/Resource.h @@ -22,7 +22,7 @@ #define IDC_BTN_REFRESH 4002 -#define IDC_BTN_SHOW_SELECTED 4001 +#define IDC_BTN_DELETE_PASSKEY 4001 #define ID_BTN_PASSKEYS 2001 #define ID_BTN_FINGERPRINT 2002