Route byre client-exec through HTTP_PROXY for loopback too
This commit is contained in:
+49
-1
@@ -6,6 +6,8 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -50,7 +52,9 @@ func clientExecCmd(args []string) {
|
||||
}
|
||||
hr.Header.Set("Authorization", "Bearer "+token)
|
||||
hr.Header.Set("Content-Type", "application/json")
|
||||
hc := &http.Client{Timeout: time.Duration(*timeout)*time.Second + execGrace}
|
||||
tr := http.DefaultTransport.(*http.Transport).Clone()
|
||||
tr.Proxy = apiProxy
|
||||
hc := &http.Client{Transport: tr, Timeout: time.Duration(*timeout)*time.Second + execGrace}
|
||||
resp, err := hc.Do(hr)
|
||||
if err != nil {
|
||||
execFail(execUnavailable, err.Error())
|
||||
@@ -82,6 +86,50 @@ func clientExecCmd(args []string) {
|
||||
os.Exit(res.ExitCode)
|
||||
}
|
||||
|
||||
// http.ProxyFromEnvironment never proxies loopback, but a sandboxed shell can
|
||||
// reach byre's loopback API only through its proxy.
|
||||
func apiProxy(r *http.Request) (*url.URL, error) {
|
||||
if os.Getenv("BYRE_NO_PROXY") == "1" {
|
||||
return nil, nil
|
||||
}
|
||||
p := os.Getenv("HTTP_PROXY")
|
||||
if p == "" {
|
||||
p = os.Getenv("http_proxy")
|
||||
}
|
||||
if p == "" || noProxy(r.URL) {
|
||||
return nil, nil
|
||||
}
|
||||
if !strings.Contains(p, "://") {
|
||||
p = "http://" + p
|
||||
}
|
||||
return url.Parse(p)
|
||||
}
|
||||
|
||||
func noProxy(u *url.URL) bool {
|
||||
list := os.Getenv("NO_PROXY")
|
||||
if list == "" {
|
||||
list = os.Getenv("no_proxy")
|
||||
}
|
||||
host := u.Hostname()
|
||||
ip, ipErr := netip.ParseAddr(host)
|
||||
for _, e := range strings.Split(list, ",") {
|
||||
e = strings.TrimSpace(e)
|
||||
if e == "" {
|
||||
continue
|
||||
}
|
||||
if pfx, err := netip.ParsePrefix(e); err == nil {
|
||||
if ipErr == nil && pfx.Contains(ip) {
|
||||
return true
|
||||
}
|
||||
continue
|
||||
}
|
||||
if e == "*" || e == u.Host || e == host || strings.HasSuffix(host, "."+strings.TrimPrefix(e, ".")) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func execFail(code int, msg string) {
|
||||
fmt.Fprintln(os.Stderr, "byre client-exec: "+msg)
|
||||
os.Exit(code)
|
||||
|
||||
@@ -26,6 +26,10 @@ BYRE_TOKEN=$(<"$HOME/Library/Application Support/byre/loopback-token") byre clie
|
||||
|
||||
byre logs each call (client, command, exit status, duration), never its output.
|
||||
|
||||
## Sandboxed shells
|
||||
|
||||
client-exec calls byre's API at `http://127.0.0.1:8270`. When `HTTP_PROXY` (or `http_proxy`) is set it sends that call through the proxy, loopback included, unless `NO_PROXY` lists the address; a sandbox that denies direct loopback connections then needs only to allow `127.0.0.1:8270` through its proxy. `BYRE_NO_PROXY=1` connects directly whatever the proxy variables say.
|
||||
|
||||
## Screen lock
|
||||
|
||||
`byre screen` prints `unlocked`, `locked` or `no-session` (no GUI login for this user) for the Mac it runs on, and exits 0. Check the server Mac with `byre screen` and the client with:
|
||||
|
||||
Reference in New Issue
Block a user