Linux Equivalent of MachineGuid - c++

I have program that needs OS installation fingerprint like one in MSW stored at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\MachineGuid
In Microsoft Windows I have it ready for me but I cannot find equivalent for Linux. Is there anything close to this in Linux? I will not have root access so anything like dmidecode -s system-uuid becomes out of the question.
An example will be nice but no necessary.

One possibility would be to read /etc/ssh/ssh_host_{d,r}sa_key.pub, which are readable by all, and are randomly generated during installation.
Obviously the problem is that those files may not exist at all, if there is no SSH (server) installed. They are also often copied from an older installation.

I believe MAC addresses are not a good choice for identifying a machine. There are many USB dongles which may be plugged into a PC to provide a mobile/3G/H+/etc. network interface, so while such a dongle is plugged into the machine, it will have a different id derived from available network interface MAC addresses.
Is /etc/machine-id (/var/lib/dbus/machine-id) available on your target system?
see: http://man7.org/linux/man-pages/man5/machine-id.5.html
see: http://0pointer.de/blog/projects/ids.html

The canonical Unix'y answer is the Host ID, but in practice, this often ends up falling back on a hash of the IP address…
#include <unistd.h>
long gethostid(void);
int sethostid(long hostid);
DESCRIPTION
gethostid() and sethostid() respectively get or set a unique 32-bit identifier for
the current machine. The 32-bit identifier is intended to be unique among all UNIX
systems in existence. This normally resembles the Internet address for the local
machine, as returned by gethostbyname(3), and thus usually never needs to be set.
NOTES
In the glibc implementation, the hostid is stored in the file /etc/hostid. (In glibc
versions before 2.2, the file /var/adm/hostid was used.)
In the glibc implementation, if gethostid() cannot open the file containing the host
ID, then it obtains the hostname using gethostname(2), passes that hostname to geth‐
ostbyname_r(3) in order to obtain the host's IPv4 address, and returns a value
obtained by bit-twiddling the IPv4 address. (This value may not be unique.)

I assume you're trying to do this because you want to "lock" the software to a specific piece of hardware?
One option is to use the MAC address of a network interface to identify the current machine. The MAC address is fairly easy to get at, see this Stackoverflow question.
This nicely works around issues with changing IPs etc as the MAC address of an interface is much less likely to change unless someone replaces the network card.

Related

Unique ID of an embedded system running Yocto

I have an embedded system running Yocto. The MAC address is not stable (it is random one that changes at every restart). The CPU ID is the same for all devices of this embedded system model.
What other options should I look for to use as unique ID of the system? I need a unique ID for licensing purposes. I should retrieve this ID from an C++ Application.
try to ask Intel if they have space on the MCU, we usually store our MAC Address, Serial number, as well as ddr configuration there; This can be a one time flash.
After you have confirmed the address; You could use smbus to write the serial number into that space and retrieve it later;
This is a better way than UUID because the serial will always be there even after you have delete everything;
By the way, if the MAC Address is random, it is most likely because there are no MAC Address flashed into the system.
Again, ask Intel on how to flash your own MAC Address into the system. This might eliminate the need to create another serial number;

Returning Device GUIDs and Bios ID, C++, Linux

I am trying to write a function to return all the GUIDs of the devices attached to the machine, as well as returning the BIOS Id. How would I achieve this? I can only seem to find ways of doing it on a windows machine, but not a linux.
Linux does not assign a GUID to everything. Hardware is identified by hardware-native means, e.g. USB and PCI devices are identifies by vendor and device ID (and serial number).
You can see what data the kernel offers by browsing /sys. I'd also check the source of tools like lspci and lsusb to get an idea on how one retrieves data programmatically (i.e. without parsing files in /sys).
There is, by the way, also a tool called dmidecode, that does operate directly on DMI data.

How to convert a MAC address to the corresponding IP address?

I am looking for an easy way to convert a MAC address to the corresponding IP address in a local network. In my case, there are only two devices: a very normal PC (192.168.0.1) and a scientific instrument which has an arbitrary IP address (192.168.0.xxx) hard coded in its ROM. The PC and the instrument are directly connected over a UDP socket with a CAT5 cable.
I know the MAC address of the instrument, but please assume that its IP address is unknown. I would like to write a C/C++ application which talks with the instrument using a socket connection. But I need to know the IP address before opening a socket (WinSock on Windows, sys/socket on OS X and Linux).
Currently I use a very dirty way as shown below.
Execute ping command ping 192.168.0.2 (NOTE: the instrument does not respond to ping)
Repeat this from 192.168.0.2 to 192.168.0.255
Execute arp -a to print a list of IP and MAC addresses
Find the known MAC address and the corresponding IP address from the list
I would like to know how to retrieve the IP address in a more sophisticated way. It will be very nice if I can use the same method on Mac, Linux and Windows machines.
As far as I know, I have to broadcast a ARP packet to the network in order to retrieve a MAC address from a known IP address. But I could not find a way to get an IP address from a MAC address.
There's no good, generic solution for this as it is the reverse of intended behavior. Lower level protocols are not supposed to need to be aware of higher layer ones, so operations at the MAC layer don't have any good way of finding out about IP addresses. And then you get into the situation you're in now. So you can either employ a hack like the code you already have, or you can tackle this from a different direction. Is there any non-code way to determine the IP address of the device before hand? Such as setting it explicitly or putting it in a configuration file for your app. Alternatively, can you have the device send out spurious ARP requests? The PC should update its ARP cache based off of incoming requests as well as responses to requests it made.
We had to do this a while back, but I don't think we got it working properly.
I don't have the API calls off-hand, but they're easy to find in the Windows API. That's what we used, so our solution wouldn't be portable to non-Windows systems.
In our case, we ran into the same hurdle--no easy translation. What we ended up having to do was get a list of all the NICs available, and then loop through each one trying to match our given MAC address against the MAC address obtained from the NIC structure.
Once we found a match, we looked up the IP address given to the NIC structure.
We kept on going to see if we found any other matches in order to log an error. It's a good thing we did, because I believe we did find it multiple times, and it wasn't due to a MAC address being cloned.
That's when we learned that this would be an even harder problem, and we decided to abandon the whole thing and stick to just IP addresses.
How about try the system command arp within c++
system("arp");
This gives you a IP-MAC translation table.
few days ago I was also facing this issue but after many struggle I got its solution below
How MAC to IP address converter tool works?
This MAC address converter can convert MAC address to IPv4 IP Address and convert MAC address to IPv6 IP Address, these internet protocol Addresses are very common to use. It takes MAC Address as input string and generates a query against given MAC to IP address and MAC conversion option like to MAC to IPV6 or MAC to IPV4 or both for MAC address conversion together. After this MAC conversion you can also revert MAC to IP conversion changes by using IPv6 to IPv4. Query generates an output response according to selected options.If you insert any invalid input produces an invalid input message response

