Microsoft App-V and Hardware IDs - c#

I am currently working on a software solution written in C# .NET 4.5. The software uses a licensing system that is based on hardware IDs (for example MAC address or CPU ID).
One user now reported that he has issues with the licensing when using the software with Microsoft App-V. He mentioned that every time a new User wants to use the software the application complains that the license is not valid (due to a change in the hardware).
This also happens if a previously registered user uses the Software on a different client.
My question now is, when running an application via App-V, what does the following snipped of code return, the Mac address of the client or of the server where to application is actually running. If the first is true, is there a way to get the same information from the server too, using some functionality in .NET?
private static string getMAC() {
ManagementClass oMClass = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection MOCol = oMClass.GetInstances();
string mac = "";
foreach (ManagementObject MO in MOCol) {
if (MO != null) {
if (MO["MacAddress"] != null) {
mac = MO["MacAddress"].ToString().Replace(":", "");
if (mac != string.Empty) {
break;
}
}
}
return mac;
}

Next-to-last bullet in the Limitations section in App-V's Wikipedia article fits your problem exactly:
Licensing Policies: Applications with licensing enforcement tied to the machine, e.g. the license is tied to the system’s MAC address or harddisk serial number. This type of application should not be sequenced if the activation can not be done by the user at the first launch of sequenced application, manually or by script.
You'll need to tell your customer that you cannot support App-V if you verify the license on each individual run of the app instead of just once at app install time. If that means that you'll lose a valuable customer then quickly get rid of this scheme, a business decision we cannot make for you.

Related

Windows 10: differentiate between preinstalled app and downloaded app

One of my clients has a deal with an OEM. Their app X will be preinstalled on a number of laptops. This app will receive updates from the Windows 10 store. This app X will also available for download in the Windows 10 store to other users. Only users using the preinstalled version should receive a free 3-month trial.
Unfortunately, the OEM is not providing any device IDs, and the users are not getting any unlock codes for their trial. I came up with the following initial "solution":
Use version 1.0.1.0 for the preinstalled app.
Upload 1.0.0.0 to the store.
When the app starts and the version is 1.0.1.0, it is identified as a preinstalled version, at which point I can make a server call to send a device ID to the client's server to recognize this device even after app deletions.
I can update the store app without losing any knowledge of preinstalled apps since I can update to any version below 1.0.1.0. This means the preinstalled version will not be overwritten by auto update with the store version (since the installed version number is greater than the store version). However, if a serious bug is detected in the preinstalled version, I cannot update that app or a certain class of users will not receive their free trial. Namely, the users that have not started the app on the device yet before Windows 10 updates the app with the new version (1.0.1.1 for example).
This all sounds unnecessarily complicated, and I hope it is. Can anyone think of an easier way to distinguish between the preinstalled and downloaded version that's foolproof?
Thanks!
As you are already thinking about offering 2 different versions, this one might be a better solution, where you can deploy two times the version 1.0.0.0.
Instead of using the versions to differ between the state, use build symbols.
Create two differnt builds, one for your OEM client, and one for store deployment.
For the OEM, where you want to allow the trial, use the following - as an example:
private bool CanUseTrial()
{
#if OEM
return true;
#else
return false;
#endif
}
Doing it this way will allow you to maintain the same code base for all clients, but differing between case OEM and case store deployment, without much logic needed.
EDIT #1:
To address the problem of OEM clients updating to non-OEM clients, you can still go with this approach (as long as the app runs at least once as #OEM build):
private async Task<bool> CanUseTrial()
{
var clientCode = GenerateClientCode(); // However you're going to do this
#if OEM
WebServiceXyz.RegisterOemClient(clientCode);
return true;
#else
try
{
return await WebServiceXyz.IsRegisteredOemClient(clientCode);
}
catch
{
return false;
}
#endif
}

identify a machine not by using IP

Suppose I'm programming a game and I want the option of banning people from it after violating the terms. I can ban them per account, I can also ban their IP but it's not going to ban them from my game forever. They will just have to create a new account and change their IP.
Is there something like a machine-ID that is unique for every machine in the world? If there is, is it possible to read it using a program language? Is it possible for the user to change this machine-ID?
Bulletproof solution?
I would say no solution will be 100% secure, even with huge invested money..
What you can do, is to make it as hard as possible for normal users, and this way minimize the cheaters.
You could make a hash id of the pc machine id + the mac address + the motherboard id + the harddisk id, etc. But a clever cracker/hacker could get around this. I mean take a look at companies like Microsoft that uses millions in making a secure way and still people can get around the activation in some way... ;)
In windows there is a hardware id, that you might be intrested in.
HKEY_LOCAL_MACHINE\Software\Microsoft\Cryptography\MachineGuid
Take a look at WMI too, there are examples of how to use it with c++
Windows Management Instrumentation (WMI) is a set of extensions to the Windows Driver Model that provides an operating system interface through which instrumented components.
see WMI c++ exmaples
How about hard disk serial number which you can get in WMI Win32_DiskDrive.
ManagementObjectSearcher searcher = null;
try
{
searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_DiskDrive");
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("SerialNumber: {0}", queryObj["SerialNumber"]);
queryObj.Dispose();
}
}
finally
{
if (searcher != null)
searcher.Dispose();
}

