views:

84

answers:

5

I'm working with a WPF/C# app where I need to lock out users from accessing a particular feature for some amount of time. Basically, from the time a certain event happens, I want to prevent certain access for the next 24 hours.

The simple case:

  • Event happens, save timestamp (using DateTime or similar)
  • User tries to access area 15 hours later, compare Now to timestamp... block
  • User tries to access area 25 hours later, compare Now to timestamp... allow

All good. However, the user has the ability to change the system time, which royally screws me. They can simply set the system time 24 hours ahead and my app will be none the wiser.

I'm assuming that changing the time in Windows makes its way to the system's real time clock... so is there any free running timer that is independent of the system clock? One that the user can't mess with?

Any insight is appreciated.

+3  A: 

Environment.TickCount doesn't change with system time changes but it resets on reboots. One option is an HTTPS secured web service and a certificate policy that does not allow certificate validation failures. Otherwise it would be pretty trivial to spoof the response from the service.

Back when I first started selling software I was very paranoid about piracy and such. Not that I'm suggesting your purposes is the same. But I came to the conclusion that people generally won't mess with their system time because it screws up so many other things on their computer that it's not worth the hassle. Naturally different applications will have different integrity requirements but I just thought I'd add this bit.

Josh Einstein
but both of those are dependent upon the user's environment. What happens at reboot (for Environment.TickCount) or if the internet is unplugged (web service)?
Stephen Wrighton
@Stephen, I specifically noted that Environment.TickCount resets on reboot. As for if the service is unavailable - if the app requires that level of integrity it should not be allowed to function offline.
Josh Einstein
+1 The important part of this answer is that not only is an external time source the only real option, but if you really want to be sure, you need to protect youself against malicious users spoofing the time service - hence the need for SSL.
Mark Seemann
@Mark, yeah I should probably point that out more clearly in my answer. Thanks.
Josh Einstein
+1  A: 

Not really. The only reliable absolute timer is an external one, under your control or the control of someone you trust, such as one of the time servers on the Internet (e.g. time.windows.com). You could access these using a NTP or SNTP library such as the one posted at http://www.codeproject.com/KB/IP/ntpclient.aspx. Of course, in this case (as per a comment to Josh's answer) you need to consider what to do if you are unable to reach the time server, e.g. the user disconnects the machine from the network.

You can use Environment.TickCount to get the time since the system started, which the user can't mess with -- but if the user or somebody else reboots the system then this will get restarted, so it's not reliable for the purpose you require.

itowlson
+1  A: 

No, there is no absolute knowledge of what time it is in Windows, how could there be? If you need a reliable timestamp, then you need to get one from a reliable location on the internet. One that the user can't mess with.

You could get the time from a Network time service, or go to www.time.gov and scrape the time out of the html that you get back. http://www.time.gov/about.html

Or just live with the few users willing to set their clock forward.

John Knoeller
+1  A: 

To get an absolute time stamp, try an NTP request to one of the (free) NIST time servers

Traveling Tech Guy
+1  A: 

Using a Windows service, you could fake an absolute elapsed time, by logging when the system time is updated.

This would require that you're able to install a service on the machine, of course, and that your users aren't clever enough to root it out.

Here's some info on trapping the WM_TIMECHANGE message in a .NET service: detecting a wm_timechange event in a .net windows service

overslacked
It may be worth noting that users can still change the time in the BIOS configuration, so, even this much work can be pretty easily circumvented.
overslacked