Documentation ¶
Overview ¶
Package authentication has mechanisms for authenticating users to Pullcord
Index ¶
- Constants
- func LoadPlugin()
- type CookiemaskFilter
- type InMemPwdStore
- type LoginHandler
- type MinSession
- func (sesh *MinSession) CookieMask(incomingCookies []*http.Cookie) (forwardedCookies []*http.Cookie, setCookies []*http.Cookie, err error)
- func (sesh *MinSession) GetValue(key string) (interface{}, error)
- func (sesh *MinSession) GetValues() map[string]interface{}
- func (sesh *MinSession) SetValue(key string, value interface{}) error
- type MinSessionHandler
- type PasswordChecker
- type Pbkdf2Hash
- type Session
- type SessionHandler
Constants ¶
const BadPasswordError = errors.New(
"The hash generated from the given password does not match the hash" +
" associated with the given identifier in the password store",
)
BadPasswordError is the error object that is returned if the given identifier (probably a username) does exist in the password store, but the given password does not generate a matching hash.
const IncorrectHashLengthError = errors.New(
"The base64 encoded hash does not decode to Pbkdf2KeyLength bytes",
)
IncorrectHashLengthError is the error object that is returned if the given base64 encoded hash does not decode to exactly Pbkdf2KeyLength bytes.
const IncorrectSaltLengthError = errors.New(
"The base64 encoded salt does not decode to Pbkdf2KeyLength bytes",
)
IncorrectSaltLengthError is the error object that is returned if the given base64 encoded salt does not decode to exactly Pbkdf2KeyLength bytes.
const InsufficientEntropyError = errors.New(
"The amount of entropy available from the operating system was not" +
" enough to generate a salt of length Pbkdf2KeyLength",
)
InsufficientEntropyError is the error object that is returned if the operating system does not have enough entropy to generated a random salt of length Pbkdf2KeyLength.
const InsufficientIterationsError = errors.New(
"The number of iterations must be at least Pbkdf2MinIterations",
)
InsufficientIterationsError is the error object that is returned if the requested number of iterations for a new PBKDF2 hash is less than Pbkdf2MinIterations.
const NoSuchIdentifierError = errors.New(
"The given identifier does not have an entry in the password store",
)
NoSuchIdentifierError is the error object that is returned if the given identifier (probably a username) does not exist in the password store.
It is considered best practice to not indicate to a possible attacker whether an authentication attempt failed due to a bad password or due to a non-existent user. However, while this implementation makes a few very modest attempts to reduce time-based information leakage, the way the identifier lookup process is implemented is likely to leak information about the presence of a user. Perhaps that issue will be fixed at a later time, but it is worth at least knowing for the time being.
const NoSuchSessionValueError = errors.New(
"The session does not have a the requested value",
)
NoSuchSessionValueError is the error constant that would be returned in the event that a given key requested from a Session using its GetValue function is not present in the session.
const Pbkdf2KeyLength = 64
Pbkdf2KeyLength is the length (in bytes) of the generated PBKDF2 hashes.
const Pbkdf2MinIterations = uint16(4096)
Pbkdf2MinIterations is the minimum number of iterations allowed for PBKDF2 hashes.
const XSRFTokenLength = 64
XSRFTokenLength is the length of XSRF token strings.
Variables ¶
This section is empty.
Functions ¶
func LoadPlugin ¶
func LoadPlugin()
LoadPlugin being called forces the package to be loaded in order to ensure that the resource types are registered during the package's Init.
Types ¶
type CookiemaskFilter ¶
type CookiemaskFilter struct { Handler SessionHandler Masked http.Handler }
CookiemaskFilter is a falcore.RequestFilter that will apply a "cookie mask" function before forwarding the (possibly modified) request to the next RequestFilter in the chain (which may ultimately lead to a proxy).
As HTTP clients typically have internal cookie managers sophisticated enough to send multiple cookies (with possibly different scopes or properties) with each request, we should be able to use our own cookies to keep track of state without exposing those cookies to any external application to which we may be proxying (since we have no guarantee that the presence of such cookies would not effect the behavior of such an external application). To that end, this function is given a cookie masking function which checks for any cookies intended to be received by the particular function, and potentially retrieves session information from some session handler to be forwarded down the RequestFilter chain as part of the context map. The cookie filter function returns the array of cookies which are not masked (and are to be allowed down the RequestFilter chain along with the rest of the original request), plus an array of any new cookies associated with this particular filter which are to be sent to the browser for storage (which should happen seamlessly as part of the next response), plus any session data which is to be forwarded down the RequestFilter chain as part of the context map, and of course a possible error (which will cause the onError RequestFilter chain to receive the context instead, with any new cookies still being added to the response, even though the onError chain will receive no cookies as part of the request).
func (*CookiemaskFilter) ServeHTTP ¶
func (f *CookiemaskFilter) ServeHTTP( w http.ResponseWriter, req *http.Request, )
FilterRequest implements the required function to allow CookiemaskFilter to be a falcore.RequestFilter.
func (*CookiemaskFilter) UnmarshalJSON ¶
func (f *CookiemaskFilter) UnmarshalJSON(input []byte) error
UnmarshalJSON implements encoding/json.Unmarshaler.
type InMemPwdStore ¶
type InMemPwdStore map[string]*Pbkdf2Hash
InMemPwdStore is a basic password store where all the identifiers and hash information are stored in memory. This would likely not be a useful password store implementation in a production environment, but it can be useful in testing. All passwords are hashed using PBKDF2 with SHA-256.
func (*InMemPwdStore) CheckPassword ¶
func (store *InMemPwdStore) CheckPassword(id, pass string) error
CheckPassword implements the required password checking function to make InMemPwdStore a PasswordChecker implementation.
func (*InMemPwdStore) UnmarshalJSON ¶
func (store *InMemPwdStore) UnmarshalJSON(input []byte) error
UnmarshalJSON implements encoding/json.Unmarshaler.
type LoginHandler ¶
type LoginHandler struct { Identifier string PasswordChecker PasswordChecker Downstream http.Handler }
LoginHandler is a login handling system that presents a login page backed by a PasswordChecker for users that are not yet logged in, while seamlessly forwarding all requests downstream for users that are logged in. A LoginHandler has an identifier (which it uses to differentiate its login tokens and authentication flags from other components, possibly including other LoginHandlers), a PasswordChecker (which it allows users to authenticate against in conjunction with its own XSRF token), and a downstream RequestFilter (possibly an entire pipeline).
func (*LoginHandler) ServeHTTP ¶
func (h *LoginHandler) ServeHTTP( w http.ResponseWriter, request *http.Request, )
func (*LoginHandler) UnmarshalJSON ¶
func (h *LoginHandler) UnmarshalJSON(input []byte) error
UnmarshalJSON implements encoding/json.Unmarshaler.
type MinSession ¶
type MinSession struct {
// contains filtered or unexported fields
}
MinSession represents a particular user session, and is intrinsically linked with the MinSessionHandler that created it.
func (*MinSession) CookieMask ¶
func (sesh *MinSession) CookieMask(incomingCookies []*http.Cookie) ( forwardedCookies []*http.Cookie, setCookies []*http.Cookie, err error, )
CookieMask for the MinSession is an implementation of the CookieMask function required by all Session derivatives.
func (*MinSession) GetValue ¶
func (sesh *MinSession) GetValue(key string) (interface{}, error)
GetValue looks up a value stored in the session for a given key. If the key did not match an existing saved value, an error will be returned.
func (*MinSession) GetValues ¶
func (sesh *MinSession) GetValues() map[string]interface{}
GetValues retrieves all the key/value pairs associated with the session.
func (*MinSession) SetValue ¶
func (sesh *MinSession) SetValue(key string, value interface{}) error
SetValue saves a key/value pair into the session, possibly overwriting a previously set value.
type MinSessionHandler ¶
type MinSessionHandler struct { Name string Path string Domain string // contains filtered or unexported fields }
MinSessionHandler is a somewhat minimalist form of a SessionHandler.
func NewMinSessionHandler ¶
func NewMinSessionHandler(name, path, domain string) *MinSessionHandler
NewMinSessionHandler creates an initialized session handler. Unfortunately a nil MinSessionHandler does not currently provide the desired behavior.
func (*MinSessionHandler) GetSession ¶
func (h *MinSessionHandler) GetSession() (Session, error)
GetSession generates a new session to track state with.
func (*MinSessionHandler) UnmarshalJSON ¶
func (h *MinSessionHandler) UnmarshalJSON(data []byte) error
UnmarshalJSON implements encoding/json.Unmarshaler.
type PasswordChecker ¶
PasswordChecker is an abstract interface describing any system which can check password (and presumably also store them in some way?).
CheckPassword is a function that takes some kind of identifier (likely a username, but perhaps something else) and a raw password and determines whether this combination is for an authorized entity, in which case an error is not returned. What other errors may be returned is not specified at this level, but it is possible that different errors indicating a bad password, a bad username, too many tries, or even a broken password checker could be returned. It is often not advisable to indicate to a user which particular reason a login failed, but it makes sense that an interface providing such specificity is a good idea, especially given that the granularity of errors could potentially be controlled through some configuration option.
type Pbkdf2Hash ¶
type Pbkdf2Hash struct { Hash [Pbkdf2KeyLength]byte Salt [Pbkdf2KeyLength]byte Iterations uint16 }
Pbkdf2Hash is a cryptogaphic hash generated by PBKDF2 using SHA-256 for an InMemPwdStore. The iteration count must be at least Pbkdf2MinIterations to be accepted by this implementation. The hash and salt must be standard base64 encoded (i.e. RFC 4648 with padding) byte arrays of length Pbkdf2KeyLength.
func GetPbkdf2Hash ¶
func GetPbkdf2Hash( password string, iterations uint16, ) (*Pbkdf2Hash, error)
GetPbkdf2Hash generates a new PBKDF2 hash in a secure way from a raw password and an iteration count.
func (*Pbkdf2Hash) Check ¶
func (hashStruct *Pbkdf2Hash) Check( password string, ) error
Check verifies that the given password yields the same PBKDF2 hash given the same salt and iteration count. It returns nil if the resulting hash matches, or an error if the resulting hash does not match.
func (*Pbkdf2Hash) MarshalJSON ¶
func (hashStruct *Pbkdf2Hash) MarshalJSON() ([]byte, error)
MarshalJSON implements encoding/json.Marshaler.
func (*Pbkdf2Hash) UnmarshalJSON ¶
func (hashStruct *Pbkdf2Hash) UnmarshalJSON(input []byte) error
UnmarshalJSON implements encoding/json.Unmarshaler.
type Session ¶
type Session interface { GetValue(key string) (value interface{}, err error) SetValue(key string, value interface{}) (err error) CookieMask(inCookies []*http.Cookie) ( fwdCookies []*http.Cookie, setCookies []*http.Cookie, err error, ) }
Session is an abstract interface that allows session-level data to not only be read at any point, but also be set at any point as well.
GetValue is a function that gives read access to the implicit key-value store of the Session.
SetValue is a function that gives write access to the implicit key-value store of the Session.
CookieMask is a function that takes a list of cookies received as part of a request and masks any of those cookies which may belong to the SessionHandler from all later RequestFilters and external services. All cookies which are not being masked will be returned as part of the forward cookies. If any cookies which belong to the SessionHandler are found, then the returned Session will have the data which had been set on the equivalent Session previously (as one would expect from a session). It is possible that the SessionHandler will also create new cookies which are to be added as "Set-cookie" headers in response to be sent back to the requester.
type SessionHandler ¶
SessionHandler is an abstract interface describing any system which tracks a user's state across requests using a combination of cookies, some kind of data store, and a way for various components of the RequestFilter chain to add data to that state information.
GetSession is a function that returns a Session implementation that will be managed by the SessionHandler. As the details of determining whether or not two Sessions are equivalent is the purview of a SessionHandler, the details of such possible comparisons and their implications are abstracted away by the Session's CookieMask call.