Skip to content
Snippets Groups Projects
Commit a4dad66e authored by Lucas Hedding's avatar Lucas Hedding Committed by Lucas Hedding
Browse files

Issue #3087498 by heddn: Validate downloaded update archives

parent 7df0066d
No related branches found
No related tags found
No related merge requests found
......@@ -8,6 +8,9 @@ use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\File\Exception\FileException;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Url;
use Drupal\Signify\ChecksumList;
use Drupal\Signify\FailedCheckumFilter;
use Drupal\Signify\Verifier;
use DrupalFinder\DrupalFinder;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\RequestException;
......@@ -209,6 +212,7 @@ class InPlaceUpdate implements UpdateInterface {
*/
protected function processUpdate(ArchiverInterface $archive, $project_root) {
$archive->extract($this->getTempDirectory());
$this->validateArchive($this->getTempDirectory());
foreach ($this->getFilesList($this->getTempDirectory()) as $file) {
$file_real_path = $this->getFileRealPath($file);
$file_path = substr($file_real_path, strlen($this->getTempDirectory() . self::ARCHIVE_DIRECTORY));
......@@ -236,6 +240,29 @@ class InPlaceUpdate implements UpdateInterface {
return TRUE;
}
/**
* Validate the downloaded archive.
*
* @param string $directory
* The location of the downloaded archive.
*/
protected function validateArchive($directory) {
$csig_file = $directory . DIRECTORY_SEPARATOR . 'checksumlist.csig';
if (!file_exists($csig_file)) {
throw new \RuntimeException('The CSIG file does not exist in the archive.');
}
$contents = file_get_contents($csig_file);
$module_path = drupal_get_path('module', 'automatic_updates');
$key = file_get_contents($module_path . '/artifacts/keys/root.pub');
$verifier = new Verifier($key);
$files = $verifier->verifyCsigMessage($contents);
$checksums = new ChecksumList($files, TRUE);
$failed_checksums = new FailedCheckumFilter($checksums, $directory);
if (iterator_count($failed_checksums)) {
throw new \RuntimeException('The downloaded files did not match what was expected.');
}
}
/**
* Backup before an update.
*
......
......@@ -105,7 +105,7 @@ class ModifiedFiles implements ModifiedFilesInterface {
$module_path = drupal_get_path('module', 'automatic_updates');
$key = file_get_contents($module_path . '/artifacts/keys/root.pub');
$verifier = new Verifier($key);
$files = $verifier->verifyCsigMessage($contents, new \DateTime('2020-01-01', new \DateTimeZone('UTC')));
$files = $verifier->verifyCsigMessage($contents);
$checksums = new ChecksumList($files, TRUE);
foreach (new FailedCheckumFilter($checksums, $directory_root) as $failed_checksum) {
$file_path = implode(DIRECTORY_SEPARATOR, array_filter([
......
......@@ -156,7 +156,7 @@ class InPlaceUpdateTest extends QuickStartTestBase {
$this->assertDrupalVisit();
// Update the contrib project.
$this->visit("/automatic_updates/in-place-update/$project/$project_type/$from_version/$to_version");
$this->visit("/test_automatic_updates/in-place-update/$project/$project_type/$from_version/$to_version");
$this->assertDrupalVisit();
// Assert that the update worked.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment