No description
  • Scheme 69.3%
  • Shell 23.5%
  • Makefile 7%
  • Common Lisp 0.2%
Find a file
ober 4814f6af03
Some checks failed
required-ci / required (push) Failing after 3m43s
Merge pull request #5
2026-09-19 16:41:13 -04:00
.forgejo Use FreeBSD Forgejo CI runner 2026-08-03 14:48:15 -06:00
.jerboa Resolve security audit findings 2026-07-11 17:22:32 -06:00
.jpkg/build chore: move dependency locks to git.jerboa.sh 2026-08-11 10:48:43 -06:00
bin chore: move dependency locks to git.jerboa.sh 2026-08-11 10:48:43 -06:00
docs Resolve security audit findings 2026-07-11 17:22:32 -06:00
protonmail fix: honor imap uidvalidity during sync 2026-09-05 13:06:05 -06:00
scripts chore: move dependency locks to git.jerboa.sh 2026-08-11 10:48:43 -06:00
support chore: move dependency locks to git.jerboa.sh 2026-08-11 10:48:43 -06:00
test fix: honor imap uidvalidity during sync 2026-09-05 13:06:05 -06:00
.gitignore Security hardening and release readiness 2026-06-23 10:50:53 -06:00
.gitsafeignore Set up Forgejo CI/CD policy 2026-08-03 12:50:51 -06:00
AGENTS.md docs(agents): add checkout hygiene policy (work dirs under ~/work, cleanup when done) 2026-09-12 19:11:20 -06:00
dependencies.lock fix: honor imap uidvalidity during sync 2026-09-05 13:06:05 -06:00
jpkg.sexp Use FreeBSD Forgejo CI runner 2026-08-03 14:48:15 -06:00
LICENSE Switch to MIT license 2026-07-21 13:42:19 -06:00
main.ss Security hardening and release readiness 2026-06-23 10:50:53 -06:00
Makefile fix: honor imap uidvalidity during sync 2026-09-05 13:06:05 -06:00
plan.md Resolve security audit findings 2026-07-11 17:22:32 -06:00
README.md feat: sync Bridge mail to sqlite 2026-08-11 11:44:21 -06:00
SECURITY.md Resolve security audit findings 2026-07-11 17:22:32 -06:00
VERSION fix: honor imap uidvalidity during sync 2026-09-05 13:06:05 -06:00

jerboa-protonmail

Read-only Proton Mail access experiments in Jerboa.

The stable first target is a local IMAP client for Proton Mail Bridge. Bridge handles Proton authentication, key management, and local decryption; this tool will initially list folders, list messages, fetch raw messages, decode common email formats, and export .eml files without mutating mailbox state.

The native direct-Proton track is documented in plan.md, but it is not the first implementation path.

Current Status

Phase 7 is in progress:

  • CLI entry point.
  • Environment config helper.
  • Bridge IMAP connectivity probe.
  • Structured IMAP response parser.
  • Folder listing.
  • Header-only message listing.
  • Raw message fetch.
  • .eml export.
  • Full Bridge folder sync into a local SQLite database.
  • Decoded show output through jerboa-mail.
  • Search by from, subject, and since.
  • Config validation and opt-in integration checks.
  • Smoke tests.
  • Makefile.
  • Project plan.

Live Proton Bridge checks are attempted only when Bridge credentials are set.

Development

make run ARGS='--help'
make doctor
make binary
make test
make release-evidence
make integration-test
bin/protonmail-read doctor

By default the Makefile uses a checked-in ./jerbuild, a local .jerboa/bin/jerbuild, or a jerbuild on PATH. If no toolchain exists, make test fetches the pinned Jerboa release into .jerboa/bin. Override with:

make JERBUILD=/path/to/jerbuild test

Pinned dependencies are fetched from git.jerboa.sh into .deps and verified against dependencies.lock. Override dependency paths with:

make JERBOA_SSL_DIR=/path/to/jerboa-ssl \
     JERBOA_MAIL_DIR=/path/to/jerboa-mail \
     JERBOA_SQLITE_DIR=/path/to/jerboa-sqlite \
     test

Bridge Configuration

Later phases will read Bridge IMAP settings from environment variables:

export PROTON_BRIDGE_HOST=127.0.0.1
export PROTON_BRIDGE_PORT=1143
export PROTON_BRIDGE_USER='bridge-generated-user'
export PROTON_BRIDGE_PASSWORD='bridge-generated-password'
export PROTON_BRIDGE_TLS=loopback-plain

Use Bridge-generated IMAP credentials, not your Proton account password. The default transport is tls and certificate or handshake failures are fatal. Because the common Bridge listener on port 1143 is plaintext, it requires the explicit mode loopback-plain; that mode accepts only literal 127.0.0.1 or ::1. There is no opportunistic plaintext fallback and DNS names are rejected for plaintext.

Commands

bin/protonmail-read doctor
bin/protonmail-read folders
bin/protonmail-read list --folder INBOX --limit 20
bin/protonmail-read show --folder INBOX --uid 123
bin/protonmail-read raw --folder INBOX --uid 123 > message.eml
bin/protonmail-read export-eml --folder INBOX --uid 123 --output message.eml
bin/protonmail-read sync-db --db protonmail.sqlite
bin/protonmail-read sync-db --db protonmail.sqlite --folder INBOX
bin/protonmail-read search --folder INBOX --from person@example.com
bin/protonmail-read search --folder INBOX --subject invoice
bin/protonmail-read search --folder INBOX --since 2026-01-01

Safety

The implemented IMAP fetches use BODY.PEEK[...] so reads should not mark messages as read. The tool does not issue STORE, EXPUNGE, COPY, MOVE, APPEND, CREATE, or DELETE.

Exported .eml files contain plaintext mail after Bridge has decrypted it locally. export-eml refuses existing destinations, symlinks, and untrusted group/world-writable parent directories; it creates a verified 0600 file and publishes complete content atomically. Treat exports as sensitive.

sync-db also stores plaintext mail after Bridge has decrypted it locally. The SQLite database contains raw RFC 5322 message bytes in the messages.raw BLOB column plus indexed folder, UID, header, size, and SHA-256 metadata. The command is resumable: messages already present for the same (folder, uid) are skipped, and new messages are fetched with BODY.PEEK[].

Normal folder, summary, header, body, greeting, and error output filters ANSI, OSC, C0/C1, DEL, and bidirectional terminal controls. raw is intentionally unfiltered for exact RFC 5322 output and refuses a terminal unless the user passes --unsafe-terminal; piping it is preferred.

IMAP input is bounded before allocation: 16 KiB per line, 32 MiB per message literal, 64 MiB per command response, 4096 response entries, 64 literals, and a 60-second total response deadline in addition to socket idle timeouts.

Credential and plaintext-mail handling are documented in docs/credential-handling.md. Dependency provenance is documented in docs/dependency-provenance.md, and local release evidence is documented in docs/release-evidence.md. Production release requires make release-evidence plus live Bridge credential and plaintext export review.