sign-pull: improve error handling
Use glnx_* functions in signature related pull code for clear error handling. Signed-off-by: Denis Pynkin <denis.pynkin@collabora.com>
This commit is contained in:
parent
584ad40549
commit
cce3864160
|
|
@ -1470,7 +1470,7 @@ process_verify_result (OtPullData *pull_data,
|
||||||
}
|
}
|
||||||
#endif /* OSTREE_DISABLE_GPGME */
|
#endif /* OSTREE_DISABLE_GPGME */
|
||||||
|
|
||||||
/* _remote_load_public_keys:
|
/* _load_public_keys:
|
||||||
*
|
*
|
||||||
* Load public keys according remote's configuration:
|
* Load public keys according remote's configuration:
|
||||||
* inlined key passed via config option `verification-key` or
|
* inlined key passed via config option `verification-key` or
|
||||||
|
|
@ -1493,6 +1493,9 @@ _load_public_keys (OstreeSign *sign,
|
||||||
g_autofree gchar *pk_file = NULL;
|
g_autofree gchar *pk_file = NULL;
|
||||||
gboolean loaded_from_file = TRUE;
|
gboolean loaded_from_file = TRUE;
|
||||||
gboolean loaded_inlined = TRUE;
|
gboolean loaded_inlined = TRUE;
|
||||||
|
g_autoptr (GError) verification_error = NULL;
|
||||||
|
|
||||||
|
glnx_throw (&verification_error, "no public keys loaded");
|
||||||
|
|
||||||
ostree_repo_get_remote_option (repo,
|
ostree_repo_get_remote_option (repo,
|
||||||
remote_name,
|
remote_name,
|
||||||
|
|
@ -1521,6 +1524,7 @@ _load_public_keys (OstreeSign *sign,
|
||||||
|
|
||||||
if (pk_file != NULL)
|
if (pk_file != NULL)
|
||||||
{
|
{
|
||||||
|
g_autoptr (GError) local_error = NULL;
|
||||||
g_autoptr (GVariantBuilder) builder = NULL;
|
g_autoptr (GVariantBuilder) builder = NULL;
|
||||||
g_autoptr (GVariant) options = NULL;
|
g_autoptr (GVariant) options = NULL;
|
||||||
|
|
||||||
|
|
@ -1528,11 +1532,15 @@ _load_public_keys (OstreeSign *sign,
|
||||||
g_variant_builder_add (builder, "{sv}", "filename", g_variant_new_string (pk_file));
|
g_variant_builder_add (builder, "{sv}", "filename", g_variant_new_string (pk_file));
|
||||||
options = g_variant_builder_end (builder);
|
options = g_variant_builder_end (builder);
|
||||||
|
|
||||||
if (ostree_sign_load_pk (sign, options, error))
|
if (ostree_sign_load_pk (sign, options, &local_error))
|
||||||
loaded_from_file = TRUE;
|
loaded_from_file = TRUE;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
g_debug("Unable to load public keys for '%s' from file '%s': %s",
|
g_debug("Unable to load public keys for '%s' from file '%s': %s",
|
||||||
ostree_sign_get_name(sign), pk_file, (*error)->message);
|
ostree_sign_get_name(sign), pk_file, local_error->message);
|
||||||
|
/* Save error message for better reason detection later if needed */
|
||||||
|
glnx_prefix_error (&verification_error, "%s", local_error->message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pk_ascii != NULL)
|
if (pk_ascii != NULL)
|
||||||
|
|
@ -1549,24 +1557,18 @@ _load_public_keys (OstreeSign *sign,
|
||||||
if (!loaded_inlined)
|
if (!loaded_inlined)
|
||||||
{
|
{
|
||||||
g_debug("Unable to load public key '%s' for '%s': %s",
|
g_debug("Unable to load public key '%s' for '%s': %s",
|
||||||
pk_ascii, ostree_sign_get_name(sign), local_error->message);
|
pk_ascii, ostree_sign_get_name (sign), local_error->message);
|
||||||
|
|
||||||
/* Save error message for better reason detection later if needed */
|
/* Save error message for better reason detection later if needed */
|
||||||
if (*error == NULL)
|
glnx_prefix_error (&verification_error, "%s", local_error->message);
|
||||||
g_propagate_error (error, g_steal_pointer (&local_error));
|
|
||||||
else
|
|
||||||
g_prefix_error (error, "%s; ", local_error->message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return true if able to load from any source */
|
/* Return true if able to load from any source */
|
||||||
if (loaded_from_file || loaded_inlined)
|
if (loaded_from_file || loaded_inlined)
|
||||||
{
|
return TRUE;
|
||||||
g_clear_error (error);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
return glnx_throw (error, "%s", verification_error->message);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
@ -1578,6 +1580,10 @@ _ostree_repo_sign_verify (OstreeRepo *repo,
|
||||||
{
|
{
|
||||||
/* list all signature types in detached metadata and check if signed by any? */
|
/* list all signature types in detached metadata and check if signed by any? */
|
||||||
g_auto (GStrv) names = ostree_sign_list_names();
|
g_auto (GStrv) names = ostree_sign_list_names();
|
||||||
|
g_autoptr (GError) verification_error = NULL;
|
||||||
|
|
||||||
|
glnx_throw (&verification_error, "signed with unknown key");
|
||||||
|
|
||||||
for (char **iter=names; iter && *iter; iter++)
|
for (char **iter=names; iter && *iter; iter++)
|
||||||
{
|
{
|
||||||
g_autoptr (OstreeSign) sign = NULL;
|
g_autoptr (OstreeSign) sign = NULL;
|
||||||
|
|
@ -1609,26 +1615,16 @@ _ostree_repo_sign_verify (OstreeRepo *repo,
|
||||||
signed_data,
|
signed_data,
|
||||||
signatures,
|
signatures,
|
||||||
&local_error))
|
&local_error))
|
||||||
{
|
return TRUE;
|
||||||
g_clear_error (error);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save error message for better reason detection later if needed */
|
/* Save error message for better reason detection later if needed */
|
||||||
if (*error == NULL)
|
glnx_prefix_error (&verification_error, "%s", local_error->message);
|
||||||
g_propagate_error (error, g_steal_pointer (&local_error));
|
|
||||||
else
|
|
||||||
g_prefix_error (error, "%s; ", local_error->message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In case if there were no signatures of known type
|
/* In case if there were no signatures of known type
|
||||||
* or metadata contains invalid data */
|
* or metadata contains invalid data */
|
||||||
if (*error == NULL)
|
return glnx_throw (error, "%s", verification_error->message);
|
||||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
|
||||||
"Metadata doesn't signed with supported type");
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
@ -1672,17 +1668,10 @@ ostree_verify_unwritten_commit (OtPullData *pull_data,
|
||||||
{
|
{
|
||||||
/* Nothing to check if detached metadata is absent */
|
/* Nothing to check if detached metadata is absent */
|
||||||
if (detached_metadata == NULL)
|
if (detached_metadata == NULL)
|
||||||
{
|
return glnx_throw (error, "Can't verify commit without detached metadata");
|
||||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
|
||||||
"Can't verify commit without detached metadata");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_ostree_repo_sign_verify (pull_data->repo, pull_data->remote_name, signed_data, detached_metadata, error))
|
if (!_ostree_repo_sign_verify (pull_data->repo, pull_data->remote_name, signed_data, detached_metadata, error))
|
||||||
{
|
return glnx_prefix_error (error, "Can't verify commit");
|
||||||
g_prefix_error (error, "Can't verify commit");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mark the commit as verified to avoid double verification
|
/* Mark the commit as verified to avoid double verification
|
||||||
* see process_verify_result () for rationale */
|
* see process_verify_result () for rationale */
|
||||||
|
|
@ -2022,6 +2011,8 @@ scan_commit_object (OtPullData *pull_data,
|
||||||
!g_hash_table_contains (pull_data->verified_commits, checksum))
|
!g_hash_table_contains (pull_data->verified_commits, checksum))
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
|
g_autoptr (GError) verification_error = NULL;
|
||||||
|
|
||||||
/* list all signature types in detached metadata and check if signed by any? */
|
/* list all signature types in detached metadata and check if signed by any? */
|
||||||
g_auto (GStrv) names = ostree_sign_list_names();
|
g_auto (GStrv) names = ostree_sign_list_names();
|
||||||
for (char **iter=names; !ret && iter && *iter; iter++)
|
for (char **iter=names; !ret && iter && *iter; iter++)
|
||||||
|
|
@ -2042,29 +2033,16 @@ scan_commit_object (OtPullData *pull_data,
|
||||||
checksum,
|
checksum,
|
||||||
cancellable,
|
cancellable,
|
||||||
&local_error))
|
&local_error))
|
||||||
{
|
ret = TRUE;
|
||||||
ret = TRUE;
|
|
||||||
g_clear_error (error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save error message for better reason detection later if needed */
|
/* Save error message for better reason detection later if needed */
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
glnx_prefix_error (&verification_error, "%s", local_error->message);
|
||||||
if (*error == NULL)
|
|
||||||
g_propagate_error (error, g_steal_pointer (&local_error));
|
|
||||||
else
|
|
||||||
g_prefix_error (error, "%s; ", local_error->message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
return glnx_throw (error, "Can't verify commit %s: %s", checksum, verification_error->message);
|
||||||
g_prefix_error (error, "Can't verify commit %s: ", checksum);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
/* Clear non-fatal error */
|
|
||||||
g_clear_error (error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we found a legacy transaction flag, assume we have to scan.
|
/* If we found a legacy transaction flag, assume we have to scan.
|
||||||
|
|
@ -4444,8 +4422,6 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
||||||
|
|
||||||
if (!_ostree_repo_sign_verify (pull_data->repo, pull_data->remote_name, bytes_summary, signatures, &temp_error))
|
if (!_ostree_repo_sign_verify (pull_data->repo, pull_data->remote_name, bytes_summary, signatures, &temp_error))
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
|
||||||
|
|
||||||
if (summary_from_cache)
|
if (summary_from_cache)
|
||||||
{
|
{
|
||||||
/* The cached summary doesn't match, fetch a new one and verify again */
|
/* The cached summary doesn't match, fetch a new one and verify again */
|
||||||
|
|
@ -4473,16 +4449,12 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (_ostree_repo_sign_verify (pull_data->repo, pull_data->remote_name, bytes_summary, signatures, error))
|
if (!_ostree_repo_sign_verify (pull_data->repo, pull_data->remote_name, bytes_summary, signatures, error))
|
||||||
ret = TRUE;
|
goto out;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
g_propagate_error (error, g_steal_pointer (&temp_error));
|
|
||||||
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
{
|
{
|
||||||
g_prefix_error (error, "Can't verify summary: ");
|
g_propagate_error (error, g_steal_pointer (&temp_error));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,7 @@ do
|
||||||
if ${OSTREE} --repo=repo pull origin main 2>err.txt; then
|
if ${OSTREE} --repo=repo pull origin main 2>err.txt; then
|
||||||
assert_not_reached "Successful pull with invalid ${engine} signature"
|
assert_not_reached "Successful pull with invalid ${engine} signature"
|
||||||
fi
|
fi
|
||||||
assert_file_has_content err.txt "Can't verify summary"
|
assert_file_has_content err.txt "signed with unknown key"
|
||||||
mv ${test_tmpdir}/ostree-srv/gnomerepo/summary.sig{.good,}
|
mv ${test_tmpdir}/ostree-srv/gnomerepo/summary.sig{.good,}
|
||||||
echo "ok ${engine} pull with invalid ${engine} summary signature fails"
|
echo "ok ${engine} pull with invalid ${engine} summary signature fails"
|
||||||
|
|
||||||
|
|
@ -223,7 +223,7 @@ cp ${test_tmpdir}/ostree-srv/gnomerepo/summary.sig{.2,}
|
||||||
if ${OSTREE} --repo=repo pull origin main 2>err.txt; then
|
if ${OSTREE} --repo=repo pull origin main 2>err.txt; then
|
||||||
assert_not_reached "Successful pull with old summary"
|
assert_not_reached "Successful pull with old summary"
|
||||||
fi
|
fi
|
||||||
assert_file_has_content err.txt "Can't verify summary"
|
assert_file_has_content err.txt "signed with unknown key"
|
||||||
assert_has_file repo/tmp/cache/summaries/origin
|
assert_has_file repo/tmp/cache/summaries/origin
|
||||||
assert_has_file repo/tmp/cache/summaries/origin.sig
|
assert_has_file repo/tmp/cache/summaries/origin.sig
|
||||||
cmp repo/tmp/cache/summaries/origin ${test_tmpdir}/ostree-srv/gnomerepo/summary.1 >&2
|
cmp repo/tmp/cache/summaries/origin ${test_tmpdir}/ostree-srv/gnomerepo/summary.1 >&2
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue