diff --git a/Makefile b/Makefile index dd93338..6bc7c50 100644 --- a/Makefile +++ b/Makefile @@ -63,3 +63,7 @@ test-telegram: test-coverage: docker compose exec -w /module/oc_telegram_shop/upload/oc_telegram_shop web bash -c "./vendor/bin/phpunit --coverage-html coverage tests/" + +phar: + docker build -t telecart_local_build -f ./docker/build.dockerfile . && \ + docker run -v "./src/upload/system/library/oc_telegram_shop:/build" telecart_local_build sh -c 'sh /scripts/build_phar.sh' \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index 7fb4af4..694eabb 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -6,6 +6,7 @@ services: - "./src:/web" - "./scripts:/scripts" - "./module:/module" + - "./build:/build" - "/Users/nikitakiselev/code/msvlad.com/image/catalog/products:/web/upload/image/catalog/products" ports: - "8000:80" diff --git a/docker/build.dockerfile b/docker/build.dockerfile index 2abd8ff..86850cc 100644 --- a/docker/build.dockerfile +++ b/docker/build.dockerfile @@ -1,11 +1,15 @@ -FROM node:latest +FROM php:7.4-alpine -RUN apt update && apt install -y zip -RUN mkdir -p /app -COPY ./frontend /app/frontend -COPY ./module /app/module -COPY ./scripts/build.sh /app/scripts/build.sh +RUN apk update +RUN apk add git -WORKDIR /app +RUN mkdir -p /usr/local && \ + cd /usr/local && git clone https://github.com/pk-fr/yakpro-po.git && \ + cd yakpro-po && git clone https://github.com/nikic/PHP-Parser.git --branch 4.x && \ + chmod a+x yakpro-po.php && \ + ln -s /usr/local/yakpro-po/yakpro-po.php /usr/local/bin/yakpro-po -CMD ["./scripts/build.sh"] +COPY ./docker/config.php /usr/local/yakpro-po + +COPY ./module/oc_telegram_shop/upload/oc_telegram_shop /app +COPY ./scripts /scripts diff --git a/docker/config.php b/docker/config.php new file mode 100644 index 0000000..faadc57 --- /dev/null +++ b/docker/config.php @@ -0,0 +1,100 @@ +t_ignore_pre_defined_classes = 'all'; // 'all' (default value) , 'none', or array of pre-defined classes that you use in your software: +// ex: array('Exception', 'PDO', 'PDOStatement', 'PDOException'); +// As instantiation is done at runtime, it is impossible to statically determinate when a method call is detected, on which class the object belong. +// so, all method names that exists in a pre_defined_class to ignore are ignored within every classes. +// if you have some method names in your classes that have the same name that a predefine class method, it will not be obfuscated. +// you can limit the number of method names to ignore by providing an array of the pre-defined classes you really use in your software! +// same behaviour for properties... + +$conf->t_ignore_constants = null; // array where values are names to ignore. +$conf->t_ignore_variables = null; // array where values are names to ignore. +$conf->t_ignore_functions = null; // array where values are names to ignore. +$conf->t_ignore_class_constants = null; // array where values are names to ignore. +$conf->t_ignore_methods = null; // array where values are names to ignore. +$conf->t_ignore_properties = null; // array where values are names to ignore. +$conf->t_ignore_classes = null; // array where values are names to ignore. +$conf->t_ignore_interfaces = null; // array where values are names to ignore. +$conf->t_ignore_traits = null; // array where values are names to ignore. +$conf->t_ignore_namespaces = null; // array where values are names to ignore. +$conf->t_ignore_labels = null; // array where values are names to ignore. + +$conf->t_ignore_constants_prefix = null; // array where values are prefix of names to ignore. +$conf->t_ignore_variables_prefix = null; // array where values are prefix of names to ignore. +$conf->t_ignore_functions_prefix = null; // array where values are prefix of names to ignore. + +$conf->t_ignore_class_constants_prefix = null; // array where values are prefix of names to ignore. +$conf->t_ignore_properties_prefix = null; // array where values are prefix of names to ignore. +$conf->t_ignore_methods_prefix = null; // array where values are prefix of names to ignore. + +$conf->t_ignore_classes_prefix = null; // array where values are prefix of names to ignore. +$conf->t_ignore_interfaces_prefix = null; // array where values are prefix of names to ignore. +$conf->t_ignore_traits_prefix = null; // array where values are prefix of names to ignore. +$conf->t_ignore_namespaces_prefix = null; // array where values are prefix of names to ignore. +$conf->t_ignore_labels_prefix = null; // array where values are prefix of names to ignore. + +$conf->parser_mode = 'ONLY_PHP7';// allowed modes are 'PREFER_PHP7', 'PREFER_PHP5', 'ONLY_PHP7', 'ONLY_PHP5' +// see PHP-Parser documentation for meaning... + +$conf->scramble_mode = 'identifier'; // allowed modes are 'identifier', 'hexa', 'numeric' +$conf->scramble_length = 5; // min length of scrambled names (min = 2; max = 16 for identifier, 32 for hexa and numeric) + +$conf->t_obfuscate_php_extension = array('php'); // array where values are extensions of php files to be obfuscated. + +$conf->obfuscate_constant_name = false; // self explanatory +$conf->obfuscate_variable_name = false; // self explanatory +$conf->obfuscate_function_name = false; // self explanatory +$conf->obfuscate_class_name = false; // self explanatory +$conf->obfuscate_interface_name = false; // self explanatory +$conf->obfuscate_trait_name = false; // self explanatory +$conf->obfuscate_class_constant_name = false; // self explanatory +$conf->obfuscate_property_name = false; // self explanatory +$conf->obfuscate_method_name = false; // self explanatory +$conf->obfuscate_namespace_name = false; // self explanatory +$conf->obfuscate_label_name = false; // label: , goto label; obfuscation +$conf->obfuscate_if_statement = false; // obfuscation of if else elseif statements +$conf->obfuscate_loop_statement = false; // obfuscation of for while do while statements +$conf->obfuscate_string_literal = true; // pseudo-obfuscation of string literals + +$conf->shuffle_stmts = true; // shuffle chunks of statements! disable this obfuscation (or minimize the number of chunks) if performance is important for you! +$conf->shuffle_stmts_min_chunk_size = 1; // minimum number of statements in a chunk! the min value is 1, that gives you the maximum of obfuscation ... and the minimum of performance... +$conf->shuffle_stmts_chunk_mode = 'fixed'; // 'fixed' or 'ratio' in fixed mode, the chunk_size is always equal to the min chunk size! +$conf->shuffle_stmts_chunk_ratio = 20; // ratio > 1 100/ratio is the percentage of chunks in a statements sequence ratio = 2 means 50% ratio = 100 mins 1% ... +// if you increase the number of chunks, you increase also the obfuscation level ... and you increase also the performance overhead! + +$conf->strip_indentation = true; // all your obfuscated code will be generated on a single line +$conf->abort_on_error = true; // self explanatory +$conf->confirm = true; // rfu : will answer Y on confirmation request (reserved for future use ... or not...) +$conf->silent = false; // display or not Information level messages. + + +$conf->source_directory = null; // self explanatory +$conf->target_directory = null; // self explanatory + +$conf->t_keep = null; // array of directory or file pathnames, to keep 'as is' (i.e. not obfuscate.) +$conf->t_skip = null; // array of directory or file pathnames, to skip when exploring source tree structure ... they will not be on target! +$conf->allow_and_overwrite_empty_files = true; // allow empty files to be kept as is + +$conf->max_nested_directory = 99; +$conf->follow_symlinks = false; // WARNING: setting it to true will copy the directory instead of replicating the link... +// WARNING: if there is a loop of links, $conf->max_nested_directory can be created... + +$conf->user_comment = null; // user comment to insert inside each obfuscated file + +$conf->extract_comment_from_line = null; // when both 2 are set, each obfuscated file will contain an extract of the corresponding source file, +$conf->extract_comment_to_line = null; // starting from extract_comment_from_line number, and ending at extract_comment_to_line line number. diff --git a/scripts/build_phar.sh b/scripts/build_phar.sh new file mode 100755 index 0000000..8c5953a --- /dev/null +++ b/scripts/build_phar.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +set -e + +SRC_PATH="/app" +BUILD_PATH="/build" +MODULE_NAME="oc_telegram_shop" +PHAR_PATH="${BUILD_PATH}/${MODULE_NAME}.phar" + +echo "PHP Obfuscation: framework" +yakpro-po --config-file /usr/local/yakpro-po/config.php ${SRC_PATH}/framework -o /tmp/obfuscated +rm -rf ${SRC_PATH}/framework +mv /tmp/obfuscated/yakpro-po/obfuscated ${SRC_PATH}/framework + +echo "PHP Obfuscation: src" +yakpro-po --config-file /usr/local/yakpro-po/config.php ${SRC_PATH}/src -o /tmp/obfuscated +rm -rf ${SRC_PATH}/src +mv /tmp/obfuscated/yakpro-po/obfuscated ${SRC_PATH}/src + +echo "PHP Obfuscation: bastion" +yakpro-po --config-file /usr/local/yakpro-po/config.php ${SRC_PATH}/bastion -o /tmp/obfuscated +rm -rf ${SRC_PATH}/bastion +mv /tmp/obfuscated/yakpro-po/obfuscated ${SRC_PATH}/bastion + +echo "📜 Creating Phar archive..." +rm -rf "${BUILD_PATH}/extracted" +mkdir -p "${BUILD_PATH}" +echo "Source path: ${SRC_PATH}" +echo "Destination: ${PHAR_PATH}" +php -d phar.readonly=0 /scripts/ci/create-phar.php "${SRC_PATH}" "${PHAR_PATH}" + + +echo "Extracting ..." +php -d phar.readonly=0 /scripts/ci/extract-phar.php "${PHAR_PATH}" "${BUILD_PATH}/extracted" diff --git a/scripts/ci/build.sh b/scripts/ci/build.sh index 7939bc5..d237320 100755 --- a/scripts/ci/build.sh +++ b/scripts/ci/build.sh @@ -71,6 +71,45 @@ echo "Copy .env for production" cp "${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/.env.production" \ "${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/.env" +echo "Install PHP Obfuscation lib" +mkdir -p /usr/local +cd /usr/local +wget https://github.com/pk-fr/yakpro-po/archive/refs/heads/master.zip +unzip -o "master.zip" -d /usr/local/yakpro-po +rm master.zip +ls -la /usr/local/yakpro-po +cd /usr/local/yakpro-po +wget https://github.com/nikic/PHP-Parser/archive/refs/heads/4.x.zip -O parser.zip +unzip -o "parser.zip" -d /usr/local/yakpro-po/PHP-Parser +ls -la /usr/local/yakpro-po +ls -la /usr/local/yakpro-po/PHP-Parser +chmod a+x /usr/local/yakpro-po/yakpro-po.php +ln -s /usr/local/yakpro-po/yakpro-po.php /usr/local/bin/yakpro-po + +echo "PHP Obfuscation: framework" +yakpro-po --config-file \ + "${SRC_PATH}/docker/config.php" \ + "${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/framework" \ + -o /tmp/obfuscated +rm -rf "${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/framework" +mv /tmp/obfuscated/yakpro-po/obfuscated "${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/framework" + +echo "PHP Obfuscation: src" +yakpro-po --config-file \ + "${SRC_PATH}/docker/config.php" \ + "${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/src" \ + -o /tmp/obfuscated +rm -rf "${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/src" +mv /tmp/obfuscated/yakpro-po/obfuscated "${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/src" + +echo "PHP Obfuscation: bastion" +yakpro-po --config-file \ + "${SRC_PATH}/docker/config.php" \ + "${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/bastion" \ + -o /tmp/obfuscated +rm -rf "${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/bastion" +mv /tmp/obfuscated/yakpro-po/obfuscated "${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/bastion" + echo "📜 Creating Phar archive..." rm -rf \ "${SRC_PATH}/module/oc_telegram_shop/upload/oc_telegram_shop/tests" \ diff --git a/scripts/ci/extract-phar.php b/scripts/ci/extract-phar.php new file mode 100644 index 0000000..c5978aa --- /dev/null +++ b/scripts/ci/extract-phar.php @@ -0,0 +1,17 @@ +extractTo($dstPath); + +echo "Phar extracted: $pharFile\n";