Skip to content

Commit 5e6c7f7

Browse files
avoid running Process instances beacuse of a bug in python3.13 python/cpython#134381
1 parent 5b62eea commit 5e6c7f7

File tree

2 files changed

+48
-7
lines changed

2 files changed

+48
-7
lines changed

impacket/smbserver.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4887,9 +4887,10 @@ class SimpleSMBServer:
48874887
:param string configFile: a file with all the servers' configuration. If no file specified, this class will create the basic parameters needed to run. You will need to add your shares manually tho. See addShare() method
48884888
"""
48894889

4890-
def __init__(self, listenAddress='0.0.0.0', listenPort=445, configFile=''):
4890+
def __init__(self, listenAddress='0.0.0.0', listenPort=445, configFile='', smbserverclass=SMBSERVER):
48914891
if configFile != '':
4892-
self.__server = SMBSERVER((listenAddress, listenPort))
4892+
#self.__server = SMBSERVER((listenAddress, listenPort))
4893+
self.__server = smbserverclass((listenAddress, listenPort))
48934894
self.__server.processConfigFile(configFile)
48944895
self.__smbConfig = None
48954896
else:
@@ -4914,7 +4915,7 @@ def __init__(self, listenAddress='0.0.0.0', listenPort=445, configFile=''):
49144915
self.__smbConfig.set('IPC$', 'read only', 'yes')
49154916
self.__smbConfig.set('IPC$', 'share type', '3')
49164917
self.__smbConfig.set('IPC$', 'path', '')
4917-
self.__server = SMBSERVER((listenAddress, listenPort), config_parser=self.__smbConfig)
4918+
self.__server = smbserverclass((listenAddress, listenPort), config_parser=self.__smbConfig)
49184919
self.__server.processConfigFile()
49194920

49204921
# Now we have to register the MS-SRVS server. This specially important for
@@ -4926,6 +4927,9 @@ def __init__(self, listenAddress='0.0.0.0', listenPort=445, configFile=''):
49264927
self.__server.registerNamedPipe('srvsvc', ('127.0.0.1', self.__srvsServer.getListenPort()))
49274928
self.__server.registerNamedPipe('wkssvc', ('127.0.0.1', self.__wkstServer.getListenPort()))
49284929

4930+
def getServer(self):
4931+
return self.__server
4932+
49294933
def start(self):
49304934
self.__srvsServer.start()
49314935
self.__wkstServer.start()

tests/SMB_RPC/test_smbserver.py

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,36 @@
8383
from six import PY2, StringIO, BytesIO, b, assertRaisesRegex, assertCountEqual
8484

8585
from impacket.smb import SMB_DIALECT
86-
from impacket.smbserver import normalize_path, isInFileJail, SimpleSMBServer
86+
from impacket.smbserver import normalize_path, isInFileJail, SimpleSMBServer, SMBSERVER
8787
from impacket.smbconnection import SMBConnection, SessionError, compute_lmhash, compute_nthash
88+
from threading import Thread
8889

90+
import select
91+
import socket
92+
93+
class StoppableMixin():
94+
def serve_forever(self):
95+
self.must_serve = True
96+
self.timeout = 0.1
97+
98+
while self.must_serve:
99+
self.handle_request()
100+
101+
def close_request(self,request):
102+
if self.must_serve:
103+
request.close()
104+
105+
def get_request(self):
106+
timeout = 0.1
107+
while self.must_serve:
108+
_read,_,_ = select.select([self.socket],[],[],timeout)
109+
110+
if _read and self.must_serve:
111+
return self.socket.accept()
112+
raise socket.error
113+
114+
class SMBSERVERForTests(StoppableMixin,SMBSERVER):
115+
pass
89116

90117
class SMBServerUnitTests(unittest.TestCase):
91118
"""Unit tests for the SMBServer
@@ -214,7 +241,10 @@ def tearDown(self):
214241
self.stop_smbserver()
215242

216243
def get_smbserver(self, add_credential=True, add_share=True):
217-
smbserver = SimpleSMBServer(listenAddress=self.address, listenPort=int(self.port))
244+
#smbserver = SimpleSMBServerForTests(listenAddress=self.address, listenPort=int(self.port))
245+
# smbserver should be run in a host thread and also be able to be terminated in order to run several times
246+
# different configurations.
247+
smbserver = SimpleSMBServer(listenAddress=self.address, listenPort=int(self.port),smbserverclass=SMBSERVERForTests)
218248
if add_credential:
219249
smbserver.addCredential(self.username, 0, self.lmhash, self.nthash)
220250
if add_share:
@@ -232,18 +262,25 @@ def start_smbserver(self, server):
232262
"""Starts the SimpleSMBServer process.
233263
"""
234264
self.server = server
235-
self.server_process = Process(target=server.start)
265+
#self.server_process = Process(target=server.start)
266+
# avoid using Process beacuse of bug in python3.13 https://github.com/python/cpython/issues/134381
267+
# TODO: remove these changes once a bugfix gets backported.
268+
self.server_process = Thread(target=server.start)
269+
self.server_process.daemon = True
236270
self.server_process.start()
237271

238272
def stop_smbserver(self):
239273
"""Stops the SimpleSMBServer process and wait for insider threads to join.
240274
"""
241275
if self.server:
242276
self.server.stop()
277+
self.server.getServer().must_serve=False
243278
self.server = None
244279
if self.server_process:
245-
self.server_process.terminate()
280+
#self.server_process.terminate()
281+
#self.server_process._stop()
246282
sleep(0.1)
283+
self.server_process.join()
247284
self.server_process = None
248285

249286
def test_smbserver_login_valid(self):

0 commit comments

Comments
 (0)