mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-02-09 00:31:26 +01:00
support sending password to remote
This commit is contained in:
parent
23759b7283
commit
3beb00998b
@ -378,11 +378,11 @@ func main() {
|
|||||||
fmt.Printf("[error] ensuring test01 remote: %v\n", err)
|
fmt.Printf("[error] ensuring test01 remote: %v\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = sstore.AddTest02Remote(context.Background())
|
//err = sstore.AddTest02Remote(context.Background())
|
||||||
if err != nil {
|
//if err != nil {
|
||||||
fmt.Printf("[error] ensuring test02 remote: %v\n", err)
|
// fmt.Printf("[error] ensuring test02 remote: %v\n", err)
|
||||||
return
|
// return
|
||||||
}
|
//}
|
||||||
_, err = sstore.EnsureDefaultSession(context.Background())
|
_, err = sstore.EnsureDefaultSession(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("[error] ensuring default session: %v\n", err)
|
fmt.Printf("[error] ensuring default session: %v\n", err)
|
||||||
|
@ -593,6 +593,9 @@ func RemoteNewCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (ss
|
|||||||
}
|
}
|
||||||
remoteOpts.Color = color
|
remoteOpts.Color = color
|
||||||
}
|
}
|
||||||
|
if pk.Kwargs["password"] != "" {
|
||||||
|
sshOpts.SSHPassword = pk.Kwargs["password"]
|
||||||
|
}
|
||||||
r := &sstore.RemoteType{
|
r := &sstore.RemoteType{
|
||||||
RemoteId: scbase.GenSCUUID(),
|
RemoteId: scbase.GenSCUUID(),
|
||||||
PhysicalId: "",
|
PhysicalId: "",
|
||||||
@ -737,12 +740,15 @@ func CrCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.Up
|
|||||||
if newRemote == "" {
|
if newRemote == "" {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
remoteName, rptr, _, _, err := resolveRemote(ctx, newRemote, ids.SessionId, ids.WindowId)
|
remoteName, rptr, _, rstate, err := resolveRemote(ctx, newRemote, ids.SessionId, ids.WindowId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if rptr == nil {
|
if rptr == nil {
|
||||||
return nil, fmt.Errorf("/cr error: remote [%s] not found", newRemote)
|
return nil, fmt.Errorf("/cr error: remote %q not found", newRemote)
|
||||||
|
}
|
||||||
|
if rstate.Archived {
|
||||||
|
return nil, fmt.Errorf("/cr error: remote %q cannot switch to archived remote", newRemote)
|
||||||
}
|
}
|
||||||
err = sstore.UpdateCurRemote(ctx, ids.SessionId, ids.WindowId, *rptr)
|
err = sstore.UpdateCurRemote(ctx, ids.SessionId, ids.WindowId, *rptr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -755,7 +761,7 @@ func CrCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.Up
|
|||||||
CurRemote: *rptr,
|
CurRemote: *rptr,
|
||||||
},
|
},
|
||||||
Info: &sstore.InfoMsgType{
|
Info: &sstore.InfoMsgType{
|
||||||
InfoMsg: fmt.Sprintf("current remote = %s", remoteName),
|
InfoMsg: fmt.Sprintf("current remote = %q", remoteName),
|
||||||
TimeoutMs: 2000,
|
TimeoutMs: 2000,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/armon/circbuf"
|
"github.com/armon/circbuf"
|
||||||
"github.com/creack/pty"
|
"github.com/creack/pty"
|
||||||
@ -111,10 +112,11 @@ type RemoteRuntimeState struct {
|
|||||||
DefaultState *sstore.RemoteState `json:"defaultstate"`
|
DefaultState *sstore.RemoteState `json:"defaultstate"`
|
||||||
ConnectMode string `json:"connectmode"`
|
ConnectMode string `json:"connectmode"`
|
||||||
AutoInstall bool `json:"autoinstall"`
|
AutoInstall bool `json:"autoinstall"`
|
||||||
Archived bool `json:"archived"`
|
Archived bool `json:"archived,omitempty"`
|
||||||
RemoteIdx int64 `json:"remoteidx"`
|
RemoteIdx int64 `json:"remoteidx"`
|
||||||
UName string `json:"uname"`
|
UName string `json:"uname"`
|
||||||
MShellVersion string `json:"mshellversion"`
|
MShellVersion string `json:"mshellversion"`
|
||||||
|
WaitingForPassword bool `json:"waitingforpassword,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state RemoteRuntimeState) IsConnected() bool {
|
func (state RemoteRuntimeState) IsConnected() bool {
|
||||||
@ -391,6 +393,9 @@ func (msh *MShellProc) GetRemoteRuntimeState() RemoteRuntimeState {
|
|||||||
if msh.InstallErr != nil {
|
if msh.InstallErr != nil {
|
||||||
state.InstallErrorStr = msh.InstallErr.Error()
|
state.InstallErrorStr = msh.InstallErr.Error()
|
||||||
}
|
}
|
||||||
|
if msh.Status == StatusConnecting {
|
||||||
|
state.WaitingForPassword = msh.isWaitingForPassword_nolock()
|
||||||
|
}
|
||||||
local := (msh.Remote.SSHOpts == nil || msh.Remote.SSHOpts.Local)
|
local := (msh.Remote.SSHOpts == nil || msh.Remote.SSHOpts.Local)
|
||||||
vars := make(map[string]string)
|
vars := make(map[string]string)
|
||||||
vars["user"] = msh.Remote.RemoteUser
|
vars["user"] = msh.Remote.RemoteUser
|
||||||
@ -659,8 +664,25 @@ func sendRemotePtyUpdate(remoteId string, dataOffset int64, data []byte) {
|
|||||||
sstore.MainBus.SendUpdate("", update)
|
sstore.MainBus.SendUpdate("", update)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (msh *MShellProc) isWaitingForPassword_nolock() bool {
|
||||||
|
barr := msh.PtyBuffer.Bytes()
|
||||||
|
if len(barr) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
nlIdx := bytes.LastIndex(barr, []byte{'\n'})
|
||||||
|
var lastLine string
|
||||||
|
if nlIdx == -1 {
|
||||||
|
lastLine = string(barr)
|
||||||
|
} else {
|
||||||
|
lastLine = string(barr[nlIdx+1:])
|
||||||
|
}
|
||||||
|
pwIdx := strings.Index(lastLine, "assword")
|
||||||
|
return pwIdx != -1
|
||||||
|
}
|
||||||
|
|
||||||
func (msh *MShellProc) RunPtyReadLoop(cmdPty *os.File) {
|
func (msh *MShellProc) RunPtyReadLoop(cmdPty *os.File) {
|
||||||
buf := make([]byte, PtyReadBufSize)
|
buf := make([]byte, PtyReadBufSize)
|
||||||
|
var isWaiting bool
|
||||||
for {
|
for {
|
||||||
n, readErr := cmdPty.Read(buf)
|
n, readErr := cmdPty.Read(buf)
|
||||||
if readErr == io.EOF {
|
if readErr == io.EOF {
|
||||||
@ -670,11 +692,55 @@ func (msh *MShellProc) RunPtyReadLoop(cmdPty *os.File) {
|
|||||||
msh.WriteToPtyBuffer("*error reading from controlling-pty: %v\n", readErr)
|
msh.WriteToPtyBuffer("*error reading from controlling-pty: %v\n", readErr)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
var newIsWaiting bool
|
||||||
msh.WithLock(func() {
|
msh.WithLock(func() {
|
||||||
curOffset := msh.PtyBuffer.TotalWritten()
|
curOffset := msh.PtyBuffer.TotalWritten()
|
||||||
msh.PtyBuffer.Write(buf[0:n])
|
msh.PtyBuffer.Write(buf[0:n])
|
||||||
sendRemotePtyUpdate(msh.Remote.RemoteId, curOffset, buf[0:n])
|
sendRemotePtyUpdate(msh.Remote.RemoteId, curOffset, buf[0:n])
|
||||||
|
newIsWaiting = msh.isWaitingForPassword_nolock()
|
||||||
})
|
})
|
||||||
|
if newIsWaiting != isWaiting {
|
||||||
|
isWaiting = newIsWaiting
|
||||||
|
go msh.NotifyRemoteUpdate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msh *MShellProc) WaitAndSendPassword(pw string) {
|
||||||
|
var numWaits int
|
||||||
|
for {
|
||||||
|
var isWaiting bool
|
||||||
|
var isConnecting bool
|
||||||
|
msh.WithLock(func() {
|
||||||
|
isWaiting = msh.isWaitingForPassword_nolock()
|
||||||
|
isConnecting = msh.Status == StatusConnecting
|
||||||
|
})
|
||||||
|
if !isConnecting {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if !isWaiting {
|
||||||
|
numWaits = 0
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
numWaits++
|
||||||
|
if numWaits < 10 {
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
} else {
|
||||||
|
// send password
|
||||||
|
msh.WithLock(func() {
|
||||||
|
if msh.ControllingPty == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pwBytes := []byte(pw + "\r")
|
||||||
|
msh.writeToPtyBuffer_nolock("~[sent password]\r\n")
|
||||||
|
_, err := msh.ControllingPty.Write(pwBytes)
|
||||||
|
if err != nil {
|
||||||
|
msh.writeToPtyBuffer_nolock("*cannot write password to controlling pty: %v\n", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -770,7 +836,7 @@ func (msh *MShellProc) Launch() {
|
|||||||
msh.WriteToPtyBuffer("connecting to %s...\n", remoteCopy.RemoteCanonicalName)
|
msh.WriteToPtyBuffer("connecting to %s...\n", remoteCopy.RemoteCanonicalName)
|
||||||
sshOpts := convertSSHOpts(remoteCopy.SSHOpts)
|
sshOpts := convertSSHOpts(remoteCopy.SSHOpts)
|
||||||
sshOpts.SSHErrorsToTty = true
|
sshOpts.SSHErrorsToTty = true
|
||||||
if remoteCopy.ConnectMode != sstore.ConnectModeManual {
|
if remoteCopy.ConnectMode != sstore.ConnectModeManual && remoteCopy.SSHOpts.SSHPassword == "" {
|
||||||
sshOpts.BatchMode = true
|
sshOpts.BatchMode = true
|
||||||
}
|
}
|
||||||
cmdStr := MakeServerCommandStr()
|
cmdStr := MakeServerCommandStr()
|
||||||
@ -788,6 +854,9 @@ func (msh *MShellProc) Launch() {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
go msh.RunPtyReadLoop(cmdPty)
|
go msh.RunPtyReadLoop(cmdPty)
|
||||||
|
if remoteCopy.SSHOpts.SSHPassword != "" {
|
||||||
|
go msh.WaitAndSendPassword(remoteCopy.SSHOpts.SSHPassword)
|
||||||
|
}
|
||||||
makeClientCtx, makeClientCancelFn := context.WithCancel(context.Background())
|
makeClientCtx, makeClientCancelFn := context.WithCancel(context.Background())
|
||||||
defer makeClientCancelFn()
|
defer makeClientCancelFn()
|
||||||
msh.WithLock(func() {
|
msh.WithLock(func() {
|
||||||
|
@ -476,6 +476,7 @@ type SSHOpts struct {
|
|||||||
SSHOptsStr string `json:"sshopts,omitempty"`
|
SSHOptsStr string `json:"sshopts,omitempty"`
|
||||||
SSHIdentity string `json:"sshidentity,omitempty"`
|
SSHIdentity string `json:"sshidentity,omitempty"`
|
||||||
SSHPort int `json:"sshport,omitempty"`
|
SSHPort int `json:"sshport,omitempty"`
|
||||||
|
SSHPassword string `json:"sshpassword,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RemoteOptsType struct {
|
type RemoteOptsType struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user