HEX
HEX
Server: Apache/2.4.29 (Ubuntu)
System: Linux 2amigos-php74 5.4.0-1103-aws #111~18.04.1-Ubuntu SMP Tue May 23 20:04:10 UTC 2023 x86_64
User: squarehillcompany.com (1002)
PHP: 7.4.25
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /var/www/vhosts/app.ett-dev.2amigos.us/cgi-bin/deployer.php
<?php
$content = file_get_contents('php://input');
$json = json_decode($content, true);
$token = false;
$sha  = false;
$DIR = preg_match("/\/$/", DIR) ? DIR : DIR . '/';
$LOGDIR = preg_match("/\/$/", LOGDIR) ? LOGDIR : LOGDIR . '/';

// retrieve the token
if (!$token && isset($_SERVER['HTTP_X_HUB_SIGNATURE'])) {
    list($algo, $token) = explode('=', $_SERVER['HTTP_X_HUB_SIGNATURE'], 2) + array('', '');
} elseif (isset($_SERVER['HTTP_X_GITLAB_TOKEN'])) {
    $token = $_SERVER['HTTP_X_GITLAB_TOKEN'];
} elseif (isset($_GET['token'])) {
    $token = $_GET['token'];
}

// retrieve the checkout_sha
if (isset($json['checkout_sha'])) {
    $sha = $json['checkout_sha'];
} elseif (isset($_SERVER['checkout_sha'])) {
    $sha = $_SERVER['checkout_sha'];
} elseif (isset($_GET['sha'])) {
    $sha = $_GET['sha'];
}

// specify that the response does not contain HTML
header('Content-Type: text/plain');

// use user-defined max_execution_time
if (!empty(MAX_EXECUTION_TIME)) {
    ini_set('max_execution_time', MAX_EXECUTION_TIME);
}

// function to forbid access
function DenyAccess($reason) {
    // format the error
    $error = '=== ERROR: ' . $reason . ' ===' . PHP_EOL . '*** ACCESS DENIED ***' . PHP_EOL;

    // forbid
    http_response_code(403);

    // write the error to the body
    echo $error;

    // stop executing
    exit;
}

// function to run command in background
function runCommand($cmd, $outputFile = '/dev/null') {
    $pid = shell_exec(sprintf("%s >>%s 2>>%s & echo $!", $cmd, $outputFile, $outputFile));

    // return the pid of background process
    return $pid;
}

// function to check if process is running
function isRunning($pid) {
    try{
        $result = shell_exec(sprintf("ps %s", $pid));
        if( count(preg_split("/\n/", $result)) > 2){
            return true;
        }
    } catch(Exception $e){}

    return false;
}

// check for a GitHub signature
if (!empty(TOKEN) && isset($_SERVER['HTTP_X_HUB_SIGNATURE']) && $token !== hash_hmac($algo, $content, TOKEN)) {
    DenyAccess('X-Hub-Signature does not match TOKEN');
}

// Check for a GitLab token
if (!empty(TOKEN) && isset($_SERVER['HTTP_X_GITLAB_TOKEN']) && $token !== TOKEN) {
    DenyAccess('X-GitLab-Token does not match TOKEN');
}

// check for a $_GET token
if (!empty(TOKEN) && isset($_GET['token'])) {
    if (!isset($_SERVER['REMOTE_ADDR']) || !in_array($_SERVER['REMOTE_ADDR'], ALLOWED_IP)) {
        DenyAccess($_SERVER['REMOTE_ADDR'] . ' is not in allowed IPs list');
    }
    if ($token !== TOKEN) {
        DenyAccess('$_GET[\'token\'] does not match TOKEN');
    }
}

// no token provided
if (!empty(TOKEN) && !isset($_SERVER['HTTP_X_HUB_SIGNATURE']) && !isset($_SERVER['HTTP_X_GITLAB_TOKEN']) && !isset($_GET['token'])) {
  DenyAccess('No token detected');
}

