Skip to content

Commit

Permalink
Split out registration to its own enrolment package
Browse files Browse the repository at this point in the history
  • Loading branch information
NHAS committed Oct 17, 2024
1 parent 3212ccf commit 8ac81d7
Show file tree
Hide file tree
Showing 14 changed files with 630 additions and 555 deletions.
37 changes: 0 additions & 37 deletions adminui/security.go
Original file line number Diff line number Diff line change
@@ -1,38 +1 @@
package adminui

import (
"net/http"
"net/url"
)

type security struct {
next http.Handler
}

func (sh *security) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-Frame-Options", "DENY")
w.Header().Set("Strict-Transport-Security", "max-age=31536000")
w.Header().Set("X-Content-Type-Options", "nosniff")

if r.Method != "GET" {
u, err := url.Parse(r.Header.Get("Origin"))
if err != nil {
http.Error(w, "Bad Request", 400)
return
}

//If origin != host header
if r.Host != u.Host {
http.Error(w, "Bad Request", 400)
return
}
}

sh.next.ServeHTTP(w, r)
}

func setSecurityHeaders(f http.Handler) http.Handler {
return &security{
next: f,
}
}
84 changes: 42 additions & 42 deletions adminui/src/css/sb-admin-2.css
Original file line number Diff line number Diff line change
Expand Up @@ -10289,67 +10289,67 @@ a:focus {

@keyframes noise-anim {
0% {
clip: rect(62px, 9999px, 66px, 0);
clip: rect(79px, 9999px, 67px, 0);
}
5% {
clip: rect(44px, 9999px, 54px, 0);
clip: rect(2px, 9999px, 86px, 0);
}
10% {
clip: rect(47px, 9999px, 34px, 0);
clip: rect(53px, 9999px, 16px, 0);
}
15% {
clip: rect(75px, 9999px, 98px, 0);
clip: rect(38px, 9999px, 49px, 0);
}
20% {
clip: rect(45px, 9999px, 70px, 0);
clip: rect(38px, 9999px, 94px, 0);
}
25% {
clip: rect(29px, 9999px, 35px, 0);
clip: rect(41px, 9999px, 28px, 0);
}
30% {
clip: rect(88px, 9999px, 100px, 0);
clip: rect(91px, 9999px, 92px, 0);
}
35% {
clip: rect(80px, 9999px, 39px, 0);
clip: rect(32px, 9999px, 91px, 0);
}
40% {
clip: rect(84px, 9999px, 60px, 0);
clip: rect(53px, 9999px, 57px, 0);
}
45% {
clip: rect(24px, 9999px, 38px, 0);
clip: rect(5px, 9999px, 85px, 0);
}
50% {
clip: rect(73px, 9999px, 80px, 0);
clip: rect(82px, 9999px, 43px, 0);
}
55% {
clip: rect(66px, 9999px, 20px, 0);
clip: rect(41px, 9999px, 44px, 0);
}
60% {
clip: rect(19px, 9999px, 18px, 0);
clip: rect(47px, 9999px, 97px, 0);
}
65% {
clip: rect(66px, 9999px, 32px, 0);
clip: rect(35px, 9999px, 62px, 0);
}
70% {
clip: rect(90px, 9999px, 22px, 0);
clip: rect(91px, 9999px, 62px, 0);
}
75% {
clip: rect(28px, 9999px, 66px, 0);
clip: rect(49px, 9999px, 24px, 0);
}
80% {
clip: rect(10px, 9999px, 67px, 0);
clip: rect(51px, 9999px, 84px, 0);
}
85% {
clip: rect(79px, 9999px, 78px, 0);
clip: rect(67px, 9999px, 66px, 0);
}
90% {
clip: rect(1px, 9999px, 14px, 0);
clip: rect(60px, 9999px, 20px, 0);
}
95% {
clip: rect(8px, 9999px, 81px, 0);
clip: rect(80px, 9999px, 30px, 0);
}
100% {
clip: rect(48px, 9999px, 74px, 0);
clip: rect(26px, 9999px, 100px, 0);
}
}
.error:after {
Expand All @@ -10367,67 +10367,67 @@ a:focus {

@keyframes noise-anim-2 {
0% {
clip: rect(82px, 9999px, 91px, 0);
clip: rect(52px, 9999px, 16px, 0);
}
5% {
clip: rect(24px, 9999px, 30px, 0);
clip: rect(79px, 9999px, 20px, 0);
}
10% {
clip: rect(31px, 9999px, 41px, 0);
clip: rect(39px, 9999px, 37px, 0);
}
15% {
clip: rect(66px, 9999px, 42px, 0);
clip: rect(36px, 9999px, 20px, 0);
}
20% {
clip: rect(60px, 9999px, 93px, 0);
clip: rect(64px, 9999px, 79px, 0);
}
25% {
clip: rect(98px, 9999px, 23px, 0);
clip: rect(91px, 9999px, 13px, 0);
}
30% {
clip: rect(68px, 9999px, 72px, 0);
clip: rect(43px, 9999px, 93px, 0);
}
35% {
clip: rect(91px, 9999px, 41px, 0);
clip: rect(50px, 9999px, 23px, 0);
}
40% {
clip: rect(95px, 9999px, 49px, 0);
clip: rect(39px, 9999px, 59px, 0);
}
45% {
clip: rect(50px, 9999px, 37px, 0);
clip: rect(32px, 9999px, 88px, 0);
}
50% {
clip: rect(19px, 9999px, 2px, 0);
clip: rect(23px, 9999px, 84px, 0);
}
55% {
clip: rect(44px, 9999px, 84px, 0);
clip: rect(12px, 9999px, 89px, 0);
}
60% {
clip: rect(69px, 9999px, 41px, 0);
clip: rect(87px, 9999px, 15px, 0);
}
65% {
clip: rect(11px, 9999px, 12px, 0);
clip: rect(4px, 9999px, 27px, 0);
}
70% {
clip: rect(36px, 9999px, 35px, 0);
clip: rect(67px, 9999px, 4px, 0);
}
75% {
clip: rect(1px, 9999px, 4px, 0);
clip: rect(34px, 9999px, 70px, 0);
}
80% {
clip: rect(75px, 9999px, 83px, 0);
clip: rect(80px, 9999px, 11px, 0);
}
85% {
clip: rect(51px, 9999px, 74px, 0);
clip: rect(70px, 9999px, 16px, 0);
}
90% {
clip: rect(86px, 9999px, 21px, 0);
clip: rect(82px, 9999px, 91px, 0);
}
95% {
clip: rect(67px, 9999px, 5px, 0);
clip: rect(95px, 9999px, 58px, 0);
}
100% {
clip: rect(13px, 9999px, 60px, 0);
clip: rect(64px, 9999px, 5px, 0);
}
}
.error:before {
Expand Down
20 changes: 10 additions & 10 deletions adminui/ui_webserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ func New(firewall *router.Firewall, errs chan<- error) (ui *AdminUI, err error)
}

u.Path = path.Join(u.Path, "/login/oidc/callback")
log.Println("Admin OIDC callback: ", u.String())
log.Println("Connecting to Admin UI OIDC provider: ", config.Values.ManagementUI.OIDC.IssuerURL)
log.Println("[ADMINUI] OIDC callback: ", u.String())
log.Println("[ADMINUI] Connecting to OIDC provider: ", config.Values.ManagementUI.OIDC.IssuerURL)

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)

Expand All @@ -106,7 +106,7 @@ func New(firewall *router.Firewall, errs chan<- error) (ui *AdminUI, err error)
return nil, fmt.Errorf("unable to connect to oidc provider for admin ui. err %s", err)
}

log.Println("Connected to admin oidc provider!")
log.Println("[ADMINUI] Connected to admin oidc provider!")
}

if *config.Values.ManagementUI.Password.Enabled {
Expand All @@ -117,7 +117,7 @@ func New(firewall *router.Firewall, errs chan<- error) (ui *AdminUI, err error)
}

if len(admins) == 0 {
log.Println("[INFO] *************** Web interface enabled but no administrator users exist, generating new ones CREDENTIALS FOLLOW ***************")
log.Println("[ADMINUI] *************** Web interface enabled but no administrator users exist, generating new ones CREDENTIALS FOLLOW ***************")

username, err := utils.GenerateRandomHex(8)
if err != nil {
Expand All @@ -129,10 +129,10 @@ func New(firewall *router.Firewall, errs chan<- error) (ui *AdminUI, err error)
return nil, fmt.Errorf("failed to generate random password: %s", err)
}

log.Println("Username: ", username)
log.Println("Password: ", password)
log.Println("[ADMINUI] Username: ", username)
log.Println("[ADMINUI] Password: ", password)

log.Println("This information will not be shown again. ")
log.Println("[ADMINUI] This information will not be shown again. ")

err = adminUI.ctrl.AddAdminUser(username, password, true)
if err != nil {
Expand Down Expand Up @@ -303,7 +303,7 @@ func New(firewall *router.Firewall, errs chan<- error) (ui *AdminUI, err error)
WriteTimeout: 10 * time.Second,
IdleTimeout: 120 * time.Second,
TLSConfig: tlsConfig,
Handler: setSecurityHeaders(allRoutes),
Handler: utils.SetSecurityHeaders(allRoutes),
}

if err := adminUI.https.ListenAndServeTLS(config.Values.ManagementUI.CertPath, config.Values.ManagementUI.KeyPath); err != nil && !errors.Is(err, http.ErrServerClosed) {
Expand All @@ -318,7 +318,7 @@ func New(firewall *router.Firewall, errs chan<- error) (ui *AdminUI, err error)
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
IdleTimeout: 120 * time.Second,
Handler: setSecurityHeaders(allRoutes),
Handler: utils.SetSecurityHeaders(allRoutes),
}
if err := adminUI.http.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
errs <- fmt.Errorf("webserver management listener failed: %v", adminUI.http.ListenAndServe())
Expand All @@ -328,7 +328,7 @@ func New(firewall *router.Firewall, errs chan<- error) (ui *AdminUI, err error)
}
}()

log.Println("Started Managemnt UI:\n\t\t\tListening:", config.Values.ManagementUI.ListenAddress)
log.Println("[ADMINUI] Started Managemnt UI listening:", config.Values.ManagementUI.ListenAddress)

return &adminUI, nil
}
Expand Down
18 changes: 15 additions & 3 deletions commands/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/NHAS/wag/adminui"
"github.com/NHAS/wag/internal/config"
"github.com/NHAS/wag/internal/data"
"github.com/NHAS/wag/internal/enrolment"
"github.com/NHAS/wag/internal/mfaportal"

"github.com/NHAS/wag/internal/router"
Expand Down Expand Up @@ -90,9 +91,10 @@ func startWag(noIptables bool, cancel <-chan bool, errorChan chan<- error) func(

routerFw *router.Firewall

controlServer *server.WagControlSocketServer
mfaPortal *mfaportal.MfaPortal
adminUI *adminui.AdminUI
controlServer *server.WagControlSocketServer
mfaPortal *mfaportal.MfaPortal
enrolmentServer *enrolment.EnrolmentServer
adminUI *adminui.AdminUI

err error
)
Expand All @@ -109,6 +111,10 @@ func startWag(noIptables bool, cancel <-chan bool, errorChan chan<- error) func(
mfaPortal.Close()
}

if enrolmentServer != nil {
enrolmentServer.Close()
}

if adminUI != nil {
adminUI.Close()
}
Expand Down Expand Up @@ -176,6 +182,12 @@ func startWag(noIptables bool, cancel <-chan bool, errorChan chan<- error) func(
return
}

enrolmentServer, err = enrolment.New(routerFw, errorChan)
if err != nil {
errorChan <- fmt.Errorf("unable to start enrolment server: %v", err)
return
}

if config.Values.ManagementUI.Enabled {
adminUI, err = adminui.New(routerFw, errorChan)
if err != nil {
Expand Down
2 changes: 2 additions & 0 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ services:
command: sleep infinity
ports:
- "4433:4433/tcp"
- "53230:53230/udp"
- "8081:8081/tcp"
volumes:
- .:/usr/local/bin/wag:ro
- ./docker-test-config.json:/opt/config.json
Expand Down
44 changes: 44 additions & 0 deletions internal/enrolment/resources/embed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package resources

import (
"embed"
"html/template"
"io"
"path"

"github.com/NHAS/wag/internal/config"
)

type Interface struct {
ClientPrivateKey string
ClientAddress string
ClientPresharedKey string

ServerAddress string
ServerPublicKey string
CapturedAddresses []string
DNS []string
}

type QrCodeRegistrationDisplay struct {
ImageData template.URL
Username string
}

//go:embed templates/*
var templates embed.FS

func Render(page string, out io.Writer, data interface{}) error {
return RenderWithFuncs(page, out, data, nil)
}

func RenderWithFuncs(page string, out io.Writer, data interface{}, templateFuncs template.FuncMap) error {
var currentTemplate *template.Template
if len(config.Values.MFATemplatesDirectory) != 0 {
currentTemplate = template.Must(template.New(path.Base(page)).Funcs(templateFuncs).ParseFiles(path.Join(config.Values.MFATemplatesDirectory, page)))
} else {
currentTemplate = template.Must(template.New(path.Base(page)).Funcs(templateFuncs).ParseFS(templates, "templates/"+page))
}

return currentTemplate.Execute(out, data)
}
Loading

0 comments on commit 8ac81d7

Please sign in to comment.