|
#!/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") |