Added firewall testing framework.

Fixed simple bug in fw-prompt that accidentally disabled process scope option.
shw_dev
Stephen Watt 7 years ago
parent 32983deba4
commit 0666e9c3c7

@ -1,5 +1,5 @@
To get this to work, first edit /usr/share/gnome-shell/modes/subgraph.json To get this to work, first edit /usr/share/gnome-shell/modes/subgraph.json
Remove the entry for "firewall@subgraph.com", hit CTRL+F2 and then issue the reload "r" command. Remove the entry for "firewall@subgraph.com", hit ALT+F2 and then issue the reload "r" command.
Reset these changes to revert back to the old gnome-shell prompt. Reset these changes to revert back to the old gnome-shell prompt.

@ -1351,7 +1351,7 @@ func main() {
editPort.SetText(strconv.Itoa(seldata.Port)) editPort.SetText(strconv.Itoa(seldata.Port))
radioOnce.SetActive(seldata.Scope == int(sgfw.APPLY_ONCE)) radioOnce.SetActive(seldata.Scope == int(sgfw.APPLY_ONCE))
radioProcess.SetSensitive(seldata.Scope == int(sgfw.APPLY_PROCESS)) radioProcess.SetActive(seldata.Scope == int(sgfw.APPLY_PROCESS))
radioParent.SetActive(false) radioParent.SetActive(false)
radioSession.SetActive(seldata.Scope == int(sgfw.APPLY_SESSION)) radioSession.SetActive(seldata.Scope == int(sgfw.APPLY_SESSION))
radioPermanent.SetActive(seldata.Scope == int(sgfw.APPLY_FOREVER)) radioPermanent.SetActive(seldata.Scope == int(sgfw.APPLY_FOREVER))

@ -4,6 +4,8 @@ import (
"errors" "errors"
"path" "path"
"strconv" "strconv"
"net"
"time"
"github.com/godbus/dbus" "github.com/godbus/dbus"
"github.com/godbus/dbus/introspect" "github.com/godbus/dbus/introspect"
@ -276,6 +278,38 @@ func (ds *dbusServer) AddRuleAsync(scope uint32, rule, policy, guid string) (boo
return true, nil return true, nil
} }
func (ds *dbusServer) AddTestVPC(proto string, srcip string, sport uint16, dstip string, dport uint16, hostname string) (bool, *dbus.Error) {
log.Warningf("AddTestVPC(proto=%s, srcip=%s, sport=%v, dstip=%s, dport=%v, hostname=%s)\n",
proto, srcip, sport, dstip, dport, hostname)
sip := net.ParseIP(srcip)
if sip == nil {
log.Error("Test virtual rule supplied bad source IP: ", srcip)
return false, nil
}
dip := net.ParseIP(srcip)
if dip == nil {
log.Error("Test virtual rule supplied bad dst IP: ", dstip)
return false, nil
}
now := time.Now()
optstring := "[virtual connection (TEST)]"
pinfo := getEmptyPInfo()
exepath := "/bin/bla"
pid := 666
sandbox := ""
policy := ds.fw.PolicyForPathAndSandbox(GetRealRoot(exepath, pid), sandbox)
vpc := &virtualPkt{_proto: proto, srcip: sip, sport: sport, dstip: dip, dport: dport, name: hostname, timestamp: now, optstring: optstring, pol: policy, pinfo: pinfo}
policy.processPromptResult(vpc)
log.Warning("NEW VPC: ", vpc)
return true, nil
}
func (ds *dbusServer) UpdateRule(rule DbusRule) *dbus.Error { func (ds *dbusServer) UpdateRule(rule DbusRule) *dbus.Error {
log.Debugf("UpdateRule %v", rule) log.Debugf("UpdateRule %v", rule)
ds.fw.lock.Lock() ds.fw.lock.Lock()

@ -89,8 +89,8 @@ func (pp *pendingPkt) sandbox() string {
return pp.pinfo.Sandbox return pp.pinfo.Sandbox
} }
func (pc *pendingPkt) getTimestamp() string { func (pp *pendingPkt) getTimestamp() string {
return pc.timestamp.Format("15:04:05.00") return pp.timestamp.Format("15:04:05.00")
} }
func (pp *pendingPkt) socks() bool { func (pp *pendingPkt) socks() bool {
@ -701,7 +701,7 @@ func GetRealRoot(pathname string, pid int) string {
lnk, err := os.Readlink(pfname) lnk, err := os.Readlink(pfname)
if err != nil { if err != nil {
fmt.Printf("Error reading link at %s: %v", pfname, err) fmt.Printf("Error reading link at %s: %v\n", pfname, err)
return pathname return pathname
} }

@ -0,0 +1,180 @@
package sgfw
import (
"fmt"
"net"
"time"
"sync"
"github.com/subgraph/go-procsnitch"
"github.com/godbus/dbus"
)
type virtualPkt struct {
pol *Policy
name string
pinfo *procsnitch.Info
optstring string
prompting bool
prompter *prompter
guid string
timestamp time.Time
is_socks bool
_proto string
srcip net.IP
sport uint16
dstip net.IP
dport uint16
}
var tdb *dbusObjectP
var tdbMutex = &sync.Mutex{}
var tdbInit = false
func init() {
fmt.Println("Initializing virtual packet test subsystem...")
conn, err := dbus.SystemBus()
if err != nil {
fmt.Println("Error setting up server on test DBus path:", err)
tdb = &dbusObjectP{nil}
}
tdb = &dbusObjectP{conn.Object("com.subgraph.FirewallTest", "/com/subgraph/FirewallTest")}
tdbInit = true
}
func sendSGFWTestAlert(accepted int, guid string, other string) bool {
var dres bool
if !tdbInit {
fmt.Println("Skipping over invocation of SGFWTestAlert(); DBus method was not properly bound")
return false
}
tdbMutex.Lock()
defer tdbMutex.Unlock()
call := tdb.Call("com.subgraph.FirewallTest.SGFWTestAlert", 0, int32(accepted), guid, other)
err := call.Store(&dres)
if err != nil {
fmt.Println("Error sending DBus SGFWTestAlert() notification:", err)
return false
}
return true
}
func (vp *virtualPkt) sandbox() string {
return vp.pinfo.Sandbox
}
func (vp *virtualPkt) getTimestamp() string {
return vp.timestamp.Format("15:04:05.00")
}
func (vp *virtualPkt) socks() bool {
return vp.is_socks
}
func (vp *virtualPkt) policy() *Policy {
return vp.pol
}
func (vp *virtualPkt) procInfo() *procsnitch.Info {
if vp.pinfo == nil {
return getEmptyPInfo()
}
return vp.pinfo
}
func (vp *virtualPkt) getOptString() string {
return vp.optstring
}
func (vp *virtualPkt) hostname() string {
return vp.name
}
func (vp *virtualPkt) src() net.IP {
return vp.srcip
}
func (vp *virtualPkt) dst() net.IP {
return vp.dstip
}
func (vp *virtualPkt) proto() string {
return vp._proto
}
func (vp *virtualPkt) srcPort() uint16 {
return vp.sport
}
func (vp *virtualPkt) dstPort() uint16 {
return vp.dport
}
func (vp *virtualPkt) accept() {
fmt.Println("VIRTUAL PACKET ACCEPTED")
sendSGFWTestAlert(1, vp.getGUID(), "")
}
func (vp *virtualPkt) acceptTLSOnly() {
fmt.Println("VIRTUAL PACKET ACCEPTED (TLSONLY)")
sendSGFWTestAlert(1, vp.getGUID(), "tls")
}
func (vp *virtualPkt) drop() {
fmt.Println("VIRTUAL PACKET DROPPED")
sendSGFWTestAlert(0, vp.getGUID(), "")
}
func (vp *virtualPkt) setPrompter(val *prompter) {
vp.prompter = val
}
func (vp *virtualPkt) getPrompter() *prompter {
return vp.prompter
}
func (vp *virtualPkt) getGUID() string {
if vp.guid == "" {
vp.guid = genGUID()
}
return vp.guid
}
func (vp *virtualPkt) getPrompting() bool {
return vp.prompting
}
func (vp *virtualPkt) setPrompting(val bool) {
vp.prompting = val
}
func (vp *virtualPkt) print() string {
desc := fmt.Sprintf("virtualPkt { src %s:%u, dst %s:%u (%s) proto %s",
vp.srcip, vp.sport, vp.dstip, vp.dport, vp.hostname, vp._proto)
// pinfo excluded
desc += fmt.Sprintf(" socks=%v [policy=%s]", vp.is_socks, vp.pol.application)
desc += fmt.Sprintf(" prompting=%v ts=%s", vp.prompting, vp.getTimestamp())
desc += fmt.Sprintf(" guid=%s [optstring=%s] }", vp.getGUID(), vp.optstring)
return desc
}
func (vp *virtualPkt) SetPacket(proto string, srcip net.IP, sport uint16, dstip net.IP, dport uint16, hostname string) bool {
vp._proto = proto
vp.srcip = srcip
vp.dstip = dstip
vp.sport = sport
vp.dport = dport
vp.name = hostname
return true
}

@ -25,4 +25,14 @@
<allow send_destination="com.subgraph.Firewall" /> <allow send_destination="com.subgraph.Firewall" />
</policy> </policy>
<!-- Only 'user' can own this service -->
<policy user="1000">
<allow own="com.subgraph.FirewallTest"/>
</policy>
<!-- Anyone can send messages to com.subgraph.FirewallTest-->
<policy context="default">
<allow send_destination="com.subgraph.FirewallTest"/>
</policy>
</busconfig> </busconfig>

@ -0,0 +1,77 @@
package main
import (
"errors"
"fmt"
"github.com/godbus/dbus"
)
const busName = "com.subgraph.FirewallTest"
const objectPath = "/com/subgraph/FirewallTest"
const interfaceName = "com.subgraph.FirewallTest"
type dbusObjectP struct {
dbus.BusObject
}
func newDbusObjectAdd() (*dbusObjectP, error) {
conn, err := dbus.SystemBus()
if err != nil {
return nil, err
}
return &dbusObjectP{conn.Object("com.subgraph.Firewall", "/com/subgraph/Firewall")}, nil
}
type dbusServer struct {
conn *dbus.Conn
}
func newDbusServer() (*dbusServer, error) {
conn, err := dbus.SystemBus()
if err != nil {
return nil, err
}
reply, err := conn.RequestName(busName, dbus.NameFlagDoNotQueue)
if err != nil {
return nil, err
}
if reply != dbus.RequestNameReplyPrimaryOwner {
return nil, errors.New("Bus name is already owned")
}
ds := &dbusServer{}
if err := conn.Export(ds, objectPath, interfaceName); err != nil {
return nil, err
}
ds.conn = conn
return ds, nil
}
func (ds *dbusServer) SGFWTestAlert(accepted int32, guid string, other string) (bool, *dbus.Error) {
fmt.Printf("<- SGFWTestAlert(accepted = %v, guid = %s, other=[%s])\n", accepted, guid, other)
return true, nil
}
func CallAddTestVPC(d *dbusObjectP, proto string, srcip string, sport uint16, dstip string, dport uint16, hostname string) bool {
var dres bool
fmt.Printf("CallAddTestVPC(proto=%s, srcip=%s, sport=%u, dstip=%s, dport=%u, hostname=%s)\n",
proto, srcip, sport, dstip, dport, hostname)
call := d.Call("AddTestVPC", 0,
proto, srcip, sport, dstip, dport, hostname)
err := call.Store(&dres)
if err != nil {
fmt.Println("Error sending DBus AddTestVPC() request:", err)
return false
}
return true
}

@ -0,0 +1,36 @@
package main
import (
"fmt"
"log"
"time"
)
var dbuso *dbusObjectP
func main() {
fmt.Println("Starting up test units...")
_, err := newDbusServer()
if err != nil {
log.Fatal("Error:", err)
return
}
dbuso, err := newDbusObjectAdd()
if err != nil {
log.Fatal("Failed to connect to dbus system bus: %v", err)
}
res := CallAddTestVPC(dbuso, "udp", "10.0.0.1", 61921, "8.8.8.8", 53, "dnsthing.google.com")
fmt.Println("res =", res)
fmt.Println("Waiting until interrupted...")
for true {
time.Sleep(1 * time.Second)
}
}
Loading…
Cancel
Save