How can I connect to a Server Side USB (HID) Device from within an ASP.NET Application?

I'm trying to write my own controller for a USB device instead of using the SDK that comes with the product (I feel the sdk is sub-par).
The USB Device is plugged into the SAME SERVER that this application is running on.
So I decided to head over to Nuget and grab the HidLibrary
PM> Install-Package hidlibrary
and I proceeded to follow the example found on GitHub.
First I went into my control panel to verify the VendorID and the ProductID
And I dropped it into my code.
Then I set a breakpoint on the line that grabs the device, but unfortunately it always comes back null.
using HidLibrary;
public class MyController : ApiController
{
private const int VendorId = 0x0BC7;
private const int ProductId = 0x0001;
private static HidDevice _device;
// POST api/<controller>
public string Post(CommandModel command)
{
_device = HidDevices.Enumerate(VendorId, ProductId).FirstOrDefault();
if (_device != null)
{
// getting here means the device exists
}
else
{
// ending up here means the device doesn't exist
throw new Exception("device not connected");
}
return null;
}
I'm hoping it's something silly, and not some deal-breaking permissions issue regarding connecting to a USB device directly from an IIS worker.
Despite your hopes to be something silly, it is not. You have some deal-breaking permission issues. If you will browse Mike O'Brien's code from GitHub of the Hid Library you will see that it calls Win32 API functions located in: kernel32.dll, setupapi.dll, user32.dll, hid.dll (Native.cs).
The enumeration itself it's done through setupapi.dll functions. It browse all the installed devices and filters what it's need it.
So... I think it's a security issue to execute kernel32.dll code directly from a web-app in IIS with anonymous authentication, don't you?
If you really need to communicate with that HID (who knows maybe it's a temperature sensor, or something else) I would do a separate Windows service and the IIS hosted web app would communication through WCF with this service. This service would like a proxy.
Put the same code in a console application and run it. That will help you verify if it's your code or environment.
If it's environment, try using Process Monitor to see if there are any hidden access errors. Also try enumerating all devices, not just looking for the one device you're after, just to see if you can do it in ASP.NET.
#Chase, unless this is an experiment - it is best not to attempt connecting to a device from IIS process. [It's a Pandora's box if you start down this path].
Best way to do this is to have another (WCF) service as proxy to the device and expose just what you need out of the service, hook it up with your app. Feel free to ask for an example if you think that would help.
I +1 #garzanti.

Secure My ASP .NET Code For Presentation?

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.

Is it possible to programatically log access to a windows share (SMB share) using the .Net framework?

Just wondering if it is possible to figure out who has read files from a Windows share (using .NET ideally but win32 native will do)?
What I'm try to do is create something like awstats for a windows share so I can see who is accessing what and which are the most popular files.
I'm not interested in changes - I just want to log access (with time) along with ip / hostname and what file.
this is possible using WMI... below the sample c# snippet used to identify whose accessing the shares currenlty
using System.Management;
ManagementObjectSearcher search =
new ManagementObjectSearcher("root\\CIMV2","SELECT * FROM Win32_ConnectionShare");
foreach (ManagementObject MO in search.Get())
{
string antecedent = MO["antecedent"].ToString();
ManagementObject share = new ManagementObject(antecedent);
string dependent = MO["dependent"].ToString();
ManagementObject server = new ManagementObject(dependent);
string userName = server["UserName"].ToString();
string compname = server["ComputerName"].ToString();
string sharename = server["ShareName"].ToString();
}
Am not sure about the core file event listners for WMI. But you can nicely integrate this into the NoramlFileSystemWatcher. And trigger the above code if there is a change detected in the network path.
You want FileSystemWatcher. Build a program that uses it and logs changes.
SMB runs by default on port 445. So you can just log traffic on port 445 (or whatever port(s) you happen to be running it on) and massage that easily enough into whatever data you need.
I'd do it with WinPcap and WinDump (Windows versions of libpcap and tcpdump). Defining custom rules (say, to record data on only one or on a range of ports) is easy. Check out the 'expression' section of the manual. There are parsers available in a lot of different languages for the data files. A quick search will find you what you need.
In order to do it using WinPcap in .NET you can use Pcap.Net.
It is a wrapper for WinPcap written in C++/CLI and C# and it includes a packet interpretation framework.

Categories

Resources