]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/scripts/debug.py
fix dump-uri-extension
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / scripts / debug.py
1
2 # do not import any allmydata modules at this level. Do that from inside
3 # individual functions instead.
4 import os, sys, struct
5 from twisted.python import usage
6 from allmydata.scripts.common import BasedirMixin
7
8 class DumpOptions(usage.Options):
9     optParameters = [
10         ["filename", "f", None, "which file to dump"],
11         ]
12
13     def parseArgs(self, filename=None):
14         if filename:
15             self['filename'] = filename
16
17     def postOptions(self):
18         if not self['filename']:
19             raise usage.UsageError("<filename> parameter is required")
20
21 class DumpRootDirnodeOptions(BasedirMixin, usage.Options):
22     optParameters = [
23         ["basedir", "C", None, "the vdrive-server's base directory"],
24         ]
25
26 class DumpDirnodeOptions(BasedirMixin, usage.Options):
27     optParameters = [
28         ["uri", "u", None, "the URI of the dirnode to dump."],
29         ["basedir", "C", None, "which directory to create the introducer in"],
30         ]
31     optFlags = [
32         ["verbose", "v", "be extra noisy (show encrypted data)"],
33         ]
34     def parseArgs(self, *args):
35         if len(args) == 1:
36             self['uri'] = args[-1]
37             args = args[:-1]
38         BasedirMixin.parseArgs(self, *args)
39
40     def postOptions(self):
41         BasedirMixin.postOptions(self)
42         if not self['uri']:
43             raise usage.UsageError("<uri> parameter is required")
44
45 def dump_uri_extension(config, out=sys.stdout, err=sys.stderr):
46     from allmydata import uri, storageserver
47
48     filename = config['filename']
49     f = open(filename,"rb")
50     # use a ReadBucketProxy to parse the bucket and find the uri extension
51     bp = storageserver.ReadBucketProxy(None)
52     offsets = bp._parse_offsets(f.read(8*4))
53     f.seek(offsets['uri_extension'])
54     length = struct.unpack(">L", f.read(4))[0]
55     data = f.read(length)
56
57     unpacked = uri.unpack_extension_readable(data)
58     keys1 = ("size", "num_segments", "segment_size",
59              "needed_shares", "total_shares")
60     keys2 = ("codec_name", "codec_params", "tail_codec_params")
61     keys3 = ("plaintext_hash", "plaintext_root_hash",
62              "crypttext_hash", "crypttext_root_hash",
63              "share_root_hash")
64     for k in keys1:
65         if k in unpacked:
66             print >>out, "%19s: %s" % (k, unpacked[k])
67     print >>out
68     for k in keys2:
69         if k in unpacked:
70             print >>out, "%19s: %s" % (k, unpacked[k])
71     print >>out
72     for k in keys3:
73         if k in unpacked:
74             print >>out, "%19s: %s" % (k, unpacked[k])
75
76     leftover = set(unpacked.keys()) - set(keys1 + keys2 + keys3)
77     if leftover:
78         print >>out
79         print >>out, "LEFTOVER:"
80         for k in sorted(leftover):
81             print >>out, "%s: %s" % (k, unpacked[k])
82
83     print >>out
84     return 0
85
86 def dump_root_dirnode(config, out=sys.stdout, err=sys.stderr):
87     from allmydata import uri
88
89     basedir = config['basedirs'][0]
90     root_dirnode_file = os.path.join(basedir, "vdrive", "root")
91     try:
92         f = open(root_dirnode_file, "rb")
93         key = f.read()
94         rooturi = uri.pack_dirnode_uri("fakeFURL", key)
95         print >>out, rooturi
96         return 0
97     except EnvironmentError:
98         print >>out,  "unable to read root dirnode file from %s" % \
99               root_dirnode_file
100         return 1
101
102 def dump_directory_node(config, out=sys.stdout, err=sys.stderr):
103     from allmydata import uri, dirnode
104     from allmydata.util import hashutil, idlib
105     basedir = config['basedirs'][0]
106     dir_uri = config['uri']
107     verbose = config['verbose']
108
109     furl, key = uri.unpack_dirnode_uri(dir_uri)
110     if uri.is_mutable_dirnode_uri(dir_uri):
111         wk, we, rk, index = hashutil.generate_dirnode_keys_from_writekey(key)
112     else:
113         wk, we, rk, index = hashutil.generate_dirnode_keys_from_readkey(key)
114
115     filename = os.path.join(basedir, "vdrive", idlib.b2a(index))
116
117     print >>out
118     print >>out, "dirnode uri: %s" % dir_uri
119     print >>out, "filename : %s" % filename
120     print >>out, "index        : %s" % idlib.b2a(index)
121     if wk:
122         print >>out, "writekey     : %s" % idlib.b2a(wk)
123         print >>out, "write_enabler: %s" % idlib.b2a(we)
124     else:
125         print >>out, "writekey     : None"
126         print >>out, "write_enabler: None"
127     print >>out, "readkey      : %s" % idlib.b2a(rk)
128
129     print >>out
130
131     vds = dirnode.VirtualDriveServer(os.path.join(basedir, "vdrive"), False)
132     data = vds._read_from_file(index)
133     if we:
134         if we != data[0]:
135             print >>out, "ERROR: write_enabler does not match"
136
137     for (H_key, E_key, E_write, E_read) in data[1]:
138         if verbose:
139             print >>out, " H_key %s" % idlib.b2a(H_key)
140             print >>out, " E_key %s" % idlib.b2a(E_key)
141             print >>out, " E_write %s" % idlib.b2a(E_write)
142             print >>out, " E_read %s" % idlib.b2a(E_read)
143         key = dirnode.decrypt(rk, E_key)
144         print >>out, " key %s" % key
145         if hashutil.dir_name_hash(rk, key) != H_key:
146             print >>out, "  ERROR: H_key does not match"
147         if wk and E_write:
148             if len(E_write) < 14:
149                 print >>out, "  ERROR: write data is short:", idlib.b2a(E_write)
150             write = dirnode.decrypt(wk, E_write)
151             print >>out, "   write: %s" % write
152         read = dirnode.decrypt(rk, E_read)
153         print >>out, "   read: %s" % read
154         print >>out
155
156     return 0
157
158
159 subCommands = [
160     ["dump-uri-extension", None, DumpOptions,
161      "Unpack and display the contents of a uri_extension file."],
162     ["dump-root-dirnode", None, DumpRootDirnodeOptions,
163      "Compute most of the URI for the vdrive server's root dirnode."],
164     ["dump-dirnode", None, DumpDirnodeOptions,
165      "Unpack and display the contents of a vdrive DirectoryNode."],
166     ]
167
168 dispatch = {
169     "dump-uri-extension": dump_uri_extension,
170     "dump-root-dirnode": dump_root_dirnode,
171     "dump-dirnode": dump_directory_node,
172     }