added unbound to external deps

This commit is contained in:
Riccardo Spagni
2014-10-05 23:44:31 +02:00
parent 732493c5cb
commit 9ef094b356
394 changed files with 199264 additions and 0 deletions

100
external/unbound/winrc/README.txt vendored Normal file
View File

@@ -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

152
external/unbound/winrc/anchor-update.c vendored Normal file
View File

@@ -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;
}

BIN
external/unbound/winrc/combined.ico vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
external/unbound/winrc/gen_msg.bin vendored Normal file

Binary file not shown.

44
external/unbound/winrc/gen_msg.mc vendored Normal file
View File

@@ -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
.

View File

@@ -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"

45
external/unbound/winrc/rsrc_svcinst.rc vendored Normal file
View File

@@ -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"

View File

@@ -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"

48
external/unbound/winrc/rsrc_unbound.rc vendored Normal file
View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

13
external/unbound/winrc/service.conf vendored Normal file
View File

@@ -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

228
external/unbound/winrc/setup.nsi vendored Normal file
View File

@@ -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

BIN
external/unbound/winrc/setup_left.bmp vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

BIN
external/unbound/winrc/setup_top.bmp vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -0,0 +1,3 @@
[InternetShortcut]
URL=http://unbound.net/

BIN
external/unbound/winrc/unbound16.ico vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 894 B

BIN
external/unbound/winrc/unbound32.ico vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
external/unbound/winrc/unbound48.ico vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

BIN
external/unbound/winrc/unbound64.ico vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
external/unbound/winrc/unbound64.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@@ -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>

View File

@@ -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>

321
external/unbound/winrc/w_inst.c vendored Normal file
View File

@@ -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");
}

80
external/unbound/winrc/w_inst.h vendored Normal file
View File

@@ -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 */

620
external/unbound/winrc/win_svc.c vendored Normal file
View File

@@ -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;
}

90
external/unbound/winrc/win_svc.h vendored Normal file
View File

@@ -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 */