Browse Source

Implement support to detect unwanted extensions inside RAR archives.

unwanted_extensions = .exe, .bla
action_on_unwanted_extensions = 1
pull/175/head
shypike 11 years ago
parent
commit
6b1f9c0a50
  1. 2
      SABnzbd.py
  2. 14
      interfaces/Config/templates/config_switches.tmpl
  3. 39
      sabnzbd/assembler.py
  4. 3
      sabnzbd/cfg.py
  5. 6
      sabnzbd/interface.py
  6. 8
      sabnzbd/nzbstuff.py
  7. 4
      sabnzbd/skintext.py

2
SABnzbd.py

@ -1356,6 +1356,8 @@ def main():
sabnzbd.WEB_COLOR2 = CheckColor(sabnzbd.cfg.web_color2(), web_dir2)
sabnzbd.cfg.web_color2.set(sabnzbd.WEB_COLOR2)
logging.debug('Unwanted extensions are ... %s',sabnzbd.cfg.unwanted_extensions())
if fork and not sabnzbd.WIN32:
daemonize()

14
interfaces/Config/templates/config_switches.tmpl

@ -126,6 +126,20 @@
<span class="desc">$T('explain-pause_on_pwrar')</span>
</div>
<div class="field-pair alt">
<label class="config" for="action_on_unwanted_extensions">$T('opt-action_on_unwanted_extensions')</label>
<select name="action_on_unwanted_extensions" id="action_on_unwanted_extensions">
<option value="0" <!--#if int($action_on_unwanted_extensions) == 0 then 'selected="selected" class="selected"' else ""#--> >$T('nodupes-off')</option>
<option value="1" <!--#if int($action_on_unwanted_extensions) == 1 then 'selected="selected" class="selected"' else ""#--> >$T('nodupes-pause')</option>
<option value="2" <!--#if int($action_on_unwanted_extensions) == 2 then 'selected="selected" class="selected"' else ""#--> >$T('abort')</option>
</select>
<span class="desc">$T('explain-action_on_unwanted_extensions')</span>
</div>
<div class="field-pair">
<label class="config" for="unwanted_extensions">$T('opt-unwanted_extensions')</label>
<input type="text" name="unwanted_extensions" id="unwanted_extensions" value="$unwanted_extensions" size="50"/>
<span class="desc">$T('explain-unwanted_extensions')</span>
</div>
<div class="field-pair alt">
<label class="config" for="top_only">$T('opt-top_only')</label>
<input type="checkbox" name="top_only" id="top_only" value="1" <!--#if int($top_only) > 0 then 'checked="checked"' else ""#--> />
<span class="desc">$T('explain-top_only')</span>

39
sabnzbd/assembler.py

@ -121,6 +121,21 @@ class Assembler(Thread):
nzo.fail_msg = T('Aborted, encryption detected')
import sabnzbd.nzbqueue
sabnzbd.nzbqueue.NzbQueue.do.end_job(nzo)
unwanted = rar_contains_unwanted_file(nzo, filepath)
if unwanted:
logging.warning(Ta('WARNING: In "%s" unwanted extension in RAR file. Unwanted file is %s '), latin1(nzo.final_name), unwanted)
if cfg.action_on_unwanted_extensions() == 1:
logging.debug('Unwanted extension ... pausing')
nzo.unwanted_ext = True
nzo.pause()
if cfg.action_on_unwanted_extensions() == 2:
logging.debug('Unwanted extension ... aborting')
nzo.fail_msg = T('Aborted, unwanted extension detected')
import sabnzbd.nzbqueue
sabnzbd.nzbqueue.NzbQueue.do.end_job(nzo)
nzf.completed = True
else:
sabnzbd.nzbqueue.NzbQueue.do.remove(nzo.nzo_id, add_to_history=False, cleanup=False)
@ -322,3 +337,27 @@ def check_encrypted_rar(nzo, filepath):
logging.debug('RAR file %s cannot be inspected', filepath)
return encrypted
def rar_contains_unwanted_file(nzo, filepath):
# checks for unwanted extensions in the rar file 'filepath'
# ... unwanted extensions are defined in global variable cfg.unwanted_extensions()
# returns False if no unwanted extensions are found in the rar file
# returns name of file if unwanted extension is found in the rar file
unwanted = False
if is_rarfile(filepath):
#logging.debug('rar file to check: %s',filepath)
#logging.debug('unwanted extensions are: %s', cfg.unwanted_extensions())
try:
zf = RarFile(filepath, all_names=True)
#logging.debug('files in rar file: %s', zf.namelist())
for somefile in zf.namelist() :
logging.debug('file in rar file: %s', somefile)
if os.path.splitext(somefile)[1].replace('.', '').lower() in cfg.unwanted_extensions():
logging.debug('Unwanted file %s', somefile)
unwanted = True
zf.close()
except:
logging.debug('RAR file %s cannot be inspected.', filepath)
return unwanted

