]> granicus.if.org Git - php/commitdiff
[DOC] implement full signature support for tar-based archives. By default, data...
authorGreg Beaver <cellog@php.net>
Fri, 13 Jun 2008 22:07:44 +0000 (22:07 +0000)
committerGreg Beaver <cellog@php.net>
Fri, 13 Jun 2008 22:07:44 +0000 (22:07 +0000)
not have a signature, but can have one set via setSignatureAlgorithm()

35 files changed:
ext/phar/phar.phar
ext/phar/phar_internal.h
ext/phar/phar_object.c
ext/phar/tar.c
ext/phar/tests/badparameters.phpt
ext/phar/tests/phar_convert_again.phpt
ext/phar/tests/phar_setsignaturealgo2.phpt
ext/phar/tests/stat2.phpt
ext/phar/tests/stat2_5.3.phpt
ext/phar/tests/tar/bignames.phpt
ext/phar/tests/tar/files/frontcontroller.phar.tar
ext/phar/tests/tar/files/frontcontroller10.phar.tar
ext/phar/tests/tar/files/frontcontroller11.phar.tar
ext/phar/tests/tar/files/frontcontroller12.phar.tar
ext/phar/tests/tar/files/frontcontroller2.phar.tar
ext/phar/tests/tar/files/frontcontroller3.phar.tar
ext/phar/tests/tar/files/frontcontroller4.phar.tar
ext/phar/tests/tar/files/frontcontroller5.phar.tar
ext/phar/tests/tar/files/frontcontroller6.phar.tar
ext/phar/tests/tar/files/frontcontroller7.phar.tar
ext/phar/tests/tar/files/frontcontroller8.phar.tar
ext/phar/tests/tar/files/frontcontroller9.phar.tar
ext/phar/tests/tar/links.phpt
ext/phar/tests/tar/links3.phpt
ext/phar/tests/tar/links4.phpt
ext/phar/tests/tar/links5.phpt
ext/phar/tests/tar/phar_setsignaturealgo2.phpt [new file with mode: 0644]
ext/phar/tests/tar/require_hash.phpt [new file with mode: 0644]
ext/phar/tests/tar/tar_003.phpt
ext/phar/tests/tar/tar_004.phpt
ext/phar/tests/tar/tar_bz2.phpt
ext/phar/tests/tar/tar_gzip.phpt
ext/phar/tests/tar/tar_nostub.phpt
ext/phar/tests/zf_test.phpt
ext/phar/util.c

index 06432e05798d05ddf8d1c336a0f9a1092d05d695..834529deebd790b4eb28bf890ef7fa69fe22c685 100755 (executable)
Binary files a/ext/phar/phar.phar and b/ext/phar/phar.phar differ
index cb7a20419bcdd9a5efaa0e625835b0eade3874a2..f1c12a18df7827afd8f560e9d6cce78dc7110d41 100755 (executable)
@@ -420,7 +420,7 @@ int phar_open_executed_filename(char *alias, int alias_len, char **error TSRMLS_
 int phar_free_alias(phar_archive_data *phar, char *alias, int alias_len TSRMLS_DC);
 int phar_get_archive(phar_archive_data **archive, char *fname, int fname_len, char *alias, int alias_len, char **error TSRMLS_DC);
 int phar_open_parsed_phar(char *fname, int fname_len, char *alias, int alias_len, int is_data, int options, phar_archive_data** pphar, char **error TSRMLS_DC);
-int phar_verify_signature(php_stream *fp, size_t end_of_phar, int sig_type, char *sig, int sig_len, char *fname, char **signature, int *signature_len, char **error TSRMLS_DC);
+int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_type, char *sig, int sig_len, char *fname, char **signature, int *signature_len, char **error TSRMLS_DC);
 int phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, int *signature_length, char **error TSRMLS_DC);
 
 /* utility functions */
index c7801542c9ec01e955328e1b38cab44759b9d857..092162b95515baf8f0bdaa73ade9b5948c765eec 100755 (executable)
@@ -2707,11 +2707,6 @@ PHP_METHOD(Phar, setSignatureAlgorithm)
                        "Cannot set signature algorithm, phar is read-only");
                return;
        }
-       if (phar_obj->arc.archive->is_tar) {
-               zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
-                       "Cannot set signature algorithm, not possible with tar-based phar archives");
-               return;
-       }
        if (phar_obj->arc.archive->is_zip) {
                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
                        "Cannot set signature algorithm, not possible with zip-based phar archives");
index 1cd5046aa0930da0f5b78bbd7c6694adff330d00..bb79b1a46d0e128328af65deb76a004ab694747c 100644 (file)
@@ -243,6 +243,86 @@ int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias,
                size = entry.uncompressed_filesize = entry.compressed_filesize =
                        phar_tar_number(hdr->size, sizeof(hdr->size));
 
+               if (((!old && hdr->prefix[0] == 0) || old) && strlen(hdr->name) == sizeof(".phar/signature.bin")-1 && !strncmp(hdr->name, ".phar/signature.bin", sizeof(".phar/signature.bin")-1)) {
+                       size_t read;
+                       if (size > 511) {
+                               if (error) {
+                                       spprintf(error, 4096, "phar error: tar-based phar \"%s\" has signature that is larger than 511 bytes, cannot process", fname);
+                               }
+bail:
+                               php_stream_close(fp);
+                               zend_hash_destroy(&myphar->manifest);
+                               myphar->manifest.arBuckets = 0;
+                               zend_hash_destroy(&myphar->mounted_dirs);
+                               myphar->mounted_dirs.arBuckets = 0;
+                               pefree(myphar, myphar->is_persistent);
+                               return FAILURE;
+                       }
+                       read = php_stream_read(fp, buf, size);
+                       if (read != size) {
+                               if (error) {
+                                       spprintf(error, 4096, "phar error: tar-based phar \"%s\" signature cannot be read", fname);
+                               }
+                               goto bail;
+                       }
+#ifdef WORDS_BIGENDIAN
+# define PHAR_GET_32(buffer) \
+       (((((unsigned char*)(buffer))[3]) << 24) \
+               | ((((unsigned char*)(buffer))[2]) << 16) \
+               | ((((unsigned char*)(buffer))[1]) <<  8) \
+               | (((unsigned char*)(buffer))[0]))
+#else
+# define PHAR_GET_32(buffer) (php_uint32) *(buffer)
+#endif
+                       if (FAILURE == phar_verify_signature(fp, php_stream_tell(fp) - size - 512, PHAR_GET_32(buf), buf + 8, PHAR_GET_32(buf + 4), fname, &myphar->signature, &myphar->sig_len, error TSRMLS_CC)) {
+                               if (error) {
+                                       char *save = *error;
+                                       spprintf(error, 4096, "phar error: tar-based phar \"%s\" signature cannot be verified: %s", fname, save);
+                                       efree(save);
+                               }
+                               goto bail;
+                       }
+                       /* signature checked out, let's ensure this is the last file in the phar */
+                       size = ((size+511)&~511) + 512;
+                       if (((hdr->typeflag == 0) || (hdr->typeflag == TAR_FILE)) && size > 0) {
+                               /* this is not good enough - seek succeeds even on truncated tars */
+                               php_stream_seek(fp, size, SEEK_CUR);
+                               if ((uint)php_stream_tell(fp) > totalsize) {
+                                       if (error) {
+                                               spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file (truncated)", fname);
+                                       }
+                                       php_stream_close(fp);
+                                       zend_hash_destroy(&myphar->manifest);
+                                       myphar->manifest.arBuckets = 0;
+                                       zend_hash_destroy(&myphar->mounted_dirs);
+                                       myphar->mounted_dirs.arBuckets = 0;
+                                       pefree(myphar, myphar->is_persistent);
+                                       return FAILURE;
+                               }
+                       }
+                       read = php_stream_read(fp, buf, sizeof(buf));
+                       if (read != sizeof(buf)) {
+                               if (error) {
+                                       spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file (truncated)", fname);
+                               }
+                               php_stream_close(fp);
+                               zend_hash_destroy(&myphar->manifest);
+                               myphar->manifest.arBuckets = 0;
+                               zend_hash_destroy(&myphar->mounted_dirs);
+                               myphar->mounted_dirs.arBuckets = 0;
+                               pefree(myphar, myphar->is_persistent);
+                               return FAILURE;
+                       }
+                       hdr = (tar_header*) buf;
+                       sum1 = phar_tar_number(hdr->checksum, sizeof(hdr->checksum));
+                       if (sum1 == 0 && phar_tar_checksum(buf, sizeof(buf)) == 0) {
+                               break;
+                       }
+                       if (error) {
+                               spprintf(error, 4096, "phar error: \"%s\" has entries after signature, invalid phar", fname);
+                       }
+                       goto bail;
+               }
                if (!old && hdr->prefix[0] != 0) {
                        char name[256];
 
@@ -419,6 +499,21 @@ int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias,
                        return FAILURE;
                }
        } while (read != 0);
