Пример #1
0
    def create_credentials():
        """
        Create PKI credentials for TLS access to libvirtd.

        Credentials are not signed by the host CA. This only allows
        unverified access but removes the need to transfer files
        between the host and the guest.
        """
        path = FilePath(tempfile.mkdtemp())
        try:
            ca = RootCredential.initialize(path, b"mycluster")
            NodeCredential.initialize(path, ca, uuid='client')
            ca_dir = FilePath('/etc/pki/CA')
            if not ca_dir.exists():
                ca_dir.makedirs()
            path.child(AUTHORITY_CERTIFICATE_FILENAME).copyTo(
                FilePath('/etc/pki/CA/cacert.pem')
            )
            client_key_dir = FilePath('/etc/pki/libvirt/private')
            if not client_key_dir.exists():
                client_key_dir.makedirs()
            client_key_dir.chmod(0700)
            path.child('client.key').copyTo(
                client_key_dir.child('clientkey.pem')
            )
            path.child('client.crt').copyTo(
                FilePath('/etc/pki/libvirt/clientcert.pem')
            )
        finally:
            path.remove()
Пример #2
0
    def test_no_logging_if_permission_denied(self):
        """
        If there is no permission to write to the given directory this does
        not prevent the script from running.
        """
        options = usage.Options()
        sys = FakeSysModule(argv=[b"mythingie"])
        logs = FilePath(self.mktemp())
        logs.makedirs()
        logs.chmod(0)
        self.addCleanup(logs.chmod, 0o777)

        class Script(object):
            ran = False

            def main(self, *args, **kwargs):
                self.ran = True
                return succeed(None)

        script = Script()
        from twisted.test.test_task import _FakeReactor
        fakeReactor = _FakeReactor()
        runner = FlockerScriptRunner(script, options, reactor=fakeReactor,
                                     sys_module=sys)
        runner.log_directory = logs
        try:
            with attempt_effective_uid('nobody', suppress_errors=True):
                runner.main()
        except SystemExit:
            pass
        self.assertTrue(script.ran)
Пример #3
0
 def test_twistd(self):
     """
     Should run twistd with the given arguments
     """
     runner = Runner()
     fake_twistd = FilePath(self.mktemp())
     fake_twistd.setContent('#!%s\n'
                             'import sys, os\n'
                             'print " ".join(sys.argv[1:])\n'
                             'print os.environ["FOO"]\n'
                             'print os.path.abspath(os.curdir)\n'
                             'sys.stdout.flush()\n'
                             'sys.stderr.write("error\\n")\n'
                             'print "stdout"\n'
                             'sys.exit(4)\n' % sys.executable)
     fake_twistd.chmod(0777)
     runner._twistdBin = lambda: fake_twistd.path
     
     path = FilePath(self.mktemp())
     path.makedirs()
     
     d = runner.twistd(['foo', 'bar', 'baz'], env={'FOO': 'foo value'},
                   path=path.path)
     def check(result):
         out, err, code = result
         self.assertEqual(code, 4)
         self.assertEqual(out, 
             'foo bar baz\n'
             'foo value\n'
             '%s\n'
             'stdout\n' % path.path)
         self.assertEqual(err, 'error\n')
     return d.addCallback(check)
Пример #4
0
    def test_no_logging_if_permission_denied(self):
        """
        If there is no permission to write to the given directory this does
        not prevent the script from running.
        """
        options = usage.Options()
        sys = FakeSysModule(argv=[b"mythingie"])
        logs = FilePath(self.mktemp())
        logs.makedirs()
        logs.chmod(0)
        self.addCleanup(logs.chmod, 0o777)

        class Script(object):
            ran = False

            def main(self, *args, **kwargs):
                self.ran = True
                return succeed(None)

        script = Script()
        from twisted.test.test_task import _FakeReactor
        fakeReactor = _FakeReactor()
        runner = FlockerScriptRunner(script, options, reactor=fakeReactor,
                                     sys_module=sys)
        runner.log_directory = logs
        try:
            with attempt_effective_uid('nobody', suppress_errors=True):
                runner.main()
        except SystemExit:
            pass
        self.assertTrue(script.ran)
Пример #5
0
    def test_unix_already_listening_cant_delete(self):
        """
        A config with type = "unix" will create an endpoint for a UNIX socket
        at the given path, and delete it if required. If it can't delete it, it
        will raise an exception.
        """
        parent_fp = FilePath("/tmp").child(uuid4().hex)
        parent_fp.makedirs()
        fp = parent_fp.child(uuid4().hex)

        # Something is already there
        fp.setContent(b"")
        fp.chmod(0o544)
        parent_fp.chmod(0o544)

        reactor = SelectReactor()
        config = {
            "type": "unix",
            "path": fp.path
        }

        with self.assertRaises(OSError) as e:
            create_listening_endpoint_from_config(config, self.cbdir,
                                                  reactor, self.log)
        self.assertEqual(e.exception.errno, 13)  # Permission Denied

        parent_fp.chmod(0o777)
        parent_fp.remove()
Пример #6
0
 def test_file(self):
     """
     An existing file has these attributes
     """
     root = FilePath(self.mktemp())
     root.setContent('the content')
     root.chmod(0777)
     
     stdout, stderr, code = self.runScript(['inspect'], json.dumps({
         'kind': 'file',
         'path': root.path,
     }))
     data = json.loads(stdout)
     
     self.assertEqual(data['kind'], 'file')
     self.assertEqual(data['path'], root.path)
     self.assertEqual(data['exists'], True)
     self.assertEqual(data['filetype'], 'file')
     self.assertEqual(data['owner'], pwd.getpwuid(os.geteuid()).pw_name)
     self.assertEqual(data['group'], grp.getgrgid(os.getegid()).gr_name)
     self.assertEqual(data['perms'], '0777')
     root.restat()
     self.assertEqual(data['ctime'], int(root.statinfo.st_ctime))
     self.assertEqual(type(data['ctime']), int)
     self.assertEqual(data['mtime'], int(root.statinfo.st_mtime))
     self.assertEqual(type(data['mtime']), int)
     self.assertEqual(data['atime'], int(root.statinfo.st_atime))
     self.assertEqual(type(data['atime']), int)
     
     self.assertEqual(data['sha1'], sha1('the content').hexdigest())
     self.assertEqual(data['size'], len('the content'))
Пример #7
0
 def test_directory(self):
     """
     A directory can exist
     """
     root = FilePath(self.mktemp())
     root.makedirs()
     root.chmod(0777)
     
     stdout, stderr, code = self.runScript(['inspect'], json.dumps({
         'kind': 'file',
         'path': root.path,
     }))
     data = json.loads(stdout)
     self.assertEqual(data['kind'], 'file')
     self.assertEqual(data['path'], root.path)
     self.assertEqual(data['exists'], True)
     self.assertEqual(data['filetype'], 'dir')
     self.assertEqual(data['owner'], pwd.getpwuid(os.geteuid()).pw_name)
     self.assertEqual(data['group'], grp.getgrgid(os.getegid()).gr_name)
     self.assertEqual(data['perms'], '0777')
     root.restat()
     self.assertEqual(data['ctime'], int(root.statinfo.st_ctime))
     self.assertEqual(type(data['ctime']), int)
     self.assertEqual(data['mtime'], int(root.statinfo.st_mtime))
     self.assertEqual(type(data['mtime']), int)
     self.assertEqual(data['atime'], int(root.statinfo.st_atime))
     self.assertEqual(type(data['atime']), int)
