15

The default ServerManagedPolicy that Google provides in their License Verification Library relies on the server responses to determine the license revalidation interval. This results in requiring a revalidation every few days, in perpetuity. This is not only a nuisance to users, it can be a serious problem for users who go extended periods with no connectivity. (We just had an inquiry from a user who expects to be without Internet connectivity for several weeks, which is what motivates this question.)

In summary, I'm looking for an algorithm that will accomplish two things:

  1. drastically reduce the connectivity requirements compared to ServerManagedPolicy;
  2. provide the same level of anti-piracy protection.

In an answer to this question the suggested policy algorithm is to ignore the times provided in the response from Google's server and instead to use a LICENSED expiration period of about a month, with license checks being attempted every few days (to extend the expiration period if a LICENSED response is received).

While this approach partially addresses the first goal, it still requires users to be connected once a month while using the app, so it would not work for (at least one of) our users.

The following algorithm accomplishes the first goal, but I don't know about the second. Any comments pointing out weaknesses of this algorithm, or suggestions for another approach, would be welcome.

  1. On first run, do a license check and insist on a LICENSED response before providing full functionality. Once received, set a relatively short expiration period (but longer than the refund period that Google Play provides, currently 15 minutes). Also register a grace period of a few days beyond that.
  2. The app would start checking again after the license expiration period. If it failed to connect (airplane mode, etc.), it would still function until the expiration of the grace period.
  3. After expiration of the grace period, insist on a second LICENSED response before allowing normal app functioning.
  4. After receiving the second LICENSED response, permanently enable all features of the app and never bother checking again.
  5. If an UNLICENSED response is received at any point, permanently disable full functionality. (The user can, of course, revert to step 1 by deleting all app data.)

Additional points:

  • A suggestion was made to forgo the first license check and wait until the expiration of the return period before doing a license check. The purpose of insisting on the first LICENSED response is to prevent the exploit where, after a license check fails, the user simply stops the app process, clears the app data, and restarts the app. (The app provides value even if usable for only 15 minutes at a time.)
  • The purpose of insisting on a second LICENSED response is to get around the buy-run-backup-return-restore exploit.
  • I'm not asking whether call-back license checking is a good idea or not (that's what Google offers in place of their deprecated copy protection mechanism). I'm also well aware that no anti-piracy protection is foolproof and Google's entire licensing mechanism can be circumvented (in which case all questions about design of a policy algorithm are irrelevant). The main point of this question is the relative risks (to us) and benefits (to the user) of the above algorithm as compared to other policies (such as the ServerManagedPolicy).
Machavity
  • 30,841
  • 27
  • 92
  • 100
Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • The "invisible" transition from "purchased, still requires verification" to "purchased, no more verification required" has issues. You need to reflect that somewhere in your app, if only in some settings dialog. (License: provisional somewhere, that if clicked after the "return window" closes forces a check *right then*, generating an error message if it is "too soon" to get a perpetual license. Once verified the 2nd time (automatic, or manually), becomes License: perpetual.) – Yakk - Adam Nevraumont Jun 18 '15 at 21:21
  • @Yakk - I'm not sure what issue you are seeing. Is it that the user needs to be offered control over the timing of the second check? – Ted Hopp Jun 18 '15 at 21:30
  • 1
    So someone buys your product, knowing that it "works offline". They then download it, run it, it works. Next, they lose connectivity (no data, wifi off for whatever reason). 3 days later, their app stops working, with little diagnostic. The point is to be able to say "The app works offline *once it says perpetual license*". It is (apparently) an important state-change for your customers: making that state change visible to the customers is important then. – Yakk - Adam Nevraumont Jun 19 '15 at 01:13
  • @Yakk - Ah, I see your point. The customer experience is paramount, so this policy still needs some tweaking. It's been three years since I asked this question and we actually adopted a variation where basically the customer never sees anything untoward unless the app gets a definite NOT_LICENSED (or similar) response. In particular, after the first license check, an inability to communicate with the server never impacts the user. This is vulnerable to an "always run this app off-line" exploit, but due to the nature of our app, we find this an acceptable risk. – Ted Hopp Jun 19 '15 at 01:53
  • I would suggest that instead of 'permanently disable all functionality' you should just issue a popup that insists on payment and registration. Your objective isn't really to prevent use, it is to collect revenue. – user207421 Jun 21 '15 at 03:56
  • @EJP - Yes, that obviously makes sense and I didn't really mean "permanently disable". After all, the job of the policy class is simply to report a binary result: allow or deny. In the case of deny, it's up to the rest of the app to decide how to present the news to the user. (Running in a demo mode is an obvious choice.) However, there does need to be provision for repeating the request to Google's server if the user goes ahead and makes a payment. The policy should never simply rely on a previous NOT_LICENSED response (unless Google's server cannot be reached). – Ted Hopp Jun 21 '15 at 19:54

1 Answers1

5

In regards to piracy, there's always going to be a risk, nothing you do will prevent it completely.

As opposed to other risks, you risk upsetting your customers with an app they can't use.

I would expect a lot of 0* reviews from unhappy customers who can't even use an application they paid for as it's been disabled, whereas the people who got the app for free will likely have no interruptions. It's like buying a dvd and getting your face full of copyright warnings, when the pirates receive uninterrupted viewing.

I would insist on a licensed response when purchasing the app, and not bother with the second response. If someone can find their way around one response, they will find their away around the second.

Edit: I agree with kcoppock that a licensed check 20 minutes after purchasing would cause the least interference to customers and avoid the refund bug you've mentioned

Alex
  • 1,018
  • 1
  • 11
  • 21
  • 2
    A one-shot approval is subject to a very easy and well-known exploit: 1) buy the app; 2) run it and get a LICENSED response; 3) back up your device; 4) return the app (within the 15 minute refund window); 5) restore your app from the backup. Voilà -- an unpurchased app that thinks it is licensed. To prevent this, there has to be at least one license check after the return window has closed. I should add that the question is whether the proposed policy has more piracy or other risks than the default policy that comes with LVL (which requires checks every few days, forever). – Ted Hopp Jul 27 '12 at 18:47
  • 1
    Why not just delay the licensing check (allowing full functionality) for ~20 minutes after the first launch? Then you're outside of the return window. – Kevin Coppock Jul 27 '12 at 19:49
  • @kcoppock - Yes, that's probably a good idea. It's consistent with the recommendations posted [here](http://www.androidpolice.com/2010/08/24/response-to-a-response-more-on-googles-android-licensing-service/). The real question is, does relying on a single LICENSED response delivered after the expiration period expose us to any more risk than, for instance, the default behavior of `ServerManagedPolicy`. – Ted Hopp Jul 27 '12 at 20:08
  • 1
    Realistically, I have to agree with @Alex -- people who want to pirate will pirate, and goign to extremes to protect against it is only going to aggravate your paying customers. I have no knowledge of the ServerManagedPolicy, so I can't say anything for comparison, but once you've got one licensed response from a post-refund window timeframe, I'd just let it go at that point. – Kevin Coppock Jul 27 '12 at 20:22
  • @kcoppock - I'm not asking about going to extremes. I'm asking about what additional piracy risks we are exposing ourselves to if we _relax_ protections from the default implementation that Google supplies with LVL. – Ted Hopp Jul 29 '12 at 03:31
  • You might be interested in reading the following blog: http://androidcracking.blogspot.co.il/search/label/antilvl and especially that post: http://androidcracking.blogspot.co.il/2011/01/anti-cracking-example.html or that one: http://androidcracking.blogspot.co.il/p/antilvl_01.html – Muzikant Jul 03 '13 at 09:02