Example #1
0
 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);
     }
 }
Example #2
0
    /**
     * 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";
    }