ADDED: System rules

ADDED: Persistant configs
ADDED: Prompt configurations (default action, advanced options, auto expand)
FIXED: Default focus on prompt
FIXED: Bug in display of *:<port> rule
FIXED: Updated ui to gnome >= 3.20
socks-filter
xSmurf 8 years ago
parent 3798b30a2c
commit 95c5e486ba

@ -0,0 +1,79 @@
// TODO: Check permissions on file
// TODO: Create dir if needed
// TODO: Dont' fail hard on failed read
package main
import (
"bufio"
"io/ioutil"
"os"
"github.com/naoina/toml"
"github.com/op/go-logging"
)
const (
configDefaultPath string = "/etc/sgfw/sgfw.conf"
)
type FirewallConfigs struct {
LogLevel string
LoggingLevel logging.Level `toml:"-"`
LogRedact bool
PromptExpanded bool
PromptExpert bool
DefaultAction string
DefaultActionId int32 `toml:"-"`
}
var FirewallConfig FirewallConfigs
func readConfig() {
f, err := os.Open(configDefaultPath)
if err != nil {
log.Error(err.Error())
os.Exit(1)
}
defer f.Close()
buf, err := ioutil.ReadAll(f)
if err != nil {
log.Error(err.Error())
os.Exit(1)
}
FirewallConfig = FirewallConfigs{
LogLevel: "NOTICE",
LoggingLevel: logging.NOTICE,
LogRedact: false,
PromptExpanded: false,
PromptExpert: false,
DefaultAction: "SESSION",
DefaultActionId: 1,
}
if err := toml.Unmarshal(buf, &FirewallConfig); err != nil {
log.Error(err.Error())
os.Exit(1)
}
FirewallConfig.LoggingLevel, _ = logging.LogLevel(FirewallConfig.LogLevel)
FirewallConfig.DefaultActionId = valueScope(FirewallConfig.DefaultAction)
}
func writeConfig() {
FirewallConfig.LogLevel = FirewallConfig.LoggingLevel.String()
FirewallConfig.DefaultAction = printScope(FirewallConfig.DefaultActionId)
f, err := os.Create(configDefaultPath)
if err != nil {
log.Error(err.Error())
os.Exit(1)
}
defer f.Close()
w := bufio.NewWriter(f)
cw := toml.NewEncoder(w)
if err := cw.Encode(FirewallConfig); err != nil {
log.Error(err.Error())
os.Exit(1)
}
w.Flush()
}

@ -60,6 +60,7 @@ type DbusRule struct {
Path string Path string
Verb uint32 Verb uint32
Target string Target string
Mode uint16
} }
func newDbusServer() (*dbusServer, error) { func newDbusServer() (*dbusServer, error) {
@ -107,6 +108,7 @@ func createDbusRule(r *Rule) DbusRule {
Path: r.policy.path, Path: r.policy.path,
Verb: uint32(r.rtype), Verb: uint32(r.rtype),
Target: r.AddrString(false), Target: r.AddrString(false),
Mode: uint16(r.mode),
} }
} }
@ -126,10 +128,14 @@ func (ds *dbusServer) DeleteRule(id uint32) *dbus.Error {
ds.fw.lock.Lock() ds.fw.lock.Lock()
r := ds.fw.rulesById[uint(id)] r := ds.fw.rulesById[uint(id)]
ds.fw.lock.Unlock() ds.fw.lock.Unlock()
if r.mode == RULE_MODE_SYSTEM {
log.Warningf("Cannot delete system rule: %s", r.String())
return nil
}
if r != nil { if r != nil {
r.policy.removeRule(r) r.policy.removeRule(r)
} }
if !r.sessionOnly { if r.mode != RULE_MODE_SESSION {
ds.fw.saveRules() ds.fw.saveRules()
} }
return nil return nil
@ -141,6 +147,10 @@ func (ds *dbusServer) UpdateRule(rule DbusRule) *dbus.Error {
r := ds.fw.rulesById[uint(rule.Id)] r := ds.fw.rulesById[uint(rule.Id)]
ds.fw.lock.Unlock() ds.fw.lock.Unlock()
if r != nil { if r != nil {
if r.mode == RULE_MODE_SYSTEM {
log.Warningf("Cannot modify system rule: %s", r.String())
return nil
}
tmp := new(Rule) tmp := new(Rule)
tmp.addr = noAddress tmp.addr = noAddress
if !tmp.parseTarget(rule.Target) { if !tmp.parseTarget(rule.Target) {
@ -154,8 +164,9 @@ func (ds *dbusServer) UpdateRule(rule DbusRule) *dbus.Error {
r.hostname = tmp.hostname r.hostname = tmp.hostname
r.addr = tmp.addr r.addr = tmp.addr
r.port = tmp.port r.port = tmp.port
r.mode = RuleMode(rule.Mode)
r.policy.lock.Unlock() r.policy.lock.Unlock()
if !r.sessionOnly { if r.mode != RULE_MODE_SESSION {
ds.fw.saveRules() ds.fw.saveRules()
} }
} }
@ -164,21 +175,35 @@ func (ds *dbusServer) UpdateRule(rule DbusRule) *dbus.Error {
func (ds *dbusServer) GetConfig() (map[string]dbus.Variant, *dbus.Error) { func (ds *dbusServer) GetConfig() (map[string]dbus.Variant, *dbus.Error) {
conf := make(map[string]dbus.Variant) conf := make(map[string]dbus.Variant)
conf["loglevel"] = dbus.MakeVariant(int32(ds.fw.logBackend.GetLevel("sgfw"))) conf["log_level"] = dbus.MakeVariant(int32(ds.fw.logBackend.GetLevel("sgfw")))
conf["logredact"] = dbus.MakeVariant(logRedact) conf["log_redact"] = dbus.MakeVariant(FirewallConfig.LogRedact)
conf["prompt_expanded"] = dbus.MakeVariant(FirewallConfig.PromptExpanded)
conf["prompt_expert"] = dbus.MakeVariant(FirewallConfig.PromptExpert)
conf["default_action"] = dbus.MakeVariant(int32(FirewallConfig.DefaultActionId))
return conf, nil return conf, nil
} }
func (ds *dbusServer) SetConfig(key string, val dbus.Variant) *dbus.Error { func (ds *dbusServer) SetConfig(key string, val dbus.Variant) *dbus.Error {
switch key { switch key {
case "loglevel": case "log_level":
l := val.Value().(int32) l := val.Value().(int32)
lvl := logging.Level(l) lvl := logging.Level(l)
ds.fw.logBackend.SetLevel(lvl, "sgfw") ds.fw.logBackend.SetLevel(lvl, "sgfw")
case "logredact": FirewallConfig.LoggingLevel = lvl
case "log_redact":
flag := val.Value().(bool) flag := val.Value().(bool)
logRedact = flag FirewallConfig.LogRedact = flag
case "prompt_expanded":
flag := val.Value().(bool)
FirewallConfig.PromptExpanded = flag
case "prompt_expert":
flag := val.Value().(bool)
FirewallConfig.PromptExpert = flag
case "default_action":
l := val.Value().(int32)
FirewallConfig.DefaultActionId = l
} }
writeConfig()
return nil return nil
} }

@ -54,7 +54,7 @@ func (dc *dnsCache) processRecordA(name string, answers []dnsRR) {
name = name[:len(name)-1] name = name[:len(name)-1]
} }
dc.ipMap[ip] = name dc.ipMap[ip] = name
if !logRedact { if !FirewallConfig.LogRedact {
log.Infof("Adding %s: %s", name, ip) log.Infof("Adding %s: %s", name, ip)
} }
default: default:

@ -21,13 +21,33 @@ var idToLevel = func() map[string]int32 {
return m return m
}() }()
var actionToId = map[int32]string{
0: "ONCE",
1: "SESSION",
3: "FOREVER",
}
var idToAction = func() map[string]int32 {
m := make(map[string]int32)
for k, v := range actionToId {
m[v] = k
}
return m
}()
func loadConfig(win *gtk.Window, b *builder, dbus *dbusObject) { func loadConfig(win *gtk.Window, b *builder, dbus *dbusObject) {
var levelCombo *gtk.ComboBoxText var levelCombo *gtk.ComboBoxText
var redactCheck *gtk.CheckButton var redactCheck *gtk.CheckButton
var expandedCheck *gtk.CheckButton
var expertCheck *gtk.CheckButton
var actionCombo *gtk.ComboBoxText
b.getItems( b.getItems(
"level_combo", &levelCombo, "level_combo", &levelCombo,
"redact_checkbox", &redactCheck, "redact_checkbox", &redactCheck,
"expanded_checkbox", &expandedCheck,
"expert_checkbox", &expertCheck,
"action_combo", &actionCombo,
) )
conf, err := dbus.getConfig() conf, err := dbus.getConfig()
@ -35,22 +55,44 @@ func loadConfig(win *gtk.Window, b *builder, dbus *dbusObject) {
failDialog(win, "Failed to load config from fw daemon: %v", err) failDialog(win, "Failed to load config from fw daemon: %v", err)
} }
if lvl, ok := conf["loglevel"].(int32); ok { if lvl, ok := conf["log_level"].(int32); ok {
if id, ok := levelToId[lvl]; ok { if id, ok := levelToId[lvl]; ok {
levelCombo.SetActiveID(id) levelCombo.SetActiveID(id)
} }
} }
if v, ok := conf["logredact"].(bool); ok { if v, ok := conf["log_redact"].(bool); ok {
redactCheck.SetActive(v) redactCheck.SetActive(v)
} }
if v, ok := conf["prompt_expanded"].(bool); ok {
expandedCheck.SetActive(v)
}
if v, ok := conf["prompt_expert"].(bool); ok {
expertCheck.SetActive(v)
}
if av, ok := conf["default_action"].(int32); ok {
if id, ok := actionToId[av]; ok {
actionCombo.SetActiveID(id)
}
}
b.ConnectSignals(map[string]interface{}{ b.ConnectSignals(map[string]interface{}{
"on_level_combo_changed": func() { "on_level_combo_changed": func() {
if lvl, ok := idToLevel[levelCombo.GetActiveID()]; ok { if lvl, ok := idToLevel[levelCombo.GetActiveID()]; ok {
dbus.setConfig("loglevel", lvl) dbus.setConfig("log_level", lvl)
} }
}, },
"on_redact_checkbox_toggled": func() { "on_redact_checkbox_toggled": func() {
dbus.setConfig("logredact", redactCheck.GetActive()) dbus.setConfig("log_redact", redactCheck.GetActive())
},
"on_expanded_checkbox_toggled": func() {
dbus.setConfig("prompt_expanded", expandedCheck.GetActive())
},
"on_expert_checkbox_toggled": func() {
dbus.setConfig("prompt_expert", expertCheck.GetActive())
},
"on_action_combo_changed": func() {
if al, ok := idToAction[actionCombo.GetActiveID()]; ok {
dbus.setConfig("default_action", al)
}
}, },
}) })

@ -8,12 +8,21 @@ type dbusObject struct {
dbus.BusObject dbus.BusObject
} }
//type RuleMode uint16
const (
RULE_MODE_SESSION uint16 = iota
RULE_MODE_PERMANENT
RULE_MODE_SYSTEM
)
type dbusRule struct { type dbusRule struct {
Id uint32 Id uint32
App string App string
Path string Path string
Verb uint32 Verb uint32
Target string Target string
Mode uint16
} }
func newDbusObject() (*dbusObject, error) { func newDbusObject() (*dbusObject, error) {

@ -1,53 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.19.0 --> <!-- Generated with glade 3.20.0 -->
<interface> <interface>
<requires lib="gtk+" version="3.16"/> <requires lib="gtk+" version="3.20"/>
<object class="GtkWindow" id="window"> <object class="GtkWindow" id="window">
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="hexpand">True</property> <property name="title">Subgraph Firewall</property>
<property name="title" translatable="yes">Firewall Settings</property> <property name="window_position">center</property>
<property name="default_width">600</property> <property name="default_width">600</property>
<property name="default_height">400</property> <property name="default_height">400</property>
<property name="type_hint">dialog</property>
<child> <child>
<object class="GtkNotebook" id="notebook"> <object class="GtkBox" id="box1">
<property name="visible">True</property> <property name="can_focus">False</property>
<property name="can_focus">True</property> <property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkStack" id="toplevel_stack">
<property name="can_focus">False</property>
<property name="margin_bottom">5</property> <property name="margin_bottom">5</property>
<property name="transition_duration">1000</property>
<child> <child>
<object class="GtkGrid" id="grid3"> <object class="GtkNotebook" id="rulesnotebook">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">True</property>
<property name="margin_left">12</property> <property name="hexpand">True</property>
<property name="margin_right">12</property> <property name="vexpand">True</property>
<property name="margin_top">12</property>
<property name="margin_bottom">12</property>
<child> <child>
<object class="GtkLabel" id="label4"> <object class="GtkScrolledWindow" id="swRulesPermanent">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">True</property>
<property name="label" translatable="yes">Firewall Rules</property> <property name="hexpand">True</property>
<property name="xalign">0</property> <property name="vexpand">True</property>
<attributes> <property name="hscrollbar_policy">never</property>
<attribute name="weight" value="bold"/> <property name="shadow_type">in</property>
</attributes>
</object> </object>
<packing> <packing>
<property name="left_attach">0</property> <property name="tab_expand">True</property>
<property name="top_attach">0</property>
</packing> </packing>
</child> </child>
<child> <child type="tab">
<object class="GtkGrid" id="grid4"> <object class="GtkLabel">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_left">12</property> <property name="label" translatable="yes">Permanent</property>
<property name="margin_right">12</property> </object>
<property name="margin_top">8</property> <packing>
<property name="hexpand">True</property> <property name="tab_expand">True</property>
<property name="vexpand">True</property> <property name="tab_fill">False</property>
</packing>
</child>
<child> <child>
<object class="GtkScrolledWindow" id="scrolledwindow"> <object class="GtkScrolledWindow" id="swRulesSession">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="hexpand">True</property> <property name="hexpand">True</property>
@ -56,62 +59,121 @@
<property name="shadow_type">in</property> <property name="shadow_type">in</property>
</object> </object>
<packing> <packing>
<property name="left_attach">0</property> <property name="position">1</property>
<property name="top_attach">0</property> <property name="tab_expand">True</property>
</packing> </packing>
</child> </child>
<child type="tab">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Session</property>
</object> </object>
<packing> <packing>
<property name="left_attach">0</property> <property name="position">1</property>
<property name="top_attach">1</property> <property name="tab_expand">True</property>
<property name="tab_fill">False</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkScrolledWindow" id="swRulesSystem">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="hscrollbar_policy">never</property>
<property name="shadow_type">in</property>
</object> </object>
<packing> <packing>
<property name="position">1</property> <property name="position">2</property>
<property name="tab_expand">True</property>
</packing> </packing>
</child> </child>
<child type="tab"> <child type="tab">
<object class="GtkLabel" id="label2"> <object class="GtkLabel">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label" translatable="yes">Rules</property> <property name="label" translatable="yes">System</property>
</object> </object>
<packing> <packing>
<property name="position">1</property> <property name="position">2</property>
<property name="tab_expand">True</property>
<property name="tab_fill">False</property> <property name="tab_fill">False</property>
</packing> </packing>
</child> </child>
</object>
<packing>
<property name="name">page0</property>
<property name="title" translatable="yes">Rules</property>
</packing>
</child>
<child> <child>
<object class="GtkGrid" id="grid1"> <object class="GtkGrid" id="grid1">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_left">12</property> <property name="margin_left">10</property>
<property name="margin_top">12</property> <property name="margin_right">10</property>
<property name="margin_top">10</property>
<property name="margin_bottom">10</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="row_spacing">5</property>
<property name="column_homogeneous">True</property>
<child> <child>
<object class="GtkGrid" id="grid2"> <object class="GtkLabel" id="label1">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_left">12</property> <property name="halign">start</property>
<property name="margin_top">8</property> <property name="margin_top">10</property>
<property name="row_spacing">6</property> <property name="margin_bottom">5</property>
<property name="column_spacing">6</property> <property name="label" translatable="yes">Prompt</property>
<property name="ellipsize">start</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">2</property>
</packing>
</child>
<child> <child>
<object class="GtkLabel" id="label3"> <object class="GtkLabel" id="label5">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="halign">start</property> <property name="halign">start</property>
<property name="label" translatable="yes">Log Level:</property> <property name="margin_bottom">5</property>
<property name="label" translatable="yes">Logging</property>
<property name="ellipsize">start</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object> </object>
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">0</property> <property name="top_attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">10</property>
<property name="label" translatable="yes">Daemon Log Level:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkComboBoxText" id="level_combo"> <object class="GtkComboBoxText" id="level_combo">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="active">0</property> <property name="active">0</property>
<items> <items>
<item id="error" translatable="yes">Error</item> <item id="error" translatable="yes">Error</item>
@ -124,7 +186,7 @@
</object> </object>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">0</property> <property name="top_attach">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -133,55 +195,111 @@
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="xalign">0</property> <property name="halign">start</property>
<property name="margin_left">10</property>
<property name="draw_indicator">True</property> <property name="draw_indicator">True</property>
<signal name="toggled" handler="on_redact_checkbox_toggled" swapped="no"/> <signal name="toggled" handler="on_redact_checkbox_toggled" swapped="no"/>
</object> </object>
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">1</property> <property name="top_attach">2</property>
<property name="width">2</property> <property name="width">2</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkCheckButton" id="expanded_checkbox">
<property name="label" translatable="yes">Always expand event prompt</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="halign">start</property>
<property name="margin_left">10</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_expanded_checkbox_toggled" swapped="no"/>
</object> </object>
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">1</property> <property name="top_attach">4</property>
<property name="width">2</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkLabel" id="label5"> <object class="GtkCheckButton" id="expert_checkbox">
<property name="label" translatable="yes">Show expert options in event prompt</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">True</property>
<property name="label" translatable="yes">Logging</property> <property name="receives_default">False</property>
<property name="ellipsize">start</property> <property name="halign">start</property>
<property name="xalign">0</property> <property name="margin_left">10</property>
<attributes> <property name="draw_indicator">True</property>
<attribute name="weight" value="bold"/> <signal name="toggled" handler="on_expert_checkbox_toggled" swapped="no"/>
</attributes>
</object> </object>
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">0</property> <property name="top_attach">5</property>
<property name="width">2</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">10</property>
<property name="label" translatable="yes">Default Scope:</property>
</object> </object>
<packing> <packing>
<property name="position">1</property> <property name="left_attach">0</property>
<property name="top_attach">6</property>
</packing> </packing>
</child> </child>
<child type="tab"> <child>
<object class="GtkLabel" id="label1"> <object class="GtkComboBoxText" id="action_combo">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label" translatable="yes">Options</property> <property name="hexpand">True</property>
<property name="active">0</property>
<items>
<item id="FOREVER" translatable="yes">Forever</item>
<item id="SESSION" translatable="yes">Session</item>
<item id="ONCE" translatable="yes">Once</item>
</items>
<signal name="changed" handler="on_action_combo_changed" swapped="no"/>
</object> </object>
<packing> <packing>
<property name="left_attach">1</property>
<property name="top_attach">6</property>
</packing>
</child>
</object>
<packing>
<property name="name">page1</property>
<property name="title" translatable="yes">Options</property>
<property name="position">1</property> <property name="position">1</property>
<property name="tab_fill">False</property>
</packing> </packing>
</child> </child>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
<child type="titlebar">
<object class="GtkHeaderBar" id="headerbar">
<property name="can_focus">False</property>
<property name="show_close_button">True</property>
<property name="decoration_layout">:minimize,maximize,close</property>
<child type="title">
<object class="GtkStackSwitcher" id="stack_switcher">
<property name="can_focus">False</property>
<property name="icon_size">2</property>
<property name="stack">toplevel_stack</property>
</object>
</child>
</object>
</child> </child>
</object> </object>
</interface> </interface>

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.19.0 --> <!-- Generated with glade 3.20.0 -->
<interface> <interface>
<requires lib="gtk+" version="3.16"/> <requires lib="gtk+" version="3.16"/>
<object class="GtkDialog" id="dialog"> <object class="GtkDialog" id="dialog">
@ -34,7 +34,6 @@
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="yalign">0.60000002384185791</property>
</object> </object>
<packing> <packing>
<property name="expand">True</property> <property name="expand">True</property>
@ -78,8 +77,8 @@
<object class="GtkLabel" id="path_label"> <object class="GtkLabel" id="path_label">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property> <property name="hexpand">True</property>
<property name="xalign">0</property>
</object> </object>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
@ -171,10 +170,11 @@
<object class="GtkLabel" id="label2"> <object class="GtkLabel" id="label2">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">12</property> <property name="margin_left">12</property>
<property name="margin_right">10</property> <property name="margin_right">10</property>
<property name="hexpand">False</property>
<property name="label" translatable="yes">Path:</property> <property name="label" translatable="yes">Path:</property>
<property name="xalign">1</property>
<attributes> <attributes>
<attribute name="weight" value="bold"/> <attribute name="weight" value="bold"/>
</attributes> </attributes>

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.19.0 --> <!-- Generated with glade 3.20.0 -->
<interface> <interface>
<requires lib="gtk+" version="3.16"/> <requires lib="gtk+" version="3.16"/>
<object class="GtkGrid" id="grid"> <object class="GtkGrid" id="grid">
@ -13,7 +13,6 @@
<property name="halign">start</property> <property name="halign">start</property>
<property name="margin_left">8</property> <property name="margin_left">8</property>
<property name="margin_right">10</property> <property name="margin_right">10</property>
<property name="xalign">0</property>
</object> </object>
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
@ -24,8 +23,8 @@
<object class="GtkLabel" id="verb_label"> <object class="GtkLabel" id="verb_label">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_right">10</property> <property name="margin_right">10</property>
<property name="xalign">1</property>
</object> </object>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
@ -38,7 +37,6 @@
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="halign">start</property> <property name="halign">start</property>
<property name="hexpand">True</property> <property name="hexpand">True</property>
<property name="xalign">0</property>
</object> </object>
<packing> <packing>
<property name="left_attach">2</property> <property name="left_attach">2</property>
@ -50,11 +48,11 @@
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Edit Firewall rule</property> <property name="tooltip_text" translatable="yes">Edit firewall rule</property>
<property name="relief">none</property> <property name="relief">none</property>
<signal name="clicked" handler="on_edit_rule" swapped="no"/> <signal name="clicked" handler="on_edit_rule" swapped="no"/>
<child> <child>
<object class="GtkImage" id="image2"> <object class="GtkImage" id="img_edit_button">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="icon_name">document-properties-symbolic</property> <property name="icon_name">document-properties-symbolic</property>
@ -71,7 +69,7 @@
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Delete Firewall rule</property> <property name="tooltip_text" translatable="yes">Delete firewall rule</property>
<property name="relief">none</property> <property name="relief">none</property>
<signal name="clicked" handler="on_delete_rule" swapped="no"/> <signal name="clicked" handler="on_delete_rule" swapped="no"/>
<child> <child>
@ -82,6 +80,28 @@
</object> </object>
</child> </child>
</object> </object>
<packing>
<property name="left_attach">5</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="save_button">
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="no_show_all">True</property>
<property name="tooltip_text" translatable="yes">Save as new permanent firewall rule</property>
<property name="relief">none</property>
<signal name="clicked" handler="on_save_rule" swapped="no"/>
<child>
<object class="GtkImage" id="img_save_button">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">document-new-symbolic</property>
</object>
</child>
</object>
<packing> <packing>
<property name="left_attach">4</property> <property name="left_attach">4</property>
<property name="top_attach">0</property> <property name="top_attach">0</property>

@ -9,55 +9,58 @@ type defDialog struct{}
func (*defDialog) String() string { func (*defDialog) String() string {
return ` return `
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.19.0 --> <!-- Generated with glade 3.20.0 -->
<interface> <interface>
<requires lib="gtk+" version="3.16"/> <requires lib="gtk+" version="3.20"/>
<object class="GtkWindow" id="window"> <object class="GtkWindow" id="window">
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="hexpand">True</property> <property name="title">Subgraph Firewall</property>
<property name="title" translatable="yes">Firewall Settings</property> <property name="window_position">center</property>
<property name="default_width">600</property> <property name="default_width">600</property>
<property name="default_height">400</property> <property name="default_height">400</property>
<property name="type_hint">dialog</property>
<child> <child>
<object class="GtkNotebook" id="notebook"> <object class="GtkBox" id="box1">
<property name="visible">True</property> <property name="can_focus">False</property>
<property name="can_focus">True</property> <property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkStack" id="toplevel_stack">
<property name="can_focus">False</property>
<property name="margin_bottom">5</property> <property name="margin_bottom">5</property>
<property name="transition_duration">1000</property>
<child> <child>
<object class="GtkGrid" id="grid3"> <object class="GtkNotebook" id="rulesnotebook">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">True</property>
<property name="margin_left">12</property> <property name="hexpand">True</property>
<property name="margin_right">12</property> <property name="vexpand">True</property>
<property name="margin_top">12</property>
<property name="margin_bottom">12</property>
<child> <child>
<object class="GtkLabel" id="label4"> <object class="GtkScrolledWindow" id="swRulesPermanent">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">True</property>
<property name="label" translatable="yes">Firewall Rules</property> <property name="hexpand">True</property>
<property name="xalign">0</property> <property name="vexpand">True</property>
<attributes> <property name="hscrollbar_policy">never</property>
<attribute name="weight" value="bold"/> <property name="shadow_type">in</property>
</attributes>
</object> </object>
<packing> <packing>
<property name="left_attach">0</property> <property name="tab_expand">True</property>
<property name="top_attach">0</property>
</packing> </packing>
</child> </child>
<child> <child type="tab">
<object class="GtkGrid" id="grid4"> <object class="GtkLabel">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_left">12</property> <property name="label" translatable="yes">Permanent</property>
<property name="margin_right">12</property> </object>
<property name="margin_top">8</property> <packing>
<property name="hexpand">True</property> <property name="tab_expand">True</property>
<property name="vexpand">True</property> <property name="tab_fill">False</property>
</packing>
</child>
<child> <child>
<object class="GtkScrolledWindow" id="scrolledwindow"> <object class="GtkScrolledWindow" id="swRulesSession">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="hexpand">True</property> <property name="hexpand">True</property>
@ -66,62 +69,121 @@ func (*defDialog) String() string {
<property name="shadow_type">in</property> <property name="shadow_type">in</property>
</object> </object>
<packing> <packing>
<property name="left_attach">0</property> <property name="position">1</property>
<property name="top_attach">0</property> <property name="tab_expand">True</property>
</packing> </packing>
</child> </child>
<child type="tab">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Session</property>
</object> </object>
<packing> <packing>
<property name="left_attach">0</property> <property name="position">1</property>
<property name="top_attach">1</property> <property name="tab_expand">True</property>
<property name="tab_fill">False</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkScrolledWindow" id="swRulesSystem">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="hscrollbar_policy">never</property>
<property name="shadow_type">in</property>
</object> </object>
<packing> <packing>
<property name="position">1</property> <property name="position">2</property>
<property name="tab_expand">True</property>
</packing> </packing>
</child> </child>
<child type="tab"> <child type="tab">
<object class="GtkLabel" id="label2"> <object class="GtkLabel">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label" translatable="yes">Rules</property> <property name="label" translatable="yes">System</property>
</object> </object>
<packing> <packing>
<property name="position">1</property> <property name="position">2</property>
<property name="tab_expand">True</property>
<property name="tab_fill">False</property> <property name="tab_fill">False</property>
</packing> </packing>
</child> </child>
</object>
<packing>
<property name="name">page0</property>
<property name="title" translatable="yes">Rules</property>
</packing>
</child>
<child> <child>
<object class="GtkGrid" id="grid1"> <object class="GtkGrid" id="grid1">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_left">12</property> <property name="margin_left">10</property>
<property name="margin_top">12</property> <property name="margin_right">10</property>
<property name="margin_top">10</property>
<property name="margin_bottom">10</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="row_spacing">5</property>
<property name="column_homogeneous">True</property>
<child> <child>
<object class="GtkGrid" id="grid2"> <object class="GtkLabel" id="label1">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_left">12</property> <property name="halign">start</property>
<property name="margin_top">8</property> <property name="margin_top">10</property>
<property name="row_spacing">6</property> <property name="margin_bottom">5</property>
<property name="column_spacing">6</property> <property name="label" translatable="yes">Prompt</property>
<property name="ellipsize">start</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">2</property>
</packing>
</child>
<child> <child>
<object class="GtkLabel" id="label3"> <object class="GtkLabel" id="label5">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="halign">start</property> <property name="halign">start</property>
<property name="label" translatable="yes">Log Level:</property> <property name="margin_bottom">5</property>
<property name="label" translatable="yes">Logging</property>
<property name="ellipsize">start</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object> </object>
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">0</property> <property name="top_attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">10</property>
<property name="label" translatable="yes">Daemon Log Level:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkComboBoxText" id="level_combo"> <object class="GtkComboBoxText" id="level_combo">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="active">0</property> <property name="active">0</property>
<items> <items>
<item id="error" translatable="yes">Error</item> <item id="error" translatable="yes">Error</item>
@ -134,7 +196,7 @@ func (*defDialog) String() string {
</object> </object>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">0</property> <property name="top_attach">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -143,55 +205,111 @@ func (*defDialog) String() string {
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="xalign">0</property> <property name="halign">start</property>
<property name="margin_left">10</property>
<property name="draw_indicator">True</property> <property name="draw_indicator">True</property>
<signal name="toggled" handler="on_redact_checkbox_toggled" swapped="no"/> <signal name="toggled" handler="on_redact_checkbox_toggled" swapped="no"/>
</object> </object>
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">1</property> <property name="top_attach">2</property>
<property name="width">2</property> <property name="width">2</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkCheckButton" id="expanded_checkbox">
<property name="label" translatable="yes">Always expand event prompt</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="halign">start</property>
<property name="margin_left">10</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_expanded_checkbox_toggled" swapped="no"/>
</object> </object>
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">1</property> <property name="top_attach">4</property>
<property name="width">2</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkLabel" id="label5"> <object class="GtkCheckButton" id="expert_checkbox">
<property name="label" translatable="yes">Show expert options in event prompt</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">True</property>
<property name="label" translatable="yes">Logging</property> <property name="receives_default">False</property>
<property name="ellipsize">start</property> <property name="halign">start</property>
<property name="xalign">0</property> <property name="margin_left">10</property>
<attributes> <property name="draw_indicator">True</property>
<attribute name="weight" value="bold"/> <signal name="toggled" handler="on_expert_checkbox_toggled" swapped="no"/>
</attributes>
</object> </object>
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">0</property> <property name="top_attach">5</property>
<property name="width">2</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">10</property>
<property name="label" translatable="yes">Default Scope:</property>
</object> </object>
<packing> <packing>
<property name="position">1</property> <property name="left_attach">0</property>
<property name="top_attach">6</property>
</packing> </packing>
</child> </child>
<child type="tab"> <child>
<object class="GtkLabel" id="label1"> <object class="GtkComboBoxText" id="action_combo">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="label" translatable="yes">Options</property> <property name="hexpand">True</property>
<property name="active">0</property>
<items>
<item id="FOREVER" translatable="yes">Forever</item>
<item id="SESSION" translatable="yes">Session</item>
<item id="ONCE" translatable="yes">Once</item>
</items>
<signal name="changed" handler="on_action_combo_changed" swapped="no"/>
</object> </object>
<packing> <packing>
<property name="left_attach">1</property>
<property name="top_attach">6</property>
</packing>
</child>
</object>
<packing>
<property name="name">page1</property>
<property name="title" translatable="yes">Options</property>
<property name="position">1</property> <property name="position">1</property>
<property name="tab_fill">False</property>
</packing> </packing>
</child> </child>
</object> </object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
<child type="titlebar">
<object class="GtkHeaderBar" id="headerbar">
<property name="can_focus">False</property>
<property name="show_close_button">True</property>
<property name="decoration_layout">:minimize,maximize,close</property>
<child type="title">
<object class="GtkStackSwitcher" id="stack_switcher">
<property name="can_focus">False</property>
<property name="icon_size">2</property>
<property name="stack">toplevel_stack</property>
</object>
</child>
</object>
</child> </child>
</object> </object>
</interface> </interface>

@ -9,7 +9,7 @@ type defRuleEdit struct{}
func (*defRuleEdit) String() string { func (*defRuleEdit) String() string {
return ` return `
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.19.0 --> <!-- Generated with glade 3.20.0 -->
<interface> <interface>
<requires lib="gtk+" version="3.16"/> <requires lib="gtk+" version="3.16"/>
<object class="GtkDialog" id="dialog"> <object class="GtkDialog" id="dialog">
@ -44,7 +44,6 @@ func (*defRuleEdit) String() string {
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="yalign">0.60000002384185791</property>
</object> </object>
<packing> <packing>
<property name="expand">True</property> <property name="expand">True</property>
@ -88,8 +87,8 @@ func (*defRuleEdit) String() string {
<object class="GtkLabel" id="path_label"> <object class="GtkLabel" id="path_label">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property> <property name="hexpand">True</property>
<property name="xalign">0</property>
</object> </object>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
@ -181,10 +180,11 @@ func (*defRuleEdit) String() string {
<object class="GtkLabel" id="label2"> <object class="GtkLabel" id="label2">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">12</property> <property name="margin_left">12</property>
<property name="margin_right">10</property> <property name="margin_right">10</property>
<property name="hexpand">False</property>
<property name="label" translatable="yes">Path:</property> <property name="label" translatable="yes">Path:</property>
<property name="xalign">1</property>
<attributes> <attributes>
<attribute name="weight" value="bold"/> <attribute name="weight" value="bold"/>
</attributes> </attributes>

@ -9,7 +9,7 @@ type defRuleItem struct{}
func (*defRuleItem) String() string { func (*defRuleItem) String() string {
return ` return `
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.19.0 --> <!-- Generated with glade 3.20.0 -->
<interface> <interface>
<requires lib="gtk+" version="3.16"/> <requires lib="gtk+" version="3.16"/>
<object class="GtkGrid" id="grid"> <object class="GtkGrid" id="grid">
@ -23,7 +23,6 @@ func (*defRuleItem) String() string {
<property name="halign">start</property> <property name="halign">start</property>
<property name="margin_left">8</property> <property name="margin_left">8</property>
<property name="margin_right">10</property> <property name="margin_right">10</property>
<property name="xalign">0</property>
</object> </object>
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
@ -34,8 +33,8 @@ func (*defRuleItem) String() string {
<object class="GtkLabel" id="verb_label"> <object class="GtkLabel" id="verb_label">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_right">10</property> <property name="margin_right">10</property>
<property name="xalign">1</property>
</object> </object>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
@ -48,7 +47,6 @@ func (*defRuleItem) String() string {
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="halign">start</property> <property name="halign">start</property>
<property name="hexpand">True</property> <property name="hexpand">True</property>
<property name="xalign">0</property>
</object> </object>
<packing> <packing>
<property name="left_attach">2</property> <property name="left_attach">2</property>
@ -60,11 +58,11 @@ func (*defRuleItem) String() string {
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Edit Firewall rule</property> <property name="tooltip_text" translatable="yes">Edit firewall rule</property>
<property name="relief">none</property> <property name="relief">none</property>
<signal name="clicked" handler="on_edit_rule" swapped="no"/> <signal name="clicked" handler="on_edit_rule" swapped="no"/>
<child> <child>
<object class="GtkImage" id="image2"> <object class="GtkImage" id="img_edit_button">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="icon_name">document-properties-symbolic</property> <property name="icon_name">document-properties-symbolic</property>
@ -81,7 +79,7 @@ func (*defRuleItem) String() string {
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Delete Firewall rule</property> <property name="tooltip_text" translatable="yes">Delete firewall rule</property>
<property name="relief">none</property> <property name="relief">none</property>
<signal name="clicked" handler="on_delete_rule" swapped="no"/> <signal name="clicked" handler="on_delete_rule" swapped="no"/>
<child> <child>
@ -92,6 +90,28 @@ func (*defRuleItem) String() string {
</object> </object>
</child> </child>
</object> </object>
<packing>
<property name="left_attach">5</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="save_button">
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="no_show_all">True</property>
<property name="tooltip_text" translatable="yes">Save as new permanent firewall rule</property>
<property name="relief">none</property>
<signal name="clicked" handler="on_save_rule" swapped="no"/>
<child>
<object class="GtkImage" id="img_save_button">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">document-new-symbolic</property>
</object>
</child>
</object>
<packing> <packing>
<property name="left_attach">4</property> <property name="left_attach">4</property>
<property name="top_attach">0</property> <property name="top_attach">0</property>

@ -22,29 +22,52 @@ func activate(app *gtk.Application) {
return return
} }
var scrolled *gtk.ScrolledWindow var swRulesPermanent *gtk.ScrolledWindow
var swRulesSession *gtk.ScrolledWindow
var swRulesSystem *gtk.ScrolledWindow
b := newBuilder("Dialog") b := newBuilder("Dialog")
b.getItems( b.getItems(
"window", &win, "window", &win,
"scrolledwindow", &scrolled, "swRulesPermanent", &swRulesPermanent,
"swRulesSession", &swRulesSession,
"swRulesSystem", &swRulesSystem,
) )
win.SetIconName("security-high-symbolic") //win.SetIconName("security-high-symbolic")
win.SetIconName("security-medium")
box, _ := gtk.ListBoxNew() boxPermanent, _ := gtk.ListBoxNew()
scrolled.Add(box) swRulesPermanent.Add(boxPermanent)
boxSession, _ := gtk.ListBoxNew()
swRulesSession.Add(boxSession)
boxSystem, _ := gtk.ListBoxNew()
swRulesSystem.Add(boxSystem)
dbus, err := newDbusObject() dbus, err := newDbusObject()
if err != nil { if err != nil {
failDialog(win, "Failed to connect to dbus system bus: %v", err) failDialog(win, "Failed to connect to dbus system bus: %v", err)
} }
rl := NewRuleList(dbus, win, box) rlPermanent := NewRuleList(dbus, win, boxPermanent)
if _, err := dbus.isEnabled(); err != nil {
failDialog(win, "Unable is connect to firewall daemon. Is it running?")
}
rlPermanent.loadRules(RULE_MODE_PERMANENT)
rlSession := NewRuleList(dbus, win, boxSession)
if _, err := dbus.isEnabled(); err != nil {
failDialog(win, "Unable is connect to firewall daemon. Is it running?")
}
rlSession.loadRules(RULE_MODE_SESSION)
rlSystem := NewRuleList(dbus, win, boxSystem)
if _, err := dbus.isEnabled(); err != nil { if _, err := dbus.isEnabled(); err != nil {
failDialog(win, "Unable is connect to firewall daemon. Is it running?") failDialog(win, "Unable is connect to firewall daemon. Is it running?")
} }
rl.loadRules() rlSystem.loadRules(RULE_MODE_SYSTEM)
loadConfig(win, b, dbus) loadConfig(win, b, dbus)
app.AddWindow(win) app.AddWindow(win)
win.ShowAll() win.ShowAll()

@ -2,11 +2,12 @@ package main
import ( import (
"fmt" "fmt"
"github.com/gotk3/gotk3/gtk"
"net" "net"
"strconv" "strconv"
"strings" "strings"
"unicode" "unicode"
"github.com/gotk3/gotk3/gtk"
) )
const ( const (
@ -24,7 +25,7 @@ type ruleEdit struct {
ok *gtk.Button ok *gtk.Button
} }
func newRuleEdit(rr *ruleRow) *ruleEdit { func newRuleEdit(rr *ruleRow, saveasnew bool) *ruleEdit {
redit := &ruleEdit{row: rr} redit := &ruleEdit{row: rr}
b := newBuilder("RuleEdit") b := newBuilder("RuleEdit")
b.getItems( b.getItems(
@ -40,6 +41,9 @@ func newRuleEdit(rr *ruleRow) *ruleEdit {
"on_port_changed": redit.onChanged, "on_port_changed": redit.onChanged,
"on_host_changed": redit.onChanged, "on_host_changed": redit.onChanged,
}) })
if saveasnew {
redit.ok.SetLabel("Save As New")
}
return redit return redit
} }
@ -124,19 +128,25 @@ func (re *ruleEdit) updateRow() {
re.row.update() re.row.update()
} }
func (re *ruleEdit) run() { func (re *ruleEdit) run(saveasnew bool) {
re.dialog.SetTransientFor(re.row.rl.win) re.dialog.SetTransientFor(re.row.rl.win)
if re.dialog.Run() == editDialogOk { if re.dialog.Run() == editDialogOk {
if saveasnew {
re.row.rule.Mode = RULE_MODE_PERMANENT
}
re.updateRow() re.updateRow()
re.row.rl.dbus.updateRule(re.row.rule) re.row.rl.dbus.updateRule(re.row.rule)
if saveasnew {
re.row.widget.Hide()
}
} }
re.dialog.Destroy() re.dialog.Destroy()
} }
func (rr *ruleRow) runEditor() { func (rr *ruleRow) runEditor(saveasnew bool) {
redit := newRuleEdit(rr) redit := newRuleEdit(rr, saveasnew)
redit.updateDialogFields() redit.updateDialogFields()
redit.run() redit.run(saveasnew)
} }
func (re *ruleEdit) onPortInsertText(entry *gtk.Entry, text string) { func (re *ruleEdit) onPortInsertText(entry *gtk.Entry, text string) {

@ -22,27 +22,34 @@ type ruleRow struct {
app_label *gtk.Label app_label *gtk.Label
verb_label *gtk.Label verb_label *gtk.Label
target_label *gtk.Label target_label *gtk.Label
edit_button *gtk.Button
save_button *gtk.Button
delete_button *gtk.Button
} }
func NewRuleList(dbus *dbusObject, win *gtk.Window, list *gtk.ListBox) *ruleList { func NewRuleList(dbus *dbusObject, win *gtk.Window, list *gtk.ListBox) *ruleList {
rl := &ruleList{dbus: dbus, win: win, list: list} rl := &ruleList{dbus: dbus, win: win, list: list}
rl.list.SetSelectionMode(gtk.SELECTION_NONE)
rl.col1, _ = gtk.SizeGroupNew(gtk.SIZE_GROUP_HORIZONTAL) rl.col1, _ = gtk.SizeGroupNew(gtk.SIZE_GROUP_HORIZONTAL)
rl.col2, _ = gtk.SizeGroupNew(gtk.SIZE_GROUP_HORIZONTAL) rl.col2, _ = gtk.SizeGroupNew(gtk.SIZE_GROUP_HORIZONTAL)
rl.col3, _ = gtk.SizeGroupNew(gtk.SIZE_GROUP_HORIZONTAL) rl.col3, _ = gtk.SizeGroupNew(gtk.SIZE_GROUP_HORIZONTAL)
return rl return rl
} }
func (rl *ruleList) loadRules() error { func (rl *ruleList) loadRules(mode uint16) error {
rules, err := rl.dbus.listRules() rules, err := rl.dbus.listRules()
if err != nil { if err != nil {
return err return err
} }
rl.addRules(rules) rl.addRules(rules, mode)
return nil return nil
} }
func (rl *ruleList) addRules(rules []dbusRule) { func (rl *ruleList) addRules(rules []dbusRule, mode uint16) {
for i := 0; i < len(rules); i++ { for i := 0; i < len(rules); i++ {
if rules[i].Mode != mode {
continue
}
row := createWidget(&rules[i]) row := createWidget(&rules[i])
row.rl = rl row.rl = rl
rl.col1.AddWidget(row.app_label) rl.col1.AddWidget(row.app_label)
@ -65,9 +72,26 @@ func createWidget(rule *dbusRule) *ruleRow {
"app_label", &row.app_label, "app_label", &row.app_label,
"verb_label", &row.verb_label, "verb_label", &row.verb_label,
"target_label", &row.target_label, "target_label", &row.target_label,
"edit_button", &row.edit_button,
"save_button", &row.save_button,
"delete_button", &row.delete_button,
) )
switch rule.Mode {
case RULE_MODE_SYSTEM:
row.edit_button.SetVisible(false)
row.edit_button.SetNoShowAll(true)
row.delete_button.SetSensitive(false)
row.delete_button.SetTooltipText("Cannot delete system rules")
break
case RULE_MODE_SESSION:
row.save_button.SetSensitive(true)
row.save_button.SetNoShowAll(false)
break
}
builder.ConnectSignals(map[string]interface{}{ builder.ConnectSignals(map[string]interface{}{
"on_edit_rule": row.onEdit, "on_edit_rule": row.onEdit,
"on_save_rule": row.onSaveAsNew,
"on_delete_rule": row.onDelete, "on_delete_rule": row.onDelete,
}) })
row.widget, _ = gtk.ListBoxRowNew() row.widget, _ = gtk.ListBoxRowNew()
@ -104,14 +128,18 @@ func getTargetText(rule *dbusRule) string {
return fmt.Sprintf("Connections to All hosts on port %s", items[1]) return fmt.Sprintf("Connections to All hosts on port %s", items[1])
} }
if items[1] == "*" { if items[1] == "*" {
return fmt.Sprintf("All connections to host %s") return fmt.Sprintf("All connections to host %s", items[0])
} }
return fmt.Sprintf("Connections to %s on port %s", items[0], items[1]) return fmt.Sprintf("Connections to %s on port %s", items[0], items[1])
} }
func (rr *ruleRow) onSaveAsNew() {
rr.runEditor(true)
}
func (rr *ruleRow) onEdit() { func (rr *ruleRow) onEdit() {
rr.runEditor() rr.runEditor(false)
} }
func (rr *ruleRow) onDelete() { func (rr *ruleRow) onDelete() {

@ -73,7 +73,15 @@ const OptionListItem = new Lang.Class({
}, },
setText: function(text) { setText: function(text) {
if (text) {
this._label.text = text; this._label.text = text;
this._label.show();
this.actor.show();
} else {
this._label.text = "";
this._label.hide();
this.actor.hide();
}
}, },
setSelected: function(isSelected) { setSelected: function(isSelected) {
@ -155,6 +163,20 @@ const OptionList = new Lang.Class({
log("unexpected scope value "+ this.buttonGroup._selected); log("unexpected scope value "+ this.buttonGroup._selected);
return RuleScope.APPLY_SESSION; return RuleScope.APPLY_SESSION;
} }
},
scopeToIdx: function(scope) {
switch (scope) {
case RuleScope.APPLY_ONCE:
return 2;
case RuleScope.APPLY_SESSION:
return 1;
case RuleScope.APPLY_FOREVER:
return 0;
default:
log("unexpected scope value "+ scope);
return 1;
}
} }
}); });
@ -379,13 +401,15 @@ const PromptDialog = new Lang.Class({
box.add_child(this.optionList.actor); box.add_child(this.optionList.actor);
this.optionList.addOptions([ this.optionList.addOptions([
"Only PORT AND ADDRESS", "Only PORT AND ADDRESS",
"Only ADDRESS",
"Only PORT",
"Any Connection"]); "Any Connection"]);
this._initialKeyFocusDestroyId = 1;
this.setButtons([ this.setButtons([
{ label: "Allow", action: Lang.bind(this, this.onAllow) }, { label: "Allow", action: Lang.bind(this, this.onAllow) },
{ label: "Deny", action: Lang.bind(this, this.onDeny) }]); { label: "Deny", action: Lang.bind(this, this.onDeny) }
]);
}, },
onAllow: function() { onAllow: function() {
@ -417,20 +441,27 @@ const PromptDialog = new Lang.Class({
case 0: case 0:
return this._address + ":" + this._port; return this._address + ":" + this._port;
case 1: case 1:
return this._address + ":*";
case 2:
return "*:" + this._port;
case 3:
return "*:*"; return "*:*";
} }
}, },
update: function(application, icon, path, address, port, ip, user, pid) { update: function(application, icon, path, address, port, ip, user, pid, proto, expanded, expert, action) {
this._address = address; this._address = address;
this._port = port; this._port = port;
let port_str = "TCP Port "+ port; let port_str = (proto+"").toUpperCase() + " Port "+ port;
this.header.setTitle(application); this.header.setTitle(application);
this.header.setMessage("Wants to connect to "+ address + " on " + port_str); this.header.setMessage("Wants to connect to "+ address + " on " + port_str);
if (expanded) {
this.details.isOpen = false;
this.details.activate()
}
if(icon) { if(icon) {
this.header.setIcon(icon); this.header.setIcon(icon);
} else { } else {
@ -438,6 +469,15 @@ const PromptDialog = new Lang.Class({
} }
this.optionList.setOptionText(0, "Only "+ address + " on "+ port_str); this.optionList.setOptionText(0, "Only "+ address + " on "+ port_str);
if (expert) {
this.optionList.setOptionText(1, "Only "+ address + " on any port");
this.optionList.setOptionText(2, "Only "+ port_str);
} else {
this.optionList.setOptionText(1, false);
this.optionList.setOptionText(2, false);
}
this.optionList.buttonGroup._setChecked(this.optionList.scopeToIdx(action))
this.info.setDetails(ip, path, pid, user); this.info.setDetails(ip, path, pid, user);
}, },
}); });

@ -52,6 +52,9 @@ const FirewallPromptInterface = '<node> \
<arg type="s" direction="in" name="ip" /> \ <arg type="s" direction="in" name="ip" /> \
<arg type="s" direction="in" name="user" /> \ <arg type="s" direction="in" name="user" /> \
<arg type="i" direction="in" name="pid" /> \ <arg type="i" direction="in" name="pid" /> \
<arg type="b" direction="in" name="expanded" /> \
<arg type="b" direction="in" name="expert" /> \
<arg type="i" direction="in" name="action" /> \
<arg type="i" direction="out" name="scope" /> \ <arg type="i" direction="out" name="scope" /> \
<arg type="s" direction="out" name="rule" /> \ <arg type="s" direction="out" name="rule" /> \
</method> \ </method> \
@ -83,13 +86,12 @@ const FirewallPromptHandler = new Lang.Class({
}, },
RequestPromptAsync: function(params, invocation) { RequestPromptAsync: function(params, invocation) {
let [app, icon, path, address, port, ip, user, pid] = params; let [app, icon, path, address, port, ip, user, pid, expanded, expert, action] = params;
this._closeDialog(); this._closeDialog();
this._dialog = new Dialog.PromptDialog(invocation); this._dialog = new Dialog.PromptDialog(invocation);
this._invocation = invocation; this._invocation = invocation;
this._dialog.update(app, icon, path, address, port, ip, user, pid); this._dialog.update(app, icon, path, address, port, ip, user, pid, "TCP", expanded, expert, action);
this._dialog.open(); this._dialog.open();
}, },
CloseAsync: function(params, invocation) { CloseAsync: function(params, invocation) {
@ -99,7 +101,7 @@ const FirewallPromptHandler = new Lang.Class({
TestPrompt: function(params, invocation) { TestPrompt: function(params, invocation) {
this._closeDialog(); this._closeDialog();
this._dialog = new Dialog.PromptDialog(nil); this._dialog = new Dialog.PromptDialog(nil);
this._dialog.update("Firefox", "firefox", "/usr/bin/firefox", "242.12.111.18", "443", "linux", "2342"); this._dialog.update("Firefox", "firefox", "/usr/bin/firefox-esr", "242.12.111.18", "443", "linux", "2342", "TCP", true, true);
this._dialog.open(); this._dialog.open();
} }
}); });

@ -9,9 +9,12 @@ import (
const iptablesRule = "OUTPUT -t mangle -m conntrack --ctstate NEW -j NFQUEUE --queue-num 0 --queue-bypass" const iptablesRule = "OUTPUT -t mangle -m conntrack --ctstate NEW -j NFQUEUE --queue-num 0 --queue-bypass"
const dnsRule = "INPUT --protocol udp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass" const dnsRule = "INPUT --protocol udp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass"
//const logRule = "OUTPUT --protocol tcp -m mark --mark 1 -j LOG"
const blockRule = "OUTPUT --protocol tcp -m mark --mark 1 -j REJECT" const blockRule = "OUTPUT --protocol tcp -m mark --mark 1 -j REJECT"
func setupIPTables() { func setupIPTables() {
// addIPTRules(iptablesRule, dnsRule, logRule, blockRule)
addIPTRules(iptablesRule, dnsRule, blockRule) addIPTRules(iptablesRule, dnsRule, blockRule)
} }

@ -13,9 +13,10 @@ import (
"time" "time"
"unsafe" "unsafe"
"github.com/op/go-logging"
"github.com/subgraph/fw-daemon/nfqueue" "github.com/subgraph/fw-daemon/nfqueue"
"github.com/subgraph/go-procsnitch" "github.com/subgraph/go-procsnitch"
"github.com/op/go-logging"
) )
var log = logging.MustGetLogger("sgfw") var log = logging.MustGetLogger("sgfw")
@ -35,7 +36,7 @@ func isTerminal(fd int) bool {
return err == 0 return err == 0
} }
func setupLoggerBackend() logging.LeveledBackend { func setupLoggerBackend(lvl logging.Level) logging.LeveledBackend {
format := logFormat format := logFormat
if isTerminal(int(os.Stderr.Fd())) { if isTerminal(int(os.Stderr.Fd())) {
format = ttyFormat format = ttyFormat
@ -43,12 +44,10 @@ func setupLoggerBackend() logging.LeveledBackend {
backend := logging.NewLogBackend(os.Stderr, "", 0) backend := logging.NewLogBackend(os.Stderr, "", 0)
formatter := logging.NewBackendFormatter(backend, format) formatter := logging.NewBackendFormatter(backend, format)
leveler := logging.AddModuleLevel(formatter) leveler := logging.AddModuleLevel(formatter)
leveler.SetLevel(logging.NOTICE, "sgfw") leveler.SetLevel(lvl, "sgfw")
return leveler return leveler
} }
var logRedact bool
type Firewall struct { type Firewall struct {
dbus *dbusServer dbus *dbusServer
dns *dnsCache dns *dnsCache
@ -187,8 +186,8 @@ func getSocksChainConfig(config *SocksJsonConfig) *socksChainConfig {
} }
func main() { func main() {
readConfig()
logBackend := setupLoggerBackend() logBackend := setupLoggerBackend(FirewallConfig.LoggingLevel)
log.SetBackend(logBackend) log.SetBackend(logBackend)
procsnitch.SetLogger(log) procsnitch.SetLogger(log)

@ -2,6 +2,7 @@ package main
import ( import (
"fmt" "fmt"
"strings"
"sync" "sync"
"github.com/subgraph/fw-daemon/nfqueue" "github.com/subgraph/fw-daemon/nfqueue"
@ -9,6 +10,12 @@ import (
"net" "net"
) )
var _interpreters = []string{
"python",
"ruby",
"bash",
}
type pendingConnection interface { type pendingConnection interface {
policy() *Policy policy() *Policy
procInfo() *procsnitch.Info procInfo() *procsnitch.Info
@ -98,7 +105,7 @@ func (p *Policy) processPacket(pkt *nfqueue.Packet, pinfo *procsnitch.Info) {
p.lock.Lock() p.lock.Lock()
defer p.lock.Unlock() defer p.lock.Unlock()
name := p.fw.dns.Lookup(pkt.Dst) name := p.fw.dns.Lookup(pkt.Dst)
if !logRedact { if !FirewallConfig.LogRedact {
log.Infof("Lookup(%s): %s", pkt.Dst.String(), name) log.Infof("Lookup(%s): %s", pkt.Dst.String(), name)
} }
result := p.rules.filterPacket(pkt, pinfo, name) result := p.rules.filterPacket(pkt, pinfo, name)
@ -165,6 +172,7 @@ func (p *Policy) processNewRule(r *Rule, scope int32) bool {
func (p *Policy) parseRule(s string, add bool) (*Rule, error) { func (p *Policy) parseRule(s string, add bool) (*Rule, error) {
r := new(Rule) r := new(Rule)
r.mode = RULE_MODE_PERMANENT
r.policy = p r.policy = p
if !r.parse(s) { if !r.parse(s) {
return nil, parseError(s) return nil, parseError(s)
@ -195,7 +203,7 @@ func (p *Policy) filterPending(rule *Rule) {
remaining := []pendingConnection{} remaining := []pendingConnection{}
for _, pc := range p.pendingQueue { for _, pc := range p.pendingQueue {
if rule.match(pc.dst(), pc.dstPort(), pc.hostname()) { if rule.match(pc.dst(), pc.dstPort(), pc.hostname()) {
log.Infof("Also applying %s to %s", rule.getString(logRedact), pc.print()) log.Infof("Also applying %s to %s", rule.getString(FirewallConfig.LogRedact), pc.print())
if rule.rtype == RULE_ALLOW { if rule.rtype == RULE_ALLOW {
pc.accept() pc.accept()
} else { } else {
@ -212,7 +220,7 @@ func (p *Policy) filterPending(rule *Rule) {
func (p *Policy) hasPersistentRules() bool { func (p *Policy) hasPersistentRules() bool {
for _, r := range p.rules { for _, r := range p.rules {
if !r.sessionOnly { if r.mode != RULE_MODE_SESSION {
return true return true
} }
} }
@ -231,7 +239,7 @@ func printPacket(pkt *nfqueue.Packet, hostname string) string {
} }
}() }()
if logRedact { if FirewallConfig.LogRedact {
hostname = "[redacted]" hostname = "[redacted]"
} }
name := hostname name := hostname
@ -253,12 +261,23 @@ func (fw *Firewall) filterPacket(pkt *nfqueue.Packet) {
pkt.Accept() pkt.Accept()
return return
} }
log.Debugf("filterPacket [%s] %s", pinfo.ExePath, printPacket(pkt, fw.dns.Lookup(pkt.Dst))) ppath := pinfo.ExePath
cf := strings.Fields(pinfo.CmdLine)
if len(cf) > 1 && strings.HasPrefix(cf[1], "/") {
for _, intp := range _interpreters {
if strings.Contains(pinfo.ExePath, intp) {
ppath = cf[1]
break
}
}
}
//log.Debugf("pinfo: [%d] %s > %s", pinfo.ParentPid, pinfo.CmdLine, pinfo.ParentExePath)
log.Debugf("filterPacket [%s] %s", ppath, printPacket(pkt, fw.dns.Lookup(pkt.Dst)))
if basicAllowPacket(pkt) { if basicAllowPacket(pkt) {
pkt.Accept() pkt.Accept()
return return
} }
policy := fw.PolicyForPath(pinfo.ExePath) policy := fw.PolicyForPath(ppath)
policy.processPacket(pkt, pinfo) policy.processPacket(pkt, pinfo)
} }

@ -5,6 +5,7 @@ import (
"github.com/godbus/dbus" "github.com/godbus/dbus"
"os/user" "os/user"
"strconv" "strconv"
"strings"
"sync" "sync"
) )
@ -65,14 +66,28 @@ func (p *prompter) processNextPacket() bool {
func printScope(scope int32) string { func printScope(scope int32) string {
switch scope { switch scope {
case APPLY_FOREVER:
return "APPLY_FOREVER"
case APPLY_SESSION: case APPLY_SESSION:
return "APPLY_SESSION" return "SESSION"
case APPLY_ONCE: case APPLY_ONCE:
return "APPLY_ONCE" return "ONCE"
case APPLY_FOREVER:
return "FOREVER"
default:
return "SESSION"
}
}
func valueScope(scope string) int32 {
scope = strings.ToUpper(scope)
switch scope {
case "SESSION":
return APPLY_SESSION
case "ONCE":
return APPLY_ONCE
case "FOREVER":
return APPLY_FOREVER
default: default:
return fmt.Sprintf("Unknown (%d)", scope) return APPLY_SESSION
} }
} }
@ -94,7 +109,10 @@ func (p *prompter) processConnection(pc pendingConnection) {
int32(pc.dstPort()), int32(pc.dstPort()),
pc.dst().String(), pc.dst().String(),
uidToUser(pc.procInfo().UID), uidToUser(pc.procInfo().UID),
int32(pc.procInfo().Pid)) int32(pc.procInfo().Pid),
FirewallConfig.PromptExpanded,
FirewallConfig.PromptExpert,
FirewallConfig.DefaultActionId)
err := call.Store(&scope, &rule) err := call.Store(&scope, &rule)
if err != nil { if err != nil {
log.Warningf("Error sending dbus RequestPrompt message: %v", err) log.Warningf("Error sending dbus RequestPrompt message: %v", err)
@ -111,7 +129,7 @@ func (p *prompter) processConnection(pc pendingConnection) {
return return
} }
if scope == APPLY_SESSION { if scope == APPLY_SESSION {
r.sessionOnly = true r.mode = RULE_MODE_SESSION
} }
if !policy.processNewRule(r, scope) { if !policy.processNewRule(r, scope) {
p.lock.Lock() p.lock.Lock()

@ -23,10 +23,18 @@ const (
const matchAny = 0 const matchAny = 0
const noAddress = uint32(0xffffffff) const noAddress = uint32(0xffffffff)
type RuleMode uint16
const (
RULE_MODE_SESSION RuleMode = iota
RULE_MODE_PERMANENT
RULE_MODE_SYSTEM
)
type Rule struct { type Rule struct {
id uint id uint
policy *Policy policy *Policy
sessionOnly bool mode RuleMode
rtype int rtype int
hostname string hostname string
addr uint32 addr uint32
@ -42,8 +50,12 @@ func (r *Rule) getString(redact bool) string {
if r.rtype == RULE_ALLOW { if r.rtype == RULE_ALLOW {
rtype = "ALLOW" rtype = "ALLOW"
} }
rmode := ""
if r.mode == RULE_MODE_SYSTEM {
rmode = "|SYSTEM"
}
return fmt.Sprintf("%s|%s", rtype, r.AddrString(redact)) return fmt.Sprintf("%s|%s%s", rtype, r.AddrString(redact), rmode)
} }
func (r *Rule) AddrString(redact bool) string { func (r *Rule) AddrString(redact bool) string {
@ -103,10 +115,10 @@ func (rl *RuleList) filter(dst net.IP, dstPort uint16, hostname string, pinfo *p
for _, r := range *rl { for _, r := range *rl {
if r.match(dst, dstPort, hostname) { if r.match(dst, dstPort, hostname) {
dstStr := dst.String() dstStr := dst.String()
if logRedact { if FirewallConfig.LogRedact {
dstStr = "[redacted]" dstStr = "[redacted]"
} }
log.Infof("%s (%s -> %s:%d)", r.getString(logRedact), pinfo.ExePath, dstStr, dstPort) log.Infof("%s (%s -> %s:%d)", r.getString(FirewallConfig.LogRedact), pinfo.ExePath, dstStr, dstPort)
if r.rtype == RULE_DENY { if r.rtype == RULE_DENY {
return FILTER_DENY return FILTER_DENY
} else if r.rtype == RULE_ALLOW { } else if r.rtype == RULE_ALLOW {
@ -124,9 +136,12 @@ func parseError(s string) error {
func (r *Rule) parse(s string) bool { func (r *Rule) parse(s string) bool {
r.addr = noAddress r.addr = noAddress
parts := strings.Split(s, "|") parts := strings.Split(s, "|")
if len(parts) != 2 { if len(parts) < 2 {
return false return false
} }
if len(parts) >= 3 && parts[2] == "SYSTEM" {
r.mode = RULE_MODE_SYSTEM
}
return r.parseVerb(parts[0]) && r.parseTarget(parts[1]) return r.parseVerb(parts[0]) && r.parseTarget(parts[1])
} }
@ -231,7 +246,7 @@ func savePolicy(f *os.File, p *Policy) {
return return
} }
for _, r := range p.rules { for _, r := range p.rules {
if !r.sessionOnly { if r.mode != RULE_MODE_SESSION {
if !writeLine(f, r.String()) { if !writeLine(f, r.String()) {
return return
} }

Loading…
Cancel
Save