#!/usr/bin/perl -w # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 1, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # use strict; my $i = 0; my $passwd = "/etc/passwd"; print "Checking SSH userfiles for problems\n"; open (PASSWD, "<$passwd") or die ("Couldn't open $passwd for reading, perhaps you did something?\n"); flock (PASSWD, 2); until (eof PASSWD) { my @line; if (@line = split (":", readline (*PASSWD))) { if (!($line[0] =~ /[#]/)) { determine_config($line[0], $line[2], $line[5]); } } } flock (PASSWD, 8); close (PASSWD); ############################################################### # cleanup: gets rid of any temporary files, via simple rm -Rf ############################################################### sub cleanup { my $t = $_[0]; my $command = "rm -Rf $t"; system($command); } ############################################################### # determine_config: goes through all the files in the dir # checks permissions, and reports. ############################################################### sub determine_config { my $user = $_[0]; my $uid = $_[1]; my $homedir = $_[2]; my $ssh_dir = $homedir . "/.ssh"; my @listing; #print "user: $user home: $homedir uid: $uid\n"; # take the configuration directory, get a listing of all the files for processing if (opendir (SSH, $ssh_dir)) { @listing = readdir (SSH); closedir (SSH); } else { print ("--INFO-- [sshc001i] $user does not have a .ssh directory\n"); } # The following permission settings have been chosen for several reasons # 1) if a file is executable, it may be a script of some sort..better to be safe then sorry # 2) they are rather conservative so information leakage is minimized for ($i = 2; $i <= $#listing; $i++) { #print "Working on file $ssh_dir/$listing[$i]\n"; my @file = stat ($ssh_dir . "/". $listing[$i]); if ($file[2] & 020) { print ("--FAIL-- [sshc001f] File $ssh_dir/$listing[$i] is group writable\n"); } if ($file[2] & 002) { print ("--FAIL-- [sshc002f] File $ssh_dir/$listing[$i] is world writable\n"); } if ($file[2] & 040) { print ("--FAIL-- [sshc003f] File $ssh_dir/$listing[$i] is world readable\n"); } if ($file[2] & 004) { print ("--FAIL-- [sshc004f] File $ssh_dir/$listing[$i] is world readable\n"); } if ($file[2] & 010) { print ("--WARN-- [sshc001w] File $ssh_dir/$listing[$i] is world executeable\n"); } if ($file[2] & 001) { print ("--WARN-- [sshc002w] File $ssh_dir/$listing[$i] is world executeable\n"); } if ($file[2] & 200) { if (!($listing[$i] =~ /[known]/) || !($listing[$i] =~ /[auth]/)) { print("--WARN-- [sshc003w] File $ssh_dir/$listing[$i] is user writable, and shouldn't be\n"); } } if ($file[2] & 100) { print ("--WARN-- [sshc003w] File $ssh_dir/$listing[$i] is user executable, and shouldn't be\n"); } if ($file[2] & 000) { print ("--WARN-- [sshc004w] File $ssh_dir/$listing[$i] has no perms\n"); } if ($listing[$i] =~ /[known]/) { open (TEMP, "<$ssh_dir/$listing[$i]"); flock (TEMP, 2); my @line; until (eof TEMP) { @line = split (" ", readline (*TEMP)); print ("--INFO-- [sshc002i] $ssh_dir/$listing[$i] knows of host: $line[0]\n"); } flock (TEMP, 8); close (TEMP); } } }