package e2e_test import ( "fmt" "log" "os" "path" "testing" "time" "github.com/google/uuid" ) const workingdir = "/shared/workingdir" func ensureWorkingDirectory() { err := os.MkdirAll(workingdir, 0o700) if err != nil { log.Panicf("failed to create working directory %s: %v", workingdir, err) } } func TestWorkingDirectory(t *testing.T) { piperaddr, piperport := nextAvailablePiperAddress() piper, _, _, err := runCmd("/sshpiperd/sshpiperd", "-p", piperport, "/sshpiperd/plugins/workingdir", "--root", workingdir, ) if err != nil { t.Errorf("failed to run sshpiperd: %v", err) } defer killCmd(piper) waitForEndpointReady(piperaddr) ensureWorkingDirectory() t.Run("bypassword", func(t *testing.T) { userdir := path.Join(workingdir, "bypassword") { if err := os.MkdirAll(userdir, 0o700); err != nil { t.Errorf("failed to create working directory %s: %v", userdir, err) } if err := os.WriteFile(path.Join(userdir, "sshpiper_upstream"), []byte("user@host-password:2222"), 0o400); err != nil { t.Errorf("failed to write upstream file: %v", err) } } { b, err := runAndGetStdout( "ssh-keyscan", "-p", "2222", "host-password", ) if err != nil { t.Errorf("failed to run ssh-keyscan: %v", err) } if err := os.WriteFile(path.Join(userdir, "known_hosts"), b, 0o400); err != nil { t.Errorf("failed to write known_hosts: %v", err) } } { randtext := uuid.New().String() targetfie := uuid.New().String() c, stdin, stdout, err := runCmd( "ssh", "-v", "-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null", "-p", piperport, "-l", "bypassword", "127.0.0.1", fmt.Sprintf(`sh -c "echo -n %v > /shared/%v"`, randtext, targetfie), ) if err != nil { t.Errorf("failed to ssh to piper-workingdir, %v", err) } defer killCmd(c) enterPassword(stdin, stdout, "pass") time.Sleep(time.Second) // wait for file flush checkSharedFileContent(t, targetfie, randtext) } }) t.Run("bypublickey", func(t *testing.T) { userdir := path.Join(workingdir, "bypublickey") if err := os.MkdirAll(userdir, 0o700); err != nil { t.Errorf("failed to create working directory %s: %v", userdir, err) } if err := os.WriteFile(path.Join(userdir, "sshpiper_upstream"), []byte("user@host-publickey:2222"), 0o400); err != nil { t.Errorf("failed to write upstream file: %v", err) } { b, err := runAndGetStdout( "ssh-keyscan", "-p", "2222", "host-publickey", ) if err != nil { t.Errorf("failed to run ssh-keyscan: %v", err) } if err := os.WriteFile(path.Join(userdir, "known_hosts"), b, 0o400); err != nil { t.Errorf("failed to write known_hosts: %v", err) } } keydir, err := os.MkdirTemp("", "") // generate a local key if err != nil { t.Errorf("failed to create temp dir: %v", err) } { if err := runCmdAndWait("rm", "-f", path.Join(keydir, "id_rsa")); err != nil { t.Errorf("failed to remove id_rsa: %v", err) } if err := runCmdAndWait( "ssh-keygen", "-N", "", "-f", path.Join(keydir, "id_rsa"), ); err != nil { t.Errorf("failed to generate private key: %v", err) } if err := runCmdAndWait( "/bin/cp", path.Join(keydir, "id_rsa.pub"), path.Join(userdir, "authorized_keys"), ); err != nil { t.Errorf("failed to copy public key: %v", err) } if err := runCmdAndWait( "chmod", "0400", path.Join(userdir, "authorized_keys"), ); err != nil { t.Errorf("failed to chmod public key: %v", err) } // set upstream key if err := runCmdAndWait("rm", "-f", path.Join(userdir, "id_rsa")); err != nil { t.Errorf("failed to remove id_rsa: %v", err) } if err := runCmdAndWait( "ssh-keygen", "-N", "", "-f", path.Join(userdir, "id_rsa"), ); err != nil { t.Errorf("failed to generate private key: %v", err) } if err := runCmdAndWait( "/bin/cp", path.Join(userdir, "id_rsa.pub"), "/publickey_authorized_keys/authorized_keys", ); err != nil { t.Errorf("failed to copy public key: %v", err) } } { randtext := uuid.New().String() targetfie := uuid.New().String() c, _, _, err := runCmd( "ssh", "-v", "-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null", "-p", piperport, "-l", "bypublickey", "-i", path.Join(keydir, "id_rsa"), "127.0.0.1", fmt.Sprintf(`sh -c "echo -n %v > /shared/%v"`, randtext, targetfie), ) if err != nil { t.Errorf("failed to ssh to piper-workingdir, %v", err) } defer killCmd(c) time.Sleep(time.Second) // wait for file flush checkSharedFileContent(t, targetfie, randtext) } }) }