From 63533a891f36220bd81a5db84f8b3ec44e00f5ac Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Fri, 24 Jun 2016 16:13:30 +1000 Subject: [PATCH] 4397. [bug] Update Windows python support. [RT #42538] (cherry picked from commit 9f5443280fcfd625a06f63a1b457ed2335840278) --- CHANGES | 4 +- bin/dnssec/win32/dsfromkey.vcxproj.in | 2 +- bin/python/dnssec-checkds.py.in | 3 +- bin/python/dnssec-coverage.py.in | 3 +- bin/python/isc/utils.py.in | 26 +++++++- configure.in | 2 +- lib/isc/win32/libisc.vcxproj.in | 1 + win32utils/Configure | 87 +++++++++++++++++++++++---- win32utils/build.txt | 47 +++++++++++++-- win32utils/legacy/BuildPost.bat.in | 9 +++ win32utils/legacy/BuildSetup.bat.in | 1 + win32utils/readme1st.txt | 13 ++++ 12 files changed, 175 insertions(+), 23 deletions(-) diff --git a/CHANGES b/CHANGES index 755339bfa3..5704d1d23b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,6 @@ -4395 [bug] Improve out-of-tree installation of python modules. +4397. [bug] Update Windows python support. [RT #42538] + +4395. [bug] Improve out-of-tree installation of python modules. [RT #42586] 4387. [bug] Change 4336 was not complete leading to SERVFAIL diff --git a/bin/dnssec/win32/dsfromkey.vcxproj.in b/bin/dnssec/win32/dsfromkey.vcxproj.in index 4fa6afdadb..112577e9d5 100644 --- a/bin/dnssec/win32/dsfromkey.vcxproj.in +++ b/bin/dnssec/win32/dsfromkey.vcxproj.in @@ -123,4 +123,4 @@ copy /Y dnssec-coverage.py ..\..\Build\$(Configuration)\dnssec-coverage.py - \ No newline at end of file + diff --git a/bin/python/dnssec-checkds.py.in b/bin/python/dnssec-checkds.py.in index 16774fb501..ef75646bc5 100644 --- a/bin/python/dnssec-checkds.py.in +++ b/bin/python/dnssec-checkds.py.in @@ -19,7 +19,8 @@ import os import sys sys.path.insert(0, os.path.dirname(sys.argv[0])) -sys.path.insert(1, os.path.join('@prefix@', 'lib')) +if os.name != 'nt': + sys.path.insert(1, os.path.join('@prefix@', 'lib')) import isc.checkds diff --git a/bin/python/dnssec-coverage.py.in b/bin/python/dnssec-coverage.py.in index af33331a22..5d897ba2d6 100644 --- a/bin/python/dnssec-coverage.py.in +++ b/bin/python/dnssec-coverage.py.in @@ -19,7 +19,8 @@ import os import sys sys.path.insert(0, os.path.dirname(sys.argv[0])) -sys.path.insert(1, os.path.join('@prefix@', 'lib')) +if os.name != 'nt': + sys.path.insert(1, os.path.join('@prefix@', 'lib')) import isc.coverage diff --git a/bin/python/isc/utils.py.in b/bin/python/isc/utils.py.in index f73dda4873..2738633b90 100644 --- a/bin/python/isc/utils.py.in +++ b/bin/python/isc/utils.py.in @@ -31,13 +31,32 @@ def prefix(bindir=''): if os.name != 'nt': return os.path.join('@prefix@', bindir) + hklm = win32con.HKEY_LOCAL_MACHINE bind_subkey = "Software\\ISC\\BIND" + sam = win32con.KEY_READ h_key = None key_found = True + # can fail if the registry redirected for 32/64 bits try: - h_key = win32api.RegOpenKeyEx(win32con.HKEY_LOCAL_MACHINE, bind_subkey) + h_key = win32api.RegOpenKeyEx(hklm, bind_subkey, 0, sam) except: key_found = False + # retry for 32 bit python with 64 bit bind9 + if not key_found: + key_found = True + sam64 = sam | win32con.KEY_WOW64_64KEY + try: + h_key = win32api.RegOpenKeyEx(hklm, bind_subkey, 0, sam64) + except: + key_found = False + # retry 64 bit python with 32 bit bind9 + if not key_found: + key_found = True + sam32 = sam | win32con.KEY_WOW64_32KEY + try: + h_key = win32api.RegOpenKeyEx(hklm, bind_subkey, 0, sam32) + except: + key_found = False if key_found: try: (named_base, _) = win32api.RegQueryValueEx(h_key, "InstallDir") @@ -56,4 +75,7 @@ def shellquote(s): version = '@BIND9_VERSION@' -sysconfdir = '@expanded_sysconfdir@' +if os.name != 'nt': + sysconfdir = '@expanded_sysconfdir@' +else: + sysconfdir = prefix('etc') diff --git a/configure.in b/configure.in index cb02cfec8e..e913ae0012 100644 --- a/configure.in +++ b/configure.in @@ -223,7 +223,7 @@ AC_ARG_WITH(python, [ --with-python=PATH specify path to python interpreter], use_python="$withval", use_python="unspec") -python="python python3 python3.4 python3.3 python3.2 python3.1 python3.0 python2 python2.7 python2.6 python2.5 python2.4" +python="python python3 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2 python2.7 python2.6 python2.5 python2.4" testargparse='try: import argparse except: exit(1)' diff --git a/lib/isc/win32/libisc.vcxproj.in b/lib/isc/win32/libisc.vcxproj.in index cbe0a85bab..8eebc9f92d 100644 --- a/lib/isc/win32/libisc.vcxproj.in +++ b/lib/isc/win32/libisc.vcxproj.in @@ -209,6 +209,7 @@ copy ..\bin\dnssec\dnssec-importkey.html ..\Build\Release @IF PYTHON copy ..\bin\python\dnssec-checkds.html ..\Build\Release copy ..\bin\python\dnssec-coverage.html ..\Build\Release +copy ..\bin\python\dnssec-keymgr.html ..\Build\Release @END PYTHON @IF PKCS11 copy ..\bin\pkcs11\pkcs11-keygen.html ..\Build\Release diff --git a/win32utils/Configure b/win32utils/Configure index 8ecabc184e..fbcbd612c1 100644 --- a/win32utils/Configure +++ b/win32utils/Configure @@ -80,6 +80,8 @@ my @filelist = ("..\\bin\\check\\win32\\checktool.dsp", "..\\bin\\pkcs11\\win32\\pk11tokens.mak", "..\\bin\\python\\dnssec-checkds.py", "..\\bin\\python\\dnssec-coverage.py", + "..\\bin\\python\\dnssec-keymgr.py", + "..\\bin\\python\\isc\\utils.py", "..\\bin\\rndc\\win32\\rndc.dsp", "..\\bin\\rndc\\win32\\rndc.mak", "..\\bin\\rndc\\win32\\rndcutil.dsp", @@ -439,6 +441,7 @@ my @substvar = ("BIND9_VERSION", "COPTMLD", "COPTX", "COPTY", + "expanded_sysconfdir", "INTRINSIC", "MACHINE", "OPENSSL_PATH", @@ -2336,23 +2339,84 @@ if ($use_python eq "no") { } my $pythonret = `python -c "quit()" 2>&1`; if ($? != 0) { - die "can't launch the python interpreter: $pythonret\n"; + print STDERR "can't launch the python interpreter: $pythonret\n"; + $use_python = "no"; } - $use_python = "yes"; } if ($use_python ne "no") { - if ($verbose) { + if ($use_python ne "auto") { + if ($verbose) { + print "checking for $python_command\n"; + } my $pythonret = `"$python_command" -c "quit()" 2>&1`; if ($? != 0) { - print STDERR - "can't lanch the local python interpreter: $pythonret\n"; + die "can't launch $python_command: $pythonret\n"; } } - $configcond{"PYTHON"} = 1; - $configdefd{"USE_PYTHON"} = "USE_PYTHON"; - $configvar{"PYTHON"} = "$python_command"; - # Only a default! - $configvar{"prefix"} = "C:\\Program Files\ISC BIND 9"; + if ($verbose) { + print "checking for python module 'argparse'\n"; + } + my $pythonret = `"$python_command" -c "import argparse" 2>&1`; + if ($? != 0) { + if ($use_python ne "auto") { + die "can't find python module 'argparse': $pythonret\n"; + } else { + print STDERR "can't find python module 'argparse': $pythonret\n"; + $use_python = "no"; + } + } + if ($use_python ne "no") { + if ($verbose) { + print "checking for python module 'ply'\n"; + } + $pythonret = `"$python_command" -c "from ply import *" 2>&1`; + if ($? != 0) { + if ($use_python ne "auto") { + die "can't find python module 'ply': $pythonret\n"; + } else { + print STDERR "can't find python module 'ply': $pythonret\n"; + $use_python = "no"; + } + } + } + if ($use_python ne "no") { + if ($verbose) { + print "checking for python module 'win32api'\n"; + } + $pythonret = `"$python_command" -c "import win32api" 2>&1`; + if ($? != 0) { + if ($use_python ne "auto") { + die "can't find python module 'win32api': $pythonret\n"; + } else { + print STDERR + "can't find python module 'win32api': $pythonret\n"; + $use_python = "no"; + } + } + } + if ($use_python ne "no") { + if ($verbose) { + print "checking for python module 'win32con'\n"; + } + $pythonret = `"$python_command" -c "import win32con" 2>&1`; + if ($? != 0) { + if ($use_python ne "auto") { + die "can't find python module 'win32con': $pythonret\n"; + } else { + print STDERR + "can't find python module 'win32con': $pythonret\n"; + $use_python = "no"; + } + } + } + if ($use_python ne "no") { + $configcond{"PYTHON"} = 1; + $configdefd{"USE_PYTHON"} = "USE_PYTHON"; + $configvar{"PYTHON"} = "$python_command"; + # Doesn't matter + $configvar{"prefix"} = "__prefix__"; + $configvar{"expanded_sysconfdir"} = "__prefix__\\etc"; + } } # with-vcredist @@ -2964,9 +3028,10 @@ sub makeinstallfile { print LOUT "pkcs11-list.exe-BNFF\n"; print LOUT "pkcs11-tokens.exe-BNFF\n"; } - if ($use_python eq "yes") { + if ($use_python ne "no") { print LOUT "dnssec-checkds.py-BNFF\n"; print LOUT "dnssec-coverage.py-BNFF\n"; + print LOUT "dnssec-keymgr.py-BNFF\n"; } print LOUT "readme1st.txt-BTFT\n"; close LOUT; diff --git a/win32utils/build.txt b/win32utils/build.txt index 5e99880e30..bc7b57a355 100644 --- a/win32utils/build.txt +++ b/win32utils/build.txt @@ -23,6 +23,9 @@ If you wish to use IP geolocation, GeoIP API and database must be downloaded, patched and built on the system on which you are building BIND. +If you wish to use python tools, you need a python (version 2 or 3) +interpreter with its standard libraries. + If you wish to use readline, the readline library must be downloaded and built on the system on which you are building BIND. @@ -118,7 +121,25 @@ Step 3: Download and build GeoIP This patch has been submitted upstream, and will be included in future versions of libGeoIP. -Step 4: Download and build Readline +Step 4: Enable python tools + + Some python packages are required: argparse, ply, win32con and win32api. + Last CPython's (version 2 or 3) from http://www.python.org include + the pip package manager which can install missing packages, for + instance for the 2 last packages 'pip install pypiwin32' downloads and + installs win32con and win32api. + + Note when the python interpreter is in the command path and + the required packages available the Configure script will detect + them and add python tools to the BIND build. + + To be used a python tool must be invoked with python (e.g., + python dnssec-checkds.py ) as the shebang doesn't work + on Windows. The isc package should be installed too, cf step 11. + At the opposite of Unix this isc package uses the Registry to + learn where BIND was installed in step 10. + +Step 5: Download and build Readline The readline library adds command-line editing in nslookup and nsupdate. If you wish to build BIND 9 without support for this feature, skip to @@ -134,7 +155,7 @@ Step 4: Download and build Readline Note: Windows command (cmd.exe) provides an integrated line edition feature so it is not recommended to configure bind with readline. -Step 5: Make the redistributable runtime object available +Step 6: Make the redistributable runtime object available Check that the Microsoft redistributable object (vcredist_x86.exe or vcredist_x64.exe) is available to the build. The file may be placed @@ -146,7 +167,7 @@ Step 5: Make the redistributable runtime object available step 4). If none of these options is used, Configure will attempt to find the redistributable based on clues in the build environment. -Step 6: Configuring the BIND build +Step 7: Configuring the BIND build From the command prompt, cd to the win32utils directory under the BIND 9 root: @@ -170,7 +191,7 @@ Step 6: Configuring the BIND build perl Configure clean -Step 7: Building BIND +Step 8: Building BIND To build using 'nmake' or older versions of Visual Studio (e.g. VS 2005 or VS 2008), go to the legacy subdirectory: @@ -194,7 +215,10 @@ Step 7: Building BIND Note: This mode does not support building for Windows XP. -Step 8: Install + After this step this documentation applies to external or remote + builds, i.e., is common with installation. + +Step 9: Install Installation is accomplished by running the BINDInstall program. All DLL's are copied to the Program Files area and all applications @@ -217,5 +241,18 @@ Step 8: Install The idea is to be able to use any BINDInstall.exe binary so a non-free version of Visual Studio is no longer required. +Step 10: Python package install + + When BIND was built with python support, the isc python package + must be installed locally by: + + cd + cd bin/python + python setup.py install + + (replace 'python' by the path of your python interpreter if needed.) + + BIND python tools should work with version 2 or 3, 32 or 64 bits. + Please report bugs, whether in the process of building the application or in BIND 9 itself, to bind9-bugs@isc.org. diff --git a/win32utils/legacy/BuildPost.bat.in b/win32utils/legacy/BuildPost.bat.in index cdcdbb1cf4..53a2f20b99 100644 --- a/win32utils/legacy/BuildPost.bat.in +++ b/win32utils/legacy/BuildPost.bat.in @@ -34,6 +34,15 @@ copy /Y ..\..\bin\python\dnssec-checkds.py ..\..\Build\Release\dnssec-checkds.py copy /Y ..\..\bin\python\dnssec-checkds.py ..\..\Build\Debug\dnssec-checkds.py copy /Y ..\..\bin\python\dnssec-coverage.py ..\..\Build\Release\dnssec-coverage.py copy /Y ..\..\bin\python\dnssec-coverage.py ..\..\Build\Debug\dnssec-coverage.py + +echo Build python parser + +cd ..\..\bin\python\isc +@PYTHON@ policy.py parse \dev\nul +set PYTHONPATH=. +@PYTHON@ -m parsetab +cd ..\..\..\win32utils\legacy + @END PYTHON echo Done. diff --git a/win32utils/legacy/BuildSetup.bat.in b/win32utils/legacy/BuildSetup.bat.in index 729ce9f2f8..b20533faf1 100644 --- a/win32utils/legacy/BuildSetup.bat.in +++ b/win32utils/legacy/BuildSetup.bat.in @@ -74,6 +74,7 @@ copy ..\..\bin\dnssec\dnssec-importkey.html ..\..\Build\Release @IF PYTHON copy ..\..\bin\python\dnssec-checkds.html ..\..\Build\Release copy ..\..\bin\python\dnssec-coverage.html ..\..\Build\Release +copy ..\..\bin\python\dnssec-keymgr.html ..\..\Build\Release @END PYTHON @IF PKCS11 copy ..\..\bin\pkcs11\pkcs11-keygen.html ..\..\Build\Release diff --git a/win32utils/readme1st.txt b/win32utils/readme1st.txt index 89ba436827..02d0e50cf6 100644 --- a/win32utils/readme1st.txt +++ b/win32utils/readme1st.txt @@ -13,6 +13,19 @@ Unpack the kit into any convenient directory and run the BINDInstall program. This will install the named and associated programs into the correct directories and set up the required registry keys. +Usually BINDInstall must be run by/as Administrator or it can fail +to operate on the filesystem or the registery or even return messages +like 'A referral was returned from the server". The best way to +avoid this kind of problems on Windows 7 or newer is: + - open a "file explorer" aka finder windows + - goes where the distribution was expanded + - click right on the BINDInstall application + - open "Properties" (last) menu + - open "Compatibility" (second) tab + - check on the (last) "Run this program as an administrator" +Unfortunately this is not saved by zip (or any archiver?) as +it is a property saved in the Registry. + BINDInstall requires that you install it under an account with restricted privileges. The installer will prompt you for an account name (the default is "named") and a password for that account. It