Example #1
0
def pactl_output(log_errors=True, *pactl_args):
    pactl_bin = get_pactl_bin()
    if not pactl_bin:
        return -1, None, None
    #ie: "pactl list"
    cmd = [pactl_bin] + list(pactl_args)
    #force "C" locale so that we can parse the output as expected
    env = os.environ.copy()
    env["LC_ALL"] = "C"
    try:
        import subprocess
        log("running %s", cmd)
        process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
        from xpra.child_reaper import getChildReaper
        procinfo = getChildReaper().add_process(process, "pactl", cmd, True, True)
        log("waiting for %s output", cmd)
        out, err = process.communicate()
        getChildReaper().add_dead_process(procinfo)
        code = process.poll()
        log("pactl_output%s returned %s", pactl_args, code)
        return  code, out, err
    except Exception as e:
        if log_errors:
            log.error("failed to execute %s: %s", cmd, e)
        else:
            log("failed to execute %s: %s", cmd, e)
        return  -1, None, None
Example #2
0
 def do_process_challenge_prompt(self, packet, prompt="password"):
     authlog("do_process_challenge_prompt() use_tty=%s", use_tty())
     if use_tty():
         import getpass
         authlog("stdin isatty, using password prompt")
         password = getpass.getpass("%s :" %
                                    self.get_challenge_prompt(prompt))
         authlog("password read from tty via getpass: %s", obsc(password))
         self.send_challenge_reply(packet, password)
         return True
     else:
         from xpra.platform.paths import get_nodock_command
         cmd = get_nodock_command() + ["_pass", prompt]
         try:
             from subprocess import Popen, PIPE
             proc = Popen(cmd, stdout=PIPE)
             getChildReaper().add_process(proc, "password-prompt", cmd,
                                          True, True)
             out, err = proc.communicate(None, 60)
             authlog("err(%s)=%s", cmd, err)
             password = out.decode()
             self.send_challenge_reply(packet, password)
             return True
         except Exception:
             log("Error: failed to show GUi for password prompt",
                 exc_info=True)
     return False
def pactl_output(log_errors=True, *pactl_args):
    pactl_bin = get_pactl_bin()
    if not pactl_bin:
        return -1, None, None
    #ie: "pactl list"
    cmd = [pactl_bin] + list(pactl_args)
    #force "C" locale so that we can parse the output as expected
    env = os.environ.copy()
    env["LC_ALL"] = "C"
    try:
        import subprocess
        log("running %s", cmd)
        process = subprocess.Popen(cmd,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   env=env)
        from xpra.child_reaper import getChildReaper
        procinfo = getChildReaper().add_process(process, "pactl", cmd, True,
                                                True)
        log("waiting for %s output", cmd)
        out, err = process.communicate()
        getChildReaper().add_dead_process(procinfo)
        code = process.poll()
        log("pactl_output%s returned %s", pactl_args, code)
        return code, out, err
    except Exception as e:
        if log_errors:
            log.error("failed to execute %s: %s", cmd, e)
        else:
            log("failed to execute %s: %s", cmd, e)
        return -1, None, None
Example #4
0
 def exec_subprocess(self):
     kwargs = exec_kwargs()
     env = self.get_env()
     log("exec_subprocess() command=%s, env=%s, kwargs=%s", self.command, env, kwargs)
     proc = subprocess.Popen(self.command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, env=env, **kwargs)
     getChildReaper().add_process(proc, self.description, self.command, True, True, callback=self.subprocess_exit)
     return proc
Example #5
0
 def setup_connection(self, conn):
     netlog("setup_connection(%s) timeout=%s, socktype=%s", conn, conn.timeout, conn.socktype)
     if conn.socktype=="udp":
         from xpra.net.udp_protocol import UDPClientProtocol
         self._protocol = UDPClientProtocol(self.get_scheduler(), conn, self.process_packet, self.next_packet)
         #use a random uuid:
         import random
         self._protocol.uuid = random.randint(0, 2**64-1)
         self.set_packet_handlers(self._packet_handlers, {
             "udp-control"   : self._process_udp_control,
             })
     else:
         self._protocol = Protocol(self.get_scheduler(), conn, self.process_packet, self.next_packet)
     for x in (b"keymap-changed", b"server-settings", b"logging", b"input-devices"):
         self._protocol.large_packets.append(x)
     self._protocol.set_compression_level(self.compression_level)
     self._protocol.receive_aliases.update(self._aliases)
     self._protocol.enable_default_encoder()
     self._protocol.enable_default_compressor()
     if self.encryption and ENCRYPT_FIRST_PACKET:
         key = self.get_encryption_key()
         self._protocol.set_cipher_out(self.encryption, DEFAULT_IV, key, DEFAULT_SALT, DEFAULT_ITERATIONS, INITIAL_PADDING)
     self.have_more = self._protocol.source_has_more
     if conn.timeout>0:
         self.timeout_add((conn.timeout + EXTRA_TIMEOUT) * 1000, self.verify_connected)
     process = getattr(conn, "process", None)        #ie: ssh is handled by anotherprocess
     if process:
         proc, name, command = process
         if proc:
             getChildReaper().add_process(proc, name, command, ignore=True, forget=False)
     netlog("setup_connection(%s) protocol=%s", conn, self._protocol)
Example #6
0
 def show_notify(self, dbus_id, tray, nid, app_name, replaces_nid, app_icon,
                 summary, body, actions, hints, expire_timeout, icon):
     from xpra.platform.darwin import osx_notifier
     osx_notifier_file = osx_notifier.__file__
     if osx_notifier_file.endswith("pyc"):
         osx_notifier_file = osx_notifier_file[:-1]
     import time
     #osx_notifier_file = "/Users/osx/osx_notifier.py"
     from xpra.platform.paths import get_app_dir
     base = get_app_dir()
     #python_bin = "/usr/bin/python"
     python_bin = os.path.join(base, "Resources", "bin", "python")
     cmd = [
         python_bin, osx_notifier_file,
         "%s-%s" % (int(time.time()), nid), summary, body
     ]
     from xpra.child_reaper import getChildReaper
     import subprocess
     env = os.environ.copy()
     for x in ("DYLD_LIBRARY_PATH", "XDG_CONFIG_DIRS", "XDG_DATA_DIRS",
               "GTK_DATA_PREFIX", "GTK_EXE_PREFIX", "GTK_PATH",
               "GTK2_RC_FILES", "GTK_IM_MODULE_FILE",
               "GDK_PIXBUF_MODULE_FILE", "PANGO_RC_FILE", "PANGO_LIBDIR",
               "PANGO_SYSCONFDIR", "CHARSETALIASDIR", "GST_BUNDLE_CONTENTS",
               "PYTHON", "PYTHONHOME", "PYTHONPATH"):
         if x in env:
             del env[x]
     notifylog("running %s with env=%s", cmd, env)
     proc = subprocess.Popen(cmd, env=env)
     proc.wait()
     notifylog("returned %i", proc.poll())
     getChildReaper().add_process(proc, "notifier-%s" % nid, cmd, True,
                                  True)
Example #7
0
 def exec_subprocess(self):
     kwargs = exec_kwargs()
     env = self.get_env()
     log("exec_subprocess() command=%s, env=%s, kwargs=%s", self.command, env, kwargs)
     proc = subprocess.Popen(self.command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=sys.stderr.fileno(), env=env, **kwargs)
     getChildReaper().add_process(proc, self.description, self.command, True, True, callback=self.subprocess_exit)
     return proc
Example #8
0
 def setup_connection(self, conn):
     netlog("setup_connection(%s) timeout=%s", conn, conn.timeout)
     self._protocol = Protocol(self.get_scheduler(), conn,
                               self.process_packet, self.next_packet)
     self._protocol.large_packets.append("keymap-changed")
     self._protocol.large_packets.append("server-settings")
     self._protocol.large_packets.append("logging")
     self._protocol.large_packets.append("input-devices")
     self._protocol.set_compression_level(self.compression_level)
     self._protocol.receive_aliases.update(self._aliases)
     self._protocol.enable_default_encoder()
     self._protocol.enable_default_compressor()
     if self.encryption and ENCRYPT_FIRST_PACKET:
         key = self.get_encryption_key()
         self._protocol.set_cipher_out(self.encryption, DEFAULT_IV, key,
                                       DEFAULT_SALT, DEFAULT_ITERATIONS,
                                       INITIAL_PADDING)
     self.have_more = self._protocol.source_has_more
     if conn.timeout > 0:
         self.timeout_add((conn.timeout + EXTRA_TIMEOUT) * 1000,
                          self.verify_connected)
     process = getattr(conn, "process",
                       None)  #ie: ssh is handled by anotherprocess
     if process:
         proc, name, command = process
         getChildReaper().add_process(proc,
                                      name,
                                      command,
                                      ignore=True,
                                      forget=False)
     netlog("setup_connection(%s) protocol=%s", conn, self._protocol)
Example #9
0
 def show_downloads(self, _btn):
     downloads = os.path.expanduser(get_download_dir())
     if WIN32:
         os.startfile(downloads) #@UndefinedVariable pylint: disable=no-member
         return
     if OSX:
         cmd = ["open", downloads]
     else:
         cmd = ["xdg-open", downloads]
     proc = subprocess.Popen(cmd)
     getChildReaper().add_process(proc, "show-downloads", cmd, ignore=True, forget=True)
Example #10
0
 def new_stream(self, sound_source, codec):
     if NEW_STREAM_SOUND:
         try:
             from xpra.platform.paths import get_resources_dir
             sample = os.path.join(get_resources_dir(), "bell.wav")
             log("new_stream(%s, %s) sample=%s, exists=%s", sound_source,
                 codec, sample, os.path.exists(sample))
             if os.path.exists(sample):
                 if POSIX:
                     sink = "alsasink"
                 else:
                     sink = "autoaudiosink"
                 cmd = [
                     "gst-launch-1.0", "-q", "filesrc",
                     "location=%s" % sample, "!", "decodebin", "!",
                     "audioconvert", "!", sink
                 ]
                 import subprocess
                 proc = subprocess.Popen(cmd, close_fds=True)
                 log("Popen(%s)=%s", cmd, proc)
                 from xpra.child_reaper import getChildReaper
                 getChildReaper().add_process(proc,
                                              "new-stream-sound",
                                              cmd,
                                              ignore=True,
                                              forget=True)
         except Exception:
             pass
     log("new_stream(%s, %s)", sound_source, codec)
     if self.sound_source != sound_source:
         log(
             "dropping new-stream signal (current source=%s, signal source=%s)",
             self.sound_source, sound_source)
         return
     codec = codec or sound_source.codec
     sound_source.codec = codec
     #tell the client this is the start:
     self.send(
         "sound-data", codec, "", {
             "start-of-stream": True,
             "codec": codec,
             "sequence": sound_source.sequence,
         })
     update_av_sync = getattr(self, "update_av_sync_delay_total", None)
     if update_av_sync:
         update_av_sync()  #pylint: disable=not-callable
         #run it again after 10 seconds,
         #by that point the source info will actually be populated:
         if PYTHON3:
             from gi.repository import GLib as glib
         else:
             import glib
         glib.timeout_add(10 * 1000, update_av_sync)
Example #11
0
 def defaults_init(self):
     #skip warning when running the client
     from xpra import child_reaper
     child_reaper.POLL_WARNING = False
     getChildReaper()
     log("XpraClientBase.defaults_init() os.environ:")
     for k,v in os.environ.items():
         log(" %s=%s", k, nonl(v))
     #client state:
     self.exit_code = None
     self.exit_on_signal = False
     self.display_desc = {}
     #connection attributes:
     self.hello_extra = {}
     self.compression_level = 0
     self.display = None
     self.username = None
     self.password = None
     self.password_file = None
     self.password_sent = False
     self.bandwidth_limit = 0
     self.encryption = None
     self.encryption_keyfile = None
     self.server_padding_options = [DEFAULT_PADDING]
     self.quality = -1
     self.min_quality = 0
     self.speed = 0
     self.min_speed = -1
     self.printer_attributes = []
     self.send_printers_timer = None
     self.exported_printers = None
     self.can_shutdown_server = True
     #protocol stuff:
     self._protocol = None
     self._priority_packets = []
     self._ordinary_packets = []
     self._mouse_position = None
     self._aliases = {}
     self._reverse_aliases = {}
     #server state and caps:
     self.server_capabilities = None
     self.completed_startup = False
     self._remote_machine_id = None
     self._remote_uuid = None
     self._remote_version = None
     self._remote_revision = None
     self._remote_platform = None
     self._remote_platform_release = None
     self._remote_platform_platform = None
     self._remote_platform_linux_distribution = None
     self.uuid = get_user_uuid()
     self.init_packet_handlers()
     sanity_checks()
Example #12
0
 def defaults_init(self):
     #skip warning when running the client
     from xpra import child_reaper
     child_reaper.POLL_WARNING = False
     getChildReaper()
     log("XpraClientBase.defaults_init() os.environ:")
     for k,v in os.environ.items():
         log(" %s=%r", k, v)
     #client state:
     self.exit_code = None
     self.exit_on_signal = False
     self.display_desc = {}
     self.progress_process = None
     self.progress_timer = None
     #connection attributes:
     self.hello_extra = {}
     self.compression_level = 0
     self.display = None
     self.challenge_handlers = []
     self.username = None
     self.password = None
     self.password_file = ()
     self.password_index = 0
     self.password_sent = False
     self.encryption = None
     self.encryption_keyfile = None
     self.server_padding_options = [DEFAULT_PADDING]
     self.server_client_shutdown = True
     self.server_compressors = []
     #protocol stuff:
     self._protocol = None
     self._priority_packets = []
     self._ordinary_packets = []
     self._mouse_position = None
     self._mouse_position_pending = None
     self._mouse_position_send_time = 0
     self._mouse_position_delay = MOUSE_DELAY
     self._mouse_position_timer = 0
     self._aliases = {}
     #server state and caps:
     self.connection_established = False
     self.completed_startup = False
     self.uuid = get_user_uuid()
     self.session_id = uuid.uuid4().hex
     self.init_packet_handlers()
     def noop():
         """
         until we hook up the real protocol instance,
         do nothing when have_more() is called
         """
     self.have_more = noop
Example #13
0
    def defaults_init(self):
        # skip warning when running the client
        from xpra import child_reaper

        child_reaper.POLL_WARNING = False
        getChildReaper()
        log("XpraClientBase.defaults_init() os.environ:")
        for k, v in os.environ.items():
            log(" %s=%s", k, nonl(v))
        # client state:
        self.exit_code = None
        self.exit_on_signal = False
        self.display_desc = {}
        # connection attributes:
        self.hello_extra = {}
        self.compression_level = 0
        self.display = None
        self.username = None
        self.password = None
        self.password_file = None
        self.password_sent = False
        self.encryption = None
        self.encryption_keyfile = None
        self.server_padding_options = [DEFAULT_PADDING]
        self.quality = -1
        self.min_quality = 0
        self.speed = 0
        self.min_speed = -1
        self.printer_attributes = []
        self.send_printers_timer = None
        self.exported_printers = None
        # protocol stuff:
        self._protocol = None
        self._priority_packets = []
        self._ordinary_packets = []
        self._mouse_position = None
        self._aliases = {}
        self._reverse_aliases = {}
        # server state and caps:
        self.server_capabilities = None
        self._remote_machine_id = None
        self._remote_uuid = None
        self._remote_version = None
        self._remote_revision = None
        self._remote_platform = None
        self._remote_platform_release = None
        self._remote_platform_platform = None
        self._remote_platform_linux_distribution = None
        self.uuid = get_user_uuid()
        self.init_packet_handlers()
        sanity_checks()
Example #14
0
def get_lpinfo_drv(make_and_model):
    if not LPINFO:
        log.error("Error: lpinfo command is not defined")
        return None
    command = shlex.split(LPINFO) + ["--make-and-model", make_and_model, "-m"]
    log("get_lpinfo_drv(%s) command=%s", make_and_model, command)
    try:
        proc = Popen(command, stdout=PIPE, stderr=PIPE, start_new_session=True)
    except Exception as e:
        log("get_lp_info_drv(%s) lpinfo command %s failed",
            make_and_model,
            command,
            exc_info=True)
        log.error("Error: lpinfo command failed to run")
        log.error(" %s", e)
        log.error(" command used: '%s'", " ".join(command))
        return None
    #use the global child reaper to make sure this doesn't end up as a zombie
    from xpra.child_reaper import getChildReaper
    cr = getChildReaper()
    cr.add_process(proc, "lpinfo", command, ignore=True, forget=True)
    from xpra.make_thread import start_thread

    def watch_lpinfo():
        #give it 15 seconds to run:
        for _ in range(15):
            if proc.poll() is not None:
                return  #finished already
            time.sleep(1)
        if proc.poll() is not None:
            return
        log.warn("Warning: lpinfo command is taking too long,")
        log.warn(" is the cups server running?")
        try:
            proc.terminate()
        except Exception as e:
            log("%s.terminate()", proc, exc_info=True)
            log.error("Error: failed to terminate lpinfo command")
            log.error(" %s", e)

    start_thread(watch_lpinfo, "lpinfo watcher", daemon=True)
    out, err = proc.communicate()
    if proc.wait() != 0:
        log.warn("Warning: lpinfo command failed and returned %s",
                 proc.returncode)
        log.warn(" command used: '%s'", " ".join(command))
        return None
    try:
        out = out.decode()
    except Exception:
        out = str(out)
    log("lpinfo out=%r", out)
    log("lpinfo err=%r", err)
    if err:
        log.warn("Warning: lpinfo command produced some warnings:")
        log.warn(" %r", err)
    for line in out.splitlines():
        if line.startswith("drv://"):
            return line.split(" ")[0]
    return None
