Skip to content

Commit

Permalink
fix: improve the compatibility of XShell
Browse files Browse the repository at this point in the history
  • Loading branch information
buptczq committed Mar 25, 2021
1 parent cfadd70 commit 26b640e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 10 deletions.
43 changes: 36 additions & 7 deletions app/xshell.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app

import (
"bytes"
"context"
"encoding/binary"
"fmt"
Expand Down Expand Up @@ -46,7 +47,7 @@ func (s *XShell) Run(ctx context.Context, handler func(conn io.ReadWriteCloser))
}
wg.Add(1)
go func(c io.ReadWriteCloser) {
w := &xshellProxy{c, nil}
w := &xshellProxy{conn: c}
handler(w)
wg.Done()
}(conn)
Expand Down Expand Up @@ -110,19 +111,26 @@ func xshellHandshake(conn net.Conn, cookie string) error {
var repMsg initAgentRepMsg
repMsg.Flag = initMsg.Flag
rep := ssh.Marshal(&repMsg)
binary.BigEndian.PutUint32(length[:], uint32(len(rep)))
if _, err := conn.Write(length[:]); err != nil {
buf := bytes.NewBuffer(nil)
err := binary.Write(buf, binary.BigEndian, uint32(len(rep)))
if err != nil {
return err
}
_, err = buf.Write(rep)
if err != nil {
return err
}
if _, err := conn.Write(rep); err != nil {
if _, err := conn.Write(buf.Bytes()); err != nil {
return err
}
return nil
}

type xshellProxy struct {
conn io.ReadWriteCloser
buf []byte
conn io.ReadWriteCloser
buf []byte
wlength int
wbuf []byte
}

type signRequestAgentMsg struct {
Expand Down Expand Up @@ -168,7 +176,28 @@ func (s *xshellProxy) Read(p []byte) (n int, err error) {
}

func (s *xshellProxy) Write(p []byte) (n int, err error) {
return s.conn.Write(p)
// xshell treats TCP as a message-oriented connection
// this piece of sh*t code is in order to be compatible with xshell
if s.wlength == 0 {
if len(p) != 4 {
return 0, fmt.Errorf("xagent proxy: invalid write status")
}
s.wlength = int(binary.BigEndian.Uint32(p)) + 4
s.wbuf = append(s.wbuf, p...)
} else {
s.wbuf = append(s.wbuf, p...)
if len(s.wbuf) == s.wlength {
s.wlength = 0
_, err := s.conn.Write(s.wbuf)
if err != nil {
return 0, err
}
s.wbuf = nil
} else if len(s.wbuf) > s.wlength {
return 0, fmt.Errorf("xagent proxy: invalid write length")
}
}
return len(p), nil
}

func (s *xshellProxy) Close() error {
Expand Down
6 changes: 3 additions & 3 deletions versioninfo.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
"FileVersion": {
"Major": 1,
"Minor": 1,
"Patch": 7,
"Patch": 8,
"Build": 0
},
"ProductVersion": {
"Major": 1,
"Minor": 1,
"Patch": 7,
"Patch": 8,
"Build": 0
},
"FileFlagsMask": "3f",
Expand All @@ -29,7 +29,7 @@
"OriginalFilename": "WinCryptSSHAgent.exe",
"PrivateBuild": "",
"ProductName": "WinCrypt SSH Agent",
"ProductVersion": "v1.1.7",
"ProductVersion": "v1.1.8",
"SpecialBuild": ""
},
"VarFileInfo": {
Expand Down

0 comments on commit 26b640e

Please sign in to comment.