Meet UAC – Why you must factor out your apps’ admin components

Let’s say you have a shareware application that can do exciting things like self-registration and updating on the fly. Back in the Windows XP days, supporting scenarios like these would be a cakewalk; you could simply write a serial number to HKLM, or run an MSI downloaded off the Internet. Too bad if a user didn’t have administrative privileges on their XP machine; that wasn’t really a normal scenario anyway.

Windows Vista throws an interesting kink into the mix with UAC. Now, an application cannot write data to protected locations like Program Files or HKEY_LOCAL_MACHINE unless it has administrative privileges. Just to make matters worse, your app cannot be granted new privileges once it’s running. Let me state this again, just because I’ve found this is the part of the message that gets missed most often.

Once your process is started, it cannot be granted new privileges. It also cannot shed permissions.

This is true if you’re running as a standard user or as an administrator. It doesn’t matter. A user whose account belongs to the Administrators group still must deal with UAC just like a standard user. The two key differences are:

  1. Administrators receive a consent dialog (“are you sure you want to do this?”) as opposed to the credentials dialog standard users see (“please enter the user name and password for an account with privileges to accomplish this task”).
  2. Processes launched by an administrator with administrative privileges (i.e. launched through a UAC consent dialog) run as the same user who launched them. Administrative processes launched on behalf of a standard user (i.e. with a UAC credentials dialog in the so-called “over the shoulder” scenario) run as the administrator who launched them. This is a extremely critical point. I have mentioned it before, and will do so again, because it is REALLY IMPORTANT.

Let’s say Abby just bought a brand-new machine with Windows Vista on it. She brings it home, sets it up, transfers her data off the family’s old Windows XP machine. Abby creates an account for herself (creatively named Abby) with administrative privileges. Abby also creates an account for her teenage son, Toby. Toby gets standard user privileges and some locked-down functionality courtesy of the new parental controls in Vista. For example, Toby is not allowed to play games rated M.

Not surprisingly, Toby doesn’t like this arrangement. He really wants to play Prey, Crysis, and Halo 2. Really bad. So, being the devilishly smart cookie that he is, he convinces his mom that he really needs to have Word or Notepad, or whatever, launched for him with administrative privileges. Toby goes to the File.Open dialog, navigates to the system32 directory, right clicks on MMC, chooses Open, selects the Users and Groups snap-in, and adds his account to the administrators group. Damn, mom just got pwned.

The bottom line is that requiring a piece of software to be run with administrative privileges in such a way that a standard user can interact with it can lead to very unexpected, very deleterious effects. This is why when you write software for Vista you should make absolutely certain that only the barest minimum chunks of code run with administrative privileges. For the 95% case, your app should never require administrative privileges to perform a task. For the other 5%, stay tuned: I’ll be writing about how to factor these pieces of administrative functionality into a separate application. 

Possibly Related Posts:


February 28, 2007

My articulate girlfriend

“The frozen goober of ballpoint thing”

– Helen describing the obstruction at the end of a ballpoint pen that she was trying to remove by huffing hot air into the pen.

Possibly Related Posts:


February 27, 2007

Paved with good intentions

I’ll admit it: I made a rookie mistake when I migrated this weblog over to WordPress. I had been neglecting my blog for over a month, but even so, FeedBurner reported that I had more subscribers to my blog than ever before. I spent the better part of a day this past weekend moving all of my content to WordPress, choosing a new theme that I didn’t find abhorrent, fixing links and images, reconfiguring my FeedBurner configuration, and figuring out how to make sure my permalinks didn’t change between MT and WP (this was a pain in the ass, by the way).

Finally, the big moment came; I flipped the switch, changed a few settings, and moved my blog to WP. I was happy, ecstatic, elated, excited, and thoroughly enthused. And then Sunday’s statistics came out on FeedBurner. My traffic had halved itself. “Huh, that must be a fluke,” I told myself. “Maybe it’s just the Oscars.” Lo and behold, Monday’s statistics were no better. I started worrying a bit at this point. Did everyone hate me all of a sudden? Was I revealed for the fraud that I’m not? I couldn’t figure it out.

Just a few minutes ago, I was walking to one of the four coffee shops that function within a three block radius of my apartment (Starbucks, Ladro, Victrola, and some random hole-in-the-wall I never go to) and had an epiphany. Way back when, when I moved to FeedBurner, I had monkeyed with the .htaccess file for my blog to ensure that all traffic to my feeds was redirected to FeedBurner’s servers. Of course, when I installed WordPress I nuked said .htaccess file in the process. Oops. Rookie mistake. It never occurred to me that I would need to update it. Dumb dumb dumb. Everything’s patched up now, and should be peachy-keen. Apologies for the dumb mistake.

