The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

Methods

Module methods.

Those starting with '_' are meant for internal use.

new

new handles the following parameters:

  { 
    use_cache           => <0|1>,
    debug               => <0..8>,
    service_url         => <0|service_url,
    norid_referral_ip   => <0|1|ip-address>,
    bauth_username      => <0|bauth_username>,
    bauth_password      => <0|bauth_password>,
    fieldset            => <0|fieldset>
    page_size           => <0|page size>, default $RDAP_PAGE_SIZE
    cursor              => <0|cursor>
    nopages             => <0|nopages>, default $RDAP_ENTITY_QUOTA_PAGES
    insert_page_info    => <0|1>
    force_ipv           => <0|4|6>
  }

 All parameters are optional:

 * use_cache:
   - 1: activate Net::RDAP lookup cache, see Net::RDAP for use,
        Note: usage not needed or tested for this lib.

 * debug:
   - 0  : debug off
   - 1  : debug output from this module
   - 2  : headers output from LWP UA callback
   - 3  : Debug output from Net::RDAP::UA (headers and contents)
   - 4-8: Debug output using LWP::ConsoleLogger::Easy,
          which then must be installed

 * service_url: 
   - the full http(s)-address of the Norid RDAP-servie to
     be accessed. 
   - default is $SERVICE_URL above.

 * norid_referral_ip : 
   - Norid internal use only.
   - set if the calling client ip address argument shall be sent. When set:
     - if the argument passed is a pure integer, use the local ip-address as value.
     - if the argument passed is a valid ip address, use that address
       as value. This is the normal variant to be used to pass a proper client 
       ip address.
     - the ip-address is passed to the server in the '?client_ip=<ip-address>'
       argument.

 * bauth_username:
   - Basic authentication username
     For a Norid registrar RDAP user where
     - RDAP username is     : 'rdapuser',
     - Norid registrar id is: 'reg1234'
     the basic username must be set as follows: 'rdapuser@reg1234'.

 * bauth_password:
   - Basic authentication password

 * fieldset:
   - Undef or one of the valid fieldSets to determine how much data
     should be returned for search hits
     If rate limiting becomes a problem, fieldset='full' could be
     considered.

 Paging parameters:

 * page_size:
   Page size for the the RDAP service.
   Recommended set by the caller, as the lib may have wrong default
   values.

 * cursor:
   - Undef or a cursor string to be used in succeeding page lookups,
     undef for first page.

 * nopages:
   - max number of pages from cursor (1..x, default 10).
     The pageSize in the RDAP service decides the number of hits per
     page.


 * insert_page_info:
    - Text formatting option, insert page info in the text if set.

 Paging parameters set by lib, read them only:

 * total_no_pages:
   Total number of pages that can be fetched with a search combo.
   Calculated as total_size / page_size and set by lib as soon as
   we know the value.

 * page_number:
   The page number signalled by the rdap service.

 * first_page|cur_page|prev_page|next_page:
    - Page hrefs set by lib when a search is performed.

Various:

 * force_ipv:
   - force use of ip protocl version, 0/undef is default, else set to
     4 or 6

lookup

Do an RDAP lookup.

  - $query      : Specifies the query string.
  - $check      : Specifies if http 'head' shall be done, default is 'get'.
  - $nameservers: Must be set to 1 for nameserver_name search
                  and 2 for a domains by nameserver name search
  - $entity     : Must be set to true for entity lookup, in which case the query should 
                  identify an entity, like:
                   - a domain name or a handle
                  For a search, this is more complex:
                  - For identities (orgno, N.XXX.YYY or registrant handles),
                    a search domains by identity/registrant is done as default.
                    To force the search to search for entities by
                    identity/registrant instead, this option must be
                    set.

_lookup_rdap

Do an RDAP HEAD or GET lookup.

  - $http_type: 'head' or 'get'
  - $uri      : full arguments to base URI, identifying the actual lookup
                method and args
  - other args as passed in $self.

_fetch_get_pages

Handle RDAP GET operations.

If search, loop and fetch the requested number of pages from the offset set by the cursor parameter.

get_href_page_cursor

Find and return cursor value from a href page link

_map_rdap_error

Some RDAP error is returned from Net::RDAP, ref. Net::RDAP::Error.

Those are normally HTTP response errors in the 400 and 500 range, which are mapped to one of the $RDAP_LOOKUP_ERR_XXX local errors.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Status - All 1xx, 2xx, 3xx are not errors, but OK, need not be handled. - All 4xx, 5xx indicate some problem, so map relevant ones. - Some are not mapped. A warning is given, which may indicate that some error case has occured, and that the situation may need to be handled and added to this lib.

get_my_ip_address

Find local ip-address.

(Note: Sys::HostAddr were also tried for this purpose, but could die at random, so Sys::HostIP is selected. Only ipv4 seems to be processed by Sys::HostIP, so the selection is limited to ipv4. TODO: Consider using another module, which also supports v6).

Best guess IP seems to be the one on the en0-interface, but when a VPN is in use, you might want that address to be selected. So, try to do the best ip selection by ourselves by a reverse sort instead of a sort, thus selecting the 'highest' numbered and public ip-address).

