2009-06-30 13 views
6

E 'possibile sostituire la finestra di login di Mac OS X, /System/Library/CoreServices/loginwindow.app, con un'applicazione di finestra di login personalizzata? (See my rational for doing so.)È possibile sostituire la schermata di accesso Mac?

Ho paura che le mie capacità di programmazione del cacao siano rudimentali. Trovo interessante il fatto che, quando ho eseguito la sonda CGSession (che è a undocumented utility that performs fast user switching) per vedere quali funzioni che utilizza, facendo

nm -mg /System/Library/CoreServices/Menu\ Extras/User.menu/Contents/Resources/CGSession 

quella della funzione associata è:

(undefined [lazy bound]) external _CGSCreateLoginSession (from ApplicationServices) 

Mi rifugio' Ho trovato la documentazione sul framework ApplicationServices.So sospetto che sto entrando in profondità nelle interfacce Service Provider invece delle Application Programmer.

Ho trovato questo frammento davvero interessante: (google cache) (direct link to down page; sembra che il sito sia in fase di riorganizzazione) da un'applicazione che afferma di passare alla finestra di accesso anche se il cambio utente rapido è disabilitato.

#include "CGSInternal.h" 

int main (int argc, const char * argv[]) { 
    // switch to the login window 
    CGSCreateLoginSession(NULL); 

    return 0; 
} 

