whois/whois.py
author Evgeni Kunev <evgeni.kunev@gmail.com>
Mon, 10 Nov 2014 13:42:37 +0200
changeset 45 52ce01013731
parent 36 af839b9c0ed1
child 52 1f80f6dec7ac
permissions -rw-r--r--
Handle experimental lookup method for bad domains Attempting to use NICClient with bad domains could hit a bad logical path that leads to an attempt to reference a variable that hasn't been defined. So in case we don't manage to find a nichost for a domain, just set `result` to `None`
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()
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   125
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   126
        s.connect((hostname, 43))
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   127
        """send takes bytes as an input
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   128
        """
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   129
        queryBytes = None
34
f9da616f15cf Pass all domains through encode('idna') in NICClient
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 32
diff changeset
   130
        if type(query) is not unicode:
f9da616f15cf Pass all domains through encode('idna') in NICClient
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 32
diff changeset
   131
            query = query.decode('utf-8')
f9da616f15cf Pass all domains through encode('idna') in NICClient
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 32
diff changeset
   132
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   133
        if (hostname == NICClient.DENICHOST):
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   134
            # print 'the domain is in NIC DENIC'
34
f9da616f15cf Pass all domains through encode('idna') in NICClient
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 32
diff changeset
   135
            queryBytes = ("-T dn,ace -C UTF-8 " + query + "\r\n").encode('idna')
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   136
            # print 'queryBytes:', queryBytes
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   137
        else:
34
f9da616f15cf Pass all domains through encode('idna') in NICClient
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 32
diff changeset
   138
            queryBytes = (query + "\r\n").encode('idna')
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   139
        s.send(queryBytes)
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   140
        """recv returns bytes
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   141
        """
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   142
        # print s
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   143
        response = b''
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   144
        while True:
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   145
            d = s.recv(4096)
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   146
            response += d
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   147
            if not d:
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   148
                break
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   149
        s.close()
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   150
        # pdb.set_trace()
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   151
        nhost = None
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   152
        # print 'response', response
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   153
        response = enforce_ascii(response)
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   154
        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
   155
            # print 'Inside first if'
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   156
            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
   157
            # print 'nhost is:', nhost
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   158
        if (nhost is not None):
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   159
            # print 'inside second if'
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   160
            response += self.whois(query, nhost, 0)
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   161
            # print 'response', response
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   162
        # print 'returning whois response'
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   163
        return response.decode()
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   164
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   165
    def choose_server(self, domain):
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   166
        """Choose initial lookup NIC host"""
36
af839b9c0ed1 Add support for punycode TLDs
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 34
diff changeset
   167
        if type(domain) is not unicode:
af839b9c0ed1 Add support for punycode TLDs
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 34
diff changeset
   168
            domain = domain.decode('utf-8').encode('idna')
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   169
        if (domain.endswith("-NORID")):
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   170
            return NICClient.NORIDHOST
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   171
        pos = domain.rfind('.')
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   172
        if (pos == -1):
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   173
            return None
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   174
        tld = domain[pos+1:]
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   175
        if (tld[0].isdigit()):
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   176
            return NICClient.ANICHOST
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   177
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   178
        return tld + NICClient.QNICHOST_TAIL
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   179
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   180
    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
   181
        """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
   182
        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
   183
        flag is false, perform a second lookup on the region-specific
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   184
        server for contact records"""
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   185
        # print 'whois_lookup'
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   186
        nichost = None
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   187
        # pdb.set_trace()
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   188
        # 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
   189
        if (options is None):
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   190
            options = {}
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   191
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   192
        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
   193
                and ('country' not in options or options['country'] is None)):
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   194
            self.use_qnichost = True
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   195
            options['whoishost'] = NICClient.NICHOST
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   196
            if (not (flags & NICClient.WHOIS_QUICK)):
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   197
                flags |= NICClient.WHOIS_RECURSE
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   198
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   199
        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
   200
            result = self.whois(
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   201
                query_arg,
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   202
                options['country'] + NICClient.QNICHOST_TAIL,
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   203
                flags
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   204
            )
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   205
        elif (self.use_qnichost):
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   206
            nichost = self.choose_server(query_arg)
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   207
            if (nichost is not None):
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   208
                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
   209
            else:
52ce01013731 Handle experimental lookup method for bad domains
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 36
diff changeset
   210
                result = ''
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   211
        else:
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   212
            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
   213
        # print 'whois_lookup finished'
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   214
        return result
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   215
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   216
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   217
def parse_command_line(argv):
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   218
    """Options handling mostly follows the UNIX whois(1) man page, except
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   219
    long-form options can also be used.
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   220
    """
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   221
    flags = 0
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   222
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   223
    usage = "usage: %prog [options] name"
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   224
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   225
    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
   226
    parser.add_option("-a", "--arin", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   227
                      const=NICClient.ANICHOST, dest="whoishost",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   228
                      help="Lookup using host " + NICClient.ANICHOST)
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   229
    parser.add_option("-A", "--apnic", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   230
                      const=NICClient.PNICHOST, dest="whoishost",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   231
                      help="Lookup using host " + NICClient.PNICHOST)
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   232
    parser.add_option("-b", "--abuse", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   233
                      const=NICClient.ABUSEHOST, dest="whoishost",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   234
                      help="Lookup using host " + NICClient.ABUSEHOST)
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   235
    parser.add_option("-c", "--country", action="store",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   236
                      type="string", dest="country",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   237
                      help="Lookup using country-specific NIC")
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   238
    parser.add_option("-d", "--mil", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   239
                      const=NICClient.DNICHOST, dest="whoishost",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   240
                      help="Lookup using host " + NICClient.DNICHOST)
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   241
    parser.add_option("-g", "--gov", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   242
                      const=NICClient.GNICHOST, dest="whoishost",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   243
                      help="Lookup using host " + NICClient.GNICHOST)
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   244
    parser.add_option("-h", "--host", action="store",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   245
                      type="string", dest="whoishost",
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   246
                      help="Lookup using specified whois host")
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   247
    parser.add_option("-i", "--nws", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   248
                      const=NICClient.INICHOST, dest="whoishost",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   249
                      help="Lookup using host " + NICClient.INICHOST)
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   250
    parser.add_option("-I", "--iana", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   251
                      const=NICClient.IANAHOST, dest="whoishost",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   252
                      help="Lookup using host " + NICClient.IANAHOST)
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   253
    parser.add_option("-l", "--lcanic", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   254
                      const=NICClient.LNICHOST, dest="whoishost",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   255
                      help="Lookup using host " + NICClient.LNICHOST)
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   256
    parser.add_option("-m", "--ra", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   257
                      const=NICClient.MNICHOST, dest="whoishost",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   258
                      help="Lookup using host " + NICClient.MNICHOST)
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   259
    parser.add_option("-p", "--port", action="store",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   260
                      type="int", dest="port",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   261
                      help="Lookup using specified tcp port")
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   262
    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
   263
                      dest="b_quicklookup",
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   264
                      help="Perform quick lookup")
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   265
    parser.add_option("-r", "--ripe", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   266
                      const=NICClient.RNICHOST, dest="whoishost",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   267
                      help="Lookup using host " + NICClient.RNICHOST)
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   268
    parser.add_option("-R", "--ru", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   269
                      const="ru", dest="country",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   270
                      help="Lookup Russian NIC")
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   271
    parser.add_option("-6", "--6bone", action="store_const",
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   272
                      const=NICClient.SNICHOST, dest="whoishost",
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   273
                      help="Lookup using host " + NICClient.SNICHOST)
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   274
    parser.add_option("-?", "--help", action="help")
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   275
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   276
    return parser.parse_args(argv)
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   277
0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   278
if __name__ == "__main__":
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   279
    flags = 0
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   280
    nic_client = NICClient()
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   281
    (options, args) = parse_command_line(sys.argv)
ea0e45971cea initial commit to mercurial
Richard Baron Penman
parents:
diff changeset
   282
    if (options.b_quicklookup is True):
32
5f851e9c196a Stylistic fixes on the NICClient class
Evgeni Kunev <evgeni.kunev@gmail.com>
parents: 12
diff changeset
   283
        flags = flags | NICClient.WHOIS_QUICK
6
7dee244ba3ef fixed builtin whois parser for pwhois.rotld.ro
Richard Baron Penman
parents: 0
diff changeset
   284
    print(nic_client.whois_lookup(options.__dict__, args[1], flags))