Exemplo n.º 1
0
Arquivo: Api.py Projeto: carlchina/nut
def getInstall(request, response):
    nsp = Nsps.getByTitleId(request.bits[2])

    try:
        url = ('%s:%s@%s:%d/api/download/%s/title.nsp' %
               (request.user.id, request.user.password, Config.server.hostname,
                Config.server.port, request.bits[2]))
        Print.info('Installing ' + url)
        file_list_payloadBytes = url.encode('ascii')

        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        #sock.settimeout(1)
        sock.connect((request.user.switchHost, request.user.switchPort))
        #sock.settimeout(99999)

        sock.sendall(
            struct.pack('!L', len(file_list_payloadBytes)) +
            file_list_payloadBytes)
        while len(sock.recv(1)) < 1:
            time.sleep(0.05)
        sock.close()
        response.write(
            json.dumps({
                'success': True,
                'message': 'install successful'
            }))
    except BaseException as e:
        response.write(json.dumps({'success': False, 'message': str(e)}))
Exemplo n.º 2
0
	def suggest(self, titleId, titleKey):
		if not titleId or not titleKey:
			raise IndexError('Missing values')

		titleId = titleId.upper()
		nsp = Nsps.getByTitleId(titleId)

		if not nsp:
			raise IOError('Title not found: ' + titleId)

		nsp.open()

		for f in nsp:
			if type(f) == Fs.Nca and f.header.contentType == Type.Content.PROGRAM:
				for fs in f.sectionFilesystems:
					if fs.fsType == Type.Fs.PFS0 and fs.cryptoType == Type.Crypto.CTR:
						f.seek(0)
						ncaHeader = f.read(0x400)

						sectionHeaderBlock = fs.buffer

						f.seek(fs.offset)
						pfs0Header = f.read(0x10)

						entry = KeyEntry(titleId, titleKey.upper(), ncaHeader, sectionHeaderBlock, pfs0Header, fs.offset)

						index = blockchain.new_transaction(entry)

						blockchain.new_block()

						return True

		return False
Exemplo n.º 3
0
def getDownload(request, response):
    nsp = Nsps.getByTitleId(request.bits[2])
    #Print.info('Downloading ' + nsp.path)
    response.attachFile(os.path.basename(nsp.path))

    chunkSize = 0x10000

    with open(nsp.path, "rb") as f:
        f.seek(0, 2)
        size = f.tell()
        if 'Range' in request.headers:
            start, end = request.headers.get('Range').strip().strip(
                'bytes=').split('-')

            if end == '':
                end = size - 1
            else:
                end = int(end) + 1

            if start == '':
                start = size - end
            else:
                start = int(start)

            if start >= size or end > size or start < 0 or end <= 0:
                return Server.Response400(request, response,
                                          'Invalid range request')

            response.setStatus(206)

        else:
            start = 0
            end = size

        f.seek(start, 0)

        response.setMime(nsp.path)
        response.setHeader('Accept-Ranges', 'bytes')
        response.setHeader('Content-Range',
                           'bytes %s-%s/%s' % (start, end - 1, size))
        response.setHeader('Content-Length', str(end - start))
        #Print.info(response.headers['Content-Range'])
        response.sendHeader()

        if not response.head:
            size = end - start

            i = 0

            while i < size:
                chunk = f.read(min(size - i, chunkSize))
                i += len(chunk)

                if chunk:
                    pass
                    response.write(chunk)
                else:
                    break
Exemplo n.º 4
0
Arquivo: Api.py Projeto: carlchina/nut
def getInfo(request, response):
    try:
        nsp = Nsps.getByTitleId(request.bits[2])
        t = Titles.get(request.bits[2]).__dict__
        t['size'] = nsp.getFileSize()
        t['mtime'] = nsp.getFileModified()
        response.write(json.dumps(t))
    except BaseException as e:
        response.write(json.dumps({'success': False, 'message': str(e)}))
Exemplo n.º 5
0
def verifyKey(titleId=None, titleKey=None):
    try:
        if not titleId:
            titleId = request.args.get('titleId')

        if not titleKey:
            titleKey = request.args.get('titleKey')

        # Check that the required fields are in the POST'ed data
        required = ['titleId', 'titleKey']
        if not titleId or not titleKey:
            return False

        titleId = titleId.upper()

        if blockchain.hasTitle(titleId):
            if blockchain.hasTitle(titleId) == titleKey:
                return True
            else:
                return False

        nsp = Nsps.getByTitleId(titleId)

        if not nsp:
            return False

        nsp.open()

        for f in nsp:
            if type(
                    f
            ) == Fs.Nca and f.header.contentType == Type.Content.PROGRAM:
                for fs in f.sectionFilesystems:
                    if fs.fsType == Type.Fs.PFS0 and fs.cryptoType == Type.Crypto.CTR:
                        f.seek(0)
                        ncaHeader = f.read(0x400)

                        sectionHeaderBlock = fs.buffer

                        f.seek(fs.offset)
                        pfs0Header = f.read(0x10)

                        entry = KeyEntry(titleId, titleKey.upper(), ncaHeader,
                                         sectionHeaderBlock, pfs0Header,
                                         fs.offset)

                        index = blockchain.new_transaction(entry)

                        blockchain.new_block()
                        nsp.close()
                        return True
        nsp.close()

        return False
    except BaseException as e:
        nsp.close()
        return False
Exemplo n.º 6
0
def new_suggestion():
    try:
        titleId = request.args.get('titleId')
        titleKey = request.args.get('titleKey')

        # Check that the required fields are in the POST'ed data
        required = ['titleId', 'titleKey']
        if not titleId or not titleKey:
            return 'Missing values', 400

        titleId = titleId.upper()
        nsp = Nsps.getByTitleId(titleId)

        if not nsp:
            return 'Title not found', 400

        nsp.open()

        for f in nsp:
            if type(
                    f
            ) == Fs.Nca and f.header.contentType == Type.Content.PROGRAM:
                for fs in f.sectionFilesystems:
                    if fs.fsType == Type.Fs.PFS0 and fs.cryptoType == Type.Crypto.CTR:
                        f.seek(0)
                        ncaHeader = f.read(0x400)

                        sectionHeaderBlock = fs.buffer

                        f.seek(fs.offset)
                        pfs0Header = f.read(0x10)

                        entry = KeyEntry(titleId, titleKey.upper(), ncaHeader,
                                         sectionHeaderBlock, pfs0Header,
                                         fs.offset)

                        index = blockchain.new_transaction(entry)

                        blockchain.new_block()

                        response = {
                            'message':
                            f'Transaction will be added to Block {index}'
                        }
                        return jsonify(response), 201

        return 'Verification failed: unable to locate correct title rights partition', 400
    except BaseException as e:
        return str(e), 400
Exemplo n.º 7
0
Arquivo: Api.py Projeto: carlchina/nut
def getDownload(request, response, start=None, end=None):
    try:
        nsp = Nsps.getByTitleId(request.bits[2])
        response.attachFile(nsp.titleId + '.nsp')

        if len(request.bits) >= 5:
            start = int(request.bits[3])
            end = int(request.bits[4])

        chunkSize = 0x400000

        with open(nsp.path, "rb") as f:
            f.seek(0, 2)
            size = f.tell()
            if 'Range' in request.headers:
                start, end = request.headers.get('Range').strip().strip(
                    'bytes=').split('-')

                if end == '':
                    end = size - 1
                else:
                    end = int(end) + 1

                if start == '':
                    start = size - end
                else:
                    start = int(start)

                if start >= size or end > size or start < 0 or end <= 0:
                    return Server.Response400(request, response,
                                              'Invalid range request')

                response.setStatus(206)

            else:
                if start == None:
                    start = 0
                if end == None:
                    end = size

            if end >= size:
                end = size

                if end <= start:
                    response.write(b'')
                    return

            print('ranged request for %d - %d' % (start, end))
            f.seek(start, 0)

            response.setMime(nsp.path)
            response.setHeader('Accept-Ranges', 'bytes')
            response.setHeader('Content-Range',
                               'bytes %s-%s/%s' % (start, end - 1, size))
            response.setHeader('Content-Length', str(end - start))
            #Print.info(response.headers['Content-Range'])
            response.sendHeader()

            if not response.head:
                size = end - start

                i = 0

                while i < size:
                    chunk = f.read(min(size - i, chunkSize))
                    i += len(chunk)

                    if chunk:
                        pass
                        response.write(chunk)
                    else:
                        break
    except BaseException as e:
        Print.error('NSP download exception: ' + str(e))
    if response.bytesSent == 0:
        response.write(b'')
Exemplo n.º 8
0
def verifyKey(titleId=None, titleKey=None):
    try:
        if not titleId:
            titleId = request.args.get('titleId')

        if not titleKey:
            titleKey = request.args.get('titleKey')

        # Check that the required fields are in the POST'ed data
        required = ['titleId', 'titleKey']
        if not titleId or not titleKey:
            return False

        titleId = titleId.upper()

        if blockchain.hasTitle(titleId):
            if blockchain.hasTitle(titleId) == titleKey:
                return True
            else:
                return False

        nsp = Nsps.getByTitleId(titleId)

        if not nsp:
            Print.info('404 ' + titleId)
            return False

        nsp.open()

        for f in nsp:
            if type(
                    f
            ) == Fs.Nca and f.header.contentType == Type.Content.PROGRAM:
                for fs in f.sectionFilesystems:
                    if fs.fsType == Type.Fs.PFS0 and fs.cryptoType == Type.Crypto.CTR:
                        f.seek(0)
                        ncaHeader = f.read(0x400)

                        sectionHeaderBlock = fs.buffer

                        f.seek(fs.offset)
                        pfs0Header = f.read(0x10)

                        entry = KeyEntry(titleId, titleKey.upper(), ncaHeader,
                                         sectionHeaderBlock, pfs0Header,
                                         fs.offset)

                        index = blockchain.new_transaction(entry)

                        blockchain.new_block()
                        nsp.close()
                        return True

        for f in nsp:
            if type(f) == Fs.Nca:
                for fs in f.sectionFilesystems:
                    if fs.fsType == Type.Fs.ROMFS and fs.cryptoType == Type.Crypto.CTR:
                        f.seek(0)
                        ncaHeader = f.read(0x400)

                        sectionHeaderBlock = fs.buffer

                        levelOffset = int.from_bytes(
                            sectionHeaderBlock[0x18:0x20],
                            byteorder='little',
                            signed=False)
                        levelSize = int.from_bytes(
                            sectionHeaderBlock[0x20:0x28],
                            byteorder='little',
                            signed=False)

                        offset = fs.offset + levelOffset

                        f.seek(offset)
                        pfs0Header = f.read(levelSize)

                        entry = KeyEntry(titleId, titleKey.upper(), ncaHeader,
                                         sectionHeaderBlock, pfs0Header,
                                         offset)

                        index = blockchain.new_transaction(entry)

                        blockchain.new_block()
                        nsp.close()
                        return True

        nsp.close()

        return False
    except BaseException as e:
        print('key exception: ' + str(e))
        nsp.close()
        return False