mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2025-12-30 17:00:57 -06:00
Bump github.com/crewjam/saml from 0.4.13 to 0.4.14
Bumps [github.com/crewjam/saml](https://github.com/crewjam/saml) from 0.4.13 to 0.4.14. - [Commits](https://github.com/crewjam/saml/compare/v0.4.13...v0.4.14) --- updated-dependencies: - dependency-name: github.com/crewjam/saml dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
committed by
Ralf Haferkamp
parent
b5ad0796c4
commit
b3a92548b7
2
go.mod
2
go.mod
@@ -161,7 +161,7 @@ require (
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/crewjam/httperr v0.2.0 // indirect
|
||||
github.com/crewjam/saml v0.4.13 // indirect
|
||||
github.com/crewjam/saml v0.4.14 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/deckarep/golang-set v1.8.0 // indirect
|
||||
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
|
||||
|
||||
10
go.sum
10
go.sum
@@ -1011,15 +1011,14 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/crewjam/httperr v0.2.0 h1:b2BfXR8U3AlIHwNeFFvZ+BV1LFvKLlzMjzaTnZMybNo=
|
||||
github.com/crewjam/httperr v0.2.0/go.mod h1:Jlz+Sg/XqBQhyMjdDiC+GNNRzZTD7x39Gu3pglZ5oH4=
|
||||
github.com/crewjam/saml v0.4.13 h1:TYHggH/hwP7eArqiXSJUvtOPNzQDyQ7vwmwEqlFWhMc=
|
||||
github.com/crewjam/saml v0.4.13/go.mod h1:igEejV+fihTIlHXYP8zOec3V5A8y3lws5bQBFsTm4gA=
|
||||
github.com/crewjam/saml v0.4.14 h1:g9FBNx62osKusnFzs3QTN5L9CVA/Egfgm+stJShzw/c=
|
||||
github.com/crewjam/saml v0.4.14/go.mod h1:UVSZCf18jJkk6GpWNVqcyQJMD5HsRugBPf4I1nl2mME=
|
||||
github.com/cs3org/reva/v2 v2.16.1-0.20231012102459-2b27cd47ab72 h1:53M+ldLYQSxl/iJokKfOUmY0ntMhnATQu9cBZE1X53k=
|
||||
github.com/cs3org/reva/v2 v2.16.1-0.20231012102459-2b27cd47ab72/go.mod h1:6M5k4UvGUgZh31t4r70RwbesW+w2EM/gd/gpuQZxAPg=
|
||||
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dchest/uniuri v1.2.0/go.mod h1:fSzm4SLHzNZvWLvWJew423PhAzkpNQYq+uNLq4kxhkY=
|
||||
github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4=
|
||||
github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo=
|
||||
github.com/deepmap/oapi-codegen v1.3.11/go.mod h1:suMvK7+rKlx3+tpa8ByptmvoXbAV70wERKTOGH3hLp0=
|
||||
@@ -1264,7 +1263,6 @@ github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptG
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
@@ -1892,7 +1890,6 @@ github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c=
|
||||
github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w=
|
||||
github.com/russellhaering/goxmldsig v1.2.0/go.mod h1:gM4MDENBQf7M+V824SGfyIUVFWydB7n0KkEubVJl+Tw=
|
||||
github.com/russellhaering/goxmldsig v1.4.0 h1:8UcDh/xGyQiyrW+Fq5t8f+l2DLB1+zlhYzkPUJ7Qhys=
|
||||
github.com/russellhaering/goxmldsig v1.4.0/go.mod h1:gM4MDENBQf7M+V824SGfyIUVFWydB7n0KkEubVJl+Tw=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
@@ -2038,7 +2035,6 @@ github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
|
||||
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
|
||||
github.com/zenazn/goji v1.0.1/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
go-micro.dev/v4 v4.9.0 h1:pd1CpqMT9hA47jSmX8mfdGK865PkMh95Rwj5RdfqPqE=
|
||||
go-micro.dev/v4 v4.9.0/go.mod h1:Ju8HrZ5hQSF+QguZ2QUs9Kbe42MHP1tJa/fpP5g07Cs=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
@@ -2131,7 +2127,6 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220128200615-198e4374d7ed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||
@@ -2973,7 +2968,6 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
|
||||
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
||||
38
vendor/github.com/crewjam/saml/.golangci.yml
generated
vendored
38
vendor/github.com/crewjam/saml/.golangci.yml
generated
vendored
@@ -7,41 +7,35 @@
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- bodyclose # checks whether HTTP response body is closed successfully [fast: false, auto-fix: false]
|
||||
- errcheck # Inspects source code for security problems [fast: true, auto-fix: false]
|
||||
- gocritic # The most opinionated Go source code linter [fast: true, auto-fix: false]
|
||||
- gocyclo # Computes and checks the cyclomatic complexity of functions [fast: true, auto-fix: false]
|
||||
- gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification [fast: true, auto-fix: true]
|
||||
- goimports # Goimports does everything that gofmt does. Additionally it checks unused imports [fast: true, auto-fix: true]
|
||||
- gosec # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases [fast: true, auto-fix: false]
|
||||
- misspell # Finds commonly misspelled English words in comments [fast: true, auto-fix: true]
|
||||
- deadcode # Finds unused code [fast: true, auto-fix: false]
|
||||
- revive # Golint differs from gofmt. Gofmt reformats Go source code, whereas golint prints out style mistakes [fast: true, auto-fix: false]
|
||||
- unconvert # Remove unnecessary type conversions [fast: true, auto-fix: false]
|
||||
|
||||
disable:
|
||||
# TODO(ross): fix errors reported by these checkers and enable them
|
||||
- bodyclose # checks whether HTTP response body is closed successfully [fast: false, auto-fix: false]
|
||||
- depguard # Go linter that checks if package imports are in a list of acceptable packages [fast: true, auto-fix: false]
|
||||
- dupl # Tool for code clone detection [fast: true, auto-fix: false]
|
||||
- errcheck # Inspects source code for security problems [fast: true, auto-fix: false]
|
||||
- gochecknoglobals # Checks that no globals are present in Go code [fast: true, auto-fix: false]
|
||||
- gochecknoinits # Checks that no init functions are present in Go code [fast: true, auto-fix: false]
|
||||
- goconst # Finds repeated strings that could be replaced by a constant [fast: true, auto-fix: false]
|
||||
- gocritic # The most opinionated Go source code linter [fast: true, auto-fix: false]
|
||||
- gocyclo # Computes and checks the cyclomatic complexity of functions [fast: true, auto-fix: false]
|
||||
- gosimple # Linter for Go source code that specializes in simplifying a code [fast: false, auto-fix: false]
|
||||
- govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string [fast: false, auto-fix: false]
|
||||
- ineffassign # Detects when assignments to existing variables are not used [fast: true, auto-fix: false]
|
||||
- interfacer # Linter that suggests narrower interface types [fast: false, auto-fix: false]
|
||||
- lll # Reports long lines [fast: true, auto-fix: false]
|
||||
- maligned # Tool to detect Go structs that would take less memory if their fields were sorted [fast: true, auto-fix: false]
|
||||
- misspell # Finds commonly misspelled English words in comments [fast: true, auto-fix: true]
|
||||
- nakedret # Finds naked returns in functions greater than a specified function length [fast: true, auto-fix: false]
|
||||
- prealloc # Finds slice declarations that could potentially be preallocated [fast: true, auto-fix: false]
|
||||
- scopelint # Scopelint checks for unpinned variables in go programs [fast: true, auto-fix: false]
|
||||
- revive # Golint differs from gofmt. Gofmt reformats Go source code, whereas golint prints out style mistakes [fast: true, auto-fix: false]
|
||||
- staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks [fast: false, auto-fix: false]
|
||||
- structcheck # Finds unused struct fields [fast: true, auto-fix: false]
|
||||
- stylecheck # Stylecheck is a replacement for golint [fast: false, auto-fix: false]
|
||||
- typecheck # Like the front-end of a Go compiler, parses and type-checks Go code [fast: true, auto-fix: false]
|
||||
- unconvert # Remove unnecessary type conversions [fast: true, auto-fix: false]
|
||||
- unparam # Reports unused function parameters [fast: false, auto-fix: false]
|
||||
- unused # Checks Go code for unused constants, variables, functions and types [fast: false, auto-fix: false]
|
||||
- varcheck # Finds unused global variables and constants [fast: true, auto-fix: false]
|
||||
|
||||
disable:
|
||||
# TODO(ross): fix errors reported by these checkers and enable them
|
||||
- dupl # Tool for code clone detection [fast: true, auto-fix: false]
|
||||
- gochecknoglobals # Checks that no globals are present in Go code [fast: true, auto-fix: false]
|
||||
- gochecknoinits # Checks that no init functions are present in Go code [fast: true, auto-fix: false]
|
||||
- goconst # Finds repeated strings that could be replaced by a constant [fast: true, auto-fix: false]
|
||||
- lll # Reports long lines [fast: true, auto-fix: false]
|
||||
- depguard # Go linter that checks if package imports are in a list of acceptable packages [fast: true, auto-fix: false]
|
||||
linters-settings:
|
||||
goimports:
|
||||
local-prefixes: github.com/crewjam/saml
|
||||
|
||||
96
vendor/github.com/crewjam/saml/identity_provider.go
generated
vendored
96
vendor/github.com/crewjam/saml/identity_provider.go
generated
vendored
@@ -9,7 +9,6 @@ import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -96,6 +95,7 @@ type AssertionMaker interface {
|
||||
// and password).
|
||||
type IdentityProvider struct {
|
||||
Key crypto.PrivateKey
|
||||
Signer crypto.Signer
|
||||
Logger logger.Interface
|
||||
Certificate *x509.Certificate
|
||||
Intermediates []*x509.Certificate
|
||||
@@ -196,10 +196,13 @@ func (idp *IdentityProvider) Handler() http.Handler {
|
||||
}
|
||||
|
||||
// ServeMetadata is an http.HandlerFunc that serves the IDP metadata
|
||||
func (idp *IdentityProvider) ServeMetadata(w http.ResponseWriter, r *http.Request) {
|
||||
func (idp *IdentityProvider) ServeMetadata(w http.ResponseWriter, _ *http.Request) {
|
||||
buf, _ := xml.MarshalIndent(idp.Metadata(), "", " ")
|
||||
w.Header().Set("Content-Type", "application/samlmetadata+xml")
|
||||
w.Write(buf)
|
||||
if _, err := w.Write(buf); err != nil {
|
||||
idp.Logger.Printf("ERROR: %s", err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
// ServeSSO handles SAML auth requests.
|
||||
@@ -362,7 +365,7 @@ func NewIdpAuthnRequest(idp *IdentityProvider, r *http.Request) (*IdpAuthnReques
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot decode request: %s", err)
|
||||
}
|
||||
req.RequestBuffer, err = ioutil.ReadAll(newSaferFlateReader(bytes.NewReader(compressedRequest)))
|
||||
req.RequestBuffer, err = io.ReadAll(newSaferFlateReader(bytes.NewReader(compressedRequest)))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot decompress request: %s", err)
|
||||
}
|
||||
@@ -716,9 +719,7 @@ func (DefaultAssertionMaker) MakeAssertion(req *IdpAuthnRequest, session *Sessio
|
||||
})
|
||||
}
|
||||
|
||||
for _, ca := range session.CustomAttributes {
|
||||
attributes = append(attributes, ca)
|
||||
}
|
||||
attributes = append(attributes, session.CustomAttributes...)
|
||||
|
||||
if len(session.Groups) != 0 {
|
||||
groupMemberAttributeValues := []AttributeValue{}
|
||||
@@ -830,24 +831,8 @@ const canonicalizerPrefixList = ""
|
||||
|
||||
// MakeAssertionEl sets `AssertionEl` to a signed, possibly encrypted, version of `Assertion`.
|
||||
func (req *IdpAuthnRequest) MakeAssertionEl() error {
|
||||
keyPair := tls.Certificate{
|
||||
Certificate: [][]byte{req.IDP.Certificate.Raw},
|
||||
PrivateKey: req.IDP.Key,
|
||||
Leaf: req.IDP.Certificate,
|
||||
}
|
||||
for _, cert := range req.IDP.Intermediates {
|
||||
keyPair.Certificate = append(keyPair.Certificate, cert.Raw)
|
||||
}
|
||||
keyStore := dsig.TLSCertKeyStore(keyPair)
|
||||
|
||||
signatureMethod := req.IDP.SignatureMethod
|
||||
if signatureMethod == "" {
|
||||
signatureMethod = dsig.RSASHA1SignatureMethod
|
||||
}
|
||||
|
||||
signingContext := dsig.NewDefaultSigningContext(keyStore)
|
||||
signingContext.Canonicalizer = dsig.MakeC14N10ExclusiveCanonicalizerWithPrefixList(canonicalizerPrefixList)
|
||||
if err := signingContext.SetSignatureMethod(signatureMethod); err != nil {
|
||||
signingContext, err := req.signingContext()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1048,24 +1033,8 @@ func (req *IdpAuthnRequest) MakeResponse() error {
|
||||
|
||||
// Sign the response element (we've already signed the Assertion element)
|
||||
{
|
||||
keyPair := tls.Certificate{
|
||||
Certificate: [][]byte{req.IDP.Certificate.Raw},
|
||||
PrivateKey: req.IDP.Key,
|
||||
Leaf: req.IDP.Certificate,
|
||||
}
|
||||
for _, cert := range req.IDP.Intermediates {
|
||||
keyPair.Certificate = append(keyPair.Certificate, cert.Raw)
|
||||
}
|
||||
keyStore := dsig.TLSCertKeyStore(keyPair)
|
||||
|
||||
signatureMethod := req.IDP.SignatureMethod
|
||||
if signatureMethod == "" {
|
||||
signatureMethod = dsig.RSASHA1SignatureMethod
|
||||
}
|
||||
|
||||
signingContext := dsig.NewDefaultSigningContext(keyStore)
|
||||
signingContext.Canonicalizer = dsig.MakeC14N10ExclusiveCanonicalizerWithPrefixList(canonicalizerPrefixList)
|
||||
if err := signingContext.SetSignatureMethod(signatureMethod); err != nil {
|
||||
signingContext, err := req.signingContext()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1083,3 +1052,44 @@ func (req *IdpAuthnRequest) MakeResponse() error {
|
||||
req.ResponseEl = responseEl
|
||||
return nil
|
||||
}
|
||||
|
||||
// signingContext will create a signing context for the request.
|
||||
func (req *IdpAuthnRequest) signingContext() (*dsig.SigningContext, error) {
|
||||
// Create a cert chain based off of the IDP cert and its intermediates.
|
||||
certificates := [][]byte{req.IDP.Certificate.Raw}
|
||||
for _, cert := range req.IDP.Intermediates {
|
||||
certificates = append(certificates, cert.Raw)
|
||||
}
|
||||
|
||||
var signingContext *dsig.SigningContext
|
||||
var err error
|
||||
// If signer is set, use it instead of the private key.
|
||||
if req.IDP.Signer != nil {
|
||||
signingContext, err = dsig.NewSigningContext(req.IDP.Signer, certificates)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
keyPair := tls.Certificate{
|
||||
Certificate: certificates,
|
||||
PrivateKey: req.IDP.Key,
|
||||
Leaf: req.IDP.Certificate,
|
||||
}
|
||||
keyStore := dsig.TLSCertKeyStore(keyPair)
|
||||
|
||||
signingContext = dsig.NewDefaultSigningContext(keyStore)
|
||||
}
|
||||
|
||||
// Default to using SHA1 if the signature method isn't set.
|
||||
signatureMethod := req.IDP.SignatureMethod
|
||||
if signatureMethod == "" {
|
||||
signatureMethod = dsig.RSASHA1SignatureMethod
|
||||
}
|
||||
|
||||
signingContext.Canonicalizer = dsig.MakeC14N10ExclusiveCanonicalizerWithPrefixList(canonicalizerPrefixList)
|
||||
if err := signingContext.SetSignatureMethod(signatureMethod); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return signingContext, nil
|
||||
}
|
||||
|
||||
1
vendor/github.com/crewjam/saml/logger/logger.go
generated
vendored
1
vendor/github.com/crewjam/saml/logger/logger.go
generated
vendored
@@ -1,3 +1,4 @@
|
||||
// Package logger provides a logging interface.
|
||||
package logger
|
||||
|
||||
import (
|
||||
|
||||
109
vendor/github.com/crewjam/saml/metadata.go
generated
vendored
109
vendor/github.com/crewjam/saml/metadata.go
generated
vendored
@@ -2,6 +2,8 @@ package saml
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/beevik/etree"
|
||||
@@ -19,6 +21,9 @@ const HTTPArtifactBinding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
|
||||
// SOAPBinding is the official URN for the SOAP binding (transport)
|
||||
const SOAPBinding = "urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
|
||||
|
||||
// SOAPBindingV1 is the URN for the SOAP binding in SAML 1.0
|
||||
const SOAPBindingV1 = "urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding"
|
||||
|
||||
// EntitiesDescriptor represents the SAML object of the same name.
|
||||
//
|
||||
// See http://docs.oasis-open.org/security/saml/v2.0/saml-metadata-2.0-os.pdf §2.3.1
|
||||
@@ -65,7 +70,7 @@ type EntityDescriptor struct {
|
||||
}
|
||||
|
||||
// MarshalXML implements xml.Marshaler
|
||||
func (m EntityDescriptor) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
func (m EntityDescriptor) MarshalXML(e *xml.Encoder, _ xml.StartElement) error {
|
||||
type Alias EntityDescriptor
|
||||
aux := &struct {
|
||||
ValidUntil RelaxedTime `xml:"validUntil,attr,omitempty"`
|
||||
@@ -188,6 +193,76 @@ type Endpoint struct {
|
||||
ResponseLocation string `xml:"ResponseLocation,attr,omitempty"`
|
||||
}
|
||||
|
||||
func checkEndpointLocation(binding string, location string) (string, error) {
|
||||
// Within the SAML standard, the complex type EndpointType describes a
|
||||
// SAML protocol binding endpoint at which a SAML entity can be sent
|
||||
// protocol messages. In particular, the location of an endpoint type is
|
||||
// defined as follows in the Metadata for the OASIS Security Assertion
|
||||
// Markup Language (SAML) V2.0 - 2.2.2 Complex Type EndpointType:
|
||||
//
|
||||
// Location [Required] A required URI attribute that specifies the
|
||||
// location of the endpoint. The allowable syntax of this URI depends
|
||||
// on the protocol binding.
|
||||
switch binding {
|
||||
case HTTPPostBinding,
|
||||
HTTPRedirectBinding,
|
||||
HTTPArtifactBinding,
|
||||
SOAPBinding,
|
||||
SOAPBindingV1:
|
||||
locationURL, err := url.Parse(location)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("invalid url %q: %w", location, err)
|
||||
}
|
||||
switch locationURL.Scheme {
|
||||
case "http", "https":
|
||||
// ok
|
||||
default:
|
||||
return "", fmt.Errorf("invalid url scheme %q for binding %q",
|
||||
locationURL.Scheme, binding)
|
||||
}
|
||||
default:
|
||||
// We don't know what form location should take, but the protocol
|
||||
// requires that we validate its syntax.
|
||||
//
|
||||
// In practice, lots of metadata contains random bindings, for example
|
||||
// "urn:mace:shibboleth:1.0:profiles:AuthnRequest" from our own test suite.
|
||||
//
|
||||
// We can't fail, but we also can't allow a location parameter whose syntax we
|
||||
// cannot verify. The least-bad course of action here is to set location to
|
||||
// and empty string, and hope the caller doesn't care need it.
|
||||
location = ""
|
||||
}
|
||||
|
||||
return location, nil
|
||||
}
|
||||
|
||||
// UnmarshalXML implements xml.Unmarshaler
|
||||
func (m *Endpoint) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
type Alias Endpoint
|
||||
aux := &struct {
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(m),
|
||||
}
|
||||
if err := d.DecodeElement(aux, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var err error
|
||||
m.Location, err = checkEndpointLocation(m.Binding, m.Location)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if m.ResponseLocation != "" {
|
||||
m.ResponseLocation, err = checkEndpointLocation(m.Binding, m.ResponseLocation)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IndexedEndpoint represents the SAML IndexedEndpointType object.
|
||||
//
|
||||
// See http://docs.oasis-open.org/security/saml/v2.0/saml-metadata-2.0-os.pdf §2.2.3
|
||||
@@ -199,6 +274,38 @@ type IndexedEndpoint struct {
|
||||
IsDefault *bool `xml:"isDefault,attr"`
|
||||
}
|
||||
|
||||
// UnmarshalXML implements xml.Unmarshaler
|
||||
func (m *IndexedEndpoint) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||
type Alias IndexedEndpoint
|
||||
aux := &struct {
|
||||
*Alias
|
||||
}{
|
||||
Alias: (*Alias)(m),
|
||||
}
|
||||
if err := d.DecodeElement(aux, &start); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var err error
|
||||
m.Location, err = checkEndpointLocation(m.Binding, m.Location)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if m.ResponseLocation != nil {
|
||||
responseLocation, err := checkEndpointLocation(m.Binding, *m.ResponseLocation)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if responseLocation != "" {
|
||||
m.ResponseLocation = &responseLocation
|
||||
} else {
|
||||
m.ResponseLocation = nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SSODescriptor represents the SAML complex type SSODescriptor
|
||||
//
|
||||
// See http://docs.oasis-open.org/security/saml/v2.0/saml-metadata-2.0-os.pdf §2.4.2
|
||||
|
||||
2
vendor/github.com/crewjam/saml/samlsp/error.go
generated
vendored
2
vendor/github.com/crewjam/saml/samlsp/error.go
generated
vendored
@@ -14,7 +14,7 @@ type ErrorFunction func(w http.ResponseWriter, r *http.Request, err error)
|
||||
// DefaultOnError is the default ErrorFunction implementation. It prints
|
||||
// an message via the standard log package and returns a simple text
|
||||
// "Forbidden" message to the user.
|
||||
func DefaultOnError(w http.ResponseWriter, r *http.Request, err error) {
|
||||
func DefaultOnError(w http.ResponseWriter, _ *http.Request, err error) {
|
||||
if parseErr, ok := err.(*saml.InvalidResponseError); ok {
|
||||
log.Printf("WARNING: received invalid saml response: %s (now: %s) %s",
|
||||
parseErr.Response, parseErr.Now, parseErr.PrivateErr)
|
||||
|
||||
12
vendor/github.com/crewjam/saml/samlsp/fetch_metadata.go
generated
vendored
12
vendor/github.com/crewjam/saml/samlsp/fetch_metadata.go
generated
vendored
@@ -5,13 +5,15 @@ import (
|
||||
"context"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/crewjam/httperr"
|
||||
xrv "github.com/mattermost/xml-roundtrip-validator"
|
||||
|
||||
"github.com/crewjam/saml/logger"
|
||||
|
||||
"github.com/crewjam/saml"
|
||||
)
|
||||
|
||||
@@ -61,12 +63,16 @@ func FetchMetadata(ctx context.Context, httpClient *http.Client, metadataURL url
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
defer func() {
|
||||
if err := resp.Body.Close(); err != nil {
|
||||
logger.DefaultLogger.Printf("Error while closing response body during fetch metadata: %v", err)
|
||||
}
|
||||
}()
|
||||
if resp.StatusCode >= 400 {
|
||||
return nil, httperr.Response(*resp)
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
33
vendor/github.com/crewjam/saml/samlsp/middleware.go
generated
vendored
33
vendor/github.com/crewjam/saml/samlsp/middleware.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package samlsp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"net/http"
|
||||
|
||||
@@ -65,16 +66,22 @@ func (m *Middleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// ServeMetadata handles requests for the SAML metadata endpoint.
|
||||
func (m *Middleware) ServeMetadata(w http.ResponseWriter, r *http.Request) {
|
||||
func (m *Middleware) ServeMetadata(w http.ResponseWriter, _ *http.Request) {
|
||||
buf, _ := xml.MarshalIndent(m.ServiceProvider.Metadata(), "", " ")
|
||||
w.Header().Set("Content-Type", "application/samlmetadata+xml")
|
||||
w.Write(buf)
|
||||
return
|
||||
if _, err := w.Write(buf); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// ServeACS handles requests for the SAML ACS endpoint.
|
||||
func (m *Middleware) ServeACS(w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
m.OnError(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
possibleRequestIDs := []string{}
|
||||
if m.ServiceProvider.AllowIDPInitiated {
|
||||
@@ -93,7 +100,6 @@ func (m *Middleware) ServeACS(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
m.CreateSessionFromAssertion(w, r, assertion, m.ServiceProvider.DefaultRedirectURI)
|
||||
return
|
||||
}
|
||||
|
||||
// RequireAccount is HTTP middleware that requires that each request be
|
||||
@@ -114,7 +120,6 @@ func (m *Middleware) RequireAccount(handler http.Handler) http.Handler {
|
||||
}
|
||||
|
||||
m.OnError(w, r, err)
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
@@ -173,9 +178,14 @@ func (m *Middleware) HandleStartAuthFlow(w http.ResponseWriter, r *http.Request)
|
||||
"script-src 'sha256-AjPdJSbZmeWHnEc5ykvJFay8FTWeTeRbs9dutfZ0HqE='; "+
|
||||
"reflected-xss block; referrer no-referrer;")
|
||||
w.Header().Add("Content-type", "text/html")
|
||||
w.Write([]byte(`<!DOCTYPE html><html><body>`))
|
||||
w.Write(authReq.Post(relayState))
|
||||
w.Write([]byte(`</body></html>`))
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString(`<!DOCTYPE html><html><body>`)
|
||||
buf.Write(authReq.Post(relayState))
|
||||
buf.WriteString(`</body></html>`)
|
||||
if _, err := w.Write(buf.Bytes()); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
panic("not reached")
|
||||
@@ -195,7 +205,10 @@ func (m *Middleware) CreateSessionFromAssertion(w http.ResponseWriter, r *http.R
|
||||
return
|
||||
}
|
||||
} else {
|
||||
m.RequestTracker.StopTrackingRequest(w, r, trackedRequestIndex)
|
||||
if err := m.RequestTracker.StopTrackingRequest(w, r, trackedRequestIndex); err != nil {
|
||||
m.OnError(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
redirectURI = trackedRequest.URI
|
||||
}
|
||||
|
||||
14
vendor/github.com/crewjam/saml/samlsp/request_tracker_jwt.go
generated
vendored
14
vendor/github.com/crewjam/saml/samlsp/request_tracker_jwt.go
generated
vendored
@@ -25,7 +25,7 @@ var _ TrackedRequestCodec = JWTTrackedRequestCodec{}
|
||||
|
||||
// JWTTrackedRequestClaims represents the JWT claims for a tracked request.
|
||||
type JWTTrackedRequestClaims struct {
|
||||
jwt.StandardClaims
|
||||
jwt.RegisteredClaims
|
||||
TrackedRequest
|
||||
SAMLAuthnRequest bool `json:"saml-authn-request"`
|
||||
}
|
||||
@@ -34,12 +34,12 @@ type JWTTrackedRequestClaims struct {
|
||||
func (s JWTTrackedRequestCodec) Encode(value TrackedRequest) (string, error) {
|
||||
now := saml.TimeNow()
|
||||
claims := JWTTrackedRequestClaims{
|
||||
StandardClaims: jwt.StandardClaims{
|
||||
Audience: s.Audience,
|
||||
ExpiresAt: now.Add(s.MaxAge).Unix(),
|
||||
IssuedAt: now.Unix(),
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
Audience: jwt.ClaimStrings{s.Audience},
|
||||
ExpiresAt: jwt.NewNumericDate(now.Add(s.MaxAge)),
|
||||
IssuedAt: jwt.NewNumericDate(now),
|
||||
Issuer: s.Issuer,
|
||||
NotBefore: now.Unix(), // TODO(ross): correct for clock skew
|
||||
NotBefore: jwt.NewNumericDate(now), // TODO(ross): correct for clock skew
|
||||
Subject: value.Index,
|
||||
},
|
||||
TrackedRequest: value,
|
||||
@@ -67,7 +67,7 @@ func (s JWTTrackedRequestCodec) Decode(signed string) (*TrackedRequest, error) {
|
||||
if !claims.VerifyIssuer(s.Issuer, true) {
|
||||
return nil, fmt.Errorf("expected issuer %q, got %q", s.Issuer, claims.Issuer)
|
||||
}
|
||||
if claims.SAMLAuthnRequest != true {
|
||||
if !claims.SAMLAuthnRequest {
|
||||
return nil, fmt.Errorf("expected saml-authn-request")
|
||||
}
|
||||
claims.TrackedRequest.Index = claims.Subject
|
||||
|
||||
2
vendor/github.com/crewjam/saml/samlsp/session_jwt.go
generated
vendored
2
vendor/github.com/crewjam/saml/samlsp/session_jwt.go
generated
vendored
@@ -106,7 +106,7 @@ func (c JWTSessionCodec) Decode(signed string) (Session, error) {
|
||||
if !claims.VerifyIssuer(c.Issuer, true) {
|
||||
return nil, fmt.Errorf("expected issuer %q, got %q", c.Issuer, claims.Issuer)
|
||||
}
|
||||
if claims.SAMLSession != true {
|
||||
if !claims.SAMLSession {
|
||||
return nil, errors.New("expected saml-session")
|
||||
}
|
||||
return claims, nil
|
||||
|
||||
28
vendor/github.com/crewjam/saml/schema.go
generated
vendored
28
vendor/github.com/crewjam/saml/schema.go
generated
vendored
@@ -48,7 +48,7 @@ type AuthnRequest struct {
|
||||
NameIDPolicy *NameIDPolicy `xml:"urn:oasis:names:tc:SAML:2.0:protocol NameIDPolicy"`
|
||||
Conditions *Conditions
|
||||
RequestedAuthnContext *RequestedAuthnContext
|
||||
//Scoping *Scoping // TODO
|
||||
// Scoping *Scoping // TODO
|
||||
|
||||
ForceAuthn *bool `xml:",attr"`
|
||||
IsPassive *bool `xml:",attr"`
|
||||
@@ -108,7 +108,7 @@ func (r *LogoutRequest) Element() *etree.Element {
|
||||
}
|
||||
|
||||
// MarshalXML implements xml.Marshaler
|
||||
func (r *LogoutRequest) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
func (r *LogoutRequest) MarshalXML(e *xml.Encoder, _ xml.StartElement) error {
|
||||
type Alias LogoutRequest
|
||||
aux := &struct {
|
||||
IssueInstant RelaxedTime `xml:",attr"`
|
||||
@@ -209,9 +209,9 @@ func (r *AuthnRequest) Element() *etree.Element {
|
||||
if r.RequestedAuthnContext != nil {
|
||||
el.AddChild(r.RequestedAuthnContext.Element())
|
||||
}
|
||||
//if r.Scoping != nil {
|
||||
// el.AddChild(r.Scoping.Element())
|
||||
//}
|
||||
// if r.Scoping != nil {
|
||||
// el.AddChild(r.Scoping.Element())
|
||||
// }
|
||||
if r.ForceAuthn != nil {
|
||||
el.CreateAttr("ForceAuthn", strconv.FormatBool(*r.ForceAuthn))
|
||||
}
|
||||
@@ -237,7 +237,7 @@ func (r *AuthnRequest) Element() *etree.Element {
|
||||
}
|
||||
|
||||
// MarshalXML implements xml.Marshaler
|
||||
func (r *AuthnRequest) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
func (r *AuthnRequest) MarshalXML(e *xml.Encoder, _ xml.StartElement) error {
|
||||
type Alias AuthnRequest
|
||||
aux := &struct {
|
||||
IssueInstant RelaxedTime `xml:",attr"`
|
||||
@@ -374,7 +374,7 @@ func (r *ArtifactResolve) SoapRequest() *etree.Element {
|
||||
}
|
||||
|
||||
// MarshalXML implements xml.Marshaler
|
||||
func (r *ArtifactResolve) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
func (r *ArtifactResolve) MarshalXML(e *xml.Encoder, _ xml.StartElement) error {
|
||||
type Alias ArtifactResolve
|
||||
aux := &struct {
|
||||
IssueInstant RelaxedTime `xml:",attr"`
|
||||
@@ -448,7 +448,7 @@ func (r *ArtifactResponse) Element() *etree.Element {
|
||||
}
|
||||
|
||||
// MarshalXML implements xml.Marshaler
|
||||
func (r *ArtifactResponse) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
func (r *ArtifactResponse) MarshalXML(e *xml.Encoder, _ xml.StartElement) error {
|
||||
type Alias ArtifactResponse
|
||||
aux := &struct {
|
||||
IssueInstant RelaxedTime `xml:",attr"`
|
||||
@@ -542,7 +542,7 @@ func (r *Response) Element() *etree.Element {
|
||||
}
|
||||
|
||||
// MarshalXML implements xml.Marshaler
|
||||
func (r *Response) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
func (r *Response) MarshalXML(e *xml.Encoder, _ xml.StartElement) error {
|
||||
type Alias Response
|
||||
aux := &struct {
|
||||
IssueInstant RelaxedTime `xml:",attr"`
|
||||
@@ -667,7 +667,7 @@ const (
|
||||
StatusRequestUnsupported = "urn:oasis:names:tc:SAML:2.0:status:RequestUnsupported"
|
||||
|
||||
// StatusRequestVersionDeprecated means the SAML responder cannot process any requests with the protocol version specified in the request.
|
||||
StatusRequestVersionDeprecated = "urn:oasis:names:tc:SAML:2.0:status:RequestVersionDeprecated"
|
||||
StatusRequestVersionDeprecated = "urn:oasis:names:tc:SAML:2.0:status:RequestVersionDeprecated" //nolint:gosec
|
||||
|
||||
// StatusRequestVersionTooHigh means the SAML responder cannot process the request because the protocol version specified in the request message is a major upgrade from the highest protocol version supported by the responder.
|
||||
StatusRequestVersionTooHigh = "urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooHigh"
|
||||
@@ -1153,9 +1153,9 @@ func (a *SubjectLocality) Element() *etree.Element {
|
||||
// See http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf §2.7.2.2
|
||||
type AuthnContext struct {
|
||||
AuthnContextClassRef *AuthnContextClassRef
|
||||
//AuthnContextDecl *AuthnContextDecl ... TODO
|
||||
//AuthnContextDeclRef *AuthnContextDeclRef ... TODO
|
||||
//AuthenticatingAuthorities []AuthenticatingAuthority... TODO
|
||||
// AuthnContextDecl *AuthnContextDecl ... TODO
|
||||
// AuthnContextDeclRef *AuthnContextDeclRef ... TODO
|
||||
// AuthenticatingAuthorities []AuthenticatingAuthority... TODO
|
||||
}
|
||||
|
||||
// Element returns an etree.Element representing the object in XML form.
|
||||
@@ -1292,7 +1292,7 @@ func (r *LogoutResponse) Element() *etree.Element {
|
||||
}
|
||||
|
||||
// MarshalXML implements xml.Marshaler
|
||||
func (r *LogoutResponse) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
func (r *LogoutResponse) MarshalXML(e *xml.Encoder, _ xml.StartElement) error {
|
||||
type Alias LogoutResponse
|
||||
aux := &struct {
|
||||
IssueInstant RelaxedTime `xml:",attr"`
|
||||
|
||||
144
vendor/github.com/crewjam/saml/service_provider.go
generated
vendored
144
vendor/github.com/crewjam/saml/service_provider.go
generated
vendored
@@ -12,7 +12,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
dsig "github.com/russellhaering/goxmldsig"
|
||||
"github.com/russellhaering/goxmldsig/etreeutils"
|
||||
|
||||
"github.com/crewjam/saml/logger"
|
||||
"github.com/crewjam/saml/xmlenc"
|
||||
)
|
||||
|
||||
@@ -189,13 +190,13 @@ func (sp *ServiceProvider) Metadata() *EntityDescriptor {
|
||||
}
|
||||
}
|
||||
|
||||
var sloEndpoints []Endpoint
|
||||
for _, binding := range sp.LogoutBindings {
|
||||
sloEndpoints = append(sloEndpoints, Endpoint{
|
||||
sloEndpoints := make([]Endpoint, len(sp.LogoutBindings))
|
||||
for i, binding := range sp.LogoutBindings {
|
||||
sloEndpoints[i] = Endpoint{
|
||||
Binding: binding,
|
||||
Location: sp.SloURL.String(),
|
||||
ResponseLocation: sp.SloURL.String(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return &EntityDescriptor{
|
||||
@@ -245,25 +246,29 @@ func (sp *ServiceProvider) MakeRedirectAuthenticationRequest(relayState string)
|
||||
}
|
||||
|
||||
// Redirect returns a URL suitable for using the redirect binding with the request
|
||||
func (req *AuthnRequest) Redirect(relayState string, sp *ServiceProvider) (*url.URL, error) {
|
||||
func (r *AuthnRequest) Redirect(relayState string, sp *ServiceProvider) (*url.URL, error) {
|
||||
w := &bytes.Buffer{}
|
||||
w1 := base64.NewEncoder(base64.StdEncoding, w)
|
||||
w2, _ := flate.NewWriter(w1, 9)
|
||||
doc := etree.NewDocument()
|
||||
doc.SetRoot(req.Element())
|
||||
doc.SetRoot(r.Element())
|
||||
if _, err := doc.WriteTo(w2); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w2.Close()
|
||||
w1.Close()
|
||||
if err := w2.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := w1.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
rv, _ := url.Parse(req.Destination)
|
||||
rv, _ := url.Parse(r.Destination)
|
||||
// We can't depend on Query().set() as order matters for signing
|
||||
query := rv.RawQuery
|
||||
if len(query) > 0 {
|
||||
query += "&SAMLRequest=" + url.QueryEscape(string(w.Bytes()))
|
||||
query += "&SAMLRequest=" + url.QueryEscape(w.String())
|
||||
} else {
|
||||
query += "SAMLRequest=" + url.QueryEscape(string(w.Bytes()))
|
||||
query += "SAMLRequest=" + url.QueryEscape(w.String())
|
||||
}
|
||||
|
||||
if relayState != "" {
|
||||
@@ -352,11 +357,11 @@ func (sp *ServiceProvider) getIDPSigningCerts() ([]*x509.Certificate, error) {
|
||||
return nil, errors.New("cannot find any signing certificate in the IDP SSO descriptor")
|
||||
}
|
||||
|
||||
var certs []*x509.Certificate
|
||||
certs := make([]*x509.Certificate, len(certStrs))
|
||||
|
||||
// cleanup whitespace
|
||||
regex := regexp.MustCompile(`\s+`)
|
||||
for _, certStr := range certStrs {
|
||||
for i, certStr := range certStrs {
|
||||
certStr = regex.ReplaceAllString(certStr, "")
|
||||
certBytes, err := base64.StdEncoding.DecodeString(certStr)
|
||||
if err != nil {
|
||||
@@ -367,7 +372,7 @@ func (sp *ServiceProvider) getIDPSigningCerts() ([]*x509.Certificate, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
certs = append(certs, parsedCert)
|
||||
certs[i] = parsedCert
|
||||
}
|
||||
|
||||
return certs, nil
|
||||
@@ -439,9 +444,9 @@ func GetSigningContext(sp *ServiceProvider) (*dsig.SigningContext, error) {
|
||||
Leaf: sp.Certificate,
|
||||
}
|
||||
// TODO: add intermediates for SP
|
||||
//for _, cert := range sp.Intermediates {
|
||||
// keyPair.Certificate = append(keyPair.Certificate, cert.Raw)
|
||||
//}
|
||||
// for _, cert := range sp.Intermediates {
|
||||
// keyPair.Certificate = append(keyPair.Certificate, cert.Raw)
|
||||
// }
|
||||
keyStore := dsig.TLSCertKeyStore(keyPair)
|
||||
|
||||
if sp.SignatureMethod != dsig.RSASHA1SignatureMethod &&
|
||||
@@ -508,9 +513,9 @@ func (sp *ServiceProvider) MakePostAuthenticationRequest(relayState string) ([]b
|
||||
}
|
||||
|
||||
// Post returns an HTML form suitable for using the HTTP-POST binding with the request
|
||||
func (req *AuthnRequest) Post(relayState string) []byte {
|
||||
func (r *AuthnRequest) Post(relayState string) []byte {
|
||||
doc := etree.NewDocument()
|
||||
doc.SetRoot(req.Element())
|
||||
doc.SetRoot(r.Element())
|
||||
reqBuf, err := doc.WriteToBytes()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -530,7 +535,7 @@ func (req *AuthnRequest) Post(relayState string) []byte {
|
||||
SAMLRequest string
|
||||
RelayState string
|
||||
}{
|
||||
URL: req.Destination,
|
||||
URL: r.Destination,
|
||||
SAMLRequest: encodedReqBuf,
|
||||
RelayState: relayState,
|
||||
}
|
||||
@@ -579,7 +584,7 @@ type InvalidResponseError struct {
|
||||
}
|
||||
|
||||
func (ivr *InvalidResponseError) Error() string {
|
||||
return fmt.Sprintf("Authentication failed")
|
||||
return "Authentication failed"
|
||||
}
|
||||
|
||||
// ErrBadStatus is returned when the assertion provided is valid but the
|
||||
@@ -606,7 +611,7 @@ func (sp *ServiceProvider) handleArtifactRequest(ctx context.Context, artifactID
|
||||
|
||||
artifactResolveRequest, err := sp.MakeArtifactResolveRequest(artifactID)
|
||||
if err != nil {
|
||||
retErr.PrivateErr = fmt.Errorf("Cannot generate artifact resolution request: %s", err)
|
||||
retErr.PrivateErr = fmt.Errorf("cannot generate artifact resolution request: %s", err)
|
||||
return nil, retErr
|
||||
}
|
||||
|
||||
@@ -633,12 +638,16 @@ func (sp *ServiceProvider) handleArtifactRequest(ctx context.Context, artifactID
|
||||
retErr.PrivateErr = fmt.Errorf("cannot resolve artifact: %s", err)
|
||||
return nil, retErr
|
||||
}
|
||||
defer response.Body.Close()
|
||||
defer func() {
|
||||
if err := response.Body.Close(); err != nil {
|
||||
logger.DefaultLogger.Printf("Error while closing response body during artifact resolution: %v", err)
|
||||
}
|
||||
}()
|
||||
if response.StatusCode != 200 {
|
||||
retErr.PrivateErr = fmt.Errorf("Error during artifact resolution: HTTP status %d (%s)", response.StatusCode, response.Status)
|
||||
return nil, retErr
|
||||
}
|
||||
responseBody, err := ioutil.ReadAll(response.Body)
|
||||
responseBody, err := io.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
retErr.PrivateErr = fmt.Errorf("Error during artifact resolution: %s", err)
|
||||
return nil, retErr
|
||||
@@ -753,11 +762,12 @@ func (sp *ServiceProvider) parseArtifactResponse(artifactResponseEl *etree.Eleme
|
||||
|
||||
var signatureRequirement signatureRequirement
|
||||
sigErr := sp.validateSignature(artifactResponseEl)
|
||||
if sigErr == nil {
|
||||
switch sigErr {
|
||||
case nil:
|
||||
signatureRequirement = signatureNotRequired
|
||||
} else if sigErr == errSignatureElementNotPresent {
|
||||
case errSignatureElementNotPresent:
|
||||
signatureRequirement = signatureRequired
|
||||
} else {
|
||||
default:
|
||||
retErr.PrivateErr = sigErr
|
||||
return nil, retErr
|
||||
}
|
||||
@@ -888,13 +898,14 @@ func (sp *ServiceProvider) parseResponse(responseEl *etree.Element, possibleRequ
|
||||
}
|
||||
|
||||
if signatureRequirement == signatureRequired {
|
||||
if responseSignatureErr == nil {
|
||||
switch responseSignatureErr {
|
||||
case nil:
|
||||
// since the request has a signature, none of the Assertions need one
|
||||
signatureRequirement = signatureNotRequired
|
||||
} else if responseSignatureErr == errSignatureElementNotPresent {
|
||||
case errSignatureElementNotPresent:
|
||||
// the request has no signature, so assertions must be signed
|
||||
signatureRequirement = signatureRequired // nop
|
||||
} else {
|
||||
default:
|
||||
return nil, responseSignatureErr
|
||||
}
|
||||
}
|
||||
@@ -1078,7 +1089,7 @@ func (sp *ServiceProvider) validateAssertion(assertion *Assertion, possibleReque
|
||||
return nil
|
||||
}
|
||||
|
||||
var errSignatureElementNotPresent = errors.New("Signature element not present")
|
||||
var errSignatureElementNotPresent = errors.New("signature element not present")
|
||||
|
||||
// validateSignature returns nil iff the Signature embedded in the element is valid
|
||||
func (sp *ServiceProvider) validateSignature(el *etree.Element) error {
|
||||
@@ -1154,9 +1165,9 @@ func (sp *ServiceProvider) SignLogoutRequest(req *LogoutRequest) error {
|
||||
Leaf: sp.Certificate,
|
||||
}
|
||||
// TODO: add intermediates for SP
|
||||
//for _, cert := range sp.Intermediates {
|
||||
// keyPair.Certificate = append(keyPair.Certificate, cert.Raw)
|
||||
//}
|
||||
// for _, cert := range sp.Intermediates {
|
||||
// keyPair.Certificate = append(keyPair.Certificate, cert.Raw)
|
||||
// }
|
||||
keyStore := dsig.TLSCertKeyStore(keyPair)
|
||||
|
||||
if sp.SignatureMethod != dsig.RSASHA1SignatureMethod &&
|
||||
@@ -1222,22 +1233,26 @@ func (sp *ServiceProvider) MakeRedirectLogoutRequest(nameID, relayState string)
|
||||
}
|
||||
|
||||
// Redirect returns a URL suitable for using the redirect binding with the request
|
||||
func (req *LogoutRequest) Redirect(relayState string) *url.URL {
|
||||
func (r *LogoutRequest) Redirect(relayState string) *url.URL {
|
||||
w := &bytes.Buffer{}
|
||||
w1 := base64.NewEncoder(base64.StdEncoding, w)
|
||||
w2, _ := flate.NewWriter(w1, 9)
|
||||
doc := etree.NewDocument()
|
||||
doc.SetRoot(req.Element())
|
||||
doc.SetRoot(r.Element())
|
||||
if _, err := doc.WriteTo(w2); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w2.Close()
|
||||
w1.Close()
|
||||
if err := w2.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := w1.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
rv, _ := url.Parse(req.Destination)
|
||||
rv, _ := url.Parse(r.Destination)
|
||||
|
||||
query := rv.Query()
|
||||
query.Set("SAMLRequest", string(w.Bytes()))
|
||||
query.Set("SAMLRequest", w.String())
|
||||
if relayState != "" {
|
||||
query.Set("RelayState", relayState)
|
||||
}
|
||||
@@ -1258,9 +1273,9 @@ func (sp *ServiceProvider) MakePostLogoutRequest(nameID, relayState string) ([]b
|
||||
}
|
||||
|
||||
// Post returns an HTML form suitable for using the HTTP-POST binding with the request
|
||||
func (req *LogoutRequest) Post(relayState string) []byte {
|
||||
func (r *LogoutRequest) Post(relayState string) []byte {
|
||||
doc := etree.NewDocument()
|
||||
doc.SetRoot(req.Element())
|
||||
doc.SetRoot(r.Element())
|
||||
reqBuf, err := doc.WriteToBytes()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -1280,7 +1295,7 @@ func (req *LogoutRequest) Post(relayState string) []byte {
|
||||
SAMLRequest string
|
||||
RelayState string
|
||||
}{
|
||||
URL: req.Destination,
|
||||
URL: r.Destination,
|
||||
SAMLRequest: encodedReqBuf,
|
||||
RelayState: relayState,
|
||||
}
|
||||
@@ -1332,22 +1347,26 @@ func (sp *ServiceProvider) MakeRedirectLogoutResponse(logoutRequestID, relayStat
|
||||
}
|
||||
|
||||
// Redirect returns a URL suitable for using the redirect binding with the LogoutResponse.
|
||||
func (resp *LogoutResponse) Redirect(relayState string) *url.URL {
|
||||
func (r *LogoutResponse) Redirect(relayState string) *url.URL {
|
||||
w := &bytes.Buffer{}
|
||||
w1 := base64.NewEncoder(base64.StdEncoding, w)
|
||||
w2, _ := flate.NewWriter(w1, 9)
|
||||
doc := etree.NewDocument()
|
||||
doc.SetRoot(resp.Element())
|
||||
doc.SetRoot(r.Element())
|
||||
if _, err := doc.WriteTo(w2); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w2.Close()
|
||||
w1.Close()
|
||||
if err := w2.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := w1.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
rv, _ := url.Parse(resp.Destination)
|
||||
rv, _ := url.Parse(r.Destination)
|
||||
|
||||
query := rv.Query()
|
||||
query.Set("SAMLResponse", string(w.Bytes()))
|
||||
query.Set("SAMLResponse", w.String())
|
||||
if relayState != "" {
|
||||
query.Set("RelayState", relayState)
|
||||
}
|
||||
@@ -1368,9 +1387,9 @@ func (sp *ServiceProvider) MakePostLogoutResponse(logoutRequestID, relayState st
|
||||
}
|
||||
|
||||
// Post returns an HTML form suitable for using the HTTP-POST binding with the LogoutResponse.
|
||||
func (resp *LogoutResponse) Post(relayState string) []byte {
|
||||
func (r *LogoutResponse) Post(relayState string) []byte {
|
||||
doc := etree.NewDocument()
|
||||
doc.SetRoot(resp.Element())
|
||||
doc.SetRoot(r.Element())
|
||||
reqBuf, err := doc.WriteToBytes()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -1390,7 +1409,7 @@ func (resp *LogoutResponse) Post(relayState string) []byte {
|
||||
SAMLResponse string
|
||||
RelayState string
|
||||
}{
|
||||
URL: resp.Destination,
|
||||
URL: r.Destination,
|
||||
SAMLResponse: encodedReqBuf,
|
||||
RelayState: relayState,
|
||||
}
|
||||
@@ -1411,9 +1430,9 @@ func (sp *ServiceProvider) SignLogoutResponse(resp *LogoutResponse) error {
|
||||
Leaf: sp.Certificate,
|
||||
}
|
||||
// TODO: add intermediates for SP
|
||||
//for _, cert := range sp.Intermediates {
|
||||
// keyPair.Certificate = append(keyPair.Certificate, cert.Raw)
|
||||
//}
|
||||
// for _, cert := range sp.Intermediates {
|
||||
// keyPair.Certificate = append(keyPair.Certificate, cert.Raw)
|
||||
// }
|
||||
keyStore := dsig.TLSCertKeyStore(keyPair)
|
||||
|
||||
if sp.SignatureMethod != dsig.RSASHA1SignatureMethod &&
|
||||
@@ -1502,10 +1521,7 @@ func (sp *ServiceProvider) ValidateLogoutResponseForm(postFormData string) error
|
||||
retErr.PrivateErr = err
|
||||
return retErr
|
||||
}
|
||||
if err := sp.validateLogoutResponse(&resp); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return sp.validateLogoutResponse(&resp)
|
||||
}
|
||||
|
||||
// ValidateLogoutResponseRedirect returns a nil error if the logout response is valid.
|
||||
@@ -1524,7 +1540,7 @@ func (sp *ServiceProvider) ValidateLogoutResponseRedirect(queryParameterData str
|
||||
}
|
||||
retErr.Response = string(rawResponseBuf)
|
||||
|
||||
gr, err := ioutil.ReadAll(newSaferFlateReader(bytes.NewBuffer(rawResponseBuf)))
|
||||
gr, err := io.ReadAll(newSaferFlateReader(bytes.NewBuffer(rawResponseBuf)))
|
||||
if err != nil {
|
||||
retErr.PrivateErr = err
|
||||
return retErr
|
||||
@@ -1550,10 +1566,7 @@ func (sp *ServiceProvider) ValidateLogoutResponseRedirect(queryParameterData str
|
||||
retErr.PrivateErr = err
|
||||
return retErr
|
||||
}
|
||||
if err := sp.validateLogoutResponse(&resp); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return sp.validateLogoutResponse(&resp)
|
||||
}
|
||||
|
||||
// validateLogoutResponse validates the LogoutResponse fields. Returns a nil error if the LogoutResponse is valid.
|
||||
@@ -1585,6 +1598,7 @@ func firstSet(a, b string) string {
|
||||
|
||||
// findChildren returns all the elements matching childNS/childTag that are direct children of parentEl.
|
||||
func findChildren(parentEl *etree.Element, childNS string, childTag string) ([]*etree.Element, error) {
|
||||
//nolint:prealloc // We don't know how many child elements we'll actually put into this array.
|
||||
var rv []*etree.Element
|
||||
for _, childEl := range parentEl.ChildElements() {
|
||||
if childEl.Tag != childTag {
|
||||
|
||||
1
vendor/github.com/crewjam/saml/util.go
generated
vendored
1
vendor/github.com/crewjam/saml/util.go
generated
vendored
@@ -21,6 +21,7 @@ var Clock *dsig.Clock
|
||||
// rand.Reader, but it can be replaced for testing.
|
||||
var RandReader = rand.Reader
|
||||
|
||||
//nolint:unparam // This always receives 20, but we want the option to do more or less if needed.
|
||||
func randomBytes(n int) []byte {
|
||||
rv := make([]byte, n)
|
||||
|
||||
|
||||
2
vendor/github.com/crewjam/saml/xmlenc/cbc.go
generated
vendored
2
vendor/github.com/crewjam/saml/xmlenc/cbc.go
generated
vendored
@@ -31,7 +31,7 @@ func (e CBC) Algorithm() string {
|
||||
|
||||
// Encrypt encrypts plaintext with key, which should be a []byte of length KeySize().
|
||||
// It returns an xenc:EncryptedData element.
|
||||
func (e CBC) Encrypt(key interface{}, plaintext []byte, nonce []byte) (*etree.Element, error) {
|
||||
func (e CBC) Encrypt(key interface{}, plaintext []byte, _ []byte) (*etree.Element, error) {
|
||||
keyBuf, ok := key.([]byte)
|
||||
if !ok {
|
||||
return nil, ErrIncorrectKeyType("[]byte")
|
||||
|
||||
1
vendor/github.com/crewjam/saml/xmlenc/decrypt.go
generated
vendored
1
vendor/github.com/crewjam/saml/xmlenc/decrypt.go
generated
vendored
@@ -90,6 +90,7 @@ func validateRSAKeyIfPresent(key interface{}, encryptedKey *etree.Element) (*rsa
|
||||
// if the key will work, or let the service provider know which key
|
||||
// to use to decrypt the message. Either way, verification is not
|
||||
// security-critical.
|
||||
//nolint:revive,staticcheck // Keep the later empty branch so that we know to address this at a later date.
|
||||
if el := encryptedKey.FindElement("./KeyInfo/X509Data/X509Certificate"); el != nil {
|
||||
certPEMbuf := el.Text()
|
||||
certPEMbuf = "-----BEGIN CERTIFICATE-----\n" + certPEMbuf + "\n-----END CERTIFICATE-----\n"
|
||||
|
||||
1
vendor/github.com/crewjam/saml/xmlenc/digest.go
generated
vendored
1
vendor/github.com/crewjam/saml/xmlenc/digest.go
generated
vendored
@@ -6,6 +6,7 @@ import (
|
||||
"crypto/sha512"
|
||||
"hash"
|
||||
|
||||
//nolint:staticcheck // We should support this for legacy reasons.
|
||||
"golang.org/x/crypto/ripemd160"
|
||||
)
|
||||
|
||||
|
||||
4
vendor/modules.txt
vendored
4
vendor/modules.txt
vendored
@@ -328,8 +328,8 @@ github.com/cpuguy83/go-md2man/v2/md2man
|
||||
# github.com/crewjam/httperr v0.2.0
|
||||
## explicit; go 1.13
|
||||
github.com/crewjam/httperr
|
||||
# github.com/crewjam/saml v0.4.13
|
||||
## explicit; go 1.16
|
||||
# github.com/crewjam/saml v0.4.14
|
||||
## explicit; go 1.19
|
||||
github.com/crewjam/saml
|
||||
github.com/crewjam/saml/logger
|
||||
github.com/crewjam/saml/samlsp
|
||||
|
||||
Reference in New Issue
Block a user