// webhook call validation
if (!isset($_SERVER['REMOTE_ADDR']) || !in_array($_SERVER['REMOTE_ADDR'], ALLOWED_IP)) {
    // check for remote repository match
    if (!(isset($json['repository']['git_url']) && $json['repository']['git_url'] === REMOTE_REPOSITORY ||
      isset($json['repository']['ssh_url']) && $json['repository']['ssh_url'] === REMOTE_REPOSITORY ||
      isset($json['repository']['clone_url']) && $json['repository']['clone_url'] === REMOTE_REPOSITORY ||
      isset($json['repository']['svn_url']) && $jsonn['repository']['svn_url'] === REMOTE_REPOSITORY ||
      isset($json['project']['git_ssh_url']) && $json['project']['git_ssh_url'] === REMOTE_REPOSITORY ||
      isset($json['project']['git_http_url']) && $json['project']['git_http_url'] === REMOTE_REPOSITORY)) {
        DenyAccess('Remote Repository mismatch');
    }

    // check for branch match, ignore if not
    $branch = 'refs/heads/' . BRANCH;
    if ($json['ref'] !== $branch) {
        $info = '=== INFO: Remote Branch mismatch, skipping ===' . PHP_EOL;
        http_response_code(200);

        // write the info to the body
        echo $info;

        // stop executing
        exit;
    }
}
// ensure directory is a repository
if (!file_exists($DIR . '.git') || !is_dir($DIR)) {
    // prepare the generic error
    $error = '=== ERROR: DIR `' . DIR . '` is not a repository ===' . PHP_EOL;

    // try to detemrine the real error
    if (!file_exists(DIR)) {
        $error = '=== ERROR: DIR `' . DIR . '` does not exist ===' . PHP_EOL;
    } elseif (!is_dir(DIR)) {
        $error = '=== ERROR: DIR `' . DIR . '` is not a directory ===' . PHP_EOL;
    }

    // bad request
    http_response_code(403);

    // write the error to the body
    echo $error;

    // stop executing
    exit;
}

// check if no deploy running atm
if (file_exists('.ht-deploy')) {
    $info = '=== INFO: There is already a deploy process running ===' . PHP_EOL;
    http_response_code(200);

    if (!isset($_SERVER['HTTP_X_HUB_SIGNATURE']) && !isset($_SERVER['HTTP_X_GITLAB_TOKEN']) && isset($_GET['token'])) {
        header('Content-Type: text/html');
        ?>
        <pre> <?php echo $info; ?></pre>
        <p>You will be redirected in <span id="counter">3</span> second(s) to deploy log</p>
        <script type="text/javascript">
          function countdown() {
              var i = document.getElementById('counter');
              if (parseInt(i.innerHTML)<=0) {
                  location.href = <?php echo '"' . $_SERVER['PHP_SELF'] . '?viewlog=yes' . '"'; ?>;
              }
              if (parseInt(i.innerHTML)!=0) {
                  i.innerHTML = parseInt(i.innerHTML)-1;
              }
          }
          setInterval(function(){ countdown(); },1000);
        </script>
        <?php
    } else { echo $info; }
    exit;
}


////
//// we finally finished preliminary checks, now generating deploy script
////
// create tmpfile with deploy commands
$tfile = fopen('.ht-deploy','w');
fwrite($tfile,
  '#!/bin/bash' . PHP_EOL .
  'trap "exit 1" TERM' . PHP_EOL .
  'TOP_PID=$$' . PHP_EOL .
  'DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)' . PHP_EOL .
  PHP_EOL .
  'function alert() {' . PHP_EOL .
  '  echo "$(date +[%d-%m-%Y\ %H:%M:%S]):   === DEPLOY NOT COMPLETE, CHECK ABOVE ERRORS ==="' . PHP_EOL .
  '  rm -f $DIR/.ht-deploy' . PHP_EOL .
  '  kill -s TERM $TOP_PID' . PHP_EOL .
  '}' . PHP_EOL .
  PHP_EOL .
  'cd ' . DIR . PHP_EOL
);

// add clean local repo to script, if enabled in settings
if (!empty(CLEAN) && CLEAN === 'YES') {
    fwrite($tfile, PHP_EOL . 'echo "$(date +[%d-%m-%Y\ %H:%M:%S]):   *** CLEAN REPO STEP ***"' . PHP_EOL);
    fwrite($tfile, GIT . ' reset --hard HEAD || alert' . PHP_EOL);
    fwrite($tfile, GIT . ' clean -dfx || alert' . PHP_EOL);
}

// add BEFORE_PULL to deploy script, if specified
if (!empty(BEFORE_PULL) && file_exists(BEFORE_PULL)) {
    fwrite($tfile, PHP_EOL . 'echo "$(date +[%d-%m-%Y\ %H:%M:%S]):   *** BEFORE PULL STEP ***"' . PHP_EOL);
    fwrite($tfile, BEFORE_PULL . ' || alert' . PHP_EOL);
}

// add pull to deploy script
fwrite($tfile, PHP_EOL . 'echo "$(date +[%d-%m-%Y\ %H:%M:%S]):   *** PULL ORIGIN STEP ***"' . PHP_EOL);
fwrite($tfile, GIT . ' pull origin ' . BRANCH . ' || alert' . PHP_EOL);

// add AFTER_PULL to deploy script, if specified
if (!empty(AFTER_PULL) && file_exists(AFTER_PULL)) {
    fwrite($tfile, PHP_EOL . 'echo "$(date +[%d-%m-%Y\ %H:%M:%S]):   *** AFTER PULL STEP ***"' . PHP_EOL);
    fwrite($tfile, AFTER_PULL . ' || alert' . PHP_EOL);
}

// complete deploy script
fwrite($tfile, PHP_EOL . 'echo "$(date +[%d-%m-%Y\ %H:%M:%S]):   === DEPLOY COMPLETE ==="' . PHP_EOL .
  'rm -f $DIR/.ht-deploy' . PHP_EOL
);

////
//// last touch, before we deploy, initiate logs
////
// open log file and write the start time to it
unlink($LOGDIR . 'deploy-last.log');
symlink($LOGDIR . 'deploy-' . date('d-m-Y-H-i-s') . '.log', $LOGDIR . 'deploy-last.log');
$file = fopen($LOGDIR . 'deploy-last.log', 'w');
fputs($file, date('[d-m-Y H:i:s]') . ':   === START DEPLOY ===' . PHP_EOL);
fclose($tfile);
fclose($file);

////
//// deploy itself
////
// start and run in brackground;
$pid = runCommand('/bin/bash .ht-deploy', $LOGDIR . 'deploy-last.log');

// workaround to be sure deploy script is really started
for ($i = 1; $i <= 10; $i++) {
    if (isset($pid) && isRunning($pid)) {
        break;
    }
    sleep(1);
}

// some information to show
$info = '=== INFO: Deploy in progress/complete ===' . PHP_EOL .
        'Reposity:   ' . REMOTE_REPOSITORY . PHP_EOL .
        'Branch:     ' . BRANCH . PHP_EOL .
        'Directory:  ' . DIR . PHP_EOL .
        'Deploy Log: ' . $LOGDIR . 'deploy-last.log' . PHP_EOL .
        '-----------------------------------------';

////
//// Redirect log deploy tail log, when deploy from browser
////
if (!isset($_SERVER['HTTP_X_HUB_SIGNATURE']) && !isset($_SERVER['HTTP_X_GITLAB_TOKEN']) && isset($_GET['token'])) {
    header('Content-Type: text/html');
    ?>
    <pre> <?php echo $info; ?></pre>
    <p>You will be redirected in <span id="counter">3</span> second(s) to deploy log</p>
    <script type="text/javascript">
      function countdown() {
          var i = document.getElementById('counter');
          if (parseInt(i.innerHTML)<=0) {
              location.href = <?php echo '"' . $_SERVER['PHP_SELF'] . '?viewlog=yes' . '"'; ?>;
          }
          if (parseInt(i.innerHTML)!=0) {
              i.innerHTML = parseInt(i.innerHTML)-1;
          }
      }
      setInterval(function(){ countdown(); },1000);
    </script>
    <?php
} else {
    http_response_code(200);
    echo $info;
}