1
0
mirror of https://github.com/moparisthebest/wget synced 2024-07-03 16:38:41 -04:00

Support at most one file signature. Adapt comments to libmetalink 0.13.

* src/metalink.c (retrieve_from_metalink): Add comment about new
libmetalink version. Do not iterate over signatures - support just one.
This commit is contained in:
Hubert Tarasiuk 2015-07-02 00:16:12 +02:00 committed by Giuseppe Scrivano
parent 225a87d4a2
commit 97389a7497

View File

@ -224,15 +224,21 @@ retrieve_from_metalink (const metalink_t* metalink)
sig_status = 0; /* Not verified. */ sig_status = 0; /* Not verified. */
#ifdef HAVE_GPGME #ifdef HAVE_GPGME
/* Check the crypto signature. */ /* Check the crypto signature.
Note that the signtures from Metalink in XML will not be
parsed when using libmetalink version older than 0.1.3.
Metalink-over-HTTP is not affected by this problem. */
if (mfile->signature) if (mfile->signature)
{ {
metalink_signature_t *msig; metalink_signature_t *msig = mfile->signature;
gpgme_error_t gpgerr; gpgme_error_t gpgerr;
gpgme_ctx_t gpgctx; gpgme_ctx_t gpgctx;
gpgme_data_t gpgsigdata, gpgdata; gpgme_data_t gpgsigdata, gpgdata;
gpgme_verify_result_t gpgres; gpgme_verify_result_t gpgres;
int fd; gpgme_signature_t gpgsig;
gpgme_protocol_t gpgprot = GPGME_PROTOCOL_UNKNOWN;
int fd = -1;
/* Initialize the library - as name suggests. */ /* Initialize the library - as name suggests. */
gpgme_check_version (NULL); gpgme_check_version (NULL);
@ -254,7 +260,7 @@ retrieve_from_metalink (const metalink_t* metalink)
logprintf (LOG_NOTQUIET, logprintf (LOG_NOTQUIET,
"GPGME data_new_from_fd: %s\n", "GPGME data_new_from_fd: %s\n",
gpgme_strerror (gpgerr)); gpgme_strerror (gpgerr));
goto gpg_cleanup_fd; goto gpg_skip_verification;
} }
/* Prepare new GPGME context. */ /* Prepare new GPGME context. */
@ -264,127 +270,122 @@ retrieve_from_metalink (const metalink_t* metalink)
logprintf (LOG_NOTQUIET, logprintf (LOG_NOTQUIET,
"GPGME new: %s\n", "GPGME new: %s\n",
gpgme_strerror (gpgerr)); gpgme_strerror (gpgerr));
goto gpg_cleanup_data; gpgme_data_release (gpgdata);
goto gpg_skip_verification;
} }
/* Note that this will only work for Metalink-over-HTTP DEBUGP (("Veryfying signature %s:\n%s\n",
requests (that we parse manually) due to a bug in quote (msig->mediatype),
Libmetalink. Another problem with Libmetalink is that msig->signature));
it supports at most one signature per file. The below
line should be modified after Libmetalink resolves these /* Check signature type. */
issues. */ if (!strcmp (msig->mediatype, "application/pgp-signature"))
for (msig = mfile->signature; msig == mfile->signature; msig++) gpgprot = GPGME_PROTOCOL_OpenPGP;
else /* Unsupported signature type. */
{ {
gpgme_signature_t gpgsig; gpgme_release (gpgctx);
gpgme_protocol_t gpgprot = GPGME_PROTOCOL_UNKNOWN; gpgme_data_release (gpgdata);
goto gpg_skip_verification;
}
DEBUGP (("Veryfying signature %s:\n%s\n", gpgerr = gpgme_set_protocol (gpgctx, gpgprot);
quote (msig->mediatype), if (gpgerr != GPG_ERR_NO_ERROR)
msig->signature)); {
logprintf (LOG_NOTQUIET,
"GPGME set_protocol: %s\n",
gpgme_strerror (gpgerr));
gpgme_release (gpgctx);
gpgme_data_release (gpgdata);
goto gpg_skip_verification;
}
/* Check signature type. */ /* Load the signature. */
if (!strcmp (msig->mediatype, "application/pgp-signature")) gpgerr = gpgme_data_new_from_mem (&gpgsigdata,
gpgprot = GPGME_PROTOCOL_OpenPGP; msig->signature,
else /* Unsupported signature type. */ strlen (msig->signature),
continue; 0);
if (gpgerr != GPG_ERR_NO_ERROR)
{
logprintf (LOG_NOTQUIET,
_("GPGME data_new_from_mem: %s\n"),
gpgme_strerror (gpgerr));
gpgme_release (gpgctx);
gpgme_data_release (gpgdata);
goto gpg_skip_verification;
}
gpgerr = gpgme_set_protocol (gpgctx, gpgprot); /* Verify the signature. */
if (gpgerr != GPG_ERR_NO_ERROR) gpgerr = gpgme_op_verify (gpgctx, gpgsigdata, gpgdata, NULL);
if (gpgerr != GPG_ERR_NO_ERROR)
{
logprintf (LOG_NOTQUIET,
_("GPGME op_verify: %s\n"),
gpgme_strerror (gpgerr));
gpgme_data_release (gpgsigdata);
gpgme_release (gpgctx);
gpgme_data_release (gpgdata);
goto gpg_skip_verification;
}
/* Check the results. */
gpgres = gpgme_op_verify_result (gpgctx);
if (!gpgres)
{
logputs (LOG_NOTQUIET,
_("GPGME op_verify_result: NULL\n"));
gpgme_data_release (gpgsigdata);
gpgme_release (gpgctx);
gpgme_data_release (gpgdata);
goto gpg_skip_verification;
}
/* The list is null-terminated. */
for (gpgsig = gpgres->signatures; gpgsig; gpgsig = gpgsig->next)
{
DEBUGP (("Checking signature 0x%p\n",
(void *) gpgsig));
DEBUGP (("Summary=0x%x Status=0x%x\n",
gpgsig->summary, gpgsig->status & 0xFFFF));
if (gpgsig->summary
& (GPGME_SIGSUM_VALID | GPGME_SIGSUM_GREEN))
{ {
logprintf (LOG_NOTQUIET, logputs (LOG_VERBOSE,
"GPGME set_protocol: %s\n", _("Signature validation suceeded.\n"));
gpgme_strerror (gpgerr)); sig_status = 1;
continue; break;
} }
/* Load the signature. */ if (gpgsig->summary & GPGME_SIGSUM_RED)
gpgerr = gpgme_data_new_from_mem (&gpgsigdata,
msig->signature,
strlen (msig->signature),
0);
if (gpgerr != GPG_ERR_NO_ERROR)
{
logprintf (LOG_NOTQUIET,
_("GPGME data_new_from_mem: %s\n"),
gpgme_strerror (gpgerr));
continue;
}
/* Verify the signature. */
gpgerr = gpgme_op_verify (gpgctx, gpgsigdata, gpgdata, NULL);
if (gpgerr != GPG_ERR_NO_ERROR)
{
logprintf (LOG_NOTQUIET,
_("GPGME op_verify: %s\n"),
gpgme_strerror (gpgerr));
gpgme_data_release (gpgsigdata);
continue;
}
/* Check the results. */
gpgres = gpgme_op_verify_result (gpgctx);
if (!gpgres)
{ {
logputs (LOG_NOTQUIET, logputs (LOG_NOTQUIET,
_("GPGME op_verify_result: NULL\n")); _("Invalid signature. Rejecting resource.\n"));
gpgme_data_release (gpgsigdata); sig_status = -1;
continue; break;
} }
/* The list is null-terminated. */ if (gpgsig->summary == 0
for (gpgsig = gpgres->signatures; gpgsig; gpgsig = gpgsig->next) && (gpgsig->status & 0xFFFF) == GPG_ERR_NO_ERROR)
{ {
DEBUGP (("Checking signature 0x%p\n", logputs (LOG_VERBOSE,
(void *) gpgsig)); _("Data matches signature, but signature "
DEBUGP (("Summary=0x%x Status=0x%x\n", "is not trusted.\n"));
gpgsig->summary, gpgsig->status & 0xFFFF));
if (gpgsig->summary
& (GPGME_SIGSUM_VALID | GPGME_SIGSUM_GREEN))
{
logputs (LOG_VERBOSE,
_("Signature validation suceeded.\n"));
sig_status = 1;
break;
}
if (gpgsig->summary & GPGME_SIGSUM_RED)
{
logputs (LOG_NOTQUIET,
_("Invalid signature. Rejecting resource.\n"));
sig_status = -1;
break;
}
if (gpgsig->summary == 0
&& (gpgsig->status & 0xFFFF) == GPG_ERR_NO_ERROR)
{
logputs (LOG_VERBOSE,
_("Data matches signature, but signature "
"is not trusted.\n"));
}
if ((gpgsig->status & 0xFFFF) != GPG_ERR_NO_ERROR)
{
logprintf (LOG_NOTQUIET,
"GPGME: %s\n",
gpgme_strerror (gpgsig->status & 0xFFFF));
}
} }
gpgme_data_release (gpgsigdata); if ((gpgsig->status & 0xFFFF) != GPG_ERR_NO_ERROR)
{
if (sig_status != 0) logprintf (LOG_NOTQUIET,
break; "GPGME: %s\n",
} /* Iterate over signatures. */ gpgme_strerror (gpgsig->status & 0xFFFF));
}
}
gpgme_data_release (gpgsigdata);
gpgme_release (gpgctx); gpgme_release (gpgctx);
gpg_cleanup_data:
gpgme_data_release (gpgdata); gpgme_data_release (gpgdata);
gpg_cleanup_fd:
close (fd);
} /* endif (mfile->signature) */
gpg_skip_verification: gpg_skip_verification:
if (fd != -1)
close (fd);
} /* endif (mfile->signature) */
#endif #endif
/* Stop if file was downloaded with success. */ /* Stop if file was downloaded with success. */
if (sig_status >= 0) if (sig_status >= 0)