From 9069c91606d835997a38141b3fa5415ea73e8fff Mon Sep 17 00:00:00 2001 From: shw Date: Tue, 18 Apr 2017 17:43:36 +0000 Subject: [PATCH] Garbage dump commit of current progress. --- sgfw/dns.go | 1 + sgfw/ipc.go | 45 ++++++++++++++++++++++++++------------ sgfw/policy.go | 33 ++++++++++++++++++---------- sgfw/prompt.go | 4 ++++ sgfw/rules.go | 39 ++++++++++++++++++++++++++++----- sgfw/sgfw.go | 2 +- sgfw/socks_server_chain.go | 2 +- 7 files changed, 93 insertions(+), 33 deletions(-) diff --git a/sgfw/dns.go b/sgfw/dns.go index 8687a95..98faa0d 100644 --- a/sgfw/dns.go +++ b/sgfw/dns.go @@ -55,6 +55,7 @@ func (dc *dnsCache) processRecordA(name string, answers []dnsRR) { if strings.HasSuffix(name, ".") { name = name[:len(name)-1] } + log.Notice("______ Adding to dns map: %s: %s", name, ip) dc.ipMap[ip] = name if !FirewallConfig.LogRedact { log.Infof("Adding %s: %s", name, ip) diff --git a/sgfw/ipc.go b/sgfw/ipc.go index e66e3ba..dc7e863 100644 --- a/sgfw/ipc.go +++ b/sgfw/ipc.go @@ -38,7 +38,23 @@ func ruleExists(rule sandboxRule) int { return -1 } -func ReceiverLoop(c net.Conn) { +func addFWRule(fw *Firewall, whitelist bool, srchost, dsthost string, dstport uint16) error { + policy := fw.PolicyForPath("*") + rulestr := "" + + if whitelist { + rulestr += "ALLOW" + } else { + rulestr += "DENY" + } + + rulestr += "|" + dsthost + ":" + strconv.Itoa(int(dstport)) + "|SESSION|" + srchost + _, err := policy.parseRule(rulestr, true) + + return err +} + +func ReceiverLoop(fw *Firewall, c net.Conn) { defer c.Close() bio := bufio.NewReader(c) @@ -104,21 +120,16 @@ func ReceiverLoop(c net.Conn) { w = false } - srcip := net.ParseIP(tokens[2]) + srchost := tokens[2] + dsthost := tokens[3] + srcip := net.ParseIP(srchost) if srcip == nil { - log.Notice("IPC received invalid source host: ", tokens[2]) - c.Write([]byte("Bad command: source host address was invalid")) - return + log.Notice("IP conversion failed: ", srchost) + srcip = net.IP{0,0,0,0} } - dstip := net.ParseIP(tokens[3]) - - if dstip == nil { - log.Notice("IPC received invalid destination host: ", tokens[3]) - c.Write([]byte("Bad command: dst host address was invalid")) - return - } + dstip := net.IP{0,0,0,0} dstport, err := strconv.Atoi(tokens[4]) @@ -151,6 +162,12 @@ func ReceiverLoop(c net.Conn) { if add { log.Notice("Adding new rule to oz sandbox/fw: ", rule) sandboxRules = append(sandboxRules, rule) + err := addFWRule(fw, w, srchost, dsthost, uint16(dstport)) + if err != nil { + log.Error("Error adding dynamic OZ firewall rule to fw-daemon: ", err) + } else { + log.Notice("XXX: rule also successfully added to fw-daemon") + } } else { log.Notice("Removing new rule from oz sandbox/fw: ", rule) sandboxRules = append(sandboxRules[:exists], sandboxRules[exists+1:]...) @@ -167,7 +184,7 @@ func ReceiverLoop(c net.Conn) { } -func OzReceiver() { +func OzReceiver(fw *Firewall) { log.Notice("XXX: dispatching oz receiver...") os.Remove(ReceiverSocketPath) lfd, err := net.Listen("unix", ReceiverSocketPath) @@ -181,7 +198,7 @@ func OzReceiver() { log.Fatal("Could not accept receiver client:", err) } - go ReceiverLoop(fd) + go ReceiverLoop(fw, fd) } } diff --git a/sgfw/policy.go b/sgfw/policy.go index e8570e3..8ad5ecb 100644 --- a/sgfw/policy.go +++ b/sgfw/policy.go @@ -29,7 +29,7 @@ type sandboxRule struct { } var sandboxRules = []sandboxRule { - { net.IP{172,16,1,42}, net.IP{140,211,166,134}, 21, false }, +// { net.IP{172,16,1,42}, net.IP{140,211,166,134}, 21, false }, } type pendingConnection interface { @@ -168,14 +168,22 @@ func (p *Policy) processPacket(pkt *nfqueue.NFQPacket, pinfo *procsnitch.Info) { dstb := pkt.Packet.NetworkLayer().NetworkFlow().Dst().Raw() dstip := net.IP(dstb) srcip := net.IP(pkt.Packet.NetworkLayer().NetworkFlow().Src().Raw()) - _, dstp := getPacketPorts(pkt) +// _, dstp := getPacketPorts(pkt) name := p.fw.dns.Lookup(dstip) if !FirewallConfig.LogRedact { log.Infof("Lookup(%s): %s", dstip.String(), name) } - fwo := matchAgainstOzRules(srcip, dstip, dstp) -log.Notice("XXX: Attempting to filter packet on rules -> ", fwo) - result := p.rules.filterPacket(pkt, pinfo, name) +// fwo := matchAgainstOzRules(srcip, dstip, dstp) + +if name == "" { +/* log.Notice("XXXXXXXXXXXXx trying better rev lookup:") + net.LookupAddr(dstip.String()) + name = p.fw.dns.Lookup(dstip) + log.Notice("NOW ITS: ", name) */ +} + +//log.Notice("XXX: Attempting to filter packet on rules -> ", fwo, " / rev lookup = ", name) + result := p.rules.filterPacket(pkt, pinfo, srcip, name) switch result { case FILTER_DENY: pkt.SetMark(1) @@ -238,6 +246,7 @@ func (p *Policy) processNewRule(r *Rule, scope FilterScope) bool { } func (p *Policy) parseRule(s string, add bool) (*Rule, error) { +log.Noticef("XXX: attempt to parse rule: |%s|\n", s) r := new(Rule) r.mode = RULE_MODE_PERMANENT r.policy = p @@ -269,7 +278,7 @@ func (p *Policy) removeRule(r *Rule) { func (p *Policy) filterPending(rule *Rule) { remaining := []pendingConnection{} for _, pc := range p.pendingQueue { - if rule.match(pc.dst(), pc.dstPort(), pc.hostname()) { + if rule.match(pc.src(), pc.dst(), pc.dstPort(), pc.hostname()) { log.Infof("Adding rule for: %s", rule.getString(FirewallConfig.LogRedact)) log.Noticef("%s > %s", rule.getString(FirewallConfig.LogRedact), pc.print()) if rule.rtype == RULE_ACTION_ALLOW { @@ -340,8 +349,8 @@ func (fw *Firewall) filterPacket(pkt *nfqueue.NFQPacket) { } } - srcip, dstip := getPacketIP4Addrs(pkt) - _, dstp := getPacketPorts(pkt) + _, dstip := getPacketIP4Addrs(pkt) +/* _, dstp := getPacketPorts(pkt) fwo := matchAgainstOzRules(srcip, dstip, dstp) log.Notice("XXX: Attempting [2] to filter packet on rules -> ", fwo) @@ -354,7 +363,7 @@ func (fw *Firewall) filterPacket(pkt *nfqueue.NFQPacket) { pkt.SetMark(1) pkt.Accept() return - } + } */ ppath := "*" @@ -380,9 +389,11 @@ func (fw *Firewall) filterPacket(pkt *nfqueue.NFQPacket) { log.Debugf("filterPacket [%s] %s", ppath, printPacket(pkt, fw.dns.Lookup(dstip), nil)) if basicAllowPacket(pkt) { pkt.Accept() +//log.Notice("XXX: passed basicallowpacket") return } policy := fw.PolicyForPath(ppath) +//log.Notice("XXX: flunked basicallowpacket; policy = ", policy) policy.processPacket(pkt, pinfo) } @@ -452,7 +463,7 @@ func getPacketPorts(pkt *nfqueue.NFQPacket) (uint16, uint16) { return s, d } -func matchAgainstOzRules(srci, dsti net.IP, dstp uint16) int { +/*func matchAgainstOzRules(srci, dsti net.IP, dstp uint16) int { for i := 0; i < len(sandboxRules); i++ { @@ -468,4 +479,4 @@ func matchAgainstOzRules(srci, dsti net.IP, dstp uint16) int { } return OZ_FWRULE_NONE -} +} */ diff --git a/sgfw/prompt.go b/sgfw/prompt.go index d26f19e..5b09c10 100644 --- a/sgfw/prompt.go +++ b/sgfw/prompt.go @@ -89,6 +89,10 @@ func (p *prompter) processConnection(pc pendingConnection) { return } + if pc.src() != nil { + rule += "|" + pc.src().String() + } + r, err := policy.parseRule(rule, false) if err != nil { log.Warningf("Error parsing rule string returned from dbus RequestPrompt: %v", err) diff --git a/sgfw/rules.go b/sgfw/rules.go index 5af6e66..a9c2f71 100644 --- a/sgfw/rules.go +++ b/sgfw/rules.go @@ -26,6 +26,7 @@ type Rule struct { rtype RuleAction hostname string addr uint32 + saddr net.IP port uint16 } @@ -70,7 +71,11 @@ func (r *Rule) AddrString(redact bool) string { type RuleList []*Rule -func (r *Rule) match(dst net.IP, dstPort uint16, hostname string) bool { +func (r *Rule) match(src net.IP, dst net.IP, dstPort uint16, hostname string) bool { + +xip := make(net.IP, 4) +binary.BigEndian.PutUint32(xip, r.addr) +log.Notice("comparison: ", hostname, " / ", dst, " : ", dstPort, " -> ", xip, " : ", r.port) if r.port != matchAny && r.port != dstPort { return false } @@ -83,19 +88,29 @@ func (r *Rule) match(dst net.IP, dstPort uint16, hostname string) bool { return r.addr == binary.BigEndian.Uint32(dst.To4()) } -func (rl *RuleList) filterPacket(p *nfqueue.NFQPacket, pinfo *procsnitch.Info, hostname string) FilterResult { +func (rl *RuleList) filterPacket(p *nfqueue.NFQPacket, pinfo *procsnitch.Info, srcip net.IP, hostname string) FilterResult { _, dstip := getPacketIP4Addrs(p) _, dstp := getPacketPorts(p) - return rl.filter(p, dstip, dstp, hostname, pinfo) + return rl.filter(p, srcip, dstip, dstp, hostname, pinfo) } -func (rl *RuleList) filter(pkt *nfqueue.NFQPacket, dst net.IP, dstPort uint16, hostname string, pinfo *procsnitch.Info) FilterResult { +func (rl *RuleList) filter(pkt *nfqueue.NFQPacket, src, dst net.IP, dstPort uint16, hostname string, pinfo *procsnitch.Info) FilterResult { if rl == nil { return FILTER_PROMPT } result := FILTER_PROMPT +// saddr_ip := make(net.IP, 4) +// binary.BigEndian.PutUint32(saddr_ip, r.saddr) for _, r := range *rl { - if r.match(dst, dstPort, hostname) { +log.Notice("------------ trying match of src ", src, " against: ", r, " | ", r.saddr) + if r.saddr == nil && src != nil { +log.Notice("! Skipping comparison against incompatible rule types: rule src = ", r.saddr, " / packet src = ", src) + continue + } else if r.saddr != nil && !r.saddr.Equal(src) { +log.Notice("! Skipping comparison of mismatching source ips") + } + if r.match(src, dst, dstPort, hostname) { +log.Notice("+ MATCH SUCCEEDED") dstStr := dst.String() if FirewallConfig.LogRedact { dstStr = STR_REDACTED @@ -116,8 +131,9 @@ func (rl *RuleList) filter(pkt *nfqueue.NFQPacket, dst net.IP, dstPort uint16, h } else if r.rtype == RULE_ACTION_ALLOW { result = FILTER_ALLOW } - } + } else { log.Notice("+ MATCH FAILED") } } +log.Notice("--- RESULT = ", result) return result } @@ -127,13 +143,24 @@ func parseError(s string) error { func (r *Rule) parse(s string) bool { r.addr = noAddress + r.saddr = nil parts := strings.Split(s, "|") if len(parts) < 2 { return false } if len(parts) >= 3 && parts[2] == "SYSTEM" { r.mode = RULE_MODE_SYSTEM + + if len(parts) > 4 { + r.saddr = net.ParseIP(parts[3]) + } + + } else if len(parts) > 3 { + r.saddr = net.ParseIP(parts[3]) + } else if len(parts) > 2 { + r.saddr = net.ParseIP(parts[2]) } + fmt.Println("----- rule parser: srcip = ", r.saddr) return r.parseVerb(parts[0]) && r.parseTarget(parts[1]) } diff --git a/sgfw/sgfw.go b/sgfw/sgfw.go index 1a84724..508f082 100644 --- a/sgfw/sgfw.go +++ b/sgfw/sgfw.go @@ -223,7 +223,7 @@ func Main() { log.Notice("Did not find SOCKS5 configuration file at", defaultSocksCfgPath, "; ignoring subsystem...") } - go OzReceiver() + go OzReceiver(fw) fw.runFilter() diff --git a/sgfw/socks_server_chain.go b/sgfw/socks_server_chain.go index 8a7172e..338299a 100644 --- a/sgfw/socks_server_chain.go +++ b/sgfw/socks_server_chain.go @@ -193,7 +193,7 @@ func (c *socksChainSession) filterConnect() bool { if ip == nil && hostname == "" { return false } - result := policy.rules.filter(nil, ip, port, hostname, pinfo) + result := policy.rules.filter(nil, nil, ip, port, hostname, pinfo) switch result { case FILTER_DENY: return false