diff options
| author | jvoisin | 2011-06-27 17:42:42 +0200 |
|---|---|---|
| committer | jvoisin | 2011-06-27 17:42:42 +0200 |
| commit | 6c5cad3f96a1bbe20b668730ba66dfb43eb14b08 (patch) | |
| tree | 152001b274384ec6a9d16a493ced84009412b525 | |
| parent | 7c05c4edef20cc7438a8a90f2e9f1b507e82c132 (diff) | |
Add is_clean() method to archives, and move the 'secure_remove' function from parser.py to mat.py
| -rw-r--r-- | lib/archive.py | 58 | ||||
| -rw-r--r-- | lib/mat.py | 12 | ||||
| -rw-r--r-- | lib/parser.py | 15 |
3 files changed, 52 insertions, 33 deletions
diff --git a/lib/archive.py b/lib/archive.py index 89425cf..446e493 100644 --- a/lib/archive.py +++ b/lib/archive.py | |||
| @@ -5,47 +5,63 @@ import mat | |||
| 5 | import shutil | 5 | import shutil |
| 6 | 6 | ||
| 7 | class TarStripper(parser.Generic_parser): | 7 | class TarStripper(parser.Generic_parser): |
| 8 | def compression_type(self): | 8 | def __init__(self, realname, filename, parser, editor, backup): |
| 9 | super(TarStripper, self).__init__(realname, | ||
| 10 | filename, parser, editor, backup) | ||
| 9 | self.compression = '' | 11 | self.compression = '' |
| 12 | self.tarin = tarfile.open(self.filename, 'r' + self.compression) | ||
| 13 | self.folder_list = [] | ||
| 10 | 14 | ||
| 11 | def remove_all(self): | 15 | def remove_all(self): |
| 12 | self.compression_type() | 16 | self.tarout = tarfile.open(self.filename + parser.POSTFIX, |
| 13 | if not tarfile.is_tarfile(self.filename): | ||
| 14 | print('%s is not a valid tar file' % self.filename) | ||
| 15 | sys.exit(1) | ||
| 16 | |||
| 17 | tarin = tarfile.open(self.filename, 'r' + self.compression) | ||
| 18 | tarout = tarfile.open(self.filename + parser.POSTFIX, | ||
| 19 | 'w' + self.compression) | 17 | 'w' + self.compression) |
| 20 | folder_list = [] | 18 | for current_file in self.tarin.getmembers(): |
| 21 | 19 | self.tarin.extract(current_file) | |
| 22 | for current_file in tarin.getmembers(): | ||
| 23 | tarin.extract(current_file) | ||
| 24 | if current_file.type is '0': #is current_file a regular file ? | 20 | if current_file.type is '0': #is current_file a regular file ? |
| 25 | #no backup file | 21 | #no backup file |
| 26 | class_file = mat.create_class_file(current_file.name, False) | 22 | class_file = mat.create_class_file(current_file.name, False) |
| 27 | class_file.remove_all() | 23 | class_file.remove_all() |
| 28 | tarout.add(current_file.name) | 24 | self.tarout.add(current_file.name) |
| 29 | class_file.secure_remove() | 25 | mat.secure_remove(current_file.name) |
| 30 | else: | 26 | else: |
| 31 | folder_list.insert(0, current_file.name) | 27 | self.folder_list.insert(0, current_file.name) |
| 32 | 28 | ||
| 33 | for folder in folder_list: #delete remainings folders | 29 | for folder in self.folder_list: #delete remainings folders |
| 34 | shutil.rmtree(folder) | 30 | shutil.rmtree(folder) |
| 35 | 31 | ||
| 36 | #meta from the tar itself | 32 | #meta from the tar itself |
| 37 | tarout.mtime = None | 33 | self.tarout.mtime = None |
| 38 | 34 | ||
| 39 | tarout.close() | 35 | self.tarout.close() |
| 40 | tarin.close() | 36 | self.tarin.close() |
| 41 | 37 | ||
| 42 | def is_clean(self): | 38 | def is_clean(self): |
| 39 | for current_file in self.tarin.getmembers(): | ||
| 40 | self.tarin.extract(current_file) | ||
| 41 | if current_file.type is '0': #is current_file a regular file ? | ||
| 42 | #no backup file | ||
| 43 | class_file = mat.create_class_file(current_file.name, False) | ||
| 44 | if not class_file.is_clean(): | ||
| 45 | self.folder_list = [] | ||
| 46 | return False | ||
| 47 | mat.secure_remove(current_file.name) | ||
| 48 | else: | ||
| 49 | self.folder_list.insert(0, current_file.name) | ||
| 50 | self.tarin.close() | ||
| 51 | |||
| 52 | for folder in self.folder_list: #delete remainings folders | ||
| 53 | shutil.rmtree(folder) | ||
| 54 | self.folder_list = [] | ||
| 43 | return False | 55 | return False |
| 44 | 56 | ||
| 45 | class GzipStripper(TarStripper): | 57 | class GzipStripper(TarStripper): |
| 46 | def compression_type(self): | 58 | def __init__(self, realname, filename, parser, editor, backup): |
| 59 | super(GzipStripper, self).__init__(realname, | ||
| 60 | filename, parser, editor, backup) | ||
| 47 | self.compression = ':gz' | 61 | self.compression = ':gz' |
| 48 | 62 | ||
| 49 | class Bzip2Stripper(TarStripper): | 63 | class Bzip2Stripper(TarStripper): |
| 50 | def compression_type(self): | 64 | def __init__(self, realname, filename, parser, editor, backup): |
| 65 | super(Bzip2Stripper, self).__init__(realname, | ||
| 66 | filename, parser, editor, backup) | ||
| 51 | self.compression = ':bz2' | 67 | self.compression = ':bz2' |
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | import sys | 7 | import sys |
| 8 | import os | 8 | import os |
| 9 | import subprocess | ||
| 9 | 10 | ||
| 10 | import hachoir_core.cmd_line | 11 | import hachoir_core.cmd_line |
| 11 | import hachoir_parser | 12 | import hachoir_parser |
| @@ -29,6 +30,17 @@ strippers = { | |||
| 29 | hachoir_parser.archive.bzip2_parser.Bzip2Parser: archive.Bzip2Stripper, | 30 | hachoir_parser.archive.bzip2_parser.Bzip2Parser: archive.Bzip2Stripper, |
| 30 | } | 31 | } |
| 31 | 32 | ||
| 33 | def secure_remove(filename): | ||
| 34 | ''' | ||
| 35 | securely remove the file | ||
| 36 | ''' | ||
| 37 | #FIXME : Vulnerable to shell injection ? | ||
| 38 | try: | ||
| 39 | subprocess.call('shred --remove %s' % filename, shell=True) | ||
| 40 | except: | ||
| 41 | print('Unable to remove %s' % filename) | ||
| 42 | |||
| 43 | |||
| 32 | def is_secure(filename): | 44 | def is_secure(filename): |
| 33 | ''' | 45 | ''' |
| 34 | Prevent shell injection | 46 | Prevent shell injection |
diff --git a/lib/parser.py b/lib/parser.py index c7e189e..6b899f3 100644 --- a/lib/parser.py +++ b/lib/parser.py | |||
| @@ -8,10 +8,11 @@ import hachoir_editor | |||
| 8 | import sys | 8 | import sys |
| 9 | import os | 9 | import os |
| 10 | import subprocess | 10 | import subprocess |
| 11 | import mat | ||
| 11 | 12 | ||
| 12 | POSTFIX = ".cleaned" | 13 | POSTFIX = ".cleaned" |
| 13 | 14 | ||
| 14 | class Generic_parser(): | 15 | class Generic_parser(object): |
| 15 | def __init__(self, realname, filename, parser, editor, backup): | 16 | def __init__(self, realname, filename, parser, editor, backup): |
| 16 | self.filename = filename | 17 | self.filename = filename |
| 17 | self.realname = realname | 18 | self.realname = realname |
| @@ -19,16 +20,6 @@ class Generic_parser(): | |||
| 19 | self.editor = editor | 20 | self.editor = editor |
| 20 | self.backup = backup | 21 | self.backup = backup |
| 21 | 22 | ||
| 22 | def secure_remove(self): | ||
| 23 | ''' | ||
| 24 | securely remove the file | ||
| 25 | ''' | ||
| 26 | #FIXME : Vulnerable to shell injection ? | ||
| 27 | try: | ||
| 28 | subprocess.call('shred --remove %s' % self.filename, shell=True) | ||
| 29 | except: | ||
| 30 | print('Unable to remove %s' % self.filename) | ||
| 31 | |||
| 32 | def is_clean(self): | 23 | def is_clean(self): |
| 33 | ''' | 24 | ''' |
| 34 | Check if the file is clean from harmful metadatas | 25 | Check if the file is clean from harmful metadatas |
| @@ -47,7 +38,7 @@ class Generic_parser(): | |||
| 47 | self._remove(field) | 38 | self._remove(field) |
| 48 | hachoir_core.field.writeIntoFile(self.editor, self.filename + POSTFIX) | 39 | hachoir_core.field.writeIntoFile(self.editor, self.filename + POSTFIX) |
| 49 | if self.backup is False: | 40 | if self.backup is False: |
| 50 | self.secure_remove() #remove the old file | 41 | mat.secure_remove(self.filename) #remove the old file |
| 51 | os.rename(self.filename+ POSTFIX, self.filename)#rename the new | 42 | os.rename(self.filename+ POSTFIX, self.filename)#rename the new |
| 52 | 43 | ||
| 53 | def remove_all_ugly(self): | 44 | def remove_all_ugly(self): |
