X-Git-Url: https://ruderich.org/simon/gitweb/?a=blobdiff_plain;f=rpc%2Fdial.go;h=d8a63386333d2c76c27affca33418d3378bcc4dc;hb=3840c3fe7fab425ef7d20d2f686884b404bb5e62;hp=b723e55c5657e78609d79b8019448636c3de5eef;hpb=ac30b1856db3d63705270ddf26ff0b7b56c9c9c9;p=safcm%2Fsafcm.git diff --git a/rpc/dial.go b/rpc/dial.go index b723e55..d8a6338 100644 --- a/rpc/dial.go +++ b/rpc/dial.go @@ -32,11 +32,15 @@ import ( "ruderich.org/simon/safcm/remote" ) -func (c *Conn) DialSSH(remote string) error { +func (c *Conn) DialSSH(user, host string) error { if c.events == nil { return fmt.Errorf("cannot reuse Conn") } + remote := host + if user != "" { + remote = user + "@" + host + } c.debugf("DialSSH: connecting to %q", remote) opts := "-eu" @@ -94,6 +98,36 @@ func (c *Conn) dialSSH(stdin io.Writer, stdout_ io.Reader) error { path := fmt.Sprintf("/tmp/safcm-remote-%d", uid) c.debugf("DialSSH: probing remote at %q", path) + + // Compatibility for different operating systems + var compat string + switch goos { + case "linux": + compat = ` +dir_stat='drwxrwxrwt 0 0' +file_stat="-rwx------ $(id -u) $(id -g)" +compat_stat() { + stat -c '%A %u %g' "$1" +} +compat_sha512sum() { + sha512sum "$1" +} +` + case "freebsd", "openbsd": + compat = ` +dir_stat='41777 0 0' +file_stat="100700 $(id -u) $(id -g)" +compat_stat() { + stat -f '%p %u %g' "$1" +} +compat_sha512sum() { + sha512 -q "$1" +} +` + default: + return fmt.Errorf("internal error: no support for %q", goos) + } + // Use a function so the shell cannot execute the input line-wise. // This is important because we're also using stdin to send data to // the script. If the shell executes the input line-wise then our @@ -112,18 +146,19 @@ func (c *Conn) dialSSH(stdin io.Writer, stdout_ io.Reader) error { // `test -e` is only used to prevent error messages if the file // doesn't exist. It does not guard against any races. _, err = fmt.Fprintf(stdin, ` +%s f() { x=%q dir="$(dirname "$x")" - if ! test "$(stat -c '%%A %%u %%g' "$dir")" = 'drwxrwxrwt 0 0'; then + if ! test "$(compat_stat "$dir")" = "$dir_stat"; then echo "unsafe permissions on $dir, aborting" >&2 exit 1 fi - if test -e "$x" && test "$(stat -c '%%A %%u' "$x")" = "-rwx------ $(id -u)"; then + if test -e "$x" && test "$(compat_stat "$x")" = "$file_stat"; then # Report checksum - sha512sum "$x" + compat_sha512sum "$x" else # Empty checksum to request upload echo @@ -146,12 +181,14 @@ f() { rm "$tmp" # Make file executable chmod 0700 "$x" + # Some BSD create files with group wheel in /tmp + chgrp "$(id -g)" "$x" fi - exec "$x" + exec "$x" sync } f -`, path) +`, compat, path) if err != nil { return err } @@ -239,7 +276,7 @@ f } func connGetGoos(stdin io.Writer, stdout *bufio.Reader) (string, error) { - _, err := fmt.Fprintln(stdin, "uname -o") + _, err := fmt.Fprintln(stdin, "uname") if err != nil { return "", err } @@ -252,10 +289,14 @@ func connGetGoos(stdin io.Writer, stdout *bufio.Reader) (string, error) { // NOTE: Adapt helper uploading in dialSSH() when adding new systems var goos string switch x { - case "GNU/Linux": + case "Linux": goos = "linux" + case "FreeBSD": + goos = "freebsd" + case "OpenBSD": + goos = "openbsd" default: - return "", fmt.Errorf("unsupported OS %q (`uname -o`)", x) + return "", fmt.Errorf("unsupported OS %q (`uname`)", x) } return goos, nil } @@ -274,7 +315,7 @@ func connGetGoarch(stdin io.Writer, stdout *bufio.Reader) (string, error) { // NOTE: Adapt cmd/safcm-remote/build.sh when adding new architectures var goarch string switch x { - case "x86_64": + case "x86_64", "amd64": goarch = "amd64" case "armv7l": goarch = "armv7l"