xref: /php-src/ext/phar/util.c (revision 6f8bda05)
1 /*
2   +----------------------------------------------------------------------+
3   | phar php single-file executable PHP extension                        |
4   | utility functions                                                    |
5   +----------------------------------------------------------------------+
6   | Copyright (c) The PHP Group                                          |
7   +----------------------------------------------------------------------+
8   | This source file is subject to version 3.01 of the PHP license,      |
9   | that is bundled with this package in the file LICENSE, and is        |
10   | available through the world-wide-web at the following url:           |
11   | https://www.php.net/license/3_01.txt                                 |
12   | If you did not receive a copy of the PHP license and are unable to   |
13   | obtain it through the world-wide-web, please send a note to          |
14   | license@php.net so we can mail you a copy immediately.               |
15   +----------------------------------------------------------------------+
16   | Authors: Gregory Beaver <cellog@php.net>                             |
17   |          Marcus Boerger <helly@php.net>                              |
18   +----------------------------------------------------------------------+
19 */
20 
21 #include "phar_internal.h"
22 #include "ext/hash/php_hash_sha.h"
23 
24 #ifdef PHAR_HAVE_OPENSSL
25 /* OpenSSL includes */
26 #include <openssl/evp.h>
27 #include <openssl/x509.h>
28 #include <openssl/x509v3.h>
29 #include <openssl/crypto.h>
30 #include <openssl/pem.h>
31 #include <openssl/err.h>
32 #include <openssl/conf.h>
33 #include <openssl/rand.h>
34 #include <openssl/ssl.h>
35 #include <openssl/pkcs12.h>
36 #else
37 static int phar_call_openssl_signverify(int is_sign, php_stream *fp, zend_off_t end, char *key, size_t key_len, char **signature, size_t *signature_len, php_uint32 sig_type);
38 #endif
39 
40 /* for links to relative location, prepend cwd of the entry */
phar_get_link_location(phar_entry_info * entry)41 static char *phar_get_link_location(phar_entry_info *entry) /* {{{ */
42 {
43 	char *p, *ret = NULL;
44 	if (!entry->link) {
45 		return NULL;
46 	}
47 	if (entry->link[0] == '/') {
48 		return estrdup(entry->link + 1);
49 	}
50 	p = strrchr(entry->filename, '/');
51 	if (p) {
52 		*p = '\0';
53 		spprintf(&ret, 0, "%s/%s", entry->filename, entry->link);
54 		return ret;
55 	}
56 	return entry->link;
57 }
58 /* }}} */
59 
phar_get_link_source(phar_entry_info * entry)60 phar_entry_info *phar_get_link_source(phar_entry_info *entry) /* {{{ */
61 {
62 	phar_entry_info *link_entry;
63 	char *link;
64 
65 	if (!entry->link) {
66 		return entry;
67 	}
68 
69 	link = phar_get_link_location(entry);
70 	if (NULL != (link_entry = zend_hash_str_find_ptr(&(entry->phar->manifest), entry->link, strlen(entry->link))) ||
71 		NULL != (link_entry = zend_hash_str_find_ptr(&(entry->phar->manifest), link, strlen(link)))) {
72 		if (link != entry->link) {
73 			efree(link);
74 		}
75 		return phar_get_link_source(link_entry);
76 	} else {
77 		if (link != entry->link) {
78 			efree(link);
79 		}
80 		return NULL;
81 	}
82 }
83 /* }}} */
84 
85 /* retrieve a phar_entry_info's current file pointer for reading contents */
phar_get_efp(phar_entry_info * entry,int follow_links)86 php_stream *phar_get_efp(phar_entry_info *entry, int follow_links) /* {{{ */
87 {
88 	if (follow_links && entry->link) {
89 		phar_entry_info *link_entry = phar_get_link_source(entry);
90 
91 		if (link_entry && link_entry != entry) {
92 			return phar_get_efp(link_entry, 1);
93 		}
94 	}
95 
96 	if (phar_get_fp_type(entry) == PHAR_FP) {
97 		if (!phar_get_entrypfp(entry)) {
98 			/* re-open just in time for cases where our refcount reached 0 on the phar archive */
99 			phar_open_archive_fp(entry->phar);
100 		}
101 		return phar_get_entrypfp(entry);
102 	} else if (phar_get_fp_type(entry) == PHAR_UFP) {
103 		return phar_get_entrypufp(entry);
104 	} else if (entry->fp_type == PHAR_MOD) {
105 		return entry->fp;
106 	} else {
107 		/* temporary manifest entry */
108 		if (!entry->fp) {
109 			entry->fp = php_stream_open_wrapper(entry->tmp, "rb", STREAM_MUST_SEEK|0, NULL);
110 		}
111 		return entry->fp;
112 	}
113 }
114 /* }}} */
115 
phar_seek_efp(phar_entry_info * entry,zend_off_t offset,int whence,zend_off_t position,int follow_links)116 int phar_seek_efp(phar_entry_info *entry, zend_off_t offset, int whence, zend_off_t position, int follow_links) /* {{{ */
117 {
118 	php_stream *fp = phar_get_efp(entry, follow_links);
119 	zend_off_t temp, eoffset;
120 
121 	if (!fp) {
122 		return -1;
123 	}
124 
125 	if (follow_links) {
126 		phar_entry_info *t;
127 		t = phar_get_link_source(entry);
128 		if (t) {
129 			entry = t;
130 		}
131 	}
132 
133 	if (entry->is_dir) {
134 		return 0;
135 	}
136 
137 	eoffset = phar_get_fp_offset(entry);
138 
139 	switch (whence) {
140 		case SEEK_END:
141 			temp = eoffset + entry->uncompressed_filesize + offset;
142 			break;
143 		case SEEK_CUR:
144 			temp = eoffset + position + offset;
145 			break;
146 		case SEEK_SET:
147 			temp = eoffset + offset;
148 			break;
149 		default:
150 			temp = 0;
151 	}
152 
153 	if (temp > eoffset + (zend_off_t) entry->uncompressed_filesize) {
154 		return -1;
155 	}
156 
157 	if (temp < eoffset) {
158 		return -1;
159 	}
160 
161 	return php_stream_seek(fp, temp, SEEK_SET);
162 }
163 /* }}} */
164 
165 /* mount an absolute path or uri to a path internal to the phar archive */
phar_mount_entry(phar_archive_data * phar,char * filename,size_t filename_len,char * path,size_t path_len)166 int phar_mount_entry(phar_archive_data *phar, char *filename, size_t filename_len, char *path, size_t path_len) /* {{{ */
167 {
168 	phar_entry_info entry = {0};
169 	php_stream_statbuf ssb;
170 	int is_phar;
171 	const char *err;
172 
173 	if (phar_path_check(&path, &path_len, &err) > pcr_is_ok) {
174 		return FAILURE;
175 	}
176 
177 	if (path_len >= sizeof(".phar")-1 && !memcmp(path, ".phar", sizeof(".phar")-1)) {
178 		/* no creating magic phar files by mounting them */
179 		return FAILURE;
180 	}
181 
182 	is_phar = (filename_len > 7 && !memcmp(filename, "phar://", 7));
183 
184 	entry.phar = phar;
185 	entry.filename = estrndup(path, path_len);
186 #ifdef PHP_WIN32
187 	phar_unixify_path_separators(entry.filename, path_len);
188 #endif
189 	entry.filename_len = path_len;
190 	if (is_phar) {
191 		entry.tmp = estrndup(filename, filename_len);
192 	} else {
193 		entry.tmp = expand_filepath(filename, NULL);
194 		if (!entry.tmp) {
195 			entry.tmp = estrndup(filename, filename_len);
196 		}
197 	}
198 	filename = entry.tmp;
199 
200 	/* only check openbasedir for files, not for phar streams */
201 	if (!is_phar && php_check_open_basedir(filename)) {
202 		efree(entry.tmp);
203 		efree(entry.filename);
204 		return FAILURE;
205 	}
206 
207 	entry.is_mounted = 1;
208 	entry.is_crc_checked = 1;
209 	entry.fp_type = PHAR_TMP;
210 
211 	if (SUCCESS != php_stream_stat_path(filename, &ssb)) {
212 		efree(entry.tmp);
213 		efree(entry.filename);
214 		return FAILURE;
215 	}
216 
217 	if (ssb.sb.st_mode & S_IFDIR) {
218 		entry.is_dir = 1;
219 		if (NULL == zend_hash_str_add_ptr(&phar->mounted_dirs, entry.filename, path_len, entry.filename)) {
220 			/* directory already mounted */
221 			efree(entry.tmp);
222 			efree(entry.filename);
223 			return FAILURE;
224 		}
225 	} else {
226 		entry.is_dir = 0;
227 		entry.uncompressed_filesize = entry.compressed_filesize = ssb.sb.st_size;
228 	}
229 
230 	entry.flags = ssb.sb.st_mode;
231 
232 	if (NULL != zend_hash_str_add_mem(&phar->manifest, entry.filename, path_len, (void*)&entry, sizeof(phar_entry_info))) {
233 		return SUCCESS;
234 	}
235 
236 	efree(entry.tmp);
237 	efree(entry.filename);
238 	return FAILURE;
239 }
240 /* }}} */
241 
phar_find_in_include_path(zend_string * filename,phar_archive_data ** pphar)242 zend_string *phar_find_in_include_path(zend_string *filename, phar_archive_data **pphar) /* {{{ */
243 {
244 	zend_string *ret;
245 	char *path, *arch, *entry, *test;
246 	size_t arch_len, entry_len;
247 	phar_archive_data *phar;
248 
249 	if (pphar) {
250 		*pphar = NULL;
251 	} else {
252 		pphar = &phar;
253 	}
254 
255 	if (!zend_is_executing() || !PHAR_G(cwd)) {
256 		return NULL;
257 	}
258 
259 	zend_string *fname = zend_get_executed_filename_ex();
260 	if (!fname) {
261 		return NULL;
262 	}
263 
264 	bool is_file_a_phar_wrapper = zend_string_starts_with_literal_ci(fname, "phar://");
265 	size_t length_phar_protocol = strlen("phar://");
266 
267 	if (
268 		PHAR_G(last_phar)
269 		&& is_file_a_phar_wrapper
270 		&& ZSTR_LEN(fname) - length_phar_protocol >= PHAR_G(last_phar_name_len)
271 		&& !memcmp(ZSTR_VAL(fname) + length_phar_protocol, PHAR_G(last_phar_name), PHAR_G(last_phar_name_len))
272 	) {
273 		arch = estrndup(PHAR_G(last_phar_name), PHAR_G(last_phar_name_len));
274 		arch_len = PHAR_G(last_phar_name_len);
275 		phar = PHAR_G(last_phar);
276 		goto splitted;
277 	}
278 
279 	if (!is_file_a_phar_wrapper || SUCCESS != phar_split_fname(ZSTR_VAL(fname), ZSTR_LEN(fname), &arch, &arch_len, &entry, &entry_len, 1, 0)) {
280 		return NULL;
281 	}
282 
283 	efree(entry);
284 
285 	if (*ZSTR_VAL(filename) == '.') {
286 		size_t try_len;
287 
288 		if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) {
289 			efree(arch);
290 			return NULL;
291 		}
292 splitted:
293 		if (pphar) {
294 			*pphar = phar;
295 		}
296 
297 		try_len = ZSTR_LEN(filename);
298 		test = phar_fix_filepath(estrndup(ZSTR_VAL(filename), ZSTR_LEN(filename)), &try_len, 1);
299 
300 		if (*test == '/') {
301 			if (zend_hash_str_exists(&(phar->manifest), test + 1, try_len - 1)) {
302 				ret = strpprintf(0, "phar://%s%s", arch, test);
303 				efree(arch);
304 				efree(test);
305 				return ret;
306 			}
307 		} else {
308 			if (zend_hash_str_exists(&(phar->manifest), test, try_len)) {
309 				ret = strpprintf(0, "phar://%s/%s", arch, test);
310 				efree(arch);
311 				efree(test);
312 				return ret;
313 			}
314 		}
315 		efree(test);
316 	}
317 
318 	spprintf(&path, MAXPATHLEN + 1 + strlen(PG(include_path)), "phar://%s/%s%c%s", arch, PHAR_G(cwd), DEFAULT_DIR_SEPARATOR, PG(include_path));
319 	efree(arch);
320 	ret = php_resolve_path(ZSTR_VAL(filename), ZSTR_LEN(filename), path);
321 	efree(path);
322 
323 	if (ret && zend_string_starts_with_literal_ci(ret, "phar://")) {
324 		/* found phar:// */
325 		if (SUCCESS != phar_split_fname(ZSTR_VAL(ret), ZSTR_LEN(ret), &arch, &arch_len, &entry, &entry_len, 1, 0)) {
326 			return ret;
327 		}
328 
329 		*pphar = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), arch, arch_len);
330 
331 		if (!*pphar && PHAR_G(manifest_cached)) {
332 			*pphar = zend_hash_str_find_ptr(&cached_phars, arch, arch_len);
333 		}
334 
335 		efree(arch);
336 		efree(entry);
337 	}
338 
339 	return ret;
340 }
341 /* }}} */
342 
343 /**
344  * Retrieve a copy of the file information on a single file within a phar, or null.
345  * This also transfers the open file pointer, if any, to the entry.
346  *
347  * If the file does not already exist, this will fail.  Pre-existing files can be
348  * appended, truncated, or read.  For read, if the entry is marked unmodified, it is
349  * assumed that the file pointer, if present, is opened for reading
350  */
phar_get_entry_data(phar_entry_data ** ret,char * fname,size_t fname_len,char * path,size_t path_len,const char * mode,char allow_dir,char ** error,int security)351 int phar_get_entry_data(phar_entry_data **ret, char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security) /* {{{ */
352 {
353 	phar_archive_data *phar;
354 	phar_entry_info *entry;
355 	int for_write  = mode[0] != 'r' || mode[1] == '+';
356 	int for_append = mode[0] == 'a';
357 	int for_create = mode[0] != 'r';
358 	int for_trunc  = mode[0] == 'w';
359 
360 	if (!ret) {
361 		return FAILURE;
362 	}
363 
364 	*ret = NULL;
365 
366 	if (error) {
367 		*error = NULL;
368 	}
369 
370 	if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, error)) {
371 		return FAILURE;
372 	}
373 
374 	if (for_write && PHAR_G(readonly) && !phar->is_data) {
375 		if (error) {
376 			spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for writing, disabled by ini setting", path, fname);
377 		}
378 		return FAILURE;
379 	}
380 
381 	if (!path_len) {
382 		if (error) {
383 			spprintf(error, 4096, "phar error: file \"\" in phar \"%s\" cannot be empty", fname);
384 		}
385 		return FAILURE;
386 	}
387 really_get_entry:
388 	if (allow_dir) {
389 		if ((entry = phar_get_entry_info_dir(phar, path, path_len, allow_dir, for_create && !PHAR_G(readonly) && !phar->is_data ? NULL : error, security)) == NULL) {
390 			if (for_create && (!PHAR_G(readonly) || phar->is_data)) {
391 				return SUCCESS;
392 			}
393 			return FAILURE;
394 		}
395 	} else {
396 		if ((entry = phar_get_entry_info(phar, path, path_len, for_create && !PHAR_G(readonly) && !phar->is_data ? NULL : error, security)) == NULL) {
397 			if (for_create && (!PHAR_G(readonly) || phar->is_data)) {
398 				return SUCCESS;
399 			}
400 			return FAILURE;
401 		}
402 	}
403 
404 	if (for_write && phar->is_persistent) {
405 		if (FAILURE == phar_copy_on_write(&phar)) {
406 			if (error) {
407 				spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for writing, could not make cached phar writeable", path, fname);
408 			}
409 			return FAILURE;
410 		} else {
411 			goto really_get_entry;
412 		}
413 	}
414 
415 	if (entry->is_modified && !for_write) {
416 		if (error) {
417 			spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for reading, writable file pointers are open", path, fname);
418 		}
419 		return FAILURE;
420 	}
421 
422 	if (entry->fp_refcount && for_write) {
423 		if (error) {
424 			spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for writing, readable file pointers are open", path, fname);
425 		}
426 		return FAILURE;
427 	}
428 
429 	if (entry->is_deleted) {
430 		if (!for_create) {
431 			return FAILURE;
432 		}
433 		entry->is_deleted = 0;
434 	}
435 
436 	if (entry->is_dir) {
437 		*ret = (phar_entry_data *) emalloc(sizeof(phar_entry_data));
438 		(*ret)->position = 0;
439 		(*ret)->fp = NULL;
440 		(*ret)->phar = phar;
441 		(*ret)->for_write = for_write;
442 		(*ret)->internal_file = entry;
443 		(*ret)->is_zip = entry->is_zip;
444 		(*ret)->is_tar = entry->is_tar;
445 
446 		if (!phar->is_persistent) {
447 			++(entry->phar->refcount);
448 			++(entry->fp_refcount);
449 		}
450 
451 		return SUCCESS;
452 	}
453 
454 	if (entry->fp_type == PHAR_MOD) {
455 		if (for_trunc) {
456 			if (FAILURE == phar_create_writeable_entry(phar, entry, error)) {
457 				return FAILURE;
458 			}
459 		} else if (for_append) {
460 			phar_seek_efp(entry, 0, SEEK_END, 0, 0);
461 		}
462 	} else {
463 		if (for_write) {
464 			if (entry->link) {
465 				efree(entry->link);
466 				entry->link = NULL;
467 				entry->tar_type = (entry->is_tar ? TAR_FILE : '\0');
468 			}
469 
470 			if (for_trunc) {
471 				if (FAILURE == phar_create_writeable_entry(phar, entry, error)) {
472 					return FAILURE;
473 				}
474 			} else {
475 				if (FAILURE == phar_separate_entry_fp(entry, error)) {
476 					return FAILURE;
477 				}
478 			}
479 		} else {
480 			if (FAILURE == phar_open_entry_fp(entry, error, 1)) {
481 				return FAILURE;
482 			}
483 		}
484 	}
485 
486 	*ret = (phar_entry_data *) emalloc(sizeof(phar_entry_data));
487 	(*ret)->position = 0;
488 	(*ret)->phar = phar;
489 	(*ret)->for_write = for_write;
490 	(*ret)->internal_file = entry;
491 	(*ret)->is_zip = entry->is_zip;
492 	(*ret)->is_tar = entry->is_tar;
493 	(*ret)->fp = phar_get_efp(entry, 1);
494 	if (entry->link) {
495 		phar_entry_info *link = phar_get_link_source(entry);
496 		if(!link) {
497 			efree(*ret);
498 			return FAILURE;
499 		}
500 		(*ret)->zero = phar_get_fp_offset(link);
501 	} else {
502 		(*ret)->zero = phar_get_fp_offset(entry);
503 	}
504 
505 	if (!phar->is_persistent) {
506 		++(entry->fp_refcount);
507 		++(entry->phar->refcount);
508 	}
509 
510 	return SUCCESS;
511 }
512 /* }}} */
513 
514 /**
515  * Create a new dummy file slot within a writeable phar for a newly created file
516  */
phar_get_or_create_entry_data(char * fname,size_t fname_len,char * path,size_t path_len,const char * mode,char allow_dir,char ** error,int security)517 phar_entry_data *phar_get_or_create_entry_data(char *fname, size_t fname_len, char *path, size_t path_len, const char *mode, char allow_dir, char **error, int security) /* {{{ */
518 {
519 	phar_archive_data *phar;
520 	phar_entry_info *entry, etemp;
521 	phar_entry_data *ret;
522 	const char *pcr_error;
523 	char is_dir;
524 
525 #ifdef PHP_WIN32
526 	phar_unixify_path_separators(path, path_len);
527 #endif
528 
529 	is_dir = (path_len && path[path_len - 1] == '/') ? 1 : 0;
530 
531 	if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, error)) {
532 		return NULL;
533 	}
534 
535 	if (FAILURE == phar_get_entry_data(&ret, fname, fname_len, path, path_len, mode, allow_dir, error, security)) {
536 		return NULL;
537 	} else if (ret) {
538 		return ret;
539 	}
540 
541 	if (phar_path_check(&path, &path_len, &pcr_error) > pcr_is_ok) {
542 		if (error) {
543 			spprintf(error, 0, "phar error: invalid path \"%s\" contains %s", path, pcr_error);
544 		}
545 		return NULL;
546 	}
547 
548 	if (phar->is_persistent && FAILURE == phar_copy_on_write(&phar)) {
549 		if (error) {
550 			spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be created, could not make cached phar writeable", path, fname);
551 		}
552 		return NULL;
553 	}
554 
555 	/* create a new phar data holder */
556 	ret = (phar_entry_data *) emalloc(sizeof(phar_entry_data));
557 
558 	/* create an entry, this is a new file */
559 	memset(&etemp, 0, sizeof(phar_entry_info));
560 	etemp.filename_len = path_len;
561 	etemp.fp_type = PHAR_MOD;
562 	etemp.fp = php_stream_fopen_tmpfile();
563 
564 	if (!etemp.fp) {
565 		if (error) {
566 			spprintf(error, 0, "phar error: unable to create temporary file");
567 		}
568 		efree(ret);
569 		return NULL;
570 	}
571 
572 	etemp.fp_refcount = 1;
573 
574 	if (allow_dir == 2) {
575 		etemp.is_dir = 1;
576 		etemp.flags = etemp.old_flags = PHAR_ENT_PERM_DEF_DIR;
577 	} else {
578 		etemp.flags = etemp.old_flags = PHAR_ENT_PERM_DEF_FILE;
579 	}
580 	if (is_dir && path_len) {
581 		etemp.filename_len--; /* strip trailing / */
582 		path_len--;
583 	}
584 
585 	phar_add_virtual_dirs(phar, path, path_len);
586 	etemp.is_modified = 1;
587 	etemp.timestamp = time(0);
588 	etemp.is_crc_checked = 1;
589 	etemp.phar = phar;
590 	etemp.filename = estrndup(path, path_len);
591 	etemp.is_zip = phar->is_zip;
592 
593 	if (phar->is_tar) {
594 		etemp.is_tar = phar->is_tar;
595 		etemp.tar_type = etemp.is_dir ? TAR_DIR : TAR_FILE;
596 	}
597 
598 	if (NULL == (entry = zend_hash_str_add_mem(&phar->manifest, etemp.filename, path_len, (void*)&etemp, sizeof(phar_entry_info)))) {
599 		php_stream_close(etemp.fp);
600 		if (error) {
601 			spprintf(error, 0, "phar error: unable to add new entry \"%s\" to phar \"%s\"", etemp.filename, phar->fname);
602 		}
603 		efree(ret);
604 		efree(etemp.filename);
605 		return NULL;
606 	}
607 
608 	if (!entry) {
609 		php_stream_close(etemp.fp);
610 		efree(etemp.filename);
611 		efree(ret);
612 		return NULL;
613 	}
614 
615 	++(phar->refcount);
616 	ret->phar = phar;
617 	ret->fp = entry->fp;
618 	ret->position = ret->zero = 0;
619 	ret->for_write = 1;
620 	ret->is_zip = entry->is_zip;
621 	ret->is_tar = entry->is_tar;
622 	ret->internal_file = entry;
623 
624 	return ret;
625 }
626 /* }}} */
627 
628 /* initialize a phar_archive_data's read-only fp for existing phar data */
phar_open_archive_fp(phar_archive_data * phar)629 int phar_open_archive_fp(phar_archive_data *phar) /* {{{ */
630 {
631 	if (phar_get_pharfp(phar)) {
632 		return SUCCESS;
633 	}
634 
635 	if (php_check_open_basedir(phar->fname)) {
636 		return FAILURE;
637 	}
638 
639 	phar_set_pharfp(phar, php_stream_open_wrapper(phar->fname, "rb", IGNORE_URL|STREAM_MUST_SEEK|0, NULL));
640 
641 	if (!phar_get_pharfp(phar)) {
642 		return FAILURE;
643 	}
644 
645 	return SUCCESS;
646 }
647 /* }}} */
648 
649 /* copy file data from an existing to a new phar_entry_info that is not in the manifest */
phar_copy_entry_fp(phar_entry_info * source,phar_entry_info * dest,char ** error)650 int phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **error) /* {{{ */
651 {
652 	phar_entry_info *link;
653 
654 	if (FAILURE == phar_open_entry_fp(source, error, 1)) {
655 		return FAILURE;
656 	}
657 
658 	if (dest->link) {
659 		efree(dest->link);
660 		dest->link = NULL;
661 		dest->tar_type = (dest->is_tar ? TAR_FILE : '\0');
662 	}
663 
664 	dest->fp_type = PHAR_MOD;
665 	dest->offset = 0;
666 	dest->is_modified = 1;
667 	dest->fp = php_stream_fopen_tmpfile();
668 	if (dest->fp == NULL) {
669 		spprintf(error, 0, "phar error: unable to create temporary file");
670 		return EOF;
671 	}
672 	phar_seek_efp(source, 0, SEEK_SET, 0, 1);
673 	link = phar_get_link_source(source);
674 
675 	if (!link) {
676 		link = source;
677 	}
678 
679 	if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(link, 0), dest->fp, link->uncompressed_filesize, NULL)) {
680 		php_stream_close(dest->fp);
681 		dest->fp_type = PHAR_FP;
682 		if (error) {
683 			spprintf(error, 4096, "phar error: unable to copy contents of file \"%s\" to \"%s\" in phar archive \"%s\"", source->filename, dest->filename, source->phar->fname);
684 		}
685 		return FAILURE;
686 	}
687 
688 	return SUCCESS;
689 }
690 /* }}} */
691 
692 /* open and decompress a compressed phar entry
693  */
phar_open_entry_fp(phar_entry_info * entry,char ** error,int follow_links)694 int phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links) /* {{{ */
695 {
696 	php_stream_filter *filter;
697 	phar_archive_data *phar = entry->phar;
698 	char *filtername;
699 	zend_off_t loc;
700 	php_stream *ufp;
701 	phar_entry_data dummy;
702 
703 	if (follow_links && entry->link) {
704 		phar_entry_info *link_entry = phar_get_link_source(entry);
705 		if (link_entry && link_entry != entry) {
706 			return phar_open_entry_fp(link_entry, error, 1);
707 		}
708 	}
709 
710 	if (entry->is_modified) {
711 		return SUCCESS;
712 	}
713 
714 	if (entry->fp_type == PHAR_TMP) {
715 		if (!entry->fp) {
716 			entry->fp = php_stream_open_wrapper(entry->tmp, "rb", STREAM_MUST_SEEK|0, NULL);
717 		}
718 		return SUCCESS;
719 	}
720 
721 	if (entry->fp_type != PHAR_FP) {
722 		/* either newly created or already modified */
723 		return SUCCESS;
724 	}
725 
726 	if (!phar_get_pharfp(phar)) {
727 		if (FAILURE == phar_open_archive_fp(phar)) {
728 			spprintf(error, 4096, "phar error: Cannot open phar archive \"%s\" for reading", phar->fname);
729 			return FAILURE;
730 		}
731 	}
732 
733 	if ((entry->old_flags && !(entry->old_flags & PHAR_ENT_COMPRESSION_MASK)) || !(entry->flags & PHAR_ENT_COMPRESSION_MASK)) {
734 		dummy.internal_file = entry;
735 		dummy.phar = phar;
736 		dummy.zero = entry->offset;
737 		dummy.fp = phar_get_pharfp(phar);
738 		if (FAILURE == phar_postprocess_file(&dummy, entry->crc32, error, 1)) {
739 			return FAILURE;
740 		}
741 		return SUCCESS;
742 	}
743 
744 	if (!phar_get_entrypufp(entry)) {
745 		phar_set_entrypufp(entry, php_stream_fopen_tmpfile());
746 		if (!phar_get_entrypufp(entry)) {
747 			spprintf(error, 4096, "phar error: Cannot open temporary file for decompressing phar archive \"%s\" file \"%s\"", phar->fname, entry->filename);
748 			return FAILURE;
749 		}
750 	}
751 
752 	dummy.internal_file = entry;
753 	dummy.phar = phar;
754 	dummy.zero = entry->offset;
755 	dummy.fp = phar_get_pharfp(phar);
756 	if (FAILURE == phar_postprocess_file(&dummy, entry->crc32, error, 1)) {
757 		return FAILURE;
758 	}
759 
760 	ufp = phar_get_entrypufp(entry);
761 
762 	if ((filtername = phar_decompress_filter(entry, 0)) != NULL) {
763 		filter = php_stream_filter_create(filtername, NULL, 0);
764 	} else {
765 		filter = NULL;
766 	}
767 
768 	if (!filter) {
769 		spprintf(error, 4096, "phar error: unable to read phar \"%s\" (cannot create %s filter while decompressing file \"%s\")", phar->fname, phar_decompress_filter(entry, 1), entry->filename);
770 		return FAILURE;
771 	}
772 
773 	/* now we can safely use proper decompression */
774 	/* save the new offset location within ufp */
775 	php_stream_seek(ufp, 0, SEEK_END);
776 	loc = php_stream_tell(ufp);
777 	php_stream_filter_append(&ufp->writefilters, filter);
778 	php_stream_seek(phar_get_entrypfp(entry), phar_get_fp_offset(entry), SEEK_SET);
779 
780 	if (entry->uncompressed_filesize) {
781 		if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_entrypfp(entry), ufp, entry->compressed_filesize, NULL)) {
782 			spprintf(error, 4096, "phar error: internal corruption of phar \"%s\" (actual filesize mismatch on file \"%s\")", phar->fname, entry->filename);
783 			php_stream_filter_remove(filter, 1);
784 			return FAILURE;
785 		}
786 	}
787 
788 	php_stream_filter_flush(filter, 1);
789 	php_stream_flush(ufp);
790 	php_stream_filter_remove(filter, 1);
791 
792 	if (php_stream_tell(ufp) - loc != (zend_off_t) entry->uncompressed_filesize) {
793 		spprintf(error, 4096, "phar error: internal corruption of phar \"%s\" (actual filesize mismatch on file \"%s\")", phar->fname, entry->filename);
794 		return FAILURE;
795 	}
796 
797 	entry->old_flags = entry->flags;
798 
799 	/* this is now the new location of the file contents within this fp */
800 	phar_set_fp_type(entry, PHAR_UFP, loc);
801 	dummy.zero = entry->offset;
802 	dummy.fp = ufp;
803 	if (FAILURE == phar_postprocess_file(&dummy, entry->crc32, error, 0)) {
804 		return FAILURE;
805 	}
806 	return SUCCESS;
807 }
808 /* }}} */
809 
phar_create_writeable_entry(phar_archive_data * phar,phar_entry_info * entry,char ** error)810 int phar_create_writeable_entry(phar_archive_data *phar, phar_entry_info *entry, char **error) /* {{{ */
811 {
812 	if (entry->fp_type == PHAR_MOD) {
813 		/* already newly created, truncate */
814 		php_stream_truncate_set_size(entry->fp, 0);
815 
816 		entry->old_flags = entry->flags;
817 		entry->is_modified = 1;
818 		phar->is_modified = 1;
819 		/* reset file size */
820 		entry->uncompressed_filesize = 0;
821 		entry->compressed_filesize = 0;
822 		entry->crc32 = 0;
823 		entry->flags = PHAR_ENT_PERM_DEF_FILE;
824 		entry->fp_type = PHAR_MOD;
825 		entry->offset = 0;
826 		return SUCCESS;
827 	}
828 
829 	if (error) {
830 		*error = NULL;
831 	}
832 
833 	/* open a new temp file for writing */
834 	if (entry->link) {
835 		efree(entry->link);
836 		entry->link = NULL;
837 		entry->tar_type = (entry->is_tar ? TAR_FILE : '\0');
838 	}
839 
840 	entry->fp = php_stream_fopen_tmpfile();
841 
842 	if (!entry->fp) {
843 		if (error) {
844 			spprintf(error, 0, "phar error: unable to create temporary file");
845 		}
846 		return FAILURE;
847 	}
848 
849 	entry->old_flags = entry->flags;
850 	entry->is_modified = 1;
851 	phar->is_modified = 1;
852 	/* reset file size */
853 	entry->uncompressed_filesize = 0;
854 	entry->compressed_filesize = 0;
855 	entry->crc32 = 0;
856 	entry->flags = PHAR_ENT_PERM_DEF_FILE;
857 	entry->fp_type = PHAR_MOD;
858 	entry->offset = 0;
859 	return SUCCESS;
860 }
861 /* }}} */
862 
phar_separate_entry_fp(phar_entry_info * entry,char ** error)863 int phar_separate_entry_fp(phar_entry_info *entry, char **error) /* {{{ */
864 {
865 	php_stream *fp;
866 	phar_entry_info *link;
867 
868 	if (FAILURE == phar_open_entry_fp(entry, error, 1)) {
869 		return FAILURE;
870 	}
871 
872 	if (entry->fp_type == PHAR_MOD) {
873 		return SUCCESS;
874 	}
875 
876 	fp = php_stream_fopen_tmpfile();
877 	if (fp == NULL) {
878 		spprintf(error, 0, "phar error: unable to create temporary file");
879 		return FAILURE;
880 	}
881 	phar_seek_efp(entry, 0, SEEK_SET, 0, 1);
882 	link = phar_get_link_source(entry);
883 
884 	if (!link) {
885 		link = entry;
886 	}
887 
888 	if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(link, 0), fp, link->uncompressed_filesize, NULL)) {
889 		if (error) {
890 			spprintf(error, 4096, "phar error: cannot separate entry file \"%s\" contents in phar archive \"%s\" for write access", entry->filename, entry->phar->fname);
891 		}
892 		return FAILURE;
893 	}
894 
895 	if (entry->link) {
896 		efree(entry->link);
897 		entry->link = NULL;
898 		entry->tar_type = (entry->is_tar ? TAR_FILE : '\0');
899 	}
900 
901 	entry->offset = 0;
902 	entry->fp = fp;
903 	entry->fp_type = PHAR_MOD;
904 	entry->is_modified = 1;
905 	return SUCCESS;
906 }
907 /* }}} */
908 
909 /**
910  * helper function to open an internal file's fp just-in-time
911  */
phar_open_jit(phar_archive_data * phar,phar_entry_info * entry,char ** error)912 phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, char **error) /* {{{ */
913 {
914 	if (error) {
915 		*error = NULL;
916 	}
917 	/* seek to start of internal file and read it */
918 	if (FAILURE == phar_open_entry_fp(entry, error, 1)) {
919 		return NULL;
920 	}
921 	if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 1)) {
922 		spprintf(error, 4096, "phar error: cannot seek to start of file \"%s\" in phar \"%s\"", entry->filename, phar->fname);
923 		return NULL;
924 	}
925 	return entry;
926 }
927 /* }}} */
928 
phar_resolve_alias(char * alias,size_t alias_len,char ** filename,size_t * filename_len)929 PHP_PHAR_API int phar_resolve_alias(char *alias, size_t alias_len, char **filename, size_t *filename_len) /* {{{ */ {
930 	phar_archive_data *fd_ptr;
931 	if (HT_IS_INITIALIZED(&PHAR_G(phar_alias_map))
932 			&& NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) {
933 		*filename = fd_ptr->fname;
934 		*filename_len = fd_ptr->fname_len;
935 		return SUCCESS;
936 	}
937 	return FAILURE;
938 }
939 /* }}} */
940 
phar_free_alias(phar_archive_data * phar,char * alias,size_t alias_len)941 int phar_free_alias(phar_archive_data *phar, char *alias, size_t alias_len) /* {{{ */
942 {
943 	if (phar->refcount || phar->is_persistent) {
944 		return FAILURE;
945 	}
946 
947 	/* this archive has no open references, so emit a notice and remove it */
948 	if (zend_hash_str_del(&(PHAR_G(phar_fname_map)), phar->fname, phar->fname_len) != SUCCESS) {
949 		return FAILURE;
950 	}
951 
952 	/* invalidate phar cache */
953 	PHAR_G(last_phar) = NULL;
954 	PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL;
955 
956 	return SUCCESS;
957 }
958 /* }}} */
959 
960 /**
961  * Looks up a phar archive in the filename map, connecting it to the alias
962  * (if any) or returns null
963  */
phar_get_archive(phar_archive_data ** archive,char * fname,size_t fname_len,char * alias,size_t alias_len,char ** error)964 int phar_get_archive(phar_archive_data **archive, char *fname, size_t fname_len, char *alias, size_t alias_len, char **error) /* {{{ */
965 {
966 	phar_archive_data *fd, *fd_ptr;
967 	char *my_realpath, *save;
968 	size_t save_len;
969 
970 	phar_request_initialize();
971 
972 	if (error) {
973 		*error = NULL;
974 	}
975 
976 	*archive = NULL;
977 
978 	if (PHAR_G(last_phar) && fname_len == PHAR_G(last_phar_name_len) && !memcmp(fname, PHAR_G(last_phar_name), fname_len)) {
979 		*archive = PHAR_G(last_phar);
980 		if (alias && alias_len) {
981 
982 			if (!PHAR_G(last_phar)->is_temporary_alias && (alias_len != PHAR_G(last_phar)->alias_len || memcmp(PHAR_G(last_phar)->alias, alias, alias_len))) {
983 				if (error) {
984 					spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, PHAR_G(last_phar)->fname, fname);
985 				}
986 				*archive = NULL;
987 				return FAILURE;
988 			}
989 
990 			if (PHAR_G(last_phar)->alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len))) {
991 				zend_hash_str_del(&(PHAR_G(phar_alias_map)), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len);
992 			}
993 
994 			zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, *archive);
995 			PHAR_G(last_alias) = alias;
996 			PHAR_G(last_alias_len) = alias_len;
997 		}
998 
999 		return SUCCESS;
1000 	}
1001 
1002 	if (alias && alias_len && PHAR_G(last_phar) && alias_len == PHAR_G(last_alias_len) && !memcmp(alias, PHAR_G(last_alias), alias_len)) {
1003 		fd = PHAR_G(last_phar);
1004 		fd_ptr = fd;
1005 		goto alias_success;
1006 	}
1007 
1008 	if (alias && alias_len) {
1009 		if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) {
1010 alias_success:
1011 			if (fname && (fname_len != fd_ptr->fname_len || strncmp(fname, fd_ptr->fname, fname_len))) {
1012 				if (error) {
1013 					spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, fd_ptr->fname, fname);
1014 				}
1015 				if (SUCCESS == phar_free_alias(fd_ptr, alias, alias_len)) {
1016 					if (error) {
1017 						efree(*error);
1018 						*error = NULL;
1019 					}
1020 				}
1021 				return FAILURE;
1022 			}
1023 
1024 			*archive = fd_ptr;
1025 			fd = fd_ptr;
1026 			PHAR_G(last_phar) = fd;
1027 			PHAR_G(last_phar_name) = fd->fname;
1028 			PHAR_G(last_phar_name_len) = fd->fname_len;
1029 			PHAR_G(last_alias) = alias;
1030 			PHAR_G(last_alias_len) = alias_len;
1031 
1032 			return SUCCESS;
1033 		}
1034 
1035 		if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_alias, alias, alias_len))) {
1036 			goto alias_success;
1037 		}
1038 	}
1039 
1040 	my_realpath = NULL;
1041 	save = fname;
1042 	save_len = fname_len;
1043 
1044 	if (fname && fname_len) {
1045 		if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), fname, fname_len))) {
1046 			*archive = fd_ptr;
1047 			fd = fd_ptr;
1048 
1049 			if (alias && alias_len) {
1050 				if (!fd->is_temporary_alias && (alias_len != fd->alias_len || memcmp(fd->alias, alias, alias_len))) {
1051 					if (error) {
1052 						spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, fd_ptr->fname, fname);
1053 					}
1054 					return FAILURE;
1055 				}
1056 
1057 				if (fd->alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), fd->alias, fd->alias_len))) {
1058 					zend_hash_str_del(&(PHAR_G(phar_alias_map)), fd->alias, fd->alias_len);
1059 				}
1060 
1061 				zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, fd);
1062 			}
1063 
1064 			PHAR_G(last_phar) = fd;
1065 			PHAR_G(last_phar_name) = fd->fname;
1066 			PHAR_G(last_phar_name_len) = fd->fname_len;
1067 			PHAR_G(last_alias) = fd->alias;
1068 			PHAR_G(last_alias_len) = fd->alias_len;
1069 
1070 			return SUCCESS;
1071 		}
1072 
1073 		if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_phars, fname, fname_len))) {
1074 			*archive = fd_ptr;
1075 			fd = fd_ptr;
1076 
1077 			/* this could be problematic - alias should never be different from manifest alias
1078 			   for cached phars */
1079 			if (!fd->is_temporary_alias && alias && alias_len) {
1080 				if (alias_len != fd->alias_len || memcmp(fd->alias, alias, alias_len)) {
1081 					if (error) {
1082 						spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, fd_ptr->fname, fname);
1083 					}
1084 					return FAILURE;
1085 				}
1086 			}
1087 
1088 			PHAR_G(last_phar) = fd;
1089 			PHAR_G(last_phar_name) = fd->fname;
1090 			PHAR_G(last_phar_name_len) = fd->fname_len;
1091 			PHAR_G(last_alias) = fd->alias;
1092 			PHAR_G(last_alias_len) = fd->alias_len;
1093 
1094 			return SUCCESS;
1095 		}
1096 
1097 		if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), save, save_len))) {
1098 			fd = *archive = fd_ptr;
1099 
1100 			PHAR_G(last_phar) = fd;
1101 			PHAR_G(last_phar_name) = fd->fname;
1102 			PHAR_G(last_phar_name_len) = fd->fname_len;
1103 			PHAR_G(last_alias) = fd->alias;
1104 			PHAR_G(last_alias_len) = fd->alias_len;
1105 
1106 			return SUCCESS;
1107 		}
1108 
1109 		if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_alias, save, save_len))) {
1110 			fd = *archive = fd_ptr;
1111 
1112 			PHAR_G(last_phar) = fd;
1113 			PHAR_G(last_phar_name) = fd->fname;
1114 			PHAR_G(last_phar_name_len) = fd->fname_len;
1115 			PHAR_G(last_alias) = fd->alias;
1116 			PHAR_G(last_alias_len) = fd->alias_len;
1117 
1118 			return SUCCESS;
1119 		}
1120 
1121 		/* not found, try converting \ to / */
1122 		my_realpath = expand_filepath(fname, my_realpath);
1123 
1124 		if (my_realpath) {
1125 			fname_len = strlen(my_realpath);
1126 			fname = my_realpath;
1127 		} else {
1128 			return FAILURE;
1129 		}
1130 #ifdef PHP_WIN32
1131 		phar_unixify_path_separators(fname, fname_len);
1132 #endif
1133 
1134 		if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), fname, fname_len))) {
1135 realpath_success:
1136 			*archive = fd_ptr;
1137 			fd = fd_ptr;
1138 
1139 			if (alias && alias_len) {
1140 				zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, fd);
1141 			}
1142 
1143 			efree(my_realpath);
1144 
1145 			PHAR_G(last_phar) = fd;
1146 			PHAR_G(last_phar_name) = fd->fname;
1147 			PHAR_G(last_phar_name_len) = fd->fname_len;
1148 			PHAR_G(last_alias) = fd->alias;
1149 			PHAR_G(last_alias_len) = fd->alias_len;
1150 
1151 			return SUCCESS;
1152 		}
1153 
1154 		if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_phars, fname, fname_len))) {
1155 			goto realpath_success;
1156 		}
1157 
1158 		efree(my_realpath);
1159 	}
1160 
1161 	return FAILURE;
1162 }
1163 /* }}} */
1164 
1165 /**
1166  * Determine which stream compression filter (if any) we need to read this file
1167  */
phar_compress_filter(phar_entry_info * entry,int return_unknown)1168 char * phar_compress_filter(phar_entry_info * entry, int return_unknown) /* {{{ */
1169 {
1170 	switch (entry->flags & PHAR_ENT_COMPRESSION_MASK) {
1171 	case PHAR_ENT_COMPRESSED_GZ:
1172 		return "zlib.deflate";
1173 	case PHAR_ENT_COMPRESSED_BZ2:
1174 		return "bzip2.compress";
1175 	default:
1176 		return return_unknown ? "unknown" : NULL;
1177 	}
1178 }
1179 /* }}} */
1180 
1181 /**
1182  * Determine which stream decompression filter (if any) we need to read this file
1183  */
phar_decompress_filter(phar_entry_info * entry,int return_unknown)1184 char * phar_decompress_filter(phar_entry_info * entry, int return_unknown) /* {{{ */
1185 {
1186 	uint32_t flags;
1187 
1188 	if (entry->is_modified) {
1189 		flags = entry->old_flags;
1190 	} else {
1191 		flags = entry->flags;
1192 	}
1193 
1194 	switch (flags & PHAR_ENT_COMPRESSION_MASK) {
1195 		case PHAR_ENT_COMPRESSED_GZ:
1196 			return "zlib.inflate";
1197 		case PHAR_ENT_COMPRESSED_BZ2:
1198 			return "bzip2.decompress";
1199 		default:
1200 			return return_unknown ? "unknown" : NULL;
1201 	}
1202 }
1203 /* }}} */
1204 
1205 /**
1206  * retrieve information on a file contained within a phar, or null if it ain't there
1207  */
phar_get_entry_info(phar_archive_data * phar,char * path,size_t path_len,char ** error,int security)1208 phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, size_t path_len, char **error, int security) /* {{{ */
1209 {
1210 	return phar_get_entry_info_dir(phar, path, path_len, 0, error, security);
1211 }
1212 /* }}} */
1213 /**
1214  * retrieve information on a file or directory contained within a phar, or null if none found
1215  * allow_dir is 0 for none, 1 for both empty directories in the phar and temp directories, and 2 for only
1216  * valid pre-existing empty directory entries
1217  */
phar_get_entry_info_dir(phar_archive_data * phar,char * path,size_t path_len,char dir,char ** error,int security)1218 phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, size_t path_len, char dir, char **error, int security) /* {{{ */
1219 {
1220 	const char *pcr_error;
1221 	phar_entry_info *entry;
1222 	int is_dir;
1223 
1224 #ifdef PHP_WIN32
1225 	phar_unixify_path_separators(path, path_len);
1226 #endif
1227 
1228 	is_dir = (path_len && (path[path_len - 1] == '/')) ? 1 : 0;
1229 
1230 	if (error) {
1231 		*error = NULL;
1232 	}
1233 
1234 	if (security && path_len >= sizeof(".phar")-1 && !memcmp(path, ".phar", sizeof(".phar")-1)) {
1235 		if (error) {
1236 			spprintf(error, 4096, "phar error: cannot directly access magic \".phar\" directory or files within it");
1237 		}
1238 		return NULL;
1239 	}
1240 
1241 	if (!path_len && !dir) {
1242 		if (error) {
1243 			spprintf(error, 4096, "phar error: invalid path \"%s\" must not be empty", path);
1244 		}
1245 		return NULL;
1246 	}
1247 
1248 	if (phar_path_check(&path, &path_len, &pcr_error) > pcr_is_ok) {
1249 		if (error) {
1250 			spprintf(error, 4096, "phar error: invalid path \"%s\" contains %s", path, pcr_error);
1251 		}
1252 		return NULL;
1253 	}
1254 
1255 	if (!HT_IS_INITIALIZED(&phar->manifest)) {
1256 		return NULL;
1257 	}
1258 
1259 	if (is_dir) {
1260 		if (path_len <= 1) {
1261 			return NULL;
1262 		}
1263 		path_len--;
1264 	}
1265 
1266 	if (NULL != (entry = zend_hash_str_find_ptr(&phar->manifest, path, path_len))) {
1267 		if (entry->is_deleted) {
1268 			/* entry is deleted, but has not been flushed to disk yet */
1269 			return NULL;
1270 		}
1271 		if (entry->is_dir && !dir) {
1272 			if (error) {
1273 				spprintf(error, 4096, "phar error: path \"%s\" is a directory", path);
1274 			}
1275 			return NULL;
1276 		}
1277 		if (!entry->is_dir && dir == 2) {
1278 			/* user requested a directory, we must return one */
1279 			if (error) {
1280 				spprintf(error, 4096, "phar error: path \"%s\" exists and is a not a directory", path);
1281 			}
1282 			return NULL;
1283 		}
1284 		return entry;
1285 	}
1286 
1287 	if (dir) {
1288 		if (zend_hash_str_exists(&phar->virtual_dirs, path, path_len)) {
1289 			/* a file or directory exists in a sub-directory of this path */
1290 			entry = (phar_entry_info *) ecalloc(1, sizeof(phar_entry_info));
1291 			/* this next line tells PharFileInfo->__destruct() to efree the filename */
1292 			entry->is_temp_dir = entry->is_dir = 1;
1293 			entry->filename = (char *) estrndup(path, path_len + 1);
1294 			entry->filename_len = path_len;
1295 			entry->phar = phar;
1296 			return entry;
1297 		}
1298 	}
1299 
1300 	if (HT_IS_INITIALIZED(&phar->mounted_dirs) && zend_hash_num_elements(&phar->mounted_dirs)) {
1301 		zend_string *str_key;
1302 
1303 		ZEND_HASH_MAP_FOREACH_STR_KEY(&phar->mounted_dirs, str_key) {
1304 			if (ZSTR_LEN(str_key) >= path_len || strncmp(ZSTR_VAL(str_key), path, ZSTR_LEN(str_key))) {
1305 				continue;
1306 			} else {
1307 				char *test;
1308 				size_t test_len;
1309 				php_stream_statbuf ssb;
1310 
1311 				if (NULL == (entry = zend_hash_find_ptr(&phar->manifest, str_key))) {
1312 					if (error) {
1313 						spprintf(error, 4096, "phar internal error: mounted path \"%s\" could not be retrieved from manifest", ZSTR_VAL(str_key));
1314 					}
1315 					return NULL;
1316 				}
1317 
1318 				if (!entry->tmp || !entry->is_mounted) {
1319 					if (error) {
1320 						spprintf(error, 4096, "phar internal error: mounted path \"%s\" is not properly initialized as a mounted path", ZSTR_VAL(str_key));
1321 					}
1322 					return NULL;
1323 				}
1324 
1325 				test_len = spprintf(&test, MAXPATHLEN, "%s%s", entry->tmp, path + ZSTR_LEN(str_key));
1326 
1327 				if (SUCCESS != php_stream_stat_path(test, &ssb)) {
1328 					efree(test);
1329 					return NULL;
1330 				}
1331 
1332 				if ((ssb.sb.st_mode & S_IFDIR) && !dir) {
1333 					efree(test);
1334 					if (error) {
1335 						spprintf(error, 4096, "phar error: path \"%s\" is a directory", path);
1336 					}
1337 					return NULL;
1338 				}
1339 
1340 				if ((ssb.sb.st_mode & S_IFDIR) == 0 && dir) {
1341 					efree(test);
1342 					/* user requested a directory, we must return one */
1343 					if (error) {
1344 						spprintf(error, 4096, "phar error: path \"%s\" exists and is a not a directory", path);
1345 					}
1346 					return NULL;
1347 				}
1348 
1349 				/* mount the file just in time */
1350 				if (SUCCESS != phar_mount_entry(phar, test, test_len, path, path_len)) {
1351 					efree(test);
1352 					if (error) {
1353 						spprintf(error, 4096, "phar error: path \"%s\" exists as file \"%s\" and could not be mounted", path, test);
1354 					}
1355 					return NULL;
1356 				}
1357 
1358 				efree(test);
1359 
1360 				if (NULL == (entry = zend_hash_str_find_ptr(&phar->manifest, path, path_len))) {
1361 					if (error) {
1362 						spprintf(error, 4096, "phar error: path \"%s\" exists as file \"%s\" and could not be retrieved after being mounted", path, test);
1363 					}
1364 					return NULL;
1365 				}
1366 				return entry;
1367 			}
1368 		} ZEND_HASH_FOREACH_END();
1369 	}
1370 
1371 	return NULL;
1372 }
1373 /* }}} */
1374 
1375 static const char hexChars[] = "0123456789ABCDEF";
1376 
phar_hex_str(const char * digest,size_t digest_len,char ** signature)1377 static int phar_hex_str(const char *digest, size_t digest_len, char **signature) /* {{{ */
1378 {
1379 	int pos = -1;
1380 	size_t len = 0;
1381 
1382 	*signature = (char*)safe_pemalloc(digest_len, 2, 1, PHAR_G(persist));
1383 
1384 	for (; len < digest_len; ++len) {
1385 		(*signature)[++pos] = hexChars[((const unsigned char *)digest)[len] >> 4];
1386 		(*signature)[++pos] = hexChars[((const unsigned char *)digest)[len] & 0x0F];
1387 	}
1388 	(*signature)[++pos] = '\0';
1389 	return pos;
1390 }
1391 /* }}} */
1392 
1393 #ifndef PHAR_HAVE_OPENSSL
phar_call_openssl_signverify(int is_sign,php_stream * fp,zend_off_t end,char * key,size_t key_len,char ** signature,size_t * signature_len,php_uint32 sig_type)1394 static int phar_call_openssl_signverify(int is_sign, php_stream *fp, zend_off_t end, char *key, size_t key_len, char **signature, size_t *signature_len, php_uint32 sig_type) /* {{{ */
1395 {
1396 	zend_fcall_info fci;
1397 	zend_fcall_info_cache fcc;
1398 	zval retval, zp[4], openssl;
1399 	zend_string *str;
1400 
1401 	ZVAL_STRINGL(&openssl, is_sign ? "openssl_sign" : "openssl_verify", is_sign ? sizeof("openssl_sign")-1 : sizeof("openssl_verify")-1);
1402 	if (*signature_len) {
1403 		ZVAL_STRINGL(&zp[1], *signature, *signature_len);
1404 	} else {
1405 		ZVAL_EMPTY_STRING(&zp[1]);
1406 	}
1407 	ZVAL_STRINGL(&zp[2], key, key_len);
1408 	php_stream_rewind(fp);
1409 	str = php_stream_copy_to_mem(fp, (size_t) end, 0);
1410 	if (str) {
1411 		ZVAL_STR(&zp[0], str);
1412 	} else {
1413 		ZVAL_EMPTY_STRING(&zp[0]);
1414 	}
1415 	if (sig_type == PHAR_SIG_OPENSSL_SHA512) {
1416 		ZVAL_LONG(&zp[3], 9); /* value from openssl.c #define OPENSSL_ALGO_SHA512 9 */
1417 	} else if (sig_type == PHAR_SIG_OPENSSL_SHA256) {
1418 		ZVAL_LONG(&zp[3], 7); /* value from openssl.c #define OPENSSL_ALGO_SHA256 7 */
1419 	} else {
1420 		/* don't rely on default value which may change in the future */
1421 		ZVAL_LONG(&zp[3], 1); /* value from openssl.c #define OPENSSL_ALGO_SHA1   1 */
1422 	}
1423 
1424 	if ((size_t)end != Z_STRLEN(zp[0])) {
1425 		zval_ptr_dtor_str(&zp[0]);
1426 		zval_ptr_dtor_str(&zp[1]);
1427 		zval_ptr_dtor_str(&zp[2]);
1428 		zval_ptr_dtor_str(&openssl);
1429 		return FAILURE;
1430 	}
1431 
1432 	if (FAILURE == zend_fcall_info_init(&openssl, 0, &fci, &fcc, NULL, NULL)) {
1433 		zval_ptr_dtor_str(&zp[0]);
1434 		zval_ptr_dtor_str(&zp[1]);
1435 		zval_ptr_dtor_str(&zp[2]);
1436 		zval_ptr_dtor_str(&openssl);
1437 		return FAILURE;
1438 	}
1439 
1440 	fci.param_count = 4;
1441 	fci.params = zp;
1442 	Z_ADDREF(zp[0]);
1443 	if (is_sign) {
1444 		ZVAL_NEW_REF(&zp[1], &zp[1]);
1445 	} else {
1446 		Z_ADDREF(zp[1]);
1447 	}
1448 	Z_ADDREF(zp[2]);
1449 
1450 	fci.retval = &retval;
1451 
1452 	if (FAILURE == zend_call_function(&fci, &fcc)) {
1453 		zval_ptr_dtor_str(&zp[0]);
1454 		zval_ptr_dtor(&zp[1]);
1455 		zval_ptr_dtor_str(&zp[2]);
1456 		zval_ptr_dtor_str(&openssl);
1457 		return FAILURE;
1458 	}
1459 
1460 	zval_ptr_dtor_str(&openssl);
1461 	Z_DELREF(zp[0]);
1462 
1463 	if (is_sign) {
1464 		ZVAL_UNREF(&zp[1]);
1465 	} else {
1466 		Z_DELREF(zp[1]);
1467 	}
1468 	Z_DELREF(zp[2]);
1469 
1470 	zval_ptr_dtor_str(&zp[0]);
1471 	zval_ptr_dtor_str(&zp[2]);
1472 
1473 	switch (Z_TYPE(retval)) {
1474 		default:
1475 		case IS_LONG:
1476 			zval_ptr_dtor(&zp[1]);
1477 			if (1 == Z_LVAL(retval)) {
1478 				return SUCCESS;
1479 			}
1480 			return FAILURE;
1481 		case IS_TRUE:
1482 			*signature = estrndup(Z_STRVAL(zp[1]), Z_STRLEN(zp[1]));
1483 			*signature_len = Z_STRLEN(zp[1]);
1484 			zval_ptr_dtor(&zp[1]);
1485 			return SUCCESS;
1486 		case IS_FALSE:
1487 			zval_ptr_dtor(&zp[1]);
1488 			return FAILURE;
1489 	}
1490 }
1491 /* }}} */
1492 #endif /* #ifndef PHAR_HAVE_OPENSSL */
1493 
phar_verify_signature(php_stream * fp,size_t end_of_phar,uint32_t sig_type,char * sig,size_t sig_len,char * fname,char ** signature,size_t * signature_len,char ** error)1494 int phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, char *sig, size_t sig_len, char *fname, char **signature, size_t *signature_len, char **error) /* {{{ */
1495 {
1496 	size_t read_size, len;
1497 	zend_off_t read_len;
1498 	unsigned char buf[1024];
1499 
1500 	php_stream_rewind(fp);
1501 
1502 	switch (sig_type) {
1503 		case PHAR_SIG_OPENSSL_SHA512:
1504 		case PHAR_SIG_OPENSSL_SHA256:
1505 		case PHAR_SIG_OPENSSL: {
1506 #ifdef PHAR_HAVE_OPENSSL
1507 			BIO *in;
1508 			EVP_PKEY *key;
1509 			const EVP_MD *mdtype;
1510 			EVP_MD_CTX *md_ctx;
1511 
1512 			if (sig_type == PHAR_SIG_OPENSSL_SHA512) {
1513 				mdtype = EVP_sha512();
1514 			} else if (sig_type == PHAR_SIG_OPENSSL_SHA256) {
1515 				mdtype = EVP_sha256();
1516 			} else {
1517 				mdtype = EVP_sha1();
1518 			}
1519 #else
1520 			size_t tempsig;
1521 #endif
1522 			zend_string *pubkey = NULL;
1523 			char *pfile;
1524 			php_stream *pfp;
1525 #ifndef PHAR_HAVE_OPENSSL
1526 			if (!zend_hash_str_exists(&module_registry, "openssl", sizeof("openssl")-1)) {
1527 				if (error) {
1528 					spprintf(error, 0, "openssl not loaded");
1529 				}
1530 				return FAILURE;
1531 			}
1532 #endif
1533 			/* use __FILE__ . '.pubkey' for public key file */
1534 			spprintf(&pfile, 0, "%s.pubkey", fname);
1535 			pfp = php_stream_open_wrapper(pfile, "rb", 0, NULL);
1536 			efree(pfile);
1537 
1538 			if (!pfp || !(pubkey = php_stream_copy_to_mem(pfp, PHP_STREAM_COPY_ALL, 0)) || !ZSTR_LEN(pubkey)) {
1539 				if (pfp) {
1540 					php_stream_close(pfp);
1541 				}
1542 				if (error) {
1543 					spprintf(error, 0, "openssl public key could not be read");
1544 				}
1545 				return FAILURE;
1546 			}
1547 
1548 			php_stream_close(pfp);
1549 #ifndef PHAR_HAVE_OPENSSL
1550 			tempsig = sig_len;
1551 
1552 			if (FAILURE == phar_call_openssl_signverify(0, fp, end_of_phar, ZSTR_VAL(pubkey), ZSTR_LEN(pubkey), &sig, &tempsig, sig_type)) {
1553 				zend_string_release_ex(pubkey, 0);
1554 
1555 				if (error) {
1556 					spprintf(error, 0, "openssl signature could not be verified");
1557 				}
1558 
1559 				return FAILURE;
1560 			}
1561 
1562 			zend_string_release_ex(pubkey, 0);
1563 
1564 			sig_len = tempsig;
1565 #else
1566 			in = BIO_new_mem_buf(ZSTR_VAL(pubkey), ZSTR_LEN(pubkey));
1567 
1568 			if (NULL == in) {
1569 				zend_string_release_ex(pubkey, 0);
1570 				if (error) {
1571 					spprintf(error, 0, "openssl signature could not be processed");
1572 				}
1573 				return FAILURE;
1574 			}
1575 
1576 			key = PEM_read_bio_PUBKEY(in, NULL, NULL, NULL);
1577 			BIO_free(in);
1578 			zend_string_release_ex(pubkey, 0);
1579 
1580 			if (NULL == key) {
1581 				if (error) {
1582 					spprintf(error, 0, "openssl signature could not be processed");
1583 				}
1584 				return FAILURE;
1585 			}
1586 
1587 			md_ctx = EVP_MD_CTX_create();
1588 			if (!md_ctx || !EVP_VerifyInit(md_ctx, mdtype)) {
1589 				if (md_ctx) {
1590 					EVP_MD_CTX_destroy(md_ctx);
1591 				}
1592 				if (error) {
1593 					spprintf(error, 0, "openssl signature could not be verified");
1594 				}
1595 				return FAILURE;
1596 			}
1597 			read_len = end_of_phar;
1598 
1599 			if ((size_t)read_len > sizeof(buf)) {
1600 				read_size = sizeof(buf);
1601 			} else {
1602 				read_size = (size_t)read_len;
1603 			}
1604 
1605 			php_stream_seek(fp, 0, SEEK_SET);
1606 
1607 			while (read_size && (len = php_stream_read(fp, (char*)buf, read_size)) > 0) {
1608 				if (UNEXPECTED(EVP_VerifyUpdate (md_ctx, buf, len) == 0)) {
1609 					goto failure;
1610 				}
1611 				read_len -= (zend_off_t)len;
1612 
1613 				if (read_len < read_size) {
1614 					read_size = (size_t)read_len;
1615 				}
1616 			}
1617 
1618 			if (EVP_VerifyFinal(md_ctx, (unsigned char *)sig, sig_len, key) != 1) {
1619 				failure:
1620 				/* 1: signature verified, 0: signature does not match, -1: failed signature operation */
1621 				EVP_PKEY_free(key);
1622 				EVP_MD_CTX_destroy(md_ctx);
1623 
1624 				if (error) {
1625 					spprintf(error, 0, "broken openssl signature");
1626 				}
1627 
1628 				return FAILURE;
1629 			}
1630 
1631 			EVP_PKEY_free(key);
1632 			EVP_MD_CTX_destroy(md_ctx);
1633 #endif
1634 
1635 			*signature_len = phar_hex_str((const char*)sig, sig_len, signature);
1636 		}
1637 		break;
1638 		case PHAR_SIG_SHA512: {
1639 			unsigned char digest[64];
1640 			PHP_SHA512_CTX context;
1641 
1642 			if (sig_len < sizeof(digest)) {
1643 				if (error) {
1644 					spprintf(error, 0, "broken signature");
1645 				}
1646 				return FAILURE;
1647 			}
1648 
1649 			PHP_SHA512Init(&context);
1650 			read_len = end_of_phar;
1651 
1652 			if ((size_t)read_len > sizeof(buf)) {
1653 				read_size = sizeof(buf);
1654 			} else {
1655 				read_size = (size_t)read_len;
1656 			}
1657 
1658 			while ((len = php_stream_read(fp, (char*)buf, read_size)) > 0) {
1659 				PHP_SHA512Update(&context, buf, len);
1660 				read_len -= (zend_off_t)len;
1661 				if ((size_t)read_len < read_size) {
1662 					read_size = (size_t)read_len;
1663 				}
1664 			}
1665 
1666 			PHP_SHA512Final(digest, &context);
1667 
1668 			if (memcmp(digest, sig, sizeof(digest))) {
1669 				if (error) {
1670 					spprintf(error, 0, "broken signature");
1671 				}
1672 				return FAILURE;
1673 			}
1674 
1675 			*signature_len = phar_hex_str((const char*)digest, sizeof(digest), signature);
1676 			break;
1677 		}
1678 		case PHAR_SIG_SHA256: {
1679 			unsigned char digest[32];
1680 			PHP_SHA256_CTX context;
1681 
1682 			if (sig_len < sizeof(digest)) {
1683 				if (error) {
1684 					spprintf(error, 0, "broken signature");
1685 				}
1686 				return FAILURE;
1687 			}
1688 
1689 			PHP_SHA256Init(&context);
1690 			read_len = end_of_phar;
1691 
1692 			if ((size_t)read_len > sizeof(buf)) {
1693 				read_size = sizeof(buf);
1694 			} else {
1695 				read_size = (size_t)read_len;
1696 			}
1697 
1698 			while ((len = php_stream_read(fp, (char*)buf, read_size)) > 0) {
1699 				PHP_SHA256Update(&context, buf, len);
1700 				read_len -= (zend_off_t)len;
1701 				if ((size_t)read_len < read_size) {
1702 					read_size = (size_t)read_len;
1703 				}
1704 			}
1705 
1706 			PHP_SHA256Final(digest, &context);
1707 
1708 			if (memcmp(digest, sig, sizeof(digest))) {
1709 				if (error) {
1710 					spprintf(error, 0, "broken signature");
1711 				}
1712 				return FAILURE;
1713 			}
1714 
1715 			*signature_len = phar_hex_str((const char*)digest, sizeof(digest), signature);
1716 			break;
1717 		}
1718 		case PHAR_SIG_SHA1: {
1719 			unsigned char digest[20];
1720 			PHP_SHA1_CTX  context;
1721 
1722 			if (sig_len < sizeof(digest)) {
1723 				if (error) {
1724 					spprintf(error, 0, "broken signature");
1725 				}
1726 				return FAILURE;
1727 			}
1728 
1729 			PHP_SHA1Init(&context);
1730 			read_len = end_of_phar;
1731 
1732 			if ((size_t)read_len > sizeof(buf)) {
1733 				read_size = sizeof(buf);
1734 			} else {
1735 				read_size = (size_t)read_len;
1736 			}
1737 
1738 			while ((len = php_stream_read(fp, (char*)buf, read_size)) > 0) {
1739 				PHP_SHA1Update(&context, buf, len);
1740 				read_len -= (zend_off_t)len;
1741 				if ((size_t)read_len < read_size) {
1742 					read_size = (size_t)read_len;
1743 				}
1744 			}
1745 
1746 			PHP_SHA1Final(digest, &context);
1747 
1748 			if (memcmp(digest, sig, sizeof(digest))) {
1749 				if (error) {
1750 					spprintf(error, 0, "broken signature");
1751 				}
1752 				return FAILURE;
1753 			}
1754 
1755 			*signature_len = phar_hex_str((const char*)digest, sizeof(digest), signature);
1756 			break;
1757 		}
1758 		case PHAR_SIG_MD5: {
1759 			unsigned char digest[16];
1760 			PHP_MD5_CTX   context;
1761 
1762 			if (sig_len < sizeof(digest)) {
1763 				if (error) {
1764 					spprintf(error, 0, "broken signature");
1765 				}
1766 				return FAILURE;
1767 			}
1768 
1769 			PHP_MD5Init(&context);
1770 			read_len = end_of_phar;
1771 
1772 			if ((size_t)read_len > sizeof(buf)) {
1773 				read_size = sizeof(buf);
1774 			} else {
1775 				read_size = (size_t)read_len;
1776 			}
1777 
1778 			while ((len = php_stream_read(fp, (char*)buf, read_size)) > 0) {
1779 				PHP_MD5Update(&context, buf, len);
1780 				read_len -= (zend_off_t)len;
1781 				if ((size_t)read_len < read_size) {
1782 					read_size = (size_t)read_len;
1783 				}
1784 			}
1785 
1786 			PHP_MD5Final(digest, &context);
1787 
1788 			if (memcmp(digest, sig, sizeof(digest))) {
1789 				if (error) {
1790 					spprintf(error, 0, "broken signature");
1791 				}
1792 				return FAILURE;
1793 			}
1794 
1795 			*signature_len = phar_hex_str((const char*)digest, sizeof(digest), signature);
1796 			break;
1797 		}
1798 		default:
1799 			if (error) {
1800 				spprintf(error, 0, "broken or unsupported signature");
1801 			}
1802 			return FAILURE;
1803 	}
1804 	return SUCCESS;
1805 }
1806 /* }}} */
1807 
phar_create_signature(phar_archive_data * phar,php_stream * fp,char ** signature,size_t * signature_length,char ** error)1808 int phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, size_t *signature_length, char **error) /* {{{ */
1809 {
1810 	unsigned char buf[1024];
1811 	size_t sig_len;
1812 
1813 	php_stream_rewind(fp);
1814 
1815 	if (phar->signature) {
1816 		efree(phar->signature);
1817 		phar->signature = NULL;
1818 	}
1819 
1820 	switch(phar->sig_flags) {
1821 		case PHAR_SIG_SHA512: {
1822 			unsigned char digest[64];
1823 			PHP_SHA512_CTX context;
1824 
1825 			PHP_SHA512Init(&context);
1826 
1827 			while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) {
1828 				PHP_SHA512Update(&context, buf, sig_len);
1829 			}
1830 
1831 			PHP_SHA512Final(digest, &context);
1832 			*signature = estrndup((char *) digest, 64);
1833 			*signature_length = 64;
1834 			break;
1835 		}
1836 		default:
1837 			phar->sig_flags = PHAR_SIG_SHA256;
1838 			ZEND_FALLTHROUGH;
1839 		case PHAR_SIG_SHA256: {
1840 			unsigned char digest[32];
1841 			PHP_SHA256_CTX  context;
1842 
1843 			PHP_SHA256Init(&context);
1844 
1845 			while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) {
1846 				PHP_SHA256Update(&context, buf, sig_len);
1847 			}
1848 
1849 			PHP_SHA256Final(digest, &context);
1850 			*signature = estrndup((char *) digest, 32);
1851 			*signature_length = 32;
1852 			break;
1853 		}
1854 		case PHAR_SIG_OPENSSL_SHA512:
1855 		case PHAR_SIG_OPENSSL_SHA256:
1856 		case PHAR_SIG_OPENSSL: {
1857 			unsigned char *sigbuf;
1858 #ifdef PHAR_HAVE_OPENSSL
1859 			unsigned int siglen;
1860 			BIO *in;
1861 			EVP_PKEY *key;
1862 			EVP_MD_CTX *md_ctx;
1863 			const EVP_MD *mdtype;
1864 
1865 			if (phar->sig_flags == PHAR_SIG_OPENSSL_SHA512) {
1866 				mdtype = EVP_sha512();
1867 			} else if (phar->sig_flags == PHAR_SIG_OPENSSL_SHA256) {
1868 				mdtype = EVP_sha256();
1869 			} else {
1870 				mdtype = EVP_sha1();
1871 			}
1872 
1873 			in = BIO_new_mem_buf(PHAR_G(openssl_privatekey), PHAR_G(openssl_privatekey_len));
1874 
1875 			if (in == NULL) {
1876 				if (error) {
1877 					spprintf(error, 0, "unable to write to phar \"%s\" with requested openssl signature", phar->fname);
1878 				}
1879 				return FAILURE;
1880 			}
1881 
1882 			key = PEM_read_bio_PrivateKey(in, NULL,NULL, "");
1883 			BIO_free(in);
1884 
1885 			if (!key) {
1886 				if (error) {
1887 					spprintf(error, 0, "unable to process private key");
1888 				}
1889 				return FAILURE;
1890 			}
1891 
1892 			md_ctx = EVP_MD_CTX_create();
1893 			if (md_ctx == NULL) {
1894 				EVP_PKEY_free(key);
1895 				if (error) {
1896 					spprintf(error, 0, "unable to initialize openssl signature for phar \"%s\"", phar->fname);
1897 				}
1898 				return FAILURE;
1899 			}
1900 
1901 			siglen = EVP_PKEY_size(key);
1902 			sigbuf = emalloc(siglen + 1);
1903 
1904 			if (!EVP_SignInit(md_ctx, mdtype)) {
1905 				EVP_PKEY_free(key);
1906 				efree(sigbuf);
1907 				if (error) {
1908 					spprintf(error, 0, "unable to initialize openssl signature for phar \"%s\"", phar->fname);
1909 				}
1910 				return FAILURE;
1911 			}
1912 
1913 			while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) {
1914 				if (!EVP_SignUpdate(md_ctx, buf, sig_len)) {
1915 					EVP_PKEY_free(key);
1916 					efree(sigbuf);
1917 					if (error) {
1918 						spprintf(error, 0, "unable to update the openssl signature for phar \"%s\"", phar->fname);
1919 					}
1920 					return FAILURE;
1921 				}
1922 			}
1923 
1924 			if (!EVP_SignFinal (md_ctx, sigbuf, &siglen, key)) {
1925 				EVP_PKEY_free(key);
1926 				efree(sigbuf);
1927 				if (error) {
1928 					spprintf(error, 0, "unable to write phar \"%s\" with requested openssl signature", phar->fname);
1929 				}
1930 				return FAILURE;
1931 			}
1932 
1933 			sigbuf[siglen] = '\0';
1934 			EVP_PKEY_free(key);
1935 			EVP_MD_CTX_destroy(md_ctx);
1936 #else
1937 			size_t siglen;
1938 			sigbuf = NULL;
1939 			siglen = 0;
1940 			php_stream_seek(fp, 0, SEEK_END);
1941 
1942 			if (FAILURE == phar_call_openssl_signverify(1, fp, php_stream_tell(fp), PHAR_G(openssl_privatekey), PHAR_G(openssl_privatekey_len), (char **)&sigbuf, &siglen, phar->sig_flags)) {
1943 				if (error) {
1944 					spprintf(error, 0, "unable to write phar \"%s\" with requested openssl signature", phar->fname);
1945 				}
1946 				return FAILURE;
1947 			}
1948 #endif
1949 			*signature = (char *) sigbuf;
1950 			*signature_length = siglen;
1951 		}
1952 		break;
1953 		case PHAR_SIG_SHA1: {
1954 			unsigned char digest[20];
1955 			PHP_SHA1_CTX  context;
1956 
1957 			PHP_SHA1Init(&context);
1958 
1959 			while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) {
1960 				PHP_SHA1Update(&context, buf, sig_len);
1961 			}
1962 
1963 			PHP_SHA1Final(digest, &context);
1964 			*signature = estrndup((char *) digest, 20);
1965 			*signature_length = 20;
1966 			break;
1967 		}
1968 		case PHAR_SIG_MD5: {
1969 			unsigned char digest[16];
1970 			PHP_MD5_CTX   context;
1971 
1972 			PHP_MD5Init(&context);
1973 
1974 			while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) {
1975 				PHP_MD5Update(&context, buf, sig_len);
1976 			}
1977 
1978 			PHP_MD5Final(digest, &context);
1979 			*signature = estrndup((char *) digest, 16);
1980 			*signature_length = 16;
1981 			break;
1982 		}
1983 	}
1984 
1985 	phar->sig_len = phar_hex_str((const char *)*signature, *signature_length, &phar->signature);
1986 	return SUCCESS;
1987 }
1988 /* }}} */
1989 
phar_add_virtual_dirs(phar_archive_data * phar,char * filename,size_t filename_len)1990 void phar_add_virtual_dirs(phar_archive_data *phar, char *filename, size_t filename_len) /* {{{ */
1991 {
1992 	const char *s;
1993 	zend_string *str;
1994 	zval *ret;
1995 
1996 	while ((s = zend_memrchr(filename, '/', filename_len))) {
1997 		filename_len = s - filename;
1998 		if (!filename_len) {
1999 			break;
2000 		}
2001 		if (GC_FLAGS(&phar->virtual_dirs) & GC_PERSISTENT) {
2002 			str = zend_string_init_interned(filename, filename_len, 1);
2003 		} else {
2004 			str = zend_string_init(filename, filename_len, 0);
2005 		}
2006 		ret = zend_hash_add_empty_element(&phar->virtual_dirs, str);
2007 		zend_string_release(str);
2008 		if (ret == NULL) {
2009 			break;
2010 		}
2011 	}
2012 }
2013 /* }}} */
2014 
phar_update_cached_entry(zval * data,void * argument)2015 static int phar_update_cached_entry(zval *data, void *argument) /* {{{ */
2016 {
2017 	phar_entry_info *entry = (phar_entry_info *)Z_PTR_P(data);
2018 
2019 	entry->phar = (phar_archive_data *)argument;
2020 
2021 	if (entry->link) {
2022 		entry->link = estrdup(entry->link);
2023 	}
2024 
2025 	if (entry->tmp) {
2026 		entry->tmp = estrdup(entry->tmp);
2027 	}
2028 
2029 	entry->filename = estrndup(entry->filename, entry->filename_len);
2030 	entry->is_persistent = 0;
2031 
2032 	/* Replace metadata with non-persistent clones of the metadata. */
2033 	phar_metadata_tracker_clone(&entry->metadata_tracker);
2034 	return ZEND_HASH_APPLY_KEEP;
2035 }
2036 /* }}} */
2037 
phar_manifest_copy_ctor(zval * zv)2038 static void phar_manifest_copy_ctor(zval *zv) /* {{{ */
2039 {
2040 	phar_entry_info *info = emalloc(sizeof(phar_entry_info));
2041 	memcpy(info, Z_PTR_P(zv), sizeof(phar_entry_info));
2042 	Z_PTR_P(zv) = info;
2043 }
2044 /* }}} */
2045 
phar_copy_cached_phar(phar_archive_data ** pphar)2046 static void phar_copy_cached_phar(phar_archive_data **pphar) /* {{{ */
2047 {
2048 	phar_archive_data *phar;
2049 	HashTable newmanifest;
2050 	char *fname;
2051 	phar_archive_object *objphar;
2052 
2053 	phar = (phar_archive_data *) emalloc(sizeof(phar_archive_data));
2054 	*phar = **pphar;
2055 	phar->is_persistent = 0;
2056 	fname = phar->fname;
2057 	phar->fname = estrndup(phar->fname, phar->fname_len);
2058 	phar->ext = phar->fname + (phar->ext - fname);
2059 
2060 	if (phar->alias) {
2061 		phar->alias = estrndup(phar->alias, phar->alias_len);
2062 	}
2063 
2064 	if (phar->signature) {
2065 		phar->signature = estrdup(phar->signature);
2066 	}
2067 
2068 	phar_metadata_tracker_clone(&phar->metadata_tracker);
2069 
2070 	zend_hash_init(&newmanifest, sizeof(phar_entry_info),
2071 		zend_get_hash_value, destroy_phar_manifest_entry, 0);
2072 	zend_hash_copy(&newmanifest, &(*pphar)->manifest, phar_manifest_copy_ctor);
2073 	zend_hash_apply_with_argument(&newmanifest, phar_update_cached_entry, (void *)phar);
2074 	phar->manifest = newmanifest;
2075 	zend_hash_init(&phar->mounted_dirs, sizeof(char *),
2076 		zend_get_hash_value, NULL, 0);
2077 	zend_hash_init(&phar->virtual_dirs, sizeof(char *),
2078 		zend_get_hash_value, NULL, 0);
2079 	zend_hash_copy(&phar->virtual_dirs, &(*pphar)->virtual_dirs, NULL);
2080 	*pphar = phar;
2081 
2082 	/* now, scan the list of persistent Phar objects referencing this phar and update the pointers */
2083 	ZEND_HASH_MAP_FOREACH_PTR(&PHAR_G(phar_persist_map), objphar) {
2084 		if (objphar->archive->fname_len == phar->fname_len && !memcmp(objphar->archive->fname, phar->fname, phar->fname_len)) {
2085 			objphar->archive = phar;
2086 		}
2087 	} ZEND_HASH_FOREACH_END();
2088 }
2089 /* }}} */
2090 
phar_copy_on_write(phar_archive_data ** pphar)2091 int phar_copy_on_write(phar_archive_data **pphar) /* {{{ */
2092 {
2093 	zval zv, *pzv;
2094 	phar_archive_data *newpphar;
2095 
2096 	ZVAL_PTR(&zv, *pphar);
2097 	if (NULL == (pzv = zend_hash_str_add(&(PHAR_G(phar_fname_map)), (*pphar)->fname, (*pphar)->fname_len, &zv))) {
2098 		return FAILURE;
2099 	}
2100 
2101 	phar_copy_cached_phar((phar_archive_data **)&Z_PTR_P(pzv));
2102 	newpphar = Z_PTR_P(pzv);
2103 	/* invalidate phar cache */
2104 	PHAR_G(last_phar) = NULL;
2105 	PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL;
2106 
2107 	if (newpphar->alias_len && NULL == zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), newpphar->alias, newpphar->alias_len, newpphar)) {
2108 		zend_hash_str_del(&(PHAR_G(phar_fname_map)), (*pphar)->fname, (*pphar)->fname_len);
2109 		return FAILURE;
2110 	}
2111 
2112 	*pphar = newpphar;
2113 	return SUCCESS;
2114 }
2115 /* }}} */
2116