From 76b399732704a904ba4dbabd0d924334d88e1452 Mon Sep 17 00:00:00 2001 From: bai Date: Sun, 12 Jul 2020 15:00:12 -0400 Subject: Agregado soporte básico para IPv6 --- cgi/formatting.py | 3 +-- cgi/framework.py | 16 ++++++---------- cgi/manage.py | 44 ++++++++++++++++++++------------------------ cgi/post.py | 18 +++++++++++++----- cgi/weabot.py | 22 +++++++++++++--------- 5 files changed, 53 insertions(+), 50 deletions(-) (limited to 'cgi') diff --git a/cgi/formatting.py b/cgi/formatting.py index 6461a33..0003f5c 100644 --- a/cgi/formatting.py +++ b/cgi/formatting.py @@ -377,7 +377,6 @@ def markdown(message): def checkWordfilters(message, ip, board): - fixed_ip = inet_aton(ip) wordfilters = FetchAll( "SELECT * FROM `filters` WHERE `type` = '0' ORDER BY `id` ASC") for wordfilter in wordfilters: @@ -399,7 +398,7 @@ def checkWordfilters(message, ip, board): until = '0' InsertDb("INSERT INTO `bans` (`ip`, `boards`, `added`, `until`, `staff`, `reason`, `note`, `blind`) VALUES (" + - "'" + str(fixed_ip) + "', '" + _mysql.escape_string(wordfilter['boards']) + + "INET6_ATON('" + str(ip) + "'), '" + _mysql.escape_string(wordfilter['boards']) + "', " + str(timestamp()) + ", " + until + ", 'System', '" + _mysql.escape_string(wordfilter['reason']) + "', 'Word Auto-ban', '"+_mysql.escape_string(wordfilter['blind'])+"')") regenerateAccess() diff --git a/cgi/framework.py b/cgi/framework.py index cc7a065..9899c16 100644 --- a/cgi/framework.py +++ b/cgi/framework.py @@ -50,11 +50,9 @@ def cleanDir(path, ext=None): def addressIsBanned(ip, board): - packed_ip = inet_aton(ip) - bans = FetchAll("SELECT * FROM `bans` WHERE (`netmask` IS NULL AND `ip` = '"+str( - packed_ip)+"') OR (`netmask` IS NOT NULL AND '"+str(packed_ip)+"' & `netmask` = `ip`)") - logTime("SELECT * FROM `bans` WHERE (`netmask` IS NULL AND `ip` = '"+str(packed_ip) + - "') OR (`netmask` IS NOT NULL AND '"+str(packed_ip)+"' & `netmask` = `ip`)") + # TODO ipv6 + + bans = FetchAll("SELECT * FROM `bans` WHERE `ip` = INET6_ATON('"+str(ip)+"')") for ban in bans: if ban["boards"] != "": boards = pickle.loads(ban["boards"]) @@ -124,13 +122,11 @@ def getHost(ip): def hostIsBanned(ip): host = getHost(ip) if host: - banned_hosts = [] - for banned_host in banned_hosts: + for banned_host in Settings.BANNED_HOSTS: if host.endswith(banned_host): return True - return False - else: - return False + + return False def updateBoardSettings(): diff --git a/cgi/manage.py b/cgi/manage.py index efcee8f..40a37a1 100644 --- a/cgi/manage.py +++ b/cgi/manage.py @@ -179,7 +179,7 @@ def manage(self, path_split): template_values = {"mode": 1, 'boards': boardlist()} elif self.formdata.get("thread"): parentid = int(self.formdata["thread"]) - posts = FetchAll('SELECT id, timestamp, timestamp_formatted, name, message, file, thumb, IS_DELETED, locked, subject, length, INET_NTOA(ip) AS ip FROM `posts` WHERE (parentid = %d OR id = %d) AND boardid = %s ORDER BY `id` ASC' % ( + posts = FetchAll('SELECT id, timestamp, timestamp_formatted, name, message, file, thumb, IS_DELETED, locked, subject, length, INET6_NTOA(ip) AS ip FROM `posts` WHERE (parentid = %d OR id = %d) AND boardid = %s ORDER BY `id` ASC' % ( parentid, parentid, board['id'])) template_filename = "mod.html" template_values = {"mode": 3, @@ -191,7 +191,7 @@ def manage(self, path_split): template_values = {"mode": 2, "dir": board["dir"], "threads": threads} elif path_split[2] == "recent": - posts = FetchAll("SELECT posts.id, posts.subject, dir, boards.board_type, parentid, file, thumb, timestamp_formatted, timestamp, posts.message, INET_NTOA(ip) AS ip, posts.name, email, tripcode, boards.name AS board_name FROM posts INNER JOIN boards ON posts.boardid = boards.id WHERE posts.timestamp > UNIX_TIMESTAMP() - 86400 ORDER BY timestamp DESC") + posts = FetchAll("SELECT posts.id, posts.subject, dir, boards.board_type, parentid, file, thumb, timestamp_formatted, timestamp, posts.message, INET6_NTOA(ip) AS ip, posts.name, email, tripcode, boards.name AS board_name FROM posts INNER JOIN boards ON posts.boardid = boards.id WHERE posts.timestamp > UNIX_TIMESTAMP() - 86400 ORDER BY timestamp DESC") template_filename = "recent.html" template_values = {"posts": posts} elif path_split[2] == 'staff': @@ -345,7 +345,7 @@ def manage(self, path_split): board = setBoard(path_split[3]) postid = int(path_split[4]) - post = FetchOne('SELECT id, message, parentid, INET_NTOA(ip) AS ip FROM posts WHERE boardid = %s AND id = %s' % ( + post = FetchOne('SELECT id, message, parentid, INET6_NTOA(ip) AS ip FROM posts WHERE boardid = %s AND id = %s' % ( board['id'], postid)) if not permanently: @@ -452,6 +452,8 @@ def manage(self, path_split): staff_account['username'], 'Disabled permasage in thread /' + path_split[3] + '/' + path_split[4]) template_filename = "message.html" elif path_split[2] == 'move': + raise NotImplementedError + if not moderator: return @@ -654,16 +656,15 @@ def manage(self, path_split): if len(path_split) > 4: board = setBoard(path_split[3]) - post = FetchOne('SELECT `ip` FROM `posts` WHERE `boardid` = ' + + post = FetchOne('SELECT INET6_NTOA(`ip`) AS `ip` FROM `posts` WHERE `boardid` = ' + board['id'] + ' AND `id` = \'' + _mysql.escape_string(path_split[4]) + '\' LIMIT 1') - formatted_ip = inet_ntoa(long(post['ip'])) # 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" else: message = 'Espere...' + Settings.CGI_URL + 'manage/ban?ip=' + post['ip'] + '" />Espere...' template_filename = "message.html" else: # if path_split[3] == '': @@ -724,7 +725,7 @@ def manage(self, path_split): blind = '0' # Banear sin mensaje - InsertDb("INSERT INTO `bans` (`ip`, `netmask`, `boards`, `added`, `until`, `staff`, `reason`, `note`, `blind`) VALUES (INET_ATON('" + _mysql.escape_string(ip) + "') & INET_ATON('"+_mysql.escape_string(netmask)+"'), INET_ATON('"+_mysql.escape_string(insnetmask)+"'), '" + + 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+"')") regenerateAccess() @@ -752,7 +753,7 @@ def manage(self, path_split): edit_id = 0 if 'edit' in self.formdata.keys(): edit_id = self.formdata['edit'] - ban = FetchOne("SELECT `id`, INET_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` = '" + + 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'] == '': @@ -786,7 +787,7 @@ def manage(self, path_split): action_taken = False if len(path_split) > 4: if path_split[3] == 'delete': - ip = FetchOne("SELECT INET_NTOA(`ip`) AS 'ip' FROM `bans` WHERE `id` = '" + + ip = FetchOne("SELECT INET6_NTOA(`ip`) AS 'ip' FROM `bans` WHERE `id` = '" + _mysql.escape_string(path_split[4]) + "' LIMIT 1", 0)[0] if ip != '': # Delete ban @@ -804,7 +805,7 @@ def manage(self, path_split): if not action_taken: bans = FetchAll( - "SELECT `id`, INET_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`, 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") if bans: for ban in bans: if ban['boards'] == '': @@ -1024,7 +1025,7 @@ def manage(self, path_split): if path_split[4] == 'delete': board = setBoard(path_split[5]) - post = FetchOne('SELECT id, parentid, message, INET_NTOA(ip) AS ip FROM `posts` WHERE `boardid` = ' + + post = FetchOne('SELECT id, parentid, message, INET6_NTOA(ip) AS ip FROM `posts` WHERE `boardid` = ' + board['id'] + ' AND `id` = \'' + _mysql.escape_string(path_split[6]) + '\' LIMIT 1') if not post: message = _( @@ -1105,7 +1106,7 @@ def manage(self, path_split): # Table if 'board' in self.formdata.keys() and self.formdata['board'] != 'all': cboard = self.formdata['board'] - posts = FetchAll("SELECT posts.id, posts.timestamp, timestamp_formatted, IS_DELETED, INET_NTOA(posts.ip) as ip, posts.message, dir, boardid FROM `posts` INNER JOIN `boards` ON boardid = boards.id WHERE `dir` = '%s' AND IS_DELETED %s ORDER BY `timestamp` DESC LIMIT %d, %d" % ( + posts = FetchAll("SELECT posts.id, posts.timestamp, timestamp_formatted, IS_DELETED, INET6_NTOA(posts.ip) as ip, posts.message, dir, boardid FROM `posts` INNER JOIN `boards` ON boardid = boards.id WHERE `dir` = '%s' AND IS_DELETED %s ORDER BY `timestamp` DESC LIMIT %d, %d" % ( _mysql.escape_string(self.formdata['board']), _mysql.escape_string(type_condition), currentpage*pagesize, pagesize)) try: totals = FetchOne("SELECT COUNT(id) FROM `posts` WHERE IS_DELETED %s AND `boardid` = %s" % ( @@ -1868,10 +1869,10 @@ def manage(self, path_split): # Tabla if 'board' in self.formdata.keys() and self.formdata['board'] != 'all': - reports = FetchAll("SELECT id, timestamp, timestamp_formatted, postid, parentid, link, board, INET_NTOA(ip) AS ip, reason, reporterip FROM `reports` WHERE `board` = '%s' ORDER BY `timestamp` DESC LIMIT %d, %d" % ( + reports = FetchAll("SELECT id, timestamp, timestamp_formatted, postid, parentid, link, board, INET6_NTOA(ip) AS ip, reason, reporterip FROM `reports` WHERE `board` = '%s' ORDER BY `timestamp` DESC LIMIT %d, %d" % ( _mysql.escape_string(self.formdata['board']), currentpage*pagesize, pagesize)) else: - reports = FetchAll("SELECT id, timestamp, timestamp_formatted, postid, parentid, link, board, INET_NTOA(ip) AS ip, reason, reporterip FROM `reports` ORDER BY `timestamp` DESC LIMIT %d, %d" % ( + reports = FetchAll("SELECT id, timestamp, timestamp_formatted, postid, parentid, link, board, INET6_NTOA(ip) AS ip, reason, reporterip FROM `reports` ORDER BY `timestamp` DESC LIMIT %d, %d" % ( currentpage*pagesize, pagesize)) if 'board' in self.formdata.keys(): @@ -1920,13 +1921,8 @@ def manage(self, path_split): if 'ip' in self.formdata.keys(): # If an IP was given... if self.formdata['ip'] != '': - formatted_ip = str(inet_aton(self.formdata['ip'])) - posts = FetchAll( - "SELECT posts.*, boards.dir, boards.board_type, boards.subject AS default_subject FROM `posts` JOIN `boards` ON boards.id = posts.boardid WHERE ip = '%s' ORDER BY posts.timestamp DESC" % _mysql.escape_string(formatted_ip)) - if '.' in self.formdata['ip']: - ip = self.formdata['ip'] - else: - ip = inet_ntoa(long(self.formdata['ip'])) + ip = self.formdata['ip'] + posts = FetchAll("SELECT posts.*, boards.dir, boards.board_type, boards.subject AS default_subject FROM `posts` JOIN `boards` ON boards.id = posts.boardid WHERE ip = INET6_ATON('%s') ORDER BY posts.timestamp DESC" % _mysql.escape_string(ip)) template_filename = "ipshow.html" template_values = {"mode": 1, "ip": ip, "host": getHost( ip), "country": getCountry(ip), "tor": addressIsTor(ip), "posts": posts} @@ -1965,7 +1961,7 @@ def manage(self, path_split): return deletedPostsTotal = 0 - ip = inet_aton(self.formdata['ip']) + ip = self.formdata['ip'] deletedPosts = 0 for theboard in where: board = setBoard(theboard['dir']) @@ -1973,7 +1969,7 @@ def manage(self, path_split): # delete all starting posts first op_posts = FetchAll( - "SELECT `id`, `message` FROM posts WHERE parentid = 0 AND boardid = '" + board['id'] + "' AND ip = " + str(ip)) + "SELECT `id`, `message` FROM posts WHERE parentid = 0 AND boardid = '" + board['id'] + "' AND ip = INET6_ATON('" + str(ip) + "')") for post in op_posts: deletePost(post['id'], None) @@ -1981,7 +1977,7 @@ def manage(self, path_split): deletedPostsTotal += 1 replies = FetchAll( - "SELECT `id`, `message`, `parentid` FROM posts WHERE parentid != 0 AND boardid = '" + board['id'] + "' AND ip = " + str(ip)) + "SELECT `id`, `message`, `parentid` FROM posts WHERE parentid != 0 AND boardid = '" + board['id'] + "' AND ip = INET6_ATON('" + str(ip) + "')") for post in replies: deletePost(post['id'], None, '2') diff --git a/cgi/post.py b/cgi/post.py index 8937054..5e17df1 100644 --- a/cgi/post.py +++ b/cgi/post.py @@ -50,11 +50,19 @@ class Post(object): def insert(self): logTime("Insertando Post") - post_values = [_mysql.escape_string(str(value)) for key, value in self.post.iteritems()] + post_values = [] + + for key, value in self.post.iteritems(): + if key == 'ip': + template = "INET6_ATON('%s')" + else: + template = "'%s'" + + post_values.append(template % _mysql.escape_string(str(value))) - return InsertDb("INSERT INTO `posts` (`%s`) VALUES ('%s')" % ( + return InsertDb("INSERT INTO `posts` (`%s`) VALUES (%s)" % ( "`, `".join(self.post.keys()), - "', '".join(post_values) + ", ".join(post_values) )) class RegenerateThread(threading.Thread): @@ -101,7 +109,7 @@ def getThread(postid=0, mobile=False, timestamp=0): else: cond = "`id` = %s" % str(postid) - op_post = FetchOne("SELECT IS_DELETED, email, file, file_size, id, image_height, image_width, ip, message, name, subject, thumb, thumb_height, thumb_width, timestamp_formatted, tripcode, parentid, locked, expires, expires_alert, expires_formatted, timestamp FROM `posts` WHERE %s AND `boardid` = %s AND parentid = 0 LIMIT 1" % (cond, board["id"])) + op_post = FetchOne("SELECT IS_DELETED, email, file, file_size, id, image_height, image_width, message, name, subject, thumb, thumb_height, thumb_width, timestamp_formatted, tripcode, parentid, locked, expires, expires_alert, expires_formatted, timestamp FROM `posts` WHERE %s AND `boardid` = %s AND parentid = 0 LIMIT 1" % (cond, board["id"])) if op_post: op_post['num'] = 1 if mobile: @@ -110,7 +118,7 @@ def getThread(postid=0, mobile=False, timestamp=0): #thread = {"id": op_post["id"], "posts": [op_post], "omitted": 0, "omitted_img": 0} total_bytes += len(op_post["message"])+80 - replies = FetchAll("SELECT IS_DELETED, email, file, file_size, id, image_height, image_width, ip, message, name, subject, thumb, thumb_height, thumb_width, timestamp_formatted, tripcode, parentid, locked, expires, expires_alert, expires_formatted, timestamp FROM `posts` WHERE `parentid` = %s AND `boardid` = %s ORDER BY `id` ASC" % (op_post["id"], board["id"])) + replies = FetchAll("SELECT IS_DELETED, email, file, file_size, id, image_height, image_width, message, name, subject, thumb, thumb_height, thumb_width, timestamp_formatted, tripcode, parentid, locked, expires, expires_alert, expires_formatted, timestamp FROM `posts` WHERE `parentid` = %s AND `boardid` = %s ORDER BY `id` ASC" % (op_post["id"], board["id"])) thread["length"] = 1 if replies: for reply in replies: diff --git a/cgi/weabot.py b/cgi/weabot.py index 1406707..0f59654 100755 --- a/cgi/weabot.py +++ b/cgi/weabot.py @@ -323,9 +323,8 @@ class weabot(object): self.output += '
...
' % url elif path_split[1] == "banned": OpenDb() - packed_ip = inet_aton(self.environ["REMOTE_ADDR"]) - bans = FetchAll("SELECT * FROM `bans` WHERE (`netmask` IS NULL AND `ip` = '"+str( - packed_ip)+"') OR (`netmask` IS NOT NULL AND '"+str(packed_ip)+"' & `netmask` = `ip`)") + packed_ip = self.environ["REMOTE_ADDR"] + bans = FetchAll("SELECT * FROM `bans` WHERE `ip` = INET6_ATON('"+str(packed_ip)+"')") if bans: for ban in bans: if ban["boards"] != "": @@ -385,7 +384,7 @@ class weabot(object): def make_post(self, ip, boarddir, parent, trap1, trap2, name, email, subject, message, file, file_original, spoil, oek_file, password, noimage, mobile): _STARTTIME = time.clock() # Comment if not debug - if addressIsUS(ip): + if hostIsBanned(ip): raise UserError, "Host en lista negra." # open database @@ -429,7 +428,7 @@ class weabot(object): raise UserError, '' % board["dir"] # Disallow posting if the site OR board is in maintenance - if Settings.MAINTENANCE: + if Settings.MAINTENANCE and board["dir"] != 'polka': raise UserError, _( "%s is currently under maintenance. We'll be back.") % Settings.SITE_TITLE if board["locked"] == '1': @@ -437,7 +436,7 @@ class weabot(object): # create post object post = Post(board["id"]) - post["ip"] = inet_aton(ip) + post["ip"] = ip post["timestamp"] = post["bumped"] = int(t) post["timestamp_formatted"] = formatTimestamp(t) @@ -519,7 +518,7 @@ class weabot(object): post["name"] = post["name"].replace('◆', '◇') # process capcodes - cap_id = hide_end = None + cap_id = hide_end = use_icon = None if post["name"] in Settings.CAPCODES: capcode = Settings.CAPCODES[post["name"]] if post["tripcode"] == (Settings.TRIP_CHAR + capcode[0]): @@ -530,12 +529,17 @@ class weabot(object): # post["name"] = post["tripcode"] = '' # post["message"] = ('[%s]