aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/fix_private-bin.py
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/fix_private-bin.py')
-rwxr-xr-xcontrib/fix_private-bin.py157
1 files changed, 0 insertions, 157 deletions
diff --git a/contrib/fix_private-bin.py b/contrib/fix_private-bin.py
deleted file mode 100755
index 86fd3d16b..000000000
--- a/contrib/fix_private-bin.py
+++ /dev/null
@@ -1,157 +0,0 @@
1#!/usr/bin/python3
2
3__author__ = "KOLANICH"
4__copyright__ = """This is free and unencumbered software released into the public domain.
5
6Anyone is free to copy, modify, publish, use, compile, sell, or
7distribute this software, either in source code form or as a compiled
8binary, for any purpose, commercial or non-commercial, and by any
9means.
10
11In jurisdictions that recognize copyright laws, the author or authors
12of this software dedicate any and all copyright interest in the
13software to the public domain. We make this dedication for the benefit
14of the public at large and to the detriment of our heirs and
15successors. We intend this dedication to be an overt act of
16relinquishment in perpetuity of all present and future rights to this
17software under copyright law.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25OTHER DEALINGS IN THE SOFTWARE.
26
27For more information, please refer to <http://unlicense.org/>"""
28__license__ = "Unlicense"
29
30import sys, os, glob, re
31
32privRx=re.compile("^(?:#\s*)?private-bin")
33
34def fixSymlinkedBins(files, replMap):
35 """
36 Used to add filenames to private-bin directives of files if the ones present are mentioned in replMap
37 replMap is a dict where key is the marker filename and value is the filename to add
38 """
39
40 rxs=dict()
41 for (old,new) in replMap.items():
42 rxs[old]=re.compile("\\b"+old+"\\b")
43 rxs[new]=re.compile("\\b"+new+"\\b")
44 #print(rxs)
45
46 for filename in files:
47 lines=None
48 with open(filename,"r") as file:
49 lines=file.readlines()
50
51 shouldUpdate=False
52 for (i,line) in enumerate(lines):
53 if privRx.search(line):
54 for (old,new) in replMap.items():
55 if rxs[old].search(line) and not rxs[new].search(line):
56 lines[i]=rxs[old].sub(old+","+new, line)
57 shouldUpdate=True
58 print(lines[i])
59
60 if shouldUpdate:
61 with open(filename,"w") as file:
62 file.writelines(lines)
63 pass
64
65def createSetOfBinaries(files):
66 """
67 Creates a set of binaries mentioned in private-bin directives of files.
68 """
69 s=set()
70 for filename in files:
71 lines=None
72 with open(filename,"r") as file:
73 for line in file:
74 if privRx.search(line):
75 bins=line.split(",")
76 bins[0]=bins[0].split(" ")[-1]
77 bins = [n.strip() for n in bins]
78 s=s|set(bins)
79 return s
80
81def createSymlinkTable(binDirs, binariesSet):
82 """
83 creates a dict of symlinked binaries in the system where a key is a symlink name and value is a symlinked binary.
84 binDirs are folders to look into for binaries symlinks
85 binariesSet is a set of binaries to be checked if they are actually a symlinks
86 """
87 m=dict()
88 toProcess=binariesSet
89 while len(toProcess)!=0:
90 additional=set()
91 for sh in toProcess:
92 for bD in binDirs:
93 p=bD+os.path.sep+sh
94 if os.path.exists(p):
95 if os.path.islink(p):
96 m[sh]=os.readlink(p)
97 additional.add(m[sh].split(" ")[0])
98 else:
99 pass
100 break
101 toProcess=additional
102 return m
103
104def doTheFixes(profilesPath, binDirs):
105 """
106 Fixes private-bin in .profiles for firejail. The pipeline is as follows:
107 discover files -> discover mentioned binaries ->
108 discover the ones which are symlinks ->
109 make a look-up table for fix ->
110 filter the ones can be fixed (we cannot fix the ones which are not in directories for binaries) ->
111 apply fix
112 """
113 files=glob.glob(profilesPath+os.path.sep+"*.profile")
114 bins=createSetOfBinaries(files)
115 #print("The binaries used are:")
116 #print(bins)
117 stbl=createSymlinkTable(binDirs,bins)
118 print("The replacement table is:")
119 print(stbl)
120 stbl={a[0]:a[1] for a in stbl.items() if a[0].find(os.path.sep) < 0 and a[1].find(os.path.sep)<0}
121 print("Filtered replacement table is:")
122 print(stbl)
123 fixSymlinkedBins(files,stbl)
124
125def printHelp():
126 print("python3 "+os.path.basename(__file__)+" <dir with .profile files>\nThe default dir is "+defaultProfilesPath+"\n"+doTheFixes.__doc__)
127
128def main():
129 """The main function. Parses the commandline args, shows messages and calles the function actually doing the work."""
130 print(repr(sys.argv))
131 defaultProfilesPath="../etc"
132 if len(sys.argv)>2 or (len(sys.argv)==2 and (sys.argv[1] == '-h' or sys.argv[1] == '--help') ):
133 printHelp()
134 exit(1)
135
136 profilesPath=None
137 if len(sys.argv)==2:
138 if os.path.isdir(sys.argv[1]):
139 profilesPath=os.path.abspath(sys.argv[1])
140 else:
141 if os.path.exists(sys.argv[1]):
142 print(sys.argv[1]+" is not a dir")
143 else:
144 print(sys.argv[1]+" does not exist")
145 printHelp()
146 exit(1)
147 else:
148 print("Using default profiles dir: " + defaultProfilesPath)
149 profilesPath=defaultProfilesPath
150
151 binDirs=["/bin","/usr/bin","/usr/sbin","/usr/local/bin","/usr/local/sbin"]
152 print("Binaries dirs are:")
153 print(binDirs)
154 doTheFixes(profilesPath, binDirs)
155
156if __name__ == "__main__":
157 main()