Password Reset is one of our more unique offerings, at least from a development perspective, due to the many (and somewhat obscure) technologies that work together to perform a relatively simple task.
When initially given this assignment, I figured “how hard could it be? You can reset a password with a couple of lines of PowerShell…”. Remember that, and check out the numbers at the end of this post. ?
I won’t spend much time on the website – where it gets interesting is the Windows Login integration, which, to my knowledge, is our only product written in c++ – a language I haven’t used since my college days.
Windows 8 and 10 are fairly similar in terms of login integration – the API provided by Microsoft is robust and 100% working and the login environment is locked down and secure. We simply implement the interface they provide, drop the dll in the system folder, make a few additions to the registry, and we’re in business.
Windows 7 has the same API, but it has a critical issue that makes it unusable for all but the most simple use cases. Specifically, calls to update the UI after the initial rendering fail. In correspondence with a source at Microsoft, we were told the following:
“I looked at the code and it looks like in Win7 the pattern was to call Advise(), then do one single operation, then Unadvise() right afterward. So unless there is something that I misread in the code it does seem that the callback interface that is passed-in is not very useful in win7. I don’t see how you could respond asynchronously with that calling pattern”
So here’s what we did instead…
The Windows 7 login environment has a flaw (perhaps it is by design, but whatever it is, Windows 8 and 10 don’t have it) that allows a process with admin rights to float a window on top of the login screen. When the user clicks the password reset icon, it sends a message to a hosted service with admin rights. This hosted service then starts an application, elevates it to session 0 and displays it over the top of the login screen. This application is a simple .Net app with a minimal browser control which simply navigates to your instance of the password reset website.
It’s a little convoluted, but we’re not the only ones who do this; it’s an accepted strategy in the industry.
The fun doesn’t stop here, however. Installing on any version of Windows is tricky because the dlls and registry entries have to go invery specific places, and when we attempt to install/write to those locations, .Net literally rewrites the path under the covers depending on whether the system is 32 or 64 bit. Most of the time this is a helpful feature, but this is one instance where it isn’t.
For example, the main dll has to be copied to C:\Windows\System32\. When we attempt to copy the dll to that location in a 64-bit environment, that path is rewritten to be “C:\Windows\SysWOW64\” since it’s a 32 bit dll. Not only is it counter-intuitive, it also doesn’t work since Windows requires login integrations to be in C:\Windows\System32 and certain registry entries to be in a very specific location.
The same thing happens when writing to the C:\Program Files folder, and when writing to certain places in the registry.
All of which not only results in a failed install, but since c++ doesn’trewrite paths, retrieving registry values, writing to a log, and starting other applications are all things that break when things aren’t where they are supposed to be.
There are multiple ways of addressing this, but ultimately the easiest was using an installer called Inno Setup (written in Delphi). It allows us to copy our dlls exactly where we tell it to, and writes to the correct locations in the registry.
Inno Setup doesn’t work for a GPO deploy, so we embed that inside an msi, and the msi does a command line install of the Inno Setup package.
Here’s the promised summary for Password Reset:
Accessible in 6 different systems: Windows 7, 8 and 10; Chrome, IE, Firefox
3 Installers: website installer, GUI installer and an MSI installer for Windows integrated login
Just another example of how much we love our customers. ?
Let us know if this is of help and feel free to reach out through the Cireson Community for more tips and tricks!