dnssec-trigger-0.13/0000775000175000017500000000000013024457644014024 5ustar wouterwouterdnssec-trigger-0.13/Changelog0000664000175000017500000007742313017046554015647 0ustar wouterwouter28 November 2016: Wouter - Updated acx_nlnetlabs.m4 for openssl-1.1.0 compatibility. - Patch for openssl-1.1.0 compilation. 8 June 2016: Wouter - Tomas Hozza (3): dnssec-trigger-script: Use ducktaping when restarting NM, instead of checking the sysfs dnssec-trigger-script: Silence the calls to chattr Improved text in the panel GUI when insecure mode is forced 9 December 2015: Wouter - Remove kickstarts of daemons because daemon died for test user. 8 December 2015: Wouter - Fixup compile on OSX with static SSL for makedist mac build. - OSX hide unbound user from login screen. - Attempt to stop panels and kickstart daemons on OSX. 7 December 2015: Wouter - Remove stuff from osx installer that logs out the user. 4 December 2015: Wouter - Fixup osx gui panel start code for new osx. installer talks about new locations and set permissions on key files and add to the path the /usr/local/sbin directory during install. Do not link RiggerStatusItem to /usr/local/opt/openssl/lib. 3 December 2015: Wouter - chmod key files for unbound, dnssec-trigger control and ldns in /usr/local. For OSX. - Fixup installer for creation of missing keys, and also start panel in osx userspace. 26 November 2015: Wouter - Fix Makefile for use of /Library, which seems okay for new OSX. - makedist prints checksums on OSX. 6 November 2015: Wouter - new acx_nlnetlabs.m4 version and it has the libdl fix. - Fix lint warnings about int and size_t conversion. - Fixes to make the installer work on OSX-ElCapitan. 6 October 2015: Wouter - Patch for preliminary Mac OSX 10.11 support (from Philip Paeps). - Move plists into uidir on OSX (/usr/local/share), and set usr/local in makedist for OSX. 1 October 2015: Wouter - default keysize for control is 3072 on windows. 31 August 2015: Wouter - Changed windows setup compression to be more transparent. 16 July 2015: Wouter - Patches from Tomas Hozza for systemd service files: Set PIDFile in the dnssec-triggerd.service file. Remove restorecon call in dnssec-triggerd-keygen.service. 14 July 2015: Wouter - Patches from Tomas Hozza for dnssec-trigger-script: Use one import on one line as defined by PEP8. Use path to DEVNULL from os module. Move the main functionality into main() function to enable testing. Use existing API in NM for distinguishing VPN connections. Construct NMClient as advised by the documentation. Forbid Python from searching local dirs and using env variables. Set low max negative cache TTL to prevent possible user issues. Send SIGHUP to NM if it is new enough instead of restarting it. Set the required version in GI before importing NMClient. 13 July 2015: Wouter - Fix #618: create sha1 and sha256 hashes for created binaries, fixed in makedist.sh. 10 July 2015: Wouter - Renamed 'open resolvers' to 'relay resolvers' in the explanatory text what dnssec-trigger is doing. Resolvers from DHCP can also be public resolvers, so the term relay resolver is used for an open resolver that performs transport layer adjustment. 8 April 2015: Wouter - Patches from Tomas Hozza for dnssec-trigger-script: Add newlines between classes to conform with PEP-8 and increase readability. Add/remove local zones in Unbound when configuring reverse addr forward zones. 7 April 2015: Wouter - Patch from Tomas Hozza: dnssec-trigger-script: Don't configure RFC1918 zones if there are no global forwarders. 12 March 2015: Wouter - Patches from Tomas Hozza (7): dnssec-trigger-script: Fix wrong default value in configuration dnssec-trigger-script: Fix formatting errors dnssec-trigger-script: Remove unused class Allow to select the default Python interpretter during build Fix 01-dnssec-trigger NOT to hardcode shell path dnssec-trigger-script: Fix typo when adding search domains dnssec-trigger-control-setup: Use 3072 bit keys 26 January 2015: Wouter - Patches from Pavel Simerda: dnssec-trigger-script: check for paths, not files https://bugzilla.redhat.com/show_bug.cgi?id=1183975 dnssec-trigger-script: fix secure/insecure forward zone switching https://bugzilla.redhat.com/show_bug.cgi?id=1185796 dnssec.conf: clean up the dnssec.conf comments dnssec-trigger-script: log dnssec-trigger-control and unbound-control calls dnssec-trigger-script: use a global config object dnssec-trigger-script: add option to set search domains in /etc/resolv.conf https://bugzilla.redhat.com/show_bug.cgi?id=1130502 dnssec-trigger-script: add (undocumented) option to avoid flushing positive answers https://bugzilla.redhat.com/show_bug.cgi?id=1105685 dnssec-trigger-script: use private address ranges https://bugzilla.redhat.com/show_bug.cgi?id=1128310 21 January 2015: Wouter - Patches from Pavel Simerda: dnssec-trigger-script: clean up servers as well, for restart dnssec-trigger-script: prefer VPN nameservers over default ones 13 January 2015: Wouter - Update OSX resolvehook to flush dns caches for new OSX release with "discoveryutil udnsflushcaches" and "discoveryutil mdnsflushcache". - Patches from Pavel Simerda: dnssec-trigger-script: The accepted version of NetworkManager patch uses `resolv.conf` instead of `resolv.conf.default`, https://bugzilla.gnome.org/show_bug.cgi?id=732941 dnssec-trigger-script: Leaking file descriptors is bad, especially when selinux or similar tool is used. https://bugzilla.redhat.com/show_bug.cgi?id=1147705 dnssec-trigger-script: Use a regular file unless use_resolv_secure_conf_symlink is set. Always install /var/run/dnssec-trigger/resolv.conf for comparison. Guard all of those regular files using immutable attribute. https://bugzilla.redhat.com/show_bug.cgi?id=1165126 dnssec-trigger-script: fix desktop file paths. 21 November 2014: Wouter - Patches from Pavel Simerda: dnssec-trigger-script: lock --update-* methods only The original locking was a bit too broad for future development. dnssec-trigger-script: improve /etc/dnssec.conf handling Minor changes that make future /etc/dnssec.conf extensions easier. dnssec-trigger-script: support 'debug' option in /etc/dnssec.conf With that you can get the debugging output even for instances run by systemd, dnssec-triggerd and NetworkManager dispatcher. dnssec-trigger-script: clean up resolv.conf backup and restore Clean up the code a bit so that later additions dont turn it into a mess. dnssec-trigger-script: use /var/run/NetworkManager/resolv.conf.default Avoid restarting NetworkManager just to restore /etc/resolv.conf when a simple symlink would do. This is only done when the NetworkManager's private resolv.conf actually exists. allow the resolv.conf hooks be handled by dnssec-trigger-script dnssec-trigger-script: handle resolv.conf events from the daemon The new implementation doesn't write directly to /etc/resolv.conf and instead it writes a temporary file and then replaces the /etc/resolv.conf using POSIX `rename()`. dnssec-trigger-script: support /etc/resolv.conf and /etc/resolv-secure.conf symlinks This is an experimental feature and is turned off by default. You need to put the following to /etc/dnssec.conf to activate it: use_resolv_conf_symlink=yes probe: use wildcard probing domains This change might need to be revisited to see whether we need to check both known wildcard and known non-wildcard domains. - Fix #629: bad if test in net_help for ctx_load_verify_locations. 31 July 2014: Wouter - Patch from Pavel Simerda: improve dnssec-trigger-script locking and avoid a dependency. 15 July 2014: Wouter - Fix NetworkManager script fails t parse nmcli version as of 0.9.10.0, patch from Gerald Turner. 3 July 2014: Wouter - Patches from Ondrej Sury (from the Debian package): Remove some ugly bashisms from the script. Fixes static paths that right be mismatched (f.e. on multiarch system). Fix IndexError in dnssec-trigger-script, when there less then 4 resolvers since you use 3xfields.pop(0) before that. Fix release date in makedist manpage to be more stable. Do substitutions in makefile, more autoconf'y Fixup dnssec-triggerd.service from Makefile.in 1 July 2014: Wouter - Better fix for pidof that sets PATH for networkmanager dispatcher script (from Ondrej Sury). 30 June 2014: Wouter - Add --with-pidof=/usr/sbin/pidof where you can set the location of the pidof command to use in the Networkmanager script, /usr/bin/pidof or /usr/sbin/pidof (depending no your distribution). 25 June 2014: Wouter - Patches from Pavel Simerda: improve systemctl call. serialize script instances. 23 June 2014: Wouter - Patches from Pavel Simerda: Fixup for python2. fix a race condition with NetworkManager restart. don't fail on empty connection list. move legacy connection handling to the cleanup phase. don't block on systemctl restart NetworkManager. 20 June 2014: Wouter - Patches from Pavel Simerda: fix bug that prevents calling dnssec-trigger-control submit (https://bugzilla.redhat.com/show_bug.cgi?id=1105896) avoid dependency on pidof handle missing resolv.conf backup gracefully upgrade zone cache format at startup ( https://bugzilla.redhat.com/show_bug.cgi?id=1111143) always log to stderr 4 June 2014: Wouter - Patch from Pavel Simerda. This, among other things, allows to restart unbound and/or dnssec-trigger without restarting NetworkManager when it's configured not to touch the DNS. And, avoid Filenotfounderror not available in python 2, https://bugzilla.redhat.com/show_bug.cgi?id=1100794 And fix unbound output parser https://bugzilla.redhat.com/show_bug.cgi?id=1100796 22 May 2014: Wouter - release 0.12. - trunk is 0.13 in development. - updated authority server addresses builtin to dnssec-trigger for d root server (ipv4) and c root server (ipv6) for its tests. 7 May 2014: Wouter - Updated dnssec-trigger-script.in to distinguish secure and insecure zones, and to flush the unbound cache on DNS server list changes. (from Pavel Simerda). 15 April 2014: Wouter - Change the ip-address of tcp and ssl service from broer.nlnetlabs.nl to zus.nlnetlabs.nl (we changed netblocks). The new ip address and new certificate fingerprint (because of ssl heartbleed vuln) are in the example.conf file. The cert was only used for transport and not for authentication, so its change was low priority. 8 April 2014: Wouter - Patch for dnssec-trigger-script.in --async flag from Pavel Simerda, stops dnssec-trigger-script to block on networkmanager, which is good in cases when networkmanager blocks on the script. 28 March 2014: Wouter - Patch from Pavel Simerda that incorporates contrib items into the build install system. Systemd scripts, dnssec-trigger-script, dnssec.conf. 24 March 2014: Wouter - Renamed 01-dnssec-trigger-hook to 01-dnssec-trigger with the networkmanager naming scheme. (From Pavel Simerda). - put contrib/01-dnssec-trigger into 01-dnssec-trigger.in 24 March 2014: Wouter - Removed files obsoleted by patch from Pavel Simerda: contrib/01-dnssec-trigger-hook-new_nm (replaced with dnssec-trigger-script and 01-dnssec-trigger) fedora/dnssec-triggerd.service (new version in contrib) fedora/dnssec-triggerd-resolvconf-handle.service (handled by dnssec-triggerd.service directly) fedora/dnssec-trigger.spec (spec files are maintained separately) fedora/dnssec-triggerd-keygen.service (new version in contrib) fedora/dnssec-triggerd-resolvconf-handle.sh (handled by dnssec-trigger-script directly) fedora/dnssec-triggerd.init (only used in epel6 which hasn't been updated for ages) 21 March 2014: Wouter - Patch from Pavel Simerda: better integration with NetworkManager and distributions, added in contrib. 13 February 2014: Wouter - Patches from Tomass Hozza; Explicitly-use-Python2-interpreter, Fix-situation-when-connection-is-going-down, resolv.conf-backup-script-restart-NM-to-handle-resolv.conf, Update-systemd-service-files-to-latest-version-used. 7 February 2014: Wouter - Fix #551: Change Regents to Copyright holder in License. 28 January 2014: Wouter - Added patch to networkmanager dispatcher script and also an example dnssec.conf file from Tomas Hozza. 21 January 2014: Wouter - Added contrib networkmanager dispatcher script from Tomas Hozza. 25 November 2013: Wouter - Added fedora/dnssec-trigger-resolvconf-handle.sh from Tomas Hozza, that will backup and restore resolv.conf for use in systemd.service scripts and networkmanager scripts. 15 November 2013: Wouter - Patch from Tomas Hozza that improves text in dialogs (on linux). 14 November 2013: Wouter - Fix NM dispatcher script to work with NM >= 0.9.9.0 (Thanks Tomas Hozza). 26 August 2013: Wouter - Fix#522: Errors found by static analysis of source from Tomas Hozza. 6 August 2013: Wouter - Patch from Tomas Hozza to improve the networkmanager connect script for VPN connections. It adds forward zones for the VPN over the VPN connection. 3 May 2013: Wouter - Update acx_nlnetlabs.m4 to deal with newer mingw and sleep. 2 May 2013: Wouter - Fixup new glib deprecated calls. 1 May 2013: Wouter - Let system dealloc feed and feed_lock on OSX and Linux/BSD. 22 April 2013: Wouter - Fixup OSX backquote backslashes. Removed wrong OSX version from its installer text. 19 April 2013: Wouter - Fixup snprintf return value usage. 8 April 2013: Wouter - OSX wake listener implementation. - patch for OSX that passes all domains from search to the OS (from Phil Pennock). 27 March 2013: Wouter - update makedist for new svn and new crosscompile environment. 26 March 2013: Wouter - Update configure, install-sh with newer autoconf. 7 March 2013: Wouter - bug 489: removed Application deprecated keyword from .desktop file. 31 July 2012: Wouter - Fixup uniqueid for Mountain Lion OSX 10.8 release, you have to run the installer again (upgrade or uninstall-reinstall). 2 July 2012: Wouter - Fix networkmanager hook to detect if it has to use the new commandline syntax of networkmanager 0.9.4. 15 June 2012: Wouter - Fix crash on read of ssl443 entry without a hash. - Squelch address family not supported errors (on low verbosity). 8 June 2012: Wouter - Fix OSX user panel stop and start in reinstall, also fix for double popups during reinstall. - lint clean. 7 June 2012: Wouter - tag 0.11 release. - trunk is 0.12 is development. - log correct type in timeout for TXT. - restart panels on install on OSX. 6 June 2012: Wouter - fix permissions on root key for OSX. 5 June 2012: Wouter - wait for old daemon to stop in osx install at setdns.sh. - fix OSX unbound to be able to write root.key from the chroot. - manpage for check-updates option. 1 June 2012: Wouter - Http redirect support, for plain http check, in case hotspot has a proxy that starts giving the internet contents. - GUI for OSX for software updates. - fix osx execl for software install. - update tray icon for osx software install. - fix osx comma in multiple DNS servers. - fix update installer 31 May 2012: Wouter - Fix bug in processing tray icon results from daemon. - url can contain numerical IP address and port number, in http implementation. 22 May 2012: Wouter - Fix windows upgrade to preserve config files and to preserve the installed (or not-installed) startmenu links. - Fix to not mess up the config files on a reinstall on windows. 21 May 2012: Wouter - windows runs installer from userspace. - windows dnssectrigger depends on unbound for boot invocation, this fixes an error where it cannot tell unbound what to do. - fix updater for double callback due to retry and double reply. - fix slash in downloaded file and executed file (windows). - linebuffer for dnssec-trigger-control stdout, for results printout. 18 May 2012: Wouter - improved printout of SSL_ERROR_SYSCALL errors. - do not print interface-unknown and conn-reset errors upon system restart for windows, only printed on high verbosity. 2 April 2012: Wouter - Remove debug print from update code. - Add debug prints to update code. - Fix FIONBIO error on windows. 30 March 2012: Wouter - windows implementation for update dialog and selfupdate. - work on osx update dialog and selfupdate. - lint clean. 29 March 2012: Wouter - fix exit of panel and threads - fix read multiple persist actions in one SSL packet frame. - gtk gui to ask for install of new software. No unix action exists. 26 March 2012: Wouter - lock unlock and delete at exit of panel is improved. 15 March 2012: Wouter - configure windows detects GetAdaptersAdresses (XP and later). - snapshot for test. - Fix compatibility with VirtualBox on Windows, that messes with the network adapters. Solution works on windows XP and later (detected by configure). - Fix trayicon on windows high DPI settings to look better. - silence connect() http errors, unless verbosity 2. - stop other download if one succeeds (happy eyeballs) on selfupdate. 13 March 2012: Wouter - self update work. 12 March 2012: Wouter - self update work. 9 March 2012: Wouter - update osx config to new config template. - login-command and login-location man page entries. - windows shows browser on login. - debug prints removed from http. 8 March 2012: Wouter - OSX GUI for no web access dialog. - OSX update dnssec-trigger.conf with new url settings. - OSX fix the double-window shown bug, bug in NSWindow deminiaturize func. - open web browser to login to a hot spot. 7 March 2012: Wouter - print syntax error for url config items. - skip_http control command. - raise dialog to top on GTK. - GTK gui for hot spot sign on. - workon windows GUI for no web hot spot sign on. 6 March 2012: Wouter - Fix memleak in new config url content. - Fix probe count when http is done. - probe logic that keeps track of http_insecure mode. - retry every 10 seconds for 5 minutes in http_insecure mode. - fix test_tcp, test_ssl, unsafe commands. - fix to show failed address lookups in probe results. 5 March 2012: Wouter - distinguish 2xx, 3xx and other (404) http rcodes. - config file contains the expected content of the urls. - ssl can list multiple hashes (for certificate rollover). 2 March 2012: Wouter - http check is performed, nonblocking. Lookup of addres(es), A, AAAA to the (up to 5) DHCP DNS resolvers. 3 urls are checked, until one connects, then it checks content. IP4 and IP6, until first works. - url for ster.nlnetlabs.nl and fedoraproject.org added in config. - absolute sbindir in netconfig hooks. 23 Feb 2012: Wouter - fedora package files updated. 22 Feb 2012: Wouter - Fix Fedora bug with no DNS servers in resolv.conf with absolute path in networkmanager hook script. - The .desktop entry name without 'panel'. 17 Feb 2012: Wouter - and osx status icon file changed. - release 0.10 - trunk is 0.11 under development. 16 Feb 2012: Wouter - Do not show the insecure and hotspot windows at the same time. - Fix for OSX to show the popups on top of the other windows. - alert icon easier to read. 25 Jan 2012: Wouter - version set to 0.10: dnssec-trigger is experimental. 23 Jan 2012: Wouter - updated acx.nlnetlabs.m4 for gcc 4.6 compat for portability tests. 19 Jan 2012: Wouter - show package version in probe results dialog. 17 Jan 2012: Wouter - do not just refresh the systray, but entire desktop (for windows). - fix dnssec-trigger-control error printout if SSL files fail. - dnssec-trigger-control uses registry config location (for windows). - install script removes leftover trayicons using direct windows API. 14 Jan 2012: Wouter - show version number in add-removeprograms configpanel (windows). - refresh systray after install to solve stray tray icon (for windows). 13 Jan 2012: Wouter - Use Processes.dll code (can be freely used, source provided) for kill process in windows NSIS installer. Compiled to 6kb (not 50kb). Processes.dll was made by Andrei Ciubotaru. - Attempt to add DHCPv6 support for windows. - If hotspot-signon, set override servers right away on a network change, so the user does not have to wait for 10 seconds after a change of the wifi. 10 Jan 2012: Wouter - truncate pidfile portable to windows. 6 Jan 2012: Wouter - truncate pidfile (just like NSD fix, in case directory not owned). 19 Dec 2011: Wouter - wait some more during reinstall on windows, to help race condition. - release 0.9 - trunk is 1.0 under development. 16 Dec 2011: Wouter - attempt to fix endless loop on windows (reported by Alan Clegg). - windows installer waits for services to come to a full stop. 15 Dec 2011: Wouter - detailprints in windows installer and uninstaller. - stoppanels waits for the connection of the panel to close, this may remove re-install race conditions. 14 Dec 2011: Wouter - Set hook throttleinterval to 1 second, this reduces the osx wakeup and bootup wrong probes because the hook was throttled for 10 seconds. 13 Dec 2011: Wouter - release 0.8. - trunk is 0.9 under development. 12 Dec 2011: Wouter - Fix apple brick by installer, because of tarfile inclusion of extended attributes that overwrote system dir extended attributes. 5 Dec 2011: Wouter - sigHUP reloads config and reopens logfile for log rotation support. - acxnlnetlabs updated to version 17. - fix fedora16 windows crosscompile. - fix double definition of malloc. 2 Dec 2011: Wouter - configure generated with autoconf 2.6.8. 30 Nov 2011: Wouter - Fix where race condition could cause blacklist of open resolver. - Fix to flush_infra and flush_requestlist when we use open resolver, the proxy that causes this to be used as fallback has polluted those entries (possibly). 29 Nov 2011: Wouter - Fix bug where no IPv6 causes wrong test results, notably SSL, due to the error report code. 13 Nov 2011: Wouter - control unsafe shows the dialog popup again. 9 Nov 2011: Wouter - Fix that if network down (nothing pings) then it picks disconnect, for slow bootup where the machine has the previous network settings. 8 Nov 2011: Wouter - the test_tcp and test_ssl command do not have the 20-sec tcpretry once timer, so that the test can try unbound. - config for new open resolver (port 80 TCP, port 443 SSL). No more probe plain tcp on port 443. 7 Nov 2011: Wouter - fixed the OSX installer problem, launchd does not load userspace agents without hacks, and has side-effects that enables boot-start. - more detailed logging at verbosity 4 (prints wire and dig output). 4 Nov 2011: Wouter - on OSX update config if old (no ssl443). - on OSX install config file before attempting to modify it. 3 Nov 2011: Wouter - remove error dialog at end of osx install. 2 Nov 2011: Wouter - check ssl fingerprint of servers. - remind user on make install about ssl443. 1 Nov 2011: Wouter - probe ssl servers (nlnetlabs default server configured). 31 Oct 2011: Wouter - do not log errors for unclean ssl close. 28 Oct 2011: Wouter - documentation fixes - osx dmg install fix for 10.6 packager (start of userspace panel). also framework for debug logging in postflight of packager. 10.6 packages work on 10.7. 10.7 packages work on 10.7. - tag 0.7 - trunk is 0.8 under development. - macinstall, launch unbound-anchor at boot (update if offline months) - echo in Makefile and newline if no probe performed. 27 Oct 2011: Wouter - osx dmg install and uninstall works. - for caches, also test if NSEC3 is present for QTYPE=NULL nodata. 26 Oct 2011: Wouter - uninstall command for OSX (put in the DMG). 25 Oct 2011: Wouter - fix echo at end of make install. - osx makepackage, donated by Carsten Strotmann. 22 Oct 2011: Wouter - fix unknown options for dnssec-trigger-panel, prints version too. 21 Oct 2011: Wouter - Add @ to echo in Makefile. - print error on control unknown command, and exit status 1. - tag 0.6 - trunk is 0.7 under development. - fix that setup hint is not printed on a reinstall. - stop executables before re-install of dnssec-trigger. - tested to work on winXP (thanks Jan-Piet Mens). - fix printout of 1970 date, instead that no probe was performed. 18 Oct 2011: Wouter - Manpage fixes - can build outside of sourcedir. - libappindicator support, for Ubuntu Unity desktop GUI. 17 Oct 2011: Wouter - Fix insecure mode after dnstcp443 has been probed. - Fix OS-race on Linux/BSD, it sets immutable settings on install, and checks this regularly (and fixes if necessary). 13 Oct 2011: Wouter - the dnssec-trigger-panel (gtk2) works on the XFCE desktop. - windows package works, tested Vista. - osx fix for insecure mode. 12 Oct 2011: Wouter - makes resolv.conf immutable and restores on uninstall. 10 Oct 2011: Wouter - detect transparent proxies and avoid them. 29 Sep 2011: Wouter - mac cocoa gui for hotspot signon. - 0.5 release. 28 Sep 2011: Wouter - nsis uninstall welcome image. - gtk menu item and dialog for hotspot signon. - win32 menu item and dialog for hotspot signon. - install unbound with dnssec-trigger on windows. Reduced install size and available for configuration by installer.exe. 27 Sep 2011: Wouter - for windows, get unbound-control config and path from registry. - new IP6 address for the service at nlnetlabs. - fix for windows busy loop in dnssectriggerd. - do not log error for RPC server not started in windows. 26 Sep 2011: Wouter - tentative fix for windows loop bug: if wlanapi.dll does not load. 23 Sep 2011: Wouter - windows README is a proper .txt files for dos. - 0.4 release. - trunk is 0.5 in development. 22 Sep 2011: Wouter - dnssec-trigger-control reprobe command from the commandline. - dnssec-trigger-control hotspot_signon, forces insecure mode for a sign-on. The reprobe command can be used to stop forced_insecure. - added probe tcp80 and tcp443 as last resort. - retry for insecure and disconnect cases with exponential backoff, start 10 seconds, max 24h. - tcp retry after 20 seconds, in case more opens up or it was slow. 21 Sep 2011: Wouter - ignore UDP without QR flag: some DNS caches send echoes of the query back initially. If we ignore them we catch a (100 msec later) correct answer later. (or timeout if no answer comes). - if probe is in progress it prints that in status. - if no DNS servers via DHCP it prints that in status. - antialiased fonts in windows native gui. 20 Sep 2011: Wouter - fix configure --with-gui, it did not change the gui but hooks. - refactor GUI panel SSL feed to be more portable. - fix stop command. - native windows GUI. - status 'dark' is now called 'nodnssec'. 19 Sep 2011: Wouter - fix so that if it cannot bind socket the server fails to start. - fix so that on OSX no zombie process remains. - kill -HUP performs a reload on UNIX. It only reload the strings and that config, it keeps the running probe results and open sockets to panels and certificates. - include pangorc, pango.modules, loaders.cache (for gdk) and the pango-basic-win32.dll and gdk png loader dll (if present) in the windows installer. - panel.exe uses the windows gui subsystem. Include more pixloaders. - added fedora spec and init script. 16 Sep 2011: Wouter - fix OSX get of DHCP options to use ipconfig API instead of faulty awk parse. 15 Sep 2011: Wouter - fix makefile dependencies for sed-ed output. - tag 0.3. (0.2 was distributed with different contents). - trunk has 0.4 14 Sep 2011: Wouter - icons in higher bitdepth, install and uninstall icons. - stoppanels control command for installers to update that panel exe. - tag 0.2 - trunk has 0.3 13 Sep 2011: Wouter - pick up SSID (for windows, OSX) to filter trigger with, so an SSID change from the wlan triggers a reprobe. - set windres resource files, icons, log-format, useradmpermission and setup.exe script with NSIS, it includes dlls. 12 Sep 2011: Wouter - fix fd leaked every second by panel if the daemon was down. - more robust outq_delete function in code notation. - do not print ID values if mismatch (enabled on verbosity 4). - print time of probe with results. - fix double-close of FD in acceptfailure case. - close log file when daemon exits. 9 Sep 2011: Wouter - can override nameserver settings on windows (needs administrator permissions) and clears them away (back to the default) on exit. - fix not enough detection of network changes on OSX. - get a probe after start on OSX. - fix submit of disconnect state, submit "". - fix resolvconf writes on OSX: more chance of winning resolv.conf which is a small race what with setting scutil at the same time, and sets it after userlogin because OSX reprobes at user login. 8 Sep 2011: Wouter - Fix that windows DHCP hook fires less often: only if list of network and GUID of adapter and IPs changes. - unbound-control execute hook. - reshook for windows. 7 Sep 2011: Wouter - dnssec-triggerd can run as a windows service. - windows DHCP hook on network changes. - support nm-tool NetworkManager (older version). 6 Sep 2011: Wouter - dnssec-trigger-keygen that works without shellscripts. Can also generate for unbound. - keygen for windows compiled (it works on other ports, but they have shell scripts). 2 Sep 2011: Wouter - GUI tray icon works on windows. - minimal theme on windows. 1 Sep 2011: Wouter - install backups and uninstall restores resolv.conf. - watch on OSX the network.plist and airport.plist files and not the entire directory, which changes too often. - README and BSD LICENSE. - renamed plist nl.nlnetlabs.x 31 Aug 2011: Wouter - cocoa and gtk build and install and uninstall make targets - GTK autostart .desktop entry. - man page. 30 Aug 2011: Wouter - osx xcode status item. - you can test the Cocoa GUI with: cd osx/RiggerStatusItem/ Build/Release and then open RiggerStatusItem.app --args -c /full/ path/to/test.conf. And have full paths inside test.conf as well. 26 Aug 2011: Wouter - status control command shows the latest probe results (and exits). - use full path for unbound-control (for install in /opt of unbound). - icons at 22px on OSX. - osx dir and osx fixes: full paths, flush cache when secure again. - use scutil to set DNS on osx. 25 Aug 2011: Wouter - OSX launchd and loginitem installed. 24 Aug 2011: Wouter - configure fixed --with.. and test for sleep and random. 23 Aug 2011: Wouter - configure adapted for windows compile. - panel compiles and GUI shows with libGTK+-2.0 on windows. 18 Aug 2011: Wouter - INSTALL instructions. - fixed for ldns linkage. - fix generated key permissions, world readable for user keys. - tag 0.1 17 Aug 2011: Wouter - noaction option that takes no action but pretends. - fix linefeed in resolv.conf printout. - unsafe test option works reliably. - fix dialog destroy that deletes the dialog. - alert icon has nicer exclamation mark. - added configfile and example.conf. - Reprobe command. 16 Aug 2011: Wouter - detect localhost in DHCP DNS servers and skip them, because a loop from the resolver to itself is not good. Since localhost resolver may probe as a good DNS cache itself easily. - can detect network disconnect and acts appropriately (very quiet). - fix bug with active number of connections. - fix nice exit for panel on quit. - present insecure or disconnect choice. - unbound control hooks. - resolv.conf hooks. 15 Aug 2011: Wouter - log with time in readable format (to logfile), detects strftime. - removed debug printouts. - menu is positioned neatly under the statusicon. - result window has icon set and a title. - fix unref for result_window by reffing it in the init function. - stop using deprecated glib function for tooltip. - lint fixes. - can handle NSEC DS denials if a zone is (temporarily) insecure, detects that the denial is from the parent and contains NSEC. 12 Aug 2011: Wouter - persistant SSL connections to the server. 11 Aug 2011: Wouter - detection probes code. 10 Aug 2011: Wouter - working osx script, netconfig script and networkmanager script. 9 Aug 2011: Wouter - daemon code. 8 Aug 2011: Wouter - import of mismash of files from Unbound (BSD licensed). dnssec-trigger-0.13/fedora/0000775000175000017500000000000013024457644015264 5ustar wouterwouterdnssec-trigger-0.13/fedora/unbound-keygen.service0000664000175000017500000000056711721417503021600 0ustar wouterwouter[Unit] Description=Unbound Control Key And Certificate Generator After=syslog.target Before=unbound.service ConditionPathExists=!/etc/unbound/unbound_control.key [Service] Type=oneshot Group=unbound ExecStart=/usr/sbin/unbound-control-setup -d /etc/unbound/ ExecStart=/sbin/restorecon /etc/unbound/* RemainAfterExit=yes [Install] WantedBy=multi-user.target dnssec-trigger-0.13/fedora/tmpfiles-unbound.conf0000664000175000017500000000005311721417503021414 0ustar wouterwouterD /var/run/unbound 0755 unbound unbound - dnssec-trigger-0.13/fedora/unbound.spec0000664000175000017500000004421711721417503017612 0ustar wouterwouter%{?!with_python: %global with_python 1} %if %{with_python} %{!?python_sitelib: %global python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} %{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")} %endif Summary: Validating, recursive, and caching DNS(SEC) resolver Name: unbound Version: 1.4.16 Release: 2%{?dist} License: BSD Url: http://www.nlnetlabs.nl/unbound/ Source: http://www.unbound.net/downloads/%{name}-%{version}.tar.gz Source1: unbound.service Source2: unbound.conf Source3: unbound.munin Source4: unbound_munin_ Source5: root.key Source6: dlv.isc.org.key Source7: unbound-keygen.service Source8: tmpfiles-unbound.conf Patch1: unbound-1.2-glob.patch Group: System Environment/Daemons BuildRequires: flex, openssl-devel , ldns-devel >= 1.5.0, BuildRequires: libevent-devel expat-devel %if %{with_python} BuildRequires: python-devel swig %endif # Required for SVN versions BuildRequires: bison BuildRequires: systemd-units Requires(post): systemd-sysv Requires(post): systemd-units Requires(preun): systemd-units Requires(postun): systemd-units Requires: ldns >= 1.5.0 Requires(pre): shadow-utils Obsoletes: dnssec-conf < 1.27-2 Provides: dnssec-conf = 1.27-1 %description Unbound is a validating, recursive, and caching DNS(SEC) resolver. The C implementation of Unbound is developed and maintained by NLnet Labs. It is based on ideas and algorithms taken from a java prototype developed by Verisign labs, Nominet, Kirei and ep.net. Unbound is designed as a set of modular components, so that also DNSSEC (secure DNS) validation and stub-resolvers (that do not run as a server, but are linked into an application) are easily possible. %package munin Summary: Plugin for the munin / munin-node monitoring package Group: System Environment/Daemons Requires: munin-node Requires: %{name} = %{version}-%{release}, bc %description munin Plugin for the munin / munin-node monitoring package %package devel Summary: Development package that includes the unbound header files Group: Development/Libraries Requires: %{name}-libs = %{version}-%{release}, openssl-devel, ldns-devel %description devel The devel package contains the unbound library and the include files %package libs Summary: Libraries used by the unbound server and client applications Group: Applications/System Requires(post): /sbin/ldconfig Requires(postun): /sbin/ldconfig Requires: openssl >= 0.9.8g-12 %description libs Contains libraries used by the unbound server and client applications %if %{with_python} %package python Summary: Python modules and extensions for unbound Group: Applications/System Requires: %{name}-libs = %{version}-%{release} %description python Python modules and extensions for unbound %endif %prep %setup -q %patch1 -p1 %build %configure --with-ldns= --with-libevent --with-pthreads --with-ssl \ --disable-rpath --disable-static \ --with-conf-file=%{_sysconfdir}/%{name}/unbound.conf \ --with-pidfile=%{_localstatedir}/run/%{name}/%{name}.pid \ %if %{with_python} --with-pythonmodule --with-pyunbound \ %endif --enable-sha2 --disable-gost %{__make} %{?_smp_mflags} %install %{__make} DESTDIR=%{buildroot} install install -d 0755 %{buildroot}%{_unitdir} install -m 0644 %{SOURCE1} %{buildroot}%{_unitdir}/unbound.service install -m 0644 %{SOURCE7} %{buildroot}%{_unitdir}/unbound-keygen.service install -m 0755 %{SOURCE2} %{buildroot}%{_sysconfdir}/unbound # Install munin plugin and its softlinks install -d 0755 %{buildroot}%{_sysconfdir}/munin/plugin-conf.d install -m 0644 %{SOURCE3} %{buildroot}%{_sysconfdir}/munin/plugin-conf.d/unbound install -d 0755 %{buildroot}%{_datadir}/munin/plugins/ install -m 0755 %{SOURCE4} %{buildroot}%{_datadir}/munin/plugins/unbound for plugin in unbound_munin_hits unbound_munin_queue unbound_munin_memory unbound_munin_by_type unbound_munin_by_class unbound_munin_by_opcode unbound_munin_by_rcode unbound_munin_by_flags unbound_munin_histogram; do ln -s unbound %{buildroot}%{_datadir}/munin/plugins/$plugin done # Install tmpfiles.d config mkdir -p %{buildroot}%{_sysconfdir}/tmpfiles.d/ install -m 0644 %{SOURCE8} %{buildroot}%{_sysconfdir}/tmpfiles.d/unbound.conf # install root and DLV key install -m 0644 %{SOURCE5} %{SOURCE6} %{buildroot}%{_sysconfdir}/unbound/ # remove static library from install (fedora packaging guidelines) rm %{buildroot}%{_libdir}/*.la %if %{with_python} rm %{buildroot}%{python_sitearch}/*.la %endif mkdir -p %{buildroot}%{_localstatedir}/run/unbound %files %doc doc/README doc/CREDITS doc/LICENSE doc/FEATURES %{_unitdir}/%{name}.service %{_unitdir}/%{name}-keygen.service %attr(0755,root,root) %dir %{_sysconfdir}/%{name} %attr(0755,unbound,unbound) %dir %{_localstatedir}/run/%{name} %config(noreplace) %{_sysconfdir}/tmpfiles.d/unbound.conf %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/%{name}/unbound.conf %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/%{name}/dlv.isc.org.key %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/%{name}/root.key %{_sbindir}/* %{_mandir}/*/* %if %{with_python} %files python %{python_sitearch}/* %doc libunbound/python/examples/* %doc pythonmod/examples/* %endif %files munin %config(noreplace) %{_sysconfdir}/munin/plugin-conf.d/unbound %{_datadir}/munin/plugins/unbound* %files devel %{_libdir}/libunbound.so %{_includedir}/unbound.h %doc README %files libs %{_libdir}/libunbound.so.* %doc doc/README doc/LICENSE %pre getent group unbound >/dev/null || groupadd -r unbound getent passwd unbound >/dev/null || \ useradd -r -g unbound -d %{_sysconfdir}/unbound -s /sbin/nologin \ -c "Unbound DNS resolver" unbound exit 0 %post if [ $1 -eq 1 ] ; then # Initial installation /bin/systemctl daemon-reload >/dev/null 2>&1 || : fi # dnssec-conf used to contain our DLV key, but now we include it via unbound # If unbound had previously been configured with dnssec-configure, we need # to migrate the location of the DLV key file (to keep DLV enabled, and because # unbound won't start with a bad location for a DLV key file. sed -i "s:/etc/pki/dnssec-keys[/]*dlv:/etc/unbound:" %{_sysconfdir}/unbound/unbound.conf %post libs -p /sbin/ldconfig %preun if [ $1 -eq 0 ]; then # Package removal, not upgrade /bin/systemctl --no-reload disable unbound.service > /dev/null 2>&1 || : /bin/systemctl stop unbound.service > /dev/null 2>&1 || : /bin/systemctl --no-reload disable unbound-keygen.service > /dev/null 2>&1 || : /bin/systemctl stop unbound-keygen.service > /dev/null 2>&1 || : fi %postun /bin/systemctl daemon-reload >/dev/null 2>&1 || : if [ $1 -ge 1 ] ; then # Package upgrade, not uninstall /bin/systemctl try-restart unbound.service >/dev/null 2>&1 || : /bin/systemctl try-restart unbound-keygen.service >/dev/null 2>&1 || : fi %postun libs -p /sbin/ldconfig %triggerun -- unbound < 1.4.12-4 # Save the current service runlevel info # User must manually run systemd-sysv-convert --apply unbound # to migrate them to systemd targets /usr/bin/systemd-sysv-convert --save unbound >/dev/null 2>&1 ||: # Run these because the SysV package being removed won't do them /sbin/chkconfig --del unbound >/dev/null 2>&1 || : /bin/systemctl try-restart unbound.service >/dev/null 2>&1 || : /bin/systemctl try-restart unbound-keygen.service >/dev/null 2>&1 || : %changelog * Thu Feb 23 2012 Paul Wouters - 1.4.16-2 - Don't ghost the directory (rhbz#788805) - Patch for unbound to support unbound-control forward_zone (needed for openswan in XAUTH mode) * Thu Feb 02 2012 Paul Wouters - 1.4.16-1 - Upgraded to 1.4.16, which was relesed due to the soname and some DNSSEC validation failures * Wed Feb 01 2012 Paul Wouters - 1.4.15-2 - Patch for SONAME version (libtool's -version-number vs -version-info) * Fri Jan 27 2012 Paul Wouters - 1.4.15-1 - Upgraded to 1.4.15 - Updated unbound.conf to show how to configure listening on tls443 * Sat Jan 14 2012 Fedora Release Engineering - 1.4.14-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild * Mon Dec 19 2011 Paul Wouters - 1.4.14-1 - Upgraded to 1.4.14 for CVE-2011-4528 / VU#209659 - SSL-wrapped query support for dnssec-trigger - EDNS handling changes - Removed integrated EDNS patches - Disabled use-caps-for-id, GoDaddy domains now break on it - Enabled new harden-below-nxdomain * Thu Sep 15 2011 Paul Wouters - 1.4.13-1 - Upgraded to 1.4.13 - Removed merged in pythonmod patch - Added EDNS1480 patch to fix unbound on broken EDNS/UDP networks - Fix python to go into sitearch instead of sitelib * Wed Sep 14 2011 Tom Callaway - 1.4.12-4 - convert to systemd, tmpfiles.d * Mon Aug 08 2011 Paul Wouters - 1.4.12-3 - Added pythonmod docs and examples * Mon Aug 08 2011 Paul Wouters - 1.4.12-2 - Fix for python module load in the server (Tom Hendrikx) - No longer enable --enable-debug as it causes degraded performance under load. * Mon Jul 18 2011 Paul Wouters - 1.4.12-1 - Updated to 1.4.12 * Sun Jul 03 2011 Paul Wouters - 1.4.11-1 - Updated to 1.4.11 - removed integrated CVE patch - updated stock unbound.conf for new options introduced * Mon Jun 06 2011 Paul Wouters - 1.4.10-1 - Added ghost for /var/run/unbound (bz#656710) * Mon Jun 06 2011 Paul Wouters - 1.4.9-3 - rebuilt * Wed May 25 2011 Paul Wouters - 1.4.9-2 - Applied patch for CVE-2011-1922 DoS vulnerability * Sun Mar 27 2011 Paul Wouters - 1.4.9-1 - Updated to 1.4.9 * Sat Feb 12 2011 Paul Wouters - 1.4.8-2 - rebuilt * Tue Jan 25 2011 Paul Wouters - 1.4.8-1 - Updated to 1.4.8 - Enable root key for DNSSEC - Fix unbound-munin to use proper file (could cause excessive logging) - Build unbound-python per default - Disable gost as Fedora/EPEL does not allow ECC and has mangled openssl * Tue Oct 26 2010 Paul Wouters - 1.4.5-4 - Revert last build - it was on the wrong branch * Tue Oct 26 2010 Paul Wouters - 1.4.5-3 - Disable do-ipv6 per default - causes severe degradation on non-ipv6 machines (see comments in inbound.conf) * Tue Jun 15 2010 Paul Wouters - 1.4.5-2 - Bump release - forgot to upload the new tar ball. * Tue Jun 15 2010 Paul Wouters - 1.4.5-1 - Upgraded to 1.4.5 * Mon May 31 2010 Paul Wouters - 1.4.4-2 - Added accidentally omitted svn patches to cvs * Mon May 31 2010 Paul Wouters - 1.4.4-1 - Upgraded to 1.4.4 with svn patches - Obsolete dnssec-conf to ensure it is de-installed * Thu Mar 11 2010 Paul Wouters - 1.4.3-1 - Update to 1.4.3 that fixes 64bit crasher * Tue Mar 09 2010 Paul Wouters - 1.4.2-1 - Updated to 1.4.2 - Updated unbound.conf with new options - Enabled pre-fetching DNSKEY records (DNSSEC speedup) - Enabled re-fetching popular records before they expire - Enabled logging of DNSSEC validation errors * Mon Mar 01 2010 Paul Wouters - 1.4.1-5 - Overriding -D_GNU_SOURCE is no longer needed. This fixes DSO issues with pthreads * Wed Feb 24 2010 Paul Wouters - 1.4.1-3 - Change make/configure lines to attempt to fix -lphtread linking issue * Thu Feb 18 2010 Paul Wouters - 1.4.1-2 - Removed dependancy for dnssec-conf - Added ISC DLV key (formerly in dnssec-conf) - Fixup old DLV locations in unbound.conf file via %%post - Fix parent child disagreement handling and no-ipv6 present [svn r1953] * Tue Jan 05 2010 Paul Wouters - 1.4.1-1 - Updated to 1.4.1 - Changed %%define to %%global * Thu Oct 08 2009 Paul Wouters - 1.3.4-2 - Bump version * Thu Oct 08 2009 Paul Wouters - 1.3.4-1 - Upgraded to 1.3.4. Security fix with validating NSEC3 records * Fri Aug 21 2009 Tomas Mraz - 1.3.3-2 - rebuilt with new openssl * Mon Aug 17 2009 Paul Wouters - 1.3.3-1 - Updated to 1.3.3 * Sun Jul 26 2009 Fedora Release Engineering - 1.3.0-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild * Sat Jun 20 2009 Paul Wouters - 1.3.0-2 - Added missing glob patch to cvs - Place python macros within the %%with_python check * Sat Jun 20 2009 Paul Wouters - 1.3.0-1 - Updated to 1.3.0 - Added unbound-python sub package. disabled for now - Patch from svn to fix DLV lookups - Patches from svn to detect wrong truncated response from BIND 9.6.1 with minimal-responses) - Added Default-Start and Default-Stop to unbound.init - Re-enabled --enable-sha2 - Re-enabled glob.patch * Wed May 20 2009 Paul Wouters - 1.2.1-7 - unbound-iterator.patch was not commited * Wed May 20 2009 Paul Wouters - 1.2.1-6 - Fix for https://bugzilla.redhat.com/show_bug.cgi?id=499793 * Tue Mar 17 2009 Paul Wouters - 1.2.1-5 - Use --nocheck to avoid giving an error on missing unbound-remote certs/keys * Tue Mar 10 2009 Adam Tkac - 1.2.1-4 - enable DNSSEC only if it is enabled in sysconfig/dnssec * Mon Mar 09 2009 Adam Tkac - 1.2.1-3 - add DNSSEC support to initscript and enabled it per default - add requires dnssec-conf * Wed Feb 25 2009 Fedora Release Engineering - 1.2.1-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild * Tue Feb 10 2009 Paul Wouters - 1.2.0-2 - rebuild with new openssl * Wed Jan 14 2009 Paul Wouters - 1.1.1-7 - Modified scandir patch to silently fail when wildcard matches nothing - Patch to allow unbound-checkconf to find empty wildcard matches * Mon Jan 5 2009 Paul Wouters - 1.1.1-6 - Added scandir patch for trusted-keys-file: option, which is used to load multiple dnssec keys in bind file format * Mon Dec 8 2008 Paul Wouters - 1.1.1-4 - Added Requires: for selinux-policy >= 3.5.13-33 for proper SElinux rules. * Mon Dec 1 2008 Paul Wouters - 1.1.1-3 - We did not own the /etc/unbound directory (#474020) - Fixed cvs anomalies * Fri Nov 28 2008 Adam Tkac - 1.1.1-2 - removed all obsolete chroot related stuff - label control certs after generation correctly * Thu Nov 20 2008 Paul Wouters - 1.1.1-1 - Updated to unbound 1.1.1 which fixes a crasher and addresses nlnetlabs bug #219 * Wed Nov 19 2008 Paul Wouters - 1.1.0-3 - Remove the chroot, obsoleted by SElinux - Add additional munin plugin links supported by unbound plugin - Move configuration directory from /var/lib/unbound to /etc/unbound - Modified unbound.init and unbound.conf to account for chroot changes - Updated unbound.conf with new available options - Enabled dns-0x20 protection per default * Wed Nov 19 2008 Adam Tkac - 1.1.0-2 - unbound-1.1.0-log_open.patch - make sure log is opened before chroot call - tracked as http://www.nlnetlabs.nl/bugs/show_bug.cgi?id=219 - removed /dev/log and /var/run/unbound and /etc/resolv.conf from chroot, not needed - don't mount files in chroot, it causes problems during updates - fixed typo in default config file * Fri Nov 14 2008 Paul Wouters - 1.1.0-1 - Updated to version 1.1.0 - Updated unbound.conf's statistics options and remote-control to work properly for munin - Added unbound-munin package - Generate unbound remote-control key/certs on first startup - Required ldns is now 1.4.0 * Wed Oct 22 2008 Paul Wouters - 1.0.2-5 - Only call ldconfig in -libs package - Move configure into build section - devel subpackage should only depend on libs subpackage * Tue Oct 21 2008 Paul Wouters - 1.0.2-4 - Fix CFLAGS getting lost in build - Don't enable interface-automatic:yes because that causes unbound to listen on 0.0.0.0 instead of 127.0.0.1 * Sun Oct 19 2008 Paul Wouters - 1.0.2-3 - Split off unbound-libs, make build verbose * Thu Oct 9 2008 Paul Wouters - 1.0.2-2 - FSB compliance, chroot fixes, initscript fixes * Thu Sep 11 2008 Paul Wouters - 1.0.2-1 - Upgraded to 1.0.2 * Wed Jul 16 2008 Paul Wouters - 1.0.1-1 - upgraded to new release * Wed May 21 2008 Paul Wouters - 1.0.0-2 - Build against ldns-1.3.0 * Wed May 21 2008 Paul Wouters - 1.0.0-1 - Split of -devel package, fixed dependancies, make rpmlint happy * Thu Apr 25 2008 Wouter Wijngaards - 0.12 - Using parts from ports collection entry by Jaap Akkerhuis. - Using Fedoraproject wiki guidelines. * Wed Apr 23 2008 Wouter Wijngaards - 0.11 - Initial version. dnssec-trigger-0.13/fedora/unbound.service0000664000175000017500000000051211721417503020306 0ustar wouterwouter[Unit] Description=Unbound recursive Domain Name Server After=syslog.target network.target After=unbound-keygen.service Wants=unbound-keygen.service [Service] Type=forking PIDFile=/var/run/unbound/unbound.pid EnvironmentFile=-/etc/sysconfig/unbound ExecStart=/usr/sbin/unbound [Install] WantedBy=multi-user.target dnssec-trigger-0.13/LICENSE0000664000175000017500000000273212275162157015034 0ustar wouterwouterCopyright (c) 2011, NLnet Labs. All rights reserved. This software is open source. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the NLNET LABS nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. dnssec-trigger-0.13/dnssec-trigger-script.in0000664000175000017500000006645712725746424020624 0ustar wouterwouter#!@PYTHON@ -sE # -*- coding: utf-8 -*- """ @author: Tomas Hozza @author: Pavel Šimerda """ import os import sys import fcntl import shutil import glob import subprocess import logging import logging.handlers import socket import struct import signal import gi gi.require_version('NMClient', '1.0') from gi.repository import NMClient # Python compatibility stuff if not hasattr(os, "O_CLOEXEC"): os.O_CLOEXEC = 0x80000 DEVNULL = open(os.devnull, "wb") log = logging.getLogger() log.setLevel(logging.INFO) log.addHandler(logging.handlers.SysLogHandler()) log.addHandler(logging.StreamHandler()) # NetworkManager reportedly doesn't pass the PATH environment variable. os.environ['PATH'] = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" # maximum negative cache TTL set by dnssec-trigger script on setup UNBOUND_MAX_NEG_CACHE_TTL = 5 class UserError(Exception): pass def pidof(process_name): """ Get pids for process with given name :param process_name: String with name of process to get PIDs of :return: list with PIDs represented as int. If there is no such process, the list is empty """ pids = list() try: output = subprocess.check_output(['pidof', process_name]) p = [int(pid) for pid in output.decode().strip().split()] pids.extend(p) except subprocess.CalledProcessError: # There is no process with given name pass return pids class Lock: """Lock used to serialize the script""" path = "/var/run/dnssec-trigger/lock" def __init__(self): # We don't use os.makedirs(..., exist_ok=True) to ensure Python 2 compatibility dirname = os.path.dirname(self.path) if not os.path.exists(dirname): os.makedirs(dirname) self.lock = os.open(self.path, os.O_WRONLY | os.O_CREAT | os.O_CLOEXEC, 0o600) def __enter__(self): fcntl.lockf(self.lock, fcntl.LOCK_EX) def __exit__(self, t, v, tb): fcntl.lockf(self.lock, fcntl.LOCK_UN) class Config: """Global configuration options""" path = "/etc/dnssec.conf" bool_options = { "debug": False, "validate_connection_provided_zones": True, "add_wifi_provided_zones": False, "use_vpn_global_forwarders": False, "use_resolv_conf_symlink": False, "use_resolv_secure_conf_symlink": False, "use_private_address_ranges": True, "set_search_domains": False, "keep_positive_answers": False, } def __init__(self): try: with open(self.path) as config_file: for line in config_file: if '=' in line: option, value = [part.strip() for part in line.split("=", 1)] if option in self.bool_options: self.bool_options[option] = (value == "yes") except IOError: pass log.debug(self) def __getattr__(self, option): return self.bool_options[option] def __str__(self): return "".format(self.bool_options) @property def flush_command(self): return "flush_negative" if self.keep_positive_answers else "flush_zone" config = Config() if config.debug: log.setLevel(logging.DEBUG) class ConnectionList: """List of NetworkManager active connections""" nm_connections = None def __init__(self, client, only_default=False, only_vpn=False, skip_wifi=False): # Cache the active connection list in the class if not client.get_manager_running(): raise UserError("NetworkManager is not running.") if self.nm_connections is None: self.__class__.nm_connections = client.get_active_connections() self.skip_wifi = skip_wifi self.only_default = only_default self.only_vpn = only_vpn log.debug(self) def __repr__(self): return "".format(list(self), **vars(self)) def __iter__(self): for item in self.nm_connections: connection = Connection(item) # Skip connections that should be ignored if connection.ignore: continue # Skip connections without servers if not connection.servers: continue # Skip WiFi connections if appropriate if self.skip_wifi and connection.is_wifi: continue # Skip non-default connections if appropriate if self.only_default and not connection.is_default: continue if self.only_vpn and not connection.is_vpn: continue yield connection def get_zone_connection_mapping(self): result = {} for connection in self: for zone in connection.zones: if zone in result: result[zone] = self.get_preferred_connection(result[zone], connection) else: result[zone] = connection return result @staticmethod def get_preferred_connection(first, second): # Prefer VPN connection if second.is_vpn and not first.is_vpn: return second if first.is_vpn and not second.is_vpn: return first # Prefer default connection if second.is_default and not first.is_default: return second if first.is_default and not second.is_default: return first # Prefer first connection return first class Connection: """Representation of a NetworkManager active connection""" def __init__(self, connection): devices = connection.get_devices() if connection.get_vpn(): self.type = "vpn" elif not devices: self.type = "ignore" elif devices[0].get_device_type().value_name == "NM_DEVICE_TYPE_WIFI": self.type = "wifi" else: self.type = "other" self.is_default = bool(connection.get_default() or connection.get_default6()) self.uuid = connection.get_uuid() self.zones = [] try: self.zones += connection.get_ip4_config().get_domains() except AttributeError: pass try: self.zones += connection.get_ip6_config().get_domains() except AttributeError: pass self.servers = [] try: self.servers += [self.ip4_to_str(server) for server in connection.get_ip4_config().get_nameservers()] except AttributeError: pass try: self.servers += [self.ip6_to_str(connection.get_ip6_config().get_nameserver(i)) for i in range(connection.get_ip6_config().get_num_nameservers())] except AttributeError: pass def __repr__(self): return "".format(**vars(self)) @staticmethod def ip4_to_str(ip4): """Converts IPv4 address from integer to string.""" return socket.inet_ntop(socket.AF_INET, struct.pack("=I", ip4)) @staticmethod def ip6_to_str(ip6): """Converts IPv6 address from integer to string.""" return socket.inet_ntop(socket.AF_INET6, ip6) @property def ignore(self): return self.type == "ignore" @property def is_vpn(self): return self.type == "vpn" @property def is_wifi(self): return self.type == "wifi" class UnboundZoneConfig: """A dictionary-like proxy object for Unbound's forward zone configuration.""" def __init__(self): subprocess.check_call(["unbound-control", "status"], stdout=DEVNULL, stderr=DEVNULL) self.cache = {} for line in subprocess.check_output(["unbound-control", "list_forwards"]).decode().split('\n'): if line: fields = line.split(" ") name = fields.pop(0)[:-1] if fields[0] == 'IN': fields.pop(0) if fields.pop(0) in ('forward', 'forward:'): fields.pop(0) secure = False if fields and fields[0] == '+i': secure = True fields.pop(0) self.cache[name] = set(fields), secure log.debug(self) def __repr__(self): return "".format(**vars(self)) def __iter__(self): return iter(self.cache) def add(self, zone, servers, secure): """Install a forward zone into Unbound.""" self._commit(zone, set(servers), secure) log.info("Connection provided zone '{}' ({}): {}".format( zone, "validated" if secure else "insecure", ', '.join(servers))) def remove(self, zone): """Remove a forward zone from Unbound.""" self._commit(zone, None, None) def _commit(self, name, servers, secure): # FIXME: Older versions of unbound don't print +i for insecure zones # and thus we cannot see whether the zone has changed or not. Therefore # we have no other chance than to re-add existing zones as well. # # old_servers, old_secure = self.cache.get(name, [None, None]) # if servers, secure == old_servers, old_secure: # log.debug("Connection provided zone '{}' already set to {} ({})".format(name, servers, 'secure' if old_secure else 'insecure')) # return if servers: self.cache[name] = servers, secure self._control(["forward_add"] + ([] if secure else ["+i"]) + [name] + list(servers)) # Unbound doesn't switch an insecure zone to a secure zone when "+i" is # specified and there is no "-i" to add a secure zone explicitly. if secure: self._control(["insecure_remove", name]) else: del self.cache[name] self._control(["forward_remove", name]) self._control([config.flush_command, name]) self._control(["flush_requestlist"]) log.debug(self) @staticmethod def _control(args): log.debug("unbound-control: {}".format(args)) subprocess.check_call(["unbound-control"] + args, stdout=DEVNULL, stderr=DEVNULL) class UnboundLocalZoneConfig: """A dictionary-like proxy object for Unbound's local zone configuration.""" def __init__(self): subprocess.check_call(["unbound-control", "status"], stdout=DEVNULL, stderr=DEVNULL) self.cache = {} for line in subprocess.check_output(["unbound-control", "list_local_zones"]).decode().split('\n'): if line: fields = line.split(" ") name = fields.pop(0).rstrip(".") type = fields.pop(0) self.cache[name] = type log.debug(self) def __repr__(self): return "".format(**vars(self)) def __iter__(self): return iter(self.cache) def add(self, zone, type): """Install a local zone into Unbound.""" self.cache[zone] = type self._control(["local_zone", zone, type]) log.debug(self) def remove(self, zone): """Remove a local zone from Unbound.""" if self.cache.pop(zone, None): self._control(["local_zone_remove", zone]) log.debug(self) @staticmethod def _control(args): log.debug("unbound-control: {}".format(args)) subprocess.check_call(["unbound-control"] + args, stdout=DEVNULL, stderr=DEVNULL) class Store: """A proxy object to access stored zones or global servers.""" def __init__(self, name): self.name = name self.cache = set() self.path = os.path.join("/var/run/dnssec-trigger", name) self.path_tmp = self.path + ".tmp" try: with open(self.path) as zone_file: for line in zone_file: line = line.strip() if line: self.cache.add(line) except IOError: pass log.debug(self) def __repr__(self): return "".format(**vars(self)) def __iter__(self): # Don't return the set itself, as it doesn't support update during # iteration. return iter(list(self.cache)) def __bool__(self): return bool(self.cache) def add(self, zone): """Add zone to the cache.""" self.cache.add(zone) log.debug(self) def update(self, zones): """Commit a new set of items and return True when it differs""" zones = set(zones) if zones != self.cache: self.cache = set(zones) log.debug(self) return True return False def remove(self, zone): """Remove zone from the cache.""" self.cache.remove(zone) log.debug(self) def commit(self): """Write data back to disk.""" # We don't use os.makedirs(..., exist_ok=True) to ensure Python 2 compatibility dirname = os.path.dirname(self.path_tmp) if not os.path.exists(dirname): os.makedirs(dirname) with open(self.path_tmp, "w") as zone_file: for zone in self.cache: zone_file.write("{}\n".format(zone)) os.rename(self.path_tmp, self.path) class Application: resolvconf = "/etc/resolv.conf" resolvconf_tmp = "/etc/.resolv.conf.dnssec-trigger" resolvconf_secure = "/etc/resolv-secure.conf" resolvconf_secure_tmp = "/etc/.resolv-secure.conf.dnssec-trigger" resolvconf_backup = "/var/run/dnssec-trigger/resolv.conf.backup" resolvconf_trigger = "/var/run/dnssec-trigger/resolv.conf" resolvconf_trigger_tmp = resolvconf_trigger + ".tmp" resolvconf_networkmanager = "/var/run/NetworkManager/resolv.conf" resolvconf_localhost_contents = "# Generated by dnssec-trigger-script\nnameserver 127.0.0.1\n" rfc1918_reverse_zones = [ "c.f.ip6.arpa", "d.f.ip6.arpa", "168.192.in-addr.arpa", ] + ["{}.172.in-addr.arpa".format(octet) for octet in range(16, 32)] + [ "10.in-addr.arpa"] def __init__(self, argv): if len(argv) > 1 and argv[1] == '--debug': argv.pop(1) log.setLevel(logging.DEBUG) if len(argv) > 1 and argv[1] == '--async': argv.pop(1) if os.fork(): sys.exit() if len(argv) < 2 or not argv[1].startswith('--'): self.usage() try: self.method = getattr(self, "run_" + argv[1][2:].replace('-', '_')) except AttributeError: self.usage() self.client = NMClient.Client().new() def nm_handles_resolv_conf(self): if not self.client.get_manager_running(): log.debug("NetworkManager is not running") return False try: with open("/etc/NetworkManager/NetworkManager.conf") as nm_config_file: for line in nm_config_file: if line.strip() in ("dns=none", "dns=unbound"): log.debug("NetworkManager doesn't handle resolv.conf") return False except IOError: pass log.debug("NetworkManager handles resolv.conf") return True def usage(self): raise UserError("Usage: dnssec-trigger-script [--debug] [--async] --prepare|--setup|--update|--update-global-forwarders|--update-connection-zones|--cleanup") def run(self): log.debug("Running: {}".format(self.method.__name__)) self.method() def _check_resolv_conf(self, path): try: with open(path) as source: if source.read() != self.resolvconf_localhost_contents: log.info("Rewriting {!r}!".format(path)) return False; return True except IOError: return False def _write_resolv_conf(self, path): self._try_remove(path) with open(path, "w") as target: target.write(self.resolvconf_localhost_contents) def _install_resolv_conf(self, path, path_tmp, symlink=False): if symlink: self._try_remove(path_tmp) os.symlink(self.resolvconf_trigger, path_tmp) self._try_set_mutable(path) os.rename(path_tmp, path) elif not self._check_resolv_conf(path): self._write_resolv_conf(path_tmp) self._try_set_mutable(path) os.rename(path_tmp, path) self._try_set_immutable(path) def _try_remove(self, path): self._try_set_mutable(path) try: os.remove(path) except OSError: pass def _try_set_immutable(self, path): subprocess.call(["chattr", "+i", path], stdout=DEVNULL, stderr=DEVNULL) def _try_set_mutable(self, path): if os.path.exists(path) and not os.path.islink(path): subprocess.call(["chattr", "-i", path], stdout=DEVNULL, stderr=DEVNULL) def _restart_nm(self): if os.path.exists(self.resolvconf_networkmanager): os.symlink(self.resolvconf_networkmanager, self.resolvconf) # Sending SIGHUP will cause NM to reload config and write the /etc/resolv.conf elif self.client.get_version() >= '1.0.3': log.debug("Sending SIGHUP to NM to rewrite the resolv.conf") nm_pids = pidof('NetworkManager') for pid in nm_pids: os.kill(pid, signal.SIGHUP) else: try: subprocess.check_call(["systemctl", "--ignore-dependencies", "try-restart", "NetworkManager.service"], stdout=DEVNULL, stderr=DEVNULL) except subprocess.CalledProcessError: subprocess.check_call(["/etc/init.d/NetworkManager", "restart"], stdout=DEVNULL, stderr=DEVNULL) def run_prepare(self): """Prepare for starting dnssec-trigger Called by the service manager before starting dnssec-trigger daemon. """ # Backup resolv.conf when appropriate if not self.nm_handles_resolv_conf(): try: log.info("Backing up {} as {}...".format(self.resolvconf, self.resolvconf_backup)) shutil.move(self.resolvconf, self.resolvconf_backup) except IOError as error: log.warning("Cannot back up {!r} as {!r}: {}".format(self.resolvconf, self.resolvconf_backup, error.strerror)) # Make sure dnssec-trigger daemon doesn't get confused by existing files. self._try_remove(self.resolvconf) self._try_remove(self.resolvconf_secure) self._try_remove(self.resolvconf_trigger) def run_setup(self): """Set up resolv.conf with localhost nameserver Called by dnssec-trigger. """ # Set the maximum negative cache TTL self._unbound_set_negative_cache_ttl(UNBOUND_MAX_NEG_CACHE_TTL) if config.set_search_domains: zones = set(sum((connection.zones for connection in ConnectionList(self.client)), [])) log.info("Search domains: " + ' '.join(zones)) self.resolvconf_localhost_contents = self.__class__.resolvconf_localhost_contents self.resolvconf_localhost_contents += "search {}\n".format(' '.join(zones)) self._install_resolv_conf(self.resolvconf_trigger, self.resolvconf_trigger_tmp, False) self._install_resolv_conf(self.resolvconf, self.resolvconf_tmp, config.use_resolv_conf_symlink) self._install_resolv_conf(self.resolvconf_secure, self.resolvconf_secure_tmp, config.use_resolv_secure_conf_symlink) def run_restore(self): """Restore resolv.conf with original data Called by dnssec-trigger or internally as part of other actions. """ self._try_remove(self.resolvconf) self._try_remove(self.resolvconf_secure) self._try_remove(self.resolvconf_trigger) log.info("Recovering {}...".format(self.resolvconf)) if self.nm_handles_resolv_conf(): # try to make NM to rewrite resolv.conf or as a last resort restart it self._restart_nm() else: try: shutil.move(self.resolvconf_backup, self.resolvconf) except IOError as error: log.warning("Cannot restore {!r} from {!r}: {}".format(self.resolvconf, self.resolvconf_backup, error.strerror)) def run_cleanup(self): """Clean up after dnssec-trigger daemon Called by the service manager after stopping dnssec-trigger daemon. """ self.run_restore() stored_zones = Store('zones') stored_servers = Store('servers') unbound_zones = UnboundZoneConfig() # provide upgrade path for previous versions old_zones = glob.glob("/var/run/dnssec-trigger/????????-????-????-????-????????????") if old_zones: log.info("Reading zones from the legacy zone store") with open("/var/run/dnssec-trigger/zones", "a") as target: for filename in old_zones: with open(filename) as source: log.debug("Reading zones from {}".format(filename)) for line in source: stored_zones.add(line.strip()) os.remove(filename) log.debug("clearing unbound configuration") for zone in stored_zones: unbound_zones.remove(zone) stored_zones.remove(zone) for server in stored_servers: stored_servers.remove(server) stored_zones.commit() stored_servers.commit() @property def global_forwarders(self): connections = None if config.use_vpn_global_forwarders: connections = list(ConnectionList(self.client, only_vpn=True)) if not connections: connections = list(ConnectionList(self.client, only_default=True)) return sum((connection.servers for connection in connections), []) def run_update(self): """Update unbound and dnssec-trigger configuration.""" self.run_update_global_forwarders() self.run_update_connection_zones() @staticmethod def _unbound_set_negative_cache_ttl(ttl): CMD = ["unbound-control", "set_option", "cache-max-negative-ttl:", str(ttl)] log.debug(" ".join(CMD)) subprocess.check_call(CMD, stdout=DEVNULL, stderr=DEVNULL) @staticmethod def dnssec_trigger_control(args): log.debug("dnssec-trigger-control: {}".format(args)) subprocess.check_call(["dnssec-trigger-control"] + args, stdout=DEVNULL, stderr=DEVNULL) def run_update_global_forwarders(self): """Configure global forwarders using dnssec-trigger-control.""" with Lock(): self.dnssec_trigger_control(["status"]) servers = Store('servers') if servers.update(self.global_forwarders): UnboundZoneConfig._control([config.flush_command, "."]) self.dnssec_trigger_control(["submit"] + list(servers)) servers.commit() log.info("Global forwarders: {}".format(' '.join(servers))) else: log.info("Global forwarders: {} (unchanged)".format(' '.join(servers))) def run_update_connection_zones(self): """Configures forward zones in the unbound using unbound-control.""" with Lock(): connections = ConnectionList(self.client, skip_wifi=not config.add_wifi_provided_zones).get_zone_connection_mapping() unbound_zones = UnboundZoneConfig() unbound_local_zones = UnboundLocalZoneConfig() stored_zones = Store('zones') # Remove any zones managed by dnssec-trigger that are no longer # valid. log.debug("removing zones that are no longer valid") for zone in stored_zones: # leave zones that are provided by some connection if zone in connections: continue if zone in self.rfc1918_reverse_zones: # if zone is private address range reverse zone and we are congifured to use them, leave it if config.use_private_address_ranges: continue # otherwise add Unbound local zone of type 'static' like Unbound does and remove it later else: unbound_local_zones.add(zone, "static") # Remove all zones that are not in connections except OR # are private address ranges reverse zones and we are NOT # configured to use them if zone in unbound_zones: unbound_zones.remove(zone) stored_zones.remove(zone) # Install all zones coming from connections except those installed # by other means than dnssec-trigger-script. log.debug("installing connection provided zones") for zone in connections: # Reinstall a known zone or install a new zone. if zone in stored_zones or zone not in unbound_zones: unbound_zones.add(zone, connections[zone].servers, secure=config.validate_connection_provided_zones) stored_zones.add(zone) # Configure forward zones for reverse name resolution of private addresses. # RFC1918 zones will be installed, except those already provided by connections # and those installed by other means than by dnssec-trigger-script. # RFC19118 zones will be removed if there are no global forwarders. if config.use_private_address_ranges: log.debug("configuring RFC 1918 private zones") for zone in self.rfc1918_reverse_zones: # Ignore a connection provided zone as it's been already # processed. if zone in connections: continue if self.global_forwarders: # Reinstall a known zone or install a new zone. log.debug("Installing RFC 1918 private zone '%s' not present in unbound or connections", zone) if zone in stored_zones or zone not in unbound_zones: unbound_zones.add(zone, self.global_forwarders, secure=False) stored_zones.add(zone) unbound_local_zones.remove(zone) else: # There are no global forwarders, therefore remove the zone log.debug("Removing RFC 1918 private zone '%s' since there are no global forwarders", zone) if zone in unbound_zones: unbound_zones.remove(zone) if zone in stored_zones: stored_zones.remove(zone) unbound_local_zones.add(zone, "static") stored_zones.commit() def main(): try: Application(sys.argv).run() except UserError as error: log.error(error) exit(1) except subprocess.CalledProcessError as error: if len(error.cmd) == 2 and error.cmd[0].endswith('-control') and error.cmd[1] == "status": log.error("Cannot connect to {}.".format(error.cmd[0][:-8])) exit(1) else: raise if __name__ == "__main__": main() dnssec-trigger-0.13/dnssec-trigger-control-setup.sh.in0000664000175000017500000001767512500331310022514 0ustar wouterwouter#!@SHELL@ # # dnssec-trigger-setup.sh - set up SSL certificates for dnssec-trigger # # Copyright (c) 2008, NLnet Labs. All rights reserved. # # This software is open source. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # Neither the name of the NLNET LABS nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # settings: # directory for files DESTDIR=@keydir@ # for domain and search options with -i. configfile=@configfile@ # issuer and subject name for certificates SERVERNAME=dnssec-trigger CLIENTNAME=dnssec-trigger-control # validity period for certificates DAYS=7200 # size of keys in bits # recommendation for new systems is to use at least 3072 bits # http://www.enisa.europa.eu/activities/identity-and-trust/library/deliverables/algorithms-key-sizes-and-parameters-report BITS=3072 # hash algorithm HASH=sha256 # base name for server keys SVR_BASE=dnssec_trigger_server # base name for control keys CTL_BASE=dnssec_trigger_control # we want -rw-r--- access (say you run this as root: grp=yes (server), all=no). umask 0026 # end of options # functions: error ( ) { echo "$0 fatal error: $1" exit 1 } action="cert" # check arguments: while test $# -ne 0; do case $1 in -d) if test $# -eq 1; then error "need argument for -d"; fi DESTDIR="$2" shift ;; -s) action="cert" ;; -i) action="install" ;; -u) action="uninstall" ;; *) echo "dnssec-trigger-control-setup.sh [-d dir] [-s|-i|-u]" echo " -d dir use directory to store keys and certificates." echo " default: $DESTDIR" echo "default action -s: setup SSL keys for dnssec-trigger-control" echo " -i install config parameters in unbound.conf (destdir)" echo " This edits unbound.conf with remote-control and the " echo " root trust-anchor and starts unbound-control-setup" echo " -u uninstall parameters installed with -i" exit 1 ;; esac shift done # go!: echo "setup in directory $DESTDIR" cd "$DESTDIR" || error "could not cd to $DESTDIR" find_unbound_config ( ) { ubconf=`unbound-control -h | awk '/config file, default/ { sub(/^.*default is /,""); print}'` } find_unbound_rootkey ( ) { rootkey=`unbound-anchor -h | awk '/root key file, default/ { sub(/^.*default /,""); print}'` } # install action if test "$action" = "install"; then if unbound-checkconf $ubconf ; then : else echo "unbound config $ubconf fails, run again when you fix it" exit 1 fi find_unbound_config find_unbound_rootkey echo "checking if unbound-control needs to be enabled" if test "`unbound-checkconf -o control-enable $ubconf`" = "no"; then echo "setup unbound control keys: unbound-control-setup" unbound-control-setup echo "add to $ubconf: control-enable: yes" echo "remote-control: control-enable: yes # linetag-dnssec-trigger" >> $ubconf fi echo "checking if root trust anchor needs to be enabled" if test -z "`unbound-checkconf -o auto-trust-anchor-file $ubconf`"; then echo "fetching or updating root trust anchor: unbound-anchor" unbound-anchor echo "add to $ubconf: auto-trust-anchor-file: \"$rootkey\"" echo "server: auto-trust-anchor-file: "$rootkey" # linetag-dnssec-trigger" >> $ubconf fi echo "check for search path in resolv.conf and edit $configfile" if test -f /etc/resolv.conf && grep "^search " /etc/resolv.conf >/dev/null; then if grep "^search: " $configfile >/dev/null; then : else echo "add search path to $configfile" echo >> $configfile echo 'search: "'`grep "^search " /etc/resolv.conf | sed -e "s/^search //"`'"' >> $configfile tail -1 $configfile fi fi echo "check for domain in resolv.conf and edit $configfile" if test -f /etc/resolv.conf && grep "^domain " /etc/resolv.conf >/dev/null; then if grep "^domain: " $configfile >/dev/null; then : else echo "add domain to $configfile" echo >> $configfile echo 'domain: "'`grep "^domain " /etc/resolv.conf | sed -e "s/^domain //"`'"' >> $configfile tail -1 $configfile fi fi exit 0 fi # uninstall action if test "$action" = "uninstall"; then find_unbound_config grep -v "linetag-dnssec-trigger" < $ubconf >$ubconf.$$ mv $ubconf.$$ $ubconf exit 0 fi # create certificate keys; do not recreate if they already exist. if test -f $SVR_BASE.key; then echo "$SVR_BASE.key exists" else echo "generating $SVR_BASE.key" openssl genrsa -out $SVR_BASE.key $BITS || error "could not genrsa" fi if test -f $CTL_BASE.key; then echo "$CTL_BASE.key exists" else echo "generating $CTL_BASE.key" openssl genrsa -out $CTL_BASE.key $BITS || error "could not genrsa" fi # create self-signed cert for server cat >request.cfg <request.cfg < and --with-ssl= options. It will statically link with openssl and ldns. Install (Linux) --------------- 1. Install required libraries and get the dnssec-trigger package. On Ubuntu you must install libappindicator-dev, so it builds for Unity GUI. 2. ./configure It needs to detect what sort of system you use - to hook into the DHCP network updates. For many linux systems, networkmanager or netconfig. Default puts files in /usr/local 3. make It could complain about missing libraries here. Install them, back to 2. 4. sudo make install Install as root. Note you can uninstall with make uninstall. 5. sudo dnssec-trigger-control-setup This should create the key files that dnssec-trigger uses to communicate securely between its components. 6. edit unbound.conf to allow remote-control: sudo dnssec-trigger-control-setup -i if you want you can edit by hand, we need root anchor and remote-control 7. setup dnssec-triggerd to start on boot. some script in /etc/rc.d or so. Or you can start it with sudo dnssec-triggerd (just this once). The startup script needs to call dnssec-trigger-control submit with a list of nameserver IPs (it may be the empty list), this will cause the server to initialise. It may be possible to call the DHCP change hook for this from the startup script. 8. the dnssec-trigger-panel needs to start for users on login. to this end a .desktop file is installed in /etc/xdg/autostart for GNOME. Or you can start it from the commandline (just this once). On uninstall you may need to chmod 644 /etc/resolv.conf so that it becomes writable again. To remove the system specific DNS override, dnssec-triggerd -u can be used. Install (OSX) ------------- Same as on Linux, but step 7 and 8 are taken care of by putting plist files in the LaunchAgents folder. On OSX prior to 10.5 it puts the user login start item enabled for you, but make uninstall cannot disable it, you have to manually perform this from the user-account control panel. On OSX 10.5 and later, a launchAgent plist item does the job and is installed and uninstalled for you. On OSX a cocoa user interface is built instead of GTK, to display the status icon on the top right of the menu bar. Test (Demonstration) -------------------- Since all the DHCP hook does is call dnssec-trigger-control submit and then those caches are probed and configuration is changed, you can use that to test. Simply sudo dnssec-trigger-control submit 127.0.0.3. Assuming there is nothing on that address (usually true), it times out and you see that the authority servers on the internet are used instead. If you want to test a failure of the network to allow DNSSEC traffic, you can use the command sudo dnssec-trigger-control unsafe. It causes the daemon to use another couple 127.0.0.x addresses (that should not answer) and a second later think that DNSSEC does not work at all. The popup window should show, if you select insecure, it then uses those 127.0.0.x addresses which will of course not really answer at all. It demonstrates the GUI. dnssec-trigger-0.13/osx/0000775000175000017500000000000013024457644014635 5ustar wouterwouterdnssec-trigger-0.13/osx/dnssec-trigger-setdns.sh.in0000664000175000017500000000512012355255103022002 0ustar wouterwouter#!@SHELL@ # dnssec-trigger shell script to set DNS servers on OSX. # must run as root. # # usage: set example.com 192.0.2.1 192.0.2.2 # perform software upgrade install function doinstall () { dmg="$*" mnt="/tmp/installdir.$$" logger "start setdns install" # copy the dmg to a tempfile because the hdiutil needs exclusive access cp $dmg $dmg.$$ for (( try=0 ; try <= 20 ; try++ )) ; do hdiutil attach "$dmg.$$" -mountpoint "$mnt" -nobrowse -noautoopen -noverify if test $? = 0 ; then # it worked break fi sleep 1 done logger "mounted setdns install" # run the installer from mnt/dnssectrigger-x.x-i386.mpkg pkg="`ls -d $mnt/dnssectrigger-*.mpkg`" installer -pkg "$pkg" -target / logger "done installer setdns install" hdiutil detach "$mnt" -force logger "detached setdns install" rm -f $dmg $dmg.$$ } cmd="$1" shift if test "$cmd" = "set"; then domains="$1" firstdomain="$1" shift # remaining arguments are the servers to set servers="$*" logger "dnssec-trigger-setdns to $domains and $servers" elif test "$cmd" = "mset"; then domains="$1" firstdomain="$1" shift while test "$1" != "--"; do domains="$domains $1" shift done if test "$1" != "--"; then echo >&2 "Usage: $0 mset domain [domain ..] -- server [server ..]" exit 1 fi shift # -- servers="$*" logger "dnssec-trigger-setdns to $domains and $servers" elif test "$cmd" = "install"; then doinstall "$*" exit 0 else if test "$cmd" = "uninit"; then logger "dnssec-trigger-setdns uninit dns override" else echo >&2 "bad command: set | mset | uninit" echo >&2 " set domain [ip ..]" echo >&2 " mset domain [domain ..] -- ip [ip ..]" exit 1 fi firstdomain="" domains="" servers="" fi # sets the DNS settings via scutil. function with_scutil () { # find the ids of the networkservices that are running or important # output like: State:/Network/Service/AB5ED934-29E2-4E1B-BEDC-9167410B49A0/DNS ids=`echo "list State:/Network/Service/[^/]+/DNS" | scutil | sed -e "s?^.* = ??"` # set the nameservers of all those entries (and the global one) for i in $ids State:/Network/Global/DNS; do scutil </dev/null | grep -v '*' | while read x ; do #echo $x $nws -setsearchdomains "$x" $domains # no quotes around servers: the IPs have to be separate arguments. $nws -setdnsservers "$x" $servers done dnssec-trigger-0.13/osx/nl.nlnetlabs.dnssec-triggerd.plist.in0000664000175000017500000000121212630055637023766 0ustar wouterwouter Label nl.nlnetlabs.dnssec-triggerd ProgramArguments @sbindir@/dnssec-triggerd -d UserName root RunAtLoad dnssec-trigger-0.13/osx/nl.nlnetlabs.dnssec-trigger-hook.plist.in0000664000175000017500000000101212355255103024550 0ustar wouterwouter Label nl.nlnetlabs.dnssec-trigger-hook ProgramArguments @libexecdir@/dnssec-trigger-osx.sh WatchPaths /Library/Preferences/SystemConfiguration ThrottleInterval 1 dnssec-trigger-0.13/osx/nl.nlnetlabs.dnssec-trigger-panel.plist.in0000664000175000017500000000066012355255103024717 0ustar wouterwouter KeepAlive Label nl.nlnetlabs.dnssec-trigger-panel ProgramArguments @libexecdir@/RiggerStatusItem.app/Contents/MacOS/RiggerStatusItem dnssec-trigger-0.13/osx/dnssec-trigger-osx.sh.in0000664000175000017500000000246512604747027021334 0ustar wouterwouter#!@SHELL@ # # dnssec trigger for OSX # the network state has changed, obtain a list of DHCP provided DNS servers. # somehow in /Library/Preferences/SystemConfiguration/ # com.apple.network.identification.plist - list of configs seen # preferences.plist - list of what is entered in the config panel tempfile=/tmp/dnssec-trigger-osx.tmp # active interfaces ifs=`ifconfig | awk '/^[^ :]*:/ { sub(/:.*$/,empty); iface=$0 } /status: active/ { print iface }'` ifs=`echo $ifs` # the ssid(s) of the wifi ssid=`/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I 2>&1 | grep "[^B]SSID:"` bssid=`/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I 2>&1 | grep "BSSID:"` # and the DNS servers for that ips="" for i in $ifs; do ips_i=`ipconfig getpacket $i | grep "domain_name_server" | sed -e 's/^.*{//' -e 's/,/ /g' -e 's/}//' ` ips="$ips $ips_i" done # fix whitespace ips=`echo $ips` # see if it has changed if test -f $tempfile; then if echo "$ifs $ips $ssid $bssid" | diff $tempfile - >/dev/null; then # it is equal #logger "dnssec-trigger(osx) no-change $ifs DNS $ips" exit 0 fi fi # store on file echo "$ifs $ips $ssid $bssid" > $tempfile logger "dnssec-trigger(osx) detected $ifs DNS $ips" @sbindir@/dnssec-trigger-control submit "$ips" exit 0 dnssec-trigger-0.13/osx/RiggerStatusItem/0000775000175000017500000000000013024457644020077 5ustar wouterwouterdnssec-trigger-0.13/osx/RiggerStatusItem/English.lproj/0000775000175000017500000000000013024457644022615 5ustar wouterwouterdnssec-trigger-0.13/osx/RiggerStatusItem/English.lproj/InfoPlist.strings0000664000175000017500000000005511627173507026137 0ustar wouterwouter/* Localized versions of Info.plist keys */ dnssec-trigger-0.13/osx/RiggerStatusItem/English.lproj/MainMenu.xib0000664000175000017500000022242511762151325025033 0ustar wouterwouter 1060 11A511 1617 1138 566.00 com.apple.InterfaceBuilder.CocoaPlugin 1617 YES NSScroller NSMenuItem NSMenu NSScrollView NSButtonCell NSButton NSTextFieldCell NSCustomObject NSTextView NSView NSWindowTemplate NSTextField YES com.apple.InterfaceBuilder.CocoaPlugin YES YES YES NSApplication FirstResponder NSApplication RiggerStatusItemAppDelegate NSFontManager YES Reprobe 2147483647 NSImage NSMenuCheckmark NSImage NSMenuMixedState Probe Results 2147483647 Hotspot Signon 2147483647 YES YES 2147483647 Quit 2147483647 RiggerApp 15 2 {{431, 389}, {480, 270}} 1685585920 Probe Results NSWindow 256 YES 256 YES 2304 YES 2322 {{0, 55}, {423, 118}} YES 134 423 1 67121127 0 3 MQA YES YES NSBackgroundColor NSColor YES 6 System selectedTextBackgroundColor 3 MC42NjY2NjY2NjY3AA 6 System selectedTextColor 3 MAA YES YES NSColor NSCursor NSUnderline YES 1 MCAwIDEAA {8, -8} 13 1 6 {463, 10000000} {223, 118} {{1, 1}, {423, 188}} {4, 5} 12582912 YES YES TU0AKgAAAHCAFUqgBVKsAAAAwdVQUqwaEQeIRGJRGFlYqwWLQ+JxuOQpVRmEx2RROKwOQyOUQSPyaUym SxqWyKXyeYxyZzWbSuJTScRCbz2Nz+gRKhUOfTqeUai0OSxiWTiBQSHSGFquGwekxyAgAAAOAQAAAwAA AAEAEAAAAQEAAwAAAAEAEAAAAQIAAwAAAAIACAAIAQMAAwAAAAEABQAAAQYAAwAAAAEAAQAAAREABAAA AAEAAAAIARIAAwAAAAEAAQAAARUAAwAAAAEAAgAAARYAAwAAAAEAEAAAARcABAAAAAEAAABnARwAAwAA AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA 3 MCAwAA 4 256 {{424, 1}, {15, 188}} _doScroller: 1 0.85256409645080566 -2147483392 {{-100, -100}, {223, 15}} 1 _doScroller: 1 0.94565218687057495 {{20, 60}, {440, 190}} 133138 268 {{338, 12}, {96, 32}} YES 67239424 134217728 OK LucidaGrande 13 1044 -2038284033 129 DQ 200 25 {480, 270} {{0, 0}, {1280, 800}} {10000000000000, 10000000000000} YES 15 2 {{250, 134}, {443, 455}} 1685585920 Network DNSSEC failure NSWindow 256 YES 268 {{17, 47}, {409, 388}} YES 67239424 1077940224 VGhlIE5ldHdvcmsgRmFpbHMgdG8gU3VwcG9ydCBETlNTRUMKClRoZSBuZXR3b3JrIHlvdSBhcmUgY29u bmVjdGVkIHRvIGRvZXMgbm90IGFsbG93IEROU1NFQywgdmlhCnRoZSBwcm92aWRlZCBETlMgY2FjaGVz LCBub3IgdmlhIGNvbnRhY3Rpbmcgc2VydmVycyBvbiB0aGUKaW50ZXJuZXQgZGlyZWN0bHkgKGl0IGZp bHRlcnMgdHJhZmZpYyB0byB0aGlzIGVuZCkuICBJdCBpcyBub3QgcG9zc2libGUKdG8gcHJvdmlkZSBE TlNTRUMgc2VjdXJpdHksIGJ1dCB5b3UgY2FuIGNvbm5lY3QgaW5zZWN1cmVseS4KCkRvIHlvdSB3YW50 IHRvIGNvbm5lY3QgaW5zZWN1cmVseT8KCuKAoiAgaWYgeW91IGNob29zZSBEaXNjb25uZWN0IHRoZW4g RE5TIGlzIGRpc2FibGVkLiBJdCBpcyBzYWZlLApidXQgdGhlcmUgaXMgdmVyeSBsaXR0bGUgdGhhdCB3 b3Jrcy4KCuKAoiAgaWYgeW91IGNob29zZSBJbnNlY3VyZSB0aGVuIHRoZSBETlNTRUMgc2VjdXJpdHkg aXMgbG9zdC4KWW91IGNhbiBjb25uZWN0IGFuZCB3b3JrLiBCdXQgdGhlcmUgaXMgbm8gc2FmZXR5LiBU aGUgbmV0d29yawppbnRlcmZlcmVzIHdpdGggRE5TU0VDLCBpdCBtYXkgYWxzbyBpbnRlcmZlcmUgd2l0 aCBvdGhlciB0aGluZ3MuCkhhdmUgY2F1dGlvbiBhbmQgd29yayB3aXRoIHNlbnNpdGl2ZSBwZXJzb25h bCBhbmQgZmluYW5jaWFsCnRoaW5ncyBzb21lIG90aGVyIHRpbWUuCgpTb21lIGhvdHNwb3RzIG1heSB3 b3JrIGFmdGVyIHlvdSBoYXZlIGdhaW5lZCBhY2Nlc3MgdmlhCml0cyBzaWdub24gcGFnZS4gVGhlbiB1 c2UgUmVwcm9iZSBmcm9tIHRoZSBtZW51IHRvIHJldHJ5LiAKClN0YXkgc2FmZSBvdXQgdGhlcmUhA YES 6 System controlColor 6 System controlTextColor 268 {{202, 12}, {110, 32}} YES 67239424 134217728 Disconnect -2038284033 129 200 25 268 {{312, 12}, {96, 32}} YES 67239424 134217728 Insecure -2038284033 129 200 25 {443, 455} {{0, 0}, {1280, 800}} {10000000000000, 10000000000000} YES 15 2 {{381, 384}, {480, 137}} 1685585920 Hotspot Signon NSWindow 256 YES 268 {{17, 49}, {446, 68}} _NS:3596 YES 67239424 272891904 U29tZSBuZXR3b3JrcyBuZWVkIGluc2VjdXJlIHNpZ25vbi4gQWZ0ZXIgeW91IGxvZyBpbiB0byB0aGUK bmV0d29yayB2aWEgaXRzIHBvcnRhbCBwYWdlLCBzZWxlY3QgUmVwcm9iZSB0byBnZXQgc2VjdXJlIGFn YWluLgoKUGxlYXNlLCBzdGF5IHNhZmUgb3V0IHRoZXJlLg LucidaGrande 13 16 _NS:3596 268 {{352, 2}, {92, 32}} _NS:161 YES 67239424 134217728 OK _NS:161 -2038284033 129 DQ 200 25 268 {{260, 2}, {92, 32}} _NS:161 YES 67239424 134217728 Cancel _NS:161 -2038284033 129 Gw 200 25 {480, 137} _NS:2818 {{0, 0}, {1280, 800}} {10000000000000, 10000000000000} YES 15 2 {{250, 134}, {490, 185}} 1685585920 No Web Access NSWindow 256 YES 268 {{17, 48}, {456, 117}} YES 67239424 1077940224 VGhlcmUgaXMgbm8gd2ViIGFjY2VzcyBvbiB0aGlzIG5ldHdvcmsuIERvIHlvdSBoYXZlIHRvIGxvZ2lu IGZvciB0aGF0PwoKV2hpbGUgeW91IGxvZ2luIHlvdSBhcmUgaW5zZWN1cmUsIGZvciBiYWNrd2FyZHMg Y29tcGF0aWJpbGl0eSwgdW50aWwgZG5zc2VjLXRyaWdnZXIgY2FuIGRldGVjdCB3ZWIgYWNjZXNzLgoK U2tpcCB0aGlzIGlmIHlvdSBkbyBub3QgaGF2ZSB0byBsb2cgaW4gb24gdGhpcyBuZXR3b3JrLg YES 268 {{246, 12}, {96, 32}} YES 67239424 134217728 Skip -2038284033 129 200 25 268 {{356, 12}, {96, 32}} YES 67239424 134217728 Log in -2038284033 129 200 25 {490, 185} {{0, 0}, {1280, 800}} {10000000000000, 10000000000000} YES NowebDelegate 15 2 {{375, 396}, {490, 127}} 1685585920 Software Update for Dnssec Trigger NSWindow 256 YES 268 {{247, 6}, {96, 32}} YES 67239424 134217728 Cancel -2038284033 129 Gw 200 25 268 {{353, 6}, {96, 32}} YES 67239424 134217728 OK -2038284033 129 DQ 200 25 268 {{17, 42}, {456, 65}} _NS:3596 YES 67239424 272629760 There is a software update for dnssec-trigger.
Do you wish to install the update? _NS:3596 {490, 127} {{0, 0}, {1280, 800}} {10000000000000, 10000000000000} YES YES delegate 495 riggermenu 538 Reprobe: 540 ProbeResults: 541 terminate: 543 resultwindow 566 ProbeResultsOK: 574 resultpane 575 unsafewindow 578 unsafepane 587 UnsafeDisconnect: 588 UnsafeInsecure: 589 delegate 590 HotspotSignon: 596 HotsignOK: 605 HotsignCancel: 606 hotsignwindow 607 nowebwindow 621 NowebLogin: 622 NowebSkip: 623 delegate 626 delegate 637 updatewindow 638 UpdateOK: 639 UpdateCancel: 640 updatelabel 654 YES 0 -2 File's Owner -1 First Responder -3 Application 420 494 533 YES StatusItem 534 535 Menu Item - Probe Results 536 537 Rigger App 539 564 YES 565 YES 567 YES 568 569 570 572 YES 573 576 YES 577 YES 579 YES 580 583 YES 584 585 YES 586 595 Menu Item - Hotspot Signon 597 YES 598 YES 599 YES 600 601 YES 602 603 YES 604 608 YES Window - No Web Access 609 YES 610 YES 611 YES 612 YES 613 614 615 625 627 YES Window - Software Update 628 YES 629 YES 630 YES 633 634 652 YES 653 YES YES -1.IBPluginDependency -2.IBPluginDependency -3.IBPluginDependency 420.IBPluginDependency 494.IBPluginDependency 533.IBPluginDependency 534.IBPluginDependency 535.IBPluginDependency 536.IBPluginDependency 537.IBPluginDependency 539.IBPluginDependency 564.IBPluginDependency 564.IBWindowTemplateEditedContentRect 564.NSWindowTemplate.visibleAtLaunch 565.IBPluginDependency 567.IBPluginDependency 568.IBPluginDependency 569.IBPluginDependency 570.IBPluginDependency 572.IBPluginDependency 573.IBPluginDependency 576.IBPluginDependency 576.IBWindowTemplateEditedContentRect 576.NSWindowTemplate.visibleAtLaunch 577.IBPluginDependency 579.IBPluginDependency 580.IBPluginDependency 583.IBPluginDependency 583.IBViewIntegration.shadowBlurRadius 583.IBViewIntegration.shadowColor 583.IBViewIntegration.shadowOffsetHeight 583.IBViewIntegration.shadowOffsetWidth 584.IBPluginDependency 585.IBPluginDependency 586.IBPluginDependency 595.IBPluginDependency 597.IBPluginDependency 597.NSWindowTemplate.visibleAtLaunch 598.IBPluginDependency 599.IBPluginDependency 600.IBPluginDependency 601.IBPluginDependency 602.IBPluginDependency 603.IBPluginDependency 604.IBPluginDependency 608.IBPluginDependency 608.IBWindowTemplateEditedContentRect 608.NSWindowTemplate.visibleAtLaunch 609.IBPluginDependency 610.IBPluginDependency 611.IBPluginDependency 611.IBViewIntegration.shadowBlurRadius 611.IBViewIntegration.shadowColor 611.IBViewIntegration.shadowOffsetHeight 611.IBViewIntegration.shadowOffsetWidth 612.IBPluginDependency 613.IBPluginDependency 614.IBPluginDependency 615.IBPluginDependency 625.IBPluginDependency 627.IBNSWindowAutoPositionCentersHorizontal 627.IBNSWindowAutoPositionCentersVertical 627.IBPluginDependency 627.IBWindowTemplateEditedContentRect 627.NSWindowTemplate.visibleAtLaunch 628.IBPluginDependency 629.IBPluginDependency 630.IBPluginDependency 630.IBViewIntegration.shadowBlurRadius 630.IBViewIntegration.shadowColor 630.IBViewIntegration.shadowOffsetHeight 630.IBViewIntegration.shadowOffsetWidth 633.IBPluginDependency 634.IBPluginDependency 652.IBPluginDependency 653.IBPluginDependency YES com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin {{329, 319}, {480, 270}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin {{306, 245}, {443, 455}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin {{306, 245}, {443, 455}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin {{306, 245}, {443, 455}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin YES YES 654 YES NowebDelegate NSObject IBProjectSource ./Classes/NowebDelegate.h RiggerApp NSObject YES YES HotsignCancel: HotsignOK: HotspotSignon: NowebLogin: NowebSkip: ProbeResults: ProbeResultsOK: Reprobe: UnsafeDisconnect: UnsafeInsecure: UpdateCancel: UpdateOK: YES id id id id id id id id id id id id YES YES HotsignCancel: HotsignOK: HotspotSignon: NowebLogin: NowebSkip: ProbeResults: ProbeResultsOK: Reprobe: UnsafeDisconnect: UnsafeInsecure: UpdateCancel: UpdateOK: YES HotsignCancel: id HotsignOK: id HotspotSignon: id NowebLogin: id NowebSkip: id ProbeResults: id ProbeResultsOK: id Reprobe: id UnsafeDisconnect: id UnsafeInsecure: id UpdateCancel: id UpdateOK: id YES YES hotsignwindow nowebwindow resultpane resultwindow riggermenu unsafepane unsafewindow updatelabel updatewindow YES NSWindow NSWindow NSTextView NSWindow NSMenu NSTextField NSWindow NSTextField NSWindow YES YES hotsignwindow nowebwindow resultpane resultwindow riggermenu unsafepane unsafewindow updatelabel updatewindow YES hotsignwindow NSWindow nowebwindow NSWindow resultpane NSTextView resultwindow NSWindow riggermenu NSMenu unsafepane NSTextField unsafewindow NSWindow updatelabel NSTextField updatewindow NSWindow IBProjectSource ./Classes/RiggerApp.h RiggerStatusItemAppDelegate NSObject window NSWindow window window NSWindow IBProjectSource ./Classes/RiggerStatusItemAppDelegate.h 0 IBCocoaFramework com.apple.InterfaceBuilder.CocoaPlugin.macosx com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 YES 3 YES YES NSMenuCheckmark NSMenuMixedState YES {9, 8} {7, 2} dnssec-trigger-0.13/osx/RiggerStatusItem/RiggerStatusItem_Prefix.pch0000664000175000017500000000024311627173507025351 0ustar wouterwouter// // Prefix header for all source files of the 'RiggerStatusItem' target in the 'RiggerStatusItem' project // #ifdef __OBJC__ #import #endif dnssec-trigger-0.13/osx/RiggerStatusItem/status-icon-alert.png0000664000175000017500000000137211717404211024153 0ustar wouterwouterPNG  IHDRVΎWsRGBIDAT8˽[Hq?97斺M4ۦ&Yt5iV"t%( nCKY%eda-NŲZi%CߗB_ E2BQ`Iw\_PRk!6;El|b`@r>(ÉOKڣ,ٴ:1Q P 3O%uKlDn0?ЋNg%ƌ ȶ@&ѽůbqMIHN<4-Ňm^v׋Vhh~g~\yDfKZ]-:ZO>5i{Yݞ-.<U} #r`V?,Q lKkF7x9 ~6p62IENDB`dnssec-trigger-0.13/osx/RiggerStatusItem/RiggerStatusItemAppDelegate.m0000664000175000017500000000062211627173507025613 0ustar wouterwouter// // RiggerStatusItemAppDelegate.m // RiggerStatusItem // // Created by Wouter Wijngaards on 8/29/11. // Copyright 2011 NLnet Labs. All rights reserved. // #import "RiggerStatusItemAppDelegate.h" @implementation RiggerStatusItemAppDelegate @synthesize window; - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { // Insert code here to initialize your application } @end dnssec-trigger-0.13/osx/RiggerStatusItem/RiggerStatusItemAppDelegate.h0000664000175000017500000000052411627173507025607 0ustar wouterwouter// // RiggerStatusItemAppDelegate.h // RiggerStatusItem // // Created by Wouter Wijngaards on 8/29/11. // Copyright 2011 NLnet Labs. All rights reserved. // #import @interface RiggerStatusItemAppDelegate : NSObject { NSWindow *window; } @property (assign) IBOutlet NSWindow *window; @end dnssec-trigger-0.13/osx/RiggerStatusItem/RiggerStatusItem-Info.plist0000664000175000017500000000201311627173507025303 0ustar wouterwouter CFBundleDevelopmentRegion English CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIconFile CFBundleIdentifier com.yourcompany.${PRODUCT_NAME:rfc1034identifier} CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType APPL CFBundleSignature ???? CFBundleShortVersionString 1.0 LSMinimumSystemVersion ${MACOSX_DEPLOYMENT_TARGET} CFBundleVersion 1 NSMainNibFile MainMenu NSPrincipalClass NSApplication LSUIElement dnssec-trigger-0.13/osx/RiggerStatusItem/status-icon.png0000664000175000017500000000331611627173507023061 0ustar wouterwouterPNG  IHDRVΎWRzTXtRaw profile type exifxڥk& .Ѕp`4i`!# Ϳ\P g2]CDdP+X27 UpMM]8]V8@BH9CUE&íxvu^D Q.O/QJsVX*+$ܴYڑ>=wֽG/2aG2꤉Tyj6},.ڒ.[bU_ߗߠF5>A~ lf ƙ@7}0nfWPμmfW(pR7AW%$Ob]b,*Or[ jc_w%}u\ VffdGl{<"'.> iŐ% Hg`gbe^*6V8\oi鼨LkVGZͣj" %H"FZƘeZ<"VfEYI[n5"Q"U.sBIT|d'IDAT8KLSY[R,P,UKEcf1wtˆacDwMht5&d&&(#:"4Bcyx+P>n{6!͈.os}__; bn^ŶE#Tem~hՂwӻmtlqqܿ] K+j$h88B 6UE5fe/Q>JK*Z@[1%䛻Jk-jTefƆ.RJ'a-hl5J!"OQ ^)~n1Gu̼%"~ͱ4_^~y$rE֥M;k\S߼Փ;I-q; SUܜjLt;:p#;G#d6vy?/<Î0 4&^?CѴ$/'1Bb1:Û5RJ$ a@C+GcG c3Y+gޏ;3zbu/ _,/MPNGz^RJGo- ɸtBRK(G \MVa_ -L~9d|kЗ,="(4iXar6 jo2 t"C ҉IPRa Y$l8$ <>Cp7 )j瞐;EPqy)}2jvhſo[UKIENDB`dnssec-trigger-0.13/osx/RiggerStatusItem/RiggerApp.m0000664000175000017500000002320612140211262022116 0ustar wouterwouter// // RiggerApp.m // RiggerStatusItem // // Created by Wouter Wijngaards on 8/29/11. // Copyright 2011 NLnet Labs. All rights reserved. // #include "config.h" #include "cfg.h" #include "log.h" #include "osxattach.h" #import "RiggerApp.h" extern char* test_config_file; /* if true logs trace for debug */ static int verb = 0; static NSLock* feed_lock = NULL; /** basically these are the commandline arguments to PanelAlert */ static NSLock* alert_lock; static struct alert_arg alertinfo; static char* versioninfo = NULL; static RiggerApp* mainapp = NULL; static void cleanup(void) { [mainapp dealloc]; } static void lock_feed_lock(void) { [feed_lock lock]; } static void unlock_feed_lock(void) { [feed_lock unlock]; } static void feed_quit(void) { [feed_lock unlock]; /* calls cleanup() atexit */ exit(0); } static void feed_update_alert(char* new_version) { /* store parameters in threadsafe manner */ [alert_lock lock]; free(versioninfo); versioninfo = new_version; [alert_lock unlock]; if(verb) printf("panel update state in attach\n"); [mainapp performSelectorOnMainThread:@selector(PanelUpdateAlert) withObject:nil waitUntilDone:NO]; } static void feed_alert(struct alert_arg* a) { /* store parameters in threadsafe manner */ [alert_lock lock]; alertinfo = *a; [alert_lock unlock]; if(verb) printf("panel alert state in attach\n"); [mainapp performSelectorOnMainThread:@selector(PanelAlert) withObject:nil waitUntilDone:NO]; } @implementation NowebDelegate -(BOOL)windowShouldClose:(NSWindow*)sender { if(verb) NSLog(@"nowebclose handler"); /* like pressing skip */ mainapp->noweb_asked = 1; attach_send_skip_http(); return YES; } @end /* of NowebDelegate */ @implementation UpdateDelegate -(BOOL)windowShouldClose:(NSWindow*)sender { if(verb) NSLog(@"updateclose handler"); /* like pressing cancel */ attach_send_update_cancel(); return YES; } @end /* of UpdateDelegate */ @implementation RiggerApp -(void) awakeFromNib { char* cfgfile = CONFIGFILE; if(test_config_file) cfgfile = test_config_file; /* Setup the status icon in the tray */ riggeritem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength] retain]; NSBundle* bundle = [NSBundle mainBundle]; /* Note that the icon images are 18x18px in size and are png with * transparency. This makes the tray icon work on OSX. Other * sizes do not work. */ icon = [[NSImage alloc] initWithContentsOfFile: [bundle pathForResource:@"status-icon" ofType:@"png"]]; icon_alert = [[NSImage alloc] initWithContentsOfFile: [bundle pathForResource:@"status-icon-alert" ofType:@"png"]]; [riggeritem setImage:icon]; /* [riggeritem setAlternateImage:icon_alert]; this would be the highlight image but * we use the builtin highlight code that uses the alpha channel in the icon */ [riggeritem setMenu:riggermenu]; [riggeritem setToolTip:@"dnssec-trigger"]; /* highlight the icon when the statusmenu is shown */ [riggeritem setHighlightMode:YES]; /* Init */ mainapp = self; unsafe_asked = 0; unsafe_should = 0; noweb_asked = 0; memset(&alertinfo, 0, sizeof(alertinfo)); alert_lock = [NSLock alloc]; log_ident_set("dnssec-trigger-panel-osx"); log_init(NULL, 0, NULL); ERR_load_crypto_strings(); ERR_load_SSL_strings(); OpenSSL_add_all_algorithms(); (void)SSL_library_init(); /* Read config */ cfg = cfg_create(cfgfile); if(!cfg) fatal_exit("cannot read config file %s", cfgfile); /* spawn the feed thread */ attach_create(); feed_lock = [NSLock alloc]; feed->lock = &lock_feed_lock; feed->unlock = &unlock_feed_lock; feed->quit = &feed_quit; feed->alert = &feed_alert; feed->update_alert = &feed_update_alert; atexit(&cleanup); [NSThread detachNewThreadSelector:@selector(SpawnFeed:) toTarget:self withObject:nil]; } -(void) dealloc { if(verb) printf("dealloc routine\n"); attach_stop(); /* [feed_lock release]; do not dealloc but let system reclaim these resources, the attach.c:check_for_event may still need to unlock this feed_lock free(feed); */ [alert_lock release]; [icon release]; [icon_alert release]; free(versioninfo); [super dealloc]; } -(void)SpawnFeed:(id)param { attach_start(cfg); } -(IBAction)Reprobe:(id)sender { if(verb) NSLog(@"Reprobe"); attach_send_reprobe(); } void append_txt(NSTextView* pane, char* str) { NSRange range; range.location = [[pane textStorage] length]; range.length = 0; NSString* s = [NSString stringWithUTF8String:str]; [pane replaceCharactersInRange: range withString: s]; /* because the string is allocated with convenience function * no need to [s release]. */ } -(IBAction)ProbeResults:(id)sender { if(verb) NSLog(@"ProbeResults"); /* this is to help us bring a window to the front * from the hidden app */ [NSApp activateIgnoringOtherApps:YES]; [resultpane setEditable:YES]; NSRange range; range.location = 0; range.length = [[resultpane textStorage] length]; [resultpane replaceCharactersInRange: range withString:@""]; char buf[102400]; fetch_proberesults(buf, sizeof(buf), "\n"); append_txt(resultpane, buf); [resultpane setEditable:NO]; [resultpane setSelectable:YES]; [resultwindow setLevel:NSScreenSaverWindowLevel + 1]; [resultwindow orderFront:sender]; } -(IBAction)ProbeResultsOK:(id)sender { if(verb) NSLog(@"ProbeResultsOK"); [resultwindow orderOut:sender]; } -(IBAction)UnsafeInsecure:(id)sender { if(verb) NSLog(@"Unsafe:Insecure"); [unsafewindow orderOut:sender]; unsafe_asked = 1; unsafe_should = 0; attach_send_insecure(1); } -(IBAction)UnsafeDisconnect:(id)sender { if(verb) NSLog(@"Unsafe:Disconnect"); [unsafewindow orderOut:sender]; unsafe_asked = 1; unsafe_should = 0; attach_send_insecure(0); } -(IBAction)HotspotSignon:(id)sender { if(verb) NSLog(@"menu-hotspotsignon"); /* this is to help us bring a window to the front * from the hidden app */ [NSApp activateIgnoringOtherApps:YES]; [hotsignwindow center]; if([hotsignwindow isMiniaturized]) /* without this if(), random win popsup often */ [hotsignwindow deminiaturize:sender]; [hotsignwindow setLevel:NSScreenSaverWindowLevel + 1]; [hotsignwindow orderFront:sender]; } -(IBAction)HotsignOK:(id)sender { if(verb) NSLog(@"hotsign ok"); attach_send_hotspot_signon(); [hotsignwindow orderOut:sender]; unsafe_asked = 1; unsafe_should = 0; } -(IBAction)HotsignCancel:(id)sender { if(verb) NSLog(@"hotsign cancel"); [hotsignwindow orderOut:sender]; if(unsafe_should) [mainapp PresentUnsafeDialog]; } -(IBAction)NowebLogin:(id)sender { if(verb) NSLog(@"noweb login"); [nowebwindow orderOut:sender]; noweb_asked = 1; attach_send_insecure(1); sleep(1); /* for dns settings to get updated */ run_login(); } -(IBAction)NowebSkip:(id)sender { if(verb) NSLog(@"noweb skip"); [nowebwindow orderOut:sender]; noweb_asked = 1; attach_send_skip_http(); } -(void)PresentNowebDialog { [nowebwindow center]; if([nowebwindow isMiniaturized]) /* without this if(), random win popsup often */ [nowebwindow deminiaturize:nil]; [nowebwindow setLevel:NSScreenSaverWindowLevel + 1]; [nowebwindow orderFront:nil]; } -(IBAction)UpdateOK:(id)sender { if(verb) NSLog(@"update OK"); [updatewindow orderOut:sender]; attach_send_update_ok(); } -(IBAction)UpdateCancel:(id)sender { if(verb) NSLog(@"update Cancel"); [updatewindow orderOut:sender]; attach_send_update_cancel(); } -(void)PresentUpdateDialog:(char*)newversion { /* set text in updatelabel */ NSString* str; char update_text[1024]; snprintf(update_text, sizeof(update_text), "There is a software update available for dnssec-trigger\n" "from %s to %s.\n" "Do you wish to install the update now?", PACKAGE_VERSION, newversion); /* no need to [str release] because of convenience function */ str = [NSString stringWithUTF8String:update_text]; [updatelabel setStringValue:str]; [updatewindow center]; if([updatewindow isMiniaturized]) /* without this if(), random win popsup often */ [updatewindow deminiaturize:nil]; [updatewindow setLevel:NSScreenSaverWindowLevel + 1]; [updatewindow orderFront:nil]; } -(BOOL)windowShouldClose:(NSWindow*)sender { if(verb) NSLog(@"unsafeclose handler"); /* like pressing disconnect */ unsafe_asked = 1; unsafe_should = 0; attach_send_insecure(0); return YES; } -(void)PresentUnsafeDialog { unsafe_should = 1; if([hotsignwindow isVisible]) return; /* wait for hotspot signon question to finish */ [unsafewindow center]; if([unsafewindow isMiniaturized]) /* without this if(), random win popsup often */ [unsafewindow deminiaturize:nil]; [unsafewindow setLevel:NSScreenSaverWindowLevel + 1]; [unsafewindow orderFront:nil]; } -(void)PanelAlertDanger { [riggeritem setImage:icon_alert]; } -(void)PanelAlertSafe { [riggeritem setImage:icon]; } static void do_danger(void) { [mainapp PanelAlertDanger]; } static void do_safe(void) { [mainapp PanelAlertSafe]; } static void do_ask(void) { [mainapp PresentUnsafeDialog]; } static void do_noweb(void) { [mainapp PresentNowebDialog]; } -(void)PanelAlert { NSString* tt; const char* ctt; struct alert_arg a; if(verb) NSLog(@"PanelAlert function"); [alert_lock lock]; a = alertinfo; [alert_lock unlock]; ctt = state_tooltip(&a); /* no need to [tt release] because of convenience function */ tt = [NSString stringWithUTF8String:ctt]; [riggeritem setToolTip:tt]; process_state(&a, &unsafe_asked, &noweb_asked, &do_danger, &do_safe, &do_ask, &do_noweb); if(!a.now_dark) unsafe_should = 0; } -(void)PanelUpdateAlert { char* newversion; if(verb) NSLog(@"PanelAlert function"); [alert_lock lock]; newversion = versioninfo; versioninfo = NULL; [alert_lock unlock]; [mainapp PresentUpdateDialog:newversion]; free(newversion); } @end dnssec-trigger-0.13/osx/RiggerStatusItem/main.m0000664000175000017500000000064311627174630021202 0ustar wouterwouter// // main.m // RiggerStatusItem // // Created by Wouter Wijngaards on 8/29/11. // Copyright 2011 NLnet Labs. All rights reserved. // #import char* test_config_file = NULL; int main(int argc, char *argv[]) { if(argc > 2 && strcmp(argv[1], "-c") == 0) { test_config_file = argv[2]; argv[2] = argv[0]; argv += 2; argc -= 2; } return NSApplicationMain(argc, (const char **) argv); } dnssec-trigger-0.13/osx/RiggerStatusItem/RiggerStatusItem.xcodeproj/0000775000175000017500000000000013024457644025335 5ustar wouterwouterdnssec-trigger-0.13/osx/RiggerStatusItem/RiggerStatusItem.xcodeproj/project.pbxproj.in0000664000175000017500000003677612631553716031041 0ustar wouterwouter// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 45; objects = { /* Begin PBXBuildFile section */ 1DDD58160DA1D0A300B32029 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD58140DA1D0A300B32029 /* MainMenu.xib */; }; 256AC3DA0F4B6AC300CF3369 /* RiggerStatusItemAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 256AC3D90F4B6AC300CF3369 /* RiggerStatusItemAppDelegate.m */; }; 6C43D4A6140CEEFF009EB6F2 /* osxattach.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C43D4A5140CEEFF009EB6F2 /* osxattach.m */; }; 6C43D4B0140CF063009EB6F2 /* cfg.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43D4AD140CF063009EB6F2 /* cfg.c */; }; 6C43D4B3140CF073009EB6F2 /* log.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43D4B1140CF073009EB6F2 /* log.c */; }; 6C43D4B6140CF07F009EB6F2 /* net_help.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43D4B4140CF07F009EB6F2 /* net_help.c */; }; 6C7579E7140BBBA500F8BF2D /* RiggerApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C7579E6140BBBA500F8BF2D /* RiggerApp.m */; }; 6C7579EB140BBC5400F8BF2D /* status-icon-alert.png in Resources */ = {isa = PBXBuildFile; fileRef = 6C7579EA140BBC5400F8BF2D /* status-icon-alert.png */; }; 6C7579ED140BBC6400F8BF2D /* status-icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 6C7579EC140BBC6400F8BF2D /* status-icon.png */; }; 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; 1DDD58150DA1D0A300B32029 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = ""; }; 256AC3D80F4B6AC300CF3369 /* RiggerStatusItemAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RiggerStatusItemAppDelegate.h; sourceTree = ""; }; 256AC3D90F4B6AC300CF3369 /* RiggerStatusItemAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RiggerStatusItemAppDelegate.m; sourceTree = ""; }; 256AC3F00F4B6AF500CF3369 /* RiggerStatusItem_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RiggerStatusItem_Prefix.pch; sourceTree = ""; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 6C43D4A5140CEEFF009EB6F2 /* osxattach.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = osxattach.m; sourceTree = ""; }; 6C43D4A7140CEF11009EB6F2 /* osxattach.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = osxattach.h; sourceTree = ""; }; 6C43D4AD140CF063009EB6F2 /* cfg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cfg.c; sourceTree = ""; }; 6C43D4AE140CF063009EB6F2 /* cfg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cfg.h; sourceTree = ""; }; 6C43D4AF140CF063009EB6F2 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = ""; }; 6C43D4B1140CF073009EB6F2 /* log.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = log.c; sourceTree = ""; }; 6C43D4B2140CF073009EB6F2 /* log.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = log.h; sourceTree = ""; }; 6C43D4B4140CF07F009EB6F2 /* net_help.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = net_help.c; sourceTree = ""; }; 6C43D4B5140CF07F009EB6F2 /* net_help.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = net_help.h; sourceTree = ""; }; 6C7579E5140BBBA500F8BF2D /* RiggerApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RiggerApp.h; sourceTree = ""; }; 6C7579E6140BBBA500F8BF2D /* RiggerApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RiggerApp.m; sourceTree = ""; }; 6C7579EA140BBC5400F8BF2D /* status-icon-alert.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "status-icon-alert.png"; sourceTree = ""; }; 6C7579EC140BBC6400F8BF2D /* status-icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "status-icon.png"; sourceTree = ""; }; 8D1107310486CEB800E47090 /* RiggerStatusItem-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "RiggerStatusItem-Info.plist"; sourceTree = ""; }; 8D1107320486CEB800E47090 /* RiggerStatusItem.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RiggerStatusItem.app; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 8D11072E0486CEB800E47090 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 080E96DDFE201D6D7F000001 /* Classes */ = { isa = PBXGroup; children = ( 256AC3D80F4B6AC300CF3369 /* RiggerStatusItemAppDelegate.h */, 256AC3D90F4B6AC300CF3369 /* RiggerStatusItemAppDelegate.m */, ); name = Classes; sourceTree = ""; }; 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { isa = PBXGroup; children = ( 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, ); name = "Linked Frameworks"; sourceTree = ""; }; 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { isa = PBXGroup; children = ( 29B97324FDCFA39411CA2CEA /* AppKit.framework */, 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */, 29B97325FDCFA39411CA2CEA /* Foundation.framework */, ); name = "Other Frameworks"; sourceTree = ""; }; 19C28FACFE9D520D11CA2CBB /* Products */ = { isa = PBXGroup; children = ( 8D1107320486CEB800E47090 /* RiggerStatusItem.app */, ); name = Products; sourceTree = ""; }; 29B97314FDCFA39411CA2CEA /* RiggerStatusItem */ = { isa = PBXGroup; children = ( 6C43D4B4140CF07F009EB6F2 /* net_help.c */, 6C43D4B5140CF07F009EB6F2 /* net_help.h */, 6C43D4B1140CF073009EB6F2 /* log.c */, 6C43D4B2140CF073009EB6F2 /* log.h */, 6C43D4AD140CF063009EB6F2 /* cfg.c */, 6C43D4AE140CF063009EB6F2 /* cfg.h */, 6C43D4AF140CF063009EB6F2 /* config.h */, 6C43D4A7140CEF11009EB6F2 /* osxattach.h */, 6C43D4A5140CEEFF009EB6F2 /* osxattach.m */, 6C7579EC140BBC6400F8BF2D /* status-icon.png */, 6C7579EA140BBC5400F8BF2D /* status-icon-alert.png */, 080E96DDFE201D6D7F000001 /* Classes */, 29B97315FDCFA39411CA2CEA /* Other Sources */, 29B97317FDCFA39411CA2CEA /* Resources */, 29B97323FDCFA39411CA2CEA /* Frameworks */, 19C28FACFE9D520D11CA2CBB /* Products */, 6C7579E5140BBBA500F8BF2D /* RiggerApp.h */, 6C7579E6140BBBA500F8BF2D /* RiggerApp.m */, ); name = RiggerStatusItem; sourceTree = ""; }; 29B97315FDCFA39411CA2CEA /* Other Sources */ = { isa = PBXGroup; children = ( 256AC3F00F4B6AF500CF3369 /* RiggerStatusItem_Prefix.pch */, 29B97316FDCFA39411CA2CEA /* main.m */, ); name = "Other Sources"; sourceTree = ""; }; 29B97317FDCFA39411CA2CEA /* Resources */ = { isa = PBXGroup; children = ( 8D1107310486CEB800E47090 /* RiggerStatusItem-Info.plist */, 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, 1DDD58140DA1D0A300B32029 /* MainMenu.xib */, ); name = Resources; sourceTree = ""; }; 29B97323FDCFA39411CA2CEA /* Frameworks */ = { isa = PBXGroup; children = ( 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, ); name = Frameworks; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 8D1107260486CEB800E47090 /* RiggerStatusItem */ = { isa = PBXNativeTarget; buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "RiggerStatusItem" */; buildPhases = ( 8D1107290486CEB800E47090 /* Resources */, 8D11072C0486CEB800E47090 /* Sources */, 8D11072E0486CEB800E47090 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = RiggerStatusItem; productInstallPath = "$(HOME)/Applications"; productName = RiggerStatusItem; productReference = 8D1107320486CEB800E47090 /* RiggerStatusItem.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0410; ORGANIZATIONNAME = "NLnet Labs"; }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "RiggerStatusItem" */; compatibilityVersion = "Xcode 3.1"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, Japanese, French, German, ); mainGroup = 29B97314FDCFA39411CA2CEA /* RiggerStatusItem */; projectDirPath = ""; projectRoot = ""; targets = ( 8D1107260486CEB800E47090 /* RiggerStatusItem */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 8D1107290486CEB800E47090 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */, 1DDD58160DA1D0A300B32029 /* MainMenu.xib in Resources */, 6C7579EB140BBC5400F8BF2D /* status-icon-alert.png in Resources */, 6C7579ED140BBC6400F8BF2D /* status-icon.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 8D11072C0486CEB800E47090 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 8D11072D0486CEB800E47090 /* main.m in Sources */, 256AC3DA0F4B6AC300CF3369 /* RiggerStatusItemAppDelegate.m in Sources */, 6C7579E7140BBBA500F8BF2D /* RiggerApp.m in Sources */, 6C43D4A6140CEEFF009EB6F2 /* osxattach.m in Sources */, 6C43D4B0140CF063009EB6F2 /* cfg.c in Sources */, 6C43D4B3140CF073009EB6F2 /* log.c in Sources */, 6C43D4B6140CF07F009EB6F2 /* net_help.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( 089C165DFE840E0CC02AAC07 /* English */, ); name = InfoPlist.strings; sourceTree = ""; }; 1DDD58140DA1D0A300B32029 /* MainMenu.xib */ = { isa = PBXVariantGroup; children = ( 1DDD58150DA1D0A300B32029 /* English */, ); name = MainMenu.xib; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ C01FCF4B08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = RiggerStatusItem_Prefix.pch; HEADER_SEARCH_PATHS = @OSX_SSL_INCLUDE@; LIBRARY_SEARCH_PATHS = @OSX_SSL_LIB@; INFOPLIST_FILE = "RiggerStatusItem-Info.plist"; INSTALL_PATH = "$(HOME)/Applications"; PRODUCT_NAME = RiggerStatusItem; }; name = Debug; }; C01FCF4C08A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_MODEL_TUNING = G5; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = RiggerStatusItem_Prefix.pch; HEADER_SEARCH_PATHS = @OSX_SSL_INCLUDE@; LIBRARY_SEARCH_PATHS = @OSX_SSL_LIB@; INFOPLIST_FILE = "RiggerStatusItem-Info.plist"; INSTALL_PATH = "$(HOME)/Applications"; PRODUCT_NAME = RiggerStatusItem; }; name = Release; }; C01FCF4F08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD)"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ( "-lcrypto", "-lssl", "-lz", ); PREBINDING = NO; SDKROOT = macosx; }; name = Debug; }; C01FCF5008A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD)"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ( "-lcrypto", "-lssl", "-lz", ); PREBINDING = NO; SDKROOT = macosx; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "RiggerStatusItem" */ = { isa = XCConfigurationList; buildConfigurations = ( C01FCF4B08A954540054247B /* Debug */, C01FCF4C08A954540054247B /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; C01FCF4E08A954540054247B /* Build configuration list for PBXProject "RiggerStatusItem" */ = { isa = XCConfigurationList; buildConfigurations = ( C01FCF4F08A954540054247B /* Debug */, C01FCF5008A954540054247B /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; } dnssec-trigger-0.13/osx/RiggerStatusItem/RiggerApp.h0000664000175000017500000000362311762151325022126 0ustar wouterwouter// // RiggerApp.h // RiggerStatusItem // // Created by Wouter Wijngaards on 8/29/11. // Copyright 2011 NLnet Labs. All rights reserved. // #import struct cfg; /* class that helps catch window close on the noweb window */ @interface NowebDelegate : NSObject { } -(BOOL)windowShouldClose:(NSWindow*)sender; @end /* class that helps catch window close on the update window */ @interface UpdateDelegate : NSObject { } -(BOOL)windowShouldClose:(NSWindow*)sender; @end @interface RiggerApp : NSObject { /* outlets connect to the interface */ IBOutlet NSMenu* riggermenu; NSStatusItem* riggeritem; NSImage* icon; NSImage* icon_alert; IBOutlet NSWindow* resultwindow; IBOutlet NSTextView* resultpane; IBOutlet NSWindow* unsafewindow; IBOutlet NSTextField* unsafepane; IBOutlet NSWindow* hotsignwindow; IBOutlet NSWindow* nowebwindow; IBOutlet NSWindow* updatewindow; IBOutlet NSTextField* updatelabel; @public /** if we have asked about disconnect or insecure */ int unsafe_asked; /** if we should ask unsafe */ int unsafe_should; /** if we have asked about noweb access */ int noweb_asked; /** configuration */ struct cfg* cfg; } /* IBAction to connect to the routine that takes actions after menu */ -(IBAction)Reprobe:(id)sender; -(IBAction)ProbeResults:(id)sender; -(IBAction)ProbeResultsOK:(id)sender; -(IBAction)UnsafeInsecure:(id)sender; -(IBAction)UnsafeDisconnect:(id)sender; -(IBAction)HotspotSignon:(id)sender; -(IBAction)HotsignOK:(id)sender; -(IBAction)HotsignCancel:(id)sender; -(IBAction)NowebLogin:(id)sender; -(IBAction)NowebSkip:(id)sender; -(IBAction)UpdateOK:(id)sender; -(IBAction)UpdateCancel:(id)sender; -(BOOL)windowShouldClose:(NSWindow*)sender; -(void)SpawnFeed:(id)param; -(void)PanelUpdateAlert; -(void)PanelAlert; -(void)PresentUnsafeDialog; -(void)PanelAlertDanger; -(void)PanelAlertSafe; -(void)PresentNowebDialog; -(void)PresentUpdateDialog:(char*)newversion; @end dnssec-trigger-0.13/osx/wakelist.h0000664000175000017500000000377512275162157016644 0ustar wouterwouter/* * wakelist.h - dnssec-trigger OSX sleep and wake listener. * * Copyright (c) 2013, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains the OSX sleep and wakeup listener service. */ #ifndef OSX_WAKELIST_H #define OSX_WAKELIST_H struct svr; /** * Start the wake and sleep listener thread * @param cfg: the configuration to know how to kick unbound's cache. * config is copied, for threadsafe access. */ void osx_wakelistener_start(struct cfg* cfg); #endif /* OSX_WAKELIST_H */ dnssec-trigger-0.13/osx/wakelist.c0000664000175000017500000001443712275162157016634 0ustar wouterwouter/* * wakelist.c - dnssec-trigger OSX sleep and wake listener. * * Copyright (c) 2013, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains the OSX sleep and wakeup listener service. */ #include "config.h" #include "riggerd/cfg.h" #include "riggerd/log.h" #include "osx/wakelist.h" #include #include #include #include #include #include #include #include #include /* a reference to the Root Power Domain IOService */ static io_connect_t root_port; static char* unbound_control; /* perform unbound command, from OSX thread */ static void osx_ub_ctrl(const char* cmd) { char s[12000]; int r; verbose(VERB_ALGO, "system %s %s", unbound_control, cmd); snprintf(s, sizeof(s), "%s %s", unbound_control, cmd); r = system(s); if(r == -1) { log_err("system(%s) failed: %s", s, strerror(errno)); } else if(r != 0) { log_warn("unbound-control exited with status %d, cmd: %s", r, s); } } /* called when OSX power status changes notifications happen */ static void sleepcallback(void* ATTR_UNUSED(arg), io_service_t ATTR_UNUSED(service), natural_t messageType, void* messageArgument ) { verbose(VERB_ALGO, "OSX ioservice messageType %08lx, arg %08lx\n", (long unsigned int)messageType, (long unsigned int)messageArgument ); if(messageType == kIOMessageCanSystemSleep) { /* allow the system to sleep */ IOAllowPowerChange(root_port, (long)messageArgument); } else if(messageType == kIOMessageSystemWillSleep) { /* do not delay sleep */ IOAllowPowerChange(root_port, (long)messageArgument); } else if(messageType == kIOMessageSystemWillPowerOn) { /* system has started the wake up process */ /* assume we are on a new network, * the ping times, and timeouts are no longer valid. * bogus information (due to timeouts) may no longer be, * and long-running timeouts on the request list removed. */ osx_ub_ctrl("flush_infra all"); osx_ub_ctrl("flush_bogus"); osx_ub_ctrl("flush_requestlist"); /* not sure if the ethernet device is already available * at this stage, but the finishwake is about 2 seconds * away, so this fits within 'normal' timeouts. * we flush the caches now so that unbound starts * giving responses during the wakeup. * The DNS cache in unbound is left intact. */ } else if(messageType == kIOMessageSystemHasPoweredOn) { /* system has finished the wake up process */ } } static void* osx_wakesleep_thread(void* ATTR_UNUSED(arg)) { /* attach sleep and wake listener as described in apple note QA1340. * http://developer.apple.com/library/mac/#qa/qa1340/_index.html * This creates a thread that listens to the sleep and wake up * notifications (it allows sleep), and notifies dnssec-trigger about * these events. The thread is killed when the process exits. */ /* notification port allocated by IORegisterForSystemPower */ IONotificationPortRef notifyPortRef; /* notifier object, used to deregister later, * but we let the system cleanup this thread */ io_object_t notifierObject; /* register to receive system sleep notifications */ root_port = IORegisterForSystemPower(NULL/*myarg*/, ¬ifyPortRef, sleepcallback, ¬ifierObject); if(!root_port) { /* could this be a permission issue? if so, just exit thread, * and do not monitor for system power changes */ log_err("IORegisterForSystemPower failed: %s", strerror(errno)); return NULL; } /* add notification port to the runloop */ CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(notifyPortRef), kCFRunLoopCommonModes ); /* run the loop to get notifications. */ CFRunLoopRun(); /* free(unbound_control) */ /* deregister and cleanup notification */ /* ENOTREACH */ return NULL; } void osx_wakelistener_start(struct cfg* cfg) { /* create the thread */ /* marks the thread as detached, so that on exit() the thread can * get removed by the operating system quickly */ pthread_attr_t attr; pthread_t id; if(cfg->noaction) return; /* copy cfg elements of interest for threadsafe access. * The cfg itself can be destroyed when sighup causes a reload. */ if(cfg->unbound_control) unbound_control = strdup(cfg->unbound_control); else unbound_control = strdup("unbound-control"); if(!unbound_control) fatal_exit("malloc failure"); if(pthread_attr_init(&attr) != 0) fatal_exit("osxsleepwake: could not pthread_attr_init"); if(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0) fatal_exit("osxsleepwake: could not pthread_attr_setdetach"); if(pthread_create(&id, &attr, osx_wakesleep_thread, NULL) != 0) fatal_exit("osxsleepwake: could not pthread_create"); if(pthread_attr_destroy(&attr) != 0) fatal_exit("osxsleepwake: could not pthread_attr_destroy"); } dnssec-trigger-0.13/configure.ac0000664000175000017500000004717112631553716016324 0ustar wouterwouter# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.56) sinclude(acx_nlnetlabs.m4) CFLAGS="$CFLAGS" AC_INIT(dnssec-trigger, 0.13, labs@nlnetlabs.nl, dnssec-trigger) AC_AIX AC_C_CONST AC_LANG_C dnl dnl By default set prefix to /usr/local dnl case "$prefix" in NONE) prefix="/usr/local" ;; esac if test "$exec_prefix" == "NONE"; then exec_prefix="$prefix" fi # are we on MinGW? if uname -s 2>&1 | grep MINGW32 >/dev/null; then on_mingw="yes" else if echo $target | grep mingw32 >/dev/null; then on_mingw="yes" else on_mingw="no"; fi fi AC_DEFINE(WINVER, 0x0502, [the version of the windows API enabled]) dnl compute package version for windows res files, the first four numbers. [ wnvs=`echo $PACKAGE_VERSION.0.0 | sed -e 's/^[^0-9]*\([0-9]\)[^0-9]*\([0-9]\)[^0-9]*\([0-9]\)[^0-9]*\([0-9]\).*$/\1,\2,\3,\4/' -e 's/^[^0-9]*\([0-9]\)[^0-9]*\([0-9]\)[^0-9]*\([0-9]\)[^0-9]*$/\1,\2,\3,0/' ` ] AC_DEFINE_UNQUOTED(RSRC_PACKAGE_VERSION, [$wnvs], [version number for resource files]) ACX_DEPFLAG ACX_DETERMINE_EXT_FLAGS_UNBOUND AC_CHECK_HEADERS([getopt.h time.h],,, [AC_INCLUDES_DEFAULT]) # flag warnings. AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [Enable debug warnings, asserts, makefile-dependencies])) debug_enabled="$enable_debug" AC_SUBST(debug_enabled) case "$enable_debug" in yes) ACX_CHECK_COMPILER_FLAG(W, [CFLAGS="$CFLAGS -W"]) ACX_CHECK_COMPILER_FLAG(Wall, [CFLAGS="$CFLAGS -Wall"]) ACX_CHECK_COMPILER_FLAG(Wextra, [CFLAGS="$CFLAGS -Wextra"]) ACX_CHECK_COMPILER_FLAG(Wdeclaration-after-statement, [CFLAGS="$CFLAGS -Wdeclaration-after-statement"]) AC_DEFINE([DO_DEBUG], [], [define this to enable debug checks.]) ;; no|*) # nothing to do. ;; esac if test "$on_mingw" = "yes"; then # this flag is only really needed for GTK+ applications for its # linkback of event functions. EXPORT_DYNAMIC="-Wl,-export-all-symbols" else AC_MSG_CHECKING([if -export-dynamic works]) bakld="$LDFLAGS" LDFLAGS="$LDFLAGS -export-dynamic" AC_LINK_IFELSE([AC_LANG_SOURCE([[ int main(void) { return 0; } ]])], [ AC_MSG_RESULT(yes) EXPORT_DYNAMIC="-export-dynamic" ], [AC_MSG_RESULT(no)]) LDFLAGS="$bakld" AC_SUBST(EXPORT_DYNAMIC) fi AC_C_INLINE ACX_CHECK_FORMAT_ATTRIBUTE ACX_CHECK_UNUSED_ATTRIBUTE if test "$srcdir" != "."; then CPPFLAGS="$CPPFLAGS -I$srcdir" fi AC_CHECK_TOOL(STRIP, strip) # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h],,, [AC_INCLUDES_DEFAULT]) # MinGW32 tests if test "$on_mingw" = "yes"; then AC_CHECK_HEADERS([windows.h winsock2.h ws2tcpip.h],,, [AC_INCLUDES_DEFAULT]) fi # end mingw32 tests # check for types AC_CHECK_TYPE(int8_t, char) AC_CHECK_TYPE(int16_t, short) AC_CHECK_TYPE(int32_t, int) AC_CHECK_TYPE(int64_t, long long) AC_CHECK_TYPE(uint8_t, unsigned char) AC_CHECK_TYPE(uint16_t, unsigned short) AC_CHECK_TYPE(uint32_t, unsigned int) AC_CHECK_TYPE(uint64_t, unsigned long long) AC_TYPE_SIZE_T AC_CHECK_TYPE(ssize_t, int) AC_TYPE_UID_T AC_TYPE_PID_T AC_TYPE_OFF_T AC_CHECK_TYPE(u_char, , [AC_DEFINE([u_char], [unsigned char], [Define to 'unsigned char' if not defined])], [ AC_INCLUDES_DEFAULT #ifdef HAVE_SYS_SOCKET_H # include #endif #ifdef HAVE_WS2TCPIP_H # include #endif ]) ACX_TYPE_RLIM_T ACX_TYPE_SOCKLEN_T ACX_TYPE_IN_ADDR_T ACX_TYPE_IN_PORT_T # check to see if libraries are needed for these functions. AC_SEARCH_LIBS([inet_pton], [nsl]) AC_SEARCH_LIBS([socket], [socket]) # set static linking if requested staticexe="no" AC_ARG_ENABLE(static-exe, AC_HELP_STRING([--enable-static-exe], [ enable to compile executables statically against ldns and crypto libs ]), , ) if test x_$enable_static_exe = x_yes; then staticexe="yes" if test "$on_mingw" = yes; then staticexe="-all-static" # for static crosscompile, include gdi32 and zlib here. if test "`uname`" = "Linux"; then LIBS="$LIBS -lgdi32 -lz" fi fi fi ACX_FUNC_MALLOC([dnssectrigger]) AC_FUNC_CHOWN AC_FUNC_FORK AC_TYPE_SIGNAL AC_FUNC_FSEEKO ACX_SYS_LARGEFILE # check for OpenSSL ACX_WITH_SSL ACX_LIB_SSL AC_CHECK_HEADERS([openssl/conf.h],,, [AC_INCLUDES_DEFAULT]) AC_CHECK_HEADERS([openssl/engine.h],,, [AC_INCLUDES_DEFAULT]) if test "$staticexe" = "yes"; then LIBS="`echo $LIBS | sed -e 's/ -lcrypto//'`" LIBS="`echo $LIBS | sed -e 's/^-lcrypto//'`" LIBS="$ssldir/lib/libssl.a $ssldir/lib/libcrypto.a $LIBS" # check if lz is needed AC_MSG_CHECKING([if static libcrypto needs -lz]) AC_TRY_LINK(, [ int SSL_library_init(void); (void)SSL_library_init(); ], [ AC_MSG_RESULT(no) ], [ AC_MSG_RESULT(yes) if test `uname` = "Darwin" -a -f $ssldir/lib/libz.a; then LIBS="$LIBS $ssldir/lib/libz.a" else LIBS="$LIBS -lz" fi ]) else LIBS="-lssl $LIBS" fi AC_SUBST(ssldir) ACX_CHECK_GETADDRINFO_WITH_INCLUDES if test "$USE_WINSOCK" = 1; then AC_DEFINE(UB_ON_WINDOWS, 1, [Use win32 resources and API]) UB_ON_WINDOWS=yes AC_SUBST(UB_ON_WINDOWS) AC_CHECK_HEADERS([iphlpapi.h],,, [AC_INCLUDES_DEFAULT #include ]) AC_CHECK_TOOL(WINDRES, windres) LIBS="$LIBS -liphlpapi" AC_CHECK_FUNC([EVP_PKEY_CTX_new_id],,[AC_ERROR(Need newer openssl)]) AC_CHECK_FUNCS([_beginthreadex]) AC_MSG_CHECKING([for GetAdaptersAddresses]) AC_LINK_IFELSE( [AC_LANG_SOURCE([[ #include #include int main(void) { (void)GetAdaptersAddresses(0, 0, NULL, NULL, NULL); return 0; } ]])] , [ AC_MSG_RESULT(yes) AC_DEFINE(HAVE_GETADAPTERSADDRESSES, [1], [If we have this function (windows XP and later)]) ], [ AC_MSG_RESULT(no) ]) fi AC_DEFINE(USE_MINI_EVENT, 1, [Use builtin event system]) if test $ac_cv_func_getaddrinfo = no; then AC_LIBOBJ([fake-rfc2553]) fi # check after getaddrinfo for its libraries ACX_FUNC_IOCTLSOCKET # see if daemon(3) exists, and if it is deprecated. AC_CHECK_FUNCS([daemon]) if test $ac_cv_func_daemon = yes; then ACX_FUNC_DEPRECATED([daemon], [(void)daemon(0, 0);], [ #include ]) fi AC_CHECK_FUNCS([strftime localtime_r fcntl setsid sleep usleep random srandom recvmsg sendmsg writev chflags]) AC_REPLACE_FUNCS(inet_pton) AC_REPLACE_FUNCS(inet_ntop) AC_REPLACE_FUNCS(snprintf) AC_REPLACE_FUNCS(strlcpy) AC_REPLACE_FUNCS(memmove) hooks="auto" AC_ARG_WITH([hooks], AC_HELP_STRING([--with-hooks], [Set the DHCP change hooks to use, default 'auto', can be 'osx', 'networkmanager', 'netconfig', 'windows' or 'none']),, withval="") if test -n "$withval"; then hooks="$withval" fi # hook settings networkmanager_dispatcher_dir="$sysconfdir/NetworkManager/dispatcher.d" AC_ARG_WITH([networkmanager-dispatch], AC_HELP_STRING([--with-networkmanager-dispatch], [Set the networkmanager dhcp dispatcher dir, default tests prefix/etc/NetworkManager/dispatcher.d and /etc/NetworkManager/dispatcher.d]), , withval="") with_nm_dispatch="$withval" AC_SUBST(networkmanager_dispatcher_dir) netconfig_dispatcher_dir="$sysconfdir/netconfig.d" AC_ARG_WITH([netconfig-dispatch], AC_HELP_STRING([--with-netconfig-dispatch], [Set the netconfig dhcp dispatcher dir, default tests prefix/etc/netconfig.d and /etc/netconfig.d]), , withval="") with_netconfig_dispatch="$withval" AC_SUBST(netconfig_dispatcher_dir) AC_MSG_CHECKING([for DHCP hooks]) if test "$hooks" != "auto"; then : else if test "$on_mingw" = "yes"; then hooks="windows" else if test -x "`which nmcli 2>&1`" -o -x "`which nm-tool 2>&1`"; then hooks="networkmanager" else if test "`uname`" = "Darwin"; then hooks="osx" else if test -x /sbin/netconfig; then hooks="netconfig" else hooks="none" fi fi fi fi fi AC_MSG_RESULT([$hooks]) AC_SUBST(hooks) if test "$hooks" = "networkmanager"; then AC_MSG_CHECKING([for NetworkManager dispatch]) if test "$with_nm_dispatch" != ""; then networkmanager_dispatcher_dir="$with_nm_dispatch" else if test -d "$networkmanager_dispatcher_dir" ; then : else if test -d /etc/NetworkManager/dispatcher.d; then networkmanager_dispatcher_dir="/etc/NetworkManager/dispatcher.d" fi fi fi AC_MSG_RESULT([$networkmanager_dispatcher_dir]) fi if test "$hooks" = "netconfig"; then AC_MSG_CHECKING([for netconfig.d]) if test "$with_netconfig_dispatch" != ""; then netconfig_dispatcher_dir="$with_netconfig_dispatch" else if test -d "$netconfig_dispatcher_dir" ; then : else if test -d /etc/netconfig.d; then netconfig_dispatcher_dir="/etc/netconfig.d" fi fi fi AC_MSG_RESULT([$netconfig_dispatcher_dir]) fi if test "$hooks" = "osx"; then AC_DEFINE([HOOKS_OSX], 1, [we are on OSX, use that os specific funcs]) fi if test "$hooks" = "none"; then AC_MSG_WARN([have no DHCP hooks, cannot detect network changes]) fi gui="auto" AC_ARG_WITH([gui], AC_HELP_STRING([--with-gui], [Set the user interface style to use, default 'auto', can be 'cocoa' (on OSX), 'windows' or 'gtk']),, withval="") if test -n "$withval" -a "$withval" != "yes"; then gui="$withval" fi AC_MSG_CHECKING([for gui]) if test "$gui" != "auto"; then : else if test "`uname`" = "Darwin"; then gui="cocoa" else if test "$on_mingw" = yes; then gui="windows" else gui="gtk" fi fi fi AC_MSG_RESULT([$gui]) AC_SUBST(gui) if test "$gui" = "gtk"; then # GTK GTK_CFLAGS=`pkg-config --cflags gtk+-2.0` GTK_LIBS=`pkg-config --libs gtk+-2.0` if test -z "$GTK_LIBS"; then AC_MSG_ERROR([No gtk+-2.0 detected, please install glib-dev, gtk2-dev]) fi AC_SUBST(GTK_CFLAGS) AC_SUBST(GTK_LIBS) AC_MSG_CHECKING([for libappindicator]) AC_ARG_ENABLE(appindicator, AS_HELP_STRING([--enable-appindicator[=@<:@no/auto/yes@:>@]],[Build support for application indicators (for Ubuntu Unity)]), [enable_appindicator=$enableval], [enable_appindicator="auto"]) if test x$enable_appindicator = xauto ; then if pkg-config --exists appindicator-0.1; then enable_appindicator="yes" else enable_appindicator="no" fi fi if test x$enable_appindicator = xyes ; then # replace since GTK is included in the appindicator flags GTK_CFLAGS=`pkg-config --cflags appindicator-0.1` GTK_LIBS=`pkg-config --libs appindicator-0.1` if test -z "$GTK_LIBS"; then AC_MSG_ERROR([appindicator-0.1 is not installed, need libappindicator-dev]) fi AC_DEFINE(HAVE_APP_INDICATOR, 1, [Have AppIndicator (Ubuntu Unity)]) APP_INDICATOR="yes" AC_SUBST(APP_INDICATOR) AC_MSG_RESULT([yes]) BAKLIBS="$LIBS" LIBS="$LIBS $GTK_LIBS" AC_CHECK_FUNCS([app_indicator_set_icon_full]) LIBS="$BAKLIBS" else AC_MSG_RESULT([no]) fi # check for missing -lgthread-2.0 in the GTK_LIBS string. case "$GTK_LIBS" in *-lgthread* ) ;; *) AC_CHECK_LIB(gthread-2.0, g_thread_init, [GTK_LIBS="$GTK_LIBS -lgthread-2.0"]) esac if test "$on_mingw" = "no"; then xdg_autostart_dir="$sysconfdir/xdg/autostart" AC_ARG_WITH([xdg-autostart], AC_HELP_STRING([--with-xdg-autostart], [Set the GNOME autostart dir, default tests prefix/etc/xdg/autostart and /etc/xdg/autostart]), , withval="") with_xdg_autostart="$withval" AC_SUBST(xdg_autostart_dir) AC_MSG_CHECKING([for autostart dir]) if test "$with_xdg_autostart" != ""; then xdg_autostart_dir="$with_xdg_autostart" else if test -d "$xdg_autostart_dir" ; then : else if test -d /etc/xdg/autostart; then xdg_autostart_dir="/etc/xdg/autostart" fi fi fi AC_MSG_RESULT([$xdg_autostart_dir]) fi fi login_command="auto" login_location="auto" AC_SUBST(login_command) AC_SUBST(login_location) AC_ARG_WITH([login-command], AC_HELP_STRING([--with-login-command], [Set the command to start login, a web browser, default 'auto']),, withval="") if test -n "$withval" -a "$withval" != "yes"; then login_command="$withval" fi AC_ARG_WITH([login-location], AC_HELP_STRING([--with-login-location], [Set the url location to login, default 'auto']),, withval="") if test -n "$withval" -a "$withval" != "yes"; then login_location="$withval" fi if test "$login_location" = "auto"; then login_location="http://www.nlnetlabs.nl/projects/dnssec-trigger" fi AC_MSG_CHECKING([for web browser]) if test "$login_command" = "auto"; then if test "$USE_WINSOCK" = 1; then login_command="open" else if test "`uname`" = "Darwin"; then login_command="open" else clist="xdg-open sensible-browser gnome-open x-www-browser firefox konqueror chrome google-chrome" login_command="" for i in $clist; do if test -x "`which $i 2>&1`"; then login_command="$i" break; fi done fi fi fi AC_MSG_RESULT([$login_command]) AC_DEFINE_UNQUOTED([LOGIN_COMMAND], ["$login_command"], [web browser to open login url]) AC_DEFINE_UNQUOTED([LOGIN_LOCATION], ["$login_location"], [login url to open at hot spots]) AC_ARG_WITH([check-updates], AC_HELP_STRING([--with-check-updates=yesno], [Set default value for check-updates config option]),, withval="") if test -n "$withval"; then check_updates="$withval" else # enable on WIN, OSX, not on unixes (use ports, package manager there). if test "$USE_WINSOCK" = 1; then check_updates="yes" else if test "`uname`" = "Darwin"; then check_updates="yes" else check_updates="no" fi fi fi AC_DEFINE_UNQUOTED([CHECK_UPDATES], ["$check_updates"], [default value for check-updates config option]) AC_SUBST(check_updates) AC_ARG_WITH([keydir], AC_HELP_STRING([--with-keydir=path], [Set the directory where ssl key files are kept, read by daemon and other tools, default prefix/etc]),, withval="") keydir=`eval echo "$sysconfdir"` if test -n "$withval"; then keydir="$withval" fi ACX_ESCAPE_BACKSLASH($keydir, keydir_esc) AC_DEFINE_UNQUOTED([KEYDIR], ["$keydir_esc"], [directory with ssl key files for dnssec-trigger]) AC_SUBST(keydir) libexec_store_dir=`eval echo "$libexecdir"` ACX_ESCAPE_BACKSLASH($libexec_store_dir, libexec_store_dir_esc) AC_DEFINE_UNQUOTED([LIBEXEC_DIR], ["$libexec_store_dir_esc"], [directory with scripts for dnssec-trigger]) AC_ARG_WITH([uidir], AC_HELP_STRING([--with-uidir=path], [Set the directory where ui files (icon,xml) are kept, default prefix/share/dnssec-trigger]),, withval="") uidir=`eval echo "$datadir/dnssec-trigger"` if test -n "$withval"; then uidir="$withval" fi ACX_ESCAPE_BACKSLASH($uidir, uidir2) uidir=`eval echo $uidir2` ACX_ESCAPE_BACKSLASH($uidir, uidir_esc) AC_DEFINE_UNQUOTED([UIDIR], ["$uidir_esc"], [directory with UI xml and png for dnssec-trigger]) AC_SUBST(uidir) AC_ARG_WITH([configfile], AC_HELP_STRING([--with-configfile=path], [set the configfile to use, default keydir/dnssec-trigger.conf]),, withval="") configfile="$keydir/dnssec-trigger.conf" if test -n "$withval"; then configfile="$withval" fi ACX_ESCAPE_BACKSLASH($configfile, configfile_esc) AC_DEFINE_UNQUOTED([CONFIGFILE], ["$configfile_esc"], [default config file name for dnssec-trigger]) AC_SUBST(configfile) AC_ARG_WITH([pidfile], AC_HELP_STRING([--with-pidfile=path], [set the pidfile to use, default /var/run/dnssec-trigger.pid]),, withval="") pidfile="/var/run/dnssec-trigger.pid" if test -n "$withval"; then pidfile="$withval" fi ACX_ESCAPE_BACKSLASH($pidfile, pidfile_esc) AC_DEFINE_UNQUOTED([PIDFILE], ["$pidfile_esc"], [default pidfile name for dnssec-trigger]) AC_SUBST(pidfile) AC_ARG_WITH([python], AC_HELP_STRING([--with-python=path], [set the path to Python interpreter to use for Python scripts, defaults /usr/bin/python]),, withval="") PYTHON="/usr/bin/python" if test -n "$withval"; then PYTHON="$withval" fi ACX_ESCAPE_BACKSLASH($PYTHON, python_esc) AC_DEFINE_UNQUOTED([PYTHON], ["$python_esc"], [default Python interpreter path for all Python scripts]) AC_SUBST(PYTHON) AC_ARG_WITH([unbound-control], AC_HELP_STRING([--with-unbound-control=path], [set the unbound-control to use, default what configure finds in its path]),, withval="") AC_MSG_CHECKING([for unbound-control]) if test "$on_mingw" = "yes"; then unbound_control_path='"C:\Program Files\Unbound\unbound-control.exe"' else unbound_control_path="`which unbound-control 2>&1`" fi if test -n "$withval"; then unbound_control_path="$withval" fi if test "$on_mingw" = "yes" -o -n "$withval"; then AC_MSG_RESULT($unbound_control_path) else if test -x "$unbound_control_path"; then AC_MSG_RESULT($unbound_control_path) else AC_MSG_RESULT([not found: try "unbound-control" in runtime PATH]) unbound_control_path="unbound-control" fi fi ACX_ESCAPE_BACKSLASH($unbound_control_path, unbound_control_esc) unbound_control_esc="`echo $unbound_control_esc | sed -e 's/\\"/\\\\"/g'`" AC_DEFINE_UNQUOTED([UNBOUND_CONTROL], ["$unbound_control_esc"], [unbound-control to call]) AC_SUBST(unbound_control_path) LDNSLIBS="" AC_ARG_WITH(ldns, AC_HELP_STRING([--with-ldns=PATH], [specify prefix of path of ldns library to use]), [ CPPFLAGS="-I$withval/include $CPPFLAGS" LDFLAGS="-L$withval -L$withval/lib $LDFLAGS" ldnsdir="$withval" if test "$staticexe" = "yes"; then LDNSLIBS="$ldnsdir/lib/libldns.a" else LDNSLIBS="-lldns" ACX_RUNTIME_PATH_ADD([$withval/lib]) fi AC_SUBST(ldnsdir) AC_SUBST(LDNSLIBS) ], [ AC_CHECK_LIB(ldns, ldns_buffer_new,,[AC_MSG_ERROR([please install ldns-devel])]) ]) # add option to disable the evil rpath ACX_ARG_RPATH AC_SUBST(RUNTIME_PATH) AC_DEFINE_UNQUOTED([MAXSYSLOGMSGLEN], [10240], [Define to the maximum message length to pass to syslog.]) AC_DEFINE_UNQUOTED([DNS_PORT], [53], [DNS port number]) AH_BOTTOM([ #ifndef DO_DEBUG # define NDEBUG #endif #include #include #include #include #if STDC_HEADERS #include #include #endif #ifdef HAVE_STDINT_H #include #endif #include #if HAVE_SYS_PARAM_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_SYS_UIO_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_ARPA_INET_H #include #endif #ifdef HAVE_WINSOCK2_H #include #endif #ifdef HAVE_WS2TCPIP_H #include #endif #ifdef HAVE_GETOPT_H #include #endif #ifdef HAVE_OPENSSL_ERR_H #include #endif #ifdef HAVE_OPENSSL_RAND_H #include #endif #ifdef HAVE_OPENSSL_SSL_H #include #endif #ifdef HAVE_ATTR_FORMAT # define ATTR_FORMAT(archetype, string_index, first_to_check) \ __attribute__ ((format (archetype, string_index, first_to_check))) #else /* !HAVE_ATTR_FORMAT */ # define ATTR_FORMAT(archetype, string_index, first_to_check) /* empty */ #endif /* !HAVE_ATTR_FORMAT */ #if defined(DOXYGEN) # define ATTR_UNUSED(x) x #elif defined(__cplusplus) # define ATTR_UNUSED(x) #elif defined(HAVE_ATTR_UNUSED) # define ATTR_UNUSED(x) x __attribute__((unused)) #else /* !HAVE_ATTR_UNUSED */ # define ATTR_UNUSED(x) x #endif /* !HAVE_ATTR_UNUSED */ #ifndef HAVE_FSEEKO #define fseeko fseek #define ftello ftell #endif /* HAVE_FSEEKO */ #if defined(HAVE_EVENT_H) && !defined(HAVE_EVENT_BASE_ONCE) && (defined(HAVE_PTHREAD) || defined(HAVE_SOLARIS_THREADS)) /* using version of libevent that is not threadsafe. */ # define LIBEVENT_SIGNAL_PROBLEM 1 #endif #ifndef RAND_MAX #define RAND_MAX 2147483647 #endif #ifndef CHECKED_INET6 # define CHECKED_INET6 # ifdef AF_INET6 # define INET6 # else # define AF_INET6 28 # endif #endif /* CHECKED_INET6 */ #ifndef HAVE_GETADDRINFO struct sockaddr_storage; #include "compat/fake-rfc2553.h" #endif ] AHX_CONFIG_INET_PTON(dnssectrigger) AHX_CONFIG_INET_NTOP(dnssectrigger) AHX_CONFIG_MEMMOVE(dnssectrigger) AHX_CONFIG_STRLCPY(dnssectrigger) AHX_CONFIG_SNPRINTF(dnssectrigger) AHX_CONFIG_W32_SLEEP AHX_CONFIG_W32_USLEEP AHX_CONFIG_W32_RANDOM AHX_CONFIG_W32_SRANDOM AHX_CONFIG_W32_FD_SET_T ) DATE=`date +%x` AC_SUBST(DATE) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([Makefile]) AC_OUTPUT if test "$hooks" = "none"; then echo "WARNING NO DHCP HOOKS DETECTED CANNOT SETUP TRIGGER" fi [ echo "configure completed with $hooks hooks and $gui gui, now you can" echo " make | make all : compile the code" echo " make install : install files" echo " make uninstall : uninstall files" ] dnssec-trigger-0.13/dnssec-trigger.8.in0000664000175000017500000002760213024457644017451 0ustar wouterwouter.TH "dnssec-trigger" "8" "2016-11-28" "NLnet Labs" "dnssec-trigger @VERSION@" .\" .\" dnssec-trigger.8 -- dnssec trigger manual .\" .\" Copyright (c) 2011, NLnet Labs. All rights reserved. .\" .\" See LICENSE for the license. .\" .\" .SH "NAME" .LP .B dnssec-trigger, .B dnssec-triggerd, .B dnssec-trigger-panel, .B dnssec-trigger-control, .B dnssec-trigger-control-setup, .B dnssec-trigger.conf \- check DNS servers for DNSSEC support and adjust to compensate. .SH "SYNOPSIS" .LP .B dnssec-triggerd .RB [ \-d ] .RB [ \-v ] .RB [ \-u ] .RB [ \-c .IR file ] .LP .B dnssec-trigger-control .RB [ \-c .IR file ] .RB [ \-s ip[@port] ] command [arguments] .LP .B dnssec-trigger-panel .RB [ \-d ] .RB [ \-c .IR file ] .SH "DESCRIPTION" .LP The \fBdnssec\-trigger\fR programs steer \fIunbound\fR(8) towards DNSSEC capable DNS servers. A DHCP hook installed on the system calls \fBdnssec\-trigger\-control\fR that contacts the daemon \fBdnssec\-triggerd\fR that probes the list of servers. The daemon then adjusts a running unbound through \fIunbound\-control\fR(8) and notifies the user applet \fBdnssec\-trigger\-panel\fR for GUI display. .P The \fBdnssec\-trigger\-panel\fR runs after user login, displays notifications and status to the user. It may popup a warning if no DNSSEC capable servers are available, with options to disconnect or to connect insecurely. .P The \fBdnssec\-trigger\-control\fR tool is used in the background by scripts to notify the daemon of new (DHCP) DNS servers. It can be used to test the system by providing a (fake) list of DNS server IP addresses. .P The \fBdnssec\-trigger\-control\-setup\fR tool is used to setup the SSL keys that the daemon and user panel use to communicate securely. It must be run once after installation. .SH "THE DNSSEC\-TRIGGERD DAEMON" .LP Thus the dnssec\-triggerd daemon runs continually, and is started after boot. It receives a list of IP addresses, probes them, and adjusts unbound and resolv.conf. Unbound acts as the validating local resolver, running on 127.0.0.1. And resolv.conf is modified to point to 127.0.0.1. .TP .B \-c\fI cfgfile Set the config file with settings for the dnssec\-triggerd to read instead of reading the file at the default location, \fI@configfile@\fR. The syntax is described below. .TP .B \-d Debug flag, do not fork into the background, but stay attached to the console. .TP .B \-u uninstall dns override: makes resolv.conf mutable again, or other OS action. .TP .B \-v Increase verbosity. If given multiple times, more information is logged. This is in addition to the verbosity (if any) from the config file. .SH "THE DNSSEC\-TRIGGER.CONF FILE" .LP The config file contains options. It is fairly simple, key: value. You can make comments with '#' and have empty lines. The parser is simple and expects one statement per line. .TP .B verbosity: \fR Amount of logging, 1 is default. 0 is only errors, 2 is more detail, 4 for debug. .TP .B pidfile: \fR"" The filename where the pid of the dnssec\-triggerd is stored. Default is @pidfile@. .TP .B logfile: \fR"" Log to a file instead of syslog, default is to syslog. .TP .B use\-syslog: \fR Log to syslog, default is yes. Set to no logs to stderr (if no logfile) or the configured logfile. .TP .B unbound\-control: \fR"" The string gives the command to execute. It can be "unbound\-control" to search the runtime PATH, or a full pathname. With a space after the command arguments can be configured to the command, i.e. "/usr/local/bin/unbound\-control \-c my.conf". .TP .B resolvconf: \fR"/etc/resolv.conf" The resolv.conf file to edit (on posix systems). The daemon keeps the file readonly and only make it writable shortly to change it itself. This is to keep other software from interfering. On OSX (if compiled in) also the DNS settings are changed in the network configuration machinery (visible in the network settings control panel). On Windows (if compiled), it sets registry settings for network configuration (may be visible in the control panel tab for network devices) and does not write a resolv.conf file. .TP .B domain: \fR"example.com" The domain to set in resolv.conf. See \fIresolv.conf\fR(5). Picked up once during installation, and not from DHCP since it allows directing traffic elsewhere. .TP .B search: \fR"example.com" The domain name search path to set in resolv.conf. See \fIresolv.conf\fR(5). Picked up once during installation, and not from DHCP since it allows directing traffic elsewhere. .TP .B noaction: \fR Default is no. If yes, no action is taken to change unbound\-control or resolv.conf. The software can be tested with this, probe results are available. .TP .B port: \fR<8955> Port number to use for communication with dnssec\-triggerd. Communication uses 127.0.0.1 (the loopback interface). SSL is used to secure it, and the keys are stored on the disk (see below). The other tools read this config file to find the port number and key locations. .TP .B login\-command: \fR"@login_command@" The command that is run when the user clicks Login on the no web access dialog. That is supposedly a web browser, that is aimed to open some url so that the hot-spot network login can intercept and show its login page. The default is a detected generic web browser. The "" empty string turns off this feature and no command gets run. .TP .B login\-location: \fR"@login_location@" The url that is opened with the web browser. Used as commandline argument. .TP .B server\-key\-file: \fR"@keydir@/dnssec_trigger_server.key" .TP .B server\-cert\-file: \fR"@keydir@/dnssec_trigger_server.pem" .TP .B control\-key\-file: \fR"@keydir@/dnssec_trigger_control.key" .TP .B control\-cert\-file: \fR"@keydir@/dnssec_trigger_control.pem" The files used for SSL secured communication with dnssec\-triggerd. These files can be created with dnssec\-trigger\-control\-setup (run as root). .TP .B check\-updates: \fR Check for software updates, if there are, download them and present the user with a dialog that allows them to run the installer to upgrade the software. It checks a SHA256 checksum on the download, the checksum is signed with DNSSEC (from a TXT record). On windows and osx the default is yes. On other systems the default is no (it'll download the source tarball if enabled). .TP .B url: \fR"http://example.com OK" This command adds an url to probe via HTTP (port 80). The first word, before the space is the url to resolve. The remainder is the string that is expected as page contents (that may be prefixed or suffixed with whitespace). The url is resolved, a HTTP 1.1 query is sent. The reply must be type 2xx and contain the page contents. If this is not true, dnssec-trigger knows that there is a 'hot spot' of some sort interfering with traffic. If you do not configure any urls, then no probes are done. If you configure multiple urls then it probes a random selection of 3 urls, all of their IP addresses in turn, with IP4 and IP6 simultaneously. At most 5 of the DHCP DNS servers are used to resolve (in parallel). If an answer is gotten and it fails the probe stop, the probing continues if there is no connection or response 404. .TP .B tcp80: \fR Add an IP4 or IP6 address to the list of fallback open DNSSEC resolvers that are used on TCP port 80. These relay traffic from port 80 to regular DNS. .TP .B tcp443: \fR Add an IP4 or IP6 address to the list of fallback open DNSSEC resolvers that are used on TCP port 443. These relay traffic from port 443 to regular DNS. .TP .B tcp443: \fR or { } Add an IP4 of IP6 address to the list of fallback SSL open DNSSEC resolvers. They serve plain-DNS(tcp-style) over port 443, encapsulated in SSL. The SSL certificate online is checked with the fingerprint (if configured here). You may configure multiple hashes (one space between), if one matches its OK, so that pre\-publish rollover of the certificates is possible. .SH "THE DNSSEC\-TRIGGER\-PANEL" The dnssec\-trigger\-panel is an applet that runs in the tray. It shows the DNSSEC status. It can be invoked with \-d to test in the build directory. The \-c \fIcfgfile\fR option can set the config file away from the default. The applet keeps an SSL connection to the daemon and displays the status, and can show the user dialogs. .P The applet has a small menu. The menu item \fBReprobe\fR causes the daemon to probe the last seen DHCP DNS servers again, which may now work after a hotspot signon. The menu item \fBHotspot Signon\fR goes into insecure mode for hotspots where this must be used to sign on to the hot spot: use reprobe when done to resume dnssec protection efforts. The \fBProbe Result\fR menu item shows the results of the previous probe to the user, for technical help with network difficulties. .SH "THE DNSSEC\-TRIGGER\-CONTROL TOOL" The dnssec\-trigger\-control tool can be used to test. It is also used inside DHCP scripts (platform specific). It can send commands to the daemon. .PP Options: .TP .B \-c \fIcfgfile Set the config file to use away from the default. .TP .B \-s \fIip[@port] Default connects to 127.0.0.1 with the port from config file, but this options overrides that with an IPv4 or IPv6 address and optional a port. .TP .B \-v increase verbosity of dnssec\-trigger\-control. .PP Commands: .TP .B submit \fR Submit a list of space separated IP addresses (from DHCP) that are the DNS servers that the daemon will probe. IPv4 and IPv6 addresses can be used. .TP .B unsafe Test command that probes some 127/8 addresses in a way that makes the daemon conclude that no DNSSEC works. Presents user with 'Insecure?' dialog. .TP .B status Shows the last probe results. .TP .B reprobe Probe the last probe again. It also cancels forced insecure state from hotspot signon, causing probes for dnssec to resume. This command acts as the menu item with the same name. .TP .B skip_http Skip the http probe step. Setup DNSSEC, as possible, without taking the result of the http probe into account. Once http works again, it'll stop skipping the http results. Useful, if you want to have DNSSEC on a network where web access is not possible. .TP .B hotspot_signon This command acts as the menu item with the same name. Use it to force insecure mode, where you can then interact with (weird) hotspot set ups. When you are done, do the reprobe command to resume DNSSEC protection efforts. .TP .B results continuous feed of probe results. .TP .B cmdtray Continuous input feed, used by the tray icon to send commands to the daemon. .TP .B stoppanels Makes connected tray icons quit. Useful for installers that need to update their executable. .TP .B stop stops the daemon. .SH "THE DNSSEC\-TRIGGER\-CONTROL\-SETUP TOOL" This tool aids setup of files. Without arguments it creates the key files. If key files already exist, it resigns certificates with existing private keys. With \fB\-d\fR \fIdir\fR the files are placed in the given directory. .PP With \fB\-i\fR the tool changes configuration files. It tests if unbound has \fBremote\-control\fR: \fBcontrol\-enable:\fR \fIyes\fR and if not appends lines to unbound.conf that enable unbound\-control, and it runs unbound\-control\-setup to generate the keys for unbound\-control. It tests if unbound has a trust anchor, if not it enables the root.key as \fBauto\-trust\-anchor\-file\fR and runs \fIunbound\-anchor\fR(8) to initialize the key. It picks up the domain and search from resolv.conf and configures the dnssec\-trigger.conf to use that. .PP Note the tool trusts the domain and search path at install time. You should review them or perform configuration manually. .PP With \fB\-u\fR it removes the options it enabled in \fIunbound.conf\fR(5). .SH "FILES" .TP .I @configfile@ The default configuration file. .TP .I @keydir@ Directory with keys used for SSL connections to dnssec\-triggerd. .TP .I @pidfile@ Default pidfile with the pid of the running dnssec\-triggerd. .SH "SEE ALSO" \fIunbound\fR(8), \fIunbound\-control\fR(8), \fIunbound.conf\fR(5), \fIresolv.conf\fR(5). .SH "AUTHORS" This program was developed by Wouter Wijngaards at NLnet Labs. dnssec-trigger-0.13/contrib/0000775000175000017500000000000013024457644015464 5ustar wouterwouterdnssec-trigger-0.13/contrib/README0000664000175000017500000000065212313052531016331 0ustar wouterwouterThese files are contributed to dnssec-trigger, and are not part of the official distribution but may be helpful. * dnssec-trigger-script: A python script that reconfigures /etc/resolv.conf, dnssec-trigger and unbound. * dnssec.conf.sample: A sample /etc/dnssec.conf file used by dnssec-trigger-script. * 01-dnssec-trigger: A minimalistic NetworkManager dispatcher.d shell script that calls dnssec-trigger-script --update. dnssec-trigger-0.13/panel/0000775000175000017500000000000013024457644015123 5ustar wouterwouterdnssec-trigger-0.13/panel/dmg-icon.png0000664000175000017500000001230611652264625017330 0ustar wouterwouterPNG  IHDR@@iqsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<CIDATx[i]uNwffF 0qal2vY(;'r*!qJE;6 4I:#iE'?{0MTn{|} Q7Q7ࣆ،DT`@@3/W>,ЅA"pu}YfwZx1cs`_̿pmU>'\hϜ:v|f+ˆi "WXV?P3?!`m?OL;z@?/0sׇ Ec&|g+j7HS \lò}>?}/{t#0)g"g+ABɣpw8yػ[yh_hW$G-]YϚ:y8E'O$8 $/~nM" D^"ѦA)14HDWXVV\(rfPOG9yZx :+DfK^P'URpCypQ*L{/y0 oƍ6nx^=z+(.C ervSޟGJGU 3?rr h oΠ]&} @(h17U t(4~iXW0\.i;CRJ4TTa* 0v= |̦^RD da΋\|@$X>^x03#8 !̜f0-YͿ6hm{w3iy,`CO\Iavw^,Dԋ"Z.t9!D4w WpݪkRĬ!DyEBs}{FAJ Ӳa6xuZ)Im_t]Ȱr^oOwK߿+yt ^LDcyw0dBH4A`cmG[~ݛϥ=j&jZv4-HE]Uz?P3Fe\3T^e2k&i0BUf;+JTѽ;Z:6^"T/2sl|0ӾwLRCbcN fdlHU"Ӳ0p($1ZS>ݞEA"X^طED*cA\=w*O=2s]}-C%:=DEfN΄?=:PհXTmW :C !EYYyu6̷(EOD_;,VwQ쑖֚;6&}xWOErIolDe J):YtwuIf E(+W-^X!侾>n0DbtU" vώ)~9 ZQk`0 ~#ur鯏v"A{ͨiB;tww~lٲޛ2 cǎ[ZZg߉7-1Ds)v* "Hw!R)0%aF~ѢEeY6oo?׸䆐fy;xW8jr\HOآ>?K!#h0k(þ8۶9ziɃ A5fY`s!!5]7w2߹ngLQ?fc˾譱)7 #L9YQ! RQչmcOf1ٷvWhkD[kI[K6/J$Leh`fz׶m+O\*MФs%{t, gfgr/+D$ nTŦmR1{n].DSZL<ȴ &#q/9`I}5`eYkh8L'O "$D` &ֲ,!:::~!8dE"C)e,[ 6lKD"xG^;N"H$bd!L.sz0#DD_7n(^+$777e[bdҸsf"j݉¹" E"UV------FGG_&bزe mƉD)//mڴ)9o&`i0&wز8e syվw3d5w˩T*rT*8ߴl,e C3?>X-r:mZYkmH_hZƤ'#;Yaif3 K[o#˴`&L"ҎHT,&`~.Gz- `QHUDB3C֌Թ?6&Kap8<)`vx5Jf eda)!);`m"3PW_^!)|R&N@fG"$XQ**-(>7 !) R:iZti>/^L) oౣQ=+YIژEK^T V(̰P3t>/ADJ22}p< 'rgm ) ʐgfT]RݰlmPFC/++aaV njnnk׮ 0 .ف?`vd~i_GU/ivu>1'cBm DD*zɓQ4ş ;wL{渴I3Zh0 9Vǿ2v0 qNtRx|{ş<30AK ĺc6aa >ho .<E5ٹIENDB`dnssec-trigger-0.13/panel/dnssec-trigger-panel.desktop.in0000664000175000017500000000052612455230324023132 0ustar wouterwouter[Desktop Entry] Type=Application # note this is the version of the .desktop spec this file conforms to Version=1.0 Name=DNSSEC Trigger GenericName=Network Applet Comment=Shows DNS state and warning dialog Exec=dnssec-trigger-panel Icon=@uidir@/status-icon.png Terminal=false Categories=Utility; X-KDE-StartupNotify=false StartupNotify=false dnssec-trigger-0.13/panel/attach.h0000664000175000017500000001157212275162157016545 0ustar wouterwouter/* * attach.h - dnssec-trigger acttachment from panel to daemon. * * Copyright (c) 2011, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains the code that attaches the panel to the daemon. */ #ifndef ATTACH_H #define ATTACH_H struct feed; struct cfg; struct strlist; /** attachment structure for the results read thread */ extern struct feed* feed; /** * Alert arguments */ struct alert_arg { int last_insecure; int now_insecure; int now_dark; int now_cache; int now_auth; int now_disconn; int now_tcp; int now_ssl; int now_forced_insecure; int now_http_insecure; }; /** structure for reading from the daemon */ struct feed { /* routine that locks a mutex for this structure */ void (*lock)(void); /* routine that unlocks the mutex for this structure */ void (*unlock)(void); /* quit the program, when stop is sent by triggerd */ void (*quit)(void); /* alert function, new status information */ void (*alert)(struct alert_arg*); /* update_alert function, new software update info, must free * the passed (malloced) version string. */ void (*update_alert)(char*); /* if connection with the daemon has been established. */ int connected; /* non connection reason */ char connect_reason[512]; /* list of lines, last has status */ struct strlist* results, *results_last; /* if we are in insecure mode - here to see if it has changed */ int insecure_mode; /* list of lines for update status */ struct strlist* update, *update_last; /* config */ struct cfg* cfg; /* ssl context with keys */ SSL_CTX* ctx; /* ssl to read results from */ SSL* ssl_read; /* ssl to write results to */ SSL* ssl_write; }; /** create the feed structure and inits it * setups the global feed pointer. * Then you the caller must fill the function pointers in the struct * with proper callbacks. Then call attach_start from a fresh thread. */ void attach_create(void); /** delete feed structure. */ void attach_delete(void); /** start the connection thread */ void attach_start(struct cfg* cfg); /** stop attach */ void attach_stop(void); /** send insecure choice to the daemon */ void attach_send_insecure(int val); void attach_send_reprobe(void); void attach_send_hotspot_signon(void); void attach_send_skip_http(void); void attach_send_update_cancel(void); void attach_send_update_ok(void); /** get tooltip text from alert state (fixed string) */ const char* state_tooltip(struct alert_arg* a); /** * process state for new alert (at GUI side) * @param a: the alert state info. * @param unsafe_asked: 1 if user chose something in the unsafe dialog. * @param noweb_asked: 1 if user chose something in the noweb dialog. * @param danger: routine to show danger icon * @param safe: routine to show safe icon. * @param dialog: routine to show the insecure-question dialog. * @param noweb: routine to whot the noweb-login dialog. */ void process_state(struct alert_arg* a, int* unsafe_asked, int* noweb_asked, void (*danger)(void), void(*safe)(void), void(*dialog)(void), void (*noweb)(void)); /** * Fetch proberesults text. * @param buf: buffer for string. * @param len: length of buffer. * @param lf: line ending (string), e.g. "\n" */ void fetch_proberesults(char* buf, size_t len, const char* lf); /** * forkexec login command given cfg, where forkexec exists (unix) * Takes cfg item from feed global. logs errors to syslog. */ void run_login(void); #endif /* ATTACH_H */ dnssec-trigger-0.13/panel/status-icon-alert.png0000664000175000017500000001031711717264572021214 0ustar wouterwouterPNG  IHDR@@iqsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<LIDATxywu?wfvEuX$d6plC%1 !U(Ɖp Fх}v;=GH՞J ߪ{~*0hhhhXzsU5;S],tہc?h,hÂvv$dҹoQU/3I "}ѪzM﫟tU4. Hi@ HG^/&c~8gLEnlh ]h( /-%j4?Pcm>wNUա̹`B#("WU^YF0Ʊcs.-r:~E@{M y1d樫mg1M ۲0,iiYj[mh[>| }` wNO;Køy6")g;mtrYwաxC%Ǵ0M2x˝v0]WcizDT8YL±ɮ>r05ݶPG{xqM_APW_H5eL |mYlۦԱ<;Od|y'{ƶ8aF(6LPN4 DrYl[tC@eᆎ)'o't,ʪ ya"v޸eq, ,)I@o( G-;{PiZV=&@v.JU%TPfJ;l:WаJ?Xg9-cc96c^Zln/iX*]8Yʈ.s+9Q).E- 6,Xx]r<;ylώ/O]H7nU51$ ;{k/* XubxUP:|*K|tT</[Zlmqi0 $[%%•G2rӝh+wo:,+^ M]G[lnEUU` U[tϿ7vY5ga7|~?nΙ&(9͛zjμ>XuM3DV%޹ ]'!kه ?}8_57IpND[ۃe Hw<:⺊!.9p]f]򯇻ێe6?~ðqy)鰋xTU=xP"y- 7 и*"='GŪ9e_®lh޻; ڪowǷNiHa}+bg3h~$"~`0=x3I\zx4HgRlV3WIƆ :VDCFUjxÅmϦ3" UҟB26XYd`P$;S57%+G<Fý6^9 S" MUm_ [6 n \ZjS|5^ȧU[~ zvfv8k=TX?'̃븟|^>-\;BqG谷yڿ< cb*pEkf)"_U3 X_~z7mmrO7HefMrxw@g/i:50OmEUBWDt+gc li l&6 ˌT)i Lny7oY3g 5f$ZN8ZF8Zζg~tHr3{jf/4zyu دN'ω{&w/N)XUbm}dYJ"U\wx+Ck6uUϻOG;m2 b?\>cy]C݉1ՉDXo7& Vn[>\{+^|Q`Knt#"xeDh; Ӈ 4 K Մ1\U\uq]%9؝_vt*z`p`9=xu?6u . ^w RЀPG}_8߽i: ׆-K>ӼQc0_<Xpx$Zp[]cu6s9@k:a&W#ghun:'" _+0 ^6 =W>abSge쎾؃-{S2J̒@8XLHAU_s|* lock(); if(feed->ssl_read) { stop_ssl(feed->ssl_read, SSL_get_fd(feed->ssl_read)); feed->ssl_read = NULL; } if(feed->ssl_write) { stop_ssl(feed->ssl_write, SSL_get_fd(feed->ssl_write)); feed->ssl_write = NULL; } feed->unlock(); } /* keep trying to open the read channel, blocking */ static SSL* try_contact_server() { const char* svr = "127.0.0.1"; SSL* ssl = NULL; while(!ssl) { int fd = -1; while(fd == -1) { fd = contact_server(svr, feed->cfg->control_port, 0, feed->connect_reason, sizeof(feed->connect_reason)); if(fd == -1 || fd == -2) { feed->unlock(); sleep(1); feed->lock(); } } ssl = setup_ssl_client(feed->ctx, fd, feed->connect_reason, sizeof(feed->connect_reason)); if(!ssl) { stop_ssl(ssl, fd); feed->unlock(); sleep(1); feed->lock(); } } return ssl; } /* write the first command over SSL, blocking */ static void write_firstcmd(SSL* ssl, char* cmd) { char pre[10]; if(!ssl) return; snprintf(pre, sizeof(pre), "DNSTRIG%d ", CONTROL_VERSION); if(SSL_write(ssl, pre, (int)strlen(pre)) <= 0) fatal_exit("could not SSL_write"); if(SSL_write(ssl, cmd, (int)strlen(cmd)) <= 0) fatal_exit("could not SSL_write"); } void attach_start(struct cfg* cfg) { feed->lock(); snprintf(feed->connect_reason, sizeof(feed->connect_reason), "connecting to probe daemon"); feed->cfg = cfg; feed->ctx = cfg_setup_ctx_client(cfg, feed->connect_reason, sizeof(feed->connect_reason)); if(!feed->ctx) { fatal_exit("cannot setup ssl context: %s", feed->connect_reason); } feed->ssl_read = try_contact_server(); feed->ssl_write = try_contact_server(); if(verbosity>2) printf("contacted server\n"); write_firstcmd(feed->ssl_write, "cmdtray\n"); write_firstcmd(feed->ssl_read, "results\n"); if(verbosity>2) printf("contacted server, first cmds written\n"); feed->connected = 1; feed->unlock(); /* mainloop */ attach_main(); } static int check_for_event(void) { int fd; fd_set r; feed->lock(); if(!feed->ssl_read) { feed->unlock(); return 0; } if(SSL_pending(feed->ssl_read) != 0) { feed->unlock(); return 1; } fd = SSL_get_fd(feed->ssl_read); feed->unlock(); /* select on it */ while(1) { FD_ZERO(&r); FD_SET(FD_SET_T fd, &r); if(select(fd+1, &r, NULL, NULL, NULL) < 0) { if(errno == EAGAIN || errno == EINTR) continue; else break; } return 1; } return 0; } static int read_an_ssl_line(SSL* ssl, char* line, size_t len) { size_t i = 0; while(SSL_read(ssl, line+i, 1) > 0) { if(line[i] == '\n') { line[i]=0; return 1; } if(++i >= len) { log_err("line too long"); return 0; } } /* error */ if(ERR_get_error() != 0) log_err("failed SSL_read"); return 0; } /** * Read data from feed and return indication what to do * 0: stop. lock is unlocked for exit. * 1: nothing. caller unlocks lock. * 2: new probe results. caller unlocks lock. * 3: new softwareupdate. caller unlocks lock. */ static int read_from_feed(void) { struct strlist* first=NULL, *last=NULL; char line[1024]; if(verbosity > 2) printf("read from feed\n"); while(read_an_ssl_line(feed->ssl_read, line, sizeof(line))) { /* stop at empty line */ if(verbosity > 2) printf("feed: %s\n", line); if(!first && strcmp(line, "") == 0) { /* skip empty lines at start */ continue; } if(!first && strcmp(line, "stop") == 0) { strlist_delete(first); feed->unlock(); feed->quit(); return 0; } if(line[0] == 0) { if(!first) return 1; /* robust */ if(strncmp(first->str, "at ", 3) == 0) { if(verbosity >2) printf("got results\n"); strlist_delete(feed->results); feed->results = first; feed->results_last = last; return 2; } else if(strncmp(first->str, "update ", 7) == 0) { if(verbosity >2) printf("got update\n"); strlist_delete(feed->update); feed->update = first; feed->update_last = last; return 3; } if(verbosity >2) printf("got unknown\n"); strlist_delete(first); return 1; /* robust */ } strlist_append(&first, &last, line); } feed->connected = 0; stop_ssl(feed->ssl_read, SSL_get_fd(feed->ssl_read)); feed->ssl_read = NULL; /* for quit in meantime */ feed->ssl_read = try_contact_server(); write_firstcmd(feed->ssl_read, "results\n"); feed->connected = 1; return 1; } static void process_update(void) { char* s; /* fetch data */ feed->lock(); if(!feed->connected) { feed->unlock(); return; } if(!feed->update_last) { feed->unlock(); return; } s = strdup(feed->update_last->str); feed->unlock(); if(s) { if(feed->update_alert) feed->update_alert(s); else free(s); } } static void process_results(void) { char* s; struct alert_arg a; memset(&a, 0, sizeof(a)); /* fetch data */ feed->lock(); if(!feed->connected) { feed->unlock(); return; } if(!feed->results_last) { feed->unlock(); return; } s = feed->results_last->str; a.now_insecure = (strstr(s, "insecure_mode")!=NULL); a.now_http_insecure = (strstr(s, "http_insecure")!=NULL); a.now_forced_insecure = (strstr(s, "forced_insecure")!=NULL); a.now_dark = (strstr(s, "nodnssec")!=NULL); a.now_cache = (strstr(s, "cache")!=NULL); a.now_auth = (strstr(s, "auth")!=NULL); a.now_tcp = (strstr(s, "tcp")!=NULL); a.now_ssl = (strstr(s, "ssl")!=NULL); a.now_disconn = (strstr(s, "disconnected")!=NULL); a.last_insecure = feed->insecure_mode; feed->insecure_mode = a.now_insecure; feed->unlock(); feed->alert(&a); } static void attach_main(void) { /* check for event */ while(check_for_event()) { feed->lock(); if(!feed->ssl_read) { feed->unlock(); break; } switch(read_from_feed()) { case 0: /* already unlocked the lock */ return; default: case 1: feed->unlock(); break; case 2: feed->unlock(); process_results(); break; case 3: feed->unlock(); process_update(); break; } } } static void send_ssl_cmd(const char* cmd) { if(verbosity > 2) printf("sslcmd: %s\n", cmd); feed->lock(); if(feed->ssl_write) { if(SSL_write(feed->ssl_write, cmd, (int)strlen(cmd)) <= 0) { log_err("could not SSL_write"); /* reconnect and try again */ stop_ssl(feed->ssl_write, SSL_get_fd(feed->ssl_write)); feed->ssl_write = NULL; /* for quit in meantime */ feed->ssl_write = try_contact_server(); write_firstcmd(feed->ssl_write, "cmdtray\n"); (void)SSL_write(feed->ssl_write, cmd, (int)strlen(cmd)); } } feed->unlock(); } void attach_send_insecure(int val) { if(verbosity > 2) printf("insecure command %s\n", val?"yes":"no"); if(val) send_ssl_cmd("insecure yes\n"); else send_ssl_cmd("insecure no\n"); } void attach_send_reprobe(void) { send_ssl_cmd("reprobe\n"); } void attach_send_hotspot_signon(void) { send_ssl_cmd("hotspot_signon\n"); } void attach_send_skip_http(void) { send_ssl_cmd("skip_http\n"); } void attach_send_update_cancel(void) { send_ssl_cmd("update_cancel\n"); } void attach_send_update_ok(void) { send_ssl_cmd("update_ok\n"); } const char* state_tooltip(struct alert_arg* a) { if(a->now_forced_insecure) return "DNS DANGER (forced hotspot signon)"; else if(a->now_http_insecure && a->now_insecure) return "DNS DANGER (hotspot signon)"; else if(a->now_insecure) return "DNS DANGER"; else if(a->now_dark) return "DNS stopped"; else if(a->now_cache) return "DNSSEC via cache"; else if(a->now_tcp) return "DNSSEC via tcp relay resolver"; else if(a->now_ssl) return "DNSSEC via ssl relay resolver"; else if(a->now_disconn) return "network disconnected"; return "DNSSEC via authorities"; } void process_state(struct alert_arg* a, int* unsafe_asked, int* noweb_asked, void (*danger)(void), void(*safe)(void), void(*dialog)(void), void (*noweb)(void)) { /* if we are no longe unsafe, set asked to false to ask again * next time */ if(!a->now_dark) { *unsafe_asked = 0; *noweb_asked = 0; } if(!a->now_http_insecure) *noweb_asked = 0; if(!a->now_insecure) *unsafe_asked = 0; /* see what must be done */ if(!a->last_insecure && a->now_insecure) { danger(); } else if(a->last_insecure && !a->now_insecure) { safe(); } if(!a->now_insecure && a->now_dark && !*unsafe_asked && !a->now_forced_insecure && !a->now_http_insecure) { dialog(); } if(!a->now_insecure && a->now_dark && a->now_http_insecure && !a->now_forced_insecure && !*noweb_asked) { noweb(); } } void fetch_proberesults(char* buf, size_t len, const char* lf) { char* pos = buf; size_t left = len, n; struct strlist* p; buf[0] = 0; /* safe start */ buf[len-1] = 0; /* no buffer overflow */ snprintf(pos, left, "%s%sresults from probe ", PACKAGE_STRING, lf); n = strlen(pos); pos += n; left -= n; feed->lock(); p = feed->results; if(p && strncmp(p->str, "at ", 3) == 0) { snprintf(pos, left, "%s", p->str); n = strlen(pos); pos += n; left -= n; p=p->next; } snprintf(pos, left, "%s%s", lf, lf); n = strlen(pos); pos += n; left -= n; if(!feed->connected) { snprintf(pos, left, "error: %s%s", feed->connect_reason, lf); n = strlen(pos); pos += n; left -= n; snprintf(pos, left, "cannot connect to the dnssec-trigger service, DNSSEC%s" "status cannot be read.%s", lf, lf); n = strlen(pos); pos += n; left -= n; p = NULL; } /* indent for strings is adjusted to be able to judge line length */ for(; p; p=p->next) { if(!p->next) { /* last line */ snprintf(pos, left, "%s", lf); n = strlen(pos); pos += n; left -= n; if(strstr(p->str, "cache")) snprintf(pos, left, "DNSSEC results fetched from (DHCP) cache(s)%s", lf); else if(strstr(p->str, "auth")) snprintf(pos, left, "DNSSEC results fetched direct from authorities%s", lf); else if(strstr(p->str, "tcp")) snprintf(pos, left, "DNSSEC results fetched from relay resolvers over TCP%s", lf); else if(strstr(p->str, "ssl")) snprintf(pos, left, "DNSSEC results fetched from relay resolvers over SSL%s", lf); else if(strstr(p->str, "disconnected")) snprintf(pos, left, "The network seems to be disconnected. A local cache of DNS%s" "results is used, but no queries are made.%s", lf, lf); else if(strstr(p->str, "forced_insecure")) snprintf(pos, left, "DNS queries are being sent to INSECURE servers%s" "because Hotspot Sign-on mode was selected. Select%s" "Reprobe (from menu) after sign-on. A red exclamation%s" "mark in the icon warns you when DNSSEC is disabled.%s", lf, lf, lf, lf); else if(strstr(p->str, "http_insecure") && strstr(p->str, "insecure_mode")==NULL) snprintf(pos, left, "DNS queries are stopped until user confirmation.%s" "There is no web access, asking if user wants to do%s" "hotspot signon in insecure mode.%s", lf, lf, lf); else if(strstr(p->str, "http_insecure") && strstr(p->str, "insecure_mode")) snprintf(pos, left, "DNS queries are sent to INSECURE servers. There is%s" "no web access, perhaps you must do hotspot signon.%s" "Please, be careful out there.%s", lf, lf, lf); else if(strstr(p->str, "nodnssec") && !strstr(p->str, "insecure")) snprintf(pos, left, "A local cache of DNS results is used but no queries%s" "are made, because DNSSEC is intercepted on this network.%s" "(DNS is stopped)%s", lf, lf, lf); else snprintf(pos, left, "DNS queries are sent to INSECURE servers.%s" "Please, be careful out there.%s", lf, lf); n = strlen(pos); pos += n; left -= n; } else { snprintf(pos, left, "%s%s", p->str, lf); n = strlen(pos); pos += n; left -= n; } } feed->unlock(); } void run_login(void) { struct cfg* cfg = feed->cfg; #ifndef USE_WINSOCK pid_t p; #endif if(!cfg->login_command || !cfg->login_command[0]) return; /* disabled */ #ifndef USE_WINSOCK p = fork(); if(p == -1) { log_err("could not fork: %s", strerror(errno)); return; } if(p) return; /* parent returns */ if(execlp(cfg->login_command, cfg->login_command, cfg->login_location, NULL) == -1) { log_err("could not exec: %s", strerror(errno)); } /* not reachable */ exit(1); #endif /* USE_WINSOCK */ } dnssec-trigger-0.13/panel/install-icon.png0000664000175000017500000001201611634046156020222 0ustar wouterwouterPNG  IHDR@@iqsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxi\uuOLO`V 0H, .Z hdPVh)9mYSI*/.'VRVbbK,[E&C@orO>i`b/L=}gUO=("v 7kbzt ^U}cȇio1~{wLQ'OՆ^AuI*xzUsMlJ{{{[rm[Hg2&ݟˇtMIU͛+-`6_pәLtEәtKt?'3_AƓCO= >6Q@D |طw~`b( €Qo+ x@ fno6,bojՄa㸄+j6&Х{Zu%Pux;G""c,yz9zXq}? % CDsON{bv7f۳t8R*jӜ|.0u đC[+h3*O>lueq6UO;|_[ SPUrmń`UWbjk+yR_Q{(/2 7FlOZ^*|̏]pfx50^Y_m1"qMWW6k~drWj^pBjm DZ}yaC' wL;QVVIRuK7XŸ&=qRM>2X*ȥIvk'&_R]6Ҁqaܨ,DKdmZlhܔ?yEDQh*43 ,/J9DD>xtqk\ibb(&u -)]o̿ozWolq(Z( Tk+@DP\Rn4yb<맋=$qIgs~#z35OV% mT-aYun~u9Co0ku5@UcK64js`DG&Z8kEu4q-wu.C6~5ؙd{NBIujfZx[ `ٱ̖= 6ΐ,}@,"L>873|_P7 r\7$ZM#7!H:[ު0tzqܜc@""/񜪎ܠƩ[ro~wo{g^U)/-!b x||:\[%_`PZoW`|r[cgt:wO{ssU2UuU "Myo|{DbC8c :Sv޳q"rj !?ڬL*k:^Tj E0hęsTШ;*y~:y>qJu=(.z&7%` Ĉ<UD,Bk;pŻ3EfƆZ9}3G^@ "I*T0SUT-jCߚX^5k?~;<'cq=q:7Ck7慎q,(Vb% =w瞖mq gTξˇ?OM1PMٵ5{I٧. 4~$ؙ򅗿?U³j_ p q~@) +|c1N-/#AzjXUU8bt^]}᧗7+"qc@ȐTUzg_~vfEz8&*;lީUY榋7%"'>}Z$1_So_%w\ӌ6%I߶8;ZBIy-1m%^]x?LG3uk#Xe闞ѳyc\{2g&:'TܖQs"Tn UUlR#U.XUUEdx\֛a6m gmtCw;z 5UO/_%1qlhJe)f(u]o-8FVb FpBU ,3z{KJQzqhmY]5Ǩ^0>]2vó`Jyi5shqU_Ox#@`mM6!!Υ {ǻھZ˹#o3ب AU75aXD\.vgH}}S7\1!kKT|'=3dZOV;{0qeD! /|7XDJNZ[ %v`8)ҹ&Z8hDR# ɦ D)n٩ Ƙ0?Yg|d;/dfǁDxDZ߱wۀtZi/]ҿ5 l|;BX\(EA qbHlcH2Nc\;ESm=[Z:ԒXW:J]ES*ejl^yiK<q֑<8 Ogb8oL/ 1o`ӛ15O{qw>|틞im㧝pU#lJK`L1+Ƭ:uJMo+2"u"F|aQG1dur+T})T MQ^X,Fz&[lƈ4uOz/-5P}ǒEaƛ!u z Xͥɴwv, K-|Ji[}bm- ,p>q3\]C33ck#R)tlI_X͞9* Ieanѳ#AD͊p?ŝt۰Ny<6lDոQg`KbK|'ֳq`NJN~u܄7V[ A[;|DWI:Y ;9@L@Zay.6(YUzlDo}ûnO$ezysFmAWCߎ'1{|],FGU7Z\7%@$F*t"Z]x+a0aPfjcÓIى%sĸy.bCPC,N 5My.PTDBvToLp=YVrLQ\~y>*_~0'GA$bey3W$9_{HNKG{i׽Ƭ 8 sCGd+!=<_1_X%Gzk-Yt:jI|`KJ_3OZJ4=tv#U=}oFOR$>X;mj90Jz\@K~!Ǹ)RJ\+?KOh8o"#/ImOmоT:7WµYL緵7Ncj8:ҥwvvzQev8y@iEl*9-=#RZ.gy,#nM\k/pMskjZYUmǏ=]yԟZ\/)ixK9w~VTf& 9=hi&/@A?߽U7q- +gokq޵234 image/svg+xml dnssec-trigger-0.13/panel/panel.c0000664000175000017500000005766012275162157016403 0ustar wouterwouter/* * panel/panel.c - implementation of dnssec-trigger panel * * Copyright (c) 2011, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * Implementation of dnssec-trigger panel. */ #include "config.h" #ifdef HAVE_GETOPT_H #include #endif #include #include #include #ifdef HAVE_APP_INDICATOR #include "libappindicator/app-indicator.h" #endif #include "riggerd/log.h" #include "riggerd/cfg.h" #include "panel/attach.h" static GtkTextView* result_textview; #ifndef HAVE_APP_INDICATOR static GtkStatusIcon* status_icon; #else static AppIndicator* app_ind; #endif static GtkWidget* result_window; static GtkWidget* unsafe_dialog; static GtkWidget* hotsign_dialog; static GtkWidget* noweb_dialog; static GtkWidget* update_dialog; static GtkLabel* update_label; static GdkPixbuf* normal_icon; static GdkPixbuf* alert_icon; static GtkMenu* statusmenu; /** if we have asked about disconnect or insecure */ static int unsafe_asked = 0; /** if we should ask unsafe */ static int unsafe_should = 0; /** if we have asked about noweb */ static int noweb_asked = 0; static void feed_alert(struct alert_arg* a); static void feed_update_alert(char* new_version); void present_unsafe_dialog(void); void present_noweb_dialog(void); /** print usage text */ static void usage(void) { printf("usage: dnssec-trigger-panel [options]\n"); printf(" -c config use configfile, default is %s\n", CONFIGFILE); printf(" -d run from current directory (UIDIR=panel/)\n"); printf(" -h this help\n"); printf("version %s\n", PACKAGE_VERSION); } #ifdef USE_WINSOCK /** * Obtain registry string (if it exists). * @param key: key string * @param name: name of value to fetch. * @return malloced string with the result or NULL if it did not * exist on an error (logged) was encountered. */ static char* lookup_reg_str(const char* key, const char* name) { HKEY hk = NULL; DWORD type = 0; BYTE buf[1024]; DWORD len = (DWORD)sizeof(buf); LONG ret; char* result = NULL; ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hk); if(ret == ERROR_FILE_NOT_FOUND) return NULL; /* key does not exist */ else if(ret != ERROR_SUCCESS) { log_err("RegOpenKeyEx failed"); return NULL; } ret = RegQueryValueEx(hk, (LPCTSTR)name, 0, &type, buf, &len); if(RegCloseKey(hk)) log_err("RegCloseKey"); if(ret == ERROR_FILE_NOT_FOUND) return NULL; /* name does not exist */ else if(ret != ERROR_SUCCESS) { log_err("RegQueryValueEx failed"); return NULL; } if(type == REG_SZ || type == REG_MULTI_SZ || type == REG_EXPAND_SZ) { buf[sizeof(buf)-1] = 0; buf[sizeof(buf)-2] = 0; /* for multi_sz */ result = strdup((char*)buf); if(!result) log_err("out of memory"); } return result; } #endif /* USE_WINSOCK */ /** sighandler. Since we must have one * * @param sig: signal number. * * @return signal handler return type (void or int). * */ static RETSIGTYPE record_sigh(int sig) { switch(sig) { #ifdef SIGHUP case SIGHUP: #endif case SIGTERM: #ifdef SIGQUIT case SIGQUIT: #endif #ifdef SIGBREAK case SIGBREAK: #endif case SIGINT: if(verbosity >= 2) printf("killed by signal %d\n", (int)sig); gtk_main_quit(); break; #ifdef SIGPIPE case SIGPIPE: break; #endif default: if(verbosity >= 2) printf("ignoring signal %d", sig); } } /** the lock for the feed structure */ static GMutex feed_lock; /** callback that locks feedlock */ static void lock_feed_lock(void) { g_mutex_lock(&feed_lock); } /** callback that unlocks feedlock */ static void unlock_feed_lock(void) { g_mutex_unlock(&feed_lock); } /** callback that quits the program */ static void feed_quit(void) { /* we are in the feed thread */ gdk_threads_enter(); gtk_main_quit(); gdk_threads_leave(); } gpointer feed_thread(gpointer data) { attach_start((struct cfg*)data); return NULL; } /** spawn the feed thread */ static void spawn_feed(struct cfg* cfg) { GError* err=NULL; GThread* thr; attach_create(); g_mutex_init(&feed_lock); feed->lock = &lock_feed_lock; feed->unlock = &unlock_feed_lock; feed->quit = &feed_quit; feed->alert = &feed_alert; feed->update_alert = &feed_update_alert; thr = g_thread_new("feedfromdaemon", &feed_thread, cfg); if(!thr) fatal_exit("cannot create thread: %s", err->message); } /* the G_MODULE_EXPORT makes the routine exported on windows for dynamic * linking to gtk. On linux the -export-dynamic flag to the linker does that. */ G_MODULE_EXPORT void on_quit_activate(GtkMenuItem* ATTR_UNUSED(menuitem), gpointer ATTR_UNUSED(user_data)) { gtk_main_quit(); } G_MODULE_EXPORT gboolean on_result_dialog_delete_event(GtkWidget* ATTR_UNUSED(widget), GdkEvent* ATTR_UNUSED(event), gpointer ATTR_UNUSED(user_data)) { gtk_widget_hide(GTK_WIDGET(result_window)); return TRUE; /* stop other handlers, do not destroy the window */ } G_MODULE_EXPORT void on_result_ok_button_clicked(GtkButton* ATTR_UNUSED(button), gpointer ATTR_UNUSED(user_data)) { gtk_widget_hide(GTK_WIDGET(result_window)); } G_MODULE_EXPORT void on_reprobe_activate(GtkMenuItem* ATTR_UNUSED(menuitem), gpointer ATTR_UNUSED(user_data)) { attach_send_reprobe(); } G_MODULE_EXPORT void on_proberesults_activate(GtkMenuItem* ATTR_UNUSED(menuitem), gpointer ATTR_UNUSED(user_data)) { char buf[102400]; GtkTextBuffer *buffer; /* fetch results */ fetch_proberesults(buf, sizeof(buf), "\n"); buffer = gtk_text_view_get_buffer(result_textview); gtk_text_buffer_set_text(buffer, buf, -1); /* show them */ gtk_widget_show(GTK_WIDGET(result_window)); } G_MODULE_EXPORT gboolean on_hotsign_dialog_delete_event(GtkWidget* ATTR_UNUSED(widget), GdkEvent* ATTR_UNUSED(event), gpointer ATTR_UNUSED(user_data)) { gtk_widget_hide(GTK_WIDGET(hotsign_dialog)); if(unsafe_should) present_unsafe_dialog(); return TRUE; /* stop other handlers, do not destroy the window */ } G_MODULE_EXPORT void on_hotsign_ok_button_clicked(GtkButton* ATTR_UNUSED(button), gpointer ATTR_UNUSED(user_data)) { attach_send_hotspot_signon(); gtk_widget_hide(GTK_WIDGET(hotsign_dialog)); unsafe_asked = 1; unsafe_should = 0; } G_MODULE_EXPORT void on_hotsign_cancel_button_clicked(GtkButton* ATTR_UNUSED(button), gpointer ATTR_UNUSED(user_data)) { gtk_widget_hide(GTK_WIDGET(hotsign_dialog)); if(unsafe_should) present_unsafe_dialog(); } G_MODULE_EXPORT void on_hotspotsignon_activate(GtkMenuItem* ATTR_UNUSED(menuitem), gpointer ATTR_UNUSED(user_data)) { if(gtk_widget_get_visible(GTK_WIDGET(unsafe_dialog))) { gtk_widget_hide(GTK_WIDGET(unsafe_dialog)); } gtk_widget_show(GTK_WIDGET(hotsign_dialog)); } G_MODULE_EXPORT void on_statusicon_popup_menu(GtkStatusIcon* ATTR_UNUSED(status_icon), guint button, guint activate_time, gpointer ATTR_UNUSED(user_data)) { #ifndef UB_ON_WINDOWS gtk_menu_popup(GTK_MENU(statusmenu), NULL, NULL, >k_status_icon_position_menu, status_icon, button, activate_time); #else /* on windows, the statusicon is not good to center on, use the mouse position */ gtk_menu_popup(GTK_MENU(statusmenu), NULL, NULL, NULL, NULL, button, activate_time); #endif } G_MODULE_EXPORT void on_statusicon_activate(GtkStatusIcon* ATTR_UNUSED(status_icon), gpointer ATTR_UNUSED(user_data)) { /* no window to show and hide by default */ if(0) { /* hide and show the window when the status icon is clicked */ if(gtk_widget_get_visible(result_window) && gtk_window_has_toplevel_focus(GTK_WINDOW( result_window))) { gtk_widget_hide(GTK_WIDGET(result_window)); } else { gtk_widget_show(GTK_WIDGET(result_window)); gtk_window_deiconify(GTK_WINDOW(result_window)); gtk_window_present(GTK_WINDOW(result_window)); } } } G_MODULE_EXPORT gboolean on_unsafe_dialog_delete_event(GtkWidget* ATTR_UNUSED(widget), GdkEvent* ATTR_UNUSED(event), gpointer ATTR_UNUSED(user_data)) { gtk_widget_hide(GTK_WIDGET(unsafe_dialog)); unsafe_asked = 1; unsafe_should = 0; attach_send_insecure(0); return TRUE; /* stop other handlers, do not destroy dialog */ } G_MODULE_EXPORT void on_disconnect_button_clicked(GtkButton *ATTR_UNUSED(button), gpointer ATTR_UNUSED(user_data)) { gtk_widget_hide(GTK_WIDGET(unsafe_dialog)); unsafe_asked = 1; unsafe_should = 0; attach_send_insecure(0); } G_MODULE_EXPORT void on_insecure_button_clicked(GtkButton *ATTR_UNUSED(button), gpointer ATTR_UNUSED(user_data)) { gtk_widget_hide(GTK_WIDGET(unsafe_dialog)); unsafe_asked = 1; unsafe_should = 0; attach_send_insecure(1); } void present_unsafe_dialog(void) { unsafe_should = 1; if(gtk_widget_get_visible(GTK_WIDGET(hotsign_dialog))) return; /* wait for hotspot signon question to finish */ gtk_window_set_urgency_hint(GTK_WINDOW(unsafe_dialog), TRUE); gtk_window_set_keep_above(GTK_WINDOW(unsafe_dialog), TRUE); gtk_widget_show(GTK_WIDGET(unsafe_dialog)); gtk_window_deiconify(GTK_WINDOW(unsafe_dialog)); gdk_window_raise(gtk_widget_get_window(unsafe_dialog)); gtk_window_present(GTK_WINDOW(unsafe_dialog)); } void panel_alert_danger(void) { #ifndef HAVE_APP_INDICATOR gtk_status_icon_set_from_pixbuf(status_icon, alert_icon); #else app_indicator_set_status(app_ind, APP_INDICATOR_STATUS_ATTENTION); #endif } void panel_alert_safe(void) { #ifndef HAVE_APP_INDICATOR gtk_status_icon_set_from_pixbuf(status_icon, normal_icon); #else app_indicator_set_status(app_ind, APP_INDICATOR_STATUS_ACTIVE); #endif } /** tell panel to update itself with new state information */ void panel_alert_state(struct alert_arg* a) { /* handle state changes */ #ifndef HAVE_APP_INDICATOR gtk_status_icon_set_tooltip_text(status_icon, state_tooltip(a)); #else /* no tooltip for appindicator */ #endif process_state(a, &unsafe_asked, &noweb_asked, &panel_alert_danger, &panel_alert_safe, &present_unsafe_dialog, &present_noweb_dialog); if(!a->now_dark) unsafe_should = 0; } void present_noweb_dialog(void) { gtk_window_set_urgency_hint(GTK_WINDOW(noweb_dialog), TRUE); gtk_window_set_keep_above(GTK_WINDOW(noweb_dialog), TRUE); gtk_widget_show(GTK_WIDGET(noweb_dialog)); gtk_window_deiconify(GTK_WINDOW(noweb_dialog)); gdk_window_raise(gtk_widget_get_window(noweb_dialog)); gtk_window_present(GTK_WINDOW(noweb_dialog)); } /** show software update question */ void panel_update_alert(char* new_version) { char update_text[1024]; printf("show version for %s to %s\n", PACKAGE_VERSION, new_version); /* set the text label */ snprintf(update_text, sizeof(update_text), "There is a software update available for dnssec-trigger\n" "from %s to %s.\n" "Do you wish to install the update now?", PACKAGE_VERSION, new_version); gtk_label_set_markup(update_label, update_text); gtk_window_set_keep_above(GTK_WINDOW(update_dialog), TRUE); gtk_widget_show(GTK_WIDGET(update_dialog)); gtk_window_deiconify(GTK_WINDOW(update_dialog)); gdk_window_raise(gtk_widget_get_window(update_dialog)); gtk_window_present(GTK_WINDOW(update_dialog)); free(new_version); } G_MODULE_EXPORT gboolean on_update_dialog_delete_event(GtkWidget* ATTR_UNUSED(widget), GdkEvent* ATTR_UNUSED(event), gpointer ATTR_UNUSED(user_data)) { gtk_widget_hide(GTK_WIDGET(update_dialog)); attach_send_update_cancel(); return TRUE; /* stop other handlers, do not destroy the window */ } G_MODULE_EXPORT void on_update_cancel_button_clicked(GtkButton *ATTR_UNUSED(button), gpointer ATTR_UNUSED(user_data)) { gtk_widget_hide(GTK_WIDGET(update_dialog)); attach_send_update_cancel(); } G_MODULE_EXPORT void on_update_ok_button_clicked(GtkButton *ATTR_UNUSED(button), gpointer ATTR_UNUSED(user_data)) { gtk_widget_hide(GTK_WIDGET(update_dialog)); attach_send_update_ok(); } G_MODULE_EXPORT gboolean on_noweb_dialog_delete_event(GtkWidget* ATTR_UNUSED(widget), GdkEvent* ATTR_UNUSED(event), gpointer ATTR_UNUSED(user_data)) { gtk_widget_hide(GTK_WIDGET(noweb_dialog)); noweb_asked = 1; attach_send_skip_http(); return TRUE; /* stop other handlers, do not destroy the window */ } G_MODULE_EXPORT void on_skip_button_clicked(GtkButton *ATTR_UNUSED(button), gpointer ATTR_UNUSED(user_data)) { gtk_widget_hide(GTK_WIDGET(noweb_dialog)); noweb_asked = 1; attach_send_skip_http(); } G_MODULE_EXPORT void on_login_button_clicked(GtkButton *ATTR_UNUSED(button), gpointer ATTR_UNUSED(user_data)) { gtk_widget_hide(GTK_WIDGET(noweb_dialog)); noweb_asked = 1; attach_send_insecure(1); sleep(1); /* time for DNS settings to percolate */ run_login(); } #ifdef USE_WINSOCK /* the parameters for the panel alert state */ static int call_lock_inited = 0; static GMutex call_lock; static struct alert_arg cp_arg; static char* cp_new_version = NULL; gboolean call_alert(gpointer ATTR_UNUSED(arg)) { /* get params */ struct alert_arg a; g_mutex_lock(&call_lock); a = cp_arg; g_mutex_unlock(&call_lock); panel_alert_state(&a); /* only call once, remove call_alert from the glib mainloop */ return FALSE; } /* schedule a call to the panel alert state from the main thread */ void call_panel_alert_state(struct alert_arg* a) { if(!call_lock_inited) { call_lock_inited = 1; g_mutex_init(&call_lock); } /* store parameters */ g_mutex_lock(&call_lock); cp_arg = *a; g_mutex_unlock(&call_lock); /* the call_alert function will run from the main thread, because * GTK+ is not threadsafe on windows */ g_idle_add(&call_alert, NULL); } gboolean call_update_alert(gpointer ATTR_UNUSED(arg)) { /* get params */ char* vs; g_mutex_lock(&call_lock); vs = cp_new_version; cp_new_version = NULL; g_mutex_unlock(&call_lock); panel_update_alert(vs); /* only call once, remove call_alert from the glib mainloop */ return FALSE; } /* schedule a call to the panel software alert from the main thread */ void call_panel_update_alert(char* a) { if(!call_lock_inited) { call_lock_inited = 1; g_mutex_init(&call_lock); } /* store parameters */ g_mutex_lock(&call_lock); free(cp_new_version); cp_new_version = a; g_mutex_unlock(&call_lock); /* the call_alert function will run from the main thread, because * GTK+ is not threadsafe on windows */ g_idle_add(&call_update_alert, NULL); } #endif /* USE_WINSOCK */ /** callback that alerts panel of new status */ static void feed_alert(struct alert_arg* a) { gdk_threads_enter(); #ifndef USE_WINSOCK panel_alert_state(a); #else /* call the above function from the main thread, in case the system * is not threadsafe (windows) */ call_panel_alert_state(a); #endif gdk_threads_leave(); } /** callback that alerts panel of new software update */ static void feed_update_alert(char* new_version) { gdk_threads_enter(); #ifndef USE_WINSOCK panel_update_alert(new_version); #else /* call the above function from the main thread, in case the system * is not threadsafe (windows) */ call_update_alert(new_version); #endif gdk_threads_leave(); } static GdkPixbuf* load_icon(const char* icon, int debug) { char file[1024]; GError* error = NULL; if(debug) snprintf(file, sizeof(file), "panel/%s", icon); else snprintf(file, sizeof(file), "%s/%s", UIDIR, icon); #ifdef HOOKS_OSX /* smaller icons on OSX because of its tray icon size issues */ return gdk_pixbuf_new_from_file_at_size(file, 18, 18, &error); #else return gdk_pixbuf_new_from_file_at_size(file, 64, 64, &error); #endif } static void make_tray_icon(void) { #ifndef HAVE_APP_INDICATOR status_icon = gtk_status_icon_new_from_pixbuf(normal_icon); g_signal_connect(G_OBJECT(status_icon), "activate", G_CALLBACK(on_statusicon_activate), NULL); g_signal_connect(G_OBJECT(status_icon), "popup-menu", G_CALLBACK(on_statusicon_popup_menu), NULL); gtk_status_icon_set_tooltip_text(status_icon, "dnssec-trigger"); gtk_status_icon_set_visible(status_icon, TRUE); #else /* appindicator */ const char* i = "dnssec-trigger"; const char* a = "dnssec-trigger-alert"; if(gtk_icon_theme_get_default() && !gtk_icon_theme_has_icon(gtk_icon_theme_get_default(), i)) { printf("error: icon not found in icon theme, fallback\n"); i="gtk-add"; a="gtk-dialog-warning"; } app_ind = app_indicator_new("dnssec-trigger", i, APP_INDICATOR_CATEGORY_SYSTEM_SERVICES); # ifdef HAVE_APP_INDICATOR_SET_ICON_FULL app_indicator_set_icon_full(app_ind, i, "dnssec-trigger"); app_indicator_set_attention_icon_full(app_ind, a, "DNS DANGER"); # else app_indicator_set_icon(app_ind, i); app_indicator_set_attention_icon(app_ind, a); # endif app_indicator_set_menu(app_ind, statusmenu); app_indicator_set_status(app_ind, APP_INDICATOR_STATUS_ACTIVE); #endif } /* build UI from xml */ static GtkBuilder* load_ui_xml(int debug) { const char* file; GtkBuilder* builder = gtk_builder_new(); /* read xml with gui */ if(debug) file = "panel/pui.xml"; else file = UIDIR"/pui.xml"; gtk_builder_add_from_file(builder, file, NULL); return builder; } /** initialize the gui */ static void init_gui(int debug) { GtkBuilder* builder = load_ui_xml(debug); /* grab important widgets into global variables */ result_window = GTK_WIDGET(gtk_builder_get_object(builder, "result_dialog")); if(!result_window) { printf("could not load the UI (-d to run from build dir)\n"); exit(1); } result_textview = GTK_TEXT_VIEW(gtk_builder_get_object(builder, "result_textview")); unsafe_dialog = GTK_WIDGET(gtk_builder_get_object(builder, "unsafe_dialog")); noweb_dialog = GTK_WIDGET(gtk_builder_get_object(builder, "noweb_dialog")); hotsign_dialog = GTK_WIDGET(gtk_builder_get_object(builder, "hotsign_dialog")); update_dialog = GTK_WIDGET(gtk_builder_get_object(builder, "update_dialog")); update_label = GTK_LABEL(gtk_builder_get_object(builder, "update_label")); statusmenu = GTK_MENU(gtk_builder_get_object(builder, "statusmenu")); /* we need to incref otherwise we may lose the reference */ g_object_ref(G_OBJECT(statusmenu)); gtk_widget_hide(GTK_WIDGET(result_window)); g_object_ref(G_OBJECT(result_window)); g_object_ref(G_OBJECT(unsafe_dialog)); g_object_ref(G_OBJECT(noweb_dialog)); g_object_ref(G_OBJECT(update_dialog)); g_object_ref(G_OBJECT(hotsign_dialog)); /* no more need for the builder */ gtk_builder_connect_signals(builder, NULL); g_object_unref(G_OBJECT(builder)); normal_icon = load_icon("status-icon.png", debug); alert_icon = load_icon("status-icon-alert.png", debug); /* create the status icon in the system tray */ make_tray_icon(); /* loaded the icons, also good for our windows */ gtk_window_set_icon(GTK_WINDOW(result_window), normal_icon); gtk_window_set_icon(GTK_WINDOW(unsafe_dialog), alert_icon); gtk_window_set_icon(GTK_WINDOW(noweb_dialog), alert_icon); gtk_window_set_icon(GTK_WINDOW(update_dialog), normal_icon); gtk_window_set_icon(GTK_WINDOW(hotsign_dialog), alert_icon); } /** remove GUI stuff on exit */ static void stop_gui(void) { gtk_widget_hide(GTK_WIDGET(unsafe_dialog)); gtk_widget_hide(GTK_WIDGET(noweb_dialog)); gtk_widget_hide(GTK_WIDGET(hotsign_dialog)); gtk_widget_hide(GTK_WIDGET(result_window)); gtk_widget_hide(GTK_WIDGET(update_dialog)); gtk_widget_hide(GTK_WIDGET(statusmenu)); #ifndef HAVE_APP_INDICATOR gtk_status_icon_set_visible(status_icon, FALSE); #else app_indicator_set_status(app_ind, APP_INDICATOR_STATUS_PASSIVE); #endif } /** do main work */ static void do_main_work(const char* cfgfile, int debug) { struct cfg* cfg = cfg_create(cfgfile); if(!cfg) fatal_exit("cannot read config %s", cfgfile); /* start signal handlers */ if( signal(SIGTERM, record_sigh) == SIG_ERR || #ifdef SIGQUIT signal(SIGQUIT, record_sigh) == SIG_ERR || #endif #ifdef SIGBREAK signal(SIGBREAK, record_sigh) == SIG_ERR || #endif #ifdef SIGHUP signal(SIGHUP, record_sigh) == SIG_ERR || #endif #ifdef SIGPIPE signal(SIGPIPE, SIG_IGN) == SIG_ERR || #endif signal(SIGINT, record_sigh) == SIG_ERR ) printf("install sighandler failed: %s\n", strerror(errno)); /* start */ init_gui(debug); /* initializes the GUI objects */ spawn_feed(cfg); /* starts connecting to the server in other thread */ gdk_threads_enter(); gtk_main(); gdk_threads_leave(); stop_gui(); attach_stop(); /* stop the other thread */ #ifdef USE_WINSOCK if(call_lock_inited) g_mutex_clear(&call_lock); #endif /* do not free this mutex, because the attach.c:check_for_event * may still be using it, gets cleaned up by system on exit * if(feed_lock) g_mutex_clear(&feed_lock); */ } /** getopt global, in case header files fail to declare it. */ extern int optind; /** getopt global, in case header files fail to declare it. */ extern char* optarg; /** * main program. Set options given commandline arguments. * @param argc: number of commandline arguments. * @param argv: array of commandline arguments. * @return: exit status of the program. */ int main(int argc, char *argv[]) { int c; const char* cfgfile = CONFIGFILE; int debug = 0; #ifdef USE_WINSOCK int r; WSADATA wsa_data; if((r = WSAStartup(MAKEWORD(2,2), &wsa_data)) != 0) fatal_exit("WSAStartup failed: %s", wsa_strerror(r)); /* setup THEME */ /* if the theme uses an engine dll, set GTK_PATH to the directory * that contains 2.x.0/engines/libblabla.dll */ #endif log_ident_set("dnssec-trigger-panel"); log_init(NULL, 0, NULL); #ifdef USE_WINSOCK cfgfile = lookup_reg_str("Software\\DnssecTrigger", "ConfigFile"); if(!cfgfile) cfgfile = CONFIGFILE; #endif while( (c=getopt(argc, argv, "c:dh")) != -1) { switch(c) { case 'd': debug = 1; break; case 'c': cfgfile = optarg; break; default: case 'h': usage(); return 1; } } argc -= optind; argv += optind; if(argc != 0) { usage(); return 1; } #ifdef USE_WINSOCK if(debug) putenv("GTK2_RC_FILES=./winrc/gtkrc"); else { char* inst; char* gtkrc = lookup_reg_str("Software\\DnssecTrigger", "Gtkrc"); if(gtkrc) { char buf[1024]; snprintf(buf, sizeof(buf), "GTK2_RC_FILES=%s", gtkrc); putenv(buf); free(gtkrc); } else putenv("GTK2_RC_FILES="UIDIR"\\gtkrc"); /* chdir to the uidir, in programfiles\dnssectrigger, so that * the current dir has dlls and lots of rc and modules */ inst = lookup_reg_str("Software\\DnssecTrigger", "InstallLocation"); if(inst) { if(chdir(inst) == -1) log_err("cannot chdir(%s) %s", inst, strerror(errno)); free(inst); } else { if(chdir(UIDIR) == -1) log_err("cannot chdir(%s) %s", UIDIR, strerror(errno)); } putenv("GDK_PIXBUF_MODULEDIR=."); putenv("GDK_PIXBUF_MODULE_FILE=loaders.cache"); putenv("PANGO_RC_FILE=pangorc"); } #endif #ifndef GLIB_VERSION_2_32 /* before 2_32 init threads */ g_thread_init(NULL); #endif gdk_threads_init(); gtk_init(&argc, &argv); ERR_load_crypto_strings(); ERR_load_SSL_strings(); OpenSSL_add_all_algorithms(); (void)SSL_library_init(); /* show user interface */ do_main_work(cfgfile, debug); #ifdef USE_WINSOCK WSACleanup(); #endif return 0; } dnssec-trigger-0.13/panel/status-icon.png0000664000175000017500000001126111621234751020074 0ustar wouterwouterPNG  IHDR@@iqsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<.IDATxy\u?׵tUZޒt $! ,ǣ6Gǣ2*quXD0{:֮zޝ?StzK aF{N-*0  ӰNuT3 T5vmLAN H p=p%4)`3U4c}-6f{aI]<8duoЮ͉TվӴ  "E঒Z7ΘwNIqTb|~?^1>_1vďvmz9tj1ZQX~]Mr/_gǻ/_wT0a[+g]r,İƱd6q 6]w>0|Hr, ~LĐ+mq4vN vV,  ߽:\." D$ "?s"k 8! "XRV7ܰ^NcZm#pwoxȎ N&Θ8Ə69iXɪ޵8@#P7ϊH~K:&ҀB5rg5`s|O"6ؓN&ܾ>?u,5۶xe`_r'n䃣GEdipL" Ǔ3Łl_LXddcME[GˮHUcgP11jFD~MYճM+cYضiY/Tp3-:L8Wس\_ <Ϙ`z/+,4,Ǭn!qjYf6Qr, !#mv*oMUE|ٰء &#Gv ]ۂ%۶-1-L+kЗ%چVNcStJD4.>E5dlx4Q*n@i7gu5%JdǶ@UEUuxxX<^R:tҋCN.^>CNxnlkztoZOo{륹9NrdO9/<ūjj Vaib'lY1.چҊ0eaJd}ǀR2o䷞XP&aM޻%z`ؾP^[@9|e3T+ .fm߿w:өD x<^</a^W৓PʚPyGE]AEUWyYyuRc-;75ݿuN"LB^c<҉ݱsu*B~#C#7[i+zx}x>_uKWGgTgu|_[Ɉ.Z3svq]UkZqܣlݵ[W+Dѡw<xÒ%W=,T5m=DȪj|PùWlX"o eaZyۀTuI 3~wW5.Xm( ӴF/k`Ϛigà]/7}3BO Pmk%a߱={u|CU>puugy^# ^,[y{+"5MvpuSSj,"Ok~uqd2?}U]/]}Pe@(;78:v&% Od5&#"TѝڊK+qJԱӟ&!s4ɮ]W1%˴}^#Rk~0,iZ?s@w]0czpҷ75C]93HģX~$Uhpr5ʚmM/ƌոF{ʽIum%Us=x<иWoywс;D䩓m!yVWpNl/0Us"xPգcheG_2Ղd?N󀢦ECEUeO S&@D>("?}UD0z{;yA2$\X|e)uKK\WqsH_u@ تTcJGrDdDr7M Xꊼ~L~)p][VUGUuOs<YFcRDjF)^x>,k@"0<i>>4+u9u}^_l/ca*pK+jGp3 wE4˧Q/|ZYn!"+ ~tۼ&QCS =n} _U9uM]=+8kkmU-]D$ݲ7wtXulp"U:QySeض2&ӀE@Ina21 lcc߀m>T7JYU0`o}vɈx~oWy_uoI 1.Xo%"OfAUvx;v`0/pUV^wWe_vβ<pL_~5fozK $~."b:X7ш[h sV/òQ~G_~Cm'US8&$"_xt_Ua U x".O`8xuGO2C%q4Ɏ?|uKo0N= '\_IuPA|2^>{=KTݯ*"-N8_ Ȗٰ image/svg+xml dnssec-trigger-0.13/panel/status-icon-alert.svg0000664000175000017500000003633111717264572021233 0ustar wouterwouter image/svg+xml dnssec-trigger-0.13/panel/uninstall-icon.png0000664000175000017500000001156111634046407020570 0ustar wouterwouterPNG  IHDR@@iqsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxw$W}?==qsNʖ9*&]6P,˩p* ,LS, d, e03;ްK[5;ۿވ LOLO{7H"05 r&NPDW/v|\UW%@D k =C?^U:24~:Cd:X/|dn/UurkPcTym[b 7qw ~:Md4Hg4k ]'qM,"9oӌJbB | gU-_Hۊy{?3ټYO it?o}y6a x &&$Sx ʾBwAIOIhx-Cݝp0n`ŃP!8>'.Asxoq}? 8KT|GYݹ_ᡋ. "֫#@Յ|:A_ c0v+ /@Jx<<ED|BM5@D}/-t[isN*K<7r_5~U*eP﬎MDOř|56֥pЇ@ ęV'[%B;0! t]Js+M Ȭ.G]:|q ~5;)+\-_e0Qn\Zvmy),vŰg" &">Y=tHN6mP\6Nk~;t,.PXY@T|O@ yj)jimK@CpO0f8sD$PDaH&.Iy# ?L* ?9* )\@\H+`P]Cz±X|@U<[*&Նq}u 0$ d{;\/H}0"rM&7 q=wLL n8Nr?ɛ(T=a_&!Y{Dfq >tﮁC͐GTYacQya6Q//rA$0;ya@hkMՇpgq N8ޟ"$| O‰18ٖ;|TUo?_8}e)GL!gcQ^&*"µ~N0`CEXkj\]G^)7$'!w0to3wa8ږ;1"|=i~q]cdͶED 18ְV^M[W;HD @$0XA8RV~~L S=0KyiǸAAբM"Z$`C:6Oc02  H+OK64nmڤd&&-Bt!sJU߾x"2 \#ƤD#.$!jQX'=Nyn#򰽃f c0ok=In 03;H2#afh8 & ,-lJBH1n-0MUVg*K+6َ里.JIyaI#b<t""<1 Z\¥IO#S,pXU}ڌ ٔaN|q~xoMk$vEKs%ݽ<|1&GΨ VBmB7aZᅿD8q 15qcqZ=:_^ "oYhٌU 0}s}]ޓub};'iUuVDRם<آ]G$b53#M38tӍºIyiMYբV@TTE[T\'/};>~%ECf&Q!F:Bo0q9VIKɞ;m82*RSBBнpTGug&L4n~Ʈvw*EĠ֮}V+hQ sHp[جڼġUk?ްNx^ '8\`F77Yoxo+ǞVmjG,̈́jȤmrkC Pղ$HGI2ikg=(1AUp:Jy9;=z~yܵVc}U˾랟ss/>DyWQMᦳel{VK5'eY6&77VW*#=|q:sPZň%Vk߹'xo?\]0ƕW\wmziv~RUl#"wFHU]7e2Յ&`pLqU=q4ײu{Ge䬍ykEo 1ҲoKب2'TQc"{HYU0^f{ơȪ*qc*aς9#gt9,XeܲbNn&<\qA⭱II:R cky@O7xS$ZllDž$ #11پᵰͼ41 bETHAn6¶}xYc;mۨc166Xcp nޡS5fIˮ+X T(/̄3'ׁΦC- \< |\DU 1Lp뗑^ֻcٷ#H`xeY6,gGpio6/4jĶV|A1/xa ;yZ}65 ^b\';)Ik٦iR_m0SZT:c:[I / z;\YXj)-χ?K$_q:*,&TUj#;LH :}>׷>;|;e buNy^KyyI{ 9(IڰnmzN!x.17'`&,=qʃw~uwo ܮ :UL^OQ8!Z)v-1~w8iG#p]^릉4zt֧Vs& alȶH沈$UWK1pQOI=Bo~IED~1Qt ZnH'[@h*a]o-&cSl/ BMD:g-7˞jX;tn"~:#O^Z!IENDB`dnssec-trigger-0.13/panel/install-icon.svg0000664000175000017500000003543211634046156020244 0ustar wouterwouter image/svg+xml dnssec-trigger-0.13/panel/pui.xml0000664000175000017500000005101412244645777016454 0ustar wouterwouter False 5 Disable DNSSEC for Hotspot Sign On dialog True False 2 True False Some networks, such as Hotspots, require you to sign on, or register, before allowing full network access. By clicking <i>OK</i>, DNSSEC will be disabled to allow you to connect to the captive portal's sign-on page. After you have signed on and full network access has been enabled, DNSSEC-trigger should detect this and enable DNSSEC again. You can also select <i>Reprobe</i> to attempt to establish a secure connection to a DNSSEC capable name server. <i>A red exclamation mark in the icon warns you when DNSSEC is disabled.</i> True True True 0 True False end Cancel True True True False False False 0 OK True True True False False False 1 False True end 1 hotsign_cancel_button hotsign_ok_button False 5 No Web Access dialog True True False 2 True False end Skip True True True False False False 0 Log in True True True True False False False 1 False True end 0 True False There is no access to external websites from this network. Do you have to login for that? When you select <i>Log in</i>, DNSSEC will be disabled for backwards compatibility reasons, until DNSSEC-trigger can detect web access. <i>Skip</i> this if you do not have to log in on this network. True True True 1 skip_button login_button False 5 Results of DNSSEC probe 400 280 normal True False 2 True False end OK True True True False False False 0 False True end 0 True True True True False True True 1 result_ok_button True False True False False Reprobe True True False False Probe results True False False Hotspot sign-on True True False True False False Quit False 5 Network DNSSEC Failure dialog True True False 2 True False end Disconnect True True True False False False 0 Insecure True True True False False False 1 False True end 0 True False <b>This Network Fails to Support DNSSEC</b> The network you are connected to does not allow DNS Security Extensions (DNSSEC) via the provided DNS caches, nor via contacting DNS name servers on the Internet directly (it filters traffic to this end). It is not possible to provide DNSSEC, but you can connect insecurely. Do you want to connect insecurely? * if you choose <b>Disconnect</b> then DNS is disabled. It is safe, but there is very little that works. * if you choose <b>Insecure</b> then DNSSEC is disabled and security is lost. You can connect and work. But there is no safety. The network interferes with DNSSEC, it may also interfere with other things. Have caution and work with sensitive personal and financial things some other time. Some Hotspots may work after you have gained access via its sign-on page. Then use <i>Reprobe</i> from the menu to retry. <i>A red exclamation mark in the icon warns you when DNSSEC is disabled.</i> True True True 1 disconnect_button insecure_button False 5 Software Update for Dnssec Trigger dialog True False 2 True False There is a software update available for DNSSEC-trigger. Do you wish to install the update? True True True 0 True False end Cancel True True True False False False 0 OK True True True True False False False 1 False True end 1 update_cancel_button update_ok_button dnssec-trigger-0.13/panel/uninstall-icon.svg0000664000175000017500000003542411634046407020607 0ustar wouterwouter image/svg+xml dnssec-trigger-0.13/Makefile.in0000664000175000017500000005332612631553716016102 0ustar wouterwouter# Copyright 2007 NLnet Labs # See the file LICENSE for the license debug_enabled=@debug_enabled@ ifeq "$(QUIET)" "" ifeq ($(debug_enabled),yes) QUIET=yes else QUIET=no endif endif ifeq "$(QUIET)" "yes" Q=@ INFO=@echo else Q= INFO=@: endif SHELL=@SHELL@ VERSION=@PACKAGE_VERSION@ PYTHON=@PYTHON@ srcdir=@srcdir@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ sbindir=@sbindir@ mandir=@mandir@ libdir=@libdir@ libexecdir=@libexecdir@ # datarootdir is here to please some checkers, use datadir. datarootdir=@datarootdir@ datadir=@datadir@ includedir=@includedir@ ldnsdir=@ldnsdir@ EXEEXT=@EXEEXT@ hooks=@hooks@ makehook=@hooks@-hook installhook=@hooks@-hook-install uninstallhook=@hooks@-hook-uninstall gui=@gui@ makegui=@gui@-gui installgui=@gui@-gui-install uninstallgui=@gui@-gui-uninstall networkmanager_dispatcher_dir=@networkmanager_dispatcher_dir@ netconfig_dispatcher_dir=@netconfig_dispatcher_dir@ xdg_autostart_dir=@xdg_autostart_dir@ osx_launchagents_dir=/Library/LaunchAgents osx_launchdaemons_dir=/Library/LaunchDaemons configfile=@configfile@ keydir=@keydir@ uidir=@uidir@ pidfile=@pidfile@ login_command=@login_command@ login_location=@login_location@ unbound_control_path=@unbound_control_path@ DATE=$(shell date +%F -r $(srcdir)/Changelog) do_subst = sed -e 's,[@]SHELL[@],$(SHELL),g' \ -e 's,[@]PACKAGE[@],$(PACKAGE),g' \ -e 's,[@]VERSION[@],$(VERSION),g' \ -e 's,[@]PYTHON[@],$(PYTHON),g' \ -e 's,[@]libexecdir[@],$(libexecdir),g' \ -e 's,[@]sbindir[@],$(sbindir),g' \ -e 's,[@]keydir[@],$(keydir),g' \ -e 's,[@]pidfile[@],$(pidfile),g' \ -e 's,[@]unbound_control_path[@],$(unbound_control_path),g' \ -e 's,[@]login_command[@],$(login_command),g' \ -e 's,[@]login_location[@],$(login_location),g' \ -e 's,[@]check_updates[@],$(check_updates),g' \ -e 's,[@]DATE[@],$(DATE),g' \ -e 's,[@]configfile[@],$(configfile),g' \ -e 's,[@]bindir[@],$(bindir),g' \ -e 's,[@]uidir[@],$(uidir),g' # override $U variable which is used by autotools for deansification (for # K&R C compilers), but causes problems if $U is defined in the env). U= YACC=@YACC@ LEX=@LEX@ STRIP=@STRIP@ CC=@CC@ CPPFLAGS=-I. @CPPFLAGS@ ifneq "$(srcdir)" "." CPPFLAGS:=-I$(srcdir) $(CPPFLAGS) endif CPPFLAGS:=$(strip $(CPPFLAGS)) GTK_CFLAGS=@GTK_CFLAGS@ CFLAGS=@CFLAGS@ $(GTK_CFLAGS) LDFLAGS=@LDFLAGS@ GTK_LIBS=@GTK_LIBS@ LDNSLIBS=@LDNSLIBS@ APP_INDICATOR=@APP_INDICATOR@ LIBS=$(strip @LIBS@) LIBOBJS=@LIBOBJS@ RUNTIME_PATH=@RUNTIME_PATH@ DEPFLAG=@DEPFLAG@ EXPORT_DYNAMIC=@EXPORT_DYNAMIC@ DATE=$(shell date +%Y%m%d) BUILD=build/ WINDRES=@WINDRES@ LINT=splint LINTFLAGS=+quiet -weak -warnposix -unrecog -Din_addr_t=uint32_t -Du_int=unsigned -Du_char=uint8_t -preproc -Drlimit=rlimit64 -D__gnuc_va_list=va_list #-Dglob64=glob -Dglobfree64=globfree # compat with openssl linux edition. LINTFLAGS+="-DBN_ULONG=unsigned long" -Dkrb5_int32=int "-Dkrb5_ui_4=unsigned int" -DPQ_64BIT=uint64_t -DRC4_INT=unsigned -fixedformalarray -D"ENGINE=unsigned" -D"RSA=unsigned" -D"DSA=unsigned" -D"EVP_PKEY=unsigned" -D"EVP_MD=unsigned" -D"SSL=unsigned" -D"SSL_CTX=unsigned" -D"X509=unsigned" -D"RC4_KEY=unsigned" -D"EVP_MD_CTX=unsigned" # compat with NetBSD ifeq "$(shell uname)" "NetBSD" LINTFLAGS+="-D__RENAME(x)=" -D_NETINET_IN_H_ endif # compat with OpenBSD LINTFLAGS+="-Dsigset_t=long" # FreeBSD8 LINTFLAGS+="-D__uint16_t=uint16_t" INSTALL=$(srcdir)/install-sh COMMON_SRC= COMMON_OBJ=$(addprefix $(BUILD),$(COMMON_SRC:.c=.o)) COMPAT_SRC=$(addprefix compat/,$(LIBOBJS:.o=.c)) COMPAT_OBJ=$(addprefix $(BUILD)compat/,$(LIBOBJS:.o=.o)) ifeq "$(gui)" "gtk" PANEL_SRC=panel/panel.c panel/attach.c riggerd/cfg.c riggerd/log.c riggerd/net_help.c else ifeq "$(gui)" "windows" # GTK works on windows but has large dependencies PANEL_SRC=winrc/trayicon.c panel/attach.c riggerd/cfg.c riggerd/log.c riggerd/net_help.c else PANEL_SRC= endif endif PANEL_OBJ=$(addprefix $(BUILD),$(PANEL_SRC:.c=.o)) $(COMPAT_OBJ) CONTROL_SRC=dnssec-trigger-control.c riggerd/cfg.c riggerd/log.c riggerd/net_help.c CONTROL_OBJ=$(addprefix $(BUILD),$(CONTROL_SRC:.c=.o)) $(COMPAT_OBJ) ifeq "$(hooks)" "windows" KEYGEN_SRC=winrc/dnssec-trigger-keygen.c else KEYGEN_SRC= endif KEYGEN_OBJ=$(addprefix $(BUILD),$(KEYGEN_SRC:.c=.o)) $(COMPAT_OBJ) RIGGERD_SRC=riggerd/riggerd.c riggerd/log.c riggerd/netevent.c riggerd/rbtree.c riggerd/mini_event.c riggerd/net_help.c riggerd/winsock_event.c riggerd/fptr_wlist.c riggerd/cfg.c riggerd/svr.c riggerd/probe.c riggerd/ubhook.c riggerd/reshook.c riggerd/http.c riggerd/update.c ifeq "$(hooks)" "windows" RIGGERD_SRC+=winrc/netlist.c winrc/win_svc.c winrc/w_inst.c endif ifeq "$(hooks)" "osx" RIGGERD_SRC+=osx/wakelist.c LDNSLIBS+=-framework IOKit -framework CoreFoundation endif RIGGERD_OBJ=$(addprefix $(BUILD),$(RIGGERD_SRC:.c=.o)) $(COMPAT_OBJ) ALL_SRC=$(sort $(COMMON_SRC) $(PANEL_SRC) $(RIGGERD_SRC) $(KEYGEN_SRC) $(CONTROL_SRC)) ALL_OBJ=$(addprefix $(BUILD),$(ALL_SRC:.c=.o) \ $(addprefix compat/,$(LIBOBJS:.o=.o))) $(COMPAT_OBJ) PANEL_LINKFLAGS= ifeq "$(hooks)" "windows" PANEL_LINKFLAGS+=-Wl,--subsystem,windows -lcomctl32 -lgdi32 PANEL_OBJ+=$(BUILD)winrc/rsrc_panel.o RIGGERD_OBJ+=$(BUILD)winrc/rsrc_triggerd.o KEYGEN_OBJ+=$(BUILD)winrc/rsrc_keygen.o CONTROL_OBJ+=$(BUILD)winrc/rsrc_control.o $(BUILD)%.o: $(srcdir)/%.rc $(srcdir)/config.h $(INFO) Resource $< @-if test ! -d $(dir $@); then $(INSTALL) -d $(patsubst %/,%,$(dir $@)); fi $Q$(WINDRES) $(CPPFLAGS) $< $@ endif COMPILE=$(CC) $(CPPFLAGS) $(CFLAGS) LINK=$(strip $(CC) $(RUNTIME_PATH) $(CFLAGS) $(LDFLAGS)) .PHONY: clean realclean doc lint all install uninstall test strip $(BUILD)%.o: $(srcdir)/%.c $(INFO) Build $< @-if test ! -d $(dir $@); then $(INSTALL) -d $(patsubst %/,%,$(dir $@)); fi $Q$(COMPILE) -o $@ -c $< all: $(COMMON_OBJ) dnssec-triggerd$(EXEEXT) dnssec-trigger-control$(EXEEXT) dnssec-trigger-control-setup $(makehook) $(makegui) example.conf dnssec-trigger.8 dnssec-triggerd.service test: @echo done example.conf: $(srcdir)/example.conf.in Makefile rm -f $@ $(do_subst) < $(srcdir)/example.conf.in > $@ dnssec-trigger.8: $(srcdir)/dnssec-trigger.8.in Makefile rm -f $@ $(do_subst) < $(srcdir)/dnssec-trigger.8.in > $@ dnssec-trigger-control-setup: $(srcdir)/dnssec-trigger-control-setup.sh.in Makefile rm -f $@ $(do_subst) < $(srcdir)/dnssec-trigger-control-setup.sh.in > $@ chmod +x $@ 01-dnssec-trigger: $(srcdir)/01-dnssec-trigger.in Makefile rm -f $@ $(do_subst) < $(srcdir)/01-dnssec-trigger.in > $@ chmod +x $@ dnssec-triggerd.service: $(srcdir)/dnssec-triggerd.service.in Makefile rm -f $@ $(do_subst) < $(srcdir)/dnssec-triggerd.service.in > $@ dnssec-trigger-panel.desktop: $(srcdir)/panel/dnssec-trigger-panel.desktop.in Makefile rm -f $@ $(do_subst) < $(srcdir)/panel/dnssec-trigger-panel.desktop.in > $@ windows-gui: dnssec-trigger-panel$(EXEEXT) gtk-gui: dnssec-trigger-panel$(EXEEXT) dnssec-trigger-panel.desktop cocoa-gui: osx/RiggerStatusItem osx/osx-riggerapp nl.nlnetlabs.dnssec-trigger-panel.plist none-hook: @echo "no dhcp hooks available, need trigger script" windows-hook: dnssec-trigger-keygen$(EXEEXT) networkmanager-hook: 01-dnssec-trigger dnssec-trigger-script dnssec-trigger-script: $(srcdir)/dnssec-trigger-script.in Makefile cp $< $@ $(do_subst) < $(srcdir)/dnssec-trigger-script.in > $@ chmod +x $@ osx/RiggerStatusItem/log.c: $(srcdir)/riggerd/log.c osx/RiggerStatusItem cp $< $@ osx/RiggerStatusItem/cfg.c: $(srcdir)/riggerd/cfg.c osx/RiggerStatusItem cp $< $@ osx/RiggerStatusItem/net_help.c: $(srcdir)/riggerd/net_help.c osx/RiggerStatusItem cp $< $@ osx/RiggerStatusItem/osxattach.m: $(srcdir)/panel/attach.c osx/RiggerStatusItem cp $< $@ osx/RiggerStatusItem/osxattach.h: $(srcdir)/panel/attach.h osx/RiggerStatusItem cp $< $@ osx/RiggerStatusItem/log.h: $(srcdir)/riggerd/log.h osx/RiggerStatusItem cp $< $@ osx/RiggerStatusItem/cfg.h: $(srcdir)/riggerd/cfg.h osx/RiggerStatusItem cp $< $@ osx/RiggerStatusItem/net_help.h: $(srcdir)/riggerd/net_help.h osx/RiggerStatusItem cp $< $@ osx/RiggerStatusItem/config.h: $(srcdir)/config.h osx/RiggerStatusItem cp $< $@ ifeq "$(srcdir)" "." osx/RiggerStatusItem: else osx/RiggerStatusItem: $(srcdir)/osx/RiggerStatusItem -mkdir osx cp -r $< $@ endif osx/RiggerStatusItem/RiggerStatusItem.xcodeproj/project.pbxproj: $(srcdir)/osx/RiggerStatusItem/RiggerStatusItem.xcodeproj/project.pbxproj.in $(srcdir)/osx/RiggerStatusItem sed -e "s?@OSX_SSL_INCLUDE@?@ssldir@/include?" -e "s?@OSX_SSL_LIB@?@ssldir@/lib?" < $< > $@ osx/osx-riggerapp: osx/RiggerStatusItem osx/RiggerStatusItem/cfg.c osx/RiggerStatusItem/cfg.h osx/RiggerStatusItem/net_help.c osx/RiggerStatusItem/net_help.h osx/RiggerStatusItem/log.c osx/RiggerStatusItem/log.h osx/RiggerStatusItem/config.h osx/RiggerStatusItem/main.m osx/RiggerStatusItem/RiggerApp.h osx/RiggerStatusItem/RiggerApp.m osx/RiggerStatusItem/osxattach.h osx/RiggerStatusItem/osxattach.m osx/RiggerStatusItem/RiggerStatusItem.xcodeproj/project.pbxproj (cd osx/RiggerStatusItem; xcodebuild -project RiggerStatusItem.xcodeproj -alltargets) touch osx/osx-riggerapp osx-hook: nl.nlnetlabs.dnssec-trigger-hook.plist dnssec-trigger-osx.sh nl.nlnetlabs.dnssec-triggerd.plist dnssec-trigger-setdns.sh nl.nlnetlabs.dnssec-trigger-hook.plist: $(srcdir)/osx/nl.nlnetlabs.dnssec-trigger-hook.plist.in Makefile rm -f $@ $(do_subst) < $(srcdir)/osx/nl.nlnetlabs.dnssec-trigger-hook.plist.in > $@ nl.nlnetlabs.dnssec-trigger-panel.plist: $(srcdir)/osx/nl.nlnetlabs.dnssec-trigger-panel.plist.in Makefile rm -f $@ $(do_subst) < $(srcdir)/osx/nl.nlnetlabs.dnssec-trigger-panel.plist.in > $@ nl.nlnetlabs.dnssec-triggerd.plist: $(srcdir)/osx/nl.nlnetlabs.dnssec-triggerd.plist.in Makefile rm -f $@ $(do_subst) < $(srcdir)/osx/nl.nlnetlabs.dnssec-triggerd.plist.in > $@ dnssec-trigger-osx.sh: $(srcdir)/osx/dnssec-trigger-osx.sh.in Makefile rm -f $@ $(do_subst) < $(srcdir)/osx/dnssec-trigger-osx.sh.in > $@ chmod +x $@ dnssec-trigger-setdns.sh: $(srcdir)/osx/dnssec-trigger-setdns.sh.in Makefile rm -f $@ $(do_subst) < $(srcdir)/osx/dnssec-trigger-setdns.sh.in > $@ chmod +x $@ netconfig-hook: dnssec-trigger-netconfig-hook dnssec-trigger-netconfig-hook: $(srcdir)/dnssec-trigger-netconfig-hook.sh.in Makefile rm -f $@ $(do_subst) < $(srcdir)/dnssec-trigger-netconfig-hook.sh.in > $@ chmod +x $@ dnssec-triggerd$(EXEEXT): $(RIGGERD_OBJ) $(INFO) Link $@ $Q$(LINK) -o $@ $(sort $(RIGGERD_OBJ)) $(LDNSLIBS) $(LIBS) dnssec-trigger-control$(EXEEXT): $(CONTROL_OBJ) $(INFO) Link $@ $Q$(LINK) -o $@ $(sort $(CONTROL_OBJ)) $(LIBS) dnssec-trigger-keygen$(EXEEXT): $(KEYGEN_OBJ) $(INFO) Link $@ $Q$(LINK) -o $@ $(sort $(KEYGEN_OBJ)) $(LIBS) dnssec-trigger-panel$(EXEEXT): $(PANEL_OBJ) $(INFO) Link $@ $Q$(LINK) $(EXPORT_DYNAMIC) -o $@ $(sort $(PANEL_OBJ)) $(LIBS) $(GTK_LIBS) $(PANEL_LINKFLAGS) util/config_file.c: util/configparser.h util/configlexer.c: $(srcdir)/util/configlexer.lex util/configparser.h $(INFO) Lex $< ifeq "$(strip $(LEX))" ":" $Qecho "rebuild lexer, but no lex program, skipped" else @-if test ! -d util; then $(INSTALL) -d util; fi $Qecho "#include \"config.h\"" > $@ $Qecho "#include \"util/configyyrename.h\"" >> $@ $Q$(LEX) -t $< >> $@ endif util/configparser.c util/configparser.h: $(srcdir)/util/configparser.y $(INFO) Yacc $< @-if test ! -d util; then $(INSTALL) -d util; fi $Q$(YACC) -d -o util/configparser.c $< clean: rm -f *.o *.d *.lo *~ tags rm -f dnssec-trigger-panel$(EXEEXT) dnssec-triggerd$(EXEEXT) rm -f dnssec-trigger-control-setup dnssec-trigger-control$(EXEEXT) rm -f 01-dnssec-trigger dnssec-trigger-script dnssec-trigger-osx.sh nl.nlnetlabs.dnssec-trigger-hook.plist dnssec-trigger-netconfig-hook example.conf nl.nlnetlabs.dnssec-triggerd.plist nl.nlnetlabs.dnssec-trigger-panel.plist dnssec-trigger-setdns.sh osx/osx-riggerapp dnssec-triggerd.service osx/RiggerStatusItem/RiggerStatusItem.xcodeproj/project.pbxproj rm -f dnssec-trigger-panel.desktop dnssec-trigger.8 dnssec-trigger-keygen$(EXEEXT) rm -rf autom4te.cache build osx/RiggerStatusItem/build realclean: clean rm -f config.status config.log config.h.in config.h rm -f util/configlexer.c util/configparser.c util/configparser.h rm -f Makefile configure $(BUILD)%.lint: $(srcdir)/%.c $(INFO) Lint $< @-if test ! -d $(dir $@); then $(INSTALL) -d $(patsubst %/,%,$(dir $@)); fi $Q$(LINT) $(LINTFLAGS) -I. -I$(srcdir) -I$(ldnsdir)/include $< $Qtouch $@ lint: $(addprefix $(BUILD),$(filter-out panel/attach.lint,$(filter-out panel/panel.lint,$(filter-out util/configparser.lint,$(filter-out util/configlexer.lint,$(sort $(ALL_SRC:.c=.lint))))))) tags: $(srcdir)/*.[ch] $(srcdir)/*/*.[ch] ctags -f $(srcdir)/tags $(srcdir)/*.[ch] $(srcdir)/*/*.[ch] strip: $(STRIP) dnssec-triggerd$(EXEEXT) $(STRIP) dnssec-trigger-control$(EXEEXT) if test -f dnssec-trigger-panel$(EXEEXT); then $(STRIP) dnssec-trigger-panel$(EXEEXT); fi if test -f dnssec-trigger-keygen$(EXEEXT); then $(STRIP) dnssec-trigger-keygen$(EXEEXT); fi none-hook-install: @echo "no hook to install" none-hook-uninstall: @echo "no hook to uninstall" windows-hook-install: @echo "Use makedist-makensis for windows hook install" windows-hook-uninstall: @echo "Use makedist-makensis for windows hook uninstall" networkmanager-hook-install: $(INSTALL) -m 755 -d $(DESTDIR)$(networkmanager_dispatcher_dir) $(INSTALL) -m 755 -d $(DESTDIR)/etc $(INSTALL) -m 755 -d $(DESTDIR)/usr/lib/systemd/system $(INSTALL) -c -m 755 01-dnssec-trigger $(DESTDIR)$(networkmanager_dispatcher_dir)/01-dnssec-trigger $(INSTALL) -c -m 755 dnssec-trigger-script $(DESTDIR)$(libexecdir)/dnssec-trigger-script $(INSTALL) -c -m 644 dnssec.conf $(DESTDIR)/etc/dnssec.conf $(INSTALL) -c -m 644 dnssec-triggerd.service $(DESTDIR)/usr/lib/systemd/system/dnssec-triggerd.service $(INSTALL) -c -m 644 dnssec-triggerd-keygen.service $(DESTDIR)/usr/lib/systemd/system/dnssec-triggerd-keygen.service networkmanager-hook-uninstall: @echo "attempt to restore resolv.conf mutability" $(DESTDIR)$(sbindir)/dnssec-triggerd$(EXEEXT) -u rm -f $(DESTDIR)$(networkmanager_dispatcher_dir)/01-dnssec-trigger rm -f $(DESTDIR)$(libexecdir)/dnssec-trigger-script rm -f $(DESTDIR)/etc/dnssec.conf rm -f $(DESTDIR)/usr/lib/systemd/system/dnssec-triggerd.service rm -f $(DESTDIR)/usr/lib/systemd/system/dnssec-triggerd-keygen.service osx-hook-install: $(INSTALL) -m 755 -d $(DESTDIR)$(osx_launchdaemons_dir) $(INSTALL) -m 755 -d $(DESTDIR)$(libexecdir) $(INSTALL) -c -m 644 nl.nlnetlabs.dnssec-trigger-hook.plist $(DESTDIR)$(osx_launchdaemons_dir)/nl.nlnetlabs.dnssec-trigger-hook.plist $(INSTALL) -c -m 755 dnssec-trigger-osx.sh $(DESTDIR)$(libexecdir)/dnssec-trigger-osx.sh $(INSTALL) -c -m 755 dnssec-trigger-setdns.sh $(DESTDIR)$(libexecdir)/dnssec-trigger-setdns.sh $(INSTALL) -c -m 644 nl.nlnetlabs.dnssec-triggerd.plist $(DESTDIR)$(osx_launchdaemons_dir)/nl.nlnetlabs.dnssec-triggerd.plist @echo "To start the daemon, trigger and panel you can reboot; (after dnssec-trigger-control-setup)" osx-hook-uninstall: @echo "attempt to remove dns override from system preferences" $(DESTDIR)$(libexecdir)/dnssec-trigger-setdns.sh uninit rm -f $(DESTDIR)$(osx_launchdaemons_dir)/nl.nlnetlabs.dnssec-trigger-hook.plist rm -f $(DESTDIR)$(libexecdir)/dnssec-trigger-osx.sh rm -f $(DESTDIR)$(libexecdir)/dnssec-trigger-setdns.sh rm -f $(DESTDIR)$(osx_launchdaemons_dir)/nl.nlnetlabs.dnssec-triggerd.plist if test "`uname -r | cut -d . -f 1`" -lt 9; then \ echo "there is no way to delete dnssec-trigger-panel from Library/Preferences/com.apple.loginwindow.plist with the defaults tool." ; \ echo "you have to manually remove it (from the accounts-LoginItems controlpanel pane)" ; \ fi cocoa-gui-install: $(INSTALL) -m 755 -d $(DESTDIR)$(osx_launchagents_dir) $(INSTALL) -m 755 -d $(DESTDIR)$(libexecdir) if test "`uname -r | cut -d . -f 1`" -lt 9; then \ echo "install the panel to launch for the user, goes into Library/Preferences/com.apple.loginwindow.plist." ; \ defaults write loginwindow AutoLaunchedApplicationDictionary -array-add "HidePath$(libexecdir)/RiggerStatusItem.app/Contents/MacOS/RiggerStatusItem" ; \ else \ echo "install panel in osx 10.5 and later mode" ; \ $(INSTALL) -c -m 644 nl.nlnetlabs.dnssec-trigger-panel.plist $(DESTDIR)$(osx_launchagents_dir)/nl.nlnetlabs.dnssec-trigger-panel.plist ; \ fi (umask 0022 ; cp -r osx/RiggerStatusItem/build/Release/RiggerStatusItem.app $(DESTDIR)$(libexecdir)/. ) cocoa-gui-uninstall: rm -f $(DESTDIR)$(osx_launchagents_dir)/nl.nlnetlabs.dnssec-trigger-panel.plist rm -rf $(DESTDIR)$(libexecdir)/RiggerStatusItem.app netconfig-hook-install: $(INSTALL) -m 755 -d $(DESTDIR)$(netconfig_dispatcher_dir) $(INSTALL) -c -m 755 dnssec-trigger-netconfig-hook $(DESTDIR)$(netconfig_dispatcher_dir)/dnssec-trigger-netconfig-hook netconfig-hook-uninstall: @echo "attempt to restore resolv.conf mutability" $(DESTDIR)$(sbindir)/dnssec-triggerd$(EXEEXT) -u rm -f $(DESTDIR)$(netconfig_dispatcher_dir)/dnssec-trigger-netconfig-hook windows-gui-install: $(INSTALL) -m 755 -d $(DESTDIR)$(bindir) $(INSTALL) -m 755 -d $(DESTDIR)$(uidir) $(INSTALL) -c -m 755 dnssec-trigger-panel$(EXEEXT) $(DESTDIR)$(bindir)/dnssec-trigger-panel$(EXEEXT) $(INSTALL) -c -m 644 $(srcdir)/winrc/alert.ico $(DESTDIR)$(uidir)/alert.ico $(INSTALL) -c -m 644 $(srcdir)/winrc/status.ico $(DESTDIR)$(uidir)/status.ico windows-gui-uninstall: rm -f $(DESTDIR)$(bindir)/dnssec-trigger-panel$(EXEEXT) rm -f $(DESTDIR)$(uidir)/alert.ico rm -f $(DESTDIR)$(uidir)/status.ico gtk-gui-install: $(INSTALL) -m 755 -d $(DESTDIR)$(bindir) $(INSTALL) -m 755 -d $(DESTDIR)$(uidir) $(INSTALL) -c -m 644 $(srcdir)/panel/pui.xml $(DESTDIR)$(uidir)/pui.xml $(INSTALL) -c -m 644 $(srcdir)/panel/status-icon.png $(DESTDIR)$(uidir)/status-icon.png $(INSTALL) -c -m 644 $(srcdir)/panel/status-icon-alert.png $(DESTDIR)$(uidir)/status-icon-alert.png $(INSTALL) -c -m 755 dnssec-trigger-panel$(EXEEXT) $(DESTDIR)$(bindir)/dnssec-trigger-panel$(EXEEXT) ifeq "$(APP_INDICATOR)" "yes" $(INSTALL) -m 755 -d $(DESTDIR)/usr/share/icons/hicolor/scalable/apps $(INSTALL) -m 755 -d $(DESTDIR)/usr/share/icons/hicolor/64x64/apps $(INSTALL) -c -m 644 $(srcdir)/panel/status-icon.svg $(DESTDIR)/usr/share/icons/hicolor/scalable/apps/dnssec-trigger.svg $(INSTALL) -c -m 644 $(srcdir)/panel/status-icon-alert.svg $(DESTDIR)/usr/share/icons/hicolor/scalable/apps/dnssec-trigger-alert.svg $(INSTALL) -c -m 644 $(srcdir)/panel/status-icon.png $(DESTDIR)/usr/share/icons/hicolor/64x64/apps/dnssec-trigger.png $(INSTALL) -c -m 644 $(srcdir)/panel/status-icon-alert.png $(DESTDIR)/usr/share/icons/hicolor/64x64/apps/dnssec-trigger-alert.png gtk-update-icon-cache $(DESTDIR)/usr/share/icons/hicolor endif if test -n "$(xdg_autostart_dir)"; then \ $(INSTALL) -m 755 -d $(DESTDIR)$(xdg_autostart_dir) ; \ $(INSTALL) -c -m 644 dnssec-trigger-panel.desktop $(DESTDIR)$(xdg_autostart_dir)/dnssec-trigger-panel.desktop ; fi gtk-gui-uninstall: rm -f $(DESTDIR)$(bindir)/dnssec-trigger-panel$(EXEEXT) rm -f $(DESTDIR)$(uidir)/pui.xml rm -f $(DESTDIR)$(uidir)/status-icon.png rm -f $(DESTDIR)$(uidir)/status-icon-alert.png ifeq "$(APP_INDICATOR)" "yes" rm -f $(DESTDIR)/usr/share/icons/hicolor/scalable/apps/dnssec-trigger.svg rm -f $(DESTDIR)/usr/share/icons/hicolor/scalable/apps/dnssec-trigger-alert.svg rm -f $(DESTDIR)/usr/share/icons/hicolor/64x64/apps/dnssec-trigger.png rm -f $(DESTDIR)/usr/share/icons/hicolor/64x64/apps/dnssec-trigger-alert.png gtk-update-icon-cache $(DESTDIR)/usr/share/icons/hicolor endif if test -n "$(xdg_autostart_dir)"; then \ rm -f $(DESTDIR)$(xdg_autostart_dir)/dnssec-trigger-panel.desktop ; fi install: all $(installgui) $(installhook) $(INSTALL) -m 755 -d $(DESTDIR)$(sbindir) $(INSTALL) -m 755 -d $(DESTDIR)$(mandir) $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man8 $(INSTALL) -m 755 -d $(DESTDIR)$(keydir) -$(INSTALL) -m 755 -d "`dirname $(DESTDIR)$(pidfile)`" $(INSTALL) -c -m 644 dnssec-trigger.8 $(DESTDIR)$(mandir)/man8/dnssec-trigger.8 $(INSTALL) -c -m 755 dnssec-trigger-control-setup $(DESTDIR)$(sbindir)/dnssec-trigger-control-setup $(INSTALL) -c -m 755 dnssec-trigger-control$(EXEEXT) $(DESTDIR)$(sbindir)/dnssec-trigger-control$(EXEEXT) $(INSTALL) -c -m 755 dnssec-triggerd$(EXEEXT) $(DESTDIR)$(sbindir)/dnssec-triggerd$(EXEEXT) if test ! -f $(DESTDIR)/etc/resolv.conf~ -a -f $(DESTDIR)/etc/resolv.conf; then \ cp $(DESTDIR)/etc/resolv.conf $(DESTDIR)/etc/resolv.conf~; fi if test ! -f $(DESTDIR)$(configfile); then \ $(INSTALL) -c -m 644 example.conf $(DESTDIR)$(configfile); fi @if test ! -f $(DESTDIR)$(keydir)/dnssec-trigger_server.key; then echo "It is probably good to run dnssec-trigger-control-setup to generate keys now, and possibly run dnssec-trigger-control-setup -i to edit unbound.conf if it does not have a trust anchor and remote-control"; fi @if test -f $(DESTDIR)$(configfile); then \ if grep "ssl443" $(DESTDIR)$(configfile) >/dev/null; then : ; else echo "You should update your config file ($(DESTDIR)$(configfile)) with the ssl443 settings from the example.conf."; fi; fi uninstall: $(uninstallgui) $(uninstallhook) rm -f $(DESTDIR)$(mandir)/man8/dnssec-trigger.8 rm -f $(DESTDIR)$(sbindir)/dnssec-trigger-control-setup rm -f $(DESTDIR)$(sbindir)/dnssec-trigger-control$(EXEEXT) rm -f $(DESTDIR)$(sbindir)/dnssec-triggerd$(EXEEXT) chmod 644 /etc/resolv.conf if test -f $(DESTDIR)/etc/resolv.conf~; then \ cp $(DESTDIR)/etc/resolv.conf~ $(DESTDIR)/etc/resolv.conf; fi @echo @echo "You still need to remove ssl keys from $(DESTDIR)$(keydir) and $(DESTDIR)$(configfile) by hand" # Automatic dependencies. $(BUILD)%.d: $(srcdir)/%.c $(INFO) Depend $< @-if test ! -d $(dir $@); then $(INSTALL) -d $(patsubst %/,%,$(dir $@)); fi $Q$(SHELL) -ec '$(CC) $(DEPFLAG) $(CPPFLAGS) $(CFLAGS) $< | sed '\''s!\(.*\)\.o[ :]*!$(dir $@)\1.o $@ : !g'\'' > $@; [ -s $@ ] || rm -f $@' ifneq ($(MAKECMDGOALS),clean) ifneq ($(MAKECMDGOALS),realclean) ifeq ($(debug_enabled),yes) -include $(addprefix $(BUILD),$(ALL_SRC:.c=.d) $(COMPAT_SRC:.c=.d)) endif endif endif dnssec-trigger-0.13/configure0000775000175000017500000072432513017046016015735 0ustar wouterwouter#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for dnssec-trigger 0.13. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and labs@nlnetlabs.nl $0: about your system, including any error possibly output $0: before this message. Then install a modern shell, or $0: manually run the script under such a shell if you do $0: have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='dnssec-trigger' PACKAGE_TARNAME='dnssec-trigger' PACKAGE_VERSION='0.13' PACKAGE_STRING='dnssec-trigger 0.13' PACKAGE_BUGREPORT='labs@nlnetlabs.nl' PACKAGE_URL='' # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='LTLIBOBJS DATE LDNSLIBS ldnsdir unbound_control_path PYTHON pidfile configfile uidir keydir check_updates login_location login_command xdg_autostart_dir APP_INDICATOR GTK_LIBS GTK_CFLAGS gui hooks netconfig_dispatcher_dir networkmanager_dispatcher_dir WINDRES UB_ON_WINDOWS ssldir RUNTIME_PATH HAVE_SSL LIBOBJS STRIP EXPORT_DYNAMIC debug_enabled DEPFLAG EGREP GREP CPP OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_debug enable_static_exe enable_largefile with_ssl with_hooks with_networkmanager_dispatch with_netconfig_dispatch with_gui enable_appindicator with_xdg_autostart with_login_command with_login_location with_check_updates with_keydir with_uidir with_configfile with_pidfile with_python with_unbound_control with_ldns enable_rpath ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures dnssec-trigger 0.13 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/dnssec-trigger] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of dnssec-trigger 0.13:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-debug Enable debug warnings, asserts, makefile-dependencies --enable-static-exe enable to compile executables statically against ldns and crypto libs --disable-largefile omit support for large files --enable-appindicator=[no/auto/yes] Build support for application indicators (for Ubuntu Unity) --disable-rpath disable hardcoded rpath (default=enabled) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-ssl=pathname enable SSL (will check /usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr) --with-hooks Set the DHCP change hooks to use, default 'auto', can be 'osx', 'networkmanager', 'netconfig', 'windows' or 'none' --with-networkmanager-dispatch Set the networkmanager dhcp dispatcher dir, default tests prefix/etc/NetworkManager/dispatcher.d and /etc/NetworkManager/dispatcher.d --with-netconfig-dispatch Set the netconfig dhcp dispatcher dir, default tests prefix/etc/netconfig.d and /etc/netconfig.d --with-gui Set the user interface style to use, default 'auto', can be 'cocoa' (on OSX), 'windows' or 'gtk' --with-xdg-autostart Set the GNOME autostart dir, default tests prefix/etc/xdg/autostart and /etc/xdg/autostart --with-login-command Set the command to start login, a web browser, default 'auto' --with-login-location Set the url location to login, default 'auto' --with-check-updates=yesno Set default value for check-updates config option --with-keydir=path Set the directory where ssl key files are kept, read by daemon and other tools, default prefix/etc --with-uidir=path Set the directory where ui files (icon,xml) are kept, default prefix/share/dnssec-trigger --with-configfile=path set the configfile to use, default keydir/dnssec-trigger.conf --with-pidfile=path set the pidfile to use, default /var/run/dnssec-trigger.pid --with-python=path set the path to Python interpreter to use for Python scripts, defaults /usr/bin/python --with-unbound-control=path set the unbound-control to use, default what configure finds in its path --with-ldns=PATH specify prefix of path of ldns library to use Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF dnssec-trigger configure 0.13 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## -------------------------------- ## ## Report this to labs@nlnetlabs.nl ## ## -------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by dnssec-trigger $as_me 0.13, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" if test "x$ac_cv_header_minix_config_h" = xyes; then : MINIX=yes else MINIX= fi if test "$MINIX" = yes; then $as_echo "#define _POSIX_SOURCE 1" >>confdefs.h $as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h $as_echo "#define _MINIX 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 $as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } if ${ac_cv_safe_to_define___extensions__+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ # define __EXTENSIONS__ 1 $ac_includes_default int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_safe_to_define___extensions__=yes else ac_cv_safe_to_define___extensions__=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 $as_echo "$ac_cv_safe_to_define___extensions__" >&6; } test $ac_cv_safe_to_define___extensions__ = yes && $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h $as_echo "#define _ALL_SOURCE 1" >>confdefs.h $as_echo "#define _GNU_SOURCE 1" >>confdefs.h $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu case "$prefix" in NONE) prefix="/usr/local" ;; esac if test "$exec_prefix" == "NONE"; then exec_prefix="$prefix" fi # are we on MinGW? if uname -s 2>&1 | grep MINGW32 >/dev/null; then on_mingw="yes" else if echo $target | grep mingw32 >/dev/null; then on_mingw="yes" else on_mingw="no"; fi fi $as_echo "#define WINVER 0x0502" >>confdefs.h wnvs=`echo $PACKAGE_VERSION.0.0 | sed -e 's/^[^0-9]*\([0-9]\)[^0-9]*\([0-9]\)[^0-9]*\([0-9]\)[^0-9]*\([0-9]\).*$/\1,\2,\3,\4/' -e 's/^[^0-9]*\([0-9]\)[^0-9]*\([0-9]\)[^0-9]*\([0-9]\)[^0-9]*$/\1,\2,\3,0/' ` cat >>confdefs.h <<_ACEOF #define RSRC_PACKAGE_VERSION $wnvs _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking $CC dependency flag" >&5 $as_echo_n "checking $CC dependency flag... " >&6; } echo 'void f(){}' >conftest.c if test "`$CC -MM conftest.c 2>&1`" = "conftest.o: conftest.c"; then DEPFLAG="-MM" else if test "`$CC -xM1 conftest.c 2>&1`" = "conftest.o: conftest.c"; then DEPFLAG="-xM1" else DEPFLAG="-MM" # dunno do something fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DEPFLAG" >&5 $as_echo "$DEPFLAG" >&6; } rm -f conftest.c { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Werror" >&5 $as_echo_n "checking whether $CC supports -Werror... " >&6; } cache=`echo Werror | sed 'y%.=/+-%___p_%'` if eval \${cv_prog_cc_flag_$cache+:} false; then : $as_echo_n "(cached) " >&6 else echo 'void f(void){}' >conftest.c if test -z "`$CC $CPPFLAGS $CFLAGS -Werror -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_$cache=yes" else eval "cv_prog_cc_flag_$cache=no" fi rm -f conftest conftest.o conftest.c fi if eval "test \"`echo '$cv_prog_cc_flag_'$cache`\" = yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : ERRFLAG="-Werror" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } : ERRFLAG="-errwarn" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wall" >&5 $as_echo_n "checking whether $CC supports -Wall... " >&6; } cache=`echo Wall | sed 'y%.=/+-%___p_%'` if eval \${cv_prog_cc_flag_$cache+:} false; then : $as_echo_n "(cached) " >&6 else echo 'void f(void){}' >conftest.c if test -z "`$CC $CPPFLAGS $CFLAGS -Wall -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_$cache=yes" else eval "cv_prog_cc_flag_$cache=no" fi rm -f conftest conftest.o conftest.c fi if eval "test \"`echo '$cv_prog_cc_flag_'$cache`\" = yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : ERRFLAG="$ERRFLAG -Wall" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } : ERRFLAG="$ERRFLAG -errfmt" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -std=c99" >&5 $as_echo_n "checking whether $CC supports -std=c99... " >&6; } cache=`echo std=c99 | sed 'y%.=/+-%___p_%'` if eval \${cv_prog_cc_flag_$cache+:} false; then : $as_echo_n "(cached) " >&6 else echo 'void f(void){}' >conftest.c if test -z "`$CC $CPPFLAGS $CFLAGS -std=c99 -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_$cache=yes" else eval "cv_prog_cc_flag_$cache=no" fi rm -f conftest conftest.o conftest.c fi if eval "test \"`echo '$cv_prog_cc_flag_'$cache`\" = yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : C99FLAG="-std=c99" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } : fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -xc99" >&5 $as_echo_n "checking whether $CC supports -xc99... " >&6; } cache=`echo xc99 | sed 'y%.=/+-%___p_%'` if eval \${cv_prog_cc_flag_$cache+:} false; then : $as_echo_n "(cached) " >&6 else echo 'void f(void){}' >conftest.c if test -z "`$CC $CPPFLAGS $CFLAGS -xc99 -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_$cache=yes" else eval "cv_prog_cc_flag_$cache=no" fi rm -f conftest conftest.o conftest.c fi if eval "test \"`echo '$cv_prog_cc_flag_'$cache`\" = yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : C99FLAG="-xc99" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } : fi for ac_header in getopt.h time.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we need $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE as a flag for $CC" >&5 $as_echo_n "checking whether we need $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE as a flag for $CC... " >&6; } cache=`$as_echo "$C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE" | $as_tr_sh` if eval \${cv_prog_cc_flag_needed_$cache+:} false; then : $as_echo_n "(cached) " >&6 else echo ' #include "confdefs.h" #include #include #include #ifdef HAVE_TIME_H #include #endif #include #include #ifdef HAVE_GETOPT_H #include #endif int test() { int a; char **opts = NULL; struct timeval tv; char *t; time_t time = 0; char *buf = NULL; const char* str = NULL; struct msghdr msg; msg.msg_control = 0; t = ctime_r(&time, buf); tv.tv_usec = 10; srandom(32); a = getopt(2, opts, "a"); a = isascii(32); str = gai_strerror(0); if(str && t && tv.tv_usec && msg.msg_control) a = 0; return a; } ' > conftest.c echo 'void f(){}' >>conftest.c if test -z "`$CC $CPPFLAGS $CFLAGS $ERRFLAG -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_needed_$cache=no" else if test -z "`$CC $CPPFLAGS $CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE $ERRFLAG -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_needed_$cache=yes" else eval "cv_prog_cc_flag_needed_$cache=fail" #echo 'Test with flag fails too!' #cat conftest.c #echo "$CC $CPPFLAGS $CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE $ERRFLAG -c conftest.c 2>&1" #echo `$CC $CPPFLAGS $CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE $ERRFLAG -c conftest.c 2>&1` #exit 1 fi fi rm -f conftest conftest.c conftest.o fi if eval "test \"`echo '$cv_prog_cc_flag_needed_'$cache`\" = yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : CFLAGS="$CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE" else if eval "test \"`echo '$cv_prog_cc_flag_needed_'$cache`\" = no"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } #echo 'Test with flag is no!' #cat conftest.c #echo "$CC $CPPFLAGS $CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE $ERRFLAG -c conftest.c 2>&1" #echo `$CC $CPPFLAGS $CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE $ERRFLAG -c conftest.c 2>&1` #exit 1 : else { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } : fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we need $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE as a flag for $CC" >&5 $as_echo_n "checking whether we need $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE as a flag for $CC... " >&6; } cache=`$as_echo "$C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE" | $as_tr_sh` if eval \${cv_prog_cc_flag_needed_$cache+:} false; then : $as_echo_n "(cached) " >&6 else echo ' #include "confdefs.h" #include #include #include #ifdef HAVE_TIME_H #include #endif #include #include #ifdef HAVE_GETOPT_H #include #endif int test() { int a; char **opts = NULL; struct timeval tv; char *t; time_t time = 0; char *buf = NULL; const char* str = NULL; struct msghdr msg; msg.msg_control = 0; t = ctime_r(&time, buf); tv.tv_usec = 10; srandom(32); a = getopt(2, opts, "a"); a = isascii(32); str = gai_strerror(0); if(str && t && tv.tv_usec && msg.msg_control) a = 0; return a; } ' > conftest.c echo 'void f(){}' >>conftest.c if test -z "`$CC $CPPFLAGS $CFLAGS $ERRFLAG -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_needed_$cache=no" else if test -z "`$CC $CPPFLAGS $CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE $ERRFLAG -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_needed_$cache=yes" else eval "cv_prog_cc_flag_needed_$cache=fail" #echo 'Test with flag fails too!' #cat conftest.c #echo "$CC $CPPFLAGS $CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE $ERRFLAG -c conftest.c 2>&1" #echo `$CC $CPPFLAGS $CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE $ERRFLAG -c conftest.c 2>&1` #exit 1 fi fi rm -f conftest conftest.c conftest.o fi if eval "test \"`echo '$cv_prog_cc_flag_needed_'$cache`\" = yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : CFLAGS="$CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE" else if eval "test \"`echo '$cv_prog_cc_flag_needed_'$cache`\" = no"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } #echo 'Test with flag is no!' #cat conftest.c #echo "$CC $CPPFLAGS $CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE $ERRFLAG -c conftest.c 2>&1" #echo `$CC $CPPFLAGS $CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE $ERRFLAG -c conftest.c 2>&1` #exit 1 : else { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } : fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we need $C99FLAG as a flag for $CC" >&5 $as_echo_n "checking whether we need $C99FLAG as a flag for $CC... " >&6; } cache=`$as_echo "$C99FLAG" | $as_tr_sh` if eval \${cv_prog_cc_flag_needed_$cache+:} false; then : $as_echo_n "(cached) " >&6 else echo ' #include #include int test() { int a = 0; return a; } ' > conftest.c echo 'void f(){}' >>conftest.c if test -z "`$CC $CPPFLAGS $CFLAGS $ERRFLAG -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_needed_$cache=no" else if test -z "`$CC $CPPFLAGS $CFLAGS $C99FLAG $ERRFLAG -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_needed_$cache=yes" else eval "cv_prog_cc_flag_needed_$cache=fail" #echo 'Test with flag fails too!' #cat conftest.c #echo "$CC $CPPFLAGS $CFLAGS $C99FLAG $ERRFLAG -c conftest.c 2>&1" #echo `$CC $CPPFLAGS $CFLAGS $C99FLAG $ERRFLAG -c conftest.c 2>&1` #exit 1 fi fi rm -f conftest conftest.c conftest.o fi if eval "test \"`echo '$cv_prog_cc_flag_needed_'$cache`\" = yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : CFLAGS="$CFLAGS $C99FLAG" else if eval "test \"`echo '$cv_prog_cc_flag_needed_'$cache`\" = no"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } #echo 'Test with flag is no!' #cat conftest.c #echo "$CC $CPPFLAGS $CFLAGS $C99FLAG $ERRFLAG -c conftest.c 2>&1" #echo `$CC $CPPFLAGS $CFLAGS $C99FLAG $ERRFLAG -c conftest.c 2>&1` #exit 1 : else { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } : fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we need -D_BSD_SOURCE -D_DEFAULT_SOURCE as a flag for $CC" >&5 $as_echo_n "checking whether we need -D_BSD_SOURCE -D_DEFAULT_SOURCE as a flag for $CC... " >&6; } cache=_D_BSD_SOURCE__D_DEFAULT_SOURCE if eval \${cv_prog_cc_flag_needed_$cache+:} false; then : $as_echo_n "(cached) " >&6 else echo ' #include int test() { int a; a = isascii(32); return a; } ' > conftest.c echo 'void f(){}' >>conftest.c if test -z "`$CC $CPPFLAGS $CFLAGS $ERRFLAG -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_needed_$cache=no" else if test -z "`$CC $CPPFLAGS $CFLAGS -D_BSD_SOURCE -D_DEFAULT_SOURCE $ERRFLAG -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_needed_$cache=yes" else eval "cv_prog_cc_flag_needed_$cache=fail" #echo 'Test with flag fails too!' #cat conftest.c #echo "$CC $CPPFLAGS $CFLAGS -D_BSD_SOURCE -D_DEFAULT_SOURCE $ERRFLAG -c conftest.c 2>&1" #echo `$CC $CPPFLAGS $CFLAGS -D_BSD_SOURCE -D_DEFAULT_SOURCE $ERRFLAG -c conftest.c 2>&1` #exit 1 fi fi rm -f conftest conftest.c conftest.o fi if eval "test \"`echo '$cv_prog_cc_flag_needed_'$cache`\" = yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : CFLAGS="$CFLAGS -D_BSD_SOURCE -D_DEFAULT_SOURCE" else if eval "test \"`echo '$cv_prog_cc_flag_needed_'$cache`\" = no"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } #echo 'Test with flag is no!' #cat conftest.c #echo "$CC $CPPFLAGS $CFLAGS -D_BSD_SOURCE -D_DEFAULT_SOURCE $ERRFLAG -c conftest.c 2>&1" #echo `$CC $CPPFLAGS $CFLAGS -D_BSD_SOURCE -D_DEFAULT_SOURCE $ERRFLAG -c conftest.c 2>&1` #exit 1 : else { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } : fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we need -D_GNU_SOURCE as a flag for $CC" >&5 $as_echo_n "checking whether we need -D_GNU_SOURCE as a flag for $CC... " >&6; } cache=_D_GNU_SOURCE if eval \${cv_prog_cc_flag_needed_$cache+:} false; then : $as_echo_n "(cached) " >&6 else echo ' #include int test() { struct in6_pktinfo inf; int a = (int)sizeof(inf); return a; } ' > conftest.c echo 'void f(){}' >>conftest.c if test -z "`$CC $CPPFLAGS $CFLAGS $ERRFLAG -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_needed_$cache=no" else if test -z "`$CC $CPPFLAGS $CFLAGS -D_GNU_SOURCE $ERRFLAG -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_needed_$cache=yes" else eval "cv_prog_cc_flag_needed_$cache=fail" #echo 'Test with flag fails too!' #cat conftest.c #echo "$CC $CPPFLAGS $CFLAGS -D_GNU_SOURCE $ERRFLAG -c conftest.c 2>&1" #echo `$CC $CPPFLAGS $CFLAGS -D_GNU_SOURCE $ERRFLAG -c conftest.c 2>&1` #exit 1 fi fi rm -f conftest conftest.c conftest.o fi if eval "test \"`echo '$cv_prog_cc_flag_needed_'$cache`\" = yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : CFLAGS="$CFLAGS -D_GNU_SOURCE" else if eval "test \"`echo '$cv_prog_cc_flag_needed_'$cache`\" = no"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } #echo 'Test with flag is no!' #cat conftest.c #echo "$CC $CPPFLAGS $CFLAGS -D_GNU_SOURCE $ERRFLAG -c conftest.c 2>&1" #echo `$CC $CPPFLAGS $CFLAGS -D_GNU_SOURCE $ERRFLAG -c conftest.c 2>&1` #exit 1 : else { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } : fi fi # check again for GNU_SOURCE for setresgid. May fail if setresgid # is not available at all. -D_FRSRESGID is to make this check unique. # otherwise we would get the previous cached result. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we need -D_GNU_SOURCE -D_FRSRESGID as a flag for $CC" >&5 $as_echo_n "checking whether we need -D_GNU_SOURCE -D_FRSRESGID as a flag for $CC... " >&6; } cache=_D_GNU_SOURCE__D_FRSRESGID if eval \${cv_prog_cc_flag_needed_$cache+:} false; then : $as_echo_n "(cached) " >&6 else echo ' #include int test() { int a = setresgid(0,0,0); a = setresuid(0,0,0); return a; } ' > conftest.c echo 'void f(){}' >>conftest.c if test -z "`$CC $CPPFLAGS $CFLAGS $ERRFLAG -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_needed_$cache=no" else if test -z "`$CC $CPPFLAGS $CFLAGS -D_GNU_SOURCE -D_FRSRESGID $ERRFLAG -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_needed_$cache=yes" else eval "cv_prog_cc_flag_needed_$cache=fail" #echo 'Test with flag fails too!' #cat conftest.c #echo "$CC $CPPFLAGS $CFLAGS -D_GNU_SOURCE -D_FRSRESGID $ERRFLAG -c conftest.c 2>&1" #echo `$CC $CPPFLAGS $CFLAGS -D_GNU_SOURCE -D_FRSRESGID $ERRFLAG -c conftest.c 2>&1` #exit 1 fi fi rm -f conftest conftest.c conftest.o fi if eval "test \"`echo '$cv_prog_cc_flag_needed_'$cache`\" = yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : CFLAGS="$CFLAGS -D_GNU_SOURCE" else if eval "test \"`echo '$cv_prog_cc_flag_needed_'$cache`\" = no"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } #echo 'Test with flag is no!' #cat conftest.c #echo "$CC $CPPFLAGS $CFLAGS -D_GNU_SOURCE -D_FRSRESGID $ERRFLAG -c conftest.c 2>&1" #echo `$CC $CPPFLAGS $CFLAGS -D_GNU_SOURCE -D_FRSRESGID $ERRFLAG -c conftest.c 2>&1` #exit 1 : else { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } : fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we need -D_POSIX_C_SOURCE=200112 as a flag for $CC" >&5 $as_echo_n "checking whether we need -D_POSIX_C_SOURCE=200112 as a flag for $CC... " >&6; } cache=_D_POSIX_C_SOURCE_200112 if eval \${cv_prog_cc_flag_needed_$cache+:} false; then : $as_echo_n "(cached) " >&6 else echo ' #include "confdefs.h" #ifdef HAVE_TIME_H #include #endif #include int test() { int a = 0; char *t; time_t time = 0; char *buf = NULL; const char* str = NULL; t = ctime_r(&time, buf); str = gai_strerror(0); if(t && str) a = 0; return a; } ' > conftest.c echo 'void f(){}' >>conftest.c if test -z "`$CC $CPPFLAGS $CFLAGS $ERRFLAG -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_needed_$cache=no" else if test -z "`$CC $CPPFLAGS $CFLAGS -D_POSIX_C_SOURCE=200112 $ERRFLAG -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_needed_$cache=yes" else eval "cv_prog_cc_flag_needed_$cache=fail" #echo 'Test with flag fails too!' #cat conftest.c #echo "$CC $CPPFLAGS $CFLAGS -D_POSIX_C_SOURCE=200112 $ERRFLAG -c conftest.c 2>&1" #echo `$CC $CPPFLAGS $CFLAGS -D_POSIX_C_SOURCE=200112 $ERRFLAG -c conftest.c 2>&1` #exit 1 fi fi rm -f conftest conftest.c conftest.o fi if eval "test \"`echo '$cv_prog_cc_flag_needed_'$cache`\" = yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : CFLAGS="$CFLAGS -D_POSIX_C_SOURCE=200112" else if eval "test \"`echo '$cv_prog_cc_flag_needed_'$cache`\" = no"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } #echo 'Test with flag is no!' #cat conftest.c #echo "$CC $CPPFLAGS $CFLAGS -D_POSIX_C_SOURCE=200112 $ERRFLAG -c conftest.c 2>&1" #echo `$CC $CPPFLAGS $CFLAGS -D_POSIX_C_SOURCE=200112 $ERRFLAG -c conftest.c 2>&1` #exit 1 : else { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } : fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we need -D__EXTENSIONS__ as a flag for $CC" >&5 $as_echo_n "checking whether we need -D__EXTENSIONS__ as a flag for $CC... " >&6; } cache=_D__EXTENSIONS__ if eval \${cv_prog_cc_flag_needed_$cache+:} false; then : $as_echo_n "(cached) " >&6 else echo ' #include "confdefs.h" #include #include #include #ifdef HAVE_TIME_H #include #endif #include #ifdef HAVE_GETOPT_H #include #endif int test() { int a; char **opts = NULL; struct timeval tv; tv.tv_usec = 10; srandom(32); a = getopt(2, opts, "a"); a = isascii(32); if(tv.tv_usec) a = 0; return a; } ' > conftest.c echo 'void f(){}' >>conftest.c if test -z "`$CC $CPPFLAGS $CFLAGS $ERRFLAG -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_needed_$cache=no" else if test -z "`$CC $CPPFLAGS $CFLAGS -D__EXTENSIONS__ $ERRFLAG -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_needed_$cache=yes" else eval "cv_prog_cc_flag_needed_$cache=fail" #echo 'Test with flag fails too!' #cat conftest.c #echo "$CC $CPPFLAGS $CFLAGS -D__EXTENSIONS__ $ERRFLAG -c conftest.c 2>&1" #echo `$CC $CPPFLAGS $CFLAGS -D__EXTENSIONS__ $ERRFLAG -c conftest.c 2>&1` #exit 1 fi fi rm -f conftest conftest.c conftest.o fi if eval "test \"`echo '$cv_prog_cc_flag_needed_'$cache`\" = yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : CFLAGS="$CFLAGS -D__EXTENSIONS__" else if eval "test \"`echo '$cv_prog_cc_flag_needed_'$cache`\" = no"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } #echo 'Test with flag is no!' #cat conftest.c #echo "$CC $CPPFLAGS $CFLAGS -D__EXTENSIONS__ $ERRFLAG -c conftest.c 2>&1" #echo `$CC $CPPFLAGS $CFLAGS -D__EXTENSIONS__ $ERRFLAG -c conftest.c 2>&1` #exit 1 : else { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } : fi fi for ac_header in getopt.h time.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # flag warnings. # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then : enableval=$enable_debug; fi debug_enabled="$enable_debug" case "$enable_debug" in yes) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -W" >&5 $as_echo_n "checking whether $CC supports -W... " >&6; } cache=`echo W | sed 'y%.=/+-%___p_%'` if eval \${cv_prog_cc_flag_$cache+:} false; then : $as_echo_n "(cached) " >&6 else echo 'void f(void){}' >conftest.c if test -z "`$CC $CPPFLAGS $CFLAGS -W -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_$cache=yes" else eval "cv_prog_cc_flag_$cache=no" fi rm -f conftest conftest.o conftest.c fi if eval "test \"`echo '$cv_prog_cc_flag_'$cache`\" = yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : CFLAGS="$CFLAGS -W" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } : fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wall" >&5 $as_echo_n "checking whether $CC supports -Wall... " >&6; } cache=`echo Wall | sed 'y%.=/+-%___p_%'` if eval \${cv_prog_cc_flag_$cache+:} false; then : $as_echo_n "(cached) " >&6 else echo 'void f(void){}' >conftest.c if test -z "`$CC $CPPFLAGS $CFLAGS -Wall -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_$cache=yes" else eval "cv_prog_cc_flag_$cache=no" fi rm -f conftest conftest.o conftest.c fi if eval "test \"`echo '$cv_prog_cc_flag_'$cache`\" = yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : CFLAGS="$CFLAGS -Wall" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } : fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wextra" >&5 $as_echo_n "checking whether $CC supports -Wextra... " >&6; } cache=`echo Wextra | sed 'y%.=/+-%___p_%'` if eval \${cv_prog_cc_flag_$cache+:} false; then : $as_echo_n "(cached) " >&6 else echo 'void f(void){}' >conftest.c if test -z "`$CC $CPPFLAGS $CFLAGS -Wextra -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_$cache=yes" else eval "cv_prog_cc_flag_$cache=no" fi rm -f conftest conftest.o conftest.c fi if eval "test \"`echo '$cv_prog_cc_flag_'$cache`\" = yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : CFLAGS="$CFLAGS -Wextra" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } : fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wdeclaration-after-statement" >&5 $as_echo_n "checking whether $CC supports -Wdeclaration-after-statement... " >&6; } cache=`echo Wdeclaration-after-statement | sed 'y%.=/+-%___p_%'` if eval \${cv_prog_cc_flag_$cache+:} false; then : $as_echo_n "(cached) " >&6 else echo 'void f(void){}' >conftest.c if test -z "`$CC $CPPFLAGS $CFLAGS -Wdeclaration-after-statement -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_$cache=yes" else eval "cv_prog_cc_flag_$cache=no" fi rm -f conftest conftest.o conftest.c fi if eval "test \"`echo '$cv_prog_cc_flag_'$cache`\" = yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : CFLAGS="$CFLAGS -Wdeclaration-after-statement" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } : fi $as_echo "#define DO_DEBUG /**/" >>confdefs.h ;; no|*) # nothing to do. ;; esac if test "$on_mingw" = "yes"; then # this flag is only really needed for GTK+ applications for its # linkback of event functions. EXPORT_DYNAMIC="-Wl,-export-all-symbols" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking if -export-dynamic works" >&5 $as_echo_n "checking if -export-dynamic works... " >&6; } bakld="$LDFLAGS" LDFLAGS="$LDFLAGS -export-dynamic" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main(void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } EXPORT_DYNAMIC="-export-dynamic" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$bakld" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if ${ac_cv_c_inline+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_inline=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 $as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler (${CC-cc}) accepts the \"format\" attribute" >&5 $as_echo_n "checking whether the C compiler (${CC-cc}) accepts the \"format\" attribute... " >&6; } if ${ac_cv_c_format_attribute+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_format_attribute=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include void f (char *format, ...) __attribute__ ((format (printf, 1, 2))); void (*pf) (char *format, ...) __attribute__ ((format (printf, 1, 2))); int main () { f ("%s", "str"); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_format_attribute="yes" else ac_cv_c_format_attribute="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_format_attribute" >&5 $as_echo "$ac_cv_c_format_attribute" >&6; } if test $ac_cv_c_format_attribute = yes; then $as_echo "#define HAVE_ATTR_FORMAT 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler (${CC-cc}) accepts the \"unused\" attribute" >&5 $as_echo_n "checking whether the C compiler (${CC-cc}) accepts the \"unused\" attribute... " >&6; } if ${ac_cv_c_unused_attribute+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_unused_attribute=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include void f (char *u __attribute__((unused))); int main () { f ("x"); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_unused_attribute="yes" else ac_cv_c_unused_attribute="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_unused_attribute" >&5 $as_echo "$ac_cv_c_unused_attribute" >&6; } if test $ac_cv_c_unused_attribute = yes; then $as_echo "#define HAVE_ATTR_UNUSED 1" >>confdefs.h fi if test "$srcdir" != "."; then CPPFLAGS="$CPPFLAGS -I$srcdir" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi # Checks for header files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi for ac_header in stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # MinGW32 tests if test "$on_mingw" = "yes"; then for ac_header in windows.h winsock2.h ws2tcpip.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done fi # end mingw32 tests # check for types ac_fn_c_check_type "$LINENO" "int8_t" "ac_cv_type_int8_t" "$ac_includes_default" if test "x$ac_cv_type_int8_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define int8_t char _ACEOF fi ac_fn_c_check_type "$LINENO" "int16_t" "ac_cv_type_int16_t" "$ac_includes_default" if test "x$ac_cv_type_int16_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define int16_t short _ACEOF fi ac_fn_c_check_type "$LINENO" "int32_t" "ac_cv_type_int32_t" "$ac_includes_default" if test "x$ac_cv_type_int32_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define int32_t int _ACEOF fi ac_fn_c_check_type "$LINENO" "int64_t" "ac_cv_type_int64_t" "$ac_includes_default" if test "x$ac_cv_type_int64_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define int64_t long long _ACEOF fi ac_fn_c_check_type "$LINENO" "uint8_t" "ac_cv_type_uint8_t" "$ac_includes_default" if test "x$ac_cv_type_uint8_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define uint8_t unsigned char _ACEOF fi ac_fn_c_check_type "$LINENO" "uint16_t" "ac_cv_type_uint16_t" "$ac_includes_default" if test "x$ac_cv_type_uint16_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define uint16_t unsigned short _ACEOF fi ac_fn_c_check_type "$LINENO" "uint32_t" "ac_cv_type_uint32_t" "$ac_includes_default" if test "x$ac_cv_type_uint32_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define uint32_t unsigned int _ACEOF fi ac_fn_c_check_type "$LINENO" "uint64_t" "ac_cv_type_uint64_t" "$ac_includes_default" if test "x$ac_cv_type_uint64_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define uint64_t unsigned long long _ACEOF fi ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default" if test "x$ac_cv_type_ssize_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define ssize_t int _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5 $as_echo_n "checking for uid_t in sys/types.h... " >&6; } if ${ac_cv_type_uid_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "uid_t" >/dev/null 2>&1; then : ac_cv_type_uid_t=yes else ac_cv_type_uid_t=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5 $as_echo "$ac_cv_type_uid_t" >&6; } if test $ac_cv_type_uid_t = no; then $as_echo "#define uid_t int" >>confdefs.h $as_echo "#define gid_t int" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" if test "x$ac_cv_type_pid_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define pid_t int _ACEOF fi ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" if test "x$ac_cv_type_off_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define off_t long int _ACEOF fi ac_fn_c_check_type "$LINENO" "u_char" "ac_cv_type_u_char" " $ac_includes_default #ifdef HAVE_SYS_SOCKET_H # include #endif #ifdef HAVE_WS2TCPIP_H # include #endif " if test "x$ac_cv_type_u_char" = xyes; then : else $as_echo "#define u_char unsigned char" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "rlim_t" "ac_cv_type_rlim_t" " $ac_includes_default #ifdef HAVE_SYS_RESOURCE_H # include #endif " if test "x$ac_cv_type_rlim_t" = xyes; then : else $as_echo "#define rlim_t unsigned long" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" " $ac_includes_default #ifdef HAVE_SYS_SOCKET_H # include #endif #ifdef HAVE_WS2TCPIP_H # include #endif " if test "x$ac_cv_type_socklen_t" = xyes; then : else $as_echo "#define socklen_t int" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "in_addr_t" "ac_cv_type_in_addr_t" " $ac_includes_default #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_NETINET_IN_H # include #endif " if test "x$ac_cv_type_in_addr_t" = xyes; then : else $as_echo "#define in_addr_t uint32_t" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "in_port_t" "ac_cv_type_in_port_t" " $ac_includes_default #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_NETINET_IN_H # include #endif " if test "x$ac_cv_type_in_port_t" = xyes; then : else $as_echo "#define in_port_t uint16_t" >>confdefs.h fi # check to see if libraries are needed for these functions. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing inet_pton" >&5 $as_echo_n "checking for library containing inet_pton... " >&6; } if ${ac_cv_search_inet_pton+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char inet_pton (); int main () { return inet_pton (); ; return 0; } _ACEOF for ac_lib in '' nsl; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_inet_pton=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_inet_pton+:} false; then : break fi done if ${ac_cv_search_inet_pton+:} false; then : else ac_cv_search_inet_pton=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_inet_pton" >&5 $as_echo "$ac_cv_search_inet_pton" >&6; } ac_res=$ac_cv_search_inet_pton if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing socket" >&5 $as_echo_n "checking for library containing socket... " >&6; } if ${ac_cv_search_socket+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char socket (); int main () { return socket (); ; return 0; } _ACEOF for ac_lib in '' socket; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_socket=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_socket+:} false; then : break fi done if ${ac_cv_search_socket+:} false; then : else ac_cv_search_socket=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_socket" >&5 $as_echo "$ac_cv_search_socket" >&6; } ac_res=$ac_cv_search_socket if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi # set static linking if requested staticexe="no" # Check whether --enable-static-exe was given. if test "${enable_static_exe+set}" = set; then : enableval=$enable_static_exe; fi if test x_$enable_static_exe = x_yes; then staticexe="yes" if test "$on_mingw" = yes; then staticexe="-all-static" # for static crosscompile, include gdi32 and zlib here. if test "`uname`" = "Linux"; then LIBS="$LIBS -lgdi32 -lz" fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5 $as_echo_n "checking for GNU libc compatible malloc... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no (crosscompile)" >&5 $as_echo "no (crosscompile)" >&6; } case " $LIBOBJS " in *" malloc.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS malloc.$ac_objext" ;; esac cat >>confdefs.h <<_ACEOF #define malloc rpl_malloc_dnssectrigger _ACEOF else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined STDC_HEADERS || defined HAVE_STDLIB_H #include #else char *malloc (); #endif int main () { if(malloc(0) != 0) return 1; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } case " $LIBOBJS " in *" malloc.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS malloc.$ac_objext" ;; esac cat >>confdefs.h <<_ACEOF #define malloc rpl_malloc_dnssectrigger _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_MALLOC 1" >>confdefs.h fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi for ac_header in unistd.h do : ac_fn_c_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default" if test "x$ac_cv_header_unistd_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UNISTD_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working chown" >&5 $as_echo_n "checking for working chown... " >&6; } if ${ac_cv_func_chown_works+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_chown_works=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default #include int main () { char *f = "conftest.chown"; struct stat before, after; if (creat (f, 0600) < 0) return 1; if (stat (f, &before) < 0) return 1; if (chown (f, (uid_t) -1, (gid_t) -1) == -1) return 1; if (stat (f, &after) < 0) return 1; return ! (before.st_uid == after.st_uid && before.st_gid == after.st_gid); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_chown_works=yes else ac_cv_func_chown_works=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f conftest.chown fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_chown_works" >&5 $as_echo "$ac_cv_func_chown_works" >&6; } if test $ac_cv_func_chown_works = yes; then $as_echo "#define HAVE_CHOWN 1" >>confdefs.h fi for ac_header in vfork.h do : ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default" if test "x$ac_cv_header_vfork_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_VFORK_H 1 _ACEOF fi done for ac_func in fork vfork do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done if test "x$ac_cv_func_fork" = xyes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5 $as_echo_n "checking for working fork... " >&6; } if ${ac_cv_func_fork_works+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_fork_works=cross else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { /* By Ruediger Kuhlmann. */ return fork () < 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_fork_works=yes else ac_cv_func_fork_works=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5 $as_echo "$ac_cv_func_fork_works" >&6; } else ac_cv_func_fork_works=$ac_cv_func_fork fi if test "x$ac_cv_func_fork_works" = xcross; then case $host in *-*-amigaos* | *-*-msdosdjgpp*) # Override, as these systems have only a dummy fork() stub ac_cv_func_fork_works=no ;; *) ac_cv_func_fork_works=yes ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5 $as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;} fi ac_cv_func_vfork_works=$ac_cv_func_vfork if test "x$ac_cv_func_vfork" = xyes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5 $as_echo_n "checking for working vfork... " >&6; } if ${ac_cv_func_vfork_works+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_vfork_works=cross else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Thanks to Paul Eggert for this test. */ $ac_includes_default #include #ifdef HAVE_VFORK_H # include #endif /* On some sparc systems, changes by the child to local and incoming argument registers are propagated back to the parent. The compiler is told about this with #include , but some compilers (e.g. gcc -O) don't grok . Test for this by using a static variable whose address is put into a register that is clobbered by the vfork. */ static void #ifdef __cplusplus sparc_address_test (int arg) # else sparc_address_test (arg) int arg; #endif { static pid_t child; if (!child) { child = vfork (); if (child < 0) { perror ("vfork"); _exit(2); } if (!child) { arg = getpid(); write(-1, "", 0); _exit (arg); } } } int main () { pid_t parent = getpid (); pid_t child; sparc_address_test (0); child = vfork (); if (child == 0) { /* Here is another test for sparc vfork register problems. This test uses lots of local variables, at least as many local variables as main has allocated so far including compiler temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should reuse the register of parent for one of the local variables, since it will think that parent can't possibly be used any more in this routine. Assigning to the local variable will thus munge parent in the parent process. */ pid_t p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); /* Convince the compiler that p..p7 are live; otherwise, it might use the same hardware register for all 8 local variables. */ if (p != p1 || p != p2 || p != p3 || p != p4 || p != p5 || p != p6 || p != p7) _exit(1); /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent from child file descriptors. If the child closes a descriptor before it execs or exits, this munges the parent's descriptor as well. Test for this by closing stdout in the child. */ _exit(close(fileno(stdout)) != 0); } else { int status; struct stat st; while (wait(&status) != child) ; return ( /* Was there some problem with vforking? */ child < 0 /* Did the child fail? (This shouldn't happen.) */ || status /* Did the vfork/compiler bug occur? */ || parent != getpid() /* Did the file descriptor bug occur? */ || fstat(fileno(stdout), &st) != 0 ); } } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_vfork_works=yes else ac_cv_func_vfork_works=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5 $as_echo "$ac_cv_func_vfork_works" >&6; } fi; if test "x$ac_cv_func_fork_works" = xcross; then ac_cv_func_vfork_works=$ac_cv_func_vfork { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5 $as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;} fi if test "x$ac_cv_func_vfork_works" = xyes; then $as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h else $as_echo "#define vfork fork" >>confdefs.h fi if test "x$ac_cv_func_fork_works" = xyes; then $as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 $as_echo_n "checking return type of signal handlers... " >&6; } if ${ac_cv_type_signal+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { return *(signal (0, 0)) (0) == 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_type_signal=int else ac_cv_type_signal=void fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 $as_echo "$ac_cv_type_signal" >&6; } cat >>confdefs.h <<_ACEOF #define RETSIGTYPE $ac_cv_type_signal _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5 $as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; } if ${ac_cv_sys_largefile_source+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* for off_t */ #include int main () { int (*fp) (FILE *, off_t, int) = fseeko; return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_sys_largefile_source=no; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _LARGEFILE_SOURCE 1 #include /* for off_t */ #include int main () { int (*fp) (FILE *, off_t, int) = fseeko; return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_sys_largefile_source=1; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_cv_sys_largefile_source=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5 $as_echo "$ac_cv_sys_largefile_source" >&6; } case $ac_cv_sys_largefile_source in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source _ACEOF ;; esac rm -rf conftest* # We used to try defining _XOPEN_SOURCE=500 too, to work around a bug # in glibc 2.1.3, but that breaks too many other things. # If you want fseeko and ftello with glibc, upgrade to a fixed glibc. if test $ac_cv_sys_largefile_source != unknown; then $as_echo "#define HAVE_FSEEKO 1" >>confdefs.h fi # Check whether --enable-largefile was given. if test "${enable_largefile+set}" = set; then : enableval=$enable_largefile; fi if test "$enable_largefile" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 $as_echo_n "checking for special C compiler options needed for large files... " >&6; } if ${ac_cv_sys_largefile_CC+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_sys_largefile_CC=no if test "$GCC" != yes; then ac_save_CC=$CC while :; do # IRIX 6.2 and later do not support large files by default, # so use the C compiler's -n32 option if that helps. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : break fi rm -f core conftest.err conftest.$ac_objext CC="$CC -n32" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_largefile_CC=' -n32'; break fi rm -f core conftest.err conftest.$ac_objext break done CC=$ac_save_CC rm -f conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 $as_echo "$ac_cv_sys_largefile_CC" >&6; } if test "$ac_cv_sys_largefile_CC" != no; then CC=$CC$ac_cv_sys_largefile_CC fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 $as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } if ${ac_cv_sys_file_offset_bits+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_file_offset_bits=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _FILE_OFFSET_BITS 64 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_file_offset_bits=64; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_file_offset_bits=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 $as_echo "$ac_cv_sys_file_offset_bits" >&6; } case $ac_cv_sys_file_offset_bits in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits _ACEOF ;; esac rm -rf conftest* if test $ac_cv_sys_file_offset_bits = unknown; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 $as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } if ${ac_cv_sys_large_files+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_large_files=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _LARGE_FILES 1 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_large_files=1; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_large_files=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 $as_echo "$ac_cv_sys_large_files" >&6; } case $ac_cv_sys_large_files in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _LARGE_FILES $ac_cv_sys_large_files _ACEOF ;; esac rm -rf conftest* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we need -D_LARGEFILE_SOURCE=1 as a flag for $CC" >&5 $as_echo_n "checking whether we need -D_LARGEFILE_SOURCE=1 as a flag for $CC... " >&6; } cache=_D_LARGEFILE_SOURCE_1 if eval \${cv_prog_cc_flag_needed_$cache+:} false; then : $as_echo_n "(cached) " >&6 else echo ' #include int test() { int a = fseeko(stdin, 0, 0); return a; } ' > conftest.c echo 'void f(){}' >>conftest.c if test -z "`$CC $CPPFLAGS $CFLAGS $ERRFLAG -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_needed_$cache=no" else if test -z "`$CC $CPPFLAGS $CFLAGS -D_LARGEFILE_SOURCE=1 $ERRFLAG -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_needed_$cache=yes" else eval "cv_prog_cc_flag_needed_$cache=fail" #echo 'Test with flag fails too!' #cat conftest.c #echo "$CC $CPPFLAGS $CFLAGS -D_LARGEFILE_SOURCE=1 $ERRFLAG -c conftest.c 2>&1" #echo `$CC $CPPFLAGS $CFLAGS -D_LARGEFILE_SOURCE=1 $ERRFLAG -c conftest.c 2>&1` #exit 1 fi fi rm -f conftest conftest.c conftest.o fi if eval "test \"`echo '$cv_prog_cc_flag_needed_'$cache`\" = yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : CFLAGS="$CFLAGS -D_LARGEFILE_SOURCE=1" else if eval "test \"`echo '$cv_prog_cc_flag_needed_'$cache`\" = no"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } #echo 'Test with flag is no!' #cat conftest.c #echo "$CC $CPPFLAGS $CFLAGS -D_LARGEFILE_SOURCE=1 $ERRFLAG -c conftest.c 2>&1" #echo `$CC $CPPFLAGS $CFLAGS -D_LARGEFILE_SOURCE=1 $ERRFLAG -c conftest.c 2>&1` #exit 1 : else { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } : fi fi # check for OpenSSL # Check whether --with-ssl was given. if test "${with_ssl+set}" = set; then : withval=$with_ssl; else withval="yes" fi if test x_$withval = x_no; then as_fn_error $? "Need SSL library to do digital signature cryptography" "$LINENO" 5 fi withval=$withval if test x_$withval != x_no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL" >&5 $as_echo_n "checking for SSL... " >&6; } if test x_$withval = x_ -o x_$withval = x_yes; then withval="/usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr" fi for dir in $withval; do ssldir="$dir" if test -f "$dir/include/openssl/ssl.h"; then found_ssl="yes" cat >>confdefs.h <<_ACEOF #define HAVE_SSL /**/ _ACEOF if test "$ssldir" != "/usr"; then CPPFLAGS="$CPPFLAGS -I$ssldir/include" LIBSSL_CPPFLAGS="$LIBSSL_CPPFLAGS -I$ssldir/include" fi break; fi done if test x_$found_ssl != x_yes; then as_fn_error $? "Cannot find the SSL libraries in $withval" "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $ssldir" >&5 $as_echo "found in $ssldir" >&6; } HAVE_SSL=yes if test "$ssldir" != "/usr" -a "$ssldir" != ""; then LDFLAGS="$LDFLAGS -L$ssldir/lib" LIBSSL_LDFLAGS="$LIBSSL_LDFLAGS -L$ssldir/lib" if test "x$enable_rpath" = xyes; then if echo "$ssldir/lib" | grep "^/" >/dev/null; then RUNTIME_PATH="$RUNTIME_PATH -R$ssldir/lib" fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for HMAC_Update in -lcrypto" >&5 $as_echo_n "checking for HMAC_Update in -lcrypto... " >&6; } LIBS="$LIBS -lcrypto" LIBSSL_LIBS="$LIBSSL_LIBS -lcrypto" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { int HMAC_Update(void); (void)HMAC_Update(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_HMAC_UPDATE 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } # check if -lwsock32 or -lgdi32 are needed. BAKLIBS="$LIBS" BAKSSLLIBS="$LIBSSL_LIBS" LIBS="$LIBS -lgdi32" LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if -lcrypto needs -lgdi32" >&5 $as_echo_n "checking if -lcrypto needs -lgdi32... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { int HMAC_Update(void); (void)HMAC_Update(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_HMAC_UPDATE 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } LIBS="$BAKLIBS" LIBSSL_LIBS="$BAKSSLLIBS" LIBS="$LIBS -ldl" LIBSSL_LIBS="$LIBSSL_LIBS -ldl" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if -lcrypto needs -ldl" >&5 $as_echo_n "checking if -lcrypto needs -ldl... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { int HMAC_Update(void); (void)HMAC_Update(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_HMAC_UPDATE 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } LIBS="$BAKLIBS" LIBSSL_LIBS="$BAKSSLLIBS" LIBS="$LIBS -ldl -pthread" LIBSSL_LIBS="$LIBSSL_LIBS -ldl -pthread" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if -lcrypto needs -ldl -pthread" >&5 $as_echo_n "checking if -lcrypto needs -ldl -pthread... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { int HMAC_Update(void); (void)HMAC_Update(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_HMAC_UPDATE 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "OpenSSL found in $ssldir, but version 0.9.7 or higher is required" "$LINENO" 5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi fi for ac_header in openssl/ssl.h do : ac_fn_c_check_header_compile "$LINENO" "openssl/ssl.h" "ac_cv_header_openssl_ssl_h" "$ac_includes_default " if test "x$ac_cv_header_openssl_ssl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_OPENSSL_SSL_H 1 _ACEOF fi done for ac_header in openssl/err.h do : ac_fn_c_check_header_compile "$LINENO" "openssl/err.h" "ac_cv_header_openssl_err_h" "$ac_includes_default " if test "x$ac_cv_header_openssl_err_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_OPENSSL_ERR_H 1 _ACEOF fi done for ac_header in openssl/rand.h do : ac_fn_c_check_header_compile "$LINENO" "openssl/rand.h" "ac_cv_header_openssl_rand_h" "$ac_includes_default " if test "x$ac_cv_header_openssl_rand_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_OPENSSL_RAND_H 1 _ACEOF fi done # check if libssl needs libdl BAKLIBS="$LIBS" LIBS="-lssl $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libssl needs libdl" >&5 $as_echo_n "checking if libssl needs libdl... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char SSL_CTX_new (); int main () { return SSL_CTX_new (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } LIBS="$BAKLIBS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } LIBS="$BAKLIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 $as_echo_n "checking for library containing dlopen... " >&6; } if ${ac_cv_search_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF for ac_lib in '' dl; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_dlopen=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_dlopen+:} false; then : break fi done if ${ac_cv_search_dlopen+:} false; then : else ac_cv_search_dlopen=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 $as_echo "$ac_cv_search_dlopen" >&6; } ac_res=$ac_cv_search_dlopen if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext for ac_header in openssl/conf.h do : ac_fn_c_check_header_compile "$LINENO" "openssl/conf.h" "ac_cv_header_openssl_conf_h" "$ac_includes_default " if test "x$ac_cv_header_openssl_conf_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_OPENSSL_CONF_H 1 _ACEOF fi done for ac_header in openssl/engine.h do : ac_fn_c_check_header_compile "$LINENO" "openssl/engine.h" "ac_cv_header_openssl_engine_h" "$ac_includes_default " if test "x$ac_cv_header_openssl_engine_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_OPENSSL_ENGINE_H 1 _ACEOF fi done if test "$staticexe" = "yes"; then LIBS="`echo $LIBS | sed -e 's/ -lcrypto//'`" LIBS="`echo $LIBS | sed -e 's/^-lcrypto//'`" LIBS="$ssldir/lib/libssl.a $ssldir/lib/libcrypto.a $LIBS" # check if lz is needed { $as_echo "$as_me:${as_lineno-$LINENO}: checking if static libcrypto needs -lz" >&5 $as_echo_n "checking if static libcrypto needs -lz... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { int SSL_library_init(void); (void)SSL_library_init(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } if test `uname` = "Darwin" -a -f $ssldir/lib/libz.a; then LIBS="$LIBS $ssldir/lib/libz.a" else LIBS="$LIBS -lz" fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext else LIBS="-lssl $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo" >&5 $as_echo_n "checking for getaddrinfo... " >&6; } ac_cv_func_getaddrinfo=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __cplusplus extern "C" { #endif char* getaddrinfo(); char* (*f) () = getaddrinfo; #ifdef __cplusplus } #endif int main() { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_func_getaddrinfo="yes" if test "$ac_cv_header_windows_h" = "yes"; then $as_echo "#define USE_WINSOCK 1" >>confdefs.h USE_WINSOCK="1" LIBS="$LIBS -lws2_32" fi else ORIGLIBS="$LIBS" LIBS="$LIBS -lws2_32" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_WS2TCPIP_H #include #endif int main () { (void)getaddrinfo(NULL, NULL, NULL, NULL); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_func_getaddrinfo="yes" $as_echo "#define USE_WINSOCK 1" >>confdefs.h USE_WINSOCK="1" else ac_cv_func_getaddrinfo="no" LIBS="$ORIGLIBS" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getaddrinfo" >&5 $as_echo "$ac_cv_func_getaddrinfo" >&6; } if test $ac_cv_func_getaddrinfo = yes; then $as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h fi if test "$USE_WINSOCK" = 1; then $as_echo "#define UB_ON_WINDOWS 1" >>confdefs.h UB_ON_WINDOWS=yes for ac_header in iphlpapi.h do : ac_fn_c_check_header_compile "$LINENO" "iphlpapi.h" "ac_cv_header_iphlpapi_h" "$ac_includes_default #include " if test "x$ac_cv_header_iphlpapi_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_IPHLPAPI_H 1 _ACEOF fi done if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args. set dummy ${ac_tool_prefix}windres; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_WINDRES+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$WINDRES"; then ac_cv_prog_WINDRES="$WINDRES" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_WINDRES="${ac_tool_prefix}windres" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi WINDRES=$ac_cv_prog_WINDRES if test -n "$WINDRES"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WINDRES" >&5 $as_echo "$WINDRES" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_WINDRES"; then ac_ct_WINDRES=$WINDRES # Extract the first word of "windres", so it can be a program name with args. set dummy windres; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_WINDRES+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_WINDRES"; then ac_cv_prog_ac_ct_WINDRES="$ac_ct_WINDRES" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_WINDRES="windres" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_WINDRES=$ac_cv_prog_ac_ct_WINDRES if test -n "$ac_ct_WINDRES"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_WINDRES" >&5 $as_echo "$ac_ct_WINDRES" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_WINDRES" = x; then WINDRES="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac WINDRES=$ac_ct_WINDRES fi else WINDRES="$ac_cv_prog_WINDRES" fi LIBS="$LIBS -liphlpapi" ac_fn_c_check_func "$LINENO" "EVP_PKEY_CTX_new_id" "ac_cv_func_EVP_PKEY_CTX_new_id" if test "x$ac_cv_func_EVP_PKEY_CTX_new_id" = xyes; then : else as_fn_error $? "Need newer openssl" "$LINENO" 5 fi for ac_func in _beginthreadex do : ac_fn_c_check_func "$LINENO" "_beginthreadex" "ac_cv_func__beginthreadex" if test "x$ac_cv_func__beginthreadex" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE__BEGINTHREADEX 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GetAdaptersAddresses" >&5 $as_echo_n "checking for GetAdaptersAddresses... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main(void) { (void)GetAdaptersAddresses(0, 0, NULL, NULL, NULL); return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_GETADAPTERSADDRESSES 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi $as_echo "#define USE_MINI_EVENT 1" >>confdefs.h if test $ac_cv_func_getaddrinfo = no; then case " $LIBOBJS " in *" fake-rfc2553.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS fake-rfc2553.$ac_objext" ;; esac fi # check after getaddrinfo for its libraries # check ioctlsocket { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ioctlsocket" >&5 $as_echo_n "checking for ioctlsocket... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_WINSOCK2_H #include #endif int main () { (void)ioctlsocket(0, 0, NULL); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_IOCTLSOCKET 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # see if daemon(3) exists, and if it is deprecated. for ac_func in daemon do : ac_fn_c_check_func "$LINENO" "daemon" "ac_cv_func_daemon" if test "x$ac_cv_func_daemon" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DAEMON 1 _ACEOF fi done if test $ac_cv_func_daemon = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if daemon is deprecated" >&5 $as_echo_n "checking if daemon is deprecated... " >&6; } cache=`echo daemon | sed 'y%.=/+-%___p_%'` if eval \${cv_cc_deprecated_$cache+:} false; then : $as_echo_n "(cached) " >&6 else echo ' #include ' >conftest.c echo 'void f(){ (void)daemon(0, 0); }' >>conftest.c if test -z "`$CC -c conftest.c 2>&1 | grep deprecated`"; then eval "cv_cc_deprecated_$cache=no" else eval "cv_cc_deprecated_$cache=yes" fi rm -f conftest conftest.o conftest.c fi if eval "test \"`echo '$cv_cc_deprecated_'$cache`\" = yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } cat >>confdefs.h <<_ACEOF #define DEPRECATED_DAEMON 1 _ACEOF : else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } : fi fi for ac_func in strftime localtime_r fcntl setsid sleep usleep random srandom recvmsg sendmsg writev chflags do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_func "$LINENO" "inet_pton" "ac_cv_func_inet_pton" if test "x$ac_cv_func_inet_pton" = xyes; then : $as_echo "#define HAVE_INET_PTON 1" >>confdefs.h else case " $LIBOBJS " in *" inet_pton.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS inet_pton.$ac_objext" ;; esac fi ac_fn_c_check_func "$LINENO" "inet_ntop" "ac_cv_func_inet_ntop" if test "x$ac_cv_func_inet_ntop" = xyes; then : $as_echo "#define HAVE_INET_NTOP 1" >>confdefs.h else case " $LIBOBJS " in *" inet_ntop.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS inet_ntop.$ac_objext" ;; esac fi ac_fn_c_check_func "$LINENO" "snprintf" "ac_cv_func_snprintf" if test "x$ac_cv_func_snprintf" = xyes; then : $as_echo "#define HAVE_SNPRINTF 1" >>confdefs.h else case " $LIBOBJS " in *" snprintf.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS snprintf.$ac_objext" ;; esac fi ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy" if test "x$ac_cv_func_strlcpy" = xyes; then : $as_echo "#define HAVE_STRLCPY 1" >>confdefs.h else case " $LIBOBJS " in *" strlcpy.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS strlcpy.$ac_objext" ;; esac fi ac_fn_c_check_func "$LINENO" "memmove" "ac_cv_func_memmove" if test "x$ac_cv_func_memmove" = xyes; then : $as_echo "#define HAVE_MEMMOVE 1" >>confdefs.h else case " $LIBOBJS " in *" memmove.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS memmove.$ac_objext" ;; esac fi hooks="auto" # Check whether --with-hooks was given. if test "${with_hooks+set}" = set; then : withval=$with_hooks; else withval="" fi if test -n "$withval"; then hooks="$withval" fi # hook settings networkmanager_dispatcher_dir="$sysconfdir/NetworkManager/dispatcher.d" # Check whether --with-networkmanager-dispatch was given. if test "${with_networkmanager_dispatch+set}" = set; then : withval=$with_networkmanager_dispatch; else withval="" fi with_nm_dispatch="$withval" netconfig_dispatcher_dir="$sysconfdir/netconfig.d" # Check whether --with-netconfig-dispatch was given. if test "${with_netconfig_dispatch+set}" = set; then : withval=$with_netconfig_dispatch; else withval="" fi with_netconfig_dispatch="$withval" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DHCP hooks" >&5 $as_echo_n "checking for DHCP hooks... " >&6; } if test "$hooks" != "auto"; then : else if test "$on_mingw" = "yes"; then hooks="windows" else if test -x "`which nmcli 2>&1`" -o -x "`which nm-tool 2>&1`"; then hooks="networkmanager" else if test "`uname`" = "Darwin"; then hooks="osx" else if test -x /sbin/netconfig; then hooks="netconfig" else hooks="none" fi fi fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hooks" >&5 $as_echo "$hooks" >&6; } if test "$hooks" = "networkmanager"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for NetworkManager dispatch" >&5 $as_echo_n "checking for NetworkManager dispatch... " >&6; } if test "$with_nm_dispatch" != ""; then networkmanager_dispatcher_dir="$with_nm_dispatch" else if test -d "$networkmanager_dispatcher_dir" ; then : else if test -d /etc/NetworkManager/dispatcher.d; then networkmanager_dispatcher_dir="/etc/NetworkManager/dispatcher.d" fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $networkmanager_dispatcher_dir" >&5 $as_echo "$networkmanager_dispatcher_dir" >&6; } fi if test "$hooks" = "netconfig"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for netconfig.d" >&5 $as_echo_n "checking for netconfig.d... " >&6; } if test "$with_netconfig_dispatch" != ""; then netconfig_dispatcher_dir="$with_netconfig_dispatch" else if test -d "$netconfig_dispatcher_dir" ; then : else if test -d /etc/netconfig.d; then netconfig_dispatcher_dir="/etc/netconfig.d" fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $netconfig_dispatcher_dir" >&5 $as_echo "$netconfig_dispatcher_dir" >&6; } fi if test "$hooks" = "osx"; then $as_echo "#define HOOKS_OSX 1" >>confdefs.h fi if test "$hooks" = "none"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: have no DHCP hooks, cannot detect network changes" >&5 $as_echo "$as_me: WARNING: have no DHCP hooks, cannot detect network changes" >&2;} fi gui="auto" # Check whether --with-gui was given. if test "${with_gui+set}" = set; then : withval=$with_gui; else withval="" fi if test -n "$withval" -a "$withval" != "yes"; then gui="$withval" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gui" >&5 $as_echo_n "checking for gui... " >&6; } if test "$gui" != "auto"; then : else if test "`uname`" = "Darwin"; then gui="cocoa" else if test "$on_mingw" = yes; then gui="windows" else gui="gtk" fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gui" >&5 $as_echo "$gui" >&6; } if test "$gui" = "gtk"; then # GTK GTK_CFLAGS=`pkg-config --cflags gtk+-2.0` GTK_LIBS=`pkg-config --libs gtk+-2.0` if test -z "$GTK_LIBS"; then as_fn_error $? "No gtk+-2.0 detected, please install glib-dev, gtk2-dev" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libappindicator" >&5 $as_echo_n "checking for libappindicator... " >&6; } # Check whether --enable-appindicator was given. if test "${enable_appindicator+set}" = set; then : enableval=$enable_appindicator; enable_appindicator=$enableval else enable_appindicator="auto" fi if test x$enable_appindicator = xauto ; then if pkg-config --exists appindicator-0.1; then enable_appindicator="yes" else enable_appindicator="no" fi fi if test x$enable_appindicator = xyes ; then # replace since GTK is included in the appindicator flags GTK_CFLAGS=`pkg-config --cflags appindicator-0.1` GTK_LIBS=`pkg-config --libs appindicator-0.1` if test -z "$GTK_LIBS"; then as_fn_error $? "appindicator-0.1 is not installed, need libappindicator-dev" "$LINENO" 5 fi $as_echo "#define HAVE_APP_INDICATOR 1" >>confdefs.h APP_INDICATOR="yes" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } BAKLIBS="$LIBS" LIBS="$LIBS $GTK_LIBS" for ac_func in app_indicator_set_icon_full do : ac_fn_c_check_func "$LINENO" "app_indicator_set_icon_full" "ac_cv_func_app_indicator_set_icon_full" if test "x$ac_cv_func_app_indicator_set_icon_full" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_APP_INDICATOR_SET_ICON_FULL 1 _ACEOF fi done LIBS="$BAKLIBS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # check for missing -lgthread-2.0 in the GTK_LIBS string. case "$GTK_LIBS" in *-lgthread* ) ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for g_thread_init in -lgthread-2.0" >&5 $as_echo_n "checking for g_thread_init in -lgthread-2.0... " >&6; } if ${ac_cv_lib_gthread_2_0_g_thread_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgthread-2.0 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char g_thread_init (); int main () { return g_thread_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_gthread_2_0_g_thread_init=yes else ac_cv_lib_gthread_2_0_g_thread_init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gthread_2_0_g_thread_init" >&5 $as_echo "$ac_cv_lib_gthread_2_0_g_thread_init" >&6; } if test "x$ac_cv_lib_gthread_2_0_g_thread_init" = xyes; then : GTK_LIBS="$GTK_LIBS -lgthread-2.0" fi esac if test "$on_mingw" = "no"; then xdg_autostart_dir="$sysconfdir/xdg/autostart" # Check whether --with-xdg-autostart was given. if test "${with_xdg_autostart+set}" = set; then : withval=$with_xdg_autostart; else withval="" fi with_xdg_autostart="$withval" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for autostart dir" >&5 $as_echo_n "checking for autostart dir... " >&6; } if test "$with_xdg_autostart" != ""; then xdg_autostart_dir="$with_xdg_autostart" else if test -d "$xdg_autostart_dir" ; then : else if test -d /etc/xdg/autostart; then xdg_autostart_dir="/etc/xdg/autostart" fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $xdg_autostart_dir" >&5 $as_echo "$xdg_autostart_dir" >&6; } fi fi login_command="auto" login_location="auto" # Check whether --with-login-command was given. if test "${with_login_command+set}" = set; then : withval=$with_login_command; else withval="" fi if test -n "$withval" -a "$withval" != "yes"; then login_command="$withval" fi # Check whether --with-login-location was given. if test "${with_login_location+set}" = set; then : withval=$with_login_location; else withval="" fi if test -n "$withval" -a "$withval" != "yes"; then login_location="$withval" fi if test "$login_location" = "auto"; then login_location="http://www.nlnetlabs.nl/projects/dnssec-trigger" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for web browser" >&5 $as_echo_n "checking for web browser... " >&6; } if test "$login_command" = "auto"; then if test "$USE_WINSOCK" = 1; then login_command="open" else if test "`uname`" = "Darwin"; then login_command="open" else clist="xdg-open sensible-browser gnome-open x-www-browser firefox konqueror chrome google-chrome" login_command="" for i in $clist; do if test -x "`which $i 2>&1`"; then login_command="$i" break; fi done fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $login_command" >&5 $as_echo "$login_command" >&6; } cat >>confdefs.h <<_ACEOF #define LOGIN_COMMAND "$login_command" _ACEOF cat >>confdefs.h <<_ACEOF #define LOGIN_LOCATION "$login_location" _ACEOF # Check whether --with-check-updates was given. if test "${with_check_updates+set}" = set; then : withval=$with_check_updates; else withval="" fi if test -n "$withval"; then check_updates="$withval" else # enable on WIN, OSX, not on unixes (use ports, package manager there). if test "$USE_WINSOCK" = 1; then check_updates="yes" else if test "`uname`" = "Darwin"; then check_updates="yes" else check_updates="no" fi fi fi cat >>confdefs.h <<_ACEOF #define CHECK_UPDATES "$check_updates" _ACEOF # Check whether --with-keydir was given. if test "${with_keydir+set}" = set; then : withval=$with_keydir; else withval="" fi keydir=`eval echo "$sysconfdir"` if test -n "$withval"; then keydir="$withval" fi keydir_esc="`echo $keydir | sed -e 's/\\\\/\\\\\\\\/g'`" cat >>confdefs.h <<_ACEOF #define KEYDIR "$keydir_esc" _ACEOF libexec_store_dir=`eval echo "$libexecdir"` libexec_store_dir_esc="`echo $libexec_store_dir | sed -e 's/\\\\/\\\\\\\\/g'`" cat >>confdefs.h <<_ACEOF #define LIBEXEC_DIR "$libexec_store_dir_esc" _ACEOF # Check whether --with-uidir was given. if test "${with_uidir+set}" = set; then : withval=$with_uidir; else withval="" fi uidir=`eval echo "$datadir/dnssec-trigger"` if test -n "$withval"; then uidir="$withval" fi uidir2="`echo $uidir | sed -e 's/\\\\/\\\\\\\\/g'`" uidir=`eval echo $uidir2` uidir_esc="`echo $uidir | sed -e 's/\\\\/\\\\\\\\/g'`" cat >>confdefs.h <<_ACEOF #define UIDIR "$uidir_esc" _ACEOF # Check whether --with-configfile was given. if test "${with_configfile+set}" = set; then : withval=$with_configfile; else withval="" fi configfile="$keydir/dnssec-trigger.conf" if test -n "$withval"; then configfile="$withval" fi configfile_esc="`echo $configfile | sed -e 's/\\\\/\\\\\\\\/g'`" cat >>confdefs.h <<_ACEOF #define CONFIGFILE "$configfile_esc" _ACEOF # Check whether --with-pidfile was given. if test "${with_pidfile+set}" = set; then : withval=$with_pidfile; else withval="" fi pidfile="/var/run/dnssec-trigger.pid" if test -n "$withval"; then pidfile="$withval" fi pidfile_esc="`echo $pidfile | sed -e 's/\\\\/\\\\\\\\/g'`" cat >>confdefs.h <<_ACEOF #define PIDFILE "$pidfile_esc" _ACEOF # Check whether --with-python was given. if test "${with_python+set}" = set; then : withval=$with_python; else withval="" fi PYTHON="/usr/bin/python" if test -n "$withval"; then PYTHON="$withval" fi python_esc="`echo $PYTHON | sed -e 's/\\\\/\\\\\\\\/g'`" cat >>confdefs.h <<_ACEOF #define PYTHON "$python_esc" _ACEOF # Check whether --with-unbound-control was given. if test "${with_unbound_control+set}" = set; then : withval=$with_unbound_control; else withval="" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for unbound-control" >&5 $as_echo_n "checking for unbound-control... " >&6; } if test "$on_mingw" = "yes"; then unbound_control_path='"C:\Program Files\Unbound\unbound-control.exe"' else unbound_control_path="`which unbound-control 2>&1`" fi if test -n "$withval"; then unbound_control_path="$withval" fi if test "$on_mingw" = "yes" -o -n "$withval"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $unbound_control_path" >&5 $as_echo "$unbound_control_path" >&6; } else if test -x "$unbound_control_path"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $unbound_control_path" >&5 $as_echo "$unbound_control_path" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found: try \"unbound-control\" in runtime PATH" >&5 $as_echo "not found: try \"unbound-control\" in runtime PATH" >&6; } unbound_control_path="unbound-control" fi fi unbound_control_esc="`echo $unbound_control_path | sed -e 's/\\\\/\\\\\\\\/g'`" unbound_control_esc="`echo $unbound_control_esc | sed -e 's/\\"/\\\\"/g'`" cat >>confdefs.h <<_ACEOF #define UNBOUND_CONTROL "$unbound_control_esc" _ACEOF LDNSLIBS="" # Check whether --with-ldns was given. if test "${with_ldns+set}" = set; then : withval=$with_ldns; CPPFLAGS="-I$withval/include $CPPFLAGS" LDFLAGS="-L$withval -L$withval/lib $LDFLAGS" ldnsdir="$withval" if test "$staticexe" = "yes"; then LDNSLIBS="$ldnsdir/lib/libldns.a" else LDNSLIBS="-lldns" if test "x$enable_rpath" = xyes; then if echo "$withval/lib" | grep "^/" >/dev/null; then RUNTIME_PATH="$RUNTIME_PATH -R$withval/lib" fi fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldns_buffer_new in -lldns" >&5 $as_echo_n "checking for ldns_buffer_new in -lldns... " >&6; } if ${ac_cv_lib_ldns_ldns_buffer_new+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lldns $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char ldns_buffer_new (); int main () { return ldns_buffer_new (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ldns_ldns_buffer_new=yes else ac_cv_lib_ldns_ldns_buffer_new=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ldns_ldns_buffer_new" >&5 $as_echo "$ac_cv_lib_ldns_ldns_buffer_new" >&6; } if test "x$ac_cv_lib_ldns_ldns_buffer_new" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBLDNS 1 _ACEOF LIBS="-lldns $LIBS" else as_fn_error $? "please install ldns-devel" "$LINENO" 5 fi fi # add option to disable the evil rpath # Check whether --enable-rpath was given. if test "${enable_rpath+set}" = set; then : enableval=$enable_rpath; enable_rpath=$enableval else enable_rpath=yes fi if test "x$enable_rpath" = xno; then ac_config_commands="$ac_config_commands disable-rpath" fi cat >>confdefs.h <<_ACEOF #define MAXSYSLOGMSGLEN 10240 _ACEOF cat >>confdefs.h <<_ACEOF #define DNS_PORT 53 _ACEOF DATE=`date +%x` ac_config_headers="$ac_config_headers config.h" ac_config_files="$ac_config_files Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by dnssec-trigger $as_me 0.13, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ dnssec-trigger config.status 0.13 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "disable-rpath") CONFIG_COMMANDS="$CONFIG_COMMANDS disable-rpath" ;; "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "disable-rpath":C) sed < libtool > libtool-2 \ 's/^hardcode_libdir_flag_spec.*$'/'hardcode_libdir_flag_spec=" -D__LIBTOOL_RPATH_SED__ "/' mv libtool-2 libtool chmod 755 libtool libtool="./libtool" ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi if test "$hooks" = "none"; then echo "WARNING NO DHCP HOOKS DETECTED CANNOT SETUP TRIGGER" fi echo "configure completed with $hooks hooks and $gui gui, now you can" echo " make | make all : compile the code" echo " make install : install files" echo " make uninstall : uninstall files" dnssec-trigger-0.13/dnssec-triggerd.service.in0000664000175000017500000000101512551723303021064 0ustar wouterwouter[Unit] Description=Reconfigure local DNSSEC resolver on connectivity changes After=NetworkManager.service unbound.service dnssec-triggerd-keygen.service Requires=unbound.service Wants=dnssec-triggerd-keygen.service [Service] PIDFile=@pidfile@ Type=simple Restart=always ExecStart=@sbindir@/dnssec-triggerd -d ExecStartPre=-@libexecdir@/dnssec-trigger-script --prepare ExecStartPost=-@libexecdir@/dnssec-trigger-script --update ExecStopPost=-@libexecdir@/dnssec-trigger-script --cleanup [Install] WantedBy=multi-user.target dnssec-trigger-0.13/install-sh0000775000175000017500000003325512124333601016022 0ustar wouterwouter#!/bin/sh # install - install a program, script, or datafile scriptversion=2011-11-20.07; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: dnssec-trigger-0.13/dnssec-triggerd-keygen.service0000664000175000017500000000037612551723303021750 0ustar wouterwouter[Unit] Description=Generate keys and certificates for dnssec-trigger ConditionPathExists=!/etc/dnssec-trigger/dnssec_trigger_control.key [Service] Type=oneshot ExecStart=/usr/sbin/dnssec-trigger-control-setup -d /etc/dnssec-trigger/ RemainAfterExit=yes dnssec-trigger-0.13/01-dnssec-trigger.in0000664000175000017500000001116112500331310017465 0ustar wouterwouter#!@SHELL@ # # Script to notify dnssec-trigger that the DNS configuration in NetworkManager # may have changed. # Future versions of NetworkManager will have an active unbound/dnssec-trigger # plugin. Don't intervene when the new plugin is being used. if [ -e /etc/NetworkManager/NetworkManager.conf ]; then grep -q '^dns=unbound\>' /etc/NetworkManager/NetworkManager.conf && exit 0 fi # Exec the dnssec-trigger update script that uses NetworkManager API to gather # all the necessary information. if [ -x @libexecdir@/dnssec-trigger-script ]; then exec @libexecdir@/dnssec-trigger-script --update fi # When dnssec-trigger-script is absent or not executable, the original # shell-based dnssec trigger hook code below is run instead. # # NetworkManager trigger for in dispatcher.d # config items # set PATH correctly instead of absolute paths to binaries PATH="@sbindir@:@bindir@:/sbin:/usr/sbin:/bin:/usr/bin" state_dir="/var/run/dnssec-trigger" validate_forward_zones="no" # implementation ifname="$1" action="$2" domains="" nameservers="" global_nameservers="" conn_zones_file="$state_dir/$CONNECTION_UUID" ################################################################ # get domains and nameservers if provided by connection going up case "$action" in "vpn-up" ) domains="`echo $VPN_IP4_DOMAINS $VPN_IP6_DOMAINS | tr " " "\n" | sort -u | tr "\n" " " | sed '$s/.$//'`" nameservers="`echo $VPN_IP4_NAMESERVERS $VPN_IP6_NAMESERVERS`" ;; "up" ) domains="`echo $IP4_DOMAINS $IP6_DOMAINS | tr " " "\n" | sort -u | tr "\n" " " | sed '$s/.$//'`" nameservers="`echo $IP4_NAMESERVERS $IP6_NAMESERVERS`" ;; esac ######################### # get global nameservers # try to get nmcli version NMCLI_VER=$(printf '%03d%03d%03d%03d\n' $(nmcli -v 2>/dev/null | sed 's/.*version \([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\).*/\1 \2 \3 \4/')) # if nmcli exists if [ -n "$NMCLI_VER" ]; then # if the version is greater or equal 0.9.9.0 if [ $NMCLI_VER -ge 000009009000 ]; then global_nameservers="`nmcli -f IP4,IP6 dev show | fgrep 'DNS' | awk '{print $2;}'`" else global_nameservers="`nmcli -f IP4,IP6 dev list | fgrep 'DNS' | awk '{print $2;}'`" fi # nmcli does not exist else global_nameservers="`nm-tool | grep 'DNS:' | awk '{print $2;}'`" fi # fix whitespaces global_nameservers="`echo $global_nameservers`" ############################################################ # configure global nameservers using dnssec-trigger-control if [ -n "`pidof dnssec-triggerd`" ] ; then dnssec-trigger-control submit "$global_nameservers" &> /dev/null logger "dnssec-trigger-hook(networkmanager) $ifname $action added global DNS $global_nameservers" else logger "dnssec-trigger-hook(networkmanager) $ifname $action NOT added global DNS - dnssec-triggerd is not running" fi ###################################################### # add forward zones into unbound using unbound-control if [ -n "`pidof unbound`" ]; then if [ -r "$conn_zones_file" ]; then for domain in `cat $conn_zones_file`; do # Remove forward zone from unbound if [ "$validate_forward_zones" = "no" ]; then unbound-control forward_remove +i $domain &> /dev/null else unbound-control forward_remove $domain &> /dev/null fi unbound-control flush_zone $domain &> /dev/null unbound-control flush_requestlist &> /dev/null logger "dnssec-trigger-hook(networkmanager) $ifname $action removed forward DNS zone $domain" done # Remove file with zones for this connection rm -f $conn_zones_file &> /dev/null fi if [ "$action" = "vpn-up" -o "$action" = "up" ]; then if [ -n "$domains" ]; then for domain in $domains; do # Add forward zone into unbound if [ "$validate_forward_zones" = "no" ]; then unbound-control forward_add +i $domain $nameservers &> /dev/null else unbound-control forward_add $domain $nameservers &> /dev/null fi unbound-control flush_zone $domain &> /dev/null unbound-control flush_requestlist &> /dev/null # Create zone info file mkdir -p $(dirname $conn_zones_file) echo $domain >> $conn_zones_file logger "dnssec-trigger-hook(networkmanager) $ifname $action added forward DNS zone $domain $nameservers" done fi fi else logger "dnssec-trigger-hook(networkmanager) $ifname $action NOT added forward DNS zone(s) - unbound is not running" fi exit 0 dnssec-trigger-0.13/riggerd/0000775000175000017500000000000013024457644015447 5ustar wouterwouterdnssec-trigger-0.13/riggerd/net_help.h0000664000175000017500000002406712275162157017426 0ustar wouterwouter/* * util/net_help.h - network help functions * * Copyright (c) 2007, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains functions to perform network related tasks. */ #ifndef NET_HELP_H #define NET_HELP_H #include "log.h" struct sock_list; struct regional; /** DNS constants for uint16_t style flag manipulation. host byteorder. * 1 1 1 1 1 1 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * |QR| Opcode |AA|TC|RD|RA| Z|AD|CD| RCODE | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ */ /** CD flag */ #define BIT_CD 0x0010 /** AD flag */ #define BIT_AD 0x0020 /** Z flag */ #define BIT_Z 0x0040 /** RA flag */ #define BIT_RA 0x0080 /** RD flag */ #define BIT_RD 0x0100 /** TC flag */ #define BIT_TC 0x0200 /** AA flag */ #define BIT_AA 0x0400 /** QR flag */ #define BIT_QR 0x8000 /** get RCODE bits from uint16 flags */ #define FLAGS_GET_RCODE(f) ((f) & 0xf) /** set RCODE bits in uint16 flags */ #define FLAGS_SET_RCODE(f, r) (f = (((f) & 0xfff0) | (r))) /** timeout in seconds for UDP queries to auth servers. */ #define UDP_AUTH_QUERY_TIMEOUT 4 /** timeout in seconds for TCP queries to auth servers. */ #define TCP_AUTH_QUERY_TIMEOUT 30 /** Advertised version of EDNS capabilities */ #define EDNS_ADVERTISED_VERSION 0 /** Advertised size of EDNS capabilities */ extern uint16_t EDNS_ADVERTISED_SIZE; /** bits for EDNS bitfield */ #define EDNS_DO 0x8000 /* Dnssec Ok */ /** byte size of ip4 address */ #define INET_SIZE 4 /** byte size of ip6 address */ #define INET6_SIZE 16 /** DNSKEY zone sign key flag */ #define DNSKEY_BIT_ZSK 0x0100 /** DNSKEY secure entry point, KSK flag */ #define DNSKEY_BIT_SEP 0x0001 /** * See if string is ip4 or ip6. * @param str: IP specification. * @return: true if string addr is an ip6 specced address. */ int str_is_ip6(const char* str); /** * Set fd nonblocking. * @param s: file descriptor. * @return: 0 on error (error is printed to log). */ int fd_set_nonblock(int s); /** * Set fd (back to) blocking. * @param s: file descriptor. * @return: 0 on error (error is printed to log). */ int fd_set_block(int s); /** * See if number is a power of 2. * @param num: the value. * @return: true if the number is a power of 2. */ int is_pow2(size_t num); /** * Allocate memory and copy over contents. * @param data: what to copy over. * @param len: length of data. * @return: NULL on malloc failure, or newly malloced data. */ void* memdup(void* data, size_t len); /** * Prints the sockaddr in readable format with log_info. Debug helper. * @param v: at what verbosity level to print this. * @param str: descriptive string printed with it. * @param addr: the sockaddr to print. Can be ip4 or ip6. * @param addrlen: length of addr. */ void log_addr(enum verbosity_value v, const char* str, struct sockaddr_storage* addr, socklen_t addrlen); /** * Convert address string, with "@port" appendix, to sockaddr. * Uses DNS port by default. * @param str: the string * @param addr: where to store sockaddr. * @param addrlen: length of stored sockaddr is returned. * @return 0 on error. */ int extstrtoaddr(const char* str, struct sockaddr_storage* addr, socklen_t* addrlen); /** * Convert ip address string and port to sockaddr. * @param ip: ip4 or ip6 address string. * @param port: port number, host format. * @param addr: where to store sockaddr. * @param addrlen: length of stored sockaddr is returned. * @return 0 on error. */ int ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr, socklen_t* addrlen); /** * Convert ip netblock (ip/netsize) string and port to sockaddr. * *SLOW*, does a malloc internally to avoid writing over 'ip' string. * @param ip: ip4 or ip6 address string. * @param port: port number, host format. * @param addr: where to store sockaddr. * @param addrlen: length of stored sockaddr is returned. * @param net: netblock size is returned. * @return 0 on error. */ int netblockstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr, socklen_t* addrlen, int* net); /** * Compare two sockaddrs. Imposes an ordering on the addresses. * Compares address and port. * @param addr1: address 1. * @param len1: lengths of addr1. * @param addr2: address 2. * @param len2: lengths of addr2. * @return: 0 if addr1 == addr2. -1 if addr1 is smaller, +1 if larger. */ int sockaddr_cmp(struct sockaddr_storage* addr1, socklen_t len1, struct sockaddr_storage* addr2, socklen_t len2); /** * Compare two sockaddrs. Compares address, not the port. * @param addr1: address 1. * @param len1: lengths of addr1. * @param addr2: address 2. * @param len2: lengths of addr2. * @return: 0 if addr1 == addr2. -1 if addr1 is smaller, +1 if larger. */ int sockaddr_cmp_addr(struct sockaddr_storage* addr1, socklen_t len1, struct sockaddr_storage* addr2, socklen_t len2); /** * Checkout address family. * @param addr: the sockaddr to examine. * @param len: the length of addr. * @return: true if sockaddr is ip6. */ int addr_is_ip6(struct sockaddr_storage* addr, socklen_t len); /** * Make sure the sockaddr ends in zeroes. For tree insertion and subsequent * comparison. * @param addr: the ip4 or ip6 addr. * @param len: length of addr. * @param net: number of bits to leave untouched, the rest of the netblock * address is zeroed. */ void addr_mask(struct sockaddr_storage* addr, socklen_t len, int net); /** * See how many bits are shared, equal, between two addrs. * @param addr1: first addr. * @param net1: netblock size of first addr. * @param addr2: second addr. * @param net2: netblock size of second addr. * @param addrlen: length of first addr and of second addr. * They must be of the same length (i.e. same type IP4, IP6). * @return: number of bits the same. */ int addr_in_common(struct sockaddr_storage* addr1, int net1, struct sockaddr_storage* addr2, int net2, socklen_t addrlen); /** * Put address into string, works for IPv4 and IPv6. * @param addr: address * @param addrlen: length of address * @param buf: result string stored here * @param len: length of buf. * On failure a string with "error" is stored inside. */ void addr_to_str(struct sockaddr_storage* addr, socklen_t addrlen, char* buf, size_t len); /** * See if sockaddr is an ipv6 mapped ipv4 address, "::ffff:0.0.0.0" * @param addr: address * @param addrlen: length of address * @return true if so */ int addr_is_ip4mapped(struct sockaddr_storage* addr, socklen_t addrlen); /** * See if sockaddr is 255.255.255.255. * @param addr: address * @param addrlen: length of address * @return true if so */ int addr_is_broadcast(struct sockaddr_storage* addr, socklen_t addrlen); /** * See if sockaddr is 0.0.0.0 or ::0. * @param addr: address * @param addrlen: length of address * @return true if so */ int addr_is_any(struct sockaddr_storage* addr, socklen_t addrlen); /** * Log libcrypto error with descriptive string. Calls log_err(). * @param str: what failed. */ void log_crypto_err(const char* str); /** * create SSL listen context * @param key: private key file. * @param pem: public key cert. * @param verifypem: if nonNULL, verifylocation file. * return SSL_CTX* or NULL on failure (logged). */ void* listen_sslctx_create(char* key, char* pem, char* verifypem); /** * create SSL connect context * @param key: if nonNULL (also pem nonNULL), the client private key. * @param pem: client public key (or NULL if key is NULL). * @param verifypem: if nonNULL used for verifylocation file. * @return SSL_CTX* or NULL on failure (logged). */ void* connect_sslctx_create(char* key, char* pem, char* verifypem); /** * accept a new fd and wrap it in a BIO in SSL * @param sslctx: the SSL_CTX to use (from listen_sslctx_create()). * @param fd: from accept, nonblocking. * @return SSL or NULL on alloc failure. */ void* incoming_ssl_fd(void* sslctx, int fd); /** * connect a new fd and wrap it in a BIO in SSL * @param sslctx: the SSL_CTX to use (from connect_sslctx_create()) * @param fd: from connect. * @return SSL or NULL on alloc failure */ void* outgoing_ssl_fd(void* sslctx, int fd); /** * Create tcp connection (blockingly) to the server. * @param svr: IP address (can have '@port'). * @param port: used if no port specced. * @param statuscmd: if true, tests to see if the server is down. * @param err: buffer to print error in (for -1 return value). * @param errlen: length of buffer. * @return fd of TCP. -1 on failure (log_err result). * -2 if server is down and statuscmd is given. */ int contact_server(const char* svr, int port, int statuscmd, char* err, size_t errlen); #endif /* NET_HELP_H */ dnssec-trigger-0.13/riggerd/log.c0000664000175000017500000003355512275162157016406 0ustar wouterwouter/* * util/log.c - implementation of the log code * * Copyright (c) 2007, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * Implementation of log.h. */ #include "config.h" #include "log.h" #ifdef HAVE_TIME_H #include #endif #ifdef HAVE_SYSLOG_H # include #else /**define LOG_ constants */ # define LOG_CRIT 2 # define LOG_ERR 3 # define LOG_WARNING 4 # define LOG_NOTICE 5 # define LOG_INFO 6 # define LOG_DEBUG 7 #endif #ifdef UB_ON_WINDOWS # include "winrc/win_svc.h" #endif /* default verbosity */ enum verbosity_value verbosity = 0; /** the file logged to. */ static FILE* logfile = 0; /** the identity of this executable/process */ static const char* ident="dnssec-trigger"; #if defined(HAVE_SYSLOG_H) || defined(UB_ON_WINDOWS) /** are we using syslog(3) to log to */ static int logging_to_syslog = 0; #endif /* HAVE_SYSLOG_H */ /** time to print in log, if NULL, use time(2) */ static uint32_t* log_now = NULL; /** print time in UTC or in secondsfrom1970 */ static int log_time_asc = 1; void log_init(const char* filename, int use_syslog, const char* chrootdir) { FILE *f; if(logfile #if defined(HAVE_SYSLOG_H) || defined(UB_ON_WINDOWS) || logging_to_syslog #endif ) verbose(VERB_QUERY, "switching log to %s", use_syslog?"syslog":(filename&&filename[0]?filename:"stderr")); if(logfile && logfile != stderr) fclose(logfile); #ifdef HAVE_SYSLOG_H if(logging_to_syslog) { closelog(); logging_to_syslog = 0; } if(use_syslog) { /* do not delay opening until first write, because we may * chroot and no longer be able to access dev/log and so on */ openlog(ident, LOG_NDELAY, LOG_DAEMON); logging_to_syslog = 1; return; } #elif defined(UB_ON_WINDOWS) if(logging_to_syslog) { logging_to_syslog = 0; } if(use_syslog) { logging_to_syslog = 1; return; } #endif /* HAVE_SYSLOG_H */ if(!filename || !filename[0]) { logfile = stderr; return; } /* open the file for logging */ if(chrootdir && chrootdir[0] && strncmp(filename, chrootdir, strlen(chrootdir)) == 0) filename += strlen(chrootdir); f = fopen(filename, "a"); if(!f) { log_err("Could not open logfile %s: %s", filename, strerror(errno)); return; } #ifndef UB_ON_WINDOWS /* line buffering does not work on windows */ setvbuf(f, NULL, (int)_IOLBF, 0); #endif logfile = f; } void log_file(FILE *f) { logfile = f; } void log_ident_set(const char* id) { ident = id; } void log_set_time(uint32_t* t) { log_now = t; } void log_set_time_asc(int use_asc) { log_time_asc = use_asc; } void log_vmsg(int pri, const char* type, const char *format, va_list args) { char message[MAXSYSLOGMSGLEN]; time_t now; #if defined(HAVE_STRFTIME) && defined(HAVE_LOCALTIME_R) char tmbuf[32]; struct tm tm; #endif (void)pri; vsnprintf(message, sizeof(message), format, args); #ifdef HAVE_SYSLOG_H if(logging_to_syslog) { syslog(pri, "[%d] %s: %s", (int)getpid(), type, message); return; } #elif defined(UB_ON_WINDOWS) if(logging_to_syslog) { char m[32768]; HANDLE* s; LPCTSTR str = m; DWORD tp = MSG_GENERIC_ERR; WORD wt = EVENTLOG_ERROR_TYPE; if(strcmp(type, "info") == 0) { tp=MSG_GENERIC_INFO; wt=EVENTLOG_INFORMATION_TYPE; } else if(strcmp(type, "warning") == 0) { tp=MSG_GENERIC_WARN; wt=EVENTLOG_WARNING_TYPE; } else if(strcmp(type, "notice") == 0 || strcmp(type, "debug") == 0) { tp=MSG_GENERIC_SUCCESS; wt=EVENTLOG_SUCCESS; } snprintf(m, sizeof(m), "[%s] %s: %s", ident, type, message); s = RegisterEventSource(NULL, SERVICE_NAME); if(!s) return; ReportEvent(s, wt, 0, tp, NULL, 1, 0, &str, NULL); DeregisterEventSource(s); return; } #endif /* HAVE_SYSLOG_H */ if(!logfile) return; if(log_now) now = (time_t)*log_now; else now = (time_t)time(NULL); #if defined(HAVE_STRFTIME) && defined(HAVE_LOCALTIME_R) if(log_time_asc && strftime(tmbuf, sizeof(tmbuf), "%b %d %H:%M:%S", localtime_r(&now, &tm))%(sizeof(tmbuf)) != 0) { /* %sizeof buf!=0 because old strftime returned max on error */ fprintf(logfile, "%s %s[%d] %s: %s\n", tmbuf, ident, (int)getpid(), type, message); } else #endif fprintf(logfile, "[%u] %s[%d] %s: %s\n", (unsigned)now, ident, (int)getpid(), type, message); #ifdef UB_ON_WINDOWS /* line buffering does not work on windows */ fflush(logfile); #endif } /** * implementation of log_info * @param format: format string printf-style. */ void log_info(const char *format, ...) { va_list args; va_start(args, format); log_vmsg(LOG_INFO, "info", format, args); va_end(args); } /** * implementation of log_err * @param format: format string printf-style. */ void log_err(const char *format, ...) { va_list args; va_start(args, format); log_vmsg(LOG_ERR, "error", format, args); va_end(args); } /** * implementation of log_warn * @param format: format string printf-style. */ void log_warn(const char *format, ...) { va_list args; va_start(args, format); log_vmsg(LOG_WARNING, "warning", format, args); va_end(args); } /** * implementation of fatal_exit * @param format: format string printf-style. */ void fatal_exit(const char *format, ...) { va_list args; va_start(args, format); log_vmsg(LOG_CRIT, "fatal error", format, args); va_end(args); exit(1); } /** * implementation of verbose * @param level: verbose level for the message. * @param format: format string printf-style. */ void verbose(enum verbosity_value level, const char* format, ...) { va_list args; va_start(args, format); if(verbosity >= level) { if(level == VERB_OPS) log_vmsg(LOG_NOTICE, "notice", format, args); else if(level == VERB_DETAIL) log_vmsg(LOG_INFO, "info", format, args); else log_vmsg(LOG_DEBUG, "debug", format, args); } va_end(args); } /** log hex data */ static void log_hex_f(enum verbosity_value v, const char* msg, void* data, size_t length) { size_t i, j; uint8_t* data8 = (uint8_t*)data; const char* hexchar = "0123456789ABCDEF"; char buf[1024+1]; /* alloc blocksize hex chars + \0 */ const size_t blocksize = 512; size_t len; if(length == 0) { verbose(v, "%s[%u]", msg, (unsigned)length); return; } for(i=0; i> 4 ]; buf[j*2 + 1] = hexchar[ data8[i+j] & 0xF ]; } buf[len*2] = 0; verbose(v, "%s[%u:%u] %.*s", msg, (unsigned)length, (unsigned)i, (int)len*2, buf); } } void log_hex(const char* msg, void* data, size_t length) { log_hex_f(verbosity, msg, data, length); } #ifdef USE_WINSOCK char* wsa_strerror(DWORD err) { static char unknown[32]; switch(err) { case WSA_INVALID_HANDLE: return "Specified event object handle is invalid."; case WSA_NOT_ENOUGH_MEMORY: return "Insufficient memory available."; case WSA_INVALID_PARAMETER: return "One or more parameters are invalid."; case WSA_OPERATION_ABORTED: return "Overlapped operation aborted."; case WSA_IO_INCOMPLETE: return "Overlapped I/O event object not in signaled state."; case WSA_IO_PENDING: return "Overlapped operations will complete later."; case WSAEINTR: return "Interrupted function call."; case WSAEBADF: return "File handle is not valid."; case WSAEACCES: return "Permission denied."; case WSAEFAULT: return "Bad address."; case WSAEINVAL: return "Invalid argument."; case WSAEMFILE: return "Too many open files."; case WSAEWOULDBLOCK: return "Resource temporarily unavailable."; case WSAEINPROGRESS: return "Operation now in progress."; case WSAEALREADY: return "Operation already in progress."; case WSAENOTSOCK: return "Socket operation on nonsocket."; case WSAEDESTADDRREQ: return "Destination address required."; case WSAEMSGSIZE: return "Message too long."; case WSAEPROTOTYPE: return "Protocol wrong type for socket."; case WSAENOPROTOOPT: return "Bad protocol option."; case WSAEPROTONOSUPPORT: return "Protocol not supported."; case WSAESOCKTNOSUPPORT: return "Socket type not supported."; case WSAEOPNOTSUPP: return "Operation not supported."; case WSAEPFNOSUPPORT: return "Protocol family not supported."; case WSAEAFNOSUPPORT: return "Address family not supported by protocol family."; case WSAEADDRINUSE: return "Address already in use."; case WSAEADDRNOTAVAIL: return "Cannot assign requested address."; case WSAENETDOWN: return "Network is down."; case WSAENETUNREACH: return "Network is unreachable."; case WSAENETRESET: return "Network dropped connection on reset."; case WSAECONNABORTED: return "Software caused connection abort."; case WSAECONNRESET: return "Connection reset by peer."; case WSAENOBUFS: return "No buffer space available."; case WSAEISCONN: return "Socket is already connected."; case WSAENOTCONN: return "Socket is not connected."; case WSAESHUTDOWN: return "Cannot send after socket shutdown."; case WSAETOOMANYREFS: return "Too many references."; case WSAETIMEDOUT: return "Connection timed out."; case WSAECONNREFUSED: return "Connection refused."; case WSAELOOP: return "Cannot translate name."; case WSAENAMETOOLONG: return "Name too long."; case WSAEHOSTDOWN: return "Host is down."; case WSAEHOSTUNREACH: return "No route to host."; case WSAENOTEMPTY: return "Directory not empty."; case WSAEPROCLIM: return "Too many processes."; case WSAEUSERS: return "User quota exceeded."; case WSAEDQUOT: return "Disk quota exceeded."; case WSAESTALE: return "Stale file handle reference."; case WSAEREMOTE: return "Item is remote."; case WSASYSNOTREADY: return "Network subsystem is unavailable."; case WSAVERNOTSUPPORTED: return "Winsock.dll version out of range."; case WSANOTINITIALISED: return "Successful WSAStartup not yet performed."; case WSAEDISCON: return "Graceful shutdown in progress."; case WSAENOMORE: return "No more results."; case WSAECANCELLED: return "Call has been canceled."; case WSAEINVALIDPROCTABLE: return "Procedure call table is invalid."; case WSAEINVALIDPROVIDER: return "Service provider is invalid."; case WSAEPROVIDERFAILEDINIT: return "Service provider failed to initialize."; case WSASYSCALLFAILURE: return "System call failure."; case WSASERVICE_NOT_FOUND: return "Service not found."; case WSATYPE_NOT_FOUND: return "Class type not found."; case WSA_E_NO_MORE: return "No more results."; case WSA_E_CANCELLED: return "Call was canceled."; case WSAEREFUSED: return "Database query was refused."; case WSAHOST_NOT_FOUND: return "Host not found."; case WSATRY_AGAIN: return "Nonauthoritative host not found."; case WSANO_RECOVERY: return "This is a nonrecoverable error."; case WSANO_DATA: return "Valid name, no data record of requested type."; case WSA_QOS_RECEIVERS: return "QOS receivers."; case WSA_QOS_SENDERS: return "QOS senders."; case WSA_QOS_NO_SENDERS: return "No QOS senders."; case WSA_QOS_NO_RECEIVERS: return "QOS no receivers."; case WSA_QOS_REQUEST_CONFIRMED: return "QOS request confirmed."; case WSA_QOS_ADMISSION_FAILURE: return "QOS admission error."; case WSA_QOS_POLICY_FAILURE: return "QOS policy failure."; case WSA_QOS_BAD_STYLE: return "QOS bad style."; case WSA_QOS_BAD_OBJECT: return "QOS bad object."; case WSA_QOS_TRAFFIC_CTRL_ERROR: return "QOS traffic control error."; case WSA_QOS_GENERIC_ERROR: return "QOS generic error."; case WSA_QOS_ESERVICETYPE: return "QOS service type error."; case WSA_QOS_EFLOWSPEC: return "QOS flowspec error."; case WSA_QOS_EPROVSPECBUF: return "Invalid QOS provider buffer."; case WSA_QOS_EFILTERSTYLE: return "Invalid QOS filter style."; case WSA_QOS_EFILTERTYPE: return "Invalid QOS filter type."; case WSA_QOS_EFILTERCOUNT: return "Incorrect QOS filter count."; case WSA_QOS_EOBJLENGTH: return "Invalid QOS object length."; case WSA_QOS_EFLOWCOUNT: return "Incorrect QOS flow count."; /*case WSA_QOS_EUNKOWNPSOBJ: return "Unrecognized QOS object.";*/ case WSA_QOS_EPOLICYOBJ: return "Invalid QOS policy object."; case WSA_QOS_EFLOWDESC: return "Invalid QOS flow descriptor."; case WSA_QOS_EPSFLOWSPEC: return "Invalid QOS provider-specific flowspec."; case WSA_QOS_EPSFILTERSPEC: return "Invalid QOS provider-specific filterspec."; case WSA_QOS_ESDMODEOBJ: return "Invalid QOS shape discard mode object."; case WSA_QOS_ESHAPERATEOBJ: return "Invalid QOS shaping rate object."; case WSA_QOS_RESERVED_PETYPE: return "Reserved policy QOS element type."; case RPC_S_SERVER_UNAVAILABLE: return "The RPC server is unavailable."; case RPC_S_UNKNOWN_IF: return "RPC interface is unknown."; default: snprintf(unknown, sizeof(unknown), "unknown WSA error code %d", (int)err); return unknown; } } #endif /* USE_WINSOCK */ dnssec-trigger-0.13/riggerd/update.c0000664000175000017500000005601012275162157017076 0ustar wouterwouter/* * update.c - dnssec-trigger update * * Copyright (c) 2012, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains the implementation to check and download the update */ #include "config.h" #include "update.h" #include "probe.h" #include "http.h" #include "netevent.h" #include "log.h" #include "cfg.h" #include "svr.h" #include struct selfupdate* selfupdate_create(struct svr* svr, struct cfg* cfg) { struct selfupdate* se = (struct selfupdate*)calloc(1, sizeof(*se)); if(!se) { log_err("out of memory"); return NULL; } se->svr = svr; se->cfg = cfg; svr->update_desired = 1; se->timer = comm_timer_create(svr->base, selfupdate_timeout, se); if(!se->timer) { log_err("out of memory"); free(se); return NULL; } return se; } /** delete the temporary file */ static void selfupdate_delete_file(struct selfupdate* se) { if(se->download_file) { (void)unlink(se->download_file); free(se->download_file); se->download_file = NULL; } } /** zero and init */ static void selfupdate_init(struct selfupdate* se) { se->update_available = 0; se->user_replied = 0; se->user_okay = 0; se->file_available = 0; outq_delete(se->txt_query); se->txt_query = NULL; free(se->version_available); se->version_available = NULL; free(se->hash); se->hash = NULL; outq_delete(se->addr_4); se->addr_4 = NULL; outq_delete(se->addr_6); se->addr_6 = NULL; ldns_rr_list_deep_free(se->addr_list_4); se->addr_list_4 = NULL; ldns_rr_list_deep_free(se->addr_list_6); se->addr_list_6 = NULL; http_get_delete(se->download_http4); se->download_http4 = NULL; http_get_delete(se->download_http6); se->download_http6 = NULL; selfupdate_delete_file(se); free(se->filename); se->filename = NULL; } void selfupdate_delete(struct selfupdate* se) { if(!se) return; selfupdate_init(se); comm_timer_delete(se->timer); free(se); } /* when timer done, set update-desired again */ void selfupdate_timeout(void* arg) { struct selfupdate* se = (struct selfupdate*)arg; /* this instructs the server to call the selfupdate_start when * dnssec becomes available */ se->svr->update_desired = 1; /* if DNSSEC available now, do so now */ svr_check_update(se->svr); } /** set retry timer after a failure */ static void selfupdate_start_retry_timer(struct selfupdate* se) { struct timeval tv; tv.tv_sec = SELFUPDATE_RETRY; tv.tv_usec = 0; comm_timer_set(se->timer, &tv); } /** set 24h timer after success but no update needed */ static void selfupdate_start_next_timer(struct selfupdate* se) { struct timeval tv; tv.tv_sec = SELFUPDATE_NEXT_CHECK; tv.tv_usec = 0; comm_timer_set(se->timer, &tv); } void selfupdate_start(struct selfupdate* se) { char* domain = NULL; char* server = "127.0.0.1"; /* do not start us again, if it fails we turn desired back on. */ if(!se->svr->update_desired) { /* robust check for double start */ return; } se->svr->update_desired = 0; verbose(VERB_ALGO, "start check for software update"); /* zero some state */ selfupdate_init(se); /* start lookup of the domain name with version string and hash */ #ifdef USE_WINSOCK if(se->test_flag) domain = "win.test."DNSSECTRIGGER_DOMAIN; else domain = "win.version."DNSSECTRIGGER_DOMAIN; #elif defined(HOOKS_OSX) if(se->test_flag) domain = "osx.test."DNSSECTRIGGER_DOMAIN; else domain = "osx.version."DNSSECTRIGGER_DOMAIN; #else if(se->test_flag) domain = "src.test."DNSSECTRIGGER_DOMAIN; else domain = "src.version."DNSSECTRIGGER_DOMAIN; #endif verbose(VERB_ALGO, "fetch domain %s TXT", domain); /* setup TXT query, DO to get AD flag, no CD flag we want to check it */ se->txt_query = outq_create(server, LDNS_RR_TYPE_TXT, domain, 1, NULL, 0, 0, DNS_PORT, 1, 0); if(!se->txt_query) { log_err("out of memory, cannot make version txt query"); selfupdate_start_retry_timer(se); return; } } /** remove "bla" to bla without quotes */ static void remove_quotes(char* str) { size_t len; if(!str || str[0] != '"') return; len = strlen(str); if(len <= 1) return; /* remove endquote */ if(str[len-1] == '"') str[len-1] = 0; /* remove startquote, end also EOS marker */ memmove(str, str+1, len); } /** parse the TXT record into version and hash */ static int selfupdate_parse_rr(struct selfupdate* se, ldns_rr* txt) { char* hashstr; /* free old strings (if necessary) */ free(se->version_available); se->version_available = NULL; free(se->hash); se->hash = NULL; se->hashlen = 0; if(ldns_rr_get_type(txt) != LDNS_RR_TYPE_TXT) { log_err("selfupdate txt record wrong RR type"); return 0; } if(ldns_rr_rd_count(txt) < 2) { log_err("selfupdate txt record has wrong rd count"); return 0; } se->version_available = ldns_rdf2str(ldns_rr_rdf(txt, 0)); if(!se->version_available) { log_err("out of memory"); return 0; } hashstr = ldns_rdf2str(ldns_rr_rdf(txt, 1)); if(!hashstr) { log_err("out of memory"); return 0; } remove_quotes(se->version_available); remove_quotes(hashstr); /* parse the hash string */ se->hashlen = strlen(hashstr)/2; if(se->hashlen == 0 || se->hashlen > 8192) { log_err("selfupdate parse rr bad hash length"); free(hashstr); return 0; } se->hash = (uint8_t*)calloc(1, se->hashlen); if(ldns_hexstring_to_data(se->hash, hashstr) != (int)se->hashlen) { log_err("selfupdate failed to parse hash"); free(hashstr); return 0; } verbose(VERB_OPS, "version check %s with hash %s", se->version_available, hashstr); free(hashstr); return 1; } /** start HTTP fetch of newer version */ static int selfupdate_start_http_fetch(struct selfupdate* se) { char* server = "127.0.0.1"; char* domain = DNSSECTRIGGER_DOWNLOAD_HOST; /* get ip4 and ip6 simultaneously, with addr lookup and http_get */ se->addr_4 = outq_create(server, LDNS_RR_TYPE_A, domain, 1, NULL, 0, 0, DNS_PORT, 1, 0); se->addr_6 = outq_create(server, LDNS_RR_TYPE_AAAA, domain, 1, NULL, 0, 0, DNS_PORT, 1, 0); if(!se->addr_4 && !se->addr_6) { log_info("failed to create address lookups for download"); return 0; } /* one of the address lookups works, so keep going */ return 1; } /** see if version x is newer than y */ int version_is_newer(const char* x, const char* y) { const char* xat = x, *yat = y; /* version in NLnetLabs format: * 1.2.3 (or 1.2.3.4) * 1.2 is newer than 1.0 * 1.2.3 is newer than 1.2 * 1.2.3rc1 (for release candidates, 1.2.3 is better) * 1.2.3_20120101 (for snapshots, with date, full 1.2.3 is better) */ /* returns true if cannot determine and it is different */ if(x[0] == 0) return 0; /* the empty version is no fun, do not prefer it */ /* for the part before the rc or _, compare the numbers every dot */ while(xat[0] && yat[0]) { char* xend, *yend; long xnr = strtol(xat, &xend, 10); long ynr = strtol(yat, ¥d, 10); /* difference at this point */ if(xnr != ynr) { return (xnr > ynr); } xat = xend; yat = yend; if(xat[0] != '.') break; if(yat[0] != '.') break; xat++; yat++; } /* one is longer than the other? */ if(xat[0] == 0 && yat[0] == 0) return 0; /* equal */ if(xat[0] == '.') return 1; /* x=1.2.3 y=1.2 and x is newer */ if(yat[0] == '.') return 0; /* x=1.2 y=1.2.3, and thus not newer */ if(xat[0] == 0 && yat[0] != 0) return 1; /* x=1.2 y=1.2[rcorsnap] and thus x is newer */ if(xat[0] != 0 && yat[0] == 0) return 0; /* x=1.2[rcorsnap] y=1.2 and thus x is not newer */ /* both xat and yat are not at eos */ if(strncmp(xat, "rc", 2)==0 && strncmp(yat, "rc", 2)==0) { /* compare rc versions */ char* xend, *yend; long xrc = strtol(xat+2, &xend, 10); long yrc = strtol(yat+2, ¥d, 10); /* check that it ends correctly, otherwise it is unknown */ if(xend[0]==0 && yend[0]==0) return (xrc > yrc); } else if(xat[0]=='_' && yat[0]=='_') { /* compare snapshots 20110304, 20120506 and so on */ char* xend, *yend; long xsnap = strtol(xat+1, &xend, 10); long ysnap = strtol(yat+1, ¥d, 10); /* check that it ends correctly, otherwise it is unknown */ if(xend[0]==0 && yend[0]==0) return (xsnap > ysnap); } /* not a clue how to compare, such as rc with snapshot, if its * different you want to update */ if(strcmp(xat, yat) != 0) return 1; return 0; } /* * The TXT query is done. */ static void selfupdate_outq_done_txt(struct selfupdate* se, struct outq* outq, ldns_pkt* pkt, const char* reason) { ldns_rr_list* txt; verbose(VERB_ALGO, "selfupdate %s done: %s", outq->qname, reason?reason:"success"); outq_delete(se->txt_query); se->txt_query = NULL; if(reason || !pkt) { /* it failed */ ldns_pkt_free(pkt); /* in case there is a packet */ selfupdate_start_retry_timer(se); return; } /* check AD flag */ if(!ldns_pkt_ad(pkt)) { log_err("selfupdate TXT without AD flag encountered, skip"); ldns_pkt_free(pkt); selfupdate_start_retry_timer(se); return; } /* get TXT record */ txt = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_TXT, LDNS_SECTION_ANSWER); if(!txt || ldns_rr_list_rr_count(txt) == 0) { log_err("selfupdate answer has AD flag, but no TXT"); ldns_rr_list_deep_free(txt); ldns_pkt_free(pkt); selfupdate_start_retry_timer(se); return; } /* parse version and hash from it */ if(!selfupdate_parse_rr(se, ldns_rr_list_rr(txt, 0))) { log_err("cannot parse selfupdate TXT rr, skip"); ldns_rr_list_deep_free(txt); ldns_pkt_free(pkt); selfupdate_start_retry_timer(se); return; } /* update the time */ se->last_check = time(NULL); ldns_rr_list_deep_free(txt); ldns_pkt_free(pkt); /* see what we need to do now */ if(version_is_newer(se->version_available, PACKAGE_VERSION)) { /* start http fetch */ verbose(VERB_OPS, "version %s available, starting download", se->version_available); if(!selfupdate_start_http_fetch(se)) { log_err("selfupdate cannot start http fetch"); selfupdate_start_retry_timer(se); return; } } else { verbose(VERB_ALGO, "version %s available (it is not newer)", se->version_available); selfupdate_start_next_timer(se); } } /* * Initiate file download from http */ static int selfupdate_start_file_download(struct selfupdate* se, ldns_rr_list* addr) { char url[256]; char file[256]; char* reason = NULL; struct http_get** handle; char* ipstr; ldns_rr* rr; file[0]=0; url[0]=0; /* pick the next address (randomly) */ rr = http_pick_random_addr(addr); if(!rr || !ldns_rr_rdf(rr, 0)) { log_err("addr without rdata"); ldns_rr_free(rr); return 0; } ipstr = ldns_rdf2str(ldns_rr_rdf(rr, 0)); if(!ipstr) { log_err("out of memory"); ldns_rr_free(rr); return 0; } /* create the URL */ #ifdef HOOKS_OSX snprintf(file, sizeof(file), "dnssectrigger-%s.dmg", se->version_available); #elif defined(USE_WINSOCK) snprintf(file, sizeof(file), "dnssec_trigger_setup_%s.exe", se->version_available); #else /* UNIX */ snprintf(file, sizeof(file), "dnssec-trigger-%s.tar.gz", se->version_available); #endif snprintf(url, sizeof(url), "http://%s%s%s%s", DNSSECTRIGGER_DOWNLOAD_HOST, DNSSECTRIGGER_DOWNLOAD_URLPRE, se->test_flag?"test/":"", file); if(!(se->filename=strdup(file))) { log_err("out of memory"); ldns_rr_free(rr); free(ipstr); return 0; } /* start http_get */ verbose(VERB_ALGO, "fetch %s from %s", url, ipstr); if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_A) handle = &se->download_http4; else handle = &se->download_http6; ldns_rr_free(rr); http_get_delete(*handle); *handle = http_get_create(url, se->svr->base, NULL); if(!*handle) { log_err("out of memory"); http_get_delete(*handle); *handle = NULL; free(ipstr); return 0; } if(!http_get_fetch(*handle, ipstr, HTTP_PORT, &reason)) { log_err("update fetch failed: %s", reason?reason:"fail"); http_get_delete(*handle); *handle = NULL; free(ipstr); return 0; } free(ipstr); return 1; } /** attempt next address in the selfupdate addr list */ static int selfupdate_next_addr(struct selfupdate* se, ldns_rr_list* list) { while(list && ldns_rr_list_rr_count(list)) { if(selfupdate_start_file_download(se, list)) { return 1; } } return 0; } /** check hash on data segment */ static int software_hash_ok(struct selfupdate* se, struct http_get* hg) { unsigned char download_hash[LDNS_SHA256_DIGEST_LENGTH]; if(se->hashlen != LDNS_SHA256_DIGEST_LENGTH) { log_err("bad hash length from TXT record %d", (int)se->hashlen); return 0; } (void)ldns_sha256((unsigned char*)ldns_buffer_begin(hg->data), (unsigned int)ldns_buffer_limit(hg->data), download_hash); if(memcmp(download_hash, se->hash, se->hashlen) != 0) { log_err("hash mismatch:"); log_hex("download", download_hash, sizeof(download_hash)); log_hex("txtindns", se->hash, se->hashlen); return 0; } verbose(VERB_ALGO, "downloaded file sha256 is OK"); return 1; } /** write to temporary file */ static int selfupdate_write_file(struct selfupdate* se, struct http_get* hg) { char buf[1024]; FILE *out; /* get directory to store the file into */ #ifdef HOOKS_OSX char* dirname = UIDIR; char* slash="/"; #elif defined(USE_WINSOCK) char* dirname = w_lookup_reg_str("Software\\Unbound", "InstallLocation"); char* slash="\\"; if(!dirname) dirname = strdup(UIDIR); if(!dirname) { log_err("out of memory"); return 0; } #else /* UNIX */ char* dirname = "/tmp"; char* slash="/"; #endif snprintf(buf, sizeof(buf), "%s%s%s", dirname, slash, se->filename); if(se->download_file) selfupdate_delete_file(se); se->download_file = strdup(buf); if(!se->download_file) { log_err("out of memory"); fail: selfupdate_delete_file(se); #ifdef USE_WINSOCK free(dirname); #endif return 0; } out = fopen(se->download_file, "wb"); if(!out) { log_err("cannot open file %s: %s", se->download_file, strerror(errno)); goto fail; } if(!fwrite(ldns_buffer_begin(hg->data), 1, ldns_buffer_limit(hg->data), out)) { log_err("cannot write to file %s: %s", se->download_file, strerror(errno)); fclose(out); goto fail; } fclose(out); #ifdef USE_WINSOCK free(dirname); #endif return 1; } static void stop_other_http(struct selfupdate* se, struct http_get* hg) { if(hg == se->download_http4) { outq_delete(se->addr_6); se->addr_6 = NULL; ldns_rr_list_deep_free(se->addr_list_6); se->addr_list_6 = NULL; http_get_delete(se->download_http6); se->download_http6 = NULL; } else { outq_delete(se->addr_4); se->addr_4 = NULL; ldns_rr_list_deep_free(se->addr_list_4); se->addr_list_4 = NULL; http_get_delete(se->download_http4); se->download_http4 = NULL; } } void selfupdate_http_connected(struct selfupdate* se, struct http_get* hg) { /* we do not need the other one any more (happy eyeballs) */ stop_other_http(se, hg); } void selfupdate_http_get_done(struct selfupdate* se, struct http_get* hg, char* reason) { ldns_rr_list* list = (hg == se->download_http4)? se->addr_list_4:se->addr_list_6; struct http_get** handle = (hg == se->download_http4)? &se->download_http4:&se->download_http6; verbose(VERB_ALGO, "selfupdate download done %s", reason?reason:"success"); if(reason) { fail: /* try next address or fail completely */ if(selfupdate_next_addr(se, list)) return; /* we failed, see if the other is active or done */ if(hg == se->download_http4 && se->addr_6) { outq_delete(se->addr_4); se->addr_4 = NULL; } else if(hg == se->download_http6 && se->addr_4) { outq_delete(se->addr_6); se->addr_6 = NULL; } else { selfupdate_start_retry_timer(se); } http_get_delete(*handle); *handle = NULL; return; } verbose(VERB_ALGO, "done with success"); ldns_buffer_flip(hg->data); /* check data integrity */ if(!software_hash_ok(se, hg)) { log_err("bad hash on download of %s from %s", hg->url, hg->dest); goto fail; } /* stop the other attempt (if any) */ stop_other_http(se, hg); if(!selfupdate_write_file(se, hg)) { selfupdate_start_retry_timer(se); http_get_delete(*handle); *handle = NULL; return; } se->file_available = 1; http_get_delete(*handle); *handle = NULL; /* go and ask the user for permission */ se->update_available = 1; /* signal panel and get return command */ svr_signal_update(se->svr, se->version_available); } /* * The addr (A, AAAA) query is done. */ static void selfupdate_outq_done_addr(struct selfupdate* se, struct outq* outq, ldns_pkt* pkt, const char* reason) { ldns_rr_list* addr; verbose(VERB_ALGO, "selfupdate addr%s %s done: %s", outq->qtype==LDNS_RR_TYPE_A?"4":"6", outq->qname, reason?reason:"success"); if(reason || !pkt) { failed: /* it failed */ ldns_pkt_free(pkt); /* in case there is a packet */ /* see if the other query is active */ if(outq==se->addr_4 && se->addr_6) { outq_delete(outq); se->addr_4 = NULL; } else if(outq==se->addr_6 && se->addr_4) { outq_delete(outq); se->addr_6 = NULL; } else { selfupdate_start_retry_timer(se); } return; } /* check AD flag */ if(!ldns_pkt_ad(pkt)) { log_err("selfupdate addr without AD flag encountered, skip"); goto failed; } /* get addresses */ addr = ldns_pkt_rr_list_by_type(pkt, outq->qtype, LDNS_SECTION_ANSWER); if(!addr || ldns_rr_list_rr_count(addr) == 0) { log_err("selfupdate answer has AD flag, but no TXT"); ldns_rr_list_deep_free(addr); goto failed; } if(outq->qtype == LDNS_RR_TYPE_A) { ldns_rr_list_deep_free(se->addr_list_4); se->addr_list_4 = addr; } else { ldns_rr_list_deep_free(se->addr_list_6); se->addr_list_6 = addr; } ldns_pkt_free(pkt); pkt = NULL; /* start the download of the file */ if(!selfupdate_next_addr(se, addr)) { log_err("selfupdate could not initiate file download"); goto failed; } } void selfupdate_outq_done(struct selfupdate* se, struct outq* outq, ldns_pkt* pkt, const char* reason) { if(se->txt_query == outq) selfupdate_outq_done_txt(se, outq, pkt, reason); else if(se->addr_4 == outq || se->addr_6 == outq) selfupdate_outq_done_addr(se, outq, pkt, reason); else { log_err("internal error: selfupdate unknown outq? leaked"); log_info("reason: %s, outq %s %d %s %s %s", reason?reason:"null", outq->qname, (int)outq->qtype, outq->edns?"edns":"noedns", outq->cdflag?"cdflag":"nocdflag", outq->on_tcp?"tcp":"udp"); /* and ignore this to continue ... */ } } #ifdef HOOKS_OSX /* close sockets on svr */ static void svr_close_sockets(struct svr* svr) { struct sslconn* b; struct listen_list* l; struct probe_ip* p; /* do not cause traffic on the fds because the real daemon * is still using them */ for(b=svr->busy_list; b; b=b->next) { if(b->c) close(b->c->fd); } for(l=svr->listen; l; l=l->next) { if(l->c) close(l->c->fd); } for(p=svr->probes; p; p=p->next) { if(p->ds_c && p->ds_c->c) close(p->ds_c->c->fd); if(p->dnskey_c && p->dnskey_c->c) close(p->dnskey_c->c->fd); if(p->nsec3_c && p->nsec3_c->c) close(p->nsec3_c->c->fd); if(p->host_c && p->host_c->c) close(p->host_c->c->fd); if(p->http && p->http->cp) close(p->http->cp->fd); } if(svr->update) { if(svr->update->download_http4 && svr->update->download_http4->cp) close(svr->update->download_http4->cp->fd); if(svr->update->download_http6 && svr->update->download_http6->cp) close(svr->update->download_http6->cp->fd); if(svr->update->txt_query && svr->update->txt_query->c) close(svr->update->txt_query->c->fd); if(svr->update->addr_4 && svr->update->addr_4->c) close(svr->update->addr_4->c->fd); if(svr->update->addr_6 && svr->update->addr_6->c) close(svr->update->addr_6->c->fd); } } /* fork and exec the script that opens the dmg and runs installer */ static void osx_run_updater(char* filename) { pid_t pid = fork(); switch(pid) { default: /* main */ return; case -1: /* error */ log_err("cannot fork installscript: %s", strerror(errno)); return; case 0: /* child */ break; } /* close our sockets */ svr_close_sockets(global_svr); /* become process leader so we are not killed by installer unload of * plist file */ if(setsid() == -1) log_err("setsid failed: %s", strerror(errno)); /* run the install script */ if(execl(LIBEXEC_DIR "/dnssec-trigger-setdns.sh", LIBEXEC_DIR "/dnssec-trigger-setdns.sh", "install", filename, (char*)0) < 0) { log_err("cannot exec setdns install: %s", strerror(errno)); } exit(1); } #endif /* HOOKS_OSX */ /** do the software update install (system specific) */ static void selfupdate_do_install(struct selfupdate* se) { if(!se) return; if(!se->update_available) return; if(!se->file_available || !se->download_file) return; verbose(VERB_OPS, "software update, install of %s", se->download_file); if(se->svr->cfg->noaction) { verbose(VERB_OPS, "noaction is true, no install action"); return; } #ifdef USE_WINSOCK /* fork and exec the installer that will stop this program and update*/ /* Do not run updater from service, but from userspace, so that * tray icon gets started correctly and so on, and reboot warn dialog*/ /*win_run_updater(se->download_file);*/ /* this stops the filename from being deleted when we exit, * the installer deletes itself (with after reboot flag). */ free(se->download_file); se->download_file = NULL; se->file_available = 0; #elif defined(HOOKS_OSX) /* fork and exec installer */ osx_run_updater(se->download_file); /* stops filename from deleted by this daemon on exit, since * the postinstall makes us exit and the installer is deleted by * the fork-exec-ed script */ free(se->download_file); se->download_file = NULL; se->file_available = 0; #else log_err("on unix, do not know how to install. tarball %s (is deleted" "on exit of the daemon)", se->download_file); #endif } void selfupdate_userokay(struct selfupdate* se, int okay) { if(!se) return; if(se->user_replied) return; /* already replied, this is a duplicate */ /* is the user OK ? */ /* if not, note so we do not ask him again for 24h or next start */ se->user_replied = 1; se->user_okay = okay; /* if OK run installer (fork,exec because it updates this one) */ if(se->user_okay) { selfupdate_do_install(se); } } dnssec-trigger-0.13/riggerd/reshook.h0000664000175000017500000000532512275162157017276 0ustar wouterwouter/* * reshook.h - dnssec-trigger resolv.conf hooks for adjusting name resolution * * Copyright (c) 2011, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains the unbound hooks for adjusting the name resolution * on the system (to 127.0.0.1). */ #ifndef RESHOOKS_H #define RESHOOKS_H struct cfg; struct probe_ip; /** * Set the system to resolve at 127.0.0.1 (where unbound is running) * @param cfg: with config options. */ void hook_resolv_localhost(struct cfg* cfg); /** * Set the system to resolve at the list of 'cache' (recursive) probes in * the given list. The original servers are used, not DNSTCP recursive probes. * @param cfg: with config options. */ void hook_resolv_iplist(struct cfg* cfg, struct probe_ip* list); /** * Flush the DNS caches on the system, if somehow possible * @param cfg: with config options. */ void hook_resolv_flush(struct cfg* cfg); #ifdef HOOKS_OSX /** on OSX we need to restore resolv.conf after user login */ void restore_resolv_osx(struct cfg* cfg); #endif /* HOOKS_OSX */ /** * Unregister the override we put in place. * The override survives reboots, this uninit is for uninstall. */ void hook_resolv_uninstall(struct cfg* cfg); #endif /* RESHOOKS_H */ dnssec-trigger-0.13/riggerd/probe.c0000664000175000017500000012167312433577271016736 0ustar wouterwouter/* * probe.c - dnssec-trigger DNSSEC probes implementation * * Copyright (c) 2011, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains the probe implementation. */ #include "config.h" #include "probe.h" #include "svr.h" #include "cfg.h" #include "log.h" #include "netevent.h" #include "net_help.h" #include "ubhook.h" #include "reshook.h" #include "http.h" #include "update.h" #include /* create probes for the ip addresses in the string */ static void probe_spawn(const char* ip, int recurse, int dnstcp, struct ssllist* ssldns, int port); /* set timeout on outq and create UDP query and send it */ static int outq_settimeout_and_send(struct outq* outq); /* send outq over tcp */ static int outq_send_tcp(struct outq* outq); /* a query is done, check probe to see if failed, succeed or wait */ static void probe_partial_done(struct probe_ip* p, const char* in, const char* reason); /* a probe is done (fail or success) see global progress */ static void probe_done(struct probe_ip* p); void probe_start(char* ips) { char* next; struct svr* svr = global_svr; if(svr->http) { http_general_delete(svr->http); svr->http = NULL; } if(svr->probes) { /* clear existing probe list */ probe_list_delete(svr->probes); svr->probes = NULL; if(svr->num_probes_done < svr->num_probes) { verbose(VERB_QUERY, "probes cancelled due to fast " "net change"); } svr->num_probes_done = 0; svr->num_probes = 0; } /* spawn a probe for every IP address in the list */ svr->saw_first_working = 0; svr->saw_direct_work = 0; svr->saw_dnstcp_work = 0; svr->probe_direct = 0; svr->probe_dnstcp = 0; while(*ips == ' ') ips++; while(ips && *ips) { if((next = strchr(ips, ' ')) != NULL) { *next++ = 0; while(*next == ' ') next++; } probe_spawn(ips, 1, 0, 0, DNS_PORT); ips = next; } svr->num_probes_to_cache = svr->num_probes; /* (if no resulting probes), check result now */ if(!svr->probes) probe_cache_done(); else if(svr->forced_insecure) { verbose(VERB_OPS, "probe started: but still forced insecure"); /* call it right away, so the user does not have to wait */ probe_setup_hotspot_signon(svr); } else { /* there are cache DNS, and not forced insecure: check HTTP */ if(!svr->http && svr->cfg->num_http_urls != 0) { svr->http = http_general_start(svr); if(!svr->http) log_err("out of memory"); svr->http->saw_http_work = 0; } } } void probe_delete(struct probe_ip* p) { if(!p) return; free(p->name); free(p->reason); free(p->http_desc); SSL_CTX_free(p->sslctx); outq_delete(p->ds_c); outq_delete(p->dnskey_c); outq_delete(p->nsec3_c); outq_delete(p->host_c); http_get_delete(p->http); free(p); } void probe_list_delete(struct probe_ip* list) { struct probe_ip* p=list, *np; while(p) { np = p->next; probe_delete(p); p = np; } } /** get random signed TLD */ static const char* get_random_dest(void) { const char* choices[] = { "se.", "uk.", "nl.", "de." }; return choices[ ldns_get_random() % 4 ]; } /** get random NSEC3 signed TLD */ static const char* get_random_nsec3_dest(void) { const char* choices[] = { "_probe.us.com.", "_probe.uk.com.", "_probe.kr.com.", "_probe.uk.net." }; return choices[ ldns_get_random() % 4 ]; } /** the NSEC3 qtype to elicit it (a nodata answer) */ #define PROBE_NSEC3_QTYPE LDNS_RR_TYPE_NULL /** get random authority server */ static const char* get_random_auth_ip4(void) { /* list of root servers */ const char* choices[] = { "198.41.0.4", /* a */ "192.228.79.201", /* b */ "192.33.4.12", /* c */ "199.7.91.13", /* d */ "192.203.230.10", /* e */ "192.5.5.241", /* f */ "192.112.36.4", /* g */ "128.63.2.53", /* h */ "192.36.148.17", /* i */ "192.58.128.30", /* j */ "193.0.14.129", /* k */ "199.7.83.42", /* l */ "202.12.27.33" /* m */ }; return choices[ ldns_get_random() % 13 ]; } /** get random authority server */ static const char* get_random_auth_ip6(void) { /* list of root servers */ const char* choices[] = { "2001:503:ba3e::2:30", /* a */ "2001:500:2::c", /* c */ "2001:500:2d::d", /* d */ "2001:500:2f::f", /* f */ "2001:500:1::803f:235", /* h */ "2001:7fe::53", /* i */ "2001:503:c27::2:30", /* j */ "2001:7fd::1", /* k */ "2001:500:3::42", /* l */ "2001:dc3::35" /* m */ }; return choices[ ldns_get_random() % 10 ]; } static const char* get_random_tcp80_ip4(struct cfg* cfg) { if(cfg->num_tcp80_ip4 == 0) return NULL; return strlist_get_num(cfg->tcp80_ip4, ((unsigned)ldns_get_random())%((unsigned)cfg->num_tcp80_ip4)); } static const char* get_random_tcp80_ip6(struct cfg* cfg) { if(cfg->num_tcp80_ip6 == 0) return NULL; return strlist_get_num(cfg->tcp80_ip6, ((unsigned)ldns_get_random())%((unsigned)cfg->num_tcp80_ip6)); } static const char* get_random_tcp443_ip4(struct cfg* cfg) { if(cfg->num_tcp443_ip4 == 0) return NULL; return strlist_get_num(cfg->tcp443_ip4, ((unsigned)ldns_get_random())%((unsigned)cfg->num_tcp443_ip4)); } static const char* get_random_tcp443_ip6(struct cfg* cfg) { if(cfg->num_tcp443_ip6 == 0) return NULL; return strlist_get_num(cfg->tcp443_ip6, ((unsigned)ldns_get_random())%((unsigned)cfg->num_tcp443_ip6)); } static struct ssllist* get_random_ssl443_ip4(struct cfg* cfg) { if(cfg->num_ssl443_ip4 == 0) return NULL; return ssllist_get_num(cfg->ssl443_ip4, ((unsigned)ldns_get_random())%((unsigned)cfg->num_ssl443_ip4)); } static struct ssllist* get_random_ssl443_ip6(struct cfg* cfg) { if(cfg->num_ssl443_ip6 == 0) return NULL; return ssllist_get_num(cfg->ssl443_ip6, ((unsigned)ldns_get_random())%((unsigned)cfg->num_ssl443_ip6)); } int probe_is_cache(struct probe_ip* p) { return !p->to_auth && !p->ssldns && !p->dnstcp && !p->to_http; } /** check if hash of x is the given hash, error or NULL on success. */ static char* match_hash(struct hashlist* he, X509* x) { unsigned char hash[EVP_MAX_MD_SIZE]; unsigned int len = (unsigned int)sizeof(hash); /* always sha256 now */ if(!X509_digest(x, EVP_sha256(), hash, &len)) { log_err("out of memory"); return "out of memory in X509_digest"; } if(verbosity >= 3) { char buf[1024]; char* at = buf; size_t blen = sizeof(buf); unsigned int i; for(i=0; ihashlen) { /* should not happen, since we test sha256 length of * the cfg hash we read in */ return "SSL certificate hash length is wrong"; } if(memcmp(hash, he->hash, len) != 0) { return "SSL certificate on internet does not match stored hash (ssl intercepted?)"; } return 0; } /** check list of hashes, error string or NULL on success */ static char* match_hashes(struct hashlist* list, X509* x) { struct hashlist* h; char* reason = "Internal error: no hashlist but comparison"; for(h=list; h; h=h->next) if( (reason=match_hash(h, x)) == NULL) return NULL; return reason; } /** check SSL certificate on probe (that is otherwise DNSSEC OK) */ static const char* check_ssl(struct outq* outq) { /* verify the ssl connection */ /* there is also the SSL_get_verify_result, but that does PKIX * verification, we simply check the entire self-signed cert with * a stored hash, you can compute this hash with the command * openssl x509 -sha256 -fingerprint -in server.pem */ X509* x = SSL_get_peer_certificate(outq->c->ssl); if(!outq->probe->ssldns->hashes) { /* no stored hash */ X509_free(x); } else if(x) { char* reason = match_hashes(outq->probe->ssldns->hashes, x); X509_free(x); if(reason) return reason; } else { return "No SSL certificate on internet but have stored hash (ssl intercepted?)"; } /* all OK */ return NULL; } /** outq is done, NULL reason for success */ static void outq_done(struct outq* outq, const char* reason) { struct probe_ip* p = outq->probe; const char* in = NULL; if(!p) { selfupdate_outq_done(global_svr->update, outq, NULL, reason); return; } if(p->sslctx && !reason) { reason = check_ssl(outq); } if(p->nsec3_c == outq) { outq_delete(p->nsec3_c); p->nsec3_c = NULL; in = "NSEC3"; } else if(p->host_c == outq) { http_host_outq_done(p, reason); return; } else if(p->ds_c == outq) { outq_delete(p->ds_c); p->ds_c = NULL; in = "DS"; } else { outq_delete(p->dnskey_c); p->dnskey_c = NULL; in = "DNSKEY"; } /* This is a good place for test code. if(!p->ssldns && !reason) reason = "failed for test purposes"; */ probe_partial_done(p, in, reason); } /** test if type is present in authority section of returned packet */ static int check_type_in_authority(ldns_pkt* p, int t) { ldns_rr_list *l = ldns_pkt_rr_list_by_type(p, t, LDNS_SECTION_AUTHORITY); if(!l) { return 0; } ldns_rr_list_deep_free(l); return 1; } /** test if type is present in returned packet */ static int check_type_in_answer(ldns_pkt* p, int t) { ldns_rr_list *l = ldns_pkt_rr_list_by_type(p, t, LDNS_SECTION_ANSWER); if(!l) { return 0; } ldns_rr_list_deep_free(l); return 1; } /** test if the right denial (from parent) is in the returned packet */ static int check_denial_in_answer(ldns_pkt* p, const char* dname) { size_t i; ldns_rdf* d = ldns_dname_new_frm_str(dname); ldns_rr_list *l = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_SOA, LDNS_SECTION_AUTHORITY); if(!d) { ldns_rr_list_deep_free(l); return 0; /* robustness, the name should parse */ } if(!l) { ldns_rdf_deep_free(d); return 0; } for(i=0; i= VERB_ALGO) { if(!outq->probe) { verbose(VERB_ALGO, "%s %s received", outq->qname, outq->qtype==LDNS_RR_TYPE_TXT?"TXT":( outq->qtype==LDNS_RR_TYPE_A?"A":( outq->qtype==LDNS_RR_TYPE_AAAA?"AAAA":"other" ))); } else if(outq->probe->to_http) { verbose(VERB_ALGO, "from %s %s received", outq->probe->name, outq->probe->http_ip6? "HTTPip6":"HTTPip4"); } else verbose(VERB_ALGO, "from %s %s %s received", outq->probe->name, outq->qtype==PROBE_NSEC3_QTYPE?"NSEC3":( outq->qtype==LDNS_RR_TYPE_DNSKEY?"DNSKEY":"DS"), outq->probe->ssldns?"SSLprobe":( outq->probe->dnstcp?"TCPprobe":( outq->probe->to_auth?"AUTHprobe":"cacheprobe" ))); log_hex("packet", wire, len); } if(outq->probe) outq->probe->got_packet = 1; if(!LDNS_QR_WIRE(wire)) { outq_done(outq, "reply without QR flag"); return; } if(LDNS_TC_WIRE(wire)) { /* start TCP query and wait for it */ verbose(VERB_ALGO, "%s: TC flag, switching to TCP", outq->probe?outq->probe->name:outq->qname); if(!outq_send_tcp(outq)) { outq_done(outq, "cannot send TCP query after TC flag"); } return; } if( (s=ldns_wire2pkt(&p, wire, len)) != LDNS_STATUS_OK) { snprintf(reason, sizeof(reason), "cannot disassemble reply: %s", ldns_get_errorstr_by_id(s)); outq_done(outq, reason); return; } if(!p) { outq_done(outq, "out of memory"); return; } if(verbosity >= VERB_ALGO) { char* desc = ldns_pkt2str(p); if(desc) verbose(VERB_ALGO, "%s", desc); free(desc); } /* does DNS work? */ if(ldns_pkt_get_rcode(p) != LDNS_RCODE_NOERROR) { char* r = ldns_pkt_rcode2str(ldns_pkt_get_rcode(p)); snprintf(reason, sizeof(reason), "no answer, %s", r?r:"(out of memory)"); outq_done(outq, reason); LDNS_FREE(r); ldns_pkt_free(p); return; } if(!outq->probe) { selfupdate_outq_done(global_svr->update, outq, p, NULL); return; } /* if this all OK, and addr, then use http addr process */ if(outq == outq->probe->host_c) { /* this routine frees pkt */ http_host_outq_result(outq->probe, p); return; } /* test EDNS0 presence, of OPT record */ /* LDNS forgets during pkt parse, but we test the ARCOUNT; * 0 additionals means no EDNS(on the wire), and after parsing the * same additional RRs as before means no EDNS OPT */ if(LDNS_ARCOUNT(wire) == 0 || ldns_pkt_arcount(p) == LDNS_ARCOUNT(wire)) { outq_done(outq, "no EDNS"); ldns_pkt_free(p); return; } /* test if the type, RRSIG present */ if(outq->qtype == PROBE_NSEC3_QTYPE) { if(!check_type_in_authority(p, LDNS_RR_TYPE_NSEC3)) { outq_done(outq, "no NSEC3 in nodata reply"); ldns_pkt_free(p); return; } rrsig_in_auth = 1; } else if(!check_type_in_answer(p, (int)outq->qtype)) { if(outq->qtype == LDNS_RR_TYPE_DS) { /* if type DS, and it is not present, it is OK if * we get a proper denial from the parent with NSEC */ if(!check_denial_in_answer(p, outq->qname)) { outq_done(outq, "no DS and no proper " "denial in reply"); ldns_pkt_free(p); return; } if(!check_type_in_authority(p, LDNS_RR_TYPE_NSEC)) { outq_done(outq, "no NSEC in denial reply"); ldns_pkt_free(p); return; } rrsig_in_auth = 1; } else { /* failed to find type */ char* r = ldns_rr_type2str(outq->qtype); snprintf(reason, sizeof(reason), "no %s in reply", r?r:"DNSSEC-RRTYPE"); outq_done(outq, reason); LDNS_FREE(r); ldns_pkt_free(p); return; } } if(rrsig_in_auth) { if(!check_type_in_authority(p, LDNS_RR_TYPE_RRSIG)) { outq_done(outq, "no RRSIGs in reply"); ldns_pkt_free(p); return; } } else { if(!check_type_in_answer(p, LDNS_RR_TYPE_RRSIG)) { outq_done(outq, "no RRSIGs in reply"); ldns_pkt_free(p); return; } } /* for authoritative probes we try to detect transparent proxies * that mess with the answer, we have to avoid them, if they * worked well, the DHCP DNS cache would work well. */ if(!outq->recurse) { if(LDNS_RA_WIRE(wire)) { outq_done(outq, "authority response has RA flag"); ldns_pkt_free(p); return; } if(!LDNS_AA_WIRE(wire)) { outq_done(outq, "authority response misses AA flag"); ldns_pkt_free(p); return; } } outq_done(outq, NULL); ldns_pkt_free(p); } int outq_handle_udp(struct comm_point* c, void* my_arg, int error, struct comm_reply *reply_info) { struct outq* outq = (struct outq*)my_arg; uint8_t* wire = ldns_buffer_begin(c->buffer); size_t len = ldns_buffer_limit(c->buffer); if(error != NETEVENT_NOERROR) { verbose(VERB_ALGO, "udp receive error"); return 0; } if(sockaddr_cmp(&outq->addr, outq->addrlen, &reply_info->addr, reply_info->addrlen) != 0) { /* from wrong source, keep listening for the real one */ log_addr(VERB_ALGO, "reply from wrong source", &reply_info->addr, reply_info->addrlen); return 0; } /* quick sanity check */ if(len < LDNS_HEADER_SIZE || LDNS_ID_WIRE(wire) != outq->qid || !LDNS_QR_WIRE(wire)) { verbose(VERB_ALGO, "%4.4x wire, qid %4.4x, qr %s", LDNS_ID_WIRE(wire), outq->qid, LDNS_QR_WIRE(wire)?"yes":"no"); /* wait for the real reply */ verbose(VERB_ALGO, "ignored bad reply (tooshort, wrong qid or noQR)"); return 0; } comm_timer_disable(outq->timer); outq_check_packet(outq, wire, len); return 0; } static int create_probe_query(struct outq* outq, ldns_buffer* buffer) { uint16_t flags = 0; ldns_pkt* pkt = NULL; ldns_status status; if(outq->recurse) flags |= LDNS_RD; if(outq->cdflag) flags |= LDNS_CD; status = ldns_pkt_query_new_frm_str(&pkt, outq->qname, outq->qtype, LDNS_RR_CLASS_IN, flags); if(status != LDNS_STATUS_OK) { log_err("could not pkt_query_new %s", ldns_get_errorstr_by_id(status)); return 0; } if(outq->edns) { ldns_pkt_set_edns_do(pkt, 1); ldns_pkt_set_edns_udp_size(pkt, 4096); } else { ldns_pkt_set_edns_do(pkt, 0); } ldns_pkt_set_id(pkt, outq->qid); ldns_buffer_clear(buffer); status = ldns_pkt2buffer_wire(buffer, pkt); if(status != LDNS_STATUS_OK) { log_err("could not host2wire packet %s", ldns_get_errorstr_by_id(status)); ldns_pkt_free(pkt); return 0; } ldns_buffer_flip(buffer); ldns_pkt_free(pkt); return 1; } struct outq* outq_create(const char* ip, int tp, const char* domain, int recurse, struct probe_ip* p, int tcp, int onssl, int port, int edns, int cdflag) { int fd; struct outq* outq = (struct outq*)calloc(1, sizeof(*outq)); /* open UDP socket */ if(!outq) { log_err("out of memory"); return NULL; } outq->qname = domain; outq->probe = p; outq->qtype = (uint16_t)tp; outq->qid = (uint16_t)ldns_get_random(); outq->recurse = recurse; outq->on_ssl = onssl; outq->port = port; outq->edns = edns; outq->cdflag = cdflag; if(!ipstrtoaddr(ip, port, &outq->addr, &outq->addrlen)) { log_err("could not parse ip %s", ip); free(outq); return NULL; } outq->timer = comm_timer_create(global_svr->base, &outq_timeout, outq); if(!outq->timer) { log_err("cannot create timer"); outq_delete(outq); return NULL; } if(tcp || onssl){ /* also sets timeout, timer */ /* we test if it works, because if it were to call outq_done * with an error reason the query counts go wrong and the * probe does not work correctly. */ if(!outq_send_tcp(outq)) { outq_delete(outq); return NULL; } return outq; } fd = socket(strchr(ip, ':')?PF_INET6:PF_INET, SOCK_DGRAM, IPPROTO_UDP); if(fd == -1) { #ifndef USE_WINSOCK if(errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) { if(verbosity <= 2) { free(outq); return NULL; } } #else if(WSAGetLastError() == WSAEAFNOSUPPORT || WSAGetLastError() == WSAEPROTONOSUPPORT) { if(verbosity <= 2) { free(outq); return NULL; } } #endif log_err("socket %s udp: %s", strchr(ip, ':')?"ip6":"ip4", strerror(errno)); free(outq); return NULL; } outq->c = comm_point_create_udp(global_svr->base, fd, global_svr->udp_buffer, &outq_handle_udp, outq); if(!outq->c) { #ifndef USE_WINSOCK close(fd); #else closesocket(fd); #endif free(outq); return NULL; } /* set timeout on commpoint */ outq->timeout = QUERY_START_TIMEOUT; /* msec */ if(!outq_settimeout_and_send(outq)) { outq_delete(outq); return NULL; } return outq; } void outq_delete(struct outq* outq) { if(!outq) return; comm_timer_delete(outq->timer); comm_point_delete(outq->c); free(outq); } static void outq_settimer(struct outq* outq) { struct timeval tv; tv.tv_sec = outq->timeout/1000; tv.tv_usec = (outq->timeout%1000)*1000; comm_timer_set(outq->timer, &tv); } static int outq_settimeout_and_send(struct outq* outq) { ldns_buffer* udpbuf = global_svr->udp_buffer; outq_settimer(outq); /* create and send a message over the fd */ if(!create_probe_query(outq, udpbuf)) { log_err("cannot create probe query"); return 0; } /* send it */ if(!comm_point_send_udp_msg(outq->c, udpbuf, (struct sockaddr*)&outq->addr, outq->addrlen)) { log_err("could not UDP send to ip %s", outq->probe->name); return 0; } return 1; } void outq_timeout(void* arg) { struct outq* outq = (struct outq*)arg; char *t = ldns_rr_type2str(outq->qtype); verbose(VERB_ALGO, "%s %s: UDP timeout after %d msec", outq->probe?outq->probe->name:outq->qname, t, outq->timeout); free(t); if(outq->timeout > QUERY_END_TIMEOUT) { /* too many timeouts */ outq_done(outq, "timeout"); return; } /* resend */ outq->timeout *= 2; if(!outq_settimeout_and_send(outq)) { outq_done(outq, "could not resend after timeout"); return; } } /** use next free buffer to service a tcp query */ static int outq_tcp_take_into_use(struct outq* outq) { int s; /* open socket */ #ifdef INET6 if(strchr(outq->probe->name, ':')) s = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP); else #endif s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if(s == -1) { #ifndef USE_WINSOCK if(errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) { if(verbosity <= 2) { return 0; } } log_err("outgoing tcp: socket: %s", strerror(errno)); #else if(WSAGetLastError() == WSAEAFNOSUPPORT || WSAGetLastError() == WSAEPROTONOSUPPORT) { if(verbosity <= 2) { return 0; } } log_err("outgoing tcp: socket: %s", wsa_strerror(WSAGetLastError())); #endif log_addr(VERB_QUERY, "failed address", &outq->addr, outq->addrlen); return 0; } fd_set_nonblock(s); if(connect(s, (struct sockaddr*)&outq->addr, outq->addrlen) == -1) { #ifndef USE_WINSOCK #ifdef EINPROGRESS if(errno != EINPROGRESS) { #else if(1) { #endif log_err("outgoing tcp: connect: %s", strerror(errno)); close(s); #else /* USE_WINSOCK */ if(WSAGetLastError() != WSAEINPROGRESS && WSAGetLastError() != WSAEWOULDBLOCK) { closesocket(s); #endif log_addr(VERB_OPS, "failed address", &outq->addr, outq->addrlen); return 0; } } if(outq->on_ssl) { outq->c->ssl = outgoing_ssl_fd(outq->probe->sslctx, s); if(!outq->c->ssl) { outq->c->fd = s; comm_point_close(outq->c); return 0; } #ifdef USE_WINSOCK comm_point_tcp_win_bio_cb(outq->c, outq->c->ssl); #endif outq->c->ssl_shake_state = comm_ssl_shake_write; } outq->c->repinfo.addrlen = outq->addrlen; memcpy(&outq->c->repinfo.addr, &outq->addr, outq->addrlen); outq->c->tcp_is_reading = 0; outq->c->tcp_byte_count = 0; comm_point_start_listening(outq->c, s, -1); return 1; } static int outq_send_tcp(struct outq* outq) { /* send outq over tcp, stop UDP in progress (if any) */ if(outq->c) comm_point_delete(outq->c); outq->timeout = QUERY_TCP_TIMEOUT; outq->on_tcp = 1; outq->qid = (uint16_t)ldns_get_random(); outq->c = comm_point_create_tcp_out(global_svr->base, 65553, outq_handle_tcp, outq); if(!outq->c) { log_err("cannot create tcp comm point, out of memory"); return 0; } if(!create_probe_query(outq, outq->c->buffer)) return 0; if(!outq_tcp_take_into_use(outq)) return 0; outq_settimer(outq); return 1; } int outq_handle_tcp(struct comm_point* c, void* my_arg, int error, struct comm_reply* ATTR_UNUSED(reply_info)) { struct outq* outq = (struct outq*)my_arg; uint8_t* wire = ldns_buffer_begin(c->buffer); size_t len = ldns_buffer_limit(c->buffer); if(error != NETEVENT_NOERROR) { if(error == NETEVENT_CLOSED) outq_done(outq, "TCP connection failure"); else outq_done(outq, "TCP receive error"); return 0; } /* quick sanity check */ if(len < LDNS_HEADER_SIZE) { outq_done(outq, "TCP reply with short header"); return 0; } if(LDNS_ID_WIRE(wire) != outq->qid) { outq_done(outq, "TCP reply with wrong ID"); return 0; } comm_timer_disable(outq->timer); outq_check_packet(outq, wire, len); return 0; } static int addr_is_localhost(const char* ip) { struct sockaddr_storage addr; socklen_t len; struct sockaddr_storage lo; socklen_t lolen; /* unified print format for ipv4 addresses */ if(strcmp(ip, "127.0.0.1") == 0) return 1; /* only for IPv6 do we need more tests */ if(!strchr(ip, ':')) return 0; /* detect ::ffff:127.0.0.1 */ if(strstr(ip, "127.0.0.1")) return 1; /* detect ::1 but there are many ways to denote that IPv6 */ if(!ipstrtoaddr(ip, DNS_PORT, &addr, &len)) { return 0; /* it is not localhost, but unparseable */ } if(!ipstrtoaddr("::1", DNS_PORT, &lo, &lolen)) { return 0; /* internal error or no IPv6 */ } return (sockaddr_cmp_addr(&lo, lolen, &addr, len) == 0); } static void probe_spawn(const char* ip, int recurse, int dnstcp, struct ssllist* ssldns, int port) { const char* dest; struct probe_ip* p; if(!ip || ip[0]==0) return; /* create a probe for this IP */ p = (struct probe_ip*)calloc(1, sizeof(*p)); if(!p) { log_err("out of memory"); return; } /* make sure the IP address is not 127.0.0.1 or ::1, that would * create a forward-loop for the resolver */ if(addr_is_localhost(ip)) { free(p); verbose(VERB_ALGO, "skip localhost address %s", ip); return; } /* create probe structure and register it */ p->to_auth = !recurse; p->dnstcp = dnstcp; p->ssldns = ssldns; p->port = port; p->got_packet = 0; p->name = strdup(ip); if(!p->name) { free(p); log_err("out of memory"); return; } if(p->ssldns) { /* this could contain verification certificates */ p->sslctx = connect_sslctx_create(NULL, NULL, NULL); if(!p->sslctx) { log_err("could not create sslctx for %s", p->name); probe_delete(p); return; } } /* send the queries */ dest = get_random_dest(); verbose(VERB_ALGO, "probe %s %s %s (tld %s)", p->name, (recurse?"rec":"norec"), ssldns?"ssl":(dnstcp?"tcp":"udp"), dest); /* send the probe queries and wait for reply */ p->dnskey_c = outq_create(p->name, LDNS_RR_TYPE_DNSKEY, ".", recurse, p, dnstcp, ssldns!=0, port, 1, 1); p->ds_c = outq_create(p->name, LDNS_RR_TYPE_DS, dest, recurse, p, dnstcp, ssldns!=0, port, 1, 1); if(!p->ds_c || !p->dnskey_c) { log_err("could not send queries for probe"); probe_delete(p); return; } if(recurse && !dnstcp) { /* for cache test NSEC3 */ const char* nd = get_random_nsec3_dest(); verbose(VERB_ALGO, "nsec3 query %s", nd); p->nsec3_c = outq_create(p->name, PROBE_NSEC3_QTYPE, nd, recurse, p, dnstcp, ssldns!=0, port, 1, 1); if(!p->nsec3_c) { log_err("could not send nsec3 query for probe"); probe_delete(p); return; } } /* put it in the svr list */ p->next = global_svr->probes; global_svr->probes = p; global_svr->num_probes++; } /** start probes for direct DNS authority server connection */ static void probe_spawn_direct(void) { int nump = global_svr->num_probes; /* try both IP4 and IP6, one that works is enough */ verbose(VERB_ALGO, "probe authority servers"); probe_spawn(get_random_auth_ip4(), 0, 0, 0, DNS_PORT); probe_spawn(get_random_auth_ip6(), 0, 0, 0, DNS_PORT); if(global_svr->num_probes == nump) { /* failed to create the probes */ /* not a loop since svr->probe_direct is true */ probe_cache_done(); } } /** start probes for TCP to open resolvers on non53 port numbers */ static void probe_spawn_dnstcp(void) { /* try ip4 and ip6, on port 80 and 443 (if configured) */ verbose(VERB_ALGO, "probe dnstcp servers"); probe_spawn(get_random_tcp80_ip4(global_svr->cfg), 1, 1, 0, 80); probe_spawn(get_random_tcp80_ip6(global_svr->cfg), 1, 1, 0, 80); probe_spawn(get_random_tcp443_ip4(global_svr->cfg), 1, 1, 0, 443); probe_spawn(get_random_tcp443_ip6(global_svr->cfg), 1, 1, 0, 443); } /** start probes for SSL DNS to open resolvers */ static void probe_spawn_ssldns(void) { struct ssllist* s4 = get_random_ssl443_ip4(global_svr->cfg); struct ssllist* s6 = get_random_ssl443_ip6(global_svr->cfg); verbose(VERB_ALGO, "probe ssl dns servers"); if(s4) probe_spawn(s4->str, 1, 1, s4, 443); if(s6) probe_spawn(s6->str, 1, 1, s6, 443); } void probe_unsafe_test(void) { int nurl = global_svr->cfg->num_http_urls; verbose(VERB_OPS, "test unsafe probe combination started"); /* pretend there is no http probing */ global_svr->cfg->num_http_urls = 0; probe_start("127.0.0.3"); global_svr->cfg->num_http_urls = nurl; /* pretend we got a reply from the cache (so not disconnected) */ if(global_svr->probes) global_svr->probes->got_packet = 1; global_svr->probe_direct = 1; probe_spawn("127.0.0.4", 0, 0, 0, DNS_PORT); global_svr->probe_dnstcp = 1; probe_spawn("127.0.0.5", 1, 1, 0, 80); probe_spawn("127.0.0.6", 1, 1, 0, 443); if(global_svr->cfg->ssl443_ip4) probe_spawn("127.0.0.7", 1, 1, global_svr->cfg->ssl443_ip4, 443); } void probe_tcp_test(void) { int nurl = global_svr->cfg->num_http_urls; verbose(VERB_OPS, "test tcp probe combination started"); /* pretend there is no http probing */ global_svr->cfg->num_http_urls = 0; probe_start("127.0.0.3"); global_svr->cfg->num_http_urls = nurl; global_svr->probe_direct = 1; probe_spawn("127.0.0.4", 0, 0, 0, DNS_PORT); global_svr->tcp_timer_used = 1; /* avoid retry after 20 sec */ } void probe_ssl_test(void) { int nurl = global_svr->cfg->num_http_urls; verbose(VERB_OPS, "test ssl probe combination started"); /* pretend there is no http probing */ global_svr->cfg->num_http_urls = 0; probe_start("127.0.0.3"); global_svr->cfg->num_http_urls = nurl; global_svr->probe_direct = 1; probe_spawn("127.0.0.4", 0, 0, 0, DNS_PORT); global_svr->probe_dnstcp = 1; probe_spawn_ssldns(); global_svr->tcp_timer_used = 1; /* avoid retry after 20 sec */ } void probe_http_test(void) { struct cfg* cfg = global_svr->cfg; struct strlist2* old_http_urls = cfg->http_urls; struct strlist2* old_http_urls_last = cfg->http_urls_last; int old_num_http_urls = cfg->num_http_urls; struct strlist2 fake; verbose(VERB_OPS, "test http probe url started"); fake.next = NULL; /* lookup of existing URL but we give wrong contents */ fake.str1 = "http://open.nlnetlabs.nl/index.html"; fake.str2 = "NoSuchString12345"; cfg->http_urls = &fake; cfg->http_urls_last = &fake; cfg->num_http_urls = 1; global_svr->skip_http = 0; cmd_reprobe(); cfg->http_urls = old_http_urls; cfg->http_urls_last = old_http_urls_last; cfg->num_http_urls = old_num_http_urls; } /* stop unfininished probes and remove them */ static void stop_unfinished_probes(void) { struct probe_ip* p, *prev = NULL, *np; for(p = global_svr->probes; p; p = np) { np = p->next; if(!p->finished) { if(prev) prev->next = p->next; else global_svr->probes = p->next; verbose(VERB_ALGO, "stop %s: not needed", p->name); probe_delete(p); } else { prev = p; } } } /* see if there are working dnstcp probes */ int probe_has_work_tcp(struct svr* svr, int port, int ip6, int ssl) { struct probe_ip* p; for(p = svr->probes; p; p = p->next) { if(p->works && p->dnstcp && p->port == port) { if(ssl && !p->ssldns) continue; if(!ssl && p->ssldns) continue; if(ip6 && strchr(p->name, ':')) return 1; if(!ip6 && !strchr(p->name, ':')) return 1; } } return 0; } /** see if probe totally done or we have to wait more */ static void probe_partial_done(struct probe_ip* p, const char* in, const char* reason) { if(!reason && (p->ds_c || p->dnskey_c || p->nsec3_c)) { /* this one success but wait for the other one */ verbose(VERB_ALGO, "probe %s: %s completed successfully", p->name, in); return; } if(reason) { verbose(VERB_ALGO, "probe %s: failed: %s in %s", p->name, reason, in); /* stop other probe (if any), it failed */ outq_delete(p->ds_c); p->ds_c = NULL; outq_delete(p->dnskey_c); p->dnskey_c = NULL; outq_delete(p->nsec3_c); p->nsec3_c = NULL; /* note failure */ p->reason = strdup(reason); p->works = 0; } else { verbose(VERB_ALGO, "probe %s: %s completed successfully", p->name, in); p->works = 1; } p->finished = 1; global_svr->num_probes_done++; probe_done(p); } /* once a probe completes, do this: * if this probe succeeds and it is the first to do so, set unbound_fwd. * if all probes are done and have successes, set unbound_fwd. * if all probes failed DNSSEC, spawn a probe for DNS-direct. * if all probes failed and dns-direct failed, we fail. * if all probes failed and dns-direct works, set unbound_fwd. * * p is the probe that is done now. */ static void probe_done(struct probe_ip* p) { struct svr* svr = global_svr; if(p->works) { if(!svr->probe_dnstcp && !svr->probe_direct && !svr->saw_first_working) { svr->saw_first_working = 1; /* if works, not forced_insecure and http works (or * did not get probed because not configured) then * we can already use this cache-DNS now before all * probes are done */ if(!svr->forced_insecure && (!svr->http || svr->skip_http || svr->http->saw_http_work)) { probe_setup_cache(svr, p); } } else if(svr->probe_direct && !svr->probe_dnstcp && !svr->saw_direct_work) { svr->saw_direct_work = 1; /* no need for wait for more done */ stop_unfinished_probes(); probe_cache_done(); return; } else if(svr->probe_dnstcp && !svr->saw_dnstcp_work) { svr->saw_dnstcp_work = 1; /* can already use this port */ if(!svr->forced_insecure) probe_setup_dnstcp(svr); } } if(svr->num_probes_done < svr->num_probes) { /* continue to wait for the rest */ return; } probe_cache_done(); } /** setup to use cache */ void probe_setup_cache(struct svr* svr, struct probe_ip* p) { svr->res_state = res_cache; if(svr->insecure_state) hook_resolv_flush(svr->cfg); svr->insecure_state = 0; /* send the working servers to unbound */ if(p) hook_unbound_cache(svr->cfg, p->name); else hook_unbound_cache_list(svr->cfg, svr->probes); /* set resolv.conf to 127.0.0.1 */ hook_resolv_localhost(svr->cfg); svr_retry_timer_stop(); svr->tcp_timer_used = 0; svr->http_insecure = 0; } /** setup for auth (direct to authorities) */ void probe_setup_auth(struct svr* svr) { svr->res_state = res_auth; if(svr->insecure_state) hook_resolv_flush(svr->cfg); svr->insecure_state = 0; hook_unbound_auth(svr->cfg); /* set resolv.conf to 127.0.0.1 */ hook_resolv_localhost(svr->cfg); svr_retry_timer_stop(); svr->tcp_timer_used = 0; svr->http_insecure = 0; } /** setup for dnstcp (uses tcp to open resolver) */ void probe_setup_dnstcp(struct svr* svr) { int tcp80_ip4, tcp443_ip4, tcp80_ip6, tcp443_ip6, ssl443_ip4, ssl443_ip6; if(svr->insecure_state) hook_resolv_flush(svr->cfg); svr->insecure_state = 0; /* see which ports work */ tcp80_ip4 = probe_has_work_tcp(svr, 80, 0, 0); tcp80_ip6 = probe_has_work_tcp(svr, 80, 1, 0); tcp443_ip4 = probe_has_work_tcp(svr, 443, 0, 0); tcp443_ip6 = probe_has_work_tcp(svr, 443, 1, 0); ssl443_ip4 = probe_has_work_tcp(svr, 443, 0, 1); ssl443_ip6 = probe_has_work_tcp(svr, 443, 1, 1); if(tcp80_ip4 || tcp443_ip4 || tcp80_ip6 || tcp443_ip6) { svr->res_state = res_tcp; hook_unbound_tcp_upstream(svr->cfg, tcp80_ip4, tcp80_ip6, tcp443_ip4, tcp443_ip6); } else { svr->res_state = res_ssl; hook_unbound_ssl_upstream(svr->cfg, ssl443_ip4, ssl443_ip6); } /* set resolv.conf to 127.0.0.1 */ hook_resolv_localhost(svr->cfg); svr_retry_timer_stop(); svr_tcp_timer_enable(); svr->http_insecure = 0; } /** setup to be disconnected */ void probe_setup_disconnected(struct svr* svr) { svr->insecure_state = 0; svr->res_state = res_disconn; /* set unbound to go dark */ hook_unbound_dark(svr->cfg); /* set resolver.conf to 127.0.0.1 (get rid of old * settings that may be in there) */ hook_resolv_localhost(svr->cfg); svr_retry_timer_next(0); svr->tcp_timer_used = 0; svr->http_insecure = 0; } /** setup for dark (no dnssec) */ void probe_setup_dark(struct svr* svr) { /* DNSSEC failure, and there is some unsafe IPs */ if(svr->res_state != res_dark) svr->insecure_state = 0; /* ask again */ svr->res_state = res_dark; /* set unbound to dark */ hook_unbound_dark(svr->cfg); /* see what the user wants */ if(svr->insecure_state) { /* set resolv.conf to DHCP IP list */ hook_resolv_iplist(svr->cfg, svr->probes); } else { /* set resolv.conf to 127.0.0.1 now, * the user may select insecure later */ hook_resolv_localhost(svr->cfg); } svr_retry_timer_next(0); svr->tcp_timer_used = 0; svr->http_insecure = 0; } /** setup forced insecure (for hotspot signon) */ void probe_setup_hotspot_signon(struct svr* svr) { svr->res_state = res_dark; svr->forced_insecure = 1; svr->insecure_state = 1; /* effectuate it */ hook_unbound_dark(svr->cfg); hook_resolv_iplist(svr->cfg, svr->probes); svr_retry_timer_stop(); svr_tcp_timer_stop(); svr->http_insecure = 0; } /** setup http insecure (for hotspot signon) */ void probe_setup_http_insecure(struct svr* svr) { svr->res_state = res_dark; svr->http_insecure = 1; /* effectuate it */ hook_unbound_dark(svr->cfg); /* see what the user wants */ if(svr->insecure_state) { /* set resolv.conf to DHCP IP list */ hook_resolv_iplist(svr->cfg, svr->probes); } else { /* set resolv.conf to 127.0.0.1 now, * the user may select insecure later */ hook_resolv_localhost(svr->cfg); } /* set timer to catch user as things work again */ svr_retry_timer_next(1); svr->tcp_timer_used = 0; } void probe_cache_done(void) { struct svr* svr = global_svr; if(!svr->probe_direct && svr->http && !svr->http->saw_http_work && !svr->skip_http) { /* cache probe completed, but http fails to work, stop probes */ /* do not probe direct authority servers, because HTTP fails*/ /* unless we skip http probe, then go on to probe authority */ probe_all_done(); return; } if(!svr->probe_direct && !svr->saw_first_working) { /* no working server, probe the direct DNS */ /* we wait until the other probes fail to not put * traffic to the authority servers when a cache works */ svr->probe_direct = 1; /* set flag first avoids loop in case spawn fails */ probe_spawn_direct(); return; } if(!svr->probe_dnstcp && !svr->saw_first_working && !svr->saw_direct_work && (cfg_have_dnstcp(svr->cfg) || cfg_have_ssldns(svr->cfg))) { int nump = global_svr->num_probes; int done = 0; if(hook_unbound_supports_tcp_upstream(svr->cfg)) { /* no working cache and authority-direct works. * probe dns-over-tcp on port 80 and 443. * Do not probe earlier to avoid traffic on * those resolvers when not necessary */ svr->probe_dnstcp = 1; probe_spawn_dnstcp(); done = 1; } if(hook_unbound_supports_ssl_upstream(svr->cfg)) { /* probe for SSL wrapped service to avoid deepstuff */ svr->probe_dnstcp = 1; probe_spawn_ssldns(); done = 1; } if(!done) { verbose(VERB_OPS, "unbound does not support " "tcp-upstream and ssl-upstream, but " "these features are needed now. " "Please upgrade unbound"); } else if(global_svr->num_probes == nump) { /* failed to create the probes (outofmemory?) */ } else if(done) { /* do the probes */ return; } } probe_all_done(); } /** true if no packets were received during the probe: network seems down */ static int got_no_packets(struct svr* svr) { struct probe_ip* p; for(p=svr->probes; p; p=p->next) { if(p->got_packet) return 0; } return 1; } void probe_all_done(void) { struct svr* svr = global_svr; if(verbosity >= VERB_DETAIL) { struct probe_ip* p; for(p=svr->probes; p; p=p->next) { if(p->to_http) verbose(VERB_DETAIL, "%s %s: %s %s", p->host_c?"addrlookup":"http", p->name, p->works?"OK":"error", p->reason?p->reason:""); else if(p->dnstcp) verbose(VERB_DETAIL, "%s%d %s: %s %s", p->ssldns?"ssl":"tcp", p->port, p->name, p->works?"OK":"error", p->reason?p->reason:""); else verbose(VERB_DETAIL, "%s %s: %s %s", p->to_auth?"authority":"cache", p->name, p->works?"OK":"error", p->reason?p->reason:""); } } /* reset skip http once it works */ if(svr->skip_http && svr->http && svr->http->saw_http_work) svr->skip_http = 0; if(svr->forced_insecure) { verbose(VERB_OPS, "probe done: but still forced insecure"); /* call it again, in case DHCP changes while hotspot-signon */ probe_setup_hotspot_signon(svr); } else if(svr->probe_dnstcp && svr->saw_dnstcp_work) { /* set unbound to process over tcp */ verbose(VERB_OPS, "probe done: DNSSEC to tcp or ssl resolver"); probe_setup_dnstcp(svr); } else if(svr->probe_direct && svr->saw_direct_work) { /* set unbound to process directly */ verbose(VERB_OPS, "probe done: DNSSEC to auth direct"); probe_setup_auth(svr); } else if(svr->probe_direct && !svr->saw_direct_work && !svr->saw_dnstcp_work) { /* if there are no cache IPs, then there is nothing else * we can do, we are in offline mode, most likely. No DHCP, * no network connectivity */ /* if none of the probes got a packet, then nothing pings, * we have a stored network state without a network connect. * The insecure option cannot ping the cache, so disconnect. */ if(svr->num_probes_to_cache == 0 || got_no_packets(svr)) { verbose(VERB_OPS, "probe done: disconnected"); probe_setup_disconnected(svr); } else { verbose(VERB_OPS, "probe done: DNSSEC fails"); probe_setup_dark(svr); } } else if(svr->http && !svr->http->saw_http_work && !svr->skip_http) { /* http probed (so have DHCPDNS), but fails */ verbose(VERB_OPS, "probe done: http fails"); probe_setup_http_insecure(svr); } else { verbose(VERB_OPS, "probe done: DNSSEC to cache"); probe_setup_cache(svr, NULL); } svr->probetime = time(0); svr_send_results(svr); svr_check_update(svr); } dnssec-trigger-0.13/riggerd/reshook.c0000664000175000017500000002327512455223503017266 0ustar wouterwouter/* * reshook.c - dnssec-trigger resolv.conf hooks for adjusting name resolution * * Copyright (c) 2011, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains the unbound hooks for adjusting the name resolution * on the system (to 127.0.0.1). */ #include "config.h" #include #include "reshook.h" #include "log.h" #include "cfg.h" #include "probe.h" #ifdef USE_WINSOCK #include "winrc/win_svc.h" #endif #ifdef HAVE_CHFLAGS #include #endif static int set_to_localhost = 0; #ifdef HOOKS_OSX /** set the DNS the OSX way */ static void set_dns_osx(struct cfg* cfg, char* iplist) { char cmd[10240]; char dm[1024]; char* domains = "nothing.invalid"; if(cfg->rescf_domain && cfg->rescf_domain[0]) domains = cfg->rescf_domain; else if(cfg->rescf_search && cfg->rescf_search[0]) { snprintf(dm, sizeof(dm), "%s", cfg->rescf_search); domains = dm; } snprintf(cmd, sizeof(cmd), "%s/dnssec-trigger-setdns.sh mset %s -- %s", LIBEXEC_DIR, domains, iplist); verbose(VERB_QUERY, "%s", cmd); system(cmd); } /** restore resolv.conf on OSX if localhost is enabled */ void restore_resolv_osx(struct cfg* cfg) { if(set_to_localhost) hook_resolv_localhost(cfg); } #endif /* HOOKS_OSX */ #ifndef USE_WINSOCK static void prline(FILE* out, const char* line) { int r = fprintf(out, "%s", line); if(r < 0) { log_err("cannot write resolvconf: %s", strerror(errno)); } else if(r != (int)strlen(line)) { log_err("short write resolvconf: filesystem full?"); } } #if defined(HAVE_CHFLAGS) && !defined(HOOKS_OSX) static void r_mutable_bsd(const char* f) { if(chflags(f, 0) < 0) { log_err("chflags(%s, nouchg) failed: %s", f, strerror(errno)); } } static void r_immutable_bsd(const char* f) { /* BSD method for immutable files */ if(chflags(f, UF_IMMUTABLE|UF_NOUNLINK) < 0) { log_err("chflags(%s, uchg) failed: %s", f, strerror(errno)); } } #elif !defined(HAVE_CHFLAGS) && !defined(HOOKS_OSX) static void r_mutable_efs(const char* f) { char buf[10240]; snprintf(buf, sizeof(buf), "chattr -i %s", f); if(system(buf) < 0) log_err("could not %s: %s", buf, strerror(errno)); } static void r_immutable_efs(const char* f) { char buf[10240]; /* this chattr only works on extX file systems */ snprintf(buf, sizeof(buf), "chattr +i %s", f); if(system(buf) < 0) log_err("could not %s: %s", buf, strerror(errno)); } #endif /* mutable/immutable on BSD and Linux */ static FILE* open_rescf(struct cfg* cfg) { FILE* out; char line[1024]; # if defined(HAVE_CHFLAGS) && !defined(HOOKS_OSX) r_mutable_bsd(cfg->resolvconf); # elif !defined(HAVE_CHFLAGS) && !defined(HOOKS_OSX) r_mutable_efs(cfg->resolvconf); # endif if(chmod(cfg->resolvconf, 0644)<0) { log_err("chmod(%s) failed: %s", cfg->resolvconf, strerror(errno)); } /* make resolv.conf writable */ out = fopen(cfg->resolvconf, "w"); if(!out) { log_err("cannot open %s: %s", cfg->resolvconf, strerror(errno)); return NULL; } prline(out, "# Generated by " PACKAGE_STRING "\n"); if(cfg->rescf_domain) { snprintf(line, sizeof(line), "domain %s\n", cfg->rescf_domain); prline(out, line); } if(cfg->rescf_search) { snprintf(line, sizeof(line), "search %s\n", cfg->rescf_search); prline(out, line); } return out; } static void close_rescf(struct cfg* cfg, FILE* out) { fclose(out); /* make resolv.conf readonly */ if(chmod(cfg->resolvconf, 0444)<0) { log_err("chmod(%s) failed: %s", cfg->resolvconf, strerror(errno)); } #if defined(HAVE_CHFLAGS) && !defined(HOOKS_OSX) r_immutable_bsd(cfg->resolvconf); #elif !defined(HAVE_CHFLAGS) && !defined(HOOKS_OSX) r_immutable_efs(cfg->resolvconf); #endif } #endif /* !USE_WINSOCK */ #if !defined(USE_WINSOCK) && !defined(HOOKS_OSX) /** check argument on line matches config option */ static int check_line_arg(char* line, const char* opt) { if(!opt) /* has opt in file but should not */ return 0; if(strncmp(line, opt, strlen(opt)) != 0) /* file has wrong content */ return 0; if(strcmp(line+strlen(opt), "\n") != 0) /* stuff after opt (too many domains) */ return 0; return 1; } /** check if resolv.conf is set to 127.0.0.1 like we want */ static int really_set_to_localhost(struct cfg* cfg) { FILE* in = fopen(cfg->resolvconf, "r"); int saw_127 = 0, saw_search = 0, saw_domain = 0; char line[1024]; if(!in) { verbose(VERB_DETAIL, "fopen %s: %s", cfg->resolvconf, strerror(errno)); return 0; } if(!fgets(line, (int)sizeof(line), in)) { fclose(in); /* failed to read first line */ return 0; } /* we want the first line to be 'Generated by me' */ if(strcmp(line, "# Generated by " PACKAGE_STRING "\n") != 0) { fclose(in); return 0; } /* must contain 127.0.0.1 and nothing else */ while(fgets(line, (int)sizeof(line), in)) { line[sizeof(line)-1] = 0; /* robust end of string */ if(strcmp(line, "nameserver 127.0.0.1\n") == 0) { saw_127 = 1; } else if(strncmp(line, "nameserver", 10) == 0) { /* not 127.0.0.1 but in resolv.conf, bad! */ fclose(in); return 0; } else if(strncmp(line, "search ", 7) == 0) { if(!check_line_arg(line+7, cfg->rescf_search)) { fclose(in); return 0; } saw_search = 1; } else if(strncmp(line, "domain ", 7) == 0) { if(!check_line_arg(line+7, cfg->rescf_domain)) { fclose(in); return 0; } saw_domain = 1; } } fclose(in); if(cfg->rescf_search && !saw_search) return 0; if(cfg->rescf_domain && !saw_domain) return 0; return saw_127; } #endif /* no USE_WINSOCK, no OSX */ void hook_resolv_localhost(struct cfg* cfg) { #ifndef USE_WINSOCK FILE* out; #endif set_to_localhost = 1; if(cfg->noaction) { return; } #ifdef HOOKS_OSX set_dns_osx(cfg, "127.0.0.1"); #endif #ifdef USE_WINSOCK win_set_resolv("127.0.0.1"); #else /* not on windows */ # ifndef HOOKS_OSX /* on Linux/BSD */ if (system("/usr/libexec/dnssec-trigger-script --setup") == 0) return; if(really_set_to_localhost(cfg)) { /* already done, do not do it again, that would open * a brief moment of mutable resolv.conf */ verbose(VERB_ALGO, "resolv.conf localhost already set"); return; } verbose(VERB_ALGO, "resolv.conf localhost write"); # endif out = open_rescf(cfg); if(!out) return; /* write the nameserver records */ prline(out, "nameserver 127.0.0.1\n"); close_rescf(cfg, out); #endif /* not on windows */ } void hook_resolv_iplist(struct cfg* cfg, struct probe_ip* list) { #ifndef USE_WINSOCK char line[1024]; FILE* out; #endif #if defined(HOOKS_OSX) || defined(USE_WINSOCK) char iplist[10240]; iplist[0] = 0; #else if (system("/usr/libexec/dnssec-trigger-script --restore") == 0) return; #endif set_to_localhost = 0; if(cfg->noaction) return; #ifndef USE_WINSOCK out = open_rescf(cfg); if(!out) return; #endif /* write the nameserver records */ while(list) { if(probe_is_cache(list)) { #ifndef USE_WINSOCK snprintf(line, sizeof(line), "nameserver %s\n", list->name); prline(out, line); #endif #if defined(HOOKS_OSX) || defined(USE_WINSOCK) snprintf(iplist+strlen(iplist), sizeof(iplist)-strlen(iplist), "%s%s", ((iplist[0]==0)?"":" "), list->name); #endif } list = list->next; } #ifndef USE_WINSOCK close_rescf(cfg, out); #endif #ifdef HOOKS_OSX set_dns_osx(cfg, iplist); #endif #ifdef USE_WINSOCK win_set_resolv(iplist); #endif } void hook_resolv_flush(struct cfg* cfg) { /* attempt to flush OS specific caches, because we go from * insecure to secure mode */ (void)cfg; #ifdef HOOKS_OSX /* dscacheutil on 10.5 an later, lookupd before that */ system("dscacheutil -flushcache || lookupd -flushcache || discoveryutil udnsflushcaches"); system("discoveryutil mdnsflushcache"); #elif defined(USE_WINSOCK) win_run_cmd("ipconfig /flushdns"); #else /* TODO */ #endif } #ifdef HOOKS_OSX static void osx_uninit(void) { char cmd[10240]; snprintf(cmd, sizeof(cmd), "%s/dnssec-trigger-setdns.sh uninit", LIBEXEC_DIR); verbose(VERB_QUERY, "%s", cmd); system(cmd); } #endif /* HOOKS_OSX */ void hook_resolv_uninstall(struct cfg* cfg) { #ifdef HOOKS_OSX /* on OSX: do the OSX thing */ (void)cfg; osx_uninit(); #elif defined(USE_WINSOCK) /* on Windows: edit registry */ (void)cfg; win_clear_resolv(); #elif defined(HAVE_CHFLAGS) /* on BSD: make file mutable again */ r_mutable_bsd(cfg->resolvconf); #else /* other (unix) systems, make it via ext2fs mutable again */ r_mutable_efs(cfg->resolvconf); #endif } dnssec-trigger-0.13/riggerd/http.c0000664000175000017500000012051112275162157016571 0ustar wouterwouter/* * http.c - dnssec-trigger HTTP client code to GET a simple URL * * Copyright (c) 2012, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains an implementation of HTTP fetch for a simple URL file. */ #include "config.h" #include #include "riggerd/http.h" #include "riggerd/netevent.h" #include "riggerd/log.h" #include "riggerd/svr.h" #include "riggerd/probe.h" #include "riggerd/cfg.h" #include "riggerd/net_help.h" #include "riggerd/update.h" #ifdef USE_WINSOCK #include "winsock_event.h" #endif /** start http get with a random dest address from the set */ void http_probe_start_http_get(struct http_probe* hp); /** parse url into hostname and filename */ static int parse_url(char* url, char** h, char** f) { char* front, *sl; if(strncmp(url, "http://", 7) != 0) { return 0; } front = url+7; sl = strchr(front, '/'); if(!sl) { /* http://www.example.com */ (*h) = strdup(front); (*f) = strdup(""); } else { *sl = 0; (*h) = strdup(front); (*f) = strdup(sl+1); *sl = '/'; } if(!(*h) || !(*f)) { log_err("parse_url: malloc failure"); return 0; } return 1; } /** setup httpprobe for a new url */ static int http_probe_setup_url(struct http_general* hg, struct http_probe* hp, size_t i) { hp->do_addr = 1; hp->url_idx = i; hp->url = strdup(hg->urls[i]); if(!hp->url) { log_err("out of memory"); return 0; } if(!parse_url(hp->url, &hp->hostname, &hp->filename)) { return 0; } verbose(VERB_ALGO, "setup url %s %s", hp->hostname, hp->filename); return 1; } /** create probe for address */ static void probe_create_addr(const char* ip, const char* domain, int rrtype) { struct probe_ip* p; p = (struct probe_ip*)calloc(1, sizeof(*p)); if(!p) { log_err("out of memory"); return; } p->port = DNS_PORT; p->to_http = 1; p->http_ip6 = (rrtype == LDNS_RR_TYPE_AAAA); p->name = strdup(ip); if(!p->name) { free(p); log_err("out of memory"); return; } /* no need for EDNS-probe, DNSSEC-types; we check for magic cookie in * HTTP response data */ p->host_c = outq_create(p->name, rrtype, domain, 1, p, 0, 0, p->port, 0, 0); if(!p->host_c) { free(p->name); free(p); log_err("out of memory"); return; } /* put it in the svr list */ p->next = global_svr->probes; global_svr->probes = p; global_svr->num_probes++; } /** create address lookup queries for http probe */ static void http_probe_make_addr_queries(struct http_general* hg, struct http_probe* hp) { /* lookup hostname at the recursive resolvers */ struct probe_ip* p; hp->num_addr_qs = 0; hp->num_failed_addr_qs = 0; /* created probes are prepended, thus this can continue easily */ for(p = hg->svr->probes; p; p=p->next) { if(!probe_is_cache(p)) continue; probe_create_addr(p->name, hp->hostname, hp->ip6?LDNS_RR_TYPE_AAAA:LDNS_RR_TYPE_A); hp->num_addr_qs++; if(hp->num_addr_qs >= HTTP_MAX_ADDR_QUERIES) break; } } /** see if hp ip6 fits with probe ip6 */ static int right_ip6(struct http_probe* hp, struct probe_ip* p) { return (hp->ip6 && p->http_ip6) || (!hp->ip6 && !p->http_ip6); } /* delete addr lookups from probe list in svr */ void http_probe_remove_addr_lookups(struct http_probe* hp) { struct svr* svr = global_svr; struct probe_ip* p = svr->probes, **pp = &svr->probes; /* find and delete addr lookups */ while(p) { /* need to delete this? */ if(p->to_http && right_ip6(hp, p) && p->host_c) { /* snip off */ (*pp) = p->next; if(p->works) svr->num_probes_done --; svr->num_probes --; probe_delete(p); p = (*pp); continue; } /* go to next item */ pp = &p->next; p = p->next; } } /* delete http lookups from probe list in svr */ void http_probe_remove_http_lookups(struct http_probe* hp) { struct svr* svr = global_svr; struct probe_ip* p = svr->probes, **pp = &svr->probes; verbose(VERB_ALGO, "remove http lookups"); /* find and delete http lookups */ while(p) { /* need to delete this? */ if(p->to_http && right_ip6(hp, p) && p->http) { /* snip off */ (*pp) = p->next; if(p->works) svr->num_probes_done --; svr->num_probes --; probe_delete(p); p = (*pp); continue; } /* go to next item */ pp = &p->next; p = p->next; } } /** parse http-hostname as IP address */ static int parse_http_addr(char* s, struct sockaddr_storage* addr, socklen_t* len, int* port) { if(s[0]=='[') { char temp[128]; char* eb = strchr(s, ']'); /* [addr] or [addr]:port */ if(!eb) return 0; /* no close bracket */ *port = HTTP_PORT; /* extract address part */ *eb = 0; (void)strlcpy(temp, s+1, sizeof(temp)); *eb = ']'; /* we know that eb[0] is ']' */ if(eb[1] == 0) { /* '[addr]' */ return ipstrtoaddr(temp, *port, addr, len); } else if(eb[1] == ':') { /* '[addr]:port' */ *port = atoi(eb+2); return ipstrtoaddr(temp, *port, addr, len); } return 0; } /* attempt parse of plain ip4 or ip6 */ *port = HTTP_PORT; if(ipstrtoaddr(s, HTTP_PORT, addr, len)) return 1; /* attempt addr:port */ if(strchr(s, ':')) { char temp[128]; char* e= strchr(s, ':'); /* extract address part */ *e = 0; (void)strlcpy(temp, s, sizeof(temp)); *e = ':'; *port = atoi(e+1); return ipstrtoaddr(temp, *port, addr, len); } return 0; } /** see if hostname is ip4, or ip6 or [ip6] or [ip6]:port or ip4:port */ static int http_probe_hostname_has_addr(struct http_probe* hp) { struct sockaddr_storage addr; socklen_t len = 0; ldns_rr* rr; ldns_rdf* f; if(!parse_http_addr(hp->hostname, &addr, &len, &hp->port)) return 0; /* setup addr structure and port */ hp->addr = ldns_rr_list_new(); if(!hp->addr) { log_err("out of memory"); return 1; } /* if we are not appriopriate (IP6 addr and we are IP4) we have empty * list as the result */ if(addr_is_ip6(&addr, len)) { if(!hp->ip6) return 1; } else { if(hp->ip6) return 1; } rr = ldns_rr_new_frm_type(addr_is_ip6(&addr, len)? LDNS_RR_TYPE_AAAA:LDNS_RR_TYPE_A); if(!rr) { log_err("out of memory"); return 1; } if(addr_is_ip6(&addr, len)) { f = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_AAAA, INET6_SIZE, &((struct sockaddr_in6*)&addr)->sin6_addr); } else { f = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_A, INET_SIZE, &((struct sockaddr_in*)&addr)->sin_addr); } if(!f) { ldns_rr_free(rr); log_err("out of memory"); return 1; } (void)ldns_rr_a_set_address(rr, f); if(!ldns_rr_list_push_rr(hp->addr, rr)) { ldns_rr_free(rr); log_err("out of memory"); return 1; } return 1; } /** the http_probe is done (fail with reason, or its is NULL) */ static void http_probe_done(struct http_general* hg, struct http_probe* hp, char* reason) { hp->finished = 1; verbose(VERB_OPS, "http probe%s %s done: %s", hp->ip6?"6":"4", hp->url, reason?reason:"success"); if(reason == NULL) { /* success! stop the other probe part */ if(hp->ip6 && hg->v4) { if(hg->v4->do_addr) http_probe_remove_addr_lookups(hg->v4); else http_probe_remove_http_lookups(hg->v4); } else if(!hp->ip6 && hg->v6) { if(hg->v6->do_addr) http_probe_remove_addr_lookups(hg->v6); else http_probe_remove_http_lookups(hg->v6); } hp->works = 1; http_general_done(reason); } else { hp->works = 0; /* if other done too, now its total fail for http */ if(hp->ip6) { if(!hg->v4 || hg->v4->finished) { http_general_done(reason); } } else { if(!hg->v6 || hg->v6->finished) { http_general_done(reason); } } } } /** start resolving the hostname of the next url in the list */ static void http_probe_go_next_url(struct http_general* hg, struct http_probe* hp, char* redirect_url) { free(hp->url); hp->url = NULL; free(hp->hostname); hp->hostname = NULL; free(hp->filename); hp->filename = NULL; ldns_rr_list_deep_free(hp->addr); hp->addr = NULL; hp->num_addr_qs = 0; hp->num_failed_addr_qs = 0; hp->port = HTTP_PORT; if(!redirect_url) { hp->redirects = 0; log_assert(hp->url_idx < hg->url_num); if(!http_probe_setup_url(hg, hp, ++hp->url_idx)) { http_probe_done(hg, hp, "out of memory or parse error"); return; } } else { hp->url = redirect_url; if(!parse_url(hp->url, &hp->hostname, &hp->filename)) { http_probe_done(hg, hp, "out of memory or parse error"); return; } verbose(VERB_ALGO, "restart http probe for %s %s", hp->hostname, hp->filename); } if(http_probe_hostname_has_addr(hp)) { if(!hp->addr || ldns_rr_list_rr_count(hp->addr)==0) { if(hp->ip6) http_probe_done(hg, hp, "no address of type IP6"); else http_probe_done(hg, hp, "no address of type IP4"); return; } hp->got_addrs = 1; hp->do_addr = 0; http_probe_start_http_get(hp); return; } http_probe_make_addr_queries(hg, hp); } /** http probe is done with an address, check next addr */ static void http_probe_done_addr(struct http_general* hg, struct http_probe* hp, char* reason, int connects, char* redirect) { /* if we have a redirect, then we should attempt to follow this, * if allowed to follow more redirects */ if(!reason && redirect) { if(hp->redirects++ > HTTP_MAX_REDIRECT) { /* redirect is strdupped and needs to be free-ed */ free(redirect); redirect = NULL; reason = "too many http redirects"; connects = 1; } } if(!reason && redirect) { /* re-setup the URL */ hp->do_addr = 1; hp->got_addrs = 0; http_probe_go_next_url(hg, hp, redirect); return; } if(redirect) { free(redirect); redirect = NULL; } /* if we connected to some sort of server, then we do not need to * attempt a different server - we are hotspotted or successed */ if(connects) { http_probe_done(hg, hp, reason); return; } if(!reason) { /* should also 'connects', but for robustness */ http_probe_done(hg, hp, reason); return; } /* So: we did not connect and there is an error reason */ log_assert(!connects && reason); /* try the next address */ if(hp->addr && ldns_rr_list_rr_count(hp->addr) != 0) { http_probe_start_http_get(hp); return; } /* no more addresses? try the next url */ if(hp->url_idx+1 < global_svr->http->url_num) { http_probe_go_next_url(hg, hp, NULL); return; } /* fail */ http_probe_done(hg, hp, reason); } static int http_probe_create_get(struct http_probe* hp, ldns_rr* addr, char** reason) { struct probe_ip* p; p = (struct probe_ip*)calloc(1, sizeof(*p)); if(!p) { *reason = "out of memory"; return 0; } p->port = hp->port; p->to_http = 1; p->http_ip6 = hp->ip6; if(!addr || !ldns_rr_rdf(addr, 0)) { *reason = "addr without rdata"; free(p); return 0; } p->name = ldns_rdf2str(ldns_rr_rdf(addr, 0)); if(!p->name) { free(p); *reason = "out of memory"; return 0; } /* create http_get structure */ p->http = http_get_create(hp->url, global_svr->base, p); if(!p->http) { *reason = "out of memory"; free(p->name); free(p); return 0; } /* put a cap on the max data size because we expect very short * responses for our probe */ p->http->data_limit = MAX_HTTP_LENGTH*10; if(!http_get_fetch(p->http, p->name, hp->port, reason)) { http_get_delete(p->http); free(p->name); free(p); return 0; } p->http_desc = strdup(hp->hostname); if(!p->http_desc) { *reason = "malloc failure"; http_get_delete(p->http); free(p->name); free(p); return 0; } /* put it in the svr list */ p->next = global_svr->probes; global_svr->probes = p; global_svr->num_probes++; return 1; } /** pick random address from ldns_rr_list and remove it from the list */ ldns_rr* http_pick_random_addr(ldns_rr_list* list) { size_t count; size_t i; ldns_rr* rr; if(!list) return NULL; count = ldns_rr_list_rr_count(list); if(count == 0) return NULL; i = (count == 1)?0:(ldns_get_random()%count); rr = ldns_rr_list_rr(list, i); /* remove from rr_list */ (void)ldns_rr_list_set_rr(list, ldns_rr_list_rr(list, count-1), i); ldns_rr_list_set_rr_count(list, count-1); return rr; } /** start http get with a random dest address from the set */ void http_probe_start_http_get(struct http_probe* hp) { char* reason = "out of memory"; /* pick random address */ ldns_rr* rr = http_pick_random_addr(hp->addr); /* create probe */ if(!http_probe_create_get(hp, rr, &reason)) { log_err("http_probe_create_get: %s", reason); ldns_rr_free(rr); http_probe_done_addr(global_svr->http, hp, reason, 0, NULL); return; } ldns_rr_free(rr); } /** delete http probe structure */ static void http_probe_delete(struct http_probe* hp) { if(!hp) return; ldns_rr_list_deep_free(hp->addr); free(hp->url); free(hp->hostname); free(hp->filename); free(hp); } /** create and start new http probe for v4 or v6 */ static struct http_probe* http_probe_start(struct http_general* hg, int ip6) { struct http_probe* hp = (struct http_probe*)calloc(1, sizeof(*hp)); if(!hp) return NULL; hp->ip6 = ip6; hp->port = HTTP_PORT; if(!http_probe_setup_url(hg, hp, 0)) { http_probe_delete(hp); return NULL; } if(http_probe_hostname_has_addr(hp)) { if(!hp->addr || ldns_rr_list_rr_count(hp->addr)==0) { if(hp->ip6) http_probe_done(hg, hp, "no address of type IP6"); else http_probe_done(hg, hp, "no address of type IP4"); return hp; } hp->got_addrs = 1; hp->do_addr = 0; http_probe_start_http_get(hp); return hp; } http_probe_make_addr_queries(hg, hp); return hp; } /* see if str in array */ static int already_used(struct http_general* hg, char* s) { size_t i; for(i=0; iurl_num; i++) if(hg->urls[i] == s) return 1; return 0; } /* pick url from list not picking twice */ static char* pick_url(struct http_general* hg, size_t x, char** code) { size_t now = 0; struct strlist2* p; for(p=hg->svr->cfg->http_urls; p; p=p->next) { if(already_used(hg, p->str1)) continue; if(now++ == x) { *code = p->str2; return p->str1; } } return NULL; } /* fill the url array randomly */ static void fill_urls(struct http_general* hg) { size_t i; for(i=0; iurl_num; i++) { /* random number from remaining number of choices */ if((int)hg->url_num == hg->svr->cfg->num_http_urls && i == hg->url_num) hg->urls[i] = pick_url(hg, 0, &hg->codes[i]); else hg->urls[i] = pick_url(hg, ldns_get_random()%(hg->svr->cfg->num_http_urls - i), &hg->codes[i]); } for(i=0; iurl_num; i++) verbose(VERB_ALGO, "hg url[%d]=%s", (int)i, hg->urls[i]); } struct http_general* http_general_start(struct svr* svr) { struct http_general* hg = (struct http_general*)calloc(1, sizeof(*hg)); if(!hg) return NULL; hg->svr = svr; if(svr->cfg->num_http_urls >= HTTP_NUM_URLS_MAX_PROBE) hg->url_num = HTTP_NUM_URLS_MAX_PROBE; else hg->url_num = (size_t)svr->cfg->num_http_urls; hg->urls = (char**)calloc(hg->url_num, sizeof(char*)); hg->codes = (char**)calloc(hg->url_num, sizeof(char*)); if(!hg->urls || !hg->codes) { free(hg->urls); free(hg->codes); free(hg); return NULL; } /* randomly pick that number of urls from the config */ fill_urls(hg); /* start v4 and v6 */ hg->v4 = http_probe_start(hg, 0); if(!hg->v4) { log_err("out of memory"); http_general_delete(hg); return NULL; } hg->v6 = http_probe_start(hg, 1); if(!hg->v6) { log_err("out of memory"); http_general_delete(hg); return NULL; } return hg; } void http_general_delete(struct http_general* hg) { if(!hg) return; free(hg->urls); free(hg->codes); http_probe_delete(hg->v4); http_probe_delete(hg->v6); free(hg); } void http_general_done(const char* reason) { struct svr* svr = global_svr; verbose(VERB_OPS, "http_general done %s", reason?reason:"success"); if(!reason) { svr->http->saw_http_work = 1; } if(svr->num_probes_done < svr->num_probes) { /* if we are probing the cache, and now http works, * and some cache was already seen to work. * (and we are not probing TCP, SSL, Authority), * (and we are not in forced_insecure mode). * Then we can already use the working cache server now. */ if(!reason && !svr->probe_dnstcp && !svr->probe_direct && svr->saw_first_working && !svr->forced_insecure) { probe_setup_cache(svr, NULL); } return; /* wait for other probes at the cache stage */ } probe_cache_done(); } void http_host_outq_done(struct probe_ip* p, const char* reason) { struct http_probe* hp; if(!reason) { verbose(VERB_OPS, "addr lookup %s at %s successful", p->host_c->qname, p->name); p->works = 1; } else { verbose(VERB_OPS, "addr lookup %s at %s failed: %s", p->host_c->qname, p->name, reason); p->reason = strdup(reason); p->works = 0; } p->finished = 1; global_svr->num_probes_done++; if(p->http_ip6) hp = global_svr->http->v6; else hp = global_svr->http->v4; if(reason) { hp->num_failed_addr_qs++; /* see if other address lookups have also failed */ if(hp->num_failed_addr_qs >= hp->num_addr_qs) { /* if so, go to next url */ /* attempt to go to the next url or fail if no next url */ if(hp->url_idx+1 < global_svr->http->url_num) { http_probe_remove_addr_lookups(hp); http_probe_go_next_url(global_svr->http, hp, NULL); } else { http_probe_done(global_svr->http, hp, "cannot resolve domain name"); } } } else { hp->got_addrs = 1; hp->do_addr = 0; /* it worked, remove other address lookups for this hostname */ http_probe_remove_addr_lookups(hp); /* if it worked, then start http part of the probe sequence */ http_probe_start_http_get(hp); } } void http_host_outq_result(struct probe_ip* p, ldns_pkt* pkt) { /* not picked by name because of CNAMEs */ ldns_rr_list* addr = ldns_pkt_rr_list_by_type(pkt, p->http_ip6? LDNS_RR_TYPE_AAAA:LDNS_RR_TYPE_A, LDNS_SECTION_ANSWER); ldns_pkt_free(pkt); /* see if RR data, is empty, outq_done with error */ if(!addr || ldns_rr_list_rr_count(addr) == 0) { ldns_rr_list_deep_free(addr); http_host_outq_done(p, "nodata answer"); return; } /* store the address results */ if(p->http_ip6) global_svr->http->v6->addr = addr; else global_svr->http->v4->addr = addr; http_host_outq_done(p, NULL); } /** check if the data is correct, ignore whitespace */ static int hg_check_data(ldns_buffer* data, char* result) { char* s = (char*)ldns_buffer_begin(data); while(isspace(*s)) s++; if(strncmp(s, result, strlen(result)) != 0) return 0; s += 2; while(isspace(*s)) s++; if(*s != 0) return 0; return 1; } /** http get is done (failure or success) */ static void http_get_done(struct http_get* hg, char* reason, int connects, char* redirect) { struct probe_ip* p; struct http_probe* hp; char* redirect_dup = NULL; if(!hg->probe) { /* update http_get */ if(redirect && !reason) reason = "error redirect for selfupdate"; selfupdate_http_get_done(global_svr->update, hg, reason); return; } p = hg->probe; hp = (p->http_ip6)?global_svr->http->v6:global_svr->http->v4; p->finished = 1; global_svr->num_probes_done++; /* printout data we got (but pages can be big) if(!reason) verbose(VERB_ALGO, "got %d data: '%s'", (int)ldns_buffer_position(hg->data), ldns_buffer_begin(hg->data)); */ if(!reason || connects) hp->connects = 1; if(!reason && !redirect) { /* check the data */ if(!hg_check_data(hg->data, global_svr->http->codes[hp->url_idx])) reason = "wrong page content"; else verbose(VERB_ALGO, "correct page content from %s", p->name); } if(redirect) { redirect_dup = strdup(redirect); if(!redirect_dup) reason = "out of memory"; } verbose(VERB_OPS, "http_get_done: %s from %s: %s (%s%s%s)", hg->url, hg->dest, reason?reason:"success", !reason||connects?"connects":"noconnects", redirect?" redirected to ":"", redirect?redirect:""); if(!reason && !redirect) { p->works = 1; } else if(redirect_dup) { /* do not set p->works otherwise, dupped already */ char buf[1024]; snprintf(buf, sizeof(buf), "http redirect to %s", redirect); p->reason = strdup(buf); if(!p->reason) log_err("malloc failure"); } else { p->works = 0; p->reason = strdup(reason); if(!p->reason) log_err("malloc failure"); } http_get_delete(hg); p->http = NULL; http_probe_done_addr(global_svr->http, hp, reason, hp->connects, redirect_dup); } /** handle timeout for the http_get operation */ void http_get_timeout_handler(void* arg) { struct http_get* hg = (struct http_get*)arg; verbose(VERB_ALGO, "http_get timeout"); http_get_done(hg, "timeout", 0, NULL); } struct http_get* http_get_create(const char* url, struct comm_base* base, struct probe_ip* probe) { struct http_get* hg = (struct http_get*)calloc(1, sizeof(*hg)); if(!hg) { log_err("http_get_create: out of memory"); return NULL; } hg->probe = probe; hg->state = http_state_none; hg->url = strdup(url); if(!hg->url) { log_err("http_get_create: out of memory"); free(hg); return NULL; } hg->buf = ldns_buffer_new(MAX_HTTP_LENGTH); if(!hg->buf) { log_err("http_get_create: out of memory"); http_get_delete(hg); return NULL; } hg->data = ldns_buffer_new(MAX_HTTP_LENGTH); if(!hg->data) { log_err("http_get_create: out of memory"); http_get_delete(hg); return NULL; } hg->timer = comm_timer_create(base, http_get_timeout_handler, hg); if(!hg->timer) { log_err("http_get_create: out of memory"); http_get_delete(hg); return NULL; } hg->base = base; return hg; } /** Put HTTP GET 1.1 into the buffer, ready to send to host */ static int prep_get_cmd(struct http_get* hg) { ldns_buffer_clear(hg->buf); if(ldns_buffer_printf(hg->buf, "GET /%s HTTP/1.1\r\n", hg->filename) == -1) return 0; if(ldns_buffer_printf(hg->buf, "Host: %s\r\n", hg->hostname) == -1) return 0; if(ldns_buffer_printf(hg->buf, "User-Agent: dnssec-trigger/%s\r\n", PACKAGE_VERSION) == -1) return 0; /* not really needed: Connection: close */ if(ldns_buffer_printf(hg->buf, "\r\n") == -1) return 0; ldns_buffer_flip(hg->buf); /* verbose(VERB_ALGO, "created http get text: %s", ldns_buffer_begin(hg->buf)); */ return 1; } /** connect to destination IP (nonblocking), return fd (or -1). */ static int http_get_connect(struct sockaddr_storage* addr, socklen_t addrlen, char** err) { int fd; #ifdef INET6 if(addr_is_ip6(addr, addrlen)) fd = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP); else #endif fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if(fd == -1) { #ifndef USE_WINSOCK *err = strerror(errno); if(!((errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) && verbosity <= 2)) log_err("http_get: socket: %s", strerror(errno)); #else *err = wsa_strerror(WSAGetLastError()); if(!((WSAGetLastError() == WSAEAFNOSUPPORT || WSAGetLastError() == WSAEPROTONOSUPPORT) && verbosity <= 2)) log_err("http_get: socket: %s", wsa_strerror(WSAGetLastError())); #endif return -1; } fd_set_nonblock(fd); if(connect(fd, (struct sockaddr*)addr, addrlen) == -1) { #ifndef USE_WINSOCK #ifdef EINPROGRESS if(errno != EINPROGRESS) { #else if(1) { #endif *err = strerror(errno); if(verbosity >= 2) log_err("http_get: connect: %s", *err); close(fd); #else /* USE_WINSOCK */ if(WSAGetLastError() != WSAEINPROGRESS && WSAGetLastError() != WSAEWOULDBLOCK) { *err = wsa_strerror(WSAGetLastError()); if(verbosity >= 2) log_err("http_get: connect: %s", *err); closesocket(fd); #endif return -1; } } return fd; } /** write buffer to socket, returns true if done, false if notdone or error */ static int hg_write_buf(struct http_get* hg, ldns_buffer* buf) { ssize_t r; char* str = NULL; int fd = hg->cp->fd; if(hg->cp->tcp_check_nb_connect) { /* check for pending error from nonblocking connect */ /* from Stevens, unix network programming, vol1, 3rd ed, p450*/ int error = 0; socklen_t len = (socklen_t)sizeof(error); if(getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&error,\ &len) < 0) { #ifndef USE_WINSOCK error = errno; /* on solaris errno is error */ #else /* USE_WINSOCK */ error = WSAGetLastError(); #endif } #ifndef USE_WINSOCK #if defined(EINPROGRESS) && defined(EWOULDBLOCK) if(error == EINPROGRESS || error == EWOULDBLOCK) return 0; /* try again later */ else #endif if(error != 0) { str = strerror(error); #else /* USE_WINSOCK */ if(error == WSAEINPROGRESS) return 0; else if(error == WSAEWOULDBLOCK) { winsock_tcp_wouldblock(comm_point_internal(hg->cp), EV_WRITE); return 0; } else if(error != 0) { str = wsa_strerror(error); #endif /* USE_WINSOCK */ log_err("http connect: %s", str); http_get_done(hg, str, 0, NULL); return 0; } /* no connect error */ hg->cp->tcp_check_nb_connect = 0; if(!hg->probe) { selfupdate_http_connected(global_svr->update, hg); } } /* write data */ r = send(fd, (void*)ldns_buffer_current(buf), ldns_buffer_remaining(buf), 0); if(r == -1) { #ifndef USE_WINSOCK if(errno == EINTR || errno == EAGAIN) return 0; str = strerror(errno); #else if(WSAGetLastError() == WSAEINPROGRESS) return 0; if(WSAGetLastError() == WSAEWOULDBLOCK) { winsock_tcp_wouldblock(comm_point_internal(hg->cp), EV_WRITE); return 0; } str = wsa_strerror(WSAGetLastError()); #endif log_err("http write: %s", str); http_get_done(hg, str, 0, NULL); return 0; } ldns_buffer_skip(buf, r); return (ldns_buffer_remaining(buf) == 0); } /** read buffer from socket, returns false on failures (or simply not done). * returns true if something extra was read in. caller checks if done. * zero terminates after a read (right after buf position) */ static int hg_read_buf(struct http_get* hg, ldns_buffer* buf) { ssize_t r; int fd = hg->cp->fd; /* save up one space at end for a trailing zero byte */ r = recv(fd, (void*)ldns_buffer_current(buf), ldns_buffer_remaining(buf)-1, 0); /* zero terminate for sure */ ldns_buffer_write_u8_at(buf, ldns_buffer_limit(buf)-1, 0); /* check for errors */ if(r == -1) { char* str = NULL; #ifndef USE_WINSOCK if(errno == EINTR || errno == EAGAIN) return 0; str = strerror(errno); #else if(WSAGetLastError() == WSAEINPROGRESS) return 0; if(WSAGetLastError() == WSAEWOULDBLOCK) { winsock_tcp_wouldblock(comm_point_internal(hg->cp), EV_READ); return 0; } /* WSAECONNRESET could happen */ str = wsa_strerror(WSAGetLastError()); #endif log_err("http read: %s", str); http_get_done(hg, str, 0, NULL); return 0; } if(r == 0) { log_err("http read: stream closed"); http_get_done(hg, "stream closed", 0, NULL); return 0; } ldns_buffer_skip(buf, r); return 1; } /** parse lines from the buffer, from begin to len, modify to remove line-end * and call parse func. Returns false on parse failure. */ static int hg_parse_lines(struct http_get* hg, ldns_buffer* src, size_t len, int (*func)(struct http_get*, char*, void*), void* arg) { size_t pos = 0; log_assert(len <= ldns_buffer_position(src)); /* the check for pos in limit is for robustness */ while(pos < len && pos <= ldns_buffer_limit(src)) { /* see if there is a (whole) line here) */ /* safe because the source buffer is zero terminated for sure*/ char* eol = strstr((char*)ldns_buffer_at(src, pos), "\r\n"); if(!eol) { http_get_done(hg, "header line without eol", 1, NULL); return 0; } if(pos >= ldns_buffer_limit(src)) { /* impossible, but check for robustness */ http_get_done(hg, "header line too long", 1, NULL); return 0; } if(eol > (char*)ldns_buffer_at(src, len)) { break; } /* eol == len is allowed, for \r\n at end of headers */ /* zero terminate the line (removes the eol from string) */ *eol = 0; /* callback function */ if(!(*func)(hg, (char*)ldns_buffer_at(src, pos), arg)) return 0; /* next line */ pos += (eol - (char*)ldns_buffer_at(src, pos)); pos += 2; /* skip -r-n (now 00-n) */ } return 1; } /** move trailing end of buffer to the front */ static void hg_buf_move(ldns_buffer* buf, size_t headlen) { if(ldns_buffer_position(buf) > headlen) { size_t traillen = ldns_buffer_position(buf)-headlen; memmove(ldns_buffer_begin(buf), ldns_buffer_at(buf, headlen), traillen); ldns_buffer_set_position(buf, traillen); } else { ldns_buffer_clear(buf); } /* zero terminate buffer */ ldns_buffer_current(buf)[0] = 0; } /** handle write of http request */ static int hg_handle_request(struct http_get* hg) { /* write request */ if(!hg_write_buf(hg, hg->buf)) return 0; /* done, start reading reply headers */ ldns_buffer_clear(hg->buf); comm_point_listen_for_rw(hg->cp, 1, 0); hg->state = http_state_reply_header; return 1; } /** parse reply header line */ static int reply_header_parse(struct http_get* hg, char* line, void* arg) { size_t* datalen = (size_t*)arg; verbose(VERB_ALGO, "http reply header: %s", line); if(strncasecmp(line, "HTTP/1.1 ", 9) == 0) { /* check returncode; we understand the following from * rcodes: * 2xx : success, look at content (perhaps changed by hotspot) * 3xx : redirect of some form - probably the hotspot. * other: failure */ if(strncmp(line+9, "302", 3)==0 || strncmp(line+9, "301", 3)==0 || strncmp(line+9, "303", 3)==0 || strncmp(line+9, "305", 3)==0 || strncmp(line+9, "307", 3)==0) { /* redirect 302 (temporary), 303 (see other), * 307(Temporariy Redirect). */ /* 305(proxy) we treat the same */ /* 301 moved permanently should not really be used * by a hot spot .. */ hg->redirect_now = 1; } else if(line[9] == '3') { /* other redirect type codes, this means it fails * completely*/ char err[512]; snprintf(err, sizeof(err), "http redirect %s", line+9); /* we connected to the server, this looks like a * hotspot that redirects */ http_get_done(hg, err, 1, NULL); return 0; } else if(line[9] != '2') { char err[512]; snprintf(err, sizeof(err), "http error %s", line+9); /* we 'connected' but it seems the page is not * there anymore. Try another url and pretend we * could not connect to get it to try another url. */ /* because we pass noconnect, it will also try other * ip addresses for the server. perhaps another server * does not give 404? */ http_get_done(hg, err, 0, NULL); return 0; } } else if(strncasecmp(line, "Content-Length: ", 16) == 0) { *datalen = (size_t)atoi(line+16); } else if(strncasecmp(line, "Transfer-Encoding: chunked", 19+7) == 0) { *datalen = 0; } else if(strncasecmp(line, "Location: ", 10) == 0 && hg->redirect_now) { /* skip whitespace before url */ char* url = line+10; while(isspace(*url)) url++; hg->redirect_now = 0; http_get_done(hg, NULL, 1, line+10); return 0; } return 1; } /** handle read of reply headers (the topmost headers) */ static int hg_handle_reply_header(struct http_get* hg) { size_t headlen = 0; size_t datalen = 0; char* endstr; if(!hg_read_buf(hg, hg->buf)) return 0; /* check if done */ endstr = strstr((char*)ldns_buffer_begin(hg->buf), "\r\n\r\n"); if(!endstr) { /* at end (with zero marker) */ if(ldns_buffer_remaining(hg->buf)-1 == 0) { http_get_done(hg, "http headers too large", 1, NULL); return 0; } return 0; } headlen = (size_t)(endstr-(char*)ldns_buffer_begin(hg->buf)); verbose(VERB_ALGO, "http done, parse reply header"); /* done reading, parse it */ log_assert(strncmp(ldns_buffer_at(hg->buf, headlen), "\r\n\r\n", 4)==0); /* there is a header part, and a start of a trailing part. */ /* extract lines, parse with the given function */ if(!hg_parse_lines(hg, hg->buf, headlen, reply_header_parse, &datalen)) return 0; /* figured out what form the reply takes (one data and its length, * or chunked, or error */ /* move trailing part to front of data buffer (skip /r/n/r/n) */ hg_buf_move(hg->buf, headlen+4); /* if one data seg: see if data can fit into the buffer, or fail */ if(datalen != 0) { if(hg->data_limit && datalen > hg->data_limit) { http_get_done(hg, "http reply data too large", 1, NULL); return 0; } if(!ldns_buffer_reserve(hg->buf, datalen - ldns_buffer_position(hg->buf)+1)) { http_get_done(hg, "out of memory", 1, NULL); return 0; } hg->state = http_state_reply_data; hg->datalen = datalen; verbose(VERB_ALGO, "http 1.0 data len %d", (int)datalen); } else { hg->state = http_state_chunk_header; } return 1; } /** add data to output buffer */ static int hg_add_data(struct http_get* hg, ldns_buffer* add, size_t len) { if(hg->data_limit && ldns_buffer_position(hg->data) + len > hg->data_limit) { http_get_done(hg, "http data too large", 1, NULL); return 0; } if(!ldns_buffer_reserve(hg->data, len+1)) { http_get_done(hg, "out of memory", 1, NULL); return 0; } ldns_buffer_write(hg->data, ldns_buffer_begin(add), len); /* zero terminate */ ldns_buffer_write_u8_at(hg->data, ldns_buffer_position(hg->data), 0); return 1; } /** handle read of reply data (as one block of data) */ static int hg_handle_reply_data(struct http_get* hg) { /* this state could start with initial data that is complete * already, otherwise, read more */ if(ldns_buffer_position(hg->buf) < hg->datalen) { if(!hg_read_buf(hg, hg->buf)) return 0; if(ldns_buffer_position(hg->buf) < hg->datalen) return 0; } log_assert(ldns_buffer_position(hg->buf) >= hg->datalen); if(!hg_add_data(hg, hg->buf, hg->datalen)) return 0; /* done with success with data */ verbose(VERB_ALGO, "http read completed"); http_get_done(hg, NULL, 1, NULL); return 0; } /** parse reply header line */ static int chunk_header_parse(struct http_get* hg, char* line, void* arg) { size_t* chunklen = (size_t*)arg; char* e = NULL; size_t v; verbose(VERB_ALGO, "http chunk header: '%s'", line); v = (size_t)strtol(line, &e, 16); if(e == line) { http_get_done(hg, "could not parse chunk header", 1, NULL); return 0; } *chunklen = v; return 1; } /** handle read of chunked reply headers (the size of the chunk) */ static int hg_handle_chunk_header(struct http_get* hg) { /* this state could start with initial data that is complete * already, otherwise, read more */ size_t headlen = 0; size_t chunklen = 0; char* endstr; if(!strstr((char*)ldns_buffer_begin(hg->buf), "\r\n")) { if(!hg_read_buf(hg, hg->buf)) return 0; } endstr = strstr((char*)ldns_buffer_begin(hg->buf), "\r\n"); if(!endstr) { /* at end (with zero marker) */ if(ldns_buffer_remaining(hg->buf)-1 == 0) { http_get_done(hg, "http chunk headers too large", 1, NULL); return 0; } return 0; } headlen = (size_t)(endstr-(char*)ldns_buffer_begin(hg->buf)); /* done reading, parse it */ log_assert(strncmp(ldns_buffer_at(hg->buf, headlen), "\r\n", 2)==0); /* extract lines, parse with the given function */ if(!hg_parse_lines(hg, hg->buf, headlen, chunk_header_parse, &chunklen)) return 0; if(chunklen == 0) { /* chunked read completed */ /* TODO there can be chunked trailer headers here .. */ verbose(VERB_ALGO, "http chunked read completed"); http_get_done(hg, NULL, 1, NULL); return 0; } /* move trailing part to front of data buffer (skip /r/n) */ hg_buf_move(hg->buf, headlen+2); /* see if data can possibly fit */ if(hg->data_limit && chunklen > hg->data_limit) { http_get_done(hg, "http reply chunk data too large", 1, NULL); return 0; } if(!ldns_buffer_reserve(hg->buf, chunklen - ldns_buffer_position(hg->buf)+1)) { http_get_done(hg, "out of memory", 1, NULL); return 0; } hg->state = http_state_chunk_data; verbose(VERB_ALGO, "http chunk len %d", (int)chunklen); hg->datalen = chunklen; return 1; } /** handle read of chunked reply data (of one chunk) */ static int hg_handle_chunk_data(struct http_get* hg) { /* this state could start with initial data that is complete * already, otherwise, read more */ /* read datalen+2 - body + /r/n */ if(ldns_buffer_position(hg->buf) < hg->datalen+2) { if(!hg_read_buf(hg, hg->buf)) return 0; if(ldns_buffer_position(hg->buf) < hg->datalen+2) return 0; } /* done reading put it together */ log_assert(ldns_buffer_position(hg->buf) >= hg->datalen); verbose(VERB_ALGO, "datalen %d", (int)hg->datalen); verbose(VERB_ALGO, "position %d", (int)ldns_buffer_position(hg->buf)); if(strncmp((char*)ldns_buffer_at(hg->buf, hg->datalen), "\r\n", 2)!=0) { http_get_done(hg, "chunk data not terminated with eol", 1, NULL); return 0; } /* remove trailing newline */ ldns_buffer_write_u8_at(hg->buf, hg->datalen, 0); if(!hg_add_data(hg, hg->buf, hg->datalen)) return 0; /* move up data (plus emptyline) */ hg_buf_move(hg->buf, hg->datalen+2); hg->state = http_state_chunk_header; return 1; } /** handle http get state (return true to continue processing) */ static int hg_handle_state(struct http_get* hg) { verbose(VERB_ALGO, "hg_handle_state %d", (int)hg->state); switch(hg->state) { case http_state_none: /* not possible */ http_get_done(hg, "got event while not connected", 0, NULL); return 0; case http_state_request: return hg_handle_request(hg); case http_state_reply_header: return hg_handle_reply_header(hg); case http_state_reply_data: return hg_handle_reply_data(hg); case http_state_chunk_header: return hg_handle_chunk_header(hg); case http_state_chunk_data: return hg_handle_chunk_data(hg); default: break; } http_get_done(hg, "unknown state", 0, NULL); return 0; } /** handle events (read or write) on the http file descriptor */ int http_get_callback(struct comm_point* ATTR_UNUSED(cp), void* arg, int err, struct comm_reply* ATTR_UNUSED(reply)) { struct http_get* hg = (struct http_get*)arg; if(err != NETEVENT_NOERROR) { /* timeout handled with timer, other errors not possible */ log_err("internal error: http_get_callback got %d", err); return 0; } /* is this read or write, and if so, what part of the protocol */ verbose(VERB_ALGO, "http_get: got event for %s from %s", hg->url, hg->dest); while(hg_handle_state(hg)) { ; } /* the return value is not used by comm_point_raw */ return 0; } int http_get_fetch(struct http_get* hg, const char* dest, int port, char** err) { int fd; struct timeval tv; struct sockaddr_storage addr; socklen_t addrlen = 0; /* parse the URL */ verbose(VERB_ALGO, "http_get fetch %s from %s", hg->url, dest); if(!parse_url(hg->url, &hg->hostname, &hg->filename)) { *err = "cannot parse url"; return 0; } verbose(VERB_ALGO, "parsed into %s and %s", hg->hostname, hg->filename); /* parse dest IP address */ if(!(hg->dest = strdup(dest))) { *err = "out of memory"; return 0; } hg->port = port; if(!ipstrtoaddr(dest, port, &addr, &addrlen)) { log_err("error in syntax of IP address %s", dest); *err = "cannot parse IP address"; return 0; } /* start TCP connection to destination, prepare send headers */ if(!prep_get_cmd(hg)) { *err = "out of memory"; return 0; } /* clear and zero terminate data buffer */ ldns_buffer_clear(hg->data); ldns_buffer_write_u8_at(hg->data, ldns_buffer_position(hg->data), 0); /* set timeout */ tv.tv_sec = HTTP_TIMEOUT/1000; tv.tv_usec = HTTP_TIMEOUT%1000; comm_timer_set(hg->timer, &tv); /* create fd and connect nonblockingly */ if( (fd=http_get_connect(&addr, addrlen, err)) == -1) { return 0; } /* commpoint, raw, get nb_connect check on write */ /* we created the fd before to pass it here, so that the event_add * on windows sees the full (TCP, SOCK_STREAM) file descriptor and * activates the necessary workarounds for TCP sticky events */ hg->cp = comm_point_create_raw(hg->base, fd, 1, http_get_callback, hg); if(!hg->cp) { *err = "out of memory"; return 0; } hg->cp->do_not_close = 0; hg->cp->tcp_check_nb_connect = 1; hg->state = http_state_request; *err = NULL; return 1; } void http_get_delete(struct http_get* hg) { if(!hg) return; free(hg->url); free(hg->hostname); free(hg->filename); free(hg->dest); ldns_buffer_free(hg->buf); ldns_buffer_free(hg->data); comm_point_delete(hg->cp); comm_timer_delete(hg->timer); free(hg); } dnssec-trigger-0.13/riggerd/ubhook.c0000664000175000017500000002011612617132371017074 0ustar wouterwouter/* * ubhook.c - dnssec-trigger unbound control hooks for adjusting that server * * Copyright (c) 2011, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains the unbound hooks for adjusting the unbound validating * DNSSEC resolver. */ #include "config.h" #include "ubhook.h" #include "cfg.h" #include "log.h" #include "probe.h" #ifdef USE_WINSOCK #include "winrc/win_svc.h" #endif /* the state configured for unbound */ static int ub_has_tcp_upstream = 0; static int ub_has_ssl_upstream = 0; /** * Perform the unbound control command. * @param cfg: the config options with the command pathname. * @param cmd: the command. * @param args: arguments. */ static void ub_ctrl(struct cfg* cfg, const char* cmd, const char* args) { char command[12000]; const char* ctrl = "unbound-control"; #ifdef USE_WINSOCK char* regctrl = NULL; #endif int r; if(cfg->noaction) return; #ifdef USE_WINSOCK if( (regctrl = get_registry_unbound_control()) != NULL) { ctrl = regctrl; } else #endif if(cfg->unbound_control) ctrl = cfg->unbound_control; verbose(VERB_ALGO, "system %s %s %s", ctrl, cmd, args); snprintf(command, sizeof(command), "%s %s %s", ctrl, cmd, args); #ifdef USE_WINSOCK r = win_run_cmd(command); free(regctrl); #else r = system(command); if(r == -1) { log_err("system(%s) failed: %s", ctrl, strerror(errno)); } else #endif if(r != 0) { log_warn("unbound-control exited with status %d, cmd: %s", r, command); } } static void disable_tcp_upstream(struct cfg* cfg) { if(ub_has_tcp_upstream) { ub_ctrl(cfg, "set_option", "tcp-upstream: no"); ub_has_tcp_upstream = 0; } } static void disable_ssl_upstream(struct cfg* cfg) { if(ub_has_ssl_upstream) { ub_ctrl(cfg, "set_option", "ssl-upstream: no"); ub_has_ssl_upstream = 0; } } void hook_unbound_auth(struct cfg* cfg) { verbose(VERB_QUERY, "unbound hook to auth"); if(cfg->noaction) return; disable_tcp_upstream(cfg); disable_ssl_upstream(cfg); ub_ctrl(cfg, "forward", "off"); } void hook_unbound_cache(struct cfg* cfg, const char* ip) { verbose(VERB_QUERY, "unbound hook to cache"); if(cfg->noaction) return; disable_tcp_upstream(cfg); disable_ssl_upstream(cfg); ub_ctrl(cfg, "forward", ip); } void hook_unbound_cache_list(struct cfg* cfg, struct probe_ip* list) { /* create list of working ips */ char buf[10240]; char* now = buf; size_t left = sizeof(buf); verbose(VERB_QUERY, "unbound hook to cache list"); if(cfg->noaction) return; buf[0]=0; /* safe, robust */ while(list) { if(probe_is_cache(list) && list->works && list->finished) { size_t len; if(left < strlen(list->name)+3) break; /* no space for more */ snprintf(now, left, "%s%s", (now==buf)?"":" ", list->name); len = strlen(now); left -= len; now += len; } list = list->next; } disable_tcp_upstream(cfg); disable_ssl_upstream(cfg); ub_ctrl(cfg, "forward", buf); } void hook_unbound_dark(struct cfg* cfg) { verbose(VERB_QUERY, "unbound hook to dark"); if(cfg->noaction) return; disable_tcp_upstream(cfg); disable_ssl_upstream(cfg); ub_ctrl(cfg, "forward", UNBOUND_DARK_IP); } static int hook_unbound_supports_option(struct cfg* cfg, const char* args) { char command[12000]; const char* ctrl = "unbound-control"; const char* cmd = "get_option"; int r; if(cfg->unbound_control) ctrl = cfg->unbound_control; verbose(VERB_ALGO, "system %s %s %s", ctrl, cmd, args); snprintf(command, sizeof(command), "%s %s %s", ctrl, cmd, args); #ifdef USE_WINSOCK r = win_run_cmd(command); #else r = system(command); if(r == -1) { log_err("system(%s) failed: %s", ctrl, strerror(errno)); } else #endif if(r != 0) { verbose(VERB_OPS, "unbound does not support option: %s", args); return 0; } verbose(VERB_OPS, "unbound supports option: %s", args); return 1; } int hook_unbound_supports_tcp_upstream(struct cfg* cfg) { return hook_unbound_supports_option(cfg, "tcp-upstream"); } int hook_unbound_supports_ssl_upstream(struct cfg* cfg) { return hook_unbound_supports_option(cfg, "ssl-upstream"); } static void append_str_port(char* buf, char** now, size_t* left, char* str, int port) { size_t len; if(*left < strlen(str)+3) return; /* no more space */ snprintf(*now, *left, "%s%s@%d", *now == buf?"":" ", str, port); len = strlen(*now); (*left) -= len; (*now) += len; } void hook_unbound_tcp_upstream(struct cfg* cfg, int tcp80_ip4, int tcp80_ip6, int tcp443_ip4, int tcp443_ip6) { char buf[102400]; char* now = buf; size_t left = sizeof(buf); struct strlist *p; verbose(VERB_QUERY, "unbound hook to tcp %s %s %s %s", tcp80_ip4?"tcp80_ip4":"", tcp80_ip6?"tcp80_ip6":"", tcp443_ip4?"tcp443_ip4":"", tcp443_ip6?"tcp443_ip6":""); if(cfg->noaction) return; buf[0] = 0; if(tcp80_ip4) { for(p=cfg->tcp80_ip4; p; p=p->next) append_str_port(buf, &now, &left, p->str, 80); } if(tcp80_ip6) { for(p=cfg->tcp80_ip6; p; p=p->next) append_str_port(buf, &now, &left, p->str, 80); } if(tcp443_ip4) { for(p=cfg->tcp443_ip4; p; p=p->next) append_str_port(buf, &now, &left, p->str, 443); } if(tcp443_ip6) { for(p=cfg->tcp443_ip6; p; p=p->next) append_str_port(buf, &now, &left, p->str, 443); } /* effectuate tcp upstream and new list of servers */ disable_ssl_upstream(cfg); ub_ctrl(cfg, "set_option", "tcp-upstream: yes"); ub_ctrl(cfg, "forward", buf); if(!ub_has_tcp_upstream) { ub_ctrl(cfg, "flush_requestlist", ""); ub_ctrl(cfg, "flush_infra", "all"); } ub_has_tcp_upstream = 1; } void hook_unbound_ssl_upstream(struct cfg* cfg, int ssl443_ip4, int ssl443_ip6) { char buf[102400]; char* now = buf; size_t left = sizeof(buf); struct ssllist *p; verbose(VERB_QUERY, "unbound hook to ssl %s %s", ssl443_ip4?"ssl443_ip4":"", ssl443_ip6?"ssl443_ip6":""); if(cfg->noaction) return; buf[0] = 0; if(ssl443_ip4) { for(p=cfg->ssl443_ip4; p; p=p->next) append_str_port(buf, &now, &left, p->str, 443); } if(ssl443_ip6) { for(p=cfg->ssl443_ip6; p; p=p->next) append_str_port(buf, &now, &left, p->str, 443); } /* effectuate ssl upstream and new list of servers */ /* set SSL first, so no contact of this server over normal DNS, * because the fake answer may cause it to be blacklisted then */ disable_tcp_upstream(cfg); ub_ctrl(cfg, "set_option", "ssl-upstream: yes"); ub_ctrl(cfg, "forward", buf); /* flush requestlist to remove queries over normal transport that * may be waiting very long. And remove bad timeouts from infra * cache. Removes edns and so on from all infra because the proxy * that causes SSL to be used may have caused fake values for some. */ if(!ub_has_ssl_upstream) { ub_ctrl(cfg, "flush_requestlist", ""); ub_ctrl(cfg, "flush_infra", "all"); } ub_has_ssl_upstream = 1; } dnssec-trigger-0.13/riggerd/update.h0000664000175000017500000001243312275162157017104 0ustar wouterwouter/* * update.h - dnssec-trigger update * * Copyright (c) 2012, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains the functions to run update check and download the update */ #ifndef UPDATE_H #define UPDATE_H #include struct outq; struct http_get; struct svr; struct cfg; struct comm_timer; /** * The update data */ struct selfupdate { /** the server */ struct svr* svr; /** the config to use (reference) */ struct cfg* cfg; /** when was the last time the update was performed, if 0 never. * At this time the version check TXT returned successfully. */ time_t last_check; /** we have to update (and ask the user) */ int update_available; /** did the user reply to the question */ int user_replied; /** did the user agree to install the update */ int user_okay; /** if this flag is on update with the unstable test version * This is used to test the software update mechanism. * Or to distribute test software to some participants. */ int test_flag; /** query for TXT record with version and hash */ struct outq* txt_query; /** the probed version (or NULL if not probed) as string */ char* version_available; /** the hash of this installer version (or NULL if not probed) */ uint8_t* hash; /** length of hash */ size_t hashlen; /** get address for http fetch, or NULL on its failure */ struct outq* addr_4; struct outq* addr_6; /** the address list for downloads */ ldns_rr_list* addr_list_4; ldns_rr_list* addr_list_6; /** http get operation that fetches the installer (or NULL if not) */ struct http_get* download_http4; struct http_get* download_http6; /** filename with downloaded file (or NULL) */ char* download_file; /** filename of the download url (no directory part) */ char* filename; /** if we have downloaded to file and hash is okay * we have to delete this file so it does not clog up the system */ int file_available; /** timer that sets selfupdate_desired after 24h in svr */ struct comm_timer* timer; }; /** retry time (in seconds) between version checks */ #define SELFUPDATE_RETRY (2*3600) /** 24h time (in seconds) between version checks */ #define SELFUPDATE_NEXT_CHECK (24*3600) /** * The dnssec trigger domain name (where the TXT records are) * TXT records at {win,src,osx}.{test,version}.ourdomain * with TXT "version" "sha256" */ #define DNSSECTRIGGER_DOMAIN "dnssec-trigger.nlnetlabs.nl" /** the download site for new software updates. */ #define DNSSECTRIGGER_DOWNLOAD_HOST "www.nlnetlabs.nl" /** the download URL for the software updates, the directory (start with /) */ #define DNSSECTRIGGER_DOWNLOAD_URLPRE "/downloads/dnssec-trigger/" /** create new selfupdate structure (empty). */ struct selfupdate* selfupdate_create(struct svr* svr, struct cfg* cfg); /** delete selfupdate structure */ void selfupdate_delete(struct selfupdate* se); /** start selfupdate * We must be in a DNSSEC secure state. unbound at 127.0.0.1 must then * be pointed at this DNSSEC secureness and its AD flag is trusted. */ void selfupdate_start(struct selfupdate* se); /** the user indicates his support for the update (or nonsupport) */ void selfupdate_userokay(struct selfupdate* se, int okay); /** the outq query is done, error reason (or NULL if works) */ void selfupdate_outq_done(struct selfupdate* se, struct outq* outq, ldns_pkt* pkt, const char* reason); /** see if version x is newer than y */ int version_is_newer(const char* x, const char* y); /** timeout handler for selfupdate timer */ void selfupdate_timeout(void* arg); /** routine called when http has connected to the server (but no data yet) */ void selfupdate_http_connected(struct selfupdate* se, struct http_get* hg); /** routine called when http is done */ void selfupdate_http_get_done(struct selfupdate* se, struct http_get* hg, char* reason); #endif /* UPDATE_H */ dnssec-trigger-0.13/riggerd/winsock_event.c0000664000175000017500000005227412275162157020502 0ustar wouterwouter/* * util/winsock_event.c - implementation of the unbound winsock event handler. * * Copyright (c) 2008, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * Implementation of the unbound WinSock2 API event notification handler * for the Windows port. */ #include "config.h" #ifdef USE_WINSOCK #include #include #include "winsock_event.h" #include "fptr_wlist.h" #include "log.h" int mini_ev_cmp(const void* a, const void* b) { const struct event *e = (const struct event*)a; const struct event *f = (const struct event*)b; if(e->ev_timeout.tv_sec < f->ev_timeout.tv_sec) return -1; if(e->ev_timeout.tv_sec > f->ev_timeout.tv_sec) return 1; if(e->ev_timeout.tv_usec < f->ev_timeout.tv_usec) return -1; if(e->ev_timeout.tv_usec > f->ev_timeout.tv_usec) return 1; if(e < f) return -1; if(e > f) return 1; return 0; } /** set time */ static int settime(struct event_base* base) { if(gettimeofday(base->time_tv, NULL) < 0) { return -1; } #ifndef S_SPLINT_S *base->time_secs = (uint32_t)base->time_tv->tv_sec; #endif return 0; } #ifdef UNBOUND_DEBUG /** * Find a fd in the list of items. * Note that not all items have a fd associated (those are -1). * Signals are stored separately, and not searched. * @param base: event base to look in. * @param fd: what socket to look for. * @return the index in the array, or -1 on failure. */ static int find_fd(struct event_base* base, int fd) { int i; for(i=0; imax; i++) { if(base->items[i]->ev_fd == fd) return i; } return -1; } #endif /** Find ptr in base array */ static void zero_waitfor(WSAEVENT waitfor[], WSAEVENT x) { int i; for(i=0; itime_secs = time_secs; base->time_tv = time_tv; if(settime(base) < 0) { event_base_free(base); return NULL; } base->items = (struct event**)calloc(WSK_MAX_ITEMS, sizeof(struct event*)); if(!base->items) { event_base_free(base); return NULL; } base->cap = WSK_MAX_ITEMS; base->max = 0; base->times = rbtree_create(mini_ev_cmp); if(!base->times) { event_base_free(base); return NULL; } base->signals = (struct event**)calloc(MAX_SIG, sizeof(struct event*)); if(!base->signals) { event_base_free(base); return NULL; } base->tcp_stickies = 0; base->tcp_reinvigorated = 0; verbose(VERB_CLIENT, "winsock_event inited"); return base; } const char *event_get_version(void) { return "winsock-event-"PACKAGE_VERSION; } const char *event_get_method(void) { return "WSAWaitForMultipleEvents"; } /** call timeouts handlers, and return how long to wait for next one or -1 */ static void handle_timeouts(struct event_base* base, struct timeval* now, struct timeval* wait) { struct event* p; #ifndef S_SPLINT_S wait->tv_sec = (time_t)-1; #endif verbose(VERB_CLIENT, "winsock_event handle_timeouts"); while((rbnode_t*)(p = (struct event*)rbtree_first(base->times)) !=RBTREE_NULL) { #ifndef S_SPLINT_S if(p->ev_timeout.tv_sec > now->tv_sec || (p->ev_timeout.tv_sec==now->tv_sec && p->ev_timeout.tv_usec > now->tv_usec)) { /* there is a next larger timeout. wait for it */ wait->tv_sec = p->ev_timeout.tv_sec - now->tv_sec; if(now->tv_usec > p->ev_timeout.tv_usec) { wait->tv_sec--; wait->tv_usec = 1000000 - (now->tv_usec - p->ev_timeout.tv_usec); } else { wait->tv_usec = p->ev_timeout.tv_usec - now->tv_usec; } verbose(VERB_CLIENT, "winsock_event wait=%d.%6.6d", (int)wait->tv_sec, (int)wait->tv_usec); return; } #endif /* event times out, remove it */ (void)rbtree_delete(base->times, p); p->ev_events &= ~EV_TIMEOUT; fptr_ok(fptr_whitelist_event(p->ev_callback)); (*p->ev_callback)(p->ev_fd, EV_TIMEOUT, p->ev_arg); } verbose(VERB_CLIENT, "winsock_event wait=(-1)"); } /** handle is_signal events and see if signalled */ static void handle_signal(struct event* ev) { DWORD ret; log_assert(ev->is_signal && ev->hEvent); /* see if the event is signalled */ ret = WSAWaitForMultipleEvents(1, &ev->hEvent, 0 /* any object */, 0 /* return immediately */, 0 /* not alertable for IOcomple*/); if(ret == WSA_WAIT_IO_COMPLETION || ret == WSA_WAIT_FAILED) { log_err("WSAWaitForMultipleEvents(signal) failed: %s", wsa_strerror(WSAGetLastError())); return; } if(ret == WSA_WAIT_TIMEOUT) { /* not signalled */ return; } /* reset the signal */ if(!WSAResetEvent(ev->hEvent)) log_err("WSAResetEvent failed: %s", wsa_strerror(WSAGetLastError())); /* do the callback (which may set the signal again) */ fptr_ok(fptr_whitelist_event(ev->ev_callback)); (*ev->ev_callback)(ev->ev_fd, ev->ev_events, ev->ev_arg); } /** call select and callbacks for that */ static int handle_select(struct event_base* base, struct timeval* wait) { DWORD timeout = 0; /* in milliseconds */ DWORD ret; struct event* eventlist[WSK_MAX_ITEMS]; WSANETWORKEVENTS netev; int i, numwait = 0, startidx = 0, was_timeout = 0; int newstickies = 0; struct timeval nultm; verbose(VERB_CLIENT, "winsock_event handle_select"); #ifndef S_SPLINT_S if(wait->tv_sec==(time_t)-1) wait = NULL; if(wait) timeout = wait->tv_sec*1000 + wait->tv_usec/1000; if(base->tcp_stickies) { wait = &nultm; nultm.tv_sec = 0; nultm.tv_usec = 0; timeout = 0; /* no waiting, we have sticky events */ } #endif /* prepare event array */ for(i=0; imax; i++) { if(base->items[i]->ev_fd == -1 && !base->items[i]->is_signal) continue; /* skip timer only events */ eventlist[numwait] = base->items[i]; base->waitfor[numwait++] = base->items[i]->hEvent; if(numwait == WSK_MAX_ITEMS) break; /* sanity check */ } log_assert(numwait <= WSA_MAXIMUM_WAIT_EVENTS); verbose(VERB_CLIENT, "winsock_event bmax=%d numwait=%d wait=%x " "timeout=%d", base->max, numwait, (int)wait, (int)timeout); /* do the wait */ if(numwait == 0) { /* WSAWaitFor.. doesn't like 0 event objects */ if(wait) { Sleep(timeout); } was_timeout = 1; } else { ret = WSAWaitForMultipleEvents(numwait, base->waitfor, 0 /* do not wait for all, just one will do */, wait?timeout:WSA_INFINITE, 0); /* we are not alertable (IO completion events) */ if(ret == WSA_WAIT_IO_COMPLETION) { log_err("WSAWaitForMultipleEvents failed: WSA_WAIT_IO_COMPLETION"); return -1; } else if(ret == WSA_WAIT_FAILED) { log_err("WSAWaitForMultipleEvents failed: %s", wsa_strerror(WSAGetLastError())); return -1; } else if(ret == WSA_WAIT_TIMEOUT) { was_timeout = 1; } else startidx = ret - WSA_WAIT_EVENT_0; } verbose(VERB_CLIENT, "winsock_event wake was_timeout=%d startidx=%d", was_timeout, startidx); /* get new time after wait */ if(settime(base) < 0) return -1; /* callbacks */ if(base->tcp_stickies) startidx = 0; /* process all events, some are sticky */ for(i=startidx; ijust_checked = 1; verbose(VERB_CLIENT, "winsock_event signals"); for(i=startidx; iwaitfor[i]) continue; /* was deleted */ if(eventlist[i]->is_signal) { eventlist[i]->just_checked = 0; handle_signal(eventlist[i]); } } /* early exit - do not process network, exit quickly */ if(base->need_to_exit) return 0; verbose(VERB_CLIENT, "winsock_event net"); for(i=startidx; iwaitfor[i]) continue; /* was deleted */ if(!eventlist[i]->just_checked) continue; /* added by other callback */ if(eventlist[i]->is_signal) continue; /* not a network event at all */ eventlist[i]->just_checked = 0; if(WSAEnumNetworkEvents(eventlist[i]->ev_fd, base->waitfor[i], /* reset the event handle */ /*NULL,*/ /* do not reset the event handle */ &netev) != 0) { log_err("WSAEnumNetworkEvents failed: %s", wsa_strerror(WSAGetLastError())); return -1; } if((netev.lNetworkEvents & FD_READ)) { if(netev.iErrorCode[FD_READ_BIT] != 0) verbose(VERB_ALGO, "FD_READ_BIT error: %s", wsa_strerror(netev.iErrorCode[FD_READ_BIT])); bits |= EV_READ; } if((netev.lNetworkEvents & FD_WRITE)) { if(netev.iErrorCode[FD_WRITE_BIT] != 0) verbose(VERB_ALGO, "FD_WRITE_BIT error: %s", wsa_strerror(netev.iErrorCode[FD_WRITE_BIT])); bits |= EV_WRITE; } if((netev.lNetworkEvents & FD_CONNECT)) { if(netev.iErrorCode[FD_CONNECT_BIT] != 0) verbose(VERB_ALGO, "FD_CONNECT_BIT error: %s", wsa_strerror(netev.iErrorCode[FD_CONNECT_BIT])); bits |= EV_READ; bits |= EV_WRITE; } if((netev.lNetworkEvents & FD_ACCEPT)) { if(netev.iErrorCode[FD_ACCEPT_BIT] != 0) verbose(VERB_ALGO, "FD_ACCEPT_BIT error: %s", wsa_strerror(netev.iErrorCode[FD_ACCEPT_BIT])); bits |= EV_READ; } if((netev.lNetworkEvents & FD_CLOSE)) { if(netev.iErrorCode[FD_CLOSE_BIT] != 0) verbose(VERB_ALGO, "FD_CLOSE_BIT error: %s", wsa_strerror(netev.iErrorCode[FD_CLOSE_BIT])); bits |= EV_READ; bits |= EV_WRITE; } if(eventlist[i]->is_tcp && eventlist[i]->stick_events) { verbose(VERB_ALGO, "winsock %d pass sticky %s%s", eventlist[i]->ev_fd, (eventlist[i]->old_events&EV_READ)?"EV_READ":"", (eventlist[i]->old_events&EV_WRITE)?"EV_WRITE":""); bits |= eventlist[i]->old_events; } if(eventlist[i]->is_tcp && bits) { eventlist[i]->old_events = bits; eventlist[i]->stick_events = 1; if((eventlist[i]->ev_events & bits)) { newstickies = 1; } verbose(VERB_ALGO, "winsock %d store sticky %s%s", eventlist[i]->ev_fd, (eventlist[i]->old_events&EV_READ)?"EV_READ":"", (eventlist[i]->old_events&EV_WRITE)?"EV_WRITE":""); } if((bits & eventlist[i]->ev_events)) { verbose(VERB_ALGO, "winsock event callback %p fd=%d " "%s%s%s%s%s ; %s%s%s", eventlist[i], eventlist[i]->ev_fd, (netev.lNetworkEvents&FD_READ)?" FD_READ":"", (netev.lNetworkEvents&FD_WRITE)?" FD_WRITE":"", (netev.lNetworkEvents&FD_CONNECT)? " FD_CONNECT":"", (netev.lNetworkEvents&FD_ACCEPT)? " FD_ACCEPT":"", (netev.lNetworkEvents&FD_CLOSE)?" FD_CLOSE":"", (bits&EV_READ)?" EV_READ":"", (bits&EV_WRITE)?" EV_WRITE":"", (bits&EV_TIMEOUT)?" EV_TIMEOUT":""); fptr_ok(fptr_whitelist_event( eventlist[i]->ev_callback)); (*eventlist[i]->ev_callback)(eventlist[i]->ev_fd, bits & eventlist[i]->ev_events, eventlist[i]->ev_arg); } if(eventlist[i]->is_tcp && bits) verbose(VERB_ALGO, "winsock %d got sticky %s%s", eventlist[i]->ev_fd, (eventlist[i]->old_events&EV_READ)?"EV_READ":"", (eventlist[i]->old_events&EV_WRITE)?"EV_WRITE":""); } verbose(VERB_CLIENT, "winsock_event net"); if(base->tcp_reinvigorated) { verbose(VERB_CLIENT, "winsock_event reinvigorated"); base->tcp_reinvigorated = 0; newstickies = 1; } base->tcp_stickies = newstickies; verbose(VERB_CLIENT, "winsock_event handle_select end"); return 0; } int event_base_dispatch(struct event_base *base) { struct timeval wait; if(settime(base) < 0) return -1; while(!base->need_to_exit) { /* see if timeouts need handling */ handle_timeouts(base, base->time_tv, &wait); if(base->need_to_exit) return 0; /* do select */ if(handle_select(base, &wait) < 0) { if(base->need_to_exit) return 0; return -1; } } return 0; } int event_base_loopexit(struct event_base *base, struct timeval * ATTR_UNUSED(tv)) { verbose(VERB_CLIENT, "winsock_event loopexit"); base->need_to_exit = 1; return 0; } void event_base_free(struct event_base *base) { verbose(VERB_CLIENT, "winsock_event event_base_free"); if(!base) return; if(base->items) free(base->items); if(base->times) free(base->times); if(base->signals) free(base->signals); free(base); } void event_set(struct event *ev, int fd, short bits, void (*cb)(int, short, void *), void *arg) { ev->node.key = ev; ev->ev_fd = fd; ev->ev_events = bits; ev->ev_callback = cb; fptr_ok(fptr_whitelist_event(ev->ev_callback)); ev->ev_arg = arg; ev->just_checked = 0; ev->added = 0; } int event_base_set(struct event_base *base, struct event *ev) { ev->ev_base = base; ev->old_events = 0; ev->stick_events = 0; ev->added = 0; return 0; } int event_add(struct event *ev, struct timeval *tv) { verbose(VERB_ALGO, "event_add %p added=%d fd=%d tv=%d %s%s%s", ev, ev->added, ev->ev_fd, (tv?(int)tv->tv_sec*1000+(int)tv->tv_usec/1000:-1), (ev->ev_events&EV_READ)?" EV_READ":"", (ev->ev_events&EV_WRITE)?" EV_WRITE":"", (ev->ev_events&EV_TIMEOUT)?" EV_TIMEOUT":""); if(ev->added) event_del(ev); log_assert(ev->ev_fd==-1 || find_fd(ev->ev_base, ev->ev_fd) == -1); ev->is_tcp = 0; ev->is_signal = 0; ev->just_checked = 0; if((ev->ev_events&(EV_READ|EV_WRITE)) && ev->ev_fd != -1) { BOOL b=0; int t, l; long events = 0; if(ev->ev_base->max == ev->ev_base->cap) return -1; ev->idx = ev->ev_base->max++; ev->ev_base->items[ev->idx] = ev; if( (ev->ev_events&EV_READ) ) events |= FD_READ; if( (ev->ev_events&EV_WRITE) ) events |= FD_WRITE; l = sizeof(t); if(getsockopt(ev->ev_fd, SOL_SOCKET, SO_TYPE, (void*)&t, &l) != 0) log_err("getsockopt(SO_TYPE) failed: %s", wsa_strerror(WSAGetLastError())); if(t == SOCK_STREAM) { /* TCP socket */ ev->is_tcp = 1; events |= FD_CLOSE; if( (ev->ev_events&EV_WRITE) ) events |= FD_CONNECT; l = sizeof(b); if(getsockopt(ev->ev_fd, SOL_SOCKET, SO_ACCEPTCONN, (void*)&b, &l) != 0) log_err("getsockopt(SO_ACCEPTCONN) failed: %s", wsa_strerror(WSAGetLastError())); if(b) /* TCP accept socket */ events |= FD_ACCEPT; } ev->hEvent = WSACreateEvent(); if(ev->hEvent == WSA_INVALID_EVENT) log_err("WSACreateEvent failed: %s", wsa_strerror(WSAGetLastError())); /* automatically sets fd to nonblocking mode. * nonblocking cannot be disabled, until wsaES(fd, NULL, 0) */ if(WSAEventSelect(ev->ev_fd, ev->hEvent, events) != 0) { log_err("WSAEventSelect failed: %s", wsa_strerror(WSAGetLastError())); } if(ev->is_tcp && ev->stick_events && (ev->ev_events & ev->old_events)) { /* go to processing the sticky event right away */ ev->ev_base->tcp_reinvigorated = 1; } } if(tv && (ev->ev_events&EV_TIMEOUT)) { #ifndef S_SPLINT_S struct timeval *now = ev->ev_base->time_tv; ev->ev_timeout.tv_sec = tv->tv_sec + now->tv_sec; ev->ev_timeout.tv_usec = tv->tv_usec + now->tv_usec; while(ev->ev_timeout.tv_usec > 1000000) { ev->ev_timeout.tv_usec -= 1000000; ev->ev_timeout.tv_sec++; } #endif (void)rbtree_insert(ev->ev_base->times, &ev->node); } ev->added = 1; return 0; } int event_del(struct event *ev) { verbose(VERB_ALGO, "event_del %p added=%d fd=%d tv=%d %s%s%s", ev, ev->added, ev->ev_fd, (ev->ev_events&EV_TIMEOUT)?(int)ev->ev_timeout.tv_sec*1000+ (int)ev->ev_timeout.tv_usec/1000:-1, (ev->ev_events&EV_READ)?" EV_READ":"", (ev->ev_events&EV_WRITE)?" EV_WRITE":"", (ev->ev_events&EV_TIMEOUT)?" EV_TIMEOUT":""); if(!ev->added) return 0; log_assert(ev->added); if((ev->ev_events&EV_TIMEOUT)) (void)rbtree_delete(ev->ev_base->times, &ev->node); if((ev->ev_events&(EV_READ|EV_WRITE)) && ev->ev_fd != -1) { log_assert(ev->ev_base->max > 0); /* remove item and compact the list */ ev->ev_base->items[ev->idx] = ev->ev_base->items[ev->ev_base->max-1]; ev->ev_base->items[ev->ev_base->max-1] = NULL; ev->ev_base->max--; if(ev->idx < ev->ev_base->max) ev->ev_base->items[ev->idx]->idx = ev->idx; zero_waitfor(ev->ev_base->waitfor, ev->hEvent); if(WSAEventSelect(ev->ev_fd, ev->hEvent, 0) != 0) log_err("WSAEventSelect(disable) failed: %s", wsa_strerror(WSAGetLastError())); if(!WSACloseEvent(ev->hEvent)) log_err("WSACloseEvent failed: %s", wsa_strerror(WSAGetLastError())); } ev->just_checked = 0; ev->added = 0; return 0; } /** which base gets to handle signals */ static struct event_base* signal_base = NULL; /** signal handler */ static RETSIGTYPE sigh(int sig) { struct event* ev; if(!signal_base || sig < 0 || sig >= MAX_SIG) return; ev = signal_base->signals[sig]; if(!ev) return; fptr_ok(fptr_whitelist_event(ev->ev_callback)); (*ev->ev_callback)(sig, EV_SIGNAL, ev->ev_arg); } int signal_add(struct event *ev, struct timeval * ATTR_UNUSED(tv)) { if(ev->ev_fd == -1 || ev->ev_fd >= MAX_SIG) return -1; signal_base = ev->ev_base; ev->ev_base->signals[ev->ev_fd] = ev; ev->added = 1; if(signal(ev->ev_fd, sigh) == SIG_ERR) { return -1; } return 0; } int signal_del(struct event *ev) { if(ev->ev_fd == -1 || ev->ev_fd >= MAX_SIG) return -1; ev->ev_base->signals[ev->ev_fd] = NULL; ev->added = 0; return 0; } void winsock_tcp_wouldblock(struct event* ev, int eventbits) { verbose(VERB_ALGO, "winsock: tcp wouldblock %s", eventbits==EV_READ?"EV_READ":"EV_WRITE"); ev->old_events &= (~eventbits); if(ev->old_events == 0) ev->stick_events = 0; /* in case this is the last sticky event, we could * possibly run an empty handler loop to reset the base * tcp_stickies variable */ } int winsock_register_wsaevent(struct event_base* base, struct event* ev, WSAEVENT wsaevent, void (*cb)(int, short, void*), void* arg) { if(base->max == base->cap) return 0; memset(ev, 0, sizeof(*ev)); ev->ev_fd = -1; ev->ev_events = EV_READ; ev->ev_callback = cb; ev->ev_arg = arg; ev->is_signal = 1; ev->hEvent = wsaevent; ev->added = 1; ev->ev_base = base; ev->idx = ev->ev_base->max++; ev->ev_base->items[ev->idx] = ev; return 1; } void winsock_unregister_wsaevent(struct event* ev) { if(!ev || !ev->added) return; log_assert(ev->added && ev->ev_base->max > 0) zero_waitfor(ev->ev_base->waitfor, ev->hEvent); /* remove item and compact the list */ ev->ev_base->items[ev->idx] = ev->ev_base->items[ev->ev_base->max-1]; ev->ev_base->items[ev->ev_base->max-1] = NULL; ev->ev_base->max--; if(ev->idx < ev->ev_base->max) ev->ev_base->items[ev->idx]->idx = ev->idx; ev->added = 0; } #else /* USE_WINSOCK */ /** symbol so this codefile defines symbols. pleasing ranlib on OSX 10.5 */ int winsock_unused_symbol = 1; #endif /* USE_WINSOCK */ dnssec-trigger-0.13/riggerd/mini_event.h0000664000175000017500000001346212275162157017762 0ustar wouterwouter/* * mini-event.h - micro implementation of libevent api, using select() only. * * Copyright (c) 2007, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * This file implements part of the event(3) libevent api. * The back end is only select. Max number of fds is limited. * Max number of signals is limited, one handler per signal only. * And one handler per fd. * * Although limited to select() and a max (1024) open fds, it * is efficient: * o dispatch call caches fd_sets to use. * o handler calling takes time ~ to the number of fds. * o timeouts are stored in a redblack tree, sorted, so take log(n). * Timeouts are only accurate to the second (no subsecond accuracy). * To avoid cpu hogging, fractional timeouts are rounded up to a whole second. */ #ifndef MINI_EVENT_H #define MINI_EVENT_H #if defined(USE_MINI_EVENT) && !defined(USE_WINSOCK) #ifndef HAVE_EVENT_BASE_FREE #define HAVE_EVENT_BASE_FREE #endif /** event timeout */ #define EV_TIMEOUT 0x01 /** event fd readable */ #define EV_READ 0x02 /** event fd writable */ #define EV_WRITE 0x04 /** event signal */ #define EV_SIGNAL 0x08 /** event must persist */ #define EV_PERSIST 0x10 /* needs our redblack tree */ #include "rbtree.h" /** max number of file descriptors to support */ #define MAX_FDS 1024 /** max number of signals to support */ #define MAX_SIG 32 /** event base */ struct event_base { /** sorted by timeout (absolute), ptr */ rbtree_t* times; /** array of 0 - maxfd of ptr to event for it */ struct event** fds; /** max fd in use */ int maxfd; /** capacity - size of the fds array */ int capfd; /* fdset for read write, for fds ready, and added */ fd_set /** fds for reading */ reads, /** fds for writing */ writes, /** fds determined ready for use */ ready, /** ready plus newly added events. */ content; /** array of 0 - maxsig of ptr to event for it */ struct event** signals; /** if we need to exit */ int need_to_exit; /** where to store time in seconds */ uint32_t* time_secs; /** where to store time in microseconds */ struct timeval* time_tv; }; /** * Event structure. Has some of the event elements. */ struct event { /** node in timeout rbtree */ rbnode_t node; /** is event already added */ int added; /** event base it belongs to */ struct event_base *ev_base; /** fd to poll or -1 for timeouts. signal number for sigs. */ int ev_fd; /** what events this event is interested in, see EV_.. above. */ short ev_events; /** timeout value */ struct timeval ev_timeout; /** callback to call: fd, eventbits, userarg */ void (*ev_callback)(int, short, void *arg); /** callback user arg */ void *ev_arg; }; /* function prototypes (some are as they appear in event.h) */ /** create event base */ void *event_init(uint32_t* time_secs, struct timeval* time_tv); /** get version */ const char *event_get_version(void); /** get polling method, select */ const char *event_get_method(void); /** run select in a loop */ int event_base_dispatch(struct event_base *); /** exit that loop */ int event_base_loopexit(struct event_base *, struct timeval *); /** free event base. Free events yourself */ void event_base_free(struct event_base *); /** set content of event */ void event_set(struct event *, int, short, void (*)(int, short, void *), void *); /** add event to a base. You *must* call this for every event. */ int event_base_set(struct event_base *, struct event *); /** add event to make it active. You may not change it with event_set anymore */ int event_add(struct event *, struct timeval *); /** remove event. You may change it again */ int event_del(struct event *); /** add a timer */ #define evtimer_add(ev, tv) event_add(ev, tv) /** remove a timer */ #define evtimer_del(ev) event_del(ev) /* uses different implementation. Cannot mix fd/timeouts and signals inside * the same struct event. create several event structs for that. */ /** install signal handler */ int signal_add(struct event *, struct timeval *); /** set signal event contents */ #define signal_set(ev, x, cb, arg) \ event_set(ev, x, EV_SIGNAL|EV_PERSIST, cb, arg) /** remove signal handler */ int signal_del(struct event *); #endif /* USE_MINI_EVENT and not USE_WINSOCK */ /** compare events in tree, based on timevalue, ptr for uniqueness */ int mini_ev_cmp(const void* a, const void* b); #endif /* MINI_EVENT_H */ dnssec-trigger-0.13/riggerd/svr.h0000664000175000017500000001463112275162157016436 0ustar wouterwouter/* * svr.h - dnssec-trigger server * * Copyright (c) 2011, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains the server definition. */ #ifndef SVR_H #define SVR_H struct cfg; struct comm_base; struct comm_reply; struct comm_timer; struct sslconn; struct listen_list; struct comm_point; struct ldns_struct_buffer; struct probe_ip; struct http_general; struct selfupdate; /** * The server */ struct svr { struct cfg* cfg; struct comm_base* base; /** SSL context with keys */ SSL_CTX* ctx; /** number of active commpoints that are handling remote control */ int active; /** max active commpoints */ int max_active; /** commpoints for accepting remote control connections */ struct listen_list* listen; /** busy commpoints */ struct sslconn* busy_list; /** udp buffer */ struct ldns_struct_buffer* udp_buffer; /** probes for the IP addresses */ struct probe_ip* probes; /** numprobes in list */ int num_probes; /** number done */ int num_probes_done; /** number of probes to cache servers (i.e. number of DHCP IPs) */ int num_probes_to_cache; /** saw the first working probe */ int saw_first_working; /** saw direct work */ int saw_direct_work; /** saw dnstcp work */ int saw_dnstcp_work; /** attempt to access DNS authority servers directly */ int probe_direct; /** attempt to probe open resolvers on tcp on 80 and 443 ports */ int probe_dnstcp; /** time of probe */ time_t probetime; /** probe retry timer */ struct comm_timer* retry_timer; /** if retry timer is turned on */ int retry_timer_enabled; /** what is the current time for exponential backoff of timer, sec. */ int retry_timer_timeout; /** count of 10-second retries */ int retry_timer_count; /** tcp retry timer */ struct comm_timer* tcp_timer; /** tcp timer was used last time? */ int tcp_timer_used; /** http lookup structure; or NULL if no urlprobe configured or done */ struct http_general* http; /** self update structure; or NULL if no selfupdate */ struct selfupdate* update; /** do we want to check for updates (when dnssec is available) */ int update_desired; /** result of probes */ enum res_state { /** to authority servers */ res_auth, /** to DHCP-advertised cache on local network */ res_cache, /** to TCP open resolver */ res_tcp, /** to SSL open resolver */ res_ssl, /** no DNSSEC */ res_dark, /** disconnected from the network */ res_disconn} res_state; /* insecure state entered */ int insecure_state; /* forced insecure (for hotspot signon) */ int forced_insecure; /* http insecure (http probe failed, hotspot signon needed perhaps */ int http_insecure; /* skip http probe part (ignore failure until it works again) */ int skip_http; }; /** retry timer start (sec.) */ #define RETRY_TIMER_START 10 /** retry timer max value (sec.) */ #define RETRY_TIMER_MAX 86400 /** retrey timer max count (number of 'START' retries for http insecure) */ #define RETRY_TIMER_COUNT_MAX 30 /** timer for tcp state to try again once (sec.) */ #define SVR_TCP_RETRY 20 /** list of commpoints */ struct listen_list { struct listen_list* next; struct comm_point* c; }; /** busy ssl connection */ struct sslconn { /** the next item in list */ struct sslconn* next; /** the commpoint */ struct comm_point* c; /** in the handshake part */ enum { rc_hs_none, rc_hs_read, rc_hs_write, rc_hs_want_write, rc_hs_want_read, rc_hs_shutdown } shake_state; /** the ssl state */ SSL* ssl; /** line state: read or write */ enum { command_read, persist_read, persist_write, persist_write_checkclose } line_state; /** buffer with info to send or receive */ struct ldns_struct_buffer* buffer; /** have to fetch another status update right away */ int fetch_another_update; /** close after writing one set of results */ int close_me; }; extern struct svr* global_svr; /** create server */ struct svr* svr_create(struct cfg* cfg); /** delete server */ void svr_delete(struct svr* svr); /** perform the service */ void svr_service(struct svr* svr); /** send results to clients */ void svr_send_results(struct svr* svr); /** timeouts of retry timer */ void svr_retry_callback(void* arg); /** timeouts of tcp timer */ void svr_tcp_callback(void* arg); /** start or enable next timeout on the retry timer */ void svr_retry_timer_next(int http_mode); /** stop retry timeouts */ void svr_retry_timer_stop(void); /** set tcp retry timer */ void svr_tcp_timer_enable(void); /** stop tcp retry timer timeouts */ void svr_tcp_timer_stop(void); /** perform a reprobe */ void cmd_reprobe(void); /** check if software updates have to be performed */ void svr_check_update(struct svr* svr); /** signal update to panels over commandchannel */ void svr_signal_update(struct svr* svr, char* version_available); int handle_ssl_accept(struct comm_point* c, void* arg, int error, struct comm_reply* reply_info); int control_callback(struct comm_point* c, void* arg, int error, struct comm_reply* reply_info); #endif /* SVR_H */ dnssec-trigger-0.13/riggerd/winsock_event.h0000664000175000017500000002304412275162157020500 0ustar wouterwouter/* * util/winsock_event.h - unbound event handling for winsock on windows * * Copyright (c) 2008, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains interface functions with the WinSock2 API on Windows. * It uses the winsock WSAWaitForMultipleEvents interface on a number of * sockets. * * Note that windows can only wait for max 64 events at one time. * * Also, file descriptors cannot be waited for. * * Named pipes are not easily available (and are not usable in select() ). * For interprocess communication, it is possible to wait for a hEvent to * be signaled by another thread. * * When a socket becomes readable, then it will not be flagged as * readable again until you have gotten WOULDBLOCK from a recv routine. * That means the event handler must store the readability (edge notify) * and process the incoming data until it blocks. * The function performing recv then has to inform the event handler that * the socket has blocked, and the event handler can mark it as such. * Thus, this file transforms the edge notify from windows to a level notify * that is compatible with UNIX. * The WSAEventSelect page says that it does do level notify, as long * as you call a recv/write/accept at least once when it is signalled. * This last bit is not true, even though documented in server2008 api docs * from microsoft, it does not happen at all. Instead you have to test for * WSAEWOULDBLOCK on a tcp stream, and only then retest the socket. * And before that remember the previous result as still valid. * * To stay 'fair', instead of emptying a socket completely, the event handler * can test the other (marked as blocking) sockets for new events. * * Additionally, TCP accept sockets get special event support. * * Socket numbers are not starting small, they can be any number (say 33060). * Therefore, bitmaps are not used, but arrays. * * on winsock, you must use recv() and send() for TCP reads and writes, * not read() and write(), those work only on files. * * Also fseek and fseeko do not work if a FILE is not fopen-ed in binary mode. * * When under a high load windows gives out lots of errors, from recvfrom * on udp sockets for example (WSAECONNRESET). Even though the udp socket * has no connection per se. */ #ifndef UTIL_WINSOCK_EVENT_H #define UTIL_WINSOCK_EVENT_H #ifdef USE_WINSOCK #ifndef HAVE_EVENT_BASE_FREE #define HAVE_EVENT_BASE_FREE #endif /** event timeout */ #define EV_TIMEOUT 0x01 /** event fd readable */ #define EV_READ 0x02 /** event fd writable */ #define EV_WRITE 0x04 /** event signal */ #define EV_SIGNAL 0x08 /** event must persist */ #define EV_PERSIST 0x10 /* needs our redblack tree */ #include "rbtree.h" /** max number of signals to support */ #define MAX_SIG 32 /** The number of items that the winsock event handler can service. * Windows cannot handle more anyway */ #define WSK_MAX_ITEMS 64 /** * event base for winsock event handler */ struct event_base { /** sorted by timeout (absolute), ptr */ rbtree_t* times; /** array (first part in use) of handles to work on */ struct event** items; /** number of items in use in array */ int max; /** capacity of array, size of array in items */ int cap; /** array of 0 - maxsig of ptr to event for it */ struct event** signals; /** if we need to exit */ int need_to_exit; /** where to store time in seconds */ uint32_t* time_secs; /** where to store time in microseconds */ struct timeval* time_tv; /** * TCP streams have sticky events to them, these are not * reported by the windows event system anymore, we have to * keep reporting those events as present until wouldblock() is * signalled by the handler back to use. */ int tcp_stickies; /** * should next cycle process reinvigorated stickies, * these are stickies that have been stored, but due to a new * event_add a sudden interest in the event has incepted. */ int tcp_reinvigorated; /** The list of events that is currently being processed. */ WSAEVENT waitfor[WSK_MAX_ITEMS]; }; /** * Event structure. Has some of the event elements. */ struct event { /** node in timeout rbtree */ rbnode_t node; /** is event already added */ int added; /** event base it belongs to */ struct event_base *ev_base; /** fd to poll or -1 for timeouts. signal number for sigs. */ int ev_fd; /** what events this event is interested in, see EV_.. above. */ short ev_events; /** timeout value */ struct timeval ev_timeout; /** callback to call: fd, eventbits, userarg */ void (*ev_callback)(int, short, void *); /** callback user arg */ void *ev_arg; /* ----- nonpublic part, for winsock_event only ----- */ /** index of this event in the items array (if added) */ int idx; /** the event handle to wait for new events to become ready */ WSAEVENT hEvent; /** true if this filedes is a TCP socket and needs special attention */ int is_tcp; /** remembered EV_ values */ short old_events; /** should remembered EV_ values be used for TCP streams. * Reset after WOULDBLOCK is signaled using the function. */ int stick_events; /** true if this event is a signaling WSAEvent by the user. * User created and user closed WSAEvent. Only signaled/unsigneled, * no read/write/distinctions needed. */ int is_signal; /** used during callbacks to see which events were just checked */ int just_checked; }; /** create event base */ void *event_init(uint32_t* time_secs, struct timeval* time_tv); /** get version */ const char *event_get_version(void); /** get polling method (select,epoll) */ const char *event_get_method(void); /** run select in a loop */ int event_base_dispatch(struct event_base *); /** exit that loop */ int event_base_loopexit(struct event_base *, struct timeval *); /** free event base. Free events yourself */ void event_base_free(struct event_base *); /** set content of event */ void event_set(struct event *, int, short, void (*)(int, short, void *), void *); /** add event to a base. You *must* call this for every event. */ int event_base_set(struct event_base *, struct event *); /** add event to make it active. You may not change it with event_set anymore */ int event_add(struct event *, struct timeval *); /** remove event. You may change it again */ int event_del(struct event *); #define evtimer_add(ev, tv) event_add(ev, tv) #define evtimer_del(ev) event_del(ev) /* uses different implementation. Cannot mix fd/timeouts and signals inside * the same struct event. create several event structs for that. */ /** install signal handler */ int signal_add(struct event *, struct timeval *); /** set signal event contents */ #define signal_set(ev, x, cb, arg) \ event_set(ev, x, EV_SIGNAL|EV_PERSIST, cb, arg) /** remove signal handler */ int signal_del(struct event *); /** compare events in tree, based on timevalue, ptr for uniqueness */ int mini_ev_cmp(const void* a, const void* b); /** * Routine for windows only, where the handling layer can signal that * a TCP stream encountered WSAEWOULDBLOCK for a stream and thus needs * retesting the event. * Pass if EV_READ or EV_WRITE gave wouldblock. */ void winsock_tcp_wouldblock(struct event* ev, int eventbit); /** * Routine for windows only. where you pass a signal WSAEvent that * you wait for. When the event is signaled, the callback gets called. * The callback has to WSAResetEvent to disable the signal. * @param base: the event base. * @param ev: the event structure for data storage * can be passed uninitialised. * @param wsaevent: the WSAEvent that gets signaled. * @param cb: callback routine. * @param arg: user argument to callback routine. * @return false on error. */ int winsock_register_wsaevent(struct event_base* base, struct event* ev, WSAEVENT wsaevent, void (*cb)(int, short, void*), void* arg); /** * Unregister a wsaevent. User has to close the WSAEVENT itself. * @param ev: event data storage. */ void winsock_unregister_wsaevent(struct event* ev); #endif /* USE_WINSOCK */ #endif /* UTIL_WINSOCK_EVENT_H */ dnssec-trigger-0.13/riggerd/netevent.h0000664000175000017500000005350412275162157017456 0ustar wouterwouter/* * util/netevent.h - event notification * * Copyright (c) 2007, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains event notification functions. * * There are three types of communication points * o UDP socket - perthread buffer. * o TCP-accept socket - array of TCP-sockets, socketcount. * o TCP socket - own buffer, parent-TCPaccept, read/write state, * number of bytes read/written, timeout. * * There are sockets aimed towards our clients and towards the internet. * o frontside - aimed towards our clients, queries come in, answers back. * o behind - aimed towards internet, to the authoritative DNS servers. * * Several event types are available: * o comm_base - for thread safety of the comm points, one per thread. * o comm_point - udp and tcp networking, with callbacks. * o comm_timer - a timeout with callback. * o comm_signal - callbacks when signal is caught. * o comm_reply - holds reply info during networking callback. * */ #ifndef NET_EVENT_H #define NET_EVENT_H #include struct comm_point; struct comm_reply; struct event_base; /* internal event notification data storage structure. */ struct internal_event; struct internal_base; struct internal_timer; /** callback from communication point function type */ typedef int comm_point_callback_t(struct comm_point*, void*, int, struct comm_reply*); /** to pass no_error to callback function */ #define NETEVENT_NOERROR 0 /** to pass closed connection to callback function */ #define NETEVENT_CLOSED -1 /** to pass timeout happened to callback function */ #define NETEVENT_TIMEOUT -2 /** to pass fallback from capsforID to callback function; 0x20 failed */ #define NETEVENT_CAPSFAIL -3 /** * A communication point dispatcher. Thread specific. */ struct comm_base { /** behind the scenes structure. with say libevent info. alloced */ struct internal_base* eb; }; /** * Reply information for a communication point. */ struct comm_reply { /** the comm_point with fd to send reply on to. */ struct comm_point* c; /** the address (for UDP based communication) */ struct sockaddr_storage addr; /** length of address */ socklen_t addrlen; /** return type 0 (none), 4(IP4), 6(IP6) */ int srctype; /** the return source interface data */ union { #ifdef IPV6_PKTINFO struct in6_pktinfo v6info; #endif #ifdef IP_PKTINFO struct in_pktinfo v4info; #elif defined(IP_RECVDSTADDR) struct in_addr v4addr; #endif } /** variable with return source data */ pktinfo; }; /** * Communication point to the network * These behaviours can be accomplished by setting the flags * and passing return values from the callback. * udp frontside: called after readdone. sendafter. * tcp frontside: called readdone, sendafter. close. * udp behind: called after readdone. No send after. * tcp behind: write done, read done, then called. No send after. */ struct comm_point { /** behind the scenes structure, with say libevent info. alloced. */ struct internal_event* ev; /** file descriptor for communication point */ int fd; /** timeout (NULL if it does not). Malloced. */ struct timeval* timeout; /** buffer pointer. Either to perthread, or own buffer or NULL */ ldns_buffer* buffer; /* -------- TCP Handler -------- */ /** Read/Write state for TCP */ int tcp_is_reading; /** The current read/write count for TCP */ size_t tcp_byte_count; /** parent communication point (for TCP sockets) */ struct comm_point* tcp_parent; /** sockaddr from peer, for TCP handlers */ struct comm_reply repinfo; /* -------- TCP Accept -------- */ /** the number of TCP handlers for this tcp-accept socket */ int max_tcp_count; /** malloced array of tcp handlers for a tcp-accept, of size max_tcp_count. */ struct comm_point** tcp_handlers; /** linked list of free tcp_handlers to use for new queries. For tcp_accept the first entry, for tcp_handlers the next one. */ struct comm_point* tcp_free; /* -------- SSL TCP DNS ------- */ /** the SSL object with rw bio (owned) or for commaccept ctx ref */ void* ssl; /** handshake state for init and renegotiate */ enum { /** no handshake, it has been done */ comm_ssl_shake_none = 0, /** ssl initial handshake wants to read */ comm_ssl_shake_read, /** ssl initial handshake wants to write */ comm_ssl_shake_write, /** ssl_write wants to read */ comm_ssl_shake_hs_read, /** ssl_read wants to write */ comm_ssl_shake_hs_write } ssl_shake_state; /** is this a UDP, TCP-accept or TCP socket. */ enum comm_point_type { /** UDP socket - handle datagrams. */ comm_udp, /** TCP accept socket - only creates handlers if readable. */ comm_tcp_accept, /** TCP handler socket - handle byteperbyte readwrite. */ comm_tcp, /** AF_UNIX socket - for internal commands. */ comm_local, /** raw - not DNS format - for pipe readers and writers */ comm_raw } /** variable with type of socket, UDP,TCP-accept,TCP,pipe */ type; /* ---------- Behaviour ----------- */ /** if set the connection is NOT closed on delete. */ int do_not_close; /** if set, the connection is closed on error, on timeout, and after read/write completes. No callback is done. */ int tcp_do_close; /** if set, read/write completes: read/write state of tcp is toggled. buffer reset/bytecount reset. this flag cleared. So that when that is done the callback is called. */ int tcp_do_toggle_rw; /** if set, checks for pending error from nonblocking connect() call.*/ int tcp_check_nb_connect; /** number of queries outstanding on this socket, used by * outside network for udp ports */ int inuse; /** callback when done. tcp_accept does not get called back, is NULL then. If a timeout happens, callback with timeout=1 is called. If an error happens, callback is called with error set nonzero. If not NETEVENT_NOERROR, it is an errno value. If the connection is closed (by remote end) then the callback is called with error set to NETEVENT_CLOSED=-1. If a timeout happens on the connection, the error is set to NETEVENT_TIMEOUT=-2. The reply_info can be copied if the reply needs to happen at a later time. It consists of a struct with commpoint and address. It can be passed to a msg send routine some time later. Note the reply information is temporary and must be copied. NULL is passed for_reply info, in cases where error happened. declare as: int my_callback(struct comm_point* c, void* my_arg, int error, struct comm_reply *reply_info); if the routine returns 0, nothing is done. Notzero, the buffer will be sent back to client. For UDP this is done without changing the commpoint. In TCP it sets write state. */ comm_point_callback_t* callback; /** argument to pass to callback. */ void *cb_arg; }; /** * Structure only for making timeout events. */ struct comm_timer { /** the internal event stuff */ struct internal_timer* ev_timer; /** callback function, takes user arg only */ void (*callback)(void*); /** callback user argument */ void* cb_arg; }; /** * Structure only for signal events. */ struct comm_signal { /** the communication base */ struct comm_base* base; /** the internal event stuff */ struct internal_signal* ev_signal; /** callback function, takes signal number and user arg */ void (*callback)(int, void*); /** callback user argument */ void* cb_arg; }; /** * Create a new comm base. * @param sigs: if true it attempts to create a default loop for * signal handling. * @return: the new comm base. NULL on error. */ struct comm_base* comm_base_create(int sigs); /** * Destroy a comm base. * All comm points must have been deleted. * @param b: the base to delete. */ void comm_base_delete(struct comm_base* b); /** * Obtain two pointers. The pointers never change (until base_delete()). * The pointers point to time values that are updated regularly. * @param b: the communication base that will update the time values. * @param tt: pointer to time in seconds is returned. * @param tv: pointer to time in microseconds is returned. */ void comm_base_timept(struct comm_base* b, uint32_t** tt, struct timeval** tv); /** * Dispatch the comm base events. * @param b: the communication to perform. */ void comm_base_dispatch(struct comm_base* b); /** * Exit from dispatch loop. * @param b: the communication base that is in dispatch(). */ void comm_base_exit(struct comm_base* b); /** * Access internal data structure (for util/tube.c on windows) * @param b: comm base * @return event_base. Could be libevent, or internal event handler. */ struct event_base* comm_base_internal(struct comm_base* b); /** * Create an UDP comm point. Calls malloc. * setups the structure with the parameters you provide. * @param base: in which base to alloc the commpoint. * @param fd : file descriptor of open UDP socket. * @param buffer: shared buffer by UDP sockets from this thread. * @param callback: callback function pointer. * @param callback_arg: will be passed to your callback function. * @return: returns the allocated communication point. NULL on error. * Sets timeout to NULL. Turns off TCP options. */ struct comm_point* comm_point_create_udp(struct comm_base* base, int fd, ldns_buffer* buffer, comm_point_callback_t* callback, void* callback_arg); /** * Create an UDP with ancillary data comm point. Calls malloc. * Uses recvmsg instead of recv to get udp message. * setups the structure with the parameters you provide. * @param base: in which base to alloc the commpoint. * @param fd : file descriptor of open UDP socket. * @param buffer: shared buffer by UDP sockets from this thread. * @param callback: callback function pointer. * @param callback_arg: will be passed to your callback function. * @return: returns the allocated communication point. NULL on error. * Sets timeout to NULL. Turns off TCP options. */ struct comm_point* comm_point_create_udp_ancil(struct comm_base* base, int fd, ldns_buffer* buffer, comm_point_callback_t* callback, void* callback_arg); /** * Create a TCP listener comm point. Calls malloc. * Setups the structure with the parameters you provide. * Also Creates TCP Handlers, pre allocated for you. * Uses the parameters you provide. * @param base: in which base to alloc the commpoint. * @param fd: file descriptor of open TCP socket set to listen nonblocking. * @param num: becomes max_tcp_count, the routine allocates that * many tcp handler commpoints. * @param bufsize: size of buffer to create for handlers. * @param callback: callback function pointer for TCP handlers. * @param callback_arg: will be passed to your callback function. * @return: returns the TCP listener commpoint. You can find the * TCP handlers in the array inside the listener commpoint. * returns NULL on error. * Inits timeout to NULL. All handlers are on the free list. */ struct comm_point* comm_point_create_tcp(struct comm_base* base, int fd, int num, size_t bufsize, comm_point_callback_t* callback, void* callback_arg); /** * Create an outgoing TCP commpoint. No file descriptor is opened, left at -1. * @param base: in which base to alloc the commpoint. * @param bufsize: size of buffer to create for handlers. * @param callback: callback function pointer for the handler. * @param callback_arg: will be passed to your callback function. * @return: the commpoint or NULL on error. */ struct comm_point* comm_point_create_tcp_out(struct comm_base* base, size_t bufsize, comm_point_callback_t* callback, void* callback_arg); /** * Create commpoint to listen to a local domain file descriptor. * @param base: in which base to alloc the commpoint. * @param fd: file descriptor of open AF_UNIX socket set to listen nonblocking. * @param bufsize: size of buffer to create for handlers. * @param callback: callback function pointer for the handler. * @param callback_arg: will be passed to your callback function. * @return: the commpoint or NULL on error. */ struct comm_point* comm_point_create_local(struct comm_base* base, int fd, size_t bufsize, comm_point_callback_t* callback, void* callback_arg); /** * Create commpoint to listen to a local domain pipe descriptor. * @param base: in which base to alloc the commpoint. * @param fd: file descriptor. * @param writing: true if you want to listen to writes, false for reads. * @param callback: callback function pointer for the handler. * @param callback_arg: will be passed to your callback function. * @return: the commpoint or NULL on error. */ struct comm_point* comm_point_create_raw(struct comm_base* base, int fd, int writing, comm_point_callback_t* callback, void* callback_arg); /** * Close a comm point fd. * @param c: comm point to close. */ void comm_point_close(struct comm_point* c); /** * Close and deallocate (free) the comm point. If the comm point is * a tcp-accept point, also its tcp-handler points are deleted. * @param c: comm point to delete. */ void comm_point_delete(struct comm_point* c); /** * Send reply. Put message into commpoint buffer. * @param repinfo: The reply info copied from a commpoint callback call. */ void comm_point_send_reply(struct comm_reply* repinfo); /** * Drop reply. Cleans up. * @param repinfo: The reply info copied from a commpoint callback call. */ void comm_point_drop_reply(struct comm_reply* repinfo); /** * Send an udp message over a commpoint. * @param c: commpoint to send it from. * @param packet: what to send. * @param addr: where to send it to. * @param addrlen: length of addr. * @return: false on a failure. */ int comm_point_send_udp_msg(struct comm_point* c, ldns_buffer* packet, struct sockaddr* addr, socklen_t addrlen); /** * Stop listening for input on the commpoint. No callbacks will happen. * @param c: commpoint to disable. The fd is not closed. */ void comm_point_stop_listening(struct comm_point* c); /** * Start listening again for input on the comm point. * @param c: commpoint to enable again. * @param newfd: new fd, or -1 to leave fd be. * @param sec: timeout in seconds, or -1 for no (change to the) timeout. */ void comm_point_start_listening(struct comm_point* c, int newfd, int sec); /** * Stop listening and start listening again for reading or writing. * @param c: commpoint * @param rd: if true, listens for reading. * @param wr: if true, listens for writing. */ void comm_point_listen_for_rw(struct comm_point* c, int rd, int wr); /** * Get size of memory used by comm point. * For TCP handlers this includes subhandlers. * For UDP handlers, this does not include the (shared) UDP buffer. * @param c: commpoint. * @return size in bytes. */ size_t comm_point_get_mem(struct comm_point* c); /** * create timer. Not active upon creation. * @param base: event handling base. * @param cb: callback function: void myfunc(void* myarg); * @param cb_arg: user callback argument. * @return: the new timer or NULL on error. */ struct comm_timer* comm_timer_create(struct comm_base* base, void (*cb)(void*), void* cb_arg); /** * disable timer. Stops callbacks from happening. * @param timer: to disable. */ void comm_timer_disable(struct comm_timer* timer); /** * reset timevalue for timer. * @param timer: timer to (re)set. * @param tv: when the timer should activate. if NULL timer is disabled. */ void comm_timer_set(struct comm_timer* timer, struct timeval* tv); /** * delete timer. * @param timer: to delete. */ void comm_timer_delete(struct comm_timer* timer); /** * see if timeout has been set to a value. * @param timer: the timer to examine. * @return: false if disabled or not set. */ int comm_timer_is_set(struct comm_timer* timer); /** * Get size of memory used by comm timer. * @param timer: the timer to examine. * @return size in bytes. */ size_t comm_timer_get_mem(struct comm_timer* timer); /** * Create a signal handler. Call signal_bind() later to bind to a signal. * @param base: communication base to use. * @param callback: called when signal is caught. * @param cb_arg: user argument to callback * @return: the signal struct or NULL on error. */ struct comm_signal* comm_signal_create(struct comm_base* base, void (*callback)(int, void*), void* cb_arg); /** * Bind signal struct to catch a signal. A signle comm_signal can be bound * to multiple signals, calling comm_signal_bind multiple times. * @param comsig: the communication point, with callback information. * @param sig: signal number. * @return: true on success. false on error. */ int comm_signal_bind(struct comm_signal* comsig, int sig); /** * Delete the signal communication point. * @param comsig: to delete. */ void comm_signal_delete(struct comm_signal* comsig); /** * perform accept(2) with error checking. * @param c: commpoint with accept fd. * @param addr: remote end returned here. * @param addrlen: length of remote end returned here. * @return new fd, or -1 on error. * if -1, error message has been printed if necessary, simply drop * out of the reading handler. */ int comm_point_perform_accept(struct comm_point* c, struct sockaddr_storage* addr, socklen_t* addrlen); /**** internal routines ****/ /** * This routine is published for checks and tests, and is only used internally. * handle libevent callback for udp comm point. * @param fd: file descriptor. * @param event: event bits from libevent: * EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT. * @param arg: the comm_point structure. */ void comm_point_udp_callback(int fd, short event, void* arg); /** * This routine is published for checks and tests, and is only used internally. * handle libevent callback for udp ancillary data comm point. * @param fd: file descriptor. * @param event: event bits from libevent: * EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT. * @param arg: the comm_point structure. */ void comm_point_udp_ancil_callback(int fd, short event, void* arg); /** * This routine is published for checks and tests, and is only used internally. * handle libevent callback for tcp accept comm point * @param fd: file descriptor. * @param event: event bits from libevent: * EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT. * @param arg: the comm_point structure. */ void comm_point_tcp_accept_callback(int fd, short event, void* arg); /** * This routine is published for checks and tests, and is only used internally. * handle libevent callback for tcp data comm point * @param fd: file descriptor. * @param event: event bits from libevent: * EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT. * @param arg: the comm_point structure. */ void comm_point_tcp_handle_callback(int fd, short event, void* arg); /** * This routine is published for checks and tests, and is only used internally. * handle libevent callback for timer comm. * @param fd: file descriptor (always -1). * @param event: event bits from libevent: * EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT. * @param arg: the comm_timer structure. */ void comm_timer_callback(int fd, short event, void* arg); /** * This routine is published for checks and tests, and is only used internally. * handle libevent callback for signal comm. * @param fd: file descriptor (used for the signal number). * @param event: event bits from libevent: * EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT. * @param arg: the internal commsignal structure. */ void comm_signal_callback(int fd, short event, void* arg); /** * This routine is published for checks and tests, and is only used internally. * libevent callback for AF_UNIX fds * @param fd: file descriptor. * @param event: event bits from libevent: * EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT. * @param arg: the comm_point structure. */ void comm_point_local_handle_callback(int fd, short event, void* arg); /** * This routine is published for checks and tests, and is only used internally. * libevent callback for raw fd access. * @param fd: file descriptor. * @param event: event bits from libevent: * EV_READ, EV_WRITE, EV_SIGNAL, EV_TIMEOUT. * @param arg: the comm_point structure. */ void comm_point_raw_handle_callback(int fd, short event, void* arg); #ifdef USE_WINSOCK /** * Callback for openssl BIO to on windows detect WSAEWOULDBLOCK and notify * the winsock_event of this for proper TCP nonblocking implementation. * @param c: comm_point, fd must be set its struct event is registered. * @param ssl: openssl SSL, fd must be set so it has a bio. */ void comm_point_tcp_win_bio_cb(struct comm_point* c, void* ssl); /** get internal event structure for commpoint */ struct event* comm_point_internal(struct comm_point* c); #endif #endif /* NET_EVENT_H */ dnssec-trigger-0.13/riggerd/rbtree.h0000664000175000017500000001417012275162157017105 0ustar wouterwouter/* * rbtree.h -- generic red-black tree * * Copyright (c) 2001-2007, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** * \file * Red black tree. Implementation taken from NSD 3.0.5, adjusted for use * in unbound (memory allocation, logging and so on). */ #ifndef UTIL_RBTREE_H_ #define UTIL_RBTREE_H_ /** * This structure must be the first member of the data structure in * the rbtree. This allows easy casting between an rbnode_t and the * user data (poor man's inheritance). */ typedef struct rbnode_t rbnode_t; /** * The rbnode_t struct definition. */ struct rbnode_t { /** parent in rbtree, RBTREE_NULL for root */ rbnode_t *parent; /** left node (smaller items) */ rbnode_t *left; /** right node (larger items) */ rbnode_t *right; /** pointer to sorting key */ const void *key; /** colour of this node */ uint8_t color; }; /** The nullpointer, points to empty node */ #define RBTREE_NULL &rbtree_null_node /** the global empty node */ extern rbnode_t rbtree_null_node; /** An entire red black tree */ typedef struct rbtree_t rbtree_t; /** definition for tree struct */ struct rbtree_t { /** The root of the red-black tree */ rbnode_t *root; /** The number of the nodes in the tree */ size_t count; /** * Key compare function. <0,0,>0 like strcmp. * Return 0 on two NULL ptrs. */ int (*cmp) (const void *, const void *); }; /** * Create new tree (malloced) with given key compare function. * @param cmpf: compare function (like strcmp) takes pointers to two keys. * @return: new tree, empty. */ rbtree_t *rbtree_create(int (*cmpf)(const void *, const void *)); /** * Init a new tree (malloced by caller) with given key compare function. * @param rbtree: uninitialised memory for new tree, returned empty. * @param cmpf: compare function (like strcmp) takes pointers to two keys. */ void rbtree_init(rbtree_t *rbtree, int (*cmpf)(const void *, const void *)); /** * Insert data into the tree. * @param rbtree: tree to insert to. * @param data: element to insert. * @return: data ptr or NULL if key already present. */ rbnode_t *rbtree_insert(rbtree_t *rbtree, rbnode_t *data); /** * Delete element from tree. * @param rbtree: tree to delete from. * @param key: key of item to delete. * @return: node that is now unlinked from the tree. User to delete it. * returns 0 if node not present */ rbnode_t *rbtree_delete(rbtree_t *rbtree, const void *key); /** * Find key in tree. Returns NULL if not found. * @param rbtree: tree to find in. * @param key: key that must match. * @return: node that fits or NULL. */ rbnode_t *rbtree_search(rbtree_t *rbtree, const void *key); /** * Find, but match does not have to be exact. * @param rbtree: tree to find in. * @param key: key to find position of. * @param result: set to the exact node if present, otherwise to element that * precedes the position of key in the tree. NULL if no smaller element. * @return: true if exact match in result. Else result points to <= element, * or NULL if key is smaller than the smallest key. */ int rbtree_find_less_equal(rbtree_t *rbtree, const void *key, rbnode_t **result); /** * Returns first (smallest) node in the tree * @param rbtree: tree * @return: smallest element or NULL if tree empty. */ rbnode_t *rbtree_first(rbtree_t *rbtree); /** * Returns last (largest) node in the tree * @param rbtree: tree * @return: largest element or NULL if tree empty. */ rbnode_t *rbtree_last(rbtree_t *rbtree); /** * Returns next larger node in the tree * @param rbtree: tree * @return: next larger element or NULL if no larger in tree. */ rbnode_t *rbtree_next(rbnode_t *rbtree); /** * Returns previous smaller node in the tree * @param rbtree: tree * @return: previous smaller element or NULL if no previous in tree. */ rbnode_t *rbtree_previous(rbnode_t *rbtree); /** * Call with node=variable of struct* with rbnode_t as first element. * with type is the type of a pointer to that struct. */ #define RBTREE_FOR(node, type, rbtree) \ for(node=(type)rbtree_first(rbtree); \ (rbnode_t*)node != RBTREE_NULL; \ node = (type)rbtree_next((rbnode_t*)node)) /** * Call function for all elements in the redblack tree, such that * leaf elements are called before parent elements. So that all * elements can be safely free()d. * Note that your function must not remove the nodes from the tree. * Since that may trigger rebalances of the rbtree. * @param tree: the tree * @param func: function called with element and user arg. * The function must not alter the rbtree. * @param arg: user argument. */ void traverse_postorder(rbtree_t* tree, void (*func)(rbnode_t*, void*), void* arg); #endif /* UTIL_RBTREE_H_ */ dnssec-trigger-0.13/riggerd/mini_event.c0000664000175000017500000002347512275162157017762 0ustar wouterwouter/* * mini_event.c - implementation of part of libevent api, portably. * * Copyright (c) 2007, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** * \file * fake libevent implementation. Less broad in functionality, and only * supports select(2). */ #include "config.h" #ifdef HAVE_TIME_H #include #endif #include #if defined(USE_MINI_EVENT) && !defined(USE_WINSOCK) #include #include "mini_event.h" #include "log.h" #include "fptr_wlist.h" /** compare events in tree, based on timevalue, ptr for uniqueness */ int mini_ev_cmp(const void* a, const void* b) { const struct event *e = (const struct event*)a; const struct event *f = (const struct event*)b; if(e->ev_timeout.tv_sec < f->ev_timeout.tv_sec) return -1; if(e->ev_timeout.tv_sec > f->ev_timeout.tv_sec) return 1; if(e->ev_timeout.tv_usec < f->ev_timeout.tv_usec) return -1; if(e->ev_timeout.tv_usec > f->ev_timeout.tv_usec) return 1; if(e < f) return -1; if(e > f) return 1; return 0; } /** set time */ static int settime(struct event_base* base) { if(gettimeofday(base->time_tv, NULL) < 0) { return -1; } #ifndef S_SPLINT_S *base->time_secs = (uint32_t)base->time_tv->tv_sec; #endif return 0; } /** create event base */ void *event_init(uint32_t* time_secs, struct timeval* time_tv) { struct event_base* base = (struct event_base*)malloc( sizeof(struct event_base)); if(!base) return NULL; memset(base, 0, sizeof(*base)); base->time_secs = time_secs; base->time_tv = time_tv; if(settime(base) < 0) { event_base_free(base); return NULL; } base->times = rbtree_create(mini_ev_cmp); if(!base->times) { event_base_free(base); return NULL; } base->capfd = MAX_FDS; #ifdef FD_SETSIZE if((int)FD_SETSIZE < base->capfd) base->capfd = (int)FD_SETSIZE; #endif base->fds = (struct event**)calloc((size_t)base->capfd, sizeof(struct event*)); if(!base->fds) { event_base_free(base); return NULL; } base->signals = (struct event**)calloc(MAX_SIG, sizeof(struct event*)); if(!base->signals) { event_base_free(base); return NULL; } #ifndef S_SPLINT_S FD_ZERO(&base->reads); FD_ZERO(&base->writes); #endif return base; } /** get version */ const char *event_get_version(void) { return "mini-event-"PACKAGE_VERSION; } /** get polling method, select */ const char *event_get_method(void) { return "select"; } /** call timeouts handlers, and return how long to wait for next one or -1 */ static void handle_timeouts(struct event_base* base, struct timeval* now, struct timeval* wait) { struct event* p; #ifndef S_SPLINT_S wait->tv_sec = (time_t)-1; #endif while((rbnode_t*)(p = (struct event*)rbtree_first(base->times)) !=RBTREE_NULL) { #ifndef S_SPLINT_S if(p->ev_timeout.tv_sec > now->tv_sec || (p->ev_timeout.tv_sec==now->tv_sec && p->ev_timeout.tv_usec > now->tv_usec)) { /* there is a next larger timeout. wait for it */ wait->tv_sec = p->ev_timeout.tv_sec - now->tv_sec; if(now->tv_usec > p->ev_timeout.tv_usec) { wait->tv_sec--; wait->tv_usec = 1000000 - (now->tv_usec - p->ev_timeout.tv_usec); } else { wait->tv_usec = p->ev_timeout.tv_usec - now->tv_usec; } return; } #endif /* event times out, remove it */ (void)rbtree_delete(base->times, p); p->ev_events &= ~EV_TIMEOUT; fptr_ok(fptr_whitelist_event(p->ev_callback)); (*p->ev_callback)(p->ev_fd, EV_TIMEOUT, p->ev_arg); } } /** call select and callbacks for that */ static int handle_select(struct event_base* base, struct timeval* wait) { fd_set r, w; int ret, i; #ifndef S_SPLINT_S if(wait->tv_sec==(time_t)-1) wait = NULL; #endif memmove(&r, &base->reads, sizeof(fd_set)); memmove(&w, &base->writes, sizeof(fd_set)); memmove(&base->ready, &base->content, sizeof(fd_set)); if((ret = select(base->maxfd+1, &r, &w, NULL, wait)) == -1) { ret = errno; if(settime(base) < 0) return -1; errno = ret; if(ret == EAGAIN || ret == EINTR) return 0; return -1; } if(settime(base) < 0) return -1; for(i=0; imaxfd+1; i++) { short bits = 0; if(!base->fds[i] || !(FD_ISSET(i, &base->ready))) { continue; } if(FD_ISSET(i, &r)) { bits |= EV_READ; ret--; } if(FD_ISSET(i, &w)) { bits |= EV_WRITE; ret--; } bits &= base->fds[i]->ev_events; if(bits) { fptr_ok(fptr_whitelist_event( base->fds[i]->ev_callback)); (*base->fds[i]->ev_callback)(base->fds[i]->ev_fd, bits, base->fds[i]->ev_arg); if(ret==0) break; } } return 0; } /** run select in a loop */ int event_base_dispatch(struct event_base* base) { struct timeval wait; if(settime(base) < 0) return -1; while(!base->need_to_exit) { /* see if timeouts need handling */ handle_timeouts(base, base->time_tv, &wait); if(base->need_to_exit) break; /* do select */ if(handle_select(base, &wait) < 0) { if(base->need_to_exit) break; return -1; } } base->need_to_exit = 0; return 0; } /** exit that loop */ int event_base_loopexit(struct event_base* base, struct timeval* ATTR_UNUSED(tv)) { base->need_to_exit = 1; return 0; } /* free event base, free events yourself */ void event_base_free(struct event_base* base) { if(!base) return; if(base->times) free(base->times); if(base->fds) free(base->fds); if(base->signals) free(base->signals); free(base); } /** set content of event */ void event_set(struct event* ev, int fd, short bits, void (*cb)(int, short, void *), void* arg) { ev->node.key = ev; ev->ev_fd = fd; ev->ev_events = bits; ev->ev_callback = cb; fptr_ok(fptr_whitelist_event(ev->ev_callback)); ev->ev_arg = arg; ev->added = 0; } /* add event to a base */ int event_base_set(struct event_base* base, struct event* ev) { ev->ev_base = base; ev->added = 0; return 0; } /* add event to make it active, you may not change it with event_set anymore */ int event_add(struct event* ev, struct timeval* tv) { if(ev->added) event_del(ev); if(ev->ev_fd != -1 && ev->ev_fd >= ev->ev_base->capfd) return -1; if( (ev->ev_events&(EV_READ|EV_WRITE)) && ev->ev_fd != -1) { ev->ev_base->fds[ev->ev_fd] = ev; if(ev->ev_events&EV_READ) { FD_SET(FD_SET_T ev->ev_fd, &ev->ev_base->reads); } if(ev->ev_events&EV_WRITE) { FD_SET(FD_SET_T ev->ev_fd, &ev->ev_base->writes); } FD_SET(FD_SET_T ev->ev_fd, &ev->ev_base->content); FD_CLR(FD_SET_T ev->ev_fd, &ev->ev_base->ready); if(ev->ev_fd > ev->ev_base->maxfd) ev->ev_base->maxfd = ev->ev_fd; } if(tv && (ev->ev_events&EV_TIMEOUT)) { #ifndef S_SPLINT_S struct timeval *now = ev->ev_base->time_tv; ev->ev_timeout.tv_sec = tv->tv_sec + now->tv_sec; ev->ev_timeout.tv_usec = tv->tv_usec + now->tv_usec; while(ev->ev_timeout.tv_usec > 1000000) { ev->ev_timeout.tv_usec -= 1000000; ev->ev_timeout.tv_sec++; } #endif (void)rbtree_insert(ev->ev_base->times, &ev->node); } ev->added = 1; return 0; } /* remove event, you may change it again */ int event_del(struct event* ev) { if(ev->ev_fd != -1 && ev->ev_fd >= ev->ev_base->capfd) return -1; if((ev->ev_events&EV_TIMEOUT)) (void)rbtree_delete(ev->ev_base->times, &ev->node); if((ev->ev_events&(EV_READ|EV_WRITE)) && ev->ev_fd != -1) { ev->ev_base->fds[ev->ev_fd] = NULL; FD_CLR(FD_SET_T ev->ev_fd, &ev->ev_base->reads); FD_CLR(FD_SET_T ev->ev_fd, &ev->ev_base->writes); FD_CLR(FD_SET_T ev->ev_fd, &ev->ev_base->ready); FD_CLR(FD_SET_T ev->ev_fd, &ev->ev_base->content); } ev->added = 0; return 0; } /** which base gets to handle signals */ static struct event_base* signal_base = NULL; /** signal handler */ static RETSIGTYPE sigh(int sig) { struct event* ev; if(!signal_base || sig < 0 || sig >= MAX_SIG) return; ev = signal_base->signals[sig]; if(!ev) return; fptr_ok(fptr_whitelist_event(ev->ev_callback)); (*ev->ev_callback)(sig, EV_SIGNAL, ev->ev_arg); } /** install signal handler */ int signal_add(struct event* ev, struct timeval* ATTR_UNUSED(tv)) { if(ev->ev_fd == -1 || ev->ev_fd >= MAX_SIG) return -1; signal_base = ev->ev_base; ev->ev_base->signals[ev->ev_fd] = ev; ev->added = 1; if(signal(ev->ev_fd, sigh) == SIG_ERR) { return -1; } return 0; } /** remove signal handler */ int signal_del(struct event* ev) { if(ev->ev_fd == -1 || ev->ev_fd >= MAX_SIG) return -1; ev->ev_base->signals[ev->ev_fd] = NULL; ev->added = 0; return 0; } #else /* USE_MINI_EVENT */ #ifndef USE_WINSOCK int mini_ev_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b)) { return 0; } #endif /* not USE_WINSOCK */ #endif /* USE_MINI_EVENT */ dnssec-trigger-0.13/riggerd/netevent.c0000664000175000017500000015326712275162157017460 0ustar wouterwouter/* * util/netevent.c - event notification * * Copyright (c) 2007, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains event notification functions. */ #include "config.h" #include #include "netevent.h" #include "log.h" #include "net_help.h" #include "fptr_wlist.h" #include #include /* -------- Start of local definitions -------- */ /** if CMSG_ALIGN is not defined on this platform, a workaround */ #ifndef CMSG_ALIGN # ifdef _CMSG_DATA_ALIGN # define CMSG_ALIGN _CMSG_DATA_ALIGN # else # define CMSG_ALIGN(len) (((len)+sizeof(long)-1) & ~(sizeof(long)-1)) # endif #endif /** if CMSG_LEN is not defined on this platform, a workaround */ #ifndef CMSG_LEN # define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr))+(len)) #endif /** if CMSG_SPACE is not defined on this platform, a workaround */ #ifndef CMSG_SPACE # ifdef _CMSG_HDR_ALIGN # define CMSG_SPACE(l) (CMSG_ALIGN(l)+_CMSG_HDR_ALIGN(sizeof(struct cmsghdr))) # else # define CMSG_SPACE(l) (CMSG_ALIGN(l)+CMSG_ALIGN(sizeof(struct cmsghdr))) # endif #endif /** The TCP reading or writing query timeout in seconds */ #define TCP_QUERY_TIMEOUT 120 #ifndef NONBLOCKING_IS_BROKEN /** number of UDP reads to perform per read indication from select */ #define NUM_UDP_PER_SELECT 100 #else #define NUM_UDP_PER_SELECT 1 #endif /* We define libevent structures here to hide the libevent stuff. */ #ifdef USE_MINI_EVENT # ifdef USE_WINSOCK # include "winsock_event.h" # else # include "mini_event.h" # endif /* USE_WINSOCK */ #else /* USE_MINI_EVENT */ /* we use libevent */ # include #endif /* USE_MINI_EVENT */ /** * The internal event structure for keeping libevent info for the event. * Possibly other structures (list, tree) this is part of. */ struct internal_event { /** the comm base */ struct comm_base* base; /** libevent event type, alloced here */ struct event ev; }; /** * Internal base structure, so that every thread has its own events. */ struct internal_base { /** libevent event_base type. */ struct event_base* base; /** seconds time pointer points here */ uint32_t secs; /** timeval with current time */ struct timeval now; }; /** * Internal timer structure, to store timer event in. */ struct internal_timer { /** the comm base */ struct comm_base* base; /** libevent event type, alloced here */ struct event ev; /** is timer enabled */ uint8_t enabled; }; /** * Internal signal structure, to store signal event in. */ struct internal_signal { /** libevent event type, alloced here */ struct event ev; /** next in signal list */ struct internal_signal* next; }; /** create a tcp handler with a parent */ static struct comm_point* comm_point_create_tcp_handler( struct comm_base *base, struct comm_point* parent, size_t bufsize, comm_point_callback_t* callback, void* callback_arg); /* -------- End of local definitions -------- */ #ifdef USE_MINI_EVENT /** minievent updates the time when it blocks. */ #define comm_base_now(x) /* nothing to do */ #else /* !USE_MINI_EVENT */ /** fillup the time values in the event base */ static void comm_base_now(struct comm_base* b) { if(gettimeofday(&b->eb->now, NULL) < 0) { log_err("gettimeofday: %s", strerror(errno)); } b->eb->secs = (uint32_t)b->eb->now.tv_sec; } #endif /* USE_MINI_EVENT */ struct comm_base* comm_base_create(int sigs) { struct comm_base* b = (struct comm_base*)calloc(1, sizeof(struct comm_base)); if(!b) return NULL; b->eb = (struct internal_base*)calloc(1, sizeof(struct internal_base)); if(!b->eb) { free(b); return NULL; } #ifdef USE_MINI_EVENT (void)sigs; /* use mini event time-sharing feature */ b->eb->base = event_init(&b->eb->secs, &b->eb->now); #else # if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP) /* libev */ if(sigs) b->eb->base=(struct event_base *)ev_default_loop(EVFLAG_AUTO); else b->eb->base=(struct event_base *)ev_loop_new(EVFLAG_AUTO); # else (void)sigs; # ifdef HAVE_EVENT_BASE_NEW b->eb->base = event_base_new(); # else b->eb->base = event_init(); # endif # endif #endif if(!b->eb->base) { free(b->eb); free(b); return NULL; } comm_base_now(b); /* avoid event_get_method call which causes crashes even when * not printing, because its result is passed */ verbose(VERB_ALGO, #if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP) "libev" #elif defined(USE_MINI_EVENT) "event " #else "libevent " #endif "%s uses %s method.", event_get_version(), #ifdef HAVE_EVENT_BASE_GET_METHOD event_base_get_method(b->eb->base) #else "not_obtainable" #endif ); return b; } void comm_base_delete(struct comm_base* b) { if(!b) return; #ifdef USE_MINI_EVENT event_base_free(b->eb->base); #elif defined(HAVE_EVENT_BASE_FREE) && defined(HAVE_EVENT_BASE_ONCE) /* only libevent 1.2+ has it, but in 1.2 it is broken - assertion fails on signal handling ev that is not deleted in libevent 1.3c (event_base_once appears) this is fixed. */ event_base_free(b->eb->base); #endif /* HAVE_EVENT_BASE_FREE and HAVE_EVENT_BASE_ONCE */ b->eb->base = NULL; free(b->eb); free(b); } void comm_base_timept(struct comm_base* b, uint32_t** tt, struct timeval** tv) { *tt = &b->eb->secs; *tv = &b->eb->now; } void comm_base_dispatch(struct comm_base* b) { int retval; retval = event_base_dispatch(b->eb->base); if(retval != 0) { fatal_exit("event_dispatch returned error %d, " "errno is %s", retval, strerror(errno)); } } void comm_base_exit(struct comm_base* b) { if(event_base_loopexit(b->eb->base, NULL) != 0) { log_err("Could not loopexit"); } } struct event_base* comm_base_internal(struct comm_base* b) { return b->eb->base; } struct event* comm_point_internal(struct comm_point* c) { return &c->ev->ev; } /** see if errno for udp has to be logged or not uses globals */ static int udp_send_errno_needs_log(struct sockaddr* addr, socklen_t addrlen) { /* do not log transient errors (unless high verbosity) */ #if defined(ENETUNREACH) || defined(EHOSTDOWN) || defined(EHOSTUNREACH) || defined(ENETDOWN) switch(errno) { # ifdef ENETUNREACH case ENETUNREACH: # endif # ifdef EHOSTDOWN case EHOSTDOWN: # endif # ifdef EHOSTUNREACH case EHOSTUNREACH: # endif # ifdef ENETDOWN case ENETDOWN: # endif if(verbosity < VERB_ALGO) return 0; default: break; } #endif /* squelch errors where people deploy AAAA ::ffff:bla for * authority servers, which we try for intranets. */ if(errno == EINVAL && addr_is_ip4mapped( (struct sockaddr_storage*)addr, addrlen) && verbosity < VERB_DETAIL) return 0; /* SO_BROADCAST sockopt can give access to 255.255.255.255, * but a dns cache does not need it. */ if(errno == EACCES && addr_is_broadcast( (struct sockaddr_storage*)addr, addrlen) && verbosity < VERB_DETAIL) return 0; return 1; } /* send a UDP reply */ int comm_point_send_udp_msg(struct comm_point *c, ldns_buffer* packet, struct sockaddr* addr, socklen_t addrlen) { ssize_t sent; log_assert(c->fd != -1); #ifdef UNBOUND_DEBUG if(ldns_buffer_remaining(packet) == 0) log_err("error: send empty UDP packet"); #endif log_assert(addr && addrlen > 0); sent = sendto(c->fd, (void*)ldns_buffer_begin(packet), ldns_buffer_remaining(packet), 0, addr, addrlen); if(sent == -1) { if(!udp_send_errno_needs_log(addr, addrlen)) return 0; #ifndef USE_WINSOCK verbose(VERB_OPS, "sendto failed: %s", strerror(errno)); #else verbose(VERB_OPS, "sendto failed: %s", wsa_strerror(WSAGetLastError())); #endif log_addr(VERB_OPS, "remote address is", (struct sockaddr_storage*)addr, addrlen); return 0; } else if((size_t)sent != ldns_buffer_remaining(packet)) { log_err("sent %d in place of %d bytes", (int)sent, (int)ldns_buffer_remaining(packet)); return 0; } return 1; } #if defined(AF_INET6) && defined(IPV6_PKTINFO) && (defined(HAVE_RECVMSG) || defined(HAVE_SENDMSG)) /** print debug ancillary info */ static void p_ancil(const char* str, struct comm_reply* r) { if(r->srctype != 4 && r->srctype != 6) { log_info("%s: unknown srctype %d", str, r->srctype); return; } if(r->srctype == 6) { char buf[1024]; if(inet_ntop(AF_INET6, &r->pktinfo.v6info.ipi6_addr, buf, (socklen_t)sizeof(buf)) == 0) { strncpy(buf, "(inet_ntop error)", sizeof(buf)); } buf[sizeof(buf)-1]=0; log_info("%s: %s %d", str, buf, r->pktinfo.v6info.ipi6_ifindex); } else if(r->srctype == 4) { #ifdef IP_PKTINFO char buf1[1024], buf2[1024]; if(inet_ntop(AF_INET, &r->pktinfo.v4info.ipi_addr, buf1, (socklen_t)sizeof(buf1)) == 0) { strncpy(buf1, "(inet_ntop error)", sizeof(buf1)); } buf1[sizeof(buf1)-1]=0; if(inet_ntop(AF_INET, &r->pktinfo.v4info.ipi_spec_dst, buf2, (socklen_t)sizeof(buf2)) == 0) { strncpy(buf2, "(inet_ntop error)", sizeof(buf2)); } buf2[sizeof(buf2)-1]=0; log_info("%s: %d %s %s", str, r->pktinfo.v4info.ipi_ifindex, buf1, buf2); #elif defined(IP_RECVDSTADDR) char buf1[1024]; if(inet_ntop(AF_INET, &r->pktinfo.v4addr, buf1, (socklen_t)sizeof(buf1)) == 0) { strncpy(buf1, "(inet_ntop error)", sizeof(buf1)); } buf1[sizeof(buf1)-1]=0; log_info("%s: %s", str, buf1); #endif /* IP_PKTINFO or PI_RECVDSTDADDR */ } } #endif /* AF_INET6 && IPV6_PKTINFO && HAVE_RECVMSG||HAVE_SENDMSG */ /** send a UDP reply over specified interface*/ static int comm_point_send_udp_msg_if(struct comm_point *c, ldns_buffer* packet, struct sockaddr* addr, socklen_t addrlen, struct comm_reply* r) { #if defined(AF_INET6) && defined(IPV6_PKTINFO) && defined(HAVE_SENDMSG) ssize_t sent; struct msghdr msg; struct iovec iov[1]; char control[256]; #ifndef S_SPLINT_S struct cmsghdr *cmsg; #endif /* S_SPLINT_S */ log_assert(c->fd != -1); #ifdef UNBOUND_DEBUG if(ldns_buffer_remaining(packet) == 0) log_err("error: send empty UDP packet"); #endif log_assert(addr && addrlen > 0); msg.msg_name = addr; msg.msg_namelen = addrlen; iov[0].iov_base = ldns_buffer_begin(packet); iov[0].iov_len = ldns_buffer_remaining(packet); msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_control = control; #ifndef S_SPLINT_S msg.msg_controllen = sizeof(control); #endif /* S_SPLINT_S */ msg.msg_flags = 0; #ifndef S_SPLINT_S cmsg = CMSG_FIRSTHDR(&msg); if(r->srctype == 4) { #ifdef IP_PKTINFO msg.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo)); log_assert(msg.msg_controllen <= sizeof(control)); cmsg->cmsg_level = IPPROTO_IP; cmsg->cmsg_type = IP_PKTINFO; memmove(CMSG_DATA(cmsg), &r->pktinfo.v4info, sizeof(struct in_pktinfo)); cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); #elif defined(IP_SENDSRCADDR) msg.msg_controllen = CMSG_SPACE(sizeof(struct in_addr)); log_assert(msg.msg_controllen <= sizeof(control)); cmsg->cmsg_level = IPPROTO_IP; cmsg->cmsg_type = IP_SENDSRCADDR; memmove(CMSG_DATA(cmsg), &r->pktinfo.v4addr, sizeof(struct in_addr)); cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); #else verbose(VERB_ALGO, "no IP_PKTINFO or IP_SENDSRCADDR"); msg.msg_control = NULL; #endif /* IP_PKTINFO or IP_SENDSRCADDR */ } else if(r->srctype == 6) { msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo)); log_assert(msg.msg_controllen <= sizeof(control)); cmsg->cmsg_level = IPPROTO_IPV6; cmsg->cmsg_type = IPV6_PKTINFO; memmove(CMSG_DATA(cmsg), &r->pktinfo.v6info, sizeof(struct in6_pktinfo)); cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); } else { /* try to pass all 0 to use default route */ msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo)); log_assert(msg.msg_controllen <= sizeof(control)); cmsg->cmsg_level = IPPROTO_IPV6; cmsg->cmsg_type = IPV6_PKTINFO; memset(CMSG_DATA(cmsg), 0, sizeof(struct in6_pktinfo)); cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); } #endif /* S_SPLINT_S */ if(verbosity >= VERB_ALGO) p_ancil("send_udp over interface", r); sent = sendmsg(c->fd, &msg, 0); if(sent == -1) { if(!udp_send_errno_needs_log(addr, addrlen)) return 0; verbose(VERB_OPS, "sendmsg failed: %s", strerror(errno)); log_addr(VERB_OPS, "remote address is", (struct sockaddr_storage*)addr, addrlen); return 0; } else if((size_t)sent != ldns_buffer_remaining(packet)) { log_err("sent %d in place of %d bytes", (int)sent, (int)ldns_buffer_remaining(packet)); return 0; } return 1; #else (void)c; (void)packet; (void)addr; (void)addrlen; (void)r; log_err("sendmsg: IPV6_PKTINFO not supported"); return 0; #endif /* AF_INET6 && IPV6_PKTINFO && HAVE_SENDMSG */ } void comm_point_udp_ancil_callback(int fd, short event, void* arg) { #if defined(AF_INET6) && defined(IPV6_PKTINFO) && defined(HAVE_RECVMSG) struct comm_reply rep; struct msghdr msg; struct iovec iov[1]; ssize_t rcv; char ancil[256]; int i; #ifndef S_SPLINT_S struct cmsghdr* cmsg; #endif /* S_SPLINT_S */ rep.c = (struct comm_point*)arg; log_assert(rep.c->type == comm_udp); if(!(event&EV_READ)) return; log_assert(rep.c && rep.c->buffer && rep.c->fd == fd); comm_base_now(rep.c->ev->base); for(i=0; ibuffer); rep.addrlen = (socklen_t)sizeof(rep.addr); log_assert(fd != -1); log_assert(ldns_buffer_remaining(rep.c->buffer) > 0); msg.msg_name = &rep.addr; msg.msg_namelen = (socklen_t)sizeof(rep.addr); iov[0].iov_base = ldns_buffer_begin(rep.c->buffer); iov[0].iov_len = ldns_buffer_remaining(rep.c->buffer); msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_control = ancil; #ifndef S_SPLINT_S msg.msg_controllen = sizeof(ancil); #endif /* S_SPLINT_S */ msg.msg_flags = 0; rcv = recvmsg(fd, &msg, 0); if(rcv == -1) { if(errno != EAGAIN && errno != EINTR) { log_err("recvmsg failed: %s", strerror(errno)); } return; } rep.addrlen = msg.msg_namelen; ldns_buffer_skip(rep.c->buffer, rcv); ldns_buffer_flip(rep.c->buffer); rep.srctype = 0; #ifndef S_SPLINT_S for(cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if( cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) { rep.srctype = 6; memmove(&rep.pktinfo.v6info, CMSG_DATA(cmsg), sizeof(struct in6_pktinfo)); break; #ifdef IP_PKTINFO } else if( cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) { rep.srctype = 4; memmove(&rep.pktinfo.v4info, CMSG_DATA(cmsg), sizeof(struct in_pktinfo)); break; #elif defined(IP_RECVDSTADDR) } else if( cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_RECVDSTADDR) { rep.srctype = 4; memmove(&rep.pktinfo.v4addr, CMSG_DATA(cmsg), sizeof(struct in_addr)); break; #endif /* IP_PKTINFO or IP_RECVDSTADDR */ } } if(verbosity >= VERB_ALGO) p_ancil("receive_udp on interface", &rep); #endif /* S_SPLINT_S */ fptr_ok(fptr_whitelist_comm_point(rep.c->callback)); if((*rep.c->callback)(rep.c, rep.c->cb_arg, NETEVENT_NOERROR, &rep)) { /* send back immediate reply */ (void)comm_point_send_udp_msg_if(rep.c, rep.c->buffer, (struct sockaddr*)&rep.addr, rep.addrlen, &rep); } if(rep.c->fd == -1) /* commpoint closed */ break; } #else (void)fd; (void)event; (void)arg; fatal_exit("recvmsg: No support for IPV6_PKTINFO. " "Please disable interface-automatic"); #endif /* AF_INET6 && IPV6_PKTINFO && HAVE_RECVMSG */ } void comm_point_udp_callback(int fd, short event, void* arg) { struct comm_reply rep; ssize_t rcv; rep.c = (struct comm_point*)arg; log_assert(rep.c->type == comm_udp); if(!(event&EV_READ)) return; log_assert(rep.c && rep.c->buffer && rep.c->fd == fd); comm_base_now(rep.c->ev->base); /* NUM UDP PER SELECT feature used to be here but removed * so that the UDP commpoint can be deleted in its callback */ { ldns_buffer_clear(rep.c->buffer); rep.addrlen = (socklen_t)sizeof(rep.addr); log_assert(fd != -1); log_assert(ldns_buffer_remaining(rep.c->buffer) > 0); rcv = recvfrom(fd, (void*)ldns_buffer_begin(rep.c->buffer), ldns_buffer_remaining(rep.c->buffer), 0, (struct sockaddr*)&rep.addr, &rep.addrlen); if(rcv == -1) { #ifndef USE_WINSOCK if(errno != EAGAIN && errno != EINTR) log_err("recvfrom %d failed: %s", fd, strerror(errno)); #else if(WSAGetLastError() != WSAEINPROGRESS && WSAGetLastError() != WSAECONNRESET && WSAGetLastError()!= WSAEWOULDBLOCK) log_err("recvfrom failed: %s", wsa_strerror(WSAGetLastError())); #endif return; } ldns_buffer_skip(rep.c->buffer, rcv); ldns_buffer_flip(rep.c->buffer); rep.srctype = 0; fptr_ok(fptr_whitelist_comm_point(rep.c->callback)); if((*rep.c->callback)(rep.c, rep.c->cb_arg, NETEVENT_NOERROR, &rep)) { /* send back immediate reply */ (void)comm_point_send_udp_msg(rep.c, rep.c->buffer, (struct sockaddr*)&rep.addr, rep.addrlen); } } } /** Use a new tcp handler for new query fd, set to read query */ static void setup_tcp_handler(struct comm_point* c, int fd) { log_assert(c->type == comm_tcp); log_assert(c->fd == -1); ldns_buffer_clear(c->buffer); c->tcp_is_reading = 1; c->tcp_byte_count = 0; comm_point_start_listening(c, fd, TCP_QUERY_TIMEOUT); } int comm_point_perform_accept(struct comm_point* c, struct sockaddr_storage* addr, socklen_t* addrlen) { int new_fd; *addrlen = (socklen_t)sizeof(*addr); new_fd = accept(c->fd, (struct sockaddr*)addr, addrlen); if(new_fd == -1) { #ifndef USE_WINSOCK /* EINTR is signal interrupt. others are closed connection. */ if( errno == EINTR || errno == EAGAIN #ifdef EWOULDBLOCK || errno == EWOULDBLOCK #endif #ifdef ECONNABORTED || errno == ECONNABORTED #endif #ifdef EPROTO || errno == EPROTO #endif /* EPROTO */ ) return -1; log_err("accept failed: %s", strerror(errno)); #else /* USE_WINSOCK */ if(WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAECONNRESET) return -1; if(WSAGetLastError() == WSAEWOULDBLOCK) { winsock_tcp_wouldblock(&c->ev->ev, EV_READ); return -1; } log_err("accept failed: %s", wsa_strerror(WSAGetLastError())); #endif log_addr(0, "remote address is", addr, *addrlen); return -1; } fd_set_nonblock(new_fd); return new_fd; } #ifdef USE_WINSOCK static long win_bio_cb(BIO *b, int oper, const char* ATTR_UNUSED(argp), int ATTR_UNUSED(argi), long argl, long retvalue) { verbose(VERB_ALGO, "bio_cb %d, %s %s %s", oper, (oper&BIO_CB_RETURN)?"return":"before", (oper&BIO_CB_READ)?"read":((oper&BIO_CB_WRITE)?"write":"other"), WSAGetLastError()==WSAEWOULDBLOCK?"wsawb":""); /* on windows, check if previous operation caused EWOULDBLOCK */ if( (oper == (BIO_CB_READ|BIO_CB_RETURN) && argl == 0) || (oper == (BIO_CB_GETS|BIO_CB_RETURN) && argl == 0)) { if(WSAGetLastError() == WSAEWOULDBLOCK) winsock_tcp_wouldblock((struct event*) BIO_get_callback_arg(b), EV_READ); } if( (oper == (BIO_CB_WRITE|BIO_CB_RETURN) && argl == 0) || (oper == (BIO_CB_PUTS|BIO_CB_RETURN) && argl == 0)) { if(WSAGetLastError() == WSAEWOULDBLOCK) winsock_tcp_wouldblock((struct event*) BIO_get_callback_arg(b), EV_WRITE); } /* return original return value */ return retvalue; } /** set win bio callbacks for nonblocking operations */ void comm_point_tcp_win_bio_cb(struct comm_point* c, void* thessl) { SSL* ssl = (SSL*)thessl; /* set them both just in case, but usually they are the same BIO */ BIO_set_callback(SSL_get_rbio(ssl), &win_bio_cb); BIO_set_callback_arg(SSL_get_rbio(ssl), (char*)comm_point_internal(c)); BIO_set_callback(SSL_get_wbio(ssl), &win_bio_cb); BIO_set_callback_arg(SSL_get_wbio(ssl), (char*)comm_point_internal(c)); } #endif void comm_point_tcp_accept_callback(int ATTR_UNUSED(fd), short event, void* arg) { struct comm_point* c = (struct comm_point*)arg, *c_hdl; int new_fd; log_assert(c->type == comm_tcp_accept); if(!(event & EV_READ)) { log_info("ignoring tcp accept event %d", (int)event); return; } comm_base_now(c->ev->base); /* find free tcp handler. */ if(!c->tcp_free) { log_warn("accepted too many tcp, connections full"); return; } /* accept incoming connection. */ c_hdl = c->tcp_free; new_fd = comm_point_perform_accept(c, &c_hdl->repinfo.addr, &c_hdl->repinfo.addrlen); if(new_fd == -1) return; if(c->ssl) { c_hdl->ssl = incoming_ssl_fd(c->ssl, new_fd); if(!c_hdl->ssl) { c_hdl->fd = new_fd; comm_point_close(c_hdl); return; } c_hdl->ssl_shake_state = comm_ssl_shake_read; #ifdef USE_WINSOCK comm_point_tcp_win_bio_cb(c_hdl, c_hdl->ssl); #endif } /* grab the tcp handler buffers */ c->tcp_free = c_hdl->tcp_free; if(!c->tcp_free) { /* stop accepting incoming queries for now. */ comm_point_stop_listening(c); } /* addr is dropped. Not needed for tcp reply. */ setup_tcp_handler(c_hdl, new_fd); } /** Make tcp handler free for next assignment */ static void reclaim_tcp_handler(struct comm_point* c) { log_assert(c->type == comm_tcp); if(c->ssl) { SSL_shutdown(c->ssl); SSL_free(c->ssl); c->ssl = NULL; } comm_point_close(c); if(c->tcp_parent) { c->tcp_free = c->tcp_parent->tcp_free; c->tcp_parent->tcp_free = c; if(!c->tcp_free) { /* re-enable listening on accept socket */ comm_point_start_listening(c->tcp_parent, -1, -1); } } } /** do the callback when writing is done */ static void tcp_callback_writer(struct comm_point* c) { log_assert(c->type == comm_tcp); ldns_buffer_clear(c->buffer); if(c->tcp_do_toggle_rw) c->tcp_is_reading = 1; c->tcp_byte_count = 0; /* switch from listening(write) to listening(read) */ comm_point_stop_listening(c); comm_point_start_listening(c, -1, -1); } /** do the callback when reading is done */ static void tcp_callback_reader(struct comm_point* c) { log_assert(c->type == comm_tcp || c->type == comm_local); ldns_buffer_flip(c->buffer); if(c->tcp_do_toggle_rw) c->tcp_is_reading = 0; c->tcp_byte_count = 0; if(c->type == comm_tcp) comm_point_stop_listening(c); fptr_ok(fptr_whitelist_comm_point(c->callback)); if( (*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, &c->repinfo) ) { comm_point_start_listening(c, -1, TCP_QUERY_TIMEOUT); } } /** continue ssl handshake */ static int ssl_handshake(struct comm_point* c) { int r; if(c->ssl_shake_state == comm_ssl_shake_hs_read) { /* read condition satisfied back to writing */ comm_point_listen_for_rw(c, 1, 1); c->ssl_shake_state = comm_ssl_shake_none; return 1; } if(c->ssl_shake_state == comm_ssl_shake_hs_write) { /* write condition satisfied, back to reading */ comm_point_listen_for_rw(c, 1, 0); c->ssl_shake_state = comm_ssl_shake_none; return 1; } ERR_clear_error(); r = SSL_do_handshake(c->ssl); if(r != 1) { int want = SSL_get_error(c->ssl, r); if(want == SSL_ERROR_WANT_READ) { if(c->ssl_shake_state == comm_ssl_shake_read) return 1; c->ssl_shake_state = comm_ssl_shake_read; comm_point_listen_for_rw(c, 1, 0); return 1; } else if(want == SSL_ERROR_WANT_WRITE) { if(c->ssl_shake_state == comm_ssl_shake_write) return 1; c->ssl_shake_state = comm_ssl_shake_write; comm_point_listen_for_rw(c, 0, 1); return 1; } else if(r == 0) { return 0; /* closed */ } else if(want == SSL_ERROR_SYSCALL) { /* SYSCALL and errno==0 means closed uncleanly */ if(errno != 0) log_err("SSL_handshake syscall: %s", strerror(errno)); return 0; } else { log_crypto_err("ssl handshake failed"); log_addr(1, "ssl handshake failed", &c->repinfo.addr, c->repinfo.addrlen); return 0; } } /* this is where peer verification could take place */ log_addr(VERB_ALGO, "SSL DNS connection", &c->repinfo.addr, c->repinfo.addrlen); /* setup listen rw correctly */ if(c->tcp_is_reading) { if(c->ssl_shake_state != comm_ssl_shake_read) comm_point_listen_for_rw(c, 1, 0); } else { comm_point_listen_for_rw(c, 1, 1); } c->ssl_shake_state = comm_ssl_shake_none; return 1; } /** ssl read callback on TCP */ static int ssl_handle_read(struct comm_point* c) { int r; if(c->ssl_shake_state != comm_ssl_shake_none) { if(!ssl_handshake(c)) return 0; if(c->ssl_shake_state != comm_ssl_shake_none) return 1; } if(c->tcp_byte_count < sizeof(uint16_t)) { /* read length bytes */ ERR_clear_error(); if((r=SSL_read(c->ssl, (void*)ldns_buffer_at(c->buffer, c->tcp_byte_count), (int)(sizeof(uint16_t) - c->tcp_byte_count))) <= 0) { int want = SSL_get_error(c->ssl, r); if(want == SSL_ERROR_ZERO_RETURN) { return 0; /* shutdown, closed */ } else if(want == SSL_ERROR_WANT_READ) { return 1; /* read more later */ } else if(want == SSL_ERROR_WANT_WRITE) { c->ssl_shake_state = comm_ssl_shake_hs_write; comm_point_listen_for_rw(c, 0, 1); return 1; } else if(want == SSL_ERROR_SYSCALL) { if(errno != 0) log_err("SSL_read syscall: %s", strerror(errno)); return 0; } log_crypto_err("could not SSL_read"); return 0; } c->tcp_byte_count += r; if(c->tcp_byte_count != sizeof(uint16_t)) return 1; if(ldns_buffer_read_u16_at(c->buffer, 0) > ldns_buffer_capacity(c->buffer)) { verbose(VERB_QUERY, "ssl: dropped larger than buffer"); return 0; } ldns_buffer_set_limit(c->buffer, ldns_buffer_read_u16_at(c->buffer, 0)); if(ldns_buffer_limit(c->buffer) < LDNS_HEADER_SIZE) { verbose(VERB_QUERY, "ssl: dropped bogus too short."); return 0; } verbose(VERB_ALGO, "Reading ssl tcp query of length %d", (int)ldns_buffer_limit(c->buffer)); } log_assert(ldns_buffer_remaining(c->buffer) > 0); ERR_clear_error(); r = SSL_read(c->ssl, (void*)ldns_buffer_current(c->buffer), (int)ldns_buffer_remaining(c->buffer)); if(r <= 0) { int want = SSL_get_error(c->ssl, r); if(want == SSL_ERROR_ZERO_RETURN) { return 0; /* shutdown, closed */ } else if(want == SSL_ERROR_WANT_READ) { return 1; /* read more later */ } else if(want == SSL_ERROR_WANT_WRITE) { c->ssl_shake_state = comm_ssl_shake_hs_write; comm_point_listen_for_rw(c, 0, 1); return 1; } else if(want == SSL_ERROR_SYSCALL) { if(errno != 0) log_err("SSL_read syscall: %s", strerror(errno)); return 0; } log_crypto_err("could not SSL_read"); return 0; } ldns_buffer_skip(c->buffer, (ssize_t)r); if(ldns_buffer_remaining(c->buffer) <= 0) { tcp_callback_reader(c); } return 1; } /** ssl write callback on TCP */ static int ssl_handle_write(struct comm_point* c) { int r; if(c->ssl_shake_state != comm_ssl_shake_none) { if(!ssl_handshake(c)) return 0; if(c->ssl_shake_state != comm_ssl_shake_none) return 1; } /* ignore return, if fails we may simply block */ (void)SSL_set_mode(c->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE); if(c->tcp_byte_count < sizeof(uint16_t)) { uint16_t len = htons(ldns_buffer_limit(c->buffer)); ERR_clear_error(); r = SSL_write(c->ssl, (void*)(((uint8_t*)&len)+c->tcp_byte_count), (int)(sizeof(uint16_t)-c->tcp_byte_count)); if(r <= 0) { int want = SSL_get_error(c->ssl, r); if(want == SSL_ERROR_ZERO_RETURN) { return 0; /* closed */ } else if(want == SSL_ERROR_WANT_READ) { c->ssl_shake_state = comm_ssl_shake_read; comm_point_listen_for_rw(c, 1, 0); return 1; /* wait for read condition */ } else if(want == SSL_ERROR_WANT_WRITE) { return 1; /* write more later */ } else if(want == SSL_ERROR_SYSCALL) { if(errno != 0) log_err("SSL_write syscall: %s", strerror(errno)); return 0; } log_crypto_err("could not SSL_write"); return 0; } c->tcp_byte_count += r; if(c->tcp_byte_count < sizeof(uint16_t)) return 1; ldns_buffer_set_position(c->buffer, c->tcp_byte_count - sizeof(uint16_t)); if(ldns_buffer_remaining(c->buffer) == 0) { tcp_callback_writer(c); return 1; } } log_assert(ldns_buffer_remaining(c->buffer) > 0); ERR_clear_error(); r = SSL_write(c->ssl, (void*)ldns_buffer_current(c->buffer), (int)ldns_buffer_remaining(c->buffer)); if(r <= 0) { int want = SSL_get_error(c->ssl, r); if(want == SSL_ERROR_ZERO_RETURN) { return 0; /* closed */ } else if(want == SSL_ERROR_WANT_READ) { c->ssl_shake_state = comm_ssl_shake_read; comm_point_listen_for_rw(c, 1, 0); return 1; /* wait for read condition */ } else if(want == SSL_ERROR_WANT_WRITE) { return 1; /* write more later */ } else if(want == SSL_ERROR_SYSCALL) { if(errno != 0) log_err("SSL_write syscall: %s", strerror(errno)); return 0; } log_crypto_err("could not SSL_write"); return 0; } ldns_buffer_skip(c->buffer, (ssize_t)r); if(ldns_buffer_remaining(c->buffer) == 0) { tcp_callback_writer(c); } return 1; } /** handle ssl tcp connection with dns contents */ static int ssl_handle_it(struct comm_point* c) { if(c->tcp_is_reading) return ssl_handle_read(c); return ssl_handle_write(c); } /** Handle tcp reading callback. * @param fd: file descriptor of socket. * @param c: comm point to read from into buffer. * @param short_ok: if true, very short packets are OK (for comm_local). * @return: 0 on error */ static int comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok) { ssize_t r; log_assert(c->type == comm_tcp || c->type == comm_local); if(c->ssl) return ssl_handle_it(c); if(!c->tcp_is_reading) return 0; log_assert(fd != -1); if(c->tcp_byte_count < sizeof(uint16_t)) { /* read length bytes */ r = recv(fd,(void*)ldns_buffer_at(c->buffer,c->tcp_byte_count), sizeof(uint16_t)-c->tcp_byte_count, 0); if(r == 0) return 0; else if(r == -1) { #ifndef USE_WINSOCK if(errno == EINTR || errno == EAGAIN) return 1; #ifdef ECONNRESET if(errno == ECONNRESET && verbosity < 2) return 0; /* silence reset by peer */ #endif log_err("read (in tcp s): %s", strerror(errno)); #else /* USE_WINSOCK */ if(WSAGetLastError() == WSAECONNRESET) return 0; if(WSAGetLastError() == WSAEINPROGRESS) return 1; if(WSAGetLastError() == WSAEWOULDBLOCK) { winsock_tcp_wouldblock(&c->ev->ev, EV_READ); return 1; } log_err("read (in tcp s): %s", wsa_strerror(WSAGetLastError())); #endif log_addr(0, "remote address is", &c->repinfo.addr, c->repinfo.addrlen); return 0; } c->tcp_byte_count += r; if(c->tcp_byte_count != sizeof(uint16_t)) return 1; if(ldns_buffer_read_u16_at(c->buffer, 0) > ldns_buffer_capacity(c->buffer)) { verbose(VERB_QUERY, "tcp: dropped larger than buffer"); return 0; } ldns_buffer_set_limit(c->buffer, ldns_buffer_read_u16_at(c->buffer, 0)); if(!short_ok && ldns_buffer_limit(c->buffer) < LDNS_HEADER_SIZE) { verbose(VERB_QUERY, "tcp: dropped bogus too short."); return 0; } verbose(VERB_ALGO, "Reading tcp query of length %d", (int)ldns_buffer_limit(c->buffer)); } log_assert(ldns_buffer_remaining(c->buffer) > 0); r = recv(fd, (void*)ldns_buffer_current(c->buffer), ldns_buffer_remaining(c->buffer), 0); if(r == 0) { return 0; } else if(r == -1) { #ifndef USE_WINSOCK if(errno == EINTR || errno == EAGAIN) return 1; log_err("read (in tcp r): %s", strerror(errno)); #else /* USE_WINSOCK */ if(WSAGetLastError() == WSAECONNRESET) return 0; if(WSAGetLastError() == WSAEINPROGRESS) return 1; if(WSAGetLastError() == WSAEWOULDBLOCK) { winsock_tcp_wouldblock(&c->ev->ev, EV_READ); return 1; } log_err("read (in tcp r): %s", wsa_strerror(WSAGetLastError())); #endif log_addr(0, "remote address is", &c->repinfo.addr, c->repinfo.addrlen); return 0; } ldns_buffer_skip(c->buffer, r); if(ldns_buffer_remaining(c->buffer) <= 0) { tcp_callback_reader(c); } return 1; } /** * Handle tcp writing callback. * @param fd: file descriptor of socket. * @param c: comm point to write buffer out of. * @return: 0 on error */ static int comm_point_tcp_handle_write(int fd, struct comm_point* c) { ssize_t r; log_assert(c->type == comm_tcp); if(c->tcp_is_reading && !c->ssl) return 0; log_assert(fd != -1); if(c->tcp_byte_count == 0 && c->tcp_check_nb_connect) { /* check for pending error from nonblocking connect */ /* from Stevens, unix network programming, vol1, 3rd ed, p450*/ int error = 0; socklen_t len = (socklen_t)sizeof(error); if(getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&error, &len) < 0){ #ifndef USE_WINSOCK error = errno; /* on solaris errno is error */ #else /* USE_WINSOCK */ error = WSAGetLastError(); #endif } #ifndef USE_WINSOCK #if defined(EINPROGRESS) && defined(EWOULDBLOCK) if(error == EINPROGRESS || error == EWOULDBLOCK) return 1; /* try again later */ else #endif if(error != 0 && verbosity < 2) return 0; /* silence lots of chatter in the logs */ else if(error != 0) { log_err("tcp connect: %s", strerror(error)); #else /* USE_WINSOCK */ /* examine error */ if(error == WSAEINPROGRESS) return 1; else if(error == WSAEWOULDBLOCK) { winsock_tcp_wouldblock(&c->ev->ev, EV_WRITE); return 1; } else if(error != 0 && verbosity < 2) return 0; else if(error != 0) { log_err("tcp connect: %s", wsa_strerror(error)); #endif /* USE_WINSOCK */ log_addr(0, "remote address is", &c->repinfo.addr, c->repinfo.addrlen); return 0; } } if(c->ssl) return ssl_handle_it(c); if(c->tcp_byte_count < sizeof(uint16_t)) { uint16_t len = htons(ldns_buffer_limit(c->buffer)); #ifdef HAVE_WRITEV struct iovec iov[2]; iov[0].iov_base = (uint8_t*)&len + c->tcp_byte_count; iov[0].iov_len = sizeof(uint16_t) - c->tcp_byte_count; iov[1].iov_base = ldns_buffer_begin(c->buffer); iov[1].iov_len = ldns_buffer_limit(c->buffer); log_assert(iov[0].iov_len > 0); log_assert(iov[1].iov_len > 0); r = writev(fd, iov, 2); #else /* HAVE_WRITEV */ r = send(fd, (void*)(((uint8_t*)&len)+c->tcp_byte_count), sizeof(uint16_t)-c->tcp_byte_count, 0); #endif /* HAVE_WRITEV */ if(r == -1) { #ifndef USE_WINSOCK #ifdef EPIPE if(errno == EPIPE && verbosity < 2) return 0; /* silence 'broken pipe' */ #endif if(errno == EINTR || errno == EAGAIN) return 1; log_err("tcp writev: %s", strerror(errno)); #else if(WSAGetLastError() == WSAENOTCONN) return 1; if(WSAGetLastError() == WSAEINPROGRESS) return 1; if(WSAGetLastError() == WSAEWOULDBLOCK) { winsock_tcp_wouldblock(&c->ev->ev, EV_WRITE); return 1; } log_err("tcp send s: %s", wsa_strerror(WSAGetLastError())); #endif log_addr(0, "remote address is", &c->repinfo.addr, c->repinfo.addrlen); return 0; } c->tcp_byte_count += r; if(c->tcp_byte_count < sizeof(uint16_t)) return 1; ldns_buffer_set_position(c->buffer, c->tcp_byte_count - sizeof(uint16_t)); if(ldns_buffer_remaining(c->buffer) == 0) { tcp_callback_writer(c); return 1; } } log_assert(ldns_buffer_remaining(c->buffer) > 0); r = send(fd, (void*)ldns_buffer_current(c->buffer), ldns_buffer_remaining(c->buffer), 0); if(r == -1) { #ifndef USE_WINSOCK if(errno == EINTR || errno == EAGAIN) return 1; log_err("tcp send r: %s", strerror(errno)); #else if(WSAGetLastError() == WSAEINPROGRESS) return 1; if(WSAGetLastError() == WSAEWOULDBLOCK) { winsock_tcp_wouldblock(&c->ev->ev, EV_WRITE); return 1; } log_err("tcp send r: %s", wsa_strerror(WSAGetLastError())); #endif log_addr(0, "remote address is", &c->repinfo.addr, c->repinfo.addrlen); return 0; } ldns_buffer_skip(c->buffer, r); if(ldns_buffer_remaining(c->buffer) == 0) { tcp_callback_writer(c); } return 1; } void comm_point_tcp_handle_callback(int fd, short event, void* arg) { struct comm_point* c = (struct comm_point*)arg; log_assert(c->type == comm_tcp); comm_base_now(c->ev->base); if(event&EV_READ) { if(!comm_point_tcp_handle_read(fd, c, 0)) { reclaim_tcp_handler(c); if(!c->tcp_do_close) { fptr_ok(fptr_whitelist_comm_point( c->callback)); (void)(*c->callback)(c, c->cb_arg, NETEVENT_CLOSED, NULL); } } return; } if(event&EV_WRITE) { if(!comm_point_tcp_handle_write(fd, c)) { reclaim_tcp_handler(c); if(!c->tcp_do_close) { fptr_ok(fptr_whitelist_comm_point( c->callback)); (void)(*c->callback)(c, c->cb_arg, NETEVENT_CLOSED, NULL); } } return; } if(event&EV_TIMEOUT) { verbose(VERB_QUERY, "tcp took too long, dropped"); reclaim_tcp_handler(c); if(!c->tcp_do_close) { fptr_ok(fptr_whitelist_comm_point(c->callback)); (void)(*c->callback)(c, c->cb_arg, NETEVENT_TIMEOUT, NULL); } return; } log_err("Ignored event %d for tcphdl.", event); } void comm_point_local_handle_callback(int fd, short event, void* arg) { struct comm_point* c = (struct comm_point*)arg; log_assert(c->type == comm_local); comm_base_now(c->ev->base); if(event&EV_READ) { if(!comm_point_tcp_handle_read(fd, c, 1)) { fptr_ok(fptr_whitelist_comm_point(c->callback)); (void)(*c->callback)(c, c->cb_arg, NETEVENT_CLOSED, NULL); } return; } log_err("Ignored event %d for localhdl.", event); } void comm_point_raw_handle_callback(int ATTR_UNUSED(fd), short event, void* arg) { struct comm_point* c = (struct comm_point*)arg; int err = NETEVENT_NOERROR; log_assert(c->type == comm_raw); comm_base_now(c->ev->base); if(event&EV_TIMEOUT) err = NETEVENT_TIMEOUT; fptr_ok(fptr_whitelist_comm_point_raw(c->callback)); (void)(*c->callback)(c, c->cb_arg, err, NULL); } struct comm_point* comm_point_create_udp(struct comm_base *base, int fd, ldns_buffer* buffer, comm_point_callback_t* callback, void* callback_arg) { struct comm_point* c = (struct comm_point*)calloc(1, sizeof(struct comm_point)); short evbits; if(!c) return NULL; c->ev = (struct internal_event*)calloc(1, sizeof(struct internal_event)); if(!c->ev) { free(c); return NULL; } c->ev->base = base; c->fd = fd; c->buffer = buffer; c->timeout = NULL; c->tcp_is_reading = 0; c->tcp_byte_count = 0; c->tcp_parent = NULL; c->max_tcp_count = 0; c->tcp_handlers = NULL; c->tcp_free = NULL; c->type = comm_udp; c->tcp_do_close = 0; c->do_not_close = 0; c->tcp_do_toggle_rw = 0; c->tcp_check_nb_connect = 0; c->inuse = 0; c->callback = callback; c->cb_arg = callback_arg; evbits = EV_READ | EV_PERSIST; /* libevent stuff */ event_set(&c->ev->ev, c->fd, evbits, comm_point_udp_callback, c); if(event_base_set(base->eb->base, &c->ev->ev) != 0) { log_err("could not baseset udp event"); comm_point_delete(c); return NULL; } if(fd!=-1 && event_add(&c->ev->ev, c->timeout) != 0 ) { log_err("could not add udp event"); comm_point_delete(c); return NULL; } return c; } struct comm_point* comm_point_create_udp_ancil(struct comm_base *base, int fd, ldns_buffer* buffer, comm_point_callback_t* callback, void* callback_arg) { struct comm_point* c = (struct comm_point*)calloc(1, sizeof(struct comm_point)); short evbits; if(!c) return NULL; c->ev = (struct internal_event*)calloc(1, sizeof(struct internal_event)); if(!c->ev) { free(c); return NULL; } c->ev->base = base; c->fd = fd; c->buffer = buffer; c->timeout = NULL; c->tcp_is_reading = 0; c->tcp_byte_count = 0; c->tcp_parent = NULL; c->max_tcp_count = 0; c->tcp_handlers = NULL; c->tcp_free = NULL; c->type = comm_udp; c->tcp_do_close = 0; c->do_not_close = 0; c->inuse = 0; c->tcp_do_toggle_rw = 0; c->tcp_check_nb_connect = 0; c->callback = callback; c->cb_arg = callback_arg; evbits = EV_READ | EV_PERSIST; /* libevent stuff */ event_set(&c->ev->ev, c->fd, evbits, comm_point_udp_ancil_callback, c); if(event_base_set(base->eb->base, &c->ev->ev) != 0) { log_err("could not baseset udp event"); comm_point_delete(c); return NULL; } if(fd!=-1 && event_add(&c->ev->ev, c->timeout) != 0 ) { log_err("could not add udp event"); comm_point_delete(c); return NULL; } return c; } static struct comm_point* comm_point_create_tcp_handler(struct comm_base *base, struct comm_point* parent, size_t bufsize, comm_point_callback_t* callback, void* callback_arg) { struct comm_point* c = (struct comm_point*)calloc(1, sizeof(struct comm_point)); short evbits; if(!c) return NULL; c->ev = (struct internal_event*)calloc(1, sizeof(struct internal_event)); if(!c->ev) { free(c); return NULL; } c->ev->base = base; c->fd = -1; c->buffer = ldns_buffer_new(bufsize); if(!c->buffer) { free(c->ev); free(c); return NULL; } c->timeout = (struct timeval*)malloc(sizeof(struct timeval)); if(!c->timeout) { ldns_buffer_free(c->buffer); free(c->ev); free(c); return NULL; } c->tcp_is_reading = 0; c->tcp_byte_count = 0; c->tcp_parent = parent; c->max_tcp_count = 0; c->tcp_handlers = NULL; c->tcp_free = NULL; c->type = comm_tcp; c->tcp_do_close = 0; c->do_not_close = 0; c->tcp_do_toggle_rw = 1; c->tcp_check_nb_connect = 0; c->repinfo.c = c; c->callback = callback; c->cb_arg = callback_arg; /* add to parent free list */ c->tcp_free = parent->tcp_free; parent->tcp_free = c; /* libevent stuff */ evbits = EV_PERSIST | EV_READ | EV_TIMEOUT; event_set(&c->ev->ev, c->fd, evbits, comm_point_tcp_handle_callback, c); if(event_base_set(base->eb->base, &c->ev->ev) != 0) { log_err("could not basetset tcphdl event"); parent->tcp_free = c->tcp_free; free(c->ev); free(c); return NULL; } return c; } struct comm_point* comm_point_create_tcp(struct comm_base *base, int fd, int num, size_t bufsize, comm_point_callback_t* callback, void* callback_arg) { struct comm_point* c = (struct comm_point*)calloc(1, sizeof(struct comm_point)); short evbits; int i; /* first allocate the TCP accept listener */ if(!c) return NULL; c->ev = (struct internal_event*)calloc(1, sizeof(struct internal_event)); if(!c->ev) { free(c); return NULL; } c->ev->base = base; c->fd = fd; c->buffer = NULL; c->timeout = NULL; c->tcp_is_reading = 0; c->tcp_byte_count = 0; c->tcp_parent = NULL; c->max_tcp_count = num; c->tcp_handlers = (struct comm_point**)calloc((size_t)num, sizeof(struct comm_point*)); if(!c->tcp_handlers) { free(c->ev); free(c); return NULL; } c->tcp_free = NULL; c->type = comm_tcp_accept; c->tcp_do_close = 0; c->do_not_close = 0; c->tcp_do_toggle_rw = 0; c->tcp_check_nb_connect = 0; c->callback = NULL; c->cb_arg = NULL; evbits = EV_READ | EV_PERSIST; /* libevent stuff */ event_set(&c->ev->ev, c->fd, evbits, comm_point_tcp_accept_callback, c); if(event_base_set(base->eb->base, &c->ev->ev) != 0 || event_add(&c->ev->ev, c->timeout) != 0 ) { log_err("could not add tcpacc event"); comm_point_delete(c); return NULL; } /* now prealloc the tcp handlers */ for(i=0; itcp_handlers[i] = comm_point_create_tcp_handler(base, c, bufsize, callback, callback_arg); if(!c->tcp_handlers[i]) { comm_point_delete(c); return NULL; } } return c; } struct comm_point* comm_point_create_tcp_out(struct comm_base *base, size_t bufsize, comm_point_callback_t* callback, void* callback_arg) { struct comm_point* c = (struct comm_point*)calloc(1, sizeof(struct comm_point)); short evbits; if(!c) return NULL; c->ev = (struct internal_event*)calloc(1, sizeof(struct internal_event)); if(!c->ev) { free(c); return NULL; } c->ev->base = base; c->fd = -1; c->buffer = ldns_buffer_new(bufsize); if(!c->buffer) { free(c->ev); free(c); return NULL; } c->timeout = NULL; c->tcp_is_reading = 0; c->tcp_byte_count = 0; c->tcp_parent = NULL; c->max_tcp_count = 0; c->tcp_handlers = NULL; c->tcp_free = NULL; c->type = comm_tcp; c->tcp_do_close = 0; c->do_not_close = 0; c->tcp_do_toggle_rw = 1; c->tcp_check_nb_connect = 1; c->repinfo.c = c; c->callback = callback; c->cb_arg = callback_arg; evbits = EV_PERSIST | EV_WRITE; event_set(&c->ev->ev, c->fd, evbits, comm_point_tcp_handle_callback, c); if(event_base_set(base->eb->base, &c->ev->ev) != 0) { log_err("could not basetset tcpout event"); ldns_buffer_free(c->buffer); free(c->ev); free(c); return NULL; } return c; } struct comm_point* comm_point_create_local(struct comm_base *base, int fd, size_t bufsize, comm_point_callback_t* callback, void* callback_arg) { struct comm_point* c = (struct comm_point*)calloc(1, sizeof(struct comm_point)); short evbits; if(!c) return NULL; c->ev = (struct internal_event*)calloc(1, sizeof(struct internal_event)); if(!c->ev) { free(c); return NULL; } c->ev->base = base; c->fd = fd; c->buffer = ldns_buffer_new(bufsize); if(!c->buffer) { free(c->ev); free(c); return NULL; } c->timeout = NULL; c->tcp_is_reading = 1; c->tcp_byte_count = 0; c->tcp_parent = NULL; c->max_tcp_count = 0; c->tcp_handlers = NULL; c->tcp_free = NULL; c->type = comm_local; c->tcp_do_close = 0; c->do_not_close = 1; c->tcp_do_toggle_rw = 0; c->tcp_check_nb_connect = 0; c->callback = callback; c->cb_arg = callback_arg; /* libevent stuff */ evbits = EV_PERSIST | EV_READ; event_set(&c->ev->ev, c->fd, evbits, comm_point_local_handle_callback, c); if(event_base_set(base->eb->base, &c->ev->ev) != 0 || event_add(&c->ev->ev, c->timeout) != 0 ) { log_err("could not add localhdl event"); free(c->ev); free(c); return NULL; } return c; } struct comm_point* comm_point_create_raw(struct comm_base* base, int fd, int writing, comm_point_callback_t* callback, void* callback_arg) { struct comm_point* c = (struct comm_point*)calloc(1, sizeof(struct comm_point)); short evbits; if(!c) return NULL; c->ev = (struct internal_event*)calloc(1, sizeof(struct internal_event)); if(!c->ev) { free(c); return NULL; } c->ev->base = base; c->fd = fd; c->buffer = NULL; c->timeout = NULL; c->tcp_is_reading = 0; c->tcp_byte_count = 0; c->tcp_parent = NULL; c->max_tcp_count = 0; c->tcp_handlers = NULL; c->tcp_free = NULL; c->type = comm_raw; c->tcp_do_close = 0; c->do_not_close = 1; c->tcp_do_toggle_rw = 0; c->tcp_check_nb_connect = 0; c->callback = callback; c->cb_arg = callback_arg; /* libevent stuff */ if(writing) evbits = EV_PERSIST | EV_WRITE; else evbits = EV_PERSIST | EV_READ; event_set(&c->ev->ev, c->fd, evbits, comm_point_raw_handle_callback, c); if(event_base_set(base->eb->base, &c->ev->ev) != 0 || event_add(&c->ev->ev, c->timeout) != 0 ) { log_err("could not add rawhdl event"); free(c->ev); free(c); return NULL; } return c; } void comm_point_close(struct comm_point* c) { if(!c) return; if(c->fd != -1) if(event_del(&c->ev->ev) != 0) { log_err("could not event_del on close"); } /* close fd after removing from event lists, or epoll.. is messed up */ if(c->fd != -1 && !c->do_not_close) { verbose(VERB_ALGO, "close fd %d", c->fd); #ifndef USE_WINSOCK close(c->fd); #else closesocket(c->fd); #endif } c->fd = -1; } void comm_point_delete(struct comm_point* c) { if(!c) return; if(c->type == comm_tcp && c->ssl) { SSL_shutdown(c->ssl); SSL_free(c->ssl); } comm_point_close(c); if(c->tcp_handlers) { int i; for(i=0; imax_tcp_count; i++) comm_point_delete(c->tcp_handlers[i]); free(c->tcp_handlers); } free(c->timeout); if(c->type == comm_tcp || c->type == comm_local) ldns_buffer_free(c->buffer); free(c->ev); free(c); } void comm_point_send_reply(struct comm_reply *repinfo) { log_assert(repinfo && repinfo->c); if(repinfo->c->type == comm_udp) { if(repinfo->srctype) comm_point_send_udp_msg_if(repinfo->c, repinfo->c->buffer, (struct sockaddr*)&repinfo->addr, repinfo->addrlen, repinfo); else comm_point_send_udp_msg(repinfo->c, repinfo->c->buffer, (struct sockaddr*)&repinfo->addr, repinfo->addrlen); } else { comm_point_start_listening(repinfo->c, -1, TCP_QUERY_TIMEOUT); } } void comm_point_drop_reply(struct comm_reply* repinfo) { if(!repinfo) return; log_assert(repinfo && repinfo->c); log_assert(repinfo->c->type != comm_tcp_accept); if(repinfo->c->type == comm_udp) return; reclaim_tcp_handler(repinfo->c); } void comm_point_stop_listening(struct comm_point* c) { verbose(VERB_ALGO, "comm point stop listening %d", c->fd); if(event_del(&c->ev->ev) != 0) { log_err("event_del error to stoplisten"); } } void comm_point_start_listening(struct comm_point* c, int newfd, int sec) { verbose(VERB_ALGO, "comm point start listening %d", c->fd==-1?newfd:c->fd); if(c->type == comm_tcp_accept && !c->tcp_free) { /* no use to start listening no free slots. */ return; } if(sec != -1 && sec != 0) { if(!c->timeout) { c->timeout = (struct timeval*)malloc(sizeof( struct timeval)); if(!c->timeout) { log_err("cpsl: malloc failed. No net read."); return; } } c->ev->ev.ev_events |= EV_TIMEOUT; #ifndef S_SPLINT_S /* splint fails on struct timeval. */ c->timeout->tv_sec = sec; c->timeout->tv_usec = 0; #endif /* S_SPLINT_S */ } if(c->type == comm_tcp) { c->ev->ev.ev_events &= ~(EV_READ|EV_WRITE); if(c->tcp_is_reading) c->ev->ev.ev_events |= EV_READ; else c->ev->ev.ev_events |= EV_WRITE; } if(newfd != -1) { if(c->fd != -1) { #ifndef USE_WINSOCK close(c->fd); #else closesocket(c->fd); #endif } c->fd = newfd; c->ev->ev.ev_fd = c->fd; } if(event_add(&c->ev->ev, sec==0?NULL:c->timeout) != 0) { log_err("event_add failed. in cpsl."); } } void comm_point_listen_for_rw(struct comm_point* c, int rd, int wr) { verbose(VERB_ALGO, "comm point listen_for_rw %d %d", c->fd, wr); if(event_del(&c->ev->ev) != 0) { log_err("event_del error to cplf"); } c->ev->ev.ev_events &= ~(EV_READ|EV_WRITE); if(rd) c->ev->ev.ev_events |= EV_READ; if(wr) c->ev->ev.ev_events |= EV_WRITE; if(event_add(&c->ev->ev, c->timeout) != 0) { log_err("event_add failed. in cplf."); } } size_t comm_point_get_mem(struct comm_point* c) { size_t s; if(!c) return 0; s = sizeof(*c) + sizeof(*c->ev); if(c->timeout) s += sizeof(*c->timeout); if(c->type == comm_tcp || c->type == comm_local) s += sizeof(*c->buffer) + ldns_buffer_capacity(c->buffer); if(c->type == comm_tcp_accept) { int i; for(i=0; imax_tcp_count; i++) s += comm_point_get_mem(c->tcp_handlers[i]); } return s; } struct comm_timer* comm_timer_create(struct comm_base* base, void (*cb)(void*), void* cb_arg) { struct comm_timer *tm = (struct comm_timer*)calloc(1, sizeof(struct comm_timer)); if(!tm) return NULL; tm->ev_timer = (struct internal_timer*)calloc(1, sizeof(struct internal_timer)); if(!tm->ev_timer) { log_err("malloc failed"); free(tm); return NULL; } tm->ev_timer->base = base; tm->callback = cb; tm->cb_arg = cb_arg; event_set(&tm->ev_timer->ev, -1, EV_TIMEOUT, comm_timer_callback, tm); if(event_base_set(base->eb->base, &tm->ev_timer->ev) != 0) { log_err("timer_create: event_base_set failed."); free(tm->ev_timer); free(tm); return NULL; } return tm; } void comm_timer_disable(struct comm_timer* timer) { if(!timer) return; evtimer_del(&timer->ev_timer->ev); timer->ev_timer->enabled = 0; } void comm_timer_set(struct comm_timer* timer, struct timeval* tv) { log_assert(tv); if(timer->ev_timer->enabled) comm_timer_disable(timer); event_set(&timer->ev_timer->ev, -1, EV_TIMEOUT, comm_timer_callback, timer); if(event_base_set(timer->ev_timer->base->eb->base, &timer->ev_timer->ev) != 0) log_err("comm_timer_set: set_base failed."); if(evtimer_add(&timer->ev_timer->ev, tv) != 0) log_err("comm_timer_set: evtimer_add failed."); timer->ev_timer->enabled = 1; } void comm_timer_delete(struct comm_timer* timer) { if(!timer) return; comm_timer_disable(timer); free(timer->ev_timer); free(timer); } void comm_timer_callback(int ATTR_UNUSED(fd), short event, void* arg) { struct comm_timer* tm = (struct comm_timer*)arg; if(!(event&EV_TIMEOUT)) return; comm_base_now(tm->ev_timer->base); tm->ev_timer->enabled = 0; fptr_ok(fptr_whitelist_comm_timer(tm->callback)); (*tm->callback)(tm->cb_arg); } int comm_timer_is_set(struct comm_timer* timer) { return (int)timer->ev_timer->enabled; } size_t comm_timer_get_mem(struct comm_timer* timer) { return sizeof(*timer) + sizeof(struct internal_timer); } struct comm_signal* comm_signal_create(struct comm_base* base, void (*callback)(int, void*), void* cb_arg) { struct comm_signal* com = (struct comm_signal*)malloc( sizeof(struct comm_signal)); if(!com) { log_err("malloc failed"); return NULL; } com->base = base; com->callback = callback; com->cb_arg = cb_arg; com->ev_signal = NULL; return com; } void comm_signal_callback(int sig, short event, void* arg) { struct comm_signal* comsig = (struct comm_signal*)arg; if(!(event & EV_SIGNAL)) return; comm_base_now(comsig->base); fptr_ok(fptr_whitelist_comm_signal(comsig->callback)); (*comsig->callback)(sig, comsig->cb_arg); } int comm_signal_bind(struct comm_signal* comsig, int sig) { struct internal_signal* entry = (struct internal_signal*)calloc(1, sizeof(struct internal_signal)); if(!entry) { log_err("malloc failed"); return 0; } log_assert(comsig); /* add signal event */ signal_set(&entry->ev, sig, comm_signal_callback, comsig); if(event_base_set(comsig->base->eb->base, &entry->ev) != 0) { log_err("Could not set signal base"); free(entry); return 0; } if(signal_add(&entry->ev, NULL) != 0) { log_err("Could not add signal handler"); free(entry); return 0; } /* link into list */ entry->next = comsig->ev_signal; comsig->ev_signal = entry; return 1; } void comm_signal_delete(struct comm_signal* comsig) { struct internal_signal* p, *np; if(!comsig) return; p=comsig->ev_signal; while(p) { np = p->next; signal_del(&p->ev); free(p); p = np; } free(comsig); } dnssec-trigger-0.13/riggerd/probe.h0000664000175000017500000001246112275162157016732 0ustar wouterwouter/* * probe.h - dnssec-trigger DNSSEC probes * * Copyright (c) 2011, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains the probe definition. */ #ifndef PROBE_H #define PROBE_H struct comm_point; struct comm_reply; struct http_get; struct http_fetch; struct outq; struct svr; /** * probe structure that contains the probe details for one IP address. */ struct probe_ip { struct probe_ip* next; /* the IP address probed */ char* name; /* to authority? */ int to_auth; /* for dnstcp? */ int dnstcp; /* for ssl? */ struct ssllist* ssldns; /* is this a http probe */ int to_http; /* is http on ipv6 (or v4)? */ int http_ip6; /* destination port */ int port; /* the ssl context (if any) for this destination address */ void* sslctx; /* DS query, or NULL if done */ struct outq* ds_c; /* DNSKEY query, or NULL if done */ struct outq* dnskey_c; /* nodata query probes NSEC3, or NULL if done or not used */ struct outq* nsec3_c; /* A,AAAA query to resolve http hostname, or NULL if done or not used*/ struct outq* host_c; /* http query in progress */ struct http_get* http; /* desc of http (available even when done and http is NULL) */ char* http_desc; /* if probe has finished */ int finished; /* result for this IP, true if DNSSEC OK */ int works; /* string with explanation of failure */ char* reason; /* if a packet has been received by a query (i.e. network is up) */ int got_packet; }; /** outstanding query */ struct outq { struct sockaddr_storage addr; socklen_t addrlen; uint16_t qid; uint16_t qtype; int recurse; /* if true: recursive probe */ const char* qname; /* reference to a static string */ int timeout; /* in msec */ int on_tcp; /* if we are using TCP */ int on_ssl; /* if we are using SSL */ int port; /* port number (mostly 53) */ int edns; /* if edns yes */ int cdflag; /* if CD flag on query */ struct comm_point* c; struct comm_timer* timer; struct probe_ip* probe; /* reference only to owner */ }; #define QUERY_START_TIMEOUT 100 /* msec */ #define QUERY_END_TIMEOUT 1000 /* msec */ #define QUERY_TCP_TIMEOUT 3000 /* msec */ /** start the probe process for a new set of IPs. * in a string, with whitespace in between * the string may be altered. */ void probe_start(char* ips); /** delete and stop probe */ void probe_delete(struct probe_ip* p); /** probe list delete */ void probe_list_delete(struct probe_ip* list); /** handle probe results */ int outq_handle_udp(struct comm_point* c, void* my_arg, int error, struct comm_reply *reply_info); int outq_handle_tcp(struct comm_point* c, void* my_arg, int error, struct comm_reply *reply_info); /** outstanding query UDP timeout handler */ void outq_timeout(void* arg); void probe_cache_done(void); void probe_all_done(void); void probe_unsafe_test(void); void probe_tcp_test(void); void probe_http_test(void); void probe_ssl_test(void); void probe_setup_cache(struct svr* svr, struct probe_ip* p); void probe_setup_hotspot_signon(struct svr* svr); void probe_setup_dnstcp(struct svr* svr); /** true if probe is a cache IP, a DNS server from the DHCP hook */ int probe_is_cache(struct probe_ip* p); /** Create new outgoing query: * @param ip: server to send to (IP4 or IP6 string). * @param tp: rr type * @param domain: domain name in text format. * @param recurse: +RD flag or not. * @param p: parent pointer. * @param tcp: false for UDP, true for TCP * @param onssl: if true, (and TCP) uses SSL wrap. * @param port: port number for query * @param edns: if true, DO flag set. * @param cdflag: if true, CD flag set. * @return new outq or out of memory. */ struct outq* outq_create(const char* ip, int tp, const char* domain, int recurse, struct probe_ip* p, int tcp, int onssl, int port, int edns, int cdflag); /* delete and stop outq */ void outq_delete(struct outq* outq); #endif /* PROBE_H */ dnssec-trigger-0.13/riggerd/log.h0000664000175000017500000001314612275162157016405 0ustar wouterwouter/* * util/log.h - logging service * * Copyright (c) 2007, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains logging functions. */ #ifndef UTIL_LOG_H #define UTIL_LOG_H /** * verbosity value: */ enum verbosity_value { /** 0 - no verbose messages */ NO_VERBOSE = 0, /** 1 - operational information */ VERB_OPS, /** 2 - detailed information */ VERB_DETAIL, /** 3 - query level information */ VERB_QUERY, /** 4 - algorithm level information */ VERB_ALGO, /** 5 - querier client information */ VERB_CLIENT }; /** The global verbosity setting */ extern enum verbosity_value verbosity; /** * log a verbose message, pass the level for this message. * It has printf formatted arguments. No trailing newline is needed. * @param level: verbosity level for this message, compared to global * verbosity setting. * @param format: printf-style format string. Arguments follow. */ void verbose(enum verbosity_value level, const char* format, ...) ATTR_FORMAT(printf, 2, 3); /** * call this to initialize logging services. * @param filename: if NULL stderr is used. * @param use_syslog: set to true to ignore filename and use syslog(3). * @param chrootdir: to which directory we have been chrooted, if any. */ void log_init(const char* filename, int use_syslog, const char* chrootdir); /** * Set logging to go to the specified file *. * This setting does not affect the use_syslog setting. * @param f: to that file, or pass NULL to disable logging. */ void log_file(FILE *f); /** * Set identity to print, default is 'unbound'. * @param id: string to print. Name of executable. */ void log_ident_set(const char* id); /** * Set the time value to print in log entries. * @param t: the point is copied and used to find the time. * if NULL, time(2) is used. */ void log_set_time(uint32_t* t); /** * Set if the time value is printed ascii or decimal in log entries. * @param use_asc: if true, ascii is printed, otherwise decimal. * If the conversion fails or you have no time functions, * decimal is printed. */ void log_set_time_asc(int use_asc); /** * Log informational message. * Pass printf formatted arguments. No trailing newline is needed. * @param format: printf-style format string. Arguments follow. */ void log_info(const char* format, ...) ATTR_FORMAT(printf, 1, 2); /** * Log error message. * Pass printf formatted arguments. No trailing newline is needed. * @param format: printf-style format string. Arguments follow. */ void log_err(const char* format, ...) ATTR_FORMAT(printf, 1, 2); /** * Log warning message. * Pass printf formatted arguments. No trailing newline is needed. * @param format: printf-style format string. Arguments follow. */ void log_warn(const char* format, ...) ATTR_FORMAT(printf, 1, 2); /** * Log a hex-string to the log. Can be any length. * performs mallocs to do so, slow. But debug useful. * @param msg: string desc to accompany the hexdump. * @param data: data to dump in hex format. * @param length: length of data. */ void log_hex(const char* msg, void* data, size_t length); /** * Log fatal error message, and exit the current process. * Pass printf formatted arguments. No trailing newline is needed. * @param format: printf-style format string. Arguments follow. */ void fatal_exit(const char* format, ...) ATTR_FORMAT(printf, 1, 2); /** * va_list argument version of log_info. * @param pri: priority type, for example 5 (INFO). * @param type: string to designate type of message (info, error). * @param format: the printf style format to print. no newline. * @param args: arguments for format string. */ void log_vmsg(int pri, const char* type, const char* format, va_list args); /** * an assertion that is thrown to the logfile. */ #ifdef UNBOUND_DEBUG # define log_assert(x) \ do { if(!(x)) \ fatal_exit("%s:%d: %s: assertion %s failed", \ __FILE__, __LINE__, __func__, #x); \ } while(0); #else # define log_assert(x) /*nothing*/ #endif #ifdef USE_WINSOCK /** * Convert WSA error into string. * @param err: from WSAGetLastError() * @return: string. */ char* wsa_strerror(DWORD err); #endif /* USE_WINSOCK */ #endif /* UTIL_LOG_H */ dnssec-trigger-0.13/riggerd/cfg.c0000664000175000017500000004010412275162157016350 0ustar wouterwouter/* * cfg.c - dnssec-trigger config * * Copyright (c) 2011, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains config file options implementation. */ #include "config.h" #include "cfg.h" #include "log.h" #include "net_help.h" #include /** append to strlist */ void strlist_append(struct strlist** first, struct strlist** last, char* str) { struct strlist* e = (struct strlist*)malloc(sizeof(*e)); if(!e) fatal_exit("out of memory"); e->next = NULL; e->str = strdup(str); if(!e->str) fatal_exit("out of memory"); if(*last) (*last)->next = e; else *first = e; *last = e; } /** append to strlist2 */ void strlist2_append(struct strlist2** first, struct strlist2** last, char* s, char* t) { struct strlist2* e = (struct strlist2*)malloc(sizeof(*e)); if(!e) fatal_exit("out of memory"); e->next = NULL; if(!s || !t) fatal_exit("parse error in url statement: %s %s", s?s:"", t?t:""); e->str1 = strdup(s); e->str2 = strdup(t); if(!e->str1 || !e->str2) fatal_exit("out of memory"); if(*last) (*last)->next = e; else *first = e; *last = e; } /** free strlist */ void strlist_delete(struct strlist* e) { struct strlist* p = e, *np; while(p) { np = p->next; free(p->str); free(p); p = np; } } /** free strlist2 */ void strlist2_delete(struct strlist2* e) { struct strlist2* p = e, *np; while(p) { np = p->next; free(p->str1); free(p->str2); free(p); p = np; } } /** append to ssllist */ void ssllist_append(struct ssllist** first, struct ssllist** last, struct ssllist* e) { e->next = NULL; if(*last) (*last)->next = e; else *first = e; *last = e; } /** prepend to hashlist */ void hashlist_prepend(struct hashlist** first, unsigned char* hash, unsigned int len) { struct hashlist* e = (struct hashlist*)calloc(1, sizeof(*e)); if(!e) fatal_exit("out of memory"); memmove(e->hash, hash, len); e->hashlen = len; e->next = *first; *first = e; } /** free hashlist */ void hashlist_delete(struct hashlist* e) { struct hashlist* p = e, *np; while(p) { np = p->next; free(p); p = np; } } /** free ssllist */ void ssllist_delete(struct ssllist* e) { struct ssllist* p = e, *np; while(p) { np = p->next; hashlist_delete(p->hashes); free(p->str); free(p); p = np; } } /** get arg in line */ static char* get_arg(char* line) { while(isspace(line[0])) line++; while(strlen(line) > 0 && isspace(line[strlen(line)-1])) line[strlen(line)-1] = 0; if(strlen(line) > 1 && line[0]=='"' && line[strlen(line)-1]=='"') { line++; line[strlen(line)-1] = 0; } else if(strlen(line) > 1 && line[0]=='\'' && line[strlen(line)-1]=='\'') { line++; line[strlen(line)-1] = 0; } return line; } /** get two arguments from the line */ static void get_arg2(char* line, char** a1, char** a2) { char* sp = strchr(line, ' '); if(!sp) { *a1 = line; *a2 = NULL; return; } *a1 = line; *sp = 0; *a2 = sp+1; } /** strdup the argument on the line */ static void str_arg(char** dest, char* line) { char* s = strdup(get_arg(line)); if(!s) fatal_exit("out of memory"); free(*dest); *dest = s; } /** strdup the two arguments on the line */ static void str2_arg(struct strlist2** first, struct strlist2** last, int* num, char* line) { char* s, *t; get_arg2(line, &s, &t); strlist2_append(first, last, s, t); (*num)++; } /** append the argument on the line */ static void tcp_arg(struct strlist** first4, struct strlist** last4, int* num4, struct strlist** first6, struct strlist** last6, int* num6, char* line) { struct sockaddr_storage addr; socklen_t len; line = get_arg(line); if(line[0] == 0) return; /* ignore empty ones */ if(!ipstrtoaddr(line, DNS_PORT, &addr, &len)) { log_err("cannot parse IP address: '%s', ignored", line); return; } if(strchr(line, ':')) { strlist_append(first6, last6, line); (*num6) ++; } else { strlist_append(first4, last4, line); (*num4) ++; } } static int read_hash(char* arg, struct ssllist* e) { int i; const int len = 32; unsigned char hash[64]; char* at = arg; log_assert(arg && arg[0]); if((int)strlen(arg) != len*3-1) {/* sha256, 32bytes of xx:xx:xx:xx */ return 0; } log_assert(len <= (int)sizeof(hash)); for(i=0; ihashes, hash, (unsigned int)len); return 1; } /** add a number of hashes */ static int add_hashes(char* str, struct ssllist* e) { char* arg1, *arg2; /* skip whitespace */ while(str && isspace(*str)) str++; while(str && *str) { get_arg2(str, &arg1, &arg2); /* there must be a hash here */ if(!read_hash(arg1, e)) return 0; str = arg2; /* skip whitespace */ while(str && isspace(*str)) str++; } return 1; } /** append the argument on the line */ static void ssl_arg(struct ssllist** first4, struct ssllist** last4, int* num4, struct ssllist** first6, struct ssllist** last6, int* num6, char* line) { struct sockaddr_storage addr; socklen_t len; struct ssllist* e; char* arg1=NULL, *arg2=NULL; line = get_arg(line); if(line[0] == 0) return; /* ignore empty ones */ e = (struct ssllist*)calloc(1, sizeof(*e)); if(!e) fatal_exit("out of memory"); get_arg2(line, &arg1, &arg2); if(!ipstrtoaddr(arg1, DNS_PORT, &addr, &len)) { log_err("cannot parse IP address: '%s', ssl ignored", arg1); free(e); return; } e->str = strdup(arg1); if(!e->str) fatal_exit("out of memory"); if(!add_hashes(arg2, e)) { log_err("cannot parse hash: '%s', ssl ignored", arg2); free(e); return; } if(strchr(arg1, ':')) { ssllist_append(first6, last6, e); (*num6) ++; } else { ssllist_append(first4, last4, e); (*num4) ++; } } /** handle bool arg */ static void bool_arg(int* dest, char* line) { line = get_arg(line); if(strcmp(line, "yes") != 0 && strcmp(line, "no") != 0) { fatal_exit("expected yes or no, but got %s", line); } *dest = (strcmp(line, "yes")==0); } /** read keyword and put into cfg */ static int keyword(struct cfg* cfg, char* p) { if(strncmp(p, "verbosity:", 10) == 0) { cfg->verbosity = atoi(get_arg(p+10)); } else if(strncmp(p, "pidfile:", 8) == 0) { str_arg(&cfg->pidfile, p+8); } else if(strncmp(p, "logfile:", 8) == 0) { str_arg(&cfg->logfile, p+8); cfg->use_syslog = 0; } else if(strncmp(p, "use-syslog:", 11) == 0) { bool_arg(&cfg->use_syslog, p+11); } else if(strncmp(p, "chroot:", 7) == 0) { str_arg(&cfg->chroot, p+7); } else if(strncmp(p, "unbound-control:", 16) == 0) { str_arg(&cfg->unbound_control, p+16); } else if(strncmp(p, "resolvconf:", 11) == 0) { str_arg(&cfg->resolvconf, p+11); } else if(strncmp(p, "domain:", 7) == 0) { str_arg(&cfg->rescf_domain, p+7); } else if(strncmp(p, "search:", 7) == 0) { str_arg(&cfg->rescf_search, p+7); } else if(strncmp(p, "login-command:", 14) == 0) { str_arg(&cfg->login_command, p+14); } else if(strncmp(p, "login-location:", 15) == 0) { str_arg(&cfg->login_location, p+15); } else if(strncmp(p, "noaction:", 9) == 0) { bool_arg(&cfg->noaction, p+9); } else if(strncmp(p, "port:", 5) == 0) { cfg->control_port = atoi(get_arg(p+5)); } else if(strncmp(p, "server-key-file:", 16) == 0) { str_arg(&cfg->server_key_file, p+16); } else if(strncmp(p, "server-cert-file:", 17) == 0) { str_arg(&cfg->server_cert_file, p+17); } else if(strncmp(p, "control-key-file:", 17) == 0) { str_arg(&cfg->control_key_file, p+17); } else if(strncmp(p, "control-cert-file:", 18) == 0) { str_arg(&cfg->control_cert_file, p+18); } else if(strncmp(p, "tcp80:", 6) == 0) { tcp_arg(&cfg->tcp80_ip4, &cfg->tcp80_ip4_last, &cfg->num_tcp80_ip4, &cfg->tcp80_ip6, &cfg->tcp80_ip6_last, &cfg->num_tcp80_ip6, p+6); } else if(strncmp(p, "tcp443:", 7) == 0) { tcp_arg(&cfg->tcp443_ip4, &cfg->tcp443_ip4_last, &cfg->num_tcp443_ip4, &cfg->tcp443_ip6, &cfg->tcp443_ip6_last, &cfg->num_tcp443_ip6, p+7); } else if(strncmp(p, "ssl443:", 7) == 0) { ssl_arg(&cfg->ssl443_ip4, &cfg->ssl443_ip4_last, &cfg->num_ssl443_ip4, &cfg->ssl443_ip6, &cfg->ssl443_ip6_last, &cfg->num_ssl443_ip6, p+7); } else if(strncmp(p, "url:", 4) == 0) { str2_arg(&cfg->http_urls, &cfg->http_urls_last, &cfg->num_http_urls, get_arg(p+4)); } else if(strncmp(p, "check-updates:", 14) == 0) { bool_arg(&cfg->check_updates, p+14); } else { return 0; } return 1; } static void attempt_readfile(struct cfg* cfg, const char* file) { FILE* in = fopen(file, "r"); int line = 0; char buf[1024]; if(!in) { if(errno == ENOENT) { verbose(VERB_OPS, "no config file, using defaults"); return; } log_err("%s: %s", file, strerror(errno)); return; } while(fgets(buf, (int)sizeof(buf), in)) { char* p = buf; line++; /* whitespace at start of line */ while(isspace(*p)) p++; /* comment */ if(p[0] == '#' || p[0] == ';' || p[0] == 0) continue; /* keyword */ if(!keyword(cfg, p)) { log_err("cannot read %s:%d %s", file, line, p); exit(1); } } fclose(in); } struct cfg* cfg_create(const char* cfgfile) { struct cfg* cfg = (struct cfg*)calloc(1, sizeof(*cfg)); if(!cfg) return NULL; cfg->use_syslog = 1; cfg->control_port = 8955; cfg->server_key_file=strdup(KEYDIR"/dnssec_trigger_server.key"); cfg->server_cert_file=strdup(KEYDIR"/dnssec_trigger_server.pem"); cfg->control_key_file=strdup(KEYDIR"/dnssec_trigger_control.key"); cfg->control_cert_file=strdup(KEYDIR"/dnssec_trigger_control.pem"); cfg->unbound_control = strdup(UNBOUND_CONTROL); cfg->login_command = strdup(LOGIN_COMMAND); cfg->login_location = strdup(LOGIN_LOCATION); cfg->pidfile = strdup(PIDFILE); cfg->resolvconf = strdup("/etc/resolv.conf"); cfg->check_updates = (strcmp(CHECK_UPDATES, "yes")==0); if(!cfg->unbound_control || !cfg->pidfile || !cfg->server_key_file || !cfg->server_cert_file || !cfg->control_key_file || !cfg->control_cert_file || !cfg->resolvconf || !cfg->login_command || !cfg->login_location) { cfg_delete(cfg); return NULL; } attempt_readfile(cfg, cfgfile); /* apply */ verbosity = cfg->verbosity; return cfg; } void cfg_delete(struct cfg* cfg) { if(!cfg) return; strlist_delete(cfg->tcp80_ip4); strlist_delete(cfg->tcp80_ip6); strlist_delete(cfg->tcp443_ip4); strlist_delete(cfg->tcp443_ip6); ssllist_delete(cfg->ssl443_ip4); ssllist_delete(cfg->ssl443_ip6); strlist2_delete(cfg->http_urls); free(cfg->login_command); free(cfg->login_location); free(cfg->pidfile); free(cfg->logfile); free(cfg->chroot); free(cfg->unbound_control); free(cfg->resolvconf); free(cfg->rescf_domain); free(cfg->rescf_search); free(cfg->server_key_file); free(cfg->server_cert_file); free(cfg->control_key_file); free(cfg->control_cert_file); free(cfg); } int cfg_have_dnstcp(struct cfg* cfg) { return cfg->num_tcp80_ip4 || cfg->num_tcp80_ip6 || cfg->num_tcp443_ip4 || cfg->num_tcp443_ip6; } int cfg_have_ssldns(struct cfg* cfg) { return cfg->num_ssl443_ip4 || cfg->num_ssl443_ip6; } /** find nth element in strlist */ char* strlist_get_num(struct strlist* list, unsigned n) { unsigned i = 0; while(list) { if(i==n) return list->str; list = list->next; i++; } return NULL; } /** find nth element in ssllist */ struct ssllist* ssllist_get_num(struct ssllist* list, unsigned n) { unsigned i = 0; while(list) { if(i==n) return list; list = list->next; i++; } return NULL; } /** give errors and return NULL */ static SSL_CTX* ctx_err_ret(SSL_CTX* ctx, char* err, size_t errlen, const char* msg) { char sslerr[512]; sslerr[0]=0; ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr)); snprintf(err, errlen, "%s %s", msg, sslerr); if(ctx) SSL_CTX_free(ctx); return NULL; } /** give errors and return NULL */ static SSL* ssl_err_ret(SSL* ssl, char* err, size_t errlen, const char* msg) { (void)ctx_err_ret(NULL, err, errlen, msg); if(ssl) SSL_free(ssl); return NULL; } /** setup SSL context */ SSL_CTX* cfg_setup_ctx_client(struct cfg* cfg, char* err, size_t errlen) { char* s_cert, *c_key, *c_cert; SSL_CTX* ctx; s_cert = cfg->server_cert_file; c_key = cfg->control_key_file; c_cert = cfg->control_cert_file; ctx = SSL_CTX_new(SSLv23_client_method()); if(!ctx) return ctx_err_ret(ctx, err, errlen, "could not allocate SSL_CTX pointer"); if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)) return ctx_err_ret(ctx, err, errlen, "could not set SSL_OP_NO_SSLv2"); if(!SSL_CTX_use_certificate_file(ctx,c_cert,SSL_FILETYPE_PEM) || !SSL_CTX_use_PrivateKey_file(ctx,c_key,SSL_FILETYPE_PEM) || !SSL_CTX_check_private_key(ctx)) return ctx_err_ret(ctx, err, errlen, "Error setting up SSL_CTX client key and cert"); if (SSL_CTX_load_verify_locations(ctx, s_cert, NULL) != 1) return ctx_err_ret(ctx, err, errlen, "Error setting up SSL_CTX verify, server cert"); SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); return ctx; } /** setup SSL on the connection, blocking, or NULL and string in err */ SSL* setup_ssl_client(SSL_CTX* ctx, int fd, char* err, size_t errlen) { SSL* ssl; X509* x; int r; ssl = SSL_new(ctx); if(!ssl) return ssl_err_ret(ssl, err, errlen, "could not SSL_new"); SSL_set_connect_state(ssl); (void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); if(!SSL_set_fd(ssl, fd)) return ssl_err_ret(ssl, err, errlen, "could not SSL_set_fd"); while(1) { ERR_clear_error(); if( (r=SSL_do_handshake(ssl)) == 1) break; r = SSL_get_error(ssl, r); if(r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE) return ssl_err_ret(ssl, err, errlen, "SSL handshake failed"); /* wants to be called again */ } /* check authenticity of server */ if(SSL_get_verify_result(ssl) != X509_V_OK) return ssl_err_ret(ssl, err, errlen, "SSL verification failed"); x = SSL_get_peer_certificate(ssl); if(!x) return ssl_err_ret(ssl, err, errlen, "Server presented no peer certificate"); X509_free(x); return ssl; } #ifdef UB_ON_WINDOWS char* w_lookup_reg_str(const char* key, const char* name) { HKEY hk = NULL; DWORD type = 0; BYTE buf[1024]; DWORD len = (DWORD)sizeof(buf); LONG ret; char* result = NULL; ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hk); if(ret == ERROR_FILE_NOT_FOUND) return NULL; /* key does not exist */ else if(ret != ERROR_SUCCESS) { log_err("RegOpenKeyEx failed"); return NULL; } ret = RegQueryValueEx(hk, (LPCTSTR)name, 0, &type, buf, &len); if(RegCloseKey(hk)) log_err("RegCloseKey"); if(ret == ERROR_FILE_NOT_FOUND) return NULL; /* name does not exist */ else if(ret != ERROR_SUCCESS) { log_err("RegQueryValueEx failed"); return NULL; } if(type == REG_SZ || type == REG_MULTI_SZ || type == REG_EXPAND_SZ) { buf[sizeof(buf)-1] = 0; buf[sizeof(buf)-2] = 0; /* for multi_sz */ result = strdup((char*)buf); if(!result) log_err("out of memory"); } return result; } #endif /* UB_ON_WINDOWS */ dnssec-trigger-0.13/riggerd/riggerd.c0000664000175000017500000002372713017046554017245 0ustar wouterwouter/* * riggerd/riggerd.c - implementation of dnssec-trigger daemon * * Copyright (c) 2011, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * Implementation of dnssec-trigger daemon. */ #include "config.h" #include "log.h" #include "cfg.h" #include "svr.h" #include "reshook.h" #include "netevent.h" #ifdef HAVE_GETOPT_H #include #endif #include #include #ifdef HAVE_OPENSSL_ENGINE_H #include #endif #ifdef HAVE_OPENSSL_CONF_H #include #endif #ifdef USE_WINSOCK #include "winrc/netlist.h" #include "winrc/win_svc.h" #endif #ifdef HOOKS_OSX #include "osx/wakelist.h" #endif /** print usage text */ static void usage(void) { printf("usage: dnssec-triggerd [options]\n"); printf(" -h this help\n"); printf(" -v increase verbosity\n"); printf(" -d do not fork into the background\n"); printf(" -c file config file, default %s\n", CONFIGFILE); printf(" -u uninstall the dns override on the system\n"); printf(" makes resolv.conf mutable again.\n"); #ifdef USE_WINSOCK printf("-w opt windows option: \n"); printf(" install, remove, start, stop - manage the service\n"); printf(" waitstop - wait for svc to stop (-c servicename)\n"); printf(" service - used to start from services control panel\n"); #endif } /** variable to signal if we need to reload */ static sig_atomic_t sig_reload = 0; /** sighandler. Since we must have one * * @param sig: signal number. * * @return signal handler return type (void or int). * */ static RETSIGTYPE record_sigh(int sig) { switch(sig) { #if defined(SIGCHLD) && defined(HOOKS_OSX) case SIGCHLD: if(1) { int status = 0; pid_t p; /* waitpid for the ended process we forked at start, * so that it does not turn into a zombie */ while( (p=waitpid(-1, &status, WNOHANG)) > 0) { verbose(VERB_ALGO, "child proc %d exited %d", (int)p, (int)WEXITSTATUS(status)); } if(p == -1 && errno != ECHILD) log_err("waitpid: %s", strerror(errno)); } break; #endif #ifdef SIGHUP case SIGHUP: sig_reload = 1; /* fall through and exit commbase with reload boolean set */ #endif case SIGTERM: #ifdef SIGQUIT case SIGQUIT: #endif #ifdef SIGBREAK case SIGBREAK: #endif case SIGINT: if(global_svr) comm_base_exit(global_svr->base); else fatal_exit("killed by signal %d", (int)sig); break; #ifdef SIGPIPE case SIGPIPE: break; #endif default: log_err("ignoring signal %d", sig); } } #ifdef HOOKS_OSX static void osx_probe_hook(void) { int s; pid_t pid = fork(); switch(pid) { default: /* main */ return; case -1: /* error */ log_err("cannot fork: %s", strerror(errno)); return; case 0: /* child */ break; } /* same value as in script - cause reprobe */ unlink("/tmp/dnssec-trigger-osx.tmp"); if((s=system(LIBEXEC_DIR"/dnssec-trigger-osx.sh")) == -1) log_err("cannot exec dnssec-trigger hook osx %s", strerror(errno)); else exit (WEXITSTATUS(s)); exit (0); } #endif /* HOOKS_OSX */ /** store pid in pidfile */ static void store_pid(char* pidfile) { FILE* f; if(!pidfile || pidfile[0]==0) return; f = fopen(pidfile, "w"); if(!f) fatal_exit("could not write pid %s: %s", pidfile, strerror(errno)); if(fprintf(f, "%u\n", (unsigned)getpid()) < 0) fatal_exit("could not write pid %s: %s", pidfile, strerror(errno)); fclose(f); } /** delete pidfile */ static void unlink_pid(char* pidfile) { int fd; /* truncate pidfile */ fd = open(pidfile, O_WRONLY | O_TRUNC, 0644); if(fd != -1) close(fd); unlink(pidfile); } /** detach from command line */ static void detach(void) { #if defined(HAVE_DAEMON) && !defined(DEPRECATED_DAEMON) /* use POSIX daemon(3) function */ if(daemon(1, 0) != 0) fatal_exit("daemon failed: %s", strerror(errno)); #else /* no HAVE_DAEMON */ #ifdef HAVE_FORK int fd; /* Take off... */ switch (fork()) { case 0: break; case -1: fatal_exit("fork failed: %s", strerror(errno)); default: /* exit interactive session */ exit(0); } /* detach */ #ifdef HAVE_SETSID if(setsid() == -1) fatal_exit("setsid() failed: %s", strerror(errno)); #endif if ((fd = open("/dev/null", O_RDWR, 0)) != -1) { (void)dup2(fd, STDIN_FILENO); (void)dup2(fd, STDOUT_FILENO); (void)dup2(fd, STDERR_FILENO); if (fd > 2) (void)close(fd); } #endif /* HAVE_FORK */ #endif /* HAVE_DAEMON */ } /** do main work of daemon */ static void do_main_work(const char* cfgfile, int nodaemonize, int verb) { struct cfg* cfg; struct svr* svr; /* start signal handlers */ if( signal(SIGTERM, record_sigh) == SIG_ERR || #ifdef SIGQUIT signal(SIGQUIT, record_sigh) == SIG_ERR || #endif #ifdef SIGBREAK signal(SIGBREAK, record_sigh) == SIG_ERR || #endif #ifdef SIGHUP signal(SIGHUP, record_sigh) == SIG_ERR || #endif #ifdef SIGPIPE signal(SIGPIPE, SIG_IGN) == SIG_ERR || #endif #if defined(SIGCHLD) && defined(HOOKS_OSX) signal(SIGCHLD, record_sigh) == SIG_ERR || #endif signal(SIGINT, record_sigh) == SIG_ERR ) log_err("install sighandler: %s", strerror(errno)); /* start daemon */ cfg = cfg_create(cfgfile); verbosity += verb; if(!cfg) fatal_exit("could not create config"); svr = svr_create(cfg); if(!svr) fatal_exit("could not init server"); log_init(cfg->logfile, cfg->use_syslog, cfg->chroot); if(!nodaemonize) detach(); store_pid(cfg->pidfile); log_info("%s start", PACKAGE_STRING); /* start 127.0.0.1 service (assumes not left in insecure mode), * unbound starts in authority-direct mode by default */ /* TODO: check if already localhost and if so do not provide a small * window of opportunity here */ hook_resolv_localhost(cfg); #ifdef USE_WINSOCK netlist_start(svr); #endif #ifdef HOOKS_OSX osx_probe_hook(); osx_wakelistener_start(cfg); #endif while(1) { svr_service(svr); if(sig_reload) { struct cfg* c2; verbose(VERB_OPS, "%s reload", PACKAGE_STRING); if(!(c2 = cfg_create(cfgfile))) log_err("could not reload config"); else { cfg_delete(cfg); cfg = c2; svr->cfg = cfg; } /* reopen log after HUP to facilitate log rotation */ if(!cfg->use_syslog) log_init(cfg->logfile, 0, cfg->chroot); sig_reload = 0; continue; } break; } /* attempt to set 127.0.0.1 in case we weren't, for next reboot, so that during the reboot there is no window of opportunity */ if(svr->insecure_state) hook_resolv_localhost(cfg); unlink_pid(cfg->pidfile); log_info("%s stop", PACKAGE_STRING); svr_delete(svr); cfg_delete(cfg); } /** getopt global, in case header files fail to declare it. */ extern int optind; /** getopt global, in case header files fail to declare it. */ extern char* optarg; /** * main program. Set options given commandline arguments. * @param argc: number of commandline arguments. * @param argv: array of commandline arguments. * @return: exit status of the program. */ int main(int argc, char *argv[]) { int c; const char* cfgfile = CONFIGFILE; int nodaemonize = 0, verb = 0, uninit_it = 0; const char* winopt = NULL; #ifdef USE_WINSOCK int cmdline_cfg = 0; int r; WSADATA wsa_data; r = WSAStartup(MAKEWORD(2,2), &wsa_data); if(r != 0) { fatal_exit("could not init winsock. WSAStartup: %s", wsa_strerror(r)); } #endif /* USE_WINSOCK */ log_ident_set("dnssec-triggerd"); log_init(NULL, 0, NULL); while( (c=getopt(argc, argv, "c:dhuvw:")) != -1) { switch(c) { case 'c': cfgfile = optarg; #ifdef USE_WINSOCK cmdline_cfg = 1; #endif break; case 'u': uninit_it = 1; break; case 'v': verbosity++; verb++; break; case 'w': winopt = optarg; break; case 'd': nodaemonize=1; break; default: case 'h': usage(); return 1; } } argc -= optind; argv += optind; if(argc != 0) { usage(); return 1; } ERR_load_crypto_strings(); ERR_load_SSL_strings(); OpenSSL_add_all_algorithms(); (void)SSL_library_init(); if(uninit_it) { struct cfg* cfg = cfg_create(cfgfile); if(!cfg) fatal_exit("could not create config"); hook_resolv_uninstall(cfg); } else if(winopt) { #ifdef USE_WINSOCK wsvc_command_option(winopt, cfgfile, verb, cmdline_cfg); #else fatal_exit("option not supported"); #endif } else { do_main_work(cfgfile, nodaemonize, verb); } EVP_cleanup(); #ifdef HAVE_OPENSSL_ENGINE_H ENGINE_cleanup(); #endif #ifdef HAVE_OPENSSL_CONF_H CONF_modules_free(); #endif #if OPENSSL_VERSION_NUMBER < 0x10100000 CRYPTO_cleanup_all_ex_data(); ERR_remove_state(0); ERR_free_strings(); RAND_cleanup(); #endif #ifdef USE_WINSOCK if(WSACleanup() != 0) { log_err("Could not WSACleanup: %s", wsa_strerror(WSAGetLastError())); } #endif log_init(NULL, 0, NULL); /* close logfile */ return 0; } dnssec-trigger-0.13/riggerd/fptr_wlist.c0000664000175000017500000000753612275162157020022 0ustar wouterwouter/* * util/fptr_wlist.c - function pointer whitelists. * * Copyright (c) 2007, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains functions that check function pointers. * The functions contain a whitelist of known good callback values. * Any other values lead to an error. * * Due to the listing nature, this file violates all the modularization * boundaries in the program. */ #include "config.h" #include "fptr_wlist.h" #include "svr.h" #include "probe.h" #include "mini_event.h" #include "http.h" #include "update.h" #ifdef USE_WINSOCK #include "winrc/netlist.h" #include "winrc/win_svc.h" #endif int fptr_whitelist_comm_point(comm_point_callback_t *fptr) { if(fptr == &outq_handle_udp) return 1; else if(fptr == &outq_handle_tcp) return 1; return 0; } int fptr_whitelist_comm_point_raw(comm_point_callback_t *fptr) { if(fptr == &handle_ssl_accept) return 1; else if(fptr == &http_get_callback) return 1; else if(fptr == &control_callback) return 1; return 0; } int fptr_whitelist_comm_timer(void (*fptr)(void*)) { if(fptr == &outq_timeout) return 1; else if(fptr == &svr_retry_callback) return 1; else if(fptr == &http_get_timeout_handler) return 1; else if(fptr == &selfupdate_timeout) return 1; else if(fptr == &svr_tcp_callback) return 1; #ifdef USE_WINSOCK else if(fptr == &wsvc_cron_cb) return 1; #endif return 0; } int fptr_whitelist_comm_signal(void (*fptr)(int, void*)) { (void)fptr; return 0; } int fptr_whitelist_event(void (*fptr)(int, short, void *)) { if(fptr == &comm_point_udp_callback) return 1; else if(fptr == &comm_point_udp_ancil_callback) return 1; else if(fptr == &comm_point_tcp_accept_callback) return 1; else if(fptr == &comm_point_tcp_handle_callback) return 1; else if(fptr == &comm_timer_callback) return 1; else if(fptr == &comm_signal_callback) return 1; else if(fptr == &comm_point_local_handle_callback) return 1; else if(fptr == &comm_point_raw_handle_callback) return 1; #ifdef USE_WINSOCK else if(fptr == &netlist_change_cb) return 1; else if(fptr == &worker_win_stop_cb) return 1; #endif return 0; } int fptr_whitelist_rbtree_cmp(int (*fptr) (const void *, const void *)) { if(fptr == &mini_ev_cmp) return 1; return 0; } #ifdef USE_WINSOCK int fptr_whitelist_enum_reg(void (*fptr) (HKEY, void *)) { if(fptr == &enum_reg_set_nameserver) return 1; return 0; } #endif /* USE_WINSOCK */ dnssec-trigger-0.13/riggerd/ubhook.h0000664000175000017500000000742212275162157017113 0ustar wouterwouter/* * ubhook.h - dnssec-trigger unbound control hooks for adjusting that server * * Copyright (c) 2011, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains the unbound hooks for adjusting the unbound validating * DNSSEC resolver. */ #ifndef UBHOOKS_H #define UBHOOKS_H struct cfg; struct probe_ip; /** * Set the unbound server to go to the authorities * @param cfg: the config options. */ void hook_unbound_auth(struct cfg* cfg); /** * Set the unbound server to go to the given cache * @param cfg: the config options. */ void hook_unbound_cache(struct cfg* cfg, const char* ip); /** * Set the unbound server to go to the working probed servers. * @param cfg: the config options. * @param list: the working servers in this list are used. */ void hook_unbound_cache_list(struct cfg* cfg, struct probe_ip* list); /** * Set the unbound server to go dark. It gets no connections. * In reality, it sets unbound to forward to 127.0.0.127 and thus no upstream. * Unbound by default does not send queries to 127/8. * @param cfg: the config options. */ void hook_unbound_dark(struct cfg* cfg); /* IP address that makes unbound go dark, no upstream. unbound has * donotquery 127.0.0.0/8 by default */ #define UNBOUND_DARK_IP "127.0.0.127" /** * Detect if unbound supports the tcp-upstream option (since 1.4.13). * @param cfg: the config options. */ int hook_unbound_supports_tcp_upstream(struct cfg* cfg); /** * Detect if unbound supports the ssl-upstream option (since 1.4.14). * @param cfg: the config options. */ int hook_unbound_supports_ssl_upstream(struct cfg* cfg); /** * Set unbound to use tcp upstream. * @param cfg: the config options. * @param tcp80_ip4: if true, use those IP addresses. * @param tcp80_ip6: if true, use those IP addresses. * @param tcp443_ip4: if true, use those IP addresses. * @param tcp443_ip6: if true, use those IP addresses. */ void hook_unbound_tcp_upstream(struct cfg* cfg, int tcp80_ip4, int tcp80_ip6, int tcp443_ip4, int tcp443_ip6); /** * Set unbound to use ssl upstream. * @param cfg: the config options. * @param ssl443_ip4: if true, use those IP addresses. * @param ssl443_ip6: if true, use those IP addresses. */ void hook_unbound_ssl_upstream(struct cfg* cfg, int ssl443_ip4, int ssl443_ip6); #endif /* UBHOOKS_H */ dnssec-trigger-0.13/riggerd/fptr_wlist.h0000664000175000017500000001012312275162157020011 0ustar wouterwouter/* * util/fptr_wlist.h - function pointer whitelists. * * Copyright (c) 2007, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains functions that check function pointers. * The functions contain a whitelist of known good callback values. * Any other values lead to an error. * * This prevent heap overflow based exploits, where the callback pointer * is overwritten by a buffer overflow (apart from this defense, buffer * overflows should be fixed of course). * * Function pointers are used in * o network code callbacks. * o rbtree, the assertions are before the critical regions. * in other places, assertions are before the callback. */ #ifndef UTIL_FPTR_WLIST_H #define UTIL_FPTR_WLIST_H #include "netevent.h" /** * Macro to perform an assertion check for fptr wlist checks. * Does not get disabled in optimize mode. Check adds security by layers. */ #define fptr_ok(x) \ do { if(!(x)) \ fatal_exit("%s:%d: %s: pointer whitelist %s failed", \ __FILE__, __LINE__, __func__, #x); \ } while(0); /** * Check function pointer whitelist for comm_point callback values. * * @param fptr: function pointer to check. * @return false if not in whitelist. */ int fptr_whitelist_comm_point(comm_point_callback_t *fptr); /** * Check function pointer whitelist for raw comm_point callback values. * * @param fptr: function pointer to check. * @return false if not in whitelist. */ int fptr_whitelist_comm_point_raw(comm_point_callback_t *fptr); /** * Check function pointer whitelist for comm_timer callback values. * * @param fptr: function pointer to check. * @return false if not in whitelist. */ int fptr_whitelist_comm_timer(void (*fptr)(void*)); /** * Check function pointer whitelist for comm_signal callback values. * * @param fptr: function pointer to check. * @return false if not in whitelist. */ int fptr_whitelist_comm_signal(void (*fptr)(int, void*)); /** * Check function pointer whitelist for event structure callback values. * This is not called by libevent itself, but checked by netevent. * * @param fptr: function pointer to check. * @return false if not in whitelist. */ int fptr_whitelist_event(void (*fptr)(int, short, void *)); /** * Check function pointer whitelist for rbtree cmp callback values. * * @param fptr: function pointer to check. * @return false if not in whitelist. */ int fptr_whitelist_rbtree_cmp(int (*fptr) (const void *, const void *)); #ifdef USE_WINSOCK /** whitelist for registry enumeration function */ int fptr_whitelist_enum_reg(void (*fptr) (HKEY, void *)); #endif /* USE_WINSOCK */ #endif /* UTIL_FPTR_WLIST_H */ dnssec-trigger-0.13/riggerd/http.h0000664000175000017500000001614412275162157016604 0ustar wouterwouter/* * http.h - dnssec-trigger HTTP client code to GET a simple URL * * Copyright (c) 2012, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains an implementation of HTTP fetch for a simple URL file. */ #ifndef HTTP_H #define HTTP_H struct comm_base; struct comm_point; #include #include struct svr; struct http_probe; struct probe_ip; struct comm_reply; /** * overall HTTP probe structure */ struct http_general { struct svr* svr; /* array of urls to attempt to transfer from */ char** urls; /* array of checkcodes to check - the content of those urls */ char** codes; /* number of urls in array */ size_t url_num; /* the ipv4 http probe */ struct http_probe* v4; /* the ipv6 http probe */ struct http_probe* v6; /* http works */ int saw_http_work; }; /** * HTTP probe. The url split up and results. */ struct http_probe { /* the current url (const reference) */ char* url; /* hostname */ char* hostname; /* filename (not prefixed with a / ) */ char* filename; /* url index in urls array */ size_t url_idx; /* are we fetching the address record or doing http_get? */ int do_addr; /* is this ipv6? */ int ip6; /* num addr queries */ int num_addr_qs; /* num addr queries that failed */ int num_failed_addr_qs; /* list of addresses (RR records) */ ldns_rr_list* addr; /* port number */ int port; /* number of redirects we followed */ int redirects; /* result: did we get addresses? */ int got_addrs; /* result: does it connect? */ int connects; /* result: does it work (correct page) */ int works; /* is the probe finished? */ int finished; }; /** the number of urls to try to probe; in case one fails. */ #define HTTP_NUM_URLS_MAX_PROBE 3 /** max number of address queries for one name (all to different caches, * once for A then for AAAA, so double that number in sockets is needed). */ #define HTTP_MAX_ADDR_QUERIES 5 /** max number of redirects in sequence */ #define HTTP_MAX_REDIRECT 8 /** * create and randomise http general structure * @param svr: with config and create and register probes here. * @return: new http lookup administration */ struct http_general* http_general_start(struct svr* svr); /** * delete the http_general structure. * @param hg: http lookup administration */ void http_general_delete(struct http_general* hg); /** * The http lookup is completely done, either success (NULL) or fail reason */ void http_general_done(const char* reason); /** a host addr lookup is done (with an error or NULL) */ void http_host_outq_done(struct probe_ip* p, const char* reason); /** a host addr lookup is done, here is the packet (QR, rcode NOERROR). * The pkt is freeed by this routine. */ void http_host_outq_result(struct probe_ip* p, ldns_pkt* pkt); /** * Structure that represents an open TCP activity for a HTTP (no -s) GET. */ struct http_get { /* The url of the target */ char* url; /* hostname : name of host part of the URL */ char* hostname; /* filename : name of file part of URL (*not* prefixed with a / ) */ char* filename; /* state of the HTTP transaction */ enum http_get_state { /* we are not sending or reading any things */ http_state_none, /* we are sending the request (initial headers) */ http_state_request, /* we are reading the reply headers */ http_state_reply_header, /* we are reading the reply (HTTP/1.0) */ http_state_reply_data, /* we are reading chunked reply headers (HTTP/1.1) */ http_state_chunk_header, /* we are reading chunked reply data (HTTP/1.1) */ http_state_chunk_data, } state; /* data length (of replydata or chunkdata) */ size_t datalen; /* max data we want (0 is no max) */ size_t data_limit; /* this is a redirect response */ int redirect_now; /* the buffer with contents sent/received */ ldns_buffer* buf; /* the buffer with the result data */ ldns_buffer* data; /* my comm_base */ struct comm_base* base; /* my comm_point (a comm_raw) */ struct comm_point* cp; /* the timer */ struct comm_timer* timer; /* destination IP as a string */ char* dest; /* port number */ int port; /* the probe that this is part of */ struct probe_ip* probe; }; /* define max length that the buffer is created for */ #define MAX_HTTP_LENGTH 16384 /* the timeout for the HTTP part of the httpprobe operation, in msec */ #define HTTP_TIMEOUT 3000 /* HTTP port */ #define HTTP_PORT 80 /** * Create a new HTTP GET for the given url (http://example.com/bla.txt) * It does a plain (noSSL) http GET. * @param url: The url to fetch. * @param base: comm_base to register connect-ed TCP socket's comm_point. * @param probe: probe this is part of. * @return new get or NULL on failure (malloc failure). */ struct http_get* http_get_create(const char* url, struct comm_base* base, struct probe_ip* probe); /** * Delete a HTTP GET fetch. * @param hg: http_get structure to delete. */ void http_get_delete(struct http_get* hg); /** * Perform the fetch that was initialised. * Parses, connects, and so on. * @param hg: http_get structure. * @param dest: destination IP address. * @param port: port number (HTTP_PORT is the default 80). * @param err: the detailed error on failure (set to constant string). * @return false if failed. */ int http_get_fetch(struct http_get* hg, const char* dest, int port, char** err); /** handle socket events on http_get */ int http_get_callback(struct comm_point* cp, void* arg, int err, struct comm_reply* reply); /** handle timeout for the http_get operation */ void http_get_timeout_handler(void* arg); /** pick random RR from rr list, removes it from the list. list not empty*/ ldns_rr* http_pick_random_addr(ldns_rr_list* list); #endif /* HTTP_H */ dnssec-trigger-0.13/riggerd/svr.c0000664000175000017500000010027112617132371016420 0ustar wouterwouter/* * svr.c - dnssec-trigger server implementation * * Copyright (c) 2011, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains the server implementation. */ #include "config.h" #include "svr.h" #include "cfg.h" #include "log.h" #include "http.h" #include "probe.h" #include "netevent.h" #include "net_help.h" #include "reshook.h" #include "update.h" #ifdef USE_WINSOCK #include "winsock_event.h" #endif struct svr* global_svr = NULL; static int setup_ssl_ctx(struct svr* svr); static int setup_listen(struct svr* svr); static void sslconn_delete(struct sslconn* sc); static int sslconn_readline(struct sslconn* sc); static int sslconn_write(struct sslconn* sc); static int sslconn_checkclose(struct sslconn* sc); static void sslconn_shutdown(struct sslconn* sc); static void sslconn_command(struct sslconn* sc); static void sslconn_persist_command(struct sslconn* sc); static void send_results_to_con(struct svr* svr, struct sslconn* s); struct svr* svr_create(struct cfg* cfg) { struct svr* svr = (struct svr*)calloc(1, sizeof(*svr)); if(!svr) return NULL; global_svr = svr; svr->max_active = 32; svr->cfg = cfg; svr->base = comm_base_create(0); ldns_init_random(NULL, 0); if(!svr->base) { log_err("cannot create base"); svr_delete(svr); return NULL; } svr->udp_buffer = ldns_buffer_new(65553); if(!svr->udp_buffer) { log_err("out of memory"); svr_delete(svr); return NULL; } svr->retry_timer = comm_timer_create(svr->base, &svr_retry_callback, svr); svr->tcp_timer = comm_timer_create(svr->base, &svr_tcp_callback, svr); if(!svr->retry_timer || !svr->tcp_timer) { log_err("out of memory"); svr_delete(svr); return NULL; } if(cfg->check_updates) { svr->update = selfupdate_create(svr, cfg); if(!svr->update) { log_err("out of memory"); svr_delete(svr); return NULL; } } /* setup SSL_CTX */ if(!setup_ssl_ctx(svr)) { log_err("cannot setup SSL context"); svr_delete(svr); return NULL; } /* create listening */ if(!setup_listen(svr)) { log_err("cannot setup listening socket"); svr_delete(svr); return NULL; } return svr; } void svr_delete(struct svr* svr) { struct listen_list* ll, *nll; if(!svr) return; /* delete busy */ while(svr->busy_list) { (void)SSL_shutdown(svr->busy_list->ssl); sslconn_delete(svr->busy_list); } /* delete listening */ ll = svr->listen; while(ll) { nll = ll->next; comm_point_delete(ll->c); free(ll); ll=nll; } /* delete probes */ probe_list_delete(svr->probes); if(svr->ctx) { SSL_CTX_free(svr->ctx); } selfupdate_delete(svr->update); ldns_buffer_free(svr->udp_buffer); comm_timer_delete(svr->retry_timer); comm_timer_delete(svr->tcp_timer); http_general_delete(svr->http); comm_base_delete(svr->base); free(svr); } static int setup_ssl_ctx(struct svr* s) { char* s_cert; char* s_key; s->ctx = SSL_CTX_new(SSLv23_server_method()); if(!s->ctx) { log_crypto_err("could not SSL_CTX_new"); return 0; } /* no SSLv2 because has defects */ if(!(SSL_CTX_set_options(s->ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)){ log_crypto_err("could not set SSL_OP_NO_SSLv2"); return 0; } s_cert = s->cfg->server_cert_file; s_key = s->cfg->server_key_file; verbose(VERB_ALGO, "setup SSL certificates"); if(!SSL_CTX_use_certificate_file(s->ctx,s_cert,SSL_FILETYPE_PEM)) { log_err("Error for server-cert-file: %s", s_cert); log_crypto_err("Error in SSL_CTX use_certificate_file"); return 0; } if(!SSL_CTX_use_PrivateKey_file(s->ctx,s_key,SSL_FILETYPE_PEM)) { log_err("Error for server-key-file: %s", s_key); log_crypto_err("Error in SSL_CTX use_PrivateKey_file"); return 0; } if(!SSL_CTX_check_private_key(s->ctx)) { log_err("Error for server-key-file: %s", s_key); log_crypto_err("Error in SSL_CTX check_private_key"); return 0; } if(!SSL_CTX_load_verify_locations(s->ctx, s_cert, NULL)) { log_crypto_err("Error setting up SSL_CTX verify locations"); return 0; } SSL_CTX_set_client_CA_list(s->ctx, SSL_load_client_CA_file(s_cert)); SSL_CTX_set_verify(s->ctx, SSL_VERIFY_PEER, NULL); return 1; } static int setup_listen(struct svr* svr) { const char* str="127.0.0.1"; struct sockaddr_storage addr; socklen_t len; int s; int fam; struct listen_list* e; #if defined(SO_REUSEADDR) || defined(IPV6_V6ONLY) int on = 1; #endif if(!ipstrtoaddr(str, svr->cfg->control_port, &addr, &len)) { log_err("cannot parse ifname %s", str); return 0; } if(strchr(str, ':')) fam = AF_INET6; else fam = AF_INET; s = socket(fam, SOCK_STREAM, 0); if(s == -1) { log_err("socket %s: %s", str, strerror(errno)); return 0; } #ifdef SO_REUSEADDR if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&on, (socklen_t)sizeof(on)) < 0) { log_err("setsockopt(.. SO_REUSEADDR ..) failed: %s", strerror(errno)); } #endif #if defined(IPV6_V6ONLY) if(fam == AF_INET6) { if(setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&on, (socklen_t)sizeof(on)) < 0) { log_err("setsockopt(..., IPV6_V6ONLY, ...) failed: %s", strerror(errno)); } } #endif if(bind(s, (struct sockaddr*)&addr, len) != 0) { fatal_exit("can't bind tcp socket %s: %s", str, strerror(errno)); } fd_set_nonblock(s); if(listen(s, 15) == -1) { log_err("can't listen: %s", strerror(errno)); } /* add entry */ e = (struct listen_list*)calloc(1, sizeof(*e)); if(!e) { fatal_exit("out of memory"); } e->c = comm_point_create_raw(svr->base, s, 0, handle_ssl_accept, NULL); e->c->do_not_close = 0; e->next = svr->listen; svr->listen = e; return 1; } void svr_service(struct svr* svr) { comm_base_dispatch(svr->base); } static void sslconn_delete(struct sslconn* sc) { struct sslconn** pp; if(!sc) return; /* delete and remove from busylist */ for(pp = &global_svr->busy_list; *pp; pp = &((*pp)->next)) { if((*pp) == sc) { (*pp) = sc->next; break; } } global_svr->active--; if(sc->buffer) ldns_buffer_free(sc->buffer); comm_point_delete(sc->c); if(sc->ssl) SSL_free(sc->ssl); free(sc); } int handle_ssl_accept(struct comm_point* c, void* ATTR_UNUSED(arg), int err, struct comm_reply* ATTR_UNUSED(reply_info)) { struct sockaddr_storage addr; socklen_t addrlen; int s; struct svr* svr = global_svr; struct sslconn* sc; if(err != NETEVENT_NOERROR) { log_err("error %d on remote_accept_callback", err); return 0; } /* perform the accept */ s = comm_point_perform_accept(c, &addr, &addrlen); if(s == -1) return 0; /* create new commpoint unless we are servicing already */ if(svr->active >= svr->max_active) { log_warn("drop incoming remote control: too many connections"); close_exit: #ifndef USE_WINSOCK close(s); #else closesocket(s); #endif return 0; } /* setup commpoint to service the remote control command */ sc = (struct sslconn*)calloc(1, sizeof(*sc)); if(!sc) { log_err("out of memory"); goto close_exit; } /* start in reading state */ sc->c = comm_point_create_raw(svr->base, s, 0, &control_callback, sc); if(!sc->c) { log_err("out of memory"); free(sc); goto close_exit; } log_addr(VERB_QUERY, "new control connection from", &addr, addrlen); sc->c->do_not_close = 0; /* no timeout on the connection: the panel stays connected for long */ memcpy(&sc->c->repinfo.addr, &addr, addrlen); sc->c->repinfo.addrlen = addrlen; sc->shake_state = rc_hs_read; sc->ssl = SSL_new(svr->ctx); if(!sc->ssl) { log_crypto_err("could not SSL_new"); comm_point_delete(sc->c); free(sc); return 0; } SSL_set_accept_state(sc->ssl); (void)SSL_set_mode(sc->ssl, SSL_MODE_AUTO_RETRY); if(!SSL_set_fd(sc->ssl, s)) { log_crypto_err("could not SSL_set_fd"); SSL_free(sc->ssl); comm_point_delete(sc->c); free(sc); return 0; } #ifdef USE_WINSOCK comm_point_tcp_win_bio_cb(sc->c, sc->ssl); #endif sc->buffer = ldns_buffer_new(65536); if(!sc->buffer) { log_err("out of memory"); SSL_free(sc->ssl); comm_point_delete(sc->c); free(sc); return 0; } sc->next = svr->busy_list; svr->busy_list = sc; svr->active ++; /* perform the first nonblocking read already, for windows, * so it can return wouldblock. could be faster too. */ (void)control_callback(sc->c, sc, NETEVENT_NOERROR, NULL); return 0; } int control_callback(struct comm_point* c, void* arg, int err, struct comm_reply* ATTR_UNUSED(reply_info)) { struct sslconn* s = (struct sslconn*)arg; int r; if(err != NETEVENT_NOERROR) { if(err==NETEVENT_TIMEOUT) log_err("remote control timed out"); sslconn_delete(s); return 0; } /* (continue to) setup the SSL connection */ if(s->shake_state == rc_hs_read || s->shake_state == rc_hs_write) { ERR_clear_error(); r = SSL_do_handshake(s->ssl); if(r != 1) { int r2 = SSL_get_error(s->ssl, r); if(r2 == SSL_ERROR_WANT_READ) { if(s->shake_state == rc_hs_read) { /* try again later */ return 0; } s->shake_state = rc_hs_read; comm_point_listen_for_rw(c, 1, 0); return 0; } else if(r2 == SSL_ERROR_WANT_WRITE) { if(s->shake_state == rc_hs_write) { /* try again later */ return 0; } s->shake_state = rc_hs_write; comm_point_listen_for_rw(c, 0, 1); return 0; } else if(r2 == SSL_ERROR_SYSCALL) { if(ERR_peek_error()) { char errbuf[128]; ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf)); log_err("ssl_handshake: %s", errbuf); } else if(r == 0) { log_err("ssl_handshake EOF violation"); } else if(r == -1) { #ifdef USE_WINSOCK log_err("ssl_handshake syscall: " "%s, wsa: %s", strerror(errno), wsa_strerror(WSAGetLastError())); #else log_err("ssl_handshake syscall: %s", strerror(errno)); #endif } else log_err("ssl_handshake syscall ret %d", r); sslconn_delete(s); return 0; } else { if(r == 0) log_err("remote control connection closed prematurely"); log_addr(1, "failed connection from", &s->c->repinfo.addr, s->c->repinfo.addrlen); log_crypto_err("remote control failed ssl"); sslconn_delete(s); return 0; } } /* once handshake has completed, check authentication */ if(SSL_get_verify_result(s->ssl) == X509_V_OK) { X509* x = SSL_get_peer_certificate(s->ssl); if(!x) { verbose(VERB_DETAIL, "remote control connection " "provided no client certificate"); sslconn_delete(s); return 0; } verbose(VERB_ALGO, "remote control connection authenticated"); X509_free(x); } else { verbose(VERB_DETAIL, "remote control connection failed to " "authenticate with client certificate"); sslconn_delete(s); return 0; } /* set to read state */ s->line_state = command_read; if(s->shake_state == rc_hs_write) comm_point_listen_for_rw(c, 1, 0); s->shake_state = rc_hs_none; ldns_buffer_clear(s->buffer); } else if(s->shake_state == rc_hs_want_write) { /* we have satisfied the condition that the socket is * writable, remove the handshake state, and continue */ comm_point_listen_for_rw(c, 1, 0); /* back to reading */ s->shake_state = rc_hs_none; } else if(s->shake_state == rc_hs_want_read) { /* we have satisfied the condition that the socket is * readable, remove the handshake state, and continue */ comm_point_listen_for_rw(c, 1, 1); /* back to writing */ s->shake_state = rc_hs_none; } else if(s->shake_state == rc_hs_shutdown) { sslconn_shutdown(s); } if(s->line_state == command_read) { if(!sslconn_readline(s)) return 0; /* we are done handle it */ sslconn_command(s); } else if(s->line_state == persist_read) { do { if(!sslconn_readline(s)) return 0; /* we are done handle it */ sslconn_persist_command(s); /* there may be more to read in the same SSL packet */ } while(SSL_pending(s->ssl) != 0); } else if(s->line_state == persist_write) { if(sslconn_checkclose(s)) return 0; if(!sslconn_write(s)) return 0; if(s->fetch_another_update) { s->fetch_another_update = 0; send_results_to_con(global_svr, s); return 0; } /* nothing more to write */ if(s->close_me) { sslconn_shutdown(s); return 0; } comm_point_listen_for_rw(c, 1, 0); s->line_state = persist_write_checkclose; } else if(s->line_state == persist_write_checkclose) { (void)sslconn_checkclose(s); } return 0; } static int sslconn_readline(struct sslconn* sc) { int r; while(ldns_buffer_available(sc->buffer, 1)) { ERR_clear_error(); if((r=SSL_read(sc->ssl, ldns_buffer_current(sc->buffer), 1)) <= 0) { int want = SSL_get_error(sc->ssl, r); if(want == SSL_ERROR_ZERO_RETURN) { sslconn_shutdown(sc); return 0; } else if(want == SSL_ERROR_WANT_READ) { return 0; } else if(want == SSL_ERROR_WANT_WRITE) { sc->shake_state = rc_hs_want_write; comm_point_listen_for_rw(sc->c, 0, 1); return 0; } else if(want == SSL_ERROR_SYSCALL) { if(ERR_peek_error()) { char errbuf[128]; ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf)); log_err("ssl_read: %s", errbuf); } else if(r == 0) { log_err("ssl_read EOF violation"); } else if(r == -1) { #ifdef USE_WINSOCK int wsar = WSAGetLastError(); /* conn reset common at restarts */ if(wsar == WSAECONNRESET) verbose(VERB_ALGO, "ssl_read syscall: %s", wsa_strerror(wsar)); else log_err("ssl_read syscall: " "%s, wsa: %s", strerror(errno), wsa_strerror(wsar)); #else log_err("ssl_read syscall: %s", strerror(errno)); #endif } else log_err("ssl_read syscall ret %d", r); sslconn_delete(sc); return 0; } log_crypto_err("could not SSL_read"); sslconn_delete(sc); return 0; } if(ldns_buffer_current(sc->buffer)[0] == '\n') { /* return string without \n */ ldns_buffer_write_u8(sc->buffer, 0); ldns_buffer_flip(sc->buffer); return 1; } ldns_buffer_skip(sc->buffer, 1); } log_err("ssl readline too long"); sslconn_delete(sc); return 0; } static int sslconn_write(struct sslconn* sc) { int r; /* ignore return, if fails we may simply block */ (void)SSL_set_mode(sc->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE); while(ldns_buffer_remaining(sc->buffer)>0) { ERR_clear_error(); if((r=SSL_write(sc->ssl, ldns_buffer_current(sc->buffer), (int)ldns_buffer_remaining(sc->buffer))) <= 0) { int want = SSL_get_error(sc->ssl, r); if(want == SSL_ERROR_ZERO_RETURN) { /* the other side has closed the channel */ verbose(VERB_ALGO, "result write closed"); sslconn_delete(sc); return 0; } else if(want == SSL_ERROR_WANT_READ) { sc->shake_state = rc_hs_want_read; comm_point_listen_for_rw(sc->c, 1, 0); return 0; } else if(want == SSL_ERROR_WANT_WRITE) { return 0; } else if(want == SSL_ERROR_SYSCALL) { if(ERR_peek_error()) { char errbuf[128]; ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf)); log_err("ssl_write: %s", errbuf); } else if(r == 0) { log_err("ssl_write EOF violation"); } else if(r == -1) { #ifdef USE_WINSOCK log_err("ssl_write syscall: " "%s, wsa: %s", strerror(errno), wsa_strerror(WSAGetLastError())); #else log_err("ssl_write syscall: %s", strerror(errno)); #endif } else log_err("ssl_write syscall ret %d", r); sslconn_delete(sc); return 0; } log_crypto_err("could not SSL_write"); /* the other side has closed the channel */ sslconn_delete(sc); return 0; } ldns_buffer_skip(sc->buffer, (ssize_t)r); } /* done writing the buffer. */ return 1; } static void sslconn_shutdown(struct sslconn* sc) { int r = SSL_shutdown(sc->ssl); if(r > 0) { sslconn_delete(sc); } else if(r == 0) { /* we do not need to get notify from the peer, since we * close the fd */ sslconn_delete(sc); } else { int want = SSL_get_error(sc->ssl, r); sc->shake_state = rc_hs_shutdown; if(want == SSL_ERROR_ZERO_RETURN) { sslconn_delete(sc); } else if(want == SSL_ERROR_WANT_READ) { comm_point_listen_for_rw(sc->c, 1, 0); } else if(want == SSL_ERROR_WANT_WRITE) { comm_point_listen_for_rw(sc->c, 0, 1); } else { log_crypto_err("could not SSL_shutdown"); sslconn_delete(sc); } } } static int sslconn_checkclose(struct sslconn* sc) { int r; ERR_clear_error(); if((r=SSL_read(sc->ssl, NULL, 0)) <= 0) { int want = SSL_get_error(sc->ssl, r); if(want == SSL_ERROR_ZERO_RETURN) { verbose(VERB_ALGO, "checked channel closed otherside"); sslconn_shutdown(sc); return 1; } else if(want == SSL_ERROR_WANT_READ) { return 0; } else if(want == SSL_ERROR_WANT_WRITE) { sc->shake_state = rc_hs_want_write; comm_point_listen_for_rw(sc->c, 0, 1); return 0; } else if(want == SSL_ERROR_SYSCALL) { if(ERR_peek_error()) { char errbuf[128]; ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf)); log_err("checkclose ssl_read: %s", errbuf); } else if(r == 0) { log_err("checkclose ssl_read EOF violation"); } else if(r == -1) { #ifdef USE_WINSOCK int wsar = WSAGetLastError(); /* connreset common at restart of system */ if(wsar == WSAECONNRESET) verbose(VERB_ALGO, "checkclose ssl_read syscall: %s", wsa_strerror(wsar)); else log_err("checkclose ssl_read syscall: " "%s, wsa: %s", strerror(errno), wsa_strerror(WSAGetLastError())); #else log_err("checkclose ssl_read syscall: %s", strerror(errno)); #endif } else log_err("checkclose ssl_read syscall ret %d", r); sslconn_delete(sc); return 0; } log_crypto_err("checkclose could not SSL_read"); sslconn_delete(sc); return 1; } if(SSL_get_shutdown(sc->ssl)) { verbose(VERB_ALGO, "checked channel closed"); sslconn_delete(sc); return 1; } return 0; } static void persist_cmd_insecure(int val) { struct svr* svr = global_svr; int was_insecure = svr->insecure_state; svr->insecure_state = val; /* see if we need to change unbound's settings */ if(svr->res_state == res_dark) { if(!was_insecure && val) { /* set resolv.conf to the DHCP IP list */ hook_resolv_iplist(svr->cfg, svr->probes); } else if(was_insecure && !val) { /* set resolv.conf to 127.0.0.1 */ hook_resolv_localhost(svr->cfg); } } else { /* no need for insecure; robustness, in case some delayed * command arrives when we have reprobed again */ if(!svr->forced_insecure) svr->insecure_state = 0; } svr_send_results(svr); } void cmd_reprobe(void) { char buf[10240]; char* now = buf; size_t left = sizeof(buf); struct probe_ip* p; buf[0]=0; /* safe, robust */ for(p = global_svr->probes; p; p = p->next) { if(probe_is_cache(p)) { size_t len; if(left < strlen(p->name)+3) break; /* no space for more */ snprintf(now, left, "%s%s", (now==buf)?"":" ", p->name); len = strlen(now); left -= len; now += len; } } probe_start(buf); } static void handle_hotspot_signon_cmd(struct svr* svr) { verbose(VERB_OPS, "state dark forced_insecure"); probe_setup_hotspot_signon(svr); svr_send_results(svr); } static void handle_skip_http_cmd(void) { verbose(VERB_OPS, "state skip_http and reprobe"); global_svr->skip_http = 1; cmd_reprobe(); } static void sslconn_persist_command(struct sslconn* sc) { char* str = (char*)ldns_buffer_begin(sc->buffer); while(*str == ' ') str++; verbose(VERB_ALGO, "persist-channel command: %s", str); if(*str == 0) { /* ignore empty lines */ } else if(strcmp(str, "insecure yes") == 0) { persist_cmd_insecure(1); } else if(strcmp(str, "insecure no") == 0) { persist_cmd_insecure(0); } else if(strcmp(str, "reprobe") == 0) { global_svr->forced_insecure = 0; global_svr->http_insecure = 0; cmd_reprobe(); } else if(strcmp(str, "skip_http") == 0) { handle_skip_http_cmd(); } else if(strcmp(str, "hotspot_signon") == 0) { handle_hotspot_signon_cmd(global_svr); } else if(strcmp(str, "update_cancel") == 0) { selfupdate_userokay(global_svr->update, 0); } else if(strcmp(str, "update_ok") == 0) { selfupdate_userokay(global_svr->update, 1); } else { log_err("unknown command from panel: %s", str); } /* and ready to read the next command */ ldns_buffer_clear(sc->buffer); } static void handle_submit(char* ips) { /* start probing the servers */ probe_start(ips); } /** append update signal to buffer to send */ static void append_update_to_con(struct sslconn* s, char* version_available) { ldns_buffer_printf(s->buffer, "update %s\n%s\n\n", PACKAGE_VERSION, version_available); } static void send_results_to_con(struct svr* svr, struct sslconn* s) { struct probe_ip* p; char at[32]; int numcache = 0, unfinished = 0; ldns_buffer_clear(s->buffer); if(svr->probetime == 0) ldns_buffer_printf(s->buffer, "at (no probe performed)\n"); else if(strftime(at, sizeof(at), "%Y-%m-%d %H:%M:%S", localtime(&svr->probetime))) ldns_buffer_printf(s->buffer, "at %s\n", at); for(p=svr->probes; p; p=p->next) { if(probe_is_cache(p)) numcache++; if(!p->finished) { unfinished++; continue; } if(p->to_http) { if(p->host_c) { ldns_buffer_printf(s->buffer, "%s %s %s from %s: %s %s\n", "addr", p->host_c->qname, p->http_ip6?"AAAA":"A", p->name, p->works?"OK":"error", p->reason?p->reason:""); } else ldns_buffer_printf(s->buffer, "%s %s (%s): %s %s\n", "http", p->http_desc, p->name, p->works?"OK":"error", p->reason?p->reason:""); } else if(p->dnstcp) ldns_buffer_printf(s->buffer, "%s%d %s: %s %s\n", p->ssldns?"ssl":"tcp", p->port, p->name, p->works?"OK":"error", p->reason?p->reason:""); else ldns_buffer_printf(s->buffer, "%s %s: %s %s\n", p->to_auth?"authority":"cache", p->name, p->works?"OK":"error", p->reason?p->reason:""); } if(unfinished) ldns_buffer_printf(s->buffer, "probe is in progress\n"); else if(!numcache) ldns_buffer_printf(s->buffer, "no cache: no DNS servers have been supplied via DHCP\n"); ldns_buffer_printf(s->buffer, "state: %s %s%s%s\n", svr->res_state==res_cache?"cache":( svr->res_state==res_tcp?"tcp":( svr->res_state==res_ssl?"ssl":( svr->res_state==res_auth?"auth":( svr->res_state==res_disconn?"disconnected":"nodnssec")))), svr->insecure_state?"insecure_mode":"secure", svr->forced_insecure?" forced_insecure":"", svr->http_insecure?" http_insecure":"" ); ldns_buffer_printf(s->buffer, "\n"); if(svr->update && svr->update->update_available && !svr->update->user_replied) { log_info("append_update signal"); append_update_to_con(s, svr->update->version_available); } ldns_buffer_flip(s->buffer); comm_point_listen_for_rw(s->c, 1, 1); s->line_state = persist_write; } void svr_signal_update(struct svr* svr, char* version_available) { /* write stop to all connected panels */ struct sslconn* s; for(s=svr->busy_list; s; s=s->next) { if(s->line_state == persist_write) { /* busy with last results, fetch update later */ s->fetch_another_update=1; } if(s->line_state == persist_write_checkclose) { ldns_buffer_clear(s->buffer); append_update_to_con(s, version_available); ldns_buffer_flip(s->buffer); comm_point_listen_for_rw(s->c, 1, 1); s->line_state = persist_write; } } } static void handle_results_cmd(struct sslconn* sc) { /* turn into persist write with results. */ ldns_buffer_clear(sc->buffer); ldns_buffer_flip(sc->buffer); /* must listen for close of connection: reading */ comm_point_listen_for_rw(sc->c, 1, 0); sc->line_state = persist_write_checkclose; /* feed it the first results (if any) */ send_results_to_con(global_svr, sc); } static void handle_status_cmd(struct sslconn* sc) { sc->close_me = 1; handle_results_cmd(sc); } static void handle_printclose(struct sslconn* sc, char* str) { /* write and then close */ sc->close_me = 1; comm_point_listen_for_rw(sc->c, 1, 1); sc->line_state = persist_write; /* enter contents */ ldns_buffer_clear(sc->buffer); ldns_buffer_printf(sc->buffer, "%s\n", str); ldns_buffer_flip(sc->buffer); } static void handle_cmdtray_cmd(struct sslconn* sc) { #ifdef HOOKS_OSX /* OSX has messed up resolv.conf after relogin */ restore_resolv_osx(global_svr->cfg); #endif /* turn into persist read */ ldns_buffer_clear(sc->buffer); comm_point_listen_for_rw(sc->c, 1, 0); sc->line_state = persist_read; } static void handle_unsafe_cmd(struct sslconn* sc) { probe_unsafe_test(); sslconn_shutdown(sc); } static void handle_test_tcp_cmd(struct sslconn* sc) { probe_tcp_test(); sslconn_shutdown(sc); } static void handle_test_ssl_cmd(struct sslconn* sc) { probe_ssl_test(); sslconn_shutdown(sc); } static void handle_test_http_cmd(struct sslconn* sc) { probe_http_test(); sslconn_shutdown(sc); } static void handle_test_update_cmd(struct sslconn* sc) { global_svr->update->test_flag = 1; global_svr->update_desired = 1; sslconn_shutdown(sc); } static void handle_stoppanels_cmd(struct sslconn* sc) { /* write stop to all connected panels */ const char* stopcmd = "stop\n"; struct sslconn* s; for(s=global_svr->busy_list; s; s=s->next) { /* skip non persistent-write connections */ if(s->line_state != persist_write_checkclose && s->line_state != persist_write) continue; (void)SSL_set_mode(s->ssl, SSL_MODE_AUTO_RETRY); if(SSL_get_fd(s->ssl) != -1) { #ifdef USE_WINSOCK /* to be able to set it back to blocking mode * we have to remove the EventSelect on it */ if(WSAEventSelect(SSL_get_fd(s->ssl), NULL, 0)!=0) log_err("WSAEventSelect disable: %s", wsa_strerror(WSAGetLastError())); #endif fd_set_block(SSL_get_fd(s->ssl)); } if(s->line_state == persist_write) { /* busy with last results, blocking write them */ if(SSL_write(s->ssl, ldns_buffer_current(s->buffer), (int)ldns_buffer_remaining(s->buffer)) < 0) log_crypto_err("cannot SSL_write remainder"); } /* blocking write the stop command */ if(SSL_write(s->ssl, stopcmd, (int)strlen(stopcmd)) < 0) log_crypto_err("cannot SSL_write panel stop"); if(!SSL_get_shutdown(s->ssl)) { if(SSL_shutdown(s->ssl) == 0) SSL_shutdown(s->ssl); /* again to wait */ } /* it will be closed now */ if(SSL_get_fd(s->ssl) != -1) fd_set_nonblock(SSL_get_fd(s->ssl)); comm_point_listen_for_rw(s->c, 1, 0); s->line_state = persist_write_checkclose; } /* wait until they all stopped, then stop commanding connection */ sslconn_shutdown(sc); } static void sslconn_command(struct sslconn* sc) { char header[10]; char* str = (char*)ldns_buffer_begin(sc->buffer); snprintf(header, sizeof(header), "DNSTRIG%d ", CONTROL_VERSION); if(strncmp(str, header, strlen(header)) != 0) { log_err("bad version in control connection"); sslconn_delete(sc); return; } str += strlen(header); while(*str == ' ') str++; verbose(VERB_ALGO, "command: %s", str); if(strncmp(str, "submit", 6) == 0) { handle_submit(str+6); sslconn_shutdown(sc); } else if(strncmp(str, "reprobe", 7) == 0) { global_svr->forced_insecure = 0; global_svr->http_insecure = 0; cmd_reprobe(); sslconn_shutdown(sc); } else if(strncmp(str, "skip_http", 9) == 0) { handle_skip_http_cmd(); sslconn_shutdown(sc); } else if(strncmp(str, "hotspot_signon", 14) == 0) { handle_hotspot_signon_cmd(global_svr); sslconn_shutdown(sc); } else if(strncmp(str, "results", 7) == 0) { handle_results_cmd(sc); } else if(strncmp(str, "status", 7) == 0) { handle_status_cmd(sc); } else if(strncmp(str, "cmdtray", 7) == 0) { handle_cmdtray_cmd(sc); } else if(strncmp(str, "unsafe", 6) == 0) { handle_unsafe_cmd(sc); } else if(strncmp(str, "test_tcp", 8) == 0) { handle_test_tcp_cmd(sc); } else if(strncmp(str, "test_ssl", 8) == 0) { handle_test_ssl_cmd(sc); } else if(strncmp(str, "test_http", 8) == 0) { handle_test_http_cmd(sc); } else if(strncmp(str, "test_update", 11) == 0) { handle_test_update_cmd(sc); } else if(strncmp(str, "stoppanels", 10) == 0) { handle_stoppanels_cmd(sc); } else if(strncmp(str, "stop", 4) == 0) { comm_base_exit(global_svr->base); sslconn_shutdown(sc); } else { verbose(VERB_DETAIL, "unknown command: %s", str); handle_printclose(sc, "error unknown command"); } } void svr_send_results(struct svr* svr) { struct sslconn* s; for(s=svr->busy_list; s; s=s->next) { if(s->line_state == persist_write) { /* busy with last results, fetch update later */ s->fetch_another_update=1; } if(s->line_state == persist_write_checkclose) { send_results_to_con(svr, s); } } } void svr_retry_callback(void* arg) { struct svr* svr = (struct svr*)arg; if(!svr->retry_timer_enabled) { comm_timer_disable(svr->retry_timer); return; } verbose(VERB_ALGO, "retry timeout"); cmd_reprobe(); } static void svr_retry_setit(struct svr* svr) { struct timeval tv; if(svr->retry_timer_count < RETRY_TIMER_COUNT_MAX) verbose(VERB_ALGO, "retry in %d seconds (try nr %d)", svr->retry_timer_timeout, svr->retry_timer_count); else verbose(VERB_ALGO, "retry in %d seconds", svr->retry_timer_timeout); tv.tv_sec = svr->retry_timer_timeout; tv.tv_usec = 0; comm_timer_set(svr->retry_timer, &tv); } static void svr_retry_start(struct svr* svr, int http_mode) { svr->retry_timer_timeout = RETRY_TIMER_START; if(http_mode) svr->retry_timer_count = 1; else svr->retry_timer_count = RETRY_TIMER_COUNT_MAX; svr->retry_timer_enabled = 1; svr_retry_setit(svr); } void svr_retry_timer_next(int http_mode) { struct svr* svr = global_svr; if(!svr->retry_timer_enabled) { svr_retry_start(svr, http_mode); return; } if(svr->retry_timer_count < RETRY_TIMER_COUNT_MAX) { svr->retry_timer_count++; } else { svr->retry_timer_timeout *= 2; if(svr->retry_timer_timeout > RETRY_TIMER_MAX) svr->retry_timer_timeout = RETRY_TIMER_MAX; } svr_retry_setit(svr); } void svr_retry_timer_stop(void) { struct svr* svr = global_svr; if(!svr->retry_timer_enabled) return; svr->retry_timer_enabled = 0; comm_timer_disable(svr->retry_timer); } void svr_tcp_timer_stop(void) { struct svr* svr = global_svr; comm_timer_disable(svr->retry_timer); } void svr_tcp_timer_enable(void) { struct svr* svr = global_svr; struct timeval tv; if(svr->tcp_timer_used) return; verbose(VERB_ALGO, "retry dnstcp in %d seconds", SVR_TCP_RETRY); tv.tv_sec = SVR_TCP_RETRY; tv.tv_usec = 0; comm_timer_set(svr->tcp_timer, &tv); } void svr_tcp_callback(void* arg) { /* we do this probe because some 20 seconds after login, more * ports may open and this can alleviate traffic on the open * recursors */ struct svr* svr = (struct svr*)arg; verbose(VERB_ALGO, "retry dnstcp timeout"); comm_timer_disable(svr->tcp_timer); if(svr->res_state == res_tcp || svr->res_state == res_ssl) { svr->tcp_timer_used = 1; cmd_reprobe(); } } void svr_check_update(struct svr* svr) { if(svr->update_desired && !svr->insecure_state && !svr->forced_insecure && svr->res_state != res_dark && svr->res_state != res_disconn) { selfupdate_start(svr->update); } } dnssec-trigger-0.13/riggerd/cfg.h0000664000175000017500000001402112275162157016354 0ustar wouterwouter/* * cfg.h - dnssec-trigger config * * Copyright (c) 2011, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains config file options. */ #ifndef CFG_H #define CFG_H struct strlist; struct ssllist; /* version of control proto */ #define CONTROL_VERSION 1 /** * The configuration options */ struct cfg { /** verbosity */ int verbosity; /** pid file */ char* pidfile; /** log file (or NULL) */ char* logfile; /** use syslog (bool) */ int use_syslog; /** chroot dir (or NULL) */ char* chroot; /** path to unbound-control, can have space and commandline options */ char* unbound_control; /** path to resolv.conf */ char* resolvconf; /** resolv.conf domain line (or NULL) */ char* rescf_domain; /** resolv.conf search line (or NULL) */ char* rescf_search; /** noaction option does no actions to resolv.conf or unbound */ int noaction; /** web browser to open login windows */ char* login_command; /** url to open for login windows */ char* login_location; /** list of port 80 open resolvers on ip4 and ip6 */ struct strlist* tcp80_ip4, *tcp80_ip4_last; int num_tcp80_ip4; struct strlist* tcp80_ip6, *tcp80_ip6_last; int num_tcp80_ip6; /** list of port 443 open resolvers on ip4 and ip6*/ struct strlist* tcp443_ip4, *tcp443_ip4_last; int num_tcp443_ip4; struct strlist* tcp443_ip6, *tcp443_ip6_last; int num_tcp443_ip6; /** list of ssl port 443 resolvers on ip4 and ip6 */ struct ssllist* ssl443_ip4, *ssl443_ip4_last; int num_ssl443_ip4; struct ssllist* ssl443_ip6, *ssl443_ip6_last; int num_ssl443_ip6; /** list of http probe urls */ struct strlist2* http_urls, *http_urls_last; int num_http_urls; /** if we should perform version check (and ask user to update) * enabled on windows and osx. */ int check_updates; /** port number for the control port */ int control_port; /** private key file for server */ char* server_key_file; /** certificate file for server */ char* server_cert_file; /** private key file for control */ char* control_key_file; /** certificate file for control */ char* control_cert_file; }; /** simple list of strings */ struct strlist { struct strlist* next; char* str; }; /** simple list of two strings */ struct strlist2 { struct strlist2* next; char* str1; char* str2; }; /** list of hashes */ struct hashlist { struct hashlist* next; unsigned char hash[64]; /* hash (SHA256) */ unsigned int hashlen; /* number of bytes used in hash */ }; /** list of ssl servers */ struct ssllist { struct ssllist* next; /* must be first for compatibility with strlist */ char* str; /* ip address */ struct hashlist* hashes; /* zero or more hashes to check */ }; /** create config and read in */ struct cfg* cfg_create(const char* cfgfile); /** delete config */ void cfg_delete(struct cfg* cfg); /** setup SSL context for client usage, or NULL and error in err */ SSL_CTX* cfg_setup_ctx_client(struct cfg* cfg, char* err, size_t errlen); /** setup SSL on the connection, blocking, or NULL and string in err */ SSL* setup_ssl_client(SSL_CTX* ctx, int fd, char* err, size_t errlen); /** append to strlist, first=last=NULL to start empty. fatal if malloc fails */ void strlist_append(struct strlist** first, struct strlist** last, char* str); /** free strlist */ void strlist_delete(struct strlist* first); /** get nth element of strlist */ char* strlist_get_num(struct strlist* list, unsigned n); /** append to ssllist, first=last=NULL to start empty. fatal if malloc fails */ void ssllist_append(struct ssllist** first, struct ssllist** last, struct ssllist* e); /** free ssllist */ void ssllist_delete(struct ssllist* first); /** get nth element of ssllist */ struct ssllist* ssllist_get_num(struct ssllist* list, unsigned n); /** free hashlist */ void hashlist_delete(struct hashlist* first); /** prepend to hashlist */ void hashlist_prepend(struct hashlist** first, unsigned char* hash, unsigned int len); /** append to strlist2 */ void strlist2_append(struct strlist2** first, struct strlist2** last, char* s, char* t); /** free strlist2 */ void strlist2_delete(struct strlist2* first); /** have tcp80 or tcp443 configured */ int cfg_have_dnstcp(struct cfg* cfg); /** have ssl443 configured */ int cfg_have_ssldns(struct cfg* cfg); #ifdef UB_ON_WINDOWS /** * Obtain registry string (if it exists). * @param key: key string * @param name: name of value to fetch. * @return malloced string with the result or NULL if it did not * exist on an error (logged with log_err) was encountered. */ char* w_lookup_reg_str(const char* key, const char* name); #endif /* UB_ON_WINDOWS */ #endif /* CFG_H */ dnssec-trigger-0.13/riggerd/net_help.c0000664000175000017500000004102012433644532017403 0ustar wouterwouter/* * util/net_help.c - implementation of the network helper code * * Copyright (c) 2007, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * Implementation of net_help.h. */ #include "config.h" #include "net_help.h" #include "log.h" #include /** max length of an IP address (the address portion) that we allow */ #define MAX_ADDR_STRLEN 128 /* characters */ /** default value for EDNS ADVERTISED size */ uint16_t EDNS_ADVERTISED_SIZE = 4096; /* returns true is string addr is an ip6 specced address */ int str_is_ip6(const char* str) { if(strchr(str, ':')) return 1; else return 0; } int fd_set_nonblock(int s) { #ifdef HAVE_FCNTL int flag; if((flag = fcntl(s, F_GETFL)) == -1) { log_err("can't fcntl F_GETFL: %s", strerror(errno)); flag = 0; } flag |= O_NONBLOCK; if(fcntl(s, F_SETFL, flag) == -1) { log_err("can't fcntl F_SETFL: %s", strerror(errno)); return 0; } #elif defined(HAVE_IOCTLSOCKET) unsigned long on = 1; if(ioctlsocket(s, FIONBIO, &on) != 0) { log_err("can't ioctlsocket FIONBIO on: %s", wsa_strerror(WSAGetLastError())); } #endif return 1; } int fd_set_block(int s) { #ifdef HAVE_FCNTL int flag; if((flag = fcntl(s, F_GETFL)) == -1) { log_err("cannot fcntl F_GETFL: %s", strerror(errno)); flag = 0; } flag &= ~O_NONBLOCK; if(fcntl(s, F_SETFL, flag) == -1) { log_err("cannot fcntl F_SETFL: %s", strerror(errno)); return 0; } #elif defined(HAVE_IOCTLSOCKET) unsigned long off = 0; if(ioctlsocket(s, FIONBIO, &off) != 0) { log_err("can't ioctlsocket FIONBIO off: %s", wsa_strerror(WSAGetLastError())); } #endif return 1; } int is_pow2(size_t num) { if(num == 0) return 1; return (num & (num-1)) == 0; } void* memdup(void* data, size_t len) { void* d; if(!data) return NULL; if(len == 0) return NULL; d = malloc(len); if(!d) return NULL; memcpy(d, data, len); return d; } void log_addr(enum verbosity_value v, const char* str, struct sockaddr_storage* addr, socklen_t addrlen) { uint16_t port; const char* family = "unknown"; char dest[100]; int af = (int)((struct sockaddr_in*)addr)->sin_family; void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; if(verbosity < v) return; switch(af) { case AF_INET: family="ip4"; break; case AF_INET6: family="ip6"; sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr; break; case AF_UNIX: family="unix"; break; default: break; } if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) { strncpy(dest, "(inet_ntop error)", sizeof(dest)); } dest[sizeof(dest)-1] = 0; port = ntohs(((struct sockaddr_in*)addr)->sin_port); if(verbosity >= 4) verbose(v, "%s %s %s port %d (len %d)", str, family, dest, (int)port, (int)addrlen); else verbose(v, "%s %s port %d", str, dest, (int)port); } int extstrtoaddr(const char* str, struct sockaddr_storage* addr, socklen_t* addrlen) { char* s; int port = DNS_PORT; if((s=strchr(str, '@'))) { char buf[MAX_ADDR_STRLEN]; if(s-str >= MAX_ADDR_STRLEN) { return 0; } strncpy(buf, str, MAX_ADDR_STRLEN); buf[s-str] = 0; port = atoi(s+1); if(port == 0 && strcmp(s+1,"0")!=0) { return 0; } return ipstrtoaddr(buf, port, addr, addrlen); } return ipstrtoaddr(str, port, addr, addrlen); } int ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr, socklen_t* addrlen) { uint16_t p; if(!ip) return 0; p = (uint16_t) port; if(str_is_ip6(ip)) { struct sockaddr_in6* sa = (struct sockaddr_in6*)addr; *addrlen = (socklen_t)sizeof(struct sockaddr_in6); memset(sa, 0, *addrlen); sa->sin6_family = AF_INET6; sa->sin6_port = (in_port_t)htons(p); if(inet_pton((int)sa->sin6_family, ip, &sa->sin6_addr) <= 0) { return 0; } } else { /* ip4 */ struct sockaddr_in* sa = (struct sockaddr_in*)addr; *addrlen = (socklen_t)sizeof(struct sockaddr_in); memset(sa, 0, *addrlen); sa->sin_family = AF_INET; sa->sin_port = (in_port_t)htons(p); if(inet_pton((int)sa->sin_family, ip, &sa->sin_addr) <= 0) { return 0; } } return 1; } int netblockstrtoaddr(const char* str, int port, struct sockaddr_storage* addr, socklen_t* addrlen, int* net) { char* s = NULL; *net = (str_is_ip6(str)?128:32); if((s=strchr(str, '/'))) { if(atoi(s+1) > *net) { log_err("netblock too large: %s", str); return 0; } *net = atoi(s+1); if(*net == 0 && strcmp(s+1, "0") != 0) { log_err("cannot parse netblock: '%s'", str); return 0; } if(!(s = strdup(str))) { log_err("out of memory"); return 0; } *strchr(s, '/') = '\0'; } if(!ipstrtoaddr(s?s:str, port, addr, addrlen)) { free(s); log_err("cannot parse ip address: '%s'", str); return 0; } if(s) { free(s); addr_mask(addr, *addrlen, *net); } return 1; } int sockaddr_cmp(struct sockaddr_storage* addr1, socklen_t len1, struct sockaddr_storage* addr2, socklen_t len2) { struct sockaddr_in* p1_in = (struct sockaddr_in*)addr1; struct sockaddr_in* p2_in = (struct sockaddr_in*)addr2; struct sockaddr_in6* p1_in6 = (struct sockaddr_in6*)addr1; struct sockaddr_in6* p2_in6 = (struct sockaddr_in6*)addr2; if(len1 < len2) return -1; if(len1 > len2) return 1; log_assert(len1 == len2); if( p1_in->sin_family < p2_in->sin_family) return -1; if( p1_in->sin_family > p2_in->sin_family) return 1; log_assert( p1_in->sin_family == p2_in->sin_family ); /* compare ip4 */ if( p1_in->sin_family == AF_INET ) { /* just order it, ntohs not required */ if(p1_in->sin_port < p2_in->sin_port) return -1; if(p1_in->sin_port > p2_in->sin_port) return 1; log_assert(p1_in->sin_port == p2_in->sin_port); return memcmp(&p1_in->sin_addr, &p2_in->sin_addr, INET_SIZE); } else if (p1_in6->sin6_family == AF_INET6) { /* just order it, ntohs not required */ if(p1_in6->sin6_port < p2_in6->sin6_port) return -1; if(p1_in6->sin6_port > p2_in6->sin6_port) return 1; log_assert(p1_in6->sin6_port == p2_in6->sin6_port); return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr, INET6_SIZE); } else { /* eek unknown type, perform this comparison for sanity. */ return memcmp(addr1, addr2, len1); } } int sockaddr_cmp_addr(struct sockaddr_storage* addr1, socklen_t len1, struct sockaddr_storage* addr2, socklen_t len2) { struct sockaddr_in* p1_in = (struct sockaddr_in*)addr1; struct sockaddr_in* p2_in = (struct sockaddr_in*)addr2; struct sockaddr_in6* p1_in6 = (struct sockaddr_in6*)addr1; struct sockaddr_in6* p2_in6 = (struct sockaddr_in6*)addr2; if(len1 < len2) return -1; if(len1 > len2) return 1; log_assert(len1 == len2); if( p1_in->sin_family < p2_in->sin_family) return -1; if( p1_in->sin_family > p2_in->sin_family) return 1; log_assert( p1_in->sin_family == p2_in->sin_family ); /* compare ip4 */ if( p1_in->sin_family == AF_INET ) { return memcmp(&p1_in->sin_addr, &p2_in->sin_addr, INET_SIZE); } else if (p1_in6->sin6_family == AF_INET6) { return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr, INET6_SIZE); } else { /* eek unknown type, perform this comparison for sanity. */ return memcmp(addr1, addr2, len1); } } int addr_is_ip6(struct sockaddr_storage* addr, socklen_t len) { if(len == (socklen_t)sizeof(struct sockaddr_in6) && ((struct sockaddr_in6*)addr)->sin6_family == AF_INET6) return 1; else return 0; } void addr_mask(struct sockaddr_storage* addr, socklen_t len, int net) { uint8_t mask[8] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe}; int i, max; uint8_t* s; if(addr_is_ip6(addr, len)) { s = (uint8_t*)&((struct sockaddr_in6*)addr)->sin6_addr; max = 128; } else { s = (uint8_t*)&((struct sockaddr_in*)addr)->sin_addr; max = 32; } if(net >= max) return; for(i=net/8+1; isin6_addr; s2 = (uint8_t*)&((struct sockaddr_in6*)addr2)->sin6_addr; to = 16; } else { s1 = (uint8_t*)&((struct sockaddr_in*)addr1)->sin_addr; s2 = (uint8_t*)&((struct sockaddr_in*)addr2)->sin_addr; to = 4; } /* match = bits_in_common(s1, s2, to); */ for(i=0; i min) match = min; return match; } void addr_to_str(struct sockaddr_storage* addr, socklen_t addrlen, char* buf, size_t len) { int af = (int)((struct sockaddr_in*)addr)->sin_family; void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; if(addr_is_ip6(addr, addrlen)) sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr; if(inet_ntop(af, sinaddr, buf, (socklen_t)len) == 0) { snprintf(buf, len, "(inet_ntop_error)"); } } int addr_is_ip4mapped(struct sockaddr_storage* addr, socklen_t addrlen) { /* prefix for ipv4 into ipv6 mapping is ::ffff:x.x.x.x */ const uint8_t map_prefix[16] = {0,0,0,0, 0,0,0,0, 0,0,0xff,0xff, 0,0,0,0}; uint8_t* s; if(!addr_is_ip6(addr, addrlen)) return 0; /* s is 16 octet ipv6 address string */ s = (uint8_t*)&((struct sockaddr_in6*)addr)->sin6_addr; return (memcmp(s, map_prefix, 12) == 0); } int addr_is_broadcast(struct sockaddr_storage* addr, socklen_t addrlen) { int af = (int)((struct sockaddr_in*)addr)->sin_family; void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; return af == AF_INET && addrlen>=(socklen_t)sizeof(struct sockaddr_in) && memcmp(sinaddr, "\377\377\377\377", 4) == 0; } int addr_is_any(struct sockaddr_storage* addr, socklen_t addrlen) { int af = (int)((struct sockaddr_in*)addr)->sin_family; void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; void* sin6addr = &((struct sockaddr_in6*)addr)->sin6_addr; if(af == AF_INET && addrlen>=(socklen_t)sizeof(struct sockaddr_in) && memcmp(sinaddr, "\000\000\000\000", 4) == 0) return 1; else if(af==AF_INET6 && addrlen>=(socklen_t)sizeof(struct sockaddr_in6) && memcmp(sin6addr, "\000\000\000\000\000\000\000\000" "\000\000\000\000\000\000\000\000", 16) == 0) return 1; return 0; } void log_crypto_err(const char* str) { /* error:[error code]:[library name]:[function name]:[reason string] */ char buf[128]; unsigned long e; ERR_error_string_n(ERR_get_error(), buf, sizeof(buf)); log_err("%s crypto %s", str, buf); while( (e=ERR_get_error()) ) { ERR_error_string_n(e, buf, sizeof(buf)); log_err("and additionally crypto %s", buf); } } void* listen_sslctx_create(char* key, char* pem, char* verifypem) { SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method()); if(!ctx) { log_crypto_err("could not SSL_CTX_new"); return NULL; } /* no SSLv2 because has defects */ if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)){ log_crypto_err("could not set SSL_OP_NO_SSLv2"); SSL_CTX_free(ctx); return NULL; } if(!SSL_CTX_use_certificate_file(ctx, pem, SSL_FILETYPE_PEM)) { log_err("error for cert file: %s", pem); log_crypto_err("error in SSL_CTX use_certificate_file"); SSL_CTX_free(ctx); return NULL; } if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM)) { log_err("error for private key file: %s", key); log_crypto_err("Error in SSL_CTX use_PrivateKey_file"); SSL_CTX_free(ctx); return NULL; } if(!SSL_CTX_check_private_key(ctx)) { log_err("error for key file: %s", key); log_crypto_err("Error in SSL_CTX check_private_key"); SSL_CTX_free(ctx); return NULL; } if(verifypem && verifypem[0]) { if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL)) { log_crypto_err("Error in SSL_CTX verify locations"); SSL_CTX_free(ctx); return NULL; } SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file( verifypem)); SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); } return ctx; } void* connect_sslctx_create(char* key, char* pem, char* verifypem) { SSL_CTX* ctx = SSL_CTX_new(SSLv23_client_method()); if(!ctx) { log_crypto_err("could not allocate SSL_CTX pointer"); return NULL; } if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)) { log_crypto_err("could not set SSL_OP_NO_SSLv2"); SSL_CTX_free(ctx); return NULL; } if(key && key[0]) { if(!SSL_CTX_use_certificate_file(ctx, pem, SSL_FILETYPE_PEM)) { log_err("error in client certificate %s", pem); log_crypto_err("error in certificate file"); SSL_CTX_free(ctx); return NULL; } if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM)) { log_err("error in client private key %s", key); log_crypto_err("error in key file"); SSL_CTX_free(ctx); return NULL; } if(!SSL_CTX_check_private_key(ctx)) { log_err("error in client key %s", key); log_crypto_err("error in SSL_CTX_check_private_key"); SSL_CTX_free(ctx); return NULL; } } if(verifypem && verifypem[0]) { if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL)) { log_crypto_err("error in SSL_CTX verify"); SSL_CTX_free(ctx); return NULL; } SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); } return ctx; } void* incoming_ssl_fd(void* sslctx, int fd) { SSL* ssl = SSL_new((SSL_CTX*)sslctx); if(!ssl) { log_crypto_err("could not SSL_new"); return NULL; } SSL_set_accept_state(ssl); (void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); if(!SSL_set_fd(ssl, fd)) { log_crypto_err("could not SSL_set_fd"); SSL_free(ssl); return NULL; } return ssl; } void* outgoing_ssl_fd(void* sslctx, int fd) { SSL* ssl = SSL_new((SSL_CTX*)sslctx); if(!ssl) { log_crypto_err("could not SSL_new"); return NULL; } SSL_set_connect_state(ssl); (void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); if(!SSL_set_fd(ssl, fd)) { log_crypto_err("could not SSL_set_fd"); SSL_free(ssl); return NULL; } return ssl; } /** contact the server with TCP connect, for clients. returns fd */ int contact_server(const char* svr, int port, int statuscmd, char* err, size_t errlen) { struct sockaddr_storage addr; socklen_t addrlen; int fd; /* use svr or the first config entry */ if(!svr) { svr = "127.0.0.1"; /* config 0 addr (everything), means ask localhost */ if(strcmp(svr, "0.0.0.0") == 0) svr = "127.0.0.1"; else if(strcmp(svr, "::0") == 0 || strcmp(svr, "0::0") == 0 || strcmp(svr, "0::") == 0 || strcmp(svr, "::") == 0) svr = "::1"; } if(strchr(svr, '@')) { if(!extstrtoaddr(svr, &addr, &addrlen)) { snprintf(err, errlen, "could not parse IP: %s", svr); return -1; } } else { if(!ipstrtoaddr(svr, port, &addr, &addrlen)) { snprintf(err, errlen, "could not parse IP: %s", svr); return -1; } } fd = socket(addr_is_ip6(&addr, addrlen)?AF_INET6:AF_INET, SOCK_STREAM, 0); if(fd == -1) { #ifndef USE_WINSOCK snprintf(err, errlen, "socket: %s", strerror(errno)); #else snprintf(err, errlen, "socket: %s", wsa_strerror(WSAGetLastError())); #endif return -1; } if(connect(fd, (struct sockaddr*)&addr, addrlen) < 0) { #ifndef USE_WINSOCK snprintf(err, errlen, "connect: %s", strerror(errno)); if(errno == ECONNREFUSED && statuscmd) { close(fd); return -2; } close(fd); #else snprintf(err, errlen, "connect: %s", wsa_strerror(WSAGetLastError())); if(WSAGetLastError() == WSAECONNREFUSED && statuscmd) { closesocket(fd); return -2; } closesocket(fd); #endif return -1; } return fd; } dnssec-trigger-0.13/riggerd/rbtree.c0000664000175000017500000003755712275162157017116 0ustar wouterwouter/* * rbtree.c -- generic red black tree * * Copyright (c) 2001-2007, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** * \file * Implementation of a redblack tree. */ #include "config.h" #include "log.h" #include "rbtree.h" #include "fptr_wlist.h" /** Node colour black */ #define BLACK 0 /** Node colour red */ #define RED 1 /** the NULL node, global alloc */ rbnode_t rbtree_null_node = { RBTREE_NULL, /* Parent. */ RBTREE_NULL, /* Left. */ RBTREE_NULL, /* Right. */ NULL, /* Key. */ BLACK /* Color. */ }; /** rotate subtree left (to preserve redblack property) */ static void rbtree_rotate_left(rbtree_t *rbtree, rbnode_t *node); /** rotate subtree right (to preserve redblack property) */ static void rbtree_rotate_right(rbtree_t *rbtree, rbnode_t *node); /** Fixup node colours when insert happened */ static void rbtree_insert_fixup(rbtree_t *rbtree, rbnode_t *node); /** Fixup node colours when delete happened */ static void rbtree_delete_fixup(rbtree_t* rbtree, rbnode_t* child, rbnode_t* child_parent); /* * Creates a new red black tree, intializes and returns a pointer to it. * * Return NULL on failure. * */ rbtree_t * rbtree_create (int (*cmpf)(const void *, const void *)) { rbtree_t *rbtree; /* Allocate memory for it */ rbtree = (rbtree_t *) malloc(sizeof(rbtree_t)); if (!rbtree) { return NULL; } /* Initialize it */ rbtree_init(rbtree, cmpf); return rbtree; } void rbtree_init(rbtree_t *rbtree, int (*cmpf)(const void *, const void *)) { /* Initialize it */ rbtree->root = RBTREE_NULL; rbtree->count = 0; rbtree->cmp = cmpf; } /* * Rotates the node to the left. * */ static void rbtree_rotate_left(rbtree_t *rbtree, rbnode_t *node) { rbnode_t *right = node->right; node->right = right->left; if (right->left != RBTREE_NULL) right->left->parent = node; right->parent = node->parent; if (node->parent != RBTREE_NULL) { if (node == node->parent->left) { node->parent->left = right; } else { node->parent->right = right; } } else { rbtree->root = right; } right->left = node; node->parent = right; } /* * Rotates the node to the right. * */ static void rbtree_rotate_right(rbtree_t *rbtree, rbnode_t *node) { rbnode_t *left = node->left; node->left = left->right; if (left->right != RBTREE_NULL) left->right->parent = node; left->parent = node->parent; if (node->parent != RBTREE_NULL) { if (node == node->parent->right) { node->parent->right = left; } else { node->parent->left = left; } } else { rbtree->root = left; } left->right = node; node->parent = left; } static void rbtree_insert_fixup(rbtree_t *rbtree, rbnode_t *node) { rbnode_t *uncle; /* While not at the root and need fixing... */ while (node != rbtree->root && node->parent->color == RED) { /* If our parent is left child of our grandparent... */ if (node->parent == node->parent->parent->left) { uncle = node->parent->parent->right; /* If our uncle is red... */ if (uncle->color == RED) { /* Paint the parent and the uncle black... */ node->parent->color = BLACK; uncle->color = BLACK; /* And the grandparent red... */ node->parent->parent->color = RED; /* And continue fixing the grandparent */ node = node->parent->parent; } else { /* Our uncle is black... */ /* Are we the right child? */ if (node == node->parent->right) { node = node->parent; rbtree_rotate_left(rbtree, node); } /* Now we're the left child, repaint and rotate... */ node->parent->color = BLACK; node->parent->parent->color = RED; rbtree_rotate_right(rbtree, node->parent->parent); } } else { uncle = node->parent->parent->left; /* If our uncle is red... */ if (uncle->color == RED) { /* Paint the parent and the uncle black... */ node->parent->color = BLACK; uncle->color = BLACK; /* And the grandparent red... */ node->parent->parent->color = RED; /* And continue fixing the grandparent */ node = node->parent->parent; } else { /* Our uncle is black... */ /* Are we the right child? */ if (node == node->parent->left) { node = node->parent; rbtree_rotate_right(rbtree, node); } /* Now we're the right child, repaint and rotate... */ node->parent->color = BLACK; node->parent->parent->color = RED; rbtree_rotate_left(rbtree, node->parent->parent); } } } rbtree->root->color = BLACK; } /* * Inserts a node into a red black tree. * * Returns NULL on failure or the pointer to the newly added node * otherwise. */ rbnode_t * rbtree_insert (rbtree_t *rbtree, rbnode_t *data) { /* XXX Not necessary, but keeps compiler quiet... */ int r = 0; /* We start at the root of the tree */ rbnode_t *node = rbtree->root; rbnode_t *parent = RBTREE_NULL; fptr_ok(fptr_whitelist_rbtree_cmp(rbtree->cmp)); /* Lets find the new parent... */ while (node != RBTREE_NULL) { /* Compare two keys, do we have a duplicate? */ if ((r = rbtree->cmp(data->key, node->key)) == 0) { return NULL; } parent = node; if (r < 0) { node = node->left; } else { node = node->right; } } /* Initialize the new node */ data->parent = parent; data->left = data->right = RBTREE_NULL; data->color = RED; rbtree->count++; /* Insert it into the tree... */ if (parent != RBTREE_NULL) { if (r < 0) { parent->left = data; } else { parent->right = data; } } else { rbtree->root = data; } /* Fix up the red-black properties... */ rbtree_insert_fixup(rbtree, data); return data; } /* * Searches the red black tree, returns the data if key is found or NULL otherwise. * */ rbnode_t * rbtree_search (rbtree_t *rbtree, const void *key) { rbnode_t *node; if (rbtree_find_less_equal(rbtree, key, &node)) { return node; } else { return NULL; } } /** helpers for delete: swap node colours */ static void swap_int8(uint8_t* x, uint8_t* y) { uint8_t t = *x; *x = *y; *y = t; } /** helpers for delete: swap node pointers */ static void swap_np(rbnode_t** x, rbnode_t** y) { rbnode_t* t = *x; *x = *y; *y = t; } /** Update parent pointers of child trees of 'parent' */ static void change_parent_ptr(rbtree_t* rbtree, rbnode_t* parent, rbnode_t* old, rbnode_t* new) { if(parent == RBTREE_NULL) { log_assert(rbtree->root == old); if(rbtree->root == old) rbtree->root = new; return; } log_assert(parent->left == old || parent->right == old || parent->left == new || parent->right == new); if(parent->left == old) parent->left = new; if(parent->right == old) parent->right = new; } /** Update parent pointer of a node 'child' */ static void change_child_ptr(rbnode_t* child, rbnode_t* old, rbnode_t* new) { if(child == RBTREE_NULL) return; log_assert(child->parent == old || child->parent == new); if(child->parent == old) child->parent = new; } rbnode_t* rbtree_delete(rbtree_t *rbtree, const void *key) { rbnode_t *to_delete; rbnode_t *child; if((to_delete = rbtree_search(rbtree, key)) == 0) return 0; rbtree->count--; /* make sure we have at most one non-leaf child */ if(to_delete->left != RBTREE_NULL && to_delete->right != RBTREE_NULL) { /* swap with smallest from right subtree (or largest from left) */ rbnode_t *smright = to_delete->right; while(smright->left != RBTREE_NULL) smright = smright->left; /* swap the smright and to_delete elements in the tree, * but the rbnode_t is first part of user data struct * so cannot just swap the keys and data pointers. Instead * readjust the pointers left,right,parent */ /* swap colors - colors are tied to the position in the tree */ swap_int8(&to_delete->color, &smright->color); /* swap child pointers in parents of smright/to_delete */ change_parent_ptr(rbtree, to_delete->parent, to_delete, smright); if(to_delete->right != smright) change_parent_ptr(rbtree, smright->parent, smright, to_delete); /* swap parent pointers in children of smright/to_delete */ change_child_ptr(smright->left, smright, to_delete); change_child_ptr(smright->left, smright, to_delete); change_child_ptr(smright->right, smright, to_delete); change_child_ptr(smright->right, smright, to_delete); change_child_ptr(to_delete->left, to_delete, smright); if(to_delete->right != smright) change_child_ptr(to_delete->right, to_delete, smright); if(to_delete->right == smright) { /* set up so after swap they work */ to_delete->right = to_delete; smright->parent = smright; } /* swap pointers in to_delete/smright nodes */ swap_np(&to_delete->parent, &smright->parent); swap_np(&to_delete->left, &smright->left); swap_np(&to_delete->right, &smright->right); /* now delete to_delete (which is at the location where the smright previously was) */ } log_assert(to_delete->left == RBTREE_NULL || to_delete->right == RBTREE_NULL); if(to_delete->left != RBTREE_NULL) child = to_delete->left; else child = to_delete->right; /* unlink to_delete from the tree, replace to_delete with child */ change_parent_ptr(rbtree, to_delete->parent, to_delete, child); change_child_ptr(child, to_delete, to_delete->parent); if(to_delete->color == RED) { /* if node is red then the child (black) can be swapped in */ } else if(child->color == RED) { /* change child to BLACK, removing a RED node is no problem */ if(child!=RBTREE_NULL) child->color = BLACK; } else rbtree_delete_fixup(rbtree, child, to_delete->parent); /* unlink completely */ to_delete->parent = RBTREE_NULL; to_delete->left = RBTREE_NULL; to_delete->right = RBTREE_NULL; to_delete->color = BLACK; return to_delete; } static void rbtree_delete_fixup(rbtree_t* rbtree, rbnode_t* child, rbnode_t* child_parent) { rbnode_t* sibling; int go_up = 1; /* determine sibling to the node that is one-black short */ if(child_parent->right == child) sibling = child_parent->left; else sibling = child_parent->right; while(go_up) { if(child_parent == RBTREE_NULL) { /* removed parent==black from root, every path, so ok */ return; } if(sibling->color == RED) { /* rotate to get a black sibling */ child_parent->color = RED; sibling->color = BLACK; if(child_parent->right == child) rbtree_rotate_right(rbtree, child_parent); else rbtree_rotate_left(rbtree, child_parent); /* new sibling after rotation */ if(child_parent->right == child) sibling = child_parent->left; else sibling = child_parent->right; } if(child_parent->color == BLACK && sibling->color == BLACK && sibling->left->color == BLACK && sibling->right->color == BLACK) { /* fixup local with recolor of sibling */ if(sibling != RBTREE_NULL) sibling->color = RED; child = child_parent; child_parent = child_parent->parent; /* prepare to go up, new sibling */ if(child_parent->right == child) sibling = child_parent->left; else sibling = child_parent->right; } else go_up = 0; } if(child_parent->color == RED && sibling->color == BLACK && sibling->left->color == BLACK && sibling->right->color == BLACK) { /* move red to sibling to rebalance */ if(sibling != RBTREE_NULL) sibling->color = RED; child_parent->color = BLACK; return; } log_assert(sibling != RBTREE_NULL); /* get a new sibling, by rotating at sibling. See which child of sibling is red */ if(child_parent->right == child && sibling->color == BLACK && sibling->right->color == RED && sibling->left->color == BLACK) { sibling->color = RED; sibling->right->color = BLACK; rbtree_rotate_left(rbtree, sibling); /* new sibling after rotation */ if(child_parent->right == child) sibling = child_parent->left; else sibling = child_parent->right; } else if(child_parent->left == child && sibling->color == BLACK && sibling->left->color == RED && sibling->right->color == BLACK) { sibling->color = RED; sibling->left->color = BLACK; rbtree_rotate_right(rbtree, sibling); /* new sibling after rotation */ if(child_parent->right == child) sibling = child_parent->left; else sibling = child_parent->right; } /* now we have a black sibling with a red child. rotate and exchange colors. */ sibling->color = child_parent->color; child_parent->color = BLACK; if(child_parent->right == child) { log_assert(sibling->left->color == RED); sibling->left->color = BLACK; rbtree_rotate_right(rbtree, child_parent); } else { log_assert(sibling->right->color == RED); sibling->right->color = BLACK; rbtree_rotate_left(rbtree, child_parent); } } int rbtree_find_less_equal(rbtree_t *rbtree, const void *key, rbnode_t **result) { int r; rbnode_t *node; log_assert(result); /* We start at root... */ node = rbtree->root; *result = NULL; fptr_ok(fptr_whitelist_rbtree_cmp(rbtree->cmp)); /* While there are children... */ while (node != RBTREE_NULL) { r = rbtree->cmp(key, node->key); if (r == 0) { /* Exact match */ *result = node; return 1; } if (r < 0) { node = node->left; } else { /* Temporary match */ *result = node; node = node->right; } } return 0; } /* * Finds the first element in the red black tree * */ rbnode_t * rbtree_first (rbtree_t *rbtree) { rbnode_t *node; for (node = rbtree->root; node->left != RBTREE_NULL; node = node->left); return node; } rbnode_t * rbtree_last (rbtree_t *rbtree) { rbnode_t *node; for (node = rbtree->root; node->right != RBTREE_NULL; node = node->right); return node; } /* * Returns the next node... * */ rbnode_t * rbtree_next (rbnode_t *node) { rbnode_t *parent; if (node->right != RBTREE_NULL) { /* One right, then keep on going left... */ for (node = node->right; node->left != RBTREE_NULL; node = node->left); } else { parent = node->parent; while (parent != RBTREE_NULL && node == parent->right) { node = parent; parent = parent->parent; } node = parent; } return node; } rbnode_t * rbtree_previous(rbnode_t *node) { rbnode_t *parent; if (node->left != RBTREE_NULL) { /* One left, then keep on going right... */ for (node = node->left; node->right != RBTREE_NULL; node = node->right); } else { parent = node->parent; while (parent != RBTREE_NULL && node == parent->left) { node = parent; parent = parent->parent; } node = parent; } return node; } /** recursive descent traverse */ static void traverse_post(void (*func)(rbnode_t*, void*), void* arg, rbnode_t* node) { if(!node || node == RBTREE_NULL) return; /* recurse */ traverse_post(func, arg, node->left); traverse_post(func, arg, node->right); /* call user func */ (*func)(node, arg); } void traverse_postorder(rbtree_t* tree, void (*func)(rbnode_t*, void*), void* arg) { traverse_post(func, arg, tree->root); } dnssec-trigger-0.13/dnssec-trigger-control.c0000664000175000017500000002012212275162157020562 0ustar wouterwouter/* * dnssec-trigger-control.c - remote control utility for dnssec-trigger. * * Copyright (c) 2008, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * The remote control utility contacts the dnssec-trigger server over ssl */ #include "config.h" #ifdef HAVE_GETOPT_H #include #endif #ifdef HAVE_OPENSSL_SSL_H #include #endif #ifdef HAVE_OPENSSL_ERR_H #include #endif #ifdef HAVE_OPENSSL_RAND_H #include #endif #include #include "riggerd/log.h" #include "riggerd/cfg.h" #include "riggerd/net_help.h" /** Give dnssec-trigger-control usage, and exit (1). */ static void usage() { printf("Usage: dnssec-trigger-control [options] command\n"); printf(" Remote control utility for dnssec-trigger server.\n"); printf("Options:\n"); printf(" -c file config file, default is %s\n", CONFIGFILE); printf(" -s ip[@port] server address, if omitted config is used.\n"); printf(" -h show this usage help.\n"); printf("Commands:\n"); printf(" submit submit a list of DHCP provided DNS servers,\n"); printf(" separated by spaces, these are then probed.\n"); printf(" status shows the latest probe results\n"); printf(" reprobe probe again\n"); printf(" skip_http skip http probe, there is no hotspot login\n"); printf(" hotspot_signon force status into insecure\n"); printf(" do a reprobe command after signon\n"); printf(" unsafe test option that pretends that dnssec fails\n"); printf(" test_tcp test option that enables tcp mode\n"); printf(" test_ssl test option that enables ssl mode\n"); printf(" test_http test option that pretends that http fails\n"); printf(" test_update software update to the unstable test version\n"); printf(" results continuous feed of probe results\n"); printf(" cmdtray command channel for gui panel\n"); printf(" stoppanels connected panels quit (for installers)\n"); printf(" stop stop the daemon\n"); printf("Version %s\n", PACKAGE_VERSION); printf("BSD licensed, see LICENSE in source package for details.\n"); printf("Report bugs to %s\n", PACKAGE_BUGREPORT); exit(1); } /** exit with ssl error */ void ssl_err(const char* s) { fprintf(stderr, "error: %s\n", s); ERR_print_errors_fp(stderr); exit(1); } static SSL* global_ssl; static RETSIGTYPE sigh(int ATTR_UNUSED(sig)) { if(global_ssl) { SSL_shutdown(global_ssl); } } /** send stdin to server */ static void send_file(SSL* ssl, FILE* in, char* buf, size_t sz) { while(fgets(buf, (int)sz, in)) { if(SSL_write(ssl, buf, (int)strlen(buf)) <= 0) ssl_err("could not SSL_write contents"); } } /** send command and display result */ static int go_cmd(SSL* ssl, int argc, char* argv[]) { char pre[10]; const char* space=" "; const char* newline="\n"; int was_error = 0, first_line = 1; int r, i; char buf[1024]; snprintf(pre, sizeof(pre), "DNSTRIG%d ", CONTROL_VERSION); if(SSL_write(ssl, pre, (int)strlen(pre)) <= 0) ssl_err("could not SSL_write"); for(i=0; i0) if(SSL_write(ssl, argv[i], (int)strlen(argv[i])) <= 0) ssl_err("could not SSL_write"); } if(SSL_write(ssl, newline, (int)strlen(newline)) <= 0) ssl_err("could not SSL_write"); if(argc == 1 && strcmp(argv[0], "cmdtray") == 0) { send_file(ssl, stdin, buf, sizeof(buf)); } #ifndef UB_ON_WINDOWS /* line buffering does not work on windows */ setvbuf(stdout, NULL, (int)_IOLBF, 0); #endif while(1) { ERR_clear_error(); if((r = SSL_read(ssl, buf, (int)sizeof(buf)-1)) <= 0) { if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) { /* EOF */ break; } ssl_err("could not SSL_read"); } buf[r] = 0; printf("%s", buf); if(first_line && strncmp(buf, "error", 5) == 0) was_error = 1; first_line = 0; } return was_error; } /** go ahead and read config, contact server and perform command and display */ static int go(const char* cfgfile, char* svr, int argc, char* argv[]) { struct cfg* cfg; int fd, ret; SSL_CTX* ctx; SSL* ssl; char err[512]; /* read config */ if(!(cfg = cfg_create(cfgfile))) fatal_exit("could not get config file"); ctx = cfg_setup_ctx_client(cfg, err, sizeof(err)); if(!ctx) fatal_exit("%s", err); /* contact server */ fd = contact_server(svr, cfg->control_port, argc>0&&strcmp(argv[0],"status")==0, err, sizeof(err)); if(fd == -1) fatal_exit("%s", err); else if(fd == -2) { log_err("%s", err); printf("the daemon is stopped\n"); exit(3); /* statuscmd and server is down */ } ssl = setup_ssl_client(ctx, fd, err, sizeof(err)); if(!ssl) fatal_exit("%s", err); global_ssl = ssl; #ifdef SIGHUP (void)signal(SIGHUP, sigh); #endif #ifdef SIGPIPE (void)signal(SIGPIPE, sigh); #endif (void)signal(SIGINT, sigh); /* send command */ ret = go_cmd(ssl, argc, argv); SSL_free(ssl); #ifndef USE_WINSOCK close(fd); #else closesocket(fd); #endif SSL_CTX_free(ctx); cfg_delete(cfg); return ret; } /** getopt global, in case header files fail to declare it. */ extern int optind; /** getopt global, in case header files fail to declare it. */ extern char* optarg; /** Main routine for dnssec-trigger-control */ int main(int argc, char* argv[]) { int c, ret; const char* cfgfile = CONFIGFILE; char* svr = NULL; #ifdef USE_WINSOCK int r; WSADATA wsa_data; #endif log_ident_set("dnssec-trigger-control"); log_init(NULL, 0, NULL); #ifdef USE_WINSOCK if((r = WSAStartup(MAKEWORD(2,2), &wsa_data)) != 0) fatal_exit("WSAStartup failed: %s", wsa_strerror(r)); /* use registry config file in preference to compiletime location */ if(!(cfgfile=w_lookup_reg_str("Software\\DnssecTrigger", "ConfigFile"))) cfgfile = CONFIGFILE; #endif ERR_load_crypto_strings(); ERR_load_SSL_strings(); OpenSSL_add_all_algorithms(); (void)SSL_library_init(); if(!RAND_status()) { /* try to seed it */ unsigned char buf[256]; unsigned int v, seed=(unsigned)time(NULL) ^ (unsigned)getpid(); size_t i; for(i=0; i<256/sizeof(v); i++) { memmove(buf+i*sizeof(v), &v, sizeof(v)); v = v*seed + (unsigned int)i; } RAND_seed(buf, 256); log_warn("no entropy, seeding openssl PRNG with time"); } /* parse the options */ while( (c=getopt(argc, argv, "c:s:h")) != -1) { switch(c) { case 'c': cfgfile = optarg; break; case 's': svr = optarg; break; case '?': case 'h': default: usage(); } } argc -= optind; argv += optind; if(argc == 0) usage(); ret = go(cfgfile, svr, argc, argv); #ifdef USE_WINSOCK WSACleanup(); #endif return ret; } dnssec-trigger-0.13/dnssec-trigger-netconfig-hook.sh.in0000664000175000017500000000144012355255103022604 0ustar wouterwouter#!@SHELL@ # # dnssec trigger for netconfig # if we are in alternate root r="$ROOT" ifconfig="/sbin/ifconfig" # in files like /var/run/netconfig/eth0/netconfig0 # there is DNSSERVERS='192.168.254.254 192.168.254.254' netconfdir="$r/var/run/netconfig" # see which ifs are up ifs=`$ifconfig | awk '/^[a-z]/ { sub(/ .*$/,empty); iface=$0 } / UP / { print iface }'` ifs=`echo $ifs` logger "dnssec-trigger detected interfaces $ifs" # get DNS for ifs ips="" for i in $ifs; do if test -d $netconfdir/$i; then for f in $netconfdir/$i/*; do ips_now=`awk "/^DNSSERVERS=/ { sub(/DNSSERVERS='/,\"\"); sub(/'\$/,\"\"); print } " < $f ` ips="$ips $ips_now" done; fi done ips=`echo $ips` logger "dnssec-trigger(netconfig) detected $ifs DNS $ips" @sbindir@/dnssec-trigger-control submit "$ips" exit 0 dnssec-trigger-0.13/example.conf.in0000664000175000017500000000604412547735341016741 0ustar wouterwouter# config for dnssec-trigger @VERSION@. # this is a comment. there must be one statement per line. # logging detail, 0=only errors, 1=operations, 2=detail, 3,4 debug detail. # verbosity: 1 # pidfile location # pidfile: "@pidfile@" # log to a file instead of syslog, default is to syslog # logfile: "/var/log/dnssec-trigger.log" # log to syslog, or (log to to stderr or a logfile if specified). yes or no. # use-syslog: yes # chroot to this directory # chroot: "" # the unbound-control binary if not found in PATH. # commandline options can be appended "unbound-control -c my.conf" if you wish. # unbound-control: "@unbound_control_path@" # where is resolv.conf to edit. # resolvconf: "/etc/resolv.conf" # the domain example.com line (if any) to add to resolv.conf(5). default none. # domain: "" # domain name search path to add to resolv.conf(5). default none. # the search path from DHCP is not picked up, it could be used to misdirect. # search: "" # the command to run to open login pages on hot spots, a web browser. # empty string runs no command. # login-command: "@login_command@" # the url to open to get hot spot login, it gets overridden by the hotspot. # login-location: "@login_location@" # do not perform actions (unbound-control or resolv.conf), for a dry-run. # noaction: no # port number to use for probe daemon. # port: 8955 # these keys and certificates can be generated with the script # dnssec-trigger-control-setup # server-key-file: "@keydir@/dnssec_trigger_server.key" # server-cert-file: "@keydir@/dnssec_trigger_server.pem" # control-key-file: "@keydir@/dnssec_trigger_control.key" # control-cert-file: "@keydir@/dnssec_trigger_control.pem" # check for updates, download and ask to install them (for Windows, OSX). # check-updates: @check_updates@ # webservers that are probed to see if internet access is possible. # They serve a simple static page over HTTP port 80. It probes a random url: # after a space is the content expected on the page, (the page can contain # whitespace before and after this code). Without urls it skips http probes. # provided by NLnetLabs # It is provided on a best effort basis, with no service guarantee. url: "http://ster.nlnetlabs.nl/hotspot.txt OK" # provided by FedoraProject url: "http://fedoraproject.org/static/hotspot.txt OK" # fallback open DNSSEC resolvers that run on TCP port 80 and TCP port 443. # These relay incoming DNS traffic on the other port numbers to the usual DNS # the ssl443 adds an ssl server IP, you may also specify one or more hashes # the following on one line: ssl443:{} # hash is output of openssl x509 -sha256 -fingerprint -in server.pem # You can add more with extra config lines. # provided by NLnetLabs # It is provided on a best effort basis, with no service guarantee. tcp80: 185.49.140.67 tcp80: 2a04:b900::10:0:0:67 ssl443: 185.49.140.67 7E:CF:B4:BE:B9:9A:56:0D:F7:3B:40:51:A4:78:E6:A6:FD:66:0F:10:58:DC:A8:2E:C0:43:D4:77:5A:71:8A:CF ssl443: 2a04:b900::10:0:0:67 7E:CF:B4:BE:B9:9A:56:0D:F7:3B:40:51:A4:78:E6:A6:FD:66:0F:10:58:DC:A8:2E:C0:43:D4:77:5A:71:8A:CF dnssec-trigger-0.13/winrc/0000775000175000017500000000000013024457644015146 5ustar wouterwouterdnssec-trigger-0.13/winrc/gtkrc0000664000175000017500000000525211633623171016201 0ustar wouterwouter# this is based on the Mist scheme from gtk-engines-2.10 # it therefore has the same open-source license as that file. # it has been modified heavily. gtk-color-scheme = "bg_color:#eaeaea\nfg_color:#000\nbase_color:#fff\ntext_color:#000\nselected_fg_color:#fff\nselected_bg_color:#729fcf" style "default" { fg[NORMAL] = @fg_color fg[ACTIVE] = @fg_color fg[INSENSITIVE] = mix (0.4, @fg_color, shade (0.85, @bg_color)) #shaded to bg[INSENSITIVE] fg[PRELIGHT] = @fg_color fg[SELECTED] = @selected_fg_color bg[ACTIVE] = shade (0.9, @bg_color) bg[NORMAL] = @bg_color bg[INSENSITIVE] = shade (0.95, @bg_color) bg[PRELIGHT] = shade (1.03, @bg_color) bg[SELECTED] = @selected_bg_color base[NORMAL] = @base_color base[ACTIVE] = shade (0.9, @selected_bg_color) base[INSENSITIVE] = @base_color base[PRELIGHT] = @bg_color base[SELECTED] = @selected_bg_color text[NORMAL] = @text_color text[ACTIVE] = @text_color text[PRELIGHT] = @text_color text[SELECTED] = @selected_fg_color text[INSENSITIVE] = mix (0.5, @text_color, @base_color) GtkRange::trough_border = 0 GtkRange::slider_width = 15 GtkRange::stepper_size = 15 GtkScrollbar::min_slider_length = 15 GtkCheckButton::indicator_size=10 GtkCheckMenuItem::indicator_size=10 GtkRadioButton::indicator_size=12 GtkNotebook::tab_vborder = 1 GtkNotebook::tab_hborder = 1 xthickness = 1 ythickness = 1 GtkMenu::horizontal_padding=0 GtkMenu::vertical_padding=0 #engine "mist" # no need to load a binary engine. #{ #} } style "button" { bg[PRELIGHT] = "#ddddff" GtkWidget::focus_line_width = 1 } style "menuitem" { ythickness = 2 xthickness = 2 #text[PRELIGHT] = "#ffffff" #fg[PRELIGHT] = "#ffffff" #bg[PRELIGHT] = shade (0.8, @bg_color) bg[PRELIGHT] = "#ddddff" GtkMenuItem::selected_shadow_type=GTK_SHADOW_ETCHED_IN } style "menu" { ythickness = 2 xthickness = 2 } class "GtkWidget" style "default" class "GtkMenu" style "menu" class "GtkButton" style "button" class "*MenuItem*" style "menuitem" widget_class "*MenuItem*" style "menuitem" widget_class "*.GtkImageMenuItem.*" style "menuitem" widget_class "*.GtkAccelMenuItem.*" style "menuitem" widget_class "*.GtkRadioMenuItem.*" style "menuitem" widget_class "*.GtkCheckMenuItem.*" style "menuitem" widget_class "*.GtkMenu.*" style "menuitem" dnssec-trigger-0.13/winrc/panel.manifest0000664000175000017500000000172511636115055017774 0ustar wouterwouter dnssec-trigger user program dnssec-trigger-0.13/winrc/setup.nsi0000664000175000017500000003751412571003003017011 0ustar wouterwouter# The NSIS (http://nsis.sourceforge.net) install script. # This script is BSD licensed. # use default compression to make anti-virus programs life easier #SetCompressor /solid /final lzma !include LogicLib.nsh !include MUI2.nsh !include WinMessages.nsh !include FileFunc.nsh !insertmacro GetParameters !insertmacro GetOptions !define VERSION "0.0.0" !define QUADVERSION "0.0.0.0" outFile "dnssec_trigger_setup_${VERSION}.exe" Name "DnssecTrigger" # default install directory installDir "$PROGRAMFILES\DnssecTrigger" installDirRegKey HKLM "Software\DnssecTrigger" "InstallLocation" RequestExecutionLevel admin #give credits to Nullsoft: BrandingText "" VIAddVersionKey "ProductName" "Dnssec Trigger" VIAddVersionKey "CompanyName" "NLnet Labs" VIAddVersionKey "FileDescription" "(un)install dnssec-trigger" VIAddVersionKey "LegalCopyright" "Copyright 2011, NLnet Labs" VIAddVersionKey "FileVersion" "${QUADVERSION}" VIAddVersionKey "ProductVersion" "${QUADVERSION}" VIProductVersion "${QUADVERSION}" !addplugindir . ; typedef struct _RECT { ; LONG left; ; LONG top; ; LONG right; ; LONG bottom; ; } RECT, *PRECT; !define stRECT "(i, i, i, i) i" # http://nsis.sourceforge.net/Refresh_SysTray !macro RefreshSysTray ; $0: SysTray Window Handle FindWindow $0 "Shell_TrayWnd" "" FindWindow $0 "TrayNotifyWnd" "" $0 FindWindow $0 "SysPager" "" $0 FindWindow $0 "ToolbarWindow32" "" $0 ; Create RECT struct System::Call "*${stRECT} .r1" ; Get windows information System::Call "User32::GetWindowRect(i, i) i (i r0, r1) .r2" ; Get left/top/right/bottom coords ; $2: Left, $3: Top, $4: Right, $5: Bottom System::Call "*$1${stRECT} (.r2, .r3, .r4, .r5)" System::Free $1 ; $2: Width IntOp $2 $4 - $2 ; $3: Height IntOp $3 $5 - $3 ; $4: Small Icon Width System::Call 'User32::GetSystemMetrics(i 49) i .r4' ; $5: Small Icon Height System::Call 'User32::GetSystemMetrics(i 50) i .r5' ; $7: y - Start at the bottom IntOp $7 $4 / 2 IntOp $7 $3 - $7 LoopY: ; $6: X - Start at the right IntOp $6 $5 / 2 IntOp $6 $2 - $6 LoopX: SendMessage $0 ${WM_MOUSEMOVE} 0 "$6 | $7" IntOp $6 $6 - $4 IntCmp $6 0 EndLoopX EndLoopX LoopX EndLoopX: IntOp $7 $7 - $5 IntCmp $7 0 EndLoopY EndLoopY LoopY EndLoopY: !macroend # delete tray icon for panel. ;typedef struct _NOTIFYICONDATA { ; DWORD cbSize; ; HWND hWnd; ; UINT uID; ; UINT uFlags; ; UINT uCallbackMessage; ; HICON hIcon; ; TCHAR szTip[64]; ;} !define stNOTIFYICONDATA '(&l4, i, i, i, i, i, &t64) i' !define NIF_MESSAGE 0x00000001 !define NIF_ICON 0x00000002 !define NIF_TIP 0x00000004 !define NIM_ADD 0x00000000 !define NIM_MODIFY 0x00000001 !define NIM_DELETE 0x00000002 !macro DeleteTrayPanel ; $0: HWND of tray icon FindWindow $0 "dnssec trigger tray icon" "" "" #MessageBox MB_OK "panel found $0" ; 0 on failure ; this exits if no such tray icons exist IntCmp $0 0 EndLoopTray LoopTray: ; $1: NOTIFYICON structure System::Call "*${stNOTIFYICONDATA} .r1" ; fill in the structure (skip the tooltiptext, skip icon) System::Call "*$1${stNOTIFYICONDATA} (., r0, 5000, ${NIF_ICON}|${NIF_MESSAGE}|${NIF_TIP}, 0x401, 0)" ; tell tray to remove it System::Call 'Shell32::Shell_NotifyIcon(i ${NIM_DELETE}, i r1) i.r2' #MessageBox MB_OK "NIMDELETE $2" ; 1 on success, 0 on failure System::Free $1 ; find next tray icon FindWindow $0 "dnssec trigger tray icon" "" "" $0 IntCmp $0 0 EndLoopTray LoopTray LoopTray EndLoopTray: !macroend # Global Variables Var StartMenuFolder # use ReserveFile for files required before actual installation # makes the installer start faster #ReserveFile "System.dll" #ReserveFile "NsExec.dll" !define MUI_ICON "install.ico" !define MUI_UNICON "uninstall.ico" !define MUI_HEADERIMAGE !define MUI_HEADERIMAGE_RIGHT !define MUI_HEADERIMAGE_BITMAP "setup_top.bmp" !define MUI_WELCOMEFINISHPAGE_BITMAP "setup_left.bmp" !define MUI_ABORTWARNING #!define MUI_FINISHPAGE_NOAUTOCLOSE # so we can inspect install log. !insertmacro MUI_PAGE_WELCOME !insertmacro MUI_PAGE_LICENSE "..\LICENSE" !insertmacro MUI_PAGE_COMPONENTS !insertmacro MUI_PAGE_DIRECTORY !define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKLM" !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\DnssecTrigger" !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder" !define MUI_STARTMENUPAGE_DEFAULTFOLDER "DnssecTrigger" !insertmacro MUI_PAGE_STARTMENU DnssecTriggerStartMenu $StartMenuFolder !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_PAGE_FINISH !define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the uninstallation of Dnssec Trigger.$\r$\n$\r$\nClick Next to continue." !define MUI_UNWELCOMEFINISHPAGE_BITMAP "setup_left_un.bmp" !insertmacro MUI_UNPAGE_WELCOME !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES !insertmacro MUI_UNPAGE_FINISH !insertmacro MUI_LANGUAGE "English" # default section, one per component, we have one component. section "DnssecTrigger" SectionDnssecTrigger SectionIn RO # cannot unselect this one # real work in postinstall sectionEnd section "-hidden.postinstall" # check if unbound installed (but not via dnssec-trigger) ReadRegStr $R1 HKLM "Software\Unbound" "InstallLocation" StrCmp $R1 "" doinstall 0 ReadRegStr $R1 HKLM "Software\Unbound" "DnssecTrigger" StrCmp $R1 "yes" doinstall 0 # unbound installed but not ours, fail Abort "Unbound is already installed, please uninstall it" doinstall: # must stop dnssec-triggerd, panel and unbound to update their exe # (if installed). ReadRegStr $R1 HKLM "Software\Unbound" "InstallLocation" StrCmp $R1 "" donestop 0 DetailPrint "Stop tray icons" nsExec::ExecToLog '"$R1\dnssec-trigger-control.exe" stoppanels' DetailPrint "Stop dnssec-trigger daemon" nsExec::ExecToLog '"$R1\dnssec-triggerd.exe" -w stop' nsExec::ExecToLog '"$R1\dnssec-triggerd.exe" -c dnssectrigger -w waitstop' DetailPrint "Stop unbound daemon" nsExec::ExecToLog '"$R1\unbound.exe" -w stop' nsExec::ExecToLog '"$R1\dnssec-triggerd.exe" -c unbound -w waitstop' Sleep 1000 DetailPrint "Terminate processes" # if somehow not gone, remove the tray icons forcefully. # delete icons while HWNDs still exist. !insertmacro DeleteTrayPanel # killed 8 times, because there may be multiple users logged on. proc::KillProcess "dnssec-trigger-panel" proc::KillProcess "dnssec-trigger-panel" proc::KillProcess "dnssec-trigger-panel" proc::KillProcess "dnssec-trigger-panel" proc::KillProcess "dnssec-trigger-panel" proc::KillProcess "dnssec-trigger-panel" proc::KillProcess "dnssec-trigger-panel" proc::KillProcess "dnssec-trigger-panel" proc::KillProcess "dnssec-triggerd" proc::KillProcess "unbound" Sleep 3000 donestop: # copy files setOutPath $INSTDIR File "..\LICENSE" File "..\tmp.collect\README.txt" File /oname=dnssec-triggerd-temp.exe "..\dnssec-triggerd.exe" Delete dnssec-triggerd.exe Rename dnssec-triggerd-temp.exe dnssec-triggerd.exe File "..\dnssec-trigger-panel.exe" File "..\dnssec-trigger-control.exe" File "..\dnssec-trigger-keygen.exe" File /oname=unbound-temp.exe "..\tmp.collect\unbound.exe" Delete unbound.exe Rename unbound-temp.exe unbound.exe File "..\tmp.collect\unbound-control.exe" File "..\tmp.collect\unbound-anchor.exe" File "..\tmp.collect\unbound-host.exe" File "..\tmp.collect\unbound-checkconf.exe" File "/oname=unbound-new.conf" "..\tmp.collect\unbound.conf" File "..\winrc\alert.ico" File "..\winrc\status.ico" File "..\tmp.collect\*.dll" File "/oname=dnssec-trigger-new.conf" "..\example.conf" # store installation folder WriteRegStr HKLM "Software\DnssecTrigger" "InstallLocation" "$INSTDIR" WriteRegStr HKLM "Software\DnssecTrigger" "ConfigFile" "$INSTDIR\dnssec-trigger.conf" # no cron action at this time. WriteRegStr HKLM "Software\DnssecTrigger" "CronAction" "" WriteRegDWORD HKLM "Software\DnssecTrigger" "CronTime" 86400 # uninstaller WriteUninstaller "uninst.exe" # see if we are overwriting old IPs version Var /GLOBAL replaceconfig ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\DnssecTrigger" "DisplayName" # copy 19 characters "DnssecTigger 0.11x" for snapshots and rc versions. StrCpy $1 $0 19 StrCmp $1 "DnssecTrigger 0.11" replace_ips no_replace_ips StrCmp $1 "DnssecTrigger 0.10" replace_ips no_replace_ips StrCmp $1 "DnssecTrigger 0.11_" replace_ips no_replace_ips StrCmp $1 "DnssecTrigger 0.10_" replace_ips no_replace_ips StrCmp $1 "DnssecTrigger 0.11r" replace_ips no_replace_ips StrCmp $1 "DnssecTrigger 0.10r" replace_ips no_replace_ips replace_ips: StrCpy $replaceconfig "yes" goto replace_check_done no_replace_ips: StrCpy $replaceconfig "no" goto replace_check_done replace_check_done: # register uninstaller WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\DnssecTrigger" "DisplayName" "DnssecTrigger ${VERSION}" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\DnssecTrigger" "UninstallString" "$\"$INSTDIR\uninst.exe$\"" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\DnssecTrigger" "QuietUninstallString" "$\"$INSTDIR\uninst.exe$\" /S" WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\DnssecTrigger" "NoModify" "1" WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\DnssecTrigger" "NoRepair" "1" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\DnssecTrigger" "URLInfoAbout" "http://nlnetlabs.nl" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\DnssecTrigger" "Publisher" "NLnet Labs" # for a silent install (upgrade) config file changes make no # sense, right now. If we change the registry entries, # this will have to be fixed up here. # If the config file contains old IP addresses, then we have to setup # the config again. StrCmp $replaceconfig "yes" do_config_anyway IfSilent skip_config do_config_anyway: DetailPrint "Setup config files" Delete "$INSTDIR\unbound.conf" Rename "$INSTDIR\unbound-new.conf" "$INSTDIR\unbound.conf" Delete "$INSTDIR\dnssec-trigger.conf" Rename "$INSTDIR\dnssec-trigger-new.conf" "$INSTDIR\dnssec-trigger.conf" # setup unbound registry entries WriteRegStr HKLM "Software\Unbound" "InstallLocation" "$INSTDIR" WriteRegStr HKLM "Software\Unbound" "ConfigFile" "$INSTDIR\unbound.conf" WriteRegStr HKLM "Software\Unbound" "CronAction" "" # setup that unbound is 'ours' WriteRegStr HKLM "Software\Unbound" "DnssecTrigger" "yes" WriteRegDWORD HKLM "Software\Unbound" "CronTime" 86400 # setup unbound.conf ClearErrors FileOpen $R1 "$INSTDIR\unbound.conf" a IfErrors done_rk FileSeek $R1 0 END FileWrite $R1 "$\n$\nserver: auto-trust-anchor-file: $\"$INSTDIR\root.key$\"$\n" FileWrite $R1 "remote-control: control-enable: yes$\n" FileWrite $R1 " server-key-file: $\"$INSTDIR\unbound_server.key$\"$\n" FileWrite $R1 " server-cert-file: $\"$INSTDIR\unbound_server.pem$\"$\n" FileWrite $R1 " control-key-file: $\"$INSTDIR\unbound_control.key$\"$\n" FileWrite $R1 " control-cert-file: $\"$INSTDIR\unbound_control.pem$\"$\n" FileWrite $R1 "$\n" FileClose $R1 done_rk: WriteRegStr HKLM "Software\Unbound" "RootAnchor" "$\"$INSTDIR\unbound-anchor.exe$\" -a $\"$INSTDIR\root.key$\" -c $\"$INSTDIR\icannbundle.pem$\"" # write key locations to file ClearErrors FileOpen $R1 "$INSTDIR\dnssec-trigger.conf" a IfErrors done_keys FileSeek $R1 0 END FileWrite $R1 "$\n" FileWrite $R1 "server-key-file: $\"$INSTDIR\dnssec_trigger_server.key$\"$\n" FileWrite $R1 "server-cert-file: $\"$INSTDIR\dnssec_trigger_server.pem$\"$\n" FileWrite $R1 "control-key-file: $\"$INSTDIR\dnssec_trigger_control.key$\"$\n" FileWrite $R1 "control-cert-file: $\"$INSTDIR\dnssec_trigger_control.pem$\"$\n" FileWrite $R1 "$\n" FileClose $R1 done_keys: DetailPrint "Setup keys" # generate keys nsExec::ExecToLog '"$INSTDIR\dnssec-trigger-keygen.exe" -d "$INSTDIR"' # generate unbound keys nsExec::ExecToLog '"$INSTDIR\dnssec-trigger-keygen.exe" -u -d "$INSTDIR"' skip_config: # If silent (upgrade), then the start menu items can be left untouched # (in their original present/absent state). IfSilent skip_menu # start menu items !insertmacro MUI_STARTMENU_WRITE_BEGIN DnssecTriggerStartMenu CreateDirectory "$SMPROGRAMS\$StartMenuFolder" CreateShortCut "$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk" "$INSTDIR\uninst.exe" "" "" "" "" "" "Uninstall dnssec trigger" !insertmacro MUI_STARTMENU_WRITE_END skip_menu: # install unbound service entry DetailPrint "Start unbound daemon" nsExec::ExecToLog '"$INSTDIR\unbound.exe" -w install' nsExec::ExecToLog '"$INSTDIR\unbound.exe" -w start' # install service entry DetailPrint "Start dnssec-trigger daemon" nsExec::ExecToLog '"$INSTDIR\dnssec-triggerd.exe" -w install' # start service nsExec::ExecToLog '"$INSTDIR\dnssec-triggerd.exe" -w start' # register tray icon DetailPrint "Start tray icon" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Run" "DnssecTrigger" '"$INSTDIR\dnssec-trigger-panel.exe"' # start tray icon Exec '"$INSTDIR\dnssec-trigger-panel.exe"' # make sure 'old' tray icons disappear. !insertmacro RefreshSysTray # is selfdelete set? (/delself on commandline). ${GetParameters} $R0 ClearErrors ${GetOptions} $R0 /delself $0 IfErrors done_delself 0 # delete self (after reboot since we are currently opened to execute) Delete /REBOOTOK "$EXEPATH" done_delself: ClearErrors sectionEnd # set section descriptions LangString DESC_dnssectrigger ${LANG_ENGLISH} "The dnssec trigger package. $\r$\n$\r$\nStarts a service and a tray icon, logs to the Application Log, and the config file is its Program Files folder." !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${SectionDnssecTrigger} $(DESC_dnssectrigger) !insertmacro MUI_FUNCTION_DESCRIPTION_END # setup macros for uninstall functions. !ifdef UN !undef UN !endif !define UN "un." # uninstaller section section "un.DnssecTrigger" # remove tray icon from startup list DeleteRegValue HKLM "Software\Microsoft\Windows\CurrentVersion\Run" "DnssecTrigger" # stop tray icon DetailPrint "Remove tray icons" nsExec::ExecToLog '"$INSTDIR\dnssec-trigger-control.exe" stoppanels' # stop service DetailPrint "Remove dnssec-trigger daemon" nsExec::ExecToLog '"$INSTDIR\dnssec-triggerd.exe" -w stop' nsExec::ExecToLog '"$INSTDIR\dnssec-triggerd.exe" -c dnssectrigger -w waitstop' # uninstall service entry nsExec::ExecToLog '"$INSTDIR\dnssec-triggerd.exe" -w remove' # stop unbound service DetailPrint "Remove unbound daemon" nsExec::ExecToLog '"$INSTDIR\unbound.exe" -w stop' nsExec::ExecToLog '"$INSTDIR\dnssec-triggerd.exe" -c unbound -w waitstop' nsExec::ExecToLog '"$INSTDIR\unbound.exe" -w remove' # remove DNS override entries from registry nsExec::ExecToLog '"$INSTDIR\dnssec-triggerd.exe" -u' # give the panel time to process the messages. Sleep 2000 # remove tray icon if panel killed too fast to remove it itself. !insertmacro RefreshSysTray # give the panel time to process the messages. Sleep 1000 # deregister uninstall DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\DnssecTrigger" Delete "$INSTDIR\uninst.exe" # delete self Delete "$INSTDIR\LICENSE" Delete "$INSTDIR\README.txt" Delete "$INSTDIR\dnssec-triggerd.exe" Delete "$INSTDIR\dnssec-triggerd-temp.exe" Delete "$INSTDIR\dnssec-trigger-panel.exe" Delete "$INSTDIR\dnssec-trigger-control.exe" Delete "$INSTDIR\dnssec-trigger-keygen.exe" Delete "$INSTDIR\unbound.exe" Delete "$INSTDIR\unbound-temp.exe" Delete "$INSTDIR\unbound-control.exe" Delete "$INSTDIR\unbound-anchor.exe" Delete "$INSTDIR\unbound-host.exe" Delete "$INSTDIR\unbound-checkconf.exe" Delete "$INSTDIR\unbound.conf" Delete "$INSTDIR\unbound-new.conf" Delete "$INSTDIR\alert.ico" Delete "$INSTDIR\status.ico" Delete "$INSTDIR\*.dll" Delete "$INSTDIR\dnssec-trigger.conf" Delete "$INSTDIR\dnssec-trigger-new.conf" RMDir "$INSTDIR" # start menu items !insertmacro MUI_STARTMENU_GETFOLDER DnssecTriggerStartMenu $StartMenuFolder Delete "$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk" RMDir "$SMPROGRAMS\$StartMenuFolder" DeleteRegKey HKLM "Software\Unbound" DeleteRegKey HKLM "Software\DnssecTrigger" sectionEnd dnssec-trigger-0.13/winrc/setup_top.bmp0000664000175000017500000006233211632470213017664 0ustar wouterwouterBMd6(9dֽֽռԺ־ռ׿׿ҷֽֿ־־׿׿־׿Թ׿ֿ׿ԺԺ־׿ԺջջԺдԻԻ׿ͯջҷͯӸѵϳֽʪϳҷʫԻеϳ˭ˬҷ̮ɩϲϳαɩԺȧʩѶαˬҶˬֽ̭սԻ־ҶӹҸӹϲеӹΰѵӸӹ׾дԺ˫ѵαԼддֽͯɩΰʩҸαǤгҷʫ־̯ѵϱ̮ϳϲ̮Ť餥000--+NNM־ֽռ׿׾ӸպӹҸԻ׿ѴԺؿռ־ռϳҸѶβӹӸѶҷѵдӺҸαҷдϲΕ//.'(#,,*EH=ϳѵгˬ׿ɨϲαƤΰβʫͰв˫ʪΰ̭ˬҸӸԼƤ׾ռ־׿ؿӹԹԺӺԺ־Ѷռ׿ֽ־ջгӸѷαҸԻдӸѵϲԺѶϲӸггVWQ()&/.,,'6,##%ϳ˻©ֽ̭ʪΰαƤΰαˬ̭дɩɩϲˬ̭ҷӸӽǥHHF0*">(A+E.,& ~~{NNM;=7??><<;:;8??>;<7DECZ[Xuvs-)%A)D,G/7,!XYVOOO))'--*<70M>.WD2\G3bL5`K7XG5OC6950--),+*QRO׿׿־ּԺսռ־׿ջѶеӹ׾ҸӹϱѵӹΰҸҷԺеϳӹӹ󨬞#!?,F.I1?/*+%[\Y91'N<'_E-hL1iM2lP5oR7rU:vX93+,(ԻҶռҷӹ󝞚-&!J2P7 R9"V=%Y?'\A)`E,_F/TB/>5.0/-===?@?AAA??>56473/SE8qZCdImNpRtTwWvVTJ<-,+ֽֽ׿ռԺҷԺֽԺӸѷҸϲеԹе((%I3R8!T;#W=%[A)_D+Q?-.)!.0*kme~p|zNPF+,'K>0`DpRuVxX{[`l[F()$jn^ˬΰͯʫֽӹռӹԻӹ׽ΰҷдԺѶսҸӹеӸӸ׿̮ӹռԻΰ?A8D2 S:"V<$Z@(^D*C6'%%#ei\ƨսˬkp_&(#X?(uW6A3"kO5eH_sbN\N?}^_bghWD'(%}Ͱ̮־˫־־0/,Y>%Z@'`D+I;-DED󉉉-("`F.{^AuVb00/443^PA`dgjSJA@@?׿༽461S;']B)`E,[D.01,ּ--+L:(pT9kMbXM@664=>=YL=ihki95-z{y׿ӹּѵս־Ժ׿ԻԻֿӸռҷּֽͮ־ӸͰβҸջӸ792E7*`E+aF-gJ1,+$x|nֿ=?650)fK2bEzZrW$#Ʋ,.(q_LmlorX443ɽͯαռȦҸ̭ɧӸˬαԻռ־ҷҷռӸϲϲϱѵԺּѵѶռԺNPG51+^D,YC-M<,+)!wzoϲȦ$& R>+xZ>pQcOE6RTLkoa,,*x[nqlE?6qslϲӹαʫսдͮǽǥ%%%83-/0.221))(KKK>4*pS7hK`t\443TUTVK?nrt~jV,,+non ()&**);<7犌.+)aG.}_CvWj:74jkeƾ*)$~asvh/,(ջ־׿ռ־սսԺԺԺֿս׾ҸԺԻӷҸ־ӸԹqueLODUXNĬѵӹϲϲ350J9'sV;mNgeXF<<<˫ϲҸαʯNQFtaKtvx;6-TXKϱӸ̭̭ѶͰϳԺҷҷ׾ԺֽսջӸ׿ּս׿ջҶջԺҷӹջѶԺϱαеӹӹϲгlmf-&fL3dG}]}`('#ҷˬαսͯѷy}mG>2uxΧ^QB-/(ѶѵΰͯддΰռӸҸ)('Q?-z\@rTf]RD@A?뭰20+vÞzͧtbP12/IJI82+pT8iLa}b'&%򼾷220wŠ{ΨoY454־ֽֽ׿ؿӸҶѵֻ׿ռӸдҷѶռҷҷҷԹռҷдԺԻ̮ϳԹдҷϲzn222]F/bExXkLC8ce^˫ɩռ)+$wǡ|Ъq[,-)VYL((#)(%VVVȬϳˬӹ׿ֽռֽռֿջ׿־Ӹҷѵ׿ջ׾ջ־ϳջֽѴҷͰ׾ջѶҸռԺΰд֨пϳӹд>@7G9-x[>oQiqY24.ҷֽеΰ~83)žzɣ}խdXH**&@91]QAqZg()$)))LOḒҷӹͼZZX:;7???OPL̒,("iN5gI^m0/)mnj־ȱPRLbUDơ}˥ѫltġرṒҮ=92111))&SSS---110C;1D;2///ZZZ...RA0{^BuUncVI222TTS222222C=9nʤΨѫҫ֯رܴ޷ڴi\P111221///000410oS9wY=\K9:40...hhh71*oS9lNce30-DDD952kWoͧʤ̦Щҫծٲ޶ڴϫk]P...,,,000[H5tW;vY=}_Av\@ZJ:1-+PPP,,,ZG4eG{[maSGTTTzzz)))?;8sŠ{Ǣ}ɤΨ֮ݵҫuxcj[NG@8-,,UUU(((UF6yZ?y[?|_CaDeG~bHTH<>6.z\@rSgg///ppp,,,333hǡ|ͧխǣfaVJ@;62/-00/iii888;62lT>z\@hM2cH/jN4x[>fIkM_tE@:rrr,,,222tcRslYJD=555999FFF///4,%H1T:"`F,mP6z]AgIsTds[555~~~@@@877???[[[wwwOOO4-%B,P7]B*hM3uX=dFmOyYcblYG531PPP10.?'J2X=%cH/nR7tX?jLuV_ireyZTK?333OOOjjj3) F.R8!`D+WD3222321mZFy\enxy`hqYE>8*))KKK=*M4Z?'`G1210+++111333NE?w]tǢ|Ψgfjjn]M''&EEED0T;#bF-YF5/..***...111n]NƠ{ͨӭiijnj[L000===NNNJ5"[A(hL2jQ:100}}}VVV111t\̦ԭͪTKCu[jb;95111===dddD5'cH.oS8`C[M=21.???654^RFÞzЩ۴{:::555YMA_RF111+++[[[311iM3uX @g$0@g 0@gD$P @g$g(0@gң0@gt- 0@gt#0@gt 0@gttȃá 0@g$#1ɉȃÍt& 0@g(0@g0@g0@g0@g$ÍU<(WVS"1)č$, D$|$1DŽ$,(󫋄$P(D$$, $$, $Mu <([^_]Í$,(t$,D$D$4$(0@g $,($,$<$1D$$D$ tō$,(D$ $,D$D$<$0@gu$,D$ l$<$D$0@g`,$$, D$,$=6<$E1ہ<([^_]fU<,WVSr)č$, $P,D$|$1$,$T$DŽ$,,f$\$D$ i @gD$n @g[$, \$1ۉ$6$, $$,$$_u <,[^_]Í$,,t$,T$D$4$(0@g g$,,$,(<$$)1D$$D$ tō$,,$,T$ D$D$<$0@gu$,D$ l$<$D$0@g`,$$, T$,$!t$,$D$,$ &1D$<$Mt2D$s @g$$$<$xv1ہ<,[^_]WfU<WVS"1)č$,D$|$1DŽ$,󫋄$P$$,$D$ Tu<[^_]Ív$,l$,D$D$,$0@g $,$,D$$,&|$1fD$t$D$0@g t$,$t$D$ @gX$,$1$,T$$>ze V1ہ<[^_]Í&;S$ \$$0@g$$0@g$,0@g$(0@gN$6u"$D$ @g{[Ív$D$ @gY[ÐS$ \$$0@g$$0@g$,0@g$(0@g$Vu"$D$ @g.[Ív$D$ @g [ÐS$ \$$0@g$$0@g$,0@g$(0@g.$u"$D$ @g[[Ív$D$ @g|9[ÐQP=L$ r -=w) XYÐ%P@g%P@g%P@g%P@g%P@g%P@g%Q@g%P@g%Q@g%P@g%P@g%P@g%P@g%P@g%P@g%P@g%P@gPSAPI.DLLEnumProcessesEnumProcessModulesGetModuleBaseNameAEnumDeviceDriversGetDeviceDriverBaseNameA.exe%s%sShell_TrayWnd%S10o/OF@(@4@@@pO@Z@f@proc.dllFindDeviceFindProcessKillProcessdPRPP,RPPHRPPdRP QQ(Q:QHQXQfQzQQQQQQQQQQ QQ(Q:QHQXQfQzQQQQQQQQQQRCloseHandle`FreeLibraryAGetProcAddressGlobalFree1LoadLibraryAuOpenProcessTerminateProcesslstrcpyAS_strlwrsprintfstrcmpstrcpystrstrFindWindowAGetDesktopWindownUpdateWindow~wsprintfAPPPPPPPPKERNEL32.dllPmsvcrt.dll(P(P(P(Pmsvcrt.dll #endif #ifdef HAVE_OPENSSL_SSL_H #include #endif #ifdef HAVE_OPENSSL_ERR_H #include #endif #ifdef HAVE_OPENSSL_RAND_H #include #endif #include #include /** max length of filename */ #define FNAMESIZE 1024 /** Give dnssec-trigger-control usage, and exit (1). */ static void usage() { printf("Usage: dnssec-trigger-keygen [options]\n"); printf(" create keys for dnssec-trigger server.\n"); printf("Options:\n"); printf(" -d dir directory, default is %s\n", KEYDIR); printf(" -u set issuer and subject for unbound use.\n"); printf(" -h show this usage help.\n"); printf("Version %s\n", PACKAGE_VERSION); printf("BSD licensed, see LICENSE in source package for details.\n"); printf("Report bugs to %s\n", PACKAGE_BUGREPORT); exit(1); } /** exit with error */ static void fatal(const char* s) { fprintf(stderr, "error: %s\n", s); exit(1); } /** exit with ssl error */ void ssl_err(const char* s) { fprintf(stderr, "error: %s\n", s); ERR_print_errors_fp(stderr); exit(1); } /** setup names of issuer and subject */ static void setup_mode(int ubmode, char** servername, char** clientname, char** svr_base, char** ctl_base) { if(ubmode) { *servername = "unbound"; *clientname = "unbound-control"; *svr_base = "unbound_server"; *ctl_base = "unbound_control"; } else { *servername = "dnssec-trigger"; *clientname = "dnssec-trigger-control"; *svr_base = "dnssec_trigger_server"; *ctl_base = "dnssec_trigger_control"; } } /** true if file exists */ static int file_exists(const char* filename) { struct stat buf; if(stat(filename, &buf) < 0) { if(errno == ENOENT) return 0; printf("error: stat(%s): %s\n", filename, strerror(errno)); } return 1; } /** read pkey from file */ static EVP_PKEY* read_key(char* filename) { EVP_PKEY* pkey; BIO* bio = BIO_new(BIO_s_file()); if(!bio) fatal("cannot BIO_new"); if(BIO_read_filename(bio, filename) <= 0) ssl_err(filename); pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL); if(!pkey) ssl_err(filename); BIO_free(bio); return pkey; } /** generate key */ static EVP_PKEY* gen_key(int bits) { EVP_PKEY* pkey = NULL; EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); if(!ctx) ssl_err("cannot create EVP_PKEY_CTX"); if(EVP_PKEY_keygen_init(ctx) <= 0) ssl_err("cannot EVP_PKEY_keygen_init"); if(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) <= 0) ssl_err("cannot EVP_PKEY_CTX_set_rsa_keygen_bits"); if(EVP_PKEY_keygen(ctx, &pkey) <= 0) ssl_err("cannot EVP_PKEY_keygen"); EVP_PKEY_CTX_free(ctx); return pkey; } /** write private key to file */ static void write_key(EVP_PKEY* pkey, char* filename) { BIO* bio = BIO_new(BIO_s_file()); if(!bio) fatal("cannot BIO_new"); if(BIO_write_filename(bio, filename) <= 0) ssl_err(filename); if(PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL) <= 0) ssl_err(filename); BIO_free(bio); } /** make or read RSA key */ static EVP_PKEY* make_or_read_key(int bits, const char* keydir, const char* nm) { char filename[FNAMESIZE]; EVP_PKEY* pkey = NULL; snprintf(filename, sizeof(filename), "%s/%s.key", keydir, nm); if(file_exists(filename)) { pkey = read_key(filename); } else { pkey = gen_key(bits); write_key(pkey, filename); } return pkey; } static char* random_64bit_hex(void) { uint16_t r[4]; static char buf[32]; RAND_bytes((unsigned char*)r, 8); snprintf(buf, sizeof(buf), "0x%4.4x%4.4x%4.4x%4.4x", r[0], r[1], r[2], r[3]); return buf; } /** set issuer and subject to string */ static void set_issuer_and_subject(X509* x, char* str) { X509_NAME* nm = X509_NAME_new(); if(!nm) fatal("out of memory"); if(!X509_NAME_add_entry_by_txt(nm, "CN", MBSTRING_ASC, (unsigned char*)str, -1, -1, 0)) ssl_err("cannot X509_NAME_add_entry_by_txt"); if(!X509_set_issuer_name(x, nm)) ssl_err("cannot X509_set_issuer_name"); if(!X509_set_subject_name(x, nm)) ssl_err("cannot X509_set_subject_name"); X509_NAME_free(nm); } /** set to random serial number */ static void set_random_serial(X509* x) { ASN1_INTEGER* serial; serial = s2i_ASN1_INTEGER(NULL, random_64bit_hex()); if(!serial) ssl_err("cannot s2i_ASN1_INTEGER"); if(!X509_set_serialNumber(x, serial)) ssl_err("cannot X509_set_serialNumber"); ASN1_INTEGER_free(serial); } /** set time on cert */ static void set_dates(X509* x, int days) { if(!X509_gmtime_adj(X509_get_notBefore(x), 0)) ssl_err("cannot X509_gmtime_adj notBefore"); if(!X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL)) ssl_err("cannot X509_time_adj_ex notAfter"); } /** set attributes on selfsigned x509 */ static void set_selfsigned_attrs(X509* x, char* servername, int days, EVP_PKEY* skey) { set_issuer_and_subject(x, servername); set_dates(x, days); if(!X509_set_pubkey(x, skey)) ssl_err("cannot X509_set_pubkey"); set_random_serial(x); } /** write certificate to file */ static void cert_write(X509* x, const char* keydir, char* nm) { char filename[FNAMESIZE]; BIO* bio = BIO_new(BIO_s_file()); if(!bio) fatal("cannot BIO_new"); snprintf(filename, sizeof(filename), "%s/%s.pem", keydir, nm); if(BIO_write_filename(bio, filename) <= 0) ssl_err(filename); if(PEM_write_bio_X509(bio, x) <= 0) ssl_err(filename); BIO_free(bio); } /** create selfsigned server certificate */ static X509* make_selfsigned(char* hash, char* servername, int days, const char* keydir, char* svr_base, EVP_PKEY* skey) { X509* x = X509_new(); if(!x) fatal("cannot X509_new"); set_selfsigned_attrs(x, servername, days, skey); /* sign */ if(!X509_sign(x, skey, EVP_get_digestbyname(hash))) ssl_err("cannot X509_sign"); /* write */ cert_write(x, keydir, svr_base); return x; } /** set client attributes on the certificate */ static void set_client_attrs(X509* x, char* clientname, int days, EVP_PKEY* ckey) { set_issuer_and_subject(x, clientname); set_dates(x, days); if(!X509_set_pubkey(x, ckey)) ssl_err("cannot X509_set_pubkey"); set_random_serial(x); } /** create signed client certificate */ static void make_clientsigned(char* hash, char* clientname, int days, const char* keydir, char* ctl_base, EVP_PKEY* skey, EVP_PKEY* ckey, X509* scert) { X509* x = X509_new(); if(!x) fatal("cannot X509_new"); /* in script we made trusted_usage(scert) to please the openssl tool */ set_client_attrs(x, clientname, days, ckey); /* sign with ckey */ if(!X509_sign(x, ckey, EVP_get_digestbyname(hash))) ssl_err("cannot X509_sign"); /* sign with scert */ if(!X509_set_issuer_name(x, X509_get_subject_name(scert))) ssl_err("cannot X509_set_issuer_name"); if(!X509_sign(x, skey, EVP_get_digestbyname(hash))) ssl_err("cannot X509_sign"); cert_write(x, keydir, ctl_base); X509_free(x); } /** do the certificate generate */ static void do_gen(const char* keydir, int ubmode) { /* validity period for certificates */ int days = 7200; /* issuer and subject name for certificates */ char* servername; char* clientname; /* size of keys in bits */ int bits = 3072; /* hash algorithm */ char* hash = "sha256"; /* base name for files on disk */ char* svr_base; char* ctl_base; EVP_PKEY* skey, *ckey; X509* scert; setup_mode(ubmode, &servername, &clientname, &svr_base, &ctl_base); skey = make_or_read_key(bits, keydir, svr_base); ckey = make_or_read_key(bits, keydir, ctl_base); scert = make_selfsigned(hash, servername, days, keydir, svr_base, skey); make_clientsigned(hash, clientname, days, keydir, ctl_base, skey, ckey, scert); EVP_PKEY_free(skey); EVP_PKEY_free(ckey); X509_free(scert); } /** getopt global, in case header files fail to declare it. */ extern int optind; /** getopt global, in case header files fail to declare it. */ extern char* optarg; /** Main routine for dnssec-trigger-keygen */ int main(int argc, char* argv[]) { int c; const char* keydir = KEYDIR; int ubmode = 0; ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); (void)SSL_library_init(); if(!RAND_status()) { /* try to seed it */ unsigned char buf[256]; unsigned int v, seed=(unsigned)time(NULL) ^ (unsigned)getpid(); size_t i; for(i=0; i<256/sizeof(v); i++) { memmove(buf+i*sizeof(v), &v, sizeof(v)); v = v*seed + (unsigned int)i; } RAND_seed(buf, 256); printf("warning: no entropy, seeding openssl PRNG with time\n"); } /* parse the options */ while( (c=getopt(argc, argv, "d:hu")) != -1) { switch(c) { case 'd': keydir = optarg; break; case 'u': ubmode = 1; break; case '?': case 'h': default: usage(); } } argc -= optind; argv += optind; if(argc != 0) usage(); do_gen(keydir, ubmode); EVP_cleanup(); CRYPTO_cleanup_all_ex_data(); ERR_remove_state(0); ERR_free_strings(); RAND_cleanup(); return 0; } dnssec-trigger-0.13/winrc/win_svc.h0000664000175000017500000001144312275162157016771 0ustar wouterwouter/* * winrc/win_svc.h - windows services API implementation for dnssec-trigger * * Copyright (c) 2009, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains functions to integrate with the windows services API. * This means it handles the commandline switches to install and remove * the service (via CreateService and DeleteService), it handles * the ServiceMain() main service entry point when started as a service, * and it handles the Handler[_ex]() to process requests to the service * (such as start and stop and status). */ #ifndef WINRC_WIN_SVC_H #define WINRC_WIN_SVC_H struct comm_base; /** service name for unbound (internal to ServiceManager) */ #define SERVICE_NAME "dnssectrigger" /** from gen_msg.h - success message record for windows message log */ #define MSG_GENERIC_SUCCESS ((DWORD)0x20010001L) /** from gen_msg.h - informational message record for windows message log */ #define MSG_GENERIC_INFO ((DWORD)0x60010002L) /** from gen_msg.h - warning message record for windows message log */ #define MSG_GENERIC_WARN ((DWORD)0xA0010003L) /** from gen_msg.h - error message record for windows message log */ #define MSG_GENERIC_ERR ((DWORD)0xE0010004L) /** * Handle commandline service for windows. * @param wopt: windows option string (install, remove, service). * @param cfgfile: configfile to open (default or passed with -c). * @param v: amount of commandline verbosity added with -v. * @param c: true if cfgfile was set by commandline -c option. */ void wsvc_command_option(const char* wopt, const char* cfgfile, int v, int c); /** * Setup lead worker events. */ void wsvc_setup_worker(struct comm_base* base); /** * Desetup lead worker events. */ void wsvc_desetup_worker(void); /** windows worker stop event callback handler */ void worker_win_stop_cb(int fd, short ev, void* arg); /** windows cron timer callback handler */ void wsvc_cron_cb(void* arg); /** * Obtain registry string (if it exists). * @param key: key string * @param name: name of value to fetch. * @return malloced string with the result or NULL if it did not * exist on an error (logged) was encountered. */ char* lookup_reg_str(const char* key, const char* name); /** * Obtain registry binary data (if it exists). * @param key: key string * @param name: name of value to fetch. * @param len: (returned value on success) length of the binary data. * @return malloced binary data with the result or NULL if it did not * exist on an error (logged) was encountered. */ uint8_t* lookup_reg_binary(const char* key, const char* name, size_t* len); /** log a windows GetLastError message */ void log_win_err(const char* str, DWORD err); /** * Run command, and wait for result. * @param cmd: the command and arguments. * @return: return code of the program. If -1, errno. */ int win_run_cmd(char* cmd); /** * Set resolver to use on windows * @param ip: list of ips with spaces. */ void win_set_resolv(char* ip); /** * Remove resolver entry */ void win_clear_resolv(void); /** sets NameServer in HKEY(registry space) to the arg(string or NULL) */ void enum_reg_set_nameserver(HKEY hk, void* arg); /** fetch unbound-control name from registry (or NULL), struped result */ char* get_registry_unbound_control(void); #endif /* WINRC_WIN_SVC_H */ dnssec-trigger-0.13/winrc/dnssec-trigger64.png0000664000175000017500000001126111632423202020731 0ustar wouterwouterPNG  IHDR@@iqsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<.IDATxy\u?׵tUZޒt $! ,ǣ6Gǣ2*quXD0{:֮zޝ?StzK aF{N-*0  ӰNuT3 T5vmLAN H p=p%4)`3U4c}-6f{aI]<8duoЮ͉TվӴ  "E঒Z7ΘwNIqTb|~?^1>_1vďvmz9tj1ZQX~]Mr/_gǻ/_wT0a[+g]r,İƱd6q 6]w>0|Hr, ~LĐ+mq4vN vV,  ߽:\." D$ "?s"k 8! "XRV7ܰ^NcZm#pwoxȎ N&Θ8Ə69iXɪ޵8@#P7ϊH~K:&ҀB5rg5`s|O"6ؓN&ܾ>?u,5۶xe`_r'n䃣GEdipL" Ǔ3Łl_LXddcME[GˮHUcgP11jFD~MYճM+cYضiY/Tp3-:L8Wس\_ <Ϙ`z/+,4,Ǭn!qjYf6Qr, !#mv*oMUE|ٰء &#Gv ]ۂ%۶-1-L+kЗ%چVNcStJD4.>E5dlx4Q*n@i7gu5%JdǶ@UEUuxxX<^R:tҋCN.^>CNxnlkztoZOo{륹9NrdO9/<ūjj Vaib'lY1.چҊ0eaJd}ǀR2o䷞XP&aM޻%z`ؾP^[@9|e3T+ .fm߿w:өD x<^</a^W৓PʚPyGE]AEUWyYyuRc-;75ݿuN"LB^c<҉ݱsu*B~#C#7[i+zx}x>_uKWGgTgu|_[Ɉ.Z3svq]UkZqܣlݵ[W+Dѡw<xÒ%W=,T5m=DȪj|PùWlX"o eaZyۀTuI 3~wW5.Xm( ӴF/k`Ϛigà]/7}3BO Pmk%a߱={u|CU>puugy^# ^,[y{+"5MvpuSSj,"Ok~uqd2?}U]/]}Pe@(;78:v&% Od5&#"TѝڊK+qJԱӟ&!s4ɮ]W1%˴}^#Rk~0,iZ?s@w]0czpҷ75C]93HģX~$Uhpr5ʚmM/ƌոF{ʽIum%Us=x<иWoywс;D䩓m!yVWpNl/0Us"xPգcheG_2Ղd?N󀢦ECEUeO S&@D>("?}UD0z{;yA2$\X|e)uKK\WqsH_u@ تTcJGrDdDr7M Xꊼ~L~)p][VUGUuOs<YFcRDjF)^x>,k@"0<i>>4+u9u}^_l/ca*pK+jGp3 wE4˧Q/|ZYn!"+ ~tۼ&QCS =n} _U9uM]=+8kkmU-]D$ݲ7wtXulp"U:QySeض2&ӀE@Ina21 lcc߀m>T7JYU0`o}vɈx~oWy_uoI 1.Xo%"OfAUvx;v`0/pUV^wWe_vβ<pL_~5fozK $~."b:X7ш[h sV/òQ~G_~Cm'US8&$"_xt_Ua U x".O`8xuGO2C%q4Ɏ?|uKo0N= '\_IuPA|2^>{=KTݯ*"-N8_ Ȗٰ>>000000CCC666000000000000<<'A)C,F.;0&000sss???000000>>>>>>A EJMMMMMMMMMMMMMrrr000?)B*E-G/C1!000燇666000000630C90P@1>>>>>>>>>? ELMMMMMMMMMM000;,D,F.I0J300/III44400072.K<,ZC-bG.eJ0gL2 !> > !!99MMMMMMMM0007.%E-H0J2M481+00000072.L;*\B*_D+aF-dI/fK1iM3 !> >  !" EMMMMMMMHHH2/-G.I1L3N5A4'100C6)Y?&[A(^C*`E,cH.eJ0hL2jO4!" > >  !!"##>@@@@MMM000E0K2M4P7L7$J7'W>%Z@'\B)_D+bG-dI/gK1iN3jO5>> !!"##$$%>>---000?1$L3O6Q8!T:#V=%Y?'[A)^C+aF-cH/_G1L>1@82210>> !"#$$%% @ @nnn11191*N5P7 S9"U<$X>&Z@(]C*`E,\D/D90100000111SSS&&&*** E E "$%%& @ A.$000hhhWWW10/O6 R8!T;#W=%Y?'\B)^D+P?.210000PPPMMMMMMMM@@@@??33   %&& A A0&0&OF=000ccc000J6$S:"V<$X>&[A(]C*H:.000999MMMMMMMM@@@@@@;; !&'' A A1'2'bSJ@000qqq000B5)U;#W=%Z@'\B)R?-000IIIMMMMMMMM@@@@@@ $)  @ A1'2(eeLD=00044482,V<$Y?&[A(^C*E9.000MMMMMMMM@@@@66  "')! > @2'2(fhb864666bbb100V=&Z@(]B*_E,R@.000MMMMMMMM@@@@  %*! >>0&2(gikqY000PPP000M:)\A)^D+aF-`F/000YYYMMMMMMMM@@..  #( ' ?? E>2(ikmocVH000000B7,]C*`E,bG.eI0<60222MMMMMMMM>> !&+# 00@@M Djlnpi332FFF>>>73/_D+aF-`G/TB1<61000MMMMMMMM&&  $)!" @@@@MMpXmoqsi[L000sss000F:.;50000000000000MMMMMMML #',# 88@@@@MMEEED?9lprtm332NNN000000000000000000???MMMMMMM C !&+" ""@@@@@@MMMMM---000nXqsuw\QF000000000000000???MMMMMMJ> $) *"<<@@@@@@MMMMMHHH;;;E@:rtvxr\000ccccccjjjMMMMMMA>"',# ++@@@@@@@@MMMMMMMM000guwyq000gggMMM555>= %*!' ??@@@@@@@@MMMMMMMM000yfTwyÞ{ơ}GA<888JJJ==#( -$ 33@@@@@@@@@@MMMMMMMM555SJAxzŠ|Ǣ~YOE000+++=>!&+"" @@@@@@@@@@@@MMMMMMMMHHHF@;yğ{ơ}ɣeXK000> ?$)!-$99@@@@@@@@@@@@MMMMMMMMYYY<96ÞzŠ|Ȣ~ʥqaQ000ooo > ?',# %%@@@@@@@@@@@@@@MMMMMMMMYYY;85ğ{ǡ}ɤ̦vfU000fff666000000111|||000! ? @*"+# ==@@@@@@@@@@@@@@MMMMMMMM999QI@Ơ|ȣ~˥ͧaUI000000000211TLDxhW000000000󑑑|||RRR110% @ A-$ --@@@@@@@@@@@@@@@@MMMMMMMM000k\NǢ~ʤ̦ϩIC=GB>>---RRR000fɣ˥ϩΩ{ԭװڲܴ޷๒qbT000000000iii000000000B:2M@4110000\\\>>>31/hM4&," A B 55@@@@@@@@@@@@@@@@>> C?643iZLǢ}˥ΨЪҬӬ֯ر۳ݶ߸⺓o000000000EEE000000210hO8sV;kR;E=4000111zzz000Q?/wY>* 0& B A @@@@@@@@@@@@@@@@??>>#/'xơ|ʤͧϩҫҬծװڲܵ޷Ṓ㻔000000bbb:::000000NA4rU:uXz\@gR=<7300099922294.oS8eH.$4) B=;;@@@@@@@@@@@@@@@@$$ >?:/$;/%Š|Ȣ~ɤͧѪӭԭ֯ٱ۴ױun\PIB000000VVVQQQ---!1&4'5(7)8+9+9++$* 8+A2%1'7,"@>''@@@@@@@@@@@@@@@@@@ >>:/$;0%ZH8[J9\K9]L:^L;_N<_N=RD6=4+)$ @@@ #$%&&'(&#) /%5* 2) >@>>@@@@@@@@@@@@@@@@@@ >>5+!;0%<1&=2&>2'8.$,%+++<<_@@@@@@@@@@@@@@@@@@@@$$ N>8=: 84333 6=DK M M!!M;;MMMMgggIII%%% 2=<<=>> ? ? @ @ B A>C..@@@@@@@@@@@@@@@@@@@@?? F=>>>?B GKMMMMM!!MDDMMMMMMM$$$  8== e!# 11@@@@@@@@@@@@@@@@@@@@>>"" ,,55666655}MMM88MMMMMMMeee///"  *= > R$&) +",#% 88@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@33dMM**MIIMMMMQQQAAA2.+>'?*'  6 ? @q%*",$/&+") # ##==@@@@@@@@@@@@@@@@@@@@@@@@@@;;""MMM@@MMMMMMMzzz0006+!C,M4W=%H3!! % ? A I.%0'1') *!*!  ..@@@@@@@@@@@@@@@@@@@@??,,VMM33MLLMMMM\\\000<*I1S9"\B)aI120.3 A B_*"4*,#*!*"+"+" 11@@@@@@@@@@@@@@@@66oMM%%MFFMMMMNNNmmm1/.E-O6X>&bG.SB3000111)))!> C D+"*!+"+#,#-$ 99@@@@@@@@@@==%%NMM;;MMMMMMMooolll0//J2T;#^C*gL2QC5000BBB000!!!7-%$5C D O+",#,$)! --@@@@@@@@00\MM..MKKMMMMUUU{{{000O7!Z@'cH/mQ6aL:000gggքKKK,,,80(;/%=2&8.->@?f'-$ //@@@@99yMM!!MCCMMMMMMM000O:&_E,iM3rV;{]AD=6000AAAUUU000:75leRC4B6*B6+ !:> C 33>>))PMM77MMMMMMMddd000@6-eI0nR7x[?bEiL[M?964653TJAgğ{Χѫu]4,$ .=>O %%33cMM**MIIMMMMPPPaaa100bJ4tW<|_BgJpQyY`ipxʤӬܴ㼓SJAAAAJJJ$$18@@y""MMM@@MMMMMMMyyy000B:3vZ?dGlNuV~]fmuŠ|ϩذ๒|kZ000sss\\\MMMLLM22MMMMM22MLLMMMM\\\000A;4eJqRzZajry˥ԭݵze000OOO󔔔NNNMMMFFM%%M%%MFFMMMMNNN000>95v`K}]gnvǢ}Ѫr\RH000FFFmmmMMMMMMMMMMMMmmm888000643\PDyfTtcRn_PRJB000000jjjgggsss疖QQQ000000000000777ooo啕ggg^^^mmm𘘘ggg^^^yyyǠkkk___]]]ggg~~~ۢ{{{eee]]]bbbyyyNfӸTbҶɰ먵ƣÞ׾ɨ666}}}444111sss111$$$,,,RRRk]Ȧ}LҶ{Iռ~MZ׿~ȧϲÞ˫666WWWAAACCClll$$$ rrr Rǥrq<ׂSP傔T׿~ͮˬšٽǥƣ666,,,}}}<<<444nYʩO̬zH~MҶ[׿~ʩд̭666333mmmnnnBBB???,,,}}}%%%111مXo׿]ǥjּ˲Ȧšˬ666TTTMMM===}}}111111LLLXXX888777666 mmmwwwhhh}}}^^^ҙ999fff111 iiiCCC666VVVhhh}}}111ooo...p;~NǤwDtSƣ❫x}ϱğֽ666ZZZ hhh}}}EEE111:::edßyG|Kϱ~MЅW׿~ƢƤƣ̭ğɩ666||| hhh}}}Sǥrq<ւSP䂔T׿~ͮˬŢٽǥƣ666hhh}}}LLL+++vuRϱVyGOǥ`׿~ͯԹœΰ666///KKKhhh}}}:::RRR嘧qϚt˫ԹӾǥĠƤгͯӸ666dddhhh}}}!!! )))III666+++hhh}}}___ttt666 >>>hhh}}}Ҷr=wC⯻~Mc߁R׿~Ƥˬΰ̭ɨƣίϲ666CCChhh}}}___qqq_œiwC~M߁R׿~Ƥˬ篺ͺġȧ666QQQhhh}}}$$$Tǥqr=ցR߁R׿~Ƥˬ冀ﯺǤƣ666ꐐ222hhh}}} g|Kջ^yG߁R׿~ƤˬӹѴѴ666rrrhhh}}}UUU𫷋ŢެœҶԺ666hhh}}}ZZZ ###666jjj}}}LLLzzz666nnn}}}###ǥxFt@{I߁R萠ftαϝx{ӷǥƤǥ342XXXuuu}}}LLLaaa[Ġl{I߁RҶ} |ʪɩȧѳ꯺ǥ231YYY}}}gggVƣp{I߁Rвĝx̭˪ƤӴԺǥ231>>>FFF}}}\\\JJJZxE{I߁RێdÞֽǿȧ紿ͮǥ231}}}lllsssǥԺ̮ϲҷ666kkk999}}}kkk333``` 666}}} ,,,(((Ҷջ666&&&}}}|||uuuišrlN鉚]xv׿~Ƥˬ̮Þгֽ331}}}mmm>>>išs>ԀQOT׿~ƤˬҴۼƣƤ231OOO222}}}www TTT666išs?ӀPO߃T׿~ƤˬҳܼƣǤ231RRR 111}}}mmmnnn:::dddišufP시_sy׿~Ƥˬΰßΰ׿331ǡ}}}͡山ջ666}}}666}}}Թʪͮг666}}}iš{I߁RِfœƤˬǦšǥг׿666}}}iš{I߁RϲŝxƤˬӵǥ666}}}iš{I߁Rҷ||Ƥˬвǥ666}}}iš{I߁RꐠfqдƤˬԺǥͮѴ׿666}}}666}}}666}}}ȧּۨȯҷĠͯг׿ռ666}}}iš\yGՀQdϒiгֽǥѶ666}}}išr<ւSP䂔TßŜv̭˫Ţǥ666}}}išwD}L˫~NՄUϱy׾ĠȦȦ˫ǥ666}}}iš{IgxXmiۛuzǥίϲֽ666}}}VVV))))))))))))))))))))))))))))))t[[[[[[[[[[[[[[[[[ͯ[[[[[[[[[[[[[[[[[[[[[[[[[׈[[[[[[[[ռ[[[[[[[dռyyF`w%YqYqYqYqZr]u!n8]嫸|J_v#YqYqZrZrh~0Ys>YqYqYqYqYqYqYqYqYqZrYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqѵYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(k3YqYqYqYqYqYqYqYqYqYqYqYqYqZrm6^v"YqYqYqYqYqYqYqYqYqYqZrk4s>YqYqYqYqYqYqYqYqYqZrYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqѵYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(vBYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYq\syYqYqYqYqYqYqYqYqYqYqYqYqYqYqZrs>YqYqYqYqYqYqYqYqYqZrYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqѵYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(bx'YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqWѵZrYqYqYqYqYqYqYqYqYqYqYqYqYqYqZrs>YqYqYqYqYqYqYqYqYqʪ[rYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqѵYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(ax&YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqWuBYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqZrs>YqYqYqYqYqYqYqYqYqӷ\tYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqѵYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(t@YqYqYqYqYqYqYqYqYqZrxEßšyQ`w%YqYqYqYqWYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqZrs>YqYqYqYqYqYqYqYqYq^v"YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqѵYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(YqYqYqYqYqYqYqYqYquBơ~i1YqWšYqYqYqYqYqYqYqYqYqZrr=Qt@\tYqYqZrs>YqYqYqYqYqYqYqYqYqby'YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqѵYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(o9YqYqYqYqYqYqYqYq[ѴYqYqYqYqYqYqYqYql4ʪPZrs>YqYqYqYqYqYqYqYqYqf|-YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqԺ׿׿׿׿׿׿׿׿׿׿׿׿׿׿YqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(YqYqYqYqYqYqYqYqn8rYqYqYqYqYqYqYqYq˫s>YqYqYqYqYqYqYqYqYqj3YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(YqYqYqYqYqYqYqYqȧpYqYqYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYqp;YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(eYqYqYqYqYqYqYqYqxpYqYqYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYqvCYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(}LYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqͯpYqYqYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYq~NYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(uBYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqͯpYqYqYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYqWYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(yFYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqѵpYqYqYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYqdYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqSYqYqYqYqYqYqYqby(XYqYqYqYqYqYqYq_v#wEwEwEwEwEwEwEwEwE`w$YqYqYqYqYqYqYqpYqYqYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYqqYqYqYqYqYqYqYqYqYqYqYq]u!QYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqm7l4YqYqYqYqYqYqYqd{+{YqYqYqYqYqYqYqp:wCYqYqYqYqYqYqYqpYqYqYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqΰYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYq]ZrYqYqYqYqYqYqYqn7ͯYqYqYqYqYqYqYq\tax&YqYqYqYqYqYqk3pYqYqYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYqޭZrYqYqYqYqYqYqYqYqYqYqZrƤYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqbqYqYqYqYqYqYqYqYqO_v#YqYqYqYqYqYqYqӸYqYqYqYqYqYqYqspYqYqYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYq|ZrYqYqYqYqYqYqYqYqYqYqZrYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqi~0ȧVYqYqYqYqYqYqYqYqYqusYqYqYqYqYqYqYqby'r=YqYqYqYqYqYqYq⏟eYqYqYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYq̭`w$YqYqYqYqYqYqYqax&ϲr=YqYqYqYqYqYqYqT}YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqšs>YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqxYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYq`w%ĠZrYqYqYqYqYqYqYqYqZr[sZrYqYqYqYqYqYqYqYq`w$ǤZrYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqšs>YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqjYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqt@ZrYqYqYqYqYqYqYqYqYqYqYqYqYqYqZrYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqͯZrYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqšs>YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYq^YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqšZrYqYqYqYqYqYqYqYqYqYqYqYqt?]u!YqYqYqYqYqYqYqYqYqYqYqYqYqYqYq^u!ʪZrYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqšs>YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqSYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqšԹi1YqYqYqYqYqYqYqYqYqYqwD؈[ZrYqYqYqYqYqYqYqYqYqYqYqYq{JYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqšs>YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYq{IYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqg}.g}.g}.g}.g}.g}.g}.g}.ʩ󳾖uBZrYqYqYqYqZrr=צwD[sYqYqYqYqYqYqe{+kYqYqYqYqYqYqYqYqe{,g}.g}.g}.g}.g}.g}.g}.ɩs>YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqt?YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqϲϱؿֽϲαֽ|YqYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYqYqYqYqYqYqn8YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqxYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYqYqYqYqYqi1YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqsYqYqYqYqYqs>YqYqYqYqYqYqYqYqYqYqYqYqe{+YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqpYqYqYqYqs>YqYqYqYqYqYqYqYqYqYqYqax&YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqlYqYqYqs>YqYqYqYqYqYqYqYqYqYq^u"YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqiYqYqs>YqYqYqYqYqYqYqYqYq\sѵYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqeYqs>YqYqYqYqYqYqYqYqZrʩYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqջ^uAuAuAuAuAuAuAuAĠuAuAuAuAuAuAuAuAuAŢuAuAuAuAuAuAuAuAuAvCdnssec-trigger-0.13/winrc/combined.ico0000664000175000017500000007644611634044563017440 0ustar wouterwouter hF  00 %V@@ (B:(  % :'d.!I5#S?+H7&  P7W>&V>(:+=. XD0rRnV?i ?S:";**tdF~cJ|\gA/8) J6#t\E?kQ}dL zYzxΦ ~1jP7^L9 iUD4J*ڟ~^M0pmYE߉qX`G13'ymOF8+cܴծe 1%oQ5z]AnS2gS@-%C *<'E2!eJtpXB zTfH-滑fMTC3C I7&vWvh9a$A5'RC45 ?OÏ( @ G: ,G,J1  #+ ! o7$J1/  G2fJ/kN3oS7uW;z\?bD~`DZE1  G% M3F1/ aE*aE,hL1pS6mP6kQ6~_AeFgHjKtSpX?RQ7S:"Z?'`E,YA*";.!}aErSvV}\-#R8!V<$_D*9)4S:$lN^|\f<1$w?+[@'O9$W)y[>e ֌nRbm)!J8&^C*_E-jM2tTmWCŕwYhojL0gK1>-cFhڳlpu^H|  vX;^J<.SJRC2sȡ{8V=(lNcvƠzI;.5; ~_Bi$)uqWǡ|lSjiM3uVpUPr\F˥|_yc4%hIpSv_IΧbtyZ>_jUBpiϩev]֯͡W"O;(\M8%oPo6,!~fNҫϩծݴ㺒ʠbQ@cpT8y[>aC9, ބeGjE7+G ̥֭ϩܴܳibQ? !4&|_B{]AxZ>oU;jP7yYfÞyknZE*"~>O6cH.xZ>lNd,#Q AK2^C*qS8iJvVfm_K7Q :%V<$O:&'ٟ`nʥcfB5(P6eI. ɢ|֯kjœv Y?%nQ6=. 9.#ѩ˜}eKiU@f>,xZ>nOgQ/ P=+mT;jKmNmNqQyWpQC5&uvP6Q8!U;#X>&\B)eI.T<'% z _I4nPqSsTyZ_lU?HL3T:"V<$Z@'_E+=,Ib:(vX&^D*9)deI/~_CzZiNlPa_iiOm'\@&\B(X?' uAJ5 xZ=sSc  pShcnnXB>l [@']C*`F-"(mP5gIf[I8 ݒtWiioH:, 5 N7"bF,kN2?._X?){]@}[y\ U"祄dlpf h>-hK0^E-6'4%sV:mNhF8+ J;,춒nnœw]L: ~ hL1dGbnT<6ЎsVuuo ]71F2|^@tUj' 8-"뾙tuǠzH:-:x lO5hJhr\F)=ͧfwˤ}jQLV>(aD}\d lpZEȢ|̦l3 - xY=nPlZJ8 K<.̥ͥq AfcI0eHc`Tz?3'Ϩ̥u#G #@.bCvWn;0%~A4(ѪΧw)"u, <5 mQ6lNjmT9\K:ҫԭmPB2lTj >*1M8%bE|\n( +jy]ѩЪzeß}޵̙=2'$C2"% &{\?pRooZDY 'fR?ΧΨϩԭ߶߶ݵ录͢x_01$|\?xZ>P=* QcaH0iKej gT2(ᢂdơ{Ѫ˥ϩԭذ߶辕仓}fN@3k'mR7{\?xZ>bD{^BI8(4&bDwWsWF6$( ˤ}ʣ}ΧׯٱرͧgiVC4+!TZ@0 pT;bEbE`CeGoV<:,lQ7pQk}`K˴pԬwi}fOA6)t= N S>*dH.[A'cG.sV:eGjKzYr3) TL=0[I9&~P&3 N5[A(jN3wY>cFoP_vY S YZ*( U6"L3W>&iM2vW;dFjLvWbk}^M=-:I/Q8 cG-S>)."fO8{Z_gttdoR=1$#-3!N4^B)T=(H9+}^nw˦fgjhN$EF.V<#eI/1$*!ػsʤ~ԭpfiœvnSAL4]C)lP54'['ÞyҫڳgOyZsm7-"-L6 eI/uW;eL6|dLЩٲ޷ s\Ex`H .!pR6uY=iKv\B6*3)fNǡ{Щj}=OdK3dFkNzYfrşy˥߶۵4*!!^Z. sY?{ZbhtͧḏڳL?2 [G5sUhpwv\ + _+#*"x4RT? x`? ??>>?~< ?(@  2&@1 ' :% %AO\igS<% =&A)C,F.% DTj-<&B*E-G/9&|x *A0I6#O;'WA+YC-P<)F5$:,$oU.D,F.I0I1z =,V>(bG.eJ0gL2jN4lP6oS8rU:tWy\@|^By\A]G2;-  | E-H0J2M4  @.[A)_D+aF-dI/fK1iM3kP5nR7qT9sV;vY=x[?{]A|_BaDcFeHfIYD2 u G.I1L3N5/!0"Y?&[A(^C*`E,cH.eJ0hL2jO4mQ6pS8rU:uXz\@|_B~`CbEeGgIiKkMlNbL7,@*K2M4P7E0?+W>%Z@'\B)_D+bG-dI/gK1iN3iN4bI0]E/XC,]F0mR8y]@}_BaDdFfHhJjLmNoPqRqRI9)iG/L3O6Q8!T:#V=%Y?'[A)^C+aF-cH/[C,:+! ;- aK6dGiKlMoPqRsSuUwWw^D  N5P7 S9"U<$X>&Z@(]C*`E,W?), shkE5&gJpRsTuVwXxY{[vX-$N5R8!T;#W=%Y?'\B)^D+D1P2-cH/cFsTvWyYzZ|\~^}]3) qB-S:"V<$X>&[A(]C*5&O Y?'oR8dGvW{\yY{[}]_aa9.#:. U;#W=%Z@'\B)I5"$~<*gL2{]AoQ`kVA@3&wY^`bdd-#X V<$Y?&[A(^C*0#J(`E,tW;iKzZb ( ٚyZaceg}^ (U;$Z@(]B*_E,G4!oK5 lP6bEtUdPA2'ٝ}]dfhjgNeC/\A)^D+aF-^D-F$eI0x[?mO^x\s,#ڧdhjlnN?0X-,]C*`E,bG.eI0 V>(qT9fIxXh3) >zTC3䮋ikmoe _D+aF-^E-I5# f3$iN3}_CqRbgNρgNlnprVF5X1$  `F,vX=jM|\h! ֱkoqsiHD0nR7dGuVfhT@vk|dLprtvD7+!e10 fK1z]AnP`d !ֹqsuw}fN]P S;%sV;hJzZiK=/UxϞatvxnP+kO5aDsTcw[<lWC辚vxÞzơ|$ _D-xZ?lN~^l-%57,"wyŠ{Ǣ}>2&o;*pT9eHwXg~gO#xğzơ|ɣ~O@1 gL2|^BpRal  ÞyŠ{Ȣ}ʥ~_N<,+L7$uXkM}]mzbK#eQ>z^wơ|ʤͧϩҫҬծװڲܵ޷Ṓ㻔|:+rU:uXz\@^H2 t oS8eHvWgo qWF6wÞyŠ{Ȣ}ɤͧѪӭԭ֯ٱ۴װmq]I/' lR6tW;vY=y[?{^A}_B}`CP>, U>)|^BoQap]K:cxğzǡ|ɤ~̦ΨѪӭӭq|fO@4)] G5$sV1#)tW'G/Q8 [@(dI0lP5aH2aDlNtU}]dlsg_kO*"r :  C,M4W=%`E,T>) -#݄hL}]aipxy`bct]F Iw5"I1S9"\B)^E- \I9处dltơ|ϩidfhf]K::E-O6X>&bG.D2";/$ݷpx˥ԭnegikmWF6J2T;#^C*gL2?/ b-#ٽuǡ|ЪٲhfhjlbMM5Z@'cH/mQ6WA.){VF5Þy̦ծݶNB4K;,᠁akmA5(BgI3_E,iM3rV;{]A% ӨhȢ}ҫڳڳ  iT?lR2+'eI0nR7x[?bEhKH8( 9-#ܞağzΧ֯߸hj^E.tW<|_BgJpQyY`howʤ~Ӭܴ㼓B6*) n`7$uY=dGlNuV~]eltŠ{ϩذ๒lYFw!ڀcGqRzZaiqx˥ԭݵmV{mU?|\fmuǢ|ѪjA6*] E7)lWCdQ>[J:4*!i02/!???????@????qdnssec-trigger-0.13/winrc/trayicon.c0000664000175000017500000007245312275162157017154 0ustar wouterwouter/** * Trayicon.c -- show tray icon in system notification area. * * Copyright (c) 2011, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file is a windows WinMain() tray icon. It works as the * dnssec-trigger-panel that shows the state of dnssec. */ #include "config.h" #include #ifndef _WIN32_IE #define _WIN32_IE 0x0502 #endif #include #include #include #include #include "riggerd/log.h" #include "riggerd/cfg.h" #include "panel/attach.h" static UINT WM_TASKBARCREATED; static NOTIFYICONDATA notifydata; static TCHAR trayclassname[] = TEXT("dnssec trigger tray icon"); static TCHAR insecclassname[] = TEXT("Network DNSSEC Failure"); static TCHAR hotsignclassname[] = TEXT("Hotspot Signon"); static TCHAR nowebclassname[] = TEXT("No Web Access"); static TCHAR updateclassname[] = TEXT("Dnssec Trigger Software Update"); #define ID_TRAY_APP_ICON 5000 #define WM_TRAYICON (WM_USER + 1) #define WM_PANELALERT (WM_USER + 2) #define WM_PANELUPDATEALERT (WM_USER + 3) #define ID_TRAY_MENU_QUIT 3000 #define ID_TRAY_MENU_REPROBE 3001 #define ID_TRAY_MENU_PROBERESULTS 3002 #define ID_TRAY_MENU_HOTSPOTSIGNON 3003 static HWND mainwnd; static HMENU mainmenu; /* this one is small */ static HICON status_icon; /* high def version */ static HICON status_icon_big; /* alert icons */ static HICON status_icon_alert; static HICON status_icon_alert_big; /* the edit box with text list of probe results */ static HWND resultbox; /* the OK button on the probe results page */ static HWND resultok; /* the insecure window */ static HWND insec_wnd; /* insecure 'go insecure' button */ static HWND insec_unsafe; /* insecure 'disconnect' button */ static HWND insec_discon; /* the hotspot signon dialog */ static HWND hotsign_wnd; /* hotsign 'OK' button */ static HWND hotsign_ok; /* hotsign 'Cancel' button */ static HWND hotsign_cancel; /* the noweb dialog */ static HWND noweb_wnd; /* the 'Skip' button */ static HWND noweb_skip; /* the 'Login' button */ static HWND noweb_login; /* the update dialog */ static HWND update_wnd; /* the update text */ static HWND update_label; /* the 'OK' button on update */ static HWND update_ok; /* the 'Cancel' button on update */ static HWND update_cancel; /* new version for update */ static char* update_new_version; /** if we have asked about disconnect or insecure */ static int unsafe_asked = 0; /** if we should ask unsafe */ static int unsafe_should = 0; /** if we have asked about noweb */ static int noweb_asked = 0; static void panel_alert(void); static void panel_dialog(void); static void noweb_dialog(void); static void panel_update_alert(void); static HFONT font; static HFONT font_bold; static void init_font(void) { /* normal font */ font = CreateFont(16, 0, 0, 0, 550, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_TT_ONLY_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "MS Outlook"); if(!font) log_err("CreateFont failed"); font_bold = CreateFont(16, 0, 0, 0, 700, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_TT_ONLY_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "MS Outlook"); if(!font_bold) log_err("CreateFont failed"); } static void init_insecwnd(HINSTANCE hInstance) { HWND statictext; /* insecure window: * static text with explanation. * Disconnect and Insecure buttons */ insec_wnd = CreateWindowEx(0, insecclassname, TEXT("Network DNSSEC Failure"), WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 455, 450, NULL, NULL, hInstance, NULL); statictext = CreateWindow(TEXT("STATIC"), TEXT( "The Network Fails to Support DNSSEC\r\n" "\r\n" "The network you are connected to does not allow DNSSEC, via\r\n" "the provided DNS caches, nor via contacting servers on the\r\n" "internet directly (it filters traffic to this end). It is not possible\r\n" "to provide DNSSEC security, but you can connect insecurely.\r\n" "\r\n" "Do you want to connect insecurely?\r\n" "\r\n" "* if you choose Disconnect then DNS is disabled. It is safe,\r\n" "but there is very little that works.\r\n" "\r\n" "* if you choose Insecure then the DNSSEC security is lost.\r\n" "You can connect and work. But there is no safety. The network\r\n" "interferes with DNSSEC, it may also interfere with other things.\r\n" "Have caution and work with sensitive personal and financial\r\n" "things some other time.\r\n" "\r\n" "Some hotspots may work after you have gained access via\r\n" "its signon page. Then use Reprobe from the menu to retry.\r\n" "\r\n" "Stay safe out there!\r\n" ), WS_CHILD | WS_VISIBLE | SS_LEFT, 10, 10, 430, 370, insec_wnd, NULL, hInstance, NULL); insec_discon = CreateWindow(TEXT("BUTTON"), TEXT("Disconnect"), WS_CHILD | WS_VISIBLE, 180, 390, 100, 25, insec_wnd, NULL, hInstance, NULL); insec_unsafe = CreateWindow(TEXT("BUTTON"), TEXT("Insecure"), WS_CHILD | WS_VISIBLE, 300, 390, 100, 25, insec_wnd, NULL, hInstance, NULL); SendMessage(statictext, WM_SETFONT, (WPARAM)font, TRUE); SendMessage(insec_discon, WM_SETFONT, (WPARAM)font_bold, TRUE); SendMessage(insec_unsafe, WM_SETFONT, (WPARAM)font_bold, TRUE); ShowWindow(insec_wnd, SW_HIDE); } static void init_hotsignwnd(HINSTANCE hInstance) { HWND statictext; /* hotspot signon dialog: * static text with explanation. * Cancel and OK buttons */ hotsign_wnd = CreateWindowEx(0, hotsignclassname, TEXT("Hotspot Signon"), WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 455, 150, NULL, NULL, hInstance, NULL); statictext = CreateWindow(TEXT("STATIC"), TEXT( "Some networks need insecure signon. After you log in to the\r\n" "network via its portal page, select Reprobe to get secure again.\r\n" "\r\n" "Please, stay safe out there.\r\n" ), WS_CHILD | WS_VISIBLE | SS_LEFT, 10, 10, 430, 70, hotsign_wnd, NULL, hInstance, NULL); hotsign_cancel = CreateWindow(TEXT("BUTTON"), TEXT("Cancel"), WS_CHILD | WS_VISIBLE, 180, 90, 100, 25, hotsign_wnd, NULL, hInstance, NULL); hotsign_ok = CreateWindow(TEXT("BUTTON"), TEXT("OK"), WS_CHILD | WS_VISIBLE, 300, 90, 100, 25, hotsign_wnd, NULL, hInstance, NULL); SendMessage(statictext, WM_SETFONT, (WPARAM)font, TRUE); SendMessage(hotsign_cancel, WM_SETFONT, (WPARAM)font_bold, TRUE); SendMessage(hotsign_ok, WM_SETFONT, (WPARAM)font_bold, TRUE); ShowWindow(hotsign_wnd, SW_HIDE); } static void init_nowebwnd(HINSTANCE hInstance) { HWND statictext; /* no web access dialog: * static text with explanation. * Skip and Login buttons */ noweb_wnd = CreateWindowEx(0, nowebclassname, TEXT("No Web Access"), WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 455, 190, NULL, NULL, hInstance, NULL); statictext = CreateWindow(TEXT("STATIC"), TEXT( "There is no web access on this network. Do you have to login for that?\r\n" "\r\n" "While you login you are insecure, for backwards compatibility, until\r\n" "dnssec-trigger can detect web access.\r\n" "\r\n" "Skip this if you do not have to log in on this network.\r\n" ), WS_CHILD | WS_VISIBLE | SS_LEFT, 10, 10, 430, 110, noweb_wnd, NULL, hInstance, NULL); noweb_skip = CreateWindow(TEXT("BUTTON"), TEXT("Skip"), WS_CHILD | WS_VISIBLE, 190, 130, 100, 25, noweb_wnd, NULL, hInstance, NULL); noweb_login = CreateWindow(TEXT("BUTTON"), TEXT("Log in"), WS_CHILD | WS_VISIBLE, 310, 130, 100, 25, noweb_wnd, NULL, hInstance, NULL); SendMessage(statictext, WM_SETFONT, (WPARAM)font, TRUE); SendMessage(noweb_skip, WM_SETFONT, (WPARAM)font_bold, TRUE); SendMessage(noweb_login, WM_SETFONT, (WPARAM)font_bold, TRUE); ShowWindow(noweb_wnd, SW_HIDE); } static void init_updatewnd(HINSTANCE hInstance) { /* update dialog: * text with explanation (and version number) * Cancel and OK buttons */ update_wnd = CreateWindowEx(0, updateclassname, TEXT("Software Update Dnssec Trigger"), WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 455, 150, NULL, NULL, hInstance, NULL); update_label = CreateWindow(TEXT("STATIC"), TEXT( "There is a software update available for dnssec-trigger.\r\n" "Do you wish to install the update?\r\n" ), WS_CHILD | WS_VISIBLE | SS_LEFT, 10, 10, 430, 70, update_wnd, NULL, hInstance, NULL); update_cancel = CreateWindow(TEXT("BUTTON"), TEXT("Cancel"), WS_CHILD | WS_VISIBLE, 180, 90, 100, 25, update_wnd, NULL, hInstance, NULL); update_ok = CreateWindow(TEXT("BUTTON"), TEXT("OK"), WS_CHILD | WS_VISIBLE, 300, 90, 100, 25, update_wnd, NULL, hInstance, NULL); SendMessage(update_label, WM_SETFONT, (WPARAM)font, TRUE); SendMessage(update_cancel, WM_SETFONT, (WPARAM)font_bold, TRUE); SendMessage(update_ok, WM_SETFONT, (WPARAM)font_bold, TRUE); ShowWindow(update_wnd, SW_HIDE); } static void init_mainwnd(HINSTANCE hInstance) { /* probe results dialog: * multiline edit with the results. * OK button */ mainwnd = CreateWindowEx(0, trayclassname, TEXT("Probe Results"), WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 450, 280, NULL, NULL, hInstance, NULL); resultbox = CreateWindow(TEXT("EDIT"), TEXT("probe results"), WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_READONLY | ES_AUTOVSCROLL | ES_AUTOHSCROLL, 10, 10, 420, 195, mainwnd, NULL, hInstance, NULL); resultok = CreateWindow(TEXT("BUTTON"), TEXT("OK"), WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 290, 215, 100, 25, mainwnd, NULL, hInstance, NULL); SendMessage(resultbox, WM_SETFONT, (WPARAM)font, TRUE); SendMessage(resultok, WM_SETFONT, (WPARAM)font_bold, TRUE); } static void init_icon(void) { memset(¬ifydata, 0, sizeof(notifydata)); notifydata.cbSize = sizeof(notifydata); notifydata.hWnd = mainwnd; notifydata.uID = ID_TRAY_APP_ICON; /* flags for icon, wndmessage on click, and show tooltip */ notifydata.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; notifydata.uCallbackMessage = WM_TRAYICON; notifydata.hIcon = status_icon; /* tooltip (less than 64 chars) */ strcpy(notifydata.szTip, TEXT("dnssec-trigger")); if(!Shell_NotifyIcon(NIM_ADD, ¬ifydata)) { log_err("cannot Shell_NotifyIcon"); } } static void panel_proberesults(void) { char buf[102400]; fetch_proberesults(buf, sizeof(buf), "\r\n"); Edit_SetText(resultbox, buf); ShowWindow(mainwnd, SW_SHOW); } /* run software updater on windows: create the process */ static void win_run_updater(char* filename) { char* ubdir = w_lookup_reg_str("Software\\Unbound", "InstallLocation"); char cmdline[1024]; STARTUPINFO sinfo; PROCESS_INFORMATION pinfo; memset(&pinfo, 0, sizeof(pinfo)); memset(&sinfo, 0, sizeof(sinfo)); sinfo.cb = sizeof(sinfo); if(!ubdir) { log_err("out of memory or improper registry in reinstall, " "please reinstall manually"); return; } /* case sensitive /S and /D. /D must be last on the line and without quotes (even if there are spaces in the path) */ /* CMD /C shows UAC privilege elevation dialog to the user */ snprintf(cmdline, sizeof(cmdline), "CMD /C \"%s\" /S /delself /D=%s", filename, ubdir); free(ubdir); if(!CreateProcess(NULL, cmdline, NULL, NULL, 0, CREATE_NO_WINDOW, NULL, NULL, &sinfo, &pinfo)) log_err("CreateProcess Error %d for cmdline: %s", (int)GetLastError(), cmdline); /*log_win_err("CreateProcess failed", GetLastError());*/ else { /* we do not wait for this, it will attempt to stop the service to update this executable, so we need to go back to our runloop */ CloseHandle(pinfo.hProcess); CloseHandle(pinfo.hThread); } } /* start software updater given version number */ static void win_update_to_version(char* version) { char* uidir = w_lookup_reg_str("Software\\Unbound", "InstallLocation"); char fname[260]; if(!uidir) { log_err("out of memory or improper registry in reinstall, " "please reinstall manually"); return; } snprintf(fname, sizeof(fname), "%s\\dnssec_trigger_setup_%s.exe", uidir, version); free(uidir); win_run_updater(fname); } LRESULT CALLBACK InsecWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_SYSCOMMAND: switch(wParam & 0xfff0) { /* removes reserved lower 4 bits */ case SC_MINIMIZE: break; case SC_CLOSE: unsafe_asked = 1; unsafe_should = 0; attach_send_insecure(0); ShowWindow(insec_wnd, SW_HIDE); return 0; break; } break; case WM_COMMAND: /* buttons pressed */ if((HWND)lParam == insec_discon) { unsafe_asked = 1; unsafe_should = 0; attach_send_insecure(0); ShowWindow(insec_wnd, SW_HIDE); } else if((HWND)lParam == insec_unsafe) { unsafe_asked = 1; unsafe_should = 0; attach_send_insecure(1); ShowWindow(insec_wnd, SW_HIDE); } break; case WM_CLOSE: unsafe_asked = 1; unsafe_should = 0; attach_send_insecure(0); ShowWindow(insec_wnd, SW_HIDE); return 0; break; case WM_DESTROY: PostQuitMessage(0); break; } return DefWindowProc(hwnd, message, wParam, lParam); } LRESULT CALLBACK HotsignWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_SYSCOMMAND: switch(wParam & 0xfff0) { /* removes reserved lower 4 bits */ case SC_MINIMIZE: break; case SC_CLOSE: ShowWindow(hotsign_wnd, SW_HIDE); if(unsafe_should) panel_dialog(); return 0; break; } break; case WM_COMMAND: /* buttons pressed */ if((HWND)lParam == hotsign_cancel) { ShowWindow(hotsign_wnd, SW_HIDE); if(unsafe_should) panel_dialog(); } else if((HWND)lParam == hotsign_ok) { attach_send_hotspot_signon(); ShowWindow(hotsign_wnd, SW_HIDE); unsafe_asked = 1; unsafe_should = 0; } break; case WM_CLOSE: ShowWindow(hotsign_wnd, SW_HIDE); if(unsafe_should) panel_dialog(); return 0; break; case WM_DESTROY: PostQuitMessage(0); break; } return DefWindowProc(hwnd, message, wParam, lParam); } LRESULT CALLBACK NowebWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_SYSCOMMAND: switch(wParam & 0xfff0) { /* removes reserved lower 4 bits */ case SC_MINIMIZE: break; case SC_CLOSE: ShowWindow(noweb_wnd, SW_HIDE); attach_send_skip_http(); noweb_asked = 1; return 0; break; } break; case WM_COMMAND: /* buttons pressed */ if((HWND)lParam == noweb_skip) { ShowWindow(noweb_wnd, SW_HIDE); attach_send_skip_http(); noweb_asked = 1; } else if((HWND)lParam == noweb_login) { ShowWindow(noweb_wnd, SW_HIDE); attach_send_insecure(1); noweb_asked = 1; /* show web browser */ if(feed->cfg->login_command && feed->cfg->login_command[0]) { sleep(1); /* wait for DNS to percolate */ (void)ShellExecute(NULL, feed->cfg->login_command, feed->cfg->login_location, NULL, NULL, SW_SHOWNORMAL); } } break; case WM_CLOSE: ShowWindow(noweb_wnd, SW_HIDE); attach_send_skip_http(); noweb_asked = 1; return 0; break; case WM_DESTROY: PostQuitMessage(0); break; } return DefWindowProc(hwnd, message, wParam, lParam); } LRESULT CALLBACK UpdateWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_SYSCOMMAND: switch(wParam & 0xfff0) { /* removes reserved lower 4 bits */ case SC_MINIMIZE: break; case SC_CLOSE: ShowWindow(update_wnd, SW_HIDE); attach_send_update_cancel(); return 0; break; } break; case WM_COMMAND: /* buttons pressed */ if((HWND)lParam == update_cancel) { ShowWindow(update_wnd, SW_HIDE); attach_send_update_cancel(); } else if((HWND)lParam == update_ok) { ShowWindow(update_wnd, SW_HIDE); attach_send_update_ok(); if(update_new_version) win_update_to_version(update_new_version); free(update_new_version); update_new_version = NULL; } break; case WM_CLOSE: ShowWindow(update_wnd, SW_HIDE); attach_send_update_cancel(); return 0; break; case WM_DESTROY: PostQuitMessage(0); break; } return DefWindowProc(hwnd, message, wParam, lParam); } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { if(message==WM_TASKBARCREATED) { Shell_NotifyIcon(NIM_ADD, ¬ifydata); return 0; } switch(message) { case WM_CREATE: /* create the menu */ mainmenu = CreatePopupMenu(); AppendMenu(mainmenu, MF_STRING, ID_TRAY_MENU_REPROBE, TEXT("Reprobe")); AppendMenu(mainmenu, MF_STRING, ID_TRAY_MENU_PROBERESULTS, TEXT("Probe Results")); AppendMenu(mainmenu, MF_STRING, ID_TRAY_MENU_HOTSPOTSIGNON, TEXT("Hotspot Signon")); AppendMenu(mainmenu, MF_SEPARATOR, 0, NULL); AppendMenu(mainmenu, MF_STRING, ID_TRAY_MENU_QUIT, TEXT("Quit")); break; case WM_SYSCOMMAND: switch(wParam & 0xfff0) { /* removes reserved lower 4 bits */ case SC_MINIMIZE: break; case SC_CLOSE: ShowWindow(mainwnd, SW_HIDE); return 0; break; } break; /* our own systray message */ case WM_TRAYICON: if(wParam != ID_TRAY_APP_ICON) { /* warning: not from our tray icon */ } /* left mousebutton press */ if(lParam == WM_LBUTTONUP) { /* left mouse on tray icon */ break; } else if(lParam == WM_RBUTTONDOWN) { POINT cur; GetCursorPos(&cur); /* make our popup show on top */ SetForegroundWindow(hwnd); /* sends WM_COMMAND with the chosen menu item */ if(!TrackPopupMenu(mainmenu, 0, cur.x, cur.y, 0, hwnd, NULL)) { log_err("cannot TrackPopupmenu"); } /* force task switch to the app of the menu, this * is an empty message to achieve it */ PostMessage(hwnd, WM_NULL, 0, 0); } break; /* our own panel alert message */ case WM_PANELALERT: panel_alert(); break; /* our own panel update alert message */ case WM_PANELUPDATEALERT: panel_update_alert(); break; case WM_COMMAND: /* result window OK */ if((HWND)lParam == resultok) { ShowWindow(mainwnd, SW_HIDE); } /* menu item is chosen */ if(lParam == 0) { if(wParam == ID_TRAY_MENU_QUIT) { PostQuitMessage(0); } else if(wParam == ID_TRAY_MENU_REPROBE) { attach_send_reprobe(); } else if(wParam == ID_TRAY_MENU_PROBERESULTS) { panel_proberesults(); } else if(wParam == ID_TRAY_MENU_HOTSPOTSIGNON) { if(IsWindowVisible(insec_wnd)) { ShowWindow(insec_wnd, SW_HIDE); } ShowWindow(hotsign_wnd, SW_SHOW); SetForegroundWindow(hotsign_wnd); } } break; case WM_CLOSE: ShowWindow(mainwnd, SW_HIDE); return 0; break; case WM_DESTROY: PostQuitMessage(0); break; } return DefWindowProc(hwnd, message, wParam, lParam); } static void panel_danger(void) { notifydata.hIcon = status_icon_alert; if(!Shell_NotifyIcon(NIM_MODIFY, ¬ifydata)) { log_err("cannot Shell_NotifyIcon modify icon"); } } static void panel_safe(void) { notifydata.hIcon = status_icon; if(!Shell_NotifyIcon(NIM_MODIFY, ¬ifydata)) { log_err("cannot Shell_NotifyIcon modify icon"); } } static void panel_dialog(void) { unsafe_should = 1; if(IsWindowVisible(hotsign_wnd)) return; /* wait for hotspot signon question to finish */ ShowWindow(insec_wnd, SW_SHOW); SetForegroundWindow(insec_wnd); } static void noweb_dialog(void) { ShowWindow(noweb_wnd, SW_SHOW); SetForegroundWindow(noweb_wnd); } static void update_dialog(char* new_version) { char update_text[1024]; snprintf(update_text, sizeof(update_text), "There is a software update available for dnssec-trigger\r\n" "from %s to %s.\r\n" "Do you wish to install the update now?\r\n", PACKAGE_VERSION, new_version); if(!SetWindowText(update_label, update_text)) log_err("Could not SetWindowText: %s", wsa_strerror(GetLastError())); ShowWindow(update_wnd, SW_SHOW); SetForegroundWindow(update_wnd); free(update_new_version); update_new_version = strdup(new_version); } static void do_args(char* str, int* debug, const char** cfgfile) { char* p = str; /* find ' -dEOS' or ' -d ' or ' -c ' */ while(p && *p) { while(*p == ' ') p++; if(strcmp(p, "-d") == 0 || strncmp(p, "-d ", 3) == 0) { *debug = 1; } else if(strncmp(p, "-c ", 3) == 0) { p += 3; while(*p == ' ') p++; *cfgfile = strdup(p); continue; } p = strchr(p, ' '); } } static const char* get_ui_file(int debug, const char* uidir, const char* file) { static char res[1024]; if(debug) snprintf(res, sizeof(res), "winrc\\%s", file); else snprintf(res, sizeof(res), "%s\\%s", uidir, file); return res; } static RETSIGTYPE record_sigh(int sig) { if(sig == SIGINT) { PostQuitMessage(0); } /* else ignored */ } /* the threading and mutexes */ typedef LONG lock_basic_t; static lock_basic_t feed_lock; static lock_basic_t alert_lock; static struct alert_arg alertinfo; static char* updateinfo; static HANDLE feed_thread; void lock_basic_init(lock_basic_t* lock) { /* implement own lock, because windows HANDLE as Mutex usage * uses too many handles and would bog down the whole system. */ (void)InterlockedExchange(lock, 0); } void lock_basic_destroy(lock_basic_t* lock) { (void)InterlockedExchange(lock, 0); } void lock_basic_lock(lock_basic_t* lock) { LONG wait = 1; /* wait 1 msec at first */ while(InterlockedExchange(lock, 1)) { /* if the old value was 1 then if was already locked */ Sleep(wait); /* wait with sleep */ wait *= 2; /* exponential backoff for waiting */ } /* the old value was 0, but we inserted 1, we locked it! */ } void lock_basic_unlock(lock_basic_t* lock) { /* unlock it by inserting the value of 0. xchg for cache coherency. */ (void)InterlockedExchange(lock, 0); } static void lock_feed_lock(void) { lock_basic_lock(&feed_lock); } static void unlock_feed_lock(void) { lock_basic_unlock(&feed_lock); } static void feed_quit(void) { /* post a message to the main window (in another thread) */ PostMessage(mainwnd, WM_DESTROY, 0, 0); } static void panel_update_alert(void) { /* get info */ char* new_version = NULL; lock_basic_lock(&alert_lock); new_version = updateinfo; updateinfo = NULL; lock_basic_unlock(&alert_lock); if(!new_version) return; update_dialog(new_version); free(new_version); } static void feed_update_alert(char* new_version) { lock_basic_lock(&alert_lock); free(updateinfo); updateinfo = new_version; lock_basic_unlock(&alert_lock); /* post a message to the main window, so that it gets received * by the main thread, since it has to do the GUI functions */ if(!PostMessage(mainwnd, WM_PANELUPDATEALERT, 0, 0)) log_err("could not PostMessage"); } static void panel_alert(void) { /* get info */ struct alert_arg a; lock_basic_lock(&alert_lock); a = alertinfo; lock_basic_unlock(&alert_lock); /* update tooltip */ snprintf(notifydata.szTip, sizeof(notifydata.szTip), "%s", state_tooltip(&a)); if(!Shell_NotifyIcon(NIM_MODIFY, ¬ifydata)) { log_err("cannot Shell_NotifyIcon modify"); } /* handle it */ process_state(&a, &unsafe_asked, &noweb_asked, &panel_danger, &panel_safe, &panel_dialog, &noweb_dialog); if(!a.now_dark) unsafe_should = 0; } static void feed_alert(struct alert_arg* a) { lock_basic_lock(&alert_lock); alertinfo = *a; lock_basic_unlock(&alert_lock); /* post a message to the main window, so that it gets received * by the main thread, since it has to do the GUI functions */ if(!PostMessage(mainwnd, WM_PANELALERT, 0, 0)) log_err("could not PostMessage"); } static void* feed_start(void* arg) { attach_start((struct cfg*)arg); return NULL; } static void spawn_feed(struct cfg* cfg) { /* setup */ attach_create(); lock_basic_init(&feed_lock); lock_basic_init(&alert_lock); feed->lock = &lock_feed_lock; feed->unlock = &unlock_feed_lock; feed->quit = &feed_quit; feed->alert = &feed_alert; feed->update_alert = &feed_update_alert; /* run thread */ #ifndef HAVE__BEGINTHREADEX feed_thread = CreateThread(NULL, /* default security (no inherit handle) */ 0, /* default stack size */ (LPTHREAD_START_ROUTINE)&feed_start, cfg, 0, /* default flags, run immediately */ NULL); /* do not store thread identifier anywhere */ #else /* the begintheadex routine setups for the C lib; aligns stack */ feed_thread=(HANDLE)_beginthreadex(NULL, 0, (void*)&feed_start, cfg, 0, NULL); #endif if(feed_thread == NULL) { /*log_win_err("CreateThread failed", GetLastError());*/ fatal_exit("thread create failed"); } } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR args, int iCmdShow) { MSG msg; WNDCLASSEX wnd; INITCOMMONCONTROLSEX icc; int debug = 0; const char* cfgfile = NULL; const char* uidir = NULL; int r; int smsz = 0; WSADATA wsa_data; struct cfg* cfg; (void)hPrevInstance; (void)iCmdShow; /* init wsa and log */ log_ident_set("dnssec-trigger-panel"); log_init(NULL, 0, NULL); if((r = WSAStartup(MAKEWORD(2,2), &wsa_data)) != 0) fatal_exit("WSAStartup failed: %s", wsa_strerror(r)); /* inits common controls for vista/7 GUI looks */ memset(&icc, 0, sizeof(icc)); icc.dwSize = sizeof(icc); icc.dwICC = ICC_WIN95_CLASSES | ICC_STANDARD_CLASSES; InitCommonControlsEx(&icc); ERR_load_crypto_strings(); ERR_load_SSL_strings(); OpenSSL_add_all_algorithms(); (void)SSL_library_init(); /* get args */ cfgfile = w_lookup_reg_str("Software\\DnssecTrigger", "ConfigFile"); if(!cfgfile) cfgfile = CONFIGFILE; uidir = w_lookup_reg_str("Software\\DnssecTrigger", "InstallLocation"); if(!uidir) uidir = UIDIR; do_args(args, &debug, &cfgfile); cfg = cfg_create(cfgfile); if(!cfg) fatal_exit("cannot read config %s", cfgfile); /* start signal handlers */ if( signal(SIGTERM, record_sigh) == SIG_ERR || #ifdef SIGQUIT signal(SIGQUIT, record_sigh) == SIG_ERR || #endif #ifdef SIGBREAK signal(SIGBREAK, record_sigh) == SIG_ERR || #endif #ifdef SIGHUP signal(SIGHUP, record_sigh) == SIG_ERR || #endif #ifdef SIGPIPE signal(SIGPIPE, SIG_IGN) == SIG_ERR || #endif signal(SIGINT, record_sigh) == SIG_ERR ) log_err("install sighandler failed: %s\n", strerror(errno)); /* if the taskbar crashes and is restarted (explorer.exe) then this * message is sent so we can re-enter ourselves */ WM_TASKBARCREATED = RegisterWindowMessageA("TaskbarCreated"); if(GetSystemMetrics(SM_CXSMICON) > 16) smsz = 32; status_icon = (HICON)LoadImage(NULL, get_ui_file(debug, uidir, "status.ico"), IMAGE_ICON, smsz, smsz, LR_LOADFROMFILE); status_icon_big = (HICON)LoadImage(NULL, get_ui_file(debug, uidir, "status.ico"), IMAGE_ICON, 64, 64, LR_LOADFROMFILE); status_icon_alert = (HICON)LoadImage(NULL, get_ui_file(debug, uidir, "alert.ico"), IMAGE_ICON, smsz, smsz, LR_LOADFROMFILE); status_icon_alert_big = (HICON)LoadImage(NULL, get_ui_file(debug, uidir, "alert.ico"), IMAGE_ICON, 64, 64, LR_LOADFROMFILE); memset(&wnd, 0, sizeof(wnd)); wnd.hInstance = hInstance; wnd.lpszClassName = trayclassname; wnd.lpfnWndProc = WndProc; wnd.style = CS_HREDRAW|CS_VREDRAW; wnd.cbSize = sizeof(wnd); wnd.hIcon = status_icon_big; wnd.hIconSm = status_icon; wnd.hCursor = LoadCursor(NULL, IDC_ARROW); wnd.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE; if(!RegisterClassEx(&wnd)) { FatalAppExit(0, TEXT("Cannot RegisterClassEx")); } wnd.lpszClassName = insecclassname; wnd.hIcon = status_icon_alert_big; wnd.hIconSm = status_icon_alert; wnd.lpfnWndProc = InsecWndProc; if(!RegisterClassEx(&wnd)) { FatalAppExit(0, TEXT("Cannot RegisterClassEx")); } wnd.lpszClassName = hotsignclassname; wnd.hIcon = status_icon_alert_big; wnd.hIconSm = status_icon_alert; wnd.lpfnWndProc = HotsignWndProc; if(!RegisterClassEx(&wnd)) { FatalAppExit(0, TEXT("Cannot RegisterClassEx")); } wnd.lpszClassName = nowebclassname; wnd.hIcon = status_icon_alert_big; wnd.hIconSm = status_icon_alert; wnd.lpfnWndProc = NowebWndProc; if(!RegisterClassEx(&wnd)) { FatalAppExit(0, TEXT("Cannot RegisterClassEx")); } wnd.lpszClassName = updateclassname; wnd.hIcon = status_icon_big; wnd.hIconSm = status_icon; wnd.lpfnWndProc = UpdateWndProc; if(!RegisterClassEx(&wnd)) { FatalAppExit(0, TEXT("Cannot RegisterClassEx")); } init_font(); init_mainwnd(hInstance); init_insecwnd(hInstance); init_hotsignwnd(hInstance); init_nowebwnd(hInstance); init_updatewnd(hInstance); ShowWindow(mainwnd, SW_HIDE); init_icon(); spawn_feed(cfg); while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } Shell_NotifyIcon(NIM_DELETE, ¬ifydata); attach_stop(); lock_basic_destroy(&feed_lock); lock_basic_destroy(&alert_lock); free(updateinfo); free(update_new_version); WSACleanup(); return msg.wParam; } dnssec-trigger-0.13/winrc/status.ico0000664000175000017500000007644611636104712017176 0ustar wouterwouter hF  00 %V@@ (B:(  % :'d.!I5#S?+H7&  P7W>&V>(:+=. XD0rRnV?i ?S:";**tdF~cJ|\gA/8) J6#t\E?kQ}dL zYzxΦ ~1jP7^L9 iUD4J*ڟ~^M0pmYE߉qX`G13'ymOF8+cܴծe 1%oQ5z]AnS2gS@-%C *<'E2!eJtpXB zTfH-滑fMTC3C I7&vWvh9a$A5'RC45 ?OÏ( @ G: ,G,J1  #+ ! o7$J1/  G2fJ/kN3oS7uW;z\?bD~`DZE1  G% M3F1/ aE*aE,hL1pS6mP6kQ6~_AeFgHjKtSpX?RQ7S:"Z?'`E,YA*";.!}aErSvV}\-#R8!V<$_D*9)4S:$lN^|\f<1$w?+[@'O9$W)y[>e ֌nRbm)!J8&^C*_E-jM2tTmWCŕwYhojL0gK1>-cFhڳlpu^H|  vX;^J<.SJRC2sȡ{8V=(lNcvƠzI;.5; ~_Bi$)uqWǡ|lSjiM3uVpUPr\F˥|_yc4%hIpSv_IΧbtyZ>_jUBpiϩev]֯͡W"O;(\M8%oPo6,!~fNҫϩծݴ㺒ʠbQ@cpT8y[>aC9, ބeGjE7+G ̥֭ϩܴܳibQ? !4&|_B{]AxZ>oU;jP7yYfÞyknZE*"~>O6cH.xZ>lNd,#Q AK2^C*qS8iJvVfm_K7Q :%V<$O:&'ٟ`nʥcfB5(P6eI. ɢ|֯kjœv Y?%nQ6=. 9.#ѩ˜}eKiU@f>,xZ>nOgQ/ P=+mT;jKmNmNqQyWpQC5&uvP6Q8!U;#X>&\B)eI.T<'% z _I4nPqSsTyZ_lU?HL3T:"V<$Z@'_E+=,Ib:(vX&^D*9)deI/~_CzZiNlPa_iiOm'\@&\B(X?' uAJ5 xZ=sSc  pShcnnXB>l [@']C*`F-"(mP5gIf[I8 ݒtWiioH:, 5 N7"bF,kN2?._X?){]@}[y\ U"祄dlpf h>-hK0^E-6'4%sV:mNhF8+ J;,춒nnœw]L: ~ hL1dGbnT<6ЎsVuuo ]71F2|^@tUj' 8-"뾙tuǠzH:-:x lO5hJhr\F)=ͧfwˤ}jQLV>(aD}\d lpZEȢ|̦l3 - xY=nPlZJ8 K<.̥ͥq AfcI0eHc`Tz?3'Ϩ̥u#G #@.bCvWn;0%~A4(ѪΧw)"u, <5 mQ6lNjmT9\K:ҫԭmPB2lTj >*1M8%bE|\n( +jy]ѩЪzeß}޵̙=2'$C2"% &{\?pRooZDY 'fR?ΧΨϩԭ߶߶ݵ录͢x_01$|\?xZ>P=* QcaH0iKej gT2(ᢂdơ{Ѫ˥ϩԭذ߶辕仓}fN@3k'mR7{\?xZ>bD{^BI8(4&bDwWsWF6$( ˤ}ʣ}ΧׯٱرͧgiVC4+!TZ@0 pT;bEbE`CeGoV<:,lQ7pQk}`K˴pԬwi}fOA6)t= N S>*dH.[A'cG.sV:eGjKzYr3) TL=0[I9&~P&3 N5[A(jN3wY>cFoP_vY S YZ*( U6"L3W>&iM2vW;dFjLvWbk}^M=-:I/Q8 cG-S>)."fO8{Z_gttdoR=1$#-3!N4^B)T=(H9+}^nw˦fgjhN$EF.V<#eI/1$*!ػsʤ~ԭpfiœvnSAL4]C)lP54'['ÞyҫڳgOyZsm7-"-L6 eI/uW;eL6|dLЩٲ޷ s\Ex`H .!pR6uY=iKv\B6*3)fNǡ{Щj}=OdK3dFkNzYfrşy˥߶۵4*!!^Z. sY?{ZbhtͧḏڳL?2 [G5sUhpwv\ + _+#*"x4RT? x`? ??>>?~< ?(@  2&@1 ' :% %AO\igS<% =&A)C,F.% DTj-<&B*E-G/9&|x *A0I6#O;'WA+YC-P<)F5$:,$oU.D,F.I0I1z =,V>(bG.eJ0gL2jN4lP6oS8rU:tWy\@|^By\A]G2;-  | E-H0J2M4  @.[A)_D+aF-dI/fK1iM3kP5nR7qT9sV;vY=x[?{]A|_BaDcFeHfIYD2 u G.I1L3N5/!0"Y?&[A(^C*`E,cH.eJ0hL2jO4mQ6pS8rU:uXz\@|_B~`CbEeGgIiKkMlNbL7,@*K2M4P7E0?+W>%Z@'\B)_D+bG-dI/gK1iN3iN4bI0]E/XC,]F0mR8y]@}_BaDdFfHhJjLmNoPqRqRI9)iG/L3O6Q8!T:#V=%Y?'[A)^C+aF-cH/[C,:+! ;- aK6dGiKlMoPqRsSuUwWw^D  N5P7 S9"U<$X>&Z@(]C*`E,W?), shkE5&gJpRsTuVwXxY{[vX-$N5R8!T;#W=%Y?'\B)^D+D1P2-cH/cFsTvWyYzZ|\~^}]3) qB-S:"V<$X>&[A(]C*5&O Y?'oR8dGvW{\yY{[}]_aa9.#:. U;#W=%Z@'\B)I5"$~<*gL2{]AoQ`kVA@3&wY^`bdd-#X V<$Y?&[A(^C*0#J(`E,tW;iKzZb ( ٚyZaceg}^ (U;$Z@(]B*_E,G4!oK5 lP6bEtUdPA2'ٝ}]dfhjgNeC/\A)^D+aF-^D-F$eI0x[?mO^x\s,#ڧdhjlnN?0X-,]C*`E,bG.eI0 V>(qT9fIxXh3) >zTC3䮋ikmoe _D+aF-^E-I5# f3$iN3}_CqRbgNρgNlnprVF5X1$  `F,vX=jM|\h! ֱkoqsiHD0nR7dGuVfhT@vk|dLprtvD7+!e10 fK1z]AnP`d !ֹqsuw}fN]P S;%sV;hJzZiK=/UxϞatvxnP+kO5aDsTcw[<lWC辚vxÞzơ|$ _D-xZ?lN~^l-%57,"wyŠ{Ǣ}>2&o;*pT9eHwXg~gO#xğzơ|ɣ~O@1 gL2|^BpRal  ÞyŠ{Ȣ}ʥ~_N<,+L7$uXkM}]mzbK#eQ>z^wơ|ʤͧϩҫҬծװڲܵ޷Ṓ㻔|:+rU:uXz\@^H2 t oS8eHvWgo qWF6wÞyŠ{Ȣ}ɤͧѪӭԭ֯ٱ۴װmq]I/' lR6tW;vY=y[?{^A}_B}`CP>, U>)|^BoQap]K:cxğzǡ|ɤ~̦ΨѪӭӭq|fO@4)] G5$sV1#)tW'G/Q8 [@(dI0lP5aH2aDlNtU}]dlsg_kO*"r :  C,M4W=%`E,T>) -#݄hL}]aipxy`bct]F Iw5"I1S9"\B)^E- \I9处dltơ|ϩidfhf]K::E-O6X>&bG.D2";/$ݷpx˥ԭnegikmWF6J2T;#^C*gL2?/ b-#ٽuǡ|ЪٲhfhjlbMM5Z@'cH/mQ6WA.){VF5Þy̦ծݶNB4K;,᠁akmA5(BgI3_E,iM3rV;{]A% ӨhȢ}ҫڳڳ  iT?lR2+'eI0nR7x[?bEhKH8( 9-#ܞağzΧ֯߸hj^E.tW<|_BgJpQyY`howʤ~Ӭܴ㼓B6*) n`7$uY=dGlNuV~]eltŠ{ϩذ๒lYFw!ڀcGqRzZaiqx˥ԭݵmV{mU?|\fmuǢ|ѪjA6*] E7)lWCdQ>[J:4*!i02/!???????@????qdnssec-trigger-0.13/winrc/install.ico0000664000175000017500000007644611634047237017327 0ustar wouterwouter hF  00 %V@@ (B:(  &(% :'d0"E3";3;3 Q7Z@(?- r y  D;G1 [Oھ߽ZN ?5-QFA8۲Ӵ ޿L@ SG1+;[pܘt  *%c| ܽ vkUE5JܘrmYE߉qX`G13'yN:.uscOC޶ծe 1%oQ5{^B[H;~t5*'/'C *<'E2!hLr[KxITfH-s^~ ܽ ΗT I7&vWwwaQbUtk\X$A5'SD4LTSTX?'???( @ G: ,&"G,J1  %-"'"+%v7$J1/  G2gJ0qS6R<)1' ;2 2+CG% M3F1/ aE*dG-^E,)  5-eWڹܼeV*$ Q7S:"[@'bF,5&!<5׻Ǭѵ߾@7#gS8![@&J4!  2+uǭԴ ~l0)2t;(',&\P˯ݼ˯ƫVK3,g1'E;E;{n~m{j޸ūٸ ܽڽn p sziJ@D:("C.$ +" 2+б߾ū3, 6-5+'!  4A75.ԸܻԷ 5-:.#pVv[9AE82+ Ȯ5-Ğxɢ|I;.23+̰5-eqWǡ|lSj8/Ѷ5-@r\F˥|_ya 80ƫ5-Cv_IΧbt!:2ܿ6.iϩev]֯͡W"O;(\V?*$=4Ӹ2+jQҫϩծݴ㺒ʠbQ@cpT8y[>aC9, ގmM*!4-ؼ0*1'!دϩܴܳibQ? !4&|_B{]AxZ>oU;jP7_"/)ټ/)*"rnZE*"~>O6cH.xZ>lNh3,3,Q AK2^C*qS8iJvVl)!6.ҷ5-:%V<$O:&'ٟ`u0'!80ҵ ˰5-P6eI. ֭3)$81ɮֺ5-Y?%nQ6=. 9.#޴6,&-'ܽŬչ5-f>,xZ>nOgQ E6(rV~ar]H?}V?(0` @E &   7COF+@-$ D+I/<(8 F     (#+& hE,G.J1 |B#7(O:%`F.dJ1I7%'( 2+J?G=,'GM @)I0P6! )R:$bF,mO3oQ5^E.5'' 3*?6sc ȪȪrb70# }#9%M4P67& J4_D)bF,hK0bH.B0  3*;2ZMXK2+#b   *O5P6N6R9"\B(`D+dH.M8$" "/(@7|lǬ ݽۺy D:(#;vP6Q8!U;#[@'`E+Y@(+ $/*_RﺡӸǬɯͲٺ ƩhY/)&! wHL3T:"Z?&X>&?. /)TI謕īϱܻMC/($S=*\@&H3' ,&@7pֻȭظ ޽Զpa;41*,#5$  )$:2i\еūӴܻ˰˰cV=5,& j  *"A7<4THзΫЧѧҥϳͲˮڹ غ ʰѶ䩓}XL?6?6 =1 5,B8B8>46.3,1*0*0*0*,&;3¨ūն ݼƬ4.)$:1:191:1/)70=5=5?71+4=% !     0({ͯۺӶ ̲0)  8-3)6,   @9 kcg`/(q׺ٸ ī/(M>1nXEmXEfRB]ggm=1P/(o޼ͱԹ/(E7*ȡzɢ{ϧH;-:xX,&r ݾǭ/(evɣ|jQT*%wɮۿ/(]pZEȢ|̦l3Y,&{ غ ɮ/(D~K<.̥ͥq A1)} Ŭ/(Gi?3'Ϩ̥u#G  4,Ѵϵ/(GmA4(ѪΧw)"u, <5!4,Ŭ/(D\K:ҫԭmPB2lTj >*1%$5-ܿչ/(y]ѩЪzeß}޵̙=2'$C2"% /"O;)#:1v׻|,&jUAΧΨϩԭ߶߶ݵ录͢x_01$|\?xZ>P=* QckO5XC0) 91nӀo/)!jR޴˥ϩԭذ߶辕仓}fN@3k'mR7{\?xZ>bD{^BI8(4&jK_K7.%3+r~n/)/&hQ۲ׯٱرͧgiVC4+!TZ@0 pT;bEbE`CeGoV<:,lQ7zYmVB#+%}n,&( lTΧi}fOA6)t= N S>*dH.[A'cG.sV:eGjKau^H)#Ӏo,& 2( .%~P&3 N5[A(jN3wY>cFoPdfQ>)#z|-'T*( U6"L3W>&iM2vW;dFjLvWiqZE"1)nܿ/(TI/Q8 cG-S>)."fO8{Z_ow`J-$7/} Īչ/(U-3!N4^B)T=(H9+}^Ýw{dM1'6.˯˰/(WEF.V<#eI/1$*!ɢ|jR2) 7/Īϴ/(WAL4]C)lP54'['ѪnV3*!2+Ҷê˱/(W-L6 eI/uW;eL6|dLߵqX4+!-'p߿ŬĪͲ/(W.!pR6uY=iKv\B6*3)fNǡ{᷎v]")#{չպ۾.'WOdK3dFkNzYfrşy˥˜y`1*k\ޘ݆tuz◃ӕ֕֞i[8/X sY?{Zbhtͧḏ޶C7->580.'0)0)/(/(/(/(.'8/?6[ [G5sUhpwv\ 5 _+#*"w/[XWWWWWWWWX\84RT? ?x`???~< (@  2&@1PP ' :% %AO\igS<G( =&A)C,F.% DT,&-( k <&B*E-G/9&|x *A0I6#O;'WA+A2!  "81;3;381BU.D,F.I0I1z =,V>(bG.eJ0gL2jN4`G05'"#+">4C9C9q`m]<4;31*  E-H0J2M4  @.[A)_D+aF-dI/fK1fK2D3"#"%7- C9C9VJ߾TH<4:3$] G.I1L3N5/!0"Y?&[A(^C*`E,cH.eJ0S=(*!"/% @6C9F<x ڹ߾ܻz E:<46/4@*K2M4P7E0?+W>%Z@'\B)_D+bG-]D,7(  # 8/@7@7gXĨ޽߾ʬl\ ?6;3-' xG/L3O6Q8!T:#V=%Y?'[A)^C+`E-D2    92;3F=Ȯɮ̰ҵٺ OD<492"O N5P7 S9"U<$X>&Z@(]C*R;%% 4-;3<5ziԸٽԸ˰ȮȮɯշ ۻr >6;35.&N5R8!T;#W=%Y?'X?'7( *$=5>6]QγӷȮαظ ߾ĨYL;3<4/( j qB-S:"V<$X>&D0" :3?6F=頋˰ʯֶ ۺ}A9<4<5!A:. U;#M6!+   1*>6?6vfھȮвٹ ޽ܽԷhZ=5?65. 7&   +%:3=5SI濦ɯ˯׷ ܻ̰Ȯг˰RH?6>6*$\  *! >5?6;3eWǭγγγγγγγԸȮӳں߾غ ȮеȮƫħŨƨƩǪk\?6?6;32=8.A7A7A7;3<3?6?6?6?6?6?6?6?6H>魖ȮͰظ ݼȮϴ>6>5F<G<G<G=G=?6;3=5?6?6?6?63, >2+9/9090:01*.(3,3-3-3-3-3-3-3-?6QFγɭն ۻѴȮTI<4.(80C8 C9 C9D9A7 /)/(3,3-3-3-3-3,x   ?6?6Ȯϱٹ ޽Ȯֺ?6?6&5+!6+!7,"8-"yb ?6>6ʰʯ׷ ݼͲɯ?6?6 P@0RB2SC3TD4L>0cH?6<4ȮҴۺܽȮ?6?6|dLprtvD7+!e1>5;3̰ٸ ޽˯̱?6?6!ֹqsuw}fN]P <3;3յ ܻ׹ Ȯ?6?6xϞatvxn;3=4ڹ ߾Ȯе?6?6<lWC辚vxÞzơ|$;3A7ݼѴȮ?6?67,"wyŠ{Ǣ}>2&>5B8Ȯػ?6?6#xğzơ|ɣ~O@1B8C9̱ʰ?6?6 ÞyŠ{Ȣ}ʥ~_N<,+ B9D:ۼȮ?6?6 ğzǡ|ɤ~̦fTAUa8 !C9E;ɯͲ?6?63* Ơ{ȣ}˥~ͧJ<.6-#gUAt nza  %D:F<ֹ Ȯ?6?6XG7Ǣ}ʤ~̦ϩ&$bP?✀cϪݵ߸# LX2#"(E;G<ȮҶ?6?6ϔy]ɣ~˥ϩΩxԭװڲܴ޷๒]L<'%9*- gL2&,"F<H=ϳȮ<4;3 UD4Ǣ}˥ΨЪҬӬ֯ر۳ݶ߸⺓~d'dJ2sV;gM5(yD0wY>* 0&G=C9Ȯٽ׺;3=5,$wơ|ʤͧϩҫҬծװڲܵ޷Ṓ㻔|:+rU:uXz\@^H2 t oS8eH.$4)G=<4ʰȮ;3?7:/$;/%Š{Ȣ}ɤͧѪӭԭ֯ٱ۴װmq]I/' lR6tW;vY=y[?{^A}_B}`CP>, U>)|^BoQ1'7,"A7;3׺Ȯ;3<5:/$;0%ǡ|ɤ~̦ΨѪӭӭq|fO@4)] G5$sV1#)tW5;3Ȯֺ?6?6 >'G/Q8 [@(dI0lP5aH2aDlNtU}]dl8.#4)F<C:дȮɯ?6?6:  C,M4W=%`E,T>) -#݄hL}]aip:/$;/%F<F<޿ͱȮ̱?6?6w5"I1S9"\B)^E- \I9处dlt<1%?3(G<F<ٻ ˯ɯ?6?6E-O6X>&bG.D2";/$ݷpx=2&@4)G=F<ٺ Ȯ˰?6?6J2T;#^C*gL2?/ b-#ٽuǡ|?3(A5*F<F<ɯȮȮ?6?6M5Z@'cH/mQ6WA.){VF5Þy̦@4)B7+@7?6Է ȮȮȮ?6?6gI3_E,iM3rV;{]A% ӨhȢ}ҫB6*A5*;3;3˯ܽȮȮȮȮ?6?6+'eI0nR7x[?bEhKH8( 9-#ܞağzΧ֯C7+.&;3<4ͲȮȮȮȮȮ?6?6^E.tW<|_BgJpQyY`howʤ~ӬܴD8, ;3>5Ͳγе?6?67$uY=dGlNuV~]eltŠ{ϩذ๒<4?6?6?6?6?6?6?6?6?6?6?6?6?6?6?6w!ڀcGqRzZaiqx˥ԭݵmV>6?6?6?6?6?6?6?6?6?6?6?6?6?6?6?6{mU?|\fmuǢ|ѪjA6*] E7)lWCdQ>[J:4*!9)i02/!????        @??????????????dnssec-trigger-0.13/winrc/rsrc_panel.rc0000664000175000017500000000177511636115055017630 0ustar wouterwouter/* dnssec-trigger-control resource file for windows. For use with windres */ #include "winver.h" #include "config.h" 1 ICON "winrc/combined.ico" 1 VERSIONINFO FILEVERSION RSRC_PACKAGE_VERSION PRODUCTVERSION RSRC_PACKAGE_VERSION FILEFLAGSMASK 0 FILEFLAGS 0 FILEOS VOS__WINDOWS32 FILETYPE VFT_APP FILESUBTYPE 0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904E4" BEGIN VALUE "CompanyName", "NLnet Labs" VALUE "FileDescription", "DnssecTrigger tray panel" VALUE "FileVersion", PACKAGE_VERSION VALUE "InternalName", "dnssec-trigger-panel" VALUE "OriginalFilename", "dnssec-trigger-panel.exe" VALUE "ProductName", "DnssecTrigger" VALUE "ProductVersion", PACKAGE_VERSION VALUE "LegalCopyright", "(C) 2011 NLnet Labs. Source is BSD licensed." END END BLOCK "VarFileInfo" BEGIN /* English(409), windows ANSI codepage (1252) */ VALUE "Translation", 0x409, 0x1252 END END /* vista user access as invoker */ 1 RT_MANIFEST "winrc/panel.manifest" dnssec-trigger-0.13/winrc/gen_msg.bin0000664000175000017500000000016411632412661017251 0ustar wouterwouter  4``DTd%1 %1 %1 %1 dnssec-trigger-0.13/winrc/setup_left.bmp0000664000175000017500000045565611640542543020040 0ustar wouterwouterBM[6(:x[  >>>000000CCC666000000000000<<'A)C,F.;0&000sss???000000000000000000...>9FAMLFMMMNNNrrr000?)B*E-G/C1!000燇666000000630C90P@1UC2YF3_J5G8(!(# ;4>6>6=684GGFMMM\\\000;,D,F.I0J300/III44400072.K<,ZC-bG.eJ0gL2jN4`G05'"#+">4C9C9rao`>6>66/.,!EEEMMMyyy0007.%E-H0J2M481+00000072.L;*\B*_D+aF-dI/fK1fK2D3"#"%7- C9C9VJ߾UI>6=6+&++'KKKPPPHHH2/-G.I1L3N5A4'100C6)Y?&[A(^C*`E,cH.eJ0S=(*!"/% @6C9F<x ڹ߾ܻz F<>6:3'$???MMMddd000E0K2M4P7L7$J7'W>%Z@'\B)_D+bG-]D,7(  %90A8A8hYĨ޽߾ʬl\ A8>63-20(LLLMMM000?1$L3O6Q8!T:#V=%Y?'[A)^C+`E-D2 '#<5>6I@ ˲ ̲ γ ӷڻPE>6<53/KKIMMMUUU11191*N5P7 S9"U<$X>&Z@(]C*R;%( 81@8D= u$%ؿε˲ ˲ ̳ ֹۻs@8>6>7 LI:MMMMMMoooWWW10/O6 R8!T;#W=%Y?'X?'7( 4. G? LDod6@@@@@?3׾˲ ϳ ظ ߾Ĩ\O>6B:LF$MLFMMMNNN000J6$S:"V<$X>&D0"%" F?MEVN,?@@@@@@@;ε̲ ֶ ۺ D<B:MFMJ3MMLMMM\\\000B5)U;#M6!+  71KCMEz";@@@@@@@@@ ˲ ѳ ٹ ޽ݿչél^G? MEMGMK@MMMMMMzzz44471+7&   .(=6H@d[̸3@@@@@@@@@@6̳ Ͳ ׷ ܻδ˲ Ҷͳ `WMEMFMH*MMIMMMQQQOOO  *! >5@7>6pcӾ56666666>@@@ؿ˲ Ӵ ں߾ټ˲ Ի˲ ȮħŨƨƩǪ |oMEMEMFMK8MMMMMMeee/// 8.A7A7A7>6A9MEMEMEMEMEMEMEMEXO/@.˲ β ظ ݼ˲ Ӻ?A9@7F<G<G<G=G=A8>6G? MEMEMEMEMG!MLDMMMMMMggg??? 5.9/9090:05.3-KEMG MG MG MG MG MG MG MEaW>Ѹ˱ ն ۻӷ˲ 0@e[D< 3-:2 C8 C9 C9D9B8 4.60 LFMG MG MG MG MG!MJ;MMMeeeLLL EEEMMMMMMMMMMMMMMMMMMMMMMEME&˲ г ٹ ޽˲ @@MEME*"5+!6+!7,"8-" 222MMMMMMMMMMMMMMMMMMMMM흝444 pppsssssssssssssssMMMMMMMELDʹ̲ ׷ ݼϵ̳ 8@@MEMEEEEP@0RB2SC3TD4N@2###ssssssssssssssssss000000000000000000???MMMMMMMEC; ˲ ӵ ۺݿ˲ "@@@MEMEMMM---000nXqsuw\QF000000000000000???MMMMMMJB>6γ ٸ ޽ͳ ϶<@@@MEMEMMMHHH;;;E@:rtvxr\000ccccccjjjMMMMMMA9>6ն ܻػ˲ +@@@@MEMEMMMMMM000guwyq000gggMMM555>6?6ڹ ߾˲ Ի?@@@@MEMEMMMMMM000yfTwyÞ{ơ}GA<888JJJ=5A7ݼӷ˲ 3@@@@@MEMEMMMMMM555SJAxzŠ|Ǣ~YOE000+++@7B8˲ @@@@@@MEMEMMMMMMHHHF@;yğ{ơ}ɣeXK000B8C9δʹ9@@@@@@MEMEMMMMMMYYY<96ÞzŠ|Ȣ~ʥqaQ000oooB9D:ܾ˲ %@@@@@@@MEMEMMMMMMYYY;85ğ{ǡ}ɤ̦vfU000fff666000000111|||000!C9E;̳ з=@@@@@@@MEMEMMMMMM999QI@Ơ|ȣ~˥ͧaUI000000000211TLDxhW000000000󑑑|||RRR110%D:F<׻˲ -@@@@@@@@MEMEMMMMMM000k\NǢ~ʤ̦ϩIC=GB>>---RRR000fɣ˥ϩΩ{ԭװڲܴ޷๒qbT000000000iii000000000B:2M@4110000\\\>>>31/hM4&,"F<H=Ѷ˲ 5@@@@@@@@>C; ?7643iZLǢ}˥ΨЪҬӬ֯ر۳ݶ߸⺓o000000000EEE000000210hO8sV;kR;E=4000111zzz000Q?/wY>* 0&G=D;˲ @@@@@@@@?>6?7#/'xơ|ʤͧϩҫҬծװڲܵ޷Ṓ㻔000000bbb:::000000NA4rU:uXz\@gR=<7300099922294.oS8eH.$4)G=>6ʹ;@@@@@@@@$˲ >6A9:/$;/%Š|Ȣ~ɤͧѪӭԭ֯ٱ۴ױun\PIB000000VVVQQQ000630mS8tW;vY=y[?{^A}_B~aD^N=532000000\F2|^BoQ1'7,"B9>6'@@@@@@@@@˲ >6>7:/$;0%ǡ}ɤ̦ΨѪӭӭwt_[QG432000000666hhh===421VF6tW=xZ?z]A}_C~`DcFeHcHTH6@8>@@@@@@@@@˲ >6>65+!;0%ȣ~˥ͧy{ceYL<97000000111XXX???000;62eP<|^B{]AiN3dI/iM3oS8y\?eHfHtUd9.#>6H@@@@@@@@@@@$˲ >6>6)"9.$~eo`QE@;000000000HHH{{{000000D4&N5T:"]C*gK2qT9z]AeHnPwWk.&@8ME@@@@@@@@@@?>6>6000000;;;pppZZZ0007*F.P7Y?'cH.lP6vY=bEjLsT|\a$>6@81@@@@@@@@@@>D< B:0006,"B*K3U<$_D+hM3rU:|^BgIoQxX`g5+ -$@7>6˲ 8@@@@@@@@@MEMEMMMMMMAAA2.+>'G/Q8 [@(dI0mQ7hP;aDlNtU}]dl8.#4)F<D;ҷ˲ ̳ #=@@@@@@@MEMEMMMMMM0006+!C,M4W=%`E,\G3631000I@7lQ}]aip:/$;/%F<F<ϴ˲ ϶.@@@@@@MEMEMMMMMM000<*I1S9"\B)aI1420000000000321m\Mflt<1%?3(G<F<ڽͳ ̳ 1@@@@@MEMEMMMMMMmmm1/.E-O6X>&bG.SB3000111000000000000UKAqy=2&@4)G=F<ڼ˲ ε9@@@@MEMEMMMMMMlll0//J2T;#^C*gL2QC5000BBB000000000LD=vǡ}?3(A5*G= F<̳ ˲ ˲ -@@@@MEMEMMMMMM{{{000O7!Z@'cH/mQ6aL:000gggքKKK000iZKÞz̦@4)B7+B9A8չ˲ ˲ ˲ /@@@@MEMEMMMMMM000O:&_E,iM3rV;{]AD=6000AAAUUU000:75lȢ~ҫB6*B6+>6>6ͳ ݿ˲ ˲ ˲ ˲ 3@@@@MEMEMMMMMM000@6-eI0nR7x[?bEiL[M?964653TJAgğ{Χ֯C7+2*">6B:з˲ ˲ ˲ ˲ ˲ %@@@@@MEMEMMMMMMaaa100bJ4tW<|_BgJpQyY`ipxʤӬܴD8,>6JB=$зҹԻ(@@@@@@MEMEMMMMMM000B:3vZ?dGlNuV~]fmuŠ|ϩذ๒% C; MEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMMMMMM000A;4eJqRzZajry˥ԭݵzeLDMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMMMMMM000>95v`K}]gnvǢ}Ѫr\RH000EEEMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMuuu888000643\PDyfTtcRn_PRJB000000jjjuuuMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMooo疖QQQ000000000000777ooo啕ggg^^^mmm𘘘ggg^^^yyyǠkkk___]]]ggg~~~ۢ{{{eee]]]bbbyyyNfӸTbҶɰ먵ƣÞ׾ɨ666}}}444111sss111$$$,,,RRRk]Ȧ}LҶ{Iռ~MZ׿~ȧϲÞ˫666WWWAAACCClll$$$ rrr Rǥrq<ׂSP傔T׿~ͮˬšٽǥƣ666,,,}}}<<<444nYʩO̬zH~MҶ[׿~ʩд̭666333mmmnnnBBB???,,,}}}%%%111مXo׿]ǥjּ˲Ȧšˬ666TTTMMM===}}}111111LLLXXX888777666 mmmwwwhhh}}}^^^ҙ999fff111 iiiCCC666VVVhhh}}}111ooo...p;~NǤwDtSƣ❫x}ϱğֽ666ZZZ hhh}}}EEE111:::edßyG|Kϱ~MЅW׿~ƢƤƣ̭ğɩ666||| hhh}}}Sǥrq<ւSP䂔T׿~ͮˬŢٽǥƣ666hhh}}}LLL+++vuRϱVyGOǥ`׿~ͯԹœΰ666///KKKhhh}}}:::RRR嘧qϚt˫ԹӾǥĠƤгͯӸ666dddhhh}}}!!! )))III666+++hhh}}}___ttt666 >>>hhh}}}Ҷr=wC⯻~Mc߁R׿~Ƥˬΰ̭ɨƣίϲ666CCChhh}}}___qqq_œiwC~M߁R׿~Ƥˬ篺ͺġȧ666QQQhhh}}}$$$Tǥqr=ցR߁R׿~Ƥˬ冀ﯺǤƣ666ꐐ222hhh}}} g|Kջ^yG߁R׿~ƤˬӹѴѴ666rrrhhh}}}UUU𫷋ŢެœҶԺ666hhh}}}ZZZ ###666jjj}}}LLLzzz666nnn}}}###ǥxFt@{I߁R萠ftαϝx{ӷǥƤǥ342XXXuuu}}}LLLaaa[Ġl{I߁RҶ} |ʪɩȧѳ꯺ǥ231YYY}}}gggVƣp{I߁Rвĝx̭˪ƤӴԺǥ231>>>FFF}}}\\\JJJZxE{I߁RێdÞֽǿȧ紿ͮǥ231}}}lllsssǥԺ̮ϲҷ666kkk999}}}kkk333``` 666}}} ,,,(((Ҷջ666&&&}}}|||uuuišrlN鉚]xv׿~Ƥˬ̮Þгֽ331}}}mmm>>>išs>ԀQOT׿~ƤˬҴۼƣƤ231OOO222}}}www TTT666išs?ӀPO߃T׿~ƤˬҳܼƣǤ231RRR 111}}}mmmnnn:::dddišufP시_sy׿~Ƥˬΰßΰ׿331ǡ}}}͡山ջ666}}}666}}}Թʪͮг666}}}iš{I߁RِfœƤˬǦšǥг׿666}}}iš{I߁RϲŝxƤˬӵǥ666}}}iš{I߁Rҷ||Ƥˬвǥ666}}}iš{I߁RꐠfqдƤˬԺǥͮѴ׿666}}}666}}}666}}}ȧּۨȯҷĠͯг׿ռ666}}}iš\yGՀQdϒiгֽǥѶ666}}}išr<ւSP䂔TßŜv̭˫Ţǥ666}}}išwD}L˫~NՄUϱy׾ĠȦȦ˫ǥ666}}}iš{IgxXmiۛuzǥίϲֽ666}}}VVV))))))))))))))))))))))))))))))t[[[[[[[[[[[[[[[[[ͯ[[[[[[[[[[[[[[[[[[[[[[[[[׈[[[[[[[[ռ[[[[[[[dռyyF`w%YqYqYqYqZr]u!n8]嫸|J_v#YqYqZrZrh~0Ys>YqYqYqYqYqYqYqYqYqZrYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqѵYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(k3YqYqYqYqYqYqYqYqYqYqYqYqYqZrm6^v"YqYqYqYqYqYqYqYqYqYqZrk4s>YqYqYqYqYqYqYqYqYqZrYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqѵYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(vBYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYq\syYqYqYqYqYqYqYqYqYqYqYqYqYqYqZrs>YqYqYqYqYqYqYqYqYqZrYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqѵYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(bx'YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqWѵZrYqYqYqYqYqYqYqYqYqYqYqYqYqYqZrs>YqYqYqYqYqYqYqYqYqʪ[rYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqѵYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(ax&YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqWuBYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqZrs>YqYqYqYqYqYqYqYqYqӷ\tYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqѵYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(t@YqYqYqYqYqYqYqYqYqZrxEßšyQ`w%YqYqYqYqWYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqZrs>YqYqYqYqYqYqYqYqYq^v"YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqѵYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(YqYqYqYqYqYqYqYqYquBơ~i1YqWšYqYqYqYqYqYqYqYqYqZrr=Qt@\tYqYqZrs>YqYqYqYqYqYqYqYqYqby'YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqѵYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(o9YqYqYqYqYqYqYqYq[ѴYqYqYqYqYqYqYqYql4ʪPZrs>YqYqYqYqYqYqYqYqYqf|-YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqԺ׿׿׿׿׿׿׿׿׿׿׿׿׿׿YqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(YqYqYqYqYqYqYqYqn8rYqYqYqYqYqYqYqYq˫s>YqYqYqYqYqYqYqYqYqj3YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(YqYqYqYqYqYqYqYqȧpYqYqYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYqp;YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(eYqYqYqYqYqYqYqYqxpYqYqYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYqvCYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(}LYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqͯpYqYqYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYq~NYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(uBYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqͯpYqYqYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYqWYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqš]YqYqYqYqYqYqYqby(yFYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqѵpYqYqYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYqdYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqSYqYqYqYqYqYqYqby(XYqYqYqYqYqYqYq_v#wEwEwEwEwEwEwEwEwE`w$YqYqYqYqYqYqYqpYqYqYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYqqYqYqYqYqYqYqYqYqYqYqYq]u!QYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqm7l4YqYqYqYqYqYqYqd{+{YqYqYqYqYqYqYqp:wCYqYqYqYqYqYqYqpYqYqYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqΰYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYq]ZrYqYqYqYqYqYqYqn7ͯYqYqYqYqYqYqYq\tax&YqYqYqYqYqYqk3pYqYqYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYqޭZrYqYqYqYqYqYqYqYqYqYqZrƤYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqbqYqYqYqYqYqYqYqYqO_v#YqYqYqYqYqYqYqӸYqYqYqYqYqYqYqspYqYqYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYq|ZrYqYqYqYqYqYqYqYqYqYqZrYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqi~0ȧVYqYqYqYqYqYqYqYqYqusYqYqYqYqYqYqYqby'r=YqYqYqYqYqYqYq⏟eYqYqYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYq̭`w$YqYqYqYqYqYqYqax&ϲr=YqYqYqYqYqYqYqT}YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqšs>YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqxYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYq`w%ĠZrYqYqYqYqYqYqYqYqZr[sZrYqYqYqYqYqYqYqYq`w$ǤZrYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqšs>YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqjYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqt@ZrYqYqYqYqYqYqYqYqYqYqYqYqYqYqZrYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqͯZrYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqšs>YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYq^YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqšZrYqYqYqYqYqYqYqYqYqYqYqYqt?]u!YqYqYqYqYqYqYqYqYqYqYqYqYqYqYq^u!ʪZrYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqšs>YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqSYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqšԹi1YqYqYqYqYqYqYqYqYqYqwD؈[ZrYqYqYqYqYqYqYqYqYqYqYqYq{JYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqšs>YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYq{IYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqg}.g}.g}.g}.g}.g}.g}.g}.ʩ󳾖uBZrYqYqYqYqZrr=צwD[sYqYqYqYqYqYqe{+kYqYqYqYqYqYqYqYqe{,g}.g}.g}.g}.g}.g}.g}.ɩs>YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqt?YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqϲϱؿֽϲαֽ|YqYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYqYqYqYqYqYqn8YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqxYqYqYqYqYqYqs>YqYqYqYqYqYqYqYqYqYqYqYqYqi1YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqsYqYqYqYqYqs>YqYqYqYqYqYqYqYqYqYqYqYqe{+YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqpYqYqYqYqs>YqYqYqYqYqYqYqYqYqYqYqax&YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqlYqYqYqs>YqYqYqYqYqYqYqYqYqYq^u"YqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqiYqYqs>YqYqYqYqYqYqYqYqYq\sѵYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqeYqs>YqYqYqYqYqYqYqYqZrʩYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqYqջ^uAuAuAuAuAuAuAuAĠuAuAuAuAuAuAuAuAuAŢuAuAuAuAuAuAuAuAuAvCdnssec-trigger-0.13/winrc/uninstall.ico0000664000175000017500000007644611634047237017672 0ustar wouterwouter hF  00 %V@@ (B:(  ^SSW% :'d0"/# g fS P7W>&W?)% & ?S:";*&E" aN2gA/8)TiT7~eMQ) ѩ ~dvjUD4J soZF߉qXQ<'%Q=`N/Ġwš|h > 6OD BL(.'7# _-$a TfH- ,#+F I7&vWvg9<$A5'RC45)(?'?( @ G: G,J1  F122355H7$J1/  G2fJ/rS7 4!!5G% M3F1/ aE*aE,hL1wX:4!!!"&1Q7S:"Z?'`E,YA*"4 $(7 R8!V<$_D*9)45#+"72(H:+w?+[@'O9$5 +"6*!s)!J8&^C*_E-5%2!nojL0gK16 +"6npu^H| 5)  6UE3众sȡ{83#(5vƠzI;.52 -#5eqWǡ|lSj5'!5@r\F˥|_ya 51'5Cv_IΧbt&76iϩev]֯͡W#Q<)\X@+( 92lSԭҫذ޶㻓ˠbQ@cN:&[D._H1 iP73)31;0b{^cdnUaP= ! #"#$%&/.)") ("7#AG yzolt|JD(C<#  4 Z$-$.$[2:%Z?%:* 64*+!+" 32P6eI. 5 E".$1'A'gY?%nQ6=. 6,!WF36-+* ab0 f>,xZ>nOgQ(;, 7 c  j8XM @)I0P6! )R:$bF,iL1rS6F4!."!" .V#9%M4P67& J4`D)bF,bG-gK0vW9K8#/#!!!#$$+P  *O5P6N6R9"\A(\B)cG-iL1YA+H5#" - "$#$) -vP6Q8!U;#X>&\B)eI.T<'% .$$' 2HL3T:"V<$Z@'_E+=,IS/ $*! 2.$D6' <)X=$X>&^D*9)dU/ '" 2$x`FsVm'\@&\B(X?' uW/ %)! 2( mW@ÜtnXB>l [@']C*`F-"W/ !+",pYApoH:, 5 N7"bF,kN2?.W/'$*pZBrpf h>-hK0^E-6'W/ #+" /D6'pnœw]L: W0!*! 0ݏtW￙uuo ]7W/ &," /;0$޾tuǠzH:-:xW-",#/fwˤ}jQT+ !() /]pZEȢ|̦l3Y+%-$/D~K<.̥ͥq A.,#&/Gi?3'Ϩ̥u#G  00& /GmA4(ѪΧw)"u, <5!0$/D\K:ҫԭmPB2lTj >*1&$ 1 /y]ѩЪzeß}޵̙=2'$B1!$.!P;'# 4 , hS@̦̦ͧҬ޵޵ݵ弔͢x_07(aB_AWB-O`sU:^G1' 4~.oT龒֮ٱݵා廒羕ĢiPB4l(;,G5!G6"P=&C3  R>(E6"4*/~.9. ZI3{dIzdI|dJ|fKycIfS=N@.2) Vy !% !,#$)!&,}-.%(1())!%&# 3/ +><:94 3 3 3 6*67,1.**.7;>A228 <= UY??=L - = e(,#-$'h=, j K1C.- 0 B{( 2(0&+!" ?0,-3!M4bE*N9%# 5 U"4*-#,#,# T2$SEF.V<#eI/4' 4 9h',",$1'!e5* wAL4]C)lP54'Y 2))!/6D,#.% D.;-L6 eI/uW;eL6yaKkRC6&8.*$0 VU6(c .!pR6uY=iKv\B6*3)fMˤ~ڱɥQC2 $6ds:(OdK3dFkNzYfrşy˥ා⻒=3(1KM2H sY?{ZbhtͧḏڳK>1 i -, k [G5sUhpwv\ +.. _+#*"xEA4RT? x`???~< ??8|?(@  2&@1)) ' :% %A =&A)C,F.% DT;;;;;;<=>???????<&B*E-G/9&|x *A0  ===<<<;;;;=>????U.D,F.I0I1z =,V>(bG.eJ0gL2 !> > ?? E-H0J2M4  @.[A)_D+aF-dI/fK1iM3 !> >  !!=? G.I1L3N5/!0"Y?&[A(^C*`E,cH.eJ0hL2jO4!" > >  !!"##;;@*K2M4P7E0?+W>%Z@'\B)_D+bG-dI/gK1iN3iN4== !!"##$$$<;G/L3O6Q8!T:#V=%Y?'[A)^C+aF-cH/[C,:+!;;  "#$$%% @? N5P7 S9"U<$X>&Z@(]C*`E,W?), == "$%%& @ A-# N5R8!T;#W=%Y?'\B)^D+D1P??  %&& A A0&/%3) qB-S:"V<$X>&[A(]C*5&O??!&'' A A1'2'a9.#:. U;#W=%Z@'\B)I5"$?? $)  @ A1'2(dd-#X V<$Y?&[A(^C*0#J??"'( < @2'2(eg}^ (U;$Z@(]B*_E,G4!o??  %*!;#'+"?? ֱkoqsiH?< !&+"??|dLprtvD7+!e1>;$) ( ??!ֹqsuw}fN]P <;"',# ??xϞatvxn;; %*!$??<lWC辚vxÞzơ|$;=#( -$ ??7,"wyŠ{Ǣ}>2&;>!&+"??#xğzơ|ɣ~O@1> ?$)!,#?? ÞyŠ{Ȣ}ʥ~_N<,+ > ?',#?? ğzǡ|ɤ~̦fTAUa8 ! ? @*")!??3* Ơ{ȣ}˥~ͧJ<.6-#gUAt nza  % @ A-$ ??XG7Ǣ}ʤ~̦ϩ&$bP?✀cϪݵ߸# LX2#"( @ B#??ϔy]ɣ~˥ϩΩxԭװڲܴ޷๒]L<'%9*- gL2&," A B<; UD4Ǣ}˥ΨЪҬӬ֯ر۳ݶ߸⺓~d'dJ2sV;gM5(yD0wY>* 0& B?;<,$wơ|ʤͧϩҫҬծװڲܵ޷Ṓ㻔|:+rU:uXz\@^H2 t oS8eH.$4) B;;=:/$;/%Š{Ȣ}ɤͧѪӭԭ֯ٱ۴װmq]I/' 0%4'5(7)8+9+9+"&8+A2%1'7,">;;<:/$;0%ZH8[J9\K9]L:^L;_N<_N=O@25,"i #$%&&'(% #) /%5* 0';;;;3);0%<1&=2&>2'6,"' x. 3 5 5 4 3 4 4 5 6 68:<2;RJ; 6<8 50.../013333> -;<<=>> ? ? @ @ B @;>C;;;;;<=>?????3 =7  8== e!#k??;2`   *= > R$&) +",#$ S?>*\ >'?*'  5 ? @q%*",$/&+")  v??5:  C,M4W=%H3! > A I.%0'1') *!*!F?<!Aw5"I1S9"\B)^E- 0 A B_*"4*,#*!*"+"*!]??/ j E-O6X>&bG.D2" > C D+"*!+"+#,#-$??9&J2T;#^C*gL2?/ b 7-%$5C D N+",#,$'L?=&OM5Z@'cH/mQ6WA.){,#;/%=2&8.->>=f'-$ g??3xgI3_E,iM3rV;{]A% ӨhdRC4B6*A5*6;BA?;4+'eI0nR7x[?bEhKH8( 9-#ܞağzΧѫt\0( %:;KR?>*]^E.tW<|_BgJpQyY`howʤ~Ӭܴ㼓9/%2;;ms??67$uY=dGlNuV~]eltŠ{ϩذ๒lYFB"<??<"Bw!ڀcGqRzZaiqx˥ԭݵmV k // k {mU?|\fmuǢ|ѪjA6*((] E7)lWCdQ>[J:4*!PPi02/!????????|???        @?@dnssec-trigger-0.13/winrc/alert.ico0000664000175000017500000007644611717264572016775 0ustar wouterwouter hF  00 %V@@ (B:(  % :'d.!L8%8  P7W>&V>(>.JL;"i ?S:";**)y`E|]gA/8);SA(FkQ}dL2hvΦ ~0G$iUD4J8)L.pmYE߉qX`G13'ytPJcܴծe 1%oQ5z]AsSCgS@-%C *<'E2!eJȡvFTfH-ÔC( I7&vWvk $A5'RC45 ?Ooga( @ G: ,G,J1  #2%%7$J1/  G2fJ/kN3sU98)r G% M3F1/ aE*aE,hL1pS7tV:3(RQ7S:"Z?'`E,YA*"(9,_-#R8!V<$_D*9)4@jT>~]f<1$w?+[@'O9$8 8' !֌nRbm)!J8&^C*_E-)aL8zaJŕwYhojL0gK1k 4'F8$ڳlpu^H| =_]b hJRC2sȡ{8!cvƠzI;.58 cuqWǡ|lSj cPr\F˥|_yc>- cSv_IΧbt݄cD biϩev]֯͡W"O;(\M8%yX {6,!~fNҫϩծݴ㺒ʠbQ@cpT8y[>aC9, ބeGo  ̥֭ϩܴܳibQ? !4&|_B{]AxZ>oU;jP7yYh ÞyknZE*"~>O6cH.xZ>lNd-$ Q AK2^C*qS8iJvVfq b:%V<$O:&'ٟ`n֮  cP6eI. ɢ|㹐  cY?%nQ6=. 9.#ѩśdf>,xZ>nOgQ. j#9%M4P67& J4`D)bF,bG-gK0oR5uW9qT9 i %B  *O5P6N6R9"\A(\B)cG-iL1YA+D2!6()"  pQC5&uvP6Q8!U;#X>&\B)eI.T<'% "yY_lU?HL3T:"V<$Z@'_E+=,Id8, b{[f|cJ <)X=$X>&^D*9)duh^J8qTa_iiOm'\@&\B(X?' u XF5" pShcnnXB>l [@']C*`F-"f %lQeQ= ݒtWiioH:, 5 N7"bF,kN2?.Z J6"qU;]uY I"祄dlpf h>-hK0^E-6'w ^J;,춒nnœw]L: #+'%&6ЎsVuuo ]78-"뾙tuǠzH:-:x=ͧfwˤ}jQMpZEȢ|̦l3 K<.̥ͥq Af z?3'Ϩ̥u#G #C1  ~A4(ѪΧw)"u, <5 qT9!\K:ҫԭmPB2lTj >*1P:&fH"+jy]ѩЪzeß}޵̙=2'$C2"% &~^@sT&E 'fR?ΧΨϩԭ߶߶ݵ录͢x_01$|\?xZ>P=* QcaH0lMa+"2'㢂dơ{Ѫ˥ϩԭذ߶辕仓}fN@3k'mR7{\?xZ>bD{^BI8(4&bDxYp ( ˤ}ʣ}ΧׯٱرͧgiVC4+!TZ@0 pT;bEbE`CeGoV<:,lQ7pQkb̴pԬwi}fOA6)t= N S>*dH.[A'cG.sV:eGjKzYr7-"L=0[I9&~P&3 N5[A(jN3wY>cFoP_wY DZ*( U6"L3W>&iM2vW;dFjLvWblz\ I/Q8 cG-S>)."fO8{Z_guu%-3!N4^B)T=(H9+}^nÞyΧ&EF.V<#eI/1$*!ػsͦ֯)! AL4]C)lP54'['Þyխܴ-L6 eI/uW;eL6|dLЩڲ޶ .!pR6uY=iKv\B6*3)fNǡ{ЩnOdK3dFkNzYfrşy˥߶۵6,"4 sY?{ZbhtͧḏڳL?2 [G5sUhpwv\ + _+#*"x4RT? x`???~< ?(@  2&@1 ' :% %AO\igS<%  =&A)C,F.% DTI<&B*E-G/9&|x *A0I6#O;'WA+T?+ U.D,F.I0I1z =,V>(bG.eJ0gL2jN4lP6oS8":| E-H0J2M4  @.[A)_D+aF-dI/fK1iM3kP5nR7C2"u G.I1L3N5/!0"Y?&[A(^C*`E,cH.eJ0hL2jO4mQ6pS8  ,@*K2M4P7E0?+W>%Z@'\B)_D+bG-dI/gK1iN3iN4bI0V@,@HjMI9)iG/L3O6Q8!T:#V=%Y?'[A)^C+aF-cH/[C,:+!rru\CwWw^D  N5P7 S9"U<$X>&Z@(]C*`E,W?), YShMxY{[vX-$N5R8!T;#W=%Y?'\B)^D+D1P yYzZ|\~^}]3) qB-S:"V<$X>&[A(]C*5&O=EB4'yY{[}]_aa9.#:. U;#W=%Z@'\B)I5"$ek dP=@3&wY^`bdd-#X V<$Y?&[A(^C*0#J5 fM ( ٚyZaceg}^ (U;$Z@(]B*_E,G4!o;."|]PA2'ٝ}]dfhjgNeC/\A)^D+aF-^D-F D1 bJ3jM^x\s,#ڧdhjlnN?0X-,]C*`E,bG.eI0 -=C1XB,hP9w^ElQ&>zTC3䮋ikmoe _D+aF-^E-I5# yρgNlnprVF5X1$  ֱkoqsiH8Jk|dLprtvD7+!e1G_!ֹqsuw}fN]P G_xϞatvxnPG_<lWC辚vxÞzơ|$ G_7,"wyŠ{Ǣ}>2&o G_#xğzơ|ɣ~O@1 G_ ÞyŠ{Ȣ}ʥ~_N<,+L7$!G_ ğzǡ|ɤ~̦fTAUa8!mQ6$G_3* Ơ{ȣ}˥~ͧJ<.6-#gUAt nza [B,y\@'G_XG7Ǣ}ʤ~̦ϩ&$bP?✀cϪݵ߸# LX2#rU:gJ+"G_2jϔy]ɣ~˥ϩΩxԭװڲܴ޷๒]L<'%9*- gL2~`DrS.%G_ UD4Ǣ}˥ΨЪҬӬ֯ر۳ݶ߸⺓~d'dJ2sV;gM5(yD0wY>kM}]2(G_#eQ>z^wơ|ʤͧϩҫҬծװڲܵ޷Ṓ㻔|:+rU:uXz\@^H2 t oS8eHvWg2(G_WF6wÞyŠ{Ȣ}ɤͧѪӭԭ֯ٱ۴װmq]I/' lR6tW;vY=y[?{^A}_B}`CP>, U>)|^BoQapG_xğzǡ|ɤ~̦ΨѪӭӭq|fO@4)] G5$sV1#)tW'G/Q8 [@(dI0lP5aH2aDlNtU}]dlsg-$G_:  C,M4W=%`E,T>) -#݄hL}]aipxy-$G_w5"I1S9"\B)^E- \I9处dltơ|ϩ0'G_E-O6X>&bG.D2";/$ݷpx˥ԭ2(G_J2T;#^C*gL2?/ b-#ٽuǡ|Ъٲ-$G_M5Z@'cH/mQ6WA.){VF5Þy̦ծݶ G_gI3_E,iM3rV;{]A% ӨhȢ}ҫڳڳ8J+'eI0nR7x[?bEhKH8( 9-#ܞağzΧ֯߸h^E.tW<|_BgJpQyY`howʤ~Ӭܴ㼓B6*7$uY=dGlNuV~]eltŠ{ϩذ๒lYF(8888888880w!ڀcGqRzZaiqx˥ԭݵmV{mU?|\fmuǢ|ѪjA6*] E7)lWCdQ>[J:4*!i02/!????@?dnssec-trigger-0.13/winrc/netlist.c0000664000175000017500000003775512275162157017014 0ustar wouterwouter/* * winrc/netlist.c - windows DHCP network listing service for dnssec trigger * * Copyright (c) 2011, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * */ #include "config.h" #include #include #include #include #ifdef HAVE_IPHLPAPI_H #include #endif #include "winrc/netlist.h" #include "winrc/win_svc.h" #include "riggerd/log.h" #include "riggerd/net_help.h" #include "riggerd/svr.h" #include "riggerd/probe.h" #include "riggerd/netevent.h" #include "riggerd/winsock_event.h" /* API constants for the Network Location Awareness API (winXP and later) * should be in mswsock.h but some crosscompile environments omit the API */ #ifndef NS_NLA /* the defines that we need to get adapter GUIDs */ #define NS_NLA 15 /* 6642243A-3BA8-4aa6-BAA5-2E0BD71FDD83 */ #define NLA_SERVICE_CLASS_GUID {0x37e515,0xb5c9,0x4a43,{0xba,0xda,0x8b,0x48,0xa8,0x7a,0xd2,0x39}} enum blobtype { NLA_INTERFACE = 1 }; typedef struct _NLA_BLOB { struct { enum blobtype type; DWORD dwSize; DWORD nextOffset; } header; union { struct { DWORD dwType; DWORD dwSpeed; CHAR adapterName[1]; } interfaceData; } data; } NLA_BLOB; #endif /* NS_NLA */ static WSAOVERLAPPED netlist_overlap; static WSACOMPLETION netlist_complete; static WSAEVENT netlist_event; static struct event netlist_ev; static HANDLE netlist_lookup; static char* netlist_netnames = NULL; static char* netlist_ips = NULL; static char* netlist_ssid = NULL; /** WLAN API (if not available). it should be in wlanapi.h and windot11.h, but * crosscompile environments may not have those header files */ #ifndef WLAN_API_VERSION #define WLAN_API_VERSION 0x1 #define WLAN_MAX_NAME_LENGTH 256 typedef enum { wlan_interface_state_not_ready = 0, wlan_interface_state_connected } WLAN_INTERFACE_STATE; typedef struct { GUID InterfaceGuid; WCHAR strInterfaceDescription[WLAN_MAX_NAME_LENGTH]; WLAN_INTERFACE_STATE isState; } WLAN_INTERFACE_INFO; typedef struct { DWORD dwNumberOfItems; DWORD dwIndex; WLAN_INTERFACE_INFO InterfaceInfo[1]; } WLAN_INTERFACE_INFO_LIST; #define DOT11_SSID_MAX_LENGTH 32 typedef struct { ULONG uSSIDLength; UCHAR ucSSID[DOT11_SSID_MAX_LENGTH]; } DOT11_SSID; typedef struct { DOT11_SSID dot11Ssid; /* .. BSSID, MacADDRESS, phytype, phytindex, quality, rrate, trate */ } WLAN_ASSOCIATION_ATTRIBUTES; typedef struct { WLAN_INTERFACE_STATE isState; enum { wlan_connection_mode_profile = 0 } wlanConnectionMode; WCHAR strProfileName[WLAN_MAX_NAME_LENGTH]; WLAN_ASSOCIATION_ATTRIBUTES wlanAssociationAttributes; /* .. wlanSecurityAttributes; */ } WLAN_CONNECTION_ATTRIBUTES; typedef enum { wlan_intf_opcode_current_connection = 7 } WLAN_INTF_OPCODE; typedef enum { wlan_opcode_value_type_query_only = 0 } WLAN_OPCODE_VALUE_TYPE; #endif /** fetch list of wlan SSIDs */ static void fetch_wlan_ssid(char* res, size_t reslen) { DWORD serviceVersion = 0; HANDLE client = NULL; DWORD r ; WLAN_INTERFACE_INFO_LIST* infolist = NULL; unsigned int i; char* p; static HMODULE wlandll = NULL; static DWORD WINAPI (*myWlanOpenHandle)(DWORD dwClientVersion, PVOID pReserved, PDWORD pdwNegotiatedVersion, PHANDLE phClientHandle); static DWORD WINAPI (*myWlanCloseHandle)(HANDLE hClientHandle, PVOID pReserved); static DWORD WINAPI (*myWlanEnumInterfaces)(HANDLE hClientHandle, PVOID pReserved, WLAN_INTERFACE_INFO_LIST **ppInterfaceList); static VOID WINAPI (*myWlanFreeMemory)(PVOID pMemory); static DWORD WINAPI (*myWlanQueryInterface)(HANDLE hClientHandle, const GUID *pInterfaceGuid, WLAN_INTF_OPCODE OpCode, PVOID pReserved, PDWORD pdwDataSize, PVOID *ppData, WLAN_OPCODE_VALUE_TYPE* pWlanOpcodeValueType); res[0] = 0; if(!wlandll) { /* see if we canload the wlan API dll (to get wlan SSID) */ wlandll = LoadLibrary("Wlanapi.dll"); if(!wlandll) { log_win_err("cannot LoadLibrary wlanapi.dll", GetLastError()); return; } /* get funcs */ myWlanOpenHandle = (DWORD(WINAPI*)(DWORD, PVOID, PDWORD, PHANDLE)) GetProcAddress(wlandll, "WlanOpenHandle"); myWlanCloseHandle = (DWORD(WINAPI*)(HANDLE, PVOID)) GetProcAddress(wlandll, "WlanCloseHandle"); myWlanEnumInterfaces = (DWORD(WINAPI*)(HANDLE, PVOID, WLAN_INTERFACE_INFO_LIST **)) GetProcAddress(wlandll, "WlanEnumInterfaces"); myWlanFreeMemory = (VOID(WINAPI*)(PVOID)) GetProcAddress(wlandll, "WlanFreeMemory"); myWlanQueryInterface = (DWORD(WINAPI*)(HANDLE, const GUID *, WLAN_INTF_OPCODE, PVOID, PDWORD, PVOID *, WLAN_OPCODE_VALUE_TYPE*)) GetProcAddress(wlandll, "WlanQueryInterface"); } r = myWlanOpenHandle(WLAN_API_VERSION, NULL, &serviceVersion, &client); if(r != ERROR_SUCCESS || client == NULL) { if(r == ERROR_SERVICE_NOT_ACTIVE) return; /* no wifi, or not started, no reason to err */ log_win_err("cannot WlanOpenHandle", r); return; } if( (r=myWlanEnumInterfaces(client, 0, &infolist)) != ERROR_SUCCESS) { log_win_err("cannot WlanEnumInterfaces", r); if(infolist) myWlanFreeMemory(infolist); myWlanCloseHandle(client, 0); return; } for(i=0; idwNumberOfItems; i++) { WLAN_CONNECTION_ATTRIBUTES* attr = NULL; PVOID data = NULL; DWORD sz = 0; if( (r=myWlanQueryInterface(client, &infolist->InterfaceInfo[i]. InterfaceGuid, wlan_intf_opcode_current_connection, 0, &sz, &data, 0)) != ERROR_SUCCESS) { log_win_err("cannot WlanQueryInterface", r); if(data) myWlanFreeMemory(data); continue; } attr = (WLAN_CONNECTION_ATTRIBUTES*)data; if(attr->isState != wlan_interface_state_connected) { /* not connected, not listed right now */ myWlanFreeMemory(data); continue; } if(strlen(res) + attr->wlanAssociationAttributes.dot11Ssid. uSSIDLength + 2 >= reslen) { /* too long */ myWlanFreeMemory(data); break; } p = res+strlen(res); p[0] = ' '; memmove(p+1, attr->wlanAssociationAttributes.dot11Ssid.ucSSID, attr->wlanAssociationAttributes.dot11Ssid.uSSIDLength); p[attr->wlanAssociationAttributes.dot11Ssid.uSSIDLength+1]=0; myWlanFreeMemory(data); } myWlanFreeMemory(infolist); myWlanCloseHandle(client, 0); } /** stop and close lookup */ static void stop_lookup(HANDLE lookup) { if(WSALookupServiceEnd(lookup) != 0) { log_err("WSALookupServiceEnd: %s", wsa_strerror(WSAGetLastError())); } } static int has_changed(char* netnames, char* ips, char* ssid) { if(!netlist_ips || !netlist_netnames || !netlist_ssid || strcmp(netlist_ips, ips) != 0 || strcmp(netlist_netnames, netnames) != 0 || strcmp(netlist_ssid, ssid) != 0) { verbose(VERB_DETAIL, "netlist is now: %s %s %s", netnames, ips, ssid); free(netlist_ips); free(netlist_netnames); free(netlist_ssid); netlist_ips = strdup(ips); netlist_netnames = strdup(netnames); netlist_ssid = strdup(ssid); return 1; } verbose(VERB_DETAIL, "netlist unchanged: %s", netnames); return 0; } /** replace characters with other characters */ static void replace_str(char* s, char a, char b) { while(*s) { if(*s == a) *s = b; s++; } } /** process network adapter */ static void process_adapter(const char* guid, char* dest, size_t len, char* netnames, size_t netlen) { char key[256]; char* res; uint8_t* bin = NULL; size_t binlen = 0; if(!guid) return; verbose(VERB_ALGO, "adapter %s", guid); snprintf(netnames+strlen(netnames), netlen-strlen(netnames), " %s", guid); /* registry lookups of the DNS servers */ /* replace , and ; with spaces */ /* append to the total string list */ snprintf(key, sizeof(key), "SYSTEM\\CurrentControlSet\\services" "\\Tcpip\\Parameters\\Interfaces\\%s", guid); res = lookup_reg_str(key, "DhcpNameServer"); if(res && strlen(res)>0) { size_t dlen = strlen(dest); replace_str(res, ',', ' '); replace_str(res, ';', ' '); verbose(VERB_ALGO, "dhcpnameserver %s", res); if(dlen + strlen(res) + 1 < len) { /* it fits in the dest array */ memmove(dest+dlen, res, strlen(res)+1); } } free(res); /* ipv6 */ snprintf(key, sizeof(key), "SYSTEM\\CurrentControlSet\\services" "\\Tcpip6\\Parameters\\Interfaces\\%s", guid); bin = lookup_reg_binary(key, "Dhcpv6DNSServers", &binlen); if(bin) { /* every 16 bytes is an IPv6 address (hopefully) */ size_t at = 0; while(at < binlen && binlen - at >= 16) { /* get the ipv6 server added */ size_t dlen = strlen(dest); char t[128]; if(inet_ntop(AF_INET6, &bin[at], t, sizeof(t))==0) { t[0] = 0; } verbose(VERB_ALGO, "dhcp6dnsservers (byte %d/%d) %s", (int)at, (int)binlen, t); /* add str + space + eos */ if(dlen + strlen(t) + 1 + 1 < len) { /* it fits in the dest array */ dest[dlen] = ' '; memmove(dest+dlen+1, t, strlen(t)+1); } at += 16; } free(bin); } } #ifdef HAVE_GETADAPTERSADDRESSES /** use the (XP) getAdaptersAddresses to look for UP networks and their DHCP, * because VirtualBox installs weird network adapters that make us have an * empty set of networks from WSALookupServiceBegin. */ static void sweep_adapters(char* netnames, size_t netnames_sz, char* result, size_t result_sz) { char buf[40960]; IP_ADAPTER_ADDRESSES *p, *list = (IP_ADAPTER_ADDRESSES*)&buf; ULONG r, sz = sizeof(buf), flags = 0; if((r=GetAdaptersAddresses(AF_UNSPEC, flags, NULL, list, &sz)) != ERROR_SUCCESS) { log_win_err("GetAdaptersAddresses", r); return; } if(sz > sizeof(buf)) { /* sanity check on buffer */ return; } /* inspect the adapters, to find ones we skipped and are UP with DHCP */ for(p=list; p; p=p->Next) { if( (p->Flags&IP_ADAPTER_DHCP_ENABLED) && (p->OperStatus&IfOperStatusUp) && !strstr(netnames, p->AdapterName)) { /* note that the dnsServers list for this structure * is now (likely) filled with 127.0.0.1 that * dnssec-trigger has configured itself, so we have * to go look in the registry */ verbose(VERB_ALGO, "GetAdaptersAddresses says %s is " "UP DHCP", p->AdapterName); process_adapter(p->AdapterName, result, result_sz, netnames, netnames_sz); } } } #endif /* HAVE_GETADAPTERSADDRESSES */ /** start lookup and notify daemon of the current list */ static HANDLE notify_nets(void) { int r; HANDLE lookup; char result[10240]; char netnames[10240]; char buf[20480]; WSAQUERYSET *qset = (WSAQUERYSET*)buf; DWORD flags = LUP_DEEP | LUP_RETURN_ALL; DWORD len; GUID nlaguid = NLA_SERVICE_CLASS_GUID; result[0]=0; netnames[0]=0; memset(qset, 0, sizeof(*qset)); qset->dwSize = sizeof(*qset); qset->dwNameSpace = NS_NLA; qset->lpServiceClassId = &nlaguid; /* not set ServiceInstance to a single network name */ verbose(VERB_ALGO, "netlist sweep"); /* open it */ if(WSALookupServiceBegin(qset, flags, &lookup) != 0) { DWORD r = WSAGetLastError(); if(r == RPC_S_SERVER_UNAVAILABLE || r == RPC_S_UNKNOWN_IF) { /* do not log 'RPC server not there yet', that happens * when we reboot and we came up before xx service */ verbose(VERB_ALGO, "WSALookupServiceBegin: %s", wsa_strerror(r)); } else log_err("WSALookupServiceBegin: %s", wsa_strerror(r)); sleep(1); return NULL; } /* check for available networks */ memset(qset, 0, sizeof(*qset)); len = sizeof(buf); while(WSALookupServiceNext(lookup, LUP_RETURN_ALL, &len, qset) == 0) { if(len > sizeof(buf)) { /* sanity check on the buffer */ stop_lookup(lookup); return NULL; } snprintf(netnames+strlen(netnames), sizeof(netnames)-strlen(netnames), " * %s", qset->lpszServiceInstanceName? qset->lpszServiceInstanceName:"-"); if(qset->lpszServiceInstanceName) verbose(VERB_ALGO, "service name %s", qset->lpszServiceInstanceName); if(qset->lpszComment) verbose(VERB_ALGO, "comment %s", qset->lpszComment); if(qset->lpszContext) verbose(VERB_ALGO, "context %s", qset->lpszContext); /* obtain GUID of interface names of the networks */ if(qset->lpBlob != NULL) { DWORD off = 0; do { NLA_BLOB* p = (NLA_BLOB*)&(qset->lpBlob-> pBlobData[off]); if( (size_t)((void*)p - (void*)buf) >= sizeof(buf)) break; /* sanity check */ if(p->header.type == NLA_INTERFACE) { /* process it (registry lookup) */ process_adapter(p->data. interfaceData.adapterName, result, sizeof(result), netnames, sizeof(netnames)); } if(p->header.nextOffset <= off) break; /* no endless loop */ off = p->header.nextOffset; } while(off != 0); } memset(qset, 0, sizeof(*qset)); len = sizeof(qset); } /* see if we terminated OK or with an error. */ r = WSAGetLastError(); if( 1 #ifdef WSAENOMORE || r == WSAENOMORE #endif #ifdef WSA_E_NO_MORE || r == WSA_E_NO_MORE #endif ) { char ssid[10240]; #ifdef HAVE_GETADAPTERSADDRESSES /* see if we have additional information, on XP and later */ sweep_adapters(netnames, sizeof(netnames), result, sizeof(result)); #endif /* HAVE_GETADAPTERSADDRESSES */ /* start the probe for the notified IPs from up networks */ fetch_wlan_ssid(ssid, sizeof(ssid)); if(has_changed(netnames, result, ssid)) { probe_start(result); } return lookup; } /* we failed */ log_err("WSALookupServiceNext: %s", wsa_strerror(r)); stop_lookup(lookup); return NULL; } /** add an event to the server to wait for changes */ static void netlist_add_event(HANDLE lookup, struct svr* svr) { DWORD bytesret = 0; netlist_event = WSACreateEvent(); if(netlist_event == WSA_INVALID_EVENT) { fatal_exit("WSACreateEvent: %s", wsa_strerror(WSAGetLastError())); } netlist_overlap.hEvent = netlist_event; netlist_complete.Type = NSP_NOTIFY_EVENT; netlist_complete.Parameters.Event.lpOverlapped = &netlist_overlap; if(WSANSPIoctl(lookup, SIO_NSP_NOTIFY_CHANGE, NULL, 0, NULL, 0, &bytesret, &netlist_complete) != NO_ERROR) { int r = WSAGetLastError(); if(r != WSA_IO_PENDING) { WSACloseEvent(netlist_event); fatal_exit("WSANSPIoctl: %s", wsa_strerror(WSAGetLastError())); } } if(!winsock_register_wsaevent(comm_base_internal(svr->base), &netlist_ev, netlist_event, &netlist_change_cb, lookup)) { fatal_exit("cannot register netlist event"); } netlist_lookup = lookup; } /** remove and close netlist event */ static void netlist_remove_event(HANDLE* lookup) { winsock_unregister_wsaevent(&netlist_ev); stop_lookup(lookup); WSACloseEvent(netlist_event); } /** callback for change */ void netlist_change_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), void* arg) { HANDLE lookup = (HANDLE)arg; netlist_remove_event(lookup); lookup = notify_nets(); while(!lookup) { sleep(1); /* wait until netinfo is possible */ lookup = notify_nets(); } netlist_add_event(lookup, global_svr); } void netlist_start(struct svr* svr) { HANDLE lookup = NULL; while(!lookup) { lookup = notify_nets(); if(!lookup) sleep(1); /* wait until netinfo is possible */ } netlist_add_event(lookup, svr); } void netlist_stop(void) { netlist_remove_event(netlist_lookup); } dnssec-trigger-0.13/winrc/gen_msg.mc0000664000175000017500000000133111632412661017075 0ustar wouterwouter; for dnssec-trigger ; severity default Success Informational Warning Error ; .bin file created with: ; "/c/Program Files/Microsoft SDKs/Windows/v6.1/Bin/mc" -c gen_msg.mc ; mv MSG00001.bin gen_msg.bin ; rm gen_msg.h ; and pasted contents of gen_msg.rc into rsrc_bla.rc FacilityNames=(Server=0x1) MessageIdTypeDef=DWORD MessageID=0x1 Severity=Success Facility=Server SymbolicName=MSG_GENERIC_SUCCESS Language=English %1 . MessageID=0x2 Severity=Informational Facility=Server SymbolicName=MSG_GENERIC_INFO Language=English %1 . MessageID=0x3 Severity=Warning Facility=Server SymbolicName=MSG_GENERIC_WARN Language=English %1 . MessageID=0x4 Severity=Error Facility=Server SymbolicName=MSG_GENERIC_ERR Language=English %1 . dnssec-trigger-0.13/winrc/w_inst.c0000664000175000017500000002574712275162157016633 0ustar wouterwouter/* * winrc/w_inst.h - install and remove functions * * Copyright (c) 2009, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * Contains install and remove functions that manipulate the * windows services API and windows registry. */ #include "config.h" #include "winrc/w_inst.h" #include "winrc/win_svc.h" void wsvc_err2str(char* str, size_t len, const char* fixed, DWORD err) { LPTSTR buf; if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, err, 0, (LPTSTR)&buf, 0, NULL) == 0) { /* could not format error message */ snprintf(str, len, "%s GetLastError=%d", fixed, (int)err); return; } snprintf(str, len, "%s (err=%d): %s", fixed, (int)err, buf); LocalFree(buf); } /** exit with windows error */ static void fatal_win(FILE* out, const char* str) { char e[256]; wsvc_err2str(e, sizeof(e), str, (int)GetLastError()); if(out) fprintf(out, "%s\n", e); else fprintf(stderr, "%s\n", e); exit(1); } /** install registry entries for eventlog */ static void event_reg_install(FILE* out, const char* pathname) { char buf[1024]; HKEY hk; DWORD t; if(out) fprintf(out, "install reg entries for %s\n", pathname); snprintf(buf, sizeof(buf), "SYSTEM\\CurrentControlSet\\Services" "\\EventLog\\Application\\%s", SERVICE_NAME); if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)buf, 0, /* reserved, mustbezero */ NULL, /* class of key, ignored */ REG_OPTION_NON_VOLATILE, /* values saved on disk */ KEY_WRITE, /* we want write permission */ NULL, /* use default security descriptor */ &hk, /* result */ NULL)) /* not interested if key new or existing */ fatal_win(out, "could not create registry key"); /* message file */ if(RegSetValueEx(hk, (LPCTSTR)"EventMessageFile", 0, /* reserved, mustbezero */ REG_EXPAND_SZ, /* value type (string w env subst) */ (BYTE*)pathname, /* data */ (DWORD)strlen(pathname)+1)) /* length of data */ { RegCloseKey(hk); fatal_win(out, "could not registry set EventMessageFile"); } /* event types */ t = EVENTLOG_SUCCESS | EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE; if(RegSetValueEx(hk, (LPCTSTR)"TypesSupported", 0, REG_DWORD, (LPBYTE)&t, sizeof(t))) { RegCloseKey(hk); fatal_win(out, "could not registry set TypesSupported"); } /* category message file */ if(RegSetValueEx(hk, (LPCTSTR)"CategoryMessageFile", 0, REG_EXPAND_SZ, (BYTE*)pathname, (DWORD)strlen(pathname)+1)) { RegCloseKey(hk); fatal_win(out, "could not registry set CategoryMessageFile"); } t = 1; if(RegSetValueEx(hk, (LPCTSTR)"CategoryCount", 0, REG_DWORD, (LPBYTE)&t, sizeof(t))) { RegCloseKey(hk); fatal_win(out, "could not registry set CategoryCount"); } RegCloseKey(hk); if(out) fprintf(out, "installed reg entries\n"); } /** remove registry entries for eventlog */ static void event_reg_remove(FILE* out) { char buf[1024]; HKEY hk; if(out) fprintf(out, "remove reg entries\n"); snprintf(buf, sizeof(buf), "SYSTEM\\CurrentControlSet\\Services" "\\EventLog\\Application"); if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)buf, 0, /* reserved, mustbezero */ NULL, /* class of key, ignored */ REG_OPTION_NON_VOLATILE, /* values saved on disk */ DELETE, /* we want key delete permission */ NULL, /* use default security descriptor */ &hk, /* result */ NULL)) /* not interested if key new or existing */ fatal_win(out, "could not open registry key"); if(RegDeleteKey(hk, (LPCTSTR)SERVICE_NAME)) { RegCloseKey(hk); fatal_win(out, "could not delete registry key"); } RegCloseKey(hk); if(out) fprintf(out, "removed reg entries\n"); } /** * put quotes around string. Needs one space in front * @param out: debugfile * @param str: to be quoted. * @param maxlen: max length of the string buffer. */ static void quote_it(FILE* out, char* str, size_t maxlen) { if(strlen(str) == maxlen) { if(out) fprintf(out, "string too long %s", str); exit(1); } str[0]='"'; str[strlen(str)+1]=0; str[strlen(str)]='"'; } /** change suffix */ static void change(FILE* out, char* path, size_t max, const char* from, const char* to) { size_t fromlen = strlen(from); size_t tolen = strlen(to); size_t pathlen = strlen(path); if(pathlen - fromlen + tolen >= max) { if(out) fprintf(out, "string too long %s", path); exit(1); } snprintf(path+pathlen-fromlen, max-(pathlen-fromlen), "%s", to); } /* Install service in servicecontrolmanager */ void wsvc_install(FILE* out, const char* rename) { SC_HANDLE scm; SC_HANDLE sv; TCHAR path[MAX_PATH+2+256]; if(out) fprintf(out, "installing %s service\n", SERVICE_NAME); if(!GetModuleFileName(NULL, path+1, MAX_PATH)) fatal_win(out, "could not GetModuleFileName"); /* change 'unbound-service-install' to 'unbound' */ if(rename) change(out, path+1, sizeof(path)-1, rename, "dnssec-triggerd.exe"); event_reg_install(out, path+1); /* have to quote it because of spaces in directory names */ /* could append arguments to be sent to ServiceMain */ quote_it(out, path, sizeof(path)); strcat(path, " -w service"); scm = OpenSCManager(NULL, NULL, (int)SC_MANAGER_CREATE_SERVICE); if(!scm) fatal_win(out, "could not OpenSCManager"); /* the dnssectrigger service depends on 'unbound' to start, * because it will signal it to do stuff */ sv = CreateService( scm, SERVICE_NAME, /* name of service */ "Dnssec Trigger", /* display name */ SERVICE_ALL_ACCESS, /* desired access */ SERVICE_WIN32_OWN_PROCESS, /* service type */ SERVICE_AUTO_START, /* start type */ SERVICE_ERROR_NORMAL, /* error control type */ path, /* path to service's binary */ NULL, /* no load ordering group */ NULL, /* no tag identifier */ "unbound\0\0", /* DependsOn */ NULL, /* on LocalSystem */ NULL /* no password */ ); if(!sv) { CloseServiceHandle(scm); fatal_win(out, "could not CreateService"); } CloseServiceHandle(sv); CloseServiceHandle(scm); if(out) fprintf(out, "%s service installed\n", SERVICE_NAME); } /* Remove installed service from servicecontrolmanager */ void wsvc_remove(FILE* out) { SC_HANDLE scm; SC_HANDLE sv; if(out) fprintf(out, "removing %s service\n", SERVICE_NAME); scm = OpenSCManager(NULL, NULL, (int)SC_MANAGER_ALL_ACCESS); if(!scm) fatal_win(out, "could not OpenSCManager"); sv = OpenService(scm, SERVICE_NAME, DELETE); if(!sv) { CloseServiceHandle(scm); fatal_win(out, "could not OpenService"); } if(!DeleteService(sv)) { CloseServiceHandle(sv); CloseServiceHandle(scm); fatal_win(out, "could not DeleteService"); } CloseServiceHandle(sv); CloseServiceHandle(scm); event_reg_remove(out); if(out) fprintf(out, "%s service removed\n", SERVICE_NAME); } /* Start daemon */ void wsvc_rc_start(FILE* out) { SC_HANDLE scm; SC_HANDLE sv; if(out) fprintf(out, "start %s service\n", SERVICE_NAME); scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if(!scm) fatal_win(out, "could not OpenSCManager"); sv = OpenService(scm, SERVICE_NAME, SERVICE_START); if(!sv) { CloseServiceHandle(scm); fatal_win(out, "could not OpenService"); } if(!StartService(sv, 0, NULL)) { CloseServiceHandle(sv); CloseServiceHandle(scm); fatal_win(out, "could not StartService"); } CloseServiceHandle(sv); CloseServiceHandle(scm); if(out) fprintf(out, "%s service started\n", SERVICE_NAME); } /* Stop daemon */ void wsvc_rc_stop(FILE* out) { SC_HANDLE scm; SC_HANDLE sv; SERVICE_STATUS st; if(out) fprintf(out, "stop %s service\n", SERVICE_NAME); scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if(!scm) fatal_win(out, "could not OpenSCManager"); sv = OpenService(scm, SERVICE_NAME, SERVICE_STOP); if(!sv) { CloseServiceHandle(scm); fatal_win(out, "could not OpenService"); } if(!ControlService(sv, SERVICE_CONTROL_STOP, &st)) { CloseServiceHandle(sv); CloseServiceHandle(scm); fatal_win(out, "could not ControlService"); } CloseServiceHandle(sv); CloseServiceHandle(scm); if(out) fprintf(out, "%s service stopped\n", SERVICE_NAME); } void wsvc_rc_waitstop(FILE* out, const char* name) { int count = 0; SC_HANDLE scm; if(!name) name = SERVICE_NAME; if(out) fprintf(out, "waitstop %s service\n", name); scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if(!scm) fatal_win(out, "could not OpenSCManager"); while(1) { SC_HANDLE sv; SERVICE_STATUS st; sv = OpenService(scm, name, SERVICE_QUERY_STATUS); if(!sv) { CloseServiceHandle(scm); fatal_win(out, "could not OpenService"); } memset(&st, 0, sizeof(st)); if(!QueryServiceStatus(sv, &st)) { CloseServiceHandle(sv); CloseServiceHandle(scm); fatal_win(out, "could not QueryServiceStatus"); } CloseServiceHandle(sv); /* check the status */ if(st.dwCurrentState == SERVICE_STOPPED) break; /* wait one second */ if(count++ > 120) { if(out) fprintf(out, "timed out\n"); break; } if(out) fprintf(out, "...\n"); Sleep(1000); } CloseServiceHandle(scm); if(out) fprintf(out, "%s service stopped\n", name); } dnssec-trigger-0.13/winrc/proc_dll_src/0000775000175000017500000000000013024457644017613 5ustar wouterwouterdnssec-trigger-0.13/winrc/proc_dll_src/processes.h0000664000175000017500000000270211704032363021761 0ustar wouterwouter#pragma once //------------------------------------------------------------------------------------------- // PSAPI function pointers typedef BOOL (WINAPI *lpfEnumProcesses) ( DWORD *, DWORD, DWORD * ); typedef BOOL (WINAPI *lpfEnumProcessModules) ( HANDLE, HMODULE *, DWORD, LPDWORD ); typedef DWORD (WINAPI *lpfGetModuleBaseName) ( HANDLE, HMODULE, LPTSTR, DWORD ); typedef BOOL (WINAPI *lpfEnumDeviceDrivers) ( LPVOID *, DWORD, LPDWORD ); typedef BOOL (WINAPI *lpfGetDeviceDriverBaseName)( LPVOID, LPTSTR, DWORD ); //------------------------------------------------------------------------------------------- // Internal use routines bool LoadPSAPIRoutines( void ); bool FreePSAPIRoutines( void ); bool FindProc( char *szProcess ); bool KillProc( char *szProcess ); bool FindDev( char *szDriverName ); //------------------------------------------------------------------------------------------- // Exported routines __declspec(dllexport) void FindProcess( HWND hwndParent, int string_size, char *variables, stack_t **stacktop ); __declspec(dllexport) void KillProcess( HWND hwndParent, int string_size, char *variables, stack_t **stacktop ); __declspec(dllexport) void FindDevice( HWND hwndParent, int string_size, char *variables, stack_t **stacktop ); dnssec-trigger-0.13/winrc/proc_dll_src/exdll.c0000664000175000017500000000166611704032363021066 0ustar wouterwouter#include #include "exdll.h" HINSTANCE g_hInstance; HWND g_hwndParent; void __declspec(dllexport) myFunction(HWND hwndParent, int string_size, char *variables, stack_t **stacktop) { g_hwndParent=hwndParent; EXDLL_INIT(); // note if you want parameters from the stack, pop them off in order. // i.e. if you are called via exdll::myFunction file.dat poop.dat // calling popstring() the first time would give you file.dat, // and the second time would give you poop.dat. // you should empty the stack of your parameters, and ONLY your // parameters. // do your stuff here { char buf[1024]; wsprintf(buf,"$0=%s\n",getuservariable(INST_0)); MessageBox(g_hwndParent,buf,0,MB_OK); } } BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) { g_hInstance=(HINSTANCE)hInst; return TRUE; } dnssec-trigger-0.13/winrc/proc_dll_src/make.sh0000664000175000017500000000045511704035376021065 0ustar wouterwouter#i686-pc-mingw32-gcc processes.cpp -o bla.dll -mdll -nodefaultlibs -luser32 -lgcc -lmoldname -lmingw32 -lmsvcrt -lkernel32 echo gcc i686-pc-mingw32-gcc -g -O2 processes.c -o proc.dll -mdll -nostartfiles -e __DllMainCRTStartup@12 ls -l proc.dll echo strip i686-pc-mingw32-strip proc.dll ls -l proc.dll dnssec-trigger-0.13/winrc/proc_dll_src/proc.dll0000775000175000017500000001400011704032363021237 0ustar wouterwouterMZ@ !L!This program cannot be run in DOS mode. $PELo/O#  @gp? @rPp`PT.text   P`.rdata @0@.bss,00.edatar@@0@.idatapP@0.reloc`@0BS0@gt.t(ST$$l 0@g$` 1Ƀ[Ð&t D$0@g0@gB$ Ðt&D$ 0@g $ @g1Ƀ 0@gD$ @g$(0@g 0@gD$ @g$0@g 0@gD$+ @g$0@g 0@gD$> @g$0@g 0@gD$P @g$g(0@gң0@gt- 0@gt#0@gt 0@gttȃá 0@g$#1ɉȃÍt& 0@g(0@g0@g0@g0@g$ÍU<(WVS"1)č$, D$|$1DŽ$,(󫋄$P(D$$, $$, $Mu <([^_]Í$,(t$,D$D$4$(0@g $,($,$<$1D$$D$ tō$,(D$ $,D$D$<$0@gu$,D$ l$<$D$0@g`,$$, D$,$=6<$E1ہ<([^_]fU<,WVSr)č$, $P,D$|$1$,$T$DŽ$,,f$\$D$ i @gD$n @g[$, \$1ۉ$6$, $$,$$_u <,[^_]Í$,,t$,T$D$4$(0@g g$,,$,(<$$)1D$$D$ tō$,,$,T$ D$D$<$0@gu$,D$ l$<$D$0@g`,$$, T$,$!t$,$D$,$ &1D$<$Mt2D$s @g$$$<$xv1ہ<,[^_]WfU<WVS"1)č$,D$|$1DŽ$,󫋄$P$$,$D$ Tu<[^_]Ív$,l$,D$D$,$0@g $,$,D$$,&|$1fD$t$D$0@g t$,$t$D$ @gX$,$1$,T$$>ze V1ہ<[^_]Í&;S$ \$$0@g$$0@g$,0@g$(0@gN$6u"$D$ @g{[Ív$D$ @gY[ÐS$ \$$0@g$$0@g$,0@g$(0@g$Vu"$D$ @g.[Ív$D$ @g [ÐS$ \$$0@g$$0@g$,0@g$(0@g.$u"$D$ @g[[Ív$D$ @g|9[ÐQP=L$ r -=w) XYÐ%P@g%P@g%P@g%P@g%P@g%P@g%Q@g%P@g%Q@g%P@g%P@g%P@g%P@g%P@g%P@g%P@g%P@gPSAPI.DLLEnumProcessesEnumProcessModulesGetModuleBaseNameAEnumDeviceDriversGetDeviceDriverBaseNameA.exe%s%sShell_TrayWnd%S10o/OF@(@4@@@pO@Z@f@proc.dllFindDeviceFindProcessKillProcessdPRPP,RPPHRPPdRP QQ(Q:QHQXQfQzQQQQQQQQQQ QQ(Q:QHQXQfQzQQQQQQQQQQRCloseHandle`FreeLibraryAGetProcAddressGlobalFree1LoadLibraryAuOpenProcessTerminateProcesslstrcpyAS_strlwrsprintfstrcmpstrcpystrstrFindWindowAGetDesktopWindownUpdateWindow~wsprintfAPPPPPPPPKERNEL32.dllPmsvcrt.dll(P(P(P(Pmsvcrt.dll   Root Entry *ZProjInfoExTaskListUserTasks$IToolboxService I1 bJ!>#2%&'()*+,-./a356789:;<=@ABCDEFGHKMNdRSTUVWXYZ[\]^cef6/?zF*Qh;C Device ControlsCrystal ReportsData XML Schema Dialog EditorMobile Web Forms Web Forms Components Windows FormsHTMLClipboard RingGeneral" EndOfStreamC:\cygwin\home\jeremiah\soolIVSMDPropertyBrowser*SourceCodeControl$,DebuggerWatches DebuggerBreakpoints(DebuggerExceptions& DebuggerFindSource& DebuggerFindSymbol&DebuggerMemoryWindows,TC:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\crt\src\C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\src\mfc\C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\src\atl\processes C:\cygwin\home\jeremiah\sooloos\DesktopClient\Win\insd/n ([\ ${343n}ͫ4ᆳͫ4ᆳMultiStartupProj=;4{3438467F-A719-46DC-93E5-137A8B691727}ExternalFilesProjectContents:DocumentWindowPositions0DocumentWindowUserData. SolutionConfiguration,.dwStartupOpt=;StartupProject=&{3438467F-A719-46DC-93E5-137A8B691727};?{3438467F-A719-46DC-93E5-137A8B691727}.Release|Win32.fBatchBld=;={3438467F-A719-46DC-93E5-137A8B691727}.Debug|Win32.fBatchBld=;4{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3NSܾ M%%ү##G}'bm4l #O¤Eprocesses#FindProcDLLIPrQ C:\cygwin\home\jeremiah\sooloos\DesktopClient\Win\install\NSIDebug|Win32DebugSettings... ....... .,GeneralConfigSettingsVCBscMakeTool 0.\Debug/FindProcDLL.bsc(EndConfigPropertiesRelease|Win32DebugSettings... ....... .,GeneralConfigSettingsVCBscMakeTool 4.\Release/FindProcDLL.bsc(EndConfigPropertiesrocDLLObjMgrContents  ClassViewContents$ProjExplorerState$"UnloadedProjects"FindProcDLL$TaskListShortcuts$0ResEdit.optProcess4lX (EndConfigPropertiesReoos\DesktopClient\Win\install\NSS\Plugins\processes\src\processes.vcprojojSource FilesDebug|Win32DebugSettings... ....... .,GeneralConfigSettingsVCBscMakeTool(EndConfigPropertiesRelease|Win32DebugSettings... ....... .,GeneralConfigSettingsVCBscMakeTool(EndConfigPropertiesocess719-46DC-93E5-137A8B69172Debug|Win32DebugSettings... ....... .,GeneralConfigSettingsVCBscMakeTool(EndConfigPropertiesRelease|Win32DebugSettings... ....... .,GeneralConfigSettingsVCBscMakeToolprocesses?lOutliningState2 POutliningState1 QVVsToolboxService"_(EndConfigPropertiesVCBscMakeTol(EndConfigPropertiesRel}.dwStartupOpt=; ActiveCfg= Release|Win32;j|f:\prisma\seS$ A+HڪWLl #O¤EL%ү##G}'bm4S8fLd9Ll #O¤EL%ү##G}'bm4365922C2A22}12rties,GeneralCc:\cygwin\home\jeremiah\s7 `c:\cygwin\home\jeremiah\sooloos\DesktopClient\Win\install\NSIS\Plugins\processes\src\processes.cppD'()*FGHIYZ ]ikprvx ^  !#+-@B" K"Pg"l"XmlPackageOptions$`ObjMgrContentsV8"LHiddenSlnFolders"OutliningStateDir$OIS\Plugins\processes\src\tall\NSIS\Plugins\processes\src\processes ooloos\DesktopClient\Win\install\NSIS\Plugins\processes\src\processes.cpp$Bookmarks V001.01BookmarkStateg(dnssec-trigger-0.13/winrc/proc_dll_src/exdll.h0000664000175000017500000000445611704032363021073 0ustar wouterwouter#ifndef _EXDLL_H_ #define _EXDLL_H_ // // only include this file from one place in your DLL. // (it is all static, if you use it in two places it will fail) // #define EXDLL_INIT() { \ g_stringsize = string_size; \ g_stacktop = stacktop; \ g_variables = variables; } // // For page showing plug-ins // #define WM_NOTIFY_OUTER_NEXT (WM_USER+0x8) #define WM_NOTIFY_CUSTOM_READY (WM_USER+0xd) #define NOTIFY_BYE_BYE 'x' typedef struct _stack_t { struct _stack_t *next; char text[1]; // this should be the length of string_size } stack_t; static unsigned int g_stringsize; static stack_t **g_stacktop; static char *g_variables; enum { INST_0, // $0 INST_1, // $1 INST_2, // $2 INST_3, // $3 INST_4, // $4 INST_5, // $5 INST_6, // $6 INST_7, // $7 INST_8, // $8 INST_9, // $9 INST_R0, // $R0 INST_R1, // $R1 INST_R2, // $R2 INST_R3, // $R3 INST_R4, // $R4 INST_R5, // $R5 INST_R6, // $R6 INST_R7, // $R7 INST_R8, // $R8 INST_R9, // $R9 INST_CMDLINE, // $CMDLINE INST_INSTDIR, // $INSTDIR INST_OUTDIR, // $OUTDIR INST_EXEDIR, // $EXEDIR INST_LANG, // $LANGUAGE __INST_LAST }; // // utility functions (not required but often useful) // static int popstring( char *str ) { stack_t *th; if( !g_stacktop || !*g_stacktop ) return 1; th = (*g_stacktop); lstrcpy( str, th->text ); *g_stacktop = th->next; GlobalFree( (HGLOBAL)th ); return 0; } static void pushstring( char *str ) { stack_t *th; if( !g_stacktop ) return; th = (stack_t*)GlobalAlloc( GPTR, sizeof(stack_t) + g_stringsize ); lstrcpyn( th->text, str, g_stringsize ); th->next = *g_stacktop; *g_stacktop = th; } static char *getuservariable( int varnum ) { if( varnum < 0 || varnum >= __INST_LAST ) return NULL; return (g_variables + varnum*g_stringsize); } static void setuservariable( int varnum, char *var ) { if( var != NULL && varnum >= 0 && varnum < __INST_LAST ) lstrcpy( g_variables + varnum*g_stringsize, var ); } #endif//_EXDLL_H_dnssec-trigger-0.13/winrc/proc_dll_src/stdafx.cpp0000664000175000017500000000045211717204640021602 0ustar wouterwouter// stdafx.cpp : source file that includes just the standard includes // KillProcDLL.pch will be the pre-compiled header // stdafx.obj will contain the pre-compiled type information #include "stdafx.h" // TODO: reference any additional headers you need in STDAFX.H // and not in this file dnssec-trigger-0.13/winrc/proc_dll_src/processes.rc0000664000175000017500000000472511704032363022145 0ustar wouterwouter// Microsoft Visual C++ generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE BEGIN "resource.h\0" END 2 TEXTINCLUDE BEGIN "#include ""afxres.h""\r\n" "\0" END 3 TEXTINCLUDE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Version // VS_VERSION_INFO VERSIONINFO FILEVERSION 1,0,0,1 PRODUCTVERSION 1,0,0,1 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x4L FILETYPE 0x2L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "Comments", "NSIS Plug-in for Windows process management. Only WinNT, Win2K, WinXP and Win2003 Server supported." VALUE "CompanyName", "Andrei Ciubotaru [Hardwired]" VALUE "FileDescription", "Windows Processes Management" VALUE "FileVersion", "1, 0, 0, 1" VALUE "InternalName", "Processes" VALUE "LegalCopyright", "Copyright (c) 2004 Hardwired. No rights reserved." VALUE "OriginalFilename", "Processes.dll" VALUE "ProductName", "Processes" VALUE "ProductVersion", "1, 0, 0, 1" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED dnssec-trigger-0.13/winrc/proc_dll_src/processes.vcproj0000664000175000017500000001546211704032363023044 0ustar wouterwouter dnssec-trigger-0.13/winrc/proc_dll_src/stdafx.h0000664000175000017500000000136611704032363021251 0ustar wouterwouter#if !defined(AFX_STDAFX_H__780690DC_E128_403D_BC07_780D1B2CC101__INCLUDED_) #define AFX_STDAFX_H__780690DC_E128_403D_BC07_780D1B2CC101__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #define NOGDI #include #include // String management... #include #include #ifdef BORLANDC #include #include #endif //To make it a NSIS Plug-In #include "exdll.h" //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_STDAFX_H__780690DC_E128_403D_BC07_780D1B2CC101__INCLUDED_) dnssec-trigger-0.13/winrc/proc_dll_src/Processes.dll0000664000175000017500000014300011704032363022242 0ustar wouterwouterMZ@ !L!This program cannot be run in DOS mode. $@*}D.D.D.P.D.kh.D.kh.D.kh.]D. f.D.E.UD.kh.D.kh.D.kh.D.kh.D.RichD.PELGQN!  xJrIwt< X@(.textwx `.rdataw$&|@@.data+@.rsrc @@.relocr @BhPV5hP֣hPh̩P֋ PhQd֋PhR`֣\PhPփ=hX^t"=dt=\t=`ttË PQ23hd`\PPU(S[3ʼnEVhjPDžVh$QARut"PhQhuM2^M3f]SW IhjRM PjhӋtjQhRVduDhPQV`t&RuPQ u&VOb}_[2^M3]eVM_[3Ͱ^u]U,Y3ʼnEVhjPDžIhjQ6h(Vh0RVh$PQtRtRhHP QRqPtNt2^M3']M3Ͱ^]U3ʼnEEM UTE LHD<uhLQ hPR 3M3]U3ʼnEEM UTE LHD<uhLQ hPR M3]U3ʼnEEM UTE LHDpE<uhLQ hPR M3_]̅t DPLAR̡HVt%0tFPQHV3^ø^; űT$ L$ti3D$ur=toWr1كt +шuʃtt uD$_ËD$ËU SW3j3Y}]9] uME;tVEEEPSu EPEEBMxE EPSpYY^_[̋L$WSV|$toqtUL$:tt :t u^[_3Ê:u~at(:uAtf:t3^[_mG^[_Ë^[_̋T$L$u<:u. t&:au% t:Au t:au uҋ3Ðt:u ttf:u t:au tjh%E uz$u38u$n$0#yp"x s xjYu  3;u[9=~ }9=@uh9}u K$E39}u=tjuYhjYY; V55,ЅtWVYY(NV!YuW'Y3@ $ j h#]3@Eu 9e;tu.`tWVSЉE}WVSCEWVS&Eu$u WPS&WjS`tWjSЅtu&WVSu!E}t`tWVSЉEEEE PQ&YYËeE3#ËU} u&uMU Y] U( 5=ff fff%f-EEE0 @(j%Yj<hd8=(uj%Yh 4PfQSuƒt7$ffAfA fA0fA@fAPfA`fApHuЅt7tIfIHut3tIJutAHu[XËۃ+3RӃtAJutIKuZUj D3ËUQVu Va0E F Yu N /@t "S3ۨt^NF F F ^] u,>. ;t 2.@;u u -YuVy-YF WF>HN+IN;~WPu u, EM F yM tt@ tjSSQC$#ƒt%FM3GWEPu , E9}t N E%_[^ËUEVF ucmFHlHhN; t pHpu8F;xtF pHpu0FF@puHpF  @F^]A @tyt$Ix  QPYYu ËUQSV G @Et uJ (EKE>u 8*u ϰ?u 8u M^[ËUx3ʼnES]Vu3Wu} ku+  t `p F @u^V=-Yttȃ A$uttȃ@$q3;g3ɉ9 G9& Bu|à ËUVMQY0^]̍B[Í$d$3D$ST$t :tτtQu WV ؋ ~333ƃu%t%uu^_[3ËB:t6t:t't:tt:tt^_B[ÍB^_[ÍB^_[ÍB^_[jHLV5Pu5,V5T^átP5 ,Ѓ tPX n,jhh`uF\Xf3G~~pƆCƆKCFhPj T-Yevh\E>j 3-Y}E FluFlvl6%YE3Guj ,Yj ,YËVWh5ЋuNhjYYt:V55,ЅtjVYY(N VAY3Wd_^ËVujY^jh( uF$tPYF,tPYF4tPYF,(,Y;stЃ;r=_^thi-Yt jjj3]j hPXj&Ye3@9D@E<} 55,֋؉]Ѕth5֋}ԉ]܉}؃};rKK9t;r>7֋85֋59]u9Et]܉]ЉE؋}ԋ]EH}TsEtЃEEX}\sEtЃEE }u)Dj$Yu}tj$YjËUjju ]jjj ËUv.u,Yh̋ULVEPj@j ^VYY3;u5;s6Hf@ Hf@ @! H3H/5@P;rSWf9ME;EþE;|9}kj@j YYtQ ;s1H```3f@ f@ @/@΍P;r҃9|3~rEt\tWM tMu Pt=4EEFhF PFEGE;|3ۋ5t tNqFujX CPtBt>Wt3%>uN@ uNhF Pt,F N@Ch5|3_[^ÃVWt6;s!p ~tV@N;r7'Y|_^Ã=uV5W3u<=tGV:YtujGWYY=$tˋ5S3V >=YXt"jSYYt?VSP+ uG>u5%'3Y[_^5$%$3PPPPP ̋UQMS3VU 9Et ]EE>"u39E"FE<tBU PF+Yt} t M E FU Mt2}u t utBe>< t< uFN>}t EE3C3FA>\t>"u&u}t F8"u 339EEtIt\BuU tU}u< tK< tGt=Pt#*Yt M E FM E  w*YtFU FVtBU ME^[t ËU S3VW9u;hHVSL54;tE8uuUEPSS} E =?sJMsB;r6PY;t)UEPWV}E H53_^[ËU SV3;u3wf93tf90uf90uW=VVV+V@PSVVE׉E;t8P;YE;t*VVuPuSVVׅu uYuSE S3_^[ËVW;stЃ;r_^ËVW;stЃ;r_^jhj3ɅP5P%Ph?d5D$l$l$+SVW1E3PeuEEEEdËMd Y__^[]Q̋US] Vs35WEE{t N3 8 N F3 8E@fMUS[ EMt_I[LDEEt(Ex@GE؃u΀}t$t N3 8N V3 :zE_^[]EɋM9csmu)=t h#tUjRM U4(E 9X thWӋ6(E MH t N3 8N V3 :EH'9S OhW'UV2N\UW9t ;r;s9t3tPu3u `3@M S^`N`Hj$Y~\d9 |~d=u Fd~=u Fdn=u Fd^=u FdN=u Fd>=u Fd.=u Fd=u Fd=uFdvdjY~d`QY^`[_^]ËUcsm9Eu u PYY]3]3@ UeeSWN@;t t УeVEPu3u3(33EPE3E3;uO@u G 5։5^_[Ã%ËUQQE VuEEWVEH&Y;u NjJuMQuPE;uht PYϋD0 EU_^jhpm]܉]Eu Ëx;r f ы<L1tP%YeD0tuuu uE܉U ]܉]E E܋Uu&YËU'3ʼnEE VuW34809}u3;u8} SL8$$?tu'Mu9 D8 tjjjVV>YD@l39H P4Ȑ3;`;t 8?PĐ4 3,9E#@?g $3 ǃx8tP4UM`8jEPKP?Yt:4+M3@;jDSP% C@jSDP% n3PPjMQjDQP C@=j,PVEP$4 @089,j,PjEP$E 4,08<t<u!33Ƀ @D<t<uRD#Yf;DI8t)j XPD"Yf;D80E9@8T4D83ɋD8?D49M3+4H;Ms&CA u 0 @F@FrՋH+j(PVHP$4C(8;;+4;El%?49MH@+4jH^;MsCΉ u0j [f @@fƁ@rH+j(PVHP$4i(8;a+4;EGK4,9Mu,@+4jH^;Ms;,,΃ uj [f@@fƁ@r3VVhU QH++PPVh;j(P+P5P$4t (; hD;\,+48;E ?Q(Qu448t(D8 hD8ulDt-j^9Du? G0?DKY1$D@t48u3$ 8+0[M_3^:jh]u x;r ,ҋ<D0tSYeD0tuu Sn E/ 7 ME EË]S0YËUTh#YMAt I AI AAAAa]ËUEu 3]Åx;r *ދȃ D@]øáVj^u;}ƣjPYYpujV5YYpujX^3ҹp  P|j^3ҹWt;tu1 B@|_3^ =<t5pYËUVu;r"0w+QN Y V̐^]ËUE}PpE H Y]ËE P̐]ËUE;r=0w` +PNY]à PА]ËUME }` QY]à PА]ËUEu;]Ë@]-t"t t Ht3øøøøËVWh3FWP3ȋ~~~  ~P F+ο@Ou@Nu_^ËU3ʼnESWPvԐ3@;rƅ t0;w+@P j R Cujv vPWPjj!3SvWPWPWv S_ DSvWPWPhv S: $3EtLtL @;rRDž3)ЍZ w LQ w L QA;rƋM_3[j hpGptltwhuj Y-j _ Yewhu;5xt6tVluPtVYxGh5xuV\E뎋uj % YËUS3SMXuXܐ8]tEMapE|D;FG;v}>uЋuE}urlj{CijC CZf1f0JuL@;v~0C@IuCC Ss3ȋ {95XTM_^3[jhЫ M}_huqE;CWh RY؅Fwh#SuYYEuvhluFh=PtPY^hS=\Fppj YeChClC p3E}fLCf E\@3E=} Lp@3E=}x@5xlux=PtPYxSE0j VY%u PtSYeEÃ=ujVY3ËUSV5\W}W֋tP֋tP֋tP֋tP֍_PE{tt tPփ{t CtPփMu֋P_^[]ËUW}SV5lW֋tP֋tP֋tP֋tP֍_PE{tt tPփ{t CtPփMu֋P^[_]ËUSVu3W;to=th;t^9uZ;t9uP8YY;t9uP!YYYY;tD9u@-P+P+P=xt9uP'~YY~PEtt;t 9uPYY9_tG;t 9uPBYMuV3Y_^[]ËUW} t;Et4V0;t(W8jYtV>YutVsY^3_]j hpFpt"~ltpluj kYj Ye5lVYYYEEj YuËVW3H(r_^á39t̋L$t$tNu$$~Ѓ3ƒtAt2t$tt͍AL$+ÍAL$+ÍAL$+ÍAL$+ËUSVu 3W};u;v E;t3{E;tvUj^0VuME9XfEf;v6;t;v WSV蓽 *8]tMap_^[;t&;w j"^08]tE`pyE;t8]t~t WW&Y|ܾ_t ~uPӃ|^[ËUE4А]j h73G}39Pu jhYYu49tmjpY;u) 3Pj XY]9u+hWuWY ] >WYE Ej )YËUEV4>uP#Yuj[Y6̐^]ËUS]woVW=PujhYYt3@Pj5Pu&j ^9(t SYu00_^SY 3[]ËUMtj3X;E s 3]M VuF3wVj5Pu2=(tVOYuҋEt 3 Mt ^]ËU}u u Y]Vu u uRY3MW0uFVuj5Pu^9(t@VYtvVY 3_^]hPYhPYjh0@xte3@ËeEPh_HËUE]ËUE V9Ptk u ;rk M^;s9Pt3]5,j hP3}}؋] KtjY+t"+t+tY+uC<}؅uTUw\]YpQÃt2t!HtF빾 EP,E3}9Euj9EtPY3Et tuO`MԉG`u>OdMGdu, M܋  9M}Mk W\DEEuwdSUY]}؃}tjYSUYt tuEԉG`uEЉGd3ËUE]ËUE]ËUE]ËU5,tuYt3@]3]ËUQSV5,W55؉]֋;+GruSl؍GY;sH;s;rPuYYuC;r>PuxYYt/P4Hu=H׉VףE3_^[ËVjj YYVHujX^Ã&3^j hpeuYEE EjËUuYH]̋UMMZf9t3]ËA<8PEu3ҹ f9H‹]̋UEH<ASVq3WDt} H ;r X;r B(;r3_^[]̋Ujhh?dPSVW1E3PEdeEh*tTE-PhPt:@$ЃEMd Y_^[]ËE3ҁ9‹ËeE3Md Y_^[]ËU3M; (t @r3]Ë,]ËU3ʼnESVuWV3Y;ljYjYu =6hdhW  h"VSf*uh4SV t 3PPPPPV@Y ]D$T$UL$)qqq( ]UVWS33333[_^]Ëjo33333USVWjRhiQ^_^[]Ul$RQt$ ]UMS3VW;|[; sS<D0t6<0t0=u+tItIuSjSjSj 3 _^[]ËUEu ]Åx;r <Ջ Dt͋]j h#}4E39^u5j vY]9^uhF Pu]FE09]tD8 P̐E3ۋ}j 8YËUEȃ D PА]ËUQ=uujMQjMQPtfEËUSVu 3;t9]t8uE;t3f3^[uMwE9XuE;tf8]tE`p3@ˍEPPYYt}E~%9M| 39]RuQVj pEuM;r 8^t8]fMapZ*8]tE`p;39]PuEjVj p:뺋Ujuu u]QL$+#ȋ%;r Y$-jhЬ3ۉ]j,Y]j_};=}Tp9tE@ tPZYtE|(p Pp4YpGE ExjYËUSVuF Ȁ3ۀu@t9FW>+~,WPVYP\ ;uF yF N _Ff^[]ËUVuu V5Y/V|YtF @tV"PYY3^]jhm3}}jY}3u;5p98t^@ tVPV'YY3BUpH t/9UuPJYtE9}utP/Yu E܉}F3up4V0YYE}EtEjGYjYËUEt8uPY]ËU3ʼnEUS3VW;~EI8t@;u+H;}@E]9]$u E@E$539](SSuuPu$֋};u3R~Cj3Xr7D?=w;tPsY;t E]9]tWuuuju$օ5SSWuuu ։E;Mt)E ;9EPuWuuu };~Bj3Xr6D?;wK;thPY;t 3;t?uWuuuu օt"SS9] uSSu uuWSu$EWYuEYe_^[M37ËUuMu(Eu$u uuuuu P$}tMapËUQQ3ʼnES3VW]9]u E@E539] SSuuPu֋;u3~<w4D?=w ;tPwY;t ؅t?PjSe WSuujuօtuPSu ESEYe_^[M3 ËUuMحu$Euuuuu P}tMapËUVucvIvAv 9v1v)v!6v v$ v(v,v0v4vv8v<@v@vDvHvLvPvTvXv\v`vdvhwvlovpgvt_vxWv|O@A6+  @xmbWLA6+  @ ۿпſ躿诿 褿$虿(莿,胿0x4m8b<W@LDAH6@L(PTX\`^]ËUVutY;tPξYF;tP輾YF; tP誾YF0;HtP蘾Yv4;5LtV膾Y^]ËUVuF ;$tP`YF;(tPNYF;,tPYËU}uj ]uj5P ]tjYttjh@jR jUWVu M};v;r=tWV;^_u ur)$xǺr $w$x$txx0xTx#ъFGFGr$xI#ъFGr$x#ъr$xIxxxxxxxxDDDDDDDDDDDDDD$xxxyyE^_ÐE^_ÐFGE^_ÍIFGFGE^_Ðt1|9u$r $|z$,zIǺr +$y$|zyyyF#шGr$|zIF#шGFGr$|zF#шGFGFGV$|zI0z8z@zHzPzXz`zszDDDDDDDDD D DDDD$|zzzzzE^_ÐFGE^_ÍIFGFGE^_ÐFGFGFGE^_ËU$3ʼnEESEE VWE觴e=,Eu}h؅=hSׅ5HPhS,PhԨS0PhS4P֣<thSP֣88M5,;tG9 <t?P5<֋؅t,t(ׅtMQj MQjPӅtEu M 30;Et)Pօt"ЉEt4;EtPօtuЉE5,օtuuuu3M_^3[諛ËUVuWt} u(j^0̱_^]ËMu3f݋f:tOut+f ftOu3ufֱj"Y몋UUS]VWuu9U u3_^[]Åt} u蛱j^0?݅u3fЋMu3fԋƒu+fft'Ou"+ fftOtKuu3fy3uM jPfDJXdf j"YjUEffu+EH]ËUVuWt} u˰j^0o_^]ËEufߋ+f ftOu3uf苰j"Y뼋UMx~ u]á ]S]USVWUjjhX~u ]_^[]ËL$At2D$H3fUhP(RP$R]D$T$SVWD$UPjh`~d53PD$dD$(Xp t:|$,t;t$,v-4v L$ H |uhDID_뷋L$d _^[3d y`~uQ R 9QuSQ SQL$ KCk UQPXY]Y[3PPjPjh@h$át tPËUVuWu輮_ DF t8V9VVPIyFt PufYf _^]j hM3uuB F @t f E&VYeV # x;r 蟪ҋ<D0tS[YeD0t SYE說 ME E蒻Ë]SYËUVuF ttvef 3YFF^]UV3PPPPPPPPU I t $uI t $s ^UV3PPPPPPPPU I t $u t $sF ^UWVSM tMu} AZ I& t' t#:r:w:r:w:u u3:t rً[^_̋D$L$ ȋL$ u D$S؋D$d$؋D$[%U 3ʼnESVW}uj^0蘨:u WYY;E r׋]Hu"?tNdpȳ~p`U'MUcM0(null)(null)EEE50P( 8PX700WP `h````xpxxxxKERNEL32.DLLFlsFreeFlsSetValueFlsGetValueFlsAllocCorExitProcessmscoree.dll  HH:mm:ssdddd, MMMM dd, yyyyMM/dd/yyPMAMDecemberNovemberOctoberSeptemberAugustJulyJuneAprilMarchFebruaryJanuaryDecNovOctSepAugJulJunMayAprMarFebJanSaturdayFridayThursdayWednesdayTuesdayMondaySundaySatFriThuWedTueMonSunHH:mm:ssdddd, MMMM dd, yyyyMM/dd/yyPMAMDecemberNovemberOctoberSeptemberAugustJulyJuneAprilMarchFebruaryJanuaryDecNovOctSepAugJulJunMayAprMarFebJanSaturdayFridayThursdayWednesdayTuesdayMondaySundaySatFriThuWedTueMonSunEEE00P('8PW700PP (`h`hhhxppwppruntime error TLOSS error SING error DOMAIN error R6033 - Attempt to use MSIL code from this assembly during native code initialization This indicates a bug in your application. It is most likely the result of calling an MSIL-compiled (/clr) function from a native constructor or from DllMain. R6032 - not enough space for locale information R6031 - Attempt to initialize the CRT more than once. This indicates a bug in your application. R6030 - CRT not initialized R6028 - unable to initialize heap R6027 - not enough space for lowio initialization R6026 - not enough space for stdio initialization R6025 - pure virtual function call R6024 - not enough space for _onexit/atexit table R6019 - unable to open console device R6018 - unexpected heap error R6017 - unexpected multithread lock error R6016 - not enough space for thread data R6010 - abort() has been called R6009 - not enough space for environment R6008 - not enough space for arguments R6002 - floating point support not loaded Ȟp  НxМxHؚH !(xyz̖ĖMicrosoft Visual C++ Runtime Library ...<program name unknown>Runtime Error! Program: ((((( H h(((( H H  !"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~GetProcessWindowStationGetUserObjectInformationWGetLastActivePopupGetActiveWindowMessageBoxWUSER32.DLLCONOUT$  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~PSAPI.DLLEnumProcessesEnumProcessModulesGetModuleBaseNameAEnumDeviceDriversGetDeviceDriverBaseNameA%s.exe%s%sShell_TrayWnd%S10H?`h`~O`00228DwLQU Y]__avcddjmndn\RĮخ$8FԳЯ0D`p|ΰް(:Jrڱ &@Pfز$0>Ndpȳ~p`<LoadLibraryAEGetProcAddressbFreeLibraryOpenProcessRCloseHandleTerminateProcessGlobalFreeGlstrcpyAKERNEL32.dllUpdateWindowFindWindowA#GetDesktopWindow2wsprintfAUSER32.dllGetCurrentThreadIdDecodePointerGetCommandLineAGetCurrentProcessUnhandledExceptionFilterSetUnhandledExceptionFilterIsDebuggerPresentIsProcessorFeaturePresentEncodePointerTlsAllocTlsGetValueTlsSetValueTlsFreeInterlockedIncrementGetModuleHandleWsSetLastErrorGetLastErrorInterlockedDecrementHeapFreeSleepExitProcessoSetHandleCountdGetStdHandleInitializeCriticalSectionAndSpinCountGetFileTypecGetStartupInfoWDeleteCriticalSectionGetModuleFileNameAaFreeEnvironmentStringsWWideCharToMultiByteGetEnvironmentStringsWHeapCreateHeapDestroyQueryPerformanceCounterGetTickCountGetCurrentProcessIdyGetSystemTimeAsFileTimefSetFilePointer%WriteFileGetConsoleCPGetConsoleModeEnterCriticalSection9LeaveCriticalSectionrGetCPInfohGetACP7GetOEMCP IsValidCodePageHeapAllocHeapReAlloc?LoadLibraryWGetModuleFileNameWRtlUnwindSetStdHandle$WriteConsoleWgMultiByteToWideChar-LCMapStringWiGetStringTypeWHeapSizeCreateFileWWFlushFileBuffersGQNF(4@pT_kProcesses.dllFindDeviceFindProcessKillProcessN@D|l        ! 5A CPR S WY l m pr   )      abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZP`y!@~ڣ @ڣ AϢ[@~QQ^ _j21~CD@<840,$ܕؕԕЕ̕ȕĕԕ|ph\PLH<(  ԔĔ|h`XPH@80( ؓ̓@lXPH4 ttttt xvvvvvvvvvv.. . 8Ph  $Z$4VS_VERSION_INFOStringFileInfo^040904b0dCommentsNSIS Plug-in for Windows process management. Only WinNT, Win2K, WinXP and Win2003 Server supported.ZCompanyNameAndrei Ciubotaru [Hardwired]bFileDescriptionWindows Processes Management6 FileVersion1, 0, 0, 14 InternalNameProcesses2LegalCopyrightCopyright (c) 2004 Hardwired. No rights reserved.DOriginalFilenameProcesses.dll4 ProductNameProcesses: ProductVersion1, 0, 0, 1DVarFileInfo$Translation  PAPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDING,00 00 0(0-020;0@0F0N0S0Y0`0e0j0s0y0000000000000/1f111232^22222,3_3334A4J4R4X4a4k4445`5v55566606>6K6z66666666 77&72777P7^7k777777777 8:S:X:b::::::,;2;8;M;;;;<3<<<<<<<<<<<<<<<===="=(=2=;=F=R=W=g=l=r=x===Y>^>i?p??? l001111?2N2i256758a88b:<<<<<<<<<<=====> >J>f>>>????????????0\000$0.040>0`0u0000 111-1E1k1122J2R22222222222 33%3*32383?3E3L3R3Z3a3f3n3w3333333333333333333444 4)4I4O4g4444444 5)555n5w5555555L6T6g6r6w6666666667 77"737l7v777777n8888 99%9l9v99999+:=:k:::::::;@;J;;;;;;|======>>4>\>>>>>>>?"?+?1?7?A?^??@000012222223)313<333334.44 55566U789m::::;;; <<<="=(=B=Q=^=j=z========> >2>e>t>}>>>^???P"131m1z1111111122$2H222273T33 4+444444445,5H5Q5W5`5e5t555555666 7788888!9'9-9=9H9:;L3>9>H>>>>C?I?U???????`0 000'0V0\0d0000000111v111 22+282>2c2j2r22222"3'3,3C384=4O4m4444 55e5}555555556E6b66677859H9`9999:0:]::::::: ;;!<~<<<<<<<===>j>>??p00"11555556&686J6\6n66666666,727K777777778)8O8m8t8x8|88888888888R9]9x9999999 ::::: :$:(:,:v:|::::::;;;#;4;<;B;L;R;\;b;l;u;;;;;;;;<>>!>L>>>5?O?X??????(0000112223>3p33f5s5#7D4181<1@1L1P1d1h1,?4? ;without ".exe" Searches the currently running processes for the given process name. return: 1 - the process was found 0 - the process was not found Processes::KillProcess ; without ".exe" Searches the currently running processes for the given process name. If the process is found then the it gets killed. return: 1 - the process was found and killed 0 - the process was not found or the process cannot be killed (insuficient rights) Processes::FindDevice Searches the installed devices drivers for the given device base name. (important: I said BASE NAME not FILENAME) return: 1 - the device driver was found 0 - the device driver was not found USAGE First of all, does not matter where you use it. Ofcourse, the routines must be called inside of a Section/Function scope. Processes::FindProcess "process_name" Pop $R0 StrCmp $R0 "1" make_my_day noooooo make_my_day: ... noooooo: ... Processes::KillProcess "process_name" Pop $R0 StrCmp $R0 "1" dead_meat why_wont_you_die dead_meat: ... why_wont_you_die: ... Processes::FindDevice "device_base_name" Pop $R0 StrCmp $R0 "1" blabla more_blabla blabla: ... more_blabla: ... THANKS Sunil Kamath for inspiring me. I wanted to use its FindProcDLL but my requirements made it imposible. Nullsoft for creating this very powerfull installer. One big, free and full-featured (hmmm... and guiless for the moment) mean install machine!:) ME for being such a great coder... ... HAHAHAHAHAHAHA! ONE MORE THING If you use the plugin or it's source-code, I would apreciate if my name is mentioned. ---------------------------------------------------------------- ---------------------------------------------------------------- dnssec-trigger-0.13/winrc/proc_dll_src/resource.h0000664000175000017500000000062711704032363021606 0ustar wouterwouter//{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by processes.rc // // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 101 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif dnssec-trigger-0.13/winrc/proc_dll_src/license.rtf0000664000175000017500000001504711704032363021747 0ustar wouterwouter{\rtf1\ansi\ansicpg1252\uc1\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f39\fswiss\fcharset0\fprq2{\*\panose 020b0604030504040204}Verdana;} {\f172\froman\fcharset238\fprq2 Times New Roman CE;}{\f173\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f175\froman\fcharset161\fprq2 Times New Roman Greek;}{\f176\froman\fcharset162\fprq2 Times New Roman Tur;} {\f177\froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f178\froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f179\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f180\froman\fcharset163\fprq2 Times New Roman (Vietnamese);} {\f562\fswiss\fcharset238\fprq2 Verdana CE;}{\f563\fswiss\fcharset204\fprq2 Verdana Cyr;}{\f565\fswiss\fcharset161\fprq2 Verdana Greek;}{\f566\fswiss\fcharset162\fprq2 Verdana Tur;}{\f569\fswiss\fcharset186\fprq2 Verdana Baltic;} {\f570\fswiss\fcharset163\fprq2 Verdana (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255; \red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{ \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 Normal;}{\*\cs10 \additive \ssemihidden Default Paragraph Font;}{\* \ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1024\langfe1024\cgrid\langnp1024\langfenp1024 \snext11 \ssemihidden Normal Table;}{\*\cs15 \additive \ul\cf2 \sbasedon10 \styrsid7485074 Hyperlink;}} {\*\latentstyles\lsdstimax156\lsdlockeddef0}{\*\rsidtbl \rsid6712196\rsid7485074\rsid11352300\rsid15940516}{\*\generator Microsoft Word 11.0.5604;}{\info{\title Processes v1}{\author Hardwired}{\operator Hardwired}{\creatim\yr2004\mo12\dy12\hr23\min42} {\revtim\yr2004\mo12\dy12\hr23\min51}{\version2}{\edmins9}{\nofpages1}{\nofwords80}{\nofchars458}{\nofcharsws537}{\vern24689}}\widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180 \dgvspace180\dghorigin1800\dgvorigin1440\dghshow1\dgvshow1 \jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct \asianbrkrule\rsidroot7485074\newtblstyruls\nogrowautofit \fet0\sectd \linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}} {\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (} {\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \qj \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid7485074 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\b\f39\insrsid7485074\charrsid7485074 Processes v1.0}{\f39\insrsid7485074\charrsid7485074 .0.1 \par }{\f39\fs20\insrsid7485074 \par }\pard \qj \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid15940516 {\f39\fs20\insrsid15940516 This software binaries and source-code are free for any kind of use, including commercial use. }{ \f39\fs20\insrsid7485074\charrsid7485074 There is no restriction and no guaranty for using}{\f39\fs20\insrsid7485074\charrsid7485074 t}{\f39\fs20\insrsid7485074\charrsid7485074 his software}{\f39\fs20\insrsid7485074\charrsid7485074 and/or it s source-code. }{\f39\fs20\insrsid15940516 \par I}{\f39\fs20\insrsid7485074\charrsid7485074 f you use the plug}{\f39\fs20\insrsid7485074\charrsid7485074 -}{\f39\fs20\insrsid7485074\charrsid7485074 in }{\f39\fs20\insrsid7485074\charrsid7485074 and/}{\f39\fs20\insrsid7485074\charrsid7485074 or it}{ \f39\fs20\insrsid7485074\charrsid7485074 s}{\f39\fs20\insrsid7485074\charrsid7485074 source-code, I would }{\f39\fs20\insrsid7485074\charrsid7485074 appreciate }{\f39\fs20\insrsid7485074\charrsid7485074 if my name is mentioned.}{ \f39\fs20\insrsid7485074\charrsid7485074 \par }\pard \qj \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid7485074 {\f39\fs20\insrsid7485074\charrsid7485074 \par }{\b\f39\fs20\insrsid7485074\charrsid7485074 Andrei Ciubotaru [Hardwired] \par }{\f39\fs20\insrsid7485074\charrsid7485074 Lead Developer ICode&Ideas SRL (}{\field\flddirty{\*\fldinst {\f39\fs20\insrsid7485074\charrsid7485074 HYPERLINK "http://www.icode.ro/" }{\f39\fs20\insrsid7485074\charrsid7485074 {\*\datafield 00d0c9ea79f9bace118c8200aa004ba90b02000000170000001500000068007400740070003a002f002f007700770077002e00690063006f00640065002e0072006f002f000000e0c9ea79f9bace118c8200aa004ba90b2a00000068007400740070003a002f002f007700770077002e00690063006f00640065002e007200 6f002f000000}}}{\fldrslt {\cs15\f39\fs20\ul\cf2\insrsid7485074\charrsid7485074 http://www.icode.ro/}}}{\f39\fs20\insrsid7485074\charrsid7485074 ) \par }{\field{\*\fldinst {\f39\fs20\insrsid7485074 HYPERLINK "hardwiredteks@gmail.com" }{\f39\fs20\insrsid15940516\charrsid7485074 {\*\datafield 00d0c9ea79f9bace118c8200aa004ba90b02000000010000000303000000000000c00000000000004600001800000068617264776972656474656b7340676d61696c2e636f6d00ffffadde000000000000000000000000000000000000000000000000}}}{\fldrslt { \cs15\f39\fs20\ul\cf2\insrsid7485074\charrsid7485074 hardwiredteks@gmail.com}}}{\f39\fs20\insrsid7485074\charrsid7485074 , }{\field{\*\fldinst {\f39\fs20\insrsid7485074 HYPERLINK "hardwired@icode.ro" }{\f39\fs20\insrsid15940516\charrsid7485074 {\*\datafield 00d0c9ea79f9bace118c8200aa004ba90b02000000010000000303000000000000c0000000000000460000130000006861726477697265644069636f64652e726f00ffffadde000000000000000000000000000000000000000000000000}}}{\fldrslt { \cs15\f39\fs20\ul\cf2\insrsid7485074\charrsid7485074 hardwired@icode.ro}}}{\f39\fs20\insrsid7485074\charrsid7485074 \par }}dnssec-trigger-0.13/winrc/proc_dll_src/processes.txt0000664000175000017500000000571511704032363022360 0ustar wouterwouter---------------------------------------------------------------- ---------------------------------------------------------------- Processes (Processes.dll) Version: 1.0.0.1 Release: 12.december.2004 Description:Nullsoft Installer (NSIS) plug-in for managing?! Windows processes. Copyright: 2004 Hardwired. No rights reserved. There is no restriction and no guaranty for using this software. Author: Andrei Ciubotaru [Hardwired] Lead Developer ICode&Ideas SRL (http://www.icode.ro) hardwiredteks@gmail.com, hardwired@icode.ro ---------------------------------------------------------------- ---------------------------------------------------------------- INTRODUCTION The Need For Plug-in - I need it for the one of my installers. Briefly: Use it when you need to find\kill a process when installing\uninstalling some application. Also, use it when you need to test the presence of a device driver. SUPPORT Supported platforms are: WinNT,Win2K,WinXP and Win2003 Server. DESCRIPTION Processes::FindProcess Searches the currently running processes for the given process name. return: 1 - the process was found 0 - the process was not found Processes::KillProcess Searches the currently running processes for the given process name. If the process is found then the it gets killed. return: 1 - the process was found and killed 0 - the process was not found or the process cannot be killed (insuficient rights) Processes::FindDevice Searches the installed devices drivers for the given device base name. (important: I said BASE NAME not FILENAME) return: 1 - the device driver was found 0 - the device driver was not found USAGE First of all, does not matter where you use it. Ofcourse, the routines must be called inside of a Section/Function scope. Processes::FindProcess "process_name.exe" Pop $R0 StrCmp $R0 "1" make_my_day noooooo make_my_day: ... noooooo: ... Processes::KillProcess "process_name.exe" Pop $R0 StrCmp $R0 "1" dead_meat why_wont_you_die dead_meat: ... why_wont_you_die: ... Processes::FindDevice "device_base_name" Pop $R0 StrCmp $R0 "1" blabla more_blabla blabla: ... more_blabla: ... THANKS Sunil Kamath for inspiring me. I wanted to use its FindProcDLL but my requirements made it imposible. Nullsoft for creating this very powerfull installer. One big, free and full-featured (hmmm... and guiless for the moment) mean install machine!:) ME for being such a great coder... ... HAHAHAHAHAHAHA! ONE MORE THING If you use the plugin or it's source-code, I would apreciate if my name is mentioned. ---------------------------------------------------------------- ---------------------------------------------------------------- dnssec-trigger-0.13/winrc/proc_dll_src/processes.c0000664000175000017500000002213611704032363021757 0ustar wouterwouter#include "stdafx.h" #include "processes.h" #include "string.h" #include "windows.h" //------------------------------------------------------------------------------------------- // global variables lpfEnumProcesses EnumProcesses; lpfEnumProcessModules EnumProcessModules; lpfGetModuleBaseName GetModuleBaseName; lpfEnumDeviceDrivers EnumDeviceDrivers; lpfGetDeviceDriverBaseName GetDeviceDriverBaseName; HINSTANCE g_hInstance; HWND g_hwndParent; HINSTANCE g_hInstLib; //------------------------------------------------------------------------------------------- // main DLL entry BOOL WINAPI _DllMainCRTStartup( HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved ) { g_hInstance = (struct HINSTANCE__ *)hInst; return TRUE; } //------------------------------------------------------------------------------------------- // loads the psapi routines bool LoadPSAPIRoutines( void ) { if( NULL == (g_hInstLib = LoadLibraryA( "PSAPI.DLL" )) ) return false; EnumProcesses = (lpfEnumProcesses) GetProcAddress( g_hInstLib, "EnumProcesses" ); EnumProcessModules = (lpfEnumProcessModules) GetProcAddress( g_hInstLib, "EnumProcessModules" ); GetModuleBaseName = (lpfGetModuleBaseName) GetProcAddress( g_hInstLib, "GetModuleBaseNameA" ); EnumDeviceDrivers = (lpfEnumDeviceDrivers) GetProcAddress( g_hInstLib, "EnumDeviceDrivers" ); GetDeviceDriverBaseName = (lpfGetDeviceDriverBaseName) GetProcAddress( g_hInstLib, "GetDeviceDriverBaseNameA" ); if( ( NULL == EnumProcesses ) || ( NULL == EnumProcessModules ) || ( NULL == EnumDeviceDrivers ) || ( NULL == GetModuleBaseName ) || ( NULL == GetDeviceDriverBaseName ) ) { FreeLibrary( g_hInstLib ); return false; } return true; } //------------------------------------------------------------------------------------------- // free the psapi routines bool FreePSAPIRoutines( void ) { EnumProcesses = NULL; EnumProcessModules = NULL; GetModuleBaseName = NULL; EnumDeviceDrivers = NULL; if( FALSE == FreeLibrary( g_hInstLib ) ) return false; return true; } //------------------------------------------------------------------------------------------- // find a process by name // return value: true - process was found // false - process not found bool FindProc( char *szProcess ) { char szProcessName[ 1024 ]; char szCurrentProcessName[ 1024 ]; DWORD dPID[ 1024 ]; DWORD dPIDSize = ( 1024 ); DWORD dSize = ( 1024 ); HANDLE hProcess; HMODULE phModule[ 1024 ]; // // make the name lower case // memset( szProcessName, 0, 1024*sizeof(char) ); sprintf( szProcessName, "%s", szProcess ); strlwr( szProcessName ); // // load PSAPI routines // if( false == LoadPSAPIRoutines() ) return false; // // enumerate processes names // if( FALSE == EnumProcesses( dPID, dSize, &dPIDSize ) ) { FreePSAPIRoutines(); return false; } // // walk trough and compare see if the process is running // int k; for( k = ( dPIDSize / sizeof( DWORD ) ); k >= 0; k-- ) { memset( szCurrentProcessName, 0, 1024*sizeof(char) ); if( NULL != ( hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE, FALSE, dPID[ k ] ) ) ) { if( TRUE == EnumProcessModules( hProcess, phModule, sizeof(HMODULE)*1024, &dPIDSize ) ) if( GetModuleBaseName( hProcess, phModule[ 0 ], szCurrentProcessName, 1024 ) > 0 ) { strlwr( szCurrentProcessName ); if( NULL != strstr( szCurrentProcessName, szProcessName ) ) { FreePSAPIRoutines(); CloseHandle( hProcess ); return true; } } CloseHandle( hProcess ); } } // // free PSAPI routines // FreePSAPIRoutines(); return false; } //------------------------------------------------------------------------------------------- // kills a process by name // return value: true - process was found // false - process not found bool KillProc( char *szProcess ) { char szProcessName[ 1024 ]; char szProcessNameWE[ 1024 ]; char szCurrentProcessName[ 1024 ]; DWORD dPID[ 1024 ]; DWORD dPIDSize = ( 1024 ); DWORD dSize = ( 1024 ); HANDLE hProcess; HMODULE phModule[ 1024 ]; // // make the name lower case // memset( szProcessName, 0, 1024*sizeof(char) ); memset( szProcessNameWE,0, 1024*sizeof(char) ); sprintf( szProcessNameWE, "%s%s", szProcess,".exe" ); sprintf( szProcessName, "%s", szProcess ); strlwr( szProcessName ); strlwr( szProcessNameWE ); // // load PSAPI routines // if( false == LoadPSAPIRoutines() ) return false; // // enumerate processes names // if( FALSE == EnumProcesses( dPID, dSize, &dPIDSize ) ) { FreePSAPIRoutines(); return false; } // // walk trough and compare see if the process is running // int k; for( k = ( dPIDSize / sizeof( DWORD ) ); k >= 0; k-- ) { memset( szCurrentProcessName, 0, 1024*sizeof(char) ); if( NULL != ( hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE, FALSE, dPID[ k ] ) ) ) { if( TRUE == EnumProcessModules( hProcess, phModule, sizeof(HMODULE)*1024, &dPIDSize ) ) if( GetModuleBaseName( hProcess, phModule[ 0 ], szCurrentProcessName, 1024 ) > 0 ) { strlwr( szCurrentProcessName ); if( 0 == strcmp( szCurrentProcessName, szProcessName ) || 0 == strcmp( szCurrentProcessName, szProcessNameWE ) ) { FreePSAPIRoutines(); // // kill process // if( false == TerminateProcess( hProcess, 0 ) ) { CloseHandle( hProcess ); return true; } // // refresh systray // UpdateWindow( FindWindow( NULL, "Shell_TrayWnd" ) ); // // refresh desktop window // UpdateWindow( GetDesktopWindow() ); CloseHandle( hProcess ); return true; } } CloseHandle( hProcess ); } } // // free PSAPI routines // FreePSAPIRoutines(); return false; } //------------------------------------------------------------------------------------------- bool FindDev( char *szDriverName ) { char szDeviceName[ 1024 ]; char szCurrentDeviceName[ 1024 ]; LPVOID lpDevices[ 1024 ]; DWORD dDevicesSize = ( 1024 ); DWORD dSize = ( 1024 ); TCHAR tszCurrentDeviceName[ 1024 ]; DWORD dNameSize = ( 1024 ); // // make the name lower case // memset( szDeviceName, 0, 1024*sizeof(char) ); sprintf( szDeviceName, "%s", strlwr( szDriverName ) ); // // load PSAPI routines // if( false == LoadPSAPIRoutines() ) return false; // // enumerate devices // if( FALSE == EnumDeviceDrivers( lpDevices, dSize, &dDevicesSize ) ) { FreePSAPIRoutines(); return false; } // // walk trough and compare see if the device driver exists // int k; for( k = ( dDevicesSize / sizeof( LPVOID ) ); k >= 0; k-- ) { memset( szCurrentDeviceName, 0, 1024*sizeof(char) ); memset( tszCurrentDeviceName, 0, 1024*sizeof(TCHAR) ); if( 0 != GetDeviceDriverBaseName( lpDevices[ k ], tszCurrentDeviceName, dNameSize ) ) { sprintf( szCurrentDeviceName, "%S", tszCurrentDeviceName ); if( 0 == strcmp( strlwr( szCurrentDeviceName ), szDeviceName ) ) { FreePSAPIRoutines(); return true; } } } // // free PSAPI routines // FreePSAPIRoutines(); return false; } //------------------------------------------------------------------------------------------- __declspec(dllexport) void FindProcess( HWND hwndParent, int string_size, char *variables, stack_t **stacktop ) { char szParameter[ 1024 ]; g_hwndParent = hwndParent; EXDLL_INIT(); { popstring( szParameter ); if( true == FindProc( szParameter ) ) wsprintf( szParameter, "1" ); else wsprintf( szParameter, "0" ); setuservariable( INST_R0, szParameter ); } } //------------------------------------------------------------------------------------------- __declspec(dllexport) void KillProcess( HWND hwndParent, int string_size, char *variables, stack_t **stacktop ) { char szParameter[ 1024 ]; g_hwndParent = hwndParent; EXDLL_INIT(); { popstring( szParameter ); if( true == KillProc( szParameter ) ) wsprintf( szParameter, "1" ); else wsprintf( szParameter, "0" ); setuservariable( INST_R0, szParameter ); } } //------------------------------------------------------------------------------------------- __declspec(dllexport) void FindDevice( HWND hwndParent, int string_size, char *variables, stack_t **stacktop ) { char szParameter[ 1024 ]; g_hwndParent = hwndParent; EXDLL_INIT(); { popstring( szParameter ); if( true == FindDev( szParameter ) ) wsprintf( szParameter, "1" ); else wsprintf( szParameter, "0" ); setuservariable( INST_R0, szParameter ); } } dnssec-trigger-0.13/winrc/proc_dll_src/stdafx_orig.h0000664000175000017500000000165411717204640022274 0ustar wouterwouter// stdafx.h : include file for standard system include files, // or project specific include files that are used frequently, but // are changed infrequently // #if !defined(AFX_STDAFX_H__780690DC_E128_403D_BC07_780D1B2CC101__INCLUDED_) #define AFX_STDAFX_H__780690DC_E128_403D_BC07_780D1B2CC101__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #include #include // String management... //From exam28.cpp #include //#include #ifdef BORLANDC #include #include #endif //To make it a NSIS Plug-In #include "exdll.h" //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_STDAFX_H__780690DC_E128_403D_BC07_780D1B2CC101__INCLUDED_) dnssec-trigger-0.13/winrc/vista_user.manifest0000664000175000017500000000127111632423202021045 0ustar wouterwouter dnssec-trigger user program dnssec-trigger-0.13/winrc/win_svc.c0000664000175000017500000005657212275162157017000 0ustar wouterwouter/* * winrc/win_svc.c - windows services API implementation for dnssec-trigger * * Copyright (c) 2009, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file contains functions to integrate with the windows services API. * This means it handles the commandline switches to install and remove * the service (via CreateService and DeleteService), it handles * the ServiceMain() main service entry point when started as a service, * and it handles the Handler[_ex]() to process requests to the service * (such as start and stop and status). */ #include "config.h" #include "winrc/win_svc.h" #include "winrc/w_inst.h" #include "winrc/netlist.h" #include "riggerd/log.h" #include "riggerd/cfg.h" #include "riggerd/svr.h" #include "riggerd/reshook.h" #include "riggerd/netevent.h" #include "riggerd/net_help.h" #include "riggerd/fptr_wlist.h" #include "riggerd/winsock_event.h" /** global service status */ static SERVICE_STATUS service_status; /** global service status handle */ static SERVICE_STATUS_HANDLE service_status_handle; /** global service stop event */ static WSAEVENT service_stop_event = NULL; /** event struct for stop callbacks */ static struct event service_stop_ev; /** if stop even means shutdown or restart */ static int service_stop_shutdown = 0; /** config file to open. global communication to service_main() */ static char* service_cfgfile = CONFIGFILE; /** commandline verbosity. global communication to service_main() */ static int service_cmdline_verbose = 0; /** the cron callback */ static struct comm_timer* service_cron = NULL; /** the cron thread */ static HANDLE cron_thread = NULL; /** if cron has already done its quick check */ static int cron_was_quick = 0; /** * Report current service status to service control manager * @param state: current state * @param exitcode: error code (when stopped) * @param wait: pending operation estimated time in milliseconds. */ static void report_status(DWORD state, DWORD exitcode, DWORD wait) { static DWORD checkpoint = 1; service_status.dwCurrentState = state; service_status.dwWin32ExitCode = exitcode; service_status.dwWaitHint = wait; if(state == SERVICE_START_PENDING) service_status.dwControlsAccepted = 0; else service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP; if(state == SERVICE_RUNNING || state == SERVICE_STOPPED) service_status.dwCheckPoint = 0; else service_status.dwCheckPoint = checkpoint++; SetServiceStatus(service_status_handle, &service_status); } /** * Service control handler. Called by serviceControlManager when a control * code is sent to the service (with ControlService). * @param ctrl: control code */ static void hdlr(DWORD ctrl) { if(ctrl == SERVICE_CONTROL_STOP) { report_status(SERVICE_STOP_PENDING, NO_ERROR, 0); service_stop_shutdown = 1; /* send signal to stop */ if(!WSASetEvent(service_stop_event)) log_err("Could not WSASetEvent: %s", wsa_strerror(WSAGetLastError())); return; } else { /* ctrl == SERVICE_CONTROL_INTERROGATE or whatever */ /* update status */ report_status(service_status.dwCurrentState, NO_ERROR, 0); } } /** * report event to system event log * For use during startup and shutdown. * @param str: the error */ static void reportev(const char* str) { char b[256]; char e[256]; HANDLE* s; LPCTSTR msg = b; /* print quickly to keep GetLastError value */ wsvc_err2str(e, sizeof(e), str, GetLastError()); snprintf(b, sizeof(b), "%s: %s", SERVICE_NAME, e); s = RegisterEventSource(NULL, SERVICE_NAME); if(!s) return; ReportEvent(s, /* event log */ EVENTLOG_ERROR_TYPE, /* event type */ 0, /* event category */ MSG_GENERIC_ERR, /* event ID (from gen_msg.mc) */ NULL, /* user security context */ 1, /* numstrings */ 0, /* binary size */ &msg, /* strings */ NULL); /* binary data */ DeregisterEventSource(s); } /** * Obtain registry string (if it exists). * @param key: key string * @param name: name of value to fetch. * @return malloced string with the result or NULL if it did not * exist on an error (logged) was encountered. */ char* lookup_reg_str(const char* key, const char* name) { HKEY hk = NULL; DWORD type = 0; BYTE buf[1024]; DWORD len = (DWORD)sizeof(buf); LONG ret; char* result = NULL; ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hk); if(ret == ERROR_FILE_NOT_FOUND) return NULL; /* key does not exist */ else if(ret != ERROR_SUCCESS) { reportev("RegOpenKeyEx failed"); return NULL; } ret = RegQueryValueEx(hk, (LPCTSTR)name, 0, &type, buf, &len); if(RegCloseKey(hk)) reportev("RegCloseKey"); if(ret == ERROR_FILE_NOT_FOUND) return NULL; /* name does not exist */ else if(ret != ERROR_SUCCESS) { reportev("RegQueryValueEx failed"); return NULL; } if(type == REG_SZ || type == REG_MULTI_SZ || type == REG_EXPAND_SZ) { buf[sizeof(buf)-1] = 0; buf[sizeof(buf)-2] = 0; /* for multi_sz */ result = strdup((char*)buf); if(!result) reportev("out of memory"); } return result; } /** * Obtain registry integer (if it exists). * @param key: key string * @param name: name of value to fetch. * @return integer value (if it exists), or 0 on error. */ static int lookup_reg_int(const char* key, const char* name) { HKEY hk = NULL; DWORD type = 0; BYTE buf[1024]; DWORD len = (DWORD)sizeof(buf); LONG ret; int result = 0; ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hk); if(ret == ERROR_FILE_NOT_FOUND) return 0; /* key does not exist */ else if(ret != ERROR_SUCCESS) { reportev("RegOpenKeyEx failed"); return 0; } ret = RegQueryValueEx(hk, (LPCTSTR)name, 0, &type, buf, &len); if(RegCloseKey(hk)) reportev("RegCloseKey"); if(ret == ERROR_FILE_NOT_FOUND) return 0; /* name does not exist */ else if(ret != ERROR_SUCCESS) { reportev("RegQueryValueEx failed"); return 0; } if(type == REG_SZ || type == REG_MULTI_SZ || type == REG_EXPAND_SZ) { buf[sizeof(buf)-1] = 0; buf[sizeof(buf)-2] = 0; /* for multi_sz */ result = atoi((char*)buf); } else if(type == REG_DWORD) { DWORD r; memmove(&r, buf, sizeof(r)); result = r; } return result; } /** * Obtain registry binary data (if it exists). * @param key: key string * @param name: name of value to fetch. * @param len: (returned value on success) length of the binary data. * @return malloced binary data with the result or NULL if it did not * exist on an error (logged) was encountered. */ uint8_t* lookup_reg_binary(const char* key, const char* name, size_t* retlen) { HKEY hk = NULL; DWORD type = 0; BYTE buf[10240]; DWORD len = (DWORD)sizeof(buf); LONG ret; uint8_t* result = NULL; ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hk); if(ret == ERROR_FILE_NOT_FOUND) return NULL; /* key does not exist */ else if(ret != ERROR_SUCCESS) { reportev("RegOpenKeyEx failed"); return NULL; } ret = RegQueryValueEx(hk, (LPCTSTR)name, 0, &type, buf, &len); if(RegCloseKey(hk)) reportev("RegCloseKey"); if(ret == ERROR_FILE_NOT_FOUND) return NULL; /* name does not exist */ else if(ret != ERROR_SUCCESS) { reportev("RegQueryValueEx failed"); return NULL; } if(type == REG_BINARY) { result = memdup(buf, len); *retlen = len; if(!result) reportev("out of memory"); } return result; } /** * Init service. Keeps calling status pending to tell service control * manager that this process is not hanging. * @param r: restart, true on restart * @param d: daemon returned here. * @param c: config file returned here. * @return false if failed. */ static int service_init(struct svr** d, struct cfg** c) { struct cfg* cfg = NULL; struct svr* svr = NULL; if(!service_cfgfile) { char* newf = lookup_reg_str("Software\\DnssecTrigger", "ConfigFile"); if(newf) service_cfgfile = newf; else service_cfgfile = strdup(CONFIGFILE); if(!service_cfgfile) fatal_exit("out of memory"); } /* create config */ cfg = cfg_create(service_cfgfile); if(!cfg) return 0; report_status(SERVICE_START_PENDING, NO_ERROR, 2800); /* create daemon */ svr = svr_create(cfg); if(!svr) return 0; report_status(SERVICE_START_PENDING, NO_ERROR, 2600); verbose(VERB_QUERY, "winservice - apply settings"); /* apply settings and init */ verbosity = cfg->verbosity + service_cmdline_verbose; log_init(cfg->logfile, cfg->use_syslog, cfg->chroot); report_status(SERVICE_START_PENDING, NO_ERROR, 2400); hook_resolv_localhost(cfg); report_status(SERVICE_START_PENDING, NO_ERROR, 2300); *d = svr; *c = cfg; return 1; } /** * Deinit the service */ static void service_deinit(struct svr* svr, struct cfg* cfg) { /* set localhost for safe reboot */ if(svr->insecure_state) hook_resolv_localhost(cfg); svr_delete(svr); cfg_delete(cfg); } /** * The main function for the service. * Called by the services API when starting on windows in background. * Arguments could have been present in the string 'path'. * @param argc: nr args * @param argv: arg text. */ static void service_main(DWORD ATTR_UNUSED(argc), LPTSTR* ATTR_UNUSED(argv)) { struct cfg* cfg = NULL; struct svr* svr = NULL; service_status_handle = RegisterServiceCtrlHandler(SERVICE_NAME, (LPHANDLER_FUNCTION)hdlr); if(!service_status_handle) { reportev("Could not RegisterServiceCtrlHandler"); return; } service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; service_status.dwServiceSpecificExitCode = 0; /* we are now starting up */ report_status(SERVICE_START_PENDING, NO_ERROR, 3000); if(!service_init(&svr, &cfg)) { reportev("Could not service_init"); report_status(SERVICE_STOPPED, NO_ERROR, 0); return; } /* event that gets signalled when we want to quit */ service_stop_event = WSACreateEvent(); if(service_stop_event == WSA_INVALID_EVENT) { log_err("WSACreateEvent: %s", wsa_strerror(WSAGetLastError())); reportev("Could not WSACreateEvent"); report_status(SERVICE_STOPPED, NO_ERROR, 0); return; } if(!WSAResetEvent(service_stop_event)) { log_err("WSAResetEvent: %s", wsa_strerror(WSAGetLastError())); } wsvc_setup_worker(svr->base); /* SetServiceStatus SERVICE_RUNNING;*/ report_status(SERVICE_RUNNING, NO_ERROR, 0); verbose(VERB_QUERY, "winservice - init complete"); /* register DHCP hook and perform first sweep */ netlist_start(svr); /* daemon performs work */ svr_service(svr); /* exit */ verbose(VERB_ALGO, "winservice - cleanup."); report_status(SERVICE_STOP_PENDING, NO_ERROR, 0); netlist_stop(); wsvc_desetup_worker(); service_deinit(svr, cfg); free(service_cfgfile); if(service_stop_event) (void)WSACloseEvent(service_stop_event); verbose(VERB_QUERY, "winservice - full stop"); report_status(SERVICE_STOPPED, NO_ERROR, 0); } /** start the service */ static void service_start(const char* cfgfile, int v, int c) { SERVICE_TABLE_ENTRY myservices[2] = { {SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)service_main}, {NULL, NULL} }; verbosity=v; if(verbosity >= VERB_QUERY) { /* log to file about start sequence */ fclose(fopen("C:\\dnssectrigger.log", "w")); log_init("C:\\dnssectrigger.log", 0, 0); verbose(VERB_QUERY, "open logfile"); } else log_init(0, 1, 0); /* otherwise, use Application log */ if(c) { service_cfgfile = strdup(cfgfile); if(!service_cfgfile) fatal_exit("out of memory"); } else service_cfgfile = NULL; service_cmdline_verbose = v; /* this call returns when service has stopped. */ if(!StartServiceCtrlDispatcher(myservices)) { reportev("Could not StartServiceCtrlDispatcher"); } } void wsvc_command_option(const char* wopt, const char* cfgfile, int v, int c) { if(strcmp(wopt, "install") == 0) wsvc_install(stdout, NULL); else if(strcmp(wopt, "remove") == 0) wsvc_remove(stdout); else if(strcmp(wopt, "start") == 0) wsvc_rc_start(stdout); else if(strcmp(wopt, "stop") == 0) wsvc_rc_stop(stdout); else if(strcmp(wopt, "service") == 0) service_start(cfgfile, v, c); else if(strcmp(wopt, "waitstop") == 0) wsvc_rc_waitstop(stdout, c?cfgfile:NULL); else fatal_exit("unknown option: %s", wopt); } void worker_win_stop_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), void* ATTR_UNUSED(arg)) { verbose(VERB_QUERY, "caught stop signal (wsaevent)"); comm_base_exit(global_svr->base); } /** log a windows GetLastError message */ void log_win_err(const char* str, DWORD err) { LPTSTR buf; if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, err, 0, (LPTSTR)&buf, 0, NULL) == 0) { /* could not format error message */ log_err("%s, GetLastError=%d", str, (int)err); return; } log_err("%s, (err=%d): %s", str, (int)err, buf); LocalFree(buf); } typedef HANDLE ub_thread_t; void ub_thread_create(ub_thread_t* thr, void* (*func)(void*), void* arg) { #ifndef HAVE__BEGINTHREADEX *thr = CreateThread(NULL, /* default security (no inherit handle) */ 0, /* default stack size */ (LPTHREAD_START_ROUTINE)func, arg, 0, /* default flags, run immediately */ NULL); /* do not store thread identifier anywhere */ #else /* the begintheadex routine setups for the C lib; aligns stack */ *thr=(ub_thread_t)_beginthreadex(NULL, 0, (void*)func, arg, 0, NULL); #endif if(*thr == NULL) { log_win_err("CreateThread failed", GetLastError()); fatal_exit("thread create failed"); } } /** wait for cron process to finish */ static void waitforit(PROCESS_INFORMATION* pinfo) { DWORD ret = WaitForSingleObject(pinfo->hProcess, INFINITE); verbose(VERB_ALGO, "cronaction done"); if(ret != WAIT_OBJECT_0) { return; /* did not end successfully */ } if(!GetExitCodeProcess(pinfo->hProcess, &ret)) { log_err("GetExitCodeProcess failed"); return; } verbose(VERB_ALGO, "exit code is %d", (int)ret); if(ret != 1) { if(!WSASetEvent(service_stop_event)) log_err("Could not WSASetEvent: %s", wsa_strerror(WSAGetLastError())); } } /** Do the cron action and wait for result exit value */ static void* win_do_cron(void* ATTR_UNUSED(arg)) { char* cronaction; cronaction = lookup_reg_str("Software\\DnssecTrigger", "CronAction"); if(cronaction && strlen(cronaction)>0) { STARTUPINFO sinfo; PROCESS_INFORMATION pinfo; memset(&pinfo, 0, sizeof(pinfo)); memset(&sinfo, 0, sizeof(sinfo)); sinfo.cb = sizeof(sinfo); verbose(VERB_ALGO, "cronaction: %s", cronaction); if(!CreateProcess(NULL, cronaction, NULL, NULL, 0, CREATE_NO_WINDOW, NULL, NULL, &sinfo, &pinfo)) log_err("CreateProcess error"); else { waitforit(&pinfo); CloseHandle(pinfo.hProcess); CloseHandle(pinfo.hThread); } } free(cronaction); /* stop self */ CloseHandle(cron_thread); cron_thread = NULL; return NULL; } /** Set the timer for cron for the next wake up */ static void set_cron_timer() { struct timeval tv; int crontime; if(cron_was_quick == 0) { cron_was_quick = 1; crontime = 3600; /* first update some time after boot */ } else { crontime = lookup_reg_int("Software\\DnssecTrigger", "CronTime"); if(crontime == 0) crontime = 60*60*24; /* 24 hours */ } memset(&tv, 0, sizeof(tv)); tv.tv_sec = (time_t)crontime; comm_timer_set(service_cron, &tv); } void wsvc_cron_cb(void* arg) { /* perform cronned operation */ verbose(VERB_ALGO, "cron timer callback"); if(cron_thread == NULL) { /* create new thread to do it */ ub_thread_create(&cron_thread, win_do_cron, arg); } /* reschedule */ set_cron_timer(); } void wsvc_setup_worker(struct comm_base* base) { /* if not started with -w service, do nothing */ if(!service_stop_event) return; if(!winsock_register_wsaevent(comm_base_internal(base), &service_stop_ev, service_stop_event, &worker_win_stop_cb, NULL)) { fatal_exit("could not register wsaevent"); return; } if(!service_cron) { service_cron = comm_timer_create(base, &wsvc_cron_cb, NULL); if(!service_cron) fatal_exit("could not create cron timer"); set_cron_timer(); } } void wsvc_desetup_worker(void) { comm_timer_delete(service_cron); service_cron = NULL; } int win_run_cmd(char* cmd) { STARTUPINFO sinfo; PROCESS_INFORMATION pinfo; DWORD ret; memset(&pinfo, 0, sizeof(pinfo)); memset(&sinfo, 0, sizeof(sinfo)); sinfo.cb = sizeof(sinfo); /* start it */ if(!CreateProcess(NULL, cmd, NULL, NULL, 0, CREATE_NO_WINDOW, NULL, NULL, &sinfo, &pinfo)) { log_win_err(cmd, GetLastError()); return -1; } /* wait for it */ if(WaitForSingleObject(pinfo.hProcess, INFINITE) == WAIT_FAILED) { log_win_err("cannot WaitForSingleObject(exe):", GetLastError()); } if(!GetExitCodeProcess(pinfo.hProcess, &ret)) { log_win_err("cannot GetExitCodeProcess", GetLastError()); ret = -1; } CloseHandle(pinfo.hProcess); CloseHandle(pinfo.hThread); return ret; } /** enumerate all subkeys of base, and call process(hk, arg) on them */ void enum_guids(const char* base, void (*process_it)(HKEY,void*), void* arg) { char subname[1024]; HKEY base_hk, sub_hk; DWORD sz = sizeof(subname); DWORD i = 0, ret; if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)base, 0, /* reserved, mustbezero */ NULL, /* class of key, ignored */ REG_OPTION_NON_VOLATILE, /* values saved on disk */ KEY_WRITE|KEY_ENUMERATE_SUB_KEYS, NULL, /* use default security descriptor */ &base_hk, /* result */ NULL)) /* not interested if key new or existing */ { log_win_err("could not open enum registry key", GetLastError()); return; } while( (ret=RegEnumKeyEx(base_hk, i, (LPTSTR)subname, &sz, NULL, NULL, 0, NULL)) == ERROR_SUCCESS) { verbose(VERB_ALGO, "enum %d %s", (int)i, subname); /* process it */ if(RegOpenKeyEx(base_hk, (LPCTSTR)subname, 0, KEY_WRITE, &sub_hk)) { log_win_err("enum cannot RegOpenKey", GetLastError()); } else { fptr_ok(fptr_whitelist_enum_reg(process_it)); (*process_it)(sub_hk, arg); RegCloseKey(sub_hk); } /* prepare for next iteration */ i++; sz = sizeof(subname); } if(ret == ERROR_MORE_DATA) { log_err("part of %s has registry keys that are too long", base); } else if(ret != ERROR_NO_MORE_ITEMS) { log_win_err("cannot RegEnumKey", GetLastError()); } RegCloseKey(base_hk); } void enum_reg_set_nameserver(HKEY hk, void* arg) { DWORD len = 0; if(arg) len = strlen((char*)arg); if(RegSetValueEx(hk, (LPCTSTR)"NameServer", 0, REG_SZ, (BYTE*)arg, (DWORD)len)) { log_win_err("could not enumset regkey NameServer", GetLastError()); } } void win_set_resolv(char* ip) { const char* key = "SYSTEM\\CurrentControlSet\\Services\\Tcpip" "\\Parameters"; const char* ifs = "SYSTEM\\CurrentControlSet\\services\\Tcpip" "\\Parameters\\Interfaces"; const char* key6 = "SYSTEM\\CurrentControlSet\\Services\\Tcpip6" "\\Parameters"; const char* ifs6 = "SYSTEM\\CurrentControlSet\\services\\Tcpip6" "\\Parameters\\Interfaces"; HKEY hk; verbose(VERB_DETAIL, "set reg %s", ip); /* needs administrator permissions */ if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)key, 0, /* reserved, mustbezero */ NULL, /* class of key, ignored */ REG_OPTION_NON_VOLATILE, /* values saved on disk */ KEY_WRITE, /* we want write permission */ NULL, /* use default security descriptor */ &hk, /* result */ NULL)) /* not interested if key new or existing */ { log_win_err("could not open registry key", GetLastError()); } else { /* set NameServer */ if(RegSetValueEx(hk, (LPCTSTR)"NameServer", 0, REG_SZ, (BYTE*)ip, (DWORD)strlen(ip)+1)) { log_win_err("could not set regkey NameServer", GetLastError()); } RegCloseKey(hk); } /* set all interfaces/guid/nameserver */ enum_guids(ifs, &enum_reg_set_nameserver, ip); /* IPv6 */ /* needs administrator permissions */ if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)key6, 0, /* reserved, mustbezero */ NULL, /* class of key, ignored */ REG_OPTION_NON_VOLATILE, /* values saved on disk */ KEY_WRITE, /* we want write permission */ NULL, /* use default security descriptor */ &hk, /* result */ NULL)) /* not interested if key new or existing */ { log_win_err("could not open registry key6", GetLastError()); } else { /* set NameServer */ if(RegSetValueEx(hk, (LPCTSTR)"NameServer", 0, REG_SZ, (BYTE*)ip, (DWORD)strlen(ip)+1)) { log_win_err("could not set6 regkey NameServer", GetLastError()); } RegCloseKey(hk); } /* set all interfaces/guid/nameserver */ enum_guids(ifs6, &enum_reg_set_nameserver, ip); } void win_clear_resolv(void) { const char* key = "SYSTEM\\CurrentControlSet\\Services\\Tcpip" "\\Parameters"; const char* ifs = "SYSTEM\\CurrentControlSet\\services\\Tcpip" "\\Parameters\\Interfaces"; const char* key6 = "SYSTEM\\CurrentControlSet\\Services\\Tcpip6" "\\Parameters"; const char* ifs6 = "SYSTEM\\CurrentControlSet\\services\\Tcpip6" "\\Parameters\\Interfaces"; HKEY hk; verbose(VERB_DETAIL, "clear reg"); if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)key, 0, /* reserved, mustbezero */ NULL, /* class of key, ignored */ REG_OPTION_NON_VOLATILE, /* values saved on disk */ KEY_WRITE, /* we want write permission */ NULL, /* use default security descriptor */ &hk, /* result */ NULL)) /* not interested if key new or existing */ { log_win_err("could not create registry key", GetLastError()); } else { if(RegSetValueEx(hk, (LPCTSTR)"NameServer", 0, REG_SZ, (BYTE*)NULL, (DWORD)0)) { log_win_err("could not zero regkey NameServer", GetLastError()); } RegCloseKey(hk); } enum_guids(ifs, &enum_reg_set_nameserver, NULL); /* IPv6 */ if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)key6, 0, /* reserved, mustbezero */ NULL, /* class of key, ignored */ REG_OPTION_NON_VOLATILE, /* values saved on disk */ KEY_WRITE, /* we want write permission */ NULL, /* use default security descriptor */ &hk, /* result */ NULL)) /* not interested if key new or existing */ { log_win_err("could not create registry key", GetLastError()); } else { if(RegSetValueEx(hk, (LPCTSTR)"NameServer", 0, REG_SZ, (BYTE*)NULL, (DWORD)0)) { log_win_err("could not zero regkey NameServer", GetLastError()); } RegCloseKey(hk); } enum_guids(ifs6, &enum_reg_set_nameserver, NULL); } char* get_registry_unbound_control(void) { char buf[1024]; char* ubdir = lookup_reg_str("Software\\Unbound", "InstallLocation"); char* cfg; if(!ubdir) return NULL; cfg = lookup_reg_str("Software\\Unbound", "ConfigFile"); if(!cfg) { free(ubdir); return NULL; } /* spaces in path need quotes in result */ snprintf(buf, sizeof(buf), "\"%s\\unbound-control.exe\" -c \"%s\"", ubdir, cfg); free(ubdir); free(cfg); return strdup(buf); } dnssec-trigger-0.13/winrc/netlist.h0000664000175000017500000000423112275162157017000 0ustar wouterwouter/* * winrc/netlist.h - windows DHCP network listing service for dnssec trigger * * Copyright (c) 2011, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * This file waits for a network change then detects the networks that * exist. Looksup the DHCPprovided nameserver IPs from the registry and * informs the dnssec-triggerdaemon about it. */ #ifndef NETLIST_H #define NETLIST_H struct svr; /** callback from netlist */ void netlist_change_cb(int fd, short ev, void* arg); /** Start the netlist, adds event callback to the eventbase */ void netlist_start(struct svr* svr); /** Stop netlist, removes event. */ void netlist_stop(void); #endif /* NETLIST_H */ dnssec-trigger-0.13/winrc/rsrc_keygen.rc0000664000175000017500000000200711633651034017777 0ustar wouterwouter/* dnssec-trigger-keygen resource file for windows. For use with windres */ #include "winver.h" #include "config.h" 1 ICON "winrc/combined.ico" 1 VERSIONINFO FILEVERSION RSRC_PACKAGE_VERSION PRODUCTVERSION RSRC_PACKAGE_VERSION FILEFLAGSMASK 0 FILEFLAGS 0 FILEOS VOS__WINDOWS32 FILETYPE VFT_APP FILESUBTYPE 0 BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904E4" BEGIN VALUE "CompanyName", "NLnet Labs" VALUE "FileDescription", "DnssecTrigger access key gen" VALUE "FileVersion", PACKAGE_VERSION VALUE "InternalName", "dnssec-trigger-keygen" VALUE "OriginalFilename", "dnssec-trigger-keygen.exe" VALUE "ProductName", "DnssecTrigger" VALUE "ProductVersion", PACKAGE_VERSION VALUE "LegalCopyright", "(C) 2011 NLnet Labs. Source is BSD licensed." END END BLOCK "VarFileInfo" BEGIN /* English(409), windows ANSI codepage (1252) */ VALUE "Translation", 0x409, 0x1252 END END /* vista user access as invoker */ 1 RT_MANIFEST "winrc/vista_user.manifest" dnssec-trigger-0.13/winrc/w_inst.h0000664000175000017500000000610212275162157016620 0ustar wouterwouter/* * winrc/w_inst.h - install and remove functions * * Copyright (c) 2009, NLnet Labs. All rights reserved. * * This software is open source. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the NLNET LABS nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \file * * Contains install and remove functions that manipulate the * windows services API and windows registry. */ #ifndef WINRC_W_INST_H #define WINRC_W_INST_H /** * Install service in servicecontrolmanager, setup registry * @param out: debug output printed here (errors). or NULL. * @param rename: if nonNULL this executable is not the .exe but this name. */ void wsvc_install(FILE* out, const char* rename); /** * Remove installed service from servicecontrolmanager, registry entries * @param out: debug output printed here (errors). or NULL. */ void wsvc_remove(FILE* out); /** * Start the service from servicecontrolmanager, tells OS to start daemon. * @param out: debug output printed here (errors). or NULL. */ void wsvc_rc_start(FILE* out); /** * Stop the service from servicecontrolmanager, tells OS to stop daemon. * @param out: debug output printed here (errors). or NULL. */ void wsvc_rc_stop(FILE* out); /** * Wait for a service to come to a full stop. * @param out: debug output printed here (errors). or NULL. * @param name: service name to wait for. */ void wsvc_rc_waitstop(FILE* out, const char* name); /** * Convert windows GetLastError() value to a neat string. * @param str: destination buffer * @param len: length of dest buffer * @param fixed: fixed text to prepend to string. * @param err: the GetLastError() value. */ void wsvc_err2str(char* str, size_t len, const char* fixed, DWORD err); #endif /* WINRC_W_INST_H */ dnssec-trigger-0.13/winrc/vista_admin.manifest0000664000175000017500000000131511632423202021156 0ustar wouterwouter the dnssec-trigger service dnssec-trigger-0.13/config.h.in0000664000175000017500000003267013017046016016044 0ustar wouterwouter/* config.h.in. Generated from configure.ac by autoheader. */ /* default value for check-updates config option */ #undef CHECK_UPDATES /* default config file name for dnssec-trigger */ #undef CONFIGFILE /* Whether daemon is deprecated */ #undef DEPRECATED_DAEMON /* DNS port number */ #undef DNS_PORT /* define this to enable debug checks. */ #undef DO_DEBUG /* Have AppIndicator (Ubuntu Unity) */ #undef HAVE_APP_INDICATOR /* Define to 1 if you have the `app_indicator_set_icon_full' function. */ #undef HAVE_APP_INDICATOR_SET_ICON_FULL /* Define to 1 if you have the header file. */ #undef HAVE_ARPA_INET_H /* Whether the C compiler accepts the "format" attribute */ #undef HAVE_ATTR_FORMAT /* Whether the C compiler accepts the "unused" attribute */ #undef HAVE_ATTR_UNUSED /* Define to 1 if you have the `chflags' function. */ #undef HAVE_CHFLAGS /* Define to 1 if your system has a working `chown' function. */ #undef HAVE_CHOWN /* Define to 1 if you have the `daemon' function. */ #undef HAVE_DAEMON /* Define to 1 if you have the `fcntl' function. */ #undef HAVE_FCNTL /* Define to 1 if you have the `fork' function. */ #undef HAVE_FORK /* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ #undef HAVE_FSEEKO /* If we have this function (windows XP and later) */ #undef HAVE_GETADAPTERSADDRESSES /* Whether getaddrinfo is available */ #undef HAVE_GETADDRINFO /* Define to 1 if you have the header file. */ #undef HAVE_GETOPT_H /* If you have HMAC_Update */ #undef HAVE_HMAC_UPDATE /* Define to 1 if you have the `inet_ntop' function. */ #undef HAVE_INET_NTOP /* Define to 1 if you have the `inet_pton' function. */ #undef HAVE_INET_PTON /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* if the function 'ioctlsocket' is available */ #undef HAVE_IOCTLSOCKET /* Define to 1 if you have the header file. */ #undef HAVE_IPHLPAPI_H /* Define to 1 if you have the `ldns' library (-lldns). */ #undef HAVE_LIBLDNS /* Define to 1 if you have the `localtime_r' function. */ #undef HAVE_LOCALTIME_R /* If have GNU libc compatible malloc */ #undef HAVE_MALLOC /* Define to 1 if you have the `memmove' function. */ #undef HAVE_MEMMOVE /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_NETDB_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_H /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_CONF_H /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_ENGINE_H /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_ERR_H /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_RAND_H /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_SSL_H /* Define to 1 if you have the `random' function. */ #undef HAVE_RANDOM /* Define to 1 if you have the `recvmsg' function. */ #undef HAVE_RECVMSG /* Define to 1 if you have the `sendmsg' function. */ #undef HAVE_SENDMSG /* Define to 1 if you have the `setsid' function. */ #undef HAVE_SETSID /* Define to 1 if you have the `sleep' function. */ #undef HAVE_SLEEP /* Define to 1 if you have the `snprintf' function. */ #undef HAVE_SNPRINTF /* Define to 1 if you have the `srandom' function. */ #undef HAVE_SRANDOM /* Define if you have the SSL libraries installed. */ #undef HAVE_SSL /* Define to 1 if you have the header file. */ #undef HAVE_STDARG_H /* Define to 1 if you have the header file. */ #undef HAVE_STDBOOL_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strftime' function. */ #undef HAVE_STRFTIME /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strlcpy' function. */ #undef HAVE_STRLCPY /* Define to 1 if you have the header file. */ #undef HAVE_SYSLOG_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PARAM_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_RESOURCE_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_UIO_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_WAIT_H /* Define to 1 if you have the header file. */ #undef HAVE_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `usleep' function. */ #undef HAVE_USLEEP /* Define to 1 if you have the `vfork' function. */ #undef HAVE_VFORK /* Define to 1 if you have the header file. */ #undef HAVE_VFORK_H /* Define to 1 if you have the header file. */ #undef HAVE_WINDOWS_H /* Define to 1 if you have the header file. */ #undef HAVE_WINSOCK2_H /* Define to 1 if `fork' works. */ #undef HAVE_WORKING_FORK /* Define to 1 if `vfork' works. */ #undef HAVE_WORKING_VFORK /* Define to 1 if you have the `writev' function. */ #undef HAVE_WRITEV /* Define to 1 if you have the header file. */ #undef HAVE_WS2TCPIP_H /* Define to 1 if you have the `_beginthreadex' function. */ #undef HAVE__BEGINTHREADEX /* we are on OSX, use that os specific funcs */ #undef HOOKS_OSX /* directory with ssl key files for dnssec-trigger */ #undef KEYDIR /* directory with scripts for dnssec-trigger */ #undef LIBEXEC_DIR /* web browser to open login url */ #undef LOGIN_COMMAND /* login url to open at hot spots */ #undef LOGIN_LOCATION /* Define to the maximum message length to pass to syslog. */ #undef MAXSYSLOGMSGLEN /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* default pidfile name for dnssec-trigger */ #undef PIDFILE /* default Python interpreter path for all Python scripts */ #undef PYTHON /* Define as the return type of signal handlers (`int' or `void'). */ #undef RETSIGTYPE /* version number for resource files */ #undef RSRC_PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Use win32 resources and API */ #undef UB_ON_WINDOWS /* directory with UI xml and png for dnssec-trigger */ #undef UIDIR /* unbound-control to call */ #undef UNBOUND_CONTROL /* Use builtin event system */ #undef USE_MINI_EVENT /* Enable extensions on AIX 3, Interix. */ #ifndef _ALL_SOURCE # undef _ALL_SOURCE #endif /* Enable GNU extensions on systems that have them. */ #ifndef _GNU_SOURCE # undef _GNU_SOURCE #endif /* Enable threading extensions on Solaris. */ #ifndef _POSIX_PTHREAD_SEMANTICS # undef _POSIX_PTHREAD_SEMANTICS #endif /* Enable extensions on HP NonStop. */ #ifndef _TANDEM_SOURCE # undef _TANDEM_SOURCE #endif /* Enable general extensions on Solaris. */ #ifndef __EXTENSIONS__ # undef __EXTENSIONS__ #endif /* Whether the windows socket API is used */ #undef USE_WINSOCK /* the version of the windows API enabled */ #undef WINVER /* Enable large inode numbers on Mac OS X 10.5. */ #ifndef _DARWIN_USE_64_BIT_INODE # define _DARWIN_USE_64_BIT_INODE 1 #endif /* Number of bits in a file offset, on hosts where this is settable. */ #undef _FILE_OFFSET_BITS /* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ #undef _LARGEFILE_SOURCE /* Define for large files, on AIX-style hosts. */ #undef _LARGE_FILES /* Define to 1 if on MINIX. */ #undef _MINIX /* Define to 2 if the system does not provide POSIX.1 features except with this defined. */ #undef _POSIX_1_SOURCE /* Define to 1 if you need to in order for `stat' and other things to work. */ #undef _POSIX_SOURCE /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to `int' if doesn't define. */ #undef gid_t /* in_addr_t */ #undef in_addr_t /* in_port_t */ #undef in_port_t /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif /* Define to `short' if does not define. */ #undef int16_t /* Define to `int' if does not define. */ #undef int32_t /* Define to `long long' if does not define. */ #undef int64_t /* Define to `char' if does not define. */ #undef int8_t /* Define if replacement function should be used. */ #undef malloc /* Define to `long int' if does not define. */ #undef off_t /* Define to `int' if does not define. */ #undef pid_t /* Define to 'int' if not defined */ #undef rlim_t /* Define to `unsigned int' if does not define. */ #undef size_t /* Define to 'int' if not defined */ #undef socklen_t /* Define to `int' if does not define. */ #undef ssize_t /* Define to 'unsigned char' if not defined */ #undef u_char /* Define to `int' if doesn't define. */ #undef uid_t /* Define to `unsigned short' if does not define. */ #undef uint16_t /* Define to `unsigned int' if does not define. */ #undef uint32_t /* Define to `unsigned long long' if does not define. */ #undef uint64_t /* Define to `unsigned char' if does not define. */ #undef uint8_t /* Define as `fork' if `vfork' does not work. */ #undef vfork #ifndef DO_DEBUG # define NDEBUG #endif #include #include #include #include #if STDC_HEADERS #include #include #endif #ifdef HAVE_STDINT_H #include #endif #include #if HAVE_SYS_PARAM_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_SYS_UIO_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_ARPA_INET_H #include #endif #ifdef HAVE_WINSOCK2_H #include #endif #ifdef HAVE_WS2TCPIP_H #include #endif #ifdef HAVE_GETOPT_H #include #endif #ifdef HAVE_OPENSSL_ERR_H #include #endif #ifdef HAVE_OPENSSL_RAND_H #include #endif #ifdef HAVE_OPENSSL_SSL_H #include #endif #ifdef HAVE_ATTR_FORMAT # define ATTR_FORMAT(archetype, string_index, first_to_check) \ __attribute__ ((format (archetype, string_index, first_to_check))) #else /* !HAVE_ATTR_FORMAT */ # define ATTR_FORMAT(archetype, string_index, first_to_check) /* empty */ #endif /* !HAVE_ATTR_FORMAT */ #if defined(DOXYGEN) # define ATTR_UNUSED(x) x #elif defined(__cplusplus) # define ATTR_UNUSED(x) #elif defined(HAVE_ATTR_UNUSED) # define ATTR_UNUSED(x) x __attribute__((unused)) #else /* !HAVE_ATTR_UNUSED */ # define ATTR_UNUSED(x) x #endif /* !HAVE_ATTR_UNUSED */ #ifndef HAVE_FSEEKO #define fseeko fseek #define ftello ftell #endif /* HAVE_FSEEKO */ #if defined(HAVE_EVENT_H) && !defined(HAVE_EVENT_BASE_ONCE) && (defined(HAVE_PTHREAD) || defined(HAVE_SOLARIS_THREADS)) /* using version of libevent that is not threadsafe. */ # define LIBEVENT_SIGNAL_PROBLEM 1 #endif #ifndef RAND_MAX #define RAND_MAX 2147483647 #endif #ifndef CHECKED_INET6 # define CHECKED_INET6 # ifdef AF_INET6 # define INET6 # else # define AF_INET6 28 # endif #endif /* CHECKED_INET6 */ #ifndef HAVE_GETADDRINFO struct sockaddr_storage; #include "compat/fake-rfc2553.h" #endif #ifndef HAVE_INET_PTON #define inet_pton inet_pton_dnssectrigger int inet_pton(int af, const char* src, void* dst); #endif /* HAVE_INET_PTON */ #ifndef HAVE_INET_NTOP #define inet_ntop inet_ntop_dnssectrigger const char *inet_ntop(int af, const void *src, char *dst, size_t size); #endif #ifndef HAVE_MEMMOVE #define memmove memmove_dnssectrigger void *memmove(void *dest, const void *src, size_t n); #endif #ifndef HAVE_STRLCPY #define strlcpy strlcpy_dnssectrigger size_t strlcpy(char *dst, const char *src, size_t siz); #endif #ifndef HAVE_SNPRINTF #define snprintf snprintf_dnssectrigger #define vsnprintf vsnprintf_dnssectrigger #include int snprintf (char *str, size_t count, const char *fmt, ...); int vsnprintf (char *str, size_t count, const char *fmt, va_list arg); #endif /* HAVE_SNPRINTF */ #if !defined(HAVE_SLEEP) || defined(HAVE_WINDOWS_H) #define sleep(x) Sleep((x)*1000) /* on win32 */ #endif /* HAVE_SLEEP */ #ifndef HAVE_USLEEP #define usleep(x) Sleep((x)/1000 + 1) /* on win32 */ #endif /* HAVE_USLEEP */ #ifndef HAVE_RANDOM #define random rand /* on win32, for tests only (bad random) */ #endif /* HAVE_RANDOM */ #ifndef HAVE_SRANDOM #define srandom(x) srand(x) /* on win32, for tests only (bad random) */ #endif /* HAVE_SRANDOM */ /* detect if we need to cast to unsigned int for FD_SET to avoid warnings */ #ifdef HAVE_WINSOCK2_H #define FD_SET_T (u_int) #else #define FD_SET_T #endif dnssec-trigger-0.13/README0000664000175000017500000001172111652453400014675 0ustar wouterwouterDnssec Trigger Readme By Wouter Wijngaards, NLnet Labs, 2011 BSD license is in the LICENSE file. Bugs or comments: labs@nlnetlabs.nl To install see the INSTALL instructions file. Intro ----- This package contains the dnssec-trigger tools. It works together with a local validating resolver (unbound) and keeps DNSSEC enabled. It does so by selecting DNSSEC enabled upstream caches or servers for unbound to talk to and by modifying the DNS path on the system to 127.0.0.1. If DNSSEC does not work because of middleboxes, the insecure option (after a dialog window for the user) causes the DNS path to be set to the insecure servers. The main components are the daemon, DHCP-hooks, and a GUI-panel. The daemon starts at bootup and runs in the background. The DHCP hooks tell the daemon, these are sometimes scripts depending on the system. The GUI-panel shows a tray icon notification applet. The GUI panel shows the dialog to the user if insecure is the only option. The GUI panel has a Reprobe button, so after sigon for the hotspot the user can retry (it makes the red ! disappear if it works). Applications can then trust responses with the AD flag from 127.0.0.1. But they should know that sometimes the resolv.conf contains 'bad' insecure servers (not 127.0.0.1) and then they must not trust the AD flag from them (and may need to send the query without the DO flag to fallback). Responses asked with DO flag to 127.0.0.1 and with the returned AD flag can then be trusted. Trusted DNS responses may help with DANE. The dnssec-trigger package thus runs alongside the unbound daemon. It provides the user with the option to go to Insecure. It selects DNSSEC service where possible. This helps people run DNSSEC. Normal usage ------------ The user logs in and sees a status icon in the tray. Most of the time it displays no ! (exclamation) but is quiet. The icon can be ignored. When the user connects to a new network, the DHCP hooks notify the dnssec-trigger daemon. This probes the network, and notifies unbound. The user sees no change and continues to ignore the icon, unless there is no DNSSEC. If the daemon probe fails to find DNSSEC capability, it tells unbound to stop talking to the network, and tells the statusicon to ask the user. A dialog pops up out of the tray icon. If insecure, then the resolv.conf is changed to the insecure servers, unbound is inactive (loops to 127.0.0.127). The user can work normally on this network connection. For a hotspot, the probe would fail (after a second or two), then with insecure mode the user can login to the hotspot. With Reprobe menu item the user can reprobe dnssec and if it works then (many hotspots provide good access once logged in) the icon is restored to safe. The scripts would also reprobe on a DHCP change. Operations on Platforms ----------------------- How the different platforms operate is described here. * Security There used to be a race condition where DHCP info briefly overriddes the secure version, but this was fixed in 0.6. * unix - NetworkManager In /etc/NetworkManager/dispatcher.d a script sends DHCP changes to the daemon. The script is a networkmanager dhcp hook script and uses dnssec-trigger-control to talk to the daemon. The script uses nmcli to find the DNS info. GTK user interface. In /etc/xdg/autostart/ a .desktop entry starts the user-side tray icon (dnssec-trigger-panel). The daemon is started from /etc/rc.d like regular daemons. The tray icon communicates with the daemon over a persistent SSL connection over loopback (127.0.0.1). It is possible to have multiple tray icons connected over SSL. * unix - Netconfig In /etc/netconfig.d a script sends DHCP changes to the daemon. It greps the info out of /var/run/netconfig/* files. It sends with dnssec-trigger-control to the daemon. GTK like networkmanager. * OSX In /Library/LaunchDaemons two plist files exist. One starts the daemon. The other watches the /Library/Preferences/SystemConfiguration for changes and launches a script. This script uses ifconfig and parses plist files and then sends the results with dnssec-trigger-control to the daemon. The daemon changes resolv.conf but does not need to as on OSX it also sets the network preferences for the network interfaces to the values. These preferences survive a reboot, so the reboot is safe. There then is no connection until unbound is started during reboot. In /Library/LaunchAgents a plist file starts the tray icon (Cocoa app). It uses an SSL connection to the daemon over loopback (127.0.0.1). * Windows The daemon is a service. It has a thread that listens to network changes and blocks on that, it notifies the main daemon when there is a change. The DHCP DNS servers are picked from the registry and the override DNS options are put in the registry as the network preferences. These survive a reboot, so that the system is safe during a reboot. There then is no DNS connection until unbound is started during reboot. The tray icon is a native application. It uses SSL to talk to the daemon. dnssec-trigger-0.13/acx_nlnetlabs.m40000664000175000017500000012440113017046016017072 0ustar wouterwouter# acx_nlnetlabs.m4 - common macros for configure checks # Copyright 2009, Wouter Wijngaards, NLnet Labs. # BSD licensed. # # Version 34 # 2016-03-21 Check -ldl -pthread for libcrypto for ldns and openssl 1.1.0. # 2016-03-21 Use HMAC_Update instead of HMAC_CTX_Init (for openssl-1.1.0). # 2016-01-04 -D_DEFAULT_SOURCE defined with -D_BSD_SOURCE for Linux glibc 2.20 # 2015-12-11 FLTO check for new OSX, clang. # 2015-11-18 spelling check fix. # 2015-11-05 ACX_SSL_CHECKS no longer adds -ldl needlessly. # 2015-08-28 ACX_CHECK_PIE and ACX_CHECK_RELRO_NOW added. # 2015-03-17 AHX_CONFIG_REALLOCARRAY added # 2013-09-19 FLTO help text improved. # 2013-07-18 Enable ACX_CHECK_COMPILER_FLAG to test for -Wstrict-prototypes # 2013-06-25 FLTO has --disable-flto option. # 2013-05-03 Update W32_SLEEP for newer mingw that links but not defines it. # 2013-03-22 Fix ACX_RSRC_VERSION for long version numbers. # 2012-02-09 Fix AHX_MEMCMP_BROKEN with undef in compat/memcmp.h. # 2012-01-20 Fix COMPILER_FLAGS_UNBOUND for gcc 4.6.2 assigned-not-used-warns. # 2011-12-05 Fix getaddrinfowithincludes on windows with fedora16 mingw32-gcc. # Fix ACX_MALLOC for redefined malloc error. # Fix GETADDRINFO_WITH_INCLUDES to add -lws2_32 # 2011-11-10 Fix FLTO test to not drop a.out in current directory. # 2011-11-01 Fix FLTO test for llvm on Lion. # 2011-08-01 Fix nonblock test (broken at v13). # 2011-08-01 Fix autoconf 2.68 warnings # 2011-06-23 Add ACX_CHECK_FLTO to check -flto. # 2010-08-16 Fix FLAG_OMITTED for AS_TR_CPP changes in autoconf-2.66. # 2010-07-02 Add check for ss_family (for minix). # 2010-04-26 Fix to use CPPFLAGS for CHECK_COMPILER_FLAGS. # 2010-03-01 Fix RPATH using CONFIG_COMMANDS to run at the very end. # 2010-02-18 WITH_SSL outputs the LIBSSL_LDFLAGS, LIBS, CPPFLAGS separate, -ldl # 2010-02-01 added ACX_CHECK_MEMCMP_SIGNED, AHX_MEMCMP_BROKEN # 2010-01-20 added AHX_COONFIG_STRLCAT # 2009-07-14 U_CHAR detection improved for windows crosscompile. # added ACX_FUNC_MALLOC # fixup some #if to #ifdef # NONBLOCKING test for mingw crosscompile. # 2009-07-13 added ACX_WITH_SSL_OPTIONAL # 2009-07-03 fixup LDFLAGS for empty ssl dir. # # Automates some of the checking constructs. Aims at portability for POSIX. # Documentation for functions is below. # # the following macro's are provided in this file: # (see below for details on each macro). # # ACX_ESCAPE_BACKSLASH - escape backslashes in var for C-preproc. # ACX_RSRC_VERSION - create windows resource version number. # ACX_CHECK_COMPILER_FLAG - see if cc supports a flag. # ACX_CHECK_ERROR_FLAGS - see which flag is -werror (used below). # ACX_CHECK_COMPILER_FLAG_NEEDED - see if flags make the code compile cleanly. # ACX_DEPFLAG - find cc dependency flags. # ACX_DETERMINE_EXT_FLAGS_UNBOUND - find out which flags enable BSD and POSIX. # ACX_CHECK_FORMAT_ATTRIBUTE - find cc printf format syntax. # ACX_CHECK_UNUSED_ATTRIBUTE - find cc variable unused syntax. # ACX_CHECK_FLTO - see if cc supports -flto and use it if so. # ACX_LIBTOOL_C_ONLY - create libtool for C only, improved. # ACX_TYPE_U_CHAR - u_char type. # ACX_TYPE_RLIM_T - rlim_t type. # ACX_TYPE_SOCKLEN_T - socklen_t type. # ACX_TYPE_IN_ADDR_T - in_addr_t type. # ACX_TYPE_IN_PORT_T - in_port_t type. # ACX_ARG_RPATH - add --disable-rpath option. # ACX_WITH_SSL - add --with-ssl option, link -lcrypto. # ACX_WITH_SSL_OPTIONAL - add --with-ssl option, link -lcrypto, # where --without-ssl is also accepted # ACX_LIB_SSL - setup to link -lssl. # ACX_SYS_LARGEFILE - improved sys_largefile, fseeko, >2G files. # ACX_CHECK_GETADDRINFO_WITH_INCLUDES - find getaddrinfo, portably. # ACX_FUNC_DEPRECATED - see if func is deprecated. # ACX_CHECK_NONBLOCKING_BROKEN - see if nonblocking sockets really work. # ACX_MKDIR_ONE_ARG - determine mkdir(2) number of arguments. # ACX_FUNC_IOCTLSOCKET - find ioctlsocket, portably. # ACX_FUNC_MALLOC - check malloc, define replacement . # AHX_CONFIG_FORMAT_ATTRIBUTE - config.h text for format. # AHX_CONFIG_UNUSED_ATTRIBUTE - config.h text for unused. # AHX_CONFIG_FSEEKO - define fseeko, ftello fallback. # AHX_CONFIG_RAND_MAX - define RAND_MAX if needed. # AHX_CONFIG_MAXHOSTNAMELEN - define MAXHOSTNAMELEN if needed. # AHX_CONFIG_IPV6_MIN_MTU - define IPV6_MIN_MTU if needed. # AHX_CONFIG_SNPRINTF - snprintf compat prototype # AHX_CONFIG_INET_PTON - inet_pton compat prototype # AHX_CONFIG_INET_NTOP - inet_ntop compat prototype # AHX_CONFIG_INET_ATON - inet_aton compat prototype # AHX_CONFIG_MEMMOVE - memmove compat prototype # AHX_CONFIG_STRLCAT - strlcat compat prototype # AHX_CONFIG_STRLCPY - strlcpy compat prototype # AHX_CONFIG_GMTIME_R - gmtime_r compat prototype # AHX_CONFIG_W32_SLEEP - w32 compat for sleep # AHX_CONFIG_W32_USLEEP - w32 compat for usleep # AHX_CONFIG_W32_RANDOM - w32 compat for random # AHX_CONFIG_W32_SRANDOM - w32 compat for srandom # AHX_CONFIG_W32_FD_SET_T - w32 detection of FD_SET_T. # ACX_CFLAGS_STRIP - strip one flag from CFLAGS # ACX_STRIP_EXT_FLAGS - strip extension flags from CFLAGS # AHX_CONFIG_FLAG_OMITTED - define omitted flag # AHX_CONFIG_FLAG_EXT - define omitted extension flag # AHX_CONFIG_EXT_FLAGS - define the stripped extension flags # ACX_CHECK_MEMCMP_SIGNED - check if memcmp uses signed characters. # AHX_MEMCMP_BROKEN - replace memcmp func for CHECK_MEMCMP_SIGNED. # ACX_CHECK_SS_FAMILY - check for sockaddr_storage.ss_family # ACX_CHECK_PIE - add --enable-pie option and check if works # ACX_CHECK_RELRO_NOW - add --enable-relro-now option and check it # dnl Escape backslashes as \\, for C:\ paths, for the C preprocessor defines. dnl for example, ACX_ESCAPE_BACKSLASH($from_var, to_var) dnl $1: the text to change. dnl $2: the result. AC_DEFUN([ACX_ESCAPE_BACKSLASH], [$2="`echo $1 | sed -e 's/\\\\/\\\\\\\\/g'`" ]) dnl Calculate comma separated windows-resource numbers from package version. dnl Picks the first three(,0) or four numbers out of the name. dnl $1: variable for the result AC_DEFUN([ACX_RSRC_VERSION], [$1=[`echo $PACKAGE_VERSION | sed -e 's/^[^0-9]*\([0-9][0-9]*\)[^0-9][^0-9]*\([0-9][0-9]*\)[^0-9][^0-9]*\([0-9][0-9]*\)[^0-9][^0-9]*\([0-9][0-9]*\).*$/\1,\2,\3,\4/' -e 's/^[^0-9]*\([0-9][0-9]*\)[^0-9][^0-9]*\([0-9][0-9]*\)[^0-9][^0-9]*\([0-9][0-9]*\)[^0-9]*$/\1,\2,\3,0/' `] ]) dnl Routine to help check for compiler flags. dnl Checks if the compiler will accept the flag. dnl $1: the flag without a - in front, so g to check -g. dnl $2: executed if yes dnl $3: executed if no AC_DEFUN([ACX_CHECK_COMPILER_FLAG], [ AC_REQUIRE([AC_PROG_CC]) AC_MSG_CHECKING(whether $CC supports -$1) cache=`echo $1 | sed 'y%.=/+-%___p_%'` AC_CACHE_VAL(cv_prog_cc_flag_$cache, [ echo 'void f(void){}' >conftest.c if test -z "`$CC $CPPFLAGS $CFLAGS -$1 -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_$cache=yes" else eval "cv_prog_cc_flag_$cache=no" fi rm -f conftest conftest.o conftest.c ]) if eval "test \"`echo '$cv_prog_cc_flag_'$cache`\" = yes"; then AC_MSG_RESULT(yes) : $2 else AC_MSG_RESULT(no) : $3 fi ]) dnl setup flags for ACX_CHECK_COMPILER_FLAG_NEEDED dnl ERRFLAG: result, compiler flag to turn warnings into errors AC_DEFUN([ACX_CHECK_ERROR_FLAGS], [ ACX_CHECK_COMPILER_FLAG(Werror, [ERRFLAG="-Werror"], [ERRFLAG="-errwarn"]) ACX_CHECK_COMPILER_FLAG(Wall, [ERRFLAG="$ERRFLAG -Wall"], [ERRFLAG="$ERRFLAG -errfmt"]) ]) dnl Routine to help check for needed compiler flags. dnl $1: flags for CC dnl $2: the includes and code dnl $3: if the given code only compiles with the flag, execute argument 3 dnl $4: if the given code compiles without the flag, execute argument 4 dnl $5: with and without flag the compile fails, execute argument 5. AC_DEFUN([ACX_CHECK_COMPILER_FLAG_NEEDED], [ AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([ACX_CHECK_ERROR_FLAGS]) AC_MSG_CHECKING(whether we need $1 as a flag for $CC) cache=AS_TR_SH($1) dnl cache=`echo $1 | sed 'y%.=/+- %___p__%'` AC_CACHE_VAL(cv_prog_cc_flag_needed_$cache, [ echo '$2' > conftest.c echo 'void f(){}' >>conftest.c if test -z "`$CC $CPPFLAGS $CFLAGS $ERRFLAG -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_needed_$cache=no" else [ if test -z "`$CC $CPPFLAGS $CFLAGS $1 $ERRFLAG -c conftest.c 2>&1`"; then eval "cv_prog_cc_flag_needed_$cache=yes" else eval "cv_prog_cc_flag_needed_$cache=fail" #echo 'Test with flag fails too!' #cat conftest.c #echo "$CC $CPPFLAGS $CFLAGS $1 $ERRFLAG -c conftest.c 2>&1" #echo `$CC $CPPFLAGS $CFLAGS $1 $ERRFLAG -c conftest.c 2>&1` #exit 1 fi ] fi rm -f conftest conftest.c conftest.o ]) if eval "test \"`echo '$cv_prog_cc_flag_needed_'$cache`\" = yes"; then AC_MSG_RESULT(yes) : $3 else if eval "test \"`echo '$cv_prog_cc_flag_needed_'$cache`\" = no"; then AC_MSG_RESULT(no) #echo 'Test with flag is no!' #cat conftest.c #echo "$CC $CPPFLAGS $CFLAGS $1 $ERRFLAG -c conftest.c 2>&1" #echo `$CC $CPPFLAGS $CFLAGS $1 $ERRFLAG -c conftest.c 2>&1` #exit 1 : $4 else AC_MSG_RESULT(failed) : $5 fi fi ]) dnl Check for CC dependency flag dnl DEPFLAG: set to flag that generates dependencies. AC_DEFUN([ACX_DEPFLAG], [ AC_MSG_CHECKING([$CC dependency flag]) echo 'void f(){}' >conftest.c if test "`$CC -MM conftest.c 2>&1`" = "conftest.o: conftest.c"; then DEPFLAG="-MM" else if test "`$CC -xM1 conftest.c 2>&1`" = "conftest.o: conftest.c"; then DEPFLAG="-xM1" else DEPFLAG="-MM" # dunno do something fi fi AC_MSG_RESULT($DEPFLAG) rm -f conftest.c AC_SUBST(DEPFLAG) ]) dnl Determine flags that gives POSIX and BSD functionality. dnl CFLAGS is modified for the result. AC_DEFUN([ACX_DETERMINE_EXT_FLAGS_UNBOUND], [ ACX_CHECK_COMPILER_FLAG(std=c99, [C99FLAG="-std=c99"]) ACX_CHECK_COMPILER_FLAG(xc99, [C99FLAG="-xc99"]) AC_CHECK_HEADERS([getopt.h time.h],,, [AC_INCLUDES_DEFAULT]) ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE, [ #include "confdefs.h" #include #include #include #ifdef HAVE_TIME_H #include #endif #include #include #ifdef HAVE_GETOPT_H #include #endif int test() { int a; char **opts = NULL; struct timeval tv; char *t; time_t time = 0; char *buf = NULL; const char* str = NULL; struct msghdr msg; msg.msg_control = 0; t = ctime_r(&time, buf); tv.tv_usec = 10; srandom(32); a = getopt(2, opts, "a"); a = isascii(32); str = gai_strerror(0); if(str && t && tv.tv_usec && msg.msg_control) a = 0; return a; } ], [CFLAGS="$CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE"]) ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE, [ #include "confdefs.h" #include #include #include #ifdef HAVE_TIME_H #include #endif #include #include #ifdef HAVE_GETOPT_H #include #endif int test() { int a; char **opts = NULL; struct timeval tv; char *t; time_t time = 0; char *buf = NULL; const char* str = NULL; struct msghdr msg; msg.msg_control = 0; t = ctime_r(&time, buf); tv.tv_usec = 10; srandom(32); a = getopt(2, opts, "a"); a = isascii(32); str = gai_strerror(0); if(str && t && tv.tv_usec && msg.msg_control) a = 0; return a; } ], [CFLAGS="$CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE"]) ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG, [ #include #include int test() { int a = 0; return a; } ], [CFLAGS="$CFLAGS $C99FLAG"]) ACX_CHECK_COMPILER_FLAG_NEEDED(-D_BSD_SOURCE -D_DEFAULT_SOURCE, [ #include int test() { int a; a = isascii(32); return a; } ], [CFLAGS="$CFLAGS -D_BSD_SOURCE -D_DEFAULT_SOURCE"]) ACX_CHECK_COMPILER_FLAG_NEEDED(-D_GNU_SOURCE, [ #include int test() { struct in6_pktinfo inf; int a = (int)sizeof(inf); return a; } ], [CFLAGS="$CFLAGS -D_GNU_SOURCE"]) # check again for GNU_SOURCE for setresgid. May fail if setresgid # is not available at all. -D_FRSRESGID is to make this check unique. # otherwise we would get the previous cached result. ACX_CHECK_COMPILER_FLAG_NEEDED(-D_GNU_SOURCE -D_FRSRESGID, [ #include int test() { int a = setresgid(0,0,0); a = setresuid(0,0,0); return a; } ], [CFLAGS="$CFLAGS -D_GNU_SOURCE"]) ACX_CHECK_COMPILER_FLAG_NEEDED(-D_POSIX_C_SOURCE=200112, [ #include "confdefs.h" #ifdef HAVE_TIME_H #include #endif #include int test() { int a = 0; char *t; time_t time = 0; char *buf = NULL; const char* str = NULL; t = ctime_r(&time, buf); str = gai_strerror(0); if(t && str) a = 0; return a; } ], [CFLAGS="$CFLAGS -D_POSIX_C_SOURCE=200112"]) ACX_CHECK_COMPILER_FLAG_NEEDED(-D__EXTENSIONS__, [ #include "confdefs.h" #include #include #include #ifdef HAVE_TIME_H #include #endif #include #ifdef HAVE_GETOPT_H #include #endif int test() { int a; char **opts = NULL; struct timeval tv; tv.tv_usec = 10; srandom(32); a = getopt(2, opts, "a"); a = isascii(32); if(tv.tv_usec) a = 0; return a; } ], [CFLAGS="$CFLAGS -D__EXTENSIONS__"]) ])dnl End of ACX_DETERMINE_EXT_FLAGS_UNBOUND dnl Check if CC supports -flto. dnl in a way that supports clang and suncc (that flag does something else, dnl but fails to link). It sets it in CFLAGS if it works. AC_DEFUN([ACX_CHECK_FLTO], [ AC_ARG_ENABLE([flto], AS_HELP_STRING([--disable-flto], [Disable link-time optimization (gcc specific option)])) AS_IF([test "x$enable_flto" != "xno"], [ AC_MSG_CHECKING([if $CC supports -flto]) BAKCFLAGS="$CFLAGS" CFLAGS="$CFLAGS -flto" AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], [ if $CC $CFLAGS -o conftest conftest.c 2>&1 | $GREP -e "warning: no debug symbols in executable" -e "warning: object" >/dev/null; then CFLAGS="$BAKCFLAGS" AC_MSG_RESULT(no) else AC_MSG_RESULT(yes) fi rm -f conftest conftest.c conftest.o ], [CFLAGS="$BAKCFLAGS" ; AC_MSG_RESULT(no)]) ]) ]) dnl Check the printf-format attribute (if any) dnl result in HAVE_ATTR_FORMAT. dnl Make sure you also include the AHX_CONFIG_FORMAT_ATTRIBUTE. AC_DEFUN([ACX_CHECK_FORMAT_ATTRIBUTE], [AC_REQUIRE([AC_PROG_CC]) AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "format" attribute) AC_CACHE_VAL(ac_cv_c_format_attribute, [ac_cv_c_format_attribute=no AC_TRY_COMPILE( [#include void f (char *format, ...) __attribute__ ((format (printf, 1, 2))); void (*pf) (char *format, ...) __attribute__ ((format (printf, 1, 2))); ], [ f ("%s", "str"); ], [ac_cv_c_format_attribute="yes"], [ac_cv_c_format_attribute="no"]) ]) AC_MSG_RESULT($ac_cv_c_format_attribute) if test $ac_cv_c_format_attribute = yes; then AC_DEFINE(HAVE_ATTR_FORMAT, 1, [Whether the C compiler accepts the "format" attribute]) fi ])dnl End of ACX_CHECK_FORMAT_ATTRIBUTE dnl Setup ATTR_FORMAT config.h parts. dnl make sure you call ACX_CHECK_FORMAT_ATTRIBUTE also. AC_DEFUN([AHX_CONFIG_FORMAT_ATTRIBUTE], [ #ifdef HAVE_ATTR_FORMAT # define ATTR_FORMAT(archetype, string_index, first_to_check) \ __attribute__ ((format (archetype, string_index, first_to_check))) #else /* !HAVE_ATTR_FORMAT */ # define ATTR_FORMAT(archetype, string_index, first_to_check) /* empty */ #endif /* !HAVE_ATTR_FORMAT */ ]) dnl Check how to mark function arguments as unused. dnl result in HAVE_ATTR_UNUSED. dnl Make sure you include AHX_CONFIG_UNUSED_ATTRIBUTE also. AC_DEFUN([ACX_CHECK_UNUSED_ATTRIBUTE], [AC_REQUIRE([AC_PROG_CC]) AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "unused" attribute) AC_CACHE_VAL(ac_cv_c_unused_attribute, [ac_cv_c_unused_attribute=no AC_TRY_COMPILE( [#include void f (char *u __attribute__((unused))); ], [ f ("x"); ], [ac_cv_c_unused_attribute="yes"], [ac_cv_c_unused_attribute="no"]) ]) dnl Setup ATTR_UNUSED config.h parts. dnl make sure you call ACX_CHECK_UNUSED_ATTRIBUTE also. AC_DEFUN([AHX_CONFIG_UNUSED_ATTRIBUTE], [ #if defined(DOXYGEN) # define ATTR_UNUSED(x) x #elif defined(__cplusplus) # define ATTR_UNUSED(x) #elif defined(HAVE_ATTR_UNUSED) # define ATTR_UNUSED(x) x __attribute__((unused)) #else /* !HAVE_ATTR_UNUSED */ # define ATTR_UNUSED(x) x #endif /* !HAVE_ATTR_UNUSED */ ]) AC_MSG_RESULT($ac_cv_c_unused_attribute) if test $ac_cv_c_unused_attribute = yes; then AC_DEFINE(HAVE_ATTR_UNUSED, 1, [Whether the C compiler accepts the "unused" attribute]) fi ])dnl dnl Pre-fun for ACX_LIBTOOL_C_ONLY AC_DEFUN([ACX_LIBTOOL_C_PRE], [ # skip these tests, we do not need them. AC_DEFUN([AC_PROG_F77], [:]) AC_DEFUN([AC_PROG_FC], [:]) AC_DEFUN([AC_PROG_CXX], [:]) AC_DEFUN([AC_PROG_CXXCPP], [:]) AC_DEFUN([AC_PROG_OBJC], [:]) AC_DEFUN([AC_PROG_OBJCCPP], [:]) AC_DEFUN([AC_LIBTOOL_CXX], [:]) AC_DEFUN([AC_LIBTOOL_F77], [:]) # always use ./libtool unless override from commandline (libtool=mylibtool) if test -z "$libtool"; then libtool="./libtool" fi AC_SUBST(libtool) # avoid libtool max commandline length test on systems that fork slowly. AC_CANONICAL_HOST if echo "$host_os" | grep "sunos4" >/dev/null; then lt_cv_sys_max_cmd_len=32750; fi AC_PATH_TOOL(AR, ar, [false]) if test $AR = false; then AC_MSG_ERROR([Cannot find 'ar', please extend PATH to include it]) fi ]) dnl Perform libtool check, portably, only for C AC_DEFUN([ACX_LIBTOOL_C_ONLY], [ dnl as a requirement so that is gets called before LIBTOOL dnl because libtools 'AC_REQUIRE' names are right after this one, before dnl this function contents. AC_REQUIRE([ACX_LIBTOOL_C_PRE]) AC_PROG_LIBTOOL ]) dnl Detect if u_char type is defined, otherwise define it. AC_DEFUN([ACX_TYPE_U_CHAR], [AC_CHECK_TYPE([u_char], , [AC_DEFINE([u_char], [unsigned char], [Define to 'unsigned char if not defined])], [ AC_INCLUDES_DEFAULT #ifdef HAVE_WINSOCK2_H # include #endif ]) ]) dnl Detect if rlim_t type is defined, otherwise define it. AC_DEFUN([ACX_TYPE_RLIM_T], [AC_CHECK_TYPE(rlim_t, , [AC_DEFINE([rlim_t], [unsigned long], [Define to 'int' if not defined])], [ AC_INCLUDES_DEFAULT #ifdef HAVE_SYS_RESOURCE_H # include #endif ]) ]) dnl Detect if socklen_t type is defined, otherwise define it. AC_DEFUN([ACX_TYPE_SOCKLEN_T], [ AC_CHECK_TYPE(socklen_t, , [AC_DEFINE([socklen_t], [int], [Define to 'int' if not defined])], [ AC_INCLUDES_DEFAULT #ifdef HAVE_SYS_SOCKET_H # include #endif #ifdef HAVE_WS2TCPIP_H # include #endif ]) ]) dnl Detect if in_addr_t type is defined, otherwise define it. AC_DEFUN([ACX_TYPE_IN_ADDR_T], [ AC_CHECK_TYPE(in_addr_t, [], [AC_DEFINE([in_addr_t], [uint32_t], [in_addr_t])], [ AC_INCLUDES_DEFAULT #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_NETINET_IN_H # include #endif ]) ]) dnl Detect if in_port_t type is defined, otherwise define it. AC_DEFUN([ACX_TYPE_IN_PORT_T], [ AC_CHECK_TYPE(in_port_t, [], [AC_DEFINE([in_port_t], [uint16_t], [in_port_t])], [ AC_INCLUDES_DEFAULT #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_NETINET_IN_H # include #endif ]) ]) dnl Add option to disable the evil rpath. Check whether to use rpath or not. dnl Adds the --disable-rpath option. Uses trick to edit the ./libtool. AC_DEFUN([ACX_ARG_RPATH], [ AC_ARG_ENABLE(rpath, [ --disable-rpath disable hardcoded rpath (default=enabled)], enable_rpath=$enableval, enable_rpath=yes) if test "x$enable_rpath" = xno; then dnl AC_MSG_RESULT([Fixing libtool for -rpath problems.]) AC_CONFIG_COMMANDS([disable-rpath], [ sed < libtool > libtool-2 \ 's/^hardcode_libdir_flag_spec.*$'/'hardcode_libdir_flag_spec=" -D__LIBTOOL_RPATH_SED__ "/' mv libtool-2 libtool chmod 755 libtool libtool="./libtool" ]) fi ]) dnl Add a -R to the RUNTIME_PATH. Only if rpath is enabled and it is dnl an absolute path. dnl $1: the pathname to add. AC_DEFUN([ACX_RUNTIME_PATH_ADD], [ if test "x$enable_rpath" = xyes; then if echo "$1" | grep "^/" >/dev/null; then RUNTIME_PATH="$RUNTIME_PATH -R$1" fi fi ]) dnl Common code for both ACX_WITH_SSL and ACX_WITH_SSL_OPTIONAL dnl Takes one argument; the withval checked in those 2 functions dnl sets up the environment for the given openssl path AC_DEFUN([ACX_SSL_CHECKS], [ withval=$1 if test x_$withval != x_no; then AC_MSG_CHECKING(for SSL) if test x_$withval = x_ -o x_$withval = x_yes; then withval="/usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr" fi for dir in $withval; do ssldir="$dir" if test -f "$dir/include/openssl/ssl.h"; then found_ssl="yes" AC_DEFINE_UNQUOTED([HAVE_SSL], [], [Define if you have the SSL libraries installed.]) dnl assume /usr/include is already in the include-path. if test "$ssldir" != "/usr"; then CPPFLAGS="$CPPFLAGS -I$ssldir/include" LIBSSL_CPPFLAGS="$LIBSSL_CPPFLAGS -I$ssldir/include" fi break; fi done if test x_$found_ssl != x_yes; then AC_MSG_ERROR(Cannot find the SSL libraries in $withval) else AC_MSG_RESULT(found in $ssldir) HAVE_SSL=yes dnl assume /usr is already in the lib and dynlib paths. if test "$ssldir" != "/usr" -a "$ssldir" != ""; then LDFLAGS="$LDFLAGS -L$ssldir/lib" LIBSSL_LDFLAGS="$LIBSSL_LDFLAGS -L$ssldir/lib" ACX_RUNTIME_PATH_ADD([$ssldir/lib]) fi AC_MSG_CHECKING([for HMAC_Update in -lcrypto]) LIBS="$LIBS -lcrypto" LIBSSL_LIBS="$LIBSSL_LIBS -lcrypto" AC_TRY_LINK(, [ int HMAC_Update(void); (void)HMAC_Update(); ], [ AC_MSG_RESULT(yes) AC_DEFINE([HAVE_HMAC_UPDATE], 1, [If you have HMAC_Update]) ], [ AC_MSG_RESULT(no) # check if -lwsock32 or -lgdi32 are needed. BAKLIBS="$LIBS" BAKSSLLIBS="$LIBSSL_LIBS" LIBS="$LIBS -lgdi32" LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32" AC_MSG_CHECKING([if -lcrypto needs -lgdi32]) AC_TRY_LINK([], [ int HMAC_Update(void); (void)HMAC_Update(); ],[ AC_DEFINE([HAVE_HMAC_UPDATE], 1, [If you have HMAC_Update]) AC_MSG_RESULT(yes) ],[ AC_MSG_RESULT(no) LIBS="$BAKLIBS" LIBSSL_LIBS="$BAKSSLLIBS" LIBS="$LIBS -ldl" LIBSSL_LIBS="$LIBSSL_LIBS -ldl" AC_MSG_CHECKING([if -lcrypto needs -ldl]) AC_TRY_LINK([], [ int HMAC_Update(void); (void)HMAC_Update(); ],[ AC_DEFINE([HAVE_HMAC_UPDATE], 1, [If you have HMAC_Update]) AC_MSG_RESULT(yes) ],[ AC_MSG_RESULT(no) LIBS="$BAKLIBS" LIBSSL_LIBS="$BAKSSLLIBS" LIBS="$LIBS -ldl -pthread" LIBSSL_LIBS="$LIBSSL_LIBS -ldl -pthread" AC_MSG_CHECKING([if -lcrypto needs -ldl -pthread]) AC_TRY_LINK([], [ int HMAC_Update(void); (void)HMAC_Update(); ],[ AC_DEFINE([HAVE_HMAC_UPDATE], 1, [If you have HMAC_Update]) AC_MSG_RESULT(yes) ],[ AC_MSG_RESULT(no) AC_MSG_ERROR([OpenSSL found in $ssldir, but version 0.9.7 or higher is required]) ]) ]) ]) ]) fi AC_SUBST(HAVE_SSL) AC_SUBST(RUNTIME_PATH) fi AC_CHECK_HEADERS([openssl/ssl.h],,, [AC_INCLUDES_DEFAULT]) AC_CHECK_HEADERS([openssl/err.h],,, [AC_INCLUDES_DEFAULT]) AC_CHECK_HEADERS([openssl/rand.h],,, [AC_INCLUDES_DEFAULT]) ])dnl End of ACX_SSL_CHECKS dnl Check for SSL, where SSL is mandatory dnl Adds --with-ssl option, searches for openssl and defines HAVE_SSL if found dnl Setup of CPPFLAGS, CFLAGS. Adds -lcrypto to LIBS. dnl Checks main header files of SSL. dnl AC_DEFUN([ACX_WITH_SSL], [ AC_ARG_WITH(ssl, AC_HELP_STRING([--with-ssl=pathname], [enable SSL (will check /usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr)]),[ ],[ withval="yes" ]) if test x_$withval = x_no; then AC_MSG_ERROR([Need SSL library to do digital signature cryptography]) fi ACX_SSL_CHECKS($withval) ])dnl End of ACX_WITH_SSL dnl Check for SSL, where ssl is optional (--without-ssl is allowed) dnl Adds --with-ssl option, searches for openssl and defines HAVE_SSL if found dnl Setup of CPPFLAGS, CFLAGS. Adds -lcrypto to LIBS. dnl Checks main header files of SSL. dnl AC_DEFUN([ACX_WITH_SSL_OPTIONAL], [ AC_ARG_WITH(ssl, AC_HELP_STRING([--with-ssl=pathname], [enable SSL (will check /usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr)]),[ ],[ withval="yes" ]) ACX_SSL_CHECKS($withval) ])dnl End of ACX_WITH_SSL_OPTIONAL dnl Setup to use -lssl dnl To use -lcrypto, use the ACX_WITH_SSL setup (before this one). AC_DEFUN([ACX_LIB_SSL], [ # check if libssl needs libdl BAKLIBS="$LIBS" LIBS="-lssl $LIBS" AC_MSG_CHECKING([if libssl needs libdl]) AC_TRY_LINK_FUNC([SSL_CTX_new], [ AC_MSG_RESULT([no]) LIBS="$BAKLIBS" ] , [ AC_MSG_RESULT([yes]) LIBS="$BAKLIBS" AC_SEARCH_LIBS([dlopen], [dl]) ]) ])dnl End of ACX_LIB_SSL dnl Setup to use very large files (>2Gb). dnl setups fseeko and its own AC_DEFUN([ACX_SYS_LARGEFILE], [ AC_SYS_LARGEFILE dnl try to see if an additional _LARGEFILE_SOURCE 1 is needed to get fseeko ACX_CHECK_COMPILER_FLAG_NEEDED(-D_LARGEFILE_SOURCE=1, [ #include int test() { int a = fseeko(stdin, 0, 0); return a; } ], [CFLAGS="$CFLAGS -D_LARGEFILE_SOURCE=1"]) ]) dnl Check getaddrinfo. dnl Works on linux, solaris, bsd and windows(links winsock). dnl defines HAVE_GETADDRINFO, USE_WINSOCK. AC_DEFUN([ACX_CHECK_GETADDRINFO_WITH_INCLUDES], [AC_REQUIRE([AC_PROG_CC]) AC_MSG_CHECKING(for getaddrinfo) ac_cv_func_getaddrinfo=no AC_LINK_IFELSE( [AC_LANG_SOURCE([[ #ifdef __cplusplus extern "C" { #endif char* getaddrinfo(); char* (*f) () = getaddrinfo; #ifdef __cplusplus } #endif int main() { ; return 0; } ]])], dnl this case on linux, solaris, bsd [ac_cv_func_getaddrinfo="yes" dnl see if on windows if test "$ac_cv_header_windows_h" = "yes"; then AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used]) USE_WINSOCK="1" LIBS="$LIBS -lws2_32" fi ], dnl no quick getaddrinfo, try mingw32 and winsock2 library. ORIGLIBS="$LIBS" LIBS="$LIBS -lws2_32" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [ #ifdef HAVE_WS2TCPIP_H #include #endif ], [ (void)getaddrinfo(NULL, NULL, NULL, NULL); ] )], [ ac_cv_func_getaddrinfo="yes" dnl already: LIBS="$LIBS -lws2_32" AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used]) USE_WINSOCK="1" ], [ ac_cv_func_getaddrinfo="no" LIBS="$ORIGLIBS" ]) ) AC_MSG_RESULT($ac_cv_func_getaddrinfo) if test $ac_cv_func_getaddrinfo = yes; then AC_DEFINE(HAVE_GETADDRINFO, 1, [Whether getaddrinfo is available]) fi ])dnl Endof AC_CHECK_GETADDRINFO_WITH_INCLUDES dnl check if a function is deprecated. defines DEPRECATED_func in config.h. dnl $1: function name dnl $2: C-statement that calls the function. dnl $3: includes for the program. dnl $4: executes if yes dnl $5: executes if no AC_DEFUN([ACX_FUNC_DEPRECATED], [ AC_REQUIRE([AC_PROG_CC]) AC_MSG_CHECKING(if $1 is deprecated) cache=`echo $1 | sed 'y%.=/+-%___p_%'` AC_CACHE_VAL(cv_cc_deprecated_$cache, [ echo '$3' >conftest.c echo 'void f(){ $2 }' >>conftest.c if test -z "`$CC -c conftest.c 2>&1 | grep deprecated`"; then eval "cv_cc_deprecated_$cache=no" else eval "cv_cc_deprecated_$cache=yes" fi rm -f conftest conftest.o conftest.c ]) if eval "test \"`echo '$cv_cc_deprecated_'$cache`\" = yes"; then AC_MSG_RESULT(yes) AC_DEFINE_UNQUOTED(AS_TR_CPP([DEPRECATED_$1]), 1, [Whether $1 is deprecated]) : $4 else AC_MSG_RESULT(no) : $5 fi ])dnl end of ACX_FUNC_DEPRECATED dnl check if select and nonblocking sockets actually work. dnl Needs fork(2) and select(2). dnl defines NONBLOCKING_IS_BROKEN, and if that is true multiple reads from dnl a nonblocking socket do not work, a new call to select is necessary. AC_DEFUN([ACX_CHECK_NONBLOCKING_BROKEN], [ AC_MSG_CHECKING([if nonblocking sockets work]) if echo $target | grep mingw32 >/dev/null; then AC_MSG_RESULT([no (windows)]) AC_DEFINE([NONBLOCKING_IS_BROKEN], 1, [Define if the network stack does not fully support nonblocking io (causes lower performance).]) else AC_RUN_IFELSE([ AC_LANG_SOURCE([[ #include #include #include #include #include #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_ARPA_INET_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_TIME_H #include #endif int main(void) { int port; int sfd, cfd; int num = 10; int i, p; struct sockaddr_in a; /* test if select and nonblocking reads work well together */ /* open port. fork child to send 10 messages. select to read. then try to nonblocking read the 10 messages then, nonblocking read must give EAGAIN */ port = 12345 + (time(0)%32); sfd = socket(PF_INET, SOCK_DGRAM, 0); if(sfd == -1) { perror("socket"); return 1; } memset(&a, 0, sizeof(a)); a.sin_family = AF_INET; a.sin_port = htons(port); a.sin_addr.s_addr = inet_addr("127.0.0.1"); if(bind(sfd, (struct sockaddr*)&a, sizeof(a)) < 0) { perror("bind"); return 1; } if(fcntl(sfd, F_SETFL, O_NONBLOCK) == -1) { perror("fcntl"); return 1; } cfd = socket(PF_INET, SOCK_DGRAM, 0); if(cfd == -1) { perror("client socket"); return 1; } a.sin_port = 0; if(bind(cfd, (struct sockaddr*)&a, sizeof(a)) < 0) { perror("client bind"); return 1; } a.sin_port = htons(port); /* no handler, causes exit in 10 seconds */ alarm(10); /* send and receive on the socket */ if((p=fork()) == 0) { for(i=0; i #include #ifdef HAVE_WINSOCK2_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif ], [ (void)mkdir("directory"); ], AC_MSG_RESULT(yes) AC_DEFINE(MKDIR_HAS_ONE_ARG, 1, [Define if mkdir has one argument.]) , AC_MSG_RESULT(no) ) ])dnl end of ACX_MKDIR_ONE_ARG dnl Check for ioctlsocket function. works on mingw32 too. AC_DEFUN([ACX_FUNC_IOCTLSOCKET], [ # check ioctlsocket AC_MSG_CHECKING(for ioctlsocket) AC_LINK_IFELSE([AC_LANG_PROGRAM([ #ifdef HAVE_WINSOCK2_H #include #endif ], [ (void)ioctlsocket(0, 0, NULL); ])], [ AC_MSG_RESULT(yes) AC_DEFINE(HAVE_IOCTLSOCKET, 1, [if the function 'ioctlsocket' is available]) ],[AC_MSG_RESULT(no)]) ])dnl end of ACX_FUNC_IOCTLSOCKET dnl detect malloc and provide malloc compat prototype. dnl $1: unique name for compat code AC_DEFUN([ACX_FUNC_MALLOC], [ AC_MSG_CHECKING([for GNU libc compatible malloc]) AC_RUN_IFELSE([AC_LANG_PROGRAM( [[#if defined STDC_HEADERS || defined HAVE_STDLIB_H #include #else char *malloc (); #endif ]], [ if(malloc(0) != 0) return 1;]) ], [AC_MSG_RESULT([no]) AC_LIBOBJ(malloc) AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])] , [AC_MSG_RESULT([yes]) AC_DEFINE([HAVE_MALLOC], 1, [If have GNU libc compatible malloc])], [AC_MSG_RESULT([no (crosscompile)]) AC_LIBOBJ(malloc) AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])] ) ]) dnl Define fallback for fseeko and ftello if needed. AC_DEFUN([AHX_CONFIG_FSEEKO], [ #ifndef HAVE_FSEEKO #define fseeko fseek #define ftello ftell #endif /* HAVE_FSEEKO */ ]) dnl Define RAND_MAX if not defined AC_DEFUN([AHX_CONFIG_RAND_MAX], [ #ifndef RAND_MAX #define RAND_MAX 2147483647 #endif ]) dnl Define MAXHOSTNAMELEN if not defined AC_DEFUN([AHX_CONFIG_MAXHOSTNAMELEN], [ #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN 256 #endif ]) dnl Define IPV6_MIN_MTU if not defined AC_DEFUN([AHX_CONFIG_IPV6_MIN_MTU], [ #ifndef IPV6_MIN_MTU #define IPV6_MIN_MTU 1280 #endif /* IPV6_MIN_MTU */ ]) dnl provide snprintf, vsnprintf compat prototype dnl $1: unique name for compat code AC_DEFUN([AHX_CONFIG_SNPRINTF], [ #ifndef HAVE_SNPRINTF #define snprintf snprintf_$1 #define vsnprintf vsnprintf_$1 #include int snprintf (char *str, size_t count, const char *fmt, ...); int vsnprintf (char *str, size_t count, const char *fmt, va_list arg); #endif /* HAVE_SNPRINTF */ ]) dnl provide inet_pton compat prototype. dnl $1: unique name for compat code AC_DEFUN([AHX_CONFIG_INET_PTON], [ #ifndef HAVE_INET_PTON #define inet_pton inet_pton_$1 int inet_pton(int af, const char* src, void* dst); #endif /* HAVE_INET_PTON */ ]) dnl provide inet_ntop compat prototype. dnl $1: unique name for compat code AC_DEFUN([AHX_CONFIG_INET_NTOP], [ #ifndef HAVE_INET_NTOP #define inet_ntop inet_ntop_$1 const char *inet_ntop(int af, const void *src, char *dst, size_t size); #endif ]) dnl provide inet_aton compat prototype. dnl $1: unique name for compat code AC_DEFUN([AHX_CONFIG_INET_ATON], [ #ifndef HAVE_INET_ATON #define inet_aton inet_aton_$1 int inet_aton(const char *cp, struct in_addr *addr); #endif ]) dnl provide memmove compat prototype. dnl $1: unique name for compat code AC_DEFUN([AHX_CONFIG_MEMMOVE], [ #ifndef HAVE_MEMMOVE #define memmove memmove_$1 void *memmove(void *dest, const void *src, size_t n); #endif ]) dnl provide strlcat compat prototype. dnl $1: unique name for compat code AC_DEFUN([AHX_CONFIG_STRLCAT], [ #ifndef HAVE_STRLCAT #define strlcat strlcat_$1 size_t strlcat(char *dst, const char *src, size_t siz); #endif ]) dnl provide strlcpy compat prototype. dnl $1: unique name for compat code AC_DEFUN([AHX_CONFIG_STRLCPY], [ #ifndef HAVE_STRLCPY #define strlcpy strlcpy_$1 size_t strlcpy(char *dst, const char *src, size_t siz); #endif ]) dnl provide gmtime_r compat prototype. dnl $1: unique name for compat code AC_DEFUN([AHX_CONFIG_GMTIME_R], [ #ifndef HAVE_GMTIME_R #define gmtime_r gmtime_r_$1 struct tm *gmtime_r(const time_t *timep, struct tm *result); #endif ]) dnl provide reallocarray compat prototype. dnl $1: unique name for compat code AC_DEFUN([AHX_CONFIG_REALLOCARRAY], [ #ifndef HAVE_REALLOCARRAY #define reallocarray reallocarray$1 void* reallocarray(void *ptr, size_t nmemb, size_t size); #endif ]) dnl provide w32 compat definition for sleep AC_DEFUN([AHX_CONFIG_W32_SLEEP], [ #if !defined(HAVE_SLEEP) || defined(HAVE_WINDOWS_H) #define sleep(x) Sleep((x)*1000) /* on win32 */ #endif /* HAVE_SLEEP */ ]) dnl provide w32 compat definition for usleep AC_DEFUN([AHX_CONFIG_W32_USLEEP], [ #ifndef HAVE_USLEEP #define usleep(x) Sleep((x)/1000 + 1) /* on win32 */ #endif /* HAVE_USLEEP */ ]) dnl provide w32 compat definition for random AC_DEFUN([AHX_CONFIG_W32_RANDOM], [ #ifndef HAVE_RANDOM #define random rand /* on win32, for tests only (bad random) */ #endif /* HAVE_RANDOM */ ]) dnl provide w32 compat definition for srandom AC_DEFUN([AHX_CONFIG_W32_SRANDOM], [ #ifndef HAVE_SRANDOM #define srandom(x) srand(x) /* on win32, for tests only (bad random) */ #endif /* HAVE_SRANDOM */ ]) dnl provide w32 compat definition for FD_SET_T AC_DEFUN([AHX_CONFIG_W32_FD_SET_T], [ /* detect if we need to cast to unsigned int for FD_SET to avoid warnings */ #ifdef HAVE_WINSOCK2_H #define FD_SET_T (u_int) #else #define FD_SET_T #endif ]) dnl Remove an extension flag from CFLAGS, define replacement to be made. dnl Used by ACX_STRIP_EXT_FLAGS. dnl $1: the name of the flag, for example -D_GNU_SOURCE. AC_DEFUN([ACX_CFLAGS_STRIP], [ if echo $CFLAGS | grep " $1" >/dev/null 2>&1; then CFLAGS="`echo $CFLAGS | sed -e 's/ $1//g'`" AC_DEFINE(m4_bpatsubst(OMITTED_$1,[[-=]],_), 1, Put $1 define in config.h) fi ]) dnl Remove EXT flags from the CFLAGS and set them to be defined in config.h dnl use with ACX_DETERMINE_EXT_FLAGS. AC_DEFUN([ACX_STRIP_EXT_FLAGS], [ AC_MSG_NOTICE([Stripping extension flags...]) ACX_CFLAGS_STRIP(-D_GNU_SOURCE) ACX_CFLAGS_STRIP(-D_BSD_SOURCE) ACX_CFLAGS_STRIP(-D_DEFAULT_SOURCE) ACX_CFLAGS_STRIP(-D__EXTENSIONS__) ACX_CFLAGS_STRIP(-D_POSIX_C_SOURCE=200112) ACX_CFLAGS_STRIP(-D_XOPEN_SOURCE=600) ACX_CFLAGS_STRIP(-D_XOPEN_SOURCE_EXTENDED=1) ACX_CFLAGS_STRIP(-D_ALL_SOURCE) ACX_CFLAGS_STRIP(-D_LARGEFILE_SOURCE=1) ]) dnl End of ACX_STRIP_EXT_FLAGS dnl define one omitted flag for config.h dnl $1: flag name. -D_GNU_SOURCE dnl $2: replacement define. _GNU_SOURCE dnl $3: define value, 1 AC_DEFUN([AHX_CONFIG_FLAG_OMITTED], [#if defined($1) && !defined($2) #define $2 $3 [#]endif ]) dnl Wrapper for AHX_CONFIG_FLAG_OMITTED for -D style flags dnl $1: the -DNAME or -DNAME=value string. AC_DEFUN([AHX_CONFIG_FLAG_EXT], [AHX_CONFIG_FLAG_OMITTED(m4_bpatsubst(OMITTED_$1,[[-=]],_),m4_bpatsubst(m4_bpatsubst($1,-D,),=.*$,),m4_if(m4_bregexp($1,=),-1,1,m4_bpatsubst($1,^.*=,))) ]) dnl config.h part to define omitted cflags, use with ACX_STRIP_EXT_FLAGS. AC_DEFUN([AHX_CONFIG_EXT_FLAGS], [AHX_CONFIG_FLAG_EXT(-D_GNU_SOURCE) AHX_CONFIG_FLAG_EXT(-D_BSD_SOURCE) AHX_CONFIG_FLAG_EXT(-D_DEFAULT_SOURCE) AHX_CONFIG_FLAG_EXT(-D__EXTENSIONS__) AHX_CONFIG_FLAG_EXT(-D_POSIX_C_SOURCE=200112) AHX_CONFIG_FLAG_EXT(-D_XOPEN_SOURCE=600) AHX_CONFIG_FLAG_EXT(-D_XOPEN_SOURCE_EXTENDED=1) AHX_CONFIG_FLAG_EXT(-D_ALL_SOURCE) AHX_CONFIG_FLAG_EXT(-D_LARGEFILE_SOURCE=1) ]) dnl check if memcmp is using signed characters and replace if so. AC_DEFUN([ACX_CHECK_MEMCMP_SIGNED], [AC_MSG_CHECKING([if memcmp compares unsigned]) AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include #include int main(void) { char a = 255, b = 0; if(memcmp(&a, &b, 1) < 0) return 1; return 0; } ]])], [AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) AC_DEFINE([MEMCMP_IS_BROKEN], [1], [Define if memcmp() does not compare unsigned bytes]) AC_LIBOBJ([memcmp]) ], [ AC_MSG_RESULT([cross-compile no]) AC_DEFINE([MEMCMP_IS_BROKEN], [1], [Define if memcmp() does not compare unsigned bytes]) AC_LIBOBJ([memcmp]) ]) ]) dnl define memcmp to its replacement, pass unique id for program as arg AC_DEFUN([AHX_MEMCMP_BROKEN], [ #ifdef MEMCMP_IS_BROKEN #include "compat/memcmp.h" #define memcmp memcmp_$1 int memcmp(const void *x, const void *y, size_t n); #endif ]) dnl ACX_CHECK_SS_FAMILY - check for sockaddr_storage.ss_family AC_DEFUN([ACX_CHECK_SS_FAMILY], [AC_CHECK_MEMBER([struct sockaddr_storage.ss_family], [], [ AC_CHECK_MEMBER([struct sockaddr_storage.__ss_family], [ AC_DEFINE([ss_family], [__ss_family], [Fallback member name for socket family in struct sockaddr_storage]) ],, [AC_INCLUDES_DEFAULT #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_NETDB_H #include #endif #ifdef HAVE_ARPA_INET_H #include #endif ]) ], [AC_INCLUDES_DEFAULT #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_NETDB_H #include #endif #ifdef HAVE_ARPA_INET_H #include #endif ]) ]) dnl Check if CC and linker support -fPIE and -pie. dnl If so, sets them in CFLAGS / LDFLAGS. AC_DEFUN([ACX_CHECK_PIE], [ AC_ARG_ENABLE([pie], AS_HELP_STRING([--enable-pie], [Enable Position-Independent Executable (eg. to fully benefit from ASLR, small performance penalty)])) AS_IF([test "x$enable_pie" = "xyes"], [ AC_MSG_CHECKING([if $CC supports PIE]) BAKLDFLAGS="$LDFLAGS" BAKCFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS -pie" CFLAGS="$CFLAGS -fPIE" AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], [ if $CC $CFLAGS $LDFLAGS -o conftest conftest.c 2>&1 | grep "warning: no debug symbols in executable" >/dev/null; then LDFLAGS="$BAKLDFLAGS" AC_MSG_RESULT(no) else AC_MSG_RESULT(yes) fi rm -f conftest conftest.c conftest.o ], [LDFLAGS="$BAKLDFLAGS" ; CFLAGS="$BAKCFLAGS" ; AC_MSG_RESULT(no)]) ]) ]) dnl Check if linker supports -Wl,-z,relro,-z,now. dnl If so, adds it to LDFLAGS. AC_DEFUN([ACX_CHECK_RELRO_NOW], [ AC_ARG_ENABLE([relro_now], AS_HELP_STRING([--enable-relro-now], [Enable full relocation binding at load-time (RELRO NOW, to protect GOT and .dtor areas)])) AS_IF([test "x$enable_relro_now" = "xyes"], [ AC_MSG_CHECKING([if $CC supports -Wl,-z,relro,-z,now]) BAKLDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -Wl,-z,relro,-z,now" AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], [ if $CC $CFLAGS $LDFLAGS -o conftest conftest.c 2>&1 | grep "warning: no debug symbols in executable" >/dev/null; then LDFLAGS="$BAKLDFLAGS" AC_MSG_RESULT(no) else AC_MSG_RESULT(yes) fi rm -f conftest conftest.c conftest.o ], [LDFLAGS="$BAKLDFLAGS" ; AC_MSG_RESULT(no)]) ]) ]) dnl End of file dnssec-trigger-0.13/compat/0000775000175000017500000000000013024457644015307 5ustar wouterwouterdnssec-trigger-0.13/compat/malloc.c0000664000175000017500000000056411624670713016725 0ustar wouterwouter/* Just a replacement, if the original malloc is not GNU-compliant. See autoconf documentation. */ #include "config.h" #undef malloc #include void *malloc (); /* Allocate an N-byte block of memory from the heap. If N is zero, allocate a 1-byte block. */ void * rpl_malloc_dnssectrigger (size_t n) { if (n == 0) n = 1; return malloc (n); } dnssec-trigger-0.13/compat/strlcpy.c0000664000175000017500000000320511624670713017151 0ustar wouterwouter/* from openssh 4.3p2 compat/strlcpy.c */ /* * Copyright (c) 1998 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* OPENBSD ORIGINAL: lib/libc/string/strlcpy.c */ #include #ifndef HAVE_STRLCPY #include #include /* * Copy src to string dst of size siz. At most siz-1 characters * will be copied. Always NUL terminates (unless siz == 0). * Returns strlen(src); if retval >= siz, truncation occurred. */ size_t strlcpy(char *dst, const char *src, size_t siz) { char *d = dst; const char *s = src; size_t n = siz; /* Copy as many bytes as will fit */ if (n != 0 && --n != 0) { do { if ((*d++ = *s++) == 0) break; } while (--n != 0); } /* Not enough room in dst, add NUL and traverse rest of src */ if (n == 0) { if (siz != 0) *d = '\0'; /* NUL-terminate dst */ while (*s++) ; } return(s - src - 1); /* count does not include NUL */ } #endif /* !HAVE_STRLCPY */ dnssec-trigger-0.13/compat/inet_pton.c0000664000175000017500000001222511624670713017452 0ustar wouterwouter/* $KAME: inet_pton.c,v 1.5 2001/08/20 02:32:40 itojun Exp $ */ /* Copyright (c) 1996 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ #include #include #include #include /* * WARNING: Don't even consider trying to compile this on a system where * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ static int inet_pton4 (const char *src, uint8_t *dst); static int inet_pton6 (const char *src, uint8_t *dst); /* * * The definitions we might miss. * */ #ifndef NS_INT16SZ #define NS_INT16SZ 2 #endif #ifndef NS_IN6ADDRSZ #define NS_IN6ADDRSZ 16 #endif #ifndef NS_INADDRSZ #define NS_INADDRSZ 4 #endif /* int * inet_pton(af, src, dst) * convert from presentation format (which usually means ASCII printable) * to network format (which is usually some kind of binary format). * return: * 1 if the address was valid for the specified address family * 0 if the address wasn't valid (`dst' is untouched in this case) * -1 if some other error occurred (`dst' is untouched in this case, too) * author: * Paul Vixie, 1996. */ int inet_pton(af, src, dst) int af; const char *src; void *dst; { switch (af) { case AF_INET: return (inet_pton4(src, dst)); case AF_INET6: return (inet_pton6(src, dst)); default: #ifdef EAFNOSUPPORT errno = EAFNOSUPPORT; #else errno = ENOSYS; #endif return (-1); } /* NOTREACHED */ } /* int * inet_pton4(src, dst) * like inet_aton() but without all the hexadecimal and shorthand. * return: * 1 if `src' is a valid dotted quad, else 0. * notice: * does not touch `dst' unless it's returning 1. * author: * Paul Vixie, 1996. */ static int inet_pton4(src, dst) const char *src; uint8_t *dst; { static const char digits[] = "0123456789"; int saw_digit, octets, ch; uint8_t tmp[NS_INADDRSZ], *tp; saw_digit = 0; octets = 0; *(tp = tmp) = 0; while ((ch = *src++) != '\0') { const char *pch; if ((pch = strchr(digits, ch)) != NULL) { uint32_t new = *tp * 10 + (pch - digits); if (new > 255) return (0); *tp = new; if (! saw_digit) { if (++octets > 4) return (0); saw_digit = 1; } } else if (ch == '.' && saw_digit) { if (octets == 4) return (0); *++tp = 0; saw_digit = 0; } else return (0); } if (octets < 4) return (0); memcpy(dst, tmp, NS_INADDRSZ); return (1); } /* int * inet_pton6(src, dst) * convert presentation level address to network order binary form. * return: * 1 if `src' is a valid [RFC1884 2.2] address, else 0. * notice: * (1) does not touch `dst' unless it's returning 1. * (2) :: in a full address is silently ignored. * credit: * inspired by Mark Andrews. * author: * Paul Vixie, 1996. */ static int inet_pton6(src, dst) const char *src; uint8_t *dst; { static const char xdigits_l[] = "0123456789abcdef", xdigits_u[] = "0123456789ABCDEF"; uint8_t tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; const char *xdigits, *curtok; int ch, saw_xdigit; uint32_t val; memset((tp = tmp), '\0', NS_IN6ADDRSZ); endp = tp + NS_IN6ADDRSZ; colonp = NULL; /* Leading :: requires some special handling. */ if (*src == ':') if (*++src != ':') return (0); curtok = src; saw_xdigit = 0; val = 0; while ((ch = *src++) != '\0') { const char *pch; if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) pch = strchr((xdigits = xdigits_u), ch); if (pch != NULL) { val <<= 4; val |= (pch - xdigits); if (val > 0xffff) return (0); saw_xdigit = 1; continue; } if (ch == ':') { curtok = src; if (!saw_xdigit) { if (colonp) return (0); colonp = tp; continue; } if (tp + NS_INT16SZ > endp) return (0); *tp++ = (uint8_t) (val >> 8) & 0xff; *tp++ = (uint8_t) val & 0xff; saw_xdigit = 0; val = 0; continue; } if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && inet_pton4(curtok, tp) > 0) { tp += NS_INADDRSZ; saw_xdigit = 0; break; /* '\0' was seen by inet_pton4(). */ } return (0); } if (saw_xdigit) { if (tp + NS_INT16SZ > endp) return (0); *tp++ = (uint8_t) (val >> 8) & 0xff; *tp++ = (uint8_t) val & 0xff; } if (colonp != NULL) { /* * Since some memmove()'s erroneously fail to handle * overlapping regions, we'll do the shift by hand. */ const int n = tp - colonp; int i; for (i = 1; i <= n; i++) { endp[- i] = colonp[n - i]; colonp[n - i] = 0; } tp = endp; } if (tp != endp) return (0); memcpy(dst, tmp, NS_IN6ADDRSZ); return (1); } dnssec-trigger-0.13/compat/memmove.c0000664000175000017500000000166411624670713017125 0ustar wouterwouter/* * memmove.c: memmove compat implementation. * * Copyright (c) 2001-2006, NLnet Labs. All rights reserved. * * See LICENSE for the license. */ #include #include void *memmove(void *dest, const void *src, size_t n); void *memmove(void *dest, const void *src, size_t n) { uint8_t* from = (uint8_t*) src; uint8_t* to = (uint8_t*) dest; if (from == to || n == 0) return dest; if (to > from && to-from < (int)n) { /* to overlaps with from */ /* */ /* */ /* copy in reverse, to avoid overwriting from */ int i; for(i=n-1; i>=0; i--) to[i] = from[i]; return dest; } if (from > to && from-to < (int)n) { /* to overlaps with from */ /* */ /* */ /* copy forwards, to avoid overwriting from */ size_t i; for(i=0; i #include #include #include #include #include #ifdef HAVE_STDINT_H #include #endif /* for test */ /* #define SNPRINTF_TEST 1 */ #ifdef SNPRINTF_TEST #define snprintf my_snprintf #define vsnprintf my_vsnprintf #endif /* SNPRINTF_TEST */ int snprintf(char* str, size_t size, const char* format, ...); int vsnprintf(char* str, size_t size, const char* format, va_list arg); /** * Very portable snprintf implementation, limited in functionality, * esp. for %[capital] %[nonportable] and so on. Reduced float functionality, * mostly in formatting and range (e+-16), for %f and %g. * * %s, %d, %u, %i, %x, %c, %n and %% are fully supported. * This includes width, precision, flags 0- +, and *(arg for wid,prec). * %f, %g, %m, %p have reduced support, support for wid,prec,flags,*, but * less floating point range, no %e formatting for %g. */ int snprintf(char* str, size_t size, const char* format, ...) { int r; va_list args; va_start(args, format); r = vsnprintf(str, size, format, args); va_end(args); return r; } /** add padding to string */ static void print_pad(char** at, size_t* left, int* ret, char p, int num) { while(num--) { if(*left > 1) { *(*at)++ = p; (*left)--; } (*ret)++; } } /** get negative symbol, 0 if none */ static char get_negsign(int negative, int plus, int space) { if(negative) return '-'; if(plus) return '+'; if(space) return ' '; return 0; } #define PRINT_DEC_BUFSZ 32 /* 20 is enough for 64 bit decimals */ /** print decimal into buffer, returns length */ static int print_dec(char* buf, int max, unsigned int value) { int i = 0; if(value == 0) { if(max > 0) { buf[0] = '0'; i = 1; } } else while(value && i < max) { buf[i++] = '0' + value % 10; value /= 10; } return i; } /** print long decimal into buffer, returns length */ static int print_dec_l(char* buf, int max, unsigned long value) { int i = 0; if(value == 0) { if(max > 0) { buf[0] = '0'; i = 1; } } else while(value && i < max) { buf[i++] = '0' + value % 10; value /= 10; } return i; } /** print long decimal into buffer, returns length */ static int print_dec_ll(char* buf, int max, unsigned long long value) { int i = 0; if(value == 0) { if(max > 0) { buf[0] = '0'; i = 1; } } else while(value && i < max) { buf[i++] = '0' + value % 10; value /= 10; } return i; } /** print hex into buffer, returns length */ static int print_hex(char* buf, int max, unsigned int value) { const char* h = "0123456789abcdef"; int i = 0; if(value == 0) { if(max > 0) { buf[0] = '0'; i = 1; } } else while(value && i < max) { buf[i++] = h[value & 0x0f]; value >>= 4; } return i; } /** print long hex into buffer, returns length */ static int print_hex_l(char* buf, int max, unsigned long value) { const char* h = "0123456789abcdef"; int i = 0; if(value == 0) { if(max > 0) { buf[0] = '0'; i = 1; } } else while(value && i < max) { buf[i++] = h[value & 0x0f]; value >>= 4; } return i; } /** print long long hex into buffer, returns length */ static int print_hex_ll(char* buf, int max, unsigned long long value) { const char* h = "0123456789abcdef"; int i = 0; if(value == 0) { if(max > 0) { buf[0] = '0'; i = 1; } } else while(value && i < max) { buf[i++] = h[value & 0x0f]; value >>= 4; } return i; } /** copy string into result, reversed */ static void spool_str_rev(char** at, size_t* left, int* ret, const char* buf, int len) { int i = len; while(i) { if(*left > 1) { *(*at)++ = buf[--i]; (*left)--; } else --i; (*ret)++; } } /** copy string into result */ static void spool_str(char** at, size_t* left, int* ret, const char* buf, int len) { int i; for(i=0; i 1) { *(*at)++ = buf[i]; (*left)--; } (*ret)++; } } /** print number formatted */ static void print_num(char** at, size_t* left, int* ret, int minw, int precision, int prgiven, int zeropad, int minus, int plus, int space, int zero, int negative, char* buf, int len) { int w = len; /* excludes minus sign */ char s = get_negsign(negative, plus, space); if(minus) { /* left adjust the number into the field, space padding */ /* calc numw = [sign][zeroes][number] */ int numw = w; if(precision == 0 && zero) numw = 0; if(numw < precision) numw = precision; if(s) numw++; /* sign */ if(s) print_pad(at, left, ret, s, 1); /* number */ if(precision == 0 && zero) { /* "" for the number */ } else { if(w < precision) print_pad(at, left, ret, '0', precision - w); spool_str_rev(at, left, ret, buf, len); } /* spaces */ if(numw < minw) print_pad(at, left, ret, ' ', minw - numw); } else { /* pad on the left of the number */ /* calculate numw has width of [sign][zeroes][number] */ int numw = w; if(precision == 0 && zero) numw = 0; if(numw < precision) numw = precision; if(!prgiven && zeropad && numw < minw) numw = minw; else if(s) numw++; /* pad with spaces */ if(numw < minw) print_pad(at, left, ret, ' ', minw - numw); /* print sign (and one less zeropad if so) */ if(s) { print_pad(at, left, ret, s, 1); numw--; } /* pad with zeroes */ if(w < numw) print_pad(at, left, ret, '0', numw - w); if(precision == 0 && zero) return; /* print the characters for the value */ spool_str_rev(at, left, ret, buf, len); } } /** print %d and %i */ static void print_num_d(char** at, size_t* left, int* ret, int value, int minw, int precision, int prgiven, int zeropad, int minus, int plus, int space) { char buf[PRINT_DEC_BUFSZ]; int negative = (value < 0); int zero = (value == 0); int len = print_dec(buf, (int)sizeof(buf), (unsigned int)(negative?-value:value)); print_num(at, left, ret, minw, precision, prgiven, zeropad, minus, plus, space, zero, negative, buf, len); } /** print %ld and %li */ static void print_num_ld(char** at, size_t* left, int* ret, long value, int minw, int precision, int prgiven, int zeropad, int minus, int plus, int space) { char buf[PRINT_DEC_BUFSZ]; int negative = (value < 0); int zero = (value == 0); int len = print_dec_l(buf, (int)sizeof(buf), (unsigned long)(negative?-value:value)); print_num(at, left, ret, minw, precision, prgiven, zeropad, minus, plus, space, zero, negative, buf, len); } /** print %lld and %lli */ static void print_num_lld(char** at, size_t* left, int* ret, long long value, int minw, int precision, int prgiven, int zeropad, int minus, int plus, int space) { char buf[PRINT_DEC_BUFSZ]; int negative = (value < 0); int zero = (value == 0); int len = print_dec_ll(buf, (int)sizeof(buf), (unsigned long long)(negative?-value:value)); print_num(at, left, ret, minw, precision, prgiven, zeropad, minus, plus, space, zero, negative, buf, len); } /** print %u */ static void print_num_u(char** at, size_t* left, int* ret, unsigned int value, int minw, int precision, int prgiven, int zeropad, int minus, int plus, int space) { char buf[PRINT_DEC_BUFSZ]; int negative = 0; int zero = (value == 0); int len = print_dec(buf, (int)sizeof(buf), value); print_num(at, left, ret, minw, precision, prgiven, zeropad, minus, plus, space, zero, negative, buf, len); } /** print %lu */ static void print_num_lu(char** at, size_t* left, int* ret, unsigned long value, int minw, int precision, int prgiven, int zeropad, int minus, int plus, int space) { char buf[PRINT_DEC_BUFSZ]; int negative = 0; int zero = (value == 0); int len = print_dec_l(buf, (int)sizeof(buf), value); print_num(at, left, ret, minw, precision, prgiven, zeropad, minus, plus, space, zero, negative, buf, len); } /** print %llu */ static void print_num_llu(char** at, size_t* left, int* ret, unsigned long long value, int minw, int precision, int prgiven, int zeropad, int minus, int plus, int space) { char buf[PRINT_DEC_BUFSZ]; int negative = 0; int zero = (value == 0); int len = print_dec_ll(buf, (int)sizeof(buf), value); print_num(at, left, ret, minw, precision, prgiven, zeropad, minus, plus, space, zero, negative, buf, len); } /** print %x */ static void print_num_x(char** at, size_t* left, int* ret, unsigned int value, int minw, int precision, int prgiven, int zeropad, int minus, int plus, int space) { char buf[PRINT_DEC_BUFSZ]; int negative = 0; int zero = (value == 0); int len = print_hex(buf, (int)sizeof(buf), value); print_num(at, left, ret, minw, precision, prgiven, zeropad, minus, plus, space, zero, negative, buf, len); } /** print %lx */ static void print_num_lx(char** at, size_t* left, int* ret, unsigned long value, int minw, int precision, int prgiven, int zeropad, int minus, int plus, int space) { char buf[PRINT_DEC_BUFSZ]; int negative = 0; int zero = (value == 0); int len = print_hex_l(buf, (int)sizeof(buf), value); print_num(at, left, ret, minw, precision, prgiven, zeropad, minus, plus, space, zero, negative, buf, len); } /** print %llx */ static void print_num_llx(char** at, size_t* left, int* ret, unsigned long long value, int minw, int precision, int prgiven, int zeropad, int minus, int plus, int space) { char buf[PRINT_DEC_BUFSZ]; int negative = 0; int zero = (value == 0); int len = print_hex_ll(buf, (int)sizeof(buf), value); print_num(at, left, ret, minw, precision, prgiven, zeropad, minus, plus, space, zero, negative, buf, len); } /** print %llp */ static void print_num_llp(char** at, size_t* left, int* ret, void* value, int minw, int precision, int prgiven, int zeropad, int minus, int plus, int space) { char buf[PRINT_DEC_BUFSZ]; int negative = 0; int zero = (value == 0); #if defined(UINTPTR_MAX) && defined(UINT32_MAX) && (UINTPTR_MAX == UINT32_MAX) /* avoid warning about upcast on 32bit systems */ unsigned long long llvalue = (unsigned long)value; #else unsigned long long llvalue = (unsigned long long)value; #endif int len = print_hex_ll(buf, (int)sizeof(buf), llvalue); if(zero) { buf[0]=')'; buf[1]='l'; buf[2]='i'; buf[3]='n'; buf[4]='('; len = 5; } else { /* put '0x' in front of the (reversed) buffer result */ if(len < PRINT_DEC_BUFSZ) buf[len++] = 'x'; if(len < PRINT_DEC_BUFSZ) buf[len++] = '0'; } print_num(at, left, ret, minw, precision, prgiven, zeropad, minus, plus, space, zero, negative, buf, len); } #define PRINT_FLOAT_BUFSZ 64 /* xx.yy with 20.20 about the max */ /** spool remainder after the decimal point to buffer, in reverse */ static int print_remainder(char* buf, int max, double r, int prec) { unsigned long long cap = 1; unsigned long long value; int len, i; if(prec > 19) prec = 19; /* max we can do */ if(max < prec) return 0; for(i=0; i= 5) { value++; /* that might carry to numbers before the comma, if so, * just ignore that rounding. failure because 64bitprintout */ if(value >= cap) value = cap-1; } len = print_dec_ll(buf, max, value); while(len < prec) { /* pad with zeroes, e.g. if 0.0012 */ buf[len++] = '0'; } if(len < max) buf[len++] = '.'; return len; } /** spool floating point to buffer */ static int print_float(char* buf, int max, double value, int prec) { /* as xxx.xxx if prec==0, no '.', with prec decimals after . */ /* no conversion for NAN and INF, because we do not want to require linking with -lm. */ /* Thus, the conversions use 64bit integers to convert the numbers, * which makes 19 digits before and after the decimal point the max */ unsigned long long whole = (unsigned long long)value; double remain = value - (double)whole; int len = 0; if(prec != 0) len = print_remainder(buf, max, remain, prec); len += print_dec_ll(buf+len, max-len, whole); return len; } /** print %f */ static void print_num_f(char** at, size_t* left, int* ret, double value, int minw, int precision, int prgiven, int zeropad, int minus, int plus, int space) { char buf[PRINT_FLOAT_BUFSZ]; int negative = (value < 0); int zero = 0; int len; if(!prgiven) precision = 6; len = print_float(buf, (int)sizeof(buf), negative?-value:value, precision); print_num(at, left, ret, minw, 1, 0, zeropad, minus, plus, space, zero, negative, buf, len); } /* rudimentary %g support */ static int print_float_g(char* buf, int max, double value, int prec) { unsigned long long whole = (unsigned long long)value; double remain = value - (double)whole; int before = 0; int len = 0; /* number of digits before the decimal point */ while(whole > 0) { before++; whole /= 10; } whole = (unsigned long long)value; if(prec > before && remain != 0.0) { /* see if the last decimals are zero, if so, skip them */ len = print_remainder(buf, max, remain, prec-before); while(len > 0 && buf[0]=='0') { memmove(buf, buf+1, --len); } } len += print_dec_ll(buf+len, max-len, whole); return len; } /** print %g */ static void print_num_g(char** at, size_t* left, int* ret, double value, int minw, int precision, int prgiven, int zeropad, int minus, int plus, int space) { char buf[PRINT_FLOAT_BUFSZ]; int negative = (value < 0); int zero = 0; int len; if(!prgiven) precision = 6; if(precision == 0) precision = 1; len = print_float_g(buf, (int)sizeof(buf), negative?-value:value, precision); print_num(at, left, ret, minw, 1, 0, zeropad, minus, plus, space, zero, negative, buf, len); } /** strnlen (compat implementation) */ static int my_strnlen(const char* s, int max) { int i; for(i=0; i 1) { *at++ = *fmt++; left--; } else fmt++; ret++; } /* see if we are at end */ if(!*fmt) break; /* fetch next argument % designation from format string */ fmt++; /* skip the '%' */ /********************************/ /* get the argument designation */ /********************************/ /* we must do this vararg stuff inside this function for * portability. Hence, get_designation, and print_designation * are not their own functions. */ /* printout designation: * conversion specifier: x, d, u, s, c, n, m, p * flags: # not supported * 0 zeropad (on the left) * - left adjust (right by default) * ' ' printspace for positive number (in - position). * + alwayssign * fieldwidth: [1-9][0-9]* minimum field width. * if this is * then type int next argument specifies the minwidth. * if this is negative, the - flag is set (with positive width). * precision: period[digits]*, %.2x. * if this is * then type int next argument specifies the precision. * just '.' or negative value means precision=0. * this is mindigits to print for d, i, u, x * this is aftercomma digits for f * this is max number significant digits for g * maxnumber characters to be printed for s * length: 0-none (int), 1-l (long), 2-ll (long long) * notsupported: hh (char), h (short), L (long double), q, j, z, t * Does not support %m$ and *m$ argument designation as array indices. * Does not support %#x * */ minw = 0; precision = 1; prgiven = 0; zeropad = 0; minus = 0; plus = 0; space = 0; length = 0; /* get flags in any order */ for(;;) { if(*fmt == '0') zeropad = 1; else if(*fmt == '-') minus = 1; else if(*fmt == '+') plus = 1; else if(*fmt == ' ') space = 1; else break; fmt++; } /* field width */ if(*fmt == '*') { fmt++; /* skip char */ minw = va_arg(arg, int); if(minw < 0) { minus = 1; minw = -minw; } } else while(*fmt >= '0' && *fmt <= '9') { minw = minw*10 + (*fmt++)-'0'; } /* precision */ if(*fmt == '.') { fmt++; /* skip period */ prgiven = 1; precision = 0; if(*fmt == '*') { fmt++; /* skip char */ precision = va_arg(arg, int); if(precision < 0) precision = 0; } else while(*fmt >= '0' && *fmt <= '9') { precision = precision*10 + (*fmt++)-'0'; } } /* length */ if(*fmt == 'l') { fmt++; /* skip char */ length = 1; if(*fmt == 'l') { fmt++; /* skip char */ length = 2; } } /* get the conversion */ if(!*fmt) conv = 0; else conv = *fmt++; /***********************************/ /* print that argument designation */ /***********************************/ switch(conv) { case 'i': case 'd': if(length == 0) print_num_d(&at, &left, &ret, va_arg(arg, int), minw, precision, prgiven, zeropad, minus, plus, space); else if(length == 1) print_num_ld(&at, &left, &ret, va_arg(arg, long), minw, precision, prgiven, zeropad, minus, plus, space); else if(length == 2) print_num_lld(&at, &left, &ret, va_arg(arg, long long), minw, precision, prgiven, zeropad, minus, plus, space); break; case 'u': if(length == 0) print_num_u(&at, &left, &ret, va_arg(arg, unsigned int), minw, precision, prgiven, zeropad, minus, plus, space); else if(length == 1) print_num_lu(&at, &left, &ret, va_arg(arg, unsigned long), minw, precision, prgiven, zeropad, minus, plus, space); else if(length == 2) print_num_llu(&at, &left, &ret, va_arg(arg, unsigned long long), minw, precision, prgiven, zeropad, minus, plus, space); break; case 'x': if(length == 0) print_num_x(&at, &left, &ret, va_arg(arg, unsigned int), minw, precision, prgiven, zeropad, minus, plus, space); else if(length == 1) print_num_lx(&at, &left, &ret, va_arg(arg, unsigned long), minw, precision, prgiven, zeropad, minus, plus, space); else if(length == 2) print_num_llx(&at, &left, &ret, va_arg(arg, unsigned long long), minw, precision, prgiven, zeropad, minus, plus, space); break; case 's': print_str(&at, &left, &ret, va_arg(arg, char*), minw, precision, prgiven, minus); break; case 'c': print_char(&at, &left, &ret, va_arg(arg, int), minw, minus); break; case 'n': *va_arg(arg, int*) = ret; break; case 'm': print_str(&at, &left, &ret, strerror(errno), minw, precision, prgiven, minus); break; case 'p': print_num_llp(&at, &left, &ret, va_arg(arg, void*), minw, precision, prgiven, zeropad, minus, plus, space); break; case '%': print_pad(&at, &left, &ret, '%', 1); break; case 'f': print_num_f(&at, &left, &ret, va_arg(arg, double), minw, precision, prgiven, zeropad, minus, plus, space); break; case 'g': print_num_g(&at, &left, &ret, va_arg(arg, double), minw, precision, prgiven, zeropad, minus, plus, space); break; /* unknown */ default: case 0: break; } } /* zero terminate */ if(left > 0) *at = 0; return ret; } #ifdef SNPRINTF_TEST /** do tests */ #undef snprintf #define DOTEST(bufsz, result, retval, ...) do { \ char buf[bufsz]; \ printf("now test %s\n", #__VA_ARGS__); \ int r=my_snprintf(buf, sizeof(buf), __VA_ARGS__); \ if(r != retval || strcmp(buf, result) != 0) { \ printf("error test(%s) was \"%s\":%d\n", \ ""#bufsz", "#result", "#retval", "#__VA_ARGS__, \ buf, r); \ exit(1); \ } \ r=snprintf(buf, sizeof(buf), __VA_ARGS__); \ if(r != retval || strcmp(buf, result) != 0) { \ printf("error test(%s) differs with system, \"%s\":%d\n", \ ""#bufsz", "#result", "#retval", "#__VA_ARGS__, \ buf, r); \ exit(1); \ } \ printf("test(\"%s\":%d) passed\n", buf, r); \ } while(0); /** test program */ int main(void) { int x = 0; /* bufsize, expectedstring, expectedretval, snprintf arguments */ DOTEST(1024, "hello", 5, "hello"); DOTEST(1024, "h", 1, "h"); /* warning from gcc for format string, but it does work * DOTEST(1024, "", 0, ""); */ DOTEST(3, "he", 5, "hello"); DOTEST(1, "", 7, "%d", 7823089); /* test positive numbers */ DOTEST(1024, "0", 1, "%d", 0); DOTEST(1024, "1", 1, "%d", 1); DOTEST(1024, "9", 1, "%d", 9); DOTEST(1024, "15", 2, "%d", 15); DOTEST(1024, "ab15cd", 6, "ab%dcd", 15); DOTEST(1024, "167", 3, "%d", 167); DOTEST(1024, "7823089", 7, "%d", 7823089); DOTEST(1024, " 12", 3, "%3d", 12); DOTEST(1024, "012", 3, "%.3d", 12); DOTEST(1024, "012", 3, "%3.3d", 12); DOTEST(1024, "012", 3, "%03d", 12); DOTEST(1024, " 012", 4, "%4.3d", 12); DOTEST(1024, "", 0, "%.0d", 0); /* test negative numbers */ DOTEST(1024, "-1", 2, "%d", -1); DOTEST(1024, "-12", 3, "%3d", -12); DOTEST(1024, " -2", 3, "%3d", -2); DOTEST(1024, "-012", 4, "%.3d", -12); DOTEST(1024, "-012", 4, "%3.3d", -12); DOTEST(1024, "-012", 4, "%4.3d", -12); DOTEST(1024, " -012", 5, "%5.3d", -12); DOTEST(1024, "-12", 3, "%03d", -12); DOTEST(1024, "-02", 3, "%03d", -2); DOTEST(1024, "-15", 3, "%d", -15); DOTEST(1024, "-7307", 5, "%d", -7307); DOTEST(1024, "-12 ", 5, "%-5d", -12); DOTEST(1024, "-00012", 6, "%-.5d", -12); /* test + and space flags */ DOTEST(1024, "+12", 3, "%+d", 12); DOTEST(1024, " 12", 3, "% d", 12); /* test %u */ DOTEST(1024, "12", 2, "%u", 12); DOTEST(1024, "0", 1, "%u", 0); DOTEST(1024, "4294967295", 10, "%u", 0xffffffff); /* test %x */ DOTEST(1024, "0", 1, "%x", 0); DOTEST(1024, "c", 1, "%x", 12); DOTEST(1024, "12ab34cd", 8, "%x", 0x12ab34cd); /* test %llu, %lld */ DOTEST(1024, "18446744073709551615", 20, "%llu", (long long)0xffffffffffffffff); DOTEST(1024, "-9223372036854775808", 20, "%lld", (long long)0x8000000000000000); DOTEST(1024, "9223372036854775808", 19, "%llu", (long long)0x8000000000000000); /* test %s */ DOTEST(1024, "hello", 5, "%s", "hello"); DOTEST(1024, " hello", 10, "%10s", "hello"); DOTEST(1024, "hello ", 10, "%-10s", "hello"); DOTEST(1024, "he", 2, "%.2s", "hello"); DOTEST(1024, " he", 4, "%4.2s", "hello"); DOTEST(1024, " h", 4, "%4.2s", "h"); /* test %c */ DOTEST(1024, "a", 1, "%c", 'a'); /* warning from gcc for format string, but it does work DOTEST(1024, " a", 5, "%5c", 'a'); DOTEST(1024, "a", 1, "%.0c", 'a'); */ /* test %n */ DOTEST(1024, "hello", 5, "hello%n", &x); if(x != 5) { printf("the %%n failed\n"); exit(1); } /* test %m */ errno = 0; DOTEST(1024, "Success", 7, "%m"); /* test %p */ DOTEST(1024, "0x10", 4, "%p", (void*)0x10); DOTEST(1024, "(nil)", 5, "%p", (void*)0x0); /* test %% */ DOTEST(1024, "%", 1, "%%"); /* test %f */ DOTEST(1024, "0.000000", 8, "%f", 0.0); DOTEST(1024, "0.00", 4, "%.2f", 0.0); /* differs, "-0.00" DOTEST(1024, "0.00", 4, "%.2f", -0.0); */ DOTEST(1024, "234.00", 6, "%.2f", 234.005); DOTEST(1024, "8973497.1246", 12, "%.4f", 8973497.12456); DOTEST(1024, "-12.000000", 10, "%f", -12.0); DOTEST(1024, "6", 1, "%.0f", 6.0); DOTEST(1024, "6", 1, "%g", 6.0); DOTEST(1024, "6.1", 3, "%g", 6.1); DOTEST(1024, "6.15", 4, "%g", 6.15); /* These format strings are from the code of NSD, Unbound, ldns */ DOTEST(1024, "abcdef", 6, "%s", "abcdef"); DOTEST(1024, "005", 3, "%03u", 5); DOTEST(1024, "12345", 5, "%03u", 12345); DOTEST(1024, "5", 1, "%d", 5); DOTEST(1024, "(nil)", 5, "%p", NULL); DOTEST(1024, "12345", 5, "%ld", (long)12345); DOTEST(1024, "12345", 5, "%lu", (long)12345); DOTEST(1024, " 12345", 12, "%12u", (unsigned)12345); DOTEST(1024, "12345", 5, "%u", (unsigned)12345); DOTEST(1024, "12345", 5, "%llu", (unsigned long long)12345); DOTEST(1024, "12345", 5, "%x", 0x12345); DOTEST(1024, "12345", 5, "%llx", (long long)0x12345); DOTEST(1024, "012345", 6, "%6.6d", 12345); DOTEST(1024, "012345", 6, "%6.6u", 12345); DOTEST(1024, "1234.54", 7, "%g", 1234.54); DOTEST(1024, "123456789.54", 12, "%.12g", 123456789.54); DOTEST(1024, "3456789123456.54", 16, "%.16g", 3456789123456.54); /* %24g does not work with 24 digits, not enough accuracy, * the first 16 digits are correct */ DOTEST(1024, "12345", 5, "%3.3d", 12345); DOTEST(1024, "000", 3, "%3.3d", 0); DOTEST(1024, "001", 3, "%3.3d", 1); DOTEST(1024, "012", 3, "%3.3d", 12); DOTEST(1024, "-012", 4, "%3.3d", -12); DOTEST(1024, "he", 2, "%.2s", "hello"); DOTEST(1024, "helloworld", 10, "%s%s", "hello", "world"); DOTEST(1024, "he", 2, "%.*s", 2, "hello"); DOTEST(1024, " hello", 7, "%*s", 7, "hello"); DOTEST(1024, "hello ", 7, "%*s", -7, "hello"); DOTEST(1024, "0", 1, "%c", '0'); DOTEST(1024, "A", 1, "%c", 'A'); DOTEST(1024, "", 1, "%c", 0); DOTEST(1024, "\010", 1, "%c", 8); DOTEST(1024, "%", 1, "%%"); DOTEST(1024, "0a", 2, "%02x", 0x0a); DOTEST(1024, "bd", 2, "%02x", 0xbd); DOTEST(1024, "12", 2, "%02ld", (long)12); DOTEST(1024, "02", 2, "%02ld", (long)2); DOTEST(1024, "02", 2, "%02u", (unsigned)2); DOTEST(1024, "765432", 6, "%05u", (unsigned)765432); DOTEST(1024, "10.234", 6, "%0.3f", 10.23421); DOTEST(1024, "123456.234", 10, "%0.3f", 123456.23421); DOTEST(1024, "123456789.234", 13, "%0.3f", 123456789.23421); DOTEST(1024, "123456.23", 9, "%.2f", 123456.23421); DOTEST(1024, "123456", 6, "%.0f", 123456.23421); DOTEST(1024, "0123", 4, "%.4x", 0x0123); DOTEST(1024, "00000123", 8, "%.8x", 0x0123); DOTEST(1024, "ffeb0cde", 8, "%.8x", 0xffeb0cde); DOTEST(1024, " 987654321", 10, "%10lu", (unsigned long)987654321); DOTEST(1024, " 987654321", 12, "%12lu", (unsigned long)987654321); DOTEST(1024, "987654321", 9, "%i", 987654321); DOTEST(1024, "-87654321", 9, "%i", -87654321); DOTEST(1024, "hello ", 16, "%-16s", "hello"); DOTEST(1024, " ", 16, "%-16s", ""); DOTEST(1024, "a ", 16, "%-16s", "a"); DOTEST(1024, "foobarfoobar ", 16, "%-16s", "foobarfoobar"); DOTEST(1024, "foobarfoobarfoobar", 18, "%-16s", "foobarfoobarfoobar"); /* combined expressions */ DOTEST(1024, "foo 1.0 size 512 edns", 21, "foo %s size %d %s%s", "1.0", 512, "", "edns"); DOTEST(15, "foo 1.0 size 5", 21, "foo %s size %d %s%s", "1.0", 512, "", "edns"); DOTEST(1024, "packet 1203ceff id", 18, "packet %2.2x%2.2x%2.2x%2.2x id", 0x12, 0x03, 0xce, 0xff); DOTEST(1024, "/tmp/testbound_123abcd.tmp", 26, "/tmp/testbound_%u%s%s.tmp", 123, "ab", "cd"); return 0; } #endif /* SNPRINTF_TEST */ dnssec-trigger-0.13/compat/inet_ntop.c0000664000175000017500000001275311667151650017461 0ustar wouterwouter/* From openssh 4.3p2 compat/inet_ntop.c */ /* Copyright (c) 1996 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /* OPENBSD ORIGINAL: lib/libc/net/inet_ntop.c */ #include #ifndef HAVE_INET_NTOP #include #include #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #include #include #include #ifndef IN6ADDRSZ #define IN6ADDRSZ 16 /* IPv6 T_AAAA */ #endif #ifndef INT16SZ #define INT16SZ 2 /* for systems without 16-bit ints */ #endif /* * WARNING: Don't even consider trying to compile this on a system where * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ static const char *inet_ntop4(const u_char *src, char *dst, size_t size); static const char *inet_ntop6(const u_char *src, char *dst, size_t size); /* char * * inet_ntop(af, src, dst, size) * convert a network format address to presentation format. * return: * pointer to presentation format address (`dst'), or NULL (see errno). * author: * Paul Vixie, 1996. */ const char * inet_ntop(int af, const void *src, char *dst, size_t size) { switch (af) { case AF_INET: return (inet_ntop4(src, dst, size)); case AF_INET6: return (inet_ntop6(src, dst, size)); default: #ifdef EAFNOSUPPORT errno = EAFNOSUPPORT; #else errno = ENOSYS; #endif return (NULL); } /* NOTREACHED */ } /* const char * * inet_ntop4(src, dst, size) * format an IPv4 address, more or less like inet_ntoa() * return: * `dst' (as a const) * notes: * (1) uses no statics * (2) takes a u_char* not an in_addr as input * author: * Paul Vixie, 1996. */ static const char * inet_ntop4(const u_char *src, char *dst, size_t size) { static const char fmt[] = "%u.%u.%u.%u"; char tmp[sizeof "255.255.255.255"]; int l; l = snprintf(tmp, size, fmt, src[0], src[1], src[2], src[3]); if (l <= 0 || l >= (int)size) { errno = ENOSPC; return (NULL); } strlcpy(dst, tmp, size); return (dst); } /* const char * * inet_ntop6(src, dst, size) * convert IPv6 binary address into presentation (printable) format * author: * Paul Vixie, 1996. */ static const char * inet_ntop6(const u_char *src, char *dst, size_t size) { /* * Note that int32_t and int16_t need only be "at least" large enough * to contain a value of the specified size. On some systems, like * Crays, there is no such thing as an integer variable with 16 bits. * Keep this in mind if you think this function should have been coded * to use pointer overlays. All the world's not a VAX. */ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; char *tp, *ep; struct { int base, len; } best, cur; u_int words[IN6ADDRSZ / INT16SZ]; int i; int advance; /* * Preprocess: * Copy the input (bytewise) array into a wordwise array. * Find the longest run of 0x00's in src[] for :: shorthanding. */ memset(words, '\0', sizeof words); for (i = 0; i < IN6ADDRSZ; i++) words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); best.base = -1; best.len = 0; cur.base = -1; cur.len = 0; for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { if (words[i] == 0) { if (cur.base == -1) cur.base = i, cur.len = 1; else cur.len++; } else { if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; cur.base = -1; } } } if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; } if (best.base != -1 && best.len < 2) best.base = -1; /* * Format the result. */ tp = tmp; ep = tmp + sizeof(tmp); for (i = 0; i < (IN6ADDRSZ / INT16SZ) && tp < ep; i++) { /* Are we inside the best run of 0x00's? */ if (best.base != -1 && i >= best.base && i < (best.base + best.len)) { if (i == best.base) { if (tp + 1 >= ep) return (NULL); *tp++ = ':'; } continue; } /* Are we following an initial run of 0x00s or any real hex? */ if (i != 0) { if (tp + 1 >= ep) return (NULL); *tp++ = ':'; } /* Is this address an encapsulated IPv4? */ if (i == 6 && best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { if (!inet_ntop4(src+12, tp, (size_t)(ep - tp))) return (NULL); tp += strlen(tp); break; } advance = snprintf(tp, ep - tp, "%x", words[i]); if (advance <= 0 || advance >= ep - tp) return (NULL); tp += advance; } /* Was it a trailing run of 0x00's? */ if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) { if (tp + 1 >= ep) return (NULL); *tp++ = ':'; } if (tp + 1 >= ep) return (NULL); *tp++ = '\0'; /* * Check for overflow, copy, and we're done. */ if ((size_t)(tp - tmp) > size) { errno = ENOSPC; return (NULL); } strlcpy(dst, tmp, size); return (dst); } #endif /* !HAVE_INET_NTOP */ dnssec-trigger-0.13/dnssec.conf0000664000175000017500000001104012461441377016146 0ustar wouterwouter# The options configured in this file are supported by dnssec-trigger-script # which is called due to various events in related services including # dnssec-trigger and NetworkManager. As a result, dnssec-trigger-script, # together with the dnssec-trigger daemon, reconfigures a running instance # of Unbound, your local validating resolver. # # Changes in this file are typically applied on the next network change. To # make them work immediately, restart the dnssec-trigger service. On many # systems this is achieved by the following command: # # systemctl restart dnssec-triggerd # # To achieve a clean state of Unbound, you can just restart the unbound # service and dnssec-trigger gets restarted automatically. Note that some # other services like VPN clients may have reconfigured unbound at runtime # and thus may need to be restarted as well. # # systemctl restart unbound # # In future some of the options may be interpretted by other services as well, # so be careful to restart all of them. One such service may be a future # version of NetworkManager. # # systemctl restart NetworkManager # # validate_connection_provided_zones: # ----------------------------------- # Ensures that foward zones provided by NetworkManager connections will be # validated by Unbound. # # Security notes: # # - If this option is turned off, the network you're connecting to # can provide you a list of spoofed domains e.g. via DHCP. Those domains # are then configured as insecure forward zones in your local validating # resolver, constituting a downgrade attack on DNSSEC validation. # # - See also security notes on the `add_wifi_provided_zones` option. # # validate_connection_provided_zones=yes # # - Connection provided zones will be configured in Unbound as secure forward # zones, validated using DNSSEC. # # If the DNS servers for such a connection are not capable of forwarding # DNSSEC queries and responses or the local zone is required to be signed # according to the global DNSSEC database, local resources will not be # resolved correctly and will appear inaccessible. # # Many networks use fake top level domains which fail DNSSEC validation # as there is no way to validate them at all. Do not use this strict # option if you want to access resources on such networks. # # validate_connection_provided_zones=no # # - Connection provided zones will be configured in Unbound as insecure # forward zones, not validated using DNSSEC. This allows you to access # local resources on networks with non-compliant DNS servers as well # as networks that hijack domains that are either not in the global DNS # tree at all or are required to be signed. # # Turning this option off has security implications, See the security # notice above. # validate_connection_provided_zones=yes # add_wifi_provided_zones: # ------------------------ # Ensures that wifi provided zones are accepted by dnssec-trigger-script just # as any other connection provided zones. Wireless ethernet is special in # that you often connect to network with no authentication or authentication # based on a shared secret. # # Security notes: # # - Anyone knowing such a shared secret can set up an access point for the # network and provide you a spoofed domain list via DHCP. When this option # is turned on, the spoofed domains are configured as forward zones in your # local validating resolver. # # - See also security notes on the `validate_connection_provided_zones` option. # # add_wifi_provided_zones=yes # # - Domains provided by WiFi connections will be configured as forward zones # in your local validating resolver. See the security notice above. # # add_wifi_provided_zones=no # # - Domains provided by WiFi connection will be ignored. # add_wifi_provided_zones=no # set_search_domains: # ------------------- # Enable or disable writing of search domains to `/etc/resolv.conf`. # # set_search_domains=yes - Search domains are written to `/etc/resolv.conf`. # # set_search_domains=no - Search domains are not written to `/etc/resolv.conf`. # set_search_domains=no # use_private_address_ranges: # --------------------------- # Enable or disable adding reverse name resolution zones derived from # private IP addresses as defined in RFC 1918 and RFC 4193. # # use_private_address_ranges=yes - Use standard private IP address ranges to build # reverse name resolution zones using the global # forwarders. # # use_private_address_ranges=no - Ignore standard IP address ranges. use_private_address_ranges=yes