Adding new UCIFirewall struct

This is to manage all Firewall
This commit is contained in:
Philippe Caseiro 2018-11-12 09:16:41 +01:00
parent b9559bb9f3
commit da4fa533b4
3 changed files with 154 additions and 2 deletions

14
uci.go
View File

@ -16,6 +16,7 @@ type UCI struct {
exec Executor exec Executor
CustomFirewallFile string CustomFirewallFile string
Wireless *UCIWirelessConf Wireless *UCIWirelessConf
Firewall *UCIFirewall
} }
// NewUCI return an UCI instance to interact with UCI // NewUCI return an UCI instance to interact with UCI
@ -23,7 +24,8 @@ func NewUCI() *UCI {
exec := &localExecutor{} exec := &localExecutor{}
customFWFile := "/etc/" customFWFile := "/etc/"
wireless := &UCIWirelessConf{} wireless := &UCIWirelessConf{}
return &UCI{exec, customFWFile, wireless} firewall := &UCIFirewall{}
return &UCI{exec, customFWFile, wireless, firewall}
} }
// NewUCIWithExecutor returns a UCI Instance an gives you the ability to provide // NewUCIWithExecutor returns a UCI Instance an gives you the ability to provide
@ -31,7 +33,8 @@ func NewUCI() *UCI {
func NewUCIWithExecutor(exec Executor, customFWFile string) *UCI { func NewUCIWithExecutor(exec Executor, customFWFile string) *UCI {
wireless := &UCIWirelessConf{} wireless := &UCIWirelessConf{}
return &UCI{exec, customFWFile, wireless} firewall := &UCIFirewall{}
return &UCI{exec, customFWFile, wireless, firewall}
} }
// uciRun, private method to run the UCI command // uciRun, private method to run the UCI command
@ -103,6 +106,13 @@ func (u *UCI) LoadWirelessConf() {
u.Wireless.Load() u.Wireless.Load()
} }
// LoadFirewallConf scan UCI configration and load saved firewall rules
func (u *UCI) LoadFirewallConf() error {
fmt.Println("DEBUG ICI ICI ICI ICI !!!")
u.Firewall = NewUCIFirewall(u)
return u.Firewall.Load()
}
// GetWifiIface returns the wifi Interface by Index // GetWifiIface returns the wifi Interface by Index
func (u *UCI) GetWifiIface(idx int) *UCIWirelessInterface { func (u *UCI) GetWifiIface(idx int) *UCIWirelessInterface {
ifaces := u.Wireless.Interfaces ifaces := u.Wireless.Interfaces

119
uci_firewall.go Normal file
View File

@ -0,0 +1,119 @@
package owrt
import (
"fmt"
"regexp"
"strconv"
"strings"
)
// UCIFirewall is the description of the OpenWRT Firewall rules (all types)
type UCIFirewall struct {
UCI *UCI
Rules map[int]*UCIFirewallRule
Redirects map[int]*UCIFirewallRedirect
Customs map[int]*UCIFirewallCustomRule
}
// NewUCIFirewall builds a new UCIFirewall instance
func NewUCIFirewall(uci *UCI) *UCIFirewall {
return &UCIFirewall{
UCI: uci,
Rules: map[int]*UCIFirewallRule{},
Redirects: map[int]*UCIFirewallRedirect{},
Customs: map[int]*UCIFirewallCustomRule{},
}
}
// loadRules loads existing firewall rules
func (f *UCIFirewall) loadRules() error {
var rules = map[int]*UCIFirewallRule{}
var lines []string
matches := map[string]*regexp.Regexp{
"Name": regexp.MustCompile(`@rule\[[0-9]*\].name=`),
"Src": regexp.MustCompile(`@rule\[[0-9]*\].src=`),
"Target": regexp.MustCompile(`@rule\[[0-9]*\].target=`),
"Proto": regexp.MustCompile(`@rule\[[0-9]*\].porto=`),
"DestPort": regexp.MustCompile(`@rule\[[0-9]*\].dest_port=`),
}
if f.UCI == nil {
return fmt.Errorf("No UCI Client present ... this could not append")
}
firewallRes := f.UCI.uciRun("uci", "show", "firewall")
if firewallRes.ReturnCode == 0 {
lines = grep(firewallRes.Stdout, "firewall.@rule")
// lines = strings.Split(firewallRes.Stdout, "\n")
} else {
return fmt.Errorf("%d - %s %s %s",
firewallRes.ReturnCode,
firewallRes.Command,
firewallRes.Stdout,
firewallRes.Stdout)
}
for _, li := range lines {
var idx int
var sIdx string
if li != "" {
sIdx = strings.Split(li, "[")[1]
sIdx = strings.Split(sIdx, "]")[0]
if s, err := strconv.ParseInt(sIdx, 10, 32); err == nil {
idx = int(s)
}
}
if _, exists := rules[idx]; !exists {
rules[idx] = NewUCIFirewallRule(f.UCI)
rules[idx].Index = idx
}
for key, expr := range matches {
if expr.MatchString(li) {
value := strings.Split(li, "=")[1]
value = strings.Trim(value, "'")
if key == "Name" {
fmt.Printf("Setting Name %s for rule #%d\n", value, idx)
rules[idx].Name = value
}
if key == "Src" {
rules[idx].Src = value
}
if key == "Proto" {
rules[idx].Proto = value
}
if key == "DestPort" {
rules[idx].DestPort = value
}
if key == "Target" {
rules[idx].Target = value
}
}
}
}
f.Rules = rules
return nil
}
func (f *UCIFirewall) loadRedirects() error {
return nil
}
func (f *UCIFirewall) loadCustoms() error {
return nil
}
// Load run uci show firewall and creates an nice UCIFirewall Object
func (f *UCIFirewall) Load() error {
if r := f.loadRules(); r != nil {
return r
}
if r := f.loadRedirects(); r != nil {
return r
}
return f.loadCustoms()
}

23
uci_firewall_test.go Normal file
View File

@ -0,0 +1,23 @@
package owrt
import (
"io/ioutil"
"testing"
)
func TestUCILoadFirewall(t *testing.T) {
config, err := ioutil.ReadFile("./testdata/uci_show_firewall.txt")
if err != nil {
t.Fatal(err)
}
exec := createMockExecutor(string(config), "", 0)
uci := NewUCIWithExecutor(exec, "")
if err := uci.LoadFirewallConf(); err != nil {
t.Fatalf("%s", err.Error())
}
//if uci.Firewall.Rules[13].Name != "MyTestRule" {
// t.Fatalf("Something is wrong with the last firewall rule")
//}
}