def setDBM(self, dbm):
        self.dbm = dbm
        #setup encryption password
        import anydbm

        dbm = anydbm.open(dbm, 'r')
        try:
            from resources.lib import encryption
            self.encrypt = encryption.encryption(dbm['salt'], dbm['password'])
        except:
            self.encrypt = None

        # login password?
        try:
            self.username = dbm['username']
            self.password = dbm['password']
        except:
            self.username = None
            self.password = None

        try:
            if dbm['hide'] == 'true':
                self.hide = True
            if dbm['keyvalue'] == 'true':
                self.keyvalue = True
        except:
            pass

        try:
            self.cryptoSalt = dbm['crypto_salt']
            self.cryptoPassword = dbm['crypto_password']
        except:
            pass

        dbm.close()
Пример #2
0
def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], "s:p:d:x:z:va", [
            "help", "directory=", "salt=", "password="******"search=", "replace="
        ])
    except getopt.GetoptError as err:
        # print help information and exit:
        print str(err)  # will print something like "option -a not recognized"
        usage()
        sys.exit(2)
    directory = None
    salt = None
    password = None
    search = None
    replace = None
    verbose = False
    decryptOnly = False
    wasEncrypted = False
    for o, a in opts:
        if o in ('-v'):
            verbose = True
        elif o in ('-a'):
            decryptOnly = True
        elif o in ("-p", "--password"):
            password = a
        elif o in ("-s", "--salt"):
            salt = a
        elif o in ("-h", "--help"):
            print "usage: "
            sys.exit()
        elif o in ("-d", "--directory"):
            directory = a
        elif o in ("-x", "--search"):
            search = a
        elif o in ("-z", "--replace"):
            replace = a
        else:
            assert False, "unhandled option"

    if (directory is None):
        print "No directory (-d) provided."
        print "-d directory [-s salt -p salt password -x search -z replace -a]"
        return

    if (salt is None or password is None):
        print "Crypto salt (-s) or password (-p) not provided."
        return

    encrypt = None
    if (salt is not None and password is not None):
        encrypt = encryption.encryption(salt, password)

    for root, dirs, files in os.walk(directory):
        for filename in files:
            if filename.endswith(".strm"):

                print "reading " + str(filename) + "\n"
                file = open(str(root) + '/' + str(filename), "r")
                url = file.read()
                file.close()

                if verbose:
                    print "url = " + str(url) + "\n"
                m = re.search("kv\=([^\&]+)", url)
                kv = None
                if m:
                    kv = m.group(1)
                    kv = encrypt.decryptString(kv)
                    wasEncrypted = True
                else:
                    kv = url
                m = re.search("^([^\?]+)\?", url)
                baseurl = None
                if m:
                    baseurl = m.group(1)
                    if verbose:
                        print "base url = " + str(baseurl) + "\n"
                if verbose:
                    print "kv = " + str(kv) + "\n"
                if (search is not None and replace is not None):
                    kv = kv.replace(search, replace)
                    if verbose:
                        print "kv (with replacements) = " + str(kv) + "\n"
                file = open(str(root) + '/' + str(filename), "w")
                if not decryptOnly:
                    kv = str(baseurl) + '?kv=' + str(encrypt.encryptString(kv))
                file.write(str(kv) + "\n")
                file.close()
Пример #3
0
from resources.lib import encryption
#from subprocess import call

import sys
import re
import os

saltFile = str(sys.argv[1])
password = str(sys.argv[2])
source = str(sys.argv[3])
target = str(sys.argv[4])

encrypt = encryption.encryption(saltFile, password)
#encrypt.encryptString(file)
#print encrypt.decryptString(file)


def encrypt_dir(source, target):

    current, dirs, files = os.walk(source).next()

    for file in files:
        encFile = encrypt.encryptString(file)
        encrypt.encryptFile(
            str(source) + '/' + str(file),
            str(target) + '/' + str(encFile))
        print str(source) + '/' + str(file) + ' -> ' + str(target) + '/' + str(
            encFile)
    for dir in dirs:
        encDIR = encrypt.encryptString(dir)
        os.mkdir(str(target) + '/' + str(encDIR))
