# Module Netpop

    module Netpop: sig .. end

This is an interface for the Post Office Protocol - Version 3 (POP3) as specifed by RFC 1939. The protocol is intended to permit a workstation to dynamically access a maildrop on a server host in a useful fashion.

    type state = [ `Authorization | `Transaction | `Update ]

    exception Protocol_error

    exception Authentication_error

    exception Err_status of string

    exception Bad_state

    val tcp_port : int

Default TCP port for POP version 3

    class client : Netchannels.in_obj_channel -> Netchannels.out_obj_channel -> object .. end

The class `client` implements the POP3 protocol.

    class connect : ?proxy:#Uq_engines.client_endpoint_connector -> Uq_engines.connect_address -> float -> client

`connect addr timeout`: Connects with the server at `addr`, and configure that I/O operations time out after `timeout` seconds of waiting.

    val authenticate : ?tls_config:Netsys_crypto_types.tls_config ->
           ?tls_required:bool ->
           ?tls_peer:string ->
           ?sasl_mechs:Netsys_sasl.sasl_mechanism list ->
           ?sasl_params:(string * string * bool) list ->
           ?user:string ->
           ?authz:string -> ?creds:Netsys_sasl.credentials -> client -> unit

Authenticates the session:

- requests capabilitlies
- if the server supports TLS, and `tls_config` is set, the TLS session is started, and the capabilities are refreshed.
- if SASL support is announced by the server, one of the `sasl_mechs` is taken and used for authentication. If `sasl_mechs` is empty, this authentication step is skipped.

Options:

- `tls_config`: if set, TLS is tried on the connection
- `tls_required`: if set, it is even required that TLS is supported. If not, a `Netsys_types.TLS_error` exception is raised.
- `tls_peer`: the host name of the server (only needed for TLS, and only needed if the TLS configuration authenticates the server, or if the SNI extension is active)
- `sasl_mechs`: available SASL mechanisms (in order of preference). If you pass mechanisms, you'll normally also need to pass `user` and `creds`.
- `sasl_params`: parameters for SASL. A "digest-uri" parameter is always generated, and need not to be set
- `user`: the user name to authenticate as
- `authz`: the identity to act as (authorization name)
- `creds`: credentials

You can get a simple TLS configuration with:

    let tls_config =
      Netsys_tls.create_x509_config
        ~system_trust:true
        ~peer_auth:`Required
        (Netsys_crypto.current_tls())

SASL example:

    Netpop.authenticate
      ~sasl_mechs:[ (module Netmech_scram_sasl.SCRAM_SHA1);
                    (module Netmech_digest_sasl.DIGEST_MD5);
                  ]
      ~user:"tom"
      ~creds:[ "password", "sEcReT", [] ]
      client

# Debugging

    module Debug: sig .. end