Mac のログイン画面を置き換えることはできますか?
-
21-08-2019 - |
質問
Mac OS X ログイン ウィンドウ /System/Library/CoreServices/loginwindow.app をカスタム ログイン ウィンドウ アプリケーションに置き換えることはできますか?(そうする私の理由を見てください.)
私の Cocoa プログラミング スキルは初歩的なものだと思います。プローブ CGSession (つまり、 ユーザーの高速切り替えを実行する文書化されていないユーティリティ) どのような関数が使用されているかを確認するには、次のようにします。
nm -mg /System/Library/CoreServices/Menu\ Extras/User.menu/Contents/Resources/CGSession
リンクされた関数の 1 つは次のとおりです。
(undefined [lazy bound]) external _CGSCreateLoginSession (from ApplicationServices)
ApplicationServices フレームワークに関するドキュメントが見つかりませんでした。アプリケーション プログラマー インターフェイスではなく、サービス プロバイダー インターフェイスに深く入り込んでいるのではないかと思います。
この非常に興味深いスニペットを見つけました。(Googleのキャッシュ) (ダウンページへの直接リンク;ユーザーの高速切り替えが無効になっている場合でも、ログイン ウィンドウに切り替えると主張するアプリケーションから、サイトの再編成が行われているようです。
#include "CGSInternal.h"
int main (int argc, const char * argv[]) {
// switch to the login window
CGSCreateLoginSession(NULL);
return 0;
}
私は CG を CoreGraphics のことだと考えていますが、それがログインと何の関係があるのか理解できません (おそらく現在のユーザーの作業の上にログイン ダイアログを表示することを除いて)。
たとえログインウィンドウを置き換えることは不可能だとしても、(Apple で働いていない人が) この方針に沿って何ができるのか知りたいと思います。
解決
ログイン ウィンドウ アプリケーションは、launchd 構成の一部として定義されます。 /システム/ライブラリ/LaunchDaemons/com.apple.loginwindow.plist.
理論的には、ログイン ウィンドウを独自のものに置き換えることはできますが、新しいアプリで何をしなければならないのかわかりません。ログイン ウィンドウは認証とユーザー セッションの設定以外のことを行うと思います -> とりわけ、 launchd 関連の雑務を行っているようです。
を呼び出すアプリケーションをコンパイルしました CGSCreateLoginSession 実行すると、回転する立方体を介してログイン ウィンドウに移行します。これが、CoreGraphics が必要な理由だと思います。CoreGraphics は、最後にログアウトを呼び出す単なるグラフィックス関数です。
InputManager を試してみて、ログイン ウィンドウがコードをロードすることを確認できます。ロードされた場合は、ログイン ウィンドウの NIB を変更できます (ログインウィンドウUI.nib) そして、ユーザーのブラウザで新しいウィンドウを表示するためのいくつかのボタンを追加します。学生が自分の写真を選択したら、ログイン ウィンドウのユーザー名とパスワードのフィールドを自動入力できます。
ノード、これはすべて理論であり、次のようになります とても 壊れやすく安全ではありません。
幸運を。
後で編集する
これは非常に危険であることに注意してください。注意して使用してください。私はこれを試したときにシステムに数回ホースをかけました。
これは、ログイン ウィンドウにコードを挿入する概念実証の実装です。
#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;
}
コードは次のようにコンパイルされます。
gcc -Wall -dynamiclib -undefined dynamic_lookup -o ~/Desktop/libinterposers.dylib testin.m -framework Cocoa
コードの読み込みは挿入に基づいているため、loginwindow の launchd 定義には追加のエントリ (動的リンカーでの挿入を有効にするため) が含まれている必要があります。つまり、次のようになります。
<key>EnvironmentVariables</key>
<dict>
<key>DYLD_INSERT_LIBRARIES</key>
<string>path_to/Desktop/libinterposers.dylib</string>
</dict>
他のヒント
はい、あなたはSFAuthorizationPluginViewを使用することができます。