Commit graph

446 commits

Author SHA1 Message Date
Jussi Kukkonen
7da1f1e41b legacy client: Remove dead code
_fileinfo_has_changed() and _update_fileinfo() have been unused internal
methods since 2016. Remove them.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-10-13 15:59:56 +03:00
Jussi Kukkonen
98e97e31d9 legacy client: Do local filename encoding in all places
The original commit 051b8229 handled the loading and saving metadata
cases but the legacy client actually checks for the files existence
in various other places:
 * _update_versioninfo() never reads the file but operates differently
   depending on whether the file exists or not
 * _move_current_to_previous() that copies files around
 * MultiRepoUpdater initialization: this only handle root.json so
   is still correct
 * _update_fileinfo() which is dead code

Fix the first two of these cases.
2021-10-13 15:59:56 +03:00
Jussi Kukkonen
81e5862be9 legacy client: Encode rolenames when using as filenames
If an attacker manages to create arbitrary rolenames they could trick
the client into writing metadata files into unexpected locations:
To avoid directory traversal and writing files into unexpected
locations, encode the rolename before using it as filename.

If a client has delegated targets metadata with rolenames that have
percent-encoded characters in them, these metadata will now not be
found in local metadata cache and must be re-downloaded.

Note that this does not mean using rolenames that get encoded is
advisable (as forming the download URLs still has issues with them),
this just means the client will not do unsafe writes when it encounters
rolenames like this.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-10-13 15:59:56 +03:00
Velichka Atanasova
0fa6c6f2ca Add 'ecdsa' to the list of supported key types
Signed-off-by: Velichka Atanasova <avelichka@vmware.com>
2021-06-17 11:48:30 +03:00
Kainaat Singh
ec68bd9316 Remove future module #1297
Signed-off-by: Kainaat Singh <kainaatsingh93@gmail.com>

remove unwanted lines
2021-04-11 11:37:45 +02:00
Velichka Atanasova
d8b3554662 Remove use of six
Remove use of six

Signed-off-by: Velichka Atanasova <avelichka@vmware.com>

Replace the use of dict.items(mydict) with mydict.items(), dict.keys(mydict) with mydict.keys() and dict.values(mydict) with mydict.values()

Signed-off-by: Velichka Atanasova <avelichka@vmware.com>

Replace 'import urllib' and 'import urllib.x' with 'from urllib import x' for vendor compatibility

Signed-off-by: Velichka Atanasova <avelichka@vmware.com>
2021-04-09 14:07:44 +03:00
Jussi Kukkonen
30ab838575 Make requests_fetcher import vendoring compatible
Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-03-19 17:01:45 +02:00
Jussi Kukkonen
d5b6f91f6f imports: Remove unused imports
The linter now understands our imports (yay), and complains a lot (boo):
* Remove really unused imports
* disable lints for tuf.log and securesystemslib imports: these imports
  have logging side-effects (they set default loggers for tuf and
  securesystemslib respectively) and I'm cautious about just removing
  them

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-03-19 16:56:50 +02:00
Jussi Kukkonen
0aabb82a80 imports: Move six imports to 3rd party section
Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-03-19 16:56:50 +02:00
Jussi Kukkonen
538623b6eb imports: Make 'keydb' imports vendoring-compatible
Use "from tuf import <module>" instead of "import tuf.<module>": this
makes it possible for vendoring tool to vendor tuf. Fix all references
to <module> in the code.

Also fix import orders so tuf internal imports are last.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-03-19 16:56:50 +02:00
Jussi Kukkonen
dd134a43c8 imports: Fix securesystemslib.hash imports
Make them compatible with vendoring, use
  from securesystemslib import hash as sslib_hash
to have the same style as other securesystemslib imports (and to avoid
potential conflict with system hash()).

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-03-19 16:56:50 +02:00
Jussi Kukkonen
46ebfd0461 imports: Fix securesystemslib.util imports
Make the import compatible with vendoring tool and alias the import so
it does not clash with the local module. Fix all references
to the module in the code.

In one instance import a specific function to avoid a more complex
redirection in the code.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-03-19 16:56:50 +02:00
Jussi Kukkonen
f702fdfd0c imports: Fix securesystemslib.keys imports
Make them compatible with vendoring, use
  from securesystemslib import keys as sslib_keys
to have the same style as other securesystemslib imports.

Note that developer_tool already used a
   from securesystemslib.keys import ...
for some functions so that style was used consistently there.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-03-19 16:56:50 +02:00
Jussi Kukkonen
79385cc10f imports: Fix securesystemslib.formats imports
Make the import compatible with vendoring tool and alias the import so
it does not clash with the local module. Fix all references
to the module in the code.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-03-19 16:56:50 +02:00
Jussi Kukkonen
fe3daccdb5 imports: Make 'updater' import vendoring-compatible
Make the updater imports compatible with vendoring tool by importing
the Updater class directly (don't import the whole module to avoid the
clash with the obvious variable name 'updater').

Also update the example: This is not required in the clients but tuf
source code will be vendored and this import line (even though in a
comment) might trigger an error in future vendoring tool releases.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-03-19 16:56:50 +02:00
Jussi Kukkonen
6faed27e0a imports: Fix securesystemslib.exceptions imports
Make the import compatible with vendoring tool and alias the import so
it does not clash with the local module. Fix all references
to the module in the code.

Remove a related repo.py comment that was badly duplicated from module
docstring.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-03-19 16:56:50 +02:00
Jussi Kukkonen
9d7047ffc9 imports: Make 'sig' imports vendoring-compatible
Use "from tuf import <module>" instead of "import tuf.<module>": this
makes it possible for vendoring tool to vendor tuf. Fix all references
to <module> in the code.

Remove one unused import.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-03-19 16:56:50 +02:00
Jussi Kukkonen
c66c61f1d0 imports: Make 'settings' imports vendoring-compatible
Use "from tuf import <module>" instead of "import tuf.<module>": this
makes it possible for vendoring tool to vendor tuf. Fix all references
to <module> in the code.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-03-19 16:56:50 +02:00
Jussi Kukkonen
9550b1470d imports: Make 'roledb' imports vendoring-compatible
Use "from tuf import <module>" instead of "import tuf.<module>": this
makes it possible for vendoring tool to vendor tuf. Fix all references
to <module> in the code.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-03-19 16:56:50 +02:00
Jussi Kukkonen
02046c0f49 imports: Make 'mirrors' imports vendoring compatible
Use "from tuf import <module>" instead of "import tuf.<module>": this
makes it possible for vendoring tool to vendor tuf. Fix all references
to <module> in the code.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-03-19 16:56:50 +02:00
Jussi Kukkonen
696b92902e updater: rename mirrors variables
Make sure mirrors is not used as variable name (so it can be used for
the module import name later).

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-03-19 16:56:50 +02:00
Jussi Kukkonen
07b3aed03c imports: Make 'log' imports vendoring-compatible
Use "from tuf import <module>" instead of "import tuf.<module>": this
makes it possible for vendoring tool to vendor tuf. Fix all references
to <module> in the code.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-03-19 16:56:50 +02:00
Jussi Kukkonen
4575637efd imports: Make 'formats' imports vendoring-compatible
Use "from tuf import <module>" instead of "import tuf.<module>": this
makes it possible for vendoring tool to vendor tuf. Fix all references
to <module> in the code.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-03-19 16:56:47 +02:00
Jussi Kukkonen
4b078b0975 imports: Make 'exceptions' imports vendoring-compatible
Use "from tuf import <module>" instead of "import tuf.<module>": this
makes it possible for vendoring tool to vendor tuf. Fix all references
to <module> in the code.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-03-19 16:54:39 +02:00
Jussi Kukkonen
8dc07ccd9a imports: Make 'download' imports vendoring-compatible
Use "from tuf import <module>" instead of "import tuf.<module>": this
makes it possible for vendoring tool to vendor tuf. Fix all references
to <module> in the code.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-03-19 16:53:42 +02:00
Joshua Lock
8ee8e862af updater: remove magic number
Remove the magic number, a whence value of 2 for file.seek(), and instead
use the io.SEEK_END constant from the io module.

