Version and update verdict kernel functions
This commit is contained in:
@@ -177,7 +177,9 @@ func interceptionStart() error {
|
|||||||
interceptionModule.StartWorker("stat logger", statLogger)
|
interceptionModule.StartWorker("stat logger", statLogger)
|
||||||
interceptionModule.StartWorker("packet handler", packetHandler)
|
interceptionModule.StartWorker("packet handler", packetHandler)
|
||||||
|
|
||||||
return interception.Start()
|
err := interception.Start()
|
||||||
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func interceptionStop() error {
|
func interceptionStop() error {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/safing/portmaster/firewall/interception/windowskext"
|
"github.com/safing/portmaster/firewall/interception/windowskext"
|
||||||
|
"github.com/safing/portmaster/network"
|
||||||
"github.com/safing/portmaster/network/packet"
|
"github.com/safing/portmaster/network/packet"
|
||||||
"github.com/safing/portmaster/updates"
|
"github.com/safing/portmaster/updates"
|
||||||
)
|
)
|
||||||
@@ -39,3 +40,16 @@ func stop() error {
|
|||||||
func ResetVerdictOfAllConnections() error {
|
func ResetVerdictOfAllConnections() error {
|
||||||
return windowskext.ClearCache()
|
return windowskext.ClearCache()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func UpdateVerdictOfConnection(conn *network.Connection) error {
|
||||||
|
return windowskext.UpdateVerdict(conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetVersion() (string, error) {
|
||||||
|
version, err := windowskext.GetVersion()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return version.String(), nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ package windowskext
|
|||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/tevino/abool"
|
"github.com/tevino/abool"
|
||||||
@@ -50,6 +51,23 @@ type VerdictInfo struct {
|
|||||||
verdict network.Verdict // verdict for the connection
|
verdict network.Verdict // verdict for the connection
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type VerdictUpdateInfo struct {
|
||||||
|
ipV6 uint8 //True: IPv6, False: IPv4
|
||||||
|
protocol uint8 //Protocol (UDP, TCP, ...)
|
||||||
|
localIP [4]uint32 //Source Address, only srcIP[0] if IPv4
|
||||||
|
remoteIP [4]uint32 //Destination Address
|
||||||
|
localPort uint16 //Source Port
|
||||||
|
remotePort uint16 //Destination port
|
||||||
|
verdict uint8 //New verdict
|
||||||
|
}
|
||||||
|
|
||||||
|
type VersionInfo struct {
|
||||||
|
major uint8
|
||||||
|
minor uint8
|
||||||
|
revision uint8
|
||||||
|
build uint8
|
||||||
|
}
|
||||||
|
|
||||||
// Handler transforms received packets to the Packet interface.
|
// Handler transforms received packets to the Packet interface.
|
||||||
func Handler(packets chan packet.Packet) {
|
func Handler(packets chan packet.Packet) {
|
||||||
if !ready.IsSet() {
|
if !ready.IsSet() {
|
||||||
@@ -152,3 +170,7 @@ func convertIPv6(input [4]uint32) net.IP {
|
|||||||
}
|
}
|
||||||
return net.IP(addressBuf)
|
return net.IP(addressBuf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *VersionInfo) String() string {
|
||||||
|
return fmt.Sprintf("%d.%d.%d.%d", v.major, v.minor, v.revision, v.build)
|
||||||
|
}
|
||||||
|
|||||||
@@ -226,6 +226,61 @@ func ClearCache() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func UpdateVerdict(conn *network.Connection) error {
|
||||||
|
kextLock.RLock()
|
||||||
|
defer kextLock.RUnlock()
|
||||||
|
|
||||||
|
// Check if driver is initialized
|
||||||
|
if !ready.IsSet() {
|
||||||
|
log.Error("kext: failed to clear the cache: kext not ready")
|
||||||
|
return ErrKextNotReady
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize variables
|
||||||
|
info := &VerdictUpdateInfo{
|
||||||
|
ipV6: uint8(conn.IPVersion),
|
||||||
|
protocol: uint8(conn.IPProtocol),
|
||||||
|
localPort: conn.LocalPort,
|
||||||
|
remotePort: conn.Entity.Port,
|
||||||
|
verdict: uint8(conn.Verdict.Active),
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy ip addresses
|
||||||
|
copy(asByteArray(&info.localIP[0]), conn.LocalIP)
|
||||||
|
copy(asByteArray(&info.remoteIP[0]), conn.Entity.IP)
|
||||||
|
|
||||||
|
// Make driver request
|
||||||
|
data := asByteArray(&info)
|
||||||
|
err := deviceIoControlDirect(kextHandle, IOCTL_UPDATE_VERDICT, data)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetVersion() (*VersionInfo, error) {
|
||||||
|
kextLock.RLock()
|
||||||
|
defer kextLock.RUnlock()
|
||||||
|
|
||||||
|
// Check if driver is initialized
|
||||||
|
if !ready.IsSet() {
|
||||||
|
log.Error("kext: failed to clear the cache: kext not ready")
|
||||||
|
return nil, ErrKextNotReady
|
||||||
|
}
|
||||||
|
|
||||||
|
data := make([]uint8, 4)
|
||||||
|
err := deviceIoControlDirect(kextHandle, IOCTL_VERSION, data)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
version := &VersionInfo{
|
||||||
|
major: data[0],
|
||||||
|
minor: data[1],
|
||||||
|
revision: data[2],
|
||||||
|
build: data[3],
|
||||||
|
}
|
||||||
|
return version, nil
|
||||||
|
}
|
||||||
|
|
||||||
func asByteArray[T any](obj *T) []byte {
|
func asByteArray[T any](obj *T) []byte {
|
||||||
return unsafe.Slice((*byte)(unsafe.Pointer(obj)), unsafe.Sizeof(*obj))
|
return unsafe.Slice((*byte)(unsafe.Pointer(obj)), unsafe.Sizeof(*obj))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,12 +15,13 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
IOCTL_HELLO = ctlCode(SIOCTL_TYPE, 0x800, METHOD_BUFFERED, windows.FILE_READ_DATA|windows.FILE_WRITE_DATA)
|
IOCTL_VERSION = ctlCode(SIOCTL_TYPE, 0x800, METHOD_NEITHER, windows.FILE_READ_DATA|windows.FILE_WRITE_DATA)
|
||||||
IOCTL_RECV_VERDICT_REQ_POLL = ctlCode(SIOCTL_TYPE, 0x801, METHOD_BUFFERED, windows.FILE_READ_DATA|windows.FILE_WRITE_DATA)
|
IOCTL_RECV_VERDICT_REQ_POLL = ctlCode(SIOCTL_TYPE, 0x801, METHOD_BUFFERED, windows.FILE_READ_DATA|windows.FILE_WRITE_DATA) // Not used
|
||||||
IOCTL_RECV_VERDICT_REQ = ctlCode(SIOCTL_TYPE, 0x802, METHOD_BUFFERED, windows.FILE_READ_DATA|windows.FILE_WRITE_DATA)
|
IOCTL_RECV_VERDICT_REQ = ctlCode(SIOCTL_TYPE, 0x802, METHOD_BUFFERED, windows.FILE_READ_DATA|windows.FILE_WRITE_DATA)
|
||||||
IOCTL_SET_VERDICT = ctlCode(SIOCTL_TYPE, 0x803, METHOD_BUFFERED, windows.FILE_READ_DATA|windows.FILE_WRITE_DATA)
|
IOCTL_SET_VERDICT = ctlCode(SIOCTL_TYPE, 0x803, METHOD_BUFFERED, windows.FILE_READ_DATA|windows.FILE_WRITE_DATA)
|
||||||
IOCTL_GET_PAYLOAD = ctlCode(SIOCTL_TYPE, 0x804, METHOD_BUFFERED, windows.FILE_READ_DATA|windows.FILE_WRITE_DATA)
|
IOCTL_GET_PAYLOAD = ctlCode(SIOCTL_TYPE, 0x804, METHOD_BUFFERED, windows.FILE_READ_DATA|windows.FILE_WRITE_DATA)
|
||||||
IOCTL_CLEAR_CACHE = ctlCode(SIOCTL_TYPE, 0x805, METHOD_BUFFERED, windows.FILE_READ_DATA|windows.FILE_WRITE_DATA)
|
IOCTL_CLEAR_CACHE = ctlCode(SIOCTL_TYPE, 0x805, METHOD_BUFFERED, windows.FILE_READ_DATA|windows.FILE_WRITE_DATA)
|
||||||
|
IOCTL_UPDATE_VERDICT = ctlCode(SIOCTL_TYPE, 0x806, METHOD_NEITHER, windows.FILE_READ_DATA|windows.FILE_WRITE_DATA)
|
||||||
)
|
)
|
||||||
|
|
||||||
func ctlCode(device_type, function, method, access uint32) uint32 {
|
func ctlCode(device_type, function, method, access uint32) uint32 {
|
||||||
@@ -89,3 +90,21 @@ func deviceIoControlReadWrite(handle windows.Handle, code uint32, inData []byte,
|
|||||||
|
|
||||||
return bytesReturned, err
|
return bytesReturned, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use for METHOD_NEITHER IOCTL, the data buffer is passed directly to the kernel
|
||||||
|
func deviceIoControlDirect(handle windows.Handle, code uint32, data []byte) error {
|
||||||
|
var dataPtr *byte = nil
|
||||||
|
var dataSize uint32 = 0
|
||||||
|
if data != nil {
|
||||||
|
dataPtr = &data[0]
|
||||||
|
dataSize = uint32(len(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
err := windows.DeviceIoControl(handle,
|
||||||
|
code,
|
||||||
|
dataPtr, dataSize,
|
||||||
|
nil, 0,
|
||||||
|
nil, nil)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user