browserpass-extension icon indicating copy to clipboard operation
browserpass-extension copied to clipboard

Thunderbird Support for Browserpass

Open thardeck opened this issue 1 month ago • 4 comments

Summary

This PR adds Thunderbird email client support to the Browserpass extension. It allows users to store and retrieve email credentials (IMAP, SMTP, POP3) and OAuth tokens (Gmail, Microsoft, Fastmail) from their pass password store instead of Thunderbird's built-in password manager.

I am already running the implementation locally since a few days. I have tried different setups, fixed several issues on the way and also ran into Thunderbird issues. For debugging purposes I have added quite some logging, which should not hurt and probably at least be kept until more users tried the extension.

I am interested in this feature myself and got some time to work on this. It turned out to be much more code then originally anticipated but there were a lot of edge cases to cover and will probably be some more. Any feedback is appreciated.

Features

  • Mail Protocol Support: Automatic password retrieval for IMAP, SMTP, and POP3 accounts
  • OAuth2 Token Storage: Refresh token storage for Gmail, Microsoft, and Fastmail
  • CalDAV/CardDAV: OAuth authentication for calendar and contacts
  • Automatic Migration: Credentials are migrated from Thunderbird's password manager to pass
  • Credential Saving: New credentials entered in Thunderbird are automatically saved to pass
  • OAuth Window Autofill: Clipboard-based autofill for OAuth browser windows with keyboard shortcuts

Technical Implementation

Why Separate Builds?

Thunderbird requires WebExtension Experiments to hook into its authentication system, which Firefox doesn't allow for non-privileged add-ons. The experiment API provides access to:

  • MsgAuthPrompt - Intercepts IMAP/SMTP/POP3 password prompts
  • OAuth2Module - Intercepts OAuth token requests for CalDAV/CardDAV
  • browserRequest - Monitors OAuth browser windows for autofill

Therefore, the extension is built separately:

  • Firefox: make firefox - Standard browser extension
  • Thunderbird: make thunderbird - Includes experimental credentials API

The core extension code remains shared; only the manifest and experiment files differ.

Architecture

Thunderbird Auth Request
        ↓
implementation.js (WebExtension Experiment)
  - Hooks MsgAuthPrompt (IMAP/SMTP/POP3)
  - Hooks OAuth2Module (CalDAV/CardDAV)
  - Hooks browserRequest (OAuth windows)
        ↓
Event Emitters → background.js
        ↓
thunderbird.js
  - Matches credentials from pass
  - Stores new credentials to pass
        ↓
browserpass-native (GPG decryption)

Requirements

  • Thunderbird 128.0+: Uses WebExtension Experiments API
  • browserpass-native: Required for GPG decryption - run make hosts-thunderbird-user to register
  • pass: Standard Unix password manager with GPG

Testing

  1. Build extension: make thunderbird
  2. Package as XPI: cd thunderbird && zip -r browserpass-thunderbird.xpi *
  3. Install in Thunderbird via Add-ons → Install from File
  4. Open Thunderbird Error Console with Ctrl+Shift+J
  5. Test credential retrieval for existing email accounts
  6. Test OAuth authentication for Google/Microsoft accounts
  7. Test migration of existing Thunderbird credentials

Password Store Organization

~/.password-store/
├── imap/
│   └── mail.example.com.gpg            # IMAP server credentials
├── smtp/
│   └── mail.example.com.gpg            # SMTP server credentials
├── pop3/
│   └── pop.example.com.gpg             # POP3 server credentials
├── https/
│   └── sso.example.com.gpg             # OAuth identity provider credentials
└── oauth/
    ├── mail/
    │   └── [email protected]        # OAuth mail tokens
    ├── caldav/
    │   └── [email protected]        # Calendar OAuth tokens
    └── carddav/
        └── [email protected]        # Contacts OAuth tokens

The https/ directory is for OAuth identity provider login pages (e.g., Google, Okta) that appear in the OAuth browser window during account setup.

Design Decisions

1. Offline Startup Control

Thunderbird is forced to start offline to prevent auth requests before the extension is ready (This seems to be a Thunderbird issue). Once hooks are registered, Thunderbird goes online automatically. User's "Always offline" preference is respected.

2. OAuth Token Caching

Tokens retrieved from pass are cached for 8 hours to reduce GPG decryption overhead. Cache is cleared on token update or after the timeout expires.

3. Credential Migration

Credentials are migrated from Thunderbird's password manager to pass. Existing pass entries are not overwritten.

4. Service-Specific OAuth Storage

OAuth tokens are stored in service-specific directories (oauth/mail/, oauth/caldav/, oauth/carddav/) because different services may request tokens with different scopes. A calendar app might request a token with calendar-only permissions, while mail needs separate permissions. Sharing a single token would break services that require permissions the new token doesn't have.

Known Limitations

  • CalDAV Startup OAuth Windows: CalDAV calendars without offline cache may trigger OAuth windows at startup before the extension hooks are ready (This seems to be a Thunderbird issue). The extension automatically closes these windows and retries once initialization is complete
  • OAuth Autofill Method: OAuth browser window autofill uses clipboard-based injection with keyboard shortcuts rather than direct DOM manipulation, due to security restrictions in browser windows.

Breaking Changes

None - this is additive functionality that is mainly added to the Thunderbird extension.

Related PRs

A companion PR to browserpass-native is required to register the native host for Thunderbird:

  • Adds hosts-thunderbird-user and hosts-thunderbird Makefile targets
  • Registers firefox-host.json native messaging manifest

References

  • pass - Standard Unix password manager
  • WebExtension Experiments - Thunderbird API documentation
  • keepassxc-mail - Inspired the general architecture approach (offline startup control, WebExtension Experiments, credential event handling)

thardeck avatar Dec 05 '25 17:12 thardeck