mirror of
https://gogs.blitter.com/RLabs/xs
synced 2024-08-14 10:26:42 +00:00
Chaff packets w/sync.Mutex to allow chaff & main goroutine to both input to server.
TODO: smart chaff, mutating or mimicking recent input.
This commit is contained in:
parent
8162707ffa
commit
b8a07e9648
3 changed files with 74 additions and 7 deletions
15
hkexnet.go
15
hkexnet.go
|
@ -391,7 +391,7 @@ func (c Conn) Read(b []byte) (n int, err error) {
|
||||||
|
|
||||||
// Throw away pkt if it's chaff (ie., caller to Read() won't see this data)
|
// Throw away pkt if it's chaff (ie., caller to Read() won't see this data)
|
||||||
if ctrlStatOp == CSOChaff {
|
if ctrlStatOp == CSOChaff {
|
||||||
log.Printf("[Chaff pkt]\n")
|
log.Printf("[Chaff pkt, discarded]\n")
|
||||||
} else if ctrlStatOp == CSOTermSize {
|
} else if ctrlStatOp == CSOTermSize {
|
||||||
fmt.Sscanf(string(payloadBytes), "%d %d", &c.Rows, &c.Cols)
|
fmt.Sscanf(string(payloadBytes), "%d %d", &c.Rows, &c.Cols)
|
||||||
log.Printf("[TermSize pkt: rows %v cols %v]\n", c.Rows, c.Cols)
|
log.Printf("[TermSize pkt: rows %v cols %v]\n", c.Rows, c.Cols)
|
||||||
|
@ -428,7 +428,8 @@ func (c Conn) Read(b []byte) (n int, err error) {
|
||||||
//
|
//
|
||||||
// See go doc io.Writer
|
// See go doc io.Writer
|
||||||
func (c Conn) Write(b []byte) (n int, err error) {
|
func (c Conn) Write(b []byte) (n int, err error) {
|
||||||
return c.WritePacket(b, CSONone)
|
n, err = c.WritePacket(b, CSONone)
|
||||||
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write a byte slice with specified ctrlStatusOp byte
|
// Write a byte slice with specified ctrlStatusOp byte
|
||||||
|
@ -441,6 +442,11 @@ func (c Conn) WritePacket(b []byte, op byte) (n int, err error) {
|
||||||
|
|
||||||
payloadLen = uint32(len(b))
|
payloadLen = uint32(len(b))
|
||||||
|
|
||||||
|
// Testing: '`1' will trigger a chaff packet
|
||||||
|
//if payloadLen == 2 && string(b) == "`1" {
|
||||||
|
// op = CSOChaff
|
||||||
|
//}
|
||||||
|
|
||||||
// Calculate hmac on payload
|
// Calculate hmac on payload
|
||||||
c.wm.Write(b)
|
c.wm.Write(b)
|
||||||
hmacOut = c.wm.Sum(nil)[0:4]
|
hmacOut = c.wm.Sum(nil)[0:4]
|
||||||
|
@ -458,13 +464,14 @@ func (c Conn) WritePacket(b []byte, op byte) (n int, err error) {
|
||||||
log.Printf(" ->ctext:\r\n%s\r\n", hex.Dump(wb.Bytes()))
|
log.Printf(" ->ctext:\r\n%s\r\n", hex.Dump(wb.Bytes()))
|
||||||
|
|
||||||
ctrlStatOp := op
|
ctrlStatOp := op
|
||||||
_ = binary.Write(c.c, binary.BigEndian, &ctrlStatOp)
|
|
||||||
|
|
||||||
|
//{
|
||||||
|
_ = binary.Write(c.c, binary.BigEndian, &ctrlStatOp)
|
||||||
// Write hmac LSB, payloadLen followed by payload
|
// Write hmac LSB, payloadLen followed by payload
|
||||||
_ = binary.Write(c.c, binary.BigEndian, hmacOut)
|
_ = binary.Write(c.c, binary.BigEndian, hmacOut)
|
||||||
_ = binary.Write(c.c, binary.BigEndian, payloadLen)
|
_ = binary.Write(c.c, binary.BigEndian, payloadLen)
|
||||||
|
|
||||||
n, err = c.c.Write(wb.Bytes())
|
n, err = c.c.Write(wb.Bytes())
|
||||||
|
//}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//panic(err)
|
//panic(err)
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
hkexsh "blitter.com/go/hkexsh"
|
hkexsh "blitter.com/go/hkexsh"
|
||||||
isatty "github.com/mattn/go-isatty"
|
isatty "github.com/mattn/go-isatty"
|
||||||
|
@ -192,6 +193,8 @@ func main() {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
m := &sync.Mutex{}
|
||||||
|
|
||||||
if isInteractive {
|
if isInteractive {
|
||||||
// Handle pty resizes (notify server side)
|
// Handle pty resizes (notify server side)
|
||||||
ch := make(chan os.Signal, 1)
|
ch := make(chan os.Signal, 1)
|
||||||
|
@ -209,11 +212,26 @@ func main() {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
termSzPacket := fmt.Sprintf("%d %d", rows, cols)
|
termSzPacket := fmt.Sprintf("%d %d", rows, cols)
|
||||||
|
m.Lock()
|
||||||
conn.WritePacket([]byte(termSzPacket), hkexsh.CSOTermSize)
|
conn.WritePacket([]byte(termSzPacket), hkexsh.CSOTermSize)
|
||||||
|
m.Unlock()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
ch <- syscall.SIGWINCH // Initial resize.
|
ch <- syscall.SIGWINCH // Initial resize.
|
||||||
|
|
||||||
|
// client chaffing goroutine
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
for {
|
||||||
|
m.Lock()
|
||||||
|
conn.WritePacket([]byte("CHAFF"), hkexsh.CSOChaff)
|
||||||
|
m.Unlock()
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
// client writer (to server) goroutine
|
// client writer (to server) goroutine
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -221,7 +239,11 @@ func main() {
|
||||||
|
|
||||||
// io.Copy() expects EOF so this will
|
// io.Copy() expects EOF so this will
|
||||||
// exit with outerr == nil
|
// exit with outerr == nil
|
||||||
_, outerr := io.Copy(conn, os.Stdin)
|
//!_, outerr := io.Copy(conn, os.Stdin)
|
||||||
|
_, outerr := func(m *sync.Mutex, conn *hkexsh.Conn, r io.Reader) (w int64, e error) {
|
||||||
|
return safeCopy(m, conn, r)
|
||||||
|
}(m, conn, os.Stdin)
|
||||||
|
|
||||||
if outerr != nil {
|
if outerr != nil {
|
||||||
log.Println(outerr)
|
log.Println(outerr)
|
||||||
if outerr.Error() != "EOF" {
|
if outerr.Error() != "EOF" {
|
||||||
|
@ -238,3 +260,43 @@ func main() {
|
||||||
// Wait until both stdin and stdout goroutines finish
|
// Wait until both stdin and stdout goroutines finish
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func safeCopy(m *sync.Mutex, dst io.Writer, src io.Reader) (written int64, err error) {
|
||||||
|
// // If the reader has a WriteTo method, use it to do the copy.
|
||||||
|
// // Avoids an allocation and a copy.
|
||||||
|
// if wt, ok := src.(io.WriterTo); ok {
|
||||||
|
// return wt.WriteTo(dst)
|
||||||
|
// }
|
||||||
|
// // Similarly, if the writer has a ReadFrom method, use it to do the copy.
|
||||||
|
// if rt, ok := dst.(io.ReaderFrom); ok {
|
||||||
|
// return rt.ReadFrom(src)
|
||||||
|
// }
|
||||||
|
|
||||||
|
buf := make([]byte, 32*1024)
|
||||||
|
for {
|
||||||
|
nr, er := src.Read(buf)
|
||||||
|
if nr > 0 {
|
||||||
|
m.Lock()
|
||||||
|
nw, ew := dst.Write(buf[0:nr])
|
||||||
|
m.Unlock()
|
||||||
|
if nw > 0 {
|
||||||
|
written += int64(nw)
|
||||||
|
}
|
||||||
|
if ew != nil {
|
||||||
|
err = ew
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if nr != nw {
|
||||||
|
err = io.ErrShortWrite
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if er != nil {
|
||||||
|
if er != io.EOF {
|
||||||
|
err = er
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return written, err
|
||||||
|
}
|
||||||
|
|
|
@ -28,8 +28,6 @@ type cmdSpec struct {
|
||||||
who []byte
|
who []byte
|
||||||
cmd []byte
|
cmd []byte
|
||||||
authCookie []byte
|
authCookie []byte
|
||||||
termRows []byte
|
|
||||||
termCols []byte
|
|
||||||
status int
|
status int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue