aboutsummaryrefslogtreecommitdiff
path: root/cgi
diff options
context:
space:
mode:
authorLibravatar bai 2020-07-21 06:41:28 -0400
committerLibravatar bai 2020-07-21 06:41:28 -0400
commitcce54237952b104efc98afec3f3edfd0cb5ed714 (patch)
tree6dfdebde0a8bc3e7fef05e6e54496c3aff7de36d /cgi
parentacedc645c398d6afeff3a8f2e500220da3c8549d (diff)
downloadweabot-cce54237952b104efc98afec3f3edfd0cb5ed714.tar.gz
weabot-cce54237952b104efc98afec3f3edfd0cb5ed714.tar.xz
weabot-cce54237952b104efc98afec3f3edfd0cb5ed714.zip
Implementados bans de rangos compatibles con IPv4 y IPv6
Diffstat (limited to 'cgi')
-rw-r--r--cgi/framework.py4
-rw-r--r--cgi/manage.py214
-rw-r--r--cgi/templates/banned.html11
-rw-r--r--cgi/templates/manage/bans.html9
-rwxr-xr-xcgi/weabot.py7
5 files changed, 121 insertions, 124 deletions
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.') + '<a href="' +
- Settings.CGI_URL+'manage/ban/' + ip + '?edit=' + ban['id']+'">' + _('Edit') + '</a>')
- 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.') + '<a href="' +
+ Settings.CGI_URL+'manage/ban/' + ip + '?edit=' + ban['id']+'">' + _('Edit') + '</a>')
+ 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 @@
<b>#{reason}</b>
</li>
<?py #endif ?>
- <li>Tu ban fue puesto el
- <b>#{added}</b> para las siguientes secciones: <b>#{boards_str}.</b></li>
+ <li>La suspensión fue puesta el <b>#{added}</b> para las siguientes secciones: <b>#{boards_str}</b>.</li>
<?py if expire != "": ?>
- <li>Se te concederá nuevamente el acceso en la siguiente fecha y hora:
- <b>#{expire}</b>.</li>
+ <li>Se te concederá nuevamente el acceso en la siguiente fecha y hora: <b>#{expire}</b>.</li>
+ <?py else: ?>
+ <li>No se te volverá a conceder el acceso ya que la suspensión es permanente.</li>
<?py #endif ?>
+ <li>El rango IP de la suspensión es: <b>#{ipstr}</b>
</ul>
<hr />
<p>Si crees que tu expulsión fue puesta incorrectamente no dudes en <a
@@ -75,4 +76,4 @@
</div>
</div>
</body>
-</html> \ No newline at end of file
+</html>
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 @@
<center>
<div class="replymode">Bans</div>
<?py if mode == 0: ?>
-<form action="#{cgi_url}manage/ban/" name="banform" method="post">
+<form action="#{cgi_url}manage/ban/" name="banform" method="get">
<table>
<tr>
<td class="postblock">Dirección IP</td>
@@ -17,7 +17,6 @@
<table class="managertable">
<tr>
<th>Dirección IP</th>
- <th>Máscara de red</th>
<th>Boards</th>
<th>Agregado</th>
<th>Expira</th>
@@ -30,7 +29,6 @@
<?py for ban in bans: ?>
<tr>
<td>${ban['ip']}</td>
- <td>${ban['netmask']}</td>
<td>${ban['boards']}</td>
<td>${ban['added']}</td>
<td>${ban['until']}</td>
@@ -49,8 +47,7 @@
<?py elif mode == 1: ?>
<form action="#{cgi_url}manage/ban" name="banform" method="post">
<table>
- <tr><td class="postblock">IP</td><td><input type="text" name="ip" value="${ip}" size="20" style="width:100%;" /></td></tr>
- <tr><td class="postblock">Máscara de red</td><td><input type="text" name="netmask" value="${startvalues['netmask']}" style="width:100%;" /></td></tr>
+ <tr><td class="postblock">IP o Rango</td><td><input type="text" name="ip" value="${ip}" size="20" style="width:100%;" /></td></tr>
<tr>
<td class="postblock">Board(s)</td>
<td>
@@ -89,4 +86,4 @@
<?py #endif ?>
</center>
<hr />
-<?py include('templates/base_bottom.html') ?> \ No newline at end of file
+<?py include('templates/base_bottom.html') ?>
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 += '<html xmlns="http://www.w3.org/1999/xhtml"><meta http-equiv="refresh" content="0;url=%s" /><body><p>...</p></body></html>' % 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)