Skip to content

Commit

Permalink
Various improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
oyvindhagberg committed Jan 26, 2018
1 parent 80abec4 commit 36f1850
Show file tree
Hide file tree
Showing 11 changed files with 162 additions and 95 deletions.
34 changes: 32 additions & 2 deletions client/nivlheim_client
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ my %defaultopt = (
my $NAME = 'nivlheim_client';
my $AUTHOR = 'Øyvind Hagberg';
my $CONTACT = '[email protected]';
my $RIGHTS = 'USIT/IT-DRIFT/GD/GID, University of Oslo';
my $RIGHTS = 'USIT/IT-DRIFT/GD/GID, University of Oslo, Norway';
open(my $F, "/etc/nivlheim/version");
chomp(my $VERSION = <$F>);
close($F);
Expand Down Expand Up @@ -293,6 +293,21 @@ elsif ($have_cert && !$cert_works) {
# Determine which files to send
my @filelist = keys %{$config{'files'}};

# Make sure essential files are on the list
my @essentials = (
"/etc/redhat-release",
"/etc/debian_version",
"/etc/lsb-release",
"/usr/lib/os.release.d/os-release-workstation",
"/usr/lib/os.release.d/os-release-server",
"/usr/lib/os.release.d/os-release-cloud"
);
foreach my $e (@essentials) {
if (!grep {$e eq $_} @filelist) {
push @filelist, $e;
}
}

# Create tar archive
my $tar = Archive::Tar->new();

Expand All @@ -312,8 +327,23 @@ for my $filename (@filelist) {
}
}

# Run all the commands, collect the output and store it
# Get the list of commands
my @cmdlist = keys %{$config{'commands'}};

# Make sure essential commands are on the list
@essentials = (
"/bin/uname -a",
"/usr/bin/dpkg-query -l",
"/usr/bin/sw_vers",
"/usr/sbin/dmidecode -t system"
);
foreach my $e (@essentials) {
if (!grep {$e eq $_} @cmdlist) {
push @cmdlist, $e;
}
}

# Run all the commands, collect the output and store it
foreach my $cmd (@cmdlist) {
# if it got parsed erroneously and is split on /=/, re-assemble it
if (defined($config{'commands'}{$cmd})) {
Expand Down
6 changes: 0 additions & 6 deletions rpm/buildrpm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,4 @@ do
rm -f /var/lib/mock/$config/result/*.src.rpm
rpmlint -i /var/lib/mock/$config/result/*.rpm || exit 1
echo ""

#if [ "$GIT_BRANCH" = "origin/master" ]; then
# cp -v /var/lib/mock/$config/result/*.rpm /var/www/html/repo || exit 1
# cd /var/www/html/repo
# createrepo . || exit 1
#fi
done
4 changes: 2 additions & 2 deletions rpm/test_packages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ fi

# wait for server to process incoming data
OK=0
for try in {1..30}; do
sleep 1
for try in {1..20}; do
sleep 3
if [ $(curl -s -k https://localhost/ | grep -c "novalocal") -gt 0 ]; then
OK=1
break
Expand Down
149 changes: 95 additions & 54 deletions server/cgi/parsefile
Original file line number Diff line number Diff line change
Expand Up @@ -71,49 +71,84 @@ eval{
}

# Detect if a host got a new certificate. Clean up the old one, in that case
my $rv = $dbh->do("DELETE FROM hostinfo WHERE hostname=? AND (certfp is null OR certfp != ?)",
$rv = $dbh->do("DELETE FROM hostinfo WHERE hostname=? AND (certfp is null OR certfp != ?)",
undef, ($row->{'hostname'}, $row->{'certfp'}));
if ($rv > 0) {
$logger->info("It seems " . $row->{'hostname'} . " got a new certificate.");
}

# Different files must be parsed differently
if ($row->{'filename'} eq "/etc/redhat-release") {
my ($os, $type);
my ($os, $os_edition);
if ($row->{'content'} =~ /^Red Hat Enterprise Linux (\w+).*Tikanga/) {
$os = 'RHEL5';
$type = $1;
$os = 'RHEL 5';
$os_edition = $1;
}
elsif ($row->{'content'} =~ /^Red Hat Enterprise Linux (\w+).*Santiago/) {
$os = 'RHEL6';
$type = $1;
$os = 'RHEL 6';
$os_edition = $1;
}
elsif ($row->{'content'} =~ /^Red Hat Enterprise Linux (\w+).*Maipo/) {
$os = 'RHEL7';
$type = $1;
$os = 'RHEL 7';
$os_edition = $1;
}
elsif ($row->{'content'} =~ /^Fedora.*Schrödinger/) {
$os = 'Fedora19';
$type = 'Workstation';
elsif ($row->{'content'} =~ /^Fedora release (\d+)/i) {
$os = "Fedora $1";
}
elsif ($row->{'content'} =~ /^Fedora.*Heisenbug/) {
$os = 'Fedora20';
$type = 'Workstation';
elsif ($row->{'content'} =~ /^CentOS Linux release (\d+)/) {
$os = "CentOS $1";
}
elsif ($row->{'content'} =~ /^Fedora release (\d+)/i) {
$os = "Fedora$1";
$type = 'Workstation';
my $sth;
if (defined($os_edition)) {
$sth = $dbh->prepare("UPDATE hostinfo SET os=?, os_edition=? WHERE certfp=?");
$sth->execute(($os, $os_edition, $row->{'certfp'}));
} else {
$sth = $dbh->prepare("UPDATE hostinfo SET os=? WHERE certfp=?");
$sth->execute(($os, $row->{'certfp'}));
}
my $sth = $dbh->prepare("UPDATE hostinfo SET os=?, osclass='Linux', type=? WHERE certfp=?");
$sth->execute(($os, $type, $row->{'certfp'}));
$sth->finish;
}

if ($row->{'filename'} eq "/usr/lib/os.release.d/os-release-workstation") {
my $os_edition = 'Workstation';
my $sth = $dbh->prepare("UPDATE hostinfo SET os_edition=? WHERE certfp=?");
$sth->execute(($os_edition, $row->{'certfp'}));
$sth->finish;
}

if ($row->{'filename'} eq "/usr/lib/os.release.d/os-release-server") {
my $os_edition = 'Server';
my $sth = $dbh->prepare("UPDATE hostinfo SET os_edition=? WHERE certfp=?");
$sth->execute(($os_edition, $row->{'certfp'}));
$sth->finish;
}

if ($row->{'filename'} eq "/usr/lib/os.release.d/os-release-cloud") {
my $os_edition = 'Cloud';
my $sth = $dbh->prepare("UPDATE hostinfo SET os_edition=? WHERE certfp=?");
$sth->execute(($os_edition, $row->{'certfp'}));
$sth->finish;
}

if ($row->{'filename'} eq "/usr/bin/dpkg-query -l") {
my $os_edition;
if ($row->{'content'} =~ /ubuntu-desktop/) {
$os_edition = 'Desktop';
} elsif ($row->{'content'} =~ /ubuntu-server/) {
$os_edition = 'Server';
}
if (defined($os_edition)) {
my $sth = $dbh->prepare("UPDATE hostinfo SET os_edition=? WHERE certfp=?");
$sth->execute(($os_edition, $row->{'certfp'}));
$sth->finish;
}
}

if ($row->{'filename'} eq "/etc/debian_version") {
if ($row->{'content'} =~ /^(\d+)\./) {
my $os = "Debian$1";
my $sth = $dbh->prepare("UPDATE hostinfo SET os=?, osclass='Linux', "
."type=null WHERE certfp=?");
my $os = "Debian $1";
my $sth = $dbh->prepare("UPDATE hostinfo SET os=?, "
."os_edition=null WHERE certfp=?");
$sth->execute(($os, $row->{'certfp'}));
$sth->finish;
}
Expand All @@ -122,69 +157,75 @@ eval{
if ($row->{'filename'} eq "/etc/lsb-release") {
if ($row->{'content'} =~ /DISTRIB_ID=Ubuntu.*DISTRIB_RELEASE=(\d+)\.(\d+)/s) {
my $os = "Ubuntu $1.$2";
my $sth = $dbh->prepare("UPDATE hostinfo SET os=?, osclass='Linux', "
."type=null WHERE certfp=?");
my $sth = $dbh->prepare("UPDATE hostinfo SET os=? "
."WHERE certfp=?");
$sth->execute(($os, $row->{'certfp'}));
$sth->finish;
}
}

if ($row->{'filename'} eq "/usr/bin/sw_vers"
&& $row->{'content'} =~ /ProductName:\s+Mac OS X\nProductVersion:\s+([\d\.]+)/) {
my $os = "OSX $1";
my $sth = $dbh->prepare("UPDATE hostinfo SET os=?, osclass='Darwin', "
."type='Workstation' WHERE certfp=?");
&& $row->{'content'} =~ /ProductName:\s+Mac OS X\nProductVersion:\s+(\d+\.\d+)/) {
my $os = "macOS $1";
my $sth = $dbh->prepare("UPDATE hostinfo SET os=?, "
."os_edition=null WHERE certfp=?");
$sth->execute(($os, $row->{'certfp'}));
$sth->finish;
# There is a product called macOS Server, but I don't know how to
# distinguish it from the "plain" macOS.
# https://en.wikipedia.org/wiki/MacOS_Server
}

if ($row->{'filename'} eq "(Get-WmiObject Win32_OperatingSystem).Caption") {
my $s = $row->{'content'};
my ($os, $type);
my ($os, $os_edition);
if ($s =~ /Microsoft Windows 7/) {
$os = 'Win7';
$type = 'Workstation';
$os = 'Windows 7';
}
elsif ($s =~ /Microsoft Windows 10/) {
$os = 'Windows 10';
}
elsif ($s =~ /Microsoft Windows Server 2008 R2/) {
$os = 'Win2008R2';
$type = 'Server';
$os = 'Windows 2008 R2';
$os_edition = 'Server';
}
elsif ($s =~ /Microsoft.+Windows.+Server.+2008.+(Standard|Enterprise)/) {
$os = 'Win2008';
$type = 'Server';
$os = 'Windows 2008';
$os_edition = 'Server';
}
elsif ($s =~ /Microsoft Windows Server 2012 R2/) {
$os = 'Win2012R2';
$type = 'Server';
$os = 'Windows 2012 R2';
$os_edition = 'Server';
}
elsif ($s =~ /Microsoft Windows Server 2012/) {
$os = 'Win2012';
$type = 'Server';
$os = 'Windows 2012';
$os_edition = 'Server';
}
elsif ($s =~ /Microsoft Windows Server 2016/) {
$os = 'Win2016';
$type = 'Server';
$os = 'Windows 2016';
$os_edition = 'Server';
}
my $sth;
if (defined($os_edition)) {
$sth = $dbh->prepare("UPDATE hostinfo SET os=?, os_edition=? WHERE certfp=?");
$sth->execute(($os, $os_edition, $row->{'certfp'}));
} else {
$sth = $dbh->prepare("UPDATE hostinfo SET os=? WHERE certfp=?");
$sth->execute(($os, $row->{'certfp'}));
}
my $sth = $dbh->prepare("UPDATE hostinfo SET os=?, type=?, osclass='Windows' "
." WHERE certfp=?");
$sth->execute(($os, $type, $row->{'certfp'}));
$sth->finish;
}

# kernel and os
# kernel
if ($row->{'filename'} eq "/bin/uname -a"
&& $row->{'content'} =~ /(\S+) \S+ (\S+)/) {
my $osclass = $1;
my $os = $1;
my $kernel = $2;
$dbh->do("UPDATE hostinfo SET kernel=? WHERE certfp=?", undef,
($kernel, $row->{'certfp'}));
if ($osclass eq 'Darwin') {
$dbh->do("UPDATE hostinfo SET osclass='Darwin' WHERE certfp=?", undef,
($row->{'certfp'}));
}
if ($osclass eq 'FreeBSD' && $kernel =~ /^(\d+)/) {
my $os = "FreeBSD$1";
$dbh->do("UPDATE hostinfo SET osclass='BSD', os=? WHERE certfp=?", undef,
if ($os eq 'FreeBSD' && $kernel =~ /^(\d+)/) {
$os = "FreeBSD $1";
$dbh->do("UPDATE hostinfo SET os=? WHERE certfp=?", undef,
($os, $row->{'certfp'}));
}
}
Expand Down Expand Up @@ -213,7 +254,7 @@ eval{
if ($info =~ /Product Name: (.*?)\s*$/m) {
$model = $1;
}
if ($info =~ /Serial Number: ([a-zA-Z0-9]+)\s*$/m) {
if ($info =~ /Serial Number: ([^\s]+)\s*$/m) {
$serial = $1;
}
$dbh->do("UPDATE hostinfo SET vendor=?, model=?, serialno=? WHERE certfp=?",
Expand Down
1 change: 1 addition & 0 deletions server/cgi/post
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ eval {
print $F "certfp = $fingerprint\n";
print $F "ip = $ipaddr\n";
print $F "clientversion = $clientversion\n";
print $F "received = ".time()."\n";
close($F);

# Response
Expand Down
26 changes: 14 additions & 12 deletions server/cgi/processarchive
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@ if (!$dbh) {

# Check parameters
my %params = parse_query_string();
unless (exists $params{'archivefile'}) {
print "Status: 400\n\nMissing parameter: archivefile\n";
unless (exists $params{'file'}) {
print "Status: 400\n\nMissing parameter: file\n";
exit;
}
if ($params{'archivefile'} =~ m![\\/]!) {
if ($params{'file'} =~ m![\\/]!) {
print "Status: 403\n\n";
exit;
}
my $archivefile = $params{'archivefile'};
my $archivefile = $params{'file'};
$archivefile = "$confdir/queue/$archivefile";
unless (-r $archivefile) {
print "Status: 410\n\nCan't find the archive file.\n";
Expand All @@ -66,10 +66,10 @@ eval{
$logger->debug("Unpacking into $dir");
chdir($dir);
if ($archivefile =~ /\.tgz$/) {
run_command("/bin/tar -xzmf $archivefile");
run_command("/bin/tar -xzf $archivefile");
}
elsif ($archivefile =~ /\.zip$/) {
run_command("/usr/bin/unzip -Doqq $archivefile 2>&1");
run_command("/usr/bin/unzip -oqq $archivefile 2>&1");
}
else {
# The way the client is currently written, this will not happen.
Expand Down Expand Up @@ -118,9 +118,11 @@ eval{
}
close($F);

my $iso_received = uts_to_iso8601($meta{'received'});

my $sth = $dbh->prepare("INSERT INTO files(ipaddr,clienthostname,"
."certcn,certfp,filename,received,content,is_command,clientversion) "
."VALUES(?,?,?, ?,?,?, ?,?,?)");
."certcn,certfp,filename,received,mtime,content,is_command,clientversion) "
."VALUES(?,?,?,?, ?,?,?,?, ?,?)");

# For each file
sub callback1 {
Expand All @@ -131,12 +133,12 @@ eval{
return unless $File::Find::name =~ m!/(files|commands)/!;
$logger->debug("Processing " . basename($File::Find::name));

# Make an ISO timestamp from the modified time of the archive
# Make an ISO timestamp from the modified time of the file
my $mtime = (stat($File::Find::name))[9];
my $isotime = uts_to_iso8601($mtime);
my ($content, $originalfilename);
my $iso_mtime = uts_to_iso8601($mtime);

# Read the content
my ($content, $originalfilename);
my $is_command = ($File::Find::name =~ m!/commands/!) ? 1 : 0;
my $F;
if (!open($F, $File::Find::name)) {
Expand Down Expand Up @@ -178,7 +180,7 @@ eval{
# Run the database INSERT operation
my @values = ($meta{ip}, $meta{clienthostname},
$meta{certcn}, $meta{certfp}, $originalfilename,
$isotime, $content, $is_command,
$iso_received, $iso_mtime, $content, $is_command,
$meta{clientversion});
$sth->execute(@values) or $logger->error($sth->errstr);
}
Expand Down
Loading

1 comment on commit 36f1850

@oyvindhagberg
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolves #25

Please sign in to comment.