Possibly Related Posts:


February 27, 2007

Lightweight Development Experiences

Jeremy Jarrell raises some excellent points on his blog about the pain and suffering he goes through when trying to use Visual Studio for lightweight code editing and experimentation:

[F]or just playing with scratch code while lying in bed at night, working on my open source projects, or just plain having fun…Visual Studio seems like overkill. It does crash occasionally, it has its little quirks, and it takes forever to start up. And I have to accept that I have to sacrifice nearly all of my clock cycles and memory to the care and feeding of it. But hey, every relationship has its sacrifices…SharpDevelop, however, is super lightweight. It starts up fast, its super responsive, and…thus far…hasn’t crashed on me yet.

It pains me a bit to read this, since I owned the Visual Studio shell and had responsibility for a lot of these scenarios up until a month ago. Even still, I recognize where Jeremy’s coming from on this. Jeremy appears to be using Team System, which does have a lot more functionality (which means more code) than some of our other SKUs, such as Visual C# Express. Jeremy specifically mentions his love for the Object Test Bench and Immediates Window, both of which are included in VC# Express. VC# Express is really, really fast, too. It boots in something under a second on my computer at home, an Athlon 3200+ system, which only cost me about a thousand bucks when I built it over a year ago. I’m sure you could get something even better for less now.

Regarding crashes, I actually don’t see any when I use VS. It’s weird, I know, and a useless answer, to be certain, but I’ve certainly seen my fair share from other locations. If you haven’t upgraded to VS 2005 SP1, do that. If that doesn’t help, then the best advice I can give on reporting a crash in Visual Studio comes from the totally awesome Sara Ford:

If you happen to encounter a crash, please send the report to Microsoft to help us investigate.  Then let us know the crash ID number you sent in the report.  To find this information, please do the following:

1.  From Start – Run dialog, run “eventvwr.msc”
2.  Open the “Application Log” node.
3.  Look for the newest event with Source=”Microsoft Development Environment” and Event=”1–1″
4.  Open that event and you’ll see “Bucket” followed by the crash ID number we’re looking for.

Getting crash reports from our customers is helpful. Getting crash reports, plus a Microsoft Connect bug, plus the ability to follow up with you over email is invaluable.

Possibly Related Posts:


February 25, 2007

Meet UAC – Embedding Manifests in Managed Apps

Over the past few blog posts, we’ve looked into what Virtualization and run levels are all about, and learned how to create a Fusion manifest that is appropriate for inclusion on Windows Vista. When we created that Fusion manifest for Windows Vista, we never solved the problem of how to include it in your application. I gave you a hand-wavy answer about including the manifest file side-by-side with your app. This is an okay solution, but certainly not a great one. Ideally, we’d be able to embed our manifest directly into our managed exe, just like the big dogs do with their fancy native apps.

Today, we’re going to do just that. It’s actually surprisingly easy to accomplish this with Visual Studio 2005, due to the awesomeness of the managed Project system and MSBuild (not that I’m biased or anything ;-) ).

Step 1: Locate the Project in Solution Explorer that builds your executable.

Step 2: Double-click on the Properties node in Solution Explorer.

Step 3: Click on the Build Events tab in the App Designer (or Project Designer, or whatever it’s called).

Step 4: Add the following text to the Post-Build Steps:

“C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\Bin\mt.exe” -manifest “$(ProjectDir)Borealis.exe.manifest” -outputresource:$(TargetDir)Borealis.exe;#1

Clearly, you should make sure that the path to mt.exe jives with the installation location on your machine, and you should name the manifest and output executable files according to what they’re actually called for your project (hey, what’s Borealis?). But yeah, otherwise you’re done. That was pretty easy, no? Check out the screenshot below.

Virtualization Disabled

Possibly Related Posts:


February 25, 2007

Leaving a bad relationship

I finally dumped MovableType. We had a long, sordid relationship that started all the way back in 2003. I used to think that I really liked it, and even loved it at one point. We broke up under less than optimal circumstances, and I thought that I’d put it all behind me. Then, last year I came back to it. And for a while it was really good again. MovableType had changed and grown up a bit. It no longer had dirt under its fingernails, or Perl in its heart.

 But no good thing can last. MT would occasionally throw up on me and pass out, especially when dealing with huge amounts of comment spam. I mean, it’s natural that comment spam exists, and I really appreciate MT’s newest abilities to filter it out, but there was still way too much work on my part to deal with it. It seemed like MovableType was just trying to piss me off at times.

I reached my breaking point yesterday when I read a blog post that told me it could be different. I didn’t have to be snared up by MT’s freakouts or weird behavior anymore. I wouldn’t have to click on stupid infobar warnings informing me that MT really wanted to open up a scripted window, or wait for 30 seconds while spam was deleted from my comments tables.

Most importantly, there was something far more attractive that could be every MT had ever been to me. It is far easier to use, maintain, update, and upgrade. Whew, what a relief. No more MT for me :)

Possibly Related Posts:


February 24, 2007

Meet UAC – Creating a UAC Manifest

Last time, we took a dive into what virtualization on Windows Vista is all about, and examined the different run levels available to your application. Like I mentioned before, unless you know for a fact that your app should run with higher privileges, you should always make your application run under asInvoker.

Today, we’re going to look at how to create a UAC-aware Fusion manifest, in order to deliver the best User Experience possible to your customers on Windows Vista.

The manifest file itself is relatively simple: it’s a blob of XML that sits either side-by-side or embedded within your executable. Back in the Windows XP timeframe, there were two ways to give your application Windows XP visual styles. The first was to call the method EnableVisualStyles() on the Application() class in your Main() method. The second was to create a Fusion manifest:

  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <assembly xmlns="urn:schemas-microsoft-com:asm.v1"
            manifestVersion="1.0">
  <assemblyIdentity
      version="Insert Your Exact Version Number Here"
      processorArchitecture="X86"
      name="Name of Application"
      type="win32"
  />
  <description>Description of Application</description>
  <dependency>
      <dependentAssembly>
          <assemblyIdentity
              type="win32"
              name="Microsoft.Windows.Common-Controls"
              version="6.0.0.0"
              processorArchitecture="X86"
              publicKeyToken="6595b64144ccf1df"
              language="*"
          />
      </dependentAssembly>
  </dependency>
  </assembly>

When Windows Vista came along, the simplest way for the UAC team to correctly support various runlevels was by overloading the functionality provided by a Fusion manifest to provide this extra information. You can specify the desired runlevel for your application by adding an extra bit of goop to your application’s manifest. If your app doesn’t have one yet, don’t fret! We’ll handle that, too.

UAC information specified within a Fusion manifest looks like the following:

    <!-- Identify the application security requirements. -->
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
      <security>
        <requestedPrivileges>
          <requestedExecutionLevel
            level="asInvoker"
            uiAccess="false"/>
        </requestedPrivileges>
      </security>
    </trustInfo>
  </assembly>

There are two key elements specified within the requestedExecutionLevel:

  • level – This is the runlevel we explored last time. Unless you have a very good reason not to, you should always specify asInvoker here.
  • uiAccess – Set this to “false” unless you know exactly why you require UI access. Essentially, this parameter specifies whether or not your application requires the ability to drive UI input into other apps. Examples of apps in this class would include assistive technologies like screen readers or automated UI testing frameworks.

The full Fusion manifest updated for Vista will look like this:

  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <assemblyIdentity
        version="1.0.0.0"
        processorArchitecture="X86"
        name="ChimpSoftware.Borealis"
        type="win32"
      />
    <description>Chimp Software Borealis</description>
    <dependency>
      <dependentAssembly>
        <assemblyIdentity
            type="win32"
            name="Microsoft.Windows.Common-Controls"
            version="6.0.0.0"
            processorArchitecture="*"
            publicKeyToken="6595b64144ccf1df"
            language="*"
          />
      </dependentAssembly>
    </dependency>

    <!-- Identify the application security requirements. -->
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
      <security>
        <requestedPrivileges>
          <requestedExecutionLevel
            level="asInvoker"
            uiAccess="false"/>
        </requestedPrivileges>
      </security>
    </trustInfo>
  </assembly>

Drop this text into a file named MyApplication.exe.manifest, and place it next to your executable. Clearly, MyApplication should be the name of your app. You should also replace the references to Chimp Software Borealis with references to the name of your app (gee, what’s Borealis?). Now, launch your app and then Task Manager. You should see that your application is no longer being virtualized. If you do bad things, like writing to Program Files or the Windows directory, these calls will now promptly fail. This is good, because those are bugs in your app. Go fix ‘em!

Clearly, you still need a way to bundle the manifest with your application. You could simply add the manifest to your setup application, but you’d be better off embedding the manifest directly into your application. Directions for doing this are pretty straightforward for native applications, and instructions already exist on how to do this. Trying to do this for a managed application with VS 2005 is trickier. Next time, I’ll show you how to solve this problem.

