#!/usr/bin/python import sys import os import struct import socket import subprocess import signal from gi.repository import GLib from gi.repository import LightDM loop = GLib.MainLoop () def sigterm_cb (data): status_notify ('GREETER %s TERMINATE SIGNAL=%d' % (os.getenv ('DISPLAY'), signum)) loop.quit () GLib.unix_signal_add (GLib.PRIORITY_DEFAULT, signal.SIGTERM, sigterm_cb, None) status_socket = None def status_notify (message): sys.stderr.write ("status_notify\n"); if status_socket is not None: status_socket.send (struct.pack ('i', len (message)) + message) else: sys.stderr.write ('%s\n' % message) def request_cb (channel, condition): sys.stderr.write ("request_cb\n") length = status_socket.recv (4) sys.stderr.write ("read %d\n" % len (length)) if len (length) == 0: return False if len (length) > 0: (l,) = struct.unpack ('i', length) request = status_socket.recv (l) sys.stderr.write ("read '%s' %d\n" % (request, len (request))) r = 'GREETER %s AUTHENTICATE' % os.getenv ('DISPLAY') if request == r: greeter.authenticate (None) r = 'GREETER %s AUTHENTICATE USERNAME=' % os.getenv ('DISPLAY') if request.startswith (r): greeter.authenticate (request[len(r):]) r = 'GREETER %s AUTHENTICATE-GUEST' % os.getenv ('DISPLAY') if request == r: greeter.authenticate_as_guest () r = 'GREETER %s AUTHENTICATE-AUTOLOGIN' % os.getenv ('DISPLAY') if request == r: greeter.authenticate_autologin () r = 'GREETER %s AUTHENTICATE-REMOTE SESSION=' % os.getenv ('DISPLAY') if request.startswith (r): greeter.authenticate_remote (request[len(r):], None) r = 'GREETER %s RESPOND TEXT=\"' % os.getenv ('DISPLAY') if request.startswith (r): greeter.respond (request[len (r):-1]) r = 'GREETER %s START-SESSION' % os.getenv ('DISPLAY') if request == r: sys.stderr.write ("start-session\n"); if not greeter.start_session_sync (None): sys.stderr.write ("start-session-failed\n"); status_notify ('GREETER %s SESSION-FAILED' % os.getenv ('DISPLAY')) sys.stderr.write ("start-session ok\n"); r = 'GREETER %s START-SESSION SESSION=' % os.getenv ('DISPLAY') if request.startswith (r): if not greeter.start_session_sync (request[len(r):]): status_notify ('GREETER %s SESSION-FAILED' % os.getenv ('DISPLAY')) r = 'GREETER %s LOG-LAYOUT' % os.getenv ('DISPLAY') if request == r: layout = LightDM.get_layout ().get_name () status_notify ('GREETER %s LOG-LAYOUT LAYOUT=%s' % (os.getenv ('DISPLAY'), layout)) r = 'GREETER %s LOG-LAYOUT USERNAME=' % os.getenv ('DISPLAY') if request.startswith (r): username = request[len(r):] user = LightDM.UserList.get_instance ().get_user_by_name (username) layout = user.get_layout () if layout is None: layout = '' status_notify ('GREETER %s LOG-LAYOUT USERNAME=%s LAYOUT=%s' % (os.getenv ('DISPLAY'), username, layout)) r = 'GREETER %s LOG-LANGUAGE USERNAME=' % os.getenv ('DISPLAY') if request.startswith (r): username = request[len(r):] user = lightdm_user_list_get_user_by_name (lightdm_user_list_get_instance (), username) language = lightdm_user_get_language (user) if language is None: language = '' status_notify ('GREETER %s LOG-LANGUAGE USERNAME=%s LANGUAGE=%s' % (os.getenv ('DISPLAY'), username, language)) sys.stderr.write ("request_cb end\n") return True path = os.getenv ('LIGHTDM_TEST_ROOT') + '/.status-socket' status_socket = socket.socket (socket.AF_UNIX, socket.SOCK_STREAM) status_socket.connect (path) GLib.io_add_watch (status_socket.fileno (), GLib.IO_IN, request_cb) status_notify ('GREETER %s START' % os.getenv ('DISPLAY')) # NOTE: There don't seem to be any good X bindings so we have to mock up our own... (host, display) = os.getenv ('DISPLAY').split (':') if host == '': x_socket = socket.socket (socket.AF_UNIX, socket.SOCK_STREAM) x_socket.connect ('/tmp/.X11-unix/X%s' % display) else: x_socket = socket.socket (socket.AF_INET, socket.SOCK_STREAM) x_socket.connect ((host, 6000 + int (display))) authority = subprocess.check_output(['xauth', 'list']).split () auth_name = '' auth_data = '' if len (authority) >= 3: auth_name = authority[1] hex = authority[2] while len (hex) >= 2: auth_data += chr (int (hex[:2], 16)) hex = hex[2:] def pad (value): if len (value) % 4 != 0: return value + '\x00' * (4 - len (value) % 4) else: return value x_socket.send (struct.pack ('!cxHHHHxx', 'B', 11, 0, len (auth_name), len (auth_data)) + pad (auth_name) + pad (auth_data)) data = x_socket.recv (1024) if ord (data[0]) != 1: status_notify ('GREETER %s FAIL-CONNECT-XSERVER' % os.getenv ('DISPLAY')) exit (1) status_notify ('GREETER %s CONNECT-XSERVER' % (os.getenv ('DISPLAY'))) def show_message_cb (greeter, text, type): status_notify ('GREETER %s SHOW-MESSAGE TEXT=\"%s\"' % (os.getenv ('DISPLAY'), text)) def show_prompt_cb (greeter, text, type): status_notify ('GREETER %s SHOW-PROMPT TEXT=\"%s\"' % (os.getenv ('DISPLAY'), text)) def authentication_complete_cb (greeter): if greeter.get_is_authenticated (): is_authenticated = 'TRUE' else: is_authenticated = 'FALSE' if greeter.get_authentication_user () is not None: status_notify ('GREETER %s AUTHENTICATION-COMPLETE USERNAME=%s AUTHENTICATED=%s' % (os.getenv ('DISPLAY'), greeter.get_authentication_user (), is_authenticated)) else: status_notify ('GREETER %s AUTHENTICATION-COMPLETE AUTHENTICATED=%s' % (os.getenv ('DISPLAY'), is_authenticated)) def autologin_timer_expired_cb (greeter): status_notify ('GREETER %s AUTOLOGIN-TIMER-EXPIRED' % os.getenv ('DISPLAY')) greeter = LightDM.Greeter () greeter.connect ('show-message', show_message_cb) greeter.connect ('show-prompt', show_prompt_cb) greeter.connect ('authentication-complete', authentication_complete_cb) greeter.connect ('autologin-timer-expired', autologin_timer_expired_cb) status_notify ('GREETER %s CONNECT-TO-DAEMON' % os.getenv ('DISPLAY')) if not greeter.connect_sync (): status_notify ('GREETER %s FAIL-CONNECT-DAEMON' % os.getenv ('DISPLAY')) exit (1) status_notify ('GREETER %s CONNECTED-TO-DAEMON' % os.getenv ('DISPLAY')) if greeter.get_select_user_hint () is not None: status_notify ('GREETER %s SELECT-USER-HINT USERNAME=%s' % (os.getenv ('DISPLAY'), greeter.get_select_user_hint ())) if greeter.get_lock_hint (): status_notify ('GREETER %s LOCK-HINT' % os.getenv ('DISPLAY')); loop.run ()