[Python-modules-commits] [python-getdns] 01/04: Imported Upstream version 0.6.0

Ondrej Sury ondrej at moszumanska.debian.org
Wed Jan 27 09:50:58 UTC 2016


This is an automated email from the git hooks/post-receive script.

ondrej pushed a commit to branch master
in repository python-getdns.

commit e10dc03cb6c822499a3919498c69116e6546d448
Author: Ondřej Surý <ondrej at sury.org>
Date:   Wed Jan 27 10:42:35 2016 +0100

    Imported Upstream version 0.6.0
---
 .gitignore                |   1 +
 context.c                 |  33 +++----
 doc/conf.py               |   4 +-
 doc/functions.rst         | 115 ++++++++++++-----------
 doc/index.rst             |  17 ++--
 doc/response.rst          |  17 +++-
 examples/client_subnet.py |  54 +++++++++++
 examples/dane_encrypt.py  |   0
 examples/pinset.py        |  17 ++++
 examples/tsig_demo.py     |  15 +++
 getdns.c                  |  39 +++++++-
 pygetdns.h                |   8 ++
 pygetdns_util.c           | 231 ++++++++++++++++++++++++++++++++++++----------
 result.c                  |  13 +++
 setup.py                  |   8 +-
 15 files changed, 437 insertions(+), 135 deletions(-)

diff --git a/.gitignore b/.gitignore
index 9c173f1..467aeca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@ build/
 _build/
 *~
 getdns.so
+getdns.cpython-34m.so
 *.save
 doc/_build/
 doc/_build/*
diff --git a/context.c b/context.c
index b31859e..096b535 100644
--- a/context.c
+++ b/context.c
@@ -476,9 +476,9 @@ context_set_tls_authentication(getdns_context *context, PyObject *py_value)
         return -1;
     }
 #if PY_MAJOR_VERSION >= 3
-    if ((value = (getdns_tls_authentication_t)PyLong_AsLong(py_value)) < 0)  {
+    if ((int)(value = (getdns_tls_authentication_t)PyLong_AsLong(py_value)) < 0)  {
 #else
-    if ((value = (getdns_tls_authentication_t)PyInt_AsLong(py_value)) < 0)  {
+    if ((int)(value = (getdns_tls_authentication_t)PyInt_AsLong(py_value)) < 0)  {
 #endif
         PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
         return -1;
@@ -875,11 +875,11 @@ context_set_dns_transport_list(getdns_context *context, PyObject *py_value)
         long transport;
         if ((py_transport = PyList_GetItem(py_value, (Py_ssize_t)i)) != NULL)  {
             transport = PyLong_AsLong(py_transport);
-            if ((transport < GETDNS_TRANSPORT_UDP) || (transport > GETDNS_TRANSPORT_STARTTLS))  {
+            if ((transport < GETDNS_TRANSPORT_UDP) || (transport > GETDNS_TRANSPORT_TLS))  {
                 PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
                 return -1;
             }
-            transports[i] = transport;
+            transports[i] = (getdns_transport_list_t)transport;
         }
         else  {
             PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
@@ -947,6 +947,19 @@ context_getattro(PyObject *self, PyObject *nameobj)
         }
     }
 
+    if (!strncmp(attrname, "suffix", strlen("suffix")))  {
+        PyObject *py_suffix;
+        getdns_list *suffix;
+
+        if ((ret = getdns_context_get_suffix(context, &suffix)) != GETDNS_RETURN_GOOD)  {
+            PyErr_SetString(getdns_error, getdns_get_errorstr_by_id(ret));
+            return NULL;
+        }
+        if ((py_suffix = glist_to_plist(suffix)) == NULL)
+            PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
+        return py_suffix;
+    }
+
     api_info = getdns_context_get_api_information(context);
     if (!strncmp(attrname, "resolution_type", strlen("resolution_type")))  {
         uint32_t resolution_type;
@@ -1198,18 +1211,6 @@ context_getattro(PyObject *self, PyObject *nameobj)
             PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
         return py_namespaces;
     }
-    if (!strncmp(attrname, "suffix", strlen("suffix")))  {
-        PyObject *py_suffix;
-        getdns_list *suffix;
-        if ((ret = getdns_dict_get_list(all_context, "suffix",
-                                        &suffix)) != GETDNS_RETURN_GOOD)  {
-            PyErr_SetString(getdns_error, getdns_get_errorstr_by_id(ret));
-            return NULL;
-        }
-        if ((py_suffix = glist_to_plist(suffix)) == NULL)
-            PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
-        return py_suffix;
-    }
     if (!strncmp(attrname, "upstream_recursive_servers", strlen("upstream_recursive_servers")))  {
         PyObject *py_upstream_servers;
         getdns_list *upstream_list;
diff --git a/doc/conf.py b/doc/conf.py
index 1e43138..7042ed0 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -48,9 +48,9 @@ copyright = u'2014, Verisign Labs, NLnet Labs'
 # built documents.
 #
 # The short X.Y version.
-version = 'v0.5.0'
+version = 'v0.6.0'
 # The full version, including alpha/beta/rc tags.
-release = 'v0.5.0'
+release = 'v0.6.0'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/doc/functions.rst b/doc/functions.rst
index 3642d9e..2875a8d 100644
--- a/doc/functions.rst
+++ b/doc/functions.rst
@@ -10,7 +10,8 @@
 getdns contexts
 ---------------
 
-This section describes the *getdns* Context object, as well as its
+This section describes the *getdns* Context object, as well
+as its
 as its methods and attributes.
 
 .. py:class:: Context([set_from_os])
@@ -22,12 +23,14 @@ as its methods and attributes.
    attributes described below.
 
    Context() takes one optional constructor argument.
-   ``set_from_os`` is an integer and may take the value either
+   ``set_from_os`` is an integer and may take the value
+   either
    0 or 1.  If 1, which most developers will want, getdns
    will populate the context with default values for the
    platform on which it's running.
 
-  The :class:`Context` class has the following public read/write attributes:
+  The :class:`Context` class has the following public
+  read/write attributes:
 
   .. py:attribute:: append_name
 
@@ -37,7 +40,8 @@ as its methods and attributes.
    ``getdns.APPEND_NAME_ALWAYS``,
    ``getdns.APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE``,
    ``getdns.APPEND_NAME_ONLY_TO_MULTIPLE_LABEL_NAME_AFTER_FAILURE``,
-   or ``getdns.APPEND_NAME_NEVER``. This controls whether or not
+   or ``getdns.APPEND_NAME_NEVER``. This controls whether or
+   not
    to append the suffix given by :attr:`suffix`.
 
   .. py:attribute:: dns_root_servers
@@ -53,8 +57,10 @@ as its methods and attributes.
 
    For example, the addresses list could look like
 
-   >>> addrs = [ { 'address_data': '2001:7b8:206:1::4:53', 'address_type': 'IPv6' },
-   ...         { 'address_data': '65.22.9.1', 'address_type': 'IPv4' } ]
+   >>> addrs = [ { 'address_data': '2001:7b8:206:1::4:53',
+       'address_type': 'IPv6' },
+   ...         { 'address_data': '65.22.9.1',
+       'address_type': 'IPv4' } ]
    >>> mycontext.dns_root_servers = addrs
 
   .. py:attribute:: dns_transport_list
@@ -63,8 +69,7 @@ as its methods and attributes.
    lookups, ordered by preference (first choice as list
    element 0, second as list element 1, and so on).  The
    possible values are ``getdns.TRANSPORT_UDP``,
-   ``getdns.TRANSPORT_TCP``, ``getdns.TRANSPORT_TLS``,
-   and ``getdns.TRANSPORT_STARTTLS``. 
+   ``getdns.TRANSPORT_TCP``, and ``getdns.TRANSPORT_TLS``.
 
   .. py:attribute:: dnssec_allowed_skew
 
@@ -84,11 +89,13 @@ as its methods and attributes.
 
   .. py:attribute:: edns_do_bit
 
-   Its value must be an integer valued either 0 or 1.  The default is 0.
+   Its value must be an integer valued either 0 or 1.  The
+   default is 0.
 
   .. py:attribute:: edns_extended_rcode
 
-   Its value must be an integer between 0 and 255, inclusive.
+   Its value must be an integer between 0 and 255,
+   inclusive.
    The default is 0.
 
   .. py:attribute:: edns_maximum_udp_payload_size
@@ -98,15 +105,18 @@ as its methods and attributes.
 
   .. py:attribute:: edns_version
 
-   Its value must be an integer between 0 and 255, inclusive.
+   Its value must be an integer between 0 and 255,
+   inclusive.
    The default is 0.
 
   .. py:attribute:: follow_redirects
 
    Specifies whether or not DNS queries follow
-   redirects.  The value must be one of ``getdns.REDIRECTS_FOLLOW`` for
+   redirects.  The value must be one of
+   ``getdns.REDIRECTS_FOLLOW`` for
    normal following of redirects though CNAME and DNAME; or
-   ``getdns.REDIRECTS_DO_NOT_FOLLOW`` to cause any lookups that
+   ``getdns.REDIRECTS_DO_NOT_FOLLOW`` to cause any lookups
+   that
    would have gone through CNAME and DNAME to return the
    CNAME or DNAME, not the eventual target.
 
@@ -122,22 +132,27 @@ as its methods and attributes.
 
   .. py:attribute:: limit_outstanding_queries
 
-   Specifies `limit` (an integer value) on the number of outstanding DNS
+   Specifies `limit` (an integer value) on the number of
+   outstanding DNS
    queries. The API will block itself from sending more
    queries if it is about to exceed this value, and instead
    keep those queries in an internal queue. The a value of 0
-   indicates that the number of outstanding DNS queries is unlimited.
+   indicates that the number of outstanding DNS queries is
+   unlimited.
 
   .. py:attribute:: namespaces
 
    The `namespaces` attribute takes an ordered list of
-   namespaces that will be queried. (*Important: this context
+   namespaces that will be queried. (*Important: this
+   context
    setting is ignored for the getdns.general() function;
    it is used for the other
    functions.*) The allowed values are
-   ``getdns.NAMESPACE_DNS``, ``getdns.NAMESPACE_LOCALNAMES``, 
+   ``getdns.NAMESPACE_DNS``,
+   ``getdns.NAMESPACE_LOCALNAMES``, 
    ``getdns.NAMESPACE_NETBIOS``,
-   ``getdns.NAMESPACE_MDNS``, and ``getdns.NAMESPACE_NIS``. When a
+   ``getdns.NAMESPACE_MDNS``, and
+   ``getdns.NAMESPACE_NIS``. When a
    normal lookup is done, the API does the lookups in the
    order given and stops when it gets the first result; a
    different method with the same result would be to run the
@@ -145,7 +160,8 @@ as its methods and attributes.
    result. Because lookups might be done over different
    mechanisms because of the different namespaces, there can
    be information leakage that is similar to that seen with
-   POSIX *getaddrinfo()*. The default is determined by the OS.
+   POSIX *getaddrinfo()*. The default is determined by the
+   OS.
 
   .. py:attribute:: resolution_type
 
@@ -166,22 +182,28 @@ as its methods and attributes.
 
   .. py:attribute:: timeout
    
-   Its value must be an integer specifying a timeout for a query, expressed 
+   Its value must be an integer specifying a timeout for a
+   query, expressed 
    in milliseconds.
 
   .. py:attribute:: tls_authentication
 
    The mechanism to be used for authenticating the TLS
-   server when using a TLS transport.  May be ``getdns.AUTHENTICATION_HOSTNAME`` or
+   server when using a TLS transport.  May be
+   ``getdns.AUTHENTICATION_REQUIRED`` or
    ``getdns.AUTHENTICATION_NONE``.
+   (getdns.AUTHENTICATION_HOSTNAME remains as an alias for
+   getdns.AUTHENTICATION_REQUIRED but is deprecated and will
+   be removed in a future release)
 
   .. py:attribute:: tls_query_padding_blocksize
 
-   Optional padding blocksize for queries when using TLS.  Used to
+   Optional padding blocksize for queries when using TLS.
+   Used to
    increase the difficulty for observers to guess traffic
    content.
 
-  .. py:attribute:: upstream_recursive_servers
+   .. py:attribute:: upstream_recursive_servers
 
    A list of dicts defining where a stub resolver will send queries.
    Each dict in the list contains at least two names: address_type
@@ -193,11 +215,19 @@ as its methods and attributes.
    tsig_algorithm (a bindata) that is the name of the TSIG hash
    algorithm, and tsig_secret (a bindata) that is the TSIG key.
 
+   There is also now support for pinning an upstream's
+   certificate's public keys, with pinsets (when using TLS
+   for transport.  Add an element to the
+   upstream_recursive_server list entry, called
+   'tls_pubkey_pinset', which is a list of public key pins.
+   (See the example code in our examples directory).
+                    
   .. py:attribute:: version_string
 
     The libgetdns version, retrieved from the underlying
     getdns library.
-                    
+
+
   The :class:`Context` class includes public methods to execute a DNS query, as well as a
   method to return the entire set of context attributes as a Python dictionary.  :class:`Context`
   methods are described below:
@@ -253,7 +283,7 @@ as its methods and attributes.
 
    * ``version_string``
    * ``implementation_string``
-   * ``resolver_type``
+   * ``resolution_type``
    * ``all_context``
 
    ``all_context`` is a dictionary containing the following keys:
@@ -263,13 +293,13 @@ as its methods and attributes.
    * ``dnssec_allowed_skew``
    * ``edns_do_bit``
    * ``edns_extended_rcode``
-   * ``edns_maximum_udp_payload_size``
    * ``edns_version``
    * ``follow_redirects``
    * ``limit_outstanding_queries``
    * ``namespaces``
    * ``suffix``
    * ``timeout``
+   * ``tls_authentication``
    * ``upstream_recursive_servers``
 
   .. py:method:: get_supported_attributes()
@@ -301,13 +331,7 @@ The extensions currently supported by :py:mod:`getdns` are:
    * ``add_opt_parameters``
    * ``add_warning_for_bad_dns``
    * ``specify_class``
-   * ``return_call_debugging``
-
-Extensions that are optionally built (see above) include
-
-   * ``edns-cookies``
-
-``edns-cookies`` also takes the value ``getdns.EXTENSION_TRUE``.
+   * ``return_call_reporting``
 
 Extensions for DNSSEC
 ^^^^^^^^^^^^^^^^^^^^^
@@ -407,6 +431,9 @@ record sets the resource record appropriately, making the
 needed changes to the settings from the ``add_opt_parameters``
 extension.
 
+The ``client_subnet.py`` program in our example directory
+shows how to pack and send an OPT record.
+
 Getting Warnings for Responses that Violate the DNS Standard
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -444,9 +471,9 @@ Extensions relating to the API
 
 An application might want to see debugging information for
 queries, such as the length of time it takes for each query
-to return to the API.  Use the ``return_call_debugging``
+to return to the API.  Use the ``return_call_reporting``
 extension. The extension's value is set to
-``getdns.EXTENSION_TRUE`` to add the name ``call_debugging`` (a
+``getdns.EXTENSION_TRUE`` to add the name ``call_reporting`` (a
 list) to the top level of the ``response`` object. Each member
 of the list is a dict that represents one call made for the
 call to the API. Each member has the following names:
@@ -543,21 +570,3 @@ This is an example callback function:
             print 'Unknown error'
 
 
-Utility methods
----------------
-
-At the present time we support one utility method.
-
-.. py:method:: get_errorstr_by_id(id)
-
-   ``getdns.get_errorstr_by_id`` returns a string containing
-   text describing a getdns return code, helping to make
-   reporting errors to users a little easier.  For example:
-
-.. code-block:: python
-
-    if results.replies_full['status'] != getdns.RESPSTATUS_GOOD:
-        print(getdns.get_errorstr_by_id(id=results.replies_full['status'])
-        sys.exit(1)
-
-   
diff --git a/doc/index.rst b/doc/index.rst
index 673d253..bcb0da4 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -18,18 +18,18 @@ getdns implementation developed as a joint project between
 and `NLnet Labs <http://nlnetlabs.nl/>`_.
 
 We have tried to keep this interface as Pythonic as we can
-while staying true to the getdns architecture.  With this 
-release we are moving towards a design that is more consistent with
+while staying true to the getdns architecture, including
+trying to maintain consistency with
 Python object design.
 
 Dependencies
 ============
 
 This version of getdns has been built and tested against Python
-2.7.  We also expect these other prerequisites to be
+2.7 and Python 3.4.  We also expect these other prerequisites to be
 installed:
 
-* `libgetdns <http://getdnsapi.net/>`_, version 0.5.0 or later
+* `libgetdns <http://getdnsapi.net/>`_, version 0.9.0 or later
 * `libunbound
   <http://www.nlnetlabs.nl/projects/unbound/>`_, version
   1.4.16 or later
@@ -53,7 +53,8 @@ Building
 ========
 
 The code repository for getdns is available at:
-`<https://github.com/getdnsapi/getdns-python-bindings>`_.  If you are building from source you will
+`<https://github.com/getdnsapi/getdns-python-bindings>`_.  
+If you are building from source you will
 need the Python development package for Python 2.7.  On
 Linux systems this is typically something along the lines of
 "python-dev" or "python2.7-dev", available through your
@@ -214,13 +215,17 @@ Module-level attributes and methods
 
 .. py:method:: ulabel_to_alabel()
 
-   Converts a ulabel to an alabel.  Takes one argument (the ulabel)
+   Converts a ulabel to an alabel.  Takes one argument (the
+   ulabel)
 
 .. py:method:: alabel_to_ulabel()
 
    Converts an alabel to a ulabel.  Takes one argument (the
    alabel)
 
+.. py:method:: root_trust_anchor()
+
+   Returns the default root trust anchor for DNSSEC.
 
 Known issues
 ============
diff --git a/doc/response.rst b/doc/response.rst
index bd0efcd..ab9cd1a 100644
--- a/doc/response.rst
+++ b/doc/response.rst
@@ -49,6 +49,13 @@ Response data from queries
     specified, and at least one DNS response was received, but
     no DNS response was determined to be secure through DNSSEC.
 
+    .. py:data:: getdns.RESPSTATUS_ALL_BOGUS_ANSWERS
+
+    The context setting for getting only secure responses
+    was specified, and at least one DNS response was
+    received, but all received responses for the requested
+    name were bogus.
+
   .. py:attribute:: answer_type
 
    The ``answer_type`` attribute contains the type of data
@@ -154,10 +161,10 @@ Response data from queries
    RRSIGs) that are needed to perform the validation from
    the root up.                    
 
-  .. py:attribute:: call_debugging
+  .. py:attribute:: call_reporting
 
-    A list of dictionaries containing call_debugging
-    information, if requested in the query.
+   A list of dictionaries containing call_debugging
+   information, if requested in the query.
 
   .. py:attribute:: replies_tree
 
@@ -351,3 +358,7 @@ The return codes for all the functions are:
 .. py:data:: RETURN_INVALID_PARAMETER
 
   A required parameter had an invalid value.
+
+.. py:data:: RETURN_NOT_IMPLEMENTED
+
+  The requested API feature is not implemented.
diff --git a/examples/client_subnet.py b/examples/client_subnet.py
new file mode 100755
index 0000000..e3b781b
--- /dev/null
+++ b/examples/client_subnet.py
@@ -0,0 +1,54 @@
+import getdns
+import socket, fcntl, sys
+from struct import pack, unpack
+
+
+#
+#  returns a tuple containing the network part of the ip 
+#  address for the interface and the netmask, both encoded
+#  in strings.  Definitely not portable to Windows, probably
+#  not portable to some Unixes.  Unfortunately you have
+#  to pass in the name of the interface; interface name
+#  will be discovered in a future version
+#
+
+def get_network_info(ifname):
+    SIOCGIFADDR = 0x8915
+    SIOCGIFNETMASK = 0x891b
+
+    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    netmask = fcntl.ioctl(s.fileno(), SIOCGIFNETMASK, pack('256s',ifname))[20:24]
+    addr = fcntl.ioctl(s.fileno(), SIOCGIFADDR, pack('256s', ifname))[20:24]
+    return (pack('!I', (unpack('!I', addr)[0] & unpack('!I', netmask)[0])), netmask)
+    
+
+def main():
+    CLIENT_SUBNET_OPCODE = 8
+    LOCAL_INTERFACE = 'eth0'
+    host = 'getdnsapi.net'
+    
+    if len(sys.argv) == 2:
+        host = sys.argv[1]
+    family = pack("!H", 1)  # start building the edns option fields
+    source_netmask, address = get_network_info(LOCAL_INTERFACE)
+    scope_netmask = pack("B", 0)
+
+#
+# encoding the binary data in strings makes it really easy
+# to build packets by concatenating those strings
+#
+    payload = family + source_netmask + scope_netmask + address
+    length = pack("!H", len(payload))
+    ext = { 'add_opt_parameters': {'options':
+                                       [ {'option_code': CLIENT_SUBNET_OPCODE,
+                                          'option_data': length+payload} ] }}
+
+    c = getdns.Context()
+    c.resolution_type = getdns.RESOLUTION_STUB
+    response = c.address(host, extensions=ext)
+
+# do things with response ...
+    print response
+
+if __name__ == '__main__':
+    main()
diff --git a/examples/dane_encrypt.py b/examples/dane_encrypt.py
old mode 100644
new mode 100755
diff --git a/examples/pinset.py b/examples/pinset.py
new file mode 100755
index 0000000..6d7aaaa
--- /dev/null
+++ b/examples/pinset.py
@@ -0,0 +1,17 @@
+#
+# Note that we expect that each pin in the pinset list
+#   must be prefaced with pin-<algorithm>= and the pin 
+#   itself must be base64-encoded and enclosed in double-
+#   quotes.  We may loosen this up in a future version
+#
+
+import getdns
+c = getdns.Context()
+u = [ { 'address_data': '185.49.141.37', 
+        'address_type': 'IPv4', 
+        'tls_pubkey_pinset': ['pin-sha256="foxZRnIh9gZpWnl+zEiKa0EJ2rdCGroMWm02gaxSc9S="']
+ }]
+c.resolution_type = getdns.RESOLUTION_STUB
+c.dns_transport_list = [ getdns.TRANSPORT_TLS ]
+c.upstream_recursive_servers = u
+f = c.address('getdnsapi.net')
diff --git a/examples/tsig_demo.py b/examples/tsig_demo.py
new file mode 100755
index 0000000..37ddcf3
--- /dev/null
+++ b/examples/tsig_demo.py
@@ -0,0 +1,15 @@
+import getdns
+import base64
+
+u = [ { 'address_data': '185.49.141.37', 
+        'address_type': 'IPv4', 
+        'tsig_algorithm': 'hmac-md5.sig-alg.reg.int', 
+        'tsig_name': 'hmac-md5.tsigs.getdnsapi.net',
+        'tsig_secret':  base64.b64decode('16G69OTeXW6xSQ==')
+ }]
+
+c = getdns.Context()
+c.resolution_type = getdns.RESOLUTION_STUB
+c.upstream_recursive_servers = u
+f = c.general('getdnsapi.net', request_type = getdns.RRTYPE_SOA)
+print('tsig_status is {0}'.format(f.replies_tree[0]['tsig_status']))
diff --git a/getdns.c b/getdns.c
index 0f009c5..4dde53e 100644
--- a/getdns.c
+++ b/getdns.c
@@ -55,6 +55,10 @@ static PyObject *root_trust_anchor(PyObject *self, PyObject *args, PyObject *key
 static void add_getdns_constants(PyObject *g);
 static PyObject *ulabel_to_alabel(PyObject *self, PyObject *args, PyObject *keywds);
 static PyObject *alabel_to_ulabel(PyObject *self, PyObject *args, PyObject *keywds);
+#if 0
+static PyObject *wire_to_string(PyObject *self, PyObject *args, PyObject *keywds);
+#endif
+
 	
 static struct PyMethodDef getdns_methods[] = {
     { "get_errorstr_by_id", (PyCFunction)get_errorstr_by_id,
@@ -65,6 +69,10 @@ static struct PyMethodDef getdns_methods[] = {
       METH_VARARGS|METH_KEYWORDS, "return ulabel from alabel" },
     { "ulabel_to_alabel", (PyCFunction)ulabel_to_alabel,
       METH_VARARGS|METH_KEYWORDS, "return alabel from ulabel" },
+#if 0
+    { "wire_to_string", (PyCFunction)wire_to_string,
+      METH_VARARGS|METH_KEYWORDS, "convert a wire format buffer to a zone file format string" },
+#endif
     { 0, 0, 0 }
 };
 
@@ -98,8 +106,13 @@ PyMemberDef Result_members[] = {
       "Canonical name" },
     { "validation_chain", T_OBJECT_EX, offsetof(getdns_ResultObject, validation_chain),
       READONLY, "DNSSEC certificate chain" },
+#if GETDNS_NUMERIC_VERSION < 0x00090000
     { "call_debugging", T_OBJECT_EX, offsetof(getdns_ResultObject, call_debugging),
       READONLY, "Query debugging info" },
+#else
+    { "call_reporting", T_OBJECT_EX, offsetof(getdns_ResultObject, call_reporting),
+      READONLY, "Return call reporting data" },
+#endif
     { NULL },
 };
 
@@ -286,6 +299,7 @@ alabel_to_ulabel(PyObject *self, PyObject *args, PyObject *keywds)
 #endif
 }
 
+
 static PyObject  *
 ulabel_to_alabel(PyObject *self, PyObject *args, PyObject *keywds)
 {
@@ -305,11 +319,32 @@ ulabel_to_alabel(PyObject *self, PyObject *args, PyObject *keywds)
 #endif
 }
 
+#if 0
+static PyObject *
+wire_to_string(PyObject *self, PyObject *args, PyObject *keywds)
+{
+    static char *kwlist[] = { "wirebuf",
+                              NULL };
+    int  nbytes;
+
+    char *wirebuf;
+    if (!PyArg_ParseTupleAndKeywords(args, keywds, "t#", kwlist,
+                                     &wirebuf, &nbytes))  {
+        PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
+        return NULL;
+    }
+    printf("len = %d\n", nbytes);
+    printf("%s\n", gldns_wire2str_rr(wirebuf, (size_t)nbytes));
+    return Py_None;
+}
+#endif
+
+
 static PyObject *
 get_errorstr_by_id(PyObject *self, PyObject *args, PyObject *keywds)
 {
     static char *kwlist[] = { "id",
-                            NULL };
+                              NULL };
     int id;
     char *errstr;
 
@@ -488,7 +523,6 @@ add_getdns_constants(PyObject *g)
     PyModule_AddIntConstant(g, "TRANSPORT_UDP", 1200);
     PyModule_AddIntConstant(g, "TRANSPORT_TCP", 1201);
     PyModule_AddIntConstant(g, "TRANSPORT_TLS", 1202);
-    PyModule_AddIntConstant(g, "TRANSPORT_STARTTLS", 1203);
 
 /*
  * suffix appending methods
@@ -683,4 +717,5 @@ add_getdns_constants(PyObject *g)
 
     PyModule_AddIntConstant(g, "AUTHENTICATION_NONE", 1300);
     PyModule_AddIntConstant(g, "AUTHENTICATION_HOSTNAME", 1301);
+    PyModule_AddIntConstant(g, "AUTHENTICATION_REQUIRED", 1301);
 }
diff --git a/pygetdns.h b/pygetdns.h
index cbd5ee3..d3334c9 100644
--- a/pygetdns.h
+++ b/pygetdns.h
@@ -59,7 +59,11 @@ typedef struct  {
     PyObject *canonical_name;
     PyObject *replies_full;
     PyObject *validation_chain;
+#if GETDNS_NUMERIC_VERSION < 0x00090000
     PyObject *call_debugging;
+#else 
+    PyObject *call_reporting;
+#endif
 } getdns_ResultObject;
 
 
@@ -121,7 +125,11 @@ char *get_canonical_name(struct getdns_dict *result_dict);
 PyObject *get_just_address_answers(struct getdns_dict *result_dict);
 PyObject *get_replies_tree(struct getdns_dict *result_dict);
 PyObject *get_validation_chain(struct getdns_dict *result_dict);
+#if GETDNS_NUMERIC_VERSION < 0x00090000
 PyObject *get_call_debugging(struct getdns_dict *result_dict);
+#else
+PyObject *get_call_reporting(struct getdns_dict *result_dict);
+#endif
 
 int context_init(getdns_ContextObject *self, PyObject *args, PyObject *keywds);
 PyObject *context_getattro(PyObject *self, PyObject *nameobj);
diff --git a/pygetdns_util.c b/pygetdns_util.c
index 01f93bb..36a0d5a 100644
--- a/pygetdns_util.c
+++ b/pygetdns_util.c
@@ -122,18 +122,35 @@ get_validation_chain(struct getdns_dict *result_dict)
 }
 
 
+#if GETDNS_NUMERIC_VERSION < 0x00090000
 PyObject *
 get_call_debugging(struct getdns_dict *result_dict)
+#else
+PyObject *
+get_call_reporting(struct getdns_dict *result_dict)
+#endif
 {
+#if GETDNS_NUMERIC_VERSION < 0x00090000
     struct getdns_list *call_debugging;
+#else
+    struct getdns_list *call_reporting;
+#endif
     getdns_return_t ret;
 
 
+#if GETDNS_NUMERIC_VERSION < 0x00090000
     if ((ret = getdns_dict_get_list(result_dict, "call_debugging", &call_debugging)) !=
+#else
+    if ((ret = getdns_dict_get_list(result_dict, "call_reporting", &call_reporting)) !=
+#endif
         GETDNS_RETURN_GOOD)
         Py_RETURN_NONE;
     else
+#if GETDNS_NUMERIC_VERSION < 0x00090000
         return glist_to_plist(call_debugging);
+#else
+        return glist_to_plist(call_reporting);
+#endif
 }
 
 struct getdns_dict *
@@ -171,7 +188,11 @@ extensions_to_getdnsdict(PyDictObject *pydict)
              (!strncmp(tmp_key, "dnssec_return_validation_chain", strlen("dnssec_return_validation_chain")))  ||
              (!strncmp(tmp_key, "return_both_v4_and_v6", strlen("return_both_v4_and_v6")))  ||
              (!strncmp(tmp_key, "return_api_information", strlen("return_api_information")))  ||
+#if GETDNS_NUMERIC_VERSION < 0x00090000
              (!strncmp(tmp_key, "return_call_debugging", strlen("return_call_debugging")))  ||
+#else
+             (!strncmp(tmp_key, "return_call_reporting", strlen("return_call_reporting")))  ||
+#endif
              (!strncmp(tmp_key, "add_warning_for_bad_dns", strlen("add_warning_for_bad_dns"))) )  {
 #if PY_MAJOR_VERSION >= 3
             if (!PyLong_Check(value))  {
@@ -342,7 +363,7 @@ extensions_to_getdnsdict(PyDictObject *pydict)
 
 
 getdns_dict *
-getdnsify_addressdict(PyObject *pydict)
+    getdnsify_addressdict(PyObject *pydict)
 {
     getdns_dict *addr_dict;
     getdns_bindata addr_data;
@@ -352,56 +373,34 @@ getdnsify_addressdict(PyObject *pydict)
     int domain;
     getdns_bindata tls_auth_name;
     getdns_bindata scope_id;
-    uint32_t tls_port;
+    getdns_bindata tsig_name;
+    getdns_bindata tsig_alg;
+    getdns_bindata tsig_secret;
+    uint32_t tls_port, port;
+    getdns_return_t ret;
+    getdns_list *tls_pubkey_pinset;
 
     if (!PyDict_Check(pydict))  {
         PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
         return NULL;
     }
-#if 0
-    if (PyDict_Size(pydict) != 2)  {
-        PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
-        return NULL;
-    }
-#endif
-    addr_dict = getdns_dict_create();
+
     /* XXX rewrite this so it's more general */
