????

Your IP : 216.73.216.174


Current Path : /usr/lib/sonarpush/SonarPush/Providers/
Upload File :
Current File : //usr/lib/sonarpush/SonarPush/Providers/Software.pm

package SonarPush::Providers::Software;
use base qw(SonarPush::Providers);
use strict;

use SonarPush::Util;

=head1 NAME

SonarPush::Providers::Software - collects software information 

=head1 DESCRIPTION

class of tasks for collecing various information about software that
is installed on a machine

=cut

sub apache {
	my $self = shift;

	my $provider = 'apache';
	my $apache   = {
		name       => 'apache',
		attributes => {
			providedby => $provider,
			datatype   => 'Text'
		},
	};
	my $apacheMods = {
		name       => 'apachemodules',
		attributes => {
			providedby => $provider,
			datatype   => 'None'
		},
		value => [],
	};

	my @apachelocations = ("/usr/local/apache/bin/httpd", "/usr/sbin/httpd", "/usr/sbin/apache2", "/usr/sbin/apache");
	foreach my $location (@apachelocations) {
		if (-x $location) {
			my $version = `$location -v | head -n 1| awk '{print \$3}' | cut -d / -f 2`;
			$version =~ s/^\s+|\s+$//g;
			$apache->{value} = $version;
			last;
		}
	}

	if ((-e "/usr/local/cpanel/modules-install/modsecurity-Linux-i686/progversion")
		or (-e "/usr/local/cpanel/modules-install/modsecurity-Linux-x86_64/progversion")) {
		my $modSec = {
			name       => 'mod_security',
			attributes => {
				providedby => $provider,
				datatype   => 'Text'
			},
		};
		push(@{ $apacheMods->{value} }, $modSec);

		my $flag = 1;

		{
			local $/;
			open(INPUT, "< /usr/local/cpanel/modules-install/modsecurity-Linux-i686/progversion") or $flag = 0;
			if (!$flag) {
				open(INPUT, "< /usr/local/cpanel/modules-install/modsecurity-Linux-x86_64/progversion") or $flag = 0;
			}

			if ($flag) {
				my $input = <INPUT>;
				if ($input =~ /\s*(\S+)\s*/) {
					$modSec->{value} = $1;
				}
			}
		}
	}

	return ($apache, $apacheMods);
}

sub clamav {
	my $self     = shift;
	my $provider = 'clamav';
	my $attrs    = {
		providedby => $provider,
		datatype   => 'Text'
	};
	my $xml = {
		name       => $provider,
		attributes => $attrs,
		value      => [],
	};

	if (-x "/usr/sbin/clamd") {
		my $input = `/usr/sbin/clamd --version`;
		$input =~ s/^\s+|\s+$//g;

		if (my ($version, $db, $timestamp) = $input =~ /^ClamAV (\S+)\/(\S+)\/(.+)$/) {
			push(@{ $xml->{value} }, { name => 'clamversion', value => $version });
			push(@{ $xml->{value} }, { name => 'dbversion',   value => $db });
			push(@{ $xml->{value} }, { name => 'dbtimestamp', value => $timestamp });
			map { $_->{attributes} = $attrs } @{ $xml->{value} };
		}
	}

	return $xml;
}

sub cpanel {
	my $self     = shift;
	my $provider = 'cpanel';
	my $attrs    = {
		providedby => $provider,
		datatype   => 'Text'
	};
	my $xml = {
		name       => $provider,
		attributes => $attrs,
	};

	{
		local $/;
		open(my $file, "< /usr/local/cpanel/version");
		if ($file) {
			my $version = <$file>;
			$version =~ s/^\s+|\s+$//g;
			$xml->{value} = $version;
		}
	}

	return $xml;
}

sub dpkglist {
	my $self     = shift;
	my $provider = 'dpkglist';
	my %attrs    = (
		config => {
			providedby => $provider,
			datatype   => 'Text'
		},
		noConfig => {
			providedby => $provider,
			datatype   => 'None'
		},
	);
	my $xml = {
		name       => $provider,
		attributes => $attrs{noConfig},
		value      => [],
	};

	my $file = "/usr/local/lp/var/sonarpush/dpkgexport";
	if (-r $file) {
		my $flag = 1;
		my $input;

		{
			local $/;
			open(INPUT, "< $file") or $flag = 0;
			if ($flag) {
				$input = <INPUT>;
			}
		}

		if ($flag) {
			if ($input =~ /^([0-9]{10})\n(.*)/s) {
				my $list = SonarPush::Util::encode_entities($2);
				push(@{ $xml->{value} }, { name => 'timestamp', value => $1 });
				push(@{ $xml->{value} }, { name => 'list',      value => $list });
				map { $_->{attributes} = $attrs{config} } @{ $xml->{value} };
			}
		}
	}
	return $xml;
}

sub exim {
	my $self     = shift;
	my $provider = 'exim';
	my %attrs    = (
		config => {
			providedby => $provider,
			datatype   => 'Text'
		},
	);
	my $xml = {
		name       => $provider,
		attributes => $attrs{config},
	};

	if (-x "/usr/sbin/exim") {
		my $input = `/usr/sbin/exim -bV`;

		if ($input =~ /Exim version (\S+) #(\d+) built (.+)$/m) {
			## Can improve a bit here on what is returned
			$xml->{value} = $1;
		}
	}

	return $xml;
}

sub lpsoftware {
	my $self     = shift;
	my $provider = 'lp-software';
	my %attrs    = (
		config => {
			providedby => $provider,
			datatype   => 'Text'
		},
		noConfig => {
			providedby => $provider,
			datatype   => 'None'
		},
	);
	my $xml = {
		name       => $provider,
		attributes => $attrs{noConfig},
		value      => [],
	};

	my $sonarVersion = $self->sonar->version;

	if (defined($sonarVersion)) {
		push(@{ $xml->{value} }, { name => 'SonarPush', value => "Linux-$sonarVersion" });
	}

	my $input;
	my $flag;

	my $file    = '/usr/local/lp/apps/security/infected.pl';
	my $version = 'Unable to determine version.';
	if (-e $file) {
		my $contents = do {
			local $/;
			open(my $INPUT, '<', $file);
			<$INPUT>;
		};

		if ($contents =~ /\$version\s*?=\s*?"(.*?)"\s*?;/) {
			$version = $1;
		}
	}
	push(@{ $xml->{value} }, { name => 'infected.pl', value => $version });

	$file    = '/usr/local/apache/conf/modsec.user.conf';
	$version = 'Not Present';
	if (-e $file) {
		my $contents = do {
			local $/;
			open(my $INPUT, '<', $file);
			<$INPUT>;
		};
		if ($contents) {
			if ($contents =~ /### Modsec rules v(\S+) ###/) {
				$version = $1;
			}
			else {
				$version = "Custom";
			}
		}
	}
	push(@{ $xml->{value} }, { name => 'lp-modsecrules', value => $version });

	if (-e "/usr/local/lp/apps/autoupdate/lp-autoupdate.pl") {
		my $autoUpdate = { name => 'lp-autoupdate', attributes => $attrs{noConfig}, value => [] };
		$flag = 1;
		{
			local $/;
			open(INPUT, "< /usr/local/lp/apps/autoupdate/lp-autoupdate.pl") or $flag = 0;
			if ($flag) {
				$input = <INPUT>;
			}
		}

		if ($flag) {
			if ($input =~ /### lp-autoupdate v(\S+) ###/) {
				push(@{ $autoUpdate->{value} }, { name => 'lp-autoupdate.pl', value => $1, attributes => $attrs{config} });
			}
		}

		$flag = 1;
		{
			local $/;
			open(INPUT, "< /usr/local/lp/var/autoupdate/serial") or $flag = 0;
			if ($flag) {
				$input = <INPUT>;
			}
		}

		if ($flag) {
			if ($input =~ /LastUpdate: (\d+)/) {
				push(@{ $autoUpdate->{value} }, { name => 'serial', value => $1, attributes => $attrs{config} });
			}
		}
		push(@{ $xml->{value} }, $autoUpdate);
	}

	if (-e "/usr/local/lp/etc/skel-version") {
		$flag = 1;
		{
			local $/;
			open(INPUT, "< $file") or $flag = 0;
			if ($flag) {
				$input = <INPUT>;
			}
		}

		if ($flag) {
			if ($input =~ /\s*(\S+)\s*/) {
				push(@{ $xml->{value} }, { name => 'lp-skel', value => $1 });
			}
		}
	}

	#lp rpms
	my @rpmlist = ("lp-apf", "lp-bfd", "lp-modevasive", "lp-chkrootkit", "lp-rkhunter");
	my $rpmverpath = "/usr/local/lp/rpmver/";

	foreach my $file (@rpmlist) {
		if (-e $rpmverpath . $file) {
			$flag = 1;
			{
				local $/;
				open(INPUT, "< " . $rpmverpath . $file) or $flag = 0;
				if ($flag) {
					$input = <INPUT>;
				}
			}

			if ($flag) {
				if ($input =~ /\s*(\S+)\s*/) {
					push(@{ $xml->{value} }, { name => $file, value => $1 });
				}
			}
		}
	}

	$file = "/etc/lwversion";
	if (-e $file) {
		$flag = 1;
		{
			local $/;
			open(INPUT, "< $file") or $flag = 0;
			if ($flag) {
				$input = <INPUT>;
			}
		}

		if ($flag) {
			if ($input =~ /\s*(\S+)\s*/) {
				push(@{ $xml->{value} }, { name => 'initadmin', value => $1 });
			}
		}
	}

	# status on patches
	my $lpPatches = { name => 'lp-patches', attributes => $attrs{noConfig}, value => [] };
	$file = "/usr/local/lp/var/fstabpatchstatus";
	if (-e $file) {
		$flag = 1;
		{
			local $/;
			open(INPUT, "< $file") or $flag = 0;
			if ($flag) {
				$input = <INPUT>;
			}
		}

		if ($flag) {
			if ($input =~ /\s*([a-zA-Z0-9 ]+)\s*/) {
				push(@{ $lpPatches->{value} }, { name => 'CVE-2006-3626', value => $1, attributes => $attrs{config} });
			}
		}
	}

	$file = "/usr/local/lp/var/coredumppatchstatus";
	if (-e $file) {
		$flag = 1;
		{
			local $/;
			open(INPUT, "< $file") or $flag = 0;
			if ($flag) {
				$input = <INPUT>;
			}
		}

		if ($flag) {
			if ($input =~ /\s*([a-zA-Z0-9 ]+)\s*/) {
				push(@{ $lpPatches->{value} }, { name => 'CVE-2006-2451', value => $1, attributes => $attrs{config} });
			}
		}
	}

	$file = "/proc/driver/snd-page-alloc";
	if (-r $file) {
		push(@{ $lpPatches->{value} }, { name => 'CVE-2007-4571', value => 'snd-page-alloc present', attributes => $attrs{config} });
	}
	else {
		push(@{ $lpPatches->{value} }, { name => 'CVE-2007-4571', value => 'snd-page-alloc not present', attributes => $attrs{config} });
	}

	$file = "/usr/local/lp/var/yumvskern.run";
	if (-e $file) {
		my $node = { name => 'yumvskern', attributes => $attrs{config} };
		$file = "/usr/local/lp/var/yumvskern";
		if (-e $file) {
			$flag = 1;
			{
				local $/;
				open(INPUT, "< $file") or $flag = 0;
				if ($flag) {
					$input = <INPUT>;
				}
			}

			if ($flag) {
				if ($input =~ /\s*([a-zA-Z0-9 ]+)\s*/) {
					$node->{value} = $1;
				}
			}
		}
		else {
			$node->{value} = "noactiontaken";
		}
		push(@{ $lpPatches->{value} }, $node);
	}

	push(@{ $xml->{value} }, $lpPatches);

	map { $_->{attributes} = $attrs{config} } grep { !exists $_->{attributes} } @{ $xml->{value} };

	return $xml;
}

sub mailman {
	my $self     = shift;
	my $provider = 'mailman';
	my $attrs    = {
		providedby => $provider,
		datatype   => 'Text'
	};
	my $xml = {
		name       => $provider,
		attributes => $attrs,
	};
	if (-e "/usr/local/cpanel/3rdparty/mailman/Mailman/Version.py") {
		my $flag = 1;
		my $input;
		{
			local $/;
			open(INPUT, "< /usr/local/cpanel/3rdparty/mailman/Mailman/Version.py") or $flag = 0;
			if ($flag) {
				$input = <INPUT>;
			}
		}

		if ($flag) {
			if ($input =~ /^VERSION\s=\s\'(\S+)\'$/m) {
				$xml->{value} = $1;
			}
		}
	}

	return $xml;
}

