function download() { $url = $this->getDownloadURL(); $errs = new \PEAR2\MultiErrors(); $certdownloaded = false; if (extension_loaded('openssl')) { // try to download openssl x509 signature certificate for our release try { $cert = \PEAR2\Pyrus\Main::download($url . '.pem'); $cert = $cert->body; $certdownloaded = true; } catch (\PEAR2\Pyrus\HTTPException $e) { // file does not exist, ignore } if ($certdownloaded) { $info = openssl_x509_parse($cert); if (!$info) { throw new \PEAR2\Pyrus\Package\Exception('Invalid abstract package ' . $this->channel . '/' . $this->name . ' - releasing maintainer\'s certificate is not a certificate'); } if (true !== openssl_x509_checkpurpose($cert, X509_PURPOSE_SSL_SERVER, self::authorities())) { throw new \PEAR2\Pyrus\Package\Exception('Invalid abstract package ' . $this->channel . '/' . $this->name . ' - releasing maintainer\'s certificate is invalid'); } // now verify that this cert is in fact the releasing maintainer's certificate // by verifying that alternate name is the releaser's email address if (!isset($info['subject']) || !isset($info['subject']['emailAddress'])) { throw new \PEAR2\Pyrus\Package\Exception('Invalid abstract package ' . $this->channel . '/' . $this->name . ' - releasing maintainer\'s certificate does not contain' . ' an alternate name corresponding to the releaser\'s email address'); } // retrieve releaser's email address if ($info['subject']['emailAddress'] != $this->maintainer[$this->remoteAbridgedInfo['m']]->email) { throw new \PEAR2\Pyrus\Package\Exception('Invalid abstract package ' . $this->channel . '/' . $this->name . ' - releasing maintainer\'s certificate ' . 'alternate name does not match the releaser\'s email address ' . $this->maintainer[$this->remoteAbridgedInfo['m']]->email); } $key = openssl_pkey_get_public($cert); $key = openssl_pkey_get_details($key); $key = $key['key']; } } // first try to download .phar, then .tgz, then .tar, then .zip // if a public key was downloaded, save it where ext/phar will // look to validate the openssl signature foreach (array('.phar', '.tgz', '.tar') as $ext) { try { if ($certdownloaded) { if (!file_exists(Config::current()->download_dir)) { mkdir(Config::current()->download_dir, 0755, true); } file_put_contents($pubkey = Config::current()->download_dir . DIRECTORY_SEPARATOR . basename($url) . $ext . '.pubkey', $key); } $ret = new \PEAR2\Pyrus\Package\Remote($url . $ext); if ($certdownloaded) { if ($ext == '.tar' || $ext == '.tgz') { if (phpversion() == '5.3.0') { Logger::log(0, 'WARNING: ' . $url . $ext . ' may not be installable ' . 'with PHP version 5.3.0, the PHP extension phar ' . 'has a bug verifying openssl signatures for ' . 'tar and tgz files. Either upgrade to PHP 5.3.1 ' . 'or install the .zip version'); } } } return $ret; } catch (\PEAR2\Pyrus\HTTPException $e) { if ($certdownloaded && file_exists($pubkey)) { unlink($pubkey); } $errs->E_ERROR[] = $e; } catch (\Exception $e) { if ($certdownloaded && file_exists($pubkey)) { unlink($pubkey); } $errs->E_ERROR[] = $e; throw new \PEAR2\Pyrus\Package\Exception('Invalid abstract package ' . $this->channel . '/' . $this->name, $errs); } } try { // phar does not support signatures for zip archives $ret = new \PEAR2\Pyrus\Package\Remote($url . '.zip'); return $ret; } catch (\PEAR2\Pyrus\HTTPException $e) { $errs->E_ERROR[] = $e; throw new \PEAR2\Pyrus\Package\Exception('Could not download abstract package ' . $this->channel . '/' . $this->name, $errs); } catch (\Exception $e) { $errs->E_ERROR[] = $e; throw new \PEAR2\Pyrus\Package\Exception('Invalid abstract package ' . $this->channel . '/' . $this->name, $errs); } }
/** * remotely connect to a channel server and grab the channel information, * then add it to the current pyrus managed repo * * @param array $args $args[0] should be the channel name, eg:pear.unl.edu */ function channelDiscover($args) { // try secure first $chan = 'https://' . $args['channel'] . '/channel.xml'; try { $response = \PEAR2\Pyrus\Main::download($chan); if ($response->code != 200) { throw new \PEAR2\Pyrus\Exception('Download of channel.xml failed'); } } catch (\Exception $e) { try { $chan = 'http://' . $args['channel'] . '/channel.xml'; $response = \PEAR2\Pyrus\Main::download($chan); if ($response->code != 200) { throw new \PEAR2\Pyrus\Exception('Download of channel.xml failed'); } } catch (\Exception $e) { // failed, re-throw original error echo "Discovery of channel ", $args['channel'], " failed: ", $e->getMessage(), "\n"; return; } } $chan = new \PEAR2\Pyrus\Channel(new \PEAR2\Pyrus\ChannelFile($response->body, true)); \PEAR2\Pyrus\Config::current()->channelregistry->add($chan); echo "Discovery of channel ", $chan->name, " successful\n"; }