Skip to content

Commit

Permalink
Merge branch 'ddurieux-2.4.x+dynamic_registry_collect' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
g-bougard committed Sep 27, 2018
2 parents f058d12 + 7bad05f commit d9e7a5d
Show file tree
Hide file tree
Showing 4 changed files with 216 additions and 4 deletions.
5 changes: 5 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ netdiscovery/netinventory:
* Thanks to @QuickNerd357, Brocade devices will now show serial number and
firmware informations.

collect:
* Thanks to David Durieux, add support for dynamic pattern in registry key
collect under win32. The dynamic pattern is '**' to glob subkeys like in:
HKEY_USERS/**/Software/**/**/CurrentVersion

maintenance:
* bump Maintenance task version to 1.1
* disable Maintenance task if no maintenance module could be used
Expand Down
75 changes: 73 additions & 2 deletions lib/FusionInventory/Agent/Tools/Win32.pm
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,16 @@ sub getRegistryValue {
return _call_win32_ole_dependent_api($win32_ole_dependent_api);
}

# Handle differently paths including /**/ pattern
if ($root =~ m/\/\*\*(?:\/.*|)$/ || $keyName eq '**') {
return _getRegistryDynamic(
logger => $params{logger},
path => "$root/$keyName",
valueName => $valueName,
withtype => $params{withtype}
);
}

my $key = _getRegistryKey(
logger => $params{logger},
root => $root,
Expand All @@ -260,7 +270,7 @@ sub getRegistryValue {

if ($valueName eq '*') {
my %ret;
foreach (keys %$key) {
foreach (grep { m|^/| } keys %$key) {
s{^/}{};
$ret{$_} = $params{withtype} ? [$key->GetValue($_)] : $key->{"/$_"} ;
}
Expand Down Expand Up @@ -367,7 +377,7 @@ sub getRegistryKey {
);
}

sub _getRegistryKey {
sub _getRegistryRoot {
my (%params) = @_;

## no critic (ProhibitBitwise)
Expand All @@ -381,11 +391,72 @@ sub _getRegistryKey {
) if $params{logger};
return;
}
return $rootKey;
}

sub _getRegistryKey {
my (%params) = @_;

my $rootKey = _getRegistryRoot(%params)
or return;

my $key = $rootKey->Open($params{keyName});

return $key;
}

sub _getRegistryDynamic {
my (%params) = @_;

my %ret;
my $valueName = $params{valueName};

my @rootparts = split(/\/+\*\*\/+/, $params{path}.'/', 2);
my $first = shift(@rootparts);
my $second = shift(@rootparts) || '';
$first .= '/';
$second = '/'.$second;
$second =~ s|/*$||;

my $rootSub = _getRegistryRoot(
root => $first,
logger => $params{logger}
);
return unless defined($rootSub);

foreach my $sub ($rootSub->SubKeyNames) {
if ($second =~ m/\/+\*\*(?:\/.*|)/) {
my $subret = _getRegistryDynamic(
logger => $params{logger},
path => $first.$sub.$second,
valueName => $valueName,
withtype => $params{withtype}
);
next unless defined($subret);
my ($subkey) = $second =~ /^([^*]+)\*\*(?:\/.*|)$/;
foreach my $subretkey (keys %$subret) {
$ret{$sub.$subkey.$subretkey} = $subret->{$subretkey};
}
} else {
my $key = _getRegistryRoot(
root => $first.$sub.$second,
logger => $params{logger}
);
next unless defined($key);

if ($valueName eq '*') {
foreach (grep { m|^/| } keys %$key) {
s{^/}{};
$ret{$sub.$second."/".$_} = $params{withtype} ? [$key->GetValue($_)] : $key->{"/$_"} ;
}
} elsif (exists($key->{"/$valueName"})) {
$ret{$sub.$second."/".$valueName} = $params{withtype} ? [$key->GetValue($valueName)] : $key->{"/$valueName"} ;
}
}
}
return \%ret;
}

sub _getRegistryKeyFromWMI{
my (%params) = @_;

Expand Down
134 changes: 132 additions & 2 deletions t/agent/tools/win32.t
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,47 @@ my %register = (
'/TEMP' => '%SystemRoot%\\TEMP',
'/OS' => 'Windows_NT',
}
},
'HKEY_USERS/' => {
'S-1-5-21-2246875202-1293753324-4206800371-500/' => {
'Software/' => {
'SimonTatham/' => {
'PuTTY/' => {
'/Version' => '4.1',
'SshHostKeys/' => {
'/rsa2@22:192.168.20.32' => '76f523a6eec4ea6b'
},
'/username' => 'johndoe'
}
},
'Mozilla/' => {
'Firefox/' => {
'/Version' => '59.0'
}
}
}
},
'S-1-5-21-2246875202-1293753324-4206800567-500/' => {
'/DisplayName' => 'Janine',
'Software/' => {
'SimonTatham/' => {
'PuTTY/' => {
'/Version' => '5.2',
'/username' => 'jane',
'SshHostKeys/' => {
'/rsa2@22:192.168.20.54' => 'fdfb3a2eeaa7'
}
}
},
'Mozilla/' => {
'Firefox/' => {
'/Version' => '62.0',
'Configuration/' => {},
'/Timeout' => '15'
}
}
}
}
}
);

Expand Down Expand Up @@ -235,7 +276,6 @@ my %regval_tests = (
_expected => {
'ClientID' => '0x12345678',
'Version' => '12.0.72365',
'subkey/' => undef
}
},
'teamviewerid-withtype' => {
Expand All @@ -249,12 +289,80 @@ my %regval_tests = (
_expected => {
'ClientID' => [ '0x12345678', REG_DWORD() ],
'Version' => [ '12.0.72365', REG_SZ() ],
'subkey/' => []
}
},
'temp-env' => {
path => 'HKEY_LOCAL_MACHINE/CurrentControlSet/Control/Session Manager/Environment/TEMP',
_expected => '%SystemRoot%\\TEMP'
},
'putty_keys' => {
path => 'HKEY_USERS/**/Software/SimonTatham/PuTTY/SshHostKeys/*',
_expected => {
'S-1-5-21-2246875202-1293753324-4206800371-500/Software/SimonTatham/PuTTY/SshHostKeys/rsa2@22:192.168.20.32'
=> '76f523a6eec4ea6b',
'S-1-5-21-2246875202-1293753324-4206800567-500/Software/SimonTatham/PuTTY/SshHostKeys/rsa2@22:192.168.20.54'
=> 'fdfb3a2eeaa7'
}
},
'users_software_versions' => {
path => 'HKEY_USERS/**/Software/Mozilla/Firefox/Version',
_expected => {
'S-1-5-21-2246875202-1293753324-4206800567-500/Software/Mozilla/Firefox/Version' => '62.0',
'S-1-5-21-2246875202-1293753324-4206800371-500/Software/Mozilla/Firefox/Version' => '59.0'
}
},
'users_softwares_versions' => {
path => 'HKEY_USERS/**/Software/**/**/Version',
_expected => {
'S-1-5-21-2246875202-1293753324-4206800371-500/Software/SimonTatham/PuTTY/Version' => '4.1',
'S-1-5-21-2246875202-1293753324-4206800567-500/Software/SimonTatham/PuTTY/Version' => '5.2',
'S-1-5-21-2246875202-1293753324-4206800371-500/Software/Mozilla/Firefox/Version' => '59.0',
'S-1-5-21-2246875202-1293753324-4206800567-500/Software/Mozilla/Firefox/Version' => '62.0'
}
},
'users_software_values' => {
path => 'HKEY_USERS/**/Software/**/**/*',
_expected => {
'S-1-5-21-2246875202-1293753324-4206800371-500/Software/SimonTatham/PuTTY/Version' => '4.1',
'S-1-5-21-2246875202-1293753324-4206800371-500/Software/SimonTatham/PuTTY/username' => 'johndoe',
'S-1-5-21-2246875202-1293753324-4206800567-500/Software/SimonTatham/PuTTY/Version' => '5.2',
'S-1-5-21-2246875202-1293753324-4206800567-500/Software/Mozilla/Firefox/Version' => '62.0',
'S-1-5-21-2246875202-1293753324-4206800371-500/Software/Mozilla/Firefox/Version' => '59.0',
'S-1-5-21-2246875202-1293753324-4206800567-500/Software/SimonTatham/PuTTY/username' => 'jane',
'S-1-5-21-2246875202-1293753324-4206800567-500/Software/Mozilla/Firefox/Timeout' => '15'
}
},
'users_software_values' => {
path => 'HKEY_USERS/**/Software/**/Firefox/*',
_expected => {
'S-1-5-21-2246875202-1293753324-4206800567-500/Software/Mozilla/Firefox/Version' => '62.0',
'S-1-5-21-2246875202-1293753324-4206800371-500/Software/Mozilla/Firefox/Version' => '59.0',
'S-1-5-21-2246875202-1293753324-4206800567-500/Software/Mozilla/Firefox/Timeout' => '15'
}
},
'users_vars' => {
path => 'HKEY_USERS/**/*',
_expected => {
'S-1-5-21-2246875202-1293753324-4206800567-500/DisplayName' => 'Janine'
}
},
'users_displayname' => {
path => 'HKEY_USERS/**/DisplayName',
_expected => {
'S-1-5-21-2246875202-1293753324-4206800567-500/DisplayName' => 'Janine'
}
},
'bad_glob_on_values' => {
path => 'HKEY_USERS/**/Software/**/**/**',
_expected => {}
},
'bad_glob_on_values_2' => {
path => 'HKEY_USERS/S-1-5-21-2246875202-1293753324-4206800371-500/Software/Mozilla/Firefox/**',
_expected => undef
},
'bad_glob_on_values_3' => {
path => 'HKEY_USERS/**/**',
_expected => {}
}
);

Expand Down Expand Up @@ -307,6 +415,28 @@ SKIP: {
}
);

$module->mock(
'_getRegistryRoot',
sub {
my (%params) = @_;
return unless $params{root};
my $root;
if (exists($register{$params{root}})) {
$root = { %{$register{$params{root}}} };
} else {
$root = \%register;
foreach my $part (split('/',$params{root})) {
return unless $root->{$part.'/'};
$root = { %{$root->{$part.'/'}} }
}
}
# Bless leaf as expected
map { bless $root->{$_}, 'Win32::TieRegistry' } grep { m|/$| } keys %{$root};
bless $root, 'Win32::TieRegistry';
return $root;
}
);

FusionInventory::Agent::Tools::Win32->use('getRegistryKey');
foreach my $test (keys %regkey_tests) {

Expand Down
6 changes: 6 additions & 0 deletions t/lib/fake/windows/Win32/TieRegistry.pm
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,10 @@ sub GetValue {
: $self->{$value} ;
}

sub SubKeyNames {
my ($self, $key) = @_ ;
my @keys = map { s|/$|| && $_ } grep { m|/$| } keys(%{$self});
return @keys;
}

1;

0 comments on commit d9e7a5d

Please sign in to comment.