sub mysql {
	my $self     = shift;
	my $provider = 'mysql';
	my $attrs    = {
		providedby => $provider,
		datatype   => 'Text'
	};
	my $xml = {
		name       => $provider,
		attributes => $attrs,
	};

	my @mysqldlist = ("/usr/libexec/mysqld", "/usr/sbin/mysqld");
	my $mysqld;
	my $input;
	my $found = 0;
	foreach $mysqld (@mysqldlist) {
		if (-x $mysqld) {
			$input = `$mysqld --version`;

			## /usr/libexec/mysqld  Ver 5.0.45-log for redhat-linux-gnu on x86_64 (Source distribution)
			if ($input =~ /^\S+\s+Ver\s+(\S+)\s+for\s+\S+/) {
				$xml->{value} = $1;
				$found = $mysqld;
				last;
			}
		}
	}

	return $xml;
}

sub named {
	my $self     = shift;
	my $provider = 'named';
	my $attrs    = {
		providedby => $provider,
		datatype   => 'Text'
	};
	my $xml = {
		name       => $provider,
		attributes => {
			providedby => $provider,
			datatype   => 'None'
		},
		value => [],
	};

	#look for caching nameserver
	my $sourcedir  = "/usr/share/doc";
	my $matchcount = 0;

	if (-d "$sourcedir") {
		if (opendir my $dh, "$sourcedir") {
			my $file;
			while ($file = readdir($dh)) {
				if (-d "$sourcedir/$file") {
					if ($file =~ /caching-nameserver/) {
						$matchcount++;
					}
				}
			}
		}
	}
	if ($matchcount > 0) {
		push(@{ $xml->{value} }, { name => 'caching-nameserver', attributes => $attrs, value => "installed" });
	}
	else {
		push(@{ $xml->{value} }, { name => 'caching-nameserver', attributes => $attrs, value => "not installed" });
	}

	# check for chroot in /etc/sysconfig/named
	if (-r "/etc/sysconfig/named") {
		my $input;
		my $flag = 1;
		{
			local $/;
			open(INPUT, "< /etc/sysconfig/named") or $flag = 0;
			if ($flag) {
				$input = <INPUT>;
			}
		}

		if ($flag) {
			if ($input =~ /^\s*ROOTDIR=/m) {
				push(@{ $xml->{value} }, { name => 'chroot', attributes => $attrs, value => 'active' });
			}
			else {
				push(@{ $xml->{value} }, { name => 'chroot', attributes => $attrs, value => 'not active' });
			}
		}
	}

	return $xml;
}

sub openssl {
	my $self     = shift;
	my $provider = 'openssl';
	my $xml      = {
		name       => $provider,
		attributes => {
			providedby => $provider,
			datatype   => 'Text'
		},
	};

	if (-x "/usr/bin/openssl") {
		if (my $input = `/usr/bin/openssl version | /usr/bin/awk '{print \$2}'`) {
			$input =~ s/\s+$//;
			$input =~ s/^\s+//;

			$xml->{value} = $input;
		}
		else {
			$xml->{value} = "ERROR";
		}
	}

	return $xml;
}

