whois/whois.py
author Richard Penman
Tue, 01 Sep 2015 11:52:23 +0800
changeset 57 1f14b45214eb
parent 52 1f80f6dec7ac
child 60 7801a420f679
permissions -rw-r--r--
added rf class issue #72
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
     1
"""
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
     2
Whois client for python
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
     3
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
     4
transliteration of:
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
     5
http://www.opensource.apple.com/source/adv_cmds/adv_cmds-138.1/whois/whois.c
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
     6
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
     7
Copyright (c) 2010 Chris Wolf
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
     8
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
     9
Permission is hereby granted, free of charge, to any person obtaining a copy
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    10
of this software and associated documentation files (the "Software"), to deal
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    11
in the Software without restriction, including without limitation the rights
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    12
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    13
copies of the Software, and to permit persons to whom the Software is
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    14
furnished to do so, subject to the following conditions:
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    15
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    16
The above copyright notice and this permission notice shall be included in
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    17
all copies or substantial portions of the Software.
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    18
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    19
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    20
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    21
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    22
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    23
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    24
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    25
THE SOFTWARE.
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    26
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    27
  Last edited by:  $Author$
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    28
              on:  $DateTime$
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    29
        Revision:  $Revision$
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    30
              Id:  $Id$
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    31
          Author:  Chris Wolf
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    32
"""
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    33
import sys
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    34
import socket
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    35
import optparse
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    36
# import pdb
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    37
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    38
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
    39
def enforce_ascii(a):
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
    40
    if isinstance(a, str) or isinstance(a, unicode):
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
    41
        # return a.encode('ascii', 'replace')
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
    42
        r = ""
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
    43
        for i in a:
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
    44
            if ord(i) >= 128:
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
    45
                r += "?"
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
    46
            else:
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
    47
                r += i
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
    48
        return r
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
    49
    else:
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
    50
        return a
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    51
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    52
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    53
class NICClient(object):
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    54
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    55
    ABUSEHOST = "whois.abuse.net"
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    56
    NICHOST = "whois.crsnic.net"
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    57
    INICHOST = "whois.networksolutions.com"
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    58
    DNICHOST = "whois.nic.mil"
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    59
    GNICHOST = "whois.nic.gov"
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    60
    ANICHOST = "whois.arin.net"
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    61
    LNICHOST = "whois.lacnic.net"
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    62
    RNICHOST = "whois.ripe.net"
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    63
    PNICHOST = "whois.apnic.net"
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    64
    MNICHOST = "whois.ra.net"
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    65
    QNICHOST_TAIL = ".whois-servers.net"
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    66
    SNICHOST = "whois.6bone.net"
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    67
    BNICHOST = "whois.registro.br"
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    68
    NORIDHOST = "whois.norid.no"
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    69
    IANAHOST = "whois.iana.org"
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    70
    DENICHOST = "de.whois-servers.net"
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    71
    DEFAULT_PORT = "nicname"
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    72
    WHOIS_SERVER_ID = "Whois Server:"
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    73
    WHOIS_ORG_SERVER_ID = "Registrant Street1:Whois Server:"
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    74
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    75
    WHOIS_RECURSE = 0x01
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    76
    WHOIS_QUICK = 0x02
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    77
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    78
    ip_whois = [LNICHOST, RNICHOST, PNICHOST, BNICHOST]
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    79
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    80
    def __init__(self):
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    81
        self.use_qnichost = False
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    82
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    83
    def findwhois_server(self, buf, hostname):
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    84
        """Search the initial TLD lookup results for the regional-specifc
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    85
        whois server for getting contact details.
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    86
        """
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    87
        # print 'finding whois server'
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    88
        # print 'parameters:', buf, 'hostname', hostname
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    89
        nhost = None
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    90
        parts_index = 1
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    91
        start = buf.find(NICClient.WHOIS_SERVER_ID)
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    92
        # print 'start', start
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    93
        if (start == -1):
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    94
            start = buf.find(NICClient.WHOIS_ORG_SERVER_ID)
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    95
            parts_index = 2
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    96
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    97
        if (start > -1):
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
    98
            end = buf[start:].find('\n')
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
    99
            # print 'end:', end
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   100
            whois_line = buf[start:end+start]
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   101
            # print 'whois_line', whois_line
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   102
            nhost = whois_line.split(NICClient.WHOIS_SERVER_ID+' ').pop()
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   103
            nhost = nhost.split('http://').pop()
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   104
            # if the whois address is domain.tld/something then
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   105
            # s.connect((hostname, 43)) does not work
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   106
            if nhost.count('/') > 0:
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   107
                nhost = None
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   108
            # print 'nhost:',nhost
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   109
        elif (hostname == NICClient.ANICHOST):
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   110
            for nichost in NICClient.ip_whois:
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   111
                if (buf.find(nichost) != -1):
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   112
                    nhost = nichost
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   113
                    break
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   114
        return nhost
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   115
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   116
    def whois(self, query, hostname, flags):
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   117
        """Perform initial lookup with TLD whois server
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   118
        then, if the quick flag is false, search that result
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   119
        for the region-specifc whois server and do a lookup
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   120
        there for contact details
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   121
        """
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   122
        # print 'Performing the whois'
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   123
        # print 'parameters given:', query, hostname, flags
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   124
        # pdb.set_trace()
