aboutsummaryrefslogtreecommitdiffstats
path: root/share
diff options
context:
space:
mode:
authorEugeni Dodonov <eugeni@mandriva.org>2009-01-06 21:31:46 +0000
committerEugeni Dodonov <eugeni@mandriva.org>2009-01-06 21:31:46 +0000
commitff31c9236b1fd7465ea9687fc735e8af882e780e (patch)
treeeec89033b4ad0b2459fbb91fa6dd39077eeaf407 /share
parentab984707253940bf5ced3a379699e8d0dc757fa6 (diff)
downloadmsec-ff31c9236b1fd7465ea9687fc735e8af882e780e.tar
msec-ff31c9236b1fd7465ea9687fc735e8af882e780e.tar.gz
msec-ff31c9236b1fd7465ea9687fc735e8af882e780e.tar.bz2
msec-ff31c9236b1fd7465ea9687fc735e8af882e780e.tar.xz
msec-ff31c9236b1fd7465ea9687fc735e8af882e780e.zip
Updated to working version of new msec.
Conflicts: Makefile cron-sh/security_check.sh share/msec.py
Diffstat (limited to 'share')
-rw-r--r--share/.svnignore6
-rw-r--r--share/CHANGES73
-rw-r--r--share/Config.py44
-rw-r--r--share/ConfigFile.py453
-rw-r--r--share/Log.py54
-rw-r--r--share/Makefile45
-rwxr-xr-xshare/Perms.py305
-rw-r--r--share/README87
-rwxr-xr-xshare/compile.py17
-rwxr-xr-xshare/draksec_help.py65
-rw-r--r--share/libmsec.py1391
-rwxr-xr-xshare/man.py67
-rwxr-xr-xshare/msec85
-rwxr-xr-xshare/msec.py290
-rwxr-xr-xshare/shadow.py116
15 files changed, 0 insertions, 3098 deletions
diff --git a/share/.svnignore b/share/.svnignore
deleted file mode 100644
index 17005aa..0000000
--- a/share/.svnignore
+++ /dev/null
@@ -1,6 +0,0 @@
-*.pyo
-*.pyc
-*.flog
-mseclib.man
-mseclib.py
-level.*
diff --git a/share/CHANGES b/share/CHANGES
deleted file mode 100644
index 22e546a..0000000
--- a/share/CHANGES
+++ /dev/null
@@ -1,73 +0,0 @@
-changes in version 0.30
-=======================
-
- * don't lower security if the admin has already augmented it (when called without argument).
- * splitted functions that worked on multiple levels.
-
-changes between version 0.18 and 0.19
-=====================================
-
-msec utility changes:
-
- * no password in level 0
-
-Periodic security checks changes:
-
- * config file is now in /var/lib/msec/security.conf and can
-be overriden by /etc/security/msec/security.conf.
-
-changes between version 0.17 and 0.18
-=====================================
-
-msec utility changes:
-
- * allow /etc/security/msec/level.local to override the default
-setting of the level.
- * promisc_check.sh works now.
- * added mseclib man page.
-
-changes between version 0.16 and 0.17
-=====================================
-
-msec utility changes:
-
- * handle shell timeout (level 4 and 5)
- * limit shell history (level 4 and 5)
- * su only for wheel group (level 5)
- * sulogin for single user mode (level 4 and 5)
- * various sysctl.conf settings for icmp and network parameters
- * password aging (level 4 and 5)
- * suppress /etc/issue.net (level 4 and 5) and /etc/issue (level 5)
- * removed manipulation of the groups of users
- * removed removal of services
- * logging in syslog according to the guideline for explanations in tools
- * more correct prevention of direct root logins
- * rewritten in python
-
-msec can be used to change level and it's also run hourly by cron to
-maintain the security level on the system. Only the minimum of changes
-on the filesystem are applied and the minimum of programs started.
-
-Periodic security checks changes:
-
- * added rpm database checks (rpm -va and rpm -qa)
- * report when a user other than root is at uid 0
- * diff_check reports even when the log is empty
- * use chkrootkit if present.
-
-Permissions settings changes:
-
- * /
- * removed audio group handling because it has always conflicted with pam_console
- * handle /var/log sub-directories in a generic manner
- * /etc/rc.d/init.d/*
- * corrected ssh and ping related paths
- * /etc/sysconfig
- * /proc
- * corrected gcc files
- * rpm related files to avoid exposing what is installed
- * /var/lock/subsys
- * added a local.perm to allow modifications without modifying level perms
- * corrected all the inconsistencies between levels to be able to change and come back
-without problem
- * rewritten in python
diff --git a/share/Config.py b/share/Config.py
deleted file mode 100644
index 14699b4..0000000
--- a/share/Config.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#---------------------------------------------------------------
-# Project : Mandriva Linux
-# Module : msec
-# File : Config.py
-# Version : $Id$
-# Author : Frederic Lepied
-# Created On : Thu Dec 6 19:54:35 2001
-# Purpose : configuration settings
-#---------------------------------------------------------------
-
-CONFIG='/etc/security/msec2.conf'
-
-_config={ 'root' : '',
- 'run_commands': 1,
- 'log': 'syslog',
- }
-try:
- execfile(CONFIG, _config)
-except IOError:
- #sys.stderr.write("no config file in %s. Using default values.\n" % CONFIG)
- pass
-
-def get_config(name, default=None):
- try:
- return _config[name]
- except KeyError:
- return default
-
-def set_config(name, value):
- _config[name] = value
-
-# def converthexa(array):
-# result=""
-# for c in array:
-# o=ord(c)
-# d=int(o/16)
-# u=o-(d*16)
-# result=result + "%x%x" % (d, u)
-# return result
-#
-# def hashstring(str):
-# return converthexa(md5.new(str).digest())
-
-# Config.py ends here
diff --git a/share/ConfigFile.py b/share/ConfigFile.py
deleted file mode 100644
index 26a93e6..0000000
--- a/share/ConfigFile.py
+++ /dev/null
@@ -1,453 +0,0 @@
-#---------------------------------------------------------------
-# Project : Mandriva Linux
-# Module : msec
-# File : ConfigFile.py
-# Version : $Id$
-# Author : Frederic Lepied
-# Created On : Wed Dec 5 21:42:49 2001
-# Purpose : class abstraction to handle configuration
-# files.
-#---------------------------------------------------------------
-
-import re
-import string
-import os
-import stat
-import Config
-import commands
-from Log import *
-import gettext
-
-STRING_TYPE = type('')
-
-try:
- cat = gettext.Catalog('msec')
- _ = cat.gettext
-except IOError:
- _ = str
-
-BEFORE=0
-INSIDE=1
-AFTER=2
-
-space = re.compile('\s')
-
-class ConfigFiles:
- def __init__(self):
- self.files = {}
- self.modified_files = []
- self.action_assoc = []
-
- def add(self, file, path):
- self.files[path] = file
-
- def modified(self, path):
- if not path in self.modified_files:
- self.modified_files.append(path)
-
- def get_config_file(self, path, suffix):
- try:
- return self.files[path]
- except KeyError:
- return ConfigFile(path, suffix, self)
-
- def add_config_assoc(self, regex, action):
- self.action_assoc.append((re.compile(regex), action))
-
-all_files=ConfigFiles()
-
-def move(old, new):
- try:
- os.unlink(new)
- except OSError:
- pass
- try:
- os.rename(old, new)
- except:
- error('rename %s %s: %s' % (old, new, str(sys.exc_value)))
-
-class ConfigFile:
- def __init__(self, path, suffix=None, meta=all_files):
- self.meta=meta
- self.path = Config.get_config('root', '') + path
- self.is_modified = 0
- self.is_touched = 0
- self.is_deleted = 0
- self.is_moved = 0
- self.suffix = suffix
- self.lines = None
- self.sym_link = None
- self.meta.add(self, path)
-
- def get_lines(self):
- if self.lines == None:
- file=None
- try:
- file = open(self.path, 'r')
- except IOError:
- if self.suffix:
- try:
- moved = self.path + self.suffix
- file = open(moved, 'r')
- move(moved, self.path)
- self.meta.modified(self.path)
- except IOError:
- self.lines = []
- else:
- self.lines = []
- if file:
- self.lines = string.split(file.read(), "\n")
- file.close()
- return self.lines
-
- def append(self, value):
- lines = self.lines
- l = len(lines)
- if l > 0 and lines[l - 1] == '':
- lines.insert(l - 1, value)
- else:
- lines.append(value)
- lines.append('')
-
- def modified(self):
- self.is_modified = 1
- return self
-
- def touch(self):
- self.is_touched = 1
- return self
-
- def symlink(self, link):
- self.sym_link = link
- return self
-
- def exists(self, really=0):
- return os.path.exists(self.path) or (not really and self.suffix and os.path.exists(self.path + self.suffix))
-
- def move(self, suffix):
- self.suffix = suffix
- self.is_moved = 1
-
- def unlink(self):
- self.is_deleted = 1
- self.lines=[]
- return self
-
- def write(self):
- if self.is_deleted:
- if self.exists():
- try:
- os.unlink(self.path)
- except:
- error('unlink %s: %s' % (self.path, str(sys.exc_value)))
- log(_('deleted %s') % (self.path,))
- elif self.is_modified:
- content = string.join(self.lines, "\n")
- mkdir_p(os.path.dirname(self.path))
- file = open(self.path, 'w')
- file.write(content)
- file.close()
- self.meta.modified(self.path)
- elif self.is_touched:
- if os.path.exists(self.path):
- try:
- os.utime(self.path, None)
- except:
- error('utime %s: %s' % (self.path, str(sys.exc_value)))
- elif self.suffix and os.path.exists(self.path + self.suffix):
- move(self.path + self.suffix, self.path)
- try:
- os.utime(self.path, None)
- except:
- error('utime %s: %s' % (self.path, str(sys.exc_value)))
- else:
- self.lines = []
- self.is_modified = 1
- file = open(self.path, 'w')
- file.close()
- log(_('touched file %s') % (self.path,))
- elif self.sym_link:
- done = 0
- if self.exists():
- full = os.lstat(self.path)
- if stat.S_ISLNK(full[stat.ST_MODE]):
- link = os.readlink(self.path)
- # to be fixed: resolv relative symlink
- done = (link == self.sym_link)
- if not done:
- try:
- os.unlink(self.path)
- except:
- error('unlink %s: %s' % (self.path, str(sys.exc_value)))
- log(_('deleted %s') % (self.path,))
- if not done:
- try:
- os.symlink(self.sym_link, self.path)
- except:
- error('symlink %s %s: %s' % (self.sym_link, self.path, str(sys.exc_value)))
- log(_('made symbolic link from %s to %s') % (self.sym_link, self.path))
-
- if self.is_moved:
- move(self.path, self.path + self.suffix)
- log(_('moved file %s to %s') % (self.path, self.path + self.suffix))
- self.meta.modified(self.path)
- self.is_touched = 0
- self.is_modified = 0
- self.is_deleted = 0
- self.is_moved = 0
-
- def set_shell_variable(self, var, value, start=None, end=None):
- regex = re.compile('^' + var + '="?([^#"]+)"?(.*)')
- lines = self.get_lines()
- idx=0
- value=str(value)
- start_regexp = start
-
- if start:
- status = BEFORE
- start = re.compile(start)
- else:
- status = INSIDE
-
- if end:
- end = re.compile(end)
-
- idx = None
- for idx in range(0, len(lines)):
- line = lines[idx]
- if status == BEFORE:
- if start.search(line):
- status = INSIDE
- else:
- continue
- elif end and end.search(line):
- break
- res = regex.search(line)
- if res:
- if res.group(1) != value:
- if space.search(value):
- lines[idx] = var + '="' + value + '"' + res.group(2)
- else:
- lines[idx] = var + '=' + value + res.group(2)
- self.modified()
- log(_('set variable %s to %s in %s') % (var, value, self.path,))
- return self
- if status == BEFORE:
- # never found the start delimiter
- log(_('WARNING: never found regexp %s in %s, not writing changes') % (start_regexp, self.path))
- return self
- if space.search(value):
- s = var + '="' + value + '"'
- else:
- s = var + '=' + value
- if idx == None or idx == len(lines):
- self.append(s)
- else:
- lines.insert(idx, s)
-
- self.modified()
- log(_('set variable %s to %s in %s') % (var, value, self.path,))
- return self
-
- def get_shell_variable(self, var, start=None, end=None):
- if end:
- end=re.compile(end)
- if start:
- start=re.compile(start)
- regex = re.compile('^' + var + '="?([^#"]+)"?(.*)')
- lines = self.get_lines()
- llen = len(lines)
- start_idx = 0
- end_idx = llen
- if start:
- found = 0
- for idx in range(0, llen):
- if start.search(lines[idx]):
- start_idx = idx
- found = 1
- break
- if found:
- for idx in range(start_idx, llen):
- if end.search(lines[idx]):
- end_idx = idx
- break
- else:
- start_idx = 0
- for idx in range(end_idx - 1, start_idx - 1, -1):
- res = regex.search(lines[idx])
- if res:
- return res.group(1)
- return None
-
- def get_match(self, regex, replace=None):
- r=re.compile(regex)
- lines = self.get_lines()
- for idx in range(0, len(lines)):
- res = r.search(lines[idx])
- if res:
- if replace:
- s = substitute_re_result(res, replace)
- return s
- else:
- return lines[idx]
- return None
-
- def replace_line_matching(self, regex, value, at_end_if_not_found=0, all=0, start=None, end=None):
- # if at_end_if_not_found is a string its value will be used as the string to inster
- r=re.compile(regex)
- lines = self.get_lines()
- matches = 0
-
- if start:
- status = BEFORE
- start = re.compile(start)
- else:
- status = INSIDE
-
- if end:
- end = re.compile(end)
-
- idx = None
- for idx in range(0, len(lines)):
- line = lines[idx]
- if status == BEFORE:
- if start.search(line):
- status = INSIDE
- else:
- continue
- elif end and end.search(line):
- break
- res = r.search(line)
- if res:
- s = substitute_re_result(res, value)
- matches = matches + 1
- if s != line:
- log(_("replaced in %s the line %d:\n%s\nwith the line:\n%s") % (self.path, idx, line, s))
- lines[idx] = s
- self.modified()
- if not all:
- return matches
- if matches == 0 and at_end_if_not_found:
- if type(at_end_if_not_found) == STRING_TYPE:
- value = at_end_if_not_found
- log(_("appended in %s the line:\n%s") % (self.path, value))
- if idx == None or idx == len(lines):
- self.append(value)
- else:
- lines.insert(idx, value)
- self.modified()
- matches = matches + 1
- return matches
-
- def insert_after(self, regex, value, at_end_if_not_found=0, all=0):
- matches = 0
- r=re.compile(regex)
- lines = self.get_lines()
- for idx in range(0, len(lines)):
- res = r.search(lines[idx])
- if res:
- s = substitute_re_result(res, value)
- log(_("inserted in %s after the line %d:\n%s\nthe line:\n%s") % (self.path, idx, lines[idx], s))
- lines.insert(idx+1, s)
- self.modified()
- matches = matches + 1
- if not all:
- return matches
- if matches == 0 and at_end_if_not_found:
- log(_("appended in %s the line:\n%s") % (self.path, value))
- self.append(value)
- self.modified()
- matches = matches + 1
- return matches
-
- def insert_before(self, regex, value, at_top_if_not_found=0, all=0):
- matches = 0
- r=re.compile(regex)
- lines = self.get_lines()
- for idx in range(0, len(lines)):
- res = r.search(lines[idx])
- if res:
- s = substitute_re_result(res, value)
- log(_("inserted in %s before the line %d:\n%s\nthe line:\n%s") % (self.path, idx, lines[idx], s))
- lines.insert(idx, s)
- self.modified()
- matches = matches + 1
- if not all:
- return matches
- if matches == 0 and at_top_if_not_found:
- log(_("inserted at the top of %s the line:\n%s") % (self.path, value))
- lines.insert(0, value)
- self.modified()
- matches = matches + 1
- return matches
-
- def insert_at(self, idx, value):
- lines = self.get_lines()
- try:
- lines.insert(idx, value)
- log(_("inserted in %s at the line %d:\n%s") % (self.path, idx, value))
- self.modified()
- return 1
- except KeyError:
- return 0
-
- def remove_line_matching(self, regex, all=0):
- matches = 0
- r=re.compile(regex)
- lines = self.get_lines()
- for idx in range(len(lines) - 1, -1, -1):
- res = r.search(lines[idx])
- if res:
- log(_("removing in %s the line %d:\n%s") % (self.path, idx, lines[idx]))
- lines.pop(idx)
- self.modified()
- matches = matches + 1
- if not all:
- return matches
- return matches
-
-# utility funtions
-
-def substitute_re_result(res, s):
- for idx in range(0, (res.lastindex or 0) + 1):
- subst = res.group(idx) or ''
- s = string.replace(s, '@' + str(idx), subst)
- return s
-
-def write_files():
- global all_files
-
- run_commands = Config.get_config('run_commands', 0)
- for f in all_files.files.values():
- f.write()
-
- for f in all_files.modified_files:
- for a in all_files.action_assoc:
- res = a[0].search(f)
- if res:
- s = substitute_re_result(res, a[1])
- if run_commands != '0':
- log(_('%s modified so launched command: %s') % (f, s))
- cmd = commands.getstatusoutput(s)
- if cmd[0] == 0:
- log(cmd[1])
- else:
- error(cmd[1])
- else:
- log(_('%s modified so should have run command: %s') % (f, s))
-
-def get_config_file(path, suffix=None):
- global all_files
-
- return all_files.get_config_file(path, suffix)
-
-def add_config_assoc(regex, action):
- global all_files
-
- return all_files.add_config_assoc(regex, action)
-
-def mkdir_p(path):
- if not os.path.exists(path):
- os.makedirs(path)
-
-# ConfigFile.py ends here
diff --git a/share/Log.py b/share/Log.py
deleted file mode 100644
index 061a5fb..0000000
--- a/share/Log.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#---------------------------------------------------------------
-# Project : Mandriva Llinux
-# Module : msec
-# File : Log.py
-# Version : $Id$
-# Author : Frederic Lepied
-# Created On : Wed Dec 5 23:50:29 2001
-# Purpose : write log through syslog conforming to
-# the Mandriva Linux guideline for the explanations
-# in tools. Errors are reported to stderr.
-#---------------------------------------------------------------
-
-import syslog
-import sys
-import string
-import Config
-
-_name = ''
-_use_syslog = 1
-
-def initlog(name, facility = syslog.LOG_AUTH):
- global _name
- global _use_syslog
-
- _use_syslog = (Config.get_config('log', 'syslog') == 'syslog')
-
- if _use_syslog:
- syslog.openlog(name, 0, facility)
-
- _name = name
-
-def log(s, level = syslog.LOG_INFO):
- global _use_syslog
-
- if _use_syslog:
- for l in string.split(s, '\n'):
- syslog.syslog(level, l)
- else:
- sys.stderr.write(s + '\n')
- return 1
-
-def closelog():
- global _use_syslog
-
- if _use_syslog:
- syslog.closelog()
-
-def error(s):
- global _name
-
- sys.stderr.write(_name + ': ' + s + '\n')
- log(s)
-
-# Log.py ends here
diff --git a/share/Makefile b/share/Makefile
deleted file mode 100644
index 639324d..0000000
--- a/share/Makefile
+++ /dev/null
@@ -1,45 +0,0 @@
-#---------------------------------------------------------------
-# Project : Mandriva Linux
-# Module : share
-# File : Makefile
-# Version : $Id$
-# Author : Frederic Lepied
-# Created On : Sat Jan 26 20:17:55 2002
-#---------------------------------------------------------------
-
-MAN=../man/C/mseclib.3
-PFILES=Config.py ConfigFile.py Log.py Perms.py compile.py draksec_help.py libmsec.py man.py
-
-all: mseclib.py compile man help.pm
-
-compile:
- ./compile.py '/usr/share/msec/' *.py
- rm -f msec.pyo
- @for f in $(PFILES); do if grep -q print $$f; then echo "print statement in $$f:"; grep -Hn print $$f; exit 1; fi; done
-
-mseclib.py: libmsec.py shadow.py
- rm -f $@
- ./shadow.py libmsec > $@
-
-man: $(MAN) levels
-
-help.pm: libmsec.py draksec_help.py
- rm -f $@
- ./draksec_help.py libmsec > $@
-
-$(MAN): libmsec.py man.py
- rm -f $@
- ./man.py libmsec > $@
-
-levels:
- for l in 0 1 2 3 4 5; do rm -f level.$$l; \
- ./msec.py -o log=stderr -o print=1 -o nolocal=1 $$l < /dev/null | sort > level.$$l; \
- done
-clean:
- rm -f *.pyc *.pyo mseclib.py *~ level.[0-5] help.pm
-
-# Local variables:
-# mode: makefile
-# End:
-#
-# Makefile ends here
diff --git a/share/Perms.py b/share/Perms.py
deleted file mode 100755
index ff4af73..0000000
--- a/share/Perms.py
+++ /dev/null
@@ -1,305 +0,0 @@
-#!/usr/bin/python -O
-#---------------------------------------------------------------
-# Project : Mandriva Linux
-# Module : msec
-# File : Perms.py
-# Version : $Id$
-# Author : Frederic Lepied
-# Created On : Fri Dec 7 23:33:49 2001
-# Purpose : fix permissions and owner/group of files
-# and directories.
-#---------------------------------------------------------------
-
-import glob
-import re
-import string
-import os
-import stat
-import pwd
-import grp
-import Config
-import sys
-from Log import *
-import gettext
-
-try:
- cat = gettext.Catalog('msec')
- _ = cat.gettext
-except IOError:
- _ = str
-
-comment_regex = re.compile('^\s*#|^\s*$')
-
-USER = {}
-GROUP = {}
-USERID = {}
-GROUPID = {}
-
-def get_user_id(name):
- try:
- return USER[name]
- except KeyError:
- try:
- USER[name] = pwd.getpwnam(name)[2]
- except KeyError:
- error(_('user name %s not found') % name)
- USER[name] = -1
- return USER[name]
-
-def get_user_name(id):
- try:
- return USERID[id]
- except KeyError:
- try:
- USERID[id] = pwd.getpwuid(id)[0]
- except KeyError:
- error(_('user name not found for id %d') % id)
- USERID[id] = str(id)
- return USERID[id]
-
-def get_group_id(name):
- try:
- return GROUP[name]
- except KeyError:
- try:
- GROUP[name] = grp.getgrnam(name)[2]
- except KeyError:
- error(_('group name %s not found') % name)
- GROUP[name] = -1
- return GROUP[name]
-
-def get_group_name(id):
- try:
- return GROUPID[id]
- except KeyError:
- try:
- GROUPID[id] = grp.getgrgid(id)[0]
- except KeyError:
- error(_('group name not found for id %d') % id)
- GROUPID[id] = str(id)
- return GROUPID[id]
-
-# Build a regexp that matches all the non local filesystems
-REGEXP_START = '^('
-REGEXP_END = ')'
-
-def build_non_localfs_regexp():
- # Allow to avoid this feature
- if Config.get_config('all-local-files', '0') == '1':
- return None
-
- try:
- file = open('/proc/mounts', 'r')
- except IOError:
- error(_('Unable to check /proc/mounts. Assuming all file systems are local.'))
- return None
-
- non_localfs = Config.get_config('non-local-fstypes', None)
- if non_localfs:
- non_localfs = string.split(non_localfs)
- else:
- non_localfs = ('nfs', 'codafs', 'smbfs')
-
- regexp = None
-
- for line in file.readlines():
- fields = string.split(line)
- if fields[2] in non_localfs:
- if regexp:
- regexp = regexp + '|' + fields[1]
- else:
- regexp = REGEXP_START + fields[1]
-
- file.close()
-
- if not regexp:
- return None
- else:
- return re.compile(regexp + REGEXP_END)
-
-# put the new perm/group/owner in the assoc variable according to the
-# content of the path file.
-assoc = {}
-
-def fix_perms(path, _interactive, force):
- try:
- file = open(path, 'r')
- except IOError:
- return
- root = Config.get_config('root', '')
-
- fs_regexp = build_non_localfs_regexp()
-
- lineno = 0
- for line in file.readlines():
- lineno = lineno + 1
-
- if comment_regex.search(line):
- continue
-
- fields = re.split('\s*', line)
- try:
- mode_str = fields[2]
- except IndexError:
- error(_("%s: syntax error line %d") % (path, lineno))
- continue
-
- if mode_str == 'current':
- perm = -1
- else:
- try:
- perm = int(mode_str, 8)
- except ValueError:
- error(_("%s: syntax error line %d") % (path, lineno))
- continue
-
- if fields[1] == 'current':
- user = group = -1
- user_str = group_str = ''
- else:
- (user_str, group_str) = string.split(fields[1], '.')
- if user_str != '':
- user = get_user_id(user_str)
- else:
- user = -1
- if group_str != '':
- group = get_group_id(group_str)
- else:
- group = -1
-
- fieldcount = len(fields)
- if fieldcount == 5:
- if fields[3] == 'force':
- mandatory = 1
- fieldcount = 4
- else:
- mandatory = 0
-
- if fieldcount == 4:
- for f in glob.glob(fields[0]):
- newperm = perm
- f = os.path.realpath(f)
- try:
- full = os.lstat(f)
- except OSError:
- continue
-
- if fs_regexp and fs_regexp.search(f):
- _interactive and log(_('Non local file: "%s". Nothing changed.') % fields[0])
- continue
-
- mode = stat.S_IMODE(full[stat.ST_MODE])
-
- if newperm != -1 and stat.S_ISDIR(full[stat.ST_MODE]):
- if newperm & 0400:
- newperm = newperm | 0100
- if newperm & 0040:
- newperm = newperm | 0010
- if newperm & 0004:
- newperm = newperm | 0001
-
- uid = full[stat.ST_UID]
- gid = full[stat.ST_GID]
- if f != '/' and f[-1] == '/':
- f = f[:-1]
- if f[-2:] == '/.':
- f = f[:-2]
- assoc[f] = (mode, uid, gid, newperm, user, group, user_str, group_str, mandatory or force)
- else:
- error(_('invalid syntax in %s line %d') % (path, lineno))
- file.close()
-
-# commit the changes to the files
-def act(change):
- for f in assoc.keys():
- (mode, uid, gid, newperm, user, group, user_str, group_str, mandatory) = assoc[f]
- # if we don't change the security level, try not to lower the security
- # if the user has changed it manually
- if not change and not mandatory:
- newperm = newperm & mode
- if newperm != -1 and mode != newperm:
- try:
- os.chmod(f, newperm)
- log(_('changed mode of %s from %o to %o') % (f, mode, newperm))
- except:
- error('chmod %s %o: %s' % (f, newperm, str(sys.exc_value)))
- if user != -1 and user != uid:
- try:
- os.chown(f, user, -1)
- log(_('changed owner of %s from %s to %s') % (f, get_user_name(uid), user_str))
- except:
- error('chown %s %s: %s' % (f, user, str(sys.exc_value)))
- if group != -1 and group != gid:
- try:
- os.chown(f, -1, group)
- log(_('changed group of %s from %s to %s') % (f, get_group_name(gid), group_str))
- except:
- error('chgrp %s %s: %s' % (f, group, str(sys.exc_value)))
-
-def chmod(f, newperm):
- try:
- full = os.stat(f)
- except OSError:
- return 0
- mode = stat.S_IMODE(full[stat.ST_MODE])
- if stat.S_ISDIR(full[stat.ST_MODE]):
- if newperm & 0400:
- newperm = newperm | 0100
- if newperm & 0040:
- newperm = newperm | 0010
- if newperm & 0004:
- newperm = newperm | 0001
- if mode != newperm:
- log(_('changed mode of %s from %o to %o') % (f, mode, newperm))
- try:
- os.chmod(f, newperm)
- except:
- error('chmod %s %o: %s' % (f, newperm, str(sys.exc_value)))
- return 1
-
-if __name__ == '__main__':
- import getopt
-
- _interactive = sys.stdin.isatty()
- change = 0
-
- # process the options
- try:
- (opt, args) = getopt.getopt(sys.argv[1:], 'co:',
- ['change', 'option'])
- except getopt.error:
- error(_('Invalid option. Use %s (-o var=<val>...) ([0-5])') % sys.argv[0])
- sys.exit(1)
-
- for o in opt:
- if o[0] == '-o' or o[0] == '--option':
- pair = string.split(o[1], '=')
- if len(pair) != 2:
- error(_('Invalid option format %s %s: use -o var=<val>') % (o[0], o[1]))
- sys.exit(1)
- else:
- Config.set_config(pair[0], pair[1])
- elif o[0] == '-c' or o[0] == '--change':
- change = 1
-
- # initlog must be done after processing the option because we can change
- # the way to report log with options...
- if _interactive:
- import syslog
-
- initlog('msec', syslog.LOG_LOCAL1)
- else:
- initlog('msec')
-
- _interactive and log(_('Fixing owners and permissions of files and directories'))
-
- # process the files
- fix_perms(args[0], _interactive, 0)
- for p in args[1:]:
- _interactive and log(_('Reading data from %s') % p)
- fix_perms(p, _interactive, 1)
-
- # do the modifications
- act(change)
-
-# Perms.py ends here
diff --git a/share/README b/share/README
deleted file mode 100644
index 4bb3846..0000000
--- a/share/README
+++ /dev/null
@@ -1,87 +0,0 @@
-******************
-Configurations files in /etc/security/msec/
-Shell scripts in /usr/share/msec.
-******************
-
-Suggestions & comments:
-flepied@mandriva.com
-
-******************
-Doc of the rewritting in python:
-
- 0 1 2 3 4 5
-root umask 022 022 022 022 022 077
-shell timeout 0 0 0 0 3600 900
-deny services none none none none local all
-su only for wheel grp no no no no no yes
-user umask 022 022 022 022 077 077
-shell history size default default default default 10 10
-direct root login yes yes yes yes no no
-remote root login yes yes yes yes no no
-sulogin for single user no no no no yes yes
-user list in [kg]dm yes yes yes yes no no
-promisc check no no no no yes yes
-ignore icmp echo no no no no yes yes
-ignore broadcasted icmp echo no no no no yes yes
-ignore bogus error responses no no no no yes yes
-enable libsafe no no no no yes yes
-allow reboot by user yes yes yes yes no no
-allow crontab/at yes yes yes yes no no
-password aging no no no no 60 30
-allow autologin yes yes yes no no no
-console log no no no yes yes yes
-issues yes yes yes local local no
-ip spoofing protection no no no yes yes yes
-dns spoofing protection no no no yes yes yes
-log stange ip packets no no no yes yes yes
-periodic security check no yes yes yes yes yes
-allow X connections yes local local no no no
-allow xauth from root yes yes yes yes no no
-X server listen to tcp tcp tcp tcp local local
-run msec by cron yes yes yes yes yes yes
-
-Periodic security checks by level:
-
- 0 1 2 3 4 5
-CHECK_SECURITY no yes yes yes yes yes
-CHECK_PERMS no no no yes yes yes
-CHECK_SUID_ROOT no no yes yes yes yes
-CHECK_SUID_MD5 no no yes yes yes yes
-CHECK_SGID no no yes yes yes yes
-CHECK_WRITABLE no no yes yes yes yes
-CHECK_UNOWNED no no no no yes yes
-CHECK_PROMISC no no no no yes yes
-CHECK_OPEN_PORT no no no yes yes yes
-CHECK_PASSWD no no no yes yes yes
-CHECK_SHADOW no no no yes yes yes
-TTY_WARN no no no no yes yes
-MAIL_WARN no no no yes yes yes
-SYSLOG_WARN no no yes yes yes yes
-RPM_CHECK no no no yes yes yes
-CHKROOTKIT_CHECK no no no yes yes yes
-
-These variables are configured by the user:
-
-MAIL_USER the user to send the dayly reports. If not set, the email is
-sent to root.
-
-PERM_LEVEL is used to determine which file to use to fix
-permissions/owners/groups (from /usr/share/msec/perm.$PERM_LEVEL). If
-not set, the SECURE_LEVEL is used instead. If the file
-/etc/security/msec/perm.local exists, it's used too. The syntax for
-each line if the following:
-
-<file specification> <owner> <permission> [force]
-
-<file specification> can be any glob to specify one or multiple
-files/diretories.
-
-<owner> must be in the form <user>.<group> or <user>. (force only
-user) or .<group> (force only group) or current (keep current user and
-group).
-
-<permission> is an octal number representing the access rights or
-current to keep the current permissions.
-
-If force is present as a 4th argument, it means that msec will enforce
-the permission even if the previous permission was lower.
diff --git a/share/compile.py b/share/compile.py
deleted file mode 100755
index a325016..0000000
--- a/share/compile.py
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/python -O
-#############################################################################
-# File : compile.py
-# Package : rpmlint
-# Author : Frederic Lepied
-# Created on : Sat Oct 23 23:40:21 1999
-# Version : $Id$
-# Purpose : byte compile all python files given in arguments.
-#############################################################################
-
-import py_compile
-import sys
-
-for f in sys.argv[2:]:
- py_compile.compile(f, f+"o", sys.argv[1] + f)
-
-# compile.py ends here
diff --git a/share/draksec_help.py b/share/draksec_help.py
deleted file mode 100755
index b57ab86..0000000
--- a/share/draksec_help.py
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/python
-#---------------------------------------------------------------
-# Project : Mandriva Linux
-# Module : share
-# File : draksec_help.py
-# Version : $Id$
-# Author : Thierry Vignaud
-# Created On : Sat Jan 26 17:38:39 2002
-# Purpose : loads a python module and creates a help hash
-# for draksec.
-#---------------------------------------------------------------
-
-import sys
-import imp
-import inspect
-import re
-
-header = '''package security::help;
-# !! THIS FILE WAS AUTO-GENERATED BY draksec_help.py !!
-# !! DO NOT MODIFY HERE, MODIFY IN THE *MSEC* CVS !!
-
-use strict;
-use common;
-
-our %help = (
-'''
-
-footer = ''');
-'''
-
-### strings used in the rewritting
-function_str = '''
-'%s' => N("Arguments: %s
-%s"),
-'''
-
-### code
-modulename = sys.argv[1]
-
-module = __import__(modulename)
-
-sys.stdout.write(header)
-
-clean = re.compile('^.[a-z].*\n', re.M)
-clean2 = re.compile('^\n', re.M)
-perl = re.compile('^([A-Z_0-9]*) (.*)$', re.M)
-
-for f in inspect.getmembers(module, inspect.isfunction):
- (args, varargs, varkw, locals) = inspect.getargspec(f[1])
- doc = f[1].__doc__
- if doc and len(doc) > 2:
- doc = doc[2:]
- argspec = inspect.formatargspec(args, varargs, varkw, locals) + '\n'
- if f[0] == 'set_security_conf':
- doc = clean.sub('', doc)
- doc = clean2.sub('', doc)
- doc = perl.sub('\\1 => N("\\2"),', doc)
- sys.stdout.write(doc)
- else:
- s = function_str % (f[0], argspec, doc)
- sys.stdout.write(s)
-
-sys.stdout.write(footer)
-
-# draksec_help.py ends here
diff --git a/share/libmsec.py b/share/libmsec.py
deleted file mode 100644
index 2ef2e3c..0000000
--- a/share/libmsec.py
+++ /dev/null
@@ -1,1391 +0,0 @@
-#---------------------------------------------------------------
-# Project : Mandriva Linux
-# Module : msec
-# File : libmsec.py
-# Version : $Id$
-# Author : Frederic Lepied
-# Created On : Mon Dec 10 22:52:17 2001
-# Purpose : all access points of the msec utility.
-#---------------------------------------------------------------
-
-import ConfigFile
-import Config
-from Log import *
-
-import os
-import grp
-import Perms
-import gettext
-import pwd
-import re
-import string
-import commands
-import time
-import traceback
-
-try:
- cat = gettext.Catalog('msec')
- _ = cat.gettext
-except IOError:
- _ = str
-
-SUFFIX='.msec'
-_interactive=0
-_same_level=1
-FORCED = {}
-
-# list of config files
-
-ATALLOW = '/etc/at.allow'
-AUTOLOGIN = '/etc/sysconfig/autologin'
-BASTILLENOLOGIN = '/etc/bastille-no-login'
-CRON = '/etc/cron.d/msec'
-CRONALLOW = '/etc/cron.allow'
-FSTAB = '/etc/fstab'
-GDM = '/etc/pam.d/gdm'
-GDMCONF = '/etc/X11/gdm/custom.conf'
-HALT = '/usr/bin/halt'
-HOSTCONF = '/etc/host.conf'
-HOSTSDENY = '/etc/hosts.deny'
-INITTAB = '/etc/inittab'
-ISSUE = '/etc/issue'
-ISSUENET = '/etc/issue.net'
-KDE = '/etc/pam.d/kde'
-KDMRC = '/usr/share/config/kdm/kdmrc'
-LDSOPRELOAD = '/etc/ld.so.preload'
-LILOCONF = '/etc/lilo.conf'
-LOGINDEFS = '/etc/login.defs'
-MENULST = '/boot/grub/menu.lst'
-MSEC = '/etc/sysconfig/msec'
-MSECBIN = '/usr/sbin/msec'
-MSECCRON = '/etc/cron.hourly/msec'
-MSEC_XINIT = '/etc/X11/xinit.d/msec'
-OPASSWD = '/etc/security/opasswd'
-PASSWD = '/etc/pam.d/passwd'
-POWEROFF = '/usr/bin/poweroff'
-REBOOT = '/usr/bin/reboot'
-SECURETTY = '/etc/securetty'
-SECURITYCONF = '/var/lib/msec/security.conf'
-SECURITYCONF2 = '/etc/security/msec/security.conf'
-SECURITYCRON = '/etc/cron.daily/msec'
-SECURITYSH = '/usr/share/msec/security.sh'
-SERVER = '/etc/security/msec/server'
-SHADOW = '/etc/shadow'
-SHUTDOWN = '/usr/bin/shutdown'
-SHUTDOWNALLOW = '/etc/shutdown.allow'
-SIMPLE_ROOT_AUTHEN = '/etc/pam.d/simple_root_authen'
-SSHDCONFIG = '/etc/ssh/sshd_config'
-STARTX = '/usr/bin/startx'
-SU = '/etc/pam.d/su'
-SYSCTLCONF = '/etc/sysctl.conf'
-SYSLOGCONF = '/etc/syslog.conf'
-SYSTEM_AUTH = '/etc/pam.d/system-auth'
-XDM = '/etc/pam.d/xdm'
-XSERVERS = '/etc/X11/xdm/Xservers'
-EXPORT = '/root/.xauth/export'
-
-# constants to keep in sync with shadow.py
-NONE=0
-ALL=1
-LOCAL=2
-
-no=0
-yes=1
-without_password=2
-
-ALL_LOCAL_NONE_TRANS = {ALL : 'ALL', NONE: 'NONE', LOCAL : 'LOCAL'}
-YES_NO_TRANS = {yes : 'yes', no : 'no'}
-ALLOW_ROOT_LOGIN_TRANS = {no : 'no', yes : 'yes', without_password : 'without_password'}
-
-# config files => actions
-
-ConfigFile.add_config_assoc(INITTAB, '/sbin/telinit q')
-ConfigFile.add_config_assoc('/etc(?:/rc.d)?/init.d/(.+)', '[ -f /var/lock/subsys/@1 ] && @0 reload')
-ConfigFile.add_config_assoc(SYSCTLCONF, '/sbin/sysctl -e -p /etc/sysctl.conf')
-ConfigFile.add_config_assoc(SSHDCONFIG, '[ -f /var/lock/subsys/sshd ] && /etc/rc.d/init.d/sshd restart')
-ConfigFile.add_config_assoc(LILOCONF, '[ `/usr/sbin/detectloader` = LILO ] && /sbin/lilo')
-ConfigFile.add_config_assoc(SYSLOGCONF, '[ -f /var/lock/subsys/syslog ] && service syslog reload')
-ConfigFile.add_config_assoc('^/etc/issue$', '/usr/bin/killall mingetty')
-
-# functions
-
-################################################################################
-
-# The same_level function inspects the call stack in the 2 previous
-# levels to see if a function is used that has been registered by
-# force_val and if this is the case we act as if we were changing the
-# security level to force the value to be used.
-def same_level():
- 'D'
- tb = traceback.extract_stack()
- if FORCED.has_key(tb[-2][2]) or FORCED.has_key(tb[-3][2]):
- return 0
- else:
- return _same_level
-
-def changing_level():
- 'D'
- global _same_level
- _same_level=0
-
-def force_val(name):
- 'D'
- global FORCED
- FORCED[name] = 1
-
-# configuration rules
-
-################################################################################
-
-def set_secure_level(level):
- msec = ConfigFile.get_config_file(MSEC)
-
- val = msec.get_shell_variable('SECURE_LEVEL')
-
- if not val or int(val) != level:
- _interactive and log(_('Setting secure level to %s') % level)
- msec.set_shell_variable('SECURE_LEVEL', level)
-
-################################################################################
-
-def get_secure_level():
- 'D'
- msec = ConfigFile.get_config_file(MSEC)
- return msec.get_shell_variable('SECURE_LEVEL')
-
-################################################################################
-
-def set_server_level(level):
- _interactive and log(_('Setting server level to %s') % level)
- securityconf = ConfigFile.get_config_file(SECURITYCONF2)
- securityconf.set_shell_variable('SERVER_LEVEL', level)
-
-################################################################################
-
-def get_server_level():
- 'D'
- securityconf = ConfigFile.get_config_file(SECURITYCONF2)
- level = securityconf.get_shell_variable('SERVER_LEVEL')
- if level: return level
- msec = ConfigFile.get_config_file(MSEC)
- return msec.get_shell_variable('SECURE_LEVEL')
-
-################################################################################
-
-def create_server_link():
- ''' If SERVER_LEVEL (or SECURE_LEVEL if absent) is greater than 3
-in /etc/security/msec/security.conf, creates the symlink /etc/security/msec/server
-to point to /etc/security/msec/server.<SERVER_LEVEL>. The /etc/security/msec/server
-is used by chkconfig --add to decide to add a service if it is present in the file
-during the installation of packages.'''
- level = get_server_level()
- server = ConfigFile.get_config_file(SERVER)
- if level in ('0', '1', '2', '3'):
- _interactive and log(_('Allowing chkconfig --add from rpm'))
- server.exists() and server.unlink()
- else:
- _interactive and log(_('Restricting chkconfig --add from rpm'))
- server.symlink(SERVER + '.' + str(level))
-
-create_server_link.arg_trans = YES_NO_TRANS
-
-################################################################################
-
-STRING_TYPE = type('')
-
-# helper function for set_root_umask and set_user_umask
-def set_umask(variable, umask, msg):
- 'D'
- msec = ConfigFile.get_config_file(MSEC)
-
- if type(umask) == STRING_TYPE:
- umask = int(umask, 8)
-
- if msec.exists():
- val = msec.get_shell_variable(variable)
- else:
- val = None
-
- # don't lower security when not changing security level
- if same_level():
- if val:
- octal = umask | int(val, 8)
- umask = '0%o' % octal
-
- if type(umask) != STRING_TYPE:
- umask = '0%o' % umask
-
- if val != umask:
- _interactive and log(_('Setting %s umask to %s') % (msg, umask))
- msec.set_shell_variable(variable, umask)
-
-def set_root_umask(umask):
- ''' Set the root umask.'''
- set_umask('UMASK_ROOT', umask, 'root')
-
-def set_user_umask(umask):
- ''' Set the user umask.'''
- set_umask('UMASK_USER', umask, 'users')
-
-################################################################################
-
-# the listen_tcp argument is kept for backward compatibility
-def allow_x_connections(arg, listen_tcp=None):
- ''' Allow/Forbid X connections. First arg specifies what is done
-on the client side: ALL (all connections are allowed), LOCAL (only
-local connection) and NONE (no connection).'''
-
- msec = ConfigFile.get_config_file(MSEC_XINIT)
-
- val = msec.exists() and msec.get_match('/usr/bin/xhost\s*\+\s*([^#]*)')
-
- if val:
- if val == '':
- val = ALL
- elif val == 'localhost':
- val = LOCAL
- else:
- val = NONE
- else:
- val = NONE
-
- # don't lower security when not changing security level
- if same_level():
- if val == NONE or (val == LOCAL and arg == ALL):
- return
-
- if arg == ALL:
- if val != arg:
- _interactive and log(_('Allowing users to connect X server from everywhere'))
- msec.exists() and msec.replace_line_matching('/usr/bin/xhost', '/usr/bin/xhost +', 1)
-
- elif arg == LOCAL:
- if val != arg:
- _interactive and log(_('Allowing users to connect X server from localhost'))
- msec.exists() and msec.replace_line_matching('/usr/bin/xhost', '/usr/bin/xhost + localhost', 1)
-
- elif arg == NONE:
- if val != arg:
- _interactive and log(_('Restricting X server connection to the console user'))
- msec.exists() and msec.remove_line_matching('/usr/bin/xhost', 1)
-
- else:
- error(_('invalid allow_x_connections arg: %s') % arg)
- return
-
-allow_x_connections.arg_trans=ALL_LOCAL_NONE_TRANS
-allow_x_connections.one_arg = 1
-
-################################################################################
-
-STARTX_REGEXP = '(\s*serverargs=".*) -nolisten tcp(.*")'
-XSERVERS_REGEXP = '(\s*[^#]+/usr/bin/X .*) -nolisten tcp(.*)'
-GDMCONF_REGEXP = '(\s*command=.*/X.*?) -nolisten tcp(.*)$'
-KDMRC_REGEXP = re.compile('(.*?)-nolisten tcp(.*)$')
-
-def allow_xserver_to_listen(arg):
- ''' The argument specifies if clients are authorized to connect
-to the X server on the tcp port 6000 or not.'''
-
- startx = ConfigFile.get_config_file(STARTX)
- xservers = ConfigFile.get_config_file(XSERVERS)
- gdmconf = ConfigFile.get_config_file(GDMCONF)
- kdmrc = ConfigFile.get_config_file(KDMRC)
-
- val_startx = startx.exists() and startx.get_match(STARTX_REGEXP)
- val_xservers = xservers.exists() and xservers.get_match(XSERVERS_REGEXP)
- val_gdmconf = gdmconf.exists() and gdmconf.get_match(GDMCONF_REGEXP)
- str = kdmrc.exists() and kdmrc.get_shell_variable('ServerArgsLocal', 'X-\*-Core', '^\s*$')
-
- if str:
- val_kdmrc = KDMRC_REGEXP.search(str)
- else:
- val_kdmrc = None
-
- # don't lower security when not changing security level
- if same_level():
- if val_startx and val_xservers and val_gdmconf and val_kdmrc:
- return
-
- if arg:
- if val_startx or val_xservers or val_gdmconf or val_kdmrc:
- _interactive and log(_('Allowing the X server to listen to tcp connections'))
- if not (same_level() and val_startx):
- startx.exists() and startx.replace_line_matching(STARTX_REGEXP, '@1@2')
- if not (same_level() and val_xservers):
- xservers.exists() and xservers.replace_line_matching(XSERVERS_REGEXP, '@1@2', 0, 1)
- if not (same_level() and val_gdmconf):
- gdmconf.exists() and gdmconf.replace_line_matching(GDMCONF_REGEXP, '@1@2', 0, 1)
- if not (same_level() and val_kdmrc):
- kdmrc.exists() and kdmrc.replace_line_matching('^(ServerArgsLocal=.*?)-nolisten tcp(.*)$', '@1@2', 0, 0, 'X-\*-Core', '^\s*$')
- else:
- if not val_startx or not val_xservers or not val_gdmconf or not val_kdmrc:
- _interactive and log(_('Forbidding the X server to listen to tcp connection'))
- startx.exists() and not val_startx and startx.replace_line_matching('serverargs="(.*?)( -nolisten tcp)?"', 'serverargs="@1 -nolisten tcp"')
- xservers.exists() and not val_xservers and xservers.replace_line_matching('(\s*[^#]+/usr/bin/X .*?)( -nolisten tcp)?$', '@1 -nolisten tcp', 0, 1)
- gdmconf.exists() and not val_gdmconf and gdmconf.replace_line_matching('(\s*command=.*/X.*?)( -nolisten tcp)?$', '@1 -nolisten tcp', 0, 1)
- kdmrc.exists() and not val_kdmrc and kdmrc.replace_line_matching('^(ServerArgsLocal=.*)( -nolisten tcp)?$', '@1 -nolisten tcp', 'ServerArgsLocal=-nolisten tcp', 0, 'X-\*-Core', '^\s*$')
-
-allow_xserver_to_listen.arg_trans = YES_NO_TRANS
-
-################################################################################
-
-def set_shell_timeout(val):
- ''' Set the shell timeout. A value of zero means no timeout.'''
-
- msec = ConfigFile.get_config_file(MSEC)
-
- if msec.exists():
- old = msec.get_shell_variable('TMOUT')
- if old != None:
- old = int(old)
- else:
- old = None
-
- # don't lower security when not changing security level
- if same_level():
- if old != None and old > val:
- return
-
- if old != val:
- _interactive and log(_('Setting shell timeout to %s') % val)
- msec.set_shell_variable('TMOUT', val)
-
-################################################################################
-
-def set_shell_history_size(size):
- ''' Set shell commands history size. A value of -1 means unlimited.'''
- msec = ConfigFile.get_config_file(MSEC)
-
- if msec.exists():
- val = msec.get_shell_variable('HISTFILESIZE')
- else:
- val = None
-
- # don't lower security when not changing security level
- if same_level():
- if val != None:
- val = int(val)
- if size == -1 or val < size:
- return
-
- if size >= 0:
- if val != size:
- _interactive and log(_('Setting shell history size to %s') % size)
- msec.set_shell_variable('HISTFILESIZE', size)
- else:
- if val != None:
- _interactive and log(_('Removing limit on shell history size'))
- msec.remove_line_matching('^HISTFILESIZE=')
-
-################################################################################
-
-def set_win_parts_umask(umask):
- ''' Set umask option for mounting vfat and ntfs partitions. A value of None means default umask.'''
- fstab = ConfigFile.get_config_file(FSTAB)
-
- # don't lower security when not changing security level
- if same_level():
- if umask != None:
- return
-
- if umask == None:
- fstab.replace_line_matching("(.*\s(vfat|ntfs)\s+)umask=\d+(\s.*)", "@1defaults@3", 0, 1)
- fstab.replace_line_matching("(.*\s(vfat|ntfs)\s+)umask=\d+,(.*)", "@1@3", 0, 1)
- fstab.replace_line_matching("(.*\s(vfat|ntfs)\s+\S+),umask=\d+(.*)", "@1@3", 0, 1)
- else:
- fstab.replace_line_matching("(.*\s(vfat|ntfs)\s+\S*)umask=\d+(.*)", "@1umask=0@3", 0, 1)
- fstab.replace_line_matching("(.*\s(vfat|ntfs)\s+)(?!.*umask=)(\S+)(.*)", "@1@3,umask=0@4", 0, 1)
-
-################################################################################
-
-def get_index(val, array):
- for loop in range(0, len(array)):
- if val == array[loop]:
- return loop
- return -1
-
-################################################################################
-ALLOW_SHUTDOWN_VALUES = ('All', 'Root', 'None')
-CTRALTDEL_REGEXP = '^ca::ctrlaltdel:/sbin/shutdown.*'
-CONSOLE_HELPER = 'consolehelper'
-
-def allow_reboot(arg):
- ''' Allow/Forbid reboot by the console user.'''
- shutdownallow = ConfigFile.get_config_file(SHUTDOWNALLOW)
- sysctlconf = ConfigFile.get_config_file(SYSCTLCONF)
- kdmrc = ConfigFile.get_config_file(KDMRC)
- gdmconf = ConfigFile.get_config_file(GDMCONF)
- inittab = ConfigFile.get_config_file(INITTAB)
-
- val_shutdownallow = shutdownallow.exists()
- val_sysctlconf = sysctlconf.exists() and sysctlconf.get_shell_variable('kernel.sysrq')
- val_inittab = inittab.exists() and inittab.get_match(CTRALTDEL_REGEXP)
- num = 0
- val = {}
- for f in [SHUTDOWN, POWEROFF, REBOOT, HALT]:
- val[f] = ConfigFile.get_config_file(f).exists()
- if val[f]:
- num = num + 1
- val_gdmconf = gdmconf.exists() and gdmconf.get_shell_variable('SystemMenu')
- oldval_kdmrc = kdmrc.exists() and kdmrc.get_shell_variable('AllowShutdown', 'X-:\*-Core', '^\s*$')
- if oldval_kdmrc:
- oldval_kdmrc = get_index(oldval_kdmrc, ALLOW_SHUTDOWN_VALUES)
- if arg:
- val_kdmrc = 0
- else:
- val_kdmrc = 2
-
- # don't lower security when not changing security level
- if same_level():
- if val_shutdownallow and val_sysctlconf == '0' and num == 0 and oldval_kdmrc >= val_kdmrc and val_gdmconf == 'false' and not val_inittab:
- return
- if oldval_kdmrc > val_kdmrc:
- val_kdmrc = oldval_kdmrc
-
- if arg:
- _interactive and log(_('Allowing reboot to the console user'))
- if not (same_level() and val_shutdownallow):
- shutdownallow.exists() and shutdownallow.move(SUFFIX)
- for f in [SHUTDOWN, POWEROFF, REBOOT, HALT]:
- cfg = ConfigFile.get_config_file(f)
- if not (same_level() and not val[f]):
- cfg.exists() or cfg.symlink(CONSOLE_HELPER)
- if not (same_level() and val_sysctlconf == '0'):
- sysctlconf.set_shell_variable('kernel.sysrq', 1)
- if not same_level() and val_gdmconf == 'false':
- gdmconf.exists() and gdmconf.set_shell_variable('SystemMenu', 'true', '\[greeter\]', '^\s*$')
- if not (same_level() and not val_inittab):
- inittab.replace_line_matching(CTRALTDEL_REGEXP, 'ca::ctrlaltdel:/sbin/shutdown -t3 -r now', 1)
- else:
- _interactive and log(_('Forbidding reboot to the console user'))
- ConfigFile.get_config_file(SHUTDOWNALLOW, SUFFIX).touch()
- for f in [SHUTDOWN, POWEROFF, REBOOT, HALT]:
- ConfigFile.get_config_file(f).unlink()
- sysctlconf.set_shell_variable('kernel.sysrq', 0)
- gdmconf.exists() and gdmconf.set_shell_variable('SystemMenu', 'false', '\[greeter\]', '^\s*$')
- inittab.remove_line_matching(CTRALTDEL_REGEXP)
-
- kdmrc.exists() and kdmrc.set_shell_variable('AllowShutdown', ALLOW_SHUTDOWN_VALUES[val_kdmrc], 'X-:\*-Core', '^\s*$')
-
-allow_reboot.arg_trans = YES_NO_TRANS
-
-################################################################################
-SHOW_USERS_VALUES = ('NotHidden', 'Selected')
-
-def allow_user_list(arg):
- ''' Allow/Forbid the list of users on the system on display managers (kdm and gdm).'''
- kdmrc = ConfigFile.get_config_file(KDMRC)
- gdmconf = ConfigFile.get_config_file(GDMCONF)
-
- oldval_gdmconf = gdmconf.exists() and gdmconf.get_shell_variable('Browser')
- oldval_kdmrc = kdmrc.exists() and kdmrc.get_shell_variable('ShowUsers', 'X-\*-Greeter', '^\s*$')
- if oldval_kdmrc:
- oldval_kdmrc = get_index(oldval_kdmrc, SHOW_USERS_VALUES)
-
- if arg:
- msg = 'Allowing the listing of users in display managers'
- val_kdmrc = 0
- val_gdmconf = 'true'
- else:
- msg = 'Disabling the listing of users in display managers'
- val_kdmrc = 1
- val_gdmconf = 'false'
-
- # don't lower security when not changing security level
- if same_level():
- if oldval_kdmrc >= val_kdmrc and oldval_gdmconf == 'false':
- return
- if oldval_kdmrc > val_kdmrc:
- val_kdmrc = oldval_kdmrc
- if oldval_gdmconf == 'false':
- val_gdmconf = 'false'
-
- if (gdmconf.exists() and oldval_gdmconf != val_gdmconf) or (kdmrc.exists() and oldval_kdmrc != val_kdmrc):
- _interactive and log(_(msg))
- oldval_kdmrc != val_gdmconf and kdmrc.exists() and kdmrc.set_shell_variable('ShowUsers', SHOW_USERS_VALUES[val_kdmrc], 'X-\*-Greeter', '^\s*$')
- oldval_gdmconf != val_gdmconf and gdmconf.exists() and gdmconf.set_shell_variable('Browser', val_gdmconf)
-
-allow_user_list.arg_trans = YES_NO_TRANS
-
-################################################################################
-
-def allow_root_login(arg):
- ''' Allow/Forbid direct root login.'''
- securetty = ConfigFile.get_config_file(SECURETTY)
- kde = ConfigFile.get_config_file(KDE)
- gdm = ConfigFile.get_config_file(GDM)
- gdmconf = ConfigFile.get_config_file(GDMCONF)
- xdm = ConfigFile.get_config_file(XDM)
-
- val = {}
- val[kde] = kde.exists() and kde.get_match('auth required (?:/lib/security/)?pam_listfile.so onerr=succeed item=user sense=deny file=/etc/bastille-no-login')
- val[gdm] = gdm.exists() and gdm.get_match('auth required (?:/lib/security/)?pam_listfile.so onerr=succeed item=user sense=deny file=/etc/bastille-no-login')
- val[xdm] = xdm.exists() and xdm.get_match('auth required (?:/lib/security/)?pam_listfile.so onerr=succeed item=user sense=deny file=/etc/bastille-no-login')
- num = 0
- for n in range(1, 7):
- s = 'tty' + str(n)
- if securetty.get_match(s):
- num = num + 1
- val[s] = 1
- else:
- val[s] = 0
- s = 'vc/' + str(n)
- if securetty.get_match(s):
- num = num + 1
- val[s] = 1
- else:
- val[s] = 0
-
- # don't lower security when not changing security level
- if same_level():
- if (not kde.exists() or val[kde]) and (not gdm.exists() or val[gdm]) and (not xdm.exists() or val[xdm]) and num == 12:
- return
-
- if arg:
- if val[kde] or val[gdm] or val[xdm] or num != 12:
- _interactive and log(_('Allowing direct root login'))
- gdmconf.exists() and gdmconf.set_shell_variable('ConfigAvailable', 'true', '\[greeter\]', '^\s*')
-
-
- for cnf in (kde, gdm, xdm):
- if not (same_level() and val[cnf]):
- cnf.exists() and cnf.remove_line_matching('^auth\s*required\s*(?:/lib/security/)?pam_listfile.so.*bastille-no-login', 1)
-
- for n in range(1, 7):
- s = 'tty' + str(n)
- if not (same_level() and not val[s]):
- securetty.replace_line_matching(s, s, 1)
- s = 'vc/' + str(n)
- if not (same_level() and not val[s]):
- securetty.replace_line_matching(s, s, 1)
- else:
- gdmconf.exists() and gdmconf.set_shell_variable('ConfigAvailable', 'false', '\[greeter\]', '^\s*')
- if (kde.exists() and not val[kde]) or (gdm.exists() and not val[gdm]) or (xdm.exists() and not val[xdm]) or num > 0:
- _interactive and log(_('Forbidding direct root login'))
-
- bastillenologin = ConfigFile.get_config_file(BASTILLENOLOGIN)
- bastillenologin.replace_line_matching('^\s*root', 'root', 1)
-
- for cnf in (kde, gdm, xdm):
- cnf.exists() and (cnf.replace_line_matching('^auth\s*required\s*(?:/lib/security/)?pam_listfile.so.*bastille-no-login', 'auth required pam_listfile.so onerr=succeed item=user sense=deny file=/etc/bastille-no-login') or \
- cnf.insert_at(0, 'auth required pam_listfile.so onerr=succeed item=user sense=deny file=/etc/bastille-no-login'))
- securetty.remove_line_matching('.+', 1)
-
-allow_root_login.arg_trans = YES_NO_TRANS
-
-PERMIT_ROOT_LOGIN_REGEXP = '^\s*PermitRootLogin\s+(no|yes|without-password|forced-commands-only)'
-
-################################################################################
-
-def allow_remote_root_login(arg):
- ''' Allow/Forbid remote root login via sshd. You can specify
-yes, no and without-password. See sshd_config(5) man page for more
-information.'''
- sshd_config = ConfigFile.get_config_file(SSHDCONFIG)
-
- if sshd_config.exists():
- val = sshd_config.get_match(PERMIT_ROOT_LOGIN_REGEXP, '@1')
- else:
- val = None
-
- # don't lower security when not changing security level
- if same_level():
- if val == 'no':
- return
- if val == 'forced-commands-only':
- return
-
- if val == 'yes':
- val = yes
- elif val == 'no':
- val = no
- elif val == 'without-password':
- val = without_password
- else:
- val = yes
-
- if val != arg:
- if arg == yes:
- _interactive and log(_('Allowing remote root login'))
- sshd_config.exists() and sshd_config.replace_line_matching(PERMIT_ROOT_LOGIN_REGEXP,
- 'PermitRootLogin yes', 1)
- elif arg == no:
- _interactive and log(_('Forbidding remote root login'))
- sshd_config.exists() and sshd_config.replace_line_matching(PERMIT_ROOT_LOGIN_REGEXP,
- 'PermitRootLogin no', 1)
- elif arg == without_password:
- _interactive and log(_('Allowing remote root login only by passphrase'))
- sshd_config.exists() and sshd_config.replace_line_matching(PERMIT_ROOT_LOGIN_REGEXP,
- 'PermitRootLogin without-password', 1)
-
-allow_remote_root_login.arg_trans = ALLOW_ROOT_LOGIN_TRANS
-
-################################################################################
-
-def enable_pam_wheel_for_su(arg):
- ''' Enabling su only from members of the wheel group or allow su from any user.'''
- su = ConfigFile.get_config_file(SU)
-
- val = su.exists() and su.get_match('^auth\s+required\s+(?:/lib/security/)?pam_wheel.so\s+use_uid\s*$')
-
- # don't lower security when not changing security level
- if same_level():
- if val:
- return
-
- if arg:
- if not val:
- _interactive and log(_('Allowing su only from wheel group members'))
- try:
- ent = grp.getgrnam('wheel')
- except KeyError:
- error(_('no wheel group'))
- return
- members = ent[3]
- if members == [] or members == ['root']:
- _interactive and error(_('wheel group is empty'))
- return
- su.exists() and (su.replace_line_matching('^auth\s+required\s+(?:/lib/security/)?pam_wheel.so\s+use_uid\s*$',
- 'auth required pam_wheel.so use_uid') or \
- su.insert_after('^auth\s+required',
- 'auth required pam_wheel.so use_uid'))
- else:
- if val:
- _interactive and log(_('Allowing su for all'))
- su.exists() and su.remove_line_matching('^auth\s+required\s+(?:/lib/security/)?pam_wheel.so\s+use_uid\s*$')
-
-enable_pam_wheel_for_su.arg_trans = YES_NO_TRANS
-
-################################################################################
-
-SUCCEED_MATCH = '^auth\s+sufficient\s+pam_succeed_if.so\s+use_uid\s+user\s+ingroup\s+wheel\s*$'
-SUCCEED_LINE = 'auth sufficient pam_succeed_if.so use_uid user ingroup wheel'
-
-def enable_pam_root_from_wheel(arg):
- ''' Allow root access without password for the members of the wheel group.'''
- su = ConfigFile.get_config_file(SU)
- simple = ConfigFile.get_config_file(SIMPLE_ROOT_AUTHEN)
-
- if not su.exists():
- return
-
- val = su.get_match(SUCCEED_MATCH)
-
- if simple.exists():
- val_simple = simple.get_match(SUCCEED_MATCH)
- else:
- val_simple = False
-
- # don't lower security when not changing security level
- if same_level():
- if not val and not val_simple:
- return
-
- if arg:
- if not val or (simple.exists() and not val_simple):
- _interactive and log(_('Allowing transparent root access for wheel group members'))
- if not val:
- su.insert_before('^auth\s+required', SUCCEED_LINE)
- if simple.exists() and not val_simple:
- simple.insert_before('^auth\s+required', SUCCEED_LINE)
- else:
- if val or (simple.exists() and val_simple):
- _interactive and log(_('Disabling transparent root access for wheel group members'))
- if val:
- su.remove_line_matching(SUCCEED_MATCH)
- if simple.exists() and val_simple:
- simple.remove_line_matching(SUCCEED_MATCH)
-
-enable_pam_root_from_wheel.arg_trans = YES_NO_TRANS
-
-################################################################################
-
-def allow_issues(arg):
- ''' If \\fIarg\\fP = ALL allow /etc/issue and /etc/issue.net to exist. If \\fIarg\\fP = NONE no issues are
-allowed else only /etc/issue is allowed.'''
- issue = ConfigFile.get_config_file(ISSUE, SUFFIX)
- issuenet = ConfigFile.get_config_file(ISSUENET, SUFFIX)
-
- val = issue.exists(1)
- valnet = issuenet.exists(1)
-
- # don't lower security when not changing security level
- if same_level():
- if not val and not valnet:
- return
- if arg == ALL and not valnet:
- return
-
- if arg == ALL:
- if not (val and valnet):
- _interactive and log(_('Allowing network pre-login messages'))
- issue.exists() and issue.get_lines()
- issuenet.exists() and issuenet.get_lines()
- else:
- if arg == NONE:
- if val:
- _interactive and log(_('Disabling pre-login message'))
- issue.exists(1) and issue.move(SUFFIX) and issue.modified()
- else:
- if not val:
- _interactive and log(_('Allowing pre-login message'))
- issue.exists() and issue.get_lines()
- if valnet:
- _interactive and log(_('Disabling network pre-login message'))
- issuenet.exists(1) and issuenet.move(SUFFIX)
-
-allow_issues.arg_trans = ALL_LOCAL_NONE_TRANS
-
-################################################################################
-
-def allow_autologin(arg):
- ''' Allow/Forbid autologin.'''
- autologin = ConfigFile.get_config_file(AUTOLOGIN)
-
- if autologin.exists():
- val = autologin.get_shell_variable('AUTOLOGIN')
- else:
- val = None
-
- # don't lower security when not changing security level
- if same_level():
- if val == 'no':
- return
-
- if arg:
- if val != 'yes':
- _interactive and log(_('Allowing autologin'))
- autologin.exists() and autologin.set_shell_variable('AUTOLOGIN', 'yes')
- else:
- if val != 'no':
- _interactive and log(_('Forbidding autologin'))
- autologin.exists() and autologin.set_shell_variable('AUTOLOGIN', 'no')
-
-allow_autologin.arg_trans = YES_NO_TRANS
-
-################################################################################
-
-def password_loader(value):
- 'D'
- _interactive and log(_('Activating password in boot loader'))
- liloconf = ConfigFile.get_config_file(LILOCONF)
- liloconf.exists() and (liloconf.replace_line_matching('^password=', 'password="' + value + '"', 0, 1) or \
- liloconf.insert_after('^boot=', 'password="' + value + '"')) and \
- Perms.chmod(liloconf.path, 0600)
- # TODO encrypt password in grub
- menulst = ConfigFile.get_config_file(MENULST)
- menulst.exists() and (menulst.replace_line_matching('^password\s', 'password "' + value + '"') or \
- menulst.insert_at(0, 'password "' + value + '"')) and \
- Perms.chmod(menulst.path, 0600)
- # TODO add yaboot support
-
-################################################################################
-
-def nopassword_loader():
- 'D'
- _interactive and log(_('Removing password in boot loader'))
- liloconf = ConfigFile.get_config_file(LILOCONF)
- liloconf.exists() and liloconf.remove_line_matching('^password=', 1)
- menulst = ConfigFile.get_config_file(MENULST)
- menulst.exists() and menulst.remove_line_matching('^password\s')
-
-################################################################################
-
-def enable_console_log(arg, expr='*.*', dev='tty12'):
- ''' Enable/Disable syslog reports to console 12. \\fIexpr\\fP is the
-expression describing what to log (see syslog.conf(5) for more details) and
-dev the device to report the log.'''
-
- syslogconf = ConfigFile.get_config_file(SYSLOGCONF)
-
- if syslogconf.exists():
- val = syslogconf.get_match('\s*[^#]+/dev/([^ ]+)', '@1')
- else:
- val = None
-
- # don't lower security when not changing security level
- if same_level():
- if val:
- return
-
- if arg:
- if dev != val:
- _interactive and log(_('Enabling log on console'))
- syslogconf.exists() and syslogconf.replace_line_matching('\s*[^#]+/dev/', expr + ' /dev/' + dev, 1)
- else:
- if val != None:
- _interactive and log(_('Disabling log on console'))
- syslogconf.exists() and syslogconf.remove_line_matching('\s*[^#]+/dev/')
-
-enable_console_log.arg_trans = YES_NO_TRANS
-
-CRON_ENTRY = '*/1 * * * * root /usr/share/msec/promisc_check.sh'
-CRON_REGEX = '[^#]+/usr/share/msec/promisc_check.sh'
-
-################################################################################
-
-def enable_promisc_check(arg):
- ''' Activate/Disable ethernet cards promiscuity check.'''
- cron = ConfigFile.get_config_file(CRON)
-
- val = cron.exists() and cron.get_match(CRON_REGEX)
-
- # don't lower security when not changing security level
- if same_level():
- if val == CRON_ENTRY:
- return
-
- if arg:
- if val != CRON_ENTRY:
- _interactive and log(_('Activating periodic promiscuity check'))
- cron.replace_line_matching(CRON_REGEX, CRON_ENTRY, 1)
- else:
- if val:
- _interactive and log(_('Disabling periodic promiscuity check'))
- cron.remove_line_matching('[^#]+/usr/share/msec/promisc_check.sh')
-
-enable_promisc_check.arg_trans = YES_NO_TRANS
-
-################################################################################
-
-def enable_security_check(arg):
- ''' Activate/Disable daily security check.'''
- cron = ConfigFile.get_config_file(CRON)
- cron.remove_line_matching('[^#]+/usr/share/msec/security.sh')
-
- securitycron = ConfigFile.get_config_file(SECURITYCRON)
-
- val = securitycron.exists()
-
- # don't lower security when not changing security level
- if same_level():
- if val:
- return
-
- if arg:
- if not val:
- _interactive and log(_('Activating daily security check'))
- securitycron.symlink(SECURITYSH)
- else:
- if val:
- _interactive and log(_('Disabling daily security check'))
- securitycron.unlink()
-
-enable_security_check.arg_trans = YES_NO_TRANS
-
-################################################################################
-
-ALL_REGEXP = '^ALL:ALL:DENY'
-ALL_LOCAL_REGEXP = '^ALL:ALL EXCEPT 127\.0\.0\.1:DENY'
-def authorize_services(arg):
- ''' Authorize all services controlled by tcp_wrappers (see hosts.deny(5)) if \\fIarg\\fP = ALL. Only local ones
-if \\fIarg\\fP = LOCAL and none if \\fIarg\\fP = NONE. To authorize the services you need, use /etc/hosts.allow
-(see hosts.allow(5)).'''
- hostsdeny = ConfigFile.get_config_file(HOSTSDENY)
-
- if hostsdeny.exists():
- if hostsdeny.get_match(ALL_REGEXP):
- val = NONE
- elif hostsdeny.get_match(ALL_LOCAL_REGEXP):
- val = LOCAL
- else:
- val = ALL
- else:
- val = ALL
-
- # don't lower security when not changing security level
- if same_level():
- if val == NONE or (val == LOCAL and arg == ALL):
- return
-
- if arg == ALL:
- if arg != val:
- _interactive and log(_('Authorizing all services'))
- hostsdeny.remove_line_matching(ALL_REGEXP, 1)
- hostsdeny.remove_line_matching(ALL_LOCAL_REGEXP, 1)
- elif arg == NONE:
- if arg != val:
- _interactive and log(_('Disabling all services'))
- hostsdeny.remove_line_matching('^ALL:ALL EXCEPT 127\.0\.0\.1:DENY', 1)
- hostsdeny.replace_line_matching('^ALL:ALL:DENY', 'ALL:ALL:DENY', 1)
- elif arg == LOCAL:
- if arg != val:
- _interactive and log(_('Disabling non local services'))
- hostsdeny.remove_line_matching(ALL_REGEXP, 1)
- hostsdeny.replace_line_matching(ALL_LOCAL_REGEXP, 'ALL:ALL EXCEPT 127.0.0.1:DENY', 1)
- else:
- error(_('authorize_services invalid argument: %s') % arg)
-
-authorize_services.arg_trans = ALL_LOCAL_NONE_TRANS
-
-################################################################################
-
-def boolean2bit(bool):
- if bool:
- return 1
- else:
- return 0
-
-# helper function for enable_ip_spoofing_protection, accept_icmp_echo, accept_broadcasted_icmp_echo,
-# accept_bogus_error_responses and enable_log_strange_packets.
-def set_zero_one_variable(file, variable, value, secure_value, one_msg, zero_msg):
- 'D'
- f = ConfigFile.get_config_file(file)
-
- if f.exists():
- val = f.get_shell_variable(variable)
- if val:
- val = int(val)
- else:
- val = None
-
- # don't lower security when not changing security level
- if same_level():
- if val == secure_value:
- return
-
- if value != val:
- if value:
- msg = _(one_msg)
- else:
- msg = _(zero_msg)
-
- _interactive and log(msg)
- f.set_shell_variable(variable, boolean2bit(value))
-
-################################################################################
-
-# the alert argument is kept for backward compatibility
-def enable_ip_spoofing_protection(arg, alert=1):
- ''' Enable/Disable IP spoofing protection.'''
- set_zero_one_variable(SYSCTLCONF, 'net.ipv4.conf.all.rp_filter', arg, 1, 'Enabling ip spoofing protection', 'Disabling ip spoofing protection')
-
-enable_ip_spoofing_protection.arg_trans = YES_NO_TRANS
-enable_ip_spoofing_protection.one_arg = 1
-
-################################################################################
-
-def enable_dns_spoofing_protection(arg, alert=1):
- ''' Enable/Disable name resolution spoofing protection. If
-\\fIalert\\fP is true, also reports to syslog.'''
- hostconf = ConfigFile.get_config_file(HOSTCONF)
-
- val = hostconf.exists() and hostconf.get_match('nospoof\s+on')
-
- # don't lower security when not changing security level
- if same_level():
- if val:
- return
-
- if arg:
- if not val:
- _interactive and log(_('Enabling name resolution spoofing protection'))
- hostconf.replace_line_matching('nospoof', 'nospoof on', 1)
- hostconf.replace_line_matching('spoofalert', 'spoofalert on', (alert != 0))
- else:
- if val:
- _interactive and log(_('Disabling name resolution spoofing protection'))
- hostconf.remove_line_matching('nospoof')
- hostconf.remove_line_matching('spoofalert')
-
-enable_dns_spoofing_protection.arg_trans = YES_NO_TRANS
-
-################################################################################
-
-def accept_icmp_echo(arg):
- ''' Accept/Refuse icmp echo.'''
- set_zero_one_variable(SYSCTLCONF, 'net.ipv4.icmp_echo_ignore_all', not arg, 1, 'Ignoring icmp echo', 'Accepting icmp echo')
-
-accept_icmp_echo.arg_trans = YES_NO_TRANS
-
-################################################################################
-
-def accept_broadcasted_icmp_echo(arg):
- ''' Accept/Refuse broadcasted icmp echo.'''
- set_zero_one_variable(SYSCTLCONF, 'net.ipv4.icmp_echo_ignore_broadcasts', not arg, 1, 'Ignoring broadcasted icmp echo', 'Accepting broadcasted icmp echo')
-
-accept_broadcasted_icmp_echo.arg_trans = YES_NO_TRANS
-
-################################################################################
-
-def accept_bogus_error_responses(arg):
- ''' Accept/Refuse bogus IPv4 error messages.'''
- set_zero_one_variable(SYSCTLCONF, 'net.ipv4.icmp_ignore_bogus_error_responses', not arg, 1, 'Ignoring bogus icmp error responses', 'Accepting bogus icmp error responses')
-
-accept_bogus_error_responses.arg_trans = YES_NO_TRANS
-
-################################################################################
-
-def enable_log_strange_packets(arg):
- ''' Enable/Disable the logging of IPv4 strange packets.'''
- set_zero_one_variable(SYSCTLCONF, 'net.ipv4.conf.all.log_martians', arg, 1, 'Enabling logging of strange packets', 'Disabling logging of strange packets')
-
-enable_log_strange_packets.arg_trans = YES_NO_TRANS
-
-################################################################################
-
-def enable_libsafe(arg):
- ''' Enable/Disable libsafe if libsafe is found on the system.'''
-
- ldsopreload = ConfigFile.get_config_file(LDSOPRELOAD)
-
- val = ldsopreload.exists() and ldsopreload.get_match('/lib/libsafe.so.2')
-
- # don't lower security when not changing security level
- if same_level():
- if val:
- return
-
- if arg:
- if not val:
- if os.path.exists(Config.get_config('root', '') + '/lib/libsafe.so.2'):
- _interactive and log(_('Enabling libsafe'))
- ldsopreload.replace_line_matching('[^#]*libsafe', '/lib/libsafe.so.2', 1)
- else:
- if val:
- _interactive and log(_('Disabling libsafe'))
- ldsopreload.remove_line_matching('[^#]*libsafe')
-
-enable_libsafe.arg_trans = YES_NO_TRANS
-
-################################################################################
-
-LENGTH_REGEXP = re.compile('^(password\s+required\s+(?:/lib/security/)?pam_cracklib.so.*?)\sminlen=([0-9]+)\s(.*)')
-NDIGITS_REGEXP = re.compile('^(password\s+required\s+(?:/lib/security/)?pam_cracklib.so.*?)\sdcredit=([0-9]+)\s(.*)')
-UCREDIT_REGEXP = re.compile('^(password\s+required\s+(?:/lib/security/)?pam_cracklib.so.*?)\sucredit=([0-9]+)\s(.*)')
-
-def password_length(length, ndigits=0, nupper=0):
- ''' Set the password minimum length and minimum number of digit and minimum number of capitalized letters.'''
-
- passwd = ConfigFile.get_config_file(SYSTEM_AUTH)
-
- val_length = val_ndigits = val_ucredit = 999999
-
- if passwd.exists():
- val_length = passwd.get_match(LENGTH_REGEXP, '@2')
- if val_length:
- val_length = int(val_length)
-
- val_ndigits = passwd.get_match(NDIGITS_REGEXP, '@2')
- if val_ndigits:
- val_ndigits = int(val_ndigits)
-
- val_ucredit = passwd.get_match(UCREDIT_REGEXP, '@2')
- if val_ucredit:
- val_ucredit = int(val_ucredit)
-
- # don't lower security when not changing security level
- if same_level():
- if val_length > length and val_ndigits > ndigits and val_ucredit > nupper:
- return
-
- if val_length > length:
- length = val_length
-
- if val_ndigits > ndigits:
- ndigits = val_ndigits
-
- if val_ucredit > nupper:
- nupper = val_ucredit
-
- if passwd.exists() and (val_length != length or val_ndigits != ndigits or val_ucredit != nupper):
- _interactive and log(_('Setting minimum password length %d') % length)
- (passwd.replace_line_matching(LENGTH_REGEXP,
- '@1 minlen=%s @3' % length) or \
- passwd.replace_line_matching('^password\s+required\s+(?:/lib/security/)?pam_cracklib.so.*',
- '@0 minlen=%s ' % length))
-
- (passwd.replace_line_matching(NDIGITS_REGEXP,
- '@1 dcredit=%s @3' % ndigits) or \
- passwd.replace_line_matching('^password\s+required\s+(?:/lib/security/)?pam_cracklib.so.*',
- '@0 dcredit=%s ' % ndigits))
-
- (passwd.replace_line_matching(UCREDIT_REGEXP,
- '@1 ucredit=%s @3' % nupper) or \
- passwd.replace_line_matching('^password\s+required\s+(?:/lib/security/)?pam_cracklib.so.*',
- '@0 ucredit=%s ' % nupper))
-
-################################################################################
-
-PASSWORD_REGEXP = '^\s*auth\s+sufficient\s+(?:/lib/security/)?pam_permit.so'
-def enable_password(arg):
- ''' Use password to authenticate users.'''
- system_auth = ConfigFile.get_config_file(SYSTEM_AUTH)
-
- val = system_auth.exists() and system_auth.get_match(PASSWORD_REGEXP)
-
- # don't lower security when not changing security level
- if same_level():
- if not val:
- return
-
- if arg:
- if val:
- _interactive and log(_('Using password to authenticate users'))
- system_auth.remove_line_matching(PASSWORD_REGEXP)
- else:
- if not val:
- _interactive and log(_('Don\'t use password to authenticate users'))
- system_auth.replace_line_matching(PASSWORD_REGEXP, 'auth sufficient pam_permit.so') or \
- system_auth.insert_before('auth\s+sufficient', 'auth sufficient pam_permit.so')
-
-enable_password.arg_trans = YES_NO_TRANS
-
-################################################################################
-
-UNIX_REGEXP = re.compile('(^\s*password\s+sufficient\s+(?:/lib/security/)?pam_unix.so.*)\sremember=([0-9]+)(.*)')
-
-def password_history(arg):
- ''' Set the password history length to prevent password reuse.'''
- system_auth = ConfigFile.get_config_file(SYSTEM_AUTH)
-
- if system_auth.exists():
- val = system_auth.get_match(UNIX_REGEXP, '@2')
-
- if val and val != '':
- val = int(val)
- else:
- val = 0
- else:
- val = 0
-
- # don't lower security when not changing security level
- if same_level():
- if val >= arg:
- return
-
- if arg != val:
- if arg > 0:
- _interactive and log(_('Setting password history to %d.') % arg)
- system_auth.replace_line_matching(UNIX_REGEXP, '@1 remember=%d@3' % arg) or \
- system_auth.replace_line_matching('(^\s*password\s+sufficient\s+(?:/lib/security/)?pam_unix.so.*)', '@1 remember=%d' % arg)
- opasswd = ConfigFile.get_config_file(OPASSWD)
- opasswd.exists() or opasswd.touch()
- else:
- _interactive and log(_('Disabling password history'))
- system_auth.replace_line_matching(UNIX_REGEXP, '@1@3')
-
-################################################################################
-
-SULOGIN_REGEXP = '~~:S:wait:/sbin/sulogin'
-def enable_sulogin(arg):
- ''' Enable/Disable sulogin(8) in single user level.'''
- inittab = ConfigFile.get_config_file(INITTAB)
-
- val = inittab.exists() and inittab.get_match(SULOGIN_REGEXP)
-
- # don't lower security when not changing security level
- if same_level():
- if val:
- return
-
- if arg:
- if not val:
- _interactive and log(_('Enabling sulogin in single user runlevel'))
- inittab.replace_line_matching('[^#]+:S:', '~~:S:wait:/sbin/sulogin', 1)
- else:
- if val:
- _interactive and log(_('Disabling sulogin in single user runlevel'))
- inittab.remove_line_matching('~~:S:wait:/sbin/sulogin')
-
-enable_sulogin.arg_trans = YES_NO_TRANS
-
-################################################################################
-
-def enable_msec_cron(arg):
- ''' Enable/Disable msec hourly security check.'''
- mseccron = ConfigFile.get_config_file(MSECCRON)
-
- val = mseccron.exists()
-
- # don't lower security when not changing security level
- if same_level():
- if val:
- return
-
- if arg:
- if arg != val:
- _interactive and log(_('Enabling msec periodic runs'))
- mseccron.symlink(MSECBIN)
- else:
- if arg != val:
- _interactive and log(_('Disabling msec periodic runs'))
- mseccron.unlink()
-
-enable_msec_cron.arg_trans = YES_NO_TRANS
-
-################################################################################
-
-def enable_at_crontab(arg):
- ''' Enable/Disable crontab and at for users. Put allowed users in /etc/cron.allow and /etc/at.allow
-(see man at(1) and crontab(1)).'''
- cronallow = ConfigFile.get_config_file(CRONALLOW)
- atallow = ConfigFile.get_config_file(ATALLOW)
-
- val_cronallow = cronallow.exists() and cronallow.get_match('root')
- val_atallow = atallow.exists() and atallow.get_match('root')
-
- # don't lower security when not changing security level
- if same_level():
- if val_cronallow and val_atallow:
- return
-
- if arg:
- if val_cronallow or val_atallow:
- _interactive and log(_('Enabling crontab and at'))
- if not (same_level() and val_cronallow):
- cronallow.exists() and cronallow.move(SUFFIX)
- if not (same_level() and val_atallow):
- atallow.exists() and atallow.move(SUFFIX)
- else:
- if not val_cronallow or not val_atallow:
- _interactive and log(_('Disabling crontab and at'))
- cronallow.replace_line_matching('root', 'root', 1)
- atallow.replace_line_matching('root', 'root', 1)
-
-enable_at_crontab.arg_trans = YES_NO_TRANS
-
-################################################################################
-
-maximum_regex = re.compile('^Maximum.*:\s*([0-9]+|-1)', re.MULTILINE)
-inactive_regex = re.compile('^(Inactive|Password inactive\s*):\s*(-?[0-9]+|never)', re.MULTILINE)
-no_aging_list = []
-
-def no_password_aging_for(name):
- '''D Add the name as an exception to the handling of password aging by msec.
-Name must be put between '. Msec will then no more manage password aging for
-name so you have to use chage(1) to manage it by hand.'''
- no_aging_list.append(name)
-
-def password_aging(max, inactive=-1):
- ''' Set password aging to \\fImax\\fP days and delay to change to \\fIinactive\\fP.'''
- uid_min = 500
- _interactive and log(_('Setting password maximum aging for new user to %d') % max)
- logindefs = ConfigFile.get_config_file(LOGINDEFS)
- if logindefs.exists():
- logindefs.replace_line_matching('^\s*PASS_MAX_DAYS', 'PASS_MAX_DAYS ' + str(max), 1)
- uid_min = logindefs.get_match('^\s*UID_MIN\s+([0-9]+)', '@1')
- if uid_min:
- uid_min = int(uid_min)
- shadow = ConfigFile.get_config_file(SHADOW)
- if shadow.exists():
- _interactive and log(_('Setting password maximum aging for root and users with id greater than %d to %d and delay to %d days') % (uid_min, max, inactive))
- for line in shadow.get_lines():
- field = string.split(line, ':')
- if len(field) < 2:
- continue
- name = field[0]
- password = field[1]
- if name in no_aging_list:
- _interactive and log(_('User %s in password aging exception list') % (name,))
- continue
- try:
- entry = pwd.getpwnam(name)
- except KeyError:
- error(_('User %s in shadow but not in passwd file') % name)
- continue
- if (len(password) > 0 and password[0] != '!') and password != '*' and password != 'x' and (entry[2] >= uid_min or entry[2] == 0):
- if field[4] == '':
- current_max = 99999
- else:
- current_max = int(field[4])
- if field[6] == '':
- current_inactive = -1
- else:
- current_inactive = int(field[6])
- new_max = max
- new_inactive = inactive
- # don't lower security when not changing security level
- if same_level():
- if current_max < max and current_inactive < inactive:
- continue
- if current_max < max:
- new_max = current_max
- if current_inactive < inactive:
- new_inactive = current_inactive
- if new_max != current_max or current_inactive != new_inactive:
- cmd = 'LC_ALL=C /usr/bin/chage -M %d -I %d -d %s \'%s\'' % (new_max, new_inactive, time.strftime('%Y-%m-%d'), entry[0])
- ret = commands.getstatusoutput(cmd)
- log(_('changed maximum password aging for user \'%s\' with command %s') % (entry[0], cmd))
-
-################################################################################
-
-def allow_xauth_from_root(arg):
- ''' Allow/forbid to export display when passing from the root account
-to the other users. See pam_xauth(8) for more details.'''
- export = ConfigFile.get_config_file(EXPORT)
-
- allow = export.exists() and export.get_match('^\*$')
-
- # don't lower security when not changing security level
- if same_level():
- if not allow:
- return
-
- if arg:
- if not allow:
- _interactive and log(_('Allowing export display from root'))
- export.insert_at(0, '*')
- else:
- if allow:
- _interactive and log(_('Forbidding export display from root'))
- export.remove_line_matching('^\*$')
-
-################################################################################
-
-def set_security_conf(var, value):
- '''1 Set the variable \\fIvar\\fP to the value \\fIvalue\\fP in /var/lib/msec/security.conf.
-The best way to override the default setting is to create /etc/security/msec/security.conf
-with the value you want. These settings are used to configure the daily check run each night.
-
-The following variables are currentrly recognized by msec:
-
-CHECK_UNOWNED if set to yes, report unowned files.
-
-CHECK_SHADOW if set to yes, check empty password in /etc/shadow.
-
-CHECK_SUID_MD5 if set to yes, verify checksum of the suid/sgid files.
-
-CHECK_SECURITY if set to yes, run the daily security checks.
-
-CHECK_PASSWD if set to yes, check for empty passwords, for no password in /etc/shadow and for users with the 0 id other than root.
-
-SYSLOG_WARN if set to yes, report check result to syslog.
-
-CHECK_SUID_ROOT if set to yes, check additions/removals of suid root files.
-
-CHECK_PERMS if set to yes, check permissions of files in the users' home.
-
-CHKROOTKIT_CHECK if set to yes, run chkrootkit checks.
-
-CHECK_PROMISC if set to yes, check if the network devices are in promiscuous mode.
-
-RPM_CHECK if set to yes, run some checks against the rpm database.
-
-TTY_WARN if set to yes, reports check result to tty.
-
-CHECK_WRITABLE if set to yes, check files/directories writable by everybody.
-
-MAIL_WARN if set to yes, report check result by mail.
-
-MAIL_USER if set, send the mail report to this email address else send it to root.
-
-CHECK_OPEN_PORT if set to yes, check open ports.
-
-CHECK_SGID if set to yes, check additions/removals of sgid files.
-'''
- securityconf = ConfigFile.get_config_file(SECURITYCONF)
- securityconf.set_shell_variable(var, value)
-
-# various
-
-def set_interactive(v):
- "D"
-
- global _interactive
-
- _interactive = v
-
-# libmsec.py ends here
-
diff --git a/share/man.py b/share/man.py
deleted file mode 100755
index 7859ed8..0000000
--- a/share/man.py
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/bin/python
-#---------------------------------------------------------------
-# Project : Mandriva Linux
-# Module : share
-# File : man.py
-# Version : $Id$
-# Author : Frederic Lepied
-# Created On : Sat Jan 26 17:38:39 2002
-# Purpose : loads a python module and creates a man page from
-# the doc strings of the functions.
-#---------------------------------------------------------------
-
-import sys
-import imp
-import inspect
-
-header = '''.ds q \N'34'
-.TH mseclib 3 V0 msec "Mandriva Linux"
-.SH NAME
-mseclib
-.SH SYNOPSIS
-.nf
-.B from mseclib import *
-.B function1(yes)
-.B function2(ignore)
-.fi
-.SH DESCRIPTION
-.B mseclib
-is a python library to access the function used by the msec program. This functions can be used
-in /etc/security/msec/level.local to override the behaviour of the msec program or in standalone
-scripts. The first argument of the functions takes a value of 1 or 0 or -1 (or yes/no/ignore)
-except when specified otherwise.
-'''
-
-footer = '''.RE
-.SH "SEE ALSO"
-msec(8)
-.SH AUTHORS
-Frederic Lepied <flepied@mandriva.com>
-'''
-
-### strings used in the rewritting
-function_str = '''
-.TP 4
-.B \\fI%s%s\\fP
-%s
-'''
-
-### code
-modulename = sys.argv[1]
-
-module = __import__(modulename)
-
-sys.stdout.write(header)
-
-for f in inspect.getmembers(module, inspect.isfunction):
- (args, varargs, varkw, locals) = inspect.getargspec(f[1])
- doc = f[1].__doc__
- if doc and len(doc) > 2:
- doc = doc[2:]
- argspec = inspect.formatargspec(args, varargs, varkw, locals)
- s = function_str % (f[0], argspec, doc)
- sys.stdout.write(s)
-
-sys.stdout.write(footer)
-
-# man.py ends here
diff --git a/share/msec b/share/msec
deleted file mode 100755
index f19cd9b..0000000
--- a/share/msec
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/bin/sh
-#---------------------------------------------------------------
-# Project : Mandriva Linux
-# Module : share
-# File : msec
-# Version : $Id$
-# Author : Frederic Lepied
-# Created On : Thu Dec 13 11:36:50 2001
-# Purpose : entry script to run hardness script or change
-# the security level.
-#---------------------------------------------------------------
-
-if [ "`whoami`" != "root" ]; then
- echo 'msec: sorry, you must be root !'
- exit 1
-fi
-
-LCK=/var/run/msec.pid
-
-function cleanup() {
- rm -f $LCK
-}
-
-if [ -f $LCK ]; then
- if [ -d /proc/`cat $LCK` ]; then
- exit 0
- else
- rm -f $LCK
- fi
-fi
-
-echo -n $$ > $LCK
-
-trap cleanup 0
-
-MSEC=/usr/share/msec/msec.py
-OPT=""
-
-for a in "$@"; do
- if [ "$a" = '-o' ]; then
- OPT="$OPT -o"
- NEXT=1
- else
- if [ "$NEXT" = 1 ]; then
- OPT="$OPT $a"
- else
- last="$a"
- fi
- NEXT=0
- fi
-done
-
-if [ -n "$last" ]; then
- CHANGE=-c
- case "$last" in
- [0-5]) ;;
- *) [ -x /usr/share/msec/$last.py ] && MSEC=/usr/share/msec/$last.py;;
- esac
-else
- # no args so try to guess if a custom msec is needed
- . /etc/sysconfig/msec
-
- case "$SECURE_LEVEL" in
- [0-5]) ;;
- *) MSEC=/usr/share/msec/$SECURE_LEVEL.py;;
- esac
-fi
-
-if [ ! -x "$MSEC" ]; then
- echo "$MSEC not found or not executable. Aborting" 1>&2
- exit 1
-fi
-
-if $MSEC "$@"; then
- . /etc/sysconfig/msec
-
- [ -z "$PERM_LEVEL" ] && PERM_LEVEL=$SECURE_LEVEL
-
- LOCAL=
- [ -f /etc/security/msec/perm.local ] && LOCAL=/etc/security/msec/perm.local
-
- /usr/share/msec/Perms.py $CHANGE $OPT /usr/share/msec/perm.$PERM_LEVEL $LOCAL
-fi
-
-# msec ends here
diff --git a/share/msec.py b/share/msec.py
deleted file mode 100755
index 553890c..0000000
--- a/share/msec.py
+++ /dev/null
@@ -1,290 +0,0 @@
-#!/usr/bin/python -O
-#---------------------------------------------------------------
-# Project : Mandriva Linux
-# Module : msec/share
-# File : msec.py
-# Version : $Id$
-# Author : Frederic Lepied
-# Created On : Wed Dec 5 20:20:21 2001
-#---------------------------------------------------------------
-
-from mseclib import *
-from Log import *
-from Log import _name
-import Config
-import ConfigFile
-
-import sys
-import os
-import string
-import getopt
-import gettext
-import imp
-
-try:
- cat = gettext.Catalog('msec')
- _ = cat.gettext
-except IOError:
- _ = str
-
-# Eval a file
-import mseclib
-def import_only_mseclib(name, globals = None, locals = None, fromlist = None):
- """ Import hook to allow only the mseclib module to be imported. """
-
- if name == 'mseclib':
- return mseclib
- else:
- raise ImportError, '%s cannot be imported' % name
-
-def eval_file(name):
- """ Eval level.local file. Only allow mseclib to be imported for
- backward compatibility. """
-
- globals = {}
- locals = {}
- builtins = {}
-
- # Insert symbols from mseclib into globals
- non_exported_names = ['FAKE', 'indirect', 'commit_changes', 'print_changes', 'get_translation']
- for attrib_name in dir(mseclib):
- if attrib_name[0] != '_' and attrib_name not in non_exported_names:
- globals[attrib_name] = getattr(mseclib, attrib_name)
-
- # Set import hook -- it needs to be in globals['__builtins'] so we make
- # a copy of builtins to put there
- builtins.update(__builtins__.__dict__)
- builtins['__import__'] = import_only_mseclib
- globals['__builtins__'] = builtins
-
- # Exec file
- execfile(os.path.expanduser(name), globals, locals)
-
-# program
-_name = 'msec'
-
-sys.argv[0] = os.path.basename(sys.argv[0])
-
-try:
- (opt, args) = getopt.getopt(sys.argv[1:], 'o:',
- ['option'])
-except getopt.error:
- error(_('Invalid option. Use %s (-o var=<val>...) ([0-5])') % _name)
- sys.exit(1)
-
-
-for o in opt:
- if o[0] == '-o' or o[0] == '--option':
- pair = string.split(o[1], '=')
- if len(pair) != 2:
- error(_('Invalid option format %s %s: use -o var=<val>') % (o[0], o[1]))
- sys.exit(1)
- else:
- Config.set_config(pair[0], pair[1])
-
-interactive = sys.stdin.isatty()
-set_interactive(interactive)
-
-# initlog must be done after processing the option because we can change
-# the way to report log with options...
-if interactive:
- import syslog
-
- initlog('msec', syslog.LOG_LOCAL1)
-else:
- initlog('msec')
-
-if len(args) == 0:
- level = get_secure_level()
- if level == None:
- error(_('Secure level not set. Use %s <secure level> to set it.') % _name)
- sys.exit(1)
-else:
- level = args[0]
- changing_level()
-
-try:
- level = int(level)
-except ValueError:
- error(_('Invalid secure level %s. Use %s [0-5] to set it.') % (level, _name))
- sys.exit(1)
-
-if level < 0 or level > 5:
- error(_('Invalid secure level %s. Use %s [0-5] to set it.') % (level, _name))
- sys.exit(1)
-
-interactive and log(_('### Program is starting ###'))
-
-set_secure_level(level)
-
-server=(level in range(3, 6))
-
-# process options
-server_level = Config.get_config('server_level')
-if server_level:
- set_server_level(server_level)
-
-create_server_link()
-
-# for all levels: min length = 2 * (level - 1) and for level 4,5 makes mandatory
-# to have at least one upper case character and one digit.
-if level > 1:
- plength = (level - 1) * 2
-else:
- plength = 0
-
-password_length(plength, level / 4, level / 4)
-
-enable_ip_spoofing_protection(server)
-enable_dns_spoofing_protection(server)
-
-# differences between level 5 and others
-if level == 5:
- set_root_umask('077')
- set_shell_timeout(900)
- authorize_services(NONE)
- enable_pam_wheel_for_su(yes)
- password_history(5)
-else:
- set_root_umask('022')
- if level == 4:
- set_shell_timeout(3600)
- authorize_services(LOCAL)
- else:
- set_shell_timeout(0)
- authorize_services(ALL)
- enable_pam_wheel_for_su(no)
- password_history(0)
-
-# differences between level 4,5 and others
-if level >= 4:
- set_user_umask('077')
- set_shell_history_size(10)
- allow_root_login(no)
- enable_sulogin(yes)
- allow_user_list(no)
- enable_promisc_check(yes)
- accept_icmp_echo(no)
- accept_broadcasted_icmp_echo(no)
- accept_bogus_error_responses(no)
- allow_reboot(no)
- enable_at_crontab(no)
- if level == 4:
- password_aging(60, 30)
- else:
- password_aging(30, 15)
- allow_xauth_from_root(no)
- set_win_parts_umask(None)
-else:
- set_user_umask('022')
- set_shell_history_size(-1)
- allow_root_login(yes)
- enable_sulogin(no)
- allow_user_list(yes)
- enable_promisc_check(no)
- accept_icmp_echo(yes)
- accept_broadcasted_icmp_echo(yes)
- accept_bogus_error_responses(yes)
- allow_reboot(yes)
- enable_at_crontab(yes)
- password_aging(99999)
- allow_xauth_from_root(yes)
-
-# special exception for ssh; if level == 3, set
-# PermitRootLogin to without_password, otherwise set to no
-# see https://qa.mandriva.com/show_bug.cgi?id=19726
-if level >= 3:
- if level == 3:
- allow_remote_root_login(without_password)
- else:
- allow_remote_root_login(no)
-else:
- allow_remote_root_login(yes)
-
-# differences between level 3,4,5 and others
-if server:
- allow_autologin(no)
- enable_console_log(yes)
- if level == 5:
- allow_issues(NONE)
- else:
- allow_issues(LOCAL)
- enable_log_strange_packets(yes)
- enable_pam_root_from_wheel(no)
-else:
- allow_autologin(yes)
- enable_console_log(no)
- allow_issues(ALL)
- enable_log_strange_packets(no)
- enable_pam_root_from_wheel(yes)
- set_win_parts_umask('0')
-
-# differences between level 0 and others
-if level != 0:
- enable_security_check(yes)
- enable_password(yes)
- if level < 3:
- allow_x_connections(LOCAL)
- allow_xserver_to_listen(yes)
- else:
- if level == 3:
- allow_x_connections(NONE)
- allow_xserver_to_listen(yes)
- else:
- allow_x_connections(NONE)
- allow_xserver_to_listen(no)
-else:
- enable_security_check(no)
- enable_password(no)
- allow_x_connections(ALL, 1)
- allow_xserver_to_listen(yes)
-
-# msec cron
-enable_msec_cron(1)
-
-# 0 1 2 3 4 5
-FILE_CHECKS = {'CHECK_SECURITY' : ('no', 'yes', 'yes', 'yes', 'yes', 'yes', ),
- 'CHECK_PERMS' : ('no', 'no', 'no', 'yes', 'yes', 'yes', ),
- 'CHECK_SUID_ROOT' : ('no', 'no', 'yes', 'yes', 'yes', 'yes', ),
- 'CHECK_SUID_MD5' : ('no', 'no', 'yes', 'yes', 'yes', 'yes', ),
- 'CHECK_SGID' : ('no', 'no', 'yes', 'yes', 'yes', 'yes', ),
- 'CHECK_WRITABLE' : ('no', 'no', 'yes', 'yes', 'yes', 'yes', ),
- 'CHECK_UNOWNED' : ('no', 'no', 'no', 'no', 'yes', 'yes', ),
- 'CHECK_PROMISC' : ('no', 'no', 'no', 'no', 'yes', 'yes', ),
- 'CHECK_OPEN_PORT' : ('no', 'no', 'no', 'yes', 'yes', 'yes', ),
- 'CHECK_PASSWD' : ('no', 'no', 'no', 'yes', 'yes', 'yes', ),
- 'CHECK_SHADOW' : ('no', 'no', 'no', 'yes', 'yes', 'yes', ),
- 'TTY_WARN' : ('no', 'no', 'no', 'no', 'yes', 'yes', ),
- 'MAIL_WARN' : ('no', 'no', 'no', 'yes', 'yes', 'yes', ),
- 'MAIL_EMPTY_CONTENT':('no', 'no', 'no', 'no', 'yes', 'yes', ),
- 'SYSLOG_WARN' : ('no', 'no', 'yes', 'yes', 'yes', 'yes', ),
- 'RPM_CHECK' : ('no', 'no', 'no', 'yes', 'yes', 'yes', ),
- 'CHKROOTKIT_CHECK' : ('no', 'no', 'no', 'yes', 'yes', 'yes', ),
- }
-
-for k in FILE_CHECKS.keys():
- set_security_conf(k, FILE_CHECKS[k][level])
-
-if Config.get_config('nolocal', '0') == '0':
- # load local customizations
- CONFIG='/etc/security/msec/level.local'
- if os.path.exists(CONFIG):
- interactive and log(_('Reading local rules from %s') % CONFIG)
- local_config(1)
- try:
- eval_file(CONFIG)
- except:
- log(_('Error loading %s: %s') % (CONFIG, str(sys.exc_value)))
- local_config(0)
-
-if Config.get_config('print', '0') == '1':
- print_changes()
-else:
- commit_changes()
-
-interactive and log(_('Writing config files and then taking needed actions'))
-ConfigFile.write_files()
-
-closelog()
-
-# msec.py ends here
diff --git a/share/shadow.py b/share/shadow.py
deleted file mode 100755
index e49ebb4..0000000
--- a/share/shadow.py
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/usr/bin/python
-#---------------------------------------------------------------
-# Project : Mandriva Linux
-# Module : msec/share
-# File : shadow.py
-# Version : $Id$
-# Author : Frederic Lepied
-# Created On : Sat Jan 26 17:38:39 2002
-# Purpose : loads a python module and creates another one
-# on stdout. All the functions of the module are shadowed according
-# to their doc string: "D" direct mapping, "1" indirect call but
-# name + first arg used as the key and all other cases indirect
-# call with the name as the key.
-#---------------------------------------------------------------
-
-import sys
-import imp
-import inspect
-
-### strings used in the rewritting
-direct_str = """
-%s=%s.%s
-
-"""
-
-indirect_str = """
-def %s(*args):
- indirect(\"%s\", %s.%s, %d, args)
-
-"""
-
-header = """
-
-NONE=0
-ALL=1
-LOCAL=2
-
-yes=1
-no=0
-without_password=2
-ignore=-1
-
-FAKE = {}
-
-_force = 0
-
-def local_config(val):
- global _force
- _force = val
-
-def indirect(name, func, type, args):
- if type == 1:
- key = (name, args[0])
- else:
- key = name
- FAKE[key] = (func, args)
- if _force:
- force_val(name)
-
-def commit_changes():
- for f in FAKE.values():
- if len(f[1]) >= 1 and (f[1][0] != -1 or f[0].__name__ == 'set_shell_history_size'):
- f[0](*f[1])
- elif len(f[1]) == 0:
- f[0]()
-
-def print_changes():
- import sys
- for f in FAKE.values():
- l = len(f[1])
- if l >= 1 and (f[1][0] != -1 or f[0].__name__ == 'set_shell_history_size'):
- name = f[0].__name__
- try:
- if f[0].one_arg:
- l = 1
- except AttributeError:
- pass
- if l == 1:
- print name, get_translation(f[0], f[1][0])
- else:
- sys.stdout.write(name)
- for a in f[1]:
- sys.stdout.write(' ' + str(a))
- sys.stdout.write('\\n')
-
-def get_translation(func, value):
- try:
- return func.arg_trans[value]
- except (KeyError, AttributeError):
- return value
-
-"""
-
-### code
-modulename = sys.argv[1]
-
-module = __import__(modulename)
-
-sys.stdout.write(header)
-
-sys.stdout.write("import %s\n\n" % modulename)
-
-for f in inspect.getmembers(module, inspect.isfunction):
- (args, varargs, varkw, locals) = inspect.getargspec(f[1])
- if f[1].__doc__ and f[1].__doc__[0] == 'D':
- #argspec = inspect.formatargspec(args, varargs, varkw, locals)
- s = direct_str % (f[0], modulename, f[0])
- else:
- if f[1].__doc__ and f[1].__doc__[0] == '1':
- type = 1
- else:
- type = 0
- s = indirect_str % (f[0], f[0], modulename, f[0], type)
- sys.stdout.write(s)
-
-# shadow.py ends here