sub os {
	my $self     = shift;
	my $provider = 'os';
	my $xml      = {
		name       => $provider,
		attributes => {
			providedby => $provider,
			datatype   => 'Text'
		},
	};

	my $counter = 0;
	my $gentoo  = 0;
	my $redhat  = 0;
	my $debian  = 0;
	my $openbsd = 0;
	my $freebsd = 0;

	my $input = 0;
	my $flag  = 1;

	#take the easy (and accurate) way out, if it exists
	if (-x "/usr/bin/lsb_release") {
		$input = `/usr/bin/lsb_release -d`;

		if ($input =~ /^Description:\t(.+)$/m) {
			$xml->{value} = $1;
			return $xml;
		}
	}

	if (-e "/etc/redhat-release") {
		$counter++;
		$redhat = 1;
	}
	if (-e "/etc/gentoo-release") {
		$counter++;
		$gentoo = 1;
	}
	if (-e "/etc/debian_version") {
		$counter++;
		$debian = 1;
	}

	if ($counter == 0) {
		$xml->{value} = "Unknown";
	}
	elsif ($counter == 1) {
		if ($redhat) {
			{
				local $/;
				open(INPUT, "< /etc/redhat-release") or $flag = 0;
				if ($flag) {
					$input = <INPUT>;
				}
			}

			if ($flag) {
				$input =~ s/\s+$//;
				$input =~ s/^\s+//;

				$xml->{value} = $input;
			}
			else {
				$xml->{value} = "RedHat/Fedora: could not determine version";
			}
		}

		if ($gentoo) {
			{
				local $/;
				open(INPUT, "< /etc/gentoo-release") or $flag = 0;
				if ($flag) {
					$input = <INPUT>;
				}
			}
			if ($flag) {
				$input =~ s/\s+$//;
				$input =~ s/^\s+//;

				$xml->{value} = $input;
			}
			else {
				$xml->{value} = "Gentoo: could not determine version";
			}
		}

		if ($debian) {
			{
				local $/;
				open(INPUT, "< /etc/debian_version") or $flag = 0;
				if ($flag)
				{
					$input = <INPUT>;
				}
			}
			if ($flag) {
				$input =~ s/\s+$//;
				$input =~ s/^\s+//;

				$xml->{value} = "Debian: $input";
			}
			else {
				$xml->{value} = "Debian: could not determine version";
			}
		}
	}
	else {
		$xml->{value} = "ERROR - multiple OS signatures detected";
	}

	return $xml;
}

sub perl {
	my $self     = shift;
	my $provider = 'perl';
	my $xml      = {
		name       => $provider,
		attributes => {
			providedby => $provider,
			datatype   => 'Text'
		},
	};

	my ($perl) = `/usr/bin/perl -V`;
	$perl =~ m/\(revision (\d+?) version (\d+?) subversion (\d+?)\)/;

	$xml->{value} = join('.', $1, $2, $3);

	return $xml;
}

sub php {
	my $self     = shift;
	my $provider = 'php';
	my $xml      = {
		name       => $provider,
		attributes => {
			providedby => $provider,
			datatype   => 'Text'
		},
	};

	my $input = `php -v | grep PHP`;
	if ($input =~ /^PHP (\d+\.\d+\.\d+)\s+/m) {
		$xml->{value} = $1;
	}

	return $xml;
}

sub platform {
	my $self     = shift;
	my $provider = 'platform';
	my %attrs    = (
		config => {
			providedby => $provider,
			datatype   => 'Text'
		},
		noConfig => {
			providedby => $provider,
			datatype   => 'None'
		},
	);
	my $xml = {
		name       => $provider,
		attributes => $attrs{noConfig},
		value      => [],
	};

	my %nameFlagMap = (
		kernelname       => '-s',
		kernelrelease    => '-r',
		kernelversion    => '-v',
		hardwarename     => '-m',
		hardwareplatform => '-i',
		operatingsystem  => '-o',
		nodename         => '-n',
	);

	for my $property (sort keys %nameFlagMap) {
		my $value = `uname $nameFlagMap{$property}`;
		$value =~ s/^\s+|\s+$//g;
		push(@{ $xml->{value} }, { name => $property, value => $value, attributes => $attrs{config} });
	}

	my $kmods = {
		name       => 'kmodlist',
		attributes => $attrs{config},
	};
	my $modList = `/sbin/lsmod`;
	$modList =~ s/^\s+|\s+$//g;
	$kmods->{value} = $modList;

	return ($xml, $kmods);
}

sub rpmlist {
	my $self     = shift;
	my $provider = 'rpmlist';
	my %attrs    = (
		config => {
			providedby => $provider,
			datatype   => "Text",
		},
		noConfig => {
			providedby => $provider,
			datatype   => "None",
		},
	);
	my $xml = {
		name       => $provider,
		attributes => $attrs{noConfig},
		value      => [],
	};

	my $file = "/usr/local/lp/var/sonarpush/rpmexport";

	if (-r $file) {
		my $flag = 1;
		my $input;

		{
			local $/;
			open(INPUT, "< $file") or $flag = 0;
			if ($flag) {
				$input = <INPUT>;
			}
		}

		if ($flag) {
			if ($input =~ /^([0-9]{10})\n(.*)/s) {

				#$trans = array("\n" => "[[cr]]");
				#$list = strtr(trim($match[2]), $trans);
				my $list = SonarPush::Util::encode_entities($2);

				push(@{ $xml->{value} }, { name => 'timestamp', value => $1,    attributes => $attrs{config} });
				push(@{ $xml->{value} }, { name => 'list',      value => $list, attributes => $attrs{config} });
			}
		}
	}

	return $xml;
}

