Desctiption-Docs
Some checks failed
CI / checks (push) Failing after 1m51s

This commit is contained in:
Alex Emmet 2026-07-02 20:21:12 +02:00
commit 5bfcccc056
5 changed files with 36 additions and 5 deletions

View file

@ -71,7 +71,8 @@ The host's `accept()` method:
### Login/Register Handshake
When `require_authentication` is set, the parties run a mutually-authenticated
When `authentication_policy` is `ForceAuthentication` or `AllowAuthentication`,
the parties run a mutually-authenticated
**challenge-response**. The client speaks first with an *unsigned* hello:
- **Login** (`CommunicationType::Identification`, reserved ID 0): version, client ID

View file

@ -29,6 +29,7 @@ let config = ClientConfig::new("https://host.example.com:4433")
| `url` | `String` | `https://host:port` address of the MTP host |
| `tls` | `ClientTlsConfig` | `SystemRoots` or `PinnedPem(pem_bytes)` |
| `client_id` | `u64` | Client identifier (ignored during `auth_register`) |
| `description` | `Option<String>` | Optional label sent during handshake (e.g. `"phone"`) |
| `auth_timeout` | `Duration` (crypto) | Authentication handshake timeout (default 30s) |
### TLS Certificate Handling
@ -60,6 +61,7 @@ pub struct MTPConnection {
pub version: Version,
pub sender: Sender,
pub receiver: Receiver,
pub description: Option<String>,
#[cfg(feature = "crypto")]
pub auth_state: AuthState,
#[cfg(feature = "crypto")]
@ -69,6 +71,7 @@ pub struct MTPConnection {
- `version` -- the negotiated protocol version
- `sender` / `receiver` -- for message I/O
- `description` -- the label sent during handshake (set via `ClientConfig::with_description`)
- `client_id` -- the confirmed/assigned client identifier (crypto only)
### Unauthenticated Connect

View file

@ -48,11 +48,30 @@ let config = HostConfig::new(
| `port` | `u16` | Listen port |
| `tls_fullchain` | `Vec<u8>` | PEM-encoded TLS certificate chain |
| `tls_key` | `Vec<u8>` | PEM-encoded TLS private key |
| `require_authentication` | `bool` (crypto) | Enable login/register handshake |
| `authentication_policy` | `AuthenticationPolicy` (crypto) | `ForceAuthentication`, `AllowAuthentication`, or `Unauthenticated` |
| `host_keyring` | `Keyring` (crypto) | Host's signing and KEM keys |
| `get_existing_user` | `Fn(u64) -> Pin<Box<dyn Future<Output = Option<PublicKeyBundle>> + Send>> + Send + Sync` (crypto) | Async lookup callback for login |
| `complete_register` | `Fn(PublicKeyBundle) -> Pin<Box<dyn Future<Output = u64> + Send>> + Send + Sync` (crypto) | Async registration callback, returns new client ID |
### AuthenticationPolicy
`ForceAuthentication` requires every client to complete the login/register handshake. `AllowAuthentication` accepts both authenticated and unauthenticated connections — unauthenticated clients get a random ID and `AuthState::Unauthenticated`. `Unauthenticated` rejects any client that tries to authenticate and is the default.
```rust
use mtp::host::AuthenticationPolicy;
// Force authentication (default was `require_authentication: true`):
let config = HostConfig::new(ip, port, cert, key)
.with_authentication(host_keyring, get_user, register);
// Allow both authenticated and unauthenticated:
let config = HostConfig::new(ip, port, cert, key)
.with_allow_authentication(host_keyring, get_user, register);
// Unauthenticated only (default):
let config = HostConfig::new(ip, port, cert, key);
```
### TLS
The host requires a TLS certificate. For development, generate a self-signed
@ -82,6 +101,7 @@ pub struct MTPConnection {
pub codec: VersionedCodec,
pub sender: Sender,
pub receiver: Receiver,
pub description: Option<String>,
#[cfg(feature = "crypto")]
pub auth_state: AuthState,
#[cfg(feature = "crypto")]
@ -95,6 +115,7 @@ pub struct MTPConnection {
- `codec` -- a `VersionedCodec` scoped to the negotiated version (use for
version-aware encode/decode)
- `sender` / `receiver` -- for message I/O
- `description` -- optional client-provided label (e.g. `"phone"`, `"desktop"`)
- `client_id` -- the authenticated client's ID
- `client_public_key` -- the client's public key bundle (for signature
verification of subsequent messages)
@ -130,7 +151,7 @@ let negotiated = registry.negotiate(&[Version(1, 0), Version(2, 0)]);
## Authentication Flow
When `require_authentication` is `true`, `accept()` runs a mutually-authenticated
When `authentication_policy` is `ForceAuthentication`, `accept()` runs a mutually-authenticated
**challenge-response** handshake before returning the connection. The host issues
a fresh, random `server_challenge` that the client must sign, which is what makes
the client's proof unreplayable: a captured proof is bound to a one-time challenge