def _download(url, filename, directory, TUF=False):
    destination = os.path.join(directory, filename)
    if TUF:
        tuf.interposition.urllib_tuf.urlretrieve(url, destination)
    else:
        urllib.urlretrieve(url, destination)

    if util_test_tools.read_file_content(destination) != '':
        required_files = util_test_tools.read_file_content(destination).split(
            ',')
        for required_filename in required_files:
            required_file_url = os.path.dirname(
                url) + os.sep + required_filename
            _download(required_file_url, required_filename, directory, TUF)
Example #2
0
    def test_methods(self):
        """
    Making sure following methods work as intended:
    - add_file_to_repository(data)
    - modify_file_at_repository(filepath, data)
    - delete_file_at_repository(filepath)
    - read_file_content(filepath)
    - tuf_refresh_repo()
    - tuf_refresh_and_download()

    Note: here file at the 'filepath' and the 'target' file at tuf-targets
    directory are identical files.
    Ex: filepath = '{root_repo}/reg_repo/file.txt'
        target = '{root_repo}/tuf_repo/targets/file.txt'
    """

        reg_repo = os.path.join(self.root_repo, 'reg_repo')
        tuf_repo = os.path.join(self.root_repo, 'tuf_repo')
        downloads = os.path.join(self.root_repo, 'downloads')

        # Test 'add_file_to_repository(directory, data)' and
        # read_file_content(filepath) methods.
        filepath = util_test_tools.add_file_to_repository(reg_repo, 'Test')
        self.assertTrue(os.path.isfile(filepath))
        self.assertEquals(os.path.dirname(filepath), reg_repo)
        filepath_content = util_test_tools.read_file_content(filepath)
        self.assertEquals('Test', filepath_content)

        # Test 'modify_file_at_repository(filepath, data)' method.
        filepath = util_test_tools.modify_file_at_repository(
            filepath, 'Modify')
        self.assertTrue(os.path.exists(filepath))
        filepath_content = util_test_tools.read_file_content(filepath)
        self.assertEquals('Modify', filepath_content)

        # Test 'tuf_refresh_repo' method.
        util_test_tools.tuf_refresh_repo(self.root_repo, self.keyids)
        file_basename = os.path.basename(filepath)
        target = os.path.join(tuf_repo, 'targets', file_basename)
        self.assertTrue(os.path.isfile(target))

        # Test 'delete_file_at_repository(filepath)' method.
        util_test_tools.delete_file_at_repository(filepath)
        self.assertFalse(os.path.exists(filepath))

        # Test 'tuf_refresh_repo' method once more.
        util_test_tools.tuf_refresh_repo(self.root_repo, self.keyids)
        file_basename = os.path.basename(filepath)
        target = os.path.join(tuf_repo, 'targets', file_basename)
        self.assertFalse(os.path.isfile(target))
Example #3
0
  def test_methods(self):
    """
    Making sure following methods work as intended:
    - add_file_to_repository(data)
    - modify_file_at_repository(filepath, data)
    - delete_file_at_repository(filepath)
    - read_file_content(filepath)
    - tuf_refresh_repo()
    - tuf_refresh_and_download()

    Note: here file at the 'filepath' and the 'target' file at tuf-targets
    directory are identical files.
    Ex: filepath = '{root_repo}/reg_repo/file.txt'
        target = '{root_repo}/tuf_repo/targets/file.txt'
    """

    reg_repo = os.path.join(self.root_repo, 'reg_repo')
    tuf_repo = os.path.join(self.root_repo, 'tuf_repo')
    downloads = os.path.join(self.root_repo, 'downloads')

    # Test 'add_file_to_repository(directory, data)' and
    # read_file_content(filepath) methods.
    filepath = util_test_tools.add_file_to_repository(reg_repo, 'Test')
    self.assertTrue(os.path.isfile(filepath))
    self.assertEquals(os.path.dirname(filepath), reg_repo)
    filepath_content = util_test_tools.read_file_content(filepath)
    self.assertEquals('Test', filepath_content)

    # Test 'modify_file_at_repository(filepath, data)' method.
    filepath = util_test_tools.modify_file_at_repository(filepath, 'Modify')
    self.assertTrue(os.path.exists(filepath))
    filepath_content = util_test_tools.read_file_content(filepath)
    self.assertEquals('Modify', filepath_content)

    # Test 'tuf_refresh_repo' method.
    util_test_tools.tuf_refresh_repo(self.root_repo, self.keyids)
    file_basename = os.path.basename(filepath)
    target = os.path.join(tuf_repo, 'targets', file_basename)
    self.assertTrue(os.path.isfile(target))

    # Test 'delete_file_at_repository(filepath)' method.
    util_test_tools.delete_file_at_repository(filepath)
    self.assertFalse(os.path.exists(filepath))

    # Test 'tuf_refresh_repo' method once more.
    util_test_tools.tuf_refresh_repo(self.root_repo, self.keyids)
    file_basename = os.path.basename(filepath)
    target = os.path.join(tuf_repo, 'targets', file_basename)
    self.assertFalse(os.path.isfile(target))
Example #4
0
    def test_direct_download(self):
        # Setup.
        reg_repo = os.path.join(self.root_repo, 'reg_repo')
        downloads = os.path.join(self.root_repo, 'downloads')
        filepath = util_test_tools.add_file_to_repository(reg_repo, 'Test')
        file_basename = os.path.basename(filepath)
        url_to_reg_repo = self.url + 'reg_repo/' + file_basename
        downloaded_file = os.path.join(downloads, file_basename)

        # Test direct download using 'urllib.urlretrieve'.
        urllib.urlretrieve(url_to_reg_repo, downloaded_file)
        self.assertTrue(os.path.isfile(downloaded_file))

        # Verify the content of the downloaded file.
        downloaded_content = util_test_tools.read_file_content(downloaded_file)
        self.assertEquals('Test', downloaded_content)
Example #5
0
  def test_direct_download(self):
    # Setup.
    reg_repo = os.path.join(self.root_repo, 'reg_repo')
    downloads = os.path.join(self.root_repo, 'downloads')
    filepath = util_test_tools.add_file_to_repository(reg_repo, 'Test')
    file_basename = os.path.basename(filepath)
    url_to_reg_repo = self.url+'reg_repo/'+file_basename
    downloaded_file = os.path.join(downloads, file_basename)

    # Test direct download using 'urllib.urlretrieve'.
    urllib.urlretrieve(url_to_reg_repo, downloaded_file)
    self.assertTrue(os.path.isfile(downloaded_file))

    # Verify the content of the downloaded file.
    downloaded_content = util_test_tools.read_file_content(downloaded_file)
    self.assertEquals('Test', downloaded_content)
def test_arbitrary_package_attack(TUF=False):
  """
  <Arguments>
    TUF:
      If set to 'False' all directories that start with 'tuf_' are ignored, 
      indicating that tuf is not implemented.

  <Purpose>
    Illustrate arbitrary package attack vulnerability.

  """

  ERROR_MSG = 'Arbitrary Package Attack was Successful!\n'


  try:
    # Setup.
    root_repo, url, server_proc, keyids = util_test_tools.init_repo(tuf=TUF)
    reg_repo = os.path.join(root_repo, 'reg_repo')
    tuf_repo = os.path.join(root_repo, 'tuf_repo')
    downloads = os.path.join(root_repo, 'downloads')
    targets_dir = os.path.join(tuf_repo, 'targets')

    # Add a file to 'repo' directory: {root_repo}
    filepath = util_test_tools.add_file_to_repository(reg_repo, 'Test A')
    file_basename = os.path.basename(filepath)
    url_to_repo = url+'reg_repo/'+file_basename
    downloaded_file = os.path.join(downloads, file_basename)

    if TUF:
      # Update TUF metadata before attacker modifies anything.
      util_test_tools.tuf_refresh_repo(root_repo, keyids)

      # Modify the url.  Remember that the interposition will intercept 
      # urls that have 'localhost:9999' hostname, which was specified in
      # the json interposition configuration file.  Look for 'hostname'
      # in 'util_test_tools.py'. Further, the 'file_basename' is the target
      # path relative to 'targets_dir'. 
      url_to_repo = 'http://localhost:9999/'+file_basename

      # Attacker modifies the file at the targets repository.
      target = os.path.join(targets_dir, file_basename)
      util_test_tools.modify_file_at_repository(target, 'Evil A')

    # Attacker modifies the file at the regular repository.
    util_test_tools.modify_file_at_repository(filepath, 'Evil A')

    # End of Setup.


    try:
      # Client downloads (tries to download) the file.
      _download(url=url_to_repo, filename=downloaded_file, tuf=TUF)

    except tuf.DownloadError:
      # If tuf.DownloadError is raised, this means that TUF has prevented
      # the download of an unrecognized file.  Enable the logging to see,
      # what actually happened.
      pass

    else:
      # Check whether the attack succeeded by inspecting the content of the
      # update.  The update should contain 'Test A'.  Technically it suffices
      # to check whether the file was downloaded or not.
      downloaded_content = util_test_tools.read_file_content(downloaded_file)
      if 'Test A' != downloaded_content:
        raise ArbitraryPackageAlert(ERROR_MSG)


  finally:
    util_test_tools.cleanup(root_repo, server_proc)
Example #7
0
def test_arbitrary_package_attack(TUF=False):
    """
  <Arguments>
    TUF:
      If set to 'False' all directories that start with 'tuf_' are ignored, 
      indicating that tuf is not implemented.

  <Purpose>
    Illustrate endless data attack vulnerability.

  """

    ERROR_MSG = 'Endless Data Attack was Successful!\n'

    try:
        # Setup.
        root_repo, url, server_proc, keyids = util_test_tools.init_repo(
            tuf=TUF)
        reg_repo = os.path.join(root_repo, 'reg_repo')
        tuf_repo = os.path.join(root_repo, 'tuf_repo')
        downloads = os.path.join(root_repo, 'downloads')
        tuf_targets = os.path.join(tuf_repo, 'targets')

        # Add a file to 'repo' directory: {root_repo}
        filepath = util_test_tools.add_file_to_repository(reg_repo, 'Test A')
        file_basename = os.path.basename(filepath)
        url_to_repo = url + 'reg_repo/' + file_basename
        downloaded_file = os.path.join(downloads, file_basename)
        endless_data = 'A' * 100

        if TUF:
            # Update TUF metadata before attacker modifies anything.
            util_test_tools.tuf_refresh_repo(root_repo, keyids)

            # Modify the url.  Remember that the interposition will intercept
            # urls that have 'localhost:9999' hostname, which was specified in
            # the json interposition configuration file.  Look for 'hostname'
            # in 'util_test_tools.py'. Further, the 'file_basename' is the target
            # path relative to 'targets_dir'.
            url_to_repo = 'http://localhost:9999/' + file_basename

            # Attacker modifies the file at the targets repository.
            target = os.path.join(tuf_targets, file_basename)
            util_test_tools.modify_file_at_repository(target, endless_data)

        # Attacker modifies the file at the regular repository.
        util_test_tools.modify_file_at_repository(filepath, endless_data)

        # End Setup.

        try:
            # Client downloads (tries to download) the file.
            _download(url=url_to_repo, filename=downloaded_file, tuf=TUF)

        except tuf.DownloadError:
            # If tuf.DownloadError is raised, this means that TUF has prevented
            # the download of an unrecognized file.  Enable the logging to see,
            # what actually happened.
            pass

        else:
            # Check whether the attack succeeded by inspecting the content of the
            # update.  The update should contain 'Test A'.  Technically it suffices
            # to check whether the file was downloaded or not.
            downloaded_content = util_test_tools.read_file_content(
                downloaded_file)
            if 'Test A' != downloaded_content:
                raise EndlessDataAttack(ERROR_MSG)

    finally:
        util_test_tools.cleanup(root_repo, server_proc)
def test_mix_and_match_attack(TUF=False):
  """
  Attack design:
    There are 3 stages:
      Stage 1: Consists of a usual mode of operations using tuf.  Client 
      downloads a target file. (Initial download)

      Stage 2: The target file is legitimately modified and metadata correctly
      updated.  Client downloads the target file again. (Patched target download)

      Stage 3: The target file is legitimately modified  and metadata correctly
      updated again.  However, before client gets to download the newly patched
      target file the attacker replaces the release metadata, targets metadata
      and the target file with the ones from stage 1 (mix-and-match attack).
      Note that timestamp metadata is untouched.  Further note that same would
      happen if only target metadata, and target file are reverted.
  """

  ERROR_MSG = '\tMix-And-Match Attack was Successful!\n\n'


  try:
    # Setup / Stage 1
    # ---------------
    root_repo, url, server_proc, keyids = util_test_tools.init_repo(tuf=TUF)
    reg_repo = os.path.join(root_repo, 'reg_repo')
    downloads = os.path.join(root_repo, 'downloads')
    evil_dir = tempfile.mkdtemp(dir=root_repo)
    
    # Add file to 'repo' directory: {root_repo}
    filepath = util_test_tools.add_file_to_repository(reg_repo, 'A'*10)
    file_basename = os.path.basename(filepath)
    url_to_file = url+'reg_repo/'+file_basename
    downloaded_file = os.path.join(downloads, file_basename)

    # Attacker saves the initial file.
    shutil.copy(filepath, evil_dir)
    unpatched_file = os.path.join(evil_dir, file_basename)


    if TUF:
      print 'TUF ...'
      tuf_repo = os.path.join(root_repo, 'tuf_repo')
      tuf_targets = os.path.join(tuf_repo, 'targets')
      metadata_dir = os.path.join(tuf_repo, 'metadata')
      release_meta_file = os.path.join(metadata_dir, 'release.txt')
      targets_meta_file = os.path.join(metadata_dir, 'targets.txt')
      target = os.path.join(tuf_targets, file_basename)
      
      # Update TUF metadata before attacker modifies anything.
      util_test_tools.tuf_refresh_repo(root_repo, keyids)

      # Attacker saves the original metadata and the target file.
      #shutil.copy(target, evil_dir)
      shutil.copy(release_meta_file, evil_dir)
      shutil.copy(targets_meta_file, evil_dir)
      #target_old = os.path.join(evil_dir, file_basename)
      release_meta_file_old = os.path.join(evil_dir, 'release.txt')
      targets_meta_file_old = os.path.join(evil_dir, 'targets.txt')

      # Modify the url.  Remember that the interposition will intercept 
      # urls that have 'localhost:9999' hostname, which was specified in
      # the json interposition configuration file.  Look for 'hostname'
      # in 'util_test_tools.py'. Further, the 'file_basename' is the target
      # path relative to 'targets_dir'. 
      url_to_file = 'http://localhost:9999/'+file_basename


    # Client's initial download.
    _download(url=url_to_file, filename=downloaded_file, tuf=TUF)

    # Stage 2
    # -------
    # Developer patches the file and updates the repository.
    util_test_tools.modify_file_at_repository(filepath, 'B'*11)

    # Updating tuf repository.  This will copy files from regular repository
    # into tuf repository and refresh the metadata
    if TUF:
      util_test_tools.tuf_refresh_repo(root_repo, keyids)

    # Client downloads the patched file.
    _download(url=url_to_file, filename=downloaded_file, tuf=TUF)

    downloaded_content = util_test_tools.read_file_content(downloaded_file)

    # Stage 3
    # -------
    # Developer patches the file and updates the repository again.
    util_test_tools.modify_file_at_repository(filepath, 'C'*10)

    # Updating tuf repository.  This will copy files from regular repository
    # into tuf repository and refresh the metadata
    if TUF:
      util_test_tools.tuf_refresh_repo(root_repo, keyids)

      # Attacker replaces the metadata and the target file.
      shutil.copyfile(unpatched_file, target)
      shutil.copyfile(release_meta_file_old, release_meta_file)
      shutil.copyfile(targets_meta_file_old, targets_meta_file)

    # Attacker replaces the patched file with the unpatched one.
    shutil.copyfile(unpatched_file, filepath)

    # Client tries to downloads the newly patched file.
    try:
      _download(url=url_to_file, filename=downloaded_file, tuf=TUF)
    except tuf.MetadataNotAvailableError:
      pass

    # Check whether the attack succeeded by inspecting the content of the
    # update.  The update should contain 'Test NOT A'.
    downloaded_content = util_test_tools.read_file_content(downloaded_file)
    if ('B'*11) != downloaded_content:
      raise MixAndMatchAttackAlert(ERROR_MSG)


  finally:
    util_test_tools.cleanup(root_repo, server_proc)
def test_replay_attack(TUF=False):
  """
  <Arguments>
    TUF:
      If set to 'False' all directories that start with 'tuf_' are ignored, 
      indicating that tuf is not implemented.

  <Purpose>
    

  """

  try:
    # Setup.
    root_repo, url, server_proc, keyids, interpose_json = \
      util_test_tools.init_repo(tuf=TUF)
    reg_repo = os.path.join(root_repo, 'reg_repo')
    tuf_repo = os.path.join(root_repo, 'tuf_repo')
    downloads = os.path.join(root_repo, 'downloads')
    tuf_targets = os.path.join(tuf_repo, 'targets')

    # Add file to 'repo' directory: {root_repo}
    filepath = util_test_tools.add_file_to_repository(reg_repo, 'Test A')
    file_basename = os.path.basename(filepath)
    url_to_repo = url+'reg_repo/'+file_basename
    downloaded_file = os.path.join(downloads, file_basename)

    # Attacker saves the original file into 'evil_dir'.
    evil_dir = tempfile.mkdtemp(dir=root_repo)
    vulnerable_file = os.path.join(evil_dir, file_basename)
    shutil.copy(filepath, evil_dir)

    # Refresh the tuf repository and apply tuf interpose.
    if TUF:
      util_test_tools.tuf_refresh_repo(root_repo, keyids)
      tuf.interposition.configure(interpose_json)
      tuf.interposition.interpose()

    # End Setup.

    # Client performs initial update.
    urllib.urlretrieve(url_to_repo, downloaded_file)

    # Downloads are stored in the same directory '{root_repo}/downloads/'
    # for regular and tuf clients.
    downloaded_content = util_test_tools.read_file_content(downloaded_file)
    msg = '[Initial Updata] Failed to download the file.'
    if 'Test A' != downloaded_content:
      raise TestSetupError(msg)

    # Developer patches the file and updates the repository.
    util_test_tools.modify_file_at_repository(filepath, 'Test NOT A')

    # Updating tuf repository.  This will copy files from regular repository
    # into tuf repository and refresh the metad 
    if TUF:
      util_test_tools.tuf_refresh_repo(root_repo, keyids)

    # Client downloads the patched file.
    urllib.urlretrieve(url_to_repo, downloaded_file)

    # Content of the downloaded file.
    downloaded_content = util_test_tools.read_file_content(downloaded_file)
    msg = '[Update] Failed to update the file.'
    if 'Test NOT A' != downloaded_content:
      raise TestSetupError(msg)

    # Attacker tries to be clever, he manages to modifies regular and tuf 
    # targets directory by replacing a patched file with an old one.
    if os.path.isdir(tuf_targets):
      target = os.path.join(tuf_targets, file_basename)
      util_test_tools.delete_file_at_repository(target)
      shutil.copy(vulnerable_file, tuf_targets)
      # Verify that 'target' is an old, un-patched file.
      target = os.path.join(tuf_targets, file_basename)
      target_content = util_test_tools.read_file_content(target)
      msg = "The 'target' file contains new data!"
      if 'Test A' != target_content:
        raise TestSetupError(msg)
    else:
      util_test_tools.delete_file_at_repository(filepath)
      shutil.copy(vulnerable_file, reg_repo)

    # Client downloads the file once time.
    urllib.urlretrieve(url_to_repo, downloaded_file)

    # Check whether the attack succeeded by inspecting the content of the
    # update.  The update should contain 'Test NOT A'.
    downloaded_content = util_test_tools.read_file_content(downloaded_file)
    msg = 'Replay attack was successful!\n'
    if 'Test NOT A' != downloaded_content:
      raise ReplayAttackError(msg)

  finally:
    tuf.interposition.go_away()
    util_test_tools.cleanup(root_repo, server_proc)
Example #10
0
def test_mix_and_match_attack(TUF=False):
    """
  Attack design:
    There are 3 stages:
      Stage 1: Consists of a usual mode of operations using tuf.  Client 
      downloads a target file. (Initial download)

      Stage 2: The target file is legitimately modified and metadata correctly
      updated.  Client downloads the target file again. (Patched target download)

      Stage 3: The target file is legitimately modified  and metadata correctly
      updated again.  However, before client gets to download the newly patched
      target file the attacker replaces the release metadata, targets metadata
      and the target file with the ones from stage 1 (mix-and-match attack).
      Note that timestamp metadata is untouched.  Further note that same would
      happen if only target metadata, and target file are reverted.
  """

    ERROR_MSG = '\tMix-And-Match Attack was Successful!\n\n'

    try:
        # Setup / Stage 1
        # ---------------
        root_repo, url, server_proc, keyids = util_test_tools.init_repo(
            tuf=TUF)
        reg_repo = os.path.join(root_repo, 'reg_repo')
        downloads = os.path.join(root_repo, 'downloads')
        evil_dir = tempfile.mkdtemp(dir=root_repo)

        # Add file to 'repo' directory: {root_repo}
        filepath = util_test_tools.add_file_to_repository(reg_repo, 'A' * 10)
        file_basename = os.path.basename(filepath)
        url_to_file = url + 'reg_repo/' + file_basename
        downloaded_file = os.path.join(downloads, file_basename)

        # Attacker saves the initial file.
        shutil.copy(filepath, evil_dir)
        unpatched_file = os.path.join(evil_dir, file_basename)

        if TUF:
            print 'TUF ...'
            tuf_repo = os.path.join(root_repo, 'tuf_repo')
            tuf_targets = os.path.join(tuf_repo, 'targets')
            metadata_dir = os.path.join(tuf_repo, 'metadata')
            release_meta_file = os.path.join(metadata_dir, 'release.txt')
            targets_meta_file = os.path.join(metadata_dir, 'targets.txt')
            target = os.path.join(tuf_targets, file_basename)

            # Update TUF metadata before attacker modifies anything.
            util_test_tools.tuf_refresh_repo(root_repo, keyids)

            # Attacker saves the original metadata and the target file.
            #shutil.copy(target, evil_dir)
            shutil.copy(release_meta_file, evil_dir)
            shutil.copy(targets_meta_file, evil_dir)
            #target_old = os.path.join(evil_dir, file_basename)
            release_meta_file_old = os.path.join(evil_dir, 'release.txt')
            targets_meta_file_old = os.path.join(evil_dir, 'targets.txt')

            # Modify the url.  Remember that the interposition will intercept
            # urls that have 'localhost:9999' hostname, which was specified in
            # the json interposition configuration file.  Look for 'hostname'
            # in 'util_test_tools.py'. Further, the 'file_basename' is the target
            # path relative to 'targets_dir'.
            url_to_file = 'http://localhost:9999/' + file_basename

        # Client's initial download.
        _download(url=url_to_file, filename=downloaded_file, tuf=TUF)

        # Stage 2
        # -------
        # Developer patches the file and updates the repository.
        util_test_tools.modify_file_at_repository(filepath, 'B' * 11)

        # Updating tuf repository.  This will copy files from regular repository
        # into tuf repository and refresh the metadata
        if TUF:
            util_test_tools.tuf_refresh_repo(root_repo, keyids)

        # Client downloads the patched file.
        _download(url=url_to_file, filename=downloaded_file, tuf=TUF)

        downloaded_content = util_test_tools.read_file_content(downloaded_file)

        # Stage 3
        # -------
        # Developer patches the file and updates the repository again.
        util_test_tools.modify_file_at_repository(filepath, 'C' * 10)

        # Updating tuf repository.  This will copy files from regular repository
        # into tuf repository and refresh the metadata
        if TUF:
            util_test_tools.tuf_refresh_repo(root_repo, keyids)

            # Attacker replaces the metadata and the target file.
            shutil.copyfile(unpatched_file, target)
            shutil.copyfile(release_meta_file_old, release_meta_file)
            shutil.copyfile(targets_meta_file_old, targets_meta_file)

        # Attacker replaces the patched file with the unpatched one.
        shutil.copyfile(unpatched_file, filepath)

        # Client tries to downloads the newly patched file.
        try:
            _download(url=url_to_file, filename=downloaded_file, tuf=TUF)
        except tuf.MetadataNotAvailableError:
            pass

        # Check whether the attack succeeded by inspecting the content of the
        # update.  The update should contain 'Test NOT A'.
        downloaded_content = util_test_tools.read_file_content(downloaded_file)
        if ('B' * 11) != downloaded_content:
            raise MixAndMatchAttackAlert(ERROR_MSG)

    finally:
        util_test_tools.cleanup(root_repo, server_proc)
Example #11
0
def test_replay_attack(TUF=False):
  """
  <Arguments>
    TUF:
      If set to 'False' all directories that start with 'tuf_' are ignored, 
      indicating that tuf is not implemented.

  <Purpose>
    Illustrate replay attack vulnerability.

  """

  ERROR_MSG = 'Replay Attack was Successful!\n'


  try:
    # Setup.
    root_repo, url, server_proc, keyids = util_test_tools.init_repo(tuf=TUF)
    reg_repo = os.path.join(root_repo, 'reg_repo')
    tuf_repo = os.path.join(root_repo, 'tuf_repo')
    downloads = os.path.join(root_repo, 'downloads')
    tuf_targets = os.path.join(tuf_repo, 'targets')

    # Add file to 'repo' directory: {root_repo}
    filepath = util_test_tools.add_file_to_repository(reg_repo, 'Test A')
    file_basename = os.path.basename(filepath)
    url_to_repo = url+'reg_repo/'+file_basename
    downloaded_file = os.path.join(downloads, file_basename)

    # Attacker saves the original file into 'evil_dir'.
    evil_dir = tempfile.mkdtemp(dir=root_repo)
    vulnerable_file = os.path.join(evil_dir, file_basename)
    shutil.copy(filepath, evil_dir)

    if TUF:
      # Update TUF metadata before attacker modifies anything.
      util_test_tools.tuf_refresh_repo(root_repo, keyids)

      # Modify the url.  Remember that the interposition will intercept 
      # urls that have 'localhost:9999' hostname, which was specified in
      # the json interposition configuration file.  Look for 'hostname'
      # in 'util_test_tools.py'. Further, the 'file_basename' is the target
      # path relative to 'targets_dir'. 
      url_to_repo = 'http://localhost:9999/'+file_basename

    # End of Setup.


    # Client performs initial update.
    _download(url=url_to_repo, filename=downloaded_file, tuf=TUF)

    # Downloads are stored in the same directory '{root_repo}/downloads/'
    # for regular and tuf clients.
    downloaded_content = util_test_tools.read_file_content(downloaded_file)
    if 'Test A' != downloaded_content:
      raise TestSetupError('[Initial Updata] Failed to download the file.')

    # Developer patches the file and updates the repository.
    util_test_tools.modify_file_at_repository(filepath, 'Test NOT A')

    # Updating tuf repository.  This will copy files from regular repository
    # into tuf repository and refresh the metad 
    if TUF:
      util_test_tools.tuf_refresh_repo(root_repo, keyids)


    # Client downloads the patched file.
    _download(url=url_to_repo, filename=downloaded_file, tuf=TUF)

    # Content of the downloaded file.
    downloaded_content = util_test_tools.read_file_content(downloaded_file)
    if 'Test NOT A' != downloaded_content:
      raise TestSetupError('[Update] Failed to update the file.')

    # Attacker tries to be clever, he manages to modifies regular and tuf 
    # targets directory by replacing a patched file with an old one.
    if os.path.isdir(tuf_targets):
      target = os.path.join(tuf_targets, file_basename)
      util_test_tools.delete_file_at_repository(target)
      shutil.copy(vulnerable_file, tuf_targets)
      # Verify that 'target' is an old, un-patched file.
      target = os.path.join(tuf_targets, file_basename)
      target_content = util_test_tools.read_file_content(target)
      if 'Test A' != target_content:
        raise TestSetupError("The 'target' file contains new data!")

    else:
      util_test_tools.delete_file_at_repository(filepath)
      shutil.copy(vulnerable_file, reg_repo)


    # Client downloads the file once more.
    _download(url=url_to_repo, filename=downloaded_file, tuf=TUF)

    # Check whether the attack succeeded by inspecting the content of the
    # update.  The update should contain 'Test NOT A'.
    downloaded_content = util_test_tools.read_file_content(downloaded_file)
    if 'Test NOT A' != downloaded_content:
      raise ReplayAttackAlert(ERROR_MSG)


  finally:
    util_test_tools.cleanup(root_repo, server_proc)