+
+       /* ensure signature set */
+       if (PHAR_G(require_hash) && !myphar->signature) {
+               php_stream_close(fp);
+               zend_hash_destroy(&myphar->manifest);
+               myphar->manifest.arBuckets = 0;
+               zend_hash_destroy(&myphar->mounted_dirs);
+               myphar->mounted_dirs.arBuckets = 0;
+               pefree(myphar, myphar->is_persistent);
+               if (error) {
+                       spprintf(error, 0, "tar-based phar \"%s\" does not have a signature", fname);
+               }
+               return FAILURE;
+       }
+
        myphar->fname = pestrndup(fname, fname_len, myphar->is_persistent);
 #ifdef PHP_WIN32
        phar_unixify_path_separators(myphar->fname, fname_len);
@@ -712,9 +807,9 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defau
        phar_entry_info entry = {0};
        static const char newstub[] = "<?php // tar-based phar archive stub file\n__HALT_COMPILER();";
        php_stream *oldfile, *newfile, *stubfile;
-       int closeoldfile, free_user_stub;
+       int closeoldfile, free_user_stub, signature_length;
        struct _phar_pass_tar_info pass;
-       char *buf;
+       char *buf, *signature, sigbuf[8];
 
        entry.flags = PHAR_ENT_PERM_DEF_FILE;
        entry.timestamp = time(NULL);
@@ -734,7 +829,6 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defau
                entry.filename = estrndup(".phar/alias.txt", sizeof(".phar/alias.txt")-1);
                entry.filename_len = sizeof(".phar/alias.txt")-1;
                entry.fp = php_stream_fopen_tmpfile();
