public IDictionary <string, string> SendDirectMessageAndGetResponse(ServiceEndpoint provider, IDictionary <string, string> fields) { if (provider == null) { throw new ArgumentNullException("provider"); } if (fields == null) { throw new ArgumentNullException("fields"); } byte[] body = ProtocolMessages.Http.GetBytes(fields); IDictionary <string, string> args; UntrustedWebResponse resp = null; string fullResponseText = null; try { resp = UntrustedWebRequest.Request(provider.ProviderEndpoint, body); // If an internal server error occurred, there won't be any KV-form stream // to read in. So instead, preserve whatever error the server did send back // and throw it in the exception. if (resp.StatusCode == HttpStatusCode.InternalServerError) { string errorStream = new StreamReader(resp.ResponseStream).ReadToEnd(); throw new OpenIdException(string.Format(CultureInfo.CurrentCulture, Strings.ProviderRespondedWithError, errorStream)); } if (Logger.IsDebugEnabled) { fullResponseText = resp.ReadResponseString(); } args = ProtocolMessages.KeyValueForm.GetDictionary(resp.ResponseStream); Logger.DebugFormat("Received direct response from {0}: {1}{2}", provider.ProviderEndpoint, Environment.NewLine, Util.ToString(args)); } catch (ArgumentException e) { Logger.DebugFormat("Full response from provider (where KVF was expected):{0}{1}", Environment.NewLine, fullResponseText); throw new OpenIdException("Failure decoding Key-Value Form response from provider.", e); } catch (WebException e) { throw new OpenIdException("Failure while connecting to provider.", e); } // All error codes are supposed to be returned with 400, but // some (like myopenid.com) sometimes send errors as 200's. if (resp.StatusCode == HttpStatusCode.BadRequest || Util.GetOptionalArg(args, provider.Protocol.openidnp.mode) == provider.Protocol.Args.Mode.error) { throw new OpenIdException(string.Format(CultureInfo.CurrentCulture, Strings.ProviderRespondedWithError, Util.GetOptionalArg(args, provider.Protocol.openidnp.error)), args); } else if (resp.StatusCode == HttpStatusCode.OK) { return(args); } else { throw new OpenIdException(string.Format(CultureInfo.CurrentCulture, Strings.ProviderRespondedWithUnrecognizedHTTPStatusCode, resp.StatusCode)); } }
public void DisallowUnsafeHosts() { string[] unsafeHosts = new[] { // IPv4 loopback representations "http://127.0.0.1", "http://127.100.0.1", "http://127.0.0.100", "http://2130706433", // 127.0.0.1 in decimal format "http://0x7f000001", // 127.0.0.1 in hex format // IPv6 loopback representation "http://[::1]", // disallowed schemes "ftp://ftp.microsoft.com", "xri://boo", }; foreach (string unsafeHost in unsafeHosts) { try { UntrustedWebRequest.Request(new Uri(unsafeHost)); Assert.Fail("ArgumentException expected but none thrown."); } catch (ArgumentException) { // expected exception caught. } } }
public void Redirects() { UntrustedWebRequest.WhitelistHosts.Add("localhost"); UntrustedWebResponse resp = new UntrustedWebResponse( new Uri("http://localhost/req"), new Uri("http://localhost/resp"), new WebHeaderCollection(), HttpStatusCode.OK, "text/html", null, new MemoryStream()); MockHttpRequest.RegisterMockResponse(resp); Assert.AreSame(resp, UntrustedWebRequest.Request(new Uri("http://localhost/req"))); }
public void WhitelistRegex() { UntrustedWebRequest.WhitelistHostsRegex.Add(new Regex(@"^127\.\d+\.\d+\.\d+$")); // if this works, then we'll be waiting around for localhost to not respond // for a while unless we take the timeout to zero. UntrustedWebRequest.Timeout = TimeSpan.Zero; // will be reset in TearDown method try { UntrustedWebRequest.Request(new Uri("http://127.0.0.1:1234")); // We're verifying that an ArgumentException is not thrown // since we requested localhost to be allowed. } catch (WebException) { // It's ok, we're not expecting the request to succeed. } }
public void RelativeRedirect() { UntrustedWebRequest.WhitelistHosts.Add("localhost"); UntrustedWebResponse resp1 = new UntrustedWebResponse( new Uri("http://localhost/dir/file1"), new Uri("http://localhost/dir/file1"), new WebHeaderCollection { { HttpResponseHeader.Location, "file2" }, }, HttpStatusCode.Redirect, "text/html", null, new MemoryStream()); MockHttpRequest.RegisterMockResponse(resp1); UntrustedWebResponse resp2 = new UntrustedWebResponse( new Uri("http://localhost/dir/file2"), new Uri("http://localhost/dir/file2"), new WebHeaderCollection(), HttpStatusCode.OK, "text/html", null, new MemoryStream()); MockHttpRequest.RegisterMockResponse(resp2); Assert.AreSame(resp2, UntrustedWebRequest.Request(new Uri("http://localhost/dir/file1"))); }
public void BlacklistRegex() { UntrustedWebRequest.BlacklistHostsRegex.Add(new Regex(@"\Wmicrosoft.com$")); UntrustedWebRequest.Request(new Uri("http://WWW.MICROSOFT.COM")); }
public void Blacklist() { UntrustedWebRequest.BlacklistHosts.Add("www.microsoft.com"); UntrustedWebRequest.Request(new Uri("http://WWW.MICROSOFT.COM")); }
/// <summary> /// Performs YADIS discovery on some identifier. /// </summary> /// <param name="uri">The URI to perform discovery on.</param> /// <param name="requireSsl">Whether discovery should fail if any step of it is not encrypted.</param> /// <returns> /// The result of discovery on the given URL. /// Null may be returned if an error occurs, /// or if <paramref name="requireSsl"/> is true but part of discovery /// is not protected by SSL. /// </returns> public static DiscoveryResult Discover(UriIdentifier uri, bool requireSsl) { UntrustedWebResponse response; try { if (requireSsl && !string.Equals(uri.Uri.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase)) { //Logger.WarnFormat("Discovery on insecure identifier '{0}' aborted.", uri); return(null); } response = UntrustedWebRequest.Request(uri, null, new[] { ContentTypes.Html, ContentTypes.XHtml, ContentTypes.Xrds }, requireSsl, UntrustedWebRequest.IdentifierDiscoveryCachePolicy); if (response.StatusCode != System.Net.HttpStatusCode.OK) { //Logger.ErrorFormat("HTTP error {0} {1} while performing discovery on {2}.", (int)response.StatusCode, response.StatusCode, uri); return(null); } } catch (ArgumentException ex) { // Unsafe URLs generate this //Logger.WarnFormat("Unsafe OpenId URL detected ({0}). Request aborted. {1}", uri, ex); return(null); } UntrustedWebResponse response2 = null; if (isXrdsDocument(response)) { //Logger.Debug("An XRDS response was received from GET at user-supplied identifier."); response2 = response; } else { string uriString = response.Headers.Get(HeaderName); Uri url = null; if (uriString != null) { if (Uri.TryCreate(uriString, UriKind.Absolute, out url)) { //Logger.DebugFormat("{0} found in HTTP header. Preparing to pull XRDS from {1}", HeaderName, url); } } if (url == null && (response.ContentType.MediaType == ContentTypes.Html || response.ContentType.MediaType == ContentTypes.XHtml)) { url = FindYadisDocumentLocationInHtmlMetaTags(response.ReadResponseString()); if (url != null) { //Logger.DebugFormat("{0} found in HTML Http-Equiv tag. Preparing to pull XRDS from {1}", HeaderName, url); } } if (url != null) { if (!requireSsl || string.Equals(url.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase)) { response2 = UntrustedWebRequest.Request(url, null, new[] { ContentTypes.Xrds }, requireSsl, UntrustedWebRequest.IdentifierDiscoveryCachePolicy); if (response2.StatusCode != System.Net.HttpStatusCode.OK) { return(null); } } else { //Logger.WarnFormat("XRDS document at insecure location '{0}'. Aborting YADIS discovery.", url); } } } return(new DiscoveryResult(uri, response, response2)); }