Commit 6d3a620e authored by ale's avatar ale

Update id/auth dependency

parent 45c4f032
Pipeline #4804 passed with stages
in 3 minutes and 25 seconds
...@@ -121,7 +121,29 @@ should specify the following attributes: ...@@ -121,7 +121,29 @@ should specify the following attributes:
only be applied to failed authentication requests only be applied to failed authentication requests
* `keys` is a list of strings specifying the request identifiers that * `keys` is a list of strings specifying the request identifiers that
will make up the rate limiter key. The list can include one or both will make up the rate limiter key. The list can include one or both
of *ip* (referring to the remote client's IP) and *user* (username) of *ip* (referring to the remote client's IP) and *user* (username).
* `bypass` is a list of criteria that will cause the request to skip
the enforcement of this ratelimit/blacklist. Criteria are objects
with `key` (one of *ip* or *user*) and *value* attributes, which
specify an exact equality match.
The following is an example of an IP-based ratelimit with blacklist
period of 1 hour, that will allow an arbitrary amount of requests from
localhost:
```yaml
rate_limits:
blacklist_10qps_1h:
limit: 100
period: 10
blacklist_for: 3600
keys: [ip]
bypass:
- key: ip
value: "127.0.0.1"
- key: ip
value: "::1"
```
## Service definition ## Service definition
...@@ -160,8 +182,10 @@ user, with the following attributes: ...@@ -160,8 +182,10 @@ user, with the following attributes:
* `name` is the username * `name` is the username
* `email` is the email associated with the user (optional) * `email` is the email associated with the user (optional)
* `password` stores the encrypted password * `password` stores the encrypted password, see *Password Encoding*
below for details on the supported algorithms etc.
* `totp_secret` stores the *unencrypted* TOTP secret seed * `totp_secret` stores the *unencrypted* TOTP secret seed
(base32-encoded)
* `u2f_registrations` is a list of U2F registrations with `key_handle` * `u2f_registrations` is a list of U2F registrations with `key_handle`
and `public_key` attributes, in the format used by *pamu2fcfg* (for and `public_key` attributes, in the format used by *pamu2fcfg* (for
convenience) convenience)
...@@ -209,8 +233,10 @@ LDAP attributes). The following attribute names are defined: ...@@ -209,8 +233,10 @@ LDAP attributes). The following attribute names are defined:
* `password` contains the encrypted password. Since this attribute is * `password` contains the encrypted password. Since this attribute is
often also used for authentication of the LDAP protocol itself, an often also used for authentication of the LDAP protocol itself, an
eventual `{crypt}` prefix is ignored. Passwords should be encrypted. eventual `{crypt}` prefix is ignored. Passwords should be encrypted,
* `otp_secret` should contain the hex-encoded TOTP secret see *Password Encoding* below for details on the supported
algorithms etc.
* `otp_secret` should contain the base32-encoded TOTP secret
* `app_specific_password` (possibly repeated) contains an encrypted * `app_specific_password` (possibly repeated) contains an encrypted
app-specific password app-specific password
...@@ -409,3 +435,28 @@ Responses will contain the following attributes: ...@@ -409,3 +435,28 @@ Responses will contain the following attributes:
* `email`: email of this user * `email`: email of this user
* `groups`: groups the user is a member of. * `groups`: groups the user is a member of.
### Password encoding
Multiple password hashing algorithms are supported. The format is the
well-known dollar-separated field string, extended with optional
algorithm-specific parameters:
```
$id[$params...]$salt$encrypted
```
where the optional *params* field is itself a dollar-separated list of
integers.
All *id* values understood by the libc *crypt(3)* function are
supported, as well as a few more custom algorithms:
* Scrypt (id `$s$`), in which case the parameters are *N*, *R* and
*P*.
* Argon2 (id `$a2$`), with parameters *time*, *memory* and
*threads*.
Check the documentation for these algorithms for an explanation of the
meaning of the parameters. Each algorithm has different requirements
for the salt.
...@@ -2,8 +2,11 @@ package client ...@@ -2,8 +2,11 @@ package client
import ( import (
"context" "context"
"net"
"net/textproto" "net/textproto"
"github.com/cenkalti/backoff"
"git.autistici.org/id/auth" "git.autistici.org/id/auth"
) )
...@@ -26,6 +29,23 @@ func New(socketPath string) Client { ...@@ -26,6 +29,23 @@ func New(socketPath string) Client {
} }
func (c *socketClient) Authenticate(ctx context.Context, req *auth.Request) (*auth.Response, error) { func (c *socketClient) Authenticate(ctx context.Context, req *auth.Request) (*auth.Response, error) {
// Retry the request, with backoff, if we get a temporary
// network error.
var resp *auth.Response
err := backoff.Retry(func() error {
var err error
resp, err = c.doAuthenticate(ctx, req)
if err == nil {
return nil
} else if netErr, ok := err.(net.Error); ok && netErr.Temporary() {
return netErr
}
return backoff.Permanent(err)
}, backoff.WithContext(backoff.NewExponentialBackOff(), ctx))
return resp, err
}
func (c *socketClient) doAuthenticate(ctx context.Context, req *auth.Request) (*auth.Response, error) {
// Create the connection outside of the timed goroutine, so // Create the connection outside of the timed goroutine, so
// that we can call Close() on exit regardless of the reason: // that we can call Close() on exit regardless of the reason:
// this way, when a timeout occurs or the context is canceled, // this way, when a timeout occurs or the context is canceled,
......
...@@ -148,7 +148,7 @@ func (i *inputScanner) parseQuotedString() (string, error) { ...@@ -148,7 +148,7 @@ func (i *inputScanner) parseQuotedString() (string, error) {
} }
func (i *inputScanner) parseBase64String() (string, error) { func (i *inputScanner) parseBase64String() (string, error) {
data := i.parseUntilOrEOF(' ') data := bytes.TrimRight(i.parseUntilOrEOF(' '), "=")
out := make([]byte, base64.RawURLEncoding.DecodedLen(len(data))) out := make([]byte, base64.RawURLEncoding.DecodedLen(len(data)))
_, err := base64.RawURLEncoding.Decode(out, data) _, err := base64.RawURLEncoding.Decode(out, data)
if err != nil { if err != nil {
......
...@@ -27,16 +27,16 @@ ...@@ -27,16 +27,16 @@
"revisionTime": "2019-06-30T08:30:15Z" "revisionTime": "2019-06-30T08:30:15Z"
}, },
{ {
"checksumSHA1": "T9WPwUls+LPk89st6TGCbQf5HNQ=", "checksumSHA1": "5WLGZjUV9Ly/rMdQwo9j8FJSlQA=",
"path": "git.autistici.org/id/auth", "path": "git.autistici.org/id/auth",
"revision": "5f6c4202ceac71349b414ab65b94f8e0f191c208", "revision": "ffc5d8791fd81d28fb2b0bce4540a10426a25124",
"revisionTime": "2019-05-24T11:03:32Z" "revisionTime": "2019-10-24T15:02:31Z"
}, },
{ {
"checksumSHA1": "Xd+uslNbKnbygNAhwAWQ2JVc6do=", "checksumSHA1": "3xM1BQ7kVyqn74GQz07uCBSNh2E=",
"path": "git.autistici.org/id/auth/client", "path": "git.autistici.org/id/auth/client",
"revision": "5f6c4202ceac71349b414ab65b94f8e0f191c208", "revision": "ffc5d8791fd81d28fb2b0bce4540a10426a25124",
"revisionTime": "2019-05-24T11:03:32Z" "revisionTime": "2019-10-24T15:02:31Z"
}, },
{ {
"checksumSHA1": "MlpsZgRytv/c9IX9YawRJDN/ibQ=", "checksumSHA1": "MlpsZgRytv/c9IX9YawRJDN/ibQ=",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment