Skip to content

Commit

Permalink
Add clear userlist on misconfigured basic auth #71
Browse files Browse the repository at this point in the history
  • Loading branch information
jcmoraisjr committed Dec 24, 2017
1 parent 240e9bf commit 56119eb
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 40 deletions.
59 changes: 32 additions & 27 deletions pkg/common/ingress/annotations/auth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package auth

import (
"fmt"
"github.com/golang/glog"
"io/ioutil"
"os"
"path"
Expand All @@ -40,19 +41,20 @@ const (
)

var (
authTypeRegex = regexp.MustCompile(`basic|digest`)
authTypeRegex = regexp.MustCompile(`^(basic)$`)
// AuthDirectory default directory used to store files
// to authenticate request
AuthDirectory = "/etc/ingress-controller/auth"
)

// BasicDigest returns authentication configuration for an Ingress rule
type BasicDigest struct {
Type string `json:"type"`
Realm string `json:"realm"`
File string `json:"file"`
Secured bool `json:"secured"`
FileSHA string `json:"fileSha"`
Type string `json:"type"`
Realm string `json:"realm"`
ListName string `json:"listName"`
File string `json:"file"`
Secured bool `json:"secured"`
FileSHA string `json:"fileSha"`
}

// Equal tests for equality between two BasicDigest types
Expand Down Expand Up @@ -118,35 +120,38 @@ func (a auth) Parse(ing *extensions.Ingress) (interface{}, error) {
return nil, ing_errors.NewLocationDenied("invalid authentication type")
}

s, err := parser.GetStringAnnotation(authSecret, ing)
if err != nil {
return nil, ing_errors.LocationDenied{
Reason: errors.Wrap(err, "error reading secret name from annotation"),
}
}

name := a.cfg.GetFullResourceName(s, ing.Namespace)
secret, err := a.secretResolver.GetSecret(name)
if err != nil {
return nil, ing_errors.LocationDenied{
Reason: errors.Wrapf(err, "unexpected error reading secret %v", name),
passFile := ""
listName := fmt.Sprintf("%v-%v", ing.GetNamespace(), ing.GetName())
if s, err := parser.GetStringAnnotation(authSecret, ing); err == nil {
name := a.cfg.GetFullResourceName(s, ing.Namespace)
if secret, err := a.secretResolver.GetSecret(name); err == nil {
passFile = fmt.Sprintf("%v/%v.passwd", a.authDirectory, listName)
err = dumpSecret(passFile, secret)
if err != nil {
glog.Errorf("unexpected error writing auth file %v: %v", passFile, err)
passFile = ""
}
} else {
glog.Errorf("unexpected error reading secret %v: %v", name, err)
}
} else {
glog.Errorf("error reading secret name from annotation: %v", err)
}

realm, _ := parser.GetStringAnnotation(authRealm, ing)

passFile := fmt.Sprintf("%v/%v-%v.passwd", a.authDirectory, ing.GetNamespace(), ing.GetName())
err = dumpSecret(passFile, secret)
if err != nil {
return nil, err
fileSHA := ""
if passFile != "" {
fileSHA = file.SHA1(passFile)
}

return &BasicDigest{
Type: at,
Realm: realm,
File: passFile,
Secured: true,
FileSHA: file.SHA1(passFile),
Type: at,
Realm: realm,
ListName: listName,
File: passFile,
Secured: true,
FileSHA: fileSHA,
}, nil
}

Expand Down
26 changes: 13 additions & 13 deletions pkg/controller/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ func (cfg *haConfig) newHAProxyLocations(server *ingress.Server) ([]*types.HAPro
for _, cidr := range location.RateLimit.Whitelist {
haLocation.HARateLimitWhiteList = haLocation.HARateLimitWhiteList + " " + cidr
}
if userList, ok := cfg.userlists[location.BasicDigestAuth.File]; ok {
if userList, ok := cfg.userlists[location.BasicDigestAuth.ListName]; ok {
haLocation.Userlist = userList
} else {
haLocation.Userlist = types.Userlist{}
Expand Down Expand Up @@ -248,20 +248,17 @@ func (cfg *haConfig) createUserlists() {
userlists := map[string]types.Userlist{}
for _, server := range cfg.ingress.Servers {
for _, location := range server.Locations {
listName := location.BasicDigestAuth.ListName
fileName := location.BasicDigestAuth.File
authType := location.BasicDigestAuth.Type
if fileName != "" && authType == "basic" {
_, ok := userlists[fileName]
if !ok {
slashPos := strings.LastIndex(fileName, "/")
dotPos := strings.LastIndex(fileName, ".")
listName := fileName[slashPos+1 : dotPos]
if authType == "basic" {
if _, ok := userlists[listName]; !ok {
users, err := readUsers(fileName, listName)
if err != nil {
glog.Errorf("Unexpected error reading %v: %v", listName, err)
break
glog.Errorf("unexpected error reading userlist %v: %v", listName, err)
users = []types.AuthUser{}
}
userlists[fileName] = types.Userlist{
userlists[listName] = types.Userlist{
ListName: listName,
Realm: location.BasicDigestAuth.Realm,
Users: users,
Expand All @@ -274,6 +271,9 @@ func (cfg *haConfig) createUserlists() {
}

func readUsers(fileName string, listName string) ([]types.AuthUser, error) {
if fileName == "" {
return []types.AuthUser{}, nil
}
file, err := os.Open(fileName)
if err != nil {
return nil, err
Expand All @@ -284,16 +284,16 @@ func readUsers(fileName string, listName string) ([]types.AuthUser, error) {
line := scanner.Text()
sep := strings.Index(line, ":")
if sep == -1 {
glog.Warningf("Missing ':' on userlist '%v'", listName)
glog.Warningf("missing ':' in userlist '%v'", listName)
break
}
userName := line[0:sep]
if userName == "" {
glog.Warningf("Missing username on userlist '%v'", listName)
glog.Warningf("missing username in userlist '%v'", listName)
break
}
if sep == len(line)-1 || line[sep:] == "::" {
glog.Warningf("Missing '%v' password on userlist '%v'", userName, listName)
glog.Warningf("missing '%v' password in userlist '%v'", userName, listName)
break
}
user := types.AuthUser{}
Expand Down

0 comments on commit 56119eb

Please sign in to comment.