通过来宾虚拟机检索主机虚拟机MAC地址



这是我两天来一直在关注的问题。我将分享我的发现。

我目前正在为我们的软件开发一个内部许可证管理系统。它没有什么太花哨的——只要它能唯一地识别用户,就足够了。我们的机制目前依赖于用户登录+密码+MAC地址。

到目前为止,99%的用户没有问题,但有一小部分,即1%,一直在返回问题。这1%对我们来说非常重要,因为一次失败意味着我们的系统中有一个漏洞,这是我们想要清除的。好的,进入主题。

方法1:

public static string returnMAC1()
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select MACAddress, PNPDeviceID FROM Win32_NetworkAdapter WHERE MACAddress IS NOT NULL AND PNPDEVICEID IS NOT NULL");
ManagementObjectCollection mObject = searcher.Get();
foreach (ManagementObject obj in mObject)
{
string pnp = obj["PNPDeviceID"].ToString();
if (pnp.Contains("PCI\"))
{
string mac = obj["MACAddress"].ToString();
mac = mac.Replace(":", string.Empty);
return mac;
}
}
return "Nothing happened...";
}

方法1基于物理卡连接到PCI接口的事实来检索MAC地址。

方法2:

public static string returnMAC2()
{
string mac = string.Empty;
foreach (System.Net.NetworkInformation.NetworkInterface nic in System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces())
{
if (nic.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up)
{
macAddresses += nic.GetPhysicalAddress().ToString();
break;
}
}
return mac;
}

第二种方法是从MSDN文档中检索到的关于MAC地址的标准方法。

根据一些测试,第二种方法检索MAC地址似乎有点不可靠,因为它检索无线卡的地址。我们已经有一些用户因为使用这种方法而返回null地址,虽然我不知道为什么会发生这种情况,但可能是因为他们的计算机中缺少无线卡。话虽如此,这只是猜测方法#1依赖于使用SQL查询来检索PCI MAC。这个是可靠的

测试:

使用安装在VirtualBox虚拟机上的Windows 8.1 Enterprise Evaluation版本(免费试用90天,耶!),测试确认通过来宾虚拟机和主机虚拟机返回的MAC地址存在重大差异。

根据我的研究,在大多数情况下,只要不移动虚拟机,也不更改配置文件中的某些设置,虚拟机每次通电时都会被分配相同的MAC地址。话虽如此,但坏消息是。。。来宾VM MAC可以是任何东西。因此,这似乎是MAC地址在用作唯一标识符时不一致的原因之一,这是我在一些用户使用公司虚拟机时发现的一个问题。我从来不知道人们是这样工作的,但我们现在在这里,所以在这一点上不要幸灾乐祸。

我的问题是-有没有任何方法,在不让用户更改其端的任何设置的情况下,检索主机虚拟机的MAC,而不是访客虚拟机

在这一点上,我看不出有什么理由不给每台客户机分配相同的MAC来绕过我们的浮动许可机制。检索主机VM MAC可以解决这个问题,因为它将显示为一个MAC。

我们认为这既是不可能的,也是不必要的。我们还决定使用主板UUID作为主要的唯一标识符,并使用下面的MAC地址方法返回MAC地址,以防UUID在极少数情况下返回FFFF-FFFF.......,供应商不向该主板提供UUID。

public static string returnMAC1()
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select MACAddress, PNPDeviceID FROM Win32_NetworkAdapter WHERE MACAddress IS NOT NULL AND PNPDEVICEID IS NOT NULL");
ManagementObjectCollection mObject = searcher.Get();
foreach (ManagementObject obj in mObject)
{
string pnp = obj["PNPDeviceID"].ToString();
if (pnp.Contains("PCI\"))
{
string mac = obj["MACAddress"].ToString();
mac = mac.Replace(":", string.Empty);
return mac;
}
}
return "Nothing happened...";
}

最新更新