diff --git a/fw-prompt/README.txt b/fw-prompt/README.txt
index deece26..8a7d344 100644
--- a/fw-prompt/README.txt
+++ b/fw-prompt/README.txt
@@ -1,5 +1,5 @@
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.
diff --git a/fw-prompt/fw-prompt.go b/fw-prompt/fw-prompt.go
index 38f73d0..8db4389 100644
--- a/fw-prompt/fw-prompt.go
+++ b/fw-prompt/fw-prompt.go
@@ -1351,7 +1351,7 @@ func main() {
editPort.SetText(strconv.Itoa(seldata.Port))
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)
radioSession.SetActive(seldata.Scope == int(sgfw.APPLY_SESSION))
radioPermanent.SetActive(seldata.Scope == int(sgfw.APPLY_FOREVER))
diff --git a/sgfw/dbus.go b/sgfw/dbus.go
index fed6100..1e40396 100644
--- a/sgfw/dbus.go
+++ b/sgfw/dbus.go
@@ -4,6 +4,8 @@ import (
"errors"
"path"
"strconv"
+ "net"
+ "time"
"github.com/godbus/dbus"
"github.com/godbus/dbus/introspect"
@@ -276,6 +278,38 @@ func (ds *dbusServer) AddRuleAsync(scope uint32, rule, policy, guid string) (boo
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 {
log.Debugf("UpdateRule %v", rule)
ds.fw.lock.Lock()
diff --git a/sgfw/policy.go b/sgfw/policy.go
index 4f144c4..2fbb486 100644
--- a/sgfw/policy.go
+++ b/sgfw/policy.go
@@ -89,8 +89,8 @@ func (pp *pendingPkt) sandbox() string {
return pp.pinfo.Sandbox
}
-func (pc *pendingPkt) getTimestamp() string {
- return pc.timestamp.Format("15:04:05.00")
+func (pp *pendingPkt) getTimestamp() string {
+ return pp.timestamp.Format("15:04:05.00")
}
func (pp *pendingPkt) socks() bool {
@@ -701,7 +701,7 @@ func GetRealRoot(pathname string, pid int) string {
lnk, err := os.Readlink(pfname)
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
}
diff --git a/sgfw/virtual.go b/sgfw/virtual.go
new file mode 100644
index 0000000..7754fed
--- /dev/null
+++ b/sgfw/virtual.go
@@ -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
+}
diff --git a/sources/etc/dbus-1/system.d/com.subgraph.Firewall.conf b/sources/etc/dbus-1/system.d/com.subgraph.Firewall.conf
index fc5e02d..e71afd8 100644
--- a/sources/etc/dbus-1/system.d/com.subgraph.Firewall.conf
+++ b/sources/etc/dbus-1/system.d/com.subgraph.Firewall.conf
@@ -25,4 +25,14 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/testfw/dbus.go b/testfw/dbus.go
new file mode 100644
index 0000000..9f2fba2
--- /dev/null
+++ b/testfw/dbus.go
@@ -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
+}
diff --git a/testfw/testfw.go b/testfw/testfw.go
new file mode 100644
index 0000000..d972f38
--- /dev/null
+++ b/testfw/testfw.go
@@ -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)
+ }
+
+}