1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 """
20 L{ProxyCommand}.
21 """
22
23 import os
24 from shlex import split as shlsplit
25 import signal
26 from subprocess import Popen, PIPE
27
28 from paramiko.ssh_exception import ProxyCommandFailure
29
30
32 """
33 Wraps a subprocess running ProxyCommand-driven programs.
34
35 This class implements a the socket-like interface needed by the
36 L{Transport} and L{Packetizer} classes. Using this class instead of a
37 regular socket makes it possible to talk with a Popen'd command that will
38 proxy traffic between the client and a server hosted in another machine.
39 """
41 """
42 Create a new CommandProxy instance. The instance created by this
43 class can be passed as an argument to the L{Transport} class.
44
45 @param command_line: the command that should be executed and
46 used as the proxy.
47 @type command_line: str
48 """
49 self.cmd = shlsplit(command_line)
50 self.process = Popen(self.cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
51
52 - def send(self, content):
53 """
54 Write the content received from the SSH client to the standard
55 input of the forked command.
56
57 @param content: string to be sent to the forked command
58 @type content: str
59 """
60 try:
61 self.process.stdin.write(content)
62 except IOError, e:
63
64
65
66
67 raise BadProxyCommand(' '.join(self.cmd), e.strerror)
68 return len(content)
69
70 - def recv(self, size):
71 """
72 Read from the standard output of the forked program.
73
74 @param size: how many chars should be read
75 @type size: int
76
77 @return: the length of the read content
78 @rtype: int
79 """
80 try:
81 return os.read(self.process.stdout.fileno(), size)
82 except IOError, e:
83 raise BadProxyCommand(' '.join(self.cmd), e.strerror)
84
86 os.kill(self.process.pid, signal.SIGTERM)
87
92