Xamarin Android FTP authentication problem on startup - c#

I'm developing an Android application in C# language with Xamarin.
In this application I need a service that starts after the device boot and upload files in a FTP server.
If I start this service with a button click action all works good, but if I use a BroadcastReceiver and I intercept the BOOT_COMPLETED event to start the FTP connection, I receive this error:
ex.Message: The authentication or decryption has failed.
ex.StackTrace: at System.Net.FtpWebRequest.EndGetRequestStream (System.IAsyncResult asyncResult)
at System.Net.FtpWebRequest.GetRequestStream ()
at TestProject.FTPUtility.upload (System.String userName, System.String password, System.String sourceFile, System.String targetFile)
I don't understand why I receive the authentication or decryption error only if the service starts on startup. I tried also to start the connection only after a ping success (to wait the device internet connection) but nothing is changed.

I solved the problem with this line of code:
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

Related

Can't connect to OpenSSH SFTP when using SSH.NET in a WCF Service

The organization has a integration service layer built on .NET 4.5.2. It has several WCF services running. One service uses SFTP to connect to SFTP server in the same machine to read and move some files. It uses simple username and password authentication. All works well in the production environments.
I'm trying to debug the solution in Visual Studio 2019 (16.8.6) and having trouble connecting to the SFTP server. It uses Renci SSH.NET v2016.0.0. Upgrading is not an option. I just want to debug it on the development environment.
The development environment (Windows Server 2012 R2) already had OpenSSH installed (OpenSSH_for_Windows_8.9p1, LibreSSL 3.4.3). And I'm running Visual Studio as administrator.
I can connect to the SFTP using the specific user and password in CMD, and in FileZilla. I also created a simple console application and it is also able to connect, navigate to the relevant folder and read the files.
I then created a simple WCF service and a service host and tried to connect, but this fails. It gives the error, "An existing connection was forcibly closed by the remote host", when it tries to connect.
Sample of console app connect code, This one works.
SftpClient _client = new SftpClient(host, u1, password1);
_client.Connect();
This is the code sample from the WCF service.
public string GetSFTPConnection(ConnectionDetails connectionDetails)
{
try
{
SftpClient _client = new SftpClient(connectionDetails.Host, connectionDetails.UserName, connectionDetails.Password);
_client.Connect();
if (_client.IsConnected)
{
return "SFTP Connected Successfully!";
}
return "SFTP Connection Failed!";
}
catch (Exception e)
{
return $"SFT Connection Error# {e}";
}
}
Error:
InnerException = An existing connection was forcibly closed by the remote host
StackTrace = at Renci.SshNet.Session.WaitOnHandle(WaitHandle waitHandle, TimeSpan timeout)
at Renci.SshNet.Session.Connect()
at Renci.SshNet.BaseClient.Connect()
at SFTPServiceNew.Service1.GetSFTPConnection(ConnectionDetails connectionDetails) in C...
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header />
<s:Body>
<GetSFTPConnectionResponse xmlns="http://tempuri.org/">
<GetSFTPConnectionResult>SFT Connection Error# Renci.SshNet.Common.SshConnectionException: An existing connection was forcibly closed by the remote host ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at Renci.SshNet.Abstractions.SocketAbstraction.Read(Socket socket, Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
at Renci.SshNet.Session.SocketRead(Int32 length, Byte[] buffer)
at Renci.SshNet.Session.ReceiveMessage()
at Renci.SshNet.Session.MessageListener()
--- End of inner exception stack trace ---
at Renci.SshNet.Session.WaitOnHandle(WaitHandle waitHandle, TimeSpan timeout)
at Renci.SshNet.Session.Connect()
at Renci.SshNet.BaseClient.Connect()
at SFTPServiceNew.Service1.GetSFTPConnection(ConnectionDetails connectionDetails) in C:...</GetSFTPConnectionResult>
</GetSFTPConnectionResponse>
</s:Body>
</s:Envelope>
It also returns different errors depending on the host.
localhost:
An existing connection was forcibly closed by the remote host
127.0.0.1:
Server response does not contain SSH protocol identification.
Environment IP address (10.xx.xx.xx):
Permission denied (password).
Computer name:
An existing connection was forcibly closed by the remote host
I have a feeling that this could be something to do with how a WCF service and it's host is run in the debug mode. And the user configuration in SSH. But I'm stumped as to how to figure it out. I don't have a lot of experience with WCF services or OpenSSH.
I've also tried to add my user account into OpenSSH using the blow command. But it fails.
mkpasswd -l -u [my_user_account] >> etc\passwd
The system cannot find the path specified.
And there doesn't seem to be any etc\passwd file in the OpenSSH folder either.
Sample WCF service application structure
Sample WCF service when debugging
OpenSSH folder in server
Very grateful if someone can point me in the right direction.
I found out recently that this machine had both OpenSSH and Cerberus running and configured for SFTP. Cerberus had a different set of users defined. I turned off OpenSSH and tried connecting to the Cerberus SFTP in the WCF service and it was successful.
I'm guessing this was due to some kind of conflict between OpenSSH and Cerberus SFTP.

Dns.GetHostAddressesAsync: Resource temporarily unavailable

First, for some context: I am using .NetCore to develop an API with Identity. Everything is on a Cloud server, inside a Docker. When a user is created, an email is sent to the new User using a mailkit and the webmail server through Plesk (Hosted on the same machine). The docker is accessed via a redirection trough Apache using a ProxyPass from the subdomain to the port on localhost
Everything works great while debugging trough JetBrain's Rider, but it is not able to process the email in the docker on the server.
Here is the stack:
System.Net.Internals.SocketExceptionFactory+ExtendedSocketException (00000001, 11): Resource temporarily unavailable
at System.Net.Dns.InternalGetHostByName(String hostName)
at System.Net.Dns.ResolveCallback(Object context)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw(Exception source)
at System.Net.Dns.HostResolutionEndHelper(IAsyncResult asyncResult)
at System.Net.Dns.EndGetHostAddresses(IAsyncResult asyncResult)
at System.Net.Dns.<>c.<GetHostAddressesAsync>b__25_1(IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
I have yet to try and run the docker on another linux machine to test.
One of my current guess would be a problem with the SSL certificate, but I don't think it would cause a problem with the DNS or any internal socket.
Another guess is thats its a problem for the Docker to get the DNS Hostname, but since it works ok in a local.
Edit: I tried multiple time to run the docker on the mac and the error is still triggered once in a while but not always. It is although always triggered on the server and never send the email
After two weeks of research, I finally stumbled upon a solution for this:
The problem is related to the network, that was obvious, but it's precisely about how containers are isolated from one another. Problem is, the container has no outbound connection. A solution that work inside a standalone container is to use the --network host parameter, which would expose the host network to the container. Note that using this would remove the port mapping from the container since the container's port 5000 is now linked to the host's port 5000
Hope this solution can help others

Mono HTTPS Error - "Error Writing Headers"

Scope:
I am trying to integrate with an external centralized Logging service provider, using HTTPS requests to post the logs to it.
We are running C# on top of Mono, using Ubuntu 14.04 LTS as the OS.
We have been using mono for years already, so we are somehow familiar with it's behaviors and potential flaws / issues.
Previous Setup
When you google this issue, you find basically two solutions to it, and none of them worked to me, for this case. Here's what I have done so far
Basic Mono-Complete Setup + ca-certificates-mono (that would potentially solve HTTPS related issues).
Other than that, I know that mono does not trust any certificate by default, having it's own certificates-chain, and that we have to import them to it. To do that I ran mozroots --import --sync --ask-remove and it printed me that "140 certificates were downloaded and installed".
Aditionally, we overrode the CertificateValidationCallback using this nasty one-liner:
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => { return true; };
None of the above solved our issue.
Errors, Errors and more Errors:
Note that all of the codes below do work on Windows.
So far we have tried:
Using Native .NET WebClient Async Calls (PostAsync).
As the result, we get errors such as Cant find file system.net.http.dll, and once we actually copy the one from our windows system to it, we get another error Task Exception (can't remember the exact message there).
Using ModernHttpClient
Apparently, using this client on Xamarin programs tend to solve the issues people have, but we still get the same errors listed above, using the standard HttpClient class from .NET
Writing our own WebRequests Wrapper
This was the closest we got to an actual solution, that leads to Error Writing Headers when running it on Mono.
Small Code Sample:
using (WebRequests webClient = new WebRequests ())
{
// Client Configuration
webClient.BufferSize = 32 * 1024;
webClient.Accept = "application/json";
webClient.ContentType = "application/json; charset=" + Encoding.UTF8.HeaderName;
webClient.Timeout = 60000;
webClient.ReadWriteTimeout = 60000;
webClient.Encoding = Encoding.UTF8.WebName;
// Dummy Logz Payload - One Json Per Line
string LogzPayload = "{id:'1', value='1'}\n{id:'2', value='2'}";
// Request to Logz
webClient.Post ("https://listener-4.logz.io:8071/?token=OUR_TOKEN&type=json", LogzPayload);
}
Update 1:
Just tried running the following command and got an exception right away:
certmgr --ssl https://listener-4.logz.io:8071/?token=OUR_TOKEN&type=json --machine
Exception:
Unhandled Exception:
System.IO.IOException: The authentication or decryption has failed. ---> System.IO.IOException: The authentication or decryption has failed. ---> Mono.Security.Protocol.Tls.TlsException: The authentication or decryption has failed.
at Mono.Security.Protocol.Tls.RecordProtocol.EndReceiveRecord (IAsyncResult asyncResult) <0x4192e470 + 0x00132> in <filename unknown>:0
at Mono.Security.Protocol.Tls.SslClientStream.SafeEndReceiveRecord (IAsyncResult ar, Boolean ignoreEmpty) <0x4192e3a0 + 0x00031> in <filename unknown>:0
at Mono.Security.Protocol.Tls.SslClientStream.NegotiateAsyncWorker (IAsyncResult result) <0x4192abb0 + 0x00225> in <filename unknown>:0
--- End of inner exception stack trace ---
I'm not very familiar with Mono but I know that they use their own TLS stack whereas .NET uses the TLS stack from the OS. If I'm correct than the available cipher suites are defined in CipherSuiteFactory.cs which shows that no ECDHE and no DHE ciphers are available. But from what I can see the server supports only ECDHE and DHE ciphers and thus there will be no shared ciphers and the TLS handshake will fail. The ciphers supported by the server are:
ECDHE-RSA-AES256-GCM-SHA384
ECDHE-RSA-AES128-GCM-SHA256
DHE-RSA-AES256-GCM-SHA384
DHE-RSA-AES128-GCM-SHA256
ECDHE-RSA-AES256-SHA384
ECDHE-RSA-AES256-SHA
DHE-RSA-AES256-SHA256
DHE-RSA-AES256-SHA
Most of these are ciphers need TLS 1.2 which is not supported by Mono at all (see State of TLS in Mono). But even the rest is DHE or ECDHE only which Mono does not seem to support. They are actively working on a new TLS stack but it looks like it is not done yet.
If you have access to the server you might try to configure the cipher AES256-SHA which is probably the best cipher currently supported by Mono.
I recommend you to switch to Ubuntu 16.04 because that brings a version of Mono's packages that syncs certificates by default and therefore you don't need to run mozroots, and you will more likely to not have problems around this area.

WCF ServiceHost throws exception when UI client exits

I am creating a a service which I am hosting in a Console Application. It contains a single method to get data from the service, and a couple of methods that can be executed on the server.
In order to test the service I made a simple WinForms application that connects to the service and calls the operations on the host. This seemingly works just fine, but when I added service tracing to the config file to see what was going on I noticed that an exception is thrown on the service side as soon as I close the UI client:
<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Error">
<TraceIdentifier>http://msdn.microsoft.com/nb-NO/library/System.ServiceModel.Diagnostics.ThrowingException.aspx</TraceIdentifier>
<Description>Throwing an exception.</Description>
<AppDomain>WCF.Host.vshost.exe</AppDomain>
<Exception>
<ExceptionType>System.Net.Sockets.SocketException, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>
An existing connection was forcibly closedby the remote host
</Message>
<StackTrace>
at System.ServiceModel.Channels.SocketConnection.HandleReceiveAsyncCompleted() at System.ServiceModel.Channels.SocketConnection.OnReceiveAsync(Object sender, SocketAsyncEventArgs eventArgs) at System.Net.Sockets.SocketAsyncEventArgs.FinishOperationAsyncFailure(SocketError socketError, Int32 bytesTransferred, SocketFlags flags) at System.Net.Sockets.SocketAsyncEventArgs.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
</StackTrace>
<ExceptionString>
System.Net.Sockets.SocketException (0x80004005): An existing connection was forcibly closed by the remote host
</ExceptionString>
<NativeErrorCode>2746</NativeErrorCode>
</Exception>
</TraceRecord>
(I've added a ConsoleTraceListener to the config so that I can see the warnings as soon as they occur.)
When this happens it doesn't affect the server side as far as I can tell, no exceptions are thrown in the console application that hosts the service, and if I restart the UI client it happily lets me perform the operations against the host.
Even so, this is an exception I'd very much like to catch at the host side so that I could handle it. In my opinion, any sign of an exception in the trace log should be investigated, but I simply can't understand where I can catch this error in my code. The Closed and Faulted events on the channel doesn't seem to fire at all.
I've recreated the problem in this VS 2012 solution that can be downloaded here:
http://db.tt/7l2Dnkpr (110 kB)
It consists of three projects, a DLL with the service definitions, a console host and a WinForms UI client. This replicates the setup I have in the real application, but this test is a lot simpler. The solution is setup to start multiple projects, so it should be straight forward to test it.
The WCF.Host application creates a host that is listening on net.tcp://localhost:5000/singleservice
In the UI client, click "GetObjects". This creates the channel to the servicehost and calls the GetObjects() method on it.
Now, exit the UI application and notice the trace output in the console window.
Can anyone see a reason why this would happen, and/or how I could handle the exception in code?
You're holding a reference to service object in your wcf client application (WCF.ClientUI). So you've to close the channel before exiting client process. Add the following code in client, you'll not get any exceptions on closing the client application.
protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
((IChannel)service).Close();
}

HttpWebRequest NameResolutionFailure exception in .NET (with Mono on Ubuntu)

I have a .NET program running on Ubuntu via Mono 2.10
The program downloads a webpage via an HttpWebRequest every minute or so which works fine most of the time:
String result;
WebResponse objResponse;
WebRequest objRequest = System.Net.HttpWebRequest.Create(url);
using (objResponse = objRequest.GetResponse())
{
using (StreamReader sr =
new StreamReader(objResponse.GetResponseStream()))
{
result = sr.ReadToEnd();
// Close and clean up the StreamReader
sr.Close();
}
}
The problem is that after few days I start getting exceptions thrown:
DateTime: 01/25/2012 08:15:41
Type: System.Net.WebException
Error: Error: NameResolutionFailure
Stack:
at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0
at System.Net.HttpWebRequest.GetResponse () [0x00000] in <filename unknown>:0
at socks_server.Program.readHtmlPage (System.String url) [0x00000] in <filename unknown>:0
at socks_server.Program.getAccessKeysProc () [0x00000] in <filename unknown>:0
The server is still abel to resolve DNS, for example
wget http://www.google.com
Will return the file without any probelm as will ping and other commands that resolve DNS.
My program however will continue to throw that exception until I restart it. After restarting the application it will start working again as it should.
I have checked open file counts on the system (400 ish), memory usage (327mb of 4gb), CPU usage (2-3%) and all are OK.
Any ideas?
You can solve it by translating the host name to ip and add the host name to Headers collection or to Host property.
If your url is http://example.com/uri. Resolve the host yourself. Suppose its 1.2.3.4. It'll be http://1.2.3.4/uri. Now add Host: example.com header to your request. I think it can be done by setting HttpWebRequest.Host property.
I know this is an old post, but was facing the same error, so thought to share the solution.
The best solution I found, when that exception occurs while the Wifi
is connected, is just to retry my server call with a slight sleep in
between. It works most of the time, otherwise if the second call
fails I cancel the request.
This error can also raise if the user's Wifi is very unstable or the
signal is very low. The same error occurs if there is no internet
connection at all, even if connected to Wifi.
This is in line with my ans on :
System.Net.WebException: Error: NameResolutionFailure when Calling WCF Services throwing exception in mono android application
Well I use the HttpClient - but it might be a similar problem. I had the same issue on a Android device (it worked on a Windows Phone)... But after I added the Host to the header it worked!
client.DefaultRequestHeaders.Host = "mydomain.com";
You can still use the name in the url (you don't have to use the IP address)
I was experiencing the same issue in my mono application on raspbian. I've tried different solutions described in this and other threads but none worked. Eventually, I was able to fix the problem by changing the name servers in /etc/resolv.conf to the google ones https://developers.google.com/speed/public-dns/
Mirko
I was getting this error when I started the mobile app (android or iOS it does not matter) without internet connection. After restored the connection every request returns "NameResolutionFailure exception". I had to wait 120 seconds for having the http request working again. Setting the following line of code anywhere in the app startup the error was finally gone.
System.Net.ServicePointManager.DnsRefreshTimeout = 0;
The default DnsRefreshTimeout value is 120 seconds.

Categories

Resources