Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added callback-based request ID checking #581

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/crewjam/saml

go 1.19
go 1.23

require (
github.com/beevik/etree v1.2.0
Expand Down
17 changes: 10 additions & 7 deletions identity_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,17 +113,20 @@ type IdentityProvider struct {
func (idp *IdentityProvider) Metadata() *EntityDescriptor {
certStr := base64.StdEncoding.EncodeToString(idp.Certificate.Raw)

var validDuration time.Duration
if idp.ValidDuration != nil {
validDuration = *idp.ValidDuration
} else {
validDuration = DefaultValidDuration
var validUntil *time.Time

if idp.ValidDuration == nil {
// To avoid breaking backward compatibility, nil here means default
defaultValid := time.Now().Add(DefaultValidDuration)
validUntil = &defaultValid
} else if *(idp.ValidDuration) == METADATA_OMIT_VALID_UNTIL {
validUntil = nil
}

ed := &EntityDescriptor{
EntityID: idp.MetadataURL.String(),
ValidUntil: TimeNow().Add(validDuration),
CacheDuration: validDuration,
ValidUntil: validUntil,
CacheDuration: idp.ValidDuration,
IDPSSODescriptors: []IDPSSODescriptor{
{
SSODescriptor: SSODescriptor{
Expand Down
53 changes: 40 additions & 13 deletions metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ var Metadata = struct{}{}
//
// See http://docs.oasis-open.org/security/saml/v2.0/saml-metadata-2.0-os.pdf §2.3.2
type EntityDescriptor struct {
XMLName xml.Name `xml:"urn:oasis:names:tc:SAML:2.0:metadata EntityDescriptor"`
EntityID string `xml:"entityID,attr"`
ID string `xml:",attr,omitempty"`
ValidUntil time.Time `xml:"validUntil,attr,omitempty"`
CacheDuration time.Duration `xml:"cacheDuration,attr,omitempty"`
XMLName xml.Name `xml:"urn:oasis:names:tc:SAML:2.0:metadata EntityDescriptor"`
EntityID string `xml:"entityID,attr"`
ID string `xml:",attr,omitempty"`
ValidUntil *time.Time `xml:"validUntil,attr,omitempty"`
CacheDuration *time.Duration `xml:"cacheDuration,attr,omitempty"`
Signature *etree.Element
RoleDescriptors []RoleDescriptor `xml:"RoleDescriptor"`
IDPSSODescriptors []IDPSSODescriptor `xml:"IDPSSODescriptor"`
Expand All @@ -69,16 +69,31 @@ type EntityDescriptor struct {
AdditionalMetadataLocations []string `xml:"AdditionalMetadataLocation"`
}

const METADATA_OMIT_VALID_UNTIL = -1

// MarshalXML implements xml.Marshaler
func (m EntityDescriptor) MarshalXML(e *xml.Encoder, _ xml.StartElement) error {
type Alias EntityDescriptor
var rt *RelaxedTime

var cacheDuration *Duration
if m.CacheDuration != nil {
d := Duration(*m.CacheDuration)
cacheDuration = &d
}

if m.ValidUntil != nil {
rttemp := RelaxedTime(*m.ValidUntil)
rt = &rttemp
}

aux := &struct {
ValidUntil RelaxedTime `xml:"validUntil,attr,omitempty"`
CacheDuration Duration `xml:"cacheDuration,attr,omitempty"`
ValidUntil *RelaxedTime `xml:"validUntil,attr,omitempty"`
CacheDuration *Duration `xml:"cacheDuration,attr,omitempty"`
*Alias
}{
ValidUntil: RelaxedTime(m.ValidUntil),
CacheDuration: Duration(m.CacheDuration),
ValidUntil: rt,
CacheDuration: cacheDuration,
Alias: (*Alias)(&m),
}
return e.Encode(aux)
Expand All @@ -88,17 +103,29 @@ func (m EntityDescriptor) MarshalXML(e *xml.Encoder, _ xml.StartElement) error {
func (m *EntityDescriptor) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
type Alias EntityDescriptor
aux := &struct {
ValidUntil RelaxedTime `xml:"validUntil,attr,omitempty"`
CacheDuration Duration `xml:"cacheDuration,attr,omitempty"`
ValidUntil *RelaxedTime `xml:"validUntil,attr,omitempty"`
CacheDuration *Duration `xml:"cacheDuration,attr,omitempty"`
*Alias
}{
Alias: (*Alias)(m),
}
if err := d.DecodeElement(aux, &start); err != nil {
return err
}
m.ValidUntil = time.Time(aux.ValidUntil)
m.CacheDuration = time.Duration(aux.CacheDuration)

if aux.ValidUntil != nil {
t := time.Time(*aux.ValidUntil)
m.ValidUntil = &t
} else {
m.ValidUntil = nil
}

if aux.CacheDuration != nil {
d := time.Duration(*aux.CacheDuration)
m.CacheDuration = &d
} else {
m.ValidUntil = nil
}
return nil
}

Expand Down
14 changes: 14 additions & 0 deletions requestid.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package saml

type RequestIdCheckFunction func(string) bool

func createDefaultChecker(possibleRequestIDs []string) RequestIdCheckFunction {
return func(id string) bool {
for _, possibleRequestID := range possibleRequestIDs {
if id == possibleRequestID {
return true
}
}
return false
}
}
Loading
Loading