52
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   125
        try:
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   126
          s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   127
          s.settimeout(2)
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   128
          s.connect((hostname, 43))
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   129
          """send takes bytes as an input
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   130
          """
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   131
          queryBytes = None
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   132
          if type(query) is not unicode:
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   133
              query = query.decode('utf-8')
34
f9da616f15cf Pass all domains through encode('idna') in NICClient
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 32
diff changeset
   134
52
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   135
          if (hostname == NICClient.DENICHOST):
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   136
              # print 'the domain is in NIC DENIC'
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   137
              queryBytes = ("-T dn,ace -C UTF-8 " + query + "\r\n").encode('idna')
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   138
              # print 'queryBytes:', queryBytes
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   139
          else:
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   140
              queryBytes = (query + "\r\n").encode('idna')
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   141
          s.send(queryBytes)
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   142
          """recv returns bytes
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   143
          """
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   144
          # print s
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   145
          response = b''
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   146
          while True:
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   147
              d = s.recv(4096)
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   148
              response += d
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   149
              if not d:
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   150
                  break
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   151
          s.close()
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   152
        except socket.error as socketerror:
1f80f6dec7ac add socket timeout exception
Jasey Wang <jaseywang@gmail.com>
parents: 45
diff changeset
   153
          print("Error: ", socketerror)
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   154
        # pdb.set_trace()
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   155
        nhost = None
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   156
        # print 'response', response
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   157
        response = enforce_ascii(response)
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   158
        if (flags & NICClient.WHOIS_RECURSE and nhost is None):
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   159
            # print 'Inside first if'
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   160
            nhost = self.findwhois_server(response.decode(), hostname)
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   161
            # print 'nhost is:', nhost
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   162
        if (nhost is not None):
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   163
            # print 'inside second if'
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   164
            response += self.whois(query, nhost, 0)
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   165
            # print 'response', response
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   166
        # print 'returning whois response'
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   167
        return response.decode()
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   168
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   169
    def choose_server(self, domain):
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   170
        """Choose initial lookup NIC host"""
36
af839b9c0ed1 Add support for punycode TLDs
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 34
diff changeset
   171
        if type(domain) is not unicode:
af839b9c0ed1 Add support for punycode TLDs
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 34
diff changeset
   172
            domain = domain.decode('utf-8').encode('idna')
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   173
        if (domain.endswith("-NORID")):
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   174
            return NICClient.NORIDHOST
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   175
        pos = domain.rfind('.')
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   176
        if (pos == -1):
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   177
            return None
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   178
        tld = domain[pos+1:]
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   179
        if (tld[0].isdigit()):
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   180
            return NICClient.ANICHOST
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   181
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   182
        return tld + NICClient.QNICHOST_TAIL
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   183
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   184
    def whois_lookup(self, options, query_arg, flags):
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   185
        """Main entry point: Perform initial lookup on TLD whois server,
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   186
        or other server to get region-specific whois server, then if quick
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   187
        flag is false, perform a second lookup on the region-specific
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   188
        server for contact records"""
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   189
        # print 'whois_lookup'
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   190
        nichost = None
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   191
        # pdb.set_trace()
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   192
        # whoud happen when this function is called by other than main
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   193
        if (options is None):
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   194
            options = {}
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   195
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   196
        if (('whoishost' not in options or options['whoishost'] is None)
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   197
                and ('country' not in options or options['country'] is None)):
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   198
            self.use_qnichost = True
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   199
            options['whoishost'] = NICClient.NICHOST
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   200
            if (not (flags & NICClient.WHOIS_QUICK)):
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   201
                flags |= NICClient.WHOIS_RECURSE
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   202
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   203
        if ('country' in options and options['country'] is not None):
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   204
            result = self.whois(
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   205
                query_arg,
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   206
                options['country'] + NICClient.QNICHOST_TAIL,
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   207
                flags
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   208
            )
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   209
        elif (self.use_qnichost):
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   210
            nichost = self.choose_server(query_arg)
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   211
            if (nichost is not None):
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   212
                result = self.whois(query_arg, nichost, flags)
