Skip to content

Commit

Permalink
Merge branch 'unstable'
Browse files Browse the repository at this point in the history
  • Loading branch information
NHAS committed Aug 7, 2023
2 parents 0be940c + 833ebb2 commit 48881b8
Show file tree
Hide file tree
Showing 13 changed files with 109 additions and 24 deletions.
6 changes: 5 additions & 1 deletion commands/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ type registration struct {
groups arrayFlags
groupsString string
overwrite string

uses int
}

func Registration() *registration {
Expand All @@ -49,6 +51,8 @@ func Registration() *registration {

gc.fs.StringVar(&gc.overwrite, "overwrite", "", "Add registration token for an existing user device, will overwrite wireguard public key (but not 2FA)")

gc.fs.IntVar(&gc.uses, "uses", 1, "Number of times a registration token can be used")

gc.fs.Bool("add", false, "Create a new enrolment token")
gc.fs.Bool("del", false, "Delete existing enrolment token")
gc.fs.Bool("list", false, "List tokens")
Expand Down Expand Up @@ -113,7 +117,7 @@ func (g *registration) Run() error {
switch g.action {
case "add":

result, err := ctl.NewRegistration(g.token, g.username, g.overwrite, g.groups...)
result, err := ctl.NewRegistration(g.token, g.username, g.overwrite, g.uses, g.groups...)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (a Acls) GetUserGroups(username string) (result []string) {
type Config struct {
path string
Socket string `json:",omitempty"`
GID int `json:,omitempty`
GID *int `json:",omitempty"`
CheckUpdates bool `json:",omitempty"`
Proxied bool
ExposePorts []string `json:",omitempty"`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-- version 10
ALTER TABLE RegistrationTokens ADD uses INTEGER;

53 changes: 41 additions & 12 deletions internal/data/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ func GetRegistrationToken(token string) (username, overwrites string, group []st
RegistrationTokens
WHERE
token = ?
AND
uses > 0
`, token).Scan(&token, &username, &overwrites, &groupsJson)
if err != nil {
return
Expand All @@ -41,7 +43,7 @@ func GetRegistrationToken(token string) (username, overwrites string, group []st
// Returns list of tokens
func GetRegistrationTokens() (result []control.RegistrationResult, err error) {

rows, err := database.Query("SELECT token, username, overwrite, groups FROM RegistrationTokens ORDER by ROWID DESC")
rows, err := database.Query("SELECT token, username, overwrite, groups, uses FROM RegistrationTokens ORDER by ROWID DESC")
if err != nil {
return nil, err
}
Expand All @@ -51,7 +53,7 @@ func GetRegistrationTokens() (result []control.RegistrationResult, err error) {
groupsJson sql.NullString
registration control.RegistrationResult
)
err = rows.Scan(&registration.Token, &registration.Username, &registration.Overwrites, &groupsJson)
err = rows.Scan(&registration.Token, &registration.Username, &registration.Overwrites, &groupsJson, &registration.NumUses)
if err != nil {
return nil, err
}
Expand All @@ -74,26 +76,53 @@ func DeleteRegistrationToken(identifier string) error {
DELETE FROM
RegistrationTokens
WHERE
token = $1 OR username = $1
(token = $1 OR username = $1) or uses <= 0
`, identifier)
return err
}

// FinaliseRegistration may or may not delete the token in question depending on whether the number of uses is <= 0
func FinaliseRegistration(token string) error {
_, err := database.Exec(`UPDATE
RegistrationTokens
SET
uses = uses - 1
WHERE
token = ?`,
token)
if err != nil {
return err
}

var uses int
err = database.QueryRow(`SELECT uses FROM RegistrationTokens WHERE token = ?`, token).Scan(&uses)
// Due to the (token = $1 OR username = $1) or uses <= 0 in DeleteRegistrationToken it is possible for tokens to get deleted between update and now
if err != nil && err != sql.ErrNoRows {
return err
}

if uses <= 0 && err != sql.ErrNoRows {
return DeleteRegistrationToken(token)
}

return nil
}

// Randomly generate a token for a specific username
func GenerateToken(username, overwrite string, groups []string) (token string, err error) {
func GenerateToken(username, overwrite string, groups []string, uses int) (token string, err error) {
tokenBytes, err := generateRandomBytes(32)
if err != nil {
return "", err
}

token = hex.EncodeToString(tokenBytes)
err = AddRegistrationToken(token, username, overwrite, groups)
err = AddRegistrationToken(token, username, overwrite, groups, uses)

return
}

// Add a token to the database to add or overwrite a device for a user, may fail of the token does not meet complexity requirements
func AddRegistrationToken(token, username, overwrite string, groups []string) error {
func AddRegistrationToken(token, username, overwrite string, groups []string, uses int) error {
if len(token) < 32 {
return errors.New("registration token is too short")
}
Expand All @@ -120,20 +149,20 @@ func AddRegistrationToken(token, username, overwrite string, groups []string) er

_, err = database.Exec(`
INSERT INTO
RegistrationTokens (token, username, overwrite, groups)
RegistrationTokens (token, username, overwrite, groups, uses)
VALUES
(?, ?, ?, ?)
`, token, username, overwrite, string(result))
(?, ?, ?, ?, ?)
`, token, username, overwrite, string(result), uses)

return err
}

_, err = database.Exec(`
INSERT INTO
RegistrationTokens (token, username, overwrite)
RegistrationTokens (token, username, overwrite, uses)
VALUES
(?, ?, ?)
`, token, username, overwrite)
(?, ?, ?, ?)
`, token, username, overwrite, uses)

return err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/webserver/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ func registerDevice(w http.ResponseWriter, r *http.Request) {
}

//Finish registration process
err = data.DeleteRegistrationToken(key)
err = data.FinaliseRegistration(key)
if err != nil {
log.Println(username, remoteAddr, "expiring registration token failed:", err)
http.Error(w, "Server Error", 500)
Expand Down
19 changes: 16 additions & 3 deletions pkg/control/server/registrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"log"
"net/http"
"strconv"
"strings"

"github.com/NHAS/wag/internal/config"
Expand Down Expand Up @@ -52,6 +53,7 @@ func newRegistration(w http.ResponseWriter, r *http.Request) {
overwrite := r.FormValue("overwrite")

groupsString := r.FormValue("groups")
usesString := r.FormValue("uses")

var groups []string = nil
err = json.Unmarshal([]byte(groupsString), &groups)
Expand All @@ -72,15 +74,26 @@ func newRegistration(w http.ResponseWriter, r *http.Request) {
config.AddVirtualUser(username, groups)
}

resp := control.RegistrationResult{Token: token, Username: username, Groups: groups}
uses, err := strconv.Atoi(usesString)
if err != nil {
http.Error(w, "invalid number of uses for registration token: "+err.Error(), 500)
return
}

if uses <= 0 {
http.Error(w, "invalid number of uses for registration token: "+usesString, 400)
return
}

resp := control.RegistrationResult{Token: token, Username: username, Groups: groups, NumUses: uses}

tokenType := "registration"
if overwrite != "" {
tokenType = "overwrite"
}

if token != "" {
err := data.AddRegistrationToken(token, username, overwrite, groups)
err := data.AddRegistrationToken(token, username, overwrite, groups, uses)
if err != nil {
http.Error(w, err.Error(), 500)
return
Expand All @@ -98,7 +111,7 @@ func newRegistration(w http.ResponseWriter, r *http.Request) {
return
}

token, err = data.GenerateToken(username, overwrite, groups)
token, err = data.GenerateToken(username, overwrite, groups, uses)
if err != nil {
http.Error(w, err.Error(), 500)
return
Expand Down
6 changes: 4 additions & 2 deletions pkg/control/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,10 @@ func StartControlSocket() error {
return err
}

if err := os.Chown(config.Values().Socket, -1, config.Values().GID); err != nil {
return err
if config.Values().GID != nil {
if err := os.Chown(config.Values().Socket, -1, *config.Values().GID); err != nil {
return err
}
}

log.Println("Started control socket: \n\t\t\t", config.Values().Socket)
Expand Down
1 change: 1 addition & 0 deletions pkg/control/shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ type RegistrationResult struct {
Username string
Groups []string
Overwrites string
NumUses int
}

type PolicyData struct {
Expand Down
8 changes: 7 additions & 1 deletion pkg/control/wagctl/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -526,12 +526,18 @@ func (c *CtrlClient) Registrations() (result []control.RegistrationResult, err e
return
}

func (c *CtrlClient) NewRegistration(token, username, overwrite string, groups ...string) (r control.RegistrationResult, err error) {
func (c *CtrlClient) NewRegistration(token, username, overwrite string, uses int, groups ...string) (r control.RegistrationResult, err error) {

if uses <= 0 {
err = errors.New("unable to create token with <= 0 uses")
return
}

form := url.Values{}
form.Add("username", username)
form.Add("token", token)
form.Add("overwrite", overwrite)
form.Add("uses", fmt.Sprintf("%d", uses))

for _, group := range groups {
if !strings.HasPrefix(group, "group:") {
Expand Down
9 changes: 8 additions & 1 deletion ui/src/js/tokens.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ $(function () {
sortable: true,
align: 'center',
escape: "true"
}, {
field: 'uses',
title: 'Uses',
sortable: true,
align: 'center',
escape: "true"
}
])

Expand Down Expand Up @@ -110,7 +116,8 @@ $(function () {
"username": $('#recipient-name').val(),
"token": $('#token').val(),
"overwrites": $('#overwrite').val(),
"groups": $('#groups').val()
"groups": $('#groups').val(),
"uses": ($("#uses").val() == "" ? "1" : $("#uses").val())
}

fetch("/management/registration_tokens/data", {
Expand Down
1 change: 1 addition & 0 deletions ui/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ type TokensData struct {
Username string `json:"username"`
Groups []string `json:"groups"`
Overwrites string `json:"overwrites"`
Uses int `json:"uses"`
}

type WgDevicesData struct {
Expand Down
5 changes: 5 additions & 0 deletions ui/templates/management/registration_tokens.html
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ <h5 class="modal-title" id="tokensModalLabel">New Registration Token</h5>
<input type="text" class="form-control" id="groups" name="overwrite" placeholder="(Optional)">
</div>

<div class="form-group">
<label for="uses" class="col-form-label">Number of Uses</label>
<input type="number" class="form-control" id="uses" name="uses" placeholder="1">
</div>

<div id="formIssue" class="alert alert-danger" role="alert" style="display:none"></div>

</form>
Expand Down
18 changes: 16 additions & 2 deletions ui/ui_webserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"log"
"net/http"
"os"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -1148,6 +1149,7 @@ func registrationTokens(w http.ResponseWriter, r *http.Request) {
Token: reg.Token,
Groups: reg.Groups,
Overwrites: reg.Overwrites,
Uses: reg.NumUses,
})
}

Expand Down Expand Up @@ -1184,12 +1186,24 @@ func registrationTokens(w http.ResponseWriter, r *http.Request) {
Token string
Overwrites string
Groups string
Uses string
}

defer r.Body.Close()
err := json.NewDecoder(r.Body).Decode(&b)
if err != nil {
http.Error(w, "Bad request", 400)
http.Error(w, err.Error(), 400)
return
}

uses, err := strconv.Atoi(b.Uses)
if err != nil {
http.Error(w, err.Error(), 400)
return
}

if uses <= 0 {
http.Error(w, "cannot create token with <= 0 uses", 400)
return
}

Expand All @@ -1198,7 +1212,7 @@ func registrationTokens(w http.ResponseWriter, r *http.Request) {
groups = strings.Split(b.Groups, ",")
}

_, err = ctrl.NewRegistration(b.Token, b.Username, b.Overwrites, groups...)
_, err = ctrl.NewRegistration(b.Token, b.Username, b.Overwrites, uses, groups...)
if err != nil {
http.Error(w, err.Error(), 400)
return
Expand Down

0 comments on commit 48881b8

Please sign in to comment.