File Coverage

blib/lib/FusionInventory/Agent/Tools/License.pm
Criterion Covered Total %
statement 15 69 21.7
branch 0 16 0.0
condition 0 3 0.0
subroutine 5 9 55.5
pod 2 2 100.0
total 22 99 22.2


line stmt bran cond sub pod time code
1             package FusionInventory::Agent::Tools::License;
2              
3 4     4   9677891 use strict;
  4         16  
  4         196  
4 4     4   24 use warnings;
  4         5  
  4         147  
5 4     4   26 use base 'Exporter';
  4         33  
  4         539  
6              
7 4     4   19 use English qw(-no_match_vars);
  4         5  
  4         34  
8              
9 4     4   2668 use FusionInventory::Agent::Tools;
  4         8  
  4         2634  
10              
11             our @EXPORT = qw(
12             getAdobeLicenses
13             decodeMicrosoftKey
14             );
15              
16             # Thanks to Brandon Mulcahy
17             # http://www.a1vbcode.com/snippet-4796.asp
18             sub _decodeAdobeKey {
19 0     0     my ($encrypted_key) = @_;
20              
21 0           my @cipher_key = qw/
22             0000000001 5038647192 1456053789 2604371895
23             4753896210 8145962073 0319728564 7901235846
24             7901235846 0319728564 8145962073 4753896210
25             2604371895 1426053789 5038647192 3267408951
26             5038647192 2604371895 8145962073 7901235846
27             3267408951 1426053789 4753896210 0319728564/;
28              
29 0           my @decrypted_key_chars;
30 0           foreach my $char (split(//, $encrypted_key)) {
31 0           my $sub_cipher_key = shift @cipher_key;
32 0           push @decrypted_key_chars, (split(//, $sub_cipher_key))[$char];
33             }
34              
35 0           return sprintf
36             '%s%s%s%s-%s%s%s%s-%s%s%s%s-%s%s%s%s-%s%s%s%s-%s%s%s%s',
37             @decrypted_key_chars;
38             }
39              
40             sub getAdobeLicenses {
41 0     0 1   my (%params) = @_;
42              
43 0           my $handle = getFileHandle(%params);
44              
45 0           my @licenses;
46              
47             my %data;
48              
49 0           while (my $line = <$handle>) {
50 0           chomp($line);
51              
52 0           my @f = split(/ <> /, $line);
53              
54 0 0         next unless $f[3];
55              
56 0           $f[1] =~ s/\{\|\}.*//;
57 0           $f[2] =~ s/\{\|\}.*//;
58 0           $f[3] =~ s/\{\|\}.*//;
59              
60 0 0         if ($f[2] eq 'FLMap') {
    0          
61 0           push @{$data{$f[3]}{with}}, $f[1];
  0            
62             } elsif ($f[3] ne "unlicensed") {
63 0           $data{$f[1]}{$f[2]} = $f[3];
64             }
65             }
66              
67 0           foreach my $key (keys %data) {
68 0 0 0       next unless $data{$key}{SN} || $data{$key}{with};
69              
70 0           push @licenses, {
71             NAME => $key,
72             FULLNAME => $data{$key}{ALM_LicInfo_EpicAppName},
73             KEY => _decodeAdobeKey($data{$key}{SN}),
74 0           COMPONENTS => join('/', @{$data{$key}{with}})
75             }
76             }
77              
78 0           return @licenses;
79             }
80              
81             # inspired by http://poshcode.org/4363
82             sub decodeMicrosoftKey {
83 0     0 1   my ($raw) = @_;
84              
85             ## no critic (ProhibitBitwise)
86              
87 0 0         return unless $raw;
88              
89 0           my @key_bytes = unpack 'C*', $raw;
90              
91             # check for Windows 8/Office 2013 style key (can contains the letter "N")
92 0           my $containsN = ($key_bytes[66] >> 3) & 1;
93 0           $key_bytes[66] = ($key_bytes[66] & 0xF7);
94              
95             # length of product key, in chars
96 0           my $chars_length = 25;
97              
98             # length of product key, in bytes
99 0           my $bytes_length = 15;
100              
101             # product key available characters
102 0           my @letters = qw(B C D F G H J K M P Q R T V W X Y 2 3 4 6 7 8 9);
103              
104             # extract bytes 52 to 66
105 0           my @bytes = @key_bytes[52 .. 66];
106              
107             # return immediatly for null keys
108 0 0   0     return if all { $_ == 00 } @bytes;
  0            
109              
110             # decoded product key
111 0           my @chars;
112              
113 0           for (my $i = $chars_length - 1; $i >= 0; $i--) {
114 0           my $index = 0;
115 0           for (my $j = $bytes_length - 1; $j >= 0; $j--) {
116 0           my $value = ($index << 8) | $bytes[$j];
117 0           $bytes[$j] = $value / scalar @letters;
118 0           $index = $value % (scalar @letters);
119             }
120 0           $chars[$i] = $letters[$index];
121             }
122              
123 0 0         if ($containsN != 0) {
124 0           my $first_char = shift @chars;
125 0           my $first_char_index = 0;
126 0           for (my $index = 0; $index < scalar @letters; $index++) {
127 0 0         next if $first_char ne $letters[$index];
128 0           $first_char_index = $index;
129 0           last;
130             }
131              
132 0           splice @chars, $first_char_index, 0, 'N';
133             }
134              
135 0           return sprintf
136             '%s%s%s%s%s-%s%s%s%s%s-%s%s%s%s%s-%s%s%s%s%s-%s%s%s%s%s', @chars;
137             }
138              
139             1;
140             __END__