예제 #1
0
파일: naclkeys.py 프로젝트: Rendaw/bizast
 def save(self, default=False):
     if not self.fileroot:
         self.fileroot = keydir
         mkdirs(keydir)
     if not self.filename:
         self.filename = os.path.join(self.fileroot, self.name)
     if self.new:
         fd = os.open(self.filename, os.O_WRONLY | os.O_CREAT | os.O_EXCL)
         file = os.fdopen(fd, 'w')
         if not file:
             raise RuntimeError(
                 'Key file [{}] already exists'.format(filename))
         file.write(self.dump())
         file.close()
         self.new = False
     else:
         temp = tempfile.NamedTemporaryFile(dir=self.fileroot, delete=False)
         temp.write(self.dump())
         temp.close()
         os.rename(temp.name, self.filename)
     if default:
         self._write_default(self.filename)
예제 #2
0
파일: bizast.py 프로젝트: Rendaw/bizast
def twisted_main(args):
    log_observer = log.FileLogObserver(sys.stdout, log.INFO)
    log_observer.start()

    # Load state
    root = appdirs.user_cache_dir(args.instancename, 'zarbosoft')
    mkdirs(root)
    state = {}
    try:
        with open(os.path.join(root, 'state.json'), 'r') as prestate:
            state = json.loads(prestate.read())
    except Exception as e:
        if args.verbose:
            log_info('Failed to load state: {}'.format(e))
    republish = state.get('republish', {})

    # Set up kademlia

    kserver = Server(
        ksize=state.get('ksize', 20), 
        alpha=state.get('alpha', 3), 
        seed=binascii.unhexlify(state['seed']) if 'seed' in state else None, 
        storage=Storage(args))
    bootstraps = map(tuple, state.get('bootstrap', []))
    for bootstrap in args.bootstrap:
        bhost, bport = bootstrap.split(':', 2)
        bport = int(bport)
        bhost_ip = yield reactor.resolve(bhost)
        bootstraps.append((bhost_ip, bport))
    if args.verbose:
        log_info('Bootstrapping hosts: {}'.format(bootstraps))
    kserver.bootstrap(bootstraps)

    udpserver = internet.UDPServer(args.dhtport, kserver.protocol)
    udpserver.startService()

    # Set up state saver
    def save_state():
        if args.verbose:
            log_info('Saving state')
        state['ksize'] = kserver.ksize
        state['alpha'] = kserver.alpha
        state['seed'] = binascii.hexlify(kserver.node.seed)
        state['republish'] = republish
        state['bootstrap'] = kserver.bootstrappableNeighbors()
        with open(os.path.join(root, 'state.json.1'), 'w') as prestate:
            prestate.write(json.dumps(state))
        os.rename(
            os.path.join(root, 'state.json.1'), 
            os.path.join(root, 'state.json'))

    save_state_loop = LoopingCall(save_state)
    save_state_loop.start(60)

    # Set up value republisher
    def start_republish():
        @defer.inlineCallbacks
        def republish_call():
            for key, val in republish.items():
                if args.verbose:
                    log_info('Republishing {}'.format(key))
                yield kserver.set(key, val)
        republish_loop = LoopingCall(republish_call)
        republish_loop.start(1 * 60 * 60 * 24)
    deferLater(reactor, 60, start_republish)

    # Set up webserver
    with open(res('redirect_template.html'), 'r') as template:
        redirect_template = template.read()
    class Resource(resource.Resource):
        def getChild(self, child, request):
            return self

        def render_GET(self, request):
            key = urllib.unquote(request.path[1:])
            if key == 'setup':
                with open(res('browser_setup.html'), 'r') as static:
                    return static.read()
            if key == 'icon-bizast-off.png':
                with open(res('icon-bizast-off.png'), 'r') as static:
                    return static.read()
            if key.startswith(webprotocol):
                key = key[len(webprotocol):]
            if key.startswith(webprotocol2):
                key = key[len(webprotocol2):]
            if key.count(':') != 1:
                raise ValueError('Invalid resource id')
            try:
                key, path = key.split('/', 1)
                path = '/' + path
            except ValueError:
                path = ''
            def respond(value):
                if not value:
                    request.write(NoResource().render(request))
                else:
                    valid, ign, ign = validate(args, None, value, None)
                    if not valid:
                        request.write(NoResource('Received invalid resource: {}'.format(value)).render(request))
                    else:
                        value = json.loads(value)
                        if any('text/html' in val for val in request.requestHeaders.getRawHeaders('Accept', [])):
                            message = value['message'] + path
                            if urlmatch.match(message) and '\'' not in message and '"' not in message:
                                request.write(redirect_template.format(
                                    resource=message).encode('utf-8'))
                            else:
                                request.write(message.encode('utf-8'))
                        else:
                            request.write(json.dumps(value))
                request.finish()
            log.msg('GET: key [{}]'.format(key))
            d = kserver.get(key)
            d.addCallback(respond)
            return server.NOT_DONE_YET

        def render_POST(self, request):
            value = request.content.getvalue()
            valid, rec_key, fingerprint = validate(args, None, value, None)
            if not valid:
                raise ValueError('Failed verification')
            log.msg('SET: key [{}] = val [{}]'.format(rec_key, value))
            republish[rec_key] = value
            def respond(result):
                request.write('Success')
                request.finish()
            d = kserver.set(rec_key, value)
            d.addCallback(respond)
            return server.NOT_DONE_YET
        
        def render_DELETE(self, request):
            key = urllib.unquote(request.path[1:])
            if key.startswith(webprotocol):
                key = key[len(webprotocol):]
            if key.count(':') != 1:
                raise ValueError('Invalid resource id')
            if key not in republish:
                raise ValueError('Not republishing key {}'.format(key))
            del republish[key]
            return 'Success'

    webserver = internet.TCPServer(args.webport, server.Site(Resource()))
    webserver.startService()
