diff --git a/proto/bash.go b/proto/bash.go index 62b57be..ec87185 100644 --- a/proto/bash.go +++ b/proto/bash.go @@ -1,7 +1,9 @@ package proto import ( + "bytes" "context" + "io" "os" "os/exec" @@ -10,12 +12,37 @@ import ( "github.com/libp2p/go-libp2p/core/peer" protocol "github.com/libp2p/go-libp2p/core/protocol" "github.com/portal-co/portald/provision" + "golang.org/x/crypto/bcrypt" ) +func HasHash(pws [][]byte, x []byte) bool { + for _, pw := range pws { + if bcrypt.CompareHashAndPassword(x, pw) == nil { + return true + } + } + return false +} +func ReadHash(pw [][]byte, x io.Reader) error { + var b [1]byte + h := bytes.NewBuffer([]byte{}) + for !HasHash(pw, h.Bytes()) { + _, err := x.Read(b[:]) + if err != nil { + return err + } + h.Write(b[:]) + } + return nil +} + var BashId = "/p2p/portal-co-bash/0.0.1" -func AddBash(h host.Host) { +func AddBash(h host.Host, pw [][]byte) { h.SetStreamHandler(protocol.ID(BashId), func(s network.Stream) { + if ReadHash(pw, s) != nil { + return + } o, _ := os.MkdirTemp("/tmp", "portal-*") defer os.RemoveAll(o) e := exec.Command("bwrap", "--unshare-all", "--share-net", "--ro-bind", "/", "/", "--ro-bind", "/ipfs", "/ipfs", "--dev /dev", "--proc", "/proc", "--tmp", "/tmp", "--bind", o, o, "/bin/bash") @@ -28,11 +55,19 @@ func AddBash(h host.Host) { func GetBash(ctx context.Context, host host.Host, peer peer.ID) (network.Stream, error) { return host.NewStream(ctx, peer, protocol.ID(BashId)) } -func RunIn(ctx context.Context, host host.Host, peer peer.ID, x provision.ProcessInputs) (provision.ProcessOutputs, error) { +func RunIn(ctx context.Context, host host.Host, peer peer.ID, x provision.ProcessInputs, pw []byte) (provision.ProcessOutputs, error) { s, err := GetBash(ctx, host, peer) if err != nil { return provision.ProcessOutputs{}, err } defer s.Close() + b, err := bcrypt.GenerateFromPassword(pw, bcrypt.DefaultCost) + if err != nil { + return provision.ProcessOutputs{}, err + } + _, err = s.Write(b) + if err != nil { + return provision.ProcessOutputs{}, err + } return provision.Run(s, x) }