-    if ((str = PyDict_GetItemString(pydict, "tls_auth_name")) != NULL)  {
-#if PY_MAJOR_VERSION >= 3
-        tls_auth_name.data = (uint8_t *)strdup(PyBytes_AsString(PyUnicode_AsEncodedString(str, "ascii", NULL)));
-#else
-        tls_auth_name.data = (uint8_t *)strdup(PyString_AsString(str));
-#endif
-        tls_auth_name.size = (size_t)strlen((char *)tls_auth_name.data);
-        getdns_dict_set_bindata(addr_dict, "tls_auth_name", &tls_auth_name);
-    }
-    if ((str = PyDict_GetItemString(pydict, "scope_id")) != NULL)  {
-#if PY_MAJOR_VERSION >= 3
-        scope_id.data = (uint8_t *)strdup(PyBytes_AsString(PyUnicode_AsEncodedString(str, "ascii", NULL)));
-#else
-        scope_id.data = (uint8_t *)strdup(PyString_AsString(str));
-#endif
-        scope_id.size = (size_t)strlen((char *)scope_id.data);
-        getdns_dict_set_bindata(addr_dict, "scope_id", &scope_id);
-    }
-    if ((str = PyDict_GetItemString(pydict, "tls_port")) != NULL)  {
-#if PY_MAJOR_VERSION >= 3
-        if (!PyLong_Check(str))  {
-            PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
-            return NULL;
-        }
-        tls_port = (uint32_t)PyLong_AsLong(str);
-        getdns_dict_set_int(addr_dict, "tls_port", tls_port);
-#else
-        if (!PyInt_Check(str))  {
-            PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
-            return NULL;
-        }
-        tls_port = (uint32_t)PyInt_AsLong(str);
-        getdns_dict_set_int(addr_dict, "tls_port", tls_port);
-#endif
-    }
 
+    /* dict members supported:
+     *  address_data
+     *  address_type
+     *  tls_auth_name
+     *  scope_id
+     *  port
+     *  tls_port
+     *  tsig_name
+     *  tsig_secret
+     *  tsig_algorithm
+     *  tls_pubkey_pinset
+     */
+
+    addr_dict = getdns_dict_create();
     if ((str = PyDict_GetItemString(pydict, "address_type")) == NULL)  {
         PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
         return NULL;
@@ -458,6 +457,137 @@ getdnsify_addressdict(PyObject *pydict)
     addr_data.size = (domain == AF_INET ? 4 : 16);
     getdns_dict_set_bindata(addr_dict, "address_data", &addr_data);
 
+    if ((str = PyDict_GetItemString(pydict, "tls_auth_name")) != NULL)  {
+#if PY_MAJOR_VERSION >= 3
+        tls_auth_name.data = (uint8_t *)strdup(PyBytes_AsString(PyUnicode_AsEncodedString(str, "ascii", NULL)));
+#else
+        tls_auth_name.data = (uint8_t *)strdup(PyString_AsString(str));
+#endif
+        tls_auth_name.size = (size_t)strlen((char *)tls_auth_name.data);
+        getdns_dict_set_bindata(addr_dict, "tls_auth_name", &tls_auth_name);
+    }
+
+    if ((str = PyDict_GetItemString(pydict, "scope_id")) != NULL)  {
+#if PY_MAJOR_VERSION >= 3
+        scope_id.data = (uint8_t *)strdup(PyBytes_AsString(PyUnicode_AsEncodedString(str, "ascii", NULL)));
+#else
+        scope_id.data = (uint8_t *)strdup(PyString_AsString(str));
+#endif
+        scope_id.size = (size_t)strlen((char *)scope_id.data);
+        getdns_dict_set_bindata(addr_dict, "scope_id", &scope_id);
+    }
+
+    if ((str = PyDict_GetItemString(pydict, "tsig_name")) != NULL)  {
+#if PY_MAJOR_VERSION >= 3
+        tsig_name.data = (uint8_t *)strdup(PyBytes_AsString(PyUnicode_AsEncodedString(str, "ascii", NULL)));
+#else
+        tsig_name.data = (uint8_t *)strdup(PyBytes_AsString(str));
+#endif
+        tsig_name.size = (size_t)strlen((char *)tsig_name.data);
+        if ((ret = getdns_dict_set_bindata(addr_dict, "tsig_name", &tsig_name)) != GETDNS_RETURN_GOOD)  {
+            PyErr_SetString(getdns_error, "bad tsig name");
+            return NULL;
+        }
+    }
+
+    if ((str = PyDict_GetItemString(pydict, "tsig_algorithm")) != NULL)  {
+#if PY_MAJOR_VERSION >= 3
+        tsig_alg.data = (uint8_t *)strdup(PyBytes_AsString(PyUnicode_AsEncodedString(str, "ascii", NULL)));
+#else
+        tsig_alg.data = (uint8_t *)strdup(PyBytes_AsString(str));
+#endif
+        tsig_alg.size = (size_t)strlen((char *)tsig_alg.data);
+        if ((ret = getdns_dict_set_bindata(addr_dict, "tsig_algorithm", &tsig_alg)) != GETDNS_RETURN_GOOD)  {
+            PyErr_SetString(getdns_error, "bad tsig algorithm");
+            return NULL;
+        }
+    }
+
+    if ((str = PyDict_GetItemString(pydict, "tsig_secret")) != NULL)  {
+        tsig_secret.size = PyByteArray_Size(str);
+#if PY_MAJOR_VERSION >= 3
+        tsig_secret.data = (uint8_t *)strdup(PyBytes_AS_STRING(str));
+#else
+        tsig_secret.data = (uint8_t *)strdup(PyBytes_AsString(str));
+#endif
+        if ((ret = getdns_dict_set_bindata(addr_dict, "tsig_secret", &tsig_secret)) != GETDNS_RETURN_GOOD)  {
+            PyErr_SetString(getdns_error, "bad tsig secret");
+            return NULL;
+        }
+    }
+
+    if ((str = PyDict_GetItemString(pydict, "tls_pubkey_pinset")) != NULL)  {
+        Py_ssize_t pinset_len;
+        int  i;
+        PyObject *py_item;
+        char *str_item;
+        getdns_dict *pubkey_pin = 0;
+
+        if (!PyList_Check(str))  {
+            PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
+            return NULL;
+        }
+        pinset_len = PyList_Size(str);
+        if (pinset_len == 0)    {
+            PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
+            return NULL;
+        }
+        tls_pubkey_pinset = getdns_list_create();
+        for ( i = 0 ; i < (int)pinset_len ; i++ )  {
+            py_item = PyList_GetItem(str, (Py_ssize_t)i);
+#if PY_MAJOR_VERSION >= 3
+            str_item = PyBytes_AsString(PyUnicode_AsEncodedString(py_item, "ascii", NULL));
+#else
+            str_item = PyString_AsString(py_item);
+#endif
+            pubkey_pin = getdns_pubkey_pin_create_from_string(0, str_item);
+            if (pubkey_pin == NULL)  {
+                PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
+                return NULL;
+            }
+            if ((ret = getdns_list_set_dict(tls_pubkey_pinset, i, pubkey_pin)) != GETDNS_RETURN_GOOD)  {
+                PyErr_SetString(getdns_error, GETDNS_RETURN_GENERIC_ERROR_TEXT);
+                return NULL;
+            }
+        }
+        if (pubkey_pin)
+            getdns_dict_destroy(pubkey_pin);
+        getdns_dict_set_list(addr_dict, "tls_pubkey_pinset", tls_pubkey_pinset);
+    }
+
+    if ((str = PyDict_GetItemString(pydict, "port")) != NULL)  {
+#if PY_MAJOR_VERSION >= 3
+        if (!PyLong_Check(str))  {
+#else
+        if (!PyInt_Check(str))  {
+#endif
+            PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
+            return NULL;
+        }
+#if PY_MAJOR_VERSION >= 3
+        port = (uint32_t)PyLong_AsLong(str);
+#else
+        port = (uint32_t)PyInt_AsLong(str);
+#endif
+        getdns_dict_set_int(addr_dict, "port", port);
+    }
+
+    if ((str = PyDict_GetItemString(pydict, "tls_port")) != NULL)  {
+#if PY_MAJOR_VERSION >= 3
+        if (!PyLong_Check(str))  {
+#else
+        if (!PyInt_Check(str))  {
+#endif
+            PyErr_SetString(getdns_error, GETDNS_RETURN_INVALID_PARAMETER_TEXT);
+            return NULL;
+        }
+#if PY_MAJOR_VERSION >= 3
+        tls_port = (uint32_t)PyLong_AsLong(str);
+#else
+        tls_port = (uint32_t)PyInt_AsLong(str);
... 130 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-getdns.git



More information about the Python-modules-commits mailing list