m2crypt update
This commit is contained in:
@@ -1,8 +1,17 @@
|
||||
# Copyright 2013 Johannes Fuermann <johannes at fuermann.cc>
|
||||
# Copyright 2013 Manuel Munz <manu at somakoma.de>
|
||||
#
|
||||
# This file is part of fail2ban-p2p.
|
||||
#
|
||||
# Licensed under the GNU GENERAL PUBLIC LICENSE Version 3. For details
|
||||
# see the file COPYING or http://www.gnu.org/licenses/gpl-3.0.en.html.
|
||||
|
||||
import json
|
||||
|
||||
import M2Crypto
|
||||
from M2Crypto import EVP
|
||||
|
||||
import config
|
||||
import crypto
|
||||
import log
|
||||
import util
|
||||
import version
|
||||
@@ -11,7 +20,9 @@ logger = log.initialize_logging("fail2ban-p2p." + __name__)
|
||||
|
||||
|
||||
class Command:
|
||||
"""Handle command objects."""
|
||||
"""
|
||||
Handle command objects.
|
||||
"""
|
||||
|
||||
msgType = None
|
||||
parameter = ()
|
||||
@@ -26,9 +37,12 @@ class Command:
|
||||
self.hops = hops if hops is not None else []
|
||||
|
||||
def __string__(self):
|
||||
return f"Command (msgType = {self.msgType}, ...)"
|
||||
return "Command (msgType = " + str(self.msgType) + ", ...)"
|
||||
|
||||
def toSerializableDict(self):
|
||||
"""
|
||||
Returns a recursively sorted dictionary.
|
||||
"""
|
||||
unordered_dict = {
|
||||
"msgType": self.msgType,
|
||||
"parameter": self.parameter,
|
||||
@@ -37,6 +51,9 @@ class Command:
|
||||
return util.sort_recursive(unordered_dict)
|
||||
|
||||
def toProtocolMessage(self):
|
||||
"""
|
||||
Create a JSON-encoded protocol message.
|
||||
"""
|
||||
serializable_dict = self.toSerializableDict()
|
||||
signed_message = json.dumps(serializable_dict)
|
||||
signature = self.sign(signed_message)
|
||||
@@ -48,10 +65,19 @@ class Command:
|
||||
return json.dumps(signed_dict)
|
||||
|
||||
def sign(self, text):
|
||||
"""
|
||||
Compute signature for a message.
|
||||
|
||||
Args:
|
||||
text (str): The JSON encoded message text.
|
||||
|
||||
Returns:
|
||||
str: Hex-encoded signature.
|
||||
"""
|
||||
logger.debug("signing outgoing message")
|
||||
c = config.Config()
|
||||
|
||||
signer = M2Crypto.EVP.load_key(c.privkey)
|
||||
signer = EVP.load_key(c.privkey)
|
||||
signer.sign_init()
|
||||
signer.sign_update(text.encode("utf-8"))
|
||||
string_signature = signer.sign_final().hex()
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
import os
|
||||
import sys
|
||||
# Copyright 2013 Johannes Fuermann <johannes at fuermann.cc>
|
||||
# Copyright 2013 Manuel Munz <manu at somakoma.de>
|
||||
#
|
||||
# This file is part of fail2ban-p2p.
|
||||
#
|
||||
# Licensed under the GNU GENERAL PUBLIC LICENSE Version 3. For details
|
||||
# see the file COPYING or http://www.gnu.org/licenses/gpl-3.0.en.html.
|
||||
|
||||
import M2Crypto
|
||||
import os
|
||||
|
||||
from M2Crypto import Rand, RSA
|
||||
|
||||
import config
|
||||
import log
|
||||
@@ -12,14 +19,16 @@ logger = log.initialize_logging("fail2ban-p2p." + __name__)
|
||||
|
||||
def create_keys():
|
||||
"""Create private/public keypair (RSA 1024 bit)."""
|
||||
|
||||
if os.path.isfile(c.privkey) or os.path.isfile(c.pubkey):
|
||||
print("A keypair for this node already exists.")
|
||||
ask = input('Do you really want to create a new one? [y/N] ')
|
||||
ask = input("Do you really want to create a new one? [y/N] ")
|
||||
if ask != "y":
|
||||
return
|
||||
M2Crypto.Rand.rand_seed(os.urandom(1024))
|
||||
|
||||
Rand.rand_seed(os.urandom(1024))
|
||||
logger.info("Generating a 1024 bit private/public key pair...")
|
||||
keypair = M2Crypto.RSA.gen_key(1024, 65537)
|
||||
keypair = RSA.gen_key(1024, 65537)
|
||||
try:
|
||||
keypair.save_key(c.privkey, None)
|
||||
os.chmod(c.privkey, 0o400)
|
||||
@@ -28,4 +37,4 @@ def create_keys():
|
||||
logger.debug("Public key was saved to %s", c.pubkey)
|
||||
except IOError as e:
|
||||
logger.error("Could not save the keypair, check permissions! %s", e)
|
||||
sys.exit(1)
|
||||
raise
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
# Copyright 2013 Johannes Fuermann <johannes at fuermann.cc>
|
||||
# Copyright 2013 Manuel Munz <manu at somakoma.de>
|
||||
#
|
||||
# This file is part of fail2ban-p2p.
|
||||
#
|
||||
# Licensed under the GNU GENERAL PUBLIC LICENSE Version 3. For details
|
||||
# see the file COPYING or http://www.gnu.org/licenses/gpl-3.0.en.html.
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
@@ -7,7 +15,7 @@ import threading
|
||||
from select import select
|
||||
from time import time
|
||||
|
||||
import M2Crypto
|
||||
from M2Crypto import EVP, RSA
|
||||
|
||||
import config
|
||||
import crypto
|
||||
@@ -47,22 +55,26 @@ class Node:
|
||||
logger.debug("running version: %s", version.version)
|
||||
try:
|
||||
sockets = []
|
||||
for a in self.addresses:
|
||||
for address in self.addresses:
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.bind((a, int(self.port)))
|
||||
s.listen(1)
|
||||
sockets.append(s)
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.bind((address, int(self.port)))
|
||||
sock.listen(1)
|
||||
sockets.append(sock)
|
||||
except Exception as e:
|
||||
logger.warning("Couldn't bind to address %s (Reason: %s)", a, e)
|
||||
logger.warning("Couldn't bind to address %s (Reason: %s)", address, e)
|
||||
|
||||
while self.running:
|
||||
readable, _, _ = select(sockets, [], [])
|
||||
for sock in readable:
|
||||
client_socket, address = sock.accept()
|
||||
logger.debug("connection from %s", address[0])
|
||||
t = threading.Thread(target=server.serve, args=(self, client_socket, address), daemon=True)
|
||||
t.start()
|
||||
thread = threading.Thread(
|
||||
target=server.serve,
|
||||
args=(self, client_socket, address),
|
||||
daemon=True,
|
||||
)
|
||||
thread.start()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
@@ -73,84 +85,101 @@ class Node:
|
||||
def processMessages(self):
|
||||
self.lock.acquire()
|
||||
logger.debug("begin message handling")
|
||||
for c in self.messageQueue:
|
||||
if self.uid not in c.hops:
|
||||
if c.hops[0] == 'local':
|
||||
del c.hops[0]
|
||||
c.hops.append(self.uid)
|
||||
if c.msgType == 1:
|
||||
if 'Trustlevel' not in c.parameter:
|
||||
logger.warning("Incoming Message has no Trustlevel, I won't trust it. Never.")
|
||||
c.parameter['Trustlevel'] = 0
|
||||
for command in self.messageQueue:
|
||||
if self.uid not in command.hops:
|
||||
if command.hops[0] == "local":
|
||||
del command.hops[0]
|
||||
command.hops.append(self.uid)
|
||||
if command.msgType == 1:
|
||||
if "Trustlevel" not in command.parameter:
|
||||
logger.warning("Incoming message has no Trustlevel, I won't trust it.")
|
||||
command.parameter["Trustlevel"] = 0
|
||||
|
||||
if c.sender != "local":
|
||||
c.parameter['Trustlevel'] = int((float(c.sender.trustLevel) / 100 * float(c.parameter['Trustlevel']) / 100) * 100)
|
||||
logger.debug("Message now has trust level %s", c.parameter['Trustlevel'])
|
||||
if command.sender != "local":
|
||||
command.parameter["Trustlevel"] = int(
|
||||
(float(command.sender.trustLevel) / 100.0)
|
||||
* (float(command.parameter["Trustlevel"]) / 100.0)
|
||||
* 100
|
||||
)
|
||||
logger.debug("Message now has trust level %s", command.parameter["Trustlevel"])
|
||||
|
||||
relay = True
|
||||
ipindb = False
|
||||
if len(self.banList) > 0:
|
||||
if self.banList:
|
||||
for ban in self.banList:
|
||||
if ban['AttackerIP'] == c.parameter['AttackerIP']:
|
||||
if ban["AttackerIP"] == command.parameter["AttackerIP"]:
|
||||
ipindb = True
|
||||
logger.debug("IP already in database.")
|
||||
|
||||
if int(ban['Timestamp']) != int(c.parameter['Timestamp']):
|
||||
if c.hops[0] not in ban['Hops']:
|
||||
trustold = ban['Trustlevel']
|
||||
trustnew = int(trustold) + int(c.parameter['Trustlevel'])
|
||||
if int(ban["Timestamp"]) != int(command.parameter["Timestamp"]):
|
||||
if command.hops[0] not in ban["Hops"]:
|
||||
trustold = ban["Trustlevel"]
|
||||
trustnew = int(trustold) + int(command.parameter["Trustlevel"])
|
||||
if trustnew > 100:
|
||||
trustnew = 100
|
||||
ban['Trustlevel'] = trustnew
|
||||
ban['Hops'].append(c.hops[0])
|
||||
ban["Trustlevel"] = trustnew
|
||||
ban["Hops"].append(command.hops[0])
|
||||
logger.debug("TrustLevel for this IP is now %s", trustnew)
|
||||
c.parameter['Trustlevel'] = trustnew
|
||||
command.parameter["Trustlevel"] = trustnew
|
||||
else:
|
||||
relay = False
|
||||
logger.debug("There is already an entry from %s in our database, do nothing with this message.", c.hops[0])
|
||||
logger.debug(
|
||||
"There is already an entry from %s in our database, do nothing with this message.",
|
||||
command.hops[0],
|
||||
)
|
||||
else:
|
||||
relay = False
|
||||
logger.debug("Timestamp has not changed, do nothing with this message")
|
||||
|
||||
if not ipindb:
|
||||
self.banList.append({
|
||||
'AttackerIP': c.parameter['AttackerIP'],
|
||||
'Timestamp': c.parameter['Timestamp'],
|
||||
'BanTime': self.banTime,
|
||||
'Trustlevel': c.parameter['Trustlevel'],
|
||||
'Hops': [c.hops[0]],
|
||||
})
|
||||
logger.debug("Added %s to internal banlist", c.parameter['AttackerIP'])
|
||||
self.banList.append(
|
||||
{
|
||||
"AttackerIP": command.parameter["AttackerIP"],
|
||||
"Timestamp": command.parameter["Timestamp"],
|
||||
"BanTime": self.banTime,
|
||||
"Trustlevel": command.parameter["Trustlevel"],
|
||||
"Hops": [command.hops[0]],
|
||||
}
|
||||
)
|
||||
logger.debug("Added %s to internal banlist", command.parameter["AttackerIP"])
|
||||
|
||||
if relay:
|
||||
if int(c.parameter['Trustlevel']) >= int(config.Config().threshold):
|
||||
logger.ban(c.parameter['AttackerIP'])
|
||||
if int(command.parameter["Trustlevel"]) >= int(config.Config().threshold):
|
||||
logger.ban(command.parameter["AttackerIP"])
|
||||
else:
|
||||
logger.debug("Message's trust level (%s) was below our threshold (%s)", c.parameter['Trustlevel'], config.Config().threshold)
|
||||
logger.debug(
|
||||
"Message's trust level (%s) was below our threshold (%s)",
|
||||
command.parameter["Trustlevel"],
|
||||
config.Config().threshold,
|
||||
)
|
||||
|
||||
for peer in self.friends:
|
||||
logger.debug("sending message to all friends")
|
||||
peer.sendCommand(c)
|
||||
peer.sendCommand(command)
|
||||
|
||||
if c.msgType == 3:
|
||||
sender_uid = c.hops[0]
|
||||
if command.msgType == 3:
|
||||
sender_uid = command.hops[0]
|
||||
for peer in self.friends:
|
||||
logger.debug("Comparing senders uid (%s) with one of our friends uid (%s)", sender_uid, peer.uid)
|
||||
logger.debug(
|
||||
"Comparing senders uid (%s) with one of our friends uid (%s)",
|
||||
sender_uid,
|
||||
peer.uid,
|
||||
)
|
||||
if peer.uid == sender_uid:
|
||||
logger.debug("The message is from our friend %s (uid: %s)", peer.name, peer.uid)
|
||||
logger.debug("Dumping banlist to %s (uid: %s)", peer.name, peer.uid)
|
||||
if len(self.banList) > 0:
|
||||
if self.banList:
|
||||
for ban in self.banList:
|
||||
cmd = Command()
|
||||
cmd.msgType = 1
|
||||
cmd.hops = [self.uid]
|
||||
cmd.protocolVersion = version.protocolVersion
|
||||
cmd.parameter = {
|
||||
"AttackerIP": ban['AttackerIP'],
|
||||
"Timestamp": ban['Timestamp'],
|
||||
"Trustlevel": ban['Trustlevel'],
|
||||
dump_cmd = Command()
|
||||
dump_cmd.msgType = 1
|
||||
dump_cmd.hops = [self.uid]
|
||||
dump_cmd.protocolVersion = version.protocolVersion
|
||||
dump_cmd.parameter = {
|
||||
"AttackerIP": ban["AttackerIP"],
|
||||
"Timestamp": ban["Timestamp"],
|
||||
"Trustlevel": ban["Trustlevel"],
|
||||
}
|
||||
peer.sendCommand(cmd)
|
||||
peer.sendCommand(dump_cmd)
|
||||
else:
|
||||
logger.debug("I know this message, I won't resend it to prevent loops")
|
||||
logger.debug("end message handling")
|
||||
@@ -170,9 +199,12 @@ class Node:
|
||||
self.configPath = c.configPath
|
||||
self.configFile = c.configFile
|
||||
|
||||
with open(c.pubkey, 'r', encoding='utf-8') as fh:
|
||||
pubkey_file = fh.read()
|
||||
pubkey = re.findall("-----BEGIN PUBLIC KEY-----(.*?)-----END PUBLIC KEY-----", pubkey_file, re.DOTALL | re.M)[0]
|
||||
pubkey_file = open(c.pubkey, "r", encoding="utf-8").read()
|
||||
pubkey = re.findall(
|
||||
"-----BEGIN PUBLIC KEY-----(.*?)-----END PUBLIC KEY-----",
|
||||
pubkey_file,
|
||||
re.DOTALL | re.M,
|
||||
)[0]
|
||||
|
||||
logger.debug("our own pubkey is: %s", pubkey)
|
||||
|
||||
@@ -186,28 +218,36 @@ class Node:
|
||||
|
||||
def getFriends(self):
|
||||
error = False
|
||||
friendPath = os.path.join(self.configPath, 'friends')
|
||||
friends = [f for f in os.listdir(friendPath) if os.path.isfile(os.path.join(friendPath, f))]
|
||||
if not friends:
|
||||
friendPath = os.path.join(self.configPath, "friends")
|
||||
friend_files = [f for f in os.listdir(friendPath) if os.path.isfile(os.path.join(friendPath, f))]
|
||||
if not friend_files:
|
||||
logger.warning("No friends found. In order to properly use fail2ban-p2p add at least one friend.")
|
||||
|
||||
for file in friends:
|
||||
with open(os.path.join(friendPath, file), 'r', encoding='utf-8') as f:
|
||||
friendinfo = f.read()
|
||||
for file in friend_files:
|
||||
with open(os.path.join(self.configPath, "friends", file), "r", encoding="utf-8") as handle:
|
||||
friendinfo = str(handle.read())
|
||||
|
||||
pubkey = None
|
||||
try:
|
||||
pubkey = re.findall("-----BEGIN PUBLIC KEY-----(.*?)-----END PUBLIC KEY-----", friendinfo, re.DOTALL | re.M)[0]
|
||||
pubkey = re.findall(
|
||||
"-----BEGIN PUBLIC KEY-----(.*?)-----END PUBLIC KEY-----",
|
||||
friendinfo,
|
||||
re.DOTALL | re.M,
|
||||
)[0]
|
||||
except IndexError:
|
||||
logger.warning("No pubkey found in config for %s", file)
|
||||
error = True
|
||||
|
||||
if pubkey:
|
||||
logger.debug("read friend's public key: %s", pubkey)
|
||||
uid = hashlib.sha224(pubkey.encode("utf-8")).hexdigest()
|
||||
|
||||
try:
|
||||
address = re.search(r"address\s*=\s*(.*)", friendinfo).group(1)
|
||||
except AttributeError:
|
||||
logger.warning("address not found in config for %s", file)
|
||||
error = True
|
||||
|
||||
try:
|
||||
port = re.search(r"port\s*=\s*(.*)", friendinfo).group(1)
|
||||
if not 0 < int(port) < 65536:
|
||||
@@ -216,6 +256,7 @@ class Node:
|
||||
except AttributeError:
|
||||
logger.warning("port not found in config for %s", file)
|
||||
error = True
|
||||
|
||||
try:
|
||||
trustlevel = re.search(r"trustlevel\s*=\s*(.*)", friendinfo).group(1)
|
||||
except AttributeError:
|
||||
@@ -223,19 +264,32 @@ class Node:
|
||||
error = True
|
||||
|
||||
if not error:
|
||||
obj = friend.Friend(name=file, uid=uid, address=address, port=int(port), trustLevel=int(trustlevel), publicKey=pubkey)
|
||||
obj.configpath = os.path.join(friendPath, file)
|
||||
logger.debug("added friend %s (uid=%s, address=%s, port=%s, trustLevel=%s)", file, uid, address, port, trustlevel)
|
||||
obj = friend.Friend(
|
||||
name=file,
|
||||
uid=uid,
|
||||
address=address,
|
||||
port=int(port),
|
||||
trustLevel=int(trustlevel),
|
||||
publicKey=pubkey,
|
||||
)
|
||||
obj.configpath = os.path.join(self.configPath, "friends", file)
|
||||
logger.debug(
|
||||
"added friend %s (uid=%s, address=%s, port=%s, trustLevel=%s)",
|
||||
file,
|
||||
uid,
|
||||
address,
|
||||
port,
|
||||
trustlevel,
|
||||
)
|
||||
self.friends.append(obj)
|
||||
else:
|
||||
logger.error("Could not add friend '%s' due to errors in the config file", file)
|
||||
error = False
|
||||
|
||||
def verifyMessage(self, message):
|
||||
logger.debug("signature in command class is: %s", message.signature)
|
||||
logger.debug("attempting to verify command")
|
||||
|
||||
if message.msgType is None:
|
||||
if not message.msgType:
|
||||
logger.warning("Required parameter 'msgType' is missing in received message.")
|
||||
raise customexceptions.InvalidMessage
|
||||
if not validators.isInteger(message.msgType):
|
||||
@@ -254,8 +308,8 @@ class Node:
|
||||
logger.warning("Signature is missing in received message")
|
||||
raise customexceptions.InvalidMessage
|
||||
|
||||
for h in message.hops:
|
||||
if not validators.isAlphaNumeric(h):
|
||||
for hop in message.hops:
|
||||
if not validators.isAlphaNumeric(hop):
|
||||
logger.warning("Invalid characters in hops. Only alphanumeric characters are allowed.")
|
||||
raise customexceptions.InvalidMessage
|
||||
|
||||
@@ -267,29 +321,32 @@ class Node:
|
||||
if "AttackerIP" not in message.parameter:
|
||||
logger.warning("Required parameter 'AttackerIP' is missing in received message.")
|
||||
raise customexceptions.InvalidMessage
|
||||
if not validators.isIPv4address(message.parameter['AttackerIP']):
|
||||
if not validators.isIPv4address(message.parameter["AttackerIP"]):
|
||||
logger.warning('Invalid parameter "AttackerIP" in received message.')
|
||||
raise customexceptions.InvalidMessage
|
||||
|
||||
if "Timestamp" not in message.parameter:
|
||||
logger.warning("Required parameter 'Timestamp' is missing in received message.")
|
||||
raise customexceptions.InvalidMessage
|
||||
if not validators.isInteger(message.parameter['Timestamp']):
|
||||
if not validators.isInteger(message.parameter["Timestamp"]):
|
||||
logger.warning('Invalid parameter "Timestamp" in received message.')
|
||||
raise customexceptions.InvalidMessage
|
||||
|
||||
if 'Trustlevel' not in message.parameter:
|
||||
if "Trustlevel" not in message.parameter:
|
||||
logger.warning('Required parameter "Trustlevel" in missing in received message.')
|
||||
raise customexceptions.InvalidMessage
|
||||
if not (validators.isInteger(message.parameter['Trustlevel']) and 0 <= int(message.parameter['Trustlevel']) <= 100):
|
||||
if not (
|
||||
validators.isInteger(message.parameter["Trustlevel"])
|
||||
and 0 <= int(message.parameter["Trustlevel"]) <= 100
|
||||
):
|
||||
logger.warning('Invalid parameter "Trustlevel" in received message.')
|
||||
raise customexceptions.InvalidMessage
|
||||
|
||||
elif message.msgType == 2 or message.msgType == 3:
|
||||
elif message.msgType in (2, 3):
|
||||
if "TimeFrame" not in message.parameter:
|
||||
logger.warning("Required parameter 'TimeFrame' is missing in received message.")
|
||||
raise customexceptions.InvalidMessage
|
||||
if not validators.isInteger(message.parameter['TimeFrame']):
|
||||
if not validators.isInteger(message.parameter["TimeFrame"]):
|
||||
logger.warning('Invalid parameter "TimeFrame" in received message.')
|
||||
raise customexceptions.InvalidMessage
|
||||
else:
|
||||
@@ -301,32 +358,35 @@ class Node:
|
||||
logger.debug("Last hop's uid is: %s", last_hop_uid)
|
||||
|
||||
sender = None
|
||||
pk = None
|
||||
for peer in self.friends:
|
||||
logger.debug("Comparing last hops uid (%s) with one of our friends uid (%s)", last_hop_uid, peer.uid)
|
||||
if peer.uid == last_hop_uid:
|
||||
logger.debug("The message seems to be from our friend %s (uid: %s)", peer.name, peer.uid)
|
||||
sender = peer
|
||||
pk = M2Crypto.RSA.load_pub_key(sender.configpath)
|
||||
pk = RSA.load_pub_key(sender.configpath)
|
||||
break
|
||||
if last_hop_uid == "local":
|
||||
logger.debug("This message was signed with our own key.")
|
||||
c = config.Config()
|
||||
pk = M2Crypto.RSA.load_pub_key(c.pubkey)
|
||||
sender = "local"
|
||||
break
|
||||
if sender is None:
|
||||
|
||||
if last_hop_uid == "local":
|
||||
logger.debug("This message was signed with our own key.")
|
||||
c = config.Config()
|
||||
pk = RSA.load_pub_key(c.pubkey)
|
||||
sender = "local"
|
||||
|
||||
if sender is None or pk is None:
|
||||
logger.warning("The message could not be mapped to one of our friends!")
|
||||
raise customexceptions.InvalidSignature
|
||||
|
||||
verifier = M2Crypto.EVP.PKey()
|
||||
verifier = EVP.PKey()
|
||||
verifier.assign_rsa(pk)
|
||||
verifier.verify_init()
|
||||
verifier.verify_update(json.dumps(message.toSerializableDict()).encode("utf-8"))
|
||||
|
||||
if verifier.verify_final(bytes.fromhex(message.signature)) != 1:
|
||||
logger.warning('Signature doesnt match!')
|
||||
logger.warning("Signature doesnt match!")
|
||||
return False
|
||||
logger.debug('Signature verified successfully')
|
||||
|
||||
logger.debug("Signature verified successfully")
|
||||
message.sender = sender
|
||||
return True
|
||||
|
||||
@@ -338,7 +398,7 @@ class Node:
|
||||
timeframestart = int(time()) - int(timeframe)
|
||||
logger.debug("Dumping all nodes that were inserted after %s", timeframestart)
|
||||
for entry in self.banList:
|
||||
if int(entry['Timestamp']) > int(timeframestart):
|
||||
if int(entry["Timestamp"]) > int(timeframestart):
|
||||
banlist.append(entry)
|
||||
|
||||
return json.dumps(banlist)
|
||||
@@ -346,22 +406,22 @@ class Node:
|
||||
def requestBanlist(self):
|
||||
for peer in self.friends:
|
||||
logger.debug("Sending dump request to %s", peer.name)
|
||||
c = Command()
|
||||
c.msgType = 3
|
||||
c.hops = [self.uid]
|
||||
c.protocolVersion = version.protocolVersion
|
||||
c.parameter = {"TimeFrame": self.banTime or 3600}
|
||||
peer.sendCommand(c)
|
||||
command = Command()
|
||||
command.msgType = 3
|
||||
command.hops = [self.uid]
|
||||
command.protocolVersion = version.protocolVersion
|
||||
command.parameter = {"TimeFrame": self.banTime or 3600}
|
||||
peer.sendCommand(command)
|
||||
|
||||
def cleanBanlist(self):
|
||||
logger.debug("Purging all entries from banlist that are older than %s seconds.", self.banTime)
|
||||
if len(self.banList) > 0:
|
||||
if self.banList:
|
||||
banListKeep = []
|
||||
for ban in self.banList:
|
||||
if ban['Timestamp'] + self.banTime > time():
|
||||
if ban["Timestamp"] + self.banTime > time():
|
||||
banListKeep.append(ban)
|
||||
else:
|
||||
logger.info("Removed %s from internal banlist because the ban has expired.", ban['AttackerIP'])
|
||||
logger.info("Removed %s from internal banlist because the ban has expired.", ban["AttackerIP"])
|
||||
self.banList = banListKeep
|
||||
global cleaner
|
||||
cleaner = threading.Timer(60, self.cleanBanlist)
|
||||
|
||||
Reference in New Issue
Block a user