views:

365

answers:

2

I am making a simple application that lets you quickly enter a shell command to be run. It works perfectly, however there is the problem of sudo commands. Currently, it detects a sudo command, and then I try and get it to bring up an authorization window for the user's password, exactly like you would see in Installer.

Here's the code once it detects it is a sudo command:

SFAuthorization *authorization = [[SFAuthorization alloc] initWithFlags:kAuthorizationFlagPreAuthorize rights:NULL environment:kAuthorizationEmptyEnvironment];
if ([authorization obtainWithRight:"com.mycompany.myapplication" flags:kAuthorizationFlagPreAuthorize error:nil]){
 //authorized, now run the command using NSTask.
}else{
 //fail
}

Now, as far as I know, this is totally and completely wrong. This is just what I pieced together from the documentation. Any ideas?

+1  A: 

Security is hard. I could paraphrase the documentation and provide code snippets, but I would likely be wrong. Worse, even if my high level descriptions were right, there would most likely be a tiny bug in the code snippets that would kill security.

If you are going to mess with privilege escalation, the best approach is to read the docs and use the provided samples.

https://developer.apple.com/mac/library/documentation/Security/Conceptual/authorization%5Fconcepts/01introduction/introduction.html#//apple%5Fref/doc/uid/TP30000995-CH204-TP1

bbum
A: 

Hi,

You'll want to use the AuthorizationExecuteWithPrivileges function, like this:

- (IBAction)touch: (id) sender {

  NSString * filepath = [_filepathfield stringValue];
  FILE *commpipe = NULL;
  OSStatus execstatus;


  NSLog(@"file path is %@", filepath);

  char *args[] = {[filepath cString], NULL};


  SFAuthorization * authorization = [SFAuthorization authorization];

  execstatus = AuthorizationExecuteWithPrivileges([authorization authorizationRef],
                                                  "/usr/bin/touch",
                                                  kAuthorizationFlagDefaults,
                                                  args,
                                                  &commpipe);

  if (execstatus == errAuthorizationSuccess) 
    NSlog(@"Toot! It worked");
  else
    NSLog(@"No dice");

}

Given that BSD is a delicate and grumpy flower I'd recommend not letting a user execute commands arbitrary from the app as root.

/lecture

The code from your example is the beginnings of the way to go if you want to limit the functions of your own program from it's own users. For example, you might have an app that only lets certain users alter data from a saved file. So you'd create an entry in the security database 'com.mycompany.LibraryApp.AlterData' and check to see if the user has that privilege when they try to change the data. But that's a whole different topic...

Hope that helps, -p.

Robert Daniel Pickard