Skip to content

Commit 247be54

Browse files
committed
changed stdin to not run in a thread as it wasn't needed
1 parent b252876 commit 247be54

File tree

3 files changed

+53
-75
lines changed

3 files changed

+53
-75
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,10 @@ commands;
138138

139139
```
140140
# PowerShell (Windows 8 and Server 2012 or Newer)
141-
New-NetFirewallRule -Name SMB -DisplayName "SMB Inbound" -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 445
141+
Set-NetFirewallRule -Name FPS-SMB-In-TCP -Enabled True
142142
143143
# CMD (All OS's)
144-
netsh advfirewall firewall add rule name=SMB dir=in action=allow protocol=TCP localport=445
144+
netsh advfirewall firewall set rule name="File and Printer Sharing (SMB-In)" dir=in new enable=Yes
145145
```
146146

147147
This will open up inbound traffic to port `445` which is used by SMB.

pypsexec/client.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,6 @@ def run_executable(self, executable, arguments=None, processors=None,
334334
stderr_pipe = stderr(smb_tree, self._stderr_pipe_name)
335335
stderr_pipe.start()
336336
stdin_pipe = InputPipe(smb_tree, self._stdin_pipe_name)
337-
stdin_pipe.start()
338337

339338
# wait until the stdout and stderr pipes have sent their first
340339
# response
@@ -349,12 +348,12 @@ def run_executable(self, executable, arguments=None, processors=None,
349348
if stdin and isinstance(stdin, bytes):
350349
log.info("Sending stdin bytes over stdin pipe: %s"
351350
% self._stdin_pipe_name)
352-
stdin_pipe.pipe_buffer.put(stdin)
351+
stdin_pipe.write(stdin)
353352
elif stdin:
354353
log.info("Sending stdin generator bytes over stdin pipe: %s"
355354
% self._stdin_pipe_name)
356355
for stdin_data in stdin():
357-
stdin_pipe.pipe_buffer.put(stdin_data)
356+
stdin_pipe.write(stdin_data)
358357

359358
# read the final response from the process
360359
log.info("Reading result of PAExec process")

pypsexec/pipe.py

Lines changed: 49 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import binascii
21
import logging
3-
import os
42
import sys
53
import threading
64
import warnings
@@ -19,11 +17,6 @@
1917
except ImportError: # pragma: no cover
2018
from ordereddict import OrderedDict
2119

22-
if sys.version[0] == '2':
23-
from Queue import Queue
24-
else:
25-
from queue import Queue
26-
2720
log = logging.getLogger(__name__)
2821

2922

@@ -108,84 +101,66 @@ def __init__(self):
108101
super(FSCTLPipeWait, self).__init__()
109102

110103

111-
class _NamedPipe(threading.Thread):
112-
113-
ACCESS_MASK = 0
104+
class InputPipe(object):
114105

115106
def __init__(self, tree, name):
116-
super(_NamedPipe, self).__init__()
117-
log.info("Initialising Named Pipe with the name: %s" % name)
107+
"""
108+
Thin wrapper around an input Named Pipe. This isn't run in a thread
109+
and any data sent to write is written to the Named Pipe.
110+
111+
:param tree: The SMB tree connected to IPC$
112+
:param name: The name of the input Named Pipe
113+
"""
114+
log.info("Initialising Input Named Pipe with the name: %s" % name)
118115
self.name = name
119116
self.connection = tree.session.connection
120117
self.sid = tree.session.session_id
121118
self.tid = tree.tree_connect_id
122119
self.pipe = open_pipe(tree, name,
123-
self.ACCESS_MASK,
120+
FilePipePrinterAccessMask.FILE_WRITE_DATA |
121+
FilePipePrinterAccessMask.FILE_APPEND_DATA |
122+
FilePipePrinterAccessMask.FILE_WRITE_EA |
123+
FilePipePrinterAccessMask.FILE_WRITE_ATTRIBUTES |
124+
FilePipePrinterAccessMask.FILE_READ_ATTRIBUTES |
125+
FilePipePrinterAccessMask.READ_CONTROL |
126+
FilePipePrinterAccessMask.SYNCHRONIZE,
124127
fsctl_wait=True)
125128

126-
def _close_thread(self):
127-
self.join(timeout=5)
128-
if self.is_alive():
129-
warnings.warn("Timeout while waiting for pipe thread to close: %s"
130-
% self.name, TheadCloseTimeoutWarning)
131-
132-
133-
class InputPipe(_NamedPipe):
134-
135-
ACCESS_MASK = FilePipePrinterAccessMask.FILE_WRITE_DATA | \
136-
FilePipePrinterAccessMask.FILE_APPEND_DATA | \
137-
FilePipePrinterAccessMask.FILE_WRITE_EA | \
138-
FilePipePrinterAccessMask.FILE_WRITE_ATTRIBUTES | \
139-
FilePipePrinterAccessMask.FILE_READ_ATTRIBUTES | \
140-
FilePipePrinterAccessMask.READ_CONTROL | \
141-
FilePipePrinterAccessMask.SYNCHRONIZE
142-
143-
def __init__(self, tree, name):
144-
super(InputPipe, self).__init__(tree, name)
145-
self.pipe_buffer = Queue()
146-
self.close_bytes = os.urandom(16)
147-
log.debug("Shutdown bytes for input pipe: %s"
148-
% binascii.hexlify(self.close_bytes))
149-
self.pipe_buffer = Queue()
150-
151-
def run(self):
152-
try:
153-
log.debug("Starting thread of Input Named Pipe: %s" % self.name)
154-
while True:
155-
log.debug("Waiting for input for %s" % self.name)
156-
input_data = self.pipe_buffer.get()
157-
log.debug("Input for %s was found: %s"
158-
% (self.name, binascii.hexlify(input_data)))
159-
if input_data == self.close_bytes:
160-
log.debug("Close bytes was received for input pipe: %s"
161-
% self.name)
162-
break
163-
164-
log.debug("Writing bytes to Input Named Pipe: %s" % self.name)
165-
self.pipe.write(input_data, 0)
166-
finally:
167-
log.debug("Closing SMB Open to Input Named Pipe: %s" % self.name)
168-
self.pipe.close(get_attributes=False)
169-
log.debug("Input Named Pipe %s thread finished" % self.name)
129+
def write(self, data):
130+
log.info("Sending bytes to Input Named Pipe: %s" % self.name)
131+
self.pipe.write(data, 0)
170132

171133
def close(self):
172134
log.info("Closing Input Named Pipe: %s" % self.name)
173-
log.debug("Send shutdown bytes to Input Named Pipe: %s" % self.name)
174-
self.pipe_buffer.put(self.close_bytes)
175-
self._close_thread()
176-
135+
self.pipe.close(get_attributes=False)
177136

178-
class OutputPipe(with_metaclass(ABCMeta, _NamedPipe)):
179137

180-
ACCESS_MASK = FilePipePrinterAccessMask.FILE_READ_DATA | \
181-
FilePipePrinterAccessMask.FILE_READ_ATTRIBUTES | \
182-
FilePipePrinterAccessMask.FILE_READ_EA | \
183-
FilePipePrinterAccessMask.READ_CONTROL | \
184-
FilePipePrinterAccessMask.SYNCHRONIZE
138+
class OutputPipe(with_metaclass(ABCMeta, threading.Thread)):
185139

186140
def __init__(self, tree, name):
187-
"""Generic Output/Read Pipe that stores the output read in a Queue"""
188-
super(OutputPipe, self).__init__(tree, name)
141+
"""
142+
Base class for an Output/Read pipe that reads the output from a Named
143+
Pipe in a separate thread and sends that data to the handle_output
144+
method defined by the implementation class. This should not be used
145+
directly, i.e. use OutputPipeBytes instead which returns the Named
146+
Pipe output as a byte string.
147+
148+
:param tree: The SMB tree connected to IPC$
149+
:param name: The name of the output Named Pipe
150+
"""
151+
super(OutputPipe, self).__init__()
152+
log.info("Initialising Output Named Pipe with the name: %s" % name)
153+
self.name = name
154+
self.connection = tree.session.connection
155+
self.sid = tree.session.session_id
156+
self.tid = tree.tree_connect_id
157+
self.pipe = open_pipe(tree, name,
158+
FilePipePrinterAccessMask.FILE_READ_DATA |
159+
FilePipePrinterAccessMask.FILE_READ_ATTRIBUTES |
160+
FilePipePrinterAccessMask.FILE_READ_EA |
161+
FilePipePrinterAccessMask.READ_CONTROL |
162+
FilePipePrinterAccessMask.SYNCHRONIZE,
163+
fsctl_wait=True)
189164
self.sent_first = False
190165

191166
def run(self):
@@ -253,12 +228,16 @@ def get_output(self):
253228

254229
def close(self):
255230
log.info("Closing Output Named Pipe: %s" % self.name)
256-
self._close_thread()
231+
self.join(timeout=5)
232+
if self.is_alive():
233+
warnings.warn("Timeout while waiting for pipe thread to close: %s"
234+
% self.name, TheadCloseTimeoutWarning)
257235

258236

259237
class OutputPipeBytes(OutputPipe):
260238

261239
def __init__(self, tree, name):
240+
""" An impl of OuputPipe that stores the output buffer as bytes"""
262241
self.pipe_buffer = b""
263242
super(OutputPipeBytes, self).__init__(tree, name)
264243

0 commit comments

Comments
 (0)