amonroy has asked for the wisdom of the Perl Monks concerning the following question:

Summary: I have a group of CGIs that check a license at runtime. The license is based on the IP of the server and it's stored in an external file. This model has been useful for a while, but I have encountered problems reading the real IP address of the machine because (I believe) the way I read the IP address is based on the hostname. Let me elaborate.

The license string is generated doing an hexdigest of the IP addres and a predefined number. I also check that the IP address is not an internal network IP (such as 10.*.*.*) or the loopback address 127.0.0.1.

Basically the license creation is done like this:

use Sys::Hostname; use Socket; use Digest::MD5; my $hostname = hostname(); my $address = gethostbyname($hostname); my $ip = inet_ntoa($address); my $key = "1234567"; # arbitray number my $md5 = Digest::MD5->new; $md5->add($key, $ip); my $license = $md5->hexdigest;

For checking the license is just the reverse of the above.

My methodology has some problems because sometimes the /etc/hosts resolves the hostname to 127.0.0.1 or to an internal IP instead of the "real" external IP. I obviously don't want to give licenses to internal IPs or the loopback address.

I wish there was a way to know the "real" IP address that the machine has for the exterior world. Question 1: Is there a better way to read the IP address?
Question 2: Have any of you implemented a similar licensing model, what other models have you used?

P.S. I have encrypted my code so the license thing is not easy to read. Although the only way to hide the source code is by deleting it :-) (FAQ).

Pax vobiscum.
-Andrés

Update: Thanks for your comments. Yes, I am aware that there is no way to be 100% sure that the customer cannot read the code. But as I mentioned before, this protection is good enough for this specific case.

Replies are listed 'Best First'.
Re: Licensing model for CGIs using IP addres
by Errto (Vicar) on Apr 21, 2004 at 04:06 UTC
    The earlier anonymous post is correct, but I'd like to add a couple of things:
    • Many boxes sit behind a NAT-enabled firewall. That means the box will have an IP address of 192.168.x.x or 10.x.x.x and will have no reliable means of determining its Internet IP address (if it even has one)
    • A box admin can set its IP address to whatever they want as long as their local router is equipped to read it
    • Boxes can have multiple network interfaces with different IP addresses. How would you determine which is the real one?
    • Even boxes directly hooked up to the Internet can spoof IP addresses
    The only thing I can think of is to have your code "call home" to a server of yours. Then you would (probably) know the real IP address it was coming from and could respond by returning a cryptographic key of some sort. This key would then be used to "unlock" the remainder of your code. However, as my anonymous colleague mentioned, this relies on your code staying obfuscated, which is, well, difficult. This is because otherwise, even if you used such a scheme, the customer could modify the code to store the key and then share it among multiple installations.

    IP address checking may be appropriate if you are providing some service via the Internet, which your software, installed on customer sites, needs to invoke. But unless you're planning to establish some communication, you may have to rely on compiled code.

Re: Licensing model for CGIs using IP addres
by Abigail-II (Bishop) on Apr 21, 2004 at 09:17 UTC
    You are making a classical mistake, and that's the assumption that machines have IP addresses. Machines don't have IP addresses, interfaces do. Servers often have more than one interface, interfaces often have more than one IP address, IP addresses can be assigned to more than one interface at the same time, and interfaces can change their IP addresses without the services on the same machine needing a restart. This is common practise with webservers that run in a high-available and/or load balancing cluster. Furthermore, it's not at all uncommon for the actual webserver to only have "internal" IP addresses (addresses in the private range) - routers, firewalls and NAT boxes happily do address translation, port forwarding, etc.

    Therefore, the question "finding out the 'real' IP address of a machine" doesn't make much sense.

    Abigail

      Thanks, that was enlightening.

      -Andrés
Re: Licensing model for CGIs using IP addres
by Anonymous Monk on Apr 21, 2004 at 03:37 UTC

    All I can say is that no matter what you do, the licensing can be nulled out completely and the script run normally. Once a determined person gets rid of your so called "encryption" (most likely you meant "code obscuring"), all it takes to bypass the license is to replace whatever line looks like if ($should_be_license eq $real_license) {} with a if (1) {} or something similar. As far as I can see, there is no way to write a script that enforces licenses. The best you can do is pull together some fancy legal team that will go after any person(s) who use the licensed program after the license expires. Or do it the smart way and 'sell' the code (as in, they own their copy, no expiration). Even then, you may want a legal team that will chase after those who break a written 'license'-type contract. (ie: "This contract permits the purchased software to be installed on no more than 3 computers... etc etc").

      All I can say is that no matter what you do, the licensing can be nulled out completely and the script run normally.
      While that's true, it doesn't mean that putting in some enforcement is meaningless. A determined person will be able to break into your house as well - all they need to do is break a window, drill out the lock, pick the lock, etc. However, entering your house by breaking the protection is in most countries a more severe crime than opening an unlocked door and entering the house. If something gets stolen, your insurance company might not pay if you didn't use locks.

      If your program makes some attempt to enforce a license, it takes a conscious action to bypass it, and someone breaking it can't plead innocense. They also might lose their right to support if they modify the program in any way (yeah, I know, it's hard to find out whether they did). It raises the bar.

      Abigail

Re: Licensing model for CGIs using IP addres
by coec (Chaplain) on Apr 21, 2004 at 04:16 UTC
    I could be way off base here (with respect to the question being asked) but here goes...

    If your script is running on the machine you are checking the IP of, you could do a 'netstat -i' or a 'ifconfig | grep "inet addr"' to get the list of IPs and parse the list (depending on your Unix variant.)

    Obviously, I'm assuming you're using Unix, under Win32 run 'ipconfig /all'

    CC

Re: Licensing model for CGIs using IP address
by BigLug (Chaplain) on Apr 22, 2004 at 03:45 UTC
    While still not 100% accurate, you could use the output of ifconfig to determine if your script is running on the machine you expect. My host, for example, has no external IP address but uses an Ethernet card to connect to a router. ifconfig returns the Hardware address of the Ethernet card. This is (supposedly) a unique address and thus you could use this address for your script.

    Others have pointed out that code like  die unless $hardware eq '6E:34:D8:6C:18' is easily bypassed. So maybe it'd be worth looking at an encryption of your code that uses the machine's hardware address as the key? That way the 'proxy' gets your hardware address and decrypts a code file using the key. It then runs the file or returns an error.

    Of course, the serious hacker can still easily bypass this, but it wouldn't be too hard to write just this part in a compiled C file.

    Just my thoughts on how to do the (nearly) impossible.

    "Get real! This is a discussion group, not a helpdesk. You post something, we discuss its implications. If the discussion happens to answer a question you've asked, that's incidental." -- nobull@mail.com in clpm