Skip to content

Commit 26b640e

Browse files
committed
fix: improve the compatibility of XShell
1 parent cfadd70 commit 26b640e

File tree

2 files changed

+39
-10
lines changed

2 files changed

+39
-10
lines changed

app/xshell.go

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package app
22

33
import (
4+
"bytes"
45
"context"
56
"encoding/binary"
67
"fmt"
@@ -46,7 +47,7 @@ func (s *XShell) Run(ctx context.Context, handler func(conn io.ReadWriteCloser))
4647
}
4748
wg.Add(1)
4849
go func(c io.ReadWriteCloser) {
49-
w := &xshellProxy{c, nil}
50+
w := &xshellProxy{conn: c}
5051
handler(w)
5152
wg.Done()
5253
}(conn)
@@ -110,19 +111,26 @@ func xshellHandshake(conn net.Conn, cookie string) error {
110111
var repMsg initAgentRepMsg
111112
repMsg.Flag = initMsg.Flag
112113
rep := ssh.Marshal(&repMsg)
113-
binary.BigEndian.PutUint32(length[:], uint32(len(rep)))
114-
if _, err := conn.Write(length[:]); err != nil {
114+
buf := bytes.NewBuffer(nil)
115+
err := binary.Write(buf, binary.BigEndian, uint32(len(rep)))
116+
if err != nil {
117+
return err
118+
}
119+
_, err = buf.Write(rep)
120+
if err != nil {
115121
return err
116122
}
117-
if _, err := conn.Write(rep); err != nil {
123+
if _, err := conn.Write(buf.Bytes()); err != nil {
118124
return err
119125
}
120126
return nil
121127
}
122128

123129
type xshellProxy struct {
124-
conn io.ReadWriteCloser
125-
buf []byte
130+
conn io.ReadWriteCloser
131+
buf []byte
132+
wlength int
133+
wbuf []byte
126134
}
127135

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

170178
func (s *xshellProxy) Write(p []byte) (n int, err error) {
171-
return s.conn.Write(p)
179+
// xshell treats TCP as a message-oriented connection
180+
// this piece of sh*t code is in order to be compatible with xshell
181+
if s.wlength == 0 {
182+
if len(p) != 4 {
183+
return 0, fmt.Errorf("xagent proxy: invalid write status")
184+
}
185+
s.wlength = int(binary.BigEndian.Uint32(p)) + 4
186+
s.wbuf = append(s.wbuf, p...)
187+
} else {
188+
s.wbuf = append(s.wbuf, p...)
189+
if len(s.wbuf) == s.wlength {
190+
s.wlength = 0
191+
_, err := s.conn.Write(s.wbuf)
192+
if err != nil {
193+
return 0, err
194+
}
195+
s.wbuf = nil
196+
} else if len(s.wbuf) > s.wlength {
197+
return 0, fmt.Errorf("xagent proxy: invalid write length")
198+
}
199+
}
200+
return len(p), nil
172201
}
173202

174203
func (s *xshellProxy) Close() error {

versioninfo.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
"FileVersion": {
44
"Major": 1,
55
"Minor": 1,
6-
"Patch": 7,
6+
"Patch": 8,
77
"Build": 0
88
},
99
"ProductVersion": {
1010
"Major": 1,
1111
"Minor": 1,
12-
"Patch": 7,
12+
"Patch": 8,
1313
"Build": 0
1414
},
1515
"FileFlagsMask": "3f",
@@ -29,7 +29,7 @@
2929
"OriginalFilename": "WinCryptSSHAgent.exe",
3030
"PrivateBuild": "",
3131
"ProductName": "WinCrypt SSH Agent",
32-
"ProductVersion": "v1.1.7",
32+
"ProductVersion": "v1.1.8",
3333
"SpecialBuild": ""
3434
},
3535
"VarFileInfo": {

0 commit comments

Comments
 (0)