#!/usr/local/cpanel/3rdparty/bin/perl

# cpanel - autofixer2/update_hostname_sectigo_cabundles
#                                                  Copyright 2020 cPanel, L.L.C.
#                                                           All rights reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited

use strict;
use warnings;

use experimental 'signatures';

use Cpanel::SSLCerts                  ();
use Cpanel::SSLInstall::Service       ();
use Cpanel::SSL::CABundleCache        ();
use Cpanel::SSL::Objects::Certificate ();

__PACKAGE__->run() if !caller;

sub run {
    my @services = qw( dovecot exim ftp cpanel );

    for my $service (@services) {
        print "Checking $service …$/";

        eval { _do_service($service); 1 } or warn;
    }

    return;
}

sub _do_service {
    my ($service) = @_;

    my $ssldata = Cpanel::SSLCerts::fetchSSLFiles(
        service => $service,
    );

    my $cert_pem = $ssldata->{'crt'} or do {
        print "\tNo SSL installed.$/";
        return;
    };

    my $cert_obj = Cpanel::SSL::Objects::Certificate->new(
        cert => $cert_pem,
    );

    if ( $cert_obj->expired() ) {
        print "\tLeaf certificate is already expired.$/";
        return;
    }

    my @cab_pieces = split m[(?<=)-[\r\n]+(?=-)], $ssldata->{'cab'} // ();

    my $needs_replace;

    for my $cabcert_pem (@cab_pieces) {
        my $cabcert_obj = Cpanel::SSL::Objects::Certificate->new(
            cert => $cabcert_pem,
        );

        my $issuer_text = $cabcert_obj->issuer_text();

        next if $issuer_text !~ m<sectigo|comodo|addtrust>i;

        if ( $cabcert_obj->expired() ) {
            $needs_replace = 1;
            print "\tCA certificate needs replacement.$/";
            last;
        }
    }

    if ($needs_replace) {
        my $caissuers_url = $cert_obj->caIssuers_url();

        if ($caissuers_url) {
            print "\tFetching CA bundle …$/";

            my $cab_pem = Cpanel::SSL::CABundleCache->load($caissuers_url);

            print "\tReinstalling certificate with new CA bundle …$/";

            my ( $ok, $why ) = Cpanel::SSLCerts::installSSLFiles(
                service => $service,
                crt     => $cert_pem,
                key     => $ssldata->{'key'},
                cab     => $cab_pem,
            );

            if ($ok) {
                print "\tInstallation succeeded! Restarting $service …$/";

                Cpanel::SSLInstall::Service->new()->_restart_service($service);
            }
            else {
                print "\tFAILED: $why$/";
            }
        }
        else {
            print "\tNo caIssuers URL in leaf certificate!$/";
        }
    }
    else {
        print "\tNo replacement needed.$/";
    }

    return;
}

1;
