Length calc but not xmit -- grouped Read() likely the issue to handle

This commit is contained in:
Russ Magee 2018-02-16 22:12:27 -08:00
parent 744730ae23
commit e14ccbe366

View file

@ -27,6 +27,7 @@ import (
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"hash" "hash"
"io"
"log" "log"
"math/big" "math/big"
"net" "net"
@ -41,7 +42,6 @@ type Conn struct {
c net.Conn // which also implements io.Reader, io.Writer, ... c net.Conn // which also implements io.Reader, io.Writer, ...
h *HerraduraKEx h *HerraduraKEx
hmacOn bool // turned on once channel param negotiation is done hmacOn bool // turned on once channel param negotiation is done
byteCount int
cipheropts uint32 // post-KEx cipher/hmac options cipheropts uint32 // post-KEx cipher/hmac options
opts uint32 // post-KEx protocol options (caller-defined) opts uint32 // post-KEx protocol options (caller-defined)
r cipher.Stream //read cipherStream r cipher.Stream //read cipherStream
@ -296,8 +296,16 @@ func (hl HKExListener) Accept() (hc Conn, err error) {
// See go doc io.Reader // See go doc io.Reader
func (c Conn) Read(b []byte) (n int, err error) { func (c Conn) Read(b []byte) (n int, err error) {
//log.Printf("[Decrypting...]\r\n") //log.Printf("[Decrypting...]\r\n")
var hIn []byte = make([]byte, 1, 1)
if c.hmacOn {
_, _ = io.ReadFull(c.c, hIn)
//if e != nil {
// panic(e)
//}
}
n, err = c.c.Read(b) n, err = c.c.Read(b)
// Normal client 'exit' from interactive session will cause // Normal client 'exit' from interactive session will cause
// (on server side) err.Error() == "<iface/addr info ...>: use of closed network connection" // (on server side) err.Error() == "<iface/addr info ...>: use of closed network connection"
if err != nil && err.Error() != "EOF" { if err != nil && err.Error() != "EOF" {
@ -307,6 +315,7 @@ func (c Conn) Read(b []byte) (n int, err error) {
log.Println("[Client hung up]") log.Println("[Client hung up]")
} }
} }
log.Printf(" <:ctext:\r\n%s\r\n", hex.Dump(b[:n])) //EncodeToString(b[:n])) // print only used portion log.Printf(" <:ctext:\r\n%s\r\n", hex.Dump(b[:n])) //EncodeToString(b[:n])) // print only used portion
db := bytes.NewBuffer(b[:n]) db := bytes.NewBuffer(b[:n])
@ -314,13 +323,15 @@ func (c Conn) Read(b []byte) (n int, err error) {
// whatever is available and forwarding the result // whatever is available and forwarding the result
// to the parameter of Read() as a normal io.Reader // to the parameter of Read() as a normal io.Reader
rs := &cipher.StreamReader{S: c.r, R: db} rs := &cipher.StreamReader{S: c.r, R: db}
// FIXME: Possibly the bug here -- Read() may get grouped writes from
// server side, causing loss of hmac sync. -rlm 2018-0-16
n, err = rs.Read(b) n, err = rs.Read(b)
log.Printf(" <-ptext:\r\n%s\r\n", hex.Dump(b[:n])) //EncodeToString(b[:n])) log.Printf(" <-ptext:\r\n%s\r\n", hex.Dump(b[:n])) //EncodeToString(b[:n]))
if c.hmacOn { if c.hmacOn {
c.rm.Write(b[:n]) c.rm.Write(b[:n])
c.byteCount += len(b[:n]) hTmp := c.rm.Sum(nil)[0]
fmt.Printf("(%x) HMAC:%x\r\n", c.byteCount, c.rm.Sum(nil)) fmt.Printf("<%04x) HMAC:(i)%x (c)%x\r\n", len(b[:n]), hIn, hTmp)
} }
return return
@ -331,12 +342,22 @@ 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) {
//log.Printf("[Encrypting...]\r\n") //log.Printf("[Encrypting...]\r\n")
//var pLen uint32
var hTmp = make([]byte, 1, 1)
log.Printf(" :>ptext:\r\n%s\r\n", hex.Dump(b)) //EncodeToString(b)) log.Printf(" :>ptext:\r\n%s\r\n", hex.Dump(b)) //EncodeToString(b))
if c.hmacOn { if c.hmacOn {
//pLen = uint32(len(b))
//_ = binary.Write(c.c, binary.BigEndian, &pLen)
c.wm.Write(b) c.wm.Write(b)
c.byteCount += len(b) hTmp[0] = c.wm.Sum(nil)[0]
fmt.Printf("(%x) HMAC:%x\r\n", c.byteCount, c.wm.Sum(nil)) _, e := c.c.Write(hTmp)
if e != nil {
panic(e)
}
fmt.Printf(" (%04x> HMAC(o):%x\r\n", len(b) /*pLen*/, hTmp)
} }
var wb bytes.Buffer var wb bytes.Buffer
@ -348,6 +369,10 @@ func (c Conn) Write(b []byte) (n int, err error) {
panic(err) panic(err)
} }
log.Printf(" ->ctext:\r\n%s\r\n", hex.Dump(wb.Bytes())) //EncodeToString(b)) // print only used portion log.Printf(" ->ctext:\r\n%s\r\n", hex.Dump(wb.Bytes())) //EncodeToString(b)) // print only used portion
n, err = c.c.Write(wb.Bytes()) n, err = c.c.Write(wb.Bytes())
if err != nil {
panic(err)
}
return return
} }