1 | # |
---|
2 | # Copyright (C) 2022 Soleta Networks <info@soleta.eu> |
---|
3 | # |
---|
4 | # This program is free software: you can redistribute it and/or modify it under |
---|
5 | # the terms of the GNU Affero General Public License as published by the |
---|
6 | # Free Software Foundation; either version 3 of the License, or |
---|
7 | # (at your option) any later version. |
---|
8 | |
---|
9 | import os |
---|
10 | import subprocess |
---|
11 | |
---|
12 | from subprocess import PIPE |
---|
13 | |
---|
14 | def getlinuxversion(osrelease): |
---|
15 | """ |
---|
16 | Parses a os-release file to fetch 'PRETTY_NAME' key. |
---|
17 | If file or key are not found, then returns generic |
---|
18 | 'Linux' string. |
---|
19 | """ |
---|
20 | with open(osrelease, 'r') as f: |
---|
21 | for line in f: |
---|
22 | if line.find('=') == -1: |
---|
23 | continue |
---|
24 | key, value = line.split('=') |
---|
25 | if key == 'PRETTY_NAME': |
---|
26 | value = value.replace('\n', '') |
---|
27 | value = value.strip('"') |
---|
28 | return value |
---|
29 | return 'Linux' |
---|
30 | |
---|
31 | |
---|
32 | def getwindowsversion(winreghives): |
---|
33 | """ |
---|
34 | Tries to obtain windows version information by |
---|
35 | querying the SOFTWARE registry hive. Registry |
---|
36 | hives path is a required parameter. |
---|
37 | |
---|
38 | Runs hivexget(1) to fetch ProductName and |
---|
39 | ReleaseId. If something fails (hivexget is |
---|
40 | not installed, or registry is not found) it |
---|
41 | returns a generic "Microsoft Windows" string. |
---|
42 | """ |
---|
43 | |
---|
44 | # XXX: 3.6 friendly |
---|
45 | try: |
---|
46 | proc_prodname = subprocess.run(['hivexget', |
---|
47 | f'{winreghives}/SOFTWARE', |
---|
48 | 'microsoft\windows nt\currentversion', |
---|
49 | 'ProductName'], stdout=PIPE) |
---|
50 | proc_releaseid = subprocess.run(['hivexget', |
---|
51 | f'{winreghives}/SOFTWARE', |
---|
52 | 'microsoft\windows nt\currentversion', |
---|
53 | 'ReleaseId'], stdout=PIPE) |
---|
54 | |
---|
55 | prodname = proc_prodname.stdout.decode().replace('\n', '') |
---|
56 | releaseid = proc_releaseid.stdout.decode().replace('\n', '') |
---|
57 | |
---|
58 | if proc_prodname.returncode == 0 and proc_releaseid.returncode == 0: |
---|
59 | return f'{prodname} {releaseid}' |
---|
60 | except FileNotFoundError: # hivexget command not found |
---|
61 | pass |
---|
62 | return 'Microsoft Windows' |
---|
63 | |
---|
64 | |
---|
65 | def cache_probe(): |
---|
66 | """ |
---|
67 | Runs 'blkid -L CACHE' and returns stripped stdout |
---|
68 | """ |
---|
69 | proc_blkid = subprocess.run(['blkid', '-L', 'CACHE'], |
---|
70 | stdout=subprocess.PIPE) |
---|
71 | stdout = proc_blkid.stdout.decode().strip() |
---|
72 | return stdout |
---|
73 | |
---|
74 | def os_probe(mountpoint): |
---|
75 | """ |
---|
76 | Probes mountpoint for typical OS dependant files. |
---|
77 | |
---|
78 | Windows: Tries finding and querying the software |
---|
79 | registry hive. |
---|
80 | Linux: Looks for /etc/os-release file. |
---|
81 | |
---|
82 | Returns a string depending on the OS it detects. |
---|
83 | """ |
---|
84 | winreghives = f'{mountpoint}/Windows/System32/config' |
---|
85 | osrelease = f'{mountpoint}/etc/os-release' |
---|
86 | |
---|
87 | if os.path.exists(osrelease): |
---|
88 | return getlinuxversion(osrelease) |
---|
89 | elif os.path.exists(winreghives): |
---|
90 | return getwindowsversion(winreghives) |
---|
91 | else: |
---|
92 | return '' |
---|