I\'m trying to run a command with paramiko that should be able to open an X window. The script I\'m using would something as follows:
import par
x11 request may use a MIT-MAGIC-COOKIE-1 that you may not handled properly.Xauthority file may also be an issuestrace ssh process and see a normal flowxterm with strace xterm and compare with the above.some links:
good luck.
EDIT: building on top of Gary's answer, with multiple x11 connections.
#!/usr/bin/env python
import os
import select
import sys
import getpass
import paramiko
import socket
import logging
import Xlib.support.connect as xlib_connect
LOGGER = logging.getLogger(__name__)
# connection settings
host = '192.168.122.55'
user = 'user'
password = getpass.getpass()
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_client.connect(host, username=user, password=password)
del password
# maintain map
# { fd: (channel, remote channel), ... }
channels = {}
poller = select.poll()
def x11_handler(channel, (src_addr, src_port)):
'''handler for incoming x11 connections
for each x11 incoming connection,
- get a connection to the local display
- maintain bidirectional map of remote x11 channel to local x11 channel
- add the descriptors to the poller
- queue the channel (use transport.accept())'''
x11_chanfd = channel.fileno()
local_x11_socket = xlib_connect.get_socket(*local_x11_display[:3])
local_x11_socket_fileno = local_x11_socket.fileno()
channels[x11_chanfd] = channel, local_x11_socket
channels[local_x11_socket_fileno] = local_x11_socket, channel
poller.register(x11_chanfd, select.POLLIN)
poller.register(local_x11_socket, select.POLLIN)
LOGGER.debug('x11 channel on: %s %s', src_addr, src_port)
transport._queue_incoming_channel(channel)
def flush_out(session):
while session.recv_ready():
sys.stdout.write(session.recv(4096))
while session.recv_stderr_ready():
sys.stderr.write(session.recv_stderr(4096))
# get local disply
local_x11_display = xlib_connect.get_display(os.environ['DISPLAY'])
# start x11 session
transport = ssh_client.get_transport()
session = transport.open_session()
session.request_x11(handler=x11_handler)
session.exec_command('xterm')
session_fileno = session.fileno()
poller.register(session_fileno, select.POLLIN)
# accept first remote x11 connection
transport.accept()
# event loop
while not session.exit_status_ready():
poll = poller.poll()
# accept subsequent x11 connections if any
if len(transport.server_accepts) > 0:
transport.accept()
if not poll: # this should not happen, as we don't have a timeout.
break
for fd, event in poll:
if fd == session_fileno:
flush_out(session)
# data either on local/remote x11 socket
if fd in channels.keys():
channel, counterpart = channels[fd]
try:
# forward data between local/remote x11 socket.
data = channel.recv(4096)
counterpart.sendall(data)
except socket.error:
channel.close()
counterpart.close()
del channels[fd]
print 'Exit status:', session.recv_exit_status()
flush_out(session)
session.close()