Пример #8
0
    def test_unix_already_listening_cant_delete(self):
        """
        A config with type = "unix" will create an endpoint for a UNIX socket
        at the given path, and delete it if required. If it can't delete it, it
        will raise an exception.
        """
        parent_fp = FilePath("/tmp").child(uuid4().hex)
        parent_fp.makedirs()
        fp = parent_fp.child(uuid4().hex)

        # Something is already there
        fp.setContent(b"")
        fp.chmod(0o544)
        parent_fp.chmod(0o544)

        reactor = SelectReactor()
        config = {"type": "unix", "path": fp.path}

        with self.assertRaises(OSError) as e:
            create_listening_endpoint_from_config(config, self.cbdir, reactor,
                                                  self.log)
        self.assertEqual(e.exception.errno, 13)  # Permission Denied

        parent_fp.chmod(0o777)
        parent_fp.remove()
Пример #9
0
 def wrapper(case, *args, **kwargs):
     test_file = FilePath(case.mktemp())
     test_file.touch()
     test_file.chmod(0o000)
     permissions = test_file.getPermissions()
     test_file.chmod(0o777)
     if permissions != Permissions(0o000):
         raise SkipTest("Can't run test on filesystem with broken permissions.")
     return test_method(case, *args, **kwargs)
Пример #10
0
 def test_config_write_failed(self):
     """If writing the config fails then CreateConfigurationError
     is raised."""
     path = FilePath(self.mktemp())
     path.makedirs()
     path.chmod(0)
     self.addCleanup(path.chmod, 0o777)
     path = path.child(b"config.json")
     service = VolumeService(path, None, reactor=Clock())
     self.assertRaises(CreateConfigurationError, service.startService)
Пример #11
0
 def test_config_write_failed(self):
     """If writing the config fails then CreateConfigurationError
     is raised."""
     path = FilePath(self.mktemp())
     path.makedirs()
     path.chmod(0)
     self.addCleanup(path.chmod, 0o777)
     path = path.child(b"config.json")
     service = VolumeService(path, None, reactor=Clock())
     with attempt_effective_uid('nobody', suppress_errors=True):
         self.assertRaises(CreateConfigurationError, service.startService)
Пример #12
0
 def test_config_write_failed(self):
     """If writing the config fails then CreateConfigurationError
     is raised."""
     path = FilePath(self.mktemp())
     path.makedirs()
     path.chmod(0)
     self.addCleanup(path.chmod, 0o777)
     path = path.child(b"config.json")
     service = VolumeService(path, FilesystemStoragePool(FilePath(self.mktemp())), reactor=Clock())
     with attempt_effective_uid("nobody", suppress_errors=True):
         self.assertRaises(CreateConfigurationError, service.startService)
Пример #13
0
 def test_config_makedirs_failed(self):
     """If creating the config directory fails then CreateConfigurationError
     is raised."""
     path = FilePath(self.mktemp())
     path.makedirs()
     path.chmod(0)
     self.addCleanup(path.chmod, 0o777)
     path = path.child(b"dir").child(b"config.json")
     service = VolumeService(path, None, reactor=Clock())
     with attempt_effective_uid('nobody', suppress_errors=True):
         self.assertRaises(CreateConfigurationError, service.startService)
Пример #14
0
 def test_no_permission(self):
     """If the config file is not writeable a meaningful response is
     written.
     """
     path = FilePath(self.mktemp())
     path.makedirs()
     path.chmod(0)
     self.addCleanup(path.chmod, 0o777)
     config = path.child(b"out.json")
     with attempt_effective_uid("nobody", suppress_errors=True):
         result = run_expecting_error(b"--config", config.path)
     self.assertEqual(result, b"Writing config file %s failed: Permission denied\n" % (config.path,))
Пример #15
0
    def _large_request_test(self, request_body_size):
        """
        Assert that when a request with a body of of the given size is received
        its content is written to the directory the ``TahoeLAFSSite`` is
        configured with.
        """
        tempdir = FilePath(self.mktemp())
        tempdir.makedirs()
        request = self._create_request(tempdir)

        # So.  Bad news.  The temporary file for the uploaded content is
        # unnamed (and this isn't even necessarily a bad thing since it is how
        # you get automatic on-process-exit cleanup behavior on POSIX).  It's
        # not visible by inspecting the filesystem.  It has no name we can
        # discover.  Then how do we verify it is written to the right place?
        # The question itself is meaningless if we try to be too precise.  It
        # *has* no filesystem location.  However, it is still stored *on* some
        # filesystem.  We still want to make sure it is on the filesystem we
        # specified because otherwise it might be on a filesystem that's too
        # small or undesirable in some other way.
        #
        # I don't know of any way to ask a file descriptor which filesystem
        # it's on, either, though.  It might be the case that the [f]statvfs()
        # result could be compared somehow to infer the filesystem but
        # ... it's not clear what the failure modes might be there, across
        # different filesystems and runtime environments.
        #
        # Another approach is to make the temp directory unwriteable and
        # observe the failure when an attempt is made to create a file there.
        # This is hardly a lovely solution but at least it's kind of simple.
        #
        # It would be nice if it worked consistently cross-platform but on
        # Windows os.chmod is more or less broken.
        if platform.isWindows():
            request.gotLength(request_body_size)
            self.assertThat(
                tempdir.children(),
                HasLength(1),
            )
        else:
            tempdir.chmod(0o550)
            with self.assertRaises(OSError) as ctx:
                request.gotLength(request_body_size)
                raise Exception(
                    "OSError not raised, instead tempdir.children() = {}".format(
                        tempdir.children(),
                    ),
                )

            self.assertThat(
                ctx.exception.errno,
                Equals(EACCES),
            )
Пример #16
0
 def test_permissionDenied(self):
     """
     If the a source file is not readable, this is reported on standard
     error.
     """
     sourcePath = FilePath(self.mktemp())
     sourcePath.setContent('')
     sourcePath.chmod(0)
     err = StringIO()
     count = withStderrTo(err, lambda: checkPath(sourcePath.path))
     self.assertEquals(count, 1)
     self.assertEquals(
         err.getvalue(), "%s: Permission denied\n" % (sourcePath.path,))
Пример #17
0
 def test_permissionDenied(self):
     """
     If the a source file is not readable, this is reported on standard
     error.
     """
     sourcePath = FilePath(self.mktemp())
     sourcePath.setContent('')
     sourcePath.chmod(0)
     err = StringIO()
     count = withStderrTo(err, lambda: checkPath(sourcePath.path))
     self.assertEquals(count, 1)
     self.assertEquals(err.getvalue(),
                       "%s: Permission denied\n" % (sourcePath.path, ))
Пример #18
0
 def test_no_permission(self):
     """If the config file is not writeable a meaningful response is
     written.
     """
     path = FilePath(self.mktemp())
     path.makedirs()
     path.chmod(0)
     self.addCleanup(path.chmod, 0o777)
     config = path.child(b"out.json")
     with attempt_effective_uid('nobody', suppress_errors=True):
         result = run_expecting_error(b"--config", config.path)
     self.assertEqual(result,
                      b"Writing config file %s failed: Permission denied\n"
                      % (config.path,))
Пример #19
0
 def test_install_dir_normalises_permissions(self):
     # install_dir() normalises directory permissions to 0755 and file
     # permissions to 0644.
     target_dir = FilePath(self.make_dir())
     new_dir = FilePath(self.make_dir())
     new_dir.chmod(0700)
     new_image = new_dir.child("image")
     new_image.touch()
     new_image.chmod(0600)
     install_dir(new_dir.path, target_dir.path)
     self.assertEqual(
         "rwxr-xr-x",
         target_dir.getPermissions().shorthand())
     self.assertEqual(
         "rw-r--r--",
         target_dir.child("image").getPermissions().shorthand())
Пример #20
0
    def test_exit(self):
        """
        ``VolumeScript._create_volume_service`` raises ``SystemExit`` with a
        non-zero code if ``VolumeService.startService`` raises
        ``CreateConfigurationError``.
        """
        directory = FilePath(self.mktemp())
        directory.makedirs()
        directory.chmod(0o000)
        self.addCleanup(directory.chmod, 0o777)
        config = directory.child("config.yml")

        stderr = StringIO()
        reactor = object()
        options = VolumeOptions()
        options.parseOptions([b"--config", config.path])
        with attempt_effective_uid("nobody", suppress_errors=True):
            exc = self.assertRaises(SystemExit, VolumeScript._create_volume_service, stderr, reactor, options)
        self.assertEqual(1, exc.code)
Пример #21
0
def makeService(config, reactor=reactor):
    parent = MultiService()
    basedir = FilePath(os.path.expanduser(config["basedir"]))
    basedir.makedirs(ignoreExistingDirectory=True)
    basedir.chmod(0o700)

    data = Data(basedir.child("config.json"))

    dns_server = DNSServerFactory(verbose=0)
    s1 = UDPServer(int(config["dns-port"]), dns.DNSDatagramProtocol(dns_server),
                   interface=config["dns-interface"])
    s1.setServiceParent(parent)
    s2 = TCPServer(int(config["dns-port"]), dns_server,
                   interface=config["dns-interface"])
    s2.setServiceParent(parent)

    s = Server(data, dns_server)
    s.update_records()

    certFile = basedir.child("tub.data").path
    #furlFile = basedir.child("server.furl").path
    t = Tub(certFile=certFile)
    t.setOption("keepaliveTimeout", 60) # ping after 60s of idle
    t.setOption("disconnectTimeout", 5*60) # disconnect/reconnect after 5m
    #t.setOption("logLocalFailures", True)
    #t.setOption("logRemoteFailures", True)
    #t.unsafeTracebacks = True
    fp = config["foolscap-port"]
    if not fp.startswith("tcp:"):
        raise usage.UsageError("I don't know how to handle non-tcp foolscap-port=")
    port = int(fp.split(":")[1])
    assert port > 1
    t.listenOn(fp)
    t.setLocation("tcp:%s:%d" % (config["hostname"], port))

    c = Controller(data, s)
    cf = t.registerReference(c, furlFile=basedir.child("controller.furl").path)
    furl_prefix = cf[:cf.rfind("/")+1]
    c.set_furl_prefix(furl_prefix)
    t.registerNameLookupHandler(c.lookup)

    t.setServiceParent(parent)
    return parent
Пример #22
0
    def test_forbiddenResource(self):
        """
        If the file in the filesystem which would satisfy a request cannot be
        read, L{File.render} sets the HTTP response code to I{FORBIDDEN}.
        """
        base = FilePath(self.mktemp())
        base.setContent('')
        # Make sure we can delete the file later.
        self.addCleanup(base.chmod, 0700)

        # Get rid of our own read permission.
        base.chmod(0)

        file = static.File(base.path)
        request = DummyRequest([''])
        d = self._render(file, request)
        def cbRendered(ignored):
            self.assertEqual(request.responseCode, 403)
        d.addCallback(cbRendered)
        return d
Пример #23
0
def makeService(config, reactor=reactor):
    parent = MultiService()
    basedir = FilePath(os.path.expanduser(config["basedir"]))
    basedir.makedirs(ignoreExistingDirectory=True)
    basedir.chmod(0o700)

    data = Data(basedir.child("config.json"))

    certFile = basedir.child("tub.data").path
    tub = Tub(certFile=certFile)
    tub.setOption("keepaliveTimeout", 60) # ping after 60s of idle
    tub.setOption("disconnectTimeout", 5*60) # disconnect/reconnect after 5m
    tub.listenOn("tcp:6319:interface=127.0.0.1")
    tub.setLocation("tcp:127.0.0.1:6319")
    tub.setServiceParent(parent)

    acme_path = basedir.asTextMode()
    acme_key = maybe_key(acme_path)
    cert_store = FlancerCertificateStore(data, basedir)
    staging = not config["really"]
    if staging:
        print("STAGING mode")
        le_url = LETSENCRYPT_STAGING_DIRECTORY
    else:
        print("REAL CERTIFICATE mode")
        le_url = LETSENCRYPT_DIRECTORY
    client_creator = partial(Client.from_url, reactor=reactor,
                             url=le_url,
                             key=acme_key, alg=RS256)
    r = FlancerResponder(tub, data)
    issuer = AcmeIssuingService(cert_store, client_creator, reactor, [r])
    issuer.setServiceParent(parent)

    if "dyndns_furl" in data:
        start_dyndns_canary(tub, data["dyndns_furl"].encode("ascii"))

    c = Controller(tub, data, issuer)
    tub.registerReference(c, furlFile=basedir.child("controller.furl").path)

    #TimerService(5*60.0, f.timerUpdateStats).setServiceParent(parent)
    return parent
Пример #24
0
    def test_exit(self):
        """
        ``VolumeScript._create_volume_service`` raises ``SystemExit`` with a
        non-zero code if ``VolumeService.startService`` raises
        ``CreateConfigurationError``.
        """
        directory = FilePath(self.mktemp())
        directory.makedirs()
        directory.chmod(0o000)
        self.addCleanup(directory.chmod, 0o777)
        config = directory.child("config.yml")

        stderr = StringIO()
        reactor = object()
        options = VolumeOptions()
        options.parseOptions([b"--config", config.path])
        with attempt_effective_uid('nobody', suppress_errors=True):
            exc = self.assertRaises(SystemExit,
                                    VolumeScript._create_volume_service,
                                    stderr, reactor, options)
        self.assertEqual(1, exc.code)
Пример #25
0
    def test_details_written(self):
        """
        ``VolumeScript._create_volume_service`` writes details of the error to
        the given ``stderr`` if ``VolumeService.startService`` raises
        ``CreateConfigurationError``.
        """
        directory = FilePath(self.mktemp())
        directory.makedirs()
        directory.chmod(0o000)
        self.addCleanup(directory.chmod, 0o777)
        config = directory.child("config.yml")

        stderr = StringIO()
        reactor = object()
        options = VolumeOptions()
        options.parseOptions([b"--config", config.path])
        with attempt_effective_uid("nobody", suppress_errors=True):
            self.assertRaises(SystemExit, VolumeScript._create_volume_service, stderr, reactor, options)
        self.assertEqual(
            "Writing config file {} failed: Permission denied\n".format(config.path).encode("ascii"), stderr.getvalue()
        )
Пример #26
0
    def test_details_written(self):
        """
        ``VolumeScript._create_volume_service`` writes details of the error to
        the given ``stderr`` if ``VolumeService.startService`` raises
        ``CreateConfigurationError``.
        """
        directory = FilePath(self.mktemp())
        directory.makedirs()
        directory.chmod(0o000)
        self.addCleanup(directory.chmod, 0o777)
        config = directory.child("config.yml")

        stderr = StringIO()
        reactor = object()
        options = VolumeOptions()
        options.parseOptions([b"--config", config.path])
        with attempt_effective_uid('nobody', suppress_errors=True):
            self.assertRaises(SystemExit, VolumeScript._create_volume_service,
                              stderr, reactor, options)
        self.assertEqual(
            "Writing config file {} failed: Permission denied\n".format(
                config.path).encode("ascii"), stderr.getvalue())
Пример #27
0
    def test_forbiddenResource(self):
        """
        If the file in the filesystem which would satisfy a request cannot be
        read, L{File.render} sets the HTTP response code to I{FORBIDDEN}.
        """
        base = FilePath(self.mktemp())
        base.setContent('')
        # Make sure we can delete the file later.
        self.addCleanup(base.chmod, 0700)

        # Get rid of our own read permission.
        base.chmod(0)

        file = static.File(base.path)
        request = DummyRequest([''])
        d = self._render(file, request)

        def cbRendered(ignored):
            self.assertEqual(request.responseCode, 403)

        d.addCallback(cbRendered)
        return d