source: branches/fc17-dev/server/common/oursrc/fuse-better-mousetrapfs/better-mousetrapfs @ 2195

Last change on this file since 2195 was 2161, checked in by ezyang, 11 years ago
Remove pointless race checking; kernel doesn't preserve old proc directories.
  • Property svn:executable set to *
File size: 3.1 KB
Line 
1#!/usr/bin/python
2# -*- coding: utf-8 -*-
3
4# better-mousetrapfs: Filesystem that logs and kills any accessors
5# version 1.0, released 2010-03-31
6# Copyright © 2010 Anders Kaseorg <andersk@mit.edu>
7#
8# Permission is hereby granted, free of charge, to any person
9# obtaining a copy of this software and associated documentation files
10# (the “Software”), to deal in the Software without restriction,
11# including without limitation the rights to use, copy, modify, merge,
12# publish, distribute, sublicense, and/or sell copies of the Software,
13# and to permit persons to whom the Software is furnished to do so,
14# subject to the following conditions:
15#
16# The above copyright notice and this permission notice shall be
17# included in all copies or substantial portions of the Software.
18#
19# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
20# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22# NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
23# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
24# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26# SOFTWARE.
27
28import errno
29import fuse
30import grp
31import os
32import pwd
33import signal
34import stat
35import syslog
36
37fuse.fuse_python_api = (0, 2)
38
39class BetterMousetrapFS(fuse.Fuse):
40    def __init__(self, *args, **kwargs):
41        syslog.openlog('better-mousetrapfs')
42        fuse.Fuse.__init__(self, *args, **kwargs)
43
44    def getattr(self, path):
45        if path == '/':
46            return fuse.Stat(st_mode = stat.S_IFDIR | 0755, st_nlink = 2)
47        else:
48            return -errno.EACCES
49
50    def opendir(self, path):
51        self.spring(fuse.FuseGetContext())
52        return -errno.EACCES
53
54    def spring(self, context):
55        pid = context['pid']
56        uid = context['uid']
57        gid = context['gid']
58        try:
59            user = '%d %r' % (uid, pwd.getpwuid(uid).pw_name)
60        except KeyError:
61            user = '%d' % uid
62        try:
63            group = '%d %r' % (gid, grp.getgrgid(gid).gr_name)
64        except KeyError:
65            group = '%d' % gid
66        cmdline = open('/proc/%d/cmdline' % pid).read().split('\0')[:-1]
67        exe = os.readlink('/proc/%d/exe' % pid)
68        status = dict(tuple(v.strip() for v in l.split(':', 1))
69                      for l in open('/proc/%d/status' % pid).readlines())
70        cwd = os.readlink('/proc/%d/cwd' % pid)
71
72        syslog.syslog(
73            syslog.LOG_WARNING | 80, # 80 = LOG_AUTHPRIV
74            'mousetrap caught process %d, uid=%s, gid=%s, exe=%r, cmdline=%r, cwd=%r' %
75            (pid, user, group, exe, cmdline, cwd))
76
77        try:
78            nonlocal_gid = grp.getgrnam('nss-nonlocal-users').gr_gid
79        except KeyError:
80            nonlocal_gid = None
81        if str(nonlocal_gid) in status['Groups'].split():
82            os.kill(pid, signal.SIGKILL)
83            pass
84
85if __name__ == '__main__':
86    fs = BetterMousetrapFS()
87    fs.parse(errex=1)
88    fs.fuse_args.add('allow_other')
89    fs.fuse_args.add('ro')
90    fs.main()
Note: See TracBrowser for help on using the repository browser.