Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement machine id support for the future. #152

Merged
merged 11 commits into from
Sep 4, 2015
Merged

Implement machine id support for the future. #152

merged 11 commits into from
Sep 4, 2015

Conversation

voided
Copy link
Member

@voided voided commented Aug 26, 2015

Any day that requires code changes to logon to Steam is a spooky day, so here's some work to make sure we don't need any changes in the future when valid machine ids are required for logon.

Things to note:

  • WMI can be painfully slow. Valve spins up a separate thread at startup that gathers info, we currently query for info at logon time. Not ideal, but this is still a WIP.
  • For the linux machine id, valve primarily touches /var/lib/dbus/machine-id, but this may not be present on some systems (and may have been why certain linux steamclients were unable to logon today). Might need to look into alternatives for anybody not using systemd/dbus.
  • Nothing available for OSX. Haven't had much time to dig into the steamclient binary for it, but I'd imagine there aren't many consumers who need SteamKit on OSX.

public override byte[] GetMachineGuid()
{
RegistryKey localKey = RegistryKey
.OpenBaseKey( Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64 )

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does Registry64 behave on 32-bit Windows?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://msdn.microsoft.com/en-us/library/microsoft.win32.registryview%28v=vs.110%29.aspx

"If you request a 64-bit view on a 32-bit operating system, the returned keys will be in the 32-bit view."

@Netshroud
Copy link

OS X notes:

  • Machine Guid is IOPlatformSerialNumber
  • MAC Address is acquired by looping through IOEthernetInterface services from IOKit and getting the IOMACAddress.
  • Disk ID is acquired via the DiskArbitration framework - I didn't even know this exists. Steam requests the kDADiskDescriptionMediaUUIDKey property from whichever disk is mounted at /.

That's going to be a pain to P/Invoke, I doubt Mono has a wrapper for DiskArbitration.


public override byte[] GetDiskId()
{
return Encoding.UTF8.GetBytes( "SteamKit-DiskId" );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's too generic and it should return null instead. We don't want completely different servers to match as one machineid, do we?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A null hash would have the same result.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't hash it, if it's null?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hash field needs to be present and populated.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well that's no good, I'm not keen on having a generic hash this way.

@@ -161,7 +161,7 @@ public void LogOnAnonymous( uint appId = 0 )

logon.Body.client_os_type = ( uint )Utils.GetOSType();
logon.Body.game_server_app_id = ( int )appId;
logon.Body.machine_id = MachineIdUtils.GenerateMachineID();
logon.Body.machine_id = HardwareUtils.GenerateMachineID();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just nethooked steamcmd, and anonymous logins do not have machine_id set. And anonymous logins worked fine last night.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well I just checked normal logins, and they send an empty MessageObject on windows. Someone in steamworks forum was complaining that steamcmd didn't work last night 😆

// this was flipped off shortly after the update rolled out, likely due to linux steamclients running on distros without a way to build a machineid
// so while a valid MO isn't currently (as of aug 25th) required, they could be in the future and we'll abide by The Valve Law now

var machineId = new MachineID();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this function cache constructed machine id, and just return the cached object on future calls? WMI is slow, and the result isn't going to change between calls.

@voided
Copy link
Member Author

voided commented Aug 27, 2015

Okay, we now essentially have 1:1 functionality with how steamclient generates machine ids, along with a few extras:

  • We additionally check /etc/machine-id, some gentoo systems have this while lack /var/lib/dbus/machine-id.
  • We also use partition UUIDs for disk id.

I believe one last issue is outstanding for Linux: what can we do about getting some disk information for anyone not mounting their root directory by UUID?

Perhaps iterate /dev/disk/by-uuid and grab something from there?

@Netshroud
Copy link

On OS X, Valve get the UUID for whichever disk is mounted to /. I assume we could do the same on Linux somehow?

If it's not mounted by UUID, there's gotta be another way to get the UUID for that disk.

// if it turns out to be buggy we can always roll our own and poke into /sys/class/net on nix

var firstEth = NetworkInterface.GetAllNetworkInterfaces()
.Where( i => i.NetworkInterfaceType == NetworkInterfaceType.Ethernet )

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about other network interface types?

On OS X Mono 4.0.1, almost everything is showing as Ethernet.
On Windows .NET Framework, I'm seeing Ethernet for wired connections and Wireless80211 for WiFi.

This seems like it could fall back to "SteamKit-MacAddress" a bit too frequently. What adapters does Steam search for?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and Wireless80211 for WiFi.

Interesting, the MSDN docs don't state that that's a possible value. I suppose it can't hurt to include wireless adapters as well.

On Windows, Steam is using GetAdaptersInfo and checks for adapters of type MIB_IF_TYPE_ETHERNET and MIB_IF_TYPE_OTHER.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IF_TYPE_IEEE80211
71
An IEEE 802.11 wireless network interface.
Note  This adapter type is returned on Windows Vista and later. On Windows Server 2003 and Windows XP , an IEEE 802.11 wireless network interface returns an adapter type of MIB_IF_TYPE_ETHERNET.

I wonder when the machine ID code was written.

@Netshroud
Copy link

LGTM 👍

I don't think it should be reasonably able to fall back to the DefaultInfoProvider strings now, unless something goes catastrophically wrong.

voided added a commit that referenced this pull request Sep 4, 2015
Implement machine id support for the future.
@voided voided merged commit 0b25801 into master Sep 4, 2015
@voided voided deleted the machine-info branch September 13, 2015 18:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants