Solipsism Gradient

Rainer Brockerhoff’s blog

Browsing Posts in Software

So, I needed to autoresize NSTextFields in XRay II (vertically only). Sort of a poor man’s WebView. This had to “just work” on certain NSTextFields used by third-party plugins, though, without any extra code or subclassing by the plugin writer.

There are two problems there. One is finding out the actual optimum vertical size, while editing and while not, for any type of border or bezel. Here’s the code I finally worked out, with the kind help of Daniel Jalkut:

- (NSSize)minSizeForContent {
   NSRect frame = [self frame];
   NSRect newf = frame;
   NSTextView* editor = nil;
   if ((editor = (NSTextView*)[self currentEditor])) {
      newf = [[editor layoutManager] usedRectForTextContainer:[editor textContainer]];
      newf.size.height += frame.size.height-[[self cell] drawingRectForBounds:frame].size.height;
   } else {
      newf.size.height = HUGE_VALF;
      newf.size = [[self cell] cellSizeForBounds:newf];
   }
   frame.size.height = newf.size.height;
   return frame.size;
}

So I put this into a category of NSTextField and did some runtime diddling with implementation pointers, but for other uses it could well be in a subclass.

The second problem is properly pushing down the views below the field when it is resized. The solution I ended up coding is a little too gnarly to post here, and it depends on the field and its sibling views being inside a custom NSView subclass with flipped coordinates… still, it seems to work well enough now, so I’ll leave it there and work on other stuff.

Adam has posted a response on the installer authorization issue:

I don’t believe they’re even calling that function to gain root, honestly, because it follows the authorization file. It can’t not. They’re doing something else and I believe that’s a red herring here. There’s no way to call that function and have it not consult the database, so they’re doing something internal to get around it. Be that a SUID program somewhere or some private call, they’re getting around the clause in authorization that says the user needs a password.

Well, that’d be a surprise to me, but it’s not impossible. I’ll try to find some time to do a test package and some rooting (oops!) around inside the Installer before writing more about this.

Adam Knight the codepoet, whom I link to quite often from here, has an article out on Mac Geekery, ominously called “How a Malformed Installer Package Can Crack Mac OS X“:

There exists a pretty significant interface problem with the Apple Installer program such that any package requesting admin access via the AdminAuthorization key, when run in an admin user account, is given full root-level access without providing the user with a password prompt during the install. This is even explained in Apple’s Installer documentation as proper behavior. The distinction between the AdminAuthorization and RootAuthorization keys is, simply, whether or not the admin user is prompted for a password; the end powers are exactly the same and it is up to the creator of the package as to if he will be kind enough to ask for a password…

Well, at first glance this looks like a pretty serious security hole. Let’s see what that Apple documentation says about this:

This is actually quite clear. If the installer package asks for the same level of privileges that the logged-in user already has, authorization is not required; meaning, it won’t ask for a password. Which makes sense; after all, to log in as root or as an administrator you must know the root or an administrator’s password to start with – usually. If the packages needs higher privileges to do its stuff, the user will be “prompted for authorization”. This autorization will be used for two purposes: setting permissions on the installed files, and for running pre- and post-installation scripts. We’re concerned only about the second purpose. Before going into that, let me explain a few things.

First of all, using an installer package is pretty much, nowadays, a good thing only when you’re installing something that messes with the system’s folders, or that executes scripts that do restricted things. Installing a kernel extension, updating the system frameworks, setting up servers and startup/login items are common examples. It’s frightfully infra-dig to make a package just to install your application in /Applications. In other words, just the presence of an installer package on a disk image should be pretty much an indication that something uncommon will happen if you double-click it.

So, the common perception is that for an installer package to mess with the restricted system folders is that it should ask for root authorization, and therefore you’ll be asked for a password – since you’re not running as root to begin with. Or shouldn’t be; the root account comes disabled by default on Mac OS X. And since most packages do it this way, this perception is reinforced; it’s become pretty much automatic to double-click on a package, type in your administrator password at the prompt, and “boom” (can’t remember who says that icon_wink.gif).

So Adam strongly recommends:

Run as a normal user. Open files you trust. Stick to that and you’ll be fine.

Read his recommendations and follow at least some of them. I’d add: use Charles Srstka’s excellent Pacifist software to see what’s being installed, and where, before running the Installer – for one, Pacifist doesn’t run pre- and post-installation scripts contained in the package, so it’s not an Installer replacement.

The tricky part comes when the package asks for admin authorization. Mac OS X installs the first user as an administrator, and it’s required to have an administrator account present – after all, if you had none, the system would become quite unmodifiable. So, the recommended practice is to set up your system in this first account, then set up a second non-admin user account and use this for your normal activities; switch back to the admin account only when installing software.

Unfortunately, Apple seems to have found this confusing for “normal” users, and I’d tend to agree. A significant amount of explanation would have to be inserted into the setup application, especially as this not-normally-used “user” would also have a home folder where stuff would not be visible by the day-to-day user. There’s even the option of setting the machine to boot automatically into a certain user, and I’d say many non-technical users click this to speed up booting and to avoid having to remember their password every day. Unfortunately, as a side-effect of these circumstances, most users are running as an administrator without having had to type in the administrator password at all.

Now let’s suppose you get a (underhandedly malicious) installer package and double-click on it without examining its contents beforehand. You think it can’t mess up much as it will ask for a password if it does anything serious, right?

Wrong. True, it will ask for a password if it wants root authorization – but then, you’re already conditioned to type in your password anyway. But if it asks for admin authorization and you’re already running as an admin, it won’t ask for a password at all, and merrily use the admin authorization you gave it (by logging in!) to muck about with your system.

Now wait a minute. Why does this admin authorization which is not root authorization let the installer run scripts as root, as Adam proved by a test package? Isn’t that a serious bug and security hole, as he claims?

Well, yes and no. The answer lies in a file called /etc/authorization. This is an XML file in property list format which defines the various rights a process can ask for when using the Authorization Framework, and defines a set of rules that are applied when this happens. The principles involved are quite complex, and I’m still learning to understand them fully. Here’s a paragraph from that documentation:

When a user who is a member of the admin group logs on to the system, for example, the user’s credential (that is, the fact that they have entered a valid admin user name and password) is saved in the global credentials cache. Then when this user attempts to modify a system preference, Security Server finds the credential in the cache and does not display an authentication dialog.

which confirms what I said above. And later on:

Not all installers require authorization – only those that need special privileges to copy files to restricted directories, make changes to restricted files, or set setuid bits.

An installer is a special case because unlike other applications, an installer is usually run only once. Due to the limited use, Authorization Services provides a function to invoke your installer to run with root privileges. It is up to the user to determine if the installer is from a trusted source.

So far so good; but why in, practice, do admin privileges mean “run as root”? Well, in that XML file we have the following section:

      <key>system.privilege.admin</key>
      <dict>
         <key>allow-root</key>
         <true/>
         ...
         <key>group</key>
         <string>admin</string>
         <key>shared</key>
         <false/>
         <key>timeout</key>
         <integer>300</integer>
      </dict>

Translating this into a slightly less geeky form, this is the autorization right requested by the AuthorizationExecuteWithPrivileges() call, which is the one used by the Installer. It can be granted to users of the “admin” group, is granted automatically to the root user, and times out in 5 minutes. AuthorizationExecuteWithPrivileges(), in turn, is the system call to run a script as root; which is allowed for administrators, as we’ve seen.

In other words, everything is certainly “behaving as expected”; it’s not a bug, it’s a mistaken assumption: “anything that runs as root will ask for authentication when run by an admin user”. That’s certainly not true. However, I don’t deny that the Installer could be more explicit here, either not calling AuthorizationExecuteWithPrivileges() for its scripts when admin authorization is asked for (which might break some existing packages), or by showing a separate alert at the beginning, saying “this package will run its scripts as root”. Let’s suggest this to Apple and see what happens…

Re: Showtime, sorta

No comments

The codepoet has got right what I wanted to say about the iTunes 7 interface:

I do like how it looks as a finished product, but it doesn’t make me feel like I’m using a Mac at all. It looks like the new iTunes Store does, right down to the scroll bars and buttons.

The only reason for this that I can put forth is that they needed one unified interface for both Mac, Windows, and the iTS and we thus have this new concept. It’s interesting, and it’s not entirely unusable, but it’s kind of annoying to have this iconic Mac application turned into a bastion of wishy-washy cross-platform interface design, from a place of pure principle.

