def onConnect(self, request): # ----- init decryptor ----- if not config.tun_ssl: if config.compatible: cookie = request.headers['cookie'] if cookie.count(';') > 0: raise ConnectionDeny(400) if not cookie.startswith(config.cookie_key + '='): raise ConnectionDeny(400) nonceB64 = cookie.lstrip(config.cookie_key + '=') else: nonceB64 = request.headers['sec-websocket-key'] try: nonce = base64.b64decode(nonceB64) self.initCipher(nonce, decryptor=True) except Exception as e: logging.error('failed to initialize cipher: %s' % e) raise ConnectionDeny(400) else: nonceB64 = nonce = None # for decrypting # ----- extract header ----- path = self.http_request_path try: if path.startswith(factory.path): path = path[len(factory.path):] dat = base64.urlsafe_b64decode( path[1:] if path.startswith('/') else path) cmd = ord(self.decrypt(dat[:1])) addr, port, remainData, timestamp = self.parseRelayHeader(dat) if cmd != self.CMD_REQ: raise ValueError('wrong command %s' % cmd) except (ValueError, Base64Error) as e: logging.error('invalid request: %s (from %s), path: %s' % (e, self.peer, path)) raise ConnectionDeny(400) if not config.tun_ssl: # filter replay attack seen = seenNonceByTime[timestamp // 10] if nonce in seen: logging.warning('replay attack detected (from %s)' % self.peer) raise ConnectionDeny(400) seen.add(nonce) if config.compatible: # avoid generating a new random nonce for encrypting, and client will do same # calculating to get this nonce encNonce = get_sha1(nonce)[:16] else: # repeat calculation in websocket library so that key in WS handshake reply # is the same as this one encNonce = get_sha1( nonceB64.encode() + b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11")[:16] self.initCipher(encNonce, encryptor=True) self.tunOpen.set_result(None) self.connectTargetTask = async_( self.connectTarget(addr, port, remainData))
def onConnect(self, request): self.clientInfo = '{0}:{1}'.format(*self.transport.get_extra_info('peername')) # ----- init decryptor ----- if not config.tun_ssl: if config.compatible: cookie = request.headers['cookie'] if cookie.count(';') > 0: raise ConnectionDeny(400) if not cookie.startswith(config.cookie_key + '='): raise ConnectionDeny(400) nonceB64 = cookie.lstrip(config.cookie_key + '=') else: nonceB64 = request.headers['sec-websocket-key'] try: nonce = base64.b64decode(nonceB64) self.initCipher(nonce, decryptor=True) except Exception as e: logging.error('failed to initialize cipher: %s' % e) raise ConnectionDeny(400) else: nonceB64 = nonce = None # for decrypting # ----- extract header ----- try: dat = base64.urlsafe_b64decode(self.http_request_path[1:]) cmd = ord(self.decrypt(dat[:1])) addr, port, remainData, timestamp = self.parseRelayHeader(dat) if cmd != self.CMD_REQ: raise ValueError('wrong command %s' % cmd) except (ValueError, Base64Error) as e: logging.error('invalid request: %s (from %s), path: %s' % (e, self.clientInfo, self.http_request_path)) raise ConnectionDeny(400) if not config.tun_ssl: # filter replay attack seen = seenNonceByTime[timestamp // 10] if nonce in seen: logging.warning('replay attack detected (from %s)' % self.clientInfo) raise ConnectionDeny(400) seen.add(nonce) if config.compatible: # avoid generating a new random nonce for encrypting, and client will do same # calculating to get this nonce encNonce = get_sha1(nonce)[:16] else: # repeat calculation in websocket library so that key in WS handshake reply # is the same as this one encNonce = get_sha1(nonceB64.encode() + b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11")[:16] self.initCipher(encNonce, encryptor=True) self.tunOpen.set_result(None) self.connectTargetTask = async_(self.connectTarget(addr, port, remainData))
def onOpen(self): self.tunOpen.set_result(None) self.lastIdleTime = time.time() if not config.debug: self.customUriPath = None # save memory if not config.tun_ssl: if config.compatible: nonce = get_sha1(base64.b64decode(self.customWsKey))[:16] else: # SHA-1 has 20 bytes nonce = base64.b64decode(self.http_headers['sec-websocket-accept'])[:16] self.initCipher(nonce, decryptor=True)
def onOpen(self): self.tunOpen.set_result(None) self.lastIdleTime = time.time() self.setAutoPing(self.TUN_AUTO_PING_INTERVAL, self.TUN_AUTO_PING_TIMEOUT) if not config.debug: self.customUriPath = None # save memory if not config.tun_ssl: if config.compatible: nonce = get_sha1(base64.b64decode(self.customWsKey))[:16] else: # SHA-1 has 20 bytes nonce = base64.b64decode( self.http_headers['sec-websocket-accept'])[:16] self.initCipher(nonce, decryptor=True)
def onOpen(self): self.tunOpen.set_result(None) now = time.time() self.lastIdleTime = now # measure RTT rtt = now - self.handshakeSentTime if WSTunClientProtocol.rtt is None: WSTunClientProtocol.rtt = rtt else: WSTunClientProtocol.rtt = 0.8 * WSTunClientProtocol.rtt + 0.2 * rtt assert not self._pushToTunTask self._pushToTunTask = async_(self._pushToTunnelLoop()) self.setAutoPing(self.TUN_AUTO_PING_INTERVAL, self.TUN_AUTO_PING_TIMEOUT) if not config.debug: self.customUriPath = None # save memory if not config.tun_ssl: if config.compatible: nonce = get_sha1(base64.b64decode(self.customWsKey))[:16] else: # SHA-1 has 20 bytes nonce = base64.b64decode(self.http_headers['sec-websocket-accept'])[:16] self.initCipher(nonce, decryptor=True)