From 76b194840a128f5de27885a19551b754fc4df0fa Mon Sep 17 00:00:00 2001 From: dma Date: Fri, 16 Nov 2018 13:14:04 -0500 Subject: [PATCH] experimental realms / citadel integration --- fw-settings/main.go | 258 +++++++++--------- fw-settings/rules.go | 4 +- gnome-shell/firewall@subgraph.com/dialog.js | 126 +++++++-- .../firewall@subgraph.com/extension.js | 8 +- .../firewall@subgraph.com/stylesheet.css | 12 + sgfw/dbus.go | 4 +- sgfw/policy.go | 8 +- sgfw/prompt.go | 28 +- sgfw/rules.go | 2 +- 9 files changed, 287 insertions(+), 163 deletions(-) diff --git a/fw-settings/main.go b/fw-settings/main.go index 95f0b45..b6ee156 100644 --- a/fw-settings/main.go +++ b/fw-settings/main.go @@ -17,8 +17,8 @@ import ( "io/ioutil" "os" "os/signal" - "strings" "strconv" + "strings" "sync" "syscall" "time" @@ -29,6 +29,8 @@ import ( "github.com/gotk3/gotk3/gdk" "github.com/gotk3/gotk3/glib" "github.com/gotk3/gotk3/gtk" + + "github.com/godbus/dbus" ) type promptModes uint @@ -55,6 +57,7 @@ type appShortcuts struct { type cbPromptAdd func(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 type cbPromptRemove func(string) + var cbPromptAddRequest cbPromptAdd = nil var cbPromptRemoveRequest cbPromptRemove = nil @@ -66,64 +69,63 @@ type fwApp struct { forceMenu bool - Dbus *dbusObject + Dbus *dbusObject DbusServer *dbusServer promptMode promptModes - prompt *Prompt + prompt *Prompt - Config *sgfw.FirewallConfigs + Config *sgfw.FirewallConfigs Settings *settings.Settings - winb *builder - win *gtk.ApplicationWindow + winb *builder + win *gtk.ApplicationWindow repopMutex *sync.Mutex swRulesPermanent *gtk.ScrolledWindow - swRulesSession *gtk.ScrolledWindow - swRulesProcess *gtk.ScrolledWindow - swRulesSystem *gtk.ScrolledWindow - swPrompt *gtk.ScrolledWindow + swRulesSession *gtk.ScrolledWindow + swRulesProcess *gtk.ScrolledWindow + swRulesSystem *gtk.ScrolledWindow + swPrompt *gtk.ScrolledWindow boxPermanent *gtk.ListBox - boxSession *gtk.ListBox - boxProcess *gtk.ListBox - boxSystem *gtk.ListBox + boxSession *gtk.ListBox + boxProcess *gtk.ListBox + boxSystem *gtk.ListBox rlPermanent *ruleList - rlSession *ruleList - rlProcess *ruleList - rlSystem *ruleList + rlSession *ruleList + rlProcess *ruleList + rlSystem *ruleList - btnNewRule *gtk.Button - nbRules *gtk.Notebook - tlStack *gtk.Stack + btnNewRule *gtk.Button + nbRules *gtk.Notebook + tlStack *gtk.Stack tlStackSwitcher *gtk.StackSwitcher - gridConfig *gtk.Grid - entrySearch *gtk.SearchEntry - btnSearch *gtk.ToggleButton - revealerSearch *gtk.Revealer - boxAppMenu *gtk.Box - btnAppMenu *gtk.MenuButton - dialog *gtk.MessageDialog + gridConfig *gtk.Grid + entrySearch *gtk.SearchEntry + btnSearch *gtk.ToggleButton + revealerSearch *gtk.Revealer + boxAppMenu *gtk.Box + btnAppMenu *gtk.MenuButton + dialog *gtk.MessageDialog signalDelete glib.SignalHandle - lcache string + lcache string shortcuts []appShortcuts - userMap map[int32]string - userIDs []int32 - groupMap map[int32]string - groupIDs []int32 - userMapLock *sync.Mutex + userMap map[int32]string + userIDs []int32 + groupMap map[int32]string + groupIDs []int32 + userMapLock *sync.Mutex groupMapLock *sync.Mutex - intcount uint + intcount uint ozProfiles []string } - /* * App Setup */ @@ -183,7 +185,7 @@ func (fa *fwApp) initGtk() { appFlags |= glib.APPLICATION_CAN_OVERRIDE_APP_ID //appFlags |= glib.APPLICATION_IS_LAUNCHER //appFlags |= glib.APPLICATION_IS_SERVICE - app, err := gtk.ApplicationNew("com.subgraph.Firewall.Settings", appFlags)//glib.APPLICATION_FLAGS_NONE) + app, err := gtk.ApplicationNew("com.subgraph.Firewall.Settings", appFlags) //glib.APPLICATION_FLAGS_NONE) if err != nil { panic(fmt.Sprintf("gtk.ApplicationNew() failed: %v", err)) } @@ -241,25 +243,25 @@ func (fa *fwApp) build() { func (fa *fwApp) registerActions() { anr := glib.SimpleActionNew("new_rule", glib.VARIANT_TYPE_NONE) - anr.Connect("activate", func () { + anr.Connect("activate", func() { fa.btnNewRule.Activate() }) fa.ActionMap.AddAction(&anr.Action) snr := glib.SimpleActionNew("shortcuts", glib.VARIANT_TYPE_NONE) - snr.Connect("activate", func () { + snr.Connect("activate", func() { fa.showShortcutsWindow() }) fa.ActionMap.AddAction(&snr.Action) abnr := glib.SimpleActionNew("about", glib.VARIANT_TYPE_NONE) - abnr.Connect("activate", func() {fa.showAboutDialog()}) + abnr.Connect("activate", func() { fa.showAboutDialog() }) fa.ActionMap.AddAction(&abnr.Action) -/* - hbnr := glib.SimpleActionNew("help", glib.VARIANT_TYPE_NONE) - hbnr.Connect("activate", func() {fmt.Println("UNIMPLEMENTED")}) - fa.ActionMap.AddAction(&hbnr.Action) -*/ + /* + hbnr := glib.SimpleActionNew("help", glib.VARIANT_TYPE_NONE) + hbnr.Connect("activate", func() {fmt.Println("UNIMPLEMENTED")}) + fa.ActionMap.AddAction(&hbnr.Action) + */ qnr := glib.SimpleActionNew("quit", glib.VARIANT_TYPE_NONE) qnr.Connect("activate", func() { fa.win.Close() @@ -268,18 +270,18 @@ func (fa *fwApp) registerActions() { } func (fa *fwApp) registerShortcuts() { - fa.ConnectShortcut("Page_Down", "rules", "Go to next rules views", fa.win.Window, func (win gtk.Window) { + fa.ConnectShortcut("Page_Down", "rules", "Go to next rules views", fa.win.Window, func(win gtk.Window) { fa.switchRulesItem(switcherDirectionUp) }) - fa.ConnectShortcut("Page_Up", "rules", "Go to previous rules views", fa.win.Window, func (win gtk.Window) { + fa.ConnectShortcut("Page_Up", "rules", "Go to previous rules views", fa.win.Window, func(win gtk.Window) { fa.switchRulesItem(switcherDirectionDown) }) - fa.ConnectShortcut("n", "rules", "Create new rule", fa.win.Window, func (win gtk.Window) { + fa.ConnectShortcut("n", "rules", "Create new rule", fa.win.Window, func(win gtk.Window) { if fa.btnNewRule.GetSensitive() { fa.btnNewRule.Emit("clicked") } }) - fa.ConnectShortcut("f", "rules", "Search for rule", fa.win.Window, func (win gtk.Window) { + fa.ConnectShortcut("f", "rules", "Search for rule", fa.win.Window, func(win gtk.Window) { if fa.tlStack.GetVisibleChildName() == "rules" { reveal := fa.revealerSearch.GetRevealChild() if !reveal { @@ -289,31 +291,31 @@ func (fa *fwApp) registerShortcuts() { fa.entrySearch.Widget.GrabFocus() } }) - fa.ConnectShortcut("Page_Down", "general", "Go to the next view", fa.win.Window, func (win gtk.Window) { + fa.ConnectShortcut("Page_Down", "general", "Go to the next view", fa.win.Window, func(win gtk.Window) { fa.switchStackItem(switcherDirectionDown) }) - fa.ConnectShortcut("Page_Up", "general", "Go to the previous view", fa.win.Window, func (win gtk.Window) { + fa.ConnectShortcut("Page_Up", "general", "Go to the previous view", fa.win.Window, func(win gtk.Window) { fa.switchStackItem(switcherDirectionUp) }) if fa.promptMode != promptModeDisabled { fa.RegisterShortcutHelp("space", "general", "Answer first firewall prompt") } -/* - fa.ConnectShortcut("question", "general", "Show the program help", fa.win.Window, func (win gtk.Window) { - ha := fa.ActionMap.LookupAction("help") - if ha != nil { - ha.Activate(nil) - } - }) -*/ - fa.ConnectShortcut("F1", "general", "Show this help window", fa.win.Window, func (win gtk.Window) { + /* + fa.ConnectShortcut("question", "general", "Show the program help", fa.win.Window, func (win gtk.Window) { + ha := fa.ActionMap.LookupAction("help") + if ha != nil { + ha.Activate(nil) + } + }) + */ + fa.ConnectShortcut("F1", "general", "Show this help window", fa.win.Window, func(win gtk.Window) { fa.showShortcutsWindow() }) - fa.ConnectShortcut("q", "general", "Exit program", fa.win.Window, func (win gtk.Window) { + fa.ConnectShortcut("q", "general", "Exit program", fa.win.Window, func(win gtk.Window) { fa.win.Close() }) // Easter Egg - fa.ConnectShortcut("F5", "", "", fa.win.Window, func (win gtk.Window) { + fa.ConnectShortcut("F5", "", "", fa.win.Window, func(win gtk.Window) { fa.repopulateWindow() fa.loadConfig(false) }) @@ -342,12 +344,12 @@ func (fa *fwApp) buildWindow() { fa.win.SetIconName("security-medium") fa.win.SetTitle("Subgraph Firewall Settings") -/* - fa.winb.ConnectSignals(map[string]interface{} { - "on_changed_search": fa.onChangedSearch, - "on_stoped_search": fa.onStopedSearch, - }) -*/ + /* + fa.winb.ConnectSignals(map[string]interface{} { + "on_changed_search": fa.onChangedSearch, + "on_stoped_search": fa.onStopedSearch, + }) + */ //fa.swRulesPermanent.Connect("key-press-event", fa.onRulesKeyPress) fa.entrySearch.Connect("search-changed", fa.onChangedSearch) fa.entrySearch.Connect("stop-search", fa.onStopedSearch) @@ -414,7 +416,6 @@ func (fa *fwApp) buildAppMenu() { } } - /* * Windows */ @@ -449,7 +450,7 @@ func (fa *fwApp) showPromptQuit() bool { func (fa *fwApp) showAddRuleDialog() { rule := &sgfw.DbusRule{} rl := &ruleList{app: fa} - rr := &ruleRow{ rl: rl, rule: rule} + rr := &ruleRow{rl: rl, rule: rule} rnew := newRuleAdd(rr, DIALOG_MODE_NEW) rnew.update() rnew.run("", nil) @@ -479,7 +480,7 @@ func (fa *fwApp) showAboutDialog() { ad, _ := gtk.AboutDialogNew() ad.SetName(sfs) ad.SetProgramName(sfs) - ad.SetAuthors([]string{"Subgraph Inc"}) + ad.SetAuthors([]string{"Subgraph Inc"}) //ad.AddCreditSection("", []string{"- Bruce Leidl", "- David Mirza", "- Stephen Watt", "- Matthieu Lalonde"}) ad.SetVersion("0.1.0") ad.SetCopyright(fmt.Sprintf("© %s.", cs)) @@ -501,8 +502,8 @@ func (fa *fwApp) showShortcutsWindow() { var groups = []string{"general", "rules", "prompt"} var titles = map[string]string{ "general": "General", - "rules": "Rules", - "prompt": "Firewall Prompt", + "rules": "Rules", + "prompt": "Firewall Prompt", } xv := new(GtkXMLInterface) xv.Comment = " interface-requires gtk+ 3.20 " @@ -517,19 +518,19 @@ func (fa *fwApp) showShortcutsWindow() { xss := new(GtkXMLObject) xss.Class = "GtkShortcutsSection" xss.Properties = []GtkXMLProperty{ - {Name: "visible", Value: "1"}, - {Name: "section-name", Value: "shortcuts"}, - {Name: "max-height", Value: "16"}, - } + {Name: "visible", Value: "1"}, + {Name: "section-name", Value: "shortcuts"}, + {Name: "max-height", Value: "16"}, + } xsw.Children = append(xsw.Children, GtkXMLChild{Objects: []*GtkXMLObject{xss}}) for _, g := range groups { xsg := new(GtkXMLObject) xsg.Class = "GtkShortcutsGroup" xsg.Properties = []GtkXMLProperty{ - {Name: "title", Value: titles[g], Translatable: "yes"}, - {Name: "visible", Value: "1"}, - } + {Name: "title", Value: titles[g], Translatable: "yes"}, + {Name: "visible", Value: "1"}, + } found := false for _, sc := range fa.shortcuts { if sc.Group != g { @@ -539,10 +540,10 @@ func (fa *fwApp) showShortcutsWindow() { xps := new(GtkXMLObject) xps.Class = "GtkShortcutsShortcut" xps.Properties = []GtkXMLProperty{ - {Name: "visible", Value: "yes"}, - {Name: "accelerator", Value: sc.Accel}, - {Name: "title", Translatable: "yes", Value: sc.Title}, - } + {Name: "visible", Value: "yes"}, + {Name: "accelerator", Value: sc.Accel}, + {Name: "title", Translatable: "yes", Value: sc.Title}, + } xsg.Children = append(xsg.Children, GtkXMLChild{Objects: []*GtkXMLObject{xps}}) } if found { @@ -573,7 +574,6 @@ func (fa *fwApp) showShortcutsWindow() { } } - /* * Private Utils */ @@ -583,7 +583,7 @@ func (fa *fwApp) populateWindow() { if fa.boxPermanent == nil { fa.boxPermanent, _ = gtk.ListBoxNew() fa.swRulesPermanent.Add(fa.boxPermanent) - + fa.rlPermanent = newRuleList(fa, fa.boxPermanent, sgfw.RULE_MODE_PERMANENT) if _, err := fa.Dbus.isEnabled(); err != nil { failDialog(&fa.win.Window, "Unable is connect to firewall daemon. Is it running?") @@ -592,7 +592,6 @@ func (fa *fwApp) populateWindow() { fa.rlPermanent.loadRules(true) fa.rlPermanent.reloadRules(tt) - if fa.boxSession == nil { fa.boxSession, _ = gtk.ListBoxNew() fa.swRulesSession.Add(fa.boxSession) @@ -605,7 +604,6 @@ func (fa *fwApp) populateWindow() { fa.rlSession.loadRules(true) fa.rlSession.reloadRules(tt) - if fa.boxProcess == nil { fa.boxProcess, _ = gtk.ListBoxNew() fa.swRulesProcess.Add(fa.boxProcess) @@ -621,7 +619,7 @@ func (fa *fwApp) populateWindow() { if fa.boxSystem == nil { fa.boxSystem, _ = gtk.ListBoxNew() fa.swRulesSystem.Add(fa.boxSystem) - + fa.rlSystem = newRuleList(fa, fa.boxSystem, sgfw.RULE_MODE_SYSTEM) if _, err := fa.Dbus.isEnabled(); err != nil { failDialog(&fa.win.Window, "Unable is connect to firewall daemon. Is it running?") @@ -630,38 +628,37 @@ func (fa *fwApp) populateWindow() { fa.rlSystem.loadRules(true) fa.rlSystem.reloadRules(tt) - } func (fa *fwApp) repopulateWindow() { fmt.Println("Refreshing firewall rule list.") fa.repopMutex.Lock() defer fa.repopMutex.Unlock() -/* - child, err := fa.swRulesPermanent.GetChild() - if err != nil { - failDialog(&fa.win.Window, "Unable to clear out permanent rules list display: %v", err) - } - fa.swRulesPermanent.Remove(child) + /* + child, err := fa.swRulesPermanent.GetChild() + if err != nil { + failDialog(&fa.win.Window, "Unable to clear out permanent rules list display: %v", err) + } + fa.swRulesPermanent.Remove(child) - child, err = fa.swRulesSession.GetChild() - if err != nil { - failDialog(&fa.win.Window, "Unable to clear out session rules list display: %v", err) - } - fa.swRulesSession.Remove(child) + child, err = fa.swRulesSession.GetChild() + if err != nil { + failDialog(&fa.win.Window, "Unable to clear out session rules list display: %v", err) + } + fa.swRulesSession.Remove(child) - child, err = fa.swRulesProcess.GetChild() - if err != nil { - failDialog(&fa.win.Window, "Unable to clear out process rules list display: %v", err) - } - fa.swRulesProcess.Remove(child) + child, err = fa.swRulesProcess.GetChild() + if err != nil { + failDialog(&fa.win.Window, "Unable to clear out process rules list display: %v", err) + } + fa.swRulesProcess.Remove(child) - child, err = fa.swRulesSystem.GetChild() - if err != nil { - failDialog(&fa.win.Window, "Unable to clear out system rules list display: %v", err) - } - fa.swRulesSystem.Remove(child) -*/ + child, err = fa.swRulesSystem.GetChild() + if err != nil { + failDialog(&fa.win.Window, "Unable to clear out system rules list display: %v", err) + } + fa.swRulesSystem.Remove(child) + */ if fa.tlStack.GetVisibleChildName() != "rules" && fa.promptMode == promptModeDisabled { stack := fa.tlStack.GetChildByName("rules") err := fa.tlStack.ChildSetProperty(stack, "needs-attention", true) @@ -701,7 +698,7 @@ func (fa *fwApp) switchStackItem(dir switcherDirection) { stacks := []string{"prompt", "rules", "config"} stacksByName := map[string]int{ "prompt": 0, - "rules": 1, + "rules": 1, "config": 2, } if fa.promptMode == promptModeDisabled { @@ -727,7 +724,6 @@ func (fa *fwApp) switchStackItem(dir switcherDirection) { fa.onStackChanged() } - /* * Handlers */ @@ -738,7 +734,7 @@ func (fa *fwApp) handleSignals(c <-chan os.Signal) { switch sig { case syscall.SIGINT: if fa.intcount == 0 { - glib.IdleAdd(func () bool { + glib.IdleAdd(func() bool { fa.win.Close() return false }) @@ -780,7 +776,7 @@ func (fa *fwApp) onWindowDelete() bool { } func (fa *fwApp) onStackChanged() { -tn := fa.tlStack.GetVisibleChildName() + tn := fa.tlStack.GetVisibleChildName() nra := fa.ActionMap.LookupAction("new_rule") if tn == "rules" { fa.btnNewRule.SetSensitive(true) @@ -803,7 +799,7 @@ tn := fa.tlStack.GetVisibleChildName() nra.SetProperty("enabled", false) } - if fa.prompt != nil && tn != "prompt"{ + if fa.prompt != nil && tn != "prompt" { pstack := fa.tlStack.GetChildByName("prompt") nag, _ := fa.tlStack.ChildGetProperty(pstack, "needs-attention", glib.TYPE_BOOLEAN) if fa.prompt.HasItems() && !nag.(bool) { @@ -853,7 +849,6 @@ func (fa *fwApp) onRulesKeyPress(i interface{}, e *gdk.Event) bool { return true } - /* * Users, Groups */ @@ -867,7 +862,7 @@ func (fa *fwApp) cacheUsers() error { fa.userMapLock.Lock() defer fa.userMapLock.Unlock() - readColonFile(f, func (line []byte) { + readColonFile(f, func(line []byte) { t := strings.Split(string(line), ":") id, _ := strconv.ParseInt(t[2], 10, 32) fa.userMap[int32(id)] = t[0] @@ -886,7 +881,7 @@ func (fa *fwApp) cacheGroups() error { fa.groupMapLock.Lock() defer fa.groupMapLock.Unlock() - readColonFile(f, func (line []byte) { + readColonFile(f, func(line []byte) { t := strings.Split(string(line), ":") id, _ := strconv.ParseInt(t[2], 10, 32) fa.groupMap[int32(id)] = t[0] @@ -895,7 +890,6 @@ func (fa *fwApp) cacheGroups() error { return nil } - /* * Exported */ @@ -918,14 +912,23 @@ func (fa *fwApp) ConnectShortcut(accel, group, title string, w gtk.Window, actio }) w.AddAccelGroup(gr) - w.Connect("delete-event", func () bool { + w.Connect("delete-event", func() bool { w.RemoveAccelGroup(gr) return false }) } -func (fa *fwApp) LookupUsername(uid int32) string { +func (fa *fwApp) LookupUsername(realm string, uid int32) string { // TODO: needs to be realm aware + // TODO: cache ^^ + if realm != "" { + user := "" + var db, _ = dbus.SystemBus() + obj := db.Object("com.subgraph.realms", "/") + obj.Call("com.subgraph.realms.Manager.RealmUsernameFromUID", 0, realm, strconv.Itoa(int(uid))).Store(&user) + return user + } + if uid == -1 { return "any" } @@ -938,8 +941,17 @@ func (fa *fwApp) LookupUsername(uid int32) string { return "unknown" } -func (fa *fwApp) LookupGroup(gid int32) string { +func (fa *fwApp) LookupGroup(realm string, gid int32) string { // TODO: needs to be realm aware + // ^^ cache + if realm != "" { + group := "" + var db, _ = dbus.SystemBus() + obj := db.Object("com.subgraph.realms", "/") + obj.Call("com.subgraph.realms.Manager.RealmGroupnameFromGID", 0, realm, strconv.Itoa(int(gid))).Store(&group) + return group + } + if gid == -1 { return "any" } @@ -952,7 +964,6 @@ func (fa *fwApp) LookupGroup(gid int32) string { return "unknown" } - /* * Global Utils */ @@ -990,7 +1001,6 @@ func readColonFile(r io.Reader, fn func(line []byte)) (v interface{}, err error) return nil, bs.Err() } - /* * Main */ diff --git a/fw-settings/rules.go b/fw-settings/rules.go index 892b222..b782a63 100644 --- a/fw-settings/rules.go +++ b/fw-settings/rules.go @@ -226,13 +226,13 @@ func (rr *ruleRow) update() { tt = tt + " for " } if rr.rule.UID > -1 { - tt = tt + rr.rl.app.LookupUsername(rr.rule.UID) + tt = tt + rr.rl.app.LookupUsername(rr.rule.Sandbox, rr.rule.UID) } if rr.rule.UID > -1 && rr.rule.GID > -1 { tt = tt + ":" } if rr.rule.GID > -1 { - tt = tt + rr.rl.app.LookupGroup(rr.rule.GID) + tt = tt + rr.rl.app.LookupGroup(rr.rule.Sandbox, rr.rule.GID) } rr.gtkLabelTarget.SetText(tt) } diff --git a/gnome-shell/firewall@subgraph.com/dialog.js b/gnome-shell/firewall@subgraph.com/dialog.js index 42ab747..25a3246 100644 --- a/gnome-shell/firewall@subgraph.com/dialog.js +++ b/gnome-shell/firewall@subgraph.com/dialog.js @@ -9,6 +9,8 @@ const St = imports.gi.St; const CheckBox = imports.ui.checkBox const ModalDialog = imports.ui.modalDialog; const Tweener = imports.ui.tweener; +const Extension = imports.misc.extensionUtils.getCurrentExtension(); +const Misc = Extension.imports.misc; const RuleScope = { APPLY_SESSION: 0, @@ -22,36 +24,47 @@ const DetailSection = new Lang.Class({ Name: 'DetailSection', _init: function(sandboxed) { - this.actor = new St.BoxLayout({ style_class: 'fw-details-section' }); - this._left = new St.BoxLayout({ vertical: true, style_class: 'fw-details-left'}); + //this.actor = new St.BoxLayout({ style_class: 'fw-details-section', pack_start: false }); + this.actor = new St.BoxLayout({ style_class: 'fw-details-section-container', pack_start: false }); + this._cont = new St.BoxLayout({ style_class: 'fw-details-section' }); + this._left = new St.BoxLayout({ vertical: true, style_class: 'fw-details-left' }); + //this._right = new St.BoxLayout({ vertical: true, style_class: 'fw-details-right' }); this._right = new St.BoxLayout({ vertical: true, style_class: 'fw-details-right' }); - this.actor.add_child(this._left); - this.actor.add_child(this._right); - + this._more = new St.BoxLayout({ vertical: true, style_class: 'fw-details-right', y_align: Clutter.ActorAlign.CENTER, x_align: St.Align.END }); + this._cont.add_child(this._left); + this._cont.add_child(this._right); + this.actor.add_child(this._cont); + this.actor.add_child(this._more); + //this.actor.add_child(this._left); + //this.actor.add_child(this._right); + //this.actor.add_child(this._more); + if (sandboxed) { + this.sandbox = this._addDetails("Realm:"); + } this.ipAddr = this._addDetails("IP Address:"); this.path = this._addDetails("Path:"); this.pid = this._addDetails("Process ID:"); - this.origin = this._addDetails("Origin:"); + this.origin = this._addDetails("Origin IP address:"); this.user = this._addCheckboxDetails("User:"); this.group = this._addCheckboxDetails("Group:"); this.sandboxed = sandboxed; - if (sandboxed) { - this.sandbox = this._addDetails("Sandbox:"); - } this.optstring = this._addDetails(""); }, _addDetails: function(text, d) { let title = new St.Label({ style_class: 'fw-detail-title', text: text}); + //this._left.add(title, { expand: true, x_fill: false, x_align: St.Align.END}); this._left.add(title, { expand: true, x_fill: false, x_align: St.Align.END}); let msg = new St.Label({ style_class: 'fw-detail-message' }); if (d === undefined) { - this._right.add(msg); + // this._right.add(msg); + this._right.add(msg, { expand: true, x_fill: false, x_align: St.Align.END}); } else { - let inner = new St.BoxLayout({ vertical: false, style_class: 'fw-ugid-apply-checkbox' }); - inner.add(msg); - inner.add(d.actor); + let inner = new St.BoxLayout({ vertical: false, style_class: 'fw-ugid-apply-checkbox', x_align: St.Align.END }); + //inner.add(msg); + inner.add(msg, { expand: true, x_fill: true, x_align: St.Align.END}); + inner.add(d.actor, { x_fill: true, x_align: St.Align.END, expand: true}); this._right.add(inner); } return msg; @@ -60,13 +73,14 @@ const DetailSection = new Lang.Class({ _addCheckboxDetails: function(text) { let title = new St.Label({ style_class: 'fw-detail-title', text: text}); title.hide(); + //this._left.add(title, { expand: true, x_fill: false, x_align: St.Align.END}); this._left.add(title, { expand: true, x_fill: false, x_align: St.Align.END}); //let msg = new St.Label({ style_class: 'fw-detail-message' }); let check = new CheckBox.CheckBox(""); check.actor.checked = true; check.actor.hide(); - this._right.add(check.actor); + this._right.add(check.actor, { expand: true, x_align: St.Align.END, x_fill: false}); /* let inner = new St.BoxLayout({ vertical: false, style_class: 'fw-ugid-apply-checkbox' }); @@ -115,10 +129,78 @@ const DetailSection = new Lang.Class({ } if (sandbox != "") { - this.sandbox.text = sandbox; - } - - this.optstring.text = optstring + + //this.sandbox = new St.Label({ style_class: 'fw-detail-message' }); + //this._right.remove_child(this.sandbox); + //let yek = new St.Label({ style_class: 'fw-detail-message' }); + var [r,g,b] = Misc.pastelColorsFromName(sandbox); + var hexbg = r.toString(16) + g.toString(16) + b.toString(16); + this.sandbox.get_clutter_text().set_markup(''+sandbox+''); + //this._right.add_child(yek); + //this.sandbox.show(); +// result_label.get_clutter_text().set_markup('' + Fuzzy.fuzzysort.highlight(r[k], open = '', close = '') + ''); + + // global.log(hexbg); + /* var _dot = new St.Widget({ style_class: 'realm-running-dot',//'app-well-app-running-dot', + layout_manager: new Clutter.BinLayout(), + x_expand: true, y_expand: true, + x_align: Clutter.ActorAlign.CENTER, + y_align: Clutter.ActorAlign.CENTER }); + + _dot.style = 'background-color: #'+hexbg+';width: '+width+'px;'; + this.sandbox.add_actor(_dot); + this.sandbox = _dot; + _dot.show(); */ + + } + + this.optstring.text = optstring; + let windows = global.get_window_actors(); + let tnpid = -1; + let winpids = {}; + let t; + let mw; + let x = 0; + let thumb = false; + for (x = 0; x < windows.length; x++) { + mw = windows[x].get_meta_window(); + if (typeof mw != 'undefined') { + global.log("pid: "+pid+" mw.get_client_pid(): "+mw.get_client_pid().toString()); + winpids[pid] = windows[x].get_meta_window(); + if (pid == mw.get_client_pid().toString()) { + t = Misc.getThumbnail(mw); + this._more.add(t); + tnpid = pid; + thumb = true; + break; + } + } + } + if (pid > 1 && tnpid == -1) { + tnpid = Misc.findParentProcessWindow(pid); + global.log(tnpid); + } + if (tnpid > 1 && thumb == false) { + for (x = 0; x < windows.length; x++) { + mw = windows[x].get_meta_window(); + if (typeof mw != 'undefined') { + if (tnpid == mw.get_client_pid().toString()) { + t = Misc.getThumbnail(mw); + t.expand = true; + t.x_align = St.Align.END; + t.x_fill = true; + t.y_fill = true; + this._more.add(t); + thumb = true; + break; + } + } + } + + } + if (thumb == true) { + this._right.height = this._left.height; + } } }); @@ -184,7 +266,7 @@ const OptionList = new Lang.Class({ } this.actor.add_child(this.buttonGroup.actor); this.items = []; - this._selected; + this._selected = ""; this.tlsGuard = false; if (sandboxed) { this.tlsGuard = true; @@ -595,7 +677,9 @@ const PromptDialogHeader = new Lang.Class({ if (!remaining) { this.waiting.text; } else { - this.waiting.text = "Remaining: " + remaining; + //ithis.waiting.text = "Remaining: " + remaining; + + // this.waiting = new St.Label({style_class: 'fw-prompt-waiting', text: "Remaining: " + remaining}); } }, @@ -782,7 +866,7 @@ const PromptDialog = new Lang.Class({ } if (sandbox != "") { - application = application + " (sandboxed)" + application = application; } this.header.setTitle(application); diff --git a/gnome-shell/firewall@subgraph.com/extension.js b/gnome-shell/firewall@subgraph.com/extension.js index c4d426f..930633a 100644 --- a/gnome-shell/firewall@subgraph.com/extension.js +++ b/gnome-shell/firewall@subgraph.com/extension.js @@ -134,7 +134,7 @@ const FirewallPromptHandler = new Lang.Class({ return false; } - let fname = binding.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); }); + // let fname = binding.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); }); let fname = "_on"+ fname[0].toUpperCase() + fname.substr(1); if (!( fname in this._dialog )) { log("SGFW: Invalid key binding (1)... " + fname); @@ -291,18 +291,18 @@ const FirewallPromptHandler = new Lang.Class({ } }, - _updateDialogRemainingPrompts: function() { + _updateDialogRemainingPrompts: function() { /* if (this._dialog === null) { return; } try { let remaining = (this._guids.length - 1); - if (remaining > 0) { + /*if (remaining > 0) { this._dialog.updateRemainingPrompts(remaining); } } catch(err) { log("SGFW: Error while updating remaining dialogs count: " + err); - } + }*/ return; } diff --git a/gnome-shell/firewall@subgraph.com/stylesheet.css b/gnome-shell/firewall@subgraph.com/stylesheet.css index 90f237e..1a64d08 100644 --- a/gnome-shell/firewall@subgraph.com/stylesheet.css +++ b/gnome-shell/firewall@subgraph.com/stylesheet.css @@ -76,6 +76,10 @@ font-weight: bold; } +.fw-details-section-container { + padding: 5px; +} + .fw-details-section { padding: 20px; } @@ -113,3 +117,11 @@ padding-top: 2px !important; vertical-align: middle; } + +.realm-running-dot { + min-width: 15px; + height: 2px;/*3*/ + background-color: #ffffff; + padding: 0px 0px 0px 0px; + margin: 0px 0px 0px 0px; +} diff --git a/sgfw/dbus.go b/sgfw/dbus.go index 41f3fc3..1c74017 100644 --- a/sgfw/dbus.go +++ b/sgfw/dbus.go @@ -269,8 +269,8 @@ func (ds *dbusServer) GetPendingRequests(policy string) (bool, *dbus.Error) { pc.proto(), int32(pc.procInfo().UID), int32(pc.procInfo().GID), - uidToUser(pc.procInfo().UID), - gidToGroup(pc.procInfo().GID), + uidToUser(pc.sandbox(),pc.procInfo().UID), + gidToGroup(pc.sandbox(),pc.procInfo().GID), int32(pc.procInfo().Pid), pc.sandbox(), pc.socks(), diff --git a/sgfw/policy.go b/sgfw/policy.go index b8c0e50..74c8c58 100644 --- a/sgfw/policy.go +++ b/sgfw/policy.go @@ -426,7 +426,7 @@ func (p *Policy) filterPendingOne(rule *Rule, guid string) { continue } - 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.sandbox(),pc.procInfo().UID), gidToGroup(pc.sandbox(),pc.procInfo().GID), pc.procInfo().Sandbox) { prompter := pc.getPrompter() if prompter == nil { @@ -465,7 +465,7 @@ func (p *Policy) filterPendingOne(rule *Rule, guid string) { func (p *Policy) filterPending(rule *Rule) { remaining := []pendingConnection{} 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.sandbox(),pc.procInfo().UID), gidToGroup(pc.sandbox(),pc.procInfo().GID), pc.procInfo().Sandbox) { prompter := pc.getPrompter() if prompter == nil { @@ -606,7 +606,6 @@ func (fw *Firewall) filterPacket(pkt *nfqueue.NFQPacket, timestamp time.Time) { // return } else { ppath = pinfo.ExePath - optstring = fmt.Sprintf("Realm: %s", pinfo.Realm) cf := strings.Fields(pinfo.CmdLine) if len(cf) > 1 && strings.HasPrefix(cf[1], "/") { for _, intp := range _interpreters { @@ -896,7 +895,8 @@ func findProcessForPacket(pkt *nfqueue.NFQPacket, reverse bool, strictness int) } if res != nil { - optstr = "Realm: " + OzInitPids[i].Name + //optstr = "Realm: " + OzInitPids[i].Name + res.Realm = OzInitPids[i].Name res.Sandbox = OzInitPids[i].Name res.ExePath = GetRealRoot(res.ExePath, OzInitPids[i].Pid) break diff --git a/sgfw/prompt.go b/sgfw/prompt.go index a8cb987..0af716f 100644 --- a/sgfw/prompt.go +++ b/sgfw/prompt.go @@ -158,7 +158,7 @@ func monitorPromptFDs(pc pendingConnection) { //fmt.Printf("ADD TO MONITOR: %v | %v / %v / %v\n", pc.policy().application, guid, pid, fd) if pid == -1 || fd == -1 || prompter == nil { - log.Warningf("Unexpected error condition occurred while adding socket fd to monitor: %d %d %v",pid, fd, prompter) + log.Warning("Unexpected error condition occurred while adding socket fd to monitor"); return } else { log.Warning("No unexpected errors"); @@ -315,8 +315,8 @@ func (p *prompter) processConnection(pc pendingConnection) { pc.proto(), int32(pc.procInfo().UID), int32(pc.procInfo().GID), - uidToUser(pc.procInfo().UID), - gidToGroup(pc.procInfo().GID), + uidToUser(pc.sandbox(), pc.procInfo().UID), + gidToGroup(pc.sandbox(), pc.procInfo().GID), int32(pc.procInfo().Pid), pc.sandbox(), pc.socks(), @@ -589,7 +589,16 @@ func lookupGroup(gid int) string { return g.Name } -func uidToUser(uid int) string { +func uidToUser(realm string, uid int) string { + // TODO: cache + if (realm != "") { + user := ""; + var db,_ = dbus.SystemBus() + obj := db.Object("com.subgraph.realms", "/") + obj.Call("com.subgraph.realms.Manager.RealmUsernameFromUID", 0, realm, strconv.Itoa(uid)).Store(&user) + return user; + } + uname, ok := userMap[uid] if ok { return uname @@ -599,7 +608,16 @@ func uidToUser(uid int) string { return uname } -func gidToGroup(gid int) string { +func gidToGroup(realm string, gid int) string { + // TODO: cache + if (realm != "") { + group := ""; + var db,_ = dbus.SystemBus() + obj := db.Object("com.subgraph.realms", "/") + obj.Call("com.subgraph.realms.Manager.RealmGroupnameFromGID", 0, realm, strconv.Itoa(gid)).Store(&group) + return group; + } + gname, ok := groupMap[gid] if ok { return gname diff --git a/sgfw/rules.go b/sgfw/rules.go index 1b51b8c..4f8f75a 100644 --- a/sgfw/rules.go +++ b/sgfw/rules.go @@ -200,7 +200,7 @@ func (rl *RuleList) filter(pkt *nfqueue.NFQPacket, src, dst net.IP, dstPort uint //log.Notice("! Skipping comparison of mismatching PIDs") continue } - if r.match(src, dst, dstPort, hostname, nfqproto, 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.Sandbox, pinfo.UID), gidToGroup(pinfo.Sandbox, pinfo.GID), pinfo.Sandbox) { // log.Notice("+ MATCH SUCCEEDED") dstStr := dst.String() if FirewallConfig.LogRedact {