Title: ForwardMachine: UnboundLocalError in cb_sni when crtfile/keyfile is provided - TLS interception completely broken with user certificates
## Summary
ForwardMachine with tls=True and user-provided crtfile/keyfile parameters is completely non-functional in Scapy 2.7.1. Every TLS connection attempt crashes silently with UnboundLocalError in the cb_sni callback, causing [SSL: CALLBACK_FAILED] on the client side.
## Affected version
Scapy 2.7.1 (released July 10, 2026) - scapy/fwdmachine.py line 398
## Root cause
In 'ForwardMachine.handler().cb_sni(), the variable passwordis only assigned inside theif self.crtfile is Nonebranch (self-signed mode). Whencrtfileis provided, theelsebranch runs but never assignspassword. Line 398 then references password` unconditionally in both branches:
if self.crtfile is None:
# SELF-SIGNED mode
...
password = os.urandom(32) # <-- only assigned here
...
else:
certfile = self.crtfile
keyfile = self.keyfile
# password is NEVER assigned here
sslcontext.load_cert_chain(certfile, keyfile, password=password) # line 398
# ^^^^^^^^
# UnboundLocalError when crtfile provided
## Reproduce
# Generate a test certificate
openssl req -x509 -newkey rsa:2048 -keyout /tmp/k.key -out /tmp/c.crt -days 1 -nodes -subj "/CN=test"
import threading, socket, ssl, time
from scapy.fwdmachine import ForwardMachine
from scapy.layers.http import HTTP
# Start a dummy TLS remote for cb_sni to connect to
def remote():
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ctx.load_cert_chain("/tmp/c.crt", "/tmp/k.key")
srv = socket.socket()
srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
srv.bind(("127.0.0.1", 19444))
srv.listen(5)
while True:
try:
conn, _ = srv.accept()
ctx.wrap_socket(conn, server_side=True).close()
except: pass
threading.Thread(target=remote, daemon=True).start()
**# Patch**
_getpeersock to use local dummy remote
def patched(self, dest, server_hostname=None):
s = socket.socket()
s.settimeout(3)
s.connect(("127.0.0.1", 19444))
return s
ForwardMachine._getpeersock = patched
def run():
fm = ForwardMachine(
mode=ForwardMachine.MODE.SERVER,
port=19443, cls=HTTP, tls=True,
crtfile="/tmp/c.crt",
keyfile="/tmp/k.key",
remote_address="127.0.0.1", timeout=3,
)
fm.run()
threading.Thread(target=run, daemon=True).start()
time.sleep(0.5)
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
s = socket.create_connection(("127.0.0.1", 19443), timeout=5)
ctx.wrap_socket(s, server_hostname="example.com")
## Actual output
Exception ignored in: <function ForwardMachine.handler..cb_sni at 0x...>
Traceback (most recent call last):
File ".../scapy/fwdmachine.py", line 398, in cb_sni
sslcontext.load_cert_chain(certfile, keyfile, password=password)
UnboundLocalError: cannot access local variable 'password' where it is not associated with a value
[SSL: CALLBACK_FAILED] callback failed (_ssl.c:1033)
## Fix
Add password = None in the else branch:
else:
certfile = self.crtfile
keyfile = self.keyfile
password = None # <-- add this line
## Additional notes
The self-signed mode works fine, but the custom cert path is broken. Happy to open a PR if that helps.
Scapy 2.7.1, Python 3.13, Kali Linux.
Title: ForwardMachine: UnboundLocalError in cb_sni when crtfile/keyfile is provided - TLS interception completely broken with user certificates
## Summary
ForwardMachinewithtls=Trueand user-providedcrtfile/keyfileparameters is completely non-functional in Scapy 2.7.1. Every TLS connection attempt crashes silently withUnboundLocalErrorin thecb_snicallback, causing[SSL: CALLBACK_FAILED]on the client side.## Affected version
Scapy 2.7.1 (released July 10, 2026) -
scapy/fwdmachine.pyline 398## Root cause
In 'ForwardMachine.handler().cb_sni()
, the variablepasswordis only assigned inside theif self.crtfile is Nonebranch (self-signed mode). Whencrtfileis provided, theelsebranch runs but never assignspassword. Line 398 then referencespassword` unconditionally in both branches:## Reproduce
## Actual output
Exception ignored in: <function ForwardMachine.handler..cb_sni at 0x...>
Traceback (most recent call last):
File ".../scapy/fwdmachine.py", line 398, in cb_sni
sslcontext.load_cert_chain(certfile, keyfile, password=password)
UnboundLocalError: cannot access local variable 'password' where it is not associated with a value
[SSL: CALLBACK_FAILED] callback failed (_ssl.c:1033)
## Fix
Add
password = Nonein theelsebranch:## Additional notes
The self-signed mode works fine, but the custom cert path is broken. Happy to open a PR if that helps.
Scapy 2.7.1, Python 3.13, Kali Linux.