Example #15
0
def exec_lpadmin(args):
    command = shlex.split(LPADMIN) + args

    def preexec():
        os.setsid()

    log("exec_lpadmin(%s) command=%s", args, command)
    proc = subprocess.Popen(command,
                            stdin=None,
                            stdout=None,
                            stderr=None,
                            shell=False,
                            close_fds=True,
                            preexec_fn=preexec)
    #use the global child reaper to make sure this doesn't end up as a zombie
    from xpra.child_reaper import getChildReaper
    cr = getChildReaper()

    def check_returncode(proc):
        returncode = proc.returncode
        if returncode is not None and returncode != 0:
            log.warn("lpadmin failed and returned error code: %s", returncode)
            log.warn(
                "you may want to check that this user has the required permissions for using this command"
            )

    cr.add_process(proc,
                   "lpadmin",
                   command,
                   ignore=True,
                   forget=True,
                   callback=check_returncode)
    assert proc.poll() in (None, 0)
Example #16
0
def exec_lpadmin(args, success_cb=None):
    command = shlex.split(LPADMIN) + args
    log("exec_lpadmin(%s) command=%s", args, command)
    proc = Popen(command, start_new_session=True)
    #use the global child reaper to make sure this doesn't end up as a zombie
    from xpra.child_reaper import getChildReaper
    cr = getChildReaper()

    def check_returncode(_proc_cb):
        returncode = proc.poll()
        log("returncode(%s)=%s", command, returncode)
        if returncode != 0:
            log.warn("lpadmin failed and returned error code: %s", returncode)
            from xpra.platform import get_username
            log.warn(" verify that user '%s' has all the required permissions",
                     get_username())
            log.warn(" for running: '%s'", LPADMIN)
            log.warn(" full command: %s",
                     " ".join("'%s'" % x for x in command))
        elif success_cb:
            success_cb()

    cr.add_process(proc,
                   "lpadmin",
                   command,
                   ignore=True,
                   forget=True,
                   callback=check_returncode)
    if proc.poll() not in (None, 0):
        raise Exception("lpadmin command '%s' failed and returned %s" %
                        (command, proc.poll()))
Example #17
0
 def authenticate(self, _challenge_response=None, _client_salt=None):
     info = "Connection request from %s" % self.connection_str
     cmd = [self.command, info, str(self.timeout)]
     self.proc = Popen(cmd, close_fds=True, shell=False)
     log("authenticate(..) Popen(%s)=%s", cmd, self.proc)
     #if required, make sure we kill the command when it times out:
     if self.timeout > 0:
         self.timer = glib.timeout_add(self.timeout * 1000,
                                       self.command_timedout)
         getChildReaper().add_process(self.proc, "exec auth", cmd, True,
                                      True, self.command_ended)
     v = self.proc.wait()
     log("authenticate(..) returncode(%s)=%s", cmd, v)
     if self.timeout and self.timeout_event:
         return False
     return v == 0
Example #18
0
    def exec_open_command(self, url):
        filelog("exec_open_command(%s)", url)
        try:
            import shlex
            command = shlex.split(self.open_command) + [url]
        except ImportError as e:
            filelog("exec_open_command(%s) no shlex: %s", url, e)
            command = self.open_command.split(" ")
        filelog("exec_open_command(%s) command=%s", url, command)
        try:
            proc = subprocess.Popen(command,
                                    env=self.get_open_env(),
                                    shell=WIN32)
        except Exception as e:
            filelog("exec_open_command(%s)", url, exc_info=True)
            filelog.error("Error: cannot open '%s': %s", url, e)
            return
        filelog("exec_open_command(%s) Popen(%s)=%s", url, command, proc)

        def open_done(*_args):
            returncode = proc.poll()
            filelog("open_file: command %s has ended, returncode=%s", command,
                    returncode)
            if returncode != 0:
                filelog.warn("Warning: failed to open the downloaded content")
                filelog.warn(" '%s' returned %s", " ".join(command),
                             returncode)

        cr = getChildReaper()
        cr.add_process(proc, "Open file %s" % url, command, True, True,
                       open_done)
Example #19
0
def get_lpinfo_drv(make_and_model):
    command = shlex.split(LPINFO) + ["--make-and-model", make_and_model, "-m"]

    def preexec():
        os.setsid()

    log("get_lpinfo_drv(%s) command=%s", make_and_model, command)
    try:
        proc = subprocess.Popen(
            command,
            stdin=None,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            shell=False,
            close_fds=True,
            preexec_fn=preexec,
        )
    except Exception as e:
        log("get_lp_info_drv(%s) lpinfo command %s failed", make_and_model, command, exc_info=True)
        log.error("Error: lpinfo command failed to run")
        log.error(" %s", e)
        log.error(" command used: '%s'", " ".join(command))
        return None
    # use the global child reaper to make sure this doesn't end up as a zombie
    from xpra.child_reaper import getChildReaper
    from xpra.util import nonl

    cr = getChildReaper()
    cr.add_process(proc, "lpinfo", command, ignore=True, forget=True)
    from xpra.make_thread import make_thread

    def watch_lpinfo():
        # give it 15 seconds to run:
        for _ in range(15):
            if proc.poll() is not None:
                return  # finished already
            time.sleep(1)
        log.warn("Warning: lpinfo command is taking too long")
        proc.terminate()

    make_thread(watch_lpinfo, "lpinfo watcher", daemon=True).start()
    out, err = proc.communicate()
    if proc.wait() != 0:
        log.warn("Warning: lpinfo command failed and returned %s", proc.returncode)
        log.warn(" command used: '%s'", " ".join(command))
        return None
    if sys.version_info[0] >= 3:
        try:
            out = out.decode()
        except:
            out = str(out)
    log("lpinfo out=%s", nonl(out))
    log("lpinfo err=%s", nonl(err))
    if err:
        log.warn("Warning: lpinfo command produced some warnings:")
        log.warn(" '%s'", nonl(err))
    for line in out.splitlines():
        if line.startswith("drv://"):
            return line.split(" ")[0]
    return None
Example #20
0
def exec_lpadmin(args, success_cb=None):
    command = shlex.split(LPADMIN) + args

    def preexec():
        os.setsid()

    log("exec_lpadmin(%s) command=%s", args, command)
    proc = subprocess.Popen(
        command, stdin=None, stdout=None, stderr=None, shell=False, close_fds=True, preexec_fn=preexec
    )
    # use the global child reaper to make sure this doesn't end up as a zombie
    from xpra.child_reaper import getChildReaper

    cr = getChildReaper()

    def check_returncode(proc_cb):
        returncode = proc.poll()
        log("returncode(%s)=%s", command, returncode)
        if returncode != 0:
            log.warn("lpadmin failed and returned error code: %s", returncode)
            from xpra.platform import get_username

            log.warn(" verify that user '%s' has all the required permissions", get_username())
            log.warn(" for running: '%s'", LPADMIN)
        elif success_cb:
            success_cb()

    cr.add_process(proc, "lpadmin", command, ignore=True, forget=True, callback=check_returncode)
    if proc.poll() not in (None, 0):
        raise Exception("lpadmin command '%s' failed and returned %s" % (command, proc.poll()))
Example #21
0
    def __init__(self, options, title="Xpra Session Browser"):
        gtk.Window.__init__(self)
        self.exit_code = 0
        self.set_title(title)
        self.set_border_width(20)
        self.set_resizable(True)
        self.set_decorated(True)
        icon = self.get_pixbuf("xpra")
        if icon:
            self.set_icon(icon)
        add_close_accel(self, self.quit)
        self.connect("delete_event", self.quit)

        self.child_reaper = getChildReaper()

        self.vbox = gtk.VBox(False, 20)
        self.add(self.vbox)

        title_label = gtk.Label(title)
        title_label.modify_font(pango.FontDescription("sans 14"))
        self.vbox.add(title_label)

        self.warning = gtk.Label(" ")
        red = color_parse("red")
        self.warning.modify_fg(STATE_NORMAL, red)
        self.vbox.add(self.warning)

        hbox = gtk.HBox(False, 10)
        al = gtk.Alignment(xalign=1, yalign=0.5)
        al.add(gtk.Label("Password:"******""
        #log.info("options=%s (%s)", options, type(options))
        self.local_info_cache = {}
        self.dotxpra = DotXpra(options.socket_dir, options.socket_dirs,
                               username)
        self.poll_local_sessions()
        glib.timeout_add(5 * 1000, self.poll_local_sessions)
        self.populate_table()

        import signal
        signal.signal(signal.SIGINT, self.app_signal)
        signal.signal(signal.SIGTERM, self.app_signal)
        self.show_all()
Example #22
0
 def show_downloads(self, _btn):
     downloads = os.path.expanduser(get_download_dir())
     if WIN32:
         os.startfile(downloads) #@UndefinedVariable pylint: disable=no-member
         return
     if OSX:
         cmd = ["open", downloads]
     else:
         cmd = ["xdg-open", downloads]
     try:
         proc = subprocess.Popen(cmd)
     except Exception as e:
         log("show_downloads()", exc_info=True)
         log.error("Error: failed to open 'Downloads' folder:")
         log.error(" %s", e)
     else:
         getChildReaper().add_process(proc, "show-downloads", cmd, ignore=True, forget=True)
Example #23
0
    def do_test_child_reaper(self):
        #force reset singleton:
        child_reaper.singleton = None
        #no-op:
        reaper_cleanup()

        log.logger.setLevel(logging.ERROR)
        cr = getChildReaper()
        #one that exits before we add the process, one that takes longer:
        TEST_CHILDREN = (["echo"], ["sleep", "0.5"])
        count = 0
        for cmd in TEST_CHILDREN:
            cmd_info = " ".join(cmd)
            proc = subprocess.Popen(cmd)
            cr.add_process(proc, cmd_info, cmd_info, False, False, None)
            count += 1
            for _ in range(10):
                if not cr.check():
                    break
                time.sleep(0.1)
            #we can't check the returncode because it may not be set yet!
            #assert proc.poll() is not None, "%s process did not terminate?" % cmd_info
            assert cr.check() is False, "reaper did not notice that the '%s' process has terminated" % cmd_info
            i = cr.get_info()
            children = i.get("children").get("total")
            assert children==count, "expected %s children recorded, but got %s" % (count, children)

        #now check for the forget option:
        proc = subprocess.Popen(["sleep", "60"])
        procinfo = cr.add_process(proc, "sleep 60", "sleep 60", False, True, None)
        assert repr(procinfo)
        count +=1
        assert cr.check() is True, "sleep process terminated too quickly"
        i = cr.get_info()
        children = i.get("children").get("total")
        assert children==count, "expected %s children recorded, but got %s" % (count, children)
        #trying to claim it is dead when it is not:
        #(this will print some warnings)
        cr.add_dead_pid(proc.pid)
        proc.terminate()
        #now wait for the sleep process to exit:
        for _ in range(10):
            if proc.poll() is not None:
                break
            time.sleep(0.1)
        assert proc.poll() is not None
        assert cr.check() is False, "sleep process did not terminate?"
        count -= 1
        i = cr.get_info()
        children = i.get("children").get("total")
        if children!=count:
            raise Exception("expected the sleep process to have been forgotten (%s children)" % count +
            "but got %s children instead in the reaper records" % children)
        reaper_cleanup()
        #can run again:
        reaper_cleanup()
        #nothing for an invalid pid:
        assert cr.get_proc_info(-1) is None
Example #24
0
 def new_stream(self, sound_source, codec):
     if NEW_STREAM_SOUND:
         try:
             from xpra.platform.paths import get_resources_dir
             sample = os.path.join(get_resources_dir(), "bell.wav")
             log("new_stream(%s, %s) sample=%s, exists=%s", sound_source,
                 codec, sample, os.path.exists(sample))
             if os.path.exists(sample):
                 if POSIX:
                     sink = "alsasink"
                 else:
                     sink = "autoaudiosink"
                 cmd = [
                     "gst-launch-1.0", "-q", "filesrc",
                     "location=%s" % sample, "!", "decodebin", "!",
                     "audioconvert", "!", sink
                 ]
                 import subprocess
                 proc = subprocess.Popen(cmd, close_fds=True)
                 log("Popen(%s)=%s", cmd, proc)
                 from xpra.child_reaper import getChildReaper
                 getChildReaper().add_process(proc,
                                              "new-stream-sound",
                                              cmd,
                                              ignore=True,
                                              forget=True)
         except:
             pass
     log("new_stream(%s, %s)", sound_source, codec)
     if self.sound_source != sound_source:
         log(
             "dropping new-stream signal (current source=%s, signal source=%s)",
             self.sound_source, sound_source)
         return
     codec = codec or sound_source.codec
     sound_source.codec = codec
     #tell the client this is the start:
     self.send(
         "sound-data", codec, "", {
             "start-of-stream": True,
             "codec": codec,
             "sequence": sound_source.sequence,
         })
     self.update_av_sync_delay_total()
Example #25
0
 def defaults_init(self):
     #skip warning when running the client
     from xpra import child_reaper
     child_reaper.POLL_WARNING = False
     getChildReaper()
     log("XpraClientBase.defaults_init() os.environ:")
     for k,v in os.environ.items():
         log(" %s=%s", k, nonl(v))
     #client state:
     self.exit_code = None
     self.exit_on_signal = False
     self.display_desc = {}
     #connection attributes:
     self.hello_extra = {}
     self.compression_level = 0
     self.display = None
     self.challenge_handlers = OrderedDict()
     self.username = None
     self.password = None
     self.password_file = ()
     self.password_index = 0
     self.password_sent = False
     self.encryption = None
     self.encryption_keyfile = None
     self.server_padding_options = [DEFAULT_PADDING]
     self.server_client_shutdown = True
     self.server_compressors = []
     #protocol stuff:
     self._protocol = None
     self._priority_packets = []
     self._ordinary_packets = []
     self._mouse_position = None
     self._mouse_position_pending = None
     self._mouse_position_send_time = 0
     self._mouse_position_delay = MOUSE_DELAY
     self._mouse_position_timer = 0
     self._aliases = {}
     self._reverse_aliases = {}
     #server state and caps:
     self.server_capabilities = None
     self.completed_startup = False
     self.uuid = get_user_uuid()
     self.init_packet_handlers()
     sanity_checks()
Example #26
0
 def defaults_init(self):
     getChildReaper()
     log("XpraClientBase.defaults_init() os.environ:")
     for k, v in os.environ.items():
         log(" %s=%s", k, nonl(v))
     #client state:
     self.exit_code = None
     self.exit_on_signal = False
     #connection attributes:
     self.compression_level = 0
     self.display = None
     self.username = None
     self.password_file = None
     self.password_sent = False
     self.encryption = None
     self.encryption_keyfile = None
     self.server_padding_options = [DEFAULT_PADDING]
     self.quality = -1
     self.min_quality = 0
     self.speed = 0
     self.min_speed = -1
     self.printer_attributes = []
     self.send_printers_pending = False
     self.exported_printers = None
     #protocol stuff:
     self._protocol = None
     self._priority_packets = []
     self._ordinary_packets = []
     self._mouse_position = None
     self._aliases = {}
     self._reverse_aliases = {}
     #server state and caps:
     self.server_capabilities = None
     self._remote_machine_id = None
     self._remote_uuid = None
     self._remote_version = None
     self._remote_revision = None
     self._remote_platform = None
     self._remote_platform_release = None
     self._remote_platform_platform = None
     self._remote_platform_linux_distribution = None
     self.uuid = get_user_uuid()
     self.init_packet_handlers()
     sanity_checks()
Example #27
0
 def init(self, opts):
     log("ProxyServer.init(%s)", opts)
     self.video_encoders = opts.video_encoders
     self.csc_modules = opts.csc_modules
     ServerCore.init(self, opts)
     #ensure we cache the platform info before intercepting SIGCHLD
     #as this will cause a fork and SIGCHLD to be emitted:
     from xpra.version_util import get_platform_info
     get_platform_info()
     self.child_reaper = getChildReaper()
Example #28
0
 def authenticate(self, _challenge_response=None, _client_salt=None):
     info = "Connection request from %s" % self.connection_str
     cmd = [self.command, info, str(self.timeout)]
     proc = Popen(cmd, close_fds=True, shell=False)
     self.proc = proc
     log("authenticate(..) Popen(%s)=%s", cmd, proc)
     #if required, make sure we kill the command when it times out:
     if self.timeout>0:
         self.timer = glib.timeout_add(self.timeout*1000, self.command_timedout)
         if not OSX:
             #python on macos may set a 0 returncode when we use poll()
             #so we cannot use the ChildReaper on macos,
             #and we can't cancel the timer
             getChildReaper().add_process(proc, "exec auth", cmd, True, True, self.command_ended)
     v = proc.wait()
     log("authenticate(..) returncode(%s)=%s", cmd, v)
     if self.timeout_event:
         return False
     return v==0
Example #29
0
 def authenticate(self, caps : typedict) -> bool:
     info = "Connection request from %s" % self.connection_str
     cmd = [self.command, info, str(self.timeout)]
     with Popen(cmd) as proc:
         self.proc = proc
         log("authenticate(..) Popen(%s)=%s", cmd, proc)
         #if required, make sure we kill the command when it times out:
         if self.timeout>0:
             self.timer = GLib.timeout_add(self.timeout*1000, self.command_timedout)
             if not OSX:
                 #python on macos may set a 0 returncode when we use poll()
                 #so we cannot use the ChildReaper on macos,
                 #and we can't cancel the timer
                 getChildReaper().add_process(proc, "exec auth", cmd, True, True, self.command_ended)
     v = proc.returncode
     log("authenticate(..) returncode(%s)=%s", cmd, v)
     if self.timeout_event:
         return False
     return v==0
Example #30
0
 def init(self, opts):
     log("ProxyServer.init(%s)", opts)
     self.pings = int(opts.pings)
     self.video_encoders = opts.proxy_video_encoders
     self._start_sessions = opts.proxy_start_sessions
     super().init(opts)
     #ensure we cache the platform info before intercepting SIGCHLD
     #as this will cause a fork and SIGCHLD to be emitted:
     from xpra.version_util import get_platform_info
     get_platform_info()
     self.child_reaper = getChildReaper()
Example #31
0
 def init(self, opts):
     log("ProxyServer.init(%s)", opts)
     self.video_encoders = opts.proxy_video_encoders
     self.csc_modules = opts.csc_modules
     self._start_sessions = opts.proxy_start_sessions
     ServerCore.init(self, opts)
     #ensure we cache the platform info before intercepting SIGCHLD
     #as this will cause a fork and SIGCHLD to be emitted:
     from xpra.version_util import get_platform_info
     get_platform_info()
     self.child_reaper = getChildReaper()
Example #32
0
 def init(self, opts):
     log("ProxyServer.init(%s)", opts)
     if not opts.tcp_auth:
         raise InitException("The proxy server requires an authentication mode (use 'none' to disable authentication)")
     self.video_encoders = opts.video_encoders
     self.csc_modules = opts.csc_modules
     ServerCore.init(self, opts)
     #ensure we cache the platform info before intercepting SIGCHLD
     #as this will cause a fork and SIGCHLD to be emitted:
     from xpra.version_util import get_platform_info
     get_platform_info()
     self.child_reaper = getChildReaper()
Example #33
0
 def init(self, opts):
     log("ProxyServer.init(%s)", opts)
     if not opts.tcp_auth:
         raise InitException(
             "The proxy server requires an authentication mode (use 'none' to disable authentication)"
         )
     self.video_encoders = opts.video_encoders
     self.csc_modules = opts.csc_modules
     ServerCore.init(self, opts)
     #ensure we cache the platform info before intercepting SIGCHLD
     #as this will cause a fork and SIGCHLD to be emitted:
     from xpra.version_util import get_platform_info
     get_platform_info()
     self.child_reaper = getChildReaper()
Example #34
0
 def setup_connection(self, conn):
     netlog("setup_connection(%s) timeout=%s", conn, conn.timeout)
     self._protocol = Protocol(self.get_scheduler(), conn, self.process_packet, self.next_packet)
     self._protocol.large_packets.append("keymap-changed")
     self._protocol.large_packets.append("server-settings")
     self._protocol.large_packets.append("logging")
     self._protocol.set_compression_level(self.compression_level)
     self._protocol.receive_aliases.update(self._aliases)
     self._protocol.enable_default_encoder()
     self._protocol.enable_default_compressor()
     if self.encryption and ENCRYPT_FIRST_PACKET:
         key = self.get_encryption_key()
         self._protocol.set_cipher_out(
             self.encryption, DEFAULT_IV, key, DEFAULT_SALT, DEFAULT_ITERATIONS, INITIAL_PADDING
         )
     self.have_more = self._protocol.source_has_more
     if conn.timeout > 0:
         self.timeout_add((conn.timeout + EXTRA_TIMEOUT) * 1000, self.verify_connected)
     process = getattr(conn, "process", None)  # ie: ssh is handled by anotherprocess
     if process:
         proc, name, command = process
         getChildReaper().add_process(proc, name, command, ignore=True, forget=False)
     netlog("setup_connection(%s) protocol=%s", conn, self._protocol)
Example #35
0
 def init(self, opts):
     self.exit_with_children = opts.exit_with_children
     self.terminate_children = opts.terminate_children
     self.start_new_commands = opts.start_new_commands
     self.start_commands = opts.start
     self.start_child_commands = opts.start_child
     self.start_after_connect = opts.start_after_connect
     self.start_child_after_connect = opts.start_child_after_connect
     self.start_on_connect = opts.start_on_connect
     self.start_child_on_connect = opts.start_child_on_connect
     if opts.exec_wrapper:
         import shlex
         self.exec_wrapper = shlex.split(opts.exec_wrapper)
     self.child_reaper = getChildReaper()
     self.start_env = parse_env(opts.start_env)
Example #36
0
def exec_lpadmin(args):
    command = shlex.split(LPADMIN)+args
    def preexec():
        os.setsid()
    log("exec_lpadmin(%s) command=%s", args, command)
    proc = subprocess.Popen(command, stdin=None, stdout=None, stderr=None, shell=False, close_fds=True, preexec_fn=preexec)
    #use the global child reaper to make sure this doesn't end up as a zombie
    from xpra.child_reaper import getChildReaper
    cr = getChildReaper()
    def check_returncode(proc):
        returncode = proc.returncode
        if returncode is not None and returncode!=0:
            log.warn("lpadmin failed and returned error code: %s", returncode)
            log.warn("you may want to check that this user has the required permissions for using this command")
    cr.add_process(proc, "lpadmin", command, ignore=True, forget=True, callback=check_returncode)
    assert proc.poll() in (None, 0)
Example #37
0
 def _open_file(self, filename):
     if not self.open_files:
         filelog.warn("Warning: opening files automatically is disabled,")
         filelog.warn(" ignoring uploaded file:")
         filelog.warn(" '%s'", filename)
         return
     command = shlex.split(self.open_command)+[filename]
     proc = subprocess.Popen(command)
     cr = getChildReaper()
     def open_done(*args):
         returncode = proc.poll()
         filelog("open_done: command %s has ended, returncode=%s", command, returncode)
         if returncode!=0:
             filelog.warn("Warning: failed to open the downloaded file")
             filelog.warn(" '%s %s' returned %s", self.open_command, filename, returncode)
     cr.add_process(proc, "Open File %s" % filename, command, True, True, open_done)
Example #38
0
def get_lpinfo_drv(make_and_model):
    command = shlex.split(LPINFO)+["--make-and-model", make_and_model, "-m"]
    def preexec():
        os.setsid()
    log("get_lpinfo_drv(%s) command=%s", make_and_model, command)
    try:
        proc = subprocess.Popen(command, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, close_fds=True, preexec_fn=preexec)
    except Exception as e:
        log("get_lp_info_drv(%s) lpinfo command %s failed", make_and_model, command, exc_info=True)
        log.error("Error: lpinfo command failed to run")
        log.error(" %s", e)
        log.error(" command used: '%s'", " ".join(command))
        return None
    #use the global child reaper to make sure this doesn't end up as a zombie
    from xpra.child_reaper import getChildReaper
    from xpra.util import nonl
    cr = getChildReaper()
    cr.add_process(proc, "lpinfo", command, ignore=True, forget=True)
    from xpra.make_thread import make_thread
    def watch_lpinfo():
        #give it 15 seconds to run:
        for _ in range(15):
            if proc.poll() is not None:
                return      #finished already
            time.sleep(1)
        log.warn("Warning: lpinfo command is taking too long")
        proc.terminate()
    make_thread(watch_lpinfo, "lpinfo watcher", daemon=True).start()
    out, err = proc.communicate()
    if proc.wait()!=0:
        log.warn("Warning: lpinfo command failed and returned %s", proc.returncode)
        log.warn(" command used: '%s'", " ".join(command))
        return None
    if sys.version_info[0]>=3:
        try:
            out = out.decode()
        except:
            out = str(out)
    log("lpinfo out=%s", nonl(out))
    log("lpinfo err=%s", nonl(err))
    if err:
        log.warn("Warning: lpinfo command produced some warnings:")
        log.warn(" '%s'", nonl(err))
    for line in out.splitlines():
        if line.startswith("drv://"):
            return line.split(" ")[0]
    return None
Example #39
0
    def test_sigchld(self):
        import logging
        log.logger.setLevel(logging.ERROR)
        cr = getChildReaper()
        #one that exits before we add the process, one that takes longer:
        TEST_CHILDREN = (["echo"], ["sleep", "0.5"])
        count = 0
        for cmd in TEST_CHILDREN:
            cmd_info = " ".join(cmd)
            proc = subprocess.Popen(cmd)
            cr.add_process(proc, cmd_info, cmd_info, False, False, None)
            count += 1
            for _ in range(10):
                if not cr.check():
                    break
                time.sleep(0.1)
            #we can't check the returncode because it may not be set yet!
            #assert proc.poll() is not None, "%s process did not terminate?" % cmd_info
            assert cr.check() is False, "reaper did not notice that the '%s' process has terminated" % cmd_info
            i = cr.get_info()
            children = i.get("children").get("total")
            assert children==count, "expected %s children recorded, but got %s" % (count, children)

        #now check for the forget option:
        proc = subprocess.Popen(["sleep", "60"])
        cr.add_process(proc, "sleep 60", "sleep 60", False, True, None)
        count +=1
        assert cr.check() is True, "sleep process terminated too quickly"
        i = cr.get_info()
        children = i.get("children").get("total")
        assert children==count, "expected %s children recorded, but got %s" % (count, children)
        proc.terminate()
        #now wait for the sleep process to exit:
        for _ in range(10):
            if proc.poll() is not None:
                break
            time.sleep(0.1)
        assert proc.poll() is not None
        assert cr.check() is False, "sleep process did not terminate?"
        count -= 1
        i = cr.get_info()
        children = i.get("children").get("total")
        assert children==count, "expected the sleep process to have been forgotten (%s children), but got %s children instead in the reaper records" % (count, children)
        reaper_cleanup()
Example #40
0
def get_lpinfo_drv(make_and_model):
    command = shlex.split(LPINFO) + ["--make-and-model", make_and_model, "-m"]

    def preexec():
        os.setsid()

    log("get_lpinfo_drv(%s) command=%s", make_and_model, command)
    proc = subprocess.Popen(
        command,
        stdin=None,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        shell=False,
        close_fds=True,
        preexec_fn=preexec,
    )
    # use the global child reaper to make sure this doesn't end up as a zombie
    from xpra.child_reaper import getChildReaper
    from xpra.util import nonl

    cr = getChildReaper()
    cr.add_process(proc, "lpinfo", command, ignore=True, forget=True)
    out, err = proc.communicate()
    if proc.wait() != 0:
        log.warn("Warning: lpinfo command failed and returned %s", proc.returncode)
        log.warn(" command used: '%s'", command)
        return None
    if sys.version_info[0] >= 3:
        try:
            out = out.decode()
        except:
            out = str(out)
    log("lpinfo out=%s", nonl(out))
    log("lpinfo err=%s", nonl(err))
    if err:
        log.warn("Warning: lpinfo command produced some warnings:")
        log.warn(" '%s'", nonl(err))
    for line in out.splitlines():
        if line.startswith("drv://"):
            return line.split(" ")[0]
    return None
Example #41
0
    def _open_file(self, filename):
        if not self.open_files:
            filelog.warn("Warning: opening files automatically is disabled,")
            filelog.warn(" ignoring uploaded file:")
            filelog.warn(" '%s'", filename)
            return
        command = shlex.split(self.open_command) + [filename]
        proc = subprocess.Popen(command)
        cr = getChildReaper()

        def open_done(*_args):
            returncode = proc.poll()
            filelog("open_done: command %s has ended, returncode=%s", command,
                    returncode)
            if returncode != 0:
                filelog.warn("Warning: failed to open the downloaded file")
                filelog.warn(" '%s %s' returned %s", self.open_command,
                             filename, returncode)

        cr.add_process(proc, "Open File %s" % filename, command, True, True,
                       open_done)