C# Mono ssl issue - c#

Alright, I am using the following code:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
ServicePointManager.ServerCertificateValidationCallback += (send, cert, chain, sslPolicyErrors) => true;
string dlclresponse = "";
try
{
WebRequest wr = WebRequest.Create(url);
Stream stream = wr.GetResponse().GetResponseStream();
Debug.WriteLine("HTTPDEBUG:" + " Success");
dlclresponse = new StreamReader(stream).ReadToEnd();
}
catch (WebException we)
{
var ex = we as Exception;
while (ex != null)
{
Debug.WriteLine("HTTPDEBUG:" + ex.ToString());
ex = ex.InnerException;
}
}
I am fully aware that this just neglects the security behind ssl, but I just can't seem to get this working on my Ubuntu server using mono.
The url that isn't working is the following:
https://atarashii.toshocat.com/2.1/anime/schedule
It keeps giving me this exception:
System.Net.WebException: Error: SendFailure (Error writing headers) ---> System.Net.WebException: Error writing headers ---> System.IO.IOException: The authentication or decryption has failed. ---> Mono.Security.Protocol.Tls.TlsException: The authentication or decryption has failed.
I've read quit a bunch but honestly I don't understand much of it.
What am I doing wrong? Most of the answers found to this solution is something like the above, but it just keeps crashing. I tried multiple about everything from here:
Mono https webrequest fails with "The authentication or decryption has failed"
But none seemed to do anything ;(.
At the moment I am really lurking to use that curl hack since this just feels unsolvable at the moment.
I hope maybe one of you might have another idea which could help me out.
Thanks in advance!

Ok, stupid me. I actually had an older version of mono, 4.2.1.102 in fact. Which just didn't want to work with me. Removing that and updating to the latest version fixed it ;/. Bye bye hours wasted on finding the ultimate: did you reinstall it fix.

Related

SSIS C# HTTP GetAsync not waiting for the response

I'm using the getAsync(URL).Result function inside an SSIS C# task. In the debug window I can see the Result="{Not yet computed}".
The code is working very well for the last 1 year, although stops working after a new release of the API came up. It seems it's not waiting for the response.
MY CODE:
public void Main()
{
GetRequest(Dts.Variables["User::URL"].Value.ToString());
Dts.TaskResult = (int)ScriptResults.Success;
}
private static void GetRequest(string url)
{
try
{
HttpClient client = new HttpClient();
HttpResponseMessage response = client.GetAsync(url).Result;
response.EnsureSuccessStatusCode();
}
catch (Exception e)
{
System.Console.WriteLine("Caught Exception: " + e.Message);
}
}
Can someone give me some insights?
Thank you
Thank you #jdweng
Copy of the comment that helps me to solve the issue:
Sounds like a TLS authentication issue. Five years ago the industry decided to eliminate TLS 1.0/1.1 due to security issues. In June this year Microsoft pushed a security update disabling TLS 1.0/1.1 and now require clients to use TLS 1.2/1.3. So adding to your code following seems to solve issue : ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Getting "The request was aborted: Could not create SSL/TLS secure channel" exception when validating the URL

I am trying to validate URL in C# code and I am facing error on Windows server 2012R2 server machine
The request was aborted: Could not create SSL/TLS secure channel
I have checked the multiple solutions found/got via various posts in net and nothing resolved this.
C# code
public static bool isBrokenLink(string url, string KBid)
{
Boolean isBrokenLink = false;
try
{
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create(url);
webRequest.CookieContainer = new CookieContainer();
webRequest.AllowAutoRedirect = false;
webRequest.Timeout = 40000;
using (HttpWebResponse httpresponse = (HttpWebResponse)webRequest.GetResponse())
{
if (httpresponse.StatusCode == HttpStatusCode.OK)
{
isBrokenLink = false;
}
else if (httpresponse.StatusCode >= HttpStatusCode.Ambiguous && httpresponse.StatusCode <= HttpStatusCode.RedirectKeepVerb)
{
isBrokenLink = false;
}
else
{
isBrokenLink = true;
}
}
}
catch (Exception ex)
{
isBrokenLink = true;
}
return isBrokenLink;
}
On the machine, I have installed both IE and Chrome browser. When I trying to load the URL in IE 11 browser, I am getting the same error.
When trying to check in the chrome browser with the URL, it works fine. I also tried to set the default browser as chrome in my machine and checked. But still the same issue. Does anybody know about this issue?
Can we modify the code to consider the chrome browser for HttpWebResponse validation?
There can be many reasons for this kind of error and the provided details are not sufficient. Typical problems are with validating certificates or with TLS versions or with supported ciphers etc.
In general: your C# code and IE use the same TLS stack built into Windows while Chrome comes with its own TLS stack (BoringSSL). Setting Chrome is default browser will not magically replace the OS TLS stack, i.e. it will still only used by Chrome and not your C# program.
If the URL is public you can use SSLLabs to get more information about this site which also displays typical problems and compatibility with various kind of clients. This might help you to narrow down the problem yourself.

SSL Handshake exception for HTTP Get method - ASP.NET core 2.1

I'm trying to invoke rest method with asp.net core 2.1 but keep getting the ssl exception even I'm using a http in this call. The code that im using is:
public async Task<bool> SyncTickets()
{
try
{
HttpClient client = new HttpClient();
var path = "http://testdesk.vmw.be:8082/helpdesk/WebObjects/Helpdesk.woa/ra/PriorityTypes?username=admin&apiKey=bJZw2jP8wgtyGXI736K6DfUiEjJYTLuqC8fGuOBN";
Ticket ticket = new Ticket();
HttpResponseMessage response = await client.GetAsync(path);
if (response.IsSuccessStatusCode)
{
var responseMsg = await response.Content.ReadAsAsync<Object>();
return true;
}
return false;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
return false;
}
Exception is:
{System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception. ---> System.IO.IOException: The handshake failed due to an unexpected packet format
Exception occur on GetAsync method.
When I'm using the same path to test trough postman or browser it's working perfectly fine, I'm getting the response.
Any idea what I'm missing here?
Maybe your server requires encryption anyway and redirects to https?
If that's the case and https still reports add before creating HttpClient:
ServicePointManager.ServerCertificateValidationCallback +=
(sender, cert, chain, sslPolicyErrors) => true;
This will accept all certs. This setting is global to your app. DO NOT USE IT IN PRODUCTION. If your server uses selfsigned cert or internal CA issued cert use it only for testing. In production add proper validation of internal CA or accept only specific self-signed cert. Browsers might have internal certs or CAs added on PC's from domain controller or via group policy and therefore they don't report them untrusted.
Also, for https you can explicitly use TLS protocols. Add the following line before creating HttpClient and try again:
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
If you have defined protocol set at your server, you can narrow down protocol list just to enable those actually supported.

WebClient.DownloadFile requires what exactly for the URI?

I'm good with the code, it works great for other solutions of mine. I have a knowledge gap as I do not understand what constitutes a URI. This should work, but does not:
https://www.nasdaq.com/screening/companies-by-name.aspx?letter=0&exchange=nasdaq&render=download
Now I'm thinking that this is not a file right? Throwing the above at a browser provides a file though. The exception message is "The underlying connection was closed: An unexpected error occurred on a receive."
String address = "https://www.nasdaq.com/screening/companies-by-name.aspx?letter=0&exchange=nasdaq&render=download";
.....
using (WebClient Client = new WebClient())
{
try
{
Client.DownloadFile(address, destPath + filename);
}
catch (Exception ex)
{
Log.Line("Error: " + ex.Message);
return 1;
}
}
The URI:
this link
You've got a perfectly valid URI. The target server may respond to requests in a different way than you expect though. For example depending on your web client. To debug issues like this use curl.
curl -v https://www.nasdaq.com/screening/companies-by-name.aspx?letter=0&exchange=nasdaq&render=download
The above command shows you that the server does not reply with the expected csv file. That's not a problem in your code. You can try to pretend a different user agent using the curl -H flag or set some redirection options until you get there.
In your specific case it seems to be the header Accept-Encoding: gzip that solves the issue.

"The underlying connection was closed: An unexpected error occurred on a send.". Postman goes OK with same headers

Scenario
Win10 x64
VS2013
I'm trying to make a WebRequest, but I'm getting the following error:
The underlying connection was closed: An unexpected error occurred on a send.
Digging into the inner exception, I got:
"Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."
The code which does the request is the following:
private static Hashtable exec (String method, String uri, Object data, String contentType) {
Hashtable response;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create (API_BASE_URL + uri);
request.UserAgent = "MercadoPago .NET SDK v"+MP.version; //version resolves to 0.3.4
request.Accept = MIME_JSON; // application/json
request.Method = method; //GET
request.ContentType = contentType; //application/json
setData (request, data, contentType); //setData in this case does nothing.
String responseBody = null;
try {
HttpWebResponse apiResult = (HttpWebResponse)request.GetResponse (); //Error throws here
responseBody = new StreamReader (apiResult.GetResponseStream ()).ReadToEnd ();
response = new Hashtable();
response["status"] = (int) apiResult.StatusCode;
response["response"] = JSON.JsonDecode(responseBody);
} catch (WebException e) {
Console.WriteLine (e.Message);
}
}
What i've already done:
Made the request via Console Application and MVC Application controller. Both throws the same exception
Called the API via Postman with the exact same headers, which brings me the content correctly.
Those requests were working okay via c# about 4 days ago and I suddenly started having issues, but considering the fact that it responds okay for Postman, I can't figure out where's the problem.
Here's Postman's response
EDIT: Did both requests with Fiddler listening. The result for Postman shows a direct request to the API with HTTPS. When trying with my ConsoleApplication, it shows a HTTP request, which makes a tunnel to the API endpoint, port 443.
The TextView from Fiddler for the tunnel request says the following:
I noticed the "time" field which refers to a very old date, but i don't know what does it mean.
It is kind of bad practice to enable Tls12 like this-
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
In future, if you'd need to use higher version of TLS, you'll have to update your code.
If you are using an older version of .NET, you can simply switch it higher version in which Tls12 is enabled by default.
For example, this simple change in your web.config will enable Tls12 automatically-
<httpRuntime targetFramework="4.6.1"/>
You can try the code below:
string url = ""; // url of the endpoint
WebClient client = new WebClient();
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
client.Encoding = Encoding.UTF8;
client.Headers.Add("content-type", "application/json"); // same as other parameters in the header
var data = client.DownloadString(url);
Figured it out. I needed to include the use of TLS1.2.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
(As a reference for others who have the same issue)this also might be the result of a Double Hop issue , where you should pass the credited user along(in the pool) to the passing server or from one Environment to the other , otherwise the user is set to "ANONYMOUS/USER" and you will get a "An existing connection was forcibly closed by the remote host." Error
i found same error, just mention
request.UserAgent = "anything u want";

Categories

Resources