Skip to content
This repository has been archived by the owner on Jun 7, 2018. It is now read-only.

Commit

Permalink
- Reverted changes to AflBaseSync to keep it independent from rsync.
Browse files Browse the repository at this point in the history
- Reverted method signatures of __prepare_sync_commandline(),
  rsync_get() and rsync_put() to include optional rsync_options.
- Double quotes converted to single quotes.
- Bug in rsync_put_options generation fixed.
- Missing assertion added to test_afl_sync_push().
- Test for `--chmod`, `--chown` functionality added.
  • Loading branch information
rc0r committed Jul 5, 2017
1 parent 8da548c commit 6eb3fd2
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 12 deletions.
2 changes: 1 addition & 1 deletion afl_utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@
__author__ = 'rc0r <hlt99@blinkenshell.org> # @_rc0r'
__author_name__ = 'rc0r'
__author_email__ = 'hlt99@blinkenshell.org'
__version__ = "1.33a"
__version__ = "1.34a"
23 changes: 12 additions & 11 deletions afl_utils/afl_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,19 @@
_rsync_default_options = ['-racz']

class AflBaseSync(object):
def __init__(self, server_config, fuzzer_config, rsync_config):
def __init__(self, server_config, fuzzer_config):
self.server_config = server_config
self.fuzzer_config = fuzzer_config
self.rsync_config = rsync_config


class AflRsync(AflBaseSync):
def __init__(self, server_config, fuzzer_config, rsync_config):
self.rsync_config = rsync_config
# default excludes
self.__excludes = ['*.cur_input']
super(AflRsync, self).__init__(server_config, fuzzer_config, rsync_config)
super(AflRsync, self).__init__(server_config, fuzzer_config)

def __prepare_rsync_commandline(self, local_path, remote_path, rsync_options,
def __prepare_rsync_commandline(self, local_path, remote_path, rsync_options=list(_rsync_default_options),
rsync_excludes=list([]), rsync_get=False):
cmd = ['rsync']

Expand Down Expand Up @@ -66,11 +66,11 @@ def __get_fuzzers(self):
fuzzers = (fuzzer for fuzzer in fuzzers if not fuzzer.endswith('.sync'))
return fuzzers

def rsync_put(self, local_path, remote_path, rsync_options, rsync_excludes=list([])):
def rsync_put(self, local_path, remote_path, rsync_options=list(_rsync_default_options), rsync_excludes=list([])):
cmd = self.__prepare_rsync_commandline(local_path, remote_path, rsync_options, rsync_excludes)
return self.__invoke_rsync(cmd)

def rsync_get(self, remote_path, local_path, rsync_options, rsync_excludes=list([])):
def rsync_get(self, remote_path, local_path, rsync_options=list(_rsync_default_options), rsync_excludes=list([])):
cmd = self.__prepare_rsync_commandline(local_path, remote_path, rsync_options, rsync_excludes, True)
return self.__invoke_rsync(cmd)

Expand Down Expand Up @@ -152,10 +152,10 @@ def main(argv):
help='Destination directory used as fuzzer state storage. This shouldn\'t be an afl sync dir!')
parser.add_argument('--chmod',
help='Affect destination\'s file and directory permissions, e.g. --chmod=g+rw to add '
'read/write group permissions.', metavar="PERMS")
'read/write group permissions.', metavar='PERMS')
parser.add_argument('--chown',
help='Affect destination\'s file and directory user and group, e.g. --chown=foo:bar to '
'let the files be owned by user foo and group bar.', metavar="USER:GROUP")
'let the files be owned by user foo and group bar.', metavar='USER:GROUP')
parser.add_argument('-S', '--session', dest='session', default=None,
help='Name of an afl-multicore session. If provided, only fuzzers belonging to '
'the specified session will be synced with the destination. Otherwise state '
Expand All @@ -179,10 +179,11 @@ def main(argv):
print_warn('--chmod and --chown have no effect with pull and will be ignored.')

if args.chmod:
rsync_put_options.append("--chmod={}".format(args.chmod))
rsync_put_options.append('--chmod={}'.format(args.chmod))

if args.chown:
rsync_put_options.append(["--protect-args", "--chown={}".format(args.chown)])
rsync_put_options.append('--protect-args')
rsync_put_options.append('--chown={}'.format(args.chown))

if not os.path.exists(args.src_sync_dir):
if args.cmd in ['pull', 'sync']:
Expand Down Expand Up @@ -218,5 +219,5 @@ def main(argv):
rsyncEngine.sync()


if __name__ == "__main__":
if __name__ == '__main__':
main(sys.argv)
5 changes: 5 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# afl-utils Changelog

Version 1.34a

- Added `--chmod`, `--chown` rsync flags to afl-sync (contributed by
Denis Kasak).

Version 1.33a

- Added `--cmin-qemu`, `--tmin-qemu` options for QEMU mode support
Expand Down
32 changes: 32 additions & 0 deletions tests/test_afl_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import os
import shutil
import unittest
from unittest.mock import patch


class AflSyncTestCase(unittest.TestCase):
Expand Down Expand Up @@ -196,6 +197,7 @@ def test_afl_rsync_push(self):
self.assertTrue(os.path.exists('testdata/rsync_output_push/fuzz000.sync'))
self.assertFalse(os.path.exists('testdata/rsync_output_push/fuzz000.sync/.cur_input'))
self.assertTrue(os.path.exists('testdata/rsync_output_push/fuzz001.sync'))
self.assertFalse(os.path.exists('testdata/rsync_output_push/fuzz001.sync/.cur_input'))
self.assertFalse(os.path.exists('testdata/rsync_output_push/fuzz002.sync'))
self.assertFalse(os.path.exists('testdata/rsync_output_push/fuzz002.sync.sync'))
self.assertFalse(os.path.exists('testdata/rsync_output_push/invalid_fuzz000.sync'))
Expand Down Expand Up @@ -291,6 +293,36 @@ def test_afl_rsync_sync(self):
self.assertTrue(os.path.exists('testdata/rsync_output_sync/invalid_fuzz000.sync'))
self.assertTrue(os.path.exists('testdata/rsync_output_sync/invalid_fuzz001.sync'))

@patch('afl_utils.afl_sync.AflRsync')
def test_main_chmod_chown(self, mock_afl_rsync):
argv = [
'afl-sync',
'--chmod=ABCD',
'--chown=EFGH',
'pull',
'testdata/sync',
'remote'
]

expected_server_config = {
'remote_path': 'remote'
}

expected_fuzzer_config = {
'sync_dir': 'testdata/sync',
'session': None,
'exclude_crashes': False,
'exclude_hangs': False
}

expected_rsync_config = {
'get': ['-racz'],
'put': ['-racz', '--chmod=ABCD', '--protect-args', '--chown=EFGH']
}

self.assertIsNone(afl_sync.main(argv))
mock_afl_rsync.assert_called_with(expected_server_config, expected_fuzzer_config, expected_rsync_config)

def test_main(self):
argv = [
'afl-sync'
Expand Down

0 comments on commit 6eb3fd2

Please sign in to comment.