45
52ce01013731 Handle experimental lookup method for bad domains
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 36
diff changeset
   213
            else:
52ce01013731 Handle experimental lookup method for bad domains
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 36
diff changeset
   214
                result = ''
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   215
        else:
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   216
            result = self.whois(query_arg, options['whoishost'], flags)
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   217
        # print 'whois_lookup finished'
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   218
        return result
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   219
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   220
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   221
def parse_command_line(argv):
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   222
    """Options handling mostly follows the UNIX whois(1) man page, except
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   223
    long-form options can also be used.
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   224
    """
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   225
    flags = 0
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   226
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   227
    usage = "usage: %prog [options] name"
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   228
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   229
    parser = optparse.OptionParser(add_help_option=False, usage=usage)
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   230
    parser.add_option("-a", "--arin", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   231
                      const=NICClient.ANICHOST, dest="whoishost",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   232
                      help="Lookup using host " + NICClient.ANICHOST)
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   233
    parser.add_option("-A", "--apnic", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   234
                      const=NICClient.PNICHOST, dest="whoishost",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   235
                      help="Lookup using host " + NICClient.PNICHOST)
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   236
    parser.add_option("-b", "--abuse", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   237
                      const=NICClient.ABUSEHOST, dest="whoishost",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   238
                      help="Lookup using host " + NICClient.ABUSEHOST)
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   239
    parser.add_option("-c", "--country", action="store",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   240
                      type="string", dest="country",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   241
                      help="Lookup using country-specific NIC")
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   242
    parser.add_option("-d", "--mil", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   243
                      const=NICClient.DNICHOST, dest="whoishost",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   244
                      help="Lookup using host " + NICClient.DNICHOST)
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   245
    parser.add_option("-g", "--gov", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   246
                      const=NICClient.GNICHOST, dest="whoishost",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   247
                      help="Lookup using host " + NICClient.GNICHOST)
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   248
    parser.add_option("-h", "--host", action="store",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   249
                      type="string", dest="whoishost",
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   250
                      help="Lookup using specified whois host")
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   251
    parser.add_option("-i", "--nws", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   252
                      const=NICClient.INICHOST, dest="whoishost",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   253
                      help="Lookup using host " + NICClient.INICHOST)
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   254
    parser.add_option("-I", "--iana", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   255
                      const=NICClient.IANAHOST, dest="whoishost",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   256
                      help="Lookup using host " + NICClient.IANAHOST)
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   257
    parser.add_option("-l", "--lcanic", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   258
                      const=NICClient.LNICHOST, dest="whoishost",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   259
                      help="Lookup using host " + NICClient.LNICHOST)
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   260
    parser.add_option("-m", "--ra", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   261
                      const=NICClient.MNICHOST, dest="whoishost",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   262
                      help="Lookup using host " + NICClient.MNICHOST)
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   263
    parser.add_option("-p", "--port", action="store",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   264
                      type="int", dest="port",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   265
                      help="Lookup using specified tcp port")
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   266
    parser.add_option("-Q", "--quick", action="store_true",
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   267
                      dest="b_quicklookup",
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   268
                      help="Perform quick lookup")
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   269
    parser.add_option("-r", "--ripe", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   270
                      const=NICClient.RNICHOST, dest="whoishost",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   271
                      help="Lookup using host " + NICClient.RNICHOST)
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   272
    parser.add_option("-R", "--ru", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   273
                      const="ru", dest="country",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   274
                      help="Lookup Russian NIC")
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   275
    parser.add_option("-6", "--6bone", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   276
                      const=NICClient.SNICHOST, dest="whoishost",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   277
                      help="Lookup using host " + NICClient.SNICHOST)
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   278
    parser.add_option("-?", "--help", action="help")
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   279
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   280
    return parser.parse_args(argv)
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   281
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   282
if __name__ == "__main__":
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   283
    flags = 0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   284
    nic_client = NICClient()
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   285
    (options, args) = parse_command_line(sys.argv)
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   286
    if (options.b_quicklookup is True):
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   287
        flags = flags | NICClient.WHOIS_QUICK
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   288
    print(nic_client.whois_lookup(options.__dict__, args[1], flags))