Escrevendo uma ferramenta auxiliar privilegiada com o SMJobBless ()

Embora a API tenha sido aberta desde o Mac OS X Leopard, há surpreendentemente, e infelizmente, muito pouca documentação sobre como usar corretamente o SMJobBless() para criar ferramentas auxiliares privilegiadas. Há muitas dicas, mesmo ao copiar o código diretamente do projeto de amostra da Apple. Felizmente, encontrei meu caminho em torno disso e consegui a base para minha ferramenta de ajuda funcionar.

No entanto, parece que o SMJobBless() apenas abençoa a ferramenta e a copia, mas não a executa. Eu incluí o código na function main() da ferramenta de ajuda que deve ser executada, mas não funciona (já que o NSLog() inexplicavelmente não funciona – de acordo com a pequena informação que encontrei – tentei o syslog() algumas strings do tipo “Hello world”, mas nada aparece no console do sistema. Não há indicação de que a ferramenta auxiliar seja lançada.
A documentação é praticamente inútil. Ele simplesmente diz que depois que o SMJobBless() é chamado, a ferramenta de ajuda está “pronta”, sem indicação do que significa “pronto”.

Além disso, a amostra da Apple não inclui nenhum código de comunicação entre processos e não explica como se deve interagir com a ferramenta auxiliar. Você usa objects distribuídos? Portas Mach Quem sabe? Não há nenhuma palavra oficial sobre como fazer isso.

Então, alguém tem alguma informação sobre como fazer isso? Confirmei que a ferramenta auxiliar está instalada e a autenticação funciona, mas simplesmente não consigo descobrir como iniciar a ferramenta auxiliar e se comunicar com ela – há simplesmente uma lacuna na documentação de que isso é um mistério por enquanto. É muito frustrante; Eu não posso ser o único com esse problema (mas há pouca menção a isso em qualquer lugar ), e o SMJobBless() obviamente funciona de alguma forma , já que é o que a Apple usa.

(Por favor, não mencione AuthorizationExecuteWithPrivileges() . Eu não estou usando: é obsoleto, com certeza vai embora, e é uma grande falha de segurança. Não, obrigado.)

O XPC não é uma opção se você estiver tentando elevar privilégios (em https://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingXPCServices.html ):

Por padrão, os serviços XPC são executados no ambiente mais restrito possível – em área restrita com access mínimo ao sistema de arquivos, access à rede e assim por diante. Elevar os privilégios de um serviço para o root não é suportado.

O SMJobBless irá instalar uma ferramenta auxiliar e registrá-la no Launchd, como no exemplo SMJobBless fornecido pela Apple. O truque para fazer com que a sua ferramenta de ajuda seja realmente lançada é simplesmente tentar conectar-se aos serviços anunciados da sua ferramenta de ajuda.

Houve um exemplo de WWDC2010 chamado ssd que demonstrou um modelo de cliente / servidor launchd simples via sockets. Não está mais disponível na Apple, mas encontrei um link aqui: http://lists.apple.com/archives/macnetworkprog/2011/Jul/msg00005.html

Eu incorporei a manipulação da fila de dispatch no código do servidor do exemplo do ssd para a ferramenta auxiliar no exemplo do SMJobBless e posso confirmar que minha ferramenta auxiliar está de fato em execução (como root) quando meu aplicativo principal tenta uma conexão na porta apropriada. Veja o vídeo do WWDC2010 no Launchd para entender os outros mecanismos com os quais você pode se comunicar com sua ferramenta auxiliar (que não seja sockets).

Não tenho certeza se posso redistribuir legalmente as fonts modificadas que tenho, mas deve ser bastante simples mesclar os dois projetos e fazer com que sua ferramenta de ajuda seja executada.

Edit: Aqui está um projeto de exemplo que eu escrevi que usa um object distribuído para comunicação entre o aplicativo e auxiliar: http://dl.dropbox.com/u/463624/Elevator.zip

De fato, o comentário do @KurtRevis está correto, você pode usar APIs XPC sem usar serviços XPC, e é ideal para o trabalho desde então.

Nathan de Vries escreveu um excelente artigo sobre o uso de APIs XPC com o SMJobBless e até modificou o aplicativo SMJobBless para usar o mach XPC para ativar o trabalho e para comunicações bidirecionais:

http://atnan.com/blog/2012/02/29/modern-privileged-helper-tools-using-smjobbless-plus-xpc/

https://github.com/atnan/SMJobBlessXPC

Algo relacionado a tudo isso é evitar solicitações desnecessárias de senha de administrador. Consulte o seguinte tópico da lista de email para saber como verificar se a versão do pacote e a assinatura de código de um auxiliar já instalado coincidem (o que também permite remover um auxiliar de versão superior no caso de um downgrade de usuário):

http://www.cocoabuilder.com/archive/cocoa/309298-question-about-smjobbless.html

Se você não quiser percorrer o encadeamento, aqui está um link para o projeto de amostra SMJobBless modificado fornecido por Eric Gorr:

http://ericgorr.net/cocoadev/SMJobBless.zip

Observe também que o exemplo do ssd mencionado em outras respostas aqui ainda está disponível on-line da Apple como parte do pacote de download do WWDC 2010:

http://connect.apple.com/cgi-bin/WebObjects/MemberSite.woa/wa/getSoftware?code=y&source=x&bundleID=20645

Eu sinto sua dor e estou no mesmo barco. Eu sou responsável pela versão para Mac de um aplicativo que precisa executar várias tarefas de configuração do sistema. É claro que algumas dessas tarefas precisam ser feitas com direitos administrativos. Comecei usando o código de exemplo de BetterAuthorizationSample . Foi uma grande dor para implementar, mas pareceu funcionar. Mas depois correu em casos em que iria cair em alguns sistemas. Eu não entendi tudo o que o código BAS fez e minha própria falta de experiência em codificação provavelmente contribuiu para os problemas. Então eu tive que remover essas funções privilegiadas do meu aplicativo.

A Apple não parece se importar com a falta de documentação. Veja esta mensagem do criador da estrutura do ServiceManagement . De seus comentários, eu assumo que o XPC é o “substituto intuitivo” ao qual ele está se referindo, mas como ele só está disponível no Lion, você ainda terá que encontrar outra solução para o Snow Leopard ou clientes anteriores. Também não está claro para mim se o XPC pode ser usado para assistentes privilegiados (tarefas no nível do sistema que exigem access de administrador ou raiz) ou se destina apenas à separação de privilégios dentro de seu próprio aplicativo para torná-lo mais seguro.

A documentação do BAS está em necessidade desesperada de uma atualização, mas também não parece ser uma prioridade .

Agora estou tentando rewrite meu aplicativo a partir do zero. O aplicativo Professional Cocoa Security, de Graham Lee, fornece algumas dicas sobre como usar os assistentes privilegiados com o SMJobBless, mas não detalha muito sobre o access sob demanda a jobs do launchd.

Então, aqui está o que eu consegui encontrar:

Se você deseja iniciar seu auxiliar privilegiado sob demanda, você precisará usar um soquete IPC. Você deve adicionar uma input Sockets ao launchd.plist do seu ajudante. Depois de instalar o aplicativo com o SMJobBless, o auxiliar precisará fazer o “check-in” com o launchd (via LAUNCH_KEY_CHECKIN) para obter os descritores do arquivo de soquete.

Infelizmente, as únicas menções de LAUNCH_KEY_CHECKIN parecem estar no código de amostra SampleD e BAS .

Eu não tenho nenhuma experiência com sockets, então esse é o meu obstáculo no momento. Eu gostaria de usar a API de nível mais alto possível, então estou tentando descobrir se posso usar qualquer class Objective-C para isso (como o NSStream).

Você pode achar útil a lista de discussão dos desenvolvedores do launchd . Outra opção XPC que acabei de descobrir é XPCKit . Vale a pena dar uma olhada.

HTH

Eu escrevi um post sobre isso alguns meses atrás, que incluiu uma versão limpa do exemplo SMJobBless da Apple. Pode ajudar…

http://www.bornsleepy.com/bornsleepy/os-x-helper-applications

A Apple agora (2015) tem um “EvenBetterAuthorizationSample” que demonstra a instalação de uma ferramenta auxiliar privilegiada e o uso da API NSXPCConnection para se comunicar entre o aplicativo e a ferramenta auxiliar:

O README é uma das melhores (apenas?) Documentação do SMJobBless() disponível.

Você já examinou o código de exemplo SMJobBless do WWDC 2010? Inclui uma ferramenta auxiliar e aplicativo para abençoá-lo.

https://developer.apple.com/library/mac/#samplecode/SMJobBless/Listings/ReadMe_txt.html#//apple_ref/doc/uid/DTS40010071-ReadMe_txt-DontLinkElementID_3

Seu arquivo README diz:

Este exemplo como está na verdade, não executa a ferramenta auxiliar. Os exemplos a seguir mostram como [sic] um job launchd e configuram a comunicação entre processos:

  • ssd (parece não estar mais on-line. Fazia parte do código de exemplo da WWDC 2010.)
  • BetterAuthorizationSample