3
sabnzbd/cfg.py

@ -199,6 +199,9 @@ web_color2 = OptionStr('misc', 'web_color2')
cleanup_list = OptionList('misc', 'cleanup_list')
warned_old_queue = OptionBool('misc', 'warned_old_queue9', False)
unwanted_extensions = OptionList('misc', 'unwanted_extensions')
action_on_unwanted_extensions = OptionNumber('misc', 'action_on_unwanted_extensions', 0)
log_web = OptionBool('logging', 'enable_cherrypy_logging', False)
log_dir = OptionDir('misc', 'log_dir', 'logs', validation=validate_notempty)
log_level = OptionNumber('logging', 'log_level', 1, -1, 2)

6
sabnzbd/interface.py

@ -1178,7 +1178,8 @@ SWITCH_LIST = \
'ssl_type', 'pre_script', 'pause_on_pwrar', 'ampm', 'sfv_check', 'folder_rename',
'unpack_check', 'quota_size', 'quota_day', 'quota_resume', 'quota_period',
'pre_check', 'max_art_tries', 'max_art_opt', 'fail_hopeless', 'enable_7zip', 'enable_all_par',
'enable_recursive', 'no_series_dupes'
'enable_recursive', 'no_series_dupes',
'unwanted_extensions', 'action_on_unwanted_extensions'
)
#------------------------------------------------------------------------------
@ -1205,6 +1206,7 @@ class ConfigSwitches(object):
for kw in SWITCH_LIST:
conf[kw] = config.get_config('misc', kw)()
conf['unwanted_extensions'] = cfg.unwanted_extensions.get_string()
conf['script_list'] = list_scripts() or ['None']
conf['have_ampm'] = HAVE_AMPM
@ -1221,6 +1223,8 @@ class ConfigSwitches(object):
for kw in SWITCH_LIST:
item = config.get_config('misc', kw)
value = platform_encode(kwargs.get(kw))
if kw == 'unwanted_extensions' and value:
value = value.lower().replace('.', '')
msg = item.set(value)
if msg:
return badParameterResponse(msg)

8
sabnzbd/nzbstuff.py

@ -473,7 +473,7 @@ NzbObjectSaver = (
'futuretype', 'deleted', 'parsed', 'action_line', 'unpack_info', 'fail_msg', 'nzo_info',
'custom_name', 'password', 'next_save', 'save_timeout', 'encrypted',
'duplicate', 'oversized', 'create_group_folder', 'precheck', 'incomplete', 'reuse', 'meta',
'md5sum', 'servercount'
'md5sum', 'servercount', 'unwanted_ext'
)
class NzbObject(TryList):
@ -565,6 +565,7 @@ class NzbObject(TryList):
self.oversized = False
self.precheck = False
self.incomplete = False
self.unwanted_ext = False
self.reuse = reuse
if self.status == Status.QUEUED and not reuse:
self.precheck = cfg.pre_check()
@ -989,6 +990,8 @@ class NzbObject(TryList):
prefix += Ta('TOO LARGE') + ' / ' #: Queue indicator for oversized job
if self.incomplete and self.status == 'Paused':
prefix += Ta('INCOMPLETE') + ' / ' #: Queue indicator for incomplete NZB
if self.unwanted_ext and self.status == 'Paused':
prefix += Ta('UNWANTED') + ' / ' #: Queue indicator for unwanted extensions
if isinstance(self.wait, float):
dif = int(self.wait - time.time() + 0.5)
if dif > 0:
@ -1026,10 +1029,11 @@ class NzbObject(TryList):
if self.encrypted:
# If user resumes after encryption warning, no more auto-pauses
self.encrypted = 2
# If user resumes after warning, reset duplicate/oversized/incomplete indicators
# If user resumes after warning, reset duplicate/oversized/incomplete/unwanted indicators
self.duplicate = False
self.oversized = False
self.incomplete = False
self.unwanted_ext = False
def add_parfile(self, parfile):
if parfile not in self.files:

4
sabnzbd/skintext.py

@ -422,6 +422,10 @@ SKIN_TEXT = {
'nodupes-ignore' : TT('Discard'), #: Three way switch for duplicates
'nodupes-pause' : TT('Pause'), #: Three way switch for duplicates
'abort' : TT('Abort'), #: Three way switch for encrypted posts
'opt-action_on_unwanted_extensions' : TT('Action when unwanted extension detected'),
'explain-action_on_unwanted_extensions' : TT('Action when an unwanted extension is detected in RAR files'),
'opt-unwanted_extensions' : TT('Unwanted extensions'),
'explain-unwanted_extensions' : TT('List all unwanted extensions'),
'opt-sfv_check' : TT('Enable SFV-based checks'),
'explain-sfv_check' : TT('Do an extra verification based on SFV files.'),
'opt-unpack_check' : TT('Check result of unpacking'),

Loading…
Cancel
Save