master
Raw Download raw file
 1#!/usr/bin/env python
 2
 3import hashlib
 4import os.path
 5import sys
 6
 7# From this package
 8import lib.error as error
 9import lib.http_client as http_client
10import lib.test_framework as test_framework
11import lib.util as util
12import runner
13
14# Deprecated in 2.7 in favor of argparse but not yet removed.
15from optparse import OptionParser
16
17class Harness(test_framework.AbstractHarness):
18    LEVEL = 0
19    VERSION = 1
20    DEFAULT_TEST_CASES = [
21          "level0-R5ez7L9mIu",
22          "level0-HhC91MrU7B",
23          "level0-znKqYRKUDB",
24          "level0-ws8xCiPURG",
25          "level0-JjIHof09MH"
26        ]
27    DICTIONARY_SHA1 = '6b898d7c48630be05b72b3ae07c5be6617f90d8e'
28
29    def __init__(self, ids_or_urls=[], options={}):
30        self.dictionary_path = options.get("dictionary_path")
31        super(Harness, self).__init__(ids_or_urls, options)
32
33    def hook_preexecute(self):
34        self.configure_dictionary()
35
36    def hook_create_runner(self):
37        return runner.Runner({'dictionary_path': self.dictionary_path})
38
39    def sha1(self, input):
40        if sys.version_info >= (3,0) and not isinstance(input, bytes):
41            input = input.encode('utf-8')
42        return hashlib.sha1(input).hexdigest()
43
44    def configure_dictionary(self):
45        if self.dictionary_path:
46            return
47
48        default_dictionary_path = '/usr/share/dict/words'
49
50        try:
51            f = open(default_dictionary_path, "rb")
52        except IOError:
53            dictionary_sha1 = None
54        else:
55            dictionary_sha1 = self.sha1(f.read())
56            f.close()
57
58        if dictionary_sha1 == self.DICTIONARY_SHA1:
59            self.dictionary_path = default_dictionary_path
60        else:
61            self.dictionary_path = os.path.join(os.path.dirname(__file__), "data", "words-" + self.DICTIONARY_SHA1)
62            self.download_dictionary(self.dictionary_path)
63
64    def download_dictionary(self, dictionary_path):
65        if os.path.isfile(dictionary_path):
66            util.logger.debug('Not downloading dictionary to already-existing path: %s', dictionary_path)
67            return
68
69        url = "https://s3-us-west-2.amazonaws.com/stripe-ctf-3/level0-statics/words-%s" % self.DICTIONARY_SHA1
70        util.logger.info("Downloading dictionary. (This will happen once. It's 2.4M, so it may take a while...). URL: %s", url)
71        content = self.fetch_s3_resource(url)
72        if self.sha1(content) != self.DICTIONARY_SHA1:
73            raise error.StripeError("We tried to download the dictionary, but we got content with an unexpected hash. If this persists, please contact ctf@stripe.com")
74        f = open(dictionary_path, "w")
75        f.write(content)
76        f.close()
77
78def main():
79    default_options = {"task": "execute", "raw": False, "dictionary_path": None}
80    usage = "usage: %prog [options] [test case URL or id]"
81    parser = OptionParser(usage=usage)
82    parser.add_option("-r", "--raw", action="store_true", dest="raw", help="Print the raw output of your solution.")
83    parser.add_option("-p", "--dictionary-path", action="store", type="string", dest="dictionary_path")
84    (options, args) = parser.parse_args()
85    options_dict = vars(options)
86
87    for key in default_options:
88        options_dict.setdefault(key, default_options[key])
89
90    harness = Harness(args, options_dict)
91    harness.run()
92
93if __name__ == "__main__":
94  main()