#!/usr/local/cpanel/3rdparty/bin/perl
# cpanel - autofixer2/mitigate_imagemagick_cve
#                                                 Copyright(c) 2016 cPanel, Inc.
#                                                           All rights Reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited

package autofixer2::mitigate_imagemagick_cve;

use strict;
use warnings;
use XML::LibXML                    ();
use Cpanel::LoadFile               ();
use Cpanel::Transaction::File::Raw ();

our $file = '/etc/ImageMagick/policy.xml';

exit( __PACKAGE__->script() ) unless caller();

sub script {
    return 0 if !-e $file;

    my $contents = Cpanel::LoadFile::loadfile($file);

    # Policy for EPHEMERAL alredy exists, assume patched
    return 0 if ( $contents =~ m{EPHEMERAL} );

    my @PATTERNS_TO_DISABLE = (qw(EPHEMERAL URL HTTPS MVG MSL));

    my $trans_obj = Cpanel::Transaction::File::Raw->new( path => $file, permissions => 0644 );
    my $xml_sr    = $trans_obj->get_data();
    my $dom       = XML::LibXML->load_xml( string => $xml_sr );

    my $root = $dom->getDocumentElement();
    my ($policymap_element) = $root->findnodes('/policymap');
    if ( !$policymap_element ) {
        $policymap_element = $dom->createElement('policymap');
        $root->appendChild($policymap_element);
    }

    my @policy_nodes = $policymap_element->findnodes('/policy');

    if ( !@policy_nodes ) {
        foreach my $format (@PATTERNS_TO_DISABLE) {
            my $newnode = $dom->createTextNode("\n  ");
            $policymap_element->appendChild($newnode);
            $newnode = $dom->createElement('policy');
            $newnode->setAttribute( 'domain',  'coder' );
            $newnode->setAttribute( 'rights',  'none' );
            $newnode->setAttribute( 'pattern', $format );
            $policymap_element->appendChild($newnode);
        }
        my $newnode = $dom->createTextNode("\n");
        $policymap_element->appendChild($newnode);

        print "Patched $file to disable: @PATTERNS_TO_DISABLE\n";

        my $newdoc = $dom->toString();
        $trans_obj->set_data( \$newdoc );
        my ( $save_ok, $save_msg ) = $trans_obj->save_and_close();

        if ( !$save_ok ) {
            warn $save_msg;
            return 1;
        }

        return 0;
    }
    else {
        $trans_obj->abort();
    }

    return 0;
}
