Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I am stumped by a request from my manager. I work for a small startup and we developed a web application for a fixed rate with a maintenance agreement for a MUCH larger company. Knowing horror stories about how large companies will only pay their bills to the last second we decided that we would like to protect ourselves by being able to license this web application in a way that if we don't get paid the software no longer works.

I have seen this done before for desktop applications however this will be a web application that they will host internally and will not be accessible from the Internet.

What is the best approach to do this, we would like it to have a small footprint and would like the ability to renew the license key that they have distributed.

Has anybody done something similar? Are we completely out of our minds? Does anybody have any better suggestions?

share|improve this question
    
If you REALLY want to do this, you probably need a commercial solution. –  user1249 Jun 14 '11 at 8:08
    
@Thorbjørn, Why? –  maple_shaft Jun 14 '11 at 11:18
    
To do this properly you will need a LOT of time (or they will just break it). It is much cheaper just buying a product which is designed to protect java programs. Otherwise just make the license a java byte code snippet which the program reads and then acts upton. –  user1249 Jun 14 '11 at 12:21
    
That is what I was afraid of, I will look into third-party solutions however we are already painfully overbudget. –  maple_shaft Jun 14 '11 at 15:49
    
Then just make it go painfully slow 2 weeks after payment is due. –  user1249 Jun 14 '11 at 16:04

6 Answers 6

up vote 5 down vote accepted

There are many ways to implement something like this, but here's one that shouldn't be too hard to do:

You need a publicly-available website somewhere that hosts a file containing the hashes of license keys that have been blacklisted. How you manage this file is up to you, but the file itself need only have a hash per line.

Then, on a recurring basis, your software initiates a download of this file (most server-side languages provide for this) and then searches it for the hash of the installed license key. If it is found, then the application knows that it should die until the blacklist is removed.

MD5 or similar plus a secret should be sufficient for this. You could get fancier and have the application send the request to your site and you look it up in a database on the fly, but the file (for what I'm assuming would hopefully be a short list) would hopefully remain small and may be the easiest way.

The harder part is going to be keeping the application dead. After all, you've got to store this somewhere internally, which means if it is overly obvious it could be easily subverted, and even if it isn't overly obvious, it can be easily reverted by restoring the appropriate table(s)/file(s). Therefore I suggest a second method of protection as well.

This method would store "LIVE" or "DEAD" (or something sufficiently similar) in a table or a file, but again HASHed. This needs to be hashed with your salt AND a timestamp. Everytime a page on your application runs, check this value with a hashed version of "LIVE"+salt+timestamp and then permit for a valid range of timestamps (for example, one day, two days, one week, one month, etc. Keep in mind the larger the range the harder performance will take a hit.). As long as things match (or a match is found), the app is alive; otherwise, even if the value in the special file or table is "LIVE", it will still be dead if there is attempt to restore from backup because the timestamp will fall outside your threshold.

In summary (this does assume that you have some programatic method of checking the validity of a license key, such as some sort of checksum or other method):

  • CheckBlacklist
    • Convert License Key to hash with salt
    • Request blacklist file from server
    • Is my hash in the file?
    • If YES, then store hash of "DEAD" + salt + timestamp (truncated to day; no need to store hours+days+minutes)
    • If NO, then store hash of "LIVE" + salt + timestamp (trunc'd)
  • IsKeyAlive
    • Create hash from "LIVE" + salt + trunc'd timestamp
    • Load DeadAlive hash
    • Do they agree?
    • If YES, then we're alive; return TRUE.
    • If NO, then we're possibly dead, but we may still be within our timestamp window:
      • Subtract a day from the timestamp and repeat hash.
      • Do we agree now?
      • YES? Return TRUE
      • Add a day to the timestamp and repeat hash
      • Do we agree now?
      • YES? Return TRUE
    • At this point, we're out of the timestamp range with no match. Return FALSE. (Kill app)

Now, goodness knows there's a million and one ways this can fail. Consider all the possible ways and build a reliable system (including one that assumes the client is right if the blacklist file can't be downloaded). Test, test, test it, and then test some more before deploying, because if it goes wrong, you'll have lost your client's trust.

share|improve this answer
    
+1 For an epically complicated answer O_o. I may be wrong but I do not think this needs to be quite this complicated. I am not distributing Microsoft Office, this a custom built application for a single client. The same problems still remain here that the server hosting this application may not be able to communicate with an external service. I don't understand why encryption, hashes and salts are really necessary here. What we really want is effectively a kill switch. –  maple_shaft Jun 14 '11 at 11:31
    
Thanks ;-) The reason I suggest using a hash is so that no one who is sniffing traffic and/or looking at code/tables/files at your client can tell what in the world is going on. Hashes mean nothing without both sides being in on it, and the client is unlikely to grasp that the hash is actually a representation of their license key. (If it were transmitted in the clear, they would know right off.) Likewise it reduces the need to do any encryption or SSL on your blacklist file -- the hashes by themselves mean zip. –  Kerri Shotts Jun 14 '11 at 19:56
    