Signed-off-by: Joshua Lock <jlock@vmware.com>
2021-03-03 09:37:21 +00:00
Teodora Sechkova
93c6573008
Apply the new code style to fetcher docstrings
Ensure that the newly added files' docstrings adhere to the
recently adopted code style guideline (#1232).

Small code style improvements in comments and imports.

Signed-off-by: Teodora Sechkova <tsechkova@vmware.com>
2021-02-24 11:41:35 +02:00
Jussi Kukkonen
1677ce0bf8
Move fetcher components to make API boundary clearer
* Move FetcherInterface to tuf/client/ directory: This way everything
  inside that directory is clearly part of client API, and everything
  outside _may_ be more of an implementation detail (settings is still
  an unfortunate exception)
* Keep RequestsFetcher in tuf/ for same reasons: it's just the default
  implementation, not explicitly part of client API

An even clearer division would be if we moved all the client specific
implementation details (download.py, mirrors.py, requests_fetcher.py)
to tuf/client/_internal/ but that's a larger change...

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-02-24 11:41:34 +02:00
Jussi Kukkonen
e9b294b57c
Add an HTTP error for Fetcher interface
A custom error is required so that updater is able to special case
403 & 404 status codes.

Rewrite the test case a bit to be more readable.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2021-02-24 11:41:34 +02:00
Teodora Sechkova
33b89a8b99
Add fetcher as parameter to Updater class
Initialize Updater with an external implementation of
FetcherInterface. If not provided, tuf.fetcher.RequestsFetcher
is used.

Signed-off-by: Teodora Sechkova <tsechkova@vmware.com>
2021-02-23 17:58:40 +02:00
Joshua Lock
4bcd703462 client: update expiration check to match spec
The specification, as of 1.0.16, describes an update expiration check as:

> The expiration timestamp in the trusted $ROLE metadata file MUST be
  higher than the fixed update expiration time.

Having done some research into how other security providers are comparing
expiration equivalents (i.e. OpenSSL x509 certificate checking code, and
GnuPG expiration checks), and how other TUF implementations are performing
the same check (rust-tuf, go-tuf), we came to a consensus that the correct
way to implement expiration comparisons is:

    expiration <= now

Where:
  expiration: is the metadata's expiration datetime
  now: is the current system time, or the fixed notion of time in the
       detailed client workflow (introduced in 1.0.16 of the spec)

Fixes #1231

Signed-off-by: Joshua Lock <jlock@vmware.com>
2020-12-08 14:05:44 +00:00
Jussi Kukkonen
6101817b4c Updater: Close temp file in exception cases
If during updater.download_target() the download succeeds but a later
check fails (e.g. BadHashError), remember to close the tempfile.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2020-11-27 12:19:01 +02:00
lukpueh
e061bc6ebb
Merge pull request #1202 from joshuagl/joshuagl/updater-simplify
Simplify updater logic for downloading and verifying target files
2020-11-26 13:48:35 +01:00
Joshua Lock
372e2184e0 client: simplify loop exit logic
Simplify the loop exit logic in _get_target_file() to simply return a
verified file_object, once we have it, rather than breaking from the loop
and then returning the file_object.

This converts a use of a try/except/else to a try/except and is a little
easier to read.

Signed-off-by: Joshua Lock <jlock@vmware.com>
2020-11-26 10:01:14 +00:00
Joshua Lock
60dcb95656
Merge pull request #1219 from jku/avoid-reading-target-in-memory
Avoid reading target in memory
2020-11-25 12:07:19 +00:00
Joshua Lock
83ac7be525 client: new root sigs only counted once per keyid
When verifying newly downloaded root metadata with the keys listed in the
root metadata being verified, multiple signatures with the same keyid
should not be counted towards the threshold. A keyid should only count
once towards the threshold.

This fixes the _verify_root_self_signed() method introduced in PR #1101 to
ensure that keyids are only counted once when verifying a threshold of new
root signatures.

Signed-off-by: Joshua Lock <jlock@vmware.com>
2020-11-24 13:22:47 +00:00
Jussi Kukkonen
fcdae97b8a Updater: clean up _check_hashes() comments
Remove duplicate/obvious comments, tighten other comments and a logline

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2020-11-23 20:37:11 +02:00
Jussi Kukkonen
e86520a667 Updater: Avoid reading whole target file in memory
We don't want to read the whole file in memory as it can be huge. Use
digest_fileobject() instead: This way Securesystemslib will read the
file in chunks.

Securesystemslib already takes care of seeking to beginning of file.

Fixes #1215

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2020-11-23 20:37:11 +02:00
Joshua Lock
02416e3376 updater: more optimal file length checking
Rather than read to the end of the file in order to determin its size, use
the whence value of seek() to move the file object's position to the end
of the file, then the tell() method of the file object to read the current
position in bytes.

Co-authored-by: Jussi Kukkonen <jkukkonen@vmware.com>
Signed-off-by: Joshua Lock <jlock@vmware.com>
2020-11-11 15:53:07 +00:00
Joshua Lock
ad1335b6ed updater: simplify Updater.download_target() call stack
The call stack and code for download_target() is more complex than
required:
* download_target() : builds target destination filepath, gets length
  and hashes
* _get_target_file() : fixes filenames if consistent snapshots enabled,
  defines verification callback
* _get_file() : iterates mirrors, tries to download files, verifies them

Remove the verification callback and collapse the call stack by a single
level to make the code easier to follow.

Signed-off-by: Joshua Lock <jlock@vmware.com>
2020-11-09 15:55:27 +00:00
Joshua Lock
b3ada5bb0b updater: remove unused _soft_check_file_length
This internal method isn't used by any code other than tests.

Signed-off-by: Joshua Lock <jlock@vmware.com>
2020-11-09 15:55:27 +00:00
Jussi Kukkonen
e7ce873f12 updater: Add missing Exception documentation
Added ExpiredMetadataError to function documentation where it seems to
be missing.

Corrected the refresh() documentation: ExpiredMetadataError can only
happen when top level metadata does not need to be updated but is
expired. If the metadata gets updated and is expired, the result will
be a NoWorkingMirror with ExpiredMetadata inside it.

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2020-10-29 20:36:33 +02:00
Martin Vrachev
946d11bca4 Make confined_target_dirs optional field
The field confined_target_dirs from the MIRROR_SCHEMA  is
a list of strings. Those strings define the accessible target
paths for that mirror. For one target to be available for that mirror,
its path should have as a prefix at least one of the strings defined
in confined_target_dirs.

That's why when confined_target_dirs is a list with one element empty
string (e.g. ['']) this means all targets files on that mirror are
available and if confined_target_dirs is empty list (e.g. []) this
would be interpreted as none of the target files is available.

This is a confusing API that could easily lead to mistakes.
That's why it's better we promote to not set confined_target_dirs
at all if a user wants targets to be available.

Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
2020-10-16 15:35:24 +03:00
Joshua Lock
b57aa5857b
Merge pull request #1173 from jku/add-missing-local-repository-error
Add MissingLocalRepositoryError
2020-10-15 10:35:39 +01:00
Jussi Kukkonen
2f69986e2b Remove iso8601 dependency
Our 'expires' strings are constrained by the ISO8601_DATETIME_SCHEMA
which matches regex '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z'. This can be
parsed with just a datetime.strptime(): iso8601 module is not needed.

* Add formats.expiry_string_to_datetime() helper function
* Modify the 3 locations that used iso8601 and the api/metadata.py usage
  of datetime.strptime()
* Remove related unnecessary logger setup
* Add the missing exception documentation to relevant functions (in many
  cases the exception is rather unlikely as the schema has been verified
  many times before this though...)

Fixes #1065

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2020-10-13 20:06:14 +03:00
Jussi Kukkonen
7d73958a2a Add MissingLocalRepositoryError
This allows clients to separate
a) missing local repository and
b) error while loading local repository

