|
1 | 1 | <?php
|
2 | 2 | /*
|
3 |
| - * Copyright (C) 2024 Xibo Signage Ltd |
| 3 | + * Copyright (C) 2025 Xibo Signage Ltd |
4 | 4 | *
|
5 | 5 | * Xibo - Digital Signage - https://xibosignage.com
|
6 | 6 | *
|
|
32 | 32 | use Xibo\Service\LogServiceInterface;
|
33 | 33 | use Xibo\Storage\StorageServiceInterface;
|
34 | 34 | use Xibo\Support\Exception\DuplicateEntityException;
|
| 35 | +use Xibo\Support\Exception\GeneralException; |
35 | 36 | use Xibo\Support\Exception\InvalidArgumentException;
|
| 37 | +use Xibo\Support\Exception\NotFoundException; |
36 | 38 |
|
37 | 39 | /**
|
38 | 40 | * Class PlayerVersion
|
@@ -223,10 +225,53 @@ public function unpack(string $libraryFolder): static
|
223 | 225 | if ($this->type === 'chromeOS') {
|
224 | 226 | $this->getLog()->debug('add: handling chromeOS upload');
|
225 | 227 |
|
226 |
| - // TODO: check the signature of the file to make sure it comes from a verified source. |
| 228 | + $fullFileName = $libraryFolder . 'playersoftware/' . $this->fileName; |
| 229 | + |
| 230 | + // Check the signature of the file to make sure it comes from a verified source. |
| 231 | + try { |
| 232 | + $this->getLog()->debug('unpack: loading gnupg to verify the signature'); |
| 233 | + |
| 234 | + $gpg = new \gnupg(); |
| 235 | + $gpg->seterrormode(\gnupg::ERROR_EXCEPTION); |
| 236 | + $info = $gpg->verify( |
| 237 | + file_get_contents($fullFileName), |
| 238 | + false, |
| 239 | + ); |
| 240 | + |
| 241 | + if ($info === false |
| 242 | + || $info[0]['fingerprint'] !== '10415C506BE63E70BAF1D58BC1EF165A0F880F75' |
| 243 | + || $info[0]['status'] !== 0 |
| 244 | + || $info[0]['summary'] !== 0 |
| 245 | + ) { |
| 246 | + $this->getLog()->error('unpack: unable to verify GPG. file = ' . $this->fileName); |
| 247 | + throw new GeneralException(); |
| 248 | + } |
| 249 | + |
| 250 | + $this->getLog()->debug('unpack: signature verified'); |
| 251 | + |
| 252 | + // Signature verified, move the file, so we can decrypt it. |
| 253 | + rename($fullFileName, $libraryFolder . 'playersoftware/' . $this->versionId . '.gpg'); |
| 254 | + |
| 255 | + $this->getLog()->debug('unpack: using the shell to decrypt the file'); |
| 256 | + |
| 257 | + // Go to the shell to decrypt it. |
| 258 | + shell_exec('gpg --decrypt --output ' . $libraryFolder . 'playersoftware/' . $this->versionId |
| 259 | + . ' ' . $libraryFolder . 'playersoftware/' . $this->versionId . '.gpg'); |
| 260 | + |
| 261 | + // Was this successful? |
| 262 | + if (!file_exists($libraryFolder . 'playersoftware/' . $this->versionId)) { |
| 263 | + throw new NotFoundException('Not found after decryption'); |
| 264 | + } |
| 265 | + |
| 266 | + // Rename the GPG file back to its original name. |
| 267 | + rename($libraryFolder . 'playersoftware/' . $this->versionId . '.gpg', $fullFileName); |
| 268 | + } catch (\Exception $e) { |
| 269 | + $this->getLog()->error('unpack: ' . $e->getMessage()); |
| 270 | + throw new InvalidArgumentException(__('Package file unsupported or invalid')); |
| 271 | + } |
227 | 272 |
|
228 | 273 | $zip = new \ZipArchive();
|
229 |
| - if (!$zip->open($libraryFolder . 'playersoftware/' . $this->fileName)) { |
| 274 | + if (!$zip->open($libraryFolder . 'playersoftware/' . $this->versionId)) { |
230 | 275 | throw new InvalidArgumentException(__('Unable to open ZIP'));
|
231 | 276 | }
|
232 | 277 |
|
@@ -273,6 +318,9 @@ public function unpack(string $libraryFolder): static
|
273 | 318 | $manifest = Str::replace('assets/icons/192x192.png', $this->config->uri('img/192x192.png'), $manifest);
|
274 | 319 |
|
275 | 320 | file_put_contents($folder . '/manifest.json', $manifest);
|
| 321 | + |
| 322 | + // Unlink our decrypted file |
| 323 | + unlink($libraryFolder . 'playersoftware/' . $this->versionId); |
276 | 324 | }
|
277 | 325 |
|
278 | 326 | return $this;
|
|
0 commit comments