diff --git a/configtypes.go b/configtypes.go index ecc8eed..dc94baf 100644 --- a/configtypes.go +++ b/configtypes.go @@ -5,6 +5,8 @@ import ( "io/ioutil" "net" "os" + + "github.com/go-playground/validator/v10" ) // see https://github.com/WireGuard/wgctrl-go/blob/master/wgtypes/types.go for definitions @@ -16,32 +18,32 @@ type PeerConfig struct { // Description of what the host is and/or does Description string `validate:"required,gte=1,lte=255"` // Internal VPN IP address. Added to AllowedIPs in server config as a /32 - IP net.IP `validate:"required,ip` + IP net.IP `validate:"required` PublicKey JSONKey `validate:"required,len=44"` PrivateKey JSONKey `json:"-"` // omitted from config! PresharedKey JSONKey `validate:"required,len=44"` // TODO ExternalIP support (Endpoint) //ExternalIP net.UDPAddr `validate:"required,udp4_addr"` // TODO support routing additional networks (AllowedIPs) - Networks []JSONIPNet `validate:"dive,cidr"` + Networks []JSONIPNet } type DsnetConfig struct { // domain to append to hostnames. Relies on separate DNS server for // resolution. Informational only. - ExternalIP net.IP `validate:"required,cidr"` + ExternalIP net.IP `validate:"required"` ListenPort int `validate:"gte=1024,lte=65535"` Domain string `validate:"required,gte=1,lte=255"` // IP network from which to allocate automatic sequential addresses // Network is chosen randomly when not specified Network JSONIPNet `validate:"required"` - IP net.IP `validate:"required,cidr"` - DNS net.IP `validate:"required,cidr"` + IP net.IP `validate:"required"` + DNS net.IP `validate:"required"` // TODO Default subnets to route via VPN - ReportFile string `validate:"required"` - PrivateKey JSONKey `validate:"required,len=44"` - PresharedKey JSONKey `validate:"required,len=44"` - Peers []PeerConfig + ReportFile string `validate:"required"` + PrivateKey JSONKey `validate:"required,len=44"` + PresharedKey JSONKey `validate:"required,len=44"` + Peers []PeerConfig `validate:"dive"` } func MustLoadDsnetConfig() *DsnetConfig { @@ -58,6 +60,10 @@ func MustLoadDsnetConfig() *DsnetConfig { conf := DsnetConfig{} err = json.Unmarshal(raw, &conf) check(err) + + err = validator.New().Struct(conf) + check(err) + return &conf } diff --git a/go.mod b/go.mod index 7afb76d..f05e9a6 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/naggie/dsnet go 1.13 require ( + github.com/go-playground/validator/v10 v10.2.0 github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 golang.org/x/tools v0.0.0-20200302155637-b1e4e04173e0 // indirect golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200205215550-e35592f146e4 diff --git a/go.sum b/go.sum index d95896a..7284bcf 100644 --- a/go.sum +++ b/go.sum @@ -1,15 +1,29 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator v9.31.0+incompatible h1:UA72EPEogEnq76ehGdEDp4Mit+3FDh548oRqwVgNsHA= +github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw= github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/mdlayher/genetlink v1.0.0/go.mod h1:0rJ0h4itni50A86M2kHcgS85ttZazNt7a8H2a2cw0Gc= github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA= github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M= github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcKp9uZHgmY= github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 h1:RlZweED6sbSArvlE924+mUcZuXKLBHA35U7LN621Bws= github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -46,3 +60,5 @@ golang.zx2c4.com/wireguard v0.0.20200121 h1:vcswa5Q6f+sylDfjqyrVNNrjsFUUbPsgAQTB golang.zx2c4.com/wireguard v0.0.20200121/go.mod h1:P2HsVp8SKwZEufsnezXZA4GRX/T49/HlU7DGuelXsU4= golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200205215550-e35592f146e4 h1:KTi97NIQGgSMaN0v/oxniJV0MEzfzmrDUOAWxombQVc= golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200205215550-e35592f146e4/go.mod h1:UdS9frhv65KTfwxME1xE8+rHYoFpbm36gOud1GhBe9c= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/reporttypes.go b/reporttypes.go index 5c0295d..c3625b6 100644 --- a/reporttypes.go +++ b/reporttypes.go @@ -8,29 +8,26 @@ import ( type DsnetReport struct { // domain to append to hostnames. Relies on separate DNS server for // resolution. Informational only. - ExternalIP net.IP `validate:"required,cidr"` - ListenPort int `validate:"gte=1024,lte=65535"` - Domain string `validate:"required,gte=1,lte=255"` + ExternalIP net.IP + ListenPort int + Domain string // IP network from which to allocate automatic sequential addresses // Network is chosen randomly when not specified - Network JSONIPNet `validate:"required"` - IP net.IP `validate:"required,cidr"` - DNS net.IP `validate:"required,cidr"` + Network JSONIPNet + IP net.IP + DNS net.IP Peers []PeerReport } type PeerReport struct { // Used to update DNS - Hostname string `validate:"required,gte=1,lte=255"` + Hostname string // username of person running this host/router - Owner string `validate:"required,gte=1,lte=255"` + Owner string // Description of what the host is and/or does - Description string `validate:"required,gte=1,lte=255"` + Description string // Internal VPN IP address. Added to AllowedIPs in server config as a /32 - IP net.IP `validate:"required,ip` - PublicKey JSONKey `validate:"required,len=44"` - PrivateKey JSONKey `json:"-"` // omitted from config! - PresharedKey JSONKey `validate:"required,len=44"` + IP net.IP // whether last heartbeat/rxdata was received (50% margin) Online bool // if no data for x days, consider revoking access @@ -38,7 +35,7 @@ type PeerReport struct { // TODO ExternalIP support (Endpoint) //ExternalIP net.UDPAddr `validate:"required,udp4_addr"` // TODO support routing additional networks (AllowedIPs) - Networks []JSONIPNet `validate:"dive,cidr"` + Networks []JSONIPNet LastHandshakeTime time.Time ReceiveBytes int64 TransmitBytes int64