remove go version

This commit is contained in:
Samuel Lorch 2023-10-28 18:49:08 +02:00
parent 797c6403ba
commit 39abbf9a60
142 changed files with 0 additions and 5617 deletions

39
go.mod
View file

@ -1,39 +0,0 @@
module nfsense.net/nfsense
go 1.21
toolchain go1.21.2
require (
github.com/coreos/go-systemd/v22 v22.5.0
github.com/godbus/dbus/v5 v5.1.0
github.com/google/uuid v1.3.1
github.com/pterm/pterm v0.12.69
github.com/r3labs/diff/v3 v3.0.1
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
github.com/tredoe/osutil v1.3.6
go4.org/netipx v0.0.0-20230824141953-6213f710f925
golang.org/x/exp v0.0.0-20231006140011-7918f672742d
nhooyr.io/websocket v1.8.7
)
require (
atomicgo.dev/cursor v0.2.0 // indirect
atomicgo.dev/keyboard v0.2.9 // indirect
atomicgo.dev/schedule v0.1.0 // indirect
github.com/containerd/console v1.0.3 // indirect
github.com/go-playground/validator/v10 v10.15.5 // indirect
github.com/gookit/color v1.5.4 // indirect
github.com/klauspost/compress v1.17.0 // indirect
github.com/lithammer/fuzzysearch v1.1.8 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/vmihailenco/msgpack/v5 v5.4.0 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/net v0.16.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/term v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
)

202
go.sum
View file

@ -1,202 +0,0 @@
atomicgo.dev/assert v0.0.2 h1:FiKeMiZSgRrZsPo9qn/7vmr7mCsh5SZyXY4YGYiYwrg=
atomicgo.dev/assert v0.0.2/go.mod h1:ut4NcI3QDdJtlmAxQULOmA13Gz6e2DWbSAS8RUOmNYQ=
atomicgo.dev/cursor v0.2.0 h1:H6XN5alUJ52FZZUkI7AlJbUc1aW38GWZalpYRPpoPOw=
atomicgo.dev/cursor v0.2.0/go.mod h1:Lr4ZJB3U7DfPPOkbH7/6TOtJ4vFGHlgj1nc+n900IpU=
atomicgo.dev/keyboard v0.2.9 h1:tOsIid3nlPLZ3lwgG8KZMp/SFmr7P0ssEN5JUsm78K8=
atomicgo.dev/keyboard v0.2.9/go.mod h1:BC4w9g00XkxH/f1HXhW2sXmJFOCWbKn9xrOunSFtExQ=
atomicgo.dev/schedule v0.1.0 h1:nTthAbhZS5YZmgYbb2+DH8uQIZcTlIrd4eYr3UQxEjs=
atomicgo.dev/schedule v0.1.0/go.mod h1:xeUa3oAkiuHYh8bKiQBRojqAMq3PXXbJujjb0hw8pEU=
github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs=
github.com/MarvinJWendt/testza v0.2.1/go.mod h1:God7bhG8n6uQxwdScay+gjm9/LnO4D3kkcZX4hv9Rp8=
github.com/MarvinJWendt/testza v0.2.8/go.mod h1:nwIcjmr0Zz+Rcwfh3/4UhBp7ePKVhuBExvZqnKYWlII=
github.com/MarvinJWendt/testza v0.2.10/go.mod h1:pd+VWsoGUiFtq+hRKSU1Bktnn+DMCSrDrXDpX2bG66k=
github.com/MarvinJWendt/testza v0.2.12/go.mod h1:JOIegYyV7rX+7VZ9r77L/eH6CfJHHzXjB69adAhzZkI=
github.com/MarvinJWendt/testza v0.3.0/go.mod h1:eFcL4I0idjtIx8P9C6KkAuLgATNKpX4/2oUqKc6bF2c=
github.com/MarvinJWendt/testza v0.4.2/go.mod h1:mSdhXiKH8sg/gQehJ63bINcCKp7RtYewEjXsvsVUPbE=
github.com/MarvinJWendt/testza v0.5.2 h1:53KDo64C1z/h/d/stCYCPY69bt/OSwjq5KpFNwi+zB4=
github.com/MarvinJWendt/testza v0.5.2/go.mod h1:xu53QFE5sCdjtMCKk8YMQ2MnymimEctc4n3EjyIYvEY=
github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk=
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24=
github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ=
github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo=
github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0=
github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU=
github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4=
github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pterm/pterm v0.12.27/go.mod h1:PhQ89w4i95rhgE+xedAoqous6K9X+r6aSOI2eFF7DZI=
github.com/pterm/pterm v0.12.29/go.mod h1:WI3qxgvoQFFGKGjGnJR849gU0TsEOvKn5Q8LlY1U7lg=
github.com/pterm/pterm v0.12.30/go.mod h1:MOqLIyMOgmTDz9yorcYbcw+HsgoZo3BQfg2wtl3HEFE=
github.com/pterm/pterm v0.12.31/go.mod h1:32ZAWZVXD7ZfG0s8qqHXePte42kdz8ECtRyEejaWgXU=
github.com/pterm/pterm v0.12.33/go.mod h1:x+h2uL+n7CP/rel9+bImHD5lF3nM9vJj80k9ybiiTTE=
github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5bUw8T8=
github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s=
github.com/pterm/pterm v0.12.69 h1:fBCKnB8dSLAl8FlYRQAWYGp2WTI/Xm/tKJ21Hyo9USw=
github.com/pterm/pterm v0.12.69/go.mod h1:wl06ko9MHnqxz4oDV++IORDpjCzw6+mfrvf0MPj6fdk=
github.com/r3labs/diff/v3 v3.0.1 h1:CBKqf3XmNRHXKmdU7mZP1w7TV0pDyVCis1AUHtA4Xtg=
github.com/r3labs/diff/v3 v3.0.1/go.mod h1:f1S9bourRbiM66NskseyUdo0fTmEE0qKrikYJX63dgo=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tredoe/fileutil v1.0.5/go.mod h1:HFzzpvg+3Q8LgmZgo1mVF5epHc/CVkWKEb3hja+/1Zo=
github.com/tredoe/goutil v1.0.0/go.mod h1:Qhf75QLcNEChimbl4wb8nROzw9PCFCPYTEUmTnoszXY=
github.com/tredoe/osutil v1.3.6 h1:VrweDEuUWOYU/lskw8HqsGRt4fOdbdp6td5vjgVzrj8=
github.com/tredoe/osutil v1.3.6/go.mod h1:panccMiyCdP8g45yxJ7DcxdMTZfPqHGGceuou2MNvHo=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
github.com/vmihailenco/msgpack/v5 v5.4.0 h1:hRM0digJwyR6vll33NNAwCFguy5JuBD6jxDmQP3l608=
github.com/vmihailenco/msgpack/v5 v5.4.0/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go4.org/netipx v0.0.0-20230824141953-6213f710f925 h1:eeQDDVKFkx0g4Hyy8pHgmZaK0EqB4SD6rvKbUdN3ziQ=
go4.org/netipx v0.0.0-20230824141953-6213f710f925/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.16.0 h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos=
golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g=
nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=

View file

@ -1,7 +0,0 @@
package config
import "nfsense.net/nfsense/internal/config"
type Config struct {
ConfigManager *config.ConfigManager
}

View file

@ -1,40 +0,0 @@
package config
import (
"context"
"fmt"
"github.com/r3labs/diff/v3"
)
type GetPendingStatusResult struct {
Changed bool
}
func (c *Config) GetPendingStatus(ctx context.Context, params struct{}) (GetPendingStatusResult, error) {
return GetPendingStatusResult{
Changed: c.ConfigManager.AreChangesPending(),
}, nil
}
type GetPendingChangelogResult struct {
Changelog diff.Changelog
}
func (c *Config) GetPendingChangelog(ctx context.Context, params struct{}) (GetPendingChangelogResult, error) {
log, err := c.ConfigManager.GetPendingChangelog()
if err != nil {
return GetPendingChangelogResult{}, fmt.Errorf("Get Pending changelog %w", err)
}
return GetPendingChangelogResult{
Changelog: log,
}, nil
}
func (c *Config) ApplyPendingChanges(ctx context.Context, params struct{}) (struct{}, error) {
return struct{}{}, c.ConfigManager.ApplyPendingChanges()
}
func (c *Config) DiscardPendingChanges(ctx context.Context, params struct{}) (struct{}, error) {
return struct{}{}, c.ConfigManager.DiscardPendingConfig()
}

View file

@ -1,104 +0,0 @@
package firewall
import (
"context"
"fmt"
"nfsense.net/nfsense/internal/definitions/firewall"
)
type GetDestinationNATRuleParameters struct {
ID uint
}
type GetDestinationNATRuleResult struct {
firewall.DestinationNATRule
}
func (f *Firewall) GetDestinationNATRule(ctx context.Context, params GetDestinationNATRuleParameters) (GetDestinationNATRuleResult, error) {
if int(params.ID) >= len(f.ConfigManager.GetPendingConfig().Firewall.DestinationNATRules) {
return GetDestinationNATRuleResult{}, fmt.Errorf("DestinationNATRule does not Exist")
}
return GetDestinationNATRuleResult{
DestinationNATRule: f.ConfigManager.GetPendingConfig().Firewall.DestinationNATRules[params.ID],
}, nil
}
type GetDestinationNATRulesResult struct {
DestinationNATRules []firewall.DestinationNATRule `json:"destination_nat_rules"`
}
func (f *Firewall) GetDestinationNATRules(ctx context.Context, params struct{}) (GetDestinationNATRulesResult, error) {
return GetDestinationNATRulesResult{
DestinationNATRules: f.ConfigManager.GetPendingConfig().Firewall.DestinationNATRules,
}, nil
}
type CreateDestinationNATRuleParameters struct {
firewall.DestinationNATRule
}
func (f *Firewall) CreateDestinationNATRule(ctx context.Context, params CreateDestinationNATRuleParameters) (struct{}, error) {
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Firewall.DestinationNATRules = append(conf.Firewall.DestinationNATRules, params.DestinationNATRule)
return struct{}{}, t.Commit()
}
type UpdateDestinationNATRuleParameters struct {
Index uint64 `json:"index"`
firewall.DestinationNATRule
}
func (f *Firewall) UpdateDestinationNATRule(ctx context.Context, params UpdateDestinationNATRuleParameters) (struct{}, error) {
if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Firewall.DestinationNATRules) {
return struct{}{}, fmt.Errorf("DestinationNATRule does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Firewall.DestinationNATRules[params.Index] = params.DestinationNATRule
return struct{}{}, t.Commit()
}
type MoveDestinationNATRuleParameters struct {
Index uint64 `json:"index"`
ToIndex uint64 `json:"to_index"`
}
func (f *Firewall) MoveDestinationNATRule(ctx context.Context, params MoveDestinationNATRuleParameters) (struct{}, error) {
if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Firewall.DestinationNATRules) {
return struct{}{}, fmt.Errorf("DestinationNATRule does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
rule := conf.Firewall.DestinationNATRules[params.Index]
sliceWithoutRule := append(conf.Firewall.DestinationNATRules[:params.Index], conf.Firewall.DestinationNATRules[params.Index+1:]...)
newSlice := make([]firewall.DestinationNATRule, params.ToIndex+1)
copy(newSlice, sliceWithoutRule[:params.ToIndex])
newSlice[params.ToIndex] = rule
conf.Firewall.DestinationNATRules = append(newSlice, sliceWithoutRule[params.ToIndex:]...)
return struct{}{}, t.Commit()
}
type DeleteDestinationNATRuleParameters struct {
Index uint64 `json:"index"`
}
func (f *Firewall) DeleteDestinationNATRule(ctx context.Context, params DeleteDestinationNATRuleParameters) (struct{}, error) {
if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Firewall.DestinationNATRules) {
return struct{}{}, fmt.Errorf("DestinationNATRule does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Firewall.DestinationNATRules = append(conf.Firewall.DestinationNATRules[:params.Index], conf.Firewall.DestinationNATRules[params.Index+1:]...)
return struct{}{}, t.Commit()
}

View file

@ -1,9 +0,0 @@
package firewall
import (
"nfsense.net/nfsense/internal/config"
)
type Firewall struct {
ConfigManager *config.ConfigManager
}

View file

@ -1,104 +0,0 @@
package firewall
import (
"context"
"fmt"
"nfsense.net/nfsense/internal/definitions/firewall"
)
type GetForwardRuleParameters struct {
ID uint
}
type GetForwardRuleResult struct {
firewall.ForwardRule
}
func (f *Firewall) GetForwardRule(ctx context.Context, params GetForwardRuleParameters) (GetForwardRuleResult, error) {
if int(params.ID) >= len(f.ConfigManager.GetPendingConfig().Firewall.ForwardRules) {
return GetForwardRuleResult{}, fmt.Errorf("ForwardRule does not Exist")
}
return GetForwardRuleResult{
ForwardRule: f.ConfigManager.GetPendingConfig().Firewall.ForwardRules[params.ID],
}, nil
}
type GetForwardRulesResult struct {
ForwardRules []firewall.ForwardRule `json:"forward_rules"`
}
func (f *Firewall) GetForwardRules(ctx context.Context, params struct{}) (GetForwardRulesResult, error) {
return GetForwardRulesResult{
ForwardRules: f.ConfigManager.GetPendingConfig().Firewall.ForwardRules,
}, nil
}
type CreateForwardRuleParameters struct {
firewall.ForwardRule
}
func (f *Firewall) CreateForwardRule(ctx context.Context, params CreateForwardRuleParameters) (struct{}, error) {
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Firewall.ForwardRules = append(conf.Firewall.ForwardRules, params.ForwardRule)
return struct{}{}, t.Commit()
}
type UpdateForwardRuleParameters struct {
Index uint64 `json:"index"`
firewall.ForwardRule
}
func (f *Firewall) UpdateForwardRule(ctx context.Context, params UpdateForwardRuleParameters) (struct{}, error) {
if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Firewall.ForwardRules) {
return struct{}{}, fmt.Errorf("ForwardRule does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Firewall.ForwardRules[params.Index] = params.ForwardRule
return struct{}{}, t.Commit()
}
type MoveForwardRuleParameters struct {
Index uint64 `json:"index"`
ToIndex uint64 `json:"to_index"`
}
func (f *Firewall) MoveForwardRule(ctx context.Context, params MoveForwardRuleParameters) (struct{}, error) {
if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Firewall.ForwardRules) {
return struct{}{}, fmt.Errorf("ForwardRule does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
rule := conf.Firewall.ForwardRules[params.Index]
sliceWithoutRule := append(conf.Firewall.ForwardRules[:params.Index], conf.Firewall.ForwardRules[params.Index+1:]...)
newSlice := make([]firewall.ForwardRule, params.ToIndex+1)
copy(newSlice, sliceWithoutRule[:params.ToIndex])
newSlice[params.ToIndex] = rule
conf.Firewall.ForwardRules = append(newSlice, sliceWithoutRule[params.ToIndex:]...)
return struct{}{}, t.Commit()
}
type DeleteForwardRuleParameters struct {
Index uint64 `json:"index"`
}
func (f *Firewall) DeleteForwardRule(ctx context.Context, params DeleteForwardRuleParameters) (struct{}, error) {
if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Firewall.ForwardRules) {
return struct{}{}, fmt.Errorf("ForwardRule does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Firewall.ForwardRules = append(conf.Firewall.ForwardRules[:params.Index], conf.Firewall.ForwardRules[params.Index+1:]...)
return struct{}{}, t.Commit()
}

View file

@ -1,104 +0,0 @@
package firewall
import (
"context"
"fmt"
"nfsense.net/nfsense/internal/definitions/firewall"
)
type GetSourceNATRuleParameters struct {
ID uint
}
type GetSourceNATRuleResult struct {
firewall.SourceNATRule
}
func (f *Firewall) GetSourceNATRule(ctx context.Context, params GetSourceNATRuleParameters) (GetSourceNATRuleResult, error) {
if int(params.ID) >= len(f.ConfigManager.GetPendingConfig().Firewall.SourceNATRules) {
return GetSourceNATRuleResult{}, fmt.Errorf("SourceNATRule does not Exist")
}
return GetSourceNATRuleResult{
SourceNATRule: f.ConfigManager.GetPendingConfig().Firewall.SourceNATRules[params.ID],
}, nil
}
type GetSourceNATRulesResult struct {
SourceNATRules []firewall.SourceNATRule `json:"source_nat_rules"`
}
func (f *Firewall) GetSourceNATRules(ctx context.Context, params struct{}) (GetSourceNATRulesResult, error) {
return GetSourceNATRulesResult{
SourceNATRules: f.ConfigManager.GetPendingConfig().Firewall.SourceNATRules,
}, nil
}
type CreateSourceNATRuleParameters struct {
firewall.SourceNATRule
}
func (f *Firewall) CreateSourceNATRule(ctx context.Context, params CreateSourceNATRuleParameters) (struct{}, error) {
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Firewall.SourceNATRules = append(conf.Firewall.SourceNATRules, params.SourceNATRule)
return struct{}{}, t.Commit()
}
type UpdateSourceNATRuleParameters struct {
Index uint64 `json:"index"`
firewall.SourceNATRule
}
func (f *Firewall) UpdateSourceNATRule(ctx context.Context, params UpdateSourceNATRuleParameters) (struct{}, error) {
if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Firewall.SourceNATRules) {
return struct{}{}, fmt.Errorf("SourceNATRule does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Firewall.SourceNATRules[params.Index] = params.SourceNATRule
return struct{}{}, t.Commit()
}
type MoveSourceNATRuleParameters struct {
Index uint64 `json:"index"`
ToIndex uint64 `json:"to_index"`
}
func (f *Firewall) MoveSourceNATRule(ctx context.Context, params MoveSourceNATRuleParameters) (struct{}, error) {
if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Firewall.SourceNATRules) {
return struct{}{}, fmt.Errorf("SourceNATRule does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
rule := conf.Firewall.SourceNATRules[params.Index]
sliceWithoutRule := append(conf.Firewall.SourceNATRules[:params.Index], conf.Firewall.SourceNATRules[params.Index+1:]...)
newSlice := make([]firewall.SourceNATRule, params.ToIndex+1)
copy(newSlice, sliceWithoutRule[:params.ToIndex])
newSlice[params.ToIndex] = rule
conf.Firewall.SourceNATRules = append(newSlice, sliceWithoutRule[params.ToIndex:]...)
return struct{}{}, t.Commit()
}
type DeleteSourceNATRuleParameters struct {
Index uint64 `json:"index"`
}
func (f *Firewall) DeleteSourceNATRule(ctx context.Context, params DeleteSourceNATRuleParameters) (struct{}, error) {
if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Firewall.SourceNATRules) {
return struct{}{}, fmt.Errorf("SourceNATRule does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Firewall.SourceNATRules = append(conf.Firewall.SourceNATRules[:params.Index], conf.Firewall.SourceNATRules[params.Index+1:]...)
return struct{}{}, t.Commit()
}

View file

@ -1,107 +0,0 @@
package network
import (
"context"
"fmt"
"nfsense.net/nfsense/internal/definitions/network"
"nfsense.net/nfsense/internal/networkd/dbus"
)
type GetLinksResult struct {
Links []dbus.Link
}
func (f *Network) GetLinks(ctx context.Context, params struct{}) (GetLinksResult, error) {
links, err := dbus.GetLinks(*f.DbusConn)
if err != nil {
return GetLinksResult{}, fmt.Errorf("Getting Links: %w", err)
}
return GetLinksResult{
Links: links,
}, nil
}
type GetInterfaceParameters struct {
ID string
}
type GetInterfaceResult struct {
Name string `json:"name"`
network.Interface
}
func (f *Network) GetInterface(ctx context.Context, params GetInterfaceParameters) (GetInterfaceResult, error) {
_, ok := f.ConfigManager.GetPendingConfig().Network.Interfaces[params.ID]
if !ok {
return GetInterfaceResult{}, fmt.Errorf("Interface does not Exist")
}
return GetInterfaceResult{
Name: params.ID,
Interface: f.ConfigManager.GetPendingConfig().Network.Interfaces[params.ID],
}, nil
}
type GetInterfacesResult struct {
Interfaces map[string]network.Interface
}
func (f *Network) GetInterfaces(ctx context.Context, params struct{}) (GetInterfacesResult, error) {
return GetInterfacesResult{
Interfaces: f.ConfigManager.GetPendingConfig().Network.Interfaces,
}, nil
}
type CreateInterfaceParameters struct {
Name string `json:"name"`
network.Interface
}
func (f *Network) CreateInterface(ctx context.Context, params CreateInterfaceParameters) (struct{}, error) {
_, ok := f.ConfigManager.GetPendingConfig().Network.Interfaces[params.Name]
if ok {
return struct{}{}, fmt.Errorf("Interface already Exists")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Network.Interfaces[params.Name] = params.Interface
return struct{}{}, t.Commit()
}
type UpdateInterfaceParameters struct {
Name string
network.Interface
}
func (f *Network) UpdateInterface(ctx context.Context, params UpdateInterfaceParameters) (struct{}, error) {
_, ok := f.ConfigManager.GetPendingConfig().Network.Interfaces[params.Name]
if !ok {
return struct{}{}, fmt.Errorf("Interface does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Network.Interfaces[params.Name] = params.Interface
return struct{}{}, t.Commit()
}
type DeleteInterfaceParameters struct {
Name string
}
func (f *Network) DeleteInterface(ctx context.Context, params DeleteInterfaceParameters) (struct{}, error) {
_, ok := f.ConfigManager.GetPendingConfig().Network.Interfaces[params.Name]
if !ok {
return struct{}{}, fmt.Errorf("Interface does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
delete(conf.Network.Interfaces, params.Name)
return struct{}{}, t.Commit()
}

View file

@ -1,11 +0,0 @@
package network
import (
"github.com/godbus/dbus/v5"
"nfsense.net/nfsense/internal/config"
)
type Network struct {
ConfigManager *config.ConfigManager
DbusConn *dbus.Conn
}

View file

@ -1,77 +0,0 @@
package network
import (
"context"
"fmt"
"nfsense.net/nfsense/internal/definitions/network"
)
type GetStaticRouteParameters struct {
ID uint
}
type GetStaticRouteResult struct {
network.StaticRoute
}
func (f *Network) GetStaticRoute(ctx context.Context, params GetStaticRouteParameters) (GetStaticRouteResult, error) {
if int(params.ID) >= len(f.ConfigManager.GetPendingConfig().Network.StaticRoutes) {
return GetStaticRouteResult{}, fmt.Errorf("StaticRoute does not Exist")
}
return GetStaticRouteResult{
StaticRoute: f.ConfigManager.GetPendingConfig().Network.StaticRoutes[params.ID],
}, nil
}
type GetStaticRoutesResult struct {
StaticRoutes []network.StaticRoute
}
func (f *Network) GetStaticRoutes(ctx context.Context, params struct{}) (GetStaticRoutesResult, error) {
return GetStaticRoutesResult{
StaticRoutes: f.ConfigManager.GetPendingConfig().Network.StaticRoutes,
}, nil
}
func (f *Network) CreateStaticRoute(ctx context.Context, params network.StaticRoute) (struct{}, error) {
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Network.StaticRoutes = append(conf.Network.StaticRoutes, params)
return struct{}{}, t.Commit()
}
type UpdateStaticRouteParameters struct {
Index uint
network.StaticRoute
}
func (f *Network) UpdateStaticRoute(ctx context.Context, params UpdateStaticRouteParameters) (struct{}, error) {
if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Firewall.DestinationNATRules) {
return struct{}{}, fmt.Errorf("StaticRoute does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Network.StaticRoutes = append(conf.Network.StaticRoutes, params.StaticRoute)
return struct{}{}, t.Commit()
}
type DeleteStaticRouteParameters struct {
Index uint
}
func (f *Network) DeleteStaticRoute(ctx context.Context, params DeleteStaticRouteParameters) (struct{}, error) {
if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Firewall.DestinationNATRules) {
return struct{}{}, fmt.Errorf("StaticRoute does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Network.StaticRoutes = append(conf.Network.StaticRoutes[:params.Index], conf.Network.StaticRoutes[params.Index+1:]...)
return struct{}{}, t.Commit()
}

View file

@ -1,92 +0,0 @@
package object
import (
"context"
"fmt"
"nfsense.net/nfsense/internal/definitions/object"
)
type GetAddressParameters struct {
ID string
}
type GetAddressResult struct {
Name string `json:"name"`
object.Address
}
func (f *Object) GetAddress(ctx context.Context, params GetAddressParameters) (GetAddressResult, error) {
_, ok := f.ConfigManager.GetPendingConfig().Object.Addresses[params.ID]
if !ok {
return GetAddressResult{}, fmt.Errorf("Address does not Exist")
}
return GetAddressResult{
Name: params.ID,
Address: f.ConfigManager.GetPendingConfig().Object.Addresses[params.ID],
}, nil
}
type GetAddressesResult struct {
Addresses map[string]object.Address
}
func (f *Object) GetAddresses(ctx context.Context, params struct{}) (GetAddressesResult, error) {
return GetAddressesResult{
Addresses: f.ConfigManager.GetPendingConfig().Object.Addresses,
}, nil
}
type CreateAddressParameters struct {
Name string
object.Address
}
func (f *Object) CreateAddress(ctx context.Context, params CreateAddressParameters) (struct{}, error) {
_, ok := f.ConfigManager.GetPendingConfig().Object.Addresses[params.Name]
if ok {
return struct{}{}, fmt.Errorf("Address already Exists")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Object.Addresses[params.Name] = params.Address
return struct{}{}, t.Commit()
}
type UpdateAddressParameters struct {
Name string
object.Address
}
func (f *Object) UpdateAddress(ctx context.Context, params UpdateAddressParameters) (struct{}, error) {
_, ok := f.ConfigManager.GetPendingConfig().Object.Addresses[params.Name]
if !ok {
return struct{}{}, fmt.Errorf("Address does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Object.Addresses[params.Name] = params.Address
return struct{}{}, t.Commit()
}
type DeleteAddressParameters struct {
Name string
}
func (f *Object) DeleteAddress(ctx context.Context, params DeleteAddressParameters) (struct{}, error) {
_, ok := f.ConfigManager.GetPendingConfig().Object.Addresses[params.Name]
if !ok {
return struct{}{}, fmt.Errorf("Address does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
delete(conf.Object.Addresses, params.Name)
return struct{}{}, t.Commit()
}

View file

@ -1,7 +0,0 @@
package object
import "nfsense.net/nfsense/internal/config"
type Object struct {
ConfigManager *config.ConfigManager
}

View file

@ -1,92 +0,0 @@
package object
import (
"context"
"fmt"
"nfsense.net/nfsense/internal/definitions/object"
)
type GetServiceParameters struct {
ID string
}
type GetServiceResult struct {
Name string `json:"name"`
object.Service
}
func (f *Object) GetService(ctx context.Context, params GetServiceParameters) (GetServiceResult, error) {
_, ok := f.ConfigManager.GetPendingConfig().Object.Services[params.ID]
if !ok {
return GetServiceResult{}, fmt.Errorf("Service does not Exist")
}
return GetServiceResult{
Name: params.ID,
Service: f.ConfigManager.GetPendingConfig().Object.Services[params.ID],
}, nil
}
type GetServicesResult struct {
Services map[string]object.Service
}
func (f *Object) GetServices(ctx context.Context, params struct{}) (GetServicesResult, error) {
return GetServicesResult{
Services: f.ConfigManager.GetPendingConfig().Object.Services,
}, nil
}
type CreateServiceParameters struct {
Name string
object.Service
}
func (f *Object) CreateService(ctx context.Context, params CreateServiceParameters) (struct{}, error) {
_, ok := f.ConfigManager.GetPendingConfig().Object.Services[params.Name]
if ok {
return struct{}{}, fmt.Errorf("Service already Exists")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Object.Services[params.Name] = params.Service
return struct{}{}, t.Commit()
}
type UpdateServiceParameters struct {
Name string
object.Service
}
func (f *Object) UpdateService(ctx context.Context, params UpdateServiceParameters) (struct{}, error) {
_, ok := f.ConfigManager.GetPendingConfig().Object.Services[params.Name]
if !ok {
return struct{}{}, fmt.Errorf("Service does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Object.Services[params.Name] = params.Service
return struct{}{}, t.Commit()
}
type DeleteServiceParameters struct {
Name string
}
func (f *Object) DeleteService(ctx context.Context, params DeleteServiceParameters) (struct{}, error) {
_, ok := f.ConfigManager.GetPendingConfig().Object.Services[params.Name]
if !ok {
return struct{}{}, fmt.Errorf("Interface does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
delete(conf.Object.Services, params.Name)
return struct{}{}, t.Commit()
}

View file

@ -1,81 +0,0 @@
package service
import (
"context"
"fmt"
"nfsense.net/nfsense/internal/definitions/service"
)
type GetDHCPv4ServerParameters struct {
ID uint
}
type GetDHCPv4ServerResult struct {
service.DHCPv4Server
}
func (f *Service) GetDHCPv4Server(ctx context.Context, params GetDHCPv4ServerParameters) (GetDHCPv4ServerResult, error) {
if int(params.ID) >= len(f.ConfigManager.GetPendingConfig().Service.DHCPv4Servers) {
return GetDHCPv4ServerResult{}, fmt.Errorf("DHCPv4Server does not Exist")
}
return GetDHCPv4ServerResult{
DHCPv4Server: f.ConfigManager.GetPendingConfig().Service.DHCPv4Servers[params.ID],
}, nil
}
type GetDHCPv4ServersResult struct {
DHCPv4Servers []service.DHCPv4Server `json:"dhcp_v4_servers"`
}
func (f *Service) GetDHCPv4Servers(ctx context.Context, params struct{}) (GetDHCPv4ServersResult, error) {
return GetDHCPv4ServersResult{
DHCPv4Servers: f.ConfigManager.GetPendingConfig().Service.DHCPv4Servers,
}, nil
}
type CreateDHCPv4ServerParameters struct {
service.DHCPv4Server
}
func (f *Service) CreateDHCPv4Server(ctx context.Context, params CreateDHCPv4ServerParameters) (struct{}, error) {
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Service.DHCPv4Servers = append(conf.Service.DHCPv4Servers, params.DHCPv4Server)
return struct{}{}, t.Commit()
}
type UpdateDHCPv4ServerParameters struct {
Index uint64 `json:"index"`
DHCPv4Server service.DHCPv4Server `json:"dhcp_v4_server"`
}
func (f *Service) UpdateDHCPv4Server(ctx context.Context, params UpdateDHCPv4ServerParameters) (struct{}, error) {
if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Service.DHCPv4Servers) {
return struct{}{}, fmt.Errorf("DHCPv4Server does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Service.DHCPv4Servers[params.Index] = params.DHCPv4Server
return struct{}{}, t.Commit()
}
type DeleteDHCPv4ServerParameters struct {
Index uint64 `json:"index"`
}
func (f *Service) DeleteDHCPv4Server(ctx context.Context, params DeleteDHCPv4ServerParameters) (struct{}, error) {
if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Service.DHCPv4Servers) {
return struct{}{}, fmt.Errorf("DHCPv4Server does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Service.DHCPv4Servers = append(conf.Service.DHCPv4Servers[:params.Index], conf.Service.DHCPv4Servers[params.Index+1:]...)
return struct{}{}, t.Commit()
}

View file

@ -1,81 +0,0 @@
package service
import (
"context"
"fmt"
"nfsense.net/nfsense/internal/definitions/service"
)
type GetDHCPv6ServerParameters struct {
ID uint
}
type GetDHCPv6ServerResult struct {
service.DHCPv6Server
}
func (f *Service) GetDHCPv6Server(ctx context.Context, params GetDHCPv6ServerParameters) (GetDHCPv6ServerResult, error) {
if int(params.ID) >= len(f.ConfigManager.GetPendingConfig().Service.DHCPv6Servers) {
return GetDHCPv6ServerResult{}, fmt.Errorf("DHCPv6Server does not Exist")
}
return GetDHCPv6ServerResult{
DHCPv6Server: f.ConfigManager.GetPendingConfig().Service.DHCPv6Servers[params.ID],
}, nil
}
type GetDHCPv6ServersResult struct {
DHCPv6Servers []service.DHCPv6Server `json:"dhcp_v6_servers"`
}
func (f *Service) GetDHCPv6Servers(ctx context.Context, params struct{}) (GetDHCPv6ServersResult, error) {
return GetDHCPv6ServersResult{
DHCPv6Servers: f.ConfigManager.GetPendingConfig().Service.DHCPv6Servers,
}, nil
}
type CreateDHCPv6ServerParameters struct {
service.DHCPv6Server
}
func (f *Service) CreateDHCPv6Server(ctx context.Context, params CreateDHCPv6ServerParameters) (struct{}, error) {
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Service.DHCPv6Servers = append(conf.Service.DHCPv6Servers, params.DHCPv6Server)
return struct{}{}, t.Commit()
}
type UpdateDHCPv6ServerParameters struct {
Index uint64 `json:"index"`
DHCPv6Server service.DHCPv6Server `json:"dhcp_v6_server"`
}
func (f *Service) UpdateDHCPv6Server(ctx context.Context, params UpdateDHCPv6ServerParameters) (struct{}, error) {
if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Service.DHCPv6Servers) {
return struct{}{}, fmt.Errorf("DHCPv6Server does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Service.DHCPv6Servers[params.Index] = params.DHCPv6Server
return struct{}{}, t.Commit()
}
type DeleteDHCPv6ServerParameters struct {
Index uint64 `json:"index"`
}
func (f *Service) DeleteDHCPv6Server(ctx context.Context, params DeleteDHCPv6ServerParameters) (struct{}, error) {
if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Service.DHCPv6Servers) {
return struct{}{}, fmt.Errorf("DHCPv6Server does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Service.DHCPv6Servers = append(conf.Service.DHCPv6Servers[:params.Index], conf.Service.DHCPv6Servers[params.Index+1:]...)
return struct{}{}, t.Commit()
}

View file

@ -1,81 +0,0 @@
package service
import (
"context"
"fmt"
"nfsense.net/nfsense/internal/definitions/service"
)
type GetDNSServerParameters struct {
ID uint
}
type GetDNSServerResult struct {
service.DNSServer
}
func (f *Service) GetDNSServer(ctx context.Context, params GetDNSServerParameters) (GetDNSServerResult, error) {
if int(params.ID) >= len(f.ConfigManager.GetPendingConfig().Service.DNSServers) {
return GetDNSServerResult{}, fmt.Errorf("DNSServer does not Exist")
}
return GetDNSServerResult{
DNSServer: f.ConfigManager.GetPendingConfig().Service.DNSServers[params.ID],
}, nil
}
type GetDNSServersResult struct {
DNSServers []service.DNSServer `json:"dns_servers"`
}
func (f *Service) GetDNSServers(ctx context.Context, params struct{}) (GetDNSServersResult, error) {
return GetDNSServersResult{
DNSServers: f.ConfigManager.GetPendingConfig().Service.DNSServers,
}, nil
}
type CreateDNSServerParameters struct {
service.DNSServer
}
func (f *Service) CreateDNSServer(ctx context.Context, params CreateDNSServerParameters) (struct{}, error) {
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Service.DNSServers = append(conf.Service.DNSServers, params.DNSServer)
return struct{}{}, t.Commit()
}
type UpdateDNSServerParameters struct {
Index uint64 `json:"index"`
DNSServer service.DNSServer `json:"dns_server"`
}
func (f *Service) UpdateDNSServer(ctx context.Context, params UpdateDNSServerParameters) (struct{}, error) {
if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Service.DNSServers) {
return struct{}{}, fmt.Errorf("DNSServer does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Service.DNSServers[params.Index] = params.DNSServer
return struct{}{}, t.Commit()
}
type DeleteDNSServerParameters struct {
Index uint64 `json:"index"`
}
func (f *Service) DeleteDNSServer(ctx context.Context, params DeleteDNSServerParameters) (struct{}, error) {
if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Service.DNSServers) {
return struct{}{}, fmt.Errorf("DNSServer does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Service.DNSServers = append(conf.Service.DNSServers[:params.Index], conf.Service.DNSServers[params.Index+1:]...)
return struct{}{}, t.Commit()
}

View file

@ -1,81 +0,0 @@
package service
import (
"context"
"fmt"
"nfsense.net/nfsense/internal/definitions/service"
)
type GetNTPServerParameters struct {
ID uint
}
type GetNTPServerResult struct {
service.NTPServer
}
func (f *Service) GetNTPServer(ctx context.Context, params GetNTPServerParameters) (GetNTPServerResult, error) {
if int(params.ID) >= len(f.ConfigManager.GetPendingConfig().Service.NTPServers) {
return GetNTPServerResult{}, fmt.Errorf("NTPServer does not Exist")
}
return GetNTPServerResult{
NTPServer: f.ConfigManager.GetPendingConfig().Service.NTPServers[params.ID],
}, nil
}
type GetNTPServersResult struct {
NTPServers []service.NTPServer `json:"ntp_servers"`
}
func (f *Service) GetNTPServers(ctx context.Context, params struct{}) (GetNTPServersResult, error) {
return GetNTPServersResult{
NTPServers: f.ConfigManager.GetPendingConfig().Service.NTPServers,
}, nil
}
type CreateNTPServerParameters struct {
service.NTPServer
}
func (f *Service) CreateNTPServer(ctx context.Context, params CreateNTPServerParameters) (struct{}, error) {
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Service.NTPServers = append(conf.Service.NTPServers, params.NTPServer)
return struct{}{}, t.Commit()
}
type UpdateNTPServerParameters struct {
Index uint64 `json:"index"`
NTPServer service.NTPServer `json:"ntp_server"`
}
func (f *Service) UpdateNTPServer(ctx context.Context, params UpdateNTPServerParameters) (struct{}, error) {
if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Service.NTPServers) {
return struct{}{}, fmt.Errorf("NTPServer does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Service.NTPServers[params.Index] = params.NTPServer
return struct{}{}, t.Commit()
}
type DeleteNTPServerParameters struct {
Index uint64 `json:"index"`
}
func (f *Service) DeleteNTPServer(ctx context.Context, params DeleteNTPServerParameters) (struct{}, error) {
if int(params.Index) >= len(f.ConfigManager.GetPendingConfig().Service.NTPServers) {
return struct{}{}, fmt.Errorf("NTPServer does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.Service.NTPServers = append(conf.Service.NTPServers[:params.Index], conf.Service.NTPServers[params.Index+1:]...)
return struct{}{}, t.Commit()
}

View file

@ -1,11 +0,0 @@
package service
import (
"github.com/godbus/dbus/v5"
"nfsense.net/nfsense/internal/config"
)
type Service struct {
ConfigManager *config.ConfigManager
DbusConn *dbus.Conn
}

View file

@ -1,9 +0,0 @@
package system
import (
"nfsense.net/nfsense/internal/config"
)
type System struct {
ConfigManager *config.ConfigManager
}

View file

@ -1,139 +0,0 @@
package system
import (
"context"
"fmt"
"nfsense.net/nfsense/internal/auth"
"nfsense.net/nfsense/internal/definitions/system"
)
type User struct {
Comment string `json:"comment"`
}
type GetUserParameters struct {
ID string
}
type GetUserResult struct {
Name string `json:"name"`
User
}
func (f *System) GetUser(ctx context.Context, params GetUserParameters) (GetUserResult, error) {
_, ok := f.ConfigManager.GetPendingConfig().System.Users[params.ID]
if !ok {
return GetUserResult{}, fmt.Errorf("User does not Exist")
}
return GetUserResult{
Name: params.ID,
User: User{
Comment: f.ConfigManager.GetPendingConfig().System.Users[params.ID].Comment,
},
}, nil
}
type GetUsersResult struct {
Users map[string]User
}
func (f *System) GetUsers(ctx context.Context, params struct{}) (GetUsersResult, error) {
users := map[string]User{}
for n, u := range f.ConfigManager.GetPendingConfig().System.Users {
users[n] = User{Comment: u.Comment}
}
return GetUsersResult{
Users: users,
}, nil
}
type CreateUserParameters struct {
Name string `json:"name"`
Password string `json:"password"`
User
}
func (f *System) CreateUser(ctx context.Context, params CreateUserParameters) (struct{}, error) {
_, ok := f.ConfigManager.GetPendingConfig().System.Users[params.Name]
if ok {
return struct{}{}, fmt.Errorf("User already Exists")
}
if params.Name == "" {
return struct{}{}, fmt.Errorf("Name Cannot be empty")
}
if params.Password == "" {
return struct{}{}, fmt.Errorf("Password Cannot be empty")
}
hash, salt, err := auth.GenerateHash(params.Password)
if err != nil {
return struct{}{}, fmt.Errorf("Generate Hash: %w", err)
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.System.Users[params.Name] = system.User{
Hash: hash,
Salt: salt,
Comment: params.User.Comment,
}
return struct{}{}, t.Commit()
}
type UpdateUserParameters struct {
Name string `json:"name"`
Password string `json:"password"`
User
}
func (f *System) UpdateUser(ctx context.Context, params UpdateUserParameters) (struct{}, error) {
_, ok := f.ConfigManager.GetPendingConfig().System.Users[params.Name]
if !ok {
return struct{}{}, fmt.Errorf("User does not Exist")
}
if params.Name == "" {
return struct{}{}, fmt.Errorf("Name Cannot be empty")
}
user := f.ConfigManager.GetPendingConfig().System.Users[params.Name]
if params.Password != "" {
hash, salt, err := auth.GenerateHash(params.Password)
if err != nil {
return struct{}{}, fmt.Errorf("Generate Hash: %w", err)
}
user.Hash = hash
user.Salt = salt
}
user.Comment = params.User.Comment
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.System.Users[params.Name] = user
return struct{}{}, t.Commit()
}
type DeleteUserParameters struct {
Name string
}
func (f *System) DeleteUser(ctx context.Context, params DeleteUserParameters) (struct{}, error) {
_, ok := f.ConfigManager.GetPendingConfig().System.Users[params.Name]
if !ok {
return struct{}{}, fmt.Errorf("User does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
delete(conf.System.Users, params.Name)
return struct{}{}, t.Commit()
}

View file

@ -1,92 +0,0 @@
package vpn
import (
"context"
"fmt"
"nfsense.net/nfsense/internal/definitions/vpn"
)
type GetWireguardInterfaceParameters struct {
ID string
}
type GetWireguardInterfaceResult struct {
Name string `json:"name"`
vpn.WireguardInterface
}
func (f *VPN) GetWireguardInterface(ctx context.Context, params GetWireguardInterfaceParameters) (GetWireguardInterfaceResult, error) {
_, ok := f.ConfigManager.GetPendingConfig().VPN.Wireguard.Interfaces[params.ID]
if !ok {
return GetWireguardInterfaceResult{}, fmt.Errorf("WireguardInterface does not Exist")
}
return GetWireguardInterfaceResult{
Name: params.ID,
WireguardInterface: f.ConfigManager.GetPendingConfig().VPN.Wireguard.Interfaces[params.ID],
}, nil
}
type GetWireguardInterfacesResult struct {
Interfaces map[string]vpn.WireguardInterface
}
func (f *VPN) GetWireguardInterfaces(ctx context.Context, params struct{}) (GetWireguardInterfacesResult, error) {
return GetWireguardInterfacesResult{
Interfaces: f.ConfigManager.GetPendingConfig().VPN.Wireguard.Interfaces,
}, nil
}
type CreateWireguardInterfaceParameters struct {
Name string `json:"name"`
vpn.WireguardInterface
}
func (f *VPN) CreateWireguardInterface(ctx context.Context, params CreateWireguardInterfaceParameters) (struct{}, error) {
_, ok := f.ConfigManager.GetPendingConfig().VPN.Wireguard.Interfaces[params.Name]
if ok {
return struct{}{}, fmt.Errorf("WireguardInterface already Exists")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.VPN.Wireguard.Interfaces[params.Name] = params.WireguardInterface
return struct{}{}, t.Commit()
}
type UpdateWireguardInterfaceParameters struct {
Name string
vpn.WireguardInterface
}
func (f *VPN) UpdateWireguardInterface(ctx context.Context, params UpdateWireguardInterfaceParameters) (struct{}, error) {
_, ok := f.ConfigManager.GetPendingConfig().VPN.Wireguard.Interfaces[params.Name]
if !ok {
return struct{}{}, fmt.Errorf("WireguardInterface does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.VPN.Wireguard.Interfaces[params.Name] = params.WireguardInterface
return struct{}{}, t.Commit()
}
type DeleteWireguardInterfaceParameters struct {
Name string
}
func (f *VPN) DeleteWireguardInterface(ctx context.Context, params DeleteWireguardInterfaceParameters) (struct{}, error) {
_, ok := f.ConfigManager.GetPendingConfig().VPN.Wireguard.Interfaces[params.Name]
if !ok {
return struct{}{}, fmt.Errorf("WireguardInterface does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
delete(conf.VPN.Wireguard.Interfaces, params.Name)
return struct{}{}, t.Commit()
}

View file

@ -1,92 +0,0 @@
package vpn
import (
"context"
"fmt"
"nfsense.net/nfsense/internal/definitions/vpn"
)
type GetWireguardPeerParameters struct {
ID string
}
type GetWireguardPeerResult struct {
Name string `json:"name"`
vpn.WireguardPeer
}
func (f *VPN) GetWireguardPeer(ctx context.Context, params GetWireguardPeerParameters) (GetWireguardPeerResult, error) {
_, ok := f.ConfigManager.GetPendingConfig().VPN.Wireguard.Peers[params.ID]
if !ok {
return GetWireguardPeerResult{}, fmt.Errorf("WireguardPeer does not Exist")
}
return GetWireguardPeerResult{
Name: params.ID,
WireguardPeer: f.ConfigManager.GetPendingConfig().VPN.Wireguard.Peers[params.ID],
}, nil
}
type GetWireguardPeersResult struct {
WireguardPeers map[string]vpn.WireguardPeer
}
func (f *VPN) GetWireguardPeers(ctx context.Context, params struct{}) (GetWireguardPeersResult, error) {
return GetWireguardPeersResult{
WireguardPeers: f.ConfigManager.GetPendingConfig().VPN.Wireguard.Peers,
}, nil
}
type CreateWireguardPeerParameters struct {
Name string `json:"name"`
vpn.WireguardPeer
}
func (f *VPN) CreateWireguardPeer(ctx context.Context, params CreateWireguardPeerParameters) (struct{}, error) {
_, ok := f.ConfigManager.GetPendingConfig().VPN.Wireguard.Peers[params.Name]
if ok {
return struct{}{}, fmt.Errorf("WireguardPeer already Exists")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.VPN.Wireguard.Peers[params.Name] = params.WireguardPeer
return struct{}{}, t.Commit()
}
type UpdateWireguardPeerParameters struct {
Name string
vpn.WireguardPeer
}
func (f *VPN) UpdateWireguardPeer(ctx context.Context, params UpdateWireguardPeerParameters) (struct{}, error) {
_, ok := f.ConfigManager.GetPendingConfig().VPN.Wireguard.Peers[params.Name]
if !ok {
return struct{}{}, fmt.Errorf("WireguardPeer does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
conf.VPN.Wireguard.Peers[params.Name] = params.WireguardPeer
return struct{}{}, t.Commit()
}
type DeleteWireguardPeerParameters struct {
Name string
}
func (f *VPN) DeleteWireguardPeer(ctx context.Context, params DeleteWireguardPeerParameters) (struct{}, error) {
_, ok := f.ConfigManager.GetPendingConfig().VPN.Wireguard.Peers[params.Name]
if !ok {
return struct{}{}, fmt.Errorf("WireguardPeer does not Exist")
}
t, conf := f.ConfigManager.StartTransaction()
defer t.Discard()
delete(conf.VPN.Wireguard.Peers, params.Name)
return struct{}{}, t.Commit()
}

View file

@ -1,29 +0,0 @@
package vpn
import (
"bytes"
"context"
"fmt"
"os/exec"
"golang.org/x/exp/slog"
)
type GetWireguardStatusResult struct {
Status string
}
func (f *VPN) GetWireguardStatus(ctx context.Context, params struct{}) (GetWireguardStatusResult, error) {
cmd := exec.Command("wg")
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
return GetWireguardStatusResult{}, fmt.Errorf("restarting networkd: %w", err)
}
slog.Info("wg output", "out", out.String())
return GetWireguardStatusResult{
Status: out.String(),
}, nil
}

View file

@ -1,11 +0,0 @@
package vpn
import (
"github.com/godbus/dbus/v5"
"nfsense.net/nfsense/internal/config"
)
type VPN struct {
ConfigManager *config.ConfigManager
DbusConn *dbus.Conn
}

View file

@ -1,47 +0,0 @@
package auth
import (
"fmt"
"math/rand"
"time"
"github.com/tredoe/osutil/user/crypt/sha512_crypt"
"nfsense.net/nfsense/internal/definitions/config"
)
func AuthenticateUser(conf config.Config, username, password string) error {
user, ok := conf.System.Users[username]
if !ok {
return fmt.Errorf("User not found")
}
// Using sha512 to be compatible with /etc/shadow
c := sha512_crypt.New()
hash, err := c.Generate([]byte(password), []byte(user.Salt))
if err != nil {
return fmt.Errorf("Hashing Password: %w", err)
}
if hash == user.Hash {
return nil
}
return fmt.Errorf("Invalid Password")
}
func GenerateHash(password string) (string, string, error) {
const charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
seededRand := rand.New(rand.NewSource(time.Now().UnixNano()))
s := make([]byte, 8)
for i := range s {
s[i] = charset[seededRand.Intn(len(charset))]
}
salt := []byte(fmt.Sprintf("$6$%s", s))
c := sha512_crypt.New()
hash, err := c.Generate([]byte(password), []byte(salt))
if err != nil {
return "", "", fmt.Errorf("Hashing Password: %w", err)
}
return hash, string(salt), nil
}

View file

@ -1,37 +0,0 @@
package chrony
import (
"context"
"fmt"
systemctl "github.com/coreos/go-systemd/v22/dbus"
"nfsense.net/nfsense/internal/definitions/config"
"nfsense.net/nfsense/internal/util"
)
const chronyConfigFile = "/etc/chrony.conf"
func ApplyNTPConfiguration(currentConfig config.Config, pendingConfig config.Config) error {
conf, err := GenerateChronyConfiguration(pendingConfig)
if err != nil {
return fmt.Errorf("Generating Chrony Configuration: %w", err)
}
err = util.OverwriteFile(chronyConfigFile, conf)
if err != nil {
return fmt.Errorf("Writing Chrony Configuration: %w", err)
}
conn, err := systemctl.NewSystemConnectionContext(context.Background())
if err != nil {
return fmt.Errorf("Opening Dbus Connection: %w", err)
}
_, err = conn.ReloadOrRestartUnitContext(context.Background(), "chronyd.service", "replace", nil)
if err != nil {
return fmt.Errorf("restarting chronyd.service: %w", err)
}
return nil
}

View file

@ -1,17 +0,0 @@
package chrony
import (
"bytes"
"fmt"
"nfsense.net/nfsense/internal/definitions/config"
)
func GenerateChronyConfiguration(conf config.Config) (string, error) {
buf := new(bytes.Buffer)
err := templates.ExecuteTemplate(buf, "config.tmpl", conf)
if err != nil {
return "", fmt.Errorf("executing server.tmpl template: %w", err)
}
return buf.String(), nil
}

View file

@ -1,26 +0,0 @@
package chrony
import (
"embed"
"text/template"
"nfsense.net/nfsense/internal/definitions/config"
)
//go:embed template
var templateFS embed.FS
var templates *template.Template
func init() {
var err error
templates, err = template.New("").Funcs(template.FuncMap{
"getInterfaceNetworkAddressCIDR": getInterfaceNetworkAddressCIDR,
}).ParseFS(templateFS, "template/*.tmpl")
if err != nil {
panic(err)
}
}
func getInterfaceNetworkAddressCIDR(conf config.Config, name string) string {
return conf.Network.Interfaces[name].Address.Masked().String()
}

View file

@ -1,13 +0,0 @@
pool pool.ntp.org iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
keyfile /etc/chrony.keys
ntsdumpdir /var/lib/chrony
leapsectz right/UTC
logdir /var/log/chrony
# Allowed Networks
{{- range $i, $server := .Service.NTPServers }}
allow {{ getInterfaceNetworkAddressCIDR $ $server.Interface }}
{{- end }}

View file

@ -1,52 +0,0 @@
package config
import (
"fmt"
"os"
"golang.org/x/exp/slog"
"nfsense.net/nfsense/internal/definitions/config"
)
// ApplyPendingChanges Takes all pending Changes and Tries to Apply them using the Registered Apply Functions.
// In Case of error it Attempts to Revert to the Current Config
func (m *ConfigManager) ApplyPendingChanges() error {
slog.Info("Applying Pending Changes...")
for _, fn := range m.applyFunctions {
err := fn(*m.currentConfig, *m.pendingConfig)
if err != nil {
slog.Error("Applying Pending Changes", "err", err)
err2 := revertToCurrent(m)
if err2 != nil {
slog.Error("Reverting Error", "err", err2)
return fmt.Errorf("Apply Error %w; Reverting Error %w", err, err2)
}
return err
}
}
m.currentConfig = m.pendingConfig.Clone()
err := m.saveConfig(m.currentConfigFilePath, m.pendingConfig)
if err != nil {
return fmt.Errorf("Save Current Config: %w", err)
}
err = os.Remove(m.pendingConfigFilePath)
if err != nil {
return fmt.Errorf("Delete Pending Config: %w", err)
}
return nil
}
func revertToCurrent(m *ConfigManager) error {
for _, fn := range m.applyFunctions {
err := fn(*m.pendingConfig, *m.currentConfig)
if err != nil {
return err
}
}
return nil
}
func (m *ConfigManager) RegisterApplyFunction(fn func(currentConfig config.Config, pendingConfig config.Config) error) {
m.applyFunctions = append(m.applyFunctions, fn)
}

View file

@ -1,56 +0,0 @@
package config
import (
"fmt"
"nfsense.net/nfsense/internal/definitions/config"
"nfsense.net/nfsense/internal/definitions/firewall"
"nfsense.net/nfsense/internal/definitions/network"
"nfsense.net/nfsense/internal/definitions/object"
"nfsense.net/nfsense/internal/definitions/service"
"nfsense.net/nfsense/internal/definitions/system"
"nfsense.net/nfsense/internal/definitions/vpn"
)
func (m *ConfigManager) LoadDefaultConfig() error {
conf := config.Config{
ConfigVersion: 1,
Firewall: firewall.Firewall{
ForwardRules: []firewall.ForwardRule{},
DestinationNATRules: []firewall.DestinationNATRule{},
SourceNATRules: []firewall.SourceNATRule{},
},
Object: object.Object{
Addresses: map[string]object.Address{},
Services: map[string]object.Service{},
},
Network: network.Network{
Interfaces: map[string]network.Interface{},
StaticRoutes: []network.StaticRoute{},
},
Service: service.Service{
DHCPv4Servers: []service.DHCPv4Server{},
DHCPv6Servers: []service.DHCPv6Server{},
DNSServers: []service.DNSServer{},
NTPServers: []service.NTPServer{},
},
VPN: vpn.VPN{
Wireguard: vpn.Wireguard{
Interfaces: map[string]vpn.WireguardInterface{},
Peers: map[string]vpn.WireguardPeer{},
},
},
System: system.System{
Users: map[string]system.User{},
},
}
err := config.ValidateConfig(&conf)
if err != nil {
return fmt.Errorf("validating Config: %w", err)
}
m.currentConfig = &conf
m.pendingConfig = &conf
return nil
}

View file

@ -1,11 +0,0 @@
package config
import "github.com/r3labs/diff/v3"
func (m *ConfigManager) AreChangesPending() bool {
return diff.Changed(m.currentConfig, m.pendingConfig)
}
func (m *ConfigManager) GetPendingChangelog() (diff.Changelog, error) {
return diff.Diff(m.currentConfig, m.pendingConfig, diff.SliceOrdering(true))
}

View file

@ -1,16 +0,0 @@
package config
import (
"errors"
"os"
)
func (m *ConfigManager) DiscardPendingConfig() error {
m.pendingConfig = m.currentConfig.Clone()
err := os.Remove(m.pendingConfigFilePath)
if !errors.Is(err, os.ErrNotExist) {
return err
}
return nil
}

View file

@ -1,13 +0,0 @@
package config
import (
"nfsense.net/nfsense/internal/definitions/config"
)
func (m *ConfigManager) GetCurrentConfig() config.Config {
return *m.currentConfig.Clone()
}
func (m *ConfigManager) GetPendingConfig() config.Config {
return *m.pendingConfig.Clone()
}

View file

@ -1,57 +0,0 @@
package config
import (
"encoding/json"
"fmt"
"os"
"nfsense.net/nfsense/internal/definitions/config"
)
func (m *ConfigManager) LoadCurrentConfigFromDisk() error {
var conf config.Config
configFile, err := os.Open(m.currentConfigFilePath)
if err != nil {
return fmt.Errorf("opening Config File %w", err)
}
defer configFile.Close()
jsonParser := json.NewDecoder(configFile)
jsonParser.DisallowUnknownFields()
err = jsonParser.Decode(&conf)
if err != nil {
return fmt.Errorf("decoding Config File %w", err)
}
err = config.ValidateConfig(&conf)
if err != nil {
return fmt.Errorf("validating Config: %w", err)
}
m.currentConfig = &conf
return nil
}
func (m *ConfigManager) LoadPendingConfigFromDisk() error {
var conf config.Config
configFile, err := os.Open(m.pendingConfigFilePath)
if err != nil {
return fmt.Errorf("opening Config File %w", err)
}
defer configFile.Close()
jsonParser := json.NewDecoder(configFile)
jsonParser.DisallowUnknownFields()
err = jsonParser.Decode(&conf)
if err != nil {
return fmt.Errorf("decoding Config File %w", err)
}
err = config.ValidateConfig(&conf)
if err != nil {
return fmt.Errorf("validating Config: %w", err)
}
m.pendingConfig = &conf
return nil
}

View file

@ -1,29 +0,0 @@
package config
import (
"sync"
"nfsense.net/nfsense/internal/definitions/config"
)
type ConfigManager struct {
currentConfigFilePath string
pendingConfigFilePath string
currentConfig *config.Config
pendingConfig *config.Config
transactionMutex sync.Mutex
applyFunctions []func(currentConfig config.Config, pendingConfig config.Config) error
}
func CreateConfigManager() *ConfigManager {
manager := ConfigManager{
currentConfigFilePath: "config.json",
pendingConfigFilePath: "pending.json",
currentConfig: &config.Config{},
pendingConfig: &config.Config{},
}
return &manager
}

View file

@ -1,35 +0,0 @@
package config
import (
"encoding/json"
"fmt"
"os"
"nfsense.net/nfsense/internal/definitions/config"
)
func (m *ConfigManager) saveConfig(path string, conf *config.Config) error {
data, err := json.MarshalIndent(conf, "", " ")
if err != nil {
return fmt.Errorf("Marshal Config: %w", err)
}
err = os.WriteFile(path, data, 0644)
if err != nil {
return fmt.Errorf("Write Config: %w", err)
}
return nil
}
func (m *ConfigManager) SaveWithoutApplying() error {
m.currentConfig = m.pendingConfig.Clone()
err := m.saveConfig(m.currentConfigFilePath, m.pendingConfig)
if err != nil {
return fmt.Errorf("Save Current Config: %w", err)
}
os.Remove(m.pendingConfigFilePath)
return nil
}

View file

@ -1,62 +0,0 @@
package config
import (
"fmt"
"sync"
"nfsense.net/nfsense/internal/definitions/config"
)
type ConfigTransaction struct {
finished bool
mutex sync.Mutex
configManager *ConfigManager
changes *config.Config
}
func (m *ConfigManager) StartTransaction() (*ConfigTransaction, *config.Config) {
m.transactionMutex.Lock()
confCopy := m.pendingConfig.Clone()
return &ConfigTransaction{
configManager: m,
changes: confCopy,
}, confCopy
}
func (t *ConfigTransaction) Commit() error {
t.mutex.Lock()
defer t.mutex.Unlock()
if t.finished {
return fmt.Errorf("transaction already finished")
}
t.finished = true
defer t.configManager.transactionMutex.Unlock()
err := config.ValidateConfig(t.changes)
if err != nil {
return fmt.Errorf("validating Config before Apply: %w", err)
}
err = t.configManager.saveConfig(t.configManager.pendingConfigFilePath, t.changes)
if err != nil {
return fmt.Errorf("Save Current Config: %w", err)
}
t.configManager.pendingConfig = t.changes.Clone()
return nil
}
// Discard Discards the Transaction.
// Is a noop if The Transaction Already Finished due to a Commit() or another Discard()
func (t *ConfigTransaction) Discard() {
t.mutex.Lock()
defer t.mutex.Unlock()
if !t.finished {
t.finished = true
t.configManager.transactionMutex.Unlock()
}
}

View file

@ -1,30 +0,0 @@
package common
import (
"encoding/json"
"net"
)
type HardwareAddress struct {
net.HardwareAddr
}
// MarshalJSON for IPCIDR
func (i HardwareAddress) MarshalJSON() ([]byte, error) {
return json.Marshal(i.String())
}
// UnmarshalJSON for IPCIDR
func (i *HardwareAddress) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
mac, err := net.ParseMAC(s)
if err != nil {
return err
}
i.HardwareAddr = mac
return nil
}

View file

@ -1,32 +0,0 @@
package common
import (
"encoding/json"
"net"
)
// IPCIDR is IP Address with the mask in CIDR format
type IPCIDR struct {
net.IPNet
}
// MarshalJSON for IPCIDR
func (i IPCIDR) MarshalJSON() ([]byte, error) {
return json.Marshal(i.String())
}
// UnmarshalJSON for IPCIDR
func (i *IPCIDR) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
ip, ipnet, err := net.ParseCIDR(s)
if err != nil {
return err
}
i.IPNet = *ipnet
i.IPNet.IP = ip
return nil
}

View file

@ -1,30 +0,0 @@
package common
import (
"encoding/json"
"net"
)
type IPNet struct {
net.IPNet
}
// MarshalJSON for IPNet
func (i IPNet) MarshalJSON() ([]byte, error) {
return json.Marshal(i.String())
}
// UnmarshalJSON for IPNet
func (i *IPNet) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
_, ipnet, err := net.ParseCIDR(s)
if err != nil {
return err
}
i.IPNet = *ipnet
return nil
}

View file

@ -1,34 +0,0 @@
package common
import (
"encoding/json"
"errors"
"time"
)
type Duration struct {
time.Duration
}
// MarshalJSON for IPNet
func (i Duration) MarshalJSON() ([]byte, error) {
return json.Marshal(int(i.Seconds()))
}
// UnmarshalJSON for IPNet
func (i *Duration) UnmarshalJSON(b []byte) error {
var v interface{}
if err := json.Unmarshal(b, &v); err != nil {
return err
}
switch value := v.(type) {
case float64:
i.Duration = time.Second * time.Duration(value)
return nil
case int:
i.Duration = time.Second * time.Duration(value)
return nil
default:
return errors.New("invalid duration")
}
}

View file

@ -1,42 +0,0 @@
package config
import (
"encoding/json"
"fmt"
"nfsense.net/nfsense/internal/definitions/firewall"
"nfsense.net/nfsense/internal/definitions/network"
"nfsense.net/nfsense/internal/definitions/object"
"nfsense.net/nfsense/internal/definitions/service"
"nfsense.net/nfsense/internal/definitions/system"
"nfsense.net/nfsense/internal/definitions/vpn"
"nfsense.net/nfsense/internal/validation"
)
type Config struct {
ConfigVersion uint64 `json:"config_version"`
Firewall firewall.Firewall `json:"firewall"`
Object object.Object `json:"object"`
Network network.Network `json:"network"`
Service service.Service `json:"service"`
VPN vpn.VPN `json:"vpn"`
System system.System `json:"system"`
}
// Clone TODO find a better way to deep copy
func (c *Config) Clone() *Config {
data, err := json.Marshal(c)
if err != nil {
panic(fmt.Errorf("Marshal Error: %w", err))
}
var clone Config
err = json.Unmarshal(data, &clone)
if err != nil {
panic(fmt.Errorf("Unmarshal Error: %w", err))
}
return &clone
}
func ValidateConfig(conf *Config) error {
return validation.ValidateConfig(*conf)
}

View file

@ -1,7 +0,0 @@
package firewall
type DestinationNATRule struct {
Rule
Address *string `json:"address,omitempty"`
Service *string `json:"service,omitempty"`
}

View file

@ -1,7 +0,0 @@
package firewall
type Firewall struct {
ForwardRules []ForwardRule `json:"forward_rules"`
DestinationNATRules []DestinationNATRule `json:"destination_nat_rules"`
SourceNATRules []SourceNATRule `json:"source_nat_rules"`
}

View file

@ -1,7 +0,0 @@
package firewall
type Match struct {
Services []string `json:"services,omitempty"`
SourceAddresses []string `json:"source_addresses,omitempty"`
DestinationAddresses []string `json:"destination_addresses,omitempty"`
}

View file

@ -1,49 +0,0 @@
package firewall
import "encoding/json"
type Rule struct {
Name string `json:"name"`
Match Match `json:"match"`
Comment string `json:"comment,omitempty"`
Counter bool `json:"counter,omitempty"`
}
type ForwardRule struct {
Rule
Verdict Verdict `json:"verdict"`
}
type Verdict int
const (
Accept Verdict = iota
Drop
Continue
)
func (t Verdict) String() string {
return [...]string{"accept", "drop", "continue"}[t]
}
func (t *Verdict) FromString(input string) Verdict {
return map[string]Verdict{
"accept": Accept,
"drop": Drop,
"continue": Continue,
}[input]
}
func (t Verdict) MarshalJSON() ([]byte, error) {
return json.Marshal(t.String())
}
func (t *Verdict) UnmarshalJSON(b []byte) error {
var s string
err := json.Unmarshal(b, &s)
if err != nil {
return err
}
*t = t.FromString(s)
return nil
}

View file

@ -1,42 +0,0 @@
package firewall
import "encoding/json"
type SourceNATRule struct {
Rule
Type SnatType `json:"type"`
Address *string `json:"address,omitempty"`
Service *string `json:"service,omitempty"`
}
type SnatType int
const (
Snat SnatType = iota
Masquerade
)
func (t SnatType) String() string {
return [...]string{"snat", "masquerade"}[t]
}
func (t *SnatType) FromString(input string) SnatType {
return map[string]SnatType{
"snat": Snat,
"masquerade": Masquerade,
}[input]
}
func (t SnatType) MarshalJSON() ([]byte, error) {
return json.Marshal(t.String())
}
func (t *SnatType) UnmarshalJSON(b []byte) error {
var s string
err := json.Unmarshal(b, &s)
if err != nil {
return err
}
*t = t.FromString(s)
return nil
}

View file

@ -1,90 +0,0 @@
package network
import (
"encoding/json"
"net/netip"
)
type Interface struct {
Alias string `json:"alias,omitempty"`
Type InterfaceType `json:"type"`
AddressingMode InterfaceAddressingMode `json:"addressing_mode"`
Address *netip.Prefix `json:"address,omitempty"`
HardwareDevice *string `json:"hardware_device,omitempty"`
// TODO fix Validator for int pointers with min=0,max=4094
VlanID *uint `json:"vlan_id,omitempty"`
VlanParent *string `json:"vlan_parent,omitempty"`
BondMembers *[]string `json:"bond_members,omitempty"`
BridgeMembers *[]string `json:"bridge_members,omitempty"`
Comment string `json:"comment,omitempty"`
}
type InterfaceType int
const (
Hardware InterfaceType = iota
Vlan
Bond
Bridge
)
func (t InterfaceType) String() string {
return [...]string{"hardware", "vlan", "bond", "bridge"}[t]
}
func (t *InterfaceType) FromString(input string) InterfaceType {
return map[string]InterfaceType{
"hardware": Hardware,
"vlan": Vlan,
"bond": Bond,
"bridge": Bridge,
}[input]
}
func (t InterfaceType) MarshalJSON() ([]byte, error) {
return json.Marshal(t.String())
}
func (t *InterfaceType) UnmarshalJSON(b []byte) error {
var s string
err := json.Unmarshal(b, &s)
if err != nil {
return err
}
*t = t.FromString(s)
return nil
}
type InterfaceAddressingMode int
const (
None InterfaceAddressingMode = iota
Static
Dhcp
)
func (t InterfaceAddressingMode) String() string {
return [...]string{"none", "static", "dhcp"}[t]
}
func (t *InterfaceAddressingMode) FromString(input string) InterfaceAddressingMode {
return map[string]InterfaceAddressingMode{
"none": None,
"static": Static,
"dhcp": Dhcp,
}[input]
}
func (t InterfaceAddressingMode) MarshalJSON() ([]byte, error) {
return json.Marshal(t.String())
}
func (t *InterfaceAddressingMode) UnmarshalJSON(b []byte) error {
var s string
err := json.Unmarshal(b, &s)
if err != nil {
return err
}
*t = t.FromString(s)
return nil
}

View file

@ -1,6 +0,0 @@
package network
type Network struct {
Interfaces map[string]Interface `json:"interfaces"`
StaticRoutes []StaticRoute `json:"static_routes"`
}

View file

@ -1,13 +0,0 @@
package network
import (
"net/netip"
)
type StaticRoute struct {
Name string `json:"name,omitempty"`
Interface string `json:"interface,omitempty"`
Gateway netip.Addr `json:"gateway,omitempty"`
Destination netip.Prefix `json:"destination,omitempty"`
Metric uint `json:"metric,omitempty"`
}

View file

@ -1,53 +0,0 @@
package object
import (
"encoding/json"
"net/netip"
"go4.org/netipx"
)
type Address struct {
Type AddressType `json:"type"`
Comment string `json:"comment,omitempty"`
Host *netip.Addr `json:"host,omitempty"`
Range *netipx.IPRange `json:"range,omitempty"`
NetworkAddress *netip.Prefix `json:"network,omitempty"`
Children *[]string `json:"children,omitempty"`
}
type AddressType int
const (
Host AddressType = iota
Range
NetworkAddress
AddressGroup
)
func (t AddressType) String() string {
return [...]string{"host", "range", "network", "group"}[t]
}
func (t *AddressType) FromString(input string) AddressType {
return map[string]AddressType{
"host": Host,
"range": Range,
"network": NetworkAddress,
"group": AddressGroup,
}[input]
}
func (t AddressType) MarshalJSON() ([]byte, error) {
return json.Marshal(t.String())
}
func (t *AddressType) UnmarshalJSON(b []byte) error {
var s string
err := json.Unmarshal(b, &s)
if err != nil {
return err
}
*t = t.FromString(s)
return nil
}

View file

@ -1,6 +0,0 @@
package object
type Object struct {
Addresses map[string]Address `json:"addresses"`
Services map[string]Service `json:"services"`
}

View file

@ -1,71 +0,0 @@
package object
import (
"encoding/json"
"fmt"
)
type Service struct {
Type ServiceType `json:"type"`
Comment string `json:"comment,omitempty"`
SPortStart *uint32 `json:"sport_start,omitempty"`
SPortEnd *uint32 `json:"sport_end,omitempty"`
DPortStart *uint32 `json:"dport_start,omitempty"`
DPortEnd *uint32 `json:"dport_end,omitempty"`
ICMPCode *uint32 `json:"icmp_code,omitempty"`
Children *[]string `json:"children,omitempty"`
}
func (s Service) GetSPort() string {
if s.SPortStart == nil || *s.SPortStart == 0 {
return ""
} else if s.SPortEnd == nil || *s.SPortEnd == 0 {
return fmt.Sprintf("%d", *s.SPortStart)
}
return fmt.Sprintf("%d - %d", *s.SPortStart, *s.SPortEnd)
}
func (s Service) GetDPort() string {
if s.DPortStart == nil || *s.DPortStart == 0 {
return ""
} else if s.DPortEnd == nil || *s.DPortEnd == 0 {
return fmt.Sprintf("%d", *s.DPortStart)
}
return fmt.Sprintf("%d - %d", *s.DPortStart, *s.DPortEnd)
}
type ServiceType int
const (
TCP ServiceType = iota
UDP
ICMP
ServiceGroup
)
func (t ServiceType) String() string {
return [...]string{"tcp", "udp", "icmp", "group"}[t]
}
func (t *ServiceType) FromString(input string) ServiceType {
return map[string]ServiceType{
"tcp": TCP,
"udp": UDP,
"icmp": ICMP,
"group": ServiceGroup,
}[input]
}
func (t ServiceType) MarshalJSON() ([]byte, error) {
return json.Marshal(t.String())
}
func (t *ServiceType) UnmarshalJSON(b []byte) error {
var s string
err := json.Unmarshal(b, &s)
if err != nil {
return err
}
*t = t.FromString(s)
return nil
}

View file

@ -1,21 +0,0 @@
package service
import "nfsense.net/nfsense/internal/definitions/common"
type DHCPv4Server struct {
Interface string `json:"interface"`
Pool []string `json:"pool"`
DefaultLeaseTime common.Duration `json:"default_lease_time"`
MaxLeaseTime common.Duration `json:"max_lease_time"`
GatewayMode Mode `json:"gateway_mode"`
Gateway *string `json:"gateway,omitempty"`
DNSServerMode Mode `json:"dns_server_mode"`
DNSServers *[]string `json:"dns_servers,omitempty"`
NTPServerMode Mode `json:"ntp_server_mode"`
NTPServers *[]string `json:"ntp_servers,omitempty"`
Reservations map[string]Reservation `json:"reservations"`
Comment string `json:"comment,omitempty"`
}

View file

@ -1,21 +0,0 @@
package service
import "nfsense.net/nfsense/internal/definitions/common"
type DHCPv6Server struct {
Interface string `json:"interface"`
Pool []string `json:"pool"`
DefaultLeaseTime common.Duration `json:"default_lease_time"`
MaxLeaseTime common.Duration `json:"max_lease_time"`
GatewayMode Mode `json:"gateway_mode"`
Gateway *string `json:"gateway,omitempty"`
DNSServerMode Mode `json:"dns_server_mode"`
DNSServers *[]string `json:"dns_servers,omitempty"`
NTPServerMode Mode `json:"ntp_server_mode"`
NTPServers *[]string `json:"ntp_servers,omitempty"`
Reservations map[string]Reservation `json:"reservations"`
Comment string `json:"comment,omitempty"`
}

View file

@ -1,6 +0,0 @@
package service
type DNSServer struct {
Interface string `json:"interface"`
Comment string `json:"comment,omitempty"`
}

View file

@ -1,37 +0,0 @@
package service
import "encoding/json"
type Mode int
const (
None Mode = iota
Interface
Specify
)
func (t Mode) String() string {
return [...]string{"none", "interface", "specify"}[t]
}
func (t *Mode) FromString(input string) Mode {
return map[string]Mode{
"none": None,
"interface": Interface,
"specify": Specify,
}[input]
}
func (t Mode) MarshalJSON() ([]byte, error) {
return json.Marshal(t.String())
}
func (t *Mode) UnmarshalJSON(b []byte) error {
var s string
err := json.Unmarshal(b, &s)
if err != nil {
return err
}
*t = t.FromString(s)
return nil
}

View file

@ -1,6 +0,0 @@
package service
type NTPServer struct {
Interface string `json:"interface"`
Comment string `json:"comment,omitempty"`
}

View file

@ -1,12 +0,0 @@
package service
import (
"net/netip"
"nfsense.net/nfsense/internal/definitions/common"
)
type Reservation struct {
HardwareAddress common.HardwareAddress
IPAddress netip.Addr
}

View file

@ -1,8 +0,0 @@
package service
type Service struct {
DHCPv4Servers []DHCPv4Server `json:"dhcp_v4_servers"`
DHCPv6Servers []DHCPv6Server `json:"dhcp_v6_servers"`
DNSServers []DNSServer `json:"dns_servers"`
NTPServers []NTPServer `json:"ntp_servers"`
}

View file

@ -1,5 +0,0 @@
package system
type System struct {
Users map[string]User `json:"users"`
}

View file

@ -1,7 +0,0 @@
package system
type User struct {
Comment string `json:"comment"`
Hash string `json:"hash"`
Salt string `json:"salt"`
}

View file

@ -1,9 +0,0 @@
package vpn
type WireguardInterface struct {
PublicKey string `json:"public_key"`
PrivateKey string `json:"private_key"`
ListenPort uint64 `json:"listen_port"`
Peers []string `json:"peers"`
Comment string `json:"comment,omitempty"`
}

View file

@ -1,10 +0,0 @@
package vpn
type WireguardPeer struct {
PublicKey string `json:"public_key"`
PresharedKey *string `json:"preshared_key,omitempty"`
AllowedIPs []string `json:"allowed_ips"`
Endpoint *string `json:"endpoint,omitempty"`
PersistentKeepalive *uint64 `json:"persistent_keepalive,omitempty"`
Comment string `json:"comment,omitempty"`
}

View file

@ -1,5 +0,0 @@
package vpn
type VPN struct {
Wireguard Wireguard `json:"wireguard"`
}

View file

@ -1,6 +0,0 @@
package vpn
type Wireguard struct {
Interfaces map[string]WireguardInterface `json:"interfaces"`
Peers map[string]WireguardPeer `json:"peers"`
}

View file

@ -1,65 +0,0 @@
package dhcp
import (
"context"
"fmt"
systemctl "github.com/coreos/go-systemd/v22/dbus"
"nfsense.net/nfsense/internal/definitions/config"
"nfsense.net/nfsense/internal/util"
)
const dhcpv4File = "/etc/dhcp/dhcpd.conf"
const dhcpv6File = "/etc/dhcp/dhcpd6.conf"
func ApplyDHCPServerConfiguration(currentConfig config.Config, pendingConfig config.Config) error {
v4Conf, err := GenerateDHCPServerV4Configuration(pendingConfig)
if err != nil {
return fmt.Errorf("Generating DHCPServerV4 Configuration: %w", err)
}
v6Conf, err := GenerateDHCPServerV6Configuration(pendingConfig)
if err != nil {
return fmt.Errorf("Generating DHCPServerV6 Configuration: %w", err)
}
err = util.OverwriteFile(dhcpv4File, v4Conf)
if err != nil {
return fmt.Errorf("Writing v4 Configuration: %w", err)
}
err = util.OverwriteFile(dhcpv6File, v6Conf)
if err != nil {
return fmt.Errorf("Writing v6 Configuration: %w", err)
}
conn, err := systemctl.NewSystemConnectionContext(context.Background())
if err != nil {
return fmt.Errorf("Opening Dbus Connection: %w", err)
}
if len(pendingConfig.Service.DHCPv4Servers) == 0 && len(pendingConfig.Service.DHCPv6Servers) == 0 {
// if there are no servers stop the service instead
_, err := conn.StopUnitContext(context.Background(), "dhcpd.service", "replace", nil)
if err != nil {
return fmt.Errorf("stopping dhcpd.service: %w", err)
}
_, err = conn.DisableUnitFilesContext(context.Background(), []string{"dhcpd.service"}, false)
if err != nil {
return fmt.Errorf("disableing dhcpd.service: %w", err)
}
} else {
_, err := conn.ReloadOrRestartUnitContext(context.Background(), "dhcpd.service", "replace", nil)
if err != nil {
return fmt.Errorf("restarting dhcpd.service: %w", err)
}
_, _, err = conn.EnableUnitFilesContext(context.Background(), []string{"dhcpd.service"}, false, true)
if err != nil {
return fmt.Errorf("enableing dhcpd.service: %w", err)
}
}
return nil
}

View file

@ -1,17 +0,0 @@
package dhcp
import (
"bytes"
"fmt"
"nfsense.net/nfsense/internal/definitions/config"
)
func GenerateDHCPServerV4Configuration(conf config.Config) (string, error) {
buf := new(bytes.Buffer)
err := templates.ExecuteTemplate(buf, "v4_config.tmpl", conf)
if err != nil {
return "", fmt.Errorf("executing config.tmpl template: %w", err)
}
return buf.String(), nil
}

View file

@ -1,17 +0,0 @@
package dhcp
import (
"bytes"
"fmt"
"nfsense.net/nfsense/internal/definitions/config"
)
func GenerateDHCPServerV6Configuration(conf config.Config) (string, error) {
buf := new(bytes.Buffer)
err := templates.ExecuteTemplate(buf, "v6_config.tmpl", conf)
if err != nil {
return "", fmt.Errorf("executing config.tmpl template: %w", err)
}
return buf.String(), nil
}

View file

@ -1,107 +0,0 @@
package dhcp
import (
"embed"
"fmt"
"net"
"net/netip"
"strconv"
"strings"
"text/template"
"nfsense.net/nfsense/internal/definitions/common"
"nfsense.net/nfsense/internal/definitions/config"
"nfsense.net/nfsense/internal/util"
)
//go:embed template
var templateFS embed.FS
var templates *template.Template
func init() {
var err error
templates, err = template.New("").Funcs(template.FuncMap{
"getInterfaceAddress": getInterfaceAddress,
"getInterfaceNetworkAddress": getInterfaceNetworkAddress,
"getInterfaceBroadcastAddress": getInterfaceBroadcastAddress,
"getInterfaceNetworkMask": getInterfaceNetworkMask,
"getAddressObjectsAsCommaList": getAddressObjectsAsCommaList,
"getAddressObjectAsPoolRange": getAddressObjectAsPoolRange,
"getTimeInSecond": getTimeInSecond,
}).ParseFS(templateFS, "template/*.tmpl")
if err != nil {
panic(err)
}
}
func getInterfaceAddress(conf config.Config, name string) string {
return conf.Network.Interfaces[name].Address.Addr().String()
}
func getInterfaceNetworkAddress(conf config.Config, name string) string {
return conf.Network.Interfaces[name].Address.Masked().Addr().String()
}
func getInterfaceBroadcastAddress(conf config.Config, name string) string {
return util.BroadcastAddr(prefix2IPNet(*conf.Network.Interfaces[name].Address)).String()
}
func getInterfaceNetworkMask(conf config.Config, name string) string {
return NetMaskToString(conf.Network.Interfaces[name].Address.Bits())
}
func getAddressObjectsAsCommaList(conf config.Config, names []string) string {
res := ""
for i, name := range names {
res = res + conf.Object.Addresses[name].Host.String()
if len(names)-1 != i {
res = res + ", "
}
}
return res
}
func getAddressObjectAsPoolRange(conf config.Config, name string) string {
// TODO
return strings.ReplaceAll(conf.Object.Addresses[name].Range.String(), "-", " ")
}
func getTimeInSecond(dur common.Duration) string {
return fmt.Sprintf("%d", int(dur.Seconds()))
}
func prefix2IPNet(prefix netip.Prefix) net.IPNet {
addr := prefix.Addr() // extract the address portion of the prefix
pLen := 128 // plen is the total size of the subnet mask
if addr.Is4() {
pLen = 32
}
ones := prefix.Bits() // ones is the portion of the mask that's set
ip := net.IP(addr.AsSlice()) // convert the address portion to net.IP
mask := net.CIDRMask(ones, pLen) // create a net.IPMask
return net.IPNet{ // and construct the final IPNet
IP: ip,
Mask: mask,
}
}
func NetMaskToString(mask int) string {
var binarystring string
for ii := 1; ii <= mask; ii++ {
binarystring = binarystring + "1"
}
for ii := 1; ii <= (32 - mask); ii++ {
binarystring = binarystring + "0"
}
oct1 := binarystring[0:8]
oct2 := binarystring[8:16]
oct3 := binarystring[16:24]
oct4 := binarystring[24:]
ii1, _ := strconv.ParseInt(oct1, 2, 64)
ii2, _ := strconv.ParseInt(oct2, 2, 64)
ii3, _ := strconv.ParseInt(oct3, 2, 64)
ii4, _ := strconv.ParseInt(oct4, 2, 64)
return strconv.Itoa(int(ii1)) + "." + strconv.Itoa(int(ii2)) + "." + strconv.Itoa(int(ii3)) + "." + strconv.Itoa(int(ii4))
}

View file

@ -1,46 +0,0 @@
# Global Options
authoritative;
deny bootp;
deny declines;
one-lease-per-client on;
# Servers
{{- range $i, $server := .Service.DHCPv4Servers }}
subnet {{ getInterfaceNetworkAddress $ $server.Interface }} netmask {{ getInterfaceNetworkMask $ $server.Interface }} {
# Pool
{{- range $j, $p := $server.Pool }}
range {{ getAddressObjectAsPoolRange $ $p }};
{{- end}}
# Settings
default-lease-time {{ getTimeInSecond $server.DefaultLeaseTime }};
max-lease-time {{ getTimeInSecond $server.MaxLeaseTime }};
# Options
option subnet-mask {{ getInterfaceNetworkMask $ $server.Interface }};
option broadcast-address {{ getInterfaceBroadcastAddress $ $server.Interface }};
{{- if eq $server.GatewayMode 1 }}
option routers {{ getInterfaceAddress $ $server.Interface }};
{{- else if eq $server.GatewayMode 2 }}
option routers {{ $server.Gateway }};
{{- end }}
{{- if eq $server.DNSServerMode 1 }}
option domain-name-servers {{ getInterfaceAddress $ $server.Interface }};
{{- else if eq $server.DNSServerMode 2 }}
option domain-name-servers {{ getAddressObjectsAsCommaList $ $server.DNSServers }};
{{- end }}
{{- if eq $server.NTPServerMode 1 }}
option time-servers {{ getInterfaceAddress $ $server.Interface }};
{{- else if eq $server.NTPServerMode 2 }}
option time-servers {{ getAddressObjectsAsCommaList $ $server.NTPServers }};
{{- end }}
# Hosts
{{- range $j, $reservation := $server.Reservations }}
host {{ $j }} {
hardware ethernet $reservation.HardwareAddress;
fixed-address $reservation.IPAddress;
}
{{end}}
}
{{end}}

View file

@ -1,37 +0,0 @@
package jsonrpc
import (
"io"
)
type ErrorCode int
const (
ErrParse ErrorCode = -32700
ErrInvalidRequest ErrorCode = -32600
ErrMethodNotFound ErrorCode = -32601
ErrInvalidParams ErrorCode = -32602
ErrInternalError ErrorCode = -32603
// Custom
ErrRequestError ErrorCode = -32000
)
type respError struct {
Code ErrorCode `json:"code"`
Message string `json:"message"`
// cannot be omitempty because of frontend library
Data any `json:"data"`
}
func respondError(w io.Writer, id any, code ErrorCode, err error) error {
respond(w, response{
Jsonrpc: "2.0",
ID: id,
Error: &respError{
Code: code,
Message: err.Error(),
},
})
return err
}

View file

@ -1,100 +0,0 @@
package jsonrpc
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"reflect"
"runtime/debug"
"golang.org/x/exp/slog"
"nfsense.net/nfsense/internal/session"
)
type Handler struct {
methods map[string]method
maxRequestSize int64
}
func NewHandler(maxRequestSize int64) *Handler {
return &Handler{
methods: map[string]method{},
maxRequestSize: maxRequestSize,
}
}
func (h *Handler) HandleRequest(ctx context.Context, s *session.Session, r io.Reader, w io.Writer) error {
defer func() {
if r := recover(); r != nil {
slog.Error("Recovered Panic Handling JSONRPC Request", "err", fmt.Errorf("%v", r), "stack", debug.Stack())
}
}()
var req request
bufferedRequest := new(bytes.Buffer)
reqSize, err := bufferedRequest.ReadFrom(io.LimitReader(r, h.maxRequestSize+1))
if err != nil {
return respondError(w, "", ErrInternalError, fmt.Errorf("Reading Request: %w", err))
}
if reqSize > h.maxRequestSize {
return respondError(w, "", ErrParse, fmt.Errorf("Request exceeds Max Request Size"))
}
dec := json.NewDecoder(bufferedRequest)
dec.DisallowUnknownFields()
err = dec.Decode(&req)
if err != nil {
return respondError(w, "", ErrParse, fmt.Errorf("Decodeing Request: %w", err))
}
if req.Jsonrpc != "2.0" {
return respondError(w, req.ID, ErrMethodNotFound, fmt.Errorf("Unsupported Jsonrpc version %v", req.Jsonrpc))
}
if s == nil {
return respondError(w, req.ID, 401, fmt.Errorf("Unauthorized"))
}
method, ok := h.methods[req.Method]
if !ok {
return respondError(w, req.ID, ErrMethodNotFound, fmt.Errorf("Unknown Method %v", req.Method))
}
p := reflect.New(method.inType)
paramPointer := p.Interface()
if len(req.Params) != 0 {
dec = json.NewDecoder(bytes.NewReader(req.Params))
dec.DisallowUnknownFields()
err = dec.Decode(paramPointer)
if err != nil {
return respondError(w, req.ID, ErrInvalidParams, fmt.Errorf("Decoding Parameters: %w", err))
}
}
params := make([]reflect.Value, 3)
params[0] = method.subSystem
params[1] = reflect.ValueOf(ctx)
params[2] = reflect.ValueOf(paramPointer).Elem()
defer func() {
if r := recover(); r != nil {
slog.Error("Recovered Panic Executing API Method", "err", fmt.Errorf("%v", r), "method", req.Method, "params", fmt.Sprintf("%+v", params[2]), "id", req.ID, "stack", debug.Stack())
respondError(w, req.ID, ErrInternalError, fmt.Errorf("%v", r))
}
}()
res := method.handlerFunc.Call(params)
result := res[0].Interface()
if !res[1].IsNil() {
reqerr := res[1].Interface().(error)
slog.Error("API Method", "err", reqerr, "method", req.Method, "id", req.ID, "params", fmt.Sprintf("%+v", params[2]))
respondError(w, req.ID, ErrInternalError, reqerr)
return nil
}
respondResult(w, req.ID, result)
return nil
}

View file

@ -1,10 +0,0 @@
package jsonrpc
import "reflect"
type method struct {
subSystem reflect.Value
handlerFunc reflect.Value
inType reflect.Type
outType reflect.Type
}

View file

@ -1,46 +0,0 @@
package jsonrpc
import (
"context"
"fmt"
"reflect"
)
func (h *Handler) Register(subSystemName string, s any) {
subSystem := reflect.ValueOf(s)
for i := 0; i < subSystem.NumMethod(); i++ {
m := subSystem.Type().Method(i)
funcType := m.Func.Type()
if funcType.NumIn() != 3 {
panic(fmt.Errorf("2 parameters are required %v", funcType.NumIn()))
}
if funcType.In(1) != reflect.TypeOf(new(context.Context)).Elem() {
panic(fmt.Errorf("the first argument needs to be a context.Context instead of %v ", funcType.In(1)))
}
if funcType.In(2).Kind() != reflect.Struct {
panic("the second argument needs to be a struct")
}
if funcType.NumOut() != 2 {
panic("2 return types are required")
}
if reflect.TypeOf(new(error)).Implements(funcType.Out(1)) {
panic("the second return type needs to be a error")
}
name := m.Name
if subSystemName != "" {
name = subSystemName + "." + name
}
h.methods[name] = method{
handlerFunc: m.Func,
subSystem: subSystem,
inType: funcType.In(2),
outType: funcType.Out(0),
}
}
}

View file

@ -1,10 +0,0 @@
package jsonrpc
import "encoding/json"
type request struct {
Jsonrpc string `json:"jsonrpc"`
ID any `json:"id,omitempty"`
Method string `json:"method"`
Params json.RawMessage `json:"params"`
}

View file

@ -1,30 +0,0 @@
package jsonrpc
import (
"encoding/json"
"io"
"golang.org/x/exp/slog"
)
type response struct {
Jsonrpc string `json:"jsonrpc"`
Result any `json:"result,omitempty"`
ID any `json:"id"`
Error *respError `json:"error,omitempty"`
}
func respond(w io.Writer, resp response) {
err := json.NewEncoder(w).Encode(resp)
if err != nil {
slog.Warn("write response", "err", err)
}
}
func respondResult(w io.Writer, id, res any) {
respond(w, response{
Jsonrpc: "2.0",
ID: id,
Result: res,
})
}

View file

@ -1,76 +0,0 @@
package networkd
import (
"bytes"
"fmt"
"os"
"os/exec"
"path/filepath"
"golang.org/x/exp/slog"
"nfsense.net/nfsense/internal/definitions/config"
)
const basepath = "/etc/systemd/network"
func ApplyNetworkdConfiguration(currentConfig config.Config, pendingConfig config.Config) error {
files, err := GenerateNetworkdConfiguration(pendingConfig)
if err != nil {
return fmt.Errorf("Generating Networkd Configuration: %w", err)
}
err = RemoveContents(basepath)
if err != nil {
return fmt.Errorf("Removing old Config Files: %w", err)
}
for _, file := range files {
f, err := os.Create(basepath + "/" + file.Name)
if err != nil {
return fmt.Errorf("creating File: %w", err)
}
_, err = f.WriteString(file.Content + "\n")
if err != nil {
return fmt.Errorf("writing File: %w", err)
}
err = f.Sync()
if err != nil {
return fmt.Errorf("syncing File: %w", err)
}
}
// TODO Use dbus instead
cmd := exec.Command("systemctl", "restart", "systemd-networkd")
var out bytes.Buffer
cmd.Stdout = &out
err = cmd.Run()
if err != nil {
return fmt.Errorf("restarting networkd: %w", err)
}
slog.Info("networkd output", "out", out.String())
return nil
}
func RemoveContents(dir string) error {
d, err := os.Open(dir)
if err != nil {
return err
}
defer d.Close()
names, err := d.Readdirnames(-1)
if err != nil {
return err
}
for _, name := range names {
err = os.RemoveAll(filepath.Join(dir, name))
if err != nil {
return err
}
}
return nil
}

View file

@ -1,192 +0,0 @@
package networkd
import (
"bytes"
"fmt"
"golang.org/x/exp/slog"
"nfsense.net/nfsense/internal/definitions/config"
"nfsense.net/nfsense/internal/definitions/network"
)
type NetworkdConfigFile struct {
Name string
Content string
}
type InterfaceWithName struct {
Name string
network.Interface
Vlans []string
StaticRoutes []network.StaticRoute
}
type BondMembership struct {
Name string
BondName string
}
type BridgeMembership struct {
Name string
BridgeName string
}
type NameAndConfig struct {
Name string
Config config.Config
}
func GenerateNetworkdConfiguration(conf config.Config) ([]NetworkdConfigFile, error) {
files := []NetworkdConfigFile{}
// Step 1 Generate vlan netdev files
for name, inter := range conf.Network.Interfaces {
if inter.Type == network.Vlan {
buf := new(bytes.Buffer)
err := templates.ExecuteTemplate(buf, "create-vlan.netdev.tmpl", InterfaceWithName{
Name: name,
Interface: inter,
})
if err != nil {
return nil, fmt.Errorf("executing create-vlan.netdev.tmpl template: %w", err)
}
files = append(files, NetworkdConfigFile{
Name: fmt.Sprintf("10-create-vlan-%v.netdev", name),
Content: buf.String(),
})
}
}
// Step 2 Generate bond netdev files
for name, inter := range conf.Network.Interfaces {
if inter.Type == network.Bond {
buf := new(bytes.Buffer)
err := templates.ExecuteTemplate(buf, "create-bond.netdev.tmpl", InterfaceWithName{
Name: name,
Interface: inter,
})
if err != nil {
return nil, fmt.Errorf("executing create-bond.netdev.tmpl template: %w", err)
}
files = append(files, NetworkdConfigFile{
Name: fmt.Sprintf("20-create-bond-%v.netdev", name),
Content: buf.String(),
})
}
}
// Step 3 Generate bridge netdev files
for name, inter := range conf.Network.Interfaces {
if inter.Type == network.Bridge {
buf := new(bytes.Buffer)
err := templates.ExecuteTemplate(buf, "create-bridge.netdev.tmpl", InterfaceWithName{
Name: name,
Interface: inter,
})
if err != nil {
return nil, fmt.Errorf("executing create-bridge.netdev.tmpl template: %w", err)
}
files = append(files, NetworkdConfigFile{
Name: fmt.Sprintf("30-create-bridge-%v.netdev", name),
Content: buf.String(),
})
}
}
// Step 4 Generate wireguard netdev files
for name := range conf.VPN.Wireguard.Interfaces {
buf := new(bytes.Buffer)
err := templates.ExecuteTemplate(buf, "create-wireguard.netdev.tmpl", NameAndConfig{
Name: name,
Config: conf,
})
if err != nil {
return nil, fmt.Errorf("executing create-wireguard.netdev.tmpl template: %w", err)
}
files = append(files, NetworkdConfigFile{
Name: fmt.Sprintf("40-create-wireguard-%v.netdev", name),
Content: buf.String(),
})
}
// Step 5 Generate Bond Members
for name, inter := range conf.Network.Interfaces {
if inter.Type == network.Bond && inter.BondMembers != nil {
for _, member := range *inter.BondMembers {
buf := new(bytes.Buffer)
err := templates.ExecuteTemplate(buf, "bond-membership.network.tmpl", BondMembership{
Name: member,
BondName: name,
})
if err != nil {
return nil, fmt.Errorf("executing bond-membership.network.tmpl template: %w", err)
}
files = append(files, NetworkdConfigFile{
Name: fmt.Sprintf("50-bond-membership-%v.network", name),
Content: buf.String(),
})
}
}
}
// Step 6 Generate Bridge Members
for name, inter := range conf.Network.Interfaces {
if inter.Type == network.Bridge && inter.BridgeMembers != nil {
for _, member := range *inter.BridgeMembers {
buf := new(bytes.Buffer)
err := templates.ExecuteTemplate(buf, "bridge-membership.network.tmpl", BridgeMembership{
Name: member,
BridgeName: name,
})
if err != nil {
return nil, fmt.Errorf("executing bridge-membership.network.tmpl template: %w", err)
}
files = append(files, NetworkdConfigFile{
Name: fmt.Sprintf("60-bridge-membership-%v.network", name),
Content: buf.String(),
})
}
}
}
// Step 7 Generate addressing network files
for name, inter := range conf.Network.Interfaces {
// Vlans
vlans := []string{}
if inter.Type != network.Vlan {
for vlanName, vlanInter := range conf.Network.Interfaces {
if vlanInter.Type == network.Vlan {
if *vlanInter.VlanParent == name {
vlans = append(vlans, vlanName)
}
}
}
slog.Info("Vlans on interface", "interface", name, "count", len(vlans))
}
// Static Routes
staticRoutes := []network.StaticRoute{}
for _, route := range conf.Network.StaticRoutes {
if route.Interface == name {
staticRoutes = append(staticRoutes, route)
}
}
buf := new(bytes.Buffer)
err := templates.ExecuteTemplate(buf, "config-addressing.network.tmpl", InterfaceWithName{
Name: name,
Interface: inter,
Vlans: vlans,
StaticRoutes: staticRoutes,
})
if err != nil {
return nil, fmt.Errorf("executing config-addressing.network.tmpl template: %w", err)
}
files = append(files, NetworkdConfigFile{
Name: fmt.Sprintf("70-config-addressing-%v.network", name),
Content: buf.String(),
})
}
return files, nil
}

View file

@ -1,48 +0,0 @@
package dbus
import (
"fmt"
"github.com/godbus/dbus/v5"
"golang.org/x/exp/slog"
)
type Link struct {
Name string `json:"name"`
CarrierState string `json:"carrier_state"`
OperationalState string `json:"operational_state"`
}
func GetLinks(dbusConn dbus.Conn) ([]Link, error) {
managerObj := dbusConn.Object("org.freedesktop.network1", dbus.ObjectPath("/org/freedesktop/network1"))
var links [][]any
err := managerObj.Call("org.freedesktop.network1.Manager.ListLinks", 0).Store(&links)
if err != nil {
return nil, fmt.Errorf("Calling ListLinks %w", err)
}
slog.Info("Dbus Result", "links", links)
result := []Link{}
for _, link := range links {
name := link[1].(string)
path := link[2].(dbus.ObjectPath)
linkObj := dbusConn.Object("org.freedesktop.network1", path)
carrierState, err := linkObj.GetProperty("org.freedesktop.network1.Link.CarrierState")
if err != nil {
return nil, fmt.Errorf("GetProperty CarrierState %w", err)
}
operationalState, err := linkObj.GetProperty("org.freedesktop.network1.Link.OperationalState")
if err != nil {
return nil, fmt.Errorf("GetProperty OperationalState %w", err)
}
result = append(result, Link{
Name: name,
CarrierState: carrierState.String(),
OperationalState: operationalState.String(),
})
}
return result, nil
}

View file

@ -1,36 +0,0 @@
package networkd
import (
"embed"
"text/template"
"nfsense.net/nfsense/internal/definitions/config"
"nfsense.net/nfsense/internal/definitions/object"
)
//go:embed template
var templateFS embed.FS
var templates *template.Template
func init() {
var err error
templates, err = template.New("").Funcs(template.FuncMap{
"getAddressObjectsAsCidr": getAddressObjectsAsCidr,
}).ParseFS(templateFS, "template/*.tmpl")
if err != nil {
panic(err)
}
}
func getAddressObjectsAsCidr(conf config.Config, name string) string {
addr := conf.Object.Addresses[name]
switch addr.Type {
case object.Host:
return addr.Host.String() + "/32"
case object.NetworkAddress:
return addr.NetworkAddress.String()
default:
panic("unsupported Address Type")
}
}

View file

@ -1,9 +0,0 @@
[Match]
{{- if eq .Type 0 }}
Name={{ .HardwareDevice }}
{{- else }}
Name={{ .Name }}
{{- end }}
[Network]
Bond={{ .BondName }}

View file

@ -1,9 +0,0 @@
[Match]
{{- if eq .Type 0 }}
Name={{ .HardwareDevice }}
{{- else }}
Name={{ .Name }}
{{- end }}
[Network]
Bridge={{ .BridgeName }}

View file

@ -1,26 +0,0 @@
[Match]
{{- if eq .Type 0 }}
Name={{ .HardwareDevice }}
{{- else }}
Name={{ .Name }}
{{- end }}
[Network]
LLMNR=no
{{- if eq .AddressingMode 1 }}
Address={{ .Address }}
{{- else if eq .AddressingMode 2 }}
DHCP=yes
{{- end }}
{{- range .Vlans }}
VLAN={{ . }}
{{- end}}
{{- range .StaticRoutes }}
[Route]
Destination={{ .Destination }}
Gateway={{ .Gateway }}
{{- if ne .Metric 0 }}
Metric={{ .Metric }}
{{- end }}
{{end}}

View file

@ -1,6 +0,0 @@
[NetDev]
Name={{ .Name }}
Kind=bond
[Bond]
Mode=active-backup

View file

@ -1,3 +0,0 @@
[NetDev]
Name={{ .Name }}
Kind=bridge

View file

@ -1,6 +0,0 @@
[NetDev]
Name={{ .Name }}
Kind=vlan
[VLAN]
Id={{ .VlanID }}

View file

@ -1,24 +0,0 @@
[NetDev]
Name={{ $.Name }}
Kind=wireguard
{{- $intertface := index $.Config.VPN.Wireguard.Interfaces .Name }}
[WireGuard]
ListenPort={{ $intertface.ListenPort }}
PrivateKey={{ $intertface.PrivateKey }}
{{ range $i, $peerName := $intertface.Peers }}
{{- $peer := index $.Config.VPN.Wireguard.Peers $peerName }}
[WireGuardPeer]
PublicKey={{ $peer.PublicKey }}
{{- if ne $peer.PresharedKey nil }}
PresharedKey={{ $peer.PresharedKey }}
{{- end }}
{{range $i, $allowedIpName := $peer.AllowedIPs }}
AllowedIPs={{ getAddressObjectsAsCidr $.Config $allowedIpName}}
{{- end }}
{{- if ne $peer.Endpoint nil }}
Endpoint={{ $peer.Endpoint }}
{{- end }}
{{- end }}

View file

@ -1,74 +0,0 @@
package nftables
import (
"nfsense.net/nfsense/internal/definitions/config"
"nfsense.net/nfsense/internal/definitions/firewall"
"nfsense.net/nfsense/internal/definitions/object"
)
func GenerateDestinationNatAction(conf config.Config, rule firewall.DestinationNATRule) string {
destination := ""
if rule.Address != nil {
addr := conf.Object.Addresses[*rule.Address]
if addr.Type == object.Host {
destination = addr.Host.String()
} else {
panic("invalid address type")
}
}
if rule.Service != nil {
serv := conf.Object.Services[*rule.Service]
if serv.Type == object.TCP || serv.Type == object.UDP {
destination += ":" + serv.GetDPort()
} else {
panic("invalid service type")
}
}
// TODO if the destination is ip v6 use ip6 instead of ip here
if rule.Address != nil {
return "dnat ip to " + destination
}
// ip or ip6 are not needed if the addresses is not changed
return "dnat to " + destination
}
func GenerateSourceNatAction(conf config.Config, rule firewall.SourceNATRule) string {
if rule.Type == firewall.Masquerade {
return "masquerade"
}
source := ""
if rule.Address != nil {
addr := conf.Object.Addresses[*rule.Address]
if addr.Type == object.Host {
source = addr.Host.String()
} else if addr.Type == object.Range {
source = addr.Range.String()
} else {
panic("invalid address type")
}
}
if rule.Service != nil {
serv := conf.Object.Services[*rule.Service]
if serv.Type == object.TCP || serv.Type == object.UDP {
source += ":" + serv.GetSPort()
} else {
panic("invalid service type")
}
}
// TODO if the destination is ip v6 use ip6 instead of ip here
if rule.Address != nil {
return "snat ip to " + source
}
// ip or ip6 are not needed if the addresses is not changed
return "snat to " + source
}

View file

@ -1,35 +0,0 @@
package nftables
import (
"context"
"fmt"
systemctl "github.com/coreos/go-systemd/v22/dbus"
"nfsense.net/nfsense/internal/definitions/config"
"nfsense.net/nfsense/internal/util"
)
const nftablesFile = "/etc/nftables/nfsense.conf"
func ApplyNFTablesConfiguration(currentConfig config.Config, pendingConfig config.Config) error {
nftablesConf, err := GenerateNfTablesConfig(pendingConfig)
if err != nil {
return fmt.Errorf("Generating nftables Configuration: %w", err)
}
err = util.OverwriteFile(nftablesFile, nftablesConf)
if err != nil {
return fmt.Errorf("Writing nftables Configuration: %w", err)
}
conn, err := systemctl.NewSystemConnectionContext(context.Background())
if err != nil {
return fmt.Errorf("Opening Dbus Connection: %w", err)
}
_, err = conn.ReloadOrRestartUnitContext(context.Background(), "nftables.service", "replace", nil)
if err != nil {
return fmt.Errorf("restarting unbound.service: %w", err)
}
return nil
}

View file

@ -1,17 +0,0 @@
package nftables
import (
"bytes"
"fmt"
"nfsense.net/nfsense/internal/definitions/config"
)
func GenerateNfTablesConfig(conf config.Config) (string, error) {
buf := new(bytes.Buffer)
err := templates.ExecuteTemplate(buf, "nftables.tmpl", conf)
if err != nil {
return "", fmt.Errorf("executing template: %w", err)
}
return buf.String(), nil
}

View file

@ -1,87 +0,0 @@
package nftables
import (
"fmt"
"nfsense.net/nfsense/internal/definitions/firewall"
"nfsense.net/nfsense/internal/definitions/object"
"nfsense.net/nfsense/internal/util"
)
func GenerateServiceMatcher(service object.Service) string {
res := ""
switch service.Type {
case object.TCP:
if service.GetSPort() != "" {
res = "tcp sport " + service.GetSPort()
}
if service.GetDPort() != "" {
if len(res) != 0 {
res += " "
}
res += "tcp dport " + service.GetDPort()
}
case object.UDP:
if service.GetSPort() != "" {
res = "udp sport " + service.GetSPort()
}
if service.GetDPort() != "" {
if len(res) != 0 {
res += " "
}
res += "udp dport " + service.GetDPort()
}
case object.ICMP:
res = "icmp codes " + fmt.Sprint(service.ICMPCode)
default:
panic("invalid service type")
}
return res
}
func GenerateAddressMatcher(allAddresses map[string]object.Address, match firewall.Match) string {
sourceAddressList := util.ResolveBaseAddresses(allAddresses, match.SourceAddresses)
destinationAddressList := util.ResolveBaseAddresses(allAddresses, match.DestinationAddresses)
sourceAddresses := []string{}
destinationAddresses := []string{}
for _, address := range sourceAddressList {
switch address.Type {
case object.Host:
sourceAddresses = append(sourceAddresses, address.Host.String())
case object.Range:
sourceAddresses = append(sourceAddresses, address.Range.String())
case object.NetworkAddress:
sourceAddresses = append(sourceAddresses, address.NetworkAddress.String())
default:
panic("invalid address type")
}
}
for _, address := range destinationAddressList {
switch address.Type {
case object.Host:
destinationAddresses = append(destinationAddresses, address.Host.String())
case object.Range:
destinationAddresses = append(destinationAddresses, address.Range.String())
case object.NetworkAddress:
destinationAddresses = append(destinationAddresses, address.NetworkAddress.String())
default:
panic("invalid address type")
}
}
res := ""
if len(sourceAddresses) != 0 {
res += "ip saddr " + util.ConvertSliceToSetString(sourceAddresses) + " "
}
if len(destinationAddresses) != 0 {
res += "ip daddr " + util.ConvertSliceToSetString(destinationAddresses) + " "
}
return res
}

View file

@ -1,29 +0,0 @@
package nftables
import (
"embed"
"text/template"
"nfsense.net/nfsense/internal/util"
)
//go:embed template
var templateFS embed.FS
var templates *template.Template
func init() {
funcMap := template.FuncMap{
"addressMatcher": GenerateAddressMatcher,
"serviceMatcher": GenerateServiceMatcher,
"destinationNatAction": GenerateDestinationNatAction,
"sourceNatAction": GenerateSourceNatAction,
"getBaseServices": util.ResolveBaseServices,
}
var err error
templates, err = template.New("").Funcs(funcMap).ParseFS(templateFS, "template/*.tmpl")
if err != nil {
panic(err)
}
}

View file

@ -1,97 +0,0 @@
#!/usr/sbin/nft -f
flush ruleset
# nfsense nftables inet (ipv4 + ipv6) table
table inet nfsense_inet {
# Rule Counters for Forward Rules
{{- range $i, $rule := $.Firewall.ForwardRules }}
{{- if $rule.Counter }}
counter fw_{{ $i }} {
comment "{{ $rule.Name }}"
}
{{- end}}
{{- end}}
# Rule Counters for Destination NAT Rules
{{- range $i, $rule := $.Firewall.DestinationNATRules }}
{{- if $rule.Counter }}
counter dnat_{{ $i }} {
comment "{{ $rule.Name }}"
}
{{- end}}
{{- end}}
# Rule Counters for Source NAT Rules
{{- range $i, $rule := $.Firewall.SourceNATRules }}
{{- if $rule.Counter }}
counter snat_{{ $i }} {
comment "{{ $rule.Name }}"
}
{{- end}}
{{- end}}
# Inbound Rules
chain inbound {
type filter hook input priority 0; policy drop;
# Allow traffic from established and related packets, drop invalid
ct state vmap { established : accept, related : accept, invalid : drop }
# Allow loopback traffic
iifname lo accept
# temp Allow Inbound traffic
counter accept comment "temp inbound allow"
}
# Forward Rules
chain forward {
type filter hook forward priority 0; policy drop;
# Allow traffic from established and related packets, drop invalid
ct state vmap { established : accept, related : accept, invalid : drop }
# Generated Forward Rules
{{- range $i, $rule := $.Firewall.ForwardRules }}
{{ addressMatcher $.Object.Addresses $rule.Match }} jump {
{{- $baseServices := getBaseServices $.Object.Services $rule.Match.Services }}
{{- range $service := $baseServices }}
{{ serviceMatcher $service }}{{ if $rule.Counter }} counter name fw_{{ $i }}{{ end }} {{ $rule.Verdict.String }}
{{- end}}
}
{{- end}}
}
# Destination NAT Rules
chain prerouting {
type nat hook prerouting priority -100; policy accept;
# Generated Destination NAT Rules
{{- range $i, $rule := $.Firewall.DestinationNATRules }}
{{ addressMatcher $.Object.Addresses $rule.Match }} jump {
{{- $baseServices := getBaseServices $.Object.Services $rule.Match.Services }}
{{- range $service := $baseServices }}
{{ serviceMatcher $service }}{{ if $rule.Counter }} counter name dnat_{{ $i }}{{ end }} {{ destinationNatAction $ $rule }}
{{- end}}
}
{{- end}}
}
# Source NAT Rules
chain postrouting {
type nat hook postrouting priority 100; policy accept;
# Generated Source NAT Rules
{{- range $i, $rule := $.Firewall.SourceNATRules }}
{{ addressMatcher $.Object.Addresses $rule.Match }} jump {
{{- $baseServices := getBaseServices $.Object.Services $rule.Match.Services }}
{{- range $service := $baseServices }}
{{ serviceMatcher $service }}{{ if $rule.Counter }} counter name snat_{{ $i }}{{ end }} {{ sourceNatAction $ $rule }}
{{- end}}
}
{{- end}}
}
}

View file

@ -1,35 +0,0 @@
package server
import (
"context"
"fmt"
"net/http"
"runtime/debug"
"time"
"golang.org/x/exp/slog"
"nfsense.net/nfsense/internal/session"
)
func HandleAPI(w http.ResponseWriter, r *http.Request) {
_, s := session.GetSession(r)
if s == nil {
// Fallthrough after so that jsonrpc can still deliver a valid jsonrpc error
w.WriteHeader(http.StatusUnauthorized)
}
defer func() {
if r := recover(); r != nil {
slog.Error("Recovered Panic Handling HTTP API Request", "err", fmt.Errorf("%v", r), "stack", debug.Stack())
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
}()
ctx, cancel := context.WithTimeout(context.WithValue(r.Context(), session.SessionKey, s), time.Second*10)
defer cancel()
err := apiHandler.HandleRequest(ctx, s, r.Body, w)
if err != nil {
slog.Error("Handling HTTP API Request", "err", err)
}
}

View file

@ -1,55 +0,0 @@
package server
import (
"context"
"errors"
"fmt"
"net/http"
"golang.org/x/exp/slog"
"nfsense.net/nfsense/internal/config"
"nfsense.net/nfsense/internal/jsonrpc"
"nfsense.net/nfsense/internal/session"
)
var server http.Server
var mux = http.NewServeMux()
var apiHandler *jsonrpc.Handler
var stopCleanup chan struct{}
var configManager *config.ConfigManager
func StartWebserver(_configManager *config.ConfigManager, _apiHandler *jsonrpc.Handler) {
server.Addr = ":8080"
server.Handler = mux
apiHandler = _apiHandler
configManager = _configManager
// Routing
mux.HandleFunc("/login", HandleLogin)
mux.HandleFunc("/logout", HandleLogout)
mux.HandleFunc("/session", HandleSession)
mux.HandleFunc("/api", HandleAPI)
mux.HandleFunc("/ws/api", HandleWebsocketAPI)
mux.HandleFunc("/", HandleWebinterface)
stopCleanup = make(chan struct{})
go session.CleanupSessions(stopCleanup)
go func() {
if err := server.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
slog.Error("Webserver error", "err", err)
}
slog.Info("Webserver Stopped")
}()
}
func ShutdownWebserver(ctx context.Context) error {
stopCleanup <- struct{}{}
err := server.Shutdown(ctx)
if err != nil {
return fmt.Errorf("Shutting down: %w", err)
}
return nil
}

View file

@ -1,67 +0,0 @@
package server
import (
"encoding/json"
"io"
"net/http"
"time"
"golang.org/x/exp/slog"
"nfsense.net/nfsense/internal/auth"
"nfsense.net/nfsense/internal/session"
)
type LoginRequest struct {
Username string `json:"username"`
Password string `json:"password"`
}
func HandleLogin(w http.ResponseWriter, r *http.Request) {
buf, err := io.ReadAll(r.Body)
if err != nil {
slog.Error("Reading Body", err)
return
}
var req LoginRequest
err = json.Unmarshal(buf, &req)
if err != nil {
slog.Error("Unmarshal", "err", err)
return
}
err = auth.AuthenticateUser(configManager.GetCurrentConfig(), req.Username, req.Password)
if err != nil {
slog.Error("User Login failed", "err", err, "username", req.Username)
w.WriteHeader(http.StatusUnauthorized)
return
}
slog.Info("User Login Successful", "username", req.Username)
session.GenerateSession(w, req.Username)
w.WriteHeader(http.StatusOK)
}
func HandleLogout(w http.ResponseWriter, r *http.Request) {
http.SetCookie(w, session.GetCookie("", time.Now()))
w.WriteHeader(http.StatusOK)
}
func HandleSession(w http.ResponseWriter, r *http.Request) {
id, s := session.GetSession(r)
if s == nil {
w.WriteHeader(http.StatusUnauthorized)
return
}
session.ExtendSession(s)
http.SetCookie(w, session.GetCookie(id, s.Expires))
w.WriteHeader(http.StatusOK)
resp := session.SessionResponse{
CommitHash: session.CommitHash,
}
res, err := json.Marshal(resp)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Write(res)
}

Some files were not shown because too many files have changed in this diff Show more