mirror of
https://github.com/Mudlet/Mudlet
synced 2026-08-13 18:26:27 -04:00
3 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
bf25bf8cbe
|
fix: keep saved profile passwords working on Windows after qtkeychain library update (#9395)
#### Brief overview of PR changes/additions - Adds a Windows-only migration that recovers stored passwords after qtkeychain 0.17.0 changes the Windows Credential Manager naming scheme (bare key -> "key@service"), re-storing them under the new name on first read - Fixes the existing old-format migration reads/cleanup, which relied on the same pre-0.17 service-ignoring behaviour and would silently miss under 0.17+ - Surfaces the linked qtkeychain version as a QTKEYCHAIN_LINKED_VERSION compile definition (the library's own header macro is stale); it gates the old-entry cleanup and is logged for diagnostics - Adds CredentialManagerKeychainTest: Windows-only ctests that plant the historical credential layouts in the real credential store (via empty-service QKeychain jobs, which resolve to the bare TargetName on every qtkeychain version) and verify round trip, bare-entry migration, no resurrection of deleted passwords, old-format migration, and colliding-format recovery #### Motivation for adding to Mudlet Once Windows builds pick up qtkeychain 0.17+ (e.g. via MSYS2), every stored profile password would silently become unreadable and users would have to re-enter them; this makes the transition seamless. #### Other info (issues closed, discussion etc) qtkeychain 0.17.0 breaking change: https://github.com/frankosterfeld/qtkeychain/releases/tag/0.17.0. A read with an empty service resolves to the bare key on every qtkeychain version, so the migration layer works regardless of which version is linked. On pre-0.17 builds it is normally dormant (the primary read already looks up the bare key), though a transient read failure can route into it as a harmless retry; deletion of the old entry only happens when the linked qtkeychain is known to be 0.17+, so the recovered credential can never be deleted on older versions. The new keychain tests branch their expectations on QTKEYCHAIN_LINKED_VERSION: on today's MSYS2 they verify the migration stays dormant, and they flip to verifying the actual migration automatically once MSYS2 ships 0.17+. They run on Windows PR CI via ctest and skip on other platforms or when the credential store is unavailable. **Test case:** CredentialManagerKeychainTest covers the scenarios automatically on Windows CI. Manually: store a profile password, restart, confirm auto-login still works (pre-0.17: migration is a no-op). With a qtkeychain 0.17+ build: store a password using a pre-0.17 build, then run this build - the password should still load, and the Credential Manager entry moves to the "key@service" name. --------- Signed-off-by: Michael Conley <sousesider@gmail.com> |
||
|
|
fa61c537a7
|
Fix: Restore password loading from portable file in connection dialog (#8993)
#### Brief overview of PR changes/additions
Restores the ability for the connection dialog to load saved passwords
from the portable password file on disk, which stopped working after PR
#7956 introduced secure credential management.
#### Motivation for adding to Mudlet
After #7956, users who had passwords saved in the old portable file
format (`~/.config/mudlet/profiles/<name>/password`) could no longer see
their passwords pre-filled when selecting a profile in the connection
dialog. This affected users who had not yet migrated to the system
keychain.
The fix ensures all three password sources are checked in order: system
keychain, QSettings, and finally the portable file on disk. It also
moves the password migration step to run before the connection dialog
opens, so passwords are migrated in time to be found.
Includes the profile password collision fix from #8948 and adds new unit
tests for the password migration and fallback paths.
#### Other info (issues closed, discussion etc)
Reported by @SlySven — PR #7956 (commit
|
||
|
|
79ab7be4e2
|
Improve: Secure credential management with system keychain integration and legacy migration (#7956)
#### Brief overview of PR changes/additions
This pull request implements secure credential management for Mudlet
with system keychain integration and encrypted fallback storage:
**Core Components:**
- **CredentialManager**: High-level API for secure credential storage
with QtKeychain integration
- **SecureStringUtils**: Qt-based cryptographic utilities for encrypted
file storage
- **Legacy Migration**: Automatic detection and migration of existing
plaintext passwords
**Key Features:**
- **System Keychain Integration**: Primary storage in macOS Keychain,
Windows Credential Store, and Linux Secret Service via QtKeychain
- **Encrypted File Fallback**: Qt crypto-based AES encryption for
portable mode and keychain unavailability
- **Seamless Migration**: Automatic detection and upgrade of legacy
password storage formats
- **Profile Isolation**: Per-profile encryption keys prevent
cross-profile credential access
- **Portable Mode Support**: Automatic detection and secure file-based
storage for portable installations
#### Motivation for adding to Mudlet
**Security Enhancement:**
- Eliminates plaintext password storage in profile XML files
- Provides industry-standard system keychain integration for credential
security
- Implements authenticated encryption for fallback scenarios
**User Experience:**
- Zero configuration required - works automatically across all platforms
- Seamless migration from existing plaintext passwords to secure storage
- Native system integration provides familiar credential management
experience
**Future-Proofing:**
- Extensible architecture supports additional credential types (API
keys, tokens, etc.)
- Robust fallback ensures functionality in all deployment scenarios
- Prepares foundation for OAuth and external service integrations
#### Other info (issues closed, discussion etc)
**Security Architecture:**
- **Keychain-First Strategy**: Prefers system keychain with automatic
encrypted file fallback
- **Legacy Format Detection**: Automatically migrates passwords from
development branch keychain format
- **Memory Security**: Secure string clearing and controlled credential
lifecycle management
- **Input Validation**: Path traversal protection and service name
sanitization
**Implementation Highlights:**
- **Async Operations**: Non-blocking keychain operations with timeout
protection
- **Thread Safety**: Event-driven architecture prevents UI blocking and
race conditions
- **Comprehensive Testing**: Full test coverage for encryption,
migration, and fallback scenarios
- **Cross-Platform**: Unified API across Windows, macOS, and Linux with
platform-specific optimizations
**Version Compatibility & Migration:**
- **Mudlet 4.19.x Compatibility**: Preserves existing plaintext password
storage to ensure compatibility when switching between 4.19.x stable and
development builds
- **Mudlet 4.20.x Migration**: Post-4.20.0 release, automatic migration
begins converting plaintext passwords to secure storage
- **Bidirectional Safety**: Users can safely run both 4.19.x and
development versions without losing access to their passwords during the
transition period
- **Legacy Format Support**: Automatically detects and migrates
passwords from the original development branch keychain format
(`service="Mudlet profile"`) to the new secure format
# Credential Management Workflows
## 1. Credential Storage Strategy
```mermaid
flowchart TD
A[Store Password Request] --> B{Portable Mode?}
B -->|Yes| C[Encrypt & Store in Profile File]
B -->|No| D[Store in System Keychain]
D --> E{Keychain Success?}
E -->|Yes| F[Remove Encrypted Fallback File]
E -->|No| G[Fallback to Encrypted File]
F --> H[Success]
G --> I{Encryption Success?}
I -->|Yes| H
I -->|No| J[Failure]
C --> I
classDef primary fill:#4CAF50,stroke:#2E7D32,stroke-width:2px,color:#000
classDef fallback fill:#FF9800,stroke:#E65100,stroke-width:2px,color:#000
classDef decision fill:#2196F3,stroke:#0D47A1,stroke-width:2px,color:#fff
classDef result fill:#9C27B0,stroke:#4A148C,stroke-width:2px,color:#fff
class D,F primary
class C,G fallback
class B,E,I decision
class H,J result
```
## 2. Legacy Migration Workflow
```mermaid
flowchart TD
A[Retrieve Password Request] --> B[Try New Keychain Format]
B --> C{Password Found?}
C -->|Yes| D[Return Password]
C -->|No| E[Check Legacy Keychain Format]
E --> F{Legacy Found?}
F -->|Yes| G[Migrate to New Format]
G --> H[Store in New Format]
H --> I[Remove Legacy Entry]
I --> J[Return Migrated Password]
F -->|No| K[Try Encrypted File]
K --> L{File Found?}
L -->|Yes| M[Decrypt & Return]
L -->|No| N[Return Empty - No Password Stored]
classDef newformat fill:#4CAF50,stroke:#2E7D32,stroke-width:2px,color:#000
classDef legacy fill:#FF9800,stroke:#E65100,stroke-width:2px,color:#000
classDef migration fill:#9C27B0,stroke:#4A148C,stroke-width:2px,color:#fff
classDef fallback fill:#607D8B,stroke:#263238,stroke-width:2px,color:#fff
classDef result fill:#2196F3,stroke:#0D47A1,stroke-width:2px,color:#fff
class B,H newformat
class E,I legacy
class G migration
class K fallback
class D,J,M,N result
```
## 3. Cross-Platform Keychain Integration
```mermaid
flowchart TD
A[QtKeychain Request] --> B{Platform Detection}
B -->|macOS| C[Access Keychain Services]
B -->|Windows| D[Access Credential Store]
B -->|Linux| E[Access Secret Service]
C --> F[Store/Retrieve Credential]
D --> F
E --> F
F --> G{Operation Success?}
G -->|Yes| H[Return Result]
G -->|No| I[Log Error & Fallback]
I --> J[Use Encrypted File Storage]
J --> K[AES Encryption with Profile Key]
K --> L[Store in Profile Directory]
classDef platform fill:#2196F3,stroke:#0D47A1,stroke-width:2px,color:#fff
classDef keychain fill:#4CAF50,stroke:#2E7D32,stroke-width:2px,color:#000
classDef fallback fill:#FF9800,stroke:#E65100,stroke-width:2px,color:#000
classDef crypto fill:#9C27B0,stroke:#4A148C,stroke-width:2px,color:#fff
class C,D,E platform
class F,H keychain
class I,J fallback
class K,L crypto
```
This implementation provides a comprehensive, secure, and user-friendly
credential management system that seamlessly upgrades existing Mudlet
installations while providing robust security for future credential
storage needs.
---------
Co-authored-by: Vadim Peretokin <vperetokin@hey.com>
|