From cce54237952b104efc98afec3f3edfd0cb5ed714 Mon Sep 17 00:00:00 2001 From: bai Date: Tue, 21 Jul 2020 06:41:28 -0400 Subject: Implementados bans de rangos compatibles con IPv4 y IPv6 --- cgi/framework.py | 4 +- cgi/manage.py | 214 +++++++++++++++++++++-------------------- cgi/templates/banned.html | 11 ++- cgi/templates/manage/bans.html | 9 +- cgi/weabot.py | 7 +- 5 files changed, 121 insertions(+), 124 deletions(-) (limited to 'cgi') diff --git a/cgi/framework.py b/cgi/framework.py index 9899c16..5f95303 100644 --- a/cgi/framework.py +++ b/cgi/framework.py @@ -50,9 +50,7 @@ def cleanDir(path, ext=None): def addressIsBanned(ip, board): - # TODO ipv6 - - bans = FetchAll("SELECT * FROM `bans` WHERE `ip` = INET6_ATON('"+str(ip)+"')") + bans = FetchAll("SELECT * FROM `bans` WHERE INET6_ATON('"+str(ip)+"') BETWEEN `ipstart` AND `ipend`") for ban in bans: if ban["boards"] != "": boards = pickle.loads(ban["boards"]) diff --git a/cgi/manage.py b/cgi/manage.py index 40a37a1..2aa8a5e 100644 --- a/cgi/manage.py +++ b/cgi/manage.py @@ -658,7 +658,7 @@ def manage(self, path_split): board = setBoard(path_split[3]) post = FetchOne('SELECT INET6_NTOA(`ip`) AS `ip` FROM `posts` WHERE `boardid` = ' + board['id'] + ' AND `id` = \'' + _mysql.escape_string(path_split[4]) + '\' LIMIT 1') - # Creo que esto no deberia ir aqui... -> UpdateDb('UPDATE `posts` SET `banned` = 1 WHERE `boardid` = ' + board['id'] + ' AND `id` = \'' + _mysql.escape_string(path_split[4]) + '\'') + if not post: message = _('Unable to locate a post with that ID.') template_filename = "message.html" @@ -667,119 +667,121 @@ def manage(self, path_split): Settings.CGI_URL + 'manage/ban?ip=' + post['ip'] + '" />Espere...' template_filename = "message.html" else: - # if path_split[3] == '': - try: + reason = self.formdata.get('reason') + if reason is not None: + # Start ban process + import netaddr ip = self.formdata['ip'] - except: - ip = '' - try: - netmask = insnetmask = self.formdata['netmask'] - if netmask == '255.255.255.255': - insnetmask = '' - except: - netmask = instnetmask = '' - # else: - # ip = path_split[3] - if ip != '': + + # Parse CIDR or IP glob try: - reason = self.formdata['reason'] - except: - reason = None - if reason is not None: - if self.formdata['seconds'] != '0': - until = str( - timestamp() + int(self.formdata['seconds'])) + ipnetwork = netaddr.IPNetwork(ip) + ipstart, ipend = str(ipnetwork[0]), str(ipnetwork[-1]) + ipstr = str(ipnetwork) + except netaddr.core.AddrFormatError: + # Invalid format so try with globs + iprange = netaddr.glob_to_iprange(ip) + ipstart, ipend = str(iprange[0]), str(iprange[-1]) + + cidrs = iprange.cidrs() + if len(cidrs) == 1: + ipstr = str(cidrs[0]) else: - until = '0' - where = '' - if 'board_all' not in self.formdata.keys(): - where = [] - boards = FetchAll('SELECT `dir` FROM `boards`') - for board in boards: - keyname = 'board_' + board['dir'] - if keyname in self.formdata.keys(): - if self.formdata[keyname] == "1": - where.append(board['dir']) - if len(where) > 0: - where = pickle.dumps(where) - else: - self.error( - _("You must select where the ban shall be placed")) - return + ipstr = str(iprange) - if 'edit' in self.formdata.keys(): - UpdateDb("DELETE FROM `bans` WHERE `id` = '" + - _mysql.escape_string(self.formdata['edit']) + "' LIMIT 1") - else: - ban = FetchOne("SELECT `id` FROM `bans` WHERE `ip` = '" + _mysql.escape_string( - ip) + "' AND `boards` = '" + _mysql.escape_string(where) + "' LIMIT 1") - if ban: - self.error(_('There is already an identical ban for this IP.') + '' + _('Edit') + '') - return - - # Blind mode - if 'blind' in self.formdata.keys() and self.formdata['blind'] == '1': - blind = '1' - else: - blind = '0' - # Banear sin mensaje - InsertDb("INSERT INTO `bans` (`ip`, `netmask`, `boards`, `added`, `until`, `staff`, `reason`, `note`, `blind`) VALUES (INET6_ATON('" + _mysql.escape_string(ip) + "'), INET_ATON('"+_mysql.escape_string(insnetmask)+"'), '" + - _mysql.escape_string(where) + "', " + str(timestamp()) + ", " + until + ", '" + _mysql.escape_string(staff_account['username']) + "', '" + _mysql.escape_string(self.formdata['reason']) + "', '" + _mysql.escape_string(self.formdata['note']) + "', '"+blind+"')") + if self.formdata['seconds'] != '0': + until = str( + timestamp() + int(self.formdata['seconds'])) + else: + until = '0' + where = '' + if 'board_all' not in self.formdata.keys(): + where = [] + boards = FetchAll('SELECT `dir` FROM `boards`') + for board in boards: + keyname = 'board_' + board['dir'] + if keyname in self.formdata.keys(): + if self.formdata[keyname] == "1": + where.append(board['dir']) + if len(where) > 0: + where = pickle.dumps(where) + else: + self.error( + _("You must select where the ban shall be placed")) + return - regenerateAccess() - if 'edit' in self.formdata.keys(): - message = _('Ban successfully edited.') - action = 'Edited ban for ' + ip + if 'edit' in self.formdata.keys(): + UpdateDb("DELETE FROM `bans` WHERE `id` = '" + + _mysql.escape_string(self.formdata['edit']) + "' LIMIT 1") + """else: # TODO : Duplicate check + ban = FetchOne("SELECT `id` FROM `bans` WHERE `ip` = '" + _mysql.escape_string( + ip) + "' AND `boards` = '" + _mysql.escape_string(where) + "' LIMIT 1") + if ban: + self.error(_('There is already an identical ban for this IP.') + '' + _('Edit') + '') + return""" + + # Blind mode + blind = self.formdata.get('blind', '0') + + #raise UserError, "{} {} {}".format(ipstart, ipend, ipstr) + + # Banear sin mensaje + InsertDb("INSERT INTO `bans` (`ipstart`, `ipend`, `ipstr`, `boards`, `added`, `until`, `staff`, `reason`, `note`, `blind`) VALUES (INET6_ATON('" + + ipstart + "'), INET6_ATON('" + ipend + "'), '" + ipstr + "', '" + + _mysql.escape_string(where) + "', " + str(timestamp()) + ", " + until + ", '" + _mysql.escape_string(staff_account['username']) + "', '" + _mysql.escape_string(self.formdata['reason']) + "', '" + _mysql.escape_string(self.formdata['note']) + "', '"+blind+"')") + + regenerateAccess() + if 'edit' in self.formdata.keys(): + message = _('Ban successfully edited.') + action = 'Edited ban for ' + ip + else: + message = _('Ban successfully placed.') + action = 'Banned ' + ip + if until != '0': + action += ' until ' + \ + formatTimestamp(until) else: - message = _('Ban successfully placed.') - action = 'Banned ' + ip - if until != '0': - action += ' until ' + \ - formatTimestamp(until) + action += ' permanently' + logAction(staff_account['username'], action) + template_filename = 'message.html' + else: + startvalues = {'where': [], + 'reason': '', + 'note': '', + 'message': '(GET OUT)', + 'seconds': '0', + 'blind': '1'} + edit_id = 0 + if 'edit' in self.formdata.keys(): + edit_id = self.formdata['edit'] + ban = FetchOne("SELECT `id`, INET6_NTOA(`ip`) AS 'ip', CASE WHEN `netmask` IS NULL THEN '255.255.255.255' ELSE INET_NTOA(`netmask`) END AS 'netmask', boards, added, until, staff, reason, note, blind FROM `bans` WHERE `id` = '" + + _mysql.escape_string(edit_id) + "' ORDER BY `added` DESC") + if ban: + if ban['boards'] == '': + where = '' else: - action += ' permanently' - logAction(staff_account['username'], action) - template_filename = 'message.html' - else: - startvalues = {'where': [], - 'netmask': '255.255.255.255', - 'reason': '', - 'note': '', - 'message': '(GET OUT)', - 'seconds': '0', - 'blind': '1'} - edit_id = 0 - if 'edit' in self.formdata.keys(): - edit_id = self.formdata['edit'] - ban = FetchOne("SELECT `id`, INET6_NTOA(`ip`) AS 'ip', CASE WHEN `netmask` IS NULL THEN '255.255.255.255' ELSE INET_NTOA(`netmask`) END AS 'netmask', boards, added, until, staff, reason, note, blind FROM `bans` WHERE `id` = '" + - _mysql.escape_string(edit_id) + "' ORDER BY `added` DESC") - if ban: - if ban['boards'] == '': - where = '' - else: - where = pickle.loads(ban['boards']) - if ban['until'] == '0': - until = 0 - else: - until = int(ban['until']) - timestamp() - startvalues = {'where': where, - 'netmask': ban['netmask'], - 'reason': ban['reason'], - 'note': ban['note'], - 'seconds': str(until), - 'blind': ban['blind'] - } + where = pickle.loads(ban['boards']) + if ban['until'] == '0': + until = 0 else: - edit_id = 0 + until = int(ban['until']) - timestamp() + startvalues = {'where': where, + 'reason': ban['reason'], + 'note': ban['note'], + 'seconds': str(until), + 'blind': ban['blind'] + } + else: + edit_id = 0 - template_filename = "bans.html" - template_values = {'mode': 1, - 'boards': boardlist(), - 'ip': ip, - 'startvalues': startvalues, - 'edit_id': edit_id} + template_filename = "bans.html" + template_values = {'mode': 1, + 'boards': boardlist(), + 'ip': self.formdata.get('ip'), + 'startvalues': startvalues, + 'edit_id': edit_id} elif path_split[2] == 'bans': if not moderator: return @@ -787,7 +789,7 @@ def manage(self, path_split): action_taken = False if len(path_split) > 4: if path_split[3] == 'delete': - ip = FetchOne("SELECT INET6_NTOA(`ip`) AS 'ip' FROM `bans` WHERE `id` = '" + + ip = FetchOne("SELECT ipstr FROM `bans` WHERE `id` = '" + _mysql.escape_string(path_split[4]) + "' LIMIT 1", 0)[0] if ip != '': # Delete ban @@ -805,7 +807,7 @@ def manage(self, path_split): if not action_taken: bans = FetchAll( - "SELECT `id`, INET6_NTOA(`ip`) AS 'ip', CASE WHEN `netmask` IS NULL THEN '255.255.255.255' ELSE INET_NTOA(`netmask`) END AS 'netmask', boards, added, until, staff, reason, note, blind FROM `bans` ORDER BY `added` DESC") + "SELECT `id`, `ipstr` AS 'ip', boards, added, until, staff, reason, note, blind FROM `bans` ORDER BY `added` DESC") if bans: for ban in bans: if ban['boards'] == '': diff --git a/cgi/templates/banned.html b/cgi/templates/banned.html index 9e59699..16d822e 100644 --- a/cgi/templates/banned.html +++ b/cgi/templates/banned.html @@ -58,12 +58,13 @@ #{reason} -
  • Tu ban fue puesto el - #{added} para las siguientes secciones: #{boards_str}.
  • +
  • La suspensión fue puesta el #{added} para las siguientes secciones: #{boards_str}.
  • -
  • Se te concederá nuevamente el acceso en la siguiente fecha y hora: - #{expire}.
  • +
  • Se te concederá nuevamente el acceso en la siguiente fecha y hora: #{expire}.
  • + +
  • No se te volverá a conceder el acceso ya que la suspensión es permanente.
  • +
  • El rango IP de la suspensión es: #{ipstr}

    Si crees que tu expulsión fue puesta incorrectamente no dudes en - \ No newline at end of file + diff --git a/cgi/templates/manage/bans.html b/cgi/templates/manage/bans.html index 81e0f71..96e1ed1 100644 --- a/cgi/templates/manage/bans.html +++ b/cgi/templates/manage/bans.html @@ -4,7 +4,7 @@

    Bans
    -
    + @@ -17,7 +17,6 @@
    Dirección IP
    - @@ -30,7 +29,6 @@ - @@ -49,8 +47,7 @@
    Dirección IPMáscara de red Boards Agregado Expira
    ${ban['ip']}${ban['netmask']} ${ban['boards']} ${ban['added']} ${ban['until']}
    - - +
    IP
    Máscara de red
    IP o Rango
    Board(s) @@ -89,4 +86,4 @@
    - \ No newline at end of file + diff --git a/cgi/weabot.py b/cgi/weabot.py index ec88cac..2597ac3 100755 --- a/cgi/weabot.py +++ b/cgi/weabot.py @@ -323,9 +323,7 @@ class weabot(object): self.output += '

    ...

    ' % url elif path_split[1] == "banned": OpenDb() - packed_ip = self.environ["REMOTE_ADDR"] - bans = FetchAll( - "SELECT * FROM `bans` WHERE `ip` = INET6_ATON('"+str(packed_ip)+"')") + bans = FetchAll("SELECT * FROM `bans` WHERE INET6_ATON('"+self.environ["REMOTE_ADDR"]+"') BETWEEN `ipstart` AND `ipend`") if bans: for ban in bans: if ban["boards"] != "": @@ -335,7 +333,7 @@ class weabot(object): if ban["boards"]: boards_str = '/' + '/, /'.join(boards) + '/' else: - boards_str = _("all boards") + boards_str = 'todas' if ban["until"] != "0": expire = formatTimestamp(ban["until"]) else: @@ -348,6 +346,7 @@ class weabot(object): 'added': formatTimestamp(ban["added"]), 'expire': expire, 'ip': self.environ["REMOTE_ADDR"], + 'ipstr': ban['ipstr'], } self.output = renderTemplate( 'banned.html', template_values) -- cgit v1.2.1-18-gbd029