Ping network and get mac addres

I'm a starting C/C++ programmer.
What I want is the following thing:
Start program, starts to ping whole network and saves the addresses that where active. When done, get mac address from ip addresses that where stored before, and save them.
When done, loop trough the mac address list, and find 1 mac adress, when found, shout around that he found it.
Something like that does I want to make.
I've Googled a lot, but nothing realy helped me.
So my question, what do I need (which libraries, which statements), so I can program this.
On note, my OS is at the moment Windows, but I want to make it compatible with Linux in the future also.
Use the arp tool on the commandline eg arp -a 192.168.0.100
From c++ it depends on your OS, on Windows it's SendArp()
To scan for all machines on the lan use nmap - see How do I get a list of the active IP-addresses, MAC-addresses and NetBIOS names on the LAN?

Uniquely identify PC based on software/hardware

For a requirement to generate per-PC license keys, I need some code which will return a stable and (near) unique key on any PC. It doesn't have to be guaranteed unique, but close. It does need to be reasonably stable though, so that a given PC always generates the same result unless the hardware is substantially changed.
This is for a Windows application, using wxWidgets but a Win32 or other option is fine.
I was thinking about MAC address but what about laptops which can routinely disable the network card in power-saving mode? I came across GetCurrentHwProfile but it doesn't quite look like what I want?
One idea I had a while back for this is to use CryptProtectData as a way to identify a machine. Behind-the-scenes in that API, Microsoft has done what you're looking for. I never tested it though and I'm curious if it's actually viable.
Basically you would encode a constant magic value with CryptProtectData with CRYPTPROTECT_LOCAL_MACHINE, and the result is your machine ID.
I would just go with the MAC address method; when the wireless / LAN cards are turned off they still show up in Network Connections. You should therefore still be able to get the MAC.
Consider this: Any time you'd be able to contact your webserver or whatever you're cataloging these IDs with, the user is going to have to have some form of network card available.
Oh, and you might be able to use CPU serial number of the customer's computer supports it.
I think there no really easy and unique method so far discovered here.
GetVolumeInformation retrieves not even close to unique ID.....
To use any hardware serial is problematic because manufactures are not committed to supported it always and especially to keep it globally unique
GetCurrentHwProfile retrieves GUID but it's value affected by minor! hardware changes...
Using Product Key ... will bring U to deal with the stolen software - there lot of pirate installations over the globe.
Creation of own GUID and preserving it under registry (in any place) will not prevent duplication by cloning of image ....
etc...
From my perspective of view the best way is combine:
Volume ID + MAC's list + Machine SID + Machine Name. And obviously manage license policy on the server side ;0)
Regards
Mickel.
If you want something a bit harder to spoof than whatever the machine itself can tell you, you'll probably need to provide a USB dongle dedicated for this purpose (not just a flash drive).
For a pretty brain dead test I am using the ProductID code of the OS and the computer name - both extracted from the registry. Not really secure, but its all pretend security anyway.
edit
To answer John's question about what keys I am reading:
SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductID
SYSTEM\CurrentControlset\Control\ComputerName\ComputerName\ComputerName
How about using the serial number of the harddisk where windows is installed?
The function GetVolumeInformation() will give you such serial number.
To access the ID assigned by the harddisk vendor instead of the ID assigned by Windows, you can use the Win32_PhysicalMedia Class.
To determine the drive where windows is installed, you could expand the variable %windir" by using the function ExpandEnvironmentStrings()
Another option, if your architecture allows, is to use UuidCreate() to generate a random GUID at installation time and save it permanently in the registry. This GUID can then be used as the ID as long as the registry remains. A new registry database is generally considered as a new installation.
A third option is to have a well-known server assigning the IDs. Upon starting up, the software could look up for the ID in the registry and if not found, would contact the server and supply it with its MAC address, hostname, harddisk serial number, Machine SID and any number of indentifyable information (keys).
The server then determines if the client is already registered or not based on the information given. The server could have a relaxed policy and for example only require most of the keys for a match, so that the mechanism would work even in the event of a complete wipe out of the registry and if part (but not all) of the hardware was replaced.
How about using the serial number of a CPU. I remember Microsoft used to provide an api for this that would run the necessary assembler code and give you back all sorts of info about the CPU including serial number. Not sure if it'd work with AMD chips or not, I think it was intel specific.
Surely CPU Id is secure and static enough!!