-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpassport.py
More file actions
98 lines (86 loc) · 3.61 KB
/
Copy pathpassport.py
File metadata and controls
98 lines (86 loc) · 3.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import requests
import json
import re
header = {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36'
}
class Encrypt:
def __init__(self, e, m):
self.e = e
self.m = m
def encrypt(self, message: str) -> str:
mm = int(self.m, 16)
ee = int(self.e, 16)
crypto = self._encrypt(message.encode(), mm, ee)
return crypto.hex()
def _pad_for_encryption(self, message: str, target_length: int) -> bytes:
return b'\x00'*(target_length - len(message)) + message
def _encrypt(self, message, mm: int, ee: int) -> bytes:
keylength = self.byte_size(mm)
padded = self._pad_for_encryption(message, keylength)
payload = int.from_bytes(padded, 'big', signed=False)
encrypted = pow(payload, ee, mm)
block = encrypted.to_bytes(keylength, 'big')
return block
def byte_size(self, number: int) -> int:
if number == 0:
return 1
quanta, mod = divmod(number.bit_length(), 8)
if mod:
quanta += 1
return quanta
class LoginFailedException(Exception):
def __init__(self, err='wrong user name or password'):
Exception.__init__(self, err)
class User:
base_url = 'https://zjuam.zju.edu.cn/cas'
fallback_base_url = 'http://210.32.15.40/cas'
login_url = '/login'
pubkey_url = '/v2/getPubKey'
def __init__(self, user_id: str, user_pass: str, session: requests.Session = None):
self.user_id = user_id
self.user_pass = user_pass
if session is None:
self.session = requests.Session()
else:
self.session = session
self.session.max_redirects = 10
def login(self) -> dict:
try:
page_text = self.session.get(
self.base_url + self.login_url, headers=header).text
except Exception as e:
page_text = self.session.get(
self.fallback_base_url + self.login_url, headers=header, verify=False).text
execution_id = re.findall(r'<[\s\n ]*input[\s\n ]*type[\s\n ]*=[\s\n ]*"hidden"[\s\n ]*name[\s\n ]*=[\s\n ]*"execution"[\s\n ]*value[\s\n ]*=[\s\n ]*"(.*?)"[\s\n ]*/>', page_text)[0]
enc_user_pass = self.pass_encrypt(self.user_pass)
form = {'username': self.user_id,
'password': enc_user_pass,
'authcode': '',
'execution': execution_id,
'_eventId': 'submit'}
try:
self.session.post(self.base_url + self.login_url, headers=header, data=form, allow_redirects=False)
except Exception as e:
self.session.post(self.fallback_base_url + self.login_url, headers=header, data=form, verify=False,
allow_redirects=False)
cookies = requests.utils.dict_from_cookiejar(self.session.cookies)
if 'iPlanetDirectoryPro' not in cookies:
raise LoginFailedException
else:
if 'route' in cookies:
del cookies['route']
return cookies
def pass_encrypt(self, raw_pass: str) -> str:
try:
result = self.session.get(
self.base_url + self.pubkey_url, headers=header)
except Exception as e:
result = self.session.get(
self.fallback_base_url + self.pubkey_url, headers=header, verify=False)
res_json = json.loads(result.text)
modulus = res_json['modulus']
exponent = res_json['exponent']
en = Encrypt(exponent, modulus)
encrypted = en.encrypt(raw_pass)
return encrypted