Guest User

Akamai SecureHD Proxy

a guest
Jul 30th, 2012
962
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.82 KB | None | 0 0
  1. """
  2. XBMCLocalProxy 0.1
  3. Copyright 2011 Torben Gerkensmeyer
  4.  
  5. Modified for Akamai SecureHD by BlueCop
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  20. MA 02110-1301, USA.
  21. """
  22.  
  23. import base64
  24. import re
  25. import time
  26. import urllib
  27. import urllib2
  28. import sys
  29. import traceback
  30. import socket
  31. from SocketServer import ThreadingMixIn
  32. from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
  33. from urllib import *
  34.  
  35. from flvlib import tags
  36. from flvlib import helpers
  37. from flvlib.astypes import MalformedFLV
  38.  
  39. import zlib
  40. from StringIO import StringIO
  41. import hmac
  42. import hashlib
  43. import base64
  44.  
  45.  
  46. class MyHandler(BaseHTTPRequestHandler):
  47.     """
  48.    Serves a HEAD request
  49.    """
  50.     def do_HEAD(s):
  51.         print "XBMCLocalProxy: Serving HEAD request..."
  52.         s.answer_request(0)
  53.  
  54.     """
  55.    Serves a GET request.
  56.    """
  57.     def do_GET(s):
  58.         print "XBMCLocalProxy: Serving GET request..."
  59.         s.answer_request(1)
  60.  
  61.     def answer_request(s, sendData):
  62.         try:
  63.             request_path=s.path[1:]
  64.             request_path=re.sub(r"\?.*","",request_path)
  65.             if request_path=="stop":
  66.                 sys.exit()
  67.             elif request_path=="version":
  68.                 s.send_response(200)
  69.                 s.end_headers()
  70.                 s.wfile.write("Proxy: Running\r\n")
  71.                 s.wfile.write("Version: 0.1")
  72.             elif request_path[0:12]=="secureconne/":
  73.                 (realpath,sep,swfUrlb64)=request_path[12:].partition("/")
  74.                 fURL=base64.b64decode(realpath)
  75.                 swfUrl=base64.b64decode(swfUrlb64)
  76.                 print swfUrl
  77.                 print fURL
  78.                 s.serveFile(fURL, swfUrl, sendData)
  79.             else:
  80.                 s.send_response(403)
  81.         except:
  82.                 traceback.print_exc()
  83.                 s.wfile.close()
  84.                 return
  85.         try:
  86.             s.wfile.close()
  87.         except:
  88.             pass
  89.  
  90.            
  91.     """
  92.    Sends the requested file and add additional headers.
  93.    """
  94.     def serveFile(s, fURL, swfUrl, sendData):
  95.         opener = FancyURLopener()
  96.         opener.addheaders=[]
  97.         response = opener.open(fURL)
  98.         s.send_response(response.code)
  99.         print "XBMCLocalProxy: Sending headers..."
  100.         headers=response.info()
  101.         for key in headers:
  102.             try:
  103.                 val=headers[key]
  104.                 if 'content-length' == key.lower():
  105.                     s.send_header(key, str(500*1024*1024))
  106.                 else:
  107.                     s.send_header(key, val)
  108.             except Exception, e:
  109.                 print e
  110.                 pass
  111.         s.end_headers()
  112.        
  113.         if (sendData):
  114.             print "XBMCLocalProxy: Sending data..."
  115.             fileout=s.wfile
  116.             try:
  117.                 buf="INIT"
  118.                 firstBlock=True
  119.                 try:
  120.                     while (buf!=None and len(buf)>0):
  121.                         buf=response.read(200*1024)
  122.                         fileout.write(buf)
  123.                         fileout.flush()
  124.                         if firstBlock:
  125.                             EdgeClass(buf,fURL,swfUrl)
  126.                             firstBlock=False
  127.                     response.close()
  128.                     fileout.close()
  129.                     print time.asctime(),"Closing connection"
  130.                 except socket.error, e:
  131.                     print time.asctime(),"Client Closed the connection."
  132.                     try:
  133.                         response.close()
  134.                         fileout.close()
  135.                     except Exception, e:
  136.                         return
  137.                 except Exception,e:
  138.                     traceback.print_exc(file=sys.stdout)
  139.                     response.close()
  140.                     fileout.close()
  141.             except:
  142.                 traceback.print_exc()
  143.                 s.wfile.close()
  144.                 return
  145.         try:
  146.             s.wfile.close()
  147.         except:
  148.             pass
  149.  
  150.  
  151. class EdgeClass():
  152.     def __init__(self, data, url, swfUrl):
  153.         self.url = url
  154.         self.swfUrl = swfUrl
  155.         self.domain = self.url.split('://')[1].split('/')[0]
  156.         self.control = 'http://%s/control/' % self.domain
  157.         self.onEdge = self.extractTags(data,onEdge=True)
  158.         #self.MetaData = self.extractTags(data,onMetaData=True)
  159.         self.sendNewToken(self.onEdge['session'],self.onEdge['streamName'],self.swfUrl,self.control)
  160.  
  161.     def getURL(self, url, post=False, sessionID=False, sessionToken=False):
  162.         try:
  163.             print 'GetURL --> url = '+url
  164.             opener = urllib2.build_opener()
  165.             if sessionID and sessionToken:
  166.                 opener.addheaders = [('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:14.0) Gecko/20100101 Firefox/14.0.1' ),
  167.                                      ('x-Akamai-Streaming-SessionToken', sessionToken ),
  168.                                      ('x-Akamai-Streaming-SessionID', sessionID ),
  169.                                      ('Content-Type', 'text/xml' )]
  170.             else:
  171.                 opener.addheaders = [('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:14.0) Gecko/20100101 Firefox/14.0.1' )]
  172.             if not post:
  173.                 usock=opener.open(url)
  174.             else:
  175.                 usock=opener.open(url,':)')
  176.             response=usock.read()
  177.             usock.close()
  178.         except urllib2.URLError, e:
  179.             print 'Error reason: ', e
  180.             return False
  181.         else:
  182.             return response
  183.  
  184.     def extractTags(self, filedata, onEdge=True,onMetaData=False):
  185.         f = StringIO(filedata)
  186.         flv = tags.FLV(f)
  187.         try:
  188.             tag_generator = flv.iter_tags()
  189.             for i, tag in enumerate(tag_generator):
  190.                 if isinstance(tag, tags.ScriptTag):
  191.                     if tag.name == "onEdge" and onEdge:
  192.                         return tag.variable
  193.                     elif tag.name == "onMetaData" and onMetaData:
  194.                         return tag.variable
  195.         except MalformedFLV, e:
  196.             return False
  197.         except tags.EndOfFile:
  198.             return False
  199.         f.close()
  200.         return False
  201.        
  202.     def decompressSWF(self,f):
  203.         if type(f) is str:
  204.             f = StringIO(f)
  205.         f.seek(0, 0)
  206.         magic = f.read(3)
  207.         if magic == "CWS":
  208.             return "FWS" + f.read(5) + zlib.decompress(f.read())
  209.         elif magic == "FWS":
  210.             #SWF Not Compressed
  211.             f.seek(0, 0)
  212.             return f.read()
  213.         else:
  214.             #Not SWF
  215.             return None
  216.  
  217.     def MD5(self,data):
  218.         m = hashlib.md5()
  219.         m.update(data)
  220.         return m.digest()
  221.  
  222.     def makeToken(self,sessionID,swfUrl):
  223.         swfData = self.getURL(swfUrl)
  224.         decData = self.decompressSWF(swfData)
  225.         swfMD5 = self.MD5(decData)
  226.         data = sessionID+swfMD5
  227.         sig = hmac.new('foo', data, hashlib.sha1)
  228.         return base64.encodestring(sig.digest()).replace('\n','')
  229.  
  230.     def sendNewToken(self,sessionID,path,swf,domain):
  231.         sessionToken = self.makeToken(sessionID,swf)
  232.         commandUrl = domain+path+'?cmd=sendingNewToken&v=2.7.6&swf='+swf.replace('http://','http%3A//')
  233.         self.getURL(commandUrl,True,sessionID,sessionToken)
  234.    
  235.  
  236. class Server(HTTPServer):
  237.     """HTTPServer class with timeout."""
  238.  
  239.     def get_request(self):
  240.         """Get the request and client address from the socket."""
  241.         self.socket.settimeout(5.0)
  242.         result = None
  243.         while result is None:
  244.             try:
  245.                 result = self.socket.accept()
  246.             except socket.timeout:
  247.                 pass
  248.         result[0].settimeout(1000)
  249.         return result
  250.  
  251. class ThreadedHTTPServer(ThreadingMixIn, Server):
  252.     """Handle requests in a separate thread."""
  253.  
  254. HOST_NAME = '127.0.0.1'
  255. PORT_NUMBER = 64653
  256.  
  257. if __name__ == '__main__':
  258.     socket.setdefaulttimeout(10)
  259.     server_class = ThreadedHTTPServer
  260.     httpd = server_class((HOST_NAME, PORT_NUMBER), MyHandler)
  261.     print "XBMCLocalProxy Starts - %s:%s" % (HOST_NAME, PORT_NUMBER)
  262.     while(True):
  263.         httpd.handle_request()
  264.     httpd.server_close()
  265.     print "XBMCLocalProxy Stops %s:%s" % (HOST_NAME, PORT_NUMBER)
Add Comment
Please, Sign In to add comment