vlmcsd-svn812-2015-08-30-Hotbird64

This commit is contained in:
Wind4 2015-11-29 17:30:52 +08:00
commit 1af203d2a8
133 changed files with 102338 additions and 0 deletions

563
GNUmakefile Normal file
View File

@ -0,0 +1,563 @@
################################################################################
.PHONY: clean
PROGRAM_NAME ?= vlmcsd
CLIENT_NAME ?= vlmcs
MULTI_NAME ?= vlmcsdmulti
CONFIG ?= config.h
# crypto library to use for standard algos, could save ~1-2kb ;)
# can be either 'openssl', 'polarssl' or anything other for internal impl
CRYPTO ?= internal
# use DNS_PARSER=internal if your OS doesn't supply the DNS parser routines
DNS_PARSER ?= OS
# You should supply your own version string here
VLMCSD_VERSION ?= $(shell test -d .svn && echo svn`svnversion`)
FEATURES ?= full
VERBOSE ?= NO
################################################################################
CC ?= gcc
TARGETPLATFORM := $(shell LANG=en_US.UTF-8 $(CC) -v 2>&1 | grep '^Target: ' | cut -f 2 -d ' ')
ifneq (,$(findstring darwin,$(TARGETPLATFORM)))
DARWIN := 1
UNIX := 1
endif
ifneq (,$(findstring androideabi,$(TARGETPLATFORM)))
ANDROID := 1
UNIX := 1
endif
ifneq (,$(findstring minix,$(TARGETPLATFORM)))
MINIX := 1
UNIX := 1
endif
ifneq (,$(findstring mingw,$(TARGETPLATFORM)))
MINGW := 1
WIN := 1
endif
ifneq (,$(findstring cygwin,$(TARGETPLATFORM)))
CYGWIN := 1
WIN := 1
endif
ifneq (,$(findstring freebsd,$(TARGETPLATFORM)))
FREEBSD := 1
UNIX := 1
BSD := 1
endif
ifneq (,$(findstring netbsd,$(TARGETPLATFORM)))
NETBSD := 1
UNIX := 1
BSD := 1
endif
ifneq (,$(findstring openbsd,$(TARGETPLATFORM)))
OPENBSD := 1
UNIX := 1
BSD := 1
endif
ifneq (,$(findstring solaris,$(TARGETPLATFORM)))
SOLARIS := 1
UNIX := 1
endif
ifneq (,$(findstring linux,$(TARGETPLATFORM)))
LINUX := 1
UNIX := 1
endif
ifeq ($(CYGWIN),1)
DLL_NAME ?= cygkms.dll
else ifeq ($(WIN),1)
DLL_NAME ?= libkms.dll
else ifeq ($(DARWIN),1)
DLL_NAME ?= libkms.dylib
else
DLL_NAME ?= libkms.so
endif
BASECFLAGS = -DCONFIG=\"$(CONFIG)\" -DBUILD_TIME=$(shell date '+%s') -g -Os -fno-strict-aliasing -fomit-frame-pointer -ffunction-sections -fdata-sections
BASELDFLAGS =
STRIPFLAGS =
CLIENTLDFLAGS =
SERVERLDFLAGS =
ifeq ($(NOLIBS),1)
NOLRESOLV=1
NOLPTHREAD=1
endif
ifneq ($(NO_DNS),1)
ifneq ($(ANDROID),1)
ifneq ($(NOLRESOLV),1)
ifeq ($(MINGW),1)
BASELDFLAGS += -ldnsapi
endif
ifeq ($(LINUX),1)
BASELDFLAGS += -lresolv
endif
ifeq ($(DARWIN),1)
BASELDFLAGS += -lresolv
endif
ifeq ($(CYGWIN),1)
DNS_PARSER := internal
BASELDFLAGS += -lresolv
endif
ifeq ($(OPENBSD),1)
DNS_PARSER := internal
endif
ifeq ($(SOLARIS),1)
BASELDFLAGS += -lresolv
endif
endif
endif
else
BASECFLAGS += -DNO_DNS
endif
ifneq ($(CAT),2)
BASECFLAGS += "-Wall"
endif
ifeq ($(DARWIN), 1)
STRIPFLAGS += -Wl,-S -Wl,-x
BASECFLAGS += -Wno-deprecated-declarations
else ifeq ($(shell uname), SunOS)
STRIPFLAGS += -s
ifeq ($(notdir $(LD_ALTEXEC)),gld)
BASELDFLAGS += -Wl,--gc-sections
endif
BASELDFLAGS += -lsocket
else
ifneq ($(CC),tcc)
BASELDFLAGS += -Wl,--gc-sections
endif
STRIPFLAGS += -s
endif
ifeq ($(FEATURES), embedded)
BASECFLAGS += -DNO_HELP -DNO_USER_SWITCH -DNO_BASIC_PRODUCT_LIST -DNO_CUSTOM_INTERVALS -DNO_PID_FILE -DNO_VERBOSE_LOG
else ifeq ($(FEATURES), autostart)
BASECFLAGS += -DNO_HELP
else ifeq ($(FEATURES), minimum)
BASECFLAGS += -DNO_TIMEOUT -DNO_SIGHUP -DNO_CL_PIDS -DNO_EXTENDED_PRODUCT_LIST -DNO_BASIC_PRODUCT_LIST -DNO_LOG -DNO_RANDOM_EPID -DNO_INI_FILE -DNO_INI_FILE -DNO_HELP -DNO_CUSTOM_INTERVALS -DNO_PID_FILE -DNO_USER_SWITCH -DNO_VERBOSE_LOG -DNO_LIMIT
else ifeq ($(FEATURES), most)
BASECFLAGS += -DNO_SIGHUP -DNO_PID_FILE -DNO_LIMIT
else ifeq ($(FEATURES), inetd)
BASECFLAGS += -DNO_SIGHUP -DNO_SOCKETS -DNO_PID_FILE -DNO_LIMIT
else ifeq ($(FEATURES), fixedepids)
BASECFLAGS += -DNO_SIGHUP -DNO_CL_PIDS -DNO_RANDOM_EPID -DNO_INI_FILE
endif
ifdef INI
BASECFLAGS += -DINI_FILE=\"$(INI)\"
endif
ifeq ($(THREADS), 1)
BASECFLAGS += -DUSE_THREADS
endif
ifeq ($(CHILD_HANDLER), 1)
BASECFLAGS += -DCHILD_HANDLER
endif
ifeq ($(NO_TIMEOUT), 1)
BASECFLAGS += -DNO_TIMEOUT
endif
ifdef WINDOWS
BASECFLAGS += -DEPID_WINDOWS=\"$(WINDOWS)\"
endif
ifdef OFFICE2010
BASECFLAGS += -DEPID_OFFICE2010=\"$(OFFICE2010)\"
endif
ifdef OFFICE2013
BASECFLAGS += -DEPID_OFFICE2013=\"$(OFFICE2013)\"
endif
ifdef HWID
BASECFLAGS += -DHWID=$(HWID)
endif
ifdef TERMINAL_WIDTH
BASECFLAGS += -DTERMINAL_FIXED_WIDTH=$(TERMINAL_WIDTH)
endif
ifeq ($(NOPROCFS), 1)
BASECFLAGS += -DNO_PROCFS
endif
ifeq ($(AUXV), 1)
BASECFLAGS += -DUSE_AUXV
endif
ifneq ($(ANDROID), 1)
ifneq ($(MINIX), 1)
ifneq ($(NOLPTHREAD), 1)
ifeq ($(findstring NO_LIMIT,$(CFLAGS) $(BASECFLAGS)),)
BASELDFLAGS += -lpthread
endif
ifneq ($(findstring USE_THREADS,$(BASECFLAGS)),)
BASELDFLAGS += -lpthread
endif
endif
endif
endif
$(MULTI_NAME): BASECFLAGS += -DMULTI_CALL_BINARY=1
all: $(CLIENT_NAME) $(PROGRAM_NAME)
ifdef CAT
allmulti: $(CLIENT_NAME) $(PROGRAM_NAME) $(MULTI_NAME)
endif
ifneq ($(strip $(VLMCSD_VERSION)),)
BASECFLAGS += -DVERSION=\"$(VLMCSD_VERSION),\ built\ $(shell date -u '+%Y-%m-%d %H:%M:%S' | sed -e 's/ /\\ /g')\ UTC\"
endif
ifdef CAT
BASECFLAGS += -DONE_FILE
endif
SRCS = crypto.c kms.c endian.c output.c shared_globals.c helpers.c
HEADERS = $(CONFIG) types.h rpc.h vlmcsd.h endian.h crypto.h kms.h network.h output.h shared_globals.h vlmcs.h helpers.h
DEPS = $(MULTI_SRCS:.c=.d)
VLMCSD_SRCS = vlmcsd.c $(SRCS)
VLMCSD_OBJS = $(VLMCSD_SRCS:.c=.o)
VLMCS_SRCS = vlmcs.c $(SRCS)
VLMCS_OBJS = $(VLMCS_SRCS:.c=.o)
MULTI_SRCS = vlmcsd.c vlmcs.c vlmcsdmulti.c $(SRCS)
MULTI_OBJS = $(MULTI_SRCS:.c=.o)
DLL_SRCS = libkms.c $(SRCS)
DLL_OBJS = $(DLL_SRCS:.c=.o)
PDFDOCS = vlmcs.1.pdf vlmcsd.7.pdf vlmcsd.8.pdf vlmcsdmulti.1.pdf vlmcsd.ini.5.pdf
HTMLDOCS = $(PDFDOCS:.pdf=.html)
UNIXDOCS = $(PDFDOCS:.pdf=.unix.txt)
DOSDOCS = $(PDFDOCS:.pdf=.dos.txt)
ifneq ($(NO_DNS),1)
VLMCS_SRCS += dns_srv.c
MULTI_SRCS += dns_srv.c
ifeq ($(DNS_PARSER),internal)
ifneq ($(MINGW),1)
VLMCS_SRCS += ns_parse.c ns_name.c
MULTI_SRCS += ns_parse.c ns_name.c
BASECFLAGS += "-DDNS_PARSER_INTERNAL"
endif
endif
endif
ifeq ($(MSRPC),1)
VLMCSD_SRCS += msrpc-server.c
VLMCS_SRCS += msrpc-client.c
MULTI_SRCS += msrpc-server.c msrpc-client.c
BASECFLAGS += -DUSE_MSRPC -Wno-unknown-pragmas
BASELDFLAGS += -lrpcrt4
else
SRCS += network.c rpc.c
endif
ifeq "$(WIN)" "1"
VLMCSD_SRCS += ntservice.c
MULTI_SRCS += ntservice.c
endif
ifeq ($(CRYPTO), openssl_with_aes)
BASECFLAGS += -D_CRYPTO_OPENSSL -D_USE_AES_FROM_OPENSSL
BASELDFLAGS += -lcrypto
SRCS += crypto_openssl.c
else ifeq ($(CRYPTO), openssl_with_aes_soft)
BASECFLAGS += -D_CRYPTO_OPENSSL -D_USE_AES_FROM_OPENSSL -D_OPENSSL_SOFTWARE
BASELDFLAGS += -lcrypto
SRCS += crypto_openssl.c
else ifeq ($(CRYPTO), openssl)
BASECFLAGS += -D_CRYPTO_OPENSSL
BASELDFLAGS += -lcrypto
SRCS += crypto_openssl.c
else ifeq ($(CRYPTO), polarssl)
BASECFLAGS += -D_CRYPTO_POLARSSL
BASELDFLAGS += -lpolarssl
else ifeq ($(CRYPTO), windows)
BASECFLAGS += -D_CRYPTO_WINDOWS
SRCS += crypto_windows.c
#BASELDFLAGS += -lpolarssl
else
BASECFLAGS += -D_CRYPTO_INTERNAL
SRCS += crypto_internal.c
endif
ifneq ($(STRIP),0)
BASELDFLAGS += $(STRIPFLAGS)
endif
ifeq ($(OPENSSL_HMAC),0)
BASECFLAGS += -D_OPENSSL_NO_HMAC
endif
ifeq ($(DEPENDENCIES),2)
BASECFLAGS += -MMD
endif
ifeq ($(VERBOSE),3)
COMPILER := $(shell printf "%-40s" $(notdir $(CC)))
endif
ifeq ($(CAT),2)
LDCMD := CC/LD
else
LDCMD := LD
endif
-include $(MULTI_SRCS:.c=.d)
%.o: %.c
ifeq ($(VERBOSE),1)
$(CC) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(PLATFORMFLAGS) -c $<
ifeq ($(DEPENDENCIES),1)
$(CC) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(PLATFORMFLAGS) -MM -MF $*.d $<
endif
else
@echo "$(COMPILER) CC $@ <- $<"
@$(CC) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(PLATFORMFLAGS) -c $<
ifeq ($(DEPENDENCIES),1)
@echo "$(COMPILER) DEP $*.d <- $<"
@$(CC) $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(PLATFORMFLAGS) -MM -MF $*.d $<
endif
endif
vlmcsd_all.c: $(VLMCSD_SRCS)
ifeq ($(VERBOSE),1)
cat $^ > $@
else
@echo "$(COMPILER) CAT $@ <- $^"
@cat $^ > $@
endif
vlmcs_all.c: $(VLMCS_SRCS)
ifeq ($(VERBOSE),1)
cat $^ > $@
else
@echo "$(COMPILER) CAT $@ <- $^"
@cat $^ > $@
endif
vlmcsdmulti_all.c: $(MULTI_SRCS)
ifeq ($(VERBOSE),1)
cat $^ > $@
else
@echo "$(COMPILER) CAT $@ <- $^"
@cat $^ > $@
endif
ifdef CAT
ifeq ($(CAT),2)
$(PROGRAM_NAME): vlmcsd_all.c
else
$(PROGRAM_NAME): vlmcsd_all.o
endif
else
$(PROGRAM_NAME): $(VLMCSD_OBJS)
endif
ifeq ($(VERBOSE),1)
+$(CC) -o $@ $^ $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(BASELDFLAGS) $(LDFLAGS)
else
+@echo "$(COMPILER) $(LDCMD) $@ <- $^"
+@$(CC) -o $@ $^ $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(BASELDFLAGS) $(LDFLAGS)
endif
ifdef CAT
ifeq ($(CAT),2)
$(CLIENT_NAME): vlmcs_all.c
else
$(CLIENT_NAME): vlmcs_all.o
endif
else
$(CLIENT_NAME): $(VLMCS_OBJS)
endif
ifeq ($(VERBOSE),1)
+$(CC) -o $@ $^ $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(BASELDFLAGS) $(LDFLAGS)
else
+@echo "$(COMPILER) $(LDCMD) $@ <- $^"
+@$(CC) -o $@ $^ $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(BASELDFLAGS) $(LDFLAGS)
endif
ifdef CAT
ifeq ($(CAT),2)
$(MULTI_NAME): vlmcsdmulti_all.c
else
$(MULTI_NAME): vlmcsdmulti_all.o
endif
else
$(MULTI_NAME): $(MULTI_OBJS)
endif
ifeq ($(VERBOSE),1)
+$(CC) -o $@ $^ $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(BASELDFLAGS) $(LDFLAGS)
else
+@echo "$(COMPILER) $(LDCMD) $@ <- $^"
+@$(CC) -o $@ $^ $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(BASELDFLAGS) $(LDFLAGS)
endif
$(DLL_NAME): $(DLL_SRCS)
ifeq ($(VERBOSE),1)
+$(CC) -o $@ $^ $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(BASELDFLAGS) $(LDFLAGS) -shared -DIS_LIBRARY=1 -UNO_SOCKETS -UUSE_MSRPC
else
+@echo "$(COMPILER) $(LDCMD) $@ <- $^"
+@$(CC) -o $@ $^ $(PLATFORMFLAGS) $(BASECFLAGS) $(CFLAGS) $(BASELDFLAGS) $(LDFLAGS) -shared -DIS_LIBRARY=1 -UNO_SOCKETS -UUSE_MSRPC
endif
%.pdf : %
ifeq ($(shell uname), Darwin)
groff -Tps -mandoc -c $< | pstopdf -i -o $@
else
groff -Tpdf -mandoc -c $< > $@
endif
%.html : %
groff -Thtml -mandoc -c $< > $@
%.unix.txt : %
groff -P -c -Tutf8 -mandoc -c $< | col -bx > $@
%.dos.txt : %.unix.txt
# unix2dos -n $< $@
# sed -e 's/$$/\r/' $< > $@
awk 'sub("$$", "\r")' $< > $@
pdfdocs : $(PDFDOCS)
dosdocs : $(DOSDOCS)
unixdocs : $(UNIXDOCS)
htmldocs : $(HTMLDOCS)
alldocs : $(UNIXDOCS) $(HTMLDOCS) $(PDFDOCS) $(DOSDOCS)
clean:
rm -f *.o *.d *_all.c $(PROGRAM_NAME) $(MULTI_NAME) $(DLL_NAME) $(CLIENT_NAME) $(PDFDOCS) $(DOSDOCS) $(UNIXDOCS) $(HTMLDOCS)
help:
@echo "Type:"
@echo " ${MAKE} - to build $(PROGRAM_NAME) and $(CLIENT_NAME)"
@echo " ${MAKE} clean - to remove $(PROGRAM_NAME) and $(CLIENT_NAME)"
@echo " ${MAKE} help - to see this help"
@echo " ${MAKE} pdfdocs - Create PDF versions of the documentation (Requires groff with PDF support)."
@echo " ${MAKE} htmldocs - Create HTML versions of the documentation."
@echo " ${MAKE} unixdocs - Create Unix TXT versions of the documentation."
@echo " ${MAKE} dosdocs - Create DOS/Windows TXT versions of the documentation."
@echo " ${MAKE} alldocs - Create all versions of the documentation."
@echo " ${MAKE} -j <x> - Use <x> parallel tasks (SMP support) when compiling $(PROGRAM_NAME) and $(CLIENT_NAME)"
@echo ""
@echo " ${MAKE} $(PROGRAM_NAME) - to build the server only."
@echo " ${MAKE} $(CLIENT_NAME) - to build the client only."
@echo " ${MAKE} $(MULTI_NAME) - to build $(PROGRAM_NAME) and $(CLIENT_NAME) in a single multi-call binary"
@echo " ${MAKE} $(DLL_NAME) - to build the shared library $(DLL_NAME)"
@echo ""
@echo "Options:"
@echo " CONFIG=<x> Compile <x> as instead of config.h."
@echo " INI=<x> Compile $(PROGRAM_NAME) with default ini file <x>"
@echo " PROGRAM_NAME=<x> Use <x> as output file name for the KMS server. Defaults to vlmcsd."
@echo " CLIENT_NAME=<x> Use <x> as output file name for the KMS client. Defaults to vlmcs."
@echo " MULTI_NAME=<x> Use <x> as output file name for the multi-call binary. Defaults to vlmcsdmulti."
@echo " DEPENDENCIES=1 Create dependency files."
@echo " CRYPTO=openssl Use openssl for SHA256/HMAC calculations."
@echo " CRYPTO=openssl_with_aes EXPERIMENTAL: Use openssl for SHA256/HMAC and AES calculations (hardware, e.g. AES-NI on x86)."
@echo " CRYPTO=openssl_with_aes_soft EXPERIMENTAL: Use openssl for SHA256/HMAC and AES calculations (software)."
@echo " CRYPTO=polarssl Use polarssl instead of internal crypto code for SHA256/HMAC calculations."
@echo " CRYPTO=windows Use Windows CryptoAPI instead of internal crypto code for SHA256/HMAC calculations."
@echo " CC=<x> Use compiler <x>. Supported compilers are gcc, icc, tcc and clang. Others may or may not work."
@echo " TERMINAL_WIDTH=<x> Assume a fixed terminal width of <x> columns. Use in case of problems only."
@echo " VLMCSD_VERSION=<x> Sets <x> as your version identifier. Defaults to \"private build\"."
@echo " CFLAGS=<x> Pass <x> as additional arguments to the compiler."
@echo " LDFLAGS=<x> Pass <x> as additional arguments to the linker."
@echo " PLATFORMFLAGS=<x> Pass <x> as additional arguments to the compiler and the linker."
@echo " BASECFLAGS=<x> Pass only <x> as arguments to the compiler (advanced users only)."
@echo " BASELDFLAGS=<x> Pass only <x> as arguments to the linker (advanced users only)."
@echo " STRIP=0 Don't strip debug information from $(PROGRAM_NAME) and $(CLIENT_NAME) (for developers)."
@echo " VERBOSE=1 Be verbose when making targets."
@echo " VERBOSE=3 Show name of compiler."
@echo " THREADS=1 Use threads instead of fork(). Automatically set for native Windows. Recommended for Cygwin."
@echo " WINDOWS=<x> Use <x> as the default ePID for Windows (when using $(PROGRAM_NAME) with -r 0)."
@echo " OFFICE2010=<x> Use <x> as the default ePID for Office2010 (when using $(PROGRAM_NAME) with -r 0)."
@echo " OFFICE2013=<x> Use <x> as the default ePID for Office2013 (when using $(PROGRAM_NAME) with -r 0)."
@echo " HWID=<x> Use <x> as the default HWID (when it can't be found in an ini file)."
@echo " FEATURES=full Compile $(PROGRAM_NAME) with all features (default)."
@echo " FEATURES=most Compile $(PROGRAM_NAME) without rarely used features."
@echo " FEATURES=embedded Compile $(PROGRAM_NAME) with typical features for embedded systems."
@echo " FEATURES=autostart Removes features typically not needed if you place $(PROGRAM_NAME) in an autostart script."
@echo " FEATURES=inetd Compile $(PROGRAM_NAME) for running through an internet superserver only."
@echo " FEATURES=minimum Compiles only basic features of $(PROGRAM_NAME)."
@echo " FEATURES=fixedepids $(PROGRAM_NAME) only uses bultin internal ePIDs."
@echo ""
@echo "Useful CFLAGS to save memory when running $(PROGRAM_NAME) on very small embedded devices (finer control than FEATURES=):"
@echo " -DNO_EXTENDED_PRODUCT_LIST Don't compile the detailed product list."
@echo " -DNO_BASIC_PRODUCT_LIST Don't compile the basic product list."
@echo " -DNO_VERBOSE_LOG Don't support verbose logging. Removes -v option."
@echo " -DNO_LOG Don't add support for logging. Implies -DNO_VERBOSE_LOG -DNO_EXTENDED_PRODUCT_LIST and -DNO_BASIC_PRODUCT_LIST."
@echo " -DNO_RANDOM_EPID Don't support random ePIDs."
@echo " -DNO_INI_FILE Don't support reading ePIDs/HWIDs from a file."
@echo " -DNO_PID_FILE Don't support writing a PID file. Removes -p option."
@echo " -DNO_USER_SWITCH Don't support changing uid/gid after program start. Removes -u and -g options."
@echo " -DNO_HELP Don't support command line help."
@echo " -DNO_CUSTOM_INTERVALS Don't support custom intervals for retry and refresh activation. Removes -A and -R options."
@echo " -DNO_SOCKETS Don't support standalone operation. Requires an internet superserver to start $(PROGRAM_NAME)."
@echo " -DNO_CL_PIDS Don't support specifying ePIDs and HwId from the command line in $(PROGRAM_NAME)."
@echo " -DNO_LIMIT Don't support limiting concurrent clients in $(PROGRAM_NAME)."
@echo " -DNO_SIGHUP Don't support SIGHUP handling in $(PROGRAM_NAME)."
@echo ""
@echo "Troubleshooting options"
@echo " CAT=1 Combine all sources in a single file."
@echo " CAT=2 Combine all sources in a single file and don't create a *.o file."
@echo " NOPROCFS=1 Don't rely on a properly mounted proc filesystem in /proc."
@echo " AUXV=1 Use /proc/self/auxv (requires Linux with glibc >= 2.16 or musl.)"
@echo " NOLPTHREAD=1 Disable detection if -lpthread is required (for use with Android NDK)."
@echo " NOLRESOLV=1 Disable detection if -lresolv is requires (for use with Android NDK)."
@echo " NOLIBS=1 Do not attempt to autodetect any library dependencies."
@echo " OPENSSL_HMAC=0 Compile for openssl versions that don't have HMAC support (required on some embedded devices)."
@echo " NO_TIMEOUT=1 Do not set timeouts for sockets (for systems that don't support it)."
@echo " CHILD_HANDLER=1 Install a handler for SIGCHLD (for systems that don't support SA_NOCLDWAIT)."
@echo " NO_DNS=1 Compile vlmcs without support for detecting KMS servers via DNS."
@echo " DNS_PARSER=internal Use $(CLIENT_NAME) internal DNS parsing routines. No effect on MingW (native Windows)."
@echo ""
@echo "Other useful CFLAGS:"
@echo " -DSUPPORT_WINE Add code that the Windows version of $(PROGRAM_NAME) runs on Wine if MSRPC=1"
@echo " -D_PEDANTIC Report rare error/warning conditions instead of silently ignoring them."
@echo " -DINCLUDE_BETAS Include SKU / activation IDs for obsolete beta/preview products."
@echo " -DFD_SETSIZE=<x> Allow <x> -L statements in $(PROGRAM_NAME) (default: 64 on Windows, 1024 on most Unixes)."
@echo " -flto Use link time optimization. Not supported by old compilers (gcc < 4.7). Use whenever supported."
@echo " -flto=jobserver Utilize all CPUs during link time optimization. Requires ${MAKE} -j <cpus>"
@echo " -fno-stack-protector No stack checking. Smaller binaries."
@echo " -pipe Use pipes instead of temporary files (faster compilation, extends the life of your SSD)."

14
KMSServer.idl Normal file
View File

@ -0,0 +1,14 @@
[
uuid(51C82175-844E-4750-B0D8-EC255555BC06),
version(1.0),
]
interface KMSServer
{
int RequestActivation
(
[in] int requestSize,
[in, size_is(requestSize)] unsigned char* request,
[out] int* responseSize,
[out, size_is( , *responseSize)] unsigned char** response
);
}

278
KMSServer_c_mingw_gcc.c Normal file
View File

@ -0,0 +1,278 @@
/* this ALWAYS GENERATED file contains the RPC client stubs */
/* File created by MIDL compiler version 8.00.0595 */
/* at Thu Oct 18 15:24:14 2012
*/
/* Compiler settings for KMSServer.idl:
Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.00.0595
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
DECLSPEC_UUID(), MIDL_INTERFACE()
*/
/* @@MIDL_FILE_HEADING( ) */
#if !defined(_M_IA64) && !defined(_M_AMD64) && !defined(_ARM_)
#pragma warning( disable: 4049 ) /* more than 64k source lines */
#if _MSC_VER >= 1200
#pragma warning(push)
#endif
#pragma warning( disable: 4211 ) /* redefine extern to static */
#pragma warning( disable: 4232 ) /* dllimport identity*/
#pragma warning( disable: 4024 ) /* array to pointer mapping*/
#pragma warning( disable: 4100 ) /* unreferenced arguments in x86 call */
#pragma optimize("", off )
#include <string.h>
#include "KMSServer_h.h"
#define TYPE_FORMAT_STRING_SIZE 43
#define PROC_FORMAT_STRING_SIZE 59
#define EXPR_FORMAT_STRING_SIZE 1
#define TRANSMIT_AS_TABLE_SIZE 0
#define WIRE_MARSHAL_TABLE_SIZE 0
typedef struct _KMSServer_MIDL_TYPE_FORMAT_STRING
{
short Pad;
unsigned char Format[ TYPE_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_TYPE_FORMAT_STRING;
typedef struct _KMSServer_MIDL_PROC_FORMAT_STRING
{
short Pad;
unsigned char Format[ PROC_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_PROC_FORMAT_STRING;
typedef struct _KMSServer_MIDL_EXPR_FORMAT_STRING
{
long Pad;
unsigned char Format[ EXPR_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_EXPR_FORMAT_STRING;
static const RPC_SYNTAX_IDENTIFIER _RpcTransferSyntax =
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}};
extern const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString;
extern const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString;
extern const KMSServer_MIDL_EXPR_FORMAT_STRING KMSServer__MIDL_ExprFormatString;
#define GENERIC_BINDING_TABLE_SIZE 0
/* Standard interface: KMSServer, ver. 1.0,
GUID={0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}} */
static const RPC_CLIENT_INTERFACE KMSServer___RpcClientInterface =
{
sizeof(RPC_CLIENT_INTERFACE),
{{0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}},{1,0}},
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}},
0,
0,
0,
0,
0,
0x00000000
};
RPC_IF_HANDLE KMSServer_v1_0_c_ifspec = (RPC_IF_HANDLE)& KMSServer___RpcClientInterface;
extern const MIDL_STUB_DESC KMSServer_StubDesc;
static RPC_BINDING_HANDLE KMSServer__MIDL_AutoBindHandle;
int RequestActivation(
/* [in] */ handle_t IDL_handle,
/* [in] */ int requestSize,
/* [size_is][in] */ unsigned char *request,
/* [out] */ int *responseSize,
/* [size_is][size_is][out] */ unsigned char **response)
{
CLIENT_CALL_RETURN _RetVal;
_RetVal = NdrClientCall2(
( PMIDL_STUB_DESC )&KMSServer_StubDesc,
(PFORMAT_STRING) &KMSServer__MIDL_ProcFormatString.Format[0],
( unsigned char * )&IDL_handle);
return ( int )_RetVal.Simple;
}
#if !defined(__RPC_WIN32__)
#error Invalid build platform for this stub.
#endif
#if !(TARGET_IS_NT50_OR_LATER)
#error You need Windows 2000 or later to run this stub because it uses these features:
#error /robust command line switch.
#error However, your C/C++ compilation flags indicate you intend to run this app on earlier systems.
#error This app will fail with the RPC_X_WRONG_STUB_VERSION error.
#endif
#if !MULTI_CALL_BINARY
/*static*/ const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString =
{
0,
{
/* Procedure RequestActivation */
0x0, /* 0 */
0x48, /* Old Flags: */
/* 2 */ NdrFcLong( 0x0 ), /* 0 */
/* 6 */ NdrFcShort( 0x0 ), /* 0 */
/* 8 */ NdrFcShort( 0x18 ), /* x86 Stack size/offset = 24 */
/* 10 */ 0x32, /* FC_BIND_PRIMITIVE */
0x0, /* 0 */
/* 12 */ NdrFcShort( 0x0 ), /* x86 Stack size/offset = 0 */
/* 14 */ NdrFcShort( 0x8 ), /* 8 */
/* 16 */ NdrFcShort( 0x24 ), /* 36 */
/* 18 */ 0x47, /* Oi2 Flags: srv must size, clt must size, has return, has ext, */
0x5, /* 5 */
/* 20 */ 0x8, /* 8 */
0x7, /* Ext Flags: new corr desc, clt corr check, srv corr check, */
/* 22 */ NdrFcShort( 0x1 ), /* 1 */
/* 24 */ NdrFcShort( 0x1 ), /* 1 */
/* 26 */ NdrFcShort( 0x0 ), /* 0 */
/* Parameter IDL_handle */
/* 28 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 30 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */
/* 32 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter requestSize */
/* 34 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */
/* 36 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */
/* 38 */ NdrFcShort( 0x6 ), /* Type Offset=6 */
/* Parameter request */
/* 40 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */
/* 42 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 44 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter responseSize */
/* 46 */ NdrFcShort( 0x2013 ), /* Flags: must size, must free, out, srv alloc size=8 */
/* 48 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */
/* 50 */ NdrFcShort( 0x16 ), /* Type Offset=22 */
/* Parameter response */
/* 52 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 54 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */
/* 56 */ 0x8, /* FC_LONG */
0x0, /* 0 */
0x0
}
};
/*static*/ const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString =
{
0,
{
NdrFcShort( 0x0 ), /* 0 */
/* 2 */
0x11, 0x0, /* FC_RP */
/* 4 */ NdrFcShort( 0x2 ), /* Offset= 2 (6) */
/* 6 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 8 */ NdrFcShort( 0x1 ), /* 1 */
/* 10 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x0, /* */
/* 12 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */
/* 14 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 16 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
/* 18 */
0x11, 0xc, /* FC_RP [alloced_on_stack] [simple_pointer] */
/* 20 */ 0x8, /* FC_LONG */
0x5c, /* FC_PAD */
/* 22 */
0x11, 0x14, /* FC_RP [alloced_on_stack] [pointer_deref] */
/* 24 */ NdrFcShort( 0x2 ), /* Offset= 2 (26) */
/* 26 */
0x12, 0x0, /* FC_UP */
/* 28 */ NdrFcShort( 0x2 ), /* Offset= 2 (30) */
/* 30 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 32 */ NdrFcShort( 0x1 ), /* 1 */
/* 34 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x54, /* FC_DEREFERENCE */
/* 36 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 38 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 40 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
0x0
}
};
#endif // !MULTI_CALL_BINARY
static const unsigned short KMSServer_FormatStringOffsetTable[] =
{
0
};
//typedef void *(__RPC_API midl_user_allocate_t)(size_t);
typedef void *(__RPC_API *midl_allocate_t)(size_t);
#if !MULTI_CALL_BINARY
/*static*/ const MIDL_STUB_DESC KMSServer_StubDesc =
{
(void *)& KMSServer___RpcClientInterface,
(midl_allocate_t)MIDL_user_allocate,
MIDL_user_free,
&KMSServer__MIDL_AutoBindHandle,
0,
0,
0,
0,
KMSServer__MIDL_TypeFormatString.Format,
1, /* -error bounds_check flag */
0x50002, /* Ndr library version */
0,
0x8000253, /* MIDL Version 8.0.595 */
0,
0,
0, /* notify & notify_flag routine table */
0x1, /* MIDL flag */
0, /* cs routines */
0, /* proxy/server info */
0
};
#endif // !MULTI_CALL_BINARY
#pragma optimize("", on )
#if _MSC_VER >= 1200
#pragma warning(pop)
#endif
#endif /* !defined(_M_IA64) && !defined(_M_AMD64) && !defined(_ARM_) */

731
KMSServer_c_x64_mingw_gcc.c Normal file
View File

@ -0,0 +1,731 @@
/* this ALWAYS GENERATED file contains the RPC client stubs */
/* File created by MIDL compiler version 8.00.0603 */
/* at Fri Feb 20 04:17:07 2015
* modified by Hotbird64 to work with MingW-w64 and gcc
*/
/* Compiler settings for KMSServer.idl:
Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.00.0603
protocol : all , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
DECLSPEC_UUID(), MIDL_INTERFACE()
*/
/* @@MIDL_FILE_HEADING( ) */
#if defined(_M_AMD64)
#pragma warning( disable: 4049 ) /* more than 64k source lines */
#if _MSC_VER >= 1200
#pragma warning(push)
#endif
#pragma warning( disable: 4211 ) /* redefine extern to static */
#pragma warning( disable: 4232 ) /* dllimport identity*/
#pragma warning( disable: 4024 ) /* array to pointer mapping*/
#include <string.h>
#include "KMSServer_h.h"
#define TYPE_FORMAT_STRING_SIZE 43
#define PROC_FORMAT_STRING_SIZE 61
#define EXPR_FORMAT_STRING_SIZE 1
#define TRANSMIT_AS_TABLE_SIZE 0
#define WIRE_MARSHAL_TABLE_SIZE 0
typedef struct _KMSServer_MIDL_TYPE_FORMAT_STRING
{
short Pad;
unsigned char Format[ TYPE_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_TYPE_FORMAT_STRING;
typedef struct _KMSServer_MIDL_PROC_FORMAT_STRING
{
short Pad;
unsigned char Format[ PROC_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_PROC_FORMAT_STRING;
typedef struct _KMSServer_MIDL_EXPR_FORMAT_STRING
{
long Pad;
unsigned char Format[ EXPR_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_EXPR_FORMAT_STRING;
static const RPC_SYNTAX_IDENTIFIER _RpcTransferSyntax =
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}};
static const RPC_SYNTAX_IDENTIFIER _NDR64_RpcTransferSyntax =
{{0x71710533,0xbeba,0x4937,{0x83,0x19,0xb5,0xdb,0xef,0x9c,0xcc,0x36}},{1,0}};
extern const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString;
extern const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString;
extern const KMSServer_MIDL_EXPR_FORMAT_STRING KMSServer__MIDL_ExprFormatString;
#define GENERIC_BINDING_TABLE_SIZE 0
/* Standard interface: KMSServer, ver. 1.0,
GUID={0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}} */
extern const MIDL_STUBLESS_PROXY_INFO KMSServer_ProxyInfo;
static const RPC_CLIENT_INTERFACE KMSServer___RpcClientInterface =
{
sizeof(RPC_CLIENT_INTERFACE),
{{0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}},{1,0}},
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}},
0,
0,
0,
0,
&KMSServer_ProxyInfo,
0x02000000
};
RPC_IF_HANDLE KMSServer_v1_0_c_ifspec = (RPC_IF_HANDLE)& KMSServer___RpcClientInterface;
extern const MIDL_STUB_DESC KMSServer_StubDesc;
static RPC_BINDING_HANDLE KMSServer__MIDL_AutoBindHandle;
int RequestActivation(
/* [in] */ handle_t IDL_handle,
/* [in] */ int requestSize,
/* [size_is][in] */ unsigned char *request,
/* [out] */ int *responseSize,
/* [size_is][size_is][out] */ unsigned char **response)
{
CLIENT_CALL_RETURN _RetVal;
_RetVal = NdrClientCall3(
( PMIDL_STUBLESS_PROXY_INFO )&KMSServer_ProxyInfo,
0,
0,
IDL_handle,
requestSize,
request,
responseSize,
response);
return ( int )_RetVal.Simple;
}
#if !defined(__RPC_WIN64__)
#error Invalid build platform for this stub.
#endif
#if !MULTI_CALL_BINARY
/*static*/ const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString =
{
0,
{
/* Procedure RequestActivation */
0x0, /* 0 */
0x48, /* Old Flags: */
/* 2 */ NdrFcLong( 0x0 ), /* 0 */
/* 6 */ NdrFcShort( 0x0 ), /* 0 */
/* 8 */ NdrFcShort( 0x30 ), /* X64 Stack size/offset = 48 */
/* 10 */ 0x32, /* FC_BIND_PRIMITIVE */
0x0, /* 0 */
/* 12 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
/* 14 */ NdrFcShort( 0x8 ), /* 8 */
/* 16 */ NdrFcShort( 0x24 ), /* 36 */
/* 18 */ 0x47, /* Oi2 Flags: srv must size, clt must size, has return, has ext, */
0x5, /* 5 */
/* 20 */ 0xa, /* 10 */
0x7, /* Ext Flags: new corr desc, clt corr check, srv corr check, */
/* 22 */ NdrFcShort( 0x1 ), /* 1 */
/* 24 */ NdrFcShort( 0x1 ), /* 1 */
/* 26 */ NdrFcShort( 0x0 ), /* 0 */
/* 28 */ NdrFcShort( 0x0 ), /* 0 */
/* Parameter IDL_handle */
/* 30 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 32 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
/* 34 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter requestSize */
/* 36 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */
/* 38 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */
/* 40 */ NdrFcShort( 0x6 ), /* Type Offset=6 */
/* Parameter request */
/* 42 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */
/* 44 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */
/* 46 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter responseSize */
/* 48 */ NdrFcShort( 0x2013 ), /* Flags: must size, must free, out, srv alloc size=8 */
/* 50 */ NdrFcShort( 0x20 ), /* X64 Stack size/offset = 32 */
/* 52 */ NdrFcShort( 0x16 ), /* Type Offset=22 */
/* Parameter response */
/* 54 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 56 */ NdrFcShort( 0x28 ), /* X64 Stack size/offset = 40 */
/* 58 */ 0x8, /* FC_LONG */
0x0, /* 0 */
0x0
}
};
/*static*/ const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString =
{
0,
{
NdrFcShort( 0x0 ), /* 0 */
/* 2 */
0x11, 0x0, /* FC_RP */
/* 4 */ NdrFcShort( 0x2 ), /* Offset= 2 (6) */
/* 6 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 8 */ NdrFcShort( 0x1 ), /* 1 */
/* 10 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x0, /* */
/* 12 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
/* 14 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 16 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
/* 18 */
0x11, 0xc, /* FC_RP [alloced_on_stack] [simple_pointer] */
/* 20 */ 0x8, /* FC_LONG */
0x5c, /* FC_PAD */
/* 22 */
0x11, 0x14, /* FC_RP [alloced_on_stack] [pointer_deref] */
/* 24 */ NdrFcShort( 0x2 ), /* Offset= 2 (26) */
/* 26 */
0x12, 0x0, /* FC_UP */
/* 28 */ NdrFcShort( 0x2 ), /* Offset= 2 (30) */
/* 30 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 32 */ NdrFcShort( 0x1 ), /* 1 */
/* 34 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x54, /* FC_DEREFERENCE */
/* 36 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */
/* 38 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 40 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
0x0
}
};
#endif //!MULTI_CALL_BINARY
static const unsigned short KMSServer_FormatStringOffsetTable[] =
{
0
};
#endif /* defined(_M_AMD64)*/
/* this ALWAYS GENERATED file contains the RPC client stubs */
/* File created by MIDL compiler version 8.00.0603 */
/* at Fri Feb 20 04:17:07 2015
*/
/* Compiler settings for KMSServer.idl:
Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.00.0603
protocol : all , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
DECLSPEC_UUID(), MIDL_INTERFACE()
*/
/* @@MIDL_FILE_HEADING( ) */
#if defined(_M_AMD64)
#pragma warning( disable: 4049 ) /* more than 64k source lines */
#if !defined(__RPC_WIN64__)
#error Invalid build platform for this stub.
#endif
#include "ndr64types.h"
#include "pshpack8.h"
typedef
struct
{
NDR64_FORMAT_UINT32 frag1;
struct _NDR64_EXPR_OPERATOR frag2;
struct _NDR64_EXPR_VAR frag3;
}
__midl_frag13_t;
extern const __midl_frag13_t __midl_frag13;
typedef
struct
{
struct _NDR64_CONF_ARRAY_HEADER_FORMAT frag1;
struct _NDR64_ARRAY_ELEMENT_INFO frag2;
}
__midl_frag12_t;
extern const __midl_frag12_t __midl_frag12;
typedef
struct _NDR64_POINTER_FORMAT
__midl_frag11_t;
extern const __midl_frag11_t __midl_frag11;
typedef
struct _NDR64_POINTER_FORMAT
__midl_frag10_t;
extern const __midl_frag10_t __midl_frag10;
typedef
struct _NDR64_POINTER_FORMAT
__midl_frag8_t;
extern const __midl_frag8_t __midl_frag8;
typedef
NDR64_FORMAT_CHAR
__midl_frag7_t;
extern const __midl_frag7_t __midl_frag7;
typedef
struct
{
NDR64_FORMAT_UINT32 frag1;
struct _NDR64_EXPR_VAR frag2;
}
__midl_frag6_t;
extern const __midl_frag6_t __midl_frag6;
typedef
struct
{
struct _NDR64_CONF_ARRAY_HEADER_FORMAT frag1;
struct _NDR64_ARRAY_ELEMENT_INFO frag2;
}
__midl_frag5_t;
extern const __midl_frag5_t __midl_frag5;
typedef
struct _NDR64_POINTER_FORMAT
__midl_frag4_t;
extern const __midl_frag4_t __midl_frag4;
typedef
NDR64_FORMAT_CHAR
__midl_frag3_t;
extern const __midl_frag3_t __midl_frag3;
typedef
struct
{
struct _NDR64_PROC_FORMAT frag1;
struct _NDR64_BIND_AND_NOTIFY_EXTENSION frag2;
struct _NDR64_PARAM_FORMAT frag3;
struct _NDR64_PARAM_FORMAT frag4;
struct _NDR64_PARAM_FORMAT frag5;
struct _NDR64_PARAM_FORMAT frag6;
struct _NDR64_PARAM_FORMAT frag7;
}
__midl_frag2_t;
extern const __midl_frag2_t __midl_frag2;
typedef
NDR64_FORMAT_UINT32
__midl_frag1_t;
extern const __midl_frag1_t __midl_frag1;
#if !MULTI_CALL_BINARY
/*static*/ const __midl_frag13_t __midl_frag13 =
{
/* */
(NDR64_UINT32) 1 /* 0x1 */,
{
/* struct _NDR64_EXPR_OPERATOR */
0x4, /* FC_EXPR_OPER */
0x5, /* OP_UNARY_INDIRECTION */
0x5, /* FC64_INT32 */
(NDR64_UINT8) 0 /* 0x0 */
},
{
/* struct _NDR64_EXPR_VAR */
0x3, /* FC_EXPR_VAR */
0x7, /* FC64_INT64 */
(NDR64_UINT16) 0 /* 0x0 */,
(NDR64_UINT32) 24 /* 0x18 */ /* Offset */
}
};
/*static*/ const __midl_frag12_t __midl_frag12 =
{
/* *char */
{
/* *char */
0x41, /* FC64_CONF_ARRAY */
(NDR64_UINT8) 0 /* 0x0 */,
{
/* *char */
0,
0,
0,
0,
0,
0,
0,
0
},
(NDR64_UINT8) 0 /* 0x0 */,
(NDR64_UINT32) 1 /* 0x1 */,
&__midl_frag13
},
{
/* struct _NDR64_ARRAY_ELEMENT_INFO */
(NDR64_UINT32) 1 /* 0x1 */,
&__midl_frag7
}
};
/*static*/ const __midl_frag11_t __midl_frag11 =
{
/* *char */
0x21, /* FC64_UP */
(NDR64_UINT8) 0 /* 0x0 */,
(NDR64_UINT16) 0 /* 0x0 */,
&__midl_frag12
};
/*static*/ const __midl_frag10_t __midl_frag10 =
{
/* **char */
0x20, /* FC64_RP */
(NDR64_UINT8) 20 /* 0x14 */,
(NDR64_UINT16) 0 /* 0x0 */,
&__midl_frag11
};
/*static*/ const __midl_frag8_t __midl_frag8 =
{
/* *int */
0x20, /* FC64_RP */
(NDR64_UINT8) 12 /* 0xc */,
(NDR64_UINT16) 0 /* 0x0 */,
&__midl_frag3
};
/*static*/ const __midl_frag7_t __midl_frag7 =
0x10 /* FC64_CHAR */;
/*static*/ const __midl_frag6_t __midl_frag6 =
{
/* */
(NDR64_UINT32) 1 /* 0x1 */,
{
/* struct _NDR64_EXPR_VAR */
0x3, /* FC_EXPR_VAR */
0x5, /* FC64_INT32 */
(NDR64_UINT16) 0 /* 0x0 */,
(NDR64_UINT32) 8 /* 0x8 */ /* Offset */
}
};
/*static*/ const __midl_frag5_t __midl_frag5 =
{
/* *char */
{
/* *char */
0x41, /* FC64_CONF_ARRAY */
(NDR64_UINT8) 0 /* 0x0 */,
{
/* *char */
0,
0,
0,
0,
0,
0,
0,
0
},
(NDR64_UINT8) 0 /* 0x0 */,
(NDR64_UINT32) 1 /* 0x1 */,
&__midl_frag6
},
{
/* struct _NDR64_ARRAY_ELEMENT_INFO */
(NDR64_UINT32) 1 /* 0x1 */,
&__midl_frag7
}
};
/*static*/ const __midl_frag4_t __midl_frag4 =
{
/* *char */
0x20, /* FC64_RP */
(NDR64_UINT8) 0 /* 0x0 */,
(NDR64_UINT16) 0 /* 0x0 */,
&__midl_frag5
};
/*static*/ const __midl_frag3_t __midl_frag3 =
0x5 /* FC64_INT32 */;
/*static*/ const __midl_frag2_t __midl_frag2 =
{
/* RequestActivation */
{
/* RequestActivation */ /* procedure RequestActivation */
(NDR64_UINT32) 23986240 /* 0x16e0040 */, /* explicit handle */ /* IsIntrepreted, ServerMustSize, ClientMustSize, HasReturn, ServerCorrelation, ClientCorrelation, HasExtensions */
(NDR64_UINT32) 48 /* 0x30 */ , /* Stack size */
(NDR64_UINT32) 8 /* 0x8 */,
(NDR64_UINT32) 40 /* 0x28 */,
(NDR64_UINT16) 0 /* 0x0 */,
(NDR64_UINT16) 0 /* 0x0 */,
(NDR64_UINT16) 5 /* 0x5 */,
(NDR64_UINT16) 8 /* 0x8 */
},
{
/* struct _NDR64_BIND_AND_NOTIFY_EXTENSION */
{
/* struct _NDR64_BIND_AND_NOTIFY_EXTENSION */
0x72, /* FC64_BIND_PRIMITIVE */
(NDR64_UINT8) 0 /* 0x0 */,
0 /* 0x0 */, /* Stack offset */
(NDR64_UINT8) 0 /* 0x0 */,
(NDR64_UINT8) 0 /* 0x0 */
},
(NDR64_UINT16) 0 /* 0x0 */ /* Notify index */
},
{
/* requestSize */ /* parameter requestSize */
&__midl_frag3,
{
/* requestSize */
0,
0,
0,
1,
0,
0,
1,
1,
0,
0,
0,
0,
0,
(NDR64_UINT16) 0 /* 0x0 */,
0
}, /* [in], Basetype, ByValue */
(NDR64_UINT16) 0 /* 0x0 */,
8 /* 0x8 */, /* Stack offset */
},
{
/* request */ /* parameter request */
&__midl_frag5,
{
/* request */
1,
1,
0,
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
(NDR64_UINT16) 0 /* 0x0 */,
0
}, /* MustSize, MustFree, [in], SimpleRef */
(NDR64_UINT16) 0 /* 0x0 */,
16 /* 0x10 */, /* Stack offset */
},
{
/* responseSize */ /* parameter responseSize */
&__midl_frag3,
{
/* responseSize */
0,
0,
0,
0,
1,
0,
1,
0,
1,
0,
0,
0,
0,
(NDR64_UINT16) 0 /* 0x0 */,
1
}, /* [out], Basetype, SimpleRef, UseCache */
(NDR64_UINT16) 0 /* 0x0 */,
24 /* 0x18 */, /* Stack offset */
},
{
/* response */ /* parameter response */
&__midl_frag10,
{
/* response */
1,
1,
0,
0,
1,
0,
0,
0,
0,
0,
0,
0,
0,
(NDR64_UINT16) 0 /* 0x0 */,
1
}, /* MustSize, MustFree, [out], UseCache */
(NDR64_UINT16) 0 /* 0x0 */,
32 /* 0x20 */, /* Stack offset */
},
{
/* int */ /* parameter int */
&__midl_frag3,
{
/* int */
0,
0,
0,
0,
1,
1,
1,
1,
0,
0,
0,
0,
0,
(NDR64_UINT16) 0 /* 0x0 */,
0
}, /* [out], IsReturn, Basetype, ByValue */
(NDR64_UINT16) 0 /* 0x0 */,
40 /* 0x28 */, /* Stack offset */
}
};
/*static*/ const __midl_frag1_t __midl_frag1 =
(NDR64_UINT32) 0 /* 0x0 */;
#endif // !MULTI_CALL_BINARY
#include "poppack.h"
static const FormatInfoRef KMSServer_Ndr64ProcTable[] =
{
&__midl_frag2
};
//typedef void *__RPC_USER MIDL_user_allocate_t(SIZE_T)
typedef void *(__RPC_API *midl_allocate_t)(size_t);
#if !MULTI_CALL_BINARY
/*static*/ const MIDL_STUB_DESC KMSServer_StubDesc =
{
(void *)& KMSServer___RpcClientInterface,
(midl_allocate_t)MIDL_user_allocate,
MIDL_user_free,
&KMSServer__MIDL_AutoBindHandle,
0,
0,
0,
0,
KMSServer__MIDL_TypeFormatString.Format,
1, /* -error bounds_check flag */
0x60000, /* Ndr library version */
0,
0x800025b, /* MIDL Version 8.0.603 */
0,
0,
0, /* notify & notify_flag routine table */
0x2000001, /* MIDL flag */
0, /* cs routines */
(void *)& KMSServer_ProxyInfo, /* proxy/server info */
0
};
#endif // !MULTI_CALL_BINARY
static const MIDL_SYNTAX_INFO KMSServer_SyntaxInfo [ 2 ] =
{
{
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}},
0,
KMSServer__MIDL_ProcFormatString.Format,
KMSServer_FormatStringOffsetTable,
KMSServer__MIDL_TypeFormatString.Format,
0,
0,
0
}
,{
{{0x71710533,0xbeba,0x4937,{0x83,0x19,0xb5,0xdb,0xef,0x9c,0xcc,0x36}},{1,0}},
0,
0 ,
(unsigned short *) KMSServer_Ndr64ProcTable,
0,
0,
0,
0
}
};
/*static*/ const MIDL_STUBLESS_PROXY_INFO KMSServer_ProxyInfo =
{
&KMSServer_StubDesc,
KMSServer__MIDL_ProcFormatString.Format,
KMSServer_FormatStringOffsetTable,
(RPC_SYNTAX_IDENTIFIER*)&_RpcTransferSyntax,
2,
(MIDL_SYNTAX_INFO*)KMSServer_SyntaxInfo
};
#if _MSC_VER >= 1200
#pragma warning(pop)
#endif
#endif /* defined(_M_AMD64)*/

80
KMSServer_h.h Normal file
View File

@ -0,0 +1,80 @@
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
/* Modified by Hotbird64 for use with MingW and gcc */
/* File created by MIDL compiler version 8.00.0595 */
/* at Thu Oct 18 15:24:14 2012
*/
/* Compiler settings for KMSServer.idl:
Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.00.0595
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
DECLSPEC_UUID(), MIDL_INTERFACE()
*/
/* @@MIDL_FILE_HEADING( ) */
#pragma warning( disable: 4049 ) /* more than 64k source lines */
/* verify that the <rpcndr.h> version is high enough to compile this file*/
#ifndef __REQUIRED_RPCNDR_H_VERSION__
#define __REQUIRED_RPCNDR_H_VERSION__ 475
#endif
//#include "rpc.h"
#include "rpcndr.h"
#ifndef __RPCNDR_H_VERSION__
#error this stub requires an updated version of <rpcndr.h>
#endif // __RPCNDR_H_VERSION__
#ifndef __KMSServer_h_h__
#define __KMSServer_h_h__
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif
/* Forward Declarations */
#ifdef __cplusplus
extern "C"{
#endif
#ifndef __KMSServer_INTERFACE_DEFINED__
#define __KMSServer_INTERFACE_DEFINED__
/* interface KMSServer */
/* [version][uuid] */
int RequestActivation(
/* [in] */ handle_t IDL_handle,
/* [in] */ int requestSize,
/* [size_is][in] */ unsigned char *request,
/* [out] */ int *responseSize,
/* [size_is][size_is][out] */ unsigned char **response);
extern RPC_IF_HANDLE KMSServer_v1_0_c_ifspec;
extern RPC_IF_HANDLE KMSServer_v1_0_s_ifspec;
#endif /* __KMSServer_INTERFACE_DEFINED__ */
/* Additional Prototypes for ALL interfaces */
/* end of Additional Prototypes */
#ifdef __cplusplus
}
#endif
#endif

282
KMSServer_s2_mingw_gcc.c Normal file
View File

@ -0,0 +1,282 @@
/* this ALWAYS GENERATED file contains the RPC server stubs */
/* WARNING! manually edited by Hotbird64 to work with MingW */
/* File created by MIDL compiler version 8.00.0595 */
/* at Thu Oct 18 15:24:14 2012
*/
/* Compiler settings for KMSServer.idl:
Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.00.0595
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
DECLSPEC_UUID(), MIDL_INTERFACE()
*/
/* @@MIDL_FILE_HEADING( ) */
#if !defined(_M_IA64) && !defined(_M_AMD64) && !defined(_ARM_)
#pragma warning( disable: 4049 ) /* more than 64k source lines */
#if _MSC_VER >= 1200
#pragma warning(push)
#endif
#pragma warning( disable: 4211 ) /* redefine extern to static */
#pragma warning( disable: 4232 ) /* dllimport identity*/
#pragma warning( disable: 4024 ) /* array to pointer mapping*/
#pragma warning( disable: 4100 ) /* unreferenced arguments in x86 call */
#pragma optimize("", off )
#include <string.h>
#include "KMSServer_h.h"
#define TYPE_FORMAT_STRING_SIZE 43
#define PROC_FORMAT_STRING_SIZE 59
#define EXPR_FORMAT_STRING_SIZE 1
#define TRANSMIT_AS_TABLE_SIZE 0
#define WIRE_MARSHAL_TABLE_SIZE 0
typedef struct _KMSServer_MIDL_TYPE_FORMAT_STRING
{
short Pad;
unsigned char Format[ TYPE_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_TYPE_FORMAT_STRING;
typedef struct _KMSServer_MIDL_PROC_FORMAT_STRING
{
short Pad;
unsigned char Format[ PROC_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_PROC_FORMAT_STRING;
typedef struct _KMSServer_MIDL_EXPR_FORMAT_STRING
{
long Pad;
unsigned char Format[ EXPR_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_EXPR_FORMAT_STRING;
static const RPC_SYNTAX_IDENTIFIER _RpcTransferSyntax =
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}};
extern const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString;
extern const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString;
extern const KMSServer_MIDL_EXPR_FORMAT_STRING KMSServer__MIDL_ExprFormatString;
/* Standard interface: KMSServer, ver. 1.0,
GUID={0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}} */
extern const MIDL_SERVER_INFO KMSServer_ServerInfo;
extern const RPC_DISPATCH_TABLE KMSServer_v1_0_DispatchTable;
int ProcessActivationRequest(
/* [in] */ handle_t IDL_handle,
/* [in] */ int requestSize,
/* [size_is][in] */ unsigned char *request,
/* [out] */ int *responseSize,
/* [size_is][size_is][out] */ unsigned char **response);
static const RPC_SERVER_INTERFACE KMSServer___RpcServerInterface =
{
sizeof(RPC_SERVER_INTERFACE),
{{0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}},{1,0}},
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}},
(RPC_DISPATCH_TABLE*)&KMSServer_v1_0_DispatchTable,
0,
0,
0,
&KMSServer_ServerInfo,
0x04000000
};
RPC_IF_HANDLE KMSServer_v1_0_s_ifspec = (RPC_IF_HANDLE)& KMSServer___RpcServerInterface;
extern const MIDL_STUB_DESC KMSServer_StubDesc;
#if !defined(__RPC_WIN32__)
#error Invalid build platform for this stub.
#endif
#if !(TARGET_IS_NT50_OR_LATER)
#error You need Windows 2000 or later to run this stub because it uses these features:
#error /robust command line switch.
#error However, your C/C++ compilation flags indicate you intend to run this app on earlier systems.
#error This app will fail with the RPC_X_WRONG_STUB_VERSION error.
#endif
const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString =
{
0,
{
/* Procedure RequestActivation */
0x0, /* 0 */
0x48, /* Old Flags: */
/* 2 */ NdrFcLong( 0x0 ), /* 0 */
/* 6 */ NdrFcShort( 0x0 ), /* 0 */
/* 8 */ NdrFcShort( 0x18 ), /* x86 Stack size/offset = 24 */
/* 10 */ 0x32, /* FC_BIND_PRIMITIVE */
0x0, /* 0 */
/* 12 */ NdrFcShort( 0x0 ), /* x86 Stack size/offset = 0 */
/* 14 */ NdrFcShort( 0x8 ), /* 8 */
/* 16 */ NdrFcShort( 0x24 ), /* 36 */
/* 18 */ 0x47, /* Oi2 Flags: srv must size, clt must size, has return, has ext, */
0x5, /* 5 */
/* 20 */ 0x8, /* 8 */
0x7, /* Ext Flags: new corr desc, clt corr check, srv corr check, */
/* 22 */ NdrFcShort( 0x1 ), /* 1 */
/* 24 */ NdrFcShort( 0x1 ), /* 1 */
/* 26 */ NdrFcShort( 0x0 ), /* 0 */
/* Parameter IDL_handle */
/* 28 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 30 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */
/* 32 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter requestSize */
/* 34 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */
/* 36 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */
/* 38 */ NdrFcShort( 0x6 ), /* Type Offset=6 */
/* Parameter request */
/* 40 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */
/* 42 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 44 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter responseSize */
/* 46 */ NdrFcShort( 0x2013 ), /* Flags: must size, must free, out, srv alloc size=8 */
/* 48 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */
/* 50 */ NdrFcShort( 0x16 ), /* Type Offset=22 */
/* Parameter response */
/* 52 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 54 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */
/* 56 */ 0x8, /* FC_LONG */
0x0, /* 0 */
0x0
}
};
const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString =
{
0,
{
NdrFcShort( 0x0 ), /* 0 */
/* 2 */
0x11, 0x0, /* FC_RP */
/* 4 */ NdrFcShort( 0x2 ), /* Offset= 2 (6) */
/* 6 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 8 */ NdrFcShort( 0x1 ), /* 1 */
/* 10 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x0, /* */
/* 12 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */
/* 14 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 16 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
/* 18 */
0x11, 0xc, /* FC_RP [alloced_on_stack] [simple_pointer] */
/* 20 */ 0x8, /* FC_LONG */
0x5c, /* FC_PAD */
/* 22 */
0x11, 0x14, /* FC_RP [alloced_on_stack] [pointer_deref] */
/* 24 */ NdrFcShort( 0x2 ), /* Offset= 2 (26) */
/* 26 */
0x12, 0x0, /* FC_UP */
/* 28 */ NdrFcShort( 0x2 ), /* Offset= 2 (30) */
/* 30 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 32 */ NdrFcShort( 0x1 ), /* 1 */
/* 34 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x54, /* FC_DEREFERENCE */
/* 36 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 38 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 40 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
0x0
}
};
static const unsigned short KMSServer_FormatStringOffsetTable[] =
{
0
};
typedef void *(__RPC_API *midl_allocate_t)(size_t);
const MIDL_STUB_DESC KMSServer_StubDesc =
{
(void *)& KMSServer___RpcServerInterface,
(midl_allocate_t)MIDL_user_allocate,
MIDL_user_free,
0,
0,
0,
0,
0,
KMSServer__MIDL_TypeFormatString.Format,
1, /* -error bounds_check flag */
0x50002, /* Ndr library version */
0,
0x8000253, /* MIDL Version 8.0.595 */
0,
0,
0, /* notify & notify_flag routine table */
0x1, /* MIDL flag */
0, /* cs routines */
0, /* proxy/server info */
0
};
static const RPC_DISPATCH_FUNCTION KMSServer_table[] =
{
NdrServerCall2,
0
};
const RPC_DISPATCH_TABLE KMSServer_v1_0_DispatchTable =
{
1,
(RPC_DISPATCH_FUNCTION*)KMSServer_table
};
static const SERVER_ROUTINE KMSServer_ServerRoutineTable[] =
{
(SERVER_ROUTINE)ProcessActivationRequest
};
const MIDL_SERVER_INFO KMSServer_ServerInfo =
{
&KMSServer_StubDesc,
KMSServer_ServerRoutineTable,
KMSServer__MIDL_ProcFormatString.Format,
KMSServer_FormatStringOffsetTable,
0,
0,
0,
0};
#pragma optimize("", on )
#if _MSC_VER >= 1200
#pragma warning(pop)
#endif
#endif /* !defined(_M_IA64) && !defined(_M_AMD64) && !defined(_ARM_) */

View File

@ -0,0 +1,730 @@
/* this ALWAYS GENERATED file contains the RPC server stubs */
/* File created by MIDL compiler version 8.00.0603 */
/* at Fri Feb 20 04:17:07 2015
* Modified by Hotbird64 to work with gcc and MingW-w64
*/
/* Compiler settings for KMSServer.idl:
Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.00.0603
protocol : all , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
DECLSPEC_UUID(), MIDL_INTERFACE()
*/
/* @@MIDL_FILE_HEADING( ) */
#if defined(_M_AMD64)
int ProcessActivationRequest(
/* [in] */ handle_t IDL_handle,
/* [in] */ int requestSize,
/* [size_is][in] */ unsigned char *request,
/* [out] */ int *responseSize,
/* [size_is][size_is][out] */ unsigned char **response);
#pragma warning( disable: 4049 ) /* more than 64k source lines */
#if _MSC_VER >= 1200
#pragma warning(push)
#endif
#pragma warning( disable: 4211 ) /* redefine extern to static */
#pragma warning( disable: 4232 ) /* dllimport identity*/
#pragma warning( disable: 4024 ) /* array to pointer mapping*/
#include <string.h>
#include "KMSServer_h.h"
#define TYPE_FORMAT_STRING_SIZE 43
#define PROC_FORMAT_STRING_SIZE 61
#define EXPR_FORMAT_STRING_SIZE 1
#define TRANSMIT_AS_TABLE_SIZE 0
#define WIRE_MARSHAL_TABLE_SIZE 0
typedef struct _KMSServer_MIDL_TYPE_FORMAT_STRING
{
short Pad;
unsigned char Format[ TYPE_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_TYPE_FORMAT_STRING;
typedef struct _KMSServer_MIDL_PROC_FORMAT_STRING
{
short Pad;
unsigned char Format[ PROC_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_PROC_FORMAT_STRING;
typedef struct _KMSServer_MIDL_EXPR_FORMAT_STRING
{
long Pad;
unsigned char Format[ EXPR_FORMAT_STRING_SIZE ];
} KMSServer_MIDL_EXPR_FORMAT_STRING;
static const RPC_SYNTAX_IDENTIFIER _RpcTransferSyntax =
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}};
static const RPC_SYNTAX_IDENTIFIER _NDR64_RpcTransferSyntax =
{{0x71710533,0xbeba,0x4937,{0x83,0x19,0xb5,0xdb,0xef,0x9c,0xcc,0x36}},{1,0}};
extern const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString;
extern const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString;
extern const KMSServer_MIDL_EXPR_FORMAT_STRING KMSServer__MIDL_ExprFormatString;
/* Standard interface: KMSServer, ver. 1.0,
GUID={0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}} */
extern const MIDL_SERVER_INFO KMSServer_ServerInfo;
extern const RPC_DISPATCH_TABLE KMSServer_v1_0_DispatchTable;
static const RPC_SERVER_INTERFACE KMSServer___RpcServerInterface =
{
sizeof(RPC_SERVER_INTERFACE),
{{0x51C82175,0x844E,0x4750,{0xB0,0xD8,0xEC,0x25,0x55,0x55,0xBC,0x06}},{1,0}},
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}},
(RPC_DISPATCH_TABLE*)&KMSServer_v1_0_DispatchTable,
0,
0,
0,
&KMSServer_ServerInfo,
0x06000000
};
RPC_IF_HANDLE KMSServer_v1_0_s_ifspec = (RPC_IF_HANDLE)& KMSServer___RpcServerInterface;
extern const MIDL_STUB_DESC KMSServer_StubDesc;
#if !defined(__RPC_WIN64__)
#error Invalid build platform for this stub.
#endif
/*static*/ const KMSServer_MIDL_PROC_FORMAT_STRING KMSServer__MIDL_ProcFormatString =
{
0,
{
/* Procedure RequestActivation */
0x0, /* 0 */
0x48, /* Old Flags: */
/* 2 */ NdrFcLong( 0x0 ), /* 0 */
/* 6 */ NdrFcShort( 0x0 ), /* 0 */
/* 8 */ NdrFcShort( 0x30 ), /* X64 Stack size/offset = 48 */
/* 10 */ 0x32, /* FC_BIND_PRIMITIVE */
0x0, /* 0 */
/* 12 */ NdrFcShort( 0x0 ), /* X64 Stack size/offset = 0 */
/* 14 */ NdrFcShort( 0x8 ), /* 8 */
/* 16 */ NdrFcShort( 0x24 ), /* 36 */
/* 18 */ 0x47, /* Oi2 Flags: srv must size, clt must size, has return, has ext, */
0x5, /* 5 */
/* 20 */ 0xa, /* 10 */
0x7, /* Ext Flags: new corr desc, clt corr check, srv corr check, */
/* 22 */ NdrFcShort( 0x1 ), /* 1 */
/* 24 */ NdrFcShort( 0x1 ), /* 1 */
/* 26 */ NdrFcShort( 0x0 ), /* 0 */
/* 28 */ NdrFcShort( 0x0 ), /* 0 */
/* Parameter IDL_handle */
/* 30 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 32 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
/* 34 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter requestSize */
/* 36 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */
/* 38 */ NdrFcShort( 0x10 ), /* X64 Stack size/offset = 16 */
/* 40 */ NdrFcShort( 0x6 ), /* Type Offset=6 */
/* Parameter request */
/* 42 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */
/* 44 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */
/* 46 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter responseSize */
/* 48 */ NdrFcShort( 0x2013 ), /* Flags: must size, must free, out, srv alloc size=8 */
/* 50 */ NdrFcShort( 0x20 ), /* X64 Stack size/offset = 32 */
/* 52 */ NdrFcShort( 0x16 ), /* Type Offset=22 */
/* Parameter response */
/* 54 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 56 */ NdrFcShort( 0x28 ), /* X64 Stack size/offset = 40 */
/* 58 */ 0x8, /* FC_LONG */
0x0, /* 0 */
0x0
}
};
/*static*/ const KMSServer_MIDL_TYPE_FORMAT_STRING KMSServer__MIDL_TypeFormatString =
{
0,
{
NdrFcShort( 0x0 ), /* 0 */
/* 2 */
0x11, 0x0, /* FC_RP */
/* 4 */ NdrFcShort( 0x2 ), /* Offset= 2 (6) */
/* 6 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 8 */ NdrFcShort( 0x1 ), /* 1 */
/* 10 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x0, /* */
/* 12 */ NdrFcShort( 0x8 ), /* X64 Stack size/offset = 8 */
/* 14 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 16 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
/* 18 */
0x11, 0xc, /* FC_RP [alloced_on_stack] [simple_pointer] */
/* 20 */ 0x8, /* FC_LONG */
0x5c, /* FC_PAD */
/* 22 */
0x11, 0x14, /* FC_RP [alloced_on_stack] [pointer_deref] */
/* 24 */ NdrFcShort( 0x2 ), /* Offset= 2 (26) */
/* 26 */
0x12, 0x0, /* FC_UP */
/* 28 */ NdrFcShort( 0x2 ), /* Offset= 2 (30) */
/* 30 */
0x1b, /* FC_CARRAY */
0x0, /* 0 */
/* 32 */ NdrFcShort( 0x1 ), /* 1 */
/* 34 */ 0x28, /* Corr desc: parameter, FC_LONG */
0x54, /* FC_DEREFERENCE */
/* 36 */ NdrFcShort( 0x18 ), /* X64 Stack size/offset = 24 */
/* 38 */ NdrFcShort( 0x1 ), /* Corr flags: early, */
/* 40 */ 0x2, /* FC_CHAR */
0x5b, /* FC_END */
0x0
}
};
static const unsigned short KMSServer_FormatStringOffsetTable[] =
{
0
};
static const RPC_DISPATCH_FUNCTION KMSServer_table[] =
{
NdrServerCall2,
0
};
/*static*/ const RPC_DISPATCH_TABLE KMSServer_v1_0_DispatchTable =
{
1,
(RPC_DISPATCH_FUNCTION*)KMSServer_table
};
#endif /* defined(_M_AMD64)*/
/* this ALWAYS GENERATED file contains the RPC server stubs */
/* File created by MIDL compiler version 8.00.0603 */
/* at Fri Feb 20 04:17:07 2015
*/
/* Compiler settings for KMSServer.idl:
Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.00.0603
protocol : all , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
DECLSPEC_UUID(), MIDL_INTERFACE()
*/
/* @@MIDL_FILE_HEADING( ) */
#if defined(_M_AMD64)
#pragma warning( disable: 4049 ) /* more than 64k source lines */
#if !defined(__RPC_WIN64__)
#error Invalid build platform for this stub.
#endif
#include "ndr64types.h"
#include "pshpack8.h"
typedef
struct
{
NDR64_FORMAT_UINT32 frag1;
struct _NDR64_EXPR_OPERATOR frag2;
struct _NDR64_EXPR_VAR frag3;
}
__midl_frag13_t;
extern const __midl_frag13_t __midl_frag13;
typedef
struct
{
struct _NDR64_CONF_ARRAY_HEADER_FORMAT frag1;
struct _NDR64_ARRAY_ELEMENT_INFO frag2;
}
__midl_frag12_t;
extern const __midl_frag12_t __midl_frag12;
typedef
struct _NDR64_POINTER_FORMAT
__midl_frag11_t;
extern const __midl_frag11_t __midl_frag11;
typedef
struct _NDR64_POINTER_FORMAT
__midl_frag10_t;
extern const __midl_frag10_t __midl_frag10;
typedef
struct _NDR64_POINTER_FORMAT
__midl_frag8_t;
extern const __midl_frag8_t __midl_frag8;
typedef
NDR64_FORMAT_CHAR
__midl_frag7_t;
extern const __midl_frag7_t __midl_frag7;
typedef
struct
{
NDR64_FORMAT_UINT32 frag1;
struct _NDR64_EXPR_VAR frag2;
}
__midl_frag6_t;
extern const __midl_frag6_t __midl_frag6;
typedef
struct
{
struct _NDR64_CONF_ARRAY_HEADER_FORMAT frag1;
struct _NDR64_ARRAY_ELEMENT_INFO frag2;
}
__midl_frag5_t;
extern const __midl_frag5_t __midl_frag5;
typedef
struct _NDR64_POINTER_FORMAT
__midl_frag4_t;
extern const __midl_frag4_t __midl_frag4;
typedef
NDR64_FORMAT_CHAR
__midl_frag3_t;
extern const __midl_frag3_t __midl_frag3;
typedef
struct
{
struct _NDR64_PROC_FORMAT frag1;
struct _NDR64_BIND_AND_NOTIFY_EXTENSION frag2;
struct _NDR64_PARAM_FORMAT frag3;
struct _NDR64_PARAM_FORMAT frag4;
struct _NDR64_PARAM_FORMAT frag5;
struct _NDR64_PARAM_FORMAT frag6;
struct _NDR64_PARAM_FORMAT frag7;
}
__midl_frag2_t;
extern const __midl_frag2_t __midl_frag2;
typedef
NDR64_FORMAT_UINT32
__midl_frag1_t;
extern const __midl_frag1_t __midl_frag1;
/*static*/ const __midl_frag13_t __midl_frag13 =
{
/* */
(NDR64_UINT32) 1 /* 0x1 */,
{
/* struct _NDR64_EXPR_OPERATOR */
0x4, /* FC_EXPR_OPER */
0x5, /* OP_UNARY_INDIRECTION */
0x5, /* FC64_INT32 */
(NDR64_UINT8) 0 /* 0x0 */
},
{
/* struct _NDR64_EXPR_VAR */
0x3, /* FC_EXPR_VAR */
0x7, /* FC64_INT64 */
(NDR64_UINT16) 0 /* 0x0 */,
(NDR64_UINT32) 24 /* 0x18 */ /* Offset */
}
};
/*static*/ const __midl_frag12_t __midl_frag12 =
{
/* *char */
{
/* *char */
0x41, /* FC64_CONF_ARRAY */
(NDR64_UINT8) 0 /* 0x0 */,
{
/* *char */
0,
0,
0,
0,
0,
0,
0,
0
},
(NDR64_UINT8) 0 /* 0x0 */,
(NDR64_UINT32) 1 /* 0x1 */,
&__midl_frag13
},
{
/* struct _NDR64_ARRAY_ELEMENT_INFO */
(NDR64_UINT32) 1 /* 0x1 */,
&__midl_frag7
}
};
/*static*/ const __midl_frag11_t __midl_frag11 =
{
/* *char */
0x21, /* FC64_UP */
(NDR64_UINT8) 0 /* 0x0 */,
(NDR64_UINT16) 0 /* 0x0 */,
&__midl_frag12
};
/*static*/ const __midl_frag10_t __midl_frag10 =
{
/* **char */
0x20, /* FC64_RP */
(NDR64_UINT8) 20 /* 0x14 */,
(NDR64_UINT16) 0 /* 0x0 */,
&__midl_frag11
};
/*static*/ const __midl_frag8_t __midl_frag8 =
{
/* *int */
0x20, /* FC64_RP */
(NDR64_UINT8) 12 /* 0xc */,
(NDR64_UINT16) 0 /* 0x0 */,
&__midl_frag3
};
/*static*/ const __midl_frag7_t __midl_frag7 =
0x10 /* FC64_CHAR */;
/*static*/ const __midl_frag6_t __midl_frag6 =
{
/* */
(NDR64_UINT32) 1 /* 0x1 */,
{
/* struct _NDR64_EXPR_VAR */
0x3, /* FC_EXPR_VAR */
0x5, /* FC64_INT32 */
(NDR64_UINT16) 0 /* 0x0 */,
(NDR64_UINT32) 8 /* 0x8 */ /* Offset */
}
};
/*static*/ const __midl_frag5_t __midl_frag5 =
{
/* *char */
{
/* *char */
0x41, /* FC64_CONF_ARRAY */
(NDR64_UINT8) 0 /* 0x0 */,
{
/* *char */
0,
0,
0,
0,
0,
0,
0,
0
},
(NDR64_UINT8) 0 /* 0x0 */,
(NDR64_UINT32) 1 /* 0x1 */,
&__midl_frag6
},
{
/* struct _NDR64_ARRAY_ELEMENT_INFO */
(NDR64_UINT32) 1 /* 0x1 */,
&__midl_frag7
}
};
/*static*/ const __midl_frag4_t __midl_frag4 =
{
/* *char */
0x20, /* FC64_RP */
(NDR64_UINT8) 0 /* 0x0 */,
(NDR64_UINT16) 0 /* 0x0 */,
&__midl_frag5
};
/*static*/ const __midl_frag3_t __midl_frag3 =
0x5 /* FC64_INT32 */;
/*static*/ const __midl_frag2_t __midl_frag2 =
{
/* RequestActivation */
{
/* RequestActivation */ /* procedure RequestActivation */
(NDR64_UINT32) 23986240 /* 0x16e0040 */, /* explicit handle */ /* IsIntrepreted, ServerMustSize, ClientMustSize, HasReturn, ServerCorrelation, ClientCorrelation, HasExtensions */
(NDR64_UINT32) 48 /* 0x30 */ , /* Stack size */
(NDR64_UINT32) 8 /* 0x8 */,
(NDR64_UINT32) 40 /* 0x28 */,
(NDR64_UINT16) 0 /* 0x0 */,
(NDR64_UINT16) 0 /* 0x0 */,
(NDR64_UINT16) 5 /* 0x5 */,
(NDR64_UINT16) 8 /* 0x8 */
},
{
/* struct _NDR64_BIND_AND_NOTIFY_EXTENSION */
{
/* struct _NDR64_BIND_AND_NOTIFY_EXTENSION */
0x72, /* FC64_BIND_PRIMITIVE */
(NDR64_UINT8) 0 /* 0x0 */,
0 /* 0x0 */, /* Stack offset */
(NDR64_UINT8) 0 /* 0x0 */,
(NDR64_UINT8) 0 /* 0x0 */
},
(NDR64_UINT16) 0 /* 0x0 */ /* Notify index */
},
{
/* requestSize */ /* parameter requestSize */
&__midl_frag3,
{
/* requestSize */
0,
0,
0,
1,
0,
0,
1,
1,
0,
0,
0,
0,
0,
(NDR64_UINT16) 0 /* 0x0 */,
0
}, /* [in], Basetype, ByValue */
(NDR64_UINT16) 0 /* 0x0 */,
8 /* 0x8 */, /* Stack offset */
},
{
/* request */ /* parameter request */
&__midl_frag5,
{
/* request */
1,
1,
0,
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
(NDR64_UINT16) 0 /* 0x0 */,
0
}, /* MustSize, MustFree, [in], SimpleRef */
(NDR64_UINT16) 0 /* 0x0 */,
16 /* 0x10 */, /* Stack offset */
},
{
/* responseSize */ /* parameter responseSize */
&__midl_frag3,
{
/* responseSize */
0,
0,
0,
0,
1,
0,
1,
0,
1,
0,
0,
0,
0,
(NDR64_UINT16) 0 /* 0x0 */,
1
}, /* [out], Basetype, SimpleRef, UseCache */
(NDR64_UINT16) 0 /* 0x0 */,
24 /* 0x18 */, /* Stack offset */
},
{
/* response */ /* parameter response */
&__midl_frag10,
{
/* response */
1,
1,
0,
0,
1,
0,
0,
0,
0,
0,
0,
0,
0,
(NDR64_UINT16) 0 /* 0x0 */,
1
}, /* MustSize, MustFree, [out], UseCache */
(NDR64_UINT16) 0 /* 0x0 */,
32 /* 0x20 */, /* Stack offset */
},
{
/* int */ /* parameter int */
&__midl_frag3,
{
/* int */
0,
0,
0,
0,
1,
1,
1,
1,
0,
0,
0,
0,
0,
(NDR64_UINT16) 0 /* 0x0 */,
0
}, /* [out], IsReturn, Basetype, ByValue */
(NDR64_UINT16) 0 /* 0x0 */,
40 /* 0x28 */, /* Stack offset */
}
};
/*static*/ const __midl_frag1_t __midl_frag1 =
(NDR64_UINT32) 0 /* 0x0 */;
#include "poppack.h"
static const FormatInfoRef KMSServer_Ndr64ProcTable[] =
{
&__midl_frag2
};
//typedef void *__RPC_USER MIDL_user_allocate_t(SIZE_T);
typedef void *(__RPC_API *midl_allocate_t)(size_t);
/*static*/ const MIDL_STUB_DESC KMSServer_StubDesc =
{
(void *)& KMSServer___RpcServerInterface,
(midl_allocate_t)MIDL_user_allocate,
MIDL_user_free,
0,
0,
0,
0,
0,
KMSServer__MIDL_TypeFormatString.Format,
1, /* -error bounds_check flag */
0x60000, /* Ndr library version */
0,
0x800025b, /* MIDL Version 8.0.603 */
0,
0,
0, /* notify & notify_flag routine table */
0x2000001, /* MIDL flag */
0, /* cs routines */
(void *)& KMSServer_ServerInfo, /* proxy/server info */
0
};
static const RPC_DISPATCH_FUNCTION KMSServer_NDR64__table[] =
{
NdrServerCallAll,
0
};
static const RPC_DISPATCH_TABLE KMSServer_NDR64__v1_0_DispatchTable =
{
1,
(RPC_DISPATCH_FUNCTION*)KMSServer_NDR64__table
};
static const MIDL_SYNTAX_INFO KMSServer_SyntaxInfo [ 2 ] =
{
{
{{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}},{2,0}},
(RPC_DISPATCH_TABLE*)&KMSServer_v1_0_DispatchTable,
KMSServer__MIDL_ProcFormatString.Format,
KMSServer_FormatStringOffsetTable,
KMSServer__MIDL_TypeFormatString.Format,
0,
0,
0
}
,{
{{0x71710533,0xbeba,0x4937,{0x83,0x19,0xb5,0xdb,0xef,0x9c,0xcc,0x36}},{1,0}},
(RPC_DISPATCH_TABLE*)&KMSServer_NDR64__v1_0_DispatchTable,
0 ,
(unsigned short *) KMSServer_Ndr64ProcTable,
0,
0,
0,
0
}
};
static const SERVER_ROUTINE KMSServer_ServerRoutineTable[] =
{
(SERVER_ROUTINE)ProcessActivationRequest
};
/*static*/ const MIDL_SERVER_INFO KMSServer_ServerInfo =
{
&KMSServer_StubDesc,
KMSServer_ServerRoutineTable,
KMSServer__MIDL_ProcFormatString.Format,
(unsigned short *) KMSServer_FormatStringOffsetTable,
0,
(RPC_SYNTAX_IDENTIFIER*)&_NDR64_RpcTransferSyntax,
2,
(MIDL_SYNTAX_INFO*)KMSServer_SyntaxInfo
};
#if _MSC_VER >= 1200
#pragma warning(pop)
#endif
#endif /* defined(_M_AMD64)*/

7
Makefile Normal file
View File

@ -0,0 +1,7 @@
# Let BSD make switch to GNU make
all ${.TARGETS}:
@echo "================================================================"
@echo " PLEASE USE THE GNU VERSION OF MAKE (gmake) INSTEAD OF ${MAKE} "
@echo "================================================================"
@echo ""
@gmake $@

13
README Normal file
View File

@ -0,0 +1,13 @@
To view the documentation cd to the directory containing the distribution
files and type
man ./vlmcsd.8
to see documentation for vlmcsd
man ./vlmcs.1
to see documentation for vlmcs
man ./vlmcsd.7
to see general documentation for kms
If you don't have man, you may also use the .txt, .html and .pdf files

View File

@ -0,0 +1,110 @@
Compilation and pre-built binaries FAQ
======================================
What is the best pre-built binary for my system or device?
----------------------------------------------------------
None. The best binary is compiled by yourself using a toolchain that is
optimized for your system or device in every respect.
How do I compile my own binary?
-------------------------------
On a full blown desktop system this is relativly easy. If not already done so,
install a C compiler (e.g. gcc or clang) through your packet manager, e.g.
"sudo apt-get install gcc" (Debian/Ubuntu) or "sudo yum install gcc"
(RedHat/Fedora).
Then cd to your vlmcsd directory and type "make". vlmcs and vlmcsd will
be built right away for your local system.
If you installed gcc and it is not the default compiler for your OS or
distribution, you may need to type "make CC=gcc" to explicitly select a
specific C compiller.
How do I compile a binary for my embedded device?
-------------------------------------------------
What you need is cross-compiling toolchain for your device. It consists of a
C compiler, libraries, header files and some tools (called binutils). The
toolchain must match the device in processor architecture, endianess, ABI,
library and header files version, library configuration, ...
If the endianess or ABI differs or the version of some library between
toolchain and device differs too much, the resulting binary does not run
on your device.
Once you have a proper toolchain (probably found on the Internet for download),
unpack it to any directory and type
"make CC=/path/to/toolchain/bindir/c-compiler-binary"
Building vlmcsd for using a cross-compiling toolchain is as easy as building
vlmcsd for your local machine. The only question is, whether this you have
a toolchain that actually matches your device.
Whenever you change any parameter of the make command line, you must "clean"
the source directory from intermediate files and output from previous runs
of make. You can do so by typeing "make clean" or force make to behave as if
the directory were clean by adding -B to the command line, e.g.
"make -B CC=/path/to/toolchain/bindir/c-compiler-binary"
I have downloaded several promising toolchains for my device but they all
don't work. Can I create my own toolchain?
-------------------------------------------------------------------------
You can use tools like buildroot or OpenWRT. Both are able to create toolchains
for many embedded devices. But this is out of the scope of this document.
If you are unable to walk through thousands of configuration options and make
the right choice, you may probably want to try the pre-built binaries.
How to choose a pre-built binary?
---------------------------------
The directory structure for the binaries is
binaries
+
+--<operating system>
+
+--<cpu arch>
+
+--<endianess> (omitted if CPU or OS does not allow multi-endianess)
+
+--<C-library>
<C-library> can also be "static". That means no special library is required.
Static binaries are much bigger and need more RAM than dynamic binaries but
are more likely to run on your system. Use a static binary only, if none of
the dynmic binaries run.
Don't get confused when a binary is named after an OS or a specific device,
e.g. the name contains "openwrt", "tomato" or "Fritzbox". This does not mean
that the binary will run only on that OS or on that device. It is a hint only
where I got or built the toolchain from.
How to determine the endianess of my system?
--------------------------------------------
- All Intel CPUs (x86, x32, x64) are little-endian only
- Windows is little-endian only even if the CPU support big-endian
- big-endian ARM is extremely uncommon. You can safely assume little-endian
- little-endian PowerPC virtually does not exist since only newer POWER7
and POWER8 CPUs support it. Always assume big-endian.
- For MIPS both little-endian and big-endian are common. Most Broadcomm and
TI chips run little-endian. Most Atheros and Ikanos CPUs run big-endian.
Try typing
echo -n I | od -o | awk 'FNR==1{ print substr($2,6,1)}'
This returns 1 for little-endian systems and 0 for big-endian systems. However
some devices do not have the od command and thus this method won't work.

55
README.openssl Normal file
View File

@ -0,0 +1,55 @@
IMPORTANT
=========
1. Do not use any of the OpenSSL binaries
2. Do not compile OpenSSL binaries yourself
(except for doing some research into the deep internals of OpenSSL)
REASONS
=======
All OpenSSL binaries included are highly experimental and are likely to fail
in many cases. To get some real benefit from OpenSSL (or PolarSSL) it should
handle all crypting/hashing.
However this is not possible because Microsoft has slightly altered AES
encryption in KMSv6 and uses a non-AES variant of the Rijndael CMAC in
KMSv4. OpenSSL is not able to handle this if you use it correctly.
This means OpenSSL can be used safely only for SHA256 and HMAC SHA256
calculations used in KMSv5 and KMSv6 but the code size benefit is only
100 to 300 bytes (depending on the architecture).
To benefit more from OpenSSL (getting it performing the AES stuff) I do
the first phase of AES encryption/decryption (called key expansion) with my
own code. I then poke the expanded key into internal OpenSSL structs to make
it behave in a way not intended by the OpenSSL developers but in a way to
perform non-standard AES crypting as required by KMSv4 and KMSv6. KMSv5 is
the only protocol that could use OpenSSL without hacking the OpenSSL internals.
That means vlmcsd still needs about 40% of the internal AES code plus some
OpenSSL hacking code to poke the expanded key into OpenSSL.
The entire OpenSSL hacking does not work in every case because the internal
OpenSSL structs differ depending on the OpenSSL version, OpenSSL configuration
at compile time (whether it is configured to use compiled C code or assembler
code), CPU architecture and CPU features (whether it can perform AES in
hardware).
SUMMARY
=======
If you use OpenSSL in a safe way (compile with CRYPTO=openssl), there is not
much benefit from it. The binary may become bigger or smaller and you
definitely need more RAM when you run vlmcsd or vlmcs.
If you use hacked OpenSSL (compile with CRYPTO=openssl_with_aes or
CRYPTO=openssl_with_aes_soft) you risk malfunction of vlmcs/vlmcsd even if it
performed correctly several times before.
Both vlmcs and vlmcsd do not have more features when compiled with OpenSSL
support. It may be faster (especially on CPUs with hardware assisted AES) but
uses more memory and may fail or perform unreliably.

File diff suppressed because it is too large Load Diff

583
config.h Normal file
View File

@ -0,0 +1,583 @@
#ifndef CONFIG_H_
#define CONFIG_H_
/* Don't change anything ABOVE this line */
/*
* As a best practice do not change the original config.h as distributed with vlmcsd.
* Instead make a copy, e.g. myconfig.h, customize it and type 'make CONFIG=myconfig.h'
* to build vlmcsd. This prevents your copy being overwritten when you upgrade to a
* new version.
*/
/*
* ----------------------------------------------------------------------------------------
* Useful customizations. These options are mandatory. You cannot comment them out.
* Feel free to change them to fit your needs.
* ----------------------------------------------------------------------------------------
*/
#ifndef VERSION
/*
* Define your own version identifier here, e.g. '#define VERSION "my vlmcsd based on svn560"'
*/
#define VERSION "private build"
#endif // VERSION
/*
* Define default ePIDs and HWID here. Preferrably grab ePIDs and HWID
* from a real KMS server.
*/
#ifndef EPID_WINDOWS
#define EPID_WINDOWS "06401-00206-271-298329-03-1033-9600.0000-0452015"
#endif
#ifndef EPID_OFFICE2010
#define EPID_OFFICE2010 "06401-00096-199-198322-03-1033-9600.0000-0452015"
#endif
#ifndef EPID_OFFICE2013
#define EPID_OFFICE2013 "06401-00206-234-398213-03-1033-9600.0000-0452015"
#endif
#ifndef HWID // HwId from the Ratiborus VM
#define HWID 0x36, 0x4F, 0x46, 0x3A, 0x88, 0x63, 0xD3, 0x5F
#endif
/*
* Anything below this line is optional. If you want to use any of these options
* uncomment one or more lines starting with "//#define"
*/
/*
* -------------------------------
* Defaults
* -------------------------------
*/
#ifndef INI_FILE
/*
* Uncomment and customize the following line if you want vlmcsd to look for an ini file
* at a default location
*/
//#define INI_FILE "/etc/vlmcsd.ini"
#endif // INI_FILE
/*
* ----------------------------------------------------------------------------------------
* Troubleshooting options. Please note that disabling features may also help troubleshooting.
* If you have an old OS that does not support features like pthreads, shared memory or
* semaphores, uncomment "#define NO_LIMIT" and "#define NO_SIGHUP" and leave "#define USE_THREADS"
* commented out.
* ----------------------------------------------------------------------------------------
*/
#ifndef CHILD_HANDLER
/*
* Uncomment the following #define if you are compiling for a platform that does
* not correctly handle the SA_NOCLDWAIT flag when ignoring SIGCHLD, i.e. forked
* processes remain as "zombies" after dying. This option will add a SIGCHLD handler that
* "waits" for a child that has terminated. This is only required for a few
* unixoid OSses.
*/
//#define CHILD_HANDLER
#endif // CHILD_HANDLER
#ifndef NO_TIMEOUT
/*
* Uncomment the following #define if you are compiling for a platform that does
* not support custom socket send or receive timeouts.
*/
//#define NO_TIMEOUT
#endif // NO_TIMEOUT
#ifndef NO_DNS
/*
* Uncomment the following #define if you have trouble with accessing routines
* from libresolv. If enabled, vlmcs will be compiled without support for
* detecting KMS servers via DNS.
*/
//#define NO_DNS
#endif // NO_DNS
#ifndef TERMINAL_FIXED_WIDTH
/*
* Uncomment the following #define and optionally change its value if you are compiling for
* a platform that cannot properly determine the width of a terminal/command prompt.
* This affects the output of "vlmcsd -x" only. It should be rarely necessary to use this.
*/
//#define TERMINAL_FIXED_WIDTH 80
#endif // TERMINAL_FIXED_WIDTH
#ifndef _PEDANTIC
/*
* Uncomment the following #define if you want to do vlmcs and vlmcsd more checks on the data
* it receives over the network. They are normally not necessary but may provide useful if
* you are testing any KMS server or client emulator that may send malformed KMS packets.
*/
//#define _PEDANTIC
#endif // _PEDANTIC
#ifndef NO_PROCFS
/*
* Cygwin, Linux, Android, NetBSD, DragonflyBSD:
* Do not rely on a properly mounted proc filesystem and use the less reliable
* argv[0] to determine the program's executable name when restarting vlmcsd
* by sending a SIGHUP signal. Use only if absolutely necessary (very old versions
* of these OSses).
*
* FreeBSD:
* Do not use sysctl and but the less reliable
* argv[0] to determine the program's executable name when restarting vlmcsd
* by sending a SIGHUP signal. Use only if absolutely necessary (very old FreeBSD).
*
* OpenBSD:
* This option has no effect since OpenBSD always must use the less reliable argv[0].
*
* Mac OS X, Solaris:
* This option is not neccessary (and has no effect) since these OSses provide
* a reliable way to determine the executable name.
*
* Windows:
* This option is not used because Windows doesn't support signals.
*/
//#define NO_PROCFS
#endif // NO_PROCFS
#ifndef USE_AUXV
/*
* Linux only:
* Use the process' ELF aux vector to determine the executable name when restarting
* vlmcsd by sending a SIGHUP signal. This is actually the best method but is supported
* only with
* * the musl library
* * the glbic library 2.16 or newer
*
* It does NOT work with uclibc (most routers and other small devices) and glibc < 2.16.
* Use it only if your system supports it and you do not plan to use the binary on older systems.
* It won't work on debian 7 or Red Hat 6.x.
*
* It it safe to try this by yourself. vlmcsd won't compile if your system doesn't support it.
*/
//#define USE_AUXV
#endif // USE_AUXV
#ifndef _OPENSSL_NO_HMAC
/*
* If you configured vlmcsd to use OpenSSL (which you shouldn't) you may use this option
* to calculate the KMSv6 HMAC with internal code instead of using OpenSSL.
*
* This may be necessary for some embedded devices that have OpenSSL without HMAC support.
*/
//#define _OPENSSL_NO_HMAC
#endif // _OPENSSL_NO_HMAC
/*
* ----------------------------------------------------------------------------------------
* Modes of operation
* ----------------------------------------------------------------------------------------
*/
#ifndef USE_THREADS
/*
* Do not use fork() but threads to serve your clients.
*
* Unix-like operarting systems:
* You may use this or not. Entirely your choice. Threads do not require explicitly allocating
* a shared memory segment which might be a problem on some systems. Using fork() is more robust
* although the threaded version of vlmcsd is rock solid too.
*
* Some older unixoid OSses may not have pthreads. Do NOT use USE_THREADS and define NO_SIGHUP
* and NO_LIMIT instead to disable use of the pthreads, shared memory and semaphores.
*
* Cygwin:
* It is recommended to use threads since fork() is extremely slow (no copy on write) and somewhat
* unstable.
*
* Windows:
* This option has no effect since fork() is not supported.
*/
//#define USE_THREADS
#endif // USE_THREADS
#ifndef _CRYPTO_POLARSSL
/*
* Not available on native Windows. Can be used with Cygwin.
*
* Use PolarSSL for crypto routines if possible and if it is safe. There is not much benefit by using this
* options since it can be used for SHA256 and HMAC_SHA256 only. It cannot be used for AES calculations because
* KMSv6 uses a modified algorithm that PolarSSL does not support. KMSv4 CMAC is also unsupported since it uses
* a Rijndael keysize (160 bits) that is not part of the AES standard.
*
* It is strongly recommended not to use an external crypto library.
*
* Do not define both _CRYPTO_OPENSSL and _CRYPTO_POLARSSL
*/
//#define _CRYPTO_POLARSSL
#endif // _CRYPTO_POLARSSL
#ifndef _CRYPTO_OPENSSL
/*
* Not available on native Windows. Can be used with Cygwin.
*
* Use OpenSSL for crypto routines if possible and if it is safe. There is not much benefit by using this
* options since it can be used for SHA256 and HMAC_SHA256 only. It cannot be used for AES calculations because
* KMSv6 uses a modified algorithm that OpenSSL does not support. KMSv4 CMAC is also unsupported since it uses
* a Rijndael keysize (160 bits) that is not part of the AES standard.
*
* It is strongly recommended not to use an external crypto library.
*
* Do not define both _CRYPTO_OPENSSL and _CRYPTO_POLARSSL
*/
//#define _CRYPTO_OPENSSL
#endif // _CRYPTO_OPENSSL
#ifndef _USE_AES_FROM_OPENSSL
/*
* DANGEROUS: Tweak OpenSSL to perform KMSv4 CMAC and KMSv6 modified AES. This option creates the expanded
* AES key by itself and then applies modifications to it. OpenSSL will then perfom modified AES operations.
*
* This options tampers with internal structures of OpenSSL that are subject to change or may have a platform
* specific implementation. In this case your resulting binary can only perform KMSv5 operations.
*
* This option has no effect if _CRYPTO_OPENSSL is not defined.
*
* Don't use this except for your own research on the internals of OpenSSL.
*/
//#define _USE_AES_FROM_OPENSSL
#endif // _USE_AES_FROM_OPENSSL
#ifndef _OPENSSL_SOFTWARE
/*
* Use this only if you have defined _CRYPTO_OPENSSL and _USE_AES_FROM_OPENSSL. It has no effect otherwise.
*
* This options assumes a different internal AES expanded key in OpenSSL which is used mostly if OpenSSL is
* compiled without support for hardware accelerated AES. It's worth a try if _USE_AES_FROM_OPENSSL doesn't work.
*/
//#define _OPENSSL_SOFTWARE
#endif // _OPENSSL_SOFTWARE
/*
* ------------------------------------------------------------------------------------------
* Extra features not compiled by default because they are rarely needed
* ------------------------------------------------------------------------------------------
*/
#ifndef INCLUDE_BETAS
/*
* Uncomment the following #define if you want obsolete beta/preview SKUs
* to be included in the extended product list.
*/
//#define INCLUDE_BETAS
#endif
/*
* ----------------------------------------------------------------------------------------
* Removal of features. Allows you to remove features of vlmcsd you do not need or want.
* Use it to get smaller binaries. This is especially useful on very small embedded devices.
* ----------------------------------------------------------------------------------------
*/
#ifndef NO_EXTENDED_PRODUCT_LIST
/*
* Do not compile the extended product list. Removes the list of Activation GUIDs (aka
* Client SKU Id, License Id) and their respective product names (e.g. Windows 8.1 Enterprise).
*
* This affects logging only and does not have an effect on activation itself. As long as you
* do not also define NO_BASIC_PRODUCT_LIST more generic names like Windows 8.1 or Office 2013
* will still be logged. Saves a lot of space without loosing much functionality.
*
*/
//#define NO_EXTENDED_PRODUCT_LIST
#endif // NO_EXTENDED_PRODUCT_LIST
#ifndef NO_BASIC_PRODUCT_LIST
/*
* Do not compile the basic product list. Removes the list KMS GUIDs (aka Server SKU Id) and their
* respective product names. Only affects logging not activation. This has a negative impact only
* if you activate a product that is not (yet) in the extended product list. On the other hand you
* do not save much space by not compiling this list.
*/
//#define NO_BASIC_PRODUCT_LIST
#endif // NO_BASIC_PRODUCT_LIST
#ifndef NO_VERBOSE_LOG
/*
* Removes the ability to do verbose logging and disables -v and -q in vlmcsd. It does not remove the -v
* option in the vlmcs client. Disables ini file directive LogVerbose.
*/
//#define NO_VERBOSE_LOG
#endif // NO_VERBOSE_LOG
#ifndef NO_LOG
/*
* Disables logging completely. You can neither log to a file nor to the console. -D and -f will
* start vlmcsd in foreground. -e will not be available. Disables ini file directive LogFile.
* Implies NO_VERBOSE_LOG, NO_EXTENDED_PRODUCT_LIST and NO_BASIC_PRODUCT_LIST.
*/
//#define NO_LOG
#endif // NO_LOG
#ifndef NO_RANDOM_EPID
/*
* Disables the ability to generate random ePIDs. Useful if you managed to grab ePID/HWID from a
* real KMS server and want to use these. Removes -r from the vlmcsd command line and the ini
* file directive RandomizationLevel (The randomization level will be harcoded to 0).
*/
//#define NO_RANDOM_EPID
#endif // NO_RANDOM_EPID
#ifndef NO_INI_FILE
/*
* Disables the ability to use a configuration file (aka ini file). Removes -i from the command line.
*/
//#define NO_INI_FILE
#endif // NO_INI_FILE
#ifndef NO_PID_FILE
/*
* Disables the abilty to write a pid file containing the process id of vlmcsd. If your init system
* does not need this feature, you can safely disables this but it won't save much space. Disables
* the use of -p from the command line and PidFile from the ini file.
*/
//#define NO_PID_FILE
#endif // NO_PID_FILE
#ifndef NO_USER_SWITCH
/*
* Disables switching to another uid and/or gid after starting the program and setting up the sockets.
* You cannot use -u anf -g on the command line as well as User and Group in the ini file. If your init system
* supports starting daemons as another uid/gid (user/group) you can disable this feature in vlmcsd as long as you
* do not need to run vlmcsd on a privileged port ( < 1024 on most systems).
*
* This setting has no effect on native Windows since -u and -g is not available anyway. It may be used with
* Cygwin.
*/
//#define NO_USER_SWITCH
#endif // NO_USER_SWITCH
#ifndef NO_HELP
/*
* Disables display of help in both vlmcsd and vlmcs. Saves some bytes but only makes sense if you have
* access to the man files vlmcsd.8 and vlmcs.1
*/
//#define NO_HELP
#endif // NO_HELP
#ifndef NO_CUSTOM_INTERVALS
/*
* Disables the ability to specify custom interval for renewing and retrying activation. Newer versions of the Microsoft's
* KMS activation client (as in Win 8.1) do not honor these parameters anyway. Disable them to save some bytes. Removes
* -A and -R from the command line as well as ActivationInterval and RenewalInterval in the ini file.
*/
//#define NO_CUSTOM_INTERVALS
#endif // NO_CUSTOM_INTERVALS
#ifndef NO_SOCKETS
/*
* Disables standalone startup of vlmcsd. If you use this config directive, you must start vlmcsd from an internet
* superserver like inetd, xinetd, systemd or launchd. Disables -m, -t, -4, -6, -e, -f, -P and -L in the vlmcsd
* command line. Socket setup is the job of your superserver.
*/
//#define NO_SOCKETS
#endif // NO_SOCKETS
#ifndef NO_CL_PIDS
/*
* Disables the ability to specify ePIDs and HWID at the command line. You still may use them in the ini file.
* Removes -0, -3, -w and -H from the vlmcsd command line.
*/
//#define NO_CL_PIDS
#endif // NO_CL_PIDS
#ifndef NO_LIMIT
/*
* Disables the ability to limit the number of worker threads or processes that vlmcsd uses. While you should set a
* limit whenever possible, you may save some bytes by enabling that setting. If you do not use a limit, use vlmcsd
* in a "friendly" environment only, i.e. do not run it without a reasonable limit on the internet.
*
* Removes the ability to use -m in the vlmcsd command line and MaxWorkers in the ini file.
*
* Some older unixoid OSses may not have pthreads. Do NOT use USE_THREADS and define NO_SIGHUP
* and NO_LIMIT instead to disable use of the pthreads, shared memory and semaphores.
*/
//#define NO_LIMIT
#endif // NO_LIMIT
#ifndef NO_SIGHUP
/*
* Disables the ability to signal hangup (SIGHUP) to vlmcsd to restart it (rereading the ini file). The SIGHUP
* handler makes heavy use of OS specific code. It should not cause any trouble on Solaris, Mac OS X and iOS. On Linux
* use "#define USE_AUXV" (see troubleshooting options) if this is supported by your C runtime library.
*
* You may save some bytes by enabling this option. Use it also if the SIGHUP handler causes any trouble on your
* platform. Please note that with no SIGHUP handler at all. vlmcsd will simply terminate (uncleanly) if it receives
* the SIGHUP signal. This is the same behavior as with most other signals.
*
* This option has no effect on native Windows since Posix signaling is not supported. It can be used with Cygwin.
*/
//#define NO_SIGHUP
#endif // NO_SIGHUP
/* Don't change anything BELOW this line */
#endif /* CONFIG_H_ */

328
crypto.c Normal file
View File

@ -0,0 +1,328 @@
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include "crypto.h"
#include "endian.h"
#include <stdint.h>
const BYTE AesKeyV4[] = {
0x05, 0x3D, 0x83, 0x07, 0xF9, 0xE5, 0xF0, 0x88, 0xEB, 0x5E, 0xA6, 0x68, 0x6C, 0xF0, 0x37, 0xC7, 0xE4, 0xEF, 0xD2, 0xD6};
const BYTE AesKeyV5[] = {
0xCD, 0x7E, 0x79, 0x6F, 0x2A, 0xB2, 0x5D, 0xCB, 0x55, 0xFF, 0xC8, 0xEF, 0x83, 0x64, 0xC4, 0x70 };
const BYTE AesKeyV6[] = {
0xA9, 0x4A, 0x41, 0x95, 0xE2, 0x01, 0x43, 0x2D, 0x9B, 0xCB, 0x46, 0x04, 0x05, 0xD8, 0x4A, 0x21 };
static const BYTE SBox[] = {
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B,
0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26,
0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,
0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED,
0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F,
0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC,
0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14,
0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D,
0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F,
0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11,
0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F,
0xB0, 0x54, 0xBB, 0x16
};
void XorBlock(const BYTE *const in, const BYTE *out) // Ensure that this is always 32 bit aligned
{
/*UAA64( out, 0 ) ^= UAA64( in, 0 );
UAA64( out, 1 ) ^= UAA64( in, 1 );*/
uint_fast8_t i;
for (i = 0; i < AES_BLOCK_WORDS; i++)
{
((DWORD*)out)[i] ^= ((DWORD*)in)[i];
}
}
#define AddRoundKey(d, rk) XorBlock((const BYTE *)rk, (const BYTE *)d)
#define Mul2(word) (((word & 0x7f7f7f7f) << 1) ^ (((word & 0x80808080) >> 7) * 0x1b))
#define Mul3(word) (Mul2(word) ^ word)
#define Mul4(word) (Mul2(Mul2(word)))
#define Mul8(word) (Mul2(Mul2(Mul2(word))))
#define Mul9(word) (Mul8(word) ^ word)
#define MulB(word) (Mul8(word) ^ Mul3(word))
#define MulD(word) (Mul8(word) ^ Mul4(word) ^ word)
#define MulE(word) (Mul8(word) ^ Mul4(word) ^ Mul2(word))
//32 bit Galois Multiplication (generates bigger code than Macros)
/*static DWORD Mul(DWORD x, DWORD y)
{
DWORD result = x, yTemp = y, log2;
if (!y) return 0;
for (log2 = 0; yTemp >>= 1; log2++ )
{
result = Mul2(result);
}
return result ^ Mul(x, y - (1 << log2));
}*/
void MixColumnsR(BYTE *restrict state)
{
uint_fast8_t i = 0;
for (; i < AES_BLOCK_WORDS; i++)
{
#if defined(_CRYPTO_OPENSSL) && defined(_OPENSSL_SOFTWARE) && defined(_USE_AES_FROM_OPENSSL) //Always byte swap regardless of endianess
DWORD word = BS32(((DWORD *) state)[i]);
((DWORD *) state)[i] = BS32(MulE(word) ^ ROR32(MulB(word), 8) ^ ROR32(MulD(word), 16) ^ ROR32(Mul9(word), 24));
#else
DWORD word = LE32(((DWORD *) state)[i]);
((DWORD *) state)[i] = LE32(MulE(word) ^ ROR32(MulB(word), 8) ^ ROR32(MulD(word), 16) ^ ROR32(Mul9(word), 24));
#endif
}
}
static DWORD SubDword(DWORD v)
{
BYTE *b = (BYTE *)&v;
uint_fast8_t i = 0;
for (; i < sizeof(DWORD); i++) b[i] = SBox[b[i]];
return v;
}
void AesInitKey(AesCtx *Ctx, const BYTE *Key, int_fast8_t IsV6, int RijndaelKeyBytes)
{
int RijndaelKeyDwords = RijndaelKeyBytes / sizeof(DWORD);
Ctx->rounds = (uint_fast8_t)(RijndaelKeyDwords + 6);
static const DWORD RCon[] = {
0x00000000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000 };
uint_fast8_t i;
DWORD temp;
memcpy(Ctx->Key, Key, RijndaelKeyBytes);
for ( i = RijndaelKeyDwords; i < ( Ctx->rounds + 1 ) << 2; i++ )
{
temp = Ctx->Key[ i - 1 ];
if ( ( i % RijndaelKeyDwords ) == 0 )
temp = BE32( SubDword( ROR32( BE32(temp), 24) ) ^ RCon[ i / RijndaelKeyDwords ] );
Ctx->Key[ i ] = Ctx->Key[ i - RijndaelKeyDwords ] ^ temp;
}
if ( IsV6 )
{
BYTE *_p = (BYTE *)Ctx->Key;
_p[ 4 * 16 ] ^= 0x73;
_p[ 6 * 16 ] ^= 0x09;
_p[ 8 * 16 ] ^= 0xE4;
}
}
#if !defined(_CRYPTO_OPENSSL) || !defined(_USE_AES_FROM_OPENSSL) || defined(_OPENSSL_SOFTWARE)
static void SubBytes(BYTE *block)
{
uint_fast8_t i;
for (i = 0; i < AES_BLOCK_BYTES; i++)
block[i] = SBox[ block[i] ];
}
static void ShiftRows(BYTE *state)
{
BYTE bIn[AES_BLOCK_BYTES];
uint_fast8_t i;
memcpy(bIn, state, AES_BLOCK_BYTES);
for (i = 0; i < AES_BLOCK_BYTES; i++)
{
state[i] = bIn[(i + ((i & 3) << 2)) & 0xf];
}
};
static void MixColumns(BYTE *state)
{
uint_fast8_t i = 0;
for (; i < AES_BLOCK_WORDS; i++)
{
DWORD word = LE32(((DWORD *) state)[i]);
((DWORD *) state)[i] = LE32(Mul2(word) ^ ROR32(Mul3(word), 8) ^ ROR32(word, 16) ^ ROR32(word, 24));
}
}
void AesEncryptBlock(const AesCtx *const Ctx, BYTE *block)
{
uint_fast8_t i;
for ( i = 0 ;; i += 4 )
{
AddRoundKey(block, &Ctx->Key[ i ]);
SubBytes(block);
ShiftRows(block);
if ( i >= ( Ctx->rounds - 1 ) << 2 ) break;
MixColumns(block);
}
AddRoundKey(block, &Ctx->Key[ Ctx->rounds << 2 ]);
}
void AesCmacV4(BYTE *Message, size_t MessageSize, BYTE *MacOut)
{
size_t i;
BYTE mac[AES_BLOCK_BYTES];
AesCtx Ctx;
AesInitKey(&Ctx, AesKeyV4, FALSE, V4_KEY_BYTES);
memset(mac, 0, sizeof(mac));
memset(Message + MessageSize, 0, AES_BLOCK_BYTES);
Message[MessageSize] = 0x80;
for (i = 0; i <= MessageSize; i += AES_BLOCK_BYTES)
{
XorBlock(Message + i, mac);
AesEncryptBlock(&Ctx, mac);
}
memcpy(MacOut, mac, AES_BLOCK_BYTES);
}
#endif
#if !defined(_CRYPTO_OPENSSL) || !defined(_USE_AES_FROM_OPENSSL)
static const BYTE SBoxR[] = {
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E,
0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32,
0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49,
0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50,
0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05,
0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41,
0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8,
0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B,
0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59,
0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D,
0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63,
0x55, 0x21, 0x0C, 0x7D
};
static void ShiftRowsR(BYTE *state)
{
BYTE b[AES_BLOCK_BYTES];
uint_fast8_t i;
memcpy(b, state, AES_BLOCK_BYTES);
for (i = 0; i < AES_BLOCK_BYTES; i++)
state[i] = b[(i - ((i & 0x3) << 2)) & 0xf];
}
static void SubBytesR(BYTE *block)
{
uint_fast8_t i;
for (i = 0; i < AES_BLOCK_BYTES; i++)
block[i] = SBoxR[ block[i] ];
}
void AesEncryptCbc(const AesCtx *const Ctx, BYTE *restrict iv, BYTE *restrict data, size_t *restrict len)
{
// Pad up to blocksize inclusive
size_t i;
uint_fast8_t pad = (~*len & (AES_BLOCK_BYTES - 1)) + 1;
#if defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ == 8) // gcc 4.8 memset bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56977
for (i = 0; i < pad; i++) data[*len + i] = pad;
#else
memset(data + *len, pad, pad);
#endif
*len += pad;
if ( iv ) XorBlock(iv, data);
AesEncryptBlock(Ctx, data);
for (i = *len - AES_BLOCK_BYTES; i; i -= AES_BLOCK_BYTES)
{
XorBlock(data, data + AES_BLOCK_BYTES);
data += AES_BLOCK_BYTES;
AesEncryptBlock(Ctx, data);
}
}
void AesDecryptBlock(const AesCtx *const Ctx, BYTE *block)
{
uint_fast8_t i;
AddRoundKey(block, &Ctx->Key[ Ctx->rounds << 2 ]);
for ( i = ( Ctx->rounds - 1 ) << 2 ;; i -= 4 )
{
ShiftRowsR(block);
SubBytesR(block);
AddRoundKey(block, &Ctx->Key[ i ]);
if ( i == 0 ) break;
MixColumnsR(block);
}
}
void AesDecryptCbc(const AesCtx *const Ctx, BYTE *iv, BYTE *data, size_t len)
{
BYTE *cc;
for (cc = data + len - AES_BLOCK_BYTES; cc > data; cc -= AES_BLOCK_BYTES)
{
AesDecryptBlock(Ctx, cc);
XorBlock(cc - AES_BLOCK_BYTES, cc);
}
AesDecryptBlock(Ctx, cc);
if ( iv ) XorBlock(iv, cc);
}
#endif // _CRYPTO_OPENSSL || OPENSSL_VERSION_NUMBER < 0x10000000L

59
crypto.h Normal file
View File

@ -0,0 +1,59 @@
#ifndef __crypto_h
#define __crypto_h
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include "types.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "endian.h"
#include <stdint.h>
//#define AES_ROUNDS (10)
#define AES_KEY_BYTES (16) // 128 Bits
#define AES_BLOCK_BYTES (16)
#define AES_BLOCK_WORDS (AES_BLOCK_BYTES / sizeof(DWORD))
#define AES_KEY_DWORDS (AES_KEY_BYTES / sizeof(DWORD))
//#define V4_ROUNDS (11)
#define V4_KEY_BYTES (20) // 160 Bits
#define ROR32(v, n) ( (v) << (32 - n) | (v) >> n )
void XorBlock(const BYTE *const in, const BYTE *out);
void AesCmacV4(BYTE *data, size_t len, BYTE *hash);
extern const BYTE AesKeyV5[];
extern const BYTE AesKeyV6[];
typedef struct {
DWORD Key[48]; // Supports a maximum of 160 key bits!
uint_fast8_t rounds;
} AesCtx;
void AesInitKey(AesCtx *Ctx, const BYTE *Key, int_fast8_t IsV6, int AesKeyBytes);
void AesEncryptBlock(const AesCtx *const Ctx, BYTE *block);
void AesDecryptBlock(const AesCtx *const Ctx, BYTE *block);
void AesEncryptCbc(const AesCtx *const Ctx, BYTE *iv, BYTE *data, size_t *len);
void AesDecryptCbc(const AesCtx *const Ctx, BYTE *iv, BYTE *data, size_t len);
void MixColumnsR(BYTE *restrict state);
#if defined(_CRYPTO_OPENSSL)
#include "crypto_openssl.h"
#elif defined(_CRYPTO_POLARSSL)
#include "crypto_polarssl.h"
#elif defined(_CRYPTO_WINDOWS)
#include "crypto_windows.h"
#else
#include "crypto_internal.h"
#endif
#endif // __crypto_h

212
crypto_internal.c Normal file
View File

@ -0,0 +1,212 @@
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#if !defined(_CRYPTO_OPENSSL) && !defined(_CRYPTO_POLARSSL) && !defined(_CRYPTO_WINDOWS)
#include "crypto_internal.h"
#include "endian.h"
#define F0(x, y, z) ( ((x) & (y)) | (~(x) & (z)) )
#define F1(x, y, z) ( ((x) & (y)) | ((x) & (z)) | ((y) & (z)) )
#define SI1(x) ( ROR32(x, 2 ) ^ ROR32(x, 13) ^ ROR32(x, 22) )
#define SI2(x) ( ROR32(x, 6 ) ^ ROR32(x, 11) ^ ROR32(x, 25) )
#define SI3(x) ( ROR32(x, 7 ) ^ ROR32(x, 18) ^ ((x) >> 3 ) )
#define SI4(x) ( ROR32(x, 17) ^ ROR32(x, 19) ^ ((x) >> 10) )
static const DWORD k[] = {
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1,
0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786,
0x0FC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147,
0x06CA6351, 0x14292967, 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B,
0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A,
0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
};
static void Sha256Init(Sha256Ctx *Ctx)
{
Ctx->State[0] = 0x6A09E667;
Ctx->State[1] = 0xBB67AE85;
Ctx->State[2] = 0x3C6EF372;
Ctx->State[3] = 0xA54FF53A;
Ctx->State[4] = 0x510E527F;
Ctx->State[5] = 0x9B05688C;
Ctx->State[6] = 0x1F83D9AB;
Ctx->State[7] = 0x5BE0CD19;
Ctx->Len = 0;
}
static void Sha256ProcessBlock(Sha256Ctx *Ctx, BYTE *block)
{
unsigned int i;
DWORD w[64], temp1, temp2;
DWORD a = Ctx->State[0];
DWORD b = Ctx->State[1];
DWORD c = Ctx->State[2];
DWORD d = Ctx->State[3];
DWORD e = Ctx->State[4];
DWORD f = Ctx->State[5];
DWORD g = Ctx->State[6];
DWORD h = Ctx->State[7];
for (i = 0; i < 16; i++)
//w[ i ] = GET_UAA32BE(block, i);
w[i] = BE32(((DWORD*)block)[i]);
for (i = 16; i < 64; i++)
w[ i ] = SI4(w[ i - 2 ]) + w[ i - 7 ] + SI3(w[ i - 15 ]) + w[ i - 16 ];
for (i = 0; i < 64; i++)
{
temp1 = h + SI2(e) + F0(e, f, g) + k[ i ] + w[ i ];
temp2 = SI1(a) + F1(a, b, c);
h = g;
g = f;
f = e;
e = d + temp1;
d = c;
c = b;
b = a;
a = temp1 + temp2;
}
Ctx->State[0] += a;
Ctx->State[1] += b;
Ctx->State[2] += c;
Ctx->State[3] += d;
Ctx->State[4] += e;
Ctx->State[5] += f;
Ctx->State[6] += g;
Ctx->State[7] += h;
}
static void Sha256Update(Sha256Ctx *Ctx, BYTE *data, size_t len)
{
unsigned int b_len = Ctx->Len & 63,
r_len = (b_len ^ 63) + 1;
Ctx->Len += len;
if ( len < r_len )
{
memcpy(Ctx->Buffer + b_len, data, len);
return;
}
if ( r_len < 64 )
{
memcpy(Ctx->Buffer + b_len, data, r_len);
len -= r_len;
data += r_len;
Sha256ProcessBlock(Ctx, Ctx->Buffer);
}
for (; len >= 64; len -= 64, data += 64)
Sha256ProcessBlock(Ctx, data);
if ( len ) memcpy(Ctx->Buffer, data, len);
}
static void Sha256Finish(Sha256Ctx *Ctx, BYTE *hash)
{
unsigned int i, b_len = Ctx->Len & 63;
Ctx->Buffer[ b_len ] = 0x80;
if ( b_len ^ 63 ) memset(Ctx->Buffer + b_len + 1, 0, b_len ^ 63);
if ( b_len >= 56 )
{
Sha256ProcessBlock(Ctx, Ctx->Buffer);
memset(Ctx->Buffer, 0, 56);
}
//PUT_UAA64BE(Ctx->Buffer, (unsigned long long)(Ctx->Len * 8), 7);
((uint64_t*)Ctx->Buffer)[7] = BE64((uint64_t)Ctx->Len << 3);
Sha256ProcessBlock(Ctx, Ctx->Buffer);
for (i = 0; i < 8; i++)
//PUT_UAA32BE(hash, Ctx->State[i], i);
((DWORD*)hash)[i] = BE32(Ctx->State[i]);
}
void Sha256(BYTE *data, size_t len, BYTE *hash)
{
Sha256Ctx Ctx;
Sha256Init(&Ctx);
Sha256Update(&Ctx, data, len);
Sha256Finish(&Ctx, hash);
}
static void _Sha256HmacInit(Sha256HmacCtx *Ctx, BYTE *key, size_t klen)
{
BYTE IPad[64];
unsigned int i;
memset(IPad, 0x36, sizeof(IPad));
memset(Ctx->OPad, 0x5C, sizeof(Ctx->OPad));
if ( klen > 64 )
{
BYTE *temp = (BYTE*)alloca(32);
Sha256(key, klen, temp);
klen = 32;
key = temp;
}
for (i = 0; i < klen; i++)
{
IPad[ i ] ^= key[ i ];
Ctx->OPad[ i ] ^= key[ i ];
}
Sha256Init(&Ctx->ShaCtx);
Sha256Update(&Ctx->ShaCtx, IPad, sizeof(IPad));
}
static void _Sha256HmacUpdate(Sha256HmacCtx *Ctx, BYTE *data, size_t len)
{
Sha256Update(&Ctx->ShaCtx, data, len);
}
static void _Sha256HmacFinish(Sha256HmacCtx *Ctx, BYTE *hmac)
{
BYTE temp[32];
Sha256Finish(&Ctx->ShaCtx, temp);
Sha256Init(&Ctx->ShaCtx);
Sha256Update(&Ctx->ShaCtx, Ctx->OPad, sizeof(Ctx->OPad));
Sha256Update(&Ctx->ShaCtx, temp, sizeof(temp));
Sha256Finish(&Ctx->ShaCtx, hmac);
}
int_fast8_t Sha256Hmac(BYTE* key, BYTE* restrict data, DWORD len, BYTE* restrict hmac)
{
Sha256HmacCtx Ctx;
_Sha256HmacInit(&Ctx, key, 16);
_Sha256HmacUpdate(&Ctx, data, len);
_Sha256HmacFinish(&Ctx, hmac);
return TRUE;
}
#endif // No external Crypto

38
crypto_internal.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef __crypto_internal_h
#define __crypto_internal_h
#if !defined(_CRYPTO_OPENSSL) && !defined(_CRYPTO_POLARSSL) && !defined(_CRYPTO_WINDOWS)
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include "crypto.h"
typedef struct {
DWORD State[8];
BYTE Buffer[64];
unsigned int Len;
} Sha256Ctx;
typedef struct {
Sha256Ctx ShaCtx;
BYTE OPad[64];
} Sha256HmacCtx;
void Sha256(BYTE *data, size_t len, BYTE *hash);
int_fast8_t Sha256Hmac(BYTE* key, BYTE* restrict data, DWORD len, BYTE* restrict hmac);
//void _Sha256HmacInit(Sha256HmacCtx *Ctx, BYTE *key, size_t klen);
//void _Sha256HmacUpdate(Sha256HmacCtx *Ctx, BYTE *data, size_t len);
//void _Sha256HmacFinish(Sha256HmacCtx *Ctx, BYTE *hmac);
//#define Sha256HmacInit(c, k, l) ( _Sha256HmacInit(c, k, l), !0 )
//#define Sha256HmacUpdate(c, d, l) ( _Sha256HmacUpdate(c, d, l), !0 )
//#define Sha256HmacFinish(c, h) ( _Sha256HmacFinish(c, h), !0 )
#endif // !defined(_CRYPTO_OPENSSL) && !defined(_CRYPTO_POLARSSL) && !defined(_CRYPTO_WINDOWS)
#endif // __crypto_internal_h

269
crypto_openssl.c Normal file
View File

@ -0,0 +1,269 @@
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#if defined(_CRYPTO_OPENSSL)
#include "crypto.h"
#include "crypto_openssl.h" // Required for Eclipse only
#include <stdint.h>
#include "endian.h"
#ifndef _OPENSSL_NO_HMAC
int Sha256HmacInit_OpenSSL(HMAC_CTX *c, const void *k, int l)
{
HMAC_CTX_init(c);
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
int result =
#else
int result = TRUE;
#endif
HMAC_Init_ex(c, k, l, EVP_sha256(), NULL);
return result;
}
int Sha256HmacFinish_OpenSSL(HMAC_CTX *c, unsigned char *h, unsigned int *l)
{
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
int result =
#else
int result = !0;
#endif
HMAC_Final(c, h, l);
HMAC_CTX_cleanup(c);
return result;
}
int_fast8_t Sha256Hmac(BYTE* key, BYTE* restrict data, DWORD len, BYTE* restrict hmac)
{
HMAC_CTX Ctx;
# if OPENSSL_VERSION_NUMBER >= 0x10000000L
return
Sha256HmacInit_OpenSSL(&Ctx, key, 16) &&
HMAC_Update(&Ctx, data, len) &&
Sha256HmacFinish_OpenSSL(&Ctx, hmac, NULL);
# else // OpenSSL 0.9.x
Sha256HmacInit_OpenSSL(&Ctx, key, 16);
HMAC_Update(&Ctx, data, len);
Sha256HmacFinish_OpenSSL(&Ctx, hmac, NULL);
return TRUE;
# endif
}
#else // _OPENSSL_NO_HMAC (some routers have OpenSSL without support for HMAC)
int _Sha256HmacInit(Sha256HmacCtx *Ctx, BYTE *key, size_t klen)
{
BYTE IPad[64];
unsigned int i;
memset(IPad, 0x36, sizeof(IPad));
memset(Ctx->OPad, 0x5C, sizeof(Ctx->OPad));
if ( klen > 64 )
{
BYTE *temp = (BYTE*)alloca(32);
SHA256(key, klen, temp);
klen = 32;
key = temp;
}
for (i = 0; i < klen; i++)
{
IPad[ i ] ^= key[ i ];
Ctx->OPad[ i ] ^= key[ i ];
}
SHA256_Init(&Ctx->ShaCtx);
return SHA256_Update(&Ctx->ShaCtx, IPad, sizeof(IPad));
}
int _Sha256HmacUpdate(Sha256HmacCtx *Ctx, BYTE *data, size_t len)
{
int rc = SHA256_Update(&Ctx->ShaCtx, data, len);
return rc;
}
int _Sha256HmacFinish(Sha256HmacCtx *Ctx, BYTE *hmac, void* dummy)
{
BYTE temp[32];
SHA256_Final(temp, &Ctx->ShaCtx);
SHA256_Init(&Ctx->ShaCtx);
SHA256_Update(&Ctx->ShaCtx, Ctx->OPad, sizeof(Ctx->OPad));
SHA256_Update(&Ctx->ShaCtx, temp, sizeof(temp));
return SHA256_Final(hmac, &Ctx->ShaCtx);
}
int_fast8_t Sha256Hmac(BYTE* key, BYTE* restrict data, DWORD len, BYTE* restrict hmac)
{
Sha256HmacCtx Ctx;
_Sha256HmacInit(&Ctx, key, 16);
_Sha256HmacUpdate(&Ctx, data, len);
_Sha256HmacFinish(&Ctx, hmac, NULL);
return TRUE;
}
#endif
#if defined(_USE_AES_FROM_OPENSSL)
void TransformOpenSslEncryptKey(AES_KEY *k, const AesCtx *const Ctx)
{
uint32_t *rk_OpenSSL = k->rd_key, *rk_vlmcsd = (uint32_t*)Ctx->Key;
k->rounds = Ctx->rounds;
for (; rk_OpenSSL < k->rd_key + ((k->rounds + 1) << 2); rk_OpenSSL++, rk_vlmcsd++)
{
#ifdef _OPENSSL_SOFTWARE
*rk_OpenSSL = BE32(*rk_vlmcsd);
#else
*rk_OpenSSL = LE32(*rk_vlmcsd);
#endif
}
}
void TransformOpenSslDecryptKey(AES_KEY *k, const AesCtx *const Ctx)
{
uint_fast8_t i;
#ifdef _DEBUG_OPENSSL
AES_set_decrypt_key((BYTE*)Ctx->Key, 128, k);
errorout("Correct V5 round key:");
for (i = 0; i < (Ctx->rounds + 1) << 4; i++)
{
if (!(i % 16)) errorout("\n");
if (!(i % 4)) errorout(" ");
errorout("%02X", ((BYTE*)(k->rd_key))[i]);
}
errorout("\n");
#endif
k->rounds = Ctx->rounds;
/* invert the order of the round keys blockwise (1 Block = AES_BLOCK_SIZE = 16): */
for (i = 0; i < (Ctx->rounds + 1) << 2; i++)
{
#ifdef _OPENSSL_SOFTWARE
k->rd_key[((Ctx->rounds-(i >> 2)) << 2) + (i & 3)] = BE32(Ctx->Key[i]);
#else
k->rd_key[((Ctx->rounds-(i >> 2)) << 2) + (i & 3)] = LE32(Ctx->Key[i]);
#endif
}
/* apply the inverse MixColumn transform to all round keys but the first and the last: */
uint32_t *rk = k->rd_key + 4;
for (i = 0; i < (Ctx->rounds - 1); i++)
{
MixColumnsR((BYTE*)(rk + (i << 2)));
}
#ifdef _DEBUG_OPENSSL
errorout("Real round key:");
for (i = 0; i < (Ctx->rounds + 1) << 4; i++)
{
if (!(i % 16)) errorout("\n");
if (!(i % 4)) errorout(" ");
errorout("%02X", ((BYTE*)(k->rd_key))[i]);
}
errorout("\n");
#endif
}
static BYTE NullIV[AES_BLOCK_SIZE + 8]; // OpenSSL may overwrite bytes behind IV
void AesEncryptCbc(const AesCtx *const Ctx, BYTE *iv, BYTE *data, size_t *len)
{
AES_KEY k;
// OpenSSL overwrites IV plus 4 bytes
BYTE localIV[24]; // 4 spare bytes for safety
if (iv) memcpy(localIV, iv, AES_BLOCK_SIZE);
// OpenSSL Low-Level APIs do not pad. Could use EVP API instead but needs more code to access the expanded key
uint_fast8_t pad = (~*len & (AES_BLOCK_SIZE - 1)) + 1;
#if defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ == 8) // gcc 4.8 memset bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56977
size_t i;
for (i = 0; i < pad; i++) data[*len + i] = pad;
#else
memset(data + *len, pad, pad);
#endif
*len += pad;
memset(NullIV, 0, sizeof(NullIV));
TransformOpenSslEncryptKey(&k, Ctx);
AES_cbc_encrypt(data, data, *len, &k, iv ? localIV : NullIV, AES_ENCRYPT);
}
void AesDecryptBlock(const AesCtx *const Ctx, BYTE *block)
{
AES_KEY k;
TransformOpenSslDecryptKey(&k, Ctx);
AES_decrypt(block, block, &k);
}
#if defined(_CRYPTO_OPENSSL) && defined(_USE_AES_FROM_OPENSSL) && !defined(_OPENSSL_SOFTWARE)
void AesEncryptBlock(const AesCtx *const Ctx, BYTE *block)
{
AES_KEY k;
TransformOpenSslEncryptKey(&k, Ctx);
AES_encrypt(block, block, &k);
}
#endif
void AesDecryptCbc(const AesCtx *const Ctx, BYTE *iv, BYTE *data, size_t len)
{
AES_KEY k;
memset(NullIV, 0, sizeof(NullIV));
TransformOpenSslDecryptKey(&k, Ctx);
AES_cbc_encrypt(data, data, len, &k, iv ? iv : NullIV, AES_DECRYPT);
}
#ifndef _OPENSSL_SOFTWARE
void AesCmacV4(BYTE *Message, size_t MessageSize, BYTE *HashOut)
{
size_t i;
BYTE hash[AES_BLOCK_BYTES];
AesCtx Ctx;
AES_KEY k;
AesInitKey(&Ctx, AesKeyV4, FALSE, V4_KEY_BYTES);
TransformOpenSslEncryptKey(&k, &Ctx);
memset(hash, 0, sizeof(hash));
memset(Message + MessageSize, 0, AES_BLOCK_BYTES);
Message[MessageSize] = 0x80;
for (i = 0; i <= MessageSize; i += AES_BLOCK_BYTES)
{
XorBlock(Message + i, hash);
AES_encrypt(hash, hash, &k);
}
memcpy(HashOut, hash, AES_BLOCK_BYTES);
}
#endif // !_OPENSSL_SOFTWARE
#endif // defined(_USE_AES_FROM_OPENSSL)
#endif // _CRYPTO_OPENSSL

53
crypto_openssl.h Normal file
View File

@ -0,0 +1,53 @@
#ifndef __crypto_openssl_h
#define __crypto_openssl_h
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include <openssl/opensslv.h>
#include <openssl/sha.h>
#include <openssl/hmac.h>
#include <openssl/aes.h>
#include "crypto.h"
#define Sha256(d, l, h) SHA256(d, l, h)
int_fast8_t Sha256Hmac(BYTE* key, BYTE* restrict data, DWORD len, BYTE* restrict hmac);
#ifndef _OPENSSL_NO_HMAC
#define Sha256HmacCtx HMAC_CTX
#else
typedef struct {
SHA256_CTX ShaCtx;
BYTE OPad[64];
} Sha256HmacCtx;
#endif
#ifndef _OPENSSL_NO_HMAC
#define Sha256HmacInit(c, k, l) Sha256HmacInit_OpenSSL(c, k, l)
#define Sha256HmacFinish(c, h) Sha256HmacFinish_OpenSSL(c, h, NULL)
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
#define Sha256HmacUpdate(c, d, l) HMAC_Update(c, d, l)
#else // OPENSSL_VERSION_NUMBER < 0x10000000L
#define Sha256HmacUpdate(c, d, l) (HMAC_Update(c, d, l), !0)
#endif // OPENSSL_VERSION_NUMBER >= 0x10000000L
int Sha256HmacInit_OpenSSL(HMAC_CTX *c, const void *k, int l);
int Sha256HmacFinish_OpenSSL(HMAC_CTX *c, unsigned char *h, unsigned int *l);
#else // _OPENSSL_NO_HMAC
int _Sha256HmacInit(Sha256HmacCtx *Ctx, BYTE *key, size_t klen);
int _Sha256HmacUpdate(Sha256HmacCtx *Ctx, BYTE *data, size_t len);
int _Sha256HmacFinish(Sha256HmacCtx *Ctx, BYTE *hmac, void* dummy);
#define Sha256HmacInit(c, k, l) _Sha256HmacInit(c, k, l)
#define Sha256HmacFinish(c, h) _Sha256HmacFinish(c, h, NULL)
#define Sha256HmacUpdate(c, d, l) _Sha256HmacUpdate(c, d, l)
#endif // _OPENSSL_NO_HMAC
extern const BYTE AesKeyV4[];
#endif // __crypto_openssl_h

39
crypto_polarssl.h Normal file
View File

@ -0,0 +1,39 @@
#ifndef __crypto_polarssl_h
#define __crypto_polarssl_h
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include <polarssl/version.h>
#include "crypto.h"
#if POLARSSL_VERSION_NUMBER >= 0x01030000
#include <polarssl/sha256.h>
#define Sha256(d, l, h) sha256(d, l, h, 0)
#define Sha256HmacCtx sha256_context
#define Sha256HmacInit(c, k, l) ( sha256_hmac_starts(c, k, l, 0), !0 )
#define Sha256HmacUpdate(c, d, l) ( sha256_hmac_update(c, d, l), !0 )
#define Sha256HmacFinish(c, h) ( sha256_hmac_finish(c, h), !0 )
#define Sha256Hmac(k, d, l, h) ( sha256_hmac(k, 16, d, l, h, FALSE), !0 )
#else // POLARSSL_VERSION_NUMBER
#include <polarssl/sha2.h>
#define Sha256(d, l, h) sha2(d, l, h, 0)
#define Sha256HmacCtx sha2_context
#define Sha256HmacInit(c, k, l) ( sha2_hmac_starts(c, k, l, 0), !0 )
#define Sha256HmacUpdate(c, d, l) ( sha2_hmac_update(c, d, l), !0 )
#define Sha256HmacFinish(c, h) ( sha2_hmac_finish(c, h), !0 )
#define Sha256Hmac(k, d, l, h) ( sha2_hmac(k, 16, d, l, h, FALSE), !0 )
#endif // POLARSSL_VERSION_NUMBER
#endif // __crypto_polarssl_h

170
crypto_windows.c Normal file
View File

@ -0,0 +1,170 @@
/*
* crypto_windows.c
*/
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#ifdef _CRYPTO_WINDOWS
#if !_WIN32 && !__CYGWIN__
#error You cannot use Windows CryptoAPI on non-Windows platforms
#else // _WIN32 || __CYGWIN__
#include "crypto_windows.h"
typedef struct _HMAC_KEYBLOB
{
BLOBHEADER hdr;
DWORD dwKeySize;
BYTE KeyData[16];
} HMAC_KEYBLOB;
/*
* MingW and Cygwin define NULL as ((void*)0) (Posix standard) which you can't assign to
* non-pointer types without compiler warning. Thus we use the following
*/
#define NULLHANDLE 0
#define NULLFLAGS 0
static HCRYPTPROV hRsaAesProvider = 0; // Needs to be initialized just once per process
static int_fast8_t AcquireCryptContext()
{
if (!hRsaAesProvider)
{
return CryptAcquireContextW
(
&hRsaAesProvider, // Provider handle
NULL, // No key container name
NULL, // Default provider
PROV_RSA_AES, // Provides SHA and AES
CRYPT_VERIFYCONTEXT // We don't need access to persistent keys
);
}
return TRUE;
}
int_fast8_t Sha256(BYTE* restrict data, DWORD DataSize, BYTE* restrict hash)
{
HCRYPTHASH hHash = 0;
DWORD HashSize = 32;
int_fast8_t success =
AcquireCryptContext() &&
CryptCreateHash
(
hRsaAesProvider,// Provider handle
CALG_SHA_256, // Algorithm
NULLHANDLE, // SHA256 requires no key
NULLFLAGS, // Use default flags
&hHash // Handle for hashing
) &&
CryptHashData
(
hHash, // Handle
data, // data to hash
DataSize, // size of data
NULLFLAGS // Use default flags
) &&
CryptGetHashParam
(
hHash, // Handle
HP_HASHVAL, // what you actually want to get (the resulting hash)
hash, // data to retrieve
&HashSize, // size of data
NULLFLAGS // currently reserved (as of this writing)
);
if (hHash) CryptDestroyHash(hHash);
return success;
}
int_fast8_t Sha256Hmac(const BYTE* key, BYTE* restrict data, DWORD len, BYTE* restrict hmac)
{
# ifndef USE_THREADS // In fork() mode thread-safety is not required
static
# endif
HMAC_KEYBLOB hmackeyblob = {
// Type, Version, Algorithm
{ PLAINTEXTKEYBLOB, CUR_BLOB_VERSION, 0, CALG_RC2 },
// Key length
16
};
HCRYPTKEY hKey = NULLHANDLE;
HCRYPTHASH hHmacHash = NULLHANDLE;
HMAC_INFO HmacInfo = { 0 };
DWORD dwHmacSize = 32;
HmacInfo.HashAlgid = CALG_SHA_256;
memcpy(hmackeyblob.KeyData, key, sizeof(hmackeyblob.KeyData));
BOOL success =
AcquireCryptContext() &&
CryptImportKey
(
hRsaAesProvider, // provider handle
(PBYTE)&hmackeyblob, // the actual key MS blob format
sizeof(HMAC_KEYBLOB), // size of the entire blob
NULLHANDLE, // password/key for the key store (none required here)
NULLFLAGS, // default flags
&hKey // key handle to retrieve (must be kept until you finish hashing)
) &&
CryptCreateHash
(
hRsaAesProvider, // provider handle
CALG_HMAC, // the actual key MS blob format
hKey, // size of the entire blob
NULLFLAGS, // password/key for the key store (none required here)
&hHmacHash // default flags
) && // key handle to retrieve (must be kept until you finish hashing)
CryptSetHashParam
(
hHmacHash, // hash handle
HP_HMAC_INFO, // parameter you want to set
(PBYTE)&HmacInfo, // the HMAC parameters (SHA256 with default ipad and opad)
NULLFLAGS // flags are reserved up to Windows 8.1
) &&
CryptHashData
(
hHmacHash, // hash handle
data, // Pointer to data you want to hash
len, // data length
NULLFLAGS // default flags
) &&
CryptGetHashParam
(
hHmacHash, // hash handle
HP_HASHVAL, // what you actually want to get (the resulting HMAC)
hmac, // data to retrieve
&dwHmacSize, // size of data
NULLFLAGS // currently reserved (as of this writing)
);
if (hKey) CryptDestroyKey(hKey);
if (hHmacHash) CryptDestroyHash(hHmacHash);
return success;
}
#endif // _WIN32 || __CYGWIN__
#endif // _CRYPTO_WINDOWS

31
crypto_windows.h Normal file
View File

@ -0,0 +1,31 @@
/*
* crypto_windows.h
*/
#ifdef _CRYPTO_WINDOWS
#ifndef CRYPTO_WINDOWS_H_
#define CRYPTO_WINDOWS_H_
#if !_WIN32 && !__CYGWIN__
#error You cannot use Windows CryptoAPI on non-Windows platforms
#else // _WIN32 || __CYGWIN__
#include "types.h"
typedef struct _Sha2356HmacCtx
{
HCRYPTHASH hHmac;
HCRYPTKEY hKey;
} Sha256HmacCtx;
int_fast8_t Sha256(BYTE *data, DWORD len, BYTE *hash);
int_fast8_t Sha256Hmac(const BYTE* key, BYTE* restrict data, DWORD len, BYTE* restrict hmac);
/*int_fast8_t Sha256HmacInit(Sha256HmacCtx *Ctx, BYTE *key, uint8_t keySize);
int_fast8_t Sha256HmacUpdate(Sha256HmacCtx *Ctx, BYTE *data, DWORD len);
int_fast8_t Sha256HmacFinish(Sha256HmacCtx *Ctx, BYTE *hmac);*/
#endif // _WIN32 || __CYGWIN__
#endif /* CRYPTO_WINDOWS_H_ */
#endif // _CRYPTO_WINDOWS

330
dns_srv.c Normal file
View File

@ -0,0 +1,330 @@
/*
* dns_srv.c
*
* This file contains the code for KMS SRV record lookup in DNS (_vlmcs._tcp.example.com IN SRV 0 0 1688 mykms.example.com)
*
*/
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#ifndef NO_DNS
#include "dns_srv.h"
#include <string.h>
#include <stdio.h>
#ifndef _WIN32
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <netdb.h>
//#ifndef DNS_PARSER_INTERNAL
#if __ANDROID__
#include <netinet/in.h>
#include "nameser.h"
#include "resolv.h"
#else // other Unix non-Android
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
#endif // other Unix non-Android
//#endif // DNS_PARSER_INTERNAL
#else // WIN32
#include <windns.h>
#endif // WIN32
#include "helpers.h"
#include "output.h"
#include "endian.h"
#if defined(DNS_PARSER_INTERNAL) && !defined(_WIN32)
#include "ns_name.h"
#include "ns_parse.h"
// Define macros to redirect DNS parser functions to internal versions
#undef ns_msg
#undef ns_initparse
#undef ns_parserr
#undef ns_rr
#undef ns_name_uncompress
#undef ns_msg_base
#undef ns_msg_end
#undef ns_rr_rdata
#undef ns_rr_type
#undef ns_msg_count
#undef ns_rr_class
#undef ns_s_an
#define ns_msg ns_msg_vlmcsd
#define ns_initparse ns_initparse_vlmcsd
#define ns_parserr ns_parserr_vlmcsd
#define ns_rr ns_rr_vlmcsd
#define ns_name_uncompress ns_name_uncompress_vlmcsd
#define ns_msg_base ns_msg_base_vlmcsd
#define ns_msg_end ns_msg_end_vlmcsd
#define ns_rr_rdata ns_rr_rdata_vlmcsd
#define ns_rr_type ns_rr_type_vlmcsd
#define ns_msg_count ns_msg_count_vlmcsd
#define ns_rr_class ns_rr_class_vlmcsd
#define ns_s_an ns_s_an_vlmcsd
#ifndef NS_MAXLABEL
#define NS_MAXLABEL 63
#endif
#endif // defined(DNS_PARSER_INTERNAL) && !defined(_WIN32)
//TODO: maybe move to helpers.c
static unsigned int isqrt(unsigned int n)
{
unsigned int c = 0x8000;
unsigned int g = 0x8000;
for(;;)
{
if(g*g > n)
g ^= c;
c >>= 1;
if(c == 0) return g;
g |= c;
}
}
/*
* Compare function for qsort to sort SRV records by priority and weight
* random_weight must be product of weight from SRV record and square root of a random number
*/
static int kmsServerListCompareFunc1(const void* a, const void* b)
{
if ( !a && !b) return 0;
if ( a && !b) return -1;
if ( !a && b) return 1;
int priority_order = (int)((*(kms_server_dns_ptr*)a)->priority) - ((int)(*(kms_server_dns_ptr*)b)->priority);
if (priority_order) return priority_order;
return (int)((*(kms_server_dns_ptr*)b)->random_weight) - ((int)(*(kms_server_dns_ptr*)a)->random_weight);
}
/* Sort resulting SRV records */
void sortSrvRecords(kms_server_dns_ptr* serverlist, const int answers)
{
int i;
for (i = 0; i < answers; i++)
{
serverlist[i]->random_weight = (rand32() % 256) * isqrt(serverlist[i]->weight * 1000);
}
qsort(serverlist, answers, sizeof(kms_server_dns_ptr), kmsServerListCompareFunc1);
}
#define RECEIVE_BUFFER_SIZE 2048
#ifndef _WIN32 // UNIX resolver
/*
* Retrieves a raw DNS answer (a buffer of what came over the net)
* Result must be parsed
*/
static int getDnsRawAnswer(const char *restrict query, unsigned char** receive_buffer)
{
if (res_init() < 0)
{
errorout("Cannot initialize resolver: %s", strerror(errno));
return 0;
}
//if(!(*receive_buffer = (unsigned char*)malloc(RECEIVE_BUFFER_SIZE))) OutOfMemory();
*receive_buffer = (unsigned char*)vlmcsd_malloc(RECEIVE_BUFFER_SIZE);
int bytes_received;
if (*query == '.')
{
# if __ANDROID__ || __GLIBC__ /* including __UCLIBC__*/ || __APPLE__ || __CYGWIN__ || __FreeBSD__ || __NetBSD__ || __DragonFly__ || __OpenBSD__ || __sun__
bytes_received = res_querydomain("_vlmcs._tcp", query + 1, ns_c_in, ns_t_srv, *receive_buffer, RECEIVE_BUFFER_SIZE);
# else
char* querystring = (char*)alloca(strlen(query) + 12);
strcpy(querystring, "_vlmcs._tcp");
strcat(querystring, query);
bytes_received = res_query(querystring, C_IN, ns_t_srv, *receive_buffer, RECEIVE_BUFFER_SIZE);
# endif
}
else
{
bytes_received = res_search("_vlmcs._tcp", ns_c_in, ns_t_srv, *receive_buffer, RECEIVE_BUFFER_SIZE);
}
if (bytes_received < 0)
{
errorout("Fatal: DNS query to %s%s failed: %s\n", "_vlmcs._tcp", *query == '.' ? query : "", hstrerror(h_errno));
return 0;
}
return bytes_received;
}
/*
* Retrieves an unsorted array of SRV records (Unix / Posix)
*/
int getKmsServerList(kms_server_dns_ptr** serverlist, const char *restrict query)
{
unsigned char* receive_buffer;
*serverlist = NULL;
int bytes_received = getDnsRawAnswer(query, &receive_buffer);
if (bytes_received == 0) return 0;
ns_msg msg;
if (ns_initparse(receive_buffer, bytes_received, &msg) < 0)
{
errorout("Fatal: Incorrect DNS response: %s\n", strerror(errno));
free(receive_buffer);
return 0;
}
uint16_t i, answers = ns_msg_count(msg, ns_s_an);
//if(!(*serverlist = (kms_server_dns_ptr*)malloc(answers * sizeof(kms_server_dns_ptr)))) OutOfMemory();
*serverlist = (kms_server_dns_ptr*)malloc(answers * sizeof(kms_server_dns_ptr));
memset(*serverlist, 0, answers * sizeof(kms_server_dns_ptr));
for (i = 0; i < answers; i++)
{
ns_rr rr;
if (ns_parserr(&msg, ns_s_an, i, &rr) < 0)
{
errorout("Warning: Error in DNS resource record: %s\n", strerror(errno));
continue;
}
if (ns_rr_type(rr) != ns_t_srv)
{
errorout("Warning: DNS server returned non-SRV record\n");
continue;
}
if (ns_rr_class(rr) != ns_c_in)
{
errorout("Warning: DNS server returned non-IN class record\n");
continue;
}
dns_srv_record_ptr srvrecord = (dns_srv_record_ptr)ns_rr_rdata(rr);
kms_server_dns_ptr kms_server = (kms_server_dns_ptr)vlmcsd_malloc(sizeof(kms_server_dns_t));
(*serverlist)[i] = kms_server;
if (ns_name_uncompress(ns_msg_base(msg), ns_msg_end(msg), srvrecord->name, kms_server->serverName, sizeof(kms_server->serverName)) < 0)
{
errorout("Warning: No valid DNS name returned in SRV record: %s\n", strerror(errno));
continue;
}
sprintf(kms_server->serverName + strlen(kms_server->serverName), ":%hu", GET_UA16BE(&srvrecord->port));
kms_server->priority = GET_UA16BE(&srvrecord->priority);
kms_server->weight = GET_UA16BE(&srvrecord->weight);
}
free(receive_buffer);
return answers;
}
#else // WIN32 (Windows Resolver)
/*
* Retrieves an unsorted array of SRV records (Windows)
*/
int getKmsServerList(kms_server_dns_ptr** serverlist, const char *const restrict query)
{
# define MAX_DNS_NAME_SIZE 254
*serverlist = NULL;
PDNS_RECORD receive_buffer;
char dnsDomain[MAX_DNS_NAME_SIZE];
char FqdnQuery[MAX_DNS_NAME_SIZE];
DWORD size = MAX_DNS_NAME_SIZE;
DNS_STATUS result;
int answers = 0;
PDNS_RECORD dns_iterator;
if (*query == '-')
{
if (!GetComputerNameExA(ComputerNamePhysicalDnsDomain, dnsDomain, &size))
{
errorout("Fatal: Could not determine computer's DNS name: %s\n", vlmcsd_strerror(GetLastError()));
return 0;
}
strcpy(FqdnQuery, "_vlmcs._tcp.");
strncat(FqdnQuery, dnsDomain, MAX_DNS_NAME_SIZE - 12);
}
else
{
strcpy(FqdnQuery, "_vlmcs._tcp");
strncat(FqdnQuery, query, MAX_DNS_NAME_SIZE - 11);
}
if ((result = DnsQuery_UTF8(FqdnQuery, DNS_TYPE_SRV, 0, NULL, &receive_buffer, NULL)) != 0)
{
errorout("Fatal: DNS query to %s failed: %s\n", FqdnQuery, vlmcsd_strerror(result));
return 0;
}
for (dns_iterator = receive_buffer; dns_iterator; dns_iterator = dns_iterator->pNext)
{
if (dns_iterator->Flags.S.Section != 1) continue;
if (dns_iterator->wType != DNS_TYPE_SRV)
{
errorout("Warning: DNS server returned non-SRV record\n");
continue;
}
answers++;
}
*serverlist = (kms_server_dns_ptr*)vlmcsd_malloc(answers * sizeof(kms_server_dns_ptr));
for (answers = 0, dns_iterator = receive_buffer; dns_iterator; dns_iterator = dns_iterator->pNext)
{
if (dns_iterator->wType != DNS_TYPE_SRV) continue;
kms_server_dns_ptr kms_server = (kms_server_dns_ptr)vlmcsd_malloc(sizeof(kms_server_dns_t));
memset(kms_server, 0, sizeof(kms_server_dns_t));
snprintf(kms_server->serverName, sizeof(kms_server->serverName), "%s:%hu", dns_iterator->Data.SRV.pNameTarget, dns_iterator->Data.SRV.wPort);
kms_server->priority = dns_iterator->Data.SRV.wPriority;
kms_server->weight = dns_iterator->Data.SRV.wWeight;
(*serverlist)[answers++] = kms_server;
}
//sortSrvRecords(*serverlist, answers, NoSrvRecordPriority);
DnsRecordListFree(receive_buffer, DnsFreeRecordList);
return answers;
# undef MAX_DNS_NAME_SIZE
}
#endif // _WIN32
#undef RECEIVE_BUFFER_SIZE
#endif // NO_DNS

103
dns_srv.h Normal file
View File

@ -0,0 +1,103 @@
/*
* dns_srv.h
*
*/
#ifndef DNS_SRV_H_
#define DNS_SRV_H_
#ifndef NO_DNS
#include "types.h"
typedef struct
{
uint32_t random_weight;
uint16_t priority;
uint16_t weight;
char serverName[260];
} kms_server_dns_t, *kms_server_dns_ptr;
typedef struct
{
uint16_t priority;
uint16_t weight;
uint16_t port;
unsigned char name[1];
} dns_srv_record_t, *dns_srv_record_ptr;
#if __OpenBSD__
typedef enum __ns_type {
ns_t_invalid = 0, /*%< Cookie. */
ns_t_a = 1, /*%< Host address. */
ns_t_ns = 2, /*%< Authoritative server. */
ns_t_md = 3, /*%< Mail destination. */
ns_t_mf = 4, /*%< Mail forwarder. */
ns_t_cname = 5, /*%< Canonical name. */
ns_t_soa = 6, /*%< Start of authority zone. */
ns_t_mb = 7, /*%< Mailbox domain name. */
ns_t_mg = 8, /*%< Mail group member. */
ns_t_mr = 9, /*%< Mail rename name. */
ns_t_null = 10, /*%< Null resource record. */
ns_t_wks = 11, /*%< Well known service. */
ns_t_ptr = 12, /*%< Domain name pointer. */
ns_t_hinfo = 13, /*%< Host information. */
ns_t_minfo = 14, /*%< Mailbox information. */
ns_t_mx = 15, /*%< Mail routing information. */
ns_t_txt = 16, /*%< Text strings. */
ns_t_rp = 17, /*%< Responsible person. */
ns_t_afsdb = 18, /*%< AFS cell database. */
ns_t_x25 = 19, /*%< X_25 calling address. */
ns_t_isdn = 20, /*%< ISDN calling address. */
ns_t_rt = 21, /*%< Router. */
ns_t_nsap = 22, /*%< NSAP address. */
ns_t_nsap_ptr = 23, /*%< Reverse NSAP lookup (deprecated). */
ns_t_sig = 24, /*%< Security signature. */
ns_t_key = 25, /*%< Security key. */
ns_t_px = 26, /*%< X.400 mail mapping. */
ns_t_gpos = 27, /*%< Geographical position (withdrawn). */
ns_t_aaaa = 28, /*%< Ip6 Address. */
ns_t_loc = 29, /*%< Location Information. */
ns_t_nxt = 30, /*%< Next domain (security). */
ns_t_eid = 31, /*%< Endpoint identifier. */
ns_t_nimloc = 32, /*%< Nimrod Locator. */
ns_t_srv = 33, /*%< Server Selection. */
ns_t_atma = 34, /*%< ATM Address */
ns_t_naptr = 35, /*%< Naming Authority PoinTeR */
ns_t_kx = 36, /*%< Key Exchange */
ns_t_cert = 37, /*%< Certification record */
ns_t_a6 = 38, /*%< IPv6 address (deprecated, use ns_t_aaaa) */
ns_t_dname = 39, /*%< Non-terminal DNAME (for IPv6) */
ns_t_sink = 40, /*%< Kitchen sink (experimentatl) */
ns_t_opt = 41, /*%< EDNS0 option (meta-RR) */
ns_t_apl = 42, /*%< Address prefix list (RFC3123) */
ns_t_tkey = 249, /*%< Transaction key */
ns_t_tsig = 250, /*%< Transaction signature. */
ns_t_ixfr = 251, /*%< Incremental zone transfer. */
ns_t_axfr = 252, /*%< Transfer zone of authority. */
ns_t_mailb = 253, /*%< Transfer mailbox records. */
ns_t_maila = 254, /*%< Transfer mail agent records. */
ns_t_any = 255, /*%< Wildcard match. */
ns_t_zxfr = 256, /*%< BIND-specific, nonstandard. */
ns_t_max = 65536
} ns_type;
typedef enum __ns_class {
ns_c_invalid = 0, /*%< Cookie. */
ns_c_in = 1, /*%< Internet. */
ns_c_2 = 2, /*%< unallocated/unsupported. */
ns_c_chaos = 3, /*%< MIT Chaos-net. */
ns_c_hs = 4, /*%< MIT Hesiod. */
/* Query class values which do not appear in resource records */
ns_c_none = 254, /*%< for prereq. sections in update requests */
ns_c_any = 255, /*%< Wildcard match. */
ns_c_max = 65536
} ns_class;
#endif
int getKmsServerList(kms_server_dns_ptr** serverlist, const char *restrict query);
void sortSrvRecords(kms_server_dns_ptr* serverlist, const int answers);
#endif // NO_DNS
#endif /* DNS_SRV_H_ */

171
endian.c Normal file
View File

@ -0,0 +1,171 @@
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include "endian.h"
#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) \
&& defined(BS16) && defined(BS32) && defined(BS64)
#else // ! defined(__BYTE_ORDER)
void PUT_UAA64BE(void *p, unsigned long long v, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned long long *)p)[i];
_p[ 0 ] = v >> 56;
_p[ 1 ] = v >> 48;
_p[ 2 ] = v >> 40;
_p[ 3 ] = v >> 32;
_p[ 4 ] = v >> 24;
_p[ 5 ] = v >> 16;
_p[ 6 ] = v >> 8;
_p[ 7 ] = v;
}
void PUT_UAA32BE(void *p, unsigned int v, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned int *)p)[i];
_p[ 0 ] = v >> 24;
_p[ 1 ] = v >> 16;
_p[ 2 ] = v >> 8;
_p[ 3 ] = v;
}
void PUT_UAA16BE(void *p, unsigned short v, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned short *)p)[i];
_p[ 0 ] = v >> 8;
_p[ 1 ] = v;
}
void PUT_UAA64LE(void *p, unsigned long long v, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned long long *)p)[i];
_p[ 0 ] = v;
_p[ 1 ] = v >> 8;
_p[ 2 ] = v >> 16;
_p[ 3 ] = v >> 24;
_p[ 4 ] = v >> 32;
_p[ 5 ] = v >> 40;
_p[ 6 ] = v >> 48;
_p[ 7 ] = v >> 56;
}
void PUT_UAA32LE(void *p, unsigned int v, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned int *)p)[i];
_p[ 0 ] = v;
_p[ 1 ] = v >> 8;
_p[ 2 ] = v >> 16;
_p[ 3 ] = v >> 24;
}
void PUT_UAA16LE(void *p, unsigned short v, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned short *)p)[i];
_p[ 0 ] = v;
_p[ 1 ] = v >> 8;
}
unsigned long long GET_UAA64BE(void *p, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned long long *)p)[i];
return
(unsigned long long)_p[ 0 ] << 56 |
(unsigned long long)_p[ 1 ] << 48 |
(unsigned long long)_p[ 2 ] << 40 |
(unsigned long long)_p[ 3 ] << 32 |
(unsigned long long)_p[ 4 ] << 24 |
(unsigned long long)_p[ 5 ] << 16 |
(unsigned long long)_p[ 6 ] << 8 |
(unsigned long long)_p[ 7 ];
}
unsigned int GET_UAA32BE(void *p, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned int *)p)[i];
return
(unsigned int)_p[ 0 ] << 24 |
(unsigned int)_p[ 1 ] << 16 |
(unsigned int)_p[ 2 ] << 8 |
(unsigned int)_p[ 3 ];
}
unsigned short GET_UAA16BE(void *p, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned short *)p)[i];
return
(unsigned short)_p[ 0 ] << 8 |
(unsigned short)_p[ 1 ];
}
unsigned long long GET_UAA64LE(void *p, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned long long *)p)[i];
return
(unsigned long long)_p[ 0 ] |
(unsigned long long)_p[ 1 ] << 8 |
(unsigned long long)_p[ 2 ] << 16 |
(unsigned long long)_p[ 3 ] << 24 |
(unsigned long long)_p[ 4 ] << 32 |
(unsigned long long)_p[ 5 ] << 40 |
(unsigned long long)_p[ 6 ] << 48 |
(unsigned long long)_p[ 7 ] << 56;
}
unsigned int GET_UAA32LE(void *p, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned int *)p)[i];
return
(unsigned int)_p[ 0 ] |
(unsigned int)_p[ 1 ] << 8 |
(unsigned int)_p[ 2 ] << 16 |
(unsigned int)_p[ 3 ] << 24;
}
unsigned short GET_UAA16LE(void *p, unsigned int i)
{
unsigned char *_p = (unsigned char *)&((unsigned short *)p)[i];
return
(unsigned short)_p[ 0 ] |
(unsigned short)_p[ 1 ] << 8;
}
unsigned short BE16(unsigned short x)
{
return GET_UAA16BE(&x, 0);
}
unsigned short LE16(unsigned short x)
{
return GET_UAA16LE(&x, 0);
}
unsigned int BE32(unsigned int x)
{
return GET_UAA32BE(&x, 0);
}
unsigned int LE32(unsigned int x)
{
return GET_UAA32LE(&x, 0);
}
unsigned long long BE64(unsigned long long x)
{
return GET_UAA64BE(&x, 0);
}
inline unsigned long long LE64(unsigned long long x)
{
return GET_UAA64LE(&x, 0);
}
#endif // defined(__BYTE_ORDER)

296
endian.h Normal file
View File

@ -0,0 +1,296 @@
#ifndef __endian_h
#define __endian_h
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
//
// Unaligned access
//
#define UAA16(p, i) (((PACKED16*)p)->val[i])
#define UAA32(p, i) (((PACKED32*)p)->val[i])
#define UAA64(p, i) (((PACKED64*)p)->val[i])
#define UA64(p) UAA64(p, 0)
#define UA32(p) UAA32(p, 0)
#define UA16(p) UAA16(p, 0)
//
//Byteswap: Use compiler support if available
//
#ifdef __has_builtin // Clang supports this
#if __has_builtin(__builtin_bswap16)
#define BS16(x) __builtin_bswap16(x)
#endif
#if __has_builtin(__builtin_bswap32)
#define BS32(x) __builtin_bswap32(x)
#endif
#if __has_builtin(__builtin_bswap64)
#define BS64(x) __builtin_bswap64(x)
#endif
#endif // has_builtin
#ifdef __GNUC__ // GNU C >= 4.3 has bswap32 and bswap64. GNU C >= 4.8 also has bswap16
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)
#ifndef BS32
#define BS32(x) __builtin_bswap32(x)
#endif
#ifndef BS64
#define BS64(x) __builtin_bswap64(x)
#endif
#if (__GNUC__ > 4) || (__GNUC_MINOR__ > 7)
#ifndef BS16
#define BS16(x) __builtin_bswap16(x)
#endif
#endif // GNU C > 4.7
#endif // __GNUC__ > 4
#endif // __GNUC__
//
// Byteorder
//
#if defined(__linux__) || defined(__GLIBC__) || defined(__CYGWIN__)
#include <endian.h>
#include <byteswap.h>
#ifndef BS16
#define BS16(x) bswap_16(x)
#endif
#ifndef BS32
#define BS32(x) bswap_32(x)
#endif
#ifndef BS64
#define BS64(x) bswap_64(x)
#endif
#elif defined(__sun__)
#include <sys/byteorder.h>
#ifndef BS16
#define BS16(x) BSWAP_16(x)
#endif
#ifndef BS32
#define BS32(x) BSWAP_32(x)
#endif
#ifndef BS64
#define BS64(x) BSWAP_64(x)
#endif
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#ifdef _LITTLE_ENDIAN
#define __BYTE_ORDER __LITTLE_ENDIAN
#else
#define __BYTE_ORDER __BIG_ENDIAN
#endif
#elif __minix__ || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
#include <sys/types.h>
#include <sys/endian.h>
#define __BYTE_ORDER _BYTE_ORDER
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#define __BIG_ENDIAN _BIG_ENDIAN
#ifdef __OpenBSD__
#ifndef BS16
#define BS16 swap16
#endif
#ifndef BS32
#define BS32 swap32
#endif
#ifndef BS64
#define BS64 swap64
#endif
#else // !__OpenBSD__
#ifndef BS16
#define BS16 bswap16
#endif
#ifndef BS32
#define BS32 bswap32
#endif
#ifndef BS64
#define BS64 bswap64
#endif
#endif // !__OpenBSD__
#elif defined(__APPLE__)
#include <sys/types.h>
#include <machine/endian.h>
#include <libkern/OSByteOrder.h>
#define __BYTE_ORDER _BYTE_ORDER
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#define __BIG_ENDIAN _BIG_ENDIAN
#ifndef BS16
#define BS16 OSSwapInt16
#endif
#ifndef BS32
#define BS32 OSSwapInt32
#endif
#ifndef BS64
#define BS64 OSSwapInt64
#endif
#elif defined(_WIN32)
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __BYTE_ORDER __LITTLE_ENDIAN
#include <stdlib.h>
#ifndef BS16
#define BS16 _byteswap_ushort
#endif
#ifndef BS32
#define BS32 _byteswap_ulong
#endif
#ifndef BS64
#define BS64 _byteswap_uint64
#endif
#endif // Byteorder in different OS
#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) \
&& defined(BS16) && defined(BS32) && defined(BS64)
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define __BE16(x) BS16(x)
#define __LE16(x) (x)
#define __BE32(x) BS32(x)
#define __LE32(x) (x)
#define __BE64(x) BS64(x)
#define __LE64(x) (x)
#else // __BYTE_ORDER == __BIG_ENDIAN
#define __BE16(x) (x)
#define __LE16(x) BS16(x)
#define __BE32(x) (x)
#define __LE32(x) BS32(x)
#define __BE64(x) (x)
#define __LE64(x) BS64(x)
#endif // __BYTE_ORDER
#define PUT_UAA64BE(p, v, i) ( UAA64(p, i) = __BE64(v) )
#define PUT_UAA32BE(p, v, i) ( UAA32(p, i) = __BE32(v) )
#define PUT_UAA16BE(p, v, i) ( UAA16(p, i) = __BE16(v) )
#define PUT_UAA64LE(p, v, i) ( UAA64(p, i) = __LE64(v) )
#define PUT_UAA32LE(p, v, i) ( UAA32(p, i) = __LE32(v) )
#define PUT_UAA16LE(p, v, i) ( UAA16(p, i) = __LE16(v) )
#define GET_UAA64BE(p, i) __BE64(UAA64(p, i))
#define GET_UAA32BE(p, i) __BE32(UAA32(p, i))
#define GET_UAA16BE(p, i) __BE16(UAA16(p, i))
#define GET_UAA64LE(p, i) __LE64(UAA64(p, i))
#define GET_UAA32LE(p, i) __LE32(UAA32(p, i))
#define GET_UAA16LE(p, i) __LE16(UAA16(p, i))
#define BE16(x) __BE16(x)
#define LE16(x) __LE16(x)
#define BE32(x) __BE32(x)
#define LE32(x) __LE32(x)
#define BE64(x) __BE64(x)
#define LE64(x) __LE64(x)
#else // ! defined(__BYTE_ORDER)
extern void PUT_UAA64BE(void *p, unsigned long long v, unsigned int i);
extern void PUT_UAA32BE(void *p, unsigned int v, unsigned int i);
extern void PUT_UAA16BE(void *p, unsigned short v, unsigned int i);
extern void PUT_UAA64LE(void *p, unsigned long long v, unsigned int i);
extern void PUT_UAA32LE(void *p, unsigned int v, unsigned int i);
extern void PUT_UAA16LE(void *p, unsigned short v, unsigned int i);
extern unsigned long long GET_UAA64BE(void *p, unsigned int i);
extern unsigned int GET_UAA32BE(void *p, unsigned int i);
extern unsigned short GET_UAA16BE(void *p, unsigned int i);
extern unsigned long long GET_UAA64LE(void *p, unsigned int i);
extern unsigned int GET_UAA32LE(void *p, unsigned int i);
extern unsigned short GET_UAA16LE(void *p, unsigned int i);
extern unsigned short BE16(unsigned short x);
extern unsigned short LE16(unsigned short x);
extern unsigned int BE32(unsigned int x);
extern unsigned int LE32(unsigned int x);
extern unsigned long long BE64(unsigned long long x);
extern unsigned long long LE64(unsigned long long x);
#endif // defined(__BYTE_ORDER)
#define PUT_UA64BE(p, v) PUT_UAA64BE(p, v, 0)
#define PUT_UA32BE(p, v) PUT_UAA32BE(p, v, 0)
#define PUT_UA16BE(p, v) PUT_UAA16BE(p, v, 0)
#define PUT_UA64LE(p, v) PUT_UAA64LE(p, v, 0)
#define PUT_UA32LE(p, v) PUT_UAA32LE(p, v, 0)
#define PUT_UA16LE(p, v) PUT_UAA16LE(p, v, 0)
#define GET_UA64BE(p) GET_UAA64BE(p, 0)
#define GET_UA32BE(p) GET_UAA32BE(p, 0)
#define GET_UA16BE(p) GET_UAA16BE(p, 0)
#define GET_UA64LE(p) GET_UAA64LE(p, 0)
#define GET_UA32LE(p) GET_UAA32LE(p, 0)
#define GET_UA16LE(p) GET_UAA16LE(p, 0)
#endif // __endian_h

BIN
floppy144.vfd Normal file

Binary file not shown.

369
helpers.c Normal file
View File

@ -0,0 +1,369 @@
/*
* Helper functions used by other modules
*/
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#ifndef _WIN32
#include <errno.h>
#endif // _WIN32
#include <getopt.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "helpers.h"
#include "output.h"
#include "endian.h"
#include "shared_globals.h"
/*
* UCS2 <-> UTF-8 functions
* All functions use little endian UCS2 since we only need it to communicate with Windows via RPC
*/
// Convert one character from UTF-8 to UCS2
// Returns 0xffff, if utf-8 evaluates to > 0xfffe (outside basic multilingual pane)
WCHAR utf8_to_ucs2_char (const unsigned char *input, const unsigned char **end_ptr)
{
*end_ptr = input;
if (input[0] == 0)
return ~0;
if (input[0] < 0x80) {
*end_ptr = input + 1;
return LE16(input[0]);
}
if ((input[0] & 0xE0) == 0xE0) {
if (input[1] == 0 || input[2] == 0)
return ~0;
*end_ptr = input + 3;
return
LE16((input[0] & 0x0F)<<12 |
(input[1] & 0x3F)<<6 |
(input[2] & 0x3F));
}
if ((input[0] & 0xC0) == 0xC0) {
if (input[1] == 0)
return ~0;
*end_ptr = input + 2;
return
LE16((input[0] & 0x1F)<<6 |
(input[1] & 0x3F));
}
return ~0;
}
// Convert one character from UCS2 to UTF-8
// Returns length of UTF-8 char (1, 2 or 3) or -1 on error (UTF-16 outside UCS2)
// char *utf8 must be large enough to hold 3 bytes
int ucs2_to_utf8_char (const WCHAR ucs2_le, char *utf8)
{
const WCHAR ucs2 = LE16(ucs2_le);
if (ucs2 < 0x80) {
utf8[0] = ucs2;
utf8[1] = '\0';
return 1;
}
if (ucs2 >= 0x80 && ucs2 < 0x800) {
utf8[0] = (ucs2 >> 6) | 0xC0;
utf8[1] = (ucs2 & 0x3F) | 0x80;
utf8[2] = '\0';
return 2;
}
if (ucs2 >= 0x800 && ucs2 < 0xFFFF) {
if (ucs2 >= 0xD800 && ucs2 <= 0xDFFF) {
/* Ill-formed (UTF-16 ouside of BMP) */
return -1;
}
utf8[0] = ((ucs2 >> 12) ) | 0xE0;
utf8[1] = ((ucs2 >> 6 ) & 0x3F) | 0x80;
utf8[2] = ((ucs2 ) & 0x3F) | 0x80;
utf8[3] = '\0';
return 3;
}
return -1;
}
// Converts UTF8 to UCS2. Returns size in bytes of the converted string or -1 on error
size_t utf8_to_ucs2(WCHAR* const ucs2_le, const char* const utf8, const size_t maxucs2, const size_t maxutf8)
{
const unsigned char* current_utf8 = (unsigned char*)utf8;
WCHAR* current_ucs2_le = ucs2_le;
for (; *current_utf8; current_ucs2_le++)
{
size_t size = (char*)current_utf8 - utf8;
if (size >= maxutf8) return (size_t)-1;
if (((*current_utf8 & 0xc0) == 0xc0) && (size >= maxutf8 - 1)) return (size_t)-1;
if (((*current_utf8 & 0xe0) == 0xe0) && (size >= maxutf8 - 2)) return (size_t)-1;
if (current_ucs2_le - ucs2_le >= (intptr_t)maxucs2 - 1) return (size_t)-1;
*current_ucs2_le = utf8_to_ucs2_char(current_utf8, &current_utf8);
current_ucs2_le[1] = 0;
if (*current_ucs2_le == (WCHAR)-1) return (size_t)-1;
}
return current_ucs2_le - ucs2_le;
}
// Converts UCS2 to UTF-8. Return TRUE or FALSE
BOOL ucs2_to_utf8(const WCHAR* const ucs2_le, char* utf8, size_t maxucs2, size_t maxutf8)
{
char utf8_char[4];
const WCHAR* current_ucs2 = ucs2_le;
unsigned int index_utf8 = 0;
for(*utf8 = 0; *current_ucs2; current_ucs2++)
{
if (current_ucs2 - ucs2_le > (intptr_t)maxucs2) return FALSE;
int len = ucs2_to_utf8_char(*current_ucs2, utf8_char);
if (index_utf8 + len > maxutf8) return FALSE;
strncat(utf8, utf8_char, len);
index_utf8+=len;
}
return TRUE;
}
/* End of UTF-8 <-> UCS2 conversion */
// Checks, whether a string is a valid integer number between min and max. Returns TRUE or FALSE. Puts int value in *value
BOOL stringToInt(const char *const szValue, const unsigned int min, const unsigned int max, unsigned int *const value)
{
char *nextchar;
errno = 0;
long long result = strtoll(szValue, &nextchar, 10);
if (errno || result < (long long)min || result > (long long)max || *nextchar)
{
return FALSE;
}
*value = (unsigned int)result;
return TRUE;
}
//Converts a String Guid to a host binary guid in host endianess
int_fast8_t string2Uuid(const char *const restrict input, GUID *const restrict guid)
{
int i;
if (strlen(input) < GUID_STRING_LENGTH) return FALSE;
if (input[8] != '-' || input[13] != '-' || input[18] != '-' || input[23] != '-') return FALSE;
for (i = 0; i < GUID_STRING_LENGTH; i++)
{
if (i == 8 || i == 13 || i == 18 || i == 23) continue;
const char c = toupper((int)input[i]);
if (c < '0' || c > 'F' || (c > '9' && c < 'A')) return FALSE;
}
char inputCopy[GUID_STRING_LENGTH + 1];
strncpy(inputCopy, input, GUID_STRING_LENGTH + 1);
inputCopy[8] = inputCopy[13] = inputCopy[18] = 0;
hex2bin((BYTE*)&guid->Data1, inputCopy, 8);
hex2bin((BYTE*)&guid->Data2, inputCopy + 9, 4);
hex2bin((BYTE*)&guid->Data3, inputCopy + 14, 4);
hex2bin(guid->Data4, input + 19, 16);
guid->Data1 = BE32(guid->Data1);
guid->Data2 = BE16(guid->Data2);
guid->Data3 = BE16(guid->Data3);
return TRUE;
}
// convert GUID to little-endian
void LEGUID(GUID *const restrict out, const GUID* const restrict in)
{
#if __BYTE_ORDER != __LITTLE_ENDIAN
out->Data1 = LE32(in->Data1);
out->Data2 = LE16(in->Data2);
out->Data3 = LE16(in->Data3);
memcpy(out->Data4, in->Data4, sizeof(out->Data4));
#else
memcpy(out, in, sizeof(GUID));
#endif
}
//Checks a command line argument if it is numeric and between min and max. Returns the numeric value or exits on error
__pure unsigned int getOptionArgumentInt(const char o, const unsigned int min, const unsigned int max)
{
unsigned int result;
if (!stringToInt(optarg, min, max, &result))
{
printerrorf("Fatal: Option \"-%c\" must be numeric between %u and %u.\n", o, min, max);
exit(!0);
}
return result;
}
// Resets getopt() to start parsing from the beginning
void optReset(void)
{
#if __minix__ || defined(__BSD__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
optind = 1;
optreset = 1; // Makes newer BSD getopt happy
#elif defined(__UCLIBC__) // uClibc headers also define __GLIBC__ so be careful here
optind = 0; // uClibc seeks compatibility with GLIBC
#elif defined(__GLIBC__)
optind = 0; // Makes GLIBC getopt happy
#else // Standard for most systems
optind = 1;
#endif
}
#if defined(_WIN32) || defined(USE_MSRPC)
// Returns a static message buffer containing text for a given Win32 error. Not thread safe (same as strerror)
char* win_strerror(const int message)
{
#define STRERROR_BUFFER_SIZE 256
static char buffer[STRERROR_BUFFER_SIZE];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, message, 0, buffer, STRERROR_BUFFER_SIZE, NULL);
return buffer;
}
#endif // defined(_WIN32) || defined(USE_MSRPC)
/*
* parses an address in the form host:[port] in addr
* returns host and port in seperate strings
*/
void parseAddress(char *const addr, char** szHost, char** szPort)
{
*szHost = addr;
# ifndef NO_SOCKETS
*szPort = (char*)defaultport;
# else // NO_SOCKETS
*szPort = "1688";
# endif // NO_SOCKETS
char *lastcolon = strrchr(addr, ':');
char *firstcolon = strchr(addr, ':');
char *closingbracket = strrchr(addr, ']');
if (*addr == '[' && closingbracket) //Address in brackets
{
*closingbracket = 0;
(*szHost)++;
if (closingbracket[1] == ':')
*szPort = closingbracket + 2;
}
else if (firstcolon && firstcolon == lastcolon) //IPv4 address or hostname with port
{
*firstcolon = 0;
*szPort = firstcolon + 1;
}
}
// Initialize random generator (needs to be done in each thread)
void randomNumberInit()
{
struct timeval tv;
gettimeofday(&tv, NULL);
srand((unsigned int)(tv.tv_sec ^ tv.tv_usec));
}
// We always exit immediately if any OOM condition occurs
__noreturn void OutOfMemory(void)
{
errorout("Fatal: Out of memory");
exit(!0);
}
void* vlmcsd_malloc(size_t len)
{
void* buf = malloc(len);
if (!buf) OutOfMemory();
return buf;
}
/*
* Converts hex digits to bytes in big-endian order.
* Ignores any non-hex characters
*/
void hex2bin(BYTE *const bin, const char *hex, const size_t maxbin)
{
static const char *const hexdigits = "0123456789ABCDEF";
char* nextchar;
size_t i;
for (i = 0; (i < 16) && utf8_to_ucs2_char((const unsigned char*)hex, (const unsigned char**)&nextchar) != (WCHAR)-1; hex = nextchar)
{
const char* pos = strchr(hexdigits, toupper((int)*hex));
if (!pos) continue;
if (!(i & 1)) bin[i >> 1] = 0;
bin[i >> 1] |= (char)(pos - hexdigits);
if (!(i & 1)) bin[i >> 1] <<= 4;
i++;
if (i >> 1 > maxbin) break;
}
}
__pure BOOL getArgumentBool(int_fast8_t *result, const char *const argument)
{
if (
!strncasecmp(argument, "true", 4) ||
!strncasecmp(argument, "on", 4) ||
!strncasecmp(argument, "yes", 3) ||
!strncasecmp(argument, "1", 1)
)
{
*result = TRUE;
return TRUE;
}
else if (
!strncasecmp(argument, "false", 5) ||
!strncasecmp(argument, "off", 3) ||
!strncasecmp(argument, "no", 2) ||
!strncasecmp(argument, "0", 1)
)
{
*result = FALSE;
return TRUE;
}
return FALSE;
}

34
helpers.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef HELPERS_H
#define HELPERS_H
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include <stdint.h>
#include "types.h"
#define GUID_LE 0
#define GUID_BE 1
#define GUID_SWAP 2
BOOL stringToInt(const char *const szValue, const unsigned int min, const unsigned int max, unsigned int *const value);
unsigned int getOptionArgumentInt(const char o, const unsigned int min, const unsigned int max);
void optReset(void);
char* win_strerror(const int message);
int ucs2_to_utf8_char (const WCHAR ucs2_le, char *utf8);
size_t utf8_to_ucs2(WCHAR* const ucs2_le, const char* const utf8, const size_t maxucs2, const size_t maxutf8);
WCHAR utf8_to_ucs2_char (const unsigned char * input, const unsigned char ** end_ptr);
BOOL ucs2_to_utf8(const WCHAR* const ucs2_le, char* utf8, size_t maxucs2, size_t maxutf8);
int_fast8_t string2Uuid(const char *const restrict input, GUID *const restrict guid);
void randomNumberInit();
void LEGUID(GUID *const restrict result, const GUID* const restrict guid);
void parseAddress(char *const addr, char** szHost, char** szPort);
__noreturn void OutOfMemory(void);
void* vlmcsd_malloc(size_t len);
void hex2bin(BYTE *const bin, const char *hex, const size_t maxbin);
__pure BOOL getArgumentBool(int_fast8_t *result, const char *const argument);
#endif // HELPERS_H

1118
kms.c Normal file

File diff suppressed because it is too large Load Diff

287
kms.h Normal file
View File

@ -0,0 +1,287 @@
#ifndef __kms_h
#define __kms_h
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include <sys/time.h>
#include <stdlib.h>
#include "types.h"
//
// REQUEST... types are actually fixed size
// RESPONSE... size may vary, defined here is max possible size
//
#define MAX_RESPONSE_SIZE 384
#define PID_BUFFER_SIZE 64
#define MAX_REQUEST_SIZE sizeof(REQUEST_V6)
#define WORKSTATION_NAME_BUFFER 64
// Constants for V6 time stamp interval
#define TIME_C1 0x00000022816889BDULL
#define TIME_C2 0x000000208CBAB5EDULL
#define TIME_C3 0x3156CD5AC628477AULL
#define VERSION_INFO union \
{ \
DWORD Version;\
struct { \
WORD MinorVer; \
WORD MajorVer; \
} /*__packed*/; \
} /*__packed*/
// Aliases for various KMS struct members
#define IsClientVM VMInfo
#define GraceTime BindingExpiration
#define MinutesRemaingInCurrentStatus BindingExpiration
#define ID ActID
#define ApplicationID AppID
#define SkuId ActID
#define KmsId KMSID
#define ClientMachineId CMID
#define MinimumClients N_Policy
#define TimeStamp ClientTime
#define PreviousCLientMachineId CMID_prev
#define Salt IV
#define XorSalt XoredIVs
#define ActivationInterval VLActivationInterval
#define RenewalInterval VLRenewalInterval
typedef struct {
VERSION_INFO;
DWORD VMInfo; // 0 = client is bare metal / 1 = client is VM
DWORD LicenseStatus; // 0 = Unlicensed, 1 = Licensed (Activated), 2 = OOB grace, 3 = OOT grace, 4 = NonGenuineGrace, 5 = Notification, 6 = extended grace
DWORD BindingExpiration; // Expiration of the current status in minutes (e.g. when KMS activation or OOB grace expires).
GUID AppID; // Can currently be Windows, Office2010 or Office2013 (see kms.c, table AppList).
GUID ActID; // Most detailed product list. One product key per ActID (see kms.c, table ExtendedProductList). Is ignored by KMS server.
GUID KMSID; // This is actually what the KMS server uses to grant or refuse activation (see kms.c, table BasicProductList).
GUID CMID; // Client machine id. Used by the KMS server for counting minimum clients.
DWORD N_Policy; // Minimum clients required for activation.
FILETIME ClientTime; // Current client time.
GUID CMID_prev; // previous client machine id. All zeros, if it never changed.
WCHAR WorkstationName[64]; // Workstation name. FQDN if available, NetBIOS otherwise.
} /*__packed*/ REQUEST;
typedef struct {
VERSION_INFO;
DWORD PIDSize; // Size of PIDData in bytes.
WCHAR KmsPID[PID_BUFFER_SIZE]; // ePID (must include terminating zero)
GUID CMID; // Client machine id. Must be the same as in request.
FILETIME ClientTime; // Current client time. Must be the same as in request.
DWORD Count; // Current activated machines. KMS server counts up to N_Policy << 1 then stops
DWORD VLActivationInterval; // Time in minutes when clients should retry activation if it was unsuccessful (default 2 hours)
DWORD VLRenewalInterval; // Time in minutes when clients should renew KMS activation (default 7 days)
} /*__packed*/ RESPONSE;
#ifdef _DEBUG
typedef struct {
VERSION_INFO;
DWORD PIDSize;
WCHAR KmsPID[49]; // Set this to the ePID length you want to debug
GUID CMID;
FILETIME ClientTime;
DWORD Count;
DWORD VLActivationInterval;
DWORD VLRenewalInterval;
} __packed RESPONSE_DEBUG;
#endif
typedef struct {
REQUEST RequestBase; // Base request
BYTE MAC[16]; // Aes 160 bit CMAC
} /*__packed*/ REQUEST_V4;
typedef struct {
RESPONSE ResponseBase; // Base response
BYTE MAC[16]; // Aes 160 bit CMAC
} /*__packed*/ RESPONSE_V4;
typedef struct {
VERSION_INFO; // unencrypted version info
BYTE IV[16]; // IV
REQUEST RequestBase; // Base Request
BYTE Pad[4]; // since this struct is fixed, we use fixed PKCS pad bytes
} /*__packed*/ REQUEST_V5;
typedef REQUEST_V5 REQUEST_V6; // v5 and v6 requests are identical
typedef struct {
VERSION_INFO;
BYTE IV[16];
RESPONSE ResponseBase;
BYTE RandomXoredIVs[16]; // If RequestIV was used for decryption: Random ^ decrypted Request IV ^ ResponseIV. If NULL IV was used for decryption: Random ^ decrypted Request IV
BYTE Hash[32]; // SHA256 of Random used in RandomXoredIVs
BYTE HwId[8]; // HwId from the KMS server
BYTE XoredIVs[16]; // If RequestIV was used for decryption: decrypted Request IV ^ ResponseIV. If NULL IV was used for decryption: decrypted Request IV.
BYTE HMAC[16]; // V6 Hmac (low 16 bytes only), see kms.c CreateV6Hmac
//BYTE Pad[10]; // Pad is variable sized. So do not include in struct
} /*__packed*/ RESPONSE_V6;
typedef struct { // not used except for sizeof(). Fields are the same as RESPONSE_V6
VERSION_INFO;
BYTE IV[16];
RESPONSE ResponseBase;
BYTE RandomXoredIVs[16];
BYTE Hash[32];
} /*__packed*/ RESPONSE_V5;
#ifdef _DEBUG
typedef struct { // Debug structure for direct casting of RPC data in debugger
VERSION_INFO;
BYTE IV[16];
RESPONSE_DEBUG ResponseBase;
BYTE RandomXoredIVs[16];
BYTE MAC[32];
BYTE Unknown[8];
BYTE XorSalts[16];
BYTE HMAC[16];
BYTE Pad[16];
} __packed RESPONSE_V6_DEBUG;
#endif
#define V4_PRE_EPID_SIZE ( \
sizeof(((RESPONSE*)0)->Version) + \
sizeof(((RESPONSE*)0)->PIDSize) \
)
#define V4_POST_EPID_SIZE ( \
sizeof(((RESPONSE*)0)->CMID) + \
sizeof(((RESPONSE*)0)->ClientTime) + \
sizeof(((RESPONSE*)0)->Count) + \
sizeof(((RESPONSE*)0)->VLActivationInterval) + \
sizeof(((RESPONSE*)0)->VLRenewalInterval) \
)
#define V6_DECRYPT_SIZE ( \
sizeof(((REQUEST_V6*)0)->IV) + \
sizeof(((REQUEST_V6*)0)->RequestBase) + \
sizeof(((REQUEST_V6*)0)->Pad) \
)
#define V6_UNENCRYPTED_SIZE ( \
sizeof(((RESPONSE_V6*)0)->Version) + \
sizeof(((RESPONSE_V6*)0)->IV) \
)
#define V6_PRE_EPID_SIZE ( \
V6_UNENCRYPTED_SIZE + \
sizeof(((RESPONSE*)0)->Version) + \
sizeof(((RESPONSE*)0)->PIDSize) \
)
#define V5_POST_EPID_SIZE ( \
V4_POST_EPID_SIZE + \
sizeof(((RESPONSE_V6*)0)->RandomXoredIVs) + \
sizeof(((RESPONSE_V6*)0)->Hash) \
)
#define V6_POST_EPID_SIZE ( \
V5_POST_EPID_SIZE + \
sizeof(((RESPONSE_V6*)0)->HwId) + \
sizeof(((RESPONSE_V6*)0)->XoredIVs) + \
sizeof(((RESPONSE_V6*)0)->HMAC) \
)
#define RESPONSE_RESULT_OK ((1 << 10) - 1) //(9 bits)
typedef union
{
DWORD mask;
struct
{
BOOL HashOK : 1;
BOOL TimeStampOK : 1;
BOOL ClientMachineIDOK : 1;
BOOL VersionOK : 1;
BOOL IVsOK : 1;
BOOL DecryptSuccess : 1;
BOOL HmacSha256OK : 1;
BOOL PidLengthOK : 1;
BOOL RpcOK : 1;
BOOL IVnotSuspicious : 1;
BOOL reserved3 : 1;
BOOL reserved4 : 1;
BOOL reserved5 : 1;
BOOL reserved6 : 1;
uint32_t effectiveResponseSize : 9;
uint32_t correctResponseSize : 9;
};
} RESPONSE_RESULT;
typedef BYTE hwid_t[8];
typedef struct
{
GUID guid;
const char* name;
const char* pid;
uint8_t AppIndex;
uint8_t KmsIndex;
} KmsIdList;
#define KMS_PARAM_MAJOR AppIndex
#define KMS_PARAM_REQUIREDCOUNT KmsIndex
#define APP_ID_WINDOWS 0
#define APP_ID_OFFICE2010 1
#define APP_ID_OFFICE2013 2
#define KMS_ID_VISTA 0
#define KMS_ID_WIN7 1
#define KMS_ID_WIN8_VL 2
#define KMS_ID_WIN_BETA 3
#define KMS_ID_WIN8_RETAIL 4
#define KMS_ID_WIN81_VL 5
#define KMS_ID_WIN81_RETAIL 6
#define KMS_ID_WIN2008A 7
#define KMS_ID_WIN2008B 8
#define KMS_ID_WIN2008C 9
#define KMS_ID_WIN2008R2A 10
#define KMS_ID_WIN2008R2B 11
#define KMS_ID_WIN2008R2C 12
#define KMS_ID_WIN2012 13
#define KMS_ID_WIN2012R2 14
#define KMS_ID_OFFICE2010 15
#define KMS_ID_OFFICE2013 16
#define KMS_ID_WIN_SRV_BETA 17
#define KMS_ID_OFFICE2016 18
#define KMS_ID_WIN10_VL 19
#define KMS_ID_WIN10_RETAIL 20
#define PWINGUID &AppList[APP_ID_WINDOWS].guid
#define POFFICE2010GUID &AppList[APP_ID_OFFICE2010].guid
#define POFFICE2013GUID &AppList[APP_ID_OFFICE2013].guid
typedef BOOL(__stdcall *RequestCallback_t)(const REQUEST *const baseRequest, RESPONSE *const baseResponse, BYTE *const hwId, const char* const ipstr);
size_t CreateResponseV4(REQUEST_V4 *const Request, BYTE *const response_data, const char* const ipstr);
size_t CreateResponseV6(REQUEST_V6 *restrict Request, BYTE *const response_data, const char* const ipstr);
BYTE *CreateRequestV4(size_t *size, const REQUEST* requestBase);
BYTE *CreateRequestV6(size_t *size, const REQUEST* requestBase);
void randomPidInit();
void get16RandomBytes(void* ptr);
RESPONSE_RESULT DecryptResponseV6(RESPONSE_V6* Response_v6, int responseSize, BYTE* const response, const BYTE* const request, BYTE* hwid);
RESPONSE_RESULT DecryptResponseV4(RESPONSE_V4* Response_v4, const int responseSize, BYTE* const response, const BYTE* const request);
void getUnixTimeAsFileTime(FILETIME *const ts);
__pure int64_t fileTimeToUnixTime(const FILETIME *const ts);
const char* getProductNameHE(const GUID *const guid, const KmsIdList *const List, ProdListIndex_t *const i);
const char* getProductNameLE(const GUID *const guid, const KmsIdList *const List, ProdListIndex_t *const i);
__pure ProdListIndex_t getExtendedProductListSize();
__pure ProdListIndex_t getAppListSize(void);
extern const KmsIdList ProductList[];
extern const KmsIdList AppList[];
extern const KmsIdList ExtendedProductList[];
extern RequestCallback_t CreateResponseBase;
#ifdef _PEDANTIC
uint16_t IsValidLcid(const uint16_t Lcid);
#endif // _PEDANTIC
#endif // __kms_h

35
libkms-test.c Normal file
View File

@ -0,0 +1,35 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "libkms.h"
#include "kms.h"
#include "endian.h"
static const char ePID[] = { 'T', 0, 'E', 0, 'S', 0, 'T', 0, 0, 0 };
__stdcall BOOL KmsCallBack(const REQUEST *const baseRequest, RESPONSE *const baseResponse, BYTE *const hwId, const char* const ipstr)
{
printf("libvlmcs-test.c: Entered KmsCallBack for client %s\n", ipstr);
memcpy(&baseResponse->CMID, &baseRequest->CMID, sizeof(GUID));
memcpy(&baseResponse->ClientTime, &baseRequest->ClientTime, sizeof(FILETIME));
memcpy(&baseResponse->KmsPID, ePID, sizeof(ePID));
baseResponse->Version = baseRequest->Version;
baseResponse->Count = LE32(LE32(baseRequest->N_Policy) << 1);
baseResponse->PIDSize = sizeof(ePID);
baseResponse->VLActivationInterval = LE32(120);
baseResponse->VLRenewalInterval = LE32(10080);
if (hwId && baseResponse->MajorVer > 5) memcpy(hwId, "\x01\x02\x03\x04\x05\x06\x07\x08", 8);
return TRUE;
}
int main(int argc, char** argv)
{
printf("libvlmcs-test.c: Program start\n");
StartKmsServer(1688, KmsCallBack);
return 0;
}

117
libkms.c Normal file
View File

@ -0,0 +1,117 @@
/*
* libkms.c
*/
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#define EXTERNAL dllexport
#define DLLVERSION 0x30000
#include "libkms.h"
#include "shared_globals.h"
#include "network.h"
#include "helpers.h"
#ifndef _WIN32
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <netinet/in.h>
#endif // WIN32
static int_fast8_t IsServerStarted = FALSE;
EXTERNC __declspec(EXTERNAL) DWORD __cdecl SendActivationRequest
(
const char* const hostname,
const int port,
RESPONSE* baseResponse,
const REQUEST* const baseRequest,
RESPONSE_RESULT* result, BYTE *hwid
)
{
return !0; // not yet implemented
}
EXTERNC __declspec(EXTERNAL) DWORD __cdecl StartKmsServer(const int port, RequestCallback_t requestCallback)
{
char listenAddress[64];
if (IsServerStarted) return !0;
# ifdef _WIN32
# ifndef USE_MSRPC
// Windows Sockets must be initialized
WSADATA wsadata;
int error;
if ((error = WSAStartup(0x0202, &wsadata)))
{
return error;
}
# endif // USE_MSRPC
# endif // _WIN32
CreateResponseBase = requestCallback;
int maxsockets = 0;
int_fast8_t haveIPv4 = FALSE;
int_fast8_t haveIPv6 = FALSE;
if (checkProtocolStack(AF_INET)) { haveIPv4 = TRUE; maxsockets++; }
if (checkProtocolStack(AF_INET6)) { haveIPv6 = TRUE; maxsockets++; }
if(!maxsockets) return !0;
SocketList = (SOCKET*)vlmcsd_malloc(sizeof(SOCKET) * (size_t)maxsockets);
numsockets = 0;
if (haveIPv4)
{
snprintf(listenAddress, 64, "0.0.0.0:%u", (unsigned int)port);
addListeningSocket(listenAddress);
}
if (haveIPv6)
{
snprintf(listenAddress, 64, "[::]:%u", (unsigned int)port);
addListeningSocket(listenAddress);
}
if (!numsockets)
{
free(SocketList);
return !0;
}
IsServerStarted = TRUE;
runServer();
IsServerStarted = FALSE;
return 0;
}
EXTERNC __declspec(EXTERNAL) DWORD __cdecl StopKmsServer()
{
if (!IsServerStarted) return !0;
closeAllListeningSockets();
if (SocketList) free(SocketList);
return 0;
}
EXTERNC __declspec(EXTERNAL) int __cdecl GetLibKmsVersion()
{
return DLLVERSION;
}

33
libkms.h Normal file
View File

@ -0,0 +1,33 @@
/*
* libkms.h
*/
#ifndef LIBKMS_H_
#define LIBKMS_H_
#include "types.h"
#include "kms.h"
#include "rpc.h"
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
#if !defined(_WIN32) && !__CYGWIN__
#define __declspec(x) __attribute__((__visibility__("default")))
#endif
#if !defined(EXTERNAL)
#define EXTERNAL dllimport
#endif
EXTERNC __declspec(EXTERNAL) DWORD __cdecl SendActivationRequest(const char* const hostname, const int port, RESPONSE* baseResponse, const REQUEST* const baseRequest, RESPONSE_RESULT* result, BYTE *hwid);
EXTERNC __declspec(EXTERNAL) DWORD __cdecl StartKmsServer(const int port, RequestCallback_t requestCallback);
EXTERNC __declspec(EXTERNAL) DWORD __cdecl StopKmsServer();
EXTERNC __declspec(EXTERNAL) int __cdecl GetLibKmsVersion();
//EXTERN_C __declspec(EXTERNAL) unsigned int __cdecl GetRandom32();
#endif /* LIBKMS_H_ */

31
make_dragonfly Normal file
View File

@ -0,0 +1,31 @@
#!/usr/local/bin/bash
export VERBOSE=3
export DNS_PARSER=OS
rm -f vlmcsd-* vlmcs-* vlmcsdmulti-* *_all.* 2>/dev/null
rm -f vlmcsdmulti vlmcsd vlmcs 2>/dev/null
MAKEFLAGS="-B -j12"
REUSEOBJFLAGS="-j12"
CF="-flto=12 -static-libgcc -pipe -fwhole-program -fno-common -fno-exceptions -fno-stack-protector -fno-unwind-tables -fno-asynchronous-unwind-tables -fmerge-all-constants"
CF45="-static-libgcc -pipe -fno-common -fno-exceptions -fno-stack-protector -fno-unwind-tables -fno-asynchronous-unwind-tables -fmerge-all-constants"
CFCLANG="-pipe -fno-common -fno-exceptions -fno-stack-protector -fno-unwind-tables -fno-asynchronous-unwind-tables -fmerge-all-constants"
LF="-Wl,-z,norelro -Wl,--hash-style=sysv -Wl,--build-id=none"
LFCLANG="-Wl,-z,norelro -Wl,--hash-style=sysv"
gmake $MAKEFLAGS PROGRAM_NAME=vlmcsd-DragonFly-x64 CLIENT_NAME=vlmcs-DragonFly-x64 CFLAGS="$CF" LDFLAGS="$LF"
rm vlmcsd.o vlmcs.o
gmake vlmcsdmulti-DragonFly-x64 $REUSEOBJFLAGS CFLAGS="$CF" LDFLAGS="$LF" MULTI_NAME=vlmcsdmulti-DragonFly-x64
rm *.o
strip -s --strip-unneeded --remove-section=.eh_frame_hdr --remove-section=.eh_frame --remove-section=.note.gnu.gold-version --remove-section=.comment --remove-section=.note --remove-section=.note.gnu.build-id --remove-section=.note.ABI-tag vlmcs-* vlmcsd-* vlmcsdmulti-*
sstrip -z vlmcs-* vlmcsd-* vlmcsdmulti-*
cp -af vlmcsd-DragonFly-x64 /usr/local/sbin/vlmcsd
cp -af vlmcs-DragonFly-x64 /usr/local/bin/vlmcs
# Copy everything to distribution server
scp -p vlmcsdmulti-* vlmcsd-* vlmcs-* root@ubuntu64:x/binaries/DragonFly/intel/

46
make_freebsd Normal file
View File

@ -0,0 +1,46 @@
#!/usr/local/bin/bash
export VERBOSE=3
export DNS_PARSER=OS
rm -f vlmcsd-* vlmcs-* vlmcsdmulti-* *_all.* 2>/dev/null
rm -f vlmcsdmulti vlmcsd vlmcs 2>/dev/null
MAKEFLAGS="-B -j12"
REUSEOBJFLAGS="-j12"
CF="-flto=12 -static-libgcc -pipe -fwhole-program -fno-common -fno-exceptions -fno-stack-protector -fno-unwind-tables -fno-asynchronous-unwind-tables -fmerge-all-constants"
CFCLANG="-pipe -fno-common -fno-exceptions -fno-stack-protector -fno-unwind-tables -fno-asynchronous-unwind-tables -fmerge-all-constants"
LF="-Wl,-z,norelro -Wl,--hash-style=gnu -Wl,--build-id=none"
LFCLANG="-Wl,-z,norelro -Wl,--hash-style=gnu"
gmake $MAKEFLAGS allmulti CAT=2 MULTI_NAME=vlmcsdmulti-FreeBSD-10.2-x64-gcc CLIENT_NAME=vlmcs-FreeBSD-10.2-x64-gcc PROGRAM_NAME=vlmcsd-FreeBSD-10.2-x64-gcc CC=gcc5 CFLAGS="$CF" LDFLAGS="$LF"
gmake $MAKEFLAGS CLIENT_NAME=vlmcs-FreeBSD-10.2-x64 PROGRAM_NAME=vlmcsd-FreeBSD-10.2-x64 CC=clang36 CFLAGS="$CFCLANG" LDFLAGS="$LF"
rm -f vlmcs.o vlmcsd.o vlmcsdmulti.o *_all.*
gmake $REUSEOBJFLAGS vlmcsdmulti-FreeBSD-10.2-x64 MULTI_NAME=vlmcsdmulti-FreeBSD-10.2-x64 CC=clang36 CFLAGS="$CFCLANG" LDFLAGS="$LF"
gmake $MAKEFLAGS CLIENT_NAME=vlmcs-FreeBSD-10.2-x86 PROGRAM_NAME=vlmcsd-FreeBSD-10.2-x86 CC=clang36 CFLAGS="$CFCLANG -m32" LDFLAGS="$LF"
rm -f vlmcs.o vlmcsd.o vlmcsdmulti.o *_all.*
gmake $REUSEOBJFLAGS vlmcsdmulti-FreeBSD-10.2-x86 MULTI_NAME=vlmcsdmulti-FreeBSD-10.2-x86 CC=clang36 CFLAGS="$CFCLANG -m32" LDFLAGS="$LF"
gmake $MAKEFLAGS allmulti CAT=2 MULTI_NAME=vlmcsdmulti-FreeBSD-10.2-x86-gcc CLIENT_NAME=vlmcs-FreeBSD-10.2-x86-gcc PROGRAM_NAME=vlmcsd-FreeBSD-10.2-x86-gcc CC=gcc5 CFLAGS="$CF -m32 -DCOMPAT_32BIT" LDFLAGS="-L/usr/lib32 -B/usr/lib32 $LF"
gmake $MAKEFLAGS CAT=2 vlmcsd-FreeBSD-10.2-x64-threads-gcc PROGRAM_NAME=vlmcsd-FreeBSD-10.2-x64-threads-gcc THREADS=1 CC=gcc5 CFLAGS="$CF" LDFLAGS="-lpthread $LF"
gmake $MAKEFLAGS vlmcsd-FreeBSD-10.2-x64-threads PROGRAM_NAME=vlmcsd-FreeBSD-10.2-x64-threads THREADS=1 CC=clang36 CFLAGS="$CFCLANG" LDFLAGS="-lpthread $LF"
gmake $MAKEFLAGS vlmcsd-FreeBSD-10.2-x86-threads PROGRAM_NAME=vlmcsd-FreeBSD-10.2-x86-threads THREADS=1 CC=clang36 CFLAGS="$CFCLANG -m32" LDFLAGS="-lpthread $LF"
gmake $MAKEFLAGS CAT=2 vlmcsd-FreeBSD-10.2-x86-threads-gcc PROGRAM_NAME=vlmcsd-FreeBSD-10.2-x86-threads-gcc THREADS=1 CC=gcc5 CFLAGS="$CF -m32 -DCOMPAT_32BIT" LDFLAGS="-lpthread -L/usr/lib32 -B/usr/lib32 $LF"
gmake $MAKEFLAGS CRYPTO=openssl_with_aes CLIENT_NAME=vlmcs-FreeBSD-10.2-x64-openssl1.0.1-EXPERIMENTAL PROGRAM_NAME=vlmcsd-FreeBSD-10.2-x64-openssl1.0.1-EXPERIMENTAL CC=clang36 CFLAGS="$CFCLANG" LDFLAGS="$LF"
gmake $MAKEFLAGS CRYPTO=openssl_with_aes CLIENT_NAME=vlmcs-FreeBSD-10.2-x86-openssl1.0.1-EXPERIMENTAL PROGRAM_NAME=vlmcsd-FreeBSD-10.2-x86-openssl1.0.1-EXPERIMENTAL CC=clang36 CFLAGS="$CFCLANG -m32" LDFLAGS="$LF"
rm *.o
strip -s --strip-unneeded --remove-section=.eh_frame_hdr --remove-section=.eh_frame --remove-section=.note.gnu.gold-version --remove-section=.comment --remove-section=.note --remove-section=.note.gnu.build-id --remove-section=.note.ABI-tag vlmcs-* vlmcsd-* vlmcsdmulti-*
sstrip -z vlmcs-* vlmcsd-* vlmcsdmulti-*
sudo cp -af vlmcsd-FreeBSD-10.2-x86-gcc /usr/local/sbin/vlmcsd
sudo cp -af vlmcs-FreeBSD-10.2-x86-gcc /usr/local/bin/vlmcs
# Copy everything to distribution server
scp -p vlmcsdmulti-* vlmcsd-* vlmcs-* root@ubuntu64:x/binaries/FreeBSD/intel/

3511
make_linux Normal file

File diff suppressed because it is too large Load Diff

25
make_minix Normal file
View File

@ -0,0 +1,25 @@
#!/bin/sh
export VLMCSD_VERSION=svn$(ssh root@ubuntu64.internal "cd x; svnversion")
scp -p make_minix root@ubuntu64.internal:x
scp -pr root@ubuntu64.internal:x/* .
# Compile vlmcsd binaries for Minix 3
SUFFIX=-minix-$(uname -r)-x86
export CC=clang
export CFLAGS="-pipe -fno-common -fno-exceptions -fno-stack-protector -fno-unwind-tables -fno-asynchronous-unwind-tables -fmerge-all-constants"
export LDFLAGS="-Wl,--hash-style=sysv -Wl,-z,norelro -Wl,--build-id=none"
export PROGRAM_NAME=vlmcsd$SUFFIX
export CLIENT_NAME=vlmcs$SUFFIX
export MULTI_NAME=vlmcsdmulti$SUFFIX
gmake clean
gmake -B
rm -f vlmcsd.o vlmcs.o vlmcsdmulti.o
gmake $MULTI_NAME
strip -s --strip-unneeded --remove-section .eh_frame_hdr --remove-section .eh_frame --remove-section .ident --remove-section .note.minix.ident --remove-section .note.netbsd.pax --remove-section=.note.gnu.gold-version --remove-section=.comment --remove-section=.note --remove-section=.note.gnu.build-id --remove-section=.note.ABI-tag *$SUFFIX
scp -p *$SUFFIX root@ubuntu64.internal:x/binaries/Minix/intel/

35
make_netbsd Normal file
View File

@ -0,0 +1,35 @@
#!/usr/pkg/bin/bash
export VERBOSE=3
export DNS_PARSER=OS
rm -f vlmcsd-* vlmcs-* vlmcsdmulti-* *_all.* 2>/dev/null
rm -f vlmcsdmulti vlmcsd vlmcs 2>/dev/null
MAKEFLAGS="-B -j12"
REUSEOBJFLAGS="-j12"
CF="-flto=12 -static-libgcc -pipe -fwhole-program -fno-common -fno-exceptions -fno-stack-protector -fno-unwind-tables -fno-asynchronous-unwind-tables -fmerge-all-constants"
CF45="-static-libgcc -pipe -fno-common -fno-exceptions -fno-stack-protector -fno-unwind-tables -fno-asynchronous-unwind-tables -fmerge-all-constants"
CFCLANG="-pipe -fno-common -fno-exceptions -fno-stack-protector -fno-unwind-tables -fno-asynchronous-unwind-tables -fmerge-all-constants"
LF="-Wl,-z,norelro -Wl,--hash-style=sysv -Wl,--build-id=none"
LFCLANG="-Wl,-z,norelro -Wl,--hash-style=sysv"
gmake $MAKEFLAGS CC=/usr/pkg/gcc49/bin/gcc PROGRAM_NAME=vlmcsd-NetBSD-x64 CLIENT_NAME=vlmcs-NetBSD-x64 CFLAGS="$CF" LDFLAGS="$LF"
rm vlmcsd.o vlmcs.o
gmake vlmcsdmulti-NetBSD-x64 $REUSEOBJFLAGS CC=/usr/pkg/gcc49/bin/gcc CFLAGS="$CF" LDFLAGS="$LF" MULTI_NAME=vlmcsdmulti-NetBSD-x64
gmake allmulti $MAKEFLAGS CAT=2 MULTI_NAME=vlmcsdmulti-NetBSD-x86 PROGRAM_NAME=vlmcsd-NetBSD-x86 CLIENT_NAME=vlmcs-NetBSD-x86 CFLAGS="$CF45 -m32" LDFLAGS="$LF"
#gmake $MAKEFLAGS CC=clang PROGRAM_NAME=vlmcsd-NetBSD-x64-clang CLIENT_NAME=vlmcs-NetBSD-x64-clang CFLAGS="$CFCLANG" LDFLAGS="$LFCLANG"
rm *.o
strip -s --strip-unneeded --remove-section=.eh_frame_hdr --remove-section=.eh_frame --remove-section=.note.gnu.gold-version --remove-section=.comment --remove-section=.note --remove-section=.note.gnu.build-id --remove-section=.note.ABI-tag vlmcs-* vlmcsd-* vlmcsdmulti-*
#sstrip -z vlmcs-* vlmcsd-* vlmcsdmulti-*
cp -af vlmcsd-NetBSD-x86 /usr/local/sbin/vlmcsd
cp -af vlmcs-NetBSD-x86 /usr/local/bin/vlmcs
# Copy everything to distribution server
scp -p vlmcsdmulti-* vlmcsd-* vlmcs-* root@ubuntu64:x/binaries/NetBSD/intel/

33
make_openbsd Normal file
View File

@ -0,0 +1,33 @@
#!/usr/local/bin/bash
export VERBOSE=3
export DNS_PARSER=OS
rm -f vlmcsd-* vlmcs-* vlmcsdmulti-* *_all.* 2>/dev/null
rm -f vlmcsdmulti vlmcsd vlmcs 2>/dev/null
MAKEFLAGS="-B -j12"
REUSEOBJFLAGS="-j12"
CF="-static-libgcc -pipe -fwhole-program -fno-common -fno-exceptions -fno-stack-protector -fno-unwind-tables -fno-asynchronous-unwind-tables -fmerge-all-constants"
CF45="-static-libgcc -pipe -fno-common -fno-exceptions -fno-stack-protector -fno-unwind-tables -fno-asynchronous-unwind-tables -fmerge-all-constants"
CFCLANG="-pipe -fno-common -fno-exceptions -fno-stack-protector -fno-unwind-tables -fno-asynchronous-unwind-tables -fmerge-all-constants"
LF="-Wl,-z,norelro"
LFCLANG="-Wl,-z,norelro"
gmake allmulti CAT=2 $MAKEFLAGS CC=egcc MULTI_NAME=vlmcsdmulti-OpenBSD-x64 PROGRAM_NAME=vlmcsd-OpenBSD-x64 CLIENT_NAME=vlmcs-OpenBSD-x64 CFLAGS="$CF" LDFLAGS="$LF"
#gmake allmulti $MAKEFLAGS CAT=2 MULTI_NAME=vlmcsdmulti-OpenBSD-x86 PROGRAM_NAME=vlmcsd-OpenBSD-x86 CLIENT_NAME=vlmcs-OpenBSD-x86 CFLAGS="$CF45 -m32" LDFLAGS="$LF"
#gmake $MAKEFLAGS CC=clang PROGRAM_NAME=vlmcsd-OpenBSD-x64-clang CLIENT_NAME=vlmcs-OpenBSD-x64-clang CFLAGS="$CFCLANG" LDFLAGS="$LFCLANG"
rm *.o
strip -s --strip-unneeded --remove-section=.eh_frame_hdr --remove-section=.eh_frame --remove-section=.note.gnu.gold-version --remove-section=.comment --remove-section=.note --remove-section=.note.gnu.build-id --remove-section=.note.ABI-tag vlmcs-* vlmcsd-* vlmcsdmulti-*
#sstrip -z vlmcs-* vlmcsd-* vlmcsdmulti-*
cp -f vlmcsd-OpenBSD-x64 /usr/local/sbin/vlmcsd
cp -f vlmcs-OpenBSD-x64 /usr/local/bin/vlmcs
# Copy everything to distribution server
scp -p vlmcsdmulti-* vlmcsd-* vlmcs-* root@ubuntu64:x/binaries/OpenBSD/intel/

97
make_osx Normal file
View File

@ -0,0 +1,97 @@
#!/bin/bash
export VERBOSE=3
export DNS_PARSER=OS
rm vlmcsd-* vlmcs-* vlmcsdmulti-* *_all.* 2>/dev/null
rm vlmcsd vlmcs vlmcsdmulti 2>/dev/null
MAKEFLAGS="-j -B"
REUSEOBJFLAGS="-j"
CFGCC="-static-libgcc -mdynamic-no-pic -Os -flto=jobserver -fwhole-program -fno-common -fno-exceptions -fno-stack-protector -fno-unwind-tables -fno-asynchronous-unwind-tables -fmerge-all-constants"
CFCLANG="-mdynamic-no-pic -Os -flto -fno-common -fno-exceptions -fno-stack-protector -fno-unwind-tables -fno-asynchronous-unwind-tables -fmerge-all-constants"
CFGCC42="-static-libgcc -mdynamic-no-pic -Os -fno-common -fno-exceptions -fno-stack-protector -fno-unwind-tables -fno-asynchronous-unwind-tables -fmerge-all-constants"
make $MAKEFLAGS CLIENT_NAME=vlmcs-MacOSX-x86 PROGRAM_NAME=vlmcsd-MacOSX-x86 CC=clang CFLAGS="$CFCLANG" PLATFORMFLAGS="-m32 -march=core2 -mmacosx-version-min=10.0" && \
rm -f vlmcs.o vlmcsd.o vlmcsdmulti.o *_all.* && \
make $REUSEOBJFLAGS vlmcsdmulti-MacOSX-x86 MULTI_NAME=vlmcsdmulti-MacOSX-x86 CC=clang CFLAGS="$CFCLANG" PLATFORMFLAGS="-m32 -march=core2 -mmacosx-version-min=10.0" && \
make $MAKEFLAGS vlmcsd-MacOSX-x86-threads THREADS=1 PROGRAM_NAME=vlmcsd-MacOSX-x86-threads CC=clang CFLAGS="$CFCLANG" PLATFORMFLAGS="-m32 -march=core2 -mmacosx-version-min=10.0" && \
make $MAKEFLAGS CLIENT_NAME=vlmcs-MacOSX-x64 PROGRAM_NAME=vlmcsd-MacOSX-x64 CC=clang CFLAGS="$CFCLANG" PLATFORMFLAGS="-m64 -march=core2 -mmacosx-version-min=10.0" && \
rm -f vlmcs.o vlmcsd.o vlmcsdmulti.o *_all.* && \
make $REUSEOBJFLAGS vlmcsdmulti-MacOSX-x64 MULTI_NAME=vlmcsdmulti-MacOSX-x64 CC=clang CFLAGS="$CFCLANG" PLATFORMFLAGS="-m64 -march=core2 -mmacosx-version-min=10.0" && \
make $MAKEFLAGS vlmcsd-MacOSX-x64-threads THREADS=1 PROGRAM_NAME=vlmcsd-MacOSX-x64-threads CC=clang CFLAGS="$CFCLANG" PLATFORMFLAGS="-m64 -march=core2 -mmacosx-version-min=10.0" && \
make $MAKEFLAGS CLIENT_NAME=vlmcs-MacOSX-x86-openssl-EXPERIMENTAL PROGRAM_NAME=vlmcsd-MacOSX-x86-openssl-EXPERIMENTAL CRYPTO=openssl_with_aes_soft CC=clang CFLAGS="$CFCLANG" PLATFORMFLAGS="-m32 -march=core2 -mmacosx-version-min=10.4" && \
make $MAKEFLAGS CLIENT_NAME=vlmcs-MacOSX-x64-openssl-EXPERIMENTAL PROGRAM_NAME=vlmcsd-MacOSX-x64-openssl-EXPERIMENTAL CRYPTO=openssl_with_aes_soft CC=clang CFLAGS="$CFCLANG" PLATFORMFLAGS="-m64 -march=core2 -mmacosx-version-min=10.4" && \
#make $MAKEFLAGS CLIENT_NAME=vlmcs-iOS-7.1-armv7 PROGRAM_NAME=vlmcsd-iOS-7.1-armv7 CC=clang CFLAGS="$CFCLANG" PLATFORMFLAGS="-mthumb -m32 -arch armv7 -miphoneos-version-min=1.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk" && \
rm -f vlmcs.o vlmcsd.o vlmcsdmulti.o *_all.* && \
#make $REUSEOBJFLAGS vlmcsdmulti-iOS-7.1-armv7 MULTI_NAME=vlmcsdmulti-iOS-7.1-armv7 CC=clang CFLAGS="$CFCLANG" PLATFORMFLAGS="-mthumb -m32 -arch armv7 -miphoneos-version-min=1.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk" && \
make $MAKEFLAGS CLIENT_NAME=vlmcs-iOS-8.4-armv7 PROGRAM_NAME=vlmcsd-iOS-8.4-armv7 CC=clang CFLAGS="$CFCLANG" PLATFORMFLAGS="-mthumb -m32 -arch armv7 -miphoneos-version-min=1.0 -isysroot ~/toolchains/iPhoneOS8.4.sdk" && \
rm -f vlmcs.o vlmcsd.o vlmcsdmulti.o *_all.* && \
make $REUSEOBJFLAGS vlmcsdmulti-iOS-8.4-armv7 MULTI_NAME=vlmcsdmulti-iOS-8.4-armv7 CC=clang CFLAGS="$CFCLANG" PLATFORMFLAGS="-mthumb -m32 -arch armv7 -miphoneos-version-min=1.0 -isysroot ~/toolchains/iPhoneOS8.4.sdk" && \
make $MAKEFLAGS CLIENT_NAME=vlmcs-iOS-8.4-armv8-aarch64 PROGRAM_NAME=vlmcsd-iOS-8.4-armv8-aarch64 CC=clang CFLAGS="$CFCLANG" PLATFORMFLAGS="-m64 -arch arm64 -miphoneos-version-min=7.0 -isysroot ~/toolchains/iPhoneOS8.4.sdk" && \
rm -f vlmcs.o vlmcsd.o vlmcsdmulti.o *_all.* && \
make $REUSEOBJFLAGS vlmcsdmulti-iOS-8.4-armv8-aarch64 MULTI_NAME=vlmcsdmulti-iOS-8.4-armv8-aarch64 CC=clang CFLAGS="$CFCLANG" PLATFORMFLAGS="-m64 -arch arm64 -miphoneos-version-min=7.0 -isysroot ~/toolchains/iPhoneOS8.4.sdk" && \
make $MAKEFLAGS CLIENT_NAME=vlmcs-iOS-6.1-armv7 PROGRAM_NAME=vlmcsd-iOS-6.1-armv7 CC=clang CFLAGS="$CFCLANG" PLATFORMFLAGS="-mthumb -m32 -arch armv7 -miphoneos-version-min=1.0 --sysroot ~/toolchains/iPhoneOS6.1.sdk -isysroot ~/toolchains/iPhoneOS6.1.sdk" && \
rm -f vlmcs.o vlmcsd.o vlmcsdmulti.o *_all.* && \
make $REUSEOBJFLAGS vlmcsdmulti-iOS-6.1-armv7 MULTI_NAME=vlmcsdmulti-iOS-6.1-armv7 CC=clang CFLAGS="$CFCLANG" PLATFORMFLAGS="-mthumb -m32 -arch armv7 -miphoneos-version-min=1.0 --sysroot ~/toolchains/iPhoneOS6.1.sdk -isysroot ~/toolchains/iPhoneOS6.1.sdk" && \
make $MAKEFLAGS CLIENT_NAME=vlmcs-iOS-5.1-armv7-clang3.4 PROGRAM_NAME=vlmcsd-iOS-5.1-armv7-clang3.4 CC=clang CFLAGS="$CFCLANG" PLATFORMFLAGS="-mthumb -m32 -arch armv7 -miphoneos-version-min=1.0 --sysroot ~/toolchains/iPhoneOS5.1.sdk -isysroot ~/toolchains/iPhoneOS5.1.sdk" && \
rm -f vlmcs.o vlmcsd.o vlmcsdmulti.o *_all.* && \
make $REUSEOBJFLAGS vlmcsdmulti-iOS-5.1-armv7-clang3.4 MULTI_NAME=vlmcsdmulti-iOS-5.1-armv7-clang3.4 CC=clang CFLAGS="$CFCLANG" PLATFORMFLAGS="-mthumb -m32 -arch armv7 -miphoneos-version-min=1.0 --sysroot ~/toolchains/iPhoneOS5.1.sdk -isysroot ~/toolchains/iPhoneOS5.1.sdk" && \
#PATH=~/toolchains/iOS5.1-MacOS-Lion/usr/bin:$PATH clang --version
PATH=~/toolchains/iOS5.1-MacOS-Lion/usr/bin:$PATH make $MAKEFLAGS CLIENT_NAME=vlmcs-iOS-5.1-armv6-clang3.1 PROGRAM_NAME=vlmcsd-iOS-5.1-armv6-clang3.1 CC=clang CFLAGS="$CFCLANG" PLATFORMFLAGS="-arch armv6 -miphoneos-version-min=1.0 --sysroot ~/toolchains/iPhoneOS5.1.sdk -isysroot ~/toolchains/iPhoneOS5.1.sdk" && \
rm -f vlmcs.o vlmcsd.o vlmcsdmulti.o *_all.* && \
PATH=~/toolchains/iOS5.1-MacOS-Lion/usr/bin:$PATH make $REUSEOBJFLAGS vlmcsdmulti-iOS-5.1-armv6-clang3.1 MULTI_NAME=vlmcsdmulti-iOS-5.1-armv6-clang3.1 CC=clang CFLAGS="$CFCLANG" PLATFORMFLAGS="-arch armv6 -miphoneos-version-min=1.0 --sysroot ~/toolchains/iPhoneOS5.1.sdk -isysroot ~/toolchains/iPhoneOS5.1.sdk" && \
PATH=~/toolchains/gcc4.2/usr/bin/bin:$PATH make $MAKEFLAGS CLIENT_NAME=vlmcs-iOS-4.1-armv6-llvm-gcc4.2 PROGRAM_NAME=vlmcsd-iOS-4.1-armv6-llvm-gcc4.2 CC=llvm-g++-4.2 CFLAGS="$CFGCC42" PLATFORMFLAGS="-arch armv6 -miphoneos-version-min=1.0 --sysroot ~/toolchains/iPhoneOS4.1.sdk -isysroot ~/toolchains/iPhoneOS4.1.sdk" && \
rm -f vlmcs.o vlmcsd.o vlmcsdmulti.o *_all.* && \
PATH=~/toolchains/gcc4.2/usr/bin/bin:$PATH make $REUSEOBJFLAGS vlmcsdmulti-iOS-4.1-armv6-llvm-gcc4.2 MULTI_NAME=vlmcsdmulti-iOS-4.1-armv6-llvm-gcc4.2 CC=llvm-g++-4.2 CFLAGS="$CFGCC42" PLATFORMFLAGS="-arch armv6 -miphoneos-version-min=1.0 --sysroot ~/toolchains/iPhoneOS4.1.sdk -isysroot ~/toolchains/iPhoneOS4.1.sdk" && \
#PATH=~/toolchains/gcc4.2/usr/bin:$PATH make $MAKEFLAGS CLIENT_NAME=vlmcs-iOS-4.1-armv7-clang PROGRAM_NAME=vlmcsd-iOS-4.1-armv7-llvm-clang CC=~/toolchains/gcc4.2/usr/bin/bin/clang CFLAGS="$CFGCC42" PLATFORMFLAGS="-mthumb -arch armv7 -miphoneos-version-min=4.1 --sysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.1.sdk -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.1.sdk" && \
#rm -f vlmcs.o vlmcsd.o vlmcsdmulti.o && \
#PATH=~/toolchains/gcc4.2/usr/bin:$PATH make $REUSEOBJFLAGS vlmcsdmulti-iOS-4.1-armv7-llvm-clang MULTI_NAME=vlmcsdmulti-iOS-4.1-armv7-llvm-clang CC=~/toolchains/gcc4.2/usr/bin/bin/clang CFLAGS="$CFGCC42" PLATFORMFLAGS="-mthumb -arch armv7 -miphoneos-version-min=4.1 --sysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.1.sdk -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.1.sdk" && \
PATH=~/toolchains/gcc4.2/usr/bin:$PATH make -Bj PROGRAM_NAME=vlmcsd-MacOSX-ppc CLIENT_NAME=vlmcs-MacOSX-ppc CC=gcc CFLAGS="$CFGCC42 -isysroot ~/toolchains/MacOSX10.5.sdk -arch ppc -mmacosx-version-min=10.0"
rm -f vlmcs.o vlmcsd.o vlmcsdmulti.o *_all.* && \
PATH=~/toolchains/gcc4.2/usr/bin:$PATH make -j vlmcsdmulti-MacOSX-ppc MULTI_NAME=vlmcsdmulti-MacOSX-ppc CC=gcc CFLAGS="$CFGCC42 -isysroot ~/toolchains/MacOSX10.5.sdk -arch ppc -mmacosx-version-min=10.0"
make $MAKEFLAGS CLIENT_NAME=vlmcs-MacOSX-x86-gcc PROGRAM_NAME=vlmcsd-MacOSX-x86-gcc CC=gcc-5 CFLAGS="$CFGCC" PLATFORMFLAGS="-m32 -march=core2 -mmacosx-version-min=10.0" && \
rm -f vlmcs.o vlmcsd.o vlmcsdmulti.o *_all.* && \
make $REUSEOBJFLAGS vlmcsdmulti-MacOSX-x86-gcc MULTI_NAME=vlmcsdmulti-MacOSX-x86-gcc CC=gcc-5 CFLAGS="$CFGCC" PLATFORMFLAGS="-m32 -march=core2 -mmacosx-version-min=10.0" && \
make $MAKEFLAGS vlmcsd-MacOSX-x86-threads-gcc THREADS=1 PROGRAM_NAME=vlmcsd-MacOSX-x86-threads-gcc CC=gcc-5 CFLAGS="$CFGCC" PLATFORMFLAGS="-m32 -march=core2 -mmacosx-version-min=10.0" && \
make $MAKEFLAGS CLIENT_NAME=vlmcs-MacOSX-x64-gcc PROGRAM_NAME=vlmcsd-MacOSX-x64-gcc CC=gcc-5 CFLAGS="$CFGCC" PLATFORMFLAGS="-m64 -march=core2 -mmacosx-version-min=10.0" && \
rm -f vlmcs.o vlmcsd.o vlmcsdmulti.o *_all.* && \
make $REUSEOBJFLAGS vlmcsdmulti-MacOSX-x64-gcc MULTI_NAME=vlmcsdmulti-MacOSX-x64-gcc CC=gcc-5 CFLAGS="$CFGCC" PLATFORMFLAGS="-m64 -march=core2 -mmacosx-version-min=10.0" && \
make $MAKEFLAGS vlmcsd-MacOSX-x64-threads-gcc THREADS=1 PROGRAM_NAME=vlmcsd-MacOSX-x64-threads-gcc CC=gcc-5 CFLAGS="$CFGCC" PLATFORMFLAGS="-m64 -march=core2 -mmacosx-version-min=10.0" && \
# Sign the iOS binaries
#ldid -S *iOS*
#strip vlmcs-* vlmcsd-* vlmcsdmulti-*
rm -f *.o *_all.*
rm -fr *.dSYM
sudo cp -p vlmcs-MacOSX-x86-gcc /usr/local/bin/vlmcs
sudo cp -p vlmcsd-MacOSX-x86-gcc /usr/local/bin/vlmcsd
sudo mkdir -p /usr/local/share/man/man8
sudo mkdir -p /usr/local/share/man/man1
sudo mkdir -p /usr/local/share/man/man7
sudo mkdir -p /usr/local/share/man/man5
sudo cp -p vlmcsd.8 /usr/local/share/man/man8
sudo cp -p vlmcs.1 vlmcsdmulti.1 /usr/local/share/man/man1
sudo cp -p vlmcsd.7 /usr/local/share/man/man7
sudo cp -p vlmcsd.ini.5 //usr/local/share/man/man5
# Copy the stuff to distribution server
scp -p vlmcsd-MacOSX-x* vlmcs-MacOSX-x* vlmcsdmulti-MacOSX-x* root@ubuntu64:x/binaries/MacOSX/intel
scp -p vlmcsd-MacOSX-ppc* vlmcs-MacOSX-ppc* vlmcsdmulti-MacOSX-ppc* root@ubuntu64:x/binaries/MacOSX/ppc
scp -p vlmcsd-iOS* vlmcs-iOS* vlmcsdmulti-iOS* root@ubuntu64:x/binaries/iOS/arm

57
make_solaris Normal file
View File

@ -0,0 +1,57 @@
#!/bin/sh
export VERBOSE=3
export CAT=2
if [ `uname -s` != "SunOS" ]; then
echo "This is no SunOS operating system."
exit 3
fi
SOLARIS_VERSION=`uname -v`
rm -f vlmcsd-* vlmcs-* vlmcsdmulti-* *_all.* 2>/dev/null
rm -f vlmcsdmulti vlmcsd vlmcs 2>/dev/null
MAKEFLAGS="-B -j`nproc`"
REUSEOBJFLAGS="-j`nproc`"
CF="-fno-common -fno-exceptions -fno-stack-protector -fno-unwind-tables -fno-asynchronous-unwind-tables -fmerge-all-constants -Wno-char-subscripts"
LF="-fwhole-program -Wl,-z,norelro -Wl,--hash-style=sysv -Wl,--build-id=none"
# 32 bit
if [ "$CAT" != "" ]; then
gmake $MAKEFLAGS LD_ALTEXEC=/usr/bin/gld vlmcs-Solaris$SOLARIS_VERSION-x86 vlmcsd-Solaris$SOLARIS_VERSION-x86 vlmcsdmulti-Solaris$SOLARIS_VERSION-x86 CLIENT_NAME=vlmcs-Solaris$SOLARIS_VERSION-x86 PROGRAM_NAME=vlmcsd-Solaris$SOLARIS_VERSION-x86 MULTI_NAME=vlmcsdmulti-Solaris$SOLARIS_VERSION-x86 CC=gcc CFLAGS="$CF" LDFLAGS="$LF"
else
gmake $MAKEFLAGS LD_ALTEXEC=/usr/bin/gld CLIENT_NAME=vlmcs-Solaris$SOLARIS_VERSION-x86 PROGRAM_NAME=vlmcsd-Solaris$SOLARIS_VERSION-x86 CC=gcc CFLAGS="$CF" LDFLAGS="$LF"
rm -f vlmcs.o vlmcsd.o vlmcsdmulti.o *_all.*
gmake $REUSEOBJFLAGS LD_ALTEXEC=/usr/bin/gld vlmcsdmulti-Solaris$SOLARIS_VERSION-x86 MULTI_NAME=vlmcsdmulti-Solaris$SOLARIS_VERSION-x86 CC=gcc CFLAGS="$CF" LDFLAGS="$LF"
fi
gmake $MAKEFLAGS LD_ALTEXEC=/usr/bin/gld vlmcsd-Solaris$SOLARIS_VERSION-x86-threads PROGRAM_NAME=vlmcsd-Solaris$SOLARIS_VERSION-x86-threads CC=gcc THREADS=1 CFLAGS="$CF" LDFLAGS="-lpthread $LF"
gmake $MAKEFLAGS LD_ALTEXEC=/usr/bin/gld CLIENT_NAME=vlmcs-Solaris$SOLARIS_VERSION-x86-openssl1.0-EXPERIMENTAL CRYPTO=openssl_with_aes PROGRAM_NAME=vlmcsd-Solaris$SOLARIS_VERSION-x86-openssl1.0-EXPERIMENTAL CC=gcc CFLAGS="$CF" LDFLAGS="$LF"
# 64 bit
LF="$LF -Wl,-melf_x86_64_sol2"
if [ "$CAT" != "" ]; then
gmake $MAKEFLAGS LD_ALTEXEC=/usr/bin/gld vlmcsdmulti-Solaris$SOLARIS_VERSION-x64 vlmcs-Solaris$SOLARIS_VERSION-x64 vlmcsd-Solaris$SOLARIS_VERSION-x64 MULTI_NAME=vlmcsdmulti-Solaris$SOLARIS_VERSION-x64 CLIENT_NAME=vlmcs-Solaris$SOLARIS_VERSION-x64 PROGRAM_NAME=vlmcsd-Solaris$SOLARIS_VERSION-x64 CC=gcc CFLAGS="$CF" LDFLAGS="$LF" PLATFORMFLAGS="-m64"
else
gmake $MAKEFLAGS LD_ALTEXEC=/usr/bin/gld CLIENT_NAME=vlmcs-Solaris$SOLARIS_VERSION-x64 PROGRAM_NAME=vlmcsd-Solaris$SOLARIS_VERSION-x64 CC=gcc CFLAGS="$CF" LDFLAGS="$LF" PLATFORMFLAGS="-m64"
rm -f vlmcs.o vlmcsd.o vlmcsdmulti.o *_all.*
gmake $REUSEOBJFLAGS LD_ALTEXEC=/usr/bin/gld vlmcsdmulti-Solaris$SOLARIS_VERSION-x64 MULTI_NAME=vlmcsdmulti-Solaris$SOLARIS_VERSION-x64 CC=gcc CFLAGS="$CF" LDFLAGS="$LF" PLATFORMFLAGS="-m64"
fi
gmake $MAKEFLAGS LD_ALTEXEC=/usr/bin/gld vlmcsd-Solaris$SOLARIS_VERSION-x64-threads PROGRAM_NAME=vlmcsd-Solaris$SOLARIS_VERSION-x64-threads CC=gcc THREADS=1 CFLAGS="$CF" LDFLAGS="$LF -lpthread" PLATFORMFLAGS="-m64"
gmake $MAKEFLAGS LD_ALTEXEC=/usr/bin/gld CLIENT_NAME=vlmcs-Solaris$SOLARIS_VERSION-x64-openssl1.0-EXPERIMENTAL CRYPTO=openssl_with_aes PROGRAM_NAME=vlmcsd-Solaris$SOLARIS_VERSION-x64-openssl1.0-EXPERIMENTAL CC=gcc CFLAGS="$CF" LDFLAGS="$LF" PLATFORMFLAGS="-m64"
rm -f *.o *_all.*
gstrip -s --strip-unneeded --remove-section=.note.gnu.gold-version --remove-section=.comment --remove-section=.note --remove-section=.note.gnu.build-id --remove-section=.note.ABI-tag vlmcs-* vlmcsd-*
#gstrip -s --strip-unneeded --remove-section=.eh_frame_hdr --remove-section=.eh_frame --remove-section=.note.gnu.gold-version --remove-section=.comment --remove-section=.note --remove-section=.note.gnu.build-id --remove-section=.note.ABI-tag vlmcs-* vlmcsd-*
#sstrip -z vlmcs-* vlmcsd-*
# Copy stuff to distribution server
scp -p vlmcsd-* vlmcs-* vlmcsdmulti-* root@ubuntu64:x/binaries/Solaris/intel

79
make_windows Normal file
View File

@ -0,0 +1,79 @@
#!/bin/bash
rm -f cygkms*.dll libkms*.dll vlmcsd-* vlmcs-* vlmcsdmulti-* *_all.* vlmcsd.exe vlmcs.exe vlmcsdmulti.exe 2> /dev/null
export CAT=2
export VERBOSE=3
NUMCPU=`cat /proc/cpuinfo | grep "processor" | wc -l`
CF="-Wno-missing-braces -fno-common -fno-exceptions -fno-non-call-exceptions -fno-stack-protector -fmerge-all-constants -fno-unwind-tables -fno-asynchronous-unwind-tables -pipe"
CFMSRPC="-Wno-missing-braces -Wno-unused-variable $CF" # -fno-common -fno-stack-protector -fmerge-all-constants -pipe"
PF32=""
PF64="-mpreferred-stack-boundary=4 -march=nocona -mtune=generic"
LFCYG32="-fwhole-program -Wl,--nxcompat,--dynamicbase,--tsaware,--large-address-aware"
LFWIN32="-fwhole-program -lws2_32 -Wl,--nxcompat,--dynamicbase,--tsaware,--large-address-aware"
LFCYG64="-fwhole-program -Wl,--nxcompat,--dynamicbase,--tsaware"
LFWIN64="-fwhole-program -lws2_32 -Wl,--nxcompat,--dynamicbase,--tsaware"
MAKEFLAGS="-j$NUMCPU -B"
REUSEFLAGS="-j$NUMCPU"
make $MAKEFLAGS cygkms32.dll FEATURES=minimum THREADS=1 DLL_NAME=cygkms32.dll DNS_PARSER=internal CC=i686-pc-cygwin-gcc.exe CFLAGS="$CF -flto=jobserver -fvisibility=hidden" PLATFORMFLAGS="$PF32" LDFLAGS="$LFCYG32"
make $MAKEFLAGS cygkms64.dll FEATURES=minimum THREADS=1 DLL_NAME=cygkms64.dll DNS_PARSER=internal CC=x86_64-pc-cygwin-gcc.exe CFLAGS="$CF -flto=jobserver -fvisibility=hidden" PLATFORMFLAGS="$PF64" LDFLAGS="$LFCYG64"
make $MAKEFLAGS all vlmcsdmulti-cygwin-x86 THREADS=1 DNS_PARSER=internal CLIENT_NAME=vlmcs-cygwin-x86 PROGRAM_NAME=vlmcsd-cygwin-x86 MULTI_NAME=vlmcsdmulti-cygwin-x86 CC=i686-pc-cygwin-gcc.exe CFLAGS="$CF" PLATFORMFLAGS="$PF32" LDFLAGS="$LFCYG32"
make $MAKEFLAGS all vlmcsdmulti-cygwin-x64 THREADS=1 DNS_PARSER=internal CLIENT_NAME=vlmcs-cygwin-x64 PROGRAM_NAME=vlmcsd-cygwin-x64 MULTI_NAME=vlmcsdmulti-cygwin-x64 CC=x86_64-pc-cygwin-gcc.exe CFLAGS="$CF" PLATFORMFLAGS="$PF64" LDFLAGS="$LFCYG64"
make $MAKEFLAGS MSRPC=1 THREADS=1 DNS_PARSER=internal CLIENT_NAME=vlmcs-cygwin-msrpc-x86 PROGRAM_NAME=vlmcsd-cygwin-msrpc-x86 MULTI_NAME=vlmcsdmulti-cygwin-msrpc-x86 CC=i686-pc-cygwin-gcc.exe CFLAGS="$CF -fasynchronous-unwind-tables" PLATFORMFLAGS="$PF32" LDFLAGS="$LFCYG32"
make $MAKEFLAGS MSRPC=1 THREADS=1 DNS_PARSER=internal CLIENT_NAME=vlmcs-cygwin-msrpc-x64 PROGRAM_NAME=vlmcsd-cygwin-msrpc-x64 MULTI_NAME=vlmcsdmulti-cygwin-msrpc-x64 CC=x86_64-pc-cygwin-gcc.exe CFLAGS="$CFMSRPC" PLATFORMFLAGS="$PF64" LDFLAGS="$LFCYG64"
unset CAT
make $MAKEFLAGS vlmcsdmulti-cygwin-msrpc-x64 MSRPC=1 THREADS=1 DNS_PARSER=internal MULTI_NAME=vlmcsdmulti-cygwin-msrpc-x64 CC=x86_64-pc-cygwin-gcc.exe CFLAGS="$CFMSRPC -flto=jobserver" PLATFORMFLAGS="$PF64" LDFLAGS="$LFCYG64"
make $MAKEFLAGS vlmcsdmulti-cygwin-msrpc-x86 MSRPC=1 THREADS=1 DNS_PARSER=internal MULTI_NAME=vlmcsdmulti-cygwin-msrpc-x86 CC=i686-pc-cygwin-gcc.exe CFLAGS="$CFMSRPC -flto=jobserver" PLATFORMFLAGS="$PF32" LDFLAGS="$LFCYG32"
export CAT=2
make $MAKEFLAGS THREADS=1 MSRPC=1 DNS_PARSER=internal CLIENT_NAME=vlmcs-cygwin-msrpc-x86-openssl-EXPERIMENTAL CRYPTO=openssl_with_aes PROGRAM_NAME=vlmcsd-cygwin-x86-openssl-EXPERIMENTAL CC=i686-pc-cygwin-gcc.exe CFLAGS="$CFMSRPC" PLATFORMFLAGS="$PF32" LDFLAGS="$LFCYG32"
make $MAKEFLAGS THREADS=1 MSRPC=1 DNS_PARSER=internal CLIENT_NAME=vlmcs-cygwin-msrpc-x64-openssl-EXPERIMENTAL CRYPTO=openssl_with_aes PROGRAM_NAME=vlmcsd-cygwin-x64-openssl-EXPERIMENTAL CC=x86_64-pc-cygwin-gcc.exe CFLAGS="$CFMSRPC" PLATFORMFLAGS="$PF64" LDFLAGS="$LFCYG64"
export CAT=2
make $MAKEFLAGS libkms32.dll CRYPTO=windows FEATURES=minimum THREADS=1 DLL_NAME=libkms32.dll CC=i686-w64-MingW32-gcc.exe CFLAGS="$CF -flto=jobserver -fvisibility=hidden" PLATFORMFLAGS="$PF32" LDFLAGS="-static-libgcc $LFWIN32"
make $MAKEFLAGS libkms64.dll CRYPTO=windows FEATURES=minimum THREADS=1 DLL_NAME=libkms64.dll CC=x86_64-w64-MingW32-gcc.exe CFLAGS="$CF -flto=jobserver -fvisibility=hidden" PLATFORMFLAGS="$PF64" LDFLAGS="-static-libgcc $LFWIN64"
make $MAKEFLAGS all vlmcsdmulti-Windows-x86 THREADS=1 CRYPTO=windows CLIENT_NAME=vlmcs-Windows-x86 PROGRAM_NAME=vlmcsd-Windows-x86 MULTI_NAME=vlmcsdmulti-Windows-x86 CC=i686-w64-MingW32-gcc.exe CFLAGS="$CF" PLATFORMFLAGS="$PF32" LDFLAGS="$LFWIN32"
make $MAKEFLAGS all vlmcsdmulti-Windows-x64 THREADS=1 CRYPTO=windows CLIENT_NAME=vlmcs-Windows-x64 PROGRAM_NAME=vlmcsd-Windows-x64 MULTI_NAME=vlmcsdmulti-Windows-x64 CC=x86_64-w64-MingW32-gcc.exe CFLAGS="$CF" PLATFORMFLAGS="$PF64" LDFLAGS="$LFWIN64"
make -Bj MSRPC=1 CRYPTO=windows CLIENT_NAME=vlmcs-Windows-msrpc-x86 PROGRAM_NAME=vlmcsd-Windows-msrpc-x86 MULTI_NAME=vlmcsdmulti-Windows-msrpc-x86 CC=i686-w64-MingW32-gcc.exe CFLAGS="$CFMSRPC" PLATFORMFLAGS="$PF32" LDFLAGS="-Wl,--nxcompat,--dynamicbase,--tsaware,--large-address-aware"
make $MAKEFLAGS THREADS=1 MSRPC=1 CRYPTO=windows CLIENT_NAME=vlmcs-Windows-msrpc-x64 PROGRAM_NAME=vlmcsd-Windows-msrpc-x64 MULTI_NAME=vlmcsdmulti-Windows-msrpc-x64 CC=x86_64-w64-MingW32-gcc.exe CFLAGS="$CFMSRPC" PLATFORMFLAGS="$PF64" LDFLAGS="$LFCYG64"
unset CAT
make $MAKEFLAGS vlmcsdmulti-Windows-msrpc-x86 THREADS=1 MSRPC=1 CRYPTO=windows MULTI_NAME=vlmcsdmulti-Windows-msrpc-x86 CC=i686-w64-MingW32-gcc.exe CFLAGS="$CFMSRPC" PLATFORMFLAGS="$PF32" LDFLAGS="-Wl,--nxcompat,--dynamicbase,--tsaware,--large-address-aware"
make $MAKEFLAGS vlmcsdmulti-Windows-msrpc-x64 THREADS=1 MSRPC=1 CRYPTO=windows MULTI_NAME=vlmcsdmulti-Windows-msrpc-x64 CC=x86_64-w64-MingW32-gcc.exe CFLAGS="$CFMSRPC" PLATFORMFLAGS="$PF64" LDFLAGS="$LFCYG64"
export CAT=2
rm -f *_all.* *.o 2> /dev/null &
echo ""
echo "Installing binaries"
cp -p vlmcs-cygwin-x64.exe /usr/local/bin/vlmcs &
cp -p vlmcsd-cygwin-x64.exe /usr/local/bin/vlmcsd &
cp -p cygkms64.dll /usr/local/bin/cygkms.dll &
cp -p libkms32.dll /cygdrive/c/nttools/x86 &
cp -p libkms64.dll /cygdrive/c/nttools/x64 &
cp -p vlmcsdmulti-Windows-x86.exe /cygdrive/c/nttools/x86/vlmcsdmulti.exe
cmd /C mklink c:\\nttools\\x86\\vlmcsd.exe vlmcsdmulti.exe 2> /dev/null &
cmd /C mklink c:\\nttools\\x86\\vlmcs.exe vlmcsdmulti.exe 2> /dev/null &
echo "Installing man pages"
mkdir -p /usr/share/man/man8
mkdir -p /usr/share/man/man1
mkdir -p /usr/share/man/man7
mkdir -p /usr/share/man/man5
cp -p vlmcsd.7 /usr/share/man/man7
cp -p vlmcsd.8 /usr/share/man/man8
cp -p vlmcsd.ini.5 /usr/share/man/man5
cp -p vlmcs.1 vlmcsdmulti.1 /usr/share/man/man1
bzip2 -f /usr/share/man/man5/vlmcsd.ini.5 /usr/share/man/man7/vlmcsd.7 /usr/share/man/man8/vlmcsd.8 /usr/share/man/man1/vlmcs.1 /usr/share/man/man1/vlmcsdmulti.1 &
# Copy stuff to distribution server
scp -p vlmcsd-* vlmcs-* vlmcsdmulti-* *.dll root@ubuntu64:x/binaries/Windows/intel

17
make_windows_native Normal file
View File

@ -0,0 +1,17 @@
#!/bin/bash
#
# To use on x64 hosted native multilib compiler toolchain
#
rm vlmcsd-*
rm vlmcsd
MAKEFLAGS="-j -B"
make $MAKEFLAGS PROGRAM_NAME=vlmcsd-mingw64-x86 CC=x86_64-w64-mingw32-gcc.exe CFLAGS="-flto -m32" "PLATFORMFLAGS=-march=i686 -mtune=generic" "LDFLAGS=-lcrypto -lz -lkernel32 -ladvapi32 -lws2_32 -lgdi32"
make $MAKEFLAGS PROGRAM_NAME=vlmcsd-mingw64-x64 CC=x86_64-w64-mingw32-gcc.exe CFLAGS="-flto" "PLATFORMFLAGS=-mtune=generic" "LDFLAGS=-lcrypto -lz -lkernel32 -ladvapi32 -lws2_32 -lgdi32"
make $MAKEFLAGS CRYPTO=openssl_with_aes PROGRAM_NAME=vlmcsd-mingw64-x86-openssl CC=x86_64-w64-mingw32-gcc.exe CFLAGS="-flto -m32" "PLATFORMFLAGS=-march=i686 -mtune=generic" "LDFLAGS=-lcrypto -lz -lkernel32 -ladvapi32 -lws2_32 -lgdi32"
make $MAKEFLAGS CRYPTO=openssl_with_aes PROGRAM_NAME=vlmcsd-mingw64-x64-openssl CC=x86_64-w64-mingw32-gcc.exe CFLAGS="-flto" "PLATFORMFLAGS=-mtune=generic" "LDFLAGS=-lcrypto -lz -lkernel32 -ladvapi32 -lws2_32 -lgdi32"
rm *.o

191
msrpc-client.c Normal file
View File

@ -0,0 +1,191 @@
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#ifdef USE_MSRPC
#if !defined(_WIN32) && !defined(__CYGWIN__)
#error MSRPC is only available with native Windows or Cygwin
#endif
#include "msrpc-client.h"
#include <stdio.h>
#include "output.h"
#include "helpers.h"
#if __amd64 || defined(_M_AMD64) // 64-bit
#ifndef _M_AMD64
#define _M_AMD64
#endif // _M_AMD64
#include "KMSServer_c_x64_mingw_gcc.c"
#else // 32-bit
#include "KMSServer_c_mingw_gcc.c"
#endif // 32-bit
static RPC_CSTR stringBinding;
jmp_buf jmp;
RPC_STATUS PreviousRpcCallFailed = RPC_S_OK;
/*
* Creates an RPC string binding that is used to connect to the server.
* Input is host:port, e.g. "[::1]:1688" or "127.0.0.1:1688"
* Output is for example "ncacn_ip_tcp:127.0.0.1[endpoint=1688]"
*/
#if !__amd64
#pragma GCC optimize("O0") ////TODO: Find out why gcc needs -O0 for RPC handling
#endif
static RPC_STATUS createStringBinding(char *const addr, RPC_CSTR* stringBinding)
{
char *szHost, *szPort;
parseAddress(addr, &szHost, &szPort);
return RpcStringBindingComposeA
(
NULL, /* UUID */
(RPC_CSTR)"ncacn_ip_tcp", /* use TCP */
(RPC_CSTR)szHost, /* host name or IP address */
(RPC_CSTR)szPort, /* endpoint (TCP port here) */
NULL, /* options */
stringBinding /* resulting string binding */
);
}
/*
* This does not actually connect to a TCP port because MS RPC doesn't connect
* before the actual RPC call is made. So this a stub
*/
RpcCtx connectToAddress(char *const addr, const int AddressFamily_unused, int_fast8_t showHostName_unused)
{
RPC_STATUS status;
printf("Connecting to %s ... ", addr);
if ((status = createStringBinding(addr, &stringBinding)) != RPC_S_OK)
{
errorout("%s\n", win_strerror(status));
return !0;
}
if (PreviousRpcCallFailed)
{
errorout("%s\n", win_strerror(PreviousRpcCallFailed));
return !0;
}
printf("successful\n");
return 0;
}
/*
* Does not do RPC binding on the wire. Just initializes the interface
*/
RpcStatus rpcBindClient(const RpcCtx handle, const int_fast8_t verbose)
{
RPC_STATUS status;
if ((status = RpcBindingFromStringBindingA(stringBinding, &KMSServer_v1_0_c_ifspec)) != RPC_S_OK)
{
errorout("\n%s\n", win_strerror(status));
}
return status;
}
/*
* You never know if you have a TCP connection or not
* This returns true if the previous RPC call failed
*/
int_fast8_t isDisconnected(const RpcCtx handle)
{
return PreviousRpcCallFailed;
}
/*
* This is the exception handler because the RPC call may
* throw an SEH exception and gcc does not support
* __try / __except as MSVC does.
*/
static LONG WINAPI rpcException (LPEXCEPTION_POINTERS exception_pointers)
{
DWORD exception = exception_pointers->ExceptionRecord->ExceptionCode;
if (!exception) exception = (DWORD)~0;
longjmp(jmp, exception_pointers->ExceptionRecord->ExceptionCode);
return EXCEPTION_EXECUTE_HANDLER;
}
/*
* This actually calls the RPC server
*/
#define try SetUnhandledExceptionFilter(rpcException); RPC_STATUS exception = setjmp(jmp); if (!exception)
#define catch else
RpcStatus rpcSendRequest(const RpcCtx handle, BYTE* KmsRequest, const size_t requestSize, BYTE **KmsResponse, size_t* responseSize)
{
*KmsResponse = NULL; // Let midl_user_allocate do the job
try
{
exception = RequestActivation(KMSServer_v1_0_c_ifspec, (int)requestSize, KmsRequest, (int*)responseSize, KmsResponse);
}
catch
{
errorout("\n%s", win_strerror(exception));
}
PreviousRpcCallFailed = exception;
SetUnhandledExceptionFilter(NULL);
return exception;
}
#undef catch
#undef try
/*
* Only frees local handles. Cannot close the TCP connection
*/
RpcStatus closeRpc(const RpcCtx handle)
{
RPC_STATUS status;
if ((status = RpcBindingFree(&KMSServer_v1_0_c_ifspec)) != RPC_S_OK) return status;
status = RpcStringFreeA(&stringBinding);
//Ctx = INVALID_RPCCTX;
return status;
}
#if !MULTI_CALL_BINARY
// Memory allocation function for RPC.
void *__RPC_USER midl_user_allocate(SIZE_T len)
{
return vlmcsd_malloc(len);
}
// Memory deallocation function for RPC.
void __RPC_USER midl_user_free(void __RPC_FAR *ptr)
{
if (ptr) free(ptr);
ptr = NULL;
}
#endif // !MULTI_CALL_BINARY
#endif // USE_MSRPC

22
msrpc-client.h Normal file
View File

@ -0,0 +1,22 @@
/*
* msrpc-client.h
*/
#ifndef MSRPC_CLIENT_H_
#define MSRPC_CLIENT_H_
#include "types.h"
#include <setjmp.h>
typedef int_fast8_t RpcCtx;
typedef RPC_STATUS RpcStatus;
RpcCtx connectToAddress(char *const addr, const int AddressFamily_unused, int_fast8_t showHostName);
int_fast8_t isDisconnected(const RpcCtx handle);
RpcStatus rpcBindClient(const RpcCtx handle, const int_fast8_t verbose);
RpcStatus rpcSendRequest(const RpcCtx handle, BYTE* KmsRequest, size_t requestSize, BYTE **KmsResponse, size_t *responseSize);
RpcStatus closeRpc(RpcCtx s);
#define INVALID_RPCCTX ((RpcCtx)~0)
#endif /* MSRPC_CLIENT_H_ */

219
msrpc-server.c Normal file
View File

@ -0,0 +1,219 @@
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#ifdef USE_MSRPC
#if !defined(_WIN32) && !defined(__CYGWIN__)
#error MSRPC is only available with native Windows or Cygwin
#endif
#include "msrpc-server.h"
#include "output.h"
#include "kms.h"
#include "helpers.h"
#include "shared_globals.h"
#include "ntservice.h"
#include "endian.h"
#include "types.h"
#if __amd64 || defined(_M_AMD64) // 64-bit
#ifndef _M_AMD64
#define _M_AMD64
#endif // _M_AMD64
#include "KMSServer_s2_x64_mingw_gcc.c"
#else // 32-bit
#include "KMSServer_s2_mingw_gcc.c"
#endif // 32-bit
#if !defined(NO_LIMIT)
#define MAXCALLS MaxTasks
#else // defined(NO_LIMIT)
#define MAXCALLS RPC_C_LISTEN_MAX_CALLS_DEFAULT
#endif
/*
* This is the main run loop for the KMS server
* We actually just setup things (must be after Cygwin fork) and then sleep
*/
int runServer()
{
# if !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32)
// The RPC setup survives a Cygwin exec without problems but no daemonizing
// SIGHUP is currently disabled for Cygwin. So this code should never compile
if (IsRestarted)
{
# ifndef NO_LOG
logger("vlmcsd %s started successfully\n", Version);
# endif // NO_LOG
}
else
# endif // !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32)
{
RPC_STATUS status;
// Endpoint is actually a TCP port for "ncacn_ip_tcp"
status = RpcServerUseProtseqEpA
(
(RPC_CSTR)"ncacn_ip_tcp",
RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
(RPC_CSTR)defaultport,
NULL
);
if (status)
{
printerrorf("Fatal: Cannot bind to port %s: %s\n", defaultport, win_strerror(status));
return status;
}
# ifndef NO_LOG
logger("Listening on port %s\n", defaultport);
# endif // NO_LOG
// Registers the KMSServer interface.
status = RpcServerRegisterIf2
(
KMSServer_v1_0_s_ifspec,
NULL,
NULL,
RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH | RPC_IF_AUTOLISTEN,
MAXCALLS,
MAX_RESPONSE_SIZE, // currently set to sizeof(RESPONSE_V6)
NULL
);
if (status)
{
printerrorf("Fatal: Cannot register RPC interface: %s\n", win_strerror(status));
return status;
}
# ifndef NO_LOG
logger("vlmcsd %s started successfully\n", Version);
# endif // NO_LOG
if (IsNTService) ReportServiceStatus(SERVICE_RUNNING, NO_ERROR, 200);
}
// We could run RpcServerListen here but we need something
// that can be signaled from Cygwin. So we just sleep 24h (POSIX sleep, no Windows Sleep),
// wake up for some nanoseconds and sleep again.
while(TRUE) sleep(86400); // Sleep one day
}
/*
* Get's the IP address from an RPC_BINDING_HANDLE. Caller must call RpcStringFreeA to
* release memory allocated in *ipAddress
*/
#ifndef NO_LOG
RPC_STATUS getClientIp(const RPC_BINDING_HANDLE clientBinding, RPC_CSTR *ipAddress)
{
RPC_STATUS result;
RPC_CSTR stringBinding;
RPC_BINDING_HANDLE serverBinding;
// Fix for wine (disabled by default, because vlmcsd runs natively on all platforms where wine runs)
// Feel free to #define SUPPORT_WINE if you really want to run the Windows version with MS RPC (Wine RPC in this case)
#ifdef SUPPORT_WINE
HMODULE h = GetModuleHandleA("kernel32.dll");
if (h)
{
// Since wine simply terminates the thread when RpcBindingServerFromClient is called, we exit with an error
if (GetProcAddress(h, "wine_get_unix_file_name")) return RPC_S_CANNOT_SUPPORT;
}
#endif // SUPPORT_WINE
if ((result = RpcBindingServerFromClient(clientBinding, &serverBinding)) != RPC_S_OK) return result;
if ((result = RpcBindingToStringBindingA(serverBinding, &stringBinding)) != RPC_S_OK)
{
RpcBindingFree(&serverBinding);
return result;
}
result = RpcStringBindingParseA(stringBinding, NULL, NULL, ipAddress, NULL, NULL);
RpcStringFreeA(&stringBinding);
RpcBindingFree(&serverBinding);
return result;
}
#endif // NO_LOG
/*
* This is the callback function for the RPC request as defined in KMSServer.idl
* Output from the MIDL compiler has been modified manually to support gcc (and compatible compilers)
* as well as Cygwin and MingW-w64 toolchains.
*/
int ProcessActivationRequest(handle_t IDL_handle, int requestSize, unsigned char *request, int *responseSize, unsigned char **response)
{
RPC_CSTR clientIpAddress;
RPC_STATUS result;
int status = RPC_S_OK;
result = getClientIp(IDL_handle, &clientIpAddress);
# ifndef NO_LOG
logger("RPC connection accepted: %s\n", !result ? (const char*)clientIpAddress : "Unknown IP");
# endif // NO_LOG
// Discard any packet smaller than a v4 request
if (requestSize < (int)sizeof(REQUEST_V4)) return RPC_S_CANNOT_SUPPORT;
*response = (uint8_t *)midl_user_allocate(MAX_RESPONSE_SIZE);
switch(LE16(((REQUEST*)(request))->MajorVer))
{
case 4:
*responseSize = CreateResponseV4((REQUEST_V4 *)request, *response, (char*)clientIpAddress);
break;
case 5:
case 6:
*responseSize = CreateResponseV6((REQUEST_V6 *) request, *response, (char*)clientIpAddress);
break;
default:
status = RPC_S_INVALID_ARG;
break;
}
if (!result) RpcStringFreeA(&clientIpAddress);
return status;
}
// Memory allocation function for RPC.
void *__RPC_USER midl_user_allocate(SIZE_T len)
{
return vlmcsd_malloc(len);
}
// Memory deallocation function for RPC.
void __RPC_USER midl_user_free(void __RPC_FAR *ptr)
{
if (ptr) free(ptr);
ptr = NULL;
}
#endif // USE_MSRPC

10
msrpc-server.h Normal file
View File

@ -0,0 +1,10 @@
/*
* msrpc-server.h
*/
#ifndef MSRPC_SERVER_H_
#define MSRPC_SERVER_H_
int runServer();
#endif /* MSRPC_SERVER_H_ */

569
nameser.h Normal file
View File

@ -0,0 +1,569 @@
/* $NetBSD: nameser.h,v 1.19 2005/12/26 19:01:47 perry Exp $ */
/*
* Copyright (c) 1983, 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
*/
/*
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996-1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Id: nameser.h,v 1.2.2.4.4.1 2004/03/09 08:33:30 marka Exp
*/
#ifndef _ARPA_NAMESER_H_
#define _ARPA_NAMESER_H_
#define BIND_4_COMPAT
#include <sys/types.h>
#include <sys/cdefs.h>
/*
* Revision information. This is the release date in YYYYMMDD format.
* It can change every day so the right thing to do with it is use it
* in preprocessor commands such as "#if (__NAMESER > 19931104)". Do not
* compare for equality; rather, use it to determine whether your libbind.a
* contains a new enough lib/nameser/ to support the feature you need.
*/
#define __NAMESER 19991006 /* New interface version stamp. */
/*
* Define constants based on RFC 883, RFC 1034, RFC 1035
*/
#define NS_PACKETSZ 512 /* default UDP packet size */
#define NS_MAXDNAME 1025 /* maximum domain name */
#define NS_MAXMSG 65535 /* maximum message size */
#define NS_MAXCDNAME 255 /* maximum compressed domain name */
#define NS_MAXLABEL 63 /* maximum length of domain label */
#define NS_HFIXEDSZ 12 /* #/bytes of fixed data in header */
#define NS_QFIXEDSZ 4 /* #/bytes of fixed data in query */
#define NS_RRFIXEDSZ 10 /* #/bytes of fixed data in r record */
#define NS_INT32SZ 4 /* #/bytes of data in a uint32_t */
#define NS_INT16SZ 2 /* #/bytes of data in a uint16_t */
#define NS_INT8SZ 1 /* #/bytes of data in a uint8_t */
#define NS_INADDRSZ 4 /* IPv4 T_A */
#define NS_IN6ADDRSZ 16 /* IPv6 T_AAAA */
#define NS_CMPRSFLGS 0xc0 /* Flag bits indicating name compression. */
#define NS_DEFAULTPORT 53 /* For both TCP and UDP. */
/*
* These can be expanded with synonyms, just keep ns_parse.c:ns_parserecord()
* in synch with it.
*/
typedef enum __ns_sect {
ns_s_qd = 0, /* Query: Question. */
ns_s_zn = 0, /* Update: Zone. */
ns_s_an = 1, /* Query: Answer. */
ns_s_pr = 1, /* Update: Prerequisites. */
ns_s_ns = 2, /* Query: Name servers. */
ns_s_ud = 2, /* Update: Update. */
ns_s_ar = 3, /* Query|Update: Additional records. */
ns_s_max = 4
} ns_sect;
/*
* This is a message handle. It is caller allocated and has no dynamic data.
* This structure is intended to be opaque to all but ns_parse.c, thus the
* leading _'s on the member names. Use the accessor functions, not the _'s.
*/
typedef struct __ns_msg {
const u_char *_msg, *_eom;
uint16_t _id, _flags, _counts[ns_s_max];
const u_char *_sections[ns_s_max];
ns_sect _sect;
int _rrnum;
const u_char *_msg_ptr;
} ns_msg;
/* Private data structure - do not use from outside library. */
struct _ns_flagdata { int mask, shift; };
extern const struct _ns_flagdata _ns_flagdata[];
/* Accessor macros - this is part of the public interface. */
#define ns_msg_id(handle) ((handle)._id + 0)
#define ns_msg_base(handle) ((handle)._msg + 0)
#define ns_msg_end(handle) ((handle)._eom + 0)
#define ns_msg_size(handle) ((size_t)((handle)._eom - (handle)._msg))
#define ns_msg_count(handle, section) ((handle)._counts[section] + 0)
/*
* This is a parsed record. It is caller allocated and has no dynamic data.
*/
typedef struct __ns_rr {
char name[NS_MAXDNAME];
uint16_t type;
uint16_t rr_class;
uint32_t ttl;
uint16_t rdlength;
const u_char * rdata;
} ns_rr;
/* Accessor macros - this is part of the public interface. */
#define ns_rr_name(rr) (((rr).name[0] != '\0') ? (rr).name : ".")
#define ns_rr_type(rr) ((ns_type)((rr).type + 0))
#define ns_rr_class(rr) ((ns_class)((rr).rr_class + 0))
#define ns_rr_ttl(rr) ((u_long)(rr).ttl + 0)
#define ns_rr_rdlen(rr) ((size_t)(rr).rdlength + 0)
#define ns_rr_rdata(rr) ((rr).rdata + 0)
/*
* These don't have to be in the same order as in the packet flags word,
* and they can even overlap in some cases, but they will need to be kept
* in synch with ns_parse.c:ns_flagdata[].
*/
typedef enum __ns_flag {
ns_f_qr, /* Question/Response. */
ns_f_opcode, /* Operation code. */
ns_f_aa, /* Authoritative Answer. */
ns_f_tc, /* Truncation occurred. */
ns_f_rd, /* Recursion Desired. */
ns_f_ra, /* Recursion Available. */
ns_f_z, /* MBZ. */
ns_f_ad, /* Authentic Data (DNSSEC). */
ns_f_cd, /* Checking Disabled (DNSSEC). */
ns_f_rcode, /* Response code. */
ns_f_max
} ns_flag;
/*
* Currently defined opcodes.
*/
typedef enum __ns_opcode {
ns_o_query = 0, /* Standard query. */
ns_o_iquery = 1, /* Inverse query (deprecated/unsupported). */
ns_o_status = 2, /* Name server status query (unsupported). */
/* Opcode 3 is undefined/reserved. */
ns_o_notify = 4, /* Zone change notification. */
ns_o_update = 5, /* Zone update message. */
ns_o_max = 6
} ns_opcode;
/*
* Currently defined response codes.
*/
typedef enum __ns_rcode {
ns_r_noerror = 0, /* No error occurred. */
ns_r_formerr = 1, /* Format error. */
ns_r_servfail = 2, /* Server failure. */
ns_r_nxdomain = 3, /* Name error. */
ns_r_notimpl = 4, /* Unimplemented. */
ns_r_refused = 5, /* Operation refused. */
/* these are for BIND_UPDATE */
ns_r_yxdomain = 6, /* Name exists */
ns_r_yxrrset = 7, /* RRset exists */
ns_r_nxrrset = 8, /* RRset does not exist */
ns_r_notauth = 9, /* Not authoritative for zone */
ns_r_notzone = 10, /* Zone of record different from zone section */
ns_r_max = 11,
/* The following are EDNS extended rcodes */
ns_r_badvers = 16,
/* The following are TSIG errors */
ns_r_badsig = 16,
ns_r_badkey = 17,
ns_r_badtime = 18
} ns_rcode;
/* BIND_UPDATE */
typedef enum __ns_update_operation {
ns_uop_delete = 0,
ns_uop_add = 1,
ns_uop_max = 2
} ns_update_operation;
/*
* This structure is used for TSIG authenticated messages
*/
struct ns_tsig_key {
char name[NS_MAXDNAME], alg[NS_MAXDNAME];
unsigned char *data;
int len;
};
typedef struct ns_tsig_key ns_tsig_key;
/*
* This structure is used for TSIG authenticated TCP messages
*/
struct ns_tcp_tsig_state {
int counter;
struct dst_key *key;
void *ctx;
unsigned char sig[NS_PACKETSZ];
int siglen;
};
typedef struct ns_tcp_tsig_state ns_tcp_tsig_state;
#define NS_TSIG_FUDGE 300
#define NS_TSIG_TCP_COUNT 100
#define NS_TSIG_ALG_HMAC_MD5 "HMAC-MD5.SIG-ALG.REG.INT"
#define NS_TSIG_ERROR_NO_TSIG -10
#define NS_TSIG_ERROR_NO_SPACE -11
#define NS_TSIG_ERROR_FORMERR -12
/*
* Currently defined type values for resources and queries.
*/
typedef enum __ns_type {
ns_t_invalid = 0, /* Cookie. */
ns_t_a = 1, /* Host address. */
ns_t_ns = 2, /* Authoritative server. */
ns_t_md = 3, /* Mail destination. */
ns_t_mf = 4, /* Mail forwarder. */
ns_t_cname = 5, /* Canonical name. */
ns_t_soa = 6, /* Start of authority zone. */
ns_t_mb = 7, /* Mailbox domain name. */
ns_t_mg = 8, /* Mail group member. */
ns_t_mr = 9, /* Mail rename name. */
ns_t_null = 10, /* Null resource record. */
ns_t_wks = 11, /* Well known service. */
ns_t_ptr = 12, /* Domain name pointer. */
ns_t_hinfo = 13, /* Host information. */
ns_t_minfo = 14, /* Mailbox information. */
ns_t_mx = 15, /* Mail routing information. */
ns_t_txt = 16, /* Text strings. */
ns_t_rp = 17, /* Responsible person. */
ns_t_afsdb = 18, /* AFS cell database. */
ns_t_x25 = 19, /* X_25 calling address. */
ns_t_isdn = 20, /* ISDN calling address. */
ns_t_rt = 21, /* Router. */
ns_t_nsap = 22, /* NSAP address. */
ns_t_nsap_ptr = 23, /* Reverse NSAP lookup (deprecated). */
ns_t_sig = 24, /* Security signature. */
ns_t_key = 25, /* Security key. */
ns_t_px = 26, /* X.400 mail mapping. */
ns_t_gpos = 27, /* Geographical position (withdrawn). */
ns_t_aaaa = 28, /* Ip6 Address. */
ns_t_loc = 29, /* Location Information. */
ns_t_nxt = 30, /* Next domain (security). */
ns_t_eid = 31, /* Endpoint identifier. */
ns_t_nimloc = 32, /* Nimrod Locator. */
ns_t_srv = 33, /* Server Selection. */
ns_t_atma = 34, /* ATM Address */
ns_t_naptr = 35, /* Naming Authority PoinTeR */
ns_t_kx = 36, /* Key Exchange */
ns_t_cert = 37, /* Certification record */
ns_t_a6 = 38, /* IPv6 address (deprecates AAAA) */
ns_t_dname = 39, /* Non-terminal DNAME (for IPv6) */
ns_t_sink = 40, /* Kitchen sink (experimentatl) */
ns_t_opt = 41, /* EDNS0 option (meta-RR) */
ns_t_apl = 42, /* Address prefix list (RFC 3123) */
ns_t_tkey = 249, /* Transaction key */
ns_t_tsig = 250, /* Transaction signature. */
ns_t_ixfr = 251, /* Incremental zone transfer. */
ns_t_axfr = 252, /* Transfer zone of authority. */
ns_t_mailb = 253, /* Transfer mailbox records. */
ns_t_maila = 254, /* Transfer mail agent records. */
ns_t_any = 255, /* Wildcard match. */
ns_t_zxfr = 256, /* BIND-specific, nonstandard. */
ns_t_max = 65536
} ns_type;
/* Exclusively a QTYPE? (not also an RTYPE) */
#define ns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || \
(t) == ns_t_mailb || (t) == ns_t_maila)
/* Some kind of meta-RR? (not a QTYPE, but also not an RTYPE) */
#define ns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt)
/* Exclusively an RTYPE? (not also a QTYPE or a meta-RR) */
#define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t))
#define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr)
#define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || \
(t) == ns_t_zxfr)
/*
* Values for class field
*/
typedef enum __ns_class {
ns_c_invalid = 0, /* Cookie. */
ns_c_in = 1, /* Internet. */
ns_c_2 = 2, /* unallocated/unsupported. */
ns_c_chaos = 3, /* MIT Chaos-net. */
ns_c_hs = 4, /* MIT Hesiod. */
/* Query class values which do not appear in resource records */
ns_c_none = 254, /* for prereq. sections in update requests */
ns_c_any = 255, /* Wildcard match. */
ns_c_max = 65536
} ns_class;
/* DNSSEC constants. */
typedef enum __ns_key_types {
ns_kt_rsa = 1, /* key type RSA/MD5 */
ns_kt_dh = 2, /* Diffie Hellman */
ns_kt_dsa = 3, /* Digital Signature Standard (MANDATORY) */
ns_kt_private = 254 /* Private key type starts with OID */
} ns_key_types;
typedef enum __ns_cert_types {
cert_t_pkix = 1, /* PKIX (X.509v3) */
cert_t_spki = 2, /* SPKI */
cert_t_pgp = 3, /* PGP */
cert_t_url = 253, /* URL private type */
cert_t_oid = 254 /* OID private type */
} ns_cert_types;
/* Flags field of the KEY RR rdata. */
#define NS_KEY_TYPEMASK 0xC000 /* Mask for "type" bits */
#define NS_KEY_TYPE_AUTH_CONF 0x0000 /* Key usable for both */
#define NS_KEY_TYPE_CONF_ONLY 0x8000 /* Key usable for confidentiality */
#define NS_KEY_TYPE_AUTH_ONLY 0x4000 /* Key usable for authentication */
#define NS_KEY_TYPE_NO_KEY 0xC000 /* No key usable for either; no key */
/* The type bits can also be interpreted independently, as single bits: */
#define NS_KEY_NO_AUTH 0x8000 /* Key unusable for authentication */
#define NS_KEY_NO_CONF 0x4000 /* Key unusable for confidentiality */
#define NS_KEY_RESERVED2 0x2000 /* Security is *mandatory* if bit=0 */
#define NS_KEY_EXTENDED_FLAGS 0x1000 /* reserved - must be zero */
#define NS_KEY_RESERVED4 0x0800 /* reserved - must be zero */
#define NS_KEY_RESERVED5 0x0400 /* reserved - must be zero */
#define NS_KEY_NAME_TYPE 0x0300 /* these bits determine the type */
#define NS_KEY_NAME_USER 0x0000 /* key is assoc. with user */
#define NS_KEY_NAME_ENTITY 0x0200 /* key is assoc. with entity eg host */
#define NS_KEY_NAME_ZONE 0x0100 /* key is zone key */
#define NS_KEY_NAME_RESERVED 0x0300 /* reserved meaning */
#define NS_KEY_RESERVED8 0x0080 /* reserved - must be zero */
#define NS_KEY_RESERVED9 0x0040 /* reserved - must be zero */
#define NS_KEY_RESERVED10 0x0020 /* reserved - must be zero */
#define NS_KEY_RESERVED11 0x0010 /* reserved - must be zero */
#define NS_KEY_SIGNATORYMASK 0x000F /* key can sign RR's of same name */
#define NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED2 | \
NS_KEY_RESERVED4 | \
NS_KEY_RESERVED5 | \
NS_KEY_RESERVED8 | \
NS_KEY_RESERVED9 | \
NS_KEY_RESERVED10 | \
NS_KEY_RESERVED11 )
#define NS_KEY_RESERVED_BITMASK2 0xFFFF /* no bits defined here */
/* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */
#define NS_ALG_MD5RSA 1 /* MD5 with RSA */
#define NS_ALG_DH 2 /* Diffie Hellman KEY */
#define NS_ALG_DSA 3 /* DSA KEY */
#define NS_ALG_DSS NS_ALG_DSA
#define NS_ALG_EXPIRE_ONLY 253 /* No alg, no security */
#define NS_ALG_PRIVATE_OID 254 /* Key begins with OID giving alg */
/* Protocol values */
/* value 0 is reserved */
#define NS_KEY_PROT_TLS 1
#define NS_KEY_PROT_EMAIL 2
#define NS_KEY_PROT_DNSSEC 3
#define NS_KEY_PROT_IPSEC 4
#define NS_KEY_PROT_ANY 255
/* Signatures */
#define NS_MD5RSA_MIN_BITS 512 /* Size of a mod or exp in bits */
#define NS_MD5RSA_MAX_BITS 4096
/* Total of binary mod and exp */
#define NS_MD5RSA_MAX_BYTES ((NS_MD5RSA_MAX_BITS+7/8)*2+3)
/* Max length of text sig block */
#define NS_MD5RSA_MAX_BASE64 (((NS_MD5RSA_MAX_BYTES+2)/3)*4)
#define NS_MD5RSA_MIN_SIZE ((NS_MD5RSA_MIN_BITS+7)/8)
#define NS_MD5RSA_MAX_SIZE ((NS_MD5RSA_MAX_BITS+7)/8)
#define NS_DSA_SIG_SIZE 41
#define NS_DSA_MIN_SIZE 213
#define NS_DSA_MAX_BYTES 405
/* Offsets into SIG record rdata to find various values */
#define NS_SIG_TYPE 0 /* Type flags */
#define NS_SIG_ALG 2 /* Algorithm */
#define NS_SIG_LABELS 3 /* How many labels in name */
#define NS_SIG_OTTL 4 /* Original TTL */
#define NS_SIG_EXPIR 8 /* Expiration time */
#define NS_SIG_SIGNED 12 /* Signature time */
#define NS_SIG_FOOT 16 /* Key footprint */
#define NS_SIG_SIGNER 18 /* Domain name of who signed it */
/* How RR types are represented as bit-flags in NXT records */
#define NS_NXT_BITS 8
#define NS_NXT_BIT_SET( n,p) (p[(n)/NS_NXT_BITS] |= (0x80>>((n)%NS_NXT_BITS)))
#define NS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS)))
#define NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] & (0x80>>((n)%NS_NXT_BITS)))
#define NS_NXT_MAX 127
/*
* EDNS0 extended flags, host order.
*/
#define NS_OPT_DNSSEC_OK 0x8000U
/*
* Inline versions of get/put short/long. Pointer is advanced.
*/
#define NS_GET16(s, cp) do { \
const u_char *t_cp = (const u_char *)(cp); \
(s) = ((uint16_t)t_cp[0] << 8) \
| ((uint16_t)t_cp[1]) \
; \
(cp) += NS_INT16SZ; \
} while (/*CONSTCOND*/0)
#define NS_GET32(l, cp) do { \
const u_char *t_cp = (const u_char *)(cp); \
(l) = ((uint32_t)t_cp[0] << 24) \
| ((uint32_t)t_cp[1] << 16) \
| ((uint32_t)t_cp[2] << 8) \
| ((uint32_t)t_cp[3]) \
; \
(cp) += NS_INT32SZ; \
} while (/*CONSTCOND*/0)
#define NS_PUT16(s, cp) do { \
uint32_t t_s = (uint32_t)(s); \
u_char *t_cp = (u_char *)(cp); \
*t_cp++ = t_s >> 8; \
*t_cp = t_s; \
(cp) += NS_INT16SZ; \
} while (/*CONSTCOND*/0)
#define NS_PUT32(l, cp) do { \
uint32_t t_l = (uint32_t)(l); \
u_char *t_cp = (u_char *)(cp); \
*t_cp++ = t_l >> 24; \
*t_cp++ = t_l >> 16; \
*t_cp++ = t_l >> 8; \
*t_cp = t_l; \
(cp) += NS_INT32SZ; \
} while (/*CONSTCOND*/0)
/*
* ANSI C identifier hiding for bind's lib/nameser.
*/
#define ns_msg_getflag __ns_msg_getflag
#define ns_get16 __ns_get16
#define ns_get32 __ns_get32
#define ns_put16 __ns_put16
#define ns_put32 __ns_put32
#define ns_initparse __ns_initparse
#define ns_skiprr __ns_skiprr
#define ns_parserr __ns_parserr
#define ns_sprintrr __ns_sprintrr
#define ns_sprintrrf __ns_sprintrrf
#define ns_format_ttl __ns_format_ttl
#define ns_parse_ttl __ns_parse_ttl
#define ns_datetosecs __ns_datetosecs
#define ns_name_ntol __ns_name_ntol
#define ns_name_ntop __ns_name_ntop
#define ns_name_pton __ns_name_pton
#define ns_name_unpack __ns_name_unpack
#define ns_name_pack __ns_name_pack
#define ns_name_compress __ns_name_compress
#define ns_name_uncompress __ns_name_uncompress
#define ns_name_skip __ns_name_skip
#define ns_name_rollback __ns_name_rollback
#define ns_sign __ns_sign
#define ns_sign2 __ns_sign2
#define ns_sign_tcp __ns_sign_tcp
#define ns_sign_tcp2 __ns_sign_tcp2
#define ns_sign_tcp_init __ns_sign_tcp_init
#define ns_find_tsig __ns_find_tsig
#define ns_verify __ns_verify
#define ns_verify_tcp __ns_verify_tcp
#define ns_verify_tcp_init __ns_verify_tcp_init
#define ns_samedomain __ns_samedomain
#define ns_subdomain __ns_subdomain
#define ns_makecanon __ns_makecanon
#define ns_samename __ns_samename
__BEGIN_DECLS
int ns_msg_getflag(ns_msg, int);
uint16_t ns_get16(const u_char *);
uint32_t ns_get32(const u_char *);
void ns_put16(uint16_t, u_char *);
void ns_put32(uint32_t, u_char *);
int ns_initparse(const u_char *, int, ns_msg *);
int ns_skiprr(const u_char *, const u_char *, ns_sect, int);
int ns_parserr(ns_msg *, ns_sect, int, ns_rr *);
int ns_sprintrr(const ns_msg *, const ns_rr *,
const char *, const char *, char *, size_t);
int ns_sprintrrf(const u_char *, size_t, const char *,
ns_class, ns_type, u_long, const u_char *,
size_t, const char *, const char *,
char *, size_t);
int ns_format_ttl(u_long, char *, size_t);
int ns_parse_ttl(const char *, u_long *);
uint32_t ns_datetosecs(const char *cp, int *errp);
int ns_name_ntol(const u_char *, u_char *, size_t);
int ns_name_ntop(const u_char *, char *, size_t);
int ns_name_pton(const char *, u_char *, size_t);
int ns_name_unpack(const u_char *, const u_char *,
const u_char *, u_char *, size_t);
int ns_name_pack(const u_char *, u_char *, int,
const u_char **, const u_char **);
int ns_name_uncompress(const u_char *, const u_char *,
const u_char *, char *, size_t);
int ns_name_compress(const char *, u_char *, size_t,
const u_char **, const u_char **);
int ns_name_skip(const u_char **, const u_char *);
void ns_name_rollback(const u_char *, const u_char **,
const u_char **);
int ns_sign(u_char *, int *, int, int, void *,
const u_char *, int, u_char *, int *, time_t);
int ns_sign2(u_char *, int *, int, int, void *,
const u_char *, int, u_char *, int *, time_t,
u_char **, u_char **);
int ns_sign_tcp(u_char *, int *, int, int,
ns_tcp_tsig_state *, int);
int ns_sign_tcp2(u_char *, int *, int, int,
ns_tcp_tsig_state *, int,
u_char **, u_char **);
int ns_sign_tcp_init(void *, const u_char *, int,
ns_tcp_tsig_state *);
u_char *ns_find_tsig(u_char *, u_char *);
int ns_verify(u_char *, int *, void *,
const u_char *, int, u_char *, int *,
time_t *, int);
int ns_verify_tcp(u_char *, int *, ns_tcp_tsig_state *, int);
int ns_verify_tcp_init(void *, const u_char *, int,
ns_tcp_tsig_state *);
int ns_samedomain(const char *, const char *);
int ns_subdomain(const char *, const char *);
int ns_makecanon(const char *, char *, size_t);
int ns_samename(const char *, const char *);
__END_DECLS
#ifdef BIND_4_COMPAT
#include "nameser_compat.h"
#endif
#endif /* !_ARPA_NAMESER_H_ */

236
nameser_compat.h Normal file
View File

@ -0,0 +1,236 @@
/* $NetBSD: nameser_compat.h,v 1.1.1.2 2004/11/07 01:28:27 christos Exp $ */
/* Copyright (c) 1983, 1989
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
*/
/*
* from nameser.h 8.1 (Berkeley) 6/2/93
* Id: nameser_compat.h,v 1.1.2.3.4.2 2004/07/01 04:43:41 marka Exp
*/
#ifndef _ARPA_NAMESER_COMPAT_
#define _ARPA_NAMESER_COMPAT_
#define __BIND 19950621 /* (DEAD) interface version stamp. */
#include <endian.h>
#ifndef BYTE_ORDER
#if (BSD >= 199103)
# include <machine/endian.h>
#else
#ifdef __linux
# include <endian.h>
#else
#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax, pc) */
#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */
#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp)*/
#if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \
defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \
defined(__alpha__) || defined(__alpha) || \
(defined(__Lynx__) && defined(__x86__))
#define BYTE_ORDER LITTLE_ENDIAN
#endif
#if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \
defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \
defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) ||\
defined(apollo) || defined(__convex__) || defined(_CRAY) || \
defined(__hppa) || defined(__hp9000) || \
defined(__hp9000s300) || defined(__hp9000s700) || \
defined(__hp3000s900) || defined(__hpux) || defined(MPE) || \
defined (BIT_ZERO_ON_LEFT) || defined(m68k) || defined(__sparc) || \
(defined(__Lynx__) && \
(defined(__68k__) || defined(__sparc__) || defined(__powerpc__)))
#define BYTE_ORDER BIG_ENDIAN
#endif
#endif /* __linux */
#endif /* BSD */
#endif /* BYTE_ORDER */
#if !defined(BYTE_ORDER) || \
(BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN && \
BYTE_ORDER != PDP_ENDIAN)
/* you must determine what the correct bit order is for
* your compiler - the next line is an intentional error
* which will force your compiles to bomb until you fix
* the above macros.
*/
#error "Undefined or invalid BYTE_ORDER";
#endif
/*
* Structure for query header. The order of the fields is machine- and
* compiler-dependent, depending on the byte/bit order and the layout
* of bit fields. We use bit fields only in int variables, as this
* is all ANSI requires. This requires a somewhat confusing rearrangement.
*/
typedef struct {
unsigned id :16; /* query identification number */
#if BYTE_ORDER == BIG_ENDIAN
/* fields in third byte */
unsigned qr: 1; /* response flag */
unsigned opcode: 4; /* purpose of message */
unsigned aa: 1; /* authoritive answer */
unsigned tc: 1; /* truncated message */
unsigned rd: 1; /* recursion desired */
/* fields in fourth byte */
unsigned ra: 1; /* recursion available */
unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
unsigned ad: 1; /* authentic data from named */
unsigned cd: 1; /* checking disabled by resolver */
unsigned rcode :4; /* response code */
#endif
#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
/* fields in third byte */
unsigned rd :1; /* recursion desired */
unsigned tc :1; /* truncated message */
unsigned aa :1; /* authoritive answer */
unsigned opcode :4; /* purpose of message */
unsigned qr :1; /* response flag */
/* fields in fourth byte */
unsigned rcode :4; /* response code */
unsigned cd: 1; /* checking disabled by resolver */
unsigned ad: 1; /* authentic data from named */
unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
unsigned ra :1; /* recursion available */
#endif
/* remaining bytes */
unsigned qdcount :16; /* number of question entries */
unsigned ancount :16; /* number of answer entries */
unsigned nscount :16; /* number of authority entries */
unsigned arcount :16; /* number of resource entries */
} HEADER;
#define PACKETSZ NS_PACKETSZ
#define MAXDNAME NS_MAXDNAME
#define MAXCDNAME NS_MAXCDNAME
#define MAXLABEL NS_MAXLABEL
#define HFIXEDSZ NS_HFIXEDSZ
#define QFIXEDSZ NS_QFIXEDSZ
#define RRFIXEDSZ NS_RRFIXEDSZ
#define INT32SZ NS_INT32SZ
#define INT16SZ NS_INT16SZ
#define INT8SZ NS_INT8SZ
#define INADDRSZ NS_INADDRSZ
#define IN6ADDRSZ NS_IN6ADDRSZ
#define INDIR_MASK NS_CMPRSFLGS
#define NAMESERVER_PORT NS_DEFAULTPORT
#define S_ZONE ns_s_zn
#define S_PREREQ ns_s_pr
#define S_UPDATE ns_s_ud
#define S_ADDT ns_s_ar
#define QUERY ns_o_query
#define IQUERY ns_o_iquery
#define STATUS ns_o_status
#define NS_NOTIFY_OP ns_o_notify
#define NS_UPDATE_OP ns_o_update
#define NOERROR ns_r_noerror
#define FORMERR ns_r_formerr
#define SERVFAIL ns_r_servfail
#define NXDOMAIN ns_r_nxdomain
#define NOTIMP ns_r_notimpl
#define REFUSED ns_r_refused
#define YXDOMAIN ns_r_yxdomain
#define YXRRSET ns_r_yxrrset
#define NXRRSET ns_r_nxrrset
#define NOTAUTH ns_r_notauth
#define NOTZONE ns_r_notzone
/*#define BADSIG ns_r_badsig*/
/*#define BADKEY ns_r_badkey*/
/*#define BADTIME ns_r_badtime*/
#define DELETE ns_uop_delete
#define ADD ns_uop_add
#define T_A ns_t_a
#define T_NS ns_t_ns
#define T_MD ns_t_md
#define T_MF ns_t_mf
#define T_CNAME ns_t_cname
#define T_SOA ns_t_soa
#define T_MB ns_t_mb
#define T_MG ns_t_mg
#define T_MR ns_t_mr
#define T_NULL ns_t_null
#define T_WKS ns_t_wks
#define T_PTR ns_t_ptr
#define T_HINFO ns_t_hinfo
#define T_MINFO ns_t_minfo
#define T_MX ns_t_mx
#define T_TXT ns_t_txt
#define T_RP ns_t_rp
#define T_AFSDB ns_t_afsdb
#define T_X25 ns_t_x25
#define T_ISDN ns_t_isdn
#define T_RT ns_t_rt
#define T_NSAP ns_t_nsap
#define T_NSAP_PTR ns_t_nsap_ptr
#define T_SIG ns_t_sig
#define T_KEY ns_t_key
#define T_PX ns_t_px
#define T_GPOS ns_t_gpos
#define T_AAAA ns_t_aaaa
#define T_LOC ns_t_loc
#define T_NXT ns_t_nxt
#define T_EID ns_t_eid
#define T_NIMLOC ns_t_nimloc
#define T_SRV ns_t_srv
#define T_ATMA ns_t_atma
#define T_NAPTR ns_t_naptr
#define T_A6 ns_t_a6
#define T_TSIG ns_t_tsig
#define T_IXFR ns_t_ixfr
#define T_AXFR ns_t_axfr
#define T_MAILB ns_t_mailb
#define T_MAILA ns_t_maila
#define T_ANY ns_t_any
#define C_IN ns_c_in
#define C_CHAOS ns_c_chaos
#define C_HS ns_c_hs
/* BIND_UPDATE */
#define C_NONE ns_c_none
#define C_ANY ns_c_any
#define GETSHORT NS_GET16
#define GETLONG NS_GET32
#define PUTSHORT NS_PUT16
#define PUTLONG NS_PUT32
#endif /* _ARPA_NAMESER_COMPAT_ */

675
network.c Normal file
View File

@ -0,0 +1,675 @@
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#ifndef USE_MSRPC
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <string.h>
#ifndef _WIN32
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <netinet/in.h>
#endif // WIN32
#include "network.h"
#include "endian.h"
#include "output.h"
#include "helpers.h"
#include "shared_globals.h"
#include "rpc.h"
#ifndef _WIN32
typedef ssize_t (*sendrecv_t)(int, void*, size_t, int);
#else
typedef int (WINAPI *sendrecv_t)(SOCKET, void*, int, int);
#endif
// Send or receive a fixed number of bytes regardless if received in one or more chunks
int_fast8_t sendrecv(SOCKET sock, BYTE *data, int len, int_fast8_t do_send)
{
int n;
sendrecv_t f = do_send
? (sendrecv_t) send
: (sendrecv_t) recv;
do
{
n = f(sock, data, len, 0);
}
while (
( n < 0 && socket_errno == VLMCSD_EINTR ) || ( n > 0 && ( data += n, (len -= n) > 0 ) ));
return ! len;
}
static int_fast8_t ip2str(char *restrict result, const size_t resultLength, const struct sockaddr *const restrict socketAddress, const socklen_t socketLength)
{
static const char *const fIPv4 = "%s:%s";
static const char *const fIPv6 = "[%s]:%s";
char ipAddress[64], portNumber[8];
if (getnameinfo
(
socketAddress,
socketLength,
ipAddress,
sizeof(ipAddress),
portNumber,
sizeof(portNumber),
NI_NUMERICHOST | NI_NUMERICSERV
))
{
return FALSE;
}
if ((unsigned int)snprintf(result, resultLength, socketAddress->sa_family == AF_INET6 ? fIPv6 : fIPv4, ipAddress, portNumber) > resultLength) return FALSE;
return TRUE;
}
static int_fast8_t getSocketList(struct addrinfo **saList, const char *const addr, const int flags, const int AddressFamily)
{
int status;
char *szHost, *szPort;
size_t len = strlen(addr) + 1;
// Don't alloca too much
if (len > 264) return FALSE;
char *addrcopy = (char*)alloca(len);
memcpy(addrcopy, addr, len);
parseAddress(addrcopy, &szHost, &szPort);
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AddressFamily;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = flags;
if ((status = getaddrinfo(szHost, szPort, &hints, saList)))
{
printerrorf("Warning: %s: %s\n", addr, gai_strerror(status));
return FALSE;
}
return TRUE;
}
static int_fast8_t setBlockingEnabled(SOCKET fd, int_fast8_t blocking)
{
if (fd == INVALID_SOCKET) return FALSE;
#ifdef _WIN32
unsigned long mode = blocking ? 0 : 1;
return (ioctlsocket(fd, FIONBIO, &mode) == 0) ? TRUE : FALSE;
#else // POSIX
int flags = fcntl(fd, F_GETFL, 0);
if (flags < 0) return FALSE;
flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
return (fcntl(fd, F_SETFL, flags) == 0) ? TRUE : FALSE;
#endif // POSIX
}
int_fast8_t isDisconnected(const SOCKET s)
{
char buffer[1];
if (!setBlockingEnabled(s, FALSE)) return TRUE;
int n = recv(s, buffer, 1, MSG_PEEK);
if (!setBlockingEnabled(s, TRUE)) return TRUE;
if (n == 0) return TRUE;
return FALSE;
}
// Connect to TCP address addr (e.g. "kms.example.com:1688") and return an
// open socket for the connection if successful or INVALID_SOCKET otherwise
SOCKET connectToAddress(const char *const addr, const int AddressFamily, int_fast8_t showHostName)
{
struct addrinfo *saList, *sa;
SOCKET s = INVALID_SOCKET;
char szAddr[128];
if (!getSocketList(&saList, addr, 0, AddressFamily)) return INVALID_SOCKET;
for (sa = saList; sa; sa = sa->ai_next)
{
// struct sockaddr_in* addr4 = (struct sockaddr_in*)sa->ai_addr;
// struct sockaddr_in6* addr6 = (struct sockaddr_in6*)sa->ai_addr;
if (ip2str(szAddr, sizeof(szAddr), sa->ai_addr, sa->ai_addrlen))
{
if (showHostName)
printf("Connecting to %s (%s) ... ", addr, szAddr);
else
printf("Connecting to %s ... ", szAddr);
fflush(stdout);
}
s = socket(sa->ai_family, SOCK_STREAM, IPPROTO_TCP);
# if !defined(NO_TIMEOUT) && !__minix__
# ifndef _WIN32 // Standard Posix timeout structure
struct timeval to;
to.tv_sec = 10;
to.tv_usec = 0;
# else // Windows requires a DWORD with milliseconds
DWORD to = 10000;
# endif // _WIN32
setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (sockopt_t)&to, sizeof(to));
setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (sockopt_t)&to, sizeof(to));
# endif // !defined(NO_TIMEOUT) && !__minix__
if (!connect(s, sa->ai_addr, sa->ai_addrlen))
{
printf("successful\n");
break;
}
errorout("%s\n", socket_errno == VLMCSD_EINPROGRESS ? "Timed out" : vlmcsd_strerror(socket_errno));
socketclose(s);
s = INVALID_SOCKET;
}
freeaddrinfo(saList);
return s;
}
#ifndef NO_SOCKETS
// Create a Listening socket for addrinfo sa and return socket s
// szHost and szPort are for logging only
static int listenOnAddress(const struct addrinfo *const ai, SOCKET *s)
{
int error;
char ipstr[64];
ip2str(ipstr, sizeof(ipstr), ai->ai_addr, ai->ai_addrlen);
//*s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
*s = socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP);
if (*s == INVALID_SOCKET)
{
error = socket_errno;
printerrorf("Warning: %s error. %s\n", ai->ai_family == AF_INET6 ? cIPv6 : cIPv4, vlmcsd_strerror(error));
return error;
}
# if !defined(_WIN32) && !defined(NO_SIGHUP)
int flags = fcntl(*s, F_GETFD, 0);
if (flags != -1)
{
flags |= FD_CLOEXEC;
fcntl(*s, F_SETFD, flags);
}
# ifdef _PEDANTIC
else
{
printerrorf("Warning: Could not set FD_CLOEXEC flag on %s: %s\n", ipstr, vlmcsd_strerror(errno));
}
# endif // _PEDANTIC
# endif // !defined(_WIN32) && !defined(NO_SIGHUP)
BOOL socketOption = TRUE;
// fix for lame tomato toolchain
# ifndef IPV6_V6ONLY
# ifdef __linux__
# define IPV6_V6ONLY (26)
# endif // __linux__
# endif // IPV6_V6ONLY
# ifdef IPV6_V6ONLY
if (ai->ai_family == AF_INET6) setsockopt(*s, IPPROTO_IPV6, IPV6_V6ONLY, (sockopt_t)&socketOption, sizeof(socketOption));
# endif
# ifndef _WIN32
setsockopt(*s, SOL_SOCKET, SO_REUSEADDR, (sockopt_t)&socketOption, sizeof(socketOption));
# endif
if (bind(*s, ai->ai_addr, ai->ai_addrlen) || listen(*s, SOMAXCONN))
{
error = socket_errno;
printerrorf("Warning: %s: %s\n", ipstr, vlmcsd_strerror(error));
socketclose(*s);
return error;
}
# ifndef NO_LOG
logger("Listening on %s\n", ipstr);
# endif
return 0;
}
// Adds a listening socket for an address string,
// e.g. 127.0.0.1:1688 or [2001:db8:dead:beef::1]:1688
BOOL addListeningSocket(const char *const addr)
{
struct addrinfo *aiList, *ai;
int result = FALSE;
SOCKET *s = SocketList + numsockets;
if (getSocketList(&aiList, addr, AI_PASSIVE | AI_NUMERICHOST, AF_UNSPEC))
{
for (ai = aiList; ai; ai = ai->ai_next)
{
// struct sockaddr_in* addr4 = (struct sockaddr_in*)sa->ai_addr;
// struct sockaddr_in6* addr6 = (struct sockaddr_in6*)sa->ai_addr;
if (numsockets >= FD_SETSIZE)
{
#ifdef _PEDANTIC // Do not report this error in normal builds to keep file size low
printerrorf("Warning: Cannot listen on %s. Your OS only supports %u listening sockets in an FD_SET.\n", addr, FD_SETSIZE);
#endif
break;
}
if (!listenOnAddress(ai, s))
{
numsockets++;
result = TRUE;
}
}
freeaddrinfo(aiList);
}
return result;
}
// Just create some dummy sockets to see if we have a specific protocol (IPv4 or IPv6)
__pure int_fast8_t checkProtocolStack(const int addressfamily)
{
SOCKET s; // = INVALID_SOCKET;
s = socket(addressfamily, SOCK_STREAM, 0);
int_fast8_t success = (s != INVALID_SOCKET);
socketclose(s);
return success;
}
// Build an fd_set of all listening socket then use select to wait for an incoming connection
static SOCKET network_accept_any()
{
fd_set ListeningSocketsList;
SOCKET maxSocket, sock;
int i;
int status;
FD_ZERO(&ListeningSocketsList);
maxSocket = 0;
for (i = 0; i < numsockets; i++)
{
FD_SET(SocketList[i], &ListeningSocketsList);
if (SocketList[i] > maxSocket) maxSocket = SocketList[i];
}
status = select(maxSocket + 1, &ListeningSocketsList, NULL, NULL, NULL);
if (status < 0) return INVALID_SOCKET;
sock = INVALID_SOCKET;
for (i = 0; i < numsockets; i++)
{
if (FD_ISSET(SocketList[i], &ListeningSocketsList))
{
sock = SocketList[i];
break;
}
}
if (sock == INVALID_SOCKET)
return INVALID_SOCKET;
else
return accept(sock, NULL, NULL);
}
void closeAllListeningSockets()
{
int i;
for (i = 0; i < numsockets; i++)
{
shutdown(SocketList[i], VLMCSD_SHUT_RDWR);
socketclose(SocketList[i]);
}
}
#endif // NO_SOCKETS
static void serveClient(const SOCKET s_client, const DWORD RpcAssocGroup)
{
# if !defined(NO_TIMEOUT) && !__minix__
# ifndef _WIN32 // Standard Posix timeout structure
struct timeval to;
to.tv_sec = ServerTimeout;
to.tv_usec = 0;
#else // Windows requires a DWORD with milliseconds
DWORD to = ServerTimeout * 1000;
# endif // _WIN32
# if !defined(NO_LOG) && defined(_PEDANTIC)
int result =
setsockopt(s_client, SOL_SOCKET, SO_RCVTIMEO, (sockopt_t)&to, sizeof(to)) ||
setsockopt(s_client, SOL_SOCKET, SO_SNDTIMEO, (sockopt_t)&to, sizeof(to));
if (result) logger("Warning: Set timeout failed: %s\n", vlmcsd_strerror(socket_errno));
# else // !(!defined(NO_LOG) && defined(_PEDANTIC))
setsockopt(s_client, SOL_SOCKET, SO_RCVTIMEO, (sockopt_t)&to, sizeof(to));
setsockopt(s_client, SOL_SOCKET, SO_SNDTIMEO, (sockopt_t)&to, sizeof(to));
# endif // !(!defined(NO_LOG) && defined(_PEDANTIC))
# endif // !defined(NO_TIMEOUT) && !__minix__
char ipstr[64];
socklen_t len;
struct sockaddr_storage addr;
len = sizeof addr;
if (getpeername(s_client, (struct sockaddr*)&addr, &len) ||
!ip2str(ipstr, sizeof(ipstr), (struct sockaddr*)&addr, len))
{
# if !defined(NO_LOG) && defined(_PEDANTIC)
logger("Fatal: Cannot determine client's IP address: %s\n", vlmcsd_strerror(errno));
# endif // !defined(NO_LOG) && defined(_PEDANTIC)
socketclose(s_client);
return;
}
# ifndef NO_LOG
const char *const connection_type = addr.ss_family == AF_INET6 ? cIPv6 : cIPv4;
static const char *const cAccepted = "accepted";
static const char *const cClosed = "closed";
static const char *const fIP = "%s connection %s: %s.\n";
logger(fIP, connection_type, cAccepted, ipstr);
#endif // NO_LOG
rpcServer(s_client, RpcAssocGroup, ipstr);
# ifndef NO_LOG
logger(fIP, connection_type, cClosed, ipstr);
# endif // NO_LOG
socketclose(s_client);
}
#ifndef NO_SOCKETS
static void post_sem(void)
{
#if !defined(NO_LIMIT) && !__minix__
if (!InetdMode && MaxTasks != SEM_VALUE_MAX)
{
semaphore_post(Semaphore);
}
#endif // !defined(NO_LIMIT) && !__minix__
}
static void wait_sem(void)
{
#if !defined(NO_LIMIT) && !__minix__
if (!InetdMode && MaxTasks != SEM_VALUE_MAX)
{
semaphore_wait(Semaphore);
}
#endif // !defined(NO_LIMIT) && !__minix__
}
#endif // NO_SOCKETS
#if defined(USE_THREADS) && !defined(NO_SOCKETS)
#if defined(_WIN32) || defined(__CYGWIN__) // Win32 Threads
static DWORD WINAPI serveClientThreadProc(PCLDATA clData)
#else // Posix threads
static void *serveClientThreadProc (PCLDATA clData)
#endif // Thread proc is identical in WIN32 and Posix threads
{
serveClient(clData->socket, clData->RpcAssocGroup);
free(clData);
post_sem();
return 0;
}
#endif // USE_THREADS
#ifndef NO_SOCKETS
#if defined(USE_THREADS) && (defined(_WIN32) || defined(__CYGWIN__)) // Windows Threads
static int serveClientAsyncWinThreads(const PCLDATA thr_CLData)
{
wait_sem();
HANDLE h = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)serveClientThreadProc, thr_CLData, 0, NULL);
if (h)
CloseHandle(h);
else
{
socketclose(thr_CLData->socket);
free(thr_CLData);
post_sem();
return GetLastError();
}
return NO_ERROR;
}
#endif // defined(USE_THREADS) && defined(_WIN32) // Windows Threads
#if defined(USE_THREADS) && !defined(_WIN32) && !defined(__CYGWIN__) // Posix Threads
static int ServeClientAsyncPosixThreads(const PCLDATA thr_CLData)
{
pthread_t p_thr;
pthread_attr_t attr;
wait_sem();
// Must set detached state to avoid memory leak
if (pthread_attr_init(&attr) ||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) ||
pthread_create(&p_thr, &attr, (void * (*)(void *))serveClientThreadProc, thr_CLData))
{
socketclose(thr_CLData->socket);
free(thr_CLData);
post_sem();
return !0;
}
return 0;
}
#endif // defined(USE_THREADS) && !defined(_WIN32) // Posix Threads
#ifndef USE_THREADS // fork() implementation
static void ChildSignalHandler(const int signal)
{
if (signal == SIGHUP) return;
post_sem();
#ifndef NO_LOG
logger("Warning: Child killed/crashed by %s\n", strsignal(signal));
#endif // NO_LOG
exit(!0);
}
static int ServeClientAsyncFork(const SOCKET s_client, const DWORD RpcAssocGroup)
{
int pid;
wait_sem();
if ((pid = fork()) < 0)
{
return errno;
}
else if ( pid )
{
// Parent process
socketclose(s_client);
return 0;
}
else
{
// Child process
// Setup a Child Handler for most common termination signals
struct sigaction sa;
sa.sa_flags = 0;
sa.sa_handler = ChildSignalHandler;
static int signallist[] = { SIGHUP, SIGINT, SIGTERM, SIGSEGV, SIGILL, SIGFPE, SIGBUS };
if (!sigemptyset(&sa.sa_mask))
{
uint_fast8_t i;
for (i = 0; i < _countof(signallist); i++)
{
sigaction(signallist[i], &sa, NULL);
}
}
serveClient(s_client, RpcAssocGroup);
post_sem();
exit(0);
}
}
#endif
int serveClientAsync(const SOCKET s_client, const DWORD RpcAssocGroup)
{
#ifndef USE_THREADS // fork() implementation
return ServeClientAsyncFork(s_client, RpcAssocGroup);
#else // threads implementation
PCLDATA thr_CLData = (PCLDATA)vlmcsd_malloc(sizeof(CLDATA));
thr_CLData->socket = s_client;
thr_CLData->RpcAssocGroup = RpcAssocGroup;
#if defined(_WIN32) || defined (__CYGWIN__) // Windows threads
return serveClientAsyncWinThreads(thr_CLData);
#else // Posix Threads
return ServeClientAsyncPosixThreads(thr_CLData);
#endif // Posix Threads
#endif // USE_THREADS
}
#endif // NO_SOCKETS
int runServer()
{
DWORD RpcAssocGroup = rand32();
// If compiled for inetd-only mode just serve the stdin socket
#ifdef NO_SOCKETS
serveClient(STDIN_FILENO, RpcAssocGroup);
return 0;
#else
// In inetd mode just handle the stdin socket
if (InetdMode)
{
serveClient(STDIN_FILENO, RpcAssocGroup);
return 0;
}
// Standalone mode
for (;;)
{
int error;
SOCKET s_client;
if ( (s_client = network_accept_any()) == INVALID_SOCKET )
{
error = socket_errno;
if (error == VLMCSD_EINTR || error == VLMCSD_ECONNABORTED) continue;
#ifdef _NTSERVICE
if (ServiceShutdown) return 0;
#endif
#ifndef NO_LOG
logger("Fatal: %s\n",vlmcsd_strerror(error));
#endif
return error;
}
RpcAssocGroup++;
serveClientAsync(s_client, RpcAssocGroup);
}
#endif // NO_SOCKETS
return 0;
}
#endif // USE_MSRPC

34
network.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef INCLUDED_NETWORK_H
#define INCLUDED_NETWORK_H
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include "types.h"
int_fast8_t sendrecv(SOCKET sock, BYTE *data, int len, int_fast8_t do_send);
#define _recv(s, d, l) sendrecv(s, (BYTE *)d, l, 0)
#define _send(s, d, l) sendrecv(s, (BYTE *)d, l, !0)
#ifndef NO_SOCKETS
void closeAllListeningSockets();
BOOL addListeningSocket(const char *const addr);
__pure int_fast8_t checkProtocolStack(const int addressfamily);
#endif // NO_SOCKETS
int runServer();
SOCKET connectToAddress(const char *const addr, const int AddressFamily, int_fast8_t showHostName);
int_fast8_t isDisconnected(const SOCKET s);
#endif // INCLUDED_NETWORK_H

355
ns_name.c Normal file
View File

@ -0,0 +1,355 @@
/*
* Copyright (c) 1996,1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/*
* Modified by Hotbird64 for use with vlmcs.
*/
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#ifdef DNS_PARSER_INTERNAL
#ifndef NO_DNS
#include <sys/types.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include "types.h"
#include "ns_name.h"
#ifdef SPRINTF_CHAR
# define SPRINTF(x) strlen(sprintf/**/x)
#else
# define SPRINTF(x) ((size_t)sprintf x)
#endif
#define NS_TYPE_ELT 0x40 /* EDNS0 extended label type */
#define DNS_LABELTYPE_BITSTRING 0x41
#define NS_MAXCDNAME 255
#define NS_CMPRSFLGS 0xc0
/* Data. */
static char digits[] = "0123456789";
/* Forward. */
static int special_vlmcsd(int);
static int printable_vlmcsd(int);
static int labellen_vlmcsd(const uint8_t *);
static int decode_bitstring_vlmcsd(const char **, char *, const char *);
/*
* ns_name_ntop(src, dst, dstsiz)
* Convert an encoded domain name to printable ascii as per RFC1035.
* return:
* Number of bytes written to buffer, or -1 (with errno set)
* notes:
* The root is returned as "."
* All other domains are returned in non absolute form
*/
static int
ns_name_ntop_vlmcsd(const uint8_t *src, char *dst, size_t dstsiz)
{
const uint8_t *cp;
char *dn, *eom;
uint8_t c;
uint32_t n;
int l;
cp = src;
dn = dst;
eom = dst + dstsiz;
while ((n = *cp++) != 0) {
if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
/* Some kind of compression pointer. */
errno = EMSGSIZE;
return (-1);
}
if (dn != dst) {
if (dn >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '.';
}
if ((l = labellen_vlmcsd(cp - 1)) < 0) {
errno = EMSGSIZE; /* XXX */
return(-1);
}
if (dn + l >= eom) {
errno = EMSGSIZE;
return (-1);
}
if ((n & NS_CMPRSFLGS) == NS_TYPE_ELT) {
int m;
if (n != DNS_LABELTYPE_BITSTRING) {
/* XXX: labellen should reject this case */
errno = EINVAL;
return(-1);
}
if ((m = decode_bitstring_vlmcsd((const char **)&cp, dn, eom)) < 0)
{
errno = EMSGSIZE;
return(-1);
}
dn += m;
continue;
}
for ((void)NULL; l > 0; l--) {
c = *cp++;
if (special_vlmcsd(c)) {
if (dn + 1 >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '\\';
*dn++ = (char)c;
} else if (!printable_vlmcsd(c)) {
if (dn + 3 >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '\\';
*dn++ = digits[c / 100];
*dn++ = digits[(c % 100) / 10];
*dn++ = digits[c % 10];
} else {
if (dn >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = (char)c;
}
}
}
if (dn == dst) {
if (dn >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '.';
}
if (dn >= eom) {
errno = EMSGSIZE;
return (-1);
}
*dn++ = '\0';
return (dn - dst);
}
static int
ns_name_unpack_vlmcsd(const uint8_t *msg, const uint8_t *eom, const uint8_t *src,
uint8_t *dst, size_t dstsiz)
{
const uint8_t *srcp, *dstlim;
uint8_t *dstp;
int n, len, checked, l;
len = -1;
checked = 0;
dstp = dst;
srcp = src;
dstlim = dst + dstsiz;
if (srcp < msg || srcp >= eom) {
errno = EMSGSIZE;
return (-1);
}
/* Fetch next label in domain name. */
while ((n = *srcp++) != 0) {
/* Check for indirection. */
switch (n & NS_CMPRSFLGS) {
case 0:
case NS_TYPE_ELT:
/* Limit checks. */
if ((l = labellen_vlmcsd(srcp - 1)) < 0) {
errno = EMSGSIZE;
return(-1);
}
if (dstp + l + 1 >= dstlim || srcp + l >= eom) {
errno = EMSGSIZE;
return (-1);
}
checked += l + 1;
*dstp++ = n;
memcpy(dstp, srcp, l);
dstp += l;
srcp += l;
break;
case NS_CMPRSFLGS:
if (srcp >= eom) {
errno = EMSGSIZE;
return (-1);
}
if (len < 0)
len = srcp - src + 1;
srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
if (srcp < msg || srcp >= eom) { /* Out of range. */
errno = EMSGSIZE;
return (-1);
}
checked += 2;
/*
* Check for loops in the compressed name;
* if we've looked at the whole message,
* there must be a loop.
*/
if (checked >= eom - msg) {
errno = EMSGSIZE;
return (-1);
}
break;
default:
errno = EMSGSIZE;
return (-1); /* flag error */
}
}
*dstp = '\0';
if (len < 0)
len = srcp - src;
return (len);
}
/*
* ns_name_uncompress_vlmcsd(msg, eom, src, dst, dstsiz)
* Expand compressed domain name to presentation format.
* return:
* Number of bytes read out of `src', or -1 (with errno set).
* note:
* Root domain returns as "." not "".
*/
int
ns_name_uncompress_vlmcsd(const uint8_t *msg, const uint8_t *eom, const uint8_t *src,
char *dst, size_t dstsiz)
{
uint8_t tmp[NS_MAXCDNAME];
int n;
if ((n = ns_name_unpack_vlmcsd(msg, eom, src, tmp, sizeof tmp)) == -1)
return (-1);
if (ns_name_ntop_vlmcsd(tmp, dst, dstsiz) == -1)
return (-1);
return (n);
}
/*
* special(ch)
* Thinking in noninternationalized USASCII (per the DNS spec),
* is this characted special ("in need of quoting") ?
* return:
* boolean.
*/
static int
special_vlmcsd(int ch) {
switch (ch) {
case 0x22: /* '"' */
case 0x2E: /* '.' */
case 0x3B: /* ';' */
case 0x5C: /* '\\' */
case 0x28: /* '(' */
case 0x29: /* ')' */
/* Special modifiers in zone files. */
case 0x40: /* '@' */
case 0x24: /* '$' */
return (1);
default:
return (0);
}
}
/*
* printable(ch)
* Thinking in noninternationalized USASCII (per the DNS spec),
* is this character visible and not a space when printed ?
* return:
* boolean.
*/
static int
printable_vlmcsd(int ch) {
return (ch > 0x20 && ch < 0x7f);
}
static int
decode_bitstring_vlmcsd(const char **cpp, char *dn, const char *eom)
{
const char *cp = *cpp;
char *beg = dn, tc;
int b, blen, plen;
if ((blen = (*cp & 0xff)) == 0)
blen = 256;
plen = (blen + 3) / 4;
plen += sizeof("\\[x/]") + (blen > 99 ? 3 : (blen > 9) ? 2 : 1);
if (dn + plen >= eom)
return(-1);
cp++;
dn += SPRINTF((dn, "\\[x"));
for (b = blen; b > 7; b -= 8, cp++)
dn += SPRINTF((dn, "%02x", *cp & 0xff));
if (b > 4) {
tc = *cp++;
dn += SPRINTF((dn, "%02x", tc & (0xff << (8 - b))));
} else if (b > 0) {
tc = *cp++;
dn += SPRINTF((dn, "%1x",
((tc >> 4) & 0x0f) & (0x0f << (4 - b))));
}
dn += SPRINTF((dn, "/%d]", blen));
*cpp = cp;
return(dn - beg);
}
static int
labellen_vlmcsd(const uint8_t *lp)
{
int bitlen;
uint8_t l = *lp;
if ((l & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
/* should be avoided by the caller */
return(-1);
}
if ((l & NS_CMPRSFLGS) == NS_TYPE_ELT) {
if (l == DNS_LABELTYPE_BITSTRING) {
if ((bitlen = *(lp + 1)) == 0)
bitlen = 256;
return((bitlen + 7 ) / 8 + 1);
}
return(-1); /* unknwon ELT */
}
return(l);
}
#endif // !NO_DNS
#endif // DNS_PARSER_INTERNAL

9
ns_name.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef NS_NAME_H_
#define NS_NAME_H_
int
ns_name_uncompress_vlmcsd(const uint8_t *msg, const uint8_t *eom, const uint8_t *src,
char *dst, size_t dstsiz);
#endif /* NS_NAME_H_ */

206
ns_parse.c Normal file
View File

@ -0,0 +1,206 @@
/*
* Copyright (c) 1996,1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/*
* Modified by Hotbird64 for use with vlmcs.
*/
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#ifdef DNS_PARSER_INTERNAL
#ifndef NO_DNS
/* Import. */
#include <sys/types.h>
#include <errno.h>
#include <string.h>
#include "types.h"
#include "endian.h"
#include "ns_name.h"
#include "ns_parse.h"
/* Macros. */
#define NS_GET16_VLMCSD(s, cp) do { \
(s) = GET_UA16BE(cp); \
(cp) += NS_INT16SZ; \
} while (0)
#define NS_GET32_VLMCSD(l, cp) do { \
(l) = GET_UA32BE(cp); \
(cp) += NS_INT32SZ; \
} while (0)
#define RETERR(err) do { errno = (err); return (-1); } while (0)
/* Forward. */
static void setsection_vlmcsd(ns_msg_vlmcsd *msg, ns_sect_vlmcsd sect);
static int dn_skipname_vlmcsd(const unsigned char *s, const unsigned char *end)
{
const unsigned char *p;
for (p=s; p<end; p++)
if (!*p) return p-s+1;
else if (*p>=192)
{if (p+1<end) return p-s+2;
else break;}
return -1;
}
static int
ns_skiprr_vlmcsd(const uint8_t *ptr, const uint8_t *eom, ns_sect_vlmcsd section, int count) {
const uint8_t *optr = ptr;
for ((void)NULL; count > 0; count--) {
int b, rdlength;
b = dn_skipname_vlmcsd(ptr, eom);
if (b < 0)
RETERR(EMSGSIZE);
ptr += b/*Name*/ + NS_INT16SZ/*Type*/ + NS_INT16SZ/*Class*/;
if (section != ns_s_qd_vlmcsd) {
if (ptr + NS_INT32SZ + NS_INT16SZ > eom)
RETERR(EMSGSIZE);
ptr += NS_INT32SZ/*TTL*/;
NS_GET16_VLMCSD(rdlength, ptr);
ptr += rdlength/*RData*/;
}
}
if (ptr > eom)
RETERR(EMSGSIZE);
return (ptr - optr);
}
int
ns_initparse_vlmcsd(const uint8_t *msg, int msglen, ns_msg_vlmcsd *handle) {
const uint8_t *eom = msg + msglen;
int i;
memset(handle, 0x5e, sizeof *handle);
handle->_msg = msg;
handle->_eom = eom;
if (msg + NS_INT16SZ > eom)
RETERR(EMSGSIZE);
NS_GET16_VLMCSD(handle->_id, msg);
if (msg + NS_INT16SZ > eom)
RETERR(EMSGSIZE);
NS_GET16_VLMCSD(handle->_flags, msg);
for (i = 0; i < ns_s_max_vlmcsd; i++) {
if (msg + NS_INT16SZ > eom)
RETERR(EMSGSIZE);
NS_GET16_VLMCSD(handle->_counts[i], msg);
}
for (i = 0; i < ns_s_max_vlmcsd; i++)
if (handle->_counts[i] == 0)
handle->_sections[i] = NULL;
else {
int b = ns_skiprr_vlmcsd(msg, eom, (ns_sect_vlmcsd)i,
handle->_counts[i]);
if (b < 0)
return (-1);
handle->_sections[i] = msg;
msg += b;
}
if (msg > eom)
RETERR(EMSGSIZE);
handle->_eom = msg;
setsection_vlmcsd(handle, ns_s_max_vlmcsd);
return (0);
}
int
ns_parserr_vlmcsd(ns_msg_vlmcsd *handle, ns_sect_vlmcsd section, int rrnum, ns_rr_vlmcsd *rr) {
int b;
/* Make section right. */
if (section >= ns_s_max_vlmcsd)
RETERR(ENODEV);
if (section != handle->_sect)
setsection_vlmcsd(handle, section);
/* Make rrnum right. */
if (rrnum == -1)
rrnum = handle->_rrnum;
if (rrnum < 0 || rrnum >= handle->_counts[(int)section])
RETERR(ENODEV);
if (rrnum < handle->_rrnum)
setsection_vlmcsd(handle, section);
if (rrnum > handle->_rrnum) {
b = ns_skiprr_vlmcsd(handle->_msg_ptr, handle->_eom, section,
rrnum - handle->_rrnum);
if (b < 0)
return (-1);
handle->_msg_ptr += b;
handle->_rrnum = rrnum;
}
/* Do the parse. */
b = ns_name_uncompress_vlmcsd(handle->_msg, handle->_eom,
handle->_msg_ptr, rr->name, NS_MAXDNAME);
if (b < 0)
return (-1);
handle->_msg_ptr += b;
if (handle->_msg_ptr + NS_INT16SZ + NS_INT16SZ > handle->_eom)
RETERR(EMSGSIZE);
NS_GET16_VLMCSD(rr->type, handle->_msg_ptr);
NS_GET16_VLMCSD(rr->rr_class, handle->_msg_ptr);
if (section == ns_s_qd_vlmcsd) {
rr->ttl = 0;
rr->rdlength = 0;
rr->rdata = NULL;
} else {
if (handle->_msg_ptr + NS_INT32SZ + NS_INT16SZ > handle->_eom)
RETERR(EMSGSIZE);
NS_GET32_VLMCSD(rr->ttl, handle->_msg_ptr);
NS_GET16_VLMCSD(rr->rdlength, handle->_msg_ptr);
if (handle->_msg_ptr + rr->rdlength > handle->_eom)
RETERR(EMSGSIZE);
rr->rdata = handle->_msg_ptr;
handle->_msg_ptr += rr->rdlength;
}
if (++handle->_rrnum > handle->_counts[(int)section])
setsection_vlmcsd(handle, (ns_sect_vlmcsd)((int)section + 1));
/* All done. */
return (0);
}
/* Private. */
static void
setsection_vlmcsd(ns_msg_vlmcsd *msg, ns_sect_vlmcsd sect) {
msg->_sect = sect;
if (sect == ns_s_max_vlmcsd) {
msg->_rrnum = -1;
msg->_msg_ptr = NULL;
} else {
msg->_rrnum = 0;
msg->_msg_ptr = msg->_sections[(int)sect];
}
}
#endif // !NO_DNS
#endif // DNS_PARSER_INTERNAL

73
ns_parse.h Normal file
View File

@ -0,0 +1,73 @@
#ifndef NS_PARSE_H_
#define NS_PARSE_H_
#ifndef NS_INT16SZ
#define NS_INT16SZ (sizeof(uint16_t))
#endif // NS_INT16SZ
#ifndef NS_INT32SZ
#define NS_INT32SZ (sizeof(uint32_t))
#endif // NS_INT32SZ
#ifndef NS_MAXDNAME
#define NS_MAXDNAME 1025
#endif
#define ns_msg_id_vlmcsd(handle) ((handle)._id + 0)
#define ns_msg_base_vlmcsd(handle) ((handle)._msg + 0)
#define ns_msg_end_vlmcsd(handle) ((handle)._eom + 0)
#define ns_msg_size_vlmcsd(handle) ((handle)._eom - (handle)._msg)
#define ns_msg_count_vlmcsd(handle, section) ((handle)._counts[section] + 0)
#define ns_rr_name_vlmcsd(rr) (((rr).name[0] != '\0') ? (rr).name : ".")
#define ns_rr_type_vlmcsd(rr) ((ns_type)((rr).type + 0))
#define ns_rr_class_vlmcsd(rr) ((ns_class)((rr).rr_class + 0))
#define ns_rr_ttl_vlmcsd(rr) ((rr).ttl + 0)
#define ns_rr_rdlen_vlmcsd(rr) ((rr).rdlength + 0)
#define ns_rr_rdata_vlmcsd(rr) ((rr).rdata + 0)
#define ns_msg_id_vlmcsd(handle) ((handle)._id + 0)
#define ns_msg_base_vlmcsd(handle) ((handle)._msg + 0)
#define ns_msg_end_vlmcsd(handle) ((handle)._eom + 0)
#define ns_msg_size_vlmcsd(handle) ((handle)._eom - (handle)._msg)
#define ns_msg_count_vlmcsd(handle, section) ((handle)._counts[section] + 0)
typedef enum __ns_sect_vlmcsd {
ns_s_qd_vlmcsd = 0, /*%< Query: Question. */
ns_s_zn_vlmcsd = 0, /*%< Update: Zone. */
ns_s_an_vlmcsd = 1, /*%< Query: Answer. */
ns_s_pr_vlmcsd = 1, /*%< Update: Prerequisites. */
ns_s_ns_vlmcsd = 2, /*%< Query: Name servers. */
ns_s_ud_vlmcsd = 2, /*%< Update: Update. */
ns_s_ar_vlmcsd = 3, /*%< Query|Update: Additional records. */
ns_s_max_vlmcsd = 4
} ns_sect_vlmcsd;
typedef struct __ns_msg_vlmcsd {
const uint8_t *_msg, *_eom;
uint16_t _id, _flags, _counts[ns_s_max_vlmcsd];
const uint8_t *_sections[ns_s_max_vlmcsd];
ns_sect_vlmcsd _sect;
int _rrnum;
const uint8_t *_msg_ptr;
} ns_msg_vlmcsd;
typedef struct __ns_rr_vlmcsd {
char name[NS_MAXDNAME];
uint16_t type;
uint16_t rr_class;
uint32_t ttl;
uint16_t rdlength;
const uint8_t * rdata;
} ns_rr_vlmcsd;
int ns_initparse_vlmcsd(const uint8_t *msg, int msglen, ns_msg_vlmcsd *handle);
int ns_parserr_vlmcsd(ns_msg_vlmcsd *handle, ns_sect_vlmcsd section, int rrnum, ns_rr_vlmcsd *rr);
#endif /* NS_PARSE_H_ */

346
ntservice.c Normal file
View File

@ -0,0 +1,346 @@
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include "ntservice.h"
#include "shared_globals.h"
#include "vlmcsd.h"
#include "output.h"
#include "helpers.h"
#ifdef _NTSERVICE
SERVICE_STATUS gSvcStatus;
SERVICE_STATUS_HANDLE gSvcStatusHandle;
static VOID WINAPI ServiceCtrlHandler(const DWORD dwCtrl)
{
// Handle the requested control code.
switch(dwCtrl)
{
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
ServiceShutdown = TRUE;
ReportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
// Remove PID file and free ressources
cleanup();
# ifdef USE_MSRPC
ReportServiceStatus(SERVICE_STOPPED, NO_ERROR, 0);
# endif // !USE_MSRPC
return;
/*case SERVICE_CONTROL_INTERROGATE:
break;*/
default:
break;
}
}
static VOID WINAPI ServiceMain(const int argc_unused, CARGV argv_unused)
{
// Register the handler function for the service
gSvcStatusHandle = RegisterServiceCtrlHandler(
NT_SERVICE_NAME,
ServiceCtrlHandler
);
if(!gSvcStatusHandle)
{
//ServiceReportEvent(RegisterServiceCtrlHandler);
return;
}
// These SERVICE_STATUS members remain as set here
gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
gSvcStatus.dwServiceSpecificExitCode = 0;
// Run the actual program
ReportServiceStatus(SERVICE_STOPPED, newmain(), 3000);
}
SERVICE_TABLE_ENTRY NTServiceDispatchTable[] = {
{
(LPSTR)NT_SERVICE_NAME,
(LPSERVICE_MAIN_FUNCTION) ServiceMain
},
{
NULL,
NULL
}
};
VOID ReportServiceStatus(const DWORD dwCurrentState, const DWORD dwWin32ExitCode, const DWORD dwWaitHint)
{
static DWORD dwCheckPoint = 1;
// Fill in the SERVICE_STATUS structure.
gSvcStatus.dwCurrentState = dwCurrentState;
gSvcStatus.dwWin32ExitCode = dwWin32ExitCode;
gSvcStatus.dwWaitHint = dwWaitHint;
if (dwCurrentState == SERVICE_START_PENDING)
gSvcStatus.dwControlsAccepted = 0;
else
gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
if ( (dwCurrentState == SERVICE_RUNNING) ||
(dwCurrentState == SERVICE_STOPPED) )
gSvcStatus.dwCheckPoint = 0;
else
gSvcStatus.dwCheckPoint = dwCheckPoint++;
// Report the status of the service to the SCM.
SetServiceStatus(gSvcStatusHandle, &gSvcStatus);
}
/*VOID ServiceReportEvent(char *szFunction)
{
HANDLE hEventSource;
const char *eventStrings[2];
TCHAR Buffer[80];
hEventSource = RegisterEventSource(NULL, NT_SERVICE_NAME);
if (hEventSource)
{
snprintf(Buffer, 80, "%s failed with %d", szFunction, GetLastError());
eventStrings[0] = NT_SERVICE_NAME;
eventStrings[1] = Buffer;
ReportEvent(hEventSource, // event log handle
EVENTLOG_ERROR_TYPE, // event type
0, // event category
00, // event identifier
NULL, // no security identifier
2, // size of lpszStrings array
0, // no binary data
eventStrings, // array of strings
NULL); // no binary data
DeregisterEventSource(hEventSource);
}
}*/
//Returns 0=Error, 1=Success, 2=Doesn't exist
static uint_fast8_t OpenAndRemoveService(DWORD *dwPreviousState, SC_HANDLE *schSCManager)
{
SERVICE_STATUS status;
uint_fast8_t i;
SC_HANDLE installedService;
uint_fast8_t result = 1;
BOOL closeManager = FALSE;
// Allow NULL for both Arguments
if (!dwPreviousState) dwPreviousState = (DWORD*)alloca(sizeof(*dwPreviousState));
if (!schSCManager)
{
schSCManager = (SC_HANDLE*)alloca(sizeof(*schSCManager));
closeManager = TRUE;
}
*schSCManager = OpenSCManager(
NULL, // local computer
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights
if (!*schSCManager) return 0;
if (!(installedService = OpenService(*schSCManager, NT_SERVICE_NAME, SERVICE_ALL_ACCESS)))
{
result = 2;
}
else
{
*dwPreviousState = SERVICE_STOPPED;
if (QueryServiceStatus(installedService, &status)) *dwPreviousState = status.dwCurrentState;
ControlService(installedService, SERVICE_CONTROL_STOP, &status);
for (i = 0; i < 10; i++)
{
QueryServiceStatus(installedService, &status);
// Give it 100 ms after it reported SERVICE_STOPPED. Subsequent CreateService will fail otherwise
Sleep(100);
if (status.dwCurrentState == SERVICE_STOPPED) break;
}
if (!DeleteService(installedService)) result = 0;
CloseServiceHandle(installedService);
}
if (closeManager) CloseServiceHandle(*schSCManager);
return result;
}
static VOID ServiceInstaller(const char *restrict ServiceUser, const char *const ServicePassword)
{
SC_HANDLE schSCManager;
SC_HANDLE schService;
char szPath[MAX_PATH] = "\"";
if (!GetModuleFileName(NULL, szPath + sizeof(char), MAX_PATH - 1))
{
errorout("Cannot install service (%d)\n", (uint32_t)GetLastError());
return;
}
strcat(szPath,"\"");
int i;
for (i = 1; i < global_argc; i ++)
{
// Strip unneccessary parameters, especially the password
if (!strcmp(global_argv[i], "-s")) continue;
if (!strcmp(global_argv[i], "-W") ||
!strcmp(global_argv[i], "-U"))
{
i++;
continue;
}
strcat(szPath, " ");
if (strchr(global_argv[i], ' '))
{
strcat(szPath, "\"");
strcat(szPath, global_argv[i]);
strcat(szPath, "\"");
}
else
strcat(szPath, global_argv[i]);
}
// Get a handle to the SCM database.
SERVICE_STATUS status;
DWORD dwPreviousState;
if (!OpenAndRemoveService(&dwPreviousState, &schSCManager))
{
errorout("Service removal failed (%d)\n", (uint32_t)GetLastError());
return;
}
char *tempUser = NULL;
if (ServiceUser)
{
// Shortcuts for some well known users
if (!strcasecmp(ServiceUser, "/l")) ServiceUser="NT AUTHORITY\\LocalService";
if (!strcasecmp(ServiceUser, "/n")) ServiceUser="NT AUTHORITY\\NetworkService";
// Allow Local Users without .\ , e.g. "johndoe" instead of ".\johndoe"
if (!strchr(ServiceUser, '\\'))
{
tempUser = (char*)vlmcsd_malloc(strlen(ServiceUser) + 3);
strcpy(tempUser, ".\\");
strcat(tempUser, ServiceUser);
ServiceUser = tempUser;
}
}
schService = CreateService(
schSCManager, // SCM database
NT_SERVICE_NAME, // name of service
NT_SERVICE_DISPLAY_NAME, // service name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
SERVICE_AUTO_START, // start type
SERVICE_ERROR_NORMAL, // error control type
szPath, // path to service's binary
NULL, // no load ordering group
NULL, // no tag identifier
"tcpip\0", // depends on TCP/IP
ServiceUser, // LocalSystem account
ServicePassword); // no password
# if __clang__ && (__CYGWIN__ || __MINGW64__ )
// Workaround for clang not understanding some GCC asm syntax used in <w32api/psdk_inc/intrin-impl.h>
ZeroMemory((char*)ServicePassword, strlen(ServicePassword));
# else
SecureZeroMemory((char*)ServicePassword, strlen(ServicePassword));
# endif
if (tempUser) free(tempUser);
if (schService == NULL)
{
errorout("CreateService failed (%u)\n", (uint32_t)GetLastError());
CloseServiceHandle(schSCManager);
return;
}
else
{
errorout("Service installed successfully\n");
if (dwPreviousState == SERVICE_RUNNING)
{
printf("Restarting " NT_SERVICE_NAME " service => ");
status.dwCurrentState = SERVICE_STOPPED;
if (StartService(schService, 0, NULL))
{
for (i = 0; i < 10; i++)
{
if (!QueryServiceStatus(schService, &status) || status.dwCurrentState != SERVICE_START_PENDING) break;
Sleep(100);
}
if (status.dwCurrentState == SERVICE_RUNNING)
printf("Success\n");
else if (status.dwCurrentState == SERVICE_START_PENDING)
printf("Not ready within a second\n");
else
errorout("Error\n");
}
else
errorout("Error %u\n", (uint32_t)GetLastError());
}
}
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
}
int NtServiceInstallation(const int_fast8_t installService, const char *restrict ServiceUser, const char *const ServicePassword)
{
if (IsNTService) return 0;
if (installService == 1) // Install
{
ServiceInstaller(ServiceUser, ServicePassword);
return(0);
}
if (installService == 2) // Remove
{
switch(OpenAndRemoveService(NULL, NULL))
{
case 0:
errorout("Error removing service %s\n", NT_SERVICE_NAME);
return(!0);
case 1:
printf("Service %s removed successfully\n", NT_SERVICE_NAME);
return(0);
default:
errorout("Service %s does not exist.\n", NT_SERVICE_NAME);
return(!0);
}
}
// Do nothing
return(0);
}
#endif // _NTSERVICE

28
ntservice.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef INCLUDED_NTSERVICE_H
#define INCLUDED_NTSERVICE_H
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include "types.h"
#ifdef _NTSERVICE
//#include <strsafe.h>
#define NT_SERVICE_NAME "vlmcsd"
#define NT_SERVICE_DISPLAY_NAME "Key Management Server"
extern SERVICE_TABLE_ENTRY NTServiceDispatchTable[];
VOID ReportServiceStatus(const DWORD, const DWORD, const DWORD);
int NtServiceInstallation(const int_fast8_t installService, const char *restrict ServiceUser, const char *const ServicePassword);
#else // !_NTSERVICE
#define ReportServiceStatus(x,y,z)
#endif // _NTSERVICE
#endif // INCLUDED_NTSERVICE_H

240
output.c Normal file
View File

@ -0,0 +1,240 @@
#ifndef _DEFAULT_SOURCE
#define _DEFAULT_SOURCE
#endif // _DEFAULT_SOURCE
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include "output.h"
#include "shared_globals.h"
#include "endian.h"
#include "helpers.h"
#ifndef NO_LOG
static void vlogger(const char *message, va_list args)
{
FILE *log;
#ifdef _NTSERVICE
if (!IsNTService && logstdout) log = stdout;
#else
if (logstdout) log = stdout;
#endif
else
{
if (fn_log == NULL) return;
#ifndef _WIN32
if (!strcmp(fn_log, "syslog"))
{
openlog("vlmcsd", LOG_CONS | LOG_PID, LOG_USER);
////PORTABILITY: vsyslog is not in Posix but virtually all Unixes have it
vsyslog(LOG_INFO, message, args);
closelog();
return;
}
#endif // _WIN32
log = fopen(fn_log, "a");
if ( !log ) return;
}
time_t now = time(0);
#ifdef USE_THREADS
char mbstr[2048];
#else
char mbstr[24];
#endif
strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %X", localtime(&now));
#ifndef USE_THREADS
fprintf(log, "%s: ", mbstr);
vfprintf(log, message, args);
fflush(log);
#else // USE_THREADS
// We write everything to a string before we really log inside the critical section
// so formatting the output can be concurrent
strcat(mbstr, ": ");
int len = strlen(mbstr);
vsnprintf(mbstr + len, sizeof(mbstr) - len, message, args);
lock_mutex(&logmutex);
fputs(mbstr, log);
fflush(log);
unlock_mutex(&logmutex);
#endif // USE_THREADS
if (log != stdout) fclose(log);
}
// Always sends to log output
int logger(const char *const fmt, ...)
{
va_list args;
va_start(args, fmt);
vlogger(fmt, args);
va_end(args);
return 0;
}
#endif //NO_LOG
// Output to stderr if it is available or to log otherwise (e.g. if running as daemon/service)
void printerrorf(const char *const fmt, ...)
{
va_list arglist;
va_start(arglist, fmt);
#ifndef NO_LOG
#ifdef _NTSERVICE
if (InetdMode || IsNTService)
#else // !_NTSERVICE
if (InetdMode)
#endif // NTSERVIICE
vlogger(fmt, arglist);
else
#endif //NO_LOG
{
vfprintf(stderr, fmt, arglist);
fflush(stderr);
}
va_end(arglist);
}
// Always output to stderr
int errorout(const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
int i = vfprintf(stderr, fmt, args);
va_end(args);
fflush(stderr);
return i;
}
static const char *LicenseStatusText[] =
{
"Unlicensed", "Licensed", "OOB grace", "OOT grace", "Non-Genuine", "Notification", "Extended grace"
};
void uuid2StringLE(const GUID *const guid, char *const string)
{
sprintf(string,
#ifdef _WIN32
"%08x-%04x-%04x-%04x-%012I64x",
#else
"%08x-%04x-%04x-%04x-%012llx",
#endif
(unsigned int)LE32( guid->Data1 ),
(unsigned int)LE16( guid->Data2 ),
(unsigned int)LE16( guid->Data3 ),
(unsigned int)BE16( *(uint16_t*)guid->Data4 ),
(unsigned long long)BE64(*(uint64_t*)(guid->Data4)) & 0xffffffffffffLL
);
}
void logRequestVerbose(const REQUEST *const Request, const PRINTFUNC p)
{
char guidBuffer[GUID_STRING_LENGTH + 1];
char WorkstationBuffer[3 * WORKSTATION_NAME_BUFFER];
const char *productName;
ProdListIndex_t index;
p("Protocol version : %u.%u\n", LE16(Request->MajorVer), LE16(Request->MinorVer));
p("Client is a virtual machine : %s\n", LE32(Request->VMInfo) ? "Yes" : "No");
p("Licensing status : %u (%s)\n", (uint32_t)LE32(Request->LicenseStatus), LE32(Request->LicenseStatus) < _countof(LicenseStatusText) ? LicenseStatusText[LE32(Request->LicenseStatus)] : "Unknown");
p("Remaining time (0 = forever) : %i minutes\n", (uint32_t)LE32(Request->BindingExpiration));
uuid2StringLE(&Request->AppID, guidBuffer);
productName = getProductNameLE(&Request->AppID, AppList, &index);
p("Application ID : %s (%s)\n", guidBuffer, productName);
uuid2StringLE(&Request->ActID, guidBuffer);
#ifndef NO_EXTENDED_PRODUCT_LIST
productName = getProductNameLE(&Request->ActID, ExtendedProductList, &index);
#else
productName = "Unknown";
#endif
p("Activation ID (Product) : %s (%s)\n", guidBuffer, productName);
uuid2StringLE(&Request->KMSID, guidBuffer);
#ifndef NO_BASIC_PRODUCT_LIST
productName = getProductNameLE(&Request->KMSID, ProductList, &index);
#else
productName = "Unknown";
#endif
p("Key Management Service ID : %s (%s)\n", guidBuffer, productName);
uuid2StringLE(&Request->CMID, guidBuffer);
p("Client machine ID : %s\n", guidBuffer);
uuid2StringLE(&Request->CMID_prev, guidBuffer);
p("Previous client machine ID : %s\n", guidBuffer);
char mbstr[64];
time_t st;
st = fileTimeToUnixTime(&Request->ClientTime);
strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %X", gmtime(&st));
p("Client request timestamp (UTC) : %s\n", mbstr);
ucs2_to_utf8(Request->WorkstationName, WorkstationBuffer, WORKSTATION_NAME_BUFFER, sizeof(WorkstationBuffer));
p("Workstation name : %s\n", WorkstationBuffer);
p("N count policy (minimum clients): %u\n", (uint32_t)LE32(Request->N_Policy));
}
void logResponseVerbose(const char *const ePID, const BYTE *const hwid, const RESPONSE *const response, const PRINTFUNC p)
{
char guidBuffer[GUID_STRING_LENGTH + 1];
//SYSTEMTIME st;
p("Protocol version : %u.%u\n", (uint32_t)LE16(response->MajorVer), (uint32_t)LE16(response->MinorVer));
p("KMS host extended PID : %s\n", ePID);
if (LE16(response->MajorVer) > 5)
# ifndef _WIN32
p("KMS host Hardware ID : %016llX\n", (unsigned long long)BE64(*(uint64_t*)hwid));
# else // _WIN32
p("KMS host Hardware ID : %016I64X\n", (unsigned long long)BE64(*(uint64_t*)hwid));
# endif // WIN32
uuid2StringLE(&response->CMID, guidBuffer);
p("Client machine ID : %s\n", guidBuffer);
char mbstr[64];
time_t st;
st = fileTimeToUnixTime(&response->ClientTime);
strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %X", gmtime(&st));
p("Client request timestamp (UTC) : %s\n", mbstr);
p("KMS host current active clients : %u\n", (uint32_t)LE32(response->Count));
p("Renewal interval policy : %u\n", (uint32_t)LE32(response->VLRenewalInterval));
p("Activation interval policy : %u\n", (uint32_t)LE32(response->VLActivationInterval));
}

27
output.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef INCLUDED_OUTPUT_H
#define INCLUDED_OUTPUT_H
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include "kms.h"
typedef int (*PRINTFUNC)(const char *const fmt, ...);
void printerrorf(const char *const fmt, ...);
int errorout(const char* fmt, ...);
void logRequestVerbose(const REQUEST *const Request, const PRINTFUNC p);
void logResponseVerbose(const char *const ePID, const BYTE *const hwid, const RESPONSE *const response, const PRINTFUNC p);
#ifndef NO_LOG
int logger(const char *const fmt, ...);
#endif //NO_LOG
void uuid2StringLE(const GUID *const guid, char *const string);
//void copy_arguments(int argc, char **argv, char ***new_argv);
//void destroy_arguments(int argc, char **argv);
#endif // INCLUDED_OUTPUT_H

499
resolv.h Normal file
View File

@ -0,0 +1,499 @@
/* $NetBSD: resolv.h,v 1.31 2005/12/26 19:01:47 perry Exp $ */
/*
* Copyright (c) 1983, 1987, 1989
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
*/
/*
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (c) 1996-1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* @(#)resolv.h 8.1 (Berkeley) 6/2/93
* Id: resolv.h,v 1.7.2.11.4.2 2004/06/25 00:41:05 marka Exp
*/
#ifndef _RESOLV_PRIVATE_H_
#define _RESOLV_PRIVATE_H_
#include <resolv.h>
#include "resolv_static.h"
/*
* Revision information. This is the release date in YYYYMMDD format.
* It can change every day so the right thing to do with it is use it
* in preprocessor commands such as "#if (__RES > 19931104)". Do not
* compare for equality; rather, use it to determine whether your resolver
* is new enough to contain a certain feature.
*/
#define __RES 20030124
/*
* This used to be defined in res_query.c, now it's in herror.c.
* [XXX no it's not. It's in irs/irs_data.c]
* It was
* never extern'd by any *.h file before it was placed here. For thread
* aware programs, the last h_errno value set is stored in res->h_errno.
*
* XXX: There doesn't seem to be a good reason for exposing RES_SET_H_ERRNO
* (and __h_errno_set) to the public via <resolv.h>.
* XXX: __h_errno_set is really part of IRS, not part of the resolver.
* If somebody wants to build and use a resolver that doesn't use IRS,
* what do they do? Perhaps something like
* #ifdef WANT_IRS
* # define RES_SET_H_ERRNO(r,x) __h_errno_set(r,x)
* #else
* # define RES_SET_H_ERRNO(r,x) (h_errno = (r)->res_h_errno = (x))
* #endif
*/
#define RES_SET_H_ERRNO(r,x) (h_errno = (r)->res_h_errno = (x))
struct __res_state; /* forward */
/*
* Resolver configuration file.
* Normally not present, but may contain the address of the
* initial name server(s) to query and the domain search list.
*/
#ifndef _PATH_RESCONF
#ifdef ANDROID_CHANGES
#define _PATH_RESCONF "/etc/ppp/resolv.conf"
#else
#define _PATH_RESCONF "/etc/resolv.conf"
#endif
#endif
typedef enum { res_goahead, res_nextns, res_modified, res_done, res_error }
res_sendhookact;
typedef res_sendhookact (*res_send_qhook)(struct sockaddr * const *,
const u_char **, int *,
u_char *, int, int *);
typedef res_sendhookact (*res_send_rhook)(const struct sockaddr *,
const u_char *, int, u_char *,
int, int *);
struct res_sym {
int number; /* Identifying number, like T_MX */
const char * name; /* Its symbolic name, like "MX" */
const char * humanname; /* Its fun name, like "mail exchanger" */
};
/*
* Global defines and variables for resolver stub.
*/
#define MAXNS 3 /* max # name servers we'll track */
#define MAXDFLSRCH 3 /* # default domain levels to try */
#define MAXDNSRCH 6 /* max # domains in search path */
#define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */
#define RES_TIMEOUT 5 /* min. seconds between retries */
#define MAXRESOLVSORT 10 /* number of net to sort on */
#define RES_MAXNDOTS 15 /* should reflect bit field size */
#define RES_MAXRETRANS 30 /* only for resolv.conf/RES_OPTIONS */
#define RES_MAXRETRY 5 /* only for resolv.conf/RES_OPTIONS */
#define RES_DFLRETRY 2 /* Default #/tries. */
#define RES_MAXTIME 65535 /* Infinity, in milliseconds. */
struct __res_state_ext;
struct __res_state {
int retrans; /* retransmission time interval */
int retry; /* number of times to retransmit */
#ifdef sun
u_int options; /* option flags - see below. */
#else
u_long options; /* option flags - see below. */
#endif
int nscount; /* number of name servers */
struct sockaddr_in
nsaddr_list[MAXNS]; /* address of name server */
#define nsaddr nsaddr_list[0] /* for backward compatibility */
u_short id; /* current message id */
char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */
char defdname[256]; /* default domain (deprecated) */
#ifdef sun
u_int pfcode; /* RES_PRF_ flags - see below. */
#else
u_long pfcode; /* RES_PRF_ flags - see below. */
#endif
unsigned ndots:4; /* threshold for initial abs. query */
unsigned nsort:4; /* number of elements in sort_list[] */
char unused[3];
struct {
struct in_addr addr;
uint32_t mask;
} sort_list[MAXRESOLVSORT];
#ifdef __OLD_RES_STATE
char lookups[4];
#else
res_send_qhook qhook; /* query hook */
res_send_rhook rhook; /* response hook */
int res_h_errno; /* last one set for this context */
int _vcsock; /* PRIVATE: for res_send VC i/o */
u_int _flags; /* PRIVATE: see below */
u_int _pad; /* make _u 64 bit aligned */
union {
/* On an 32-bit arch this means 512b total. */
char pad[72 - 4*sizeof (int) - 2*sizeof (void *)];
struct {
uint16_t nscount;
uint16_t nstimes[MAXNS]; /* ms. */
int nssocks[MAXNS];
struct __res_state_ext *ext; /* extention for IPv6 */
} _ext;
} _u;
#endif
struct res_static rstatic[1];
};
typedef struct __res_state *res_state;
union res_sockaddr_union {
struct sockaddr_in sin;
#ifdef IN6ADDR_ANY_INIT
struct sockaddr_in6 sin6;
#endif
#ifdef ISC_ALIGN64
int64_t __align64; /* 64bit alignment */
#else
int32_t __align32; /* 32bit alignment */
#endif
char __space[128]; /* max size */
};
/*
* Resolver flags (used to be discrete per-module statics ints).
*/
#define RES_F_VC 0x00000001 /* socket is TCP */
#define RES_F_CONN 0x00000002 /* socket is connected */
#define RES_F_EDNS0ERR 0x00000004 /* EDNS0 caused errors */
#define RES_F__UNUSED 0x00000008 /* (unused) */
#define RES_F_LASTMASK 0x000000F0 /* ordinal server of last res_nsend */
#define RES_F_LASTSHIFT 4 /* bit position of LASTMASK "flag" */
#define RES_GETLAST(res) (((res)._flags & RES_F_LASTMASK) >> RES_F_LASTSHIFT)
/* res_findzonecut2() options */
#define RES_EXHAUSTIVE 0x00000001 /* always do all queries */
#define RES_IPV4ONLY 0x00000002 /* IPv4 only */
#define RES_IPV6ONLY 0x00000004 /* IPv6 only */
/*
* Resolver options (keep these in synch with res_debug.c, please)
*/
#define RES_INIT 0x00000001 /* address initialized */
#define RES_DEBUG 0x00000002 /* print debug messages */
#define RES_AAONLY 0x00000004 /* authoritative answers only (!IMPL)*/
#define RES_USEVC 0x00000008 /* use virtual circuit */
#define RES_PRIMARY 0x00000010 /* query primary server only (!IMPL) */
#define RES_IGNTC 0x00000020 /* ignore trucation errors */
#define RES_RECURSE 0x00000040 /* recursion desired */
#define RES_DEFNAMES 0x00000080 /* use default domain name */
#define RES_STAYOPEN 0x00000100 /* Keep TCP socket open */
#define RES_DNSRCH 0x00000200 /* search up local domain tree */
#define RES_INSECURE1 0x00000400 /* type 1 security disabled */
#define RES_INSECURE2 0x00000800 /* type 2 security disabled */
#define RES_NOALIASES 0x00001000 /* shuts off HOSTALIASES feature */
#define RES_USE_INET6 0x00002000 /* use/map IPv6 in gethostbyname() */
#define RES_ROTATE 0x00004000 /* rotate ns list after each query */
#define RES_NOCHECKNAME 0x00008000 /* do not check names for sanity. */
#define RES_KEEPTSIG 0x00010000 /* do not strip TSIG records */
#define RES_BLAST 0x00020000 /* blast all recursive servers */
#define RES_NOTLDQUERY 0x00100000 /* don't unqualified name as a tld */
#define RES_USE_DNSSEC 0x00200000 /* use DNSSEC using OK bit in OPT */
/* #define RES_DEBUG2 0x00400000 */ /* nslookup internal */
/* KAME extensions: use higher bit to avoid conflict with ISC use */
#define RES_USE_DNAME 0x10000000 /* use DNAME */
#define RES_USE_EDNS0 0x40000000 /* use EDNS0 if configured */
#define RES_NO_NIBBLE2 0x80000000 /* disable alternate nibble lookup */
#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | \
RES_DNSRCH | RES_NO_NIBBLE2)
/*
* Resolver "pfcode" values. Used by dig.
*/
#define RES_PRF_STATS 0x00000001
#define RES_PRF_UPDATE 0x00000002
#define RES_PRF_CLASS 0x00000004
#define RES_PRF_CMD 0x00000008
#define RES_PRF_QUES 0x00000010
#define RES_PRF_ANS 0x00000020
#define RES_PRF_AUTH 0x00000040
#define RES_PRF_ADD 0x00000080
#define RES_PRF_HEAD1 0x00000100
#define RES_PRF_HEAD2 0x00000200
#define RES_PRF_TTLID 0x00000400
#define RES_PRF_HEADX 0x00000800
#define RES_PRF_QUERY 0x00001000
#define RES_PRF_REPLY 0x00002000
#define RES_PRF_INIT 0x00004000
#define RES_PRF_TRUNC 0x00008000
/* 0x00010000 */
/* Things involving an internal (static) resolver context. */
__BEGIN_DECLS
extern struct __res_state *__res_get_state(void);
extern void __res_put_state(struct __res_state *);
#ifndef ANDROID_CHANGES
/*
* Source and Binary compatibility; _res will not work properly
* with multi-threaded programs.
*/
extern struct __res_state *__res_state(void);
#define _res (*__res_state())
#endif
__END_DECLS
#ifndef __BIND_NOSTATIC
#define fp_nquery __fp_nquery
#define fp_query __fp_query
#define hostalias __hostalias
#define p_query __p_query
#define res_close __res_close
#define res_opt __res_opt
#define res_isourserver __res_isourserver
#define res_querydomain __res_querydomain
#define res_send __res_send
#define res_sendsigned __res_sendsigned
#ifdef BIND_RES_POSIX3
#define dn_expand __dn_expand
#define res_init __res_init
#define res_query __res_query
#define res_search __res_search
#define res_mkquery __res_mkquery
#endif
__BEGIN_DECLS
void fp_nquery(const u_char *, int, FILE *);
void fp_query(const u_char *, FILE *);
const char * hostalias(const char *);
void p_query(const u_char *);
void res_close(void);
int res_init(void);
int res_opt(int, u_char *, int, int);
int res_isourserver(const struct sockaddr_in *);
int res_mkquery(int, const char *, int, int, const u_char *, int, const u_char *, u_char *, int);
int res_query(const char *, int, int, u_char *, int);
int res_querydomain(const char *, const char *, int, int, u_char *, int);
int res_search(const char *, int, int, u_char *, int);
int res_send(const u_char *, int, u_char *, int);
int res_sendsigned(const u_char *, int, ns_tsig_key *, u_char *, int);
__END_DECLS
#endif
#if !defined(SHARED_LIBBIND) || defined(LIB)
/*
* If libbind is a shared object (well, DLL anyway)
* these externs break the linker when resolv.h is
* included by a lib client (like named)
* Make them go away if a client is including this
*
*/
extern const struct res_sym __p_key_syms[];
extern const struct res_sym __p_cert_syms[];
extern const struct res_sym __p_class_syms[];
extern const struct res_sym __p_type_syms[];
extern const struct res_sym __p_rcode_syms[];
#endif /* SHARED_LIBBIND */
#ifndef ADNROID_CHANGES
#define b64_ntop __b64_ntop
#define b64_pton __b64_pton
#endif
#define dn_comp __dn_comp
#define dn_count_labels __dn_count_labels
#define dn_skipname __dn_skipname
#define fp_resstat __fp_resstat
#define loc_aton __loc_aton
#define loc_ntoa __loc_ntoa
#define p_cdname __p_cdname
#define p_cdnname __p_cdnname
#define p_class __p_class
#define p_fqname __p_fqname
#define p_fqnname __p_fqnname
#define p_option __p_option
#define p_secstodate __p_secstodate
#define p_section __p_section
#define p_time __p_time
#define p_type __p_type
#define p_rcode __p_rcode
#define p_sockun __p_sockun
#define putlong __putlong
#define putshort __putshort
#define res_dnok __res_dnok
#define res_findzonecut __res_findzonecut
#define res_findzonecut2 __res_findzonecut2
#define res_hnok __res_hnok
#define res_hostalias __res_hostalias
#define res_mailok __res_mailok
#define res_nameinquery __res_nameinquery
#define res_nclose __res_nclose
#define res_ninit __res_ninit
#define res_nmkquery __res_nmkquery
#define res_pquery __res_pquery
#define res_nquery __res_nquery
#define res_nquerydomain __res_nquerydomain
#define res_nsearch __res_nsearch
#define res_nsend __res_nsend
#define res_nsendsigned __res_nsendsigned
#define res_nisourserver __res_nisourserver
#define res_ownok __res_ownok
#define res_queriesmatch __res_queriesmatch
#define res_randomid __res_randomid
#define sym_ntop __sym_ntop
#define sym_ntos __sym_ntos
#define sym_ston __sym_ston
#define res_nopt __res_nopt
#define res_ndestroy __res_ndestroy
#define res_nametoclass __res_nametoclass
#define res_nametotype __res_nametotype
#define res_setservers __res_setservers
#define res_getservers __res_getservers
#define res_buildprotolist __res_buildprotolist
#define res_destroyprotolist __res_destroyprotolist
#define res_destroyservicelist __res_destroyservicelist
#define res_get_nibblesuffix __res_get_nibblesuffix
#define res_get_nibblesuffix2 __res_get_nibblesuffix2
#define res_ourserver_p __res_ourserver_p
#define res_protocolname __res_protocolname
#define res_protocolnumber __res_protocolnumber
#define res_send_setqhook __res_send_setqhook
#define res_send_setrhook __res_send_setrhook
#define res_servicename __res_servicename
#define res_servicenumber __res_servicenumber
__BEGIN_DECLS
int res_hnok(const char *);
int res_ownok(const char *);
int res_mailok(const char *);
int res_dnok(const char *);
int sym_ston(const struct res_sym *, const char *, int *);
const char * sym_ntos(const struct res_sym *, int, int *);
const char * sym_ntop(const struct res_sym *, int, int *);
#ifndef ANDROID_CHANGES
int b64_ntop(u_char const *, size_t, char *, size_t);
int b64_pton(char const *, u_char *, size_t);
#endif
int loc_aton(const char *, u_char *);
const char * loc_ntoa(const u_char *, char *);
int dn_skipname(const u_char *, const u_char *);
void putlong(uint32_t, u_char *);
void putshort(uint16_t, u_char *);
#ifndef __ultrix__
uint16_t _getshort(const u_char *);
uint32_t _getlong(const u_char *);
#endif
const char * p_class(int);
const char * p_time(uint32_t);
const char * p_type(int);
const char * p_rcode(int);
const char * p_sockun(union res_sockaddr_union, char *, size_t);
const u_char * p_cdnname(const u_char *, const u_char *, int, FILE *);
const u_char * p_cdname(const u_char *, const u_char *, FILE *);
const u_char * p_fqnname(const u_char *, const u_char *,
int, char *, int);
const u_char * p_fqname(const u_char *, const u_char *, FILE *);
const char * p_option(u_long);
char * p_secstodate(u_long);
int dn_count_labels(const char *);
int dn_comp(const char *, u_char *, int, u_char **, u_char **);
int dn_expand(const u_char *, const u_char *, const u_char *,
char *, int);
u_int res_randomid(void);
int res_nameinquery(const char *, int, int, const u_char *,
const u_char *);
int res_queriesmatch(const u_char *, const u_char *,
const u_char *, const u_char *);
const char * p_section(int, int);
/* Things involving a resolver context. */
int res_ninit(res_state);
int res_nisourserver(const res_state, const struct sockaddr_in *);
void fp_resstat(const res_state, FILE *);
void res_pquery(const res_state, const u_char *, int, FILE *);
const char * res_hostalias(const res_state, const char *, char *, size_t);
int res_nquery(res_state, const char *, int, int, u_char *, int);
int res_nsearch(res_state, const char *, int, int, u_char *, int);
int res_nquerydomain(res_state, const char *, const char *,
int, int, u_char *, int);
int res_nmkquery(res_state, int, const char *, int, int,
const u_char *, int, const u_char *,
u_char *, int);
int res_nsend(res_state, const u_char *, int, u_char *, int);
int res_nsendsigned(res_state, const u_char *, int,
ns_tsig_key *, u_char *, int);
int res_findzonecut(res_state, const char *, ns_class, int,
char *, size_t, struct in_addr *, int);
int res_findzonecut2(res_state, const char *, ns_class, int,
char *, size_t,
union res_sockaddr_union *, int);
void res_nclose(res_state);
int res_nopt(res_state, int, u_char *, int, int);
void res_send_setqhook(res_send_qhook);
void res_send_setrhook(res_send_rhook);
int __res_vinit(res_state, int);
void res_destroyservicelist(void);
const char * res_servicename(uint16_t, const char *);
const char * res_protocolname(int);
void res_destroyprotolist(void);
void res_buildprotolist(void);
const char * res_get_nibblesuffix(res_state);
const char * res_get_nibblesuffix2(res_state);
void res_ndestroy(res_state);
uint16_t res_nametoclass(const char *, int *);
uint16_t res_nametotype(const char *, int *);
void res_setservers(res_state,
const union res_sockaddr_union *, int);
int res_getservers(res_state,
union res_sockaddr_union *, int);
int res_get_dns_changed();
u_int res_randomid(void);
__END_DECLS
#endif /* !_RESOLV_PRIVATE_H_ */

32
resolv_static.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef _RESOLV_STATIC_H
#define _RESOLV_STATIC_H
#include <netdb.h>
/* this structure contains all the variables that were declared
* 'static' in the original NetBSD resolver code.
*
* this caused vast amounts of crashes and memory corruptions
* when the resolver was being used by multiple threads.
*
* (note: the OpenBSD/FreeBSD resolver has similar 'issues')
*/
#define MAXALIASES 35
#define MAXADDRS 35
typedef struct res_static {
char* h_addr_ptrs[MAXADDRS + 1];
char* host_aliases[MAXALIASES];
char hostbuf[8*1024];
u_int32_t host_addr[16 / sizeof(u_int32_t)]; /* IPv4 or IPv6 */
FILE* hostf;
int stayopen;
const char* servent_ptr;
struct servent servent;
struct hostent host;
} *res_static;
extern res_static __res_get_static(void);
#endif /* _RESOLV_STATIC_H */

1113
rpc.c Normal file

File diff suppressed because it is too large Load Diff

178
rpc.h Normal file
View File

@ -0,0 +1,178 @@
#ifndef __rpc_h
#define __rpc_h
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include "types.h"
typedef struct {
BYTE VersionMajor;
BYTE VersionMinor;
BYTE PacketType;
BYTE PacketFlags;
DWORD DataRepresentation;
WORD FragLength;
WORD AuthLength;
DWORD CallId;
} /*__packed*/ RPC_HEADER;
typedef struct {
WORD MaxXmitFrag;
WORD MaxRecvFrag;
DWORD AssocGroup;
DWORD NumCtxItems;
struct {
WORD ContextId;
WORD NumTransItems;
GUID InterfaceUUID;
WORD InterfaceVerMajor;
WORD InterfaceVerMinor;
GUID TransferSyntax;
DWORD SyntaxVersion;
} CtxItems[1];
} /*__packed*/ RPC_BIND_REQUEST;
typedef struct {
WORD MaxXmitFrag;
WORD MaxRecvFrag;
DWORD AssocGroup;
WORD SecondaryAddressLength;
BYTE SecondaryAddress[6];
DWORD NumResults;
struct {
WORD AckResult;
WORD AckReason;
GUID TransferSyntax;
DWORD SyntaxVersion;
} Results[0];
} /*__packed*/ RPC_BIND_RESPONSE;
typedef struct {
DWORD AllocHint;
WORD ContextId;
WORD Opnum;
struct {
DWORD DataLength;
DWORD DataSizeIs;
} Ndr;
BYTE Data[0];
} /*__packed*/ RPC_REQUEST;
typedef struct {
DWORD AllocHint;
WORD ContextId;
BYTE CancelCount;
BYTE Pad1;
struct {
DWORD DataLength;
DWORD DataSizeIs1;
DWORD DataSizeIs2;
} Ndr;
BYTE Data[0];
} /*__packed*/ RPC_RESPONSE;
typedef struct {
DWORD AllocHint;
WORD ContextId;
WORD Opnum;
union {
struct {
DWORD DataLength;
DWORD DataSizeIs;
BYTE Data[0];
} Ndr;
struct {
uint64_t DataLength;
uint64_t DataSizeIs;
BYTE Data[0];
} Ndr64;
};
} /*__packed*/ RPC_REQUEST64;
typedef struct {
DWORD AllocHint;
WORD ContextId;
BYTE CancelCount;
BYTE Pad1;
union {
struct {
DWORD DataLength;
DWORD DataSizeMax;
union
{
DWORD DataSizeIs;
DWORD status;
};
BYTE Data[0];
} Ndr;
struct {
uint64_t DataLength;
uint64_t DataSizeMax;
union
{
uint64_t DataSizeIs;
DWORD status;
};
BYTE Data[0];
} Ndr64;
};
} /*__packed*/ RPC_RESPONSE64;
typedef SOCKET RpcCtx;
typedef int RpcStatus;
#define INVALID_NDR_CTX ((WORD)~0)
#define RPC_BIND_ACCEPT (0)
#define RPC_BIND_NACK (LE16(2))
#define RPC_BIND_ACK (LE16(3))
#define RPC_SYNTAX_UNSUPPORTED (LE16(2))
#define RPC_ABSTRACTSYNTAX_UNSUPPORTED (LE16(1))
#define RPC_BTFN_SEC_CONTEXT_MULTIPLEX (LE16(1))
#define RPC_BTFN_KEEP_ORPHAN (LE16(2))
#define INVALID_RPCCTX INVALID_SOCKET
#define closeRpc socketclose
#define RPC_PT_REQUEST 0
#define RPC_PT_RESPONSE 2
#define RPC_PT_BIND_REQ 11
#define RPC_PT_BIND_ACK 12
#define RPC_PT_ALTERCONTEXT_REQ 14
#define RPC_PT_ALTERCONTEXT_ACK 15
#define RPC_PF_FIRST 1
#define RPC_PF_LAST 2
#define RPC_PF_CANCEL_PENDING 4
#define RPC_PF_RESERVED 8
#define RPC_PF_MULTIPLEX 16
#define RPC_PF_NOT_EXEC 32
#define RPC_PF_MAYBE 64
#define RPC_PF_OBJECT 128
typedef union _RPC_FLAGS
{
DWORD mask;
struct {
uint32_t FlagsBTFN : 16;
BOOL HasNDR32 : 1;
BOOL HasNDR64 : 1;
BOOL HasBTFN : 1;
};
} RPC_FLAGS, *PRPC_FLAGS;
extern RPC_FLAGS RpcFlags;
void rpcServer(const RpcCtx socket, const DWORD RpcAssocGroup, const char* const ipstr);
RpcStatus rpcBindClient(const RpcCtx sock, const int_fast8_t verbose);
RpcStatus rpcSendRequest(const RpcCtx socket, const BYTE *const KmsRequest, const size_t requestSize, BYTE **KmsResponse, size_t *const responseSize);
#endif // __rpc_h

98
shared_globals.c Normal file
View File

@ -0,0 +1,98 @@
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include "shared_globals.h"
int global_argc, multi_argc = 0;
CARGV global_argv, multi_argv = NULL;
const char *const Version = VERSION;
DWORD VLActivationInterval = 60 * 2; // 2 hours
DWORD VLRenewalInterval = 60 * 24 * 7; // 7 days
int_fast8_t DisconnectImmediately = FALSE;
const char *const cIPv4 = "IPv4";
const char *const cIPv6 = "IPv6";
#ifndef USE_MSRPC
int_fast8_t UseMultiplexedRpc = TRUE;
int_fast8_t UseRpcNDR64 = TRUE;
int_fast8_t UseRpcBTFN = TRUE;
#endif // USE_MSRPC
#ifndef NO_SOCKETS
const char *defaultport = "1688";
#endif // NO_SOCKETS
KmsResponseParam_t KmsResponseParameters[MAX_KMSAPPS];
#if !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32)
int_fast8_t IsRestarted = FALSE;
#endif // !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32)
#if !defined(NO_TIMEOUT) && !__minix__
DWORD ServerTimeout = 30;
#endif // !defined(NO_TIMEOUT) && !__minix__
#if !defined(NO_LIMIT) && !defined (NO_SOCKETS) && !__minix__
#ifdef USE_MSRPC
uint32_t MaxTasks = RPC_C_LISTEN_MAX_CALLS_DEFAULT;
#else // !USE_MSRPC
uint32_t MaxTasks = SEM_VALUE_MAX;
#endif // !USE_MSRPC
#endif // !defined(NO_LIMIT) && !defined (NO_SOCKETS) && !__minix__
#ifndef NO_LOG
char *fn_log = NULL;
int_fast8_t logstdout = 0;
#ifndef NO_VERBOSE_LOG
int_fast8_t logverbose = 0;
#endif // NO_VERBOSE_LOG
#endif // NO_LOG
#ifndef NO_SOCKETS
int_fast8_t nodaemon = 0;
int_fast8_t InetdMode = 0;
#else
int_fast8_t nodaemon = 1;
int_fast8_t InetdMode = 1;
#endif
#ifndef NO_RANDOM_EPID
int_fast8_t RandomizationLevel = 1;
uint16_t Lcid = 0;
#endif
#ifndef NO_SOCKETS
SOCKET *SocketList;
int numsockets = 0;
#if !defined(NO_LIMIT) && !__minix__
#ifndef _WIN32 // Posix
sem_t *Semaphore;
#else // _WIN32
HANDLE Semaphore;
#endif // _WIN32
#endif // !defined(NO_LIMIT) && !__minix__
#endif // NO_SOCKETS
#ifdef _NTSERVICE
int_fast8_t IsNTService = TRUE;
int_fast8_t ServiceShutdown = FALSE;
#endif // _NTSERVICE
#ifndef NO_LOG
#ifdef USE_THREADS
#if !defined(_WIN32) && !defined(__CYGWIN__)
pthread_mutex_t logmutex = PTHREAD_MUTEX_INITIALIZER;
#else
CRITICAL_SECTION logmutex;
#endif // !defined(_WIN32) && !defined(__CYGWIN__)
#endif // USE_THREADS
#endif // NO_LOG

156
shared_globals.h Normal file
View File

@ -0,0 +1,156 @@
#ifndef INCLUDED_SHARED_GLOBALS_H
#define INCLUDED_SHARED_GLOBALS_H
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include <sys/types.h>
#ifndef _WIN32
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <pwd.h>
#include <grp.h>
#include <syslog.h>
#if (!defined(NO_LIMIT) || defined(USE_THREADS)) && !__minix__
#include <pthread.h>
#endif // (!defined(NO_LIMIT) || defined(USE_THREADS)) && !__minix__
#include <fcntl.h>
#include <sys/stat.h>
#if !defined(NO_LIMIT) && !__minix__
#include <semaphore.h>
#endif // !defined(NO_LIMIT) && !__minix__
#else
#ifndef USE_MSRPC
#include <winsock2.h>
#include <ws2tcpip.h>
#endif // USE_MSRPC
#include <windows.h>
#endif
#include <signal.h>
#include <unistd.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <limits.h>
#include <ctype.h>
#include <stdarg.h>
#include <semaphore.h>
#include "types.h"
#define MAX_KMSAPPS 3
typedef struct
{
const char* Epid;
const BYTE* HwId;
#ifndef NO_LOG
const char* EpidSource;
#endif // NO_LOG
} KmsResponseParam_t, *PKmsResponseParam_t;
#if !defined(NO_LIMIT) && !__minix__
#ifndef SEM_VALUE_MAX // Android does not define this
#ifdef __ANDROID__
#define SEM_VALUE_MAX 0x3fffffff
#elif !defined(_WIN32)
#define SEM_VALUE_MAX 0x7fffffff
#else
#define SEM_VALUE_MAX 0x7fff // Be cautious if unknown
#endif // __ANDROID__
#endif // !defined(SEM_VALUE_MAX)
#endif // !defined(NO_LIMIT) && !__minix__
extern const char *const Version;
//Fix for stupid eclipse parser
#ifndef UINT_MAX
#define UINT_MAX 4294967295
#endif
extern int global_argc, multi_argc;
extern CARGV global_argv, multi_argv;
extern int_fast8_t nodaemon;
extern DWORD VLActivationInterval;
extern DWORD VLRenewalInterval;
extern int_fast8_t DisconnectImmediately;
extern KmsResponseParam_t KmsResponseParameters[MAX_KMSAPPS];
extern const char *const cIPv4;
extern const char *const cIPv6;
extern int_fast8_t InetdMode;
#ifndef USE_MSRPC
extern int_fast8_t UseMultiplexedRpc;
extern int_fast8_t UseRpcNDR64;
extern int_fast8_t UseRpcBTFN;
#endif // USE_MSRPC
#ifndef NO_SOCKETS
extern const char *defaultport;
#endif // NO_SOCKETS
#if !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32)
extern int_fast8_t IsRestarted;
#endif // !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32)
#if !defined(NO_TIMEOUT) && !__minix__
extern DWORD ServerTimeout;
#endif // !defined(NO_TIMEOUT) && !__minix__
#if !defined(NO_LIMIT) && !defined (NO_SOCKETS) && !__minix__
extern uint32_t MaxTasks;
#endif // !defined(NO_LIMIT) && !defined (NO_SOCKETS) && !__minix__
#ifndef NO_LOG
extern char *fn_log;
extern int_fast8_t logstdout;
#ifndef NO_VERBOSE_LOG
extern int_fast8_t logverbose;
#endif
#endif
#ifndef NO_RANDOM_EPID
extern int_fast8_t RandomizationLevel;
extern uint16_t Lcid;
#endif
#if !defined(NO_SOCKETS) && !defined(USE_MSRPC)
extern SOCKET *SocketList;
extern int numsockets;
#if !defined(NO_LIMIT) && !__minix__
#ifndef _WIN32
extern sem_t *Semaphore;
#else // _WIN32
extern HANDLE Semaphore;
#endif // _WIN32
#endif // !defined(NO_LIMIT) && !__minix__
#endif // !defined(NO_SOCKETS) && !defined(USE_MSRPC)
#ifdef _NTSERVICE
extern int_fast8_t IsNTService;
extern int_fast8_t ServiceShutdown;
#endif
#ifndef NO_LOG
#ifdef USE_THREADS
#if !defined(_WIN32) && !defined(__CYGWIN__)
extern pthread_mutex_t logmutex;
#else
extern CRITICAL_SECTION logmutex;
#endif // _WIN32
#endif // USE_THREADS
#endif // NO_LOG
#endif // INCLUDED_SHARED_GLOBALS_H

266
types.h Normal file
View File

@ -0,0 +1,266 @@
#ifndef __types_h
#define __types_h
#ifndef CONFIG
#define CONFIG "config.h"
#endif // CONFIG
#include CONFIG
#include <stdlib.h>
#include <limits.h>
#include <stdint.h>
//#ifdef __sun__
//#include <alloca.h>
//#endif
#ifndef alloca
#ifdef __GNUC__
#define alloca(x) __builtin_alloca(x)
#endif // __GNUC__
#endif // alloca
#ifndef alloca
#if _MSC_VER
#define alloca _malloca
#endif // _MSC_VER
#endif // alloca
#ifndef alloca
#ifdef __has_builtin // clang feature test
#if __has_builtin(__builtin_alloca)
#define alloca(x) __builtin_alloca(x)
#endif // __has_builtin(__builtin_alloca)
#endif // __has_builtin
#endif // alloca
#ifndef alloca
#include <alloca.h>
#endif
#ifndef __packed
#if _MSC_VER
#define __packed
#else // !_MSC_VER
#define __packed __attribute__((packed))
#endif // !_MSC_VER
#endif
#ifndef __pure
#define __pure __attribute__((pure))
#endif
#ifndef __noreturn
#define __noreturn __attribute__((noreturn))
#endif
#define restrict __restrict
typedef struct __packed
{
uint16_t val[0];
} PACKED16;
typedef struct __packed
{
uint32_t val[0];
} PACKED32;
typedef struct __packed
{
uint64_t val[0];
} PACKED64;
// Extend this type to 16 or 32 bits if more than 254 products appear
typedef uint8_t ProdListIndex_t;
// Deal with Mingw32-w64 C++ header which defines a _countof that is incompatible with vlmcsd
#define vlmcsd_countof(x) ( sizeof(x) / sizeof(x[0]) )
// PATH_MAX is optional in Posix. We use a default of 260 here
#ifndef PATH_MAX
#ifdef _WIN32
#define PATH_MAX MAX_PATH
#else
#define PATH_MAX 260
#endif // _WIN32
#endif // !PATH_MAX
#if PATH_MAX > 260
#define VLMCSD_PATH_MAX 260
#else
#define VLMCSD_PATH_MAX PATH_MAX
#endif
// Synchronization Objects
// Mutexes
#ifdef USE_THREADS
#if !defined(_WIN32) && !defined(__CYGWIN__)
#define lock_mutex(x) pthread_mutex_lock(x)
#define unlock_mutex(x) pthread_mutex_unlock(x)
#else
#define lock_mutex(x) EnterCriticalSection(x)
#define unlock_mutex(x) LeaveCriticalSection(x)
#endif
#else // !USE_THREADS
//defines to nothing
#define lock_mutex(x)
#define unlock_mutex(x)
#endif // !USE_THREADS
// Semaphores
#ifndef _WIN32
#define semaphore_wait(x) sem_wait(x)
#define semaphore_post(x) sem_post(x)
#else // _WIN32
#define semaphore_wait(x) WaitForSingleObject(x, INFINITE)
#define semaphore_post(x) ReleaseSemaphore(x, 1, NULL)
#endif // _WIN32
// Stupid MingW just uses rand() from msvcrt.dll which uses RAND_MAX of 0x7fff
#if RAND_MAX < 0x7fffffff
#define rand32(x) ((uint32_t)((rand(x) << 17) | (rand(x) << 2) | (rand(x) & 3)))
#elif RAND_MAX < 0xffffffff
#define rand32(x) ((uint32_t)((rand(x) << 1) | (rand(x) & 1)))
#else
#define rand32(x) (uint32_t)rand(x)
#endif
#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(NO_SOCKETS)
#define _NTSERVICE
#endif
#if (defined(__CYGWIN__) || defined(_WIN32) || defined(NO_SOCKETS)) && !defined(NO_SIGHUP)
#define NO_SIGHUP
#endif // (defined(__CYGWIN__) || defined(_WIN32) || defined(NO_SOCKETS)) && !defined(NO_SIGHUP)
#ifdef _WIN32
#ifndef USE_THREADS
#define USE_THREADS
#endif
#endif
#if defined(USE_THREADS)
#define _TLS __thread
#else
#define _TLS
#endif
#define GUID_STRING_LENGTH 36
#if defined(_WIN32)
#ifndef USE_MSRPC
#include <winsock2.h>
#include <ws2tcpip.h>
#endif // USE_MSRPC
#include <windows.h>
typedef char* sockopt_t;
// Map VLMCSD error codes to WSAGetLastError() codes
// Add more if you need them
#define VLMCSD_EADDRINUSE WSAEADDRINUSE
#define VLMCSD_ENODEV WSAENODEV
#define VLMCSD_EADDRNOTAVAIL WSAEADDRNOTAVAIL
#define VLMCSD_EACCES WSAEACCES
#define VLMCSD_EINVAL WSAEINVAL
#define VLMCSD_ENOTSOCK WSAENOTSOCK
#define VLMCSD_EINTR WSAEINTR
#define VLMCSD_EINPROGRESS WSAEINPROGRESS
#define VLMCSD_ECONNABORTED WSAECONNABORTED
#define socket_errno WSAGetLastError()
#define socketclose(x) (closesocket(x))
#define vlmcsd_strerror(x) win_strerror(x)
#define VLMCSD_SHUT_RD SD_RECEIVE
#define VLMCSD_SHUT_WR SD_SEND
#define VLMCSD_SHUT_RDWR SD_BOTH
/* Unknown Winsock error codes */
#define WSAENODEV -1
#elif defined(__CYGWIN__)
#include <windows.h>
// Resolve conflicts between OpenSSL and MS Crypto API
#ifdef _CRYPTO_OPENSSL
#undef OCSP_RESPONSE
#undef X509_NAME
#endif
#else
typedef uint32_t DWORD;
typedef uint16_t WORD;
typedef uint8_t BYTE;
typedef uint16_t WCHAR;
typedef int BOOL;
#define FALSE 0
#define TRUE !0
typedef struct {
DWORD Data1;
WORD Data2;
WORD Data3;
BYTE Data4[8];
} /*__packed*/ GUID;
typedef struct {
DWORD dwLowDateTime;
DWORD dwHighDateTime;
} /*__packed*/ FILETIME;
#endif // defined(__CYGWIN__)
#ifndef _WIN32
// Map VLMCSD error codes to POSIX codes
// Add more if you need them
#define VLMCSD_EADDRINUSE EADDRINUSE
#define VLMCSD_ENODEV ENODEV
#define VLMCSD_EADDRNOTAVAIL EADDRNOTAVAIL
#define VLMCSD_EACCES EACCES
#define VLMCSD_EINVAL EINVAL
#define VLMCSD_ENOTSOCK ENOTSOCK
#define VLMCSD_EINTR EINTR
#define VLMCSD_EINPROGRESS EINPROGRESS
#define VLMCSD_ECONNABORTED ECONNABORTED
typedef void* sockopt_t;
#define _countof(x) ( sizeof(x) / sizeof(x[0]) )
#define SOCKET int
#define INVALID_SOCKET -1
#define socket_errno errno
#define socketclose(x) (close(x))
#define vlmcsd_strerror strerror
#define VLMCSD_SHUT_RD SHUT_RD
#define VLMCSD_SHUT_WR SHUT_WR
#define VLMCSD_SHUT_RDWR SHUT_RDWR
#endif // __MINGW__
#define INVALID_UID ((uid_t)~0)
#define INVALID_GID ((gid_t)~0)
#undef IsEqualGUID
#define IsEqualGUID(a, b) ( !memcmp(a, b, sizeof(GUID)) )
#ifndef __stdcall
#define __stdcall
#endif
#ifndef __cdecl
#define __cdecl
#endif
typedef const char *const * CARGV;
typedef struct {
SOCKET socket;
DWORD RpcAssocGroup;
} CLDATA, *const PCLDATA;
#endif // __types_h

255
vlmcs.1 Normal file
View File

@ -0,0 +1,255 @@
.mso www.tmac
.TH VLMCS 1 "February 2015" "Hotbird64" "KMS Activation Manual"
.LO 1
.SH NAME
vlmcs \- a client for testing and/or charging KMS servers
.SH SYNOPSIS
\fBvlmcs\fR [ \fIoptions\fR ] [ \fItarget\fR ] [ \fIoptions\fR ]
.PP
\fItarget\fR can be one of the following:
.RS
.PP
\fIhostname\fR|\fIipaddress\fR[:\fItcp-port\fR] or to query a specific KMS server (example: vlmcs kms.example.com:1688).
.br
\fR.\fIdomain\fR to automatically detect KMS servers via DNS for \fIdomain\fR (example: vlmcs .example.com). Please note the dot before \fIdomain\fR.
.br
\fI-\fR (a single dash) to detect KMS servers in your own domain.
.RE
If you use \fIipaddress\fR:\fIport\fR as the \fItarget\fR, the \fIipaddress\fR must be enclosed in brackets
if it contains colons, e.g. [2001:db8:dead:beef::1]:1688. If you use a link-local IPv6 address on Unix systems, you must append a percent sign and the
interface identifier of the source interface, for example fe80::dead:beef%eth0.
.PP
If you omit the \fItarget\fR, 127.0.0.1:1688 will be used except if you use \fB-i6\fR. In this case the default target is [::1]:1688.
.SH DESCRIPTION
\fBvlmcs\fR is a program that can be used to test a KMS server that provides activation for
several Microsoft products. The KMS server may also be an emulator. It supports
KMS protocol versions 4, 5 and 6.
.PP
.B vlmcs
generates one or more activation requests for a Microsoft KMS product and sends
it to a KMS server. It then analyzes and displays the responses of the KMS server.
.PP
.B vlcms
checks both the DCE-RPC protocol and the activation message for correctness and
reports any errors that it finds.
.PP
.B vlmcs
can also be used to "charge" a KMS server. A Microsoft KMS server sends correct activation messages only if it detects a certain minimum of clients (25 for Windows client OSses, 5 otherwise) on the network. This is Microsoft's futile attempt to prevent running a KMS server in a home environment.
.SH OPTIONS
.IP "\fB-h\fR or \fB-?"
Show help.
.IP \fB-x
Show valid
.IR application s
that can be used with
.BR "-l" "."
.IP \fB-e
Show some examples how to use vlmcs correctly.
.IP \fB-v
Be verbose. Instead of just displaying the returned ePID and the HwId
(protocol v6 only) vlmcsd shows all details of the query and the response.
.IP "\fB-l\fR \fIapplication"
Request activation for a specific
.IR "application" "."
Valid applications can be displayed by using
.BR "-x" "."
The default
.IR application " is"
.IR "Windows Vista Business" "."
The list of available applications is not complete. You may
supply GUIDs with
.BR "-a" ", " "-k" " and " "-s"
to specify applications that are not listed with \fB-x\fR. The
.B -l
option is used as a shortcut for the most common applications.
.IP "\fB-4\fR, \fB-5\fR and \fB-6"
Force version 4, 5 or 6 of the KMS protocol. The default is to select a suitable
version according to the
.IR "application"
selected. Plese note that some products (e.g. Office 2013) may use different protocols with different versions of Windows.
.IP "\fB-m"
Let the client pretend to be a virtual machine. Early versions of Microsoft's
KMS server did not increase the client count if the request came from a virtual
machine. Newer versions ignore this flag.
.IP "\fB-d"
Use NetBIOS names instead of DNS names. By default vlmcsd generates some random
DNS names for each request. If you prefer NetBIOS names, you may use
.IR "\fB-d" "."
A real Microsoft activation client uses DNS names or NetBIOS depending on the
client name configuration. KMS servers treat the workstation name as a comment
that affects logging only. Clients will be identified by a GUID that can
be specified using \fB-c\fR. \fB-d\fR has no effect if you also specify \fB-w\fR.
.IP "\fB-a\fR \fIapplication-guid"
Send requests with a specific
.IR "application-guid" "."
There are currently only three known valid
.IR "application-guid" "s:"
.IP
55c92734-d682-4d71-983e-d6ec3f16059f (Windows)
.br
59a52881-a989-479d-af46-f275c6370663 (Office 2010)
.br
0ff1ce15-a989-479d-af46-f275c6370663 (Office 2013)
.IP
A Microsoft KMS server uses these GUIDs to have seperate counters for the
already activated clients. A client that does not contact the KMS server
within 30 days will be deleted from the database. Emulated KMS servers
are always fully charged.
.IP "\fB-k\fR \fIkms-guid\fR"
Send requests with a specific
.IR "kms-guid" "."
A Microsoft KMS server uses these GUIDs as a product id to decide whether to
grant activation or not. A list of current \fIkms-guid\fRs can be found in
kms.c (table KmsIdList). Emulated KMS servers grant activation unconditionally
and do not check the \fIkms-guid\fR.
.IP "\fB-s\fR \fIactivation-guid\fR"
The \fIactivation-guid\fR defines the actual product, e.g. "Windows 8.1 Professional WMC KMSCLIENT edition". A \fIactivation-guid\fR maps 1:1 to a product key.
However, neither a Microsoft KMS server nor emulated servers check this id.
The \fIactivation-guid\fR is useful in logging to get a specific product description like
"Windows 8.1 Professional WMC". A list of current \fIactivation-guid\fRs can be found in
kms.c (table ExtendedProductList).
.IP "\fB-n\fR \fIrequests"
Send
.I requests
requests to the server. The default is to send at least one request and enough
subsequent requests that the server is fully charged afterwards for
the \fIapplication\-guid\fR you selected (explicitly with
.BR "-a" " or implicitly by using " "-l" ")."
.IP "\fB-T"
Causes to use a new TCP connection for each request if multiple requests
are sent with vlmcsd. This is useful when you want to test an emulated KMS
server whether it suffers from memory leaks. To test for memory leaks use
.B -n
with a large number of requests (> 100000) and then test twice (with and
without
.BR "-T" ")."
This option may become neccessary for future versions of Microsoft's KMS
server because multiple requests with different
.IR clients-guid s
for the same
.I kms-id-guid
are impossible in a real KMS szenario over the same TCP connection.
.IP "\fB-c\fR \fIclient-machine-guid\fR"
Normally vlmcs generates a random \fIclient-machine-guid\fR for each request. By using this option you can specify a fixed \fIclient-machine-guid\fR
This causes a Microsoft KMS not to increment its client count because it
receives multiple requests for the same client. Thus do not use
.BR "-c"
if you want to charge a real KMS server.
.IP "\fB-o\fR \fIprevious-client-machine-guid\fR"
If the \fIclient-machine-guid\fR changes for some reason, the real KMS client stores a \fIprevious-client-machine-guid\fR which is sent
to the KMS server. This happens rarely and usually 00000000-0000-0000-0000-000000000000 is used. You can use \fB-o\fR to specify a different
\fIprevious-client-machine-guid\fR.
.IP "\fB-G\fR \fIfilename\fR"
Grabs ePIDs and HWIDs from a KMS server and writes the information to \fIfilename\fR
in format suitable to be used as a configuration file (aka ini file) for \fBvlmcsd\fR(8).
This is especially useful if you have access to a genuine KMS server and want to use
the same data with \fBvlmcsd\fR(8).
If \fIfilename\fR does not exist, it will be created.
If you specify an existing \fIfilename\fR, it will be updated to use the information
received from the remote KMS server and a backup \fIfilename\fR~ will be created.
\fB-G\fR cannot be used with \fB-l\fR, \fB-4\fR, \fB-5\fR, \fB-6\fR, \fB-a\fR, \fB-s\fR, \fB-k\fR, \fB-r\fR and \fB-n\fR
.IP "\fB-w\fR \fIworkstation-name"
Send requests with a specific
.IR "workstation-name" "."
This disables the random generator for the workstation name. Since it is
a comment only, this option does not have much effect.
.IP "\fB-r\fR \fIrequired-client-count"
Also known as the "N count policy". Tells the KMS server that successful activation requires
\fIrequired-client-count\fR clients. The default is the
\fIrequired-client-count\fR that the product would need if the request
was a real activation. A Microsoft KMS server counts clients
up to the double amount what was specified with \fB-r\fR. This option
can be used to "overcharge" a Microsoft KMS server.
.IP "\fB\-t\ \fIstatus\fR"
Reports a specific license status to the KMS server. \fIstatus\fR is a number
that can be from 0 to 6. 0=unlicensed, 1=licensed, 2=OOB grace, 3=OOT grace,
4=Non-genuinue grace, 5=notification, 6=extended grace. Refer to
.URL "http://technet.microsoft.com/en-us/library/ff686879.aspx#_Toc257201371" "TechNet" ""
for more information. A Microsoft KMS server collects this information for
statistics only.
.IP "\fB-g\fR \fIbinding-expiration\fR"
This tells the KMS server how long a client will stay in its current license
status. This can be the remaining OOB time (the grace peroid that is granted between installation of a product and when activation is actuall required) or
the remaining time when KMS activation must be renewed.
\fIbinding-expiration\fR is specified in minutes. A Microsoft KMS server
apparantly does not use this information.
.IP "\fB-i \fIprotocol-version\fR"
Force the use of Internet protocol \fIprotocol-version\fR. Allowed values are 4 (IPv4) and 6 (IPv6). This option is useful only if you specfiy a \fIhostname\fR and not an
\fIip-address\fR on the command line.
.IP "\fB-p\fR"
Do not set the RPC_PF_MULTIPLEX flag in the RPC bind request. This can be used to test if the KMS server uses the same setting of this flag in the RPC bind respone. Some KMS
emulators don't set this correctly.
.IP "\fB-N0\fR and \fB-N1\fR"
Disables (\fB-N0\fR) or enables (\fB-N1\fR) the NDR64 transfer syntax in the RPC protocol. Disable NDR64 only in case of problems. If NDR64 is not used, vlmcs cannot detect many RPC protocol errors in KMS emulators. If you want to test whether a KMS emulator fully supports NDR64, you must use the \fB-n\fR option to send at least two requests. This is because Microsoft's client always sends the first request using NDR32 syntax and subsequent requests using NDR64 syntax.
.IP "\fB-B0\fR and \fB-B1\fR"
Disables (\fB-B0\fR) or enables (\fB-B1\fR) bind time feature negotiation (BTFN) in the RPC protocol. Disable BTFN only in case of problems. If BTFN is not used, vlmcs cannot detect many RPC protocol errors in KMS emulators.
.PP
Options that do not require an argument can be specified together with a single
dash, e.g. vlmcs -6mvT. If you specify an option more than once, the last occurence
will be in effect.
.SH FILES
.IP "\fBvlmcsd.ini\fR(5)"
.SH EXAMPLES
.IP "\fBvlmcs kms.example.com"
Request activation for Windows Vista using v4 protocol from kms.example.com.
Repeat activation requests until server is charged for all Windows products.
.IP "\fBvlmcs -"
Request activation for Windows Vista using v4 protocol from a KMS server that is published via DNS for the current domain.
.IP "\fBvlmcs .example.com"
Request activation for Windows Vista using v4 protocol from a KMS server that is published via DNS for domain example.com.
.IP "\fBvlmcs -6 -l Office2013 -v -n 1"
Request exactly one activation for Office2013 using v6 protocol from
localhost. Display verbose results.
.IP "\fBvlmcs kms.bigcompany.com -G /etc/vlmcsd.ini"
Get ePIDs and HWIDs from kms.bigcompany.com and create/update /etc/vlmcsd.ini accordingly.
.SH BUGS
Some platforms (e.g. Solaris) may have a \fBman\fR(7) system that does not handle URLs. URLs may be omitted in the documentation on those platforms. Cygwin, Linux, FreeBSD and Mac OS X are known to work correctly.
.SH AUTHOR
Written by Hotbird64
.SH CREDITS
Thanks to CODYQX4, crony12, deagles, DougQaid, eIcn, mikmik38, nosferati87, qad, Ratiborus, vityan666, ...
.SH SEE ALSO
\fBvlmcsd\fR(7), \fBvlmcsd\fR(8), \fBvlmcsdmulti\fR(1)

Some files were not shown because too many files have changed in this diff Show More