AuthorizedKeysCollector   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 79
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 31
c 0
b 0
f 0
dl 0
loc 79
rs 10
wmc 11

3 Methods

Rating   Name   Duplication   Size   Complexity  
A getIdentifier() 0 3 1
A parseAuthorizedKeysFile() 0 26 5
A collect() 0 37 5
1
<?php
2
3
namespace Startwind\Inventorio\Collector\System\Security;
4
5
use Startwind\Inventorio\Collector\Collector;
6
use Startwind\Inventorio\Exec\File;
7
8
class AuthorizedKeysCollector implements Collector
9
{
10
    public function getIdentifier(): string
11
    {
12
        return 'SystemSecurityAuthorizedKeys';
13
    }
14
15
    public function collect(): array
16
    {
17
        $file = File::getInstance();
18
19
        $results = [];
20
21
        // Read all user accounts from /etc/passwd
22
        $passwdLines = $file->getContents('/etc/passwd', true);
23
24
        foreach ($passwdLines as $line) {
25
            $parts = explode(':', $line);
26
            if (count($parts) < 6) {
27
                continue;
28
            }
29
30
            // Extract username, UID, and home directory
31
            [$username, , $uid, , , $homeDirectory] = array_slice($parts, 0, 6);
32
33
            // Only consider regular users (UID >= 1000) with a valid home directory
34
            if (!$file->isDir($homeDirectory)) {
35
                continue;
36
            }
37
38
            $authorizedKeysPath = $homeDirectory . '/.ssh/authorized_keys';
39
40
            // If authorized_keys exists, parse it
41
            if (!$file->fileExists($authorizedKeysPath)) {
42
                continue;
43
            }
44
    
45
            $entries = $this->parseAuthorizedKeysFile($authorizedKeysPath, $username);
46
47
            // Merge entries into the final result list
48
            $results = array_merge($results, $entries);
49
        }
50
51
        return $results;
52
    }
53
54
    /**
55
     * Parse an authorized_keys file and return structured entries including username.
56
     *
57
     * @param string $filePath Path to the authorized_keys file
58
     * @param string $username The user who owns the file
59
     * @return array List of structured authorized key entries
60
     */
61
    private function parseAuthorizedKeysFile(string $filePath, string $username): array
62
    {
63
        $entries = [];
64
65
        $lines = File::getInstance()->getContents($filePath, true);
66
67
        foreach ($lines as $line) {
68
            $line = trim($line);
69
70
            // Skip comments and empty lines
71
            if ($line === '' || str_starts_with($line, '#')) {
72
                continue;
73
            }
74
75
            // Some lines may include options before the key, like: command="..." ssh-rsa AAAA...
76
            if (preg_match('/^(ssh-(rsa|ed25519|dss)|ecdsa-[^\s]+)\s+([A-Za-z0-9+\/=]+)(\s+(.*))?$/', $line, $matches)) {
77
                $entries[] = [
78
                    'user' => $username,
79
                    'key_type' => $matches[1],
80
                    'key' => $matches[3],
81
                    'comment' => $matches[5] ?? null
82
                ];
83
            }
84
        }
85
86
        return $entries;
87
    }
88
}
89