Compare commits

...

6 commits

Author SHA1 Message Date
Eric Chiang
0a6c9e0984 Merge pull request #969 from ericchiang/cherry-pick-941
[cherry pick] server: fix localhost redirect validation for public clients
2017-06-15 10:06:53 -07:00
Eric Chiang
20c2ad5163 server: fix localhost redirect validation for public clients 2017-06-14 16:05:30 -07:00
rithu leena john
10253725de Merge pull request #7 from rithujohn191/ldap-password-check
connector/ldap: check for blank passwords and return error.
2017-05-01 17:06:55 -07:00
rithu leena john
65318da86e Merge pull request #6 from rithujohn191/api-resp-fic
server/api: return empty list of refresh tokens if user does not have any
2017-05-01 16:48:23 -07:00
rithu john
58eee98117 connector/ldap: check for blank passwords and return error. 2017-05-01 16:44:12 -07:00
rithu john
2dea454b26 server/api: return empty list of refresh tokens if user does not have any 2017-05-01 16:17:23 -07:00
4 changed files with 91 additions and 5 deletions

View file

@ -345,6 +345,11 @@ func (c *ldapConnector) userEntry(conn *ldap.Conn, username string) (user ldap.E
} }
func (c *ldapConnector) Login(ctx context.Context, s connector.Scopes, username, password string) (ident connector.Identity, validPass bool, err error) { func (c *ldapConnector) Login(ctx context.Context, s connector.Scopes, username, password string) (ident connector.Identity, validPass bool, err error) {
// make this check to avoid anonymous bind to the LDAP server.
if password == "" {
return connector.Identity{}, false, nil
}
var ( var (
// We want to return a different error if the user's password is incorrect vs // We want to return a different error if the user's password is incorrect vs
// if there was an error. // if there was an error.

View file

@ -215,13 +215,20 @@ func (d dexAPI) ListRefresh(ctx context.Context, req *api.ListRefreshReq) (*api.
return nil, err return nil, err
} }
var refreshTokenRefs []*api.RefreshTokenRef
offlineSessions, err := d.s.GetOfflineSessions(id.UserId, id.ConnId) offlineSessions, err := d.s.GetOfflineSessions(id.UserId, id.ConnId)
if err != nil { if err != nil {
d.logger.Errorf("api: failed to list refresh tokens: %v", err) if err == storage.ErrNotFound {
// This means that this user-client pair does not have a refresh token yet.
// An empty list should be returned instead of an error.
return &api.ListRefreshResp{
RefreshTokens: refreshTokenRefs,
}, nil
}
d.logger.Errorf("api: failed to list refresh tokens %t here : %v", err == storage.ErrNotFound, err)
return nil, err return nil, err
} }
var refreshTokenRefs []*api.RefreshTokenRef
for _, session := range offlineSessions.Refresh { for _, session := range offlineSessions.Refresh {
r := api.RefreshTokenRef{ r := api.RefreshTokenRef{
Id: session.ID, Id: session.ID,

View file

@ -12,6 +12,7 @@ import (
"fmt" "fmt"
"hash" "hash"
"io" "io"
"net"
"net/http" "net/http"
"net/url" "net/url"
"strconv" "strconv"
@ -518,9 +519,18 @@ func validateRedirectURI(client storage.Client, redirectURI string) bool {
if redirectURI == redirectURIOOB { if redirectURI == redirectURIOOB {
return true return true
} }
if !strings.HasPrefix(redirectURI, "http://localhost:") {
// verify that the host is of form "http://localhost:(port)(path)" or "http://localhost(path)"
u, err := url.Parse(redirectURI)
if err != nil {
return false return false
} }
n, err := strconv.Atoi(strings.TrimPrefix(redirectURI, "https://localhost:")) if u.Scheme != "http" {
return err == nil && n <= 0 return false
}
if u.Host == "localhost" {
return true
}
host, _, err := net.SplitHostPort(u.Host)
return err == nil && host == "localhost"
} }

View file

@ -195,3 +195,67 @@ func TestAccessTokenHash(t *testing.T) {
t.Errorf("expected %q got %q", googleAccessTokenHash, atHash) t.Errorf("expected %q got %q", googleAccessTokenHash, atHash)
} }
} }
func TestValidRedirectURI(t *testing.T) {
tests := []struct {
client storage.Client
redirectURI string
wantValid bool
}{
{
client: storage.Client{
RedirectURIs: []string{"http://foo.com/bar"},
},
redirectURI: "http://foo.com/bar",
wantValid: true,
},
{
client: storage.Client{
RedirectURIs: []string{"http://foo.com/bar"},
},
redirectURI: "http://foo.com/bar/baz",
},
{
client: storage.Client{
Public: true,
},
redirectURI: "urn:ietf:wg:oauth:2.0:oob",
wantValid: true,
},
{
client: storage.Client{
Public: true,
},
redirectURI: "http://localhost:8080/",
wantValid: true,
},
{
client: storage.Client{
Public: true,
},
redirectURI: "http://localhost:991/bar",
wantValid: true,
},
{
client: storage.Client{
Public: true,
},
redirectURI: "http://localhost",
wantValid: true,
},
{
client: storage.Client{
Public: true,
},
redirectURI: "http://localhost.localhost:8080/",
wantValid: false,
},
}
for _, test := range tests {
got := validateRedirectURI(test.client, test.redirectURI)
if got != test.wantValid {
t.Errorf("client=%#v, redirectURI=%q, wanted valid=%t, got=%t",
test.client, test.redirectURI, test.wantValid, got)
}
}
}