My goal is to get the list of web site names from remote server. But I'm getting the exception:
The RPC server is unavailable.
Here is the code:
public List<string> GetWebSites(string serverIP)
{
List<string> names = new List<string>();
DirectoryEntry Services = new DirectoryEntry(string.Format("IIS://{0}/W3SVC", serverIP));
Services.Username = "user name";
Services.Password = "password";
IEnumerator ie = Services.Children.GetEnumerator();
DirectoryEntry Server = null;
while (ie.MoveNext())
{
Server = (DirectoryEntry)ie.Current;
if (Server.SchemaClassName == "IIsWebServer")
{
names.Add(Server.Properties["ServerComment"][0].ToString());
}
}
return names;
}
this works fine, when firewall is turned off on the machine.
What I need to know is, which port(s) are used by DirectoryEntry?
or is there any other way to get web site names, without turning off firewall?
I believe LDAP protocol uses TCP no? Should be port 389 for non-ssl and 636 for SSL
Related
In my application I have to connect to remote PC's mostly with WinXP OS (Older production machines) from my office server. I am starting a CIMSession in order to read the CPU Load of the remote PC. If I use following code I get Error:
"Microsoft.Management.Infrastructure.CimException: The client cannot connect to the destination specified in the request. Verify that the service on the destination is running and is accepting requests. Consult the logs and documentation for the WS-Management service running on the destination, most commonly IIS or WinRM. If the destination is the WinRM service, run the following command on the destination to analyze and configure the WinRM service: "winrm quickconfig" "
The remote IP is added into the TrustedHosts list on the server where my app is running
public void Read_CPU_Load()
{
string Namespace = #"root\cimv2";
string OSQuery = "SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor where Name='_Total'";
string domain = "";
string username = "xxxxxx";
var s = new SecureString();
s.AppendChar('P');
s.AppendChar('a');
s.AppendChar('s');
s.AppendChar('s');
s.AppendChar('w');
s.AppendChar('o');
s.AppendChar('r');
s.AppendChar('d');
// create Credentials
CimCredential Credentials = new CimCredential(PasswordAuthenticationMechanism.Default,
domain,
username,
s);
// create SessionOptions using Credentials
WSManSessionOptions SessionOptions = new WSManSessionOptions();
SessionOptions.AddDestinationCredentials(Credentials);
// create Session using computer, SessionOptions
CimSession mySession = CimSession.Create(TagService.IP_to_Connect, SessionOptions);
IEnumerable<CimInstance> queryInstance = mySession.QueryInstances(Namespace, "WQL", OSQuery);
foreach (CimInstance process in queryInstance)
{
CPU_Load_WMI_int = Convert.ToInt16(process.CimInstanceProperties["PercentProcessorTime"]);
}
}
I've 2 desktop applications in .Net that communicate between each other. Up until now they were using WCF but we are moving toward .Net 6 so we have to update them.
They run on a local network without internet connection but we require the user to enter a password, just to avoid the technician to connect to the wrong server and misconfigure something.
Our server is a WPF application, so we will not be hosting the service inside an Asp.Net server.
Currently, I've made and retrieved this code:
[Test]
public void CustomTest()
{
string rootCert = File.ReadAllText(TestCredentials.ClientCertAuthorityPath);
keyCertPair = new KeyCertificatePair(
File.ReadAllText(TestCredentials.ServerCertChainPath),
File.ReadAllText(TestCredentials.ServerPrivateKeyPath));
VerifyPeerCallback verifyFunc = context =>
{
return true;
};
var serverCredentials = new SslServerCredentials(new[] { keyCertPair }, rootCert, SslClientCertificateRequestType.DontRequest);
var clientCredentials = new SslCredentials(rootCert, null, verifyFunc);
// Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755
server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) })
{
Ports = { { Host, ServerPort.PickUnused, serverCredentials } }
};
sslCredentialsTestServiceImpl = new SslCredentialsTestServiceImpl();
server.Services.AddCodeFirst<ITestService>(sslCredentialsTestServiceImpl, default, Console.Out);
server.Start();
var options = new List<ChannelOption>
{
new ChannelOption(ChannelOptions.SslTargetNameOverride, TestCredentials.DefaultHostOverride)
};
channel = new Channel(Host, server.Ports.Single().BoundPort, clientCredentials, options);
client = channel.CreateGrpcService<ITestService>();
CallContext callContext = default;
var call = client.UnaryCall(new SimpleRequest(), callContext);
Assert.AreEqual(false, sslCredentialsTestServiceImpl.WasPeerAuthenticated);
}
It works. But:
I don't understand why we have to provide the root certificate to the client? Shouldn't this check the windows certificate directory for the available certificate?
Same question for the server. I understand why we have to provide the certificate, but not why we need to provide the CA certificate?
Also, is there an (unsecure) way to use credentials but no SSL? I know that make no sense in a security standpoint, but in our case, it's just to avoid dum errors, the user will either be on the same computer with the 2 software, either in the same room
I have a gRPC client calling into a server on the same machine and client code uses the channel created with:
Channel channel = new Channel("localhost", 11112, ChannelCredentials.Insecure);
This works well, and I'm getting the reply as expected.
However, if I replace "localhost" with the actual machine name (FQDN) or IP address, I'm getting an error:
Status(StatusCode="Unavailable", Detail="failed to connect to all addresses", DebugException="Grpc.Core.Internal.CoreErrorDetailException: {"created":"#1616190440.553000000","description":"Failed to pick subchannel","file":"..\..\..\src\core\ext\filters\client_channel\client_channel.cc","file_line":5397,"referenced_errors":[{"created":"#1616190440.553000000","description":"failed to connect to all addresses","file":"..\..\..\src\core\ext\filters\client_channel\lb_policy\pick_first\pick_first.cc","file_line":398,"grpc_status":14}]}")
I also tested starting the server on a remote machine and having the client call into that remote machine (by name or IP) when creating the channel, but got the same failure.
The application is written in C# .NET Core 3.2 as a Console application. Nuget packages included are: Google.Protobuf, Grpc.Core, Grpc.Tools.
Not sure what is wrong in my code or whether something is not setup properly on my machine.
Here's the reset of the relevant client code:
MWCS.McpsServer.McpsServerClient client = new MWCS.McpsServer.McpsServerClient(channel);
var data = new ProcessResponseInput() { ClientID = clientID };
var options = new CallOptions();
try {
var res = client.ProcessResponse(data, options);
return res;
} catch (RpcException ex) {
StandardOutput so = new StandardOutput() { ExitCode = 1, Message = ex.Message };
return so;
}
To resolve this, I actually had to fix the server code. I should have used "0.0.0.0" instead of "localhost" in the bind address on the server. Looks like when setting the server to localhost it is not visible outside the computer.
Here's how I have the server started now (after the replacement):
_server = new Server() {
Services = { McpsServer.BindService(new McpcServerImplementation()) },
Ports = { new ServerPort("0.0.0.0", 11112, ServerCredentials.Insecure) }
};
I'm self hosing a website in a windows service via nancy/owin. The site gets hosted fine, and I can hit the site in a browser both locally and from another machine. All calls to my Web API endpoints work just fine when interacting with the site.
The problem comes when trying to hit the Web API endpoints locally via another application - except when I connect with the IP address. For instance, I have a console application where I am making a simple GET request. If I run the app locally connecting with the machine name (base name or fully qualified) or localhost, I get 400 Bad Request - Invalid Hostname. If I do that same request using the IP address, it works fine. On the other hand, if I run the console app on another machine on the same domain, it will work regardless of which host name I use. Firewalls are off on both machines. What could be causing this?
Here is the code I am using to register my urls:
public void Start(int port = 1234)
{
// Get URIS with port num
var uris = GetUriParams(port);
// Add Host URLs
var startOptions = new Microsoft.Owin.Hosting.StartOptions();
foreach (var uri in uris)
startOptions.Urls.Add(uri.ToString());
// Start OWIN
this._owinApp = WebApp.Start<Startup>(startOptions);
}
private static Uri[] GetUriParams(int port)
{
var uriParams = new List<Uri>();
string hostName = Dns.GetHostName();
// Host name URI
string hostNameUri = string.Format("http://{0}:{1}", Dns.GetHostName(), port);
uriParams.Add(new Uri(hostNameUri));
// Host address URI(s)
var hostEntry = Dns.GetHostEntry(hostName);
foreach (var ipAddress in hostEntry.AddressList)
{
if (ipAddress.AddressFamily == AddressFamily.InterNetwork) // IPv4 addresses only
{
var addrBytes = ipAddress.GetAddressBytes();
string hostAddressUri = string.Format("http://{0}.{1}.{2}.{3}:{4}", addrBytes[0], addrBytes[1], addrBytes[2], addrBytes[3], port);
uriParams.Add(new Uri(hostAddressUri));
}
}
// Localhost URI
uriParams.Add(new Uri(string.Format("http://localhost:{0}", port)));
return uriParams.ToArray();
}
And here is the web request I am making in my console app:
var getDataFormatString = "http://{0}:{1}/API/MyService/GetData";
var fqdn = "mymachine";
var address = string.Format(getDataFormatString, fqdn, 1234);
var request = (HttpWebRequest)WebRequest.Create(new Uri(address));
request.Method = "GET";
request.Credentials = new NetworkCredential("username", "password", "domain");
var response = (HttpWebResponse)request.GetResponse();
Nancy may have changed since you posted this question, but in my experience this has to do with the HostConfiguration.RewriteLocalhost setting. When I set this to false I get the same behavior you see.
When HostConfiguration.RewriteLocalhost=true, then I also need to create a URL reservation using netsh http add urlacl url=http://+:port user=<appropriate-user>
I am working on an application that needs constant internet connectivity in order to function according to specifications.
The problem that I am facing is that if I connect to a VPN then the application is unable to access the internet at all.
Here is a part of the code where I try to check whether the server is reachable or not:
try
{
using (var client = new System.Net.WebClient())
{
//var networkCredentials = new NetworkCredential("shumais", "password");
//WebProxy myProxy = new WebProxy("192.168.0.61", 8080) { Credentials = networkCredentials };
//WebProxy myProxy = new WebProxy("192.168.0.61", 8080);
//client.Proxy = WebRequest.GetSystemWebProxy();
IWebProxy proxy = WebRequest.GetSystemWebProxy();
proxy.Credentials = CredentialCache.DefaultCredentials;
client.UseDefaultCredentials = true;
client.Proxy = proxy;
using (var stream = client.OpenRead(WebUrls.URL_BASE_REQUEST))
{
_isServerReachable = true;
}
}
}
catch (Exception)
{
_isServerReachable = false;
}
I have got the code working with/without proxies and now just need to get the application to work when I am connected to any VPNs.
Any help will be greatly appreciated, thanks.
If you are using a Microsoft PPTP VPN, you need to uncheck "Use default gateway on remote network" in the TCP/IPv4 advanced settings for the VPN connection.
Since you're trying to access the site with the default network credentials, make sure to add the default proxy to the app.config file, and add a cookie container (seriously sounds stupid but it looks like it's helping other people out too).
Check out my answer to this post: How to use IE proxy server settings and its credentials in .Net Application