CLI and lib to discover PIM-related services, written in Rust.
This repository ships three things:
- Low-level I/O-free coroutines (no_std state machines that emit read/write requests)
- Mid-level clients, based on coroutines (standard, blocking)
- High-level CLI, based on std clients
- Mozilla Thunderbird Autoconfiguration support wiki (requires
autoconfigfeature):- ISP main and
/.well-known/URL lookups - Thunderbird ISPDB lookup
- DNS MX-based retry against the MX target's parent domain
- DNS TXT
mailconf=<URL>redirect
- ISP main and
- RFC 6186 SRV discovery support (requires
rfc6186feature):_imap._tcp,_imaps._tcp,_submission._tcpassembly into a single report
- PACC discovery support draft-ietf-mailmaint-pacc-02 (requires
paccfeature):- Well-known JSON configuration fetch
- SHA-256 digest verification against the
_ua-auto-configTXT record
- TLS support:
- Rustls with ring crypto (requires
rustls-ringfeature) - Rustls with aws crypto (requires
rustls-awsfeature) - Native TLS (requires
native-tlsfeature)
- Rustls with ring crypto (requires
- JSON output via
--json
Tip
pimconf is written in Rust and uses cargo features to gate functionality. The default feature set is declared in Cargo.toml.
The CLI binary pimconf has not been officially released yet. Check the releases GitHub workflow and look for the Artifacts section. These pre-built binaries are built from the master branch.
Note
Pre-built binaries are built with the default cargo features, plus cli. If you need more features, please use another installation method.
cargo install pimconf --lockedYou can also use the git repository for a more up-to-date (but less stable) version:
cargo install --locked --git https://github.com/pimalaya/pimconf.gitTo use pimconf as a library, add it to your Cargo.toml:
[dependencies]
pimconf = { version = "0.0.1", default-features = false, features = ["autoconfig", "pacc", "rfc6186", "client"] }The client feature pulls in the std-blocking helpers. Drop it (and pick any combination of autoconfig / pacc / rfc6186) for a no_std-friendly, pure-coroutine build.
If you have the Flakes feature enabled:
nix profile install github:pimalaya/pimconfOr run without installing:
nix run github:pimalaya/pimconf -- autoconfig <local-part> <domain>git clone https://github.com/pimalaya/pimconf
cd pimconf
nix runUsing a low-level DNS MX I/O-free coroutine:
use std::{io::{Read, Write}, net::TcpStream};
use pimconf::autoconfig::mx::{DiscoveryDnsMx, DiscoveryDnsMxResult};
use url::Url;
let resolver = Url::parse("tcp://1.1.1.1:53").unwrap();
let mut stream = TcpStream::connect("1.1.1.1:53").unwrap();
let mut coroutine = DiscoveryDnsMx::new("fastmail.com", resolver);
let mut buf = [0u8; 4096];
let mut arg: Option<&[u8]> = None;
let records = loop {
match coroutine.resume(arg.take()) {
DiscoveryDnsMxResult::Ok(records) => break records,
DiscoveryDnsMxResult::WantsWrite { bytes, .. } => {
stream.write_all(&bytes).unwrap();
}
DiscoveryDnsMxResult::WantsRead { .. } => {
let n = stream.read(&mut buf).unwrap();
arg = Some(&buf[..n]);
}
DiscoveryDnsMxResult::Err(err) => panic!("{err}"),
}
};
for record in records {
println!("- {} {}", record.rdata.preference.get(), record.rdata.exchange);
}Using a mid-level std PACC client:
use pimconf::pacc::client::DiscoveryPaccClientStd;
use pimalaya_stream::tls::Tls;
use url::Url;
let dns = Url::parse("tcp://1.1.1.1:53").unwrap();
let mut client = DiscoveryPaccClientStd::new(dns).with_tls(Tls::default());
let config = client.discover("fastmail.com").unwrap();
println!("{config:#?}");Run the full Thunderbird Autoconfiguration chain on <local_part> <domain>:
pimconf autoconfig user fastmail.comThe chain tries, in order: every ISP main URL (secure then plain), every /.well-known/ URL (secure then plain), the Thunderbird ISPDB, then re-tries the same against the MX target's parent domain, then logs the mailconf=<URL> TXT redirect if one is published.
Run a single primitive instead:
pimconf autoconfig user fastmail.com isp --secure
pimconf autoconfig user fastmail.com isp-fallback --secure
pimconf autoconfig user fastmail.com ispdb --secure
pimconf autoconfig user fastmail.com mx
pimconf autoconfig user fastmail.com mailconfRun RFC 6186 SRV discovery (top-level subcommand):
pimconf srv fastmail.comRun PACC discovery:
pimconf pacc fastmail.comJSON output:
pimconf --json autoconfig user fastmail.comPick a specific TLS stack and crypto provider:
pimconf --tls rustls --rustls-crypto ring autoconfig user fastmail.com
pimconf --tls native-tls pacc fastmail.com
pimconf --tls-cert /path/to/extra-root.pem autoconfig user fastmail.comHow to debug the CLI?
Use --log <level> where <level> is one of off, error, warn, info, debug, trace:
pimconf --log trace autoconfig user fastmail.comThe RUST_LOG environment variable, when set, overrides --log and supports per-target filters (see the env_logger documentation). RUST_BACKTRACE=1 enables full error backtraces.
Logs are written to stderr, so they can be redirected easily to a file:
pimconf --log trace autoconfig user fastmail.com 2>/tmp/pimconf.logThis project is licensed under either of:
at your option.
- Chat on Matrix
- News on Mastodon or RSS
- Mail at pimalaya.org@posteo.net
Special thanks to the NLnet foundation and the European Commission that have been financially supporting the project for years:
- 2022 → 2023: NGI Assure
- 2023 → 2024: NGI Zero Entrust
- 2024 → 2026: NGI Zero Core
- 2027 in preparation…
If you appreciate the project, feel free to donate using one of the following providers:
