Scrivere uno strumento di supporto privilegiato con SMJobBless ()

Anche se l’API è stata aperta da Mac OS X Leopard, c’è sorprendentemente, e sfortunatamente, pochissima documentazione su come usare correttamente SMJobBless() per creare strumenti di supporto privilegiati. Ci sono un sacco di trucchi, anche quando si copia il codice direttamente dal progetto di esempio di Apple. Fortunatamente, ho trovato il modo di aggirarlo e ho trovato le basi per il funzionamento del mio strumento di supporto.

Tuttavia, sembrerebbe che SMJobBless() solo benedica lo strumento e lo copi, ma non lo esegue. Ho incluso il codice nella funzione main() mio helper tool che dovrebbe funzionare, ma non lo fa (dal momento che NSLog() inspiegabilmente non funziona, in base al minuscolo dato che ho trovato, ho provato syslog() alcune stringhe di tipo “Hello world”, ma non appare nulla sulla console di sistema). Non c’è nessuna indicazione che lo strumento di supporto sia stato lanciato.
La documentazione è per lo più inutile. Semplicemente dice che dopo che SMJobBless() viene chiamato, lo strumento helper è ‘pronto’, senza alcuna indicazione di cosa significa ‘pronto’.

Inoltre, l’esempio di Apple non include alcun codice di comunicazione interprocesso e non spiega come si suppone che si debba interagire con lo strumento di supporto. Usi oggetti distribuiti? Porti Mach? Chissà? Non c’è una parola ufficiale su come farlo.

Quindi, qualcuno ha qualche informazione su come ottenere questo risultato? Ho confermato che lo strumento helper è installato e l’autenticazione funziona, ma non riesco a capire come avviare lo strumento helper e comunicare con esso – c’è semplicemente una lacuna nella documentazione che per ora è un mistero. È molto frustrante; Non posso essere l’ unico con questo problema (ma c’è poco da menzionare ovunque ), e SMJobBless() ovviamente funziona in qualche modo , dal momento che è quello che usa Apple.

(Si prega di non menzionare AuthorizationExecuteWithPrivileges() . Non lo sto usando: è deprecato, sicuro di andare via, ed è un grosso buco di sicurezza. No grazie.)

XPC non è un’opzione se stai cercando di elevare i privilegi (da https://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingXPCServices.html ):

Per impostazione predefinita, i servizi XPC vengono eseguiti nell’ambiente più ristretto ansible: sandbox con accesso al file system minimo, accesso alla rete e così via. L’elevazione dei privilegi di un servizio a root non è supportata.

SMJobBless installerà uno strumento di supporto e lo registrerà con Launchd, come nell’esempio SMJobBless fornito da Apple. Il trucco per far sì che lo strumento di aiuto sia effettivamente avviato è semplicemente quello di tentare di connettersi ai servizi pubblicizzati del tuo strumento di aiuto.

C’era un esempio WWDC2010 chiamato ssd che dimostrava un semplice modello client / server launchd tramite socket. Non è più disponibile da Apple, ma ho trovato un link qui: http://lists.apple.com/archives/macnetworkprog/2011/Jul/msg00005.html

Ho incorporato la gestione della coda di invio nel codice server dall’esempio ssd nello strumento di supporto nell’esempio SMJobBless e posso confermare che il mio strumento di aiuto è effettivamente in esecuzione (come root) quando la mia app principale tenta una connessione sulla porta appropriata. Guarda il video di WWDC2010 su Launchd per capire gli altri meccanismi con cui puoi comunicare con il tuo strumento di supporto (diverso da socket).

Non sono sicuro di poter ridistribuire legalmente le risorse modificate che ho, ma dovrebbe essere abbastanza semplice fondere i due progetti e far funzionare lo strumento di aiuto.

Modifica: Ecco un esempio di progetto che ho scritto che utilizza un object distribuito per la comunicazione tra l’app e l’helper: http://dl.dropbox.com/u/463624/Elevator.zip

In effetti, il commento di @ KurtRevis è corretto, è ansible utilizzare le API XPC senza utilizzare i servizi XPC ed è ideale per il lavoro da allora.

Nathan de Vries ha un’ottima conoscenza dell’uso delle API XPC con SMJobBless e ha persino modificato l’app di esempio SMJobBless per utilizzare mach XPC sia per triggersre il lavoro che per le comunicazioni bidirezionali:

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

https://github.com/atnan/SMJobBlessXPC

Un po ‘correlato a tutto ciò evita inutili richieste di password dell’amministratore. Vedere il seguente thread dell’elenco di e-mail per idee su come verificare se la versione del bundle e la firma del codice di una corrispondenza helper già installata (che consente anche di rimuovere un helper con versione più alta in caso di downgrade di un utente):

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

Se non vuoi navigare attraverso il thread, ecco un link al progetto di esempio SMJobBless modificato fornito da Eric Gorr:

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

Si noti inoltre che l’esempio ssd citato in altre risposte qui è ancora disponibile online da Apple come parte del bundle di download WWDC 2010:

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

Sento il tuo dolore e sono nella stessa barca. Sono responsabile della versione Mac di un’app che deve eseguire varie attività di configurazione del sistema. Ovviamente alcuni di questi compiti devono essere eseguiti con diritti amministrativi. Ho iniziato utilizzando il codice di esempio da BetterAuthorizationSample . È stato un grande dolore implementarlo, ma sembrava funzionare. Ma poi si è imbattuto in casi in cui si sarebbe schiantato su alcuni sistemi. Non ho capito tutto ciò che il codice BAS ha fatto e la mia mancanza di esperienza nella codifica ha probabilmente contribuito ai problemi. Quindi ho dovuto rimuovere queste funzioni privilegiate dalla mia app.

Apple non sembra preoccuparsi della mancanza di documentazione. Vedi questo messaggio dal creatore del framework ServiceManagement . Dai suoi commenti, suppongo che XPC sia la “sostituzione intuitiva” a cui si riferisce, ma dal momento che è disponibile solo su Lion, dovrai comunque trovare un’altra soluzione per Snow Leopard o per i client precedenti. Inoltre, non è chiaro se XPC può essere utilizzato per helper privilegiati (attività a livello di sistema che richiedono l’accesso di amministratore o root) o è solo inteso per la separazione dei privilegi all’interno della propria app per renderlo più sicuro.

La documentazione di BAS ha un disperato bisogno di un aggiornamento, ma non sembra essere una priorità assoluta .

Ora sto tentando di riscrivere la mia app da zero. Professional Cocoa Application Security di Graham Lee fornisce alcune informazioni su come utilizzare gli helper con privilegi con SMJobBless, ma non fornisce molti dettagli sull’accesso on-demand ai lavori di avvio.

Quindi ecco cosa sono stato in grado di trovare:

Se vuoi lanciare il tuo helper privilegiato su richiesta, dovrai usare un socket IPC. Dovresti aggiungere una voce Socket a launchd.plist del tuo helper. Dopo aver installato l’app con SMJobBless, l’helper dovrà eseguire il “check-in” con launchd (tramite LAUNCH_KEY_CHECKIN) per ottenere i descrittori del file socket.

Purtroppo, le uniche menzioni di LAUNCH_KEY_CHECKIN sembrano essere nel codice di esempio di SampleD e BAS .

Non ho alcuna esperienza con le prese, quindi questo è il mio posto di blocco al momento. Mi piacerebbe usare l’API di livello più alto che posso, quindi sto cercando di scoprire se posso usare qualsiasi class Objective-C per questo (come NSStream).

Potresti trovare utile la mailing list degli sviluppatori di launchd . Un’altra opzione XPC che ho appena scoperto è XPCKit . Vale la pena dare un’occhiata.

HTH

Ho scritto un post su questo blog alcuni mesi fa, che includeva una versione ripulita del campione SMJobBless di Apple. Potrebbe aiutare…

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

Apple ora (2015) ha un “EvenBetterAuthorizationSample” che dimostra l’installazione di uno strumento di supporto privilegiato e l’ NSXPCConnection dell’API NSXPCConnection per comunicare tra l’app e lo strumento helper:

Il README è una delle migliori (solo?) Documentazione di SMJobBless() disponibile.

Hai visto il codice di esempio SMJobBless del WWDC 2010? Include uno strumento di supporto e un’app per benedirlo.

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

Il suo file README dice:

Questo esempio così com’è in realtà non esegue lo strumento di supporto. I seguenti esempi mostrano come [sic] un lavoro di avvio e impostare la comunicazione tra processi:

  • ssd (non sembra più online. Era parte del codice di esempio WWDC 2010.)
  • BetterAuthorizationSample