generated from Vanilla-OS/vib-plugin
-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgenfilelist.py
182 lines (146 loc) · 4.86 KB
/
genfilelist.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# genfilelist.py
# Copyright 2024 axtlos <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3 of the License only.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# SPDX-License-Identifier: GPL-3.0-only
import os
import stat
import hashlib
import sys
import datetime
from os.path import isfile
def log(message: str) -> None:
"""
Logs a message with a timestamp and adds it to the global log list.
Parameters:
message (str): The message to log.
"""
timestamp = datetime.datetime.now().strftime("[%Y-%m-%d %H:%M:%S]")
log_list.append(f"{timestamp} {message}")
print(message)
def print_help() -> None:
"""
Prints the help message for using the script.
"""
log(
"Usage: python genfilelist.py <path> <filelist> <fsguard_binary> [--verbose] [--log-file <logfile>]"
)
def is_suid(path: str) -> bool:
"""
Checks if a file has the suid bit set.
Parameters:
path (str): The file to check
Returns:
bool: True if the suid bit is set, False otherwise.
"""
binary = os.stat(path)
if binary.st_mode & stat.S_ISUID == 2048:
return True
return False
def get_symlink(path: str) -> str:
"""
Checks if a file is a symlink and returns the path it points to if it is.
Parameters:
path (str): The path to check
Returns:
str: The path the symlink points to. None if the file is not a symlink
"""
if os.path.islink(path):
return os.readlink(path)
else:
return ""
def calc_checksum(file: str) -> str:
"""
Calculates the sha1sum of a given file
Parameters:
file (str): The file to calculate the checksum from
Returns:
str: The calculated checksum
"""
data = None
with open(file, "rb") as f:
data = f.read()
hash = hashlib.sha1(data).hexdigest()
log(f"Checksum: {hash}")
return hash
def main(
path: str,
filelist: str,
fsguard_binary: str,
verbose: bool = False,
log_file: str = None,
) -> None:
"""
Generates a file list with checksums and suid information for files in a given path.
Parameters:
path (str): The path to scan for files.
filelist (str): The file to store the generated file list.
fsguard_binary (str): The path to the fsguard binary.
verbose (bool, optional): Enable verbose mode. Defaults to False.
log_file (str, optional): Specify a log file to save verbose output. Defaults to None.
"""
binaries: list[str] = []
for dirpath, _, filenames in os.walk(path):
for file in filenames:
if fsguard_binary.strip() not in dirpath + "/" + file:
filepath = dirpath + "/" + file
# Check if file is symlink, skip file if symlink is broken
file_link = get_symlink(filepath)
if file_link:
if not isfile(file_link):
continue
filepath = os.path.abspath(dirpath + "/" + file_link)
if not isfile(filepath):
filepath = os.path.abspath(
get_symlink(dirpath + "/" + file))
suid = is_suid(filepath)
log(f"Processing: {filepath}")
binaries.append(
"{} #FSG# {} #FSG# {}".format(
filepath, calc_checksum(
filepath), "true" if suid else "false"
)
)
log(f"Processed: {filepath}\n")
if not os.path.exists(filelist):
file = open(filelist, "x")
file.close()
with open(filelist, "a") as file:
file.write("\n".join(binaries) + "\n")
if log_file:
with open(log_file, "w") as log_file:
log_file.write("\n".join(log_list) + "\n")
if __name__ == "__main__":
log_list = []
if len(sys.argv) < 4 or "--help" in sys.argv:
print_help()
sys.exit(1)
path = sys.argv[1]
filelist = sys.argv[2]
fsguard_binary = sys.argv[3]
verbose = "--verbose" in sys.argv
log_file = None
if "--log-file" in sys.argv:
log_file_index = sys.argv.index("--log-file")
log_file = (
sys.argv[log_file_index + 1] if log_file_index +
1 < len(sys.argv) else None
)
main(
path=path,
filelist=filelist,
fsguard_binary=fsguard_binary,
verbose=verbose,
log_file=log_file,
)