// SSOSendRequest1 does the 1st part of sending the request, handles the discovery service if needed func (tp *Testparams) SSOSendRequest1() { if tp.Logxml { log.Println(tp) log.Println("initialrequest:", tp.Initialrequest.Pp()) } u, _ := gosaml.SAMLRequest2Url(tp.Initialrequest, "", "", "") // initial request - to hub or birk tp.Resp, tp.Responsebody, tp.Err = tp.sendRequest(u, tp.Resolv[u.Host], "GET", "", tp.Cookiejar) // Errors from BIRK is 500 + text/plain if tp.Err != nil || tp.Resp.StatusCode == 500 { return } u, _ = tp.Resp.Location() query := u.Query() // we got to a discoveryservice - choose our testidp if len(query["return"]) > 0 && len(query["returnIDParam"]) > 0 { u, _ = url.Parse(query["return"][0]) q := u.Query() q.Set(query["returnIDParam"][0], tp.DSIdpentityID) u.RawQuery = q.Encode() tp.Resp, _, _ = tp.sendRequest(u, tp.Resolv[u.Host], "GET", "", tp.Cookiejar) } }
func ssoService(w http.ResponseWriter, r *http.Request) (err error) { defer r.Body.Close() // handle non ok urls gracefully // var err error // check issuer and acs in md // receiveRequest -> request, issuer md, receiver md // check for IDPList 1st in md, then in request then in query // sanitize idp from query or request request, spmd, _, err := gosaml.GetSAMLMsg(r, "SAMLRequest", hub_ops, hub, nil) if err != nil { return } idp := spmd.Query1(nil, "IDPList/ProviderID") // Need to find a place for IDPList if idp == "" { idp = request.Query1(nil, "IDPList/ProviderID") } if idp == "" { idp = r.URL.Query().Get("idpentityid") } if idp == "" { data := url.Values{} data.Set("return", "https://"+r.Host+r.RequestURI) data.Set("returnIDParam", "idpentityid") http.Redirect(w, r, config["HYBRID_DISCOVERY"]+data.Encode(), http.StatusFound) } else { var idpmd *gosaml.Xp acs := request.Query1(nil, "@AssertionConsumerServiceURL") acsurl := bify.ReplaceAllString(acs, "${1}wayf.wayf.dk/krib.php/$2") request.QueryDashP(nil, "@AssertionConsumerServiceURL", acsurl, nil) idpmd, err = edugain.MDQ(idp) if err != nil { return } const ssoquery = "./md:IDPSSODescriptor/md:SingleSignOnService[@Binding='urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect']/@Location" ssoservice := idpmd.Query1(nil, ssoquery) if ssoservice == "" { } request.QueryDashP(nil, "@Destination", ssoservice, nil) u, _ := gosaml.SAMLRequest2Url(request, "", "", "") http.Redirect(w, r, u.String(), http.StatusFound) } return }
// DoRunTestKrib func DoRunTestKrib(m modsset, overwrite *Testparams) (tp *Testparams) { if !*dokrib { return } tp = Newtp(overwrite) defer xxx(tp.Trace) tp.Usedoubleproxy = true ApplyMods(tp.Attributestmt, m["attributemods"]) tp.SSOCreateInitialRequest() ApplyMods(tp.Initialrequest, m["requestmods"]) // log.Println(tp.Initialrequest.Pp()) tp.SSOSendRequest1() if tp.Resp.StatusCode == 500 { fmt.Println(strings.TrimSpace(string(tp.Responsebody))) return } authnrequest := gosaml.Url2SAMLRequest(tp.Resp.Location()) ApplyMods(authnrequest, m["birkrequestmods"]) u, _ := gosaml.SAMLRequest2Url(authnrequest, "", "", "") tp.Resp.Header.Set("Location", u.String()) if tp.Resp.StatusCode == 500 { fmt.Println(strings.TrimSpace(string(tp.Responsebody))) return } tp.SSOSendRequest2() if tp.Newresponse == nil { log.Panic(string(tp.Responsebody)) } tp.SSOSendResponse() if tp.Resp.StatusCode == 500 { fmt.Println(strings.TrimSpace(string(tp.Responsebody))) return } tp.SSOSendResponse() if tp.Resp.StatusCode == 500 { fmt.Println(strings.TrimSpace(string(tp.Responsebody))) return } if tp.Logxml { log.Println("final response", tp.Newresponse.Pp()) } return }
// DoRunTestBirk runs a test on the hub - applying the necessary modifications on the way // Returns a *Testparams which can be analyzed func DoRunTestBirk(m modsset, overwrite *Testparams) (tp *Testparams) { if !*dobirk { return } tp = Newtp(overwrite) defer xxx(tp.Trace) tp.Firstidpmd = tp.Birkmd tp.Usedoubleproxy = true ApplyMods(tp.Attributestmt, m["attributemods"]) tp.SSOCreateInitialRequest() ApplyMods(tp.Initialrequest, m["requestmods"]) // log.Println(tp.Initialrequest.Pp()) tp.SSOSendRequest1() if tp.Resp.StatusCode == 500 { fmt.Println(strings.Trim(strings.SplitN(string(tp.Responsebody), " ", 2)[1], "\n ")) return } authnrequest := gosaml.Url2SAMLRequest(tp.Resp.Location()) ApplyMods(authnrequest, m["birkrequestmods"]) // log.Println(authnrequest.Pp()) u, _ := gosaml.SAMLRequest2Url(authnrequest, "", "", "") tp.Resp.Header.Set("Location", u.String()) tp.SSOSendRequest2() // pt. after signing - remember to have a before as well if tp.Resp.StatusCode == 500 { fmt.Println(strings.SplitN(string(tp.Responsebody), " ", 2)[1]) return } tp.SSOSendResponse() if tp.Resp.StatusCode == 500 { fmt.Println(strings.SplitN(string(tp.Responsebody), " ", 2)[1]) return } ApplyMods(tp.Newresponse, m["responsemods"]) tp.SSOSendResponse() if tp.Resp.StatusCode == 500 { fmt.Println(strings.Trim(strings.SplitN(string(tp.Responsebody), " ", 2)[1], "\n ")) return } return }
func birkService(w http.ResponseWriter, r *http.Request) (err error) { defer r.Body.Close() // get the sp as well to check for allowed acs req, _, mdbirkidp, err := gosaml.GetSAMLMsg(r, "SAMLRequest", edugain, edugain, nil) if err != nil { return } // Save the request in a cookie for when the response comes back cookievalue := base64.StdEncoding.EncodeToString(gosaml.Deflate(req.X2s())) http.SetCookie(w, &http.Cookie{Name: "BIRK", Value: cookievalue, Domain: config["HYBRID_DOMAIN"], Path: "/", Secure: true, HttpOnly: true}) idp := debify.ReplaceAllString(mdbirkidp.Query1(nil, "@entityID"), "$1$2") mdidp, err := hub_ops.MDQ(idp) mdhub, err := hub.MDQ(config["HYBRID_HUB"]) // use a std request - we take care of NameID etc in acsService below newrequest := gosaml.NewAuthnRequest(stdtiming.Refresh(), mdhub, mdidp) // to-do delete the following line when md for the hub is OK newrequest.QueryDashP(nil, "@AssertionConsumerServiceURL", config["HYBRID_HUB"]+config["HYBRID_ACS"], nil) u, _ := gosaml.SAMLRequest2Url(newrequest, "", "", "") // not signed so blank key, pw and algo http.Redirect(w, r, u.String(), http.StatusFound) return }