garbage:
- '{random 10-3000 printable}'
- '{random 10-1000 binary}'
+ garbage_no_whitespace:
+ - '{random 10-3000 printable_no_whitespace}'
+ - '{random 10-1000 binary_no_whitespace}'
choices:
- bucket
- '{bucket_not_readable}'
- '{bucket_writable}'
- '{bucket_not_writable}'
- - '2 {garbage}'
+ - '2 {garbage_no_whitespace}'
choices:
- bucket_get_simple
- bucket_get_filtered
bucket:
- '{bucket_writable}'
- '{bucket_not_writable}'
- - '2 {garbage}'
+ - '2 {garbage_no_whitespace}'
query:
- null
- policy
- website
- - '2 {garbage}'
+ - '2 {garbage_no_whitespace}'
choices: []
bucket_get:
bucket:
- '{bucket_readable}'
- '{bucket_not_readable}'
- - '2 {garbage}'
+ - '2 {garbage_no_whitespace}'
choices:
- 11 bucket_get_simple
- bucket_get_filtered
- requestPayment
- versioning
- website
- - '2 {garbage}'
+ - '2 {garbage_no_whitespace}'
choices: []
bucket_get_uploads:
set:
delimiter:
- null
- - '3 delimiter={garbage}'
+ - '3 delimiter={garbage_no_whitespace}'
prefix:
- null
- - '3 prefix={garbage}'
+ - '3 prefix={garbage_no_whitespace}'
key_marker:
- null
- 'key-marker={object_readable}'
- 'key-marker={object_not_readable}'
- 'key-marker={invalid_key}'
- - 'key-marker={random 100-1000 printable}'
+ - 'key-marker={random 100-1000 printable_no_whitespace}'
max_uploads:
- null
- - 'max-uploads={random 1-5 binary}'
+ - 'max-uploads={random 1-5 binary_no_whitespace}'
- 'max-uploads={random 1-1000 digits}'
upload_id_marker:
- null
- - '3 upload-id-marker={random}'
+ - '3 upload-id-marker={random 0-1000 printable_no_whitespace}'
query:
- 'uploads'
- 'uploads&{delimiter}&{prefix}'
- 'uploads&{max_uploads}&{key_marker}&{upload_id_marker}'
- - '2 {garbage}'
+ - '2 {garbage_no_whitespace}'
choices: []
bucket_get_filtered:
set:
delimiter:
- - 'delimiter={garbage}'
+ - 'delimiter={garbage_no_whitespace}'
prefix:
- - 'prefix={garbage}'
+ - 'prefix={garbage_no_whitespace}'
marker:
- 'marker={object_readable}'
- 'marker={object_not_readable}'
- 'marker={invalid_key}'
- - 'marker={random 100-1000 printable}'
+ - 'marker={random 100-1000 printable_no_whitespace}'
max_keys:
- - 'max-keys={random 1-5 binary}'
+ - 'max-keys={random 1-5 binary_no_whitespace}'
- 'max-keys={random 1-1000 digits}'
query:
- null
- '{delimiter}&{prefix}'
- '{max-keys}&{marker}'
- - '2 {garbage}'
+ - '2 {garbage_no_whitespace}'
choices: []
bucket_put:
bucket:
- '{bucket_writable}'
- '{bucket_not_writable}'
- - '2 {garbage}'
+ - '2 {garbage_no_whitespace}'
method: PUT
choices:
- bucket_put_simple
- '2 {garbage}'
- '<CreateBucketConfiguration><LocationConstraint>{random 2-10 binary}</LocationConstraint></CreateBucketConfiguration>'
acl:
- - private
+ - 'private'
+ - 'public-read'
+ - 'public-read-write'
+ - 'authenticated-read'
+ - 'bucket-owner-read'
+ - 'bucket-owner-full-control'
- '{random 3000 letters}'
- - '{random 100-1000 binary}'
+ - '{random 100-1000 binary_no_whitespace}'
headers:
- ['0-1', 'x-amz-acl', '{acl}']
choices: []
- '<MfaDelete>{random 2-10 binary}</MfaDelete>'
- '<MfaDelete>{random 2000-3000 printable}</MfaDelete>'
mfa_header:
- - '{random 10-1000 printable} {random 10-1000 printable}'
+ - '{random 10-1000 printable_no_whitespace} {random 10-1000 printable_no_whitespace}'
headers:
- ['0-1', 'x-amz-mfa', '{mfa_header}']
choices: []
notification_body:
- null
- '<NotificationConfiguration />'
- - '2 <NotificationConfiguration><TopicConfiguration>{topic}{event}</TopicConfiguration}</NotificationConfiguration>'
+ - '2 <NotificationConfiguration><TopicConfiguration>{topic}{event}</TopicConfiguration></NotificationConfiguration>'
topic:
- null
- '2 <Topic>{garbage}</Topic>'
class RepeatExpandingFormatter(string.Formatter):
charsets = {
+ 'printable_no_whitespace': string.printable.translate(None, string.whitespace),
'printable': string.printable,
'punctuation': string.punctuation,
'whitespace': string.whitespace,
if self._recursion > 5:
raise RecursionError(key)
fmt = self.__class__(self.prng, _recursion=self._recursion+1)
- # must use vformat not **kwargs so our SpecialVariables is not
- # downgraded to just a dict
+
n = fmt.vformat(val, args, kwargs)
return n
except IndexError:
charset_arg = 'printable'
- if charset_arg == 'binary':
+ if charset_arg == 'binary' or charset_arg == 'binary_no_whitespace':
num_bytes = length + 8
tmplist = [self.prng.getrandbits(64) for _ in xrange(num_bytes / 8)]
tmpstring = struct.pack((num_bytes / 8) * 'Q', *tmplist)
+ if charset_arg == 'binary_no_whitespace':
+ tmpstring = ''.join(c for c in tmpstring if c not in string.whitespace)
return tmpstring[0:length]
else:
charset = self.charsets[charset_arg]
def parse_options():
parser = OptionParser()
parser.add_option('-O', '--outfile', help='write output to FILE. Defaults to STDOUT', metavar='FILE')
- parser.add_option('--seed', dest='seed', type='int', help='initial seed for the random number generator', metavar='SEED')
+ parser.add_option('--seed', dest='seed', type='int', help='initial seed for the random number generator')
parser.add_option('--seed-file', dest='seedfile', help='read seeds for specific requests from FILE', metavar='FILE')
parser.add_option('-n', dest='num_requests', type='int', help='issue NUM requests before stopping', metavar='NUM')
parser.add_option('-v', '--verbose', dest='verbose', action="store_true", help='turn on verbose output')
parser.add_option('-d', '--debug', dest='debug', action="store_true", help='turn on debugging (very verbose) output')
- parser.add_option('--decision-graph', dest='graph_filename', help='file in which to find the request decision graph', metavar='NUM')
+ parser.add_option('--decision-graph', dest='graph_filename', help='file in which to find the request decision graph')
+ parser.add_option('--no-cleanup', dest='cleanup', action="store_false", help='turn off teardown so you can peruse the state of buckets after testing')
parser.set_defaults(num_requests=5)
+ parser.set_defaults(cleanup=True)
parser.set_defaults(graph_filename='request_decision_graph.yml')
return parser.parse_args()
except KeyError:
headers = {}
- print>>VERBOSE, "%s %s" %(method[:100], path[:100])
+ print>>VERBOSE, "%r %r" %(method[:100], path[:100])
for h, v in headers.iteritems():
- print>>VERBOSE, "%s: %s" %(h[:50], v[:50])
- print>>VERBOSE, "%s\n" % body[:100]
+ print>>VERBOSE, "%r: %r" %(h[:50], v[:50])
+ print>>VERBOSE, "%r\n" % body[:100]
print>>DEBUG, 'FULL REQUEST'
print>>DEBUG, 'Method: %r' %method
#response = s3_connection.make_request(method, path, data=body, headers=headers, override_num_retries=0)
response = s3_connection.make_request(method, path, data=body, headers=headers)
+ failed = True if response.status in [500, 503] else False
+ if failed:
+ print>>OUT, 'FAILED:'
+ OLD_VERBOSE = VERBOSE
+ OLD_DEBUG = DEBUG
+ VERBOSE = DEBUG = OUT
print>>VERBOSE, 'Response status code: %d %s' %(response.status, response.reason)
print>>DEBUG, 'Body:\n%s' %response.read()
- if response.status == 500 or response.status == 503:
- print>>OUT, 'FAILED:\n%s' %request
print>>VERBOSE, '='*80
+ if failed:
+ VERBOSE = OLD_VERBOSE
+ DEBUG = OLD_DEBUG
print>>OUT, '...done fuzzing'
- common.teardown()
+
+ if options.cleanup:
+ common.teardown()
def main():