FTP connections preserve passwords and filenames, with CI checking every change #1
@@ -8,17 +8,16 @@ The plugin is a WebAssembly component built against the Memona filesystem
|
||||
contract, `memona:filesystem@0.1.0`. It uses only the host's sockets; it has no
|
||||
ambient filesystem, environment or network access of its own.
|
||||
|
||||
This package requires a Memona version that supports plugin manifest schema 2.
|
||||
|
||||
## What it registers
|
||||
|
||||
One provider, `ftp`, for the `ftp` and `ftps` schemes. A connection is
|
||||
configured with a server name, an optional port, a TLS toggle for FTPS, and an
|
||||
optional username and password. An empty username signs in anonymously.
|
||||
|
||||
In Memona's connection permissions, enter the server's hostname or IP in
|
||||
**Allowed hosts**, without a scheme, port or path. An empty list blocks the
|
||||
connection. Turn on **Private network** as well for localhost or a private
|
||||
network; this switch does not grant a host by itself. Save and reconnect after
|
||||
changing permissions.
|
||||
For localhost or a server on a private network, turn on **Private network** in
|
||||
the connection settings. Save and reconnect after changing these settings.
|
||||
|
||||
The TLS toggle currently starts TLS on the control connection only. Protected
|
||||
data connections and explicit `AUTH TLS` negotiation are not implemented, so
|
||||
@@ -37,11 +36,9 @@ and connects out to it; `PASV` fallback is not implemented. The server picks a f
|
||||
transfer and announces it only as the transfer begins, so the range that has to
|
||||
be reachable is wide.
|
||||
|
||||
`manifest.json` declares `networkPorts` as 21 and 1024-65535, and `networkHosts`
|
||||
as `*` because a server can be anywhere. Declaring is not granting: a
|
||||
connection reaches only the host and ports the person grants it, and a grant
|
||||
never accepts a wildcard host. Grant the control port and the span the server
|
||||
uses for its data channel, usually `21` and `1024-65535`.
|
||||
The package declares socket ports 21 and 1024-65535, which Memona applies
|
||||
automatically to each connection. The control port and passive data ports
|
||||
must be within these ranges.
|
||||
|
||||
## Build
|
||||
|
||||
|
||||
+1
-2
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"schemaVersion": 2,
|
||||
"id": "memona/ftp",
|
||||
"name": "FTP",
|
||||
"version": "0.1.3",
|
||||
@@ -7,7 +7,6 @@
|
||||
"description": "Open an FTP server as a folder, and let agents work in it.",
|
||||
"license": "MIT",
|
||||
"entry": "plugin.wasm",
|
||||
"networkHosts": ["*"],
|
||||
"networkPorts": [
|
||||
{ "from": 21, "to": 21 },
|
||||
{ "from": 1024, "to": 65535 }
|
||||
|
||||
+10
-10
@@ -35,10 +35,10 @@ interface host {
|
||||
/// `respond`. An empty result means the body is complete.
|
||||
pull: func(limit: u32) -> result<list<u8>, host-error>;
|
||||
}
|
||||
/// Begins a request to a host both declared by the package and granted on
|
||||
/// the connection. Each redirect and DNS result is checked, and DNS is
|
||||
/// pinned. Private/LAN addresses additionally require the private-network
|
||||
/// grant. Cross-origin redirects remove request headers; HTTPS cannot
|
||||
/// Begins a request to any public HTTP or HTTPS host. Each redirect and
|
||||
/// DNS result is checked, and DNS is pinned. Private/LAN addresses require
|
||||
/// the connection's private-network grant. Cross-origin redirects remove
|
||||
/// request headers; HTTPS cannot
|
||||
/// downgrade. The host bounds total bytes per exchange, not buffer size.
|
||||
http: func(request: request) -> result<exchange, host-error>;
|
||||
|
||||
@@ -51,13 +51,13 @@ interface host {
|
||||
/// Writes at most 1,048,576 bytes and returns how many were accepted.
|
||||
write: func(data: list<u8>) -> result<u32, host-error>;
|
||||
}
|
||||
|
|
||||
/// Opens a socket to a host and port both declared by the package and
|
||||
/// granted on the connection. The host resolves and pins DNS, applies the
|
||||
/// same private-address rule as `http`, and starts TLS when asked. Ports
|
||||
/// negotiated at runtime, such as an FTP data channel, still need a grant.
|
||||
/// Opens a socket to any public host on a package-declared port.
|
||||
/// The host resolves and pins DNS, applies the same private-address rule
|
||||
/// as `http`, and starts TLS when asked. Ports
|
||||
/// negotiated at runtime, such as an FTP data channel, must be declared.
|
||||
connect: func(host: string, port: u16, tls: bool) -> result<tcp, host-error>;
|
||||
|
||||
/// One datagram socket connected to a single granted peer.
|
||||
/// One datagram socket connected to a single peer.
|
||||
resource udp {
|
||||
/// Sends one datagram of at most 65,507 bytes.
|
||||
send: func(data: list<u8>) -> result<u32, host-error>;
|
||||
@@ -65,7 +65,7 @@ interface host {
|
||||
/// means none arrived inside the host's wait, not that the peer left.
|
||||
receive: func(limit: u32) -> result<list<u8>, host-error>;
|
||||
}
|
||||
/// Connects a datagram socket under the same declaration and grant rules
|
||||
/// Connects a datagram socket under the same port and private-network rules
|
||||
/// as `connect`, for the few filesystem protocols that still need one.
|
||||
bind: func(host: string, port: u16) -> result<udp, host-error>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user
LAN and loopback access still requires Memona's Private network permission, so this contract comment incorrectly promises direct access. Restore that qualification here and in the README so users are not led to a setup that fails at runtime.