Пример #4
0
from resources.lib import  encryption
#from subprocess import call

import sys
import re
import os

saltFile = str(sys.argv[1])
password = str(sys.argv[2])
stringToEncrypt = str(sys.argv[3])

encrypt = encryption.encryption(saltFile,password)
#encrypt.encryptString(file)
print encrypt.encryptString(stringToEncrypt)
#encrypt.decryptStream
#encrypt.encryptFile(file)
#encrypt.decryptFile(file+'.enc')

    def do_GET(self):

        # debug - print headers in log
        headers = str(self.headers)
        print(headers)

        start = ''
        end = ''
        startOffset = 0
        for r in re.finditer('Range\:\s+bytes\=(\d+)\-', headers, re.DOTALL):
            start = int(r.group(1))
            break
        for r in re.finditer('Range\:\s+bytes\=\d+\-(\d+)', headers,
                             re.DOTALL):
            end = int(r.group(1))
            break

        # passed a kill signal?
        if self.path == '/kill':
            self.server.ready = False
            return

        # redirect url to output
        elif self.path == '/play':

            if (self.server.crypto and start != '' and start > 16
                    and end == ''):
                #start = start - (16 - (end % 16))
                xbmc.log("START = " + str(start))
                startOffset = 16 - ((int(self.server.length) - start) % 16) + 8

#            if (self.server.crypto and start == 23474184 ):
#start = start - (16 - (end % 16))
#                start = 23474184 - 8
            url = self.server.playbackURL
            xbmc.log('GET ' + url + "\n" +
                     self.server.service.getHeadersEncoded() + "\n")
            if start == '':
                req = urllib2.Request(url, None,
                                      self.server.service.getHeadersList())
            else:
                req = urllib2.Request(
                    url, None,
                    self.server.service.getHeadersList(
                        additionalHeader='Range',
                        additionalValue='bytes=' + str(start - startOffset) +
                        '-' + str(end)))

            try:
                response = urllib2.urlopen(req)
            except urllib2.URLError, e:
                if e.code == 403 or e.code == 401:
                    xbmc.log("ERROR\n" +
                             self.server.service.getHeadersEncoded())
                    self.server.service.refreshToken()
                    req = urllib2.Request(url, None,
                                          self.server.service.getHeadersList())
                    try:
                        response = urllib2.urlopen(req)
                    except:
                        xbmc.log("STILL ERROR\n" +
                                 self.server.service.getHeadersEncoded())
                        return
                else:
                    return

            if start == '':
                self.send_response(200)
                self.send_header('Content-Length',
                                 response.info().getheader('Content-Length'))
            else:
                self.send_response(206)
                self.send_header(
                    'Content-Length',
                    str(
                        int(response.info().getheader('Content-Length')) -
                        startOffset))
                #self.send_header('Content-Range','bytes ' + str(start) + '-' +str(end))
                if end == '':
                    self.send_header(
                        'Content-Range', 'bytes ' + str(start) + '-' +
                        str(int(self.server.length) - 1) + '/' +
                        str(int(self.server.length)))
                else:
                    self.send_header(
                        'Content-Range', 'bytes ' + str(start) + '-' +
                        str(end) + '/' + str(int(self.server.length)))

                #self.send_header('Content-Range',response.info().getheader('Content-Range'))
                xbmc.log('Content-Range!!!' + str(start) + '-' +
                         str(int(self.server.length) - 1) + '/' +
                         str(int(self.server.length)) + "\n")

            xbmc.log(str(response.info()) + "\n")
            self.send_header('Content-Type',
                             response.info().getheader('Content-Type'))

            #            self.send_header('Content-Length',response.info().getheader('Content-Length'))
            self.send_header('Cache-Control',
                             response.info().getheader('Cache-Control'))
            self.send_header('Date', response.info().getheader('Date'))
            self.send_header('Content-type', 'video/mp4')
            self.send_header('Accept-Ranges', 'bytes')

            self.end_headers()

            ## may want to add more granular control over chunk fetches
            #self.wfile.write(response.read())

            if (self.server.crypto):

                self.server.settings.setCryptoParameters()

                from resources.lib import encryption
                decrypt = encryption.encryption(
                    self.server.settings.cryptoSalt,
                    self.server.settings.cryptoPassword)

                CHUNK = 16 * 1024
                decrypt.decryptStreamChunkOld(response,
                                              self.wfile,
                                              startOffset=startOffset)

            else:
                CHUNK = 16 * 1024
                while True:
                    chunk = response.read(CHUNK)
                    if not chunk:
                        break
                    self.wfile.write(chunk)

            response.close()
            #            self.send_header('Accept-Ranges','bytes')

            #self.send_header('ETag',response.info().getheader('ETag'))
            #self.send_header('Server',response.info().getheader('Server'))
            self.end_headers()

            ## may want to add more granular control over chunk fetches
            #self.wfile.write(response.read())

            if (self.server.crypto):

                self.server.settings.setCryptoParameters()

                from resources.lib import encryption
                decrypt = encryption.encryption(
                    self.server.settings.cryptoSalt,
                    self.server.settings.cryptoPassword)

                CHUNK = 16 * 1024
                decrypt.decryptStreamChunkOld(response, self.wfile, CHUNK)

            else:
                CHUNK = 16 * 1024
                while True:
                    chunk = response.read(CHUNK)
                    if not chunk:
                        break
                    self.wfile.write(chunk)

            #response_data = response.read()
            response.close()
Пример #7
0
    def do_GET(self):

        # debug - print headers in log
        headers = str(self.headers)
        print(headers)

        start = ''
        end = ''
        startOffset = 0
        for r in re.finditer('Range\:\s+bytes\=(\d+)\-' ,
                     headers, re.DOTALL):
          start = int(r.group(1))
          break
        for r in re.finditer('Range\:\s+bytes\=\d+\-(\d+)' ,
                     headers, re.DOTALL):
          end = int(r.group(1))
          break



        # passed a kill signal?
        if self.path == '/kill':
            self.server.ready = False
            return


        # redirect url to output
        elif self.path == '/play':


            if (self.server.crypto and start != '' and start > 16 and end == ''):
                #start = start - (16 - (end % 16))
                xbmc.log("START = " + str(start))
                startOffset = 16-(( int(self.server.length) - start) % 16)+8

#            if (self.server.crypto and start == 23474184 ):
                #start = start - (16 - (end % 16))
#                start = 23474184 - 8
            url =  self.server.playbackURL
            xbmc.log('GET ' + url + "\n" + self.server.service.getHeadersEncoded() + "\n")
            if start == '':
                req = urllib2.Request(url,  None,  self.server.service.getHeadersList())
            else:
                req = urllib2.Request(url,  None,  self.server.service.getHeadersList(additionalHeader='Range', additionalValue='bytes='+str(start- startOffset)+'-' + str(end)))

            try:
                response = urllib2.urlopen(req)
            except urllib2.URLError, e:
                if e.code == 403 or e.code == 401:
                    xbmc.log("ERROR\n" + self.server.service.getHeadersEncoded())
                    self.server.service.refreshToken()
                    req = urllib2.Request(url,  None,  self.server.service.getHeadersList())
                    try:
                        response = urllib2.urlopen(req)
                    except:
                        xbmc.log("STILL ERROR\n" + self.server.service.getHeadersEncoded())
                        return
                else:
                    return

            if start == '':
                self.send_response(200)
                self.send_header('Content-Length',response.info().getheader('Content-Length'))
            else:
                self.send_response(206)
                self.send_header('Content-Length', str(int(response.info().getheader('Content-Length'))-startOffset))
                #self.send_header('Content-Range','bytes ' + str(start) + '-' +str(end))
                if end == '':
                    self.send_header('Content-Range','bytes ' + str(start) + '-' +str(int(self.server.length)-1) + '/' +str(int(self.server.length)))
                else:
                    self.send_header('Content-Range','bytes ' + str(start) + '-' + str(end) + '/' +str(int(self.server.length)))

                #self.send_header('Content-Range',response.info().getheader('Content-Range'))
                xbmc.log('Content-Range!!!' + str(start) + '-' + str(int(self.server.length)-1) + '/' +str(int(self.server.length)) + "\n")

            xbmc.log(str(response.info()) + "\n")
            self.send_header('Content-Type',response.info().getheader('Content-Type'))

#            self.send_header('Content-Length',response.info().getheader('Content-Length'))
            self.send_header('Cache-Control',response.info().getheader('Cache-Control'))
            self.send_header('Date',response.info().getheader('Date'))
            self.send_header('Content-type','video/mp4')
            self.send_header('Accept-Ranges','bytes')

            self.end_headers()

            ## may want to add more granular control over chunk fetches
            #self.wfile.write(response.read())

            if (self.server.crypto):

                self.server.settings.setCryptoParameters()

                from resources.lib import  encryption
                decrypt = encryption.encryption(self.server.settings.cryptoSalt,self.server.settings.cryptoPassword)

                CHUNK = 16 * 1024
                decrypt.decryptStreamChunkOld(response,self.wfile, startOffset=startOffset)

            else:
                CHUNK = 16 * 1024
                while True:
                    chunk = response.read(CHUNK)
                    if not chunk:
                        break
                    self.wfile.write(chunk)

            response.close()
Пример #8
0
            self.send_header('Content-type','video/mp4')
#            self.send_header('Accept-Ranges','bytes')

            #self.send_header('ETag',response.info().getheader('ETag'))
            #self.send_header('Server',response.info().getheader('Server'))
            self.end_headers()

            ## may want to add more granular control over chunk fetches
            #self.wfile.write(response.read())

            if (self.server.crypto):

                self.server.settings.setCryptoParameters()

                from resources.lib import  encryption
                decrypt = encryption.encryption(self.server.settings.cryptoSalt,self.server.settings.cryptoPassword)

                CHUNK = 16 * 1024
                decrypt.decryptStreamChunkOld(response,self.wfile, CHUNK)

            else:
                CHUNK = 16 * 1024
                while True:
                    chunk = response.read(CHUNK)
                    if not chunk:
                        break
                    self.wfile.write(chunk)

            #response_data = response.read()
            response.close()
    def do_GET(self):

        decryptkeyvalue = self.path
        if re.search(r'kv\=', str(self.path)):
            from resources.lib import encryption

            results = re.search(r'kv\=(.*)$', str(self.path))
            if results:
                keyvalue = str(results.group(1))
                decryptkeyvalue = '/' + self.server.encrypt.decryptString(
                    keyvalue).strip()
                print decryptkeyvalue + "."

        # debug - print headers in log
        headers = str(self.headers)
        print(headers)

        start = ''
        end = ''
        startOffset = 0
        for r in re.finditer('Range\:\s+bytes\=(\d+)\-', headers, re.DOTALL):
            start = int(r.group(1))
            break
        for r in re.finditer('Range\:\s+bytes\=\d+\-(\d+)', headers,
                             re.DOTALL):
            end = int(r.group(1))
            break

        # passed a kill signal?
        if decryptkeyvalue == '/kill':
            self.send_response(200)
            self.end_headers()
            if self.server.username is not None:
                self.wfile.write(
                    '<html><form action="/kill" method="post">Username: <input type="text" name="username"><br />Password: <input type="password" name="password"><br /><input type="submit" value="Stop Server"></form></html>'
                )
            else:
                self.wfile.write(
                    '<html><form action="/kill" method="post"><input type="submit" value="Stop Server"></form></html>'
                )

            #self.server.ready = False
            return

        elif decryptkeyvalue == '/settings':
            self.send_response(200)
            self.end_headers()

            self.setings = {}
            file = open('./resources/settings.xml', "r")
            print "LOAD SETTINGS\n\n\n"
            for line in file:
                result = re.search(
                    r'\<setting id\=\"([^\"]+)\" type\=\"([^\"]+)\" values\=\"([^\"]+)\" default\=\"([^\"]+)\" label\=\"([^\"]+)\" \/\>',
                    str(line))
                if result is None:
                    result = re.search(
                        r'\<setting id\=\"([^\"]+)\" type\=\"([^\"]+)\"( )label\=\"([^\"]+)\" default\=\"([^\"]+)\" \/\>',
                        str(line))

                id = ''
                type = ''
                values = ''
                defaults = ''
                label = ''
                if result:
                    id = str(result.group(1))
                    type = str(result.group(2))
                    values = str(result.group(3))
                    defaults = str(result.group(4))
                    label = str(result.group(5))
                    print "ID = " + id + "\n"

        elif decryptkeyvalue == '/list' or decryptkeyvalue == '/':
            self.send_response(200)
            self.end_headers()
            if self.server.username is not None:
                self.wfile.write(
                    '<html><form action="/list" method="post">Username: <input type="text" name="username"><br />Password: <input type="password" name="password"><br /><input type="submit" value="Login"></form></html>'
                )
            else:
                self.wfile.write(
                    '<html><form action="/list" method="post"><input type="submit" value="Login"></form></html>'
                )

            #self.server.ready = False
            return

            #self.send_response(200)
            #self.end_headers()
            #xbmcplugin.assignOutputBuffer(self.wfile)

            mediaEngine = default.contentengine()
            mediaEngine.run(self, DBM=self.server.dbm, addon=self.server.addon)
            #self.wfile.write(outputBuffer)
            return

        # redirect url to output
        elif re.search(r'/play', str(decryptkeyvalue)):
            #            self.send_response(200)
            #            self.end_headers()
            count = 0
            isEncrypted = False
            results = re.search(r'/play\?count\=(\d+)\&encrypted\=true$',
                                str(decryptkeyvalue))
            #encrypted stream
            if results:
                count = int(results.group(1))
                isEncrypted = True
            #not encrypted stream
            else:
                results = re.search(r'/play\?count\=(\d+)$',
                                    str(decryptkeyvalue))
                if results:
                    count = int(results.group(1))

            #self.send_response(200)
            #self.end_headers()
            #xbmcplugin.assignOutputBuffer(self.wfile)
            #cookies = self.headers['Cookie']
            cookie = xbmcplugin.playbackBuffer.playback[count]['cookie']
            url = xbmcplugin.playbackBuffer.playback[count]['url']
            auth = xbmcplugin.playbackBuffer.playback[count]['auth']
            auth = auth.replace("+", ' ')

            length = 0
            try:
                length = xbmcplugin.playbackBuffer.playback[count]['length']
            except:
                length = 0
                start = ''

            endOffset = 0
            startOffset = 0
            newEnd = end
            specialEnd = 0

            if isEncrypted:

                from resources.lib import encryption
                decrypt = encryption.encryption(self.server.cryptoSalt,
                                                self.server.cryptoPassword)

                #
                # 1) start > 16 bytes, back up to nearest whole chunk of 16
                if (start != '' and start > 16 and end == ''):
                    #start = start - (16 - (end % 16))
                    # startOffset = 16-(( int(length) - start) % 16)+8 ##GOOD
                    startOffset = 16 - ((int(length) - start) % 16) + 8
                    newEnd = int(xbmcplugin.playbackBuffer.playback[count]
                                 ['length']) - 1
                    print "[1] START=" + str(start) + ', END=' + str(
                        end
                    ) + ', length=' + str(length) + ' , startOffset=' + str(
                        startOffset) + ' , endOffset=' + str(
                            endOffset) + ', newEnd=' + str(newEnd) + "\n"
                #tested - good**
                # 2) start > 16 bytes, back up to nearest whole chunk of 16, end < end of file
                elif (start != '' and start > 16
                      and end == int(xbmcplugin.playbackBuffer.playback[count]
                                     ['decryptedlength']) - 1):
                    finalChunkDifference = int(
                        xbmcplugin.playbackBuffer.playback[count]['length']
                    ) - int(xbmcplugin.playbackBuffer.playback[count]
                            ['decryptedlength'])

                    #start = start - (16 - (end % 16))
                    # startOffset = 16-(( int(length) - start) % 16)+8 ##GOOD
                    #startOffset = -(( int(end) - start - finalChunkDifference) % 16)
                    startOffset += finalChunkDifference - 8
                    newEnd = int(xbmcplugin.playbackBuffer.playback[count]
                                 ['length']) - 1
                    startOffset += 16 - ((end - start + 1) % 16)
                    print "[2] START=" + str(start) + ', END=' + str(
                        end
                    ) + ', length=' + str(length) + ' , startOffset=' + str(
                        startOffset) + ' , endOffset=' + str(
                            endOffset) + ', newEnd=' + str(newEnd) + "\n"

                #tested - good**
                # fetch all, return all
                elif (start == 0
                      and end == int(xbmcplugin.playbackBuffer.playback[count]
                                     ['decryptedlength']) - 1):
                    finalChunkDifference = int(
                        xbmcplugin.playbackBuffer.playback[count]['length']
                    ) - int(xbmcplugin.playbackBuffer.playback[count]
                            ['decryptedlength']) - 8

                    #start = start - (16 - (end % 16))
                    # startOffset = 16-(( int(length) - start) % 16)+8 ##GOOD
                    startOffset = 0
                    newEnd = int(xbmcplugin.playbackBuffer.playback[count]
                                 ['length']) - 1
                    print "[5] START=" + str(start) + ', END=' + str(
                        end
                    ) + ', length=' + str(length) + ' , startOffset=' + str(
                        startOffset) + ' , endOffset=' + str(
                            endOffset) + ', newEnd=' + str(newEnd) + "\n"

                #?issue *problems
                elif (start != '' and start > 16 and end != ''):
                    #start = start - (16 - (end % 16))
                    # startOffset = 16-(( int(length) - start) % 16)+8 ##GOOD
                    #startOffset = 16-(( int(end+1) - start) % 16)+8
                    startOffset = 0  #8
                    endOffset = 16 - ((end - start + 1 + 8) % 16)
                    newEnd = end + endOffset + 8
                    #specialEnd = endOffset
                    print "[3] START=" + str(start) + ', END=' + str(
                        end
                    ) + ', length=' + str(length) + ' , startOffset=' + str(
                        startOffset) + ' , endOffset=' + str(
                            endOffset) + ', newEnd=' + str(newEnd) + "\n"
                #tested - good**
                # special case - end < 16 (such as first 2 bytes (apple)
                elif (end < 16):
                    #start = start - (16 - (end % 16))
                    # startOffset = 16-(( int(length) - start) % 16)+8 ##GOOD
                    endOffset = 16 - int(end)
                    newEnd = 15 + 8
                    print "[4] START=" + str(start) + ', END=' + str(
                        end
                    ) + ', length=' + str(length) + ' , startOffset=' + str(
                        startOffset) + ' , endOffset=' + str(
                            endOffset) + ', newEnd=' + str(newEnd) + "\n"

            if start == '':
                #                req = urllib2.Request(url,  None,  { 'Cookie' : 'DRIVE_STREAM='+ cookie, 'Authorization' : auth})
                req = urllib2.Request(url, None, {
                    'Cookie': 'DRIVE_STREAM=' + cookie,
                    'Authorization': auth
                })
            else:
                req = urllib2.Request(
                    url, None, {
                        'Cookie':
                        'DRIVE_STREAM=' + cookie,
                        'Authorization':
                        auth,
                        'Range':
                        'bytes=' + str(int(start - startOffset)) + '-' +
                        str(newEnd)
                    })
                #req = urllib2.Request(url,  None,  { 'Cookie' : 'DRIVE_STREAM='+ cookie, 'Authorization' : auth, 'Range': 'bytes='+str(int(start- startOffset))+'-' + str(int(xbmcplugin.playbackBuffer.playback[count]['decryptedlength'])-1)})

            try:
                response = urllib2.urlopen(req)
            except urllib2.URLError, e:
                if e.code == 403 or e.code == 401:
                    print "STILL ERROR" + str(e.code) + "\n"
                    return
                else:
                    return

            # first fetch (no start specified, or 0)
            if start == '':
                xbmcplugin.playbackBuffer.playback[count][
                    'length'] = response.info().getheader('Content-Length')
                #for encrypted streams
                # need to fetch the last 16 bytes to calculate unpadded size
                if isEncrypted:
                    response.close()
                    req = urllib2.Request(
                        url, None, {
                            'Cookie':
                            'DRIVE_STREAM=' + cookie,
                            'Authorization':
                            auth,
                            'Range':
                            'bytes=' + str(
                                int(xbmcplugin.playbackBuffer.playback[count]
                                    ['length']) - 16 - 8) + '-'
                        })
                    try:
                        response = urllib2.urlopen(req)
                    except urllib2.URLError, e:
                        if e.code == 403 or e.code == 401:
                            print "STILL ERROR" + str(e.code) + "\n"
                            return
                        else:
                            return
                    CHUNK = 16 * 1024

                    #originalSize = decrypt.decryptCalculateSizing(response)
                    #print "size " + response.info().getheader('Content-Length') + ' vs ' + str(originalSize) + "\n"
                    #return
                    finalChunkDifference = decrypt.decryptCalculatePadding(
                        response, chunksize=CHUNK)
                    #xbmcplugin.playbackBuffer.playback[count]['length'] = int(xbmcplugin.playbackBuffer.playback[count]['length']) - finalChunkDifference
                    xbmcplugin.playbackBuffer.playback[count][
                        'decryptedlength'] = int(
                            xbmcplugin.playbackBuffer.playback[count]
                            ['length']) - finalChunkDifference - 8
                    print "FINAL CHUNK SIZE DIFFERENCE " + str(
                        finalChunkDifference) + "\n"
                    print "length " + str(xbmcplugin.playbackBuffer.
                                          playback[count]['length']) + "\n"
                    print "decryptedlength " + str(
                        xbmcplugin.playbackBuffer.playback[count]
                        ['decryptedlength']) + "\n"
                    req = urllib2.Request(url, None, {
                        'Cookie': 'DRIVE_STREAM=' + cookie,
                        'Authorization': auth
                    })
                    try:
                        response = urllib2.urlopen(req)
                    except urllib2.URLError, e:
                        if e.code == 403 or e.code == 401:
                            print "STILL ERROR" + str(e.code) + "\n"
                            return
                        else:
                            return
	def do_GET(self):
		# debug - print headers in log
		headers = str(self.headers)
		print(headers)

		start = ''
		end = ''
		startOffset = 0

		for r in re.finditer('Range\:\s+bytes\=(\d+)\-', headers, re.DOTALL):
			start = int(r.group(1) )
			break

		for r in re.finditer('Range\:\s+bytes\=\d+\-(\d+)', headers, re.DOTALL):
			end = int(r.group(1) )
			break

		# passed a kill signal?
		if self.path == '/kill':
			self.server.ready = False
			return

		# redirect url to output
		elif self.path == '/play':

			if (self.server.crypto and start != '' and start > 16 and end == ''):
				#start = start - (16 - (end % 16) )
				xbmc.log("START = " + str(start) )
				startOffset = 16 - ( (int(self.server.length) - start) % 16) + 8

#			 if (self.server.crypto and start == 23474184):
				#start = start - (16 - (end % 16) )
#				start = 23474184 - 8

			url = self.server.playbackURL
			xbmc.log('GET ' + url + "\n" + self.server.service.getHeadersEncoded() + "\n")

			if start == '':
				req = urllib.request.Request(url, None, self.server.service.getHeadersList() )
			else:
				req = urllib.request.Request(url, None, self.server.service.getHeadersList(additionalHeader='Range', additionalValue='bytes=' + str(start- startOffset) + '-' + str(end) ) )

			try:
				response = urllib.request.urlopen(req)
			except urllib.error.URLError as e:

				if e.code == 403 or e.code == 401:
					xbmc.log("ERROR\n" + self.server.service.getHeadersEncoded() )
					self.server.service.refreshToken()
					req = urllib.request.Request(url, None, self.server.service.getHeadersList() )

					try:
						response = urllib.request.urlopen(req)
					except:
						xbmc.log("STILL ERROR\n" + self.server.service.getHeadersEncoded() )
						return
				else:
					return

			if start == '':
				self.send_response(200)
				self.send_header('Content-Length', response.info().get('Content-Length') )
			else:
				self.send_response(206)
				self.send_header('Content-Length', str(int(response.info().get('Content-Length') ) - startOffset) )
				#self.send_header('Content-Range', 'bytes ' + str(start) + '-' + str(end) )

				if end == '':
					self.send_header('Content-Range', 'bytes ' + str(start) + '-' + str(int(self.server.length) - 1) + '/' + str(int(self.server.length) ) )
				else:
					self.send_header('Content-Range', 'bytes ' + str(start) + '-' + str(end) + '/' + str(int(self.server.length) ) )

				#self.send_header('Content-Range', response.info().get('Content-Range') )
				xbmc.log('Content-Range!!!' + str(start) + '-' + str(int(self.server.length) - 1) + '/' + str(int(self.server.length) ) + "\n")

			xbmc.log(str(response.info() ) + "\n")
			self.send_header('Content-Type', response.info().get('Content-Type') )

#			 self.send_header('Content-Length', response.info().get('Content-Length') )
			self.send_header('Cache-Control', response.info().get('Cache-Control') )
			self.send_header('Date', response.info().get('Date') )
			self.send_header('Content-type', 'video/mp4')
			self.send_header('Accept-Ranges', 'bytes')

			self.end_headers()

			## may want to add more granular control over chunk fetches
			#self.wfile.write(response.read() )

			if (self.server.crypto):
				from resources.lib import encryption
				decrypt = encryption.encryption(self.server.addon.getSetting("crypto_salt"), self.server.addon.getSetting("crypto_password") )

				CHUNK = 16 * 1024
				decrypt.decryptStreamChunkOld(response, self.wfile, startOffset=startOffset)

			response.close()

		# redirect url to output
		elif self.path == '/enroll':
			self.send_response(200)
			self.end_headers()
			self.wfile.write(b'''
			<html>
			<head>
			<meta name="viewport" content="width=device-width, initial-scale=1">
			<style>
			.container {
							position: absolute;
							top: 50%;
							left: 50%;
							-moz-transform: translateX(-50%) translateY(-50%);
							-webkit-transform: translateX(-50%) translateY(-50%);
							transform: translateX(-50%) translateY(-50%);
							background-color: 080808;
							border: 1px solid black;
							height: 200px;
							width: 300px;
							background-color: #0F0F0F;
							box-shadow: 5px 10px;
			}
			.inner {
							position: absolute;
							top: 50%;
							left: 50%;
							-moz-transform: translateX(-50%) translateY(-50%);
							-webkit-transform: translateX(-50%) translateY(-50%);
							transform: translateX(-50%) translateY(-50%);
			}
			.input {
							width: 200px;
							height: 26px;
							border: 0.6px solid black;
							background-color: #2E2E2E;
			}
			.button {
							width: 200px;
							height: 26px;
							border: 0.6px solid black;
							background-color: #1D1D1D;
							margin-top: 21px;

			}
			body {
							background-color: #080808;
			}
			</style>
			</head>
			<body>
			<div class="container">
			<form action="/enroll?default=false" method="post">
			<div class="inner">
			<input div class="input" style="color:white" type="text" name="client_id" placeholder="Client ID">
			<br/>
			<br/>
			<input div class="input" style="color:white" type="text" name="client_secret" placeholder="Client Secret">
			<br/>
			<input div class="button" style="color:white" type="submit" value="Submit">
			</div>
			</div>
			</form>
			</body>
			</html>''')
			return