From 4a9e1003b6af6d89c0883eff385adb516cfb0c23 Mon Sep 17 00:00:00 2001 From: remittor Date: Mon, 20 Oct 2025 12:26:50 +0300 Subject: [PATCH] gateway: Add support https --- gateway.py | 89 ++++++++++++++++++++++-------- python/urllib3/connectionpool.pyc | Bin 24651 -> 24422 bytes 2 files changed, 66 insertions(+), 23 deletions(-) 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 b393cc2544e76aa47b70b1bd5d90c93b6d916c5b..535a32808f07bcb11a010d737976a5d5c7210493 100644 GIT binary patch delta 2777 zcmai0U2GKB74~?4z3UAIVvI1v;3R}KF-CFzXw(FQcVld06YRz2W?>lbj&}#|&MaqU zVV8ooO4OH9i6pnQN!6w#prkYsX|g408}&zRq*hA%)R$=5st=X=5cQ!_AF4jJ=evVV zl_GT?zCHKebIzQ5&UentC%@4C`ZFz+OQjMW{JZ|kf0Y09UTQ<^sj0#j^19n}J+qqE z$*FrL=?%+ps#cyxOZi6CqT!n170M>%YfZ20*!enDD%R3yzI{0MeJvqkW}~2=H7cU5 zb&YA!{p_Bemak84Zl6lbCp95&_3F=v*mx#8mYbfZ2%q~gGCi_Pmoiv|YmQU#BTE&h zutF2qN!7?{H1)D+6issJkeu6eY;Y2u1M{lUaINzu%_?WBYKP?~oBG#_lpa_Y9DCU+ zQLg>ZO_SPvqVvhU=`ihulhIXA1fS^y%}IUpGg0+`T>JXw-*;-Wve7S-Gw>fOaj>&; z)7FuZJPc0&l%J<@9OGld^N5ysl@8IPI7XOcw7sp$)x^M4{cuG`0VZG@g9vBql?vtM z>jQn-Dfz*`r;L}kUsTvD2Y37>IR)K^0MqTB!Iq{?$(Qcmp}Fn%?>`aQ+Q2~*aGqht z54*^qh7FRt)90Ut-x!NCS+e*q9U+zNB2G~wm2FzaQBWTdcPd34wBsUuG<;F(Q@SJ2 zMP=E8Dr2)fJMy=CPl|OlGAoWzME*R}_U7rEtd*rO3@*SR956GymhF);RM&kC+8Y3`%4BxS zvSQL8)@VXH#NdYuPOa%j>$Rf6qu~hl9{{Mdu0R64s0_G6suGqq;0lAEJbJsn2P>|S zm$KWmOY%l`M@w{Bc7e<)XVeez5TX{eBW}esYovH}8XGa5I8M#9MK8A+bERkzb6Dqb zVR*>k*YKcT2C<$D%Qbb!UegkZBJbIX_+p*%tS>vn=N`41s+WB(8qc3Db{#^GY!6(SLV<_9&xYg6tB+xT;X8P)Hx|d!bA{>0xR3P z*|0o%MVYgaZJxU`7j61F?+=UAYADJlUE@uX%Hn^rETlKFU3;f}W#Wp~IsnCkfN_B8 zn*^kjfbD?q0o3Gr5z-R?Ovr#LiaBcZD3&M=Vf2s#0BPtlK+#O`^c^f83qanOOlev9 z;pFpLw!Lv`F~p0?%*)5r09ScmfZ{CRPHB!~DF8nJya#w6&<6Yv@B!dMz>fg80J-+u z?DJYn*(l9BhRQ}Mt=XizNi|)HO-0;gz7|aKf+zle>mYzrcbT%2!3pJ(%;1y+3o0@t?|sM&*xhzY3fdES4^*`Im8f* zc1U{xqX1RmE=XGdDh!o!)%|yIMmgyHn1P2Rrm9F91+Q*Y^s?i6VsLd;b2v|6`{%As zOOkRIwQ>3P+(Uc3&;_j+Dt5jYDu!3$wBL(djTR$b?2S&Xqu4puk&aRYE-;h%UDdbn zyU{oglzPo1x`_kDIW?X>;-w!yXOL~#CD#u_qK(iwCDV)jz0mwD)Y0Mgu+S0i33Y4n zlq@Yi`o+7kzZ-@sH=pA?E*^|R#r~@Nba7kq=h##)ubZzNAJcALJ8(Rdeixg_@eIFy zc4Ki5K#gh@dzP1c)RZgv8SP{Fll(31RarZ+@QBL?eyrk@N_-Xi3aoAbehT0#bkHS$ zDw7B4JMv#AewF+(!~wuH`RkMWHDAW{oh?66_pHhu49F(o-Qjnu4bQ5Y{C%i;+K;O( zo>{aD_G!Qn;5Psj{KG8yk*af+Kl7f0i~&2%F>)#PK@05iqt4Q4e2_TU8D`k&M>Av3 kjvboulbMCt-1PW?>Dhx*bQb4GKv2ey`2(|0ex@7$0Yuc}D*ylh delta 2965 zcmai0U2Gf25!UfXq$tt0Y|F77*{0(-4&%rwY`3w~z^NKhVG>1>B}%d+N>_?pNhcle z=((dUDh(*xXn~?YgJ2QZK$14@Uw+UcFxWPEX=^xrE83U9X|m}*+M+*cAN)`t4*@#g zo+KA(fb!wv?Ck99?#wr{_m`g-Kfi7yN0Z4!6aS*CmkV!SOKy!FIaPWvU#a;EuCw-c z>_oobn$3HbFS;s);!gvX1&cs%ptHMsmd8{Cd|s!mzN&2#oT}LQ0y&m5f7>z5$qStw^4)!J z8IZQg*HepYQrG@Jw+_I|A;4f`&s}xH7?3X>*l(;fetKX!+F8fMD&PXcfQopCumMF) zo=C4ea0cQsgGzdSfqavr$i;M&bfOkn*6G!WA{$dd zYE|5|OD1?r^YGDlziZLBL)&*_5s1NFGz(T6`R)(4濵K|$;UN3M@pJStTlG-{ z3oc)-Ba25A}--Y7>dGRpI$&5ClGgW@KV5S$s7*Ex+5FVK#rzTdeCfaroc^ zdR8~*TZJFZDyymmOtv-Uso-bQzTL51gWrB^XSX4j(WBb6As zTiAKf-BjH2v_Va6-f+k@>sP(>o`7dBV9Qm&_W?Qu8=0gxq0<%p3CUBf>%@4-Tsp53 zl>&L9Wbz%=))F(%a`dfCueiXGAzhN~%w|#GoB0cTG;mSL_Uw*HG#!;F@|VVD8*0d&F>kV=3Q z;Ku;88hQrs007;YG%++$baT_3Koiu>jm|*=Md*2eW|ijZ4GcdWfc$W#Eks%Qv&W~5 zY$Nr=nXr+SwSi~H^y{I+JOxWUQ2&*QX$)rozXH4qcn_ce?*o1V_$}affL{Y9bc^u@ zvxcqLY3tjI^*U|1u`b<4y84p5T*W=6Xpze}*!BOf4i2H;o5q8umyILuu$$aKI<69M z>_B8*%W=Ud-j|IyU;)8@EWe(>Oc?T_2Ku zQngo|$rk8#1GIk~S%KjvIHL(n{DFZx>2dy3t%agrE!etqsZHynip!zUZQEFo_0gw| zy!>eNQ2mR>V$^%cZ+7k4lkJ=u)^8U5e8gZP6Uel|my;=@@y~ z7%hBY<;_ut-y3Vr5~Wl&mm3;Mt#$8|<)vl?I&GQ1YEr(NLO)F%I_MoblIkgyL*mHaBt8 z45<4V%)#T|!%a=zUKW}nTf%KdJk)GNLZNWvqfj&w`Y@7^7sro_URZyu%G#jQx%pUa zA@HP&Nmm&*;jgY>`=YSz^&{vK`X`L_VQ$Jh&-55KzctM@^p2dF+ObPN5Blm^w&G`W z6|O={=cU=bPkwLe-pDOh$i@A;<*lhJ#w+rx`SGJGu!-63{5-y&p5+l;2mAxTcWt7} z08OB$AiXZPPrudr6^Q!)Z^%DRf6kbc2WIX$IGL#WmVE>bxkh-wCfl@P{Zj@vpOntb zu9N@9(!+rJ8C10Fp5xEjQOIcC{d^wI<4G8Rb$0dVI-;)2D GS^f_<3`t%9