-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add capability-based security to protect all
TCP
actions.
Now we have the following hierarchy: - `Env.Root` - `TCP.Connect.Auth` - `TCP.Connect.Ticket` - `TCP.Listen.Auth` - `TCP.Listen.Ticket` Additionally we have `TCP.Accept.Ticket` which can only come from an actual pending connection trying to connect to a TCP listener. Attenuating through the hierarchy to create a connect ticket looks like this: ```savi TCP.auth(env.root).connect.to(host, port) ``` Attentuating through the hierarchy to create a listen ticket looks like this: ```savi TCP.auth(env.root).listen.on(host, port) ```
- Loading branch information
Showing
10 changed files
with
177 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
:: `TCP.Auth` grants the capability to do unlimited actions related to TCP. | ||
:: | ||
:: To grant only the capability to open connections to remote hosts, | ||
:: attenuate this capability to `TCP.Connect.Auth` using the `connect` method. | ||
:: | ||
:: To grant only the capability to bind a listener to accept connections, | ||
:: attenuate this capability to `TCP.Listen.Auth` using the `listen` method. | ||
:: | ||
:: Both of those lesser capabilities also have ways to attenuate further to | ||
:: allow only a specific host and port to bind/connect to. | ||
:struct val TCP.Auth // TODO: use :authority instead of an empty :struct | ||
:: Use the given `Env.Root` (which is the root of all authority) to | ||
:: attenuate to this lesser capability (which grants only TCP actions). | ||
:new val (root Env.Root) | ||
|
||
:: Use this capability (which grants unlimited TCP actions) to attenuate | ||
:: to a `TCP.Connect.Auth` (which grants only for opening connections). | ||
:fun val connect: TCP.Connect.Auth.new(@) | ||
|
||
:: Use this capability (which grants unlimited TCP actions) to attenuate | ||
:: to a `TCP.Listen.Auth` (which grants only for binding listeners). | ||
:fun val listen: TCP.Listen.Auth.new(@) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
:: `TCP.Connect.Auth` grants the capability to open any number of TCP connection | ||
:: sockets to any remote hosts/ports. | ||
:: | ||
:: To grant the capability to open just one TCP connection, attenuate this | ||
:: capability to a `TCP.Connect.Ticket`, using the `to` method. | ||
:struct val TCP.Connect.Auth // TODO: use :authority instead of an empty :struct | ||
|
||
:: Use the given `TCP.Auth` (which grants the capability for all TCP actions) | ||
:: to attenuate to this lesser capability (which grants only TCP connections). | ||
:new val (auth TCP.Auth) | ||
|
||
:: Use this capability (which grants unlimited TCP connections) to attenuate | ||
:: to a `TCP.Connect.Ticket` (which grants for only a single host and port). | ||
:: | ||
:: The `host` string indicates the remote host to connect to, either as an | ||
:: IP address, or as a domain name to be resolved via DNS. | ||
:: If `host` is empty, localhost (the loopback interface) will be targeted. | ||
:: | ||
:: The `port` string may be a number string (such as `"80"`) or a named port | ||
:: (such as `"http"`). See the IANA port number registry for more examples. | ||
:: | ||
:: The `from_port`, if given, indicates the local port to bind to. | ||
:: This is not usually necessary, but may be used if the remote side is | ||
:: expected to validate the port that the connection comes from. | ||
:: If `from_port` is left empty, an open port will be selected arbitrarily. | ||
:fun val to(host String, port String, from_port String = "") | ||
TCP.Connect.Ticket.new(@, host, port, from_port) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
:: A `TCP.Connect.Ticket` grants the capability to connect to a specific | ||
:: host and port using the TCP protocol. | ||
:: | ||
:: To make use of the ticket, it should be passed to an actor that will use | ||
:: `TCP.Engine.new` to create a new engine that can be used to connect and | ||
:: exchange data with the remote TCP socket (if the connection succeeds). | ||
:struct iso TCP.Connect.Ticket | ||
:: The `host` string indicates the remote host to connect to, either as an | ||
:: IP address, or as a domain name to be resolved via DNS. | ||
:: If `host` is empty, localhost (the loopback interface) will be targeted. | ||
:let host String | ||
|
||
:: The `port` string may be a number string (such as `"80"`) or a named port | ||
:: (such as `"http"`). See the IANA port number registry for more examples. | ||
:let port String | ||
|
||
:: The `from_port`, if given, indicates the local port to bind to. | ||
:: This is not usually necessary, but may be used if the remote side is | ||
:: expected to validate the port that the connection comes from. | ||
:: If `from_port` is left empty, an open port will be selected arbitrarily. | ||
:let from_port String | ||
|
||
:: Use the given `TCP.Connect.Auth` (which grants unlimited TCP connections) | ||
:: to issue a new ticket (which grants for only a single host and port). | ||
:new iso new(auth TCP.Connect.Auth, @host, @port, @from_port = "") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
:: `TCP.Listen.Auth` grants the capability to open any number of TCP listener | ||
:: sockets on any interfaces/ports, accepting any number of remote connections. | ||
:: | ||
:: To grant the capability to open just one TCP listener socket, attenuate this | ||
:: capability to a `TCP.Listen.Ticket`, using the `on` method. | ||
:struct val TCP.Listen.Auth // TODO: use :authority instead of an empty :struct | ||
|
||
:: Use the given `TCP.Auth` (which grants the capability for all TCP actions) | ||
:: to attenuate to this lesser capability (which grants only TCP listeners). | ||
:new val (auth TCP.Auth) | ||
|
||
:: Use this capability (which grants unlimited TCP listeners) to attenuate | ||
:: to a `TCP.Listen.Ticket` (which grants for only a single host and port). | ||
:: | ||
:: The `host` string is an indirect indicator of which interface to bind to. | ||
:: For example, `"localhost"` indicates the loopback interface (allowing no | ||
:: connections from remote origins), whereas `"0.0.0.0"` or `"::"` indicate | ||
:: to the listener to bind on all interfaces (allowing remote connections). | ||
:: If `host` is empty, the listener will bind on all interfaces. | ||
:: | ||
:: The `port` string may be a number string (such as `"80"`) or a named port | ||
:: (such as `"http"`). See the IANA port number registry for more examples. | ||
:: If `port` is an empty string, an open port will be selected arbitrarily. | ||
:fun val on(host String, port String) | ||
TCP.Listen.Ticket.new(@, host, port) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
:: A `TCP.Listen.Ticket` grants the capability to bind a TCP listener on | ||
:: a specific port and host (which implies the interface to bind to). | ||
:: | ||
:: To make use of the ticket, it should be passed to an actor that will use | ||
:: `TCP.Listen.Engine.new` to create a new engine that binds the listener and | ||
:: can issue `TCP.Accept.Ticket`s when new pending connections are initiated. | ||
:struct iso TCP.Listen.Ticket | ||
:: The `host` string is an indirect indicator of which interface to bind to. | ||
:: For example, `"localhost"` indicates the loopback interface (allowing no | ||
:: connections from remote origins), whereas `"0.0.0.0"` or `"::"` indicate | ||
:: to the listener to bind on all interfaces (allowing remote connections). | ||
:: If `host` is empty, the listener will bind on all interfaces. | ||
:let host String | ||
|
||
:: The `port` string may be a number string (such as `"80"`) or a named port | ||
:: (such as `"http"`). See the IANA port number registry for more examples. | ||
:: If `port` is an empty string, an open port will be selected arbitrarily. | ||
:let port String | ||
|
||
:: Use the given `TCP.Listen.Auth` (whichwhich grants unlimited TCP listeners) | ||
:: to issue a new ticket (which grants for only a single host and port). | ||
:new iso new(auth TCP.Listen.Auth, @host, @port) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
:: The `TCP` module is the namespace for this library, and is also a place | ||
:: for simple convenience functions that wrap other functions in the library. | ||
:module TCP | ||
:: Use the given `Env.Root` (which is the root of all authority) to | ||
:: attenuate to a `TCP.Auth` (which grants only TCP actions). | ||
:fun auth(root): TCP.Auth.new(root) |