dashingsoft / pyarmor

A tool used to obfuscate python scripts, bind obfuscated scripts to fixed machine or expire obfuscated scripts.
http://pyarmor.dashingsoft.com
Other
3.28k stars 280 forks source link

Unable to bind license to domain #1929

Open Paul-Rutten-MPS opened 4 days ago

Paul-Rutten-MPS commented 4 days ago

Domain binding issue

According to the documentation it should be possible to bind a license to a domain:

pyarmor gen key -b "{dashingsoft.com}"

Using this command with the domain returned by python -m pyarmor.cli.hdinfo, the generated license contains the following:

*HARDDISK:{<my_domain.lan>}

with being the domain hdinfo identified.

When I use the generated license, I get a runtime error: “RuntimeError: this license key is not for this machine” Removing the '"', '{', '}' characters from the command did not fix the issue.

Other device bindings

Creating and using license files with an expiry date, machine ID, harddisk ID, or mac address results in the Pyarmored code running as expected.

Using flags

Using an undocumented flag to mark that the specified information is a domain:

pyarmor gen key -b "*DOMAIN:{<my_domain.lan>}"

Resulted in the license containing:

*HARDDISK:*DOMAIN:{<my_domain.lan>}

Removing the '{', '}' characters from the command did not fix the issue.

These undocumented flags do work for HARDDISK and IFMAC. Information marked with the IFIPV4 flag is also interpreted as a harddisk ID: HARDDISK:*IFIPV4:

jondy commented 3 days ago

Here is pre-release version https://pyarmor.dashingsoft.com/downloads/temp/pyarmor-8.5.12.zip

It has fixed this issue

Paul-Rutten-MPS commented 3 days ago

Hi Jondy,

Thank you for your quick response. The pre-release you made available is giving me some mixed results:

Using a flag works

Using a command that contains the *DOMAIN flag gives me expected results:

pyarmor gen key -b "*DOMAIN:dashingsoft.com" creates a license with: *DOMAIN:dashingsoft.com

Using { } fails

pyarmor gen key -b "{dashingsoft.com}" creates a license with: *DOMAIN:{dashingsoft.com} which is not an exact match with the domain found with python -m pyarmor.cli.hdinfo, and thus triggers a license error.

Confusing error message

The error message you get with an incorrect domain (*DOMAIN:narnia.gov) in the license is: "RuntimeError: missing license key to run the script (1:10672)"

I would have expected a message like "License is not for this machine".

jondy commented 3 days ago

This issue has been fixed in pre-release version https://pyarmor.dashingsoft.com/downloads/temp/pyarmor-8.5.12.zip

Now both of these commands work

pyarmor gen -b "{dashingsoft.com}"
pyarmor gen -b "*DOMAIN:dashingsoft.com"

The error message you get with an incorrect domain ( *DOMAIN:narnia.gov) in the license is: "RuntimeError: missing license key to run the script (1:10672)"

I can't reproduce this issue, what I test is

pyarmor gen -b "{abc.com}" foo.py
python dist/foo.py

It raise "License is not for this machine" exactly.

Please make sure the outer key file is in the right place.

Paul-Rutten-MPS commented 2 days ago

The updated pre-release indeed fixes the issue with the '{', '}' characters being included in the license file.

The error message for invalid domains is also as expected: RuntimeError: this license key is not for this machine (1:10284)

I am not sure what the cause of the problem was yesterday. I replaced valid license files in the runtime folder with invalid ones and got unexpected error messages. Anyway, it is working now.

Possible enhancement: With domain binding working as expected, would it be possible to have the __pyarmor__ function return the bound domain, when using the 'hdinfo', and 'keyinfo' options?

jondy commented 2 days ago

The old document misses something (it has been fixed now), the domain name could be got by

__pyarmor__(4, None, b'hdinfo', 1)

About query domain name in the runtime key, the workaround is to store them in the bind data also. For example,

pyarmor gen -b "{dashingsoft.com}" --bind-data "dashingsoft.com"

Then it could be got by

doman_name = __pyarmor__(0, None, b'keyinfo', 1).decode()