Skip to content

Commit

Permalink
fix (saml): address possible panics in saml handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
jimlambrt committed Sep 9, 2023
1 parent 3b302b0 commit 26c0e39
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 12 deletions.
20 changes: 16 additions & 4 deletions saml/demo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,22 @@ func main() {
sp, err := saml.NewServiceProvider(cfg)
exitOnError(err)

http.HandleFunc("/saml/acs", handler.ACSHandlerFunc(sp))
http.HandleFunc("/saml/auth/redirect", handler.RedirectBindingHandlerFunc(sp))
http.HandleFunc("/saml/auth/post", handler.PostBindingHandlerFunc(sp))
http.HandleFunc("/metadata", handler.MetadataHandlerFunc(sp))
acsHandler, err := handler.ACSHandlerFunc(sp)
exitOnError(err)

redirectHandler, err := handler.RedirectBindingHandlerFunc(sp)
exitOnError(err)

postBindHandler, err := handler.PostBindingHandlerFunc(sp)
exitOnError(err)

metadataHandler, err := handler.MetadataHandlerFunc(sp)
exitOnError(err)

http.HandleFunc("/saml/acs", acsHandler)
http.HandleFunc("/saml/auth/redirect", redirectHandler)
http.HandleFunc("/saml/auth/post", postBindHandler)
http.HandleFunc("/metadata", metadataHandler)
http.HandleFunc("/login", func(w http.ResponseWriter, _ *http.Request) {
ts, _ := template.New("sso").Parse(
`<html><form method="GET" action="/saml/auth/redirect"><button type="submit">Submit Redirect</button></form></html>
Expand Down
11 changes: 9 additions & 2 deletions saml/handler/acs.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@ import (
"github.com/hashicorp/cap/saml"
)

func ACSHandlerFunc(sp *saml.ServiceProvider) http.HandlerFunc {
// ACSHandlerFunc creates a handler function that handles a SAML
// ACS request
func ACSHandlerFunc(sp *saml.ServiceProvider) (http.HandlerFunc, error) {
const op = "handler.ACSHandler"
switch {
case sp == nil:
return nil, fmt.Errorf("%s: missing service provider", op)
}
return func(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
samlResp := r.PostForm.Get("SAMLResponse")
Expand All @@ -20,5 +27,5 @@ func ACSHandlerFunc(sp *saml.ServiceProvider) http.HandlerFunc {
}

fmt.Fprintf(w, "Authenticated! %+v", res)
}
}, nil
}
12 changes: 10 additions & 2 deletions saml/handler/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,25 @@ package handler

import (
"encoding/xml"
"fmt"
"net/http"

"github.com/hashicorp/cap/saml"
)

func MetadataHandlerFunc(sp *saml.ServiceProvider) http.HandlerFunc {
// MetadataHandlerFunc creates a handler function that handles a SAML
// metadata request
func MetadataHandlerFunc(sp *saml.ServiceProvider) (http.HandlerFunc, error) {
const op = "handler.MetadataHandlerFunc"
switch {
case sp == nil:
return nil, fmt.Errorf("%s: missing service provider", op)
}
return func(w http.ResponseWriter, _ *http.Request) {
meta := sp.CreateMetadata()
err := xml.NewEncoder(w).Encode(meta)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
}, nil
}
9 changes: 7 additions & 2 deletions saml/handler/post_binding.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ import (
)

// PostBindingHandlerFunc creates a handler function that handles a HTTP-POST binding SAML request.
func PostBindingHandlerFunc(sp *saml.ServiceProvider) http.HandlerFunc {
func PostBindingHandlerFunc(sp *saml.ServiceProvider) (http.HandlerFunc, error) {
const op = "handler.PostBindingHandlerFunc"
switch {
case sp == nil:
return nil, fmt.Errorf("%s: missing service provider", op)
}
return func(w http.ResponseWriter, _ *http.Request) {
templ, _, err := sp.AuthnRequestPost("")
if err != nil {
Expand All @@ -33,5 +38,5 @@ func PostBindingHandlerFunc(sp *saml.ServiceProvider) http.HandlerFunc {
)
return
}
}
}, nil
}
11 changes: 9 additions & 2 deletions saml/handler/redirect_binding.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@ import (
"github.com/hashicorp/cap/saml"
)

func RedirectBindingHandlerFunc(sp *saml.ServiceProvider) http.HandlerFunc {
// RedirectBindingHandlerFunc creates a handler function that handles a SAML
// redirect request.
func RedirectBindingHandlerFunc(sp *saml.ServiceProvider) (http.HandlerFunc, error) {
const op = "handler.RedirectBindingHandlerFunc"
switch {
case sp == nil:
return nil, fmt.Errorf("%s: missing service provider", op)
}
return func(w http.ResponseWriter, r *http.Request) {
redirectURL, _, err := sp.AuthnRequestRedirect("relayState")
if err != nil {
Expand All @@ -24,5 +31,5 @@ func RedirectBindingHandlerFunc(sp *saml.ServiceProvider) http.HandlerFunc {
fmt.Printf("Redirect URL: %s\n", redirect)

http.Redirect(w, r, redirect, http.StatusFound)
}
}, nil
}

0 comments on commit 26c0e39

Please sign in to comment.