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/python3 -O
"""This file is responsible for permissions checking and
(optionally) enforcing.
"""
import glob
import re
import string
import os
import stat
import pwd
import grp
import sys
import logging
import getopt
# localization
import gettext
try:
gettext.install('msec', str=1)
except IOError:
_ = str
# config
import config
# version
try:
from version import version
except:
version = "development version"
# libmsec
from libmsec import Log, PERMS
# {{{ usage
def usage():
"""Prints help message"""
print("""Msec: Mageia Security Center (%s).
This applications verifies and (when required) enforces permissions
of certain files and directories.
Usage: msecperms [parameters] [list of paths to check]
If no paths to check are specified, all permissions stored in
%s are checked.
Otherwise, only the enties in the list of paths are expanded and checked.
For example:
msecperms '/tmp/*' '/etc/*'
will cover only files which are covered by '/tmp/*' and '/etc/*' rules of
%s.
Available parameters:
-h, --help displays this helpful message.
-l, --level <level> displays configuration for specified security
level.
-e, --enforce enforce permissions on all files.
-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
""" % (version, config.PERMCONF, config.PERMCONF))
# }}}
if __name__ == "__main__":
# default options
log_level = logging.INFO
commit = True
enforce = False
quiet = False
root = ''
# parse command line
try:
opt, args = getopt.getopt(sys.argv[1:], 'hel=dpr:q', ['help', 'enforce', 'list=', 'debug', 'pretend', 'root=', 'quiet'])
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)
permconf = config.load_default_perms(log, level)
params = permconf.list_options()
if not params:
print(_("Invalid security level '%s'.") % level, file=sys.stderr)
sys.exit(1)
for file in params:
user, group, perm, force = permconf.get(file)
if force:
print("!! forcing permissions on %s" % file)
print("%s: %s.%s perm %s" % (file, user, group, perm))
sys.exit(0)
# debugging
elif o[0] == '-d' or o[0] == '--debug':
log_level = logging.DEBUG
# permission enforcing
elif o[0] == '-e' or o[0] == '--enforce':
enforce = True
# custom root
elif o[0] == '-r' or o[0] == '--root':
root = o[1]
# 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(_("Msec: Mageia Security Center (%s)\n") % version, file=sys.stderr)
print(_("Error: This application must be executed by root!"), file=sys.stderr)
print(_("Run with --help to get help."), file=sys.stderr)
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:
log_level = logging.WARN
log = Log(log_path="%s%s" % (root, config.SECURITYLOG), interactive=True, log_syslog=False, log_level=log_level, quiet=quiet)
# loading msec config
msec_config = config.MsecConfig(log, config="%s%s" % (root, config.SECURITYCONF))
msec_config.load()
# find out the base level
base_level = msec_config.get_base_level()
# loading permissions
permconf = config.PermConfig(log, config="%s%s" % (root, config.PERMCONF))
permconf.load()
# load variables from base level
config.merge_with_baselevel(log, permconf, base_level, config.load_default_perms, root='')
# merge with a legacy perm.local if exists
if os.access("%s/etc/security/msec/perm.local" % root, os.R_OK):
permlocal = config.PermConfig(log, config="%s/etc/security/msec/perm.local" % root)
permlocal.load()
permconf.merge(permlocal, overwrite=True)
# reloading levelconf for base level
levelconf = config.load_default_perms(log, base_level, root=root)
# load the main permission class
perm = PERMS(log, root=root)
# check permissions
changed_files = perm.check_perms(permconf, files_to_check=args)
# writing back changes
perm.commit(really_commit=commit, enforce=enforce)
# saving updated config
if commit:
if not permconf.save(levelconf):
log.error(_("Unable to save config!"))
sys.exit(0)
|