aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xcontrib/fix_private-bin.py206
-rwxr-xr-xcontrib/fj-mkdeb.py102
-rwxr-xr-xcontrib/fjclip.py5
-rwxr-xr-xcontrib/fjdisplay.py17
-rwxr-xr-xcontrib/fjresize.py16
5 files changed, 189 insertions, 157 deletions
diff --git a/contrib/fix_private-bin.py b/contrib/fix_private-bin.py
index 613a945a8..65bfba52d 100755
--- a/contrib/fix_private-bin.py
+++ b/contrib/fix_private-bin.py
@@ -29,80 +29,84 @@ __license__ = "Unlicense"
29 29
30import sys, os, glob, re 30import sys, os, glob, re
31 31
32privRx=re.compile("^(?:#\s*)?private-bin") 32privRx = re.compile("^(?:#\s*)?private-bin")
33
33 34
34def fixSymlinkedBins(files, replMap): 35def fixSymlinkedBins(files, replMap):
35 """ 36 """
36 Used to add filenames to private-bin directives of files if the ones present are mentioned in replMap 37 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 replMap is a dict where key is the marker filename and value is the filename to add
38 """ 39 """
39 40
40 rxs=dict() 41 rxs = dict()
41 for (old,new) in replMap.items(): 42 for (old, new) in replMap.items():
42 rxs[old]=re.compile("\\b"+old+"\\b") 43 rxs[old] = re.compile("\\b" + old + "\\b")
43 rxs[new]=re.compile("\\b"+new+"\\b") 44 rxs[new] = re.compile("\\b" + new + "\\b")
44 #print(rxs) 45 #print(rxs)
45 46
46 for filename in files: 47 for filename in files:
47 lines=None 48 lines = None
48 with open(filename,"r") as file: 49 with open(filename, "r") as file:
49 lines=file.readlines() 50 lines = file.readlines()
50 51
51 shouldUpdate=False 52 shouldUpdate = False
52 for (i,line) in enumerate(lines): 53 for (i, line) in enumerate(lines):
53 if privRx.search(line): 54 if privRx.search(line):
54 for (old,new) in replMap.items(): 55 for (old, new) in replMap.items():
55 if rxs[old].search(line) and not rxs[new].search(line): 56 if rxs[old].search(line) and not rxs[new].search(line):
56 lines[i]=rxs[old].sub(old+","+new, line) 57 lines[i] = rxs[old].sub(old + "," + new, line)
57 shouldUpdate=True 58 shouldUpdate = True
58 print(lines[i]) 59 print(lines[i])
59 60
60 if shouldUpdate: 61 if shouldUpdate:
61 with open(filename,"w") as file: 62 with open(filename, "w") as file:
62 file.writelines(lines) 63 file.writelines(lines)
63 pass 64 pass
65
64 66
65def createSetOfBinaries(files): 67def createSetOfBinaries(files):
66 """ 68 """
67 Creates a set of binaries mentioned in private-bin directives of files. 69 Creates a set of binaries mentioned in private-bin directives of files.
68 """ 70 """
69 s=set() 71 s = set()
70 for filename in files: 72 for filename in files:
71 lines=None 73 lines = None
72 with open(filename,"r") as file: 74 with open(filename, "r") as file:
73 for line in file: 75 for line in file:
74 if privRx.search(line): 76 if privRx.search(line):
75 bins=line.split(",") 77 bins = line.split(",")
76 bins[0]=bins[0].split(" ")[-1] 78 bins[0] = bins[0].split(" ")[-1]
77 bins = [n.strip() for n in bins] 79 bins = [n.strip() for n in bins]
78 s=s|set(bins) 80 s = s | set(bins)
79 return s 81 return s
82
80 83
81def createSymlinkTable(binDirs, binariesSet): 84def createSymlinkTable(binDirs, binariesSet):
82 """ 85 """
83 creates a dict of symlinked binaries in the system where a key is a symlink name and value is a symlinked binary. 86 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 87 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 88 binariesSet is a set of binaries to be checked if they are actually a symlinks
86 """ 89 """
87 m=dict() 90 m = dict()
88 toProcess=binariesSet 91 toProcess = binariesSet
89 while len(toProcess)!=0: 92 while len(toProcess) != 0:
90 additional=set() 93 additional = set()
91 for sh in toProcess: 94 for sh in toProcess:
92 for bD in binDirs: 95 for bD in binDirs:
93 p=bD+os.path.sep+sh 96 p = bD + os.path.sep + sh
94 if os.path.exists(p): 97 if os.path.exists(p):
95 if os.path.islink(p): 98 if os.path.islink(p):
96 m[sh]=os.readlink(p) 99 m[sh] = os.readlink(p)
97 additional.add(m[sh].split(" ")[0]) 100 additional.add(m[sh].split(" ")[0])
98 else: 101 else:
99 pass 102 pass
100 break 103 break
101 toProcess=additional 104 toProcess = additional
102 return m 105 return m
106
103 107
104def doTheFixes(profilesPath, binDirs): 108def doTheFixes(profilesPath, binDirs):
105 """ 109 """
106 Fixes private-bin in .profiles for firejail. The pipeline is as follows: 110 Fixes private-bin in .profiles for firejail. The pipeline is as follows:
107 discover files -> discover mentioned binaries -> 111 discover files -> discover mentioned binaries ->
108 discover the ones which are symlinks -> 112 discover the ones which are symlinks ->
@@ -110,48 +114,60 @@ def doTheFixes(profilesPath, binDirs):
110 filter the ones can be fixed (we cannot fix the ones which are not in directories for binaries) -> 114 filter the ones can be fixed (we cannot fix the ones which are not in directories for binaries) ->
111 apply fix 115 apply fix
112 """ 116 """
113 files=glob.glob(profilesPath+os.path.sep+"*.profile") 117 files = glob.glob(profilesPath + os.path.sep + "*.profile")
114 bins=createSetOfBinaries(files) 118 bins = createSetOfBinaries(files)
115 #print("The binaries used are:") 119 #print("The binaries used are:")
116 #print(bins) 120 #print(bins)
117 stbl=createSymlinkTable(binDirs,bins) 121 stbl = createSymlinkTable(binDirs, bins)
118 print("The replacement table is:") 122 print("The replacement table is:")
119 print(stbl) 123 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} 124 stbl = {
121 print("Filtered replacement table is:") 125 a[0]: a[1]
122 print(stbl) 126 for a in stbl.items()
123 fixSymlinkedBins(files,stbl) 127 if a[0].find(os.path.sep) < 0 and a[1].find(os.path.sep) < 0
128 }
129 print("Filtered replacement table is:")
130 print(stbl)
131 fixSymlinkedBins(files, stbl)
132
124 133
125def printHelp(): 134def printHelp():
126 print("python3 "+os.path.basename(__file__)+" <dir with .profile files>\nThe default dir is "+defaultProfilesPath+"\n"+doTheFixes.__doc__) 135 print("python3 " + os.path.basename(__file__) +
136 " <dir with .profile files>\nThe default dir is " +
137 defaultProfilesPath + "\n" + doTheFixes.__doc__)
138
127 139
128def main(): 140def main():
129 """The main function. Parses the commandline args, shows messages and calles the function actually doing the work.""" 141 """The main function. Parses the commandline args, shows messages and calles the function actually doing the work."""
130 print(repr(sys.argv)) 142 print(repr(sys.argv))
131 defaultProfilesPath="../etc" 143 defaultProfilesPath = "../etc"
132 if len(sys.argv)>2 or (len(sys.argv)==2 and (sys.argv[1] == '-h' or sys.argv[1] == '--help') ): 144 if len(sys.argv) > 2 or (len(sys.argv) == 2 and
133 printHelp() 145 (sys.argv[1] == '-h' or sys.argv[1] == '--help')):
134 exit(1) 146 printHelp()
135 147 exit(1)
136 profilesPath=None 148
137 if len(sys.argv)==2: 149 profilesPath = None
138 if os.path.isdir(sys.argv[1]): 150 if len(sys.argv) == 2:
139 profilesPath=os.path.abspath(sys.argv[1]) 151 if os.path.isdir(sys.argv[1]):
140 else: 152 profilesPath = os.path.abspath(sys.argv[1])
141 if os.path.exists(sys.argv[1]): 153 else:
142 print(sys.argv[1]+" is not a dir") 154 if os.path.exists(sys.argv[1]):
143 else: 155 print(sys.argv[1] + " is not a dir")
144 print(sys.argv[1]+" does not exist") 156 else:
145 printHelp() 157 print(sys.argv[1] + " does not exist")
146 exit(1) 158 printHelp()
147 else: 159 exit(1)
148 print("Using default profiles dir: " + defaultProfilesPath) 160 else:
149 profilesPath=defaultProfilesPath 161 print("Using default profiles dir: " + defaultProfilesPath)
150 162 profilesPath = defaultProfilesPath
151 binDirs=["/bin","/usr/bin","/usr/sbin","/usr/local/bin","/usr/local/sbin"] 163
152 print("Binaries dirs are:") 164 binDirs = [
153 print(binDirs) 165 "/bin", "/usr/bin", "/usr/sbin", "/usr/local/bin", "/usr/local/sbin"
154 doTheFixes(profilesPath, binDirs) 166 ]
167 print("Binaries dirs are:")
168 print(binDirs)
169 doTheFixes(profilesPath, binDirs)
170
155 171
156if __name__ == "__main__": 172if __name__ == "__main__":
157 main() 173 main()
diff --git a/contrib/fj-mkdeb.py b/contrib/fj-mkdeb.py
index 3cc13b758..89b4e46a9 100755
--- a/contrib/fj-mkdeb.py
+++ b/contrib/fj-mkdeb.py
@@ -4,42 +4,46 @@
4 4
5import os, re, shlex, subprocess, sys 5import os, re, shlex, subprocess, sys
6 6
7
7def run(srcdir, args): 8def run(srcdir, args):
8 if srcdir: os.chdir(srcdir) 9 if srcdir: os.chdir(srcdir)
9 10
10 dry_run=False 11 dry_run = False
11 escaped_args=[] 12 escaped_args = []
12 # We need to modify the list as we go. So be sure to copy the list to be iterated! 13 # We need to modify the list as we go. So be sure to copy the list to be iterated!
13 for a in args[:]: 14 for a in args[:]:
14 if a.startswith('--prefix'): 15 if a.startswith('--prefix'):
15 # prefix should ALWAYS be /usr here. Discard user-set values 16 # prefix should ALWAYS be /usr here. Discard user-set values
16 args.remove(a) 17 args.remove(a)
17 elif a == '--only-fix-mkdeb': 18 elif a == '--only-fix-mkdeb':
18 # for us, not configure 19 # for us, not configure
19 dry_run=True 20 dry_run = True
20 args.remove(a) 21 args.remove(a)
21 else: 22 else:
22 escaped_args.append(shlex.quote(a)) 23 escaped_args.append(shlex.quote(a))
23 24
24 # Fix up mkdeb.sh to include custom configure options. 25 # Fix up mkdeb.sh to include custom configure options.
25 with open('mkdeb.sh', 'rb') as f: 26 with open('mkdeb.sh', 'rb') as f:
26 sh=str(f.read(), 'utf_8') 27 sh = str(f.read(), 'utf_8')
27 rx=re.compile(r'^\./configure\s.*$', re.M) 28 rx = re.compile(r'^\./configure\s.*$', re.M)
28 with open('mkdeb.sh', 'wb') as f: 29 with open('mkdeb.sh', 'wb') as f:
29 f.write(bytes(rx.sub('./configure --prefix=/usr '+(' '.join(escaped_args)), sh), 'utf_8')) 30 f.write(
31 bytes(
32 rx.sub('./configure --prefix=/usr ' + (' '.join(escaped_args)),
33 sh), 'utf_8'))
30 34
31 if dry_run: return 0 35 if dry_run: return 0
32 36
33 # now run configure && make 37 # now run configure && make
34 if subprocess.call(['./configure', '--prefix=/usr']+args) == 0: 38 if subprocess.call(['./configure', '--prefix=/usr'] + args) == 0:
35 subprocess.call(['make', 'deb']) 39 subprocess.call(['make', 'deb'])
36 40
37 return 0 41 return 0
38 42
39 43
40if __name__ == '__main__': 44if __name__ == '__main__':
41 if len(sys.argv) == 2 and sys.argv[1] == '--help': 45 if len(sys.argv) == 2 and sys.argv[1] == '--help':
42 print('''Build a .deb of firejail with custom configure options 46 print('''Build a .deb of firejail with custom configure options
43 47
44usage: 48usage:
45{script} [--fj-src=SRCDIR] [--only-fix-mkdeb] [CONFIGURE_OPTIONS [...]] 49{script} [--fj-src=SRCDIR] [--only-fix-mkdeb] [CONFIGURE_OPTIONS [...]]
@@ -51,24 +55,26 @@ usage:
51 --only-fix-mkdeb: don't run configure or make after modifying mkdeb.sh 55 --only-fix-mkdeb: don't run configure or make after modifying mkdeb.sh
52 CONFIGURE_OPTIONS: arguments for configure 56 CONFIGURE_OPTIONS: arguments for configure
53'''.format(script=sys.argv[0])) 57'''.format(script=sys.argv[0]))
54 sys.exit(0) 58 sys.exit(0)
55 else: 59 else:
56 # Find the source directory 60 # Find the source directory
57 srcdir=None 61 srcdir = None
58 args=sys.argv[1:] 62 args = sys.argv[1:]
59 for a in args: 63 for a in args:
60 if a.startswith('--fj-src='): 64 if a.startswith('--fj-src='):
61 args.remove(a) 65 args.remove(a)
62 srcdir=a[9:] 66 srcdir = a[9:]
63 break 67 break
64 if not(srcdir): 68 if not (srcdir):
65 # srcdir not manually specified, try to auto-detect 69 # srcdir not manually specified, try to auto-detect
66 srcdir=os.path.dirname(os.path.abspath(sys.argv[0]+'/..')) 70 srcdir = os.path.dirname(os.path.abspath(sys.argv[0] + '/..'))
67 if not(os.path.isfile(srcdir+'/mkdeb.sh')): 71 if not (os.path.isfile(srcdir + '/mkdeb.sh')):
68 # Script is probably installed. Check the cwd. 72 # Script is probably installed. Check the cwd.
69 if os.path.isfile('./mkdeb.sh'): 73 if os.path.isfile('./mkdeb.sh'):
70 srcdir=None 74 srcdir = None
71 else: 75 else:
72 print('Error: Could not find the firejail source tree. Exiting.') 76 print(
73 sys.exit(1) 77 'Error: Could not find the firejail source tree. Exiting.'
74 sys.exit(run(srcdir, args)) 78 )
79 sys.exit(1)
80 sys.exit(run(srcdir, args))
diff --git a/contrib/fjclip.py b/contrib/fjclip.py
index b45959841..3d0c56dc6 100755
--- a/contrib/fjclip.py
+++ b/contrib/fjclip.py
@@ -23,7 +23,7 @@ if sys.argv[1] == '-':
23 clipin_raw = sys.stdin.read() 23 clipin_raw = sys.stdin.read()
24else: 24else:
25 display = fjdisplay.getdisplay(sys.argv[1]) 25 display = fjdisplay.getdisplay(sys.argv[1])
26 clipin_raw = subprocess.check_output(['xsel','-b','--display',display]) 26 clipin_raw = subprocess.check_output(['xsel', '-b', '--display', display])
27 27
28clipin = clipin_raw.strip() 28clipin = clipin_raw.strip()
29 29
@@ -31,5 +31,6 @@ if sys.argv[2] == '-':
31 print(clipin) 31 print(clipin)
32else: 32else:
33 display = fjdisplay.getdisplay(sys.argv[2]) 33 display = fjdisplay.getdisplay(sys.argv[2])
34 clipout = subprocess.Popen(['xsel','-b','-i','--display',display],stdin=subprocess.PIPE) 34 clipout = subprocess.Popen(['xsel', '-b', '-i', '--display', display],
35 stdin=subprocess.PIPE)
35 clipout.communicate(clipin) 36 clipout.communicate(clipin)
diff --git a/contrib/fjdisplay.py b/contrib/fjdisplay.py
index 3f409545f..7b2db549a 100755
--- a/contrib/fjdisplay.py
+++ b/contrib/fjdisplay.py
@@ -8,23 +8,25 @@ usage = """fjdisplay.py name-of-firejail
8returns the display in the form of ':NNN' 8returns the display in the form of ':NNN'
9""" 9"""
10 10
11
11def getfirejails(): 12def getfirejails():
12 output = subprocess.check_output(['firemon','--x11']) 13 output = subprocess.check_output(['firemon', '--x11'])
13 firejails = {} 14 firejails = {}
14 name = '' 15 name = ''
15 for line in output.split('\n'): 16 for line in output.split('\n'):
16 namematch = re.search('--name=(\w+\S*)',line) 17 namematch = re.search('--name=(\w+\S*)', line)
17 if namematch: 18 if namematch:
18 name = namematch.group(1) 19 name = namematch.group(1)
19 displaymatch = re.search('DISPLAY (:\d+)',line) 20 displaymatch = re.search('DISPLAY (:\d+)', line)
20 if displaymatch: 21 if displaymatch:
21 firejails[name] = displaymatch.group(1) 22 firejails[name] = displaymatch.group(1)
22 return firejails 23 return firejails
23 24
25
24def getdisplay(name): 26def getdisplay(name):
25 firejails = getfirejails() 27 firejails = getfirejails()
26 fjlist = '\n'.join(firejails.keys()) 28 fjlist = '\n'.join(firejails.keys())
27 namere = re.compile('^'+name+'.*', re.MULTILINE) 29 namere = re.compile('^' + name + '.*', re.MULTILINE)
28 matchingjails = namere.findall(fjlist) 30 matchingjails = namere.findall(fjlist)
29 if len(matchingjails) == 1: 31 if len(matchingjails) == 1:
30 return firejails[matchingjails[0]] 32 return firejails[matchingjails[0]]
@@ -33,6 +35,7 @@ def getdisplay(name):
33 else: 35 else:
34 raise NameError("ambiguous firejail name") 36 raise NameError("ambiguous firejail name")
35 37
38
36if __name__ == '__main__': 39if __name__ == '__main__':
37 if '-h' in sys.argv or '--help' in sys.argv or len(sys.argv) > 2: 40 if '-h' in sys.argv or '--help' in sys.argv or len(sys.argv) > 2:
38 print(usage) 41 print(usage)
@@ -40,4 +43,4 @@ if __name__ == '__main__':
40 if len(sys.argv) == 1: 43 if len(sys.argv) == 1:
41 print(getfirejails()) 44 print(getfirejails())
42 if len(sys.argv) == 2: 45 if len(sys.argv) == 2:
43 print (getdisplay(sys.argv[1])) 46 print(getdisplay(sys.argv[1]))
diff --git a/contrib/fjresize.py b/contrib/fjresize.py
index 4eb33f120..95b76259d 100755
--- a/contrib/fjresize.py
+++ b/contrib/fjresize.py
@@ -6,20 +6,26 @@ import subprocess
6 6
7usage = """usage: fjresize.py firejail-name displaysize 7usage = """usage: fjresize.py firejail-name displaysize
8resize firejail xephyr windows. 8resize firejail xephyr windows.
9fjdisplay.py with no other arguments will list running named firejails with displays. 9fjdisplay.py with no other arguments will list running named firejails with
10displays.
10fjresize.py with only a firejail name will list valid resolutions. 11fjresize.py with only a firejail name will list valid resolutions.
11names can be shortened as long its unambiguous. 12names can be shortened as long as it's unambiguous.
12note: you may need to move the xephyr window for the resize to take effect 13note: you may need to move the xephyr window for the resize to take effect
13example: 14example:
14 fjresize.py browser 1280x800 15 fjresize.py browser 1280x800
15""" 16"""
16 17
17
18if len(sys.argv) == 2: 18if len(sys.argv) == 2:
19 out = subprocess.check_output(['xrandr','--display',fjdisplay.getdisplay(sys.argv[1])]) 19 out = subprocess.check_output(
20 ['xrandr', '--display',
21 fjdisplay.getdisplay(sys.argv[1])])
20 print(out) 22 print(out)
21elif len(sys.argv) == 3: 23elif len(sys.argv) == 3:
22 out = subprocess.check_output(['xrandr','--display',fjdisplay.getdisplay(sys.argv[1]),'--output','default','--mode',sys.argv[2]]) 24 out = subprocess.check_output([
25 'xrandr', '--display',
26 fjdisplay.getdisplay(sys.argv[1]), '--output', 'default', '--mode',
27 sys.argv[2]
28 ])
23 print(out) 29 print(out)
24else: 30else:
25 print(usage) 31 print(usage)