@@ -448,10 +448,45 @@ fn get_macos_key_provider(browser: BrowserId) -> Result<KeyProvider> {
448448 } )
449449}
450450
451+ /// KWallet keyring name for a browser, matching Chromium's convention.
452+ /// Ref: https://chromium.googlesource.com/chromium/src/+/refs/heads/main/components/os_crypt/sync/key_storage_kwallet.cc
453+ fn kwallet_keyring_name ( browser : BrowserId ) -> & ' static str {
454+ match browser {
455+ BrowserId :: Chrome => "Chrome" ,
456+ BrowserId :: Brave => "Brave" ,
457+ BrowserId :: Edge | BrowserId :: Opera => "Chromium" ,
458+ BrowserId :: Vivaldi => "Chrome" ,
459+ BrowserId :: Arc => "Arc" ,
460+ }
461+ }
462+
463+ fn try_kwallet_password ( browser : BrowserId ) -> Option < String > {
464+ let name = kwallet_keyring_name ( browser) ;
465+ let output = std:: process:: Command :: new ( "kwallet-query" )
466+ . args ( [
467+ "--read-password" ,
468+ & format ! ( "{name} Safe Storage" ) ,
469+ "--folder" ,
470+ & format ! ( "{name} Keys" ) ,
471+ "kdewallet" ,
472+ ] )
473+ . output ( )
474+ . ok ( ) ?;
475+ if !output. status . success ( ) {
476+ return None ;
477+ }
478+ let pw = String :: from_utf8_lossy ( & output. stdout ) . trim ( ) . to_string ( ) ;
479+ if pw. is_empty ( ) || pw. to_lowercase ( ) . starts_with ( "failed to read" ) {
480+ return None ;
481+ }
482+ Some ( pw)
483+ }
484+
451485fn get_linux_key_provider ( browser : BrowserId ) -> Result < KeyProvider > {
452486 let desc = browser. descriptor ( ) ;
453487 let app_name = desc. keychain_service_for_current_os ( ) ;
454488
489+ // Try GNOME/freedesktop secret service first, then KWallet, then "peanuts" fallback.
455490 let passphrase = if let Some ( app) = app_name {
456491 std:: process:: Command :: new ( "secret-tool" )
457492 . args ( [ "lookup" , "application" , app] )
@@ -460,6 +495,7 @@ fn get_linux_key_provider(browser: BrowserId) -> Result<KeyProvider> {
460495 . filter ( |o| o. status . success ( ) )
461496 . map ( |o| String :: from_utf8_lossy ( & o. stdout ) . trim ( ) . to_string ( ) )
462497 . filter ( |s| !s. is_empty ( ) )
498+ . or_else ( || try_kwallet_password ( browser) )
463499 . unwrap_or_else ( || "peanuts" . to_string ( ) )
464500 } else {
465501 "peanuts" . to_string ( )
0 commit comments