Commit 936dcd46 authored by Alina Quereilhac's avatar Alina Quereilhac

Attemp to connect to main namespace xserver from a child namespace.

parent e78d25e8
......@@ -27,6 +27,7 @@ PROC ENV k v k v... 200/500 (3)
PROC SIN 354+200/500 (4)
PROC SOUT 354+200/500 (4)
PROC SERR 354+200/500 (4)
PROC X11 354+200/500 (4)
PROC RUN 200 <pid>/500 (5)
PROC ABRT 200 (5)
PROC POLL <pid> 200 <code>/450/500 check if process alive
......
CFLAGS+=-fpic
LDFLAGS+=-ldl
all: libconnectwrapper.so
libconnectwrapper.so: connect.o
$(CC) $(LDFLAGS) -shared -o $@ $^
connect.o: connect.c
clean:
rm -f *.o 2>/dev/null
\ No newline at end of file
#define _GNU_SOURCE 1
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdbool.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
static int get_xfd (void)
{
char *env = getenv("NETNS_X11_FD");
if (env == 0)
{
return -1;
}
return atoi (env);
}
typedef int (*ConnectFunction) (int, const struct sockaddr *,
socklen_t);
int connect(int sockfd, const struct sockaddr *serv_addr,
socklen_t addrlen)
{
if (serv_addr->sa_family == AF_UNIX)
{
const struct sockaddr_un *sun = (const struct sockaddr_un *)serv_addr;
if (strcmp (sun->sun_path, "/tmp/.X11-unix/X0") == 0)
{
// this is an attempt to connect to the X server.
// intercept !
int xfd = get_xfd ();
fcntl (xfd, F_SETFD, 0);
int status = dup2 (xfd, sockfd);
status = close (xfd);
return 0;
}
}
// lookup the symbol named connect in the next library
// in the name lookup scope of the dynamic loader
void *symbol = dlsym (RTLD_NEXT, "connect");
if (symbol == 0)
{
return -1;
}
ConnectFunction connect_function = (ConnectFunction) symbol;
int status = connect_function (sockfd, serv_addr, addrlen);
return status;
}
......@@ -58,6 +58,7 @@ _proc_commands = {
"SIN": ("", ""),
"SOUT": ("", ""),
"SERR": ("", ""),
"X11": ("", ""),
"RUN": ("", ""),
"ABRT": ("", ""),
}
......@@ -261,12 +262,13 @@ class Server(object):
self.reply(500, "Invalid payload: %s." % payload)
return
m = {'PROC SIN': 'stdin', 'PROC SOUT': 'stdout', 'PROC SERR': 'stderr'}
m = {'PROC SIN': 'stdin', 'PROC SOUT': 'stdout', 'PROC SERR': 'stderr',
'PROC X11': 'x11'}
self._proc[m[cmdname]] = fd
self.reply(200, 'FD saved as %s.' % m[cmdname])
# Same code for the three commands
do_PROC_SOUT = do_PROC_SERR = do_PROC_SIN
do_PROC_SOUT = do_PROC_SERR = do_PROC_X11 = do_PROC_SIN
def do_PROC_RUN(self, cmdname):
params = self._proc
......@@ -470,6 +472,45 @@ class Client(object):
raise
self._read_and_check_reply()
def _create_x_socket(self):
import os
import socket
import re
if not os.environ.has_key('DISPLAY'):
use_unix = True
display = '0'
else:
disp = os.environ['DISPLAY']
m = re.match('([^:]+)(:([0-9]+))?', disp)
if m is None:
use_unix = True
display = '0'
else:
host = m.group(1)
display = m.group(3)
if host == 'unix':
use_unix = True
else:
use_unix = False
if display is None:
display = '0'
try:
if use_unix:
fd = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
fd.connect('/tmp/.X11-unix/X' + display)
else:
fd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port = 6000 + int(display)
fd.connect((host, port))
return fd
except:
return None
def _send_x11_fd(self):
fd = self._create_x_socket()
if fd is not None:
self._send_fd('X11', fd.fileno())
def spawn(self, argv, executable = None,
stdin = None, stdout = None, stderr = None,
cwd = None, env = None, user = None):
......@@ -510,6 +551,8 @@ class Client(object):
self._send_fd("SOUT", stdout)
if stderr != None:
self._send_fd("SERR", stderr)
self._send_x11_fd()
except:
self._send_cmd("PROC", "ABRT")
self._read_and_check_reply()
......
......@@ -253,7 +253,7 @@ def backticks_raise(node, args):
# Server-side code, called from netns.protocol.Server
def spawn(executable, argv = None, cwd = None, env = None, close_fds = False,
stdin = None, stdout = None, stderr = None, user = None):
stdin = None, stdout = None, stderr = None, user = None, x11 = None):
"""Internal function that performs all the dirty work for Subprocess, Popen
and friends. This is executed in the slave process, directly from the
protocol.Server class.
......@@ -299,6 +299,13 @@ def spawn(executable, argv = None, cwd = None, env = None, close_fds = False,
pid = os.fork()
if pid == 0: # pragma: no cover
# coverage doesn't seem to understand fork
if x11 is not None:
if env is None:
env = {}
env['DISPLAY'] = 'unix:0'
env['LD_PRELOAD'] = 'src/lib/libconnectwrapper.so'
env['NETNS_X11_FD'] = str(x11)
try:
# Set up stdio piping
for i in range(3):
......@@ -314,13 +321,18 @@ def spawn(executable, argv = None, cwd = None, env = None, close_fds = False,
if close_fds == True:
for i in xrange(3, MAXFD):
if i != w:
try:
os.close(i)
except:
pass
if i == w:
continue
if x11 is not None and i == x11:
continue
try:
os.close(i)
except:
pass
elif close_fds != False:
for i in close_fds:
if x11 is not None and i == x11:
continue
os.close(i)
if user != None:
......
#!/usr/bin/env python
# vim:ts=4:sw=4:et:ai:sts=4
import netns
import os
netns.environ.set_log_level(netns.environ.LOG_DEBUG)
n = netns.Node()
err = file('/tmp/out_y', 'wb')
a = n.Popen(['xterm'], stderr = err)
a.wait()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment