diff options
| author | Joe Tsai <joetsai@digital-static.net> | 2024-01-11 15:23:52 -0800 |
|---|---|---|
| committer | Joe Tsai <joetsai@digital-static.net> | 2024-01-11 15:30:43 -0800 |
| commit | 2e20bd2ffe2098877ad44d5eed93a1820956d1e9 (patch) | |
| tree | 7472ed2a5ca5442b870a03ea41d8fd4b835a4154 /util/httphdr/auth.go | |
| parent | b89c11336514d541ad25de564dcf0561c0b24e58 (diff) | |
| download | tailscale-dsnet/httpio.tar.xz tailscale-dsnet/httpio.zip | |
util/httpio: prototype design for handling I/O in HTTPdsnet/httpio
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Diffstat (limited to 'util/httphdr/auth.go')
| -rw-r--r-- | util/httphdr/auth.go | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/util/httphdr/auth.go b/util/httphdr/auth.go new file mode 100644 index 000000000..af81c9b3d --- /dev/null +++ b/util/httphdr/auth.go @@ -0,0 +1,81 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package httphdr + +import ( + "bytes" + "encoding/base64" + "fmt" + "strings" +) + +// TODO: Must authorization parameters be valid UTF-8? + +// AuthScheme is an authorization scheme per RFC 7235. +// Per section 2.1, the "Authorization" header is formatted as: +// +// Authorization: <auth-scheme> <auth-parameter> +// +// A scheme implementation must self-report the <auth-scheme> name and +// provide the ability to marshal and unmarshal the <auth-parameter>. +// +// For concrete implementations, see [Basic] and [Bearer]. +type AuthScheme interface { + // AuthScheme is the authorization scheme name. + // It must be valid according to RFC 7230, section 3.2.6. + AuthScheme() string + + // MarshalAuth marshals the authorization parameter for the scheme. + MarshalAuth() (string, error) + + // UnmarshalAuth unmarshals the authorization parameter for the scheme. + UnmarshalAuth(string) error +} + +// BasicAuth is the Basic authorization scheme as defined in RFC 2617. +type BasicAuth struct { + Username string // must not contain ':' per section 2 + Password string +} + +func (BasicAuth) AuthScheme() string { return "Basic" } + +func (a BasicAuth) MarshalAuth() (string, error) { + if strings.IndexByte(a.Username, ':') >= 0 { + return "", fmt.Errorf("invalid username: contains a colon") + } + return base64.StdEncoding.EncodeToString([]byte(a.Username + ":" + a.Password)), nil +} + +func (a *BasicAuth) UnmarshalAuth(s string) error { + b, err := base64.StdEncoding.DecodeString(s) + if err != nil { + return fmt.Errorf("invalid basic authorization: %w", err) + } + i := bytes.IndexByte(b, ':') + if i < 0 { + return fmt.Errorf("invalid basic authorization: missing a colon") + } + a.Username = string(b[:i]) + a.Password = string(b[i+len(":"):]) + return nil +} + +// BearerAuth is the Bearer Token authorization scheme as defined in RFC 6750. +type BearerAuth struct { + Token string // usually a base64-encoded string per section 2.1 +} + +func (BearerAuth) AuthScheme() string { return "Bearer" } + +func (a BearerAuth) MarshalAuth() (string, error) { + // TODO: Verify that token is valid base64? + return a.Token, nil +} + +func (a *BearerAuth) UnmarshalAuth(s string) error { + // TODO: Verify that token is valid base64? + a.Token = s + return nil +} |
