objective c - Escribir una herramienta de ayuda privilegiada con SMJobBless()
objective-c cocoa (6)
¿Has mirado el código de muestra SMJobBless de la WWDC 2010? Incluye una herramienta de ayuda y una aplicación para bendecirlo.
Su archivo README dice:
Esta muestra, tal como está, en realidad no ejecuta la herramienta de ayuda. Los siguientes ejemplos muestran cómo [sic] ejecutar un trabajo y configurar la comunicación entre procesos:
- ssd (Ya no parece estar en línea. Formaba parte del código de ejemplo de WWDC 2010).
- BetterAuthorizationSample
A pesar de que la API ha estado abierta desde Mac OS X Leopard, sorprendentemente, y desafortunadamente, hay muy poca documentación sobre cómo usar correctamente SMJobBless()
para crear herramientas de ayuda privilegiadas. Hay muchos problemas, incluso cuando se copia código directamente del proyecto de ejemplo de Apple. Afortunadamente, he encontrado mi camino a este respecto, y he obtenido la base para que funcione mi herramienta de ayuda.
Sin embargo, parece que SMJobBless()
solo bendice la herramienta y la copia, pero no la ejecuta. He incluido código en la función main()
mi herramienta auxiliar que debería ejecutarse, pero no funciona (ya que NSLog()
inexplicablemente no funciona, de acuerdo con la pequeña cantidad de información que he encontrado, he intentado con syslog()
ing de algunas cadenas tipo "Hello world", pero no aparece nada en la consola del sistema). No hay indicación de que la herramienta de ayuda se haya lanzado.
La documentación es en su mayoría inútil. Simplemente dice que después de SMJobBless()
, la herramienta auxiliar está ''lista'', sin indicación de lo que significa ''listo''.
Además, la muestra de Apple no incluye ningún código de comunicación entre procesos, y no explica cómo se supone que uno debe interactuar con la herramienta de ayuda. ¿Usas objetos distribuidos? Puertos de Mach? ¿Quién sabe? No hay una palabra oficial sobre cómo hacerlo.
Entonces, ¿alguien tiene información sobre cómo hacer esto? Confirmé que la herramienta de ayuda está instalada y que la autenticación funciona, pero simplemente no puedo entender cómo iniciar la herramienta de ayuda y comunicarme con ella, simplemente hay un vacío en la documentación que, por el momento, es un misterio. Es muy frustrante; No puedo ser el único con este problema (pero hay poca mención de ello en cualquier parte ), y SMJobBless()
obviamente funciona de alguna manera , ya que es lo que usa Apple.
(Por favor, no menciones AuthorizationExecuteWithPrivileges()
. No lo estoy usando: está obsoleto, seguro que se va, y es un gran agujero de seguridad. No, gracias.)
Apple ahora (2015) tiene una "EvenBetterAuthorizationSample" que demuestra la instalación de una herramienta de ayuda privilegiada y el uso de la API NSXPCConnection
para comunicarse entre la aplicación y la herramienta de ayuda:
El archivo README es uno de los mejores (¿solo?) Documentos de SMJobBless()
disponibles.
De hecho, el comentario de @ KurtRevis es correcto, puedes usar XPC APIs sin usar servicios XPC, y es ideal para el trabajo desde entonces.
Nathan de Vries tiene una excelente descripción del uso de las API de XPC con SMJobBless e incluso ha modificado la aplicación de ejemplo SMJobBless para usar mach XPC tanto para activar el trabajo como para las comunicaciones bidireccionales:
http://atnan.com/blog/2012/02/29/modern-privileged-helper-tools-using-smjobbless-plus-xpc/
https://github.com/atnan/SMJobBlessXPC
Algo relacionado con todo esto es evitar mensajes innecesarios de contraseña de administrador. Consulte el siguiente hilo de la lista de correo electrónico para obtener ideas sobre cómo verificar si la versión del paquete y la firma del código de un helper ya instalado coinciden (lo que también le permite eliminar un helper versionado más alto en el caso de un usuario degradado):
http://www.cocoabuilder.com/archive/cocoa/309298-question-about-smjobbless.html
Si no desea navegar a través del hilo, aquí hay un enlace al proyecto de muestra SMJobBless modificado provisto por Eric Gorr:
http://ericgorr.net/cocoadev/SMJobBless.zip
También tenga en cuenta que el ejemplo de SSD mencionado en otras respuestas aquí todavía está disponible en línea desde Apple como parte del paquete de descarga WWDC 2010:
Escribí una publicación de blog sobre esto hace unos meses, que incluía una versión limpiada de la muestra SMJobBless de Apple. Podría ayudar...
http://www.bornsleepy.com/bornsleepy/os-x-helper-applications
Siento tu dolor y estoy en el mismo barco. Estoy a cargo de la versión para Mac de una aplicación que necesita realizar varias tareas de configuración del sistema. Por supuesto, algunas de estas tareas deben hacerse con derechos administrativos. Empecé utilizando el código de muestra de BetterAuthorizationSample . Fue un gran esfuerzo implementarlo, pero pareció funcionar. Pero luego se encontró con casos en los que fallaría en algunos sistemas. No entendí todo lo que hizo el código BAS y mi propia falta de experiencia en codificación probablemente contribuyó a los problemas. Así que tuve que eliminar estas funciones privilegiadas de mi aplicación.
A Apple no parece importarle la falta de documentación. Vea este mensaje del creador de la estructura ServiceManagement . De sus comentarios, asumo que XPC es el "reemplazo intuitivo" al que se refiere, pero como solo está disponible para Lion, igual tendrá que encontrar otra solución para Snow Leopard o clientes anteriores. Tampoco me queda claro si XPC se puede usar para ayudantes privilegiados (tareas a nivel de sistema que requieren acceso de administrador o raíz) o solo para la separación de privilegios dentro de su propia aplicación para hacerlo más seguro.
La documentación de BAS necesita una actualización desesperada, pero tampoco parece ser una prioridad .
Ahora estoy intentando volver a escribir mi aplicación desde cero. La aplicación de seguridad profesional Cocoa Application Security de Graham Lee ofrece información sobre cómo utilizar ayudantes privilegiadas con SMJobBless, pero no entra en detalles sobre el acceso bajo demanda para lanzar trabajos.
Así que esto es lo que he podido encontrar:
Si desea iniciar su ayudante con privilegios a pedido, tendrá que usar un socket IPC. Debería agregar una entrada de Sockets a launchd.plist su ayudante. Después de instalar la aplicación con SMJobBless, el ayudante necesitará "check-in" con launchd (a través de LAUNCH_KEY_CHECKIN) para obtener los descriptores del archivo de socket.
Lamentablemente, las únicas menciones de LAUNCH_KEY_CHECKIN parecen estar en el código de muestra SampleD y BetterAuthorizationSample .
No tengo ninguna experiencia con sockets, así que ese es mi obstáculo en este momento. Me gustaría utilizar el API de nivel más alto que puedo, así que estoy tratando de averiguar si puedo usar cualquier clase de Objective-C para esto (como NSStream).
Es posible que encuentre útil la lista de distribución de desarrolladores de launchd . Otra opción de XPC que acabo de descubrir es XPCKit . Vale la pena echarle un vistazo.
HTH
XPC no es una opción si intenta elevar los privilegios (de https://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingXPCServices.html ):
De forma predeterminada, los servicios XPC se ejecutan en el entorno más restringido posible: espacio aislado con acceso mínimo al sistema de archivos, acceso a la red, etc. No se admite el aumento de los privilegios de un servicio a la raíz.
SMJobBless instalará una herramienta auxiliar y la registrará con Launchd, como en el ejemplo SMJobBless proporcionado por Apple. El truco para hacer que su herramienta de ayuda realmente se lance es simplemente intentar conectarse a los servicios anunciados de su herramienta de ayuda.
Había un ejemplo de WWDC2010 llamado ssd
que demostraba un modelo simple de cliente / servidor de lanzamiento a través de sockets. Ya no está disponible en Apple, pero he encontrado un enlace aquí: http://lists.apple.com/archives/macnetworkprog/2011/Jul/msg00005.html
He incorporado el manejo de la cola de envío en el código del servidor del ejemplo ssd en la herramienta auxiliar en el ejemplo SMJobBless y puedo confirmar que mi herramienta auxiliar se está ejecutando (como root) cuando mi aplicación principal intenta una conexión en el puerto apropiado. Consulte el video de WWDC2010 en Launchd para comprender los otros mecanismos con los que puede comunicarse con su herramienta de ayuda (que no sean zócalos).
No estoy seguro de poder legalmente redistribuir las fuentes modificadas que tengo, pero debería ser bastante sencillo fusionar los dos proyectos y ejecutar su herramienta de ayuda.
Editar: Aquí hay un proyecto de ejemplo que escribí que utiliza un objeto distribuido para la comunicación entre la aplicación y el ayudante: http://dl.dropbox.com/u/463624/Elevator.zip