I'm trying to figure out how if there's a way to make a hostname resolve to a certain IP without DNS or host file modification.
Using C#, I'm making a request from client to server, but I have to use the hostname in the request so that the certificates will properly authenticate the request. However, my program is meant to run without admin rights, so I can't modify the host file. I have the correct IP and the host name, is there any other way to make the computer resolve the host name to the IP?
It looks like the simplest way to solve this is to create a service with the rights to modify the host file, then invoke that service from the main program. The service runs a single command and exits. Since a service can have elevated status, you can essentially encapsulate admin rights inside a standard user program.
If you're making an HTTP request, then you don't need to resolve the hostname; use the IP address in the URL and pass the host header in your HTTP request.
HttpWebRequest.Host Property
Update: sorry didn't see the certificates requirements. I think you should be able to modify the hosts file during installation (because installation usually happens under admin rights). Add the host name you're interested in to point to 127.0.0.1 (local machine). Then, your app can open a listening socket and act as a proxy, channeling the data to the actual Web server. This may or may not work depending on the client having a firewall enabled.
public bool ModifyHostsFile(string sEntryIPAddr, string sEntryURL)
{
try
{
using (StreamWriter w = File.AppendText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), #"drivers\etc\hosts")))
{
w.WriteLine(sEntryIPAddr+" "+ sEntryURL);
return true;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return false;
}
}
this worked for me:
Step 1. Open your Windows start menu, search for the notepad application and then right click the notepad icon.
Step 2. Choose “Run as administrator” and then, while inside notepad, browse to folder (/windows/system32/drivers/etc) that contains the hosts file.
Related
I have an application that needs to communicate with a web server hosted on an external provider. It's been configured to only allow incoming connections from IP addresses that it recognizes.
If I needed to connect when I was working remotely and connected through VPN, I would add routes through a terminal window like sudo route -n add -net 22.222.222.22/32 192.168.133.1
I don't want every user that works remotely to have to do this. Can I do something in the application layer to allow a user that connected through the VPN to connect to the remote web server and use the VPN tunnel? It is a C# Winforms application.
I'm assuming all of the users of your app are behind the same firewall? If that's the case, then your network admin should be able to setup the routing for you either on the router directly or on your NAT server. It's also worth noting that, at least at my company, we've always had to add the routing statements twice - one for internal and one for outside over VPN. It would be a massive security vulnerability if an app could modify your computer's routing table so I wouldn't do that.
One more thought - it's possible that your VPN uses a common feature called split tunneling which means that all destinations behind your firewall would go over VPN (and have the associated routing rules applied), but any destinations outside (such as your external provider) are split and instead go straight out without any routing. The only way around this would be to setup a VPN tunnel between your firewall and your external provider (e.g. at my company we've done this with our cloud servers so they are accessible over VPN).
http://en.wikipedia.org/wiki/Split_tunneling
I could discern in your comments, that you are trying to add a route in a windows environment, but only found a command that works on linux?!
But I actually don't get your drift, and what the result of your application should be.
First of all I'll try to help you adding a route to your routing table with C# on a windows machine. (Server-sided)
I've created a little WinForm with a Button-Control btnAddRoute and a Textbox-Control textBox1 to give you an example:
Adding routes only works as administrator btw
private void btnAddRoute_Click(object sender, EventArgs e)
{
// route -p add xxx.xxx.xxx.xxx mask 255.255.0.0 xxx.xxx.xxx.xxx
string netIp = "22.222.222.22";
string mask = "255.255.255.255";
string exitIp = "192.168.133.1";
string arg = String.Format("-p add {0} mask {1} {2}", netIp, mask, exitIp);
Process p = new Process
{
StartInfo =
{
UseShellExecute = false,
FileName = "route",
Arguments = arg,
RedirectStandardOutput = true,
StandardOutputEncoding = Encoding.ASCII
}
};
p.Start();
textBox1.Text = p.StandardOutput.ReadToEnd();
}
This adds a route with the specified IP's to your routing table, and returns OK! or Failed! depending on if the action was successfully or not.
Is this more or less what you want? Or did I totally amiss?
I am trying to create a file on the remote machine but I am getting The "Network name cannot be found". I checked the network path and I was able to access the path from my machine. Could you please let me know what could be wrong?
Here is my code.
using (StreamWriter sw = new StreamWriter("\\\\servername\\TEST1\\TEST\\NEWFILE.csv", true))
{
sw.WriteLine(sw);
}
Go to \servername\TEST1 and give write permission to the user or aspnet (if you have a web application) on test folder and then re-run your program. It will work.
To give write permissions, just refer to this article:
How to share a folder/File
In case it still does not work, replace servername with server IP address and do the same as stated above.
Give the access rights to the user under which this application runs either it is a IIS pool or windows service etc
it is surely a security isssue. you need to give Write access to the remote machine
Is anyone else having a difficult time getting Twitters oAuth's callback URL to hit their localhost development environment.
Apparently it has been disabled recently. http://code.google.com/p/twitter-api/issues/detail?id=534#c1
Does anyone have a workaround. I don't really want to stop my development
Alternative 1.
Set up your .hosts (Windows) or etc/hosts file to point a live domain to your localhost IP. such as:
127.0.0.1 xyz.example
where xyz.example is your real domain.
Alternative 2.
Also, the article gives the tip to alternatively use a URL shortener service. Shorten your local URL and provide the result as callback.
Alternative 3.
Furthermore, it seems that it works to provide for example http://127.0.0.1:8080 as callback to Twitter, instead of http://localhost:8080.
I just had to do this last week. Apparently localhost doesn't work but 127.0.0.1 does Go figure.
This of course assumes that you are registering two apps with Twitter, one for your live www.mysite.example and another for 127.0.0.1.
Just put http://127.0.0.1:xxxx/ as the callback URL, where xxxx is the port for your framework
Yes, it was disabled because of the recent security issue that was found in OAuth. The only solution for now is to create two OAuth applications - one for production and one for development. In the development application you set your localhost callback URL instead of the live one.
Callback URL edited
http://localhost:8585/logintwitter.aspx
Convert to
http://127.0.0.1:8585/logintwitter.aspx
This is how i did it:
Registered Callback URL:
http://127.0.0.1/Callback.aspx
OAuthTokenResponse authorizationTokens =
OAuthUtility.GetRequestToken(ConfigSettings.getConsumerKey(),
ConfigSettings.getConsumerSecret(),
"http://127.0.0.1:1066/Twitter/Callback.aspx");
ConfigSettings:
public static class ConfigSettings
{
public static String getConsumerKey()
{
return System.Configuration.ConfigurationManager.AppSettings["ConsumerKey"].ToString();
}
public static String getConsumerSecret()
{
return System.Configuration.ConfigurationManager.AppSettings["ConsumerSecret"].ToString();
}
}
Web.config:
<appSettings>
<add key="ConsumerKey" value="xxxxxxxxxxxxxxxxxxxx"/>
<add key="ConsumerSecret" value="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"/>
</appSettings>
Make sure you set the property 'use dynamic ports' of you project to 'false' and enter a static port number instead. (I used 1066).
I hope this helps!
Use http://smackaho.st
What it does is a simple DNS association to 127.0.0.1 which allows you to bypass the filters on localhost or 127.0.0.1 :
smackaho.st. 28800 IN A 127.0.0.1
So if you click on the link, it will display you what you have on your local webserver (and if you don't have one, you'll get a 404). You can of course set it to any page/port you want :
http://smackaho.st:54878/twitter/callback
I was working with Twitter callback url on my localhost. If you are not sure how to create a virtual host ( this is important ) use Ampps. He is really cool and easy. In a few steps you have your own virtual host and then every url will work on it. For example:
download and install ampps
Add new domain. ( here you can set for example twitter.local) that means your virtual host will be http://twitter.local and it will work after step 3.
I am working on Win so go under to your host file -> C:\Windows\System32\Drivers\etc\hosts and add line: 127.0.0.1 twitter.local
Restart your Ampps and you can use your callback. You can specify any url, even if you are using some framework MVC or you have htaccess url rewrite.
Hope This Help!
Cheers.
Seems nowadays http://127.0.0.1 also stopped working.
A simple solution is to use http://localtest.me instead of http://localhost it is always pointing to 127.0.0.1 And you can even add any arbitrary subdomain to it, and it will still point to 127.0.0.1
See Website
When I develop locally, I always set up a locally hosted dev name that reflects the project I'm working on. I set this up in xampp through xampp\apache\conf\extra\httpd-vhosts.conf and then also in \Windows\System32\drivers\etc\hosts.
So if I am setting up a local dev site for example.com, I would set it up as example.dev in those two files.
Short Answer: Once this is set up properly, you can simply treat this url (http://example.dev) as if it were live (rather than local) as you set up your Twitter Application.
A similar answer was given here: https://dev.twitter.com/discussions/5749
Direct Quote (emphasis added):
You can provide any valid URL with a domain name we recognize on the
application details page. OAuth 1.0a requires you to send a
oauth_callback value on the request token step of the flow and we'll
accept a dynamic locahost-based callback on that step.
This worked like a charm for me. Hope this helps.
It can be done very conveniently with Fiddler:
Open menu Tools > HOSTS...
Insert a line like 127.0.0.1 your-production-domain.com, make sure that "Enable remapping of requests..." is checked. Don't forget to press Save.
If access to your real production server is needed, simply exit Fiddler or disable remapping.
Starting Fiddler again will turn on remapping (if it is checked).
A pleasant bonus is that you can specify a custom port, like this:
127.0.0.1:3000 your-production-domain.com (it would be impossible to achieve this via the hosts file). Also, instead of IP you can use any domain name (e.g., localhost).
This way, it is possible (but not necessary) to register your Twitter app only once (provided that you don't mind using the same keys for local development and production).
edit this function on TwitterAPIExchange.php at line #180
public function performRequest($return = true)
{
if (!is_bool($return))
{
throw new Exception('performRequest parameter must be true or false');
}
$header = array($this->buildAuthorizationHeader($this->oauth), 'Expect:');
$getfield = $this->getGetfield();
$postfields = $this->getPostfields();
$options = array(
CURLOPT_HTTPHEADER => $header,
CURLOPT_HEADER => false,
CURLOPT_URL => $this->url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false
);
if (!is_null($postfields))
{
$options[CURLOPT_POSTFIELDS] = $postfields;
}
else
{
if ($getfield !== '')
{
$options[CURLOPT_URL] .= $getfield;
}
}
$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);
if ($return) { return $json; }
}
I had the same challenge and I was not able to give localhost as a valid callback URL. So I created a simple domain to help us developers out:
https://tolocalhost.com
It will redirect any path to your localhost domain and port you need. Hope it can be of use to other developers.
set callbackurl in twitter app : 127.0.0.1:3000
and set WEBrick to bind on 127.0.0.1 instead of 0.0.0.0
command : rails s -b 127.0.0.1
Looks like Twitter now allows localhost alongside whatever you have in the Callback URL settings, so long as there is a value there.
I struggled with this and followed a dozen solutions, in the end all I had to do to work with any ssl apis on local host was:
Go download: cacert.pem file
In php.ini * un-comment and change:
curl.cainfo = "c:/wamp/bin/php/php5.5.12/cacert.pem"
You can find where your php.ini file is on your machine by running php --ini in your CLI
I placed my cacert.pem in the same directory as php.ini for ease.
These are the steps that worked for me to get Facebook working with a local application on my laptop:
goto apps.twitter.com
enter the name, app description and your site URL
Note: for localhost:8000, use 127.0.0.1:8000 since the former will not work
enter the callback URL matching your callback URL defined in TWITTER_REDIRECT_URI your application
Note: eg: http://127.0.0.1/login/twitter/callback (localhost will not work).
Important enter both the "privacy policy" and "terms of use" URLs if you wish to request the user's email address
check the agree to terms checkbox
click [Create Your Twitter Application]
switch to the [Keys and Access Tokens] tab at the top
copy the "Consumer Key (API Key)" and "Consumer Secret (API Secret)" to TWITTER_KEY and TWITTER_SECRET in your application
click the "Permissions" tab and set appropriately to "read only", "read and write" or "read, write and direct message" (use the least intrusive option needed for your application, for just and OAuth login "read only" is sufficient
Under "Additional Permissions" check the "request email addresses from users" checkbox if you wish for the user's email address to be returned to the OAuth login data (in most cases check yes)
I'm getting this error when I try to start a windows service I've created in C#:
My Code so far:
private ServiceHost host = null;
public RightAccessHost()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
host = new ServiceHost(typeof(RightAccessWcf));
host.Open();
}
protected override void OnStop()
{
if (host != null)
host.Close();
host = null;
}
Update #1
I solved the issue above by granting permissions to the account NETWORK SERVICE but now I have an another problem:
Update #2
Service cannot be started. System.InvalidOperationException: Service 'RightAccessManagementWcf.RightAccessWcf' has zero application (non-infrastructure) endpoints. This might be because no configuration file was found for your application, or because no service element matching the service name could be found in the configuration file, or because no endpoints were defined in the service element.
at System.ServiceModel.Description.DispatcherBuilder.EnsureThereAreNonMexEndpoints(ServiceDescription description)
at System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost)
at System.ServiceModel.ServiceHostBase.InitializeRuntime()
at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at RightAccessHosting.RightAccessHost.OnStart(String[] args) in C:\Users....
I realize this post is old, but there's no marked solution and I just wanted to throw in how I resolved this.
The first Error 5: Access Denied error was resolved by giving permissions to the output directory to the NETWORK SERVICE account.
The second Started and then stopped error seems to be a generic message when something faulted the service. Check the Event Viewer (specifically the 'Windows Logs > Application') for the real error message.
In my case, it was a bad service configuration setting in app.config.
Computer -> Manage -> Service -> [your service] properties.
Then the the tab with the account information. Play with those settings, like run the service with administrator account or so.
That did it for me.
EDIT:
What also can be the problem is that, most services are run as LOCAL SERVICE or LOCAL SYSTEM accounts. Now when you run C:/my-admin-dir/service.exe with those accounts but they are not allowed to execute anything in that directory, you will get error 5. So locate the executable of the service, RMB the directory -> Properties -> Security and make sure that the account the service is run with, is in the list of users that are alloewd to have full control over the directory.
This worked for me.
Right-click on top-level folder containing the service executable. Go to Properties
Go to "Security" Tab
Click "EDIT"
Click "ADD"
Enter the name "SYSTEM", click OK
Highlight SYSTEM user, and click ALLOW check-box next to "Full control"
Click OK twice
Make sure the Path to executable points to an actual executable (Right click service -> Properties -> General tab).
Via powershell (and sc.exe) you can install a service without pointing it to an actual executable... ahem.
I also got the same error , It resolved by
Right click on Service > Properties >Log On > log on as : Local System Account.
I was getting this error because I misread the accepted answer from here: Create Windows service from executable.
sc.exe create <new_service_name> binPath= "<path_to_the_service_executable>"
For <path_to_service_executable>, I was using the path of the executable's folder, e.g. C:\Folder.
It needs to be the path of the executable, e.g. C:\Folder\Executable.exe.
I got the solution:
1. Go to local service window(where all services found)
2. Just right click on your service name:
3. click on "properties"
4. go to "log on" tab
5. select "local system account"
6. click "ok"
now you can try to start the service.
In my case following was not checked.
if you are a having an access denied error code 5. then probably in your code your service is trying to interact with some files in the system like writing to a log file
open the services properties select log on tab and check option to allow service to interact with the desktop,
For me - the folder from which the service was to run, and the files in it, were encrypted using the Windows "Encrypt" option. Removing that and - voila!
This error happens when there is a error in your OnStart method. You cannot open a host directly in OnStart method because it will not actually open when it is called, but instead it will wait for the control. So you have to use a thread. This is my example.
public partial class Service1 : ServiceBase
{
ServiceHost host;
Thread hostThread;
public Service1()
{
InitializeComponent();
hostThread= new Thread(new ThreadStart(StartHosting));
}
protected override void OnStart(string[] args)
{
hostThread.Start();
}
protected void StartHosting()
{
host = new ServiceHost(typeof(WCFAuth.Service.AuthService));
host.Open();
}
protected override void OnStop()
{
if (host != null)
host.Close();
}
}
I had windows service hosted using OWIN and TopShelf.
I was not able to start it. Same error - "Access denied 5"
I ended up giving all the perms to my bin/Debug.
The issue was still not resolved.
So I had a look in the event logs and it turned out that the Microsoft.Owin.Host.HttpListener was not included in the class library containing the OWIN start up class.
So, please make sure you check the event log to identify the root cause before beginning to get into perms, etc.
In my case, I had to add 'Authenticated Users' in the list of 'Group or User Names' in the folder where the executable was installed.
One of the causes for this error is insufficient permissions (Authenticated Users) in your local folder.
To give permission for 'Authenticated Users'
Open the security tab in properties of your folder, Edit and Add 'Authenticated Users' group and Apply changes.
Once this was done I was able to run services even through network service account (before this I was only able to run with Local system account).
Right click on the service in service.msc and select property.
You will see a folder path under Path to executable like C:\Users\Me\Desktop\project\Tor\Tor\tor.exe
Navigate to C:\Users\Me\Desktop\project\Tor and right click on Tor.
Select property, security, edit and then add.
In the text field enter LOCAL SERVICE, click ok and then check the box FULL CONTROL
Click on add again then enter NETWORK SERVICE, click ok, check the box FULL CONTROL
Then click ok (at the bottom)
Your code may be running in the security context of a user that is not allowed to start a service.
Since you are using WCF, I am guessing that you are in the context of NETWORK SERVICE.
see: http://support.microsoft.com/kb/256299
I have monitored sppsvc.exe using process monitor and found out that it was trying to write to the HKEY_LOCAL_MACHINE\SYSTEM\WPA key. After giving permissions to NETWORK SERVICE on this key, I was able to start the service and Windows suddenly recognized that it was activated again.
Use LocalSystem Account instead of LocalService Account in Service Installer.
You can do this either from doing below change in design view of your service installer:
Properties of Service Process Installer -> Set Account to LocalSystem.
or by doing below change in in designer.cs file of your service installer:
this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
Have a look at Process Utilities > Process monitor from http://www.sysinternals.com.
This is tool that allows you monitor what a process does. If you monitor this service process, you should see an access denied somewhere, and on what resource the access denied is given.
For the error 5, i did the opposite to the solution above.
"The first Error 5: Access Denied error was resolved by giving permissions to the output directory to the NETWORK SERVICE account."
I changed mine to local account, instead of network service account, and because i was logged in as administrator it worked
If you are getting this error on a server machine try give access to the folder you got the real windows service exe. You should go to the security tab and select the Local Service as user and should give full access. You should do the same for the exe too.
I accidentally set my service to run as Local service solution was to switch to Local System
After banging my had against my desk for a few hours trying to figure this out, somehow my "Main" method got emptied of it's code!
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new DMTestService()
};
ServiceBase.Run(ServicesToRun);
Other solutions I found:
Updating the .NET framework to 4.0
Making sure the service name inside the InitializeComponent() matches the installer service name property
private void InitializeComponent()
...
this.ServiceName = "DMTestService";
And a nice server restart doesn't hurt
Szhlopp
In may case system run out of free space on local disk.
I had this issue today on a service that I was developing, and none of the other suggestions on this question worked. In my case, I had a missing .dll dependency in the folder where the service ran from.
When I added the dependencies, the issue went away.
In my case I kept the project on desktop and to access the desktop we need to add permission to the folder so I simply moved my project folder to C:\ directory now its working like a charm.
I don't know if my answer would make sense to many, but I too faced the same issue and the solution was outrageously simple. All I had to do was to open the program which I used to run the code as an administrator. (right-click --> Run as Administrator).
That was all.
check windows event log for detailed error message. I resolved the same after checking event log.
All other answers talk about permissions issues - which make sense, given that's what the error message refers to.
However, in my case, it was caused by a simple exception in my service code (System.IndexOutOfRangeException, but it could be anything).
Hence, when this error occurs, one should look inside their log and look for exceptions.
I had this issue on a service that I was deploying, and none of the other suggestions on this question worked. In my case, it was because my .config (xml) wasn't valid. I made a copy and paste error when copying from qualif to prod.
We are currently working on an API for an existing system.
It basically wraps some web-requests as an easy-to-use library that 3rd party companies should be able to use with our product.
As part of the API, there is an event mechanism where the server can call back to the client via a constantly-running socket connection.
To minimize load on the server, we want to only have one connection per computer. Currently there is a socket open per process, and that could eventually cause load problems if you had multiple applications using the API.
So my question is: if we want to deploy our API as a single standalone assembly, what is the best way to fix our problem?
A couple options we thought of:
Write an out of process COM object (don't know if that works in .Net)
Include a second exe file that would be required for events, it would have to single-instance itself, and open a named pipe or something to communicate through multiple processes
Extract this exe file from an embedded resource and execute it
None of those really seem ideal.
Any better ideas?
Do you mean something like Net.TCP port sharing?
You could fix the client-side port while opening your socket, say 45534. Since one port can be opened by only one process, only one process at a time would be able to open socket connection to the server.
Well, there are many ways to solve this as expressed in all the answers and comments, but may be the simpler way you can use is just have global status store in a place accesible for all the users of the current machine (may be you might have various users logged-in on the machine) where you store WHO has the right to have this open. Something like a "lock" as is used to be called. That store can be a field in a local or intranet database, a simple file, or whatever. That way you don't need to build or distribute extra binaries.
When a client connects to your server you create a new thread to handle him (not a process). You can store his IP address in a static dictionary (shared between all threads).
Something like:
static Dictionary<string, TcpClient> clients = new Dictionary<string, TcpClient>();
//This method is executed in a thread
void ProcessRequest(TcpClient client)
{
string ip = null;
//TODO: get client IP address
lock (clients)
{
...
if (clients.ContainsKey(ip))
{
//TODO: Deny connection
return;
}
else
{
clients.Add(ip, client);
}
}
//TODO: Answer the client
}
//TODO: Delete client from list on disconnection
The best solution we've come up with is to create a windows service that opens up a named pipe to manage multiple client processes through one socket connection to the server.
Then our API will be able to detect if the service is running/installed and fall back to creating it's own connection for the client otherwise.
3rd parties can decide if they want to bundle the service with their product or not, but core applications from our system will have it installed.
I will mark this as the answer in a few days if no one has a better option. I was hoping there was a way to execute our assembly as a new process, but all roads to do this do not seem very reliable.