1# Python 2 and 3
2try:
3    from urllib.parse import urljoin
4except ImportError:
5    from urlparse import urljoin
6
7from wfuzz.plugin_api.mixins import DiscoveryPluginMixin
8from wfuzz.plugin_api.base import BasePlugin
9from wfuzz.externals.moduleman.plugin import moduleman_plugin
10
11
12@moduleman_plugin
13class svn_extractor(BasePlugin, DiscoveryPluginMixin):
14    name = "svn_extractor"
15    author = ("Xavi Mendez (@xmendez)",)
16    version = "0.1"
17    summary = "Parses .svn/entries file."
18    description = ("Parses CVS/Entries file and enqueues found entries",)
19    category = ["active", "discovery"]
20    priority = 99
21
22    parameters = ()
23
24    def __init__(self):
25        BasePlugin.__init__(self)
26
27    def validate(self, fuzzresult):
28        return fuzzresult.url.find(".svn/entries") > 0 and fuzzresult.code == 200
29
30    def readsvn(self, content):
31        """
32        Function shamesly copied (and adapted) from https://github.com/anantshri/svn-extractor/
33        Credit (C) Anant Shrivastava http://anantshri.info
34        """
35        old_line = ""
36        file_list = []
37        dir_list = []
38        author_list = []
39
40        for a in content.splitlines():
41            # below functionality will find all usernames from svn entries file
42            if a == "has-props":
43                if old_line not in author_list:
44                    author_list.append(old_line)
45            if a == "file":
46                if old_line not in file_list:
47                    file_list.append(old_line)
48            if a == "dir":
49                if old_line != "":
50                    dir_list.append(old_line)
51            old_line = a
52        return file_list, dir_list, author_list
53
54    def process(self, fuzzresult):
55        base_url = fuzzresult.url
56
57        file_list, dir_list, author_list = self.readsvn(fuzzresult.history.content)
58
59        if author_list:
60            self.add_result("authors", "SVN authors", ", ".join(author_list))
61
62        for f in file_list:
63            u = urljoin(base_url.replace("/.svn/", "/"), f)
64            self.queue_url(u)
65
66        for d in dir_list:
67            self.queue_url(
68                urljoin(base_url.replace("/.svn/", "/"), d) + "/.svn/entries"
69            )
70