From 3409ab196055d69be58b8727f6d1b06e21a911d8 Mon Sep 17 00:00:00 2001 From: Philippe Caseiro Date: Wed, 7 Nov 2018 11:50:59 +0100 Subject: [PATCH] Adding Rules and Redirects --- uci_firewall_redirect.go | 92 +++++++++++++++++++++++++++++++++++ uci_firewall_redirect_test.go | 83 +++++++++++++++++++++++++++++++ uci_firewall_rules.go | 86 ++++++++++++++++++++++++++++++++ uci_firewall_rules_test.go | 75 ++++++++++++++++++++++++++++ 4 files changed, 336 insertions(+) create mode 100644 uci_firewall_redirect.go create mode 100644 uci_firewall_redirect_test.go create mode 100644 uci_firewall_rules.go create mode 100644 uci_firewall_rules_test.go diff --git a/uci_firewall_redirect.go b/uci_firewall_redirect.go new file mode 100644 index 0000000..9f478c7 --- /dev/null +++ b/uci_firewall_redirect.go @@ -0,0 +1,92 @@ +package owrt + +import ( + "fmt" +) + +// UCIFirewallRedirect is the description of an Wireless interface (cf Openwrt doc) on top of an Wireless Device +type UCIFirewallRedirect struct { + Name string + Index int + Src string + Dest string + Target string + Proto string + SrcDIP string + SrcDPort string + DestIP string + DestPort string +} + +// NewUCIFirewallRedirect builds a new UCIFirewallRedirect instance +func NewUCIFirewallRedirect() *UCIFirewallRedirect { + return &UCIFirewallRedirect{} +} + +// Create add a new firewall rule in UCI Configuration +func (rd *UCIFirewallRedirect) Create(uci *UCI) *Action { + var confPrefix string + + confPrefix = fmt.Sprintf("firewall.@redirect[%d]", rd.Index) + + conf := make(map[string][]string) + + conf["name"] = append(conf["name"], fmt.Sprintf("%s.name", confPrefix), rd.Name) + conf["src"] = append(conf["src"], fmt.Sprintf("%s.src", confPrefix), rd.Src) + conf["target"] = append(conf["target"], fmt.Sprintf("%s.target", confPrefix), rd.Target) + conf["proto"] = append(conf["proto"], fmt.Sprintf("%s.proto", confPrefix), rd.Proto) + conf["src_dip"] = append(conf["src_dip"], fmt.Sprintf("%s.src_dip", confPrefix), rd.SrcDIP) + conf["src_dport"] = append(conf["src_dport"], fmt.Sprintf("%s.src_dport", confPrefix), rd.SrcDPort) + conf["dest_ip"] = append(conf["dest_ip"], fmt.Sprintf("%s.dest_ip", confPrefix), rd.DestIP) + conf["dest_port"] = append(conf["dest_port"], fmt.Sprintf("%s.dest_port", confPrefix), rd.DestPort) + + uci.Add("firewall", "redirect") + + for _, value := range conf { + if value[1] != "" { + result := uci.Set(value[0], value[1]) + if result.ReturnCode != 0 { + return result + } + } + } + + return &Action{ + CommandResult: &CommandResult{ + Stdout: "", + Stderr: "", + ReturnCode: 0, + }, + } +} + +// Save commit and relaod configuration (writes it to files !) +func (rd *UCIFirewallRedirect) Save(uci *UCI) *Action { + commitRes := uci.Commit() + if commitRes.ReturnCode != 0 { + return commitRes + } + + reload := uci.Reload() + return reload +} + +// Delete remove wifi interface from UCI Configuration +func (rd *UCIFirewallRedirect) Delete(uci *UCI) *Action { + toDelete := fmt.Sprintf("firewall.@redirect[%d]", rd.Index) + del := uci.Delete(toDelete) + if del.ReturnCode != 0 { + return del + } + return uci.Commit() +} + +// Update add a new entry for wifi interface in UCI Configuration +func (rd *UCIFirewallRedirect) Update(uci *UCI) *Action { + rd.Delete(uci) + create := rd.Create(uci) + if create.ReturnCode != 0 { + return create + } + return uci.Commit() +} diff --git a/uci_firewall_redirect_test.go b/uci_firewall_redirect_test.go new file mode 100644 index 0000000..1fe9dac --- /dev/null +++ b/uci_firewall_redirect_test.go @@ -0,0 +1,83 @@ +package owrt + +import ( + "testing" +) + +const ( + redirectName = "Test" + redirectIndex = -1 + redirectSrc = "10.10.10.10/24" + redirectTarget = "ACCEPT" + redirectProto = "tcp" + redirectSrcDIP = "1.1.1.1" + redirectSrcDPort = "333" + redirectDestIP = "10.10.10.10" + redirectDestPort = "22" +) + +func TestFWRedirectCreate(t *testing.T) { + exec := createMockExecutor("", "", 0) + uci := NewUCIWithExecutor(exec) + + redirect := NewUCIFirewallRedirect() + redirect.Name = redirectName + redirect.Index = redirectIndex + redirect.Src = redirectSrc + redirect.Target = redirectTarget + redirect.Proto = redirectProto + redirect.SrcDIP = redirectSrcDIP + redirect.SrcDPort = redirectSrcDPort + redirect.DestIP = redirectDestIP + redirect.DestPort = redirectDestPort + + if redirect.Create(uci).ReturnCode != 0 { + t.Fatalf("UCIFirewallRedirect.Create() failed !") + } +} + +func TestFWRedirectUpdate(t *testing.T) { + exec := createMockExecutor("", "", 0) + uci := NewUCIWithExecutor(exec) + + redirect := NewUCIFirewallRedirect() + redirect.Name = redirectName + redirect.Index = redirectIndex + redirect.Src = redirectSrc + redirect.Target = redirectTarget + redirect.Proto = redirectProto + redirect.SrcDIP = redirectSrcDIP + redirect.SrcDPort = redirectSrcDPort + redirect.DestIP = redirectDestIP + redirect.DestPort = redirectDestPort + + if redirect.Create(uci).ReturnCode != 0 { + t.Fatalf("UCIFirewallRedirect.Create() failed !") + } + + redirect.Name = "Tutu" + + if redirect.Update(uci).ReturnCode != 0 { + t.Fatalf("UCIFirewallRedirect.Update() failed !") + } +} + +func TestFWRedirectDelete(t *testing.T) { + exec := createMockExecutor("", "", 0) + uci := NewUCIWithExecutor(exec) + + redirect := NewUCIFirewallRedirect() + redirect.Name = redirectName + redirect.Index = redirectIndex + redirect.Src = redirectSrc + redirect.Target = redirectTarget + redirect.Proto = redirectProto + redirect.SrcDIP = redirectSrcDIP + redirect.SrcDPort = redirectSrcDPort + redirect.DestIP = redirectDestIP + redirect.DestPort = redirectDestPort + + if redirect.Delete(uci).ReturnCode != 0 { + t.Fatalf("UCIWirelessInterface.Delete() failed !") + } +} diff --git a/uci_firewall_rules.go b/uci_firewall_rules.go new file mode 100644 index 0000000..3874d5e --- /dev/null +++ b/uci_firewall_rules.go @@ -0,0 +1,86 @@ +package owrt + +import ( + "fmt" +) + +// UCIFirewallRule is the description of an Wireless interface (cf Openwrt doc) on top of an Wireless Device +type UCIFirewallRule struct { + Name string + Index int + Src string + Target string + Proto string + DestPort string + SourcePort string +} + +// NewUCIFirewallRule builds a new UCIFirewallRule instance +func NewUCIFirewallRule() *UCIFirewallRule { + return &UCIFirewallRule{} +} + +// Create add a new firewall rule in UCI Configuration +func (fw *UCIFirewallRule) Create(uci *UCI) *Action { + var confPrefix string + + confPrefix = fmt.Sprintf("firewall.@rule[%d]", fw.Index) + + conf := make(map[string][]string) + + conf["name"] = append(conf["network"], fmt.Sprintf("%s.name", confPrefix), fw.Name) + conf["src"] = append(conf["src"], fmt.Sprintf("%s.src", confPrefix), fw.Src) + conf["target"] = append(conf["target"], fmt.Sprintf("%s.target", confPrefix), fw.Target) + conf["proto"] = append(conf["proto"], fmt.Sprintf("%s.proto", confPrefix), fw.Proto) + conf["dest_port"] = append(conf["dest_port"], fmt.Sprintf("%s.dest_port", confPrefix), fw.DestPort) + conf["src_port"] = append(conf["src_port"], fmt.Sprintf("%s.src_port", confPrefix), fw.SourcePort) + + uci.Add("firewall", "rule") + for _, value := range conf { + if value[1] != "" { + result := uci.Set(value[0], value[1]) + if result.ReturnCode != 0 { + return result + } + } + } + + return &Action{ + CommandResult: &CommandResult{ + Stdout: "", + Stderr: "", + ReturnCode: 0, + }, + } +} + +// Save commit and relaod configuration (writes it to files !) +func (fw *UCIFirewallRule) Save(uci *UCI) *Action { + commitRes := uci.Commit() + if commitRes.ReturnCode != 0 { + return commitRes + } + + reload := uci.Reload() + return reload +} + +// Delete remove wifi interface from UCI Configuration +func (fw *UCIFirewallRule) Delete(uci *UCI) *Action { + toDelete := fmt.Sprintf("firewall.@rule[%d]", fw.Index) + del := uci.Delete(toDelete) + if del.ReturnCode != 0 { + return del + } + return uci.Commit() +} + +// Update add a new entry for wifi interface in UCI Configuration +func (fw *UCIFirewallRule) Update(uci *UCI) *Action { + fw.Delete(uci) + create := fw.Create(uci) + if create.ReturnCode != 0 { + return create + } + return uci.Commit() +} diff --git a/uci_firewall_rules_test.go b/uci_firewall_rules_test.go new file mode 100644 index 0000000..2ff8781 --- /dev/null +++ b/uci_firewall_rules_test.go @@ -0,0 +1,75 @@ +package owrt + +import ( + "testing" +) + +const ( + ruleName = "Test" + ruleIndex = -1 + ruleSrc = "10.10.10.10/24" + ruleTarget = "ACCEPT" + ruleProto = "tcp" + ruleDestPort = "80" + ruleSourcePort = "8080" +) + +func TestFWRuleCreate(t *testing.T) { + exec := createMockExecutor("", "", 0) + uci := NewUCIWithExecutor(exec) + + rule := NewUCIFirewallRule() + rule.Name = ruleName + rule.Index = ruleIndex + rule.Src = ruleSrc + rule.Target = ruleTarget + rule.Proto = ruleProto + rule.DestPort = ruleDestPort + rule.SourcePort = ruleSourcePort + + if rule.Create(uci).ReturnCode != 0 { + t.Fatalf("UCIFirewallRule.Create() failed !") + } +} + +func TestFWRuleUpdate(t *testing.T) { + exec := createMockExecutor("", "", 0) + uci := NewUCIWithExecutor(exec) + + rule := NewUCIFirewallRule() + rule.Name = ruleName + rule.Index = ruleIndex + rule.Src = ruleSrc + rule.Target = ruleTarget + rule.Proto = ruleProto + rule.DestPort = ruleDestPort + rule.SourcePort = ruleSourcePort + + if rule.Create(uci).ReturnCode != 0 { + t.Fatalf("UCIFirewallRule.Create() failed !") + } + + rule.Name = "Tutu" + + if rule.Update(uci).ReturnCode != 0 { + t.Fatalf("UCIFirewallRule.Update() failed !") + } +} + +func TestFWRuleDelete(t *testing.T) { + exec := createMockExecutor("", "", 0) + uci := NewUCIWithExecutor(exec) + + rule := NewUCIFirewallRule() + rule.Name = ruleName + rule.Index = ruleIndex + rule.Src = ruleSrc + rule.Target = ruleTarget + rule.Proto = ruleProto + rule.DestPort = ruleDestPort + rule.SourcePort = ruleSourcePort + + if rule.Delete(uci).ReturnCode != 0 { + t.Fatalf("UCIWirelessInterface.Delete() failed !") + } +}