mirror of
https://github.com/glauth/glauth.git
synced 2026-10-25 05:30:47 +00:00
Stronger, salted paswords using bcrypt. (#195)
This commit is contained in:
committed by
GitHub
parent
25a1648706
commit
9c197cc35e
@@ -82,6 +82,11 @@ Here's a sample config wth hardcoded users and groups:
|
||||
primarygroup = 5501
|
||||
passsha256 = "6478579e37aff45f013e14eeb30b3cc56c72ccdc310123bcdf53e0333e3f416a" # dogood
|
||||
sshkeys = [ "ssh-dss AAAAB3..." ]
|
||||
[[users]]
|
||||
name = "uberhackers"
|
||||
unixid = 5006
|
||||
primarygroup = 5501
|
||||
passbcrypt = "243261243130244B62463462656F7265504F762E794F324957746D656541326B4B46596275674A79336A476845764B616D65446169784E41384F4432" # dogood
|
||||
[[groups]]
|
||||
name = "superheros"
|
||||
unixid = 5501
|
||||
@@ -141,6 +146,10 @@ More configuration options are documented here: https://github.com/glauth/glauth
|
||||
* Specify OTP secret used to validate OTP passcode
|
||||
* Example: 3hnvnk4ycv44glzigd6s25j4dougs3rk
|
||||
* default = blank
|
||||
* passappbcrypt
|
||||
* Specify an array of app passwords which can also succesfully bind - these bypass the OTP check. Hash the same way as password.
|
||||
* Example: ["c32255dbf6fd6b64883ec8801f793bccfa2a860f2b1ae1315cd95cdac1338efa","4939efa7c87095dacb5e7e8b8cfb3a660fa1f5edcc9108f6d7ec20ea4d6b3a88"]
|
||||
* default = blank
|
||||
* passappsha256
|
||||
* Specify an array of app passwords which can also succesfully bind - these bypass the OTP check. Hash the same way as password.
|
||||
* Example: ["c32255dbf6fd6b64883ec8801f793bccfa2a860f2b1ae1315cd95cdac1338efa","4939efa7c87095dacb5e7e8b8cfb3a660fa1f5edcc9108f6d7ec20ea4d6b3a88"]
|
||||
@@ -153,6 +162,9 @@ More configuration options are documented here: https://github.com/glauth/glauth
|
||||
### OpenSSH keys:
|
||||
GLAuth can store a user's SSH authorized keys. Add one or more keys per user as shown above, then setup the goklp helper: https://github.com/appliedtrust/goklp
|
||||
|
||||
### Strong Passwords
|
||||
If you are currently using sha256 passwords (`passsha256` or `passappsha256`) moving to strong, salted paswords is recommended. Simply switch to `passbcrypt` and/or `passappbcrypt` password types. Currently (2021) 2<sup>12</sup> is a reasonably good value, depending our your server's CPU.
|
||||
|
||||
### Two Factor Authentication
|
||||
GLAuth can be configured to accept OTP tokens as appended to a users password. Support is added for both **TOTP tokens** (often known by it's most prominent implementation, "Google Authenticator") and **Yubikey OTP tokens**.
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ require (
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
||||
github.com/pquerna/otp v1.3.0
|
||||
github.com/yaegashi/msgraph.go v0.1.1-0.20200221123608-2d438cf2a7cc
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
|
||||
gopkg.in/amz.v3 v3.0.0-20201001071545-24fc1eceb27b
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
|
||||
)
|
||||
|
||||
@@ -51,14 +51,23 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/yaegashi/msgraph.go v0.1.1-0.20200221123608-2d438cf2a7cc h1:ejaC8rvIvCWmsaFrvmGOxhBuMxxhBB1xRshuM98XQ7M=
|
||||
github.com/yaegashi/msgraph.go v0.1.1-0.20200221123608-2d438cf2a7cc/go.mod h1:tso14hwzqX4VbnWTNsxiL0DvMb2OwbGISFA7jDibdWc=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 h1:L2auWcuQIvxz9xSEqzESnV/QN/gNRXNApHi3fYwl2w0=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
gopkg.in/amz.v3 v3.0.0-20201001071545-24fc1eceb27b h1:tdSyAzD5FHJmZAZ13d5WexAo7YJkiyGphhzFfInMnDw=
|
||||
gopkg.in/amz.v3 v3.0.0-20201001071545-24fc1eceb27b/go.mod h1:cE0dCGx2UfBTjLFlzEx4EXJUmoX6BXBoX9GjKOvqha4=
|
||||
|
||||
@@ -51,7 +51,9 @@ type User struct {
|
||||
Name string
|
||||
OtherGroups []int
|
||||
PassSHA256 string
|
||||
PassBcrypt string
|
||||
PassAppSHA256 []string
|
||||
PassAppBcrypt []string
|
||||
PrimaryGroup int
|
||||
SSHKeys []string
|
||||
OTPSecret string
|
||||
|
||||
+46
-20
@@ -19,6 +19,7 @@ import (
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/nmcclain/ldap"
|
||||
"github.com/pquerna/otp/totp"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
var configattributematcher = regexp.MustCompile(`(?i)\((?P<attribute>[a-zA-Z0-9]+)\s*=\s*(?P<value>.*)\)`)
|
||||
@@ -129,9 +130,7 @@ func (h configHandler) Bind(bindDN, bindSimplePw string, conn net.Conn) (resultC
|
||||
|
||||
// Store the full bind password provided before possibly modifying
|
||||
// in the otp check
|
||||
// Generate a hash of the provided password
|
||||
hashFull := sha256.New()
|
||||
hashFull.Write([]byte(bindSimplePw))
|
||||
untouchedBindSimplePw := bindSimplePw
|
||||
|
||||
// Test OTP if exists
|
||||
if len(user.OTPSecret) > 0 && !validotp {
|
||||
@@ -146,21 +145,33 @@ func (h configHandler) Bind(bindDN, bindSimplePw string, conn net.Conn) (resultC
|
||||
// finally, validate user's pw
|
||||
|
||||
// check app passwords first
|
||||
for index, appPw := range user.PassAppSHA256 {
|
||||
|
||||
if appPw != hex.EncodeToString(hashFull.Sum(nil)) {
|
||||
h.log.V(6).Info("Attempt to bind app pw failed", "index", index, "binddn", bindDN, "src", conn.RemoteAddr())
|
||||
} else {
|
||||
stats.Frontend.Add("bind_successes", 1)
|
||||
h.log.V(6).Info("Bind success using app pw", "index", index, "binddn", bindDN, "src", conn.RemoteAddr())
|
||||
return ldap.LDAPResultSuccess, nil
|
||||
if user.PassAppBcrypt != nil {
|
||||
for index, appPw := range user.PassAppBcrypt {
|
||||
decoded, err := hex.DecodeString(appPw)
|
||||
if err != nil {
|
||||
h.log.V(6).Info("invalid app credentials", "incorrect stored hash", "(omitted)")
|
||||
} else {
|
||||
if bcrypt.CompareHashAndPassword(decoded, []byte(untouchedBindSimplePw)) == nil {
|
||||
stats.Frontend.Add("bind_successes", 1)
|
||||
h.log.V(6).Info("Bind success using app pw", "index", index, "binddn", bindDN, "src", conn.RemoteAddr())
|
||||
return ldap.LDAPResultSuccess, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if user.PassAppSHA256 != nil {
|
||||
hashFull := sha256.New()
|
||||
hashFull.Write([]byte(untouchedBindSimplePw))
|
||||
for index, appPw := range user.PassAppSHA256 {
|
||||
if appPw != hex.EncodeToString(hashFull.Sum(nil)) {
|
||||
h.log.V(6).Info("Attempt to bind app pw failed", "index", index, "binddn", bindDN, "src", conn.RemoteAddr())
|
||||
} else {
|
||||
stats.Frontend.Add("bind_successes", 1)
|
||||
h.log.V(6).Info("Bind success using app pw", "index", index, "binddn", bindDN, "src", conn.RemoteAddr())
|
||||
return ldap.LDAPResultSuccess, nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// then check main password with the hash
|
||||
hash := sha256.New()
|
||||
hash.Write([]byte(bindSimplePw))
|
||||
|
||||
// Then ensure the OTP is valid before checking
|
||||
if !validotp {
|
||||
@@ -168,10 +179,25 @@ func (h configHandler) Bind(bindDN, bindSimplePw string, conn net.Conn) (resultC
|
||||
return ldap.LDAPResultInvalidCredentials, nil
|
||||
}
|
||||
|
||||
// Now, check the hash
|
||||
if user.PassSHA256 != hex.EncodeToString(hash.Sum(nil)) {
|
||||
h.log.V(2).Info("invalid credentials", "binddn", bindDN, "src", conn.RemoteAddr())
|
||||
return ldap.LDAPResultInvalidCredentials, nil
|
||||
// Now, check the pasword hash
|
||||
if user.PassBcrypt != "" {
|
||||
decoded, err := hex.DecodeString(user.PassBcrypt)
|
||||
if err != nil {
|
||||
h.log.V(2).Info("invalid credentials", "incorrect stored hash", "(omitted)")
|
||||
return ldap.LDAPResultInvalidCredentials, nil
|
||||
}
|
||||
if bcrypt.CompareHashAndPassword(decoded, []byte(bindSimplePw)) != nil {
|
||||
h.log.V(2).Info("invalid credentials", "binddn", bindDN, "src", conn.RemoteAddr())
|
||||
return ldap.LDAPResultInvalidCredentials, nil
|
||||
}
|
||||
}
|
||||
if user.PassSHA256 != "" {
|
||||
hash := sha256.New()
|
||||
hash.Write([]byte(bindSimplePw))
|
||||
if user.PassSHA256 != hex.EncodeToString(hash.Sum(nil)) {
|
||||
h.log.V(2).Info("invalid credentials", "binddn", bindDN, "src", conn.RemoteAddr())
|
||||
return ldap.LDAPResultInvalidCredentials, nil
|
||||
}
|
||||
}
|
||||
|
||||
stats.Frontend.Add("bind_successes", 1)
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/nmcclain/ldap"
|
||||
"github.com/pquerna/otp/totp"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
type SqlBackend interface {
|
||||
@@ -111,9 +112,9 @@ func (h databaseHandler) Bind(bindDN, bindSimplePw string, conn net.Conn) (resul
|
||||
// find the user
|
||||
user := config.User{}
|
||||
err = h.database.cnx.QueryRow(fmt.Sprintf(`
|
||||
SELECT u.unixid,u.primarygroup,u.passsha256,u.otpsecret,u.yubikey
|
||||
SELECT u.unixid,u.primarygroup,u.passbcrypt,u.passsha256,u.otpsecret,u.yubikey
|
||||
FROM users u WHERE lower(u.name)=%s`, h.sqlBackend.GetPrepareSymbol()), userName).Scan(
|
||||
&user.UnixID, &user.PrimaryGroup, &user.PassSHA256, &user.OTPSecret, &user.Yubikey)
|
||||
&user.UnixID, &user.PrimaryGroup, &user.PassBcrypt, &user.PassSHA256, &user.OTPSecret, &user.Yubikey)
|
||||
if err != nil {
|
||||
h.log.V(2).Info(fmt.Sprintf("Bind Error: User %s not found.", userName))
|
||||
return ldap.LDAPResultInvalidCredentials, nil
|
||||
@@ -157,9 +158,7 @@ func (h databaseHandler) Bind(bindDN, bindSimplePw string, conn net.Conn) (resul
|
||||
|
||||
// Store the full bind password provided before possibly modifying
|
||||
// in the otp check
|
||||
// Generate a hash of the provided password
|
||||
hashFull := sha256.New()
|
||||
hashFull.Write([]byte(bindSimplePw))
|
||||
untouchedBindSimplePw := bindSimplePw
|
||||
|
||||
// Test OTP if exists
|
||||
if len(user.OTPSecret) > 0 && !validotp {
|
||||
@@ -174,21 +173,33 @@ func (h databaseHandler) Bind(bindDN, bindSimplePw string, conn net.Conn) (resul
|
||||
// finally, validate user's pw
|
||||
|
||||
// check app passwords first
|
||||
for index, appPw := range user.PassAppSHA256 {
|
||||
|
||||
if appPw != hex.EncodeToString(hashFull.Sum(nil)) {
|
||||
h.log.V(2).Info(fmt.Sprintf("Attempted to bind app pw #%d - failure as %s from %s", index, bindDN, conn.RemoteAddr().String()))
|
||||
} else {
|
||||
stats.Frontend.Add("bind_successes", 1)
|
||||
h.log.V(3).Info("Bind success using app pw #%d as %s from %s", index, bindDN, conn.RemoteAddr().String())
|
||||
return ldap.LDAPResultSuccess, nil
|
||||
if user.PassAppBcrypt != nil {
|
||||
for index, appPw := range user.PassAppBcrypt {
|
||||
decoded, err := hex.DecodeString(appPw)
|
||||
if err != nil {
|
||||
h.log.V(6).Info("invalid app credentials", "incorrect stored hash", "(omitted)")
|
||||
} else {
|
||||
if bcrypt.CompareHashAndPassword(decoded, []byte(untouchedBindSimplePw)) == nil {
|
||||
stats.Frontend.Add("bind_successes", 1)
|
||||
h.log.V(6).Info("Bind success using app pw", "index", index, "binddn", bindDN, "src", conn.RemoteAddr())
|
||||
return ldap.LDAPResultSuccess, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if user.PassAppSHA256 != nil {
|
||||
hashFull := sha256.New()
|
||||
hashFull.Write([]byte(untouchedBindSimplePw))
|
||||
for index, appPw := range user.PassAppSHA256 {
|
||||
if appPw != hex.EncodeToString(hashFull.Sum(nil)) {
|
||||
h.log.V(2).Info(fmt.Sprintf("Attempted to bind app pw #%d - failure as %s from %s", index, bindDN, conn.RemoteAddr().String()))
|
||||
} else {
|
||||
stats.Frontend.Add("bind_successes", 1)
|
||||
h.log.V(3).Info("Bind success using app pw #%d as %s from %s", index, bindDN, conn.RemoteAddr().String())
|
||||
return ldap.LDAPResultSuccess, nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// then check main password with the hash
|
||||
hash := sha256.New()
|
||||
hash.Write([]byte(bindSimplePw))
|
||||
|
||||
// Then ensure the OTP is valid before checking
|
||||
if !validotp {
|
||||
@@ -196,10 +207,25 @@ func (h databaseHandler) Bind(bindDN, bindSimplePw string, conn net.Conn) (resul
|
||||
return ldap.LDAPResultInvalidCredentials, nil
|
||||
}
|
||||
|
||||
// Now, check the hash
|
||||
if user.PassSHA256 != hex.EncodeToString(hash.Sum(nil)) {
|
||||
h.log.V(2).Info(fmt.Sprintf("Bind Error: invalid credentials as %s from %s", bindDN, conn.RemoteAddr().String()))
|
||||
return ldap.LDAPResultInvalidCredentials, nil
|
||||
// Now, check the password hash
|
||||
if user.PassBcrypt != "" {
|
||||
decoded, err := hex.DecodeString(user.PassBcrypt)
|
||||
if err != nil {
|
||||
h.log.V(2).Info("invalid credentials", "incorrect stored hash", "(omitted)")
|
||||
return ldap.LDAPResultInvalidCredentials, nil
|
||||
}
|
||||
if bcrypt.CompareHashAndPassword(decoded, []byte(bindSimplePw)) != nil {
|
||||
h.log.V(2).Info("invalid credentials", "binddn", bindDN, "src", conn.RemoteAddr())
|
||||
return ldap.LDAPResultInvalidCredentials, nil
|
||||
}
|
||||
}
|
||||
if user.PassSHA256 != "" {
|
||||
hash := sha256.New()
|
||||
hash.Write([]byte(bindSimplePw))
|
||||
if user.PassSHA256 != hex.EncodeToString(hash.Sum(nil)) {
|
||||
h.log.V(2).Info(fmt.Sprintf("Bind Error: invalid credentials as %s from %s", bindDN, conn.RemoteAddr().String()))
|
||||
return ldap.LDAPResultInvalidCredentials, nil
|
||||
}
|
||||
}
|
||||
|
||||
stats.Frontend.Add("bind_successes", 1)
|
||||
@@ -249,7 +275,7 @@ func (h databaseHandler) Search(bindDN string, searchReq ldap.SearchRequest, con
|
||||
}
|
||||
|
||||
rows, err := h.database.cnx.Query(`
|
||||
SELECT u.name,u.unixid,u.primarygroup,u.passsha256,u.otpsecret,u.yubikey,u.othergroups,u.givenname,u.sn,u.mail,u.loginshell,u.homedirectory,u.disabled
|
||||
SELECT u.name,u.unixid,u.primarygroup,u.passbcrypt,u.passsha256,u.otpsecret,u.yubikey,u.othergroups,u.givenname,u.sn,u.mail,u.loginshell,u.homedirectory,u.disabled
|
||||
FROM users u`)
|
||||
if err != nil {
|
||||
return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultOperationsError}, fmt.Errorf("Search Error: Unable to retrieve data [%s]", err.Error())
|
||||
@@ -260,7 +286,7 @@ func (h databaseHandler) Search(bindDN string, searchReq ldap.SearchRequest, con
|
||||
var disabled int
|
||||
u := config.User{}
|
||||
for rows.Next() {
|
||||
err := rows.Scan(&u.Name, &u.UnixID, &u.PrimaryGroup, &u.PassSHA256, &u.OTPSecret, &u.Yubikey, &otherGroups, &u.GivenName, &u.SN, &u.Mail, &u.LoginShell, &u.Homedir, &disabled)
|
||||
err := rows.Scan(&u.Name, &u.UnixID, &u.PrimaryGroup, &u.PassBcrypt, &u.PassSHA256, &u.OTPSecret, &u.Yubikey, &otherGroups, &u.GivenName, &u.SN, &u.Mail, &u.LoginShell, &u.Homedir, &disabled)
|
||||
if err != nil {
|
||||
return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultOperationsError}, fmt.Errorf("Search Error: Unable to retrieve data [%s]", err.Error())
|
||||
}
|
||||
@@ -295,9 +321,9 @@ func (h databaseHandler) FindUser(userName string) (f bool, u config.User, err e
|
||||
found := false
|
||||
|
||||
err = h.database.cnx.QueryRow(fmt.Sprintf(`
|
||||
SELECT u.unixid,u.primarygroup,u.passsha256,u.otpsecret,u.yubikey
|
||||
SELECT u.unixid,u.primarygroup,u.passbcrypt,u.passsha256,u.otpsecret,u.yubikey
|
||||
FROM users u WHERE lower(u.name)=%s`, h.sqlBackend.GetPrepareSymbol()), userName).Scan(
|
||||
&user.UnixID, &user.PrimaryGroup, &user.PassSHA256, &user.OTPSecret, &user.Yubikey)
|
||||
&user.UnixID, &user.PrimaryGroup, &user.PassBcrypt, &user.PassSHA256, &user.OTPSecret, &user.Yubikey)
|
||||
if err == nil {
|
||||
found = true
|
||||
}
|
||||
@@ -377,7 +403,7 @@ func (h databaseHandler) getGroupMembers(gid int) []string {
|
||||
members := make(map[string]bool)
|
||||
|
||||
rows, err := h.database.cnx.Query(`
|
||||
SELECT u.name,u.unixid,u.primarygroup,u.passsha256,u.otpsecret,u.yubikey,u.othergroups
|
||||
SELECT u.name,u.unixid,u.primarygroup,u.passbcrypt,u.passsha256,u.otpsecret,u.yubikey,u.othergroups
|
||||
FROM users u WHERE lower(u.name)=?`,
|
||||
)
|
||||
if err != nil {
|
||||
@@ -389,7 +415,7 @@ func (h databaseHandler) getGroupMembers(gid int) []string {
|
||||
var otherGroups string
|
||||
u := config.User{}
|
||||
for rows.Next() {
|
||||
err := rows.Scan(&u.Name, &u.UnixID, &u.PrimaryGroup, &u.PassSHA256, &u.OTPSecret, &u.Yubikey, &otherGroups)
|
||||
err := rows.Scan(&u.Name, &u.UnixID, &u.PrimaryGroup, &u.PassBcrypt, &u.PassSHA256, &u.OTPSecret, &u.Yubikey, &otherGroups)
|
||||
if err != nil {
|
||||
return []string{}
|
||||
}
|
||||
@@ -435,7 +461,7 @@ func (h databaseHandler) getGroupMembers(gid int) []string {
|
||||
func (h databaseHandler) getGroupMemberIDs(gid int) []string {
|
||||
members := make(map[string]bool)
|
||||
rows, err := h.database.cnx.Query(`
|
||||
SELECT u.name,u.unixid,u.primarygroup,u.passsha256,u.otpsecret,u.yubikey,u.othergroups
|
||||
SELECT u.name,u.unixid,u.primarygroup,u.passbcrypt,u.passsha256,u.otpsecret,u.yubikey,u.othergroups
|
||||
FROM users u`)
|
||||
if err != nil {
|
||||
// Silent fail... for now
|
||||
@@ -446,7 +472,7 @@ func (h databaseHandler) getGroupMemberIDs(gid int) []string {
|
||||
var otherGroups string
|
||||
u := config.User{}
|
||||
for rows.Next() {
|
||||
err := rows.Scan(&u.Name, &u.UnixID, &u.PrimaryGroup, &u.PassSHA256, &u.OTPSecret, &u.Yubikey, &otherGroups)
|
||||
err := rows.Scan(&u.Name, &u.UnixID, &u.PrimaryGroup, &u.PassBcrypt, &u.PassSHA256, &u.OTPSecret, &u.Yubikey, &otherGroups)
|
||||
if err != nil {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ CREATE TABLE IF NOT EXISTS users (
|
||||
homedirectory VARCHAR(64) DEFAULT '',
|
||||
disabled SMALLINT DEFAULT 0,
|
||||
passsha256 VARCHAR(64) DEFAULT '',
|
||||
passbcrypt VARCHAR(64) DEFAULT '',
|
||||
otpsecret VARCHAR(64) DEFAULT '',
|
||||
yubikey VARCHAR(128) DEFAULT '')
|
||||
`)
|
||||
|
||||
@@ -40,6 +40,7 @@ CREATE TABLE IF NOT EXISTS users (
|
||||
homedirectory TEXT DEFAULT '',
|
||||
disabled SMALLINT DEFAULT 0,
|
||||
passsha256 TEXT DEFAULT '',
|
||||
passbcrypt TEXT DEFAULT '',
|
||||
otpsecret TEXT DEFAULT '',
|
||||
yubikey TEXT DEFAULT '')
|
||||
`)
|
||||
|
||||
@@ -40,6 +40,7 @@ CREATE TABLE IF NOT EXISTS users (
|
||||
homedirectory TEXT DEFAULT '',
|
||||
disabled SMALLINT DEFAULT 0,
|
||||
passsha256 TEXT DEFAULT '',
|
||||
passbcrypt TEXT DEFAULT '',
|
||||
otpsecret TEXT DEFAULT '',
|
||||
yubikey TEXT DEFAULT '')
|
||||
`)
|
||||
|
||||
@@ -86,6 +86,19 @@ debug = true
|
||||
otpsecret = "3hnvnk4ycv44glzigd6s25j4dougs3rk"
|
||||
yubikey = "vvjrcfalhlaa"
|
||||
|
||||
[[users]]
|
||||
name = "uberhackers"
|
||||
unixid = 5005
|
||||
primarygroup = 5501
|
||||
# bcrypt format: hex($2y$2^<number of rounds>$<salt>$<hash>)
|
||||
passappbcrypt = [
|
||||
"243261243130244B62463462656F7265504F762E794F324957746D656541326B4B46596275674A79336A476845764B616D65446169784E41384F4432" # dogood
|
||||
]
|
||||
# uncomment and comment out above array to test password with otp code
|
||||
# passappbcrypt = "243261243130244B62463462656F7265504F762E794F324957746D656541326B4B46596275674A79336A476845764B616D65446169784E41384F4432" # dogood
|
||||
otpsecret = "3hnvnk4ycv44glzigd6s25j4dougs3rk"
|
||||
|
||||
|
||||
#################
|
||||
# The groups section contains a hardcoded list of valid users.
|
||||
[[groups]]
|
||||
|
||||
Reference in New Issue
Block a user