/* * Created by SharpDevelop. * User: dmacinto * Date: 10/05/11 * Time: 3:04 PM * * To change this template use Tools | Options | Coding | Edit Standard Headers. */ using System; using System.Net; using System.IO; using System.Text; //using System.Configuration; using System.Security.Cryptography.X509Certificates; using System.Net.Security; using Org.BouncyCastle.Asn1.Ocsp; namespace bdf { /// /// Provides wrapper around HttpWebRequest, handling 302 redir, binary and certificate issues /// public class Web { public Web() { } //Login1 (used to acquire token for auth) public static bool MakeRequest(string method, string uri, bool json, ref string token, ref byte[] webdata, ref CookieContainer cookie) { bool redir = true; string vars = ""; //string token = bdf.token; WebProxy proxy = null; return MakeByteRequest(method, redir, uri, vars, ref webdata, json, ref token, ref cookie, proxy); } // as above but with RO token option public static bool MakeRequest(string method, string uri, bool json, string token, ref byte[] webdata, ref CookieContainer cookie) { bool redir = true; string vars = ""; WebProxy proxy = null; return MakeByteRequest(method, redir, uri, vars, ref webdata, json, ref token, ref cookie, proxy); } //Login2 public static bool MakeRequest(string method, string uri, string vars, bool json, ref byte[] webdata, ref CookieContainer cookie) { bool redir = true; string token = bdf.token; WebProxy proxy = null; return MakeByteRequest(method, redir, uri, vars, ref webdata, json, ref token, ref cookie, proxy); } //as above with RO token public static bool MakeRequest(string method, string uri, string vars, bool json, string token, ref byte[] webdata, ref CookieContainer cookie) { bool redir = true; WebProxy proxy = null; return MakeByteRequest(method, redir, uri, vars, ref webdata, json, ref token, ref cookie, proxy); } /* public static bool MakeRequest(string method, string uri, ref byte[] webdata, ref CookieContainer cookie ) { //byte[] webdata = null; bool redir = true; string vars = ""; string token = bdf.token; bool json = (token != ""); WebProxy proxy = null; bool success = MakeByteRequest(method, redir, uri, vars, ref webdata, json, token, ref cookie, proxy); //string respstr = ""; //if (webdata != null) { respstr = Encoding.ASCII.GetString(webdata); } return success; } */ // old school object call public static object[] MakeRequest(string method, bool redir, string uri, string vars, ref CookieContainer cookie, WebProxy proxy) { byte[] webdata = null; string token = bdf.token; bool json = true; bool success = MakeByteRequest( method, redir, uri, vars, ref webdata, json, ref token, ref cookie, proxy); string respstr = ""; if ( webdata != null ) { respstr = Encoding.ASCII.GetString(webdata); } //Console.WriteLine("{0}",respstr); return new object[]{ success, respstr }; } /* public static object[] MakeRequest(string method, bool redir, string uri, string vars, ref CookieContainer cookie, WebProxy proxy) { object[] r = MakeByteRequest(method, redir, uri, vars, ref cookie, proxy); string respstr = ""; if ((byte[])r[1] != null) { respstr = Encoding.ASCII.GetString((byte[])r[1]); } return new object[] { r[0], respstr }; } */ // full feature set call public static bool MakeByteRequest(string method, bool redir, string uri, string vars, ref byte[] data, bool json, ref string token, ref CookieContainer cookie, WebProxy proxy) { bool success = false; HttpWebRequest webRequest = null; // Consider setting webRequest.KeepAlive = false; for the logout call to shut down the TCP resources. if (method == "GET") { webRequest = (HttpWebRequest)WebRequest.Create(string.Format("{0}{1}", uri, vars)); webRequest.Method = "GET"; webRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36 OPR/76.0.4017.123"; { // Try to outsmart Win11/Net481...keep NTLM auth alive webRequest.Credentials = bdf.cache; webRequest.PreAuthenticate = true; //added for Win11 .NET which fails as it does not auto-redirect webRequest.KeepAlive = true; } if (token != "") { webRequest.PreAuthenticate = true; //webRequest.Headers.Add("Authorization", "Bearer " + token); //webRequest.Headers.Add("Origin", uri); //Feb2023 //webRequest.Headers.Add("Authorization", "Negotiate " + token); //webRequest.Headers.Add("Authorization", "Negotiate " + token); //webRequest.Headers.Add("Upgrade-Insecure-Requests", "1"); } if (json) { webRequest.Accept = "application/json"; } webRequest.AllowAutoRedirect = redir; webRequest.Method = method; webRequest.CookieContainer = cookie; webRequest.Timeout = bdf.webMaxWait * 60 * 1000; // convert minutes of wait into milliseconds if (proxy != null) { webRequest.Proxy = proxy; } } else if (method == "POST") { byte[] buffer = Encoding.ASCII.GetBytes(vars); webRequest = (HttpWebRequest)WebRequest.Create(uri); { webRequest.Credentials = bdf.cache; webRequest.PreAuthenticate = true; //added for Win11 .NET which fails as it does not auto-redirect //webRequest.UnsafeAuthenticatedConnectionSharing = true; webRequest.KeepAlive = true; } if (proxy != null) { webRequest.Proxy = proxy; } webRequest.Method = "POST"; webRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36 OPR/76.0.4017.123"; if (token != "") // basically is this a JSON request { webRequest.PreAuthenticate = true; webRequest.Headers.Add("Authorization", "Bearer " + token); } if (json) { webRequest.Accept = "application/json"; webRequest.ContentType = "application/json"; } else { webRequest.ContentType = "application/x-www-form-urlencoded"; } webRequest.ContentLength = buffer.Length; webRequest.AllowAutoRedirect = redir; webRequest.Method = method; webRequest.CookieContainer = cookie; webRequest.Timeout = bdf.webMaxWait * 60 * 1000; // convert minutes of wait into milliseconds if (proxy != null) { webRequest.Proxy = proxy; } //We open a stream for writing the postvars Stream PostData = webRequest.GetRequestStream(); //Now we write, and afterwards, we close. Closing is always important! PostData.Write(buffer, 0, buffer.Length); PostData.Close(); } else { Logger.Log("Request not understood"); Logger.Log(3,"FAIL - UNKNOWN METHOD" ); return false; } // allows for validation of SSL conversations ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback( ValidateRemoteCertificate ); HttpWebResponse response = null; try { //ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072 | (SecurityProtocolType)768 | (SecurityProtocolType)192; //3072 //ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls12 | System.Net.SecurityProtocolType.Tls13; try { response = (HttpWebResponse)webRequest.GetResponse(); } catch (WebException ex) { //string authresp = Web_Auth.HttpAuthHandler.ExtractAuthenticateHeader(ex); //token = authresp.Split(new char[] { ' ' })[1]; Logger.Log(0, "webRequest failed. {0}", ex.Message); } //Let's show some information about the response //Logger.Log(6, "YY {0}", response.StatusCode); //Logger.Log(6, "ZZ {0}", response.GetResponseHeader("error")); foreach (Cookie cook in response.Cookies) { cookie.Add(cook); } //DumpCookies(response.Cookies); if ((response.StatusCode == HttpStatusCode.Found) || (response.StatusCode == HttpStatusCode.OK)) { success = true; } using (Stream s = response.GetResponseStream()) { //byte[] data = ReadStreamFully(s); data = ReadStreamFully(s); s.Close(); //System.IO.StreamWriter file = new System.IO.StreamWriter("webcs.txt"); file.BaseStream.Write(data,0,data.Length); file.Close(); //object[] ret = { success, Encoding.ASCII.GetString(data) , data }; //object[] ret = { success, data }; //return true; } return success; } catch (Exception ex) { Logger.Log(0, "WebRequest error: {0}", ex.Message); //object[] ret = { false, null }; return false; } finally { if (response != null) response.Close(); } } // this version worked for Mono and with a proxy like Fiddler, but not instraight up .NET481 on Win11 public static bool working_MakeByteRequest(string method, bool redir, string uri, string vars, ref byte[] data, bool json, ref string token, ref CookieContainer cookie, WebProxy proxy) { bool success = false; HttpWebRequest webRequest = null; // Consider setting webRequest.KeepAlive = false; for the logout call to shut down the TCP resources. if (method == "GET") { webRequest = (HttpWebRequest)WebRequest.Create(string.Format("{0}{1}", uri, vars)); webRequest.Method = "GET"; webRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36 OPR/76.0.4017.123"; { // Try to outsmart Win11/Net481... webRequest.Credentials = CredentialCache.DefaultNetworkCredentials; //cache; webRequest.UnsafeAuthenticatedConnectionSharing = true; webRequest.UseDefaultCredentials = true; webRequest.PreAuthenticate = true; //added for Win11 .NET which fails as it does not auto-redirect webRequest.KeepAlive = true; } if (token != "") { webRequest.PreAuthenticate = true; //webRequest.Headers.Add("Authorization", "Bearer " + token); //webRequest.Headers.Add("Origin", uri); //Feb2023 //webRequest.Headers.Add("Authorization", "Negotiate " + token); //webRequest.Headers.Add("Authorization", "Negotiate " + token); //webRequest.Headers.Add("Upgrade-Insecure-Requests", "1"); } if (json) { webRequest.Accept = "application/json"; } webRequest.AllowAutoRedirect = redir; webRequest.Method = method; webRequest.CookieContainer = cookie; webRequest.Timeout = bdf.webMaxWait * 60 * 1000; // convert minutes of wait into milliseconds if (proxy != null) { webRequest.Proxy = proxy; } } else if (method == "POST") { byte[] buffer = Encoding.ASCII.GetBytes(vars); webRequest = (HttpWebRequest)WebRequest.Create(uri); { webRequest.PreAuthenticate = true; //added for Win11 .NET which fails as it does not auto-redirect webRequest.UnsafeAuthenticatedConnectionSharing = true; webRequest.KeepAlive = true; } if (proxy != null) { webRequest.Proxy = proxy; } webRequest.Method = "POST"; webRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36 OPR/76.0.4017.123"; if (token != "") // basically is this a JSON request { webRequest.PreAuthenticate = true; webRequest.Headers.Add("Authorization", "Bearer " + token); } if (json) { webRequest.Accept = "application/json"; webRequest.ContentType = "application/json"; } else { webRequest.ContentType = "application/x-www-form-urlencoded"; } webRequest.ContentLength = buffer.Length; webRequest.AllowAutoRedirect = redir; webRequest.Method = method; webRequest.CookieContainer = cookie; webRequest.Timeout = bdf.webMaxWait * 60 * 1000; // convert minutes of wait into milliseconds if (proxy != null) { webRequest.Proxy = proxy; } //We open a stream for writing the postvars Stream PostData = webRequest.GetRequestStream(); //Now we write, and afterwards, we close. Closing is always important! PostData.Write(buffer, 0, buffer.Length); PostData.Close(); } else { Logger.Log("Request not understood"); Logger.Log(3, "FAIL - UNKNOWN METHOD"); return false; } // allows for validation of SSL conversations ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback( ValidateRemoteCertificate ); HttpWebResponse response = null; try { //ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072 | (SecurityProtocolType)768 | (SecurityProtocolType)192; //3072 //ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls | System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls12; try { response = (HttpWebResponse)webRequest.GetResponse(); } catch (WebException ex) { //string authresp = Web_Auth.HttpAuthHandler.ExtractAuthenticateHeader(ex); //token = authresp.Split(new char[] { ' ' })[1]; Logger.Log(0, "webRequest failed. {0}", ex.Message); } //Let's show some information about the response //Logger.Log(6, "YY {0}", response.StatusCode); //Logger.Log(6, "ZZ {0}", response.GetResponseHeader("error")); foreach (Cookie cook in response.Cookies) { cookie.Add(cook); } //DumpCookies(response.Cookies); if ((response.StatusCode == HttpStatusCode.Found) || (response.StatusCode == HttpStatusCode.OK)) { success = true; } using (Stream s = response.GetResponseStream()) { //byte[] data = ReadStreamFully(s); data = ReadStreamFully(s); s.Close(); //System.IO.StreamWriter file = new System.IO.StreamWriter("webcs.txt"); file.BaseStream.Write(data,0,data.Length); file.Close(); //object[] ret = { success, Encoding.ASCII.GetString(data) , data }; //object[] ret = { success, data }; //return true; } return success; } catch (Exception ex) { Logger.Log(0, "WebRequest error: {0}", ex.Message); //object[] ret = { false, null }; return false; } finally { if (response != null) response.Close(); } } /* public static object[] zMakeByteRequest(string method, bool redir, string uri, string vars, ref CookieContainer cookie, WebProxy proxy) { bool success = false; HttpWebRequest webRequest = null; // Set the 'Timeout' property in Milliseconds. //webRequest.Timeout = 1000 * 60 * 3; // 3min if ( method == "GET" ) { webRequest = (HttpWebRequest)WebRequest.Create(string.Format("{0}{1}", uri, vars)); webRequest.Method = "GET"; webRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36 OPR/76.0.4017.123"; if ( bdf.token != "" ) { webRequest.PreAuthenticate = true; webRequest.Headers.Add("Authorization", "Bearer " + bdf.token ); webRequest.Accept = "application/json"; } webRequest.AllowAutoRedirect = redir; webRequest.Method = method; webRequest.CookieContainer = cookie; //webRequest.Timeout = 180000; // 3min webRequest.Timeout = bdf.webMaxWait * 60 * 1000; // convert minutes of wait into milliseconds if (proxy != null) { webRequest.Proxy = proxy; } } else if ( method == "POST" ) { byte[] buffer = Encoding.ASCII.GetBytes(vars); webRequest = (HttpWebRequest)WebRequest.Create(uri); if (proxy != null) { webRequest.Proxy = proxy; } webRequest.Method = "POST"; webRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36 OPR/76.0.4017.123"; if ( bdf.token != "" ) // basically is this a JSON request { webRequest.PreAuthenticate = true; webRequest.Headers.Add("Authorization", "Bearer " + bdf.token ); webRequest.Accept = "application/json"; webRequest.ContentType = "application/json"; } else { webRequest.ContentType = "application/x-www-form-urlencoded"; webRequest.ContentType = "application/json"; // all bdf requests are json } webRequest.ContentLength = buffer.Length; webRequest.AllowAutoRedirect = redir; webRequest.Method = method; webRequest.CookieContainer = cookie; webRequest.Timeout = bdf.webMaxWait * 60 * 1000; // convert minutes of wait into milliseconds if (proxy != null) { webRequest.Proxy = proxy; } //We open a stream for writing the postvars Stream PostData = webRequest.GetRequestStream(); //Now we write, and afterwards, we close. Closing is always important! PostData.Write(buffer, 0, buffer.Length); PostData.Close(); } else { Logger.Log("Request not understood"); object[] ret = { false, "FAIL - UNKNOWN METHOD" }; return ret; } // allows for validation of SSL conversations ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback( ValidateRemoteCertificate ); HttpWebResponse response = null; try { //ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072 | (SecurityProtocolType)768 | (SecurityProtocolType)192; //3072 //ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls | System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls12; response = (HttpWebResponse)webRequest.GetResponse(); //Let's show some information about the response Logger.Log(6,"{0}",response.StatusCode); foreach (Cookie cook in response.Cookies) { cookie.Add(cook); } //DumpCookies(response.Cookies); if ( ( response.StatusCode == HttpStatusCode.Found ) || ( response.StatusCode == HttpStatusCode.OK ) ) { success = true; } using (Stream s = response.GetResponseStream() ) { byte[] data = ReadStreamFully(s); s.Close(); //System.IO.StreamWriter file = new System.IO.StreamWriter("webcs.txt"); file.BaseStream.Write(data,0,data.Length); file.Close(); //object[] ret = { success, Encoding.ASCII.GetString(data) , data }; object[] ret = { success, data }; return ret; } } catch (Exception ex) { Logger.Log(0,"WebRequest error: {0}",ex.Message); object[] ret = { false, null }; return ret; } finally { if (response != null) response.Close(); } } */ public static byte[] ReadStreamFully (Stream stream) { byte[] buffer = new byte[32768]; using (MemoryStream ms = new MemoryStream()) { while (true) { int read = stream.Read (buffer, 0, buffer.Length); if (read <= 0) //return ms; return ms.ToArray(); ms.Write (buffer, 0, read); } } } // callback used to validate the certificate in an SSL conversation private static bool ValidateRemoteCertificate( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors policyErrors ) { /*if (Convert.ToBoolean(ConfigurationManager.AppSettings["IgnoreSslErrors"])) { // allow any old dodgy certificate... return true; } else { return policyErrors == SslPolicyErrors.None; } */ return true; //policyErrors == SslPolicyErrors.None; } /* private static void DumpCookies ( System.Net.CookieCollection ckjar ) { foreach (Cookie cook in ckjar) //foreach (Cookie cook in cookie) { Logger.Log("Cookie:"); Logger.Log(0, "{0} = {1}", cook.Name, cook.Value); Logger.Log(0, "Domain: {0}", cook.Domain); Logger.Log(0, "Path: {0}", cook.Path); Logger.Log(0, "Port: {0}", cook.Port); Logger.Log(0, "Secure: {0}", cook.Secure); Logger.Log(0, "When issued: {0}", cook.TimeStamp); Logger.Log(0, "Expires: {0} (expired? {1})", cook.Expires, cook.Expired); Logger.Log(0, "Don't save: {0}", cook.Discard); Logger.Log(0, "Comment: {0}", cook.Comment); Logger.Log(0, "Uri for comments: {0}", cook.CommentUri); Logger.Log(0, "Version: RFC {0}" , cook.Version == 1 ? "2109" : "2965"); // Show the string representation of the cookie. Logger.Log (0, "String: {0}", cook.ToString()); } } */ } }