Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
34cec5c
Introduce IndexedKeySet
massar Feb 16, 2017
7a6c5a0
Typo fix: Wether -> Whether
massar Feb 16, 2017
3672b4f
Typo fix: Overriden -> Overridden
massar Feb 16, 2017
29dd820
Merge branch 'issue_82' of github.com:tridentli/pitchfork into issue_91
massar Feb 16, 2017
b6fd5d0
Typo fix: occured -> occurred
massar Feb 16, 2017
adc448b
Merge branch 'DEV_1.4.6' of github.com:tridentli/pitchfork into issue_91
massar Feb 23, 2017
f464db4
Merge branch 'DEV_1.4.6' into issue_91
bapril Feb 24, 2017
647ccba
Add iptrk_max, jwt_timeout and loginattempts_max configuration settin…
massar Mar 14, 2017
c282370
Only belongs in trident, thus moved there
massar Mar 15, 2017
904fc8b
Fix PGP download link
wesdawg Jun 30, 2017
64c1066
Update ui.go
wesdawg Sep 2, 2017
bf9e999
For tick/1961 - add ARF files as possible uploads to the wiki.
morrowc Sep 12, 2017
dd3476c
Merge pull request #147 from tridentli/pf_59
bapril Sep 24, 2017
d136de6
Only belongs in trident, thus moved there
massar Mar 15, 2017
aa47eb8
Merge branch 'tr_93' of github.com:tridentli/pitchfork into tr_93
bapril Sep 24, 2017
001d6ed
Merge pull request #148 from tridentli/tr_93
bapril Sep 24, 2017
bcdd494
Merge pull request #163 from wesdawg/ui-typo-fix
bapril Sep 24, 2017
97cbb51
Merge pull request #160 from wesdawg/patch-1
bapril Sep 24, 2017
8e93731
Bump changelog
bapril Sep 24, 2017
15bf5de
For tick/1961 - add ARF files as possible uploads to the wiki.
morrowc Sep 12, 2017
712790a
Merge branch 'fix_file' of github.com:tridentli/pitchfork into fix_file
bapril Sep 24, 2017
2cfc396
Bump changelog
bapril Sep 24, 2017
1e50080
Merge pull request #164 from tridentli/fix_file
bapril Sep 24, 2017
2f0bff3
Indentation fixups
massar Feb 10, 2017
26aa629
Ensure that the confroot path ends in a slash
massar Feb 14, 2017
e17f990
The big documentation run
massar Feb 15, 2017
4128519
Add 'header' pftype, use that for PW_comment, fix fieldset CSS, put s…
massar Feb 15, 2017
aee47ba
Indent the SQL query properly and do not filter when that is requested
massar Feb 16, 2017
5174426
Indent the SQL append properly
massar Feb 16, 2017
754f4f0
Reference the correct variable
massar Feb 16, 2017
84c8dc3
Introduce IndexedKeySet
massar Feb 16, 2017
0ae04f4
Typo fix: Wether -> Whether
massar Feb 16, 2017
8cb5d8e
Typo fix: Overriden -> Overridden
massar Feb 16, 2017
8e11e25
One more trailing verboseOutput
massar Feb 16, 2017
84cb82c
Typo fix: occured -> occurred
massar Feb 16, 2017
e93ebee
Add closing quote to tag
massar Feb 21, 2017
db25930
Print the message into the string so that it actually gets returned
massar Feb 16, 2017
91bff1f
Update example's name so that go knows it is a secondary example
massar Feb 21, 2017
dbafbdc
Page_show -> PageShow
massar Feb 21, 2017
1c8bb65
Revert logic inversion https://github.com/tridentli/pitchfork/commit/…
massar Feb 23, 2017
e8ddc8e
Update 'header' tag to 'widenote' which represents better what it is …
massar Feb 24, 2017
7564ed7
Merge branch 'issue_91' of github.com:tridentli/pitchfork into issue_91
bapril Sep 25, 2017
9fe99b1
Introduce IndexedKeySet
massar Feb 16, 2017
84b70b8
Typo fix: Wether -> Whether
massar Feb 16, 2017
1e2a699
Typo fix: Overriden -> Overridden
massar Feb 16, 2017
064c3e2
Typo fix: occured -> occurred
massar Feb 16, 2017
b453e9a
Merge branch 'issue_91' of github.com:tridentli/pitchfork into issue_91
bapril Sep 25, 2017
576bfb4
Can't have 2 fields with the same name, moved one sysadmin field to c…
bapril Sep 25, 2017
ec70d2b
revert cansysadmin -> sysadmin
bapril Sep 25, 2017
3407ae2
renaming other sysadmin field.
bapril Sep 25, 2017
445d9bc
move pfcol back to sysadmin
bapril Sep 26, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
pitchfork (1.9.5+i91) stable; urgency=medium

