shw-merge
xSmurf 7 years ago
parent 68e6d57c9b
commit 6e6e265fae

@ -1,12 +1,12 @@
package main package main
import ( import (
"fmt"
"flag" "flag"
"strconv" "fmt"
"io" "io"
"log" "log"
"net" "net"
"strconv"
) )
const ReceiverSocketPath = "/var/run/fw-daemon/fwoz.sock" const ReceiverSocketPath = "/var/run/fw-daemon/fwoz.sock"
@ -19,8 +19,8 @@ func reader(r io.Reader) {
if err != nil { if err != nil {
return return
} }
fmt.Println(string(buf[0:n])) fmt.Println(string(buf[0:n]))
} }
} }
func main() { func main() {
@ -87,4 +87,3 @@ func main() {
} }
} }

@ -4,13 +4,12 @@ import (
"errors" "errors"
"github.com/godbus/dbus" "github.com/godbus/dbus"
"log" "log"
// "github.com/gotk3/gotk3/glib" // "github.com/gotk3/gotk3/glib"
) )
type dbusServer struct { type dbusServer struct {
conn *dbus.Conn conn *dbus.Conn
run bool run bool
} }
type promptData struct { type promptData struct {
@ -34,7 +33,6 @@ type promptData struct {
Action int Action int
} }
func newDbusServer() (*dbusServer, error) { func newDbusServer() (*dbusServer, error) {
conn, err := dbus.SystemBus() conn, err := dbus.SystemBus()
@ -65,7 +63,7 @@ func newDbusServer() (*dbusServer, error) {
} }
func (ds *dbusServer) RequestPrompt(application, icon, path, address string, port int32, ip, origin, proto string, uid, gid int32, username, groupname string, pid int32, sandbox string, func (ds *dbusServer) RequestPrompt(application, icon, path, address string, port int32, ip, origin, proto string, uid, gid int32, username, groupname string, pid int32, sandbox string,
optstring string, expanded, expert bool, action int32) (int32, string, *dbus.Error) { optstring string, expanded, expert bool, action int32) (int32, string, *dbus.Error) {
log.Printf("request prompt: app = %s, icon = %s, path = %s, address = %s, action = %v\n", application, icon, path, address, action) log.Printf("request prompt: app = %s, icon = %s, path = %s, address = %s, action = %v\n", application, icon, path, address, action)
decision := addRequest(nil, path, proto, int(pid), ip, address, int(port), int(uid), int(gid), origin, optstring, sandbox) decision := addRequest(nil, path, proto, int(pid), ip, address, int(port), int(uid), int(gid), origin, optstring, sandbox)
log.Print("Waiting on decision...") log.Print("Waiting on decision...")
@ -75,6 +73,6 @@ func (ds *dbusServer) RequestPrompt(application, icon, path, address string, por
} }
log.Print("Decision returned: ", decision.Rule) log.Print("Decision returned: ", decision.Rule)
decision.Cond.L.Unlock() decision.Cond.L.Unlock()
// glib.IdleAdd(func, data) // glib.IdleAdd(func, data)
return int32(decision.Scope), decision.Rule, nil return int32(decision.Scope), decision.Rule, nil
} }

@ -1,37 +1,35 @@
package main package main
import ( import (
"github.com/gotk3/gotk3/gtk" "encoding/json"
"errors"
"fmt"
"github.com/gotk3/gotk3/glib" "github.com/gotk3/gotk3/glib"
"github.com/gotk3/gotk3/gtk"
"io/ioutil"
"log" "log"
"fmt"
"strings"
"strconv"
"os" "os"
"io/ioutil"
"encoding/json"
"os/user" "os/user"
"strconv"
"strings"
"sync" "sync"
"errors"
"github.com/subgraph/fw-daemon/sgfw" "github.com/subgraph/fw-daemon/sgfw"
) )
type fpPreferences struct { type fpPreferences struct {
Winheight uint Winheight uint
Winwidth uint Winwidth uint
Wintop uint Wintop uint
Winleft uint Winleft uint
} }
type decisionWaiter struct { type decisionWaiter struct {
Cond *sync.Cond Cond *sync.Cond
Lock sync.Locker Lock sync.Locker
Ready bool Ready bool
Scope int Scope int
Rule string Rule string
} }
type ruleColumns struct { type ruleColumns struct {
@ -46,10 +44,9 @@ type ruleColumns struct {
Uname string Uname string
Gname string Gname string
Origin string Origin string
Scope int Scope int
} }
var userPrefs fpPreferences var userPrefs fpPreferences
var mainWin *gtk.Window var mainWin *gtk.Window
var Notebook *gtk.Notebook var Notebook *gtk.Notebook
@ -63,7 +60,6 @@ var radioOnce, radioProcess, radioParent, radioSession, radioPermanent *gtk.Radi
var btnApprove, btnDeny, btnIgnore *gtk.Button var btnApprove, btnDeny, btnIgnore *gtk.Button
var chkUser, chkGroup *gtk.CheckButton var chkUser, chkGroup *gtk.CheckButton
func dumpDecisions() { func dumpDecisions() {
fmt.Println("XXX Total of decisions pending: ", len(decisionWaiters)) fmt.Println("XXX Total of decisions pending: ", len(decisionWaiters))
for i := 0; i < len(decisionWaiters); i++ { for i := 0; i < len(decisionWaiters); i++ {
@ -80,7 +76,7 @@ func addDecision() *decisionWaiter {
func promptInfo(msg string) { func promptInfo(msg string) {
dialog := gtk.MessageDialogNew(mainWin, 0, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, "Displaying full log info:") dialog := gtk.MessageDialogNew(mainWin, 0, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, "Displaying full log info:")
// dialog.SetDefaultGeometry(500, 200) // dialog.SetDefaultGeometry(500, 200)
tv, err := gtk.TextViewNew() tv, err := gtk.TextViewNew()
@ -117,7 +113,7 @@ func promptInfo(msg string) {
dialog.ShowAll() dialog.ShowAll()
dialog.Run() dialog.Run()
dialog.Destroy() dialog.Destroy()
//self.set_default_size(150, 100) //self.set_default_size(150, 100)
} }
func promptChoice(msg string) int { func promptChoice(msg string) int {
@ -137,7 +133,7 @@ func getConfigPath() string {
usr, err := user.Current() usr, err := user.Current()
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Error: could not determine location of user preferences file:", err, "\n"); fmt.Fprintf(os.Stderr, "Error: could not determine location of user preferences file:", err, "\n")
return "" return ""
} }
@ -149,7 +145,7 @@ func savePreferences() bool {
usr, err := user.Current() usr, err := user.Current()
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Error: could not determine location of user preferences file:", err, "\n"); fmt.Fprintf(os.Stderr, "Error: could not determine location of user preferences file:", err, "\n")
return false return false
} }
@ -176,7 +172,7 @@ func loadPreferences() bool {
usr, err := user.Current() usr, err := user.Current()
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Error: could not determine location of user preferences file: %v", err, "\n"); fmt.Fprintf(os.Stderr, "Error: could not determine location of user preferences file: %v", err, "\n")
return false return false
} }
@ -192,7 +188,7 @@ func loadPreferences() bool {
err = json.Unmarshal(jfile, &userPrefs) err = json.Unmarshal(jfile, &userPrefs)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Error: could not load preferences data from file: %v", err, "\n") fmt.Fprintf(os.Stderr, "Error: could not load preferences data from file: %v", err, "\n")
return false return false
} }
@ -201,23 +197,23 @@ func loadPreferences() bool {
} }
func get_hbox() *gtk.Box { func get_hbox() *gtk.Box {
hbox, err := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 0) hbox, err := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 0)
if err != nil { if err != nil {
log.Fatal("Unable to create horizontal box:", err) log.Fatal("Unable to create horizontal box:", err)
} }
return hbox return hbox
} }
func get_vbox() *gtk.Box { func get_vbox() *gtk.Box {
vbox, err := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 0) vbox, err := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 0)
if err != nil { if err != nil {
log.Fatal("Unable to create vertical box:", err) log.Fatal("Unable to create vertical box:", err)
} }
return vbox return vbox
} }
func get_checkbox(text string, activated bool) *gtk.CheckButton { func get_checkbox(text string, activated bool) *gtk.CheckButton {
@ -416,7 +412,7 @@ func setup_settings() {
fmt.Println("CLICKED") fmt.Println("CLICKED")
if err != nil { if err != nil {
promptError("Unexpected error saving log file info: "+err.Error()) promptError("Unexpected error saving log file info: " + err.Error())
return return
} }
@ -508,7 +504,6 @@ func toggleValidRuleState() {
} }
} }
btnApprove.SetSensitive(ok) btnApprove.SetSensitive(ok)
btnDeny.SetSensitive(ok) btnDeny.SetSensitive(ok)
btnIgnore.SetSensitive(ok) btnIgnore.SetSensitive(ok)
@ -554,8 +549,8 @@ func createCurrentRule() (ruleColumns, error) {
rule.UID, rule.GID = 0, 0 rule.UID, rule.GID = 0, 0
rule.Uname, rule.Gname = "", "" rule.Uname, rule.Gname = "", ""
/* Pid int /* Pid int
Origin string */ Origin string */
return rule, nil return rule, nil
} }
@ -690,7 +685,7 @@ func getSelectedRule() (ruleColumns, int, error) {
func main() { func main() {
decisionWaiters = make([]*decisionWaiter, 0) decisionWaiters = make([]*decisionWaiter, 0)
_, err := newDbusServer(); _, err := newDbusServer()
if err != nil { if err != nil {
log.Fatal("Error:", err) log.Fatal("Error:", err)
return return
@ -711,7 +706,7 @@ func main() {
mainWin.Connect("destroy", func() { mainWin.Connect("destroy", func() {
fmt.Println("Shutting down...") fmt.Println("Shutting down...")
savePreferences() savePreferences()
gtk.MainQuit() gtk.MainQuit()
}) })
mainWin.Connect("configure-event", func() { mainWin.Connect("configure-event", func() {
@ -751,7 +746,6 @@ func main() {
scrollbox.Add(box) scrollbox.Add(box)
tv, err := gtk.TreeViewNew() tv, err := gtk.TreeViewNew()
if err != nil { if err != nil {
@ -867,13 +861,13 @@ func main() {
btnApprove.Connect("clicked", func() { btnApprove.Connect("clicked", func() {
rule, idx, err := getSelectedRule() rule, idx, err := getSelectedRule()
if err != nil { if err != nil {
promptError("Error occurred processing request: "+err.Error()) promptError("Error occurred processing request: " + err.Error())
return return
} }
rule, err = createCurrentRule() rule, err = createCurrentRule()
if err != nil { if err != nil {
promptError("Error occurred constructing new rule: "+err.Error()) promptError("Error occurred constructing new rule: " + err.Error())
return return
} }
@ -886,20 +880,20 @@ func main() {
if err == nil { if err == nil {
clearEditor() clearEditor()
} else { } else {
promptError("Error setting new rule: "+err.Error()) promptError("Error setting new rule: " + err.Error())
} }
}) })
btnDeny.Connect("clicked", func() { btnDeny.Connect("clicked", func() {
rule, idx, err := getSelectedRule() rule, idx, err := getSelectedRule()
if err != nil { if err != nil {
promptError("Error occurred processing request: "+err.Error()) promptError("Error occurred processing request: " + err.Error())
return return
} }
rule, err = createCurrentRule() rule, err = createCurrentRule()
if err != nil { if err != nil {
promptError("Error occurred constructing new rule: "+err.Error()) promptError("Error occurred constructing new rule: " + err.Error())
return return
} }
@ -912,14 +906,14 @@ func main() {
if err == nil { if err == nil {
clearEditor() clearEditor()
} else { } else {
promptError("Error setting new rule: "+err.Error()) promptError("Error setting new rule: " + err.Error())
} }
}) })
btnIgnore.Connect("clicked", func() { btnIgnore.Connect("clicked", func() {
_, idx, err := getSelectedRule() _, idx, err := getSelectedRule()
if err != nil { if err != nil {
promptError("Error occurred processing request: "+err.Error()) promptError("Error occurred processing request: " + err.Error())
return return
} }
@ -929,15 +923,15 @@ func main() {
if err == nil { if err == nil {
clearEditor() clearEditor()
} else { } else {
promptError("Error setting new rule: "+err.Error()) promptError("Error setting new rule: " + err.Error())
} }
}) })
// tv.SetActivateOnSingleClick(true) // tv.SetActivateOnSingleClick(true)
tv.Connect("row-activated", func() { tv.Connect("row-activated", func() {
seldata, _, err := getSelectedRule() seldata, _, err := getSelectedRule()
if err != nil { if err != nil {
promptError("Unexpected error reading selected rule: "+err.Error()) promptError("Unexpected error reading selected rule: " + err.Error())
return return
} }
@ -980,14 +974,13 @@ func main() {
return return
}) })
scrollbox.SetSizeRequest(600, 400) scrollbox.SetSizeRequest(600, 400)
Notebook.AppendPage(scrollbox, nbLabel) Notebook.AppendPage(scrollbox, nbLabel)
// setup_settings() // setup_settings()
mainWin.Add(Notebook) mainWin.Add(Notebook)
if userPrefs.Winheight > 0 && userPrefs.Winwidth > 0 { if userPrefs.Winheight > 0 && userPrefs.Winwidth > 0 {
// fmt.Printf("height was %d, width was %d\n", userPrefs.Winheight, userPrefs.Winwidth) // fmt.Printf("height was %d, width was %d\n", userPrefs.Winheight, userPrefs.Winwidth)
mainWin.Resize(int(userPrefs.Winwidth), int(userPrefs.Winheight)) mainWin.Resize(int(userPrefs.Winwidth), int(userPrefs.Winheight))
} else { } else {
mainWin.SetDefaultSize(850, 450) mainWin.SetDefaultSize(850, 450)
@ -998,6 +991,6 @@ func main() {
} }
mainWin.ShowAll() mainWin.ShowAll()
// mainWin.SetKeepAbove(true) // mainWin.SetKeepAbove(true)
gtk.Main() gtk.Main()
} }

@ -3,12 +3,11 @@ package main
import ( import (
"errors" "errors"
"fmt" "fmt"
"github.com/subgraph/fw-daemon/sgfw"
"github.com/godbus/dbus" "github.com/godbus/dbus"
"github.com/gotk3/gotk3/glib" "github.com/gotk3/gotk3/glib"
"github.com/subgraph/fw-daemon/sgfw"
) )
type dbusObject struct { type dbusObject struct {
dbus.BusObject dbus.BusObject
} }
@ -19,7 +18,7 @@ type dbusObjectP struct {
type dbusServer struct { type dbusServer struct {
conn *dbus.Conn conn *dbus.Conn
run bool run bool
} }
func newDbusObject() (*dbusObject, error) { func newDbusObject() (*dbusObject, error) {
@ -114,5 +113,5 @@ func (ds *dbusServer) Alert(data string) *dbus.Error {
} }
func (ob *dbusObjectP) alertRule(data string) { func (ob *dbusObjectP) alertRule(data string) {
ob.Call("com.subgraph.fwprompt.EventNotifier.Alert", 0, data) ob.Call("com.subgraph.fwprompt.EventNotifier.Alert", 0, data)
} }

@ -108,7 +108,7 @@ func repopulateWin() {
rlSystem.loadRules(sgfw.RULE_MODE_SYSTEM) rlSystem.loadRules(sgfw.RULE_MODE_SYSTEM)
loadConfig(win, fwsbuilder, dbus) loadConfig(win, fwsbuilder, dbus)
// app.AddWindow(win) // app.AddWindow(win)
win.ShowAll() win.ShowAll()
} }
@ -179,11 +179,11 @@ func main() {
} }
app.Connect("activate", activate) app.Connect("activate", activate)
_, err = newDbusServer(); _, err = newDbusServer()
if err != nil { if err != nil {
panic(fmt.Sprintf("Error initializing Dbus server: %v", err)) panic(fmt.Sprintf("Error initializing Dbus server: %v", err))
} }
app.Run(os.Args) app.Run(os.Args)
} }

@ -3,8 +3,8 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"strings"
"strconv" "strconv"
"strings"
"github.com/subgraph/fw-daemon/sgfw" "github.com/subgraph/fw-daemon/sgfw"
@ -122,7 +122,7 @@ func (rr *ruleRow) update() {
} }
rr.gtkLabelApp.SetTooltipText(rr.rule.Path) rr.gtkLabelApp.SetTooltipText(rr.rule.Path)
rr.gtkLabelVerb.SetText(getVerbText(rr.rule)) rr.gtkLabelVerb.SetText(getVerbText(rr.rule))
if (rr.rule.Proto == "tcp") { if rr.rule.Proto == "tcp" {
rr.gtkLabelOrigin.SetText(rr.rule.Origin) rr.gtkLabelOrigin.SetText(rr.rule.Origin)
} else { } else {
rr.gtkLabelOrigin.SetText(rr.rule.Origin + " (" + rr.rule.Proto + ")") rr.gtkLabelOrigin.SetText(rr.rule.Origin + " (" + rr.rule.Proto + ")")

@ -2,15 +2,14 @@ package pcoroner
import ( import (
"fmt" "fmt"
"time" "os"
"strings"
"strconv" "strconv"
"strings"
"sync" "sync"
"os"
"syscall" "syscall"
"time"
) )
type WatchProcess struct { type WatchProcess struct {
Pid int Pid int
Inode uint64 Inode uint64
@ -25,14 +24,11 @@ type CallbackEntry struct {
type procCB func(int, interface{}) type procCB func(int, interface{})
var Callbacks []CallbackEntry var Callbacks []CallbackEntry
var pmutex = &sync.Mutex{} var pmutex = &sync.Mutex{}
var pidMap map[int]WatchProcess = make(map[int]WatchProcess) var pidMap map[int]WatchProcess = make(map[int]WatchProcess)
func MonitorProcess(pid int) bool { func MonitorProcess(pid int) bool {
pmutex.Lock() pmutex.Lock()
defer pmutex.Unlock() defer pmutex.Unlock()
@ -68,14 +64,14 @@ func AddCallback(cbfunc procCB, param interface{}) {
func MonitorThread(cbfunc procCB, param interface{}) { func MonitorThread(cbfunc procCB, param interface{}) {
for { for {
/* if len(pidMap) == 0 { /* if len(pidMap) == 0 {
fmt.Println("TICK") fmt.Println("TICK")
} else { fmt.Println("len = ", len(pidMap)) } */ } else { fmt.Println("len = ", len(pidMap)) } */
pmutex.Lock() pmutex.Lock()
pmutex.Unlock() pmutex.Unlock()
for pkey, pval := range pidMap { for pkey, pval := range pidMap {
// fmt.Printf("PID %v -> %v\n", pkey, pval) // fmt.Printf("PID %v -> %v\n", pkey, pval)
res := checkProcess(&pval, false) res := checkProcess(&pval, false)
if !res { if !res {
@ -100,7 +96,7 @@ func checkProcess(proc *WatchProcess, init bool) bool {
ppath := fmt.Sprintf("/proc/%d/stat", proc.Pid) ppath := fmt.Sprintf("/proc/%d/stat", proc.Pid)
f, err := os.Open(ppath) f, err := os.Open(ppath)
if err != nil { if err != nil {
// fmt.Printf("Error opening path %s: %s\n", ppath, err) // fmt.Printf("Error opening path %s: %s\n", ppath, err)
return false return false
} }
defer f.Close() defer f.Close()
@ -133,7 +129,7 @@ func checkProcess(proc *WatchProcess, init bool) bool {
} }
bstr := string(buf[:]) bstr := string(buf[:])
// fmt.Println("sstr = ", bstr) // fmt.Println("sstr = ", bstr)
fields := strings.Split(bstr, " ") fields := strings.Split(bstr, " ")

@ -12,32 +12,37 @@ const (
//RuleAction is the action to apply to a rule //RuleAction is the action to apply to a rule
type RuleAction uint16 type RuleAction uint16
const ( const (
RULE_ACTION_DENY RuleAction = iota RULE_ACTION_DENY RuleAction = iota
RULE_ACTION_ALLOW RULE_ACTION_ALLOW
RULE_ACTION_ALLOW_TLSONLY RULE_ACTION_ALLOW_TLSONLY
) )
// RuleActionString is used to get a string from an action id // RuleActionString is used to get a string from an action id
var RuleActionString = map[RuleAction]string{ var RuleActionString = map[RuleAction]string{
RULE_ACTION_DENY: "DENY", RULE_ACTION_DENY: "DENY",
RULE_ACTION_ALLOW: "ALLOW", RULE_ACTION_ALLOW: "ALLOW",
RULE_ACTION_ALLOW_TLSONLY: "ALLOW_TLSONLY", RULE_ACTION_ALLOW_TLSONLY: "ALLOW_TLSONLY",
} }
// RuleActionValue is used to get an action id using the action string // RuleActionValue is used to get an action id using the action string
var RuleActionValue = map[string]RuleAction{ var RuleActionValue = map[string]RuleAction{
RuleActionString[RULE_ACTION_DENY]: RULE_ACTION_DENY, RuleActionString[RULE_ACTION_DENY]: RULE_ACTION_DENY,
RuleActionString[RULE_ACTION_ALLOW]: RULE_ACTION_ALLOW, RuleActionString[RULE_ACTION_ALLOW]: RULE_ACTION_ALLOW,
RuleActionString[RULE_ACTION_ALLOW_TLSONLY]: RULE_ACTION_ALLOW_TLSONLY, RuleActionString[RULE_ACTION_ALLOW_TLSONLY]: RULE_ACTION_ALLOW_TLSONLY,
} }
//RuleMode contains the time scope of a rule //RuleMode contains the time scope of a rule
type RuleMode uint16 type RuleMode uint16
const ( const (
RULE_MODE_SESSION RuleMode = iota RULE_MODE_SESSION RuleMode = iota
RULE_MODE_PROCESS RULE_MODE_PROCESS
RULE_MODE_PERMANENT RULE_MODE_PERMANENT
RULE_MODE_SYSTEM RULE_MODE_SYSTEM
) )
// RuleModeString is used to get a rule mode string from its id // RuleModeString is used to get a rule mode string from its id
var RuleModeString = map[RuleMode]string{ var RuleModeString = map[RuleMode]string{
RULE_MODE_SESSION: "SESSION", RULE_MODE_SESSION: "SESSION",
@ -45,6 +50,7 @@ var RuleModeString = map[RuleMode]string{
RULE_MODE_PERMANENT: "PERMANENT", RULE_MODE_PERMANENT: "PERMANENT",
RULE_MODE_SYSTEM: "SYSTEM", RULE_MODE_SYSTEM: "SYSTEM",
} }
// RuleModeValue converts a mode string to its id // RuleModeValue converts a mode string to its id
var RuleModeValue = map[string]RuleMode{ var RuleModeValue = map[string]RuleMode{
RuleModeString[RULE_MODE_SESSION]: RULE_MODE_SESSION, RuleModeString[RULE_MODE_SESSION]: RULE_MODE_SESSION,
@ -55,12 +61,14 @@ var RuleModeValue = map[string]RuleMode{
//FilterScope contains a filter's time scope //FilterScope contains a filter's time scope
type FilterScope uint16 type FilterScope uint16
const ( const (
APPLY_ONCE FilterScope = iota APPLY_ONCE FilterScope = iota
APPLY_SESSION APPLY_SESSION
APPLY_PROCESS APPLY_PROCESS
APPLY_FOREVER APPLY_FOREVER
) )
// FilterScopeString converts a filter scope ID to its string // FilterScopeString converts a filter scope ID to its string
var FilterScopeString = map[FilterScope]string{ var FilterScopeString = map[FilterScope]string{
APPLY_ONCE: "ONCE", APPLY_ONCE: "ONCE",
@ -68,6 +76,7 @@ var FilterScopeString = map[FilterScope]string{
APPLY_PROCESS: "PROCESS", APPLY_PROCESS: "PROCESS",
APPLY_FOREVER: "FOREVER", APPLY_FOREVER: "FOREVER",
} }
// FilterScopeString converts a filter scope string to its ID // FilterScopeString converts a filter scope string to its ID
var FilterScopeValue = map[string]FilterScope{ var FilterScopeValue = map[string]FilterScope{
FilterScopeString[APPLY_ONCE]: APPLY_ONCE, FilterScopeString[APPLY_ONCE]: APPLY_ONCE,
@ -75,6 +84,7 @@ var FilterScopeValue = map[string]FilterScope{
FilterScopeString[APPLY_PROCESS]: APPLY_PROCESS, FilterScopeString[APPLY_PROCESS]: APPLY_PROCESS,
FilterScopeString[APPLY_FOREVER]: APPLY_FOREVER, FilterScopeString[APPLY_FOREVER]: APPLY_FOREVER,
} }
// GetFilterScopeString is used to safely return a filter scope string // GetFilterScopeString is used to safely return a filter scope string
func GetFilterScopeString(scope FilterScope) string { func GetFilterScopeString(scope FilterScope) string {
if val, ok := FilterScopeString[scope]; ok { if val, ok := FilterScopeString[scope]; ok {
@ -82,6 +92,7 @@ func GetFilterScopeString(scope FilterScope) string {
} }
return FilterScopeString[APPLY_SESSION] return FilterScopeString[APPLY_SESSION]
} }
// GetFilterScopeValue is used to safely return a filter scope ID // GetFilterScopeValue is used to safely return a filter scope ID
func GetFilterScopeValue(scope string) FilterScope { func GetFilterScopeValue(scope string) FilterScope {
scope = strings.ToUpper(scope) scope = strings.ToUpper(scope)
@ -93,24 +104,27 @@ func GetFilterScopeValue(scope string) FilterScope {
//FilterResult contains the filtering resulting action //FilterResult contains the filtering resulting action
type FilterResult uint16 type FilterResult uint16
const ( const (
FILTER_DENY FilterResult = iota FILTER_DENY FilterResult = iota
FILTER_ALLOW FILTER_ALLOW
FILTER_PROMPT FILTER_PROMPT
FILTER_ALLOW_TLSONLY FILTER_ALLOW_TLSONLY
) )
// FilterResultString converts a filter value ID to its string // FilterResultString converts a filter value ID to its string
var FilterResultString = map[FilterResult]string{ var FilterResultString = map[FilterResult]string{
FILTER_DENY: "DENY", FILTER_DENY: "DENY",
FILTER_ALLOW: "ALLOW", FILTER_ALLOW: "ALLOW",
FILTER_PROMPT: "PROMPT", FILTER_PROMPT: "PROMPT",
FILTER_ALLOW_TLSONLY: "ALLOW_TLSONLY", FILTER_ALLOW_TLSONLY: "ALLOW_TLSONLY",
} }
// FilterResultValue converts a filter value string to its ID // FilterResultValue converts a filter value string to its ID
var FilterResultValue = map[string]FilterResult{ var FilterResultValue = map[string]FilterResult{
FilterResultString[FILTER_DENY]: FILTER_DENY, FilterResultString[FILTER_DENY]: FILTER_DENY,
FilterResultString[FILTER_ALLOW]: FILTER_ALLOW, FilterResultString[FILTER_ALLOW]: FILTER_ALLOW,
FilterResultString[FILTER_PROMPT]: FILTER_PROMPT, FilterResultString[FILTER_PROMPT]: FILTER_PROMPT,
FilterResultString[FILTER_ALLOW_TLSONLY]: FILTER_ALLOW_TLSONLY, FilterResultString[FILTER_ALLOW_TLSONLY]: FILTER_ALLOW_TLSONLY,
} }

@ -62,7 +62,6 @@ func newDbusObjectPrompt() (*dbusObjectP, error) {
return &dbusObjectP{conn.Object("com.subgraph.fwprompt.EventNotifier", "/com/subgraph/fwprompt/EventNotifier")}, nil return &dbusObjectP{conn.Object("com.subgraph.fwprompt.EventNotifier", "/com/subgraph/fwprompt/EventNotifier")}, nil
} }
type dbusServer struct { type dbusServer struct {
fw *Firewall fw *Firewall
conn *dbus.Conn conn *dbus.Conn

@ -1,23 +1,23 @@
package sgfw package sgfw
import ( import (
"encoding/binary"
"net" "net"
"strings" "strings"
"sync" "sync"
"time" "time"
"encoding/binary"
// "github.com/subgraph/go-nfnetlink" // "github.com/subgraph/go-nfnetlink"
"github.com/google/gopacket/layers" "github.com/google/gopacket/layers"
"github.com/subgraph/fw-daemon/proc-coroner"
nfqueue "github.com/subgraph/go-nfnetlink/nfqueue" nfqueue "github.com/subgraph/go-nfnetlink/nfqueue"
"github.com/subgraph/go-procsnitch" "github.com/subgraph/go-procsnitch"
"github.com/subgraph/fw-daemon/proc-coroner"
) )
type dnsEntry struct { type dnsEntry struct {
name string name string
ttl uint32 ttl uint32
exp time.Time exp time.Time
} }
type dnsCache struct { type dnsCache struct {
@ -66,14 +66,14 @@ func (dc *dnsCache) processDNS(pkt *nfqueue.NFQPacket) {
srcip, _ := getPacketIPAddrs(pkt) srcip, _ := getPacketIPAddrs(pkt)
pinfo := getEmptyPInfo() pinfo := getEmptyPInfo()
if !isNSTrusted(srcip) { if !isNSTrusted(srcip) {
pinfo, _ = findProcessForPacket(pkt, true, procsnitch.MATCH_LOOSEST) pinfo, _ = findProcessForPacket(pkt, true, procsnitch.MATCH_LOOSEST)
if pinfo == nil { if pinfo == nil {
log.Warningf("Skipping attempted DNS cache entry for process that can't be found: %v -> %v\n", q.Name, dns.answer) log.Warningf("Skipping attempted DNS cache entry for process that can't be found: %v -> %v\n", q.Name, dns.answer)
return return
} }
} }
//log.Notice("XXX: PROCESS LOOKUP -> ", pinfo) //log.Notice("XXX: PROCESS LOOKUP -> ", pinfo)
dc.processRecordAddress(q.Name, dns.answer, pinfo.Pid) dc.processRecordAddress(q.Name, dns.answer, pinfo.Pid)
return return
} }
@ -166,7 +166,7 @@ func (dc *dnsCache) Lookup(ip net.IP, pid int) string {
entry, ok := dc.ipMap[pid][ip.String()] entry, ok := dc.ipMap[pid][ip.String()]
if ok { if ok {
if now.Before(entry.exp) { if now.Before(entry.exp) {
// log.Noticef("XXX: LOOKUP on %v / %v = %v, ttl = %v / %v\n", pid, ip.String(), entry.name, entry.ttl, entry.exp) // log.Noticef("XXX: LOOKUP on %v / %v = %v, ttl = %v / %v\n", pid, ip.String(), entry.name, entry.ttl, entry.exp)
return entry.name return entry.name
} else { } else {
log.Warningf("Skipping expired per-pid (%d) DNS cache entry: %s -> %s / exp. %v (%ds)\n", log.Warningf("Skipping expired per-pid (%d) DNS cache entry: %s -> %s / exp. %v (%ds)\n",
@ -180,13 +180,13 @@ func (dc *dnsCache) Lookup(ip net.IP, pid int) string {
if ok { if ok {
if now.Before(entry.exp) { if now.Before(entry.exp) {
str = entry.name str = entry.name
// log.Noticef("XXX: LOOKUP on %v / 0 RETURNING %v, ttl = %v / %v\n", ip.String(), str, entry.ttl, entry.exp) // log.Noticef("XXX: LOOKUP on %v / 0 RETURNING %v, ttl = %v / %v\n", ip.String(), str, entry.ttl, entry.exp)
} else { } else {
log.Warningf("Skipping expired global DNS cache entry: %s -> %s / exp. %v (%ds)\n", log.Warningf("Skipping expired global DNS cache entry: %s -> %s / exp. %v (%ds)\n",
ip.String(), entry.name, entry.exp, entry.ttl) ip.String(), entry.name, entry.exp, entry.ttl)
} }
} }
//log.Noticef("XXX: LOOKUP on %v / 0 RETURNING %v\n", ip.String(), str) //log.Noticef("XXX: LOOKUP on %v / 0 RETURNING %v\n", ip.String(), str)
return str return str
} }

@ -758,14 +758,14 @@ func unpackRR(msg []byte, off int) (rr dnsRR, off1 int, ok bool) {
// A manually-unpacked version of (id, bits). // A manually-unpacked version of (id, bits).
// This is in its own struct for easy printing. // This is in its own struct for easy printing.
type dnsMsgHdr struct { type dnsMsgHdr struct {
id uint16 id uint16
response bool response bool
opcode int opcode int
authoritative bool authoritative bool
truncated bool truncated bool
recursionDesired bool recursionDesired bool
recursionAvailable bool recursionAvailable bool
rcode int rcode int
} }
func (h *dnsMsgHdr) Walk(f func(v interface{}, name, tag string) bool) bool { func (h *dnsMsgHdr) Walk(f func(v interface{}, name, tag string) bool) bool {

@ -1,31 +1,29 @@
package sgfw package sgfw
import ( import (
"bufio"
"errors"
"fmt" "fmt"
"net" "net"
"os" "os"
"bufio"
"strings"
"strconv" "strconv"
"errors" "strings"
"github.com/subgraph/oz/ipc" "github.com/subgraph/oz/ipc"
) )
const ReceiverSocketPath = "/var/run/fw-daemon/fwoz.sock" const ReceiverSocketPath = "/var/run/fw-daemon/fwoz.sock"
type OzInitProc struct { type OzInitProc struct {
Name string Name string
Pid int Pid int
SandboxID int SandboxID int
} }
var OzInitPids []OzInitProc = []OzInitProc{} var OzInitPids []OzInitProc = []OzInitProc{}
func addInitPid(pid int, name string, sboxid int) { func addInitPid(pid int, name string, sboxid int) {
fmt.Println("::::::::::: init pid added: ", pid, " -> ", name) fmt.Println("::::::::::: init pid added: ", pid, " -> ", name)
for i := 0; i < len(OzInitPids); i++ { for i := 0; i < len(OzInitPids); i++ {
if OzInitPids[i].Pid == pid { if OzInitPids[i].Pid == pid {
return return
@ -37,7 +35,7 @@ fmt.Println("::::::::::: init pid added: ", pid, " -> ", name)
} }
func removeInitPid(pid int) { func removeInitPid(pid int) {
fmt.Println("::::::::::: removing PID: ", pid) fmt.Println("::::::::::: removing PID: ", pid)
for i := 0; i < len(OzInitPids); i++ { for i := 0; i < len(OzInitPids); i++ {
if OzInitPids[i].Pid == pid { if OzInitPids[i].Pid == pid {
OzInitPids = append(OzInitPids[:i], OzInitPids[i+1:]...) OzInitPids = append(OzInitPids[:i], OzInitPids[i+1:]...)
@ -63,7 +61,7 @@ func addFWRule(fw *Firewall, whitelist bool, srchost, dsthost, dstport string) e
} }
func removeAllByIP(fw *Firewall, srcip string) bool { func removeAllByIP(fw *Firewall, srcip string) bool {
log.Notice("XXX: Attempting to remove all rules associated with Oz interface: ", srcip) log.Notice("XXX: Attempting to remove all rules associated with Oz interface: ", srcip)
saddr := net.ParseIP(srcip) saddr := net.ParseIP(srcip)
if saddr == nil { if saddr == nil {
@ -73,13 +71,13 @@ log.Notice("XXX: Attempting to remove all rules associated with Oz interface: ",
policy := fw.PolicyForPath("*") policy := fw.PolicyForPath("*")
nrm := 0 nrm := 0
for _, rr := range policy.rules { for _, rr := range policy.rules {
if rr.saddr != nil && rr.saddr.Equal(saddr) { if rr.saddr != nil && rr.saddr.Equal(saddr) {
log.Notice("XXX: removing ephemeral rules by Oz interface ", srcip, ": ", rr) log.Notice("XXX: removing ephemeral rules by Oz interface ", srcip, ": ", rr)
policy.removeRule(rr) policy.removeRule(rr)
nrm++ nrm++
} }
} }
if nrm == 0 { if nrm == 0 {
log.Notice("XXX: did not remove any rules for interface") log.Notice("XXX: did not remove any rules for interface")
@ -102,10 +100,10 @@ func ReceiverLoop(fw *Firewall, c net.Conn) {
data := string(buf) data := string(buf)
log.Notice("Received incoming IPC:",data) log.Notice("Received incoming IPC:", data)
if data[len(data)-1] == '\n' { if data[len(data)-1] == '\n' {
data = data[0:len(data)-1] data = data[0 : len(data)-1]
} }
if data == "dump" { if data == "dump" {
@ -141,18 +139,18 @@ func ReceiverLoop(fw *Firewall, c net.Conn) {
c.Write([]byte(ruledesc)) c.Write([]byte(ruledesc))
} }
/* for i := 0; i < len(sandboxRules); i++ { /* for i := 0; i < len(sandboxRules); i++ {
rulestr := "" rulestr := ""
if sandboxRules[i].Whitelist { if sandboxRules[i].Whitelist {
rulestr += "whitelist" rulestr += "whitelist"
} else { } else {
rulestr += "blacklist" rulestr += "blacklist"
} }
rulestr += " " + sandboxRules[i].SrcIf.String() + " -> " + sandboxRules[i].DstIP.String() + " : " + strconv.Itoa(int(sandboxRules[i].DstPort)) + "\n" rulestr += " " + sandboxRules[i].SrcIf.String() + " -> " + sandboxRules[i].DstIP.String() + " : " + strconv.Itoa(int(sandboxRules[i].DstPort)) + "\n"
c.Write([]byte(rulestr)) c.Write([]byte(rulestr))
} */ } */
return return
} else { } else {
@ -166,7 +164,7 @@ func ReceiverLoop(fw *Firewall, c net.Conn) {
if tokens[0] == "register-init" && len(tokens) >= 3 { if tokens[0] == "register-init" && len(tokens) >= 3 {
initp := tokens[1] initp := tokens[1]
initpid, err := strconv.Atoi(initp) initpid, err := strconv.Atoi(initp)
if err != nil { if err != nil {
@ -177,7 +175,7 @@ func ReceiverLoop(fw *Firewall, c net.Conn) {
sboxid, err := strconv.Atoi(tokens[3]) sboxid, err := strconv.Atoi(tokens[3])
if err != nil { if err != nil {
log.Notice("IPC received invalid oz sbox number: ",tokens[3]) log.Notice("IPC received invalid oz sbox number: ", tokens[3])
log.Notice("Data: %v", data) log.Notice("Data: %v", data)
c.Write([]byte("Bad command: sandbox id was invalid")) c.Write([]byte("Bad command: sandbox id was invalid"))
return return
@ -234,30 +232,30 @@ func ReceiverLoop(fw *Firewall, c net.Conn) {
if srcip == nil { if srcip == nil {
log.Notice("IP conversion failed: ", srchost) log.Notice("IP conversion failed: ", srchost)
srcip = net.IP{0,0,0,0} srcip = net.IP{0, 0, 0, 0}
} }
dstport := tokens[4] dstport := tokens[4]
dstp, err := strconv.Atoi(dstport) dstp, err := strconv.Atoi(dstport)
if dstport != "*" && (err != nil || dstp < 0 || dstp > 65535) { if dstport != "*" && (err != nil || dstp < 0 || dstp > 65535) {
log.Notice("IPC received invalid destination port: ", tokens[4]) log.Notice("IPC received invalid destination port: ", tokens[4])
c.Write([]byte("Bad command: dst port was invalid")) c.Write([]byte("Bad command: dst port was invalid"))
return return
} }
/* initp := tokens[5] /* initp := tokens[5]
initpid, err := strconv.Atoi(initp) initpid, err := strconv.Atoi(initp)
if err != nil { if err != nil {
log.Notice("IPC received invalid oz-init pid: ", initp) log.Notice("IPC received invalid oz-init pid: ", initp)
c.Write([]byte("Bad command: init pid was invalid")) c.Write([]byte("Bad command: init pid was invalid"))
return return
} */ } */
if add { if add {
log.Noticef("Adding new rule to oz sandbox/fw: %v / %v -> %v : %v", w, srchost, dsthost, dstport) log.Noticef("Adding new rule to oz sandbox/fw: %v / %v -> %v : %v", w, srchost, dsthost, dstport)
// addInitPid(initpid) // addInitPid(initpid)
err := addFWRule(fw, w, srchost, dsthost, dstport) err := addFWRule(fw, w, srchost, dsthost, dstport)
if err != nil { if err != nil {
log.Error("Error adding dynamic OZ firewall rule to fw-daemon: ", err) log.Error("Error adding dynamic OZ firewall rule to fw-daemon: ", err)
@ -268,13 +266,11 @@ func ReceiverLoop(fw *Firewall, c net.Conn) {
log.Notice("Removing new rule from oz sandbox/fw... ") log.Notice("Removing new rule from oz sandbox/fw... ")
} }
log.Notice("IPC received command: " + data) log.Notice("IPC received command: " + data)
c.Write([]byte("OK.\n")) c.Write([]byte("OK.\n"))
return return
} }
} }
} }
@ -303,7 +299,7 @@ func OzReceiver(fw *Firewall) {
os.Remove(ReceiverSocketPath) os.Remove(ReceiverSocketPath)
lfd, err := net.Listen("unix", ReceiverSocketPath) lfd, err := net.Listen("unix", ReceiverSocketPath)
if err != nil { if err != nil {
log.Fatal("Could not open oz receiver socket:", err) log.Fatal("Could not open oz receiver socket:", err)
} }
for { for {
@ -313,11 +309,10 @@ func OzReceiver(fw *Firewall) {
} }
go ReceiverLoop(fw, fd) go ReceiverLoop(fw, fd)
} }
} }
type ListProxiesMsg struct { type ListProxiesMsg struct {
_ string "ListProxies" _ string "ListProxies"
} }
@ -339,11 +334,12 @@ func ListProxies() ([]string, error) {
} }
const OzSocketName = "@oz-control" const OzSocketName = "@oz-control"
var bSockName = OzSocketName var bSockName = OzSocketName
var messageFactory = ipc.NewMsgFactory( var messageFactory = ipc.NewMsgFactory(
new(ListProxiesMsg), new(ListProxiesMsg),
new(ListProxiesResp), new(ListProxiesResp),
) )
func clientConnect() (*ipc.MsgConn, error) { func clientConnect() (*ipc.MsgConn, error) {

@ -1,10 +1,10 @@
package sgfw package sgfw
import ( import (
"fmt"
"os" "os"
"syscall" "syscall"
"unsafe" "unsafe"
"fmt"
"github.com/op/go-logging" "github.com/op/go-logging"
) )

@ -175,7 +175,7 @@ func (pp *pendingPkt) print() string {
type Policy struct { type Policy struct {
fw *Firewall fw *Firewall
path string path string
sandbox string sandbox string
application string application string
icon string icon string
rules RuleList rules RuleList
@ -194,7 +194,7 @@ func (fw *Firewall) PolicyForPath(path string) *Policy {
func (fw *Firewall) PolicyForPathAndSandbox(path string, sandbox string) *Policy { func (fw *Firewall) PolicyForPathAndSandbox(path string, sandbox string) *Policy {
fw.lock.Lock() fw.lock.Lock()
defer fw.lock.Unlock() defer fw.lock.Unlock()
return fw.policyForPathAndSandbox(path, sandbox) return fw.policyForPathAndSandbox(path, sandbox)
} }
@ -212,7 +212,7 @@ func (fw *Firewall) policyForPathAndSandbox(path string, sandbox string) *Policy
p.icon = entry.icon p.icon = entry.icon
} }
fw.policyMap[policykey] = p fw.policyMap[policykey] = p
log.Infof("Creating new policy for path and sandbox: %s\n",policykey) log.Infof("Creating new policy for path and sandbox: %s\n", policykey)
fw.policies = append(fw.policies, p) fw.policies = append(fw.policies, p)
} }
return fw.policyMap[policykey] return fw.policyMap[policykey]
@ -502,7 +502,7 @@ func (fw *Firewall) filterPacket(pkt *nfqueue.NFQPacket) {
return return
} }
*/ */
policy := fw.PolicyForPathAndSandbox(ppath,pinfo.Sandbox) 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)
} }

@ -13,9 +13,10 @@ import (
"github.com/subgraph/fw-daemon/proc-coroner" "github.com/subgraph/fw-daemon/proc-coroner"
) )
var DoMultiPrompt = true var DoMultiPrompt = true
const MAX_PROMPTS = 3 const MAX_PROMPTS = 3
var outstandingPrompts = 0 var outstandingPrompts = 0
var promptLock = &sync.Mutex{} var promptLock = &sync.Mutex{}
@ -39,12 +40,12 @@ 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.sandbox + "|" + policy.path] _, ok := p.policyMap[policy.sandbox+"|"+policy.path]
if ok { if ok {
return return
} }
p.policyMap[policy.sandbox + "|" + policy.path] = policy p.policyMap[policy.sandbox+"|"+policy.path] = policy
fmt.Println("Saving policy key:"+policy.sandbox + "|" + policy.path) fmt.Println("Saving policy key:" + policy.sandbox + "|" + policy.path)
p.policyQueue = append(p.policyQueue, policy) p.policyQueue = append(p.policyQueue, policy)
p.cond.Signal() p.cond.Signal()
} }
@ -52,11 +53,11 @@ func (p *prompter) prompt(policy *Policy) {
func (p *prompter) promptLoop() { func (p *prompter) promptLoop() {
p.lock.Lock() p.lock.Lock()
for { for {
fmt.Println("promptLoop() outer") fmt.Println("promptLoop() outer")
for p.processNextPacket() { for p.processNextPacket() {
fmt.Println("promptLoop() inner") fmt.Println("promptLoop() inner")
} }
fmt.Println("promptLoop() wait") fmt.Println("promptLoop() wait")
p.cond.Wait() p.cond.Wait()
} }
} }
@ -78,7 +79,7 @@ func (p *prompter) processNextPacket() bool {
empty := true empty := true
for { for {
pc, empty = p.nextConnection() pc, empty = p.nextConnection()
fmt.Println("processNextPacket() loop; empty = ", empty, " / pc = ", pc) fmt.Println("processNextPacket() loop; empty = ", empty, " / pc = ", pc)
if pc == nil && empty { if pc == nil && empty {
return false return false
} else if pc == nil { } else if pc == nil {
@ -109,14 +110,14 @@ fmt.Println("processNextPacket() loop; empty = ", empty, " / pc = ", pc)
outstandingPrompts++ outstandingPrompts++
fmt.Println("Incremented outstanding to ", outstandingPrompts) fmt.Println("Incremented outstanding to ", outstandingPrompts)
promptLock.Unlock() promptLock.Unlock()
// if !pc.getPrompting() { // if !pc.getPrompting() {
pc.setPrompting(true) pc.setPrompting(true)
go p.processConnection(pc) go p.processConnection(pc)
// } // }
return true return true
} }
func processReturn (pc pendingConnection) { func processReturn(pc pendingConnection) {
promptLock.Lock() promptLock.Lock()
outstandingPrompts-- outstandingPrompts--
fmt.Println("Return decremented outstanding to ", outstandingPrompts) fmt.Println("Return decremented outstanding to ", outstandingPrompts)
@ -173,14 +174,14 @@ func (p *prompter) processConnection(pc pendingConnection) {
return return
} }
// the prompt sends: // the prompt sends:
// ALLOW|dest or DENY|dest // ALLOW|dest or DENY|dest
// //
// rule string needs to be: // rule string needs to be:
// VERB|dst|class|uid:gid|sandbox|[src] // VERB|dst|class|uid:gid|sandbox|[src]
// sometimes there's a src // sometimes there's a src
// this needs to be re-visited // this needs to be re-visited
toks := strings.Split(rule, "|") toks := strings.Split(rule, "|")
//verb := toks[0] //verb := toks[0]
@ -190,19 +191,19 @@ func (p *prompter) processConnection(pc pendingConnection) {
if len(toks) > 2 { if len(toks) > 2 {
sandbox = toks[2] sandbox = toks[2]
} }
tempRule := fmt.Sprintf("%s|%s",toks[0],toks[1])
if (pc.src() != nil && !pc.src().Equal(net.ParseIP("127.0.0.1")) && sandbox != "") { tempRule := fmt.Sprintf("%s|%s", toks[0], toks[1])
if pc.src() != nil && !pc.src().Equal(net.ParseIP("127.0.0.1")) && sandbox != "" {
//if !strings.HasSuffix(rule, "SYSTEM") && !strings.HasSuffix(rule, "||") { //if !strings.HasSuffix(rule, "SYSTEM") && !strings.HasSuffix(rule, "||") {
//rule += "||" //rule += "||"
//} //}
//ule += "|||" + pc.src().String() //ule += "|||" + pc.src().String()
tempRule += "||-1:-1|"+sandbox+"|" + pc.src().String() tempRule += "||-1:-1|" + sandbox + "|" + pc.src().String()
} else { } else {
tempRule += "||-1:-1|"+sandbox+"|" tempRule += "||-1:-1|" + sandbox + "|"
} }
r, err := policy.parseRule(tempRule, false) r, err := policy.parseRule(tempRule, false)
if err != nil { if err != nil {
@ -270,7 +271,7 @@ func (p *prompter) removePolicy(policy *Policy) {
} }
} }
p.policyQueue = newQueue p.policyQueue = newQueue
delete(p.policyMap, policy.sandbox + "|" + policy.path) delete(p.policyMap, policy.sandbox+"|"+policy.path)
} }
var userMap = make(map[int]string) var userMap = make(map[int]string)

@ -169,7 +169,7 @@ 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 := "" 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)
@ -222,14 +222,14 @@ func (rl *RuleList) filter(pkt *nfqueue.NFQPacket, src, dst net.IP, dstPort uint
result = FILTER_ALLOW result = FILTER_ALLOW
return result return result
/* /*
if r.saddr != nil { if r.saddr != nil {
return result return result
} }
*/ */
} else if r.rtype == RULE_ACTION_ALLOW_TLSONLY { } else if r.rtype == RULE_ACTION_ALLOW_TLSONLY {
result = FILTER_ALLOW_TLSONLY result = FILTER_ALLOW_TLSONLY
return result return result
} }
} else { } else {
log.Notice("+ MATCH FAILED") log.Notice("+ MATCH FAILED")
} }
@ -439,7 +439,7 @@ func savePolicy(f *os.File, p *Policy) {
if !p.hasPersistentRules() { if !p.hasPersistentRules() {
return return
} }
log.Warningf("p.path: ",p.path) log.Warningf("p.path: ", p.path)
if !writeLine(f, "["+p.sandbox+"|"+p.path+"]") { if !writeLine(f, "["+p.sandbox+"|"+p.path+"]") {
return return
} }
@ -495,7 +495,7 @@ func (fw *Firewall) loadRules() {
func (fw *Firewall) processPathLine(line string) *Policy { func (fw *Firewall) processPathLine(line string) *Policy {
pathLine := line[1 : len(line)-1] pathLine := line[1 : len(line)-1]
toks := strings.Split(pathLine, "|") toks := strings.Split(pathLine, "|")
policy := fw.policyForPathAndSandbox(toks[1],toks[0]) 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

@ -8,8 +8,8 @@ import (
"time" "time"
"github.com/subgraph/go-procsnitch" "github.com/subgraph/go-procsnitch"
"strings"
"strconv" "strconv"
"strings"
) )
type socksChainConfig struct { type socksChainConfig struct {
@ -17,7 +17,7 @@ type socksChainConfig struct {
TargetSocksAddr string TargetSocksAddr string
ListenSocksNet string ListenSocksNet string
ListenSocksAddr string ListenSocksAddr string
Name string Name string
} }
type socksChain struct { type socksChain struct {
@ -36,27 +36,27 @@ type socksChainSession struct {
bndAddr *Address bndAddr *Address
optData []byte optData []byte
procInfo procsnitch.ProcInfo procInfo procsnitch.ProcInfo
pinfo *procsnitch.Info pinfo *procsnitch.Info
server *socksChain server *socksChain
} }
const ( const (
socksVerdictDrop = 1 socksVerdictDrop = 1
socksVerdictAccept = 2 socksVerdictAccept = 2
socksVerdictAcceptTLSOnly = 3 socksVerdictAcceptTLSOnly = 3
) )
type pendingSocksConnection struct { type pendingSocksConnection struct {
pol *Policy pol *Policy
hname string hname string
srcIP net.IP srcIP net.IP
destIP net.IP destIP net.IP
sourcePort uint16 sourcePort uint16
destPort uint16 destPort uint16
pinfo *procsnitch.Info pinfo *procsnitch.Info
verdict chan int verdict chan int
prompting bool prompting bool
optstr string optstr string
} }
func (sc *pendingSocksConnection) sandbox() string { func (sc *pendingSocksConnection) sandbox() string {
@ -103,9 +103,9 @@ func (sc *pendingSocksConnection) deliverVerdict(v int) {
func (sc *pendingSocksConnection) accept() { sc.deliverVerdict(socksVerdictAccept) } func (sc *pendingSocksConnection) accept() { sc.deliverVerdict(socksVerdictAccept) }
// need to generalize special accept // need to generalize special accept
func (sc *pendingSocksConnection) acceptTLSOnly() {sc.deliverVerdict(socksVerdictAcceptTLSOnly) } func (sc *pendingSocksConnection) acceptTLSOnly() { sc.deliverVerdict(socksVerdictAcceptTLSOnly) }
func (sc *pendingSocksConnection) drop() { sc.deliverVerdict(socksVerdictDrop) } func (sc *pendingSocksConnection) drop() { sc.deliverVerdict(socksVerdictDrop) }
@ -172,7 +172,7 @@ func (c *socksChainSession) sessionWorker() {
if len(c.req.Auth.Uname) == 0 && len(c.req.Auth.Passwd) == 0 { if len(c.req.Auth.Uname) == 0 && len(c.req.Auth.Passwd) == 0 {
// Randomize username and password to force a new TOR circuit with each connection // Randomize username and password to force a new TOR circuit with each connection
rndbytes := []byte("sgfw" + strconv.Itoa(int(time.Now().UnixNano()) ^ os.Getpid())) rndbytes := []byte("sgfw" + strconv.Itoa(int(time.Now().UnixNano())^os.Getpid()))
c.req.Auth.Uname = rndbytes c.req.Auth.Uname = rndbytes
c.req.Auth.Passwd = rndbytes c.req.Auth.Passwd = rndbytes
} }
@ -230,7 +230,7 @@ func findProxyEndpoint(pdata []string, conn net.Conn) (*procsnitch.Info, string)
s1, d1, s2, d2 := toks[0], toks[2], toks[3], toks[5] s1, d1, s2, d2 := toks[0], toks[2], toks[3], toks[5]
if strings.HasSuffix(d1, ",") { if strings.HasSuffix(d1, ",") {
d1 = d1[0:len(d1)-1] d1 = d1[0 : len(d1)-1]
} }
if conn.LocalAddr().String() == d2 && conn.RemoteAddr().String() == s2 { if conn.LocalAddr().String() == d2 && conn.RemoteAddr().String() == s2 {
@ -296,15 +296,15 @@ func (c *socksChainSession) filterConnect() (bool, bool) {
optstr = "[Via SOCKS5: " + c.cfg.Name + "] " + optstr optstr = "[Via SOCKS5: " + c.cfg.Name + "] " + optstr
} }
log.Warningf("Lookup policy for %v %v",pinfo.ExePath,pinfo.Sandbox) log.Warningf("Lookup policy for %v %v", pinfo.ExePath, pinfo.Sandbox)
policy := c.server.fw.PolicyForPathAndSandbox(GetRealRoot(pinfo.ExePath,pinfo.Pid),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 == "" {
return false, false return false, false
} }
result := policy.rules.filter(nil, nil, ip, port, hostname, pinfo, optstr) result := policy.rules.filter(nil, nil, ip, port, hostname, pinfo, optstr)
log.Errorf("result %v",result) log.Errorf("result %v", result)
switch result { switch result {
case FILTER_DENY: case FILTER_DENY:
return false, false return false, false
@ -315,7 +315,7 @@ func (c *socksChainSession) filterConnect() (bool, bool) {
case FILTER_PROMPT: case FILTER_PROMPT:
caddr := c.clientConn.RemoteAddr().String() caddr := c.clientConn.RemoteAddr().String()
caddrt := strings.Split(caddr, ":") caddrt := strings.Split(caddr, ":")
caddrIP := net.IP{0,0,0,0} caddrIP := net.IP{0, 0, 0, 0}
caddrPort := uint16(0) caddrPort := uint16(0)
if len(caddrt) != 2 { if len(caddrt) != 2 {

@ -2,15 +2,14 @@ package sgfw
import ( import (
"crypto/x509" "crypto/x509"
"errors"
"io" "io"
"net" "net"
"errors"
) )
func TLSGuard(conn, conn2 net.Conn, fqdn string) error { func TLSGuard(conn, conn2 net.Conn, fqdn string) error {
// Should this be a requirement? // Should this be a requirement?
// if strings.HasSuffix(request.DestAddr.FQDN, "onion") { // if strings.HasSuffix(request.DestAddr.FQDN, "onion") {
handshakeByte, err := readNBytes(conn, 1) handshakeByte, err := readNBytes(conn, 1)
if err != nil { if err != nil {
@ -118,7 +117,7 @@ func TLSGuard(conn, conn2 net.Conn, fqdn string) error {
for remaining > 0 { for remaining > 0 {
certLen := int(int(pos[0])<<16 | int(pos[1])<<8 | int(pos[2])) certLen := int(int(pos[0])<<16 | int(pos[1])<<8 | int(pos[2]))
// fmt.Printf("Certs chain len %d, cert 1 len %d:\n", certChainLen, certLen) // fmt.Printf("Certs chain len %d, cert 1 len %d:\n", certChainLen, certLen)
cert := pos[3 : 3+certLen] cert := pos[3 : 3+certLen]
certs, err := x509.ParseCertificates(cert) certs, err := x509.ParseCertificates(cert)
if remaining == certChainLen { if remaining == certChainLen {
@ -143,18 +142,18 @@ func TLSGuard(conn, conn2 net.Conn, fqdn string) error {
} else { } else {
valid = true valid = true
} }
// else if s == 0x0d { fmt.Printf("found a client cert request, sending buf to client\n") } // else if s == 0x0d { fmt.Printf("found a client cert request, sending buf to client\n") }
} else if s == 0x0e { } else if s == 0x0e {
sendToClient = true sendToClient = true
} else if s == 0x0d { } else if s == 0x0d {
sendToClient = true sendToClient = true
} }
// fmt.Printf("Version bytes: %x %x\n", responseBuf[1], responseBuf[2]) // fmt.Printf("Version bytes: %x %x\n", responseBuf[1], responseBuf[2])
// fmt.Printf("Len bytes: %x %x\n", responseBuf[3], responseBuf[4]) // fmt.Printf("Len bytes: %x %x\n", responseBuf[3], responseBuf[4])
// fmt.Printf("Message type: %x\n", responseBuf[5]) // fmt.Printf("Message type: %x\n", responseBuf[5])
// fmt.Printf("Message len: %x %x %x\n", responseBuf[6], responseBuf[7], responseBuf[8]) // fmt.Printf("Message len: %x %x %x\n", responseBuf[6], responseBuf[7], responseBuf[8])
// fmt.Printf("Message body: %v\n", responseBuf[9:]) // fmt.Printf("Message body: %v\n", responseBuf[9:])
conn.Write(responseBuf) conn.Write(responseBuf)
responseBuf = []byte{} responseBuf = []byte{}
} }

Loading…
Cancel
Save