-
Notifications
You must be signed in to change notification settings - Fork 0
restore drop unknown client optin #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1217,7 +1217,6 @@ def __init__( | |
| self.coin = self.env.coin | ||
| self.client_longname = 'unknown' | ||
| self.sv_seen = False # has seen 'server.version' message? | ||
| self.sv_negotiated = asyncio.Event() # done negotiating protocol version | ||
| self.anon_logs = self.env.anon_logs | ||
| self.txs_sent = 0 | ||
| self.log_me = SessionBase.log_new | ||
|
|
@@ -1296,15 +1295,13 @@ async def handle_request(self, request: SingleRequest): | |
| handler = self.notification_handlers.get(request.method) | ||
| method = 'invalid method' if handler is None else request.method | ||
|
|
||
| # Version negotiation must happen before any other messages. | ||
| if not self.sv_seen and method != 'server.version': | ||
| self.logger.info(f'closing session: server.version must be first msg. got: {method}') | ||
| await self._do_crash_old_electrum_client() | ||
| # If DROP_CLIENT_UNKNOWN is enabled, check if the client identified | ||
| # by calling server.version previously. If not, disconnect the session | ||
| if (self.env.drop_client_unknown and method != 'server.version' | ||
| and self.client_longname == 'unknown'): | ||
| self.logger.info(f'disconnecting because client is unknown') | ||
| raise ReplyAndDisconnect(RPCError( | ||
| BAD_REQUEST, f'use server.version to identify client')) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [CRITICAL] You removed |
||
| # Wait for version negotiation to finish before processing other messages. | ||
| if method != 'server.version' and not self.sv_negotiated.is_set(): | ||
| await self.sv_negotiated.wait() | ||
|
|
||
| self._method_counts[method] += 1 | ||
| self.session_mgr._method_counts[method] += 1 | ||
|
|
@@ -2197,7 +2194,6 @@ async def phandle_server_version( | |
| BAD_REQUEST, f'unsupported protocol version: {protocol_version}')) | ||
| self.set_request_handlers(ptuple) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [CRITICAL] No |
||
|
|
||
| self.sv_negotiated.set() | ||
| return electrumx.version, self.protocol_version_string() | ||
|
|
||
| async def phandle_transaction_broadcast(self, raw_tx: str | Any) -> str: | ||
|
|
@@ -2429,9 +2425,7 @@ class LocalRPC(SessionBase): | |
|
|
||
| def __init__(self, *args, **kwargs): | ||
| super().__init__(*args, **kwargs) | ||
| self.sv_seen = True | ||
| assert get_running_loop() is not None, "must be running on asyncio thread" | ||
| self.sv_negotiated.set() | ||
| self.client_longname = 'RPC' | ||
| self.connection.max_response_size = 0 | ||
| # note: self.request_handlers are set on the class, in SessionManager.__init__ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -428,3 +428,18 @@ def test_ban_versions(): | |
| def test_coin_class_provided(): | ||
| e = Env(lib_coins.Bitcoin) | ||
| assert e.coin == lib_coins.Bitcoin | ||
|
|
||
|
|
||
| def test_drop_unknown_clients(): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [HIGH] |
||
| setup_base_env() | ||
| e = Env() | ||
| assert e.drop_client_unknown is False | ||
| os.environ['DROP_CLIENT_UNKNOWN'] = "" | ||
| e = Env() | ||
| assert e.drop_client_unknown is False | ||
| os.environ['DROP_CLIENT_UNKNOWN'] = "1" | ||
| e = Env() | ||
| assert e.drop_client_unknown is True | ||
| os.environ['DROP_CLIENT_UNKNOWN'] = "whatever" | ||
| e = Env() | ||
| assert e.drop_client_unknown is True | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[HIGH]
DROP_CLIENT_UNKNOWNchecksclient_longname == 'unknown'without waiting for in-flightserver.version. Legitimate pipelined Electrum clients get yeeted mid-handshake. Your robot filter shoots compliant subjects. Science.