* #82 Documentation work.
* #84 Page_Show -> PageShow.
* #88 SQL Cleanup.
* #72 Add dep for pitchfork-data package.
* (PF59) Make iptrk, jet timeout and login attempts config variables.
* (T97) Group Member Vouch overview shows wrong affiliation.
* (T93) Add a note in UI and email about the characters used in the recovery token
* (PF Merge 163) Typo Fix by wesdawg
* (PF Merge 160) Fix PGP download link by wesdawg
* Support ARF files.
* (Issue 91) Fix toggle of sysadmin.

-- Ben April <bapril@ops-trust.net> Sun, 24 Sep 2017 00:46:15 -0400

pitchfork (1.9.4) stable; urgency=medium

* (PF65) Update login min length to be a config value along with example username.
Expand Down
110 changes: 67 additions & 43 deletions lib/cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,55 +5,59 @@ import (
"bufio"
"encoding/json"
"errors"
"fmt"
"net"
"os"
"strings"
)

// PfConfig contains the configuration details for the system, as loaded from the configuration file
type PfConfig struct {
Conf_root string `` /* From command line option or default setting */
File_roots []string `json:"file_roots"` /* Where we look for files */
Var_root string `json:"var_root"` /* Where variable files are stored */
Tmp_roots []string `json:"tmp_roots"` /* Templates */
LogFile string `json:"logfile"` /* Where to write our log file (with logrotate support) */
Token_prv interface{} `` // Private portion of the JWT Token
Token_pub interface{} `` // Public portion of the JWT Token
UserAgent string `json:"useragent"` // The HTTP and SMTP/Email user agent to use when contacting other servers
CSS []string `json:"css"` // The CSS files to load (HTML meta header)
Javascript []string `json:"javascript"` // The javascript libraries to load (HTML meta header)
CSP string `json:"csp"` // The Content-Security-Protection HTTP header we include in our output
XFF []string `json:"xff_trusted_cidr"` // The CIDR prefixes that are trusted X-Forwarded-For networks
XFFc []*net.IPNet `` // Cached parsed version of X-Forward-For configuration
Db_host string `json:"db_host"` // The database hostname
Db_port string `json:"db_port"` // The database port
Db_name string `json:"db_name"` // The database name
Db_user string `json:"db_user"` // The database user
Db_pass string `json:"db_pass"` // The database password
Db_ssl_mode string `json:"db_ssl_mode"` // The database SSL mode (require|ignore)
Db_admin_db string `json:"db_admin_db"` // The database name used for administrative actions
Db_admin_user string `json:"db_admin_user"` // The database user used for administrative actions
Db_admin_pass string `json:"db_admin_pass"` // The database password used for administrative actions
Nodename string `json:"nodename"` // Name of this node (typically matches the hostname and automatically set by program)
Http_host string `json:"http_host"` // The Host on which we serve HTTP
Http_port string `json:"http_port"` // The port on which we serve HTTP
JWT_prv string `json:"jwt_key_prv"` // Private portion of the JWT Token
JWT_pub string `json:"jwt_key_pub"` // Public portion of the JWT Token
Application interface{} `json:"application"` // Application specific configuration see GetAppConfig() / GetAppConfigBool()
Username_regexp string `json:"username_regexp"` // Regular expression for filtering/rejecting usernames
UserHomeLinks bool `json:"user_home_links"` // If User Home Links are active
SMTP_host string `json:"smtp_host"` // SMTP Host to use for outbound emails
SMTP_port string `json:"smtp_port"` // SMTP Port to use for outbound emails
SMTP_SSL string `json:"smtp_ssl"` // Whether to require SSL for outbound emails (ignore|require)
Msg_mon_from string `json:"msg_monitor_from"` // Email address used for From: for monitoring messages (messages module)
Msg_mon_to string `json:"msg_monitor_to"` // Email address used for To: for monitoring messages (messages module)
TimeFormat string `json:"timeformat"` // Time Format
DateFormat string `json:"dateformat"` // Date Format
PW_WeakDicts []string `json:"pw_weakdicts"` // List of filenames containing password dictionaries
CFG_UserMinLen string `json:"username_min_length"` // Minimum Username length
CFG_UserExample string `json:"username_example"` // Username Example
TransDefault string `json:"translation_default"` // Translation - Default Language
TransLanguages []string `json:"translation_languages"` // Translation - Available Languages
Conf_root string `` /* From command line option or default setting */
File_roots []string `json:"file_roots"` /* Where we look for files */
Var_root string `json:"var_root"` /* Where variable files are stored */
Tmp_roots []string `json:"tmp_roots"` /* Templates */
LogFile string `json:"logfile"` /* Where to write our log file (with logrotate support) */
Token_prv interface{} `` // Private portion of the JWT Token
Token_pub interface{} `` // Public portion of the JWT Token
UserAgent string `json:"useragent"` // The HTTP and SMTP/Email user agent to use when contacting other servers
CSS []string `json:"css"` // The CSS files to load (HTML meta header)
Javascript []string `json:"javascript"` // The javascript libraries to load (HTML meta header)
CSP string `json:"csp"` // The Content-Security-Protection HTTP header we include in our output
XFF []string `json:"xff_trusted_cidr"` // The CIDR prefixes that are trusted X-Forwarded-For networks
XFFc []*net.IPNet `` // Cached parsed version of X-Forward-For configuration
Db_host string `json:"db_host"` // The database hostname
Db_port string `json:"db_port"` // The database port
Db_name string `json:"db_name"` // The database name
Db_user string `json:"db_user"` // The database user
Db_pass string `json:"db_pass"` // The database password
Db_ssl_mode string `json:"db_ssl_mode"` // The database SSL mode (require|ignore)
Db_admin_db string `json:"db_admin_db"` // The database name used for administrative actions
Db_admin_user string `json:"db_admin_user"` // The database user used for administrative actions
Db_admin_pass string `json:"db_admin_pass"` // The database password used for administrative actions
Nodename string `json:"nodename"` // Name of this node (typically matches the hostname and automatically set by program)
Http_host string `json:"http_host"` // The Host on which we serve HTTP
Http_port string `json:"http_port"` // The port on which we serve HTTP
JWT_prv string `json:"jwt_key_prv"` // Private portion of the JWT Token
JWT_pub string `json:"jwt_key_pub"` // Public portion of the JWT Token
Application interface{} `json:"application"` // Application specific configuration see GetAppConfig() / GetAppConfigBool()
Username_regexp string `json:"username_regexp"` // Regular expression for filtering/rejecting usernames
UserHomeLinks bool `json:"user_home_links"` // If User Home Links are active
SMTP_host string `json:"smtp_host"` // SMTP Host to use for outbound emails
SMTP_port string `json:"smtp_port"` // SMTP Port to use for outbound emails
SMTP_SSL string `json:"smtp_ssl"` // Whether to require SSL for outbound emails (ignore|require)
Msg_mon_from string `json:"msg_monitor_from"` // Email address used for From: for monitoring messages (messages module)
Msg_mon_to string `json:"msg_monitor_to"` // Email address used for To: for monitoring messages (messages module)
TimeFormat string `json:"timeformat"` // Time Format
DateFormat string `json:"dateformat"` // Date Format
PW_WeakDicts []string `json:"pw_weakdicts"` // List of filenames containing password dictionaries
CFG_UserMinLen string `json:"username_min_length"` // Minimum Username length
CFG_UserExample string `json:"username_example"` // Username Example
TransDefault string `json:"translation_default"` // Translation - Default Language
TransLanguages []string `json:"translation_languages"` // Translation - Available Languages
IPTrkMax int `json:"iptrk_max"` /* Maximum IPTrk count, before being locked out */
JWTTimeout int `json:"jwt_timeout"` /* JWT Timeout in minutes */
LoginAttemptsMax int `json:"loginattempts_max"` /* Maximum Login attempts (tracked and checked per-account) */
}