This is fully backwards-compliant: MissingLocalRepositoryError derives
from RepositoryError and every situation that now results in
MissingLocalRepositoryError used to result in a RepositoryError.

Fixes #1063

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2020-10-12 15:23:15 +03:00
Joshua Lock
505f3545d5
Merge pull request #1145 from jku/silence-errors-to-be-raised
Silence errors to be raised
2020-09-22 13:42:27 +01:00
Jussi Kukkonen
b5a3c705db Avoid leaving unclosed file objects
* move code to only create objects after potential raises
* Use 'with' when possible
* close manually if those did not help

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2020-09-22 14:22:46 +03:00
Jussi Kukkonen
69a45946e6 Updater: Don't log errors that will be raised
Don't use log level ERROR when we are only raising an exception for user
to handle (the issue is not a bug in TUF: TUF is working as expected in
all of these cases). Don't log at all if all the info is included in the
raised exception.

Also definitely don't log at error level when we don't know if this will
even be raised (e.g. a 404 is expected at least once on every
Updater.refresh()).

Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
2020-09-15 19:49:04 +03:00
Joshua Lock
7c18cbbbfb Remove uses of keyid_hash_algorithms
PR #1014 removed uses of keyid_hash_algorithms in favour of using the calculated
keyid values from the metadata. A few instances of this removal were
unintentionally reintroduced in PR #1016, when changing to explicitly passing
a list of hash algorithms rather than changing securesystemslib settings
values.

This change removes uneccessary uses of keyid_hash_algorithms.

Signed-off-by: Joshua Lock <jlock@vmware.com>
2020-09-09 10:51:46 +01:00