Return localhost if no other ip is found.

Return empty if localhost iface not found.

_is_a_valid_parameter

Check whether a parameter contains something fishy

Ref. CSS: https://www.owasp.org/index.php/Testing_for_Cross_site_scripting#Description_of_Cross-site_scripting_Vulnerabilities

Returns 0 if not ok, 1 if OK.

The below code can be used if special chars should also be generally blocked, but not in use for now:

  my $ILLCHARS = q/`';_|<>${}[]^]/;
  my $ILLCHARSqr = qr/[\|<>\$\{\}\[\]\^';_\|]/mx;
  if ($v =~ $ILLCHARSqr) {
     print STDERR "Parameter value contains illegal character(s), one or more of: '$ILLCHARS': '$v'";
     return;
  }

validate_and_analyze

 1) Validate ip address, if set
 
 2) Validate query, return if query not among the expexted ones.
    - domain name or name server name
    - some object handle (D, P, R, H)
    - some registrar handle (regXXX-NORID)
    - some identity (9 digits orgno, N.XXX.yyyyyyyy)

 2) Analyze query and args and find what http method and uri arguments
    to use for the lookup and set them in '_method' and '_uri'

is_a_valid_domainname

Check whether a domainname or nameserver is valid.

Returns undef if not ok. Returns 1 if OK.

rdap_get_obj_name

Fetch the name from an object.

If we have a Net::DNS::Domain object (domain/ns), also get the xname.

norid_handle_type

Determine type of Norid handle.

result_as_rdap_string

Return sensible rdap formatted text string. Uses internal helper formatting functions.

Shows how to access data returned by Net::RDAP.

rdap_obj_as_string

Return sensible rdap formatted text string for an rdap object.

Code stolen from rdapper and adapted.

rdap_notice_or_remark_as_string

Format RDAP notice or remark as text string.

rdap_vcard_as_string

Format vcard object(s) as a text string.

rdap_page_info_as_string

Format and insert page info, if requested.

rdap_get_entities_by_entity_handle

Based on a subscriber handle (O or P), fetch domain list for it.

rdap_get_domains_by_entity_handle

Based on a subscriber handle (O or P), fetch domain list for it.

For domain list on entity, we will try fetch all domains possible on a single quota as default via $RDAP_ENTITY_QUOTA_PAGES since it is set to a high enough value. User may try fewer or more pages bt specifying nopages.

rdap_get_entities_by_domain_name

Domain lookup entities for a domain name.

NAME

NOLookup::RDAP::RDAPLookup - Lookup RDAP data from the Norid (.no) RDAP service.

SYNOPSIS

    use Encode;
    use NOLookup::RDAP::RDAPLookup;
 
    # Default API service URL
    my $SERVICE_URL = "https://rdap.norid.no";

    # Example 1: Domain name lookup
    # Decode the query when needed, like for IDNs
    # or names with national characters.

    my $q = 'norid.no';
    #$q = decode('ISO8859-1', 'øl.no');

    # Authenticate with basic authentication 
    my $bo = NOLookup::RDAP::RDAPLookup->new(
     {
        service_url         => 'https://rdap.norid.no',
        debug               => 0,
        use_cache           => 0,
        bauth_username      => 'rdapuser@reg1234',
        bauth_password      => '<password>',
     });

    # test HEAD operation for existence
    $bo->lookup($q, 1, 0, 0);
    if ($bo->error) {
       print "HEAD: Error, error / status: ",
          $bo->error . "/" . $bo->status) . "\n";
    }

    # test GET operations
    $bo->lookup($q, 0, 0, 0);
    if ($bo->error) {
       print "GET: Error, error / status: ",
          $bo->error . "/" . $bo->status) . "\n";
    }
        
    # result of lookup is in $bo->result
    # This result contains response objects built by Net::RDAP

    # if a lookup has arguments which results in a search type, the
    # is_a_search method returns true. This is a hint to the caller to
    # process paging information in the result, and maybe perform several
    # next-lookups to get more data.

    my $res = $bo->result;
    print "handle: ", $bo->handle, "\n";

 * See bin/no_rdap.pl for more information on usage.

 * See various formatting/helper functions in this file for how to
   access the various objects returned by Net::RDAP.

DESCRIPTION

This module provides an object oriented API for use with the Norid RDAP service. It uses the Net::RDAP module from Cpan internally to fetch information from the Norid RDAP.

SUPPORT

For now, support questions should be sent to:

<(nospam)info(at)norid.no>

SEE ALSO

https://www.norid.no/en https://teknisk.norid.no/en/integrere-mot-norid/rdap-tjenesten

CAVEATS

AUTHOR

Trond Haugen, <(nospam)info(at)norid.no>

COPYRIGHT

Copyright (c) 2020- Trond Haugen <(nospam)info(at)norid.no>. All rights reserved.

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

LICENSE

This library is free software. You can redistribute it and/or modify it under the same terms as Perl itself.

About the Norid RDAP API

See https://teknisk.norid.no/en/integrere-mot-norid/rdap-tjenesten