Side note: if you trust that the client will perceive that a restore of certain tables/files is too difficult, you can reduce the complexity quite a bit by removing the check each time the app is run. That said, it wouldn't take someone too long to figure out what is going on and figure a way around it. –  Kerri Shotts Jun 14 '11 at 19:57
1  
CheckBlacklist: license-server.example.com: no route to host Now what? The license server may not even exist sometime in the future - and don't tell me that your company will still be alive in twenty years, that is rather statistically improbable. –  Piskvor Aug 11 '11 at 15:46
1  
There's a lot of ways to get around this, including not using your own servers. Use Amazon or Google or something like that. Alternatively, build in "trust" to the check so that if the host is dead users can continue to use the app. As I mentioned in the post, there's a million ways it can fail, and is really why I'm against this kind of checking. I'd rather trust my customers than come up with this kind of check. (A license key on its own, I'll go for. But blacklisting it? Not worth the effort, IMO.) –  Kerri Shotts Aug 11 '11 at 21:54

(Disclosure - I work for Agilis Software, a provider of license manager systems).

The most effective solution is to use automated product activation with a license lease. Out of the box this allows you to:

  • Automatically activate the customer's license(s). At activation time each instance is automatically locked to your chosen parameters of the target system, and the license limits you set up for them will be enforced on your application( e.g. configuring features, setting an overall trial or subscription time limit).
  • Set a 'lease interval', which is the maximum validity period of any one activation event. For customers with suspect credit you can set this to, say two weeks, which means every two weeks your app will automatically 'phone home' in the background to revalidate the license. If they are overdue on payment you can disable their license in the hosted server and it will stop running on the next phone home.
  • If there is not a network connection from the target system there is a user self-service activation process via exchange of encrypted files at any web terminal. If your user is in this position then you may want to make the lease interval longer to balance the inconvenience to them with your need to get paid. Once they pay you can make the lease interval as long as you like, up to perpetual.

Hope this helps,

Dominic

Agilis Software

share|improve this answer

Given that the system is hosted internally, many of the solutions mentioned above involving communicating with a remote server may not work.

Why not instead include a license file within the project that includes an expiry date. Once the system clock exceeds the expiry date, the system ceases to function. To secure the file, encrypt the contents to prevent tampering. When the user does pay, or renews for an extra year, you send them a new license file.

Note that if you are using PHP, the code is readily available for the user to edit, so no matter what kind of security you put in place, the user can easily go in and remove it. If you are using ASP.NET or some other compiled language, this is not a concern as the code cannot be modified.

share|improve this answer
    
This is a good suggestion but it is a packaged and deployed Java application. Giving them a new license file means trusting them to either insert it correctly into the WAR file or giving them an entirely new WAR file which would be annoying for everybody. They have mountains of paperwork and multiple IT people who need to justify their existence within their organization by getting involved whenever there is a new release of a third party application. I am not downplaying your suggestion just that it might be the least offensive suggestion. –  maple_shaft Jun 14 '11 at 11:17
    
I guess even with most compiled languages like java a jar can be easily de compiled, updated , recompiled and then included into the war , so how does one handle that ? –  Sudarshan Mar 26 '13 at 15:18

The other answers have already done a good job of covering the technical side. But please also consider the legal side.

Do you even have a right to block their app if they do not pay? If you did not mention this up front in the contract, you may not have the right to do it, even if payments lapse (like you are not necessarily entitled to repossess something you sold). Also, many countries have special laws forbidding "manipulation of computer programs" - what you do might be considered as such and could even expose you to criminal liability.

So I'd advise to discuss this with a lawyer first, to avoid getting yourself into hot water.

In the end, it might be better to just rely on the legal system. If they don't pay, negotiate, and if that doesnt help, just sue. In many countries, suing is relatively painless & cheap if the contract situation is clear (in Germany e.g. you can get a Mahnbescheid for less than 20 €).

share|improve this answer
    
This sort of ties into answering my question about if we are nuts. I got the distinct impression though that I have no choice and this is something my superiors are insistent on even though it is not in the contract. Unfortunately I live and work in the US where you can't take on a big corporation even if you are right. They have armies of lawyers that will bury everything in paperwork long enough to put us out of business if they really wanted to. –  maple_shaft Jun 14 '11 at 11:11
    
I agree with @sleske on using legal channels. Make sure the contract is sound, and then sue them if they violate the terms. Or at least threaten to sue. In what I've seen of large companies, they are very willing to pay vendors to avoid being sued or being in violation of a contract. –  RationalGeek Jun 14 '11 at 12:16
    
@maple_shaft: No idea about the legal situation in the US, but I hope the legal situation is not as hopeless as you paint it. Anyway, if you were told to implement this, I'd just point out the potential problems. If you still get the go-ahead (in writing, of course) you have done all you can. –  sleske Jun 14 '11 at 15:25

If they're hosting internally, how is this different from any other software you might ship them? Figure out what you'd do if you were shipping, say, a desktop inventory display application, and do that.

share|improve this answer
    
I guess I am just confused about what to do in general. I imagine that the application should do a nightly check against its license key by sending a request to an external webserver with the license number. The response will be a success or failure and will be stored in an application context level variable. The application will essentially "turn off" if the license key is not valid. In this way we can simply "invalidate" this license number if needed. –  maple_shaft Jun 14 '11 at 0:27
    
Do you think that this simple license authentication page should be SSL encrypted? Even if someone were to implement a packet sniffer and could derive a valid license number, they would need to have a distributed copy of the application for it be useful, and even then it is very purpose built. I can't imagine it being useful to anybody other than my direct client. –  maple_shaft Jun 14 '11 at 0:30

It depends on the system. Did you extend an existing framework like Magneto or did you write a whole application from scratch? If it is the later, building in a licensing requirement isn't too hard. You just deliver the application with a short term license, one that expires 45-days after you bill and then give a permanent one later.

This assumes that you aren't turning over the source as well. :)

share|improve this answer
    
We are not turning over the source. We will control the source code and distribute regular releases and bug fixes when needed. –  maple_shaft Jun 14 '11 at 0:19
1  
@maple_shaft: Well, there's always the possibility of just refusing to issue any fixes or updates until the bill has been paid, as I suspect the maintenance is built in to either the initial purchase or sold as an ongoing thing, with regular payment dates (usually, but not always, annual). –  Vatine Jun 14 '11 at 9:46
    
To follow up on @Vatine, For previous projects that lacked strong licensing, we have used defects as a leverage point to extract payment. Some of the defects may not have been complete accidents. –  Christopher Bibbs Jun 14 '11 at 12:17
    
@maple_shaft - If you only have a single client. The solution is simple. Do not provide updates to said program unless their balance is $0. –  Ramhound Jul 19 '11 at 17:34

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.