-               entry.crc32 = phar_tar_checksum(phar->alias, phar->alias_len);
                if (phar->alias_len != (int)php_stream_write(entry.fp, phar->alias, phar->alias_len)) {
                        if (error) {
                                spprintf(error, 0, "unable to set alias in tar-based phar \"%s\"", phar->fname);
@@ -926,6 +1020,62 @@ nostub:
 
        zend_hash_apply_with_argument(&phar->manifest, (apply_func_arg_t) phar_tar_writeheaders, (void *) &pass TSRMLS_CC);
 
+       /* add signature for executable tars or tars explicitly set with setSignatureAlgorithm */
+       if (!phar->is_data || phar->sig_flags) {
+               if (FAILURE == phar_create_signature(phar, newfile, &signature, &signature_length, error TSRMLS_CC)) {
+                       if (error) {
+                               char *save = *error;
+                               spprintf(error, 0, "phar error: unable to write signature to tar-based phar: %s", save);
+                               efree(save);
+                       }
+                       if (closeoldfile) {
+                               php_stream_close(oldfile);
+                       }
+                       php_stream_close(newfile);
+                       return EOF;
+               }
+               entry.filename = ".phar/signature.bin";
+               entry.filename_len = sizeof(".phar/signature.bin")-1;
+               entry.fp = php_stream_fopen_tmpfile();
+
+#ifdef WORDS_BIGENDIAN
+# define PHAR_SET_32(var, buffer) \
+       *(php_uint32 *)(var) = (((((unsigned char*)(buffer))[3]) << 24) \
+               | ((((unsigned char*)(buffer))[2]) << 16) \
+               | ((((unsigned char*)(buffer))[1]) <<  8) \
+               | (((unsigned char*)(buffer))[0]))
+#else
+# define PHAR_SET_32(var, buffer) *(php_uint32 *)(var) = (php_uint32) (buffer)
+#endif
+               PHAR_SET_32(sigbuf, phar->sig_flags);
+               PHAR_SET_32(sigbuf + 4, signature_length);
+               if (8 != php_stream_write(entry.fp, sigbuf, 8) || signature_length != php_stream_write(entry.fp, signature, signature_length)) {
+                       efree(signature);
+                       if (error) {
+                               spprintf(error, 0, "phar error: unable to write signature to tar-based phar %s", phar->fname);
+                       }
+                       if (closeoldfile) {
+                               php_stream_close(oldfile);
+                       }
+                       php_stream_close(newfile);
+                       return EOF;
+               }
+               efree(signature);
+
+               entry.uncompressed_filesize = entry.compressed_filesize = signature_length + 8;
+               /* throw out return value and write the signature */
+               entry.filename_len = phar_tar_writeheaders((void *)&entry, (void *)&pass);
+
+               if (error && *error) {
+                       if (closeoldfile) {
+                               php_stream_close(oldfile);
+                       }
+                       /* error is set by writeheaders */
+                       php_stream_close(newfile);
+                       return EOF;
+               }
+       } /* signature */
+
        /* add final zero blocks */
        buf = (char *) ecalloc(1024, 1);
        php_stream_write(newfile, buf, 1024);
index c644424d25a304945403591b2d4a1fff07021d8c..ed3ae274b5c7d3e1b34741e7af55a311d892e791 100644 (file)
@@ -77,11 +77,6 @@ $a->setSignatureAlgorithm(Phar::MD5);
 echo $e->getMessage() . "\n";
 }
 try {
-$b->setSignatureAlgorithm(Phar::MD5);
-} catch (Exception $e) {
-echo $e->getMessage() . "\n";
-}
-try {
 $c->setSignatureAlgorithm(Phar::MD5);
 } catch (Exception $e) {
 echo $e->getMessage() . "\n";
@@ -165,7 +160,6 @@ A Phar stub cannot be set in a plain tar archive
 Warning: Phar::setDefaultStub() expects parameter 1 to be string, array given in %sbadparameters.php on line %d
 Cannot change stub: phar.readonly=1
 Cannot set signature algorithm, phar is read-only
-Cannot set signature algorithm, not possible with tar-based phar archives
 Cannot set signature algorithm, not possible with zip-based phar archives
 
 Warning: Phar::compress() expects parameter 1 to be long, array given in %sbadparameters.php on line %d
index 4543a238d584c0a4205ae3089af515da66d15105..9485f1e6aadf613f1658ca29ac482f40b7118b7f 100644 (file)
@@ -139,12 +139,6 @@ $data->setDefaultStub();
 } catch (Exception $e) {
 echo $e->getMessage() . "\n";
 }
-try {
-$data->setSignatureAlgorithm(Phar::MD5);
-} catch (Exception $e) {
-echo $e->getMessage() . "\n";
-}
-
 try {
 $tgz->convertToData(Phar::TAR, Phar::GZ, '.phar.tgz.oops');
 } catch (Exception $e) {
@@ -211,7 +205,6 @@ Unknown compression specified, please pass one of Phar::GZ or Phar::BZ2
 A Phar stub cannot be set in a plain tar archive
 A Phar alias cannot be set in a plain tar archive
 A Phar stub cannot be set in a plain tar archive
-Cannot set signature algorithm, not possible with tar-based phar archives
 data phar "%sphar_convert_again2.phar.tgz.oops" has invalid extension phar.tgz.oops
 phar "%sphar_convert_again2.tgz.oops" has invalid extension tgz.oops
 data phar "%sphar_convert_again2.phar/.tgz.oops" has invalid extension phar/.tgz.oops
index 57b16097e75ace8a1d396bd3dd4eb952e901d7a6..c7f5f9ecfca1c591fbf382b5e41103d7b357c94f 100644 (file)
@@ -10,7 +10,7 @@ phar.readonly=0
 --FILE--
 <?php
 $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar';
-$p = new Phar(dirname(__FILE__) . '/brandnewphar.phar', 0, 'brandnewphar.phar');
+$p = new Phar($fname);
 $p['file1.txt'] = 'hi';
 var_dump($p->getSignature());
 $p->setSignatureAlgorithm(Phar::MD5);
@@ -42,7 +42,7 @@ echo $e->getMessage();
 ===DONE===
 --CLEAN--
 <?php
-unlink(dirname(__FILE__) . '/brandnewphar.phar');
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar');
 ?>
 --EXPECTF--
 array(2) {
index 6e911028ca69101e231b400f9563ec39df3297bf..defda719f3dec79df93b11e1f335756ab505e5b8 100644 (file)
@@ -5,6 +5,7 @@ Phar: test stat function interceptions and is_file/is_link edge cases (PHP 5.2)
 <?php if (substr(phpversion(), 0, 3) != '5.2') die("skip PHP 5.2 required for this test");?>
 --INI--
 phar.readonly=0
+phar.require_hash=0
 --FILE--
 <?php
 Phar::interceptFileFuncs();
index 58ca54a16a310a3bce3479642ba7866ea9c6452a..aba2a6417de5542b4acb0948d46ae372d101b424 100644 (file)
@@ -5,6 +5,7 @@ Phar: test stat function interceptions and is_file/is_link edge cases (PHP 5.3+)
 <?php if (substr(phpversion(), 0, 3) == '5.2') die("skip PHP 5.3+ required for this test");?>
 --INI--
 phar.readonly=0
+phar.require_hash=0
 --FILE--
 <?php
 Phar::interceptFileFuncs();
index 19d5f638e1b22784adc1f65a7d0b024131836445..4b51e2a9214f1b3168f8f2c9ac538200783f732d 100644 (file)
@@ -2,6 +2,8 @@
 Phar: tar with huge filenames
 --SKIPIF--
 <?php if (!extension_loaded("phar")) die("skip"); ?>
+--INI--
+phar.require_hash=0
 --FILE--
 <?php
 $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.tar';
index 522d097845e6ecce56a7b2f3352a6ae824657d17..02d8766dcc55814d443ae8489dad20335f5e245d 100644 (file)
Binary files a/ext/phar/tests/tar/files/frontcontroller.phar.tar and b/ext/phar/tests/tar/files/frontcontroller.phar.tar differ
index d43ed916a13489480678609c069207eb1efe69e1..574d7cd7c877ff8977096126c3aed0ef89cef1ac 100644 (file)
Binary files a/ext/phar/tests/tar/files/frontcontroller10.phar.tar and b/ext/phar/tests/tar/files/frontcontroller10.phar.tar differ
index c8f98a1e78f04cc44c0d48d8c9ad53e6aacf08a8..08cbdc1bfedbc0416fef723a3d5c9333231ddb5d 100644 (file)
Binary files a/ext/phar/tests/tar/files/frontcontroller11.phar.tar and b/ext/phar/tests/tar/files/frontcontroller11.phar.tar differ
index 06e7e59b03ed4677e37bd252d5d13ad712b7d5aa..e0f22f5f459c22e91265539c973b8c84b131e4b2 100644 (file)
Binary files a/ext/phar/tests/tar/files/frontcontroller12.phar.tar and b/ext/phar/tests/tar/files/frontcontroller12.phar.tar differ
index 857b1168901195870d265265ff233dc48a1e30f7..231e15ad323d009e10747ab2c35ff6c8d8ccef39 100644 (file)
Binary files a/ext/phar/tests/tar/files/frontcontroller2.phar.tar and b/ext/phar/tests/tar/files/frontcontroller2.phar.tar differ
index f733884d122423acf03d633cc2536db7ac40b923..2df61c95ac0ced1c9f160b6fbfedc1bbb4a02e3d 100644 (file)
Binary files a/ext/phar/tests/tar/files/frontcontroller3.phar.tar and b/ext/phar/tests/tar/files/frontcontroller3.phar.tar differ
index 5d11af499c181d8bada5b7a9d0579368cb034865..4cd684d25cc0346fafcd7a7e4bb5e107c16494e4 100644 (file)
Binary files a/ext/phar/tests/tar/files/frontcontroller4.phar.tar and b/ext/phar/tests/tar/files/frontcontroller4.phar.tar differ
index e6e9015bf8e23f9532eb73997712f8dcbc2d39da..6053eb278333d956fbdfc5c5db42ace0f97d543e 100644 (file)
Binary files a/ext/phar/tests/tar/files/frontcontroller5.phar.tar and b/ext/phar/tests/tar/files/frontcontroller5.phar.tar differ
index d30b7ab9eb204c030bc020ea5bf21043abe10047..e0cb2ff276e6ca7d6376672c513c8e486079f486 100644 (file)
Binary files a/ext/phar/tests/tar/files/frontcontroller6.phar.tar and b/ext/phar/tests/tar/files/frontcontroller6.phar.tar differ
index c7ccc940c149fafcc84595c7c736094bc574e4b5..8327ae981685c34a30f65ce646f67a2edf53397f 100644 (file)
Binary files a/ext/phar/tests/tar/files/frontcontroller7.phar.tar and b/ext/phar/tests/tar/files/frontcontroller7.phar.tar differ
index 98495717cec043718c39f6c04632a3c90bccd93d..3440a7f32a55316265a93e883020c09749cfeb25 100644 (file)
Binary files a/ext/phar/tests/tar/files/frontcontroller8.phar.tar and b/ext/phar/tests/tar/files/frontcontroller8.phar.tar differ
index 481864c1cf465897f23968ad6d7298f2af522da5..15e95b18f24898fa3e0a6226230707eee924597e 100644 (file)
Binary files a/ext/phar/tests/tar/files/frontcontroller9.phar.tar and b/ext/phar/tests/tar/files/frontcontroller9.phar.tar differ
index 73e257b8be9f0615d3c1c3685b6cd8bdcbbf00f6..d702cacc45b754ba56f34da3e8fb3966b8362899 100644 (file)
@@ -2,6 +2,8 @@
 Phar: tar with hard link and symbolic link
 --SKIPIF--
 <?php if (!extension_loaded("phar")) die("skip"); ?>
+--INI--
+phar.require_hash=0
 --FILE--
 <?php
 $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.tar';
index 224108166066c56e3de852f16c6f382a4a5c7b41..def399e2603c9a2bc0cbbac88ad4b2b28d22f4cc 100644 (file)
@@ -2,6 +2,8 @@
 Phar: tar with link to absolute path
 --SKIPIF--
 <?php if (!extension_loaded("phar")) die("skip"); ?>
+--INI--
+phar.require_hash=0
 --FILE--
 <?php
 try {
index d0783e84aca96138de54990286dbd6c48f1559b4..1d658a72e92c3cbef3632bbf8db1a7c2f4834b45 100644 (file)
@@ -2,6 +2,8 @@
 Phar: tar with link to root directory file from root directory file
 --SKIPIF--
 <?php if (!extension_loaded("phar")) die("skip"); ?>
+--INI--
+phar.require_hash=0
 --FILE--
 <?php
 try {
index 262d41d841ca5106c912de6f7c659aa82e435860..6d11d3eb85549eec3f60110cd243d4a77ab2e60a 100644 (file)
@@ -2,6 +2,8 @@
 Phar: tar with relative link to subdirectory file from subdirectory file
 --SKIPIF--
 <?php if (!extension_loaded("phar")) die("skip"); ?>
+--INI--
+phar.require_hash=0
 --FILE--
 <?php
 try {
diff --git a/ext/phar/tests/tar/phar_setsignaturealgo2.phpt b/ext/phar/tests/tar/phar_setsignaturealgo2.phpt
new file mode 100644 (file)
index 0000000..e9cbdb4
--- /dev/null
@@ -0,0 +1,84 @@
+--TEST--
+Phar::setSupportedSignatures() with hash, tar-based
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+<?php if (!extension_loaded("hash")) die("skip extension hash required"); ?>
+<?php if (!extension_loaded("openssl")) die("skip extension openssl required"); ?>
+--INI--
+phar.require_hash=0
+phar.readonly=0
+--FILE--
+<?php
+$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.tar';
+$p = new Phar($fname);
+$p['file1.txt'] = 'hi';
+var_dump($p->getSignature());
+$p->setSignatureAlgorithm(Phar::MD5);
+var_dump($p->getSignature());
+$p->setSignatureAlgorithm(Phar::SHA1);
+var_dump($p->getSignature());
+try {
+$p->setSignatureAlgorithm(Phar::SHA256);
+var_dump($p->getSignature());
+} catch (Exception $e) {
+echo $e->getMessage();
+}
+try {
+$p->setSignatureAlgorithm(Phar::SHA512);
+var_dump($p->getSignature());
+} catch (Exception $e) {
+echo $e->getMessage();
+}
+try {
+$private = openssl_get_privatekey(file_get_contents(dirname(dirname(__FILE__)) . '/files/private.pem'));
+$pkey = '';
+openssl_pkey_export($private, $pkey);
+$p->setSignatureAlgorithm(Phar::OPENSSL, $pkey);
+var_dump($p->getSignature());
+} catch (Exception $e) {
+echo $e->getMessage();
+}
+?>
+===DONE===
+--CLEAN--
+<?php
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.tar');
+?>
+--EXPECTF--
+array(2) {
+  ["hash"]=>
+  string(%d) "%s"
+  ["hash_type"]=>
+  string(5) "SHA-1"
+}
+array(2) {
+  ["hash"]=>
+  string(%d) "%s"
+  ["hash_type"]=>
+  string(3) "MD5"
+}
+array(2) {
+  ["hash"]=>
+  string(%d) "%s"
+  ["hash_type"]=>
+  string(5) "SHA-1"
+}
+array(2) {
+  ["hash"]=>
+  string(%d) "%s"
+  ["hash_type"]=>
+  string(7) "SHA-256"
+}
+array(2) {
+  ["hash"]=>
+  string(%d) "%s"
+  ["hash_type"]=>
+  string(7) "SHA-512"
+}
+array(2) {
+  ["hash"]=>
+  string(%d) "%s"
+  ["hash_type"]=>
+  string(7) "OpenSSL"
+}
+===DONE===
diff --git a/ext/phar/tests/tar/require_hash.phpt b/ext/phar/tests/tar/require_hash.phpt
new file mode 100644 (file)
index 0000000..002931b
--- /dev/null
@@ -0,0 +1,56 @@
+--TEST--
+Phar: tar-based phar, require_hash=1, no signature
+--SKIPIF--
+<?php if (!extension_loaded('phar')) die('skip'); ?>
+<?php if (!extension_loaded("spl")) die("skip SPL not available"); ?>
+--INI--
+phar.readonly=1
+phar.require_hash=0
+--FILE--
+<?php
+ini_set('phar.require_hash', 1);
+include dirname(__FILE__) . '/files/tarmaker.php.inc';
+$fname = dirname(__FILE__) . '/tar_004.phar.tar';
+$alias = 'phar://' . $fname;
+$fname2 = dirname(__FILE__) . '/tar_004.tar';
+
+$tar = new tarmaker($fname, 'none');
+$tar->init();
+$tar->addFile('tar_004.php', '<?php var_dump(__FILE__);');
+$tar->addFile('internal/file/here', "hi there!\n");
+$tar->close();
+
+try {
+       $phar = new Phar($fname);
+       var_dump($phar->getStub());
+} catch (Exception $e) {
+       echo $e->getMessage()."\n";
+}
+ini_set('phar.require_hash', 0);
+try {
+       $phar = new PharData($fname2);
+       $phar['file'] = 'hi';
+       var_dump($phar->getSignature());
+       $phar->setSignatureAlgorithm(Phar::MD5);
+       var_dump($phar->getSignature());
+} catch (Exception $e) {
+       echo $e->getMessage()."\n";
+}
+
+?>
+===DONE===
+--CLEAN--
+<?php
+@unlink(dirname(__FILE__) . '/tar_004.phar.tar');
+@unlink(dirname(__FILE__) . '/tar_004.tar');
+?>
+--EXPECTF--
+tar-based phar "%star_004.phar.tar" does not have a signature
+bool(false)
+array(2) {
+  ["hash"]=>
+  string(32) "%s"
+  ["hash_type"]=>
+  string(3) "MD5"
+}
+===DONE===
index b390805dc3dc146f111629c989bcb3ac745a6a19..3dec34178413cd892df2b25fc620bbea85fae0c3 100644 (file)
@@ -5,6 +5,7 @@ Phar: tar-based phar, valid 1
 <?php if (!extension_loaded("spl")) die("skip SPL not available"); ?>
 --INI--
 phar.readonly=0
+phar.require_hash=0
 --FILE--
 <?php
 include dirname(__FILE__) . '/files/tarmaker.php.inc';
index 2dd7ba169f74ab7b5d87b9cf7ede67397ee343ca..0125aecfa71775e2c8718207fc14d7fc788273d0 100644 (file)
@@ -5,6 +5,7 @@ Phar: tar-based phar, tar phar with stub, mapPhar()
 <?php if (!extension_loaded("spl")) die("skip SPL not available"); ?>
 --INI--
 phar.readonly=0
+phar.require_hash=0
 --FILE--
 <?php
 include dirname(__FILE__) . '/files/tarmaker.php.inc';
index ad1454143105c885507987fa2346d1a305d0657e..c18314e5fff723d7d42bcdf08148c6bc7344b0f6 100644 (file)
@@ -6,6 +6,7 @@ Phar: tar-based phar, bzipped tar
 <?php if (!extension_loaded("bz2")) die("skip bz2 not available"); ?>
 --INI--
 phar.readonly=0
+phar.require_hash=0
 --FILE--
 <?php
 include dirname(__FILE__) . '/files/tarmaker.php.inc';
index 8287ee7f06479986e63d29c6e61ce0fa972aa773..3e52b96f3a5d8d002462d4f7ba4e60bf31e6b5f7 100644 (file)
@@ -7,6 +7,7 @@ Phar: tar-based phar, gzipped tar
 <?php if (version_compare(phpversion(), '5.2.6', '<')) die("skip zlib is buggy in PHP < 5.2.6"); ?>
 --INI--
 phar.readonly=0
+phar.require_hash=0
 --FILE--
 <?php
 include dirname(__FILE__) . '/files/tarmaker.php.inc';
index a107a37debf40fef7b588119bdb2aa36c8baba85..0036662c385aa92485b234be691e120e8921744a 100644 (file)
@@ -5,6 +5,7 @@ Phar: tar-based phar, third-party tar with no stub, Phar->getStub()
 <?php if (!extension_loaded("spl")) die("skip SPL not available"); ?>
 --INI--
 phar.readonly=1
+phar.require_hash=0
 --FILE--
 <?php
 include dirname(__FILE__) . '/files/tarmaker.php.inc';
index 0e0da1fcc9d72234fd6a685caa476e695120fe18..c5d587dc9c2705c8f38e842e55ac50fdc1c78267 100644 (file)
@@ -5,6 +5,7 @@ Phar: test broken app
 <?php if (!extension_loaded("zlib")) die("skip zlib not available"); ?>
 --INI--
 phar.readonly=0
+phar.require_hash=0
 --FILE--
 <?php
 
index 8103bf307d00fe0cde65d2977c5bfcae5ae0c0a9..de3eda89421c68addb375d2dfb21c07b2561fa32 100644 (file)
@@ -1466,7 +1466,7 @@ static int phar_call_openssl_signverify(int is_sign, php_stream *fp, off_t end,
 }
 #endif /* #ifndef PHAR_HAVE_OPENSSL */
 
-int phar_verify_signature(php_stream *fp, size_t end_of_phar, int sig_type, char *sig, int sig_len, char *fname, char **signature, int *signature_len, char **error TSRMLS_DC) /* {{{ */
+int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_type, char *sig, int sig_len, char *fname, char **signature, int *signature_len, char **error TSRMLS_DC) /* {{{ */
 {
        int read_size, len;
        off_t read_len;