diff --git a/proxywatchd.py b/proxywatchd.py index 47a464f..6d72d6f 100644 --- a/proxywatchd.py +++ b/proxywatchd.py @@ -1028,6 +1028,14 @@ class TargetTestJob(): True, proto=proto, duration=elapsed, srv=srv, tor=tor, ssl=is_ssl ) + elif err_cat == 'ssl_mitm': + # MITM detected - proxy works but intercepts TLS + elapsed = time.time() - duration + self.proxy_state.record_result( + True, proto=proto, duration=elapsed, + srv=srv, tor=tor, ssl=is_ssl + ) + self.proxy_state.mitm = 1 else: self.proxy_state.record_result(False, category=err_cat) return @@ -1197,7 +1205,12 @@ class TargetTestJob(): _log("could not resolve connection target %s" % connect_host, "ERROR") break elif err == rocksock.RS_E_SSL_CERTIFICATE_ERROR: + # MITM detected - proxy works but intercepts TLS ps.mitm = 1 + elapsed = time.time() - duration + if pool: + pool.record_success(torhost, elapsed) + return None, proto, duration, torhost, srvname, 0, use_ssl, 'ssl_mitm' except KeyboardInterrupt as e: raise e @@ -1565,12 +1578,13 @@ class Proxywatchd(): # Check if proxy should be marked as permanently dead effective_failcount = job.failcount if job.failcount > 0: - # Mark dead if: exceeded max_fail*2, OR reached max_fail with fatal error is_fatal = job.last_fail_category in FATAL_ERROR_CATEGORIES - if job.failcount >= max_fail * 2: + # Fatal errors (refused/unreachable/auth) = immediately dead + if is_fatal: effective_failcount = DEAD_PROXY dead_count += 1 - elif job.failcount >= max_fail and is_fatal: + # Non-fatal: mark dead if exceeded max_fail*2 + elif job.failcount >= max_fail * 2: effective_failcount = DEAD_PROXY dead_count += 1 args.append((effective_failcount, job.checktime, 1, job.country, job.proto,