WCF service sometimes rejects client credentials - c#

I have a WCF service that creates its own secondary IP (using netsh) upon startup and listens on that IP. Sometimes it just so happens that the when server starts listening clients from the same machine can't connect (client credentials are rejected). From other machines, however, there are no such connection problems.
When starting service on the original IP, connection problems don't seem to occur, but the non-deterministic behavior of the previous scenario prevents me from making any conclusions.
This is what is used for credentials and protection level:
TcpClientCredentialType clientCredentialType = TcpClientCredentialType.Windows;
ProtectionLevel protectionLevel = ProtectionLevel.EncryptAndSign;
I would like to know what is happening here. Any suggestions/insights are welcome.

Related

WinSCP .NET library FTP transfer fails with "IP addresses of control and data connection do not match"

I have implemented FTP code with use of WinSCP .NET assembly and hosted it on an Azure AppService.
It works locally and on Azure.
But in very few random times, when hosted on Azure, it throws the following error:
Error transferring file 'D:\local\Temp\test_settings.txt'. Server sent passive reply with unroutable address 10.YYY.YYY.YYY, using host address instead. Copying files to remote side failed. Rejected data connection for transfer of "/test_settings.txt", IP addresses of control and data connection do not match
Since the IP starts with 10. does that mean that it's local in the FTP server's network?
Can I do something to improve the implementation?
Do you think that the solution will have a problem when used concurrently by multiple requests?
My code is a copy of the Simple C# example with the following settings:
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Ftp,
UserName = username,
Password = password,
GiveUpSecurityAndAcceptAnyTlsHostCertificate = true,
FtpSecure = FtpSecure.Explicit,
HostName = 'ftp.domain.com'
};
IP addresses of control and data connection do not match
That's a message from FileZilla FTP server. It's a security measure. It might indicate that external IP address of your app service instance changed mid transfer. Or of course, it might indicate that you connection was hijacked (that's what the server tries to detect).
It has nothing to do with WinSCP.
I do not know if the IP address of the Azure app service can be fixed somehow. If not, all you can do is to reconnect and retry the transfer. I believe you would have the same problem with any FTP client. Maybe with IPv6 connection, the problem would not happen. But I'm not sure, it's just a wild guess. Though you cannot force IPv6 with WinSCP (only by disabling IPv4 altogether, but I do not know if that's even possible with the app service).

WCF Endpoint Address using https (WebHttpBinding)

I need to modify a WCF endpoint binding address. Here is some background on the issue:
I have an NT class service (if it matters, not a webservice). It creates a System.ServiceModel.ServiceHost with an Endpoint whose endpoint address is created this way:
var epa = new EndpointAddress(string.Format("https://localhost:{0}/ServiceAPI/", 8181));
The binding used for the ServiceEndpoint is a WebHttpBinding with Mode=WebHttpSecurityMode.Transport (i.e. https).
When the ServiceHost is opened, I can go to a command prompt, and do "Netstat -a" and see the address bound to the Listen as 0.0.0.0:8181.
So far, no problem. However, a large customer has raised a "security issue" with the fact that because the WCF "listen" is on address 0.0.0.0 instead of 127.0.0.1, that a potential attacker can connect to that address from an external machine. The test that they have constructed is to use telnet 8181 from an external machine, and if the connect occurs, then the test fails. The change request is to modify the service to "listen" on 127.0.0.1:8181 so that the only possibility of connecting to that port is from the local machine.
I have done a fair amount of modifications in an attempt to get WCF to "listen" on "127.0.0.1" instead of "0.0.0.0". In all of my attempts the only way to do this is to set HostNameComparisonMode to "Exact" and create the endpoint address in this way:
var epa = new EndpointAddress(string.Format("https://127.0.0.1:{0}/ServiceAPI/", 8181));
(Actually, as an aside, if I use a different binding such as NetTcpBinding, the above EndPointAddress construction will bind to address "127.0.0.1:8181" without altering HostNameComparisonMode. It only switches internally to "0.0.0.0:8181" when I use WebHttpBinding, and fail to set HostNameComparisonMode=Exact.)
However, this (setting HostNameComparisonMode=Exact) causes a breaking complication due to the fact that existing 3rd party code has already been developed that attempts to (onboard the server) connect to "https://localhost:8181/ServiceAPI", and when HostNameComparisonMode is set to "Exact", WCF only ever returns http error 506 to any request due to the difference between "localhost" and "127.0.0.1".
What I am currently looking for is either a means of setting up WCF to bind to "127.0.0.1:8181" (as determined by netstat -a) with the HostNameComparisonMode still set to the default "StrongWildcard" setting. Or barring any possibility of there being a way to do that, another creative suggestion to cause connects coming from external machines to be unable to connect to that port. (The test would be to use "telnet servername 8181" from a different machine, and it fail to connect.)
Any ideas? Thanks!
if i understand you right, you want to connect from remote machine to this address, so can you try BasicHttpBinding? Also you can try to host it at: "https://localhost:{0}/ServiceAPI/", 8181" Correct pls if i understand you wrong.

'No connection could be made because the target machine actively refused it'

I am working on a 'Smart Device Project' using .Net Framework 3.5. I am trying to connect to some Java SOAP services on a remote server.
In order to do that, I added 'Web References' to my project.
When I try to call my web service I get a WebException 'Unable to connect to the remote server' with the inner exception being 'No connection could be made because the target machine actively refused it'.
I searched quite a lot on the Web and StackOverflow and found a lot of ASP configuration and 'Unavaliable port' answers, but as I have another application using the exact same Service successfully, I can't get why the new one isn't getting through (It did sometimes through my tests so I suppose my client implementation isn't that bad)
I tried to look if there was some connection issue on the port by using some TcpClient:
System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient();
try
{
client.Connect("myServerName", 8087);
MessageBox.Show("Success");
} catch (Exception ex)
{
MessageBox.Show("Failure");
}
finally
{
client.Close();
}
This connection succeed.
Here is a sample on how I call my WebService:
WSServiceExtended srv = new WSServiceExtended();
srv.Proxy = new System.Net.WebProxy();
ServeurWSI wsi = new ServeurWSI();
srv.Url = "http://myServerName:8087/myServerApp/services/myService";
wsr = srv.login(wsi);
The service is called 'Extended' because I overrided the auto-generated one in order to add Cookie managment since I am using the Compact Framework. Following the sample in this thread:
https://social.msdn.microsoft.com/Forums/en-US/34d88228-0b68-4fda-a8cd-58efe6b47958/no-cookies-sessionstate-in-compact-framework?forum=vssmartdevicesvbcs
EDIT:
I made some new tests with the Web references and got it to work.
When I add the Web Reference, I have to put some Url to the Web Service. When I set it with the actual hostname instead of the 'localhost' everything is fine.
But then, since I set it manually to the real address just before the call, it shouldn't matter
srv.Url = "http://myServerName:8087/myServerApp/services/myService";
EDIT2:
I might have forgotten some specifics about my environnement.
The Web Services are exposed on my computer on some Tomcat Server.
The application I am working on is also developped on this computer (That's why I can add Web References by putting 'localhost' in the address)
The application is then deployed on a distant device (Windows CE) that will make calls the Web Services through WIFI (There, localhost wouldn't work then)
I tried calling the Web services from other computers successfully.
I'm beginning to think that there might be some differential between the called Url and the one that is set, otherwise, how would I have a difference in behaviour such as the one described in the first edit?
EDIT3:
Well..Seems like it's not a network issue but a .Net compact framework (usage?) issue...
The Url property of the Web Service implementation is simply ignored and the one in the Reference.cs is used in place.
If someone had some idea on how I could troubleshot this, I would really appreciate it.
That error means that you reached a server and the server said "no way". So you're either hitting the wrong server or the wrong port.
I find the telnet client is useful for testing stuff like this. From the command line, you can do:
telnet [servername] [port]
So something like:
telnet myServerName 8087
If it goes to a blank screen, then it connected successfully. If it does not connect, it'll tell you.
The telnet client is no longer installed by default in Windows 7+, so you'll have to install it. See here for instructions: https://technet.microsoft.com/en-ca/library/cc771275
If the connection does open, you could paste in an actual HTTP request to see what happens. A simple GET would look something like this:
GET /myServerApp/services/myService HTTP/1.1
Host: myServerName:8087
One reason for this error can be that the service binds to only a certain IP address. It could well be that the service only listens on the IP that is assigned to the host name, but not on the localhost IP (127.0.0.1).
For example:
If the host myServerName has the public IP 192.168.0.1, your service can choose to listen on all IPs assigned to the host (sometimes specifying 0.0.0.0), or it can specifically listen on 192.168.0.1 only. In that case you will not be able to connect through 127.0.0.1, because the service simply doesn't listen on that IP.
You can "use" this inverse of this feature to make a service accessible only to local clients, not on the public IP-Address, by listening on 127.0.0.1 only, but not on the public IP. This is sometimes used on Linux for example to make MySQL only accessible on the host itself.
I was starting to forget this post but I finally found the problem that was messing things up and it has nothing to do with programmation.
I was doing the calls while the device was connected to the computer via the 'Windows Mobile Device Center' allowing to access the device from Windows.
While connected, the host provided is ignored and all calls on the specified port are handled by the connected computer.
Disconnecting the device allows to communicate properly...

Console app SignalR client Disconnect Timeout

I am trying to set Disconnect Timeout to higher value from the default 30s.
All examples on web are more JS oriented.
var hubConnection = new HubConnection("http://localhost:8087");
var testHubProxy = hubConnection.CreateHubProxy("TestHub");
Error: System.TimeoutException: Couldn't reconnect within the configured timeout of 00:00:30, disconnecting.
This did not work:
GlobalHost.Configuration.DisconnectTimeout = TimeSpan.FromSeconds(35);
Update:
It looks like DisconnectTimeout needs to be set on the server side!?
What is the reason for disallowing different clients to have different Disconnect Timeout?
Disconnect Timeout is configured on server-side. The main reasons could be as follows:
We know the server may take some N-time units to respond so that the all clients may be well aware.
The server should be pinging the clients for connection at regular times. So the server is aware of clients connection and can manage other hubs and eradicate the expired connections from its connection pool.
The client is not supposed to set disconnect timeout because it does not know when could it shutdown e.g. the internet switched off accidentally on client side than the client is not able to tell server that I am not going to connect to you again. Yes but we have some events at client-side which tells it that it is not connected to the signalr hub anymore. Please see the reconnecting and disconnected events.
Summary:
Disconnect timeout is to inform the server that its client is not connected anymore even if it disconnects disgracefully .

TCP Connect to Azure Fails

I recently deployed an Azure app to the staging environment which is supposed to accept TCP packets in port 2993. When run in the Azure emulator, it does this very well, and performs exactly as it should.
However, now that it is on Azure's staging servers, whenever I try to connect to the TCP port, i get the following SocketException:
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
My web app has two instances, one is a worker role (it has 2993 configured in its endpoints) and a web role (only for port 80). Port 80, by the way, functions perfectly. The web app was created with Visual Studio in C#. Why is this happening and how can I fix it?
All help is greatly appreciated.
I would like to explain what was the issue and why adding above code solve this problem for others benefit.
In your worker role, you configure any TCP endpoint along with any port number. When this VM starts the VM is provisioned to use this port and firewall is included an exception to provide access to this port. By the time your is ready to start your Azure VM already have TCP/IP address and configured port is enabled.
Now when your role starts and if you have any service or application required access this port you really need to l
For example If I have Tomcat/Java configured in my worker role, I must have to create a TCP listener on my configured port. This can be done when my worker role starts as below:
Get the IP address and Port number of the current role instance
Create a TCP Listener and start on this IP address and Port
Add the code to perform step 1) and 2) in my worker role OnStart() function.
The code will look like as below:
TcpListener TomcatPortListener = new TcpListener(RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["TomcatWeb80"].IPEndpoint);
TomcatPortListener.Start();
In your case you you did exactly the same you got the IP address and Port number from and then created an endpoint from a socket address using IP/Port:
RoleInstanceEndpoint externalEndPoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["TCPin"];
IPEndPoint localEndPoint = new IPEndPoint(externalEndPoint.IPEndpoint.Address, externalEndPoint.IPEndpoint.Port);
localEndPoint.Create();
It is a must setting for any web or worker role which create TCP endpoint.
It seems the problem had something to do with the program's detection of the server's IP address. By using the following server code instead, I managed to fix the problem:
RoleInstanceEndpoint externalEndPoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["TCPin"];
IPEndPoint localEndPoint = new IPEndPoint(externalEndPoint.IPEndpoint.Address, externalEndPoint.IPEndpoint.Port);
The IPEndpoint can then be used with the tcpListener socket.

Categories