예제 #3
0
파일: naclkeys.py 프로젝트: Rendaw/bizast
def main():
    parser = argparse.ArgumentParser(
        description='NaCl key management tool',
    )
    commands = parser.add_subparsers(dest='command')

    def add_common_subparser(*pargs, **kwargs):
        out = commands.add_parser(*pargs, **kwargs)
        out.add_argument(
            '-v',
            '--verbose',
            action='store_true',
            help='Enable verbose output',
        )
        return out

    gen_command = add_common_subparser('gen', description='Generate key')
    gen_command.add_argument(
        'name', 
        help='Name of key. Preferably something easy to type',
    )
    gen_command.add_argument(
        '-n', 
        '--nopassphrase',
        help='Don\'t encrypt key',
        action='store_true',
    )
    gen_command.add_argument(
        '-u', 
        '--dump',
        help='Print rather than store key',
        action='store_true',
    )
    gen_command.add_argument(
        '-a', 
        '--alternate',
        help='Don\'t make the new key the default',
        action='store_true',
    )
    
    mod_command = add_common_subparser('mod', description='Modify key')
    mod_command.add_argument(
        '-k',
        '--key', 
        help='Key name or filename.  Use default key if unspecified',
    )
    mod_command.add_argument(
        '-p', 
        '--passphrase',
        help='Set or change passphrase',
        action='store_true',
    )
    mod_command.add_argument(
        '-r', 
        '--remove-passphrase',
        help='Remove passphrase',
        action='store_true',
    )
    mod_command.add_argument(
        '-d', 
        '--default',
        help='Make key default',
        action='store_true',
    )
    
    args = parser.parse_args()

    mkdirs(keydir)

    if args.command == 'gen':
        key = Key.new(args.name)
        if args.alternate and args.dump:
            parser.error('Can\'t specify both alternate and print')
        if not args.nopassphrase:
            key.set_passphrase()
        if args.dump:
            print(key.dump())
        else:
            key.save(not args.alternate)
            print(key.fingerprint)

    elif args.command == 'mod':
        key = Key.open(args.key, args.passphrase)
        if args.passphrase or args.remove_passphrase:
            if args.passphrase:
                key.set_passphrase()
            elif args.remove_passphrase:
                key.remove_passphrase()
        key.save(args.default)