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) ...@@ -27,6 +27,7 @@ PROC ENV k v k v... 200/500 (3)
PROC SIN 354+200/500 (4) PROC SIN 354+200/500 (4)
PROC SOUT 354+200/500 (4) PROC SOUT 354+200/500 (4)
PROC SERR 354+200/500 (4) PROC SERR 354+200/500 (4)
PROC X11 354+200/500 (4)
PROC RUN 200 <pid>/500 (5) PROC RUN 200 <pid>/500 (5)
PROC ABRT 200 (5) PROC ABRT 200 (5)
PROC POLL <pid> 200 <code>/450/500 check if process alive 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 = { ...@@ -58,6 +58,7 @@ _proc_commands = {
"SIN": ("", ""), "SIN": ("", ""),
"SOUT": ("", ""), "SOUT": ("", ""),
"SERR": ("", ""), "SERR": ("", ""),
"X11": ("", ""),
"RUN": ("", ""), "RUN": ("", ""),
"ABRT": ("", ""), "ABRT": ("", ""),
} }
...@@ -261,12 +262,13 @@ class Server(object): ...@@ -261,12 +262,13 @@ class Server(object):
self.reply(500, "Invalid payload: %s." % payload) self.reply(500, "Invalid payload: %s." % payload)
return 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._proc[m[cmdname]] = fd
self.reply(200, 'FD saved as %s.' % m[cmdname]) self.reply(200, 'FD saved as %s.' % m[cmdname])
# Same code for the three commands # 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): def do_PROC_RUN(self, cmdname):
params = self._proc params = self._proc
...@@ -470,6 +472,45 @@ class Client(object): ...@@ -470,6 +472,45 @@ class Client(object):
raise raise
self._read_and_check_reply() 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, def spawn(self, argv, executable = None,
stdin = None, stdout = None, stderr = None, stdin = None, stdout = None, stderr = None,
cwd = None, env = None, user = None): cwd = None, env = None, user = None):
...@@ -510,6 +551,8 @@ class Client(object): ...@@ -510,6 +551,8 @@ class Client(object):
self._send_fd("SOUT", stdout) self._send_fd("SOUT", stdout)
if stderr != None: if stderr != None:
self._send_fd("SERR", stderr) self._send_fd("SERR", stderr)
self._send_x11_fd()
except: except:
self._send_cmd("PROC", "ABRT") self._send_cmd("PROC", "ABRT")
self._read_and_check_reply() self._read_and_check_reply()
......
...@@ -253,7 +253,7 @@ def backticks_raise(node, args): ...@@ -253,7 +253,7 @@ def backticks_raise(node, args):
# Server-side code, called from netns.protocol.Server # Server-side code, called from netns.protocol.Server
def spawn(executable, argv = None, cwd = None, env = None, close_fds = False, 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 """Internal function that performs all the dirty work for Subprocess, Popen
and friends. This is executed in the slave process, directly from the and friends. This is executed in the slave process, directly from the
protocol.Server class. protocol.Server class.
...@@ -299,6 +299,13 @@ def spawn(executable, argv = None, cwd = None, env = None, close_fds = False, ...@@ -299,6 +299,13 @@ def spawn(executable, argv = None, cwd = None, env = None, close_fds = False,
pid = os.fork() pid = os.fork()
if pid == 0: # pragma: no cover if pid == 0: # pragma: no cover
# coverage doesn't seem to understand fork # 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: try:
# Set up stdio piping # Set up stdio piping
for i in range(3): for i in range(3):
...@@ -314,13 +321,18 @@ def spawn(executable, argv = None, cwd = None, env = None, close_fds = False, ...@@ -314,13 +321,18 @@ def spawn(executable, argv = None, cwd = None, env = None, close_fds = False,
if close_fds == True: if close_fds == True:
for i in xrange(3, MAXFD): for i in xrange(3, MAXFD):
if i != w: if i == w:
continue
if x11 is not None and i == x11:
continue
try: try:
os.close(i) os.close(i)
except: except:
pass pass
elif close_fds != False: elif close_fds != False:
for i in close_fds: for i in close_fds:
if x11 is not None and i == x11:
continue
os.close(i) os.close(i)
if user != None: 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