diff --git a/gateway.py b/gateway.py index 8fe8d21..b532120 100644 --- a/gateway.py +++ b/gateway.py @@ -75,6 +75,7 @@ class Gateway(): self.mac_address = None self.encryptmode = 0 # 0: sha1, 1: sha256 self.nonce_key = None + self.web_scheme = 'http' self.stok = None # HTTP session token self.status = -2 self.errcode = -1 @@ -111,7 +112,7 @@ class Gateway(): if port <= 0: die("Can't found valid SSH server on IP {}".format(self.ip_addr)) - def api_request(self, path, params = None, resp = 'json', post = '', timeout = 4, stream = False): + def api_request(self, path, params = None, resp = 'json', post = '', timeout = 4, stream = False, scheme = None): self.last_resp_code = 0 self.last_resp_text = None headers = { } @@ -122,7 +123,8 @@ class Gateway(): elif post: headers["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8" headers["User-Agent"] = self.user_agent - url = f"http://{self.ip_addr}/cgi-bin/luci/" + web_scheme = scheme if scheme else self.web_scheme + url = f"{web_scheme}://{self.ip_addr}/cgi-bin/luci/" if path.startswith('API/'): url += f';stok={self.stok}/api' + path[3:] else: @@ -130,9 +132,9 @@ class Gateway(): t_timeout = (self.con_timeout, timeout) if timeout is not None else (self.con_timeout, self.timeout) #print(f'{t_timeout=}') if post: - response = requests.post(url, data = params, stream = stream, headers = headers, timeout = t_timeout) + response = requests.post(url, data = params, stream = stream, headers = headers, timeout = t_timeout, verify = False) else: - response = requests.get(url, params = params, stream = stream, headers = headers, timeout = t_timeout) + response = requests.get(url, params = params, stream = stream, headers = headers, timeout = t_timeout, verify = False) self.last_resp_code = response.status_code if resp and not stream: try: @@ -166,10 +168,35 @@ class Gateway(): self.encryptmode = 0 self.nonce_key = None self.status = -2 + web_scheme = None + page = '' + for scheme in [ 'http', 'https' ]: + page = '' + try: + page = self.api_request('web', scheme = scheme, resp = 'TEXT', timeout = self.timeout) + #with open("r0.txt", "wb") as file: + # file.write(page.encode("utf-8")) + except requests.exceptions.ConnectionError as e: + continue # try other scheme + except requests.exceptions.ConnectTimeout as e: + continue # try other scheme + except requests.exceptions.HTTPError as e: + print("Initial Request Http Error:", e) + except requests.exceptions.Timeout as e: + print("Initial Request Timeout Error:", e) + except requests.exceptions.RequestException as e: + print("Initial Request exception:", e) + except Exception as e: + print("Initial Request Exception:", e) + web_scheme = scheme + break + if not page: + return -2 + if web_scheme: + if web_scheme == 'https' and self.web_scheme != web_scheme: + print('Switch to using Secure HTTP (HTTPS)') + self.web_scheme = scheme try: - page = self.api_request('web', resp = 'TEXT', timeout = self.timeout) - #with open("r0.txt", "wb") as file: - # file.write(page.encode("utf-8")) hardware = re.findall(r'hardware = \'(.*?)\'', page) if hardware and len(hardware) > 0: self.device_name = hardware[0] @@ -186,18 +213,7 @@ class Gateway(): self.mac_address = mac_address.group(1) if mac_address else None nonce_key = re.search(r'key: \'(.*)\',', page) self.nonce_key = nonce_key.group(1) if nonce_key else None - except requests.exceptions.HTTPError as e: - print("Http Error:", e) - except requests.exceptions.ConnectionError as e: - #print("Error Connecting:", e) - return self.status - except requests.exceptions.ConnectTimeout as e: - print ("ConnectTimeout Error:", e) - except requests.exceptions.Timeout as e: - print ("Timeout Error:", e) - except requests.exceptions.RequestException as e: - print("Request Exception:", e) - except Exception: + except Exception: pass if not self.device_name: die("You need to make the initial configuration in the WEB of the device!") @@ -277,12 +293,39 @@ class Gateway(): password = self.xqhash(password) username = 'admin' data = f"username={username}&password={password}&logtype=2&nonce={nonce}" - text = self.api_request('api/xqsystem/login', data, post = 'x-www-form', resp = 'text', timeout = timeout) + web_scheme = None + code = None + text = None + for scheme in [ 'http', 'https' ]: + text = None + if scheme == 'http' and self.web_scheme == 'https': + continue + try: + text = self.api_request('api/xqsystem/login', data, scheme = scheme, post = 'x-www-form', resp = 'text', timeout = timeout) + if text and text.startswith('{'): + dresp = json.loads(text) + if 'code' in dresp: + code = int(dresp['code']) + if code == 401: # Invalid token + continue + except requests.exceptions.ConnectionError as e: + continue # try other scheme + except requests.exceptions.ConnectTimeout as e: + continue # try other scheme + web_scheme = scheme + break + if not text: + self.webpassword = "" + die(f"Cannot get response for api/xqsystem/login! (encryptmode = {self.encryptmode})") + if web_scheme: + if web_scheme == 'https' and self.web_scheme != web_scheme: + print('Switch to using Secure HTTP (HTTPS)') + self.web_scheme = scheme try: - stok = re.findall(r'"token":"(.*?)"', text)[0] + stok = re.findall(r'"token":"(.*?)"', text)[0] except Exception: - self.webpassword = "" - die("WEB password is not correct! (encryptmode = {})".format(self.encryptmode)) + self.webpassword = "" + die(f"WEB password is not correct! ERR={code} (encryptmode = {self.encryptmode})") self.webpassword = web_pass self.stok = stok return stok diff --git a/python/urllib3/connectionpool.pyc b/python/urllib3/connectionpool.pyc index b393cc2..535a328 100644 Binary files a/python/urllib3/connectionpool.pyc and b/python/urllib3/connectionpool.pyc differ