Commit Graph

20 Commits

Author SHA1 Message Date
Token2 101e04f036 Merge branch 'main' into bugfix/issue-15-hardcoded-default-pin 2026-06-09 16:23:36 +02:00
Token2 1ce7fa49ee Merge branch 'main' into bugfix/issue-12-13-delete-confirm-dead-code 2026-06-09 16:22:37 +02:00
Token2 03e21c7d8e Merge branch 'main' into bugfix/issue-2-escape-wrong-layer-createprocess 2026-06-09 16:21:44 +02:00
Token2 899c2719d1 Merge pull request #21 from allamiro/bugfix/issue-9-fixed-buffer-truncation-listview
Fix #9 - remove fixed 256-char buffers in ListView population
2026-06-09 16:18:32 +02:00
Token2 ee82bbb8d7 Merge pull request #20 from allamiro/bugfix/issue-8-populatelistview-forward-decl-mismatch
Fix #8 - correct PopulateListView forward declaration signature
2026-06-09 16:06:50 +02:00
Token2 2c8227d1cf Merge pull request #19 from allamiro/bugfix/issue-7-static-buffer-stale-pin-on-cancel
Fix #7 - static buffer in ShowInputBox returns stale PIN on cancel
2026-06-09 16:03:15 +02:00
Token2 025c5df011 Merge pull request #18 from allamiro/bugfix/issue-6-pipe-handle-leak-createprocess-fail
Fix hPipeWrite handle leak when CreateProcess fails
2026-06-09 16:02:22 +02:00
Token2 0beb0ffce4 Merge pull request #17 from allamiro/bugfix/issue-5-runcmd-timeout-never-called
Wire all command calls through the timeout variant
2026-06-09 16:02:02 +02:00
Tamir Suliman 2889bcbcd8 Fix #15 - move "0000" default from global to dialog pre-fill
globalPin is now initialised to L"" so any bypass path that skips the
dialog produces an empty string that validation will reject.  The
"0000" default is instead passed to ShowInputBox as defaultValue and
pre-filled into the edit control via SetDlgItemText on WM_INITDIALOG,
preserving the UX the author intended.  ShowInputBox now also returns
L"" when the user cancels instead of leaking the previous static buffer
contents.

Fixes #15
2026-06-06 14:18:43 +02:00
Tamir Suliman 509fca3c9b 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 <thread> 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
2026-06-06 14:00:04 +02:00
Tamir Suliman 1dbed02c20 Fix #2 - replace CMD shell escaping with correct CreateProcess quoting
EscapeCommandLineArgument prefixed shell metacharacters with ^ which
is cmd.exe syntax. RunCommandAndGetOutput calls CreateProcess directly,
so ^ characters were passed verbatim to fido2-manage.exe, corrupting
the PIN for any input containing those characters.

Replaced the function with QuoteArg which follows the Windows C-runtime
argument parsing rules: wrap in double quotes, double backslashes that
precede a double quote or the closing quote, and escape embedded double
quotes with a backslash.

Also fixed two related problems:
- The PIN length check was running against the already-escaped value.
  A 2-char PIN escaped to a 4-char quoted string would silently pass.
  Moved the check before QuoteArg so it validates the raw input.
- deviceNumber and domain were never escaped in any command string.
  Applied QuoteArg inline at all seven CreateProcess command-building
  sites. ShellExecute paths are left unchanged as they go through
  cmd.exe and deviceNumber is always regex-validated digits.

Fixes #2
2026-06-06 13:52:46 +02:00
Tamir Suliman 102718c747 Fix #9 - remove fixed 256-char buffers in ListView population
wcscpy_s into a 256-char stack buffer crashes via the invalid
parameter handler if a credential ID, fingerprint data, or device
info value exceeds 255 characters. FIDO2 credential IDs are binary
blobs encoded as hex or base64 and can easily exceed this limit.

Dropped the intermediate nameBuffer/valueBuffer in PopulateListView
and indexBuffer/dataBuffer in FingerprintDialogProc. Assigned
const_cast<LPWSTR>(str.c_str()) directly to lvItem.pszText instead,
which is safe because SendMessage(LVM_INSERTITEM/LVM_SETITEM) is
synchronous and copies the text before returning. This is the same
pattern already used correctly in PopulatePasskeysList.

Fixes #9
2026-06-06 13:46:33 +02:00
Tamir Suliman 49c0eb481a Fix #8 - correct PopulateListView forward declaration signature
The forward declaration at line 568 had one parameter
(const std::wstring&) while the definition at line 694 takes two
(HWND, const std::wstring&). The mismatch is a latent ODR violation:
the compiler currently resolves correctly because the declaration
appears after the definition, but any reorganisation that moves the
declaration above the definition would cause a compile error or a
silent wrong-function call. Updated the declaration to match the
definition and the single call site exactly.

Fixes #8
2026-06-06 13:43:49 +02:00
Tamir Suliman 7bdaab7705 Fix #7 - static buffer in ShowInputBox returns stale PIN on cancel
The static buffer in ShowInputBox was only initialised once at program
start, never between calls. Pressing Cancel left the previous PIN in
the buffer, which was returned and silently used as globalPin on the
next device selection. Two changes made:

1. ShowInputBox: zero buffer[0] at the top of every call so a cancelled
   dialog can never return stale data; capture DialogBoxParam return
   value and return an empty string on anything other than IDOK.

2. PopulateListView caller: check globalPin.empty() before escaping
   and exit silently — previously a cancel fell through to the length
   check and showed a misleading 'PIN too short' error instead of just
   resetting the UI.

Fixes #7
2026-06-06 13:41:34 +02:00
Tamir Suliman 20d080f24d Fix #6 - hPipeWrite handle leak when CreateProcess fails
In both RunCommandAndGetOutput and RunCommandAndGetOutputWithTimeout,
hPipeWrite was only closed inside the CreateProcess success branch.
On failure the write handle leaked, consuming a kernel handle slot on
every failed invocation. Captured the CreateProcess return value into
a bool and moved CloseHandle(hPipeWrite) to run unconditionally after
the call, before the success check, which is the standard Windows
pipe pattern.

Fixes #6
2026-06-06 13:35:43 +02:00
Tamir Suliman f1b6733f2b Fix #5 - wire all command calls through the timeout variant
RunCommandAndGetOutputWithTimeout was implemented but never called;
all 7 call sites used the no-timeout RunCommandAndGetOutput, leaving
the UI able to freeze permanently if fido2-manage.exe hangs or a
device is removed mid-operation. Added DEVICE_TIMEOUT_MS constant
(15 s) and routed every call site through the timeout function so
a stalled subprocess is killed and the UI recovers cleanly.

Fixes #5
2026-06-06 13:35:28 +02:00
Tamir Suliman 208a70c4b3 Fix #4 - null hwnd dereference in RefreshData
The global hwnd was shadowed by a local variable declaration in
_tWinMain, leaving the global permanently NULL. RefreshData() passed
this NULL handle to DisableAllButtons(), dereferencing it on every
Refresh click. Removing the local type specifier assigns the created
window to the global so all callers outside _tWinMain see a valid handle.

Fixes #4
2026-06-06 13:35:19 +02:00
Token2 1b6ab4892c Update FIDO2.1 Manager.cpp
allow chars like @&*! (add escape function for PIN)
2025-03-03 17:48:56 +01:00
Token2 f37dc16400 Update FIDO2.1 Manager.cpp
Adding domain field in the passkeys table
2025-02-24 18:27:31 +01:00
Token2 39bb6e43b4 Add files via upload 2024-11-30 20:08:18 +01:00