Converted xsnet Read() ctrlStatOp logic to switch

This commit is contained in:
Russ Magee 2022-09-25 11:33:09 -07:00
parent 667328a91c
commit b2e43f4bad
1 changed files with 28 additions and 13 deletions

View File

@ -1195,6 +1195,7 @@ func (hc Conn) Read(b []byte) (n int, err error) {
var hmacIn [HMAC_CHK_SZ]uint8
var payloadLen uint32
//------------- Read ctrl/status opcode --------------------
// Read ctrl/status opcode (CSOHmacInvalid on hmac mismatch)
err = binary.Read(*hc.c, binary.BigEndian, &ctrlStatOp)
if err != nil {
@ -1215,7 +1216,9 @@ func (hc Conn) Read(b []byte) (n int, err error) {
hc.Close()
return 0, errors.New("** ALERT - remote end detected HMAC mismatch - possible channel tampering **")
}
//----------------------------------------------------------
//------------------ Read HMAC len ------------------------
// Read the hmac and payload len first
err = binary.Read(*hc.c, binary.BigEndian, &hmacIn)
if err != nil {
@ -1230,7 +1233,9 @@ func (hc Conn) Read(b []byte) (n int, err error) {
logger.LogDebug(etxt)
return 0, errors.New(etxt)
}
//----------------------------------------------------------
//------------------ Read Payload len ---------------------
err = binary.Read(*hc.c, binary.BigEndian, &payloadLen)
if err != nil {
if err.Error() == "EOF" {
@ -1244,6 +1249,7 @@ func (hc Conn) Read(b []byte) (n int, err error) {
logger.LogDebug(etxt)
return 0, errors.New(etxt)
}
//----------------------------------------------------------
if payloadLen > MAX_PAYLOAD_LEN {
logger.LogDebug(fmt.Sprintf("[Insane payloadLen:%v]\n", payloadLen))
@ -1251,6 +1257,7 @@ func (hc Conn) Read(b []byte) (n int, err error) {
return 1, errors.New("Insane payloadLen")
}
//-------------------- Read Payload ------------------------
var payloadBytes = make([]byte, payloadLen)
n, err = io.ReadFull(*hc.c, payloadBytes)
if err != nil {
@ -1265,12 +1272,14 @@ func (hc Conn) Read(b []byte) (n int, err error) {
logger.LogDebug(etxt)
return 0, errors.New(etxt)
}
//----------------------------------------------------------
if hc.logCipherText {
log.Printf(" <:ctext:\r\n%s\r\n", hex.Dump(payloadBytes[:n]))
}
//fmt.Printf(" <:ctext:\r\n%s\r\n", hex.Dump(payloadBytes[:n]))
//---------------- Verify Payload via HMAC -----------------
hc.rm.Write(payloadBytes) // Calc hmac on received data
hTmp := hc.rm.Sum(nil)[0:HMAC_CHK_SZ]
//log.Printf("<%04x) HMAC:(i)%s (c)%02x\r\n", decryptN, hex.EncodeToString([]byte(hmacIn[0:])), hTmp)
@ -1280,7 +1289,9 @@ func (hc Conn) Read(b []byte) (n int, err error) {
logger.LogDebug(fmt.Sprintln("** ALERT - detected HMAC mismatch, possible channel tampering **"))
_, _ = (*hc.c).Write([]byte{CSOHmacInvalid})
}
//----------------------------------------------------------
//------------------- Decrypt Payload ----------------------
db := bytes.NewBuffer(payloadBytes[:n]) //copying payloadBytes to db
// The StreamReader acts like a pipe, decrypting
// whatever is available and forwarding the result
@ -1289,6 +1300,7 @@ func (hc Conn) Read(b []byte) (n int, err error) {
// The caller isn't necessarily reading the full payload so we need
// to decrypt to an intermediate buffer, draining it on demand of caller
decryptN, err := rs.Read(payloadBytes)
//----------------------------------------------------------
if hc.logPlainText {
log.Printf(" <:ptext:\r\n%s\r\n", hex.Dump(payloadBytes[:n]))
@ -1297,6 +1309,7 @@ func (hc Conn) Read(b []byte) (n int, err error) {
log.Println("xsnet.Read():", err)
//panic(err)
} else {
//------------ Discard Padding ---------------------
// Padding: Read padSide, padLen, (padding | d) or (d | padding)
padSide := payloadBytes[0]
padLen := payloadBytes[1]
@ -1307,15 +1320,17 @@ func (hc Conn) Read(b []byte) (n int, err error) {
} else {
payloadBytes = payloadBytes[0 : len(payloadBytes)-int(padLen)]
}
//--------------------------------------------------
// Throw away pkt if it's chaff (ie., caller to Read() won't see this data)
if ctrlStatOp == CSOChaff {
switch ctrlStatOp {
case CSOChaff:
// Throw away pkt if it's chaff (ie., caller to Read() won't see this data)
log.Printf("[Chaff pkt, discarded (len %d)]\n", decryptN)
} else if ctrlStatOp == CSOTermSize {
case CSOTermSize:
fmt.Sscanf(string(payloadBytes), "%d %d", &hc.Rows, &hc.Cols)
log.Printf("[TermSize pkt: rows %v cols %v]\n", hc.Rows, hc.Cols)
hc.WinCh <- WinSize{hc.Rows, hc.Cols}
} else if ctrlStatOp == CSOExitStatus {
case CSOExitStatus:
if len(payloadBytes) > 0 {
hc.SetStatus(CSOType(binary.BigEndian.Uint32(payloadBytes)))
} else {
@ -1323,7 +1338,7 @@ func (hc Conn) Read(b []byte) (n int, err error) {
hc.SetStatus(CSETruncCSO)
}
hc.Close()
} else if ctrlStatOp == CSOTunSetup {
case CSOTunSetup:
// server side tunnel setup in response to client
lport := binary.BigEndian.Uint16(payloadBytes[0:2])
rport := binary.BigEndian.Uint16(payloadBytes[2:4])
@ -1335,7 +1350,7 @@ func (hc Conn) Read(b []byte) (n int, err error) {
logger.LogDebug(fmt.Sprintf("[Server] Got CSOTunSetup [%d:%d]", lport, rport))
}
(*hc.tuns)[rport].Ctl <- 'd' // Dial() rport
} else if ctrlStatOp == CSOTunSetupAck {
case CSOTunSetupAck:
lport := binary.BigEndian.Uint16(payloadBytes[0:2])
rport := binary.BigEndian.Uint16(payloadBytes[2:4])
if _, ok := (*hc.tuns)[rport]; !ok {
@ -1346,7 +1361,7 @@ func (hc Conn) Read(b []byte) (n int, err error) {
logger.LogDebug(fmt.Sprintf("[Client] Got CSOTunSetupAck [%d:%d]", lport, rport))
}
(*hc.tuns)[rport].Ctl <- 'a' // Listen() for lport connection
} else if ctrlStatOp == CSOTunRefused {
case CSOTunRefused:
// client side receiving CSOTunRefused means the remote side
// could not dial() rport. So we cannot yet listen()
// for client-side on lport.
@ -1358,7 +1373,7 @@ func (hc Conn) Read(b []byte) (n int, err error) {
} else {
logger.LogDebug(fmt.Sprintf("[Client] CSOTunRefused on already-closed tun [%d:%d]", lport, rport))
}
} else if ctrlStatOp == CSOTunDisconn {
case CSOTunDisconn:
// server side's rport has disconnected (server lost)
lport := binary.BigEndian.Uint16(payloadBytes[0:2])
rport := binary.BigEndian.Uint16(payloadBytes[2:4])
@ -1368,7 +1383,7 @@ func (hc Conn) Read(b []byte) (n int, err error) {
} else {
logger.LogDebug(fmt.Sprintf("[Client] CSOTunDisconn on already-closed tun [%d:%d]", lport, rport))
}
} else if ctrlStatOp == CSOTunHangup {
case CSOTunHangup:
// client side's lport has hung up
lport := binary.BigEndian.Uint16(payloadBytes[0:2])
rport := binary.BigEndian.Uint16(payloadBytes[2:4])
@ -1378,7 +1393,7 @@ func (hc Conn) Read(b []byte) (n int, err error) {
} else {
logger.LogDebug(fmt.Sprintf("[Server] CSOTunHangup to already-closed tun [%d:%d]", lport, rport))
}
} else if ctrlStatOp == CSOTunData {
case CSOTunData:
lport := binary.BigEndian.Uint16(payloadBytes[0:2])
rport := binary.BigEndian.Uint16(payloadBytes[2:4])
//fmt.Printf("[Got CSOTunData: [lport %d:rport %d] data:%v\n", lport, rport, payloadBytes[4:])
@ -1391,7 +1406,7 @@ func (hc Conn) Read(b []byte) (n int, err error) {
} else {
logger.LogDebug(fmt.Sprintf("[Attempt to write data to closed tun [%d:%d]", lport, rport))
}
} else if ctrlStatOp == CSOTunKeepAlive {
case CSOTunKeepAlive:
// client side has sent keepalive for tunnels -- if client
// dies or exits unexpectedly the absence of this will
// let the server know to hang up on Dial()ed server rports.
@ -1402,9 +1417,9 @@ func (hc Conn) Read(b []byte) (n int, err error) {
t.KeepAlive = 0
hc.Unlock()
}
} else if ctrlStatOp == CSONone {
case CSONone:
hc.dBuf.Write(payloadBytes)
} else {
default:
logger.LogDebug(fmt.Sprintf("[Unknown CSOType:%d]", ctrlStatOp))
}
}