Skip to content

Instantly share code, notes, and snippets.

@FreedomKnight
Last active September 9, 2022 15:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FreedomKnight/7395191 to your computer and use it in GitHub Desktop.
Save FreedomKnight/7395191 to your computer and use it in GitHub Desktop.
中原 wifi 的登入器

這是我對中原大學的 wifi 做的自動登入器
因為學校的 wifi 會一段時間自動斷線
所以寫了這個 python script 去偵測是否已經斷線,並且還原連線
先找到學校叫做 CYCCWL2G 的 wifi 連線
再來使用 autologin
目前的使用方法只有兩個

  • sudo ./autologin.py start 會要求使用者輸入帳號密碼,測試完連線之後,會在背景執行偵測,預設是每分鐘一次

  • sudo ./autologin.py stop 將在背景執行的程序停掉

其實各大作業系統使用方法都差不多,只不過必須安裝 python 而這東西是在 linux 下完成的,沒有測試太多點
如果有需要請自己 hack

授權使用 GPL v3,詳情請見 GPL v3

已知問題:目前只能在圖書館、活動中心、電學大樓可以使用,教學大樓暫時無法 (誰叫我一開始就蹲麥當勞跟圖書館做)

#!/usr/bin/env python3
import urllib.request
import urllib.parse
import http.client
import time
import os
import re
import sys
import signal
import lxml.html
debug = False
class Wifi:
cycuUrl = "http://cycu.edu.tw"
def __init__(self):
self.__response = None
def getPostData(self, user, password):
postData = {
"username": user,
"password": password,
"buttonClicked": "4",
"err_flag": "0",
"err_msg": "",
"info_flag": "0",
"info_msg": "",
"redirect_url": ""
}
return urllib.parse.urlencode(postData).encode('utf-8')
def login(self, username, password, host, port, path):
postdata = self.getPostData(username, password)
# Simulate Chrome Header
header = {
"Connection": "keep-alive",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Origin": "https://acs.cycu.edu.tw",
"User-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.114 Safari/537.36",
"Content-Type": "application/x-www-form-urlencoded",
"Accept-Encoding": "gzip,deflate,sdch",
"Accept-Language": "zh-TW,zh;q=0.8,zh-CN;q=0.6,en-US;q=0.4,en;q=0.2",
}
paramRegex = "cid[a-zA-Z0-9\?&\=]+"
#login in /login
post = http.client.HTTPConnection(host, port)
post.request("POST", path, body=postdata, headers=header)
response = post.getresponse().read().decode('utf-8')
#global debug
if debug:
print(response)
match = re.search(paramRegex, response)
if not match:
print("connect fail", file=sys.stderr)
return False
match = match.group()
data = re.split("'|;", match)[0]
# get cid and username back
post.request("GET", "/login?" + data, headers=header)
response = post.getresponse().read().decode('utf-8')
# allow user and cid
post.request("GET", "/_allowuser.jsp?" + data, headers=header)
response = post.getresponse().read().decode('utf-8')
return True
def isBreak(self):
self.__response = urllib.request.urlopen(self.cycuUrl)
if self.__response.geturl() is not self.cycuUrl:
return True
return False
def parseHost(self, htmlPage):
root = lxml.html.fromstring(htmlPage)
form = root.xpath("//form[@action]")
url = form[0].get("action")
result = urllib.parse.urlparse(url)
netloc = result.netloc
path = result.path
if not netloc:
authUrl = urllib.request.urlopen(self.cycuUrl).geturl()
netloc = urllib.parse.urlparse(authUrl).netloc
netloc = netloc.split(":")
host = netloc[0]
port = netloc[1] if len(netloc) == 2 else 80
return host, port, path
def getAuthPage(self):
if self.__response.geturl() != self.cycuUrl:
return self.__response.read().decode("utf-8")
return None
def checkLogin(self, username, password):
if self.isBreak():
host, port, path = self.parseHost(self.getAuthPage())
return self.login(username, password, host, port, path)
return False
def autoLogin(self, username, password):
delayTime = 60 #1 min
while True:
while self.isBreak():
host, port, path = self.parseHost(self.getAuthPage())
self.login(username, password, host, port, path)
time.sleep(delayTime)
class Daemon:
def __init__(self, pidfile = None):
if not pidfile:
if os.name == "posix":
self.__pidfile = "/var/run/autologin.pid"
try:
open(self.__pidfile, "w")
except:
self.__pidfile = "./autologin.pid"
else:
self.__pidfile = "./autologin.pid"
else:
self.__pidfile = pidfile
def start(self):
if os.path.exists(self.__pidfile):
os.remove(self.__pidfile)
wifi = Wifi()
username = input("username: ")
password = input("password: ")
while not wifi.checkLogin(username, password):
print("login error, please again")
username = input("username: ")
password = input("password: ")
pid = os.fork()
if pid > 0:
sys.exit(0)
pidfd = open(self.__pidfile, "w")
pidfd.write(str(os.getpid()))
pidfd.close()
wifi.autoLogin(username, password)
def stop(self):
if os.path.exists(self.__pidfile):
pidfd = open(self.__pidfile)
pid = int(pidfd.read().strip())
pidfd.close()
if pid:
os.kill(pid, signal.SIGTERM)
os.remove(self.__pidfile)
if __name__ == "__main__":
daemon = Daemon()
if len(sys.argv) > 1:
if sys.argv[1] == "start":
daemon.start()
elif sys.argv[1] == "stop":
daemon.stop()
else:
print("no option")
elif debug:
username = input("username: ")
password = input("password: ")
wifi = Wifi()
wifi.checkLogint(username, password)
else:
print("Please enter an argument")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment