mirror of
https://github.com/jech/galene.git
synced 2024-12-22 15:25:48 +01:00
Reliably return an error from token.Parse.
We would sometimes return nil cast to an interface with no error, which would cause the server to crash with a null dereference.
This commit is contained in:
parent
dc8a78be32
commit
3c0dbf5e9b
4 changed files with 55 additions and 6 deletions
|
@ -120,7 +120,7 @@ func toStringArray(a []interface{}) ([]string, bool) {
|
|||
return b, true
|
||||
}
|
||||
|
||||
func parseJWT(token string, keys []map[string]interface{}) (Token, error) {
|
||||
func parseJWT(token string, keys []map[string]interface{}) (*JWT, error) {
|
||||
t, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) {
|
||||
return getKey(t.Header, keys)
|
||||
})
|
||||
|
|
|
@ -55,11 +55,14 @@ func SetStatefulFilename(filename string) {
|
|||
tokens.modTime = time.Time{}
|
||||
}
|
||||
|
||||
func getStateful(token string) (Token, error) {
|
||||
func getStateful(token string) (*Stateful, error) {
|
||||
tokens.mu.Lock()
|
||||
defer tokens.mu.Unlock()
|
||||
err := tokens.load()
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if tokens.tokens == nil {
|
||||
|
|
|
@ -2,6 +2,7 @@ package token
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
)
|
||||
|
||||
var ErrUsernameRequired = errors.New("username required")
|
||||
|
@ -11,9 +12,23 @@ type Token interface {
|
|||
}
|
||||
|
||||
func Parse(token string, keys []map[string]interface{}) (Token, error) {
|
||||
t, err := getStateful(token)
|
||||
if err == nil && t != nil {
|
||||
return t, nil
|
||||
// both getStateful and parseJWT may return nil, which we
|
||||
// shouldn't cast into an interface. Be very careful.
|
||||
s, err1 := getStateful(token)
|
||||
if err1 == nil && s != nil {
|
||||
return s, nil
|
||||
}
|
||||
|
||||
jwt, err2 := parseJWT(token, keys)
|
||||
if err2 == nil && jwt != nil {
|
||||
return jwt, nil
|
||||
}
|
||||
|
||||
if err1 != nil {
|
||||
return nil, err1
|
||||
} else if err2 != nil {
|
||||
return nil, err2
|
||||
} else {
|
||||
return nil, os.ErrNotExist
|
||||
}
|
||||
return parseJWT(token, keys)
|
||||
}
|
||||
|
|
31
token/token_test.go
Normal file
31
token/token_test.go
Normal file
|
@ -0,0 +1,31 @@
|
|||
package token
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"path/filepath"
|
||||
"os"
|
||||
)
|
||||
|
||||
func TestBad(t *testing.T) {
|
||||
d := t.TempDir()
|
||||
tokens = state{
|
||||
filename: filepath.Join(d, "test.jsonl"),
|
||||
}
|
||||
f, err := os.OpenFile(tokens.filename,
|
||||
os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("Create: %v", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
token, err := Parse("foo", nil)
|
||||
if err == nil {
|
||||
t.Errorf("Expected error, got %v", token)
|
||||
}
|
||||
|
||||
token, err = Parse("foo", []map[string]interface{}{})
|
||||
if err == nil {
|
||||
t.Errorf("Expected error, got %v", token)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue