How can i know the actual geographical location of a database? - c#

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.

Related

Obtaining the IP and MAC of client machines connecting to my ASP.NET MVC application on a server

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.

Connecting to remote mysql database with API

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.

Update web.config file in asp.net

I am working on a web application which sits on a server and connects to various client machines based on the IPAddress.I have to change the IPAddress every time in the web.config file in order to connect to a particular client machine.
I want to put a text box where i can enter the ipaddress and it updates web.config file based on the button click which should eventually connect to the respective client machine.
Is it possible to do this way or i am thinking the wrong way ?
Can any one guide me in the right path ?
It sounds to me like your thinking is backwards.
If the application is dependent on you inputting an IP address every time, why store it in the web.config? Why not just build that into the application as part of the process to connect to the machine?
Run application page, request IP input, utilize input to connect to targeted machine.
The config file is meant for rarely changing settings and other application configuration data. This is a value that is needed on a per use basis, so request it on a per use basis.
If you have a set list of IP Addresses that you're always connecting to, you can store a delimited list in the web.config and then parse it. Something like:
<add key="IPAddressList" value="192.168.1.2;192.168.10.1;192.168.15.16" />
Then, in your application, just split and loop through the list:
foreach(string ip in ConfigurationManager.AppSettings["IPAddressList"].Split(';'))
//connect to server (ip = the IP Address)
If you're dependent on input each time, then it might just be easiest to save a List of IP Addresses to the Application.Cache and update that via your page (does it need to persist?).

Connecting to a database from the beginning

I have been working in a business writing advanced software apps, and obviously im provided with access to our SQL server and all the connection strings needed.This is fine for my job now - but what if i wanted to do this for a new (very small) business... If i wanted to purchase a small database server and set up a piece of software that talks to the databases on this server, how would i go about a) Talking and connecting to the server in code (c#) and b)What would i need regarding things like internet/phone connections etc to make this possible.
Edit: the reason it would need a server is because it would need to be accessed from 2 or 3 different computers in different locations?
Actually there are quite a few ways to create a database connection, but I would say one of the easiest ways is to utilize the methods and classes found in System.Data.SQLClient. A basic connection would look something like the following:
using System.Data.SQLClient;
namespace YourNamespace
{
public class DatabaseConnect
{
public DataType getData()
{
DataType dataObj = new DataType();
SqlConnection testConn = new SqlConnection("connection string here");
SqlCommand testCommand = new SqlCommand("select * from dataTable", testConn);
testConn.Open()
using (SqlDataReader reader = testCommand.ExecuteReader())
{
while (reader.Read())
{
//Get data from reader and set into DataType object
}
}
return dataObj;
}
}
}
Keep in mind, this is a very, very simple version of a connection for reading data, but it should give you an idea of what you need to do. Make sure to use a "using" or "try/catch" statement to ensure that the connection is closed and resources are freed after each use (whether it successfully gets data or not).
As for your other question about what equipment you may require. In the beginning I would suggest just creating the database on your local machine and running tests from there. Once you are confident with trading data back and forth, feel free to move the database to another box or an online server. Any internet connection type should suffice, though I can't vouch for dial-up, haven't used it in years.
One final note, if you do happen to decide to move to an online server system, make sure that the service you use allows for outside connections. Certain services use shared server systems, and force users to use their internal database interfaces to manage and write to the database.
--- EDIT ---
As for the server system itself, build up a separate box on your local network that you can see, and load up the database software of your choice. Since you are using C#, it would probably be easiest to go with Microsoft SQL Server 2005 / 2008. The installation is rather straightforward, and it will prompt you to automatically create your first database while installing.
After installation it will be up to you to add in the tables, stored procedures, custom functions, etc... Once your base structure is created, go ahead and use the above code to make some simple connections. Since you are familiar with the above practices then I'm sure you know that all you really need to do is target the server machine and database in the connection string to be on your way.
In case your application is small (by small I mean the usage of resources like CPU and memory) then your SQL Server can reside on the same box.
Else you need to have a separate server box for your database and connect to that from your application. In this case, preferably your database box and application box would be on the local area network.
Check this link for having a connection to SQL Server from C# code - http://www.codeproject.com/KB/database/sql_in_csharp.aspx
cheers
You should probably expose your database with an xml web services layer, so that your architecture will be scalable. The general idea is host your sql server and webservices, using Native SQL Server XML Web Services you can make this available to your remote clients. When in your clients you simply add a service reference in Visual Studio and your data will now be available in your client app.
Hope this helps some.
Cheers
You may find the connectionstrings website useful - worth bookmarking.

How to tell if connected to internet

I wish to write a windows app which does something when I become disconnected from the internet. I was thinking of writing a very simple C#/Delphi app which simply polls every 20 seconds to see if I'm still connected.
If I have to poll I'd really like a solution other than trying to download a web page from the net. I can't assume that a download attempt failing means "not online" since there may be other apps eating up the internet bandwidth. Plus I'm sure constantly connecting/downloading from a particular site is going to get my IP blocked.
I'm sure there's a way to tell if you're online without downloading/connecting to a remote server but I'm not sure how.
Beware that connected to the Internet does not really mean anything: what if you are connected to your ISP, but the backbone is down, or all the sites you want to access are in a country that went off the grid like recently? Having a connection does not mean you can do what you want.
Anyway, as stated before you can use the InternetGetConnectedState API to test that you have a valid Internet connection configured.
As an example, the following routine told me correctly I had a LAN Connection, but failed to detect that I had my ZoneAlarm firewall set to block "All Internet Activity", which means that you effectively lost all Internet connectivity.
Delphi routine:
procedure IsConnected;
var
dwFlags: DWORD;
begin
if InternetGetConnectedState(#dwFlags, 0) then
begin
if (dwFlags and INTERNET_CONNECTION_MODEM) = INTERNET_CONNECTION_MODEM then
ShowMessage('Modem Connection')
else
if (dwFlags and INTERNET_CONNECTION_LAN) = INTERNET_CONNECTION_LAN then
ShowMessage('LAN Connection')
else
if (dwFlags and INTERNET_CONNECTION_PROXY) = INTERNET_CONNECTION_PROXY then
ShowMessage('Connection thru Proxy')
else
if (dwFlags and INTERNET_CONNECTION_OFFLINE) = INTERNET_CONNECTION_OFFLINE then
ShowMessage('Local system in offline mode')
else
if (dwFlags and INTERNET_CONNECTION_CONFIGURED) = INTERNET_CONNECTION_CONFIGURED then
ShowMessage('Valid connection exists, but might or might not be connected')
end
else
ShowMessage('Not Connected. Try to connect and risk of being prompted to dial into another Internet Service Provider.');
end;
Call the InternetGetConnectedState function. This knowledgebase article explains how to do it.
It looks like it can be done by using the method described here: http://www.csharphelp.com/archives3/archive499.html

Categories

Resources