Advertisement
beqa1923

Untitled

Sep 12th, 2019
360
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.95 KB | None | 0 0
  1. import base64
  2. import binascii
  3. import json
  4. import urllib.request, urllib.error, urllib.parse
  5. import logging
  6. from collections import OrderedDict
  7.  
  8. from hashlib import sha1
  9. from logging.handlers import TimedRotatingFileHandler
  10. from Crypto.Cipher import AES
  11.  
  12. '''main defines'''
  13. # Silk Prod
  14. _KEY = binascii.a2b_hex("428f62982c5e1db32d1e9f3b66f75ba9973810eb60c1001e4e581b50cc879fc8")
  15. _IV = binascii.a2b_hex("29e4c7dc1c6f8cebcf86a04f34725c8f")
  16. PROVIDER = "silknet"
  17. LICENSE_SERVER_URL = "https://license.widevine.com/cenc/getlicense"
  18. ALLOWED_TRACK_TYPES = "SD_HD"
  19. ALLOW_UNVERIFIED_PLATFORM = True
  20.  
  21.  
  22. # silk Test
  23. """_KEY = binascii.a2b_hex("a3dff872487bdc5c104aa12e90ec1fe40858f56fca8b7b6f1ecd561099993a8c")
  24. _IV = binascii.a2b_hex("73d395265dbcd512dc488e4a532cf00e")
  25. PROVIDER = "silknet"
  26. LICENSE_SERVER_URL = "https://license.uat.widevine.com/cenc/getlicense"
  27. ALLOWED_TRACK_TYPES = "SD_HD"""
  28.  
  29. PARSEFIRST = True
  30.  
  31. '''logger init'''
  32. log = logging.getLogger('proxy')
  33. log.setLevel(logging.DEBUG)
  34. aFormat = logging.Formatter('[%(asctime)s][%(levelname)s] %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
  35. consoleHandler = logging.StreamHandler()
  36. consoleHandler.setLevel(logging.DEBUG)
  37. consoleHandler.setFormatter(aFormat)
  38. fh = TimedRotatingFileHandler(filename = 'vwproxy.log', when='midnight')
  39. fh.setFormatter(aFormat)
  40. log.addHandler(fh)
  41. log.addHandler(consoleHandler)
  42.  
  43. '''functions'''
  44. def generateSignature(text_to_sign):
  45. """Ingest License Request and Encrypt"""
  46. print("!!!!!!!!!!!!!!!!!!!!!!! 46")
  47. try:
  48. hashed_text = sha1(text_to_sign.encode("utf-8")).digest()
  49. cipher = AES.new(_KEY, AES.MODE_CBC, _IV)
  50. padding = binascii.a2b_hex("" if len(hashed_text) % 16 == 0
  51. else (16 -(len(hashed_text) % 16)) * "00")
  52. aes_msg = cipher.encrypt(hashed_text + padding)
  53. signature = base64.b64encode(aes_msg)
  54. return signature
  55. except Exception as e:
  56. log.error('error generating signature' + str(e))
  57. return -1
  58.  
  59. def sendRequest(message):
  60. """Send HTTP request via urllib2"""
  61. try:
  62. log.info(message)
  63. message = message.encode("utf-8")
  64. f = urllib.request.urlopen(LICENSE_SERVER_URL + "/" + PROVIDER, message)
  65. return f.read()
  66. except urllib.error.HTTPError as e:
  67. return {'status': -1, 'errno': str(e), 'message': e}
  68.  
  69. def buildCertificateRequest(request):
  70. """Builds JSON requests to be sent to the license server."""
  71. request = json.dumps({'payload': base64.standard_b64encode(request).decode("utf-8")})
  72. request = req.encode("utf-8")
  73. request = base64.standard_b64encode(req)
  74. request = req.decode("utf-8")
  75. print(type(request))
  76. print("checkpoint 1")
  77. signature = generateSignature(request)
  78. if signature:
  79. certificate_request = json.dumps({"request": request,
  80. "signature": signature,
  81. "signer": PROVIDER})
  82. print("checkpoint 2")
  83. return certificate_request
  84. else:
  85. log.error('sigrature error in buildCertificateRequest()')
  86.  
  87. def parseLicRequest(request):
  88. # payload = base64.standard_b64encode(request)
  89. req = json.dumps({
  90. "payload": base64.standard_b64encode(request).decode("utf-8"),
  91. "provider": PROVIDER,
  92. "parse_only": True,
  93. "allowed_track_types":ALLOWED_TRACK_TYPES,
  94. "allow_unverified_platform":ALLOW_UNVERIFIED_PLATFORM
  95. })
  96. print(type(req))
  97. signature = generateSignature(req)
  98. parseServerRequest = json.dumps({
  99. "request": base64.standard_b64encode(req),
  100. "signature": signature,
  101. "signer": PROVIDER
  102. })
  103. # return json.loads(sendRequest(parseServerRequest))
  104. return json.loads(sendRequest(parseServerRequest))
  105.  
  106. def buildLicenseRequest(request, haveContentId = False, content_id = 0):
  107. reqRaw = {
  108. "payload": base64.standard_b64encode(request).decode("utf-8"),
  109. "provider": PROVIDER,
  110. "allowed_track_types":ALLOWED_TRACK_TYPES,
  111. "allow_unverified_platform":ALLOW_UNVERIFIED_PLATFORM
  112. }
  113.  
  114. if haveContentId:
  115. reqRaw["content_id"] = content_id
  116.  
  117. req = json.dumps(OrderedDict(reqRaw))
  118. signature = generateSignature(req).decode("utf-8")
  119.  
  120. print("\n\nHERE IS SIGNED REQUEST \n\n", signature )
  121. req = req.encode("utf-8")
  122. req = base64.standard_b64encode(req)
  123. req = req.decode("utf-8")
  124. print("prshshsvc", req)
  125. parseServerRequest = json.dumps({
  126. "request": req,
  127. "signature": signature,
  128. "signer": PROVIDER
  129. })
  130. return parseServerRequest
  131.  
  132. '''kinda' __main__'''
  133. def application(env, start_response):
  134.  
  135. log.debug("CONTENT_LENGTH: " + env.get('CONTENT_LENGTH', 0))
  136. try:
  137. if env.get('REQUEST_METHOD') == 'OPTIONS':
  138. log.info('sending OPTIONS')
  139. start_response('200 OK', [('Content-Type','text/html')])
  140. return ['OK']
  141. elif env.get('REQUEST_METHOD') == 'GET' or int(env.get('CONTENT_LENGTH', 0)) < 1: #TODO add other methods in exception
  142. log.error('got empty request')
  143. start_response('400', [('Content-Type','text/html')])
  144. return ['bad request']
  145. elif int(env.get('CONTENT_LENGTH', 0)) < 50:
  146. log.info('building certificate request')
  147. data = env['wsgi.input'].read()
  148. print("request ",data)
  149. answer = json.loads(sendRequest(buildCertificateRequest(data)))
  150. if answer['status'] == 'OK' and answer.has_key('license'):
  151. #TODO Populate responses
  152. log.info('sending lic anwser')
  153. start_response('200 OK', [('Content-Type','text/html')])
  154. print("certificate",answer["license"])
  155. return [base64.standard_b64decode(answer["license"])]
  156. else:
  157. start_response('400 Error', [('Content-Type','text/html')])
  158. return ['go home']
  159. else:
  160. log.debug('building license request')
  161.  
  162. data = env['wsgi.input'].read()
  163.  
  164. if all(j in env.keys() for j in ['X-QRV-CONTENT-ID', 'X-QRV-SID']):
  165. answer = parseLicRequest(data)
  166. if answer['status'] == 'OK':
  167. #TODO Populate responses
  168. log.debug("content_id: " + json.dumps(base64.standard_b64decode(answer["pssh_data"]["content_id"])))
  169. log.debug(answer["pssh_data"])
  170. log.debug('client info: ' + json.dumps(answer["client_info"], indent=4))
  171. answer = json.loads(sendRequest(buildLicenseRequest(data, haveContentId=True, content_id=answer["pssh_data"]["content_id"])))
  172. if answer['status'] == 'OK' and answer.has_key('license'):
  173. log.info(answer["license"])
  174. start_response('200 OK', [('Content-Type','text/html')])
  175. return [base64.standard_b64decode(answer["license"])]
  176. else:
  177. start_response('400 Error', [('Content-Type','text/html')])
  178. return ['go home']
  179. else:
  180. answer = json.loads(sendRequest(buildLicenseRequest(data, haveContentId=False)))
  181. if 'status' in answer and answer['status'] == 'OK' and 'license' in answer:
  182. start_response('200 OK', [('Content-Type','text/html')])
  183. return [base64.standard_b64decode(answer["license"])]
  184. else:
  185. if answer.has_key('status'):
  186. log.error('request denied. status: ' + answer['status'])
  187. start_response('500', [('Content-Type','text/html')])
  188. return ['request error']
  189. else:
  190. log.error('request error, no status code')
  191. start_response('500', [('Content-Type','text/html')])
  192. return ['request error']
  193. except Exception as e:
  194. log.error('error' + e)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement