Skip to main content

Event Password cPanel Change

Comments

8 comments

  • webnet golki

    Try move php script to /usr/local/cpanel/whostmgr/docroot/cgi/ example:

    /usr/local/cpanel/bin/manage_hooks add script /usr/local/cpanel/whostmgr/docroot/cgi/a/password_change_notice.php --manual --category Cpanel --event passwd_changed --stage post --exectype script
    /usr/local/cpanel/bin/manage_hooks add script /usr/local/cpanel/whostmgr/docroot/cgi/a/password_change_notice.php --manual --category Whostmgr --event Passwd::change_password --stage post --exectype script
    /usr/local/cpanel/bin/manage_hooks add script /usr/local/cpanel/whostmgr/docroot/cgi/a/password_change_notice.php --manual --category Whostmgr --event Passwd::modify_password --stage post --exectype script
    0
  • Oktavia Iw

    I have try adding mentioned hook but my script still not triggeredI have tried adding the [hook name] hook, but my script still isn't triggering. I have checked log, hook registered and my script, but the issue persists. When running manual call my script working.

    0
  • Andy Baugh cPanel Staff

    The issue is that the category and event name you are specifying is not correct. In our documentation (and our code) we refer to the category as 'Passwd' and event as 'ChangePasswd'. Unless you specifically use these names, this will result in the hook action code not executing, as it doesn't reference the relevant category and event.

    Try this:

    /usr/local/cpanel/bin/manage_hooks add script /var/cpanel/hook/emailsender.php --manual --category Passwd --event ChangePasswd --stage post

    Do note that we document this event name here:

    https://api.docs.cpanel.net/guides/guide-to-standardized-hooks/guide-to-standardized-hooks-hookable-events/guide-to-standardized-hooks-passwd-functions

    Hope this helps! Let me know if you continue to have difficulties.

    0
  • Oktavia Iw

    Thank you, Andy Baugh, for the guidance. I tested the password change interface after making changes to WHM's 'List Accounts' section, but the script still isn't being called.

    0
  • Oktavia Iw

    I put in the /usr/local/cpanel/whostmgr/docroot/cgi/password-change-monitor/password_change.php

    This my php script:

    #!/usr/local/cpanel/3rdparty/bin/php
    <?php

    declare(strict_types=1);

    // Mendapatkan path direktori script saat ini
    $scriptDir = dirname(__FILE__);

    // Load konfigurasi
    require_once $scriptDir . '/config.php';

    // Load PHPMailer
    require_once $scriptDir . '/PHPMailer/src/Exception.php';
    require_once $scriptDir . '/PHPMailer/src/PHPMailer.php';
    require_once $scriptDir . '/PHPMailer/src/SMTP.php';

    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\SMTP;
    use PHPMailer\PHPMailer\Exception;

    // Fungsi untuk menulis log
    function write_log(string $log_type, string $message, string $scriptDir): void
    {
        $log_dir = $scriptDir . '/logs/'; // Gunakan scriptDir untuk path log
         if (PHP_SAPI === 'cli') {
            $log_dir = '/usr/local/cpanel/whostmgr/docroot/cgi/password-change-monitor/logs/';
         }

        $log_file = $log_dir . $log_type . '.log';
        $timestamp = date('Y-m-d H:i:s');
        $log_message = "[$timestamp] $message\n";
        file_put_contents($log_file, $log_message, FILE_APPEND | LOCK_EX);
    }

    // Fungsi untuk mendapatkan informasi server
    function get_server_info(): array
    {
        return [
          'hostname' => gethostname(),
          'ip_address' => $_SERVER['SERVER_ADDR'] ?? 'Unknown',
          'protocol' => $_SERVER['SERVER_PROTOCOL'] ?? 'Unknown',
        ];
    }

    // Fungsi untuk mendapatkan informasi user agent, ip dan request method
    function get_request_info(): array
    {
      if (PHP_SAPI === 'cli') { // Cek jika script dieksekusi melalui command line
            return [
                'ip_address' => '127.0.0.1',
                'user_agent' => 'Command Line',
                'request_method' => 'CLI',
            ];
        }

       return [
            'ip_address' => $_SERVER['REMOTE_ADDR'] ?? 'Unknown',
            'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown',
            'request_method' => $_SERVER['REQUEST_METHOD'] ?? 'Unknown',
       ];
    }

    // Fungsi untuk mendapatkan path script atau url
    function get_script_path(): string
    {
       if (PHP_SAPI === 'cli') {
             return 'Command Line Execution';
         }
        $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
        $path = 'Unknown';
         foreach ($backtrace as $trace) {
             if (isset($trace['file']) && is_string($trace['file'])) {
               $path = $trace['file'];
                break;
              }
          }

        if ($path === 'Unknown' && isset($_SERVER['REQUEST_URI']) && is_string($_SERVER['REQUEST_URI'])) {
            $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http";
            $host = $_SERVER['HTTP_HOST'] ?? 'Unknown';
            $requestUri = $_SERVER['REQUEST_URI'];
            $path = "$protocol://$host$requestUri";
        }

        return $path;
    }

    // Fungsi utama untuk mengirim notifikasi email
    function send_notification(array $data, array $smtp_config, string $scriptDir): void
    {
         $mail = new PHPMailer(true);
        try {
            // Konfigurasi SMTP
            $mail->isSMTP();
            $mail->Host = $smtp_config['host'];
            $mail->SMTPAuth = true;
            $mail->Username = $smtp_config['username'];
            $mail->Password = $smtp_config['password'];
            $mail->SMTPSecure = $smtp_config['encryption'];
            $mail->Port = (int) $smtp_config['port'];

            $mail->setFrom($smtp_config['from_email'], $smtp_config['from_name']);
            $mail->addAddress($smtp_config['to_email']);

            $mail->isHTML(true);
            $mail->Subject = 'Password cPanel Changed';

            // Menyusun body email
            $body = <<<HTML
                <html>
                <head>
                    <title>Password cPanel Changed</title>
                    <style>
                        body { font-family: Arial, sans-serif; color: #333; }
                        h1 { color: #0056b3; }
                        table { width: 100%; border-collapse: collapse; margin-top: 20px; }
                        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
                        th { background-color: #f2f2f2; }
                    </style>
                </head>
                <body>
                    <h1>Password cPanel Changed</h1>
                    <p>Berikut detail perubahan password:</p>
                    <table>
                        <tr>
                            <th>Item</th>
                            <th>Detail</th>
                        </tr>
                         <tr>
                            <td>Time</td>
                            <td>{$data['time']}</td>
                        </tr>
                        <tr>
                            <td>IP Address</td>
                            <td>{$data['ip_address']}</td>
                        </tr>
                        <tr>
                            <td>User Agent</td>
                            <td>{$data['user_agent']}</td>
                        </tr>
                         <tr>
                            <td>Hostname</td>
                            <td>{$data['hostname']}</td>
                        </tr>
                        <tr>
                            <td>Request Method</td>
                            <td>{$data['request_method']}</td>
                        </tr>
                        <tr>
                            <td>Protocol</td>
                            <td>{$data['protocol']}</td>
                        </tr>
                        <tr>
                            <td>Source</td>
                            <td>{$data['source']}</td>
                        </tr>
                        <tr>
                            <td>Path</td>
                            <td>{$data['path']}</td>
                        </tr>
                    </table>
                 </body>
                </html>
                HTML;

            $mail->Body = $body;
            $mail->send();
           write_log('event', "Email notification sent successfully to {$smtp_config['to_email']}.", $scriptDir);
        } catch (Exception $e) {
            write_log('error', "Failed to send email: {$mail->ErrorInfo}", $scriptDir);
        }
    }

    // Main event
    try {
        $timeout = 50; // Timeout dalam detik
        $start_time = time();

        write_log('debug', "password_change.php started.", $scriptDir);

        // Ambil informasi server
         $server_info = get_server_info();
         $request_info = get_request_info();


        $data = [
          'time' => date('Y-m-d H:i:s', time() + (7 * 3600)) . " WIB",
          'ip_address' => $request_info['ip_address'] ?? 'Unknown',
          'user_agent' => $request_info['user_agent'] ?? 'Unknown',
          'hostname' => $server_info['hostname'] ?? 'Unknown',
          'request_method' => $request_info['request_method'] ?? 'Unknown',
          'protocol' => $server_info['protocol'] ?? 'Unknown',
          'source' => 'Unknown',
          'path' => 'Unknown',
         ];


         // Get source from backtrace
        $script_path = get_script_path();
           if ($script_path !== 'Unknown') {
             $data['path'] = $script_path;

             if(strpos($script_path, 'whm')){
               $data['source'] = 'WHM API';
             }elseif(strpos($script_path, 'cpanel')){
               $data['source'] = 'cPanel API';
             }else{
               $data['source'] = 'Script Executed';
             }
        } else {
           if (strpos($request_info['user_agent'], 'cPanel')) {
               $data['source'] = 'cPanel Interface';
           } elseif (strpos($request_info['user_agent'], 'whm')) {
                $data['source'] = 'WHM Interface';
                 $data['path'] = $_SERVER['REQUEST_URI'] ?? 'Unknown';
                  if (isset($_SERVER['REQUEST_URI']) && is_string($_SERVER['REQUEST_URI'])) {
                    $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http";
                    $host = $_SERVER['HTTP_HOST'] ?? 'Unknown';
                    $requestUri = $_SERVER['REQUEST_URI'];
                     $data['path'] = "$protocol://$host$requestUri";
                 }
           }
        }


        if ((time() - $start_time) > $timeout) {
            $data['source'] = 'Timeout - Data Tidak Lengkap';
            write_log('error', 'Timeout occurred while processing data.', $scriptDir);
        }

        send_notification($data, $smtp_config, $scriptDir);

    } catch (Throwable $e) {
        write_log('error', "Error in password_change.php: " . $e->getMessage(), $scriptDir);

         $data = [
           'time' => date('Y-m-d H:i:s', time() + (7 * 3600)) . " WIB",
           'ip_address' => 'Unknown',
           'user_agent' => 'Unknown',
           'hostname' => 'Unknown',
           'request_method' => 'Unknown',
           'protocol' => 'Unknown',
           'source' => 'Error - Data Tidak Lengkap',
           'path' => 'Unknown',
          ];
        send_notification($data, $smtp_config, $scriptDir);
    }
    0
  • Andy Baugh cPanel Staff

    You probably will want to enable "debughooks" then so that you get log messages about what's going on. That should at least help you see whether the hook executed in that context or not. See here for documentation on that:

    https://api.docs.cpanel.net/guides/guide-to-standardized-hooks/guide-to-standardized-hooks-debug-mode/

    Use of the logdata or logall setting will usually make what's going on in the backend pretty obvious if you tail the error log while doing the action that should trigger your script.

    0
  • Oktavia Iw

    I make test with below script only work for first changed password, after try again, unable to capture data

    <?php

    //
    $filename = '/usr/local/cpanel/whostmgr/docroot/cgi/password-change-monitor/change_password_log.txt';
    $file = fopen($filename, 'a'); //

    if ($file) {
      fwrite($file, "Username: " . $_POST['user'] . "\n");
      fwrite($file, "New Password: " . $_POST['new_password'] . "\n");
      fwrite($file, "Rawout: " . $_POST['rawout'] . "\n");
      fwrite($file, "Applist: " . $_POST['applist'] . "\n");
      fwrite($file, "--------------------\n");
      fclose($file);

    echo "Data saved to $filename\n";
    } else {
    echo "Unable to open $filename\n";
    }

    ?>
    0
  • Oktavia Iw

    What output formate from post return like json or just text?

    0

Please sign in to leave a comment.