Users probe for collected user data, ssh keys, crontabs
Robert 'phaylon' Sedlacek [Thu, 3 May 2012 02:42:07 +0000 (02:42 +0000)]
lib/System/Introspector/Users.pm [new file with mode: 0644]

diff --git a/lib/System/Introspector/Users.pm b/lib/System/Introspector/Users.pm
new file mode 100644 (file)
index 0000000..938f4a4
--- /dev/null
@@ -0,0 +1,77 @@
+package System::Introspector::Users;
+use Moo;
+use IPC::Run qw( run );
+
+sub gather {
+    my ($self) = @_;
+    my $fh = $self->_open_passwd_fh;
+    my %user;
+    while (defined( my $line = <$fh> )) {
+        my $data = $self->_deparse_htpasswd_line($line);
+        my $user = $data->{username};
+        my $home = $data->{home};
+        $data->{groups}    = $self->_gather_user_groups($user);
+        $data->{ssh}{keys} = $self->_gather_ssh_keys($user, $home);
+        $data->{crontab}   = $self->_gather_crontab($user);
+        $user{ $data->{uid} } = $data;
+    }
+    return \%user;
+}
+
+sub _gather_crontab {
+    my ($self, $user) = @_;
+    my ($in, $out, $err) = (('') x 3);
+    run(['crontab', '-u', $user, '-l'], \$in, \$out, \$err);
+    if (length $err) {
+        return {}
+            if $err =~ m{^no crontab}i;
+        return { error => $err };
+    }
+    return { body => $out };
+}
+
+sub _gather_ssh_keys {
+    my ($self, $user, $home) = @_;
+    my $ssh_dir = "$home/.ssh/";
+    return {}
+        unless -d $ssh_dir;
+    my $dh;
+    opendir $dh, $ssh_dir
+        or return { error => $! };
+    my %key;
+    while (defined( my $item = readdir $dh )) {
+        next unless $item =~ m{\.pub$};
+        my $item_path = "$ssh_dir/$item";
+        open my $key_fh, '<', $item_path;
+        if ($key_fh) {
+            $key{ $item }{body} = do { local $/; <$key_fh> };
+        }
+        else {
+            $key{ $item }{error} = $!;
+        }
+    }
+    return { files => \%key };
+}
+
+sub _gather_user_groups {
+    my ($self, $user) = @_;
+    return [split m{\s+}, `groups $user`];
+}
+
+sub _deparse_htpasswd_line {
+    my ($self, $line) = @_;
+    chomp $line;
+    my %value;
+    @value{qw( username uid gid comment home shell )}
+        = (split m{:}, $line)[0, 2..6];
+    return \%value;
+}
+
+sub _open_passwd_fh {
+    my ($self) = @_;
+    open my $fh, '<', '/etc/passwd'
+        or die "Unable to open /etc/passwd: $!\n";
+    return $fh;
+}
+
+1;