async def _get_banner(target_name: str, target_port: int, send: Optional[str], timeout: int) -> Optional[str]: try: async with timeout_(timeout): reader, writer = await asyncio.open_connection("localhost", 9050) socks = await _socks4a(reader, writer, target_name, target_port) if socks: buff = b"" if send is not None: writer.write(send.encode("utf8")) await writer.drain() while not b"\n" in buff: data = await reader.read(1024) buff += data if not data: break return buff.split(b"\n", 1)[0].rstrip(b"\r").decode("utf8") else: stderr.write("failed to handshake\n") except asyncio.TimeoutError: stderr.write("overall timeout\n") except Exception as e: stderr.write(f"{type(e)} {str(e)}\n")
async def _cert_match(ip: str, port: int) -> List[str]: try: async with timeout_(4): values = await _cert_values(ip, port) except asyncio.TimeoutError: print("timeout") except Exception as e: traceback.print_exc() else: return [f"{k}:{v}" for k, v in values.items()] return []
async def _cert_match(ip: str) -> Optional[str]: try: async with timeout_(4): values = await _cert_values(ip, 443) except TimeoutError: print("timeout") except Exception as e: traceback.print_exc() else: for key, value in values.items(): kv = f"{key}:{value}".lower().strip() if kv in BAD: return kv return None
async def _read_line(self, timeout: float) -> Optional[Line]: while True: if self._read_queue: return self._read_queue.popleft() try: async with timeout_(timeout): data = await self._reader.read(1024) except asyncio.TimeoutError: return None self.last_read = monotonic() lines = self.recv(data) for line in lines: self.line_preread(line) self._read_queue.append(line)
async def _match(self, ip: str, port: int, certs: List[CertPattern]) -> Optional[str]: try: async with timeout_(self._timeout): values_t = await self._values(ip, port) except (asyncio.TimeoutError, ConnectionError): pass except Exception as e: traceback.print_exc() else: values = [f"{k}:{v}" for k, v in values_t] for cert in certs: for pattern in cert.find: for value in values: if pattern.fullmatch(value): return f"{value} (:{port} {cert.name})" return None
async def wait_for(self, response: Union[IMatchResponse, Set[IMatchResponse]], sent_aw: Optional[Awaitable[SentLine]] = None, timeout: float = WAIT_TIMEOUT) -> Line: response_obj: IMatchResponse if isinstance(response, set): response_obj = ResponseOr(*response) else: response_obj = response async with self._read_lguard: self._wait_for.set() async with self._read_lwork: async with timeout_(timeout): while True: line = await self._read_line(timeout) if line: self._ping_sent = False emit = self.parse_tokens(line) self._process_queue.append((line, emit)) if response_obj.match(self, line): return line