14 # ToDo replace with ikarus
18 MINOPTS = { "Main" : ["Logfile", "Mountpoint", "Rootpath"]}
20 CONFIG_NOT_READABLE = "Configfile is not readable"
21 CONFIG_WRONG = "Something is wrong with the config"
22 CONFIG_MISSING = "Section: \"%s\" Option: \"%s\" in configfile is missing"
25 SYSTEM_FILE_COMMAND = "file"
28 def checkMinimumOptions (config):
29 for section, options in MINOPTS.iteritems ():
30 for option in options:
31 if (config.has_option(section, option) == False):
32 print (CONFIG_MISSING % (section, option))
37 print ("%s configfile" % (sys.argv[0]))
43 if (len (sys.argv) < 2):
46 configfile = sys.argv[1]
47 config = ConfigParser.SafeConfigParser ()
49 if ((os.path.exists (configfile) == False) or (os.path.isfile (configfile) == False) or (os.access (configfile, os.R_OK) == False)):
50 print (CONFIG_NOT_READABLE)
54 config.read (sys.argv[1])
57 print ("Error: %s" % (e))
59 checkMinimumOptions (config)
67 logfile = config.get("Main", "Logfile")
69 # ToDo move log level and maybe other things to config file
71 level = logging.DEBUG,
72 format = "%(asctime)s %(name)-12s %(funcName)-15s %(levelname)-8s %(message)s",
73 datefmt = "%Y-%m-%d %H:%M:%S",
77 LOG = logging.getLogger("fuse_main")
83 def rootPath (rootpath, path):
84 return "%s%s" % (rootpath, path)
86 def flag2mode (flags):
87 md = {os.O_RDONLY: 'r', os.O_WRONLY: 'w', os.O_RDWR: 'w+'}
88 m = md[flags & (os.O_RDONLY | os.O_WRONLY | os.O_RDWR)]
90 if flags | os.O_APPEND:
91 m = m.replace('w', 'a', 1)
100 LOG.debug ("Scan File: %s" % (path))
102 # ToDo implement ikarus
103 result = pyclamav.scanfile (path)
104 LOG.debug ("Result of file \"%s\": %s" % (path, result))
108 if (infected == True):
109 LOG.error ("Virus found deny Access %s" % (result,))
113 def whitelistFile (path):
116 LOG.debug ("Execute \"%s\" command on \"%s\"" %(SYSTEM_FILE_COMMAND, path))
120 result = subprocess.check_output ([SYSTEM_FILE_COMMAND, path]);
121 # ToDo replace with real whitelist
123 except Exception as e:
124 LOG.error ("Call returns with an error!")
127 LOG.debug ("Type: %s" %(result))
136 def __init__(self, rootpath, *args, **kw):
137 self.__rootpath = rootpath
138 Fuse.__init__ (self, *args, **kw)
139 LOG.debug ("Init complete.")
141 # defines that our working directory will be the __rootpath
143 os.chdir (self.__rootpath)
145 def getattr(self, path):
146 LOG.debug ("*** getattr (%s)" % (fixPath (path)))
147 return os.lstat (fixPath (path));
149 def getdir(self, path):
150 LOG.debug ("*** getdir (%s)" % (path));
151 return os.listdir (fixPath (path))
153 def readdir(self, path, offset):
154 LOG.debug ("*** readdir (%s %s)" % (path, offset));
155 for e in os.listdir (fixPath (path)):
156 yield fuse.Direntry(e)
158 def chmod (self, path, mode):
159 LOG.debug ("*** chmod %s %s" % (path, oct(mode)))
160 os.chmod (fixPath (path), mode)
162 def chown (self, path, uid, gid):
163 LOG.debug ("*** chown %s %s %s" % (path, uid, gid))
164 os.chown (fixPath (path), uid, gid)
166 def link (self, targetPath, linkPath):
167 LOG.debug ("*** link %s %s" % (targetPath, linkPath))
168 os.link (fixPath (targetPath), fixPath (linkPath))
170 def mkdir (self, path, mode):
171 LOG.debug ("*** mkdir %s %s" % (path, oct(mode)))
172 os.mkdir (fixPath (path), mode)
174 def mknod (self, path, mode, dev):
175 LOG.debug ("*** mknod %s %s %s" % (path, oct (mode), dev))
176 os.mknod (fixPath (path), mode, dev)
178 # to implement virus scan
179 def open (self, path, flags):
180 LOG.debug ("*** open %s %s" % (path, oct (flags)))
181 self.file = os.fdopen (os.open (fixPath (path), flags), flag2mode (flags))
182 self.fd = self.file.fileno ()
184 infected = scanFile (rootPath(self.__rootpath, path))
185 if (infected == True):
189 whitelisted = whitelistFile (rootPath(self.__rootpath, path))
190 if (whitelisted == False):
194 def read (self, path, length, offset):
195 LOG.debug ("*** read %s %s %s" % (path, length, offset))
196 self.file.seek (offset)
197 return self.file.read (length)
199 def readlink (self, path):
200 LOG.debug ("*** readlink %s" % (path))
201 return os.readlink (fixPath (path))
203 def release (self, path, flags):
204 LOG.debug ("*** release %s %s" % (path, oct (flags)))
207 def rename (self, oldPath, newPath):
208 LOG.debug ("*** rename %s %s" % (oldPath, newPath))
209 os.rename (fixPath (oldPath), fixPath (newPath))
211 def rmdir (self, path):
212 LOG.debug ("*** rmdir %s" % (path))
213 os.rmdir (fixPath (path))
216 LOG.debug ("*** statfs")
217 return os.statvfs(".")
219 def symlink (self, targetPath, linkPath):
220 LOG.debug ("*** symlink %s %s" % (targetPath, linkPath))
221 os.symlink (fixPath (targetPath), fixPath (linkPath))
223 def truncate (self, path, length):
224 LOG.debug ("*** truncate %s %s" % (path, length))
225 f = open (fixPath (path), "a")
229 def unlink (self, path):
230 LOG.debug ("*** unlink %s" % (path))
231 os.unlink (fixPath (path))
233 def utime (self, path, times):
234 LOG.debug ("*** utime %s %s" % (path, times))
235 os.utime (fixPath (path), times)
237 def write (self, path, buf, offset):
238 LOG.debug ("*** write %s %s %s" % (path, buf, offset))
239 self.file.seek (offset)
240 self.file.write (buf)
243 def access (self, path, mode):
244 LOG.debug ("*** access %s %s" % (path, oct (mode)))
245 if not os.access (fixPath (path), mode):
248 def create (self, path, flags, mode):
249 LOG.debug ("*** create %s %s %s %s" % (fixPath (path), oct (flags), oct (mode), flag2mode (flags)))
250 self.file = os.fdopen (os.open (fixPath (path), flags, mode), flag2mode (flags))
251 self.fd = self.file.fileno ()
254 if __name__ == "__main__":
256 fuse.fuse_python_api = (0, 2)
257 fuse.feature_assert ('stateful_files', 'has_init')
259 config = loadConfig ()
262 osecfs = OsecFS (config.get ("Main", "Rootpath"))
264 osecfs.multithreaded = 0
266 # osecfs.parser.add_option (mountopt=config.get("Main", "Mountpoint"),
268 # default=config.get("Main", "Rootpath"),
269 # help="mirror filesystem from under PATH [default: %default]")
270 # osecfs.parse(values=osecfs, errex=1)
272 fuse_args = [sys.argv[0], config.get ("Main", "Mountpoint")];
273 osecfs.main (fuse_args)