mirror of
https://github.com/genuinetools/reg.git
synced 2024-08-20 13:50:23 -04:00
![Knut Ahlers](/assets/img/avatar_default.png)
Using a registry having basic auth enabled the authentication was not submitted to Clair. This newly introduced error fixes the missing auth but needs testing with non-basic auth protected registries. Also maybe the test for the "malformed auth..." string can now be removed as it does not trigger on registries with basic auth enabled? Signed-off-by: Knut Ahlers <knut@ahlers.me>
70 lines
1.5 KiB
Go
70 lines
1.5 KiB
Go
package registry
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
bearerRegex = regexp.MustCompile(
|
|
`^\s*Bearer\s+(.*)$`)
|
|
basicRegex = regexp.MustCompile(`^\s*Basic\s+.*$`)
|
|
)
|
|
|
|
func parseAuthHeader(header http.Header) (*authService, error) {
|
|
ch, err := parseChallenge(header.Get("www-authenticate"))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return ch, nil
|
|
}
|
|
|
|
func parseChallenge(challengeHeader string) (*authService, error) {
|
|
if basicRegex.MatchString(challengeHeader) {
|
|
return nil, fmt.Errorf("basic auth required")
|
|
}
|
|
|
|
match := bearerRegex.FindAllStringSubmatch(challengeHeader, -1)
|
|
if d := len(match); d != 1 {
|
|
return nil, fmt.Errorf("malformed auth challenge header: '%s', %d", challengeHeader, d)
|
|
}
|
|
parts := strings.SplitN(strings.TrimSpace(match[0][1]), ",", 3)
|
|
|
|
var realm, service string
|
|
var scope []string
|
|
for _, s := range parts {
|
|
p := strings.SplitN(s, "=", 2)
|
|
if len(p) != 2 {
|
|
return nil, fmt.Errorf("malformed auth challenge header: '%s'", challengeHeader)
|
|
}
|
|
key := p[0]
|
|
value := strings.TrimSuffix(strings.TrimPrefix(p[1], `"`), `"`)
|
|
switch key {
|
|
case "realm":
|
|
realm = value
|
|
case "service":
|
|
service = value
|
|
case "scope":
|
|
scope = strings.Fields(value)
|
|
default:
|
|
return nil, fmt.Errorf("unknown field in challege header %s: %v", key, challengeHeader)
|
|
}
|
|
}
|
|
parsedRealm, err := url.Parse(realm)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
a := &authService{
|
|
Realm: parsedRealm,
|
|
Service: service,
|
|
Scope: scope,
|
|
}
|
|
|
|
return a, nil
|
|
}
|