aboutsummaryrefslogtreecommitdiffstats
path: root/src/msec/msec.py
blob: 879ec1970293e91ffefab64acf2c23f5f1087d8c (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
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
#!/usr/bin/python -O
"""This is the main msec module.
It checks/sets the security levels, configures security variables,
and works as a frontend to libmsec.
"""

import sys
import os
import string
import getopt
import gettext
import imp
import re

# config
import config

# version
try:
    from version import version
except:
    version = "development version"

# libmsec
from libmsec import MSEC, Log

import logging

# localization
try:
    gettext.install('msec')
except IOError:
    _ = str

# {{{ usage
def usage():
    """Prints help message"""
    print """Msec: Mandriva Security Center (%s).

When run without parameters, msec will read the configuration from
/etc/security/msec/msec.conf, and enforce the specified security settings.
If no configuration file is found on the system, a default configuration
will be created.

Arguments to msec:
    -h, --help              displays this helpful message.
    -l, --level <level>     displays configuration for specified security
                            level.
    -f, --force <level>     force new level, overwriting user settings.
    -d                      enable debugging messages.
    -p, --pretend           only pretend to change the level, perform no real
                            actions. Use this to see what operations msec
                            will perform.
    -r, --root <path>       path to use as root
    -q, --quiet             run quietly
    -s, --save <level>      save current configuration as a new security level
""" % version
# }}}

if __name__ == "__main__":
    # default options
    force_level = False
    log_level = logging.INFO
    commit = True
    root = ''
    quiet = False
    save = False

    # parse command line
    try:
        opt, args = getopt.getopt(sys.argv[1:], 'hl:f:dpr:qs:', ['help', 'list=', 'force=', 'debug', 'pretend', 'root=', 'quiet', 'save='])
    except getopt.error:
        usage()
        sys.exit(1)
    for o in opt:
        # help
        if o[0] == '-h' or o[0] == '--help':
            usage()
            sys.exit(0)
        # list
        elif o[0] == '-l' or o[0] == '--list':
            level = o[1]
            log = Log(interactive=True, log_syslog=False, log_file=False)
            levelconf = config.load_defaults(log, level)
            params = levelconf.list_options()
            if not params:
                print >>sys.stderr, _("Invalid security level '%s'.") % level
                sys.exit(1)
            for item in params:
                print "%s=%s" % (item, levelconf.get(item) )
            sys.exit(0)
        # force new level
        elif o[0] == '-f' or o[0] == '--force':
            level = o[1]
            force_level = True
        # save as new security level
        elif o[0] == '-s' or o[0] == '--save':
            level = o[1]
            save = True
        # custom root
        elif o[0] == '-r' or o[0] == '--root':
            root = o[1]
        # debugging
        elif o[0] == '-d' or o[0] == '--debug':
            log_level = logging.DEBUG
        # check-only mode
        elif o[0] == '-p' or o[0] == '--pretend':
            commit = False
        elif o[0] == '-q' or o[0] == '--quiet':
            quiet = True

    # verifying use id
    if os.geteuid() != 0:
        print >>sys.stderr, _("Msec: Mandriva Security Center (%s)\n") % version
        print >>sys.stderr, _("Error: This application must be executed by root!")
        print >>sys.stderr, _("Run with --help to get help.")
        sys.exit(1)

    # configuring logging
    interactive = sys.stdin.isatty()
    if interactive:
        # logs to file and to terminal
        log = Log(log_path="%s%s" % (root, config.SECURITYLOG), interactive=True, log_syslog=False, log_level=log_level, quiet=quiet)
    else:
        # TODO: review logging messages
        #log_level = logging.WARN
        log = Log(log_path="%s%s" % (root, config.SECURITYLOG), interactive=False, log_syslog=False, log_level=log_level, quiet=quiet)

    # loading initial config
    msec_config = config.MsecConfig(log, config="%s%s" % (root, config.SECURITYCONF))

    # forcing new level
    if force_level:
        # first load the default configuration for level
        levelconf = config.load_defaults(log, level, root=root)
        params = levelconf.list_options()
        if not params:
            log.error(_("Level '%s' not found, aborting.") % level)
            sys.exit(1)
        log.info(_("Switching to '%s' level.") % level)
        msec_config.reset()
        for opt in params:
            msec_config.set(opt, levelconf.get(opt))
    else:
        msec_config.load()

    # saving current setting as new level
    if save:
        newlevel = config.MsecConfig(log, config=config.SECURITY_LEVEL % (root, level))
        newlevel.merge(permconf, overwrite=True)
        # update new level name
        newlevel.set("BASE_LEVEL", level)
        newlevel.save()
        sys.exit(0)

    # load the msec library
    msec = MSEC(log, root=root)

    # apply the config to msec
    msec.apply(msec_config)
    # writing back changes
    msec.commit(commit)
    # saving updated config
    if force_level and commit:
        if not msec_config.save():
            log.error(_("Unable to save config!"))
    sys.exit(0)