Skip to content

Commit

Permalink
Merge pull request #510 from ivcosla/feature/therealssh-cli-pty-cmd
Browse files Browse the repository at this point in the history
Added pty flags to ssh CLI
  • Loading branch information
ivcosla authored Aug 13, 2019
2 parents e854ef8 + 77d3a48 commit aa0538b
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 43 deletions.
77 changes: 76 additions & 1 deletion cmd/therealssh-cli/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,25 @@ import (
ssh "github.com/skycoin/skywire/pkg/therealssh"
)

var rpcAddr string
var (
rpcAddr string
ptyMode bool
ptyRows uint16
ptyCols uint16
ptyX uint16
ptyY uint16
ptyBufferSize uint32
)

var rootCmd = &cobra.Command{
Use: "SSH-cli [user@]remotePK [command] [args...]",
Short: "Client for the SSH-client app",
Args: cobra.MinimumNArgs(1),
Run: func(_ *cobra.Command, args []string) {
if ptyMode {
runInPTY(args)
return
}
client, err := rpc.DialHTTP("tcp", rpcAddr)
if err != nil {
log.Fatal("RPC connection failed:", err)
Expand Down Expand Up @@ -117,6 +129,63 @@ var rootCmd = &cobra.Command{
},
}

func runInPTY(args []string) {
client, err := rpc.DialHTTP("tcp", rpcAddr)
if err != nil {
log.Fatal("RPC connection failed:", err)
}

username, pk, err := resolveUser(args[0])
if err != nil {
log.Fatal("Invalid user/pk pair: ", err)
}

remotePK := cipher.PubKey{}
if err := remotePK.UnmarshalText([]byte(pk)); err != nil {
log.Fatal("Invalid remote PubKey: ", err)
}

ptyArgs := &ssh.RequestPTYArgs{
Username: username,
RemotePK: remotePK,
Size: &pty.Winsize{
Rows: uint16(ptyRows),
Cols: ptyCols,
X: ptyX,
Y: ptyY,
},
}

var channelID uint32
if err := client.Call("RPCClient.RequestPTY", ptyArgs, &channelID); err != nil {
log.Fatal("Failed to request PTY:", err)
}

var socketPath string
execArgs := &ssh.ExecArgs{
ChannelID: channelID,
CommandWithArgs: args[1:],
}

err = client.Call("RPCClient.Run", execArgs, &socketPath)
if err != nil {
log.Fatal(err)
}

conn, err := net.DialUnix("unix", nil, &net.UnixAddr{Name: socketPath, Net: "unix"})
if err != nil {
log.Fatal(err)
}

b := make([]byte, ptyBufferSize)
_, err = conn.Read(b)
if err != nil {
log.Fatal(err)
}

fmt.Print(string(b))
}

func resolveUser(arg string) (username string, pk string, err error) {
components := strings.Split(arg, "@")
if len(components) == 1 {
Expand All @@ -137,6 +206,12 @@ func resolveUser(arg string) (username string, pk string, err error) {

func init() {
rootCmd.Flags().StringVarP(&rpcAddr, "rpc", "", ":2222", "RPC address to connect to")
rootCmd.Flags().BoolVarP(&ptyMode, "pty", "", false, "Whether to run the command in a simulated PTY or not")
rootCmd.Flags().Uint16VarP(&ptyRows, "ptyrows", "", 100, "PTY Rows. Applicable if run with pty flag")
rootCmd.Flags().Uint16VarP(&ptyCols, "ptycols", "", 100, "PTY Cols. Applicable if run with pty flag")
rootCmd.Flags().Uint16VarP(&ptyX, "ptyx", "", 100, "PTY X. Applicable if run with pty flag")
rootCmd.Flags().Uint16VarP(&ptyY, "ptyy", "", 100, "PTY Y. Applicable if run with pty flag")
rootCmd.Flags().Uint32VarP(&ptyBufferSize, "ptybuffer", "", 1024, "PTY Buffer size to store command output")
}

// Execute executes root CLI command.
Expand Down
43 changes: 1 addition & 42 deletions pkg/therealssh/pty_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// +build dragonfly freebsd linux netbsd openbsd
// +build !no_ci

package therealssh

Expand All @@ -16,47 +16,6 @@ import (
"github.com/skycoin/skywire/pkg/routing"
)

/* func TestRunInPTY(t *testing.T) {
dialConn, acceptConn := net.Pipe()
pd := PipeDialer{PipeWithRoutingAddr{dialConn}, acceptConn}
_, client, err := NewClient(":9999", pd)
require.NoError(t, err)
server := NewServer(MockAuthorizer{})
go func() {
server.Serve(PipeWithRoutingAddr{acceptConn}) // nolint
}()
_, ch, err := client.OpenChannel(cipher.PubKey{})
require.NoError(t, err)
cuser, err := user.Current()
require.NoError(t, err)
args := RequestPTYArgs{
Username: cuser.Username,
RemotePK: cipher.PubKey{},
Size: &pty.Winsize{
Rows: 100,
Cols: 100,
X: 100,
Y: 100,
},
}
_, err = ch.Request(RequestPTY, args.ToBinary())
require.NoError(t, err)
_, err = ch.Request(RequestExecWithoutShell, []byte("ls"))
require.NoError(t, err)
b := make([]byte, 6024)
_, err = ch.Read(b)
require.NoError(t, err)
require.Contains(t, string(b), "pty_test.go")
}
*/

func TestRunRPC(t *testing.T) {
dialConn, acceptConn := net.Pipe()
pd := PipeDialer{PipeWithRoutingAddr{dialConn}, acceptConn}
Expand Down

0 comments on commit aa0538b

Please sign in to comment.