whois/whois.py
changeset 60 7801a420f679
parent 52 1f80f6dec7ac
child 62 fc06c601b875
equal deleted inserted replaced
59:f1e5214a1b16 60:7801a420f679
    22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    25 THE SOFTWARE.
    25 THE SOFTWARE.
    26 
    26 
    27   Last edited by:  $Author$
       
    28               on:  $DateTime$
       
    29         Revision:  $Revision$
       
    30               Id:  $Id$
       
    31           Author:  Chris Wolf
       
    32 """
    27 """
    33 import sys
    28 import sys
    34 import socket
    29 import socket
    35 import optparse
    30 import optparse
    36 # import pdb
       
    37 
    31 
    38 
    32 
    39 def enforce_ascii(a):
    33 def enforce_ascii(a):
    40     if isinstance(a, str) or isinstance(a, unicode):
    34     if isinstance(a, str) or isinstance(a, unicode):
    41         # return a.encode('ascii', 'replace')
       
    42         r = ""
    35         r = ""
    43         for i in a:
    36         for i in a:
    44             if ord(i) >= 128:
    37             if ord(i) >= 128:
    45                 r += "?"
    38                 r += "?"
    46             else:
    39             else:
    82 
    75 
    83     def findwhois_server(self, buf, hostname):
    76     def findwhois_server(self, buf, hostname):
    84         """Search the initial TLD lookup results for the regional-specifc
    77         """Search the initial TLD lookup results for the regional-specifc
    85         whois server for getting contact details.
    78         whois server for getting contact details.
    86         """
    79         """
    87         # print 'finding whois server'
       
    88         # print 'parameters:', buf, 'hostname', hostname
       
    89         nhost = None
    80         nhost = None
    90         parts_index = 1
    81         parts_index = 1
    91         start = buf.find(NICClient.WHOIS_SERVER_ID)
    82         start = buf.find(NICClient.WHOIS_SERVER_ID)
    92         # print 'start', start
       
    93         if (start == -1):
    83         if (start == -1):
    94             start = buf.find(NICClient.WHOIS_ORG_SERVER_ID)
    84             start = buf.find(NICClient.WHOIS_ORG_SERVER_ID)
    95             parts_index = 2
    85             parts_index = 2
    96 
    86 
    97         if (start > -1):
    87         if (start > -1):
    98             end = buf[start:].find('\n')
    88             end = buf[start:].find('\n')
    99             # print 'end:', end
       
   100             whois_line = buf[start:end+start]
    89             whois_line = buf[start:end+start]
   101             # print 'whois_line', whois_line
       
   102             nhost = whois_line.split(NICClient.WHOIS_SERVER_ID+' ').pop()
    90             nhost = whois_line.split(NICClient.WHOIS_SERVER_ID+' ').pop()
   103             nhost = nhost.split('http://').pop()
    91             nhost = nhost.split('http://').pop()
   104             # if the whois address is domain.tld/something then
    92             # if the whois address is domain.tld/something then
   105             # s.connect((hostname, 43)) does not work
    93             # s.connect((hostname, 43)) does not work
   106             if nhost.count('/') > 0:
    94             if nhost.count('/') > 0:
   107                 nhost = None
    95                 nhost = None
   108             # print 'nhost:',nhost
       
   109         elif (hostname == NICClient.ANICHOST):
    96         elif (hostname == NICClient.ANICHOST):
   110             for nichost in NICClient.ip_whois:
    97             for nichost in NICClient.ip_whois:
   111                 if (buf.find(nichost) != -1):
    98                 if (buf.find(nichost) != -1):
   112                     nhost = nichost
    99                     nhost = nichost
   113                     break
   100                     break
   117         """Perform initial lookup with TLD whois server
   104         """Perform initial lookup with TLD whois server
   118         then, if the quick flag is false, search that result
   105         then, if the quick flag is false, search that result
   119         for the region-specifc whois server and do a lookup
   106         for the region-specifc whois server and do a lookup
   120         there for contact details
   107         there for contact details
   121         """
   108         """
   122         # print 'Performing the whois'
       
   123         # print 'parameters given:', query, hostname, flags
       
   124         # pdb.set_trace()
       
   125         try:
   109         try:
   126           s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   110           s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   127           s.settimeout(2)
   111           s.settimeout(2)
   128           s.connect((hostname, 43))
   112           s.connect((hostname, 43))
   129           """send takes bytes as an input
   113           """send takes bytes as an input
   130           """
   114           """
   131           queryBytes = None
   115           queryBytes = None
   132           if type(query) is not unicode:
   116           if type(query) is not unicode:
   133               query = query.decode('utf-8')
   117               query = query.decode('utf-8')
   134 
   118 
   135           if (hostname == NICClient.DENICHOST):
   119           if hostname == NICClient.DENICHOST:
   136               # print 'the domain is in NIC DENIC'
       
   137               queryBytes = ("-T dn,ace -C UTF-8 " + query + "\r\n").encode('idna')
   120               queryBytes = ("-T dn,ace -C UTF-8 " + query + "\r\n").encode('idna')
   138               # print 'queryBytes:', queryBytes
   121           elif hostname == 'com.whois-servers.net':
       
   122               queryBytes = ('=' + query + "\r\n").encode('idna')
   139           else:
   123           else:
   140               queryBytes = (query + "\r\n").encode('idna')
   124               queryBytes = (query + "\r\n").encode('idna')
   141           s.send(queryBytes)
   125           s.send(queryBytes)
   142           """recv returns bytes
   126           """recv returns bytes
   143           """
   127           """
   144           # print s
       
   145           response = b''
   128           response = b''
   146           while True:
   129           while True:
   147               d = s.recv(4096)
   130               d = s.recv(4096)
   148               response += d
   131               response += d
   149               if not d:
   132               if not d:
   150                   break
   133                   break
   151           s.close()
   134           s.close()
   152         except socket.error as socketerror:
   135         except socket.error as socketerror:
   153           print("Error: ", socketerror)
   136           print "Error: ", socketerror
   154         # pdb.set_trace()
       
   155         nhost = None
   137         nhost = None
   156         # print 'response', response
       
   157         response = enforce_ascii(response)
   138         response = enforce_ascii(response)
   158         if (flags & NICClient.WHOIS_RECURSE and nhost is None):
   139         if (flags & NICClient.WHOIS_RECURSE and nhost is None):
   159             # print 'Inside first if'
       
   160             nhost = self.findwhois_server(response.decode(), hostname)
   140             nhost = self.findwhois_server(response.decode(), hostname)
   161             # print 'nhost is:', nhost
       
   162         if (nhost is not None):
   141         if (nhost is not None):
   163             # print 'inside second if'
       
   164             response += self.whois(query, nhost, 0)
   142             response += self.whois(query, nhost, 0)
   165             # print 'response', response
       
   166         # print 'returning whois response'
       
   167         return response.decode()
   143         return response.decode()
   168 
   144 
   169     def choose_server(self, domain):
   145     def choose_server(self, domain):
   170         """Choose initial lookup NIC host"""
   146         """Choose initial lookup NIC host"""
   171         if type(domain) is not unicode:
   147         if type(domain) is not unicode:
   184     def whois_lookup(self, options, query_arg, flags):
   160     def whois_lookup(self, options, query_arg, flags):
   185         """Main entry point: Perform initial lookup on TLD whois server,
   161         """Main entry point: Perform initial lookup on TLD whois server,
   186         or other server to get region-specific whois server, then if quick
   162         or other server to get region-specific whois server, then if quick
   187         flag is false, perform a second lookup on the region-specific
   163         flag is false, perform a second lookup on the region-specific
   188         server for contact records"""
   164         server for contact records"""
   189         # print 'whois_lookup'
       
   190         nichost = None
   165         nichost = None
   191         # pdb.set_trace()
       
   192         # whoud happen when this function is called by other than main
   166         # whoud happen when this function is called by other than main
   193         if (options is None):
   167         if options is None:
   194             options = {}
   168             options = {}
   195 
   169 
   196         if (('whoishost' not in options or options['whoishost'] is None)
   170         if (('whoishost' not in options or options['whoishost'] is None)
   197                 and ('country' not in options or options['country'] is None)):
   171                 and ('country' not in options or options['country'] is None)):
   198             self.use_qnichost = True
   172             self.use_qnichost = True
   199             options['whoishost'] = NICClient.NICHOST
   173             options['whoishost'] = NICClient.NICHOST
   200             if (not (flags & NICClient.WHOIS_QUICK)):
   174             if (not (flags & NICClient.WHOIS_QUICK)):
   201                 flags |= NICClient.WHOIS_RECURSE
   175                 flags |= NICClient.WHOIS_RECURSE
   202 
   176 
   203         if ('country' in options and options['country'] is not None):
   177         if 'country' in options and options['country'] is not None:
   204             result = self.whois(
   178             result = self.whois(
   205                 query_arg,
   179                 query_arg,
   206                 options['country'] + NICClient.QNICHOST_TAIL,
   180                 options['country'] + NICClient.QNICHOST_TAIL,
   207                 flags
   181                 flags
   208             )
   182             )
   209         elif (self.use_qnichost):
   183         elif self.use_qnichost:
   210             nichost = self.choose_server(query_arg)
   184             nichost = self.choose_server(query_arg)
   211             if (nichost is not None):
   185             if (nichost is not None):
   212                 result = self.whois(query_arg, nichost, flags)
   186                 result = self.whois(query_arg, nichost, flags)
   213             else:
   187             else:
   214                 result = ''
   188                 result = ''
   215         else:
   189         else:
   216             result = self.whois(query_arg, options['whoishost'], flags)
   190             result = self.whois(query_arg, options['whoishost'], flags)
   217         # print 'whois_lookup finished'
       
   218         return result
   191         return result
   219 
   192 
   220 
   193 
   221 def parse_command_line(argv):
   194 def parse_command_line(argv):
   222     """Options handling mostly follows the UNIX whois(1) man page, except
   195     """Options handling mostly follows the UNIX whois(1) man page, except
   283     flags = 0
   256     flags = 0
   284     nic_client = NICClient()
   257     nic_client = NICClient()
   285     (options, args) = parse_command_line(sys.argv)
   258     (options, args) = parse_command_line(sys.argv)
   286     if (options.b_quicklookup is True):
   259     if (options.b_quicklookup is True):
   287         flags = flags | NICClient.WHOIS_QUICK
   260         flags = flags | NICClient.WHOIS_QUICK
   288     print(nic_client.whois_lookup(options.__dict__, args[1], flags))
   261     print nic_client.whois_lookup(options.__dict__, args[1], flags)