/* SMTP_SSL = ignore | require */
Expand Down Expand Up @@ -143,6 +147,9 @@ func (cfg *PfConfig) Load(toolname string, confroot string) (err error) {
/* Defaults */
Config.Conf_root = confroot
Config.UserHomeLinks = true
Config.IPTrkMax = 100
Config.JWTTimeout = 30
Config.LoginAttemptsMax = 5

/* Open the configuration file */
fn := Config.Conf_root + toolname + ".conf"
Expand Down Expand Up @@ -271,7 +278,24 @@ func (cfg *PfConfig) Load(toolname string, confroot string) (err error) {
Config.DateFormat = "2006-01-02"
}

/* Check that the configuration is sane */
/* Verify IPtrk count is minimum value */
if Config.IPTrkMax <= 1 {
err = fmt.Errorf("iptrk_max set to %d but that would lock everybody out after one failed attempt, minimum is 1", Config.IPTrkMax)
return
}

/* Verify JWT is at least long enough for people to be logged in for a bit */
if Config.JWTTimeout < 5 {
err = fmt.Errorf("jwt_timeout set to %d which is too short for a useable session", Config.JWTTimeout)
return
}

if Config.LoginAttemptsMax < 1 {
err = fmt.Errorf("loginattempts_max set to %d which would mean nobody could ever login, please configure it above 1", Config.LoginAttemptsMax)
return
}

/* Check that XFF are sane & pre-parse it */
for _, x := range Config.XFF {
var xc *net.IPNet

Expand Down
4 changes: 2 additions & 2 deletions lib/ctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,7 @@ func (ctx *PfCtxS) IsLoggedIn() bool {
}

// IsGroupMember can be used to check if the selected user
// is a member of the selected group and wether the user
// is a member of the selected group and whether the user
// can see the group.
func (ctx *PfCtxS) IsGroupMember() bool {
if !ctx.HasSelectedUser() {
Expand All @@ -798,7 +798,7 @@ func (ctx *PfCtxS) IsGroupMember() bool {
return true
}

/* Normal group users, it depends on wether they can see them */
/* Normal group users, it depends on whether they can see them */
return state.can_see
}

Expand Down
1 change: 1 addition & 0 deletions lib/file.go
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ func file_mimetype(path string) (mt string, err error) {

/* Quick lookup of our own to guarantee that these types are supported */
types := map[string]string{
"arf": "application/octet-stream",
"doc": "application/msword",
"docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"html": "text/html",
Expand Down
9 changes: 5 additions & 4 deletions lib/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package pitchfork

import (
"errors"
pfpgp "trident.li/pitchfork/lib/pgp"
)

const (
Expand All @@ -23,7 +24,7 @@ type PfGroup interface {
Select(ctx PfCtx, group_name string, perms Perm) (err error)
GetGroups(ctx PfCtx, username string) (groups []PfGroupMember, err error)
GetGroupsAll() (groups []PfGroupMember, err error)
GetKeys(ctx PfCtx, keyset map[[16]byte][]byte) (err error)
GetKeys(ctx PfCtx, keyset *pfpgp.IndexedKeySet) (err error)
IsMember(user string) (ismember bool, isadmin bool, out PfMemberState, err error)
ListGroupMembersTot(search string) (total int, err error)
ListGroupMembers(search string, username string, offset int, max int, nominated bool, inclhidden bool, exact bool) (members []PfGroupMember, err error)
Expand Down Expand Up @@ -226,7 +227,7 @@ func (grp *PfGroupS) GetGroupsAll() (members []PfGroupMember, err error) {
}

// GetKeys returns the keyfile for a group
func (grp *PfGroupS) GetKeys(ctx PfCtx, keyset map[[16]byte][]byte) (err error) {
func (grp *PfGroupS) GetKeys(ctx PfCtx, keyset *pfpgp.IndexedKeySet) (err error) {
var ml PfML
mls, err := ml.ListWithUser(ctx, grp, ctx.SelectedUser())
if err != nil {
Expand All @@ -251,8 +252,8 @@ func (grp *PfGroupS) GetKeys(ctx PfCtx, keyset map[[16]byte][]byte) (err error)

mlist := ctx.SelectedML()

/* Get the ML List Key */
err = mlist.GetKey(ctx, keyset)
/* Get the ML List Keys */
err = mlist.GetKeys(ctx, keyset)
if err != nil {
return err
}
Expand Down
14 changes: 7 additions & 7 deletions lib/ml.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
package pitchfork

import (
"crypto/md5"
"errors"

pfpgp "trident.li/pitchfork/lib/pgp"
Expand Down Expand Up @@ -307,7 +306,7 @@ func (ml *PfML) ListWithUser(ctx PfCtx, grp PfGroup, user PfUser) (mls []PfML, e
}

// GetKeys returns the keys for a given mailinglist.
func (ml *PfML) GetKey(ctx PfCtx, keyset map[[16]byte][]byte) (err error) {
func (ml *PfML) GetKeys(ctx PfCtx, keyset *pfpgp.IndexedKeySet) (err error) {
var key string

q := "SELECT COALESCE(pubkey, '') " +
Expand All @@ -322,11 +321,11 @@ func (ml *PfML) GetKey(ctx PfCtx, keyset map[[16]byte][]byte) (err error) {

/* Only append a list key when it exists */
if key != "" {
keyset[md5.Sum([]byte(key))] = []byte(key)
keyset.Add(key)
}

/* List active members/collect keys */
err = ListKeys(ctx, keyset, ml.GroupName, ml.ListName)
err = ml.ListKeys(ctx, keyset)
if err != nil {
return
}
Expand Down Expand Up @@ -402,7 +401,7 @@ func ml_member_list(ctx PfCtx, args []string) (err error) {
}

// ListKeys returns the keys for a mailinglist.
func ListKeys(ctx PfCtx, keyset map[[16]byte][]byte, gr_name string, ml_name string) (err error) {
func (ml *PfML) ListKeys(ctx PfCtx, keyset *pfpgp.IndexedKeySet) (err error) {
q := "SELECT me.keyring " +
"FROM member_email me, " +
"member_mailinglist ml, " +
Expand All @@ -415,7 +414,7 @@ func ListKeys(ctx PfCtx, keyset map[[16]byte][]byte, gr_name string, ml_name str
" AND ml.trustgroup = $1 " +
" AND ml.lhs = $2"

rows, err := DB.Query(q, gr_name, ml_name)
rows, err := DB.Query(q, ml.GroupName, ml.ListName)
if err != nil {
return
}
Expand All @@ -429,7 +428,8 @@ func ListKeys(ctx PfCtx, keyset map[[16]byte][]byte, gr_name string, ml_name str
if err != nil {
return
}
keyset[md5.Sum([]byte(key))] = []byte(key)

keyset.Add(key)
}
return
}
Expand Down
49 changes: 49 additions & 0 deletions lib/pgp/keyset.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package pfpgp

import (
"crypto/sha256"
)

// The index is SHA256 hashed, thus the index is 16 bytes wide.
const IndexedKeySetHashSize = sha256.Size

// IndexedKeySet is used to sort PGP keys and add them in a
// unique way to avoid keys to be listed multiple times.
//
// We SHA256 each key to only allow a key to be added once.
type IndexedKeySet struct {
keys map[[IndexedKeySetHashSize]byte][]byte
}

// NewIndexedKeySet creates a new IndexedKeySet.
func NewIndexedKeySet() *IndexedKeySet {
return &IndexedKeySet{make(map[[IndexedKeySetHashSize]byte][]byte)}
}

// Add can be used to add a key to the IndexedKeySet.
//
// The 'key' provided is a full ASCII formatted PGP PUBLIC KEY block.
//
// A SHA256 is used to hash the key to avoid duplicates of the exact same key.
func (keyset *IndexedKeySet) Add(key string) {
bkey := []byte(key)

keyset.keys[sha256.Sum256(bkey)] = bkey
}

// ToBytes converts the keyset into ASCII output.
//
// Unix-style newlines (LF-only) are added in between
// the keys to keep them separate in the output.
func (keyset *IndexedKeySet) ToBytes() (output []byte) {
// Add each key in the set
for k := range keyset.keys {
// Add the key
output = append(output, keyset.keys[k][:]...)

// Add a \n (LF)
output = append(output, byte(0x0a))
}

return
}
4 changes: 2 additions & 2 deletions lib/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ func Setup(toolname string, confroot string, verbosedb bool, app_schema_version
// Starts starts background services.
func Starts() {
/* Start IP Tracker -- against brute force login attempts */
Iptrk_start(5, 10*time.Hour, "1 hour")
Iptrk_start(Config.IPTrkMax, 10*time.Hour, "1 hour")

/* Start JWT Invalidation caching/clearing */
JwtInv_start(30 * time.Minute)
JwtInv_start(time.Duration(Config.JWTTimeout) * time.Minute)
}

// Stops stops background services, should be matching and thus deferred after a Starts() call.
Expand Down
9 changes: 5 additions & 4 deletions lib/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"time"

"github.com/pborman/uuid"
pfpgp "trident.li/pitchfork/lib/pgp"
)

// Standardized error messages
Expand Down Expand Up @@ -61,7 +62,7 @@ type PfUser interface {
SharedGroups(ctx PfCtx, otheruser PfUser) (ok bool, err error)
GetImage(ctx PfCtx) (img []byte, err error)
GetHideEmail() (hide_email bool)
GetKeys(ctx PfCtx, keyset map[[16]byte][]byte) (err error)
GetKeys(ctx PfCtx, keyset *pfpgp.IndexedKeySet) (err error)
GetDetails() (details []PfUserDetail, err error)
GetLanguages() (languages []PfUserLanguage, err error)
Get(what string) (val string, err error)
Expand Down Expand Up @@ -100,7 +101,7 @@ type PfUserS struct {
Telephone string `label:"Telephone" pftype:"tel" pfset:"self" pfget:"user_view" pfcol:"tel_info" hint:"The phone number where to contact the user using voice messages"`
Airport string `label:"Airport" min:"3" max:"3" pfset:"self" pfget:"user_view" hint:"Closest airport for this user"`
Biography string `label:"Biography" pftype:"text" pfset:"self" pfget:"user_view" pfcol:"bio_info" hint:"Biography for this user"`
IsSysadmin bool `label:"System Administrator" pfset:"sysadmin" pfget:"group_admin" pfskipfailperm:"yes" pfcol:"sysadmin" hint:"Wether the user is a System Administrator"`
IsSysadmin bool `label:"System Administrator" pfset:"sysadmin" pfget:"group_admin" pfskipfailperm:"yes" pfcol:"sysadmin" hint:"Whether the user is a System Administrator"`
CanBeSysadmin bool `label:"Can Be System Administrator" pfset:"nobody" pfget:"nobody" pfskipfailperm:"yes" pfcol:"sysadmin" hint:"If the user can toggle between Regular and SysAdmin usermode"`
LoginAttempts int `label:"Number of failed Login Attempts" pfset:"self,group_admin" pfget:"group_admin" pfskipfailperm:"yes" pfcol:"login_attempts" hint:"How many failed login attempts have been registered"`
No_email bool `label:"Email Disabled" pfset:"sysadmin" pfget:"self,group_admin" pfskipfailperm:"yes" hint:"Email address is disabled due to SMTP errors"`
Expand Down Expand Up @@ -437,7 +438,7 @@ func (user *PfUserS) GetHideEmail() (hide_email bool) {
return user.Hide_email
}

func (user *PfUserS) GetKeys(ctx PfCtx, keyset map[[16]byte][]byte) (err error) {
func (user *PfUserS) GetKeys(ctx PfCtx, keyset *pfpgp.IndexedKeySet) (err error) {
groups, err := user.GetGroups(ctx)
if err != nil {
return
Expand Down Expand Up @@ -585,7 +586,7 @@ func (user *PfUserS) CheckAuth(ctx PfCtx, username string, password string, twof
return
}

if user.LoginAttempts > 5 {
if user.LoginAttempts > Config.LoginAttemptsMax {
err = errors.New("Too many login attempts for this account")
return
}
Expand Down
Loading