sub sshd {
	my $self     = shift;
	my $provider = 'sshd';
	my $xml      = {
		name       => $provider,
		attributes => {
			providedby => $provider,
			datatype   => 'Text'
		},
	};

	my $SSH_BINARY = '/usr/sbin/sshd';

	# Need to take advantage of a hack to get the version
	#  # sshd -OMGHAX 2>&1
	# returns
	# OpenSSH_5.1p1, OpenSSL 0.9.8g 19 Oct 2007
	# usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-f config_file]
	#             [-g login_grace_time] [-h host_key_file] [-k key_gen_time]
	#             [-o option] [-p port] [-u len]

	# Another Format:
	# sshd -OMGHAX 2>&1
	# sshd: illegal option -- O
	# sshd version OpenSSH_3.6.1p2
	# Usage: sshd [options]
	# Options:
	#   -f file    Configuration file (default /etc/ssh/sshd_config)
	#   -d         Debugging mode (multiple -d means more debugging)
	#   -i         Started from inetd
	#   -D         Do not fork into daemon mode
	#   -t         Only test configuration file and keys
	#   -q         Quiet (no logging)
	#   -p port    Listen on the specified port (default: 22)
	#   -k seconds Regenerate server key every this many seconds (default: 3600)
	#   -g seconds Grace period for authentication (default: 600)
	#   -b bits    Size of server RSA key (default: 768 bits)
	#   -h file    File from which to read host key (default: /etc/ssh/ssh_host_key)
	#   -u len     Maximum hostname length for utmp recording
	#   -4         Use IPv4 only
	#   -6         Use IPv6 only
	#  -o option  Process the option as if it was read from a configuration file.

	my $input = `$SSH_BINARY -OMGBADOPTION 2>&1`;

	if ($input =~ /^(.*?), (.*?) (\d){2} (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d{4})$/m) {

		#if ($input =~ /^(.*?), (.*?) (\d){2} ([A-Za-z]{3}) (\d{4})$/)
		$xml->{value} = $1;
	}
	elsif ($input =~ /^(.*?), (.*?) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d){2} (\d{4})$/m) {
		$xml->{value} = $1;
	}
	elsif ($input =~ /^sshd version (.*?)$/m) {
		$xml->{value} = $1;
	}

	return $xml;
}

sub suexec {
	my $self     = shift;
	my $provider = 'suexec';
	my %attrs    = (
		config => {
			providedby => $provider,
			datatype   => 'Text'
		},
	);
	my $xml = {
		name       => $provider,
		attributes => $attrs{config},
	};

	if (-x "/usr/local/apache/bin/httpd") {
		if (my $input = `/usr/local/apache/bin/httpd -l | grep suexec | awk '{print \$2}'`) {
			if ($input ne "") {
				$input =~ s/^\s+|\s+$|;//g;
			}
			else {
				$input .= "not found";
			}
			$xml->{value} = $input;
		}
	}
	return $xml;
}

sub lwVMTemplateRevision {
	my ($self) = @_;
	my $provider = 'lwVMTemplateRevision';
	my $config = {
		providedby => $provider,
		datatype   => 'Text',
	};

	if (-e '/etc/lw-build') {
		my $file = do {
			local $/;
			open(my $fh, '<', '/etc/lw-build');
			<$fh>;
		};

		my ($build, $revision) = $file =~ /(?:(?:LW BUILD:|revision))\s+(\S+)/g;
		$build    ||= 'Unkown';
		$revision ||= 'Unkown';

		return {
			name => $provider,
			attributes => {
				providedby => $provider,
				datatype   => 'None',
			},
			value => [
				{
					name       => 'build',
					attributes => $config,
					value      => $build,
				},
				{
					name       => 'revision',
					attributes => $config,
					value      => $revision,
				}
			]
		};
	}

	return;
}

1;