Commit 85d80ba4 authored by Martín Ferrari's avatar Martín Ferrari

A little change in the protocol: the user name is passed as a separate and...

A little change in the protocol: the user name is passed as a separate and optional command. All the process-related functions trat the user as optional now.
parent 09f5b0fe
......@@ -19,7 +19,8 @@ ADDR DEL if# addr_spec 200/500 ip addr del
ROUT LIST 200 serialised data ip route list
ROUT ADD route_spec 200/500 ip route add
ROUT DEL route_spec 200/500 ip route del
PROC CRTE proc_params 200/500 (2)
PROC CRTE argv0 argv1... 200/500 (2)
PROC USER username 200/500 (3)
PROC CWD cwd 200/500 (3)
PROC ENV k v k v... 200/500 (3)
PROC SIN 354+200/500 (4)
......@@ -34,7 +35,6 @@ PROC KILL <pid> <signal> 200/500 kill(pid, signal)
(1) valid arguments: mtu <n>, state <up|down>, name <name>, lladdr <addr>
(2) After PROC CRTE, only secondary PROC cmds are accepted until finished.
Arguments are: user argv[0] argv[1] ...
The parameters are parsed as base64-encoded strings if they start with a '='
character.
......@@ -66,8 +66,10 @@ protocol exchanges occur through the socket.
<S> 200 Ok.
<C> ADDR DEL 10 192.168.1.1 24
<S> 500 Address does not exist.
<C> PROC CRTE root /bin/sh sh -c sleep 10
<C> PROC CRTE /bin/sh sh -c sleep 10
<S> 200 Entering PROC mode.
<C> PROC USER nobody
<S> 200 Program will run as `nobody'.
<C> PROC CWD /
<S> 200 CWD set to /.
<C> PROC SIN
......
......@@ -39,7 +39,7 @@ _proto_commands = {
"DEL": ("sisi", "")
},
"PROC": {
"CRTE": ("bb", "b*"),
"CRTE": ("b", "b*"),
"POLL": ("i", ""),
"WAIT": ("i", ""),
"KILL": ("i", "i")
......@@ -50,6 +50,7 @@ _proc_commands = {
"HELP": { None: ("", "") },
"QUIT": { None: ("", "") },
"PROC": {
"USER": ("b", ""),
"CWD": ("b", ""),
"ENV": ("bb", "b*"),
"SIN": ("", ""),
......@@ -246,14 +247,18 @@ class Server(object):
self.reply(221, "Sayounara.");
self.closed = True
def do_PROC_CRTE(self, cmdname, user, executable, *argv):
self._proc = { 'user': user, 'executable': executable, 'argv': argv }
def do_PROC_CRTE(self, cmdname, executable, *argv):
self._proc = { 'executable': executable, 'argv': argv }
self.commands = _proc_commands
self.reply(200, "Entering PROC mode.")
def do_PROC_USER(self, cmdname, user):
self._proc['user'] = user
self.reply(200, "Program will run as `%s'." % user)
def do_PROC_CWD(self, cmdname, dir):
self._proc['cwd'] = dir
self.reply(200, "CWD set to %s." % dir)
self.reply(200, "CWD set to `%s'." % dir)
def do_PROC_ENV(self, cmdname, *env):
if len(env) % 2:
......@@ -268,7 +273,7 @@ class Server(object):
def do_PROC_SIN(self, cmdname):
self.reply(354,
"Pass the file descriptor now, with '%s\\n' as payload." %
"Pass the file descriptor now, with `%s\\n' as payload." %
cmdname)
if cmdname == 'PROC SIN':
......@@ -416,15 +421,14 @@ class Client(object):
passfd.sendfd(self._fd, fd, "PROC " + type)
self._read_and_check_reply()
def spawn(self, user, executable, argv = None, cwd = None, env = None,
stdin = None, stdout = None, stderr = None):
def spawn(self, executable, argv = None, cwd = None, env = None,
stdin = None, stdout = None, stderr = None, user = None):
"""Start a subprocess in the slave; the interface resembles
subprocess.Popen, but with less functionality. In particular
stdin/stdout/stderr can only be None or a open file descriptor.
See netns.subprocess.spawn for details."""
params = ["PROC", "CRTE", base64.b64encode(user),
base64.b64encode(executable)]
params = ["PROC", "CRTE", base64.b64encode(executable)]
if argv != None:
for i in argv:
params.append(base64.b64encode(i))
......@@ -432,6 +436,10 @@ class Client(object):
self._send_cmd(*params)
self._read_and_check_reply()
if user != None:
self._send_cmd("PROC", "USER", base64.b64encode(user))
self._read_and_check_reply()
if cwd != None:
self._send_cmd("PROC", "CWD", base64.b64encode(cwd))
self._read_and_check_reply()
......
......@@ -3,8 +3,8 @@
import fcntl, grp, os, pickle, pwd, signal, sys, traceback
def spawn(user, executable, argv, cwd = None, env = None,
stdin = None, stdout = None, stderr = None):
def spawn(executable, argv = None, cwd = None, env = None,
stdin = None, stdout = None, stderr = None, user = None):
"""Forks and execs a program, with stdio redirection and user switching.
The program is specified by `executable', if it does not contain any slash,
the PATH environment variable is used to search for the file.
......
......@@ -57,6 +57,7 @@ class TestServer(unittest.TestCase):
check_error(self, "quit 1")
# Not allowed in normal mode
check_error(self, "proc user")
check_error(self, "proc sin")
check_error(self, "proc sout")
check_error(self, "proc serr")
......@@ -74,19 +75,19 @@ class TestServer(unittest.TestCase):
check_error(self, "proc poll 1 2") # too many args
check_error(self, "proc poll a") # invalid type
check_ok(self, "proc crte 0 /bin/sh", srv.do_PROC_CRTE,
[0, 0, '/bin/sh'])
check_ok(self, "proc crte /bin/sh", srv.do_PROC_CRTE,
['/bin/sh'])
# Commands that would fail, but the parsing is correct
check_ok(self, "proc poll 0", None, [0])
check_ok(self, "proc wait 0", None, [0])
check_ok(self, "proc kill 0", None, [0])
check_error(self, "proc crte 0 =") # empty b64
check_error(self, "proc crte 0 =a") # invalid b64
check_error(self, "proc crte =") # empty b64
check_error(self, "proc crte =a") # invalid b64
# simulate proc mode
srv.commands = netns.protocol._proc_commands
check_error(self, "proc crte 0 foo")
check_error(self, "proc crte foo")
check_error(self, "proc poll 0")
check_error(self, "proc wait 0")
check_error(self, "proc kill 0")
......
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