Skip to content

Commit

Permalink
Add starting work on multiple mfa devices
Browse files Browse the repository at this point in the history
  • Loading branch information
NHAS committed Jul 6, 2023
1 parent ccfa088 commit d28fd65
Show file tree
Hide file tree
Showing 10 changed files with 346 additions and 121 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ debug: .generate_ebpf .build_ui
release: .generate_ebpf .build_ui
go build -ldflags="$(LDFLAGS_RELEASE)"

go: .generate_ebpf
go build -ldflags="$(LDFLAGS_RELEASE)"

docker:
sudo docker run -u "$(ID):$(GID)" --rm -t -v `pwd`:/wag wag_builder

Expand Down
2 changes: 2 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ type Config struct {
Methods []string `json:",omitempty"`
DomainURL string

MaxMFAMethods int `json:",omitempty"`

OIDC struct {
IssuerURL string
ClientSecret string
Expand Down
10 changes: 0 additions & 10 deletions internal/data/devices.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,16 +153,6 @@ func DeleteDevice(username, id string) error {
return err
}

func DeleteDevices(username string) error {
_, err := database.Exec(`
DELETE FROM
Devices
WHERE
username = ?
`, username)
return err
}

func UpdateDevicePublicKey(username, address string, publicKey wgtypes.Key) error {
_, err := database.Exec(`
UPDATE
Expand Down
8 changes: 6 additions & 2 deletions internal/data/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (

"github.com/NHAS/wag/internal/data/migrations"
"github.com/NHAS/wag/pkg/fsops"
_ "github.com/mattn/go-sqlite3"
)

var (
Expand Down Expand Up @@ -41,5 +40,10 @@ func Load(path string) error {
}
}

return migrations.Do(db)
err = migrations.Do(db)
if err != nil {
return err
}

return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
-- version 10


-- Create temp table so the CASCADE DELETE is not triggered on table drop
CREATE TABLE IF NOT EXISTS temp (
id INTEGER primary key,
username string NOT NULL,
mfa_type string NOT NULL,
mfa string NOT NULL
);

INSERT INTO temp (username, mfa_type, mfa) SELECT username, mfa_type, mfa FROM Users;

-- Move MFA data to new table rather than keeping the field in the users table
ALTER TABLE Users RENAME TO Users_old;
CREATE TABLE Users ( username string primary key, enforcing string, locked BOOLEAN DEFAULT FALSE NOT NULL);
INSERT INTO Users (username, enforcing, locked) SELECT username, enforcing, locked FROM Users_old;
DROP TABLE Users_old;


CREATE TABLE IF NOT EXISTS MFA (
id INTEGER primary key,
username string NOT NULL,
mfa_type string NOT NULL,
mfa string NOT NULL,

FOREIGN KEY (username) references Users(username) ON DELETE CASCADE,

UNIQUE (username, mfa_type)
);

INSERT INTO MFA (username, mfa_type, mfa) SELECT username, mfa_type, mfa FROM temp;
DROP TABLE temp;



-- Start using foreign keys for devices too
ALTER TABLE Devices RENAME TO Devices_old;
CREATE TABLE Devices(
address string primary key,
username string not null,
publickey string not null unique,
endpoint string,
attempts integer DEFAULT 0 not null,

FOREIGN KEY (username) references Users(username) ON DELETE CASCADE
);

INSERT INTO Devices (address,username, publickey, endpoint, attempts) SELECT address, username, publickey, endpoint, attempts FROM Devices_old;
DROP TABLE Devices_old;
5 changes: 5 additions & 0 deletions internal/data/migrations/embed.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ func Do(db *sql.DB) error {
panic(err)
}

_, err = db.Exec("PRAGMA foreign_keys = ON;")
if err != nil {
return fmt.Errorf("unable to enable foreign_keys: %v", err)
}

var dbVersion int
err = db.QueryRow("PRAGMA user_version;").Scan(&dbVersion)
if err != nil {
Expand Down
149 changes: 77 additions & 72 deletions internal/data/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@ import (
"github.com/NHAS/wag/internal/config"
)

type MfaModel struct {
SensitiveDetails string
Type string
}

type UserModel struct {
Username string
Mfa string
MfaType string
Locked bool
Enforcing bool
Username string
MfaOptions []MfaModel
Locked bool
Enforcing bool
}

func (um *UserModel) GetID() [20]byte {
Expand All @@ -37,18 +41,22 @@ func IncrementAuthenticationAttempt(username, device string) error {
return nil
}

func GetAuthenticationDetails(username, device string) (mfa, mfaType string, attempts int, locked bool, err error) {
func GetAuthenticationDetails(username, device string) (mfaOptions []MfaModel, attempts int, locked bool, err error) {

err = database.QueryRow(`SELECT
mfa, mfa_type, attempts, locked
attempts,
locked
FROM
Users
INNER JOIN
Devices
ON
Users.username = Devices.username
INNER JOIN Devices
ON Users.username = Devices.username
WHERE
Devices.address = ? AND Users.username = ?`, device, username).Scan(&mfa, &mfaType, &attempts, &locked)
Devices.address = ? AND Users.username = ?`, device, username).Scan(&attempts, &locked)
if err != nil {
return
}

mfaOptions, err = GetMFAOptions(username)
if err != nil {
return
}
Expand Down Expand Up @@ -139,48 +147,27 @@ func SetEnforceMFAOff(username string) error {
return err
}

func GetMFASecret(username string) (string, error) {
var (
url, mfaType string
enforcing sql.NullString
)
err := database.QueryRow(`
SELECT
mfa, mfa_type, enforcing
FROM
Users
WHERE
username = ?
`, username).Scan(&url, &mfaType, &enforcing)
func GetMFAOptions(username string) (options []MfaModel, err error) {

rows, err := database.Query("SELECT mfa, mfa_type FROM MFA WHERE username = ?", username)
if err != nil {
return "", err
return nil, err
}

// The webauthn "secret" needs to be used, but isnt returned to the client
if enforcing.Valid && mfaType != "webauthn" {
return "", errors.New("MFA is set to enforcing, cannot reveal totp secret")
}
for rows.Next() {

return url, nil
}
var (
m MfaModel
)
err = rows.Scan(&m.SensitiveDetails, &m.Type)
if err != nil {
return nil, err
}

func GetMFAType(username string) (string, error) {
var (
mfaType string
)
err := database.QueryRow(`
SELECT
mfa_type
FROM
Users
WHERE
username = ?
`, username).Scan(&mfaType)
if err != nil {
return "", err
options = append(options, m)
}

return mfaType, nil
return options, nil
}

func DeleteUser(username string) error {
Expand All @@ -194,11 +181,7 @@ func DeleteUser(username string) error {
return err
}

_, err = database.Exec(`
DELETE FROM
Devices
WHERE
username = ?`, username)
// The devices and MFA entries will be cascade deleted

return err
}
Expand All @@ -209,15 +192,33 @@ func GetUserData(username string) (u UserModel, err error) {

err = database.QueryRow(`
SELECT
username, mfa, mfa_type, locked, enforcing
username, locked, enforcing
FROM
Users
WHERE
username = ?`, username).Scan(&u.Username, &u.Mfa, &u.MfaType, &u.Locked, &enforcing)
username = ?`, username).Scan(&u.Username, &u.Locked, &enforcing)
if err != nil {
return UserModel{}, err
}

rows, err := database.Query("SELECT mfa, mfa_type FROM MFA WHERE username = ?", username)
if err != nil {
return u, err
}

for rows.Next() {

var (
m MfaModel
)
err = rows.Scan(&m.SensitiveDetails, &m.Type)
if err != nil {
return u, err
}

u.MfaOptions = append(u.MfaOptions, m)
}

u.Enforcing = enforcing.Valid

return
Expand All @@ -240,28 +241,14 @@ func GetUserDataFromAddress(address string) (u UserModel, err error) {
return GetUserData(username)
}

func SetUserMfa(username, value, mfaType string) error {

_, err := database.Exec(`
UPDATE
Users
SET
mfa = ?, mfa_type = ?
WHERE
username = ?
`, value, mfaType, username)

return err
}

func CreateUserDataAccount(username string) (UserModel, error) {

//Leaves enforcing null
_, err := database.Exec(`
INSERT INTO
Users (username,mfa)
Users (username)
VALUES
(?,"")
(?)
`, username)

return UserModel{
Expand All @@ -271,7 +258,7 @@ func CreateUserDataAccount(username string) (UserModel, error) {

func GetAllUsers() (users []UserModel, err error) {

rows, err := database.Query("SELECT username, mfa, mfa_type, enforcing, locked FROM Users ORDER by ROWID DESC")
rows, err := database.Query("SELECT username, enforcing, locked FROM Users ORDER by ROWID DESC")
if err != nil {
return nil, err
}
Expand All @@ -282,13 +269,31 @@ func GetAllUsers() (users []UserModel, err error) {
enforcing sql.NullString
u UserModel
)
err = rows.Scan(&u.Username, &u.Mfa, &u.MfaType, &enforcing, &u.Locked)
err = rows.Scan(&u.Username, &enforcing, &u.Locked)
if err != nil {
return nil, err
}

u.Enforcing = enforcing.Valid

mfaRows, err := database.Query("SELECT mfa, mfa_type FROM MFA WHERE username = ?", u.Username)
if err != nil {
return nil, err
}

for mfaRows.Next() {

var (
m MfaModel
)
err = rows.Scan(&m.SensitiveDetails, &m.Type)
if err != nil {
return nil, err
}

u.MfaOptions = append(u.MfaOptions, m)
}

users = append(users, u)
}

Expand Down
Loading

0 comments on commit d28fd65

Please sign in to comment.