mirror of
https://gogs.blitter.com/RLabs/xs
synced 2024-08-14 10:26:42 +00:00
Added rekeying (-r secs) client/server
This commit is contained in:
parent
c569a5a3c9
commit
032baf63d6
6 changed files with 80 additions and 30 deletions
|
@ -57,9 +57,9 @@ func expandKeyMat(keymat []byte, blocksize int) []byte {
|
|||
return keymat
|
||||
}
|
||||
|
||||
/* Support functionality to set up encryption after a channel has
|
||||
been negotiated via xsnet.go
|
||||
*/
|
||||
/* (Re-)initialize the keystream and hmac state for an xsnet.Conn, returning
|
||||
a cipherStream and hash
|
||||
*/
|
||||
func (hc *Conn) getStream(keymat []byte) (rc cipher.Stream, mc hash.Hash, err error) {
|
||||
var key []byte
|
||||
var block cipher.Block
|
||||
|
|
|
@ -78,6 +78,7 @@ const (
|
|||
CSOTunDisconn // server -> client: tunnel rport disconnected
|
||||
CSOTunHangup // client -> server: tunnel lport hung up
|
||||
CSOKeepAlive // bidir keepalive packet to monitor main connection
|
||||
CSORekey // TODO: rekey/re-select session cipher/hash algs
|
||||
)
|
||||
|
||||
// TunEndpoint.tunCtl control values - used to control workers for client
|
||||
|
|
62
xsnet/net.go
62
xsnet/net.go
|
@ -88,6 +88,7 @@ type (
|
|||
Cols uint16
|
||||
|
||||
keepalive uint // if this reaches zero, conn is considered dead
|
||||
rekey uint // if nonzero, rekeying interval in seconds
|
||||
Pproc int // proc ID of command run on this conn
|
||||
chaff ChaffConfig
|
||||
tuns *map[uint16](*TunEndpoint)
|
||||
|
@ -1345,6 +1346,12 @@ func (hc *Conn) Read(b []byte) (n int, err error) {
|
|||
// payload of keepalive (2 bytes) is not currently used (0x55aa fixed)
|
||||
_ = binary.BigEndian.Uint16(payloadBytes[0:2])
|
||||
hc.ResetKeepAlive()
|
||||
case CSORekey:
|
||||
// rekey
|
||||
//logger.LogDebug(fmt.Sprintf("[Got rekey [%02x %02x %02x ...]\n",
|
||||
// payloadBytes[0], payloadBytes[1], payloadBytes[2]))
|
||||
rekeyData := payloadBytes
|
||||
hc.r, hc.rm, err = hc.getStream(rekeyData)
|
||||
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)
|
||||
|
@ -1461,13 +1468,18 @@ func (hc *Conn) Read(b []byte) (n int, err error) {
|
|||
// Write a byte slice
|
||||
//
|
||||
// See go doc io.Writer
|
||||
func (hc Conn) Write(b []byte) (n int, err error) {
|
||||
func (hc *Conn) Write(b []byte) (n int, err error) {
|
||||
//logger.LogDebug("[+Write]")
|
||||
n, err = hc.WritePacket(b, CSONone)
|
||||
//logger.LogDebug("[-Write]")
|
||||
return n, err
|
||||
}
|
||||
|
||||
// Write a byte slice with specified ctrlStatOp byte
|
||||
func (hc *Conn) WritePacket(b []byte, ctrlStatOp byte) (n int, err error) {
|
||||
hc.Lock()
|
||||
defer hc.Unlock()
|
||||
|
||||
//log.Printf("[Encrypting...]\r\n")
|
||||
var hmacOut []uint8
|
||||
var payloadLen uint32
|
||||
|
@ -1495,15 +1507,6 @@ func (hc *Conn) WritePacket(b []byte, ctrlStatOp byte) (n int, err error) {
|
|||
b = append([]byte{byte(padSide)}, append([]byte{byte(padLen)}, append(b, padBytes...)...)...)
|
||||
}
|
||||
|
||||
// N.B. Originally this Lock() surrounded only the
|
||||
// calls to binary.Write(hc.c ..) however there appears
|
||||
// to be some other unshareable state in the Conn
|
||||
// struct that must be protected to serialize main and
|
||||
// chaff data written to it.
|
||||
//
|
||||
// Would be nice to determine if the mutex scope
|
||||
// could be tightened.
|
||||
hc.Lock()
|
||||
payloadLen = uint32(len(b))
|
||||
if hc.logPlainText {
|
||||
log.Printf(" >:ptext:\r\n%s\r\n", hex.Dump(b[0:payloadLen]))
|
||||
|
@ -1561,7 +1564,6 @@ func (hc *Conn) WritePacket(b []byte, ctrlStatOp byte) (n int, err error) {
|
|||
} else {
|
||||
//fmt.Println("[a]WriteError!")
|
||||
}
|
||||
hc.Unlock()
|
||||
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
|
@ -1593,6 +1595,40 @@ func (hc *Conn) SetupChaff(msecsMin uint, msecsMax uint, szMax uint) {
|
|||
hc.chaff.szMax = szMax
|
||||
}
|
||||
|
||||
func (hc *Conn) ShutdownRekey() {
|
||||
hc.rekey = 0
|
||||
}
|
||||
|
||||
func (hc *Conn) RekeyHelper(intervalSecs uint) {
|
||||
go func() {
|
||||
hc.rekey = intervalSecs
|
||||
for {
|
||||
if hc.rekey != 0 {
|
||||
//logger.LogDebug(fmt.Sprintf("[rekeyHelper Loop]\n"))
|
||||
time.Sleep(time.Duration(hc.rekey) * time.Second)
|
||||
|
||||
// Send rekey to other end
|
||||
rekeyData := make([]byte, 64)
|
||||
_, err := crand.Read(rekeyData)
|
||||
//logger.LogDebug(fmt.Sprintf("[rekey [%02x %02x %02x ...]\n",
|
||||
// rekeyData[0], rekeyData[1], rekeyData[2]))
|
||||
//logger.LogDebug("[+rekeyHelper]")
|
||||
_, err = hc.WritePacket(rekeyData, CSORekey)
|
||||
hc.Lock()
|
||||
hc.w, hc.wm, err = hc.getStream(rekeyData)
|
||||
//logger.LogDebug("[-rekeyHelper]")
|
||||
hc.Unlock()
|
||||
if err != nil {
|
||||
log.Printf("[rekey WritePacket err! (%v) rekey dying ...]\n", err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// Helper routine to spawn a chaffing goroutine for each Conn
|
||||
func (hc *Conn) chaffHelper() {
|
||||
go func() {
|
||||
|
@ -1605,7 +1641,9 @@ func (hc *Conn) chaffHelper() {
|
|||
min := int(hc.chaff.msecsMin)
|
||||
nextDuration = rand.Intn(int(hc.chaff.msecsMax)-min) + min
|
||||
_, _ = rand.Read(bufTmp)
|
||||
//logger.LogDebug("[+chaffHelper]")
|
||||
_, err := hc.WritePacket(bufTmp, CSOChaff)
|
||||
//logger.LogDebug("[-chaffHelper]")
|
||||
if err != nil {
|
||||
log.Println("[ *** error - chaffHelper shutting down *** ]")
|
||||
hc.chaff.shutdown = true
|
||||
|
@ -1642,7 +1680,9 @@ func (hc *Conn) keepaliveHelper() {
|
|||
for {
|
||||
nextDuration := 10000
|
||||
bufTmp := []byte{0x55, 0xaa}
|
||||
//logger.LogDebug("[+keepaliveHelper]")
|
||||
_, err := hc.WritePacket(bufTmp, CSOKeepAlive)
|
||||
//logger.LogDebug("[-keepaliveHelper]")
|
||||
//logger.LogDebug(fmt.Sprintf("[keepalive]\n"))
|
||||
if err != nil {
|
||||
logger.LogDebug(fmt.Sprintf("[ *** error - keepaliveHelper quitting *** ]\n"))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue