diff options
Diffstat (limited to 'external/unbound/winrc')
32 files changed, 2303 insertions, 0 deletions
diff --git a/external/unbound/winrc/README.txt b/external/unbound/winrc/README.txt new file mode 100644 index 000000000..e40204bb0 --- /dev/null +++ b/external/unbound/winrc/README.txt @@ -0,0 +1,100 @@ +README for Unbound on Windows.
+
+(C) 2009, W.C.A. Wijngaards, NLnet Labs.
+
+See LICENSE for the license text file.
+
+
++++ Introduction
+
+Unbound is a recursive DNS server. It does caching, full recursion, stub
+recursion, DNSSEC validation, NSEC3, IPv6. More information can be found
+at the http://unbound.net site. Unbound has been built and tested on
+Windows XP, Vista and 7.
+
+At http://unbound.net/documentation is an install and configuration manual
+for windows.
+
+email: unbound-bugs@nlnetlabs.nl
+
+
++++ How to use it
+
+In ControlPanels\SystemTasks\Services you can start/stop the daemon.
+In ControlPanels\SystemTasks\Logbooks you can see log entries (unless you
+configured unbound to log to file).
+
+By default the daemon provides service only to localhost. See the manual
+on how to change that (you need to edit the config file).
+
+To change options, edit the service.conf file. The example.conf file
+contains information on the various configuration options. The config
+file is the same as on Unix. The options log-time-ascii, chroot, username
+and pidfile are not supported on windows.
+
+
++++ How to compile
+
+Unbound is open source under the BSD license. You can compile it yourself.
+
+1. Install MinGW and MSYS. http://www.mingw.org
+This is a free, open source, compiler and build environment.
+Note, if your username contains a space, create a directory
+C:\msys\...\home\user to work in (click on MSYS; type: mkdir /home/user ).
+
+2. Install openssl, or compile it yourself. http://www.openssl.org
+Unbounds need the header files and libraries. Static linking makes
+things easier. This is an open source library for cryptographic functions.
+And libexpat is needed.
+
+3. Compile Unbound
+Get the source code tarball http://unbound.net
+Move it into the C:\msys\...\home\user directory.
+Double click on the MSYS icon and give these commands
+$ cd /home/user
+$ tar xzvf unbound-xxx.tar.gz
+$ cd unbound-xxx
+$ ./configure --enable-static-exe
+If you compiled openssl yourself, pass --with-ssl=../openssl-xxx too.
+If you compiled libexpat yourself, pass --with-libexpat=../expat-install too.
+The configure options for libevent or threads are not applicable for
+windows, because builtin alternatives for the windows platform are used.
+$ make
+And you have unbound.exe
+
+If you run unbound-service-install.exe (double click in the explorer),
+unbound is installed as a service in the controlpanels\systemtasks\services,
+from the current directory. unbound-service-remove.exe uninstalls the service.
+
+Unbound and its utilities also work from the commandline (like on unix) if
+you prefer.
+
+
++++ Cross compile
+
+You can crosscompile unbound. This results in .exe files.
+Install the packages: mingw32-binutils mingw32-cpp mingw32-filesystem
+mingw32-gcc mingw32-openssl mingw32-openssl-static mingw32-runtime zip
+mingw32-termcap mingw32-w32api mingw32-zlib mingw32-zlib-static mingw32-nsis
+(package names for fedora 11).
+
+For dynamic linked executables
+$ mingw32-configure
+$ make
+$ mkdir /home/user/installdir
+$ make install DESTDIR=/home/user/installdir
+Find the dlls and exes in /home/user/installdir and
+crypto in /usr/i686-pc-mingw32/sys-root/mingw/bin
+
+For static linked executables
+Use --enable-staticexe for mingw32-configure, see above. Or use makedist.sh,
+copy System.dll from the windows dist of NSIS to /usr/share/nsis/Plugins/
+Then do ./makedist.sh -w and the setup.exe is created using nsis.
+
+
++++ CREDITS
+
+Unbound was written in portable C by Wouter Wijngaards (NLnet Labs).
+See the CREDITS file in the source package for more contributor information.
+Email unbound-bugs@nlnetlabs.nl
+
diff --git a/external/unbound/winrc/anchor-update.c b/external/unbound/winrc/anchor-update.c new file mode 100644 index 000000000..2b22e0142 --- /dev/null +++ b/external/unbound/winrc/anchor-update.c @@ -0,0 +1,152 @@ +/* + * winrc/anchor-update.c - windows trust anchor update util + * + * 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 is made because contrib/update-anchor.sh does not work on + * windows (no shell). + */ +#include "config.h" +#include "libunbound/unbound.h" +#include "ldns/rrdef.h" +#include "ldns/pkthdr.h" +#include "ldns/wire2str.h" + +/** usage */ +static void +usage(void) +{ + printf("usage: { name-of-domain filename }+ \n"); + printf("exit codes: 0 anchors updated, 1 no changes, 2 errors.\n"); + exit(1); +} + +/** fatal exit */ +static void fatal(const char* str) +{ + printf("fatal error: %s\n", str); + exit(2); +} + +/** lookup data */ +static struct ub_result* +do_lookup(struct ub_ctx* ctx, char* domain) +{ + struct ub_result* result = NULL; + int r; + r = ub_resolve(ctx, domain, LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, + &result); + if(r) { + printf("failed to lookup %s\n", ub_strerror(r)); + fatal("ub_resolve failed"); + } + if(!result->havedata && (result->rcode == LDNS_RCODE_SERVFAIL || + result->rcode == LDNS_RCODE_REFUSED)) + return NULL; /* probably no internet connection */ + if(!result->havedata) fatal("result has no data"); + if(!result->secure) fatal("result is not secure"); + return result; +} + +/** print result to file */ +static void +do_print(struct ub_result* result, char* file) +{ + FILE* out = fopen(file, "w"); + char s[65535], t[32]; + int i; + if(!out) { + perror(file); + fatal("fopen failed"); + } + i = 0; + if(result->havedata) + while(result->data[i]) { + sldns_wire2str_rdata_buf((uint8_t*)result->data[i], + (size_t)result->len[i], s, sizeof(s), + (uint16_t)result->qtype); + sldns_wire2str_type_buf((uint16_t)result->qtype, t, sizeof(t)); + fprintf(out, "%s\t%s\t%s\n", result->qname, t, s); + i++; + } + fclose(out); +} + +/** update domain to file */ +static int +do_update(char* domain, char* file) +{ + struct ub_ctx* ctx; + struct ub_result* result; + int r; + printf("updating %s to %s\n", domain, file); + ctx = ub_ctx_create(); + if(!ctx) fatal("ub_ctx_create failed"); + + if((r=ub_ctx_add_ta_file(ctx, file))) { + printf("%s\n", ub_strerror(r)); + fatal("ub_ctx_add_ta_file failed"); + } + + if(!(result=do_lookup(ctx, domain))) { + ub_ctx_delete(ctx); + return 1; + } + ub_ctx_delete(ctx); + do_print(result, file); + ub_resolve_free(result); + return 0; +} + +/** anchor update main */ +int main(int argc, char** argv) +{ + int retcode = 1; + if(argc == 1) { + usage(); + } + argc--; + argv++; + while(argc > 0) { + int r = do_update(argv[0], argv[1]); + if(r == 0) retcode = 0; + + /* next */ + argc-=2; + argv+=2; + } + return retcode; +} diff --git a/external/unbound/winrc/combined.ico b/external/unbound/winrc/combined.ico Binary files differnew file mode 100644 index 000000000..aa65d11e2 --- /dev/null +++ b/external/unbound/winrc/combined.ico diff --git a/external/unbound/winrc/gen_msg.bin b/external/unbound/winrc/gen_msg.bin Binary files differnew file mode 100644 index 000000000..6e560057c --- /dev/null +++ b/external/unbound/winrc/gen_msg.bin diff --git a/external/unbound/winrc/gen_msg.mc b/external/unbound/winrc/gen_msg.mc new file mode 100644 index 000000000..bde32176e --- /dev/null +++ b/external/unbound/winrc/gen_msg.mc @@ -0,0 +1,44 @@ +; for Unbound +; 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_unbound.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 +. + diff --git a/external/unbound/winrc/rsrc_anchorupd.rc b/external/unbound/winrc/rsrc_anchorupd.rc new file mode 100644 index 000000000..2419bfad5 --- /dev/null +++ b/external/unbound/winrc/rsrc_anchorupd.rc @@ -0,0 +1,40 @@ +/* + Unbound 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", "Unbound trust anchor tool" + VALUE "FileVersion", PACKAGE_VERSION + VALUE "InternalName", "anchor-update" + VALUE "OriginalFilename", "anchor-update.exe" + VALUE "ProductName", "unbound" + VALUE "ProductVersion", PACKAGE_VERSION + VALUE "LegalCopyright", "(C) 2009 NLnet Labs. Source is BSD licensed." + END + END + BLOCK "VarFileInfo" + BEGIN + /* English(409), windows ANSI codepage (1252) */ + VALUE "Translation", 0x409, 0x1252 + END +END + +/* vista administrator access, show UAC prompt */ +1 RT_MANIFEST "winrc/vista_user.manifest" diff --git a/external/unbound/winrc/rsrc_svcinst.rc b/external/unbound/winrc/rsrc_svcinst.rc new file mode 100644 index 000000000..cb325f4c4 --- /dev/null +++ b/external/unbound/winrc/rsrc_svcinst.rc @@ -0,0 +1,45 @@ +/* + Unbound 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", "Unbound Service Install Util" + VALUE "FileVersion", PACKAGE_VERSION + VALUE "InternalName", "unbound-service-install" + VALUE "OriginalFilename", "unbound-service-install.exe" + VALUE "ProductName", "unbound" + VALUE "ProductVersion", PACKAGE_VERSION + VALUE "LegalCopyright", "(C) 2009 NLnet Labs. Source is BSD licensed." + END + END + BLOCK "VarFileInfo" + BEGIN + /* English(409), windows ANSI codepage (1252) */ + VALUE "Translation", 0x409, 0x1252 + END +END + +/* error message formats */ +LANGUAGE 0x9,0x1 +1 11 "winrc/gen_msg.bin" + +/* vista administrator access, show UAC prompt */ +1 RT_MANIFEST "winrc/vista_admin.manifest" + diff --git a/external/unbound/winrc/rsrc_svcuninst.rc b/external/unbound/winrc/rsrc_svcuninst.rc new file mode 100644 index 000000000..ecff8dcd3 --- /dev/null +++ b/external/unbound/winrc/rsrc_svcuninst.rc @@ -0,0 +1,45 @@ +/* + Unbound 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", "Unbound Service Remove Util" + VALUE "FileVersion", PACKAGE_VERSION + VALUE "InternalName", "unbound-service-remove" + VALUE "OriginalFilename", "unbound-service-remove.exe" + VALUE "ProductName", "unbound" + VALUE "ProductVersion", PACKAGE_VERSION + VALUE "LegalCopyright", "(C) 2009 NLnet Labs. Source is BSD licensed." + END + END + BLOCK "VarFileInfo" + BEGIN + /* English(409), windows ANSI codepage (1252) */ + VALUE "Translation", 0x409, 0x1252 + END +END + +/* error message formats */ +LANGUAGE 0x9,0x1 +1 11 "winrc/gen_msg.bin" + +/* vista administrator access, show UAC prompt */ +1 RT_MANIFEST "winrc/vista_admin.manifest" + diff --git a/external/unbound/winrc/rsrc_unbound.rc b/external/unbound/winrc/rsrc_unbound.rc new file mode 100644 index 000000000..cc05d0eeb --- /dev/null +++ b/external/unbound/winrc/rsrc_unbound.rc @@ -0,0 +1,48 @@ +/* + Unbound resource file for windows. For use with windres +*/ +#include "winver.h" +#include "config.h" + +1 ICON "winrc/combined.ico" +/* +1 ICON "winrc/unbound64.ico" +2 ICON "winrc/unbound48.ico" +3 ICON "winrc/unbound32.ico" +4 ICON "winrc/unbound16.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", "Unbound DNS Server" + VALUE "FileVersion", PACKAGE_VERSION + VALUE "InternalName", "unbound" + VALUE "OriginalFilename", "unbound.exe" + VALUE "ProductName", "unbound" + VALUE "ProductVersion", PACKAGE_VERSION + VALUE "LegalCopyright", "(C) 2009 NLnet Labs. Source is BSD licensed." + END + END + BLOCK "VarFileInfo" + BEGIN + /* English(409), windows ANSI codepage (1252) */ + VALUE "Translation", 0x409, 0x1252 + END +END + +/* error message formats */ +LANGUAGE 0x9,0x1 +/* id=1 type=RT_MESSAGETABLE */ +1 11 "winrc/gen_msg.bin" diff --git a/external/unbound/winrc/rsrc_unbound_anchor.rc b/external/unbound/winrc/rsrc_unbound_anchor.rc new file mode 100644 index 000000000..76b96b785 --- /dev/null +++ b/external/unbound/winrc/rsrc_unbound_anchor.rc @@ -0,0 +1,37 @@ +/* + Unbound 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", "Unbound Anchor Utility" + VALUE "FileVersion", PACKAGE_VERSION + VALUE "InternalName", "unbound-anchor" + VALUE "OriginalFilename", "unbound-anchor.exe" + VALUE "ProductName", "unbound" + VALUE "ProductVersion", PACKAGE_VERSION + VALUE "LegalCopyright", "(C) 2010 NLnet Labs. Source is BSD licensed." + END + END + BLOCK "VarFileInfo" + BEGIN + /* English(409), windows ANSI codepage (1252) */ + VALUE "Translation", 0x409, 0x1252 + END +END diff --git a/external/unbound/winrc/rsrc_unbound_checkconf.rc b/external/unbound/winrc/rsrc_unbound_checkconf.rc new file mode 100644 index 000000000..de61900bf --- /dev/null +++ b/external/unbound/winrc/rsrc_unbound_checkconf.rc @@ -0,0 +1,37 @@ +/* + Unbound 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", "Unbound Configuration Checker" + VALUE "FileVersion", PACKAGE_VERSION + VALUE "InternalName", "unbound-checkconf" + VALUE "OriginalFilename", "unbound-checkconf.exe" + VALUE "ProductName", "unbound" + VALUE "ProductVersion", PACKAGE_VERSION + VALUE "LegalCopyright", "(C) 2009 NLnet Labs. Source is BSD licensed." + END + END + BLOCK "VarFileInfo" + BEGIN + /* English(409), windows ANSI codepage (1252) */ + VALUE "Translation", 0x409, 0x1252 + END +END diff --git a/external/unbound/winrc/rsrc_unbound_control.rc b/external/unbound/winrc/rsrc_unbound_control.rc new file mode 100644 index 000000000..f9e1245db --- /dev/null +++ b/external/unbound/winrc/rsrc_unbound_control.rc @@ -0,0 +1,37 @@ +/* + Unbound 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", "Unbound Remote Control Tool" + VALUE "FileVersion", PACKAGE_VERSION + VALUE "InternalName", "unbound-control" + VALUE "OriginalFilename", "unbound-control.exe" + VALUE "ProductName", "unbound" + VALUE "ProductVersion", PACKAGE_VERSION + VALUE "LegalCopyright", "(C) 2009 NLnet Labs. Source is BSD licensed." + END + END + BLOCK "VarFileInfo" + BEGIN + /* English(409), windows ANSI codepage (1252) */ + VALUE "Translation", 0x409, 0x1252 + END +END diff --git a/external/unbound/winrc/rsrc_unbound_host.rc b/external/unbound/winrc/rsrc_unbound_host.rc new file mode 100644 index 000000000..d00f95cf4 --- /dev/null +++ b/external/unbound/winrc/rsrc_unbound_host.rc @@ -0,0 +1,37 @@ +/* + Unbound 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", "Unbound Lookup Utility" + VALUE "FileVersion", PACKAGE_VERSION + VALUE "InternalName", "unbound-host" + VALUE "OriginalFilename", "unbound-host.exe" + VALUE "ProductName", "unbound" + VALUE "ProductVersion", PACKAGE_VERSION + VALUE "LegalCopyright", "(C) 2009 NLnet Labs. Source is BSD licensed." + END + END + BLOCK "VarFileInfo" + BEGIN + /* English(409), windows ANSI codepage (1252) */ + VALUE "Translation", 0x409, 0x1252 + END +END diff --git a/external/unbound/winrc/service.conf b/external/unbound/winrc/service.conf new file mode 100644 index 000000000..e0118a63a --- /dev/null +++ b/external/unbound/winrc/service.conf @@ -0,0 +1,13 @@ +# Unbound configuration file on windows. +# See example.conf for more settings and syntax +server: + # verbosity level 0-4 of logging + verbosity: 0 + + # if you want to log to a file use + #logfile: "C:\unbound.log" + + # on Windows, this setting makes reports go into the Application log + # found in ControlPanels - System tasks - Logs + #use-syslog: yes + diff --git a/external/unbound/winrc/setup.nsi b/external/unbound/winrc/setup.nsi new file mode 100644 index 000000000..cd9fc76df --- /dev/null +++ b/external/unbound/winrc/setup.nsi @@ -0,0 +1,228 @@ +# The NSIS (http://nsis.sourceforge.net) install script. +# This script is BSD licensed. +SetCompressor /solid /final lzma + +!include LogicLib.nsh +!include MUI2.nsh + +!define VERSION "0.0.0" +!define QUADVERSION "0.0.0.0" + +outFile "unbound_setup_${VERSION}.exe" +Name "Unbound" + +# default install directory +installDir "$PROGRAMFILES\Unbound" +installDirRegKey HKLM "Software\Unbound" "InstallLocation" +RequestExecutionLevel admin +#give credits to Nullsoft: BrandingText "" +VIAddVersionKey "ProductName" "Unbound" +VIAddVersionKey "CompanyName" "NLnet Labs" +VIAddVersionKey "FileDescription" "(un)install the unbound DNS resolver" +VIAddVersionKey "LegalCopyright" "Copyright 2009, NLnet Labs" +VIAddVersionKey "FileVersion" "${QUADVERSION}" +VIAddVersionKey "ProductVersion" "${QUADVERSION}" +VIProductVersion "${QUADVERSION}" + +# 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 "${NSISDIR}\Contrib\Graphics\Icons\orange-install-nsis.ico" +!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\orange-uninstall-nsis.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\Unbound" +!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder" +!define MUI_STARTMENUPAGE_DEFAULTFOLDER "Unbound" +!insertmacro MUI_PAGE_STARTMENU UnboundStartMenu $StartMenuFolder + +!insertmacro MUI_PAGE_INSTFILES +!insertmacro MUI_PAGE_FINISH + +!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the uninstallation of Unbound.$\r$\n$\r$\nClick Next to continue." +!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 "Unbound" SectionUnbound + SectionIn RO # cannot unselect this one + # real work in postinstall +sectionEnd + +section "Root anchor - DNSSEC" SectionRootKey + # add estimated size for key (Kb) + AddSize 2 +sectionEnd + +# the /o means it is not selected by default. +section /o "DLV - dlv.isc.org" SectionDLV + # add estimated size for key (Kb) + AddSize 2 + SetOutPath $INSTDIR + + # libgcc exception lib used by NSISdl plugin (in crosscompile). + File /nonfatal "/oname=$PLUGINSDIR\libgcc_s_sjlj-1.dll" "/usr/i686-w64-mingw32/sys-root/mingw/bin/libgcc_s_sjlj-1.dll" + + NSISdl::download "http://ftp.isc.org/www/dlv/dlv.isc.org.key" "$INSTDIR\dlv.isc.org.key" + Pop $R0 # result from Inetc::get + ${If} $R0 != "success" + MessageBox MB_OK|MB_ICONEXCLAMATION "Download error (ftp.isc.org: $R0), click OK to abort installation" /SD IDOK + SetOutPath "C:\" + RMDir "$INSTDIR" # doesnt work directory in use by us ... + Abort + ${EndIf} +sectionEnd + +section "-hidden.postinstall" + # copy files + setOutPath $INSTDIR + File "..\LICENSE" + File "README.txt" + File "..\unbound.exe" + File "..\unbound-checkconf.exe" + File "..\unbound-control.exe" + File "..\unbound-host.exe" + File "..\unbound-anchor.exe" + File "..\unbound-service-install.exe" + File "..\unbound-service-remove.exe" + File "..\anchor-update.exe" + File "unbound-control-setup.cmd" + File "unbound-website.url" + File "service.conf" + File "..\doc\example.conf" + + # Store Root Key choice + SectionGetFlags ${SectionRootKey} $R0 + IntOp $R0 $R0 & ${SF_SELECTED} + ${If} $R0 == ${SF_SELECTED} + ClearErrors + FileOpen $R1 "$INSTDIR\service.conf" a + IfErrors done_rk + FileSeek $R1 0 END + FileWrite $R1 "$\nserver: auto-trust-anchor-file: $\"$INSTDIR\root.key$\"$\n" + FileClose $R1 + done_rk: + WriteRegStr HKLM "Software\Unbound" "RootAnchor" "$\"$INSTDIR\unbound-anchor.exe$\" -a $\"$INSTDIR\root.key$\" -c $\"$INSTDIR\icannbundle.pem$\"" + ${Else} + WriteRegStr HKLM "Software\Unbound" "RootAnchor" "" + ${EndIf} + + # Store DLV choice + SectionGetFlags ${SectionDLV} $R0 + IntOp $R0 $R0 & ${SF_SELECTED} + ${If} $R0 == ${SF_SELECTED} + ClearErrors + FileOpen $R1 "$INSTDIR\service.conf" a + IfErrors done_dlv + FileSeek $R1 0 END + FileWrite $R1 "$\nserver: dlv-anchor-file: $\"$INSTDIR\dlv.isc.org.key$\"$\n" + FileClose $R1 + done_dlv: + WriteRegStr HKLM "Software\Unbound" "CronAction" "$\"$INSTDIR\anchor-update.exe$\" dlv.isc.org $\"$INSTDIR\dlv.isc.org.key$\"" + ${Else} + WriteRegStr HKLM "Software\Unbound" "CronAction" "" + ${EndIf} + + # store installation folder + WriteRegStr HKLM "Software\Unbound" "InstallLocation" "$INSTDIR" + WriteRegStr HKLM "Software\Unbound" "ConfigFile" "$INSTDIR\service.conf" + WriteRegDWORD HKLM "Software\Unbound" "CronTime" 86400 + + # uninstaller + WriteUninstaller "uninst.exe" + + # register uninstaller + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Unbound" "DisplayName" "Unbound" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Unbound" "UninstallString" "$\"$INSTDIR\uninst.exe$\"" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Unbound" "QuietUninstallString" "$\"$INSTDIR\uninst.exe$\" /S" + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Unbound" "NoModify" "1" + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Unbound" "NoRepair" "1" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Unbound" "URLInfoAbout" "http://unbound.net" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Unbound" "Publisher" "NLnet Labs" + + # start menu items + !insertmacro MUI_STARTMENU_WRITE_BEGIN UnboundStartMenu + CreateDirectory "$SMPROGRAMS\$StartMenuFolder" + CreateShortCut "$SMPROGRAMS\$StartMenuFolder\unbound.net website.lnk" "$INSTDIR\unbound-website.url" "" "$INSTDIR\unbound.exe" "" "" "" "Visit the unbound website" + CreateShortCut "$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk" "$INSTDIR\uninst.exe" "" "" "" "" "" "Uninstall unbound" + !insertmacro MUI_STARTMENU_WRITE_END + + # install service entry + nsExec::ExecToLog '"$INSTDIR\unbound-service-install.exe"' + # start unbound service + nsExec::ExecToLog '"$INSTDIR\unbound-service-install.exe" start' +sectionEnd + +# set section descriptions +LangString DESC_unbound ${LANG_ENGLISH} "The base unbound DNS(SEC) validating caching resolver. $\r$\n$\r$\nStarted at boot from the Services control panel, logs to the Application Log, and the config file is its Program Files folder." +LangString DESC_rootkey ${LANG_ENGLISH} "Set up to use the DNSSEC root trust anchor. It is automatically updated. $\r$\n$\r$\nThis provides the main key that is used for security verification." +LangString DESC_dlv ${LANG_ENGLISH} "Set up to use DLV with dlv.isc.org. Downloads the key during install. $\r$\n$\r$\nIt fetches additional public keys that are used for security verification by querying the isc.org server with names encountered." + +!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN + !insertmacro MUI_DESCRIPTION_TEXT ${SectionUnbound} $(DESC_unbound) + !insertmacro MUI_DESCRIPTION_TEXT ${SectionRootKey} $(DESC_rootkey) + !insertmacro MUI_DESCRIPTION_TEXT ${SectionDLV} $(DESC_dlv) +!insertmacro MUI_FUNCTION_DESCRIPTION_END + +# setup macros for uninstall functions. +!ifdef UN +!undef UN +!endif +!define UN "un." + +# uninstaller section +section "un.Unbound" + # stop unbound service + nsExec::ExecToLog '"$INSTDIR\unbound-service-remove.exe" stop' + # uninstall service entry + nsExec::ExecToLog '"$INSTDIR\unbound-service-remove.exe"' + # deregister uninstall + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Unbound" + Delete "$INSTDIR\uninst.exe" # delete self + Delete "$INSTDIR\LICENSE" + Delete "$INSTDIR\README.txt" + Delete "$INSTDIR\unbound.exe" + Delete "$INSTDIR\unbound-checkconf.exe" + Delete "$INSTDIR\unbound-control.exe" + Delete "$INSTDIR\unbound-host.exe" + Delete "$INSTDIR\unbound-anchor.exe" + Delete "$INSTDIR\unbound-service-install.exe" + Delete "$INSTDIR\unbound-service-remove.exe" + Delete "$INSTDIR\anchor-update.exe" + Delete "$INSTDIR\unbound-control-setup.cmd" + Delete "$INSTDIR\unbound-website.url" + Delete "$INSTDIR\service.conf" + Delete "$INSTDIR\example.conf" + Delete "$INSTDIR\dlv.isc.org.key" + Delete "$INSTDIR\root.key" + RMDir "$INSTDIR" + + # start menu items + !insertmacro MUI_STARTMENU_GETFOLDER UnboundStartMenu $StartMenuFolder + Delete "$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk" + Delete "$SMPROGRAMS\$StartMenuFolder\unbound.net website.lnk" + RMDir "$SMPROGRAMS\$StartMenuFolder" + + DeleteRegKey HKLM "Software\Unbound" +sectionEnd diff --git a/external/unbound/winrc/setup_left.bmp b/external/unbound/winrc/setup_left.bmp Binary files differnew file mode 100644 index 000000000..ddc17d079 --- /dev/null +++ b/external/unbound/winrc/setup_left.bmp diff --git a/external/unbound/winrc/setup_top.bmp b/external/unbound/winrc/setup_top.bmp Binary files differnew file mode 100644 index 000000000..79998ec64 --- /dev/null +++ b/external/unbound/winrc/setup_top.bmp diff --git a/external/unbound/winrc/unbound-control-setup.cmd b/external/unbound/winrc/unbound-control-setup.cmd new file mode 100644 index 000000000..13617927a --- /dev/null +++ b/external/unbound/winrc/unbound-control-setup.cmd @@ -0,0 +1,164 @@ +@Echo off +rem +rem unbound-control-setup.cmd - set up SSL certificates for unbound-control +rem +rem Copyright (c) 2008, NLnet Labs. All rights reserved. +rem Modified for Windows by Y.Voinov (c) 2014 +rem +rem This software is open source. +rem +rem Redistribution and use in source and binary forms, with or without +rem modification, are permitted provided that the following conditions +rem are met: +rem +rem Redistributions of source code must retain the above copyright notice, +rem this list of conditions and the following disclaimer. +rem +rem Redistributions in binary form must reproduce the above copyright notice, +rem this list of conditions and the following disclaimer in the documentation +rem and/or other materials provided with the distribution. +rem +rem Neither the name of the NLNET LABS nor the names of its contributors may +rem be used to endorse or promote products derived from this software without +rem specific prior written permission. +rem +rem THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +rem "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +rem LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +rem A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +rem HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +rem SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +rem TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +rem PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +rem LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +rem NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +rem SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +rem settings: + +rem directory for files +set prefix="C:\Program Files (x86)" +set DESTDIR=%prefix%\Unbound + +rem issuer and subject name for certificates +set SERVERNAME=unbound +set CLIENTNAME=unbound-control + +rem validity period for certificates +set DAYS=7200 + +rem size of keys in bits +set BITS=1536 + +rem hash algorithm +set HASH=sha256 + +rem base name for unbound server keys +set SVR_BASE=unbound_server + +rem base name for unbound-control keys +set CTL_BASE=unbound_control + +rem end of options + +rem Check OpenSSL installed +for /f "delims=" %%a in ('where openssl') do @set SSL_PROGRAM=%%a +if /I "%SSL_PROGRAM%"=="" echo SSL not found. If installed, add path to PATH environment variable. & exit 1 +echo SSL found: %SSL_PROGRAM% + +set arg=%1 +if /I "%arg%" == "-h" goto help +if /I "%arg%"=="-d" set DESTDIR=%2 + +rem go!: +echo setup in directory %DESTDIR% +cd %$DESTDIR% + +rem create certificate keys; do not recreate if they already exist. +if exist $SVR_BASE.key ( +echo %SVR_BASE%.key exists +goto next +) +echo generating %SVR_BASE%.key +"%SSL_PROGRAM%" genrsa -out %SVR_BASE%.key %BITS% || echo could not genrsa && exit 1 + +:next +if exist %CTL_BASE%.key ( +echo %CTL_BASE%.key exists +goto next2 +) +echo generating %CTL_BASE%.key +"%SSL_PROGRAM%" genrsa -out %CTL_BASE%.key %BITS% || echo could not genrsa && exit 1 + +:next2 +rem create self-signed cert for server +if exist request.cfg (del /F /Q /S request.cfg) +echo [req]>>request.cfg +echo default_bits=%BITS%>>request.cfg +echo default_md=%HASH%>>request.cfg +echo prompt=no>>request.cfg +echo distinguished_name=req_distinguished_name>>request.cfg +echo.>>request.cfg +echo [req_distinguished_name]>>request.cfg +echo commonName=%SERVERNAME%>>request.cfg + +if not exist request.cfg ( +echo could not create request.cfg +exit 1 +) + +echo create %SVR_BASE%.pem (self signed certificate) +"%SSL_PROGRAM%" req -key %SVR_BASE%.key -config request.cfg -new -x509 -days %DAYS% -out %SVR_BASE%.pem || echo could not create %SVR_BASE%.pem && exit 1 +rem create trusted usage pem +"%SSL_PROGRAM%" x509 -in %SVR_BASE%.pem -addtrust serverAuth -out %SVR_BASE%_trust.pem + +rem create client request and sign it +if exist request.cfg (del /F /Q /S request.cfg) +echo [req]>>request.cfg +echo default_bits=%BITS%>>request.cfg +echo default_md=%HASH%>>request.cfg +echo prompt=no>>request.cfg +echo distinguished_name=req_distinguished_name>>request.cfg +echo.>>request.cfg +echo [req_distinguished_name]>>request.cfg +echo commonName=%CLIENTNAME%>>request.cfg + +if not exist request.cfg ( +echo could not create request.cfg +exit 1 +) + +echo create %CTL_BASE%.pem (signed client certificate) +"%SSL_PROGRAM%" req -key %CTL_BASE%.key -config request.cfg -new | "%SSL_PROGRAM%" x509 -req -days %DAYS% -CA %SVR_BASE%_trust.pem -CAkey %SVR_BASE%.key -CAcreateserial -%HASH% -out %CTL_BASE%.pem + +if not exist %CTL_BASE%.pem ( +echo could not create %CTL_BASE%.pem +exit 1 +) +rem create trusted usage pem +rem "%SSL_PROGRAM%" x509 -in %CTL_BASE%.pem -addtrust clientAuth -out %CTL_BASE%_trust.pem + +rem see details with "%SSL_PROGRAM%" x509 -noout -text < %SVR_BASE%.pem +rem echo "create %CTL_BASE%_browser.pfx (web client certificate)" +rem echo "create webbrowser PKCSrem12 .PFX certificate file. In Firefox import in:" +rem echo "preferences - advanced - encryption - view certificates - your certs" +rem echo "empty password is used, simply click OK on the password dialog box." +rem "%SSL_PROGRAM%" pkcs12 -export -in %CTL_BASE%_trust.pem -inkey %CTL_BASE%.key -name "unbound remote control client cert" -out %CTL_BASE%_browser.pfx -password "pass:" || echo could not create browser certificate && exit 1 + +rem remove crap +del /F /Q /S request.cfg +del /F /Q /S %CTL_BASE%_trust.pem +del /F /Q /S %SVR_BASE%_trust.pem +del /F /Q /S %SVR_BASE%_trust.srl + +echo Setup success. Certificates created. Enable in unbound.conf file to use + +exit 0 + +:help +echo unbound-control-setup.cmd - setup SSL keys for unbound-control +echo -d dir use directory to store keys and certificates. +echo default: %DESTDIR% +echo please run this command using the same user id that the +echo unbound daemon uses, it needs read privileges. +exit 1 diff --git a/external/unbound/winrc/unbound-service-install.c b/external/unbound/winrc/unbound-service-install.c new file mode 100644 index 000000000..a6ce11a2a --- /dev/null +++ b/external/unbound/winrc/unbound-service-install.c @@ -0,0 +1,65 @@ +/* + * winrc/unbound-service-install.c - windows services installation util + * + * 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/w_inst.h" + +/** Install service main */ +int main(int argc, char** argv) +{ + FILE* out = stdout; + /* out = fopen("unbound-service-install.log", "w");*/ + if(argc == 2 && strcmp(argv[1], "start")==0) { + wsvc_rc_start(out); + return 0; + } + if(argc != 1) { + if(out) fprintf(out, "Usage: %s [start]\n", argv[0]); + else printf("Usage: %s [start]\n", argv[0]); + return 1; + } + wsvc_install(out, "unbound-service-install.exe"); + return 0; +} diff --git a/external/unbound/winrc/unbound-service-remove.c b/external/unbound/winrc/unbound-service-remove.c new file mode 100644 index 000000000..2a285b09a --- /dev/null +++ b/external/unbound/winrc/unbound-service-remove.c @@ -0,0 +1,65 @@ +/* + * winrc/unbound-service-remove.c - windows services installation util + * + * 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/w_inst.h" + +/** Remove service main */ +int main(int argc, char** argv) +{ + FILE* out = stdout; + /* out = fopen("unbound-service-remove.log", "w");*/ + if(argc == 2 && strcmp(argv[1], "stop")==0) { + wsvc_rc_stop(out); + return 0; + } + if(argc != 1) { + if(out) fprintf(out, "Usage: %s [stop]\n", argv[0]); + else printf("Usage: %s [stop]\n", argv[0]); + return 1; + } + wsvc_remove(NULL); + return 0; +} diff --git a/external/unbound/winrc/unbound-website.url b/external/unbound/winrc/unbound-website.url new file mode 100644 index 000000000..ef4685a73 --- /dev/null +++ b/external/unbound/winrc/unbound-website.url @@ -0,0 +1,3 @@ +[InternetShortcut]
+URL=http://unbound.net/
+
diff --git a/external/unbound/winrc/unbound16.ico b/external/unbound/winrc/unbound16.ico Binary files differnew file mode 100644 index 000000000..e62634b70 --- /dev/null +++ b/external/unbound/winrc/unbound16.ico diff --git a/external/unbound/winrc/unbound32.ico b/external/unbound/winrc/unbound32.ico Binary files differnew file mode 100644 index 000000000..64272eed4 --- /dev/null +++ b/external/unbound/winrc/unbound32.ico diff --git a/external/unbound/winrc/unbound48.ico b/external/unbound/winrc/unbound48.ico Binary files differnew file mode 100644 index 000000000..074d12ebc --- /dev/null +++ b/external/unbound/winrc/unbound48.ico diff --git a/external/unbound/winrc/unbound64.ico b/external/unbound/winrc/unbound64.ico Binary files differnew file mode 100644 index 000000000..c02f68f0a --- /dev/null +++ b/external/unbound/winrc/unbound64.ico diff --git a/external/unbound/winrc/unbound64.png b/external/unbound/winrc/unbound64.png Binary files differnew file mode 100644 index 000000000..b37bf3f11 --- /dev/null +++ b/external/unbound/winrc/unbound64.png diff --git a/external/unbound/winrc/vista_admin.manifest b/external/unbound/winrc/vista_admin.manifest new file mode 100644 index 000000000..560801440 --- /dev/null +++ b/external/unbound/winrc/vista_admin.manifest @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <assemblyIdentity version="1.0.0.0" + processorArchitecture="X86" name="unbound-service-install.exe" type="win32"/> + <description>Installs or removes the unbound service in the services control panel</description> + <!-- Identify the application security requirements. --> + <ms_asmv2:trustInfo xmlns:ms_asmv2="urn:schemas-microsoft-com:asm.v2"> + <ms_asmv2:security> + <ms_asmv2:requestedPrivileges> + <ms_asmv2:requestedExecutionLevel + level="requireAdministrator" + uiAccess="false"/> + </ms_asmv2:requestedPrivileges> + </ms_asmv2:security> + </ms_asmv2:trustInfo> +</assembly> diff --git a/external/unbound/winrc/vista_user.manifest b/external/unbound/winrc/vista_user.manifest new file mode 100644 index 000000000..24f5164aa --- /dev/null +++ b/external/unbound/winrc/vista_user.manifest @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <assemblyIdentity version="1.0.0.0" + processorArchitecture="X86" name="anchor-update.exe" type="win32"/> + <description>Retrieve latest version of trust anchor</description> + <!-- Identify the application security requirements. --> + <ms_asmv2:trustInfo xmlns:ms_asmv2="urn:schemas-microsoft-com:asm.v2"> + <ms_asmv2:security> + <ms_asmv2:requestedPrivileges> + <ms_asmv2:requestedExecutionLevel + level="asInvoker" + uiAccess="false"/> + </ms_asmv2:requestedPrivileges> + </ms_asmv2:security> + </ms_asmv2:trustInfo> +</assembly> diff --git a/external/unbound/winrc/w_inst.c b/external/unbound/winrc/w_inst.c new file mode 100644 index 000000000..d0de73b5b --- /dev/null +++ b/external/unbound/winrc/w_inst.c @@ -0,0 +1,321 @@ +/* + * 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[2*MAX_PATH+4+256]; + TCHAR path_config[2*MAX_PATH+4+256]; + if(out) fprintf(out, "installing unbound service\n"); + 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, "unbound.exe"); + memmove(path_config+1, path+1, sizeof(path)-1); + change(out, path_config+1, sizeof(path_config)-1, + "unbound.exe", "service.conf"); + } + + 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)); + + /* if we started in a different directory, also read config from it. */ + if(rename) { + quote_it(out, path_config, sizeof(path_config)); + strcat(path, " -c "); + strcat(path, path_config); + } + + strcat(path, " -w service"); + scm = OpenSCManager(NULL, NULL, (int)SC_MANAGER_CREATE_SERVICE); + if(!scm) fatal_win(out, "could not OpenSCManager"); + sv = CreateService( + scm, + SERVICE_NAME, /* name of service */ + "Unbound DNS validator", /* 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 */ + NULL, /* no deps */ + NULL, /* on LocalSystem */ + NULL /* no password */ + ); + if(!sv) { + CloseServiceHandle(scm); + fatal_win(out, "could not CreateService"); + } + CloseServiceHandle(sv); + CloseServiceHandle(scm); + if(out) fprintf(out, "unbound service installed\n"); +} + + +/* Remove installed service from servicecontrolmanager */ +void +wsvc_remove(FILE* out) +{ + SC_HANDLE scm; + SC_HANDLE sv; + if(out) fprintf(out, "removing unbound service\n"); + 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, "unbound service removed\n"); +} + + +/* Start daemon */ +void +wsvc_rc_start(FILE* out) +{ + SC_HANDLE scm; + SC_HANDLE sv; + if(out) fprintf(out, "start unbound service\n"); + 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, "unbound service started\n"); +} + + +/* Stop daemon */ +void +wsvc_rc_stop(FILE* out) +{ + SC_HANDLE scm; + SC_HANDLE sv; + SERVICE_STATUS st; + if(out) fprintf(out, "stop unbound service\n"); + 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, "unbound service stopped\n"); +} diff --git a/external/unbound/winrc/w_inst.h b/external/unbound/winrc/w_inst.h new file mode 100644 index 000000000..cc06c5a3f --- /dev/null +++ b/external/unbound/winrc/w_inst.h @@ -0,0 +1,80 @@ +/* + * 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 unbound.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); + +/** + * 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 */ diff --git a/external/unbound/winrc/win_svc.c b/external/unbound/winrc/win_svc.c new file mode 100644 index 000000000..57a160d6a --- /dev/null +++ b/external/unbound/winrc/win_svc.c @@ -0,0 +1,620 @@ +/* + * winrc/win_svc.c - windows services API implementation for unbound + * + * 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 "daemon/daemon.h" +#include "daemon/worker.h" +#include "daemon/remote.h" +#include "util/config_file.h" +#include "util/netevent.h" +#include "util/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 ub_thread_t 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. + */ +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) { + 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; +} + +/** wait for unbound-anchor process to finish */ +static void +waitforubanchor(PROCESS_INFORMATION* pinfo) +{ + /* we have 5 seconds scheduled for it, usually it will be very fast, + * with only a UDP message or two (100 msec or so), but the https + * connections could take some time */ + DWORD count = 7900; + DWORD ret = WAIT_TIMEOUT; + /* decrease timer every 1/10 second, we are still starting up */ + while(ret == WAIT_TIMEOUT) { + ret = WaitForSingleObject(pinfo->hProcess, 100); + if(count > 4000) count -= 100; + else count--; /* go slow, it is taking long */ + if(count > 3000) + report_status(SERVICE_START_PENDING, NO_ERROR, count); + } + verbose(VERB_ALGO, "unbound-anchor done"); + if(ret != WAIT_OBJECT_0) { + return; /* did not end successfully */ + } + if(!GetExitCodeProcess(pinfo->hProcess, &ret)) { + log_err("GetExitCodeProcess failed"); + return; + } + verbose(VERB_ALGO, "unbound-anchor exit code is %d", (int)ret); + if(ret != 0) { + log_info("The root trust anchor has been updated."); + } +} + + +/** + * Perform root anchor update if so configured, by calling that process + */ +static void +call_root_update(void) +{ + char* rootanchor; + rootanchor = lookup_reg_str("Software\\Unbound", "RootAnchor"); + if(rootanchor && strlen(rootanchor)>0) { + STARTUPINFO sinfo; + PROCESS_INFORMATION pinfo; + memset(&pinfo, 0, sizeof(pinfo)); + memset(&sinfo, 0, sizeof(sinfo)); + sinfo.cb = sizeof(sinfo); + verbose(VERB_ALGO, "rootanchor: %s", rootanchor); + report_status(SERVICE_START_PENDING, NO_ERROR, 8000); + if(!CreateProcess(NULL, rootanchor, NULL, NULL, 0, + CREATE_NO_WINDOW, NULL, NULL, &sinfo, &pinfo)) + log_err("CreateProcess error for unbound-anchor.exe"); + else { + waitforubanchor(&pinfo); + CloseHandle(pinfo.hProcess); + CloseHandle(pinfo.hThread); + } + } + free(rootanchor); +} + +/** + * 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(int r, struct daemon** d, struct config_file** c) +{ + struct config_file* cfg = NULL; + struct daemon* daemon = NULL; + + if(!service_cfgfile) { + char* newf = lookup_reg_str("Software\\Unbound", "ConfigFile"); + if(newf) service_cfgfile = newf; + else service_cfgfile = strdup(CONFIGFILE); + if(!service_cfgfile) fatal_exit("out of memory"); + } + + /* create daemon */ + if(r) daemon = *d; + else daemon = daemon_init(); + if(!daemon) return 0; + if(!r) report_status(SERVICE_START_PENDING, NO_ERROR, 2800); + + /* read config */ + cfg = config_create(); + if(!cfg) return 0; + if(!config_read(cfg, service_cfgfile, daemon->chroot)) { + if(errno != ENOENT) { + log_err("error in config file"); + return 0; + } + log_warn("could not open config file, using defaults"); + } + if(!r) report_status(SERVICE_START_PENDING, NO_ERROR, 2600); + + verbose(VERB_QUERY, "winservice - apply settings"); + /* apply settings and init */ + verbosity = cfg->verbosity + service_cmdline_verbose; + if(cfg->directory && cfg->directory[0]) { + if(chdir(cfg->directory)) { + log_err("could not chdir to %s: %s", + cfg->directory, strerror(errno)); + if(errno != ENOENT) + return 0; + log_warn("could not change directory - continuing"); + } else + verbose(VERB_QUERY, "chdir to %s", cfg->directory); + } + log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir); + if(!r) report_status(SERVICE_START_PENDING, NO_ERROR, 2400); + verbose(VERB_QUERY, "winservice - apply cfg"); + daemon_apply_cfg(daemon, cfg); + + if(!r) report_status(SERVICE_START_PENDING, NO_ERROR, 2300); + if(!(daemon->rc = daemon_remote_create(cfg))) { + log_err("could not set up remote-control"); + daemon_delete(daemon); + config_delete(cfg); + return 0; + } + + /* open ports */ + /* keep reporting that we are busy starting */ + if(!r) report_status(SERVICE_START_PENDING, NO_ERROR, 2200); + verbose(VERB_QUERY, "winservice - open ports"); + if(!daemon_open_shared_ports(daemon)) return 0; + verbose(VERB_QUERY, "winservice - ports opened"); + if(!r) report_status(SERVICE_START_PENDING, NO_ERROR, 2000); + + *d = daemon; + *c = cfg; + return 1; +} + +/** + * Deinit the service + */ +static void +service_deinit(struct daemon* daemon, struct config_file* cfg) +{ + daemon_cleanup(daemon); + config_delete(cfg); + daemon_delete(daemon); +} + +#ifdef DOXYGEN +#define ATTR_UNUSED(x) x +#endif +/** + * The main function for the service. + * Called by the services API when starting unbound 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 config_file* cfg = NULL; + struct daemon* daemon = 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; + + /* see if we have root anchor update enabled */ + call_root_update(); + + /* we are now starting up */ + report_status(SERVICE_START_PENDING, NO_ERROR, 3000); + if(!service_init(0, &daemon, &cfg)) { + reportev("Could not service_init"); + report_status(SERVICE_STOPPED, NO_ERROR, 0); + return; + } + + /* event that gets signalled when we want to quit; it + * should get registered in the worker-0 waiting loop. */ + 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())); + } + + /* SetServiceStatus SERVICE_RUNNING;*/ + report_status(SERVICE_RUNNING, NO_ERROR, 0); + verbose(VERB_QUERY, "winservice - init complete"); + + /* daemon performs work */ + while(!service_stop_shutdown) { + daemon_fork(daemon); + if(!service_stop_shutdown) { + daemon_cleanup(daemon); + config_delete(cfg); cfg=NULL; + if(!service_init(1, &daemon, &cfg)) { + reportev("Could not service_init"); + report_status(SERVICE_STOPPED, NO_ERROR, 0); + return; + } + } + } + + /* exit */ + verbose(VERB_ALGO, "winservice - cleanup."); + report_status(SERVICE_STOP_PENDING, NO_ERROR, 0); + service_deinit(daemon, 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:\\unbound.log", "w")); + log_init("C:\\unbound.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, "service") == 0) + service_start(cfgfile, v, c); + else if(strcmp(wopt, "start") == 0) + wsvc_rc_start(stdout); + else if(strcmp(wopt, "stop") == 0) + wsvc_rc_stop(stdout); + else fatal_exit("unknown option: %s", wopt); + exit(0); +} + +void +worker_win_stop_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), void* arg) +{ + struct worker* worker = (struct worker*)arg; + verbose(VERB_QUERY, "caught stop signal (wsaevent)"); + worker->need_to_exit = 1; + comm_base_exit(worker->base); +} + +/** 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)) +{ + int mynum=65; + char* cronaction; + log_thread_set(&mynum); + cronaction = lookup_reg_str("Software\\Unbound", "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\\Unbound", "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) +{ + struct worker* worker = (struct worker*)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, worker); + } + /* reschedule */ + set_cron_timer(); +} + +void wsvc_setup_worker(struct worker* worker) +{ + /* if not started with -w service, do nothing */ + if(!service_stop_event) + return; + if(!winsock_register_wsaevent(comm_base_internal(worker->base), + &service_stop_ev, service_stop_event, + &worker_win_stop_cb, worker)) { + fatal_exit("could not register wsaevent"); + return; + } + if(!service_cron) { + service_cron = comm_timer_create(worker->base, + wsvc_cron_cb, worker); + if(!service_cron) + fatal_exit("could not create cron timer"); + set_cron_timer(); + } +} + +void wsvc_desetup_worker(struct worker* ATTR_UNUSED(worker)) +{ + comm_timer_delete(service_cron); + service_cron = NULL; +} diff --git a/external/unbound/winrc/win_svc.h b/external/unbound/winrc/win_svc.h new file mode 100644 index 000000000..3c7e90e75 --- /dev/null +++ b/external/unbound/winrc/win_svc.h @@ -0,0 +1,90 @@ +/* + * winrc/win_svc.h - windows services API implementation for unbound + * + * 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 worker; + +/** service name for unbound (internal to ServiceManager) */ +#define SERVICE_NAME "unbound" + +/** 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. + * @param worker: the worker + */ +void wsvc_setup_worker(struct worker* worker); + +/** + * Desetup lead worker events. + * @param worker: the worker + */ +void wsvc_desetup_worker(struct worker* worker); + +/** 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); + +#endif /* WINRC_WIN_SVC_H */ |