So, they tried to make something both Mac OS X-like and Windows XP-like, and at the same time abstract it out into a distinct iTS look. Which in turn was probably inspired by Dashboard widgets. If so, they’ve pulled it off quite well. At least in the main window; preferences and popup menus use the native UI, I suppose because users might get (more) confused.

On the other hand, this means that the new UI should not be used as a guide or inspiration for other applications. Or websites for that matter; I imagine Apple’s lawyers will be very zealous in their defense of the iTS theme/platform’s look & feel.

I just realized iTunes is slowly morphing out of being just another application; instead it’s becoming an emulator running the iTunes/Store platform. Inside a window, just like Virtual PC or Parallels. Interesting. (This paragraph actually surprised me while I watched myself typing it out icon_wink.gif.) I wonder if other hybrid desktop/web multiplatform apps will follow this course… not that I can think of any right now, hm.

Showtime, sorta

No comments

So, the big announcement is past and I wasn’t too excited.

New iPods; OK; I’m still relatively satisfied with my 3G, 40GB device. The new Shuffle looks good. Finally a price point and size suitable for jogging, although I’ll probably buy it only when it grows to 2 or 4GB. The new Nanos look less scratchable now, but still, at the price points they’ll be available here for, don’t seem to be a good value for me. The large iPods do stuff I’m not interested in, like photos and video, and I suppose that they – like my current iPod – aren’t suited, speed and reliability-wise, to be used regularly as an external drive.

Games. I very rarely play any games on my Mac these days and I’ve never owned a console, so I can’t see me playing games on an iPod either. The positive part about this is that it shows that iPods are tending towards having some sort of developer API – I wonder if these were all ported in-house or if there’ll be a PodCode announced at next WWDC.

The whole movie hoopla leaves me cold. I watch almost no TV (we don’t even have cable), rent a DVD very rarely (under 10 times a year, or less), buy no DVDs, and wouldn’t know what to do with a TiVo. I suppose it’s all big news in the USA. The iTV thingy looks like it’ll boost Apple’s stock when it comes out, so I’m for it in theory…

iTunes 7 is about the only part of all this which I’ll use soon – in fact, I already gave it a try. The new UI looks quite good. All the Aqua is gone, the exception being the “traffic light” window buttons; the rest is done in muted plastic tones. Some people are decrying this as further dilution of the increasingly varied Mac OS X interface, but I’d say this is mostly dictated by iTunes unique position as a cross-platform application that looks the same on both Mac and Windows. In fact, a quick peek into the package reveals that all the UI elements are present internally – it uses no native widgets at all.

It may be subjective, or the new QuickTime decoders may have had some bits polished, but some songs sound better now. The left-hand column looks nice, though most of the items aren’t relevant to me. The two new alternate library views are somewhat wasted on me; I deliberately erase cover pictures to save on space, and this only helped me find two albums that had slipped through. I wonder whether the pictures must still be stored inside each track, and whether they still are copied to iPods that have no cover display? If so, I’ll continue avoiding them.

Finally, the iPod control screen looks good. I’ll certainly study the whole new UI to see if I glean any ideas for XRay II…

It’s here, and about time. Hopefully I’ve fixed all known bugs and incorporated most reasonable suggestions…

…now back to XRay II. icon_wink.gif

Well, I’ve received a number of e-mails and comments about Nudge’s new “touch” behavior; some like it, some want it to go back to the old standard.

I’ll probably release a 1.1.1 version that switches from one to the other by using the Option key. However, what should be the default? I tend towards doing “Nudge & Touch” as the default, myself…

The Nudge Contextual Menu is now universal, with version 1.1. This will work on both PowerPC and Intel Macs under Tiger. It now also changes the nudged item’s access and modification timestamps, like the Unix command “touch”… this may be useful even for local items. Since Tiger, the Finder is much more responsive in updating changed items on local volumes, but still may lag behind for network volumes.

Photos licensed by Creative Commons license. Unless otherwise noted, content © 2002-2024 by Rainer Brockerhoff. Iravan child theme by Rainer Brockerhoff, based on Arjuna-X, a WordPress Theme by SRS Solutions. jQuery UI based on Aristo.