handle remote input (can enter password manually now)

This commit is contained in:
sawka 2022-09-15 17:09:04 -07:00
parent fcc1737fc4
commit f2e0f9457d
4 changed files with 62 additions and 6 deletions

View File

@ -565,7 +565,6 @@ func RemoteShowCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (s
return sstore.ModelUpdate{
Info: &sstore.InfoMsgType{
InfoTitle: fmt.Sprintf("show remote [%s] info", ids.Remote.DisplayName),
InfoLines: splitLinesForInfo(buf.String()),
PtyRemoteId: state.RemoteId,
},
}, nil

View File

@ -23,6 +23,7 @@ import (
"github.com/scripthaus-dev/mshell/pkg/base"
"github.com/scripthaus-dev/mshell/pkg/packet"
"github.com/scripthaus-dev/mshell/pkg/shexec"
"github.com/scripthaus-dev/sh2-server/pkg/scpacket"
"github.com/scripthaus-dev/sh2-server/pkg/sstore"
)
@ -30,7 +31,7 @@ const RemoteTypeMShell = "mshell"
const DefaultTerm = "xterm-256color"
const DefaultMaxPtySize = 1024 * 1024
const CircBufSize = 64 * 1024
const RemoteTermRows = 10
const RemoteTermRows = 8
const RemoteTermCols = 80
const PtyReadBufSize = 100
@ -440,6 +441,29 @@ func MakeMShell(r *sstore.RemoteType) *MShellProc {
return rtn
}
func SendRemoteInput(pk *scpacket.RemoteInputPacketType) error {
data, err := base64.StdEncoding.DecodeString(pk.InputData64)
if err != nil {
return fmt.Errorf("cannot decode base64: %v\n", err)
}
msh := GetRemoteById(pk.RemoteId)
if msh == nil {
return fmt.Errorf("remote not found")
}
var cmdPty *os.File
msh.WithLock(func() {
cmdPty = msh.ControllingPty
})
if cmdPty == nil {
return fmt.Errorf("remote has no attached pty")
}
_, err = cmdPty.Write(data)
if err != nil {
return fmt.Errorf("writing to pty: %v", err)
}
return nil
}
func convertSSHOpts(opts *sstore.SSHOpts) shexec.SSHOpts {
if opts == nil || opts.Local {
opts = &sstore.SSHOpts{}
@ -521,9 +545,9 @@ func (msh *MShellProc) writeToPtyBuffer_nolock(strFmt string, args ...interface{
realStr = realStr + "\r\n"
}
if strings.HasPrefix(realStr, "*") {
realStr = "\033[0m\033[31m[scripthaus]\033[0m " + realStr[1:]
realStr = "\033[0m\033[31mscripthaus>\033[0m " + realStr[1:]
} else {
realStr = "\033[0m\033[32m[scripthaus]\033[0m " + realStr
realStr = "\033[0m\033[32mscripthaus>\033[0m " + realStr
}
barr := msh.PtyBuffer.Bytes()
if len(barr) > 0 && barr[len(barr)-1] != '\n' {
@ -592,6 +616,8 @@ func (msh *MShellProc) Launch() {
}()
if remoteName == "test2" {
go func() {
return
time.Sleep(2 * time.Second)
cmdPty.Write([]byte(Test2Pw))
msh.WriteToPtyBuffer("~[password sent]\r\n")

View File

@ -11,6 +11,7 @@ import (
const FeCommandPacketStr = "fecmd"
const WatchScreenPacketStr = "watchscreen"
const FeInputPacketStr = "feinput"
const RemoteInputPacketStr = "remoteinput"
type FeCommandPacketType struct {
Type string `json:"type"`
@ -39,6 +40,12 @@ type FeInputPacketType struct {
WinSize *packet.WinSize `json:"winsize,omitempty"`
}
type RemoteInputPacketType struct {
Type string `json:"type"`
RemoteId string `json:"remoteid"`
InputData64 string `json:"inputdata64"`
}
type WatchScreenPacketType struct {
Type string `json:"type"`
SessionId string `json:"sessionid"`
@ -50,6 +57,7 @@ func init() {
packet.RegisterPacketType(FeCommandPacketStr, reflect.TypeOf(FeCommandPacketType{}))
packet.RegisterPacketType(WatchScreenPacketStr, reflect.TypeOf(WatchScreenPacketType{}))
packet.RegisterPacketType(FeInputPacketStr, reflect.TypeOf(FeInputPacketType{}))
packet.RegisterPacketType(RemoteInputPacketStr, reflect.TypeOf(RemoteInputPacketType{}))
}
func (*FeCommandPacketType) GetType() string {
@ -75,3 +83,11 @@ func (*WatchScreenPacketType) GetType() string {
func MakeWatchScreenPacket() *WatchScreenPacketType {
return &WatchScreenPacketType{Type: WatchScreenPacketStr}
}
func MakeRemoteInputPacket() *RemoteInputPacketType {
return &RemoteInputPacketType{Type: RemoteInputPacketStr}
}
func (*RemoteInputPacketType) GetType() string {
return RemoteInputPacketStr
}

View File

@ -178,7 +178,7 @@ func (ws *WSState) RunWSRead() {
fmt.Printf("error unmarshalling ws message: %v\n", err)
continue
}
if pk.GetType() == "feinput" {
if pk.GetType() == scpacket.FeInputPacketStr {
feInputPk := pk.(*scpacket.FeInputPacketType)
if feInputPk.Remote.OwnerId != "" {
fmt.Printf("[error] cannot send input to remote with ownerid\n")
@ -189,6 +189,7 @@ func (ws *WSState) RunWSRead() {
continue
}
go func() {
// TODO enforce a strong ordering (channel with list)
err = sendCmdInput(feInputPk)
if err != nil {
fmt.Printf("[error] sending command input: %v\n", err)
@ -196,7 +197,7 @@ func (ws *WSState) RunWSRead() {
}()
continue
}
if pk.GetType() == "watchscreen" {
if pk.GetType() == scpacket.WatchScreenPacketStr {
wsPk := pk.(*scpacket.WatchScreenPacketType)
err := ws.handleWatchScreen(wsPk)
if err != nil {
@ -205,6 +206,20 @@ func (ws *WSState) RunWSRead() {
}
continue
}
if pk.GetType() == scpacket.RemoteInputPacketStr {
inputPk := pk.(*scpacket.RemoteInputPacketType)
if inputPk.RemoteId == "" {
fmt.Printf("[error] invalid remoteinput packet, remoteid is not set\n")
continue
}
go func() {
err = remote.SendRemoteInput(inputPk)
if err != nil {
fmt.Printf("[error] processing remote input: %v\n", err)
}
}()
continue
}
fmt.Printf("got ws bad message: %v\n", pk.GetType())
}
}