Jim Carroll
2016-01-15 01:12:47 UTC
We've been experimenting with creating an SSH virtual server for Windows
based on conch. We've made good process, but we've run into a problem
running child processes (children of spawnProcess()), in that stdout does
not make it back to the client.
I can demonstrate the problem using the example ptyserv.py script with a
slight change for Windows. Here's the code to demonstrate the problem:
from twisted.internet import reactor, protocol
class FakeTelnet(protocol.Protocol):
commandToRun = ['c:\\Windows\\System32\\cmd.exe']
def connectionMade(self):
print 'connection made'
self.propro = ProcessProtocol(self)
reactor.spawnProcess(self.propro, self.commandToRun[0],
self.commandToRun, os.environ)
def dataReceived(self, data):
self.propro.transport.write(data)
def conectionLost(self, reason):
print 'connection lost'
self.propro.tranport.loseConnection()
class ProcessProtocol(protocol.ProcessProtocol):
def __init__(self, pr):
self.pr = pr
def outReceived(self, data):
self.pr.transport.write(data)
def processEnded(self, reason):
print 'protocol connection lost'
self.pr.transport.loseConnection()
f = protocol.Factory()
f.protocol = FakeTelnet
reactor.listenTCP(5823, f)
reactor.run()
Run the above code on Windows, and telnet to localhost 5823.
After you get the CMD.exe prompt, try to launch python. This is what you'll
see:
Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.
C:\Temp>python
python
That's it. Hitting enter just drops down to another next blank line.
Now what's interesting is that writes to stdin of the spawned CMD.exe get
there. You can see this by pressing <CTRL>-D. The python subprocess will
exit and you'll still be connected to your telnet session, now back at the
CMD.exe prompt.
I've experimented with modifying twisted.internet._dumbwin32proc.py so that
the DuplicateHandle() calls (lines 147 - 163) are not called, thinking that
inheritance was the cause, but no-go. I've also tried adding calls to
msvcrt.set_mode() to os.O_BINARY to make sure windows isn't somehow cooking
the child processes output, but that had no effect either.
I've been banging my head against this for a week and I've reached a stuck
point. I was wondering if someone could point me towards where I'm going
wrong. Any advice would be appreciated....
FYI - once we get this worked out, we'd be happy to share the code.
Thanks
Jim C.
based on conch. We've made good process, but we've run into a problem
running child processes (children of spawnProcess()), in that stdout does
not make it back to the client.
I can demonstrate the problem using the example ptyserv.py script with a
slight change for Windows. Here's the code to demonstrate the problem:
from twisted.internet import reactor, protocol
class FakeTelnet(protocol.Protocol):
commandToRun = ['c:\\Windows\\System32\\cmd.exe']
def connectionMade(self):
print 'connection made'
self.propro = ProcessProtocol(self)
reactor.spawnProcess(self.propro, self.commandToRun[0],
self.commandToRun, os.environ)
def dataReceived(self, data):
self.propro.transport.write(data)
def conectionLost(self, reason):
print 'connection lost'
self.propro.tranport.loseConnection()
class ProcessProtocol(protocol.ProcessProtocol):
def __init__(self, pr):
self.pr = pr
def outReceived(self, data):
self.pr.transport.write(data)
def processEnded(self, reason):
print 'protocol connection lost'
self.pr.transport.loseConnection()
f = protocol.Factory()
f.protocol = FakeTelnet
reactor.listenTCP(5823, f)
reactor.run()
Run the above code on Windows, and telnet to localhost 5823.
After you get the CMD.exe prompt, try to launch python. This is what you'll
see:
Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.
C:\Temp>python
python
That's it. Hitting enter just drops down to another next blank line.
Now what's interesting is that writes to stdin of the spawned CMD.exe get
there. You can see this by pressing <CTRL>-D. The python subprocess will
exit and you'll still be connected to your telnet session, now back at the
CMD.exe prompt.
I've experimented with modifying twisted.internet._dumbwin32proc.py so that
the DuplicateHandle() calls (lines 147 - 163) are not called, thinking that
inheritance was the cause, but no-go. I've also tried adding calls to
msvcrt.set_mode() to os.O_BINARY to make sure windows isn't somehow cooking
the child processes output, but that had no effect either.
I've been banging my head against this for a week and I've reached a stuck
point. I was wondering if someone could point me towards where I'm going
wrong. Any advice would be appreciated....
FYI - once we get this worked out, we'd be happy to share the code.
Thanks
Jim C.