portforwarding in c# (matter with NATUPNPlib) - c#

hi guys i use code below to forward port 9090 to my laptop
NATUPNPLib.UPnPNAT upnpnat = new NATUPNPLib.UPnPNAT();
NATUPNPLib.IStaticPortMappingCollection mappings = upnpnat.StaticPortMappingCollection;
mappings.Add(9090, "TCP", 9090, "192.168.1.104", true, "ProApp-SHARE");
and this code for firewall permission
string command = "netsh http add urlacl url=http://" + "192.168.1.104" + ":" + "9090" + "/ user=everyone";
StreamWriter ns = new StreamWriter(Application.StartupPath + #"\fw.bat", false);
ns.WriteLine(command);
ns.Close();
Process n = new Process();
n.StartInfo.FileName = Application.StartupPath + #"\fw.bat";
if (System.Environment.OSVersion.Version.Major >= 6)
{
n.StartInfo.Verb = "runas";
}
n.Start();
when i do this i can access my local website that runs on 192.168.1.104:9090 from internet , but after 30 seconds up to 1 minute its just disabled , and i have to run these codes again, can some one help me with this???

UPnP is notoriously badly implemented in most routers. You might want to try using a different UPnP library to perform the port map. Check out Open.NAT.

Related

Programmatically login 10 users to remote desktop session

I am trying to create an application that will programmatically login 10 users using RDP. The purpose is to autologin these users so someone does not have to manually do it. The first server I tested against (Server 2012) worked just fine. However, I tried a Server 2008 R2 and it continues to prompt me for a password. Here is the code.
static void Main(string[] args)
{
var password = ConfigurationManager.AppSettings["Password"];
var machine = ConfigurationManager.AppSettings["MachineName"];
var userNameList = new List<string>(ConfigurationManager.AppSettings["UserName"].Split(new char[] { ';' }));
foreach(string name in userNameList)
{
Process rdpProcess = new Process();
rdpProcess.StartInfo.FileName = Environment.ExpandEnvironmentVariables(#"%SystemRoot%\system32\cmdkey.exe");
rdpProcess.StartInfo.Arguments = "/generic:TERMSRV/" + machine + "/user:" + name + " /pass:" + password;
rdpProcess.Start();
rdpProcess.StartInfo.FileName = Environment.ExpandEnvironmentVariables(#"%SystemRoot%\system32\mstsc.exe");
rdpProcess.StartInfo.Arguments = "/v " + machine;
rdpProcess.Start();
Thread.Sleep(3000);
}
}
I added the sleep as the connections were coming too fast and I was getting "connection is busy" errors.
Can anyone see anything I am doing wrong?
Don't really know why this was the case but my 2008 servers will not work with FQDN. IP works fine though. Whatever..

Can't dial with DotRas in Windows Server 2012 R2

i'm totally new to DotRas so please be patient.. I have a windows server 2012 R2 with "Route and remote access" configured. In this simple configuration there is a dialer connection to a vpn as you can see in the first picture..
So, if i click connect.. everything works fine and the status of the network interface changes from disconnected to connected.
Going to the event viewer this is what i got:
Events from RASCLIENT sourcelog:
Event 1:
CoId={A52088DC-5358-44D6-8B77-DA49516C3FBD}: The user SYSTEM has started dialing a VPN connection using a all-user connection profile named VpnAtlanta02. The connection settings are:
Dial-in User = c******s
VpnStrategy = PPTP
DataEncryption = Require
PrerequisiteEntry =
AutoLogon = No
UseRasCredentials = Yes
Authentication Type = MS-CHAPv2
Ipv4DefaultGateway = No
Ipv4AddressAssignment = By Server
Ipv4DNSServerAssignment = By Server
Ipv6DefaultGateway = Yes
Ipv6AddressAssignment = By Server
Ipv6DNSServerAssignment = By Server
IpDnsFlags =
IpNBTEnabled = No
UseFlags = Private Connection
ConnectOnWinlogon = No.
Event 2:
CoId={A52088DC-5358-44D6-8B77-DA49516C3FBD}: The user SYSTEM is trying to establish a link to the Remote Access Server for the connection named VpnAtlanta02 using the following device:
Server address/Phone Number = ***.***.***.***
Device = WAN Miniport (PPTP)
Port = VPN3-4
MediaType = VPN.
Event 3:
CoId={A52088DC-5358-44D6-8B77-DA49516C3FBD}: The user SYSTEM has successfully established a link to the Remote Access Server using the following device:
Server address/Phone Number = ***.***.***.***
Device = WAN Miniport (PPTP)
Port = VPN3-4
MediaType = VPN.
Event 4:
CoId={A52088DC-5358-44D6-8B77-DA49516C3FBD}: The link to the Remote Access Server has been established by user SYSTEM.
Event 5:
CoId={A52088DC-5358-44D6-8B77-DA49516C3FBD}: The user SYSTEM has dialed a connection named VpnAtlanta02 to the Remote Access Server which has successfully connected. The connection parameters are:
TunnelIpAddress = 172.20.0.19
TunnelIpv6Address = None
Dial-in User = c******s.
Now.. my goal is to get connected from a windows service
So here is my code (the essential part):
Dialer = new RasDialer();
Dialer.PhoneBookPath = "C:\\Windows\\System32\\ras\\Router.pbk";
Dialer.Timeout = 20 * 1000;
Dialer.HangUpPollingInterval = 20 * 1000;
Dialer.AllowUseStoredCredentials = false;
Dialer.AutoUpdateCredentials = RasUpdateCredential.None;
Dialer.EntryName = "VpnAtlanta02";
Dialer.Credentials = new System.Net.NetworkCredential("c******s", "*********");
Watcher = new RasConnectionWatcher();
Watcher.EnableRaisingEvents = true;
Watcher.Connected += Watcher_Connected;
Watcher.Disconnected += Watcher_Disconnected;
InfoLog("Begin connection");
Watcher.Handle = Dialer.Dial();
private void Watcher_Disconnected(object sender, RasConnectionEventArgs e)
{
InfoLog(e.Connection.EntryName + " is disconnected");
}
private void Watcher_Connected(object sender, RasConnectionEventArgs e)
{
InfoLog(e.Connection.EntryName + " is connected");
}
Sofar, no matter what... going to the event viewer looking for the RasClient event source, as expected i got 5 events logged. 1,2,3 and 4 are equal to the ones generated by the manual connection unfortunately the last (5) is:
CoId={E2814072-13C7-44CF-998A-A1160FDC86E3}: The user SYSTEM dialed a connection named VpnAtlanta02 which has failed. The error code returned on failure is 720.
Please consider that if you think at some wrong credentials or else.. i did a try with no credentials at all and as expected in that case i wasn't able to get event 4
Any ideas?
First thing first! This is not the answer to my question but... I think it could be helpful for anyone who's experienced the same trouble.
After a bunch of tries and even some attempts to debug using DotRas source code i didn't get any step forward, besides i'm not sure this can actually be done. I said that because trying with "rasdial" command from an administrator command prompt i've got the same result: failed with error code 720. That said i've got my solution using powershell.
There's 3 powerful cmdlets which are all i was looking for
- Get-VpnS2SInterface
- Connect-VpnS2SInterface
- Disconnect-VpnS2SInterface
So i just set 3 simple methods and now everything works like a charm
public Boolean IsConnected()
{
Boolean retVal = false;
using (PowerShell ps = PowerShell.Create())
{
ps.AddCommand("Get-VpnS2SInterface");
ps.AddParameter("Name", "VpnAtlanta02");
foreach (PSObject result in ps.Invoke())
{
retVal = ("" + result.Members["ConnectionState"].Value).ToLower() == "connected";
}
}
return retVal;
}
public void Connect()
{
using (PowerShell ps = PowerShell.Create())
{
ps.AddCommand("Connect-VpnS2SInterface");
ps.AddParameter("Name", "VpnAtlanta02");
ps.AddParameter("PassThru");
foreach (PSObject result in ps.Invoke())
{
String destination = "";
foreach (String s in result.Members["Destination"].Value as String[])
{
destination += "{" + s + "}";
}
Service1.InfoLog("Destination=" + destination + "\r\n" +
"ConnectionState=" + result.Members["ConnectionState"].Value + "\r\n");
}
}
}
public void Disconnect()
{
using (PowerShell ps = PowerShell.Create())
{
ps.AddCommand("Disconnect-VpnS2SInterface");
ps.AddParameter("Name", "VpnAtlanta02");
ps.AddParameter("Force");
ps.Invoke();
Service1.InfoLog("Nic: " + "VpnAtlanta02" + " is connected: " + IsConnected());
}
}

Run mstsc.exe with specified username and password with Port Number

I got this post at run mstsc.exe but if we supply port number it is not working.
Here is my code with port number change.
Process rdcProcess = new Process();
rdcProcess.StartInfo.FileName = Environment.ExpandEnvironmentVariables(#"%SystemRoot%\system32\cmdkey.exe");
rdcProcess.StartInfo.Arguments = "/generic:TERMSRV/192.168.0.217:123 /user:" + "username" + " /pass:" + "password";
rdcProcess.Start();
rdcProcess.StartInfo.FileName = Environment.ExpandEnvironmentVariables(#"%SystemRoot%\system32\mstsc.exe");
rdcProcess.StartInfo.Arguments = "/v " + "192.168.0.217:123"; // ip or name of computer to connect
rdcProcess.Start();
I have here 123 port number supply with server name. If server is supply without port number all good.
Please suggest any workaround for this.
I tried your code on my machine with Win 8.1 to connect to my office.
It's working fine, problem is not in code but in environment.
rdcProcess.StartInfo.FileName = Environment.ExpandEnvironmentVariables(#"%SystemRoot%\system32\mstsc.exe");
rdcProcess.StartInfo.Arguments = "/v " + "xxxx.cz:33893"; // ip or name of computer to connect
rdcProcess.Start();

Netstat focus on (find port)

Im recently trying to execute the following line ;
string strCmdText;
strCmdText = "netstat -np TCP | find " + quote + number + quote + "";
System.Diagnostics.Process.Start("netstat.exe", strCmdText);
Logs.Write("LISTEN_TO(" + Registry_val1.Text + ")", strCmdText);
now what this has to do is basicly find all TCP ports that contain '80' in them and show them up in my custom-made log system that will make a logbook in my folder called;
LISTEN_TO(80)-{date_time}.txt
inside this .txt it should contain the command issued text, however all i get is a time.
i debugged this command as above, and unfortunately all i know is that the CMDtext is set correctly, and that my logging system works correctly, leaving me with no choice that NETSTAT may be closed as soon as the query is launched?
hopefully i provided anough information, as this is my first post.
Regards,
Co
Due to vague description, here's an other-sort same code i tried to do, however still remain getting only a time.
const string quote = "\"";
Process p = new Process();
p.StartInfo.FileName = "cmd";
p.StartInfo.Arguments = "netstat -np TCP | find " + quote + number + quote + "";
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.Start();
String output = p.StandardOutput.ReadToEnd();
Logs.Write("LISTEN_TO(" + Registry_val1.Text + ")", output);
basicly, you could see this as; textbox1.text = output; execpt now the output is being putten to a log file.
I don't understand why you use netstat in the first place. The .Net framework has a load of classes that give all kind of data, in this case IPGlobalProperties has the method you need.
var ip = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties();
foreach(var tcp in ip.GetActiveTcpConnections()) // alternative: ip.GetActiveTcpListeners()
{
if (tcp.LocalEndPoint.Port == number
|| tcp.RemoteEndPoint.Port == number)
{
Logs.Write(
String.Format(
"{0} : {1}",
tcp.LocalEndPoint.Address,
tcp.RemoteEndPoint.Address));
}
}
The benefit of using the build-in classes is the ease of shaping and selecting whatever you need and most important: you spare yourself and your user an out-of-process call and parsing of output.
You may try this:
strCmdText = "cmd /c \"netstat -np TCP | find " + quote + number + quote + "\"";
if this does not work, try first to use the command in a cmd prompt to make sure it returns data.
cmd /c "netstat -an | find "80"

Set Port number when using FtpWebRequest in C#

I keep getting a exception when I try to FTP to my Win 2008 Server from C# code using VS2008 as debugger.
My test class looks like this:
public class FTP
{
private string ftpServerIP = "192.168.10.35:21";
private string ftpUserID = "Administrator";
private string ftpPassword = "XXXXXXXX";
private string uploadToFolder = "uploadtest";
public void Upload(string filename)
{
FileInfo fileInf = new FileInfo(filename);
string uri = "ftp://" + ftpServerIP + "/" + uploadToFolder + "/" + fileInf.Name;
FtpWebRequest reqFTP;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
reqFTP.KeepAlive = false;
reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
reqFTP.UseBinary = true;
reqFTP.ContentLength = fileInf.Length;
int buffLength = 2048;
byte[] buff = new byte[buffLength];
int contentLen;
FileStream fs = fileInf.OpenRead();
try
{
Stream strm = reqFTP.GetRequestStream();
contentLen = fs.Read(buff, 0, buffLength);
while (contentLen != 0)
{
strm.Write(buff, 0, contentLen);
contentLen = fs.Read(buff, 0, buffLength);
}
strm.Close();
fs.Close();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}
When I execute the code I get a Connection Failed with FTP error 227 in the GetRequestStream() call.
In the exception I can see the connection fails to: 192.168.10.35:52184
I have no idea how it comes up with port 52184.
I specify in the ftpServerIP that it should be port 21.
I have found a few persons with the same issues on google but I haven't found a good example on how this is solved and I still don't understand why it happens.
Anyone know how to handle this issue??
UPDATE:
I have tried to connect to a different FTP account and there it all works fine. Therefore I tested my 192.168.10.35:21 FTP but it works fine in CuteFTP Pro and the likes.
This just makes it even more strange..
My guess would be Windows firewall issues, FTP uses other ports than just port 21 - sometimes changing the FTP mode from active to passive helps to get things working.
reqFTP.UsePassive = false;
Look at this good article on FTP: Active FTP vs. Passive FTP, a Definitive Explanation
Thies got it right, it had to do with passive mode
The fix in the code is so insanely simple :)
reqFTP.UsePassive = false;
And it worked fast and without errors!
It is important to differentiate the COMMAND port and the DATA port. The connection protocol will also change depending if you are in ACTIVE or PASSIVE mode.
ACTIVE MODE :
1) The client initiate a connection from a random unspecified COMMAND port (N > 1023) to the default server COMMAND port (21). The client will specify his DATA port (N+1) and start listening on this port.
2) The server initiate a connection from his default DATA port (20) to specified client DATA port (N+1).
PASSIVE MODE :
1) The client initiate a connection from a random unspecified COMMAND port (N > 1023) to the default server COMMAND port (21) with the PASSIVE command. The server open a random DATA port (P > 1023) and send it to the client.
2) The client initiate a connection from his DATA port (N+1) to the specified server DATA port (P > 1023).
If you use ACTIVE mode, you will most likely need to let your client's firewall accept the connection from the server to your port (N+1 > 1024).
In your example, you were in ACTIVE mode. Your client initiated a connection from his COMMAND port (52183) to the server's default COMMAND port (21) and specified its DATA port (52184 = 52183 + 1). Then the server initiated a connection from its default DATA port (20) to the client's DATA port (52184) which was most likely rejected by the client's firewall.
I hope this helps you solve your problem!

Categories