diff --git a/fail2ban/client/fail2banclient.py b/fail2ban/client/fail2banclient.py index 73abacb2..7c90ca40 100755 --- a/fail2ban/client/fail2banclient.py +++ b/fail2ban/client/fail2banclient.py @@ -186,8 +186,7 @@ class Fail2banClient(Fail2banCmdLine, Thread): logSys.error("Fail2ban seems to be in unexpected state (not running but the socket exists)") return None - stream.append(['server-status']) - return stream + return [["server-stream", stream], ['server-status']] ## def __startServer(self, background=True): diff --git a/fail2ban/server/server.py b/fail2ban/server/server.py index d13698f3..14013290 100644 --- a/fail2ban/server/server.py +++ b/fail2ban/server/server.py @@ -491,8 +491,6 @@ class Server: ifexists |= (name is None) for jail in jails: cnt += jail.actions.removeBannedIP(value, ifexists=ifexists) - if value and not cnt: - logSys.info("%s is not banned", value) return cnt def getBanTime(self, name): diff --git a/fail2ban/server/transmitter.py b/fail2ban/server/transmitter.py index 2a3b0c81..a267c4b0 100644 --- a/fail2ban/server/transmitter.py +++ b/fail2ban/server/transmitter.py @@ -43,6 +43,7 @@ class Transmitter: def __init__(self, server): self.__server = server + self.__quiet = 0 ## # Proceeds a command. @@ -69,9 +70,10 @@ class Transmitter: # def __commandHandler(self, command): - if command[0] == "ping": + name = command[0] + if name == "ping": return "pong" - elif command[0] == "add": + elif name == "add": name = command[1] if name == "--all": raise Exception("Reserved name %r" % (name,)) @@ -81,11 +83,15 @@ class Transmitter: backend = "auto" self.__server.addJail(name, backend) return name - elif command[0] == "start": + elif name == "multi-set": + return self.__commandSet(command[1:], True) + elif name == "set": + return self.__commandSet(command[1:]) + elif name == "start": name = command[1] self.__server.startJail(name) return None - elif command[0] == "stop": + elif name == "stop": if len(command) == 1: self.__server.quit() elif command[1] == "--all": @@ -94,44 +100,50 @@ class Transmitter: name = command[1] self.__server.stopJail(name) return None - elif command[0] == "reload": + elif name == "reload": opts = command[1:3] + self.__quiet = 1 try: self.__server.reloadJails(*opts, begin=True) for cmd in command[3]: self.__commandHandler(cmd) finally: + self.__quiet = 0 self.__server.reloadJails(*opts, begin=False) return 'OK' - elif len(command) >= 2 and command[0] == "unban": + elif name == "unban" and len(command) >= 2: # unban in all jails: value = command[1:] # if all ips: if len(value) == 1 and value[0] == "--all": return self.__server.setUnbanIP() return self.__server.setUnbanIP(None, value) - elif command[0] == "echo": + elif name == "echo": return command[1:] - elif command[0] == "server-status": + elif name == "server-status": logSys.debug("Status: ready") return "Server ready" - elif command[0] == "sleep": + elif name == "server-stream": + self.__quiet = 1 + try: + for cmd in command[1]: + self.__commandHandler(cmd) + finally: + self.__quiet = 0 + return None + elif name == "sleep": value = command[1] time.sleep(float(value)) return None - elif command[0] == "flushlogs": + elif name == "flushlogs": return self.__server.flushLogs() - elif command[0] == "multi-set": - return self.__commandSet(command[1:], True) - elif command[0] == "set": - return self.__commandSet(command[1:]) - elif command[0] == "get": + elif name == "get": return self.__commandGet(command[1:]) - elif command[0] == "status": + elif name == "status": return self.status(command[1:]) - elif command[0] == "version": + elif name == "version": return version.version - elif command[0] == "config-error": + elif name == "config-error": logSys.error(command[1]) return None raise Exception("Invalid command") @@ -142,16 +154,19 @@ class Transmitter: if name == "loglevel": value = command[1] self.__server.setLogLevel(value) + if self.__quiet: return return self.__server.getLogLevel() elif name == "logtarget": value = command[1] if self.__server.setLogTarget(value): + if self.__quiet: return return self.__server.getLogTarget() else: raise Exception("Failed to change log target") elif name == "syslogsocket": value = command[1] if self.__server.setSyslogSocket(value): + if self.__quiet: return return self.__server.getSyslogSocket() else: raise Exception("Failed to change syslog socket") @@ -162,6 +177,7 @@ class Transmitter: if db is None: return None else: + if self.__quiet: return return db.filename elif name == "dbpurgeage": db = self.__server.getDatabase() @@ -170,6 +186,7 @@ class Transmitter: return None else: db.purgeage = command[1] + if self.__quiet: return return db.purgeage # Jail elif command[1] == "idle": @@ -179,27 +196,33 @@ class Transmitter: self.__server.setIdleJail(name, False) else: raise Exception("Invalid idle option, must be 'on' or 'off'") + if self.__quiet: return return self.__server.getIdleJail(name) # Filter elif command[1] == "ignoreself": value = command[2] self.__server.setIgnoreSelf(name, value) + if self.__quiet: return return self.__server.getIgnoreSelf(name) elif command[1] == "addignoreip": for value in command[2:]: self.__server.addIgnoreIP(name, value) + if self.__quiet: return return self.__server.getIgnoreIP(name) elif command[1] == "delignoreip": value = command[2] self.__server.delIgnoreIP(name, value) + if self.__quiet: return return self.__server.getIgnoreIP(name) elif command[1] == "ignorecommand": value = command[2] self.__server.setIgnoreCommand(name, value) + if self.__quiet: return return self.__server.getIgnoreCommand(name) elif command[1] == "ignorecache": value = command[2] self.__server.setIgnoreCache(name, value) + if self.__quiet: return return self.__server.getIgnoreCache(name) elif command[1] == "addlogpath": value = command[2] @@ -212,78 +235,96 @@ class Transmitter: elif len(command) > 4: raise ValueError("Only one file can be added at a time") self.__server.addLogPath(name, value, tail) + if self.__quiet: return return self.__server.getLogPath(name) elif command[1] == "dellogpath": value = command[2] self.__server.delLogPath(name, value) + if self.__quiet: return return self.__server.getLogPath(name) elif command[1] == "logencoding": value = command[2] self.__server.setLogEncoding(name, value) + if self.__quiet: return return self.__server.getLogEncoding(name) elif command[1] == "addjournalmatch": # pragma: systemd no cover value = command[2:] self.__server.addJournalMatch(name, value) + if self.__quiet: return return self.__server.getJournalMatch(name) elif command[1] == "deljournalmatch": # pragma: systemd no cover value = command[2:] self.__server.delJournalMatch(name, value) + if self.__quiet: return return self.__server.getJournalMatch(name) elif command[1] == "prefregex": value = command[2] self.__server.setPrefRegex(name, value) + if self.__quiet: return return self.__server.getPrefRegex(name) elif command[1] == "addfailregex": value = command[2] self.__server.addFailRegex(name, value, multiple=multiple) if multiple: return True + if self.__quiet: return return self.__server.getFailRegex(name) elif command[1] == "delfailregex": value = int(command[2]) self.__server.delFailRegex(name, value) + if self.__quiet: return return self.__server.getFailRegex(name) elif command[1] == "addignoreregex": value = command[2] self.__server.addIgnoreRegex(name, value, multiple=multiple) if multiple: return True + if self.__quiet: return return self.__server.getIgnoreRegex(name) elif command[1] == "delignoreregex": value = int(command[2]) self.__server.delIgnoreRegex(name, value) + if self.__quiet: return return self.__server.getIgnoreRegex(name) elif command[1] == "usedns": value = command[2] self.__server.setUseDns(name, value) + if self.__quiet: return return self.__server.getUseDns(name) elif command[1] == "findtime": value = command[2] self.__server.setFindTime(name, value) + if self.__quiet: return return self.__server.getFindTime(name) elif command[1] == "datepattern": value = command[2] self.__server.setDatePattern(name, value) + if self.__quiet: return return self.__server.getDatePattern(name) elif command[1] == "logtimezone": value = command[2] self.__server.setLogTimeZone(name, value) + if self.__quiet: return return self.__server.getLogTimeZone(name) elif command[1] == "maxretry": value = command[2] self.__server.setMaxRetry(name, int(value)) + if self.__quiet: return return self.__server.getMaxRetry(name) elif command[1] == "maxlines": value = command[2] self.__server.setMaxLines(name, int(value)) + if self.__quiet: return return self.__server.getMaxLines(name) # command elif command[1] == "bantime": value = command[2] self.__server.setBanTime(name, value) + if self.__quiet: return return self.__server.getBanTime(name) elif command[1] == "attempt": value = command[2:] + if self.__quiet: return return self.__server.addAttemptIP(name, *value) elif command[1] == "banip": value = command[2:] @@ -301,6 +342,7 @@ class Transmitter: if len(command) > 3: args.extend([command[3], json.loads(command[4])]) self.__server.addAction(name, *args) + if self.__quiet: return return args[0] elif command[1] == "delaction": value = command[2] @@ -324,10 +366,12 @@ class Transmitter: actionkey = command[3] if callable(getattr(action, actionkey, None)): actionvalue = json.loads(command[4]) if len(command)>4 else {} + if self.__quiet: return return getattr(action, actionkey)(**actionvalue) else: actionvalue = command[4] setattr(action, actionkey, actionvalue) + if self.__quiet: return return getattr(action, actionkey) raise Exception("Invalid command %r (no set action or not yet implemented)" % (command[1],)) diff --git a/fail2ban/tests/clientreadertestcase.py b/fail2ban/tests/clientreadertestcase.py index 9854417d..29629a53 100644 --- a/fail2ban/tests/clientreadertestcase.py +++ b/fail2ban/tests/clientreadertestcase.py @@ -878,9 +878,9 @@ class JailsReaderTest(LogCaptureTestCase): % (option, commands)) # Set up of logging should come first - self.assertEqual(find_set('syslogsocket'), 0) - self.assertEqual(find_set('loglevel'), 1) - self.assertEqual(find_set('logtarget'), 2) + self.assertTrue( + find_set('syslogsocket') < find_set('loglevel') < find_set('logtarget') + ) # then dbfile should be before dbpurgeage self.assertTrue(find_set('dbpurgeage') > find_set('dbfile')) @@ -888,7 +888,7 @@ class JailsReaderTest(LogCaptureTestCase): # server self.assertSortedEqual(commands, [['set', 'dbfile', - '/var/lib/fail2ban/fail2ban.sqlite3'], + '/var/lib/fail2ban/fail2ban.sqlite3'], ['set', 'dbpurgeage', '1d'], ['set', 'loglevel', "INFO"], ['set', 'logtarget', '/var/log/fail2ban.log'],