bistu_wifi/main.py

168 lines
5.3 KiB
Python
Raw Normal View History

2022-09-13 02:38:14 +00:00
#!/usr/bin/python3
import urllib.parse
import urllib.request
import urllib.response
import logging
import re
import argparse
logger = logging.getLogger('login_manager')
def generate_post_data(username: str, password: str):
'''
Generate bytes to send to through HTTP POST, an example from browser:
DDDDD=2021020000&upass=Bistu000000&R1=0&R2=&R3=0&R6=0&para=00&0MKKey=123456&buttonClicked=&redirect_url=&err_flag=&username=&password=&user=&cmd=&Login=
'''
data_template = {
'DDDDD': None,
'upass': None,
'R1': 0,
'R2': '',
'R3': 0,
'R6': 0,
'para': 00,
'0MKKey': 123456,
'buttonClicked': '',
'redirect_url': '',
'err_flag': '',
'username': '',
'password': '',
'user': '',
'cmd': '',
'Login': ''
}
data_template['DDDDD'] = username
data_template['upass'] = password
# login_manager.generate_post_data_hook(data_template)
logger.debug('the generated post data is %s', str(data_template))
return bytes(urllib.parse.urlencode(data_template), 'utf-8')
def login(username: str, password: str, host: str = '10.1.206.13'):
'''
There are some other host, the known are:
- 10.1.206.3 (default)
- 192.168.211.3
'''
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
'Accept-Language': 'en-US,zh-CN;q=0.5',
'Accept-Encoding': 'gzip, deflate'
}
post_data = generate_post_data(username, password)
login_url = f'http://{host}/a70.htm'
logger.debug('the dest url is: %s', login_url)
logger.debug('the headers is: %s', str(headers))
logger.debug('the encoded post data is %s', str(post_data))
req = urllib.request.Request(url=login_url, data=post_data, headers=headers, method='POST')
logger.info('sending the login request...')
with urllib.request.urlopen(req) as response:
response_body = response.read().decode('gbk')
html_title = re.search('<title>(.*)</title>', response_body)[1]
logger.info('http_status: %d', response.status)
logger.info('title_of_response_html: %s', html_title)
logger.info('login_state: %s', 'success' if html_title == '认证成功页' else 'fail')
def logout(host: str = '10.1.206.13'):
'''
param host: see login host
'''
logout_url = f'http://{host}/F.htm'
req = urllib.request.Request(url=logout_url)
logger.info('sending the logout request...')
with urllib.request.urlopen(req) as response:
response_body = response.read().decode('gbk')
html_title = re.search('<title>(.*)</title>', response_body)[1]
logger.info('http_status: %d', response.status)
logger.info('title_of_response_html: %s', html_title)
logger.info('logout_state: %s', 'success' if html_title == '信息页' else 'fail')
#@staticmethod
#def generate_post_data_hook(post_data: dict) -> None:
# username = post_data['DDDDD']
# username += '@bistu'
# post_data['DDDDD'] = username
def load_auth_info(path: str):
with open(path, 'r', encoding='utf-8') as file:
username = file.readline().strip()
password = file.readline().strip()
host = file.readline().strip()
if host == '':
host = None
return username, password, host
def main():
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger('main')
parser = argparse.ArgumentParser()
parser.description = 'login or logout bistu wifi'
parser.epilog = 'the config file format(without quote): "{username}\\n{password}". The "\\n" is a newline charactor'
parser.add_argument('-u', '--username', nargs='?',
type=str, help='username you use to login bistu wifi, logout if not provided')
parser.add_argument('-p', '--password', nargs='?',
type=str, help='password you use to login bistu wifi, logout if not provided')
parser.add_argument('--host', nargs='?', default=None,
type=str, help='host to send login/logout request to, default use 10.1.206.13')
parser.add_argument('-o', '--logout', nargs='?', type=bool, default=False,
help='logout bistu wifi')
parser.add_argument('-c', '--config', nargs='?', type=str,
help='load info(username, password, host) from config file')
args = parser.parse_args()
logger.debug('parse argument: username= %s', args.username)
logger.debug('parse argument: password= %s', args.password)
logger.debug('parse argument: host= %s', args.host)
logger.debug('parse argument: logout= %s', args.logout)
if args.config is not None:
username, password, host = load_auth_info(args.config)
if host is None:
login(username, password)
else:
login(username, password, host)
elif args.username is not None and args.password is not None:
if args.host is None:
login(args.username, args.password)
else:
login(args.username, args.password, args.host)
elif args.logout:
if args.host is None:
logout()
else:
logout(args.host)
else:
parser.print_help()
if __name__ == '__main__':
main()