aboutsummaryrefslogtreecommitdiffhomepage
path: root/main.py
blob: b2550aca5df249dee39b14d79e04589fd477c8ac (plain)
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
# -*- coding: utf-8 -*-
import os

import click

profile_path = "/etc/firejail/"
application_path = "/usr/share/applications/"

profiles = [os.path.splitext(f)[0] for f in os.listdir(profile_path)]
applications = [os.path.splitext(f)[0] for f in os.listdir(application_path)]
installed = [os.path.join(application_path, a + ".desktop")
             for a in profiles if a in applications]


@click.group()
def cli():
    pass


def get_desktop(program):
    """Get path to program's desktop file."""
    path = os.path.join(application_path, program + ".desktop")
    if os.path.isfile(path):
        return path
    else:
        raise click.ClickException(
            "Desktop file for %s does not exist." % program)


def replace(filename, condition, transform):
    """Replace lines in filename for which condition is true with transform."""
    newfile = []
    with open(filename, 'r') as f:
        for line in f:
            if condition(line):
                newfile.append(transform(line))
            else:
                newfile.append(line)

    with open(filename, 'w') as f:
        f.writelines(newfile)


def check_programs(program):
    """Return list of programs to enable / disable."""
    if len(program) == 0:
        raise click.ClickException("No program specified.")

    # Check if we have permission to modify global desktop files.
    if not os.access(installed[0], os.W_OK):
        raise click.UsageError(
            message="Can't modify desktop files, please execute as root.")

    if program[0] == "all":
        program = installed
    else:
        program = [get_desktop(p) for p in program]
    return program


@cli.command(help="enable firejail for program")
@click.argument("program", type=click.STRING, nargs=-1)
def enable(program):
    """Enable firejail for program."""
    programs = check_programs(program)

    for p in programs:
        replace(p,
                lambda l: l.startswith("Exec=") and "firejail" not in l,
                lambda l: "Exec=firejail " + l[l.find('=') + 1:])


@cli.command(help="disable firejail for program")
@click.argument("program", type=click.STRING, nargs=-1)
def disable(program):
    """Disable firejail for program."""
    programs = check_programs(program)

    for p in programs:
        replace(p,
                lambda line: line.startswith("Exec=firejail"),
                lambda line: "Exec=" + line[14:])


@cli.command(help="show status of firejail profiles")
def status():
    """Display status of available firejail profiles."""
    enabled = []
    disabled = []
    for p in installed:
        name = os.path.splitext(os.path.basename(p))[0]
        with open(p, 'r') as f:
            if "Exec=firejail" in f.read():
                enabled.append(name)
            else:
                disabled.append(name)

    click.echo("%d firejail profiles are enabled" % len(enabled))
    for p in sorted(enabled):
        click.echo("   %s" % p)

    click.echo("%d firejail profiles are available and disabled" % len(disabled))
    for p in sorted(disabled):
        click.echo("   %s" % p)


if __name__ == "__main__":
    cli()