Bug fixes, cleanup, improvement

shw_dev
dma 7 years ago
parent d2ff760197
commit 7b5a0ed980

@ -175,6 +175,7 @@ func (pp *pendingPkt) print() string {
type Policy struct { type Policy struct {
fw *Firewall fw *Firewall
path string path string
sandbox string
application string application string
icon string icon string
rules RuleList rules RuleList
@ -190,6 +191,32 @@ func (fw *Firewall) PolicyForPath(path string) *Policy {
return fw.policyForPath(path) return fw.policyForPath(path)
} }
func (fw *Firewall) PolicyForPathAndSandbox(path string, sandbox string) *Policy {
fw.lock.Lock()
defer fw.lock.Unlock()
return fw.policyForPathAndSandbox(path, sandbox)
}
func (fw *Firewall) policyForPathAndSandbox(path string, sandbox string) *Policy {
policykey := sandbox + "|" + path
if _, ok := fw.policyMap[policykey]; !ok {
p := new(Policy)
p.fw = fw
p.path = path
p.application = path
p.sandbox = sandbox
entry := entryForPath(path)
if entry != nil {
p.application = entry.name
p.icon = entry.icon
}
fw.policyMap[policykey] = p
fw.policies = append(fw.policies, p)
}
return fw.policyMap[policykey]
}
func (fw *Firewall) policyForPath(path string) *Policy { func (fw *Firewall) policyForPath(path string) *Policy {
if _, ok := fw.policyMap[path]; !ok { if _, ok := fw.policyMap[path]; !ok {
p := new(Policy) p := new(Policy)
@ -338,7 +365,7 @@ func (p *Policy) removeRule(r *Rule) {
func (p *Policy) filterPending(rule *Rule) { func (p *Policy) filterPending(rule *Rule) {
remaining := []pendingConnection{} remaining := []pendingConnection{}
for _, pc := range p.pendingQueue { for _, pc := range p.pendingQueue {
if rule.match(pc.src(), pc.dst(), pc.dstPort(), pc.hostname(), pc.proto(), pc.procInfo().UID, pc.procInfo().GID, uidToUser(pc.procInfo().UID), gidToGroup(pc.procInfo().GID), pc.procInfo().Sandbox) { if rule.match(pc.src(), pc.dst(), pc.dstPort(), pc.hostname(), pc.proto(), pc.procInfo().UID, pc.procInfo().GID, uidToUser(pc.procInfo().UID), gidToGroup(pc.procInfo().GID)) {
log.Infof("Adding rule for: %s", rule.getString(FirewallConfig.LogRedact)) log.Infof("Adding rule for: %s", rule.getString(FirewallConfig.LogRedact))
log.Noticef("%s > %s", rule.getString(FirewallConfig.LogRedact), pc.print()) log.Noticef("%s > %s", rule.getString(FirewallConfig.LogRedact), pc.print())
if rule.rtype == RULE_ACTION_ALLOW { if rule.rtype == RULE_ACTION_ALLOW {
@ -475,7 +502,7 @@ func (fw *Firewall) filterPacket(pkt *nfqueue.NFQPacket) {
return return
} }
*/ */
policy := fw.PolicyForPath(ppath) policy := fw.PolicyForPathAndSandbox(ppath,pinfo.Sandbox)
//log.Notice("XXX: flunked basicallowpacket; policy = ", policy) //log.Notice("XXX: flunked basicallowpacket; policy = ", policy)
policy.processPacket(pkt, pinfo, optstring) policy.processPacket(pkt, pinfo, optstring)
} }
@ -548,7 +575,7 @@ func getAllProcNetDataLocal() ([]string, error) {
return rlines, nil return rlines, nil
} }
func getRealRoot(pathname string, pid int) string { func GetRealRoot(pathname string, pid int) string {
pfname := fmt.Sprintf("/proc/%d/root", pid) pfname := fmt.Sprintf("/proc/%d/root", pid)
lnk, err := os.Readlink(pfname) lnk, err := os.Readlink(pfname)
@ -611,7 +638,7 @@ func LookupSandboxProc(srcip net.IP, srcp uint16, dstip net.IP, dstp uint16, pro
if res != nil { if res != nil {
// optstr = "Sandbox: " + OzInitPids[i].Name // optstr = "Sandbox: " + OzInitPids[i].Name
res.Sandbox = OzInitPids[i].Name res.Sandbox = OzInitPids[i].Name
res.ExePath = getRealRoot(res.ExePath, OzInitPids[i].Pid) res.ExePath = GetRealRoot(res.ExePath, OzInitPids[i].Pid)
break break
} }
} }
@ -710,7 +737,7 @@ func findProcessForPacket(pkt *nfqueue.NFQPacket, reverse bool, strictness int)
if res != nil { if res != nil {
optstr = "Sandbox: " + OzInitPids[i].Name optstr = "Sandbox: " + OzInitPids[i].Name
res.ExePath = getRealRoot(res.ExePath, OzInitPids[i].Pid) res.ExePath = GetRealRoot(res.ExePath, OzInitPids[i].Pid)
break break
} }
} }

@ -38,11 +38,11 @@ type prompter struct {
func (p *prompter) prompt(policy *Policy) { func (p *prompter) prompt(policy *Policy) {
p.lock.Lock() p.lock.Lock()
defer p.lock.Unlock() defer p.lock.Unlock()
_, ok := p.policyMap[policy.path] _, ok := p.policyMap[policy.sandbox + "|" + policy.path]
if ok { if ok {
return return
} }
p.policyMap[policy.path] = policy p.policyMap[policy.sandbox + "|" + policy.path] = policy
p.policyQueue = append(p.policyQueue, policy) p.policyQueue = append(p.policyQueue, policy)
p.cond.Signal() p.cond.Signal()
} }
@ -268,7 +268,7 @@ func (p *prompter) removePolicy(policy *Policy) {
} }
} }
p.policyQueue = newQueue p.policyQueue = newQueue
delete(p.policyMap, policy.path) delete(p.policyMap, policy.sandbox + "|" + policy.path)
} }
var userMap = make(map[int]string) var userMap = make(map[int]string)

@ -105,7 +105,7 @@ func (r *Rule) AddrString(redact bool) string {
type RuleList []*Rule type RuleList []*Rule
func (r *Rule) match(src net.IP, dst net.IP, dstPort uint16, hostname string, proto string, uid, gid int, uname, gname string, sandbox string) bool { func (r *Rule) match(src net.IP, dst net.IP, dstPort uint16, hostname string, proto string, uid, gid int, uname, gname string) bool {
if r.proto != proto { if r.proto != proto {
return false return false
} }
@ -127,6 +127,7 @@ func (r *Rule) match(src net.IP, dst net.IP, dstPort uint16, hostname string, pr
return true return true
} }
if r.hostname != "" { if r.hostname != "" {
log.Notice("comparing hostname")
if strings.ContainsAny(r.hostname, "*") { if strings.ContainsAny(r.hostname, "*") {
regstr := strings.Replace(r.hostname, "*", ".?", -1) regstr := strings.Replace(r.hostname, "*", ".?", -1)
match, err := regexp.MatchString(regstr, hostname) match, err := regexp.MatchString(regstr, hostname)
@ -168,25 +169,33 @@ func (rl *RuleList) filter(pkt *nfqueue.NFQPacket, src, dst net.IP, dstPort uint
} }
// sandboxed := strings.HasPrefix(optstr, "SOCKS5|Tor / Sandbox") // sandboxed := strings.HasPrefix(optstr, "SOCKS5|Tor / Sandbox")
for _, r := range *rl { for _, r := range *rl {
log.Notice("fuck ",r) log.Notice("fuck ",r)
nfqproto := ""
log.Notice("------------ trying match of src ", src, " against: ", r, " | ", r.saddr, " / optstr = ", optstr, "; pid ", pinfo.Pid, " vs rule pid ", r.pid) log.Notice("------------ trying match of src ", src, " against: ", r, " | ", r.saddr, " / optstr = ", optstr, "; pid ", pinfo.Pid, " vs rule pid ", r.pid)
log.Notice("r.saddr: ", r.saddr, "src: ", src, "sandboxed ", sandboxed, "optstr: ", optstr) log.Notice("r.saddr: ", r.saddr, "src: ", src, "sandboxed ", sandboxed, "optstr: ", optstr)
if r.saddr == nil && src != nil && sandboxed { if r.saddr == nil && src != nil && sandboxed {
log.Notice("! Skipping comparison against incompatible rule types: rule src = ", r.saddr, " / packet src = ", src) log.Notice("! Skipping comparison against incompatible rule types: rule src = ", r.saddr, " / packet src = ", src)
continue // continue
} else if r.saddr == nil && src == nil && sandboxed { } else if r.saddr == nil && src == nil && sandboxed {
continue // continue
// r.match(src, dst, dstPort, hostname, nil, pinfo.UID, pinfo.GID, uidToUser(pinfo.UID), gidToGroup(pinfo.GID))
nfqproto = "tcp"
} else if r.saddr != nil && !r.saddr.Equal(src) && r.proto != "icmp" { } else if r.saddr != nil && !r.saddr.Equal(src) && r.proto != "icmp" {
log.Notice("! Skipping comparison of mismatching source ips") log.Notice("! Skipping comparison of mismatching source ips")
continue continue
} else {
if pkt != nil {
nfqproto = getNFQProto(pkt)
} else {
log.Notice("Weird state.")
}
} }
log.Notice("r.saddr = ", r.saddr, "src = ", src, "\n") log.Notice("r.saddr = ", r.saddr, "src = ", src, "\n")
if r.pid >= 0 && r.pid != pinfo.Pid { if r.pid >= 0 && r.pid != pinfo.Pid {
//log.Notice("! Skipping comparison of mismatching PIDs") //log.Notice("! Skipping comparison of mismatching PIDs")
continue continue
} }
if r.match(src, dst, dstPort, hostname, getNFQProto(pkt), pinfo.UID, pinfo.GID, uidToUser(pinfo.UID), gidToGroup(pinfo.GID), pinfo.Sandbox) { if r.match(src, dst, dstPort, hostname, nfqproto, pinfo.UID, pinfo.GID, uidToUser(pinfo.UID), gidToGroup(pinfo.GID)) {
log.Notice("+ MATCH SUCCEEDED") log.Notice("+ MATCH SUCCEEDED")
dstStr := dst.String() dstStr := dst.String()
if FirewallConfig.LogRedact { if FirewallConfig.LogRedact {
@ -211,11 +220,16 @@ func (rl *RuleList) filter(pkt *nfqueue.NFQPacket, src, dst net.IP, dstPort uint
return FILTER_DENY return FILTER_DENY
} else if r.rtype == RULE_ACTION_ALLOW { } else if r.rtype == RULE_ACTION_ALLOW {
result = FILTER_ALLOW result = FILTER_ALLOW
return result
/*
if r.saddr != nil { if r.saddr != nil {
return result return result
} }
} */
} else if r.rtype == RULE_ACTION_ALLOW_TLSONLY {
result = FILTER_ALLOW_TLSONLY
return result
}
} else { } else {
log.Notice("+ MATCH FAILED") log.Notice("+ MATCH FAILED")
} }
@ -425,8 +439,8 @@ func savePolicy(f *os.File, p *Policy) {
if !p.hasPersistentRules() { if !p.hasPersistentRules() {
return return
} }
log.Warningf("p.path: ",p.path)
if !writeLine(f, "["+p.path+"]") { if !writeLine(f, "["+p.sandbox+"|"+p.path+"]") {
return return
} }
for _, r := range p.rules { for _, r := range p.rules {
@ -479,8 +493,9 @@ func (fw *Firewall) loadRules() {
} }
func (fw *Firewall) processPathLine(line string) *Policy { func (fw *Firewall) processPathLine(line string) *Policy {
path := line[1 : len(line)-1] pathLine := line[1 : len(line)-1]
policy := fw.policyForPath(path) toks := strings.Split(pathLine, "|")
policy := fw.policyForPathAndSandbox(toks[1],toks[0])
policy.lock.Lock() policy.lock.Lock()
defer policy.lock.Unlock() defer policy.lock.Unlock()
policy.rules = nil policy.rules = nil
@ -489,7 +504,7 @@ func (fw *Firewall) processPathLine(line string) *Policy {
func processRuleLine(policy *Policy, line string) { func processRuleLine(policy *Policy, line string) {
if policy == nil { if policy == nil {
log.Warningf("Cannot process rule line without first seeing path line: %s", line) log.Warningf("Cannot process rule line without first seeing policy key line: %s", line)
return return
} }
_, err := policy.parseRule(line, true) _, err := policy.parseRule(line, true)

@ -36,6 +36,7 @@ type socksChainSession struct {
bndAddr *Address bndAddr *Address
optData []byte optData []byte
procInfo procsnitch.ProcInfo procInfo procsnitch.ProcInfo
pinfo *procsnitch.Info
server *socksChain server *socksChain
} }
@ -287,13 +288,16 @@ func (c *socksChainSession) filterConnect() (bool, bool) {
return false, false return false, false
} }
c.pinfo = pinfo
if optstr == "" { if optstr == "" {
optstr = "Via SOCKS5: " + c.cfg.Name optstr = "Via SOCKS5: " + c.cfg.Name
} else { } else {
optstr = "[Via SOCKS5: " + c.cfg.Name + "] " + optstr optstr = "[Via SOCKS5: " + c.cfg.Name + "] " + optstr
} }
policy := c.server.fw.PolicyForPath(pinfo.ExePath) log.Warningf("Lookup policy for %v %v",pinfo.ExePath,pinfo.Sandbox)
policy := c.server.fw.PolicyForPathAndSandbox(GetRealRoot(pinfo.ExePath,pinfo.Pid),pinfo.Sandbox)
hostname, ip, port := c.addressDetails() hostname, ip, port := c.addressDetails()
if ip == nil && hostname == "" { if ip == nil && hostname == "" {
@ -387,7 +391,11 @@ func (c *socksChainSession) forwardTraffic(tls bool) {
err := TLSGuard(c.clientConn, c.upstreamConn, c.req.Addr.addrStr) err := TLSGuard(c.clientConn, c.upstreamConn, c.req.Addr.addrStr)
if err != nil { if err != nil {
log.Error("Dropping traffic due to TLSGuard violation: ", err) if c.pinfo.Sandbox != "" {
log.Errorf("Dropping traffic from %s (sandbox: %s) to %s due to TLSGuard violation: %v", c.pinfo.ExePath, c.pinfo.Sandbox, c.req.Addr.addrStr, err)
} else {
log.Errorf("Dropping traffic from %s (unsandboxed) to %s due to TLSGuard violation: %v", c.pinfo.ExePath, c.req.Addr.addrStr, err)
}
return return
} else { } else {
log.Notice("TLSGuard approved certificate presented for connection to: ", c.req.Addr.addrStr) log.Notice("TLSGuard approved certificate presented for connection to: ", c.req.Addr.addrStr)

Loading…
Cancel
Save