Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2008-393
$eventId
ID of event: wwdc2008
$eventContentId
ID of session without event part: 393
$eventShortId
Shortened ID of event: wwdc08
$year
Year of session: 2008
$extension
Extension of original filename: m4v
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: [2008] [Session 393] Managing Us...

WWDC08 • Session 393

Managing User Privileges and Operations with Authorization Services

Essentials • 54:39

Discover how Authorization Services facilitates control of privileged operations, such as accessing restricted areas of Mac OS X and self-restricted parts of your application. Learn how to factor your application to perform privileged operations securely and how to use authentication and authorization plug-ins to customize your application's user experience for these operations.

Speaker: Gary Hoo

Unlisted on Apple Developer site

Downloads from Apple

SD Video (474.6 MB)

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Well, good morning. I hope you can hear me. My name is Gary Hoo. I'm a software engineer with the data security group at Apple Computer, and I'm going to be talking to you about the Authorization Services subsystem today. Now, before I get into the actual content of the slides, I should perhaps issue the requisite caveat that Authorization Services is a Mac OS X technology. It is, in particular, not an iPhone technology. So if you are looking for something directly applicable to the iPhone, this perhaps is not quite the right session.

However, if you are going to be developing for the iPhone on Mac OS X, you might want to stay for a while. I'm going to be talking about the Authorization Services subsystem today. I'm going to be talking about what Authorization Services is and why perhaps you ought to consider using it. I'll be going over some fundamental concepts of Authorization Services and I'll be going through an example of the use of the APIs.

Authorization Services is fundamentally a policy subsystem that answers the question, can this user perform this particular action? Now, Authorization Services, by virtue of its evolution, has had to be extensible, it's had to be customizable, and it has very definitely had to be GUI-friendly. Because a lot of the time you're entering a password as part of authorization. Now, in case you were wondering whether we actually use authorization services in-house, well, we've managed to sneak it into a few corners here and there.

Now, for some reason, this panel got a little shrunk on my copy of the slides. I don't know how it looks out there. But if you've never seen this before because perhaps you have auto-login turned on, this is the login panel that you see when you first log into Mac OS X.

And this is quite literally a side effect of an application-making and authorization services API call. You type in your password, your name and your password in this case, and authorization services in the background does a whole host of interesting and potentially dangerous things on your behalf as part of login. And then once your name and password have been validated, login proceeds, desktop shows up, finder starts, all the rest of that good stuff. But what you see right here is you're right in the middle of an authorization services call. All right.

So, why use it? Well, as you can see, it does tend to save you a little bit of work because you can leverage Mac OS X frameworks and user interface. Granted, you're probably not going to be reusing the login panel for anything, but there is other UI in there that you will almost certainly be using.

Also, if your system administrator at your site decides, or your customer site decides, to swap in a new authentication mechanism, for example, he decides that names and passwords are no longer fashionable, it's now time to go to fingerprint readers or to retinal scanners or to blood samplers or something else, your application does not have to change.

And if that system administrator decides that the retinal scanner is no longer a good idea, he wants to go back to names and passwords, or he wants to move to smart cards or something else, again, your application just does not change. Which brings me to the second point, which is Authorization Services makes less work for your customers because they don't have to rev your application if they change their security policy. They can customize policy for the entire system, not on a per-application basis. It makes their lives much easier.

Authorization Services also tends to encourage you to factor your code into pieces that can run with privilege and pieces that do not have to. I'll go over what that means in greater detail a little bit later. Authorization Services also supplements the venerable Unix permissions model. Now, for those of you for whom that may be not as familiar, perhaps, Unix permissions basically subdivides the world into three groups. The user, or the owner, of a file or process.

One single group associated with a file or process and then everybody else in the rest of the world. And this works great for a number of things, but it's a little difficult for that kind of model to address, gee, I'd like group A and group B to be able to administer the printer, for instance.

And again, as you saw before with the login example, Authorization Services also allows you to extend policy to include various complex tests, user interface, associated actions. So one thing that we have baked into OS X right now is what do you do if an application needs to add something to your default keychain and your default keychain isn't there? Oh, keychain, by the way, for those of you new to OS X, is basically a bag in which we encourage users to place passwords, private keys, other sensitive information. Every user by default is given a default keychain, but something can happen to that default keychain. The user may accidentally delete it.

Various bad things can happen to it. And so any time an application wants to use the default keychain for something, and if it can't find it, what happens kind of silently and transparently in the background as far as that application is concerned is the system says, oh, there doesn't seem to be a default keychain here, so let me put up a user interface that asks, there's no default keychain.

Would you like me to reset your default keychain for you? If the user says yes, the user is then prompted via further user interface for a password to protect that keychain. And if a password is provided, then the reset keychain operation proceeds. This is all a side effect of authorization, and that authorization in turn is a side effect of applications simply wanting to use the default keychain and not finding it there.

So some fundamental concepts that I want to go over before I get into the actual authorization APIs. First, I want to clear up that authorization and authentication are two distinct concepts. Second, I want to talk about factors. I want to talk about why it's a good idea, and then I'll go into some concepts of authorization that you need to know, as well as a few system processes and files that conspire to provide the authorization subsystem.

So, authorization is not authentication. That's something to get clear right now. And that's because in the literature, if you ever read security literature, which is a great way to put yourself to sleep at night, by the way, but let's not go there, you will notice that these two terms have very specific and precise meanings. Authentication is simply verification of the user's identity.

Authorization, however, asks the question, assuming we can authenticate this user, what can this user do? So authorization might require authentication. There's at least one example, by the way, on OS X where it doesn't, and that's when your DVD player has been set to some particular region because it got set that way when you first inserted a DVD with a region code into your system.

You insert another DVD into your system with a different region code, and because you can only reset that region code a certain number of times, OS X detects this and says, well, you know, we certainly don't want to reset the region code out from underneath the user without at least giving him a chance to object so he doesn't burn through his N number of resets and then suddenly find himself locked on a region 4 DVD player when he's really living in region 1.

So there all we do is pop up a dialog that says, do you want to reset the region or something to that effect? And there is no authentication required. You just click yes or no. But most of the time, authorization does require authentication, and in fact, it might dictate the form of that authentication.

So now on to code factoring. Essentially what this means is dividing up your code into that part of the code that has to do something privileged, that is to say it needs to run as the root user, and all the rest of it, which is generally the much greater part of your code, which doesn't need to run as root.

Now, running as Root in one big application is enormously tempting because it means you don't actually have to change a line of code that you've written. However, Root is virtually unchecked on OS X and, in fact, on most Unix systems. There is great potential for Root to do good and, therefore, correspondingly great potential for Root to do not good. Therefore, running as Root requires self-restraint, and factoring your code forces you to implement that self-restraint.

Now, minimizing the amount of privileged code means that you minimize the amount of source code that you have to audit to make sure that that code is not doing particularly silly things, dangerous things. It's not calling bad APIs. It also tends to minimize the amount of external linkage that you have, external libraries and frameworks that you've got to link into your code. And all that does tend to minimize is unexpected interactions and side effects. The less there is, the less can go wrong in general. There are always exceptions.

Okay, now to some fundamental concepts of authorization. I'm going to go over each of these in turn. What is a right? What is a rule? The policy database, the system processes that actually conspire to implement authorization. I'm going to talk about some ancillary data that we call hints and context, and also plug-ins and mechanisms, which is how you extend the functionality of authorization. organization.

So a right is a pretty fundamental concept, and it's a pretty basic one. It's not hard to grasp. It just identifies a privileged operation. And as such, it has some condition or conditions that have to be met before that right can be granted. Now, as far as the names of rights go, we do have a convention that says it ought to be something along the lines of com, company, application, right. However-- The way you name your write is pretty much up to you. And as long as you avoid a couple of restricted Mac OS X-specific write hierarchy names, it's up to you how you want to name what you're doing.

Now, because of the way that we structure write names with dots between various significant pieces, we can support the concept of a wildcard write, which is simply one whose name ends in a dot. If a specific right that's requested by an application can't be matched exactly by name, then the system starts stripping off pieces of that name in order to see if it will match a prefix, that is to say a wildcard right within the system. And if it does, then whatever conditions, whatever rules are associated with that right apply to the one that the application is requesting. So wildcards are a way to create a set of rights. to which all the same rules apply.

Now, those reserved name hierarchies I mentioned earlier are SystemDot and ConfigDot. These are both used by Mac OS X. ConfigDot in particular is used by the authorization subsystem itself in order to manage changes to the authorization subsystem. So if you're an application developer and you want to start naming your rights, please avoid anything in the SystemDot and ConfigDot hierarchies.

So a rule, a condition that has to be met in order to grant a right, very basic concept. Now there are several different-- concepts that I want to go over. Actually, there's only two. All right. There's the concept of rule class, and there are some rule properties that tend to apply to multiple classes of rules.

All right, now, these rule classes, there are three of them that are essentially true classes of rules. That's user evaluate mechanisms and the so-called delegation rule. And then there are a couple of singleton rule classes, allow and deny. And allow just says, yes. If the rule granting your right is allowed, then your right is always granted. And if the rule covering your right is denied, then that rule can never be granted.

The default rule I'll go over shortly. It's basically the rule that gets applied if no other particular rule has been specified for the requested write. So, first rule class, the user rule class. This essentially is a shorthand for user in group. Now, the group is typically admin, but it certainly doesn't have to be. There are already instances in Leopard of groups that are not admin that still are used to grant particular rights baked into the system.

A special instance of a user rule is the session owner. The session owner is the current user that is logged in at this particular console or via this particular SSH login. And as long as I'm mentioning sessions, I might as well clarify that a login session is its own domain as far as authorization services go. And in particular, a write granted in one login session is not automatically granted in any other login session.

So the fact that you authorized for a particular write logged in at the console does not mean that your SSH login into the same system has acquired that write and vice versa. That's actually kind of important to know when you're writing applications and as users of the system.

The Evaluate Mechanisms class is how you extend authorization functionality. A mechanism is a chunk of code that just operates on or acquires authentication data. And as such, a mechanism can put up UI, it can have side effects on the system, it can pass data to other mechanisms that execute subsequent to it, and these mechanisms can run as root or not. They don't have to run as root. Mechanisms, for convenience's sake, live in plug-ins, and I'll be going over plug-ins and mechanisms in greater detail in a little bit.

So here's an example of an evaluate mechanisms rule. The write in question is system.shutdown. This write is invoked whenever you try and shut down the system or restart the system. And there are users logged in in the background via fast user switching. There is a plug-in called Restart Authorization. It's a standard plug-in that ships with the system, and it has at least three mechanisms associated with it.

It has Shut down, authenticate, and success. And these mechanisms each perform a different role. One of them puts up UI and the others actually evaluate the results of that UI when you type in an administrator's name and password and actually give clearance to shut down the system or to restart the system.

The Delegation Rule allows you to use one or more built-in rules on the system. There is a rules dictionary that lives in the policy database that defines all the built-in rules available on the system. And there is something called the K of N property that can apply to delegation rules, and that allows a subset of rules to grant right.

And we've got an example of such a rule right now. And in particular, you see that K of N is 1 here. N is 3. There are three possible built-in rules that actually can apply to this right. Is LP admin, is admin, and the default rule. However, since K of N is 1, only one of those rules has to be satisfied in order for this right to be granted, in order for you to be able to administer printers.

Which brings me to the default rule. Again, it's used if no other rule is specified for a write or, as seen in the previous example, it can also be used explicitly. Now, the default rule requires you to authenticate as an admin, and the credential that gets generated by successfully authenticating has a five-minute timeout, and that credential can be shared by any other process within the same login session.

So a few rule properties, some of which we've seen before. Authenticate user is a Boolean property that simply says, can we throw up user interface to the user if it's necessary? If it's true, then you'll see dialogues. If it's not true, then no dialogues can be displayed, and your rule had better succeed on its own.

The session owner property we already discussed. Again, that's the user that's currently logged in on that login session. The shared property simply means whether that credential can be used by other processes in the same login session. And the timeout, again, we already saw. The only detail here to notice is that it is specified in seconds in the policy database. You can specify also a zero timeout, which means the credential is essentially invalid pretty much as soon as it's been created. And an infinite timeout is also possible. It's not technically infinite, but it will probably be long enough for your purposes.

The policy database is where all the rights and rules currently available on the system are listed. It's not actually technically true that it lists all possible rights. Applications can request any right they like. If a right is not matched in the policy database, the default rule will automatically be applied to that right.

The policy database is a flat file. It's ETSI authorization. It is currently plain text. You can edit it with your favorite text editor and sudo, but we do not guarantee that the format of that file will not change going forward. We've been kicking around the idea for some time of changing the format of that file. Naturally, if we do, we'll give plenty of notice.

Now, as far as the system processes that actually implement authorization, there are three of them. At the heart of authorization is Security D, the security demon. Starts at startup, at boot time, runs until your system is shut down again, and Security D is where the actual authorization policy engine lives.

SecurityD, however, does not do user interfaces. It does not link against AppKit. It will never show dialogues, at least not as long as the current maintainer is maintaining it. So if SecurityD, or more appropriately, the policy engine within SecurityD determines that user interface is necessary, SecurityD has to spin off a security agent process to handle that user interface.

Security Agent literally is Security D's user interface agent that is its sole purpose in life. When it acquires information from the user, it passes it back to Security D, and Security D uses it for whatever purposes. In the case of authorization, the policy engine takes in usually names and passwords and crunches them to make sure that, in fact, the names and passwords are correct.

Now, there is one case also where SecurityD needs to spin off another agent process, and that is when it has to run, as part of authorization, a plug-in mechanism. We decided a while ago that running plug-ins within SecurityD was not a good idea, and so we created the Authorization Host process, which runs root running, that is to say, privileged plug-in mechanisms. That is Authorization Host's sole role in life.

So a typical request here starts off with a client application making its authorization request to SecurityD. I'm not good enough with Keynote to show a spinning arrow inside SecurityD, but that would basically be the policy engine going over whatever rules apply to the right that the client is requesting. Now, let's assume for a moment that the client is requesting a right that requires user interaction of some sort. Then SecurityD, if a security agent process is not already running, will start a security agent process.

And the graphics people lied to me that text was not supposed to be truncated like that. Sorry. So Security Agent process gets launched and SecurityD makes its request to Security Agent to acquire the appropriate or to display the appropriate user interface and to acquire whatever information it deems necessary from the user.

That information is returned to SecurityD, policy engine crunches some more, and determines that, oh, well, a route running mechanism needs to be run. Again, if... An authorization host process is not already running. One is spun off. SecurityD makes its request to Authorization Host to run a particular mechanism. Authorization Host runs that mechanism, sends its return to SecurityD.

This process of calling into Security Agent and Authorization Host from SecurityD and getting back results can happen an arbitrary number of times for any given write. But eventually, SecurityD decides, or the policy engine within SecurityD decides, yes or no as far as do we grant or deny this requested write, and a response is sent back to the client.

So, ancillary information can be provided by either the client or provided by the authorization subsystem itself in the course of evaluating a set of rules. This ancillary information, if it's provided by the client or provided pre-evaluation, is called, or we call them hints. Now, in the APIs for authorization, you'll see those as the authorization environment that gets passed into the API calls.

It's basically input to assist authorization, and one common piece of input is the administrator's name in a dialog. If the user happens to be logged in as an administrator and an administrator's name and password is required for a given rule, then the administrator's name will be in dialog. the dialogue when it pops up.

Now the one thing about hints is that they are not preserved after evaluation. The assumption is they don't have to be. They were just Little crutches, little bits of assistance to authorization, not strictly necessary. Context, however, is necessary. Context consists of byproducts of policy evaluation. Context may or may not be available to the caller. There are certain things that you might not want the caller to be able to see, for example, perhaps the user's password.

It's worth noting that the authorization subsystem helps to ensure that client processes never need to actually see the user's password unless they actually need to do something with that user's password. If all that the application needs is for the user to authenticate, the application never needs that password, and authorization ensures that the application does not get the password. This ancillary information, both hints and context, is all managed by the Policy Engine.

So how do you go about extending authorization's functionality? You write a plug-in and a set of mechanisms. Now these tend to be very application specific. Now, all a plug-in is is a bundle of mechanisms, quite literally a CFBundle. Application-specific mechanisms can be installed in /library/security/securityagent plug-ins. You do have to be an admin to write into that directory.

The naming convention is plugin.bundle, where plugin is whatever plugin name you decide. We saw an example of one earlier, the restart authorization bundle. That's a system bundle that lives in a slightly different location, but it gives you the flavor of application-specific bundles. Now, in ETSI authorization, in order to use a bundle, in order to use a plug-in and a set of mechanisms, you have to specify as part of the evaluate mechanisms class the name of your plug-in, along with the mechanism name.

Now, if the mechanism name has a comma privileged following it, that means that that mechanism is intended to be executed within the context of authorization host. That is to say, it's going to run as root. Now, there is one reserved plug-in name. Please do not use the plug-in name built in. That is, naturally enough, what we use internally to Mac OS X. You may get some interesting misbehavior if you decide to try to use that for your own mechanisms.

Now, the plug-in lifecycle. Plug-ins essentially are the way that mechanisms talk to the policy engine. Plug-ins manage mechanisms. So plug-ins, once they're instantiated, their main role in life is to stage mechanisms, to control the mechanism lifecycle. Mechanisms themselves have four major stages in life: creation, invocation, deactivation, and destruction.

Now, there are a few places where mechanisms interact directly with the policy engine. One of them is the getting and setting of hints and context. Another is actually setting the evaluation result. So when a mechanism runs, it's got to say whether it allowed or denied or whether the user canceled, potentially.

Now, mechanisms can also interrupt evaluation. This is something that bears some attention. Mechanism interruption can happen if something about the system changes, such that you might want to restart this entire authorization evaluation. Now, currently in Mac OS X, there's one place where I know of that that specifically occurs, and that is if your system is configured to permit smart card login, and somebody actually plugs a smart card into the system.

Now, if the system is sitting at the login prompt or the login panel, then suddenly it doesn't make any sense for the user to type in a name and a password anymore. If the smart card has been plugged in, then what the user needs to do is to type in a PIN.

Now, we've decided that we need to display a different user interface in that case. So when somebody plugs a smart card into such a system, the user interface changes. That actually is a side effect of an interrupt being sent to the entire mechanism chain for login and evaluation of that mechanism chain restarting, only this time there's a little bit of information in the context that says, hey, there's a smart card present. Therefore, different user interface is displayed.

So that's one case where I know where interrupt evaluation is necessary. And finally, because mechanisms can be interrupted, They need to confirm that they have actually deactivated themselves if they happen to be running when an interrupt occurs. And that way, the policy engine knows that it's safe to go and restart the evaluation.

Now, one particular plug-in that might be of interest to you is one called the SF Authorization Plug-in View. It's essentially our attempt to provide developers with a base for custom user interface. It adds a special view, an application-specific view, to authentication dialogues. It's in Objective-C, which is, of course, how we expect people to be writing user interfaces on OS X. Thank you. I'm not going to say a whole lot about this, but I will refer you to the proper header file and some documentation a little bit later on.

Now I'm going to go over an actual example of using the authorization APIs. Better Authorization Sample is code that is available up on developer.apple.com. It's an example of using Cocoa and authorization together. It is properly factored code.

[Transcript missing]

And from my standpoint, perhaps the most important thing about Better Authorization Sample is that it is very well commented and it explains why the code looks the way it does.

So, Better Authorization Sample factors the code into two pieces, the GUI front end, that is to say the application, and a helper tool that runs privileged, it runs as root. Now the way it typically operates, the application pre-authorizes. That is to say, it acquires rights on the helper tool's behalf.

User interaction, therefore, happens within the context of the application. That has certain nice consequences for the user interface in that we can gather a lot more information about the actual end user, like the username and whether or not that user is an admin and certain preferences, than we could if the authorization were to happen in the context of the helper tool, which will be running as root.

Now, the application, if pre-authorization is successful, forwards the authorization reference that it gets to the helper tool. And then the tool verifies that the authorization was actually granted, and then and only then does it do its privileged work. This is a general model for how to use authorization.

So this is the window that you'll see when you first start Better Authorization Sample. There are three actions that are defined there. One of them is just getting the version of the application. One of them is getting the real and effective UIDs for the helper tool. And then the last button there gets a set of low-numbered ports. And on OS X, as on other Unix systems, low-numbered ports, that is to say network ports below 1024, can only be given to root-running processes.

So the actual authorization-gated operations in Better Authorization Sample are getting the real and effective UIDs of the helper tool, getting those loaner reports, and an invisible one, installing the helper tool in the first place. So, as an example, let's see what happens when the application needs to get some low-numbered ports.

Now, the write it is requesting here is com.example.betterauthorizationsample.low numberedports. And that uses the default rule, which to refresh your memory requires that you authenticate as a member of the admin group. And the credential that gets generated is subject to a five-minute timeout, and that credential can be shared by any other process running in the same session.

So the first step that the application takes in order to get that right is to get an authorization ref. An authorization ref is your handle into the authorization subsystem. And you get that handle with the authorization create Call. Now, the first two arguments to authorization create are both null because the first argument is the write that you would request. Well, in this case, we don't actually need to request a write. We're just interested in getting a handle. The second argument would be any hints that you want to pass in. In this case, we're not passing any hints, so that again is null.

The flags argument, which is the third, allows you to customize the behavior of the authorization subsystem in some regards. And in this case, we're not actually asking to customize any of that, so we set it to default. And the last argument is the address of an authorization ref object.

Now, in spite of the fact that the variable that the Better Authorization sample writers decided to use for the return of Authorization Create is called junk, it's actually worth paying attention to. Any call that returns any error code needs to be paid attention to. And so don't let the fact that it's called junk in this case mislead you. Do pay attention, do check that that value is no error, because if it's not no error, then something went wrong and you shouldn't proceed any further.

Now, actually asking for the right in question requires that you wrap up the name of the right inside a special structure called an authorization rights structure, and then that you call the authorization copyrights call. Now, in this case, you'll notice that we're customizing the flags to some degree.

We're asking to extend rights, which means that we actually want the policy subsystem to generate a credential. We don't just want it to go through the motions. If you don't specify extend rights, then the policy engine will simply go through the motions, make sure that, in fact, you have the, that you can get that right, but it won't actually generate a credential that says, yes, he has it, that application has it. Also, authorization flag interaction allowed, very important, because the default is to assume that interaction is not allowed.

And finally, pre-authorize signifies that we actually do want to generate a credential that somebody else is going to use further down the line. There are some edge cases where you can request extend rights and pre-authorize and it won't succeed, but those are edge cases typically where, for example, the timeout of the credential is zero. It's not going to help you to try and pre-authorize something with a credential whose timeout is zero because next time you ask for authorization somewhere else, that authorization is not going to succeed or it's going to require that the user go through the entire policy evaluation again.

So this is the dialogue that you actually get when you call authorization copyrights. Now, I don't know if you can actually read this out there, but the first sentence in the dialogue says, "You must be authorized to open low-numbered TCP ports." That's an example of a customizable prompt. That is something that was provided by the Better Authorization Sample application itself. It helps to put the reason for the dialogue in some context.

Now, the second sentence, however, "Type in administrator's name and password to allow application name to make changes," that part is cooked into the dialogue. That is invariant, and that helps to promote some consistency of UI within the system. One other thing to notice is that the name field is empty. Had I been logged in as an admin when I took the snapshot of this dialogue, the name field would have been filled in with my admin username.

So that's just something to notice in case people ask you about that. If they don't see a name here, it's because they weren't logged in as an admin. Now, assuming that the user typed in an administrator's name and password, and that name and password was actually valid, the authorization handle needs to be sent off to the tool. The tool is a completely separate process. Therefore, simply sending across the authorization ref as it stands will not work because the authorization ref is something, it's a value that's only valid within your application's address space.

So, what we want to do is package up that handle in some sort of external form that the other process can absorb and turn back into an authorization handle that's valid within its address space. So, what Better Authorization Sample does first is it launches the tool and sets up the inter-process communication mechanism that it's going to use to talk to that tool. That's outside of authorization per se.

However, Authorization Make External Form is what Better Authorization Sample uses to turn the authorization handle, the authorization ref, into some form that can be sent between processes. In this case, we call it an Authorization External Form. And there should be a space between Authorization External Form and XedAuth. XedAuth is the name of the variable. Sorry about that. And Better Authorization Sample finally sends XedAuth to the tool via the IPC channel that it already set up.

The tool itself goes and internalizes the authorization ref that it got, the externalized form of the authorization ref that it got, using the authorization create from external form call. Pretty straightforward there. The tool then verifies that the application actually did authorize for the right that was required. So the tool actually goes and calls authorization copyrights again. It will allow user interaction.

So if for any reason the right is no longer granted or was never granted, the tool itself will trigger the user interface necessary in order for that right to be authorized. And finally, assuming authorization was granted one way or another, then the tool actually goes and gets the loan number ports in question. You may not be able to read the output from there, but basically it got three different ports, ports 130, 131, and 132.

Now, before it could actually get any ports or do anything else, Better Authorization Sample had to install the privileged helper tool in the first place. Now, implicit in doing so, it asked for the system.privilege.admin right. That's a special right that's baked into the system. The rule associated with it is if you're running as root, it's all good. You're just authorized. Otherwise, you have to authenticate as an administrator. The credential that gets generated as a result is not shared with any other process, and that credential times out in five minutes.

So again, in order to install the tool, in order to actually get system.privilege.admin, you first have to call authorization create to get yourself a handle. And then Better Authorization Sample calls Authorization Execute with Privileges. Authorization Execute with Privileges is a fairly dangerous call because what it ends up doing is it requests system.privilege.admin on behalf of the caller. And if the caller succeeds in authorizing that right, Authorization Execute with Privileges will execute a tool of the caller's choosing as root via a setUID root tool of its own.

Now, you can specify a communications channel that you can use between the tool that gets executed as root and the frontmost client process. Now, the reason authorization execute with privileges-- oh, sorry. I guess we're going to see the UI first. So this is what you see from Better Authorization Sample when it first needs to install the tool.

This, again, is the dialog that you get in order to type an admin's name and password. Now, for this dialog, we do not allow applications to customize. So here you only see that you have to type an administrator's name and password in order for the application to make changes.

Now, what I've done is I've opened up the disclosure triangle here to show some of the details because this is something that can help you verify that, for example, the authorization dialog you're getting is for your application and not for some other application. The requested right here is system.privilege.admin, and the actual application requesting that right is, well, it's truncated, but it says better authorization sample, sampleapp.app. And you can actually get the full path to the application if you click on the application. on that name, which is actually a button.

So, Authorization Execute with Privileges runs a set UID root tool. It does attempt to sanitize the environment to that tool to some degree. However, it's kind of dangerous because there are no restrictions on the tool that can be executed via Authorization Execute with Privileges. Now, this was an appropriate solution at the time that Authorization Execute with Privileges was introduced to OS X. However, that was a little while ago, and in the meantime, we've gotten a better solution added to the system. It's called LaunchD. LaunchD is how most processes are launched on the system nowadays. I strongly encourage you to look into using LaunchD to do this sort of thing.

Rather than Authorization Execute with Privileges, now you're expecting me to explain how you go about doing this, and I'm going to tell you that that requires an entirely different session. Now, I don't know the schedule for WWDC this year, so I'm not sure whether that session has already occurred, unfortunately. But look it up. I'm sure that you can find some documentation about that session. There's certainly a lot of documentation. There's certainly a lot of documentation about LaunchD, and I'll give you a few pointers at the end of this talk to more information.

Now, you can request any arbitrary string and call it a write. You can request com.fubar.fu, and the system will respond intelligently. It will, in all likelihood, use the default rule to cover that write, because com.fubar.fu certainly doesn't ship with OS X's ETSI authorization, and nobody's likely to have added it to the system. However, if you want your write to be subject to your specific set of mechanisms, for instance, then you will need to use these calls, authorization write set and potentially authorization write get.

Authorization Right Get, in this case, is being called by Authorization Sample to see whether or not the right name already exists in the system. If it does, Authorization Right Get will return a CFDictionary, that's the second argument here, that contains the properties associated, that is to say the rules associated with that right. Now, if Authorization Right Get returns Authorization Denied, that indicates the right doesn't exist in the system. So Better Authorization Sample then goes ahead and calls Authorization Right Set, specifying the name of the right.

The rule, if applicable. The description, which is a right description, and a bundle for localizations. Those two really are for localizations. Those are definite courtesies that we encourage you to make for users, especially if you're going to be shipping your application overseas. And then also a description string table name. That's for essentially a bunch of strings that are included in your plug-in.

Now finally, any application, for that matter any tool, that gets an authorization handle needs to dispose of it properly because otherwise you may find that authorization state lives on in the credentials cache where you didn't really want it to live. Gary Hoo Now finally, any application, for that matter any tool, that gets an authorization handle needs to dispose of it properly because otherwise you may find that authorization state lives on in the credentials cache where you didn't really want it to live.

The APIs generally live in one of these header files. Authorization.h is the main one. Authorization.db.h is where APIs to manipulate the policy database, like Authorization write get and Authorization write set, live. Authorization.plugin.h is where we define the APIs and the structures associated with plug-ins and mechanisms. And then the SF Authorization Plugin View, that base class that you can use if you want to design your custom UI for your application, the APIs and the structures for that are in the Security Interface Framework in SF Authorization Plugin View.h.

For more information, sample code for better authorization sample in particular is available at this URL, developer.apple.com/samplecode/better- authorization-sample. There are a couple of sample authorization plug-ins that you can use. Null auth plug-in is a very simple example of how to use or how to write an authorization plug-in. Name and password is an example of a plug-in that uses the SF authorization plug-in view.

There is an excellent document called Performing Privileged Operations with Authorization Services. It's also available on developer.apple.com. And there is a tech note specifically for running daemons and agents via LaunchD and via other mechanisms as well, but we encourage you to use LaunchD. And that tech note is available at that URL, which I have not memorized. So you can take a look at the slides. Okay, so authorization helps you to reduce the amount of effort you have to put in in order to take advantage of policy on OS X.

It promotes a consistent user experience that is nevertheless customizable. And it encourages you to factor your code so that you have much less code running as root and therefore you have, you open a much smaller window, I should say, to any bad guys that want to exploit root running code on the system to subvert the system.