File: policyd-rate-limit

package info (click to toggle)
policyd-rate-limit 1.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: buster, sid
  • size: 388 kB
  • sloc: python: 1,175; sh: 149; makefile: 58
file content (129 lines) | stat: -rwxr-xr-x 5,521 bytes parent folder | download | duplicates (3)
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
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 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 version 3 for
# more details.
#
# You should have received a copy of the GNU General Public License version 3
# along with this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# (c) 2015-2016 Valentin Samir
import os
import sys
import argparse
import signal
from policyd_rate_limit.policyd import Policyd
from policyd_rate_limit import utils
from policyd_rate_limit.utils import config


if __name__ == "__main__":  # pragma: no branch
    parser = argparse.ArgumentParser()
    parser.add_argument("--clean", help="clean old records from the database", action="store_true")
    parser.add_argument(
        "--get-config",
        help="return the value of a config parameter",
        metavar='PARAMETER_NAME'
    )
    parser.add_argument("--file", '-f', help="path to a config file", metavar='CONFIG_PATH')
    args = parser.parse_args()
    try:
        if args.file:
            config.setup(args.file)
        else:
            config.setup()
    except ValueError as error:
        sys.stderr.write("%s\n" % error)
        sys.exit(5)

    # if policyd-rate-limit was lauch by root, try creating piddir, socket dir and if used
    # sqlite3 database dir then, drop privileges
    if os.getuid() == 0:
        try:
            utils.make_directories()
            utils.drop_privileges()
        # if user/group from config do not exists, a ValueError is raised and we exit.
        except ValueError as error:
            sys.stderr.write("%s\n" % error)
            # continue running if asking for the value of a config param
            if not args.get_config:
                sys.exit(2)
    # ask for the value of a config param, print it and exit
    if args.get_config:
        try:
            sys.stdout.write(str(utils.get_config(args.get_config)))
        except (AttributeError):
            sys.stderr.write("%s not found\n" % args.get_config)
            sys.exit(1)
    # else we gonna need the database so we initialize it
    else:
        # do not lauch the daemon if no config file is found
        if not config.config_file:
            sys.exit(5)
        # we try to initialize the database.
        try:
            utils.database_init()
        # If initialization fail, lauch policyd-rate-limit anyway, we will try to initialize it
        # later, the database is maybe just not available right now.
        except Exception as error:
            sys.stderr.write("Fail to initialize database: %s\n" % error)
        # if database cleaning requested, remove old records and exit
        if args.clean:
            try:
                utils.clean()
            except ValueError as error:
                sys.stderr.write("%s\n" % error)
                sys.exit(8)
        # else we gonna lauch the policyd daemon
        else:
            # we check if policyd-rate-limit is not already running by lookig at config.pidfile
            try:
                # read the pid from pidfile (on clean exit policyd-rate-limit remote its pid file
                # so if it exists either policyd-rate-limit is already running or has crashed)
                if os.path.isfile(config.pidfile):
                    with open(config.pidfile) as f:
                        pid = int(f.read().strip())
                    try:
                        # should raise OSError(3) if not process found and success if found
                        os.kill(pid, 0)
                        # no exception raised so the pid in pidfile is still running, we display a
                        # error message and exit.
                        sys.stderr.write(
                            (
                                "policyd-rate-limit seems to be already running according to "
                                "the pid in the file %s. Exiting.\n"
                            ) % config.pidfile
                        )
                        sys.exit(3)
                    except OSError as error:
                        # No such process
                        if error.errno != 3:  # pragma: no cover (should not happen)
                            raise
            # unable to read the pid from pidfile, so we continue
            except (ValueError, OSError):
                pass
            try:
                # we try to write our pid. On failure a ValueError is raised
                utils.write_pidfile()
                try:
                    p = Policyd()
                    try:
                        p.socket()
                    except (ValueError, OSError) as error:
                        sys.stderr.write("%s\n" % error)
                        sys.exit(4)
                    try:
                        # exit upon SIGUSR1 reception. Used for coverage computation
                        signal.signal(signal.SIGUSR1, utils.exit_signal_handler)
                        p.run()
                    except (KeyboardInterrupt, utils.Exit):
                        pass
                    finally:
                        p.close_socket()
                finally:
                    utils.remove_pidfile()
            except Exception as error:
                sys.stderr.write("%s\n" % error)
                sys.exit(6)