#!/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¶=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('(.*)', 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('(.*)', 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()