コード例 #1
0
ファイル: Api.py プロジェクト: zhentan/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)}))
コード例 #2
0
def getInfo(request, response):
    try:
        nsp = Nsps.getByTitleId(request.bits[2])
        t = {'id': request.bits[2]}
        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)}))
コード例 #3
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

		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, fs = fs)

						index = blockchain.new_transaction(entry)

						blockchain.new_block()
						return True

		return False
コード例 #4
0
def getInfo(request, response):
    try:
        response.headers['Content-Type'] = 'application/json'
        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)}))
コード例 #5
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
コード例 #6
0
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[-2])
            end = int(request.bits[-1])

        #chunkSize = 0x1000000
        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 start < 0 or end <= 0:
                    return Server.Response400(
                        request, response,
                        'Invalid range request %d - %d' % (start, end))

                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
                status = Status.create(
                    size, 'Downloading ' + os.path.basename(nsp.path))

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

                    status.add(len(chunk))

                    if chunk:
                        pass
                        response.write(chunk)
                    else:
                        break
                status.close()
    except BaseException as e:
        Print.error('NSP download exception: ' + str(e))
        traceback.print_exc(file=sys.stdout)
    if response.bytesSent == 0:
        response.write(b'')
コード例 #7
0
ファイル: nut.py プロジェクト: blawar/nut
                else:
                    Print.info('Title key is INVALID %s - %s' %
                               (args.verify[0], args.verify[1]))

            if args.restore:
                nut.initTitles()
                nut.initFiles()
                prev = Config.extractVersion
                Config.extractVersion = True

                for path in expandFiles(args.file):
                    try:
                        f = Fs.factory(str(path))
                        f.setPath(str(path))
                        if f and f.titleId:
                            dt = Nsps.getByTitleId(f.titleId)
                            if dt and int(dt.version) >= int(
                                    f.getFileVersion()):
                                f.moveDupe()
                                continue

                        f.open(str(path), 'r+b')
                        f.restore()
                        f.close()
                        Print.info('restored %s' % f._path)

                        if args.output:
                            newPath = os.path.join(args.output,
                                                   os.path.basename(f._path))
                            Print.info('moving %s -> %s' % (path, newPath))
                            shutil.move(f._path, newPath)
コード例 #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