Possibly Related Posts:


February 22, 2007

Petzold on the Mac: It doesn’t just work

Charles Petzold, tha doggfather of Windows programming, published a few choice words about how Macs “just worked” back in December:

On Apple’s home page, the most important information they deemed necessary to convey to me was that I needed QuickTime 7 to view even more of those insufferable TV ads where that smug goateed glazy-eyed dork tries to make closed architecture and a complete disregard for backward compatibility seem cool.

Remember that for a large portion of your potential user base, ‘easy to use’ is still too damned hard, even if they have forgotten more about Win32 than you’ll ever know about Cocoa.

Possibly Related Posts:


February 22, 2007

Meet UAC – Understanding Virtualization and Run Levels

You’ve probably heard a lot about User Account Control (UAC) on Windows Vista already. Contrary to popular perception, it’s really not that bad, as long as the developers creating the software you use do the right thing by not trying to write or access stuff where they shouldn’t. Ensuring that your software correctly supports UAC is critical to providing your users with a great experience on Vista.

On 32-bit versions of Windows Vista, a system called virtualization is used to improve compatibility with apps that still do the wrong thing in terms of irresponsibly writing data to protected locations, such as the Windows directory, Program Files, or HKLM. Basically, virtualization silently redirects non-privileged writes to these locations to a location where the user who launched the process can write. You can see right now which of your applications are virtualized by opening Task Manager and choosing Select Columns from the View menu.

Virtualiztion in Task Manager

Virtualization is something that your software is automatically opted into on 32-bit Windows. To specifically exclude your application from being virtualized, you must include an XML manifest with your app that specifies its UAC runlevel. A runlevel consists of one of three values:

  • asInvoker – Run this process with the account and privileges of the person who launched it. You should default to choosing asInvoker, and only deviate if absolutely necessary.
  • highestAvailable – This one is kind of an odd duck. Basically, it says that this application should be run with the highest privileges available to the account that launched it. For example, let’s say you’re logged into your computer with an account that is a member of the Backup Operators group. Windows sees this, and requests that you authorize this application to be run at that privilege level. From the Ux perspective: if this app is launched by a standard user, it just runs. If the app is launched by anyone else (Administrator, Backup Operator, etc.) they will get a UAC prompt. Regedit uses highestAvailable. You shouldn’t. End of story.
  • requireAdministrator – Just like it sounds. This app is only available to people with administrative privileges. If your account has admin privs, you’re presented with a UAC consent dialog. If you don’t, then you get a UAC credentials dialog. The UAC credentials dialog requires an administrator to come along and enter their password “over the shoulder” of the person operating the computer. Here’s the funky bit: if an administrator does launch a process that is marked as requireAdministrator, that process runs as that administrator. If an application has the ability to launch other apps from within it, those will also be run with the administrator’s privilege set (likes beget likes is the rule of thumb). Be cautious, in any case. Some apps, like MMC, require administrative privileges to launch.

Whew, that was a mouthful. I still have a lot more to talk about: creating your manifest, specifying the runlevel, embedding it into your managed application with VS 2005. I’ll be along with a follow-up soon to answer all of these questions.

In the mean time, I highly recommend reading the old posts on the UAC team’s blog. They have a wealth of information available, there.

Possibly Related Posts:


February 21, 2007

Where you been?

I’ve been laying low for the past month, and my posting was sporadic even before that. Part of the reason for that was the Christmas-New Years blogging deadzone. But the bulk of the reason was I changed jobs. It’s pretty common for Microsofties to switch jobs. I’ve heard numbers saying that most people move around after about a year and a half or two years. In any case, I was in my old team for quite a bit longer than that.

For the past three years and change, I was the Ux Program Manager for Visual Studio, and the PM for the team that built the Visual Studio shell (devenv.exe). I started on November 10, 2003 and left on January 26, 2007. Not a bad run. I feel like I accomplished a great deal during that time: Visual Studio 2005 won Infoworld’s award for Best IDE in 2005 due to the product’s usability and fit-and-finish; Visual Studio 2005 is reasonably well supported on Windows Vista; Orcas is off to a fantastic start, and will be a product that serves to delight and enthuse every single one of Visual Studio’s customers. And, at the end of it all, I felt like I was ready for a change.

I’ve joined a fantastic, new, and very small team run by the super-talented John Montgomery. I can’t say much of anything about what we’re doing right now, but I will as soon as I can.

Possibly Related Posts:


February 19, 2007