Viewing File: /usr/local/cpanel/whostmgr/docroot/cgi/addon_clamavconnector.cgi

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

BEGIN { unshift @INC, '/usr/local/cpanel', '/usr/local/cpanel/whostmgr/docroot/cgi'; }

use Whostmgr::ACLS          ();
use Whostmgr::HTMLInterface ();
use Cpanel;

Whostmgr::ACLS::init_acls();

my %g_conf = undef;
our $prefix = '/usr/local/cpanel/3rdparty';

require "parseform.pl";
my %FORM = parseform();

# Case 59175: characters that might be acceptable to be in a username
# This file doesn't have access to Cpanel::Validate::Username as the package
# might not exist in the environment in which this cgi will be run. So,
# we're using the least strict regex.
my $looselyValidName = '^[\_\-.A-Za-z0-9]+$';

my %SCANS = (
    "mail"    => "Scan Mail",
    "homedir" => "Scan Entire Home Directory",
    "pubhtml" => "Scan Public Web Space",
    "pubftp"  => "Scan Public FTP Space"
);

print "Content-type: text/html\n\n";

Whostmgr::HTMLInterface::defheader("ClamAV Scanner Configuration");

if ( !$Whostmgr::ACLS::ACL{all} ) {
    print "ClamAV is installed and running!\n";
    Whostmgr::HTMLInterface::deffooter();
    exit();
}

Cpanel::initcp( $ENV{'REMOTE_USER'} );

# Default Action
if ( $FORM{'cgiaction'} eq "" ) {
    printForm();
}

# Modify the default allowed scans
elsif ( $FORM{'cgiaction'} eq "moddefault" ) {
    modifyDefaults();
    printForm();
}

# Defaults for user override of the global scan settings
elsif ( $FORM{'cgiaction'} eq "moddefaultoverride" ) {
    modifyDefaultOverrides();
    printUserForm();
}

# Switch to user permission view
elsif ( $FORM{'cgiaction'} eq "modusers" ) {
    printUserForm();
}

# Delete a user from the ACL
elsif ( $FORM{'cgiaction'} eq "deleteuser" ) {
    if ( $FORM{'user'} eq "" || $FORM{'user'} !~ /$looselyValidName/ ) {
        printUserForm();
    }
    else {
        deleteUser( $FORM{'user'} );
        removeUserConfig( $FORM{'user'} );
        printUserForm();
    }
}

# Delete ALL users from the ACL
elsif ( $FORM{'cgiaction'} eq "deleteall" ) {
    deleteAllUsers();
    printUserForm();
}

# Add A User to the ACL
elsif ( $FORM{'cgiaction'} eq "adduser" ) {
    if ( $FORM{'user'} eq "" || $FORM{'user'} !~ /$looselyValidName/ ) {
        printUserForm();
    }
    else {
        addUser( $FORM{'user'} );
        configureUser( $FORM{'user'} );
        printUserForm();
    }
}

# Add ALL Users to the ACL
elsif ( $FORM{'cgiaction'} eq "addall" ) {
    addAllUsers();
    configureAllUsers();
    printUserForm();
}

# Show user configuration screen.
elsif ( $FORM{'cgiaction'} eq "showuser" ) {
    if ( $FORM{'user'} eq "" || $FORM{'user'} !~ /$looselyValidName/ ) {
        printUserForm();
    }
    else {
        printConfigForm();
    }
}

# Configure a User in the ACL
elsif ( $FORM{'cgiaction'} eq "confuser" ) {
    if ( $FORM{'user'} eq "" || $FORM{'user'} !~ /$looselyValidName/ ) {
        printUserForm();
    }
    else {
        configureUser();
        printUserForm();
    }
}
else {
    print "<h2>You actioned.. And I don't know how to handle it.</h2>";
}

Whostmgr::HTMLInterface::deffooter();
################################################################################
# printForm
################################################################################
sub printForm {
    my %conf = loadClamavConf();

    # Defaults
    print "<fieldset><legend>Scans Allowed Globally</legend>";
    print "<p><div align=\"center\">";
    print "Allow the following ClamAV scans to be run for all users:</div></p>\n";
    print "<form action=\"addon_clamavconnector.cgi\">\n";
    print "<input type=\"hidden\" name=\"cgiaction\" value=\"moddefault\">\n";
    print "<table align=\"center\" cellspacing=\"0\" cellpadding=\"2\" border=\"1\">\n";

    my $bg = "2";
    foreach my $type ( sort keys %SCANS ) {
        print "<tr class=\"tdshade$bg\">\n";
        if ( $conf{'DEFAULTSCANS'} =~ /$type/ || !exists $conf{'DEFAULTSCANS'} ) {
            print "<td><input type=\"checkbox\" name=\"${type}\" CHECKED>";
        }
        else {
            print "<td><input type=\"checkbox\" name=\"${type}\">";
        }
        print "$SCANS{$type}</input></td>\n";
        print "</tr>\n";
        if   ( $bg eq "2" ) { $bg = "1"; }
        else                { $bg = "2"; }
    }
    print "<tr class=\"tdshade$bg\"><td><div align=\"center\"><input type=\"submit\" value=\"Save\"></div></td></tr>\n";
    print "</table></form>\n";
    print "</fieldset>\n";

    # Users
    print "<fieldset><legend>ClamAV Scanner User Configuration</legend>";
    print "<p><div align=\"center\">";
    print "Configure ClamAV Scanner for individual users:</div></p>\n";
    print "<form action=\"addon_clamavconnector.cgi\">\n";
    print "<input type=\"hidden\" name=\"cgiaction\" value=\"modusers\">\n";
    print "<div align=\"center\"><input type=\"submit\" value=\"User Configuration\"></div>\n";
    print "</input></form></fieldset>\n";

    return;
}

################################################################################
# printUserForm
################################################################################
sub printUserForm {
    my %conf = loadClamavConf();

    print "<script language=\"javascript\">";
    print "function fillConfig() { document.conf.user.value = ";
    print "document.acl.user.options[document.acl.user.selectedIndex].value; } ";
    print "</script>";

    print "<fieldset><legend>Group Scanner Configuration</legend>\n";
    print "<p><div align=\"center\">Select users to override the global scanner ";
    print "settings and specify override defaults:<br />\n";
    print "<i>(Settings specified for \"Defaults\" will be applied to all new ";
    print "\"Configured Users\".)</i></div></p>\n";
    print "<table align=\"center\" cellspacing=\"0\" cellpadding=\"2\" border=\"0\">";

    # Allowed Users Box, and Delete
    print "<tr align=center><td background='", Whostmgr::HTMLInterface::getbggif(), "'><b>User List</b>";
    print "</td><td width=\"30\" rowspan=\"2\" valign=\"top\">";
    print "&nbsp;</td><td background=\"", Whostmgr::HTMLInterface::getbggif(), "\"><b>Configured Users</b></td><td width=\"30\"";
    print "rowspan=\"2\" valign=\"top\">&nbsp;</td>";
    print "<td background=\"", Whostmgr::HTMLInterface::getbggif(), "\"><b>Defaults</b></td></tr>";
    print "<tr><td align=\"center\">";

    # All users box, and Add
    print "<form action=\"addon_clamavconnector.cgi\">\n";
    print "<input type=\"hidden\" name=\"cgiaction\" value=\"adduser\">\n";
    print "<select size=\"6\" width=\"150\" style=\"width: 150px\" name=\"user\">\n";
    my @userlist = getUserList();
    print join( "\n", map( "<option name=\"${_}\">$_</option>\n", @userlist ) );
    print "</select><p>\n";

    my @defaultoverride = split( /,/, $conf{'DEFAULTSCANOVERRIDES'} );
    foreach my $scan (@defaultoverride) {
        print "<input type=\"hidden\" name=\"$scan\" value=\"on\">\n";
    }
    print "<input type=\"submit\" value=\"Add\"></form>\n";
    print "<form action=\"addon_clamavconnector.cgi\">\n";
    foreach my $scan (@defaultoverride) {
        print "<input type=\"hidden\" name=\"$scan\" value=\"on\">\n";
    }
    print "<input type=\"hidden\" name=\"cgiaction\" value=\"addall\">\n";
    print "<input type=\"submit\" value=\"Add All\"></form></p></td>\n";

    print "<td align=\"center\">";
    print "<form action=\"addon_clamavconnector.cgi\" name=\"acl\">\n";
    print "<input type=hidden name=cgiaction value=\"deleteuser\">\n";
    print "<select name=\"user\" size=\"6\" width=\"150\" style=\"width: 150px\"";
    print "align=\"top\" onChange=\"fillConfig();\">\n";
    foreach my $user ( split( /,/, $conf{'CLAMAVOVERRIDEUSERS'} ) ) {
        print "<option value=\"${user}\">${user}</option>\n";
    }
    print "</select><p><input type=\"submit\" value=\"Remove\"></form>\n";
    print "<form action=\"addon_clamavconnector.cgi\"><input type=\"hidden\" ";
    print "name=\"cgiaction\" value=\"deleteall\">\n";
    print "<input type=\"submit\" Value=\"Remove All\"></form></p>\n";
    print "</td></td>\n";

    print "<td valign=\"top\"><form action=\"addon_clamavconnector.cgi\">\n";
    print "<input type=\"hidden\" name=\"cgiaction\" value=\"moddefaultoverride\">\n";
    print "<table align=\"center\" cellspacing=\"0\" cellpadding=\"2\" border=\"1\">\n";

    my $bg = "2";
    foreach my $type ( sort keys %SCANS ) {
        print "<tr class=\"tdshade$bg\">\n";
        if ( $conf{'DEFAULTSCANOVERRIDES'} =~ /$type/ ) {
            print "<td><input type=\"checkbox\" name=\"${type}\" CHECKED>";
        }
        else {
            print "<td><input type=\"checkbox\" name=\"${type}\">";
        }
        print "$SCANS{$type}</input></td>\n";
        print "</tr>\n";
        if   ( $bg eq "2" ) { $bg = "1"; }
        else                { $bg = "2"; }
    }
    print "</table><p><div align=\"center\"><input type=\"submit\" ";
    print "value=\"Save Defaults\"></div></p>\n";
    print "</form>\n";
    print "</table>\n";
    print "</fieldset>\n";

    # Configure User.
    print "<fieldset><legend>User Scanner Configuration</legend>";
    print "<p><div align=\"center\">";
    print "<b>Configure Individual Scan Preferences:</b><br />\n";
    print "<i>(Change settings for specific users specified in \"Configured Users\")</i></div></p>\n";
    print "<table align=\"center\" cellspacing=\"0\" cellpadding=\"2\">\n";
    print "<form action=\"addon_clamavconnector.cgi\" name=\"conf\">";
    print "<input type=\"hidden\" name=\"cgiaction\" value=\"showuser\">\n";
    print "<tr><td>\n";
    print "Configure User: <input type=\"text\" value=\"\" name=\"user\">\n";
    print "<input type=\"submit\" value=\"Configure\"></form></td></tr>\n";
    print "</form>\n";
    print "</table></fieldset>\n";

    # Go Back..
    print "<br /><br /><br />\n";
    print "<div align=\"center\"><a href=\"addon_clamavconnector.cgi\">[ Go Back ]</a></div>\n";
}

################################################################################
# printConfigForm
################################################################################
sub printConfigForm {
    my $string = "";
    my %l_conf = loadUserConf( $FORM{'user'} );
    my @scans  = ();
    if ( defined( $l_conf{'CLAMAVSCANS'} ) ) {
        @scans = split( /,/, $l_conf{'CLAMAVSCANS'} );
    }
    else {
        my %s_conf = loadClamavConf();
        @scans = split( /,/, $s_conf{'DEFAULTSCANOVERRIDES'} );
    }
    print "<fieldset><legend>User ", $FORM{'user'}, "'s Settings</legend>\n";

    print "<td valign=\"top\"><form action=\"addon_clamavconnector.cgi\">\n";

    print "<form action=\"addon_clamavconnector.cgi\">";
    print "<input type=\"hidden\" name=\"cgiaction\" value=\"confuser\">";
    print "<input type=\"hidden\" name=\"user\" value=\"", $FORM{'user'}, "\">";

    print "<table align=\"center\" cellspacing=\"0\" cellpadding=\"2\" border=\"1\">\n";
    my $bg = "2";
    foreach my $type ( sort keys %SCANS ) {
        print "<tr class=\"tdshade$bg\">\n";
        if ( grep( /^${type}$/, @scans ) ) {
            print "<td><input type=\"checkbox\" name=\"${type}\" CHECKED>";
        }
        else {
            print "<td><input type=\"checkbox\" name=\"${type}\">";
        }
        print "$SCANS{$type}</input></td>\n";
        print "</tr>\n";
        if   ( $bg eq "2" ) { $bg = "1"; }
        else                { $bg = "2"; }
    }
    print "</table><p><div align=\"center\"><input type=\"submit\" value=\"Save Defaults\"></div></p>\n";
    print "</form></fieldset>\n";

    # Go Back..
    print "<br><br><br>\n";
    print "<div align=\"center\"><a href=\"addon_clamavconnector.cgi\">[ Go Back ]</a></div>\n";
}

################################################################################
# loadClamavConf
################################################################################
sub loadClamavConf {
    my %conf;

    my $config = $prefix . "/etc/cpclamav.conf";

    if ( -e $config ) {
        open( CONF, "<", $config );
        while (<CONF>) {
            chomp();
            my ( $var, $val ) = split( /=/, $_ );
            $conf{$var} = $val;
        }
        close(CONF);
    }
    return %conf;
}

################################################################################
# loadUserConf
################################################################################
sub loadUserConf {
    my ($user) = @_;

    if ( $user !~ /$looselyValidName/ ) { return undef; }

    if ( !-e "/var/cpanel/users/" . $user ) { return undef; }

    open( CONF, "<", "/var/cpanel/users/" . $user ) or return undef;
    my @lconf = <CONF>;
    close(CONF);
    @lconf = map { chomp; $_ } @lconf;
    my %conf;
    foreach my $line (@lconf) {
        next if ( $line =~ /^[\s\t]*$/ );
        my ( $var, $val ) = split( /=/, $line );
        $conf{$var} = $val;
    }
    return %conf;
}

################################################################################
# deleteUser
################################################################################
sub deleteUser {
    my ($user) = @_;
    return 1 if ( $user eq "" || $user !~ /$looselyValidName/ );

    my $config = $prefix . "/etc/cpclamav.conf";
    my %conf   = loadClamavConf();
    my @users  = split( /,/, $conf{'CLAMAVOVERRIDEUSERS'} );

    if ( !grep( /^${user}$/, @users ) ) {
        return 2;
    }

    my @newusers = grep( !/^${user}$/i, @users );
    $conf{'CLAMAVOVERRIDEUSERS'} = join( ',', @newusers );
    flushConfig( \%conf, $config );
    return 0;
}

################################################################################
# deleteAllUsers
################################################################################
sub deleteAllUsers {

    my $config = $prefix . "/etc/cpclamav.conf";

    my %conf = loadClamavConf();
    $conf{'CLAMAVOVERRIDEUSERS'} = "";
    flushConfig( \%conf, $config );
    my @userlist = getUserList();
    foreach my $user (@userlist) {
        removeUserConfig($user);
    }
}

################################################################################
# addUser
################################################################################
sub addUser {
    my ($user) = @_;
    return 1 if ( $user eq "" || $user !~ /$looselyValidName/ );

    my $config = $prefix . "/etc/cpclamav.conf";

    my %conf = loadClamavConf();
    my @users = split( /,/, $conf{'CLAMAVOVERRIDEUSERS'} );
    if ( !grep( /^$user$/, @users ) ) {
        push @users, $user;
    }
    $conf{'CLAMAVOVERRIDEUSERS'} = join( ',', @users );

    flushConfig( \%conf, $config );

    return 0;
}

################################################################################
# addAllUsers
################################################################################
sub addAllUsers {
    my @users  = getUserList();
    my %conf   = loadClamavConf();
    my @cusers = split( /,/, $conf{'CLAMAVOVERRIDEUSERS'} );

    my $config = $prefix . "/etc/cpclamav.conf";

    push @cusers, @users;
    $conf{'CLAMAVOVERRIDEUSERS'} = join( ',', @cusers );
    flushConfig( \%conf, $config );

    return 0;
}

################################################################################
# getUserList
################################################################################
sub getUserList {
    my @users = `ls -1 /var/cpanel/users/`;

    # Case 59175: If a file in this directory contains bad characters, skip it.
    @users = map { chomp($_); /$looselyValidName/ ? $_ : (); } @users;
    return @users;
}

################################################################################
# flushConfig
################################################################################
sub flushConfig {
    my ( $conf, $filename ) = @_;

    my @aconf = map( "$_=$$conf{$_}", sort keys %$conf );
    open( CONF, ">", $filename ) or return 0;
    flock( CONF, 2 );
    print CONF join( "\n", @aconf );
    print CONF "\n";
    flock( CONF, 8 );
    close(CONF);
    return 1;
}

################################################################################
# configureUser
################################################################################
sub configureUser {
    my $configPath = "/var/cpanel/users/" . $FORM{'user'};
    return 1 if ( $FORM{'user'} eq "" || $FORM{'user'} !~ /$looselyValidName/ || !-e $configPath );
    my %u_config   = loadUserConf( $FORM{'user'} );
    my @validscans = ();
    foreach my $type ( keys %SCANS ) {
        if ( $FORM{$type} eq "on" ) {
            push( @validscans, $type );
        }
    }
    if ( $#validscans == -1 ) {
        $g_conf{'CLAMAVSCANS'} = 0;
    }
    $u_config{'CLAMAVSCANS'} = join( ",", @validscans );
    flushConfig( \%u_config, $configPath );
}

################################################################################
# removeUserConfig
################################################################################
sub removeUserConfig {
    my $user = "";
    if ( defined( $FORM{'user'} ) ) {
        $user = $FORM{'user'};
    }
    else {
        $user = shift;
    }
    my $configPath = "/var/cpanel/users/" . $user;
    if ( !defined($user) || $user eq "" || $user !~ /$looselyValidName/ || !-e $configPath ) { return; }
    my %config = loadUserConf($user);
    delete( $config{'CLAMAVSCANS'} );
    flushConfig( \%config, $configPath );
}

################################################################################
# configureAllUsers
################################################################################
sub configureAllUsers {
    my @userlist = getUserList();
    foreach my $user (@userlist) {
        my $configPath = "/var/cpanel/users/" . $user;
        next if ( !-e $configPath );
        my %u_config = loadUserConf($user);
        next if ( defined( $u_config{'CLAMAVSCANS'} ) );
        my @validscans = ();
        foreach my $type ( keys %SCANS ) {
            if ( $FORM{$type} eq "on" ) {
                push( @validscans, $type );
            }
        }
        if ( $#validscans == -1 ) {
            $g_conf{'CLAMAVSCANS'} = 0;
        }
        $u_config{'CLAMAVSCANS'} = join( ",", @validscans );
        flushConfig( \%u_config, $configPath );
    }
}

################################################################################
# modifyDefaults
################################################################################
sub modifyDefaults {
    my @defaults = ();

    my $config = $prefix . "/etc/cpclamav.conf";

    foreach my $type ( sort keys %SCANS ) {
        if ( $FORM{$type} eq "on" ) {
            push( @defaults, $type );
        }
    }

    my %g_conf = loadClamavConf();
    $g_conf{'DEFAULTSCANS'} = join( ',', @defaults );

    if ( $#defaults == -1 ) {
        $g_conf{'DEFAULTSCANS'} = 0;
    }

    flushConfig( \%g_conf, $config );
}

################################################################################
# modifyDefaultOverrides
################################################################################
sub modifyDefaultOverrides {
    my @defaults = ();

    my $config = $prefix . "/etc/cpclamav.conf";

    foreach my $type ( sort keys %SCANS ) {
        if ( $FORM{$type} eq 'on' ) {
            push( @defaults, $type );
        }
    }

    my %g_conf = loadClamavConf();
    $g_conf{'DEFAULTSCANOVERRIDES'} = join( ',', @defaults );

    if ( $#defaults == -1 ) {
        $g_conf{'DEFAULTSCANS'} = 0;
    }

    flushConfig( \%g_conf, $config );
}

1;
Back to Directory File Manager