Clean up linter errors

This commit is contained in:
Daniel
2019-11-07 16:13:22 +01:00
parent 35c7f4955b
commit f75fc7d162
50 changed files with 402 additions and 334 deletions

View File

@@ -3,7 +3,6 @@ package firewall
import (
"context"
"fmt"
"net"
"os"
"sync/atomic"
"time"
@@ -21,26 +20,28 @@ import (
)
var (
module *modules.Module
// localNet net.IPNet
localhost net.IP
dnsServer net.IPNet
// localhost net.IP
// dnsServer net.IPNet
packetsAccepted *uint64
packetsBlocked *uint64
packetsDropped *uint64
localNet4 *net.IPNet
// localNet4 *net.IPNet
localhost4 = net.IPv4(127, 0, 0, 1)
localhost6 = net.IPv6loopback
// localhost4 = net.IPv4(127, 0, 0, 1)
// localhost6 = net.IPv6loopback
tunnelNet4 *net.IPNet
tunnelNet6 *net.IPNet
tunnelEntry4 = net.IPv4(127, 0, 0, 17)
tunnelEntry6 = net.ParseIP("fd17::17")
// tunnelNet4 *net.IPNet
// tunnelNet6 *net.IPNet
// tunnelEntry4 = net.IPv4(127, 0, 0, 17)
// tunnelEntry6 = net.ParseIP("fd17::17")
)
func init() {
modules.Register("firewall", prep, start, stop, "core", "network", "nameserver", "profile", "updates")
module = modules.Register("firewall", prep, start, stop, "core", "network", "nameserver", "profile", "updates")
}
func prep() (err error) {
@@ -55,21 +56,21 @@ func prep() (err error) {
return err
}
_, localNet4, err = net.ParseCIDR("127.0.0.0/24")
// Yes, this would normally be 127.0.0.0/8
// TODO: figure out any side effects
if err != nil {
return fmt.Errorf("firewall: failed to parse cidr 127.0.0.0/24: %s", err)
}
// _, localNet4, err = net.ParseCIDR("127.0.0.0/24")
// // Yes, this would normally be 127.0.0.0/8
// // TODO: figure out any side effects
// if err != nil {
// return fmt.Errorf("firewall: failed to parse cidr 127.0.0.0/24: %s", err)
// }
_, tunnelNet4, err = net.ParseCIDR("127.17.0.0/16")
if err != nil {
return fmt.Errorf("firewall: failed to parse cidr 127.17.0.0/16: %s", err)
}
_, tunnelNet6, err = net.ParseCIDR("fd17::/64")
if err != nil {
return fmt.Errorf("firewall: failed to parse cidr fd17::/64: %s", err)
}
// _, tunnelNet4, err = net.ParseCIDR("127.17.0.0/16")
// if err != nil {
// return fmt.Errorf("firewall: failed to parse cidr 127.17.0.0/16: %s", err)
// }
// _, tunnelNet6, err = net.ParseCIDR("fd17::/64")
// if err != nil {
// return fmt.Errorf("firewall: failed to parse cidr fd17::/64: %s", err)
// }
var pA uint64
packetsAccepted = &pA
@@ -83,9 +84,21 @@ func prep() (err error) {
func start() error {
startAPIAuth()
go statLogger()
go run()
go portsInUseCleaner()
module.StartWorker("stat logger", func(ctx context.Context) error {
statLogger()
return nil
})
module.StartWorker("packet handler", func(ctx context.Context) error {
run()
return nil
})
module.StartWorker("ports state cleaner", func(ctx context.Context) error {
portsInUseCleaner()
return nil
})
return interception.Start()
}
@@ -106,7 +119,7 @@ func handlePacket(pkt packet.Packet) {
// allow local dns
if (pkt.Info().DstPort == 53 || pkt.Info().SrcPort == 53) && pkt.Info().Src.Equal(pkt.Info().Dst) {
log.Debugf("accepting local dns: %s", pkt)
pkt.PermanentAccept()
_ = pkt.PermanentAccept()
return
}
@@ -114,7 +127,7 @@ func handlePacket(pkt packet.Packet) {
if apiPortSet {
if (pkt.Info().DstPort == apiPort || pkt.Info().SrcPort == apiPort) && pkt.Info().Src.Equal(pkt.Info().Dst) {
log.Debugf("accepting api connection: %s", pkt)
pkt.PermanentAccept()
_ = pkt.PermanentAccept()
return
}
}
@@ -130,20 +143,20 @@ func handlePacket(pkt packet.Packet) {
switch pkt.Info().Protocol {
case packet.ICMP:
log.Debugf("accepting ICMP: %s", pkt)
pkt.PermanentAccept()
_ = pkt.PermanentAccept()
return
case packet.ICMPv6:
log.Debugf("accepting ICMPv6: %s", pkt)
pkt.PermanentAccept()
_ = pkt.PermanentAccept()
return
case packet.IGMP:
log.Debugf("accepting IGMP: %s", pkt)
pkt.PermanentAccept()
_ = pkt.PermanentAccept()
return
case packet.UDP:
if pkt.Info().DstPort == 67 || pkt.Info().DstPort == 68 {
log.Debugf("accepting DHCP: %s", pkt)
pkt.PermanentAccept()
_ = pkt.PermanentAccept()
return
}
// TODO: Howto handle NetBios?
@@ -310,39 +323,44 @@ func issueVerdict(pkt packet.Packet, link *network.Link, verdict network.Verdict
verdict = link.Verdict
}
var err error
switch verdict {
case network.VerdictAccept:
atomic.AddUint64(packetsAccepted, 1)
if link.VerdictPermanent {
pkt.PermanentAccept()
err = pkt.PermanentAccept()
} else {
pkt.Accept()
err = pkt.Accept()
}
case network.VerdictBlock:
atomic.AddUint64(packetsBlocked, 1)
if link.VerdictPermanent {
pkt.PermanentBlock()
err = pkt.PermanentBlock()
} else {
pkt.Block()
err = pkt.Block()
}
case network.VerdictDrop:
atomic.AddUint64(packetsDropped, 1)
if link.VerdictPermanent {
pkt.PermanentDrop()
err = pkt.PermanentDrop()
} else {
pkt.Drop()
err = pkt.Drop()
}
case network.VerdictRerouteToNameserver:
pkt.RerouteToNameserver()
err = pkt.RerouteToNameserver()
case network.VerdictRerouteToTunnel:
pkt.RerouteToTunnel()
err = pkt.RerouteToTunnel()
default:
atomic.AddUint64(packetsDropped, 1)
pkt.Drop()
err = pkt.Drop()
}
link.Unlock()
if err != nil {
log.Warningf("firewall: failed to apply verdict to pkt %s: %s", pkt, err)
}
log.Tracer(pkt.Ctx()).Infof("firewall: %s %s", link.Verdict, link)
}

View File

@@ -7,6 +7,7 @@ import (
"github.com/safing/portmaster/network/packet"
)
//nolint:golint,stylecheck // FIXME
const (
DO_NOTHING uint8 = iota
BLOCK_PACKET
@@ -25,6 +26,7 @@ var (
inspectorsLock sync.Mutex
)
// RegisterInspector registers a traffic inspector.
func RegisterInspector(name string, inspector inspectorFn, inspectVerdict network.Verdict) (index int) {
inspectorsLock.Lock()
defer inspectorsLock.Unlock()
@@ -35,13 +37,14 @@ func RegisterInspector(name string, inspector inspectorFn, inspectVerdict networ
return
}
// RunInspectors runs all the applicable inspectors on the given packet.
func RunInspectors(pkt packet.Packet, link *network.Link) (network.Verdict, bool) {
// inspectorsLock.Lock()
// defer inspectorsLock.Unlock()
activeInspectors := link.GetActiveInspectors()
if activeInspectors == nil {
activeInspectors = make([]bool, len(inspectors), len(inspectors))
activeInspectors = make([]bool, len(inspectors))
link.SetActiveInspectors(activeInspectors)
}

View File

@@ -1,2 +1,2 @@
// Package nfqueue provides network interception capabilites on linux via iptables nfqueue.
// Package nfqueue provides network interception capabilities on linux via iptables nfqueue.
package nfqueue

View File

@@ -27,6 +27,8 @@ func init() {
queues = make(map[uint16]*NFQueue)
}
// NFQueue holds a Linux NFQ Handle and associated information.
//nolint:maligned // FIXME
type NFQueue struct {
DefaultVerdict uint32
Timeout time.Duration
@@ -41,6 +43,7 @@ type NFQueue struct {
Packets chan packet.Packet
}
// NewNFQueue initializes a new netfilter queue.
func NewNFQueue(qid uint16) (nfq *NFQueue, err error) {
if os.Geteuid() != 0 {
return nil, errors.New("must be root to intercept packets")
@@ -61,96 +64,98 @@ func NewNFQueue(qid uint16) (nfq *NFQueue, err error) {
return nfq, nil
}
func (this *NFQueue) init() error {
func (nfq *NFQueue) init() error {
var err error
if this.h, err = C.nfq_open(); err != nil || this.h == nil {
if nfq.h, err = C.nfq_open(); err != nil || nfq.h == nil {
return fmt.Errorf("could not open nfqueue: %s", err)
}
//if this.qh, err = C.nfq_create_queue(this.h, qid, C.get_cb(), unsafe.Pointer(nfq)); err != nil || this.qh == nil {
//if nfq.qh, err = C.nfq_create_queue(nfq.h, qid, C.get_cb(), unsafe.Pointer(nfq)); err != nil || nfq.qh == nil {
this.Packets = make(chan packet.Packet, 1)
nfq.Packets = make(chan packet.Packet, 1)
if C.nfq_unbind_pf(this.h, C.AF_INET) < 0 {
this.Destroy()
if C.nfq_unbind_pf(nfq.h, C.AF_INET) < 0 {
nfq.Destroy()
return errors.New("nfq_unbind_pf(AF_INET) failed, are you root?")
}
if C.nfq_unbind_pf(this.h, C.AF_INET6) < 0 {
this.Destroy()
if C.nfq_unbind_pf(nfq.h, C.AF_INET6) < 0 {
nfq.Destroy()
return errors.New("nfq_unbind_pf(AF_INET6) failed")
}
if C.nfq_bind_pf(this.h, C.AF_INET) < 0 {
this.Destroy()
if C.nfq_bind_pf(nfq.h, C.AF_INET) < 0 {
nfq.Destroy()
return errors.New("nfq_bind_pf(AF_INET) failed")
}
if C.nfq_bind_pf(this.h, C.AF_INET6) < 0 {
this.Destroy()
if C.nfq_bind_pf(nfq.h, C.AF_INET6) < 0 {
nfq.Destroy()
return errors.New("nfq_bind_pf(AF_INET6) failed")
}
if this.qh, err = C.create_queue(this.h, C.uint16_t(this.qid)); err != nil || this.qh == nil {
C.nfq_close(this.h)
if nfq.qh, err = C.create_queue(nfq.h, C.uint16_t(nfq.qid)); err != nil || nfq.qh == nil {
C.nfq_close(nfq.h)
return fmt.Errorf("could not create queue: %s", err)
}
this.fd = int(C.nfq_fd(this.h))
nfq.fd = int(C.nfq_fd(nfq.h))
if C.nfq_set_mode(this.qh, C.NFQNL_COPY_PACKET, 0xffff) < 0 {
this.Destroy()
if C.nfq_set_mode(nfq.qh, C.NFQNL_COPY_PACKET, 0xffff) < 0 {
nfq.Destroy()
return errors.New("nfq_set_mode(NFQNL_COPY_PACKET) failed")
}
if C.nfq_set_queue_maxlen(this.qh, 1024*8) < 0 {
this.Destroy()
if C.nfq_set_queue_maxlen(nfq.qh, 1024*8) < 0 {
nfq.Destroy()
return errors.New("nfq_set_queue_maxlen(1024 * 8) failed")
}
return nil
}
func (this *NFQueue) Destroy() {
this.lk.Lock()
defer this.lk.Unlock()
// Destroy closes all the nfqueues.
func (nfq *NFQueue) Destroy() {
nfq.lk.Lock()
defer nfq.lk.Unlock()
if this.fd != 0 && this.Valid() {
syscall.Close(this.fd)
if nfq.fd != 0 && nfq.Valid() {
syscall.Close(nfq.fd)
}
if this.qh != nil {
C.nfq_destroy_queue(this.qh)
this.qh = nil
if nfq.qh != nil {
C.nfq_destroy_queue(nfq.qh)
nfq.qh = nil
}
if this.h != nil {
C.nfq_close(this.h)
this.h = nil
if nfq.h != nil {
C.nfq_close(nfq.h)
nfq.h = nil
}
// TODO: don't close, we're exiting anyway
// if this.Packets != nil {
// close(this.Packets)
// if nfq.Packets != nil {
// close(nfq.Packets)
// }
}
func (this *NFQueue) Valid() bool {
return this.h != nil && this.qh != nil
// Valid returns whether the NFQueue is still valid.
func (nfq *NFQueue) Valid() bool {
return nfq.h != nil && nfq.qh != nil
}
//export go_nfq_callback
func go_nfq_callback(id uint32, hwproto uint16, hook uint8, mark *uint32,
version, protocol, tos, ttl uint8, saddr, daddr unsafe.Pointer,
sport, dport, checksum uint16, payload_len uint32, payload, data unsafe.Pointer) (v uint32) {
sport, dport, checksum uint16, payloadLen uint32, payload, data unsafe.Pointer) (v uint32) {
qidptr := (*uint16)(data)
qid := uint16(*qidptr)
qid := *qidptr
// nfq := (*NFQueue)(nfqptr)
ipVersion := packet.IPVersion(version)
ipsz := C.int(ipVersion.ByteSize())
bs := C.GoBytes(payload, (C.int)(payload_len))
bs := C.GoBytes(payload, (C.int)(payloadLen))
verdict := make(chan uint32, 1)
pkt := Packet{
QueueId: qid,
Id: id,
QueueID: qid,
ID: id,
HWProtocol: hwproto,
Hook: hook,
Mark: *mark,

View File

@@ -1,15 +1,18 @@
package nfqueue
import (
"fmt"
"errors"
"github.com/safing/portmaster/network/packet"
)
// NFQ Errors
var (
ErrVerdictSentOrTimedOut error = fmt.Errorf("The verdict was already sent or timed out.")
ErrVerdictSentOrTimedOut = errors.New("the verdict was already sent or timed out")
)
// NFQ Packet Constants
//nolint:golint,stylecheck // FIXME
const (
NFQ_DROP uint32 = 0 // discarded the packet
NFQ_ACCEPT uint32 = 1 // the packet passes, continue iterations
@@ -19,11 +22,12 @@ const (
NFQ_STOP uint32 = 5 // accept, but don't continue iterations
)
// Packet represents a packet with a NFQ reference.
type Packet struct {
packet.Base
QueueId uint16
Id uint32
QueueID uint16
ID uint32
HWProtocol uint16
Hook uint8
Mark uint32
@@ -35,9 +39,10 @@ type Packet struct {
// func (pkt *Packet) String() string {
// return fmt.Sprintf("<Packet QId: %d, Id: %d, Type: %s, Src: %s:%d, Dst: %s:%d, Mark: 0x%X, Checksum: 0x%X, TOS: 0x%X, TTL: %d>",
// pkt.QueueId, pkt.Id, pkt.Protocol, pkt.Src, pkt.SrcPort, pkt.Dst, pkt.DstPort, pkt.Mark, pkt.Checksum, pkt.Tos, pkt.TTL)
// pkt.QueueID, pkt.Id, pkt.Protocol, pkt.Src, pkt.SrcPort, pkt.Dst, pkt.DstPort, pkt.Mark, pkt.Checksum, pkt.Tos, pkt.TTL)
// }
//nolint:unparam // FIXME
func (pkt *Packet) setVerdict(v uint32) (err error) {
defer func() {
if x := recover(); x != nil {
@@ -68,41 +73,49 @@ func (pkt *Packet) setVerdict(v uint32) (err error) {
// return pkt.setVerdict(NFQ_DROP)
// }
// Accept implements the packet interface.
func (pkt *Packet) Accept() error {
pkt.Mark = 1700
return pkt.setVerdict(NFQ_ACCEPT)
}
// Block implements the packet interface.
func (pkt *Packet) Block() error {
pkt.Mark = 1701
return pkt.setVerdict(NFQ_ACCEPT)
}
// Drop implements the packet interface.
func (pkt *Packet) Drop() error {
pkt.Mark = 1702
return pkt.setVerdict(NFQ_ACCEPT)
}
// PermanentAccept implements the packet interface.
func (pkt *Packet) PermanentAccept() error {
pkt.Mark = 1710
return pkt.setVerdict(NFQ_ACCEPT)
}
// PermanentBlock implements the packet interface.
func (pkt *Packet) PermanentBlock() error {
pkt.Mark = 1711
return pkt.setVerdict(NFQ_ACCEPT)
}
// PermanentDrop implements the packet interface.
func (pkt *Packet) PermanentDrop() error {
pkt.Mark = 1712
return pkt.setVerdict(NFQ_ACCEPT)
}
// RerouteToNameserver implements the packet interface.
func (pkt *Packet) RerouteToNameserver() error {
pkt.Mark = 1799
return pkt.setVerdict(NFQ_ACCEPT)
}
// RerouteToTunnel implements the packet interface.
func (pkt *Packet) RerouteToTunnel() error {
pkt.Mark = 1717
return pkt.setVerdict(NFQ_ACCEPT)

View File

@@ -247,28 +247,28 @@ func StartNfqueueInterception() (err error) {
err = activateNfqueueFirewall()
if err != nil {
Stop()
_ = Stop()
return fmt.Errorf("could not initialize nfqueue: %s", err)
}
out4Queue, err = nfqueue.NewNFQueue(17040)
if err != nil {
Stop()
_ = Stop()
return fmt.Errorf("interception: failed to create nfqueue(IPv4, in): %s", err)
}
in4Queue, err = nfqueue.NewNFQueue(17140)
if err != nil {
Stop()
_ = Stop()
return fmt.Errorf("interception: failed to create nfqueue(IPv4, in): %s", err)
}
out6Queue, err = nfqueue.NewNFQueue(17060)
if err != nil {
Stop()
_ = Stop()
return fmt.Errorf("interception: failed to create nfqueue(IPv4, in): %s", err)
}
in6Queue, err = nfqueue.NewNFQueue(17160)
if err != nil {
Stop()
_ = Stop()
return fmt.Errorf("interception: failed to create nfqueue(IPv4, in): %s", err)
}
@@ -321,12 +321,3 @@ func handleInterception() {
}
}
}
func stringInSlice(slice []string, value string) bool {
for _, entry := range slice {
if value == entry {
return true
}
}
return false
}

View File

@@ -1,4 +1,5 @@
// +build windows
package windowskext
import (

View File

@@ -1,4 +1,5 @@
// +build windows
package windowskext
import (

View File

@@ -1,4 +1,5 @@
// +build windows
package windowskext
import (

View File

@@ -1,26 +0,0 @@
package main
import (
"fmt"
"unsafe"
)
const integerSize int = int(unsafe.Sizeof(0))
func isBigEndian() bool {
var i int = 0x1
bs := (*[integerSize]byte)(unsafe.Pointer(&i))
if bs[0] == 0 {
return true
} else {
return false
}
}
func main() {
if isBigEndian() {
fmt.Println("System is Big Endian (Network Byte Order): uint16 0x1234 is 0x1234 in memory")
} else {
fmt.Println("System is Little Endian (Host Byte Order): uint16 0x1234 is 0x3412 in memory")
}
}

View File

@@ -139,6 +139,7 @@ func DecideOnCommunicationAfterIntel(comm *network.Communication, fqdn string, r
}
// FilterDNSResponse filters a dns response according to the application profile and settings.
//nolint:gocognit // FIXME
func FilterDNSResponse(comm *network.Communication, q *intel.Query, rrCache *intel.RRCache) *intel.RRCache {
// do not modify own queries - this should not happen anyway
if comm.Process().Pid == os.Getpid() {
@@ -497,7 +498,7 @@ func checkRelation(comm *network.Communication, fqdn string) (related bool) {
// TODO: add #AI
pathElements := strings.Split(comm.Process().Path, "/") // FIXME: path seperator
pathElements := strings.Split(comm.Process().Path, "/") // FIXME: path separator
// only look at the last two path segments
if len(pathElements) > 2 {
pathElements = pathElements[len(pathElements)-2:]
@@ -537,5 +538,5 @@ matchLoop:
log.Infof("firewall: permitting communication %s, match to domain was found: %s is related to %s", comm, domainElement, processElement)
comm.Accept(fmt.Sprintf("domain is related to process: %s is related to %s", domainElement, processElement))
}
return
return related
}

View File

@@ -80,10 +80,10 @@ func cleanPortsInUse() {
portsInUseLock.Lock()
defer portsInUseLock.Unlock()
threshhold := time.Now().Add(-cleanTimeout)
threshold := time.Now().Add(-cleanTimeout)
for port, status := range portsInUse {
if status.lastSeen.Before(threshhold) {
if status.lastSeen.Before(threshold) {
delete(portsInUse, port)
}
}

View File

@@ -1,6 +1,7 @@
package firewall
import (
"context"
"fmt"
"time"
@@ -24,6 +25,11 @@ const (
denyServingIP = "deny-serving-ip"
)
var (
mtSaveProfile = "save profile"
)
//nolint:gocognit // FIXME
func prompt(comm *network.Communication, link *network.Link, pkt packet.Packet, fqdn string) {
nTTL := time.Duration(promptTimeout()) * time.Second
@@ -66,11 +72,11 @@ func prompt(comm *network.Communication, link *network.Link, pkt packet.Packet,
case comm.Direction: // incoming
n.Message = fmt.Sprintf("Application %s wants to accept connections from %s (on %d/%d)", comm.Process(), pkt.Info().RemoteIP(), pkt.Info().Protocol, pkt.Info().LocalPort())
n.AvailableActions = []*notifications.Action{
&notifications.Action{
{
ID: permitServingIP,
Text: "Permit",
},
&notifications.Action{
{
ID: denyServingIP,
Text: "Deny",
},
@@ -78,11 +84,11 @@ func prompt(comm *network.Communication, link *network.Link, pkt packet.Packet,
case fqdn == "": // direct connection
n.Message = fmt.Sprintf("Application %s wants to connect to %s (on %d/%d)", comm.Process(), pkt.Info().RemoteIP(), pkt.Info().Protocol, pkt.Info().RemotePort())
n.AvailableActions = []*notifications.Action{
&notifications.Action{
{
ID: permitIP,
Text: "Permit",
},
&notifications.Action{
{
ID: denyIP,
Text: "Deny",
},
@@ -94,15 +100,15 @@ func prompt(comm *network.Communication, link *network.Link, pkt packet.Packet,
n.Message = fmt.Sprintf("Application %s wants to connect to %s", comm.Process(), comm.Domain)
}
n.AvailableActions = []*notifications.Action{
&notifications.Action{
{
ID: permitDomainAll,
Text: "Permit all",
},
&notifications.Action{
{
ID: permitDomainDistinct,
Text: "Permit",
},
&notifications.Action{
{
ID: denyDomainDistinct,
Text: "Deny",
},
@@ -182,7 +188,9 @@ func prompt(comm *network.Communication, link *network.Link, pkt packet.Packet,
}
// save!
go userProfile.Save("")
module.StartMicroTask(&mtSaveProfile, func(ctx context.Context) error {
return userProfile.Save("")
})
case <-n.Expired():
if link != nil {