Ejemplo n.º 1
0
    def test_get_vhosts(self):
        nparser = parser.NginxParser(self.config_path)
        vhosts = nparser.get_vhosts()

        vhost1 = obj.VirtualHost(nparser.abs_path('nginx.conf'),
                                 [obj.Addr('', '8080', False, False,
                                           False, False)],
                                 False, True,
                                 set(['localhost',
                                      r'~^(www\.)?(example|bar)\.']),
                                 [], [10, 1, 9])
        vhost2 = obj.VirtualHost(nparser.abs_path('nginx.conf'),
                                 [obj.Addr('somename', '8080', False, False,
                                           False, False),
                                  obj.Addr('', '8000', False, False,
                                           False, False)],
                                 False, True,
                                 set(['somename', 'another.alias', 'alias']),
                                 [], [10, 1, 12])
        vhost3 = obj.VirtualHost(nparser.abs_path('sites-enabled/example.com'),
                                 [obj.Addr('69.50.225.155', '9000',
                                           False, False, False, False),
                                  obj.Addr('127.0.0.1', '', False, False,
                                           False, False)],
                                 False, True,
                                 set(['.example.com', 'example.*']), [], [0])
        vhost4 = obj.VirtualHost(nparser.abs_path('sites-enabled/default'),
                                 [obj.Addr('myhost', '', False, True,
                                           False, False),
                                  obj.Addr('otherhost', '', False, True,
                                           False, False)],
                                 False, True, set(['www.example.org']),
                                 [], [0])
        vhost5 = obj.VirtualHost(nparser.abs_path('foo.conf'),
                                 [obj.Addr('*', '80', True, True,
                                           False, False)],
                                 True, True, set(['*.www.foo.com',
                                                  '*.www.example.com']),
                                 [], [2, 1, 0])

        self.assertEqual(13, len(vhosts))
        example_com = [x for x in vhosts if 'example.com' in x.filep][0]
        self.assertEqual(vhost3, example_com)
        default = [x for x in vhosts if 'default' in x.filep][0]
        self.assertEqual(vhost4, default)
        fooconf = [x for x in vhosts if 'foo.conf' in x.filep][0]
        self.assertEqual(vhost5, fooconf)
        localhost = [x for x in vhosts if 'localhost' in x.names][0]
        self.assertEqual(vhost1, localhost)
        somename = [x for x in vhosts if 'somename' in x.names][0]
        self.assertEqual(vhost2, somename)
Ejemplo n.º 2
0
    def get_vhosts(self):
        # pylint: disable=cell-var-from-loop
        """Gets list of all 'virtual hosts' found in Nginx configuration.
        Technically this is a misnomer because Nginx does not have virtual
        hosts, it has 'server blocks'.

        :returns: List of :class:`~certbot_nginx.obj.VirtualHost`
            objects found in configuration
        :rtype: list

        """
        enabled = True  # We only look at enabled vhosts for now
        servers = self._get_raw_servers()

        vhosts = []
        for filename in servers:
            for server, path in servers[filename]:
                # Parse the server block into a VirtualHost object

                parsed_server = _parse_server_raw(server)
                vhost = obj.VirtualHost(filename, parsed_server['addrs'],
                                        parsed_server['ssl'], enabled,
                                        parsed_server['names'], server, path)
                vhosts.append(vhost)

        self._update_vhosts_addrs_ssl(vhosts)

        return vhosts
Ejemplo n.º 3
0
 def test_has_ssl_on_directive(self):
     nparser = parser.NginxParser(self.config_path)
     mock_vhost = obj.VirtualHost(
         None, None, None, None, None,
         [['listen', 'myhost default_server'],
          ['server_name', 'www.example.org'],
          [['location', '/'],
           [['root', 'html'], ['index', 'index.html index.htm']]]], None)
     self.assertFalse(nparser.has_ssl_on_directive(mock_vhost))
     mock_vhost.raw = [['listen', '*:80', 'default_server', 'ssl'],
                       [
                           'server_name', '*.www.foo.com',
                           '*.www.example.com'
                       ], ['root', '/home/ubuntu/sites/foo/']]
     self.assertFalse(nparser.has_ssl_on_directive(mock_vhost))
     mock_vhost.raw = [['listen', '80 ssl'],
                       [
                           'server_name', '*.www.foo.com',
                           '*.www.example.com'
                       ]]
     self.assertFalse(nparser.has_ssl_on_directive(mock_vhost))
     mock_vhost.raw = [['listen', '80'], ['ssl', 'on'],
                       [
                           'server_name', '*.www.foo.com',
                           '*.www.example.com'
                       ]]
     self.assertTrue(nparser.has_ssl_on_directive(mock_vhost))
Ejemplo n.º 4
0
 def test_replace_server_directives(self):
     nparser = parser.NginxParser(self.config_path)
     target = set(['.example.com', 'example.*'])
     filep = nparser.abs_path('sites-enabled/example.com')
     mock_vhost = obj.VirtualHost(filep, None, None, None, target, None,
                                  [0])
     nparser.add_server_directives(mock_vhost,
                                   [['server_name', 'foobar.com']],
                                   replace=True)
     from certbot_nginx.parser import COMMENT
     self.assertEqual(
         nparser.parsed[filep],
         [[['server'],
           [['listen', '69.50.225.155:9000'], ['listen', '127.0.0.1'],
            ['server_name', 'foobar.com'], ['#', COMMENT],
            ['server_name', 'example.*'], []]]])
     mock_vhost.names = set(['foobar.com', 'example.*'])
     nparser.add_server_directives(mock_vhost,
                                   [['ssl_certificate', 'cert.pem']],
                                   replace=True)
     self.assertEqual(nparser.parsed[filep],
                      [[['server'],
                        [
                            ['listen', '69.50.225.155:9000'],
                            ['listen', '127.0.0.1'],
                            ['server_name', 'foobar.com'],
                            ['#', COMMENT],
                            ['server_name', 'example.*'],
                            [],
                            ['ssl_certificate', 'cert.pem'],
                            ['#', COMMENT],
                            [],
                        ]]])
Ejemplo n.º 5
0
    def test_comment_is_repeatable(self):
        nparser = parser.NginxParser(self.config_path)
        example_com = nparser.abs_path('sites-enabled/example.com')
        mock_vhost = obj.VirtualHost(example_com,
                                     None, None, None,
                                     set(['.example.com', 'example.*']),
                                     None, [0])
        nparser.add_server_directives(mock_vhost,
                                      [['\n  ', '#', ' ', 'what a nice comment']],
                                      replace=False)
        nparser.add_server_directives(mock_vhost,
                                      [['\n  ', 'include', ' ',
                                      nparser.abs_path('comment_in_file.conf')]],
                                      replace=False)
        from certbot_nginx.parser import COMMENT
        self.assertEqual(nparser.parsed[example_com],
            [[['server'], [['listen', '69.50.225.155:9000'],
                           ['listen', '127.0.0.1'],
                           ['server_name', '.example.com'],
                           ['server_name', 'example.*'],
                           ['#', ' ', 'what a nice comment'],
                           [],
                           ['include', nparser.abs_path('comment_in_file.conf')],
                           ['#', COMMENT],
                           []]]]
)
Ejemplo n.º 6
0
    def test_get_vhosts_global_ssl(self):
        nparser = parser.NginxParser(self.config_path, self.ssl_options)
        vhosts = nparser.get_vhosts()

        vhost = obj.VirtualHost(nparser.abs_path('sites-enabled/globalssl.com'),
                                [obj.Addr('4.8.2.6', '57', True, False)],
                                True, True, set(['globalssl.com']), [], [0])

        globalssl_com = [x for x in vhosts if 'globalssl.com' in x.filep][0]
        self.assertEqual(vhost, globalssl_com)
Ejemplo n.º 7
0
    def test_add_server_directives(self):
        nparser = parser.NginxParser(self.config_path, self.ssl_options)
        mock_vhost = obj.VirtualHost(nparser.abs_path('nginx.conf'),
                                     None, None, None,
                                     set(['localhost',
                                           r'~^(www\.)?(example|bar)\.']),
                                     None, [10, 1, 9])
        nparser.add_server_directives(mock_vhost,
                                      [['foo', 'bar'], ['\n ', 'ssl_certificate', ' ',
                                                        '/etc/ssl/cert.pem']],
                                      replace=False)
        ssl_re = re.compile(r'\n\s+ssl_certificate /etc/ssl/cert.pem')
        dump = nginxparser.dumps(nparser.parsed[nparser.abs_path('nginx.conf')])
        self.assertEqual(1, len(re.findall(ssl_re, dump)))

        example_com = nparser.abs_path('sites-enabled/example.com')
        names = set(['.example.com', 'example.*'])
        mock_vhost.filep = example_com
        mock_vhost.names = names
        mock_vhost.path = [0]
        nparser.add_server_directives(mock_vhost,
                                      [['foo', 'bar'], ['ssl_certificate',
                                                        '/etc/ssl/cert2.pem']],
                                      replace=False)
        nparser.add_server_directives(mock_vhost, [['foo', 'bar']],
                                      replace=False)
        from certbot_nginx.parser import COMMENT
        self.assertEqual(nparser.parsed[example_com],
            [[['server'], [['listen', '69.50.225.155:9000'],
                           ['listen', '127.0.0.1'],
                           ['server_name', '.example.com'],
                           ['server_name', 'example.*'],
                           ['foo', 'bar'],
                           ['#', COMMENT],
                           ['ssl_certificate', '/etc/ssl/cert2.pem'],
                           ['#', COMMENT], [], []
                           ]]])

        server_conf = nparser.abs_path('server.conf')
        names = set(['alias', 'another.alias', 'somename'])
        mock_vhost.filep = server_conf
        mock_vhost.names = names
        mock_vhost.path = []
        self.assertRaises(errors.MisconfigurationError,
                          nparser.add_server_directives,
                          mock_vhost,
                          [['foo', 'bar'],
                           ['ssl_certificate', '/etc/ssl/cert2.pem']],
                          replace=False)
Ejemplo n.º 8
0
    def test_save(self):
        filep = self.config.parser.abs_path('sites-enabled/example.com')
        mock_vhost = obj.VirtualHost(filep, None, None, None,
                                     set(['.example.com', 'example.*']), None,
                                     [0])
        self.config.parser.add_server_directives(
            mock_vhost, [['listen', ' ', '5001', ' ', 'ssl']])
        self.config.save()

        # pylint: disable=protected-access
        parsed = self.config.parser._parse_files(filep, override=True)
        self.assertEqual(
            [[['server'],
              [['listen', '69.50.225.155:9000'], ['listen', '127.0.0.1'],
               ['server_name', '.example.com'], ['server_name', 'example.*'],
               ['listen', '5001', 'ssl'], ['#', parser.COMMENT]]]], parsed[0])
Ejemplo n.º 9
0
 def test_get_all_certs_keys(self):
     nparser = parser.NginxParser(self.config_path, self.ssl_options)
     filep = nparser.abs_path('sites-enabled/example.com')
     mock_vhost = obj.VirtualHost(filep, None, None, None,
                                  set(['.example.com', 'example.*']), None,
                                  [0])
     nparser.add_server_directives(
         mock_vhost,
         [['ssl_certificate', 'foo.pem'],
          ['ssl_certificate_key', 'bar.key'], ['listen', '443 ssl']],
         replace=False)
     c_k = nparser.get_all_certs_keys()
     migration_file = nparser.abs_path('sites-enabled/migration.com')
     self.assertEqual(
         set([('foo.pem', 'bar.key', filep),
              ('cert.pem', 'cert.key', migration_file)]), c_k)
Ejemplo n.º 10
0
    def get_vhosts(self):
        # pylint: disable=cell-var-from-loop
        """Gets list of all 'virtual hosts' found in Nginx configuration.
        Technically this is a misnomer because Nginx does not have virtual
        hosts, it has 'server blocks'.

        :returns: List of :class:`~certbot_nginx.obj.VirtualHost`
            objects found in configuration
        :rtype: list

        """
        enabled = True  # We only look at enabled vhosts for now
        vhosts = []
        servers = {}

        for filename in self.parsed:
            tree = self.parsed[filename]
            servers[filename] = []
            srv = servers[filename]  # workaround undefined loop var in lambdas

            # Find all the server blocks
            _do_for_subarray(tree, lambda x: x[0] == ['server'],
                             lambda x, y: srv.append((x[1], y)))

            # Find 'include' statements in server blocks and append their trees
            for i, (server, path) in enumerate(servers[filename]):
                new_server = self._get_included_directives(server)
                servers[filename][i] = (new_server, path)

        for filename in servers:
            for server, path in servers[filename]:
                # Parse the server block into a VirtualHost object

                parsed_server = parse_server(server)
                vhost = obj.VirtualHost(filename,
                                        parsed_server['addrs'],
                                        parsed_server['ssl'],
                                        enabled,
                                        parsed_server['names'],
                                        server,
                                        path)
                vhosts.append(vhost)

        return vhosts
Ejemplo n.º 11
0
    def choose_vhost(self, target_name):
        """Chooses a virtual host based on the given domain name.

        .. note:: This makes the vhost SSL-enabled if it isn't already. Follows
            Nginx's server block selection rules preferring blocks that are
            already SSL.

        .. todo:: This should maybe return list if no obvious answer
            is presented.

        .. todo:: The special name "$hostname" corresponds to the machine's
            hostname. Currently we just ignore this.

        :param str target_name: domain name

        :returns: ssl vhost associated with name
        :rtype: :class:`~certbot_nginx.obj.VirtualHost`

        """
        vhost = None

        matches = self._get_ranked_matches(target_name)
        if not matches:
            # No matches. Create a new vhost with this name in nginx.conf.
            filep = self.parser.loc["root"]
            new_block = [['server'], [['\n', 'server_name', ' ', target_name]]]
            self.parser.add_http_directives(filep, new_block)
            vhost = obj.VirtualHost(filep, set([]), False, True,
                                    set([target_name]), list(new_block[1]))
        elif matches[0]['rank'] in xrange(2, 6):
            # Wildcard match - need to find the longest one
            rank = matches[0]['rank']
            wildcards = [x for x in matches if x['rank'] == rank]
            vhost = max(wildcards, key=lambda x: len(x['name']))['vhost']
        else:
            vhost = matches[0]['vhost']

        if vhost is not None:
            if not vhost.ssl:
                self._make_server_ssl(vhost)

        return vhost
Ejemplo n.º 12
0
 def test_remove_server_directives(self):
     nparser = parser.NginxParser(self.config_path)
     mock_vhost = obj.VirtualHost(
         nparser.abs_path('nginx.conf'), None, None, None,
         set(['localhost', r'~^(www\.)?(example|bar)\.']), None, [10, 1, 9])
     example_com = nparser.abs_path('sites-enabled/example.com')
     names = set(['.example.com', 'example.*'])
     mock_vhost.filep = example_com
     mock_vhost.names = names
     mock_vhost.path = [0]
     nparser.add_server_directives(
         mock_vhost,
         [['foo', 'bar'], ['ssl_certificate', '/etc/ssl/cert2.pem']])
     nparser.remove_server_directives(mock_vhost, 'foo')
     nparser.remove_server_directives(mock_vhost, 'ssl_certificate')
     self.assertEqual(
         nparser.parsed[example_com],
         [[['server'],
           [['listen', '69.50.225.155:9000'], ['listen', '127.0.0.1'],
            ['server_name', '.example.com'], ['server_name', 'example.*'],
            []]]])