Skip to content

Commit

Permalink
refactor: add validation to apf
Browse files Browse the repository at this point in the history
  • Loading branch information
Mike committed Dec 16, 2024
1 parent bcc3124 commit 466cc08
Show file tree
Hide file tree
Showing 3 changed files with 495 additions and 8 deletions.
34 changes: 26 additions & 8 deletions pkg/apf/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,37 +23,55 @@ func Process(data []byte, session *Session) bytes.Buffer {
case APF_GLOBAL_REQUEST: // 80
log.Debug("received APF_GLOBAL_REQUEST")

dataToSend = ProcessGlobalRequest(data)
if ValidateGlobalRequest(data) {
dataToSend = ProcessGlobalRequest(data)
}
case APF_CHANNEL_OPEN: // (90) Sent by Intel AMT when a channel needs to be open from Intel AMT. This is not common, but WSMAN events are a good example of channel coming from AMT.
log.Debug("received APF_CHANNEL_OPEN")
case APF_DISCONNECT: // (1) Intel AMT wants to completely disconnect. Not sure when this happens.
log.Debug("received APF_DISCONNECT")
case APF_SERVICE_REQUEST: // (5)
log.Debug("received APF_SERVICE_REQUEST")

dataToSend = ProcessServiceRequest(data)
if ValidateServiceRequest(data) {
dataToSend = ProcessServiceRequest(data)
}
case APF_CHANNEL_OPEN_CONFIRMATION: // (91) Intel AMT confirmation to an APF_CHANNEL_OPEN request.
log.Debug("received APF_CHANNEL_OPEN_CONFIRMATION")

ProcessChannelOpenConfirmation(data, session)
if ValidateChannelOpenConfirmation(data) {
ProcessChannelOpenConfirmation(data, session)
}
case APF_CHANNEL_OPEN_FAILURE: // (92) Intel AMT rejected our connection attempt.
log.Debug("received APF_CHANNEL_OPEN_FAILURE")

ProcessChannelOpenFailure(data, session)
if ValidateChannelOpenFailure(data) {
ProcessChannelOpenFailure(data, session)
}
case APF_CHANNEL_CLOSE: // (97) Intel AMT is closing this channel, we need to disconnect the LMS TCP connection
log.Debug("received APF_CHANNEL_CLOSE")

ProcessChannelClose(data, session)
if ValidateChannelClose(data) {
ProcessChannelClose(data, session)
}
case APF_CHANNEL_DATA: // (94) Intel AMT is sending data that we must relay into an LMS TCP connection.
ProcessChannelData(data, session)
log.Debug("received APF_CHANNEL_DATA")

if ValidateChannelData(data) {
ProcessChannelData(data, session)
}
case APF_CHANNEL_WINDOW_ADJUST: // 93
log.Debug("received APF_CHANNEL_WINDOW_ADJUST")

ProcessChannelWindowAdjust(data, session)
if ValidateChannelWindowAdjust(data) {
ProcessChannelWindowAdjust(data, session)
}
case APF_PROTOCOLVERSION: // 192
log.Debug("received APF PROTOCOL VERSION")

dataToSend = ProcessProtocolVersion(data)
if ValidateProtocolVersion(data) {
dataToSend = ProcessProtocolVersion(data)
}
case APF_USERAUTH_REQUEST: // 50
default:
}
Expand Down
72 changes: 72 additions & 0 deletions pkg/apf/vaildator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package apf

import (
"encoding/binary"
)

// ValidateProtocolVersion checks if the data length is at least 93 bytes for APF_PROTOCOLVERSION.
func ValidateProtocolVersion(data []byte) bool {
return len(data) >= 93
}

// ValidateServiceRequest checks if the data length is sufficient for APF_SERVICE_REQUEST.
func ValidateServiceRequest(data []byte) bool {
if len(data) < 5 {
return false
}

serviceLen := int(binary.BigEndian.Uint32(data[1:5]))

return len(data) >= 5+serviceLen
}

// ValidateGlobalRequest checks if the data length is sufficient for APF_GLOBAL_REQUEST.
func ValidateGlobalRequest(data []byte) bool {
if len(data) < 5 {
return false
}

globalReqLen := int(binary.BigEndian.Uint32(data[1:5]))
if len(data) < 5+globalReqLen+1 {
return false
}

serviceName := string(data[5 : 5+globalReqLen])

if serviceName == APF_GLOBAL_REQUEST_STR_TCP_FORWARD_REQUEST || serviceName == APF_GLOBAL_REQUEST_STR_TCP_FORWARD_CANCEL_REQUEST {
if len(data) < 6+globalReqLen+4 {
return false
}

addrLen := int(binary.BigEndian.Uint32(data[6+globalReqLen : 10+globalReqLen]))

return len(data) >= 14+globalReqLen+addrLen
}

return false
}

// ValidateChannelOpenConfirmation checks if the data length is at least 17 bytes for APF_CHANNEL_OPEN_CONFIRMATION.
func ValidateChannelOpenConfirmation(data []byte) bool {
return len(data) >= 17
}

// ValidateChannelOpenFailure checks if the data length is at least 17 bytes for APF_CHANNEL_OPEN_FAILURE.
func ValidateChannelOpenFailure(data []byte) bool {
return len(data) >= 17
}

// ValidateChannelClose checks if the data length is at least 5 bytes for APF_CHANNEL_CLOSE.
func ValidateChannelClose(data []byte) bool {
return len(data) >= 5
}

// ValidateChannelData checks if the data length is sufficient for APF_CHANNEL_DATA.
func ValidateChannelData(data []byte) bool {
return len(data) >= 9 && len(data) >= 9+int(binary.BigEndian.Uint32(data[5:9]))
}

// ValidateChannelWindowAdjust checks if the data length is at least 9 bytes for APF_CHANNEL_WINDOW_ADJUST.
func ValidateChannelWindowAdjust(data []byte) bool {
return len(data) >= 9
}
Loading

0 comments on commit 466cc08

Please sign in to comment.