# -*- coding: iso-8859-1 -*-
"""
MoinMoin - WhoisLookup Action
PURPOSE:
This action is used to perform Whois lookups from within the Wiki.
MODIFICATION HISTORY:
@copyright: 2007 by Alan Snelson (Alan@Wave2.org)
@license: GNU GPL, see COPYING for details.
Version: 0.1
0.1 Initial concept based on http://sourceforge.net/projects/rwhois/
"""
import re, socket, string, sys
from MoinMoin import wikiutil
from MoinMoin.Page import Page
from MoinMoin.PageEditor import PageEditor
from MoinMoin.formatter.text_html import Formatter
from MoinMoin.action import ActionBase
class WhoisLookup(ActionBase):
""" Whois Lookup action
Note: the action name is the class name
"""
def __init__(self, pagename, request):
ActionBase.__init__(self, pagename, request)
self.use_ticket = False
_ = self._
self.form_trigger = 'domaininame'
self.form_trigger_label = _('Whois Lookup')
def do_action(self):
_ = self._
form = self.form
domainname = form.get('domain', [u''])[0]
defaultserver='whois.verisign-grs.net'#'whois.networksolutions.com'
whoiscommand=""
whoismap={
'org' : 'whois.pir.org' , \
'edu' : 'whois.networksolutions.com' , \
'biz' : 'whois.biz' , \
'info': 'whois.afilias.info' , \
'eu': 'whois.eu' , \
'mobi': 'whois.dotmobiregistry.net' , \
'us' : 'whois.nic.us', \
'de' : 'whois.denic.de' , \
'gov' : 'whois.nic.gov' , \
'name': 'whois.nic.name' , \
'pro': 'whois.nic.name' , \
'museum': 'whois.museum' , \
'int': 'whois.iana.org' , \
'aero': 'whois.information.aero' , \
'coop': 'whois.nic.coop' , \
# See http://www.nic.gov/cgi-bin/whois
'mil' : 'whois.nic.mil' , \
# See http://www.nic.mil/cgi-bin/whois
'ca' : 'whois.cdnnet.ca' , \
'uk' : 'whois.nic.uk' , \
'au' : 'whois.aunic.net' , \
'hu' : 'whois.nic.hu' , \
# All the following are unverified/checked.
'be' : 'whois.ripe.net',
'it' : 'whois.ripe.net' , \
# also whois.nic.it
'at' : 'whois.ripe.net' , \
# also www.nic.at, whois.aco.net
'dk' : 'whois.ripe.net' , \
'fo' : 'whois.ripe.net' , \
'lt' : 'whois.ripe.net' , \
'no' : 'whois.ripe.net' , \
'sj' : 'whois.ripe.net' , \
'sk' : 'whois.ripe.net' , \
'tr' : 'whois.ripe.net' , \
# also whois.metu.edu.tr
'il' : 'whois.ripe.net' , \
'bv' : 'whois.ripe.net' , \
'se' : 'whois.nic-se.se' , \
'br' : 'whois.nic.br' , \
'fr' : 'whois.nic.fr' , \
'sg' : 'whois.nic.net.sg' , \
'hm' : 'whois.registry.hm' , \
# see also whois.nic.hm
'nz' : 'domainz.waikato.ac.nz' , \
'nl' : 'whois.domain-registry.nl' , \
# RIPE also handles other countries
# See http://www.ripe.net/info/ncc/rir-areas.html
'ru' : 'whois.ripn.net' , \
'ch' : 'whois.nic.ch' , \
# see http://www.nic.ch/whois_readme.html
'jp' : 'whois.nic.ad.jp' , \
'to' : 'whois.tonic.to' , \
'nu' : 'whois.nic.nu' , \
'fm' : 'www.dot.fm' , \
# http request http://www.dot.fm/search.html
'am' : 'whois.nic.am' , \
'nu' : 'www.nunames.nu' , \
'af' : 'whois.nic.af' , \
'as' : 'whois.nic.as' , \
'li' : 'whois.nic.li' , \
'lk' : 'whois.nic.lk' , \
'mx' : 'whois.nic.mx' , \
'pw' : 'whois.nic.pw' , \
'sh' : 'whois.nic.sh' , \
# consistently resets connection
'tj' : 'whois.nic.tj' , \
'tm' : 'whois.nic.tm' , \
'pt' : 'whois.dns.pt' , \
'kr' : 'whois.nic.or.kr' , \
# see also whois.krnic.net
'kz' : 'whois.nic.or.kr' , \
# see also whois.krnic.net
'al' : 'whois.ripe.net' , \
'az' : 'whois.ripe.net' , \
'ba' : 'whois.ripe.net' , \
'bg' : 'whois.ripe.net' , \
'by' : 'whois.ripe.net' , \
'cy' : 'whois.ripe.net' , \
'cz' : 'whois.ripe.net' , \
'dz' : 'whois.ripe.net' , \
'ee' : 'whois.ripe.net' , \
'eg' : 'whois.ripe.net' , \
'es' : 'whois.ripe.net' , \
'fi' : 'whois.ripe.net' , \
'gr' : 'whois.ripe.net' , \
'hr' : 'whois.ripe.net' , \
'lu' : 'whois.ripe.net' , \
'lv' : 'whois.ripe.net' , \
'ma' : 'whois.ripe.net' , \
'md' : 'whois.ripe.net' , \
'mk' : 'whois.ripe.net' , \
'mt' : 'whois.ripe.net' , \
'pl' : 'whois.ripe.net' , \
'ro' : 'whois.ripe.net' , \
'si' : 'whois.ripe.net' , \
'sm' : 'whois.ripe.net' , \
'su' : 'whois.ripe.net' , \
'tn' : 'whois.ripe.net' , \
'ua' : 'whois.ripe.net' , \
'va' : 'whois.ripe.net' , \
'yu' : 'whois.ripe.net' , \
'ac' : 'whois.nic.ac' , \
'cc' : 'whois.nic.cc' , \
'gs' : 'whois.adamsnames.tc' , \
'hk' : 'whois.apnic.net' , \
'ms' : 'whois.adamsnames.tc' , \
'my' : 'whois.mynic.net' , \
'st' : 'whois.nic.st' , \
'tc' : 'whois.adamsnames.tc' , \
'tf' : 'whois.adamsnames.tc' , \
'th' : 'whois.thnic.net' , \
'tw' : 'whois.twnic.net' , \
'us' : 'whois.isi.edu' , \
'vg' : 'whois.adamsnames.tc' , \
}
defaultipwhois='whois.arin.net'
ipwhoismap={
41 : 'whois.afrinic.net' , \
58 : 'whois.apnic.net' , \
59 : 'whois.apnic.net' , \
60 : 'whois.apnic.net' , \
61 : 'whois.apnic.net' , \
62 : 'whois.ripe.net' , \
77 : 'whois.ripe.net' , \
78 : 'whois.ripe.net' , \
79 : 'whois.ripe.net' , \
80 : 'whois.ripe.net' , \
81 : 'whois.ripe.net' , \
82 : 'whois.ripe.net' , \
83 : 'whois.ripe.net' , \
84 : 'whois.ripe.net' , \
85 : 'whois.ripe.net' , \
86 : 'whois.ripe.net' , \
87 : 'whois.ripe.net' , \
88 : 'whois.ripe.net' , \
89 : 'whois.ripe.net' , \
90 : 'whois.ripe.net' , \
91 : 'whois.ripe.net' , \
92 : 'whois.ripe.net' , \
93 : 'whois.ripe.net' , \
116 : 'whois.apnic.net' , \
117 : 'whois.apnic.net' , \
118 : 'whois.apnic.net' , \
119 : 'whois.apnic.net' , \
120 : 'whois.apnic.net' , \
121 : 'whois.apnic.net' , \
122 : 'whois.apnic.net' , \
123 : 'whois.apnic.net' , \
124 : 'whois.apnic.net' , \
125 : 'whois.apnic.net' , \
126 : 'whois.apnic.net' , \
189 : 'whois.lacnic.net' , \
190 : 'whois.lacnic.net' , \
193 : 'whois.ripe.net' , \
194 : 'whois.ripe.net' , \
195 : 'whois.ripe.net' , \
196 : 'whois.afrinic.net' , \
200 : 'whois.lacnic.net' , \
201 : 'whois.lacnic.net' , \
202 : 'whois.apnic.net' , \
203 : 'whois.apnic.net' , \
210 : 'whois.apnic.net' , \
211 : 'whois.apnic.net' , \
212 : 'whois.ripe.net' , \
213 : 'whois.ripe.net' , \
217 : 'whois.ripe.net' , \
218 : 'whois.apnic.net' , \
219 : 'whois.apnic.net' , \
220 : 'whois.apnic.net' , \
221 : 'whois.apnic.net' , \
222 : 'whois.apnic.net' , \
}
ipregex = re.compile('^(\d{1,3}\.){3}\d{1,3}$')
if ipregex.match(domainname):
addressblock = string.split(domainname, ".")[0]
whoisserver = ipwhoismap.get(int(addressblock))
if whoisserver==None:
whoisserver=defaultipwhois
else:
toplevel = string.split(domainname, ".")[-1]
whoisserver=whoismap.get(toplevel)
if whoisserver==None:
whoisserver=defaultserver
whoiscommand="domain "
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, e:
print "Strange error creating socket: %s" % e
while 1:
try:
s.connect((whoisserver, 43))
except socket.error, (ecode, reason):
if ecode==errno.EINPROGRESS:
continue
elif ecode==errno.EALREADY:
continue
else:
raise socket.error, (ecode, reason)
pass
break
s.send(whoiscommand + domainname + "\r\n")
page = "Data downloaded from: " + whoisserver + "\n\n"
while 1:
data = s.recv(8196)
if not data: break
page = page + data
pass
s.close()
return True, page
def do_action_finish(self, success):
if success:
self.request.formatter = Formatter(self.request)
self.request.http_headers()
self.request.setContentLanguage(self.request.lang)
wikiutil.send_title(self.request, self.pagename, pagename=self.pagename)
self.request.write(self.request.formatter.startContent("content"))
self.request.write(self.request.formatter.rawHTML("<pre>" + self.error + "</pre>"))
self.request.write(self.request.formatter.endContent())
wikiutil.send_footer(self.request, self.pagename)
else:
self.render_msg(self.make_form())
def get_form_html(self, buttons_html):
_ = self._
d = {
'pagename': self.pagename,
'domain_label': _("Domain / IP"),
'buttons_html': buttons_html,
}
return '''
<table>
<tr>
<td class="label"><label>%(domain_label)s</label></td>
<td class="content">
<input type="text" name="domain" maxlength="200">
</td>
</tr>
<tr>
<td></td>
<td class="buttons">
%(buttons_html)s
</td>
</tr>
</table>
''' % d
def render(self):
""" Render action - this is the main function called by action's
execute() function.
We usually render a form here, check for posted forms, etc.
"""
_ = self._
form = self.form
if form.has_key(self.form_cancel):
self.render_cancel()
return
# Validate allowance, user rights and other conditions.
error = None
if self.is_excluded():
error = _('Action %(actionname)s is excluded in this wiki!') % {'actionname': self.actionname }
elif not self.is_allowed():
error = _('You are not allowed to use action %(actionname)s on thispage!') % {'actionname': self.actionname }
if error is None:
error = self.check_condition()
if error:
self.render_msg(error)
elif form.has_key(self.form_trigger) or form.has_key('domain'): # user hit the trigger button
if self.ticket_ok():
success, self.error = self.do_action()
else:
success = False
self.error = _('Please use the interactive user interface to use action %(actionname)s!') % {'actionname': self.actionname }
self.do_action_finish(success)
else:
# Return a new form
self.render_msg(self.make_form())
def execute(pagename, request):
""" Glue code for actions """
_ = request.getText
thispage = Page(request, pagename)
if request.user.valid:
username = request.user.name
else:
username = ''
if not username:
return thispage.send_page(request,
msg = _('Please log in first.'))
WhoisLookup(pagename, request).render()