I need to get a unique ID from a computer using c#. I have done it with Mac Address by using the code
string macAddresses = "";
foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
{
if (nic.OperationalStatus == OperationalStatus.Up)
{
macAddresses += nic.GetPhysicalAddress().ToString();
break;
}
}
return macAddresses;
But when I run code in server , it returns Mac address of the server. How can I get the Mac address or any unique ID of the client system using c#.
There is nothing like a unique ID that is automatically sent to the server with requests.
One way to implement this is to generate a unique ID on the server for each time a new client connects and send this ID to the client so that it can send it with each subsequent request and you can identify it by this ID.
Of course you have to make sure that the ID you generate is actually unique and you have to store the generated IDs on the server to know about existing "connections" and to be able to reject fake IDs.
As Martin said:
There is nothing like a unique ID that is automatically sent to the server with requests.
.
You need to get that information passed INSIDE your request to be able to process it in the C# code.
For security reasons, by default of all modern broswers, you can't access the client's MAC address via JS. See more
(ASP.Net) You could set up a Session GUID as a cookie at the first time the client access your website, that should be enought to identify the users.
(WinForms/WPF) You can use that same code at the CLIENT application, then send it to your api/webservice.
(WinForms/WPF) There is also something called HD UUID (Maybe Windows-only), which can be modified by third-party softwares, which makes it not 100% safe (I've seen people modifying this to "fake auth" some licensed softwares). See more
Also could be useful if you specify what kind of server is this, I'm assuming it is web, but got some WinForms/WPF alternatives
Related
I have just signed up because I need some clarification. I am an old man but a new graduate of a Systems Analysis college program and am on my first "real" job designing a system for a local company. Here is the deal. I am using ASP.NET MVC. Now, the company has assembly lines in a large manufacturing plant. Along the lines are stations where workers do a specific job on the line. The company has paper instructions that explain to the worker step by step how to do the job at their station. They want all this done electronically now....this is what I 'm doing.
So, when the leader of the assembly line starts their shift, they log into the system by opening up IE and connecting to the application server. From there, the leader picks a part to "make" on the line. The system then goes into the repository of instruction documents and retrieves all the documents needed by each station on the line to run the selected part. The system then needs to prepare the documents according to the station that will use them (ie. station 1 docs, station 2 docs,....etc). Then, the system needs to automatically open up the IE browser window on the client machine at each station on the line and display the login screen. The worker then logs onto the station and is presented with the "dashboard" screen with the instruction forms right there in front of him with buttons to navigate through the various docs for his station.
So now, we are wanting to have the system store the IP and Mac addresses of each station machine along each assembly line in a table along with fields that denote the assembly line and station # (ie. so a row in the table would have MAC | IP | ASSEMBLYLINE-ID | STATION-ID). This table will be populated before hand by admins so that the system knows already what the Mac and IP are for each machine on the floor. So, when the leader picks a part to run, the system can just check the machine the leader is logged into and get its MAC and IP and then look up in the table what line the machine is on. Then it can create a document queue for each station on the line, and then when the queues are ready, it can look in the table for the IP's of each machine on the line so that it can open the log on screen on the right machines.
However, it is possible that IP's may change from time to time. For this reason, we want to make sure we also use MAC addresses to validate the identity of a station machine whenever any communication needs to happen between the system and the clients. IP's alone just aren't good enough. Further, we are using all zero clients for this on the stations.
So, if you're still reading, lol. How can my system on the server, run a getMAC command on a machine that connects to it?
A web server cannot get the MAC address of a client machine. MAC addresses are stored on the physical ethernet layer and are not routed through socket connections. A MAC address stored in a packet is changed on every hop of a packet's journey. MAC is an abbreviation for Media Access Control, with "Media" referring to the local communication media. While source and destination IP-Addresses remain the same throughout the journey (and are used for long-distance routing decisions), the source and destination MAC-Addresses just indicate the next hop.
That being said, you can get the IP address like so:
Request.UserHostAddress()
However, as you yourself pointed out, this isn't reliable. Especially if the computers are behind a proxy or firewall.
To address your real problem, which is identifying a machine in your assembly line, one method is to get the computer name. You can open a command window and type the command hostname and that will return the computer name. It should be unique for each of your machines. If not, you can set it by right clicking on Computer. To get this name through javascript, use this code:
function GetComputerName()
{
try
{
var network = new ActiveXObject('WScript.Network');
var computerName = network.computerName;
return computerName;
}
catch (e) { }
return "";
}
Note that this code will only with with Internet Explorer and it may require you to enable special security settings inside the browser.
I am designing a desktop application in C#, which needs to be connected to my online mysql database. I tried to give access in control panel a "%" which means from any IP, but it is not working. May be the hosting provider (bigrock) not allowing that.
Alternatively, I am trying to write some code in online on PHP which will get the "sql" as parameter and returns the output as JSON format using json_encode.
Is there any alternate methods which is better approach.
What error do you get when you try to connect? Timeout = firewalled; Permission denied = permissions not right etc.
One solution is to create a proxy with pre-coded queries (let's call then "stored procedures") - you can then say "Run query 5, parameters A, B and C". As this would be server-server (not public) you just need to add some basic authentication system (e.g. shared rotating key, checksum using parameters etc), but also ensure the queries are not dangerous if any parameters are thrown at it.
Disclaimer: It's a solution, but I'm not actually recommending that I'd do it unless you're very sure it's safe!
Do you have Cpanel ? If yes, then try adding your host in remote MySQL.
Here the link http://www.liquidweb.com/kb/enable-remote-mysql-connections-in-cpanel/ if you are unsure on how to do that.
I'd advise that you do not create a wildcard user that can connect to the database from anywhere using embedded MySQL credentials in your application. This is a bad idea.
It would be extremely easy to determine the credentials used by your application and then a malicious user could directly connect to your DB server and begin issuing queries to your database.
They will be able to issue SELECT statements for any information in your tables, even info they shouldn't see. It then becomes much easier to exploit any known or unknown vulnerabilities in MySQL much easier since now they have console access and can send data directly to the server. If the account has the DELETE privilege, they can erase all the data in your table(s).
Also, having a PHP script that issues queries provided by the application/end-user is not ideal because one can still freely issue queries. While that option is better than giving blanket access to a remote user, it is still a bad idea.
The way to go would be to identify all of the information that the C# application needs to access, and how, and write a simple web service/API that will receive parameters and issue its own queries and return the results using XML, JSON, or even SOAP. Try to abstract the database access as much as possible from the outside world for the best security.
Hope that helps.
I would do the following:
Create a user with the host of your public ip (www.whatismyip.com).
If that doesn't work, create a user with your host as your public ARPA/PTR record:
>nslookup
> set q=ptr
> 8.8.8.8
Non-authoritative answer:
8.8.8.8.in-addr.arpa name = google-public-dns-a.google.com
8.in-addr.arpa nameserver = ns1.Level3.net
8.in-addr.arpa nameserver = ns2.Level3.net
The host would then be set to google-public-dns-a.google.com.
The second worked, and I am not sure why for me on a project I worked on in the past, where you would have thought the IP address to be sufficient.
I am not sure if you have root access or access to my.cfg. If you can edit it, make sure the line "skip-networking" is commented or removed and it contains line "bind-address = *". Restart mysql after editing config.
For security reasons you shouldn't access the database directly over the (public) network.
One way is to write a php script on the database server and access it via HTTP/POST.
You should authenticate the client via username and a hashed password. The data you are sending should be encrypted (eg with the users clear text password). Don't send complete queries, only what you want to do and the parameters. As example, you want the orders for the customer, you can send a post request with the following parameters
user=abc,password=9151440965cf9c5e07f81eee6241c042a7b78e9bb2dd4f928a8f6da5e369cdffdd2b70c70663ee30d02115731d35f1ece5aad9b362aaa9850efa99e3d197212a,data=EncryptedData
You can notice, that the password is an SHA512 Hash.
The data can be json or anything else:
{
"Command": "GetOrder",
"Limit": "10"
}
In your php code you do the following steps:
1. Authenticate the user, if the password is not correct, respond with error code etc
2. Decrypt the data
3. Execute a query
4. Return the result as encrypted data
If you don't want to store the clear text password in your database, you could store in your database the hashed value and use a double hashed value for authentication and single hashed value for encryption.
If you wan't to execute the queries with parameters from the request you should use prepared statements to prevent sql injection.
More information about en/decrypting in php see: http://php.net/manual/de/ref.mcrypt.php
Like some answers suggested, I think you are firewalled by bigrock.
Now if you want to use AJAX/PHP, you need three things:
- your C# class to send requests and receive the result
- your HTML/JS (or jQuery) file to receive the request and hand it over to your PHP. Then send you the result.
- your PHP file to query your DB.
The AJAX seems superfluous to me, you could just send your query passing it through POST or a GET parameter (i.e. example.com/query.php?req='SELECT * FROM clients')
The code would be as follow:
C# using this class made by Ali Ahsan Rana:
//create the constructor with post type and few data
MyWebRequest myRequest = new MyWebRequest("http://www.example.com/query.php","POST","req=");
//use System.Web.Script.Serialization and myRequest.GetResponse();
Some tutorial on System.Web.Script.Serialization.
On the PHP side:
<?php
$request=$_POST['req'];
$dsn = 'mysql:dbname=mydb;host=example.com';
$user = 'ajay';
$password = '0000';
try {
$dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
$response = $dbh->query($request);
while ($rep = $response->fetch())
{
$response_array[] = $rep;
}
$response->closeCursor();
$return = json_encode($rep);
return($return);
?>
That's a quick draft but should work AFAIK.
I have a web application , for presentation to my client they ask me to install it on their local server so they can test it , here is my question !?
Is there any way so i can publish uniquely for that server , i did put some limitation but many features in my app are open , so they can make a disk image from server and use it anywhere else ,
Is there any method to use so my web application check if this server is same server ( by hardware id or anything i don't have any idea ) then start to work !
I saw many codes but they are win forms for generating unique hid , but how can i connect done it with asp .net
EDIT
Could u take a look at this also ,
i am using system.management class
is this reliable i mean are they unique ?
private string GetUniqueID()
{
string cpuInfo = string.Empty;
ManagementClass mc = new ManagementClass("win32_processor");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
if (cpuInfo == "")
{
//Get only the first CPU's ID
cpuInfo = mo.Properties["processorID"].Value.ToString();
break;
}
}
ManagementObject dsk = new ManagementObject(#"win32_logicaldisk.deviceid=""" + "C" + #":""");
dsk.Get();
string volumeSerial = dsk["VolumeSerialNumber"].ToString();
string HardWareUniqueID = volumeSerial + cpuInfo;
return HardWareUniqueID;
}
Appreciate your answers,
Thanks in advance
If you want to avoid having it "phone home" an alternative is to generate some kind of certificate and place it on the machine. Use a private key that only you know to encrypt the machine name and/or IP. Then have your app use your public key to decrypt it to verify that it is allowed to run on this server. Nobody who doesn't know your private key will be able to create valid certificates.
You hae a few choices...
Lock your web site to the single IP address you install it on. To make your life easier, check for that IP in a common page base class. (Note, you could also write HTTP handlers, but the base-class approach is easier.)
Put a 'phone home' call in the app that checks with your server every time it's started up. That way you can check if they have moved it or if multiple instances are running.
Use the built-in licensing features of .NET (the same one third-party developers use for controls, etc.)
The easiest... just put in a time-bomb that lets them test it for a few weeks, then automatically blocks access. Be smart though... persist the last-checked time so you can tell if they've rolled back their clock trying to get more usage.
Just make sure to distribute a web application, not a web project so you can distribute your code as a compiled bumary rather than having to ship the code-behind files. That will keep prying eyes out, but does make deployment more a pain since you always have to recompile with every change (as opposed to on-demand compiling.)
I would put in a time bomb. It's trivial to implement. Also, your client's won't think that you don't trust them. A fixed evaluation period in the application is extremely common.
Provide them a VMware image without any user-access just allow them to open the website externally via HTTP in their web browser.
I am tasked to get the location where our SQL Server database is geographically located via C# code because it may vary time to time due to frequent relocation of our database to protect it from physical and cyber harm. Is this possible or another dream of my boss thanks in advance.
1 - Buy somethihng like this. It's a UPS GPS receiver.
2 - Connect it to the server machine.
3 - Write a batch or shell script that will call the GPS software and return the current position.
4 - Use xp_cmdshell to call this script and return the current position via SQL Server query.
Buy an iPhone/Android phone and have it sellotaped to the top of the machine that has the database on it. Write a quick app to have it look at the GPS API and post it's position to the database the phone is connected on using some kind of JSON/SOAP API over HTTPS (for security purposes).
You can then access the GPS information from where you are using C#.
Edit
Working with the GPS on Mono/iPhone: http://drdobbs.com/mobility/222600599
Example code, GPS on Mono/Android: https://github.com/gshackles/Sample-Projects/blob/master/MonoDroid/MonoDroidSamples/MonoDroidSamples/DemoActivities/LocationDemo/LocationActivity.cs
The simplest solution is to do a DNS lookup, then use an IP location service as Cody suggested. Try this:
var foo = Dns.GetHostEntry("database.windows.net");
Once you've got your IP address, you'll need to load something like http://www.iplocationfinder.com/65.55.23.107 using an HttpWebRequest, unless you want to pay for an IP location database. Once you've got the response to the HttpWebRequest, you can use a regular expression to parse the location name, or latitude and longitude if you need that instead.
Do you have so many servers which are moved around overnight in your company or is this for a cloud db setup? the IP address is probably a basic inaccurate-better than nothing starting point.
As Davide Piras mentioned you can use for example this site : http://ip-lookup.net/ to trace the IP Address of you're DB Server and you can grab the Output maybe using Regular Expresion's or http://htmlagilitypack.codeplex.com/ .
Bu that works only if you can get you're DB Server IP Address ,which i think shouldn't be an Issue because you need the IP for the Connection String .
To achieve that use a WebBrowser Control ,do webbrowser1.navigate("http://ip-lookup.net/");
than :
HtmlElementCollection elc = this.webBrowser1.Document.GetElementsByTagName("input");
foreach (HtmlElement el in elc)
{
if (el.GetAttribute("type").Equals("text") && el.GetAttribute("name").Equals("ip"))
{
el.InnerText = "Server IP";
}
}
next :
HtmlElement form = webBrowser1.Document.GetElementById("form_single_IP");
if (form != null)
form.InvokeMember("submit");
//Submit the form
and try to filter the output because im not very good using Regex .You can capture the Output by using webbrowser1.DocumentText;
Why not use the database to tell you the location? To clarify what I mean:
Using SQL CLR Stored Procedure To Track IP Address - but make the CLR sproc return the ipaddress of the server its hosted on.
I saw the azure connection string you mentioned to Cody and thought these would be a handy links:
http://blogs.msdn.com/b/windowsazure/archive/2011/07/06/windows-azure-deployments-and-the-virtual-ip-address.aspx
Get Azure public IP address from deployed app
Determining the time zone is probably the best you can do from SQL Server, but that could be enough for you based on your description. You can use this query to get the GMT offset of the time zone where the server is located:
SELECT DATEDIFF(hh, GETUTCDATE(), GETDATE()) AS ServerTimeZone
From this result, you can easily add some logic to return the time zone abbreviation, i.e. EST, CST, etc. I know this isn't much, but hopefully it helps.
If someone already physically moves the server, why not write some script that writes the corresponding location to DB? When the machine starts up, auto-start that tool and have the "mover" select a location.
I have a web application that you can use to import information from another site by giving it a url. It's been pointed out that you could use this feature to access a private site that is hosted on the same web server.
So...
How can I check that a given url is publicly accessible (whether on the same web server or somewhere different)?
FIX:
I ended up doing this:
protected static bool IsHostWithinSegment(string Host)
{
Ping pinger = new Ping();
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
PingOptions options = new PingOptions();
options.Ttl = 1;
PingReply reply = pinger.Send(Host, 1000, buffer, options);
return reply.Status == IPStatus.Success;
}
private static Uri BindStringToURI(string value)
{
Uri uri;
if (Uri.TryCreate(value, UriKind.Absolute, out uri))
return uri;
// Try prepending default scheme
value = string.Format("{0}://{1}", "http", value);
if (Uri.TryCreate(value, UriKind.Absolute, out uri))
return uri;
return null;
}
The only requirement of mine that it doesn't fulfil is that some installations of our product will exist alongside each other and you won't be able to import information across them - I suspect this will require using a proxy server to get an extrenal view of things but as it's not a requirement for my project I'll leave it for someone else.
-- I've just realised that this does entirely solve my problem since all the publicly accessible urls resolve to virtual or routable ips meaning they hop.
Run a traceroute (a series of pings with short TTL's to the address, if the firewall(s) is(are) one of the hops then it's visible from outside the organisation so should be acceptable.
System.Net.NetworkInformation has a ping class that should give you enough information for a tracert like routine.
This does sound like a big hole though, another approach should probably be considered. Preventing the machine that runs this prog. from accessing any other machine on the internal network may be better - a kind of internal firewall.
I've added a simple traceroute, since you like the concept:-
class Program
{
static void Main(string[] args)
{
PingReply reply = null;
PingOptions options = new PingOptions();
options.DontFragment = true;
Ping p = new Ping();
for (int n = 1; n < 255 && (reply == null || reply.Status != IPStatus.Success); n++)
{
options.Ttl = n;
reply = p.Send("www.yahoo.com", 1000, new byte[1], options);
if (reply.Address != null)
Console.WriteLine(n.ToString() + " : " + reply.Address.ToString());
else
Console.WriteLine(n.ToString() + " : <null>");
}
Console.WriteLine("Done.");
System.Console.ReadKey();
}
}
Should be good enough for a reliable local network.
Only two things spring to mind.
Have a trusted external server verify the visibility of the address (like an HTTP Proxy)
Check the DNS record on the site -- if it resolves to something internal (127.0.0.1, 10.*, 192.168.*, etc) the reject it -- of course, this might not work depending on how your internal network is set up
Not knowing if this is on a 3rd-party hosting solution or inside your/your company's internal network makes it hard to say which solution would be best; good luck.
EDIT: On second thought, I've canceled the second suggestion as it would still leave you open to DNS rebinding. I'll leave this here for that purpose, but I don't think it's a good idea.
That said, if you have some ability to control the network makeup for this server, then it should probably live in its own world, dedicated, with nothing else on its private network.
Check the URL address, and see if it matches your server address?
edit: or check against a range of addresses...
But all this does not answer the question: could the client access it?
Maybe some script in the browser to check that the url is accessible, and informing the server of the result.
But the user could edit the page, or simulate the result...
Have the client read the url contents and send it back to the server, instead of having the server fetch it?
Don't worry about the public accessibility of anyone else's web assets, that question does not have a definite answer in all cases. Just try not to compromise the access policy to your own (or your customer's etc.) web assets.
Use the existing access control mechanisms to control the web application's access. Don't just consult the access control mechanisms in order to duplicate them in the web application. That would be relying on the web application to refrain from using its full access - a false reliance if the web application ever gets compromised or if it simply has a bug in the access control duplication functionality. See http://en.wikipedia.org/wiki/Confused_deputy_problem.
Since the web application acts as a deputy of external visitors, treat it if you can as if it resided outside the internal network. Put it in the DMZ perhaps. Note that I'm not claiming that the solution is one of network configuration, I'm just saying that the solution should be at the same level at which it is solved if the visitor would try to access the page directly.
Make the web application jump through the same hoops the external visitor would have to jump. Let it fail to access resources the external visitors would have failed to access, too. Provide an error page that does not let the external visitor distinguish between "page not found" and "access denied".
The wininet dll has a function InternetCheckConnection
Allso look at InternetGetConnectedState
You are asking the wrong question. You should be asking, how can I limit access to a given URL so that only people on a certain network can access it?
The fact is, that you cannot test in the way that you wanted, because you likely do not have access to other sites on the same web server, in order to run a script that attempts to retrieve a URL. It is better to deny all access except the access that you wish to allow.
Perhaps a firewall could do this for you, but if you want more finegrained control, so that some URLs are wide open, and others are restricted, then you probably either need help from the web server software or you need to code this into the application that serves the restricted URLs.
If you are worried that your web application might be used to transfer data that comes from other servers protected by the same firewall which protects you, then you should change the application to disallow any URLs where the domain name portion of the URL resolves to an IP address in the range which is protected by the firewall. You can get that address range information from the firewall administrator.
This is only really a concern on in-house systems because in 3rd party data centers there should not be any private servers that don't have their own protection. In other words, if it is at your company, they may expect their firewall to protect the whole data center and that is reasonable, if a bit risky. But when you rent hosting from a 3rd party with a data center on the Internet, you have to assume that everything inside that data center is equally as potentially hostile as the stuff outside.