util.c 57 KB

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