from operator import itemgetter
from socket import getaddrinfo, gaierror
import moo_utils
+import dns.resolver
+import dns.exception
+
+import pyva_net_rizon_acid_core_User as User
class Ban(object):
def __init__(self, row):
last_req = self.__get_last_request(main)
acceptable, rating, internal = self.__verify(nick, vhost, main)
else: # only for requests missed during downtime
- userinfo = self.module.inter.findUser(nick)
+ userinfo = User.findUser(nick)
if userinfo and userinfo['su']:
main = userinfo['su']
last_req = self.__get_last_request(main)
suspicious = self.__is_suspicious(vhost)
date = datetime.now()
self.list[nick.lower()] = {'id': id, 'vhost': vhost, 'rating': rating, 'date': date, 'main': main, 'nick': nick, 'last': last_req, 'suspicious': suspicious}
- self.module.msg(self.module.chan, moo_utils.format_last_req(last_req, '[new] %(id)d.@o %(nick)s @sep %(vhost)s%(susp)s @sep%(lastreq)s' % {
+ self.module.msg(self.module.chan, moo_utils.format_last_req(last_req, '[new] %(id)d.@o %(nick)s @sep %(vhost)s%(susp)s @sep%(lastreq)s %(extra)s' % {
'id' : id,
'nick' : nick,
'vhost' : vhost if not suspicious else '@c10@b[!]@o ' + vhost,
'susp' : ' @sep @bSuspicious@b %s' % suspicious if suspicious else '',
- 'lastreq': ' @bLast request@b %s ago as %s @sep' % (utils.get_timespan(last_req.date), last_req.nickname) if last_req else ''}))
+ 'lastreq': ' @bLast request@b %s ago as %s @sep' % (utils.get_timespan(last_req.date), last_req.nickname) if last_req else '',
+ 'extra' : 'vHost resolved but its ownership was verified by the existence of a DNS TXT record' if internal == 'TXT record' else ''}))
def add_blacklist(self, vhost, by, reason=None):
b = (vhost, by, reason, datetime.now())
is_blacklisted, reason, int = self.__is_blacklisted(vhost)
if is_blacklisted:
return (False, reason, int)
-
- is_resolvable, resolved, host = self.__is_resolvable(vhost)
- if is_resolvable:
- return (False,
- 'Your vHost resolves. %s' % RULES,
- 'vHost resolves (%s => %s)' % (host, resolved))
-
+
for req in self.list.values():
if main == req['main'] and nick != req['nick']:
return (False,
'You already have a pending vHost request for a grouped nickname. Please wait for it to be reviewed before requesting a new one.',
'Has a pending request with grouped nick %s' % req['nick'])
+
+ if vhost.replace(".", "").isdigit() and not self.__is_numeric_ip(vhost):
+ return (True, '@c9Acceptable@c', None)
+ is_resolvable, resolved, host = self.__is_resolvable(vhost)
+ if is_resolvable:
+ (txt_record_exists, resolving_error) = self.check_nick_in_TXT_records(vhost, nick)
+
+ if resolving_error == "timeout":
+ return (False, "Rejected vHost", "DNS Timeout when trying to check TXT record for vhost @b{}@b requested by @b{}@b.".format(
+ vhost, nick))
+ elif resolving_error:
+ return (False, "Unkown error", "The following error occured when checking TXT record for vhost @b{}@b requested by @b{}@b @sep {}.".format(
+ vhost, nick, resolving_error))
+
+ if not txt_record_exists:
+ return (False,
+ 'Your vHost resolves. You can add a particular DNS TXT record to confirm the ownership of the domain and request again. %s' % RULES,
+ 'vHost resolves (%s => %s)' % (host, resolved))
+ else:
+ return (True, '@c9Acceptable@c', 'TXT record')
+
return (True, '@c9Acceptable@c', None)
-
+
+ def __is_numeric_ip(self, host):
+ try:
+ parts = host.split(".")
+ return len(parts) == len([x for x in parts if 0 <= int(x) <= 255]) == 4
+ except:
+ return False
+
def __is_resolvable(self, host):
try:
res = getaddrinfo(host, 80)
return 'matches @c10%s@c%s' % (b.vhost, ' (%s)' % b.reason if b.reason else '')
return False
+
+ def check_nick_in_TXT_records(self, host, nick):
+ try:
+ resolver = dns.resolver.Resolver()
+ resolver.timeout = 1
+ resolver.lifetime = 1
+ answers = resolver.query(host, 'TXT')
+ for answer in answers:
+ for ans in answer.strings:
+ parts = ans.split('=')
+ if len(parts) > 1 and parts[0].lower().strip() == 'rizon_vhost':
+ if parts[1].strip() == '*':
+ return (True, "")
+ nicks = [n.lower().strip() for n in parts[1].split(',')]
+ if nick.lower() in nicks:
+ return (True, "")
+ return (False, "")
+ except dns.exception.Timeout, e:
+ return (False, "timeout")
+ except Exception, e:
+ return (False, str(e))