Duplicate entries in fw-prompt are now displayed nested by changing GTK ListStore -> TreeStore

Fixed bad scope returned with new rules by fw-prompt
shw_dev
Stephen Watt 7 years ago
parent ae1f6f12d0
commit 2fb872d8ad

@ -3,11 +3,15 @@ fw-daemon:
remove all stale references to SANDBOX: rules/policyForPathAndSandbox()
TLSGuard needs a lot of stuff removed
fw-prompt:
scope returned by new rules is bad (always set to process)
apply once rules still do not work because they the DBus invocation requires the guid to be passed
remove duplicate code for creating new treeview items
Each duplicate prompt needs to be expandable into individual items
more nesting for similar prompts (by application, pid, target host, etc)
gnome-shell:

@ -58,7 +58,7 @@ var dbuso *dbusObject
var userPrefs fpPreferences
var mainWin *gtk.Window
var Notebook *gtk.Notebook
var globalLS *gtk.ListStore = nil
var globalTS *gtk.TreeStore = nil
var globalTV *gtk.TreeView
var globalPromptLock = &sync.Mutex{}
var globalIcon *gtk.Image
@ -316,38 +316,53 @@ func createColumn(title string, id int) *gtk.TreeViewColumn {
return column
}
func createListStore(general bool) *gtk.ListStore {
func createTreeStore(general bool) *gtk.TreeStore {
colData := []glib.Type{glib.TYPE_INT, glib.TYPE_STRING, glib.TYPE_STRING, glib.TYPE_STRING, glib.TYPE_STRING, glib.TYPE_INT, glib.TYPE_STRING,
glib.TYPE_STRING, glib.TYPE_INT, glib.TYPE_INT, glib.TYPE_INT, glib.TYPE_STRING, glib.TYPE_STRING, glib.TYPE_INT, glib.TYPE_STRING, glib.TYPE_INT}
listStore, err := gtk.ListStoreNew(colData...)
treeStore, err := gtk.TreeStoreNew(colData...)
if err != nil {
log.Fatal("Unable to create list store:", err)
}
return listStore
return treeStore
}
func removeRequest(listStore *gtk.ListStore, guid string) {
func removeRequest(treeStore *gtk.TreeStore, guid string) {
removed := false
if globalLS == nil {
if globalTS == nil {
return
}
globalPromptLock.Lock()
defer globalPromptLock.Unlock()
remove_outer:
/* XXX: This is horrible. Figure out how to do this properly. */
for ridx := 0; ridx < globalLS.IterNChildren(nil); ridx++ {
rule, _, err := getRuleByIdx(ridx)
for ridx := 0; ridx < globalTS.IterNChildren(nil); ridx++ {
nchildren := 0
this_iter, err := globalTS.GetIterFromString(fmt.Sprintf("%d", ridx))
if err != nil {
break
} else if rule.GUID == guid {
removeSelectedRule(ridx, true)
removed = true
break
log.Println("Strange condition; couldn't get iter of known tree index:", err)
} else {
nchildren = globalTS.IterNChildren(this_iter)
}
for cidx := 0; cidx < nchildren-1; cidx++ {
sidx := cidx
if cidx == nchildren {
cidx = -1
}
rule, _, err := getRuleByIdx(ridx, sidx)
if err != nil {
break remove_outer
} else if rule.GUID == guid {
removeSelectedRule(ridx, true)
removed = true
break
}
}
}
@ -358,17 +373,17 @@ func removeRequest(listStore *gtk.ListStore, guid string) {
}
func addRequestInc(listStore *gtk.ListStore, guid, path, icon, proto string, pid int, ipaddr, hostname string, port, uid, gid int,
origin string, is_socks bool, optstring string, sandbox string, action int) bool {
func addRequestInc(treeStore *gtk.TreeStore, guid, path, icon, proto string, pid int, ipaddr, hostname string, port, uid, gid int,
origin, timestamp string, is_socks bool, optstring string, sandbox string, action int) bool {
duplicated := false
globalPromptLock.Lock()
defer globalPromptLock.Unlock()
for ridx := 0; ridx < globalLS.IterNChildren(nil); ridx++ {
for ridx := 0; ridx < globalTS.IterNChildren(nil); ridx++ {
/* XXX: This is horrible. Figure out how to do this properly. */
rule, iter, err := getRuleByIdx(ridx)
rule, iter, err := getRuleByIdx(ridx, -1)
if err != nil {
break
// XXX: not compared: optstring/sandbox
@ -376,7 +391,7 @@ func addRequestInc(listStore *gtk.ListStore, guid, path, icon, proto string, pid
(rule.Port == port) && (rule.UID == uid) && (rule.GID == gid) && (rule.Origin == origin) && (rule.IsSocks == is_socks) {
rule.nrefs++
err := globalLS.SetValue(iter, 0, rule.nrefs)
err := globalTS.SetValue(iter, 0, rule.nrefs)
if err != nil {
log.Println("Error creating duplicate firewall prompt entry:", err)
break
@ -384,6 +399,53 @@ func addRequestInc(listStore *gtk.ListStore, guid, path, icon, proto string, pid
fmt.Println("YES REALLY DUPLICATE: ", rule.nrefs)
duplicated = true
subiter := globalTS.Append(iter)
if is_socks {
if (optstring != "") && (strings.Index(optstring, "SOCKS") == -1) {
optstring = "SOCKS5 / " + optstring
} else if optstring == "" {
optstring = "SOCKS5"
}
}
var colVals = [16]interface{}{}
colVals[0] = 1
colVals[1] = guid
colVals[2] = path
colVals[3] = icon
colVals[4] = proto
colVals[5] = pid
if ipaddr == "" {
colVals[6] = "---"
} else {
colVals[6] = ipaddr
}
colVals[7] = hostname
colVals[8] = port
colVals[9] = uid
colVals[10] = gid
colVals[11] = origin
colVals[12] = timestamp
colVals[13] = 0
if is_socks {
colVals[13] = 1
}
colVals[14] = optstring
colVals[15] = action
for n := 0; n < len(colVals); n++ {
err = globalTS.SetValue(subiter, n, colVals[n])
if err != nil {
log.Fatal("Unable to add row:", err)
}
}
break
}
@ -392,27 +454,27 @@ func addRequestInc(listStore *gtk.ListStore, guid, path, icon, proto string, pid
return duplicated
}
func addRequestAsync(listStore *gtk.ListStore, guid, path, icon, proto string, pid int, ipaddr, hostname string, port, uid, gid int,
func addRequestAsync(treeStore *gtk.TreeStore, guid, path, icon, proto string, pid int, ipaddr, hostname string, port, uid, gid int,
origin, timestamp string, is_socks bool, optstring string, sandbox string, action int) bool {
addRequest(listStore, guid, path, icon, proto, pid, ipaddr, hostname, port, uid, gid, origin, timestamp, is_socks,
addRequest(treeStore, guid, path, icon, proto, pid, ipaddr, hostname, port, uid, gid, origin, timestamp, is_socks,
optstring, sandbox, action)
return true
}
func addRequest(listStore *gtk.ListStore, guid, path, icon, proto string, pid int, ipaddr, hostname string, port, uid, gid int,
func addRequest(treeStore *gtk.TreeStore, guid, path, icon, proto string, pid int, ipaddr, hostname string, port, uid, gid int,
origin, timestamp string, is_socks bool, optstring string, sandbox string, action int) *decisionWaiter {
if listStore == nil {
listStore = globalLS
if treeStore == nil {
treeStore = globalTS
waitTimes := []int{1, 2, 5, 10}
if listStore == nil {
if treeStore == nil {
log.Println("SGFW prompter was not ready to receive firewall request... waiting")
for _, wtime := range waitTimes {
time.Sleep(time.Duration(wtime) * time.Second)
listStore = globalLS
treeStore = globalTS
if listStore != nil {
if treeStore != nil {
break
}
@ -423,11 +485,11 @@ func addRequest(listStore *gtk.ListStore, guid, path, icon, proto string, pid in
}
if listStore == nil {
if treeStore == nil {
log.Fatal("SGFW prompter GUI failed to load for unknown reasons")
}
if addRequestInc(listStore, guid, path, icon, proto, pid, ipaddr, hostname, port, uid, gid, origin, is_socks, optstring, sandbox, action) {
if addRequestInc(treeStore, guid, path, icon, proto, pid, ipaddr, hostname, port, uid, gid, origin, timestamp, is_socks, optstring, sandbox, action) {
fmt.Println("REQUEST WAS DUPLICATE")
decision := addDecision()
globalPromptLock.Lock()
@ -439,7 +501,8 @@ func addRequest(listStore *gtk.ListStore, guid, path, icon, proto string, pid in
}
globalPromptLock.Lock()
iter := listStore.Append()
defer globalPromptLock.Unlock()
iter := treeStore.Append(nil)
if is_socks {
if (optstring != "") && (strings.Index(optstring, "SOCKS") == -1) {
@ -449,7 +512,7 @@ func addRequest(listStore *gtk.ListStore, guid, path, icon, proto string, pid in
}
}
colVals := make([]interface{}, 16)
var colVals = [16]interface{}{}
colVals[0] = 1
colVals[1] = guid
colVals[2] = path
@ -478,22 +541,16 @@ func addRequest(listStore *gtk.ListStore, guid, path, icon, proto string, pid in
colVals[14] = optstring
colVals[15] = action
colNums := make([]int, len(colVals))
for n := 0; n < len(colVals); n++ {
colNums[n] = n
}
err := listStore.Set(iter, colNums, colVals)
if err != nil {
log.Fatal("Unable to add row:", err)
err := treeStore.SetValue(iter, n, colVals[n])
if err != nil {
log.Fatal("Unable to add row:", err)
}
}
decision := addDecision()
dumpDecisions()
toggleHover()
globalPromptLock.Unlock()
return decision
}
@ -559,8 +616,8 @@ func setup_settings() {
Notebook.AppendPage(scrollbox, hLabel)
}
func lsGetStr(ls *gtk.ListStore, iter *gtk.TreeIter, idx int) (string, error) {
val, err := globalLS.GetValue(iter, idx)
func lsGetStr(ls *gtk.TreeStore, iter *gtk.TreeIter, idx int) (string, error) {
val, err := globalTS.GetValue(iter, idx)
if err != nil {
return "", err
}
@ -573,8 +630,8 @@ func lsGetStr(ls *gtk.ListStore, iter *gtk.TreeIter, idx int) (string, error) {
return sval, nil
}
func lsGetInt(ls *gtk.ListStore, iter *gtk.TreeIter, idx int) (int, error) {
val, err := globalLS.GetValue(iter, idx)
func lsGetInt(ls *gtk.TreeStore, iter *gtk.TreeIter, idx int) (int, error) {
val, err := globalTS.GetValue(iter, idx)
if err != nil {
return 0, err
}
@ -611,7 +668,7 @@ func makeDecision(idx int, rule string, scope int) error {
/* Do we need to hold the lock while this is called? Stay safe... */
func toggleHover() {
nitems := globalLS.IterNChildren(nil)
nitems := globalTS.IterNChildren(nil)
mainWin.SetKeepAbove(nitems > 0)
}
@ -743,12 +800,12 @@ func removeSelectedRule(idx int, rmdecision bool) error {
return err
}
iter, err := globalLS.GetIter(path)
iter, err := globalTS.GetIter(path)
if err != nil {
return err
}
globalLS.Remove(iter)
globalTS.Remove(iter)
if rmdecision {
// decisionWaiters = append(decisionWaiters[:idx], decisionWaiters[idx+1:]...)
@ -758,97 +815,103 @@ func removeSelectedRule(idx int, rmdecision bool) error {
return nil
}
// Needs to be locked by the caller
func numSelections() int {
sel, err := globalTV.GetSelection()
if err != nil {
return -1
}
rows := sel.GetSelectedRows(globalLS)
rows := sel.GetSelectedRows(globalTS)
return int(rows.Length())
}
// Needs to be locked by the caller
func getRuleByIdx(idx int) (ruleColumns, *gtk.TreeIter, error) {
func getRuleByIdx(idx, subidx int) (ruleColumns, *gtk.TreeIter, error) {
rule := ruleColumns{}
tpath := fmt.Sprintf("%d", idx)
path, err := gtk.TreePathNewFromString(fmt.Sprintf("%d", idx))
if subidx != -1 {
tpath = fmt.Sprintf("%d:%d", idx, subidx)
}
path, err := gtk.TreePathNewFromString(tpath)
if err != nil {
return rule, nil, err
}
iter, err := globalLS.GetIter(path)
iter, err := globalTS.GetIter(path)
if err != nil {
return rule, nil, err
}
rule.nrefs, err = lsGetInt(globalLS, iter, 0)
rule.nrefs, err = lsGetInt(globalTS, iter, 0)
if err != nil {
return rule, nil, err
}
rule.GUID, err = lsGetStr(globalLS, iter, 1)
rule.GUID, err = lsGetStr(globalTS, iter, 1)
if err != nil {
return rule, nil, err
}
rule.Path, err = lsGetStr(globalLS, iter, 2)
rule.Path, err = lsGetStr(globalTS, iter, 2)
if err != nil {
return rule, nil, err
}
rule.Icon, err = lsGetStr(globalLS, iter, 3)
rule.Icon, err = lsGetStr(globalTS, iter, 3)
if err != nil {
return rule, nil, err
}
rule.Proto, err = lsGetStr(globalLS, iter, 4)
rule.Proto, err = lsGetStr(globalTS, iter, 4)
if err != nil {
return rule, nil, err
}
rule.Pid, err = lsGetInt(globalLS, iter, 5)
rule.Pid, err = lsGetInt(globalTS, iter, 5)
if err != nil {
return rule, nil, err
}
rule.Target, err = lsGetStr(globalLS, iter, 6)
rule.Target, err = lsGetStr(globalTS, iter, 6)
if err != nil {
return rule, nil, err
}
rule.Hostname, err = lsGetStr(globalLS, iter, 7)
rule.Hostname, err = lsGetStr(globalTS, iter, 7)
if err != nil {
return rule, nil, err
}
rule.Port, err = lsGetInt(globalLS, iter, 8)
rule.Port, err = lsGetInt(globalTS, iter, 8)
if err != nil {
return rule, nil, err
}
rule.UID, err = lsGetInt(globalLS, iter, 9)
rule.UID, err = lsGetInt(globalTS, iter, 9)
if err != nil {
return rule, nil, err
}
rule.GID, err = lsGetInt(globalLS, iter, 10)
rule.GID, err = lsGetInt(globalTS, iter, 10)
if err != nil {
return rule, nil, err
}
rule.Origin, err = lsGetStr(globalLS, iter, 11)
rule.Origin, err = lsGetStr(globalTS, iter, 11)
if err != nil {
return rule, nil, err
}
rule.Timestamp, err = lsGetStr(globalLS, iter, 12)
rule.Timestamp, err = lsGetStr(globalTS, iter, 12)
if err != nil {
return rule, nil, err
}
rule.IsSocks = false
is_socks, err := lsGetInt(globalLS, iter, 13)
is_socks, err := lsGetInt(globalTS, iter, 13)
if err != nil {
return rule, nil, err
}
@ -857,7 +920,7 @@ func getRuleByIdx(idx int) (ruleColumns, *gtk.TreeIter, error) {
rule.IsSocks = true
}
rule.Scope, err = lsGetInt(globalLS, iter, 15)
rule.Scope, err = lsGetInt(globalTS, iter, 15)
if err != nil {
return rule, nil, err
}
@ -874,20 +937,35 @@ func getSelectedRule() (ruleColumns, int, error) {
return rule, -1, err
}
rows := sel.GetSelectedRows(globalLS)
rows := sel.GetSelectedRows(globalTS)
if rows.Length() <= 0 {
return rule, -1, errors.New("No selection was made")
return rule, -1, errors.New("no selection was made")
}
rdata := rows.NthData(0)
lIndex, err := strconv.Atoi(rdata.(*gtk.TreePath).String())
tpath := rdata.(*gtk.TreePath).String()
subidx := -1
ptoks := strings.Split(tpath, ":")
if len(ptoks) > 2 {
return rule, -1, errors.New("internal error parsing selected item tree path")
} else if len(ptoks) == 2 {
subidx, err = strconv.Atoi(ptoks[1])
if err != nil {
return rule, -1, err
}
tpath = ptoks[0]
}
lIndex, err := strconv.Atoi(tpath)
if err != nil {
return rule, -1, err
}
fmt.Println("lindex = ", lIndex)
rule, _, err = getRuleByIdx(lIndex)
fmt.Printf("lindex = %d : %d\n", lIndex, subidx)
rule, _, err = getRuleByIdx(lIndex, subidx)
if err != nil {
return rule, -1, err
}
@ -1203,10 +1281,10 @@ func main() {
acol.SetVisible(false)
tv.AppendColumn(acol)
listStore := createListStore(true)
globalLS = listStore
treeStore := createTreeStore(true)
globalTS = treeStore
tv.SetModel(listStore)
tv.SetModel(treeStore)
btnApprove.Connect("clicked", func() {
buttonAction("ALLOW")
@ -1242,7 +1320,7 @@ func main() {
editPort.SetText(strconv.Itoa(seldata.Port))
radioOnce.SetActive(seldata.Scope == int(sgfw.APPLY_ONCE))
radioProcess.SetSensitive(seldata.Pid > 0)
radioProcess.SetSensitive(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))

@ -58,7 +58,7 @@ func readConfig() {
PromptExpanded: false,
PromptExpert: false,
DefaultAction: "SESSION",
DefaultActionID: 1,
DefaultActionID: 0,
}
if len(buf) > 0 {

@ -41,6 +41,7 @@ const (
RULE_MODE_PROCESS
RULE_MODE_PERMANENT
RULE_MODE_SYSTEM
RULE_MODE_ONCE
)
// RuleModeString is used to get a rule mode string from its id
@ -49,6 +50,7 @@ var RuleModeString = map[RuleMode]string{
RULE_MODE_PROCESS: "PROCESS",
RULE_MODE_PERMANENT: "PERMANENT",
RULE_MODE_SYSTEM: "SYSTEM",
RULE_MODE_ONCE: "ONCE",
}
// RuleModeValue converts a mode string to its id
@ -57,16 +59,18 @@ var RuleModeValue = map[string]RuleMode{
RuleModeString[RULE_MODE_PROCESS]: RULE_MODE_PROCESS,
RuleModeString[RULE_MODE_PERMANENT]: RULE_MODE_PERMANENT,
RuleModeString[RULE_MODE_SYSTEM]: RULE_MODE_SYSTEM,
RuleModeString[RULE_MODE_ONCE]: RULE_MODE_ONCE,
}
//FilterScope contains a filter's time scope
type FilterScope uint16
const (
APPLY_ONCE FilterScope = iota
APPLY_SESSION
APPLY_SESSION FilterScope = iota
APPLY_PROCESS
APPLY_FOREVER
APPLY_SYSTEM
APPLY_ONCE
)
// FilterScopeString converts a filter scope ID to its string

@ -223,7 +223,7 @@ func stripTLSData(record []byte, start_ind, end_ind int, len_ind int, len_size i
if len_size < 1 || len_size > 2 {
return nil
} else if (start_ind >= end_ind) {
} else if start_ind >= end_ind {
return nil
} else if len_ind >= start_ind {
return nil
@ -235,7 +235,7 @@ func stripTLSData(record []byte, start_ind, end_ind int, len_ind int, len_size i
if len_size == 1 {
size = uint(rcopy[len_ind])
} else if len_size == 2 {
size = uint(binary.BigEndian.Uint16(rcopy[len_ind:len_ind+len_size]))
size = uint(binary.BigEndian.Uint16(rcopy[len_ind : len_ind+len_size]))
}
size -= uint(end_ind - start_ind)

Loading…
Cancel
Save