prendo CG significare CoreGraphics, e non si capisce cosa che ha a che fare con la registrazione in (se non con forse mettere un login dialogo fino oltre il lavoro dell'utente corrente).

Anche se non è possibile ottenere una sostituzione per la finestra di accesso, sarei interessato a sapere cosa si può fare in questo senso (da persone che non lavorano per Apple).

+2

il tuo 'razionale per farlo' sembra rotto (come in 'il collegamento è rotto') – akf

+0

Siamo spiacenti. Ho risolto il link. –

+0

Tutto è possibile. Dipende solo da quante garanzie e EULA vuoi annullare. –

risposta

18

L'applicazione finestra di accesso viene definita come parte della configurazione launchd in /System/Library/LaunchDaemons/com.apple.loginwindow.plist.

In teoria puoi sostituire la finestra di login con la tua ma non so cosa devi fare nella nuova app - Penso che la finestra di login faccia un po 'più di autenticazione e configurazione della sessione utente -> tra l'altro, sembra che stia facendo alcune faccende legate al lancio.

Ho compilato un'applicazione che chiama CGSCreateLoginSession e, una volta eseguito, passa alla finestra di accesso tramite il cubo rotante. Immagino che questo sia il motivo per cui richiede CoreGraphics - è solo una funzione grafica che chiama il logout alla fine.

Si potrebbe provare un InputManager e vedere la finestra di login carica il codice -> se lo fa, si potrebbe quindi modificare il loginwindow NIB (LoginWindowUI.nib) e aggiungere alcuni pulsanti per visualizzare una nuova finestra con l'utente browser. Una volta che lo studente ha scelto una sua foto, è possibile compilare automaticamente i campi nome utente e password nella finestra di accesso.

Nodo questo è tutto teoria, e sembra molto fragile e pericoloso.

Buona fortuna.

Successivamente modificare

Si prega di notare che questo è molto pericoloso in modo da utilizzare con attenzione - ho fatto bagnare il mio sistema un paio di volte quando si cerca fuori questa roba

Ecco un concetto proof-of- implementazione che inietta il codice nella finestra di login.

#include <stdio.h> 
#include <unistd.h> 
#include <sys/time.h> 
#include <strings.h> 
#include <syslog.h> 

#import <Cocoa/Cocoa.h> 

#include <execinfo.h> 

@interface LLApp:NSApplication 
@end 
@implementation LLApp 
- (void)run 
{ 
    syslog(LOG_ERR, "LLApp being run"); 
    [super run]; 
} 
@end 

void my_openlog(const char *ident, int logopt, int facility); 

typedef struct interpose_s 
{ 
     void * new_func; 
     void * orig_func; 
} interpose_t; 

int MyNSApplicationMain(int argc, const char ** argv); 


static const interpose_t interposers[] __attribute__ ((section("__DATA, __interpose")))  = { 
{ (void *) my_openlog, (void *) openlog }, 
}; 

void my_openlog(const char *ident, int logopt, int facility) 
{ 
     openlog(ident, logopt, facility); 

    if(!strcmp(ident, "/System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow")) 
    { 

     [LLApp poseAsClass:[NSApplication class]]; 
    } 
    else 
    { 
     syslog(LOG_ERR, "Ignoring unknown indent: >%s<", ident); 
    } 
    return; 
} 

il codice viene compilato con:

gcc -Wall -dynamiclib -undefined dynamic_lookup -o ~/Desktop/libinterposers.dylib testin.m -framework Cocoa 

Codice di carico si basa sulla interponendo quindi la definizione launchd di loginwindow deve contenere una voce aggiuntiva (per consentire interponendo nel linker dinamico), vale a dire:

<key>EnvironmentVariables</key> 
<dict>  
    <key>DYLD_INSERT_LIBRARIES</key> 
    <string>path_to/Desktop/libinterposers.dylib</string> 
</dict> 
+0

Wow. Sarei felice di revocarti una seconda volta. È incredibile e pazzo allo stesso tempo. Essendo abbastanza avanzato, sono sicuro di aver capito correttamente cosa fa questo esempio: sostituisce la chiamata a "openlog" con un "my_openlog" che fa sì che la classe LLApp finga di essere la classe NSApplication, in modo che ogni chiamata alle sue funzioni può essere modificato, e lo dimostra modificando la funzione di esecuzione per produrre qualcosa nel registro di sistema. –

+0

La sostituzione delle funzioni è resa possibile dall'interposizione - google per "interporre mac os x" e troverai un capitolo del libro di Amit Singh su OS X che descrive come funziona. Il posizionamento di classe è usato per sostituire tutte le istanze della classe X con la classe Y - nota che non è supportato su 64 bit. Per quanto riguarda la sostituzione - [Esecuzione NSApplication] probabilmente non lo si desidera - è necessario sostituire qualcosa all'interno dell'applicazione di loginwindow come ad esempio un metodo dalla classe di visualizzazione personalizzata (è possibile trovare il nome della classe di visualizzazione personalizzata aprendo il bundle in Interface builder). – diciu

+0

Sembra che non sarò in grado di allocare il tempo a questo nel prossimo futuro, ma sicuramente ti sto dando la risposta corretta per tutto il duro lavoro che hai fatto; Penso davvero che il compito possa essere raggiunto con questa guida. Grazie. –

3

sì, è possibile utilizzare lo SFAuthorizationPluginView

here the reference link at ADC

+0

Grazie per le informazioni. Sembra che sia solo Leopard (anch'io vorrei supportare Tiger). Apple ha un esempio "NameAndPassword" e ci sono un paio di domande correlate su SO, che utilizzano un tag o "SFAuthorizationPluginView" (http://stackoverflow.com/questions/tagged/sfauthorizationpluginview) –

+0

Non sono sicuro che tu possa utilizzare facilmente SFAuthorizationPluginView per modificare qualsiasi cosa nella finestra di accesso. Ho compilato e installato l'esempio di codice NameAndPassword che illustra SFAuthorizationPluginView e mi sembra che ti consenta di creare un diritto personalizzato (vedi/etc/authorization per le definizioni dei diritti esistenti -> login non è lì). Il plug-in entra in gioco quando un'applicazione chiede al sistema operativo di autorizzare l'utente per quel diritto appena creato. – diciu

+0

Grazie, diciu. Non mi era chiaro come avresti (o se avresti potuto) farlo apparire nella schermata di accesso. [L'ho compilato, ma non volevo testare (e interrompere!) L'autorizzazione sul mio computer.] –

Problemi correlati