├── crates ├── vlmgr │ ├── src │ │ └── main.rs │ └── Cargo.toml ├── kms │ ├── Cargo.toml │ └── src │ │ └── lib.rs └── kms-sys │ ├── Cargo.toml │ ├── src │ ├── kmsdata.h │ ├── vlmcs.h │ ├── output.h │ ├── crypto_internal.h │ ├── network.h │ ├── libkms.h │ ├── crypto.h │ ├── helpers.h │ ├── dns_srv.h │ ├── shared_globals.c │ ├── endian.c │ ├── libkms.c │ ├── crypto_internal.c │ ├── shared_globals.h │ ├── endian.h │ ├── rpc.h │ ├── types.h │ ├── crypto.c │ ├── kms.h │ ├── output.c │ ├── config.h │ ├── helpers.c │ └── network.c │ ├── .gitignore │ ├── README.md │ └── build.rs ├── Cargo.toml ├── README.md ├── .github ├── workflows │ └── build.yaml └── dependabot.yaml ├── .editorconfig ├── .gitignore └── LICENSE /crates/vlmgr/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("Hello, world!"); 3 | } 4 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = ["crates/kms", "crates/kms-sys", "crates/vlmgr"] 3 | resolver = "2" 4 | -------------------------------------------------------------------------------- /crates/vlmgr/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "vlmgr" 3 | version = "0.0.1" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | kms = { path = "../kms" } 8 | -------------------------------------------------------------------------------- /crates/kms/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "kms" 3 | version = "0.0.1" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | kms-sys = { path = "../kms-sys" } 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vlemu 2 | 3 | [![Build](https://github.com/mogeko/vlemu/actions/workflows/build.yaml/badge.svg)](https://github.com/mogeko/vlemu/actions/workflows/build.yaml) 4 | 5 | Volume Licensing Emulator. 6 | -------------------------------------------------------------------------------- /crates/kms-sys/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "kms-sys" 3 | build = "build.rs" 4 | links = "kms" 5 | version = "0.0.1" 6 | edition = "2021" 7 | categories = ["external-ffi-bindings"] 8 | 9 | [lib] 10 | path = "bindings.rs" 11 | 12 | [lints.rust] 13 | non_upper_case_globals = "allow" 14 | non_snake_case = "allow" 15 | non_camel_case_types = "allow" 16 | 17 | 18 | [build-dependencies] 19 | cc = "1.1.37" 20 | -------------------------------------------------------------------------------- /.github/workflows/build.yaml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | pull_request: 6 | branches: ["master"] 7 | 8 | env: 9 | CARGO_TERM_COLOR: always 10 | CC: clang 11 | 12 | jobs: 13 | build: 14 | name: Run build and tests 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v4.2.2 18 | - run: cargo build --verbose 19 | - run: cargo test --verbose 20 | -------------------------------------------------------------------------------- /crates/kms-sys/src/kmsdata.h: -------------------------------------------------------------------------------- 1 | #ifndef KMSDATA_SERVER_H 2 | #define KMSDATA_SERVER_H 3 | 4 | #ifndef CONFIG 5 | #define CONFIG "config.h" 6 | #endif // CONFIG 7 | #include CONFIG 8 | 9 | #ifndef NO_INTERNAL_DATA 10 | 11 | #include "types.h" 12 | 13 | extern uint8_t DefaultKmsData[]; 14 | __pure size_t getDefaultKmsDataSize(); 15 | 16 | #endif // NO_INTERNAL_DATA 17 | 18 | #endif // KMSDATA_SERVER_H 19 | 20 | -------------------------------------------------------------------------------- /crates/kms/src/lib.rs: -------------------------------------------------------------------------------- 1 | use kms_sys::GetEmulatorVersion; 2 | use std::ffi::CStr; 3 | 4 | pub fn get_libkms_version() -> &'static str { 5 | let c_buf = unsafe { GetEmulatorVersion() }; 6 | let c_str = unsafe { CStr::from_ptr(c_buf) }; 7 | 8 | c_str.to_str().unwrap() 9 | } 10 | 11 | #[cfg(test)] 12 | mod tests { 13 | use super::*; 14 | 15 | #[test] 16 | fn try_get_libkms_version() { 17 | get_libkms_version(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | indent_style = space 8 | indent_size = 4 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | 14 | [*.rs] 15 | max_line_length = 100 16 | 17 | [*.md] 18 | # double whitespace at end of line 19 | # denotes a line break in Markdown 20 | trim_trailing_whitespace = false 21 | 22 | [Makefile,GNUmakefile] 23 | indent_style = tab 24 | 25 | [*.{yaml,yml}] 26 | indent_size = 2 27 | -------------------------------------------------------------------------------- /.github/dependabot.yaml: -------------------------------------------------------------------------------- 1 | # Basic dependabot.yaml file with 2 | # minimum configuration for two package managers 3 | 4 | version: 2 5 | updates: 6 | # Enable version updates for Cargo 7 | - package-ecosystem: "cargo" 8 | directory: "/" 9 | schedule: 10 | interval: "weekly" 11 | open-pull-requests-limit: 5 12 | groups: 13 | rust-dependencies: 14 | patterns: ["*"] 15 | # Enable version updates for GitHub Actions 16 | - package-ecosystem: "github-actions" 17 | directory: "/" 18 | schedule: 19 | interval: "weekly" 20 | open-pull-requests-limit: 5 21 | groups: 22 | github-actions: 23 | patterns: ["*"] 24 | -------------------------------------------------------------------------------- /crates/kms-sys/.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | -------------------------------------------------------------------------------- /crates/kms-sys/src/vlmcs.h: -------------------------------------------------------------------------------- 1 | #ifndef VLMCS_H_ 2 | #define VLMCS_H_ 3 | 4 | #ifndef CONFIG 5 | #define CONFIG "config.h" 6 | #endif // CONFIG 7 | #include CONFIG 8 | 9 | #if !defined(USE_MSRPC) && defined(_WIN32) 10 | #include 11 | #endif // defined(USE_MSRPC) && defined(_WIN32) 12 | #include "types.h" 13 | #ifndef USE_MSRPC 14 | #include "rpc.h" 15 | #else // USE_MSRPC 16 | #include "msrpc-client.h" 17 | #endif // USE_MSRPC 18 | #include "kms.h" 19 | 20 | #if MULTI_CALL_BINARY < 1 21 | #define client_main main 22 | #else 23 | int client_main(int argc, CARGV argv); 24 | #endif 25 | 26 | int SendActivationRequest(const RpcCtx sock, RESPONSE *baseResponse, REQUEST *baseRequest, RESPONSE_RESULT *result, BYTE *const hwid); 27 | 28 | #endif /* VLMCS_H_ */ 29 | 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | debug/ 4 | target/ 5 | 6 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 7 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 8 | Cargo.lock 9 | 10 | # These are backup files generated by rustfmt 11 | **/*.rs.bk 12 | 13 | # MSVC Windows builds of rustc generate these, which store debugging information 14 | *.pdb 15 | 16 | # RustRover 17 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 18 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 19 | # and can be added to the global gitignore or merged into this file. For a more nuclear 20 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 21 | #.idea/ 22 | -------------------------------------------------------------------------------- /crates/kms-sys/src/output.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDED_OUTPUT_H 2 | #define INCLUDED_OUTPUT_H 3 | 4 | #ifndef CONFIG 5 | #define CONFIG "config.h" 6 | #endif // CONFIG 7 | #include CONFIG 8 | 9 | #include 10 | #include "types.h" 11 | #include "kms.h" 12 | 13 | typedef int (*PRINTFUNC)(const char *const fmt, ...); 14 | 15 | int printerrorf(const char *const fmt, ...); 16 | int errorout(const char* fmt, ...); 17 | void logRequestVerbose(REQUEST* Request, const PRINTFUNC p); 18 | void logResponseVerbose(const char *const ePID, const BYTE *const hwid, RESPONSE* response, const PRINTFUNC p); 19 | 20 | #ifndef NO_VERSION_INFORMATION 21 | void printPlatform(); 22 | void printCommonFlags(); 23 | void printServerFlags(); 24 | void printClientFlags(); 25 | #endif // NO_VERSION_INFORMATION 26 | 27 | #ifndef NO_LOG 28 | int logger(const char *const fmt, ...); 29 | #endif //NO_LOG 30 | 31 | void uuid2StringLE(const GUID *const guid, char *const string); 32 | 33 | //void copy_arguments(int argc, char **argv, char ***new_argv); 34 | //void destroy_arguments(int argc, char **argv); 35 | 36 | #endif // INCLUDED_OUTPUT_H 37 | -------------------------------------------------------------------------------- /crates/kms-sys/src/crypto_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef __crypto_internal_h 2 | #define __crypto_internal_h 3 | 4 | #if !defined(_CRYPTO_OPENSSL) && !defined(_CRYPTO_POLARSSL) && !defined(_CRYPTO_WINDOWS) 5 | 6 | #ifndef CONFIG 7 | #define CONFIG "config.h" 8 | #endif // CONFIG 9 | #include CONFIG 10 | 11 | #include "crypto.h" 12 | 13 | typedef struct { 14 | DWORD State[8]; 15 | BYTE Buffer[64]; 16 | unsigned int Len; 17 | } Sha256Ctx; 18 | 19 | typedef struct { 20 | Sha256Ctx ShaCtx; 21 | BYTE OPad[64]; 22 | } Sha256HmacCtx; 23 | 24 | void Sha256(BYTE *data, size_t len, BYTE *hash); 25 | int_fast8_t Sha256Hmac(BYTE* key, BYTE* restrict data, DWORD len, BYTE* restrict hmac); 26 | 27 | //void _Sha256HmacInit(Sha256HmacCtx *Ctx, BYTE *key, size_t klen); 28 | //void _Sha256HmacUpdate(Sha256HmacCtx *Ctx, BYTE *data, size_t len); 29 | //void _Sha256HmacFinish(Sha256HmacCtx *Ctx, BYTE *hmac); 30 | 31 | //#define Sha256HmacInit(c, k, l) ( _Sha256HmacInit(c, k, l), !0 ) 32 | //#define Sha256HmacUpdate(c, d, l) ( _Sha256HmacUpdate(c, d, l), !0 ) 33 | //#define Sha256HmacFinish(c, h) ( _Sha256HmacFinish(c, h), !0 ) 34 | 35 | 36 | #endif // !defined(_CRYPTO_OPENSSL) && !defined(_CRYPTO_POLARSSL) && !defined(_CRYPTO_WINDOWS) 37 | 38 | #endif // __crypto_internal_h 39 | -------------------------------------------------------------------------------- /crates/kms-sys/src/network.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDED_NETWORK_H 2 | #define INCLUDED_NETWORK_H 3 | 4 | #ifndef CONFIG 5 | #define CONFIG "config.h" 6 | #endif // CONFIG 7 | #include CONFIG 8 | 9 | #ifndef _GNU_SOURCE 10 | #define _GNU_SOURCE 11 | #endif 12 | 13 | #include "types.h" 14 | #include "output.h" 15 | 16 | #if _MSC_VER 17 | //typedef signed char int_fast8_t; 18 | //typedef unsigned char BYTE; 19 | //typedef UINT_PTR size_t; 20 | //typedef unsigned long DWORD; 21 | #define STDIN_FILENO 0 22 | #endif 23 | 24 | int_fast8_t sendrecv(SOCKET sock, BYTE *data, int len, int_fast8_t do_send); 25 | 26 | #define _recv(s, d, l) sendrecv(s, (BYTE *)d, l, 0) 27 | #define _send(s, d, l) sendrecv(s, (BYTE *)d, l, !0) 28 | 29 | #ifndef NO_SOCKETS 30 | 31 | void closeAllListeningSockets(); 32 | #ifdef SIMPLE_SOCKETS 33 | int listenOnAllAddresses(); 34 | #endif // SIMPLE_SOCKETS 35 | BOOL addListeningSocket(const char *const addr); 36 | __pure int_fast8_t checkProtocolStack(const int addressfamily); 37 | 38 | #if HAVE_GETIFADDR 39 | void getPrivateIPAddresses(int* numAddresses, char*** ipAddresses); 40 | #endif // HAVE_GETIFADDR 41 | 42 | #endif // NO_SOCKETS 43 | 44 | int runServer(); 45 | SOCKET connectToAddress(const char *const addr, const int AddressFamily, int_fast8_t showHostName); 46 | int_fast8_t isDisconnected(const SOCKET s); 47 | 48 | #endif // INCLUDED_NETWORK_H 49 | -------------------------------------------------------------------------------- /crates/kms-sys/src/libkms.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libkms.h 3 | */ 4 | 5 | #ifndef LIBKMS_H_ 6 | #define LIBKMS_H_ 7 | 8 | #include "types.h" 9 | #include "kms.h" 10 | #include "rpc.h" 11 | #include "vlmcs.h" 12 | 13 | #ifndef EXTERNC 14 | #ifdef __cplusplus 15 | #define EXTERNC EXTERN "C" 16 | #else 17 | #define EXTERNC 18 | #endif 19 | #endif 20 | 21 | EXTERNC __declspec(EXTERNAL) DWORD __cdecl SendKMSRequest(const SOCKET sock, RESPONSE* baseResponse, REQUEST* baseRequest, RESPONSE_RESULT* result, BYTE *hwid); 22 | EXTERNC __declspec(EXTERNAL) DWORD __cdecl StartKmsServer(const int port, RequestCallback_t requestCallback); 23 | EXTERNC __declspec(EXTERNAL) DWORD __cdecl StopKmsServer(); 24 | EXTERNC __declspec(EXTERNAL) int __cdecl GetLibKmsVersion(); 25 | EXTERNC __declspec(EXTERNAL) const char* const __cdecl GetEmulatorVersion(); 26 | EXTERNC __declspec(EXTERNAL) SOCKET __cdecl ConnectToServer(const char* host, const char* port, const int addressFamily); 27 | EXTERNC __declspec(EXTERNAL) char* __cdecl GetErrorMessage(); 28 | EXTERNC __declspec(EXTERNAL) void __cdecl CloseConnection(const SOCKET sock); 29 | EXTERNC __declspec(EXTERNAL) RpcStatus __cdecl BindRpc(const SOCKET sock, const int_fast8_t useMultiplexedRpc, const int_fast8_t useRpcNDR64, const int_fast8_t useRpcBTFN, PRpcDiag_t rpcDiag); 30 | EXTERNC __declspec(EXTERNAL) int_fast8_t __cdecl IsDisconnected(const SOCKET sock); 31 | //EXTERN_C __declspec(EXTERNAL) unsigned int __cdecl GetRandom32(); 32 | 33 | 34 | #endif /* LIBKMS_H_ */ 35 | -------------------------------------------------------------------------------- /crates/kms-sys/README.md: -------------------------------------------------------------------------------- 1 | # Rust libkms binding 2 | 3 | > [!CAUTION] 4 | > 5 | > This is a very low-level direct binding to a C library, what you may need is the [`kms`](https://github.com/mogeko/vlemu/blob/master/crates/kms) package. 6 | 7 | This library includes the Rust bindings for `libkms`, which is part of the [`vlmcsd`](https://www.upload.ee/files/11363713/vlmcsd-1113-2020-03-28-Hotbird64-source-only.7z.html) package. 8 | 9 | ## What is KMS? 10 | 11 | KMS is a way to activate Microsoft products that was designed for medium and large businesses. In a standard SOHO environment you enter a product key during installation and then activate your product over the Internet. This is done by sending a request to a server at `microsoft.com` which then either grants or refuses activation. 12 | 13 | By entering a special key called General Volume License Key (GVLK), a.k.a "KMS client key", the product no longer asks the Microsoft server for activation but a user-defined server (called the KMS server) which usually resides in a company's intranet. 14 | 15 | ## What is vlmcsd? 16 | 17 | > [!IMPORTANT] 18 | > 19 | > `vlmcsd` and this project are two independent projects, and we do not provide **ANY ENDORSEMENT** for `vlmcsd` or `libkms`. 20 | 21 | `vlmcsd` is an independent open source implementation of a KMS server that is available for everyone while Microsoft gives their KMS server only to corporations that signed a so called "Select contract". In addition vlmcsd never refuses activation while the Microsoft KMS server only activates the products the customer has paid for. 22 | -------------------------------------------------------------------------------- /crates/kms-sys/src/crypto.h: -------------------------------------------------------------------------------- 1 | #ifndef __crypto_h 2 | #define __crypto_h 3 | 4 | #ifndef CONFIG 5 | #define CONFIG "config.h" 6 | #endif // CONFIG 7 | #include CONFIG 8 | 9 | #include "types.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "endian.h" 15 | #include 16 | 17 | #define AES_KEY_BYTES (16) // 128 Bits 18 | #define AES_BLOCK_BYTES (16) 19 | #define AES_BLOCK_WORDS (AES_BLOCK_BYTES / sizeof(DWORD)) 20 | #define AES_KEY_DWORDS (AES_KEY_BYTES / sizeof(DWORD)) 21 | #define V4_KEY_BYTES (20) // 160 Bits 22 | 23 | #define ROR32(v, n) ( (v) << (32 - n) | (v) >> n ) 24 | 25 | void XorBlock(const BYTE *const in, const BYTE *out); 26 | 27 | void AesCmacV4(BYTE *data, size_t len, BYTE *hash); 28 | 29 | extern const BYTE AesKeyV5[]; 30 | extern const BYTE AesKeyV6[]; 31 | 32 | typedef struct { 33 | DWORD Key[48]; // Supports a maximum of 160 key bits! 34 | uint_fast8_t rounds; 35 | } AesCtx; 36 | 37 | void AesInitKey(AesCtx *Ctx, const BYTE *Key, int_fast8_t IsV6, int AesKeyBytes); 38 | void AesEncryptBlock(const AesCtx *const Ctx, BYTE *block); 39 | void AesDecryptBlock(const AesCtx *const Ctx, BYTE *block); 40 | void AesEncryptCbc(const AesCtx *const Ctx, BYTE *restrict iv, BYTE *restrict data, size_t *restrict len); 41 | void AesDecryptCbc(const AesCtx *const Ctx, BYTE *iv, BYTE *data, size_t len); 42 | void MixColumnsR(BYTE *restrict state); 43 | 44 | #if defined(_CRYPTO_OPENSSL) 45 | #include "crypto_openssl.h" 46 | 47 | #elif defined(_CRYPTO_POLARSSL) 48 | #include "crypto_polarssl.h" 49 | 50 | #elif defined(_CRYPTO_WINDOWS) 51 | #include "crypto_windows.h" 52 | 53 | #else 54 | #include "crypto_internal.h" 55 | 56 | #endif 57 | #endif // __crypto_h 58 | -------------------------------------------------------------------------------- /crates/kms-sys/src/helpers.h: -------------------------------------------------------------------------------- 1 | #ifndef HELPERS_H 2 | #define HELPERS_H 3 | 4 | #ifndef CONFIG 5 | #define CONFIG "config.h" 6 | #endif // CONFIG 7 | #include CONFIG 8 | 9 | #include 10 | #include "types.h" 11 | 12 | #if __ANDROID__ 13 | #include 14 | #endif // __ANDROID__ 15 | 16 | #define GUID_LE 0 17 | #define GUID_BE 1 18 | #define GUID_SWAP 2 19 | 20 | BOOL stringToInt(const char *const szValue, const unsigned int min, const unsigned int max, unsigned int *const value); 21 | unsigned int getOptionArgumentInt(const char o, const unsigned int min, const unsigned int max); 22 | void optReset(void); 23 | __pure DWORD timeSpanString2Seconds(const char *const restrict argument); 24 | #define timeSpanString2Minutes(x) (timeSpanString2Seconds(x) / 60) 25 | char* win_strerror(const int message); 26 | int ucs2_to_utf8_char (const WCHAR ucs2_le, char *utf8); 27 | size_t utf8_to_ucs2(WCHAR* const ucs2_le, const char* const utf8, const size_t maxucs2, const size_t maxutf8); 28 | WCHAR utf8_to_ucs2_char (const unsigned char * input, const unsigned char ** end_ptr); 29 | BOOL ucs2_to_utf8(const WCHAR* const ucs2_le, char* utf8, size_t maxucs2, size_t maxutf8); 30 | int_fast8_t string2UuidLE(const char *const restrict input, GUID *const restrict guid); 31 | void randomNumberInit(); 32 | void parseAddress(char *const addr, char** szHost, char** szPort); 33 | __noreturn void OutOfMemory(void); 34 | void* vlmcsd_malloc(size_t len); 35 | void hex2bin(BYTE *const bin, const char *hex, const size_t maxbin); 36 | void loadKmsData(); 37 | #if !defined(DATA_FILE) || !defined(NO_SIGHUP) 38 | void getExeName(); 39 | #endif // !defined(DATA_FILE) || !defined(NO_SIGHUP) 40 | __pure BOOL getArgumentBool(int_fast8_t *result, const char *const argument); 41 | char* vlmcsd_strdup(const char* src); 42 | 43 | #if defined(NO_SOCKETS) || IS_LIBRARY 44 | #define exitOnWarningLevel(x) 45 | #else // !NO_SOCKETS 46 | void exitOnWarningLevel(const int_fast8_t level); 47 | #endif // !NO_SOCKETS 48 | 49 | 50 | #if __ANDROID__ && !defined(USE_THREADS) // Bionic does not wrap these syscalls (intentionally because Google fears, developers don't know how to use it) 51 | int shmget(key_t key, size_t size, int shmflg); 52 | void *shmat(int shmid, const void *shmaddr, int shmflg); 53 | int shmdt(const void *shmaddr); 54 | int shmctl(int shmid, int cmd, /*struct shmid_ds*/void *buf); 55 | #endif // __ANDROID__ && !defined(USE_THREADS) 56 | 57 | #endif // HELPERS_H 58 | -------------------------------------------------------------------------------- /crates/kms-sys/build.rs: -------------------------------------------------------------------------------- 1 | extern crate cc; 2 | 3 | use std::path::PathBuf; 4 | use std::{env, fs}; 5 | 6 | fn main() { 7 | let mut cfg = cc::Build::new(); 8 | let target = env::var("TARGET").unwrap(); 9 | 10 | if target.contains("apples") { 11 | cfg.flag_if_supported("-Wno-deprecated-declarations"); 12 | } 13 | 14 | if target.contains("windows") { 15 | cfg.define("_WIN32", None); 16 | } 17 | 18 | let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap()); 19 | let version = env::var("CARGO_PKG_VERSION").unwrap(); 20 | 21 | cfg.include("./src") 22 | .define("CONFIG", "\"config.h\"") 23 | .define("VERSION", format!("\"{version}\"").as_str()) 24 | .define("IS_LIBRARY", "1") 25 | .define("SIMPLE_SOCKETS", None) 26 | .define("NO_TIMEOUT", None) 27 | .define("NO_SIGHUP", None) 28 | .define("NO_CL_PIDS", None) 29 | .define("NO_LOG", None) 30 | .define("NO_RANDOM_EPID", None) 31 | .define("NO_INI_FILE", None) 32 | .define("NO_HELP", None) 33 | .define("NO_CUSTOM_INTERVALS", None) 34 | .define("NO_PID_FILE", None) 35 | .define("NO_USER_SWITCH", None) 36 | .define("NO_VERBOSE_LOG", None) 37 | .define("NO_LIMIT", None) 38 | .define("NO_VERSION_INFORMATION", None) 39 | .define("NO_PRIVATE_IP_DETECT", None) 40 | .define("NO_STRICT_MODES", None) 41 | .define("NO_CLIENT_LIST", None) 42 | .define("NO_TAP", None) 43 | .flag_if_supported("-fno-strict-aliasing") 44 | .flag_if_supported("-fomit-frame-pointer") 45 | .flag_if_supported("-fvisibility=hidden") 46 | .flag_if_supported("-Wno-single-bit-bitfield-constant-conversion") 47 | .flag_if_supported("-Wno-unused-parameter") 48 | .flag_if_supported("-Wno-ignored-qualifiers") 49 | .flag_if_supported("-UNO_SOCKETS") 50 | .flag_if_supported("-USIMPLE_RPC") 51 | .flag_if_supported("-UUSE_MSRPC") 52 | .file("./src/crypto.c") 53 | .file("./src/crypto_internal.c") 54 | .file("./src/endian.c") 55 | .file("./src/helpers.c") 56 | .file("./src/kms.c") 57 | .file("./src/libkms.c") 58 | .file("./src/network.c") 59 | .file("./src/output.c") 60 | .file("./src/rpc.c") 61 | .file("./src/shared_globals.c") 62 | .file("./src/vlmcs.c") 63 | .out_dir(dst.join("lib")) 64 | .compile("kms"); 65 | 66 | let src = env::current_dir().unwrap().join("src"); 67 | let include = dst.join("include"); 68 | fs::create_dir_all(&include).unwrap(); 69 | fs::copy(src.join("libkms.h"), dst.join("include/libkms.h")).unwrap(); 70 | println!("cargo::rustc-link-search={}", dst.join("include").display()); 71 | println!("cargo::rustc-link-lib=static=kms"); 72 | } 73 | -------------------------------------------------------------------------------- /crates/kms-sys/src/dns_srv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * dns_srv.h 3 | * 4 | */ 5 | 6 | #ifndef DNS_SRV_H_ 7 | #define DNS_SRV_H_ 8 | #ifndef NO_DNS 9 | 10 | 11 | #include "types.h" 12 | 13 | typedef struct 14 | { 15 | uint32_t random_weight; 16 | uint16_t priority; 17 | uint16_t weight; 18 | char serverName[260]; 19 | } kms_server_dns_t, *kms_server_dns_ptr; 20 | 21 | typedef struct 22 | { 23 | uint16_t priority; 24 | uint16_t weight; 25 | uint16_t port; 26 | unsigned char name[1]; 27 | } dns_srv_record_t, *dns_srv_record_ptr; 28 | 29 | #if __OpenBSD__ 30 | typedef enum __ns_type { 31 | ns_t_invalid = 0, /*%< Cookie. */ 32 | ns_t_a = 1, /*%< Host address. */ 33 | ns_t_ns = 2, /*%< Authoritative server. */ 34 | ns_t_md = 3, /*%< Mail destination. */ 35 | ns_t_mf = 4, /*%< Mail forwarder. */ 36 | ns_t_cname = 5, /*%< Canonical name. */ 37 | ns_t_soa = 6, /*%< Start of authority zone. */ 38 | ns_t_mb = 7, /*%< Mailbox domain name. */ 39 | ns_t_mg = 8, /*%< Mail group member. */ 40 | ns_t_mr = 9, /*%< Mail rename name. */ 41 | ns_t_null = 10, /*%< Null resource record. */ 42 | ns_t_wks = 11, /*%< Well known service. */ 43 | ns_t_ptr = 12, /*%< Domain name pointer. */ 44 | ns_t_hinfo = 13, /*%< Host information. */ 45 | ns_t_minfo = 14, /*%< Mailbox information. */ 46 | ns_t_mx = 15, /*%< Mail routing information. */ 47 | ns_t_txt = 16, /*%< Text strings. */ 48 | ns_t_rp = 17, /*%< Responsible person. */ 49 | ns_t_afsdb = 18, /*%< AFS cell database. */ 50 | ns_t_x25 = 19, /*%< X_25 calling address. */ 51 | ns_t_isdn = 20, /*%< ISDN calling address. */ 52 | ns_t_rt = 21, /*%< Router. */ 53 | ns_t_nsap = 22, /*%< NSAP address. */ 54 | ns_t_nsap_ptr = 23, /*%< Reverse NSAP lookup (deprecated). */ 55 | ns_t_sig = 24, /*%< Security signature. */ 56 | ns_t_key = 25, /*%< Security key. */ 57 | ns_t_px = 26, /*%< X.400 mail mapping. */ 58 | ns_t_gpos = 27, /*%< Geographical position (withdrawn). */ 59 | ns_t_aaaa = 28, /*%< Ip6 Address. */ 60 | ns_t_loc = 29, /*%< Location Information. */ 61 | ns_t_nxt = 30, /*%< Next domain (security). */ 62 | ns_t_eid = 31, /*%< Endpoint identifier. */ 63 | ns_t_nimloc = 32, /*%< Nimrod Locator. */ 64 | ns_t_srv = 33, /*%< Server Selection. */ 65 | ns_t_atma = 34, /*%< ATM Address */ 66 | ns_t_naptr = 35, /*%< Naming Authority PoinTeR */ 67 | ns_t_kx = 36, /*%< Key Exchange */ 68 | ns_t_cert = 37, /*%< Certification record */ 69 | ns_t_a6 = 38, /*%< IPv6 address (deprecated, use ns_t_aaaa) */ 70 | ns_t_dname = 39, /*%< Non-terminal DNAME (for IPv6) */ 71 | ns_t_sink = 40, /*%< Kitchen sink (experimentatl) */ 72 | ns_t_opt = 41, /*%< EDNS0 option (meta-RR) */ 73 | ns_t_apl = 42, /*%< Address prefix list (RFC3123) */ 74 | ns_t_tkey = 249, /*%< Transaction key */ 75 | ns_t_tsig = 250, /*%< Transaction signature. */ 76 | ns_t_ixfr = 251, /*%< Incremental zone transfer. */ 77 | ns_t_axfr = 252, /*%< Transfer zone of authority. */ 78 | ns_t_mailb = 253, /*%< Transfer mailbox records. */ 79 | ns_t_maila = 254, /*%< Transfer mail agent records. */ 80 | ns_t_any = 255, /*%< Wildcard match. */ 81 | ns_t_zxfr = 256, /*%< BIND-specific, nonstandard. */ 82 | ns_t_max = 65536 83 | } ns_type; 84 | 85 | typedef enum __ns_class { 86 | ns_c_invalid = 0, /*%< Cookie. */ 87 | ns_c_in = 1, /*%< Internet. */ 88 | ns_c_2 = 2, /*%< unallocated/unsupported. */ 89 | ns_c_chaos = 3, /*%< MIT Chaos-net. */ 90 | ns_c_hs = 4, /*%< MIT Hesiod. */ 91 | /* Query class values which do not appear in resource records */ 92 | ns_c_none = 254, /*%< for prereq. sections in update requests */ 93 | ns_c_any = 255, /*%< Wildcard match. */ 94 | ns_c_max = 65536 95 | } ns_class; 96 | 97 | #endif 98 | 99 | int getKmsServerList(kms_server_dns_ptr** serverlist, const char *const restrict query); 100 | void sortSrvRecords(kms_server_dns_ptr* serverlist, const int answers); 101 | 102 | #endif // NO_DNS 103 | #endif /* DNS_SRV_H_ */ 104 | -------------------------------------------------------------------------------- /crates/kms-sys/src/shared_globals.c: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG 2 | #define CONFIG "config.h" 3 | #endif // CONFIG 4 | #include CONFIG 5 | 6 | #include "shared_globals.h" 7 | 8 | int global_argc, multi_argc = 0; 9 | CARGV global_argv, multi_argv = NULL; 10 | const char *const Version = VERSION; 11 | DWORD VLActivationInterval = 60 * 2; // 2 hours 12 | DWORD VLRenewalInterval = 60 * 24 * 7; // 7 days 13 | int_fast8_t DisconnectImmediately = FALSE; 14 | const char *const cIPv4 = "IPv4"; 15 | const char *const cIPv6 = "IPv6"; 16 | 17 | #ifdef IS_LIBRARY 18 | char ErrorMessage[MESSAGE_BUFFER_SIZE]; 19 | #endif // IS_LIBRARY 20 | 21 | #ifndef NO_STRICT_MODES 22 | uint32_t WhitelistingLevel = 0; 23 | int_fast8_t CheckClientTime = FALSE; 24 | #ifndef NO_CLIENT_LIST 25 | int_fast8_t MaintainClients = FALSE; 26 | int_fast8_t StartEmpty = FALSE; 27 | #endif // NO_CLIENT_LIST 28 | #endif // !NO_STRICT_MODES 29 | 30 | #ifndef USE_MSRPC 31 | int_fast8_t UseMultiplexedRpc = TRUE; 32 | #ifndef SIMPLE_RPC 33 | int_fast8_t UseServerRpcNDR64 = TRUE; 34 | int_fast8_t UseServerRpcBTFN = TRUE; 35 | #endif // !SIMPLE_RPC 36 | int_fast8_t UseClientRpcNDR64 = TRUE; 37 | int_fast8_t UseClientRpcBTFN = TRUE; 38 | #endif // USE_MSRPC 39 | 40 | #ifndef NO_SOCKETS 41 | char *defaultport = (char*)"1688"; 42 | #endif // NO_SOCKETS 43 | 44 | #if !defined(NO_PRIVATE_IP_DETECT) 45 | uint32_t PublicIPProtectionLevel = 0; 46 | #endif 47 | 48 | #if !defined(NO_RANDOM_EPID) || !defined(NO_CL_PIDS) || !defined(NO_INI_FILE) 49 | KmsResponseParam_t* KmsResponseParameters; 50 | #endif // !defined(NO_RANDOM_EPID) || !defined(NO_CL_PIDS) || !defined(NO_INI_FILE) 51 | 52 | #if !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32) 53 | int_fast8_t IsRestarted = FALSE; 54 | #endif // !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32) 55 | 56 | #if !defined(NO_TIMEOUT) && !__minix__ 57 | DWORD ServerTimeout = 30; 58 | #endif // !defined(NO_TIMEOUT) && !__minix__ 59 | 60 | #if !defined(NO_LIMIT) && !defined (NO_SOCKETS) && !__minix__ 61 | #ifdef USE_MSRPC 62 | uint32_t MaxTasks = RPC_C_LISTEN_MAX_CALLS_DEFAULT; 63 | #else // !USE_MSRPC 64 | uint32_t MaxTasks = SEM_VALUE_MAX; 65 | #endif // !USE_MSRPC 66 | #endif // !defined(NO_LIMIT) && !defined (NO_SOCKETS) && !__minix__ 67 | 68 | #ifndef NO_LOG 69 | int_fast8_t LogDateAndTime = TRUE; 70 | char *fn_log = NULL; 71 | int_fast8_t logstdout = 0; 72 | #ifndef NO_VERBOSE_LOG 73 | int_fast8_t logverbose = 0; 74 | #endif // NO_VERBOSE_LOG 75 | #endif // NO_LOG 76 | 77 | #ifndef NO_SOCKETS 78 | int_fast8_t ExitLevel = 0; 79 | 80 | #ifndef _WIN32 81 | int_fast8_t nodaemon = 0; 82 | #endif // _WIN32 83 | int_fast8_t InetdMode = 0; 84 | #else 85 | #ifndef _WIN32 86 | int_fast8_t nodaemon = 1; 87 | #endif // _WIN32 88 | int_fast8_t InetdMode = 1; 89 | #endif // NO_SOCKETS 90 | 91 | PVlmcsdHeader_t KmsData = NULL; 92 | #ifndef NO_EXTERNAL_DATA 93 | #ifndef DATA_FILE 94 | char *fn_data = NULL; 95 | #else // DATA_FILE 96 | char *fn_data = DATA_FILE; 97 | #endif // DATA_FILE 98 | #ifndef NO_INTERNAL_DATA 99 | int_fast8_t ExplicitDataLoad = FALSE; 100 | #endif // NO_INTERNAL_DATA 101 | #endif // NO_EXTERNAL_DATA 102 | const char *fn_exe = NULL; 103 | 104 | #ifndef NO_RANDOM_EPID 105 | int_fast8_t RandomizationLevel = 1; 106 | uint16_t Lcid = 0; 107 | uint16_t HostBuild = 0; 108 | #endif 109 | 110 | #if !defined(USE_MSRPC) && !defined(SIMPLE_RPC) 111 | uint8_t IsNDR64Defined = FALSE; 112 | #endif // !defined(USE_MSRPC) && !defined(SIMPLE_RPC) 113 | 114 | 115 | #if !defined(NO_SOCKETS) && !defined(USE_MSRPC) 116 | #ifdef SIMPLE_SOCKETS 117 | SOCKET s_server; 118 | #else 119 | SOCKET *SocketList; 120 | int numsockets = 0; 121 | #endif 122 | 123 | #if !defined(NO_LIMIT) && !__minix__ 124 | #ifndef _WIN32 // Posix 125 | sem_t *MaxTaskSemaphore; 126 | #else // _WIN32 127 | HANDLE MaxTaskSemaphore; 128 | #endif // _WIN32 129 | 130 | #endif // !defined(NO_LIMIT) && !__minix__ 131 | #endif // !defined(NO_SOCKETS) && !defined(USE_MSRPC) 132 | 133 | #ifdef _NTSERVICE 134 | int_fast8_t IsNTService = TRUE; 135 | int_fast8_t ServiceShutdown = FALSE; 136 | #endif // _NTSERVICE 137 | 138 | #ifndef NO_LOG 139 | #ifdef USE_THREADS 140 | #if !defined(_WIN32) && !defined(__CYGWIN__) 141 | pthread_mutex_t logmutex = PTHREAD_MUTEX_INITIALIZER; 142 | #else 143 | CRITICAL_SECTION logmutex; 144 | #endif // !defined(_WIN32) && !defined(__CYGWIN__) 145 | #endif // USE_THREADS 146 | #endif // NO_LOG 147 | 148 | #if HAVE_FREEBIND 149 | int_fast8_t freebind = FALSE; 150 | #endif // HAVE_FREEBIND 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /crates/kms-sys/src/endian.c: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG 2 | #define CONFIG "config.h" 3 | #endif // CONFIG 4 | #include CONFIG 5 | 6 | #include "endian.h" 7 | 8 | #if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) \ 9 | && defined(BS16) && defined(BS32) && defined(BS64) && !defined(NO_COMPILER_UAA) 10 | 11 | #else // ! defined(__BYTE_ORDER) 12 | 13 | void PUT_UAA64BE(void *p, unsigned long long v, unsigned int i) 14 | { 15 | unsigned char *_p = (unsigned char *)&((unsigned long long *)p)[i]; 16 | _p[ 0 ] = (unsigned char)(v >> 56); 17 | _p[ 1 ] = (unsigned char)(v >> 48); 18 | _p[ 2 ] = (unsigned char)(v >> 40); 19 | _p[ 3 ] = (unsigned char)(v >> 32); 20 | _p[ 4 ] = (unsigned char)(v >> 24); 21 | _p[ 5 ] = (unsigned char)(v >> 16); 22 | _p[ 6 ] = (unsigned char)(v >> 8); 23 | _p[ 7 ] = (unsigned char)(v); 24 | } 25 | 26 | void PUT_UAA32BE(void *p, unsigned int v, unsigned int i) 27 | { 28 | unsigned char *_p = (unsigned char *)&((unsigned int *)p)[i]; 29 | _p[ 0 ] = (unsigned char)(v >> 24); 30 | _p[ 1 ] = (unsigned char)(v >> 16); 31 | _p[ 2 ] = (unsigned char)(v >> 8); 32 | _p[ 3 ] = (unsigned char)(v); 33 | } 34 | 35 | void PUT_UAA16BE(void *p, unsigned short v, unsigned int i) 36 | { 37 | unsigned char *_p = (unsigned char *)&((unsigned short *)p)[i]; 38 | _p[ 0 ] = (unsigned char)(v >> 8); 39 | _p[ 1 ] = (unsigned char)(v); 40 | } 41 | 42 | 43 | void PUT_UAA64LE(void *p, unsigned long long v, unsigned int i) 44 | { 45 | unsigned char *_p = (unsigned char *)&((unsigned long long *)p)[i]; 46 | _p[ 0 ] = (unsigned char)(v); 47 | _p[ 1 ] = (unsigned char)(v >> 8); 48 | _p[ 2 ] = (unsigned char)(v >> 16); 49 | _p[ 3 ] = (unsigned char)(v >> 24); 50 | _p[ 4 ] = (unsigned char)(v >> 32); 51 | _p[ 5 ] = (unsigned char)(v >> 40); 52 | _p[ 6 ] = (unsigned char)(v >> 48); 53 | _p[ 7 ] = (unsigned char)(v >> 56); 54 | } 55 | 56 | void PUT_UAA32LE(void *p, unsigned int v, unsigned int i) 57 | { 58 | unsigned char *_p = (unsigned char *)&((unsigned int *)p)[i]; 59 | _p[ 0 ] = (unsigned char)(v); 60 | _p[ 1 ] = (unsigned char)(v >> 8); 61 | _p[ 2 ] = (unsigned char)(v >> 16); 62 | _p[ 3 ] = (unsigned char)(v >> 24); 63 | } 64 | 65 | void PUT_UAA16LE(void *p, unsigned short v, unsigned int i) 66 | { 67 | unsigned char *_p = (unsigned char *)&((unsigned short *)p)[i]; 68 | _p[ 0 ] = (unsigned char)(v); 69 | _p[ 1 ] = (unsigned char)(v >> 8); 70 | } 71 | 72 | 73 | unsigned long long GET_UAA64BE(void *p, unsigned int i) 74 | { 75 | unsigned char *_p = (unsigned char *)&((unsigned long long *)p)[i]; 76 | return 77 | (unsigned long long)_p[ 0 ] << 56 | 78 | (unsigned long long)_p[ 1 ] << 48 | 79 | (unsigned long long)_p[ 2 ] << 40 | 80 | (unsigned long long)_p[ 3 ] << 32 | 81 | (unsigned long long)_p[ 4 ] << 24 | 82 | (unsigned long long)_p[ 5 ] << 16 | 83 | (unsigned long long)_p[ 6 ] << 8 | 84 | (unsigned long long)_p[ 7 ]; 85 | 86 | } 87 | 88 | unsigned int GET_UAA32BE(void *p, unsigned int i) 89 | { 90 | unsigned char *_p = (unsigned char *)&((unsigned int *)p)[i]; 91 | return 92 | (unsigned int)_p[ 0 ] << 24 | 93 | (unsigned int)_p[ 1 ] << 16 | 94 | (unsigned int)_p[ 2 ] << 8 | 95 | (unsigned int)_p[ 3 ]; 96 | } 97 | 98 | unsigned short GET_UAA16BE(void *p, unsigned int i) 99 | { 100 | unsigned char *_p = (unsigned char *)&((unsigned short *)p)[i]; 101 | return 102 | (unsigned short)_p[ 0 ] << 8 | 103 | (unsigned short)_p[ 1 ]; 104 | } 105 | 106 | 107 | unsigned long long GET_UAA64LE(void *p, unsigned int i) 108 | { 109 | unsigned char *_p = (unsigned char *)&((unsigned long long *)p)[i]; 110 | return 111 | (unsigned long long)_p[ 0 ] | 112 | (unsigned long long)_p[ 1 ] << 8 | 113 | (unsigned long long)_p[ 2 ] << 16 | 114 | (unsigned long long)_p[ 3 ] << 24 | 115 | (unsigned long long)_p[ 4 ] << 32 | 116 | (unsigned long long)_p[ 5 ] << 40 | 117 | (unsigned long long)_p[ 6 ] << 48 | 118 | (unsigned long long)_p[ 7 ] << 56; 119 | 120 | } 121 | 122 | unsigned int GET_UAA32LE(void *p, unsigned int i) 123 | { 124 | unsigned char *_p = (unsigned char *)&((unsigned int *)p)[i]; 125 | return 126 | (unsigned int)_p[ 0 ] | 127 | (unsigned int)_p[ 1 ] << 8 | 128 | (unsigned int)_p[ 2 ] << 16 | 129 | (unsigned int)_p[ 3 ] << 24; 130 | } 131 | 132 | unsigned short GET_UAA16LE(void *p, unsigned int i) 133 | { 134 | unsigned char *_p = (unsigned char *)&((unsigned short *)p)[i]; 135 | return 136 | (unsigned short)_p[ 0 ] | 137 | (unsigned short)_p[ 1 ] << 8; 138 | } 139 | #endif 140 | 141 | 142 | #if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) \ 143 | && defined(BS16) && defined(BS32) && defined(BS64) 144 | #else 145 | unsigned short BE16(unsigned short x) 146 | { 147 | return GET_UAA16BE(&x, 0); 148 | } 149 | 150 | unsigned short LE16(unsigned short x) 151 | { 152 | return GET_UAA16LE(&x, 0); 153 | } 154 | 155 | unsigned int BE32(unsigned int x) 156 | { 157 | return GET_UAA32BE(&x, 0); 158 | } 159 | 160 | unsigned int LE32(unsigned int x) 161 | { 162 | return GET_UAA32LE(&x, 0); 163 | } 164 | 165 | unsigned long long BE64(unsigned long long x) 166 | { 167 | return GET_UAA64BE(&x, 0); 168 | } 169 | 170 | unsigned long long LE64(unsigned long long x) 171 | { 172 | return GET_UAA64LE(&x, 0); 173 | } 174 | 175 | #endif // defined(__BYTE_ORDER) 176 | -------------------------------------------------------------------------------- /crates/kms-sys/src/libkms.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libkms.c 3 | */ 4 | 5 | #ifndef CONFIG 6 | #define CONFIG "config.h" 7 | #endif // CONFIG 8 | #include CONFIG 9 | 10 | #ifdef EXTERNAL 11 | #undef EXTERNAL 12 | #endif 13 | 14 | #define EXTERNAL dllexport 15 | 16 | #define DLLVERSION 0x40000 17 | 18 | #include "libkms.h" 19 | #include "shared_globals.h" 20 | #include "network.h" 21 | #include "helpers.h" 22 | 23 | #ifndef _WIN32 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #endif // WIN32 30 | 31 | static int_fast8_t IsServerStarted = FALSE; 32 | 33 | #ifdef _WIN32 34 | #ifndef USE_MSRPC 35 | 36 | static int_fast8_t SocketsInitialized = FALSE; 37 | WSADATA wsadata; 38 | 39 | static int initializeWinSockets() 40 | { 41 | if (SocketsInitialized) return 0; 42 | SocketsInitialized = TRUE; 43 | return WSAStartup(0x0202, &wsadata); 44 | } 45 | 46 | #endif // USE_MSRPC 47 | #endif // _WIN32 48 | 49 | EXTERNC __declspec(EXTERNAL) char* __cdecl GetErrorMessage() 50 | { 51 | return ErrorMessage; 52 | } 53 | 54 | EXTERNC __declspec(EXTERNAL)SOCKET __cdecl ConnectToServer(const char* host, const char* port, const int addressFamily) 55 | { 56 | SOCKET sock; 57 | *ErrorMessage = 0; 58 | 59 | # if defined(_WIN32) && !defined(USE_MSRPC) 60 | initializeWinSockets(); 61 | # endif // defined(_WIN32) && !defined(USE_MSRPC) 62 | 63 | size_t adrlen = strlen(host) + 16; 64 | char* RemoteAddr = (char*)alloca(adrlen); 65 | vlmcsd_snprintf(RemoteAddr, adrlen, "[%s]:%s", host, port); 66 | sock = connectToAddress(RemoteAddr, addressFamily, FALSE); 67 | 68 | if (sock == INVALID_RPCCTX) 69 | { 70 | printerrorf("Fatal: Could not connect to %s\n", RemoteAddr); 71 | return sock; 72 | } 73 | 74 | return sock; 75 | } 76 | 77 | EXTERNC __declspec(EXTERNAL)RpcStatus __cdecl BindRpc(const SOCKET sock, const int_fast8_t useMultiplexedRpc, const int_fast8_t useRpcNDR64, const int_fast8_t useRpcBTFN, PRpcDiag_t rpcDiag) 78 | { 79 | *ErrorMessage = 0; 80 | UseMultiplexedRpc = useMultiplexedRpc; 81 | UseClientRpcNDR64 = useRpcNDR64; 82 | UseClientRpcBTFN = useRpcBTFN; 83 | return rpcBindClient(sock, FALSE, rpcDiag); 84 | } 85 | 86 | EXTERNC __declspec(EXTERNAL) void __cdecl CloseConnection(const SOCKET sock) 87 | { 88 | socketclose(sock); 89 | } 90 | 91 | 92 | EXTERNC __declspec(EXTERNAL)DWORD __cdecl SendKMSRequest(const SOCKET sock, RESPONSE* baseResponse, REQUEST* baseRequest, RESPONSE_RESULT* result, BYTE *hwid) 93 | { 94 | *ErrorMessage = 0; 95 | return SendActivationRequest(sock, baseResponse, baseRequest, result, hwid); 96 | } 97 | 98 | EXTERNC __declspec(EXTERNAL)int_fast8_t __cdecl IsDisconnected(const SOCKET sock) 99 | { 100 | return isDisconnected(sock); 101 | } 102 | 103 | 104 | EXTERNC __declspec(EXTERNAL)DWORD __cdecl StartKmsServer(const int port, RequestCallback_t requestCallback) 105 | { 106 | #ifndef SIMPLE_SOCKETS 107 | char listenAddress[64]; 108 | 109 | if (IsServerStarted) return SOCKET_EALREADY; 110 | 111 | # ifdef _WIN32 112 | int error = initializeWinSockets(); 113 | if (error) return error; 114 | # endif // _WIN32 115 | 116 | CreateResponseBase = requestCallback; 117 | 118 | int maxsockets = 0; 119 | int_fast8_t haveIPv4 = FALSE; 120 | int_fast8_t haveIPv6 = FALSE; 121 | 122 | if (checkProtocolStack(AF_INET)) { haveIPv4 = TRUE; maxsockets++; } 123 | if (checkProtocolStack(AF_INET6)) { haveIPv6 = TRUE; maxsockets++; } 124 | 125 | if (!maxsockets) return SOCKET_EAFNOSUPPORT; 126 | 127 | SocketList = (SOCKET*)vlmcsd_malloc(sizeof(SOCKET) * (size_t)maxsockets); 128 | numsockets = 0; 129 | 130 | if (haveIPv4) 131 | { 132 | snprintf(listenAddress, 64, "0.0.0.0:%u", (unsigned int)port); 133 | addListeningSocket(listenAddress); 134 | } 135 | 136 | if (haveIPv6) 137 | { 138 | snprintf(listenAddress, 64, "[::]:%u", (unsigned int)port); 139 | addListeningSocket(listenAddress); 140 | } 141 | 142 | if (!numsockets) 143 | { 144 | free(SocketList); 145 | return SOCKET_EADDRNOTAVAIL; 146 | } 147 | 148 | IsServerStarted = TRUE; 149 | 150 | runServer(); 151 | 152 | IsServerStarted = FALSE; 153 | return 0; 154 | 155 | # else // SIMPLE_SOCKETS 156 | 157 | if (IsServerStarted) return SOCKET_EALREADY; 158 | int error; 159 | 160 | # ifdef _WIN32 161 | error = initializeWinSockets(); 162 | if (error) return error; 163 | # endif // _WIN32 164 | 165 | defaultport = vlmcsd_malloc(16); 166 | vlmcsd_snprintf((char*)defaultport, (size_t)16, "%i", port); 167 | 168 | CreateResponseBase = requestCallback; 169 | error = listenOnAllAddresses(); 170 | free(defaultport); 171 | if (error) return error; 172 | 173 | IsServerStarted = TRUE; 174 | runServer(); 175 | IsServerStarted = FALSE; 176 | 177 | return 0; 178 | 179 | 180 | # endif // SIMPLE_SOCKETS 181 | } 182 | 183 | 184 | EXTERNC __declspec(EXTERNAL)DWORD __cdecl StopKmsServer() 185 | { 186 | if (!IsServerStarted) return VLMCSD_EPERM; 187 | 188 | closeAllListeningSockets(); 189 | 190 | # ifndef SIMPLE_SOCKETS 191 | if (SocketList) free(SocketList); 192 | # endif 193 | 194 | return 0; 195 | } 196 | 197 | 198 | EXTERNC __declspec(EXTERNAL) int __cdecl GetLibKmsVersion() 199 | { 200 | return DLLVERSION; 201 | } 202 | 203 | 204 | EXTERNC __declspec(EXTERNAL) const char* const __cdecl GetEmulatorVersion() 205 | { 206 | return VERSION; 207 | } 208 | 209 | -------------------------------------------------------------------------------- /crates/kms-sys/src/crypto_internal.c: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG 2 | #define CONFIG "config.h" 3 | #endif // CONFIG 4 | #include CONFIG 5 | 6 | #if !defined(_CRYPTO_OPENSSL) && !defined(_CRYPTO_POLARSSL) && !defined(_CRYPTO_WINDOWS) 7 | #include "crypto_internal.h" 8 | #include "endian.h" 9 | 10 | #define F0(x, y, z) ( ((x) & (y)) | (~(x) & (z)) ) 11 | #define F1(x, y, z) ( ((x) & (y)) | ((x) & (z)) | ((y) & (z)) ) 12 | 13 | #define SI1(x) ( ROR32(x, 2 ) ^ ROR32(x, 13) ^ ROR32(x, 22) ) 14 | #define SI2(x) ( ROR32(x, 6 ) ^ ROR32(x, 11) ^ ROR32(x, 25) ) 15 | #define SI3(x) ( ROR32(x, 7 ) ^ ROR32(x, 18) ^ ((x) >> 3 ) ) 16 | #define SI4(x) ( ROR32(x, 17) ^ ROR32(x, 19) ^ ((x) >> 10) ) 17 | 18 | static const DWORD k[] = { 19 | 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 20 | 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 21 | 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786, 22 | 0x0FC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 23 | 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 24 | 0x06CA6351, 0x14292967, 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 25 | 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B, 26 | 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 27 | 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 28 | 0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 29 | 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 30 | }; 31 | 32 | 33 | static void Sha256Init(Sha256Ctx *Ctx) 34 | { 35 | Ctx->State[0] = 0x6A09E667; 36 | Ctx->State[1] = 0xBB67AE85; 37 | Ctx->State[2] = 0x3C6EF372; 38 | Ctx->State[3] = 0xA54FF53A; 39 | Ctx->State[4] = 0x510E527F; 40 | Ctx->State[5] = 0x9B05688C; 41 | Ctx->State[6] = 0x1F83D9AB; 42 | Ctx->State[7] = 0x5BE0CD19; 43 | Ctx->Len = 0; 44 | } 45 | 46 | 47 | static void Sha256ProcessBlock(Sha256Ctx *Ctx, BYTE *block) 48 | { 49 | unsigned int i; 50 | DWORD w[64], temp1, temp2; 51 | DWORD a = Ctx->State[0]; 52 | DWORD b = Ctx->State[1]; 53 | DWORD c = Ctx->State[2]; 54 | DWORD d = Ctx->State[3]; 55 | DWORD e = Ctx->State[4]; 56 | DWORD f = Ctx->State[5]; 57 | DWORD g = Ctx->State[6]; 58 | DWORD h = Ctx->State[7]; 59 | 60 | for (i = 0; i < 16; i++) 61 | //w[ i ] = GET_UAA32BE(block, i); 62 | w[i] = BE32(((DWORD*)block)[i]); 63 | 64 | for (i = 16; i < 64; i++) 65 | w[ i ] = SI4(w[ i - 2 ]) + w[ i - 7 ] + SI3(w[ i - 15 ]) + w[ i - 16 ]; 66 | 67 | for (i = 0; i < 64; i++) 68 | { 69 | temp1 = h + SI2(e) + F0(e, f, g) + k[ i ] + w[ i ]; 70 | temp2 = SI1(a) + F1(a, b, c); 71 | 72 | h = g; 73 | g = f; 74 | f = e; 75 | e = d + temp1; 76 | d = c; 77 | c = b; 78 | b = a; 79 | a = temp1 + temp2; 80 | } 81 | 82 | Ctx->State[0] += a; 83 | Ctx->State[1] += b; 84 | Ctx->State[2] += c; 85 | Ctx->State[3] += d; 86 | Ctx->State[4] += e; 87 | Ctx->State[5] += f; 88 | Ctx->State[6] += g; 89 | Ctx->State[7] += h; 90 | } 91 | 92 | 93 | static void Sha256Update(Sha256Ctx *Ctx, BYTE *data, size_t len) 94 | { 95 | unsigned int b_len = Ctx->Len & 63, 96 | r_len = (b_len ^ 63) + 1; 97 | 98 | Ctx->Len += (unsigned int)len; 99 | 100 | if ( len < r_len ) 101 | { 102 | memcpy(Ctx->Buffer + b_len, data, len); 103 | return; 104 | } 105 | 106 | if ( r_len < 64 ) 107 | { 108 | memcpy(Ctx->Buffer + b_len, data, r_len); 109 | len -= r_len; 110 | data += r_len; 111 | Sha256ProcessBlock(Ctx, Ctx->Buffer); 112 | } 113 | 114 | for (; len >= 64; len -= 64, data += 64) 115 | Sha256ProcessBlock(Ctx, data); 116 | 117 | if ( len ) memcpy(Ctx->Buffer, data, len); 118 | } 119 | 120 | 121 | static void Sha256Finish(Sha256Ctx *Ctx, BYTE *hash) 122 | { 123 | unsigned int i, b_len = Ctx->Len & 63; 124 | 125 | Ctx->Buffer[ b_len ] = 0x80; 126 | if ( b_len ^ 63 ) memset(Ctx->Buffer + b_len + 1, 0, b_len ^ 63); 127 | 128 | if ( b_len >= 56 ) 129 | { 130 | Sha256ProcessBlock(Ctx, Ctx->Buffer); 131 | memset(Ctx->Buffer, 0, 56); 132 | } 133 | 134 | //PUT_UAA64BE(Ctx->Buffer, (unsigned long long)(Ctx->Len * 8), 7); 135 | ((uint64_t*)Ctx->Buffer)[7] = BE64((uint64_t)Ctx->Len << 3); 136 | Sha256ProcessBlock(Ctx, Ctx->Buffer); 137 | 138 | for (i = 0; i < 8; i++) 139 | //PUT_UAA32BE(hash, Ctx->State[i], i); 140 | ((DWORD*)hash)[i] = BE32(Ctx->State[i]); 141 | 142 | } 143 | 144 | 145 | void Sha256(BYTE *data, size_t len, BYTE *hash) 146 | { 147 | Sha256Ctx Ctx; 148 | 149 | Sha256Init(&Ctx); 150 | Sha256Update(&Ctx, data, len); 151 | Sha256Finish(&Ctx, hash); 152 | } 153 | 154 | 155 | static void _Sha256HmacInit(Sha256HmacCtx *Ctx, BYTE *key, size_t klen) 156 | { 157 | BYTE IPad[64]; 158 | unsigned int i; 159 | 160 | memset(IPad, 0x36, sizeof(IPad)); 161 | memset(Ctx->OPad, 0x5C, sizeof(Ctx->OPad)); 162 | 163 | if ( klen > 64 ) 164 | { 165 | BYTE *temp = (BYTE*)alloca(32); 166 | Sha256(key, klen, temp); 167 | klen = 32; 168 | key = temp; 169 | } 170 | 171 | for (i = 0; i < klen; i++) 172 | { 173 | IPad[ i ] ^= key[ i ]; 174 | Ctx->OPad[ i ] ^= key[ i ]; 175 | } 176 | 177 | Sha256Init(&Ctx->ShaCtx); 178 | Sha256Update(&Ctx->ShaCtx, IPad, sizeof(IPad)); 179 | } 180 | 181 | 182 | static void _Sha256HmacUpdate(Sha256HmacCtx *Ctx, BYTE *data, size_t len) 183 | { 184 | Sha256Update(&Ctx->ShaCtx, data, len); 185 | } 186 | 187 | 188 | static void _Sha256HmacFinish(Sha256HmacCtx *Ctx, BYTE *hmac) 189 | { 190 | BYTE temp[32]; 191 | 192 | Sha256Finish(&Ctx->ShaCtx, temp); 193 | Sha256Init(&Ctx->ShaCtx); 194 | Sha256Update(&Ctx->ShaCtx, Ctx->OPad, sizeof(Ctx->OPad)); 195 | Sha256Update(&Ctx->ShaCtx, temp, sizeof(temp)); 196 | Sha256Finish(&Ctx->ShaCtx, hmac); 197 | } 198 | 199 | 200 | 201 | int_fast8_t Sha256Hmac(BYTE* key, BYTE* restrict data, DWORD len, BYTE* restrict hmac) 202 | { 203 | Sha256HmacCtx Ctx; 204 | _Sha256HmacInit(&Ctx, key, 16); 205 | _Sha256HmacUpdate(&Ctx, data, len); 206 | _Sha256HmacFinish(&Ctx, hmac); 207 | return TRUE; 208 | } 209 | 210 | 211 | #endif // No external Crypto 212 | 213 | -------------------------------------------------------------------------------- /crates/kms-sys/src/shared_globals.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDED_SHARED_GLOBALS_H 2 | #define INCLUDED_SHARED_GLOBALS_H 3 | 4 | #ifndef CONFIG 5 | #define CONFIG "config.h" 6 | #endif // CONFIG 7 | #include CONFIG 8 | 9 | #include 10 | 11 | #ifndef _WIN32 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #if !__minix__ 20 | #include 21 | #endif // !__minix__ 22 | #include 23 | #include 24 | #if !defined(NO_LIMIT) && !__minix__ 25 | #include 26 | #endif // !defined(NO_LIMIT) && !__minix__ 27 | #else 28 | //#ifndef USE_MSRPC 29 | #include 30 | #include 31 | //#endif // USE_MSRPC 32 | #include 33 | #endif 34 | 35 | #include 36 | #if !_MSC_VER 37 | #include 38 | #endif 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | //#include 48 | #include "types.h" 49 | #include "kms.h" 50 | 51 | //#define MIN_CSVLK 6 52 | typedef struct 53 | { 54 | const char* Epid; 55 | const BYTE* HwId; 56 | #ifndef NO_LOG 57 | const char* EpidSource; 58 | uint8_t IsRandom; 59 | #endif // NO_LOG 60 | } KmsResponseParam_t, *PKmsResponseParam_t; 61 | 62 | typedef struct 63 | { 64 | int8_t HasRpcDiag; 65 | int8_t HasBTFN; 66 | int8_t HasNDR64; 67 | } RpcDiag_t, *PRpcDiag_t; 68 | 69 | #if !defined(NO_LIMIT) && !__minix__ 70 | #ifndef SEM_VALUE_MAX // Android does not define this 71 | #ifdef __ANDROID__ 72 | #define SEM_VALUE_MAX 0x3fffffff 73 | #elif defined(_WIN32) 74 | #define SEM_VALUE_MAX 0x7fffffff 75 | #else 76 | #define SEM_VALUE_MAX 0x7fff // Be cautious if unknown 77 | #endif // __ANDROID__ 78 | #endif // !defined(SEM_VALUE_MAX) 79 | #endif // !defined(NO_LIMIT) && !__minix__ 80 | 81 | extern const char *const Version; 82 | 83 | //Fix for stupid eclipse parser 84 | #ifndef UINT_MAX 85 | #define UINT_MAX 4294967295 86 | #endif 87 | 88 | #define MESSAGE_BUFFER_SIZE 4096 89 | #ifdef IS_LIBRARY 90 | extern char ErrorMessage[MESSAGE_BUFFER_SIZE]; 91 | #endif // IS_LIBRARY 92 | 93 | extern int global_argc, multi_argc; 94 | extern CARGV global_argv, multi_argv; 95 | #ifndef _WIN32 96 | extern int_fast8_t nodaemon; 97 | #endif // _WIN32 98 | extern DWORD VLActivationInterval; 99 | extern DWORD VLRenewalInterval; 100 | extern int_fast8_t DisconnectImmediately; 101 | #if !defined(NO_RANDOM_EPID) || !defined(NO_CL_PIDS) || !defined(NO_INI_FILE) 102 | extern KmsResponseParam_t* KmsResponseParameters; 103 | #endif // !defined(NO_RANDOM_EPID) || !defined(NO_CL_PIDS) || !defined(NO_INI_FILE) 104 | extern const char *const cIPv4; 105 | extern const char *const cIPv6; 106 | extern int_fast8_t InetdMode; 107 | extern PVlmcsdHeader_t KmsData; 108 | #ifndef NO_EXTERNAL_DATA 109 | extern char* fn_data; 110 | #ifndef NO_INTERNAL_DATA 111 | extern int_fast8_t ExplicitDataLoad; 112 | #endif // NO_INTERNAL_DATA 113 | #endif // NO_EXTERNAL_DATA 114 | extern const char* fn_exe; 115 | 116 | #ifndef NO_STRICT_MODES 117 | extern uint32_t WhitelistingLevel; 118 | extern int_fast8_t CheckClientTime; 119 | #ifndef NO_CLIENT_LIST 120 | extern int_fast8_t MaintainClients; 121 | extern int_fast8_t StartEmpty; 122 | #endif // NO_CLIENT_LIST 123 | #endif // !NO_STRICT_MODES 124 | 125 | 126 | #ifndef USE_MSRPC 127 | extern int_fast8_t UseMultiplexedRpc; 128 | #ifndef SIMPLE_RPC 129 | extern int_fast8_t UseServerRpcNDR64; 130 | extern int_fast8_t UseServerRpcBTFN; 131 | #endif // !SIMPLE_RPC 132 | extern int_fast8_t UseClientRpcNDR64; 133 | extern int_fast8_t UseClientRpcBTFN; 134 | #endif // USE_MSRPC 135 | 136 | #ifndef NO_SOCKETS 137 | extern int_fast8_t ExitLevel; 138 | extern char *defaultport; 139 | #endif // NO_SOCKETS 140 | 141 | #if !defined(NO_PRIVATE_IP_DETECT) 142 | extern uint32_t PublicIPProtectionLevel; 143 | #endif 144 | 145 | #if !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32) 146 | extern int_fast8_t IsRestarted; 147 | #endif // !defined(NO_SOCKETS) && !defined(NO_SIGHUP) && !defined(_WIN32) 148 | 149 | #if !defined(NO_TIMEOUT) && !__minix__ 150 | extern DWORD ServerTimeout; 151 | #endif // !defined(NO_TIMEOUT) && !__minix__ 152 | 153 | #if !defined(NO_LIMIT) && !defined (NO_SOCKETS) && !__minix__ 154 | extern uint32_t MaxTasks; 155 | #endif // !defined(NO_LIMIT) && !defined (NO_SOCKETS) && !__minix__ 156 | 157 | #ifndef NO_LOG 158 | extern int_fast8_t LogDateAndTime; 159 | extern char *fn_log; 160 | extern int_fast8_t logstdout; 161 | #ifndef NO_VERBOSE_LOG 162 | extern int_fast8_t logverbose; 163 | #endif 164 | #endif 165 | 166 | #if !defined(USE_MSRPC) && !defined(SIMPLE_RPC) 167 | extern uint8_t IsNDR64Defined; 168 | #endif 169 | 170 | #ifndef NO_RANDOM_EPID 171 | extern int_fast8_t RandomizationLevel; 172 | extern uint16_t Lcid; 173 | extern uint16_t HostBuild; 174 | #endif 175 | 176 | #if !defined(NO_SOCKETS) && !defined(USE_MSRPC) 177 | #if defined(SIMPLE_SOCKETS) 178 | extern SOCKET s_server; 179 | #else // !defined(SIMPLE_SOCKETS) 180 | extern SOCKET *SocketList; 181 | extern int numsockets; 182 | #endif // !defined(SIMPLE_SOCKETS) 183 | 184 | #if !defined(NO_LIMIT) && !__minix__ 185 | 186 | #ifndef _WIN32 187 | extern sem_t *MaxTaskSemaphore; 188 | #else // _WIN32 189 | extern HANDLE MaxTaskSemaphore; 190 | #endif // _WIN32 191 | 192 | #endif // !defined(NO_LIMIT) && !__minix__ 193 | 194 | #endif // !defined(NO_SOCKETS) && !defined(USE_MSRPC) 195 | 196 | #ifdef _NTSERVICE 197 | extern int_fast8_t IsNTService; 198 | extern int_fast8_t ServiceShutdown; 199 | #endif 200 | 201 | #ifndef NO_LOG 202 | #ifdef USE_THREADS 203 | #if !defined(_WIN32) && !defined(__CYGWIN__) 204 | extern pthread_mutex_t logmutex; 205 | #else 206 | extern CRITICAL_SECTION logmutex; 207 | #endif // _WIN32 208 | #endif // USE_THREADS 209 | #endif // NO_LOG 210 | 211 | #if HAVE_FREEBIND 212 | extern int_fast8_t freebind; 213 | #endif // HAVE_FREEBIND 214 | 215 | 216 | #endif // INCLUDED_SHARED_GLOBALS_H 217 | -------------------------------------------------------------------------------- /crates/kms-sys/src/endian.h: -------------------------------------------------------------------------------- 1 | #ifndef __endian_h 2 | #define __endian_h 3 | 4 | #ifndef CONFIG 5 | #define CONFIG "config.h" 6 | #endif // CONFIG 7 | #include CONFIG 8 | 9 | // 10 | // Unaligned access 11 | // 12 | 13 | #if !defined(NO_COMPILER_UAA) 14 | #define UAA16(p, i) (((PACKED16*)p)->val[i]) 15 | #define UAA32(p, i) (((PACKED32*)p)->val[i]) 16 | #define UAA64(p, i) (((PACKED64*)p)->val[i]) 17 | #endif 18 | 19 | // 20 | //Byteswap: Use compiler support if available 21 | // 22 | #ifndef NO_COMPILER_UAA 23 | #ifdef __has_builtin // Clang supports this 24 | 25 | #if __has_builtin(__builtin_bswap16) 26 | #define BS16(x) __builtin_bswap16(x) 27 | #endif 28 | 29 | #if __has_builtin(__builtin_bswap32) 30 | #define BS32(x) __builtin_bswap32(x) 31 | #endif 32 | 33 | #if __has_builtin(__builtin_bswap64) 34 | #define BS64(x) __builtin_bswap64(x) 35 | #endif 36 | 37 | #endif // has_builtin 38 | 39 | #ifdef __GNUC__ // GNU C >= 4.3 has bswap32 and bswap64. GNU C >= 4.8 also has bswap16 40 | #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ > 2) 41 | 42 | #ifndef BS32 43 | #define BS32(x) __builtin_bswap32(x) 44 | #endif 45 | 46 | #ifndef BS64 47 | #define BS64(x) __builtin_bswap64(x) 48 | #endif 49 | 50 | #if (__GNUC__ > 4) || (__GNUC_MINOR__ > 7) 51 | 52 | #ifndef BS16 53 | #define BS16(x) __builtin_bswap16(x) 54 | #endif 55 | 56 | #endif // GNU C > 4.7 57 | #endif // __GNUC__ > 4 58 | #endif // __GNUC__ 59 | #endif // NO_COMPILER_UAA 60 | 61 | // 62 | // Byteorder 63 | // 64 | #if defined(__linux__) || defined(__GLIBC__) || defined(__CYGWIN__) 65 | 66 | #include 67 | #include 68 | 69 | #ifndef BS16 70 | #define BS16(x) bswap_16(x) 71 | #endif 72 | 73 | #ifndef BS32 74 | #define BS32(x) bswap_32(x) 75 | #endif 76 | 77 | #ifndef BS64 78 | #define BS64(x) bswap_64(x) 79 | #endif 80 | 81 | #elif defined(__sun__) 82 | 83 | #include 84 | 85 | #ifndef BS16 86 | #define BS16(x) BSWAP_16(x) 87 | #endif 88 | 89 | #ifndef BS32 90 | #define BS32(x) BSWAP_32(x) 91 | #endif 92 | 93 | #ifndef BS64 94 | #define BS64(x) BSWAP_64(x) 95 | #endif 96 | 97 | #define __LITTLE_ENDIAN 1234 98 | #define __BIG_ENDIAN 4321 99 | 100 | #ifdef _LITTLE_ENDIAN 101 | #define __BYTE_ORDER __LITTLE_ENDIAN 102 | #else 103 | #define __BYTE_ORDER __BIG_ENDIAN 104 | #endif 105 | 106 | #elif __minix__ || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) 107 | 108 | #include 109 | #include 110 | 111 | #define __BYTE_ORDER _BYTE_ORDER 112 | #define __LITTLE_ENDIAN _LITTLE_ENDIAN 113 | #define __BIG_ENDIAN _BIG_ENDIAN 114 | 115 | #ifdef __OpenBSD__ 116 | 117 | #ifndef BS16 118 | #define BS16 swap16 119 | #endif 120 | 121 | #ifndef BS32 122 | #define BS32 swap32 123 | #endif 124 | 125 | #ifndef BS64 126 | #define BS64 swap64 127 | #endif 128 | 129 | #else // !__OpenBSD__ 130 | 131 | #ifndef BS16 132 | #define BS16 bswap16 133 | #endif 134 | 135 | #ifndef BS32 136 | #define BS32 bswap32 137 | #endif 138 | 139 | #ifndef BS64 140 | #define BS64 bswap64 141 | #endif 142 | 143 | #endif // !__OpenBSD__ 144 | 145 | #elif defined(__APPLE__) 146 | 147 | #include 148 | #include 149 | #include 150 | 151 | #define __BYTE_ORDER _BYTE_ORDER 152 | #define __LITTLE_ENDIAN _LITTLE_ENDIAN 153 | #define __BIG_ENDIAN _BIG_ENDIAN 154 | 155 | #ifndef BS16 156 | #define BS16 OSSwapInt16 157 | #endif 158 | 159 | #ifndef BS32 160 | #define BS32 OSSwapInt32 161 | #endif 162 | 163 | #ifndef BS64 164 | #define BS64 OSSwapInt64 165 | #endif 166 | 167 | #elif defined(_WIN32) 168 | 169 | #define __LITTLE_ENDIAN 1234 170 | #define __BIG_ENDIAN 4321 171 | #define __BYTE_ORDER __LITTLE_ENDIAN 172 | 173 | #include 174 | 175 | #ifndef BS16 176 | #define BS16 _byteswap_ushort 177 | #endif 178 | 179 | #ifndef BS32 180 | #define BS32 _byteswap_ulong 181 | #endif 182 | 183 | #ifndef BS64 184 | #define BS64 _byteswap_uint64 185 | #endif 186 | 187 | #endif // Byteorder in different OS 188 | 189 | 190 | #if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) \ 191 | && defined(BS16) && defined(BS32) && defined(BS64) 192 | 193 | #if __BYTE_ORDER == __LITTLE_ENDIAN 194 | 195 | #define __BE16(x) BS16(x) 196 | #define __LE16(x) (x) 197 | #define __BE32(x) BS32(x) 198 | #define __LE32(x) (x) 199 | #define __BE64(x) BS64(x) 200 | #define __LE64(x) (x) 201 | 202 | #define PUT_UA16(p, v) PUT_UA16LE(p, v) 203 | #define PUT_UA32(p, v) PUT_UA32LE(p, v) 204 | #define PUT_UA64(p, v) PUT_UA64LE(p, v) 205 | 206 | #else // __BYTE_ORDER == __BIG_ENDIAN 207 | 208 | #define __BE16(x) (x) 209 | #define __LE16(x) BS16(x) 210 | #define __BE32(x) (x) 211 | #define __LE32(x) BS32(x) 212 | #define __BE64(x) (x) 213 | #define __LE64(x) BS64(x) 214 | 215 | #define PUT_UA16(p, v) PUT_UA16BE(p, v) 216 | #define PUT_UA32(p, v) PUT_UA32BE(p, v) 217 | #define PUT_UA64(p, v) PUT_UA64BE(p, v) 218 | 219 | #endif // __BYTE_ORDER 220 | 221 | #define BE16(x) __BE16(x) 222 | #define LE16(x) __LE16(x) 223 | #define BE32(x) __BE32(x) 224 | #define LE32(x) __LE32(x) 225 | #define BE64(x) __BE64(x) 226 | #define LE64(x) __LE64(x) 227 | 228 | #else 229 | 230 | extern unsigned short BE16(unsigned short x); 231 | 232 | extern unsigned short LE16(unsigned short x); 233 | 234 | extern unsigned int BE32(unsigned int x); 235 | 236 | extern unsigned int LE32(unsigned int x); 237 | 238 | extern unsigned long long BE64(unsigned long long x); 239 | 240 | extern unsigned long long LE64(unsigned long long x); 241 | 242 | #endif // defined(__BYTE_ORDER) 243 | 244 | #if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) \ 245 | && defined(BS16) && defined(BS32) && defined(BS64) &&!defined(NO_COMPILER_UAA) 246 | 247 | #define PUT_UAA64BE(p, v, i) ( UAA64(p, i) = __BE64(v) ) 248 | #define PUT_UAA32BE(p, v, i) ( UAA32(p, i) = __BE32(v) ) 249 | #define PUT_UAA16BE(p, v, i) ( UAA16(p, i) = __BE16(v) ) 250 | 251 | #define PUT_UAA64LE(p, v, i) ( UAA64(p, i) = __LE64(v) ) 252 | #define PUT_UAA32LE(p, v, i) ( UAA32(p, i) = __LE32(v) ) 253 | #define PUT_UAA16LE(p, v, i) ( UAA16(p, i) = __LE16(v) ) 254 | 255 | #define GET_UAA64BE(p, i) __BE64(UAA64(p, i)) 256 | #define GET_UAA32BE(p, i) __BE32(UAA32(p, i)) 257 | #define GET_UAA16BE(p, i) __BE16(UAA16(p, i)) 258 | 259 | #define GET_UAA64LE(p, i) __LE64(UAA64(p, i)) 260 | #define GET_UAA32LE(p, i) __LE32(UAA32(p, i)) 261 | #define GET_UAA16LE(p, i) __LE16(UAA16(p, i)) 262 | 263 | 264 | #else // ! defined(__BYTE_ORDER) 265 | 266 | extern void PUT_UAA64BE(void* p, unsigned long long v, unsigned int i); 267 | 268 | extern void PUT_UAA32BE(void* p, unsigned int v, unsigned int i); 269 | 270 | extern void PUT_UAA16BE(void* p, unsigned short v, unsigned int i); 271 | 272 | 273 | extern void PUT_UAA64LE(void* p, unsigned long long v, unsigned int i); 274 | 275 | extern void PUT_UAA32LE(void* p, unsigned int v, unsigned int i); 276 | 277 | extern void PUT_UAA16LE(void* p, unsigned short v, unsigned int i); 278 | 279 | 280 | extern unsigned long long GET_UAA64BE(void* p, unsigned int i); 281 | 282 | extern unsigned int GET_UAA32BE(void* p, unsigned int i); 283 | 284 | extern unsigned short GET_UAA16BE(void* p, unsigned int i); 285 | 286 | 287 | extern unsigned long long GET_UAA64LE(void* p, unsigned int i); 288 | 289 | extern unsigned int GET_UAA32LE(void* p, unsigned int i); 290 | 291 | extern unsigned short GET_UAA16LE(void* p, unsigned int i); 292 | #endif 293 | 294 | 295 | 296 | #define PUT_UA64BE(p, v) PUT_UAA64BE(p, v, 0) 297 | #define PUT_UA32BE(p, v) PUT_UAA32BE(p, v, 0) 298 | #define PUT_UA16BE(p, v) PUT_UAA16BE(p, v, 0) 299 | 300 | #define PUT_UA64LE(p, v) PUT_UAA64LE(p, v, 0) 301 | #define PUT_UA32LE(p, v) PUT_UAA32LE(p, v, 0) 302 | #define PUT_UA16LE(p, v) PUT_UAA16LE(p, v, 0) 303 | 304 | #define GET_UA64BE(p) GET_UAA64BE(p, 0) 305 | #define GET_UA32BE(p) GET_UAA32BE(p, 0) 306 | #define GET_UA16BE(p) GET_UAA16BE(p, 0) 307 | 308 | #define GET_UA64LE(p) GET_UAA64LE(p, 0) 309 | #define GET_UA32LE(p) GET_UAA32LE(p, 0) 310 | #define GET_UA16LE(p) GET_UAA16LE(p, 0) 311 | 312 | #endif // __endian_h 313 | -------------------------------------------------------------------------------- /crates/kms-sys/src/rpc.h: -------------------------------------------------------------------------------- 1 | #ifndef __rpc_h 2 | #define __rpc_h 3 | 4 | #ifndef CONFIG 5 | #define CONFIG "config.h" 6 | #endif // CONFIG 7 | #include CONFIG 8 | 9 | #include "types.h" 10 | #include "shared_globals.h" 11 | 12 | #if !defined(_WIN32) && !defined(__CYGWIN__) 13 | #define RPC_S_OK 0 14 | #define RPC_S_INVALID_ARG 87 15 | #define RPC_S_OUT_OF_MEMORY 14 16 | #define RPC_S_OUT_OF_THREADS 164 17 | #define RPC_S_INVALID_LEVEL RPC_S_INVALID_ARG 18 | #define RPC_S_BUFFER_TOO_SMALL 122 19 | #define RPC_S_INVALID_SECURITY_DESC 1338 20 | #define RPC_S_ACCESS_DENIED 5 21 | #define RPC_S_SERVER_OUT_OF_MEMORY 1130 22 | #define RPC_S_ASYNC_CALL_PENDING 997 23 | #define RPC_S_UNKNOWN_PRINCIPAL 1332 24 | #define RPC_S_TIMEOUT 1460 25 | #define RPC_S_INVALID_STRING_BINDING 1700 26 | #define RPC_S_WRONG_KIND_OF_BINDING 1701 27 | #define RPC_S_INVALID_BINDING 1702 28 | #define RPC_S_PROTSEQ_NOT_SUPPORTED 1703 29 | #define RPC_S_INVALID_RPC_PROTSEQ 1704 30 | #define RPC_S_INVALID_STRING_UUID 1705 31 | #define RPC_S_INVALID_ENDPOINT_FORMAT 1706 32 | #define RPC_S_INVALID_NET_ADDR 1707 33 | #define RPC_S_NO_ENDPOINT_FOUND 1708 34 | #define RPC_S_INVALID_TIMEOUT 1709 35 | #define RPC_S_OBJECT_NOT_FOUND 1710 36 | #define RPC_S_ALREADY_REGISTERED 1711 37 | #define RPC_S_TYPE_ALREADY_REGISTERED 1712 38 | #define RPC_S_ALREADY_LISTENING 1713 39 | #define RPC_S_NO_PROTSEQS_REGISTERED 1714 40 | #define RPC_S_NOT_LISTENING 1715 41 | #define RPC_S_UNKNOWN_MGR_TYPE 1716 42 | #define RPC_S_UNKNOWN_IF 1717 43 | #define RPC_S_NO_BINDINGS 1718 44 | #define RPC_S_NO_PROTSEQS 1719 45 | #define RPC_S_CANT_CREATE_ENDPOINT 1720 46 | #define RPC_S_OUT_OF_RESOURCES 1721 47 | #define RPC_S_SERVER_UNAVAILABLE 1722 48 | #define RPC_S_SERVER_TOO_BUSY 1723 49 | #define RPC_S_INVALID_NETWORK_OPTIONS 1724 50 | #define RPC_S_NO_CALL_ACTIVE 1725 51 | #define RPC_S_CALL_FAILED 1726 52 | #define RPC_S_CALL_FAILED_DNE 1727 53 | #define RPC_S_PROTOCOL_ERROR 1728 54 | #define RPC_S_PROXY_ACCESS_DENIED 1729 55 | #define RPC_S_UNSUPPORTED_TRANS_SYN 1730 56 | #define RPC_S_UNSUPPORTED_TYPE 1732 57 | #define RPC_S_INVALID_TAG 1733 58 | #define RPC_S_INVALID_BOUND 1734 59 | #define RPC_S_NO_ENTRY_NAME 1735 60 | #define RPC_S_INVALID_NAME_SYNTAX 1736 61 | #define RPC_S_UNSUPPORTED_NAME_SYNTAX 1737 62 | #define RPC_S_UUID_NO_ADDRESS 1739 63 | #define RPC_S_DUPLICATE_ENDPOINT 1740 64 | #define RPC_S_UNKNOWN_AUTHN_TYPE 1741 65 | #define RPC_S_MAX_CALLS_TOO_SMALL 1742 66 | #define RPC_S_STRING_TOO_LONG 1743 67 | #define RPC_S_PROTSEQ_NOT_FOUND 1744 68 | #define RPC_S_PROCNUM_OUT_OF_RANGE 1745 69 | #define RPC_S_BINDING_HAS_NO_AUTH 1746 70 | #define RPC_S_UNKNOWN_AUTHN_SERVICE 1747 71 | #define RPC_S_UNKNOWN_AUTHN_LEVEL 1748 72 | #define RPC_S_INVALID_AUTH_IDENTITY 1749 73 | #define RPC_S_UNKNOWN_AUTHZ_SERVICE 1750 74 | #define EPT_S_INVALID_ENTRY 1751 75 | #define EPT_S_CANT_PERFORM_OP 1752 76 | #define EPT_S_NOT_REGISTERED 1753 77 | #define RPC_S_NOTHING_TO_EXPORT 1754 78 | #define RPC_S_INCOMPLETE_NAME 1755 79 | #define RPC_S_INVALID_VERS_OPTION 1756 80 | #define RPC_S_NO_MORE_MEMBERS 1757 81 | #define RPC_S_NOT_ALL_OBJS_UNEXPORTED 1758 82 | #define RPC_S_INTERFACE_NOT_FOUND 1759 83 | #define RPC_S_ENTRY_ALREADY_EXISTS 1760 84 | #define RPC_S_ENTRY_NOT_FOUND 1761 85 | #define RPC_S_NAME_SERVICE_UNAVAILABLE 1762 86 | #define RPC_S_INVALID_NAF_ID 1763 87 | #define RPC_S_CANNOT_SUPPORT 1764 88 | #define RPC_S_NO_CONTEXT_AVAILABLE 1765 89 | #define RPC_S_INTERNAL_ERROR 1766 90 | #define RPC_S_ZERO_DIVIDE 1767 91 | #define RPC_S_ADDRESS_ERROR 1768 92 | #define RPC_S_FP_DIV_ZERO 1769 93 | #define RPC_S_FP_UNDERFLOW 1770 94 | #define RPC_S_FP_OVERFLOW 1771 95 | #define RPC_X_NO_MORE_ENTRIES 1772 96 | #define RPC_X_SS_CHAR_TRANS_OPEN_FAIL 1773 97 | #define RPC_X_SS_CHAR_TRANS_SHORT_FILE 1774 98 | #define RPC_X_SS_IN_NULL_CONTEXT 1775 99 | #define RPC_X_SS_CONTEXT_DAMAGED 1777 100 | #define RPC_X_SS_HANDLES_MISMATCH 1778 101 | #define RPC_X_SS_CANNOT_GET_CALL_HANDLE 1779 102 | #define RPC_X_NULL_REF_POINTER 1780 103 | #define RPC_X_ENUM_VALUE_OUT_OF_RANGE 1781 104 | #define RPC_X_BYTE_COUNT_TOO_SMALL 1782 105 | #define RPC_X_BAD_STUB_DATA 1783 106 | #define RPC_S_CALL_IN_PROGRESS 1791 107 | #define RPC_S_NO_MORE_BINDINGS 1806 108 | #define RPC_S_NO_INTERFACES 1817 109 | #define RPC_S_CALL_CANCELLED 1818 110 | #define RPC_S_BINDING_INCOMPLETE 1819 111 | #define RPC_S_COMM_FAILURE 1820 112 | #define RPC_S_UNSUPPORTED_AUTHN_LEVEL 1821 113 | #define RPC_S_NO_PRINC_NAME 1822 114 | #define RPC_S_NOT_RPC_ERROR 1823 115 | #define RPC_S_UUID_LOCAL_ONLY 1824 116 | #define RPC_S_SEC_PKG_ERROR 1825 117 | #define RPC_S_NOT_CANCELLED 1826 118 | #define RPC_X_INVALID_ES_ACTION 1827 119 | #define RPC_X_WRONG_ES_VERSION 1828 120 | #define RPC_X_WRONG_STUB_VERSION 1829 121 | #define RPC_X_INVALID_PIPE_OBJECT 1830 122 | #define RPC_X_WRONG_PIPE_ORDER 1831 123 | #define RPC_X_WRONG_PIPE_VERSION 1832 124 | #define RPC_S_COOKIE_AUTH_FAILED 1833 125 | #define RPC_S_GROUP_MEMBER_NOT_FOUND 1898 126 | #define EPT_S_CANT_CREATE 1899 127 | #define RPC_S_INVALID_OBJECT 1900 128 | #define RPC_S_SEND_INCOMPLETE 1913 129 | #define RPC_S_INVALID_ASYNC_HANDLE 1914 130 | #define RPC_S_INVALID_ASYNC_CALL 1915 131 | #define RPC_X_PIPE_CLOSED 1916 132 | #define RPC_X_PIPE_DISCIPLINE_ERROR 1917 133 | #define RPC_X_PIPE_EMPTY 1918 134 | #define RPC_S_ENTRY_TYPE_MISMATCH 1922 135 | #define RPC_S_NOT_ALL_OBJS_EXPORTED 1923 136 | #define RPC_S_INTERFACE_NOT_EXPORTED 1924 137 | #define RPC_S_PROFILE_NOT_ADDED 1925 138 | #define RPC_S_PRF_ELT_NOT_ADDED 1926 139 | #define RPC_S_PRF_ELT_NOT_REMOVED 1927 140 | #define RPC_S_GRP_ELT_NOT_ADDED 1928 141 | #define RPC_S_GRP_ELT_NOT_REMOVED 1929 142 | #endif // !defined(_WIN32) && !_defined(__CYGWIN__) 143 | 144 | 145 | typedef struct { 146 | BYTE VersionMajor; 147 | BYTE VersionMinor; 148 | BYTE PacketType; 149 | BYTE PacketFlags; 150 | DWORD DataRepresentation; 151 | WORD FragLength; 152 | WORD AuthLength; 153 | DWORD CallId; 154 | } /*__packed*/ RPC_HEADER; 155 | 156 | 157 | typedef struct { 158 | WORD MaxXmitFrag; 159 | WORD MaxRecvFrag; 160 | DWORD AssocGroup; 161 | DWORD NumCtxItems; 162 | struct CtxItem { 163 | WORD ContextId; 164 | WORD NumTransItems; 165 | GUID InterfaceUUID; 166 | WORD InterfaceVerMajor; 167 | WORD InterfaceVerMinor; 168 | GUID TransferSyntax; 169 | DWORD SyntaxVersion; 170 | } CtxItems[1]; 171 | } /*__packed*/ RPC_BIND_REQUEST; 172 | 173 | typedef struct { 174 | WORD MaxXmitFrag; 175 | WORD MaxRecvFrag; 176 | DWORD AssocGroup; 177 | WORD SecondaryAddressLength; 178 | BYTE SecondaryAddress[6]; 179 | DWORD NumResults; 180 | struct CtxResults { 181 | WORD AckResult; 182 | WORD AckReason; 183 | GUID TransferSyntax; 184 | DWORD SyntaxVersion; 185 | } Results[0]; 186 | } /*__packed*/ RPC_BIND_RESPONSE; 187 | 188 | 189 | typedef struct { 190 | DWORD AllocHint; 191 | WORD ContextId; 192 | WORD Opnum; 193 | struct { 194 | DWORD DataLength; 195 | DWORD DataSizeIs; 196 | } Ndr; 197 | BYTE Data[0]; 198 | } /*__packed*/ RPC_REQUEST; 199 | 200 | typedef struct { 201 | DWORD AllocHint; 202 | WORD ContextId; 203 | BYTE CancelCount; 204 | BYTE Pad1; 205 | struct { 206 | DWORD DataLength; 207 | DWORD DataSizeIs1; 208 | DWORD DataSizeIs2; 209 | } Ndr; 210 | BYTE Data[0]; 211 | } /*__packed*/ RPC_RESPONSE; 212 | 213 | typedef struct { 214 | DWORD AllocHint; 215 | WORD ContextId; 216 | WORD Opnum; 217 | union { 218 | struct { 219 | DWORD DataLength; 220 | DWORD DataSizeIs; 221 | BYTE Data[0]; 222 | } Ndr; 223 | struct { 224 | uint64_t DataLength; 225 | uint64_t DataSizeIs; 226 | BYTE Data[0]; 227 | } Ndr64; 228 | }; 229 | } /*__packed*/ RPC_REQUEST64; 230 | 231 | typedef struct { 232 | DWORD AllocHint; 233 | WORD ContextId; 234 | BYTE CancelCount; 235 | BYTE Pad1; 236 | union { 237 | struct { 238 | DWORD DataLength; 239 | DWORD DataSizeMax; 240 | union 241 | { 242 | DWORD DataSizeIs; 243 | DWORD status; 244 | }; 245 | BYTE Data[0]; 246 | } Ndr; 247 | struct { 248 | uint64_t DataLength; 249 | uint64_t DataSizeMax; 250 | union 251 | { 252 | uint64_t DataSizeIs; 253 | DWORD status; 254 | }; 255 | BYTE Data[0]; 256 | } Ndr64; 257 | struct 258 | { 259 | DWORD Code; 260 | DWORD Padding; 261 | } Error; 262 | 263 | }; 264 | } /*__packed*/ RPC_RESPONSE64; 265 | 266 | 267 | //#define RpcCtx SOCKET 268 | typedef SOCKET RpcCtx; 269 | typedef int RpcStatus; 270 | 271 | #define RPC_INVALID_CTX ((WORD)~0) 272 | 273 | #define RPC_BIND_ACCEPT (0) 274 | #define RPC_BIND_NACK (LE16(2)) 275 | #define RPC_BIND_ACK (LE16(3)) 276 | 277 | #define RPC_SYNTAX_UNSUPPORTED (LE16(2)) 278 | #define RPC_ABSTRACTSYNTAX_UNSUPPORTED (LE16(1)) 279 | #define RPC_NCA_UNK_IF (LE32(0x1c010003)) 280 | #define RPC_NCA_PROTO_ERROR (LE32(0x1c01000b)) 281 | 282 | #define RPC_BTFN_SEC_CONTEXT_MULTIPLEX (LE16(1)) 283 | #define RPC_BTFN_KEEP_ORPHAN (LE16(2)) 284 | 285 | #define INVALID_RPCCTX INVALID_SOCKET 286 | #define closeRpc socketclose 287 | 288 | #define RPC_PT_REQUEST 0 289 | #define RPC_PT_RESPONSE 2 290 | #define RPC_PT_FAULT 3 291 | #define RPC_PT_BIND_REQ 11 292 | #define RPC_PT_BIND_ACK 12 293 | #define RPC_PT_ALTERCONTEXT_REQ 14 294 | #define RPC_PT_ALTERCONTEXT_ACK 15 295 | 296 | #define RPC_PF_FIRST 1 297 | #define RPC_PF_LAST 2 298 | #define RPC_PF_CANCEL_PENDING 4 299 | #define RPC_PF_RESERVED 8 300 | #define RPC_PF_MULTIPLEX 16 301 | #define RPC_PF_NOT_EXEC 32 302 | #define RPC_PF_MAYBE 64 303 | #define RPC_PF_OBJECT 128 304 | 305 | 306 | typedef union _RPC_FLAGS 307 | { 308 | DWORD mask; 309 | struct { 310 | uint32_t FlagsBTFN : 16; 311 | BOOL HasNDR32 : 1; 312 | BOOL HasNDR64 : 1; 313 | BOOL HasBTFN : 1; 314 | }; 315 | } RPC_FLAGS, *PRPC_FLAGS; 316 | 317 | extern RPC_FLAGS RpcFlags; 318 | 319 | void rpcServer(const SOCKET sock, const DWORD rpcAssocGroup, const char* const ipstr); 320 | RpcStatus rpcBindClient(const RpcCtx sock, const int_fast8_t verbose, PRpcDiag_t rpcDiag); 321 | RpcStatus rpcSendRequest(const RpcCtx socket, const BYTE *const kmsRequest, const size_t requestSize, BYTE **kmsResponse, size_t *const responseSize); 322 | 323 | #endif // __rpc_h 324 | -------------------------------------------------------------------------------- /crates/kms-sys/src/types.h: -------------------------------------------------------------------------------- 1 | #ifndef __types_h 2 | #define __types_h 3 | 4 | #ifndef _GNU_SOURCE 5 | #define _GNU_SOURCE 6 | #endif 7 | 8 | #ifndef _CRT_SECURE_NO_WARNINGS 9 | #define _CRT_SECURE_NO_WARNINGS 10 | #endif 11 | 12 | #ifndef CONFIG 13 | #define CONFIG "config.h" 14 | #endif // CONFIG 15 | #include CONFIG 16 | 17 | #if defined(NO_INTERNAL_DATA) && defined(NO_EXTERNAL_DATA) 18 | #error NO_INTERAL_DATA and NO_EXTERNAL_DATA cannot be used together 19 | #endif 20 | 21 | #if defined(_WIN32) 22 | 23 | //#ifndef USE_MSRPC 24 | #include 25 | //#include 26 | //#endif // USE_MSRPC 27 | #endif // defined(_WIN32) 28 | 29 | #define ANDROID_API_LEVEL ANDROID_HELPER1(__ANDROID_API__) 30 | #define ANDROID_HELPER1(s) ANDROID_HELPER2(s) 31 | #define ANDROID_HELPER2(s) #s 32 | 33 | #if !_WIN32 && !__CYGWIN__ 34 | 35 | #if !__minix__ 36 | #include 37 | #endif // !__minix__ 38 | 39 | #define __declspec(x) __attribute__((__visibility__("default"))) 40 | #endif 41 | 42 | #if !defined(EXTERNAL) 43 | #define EXTERNAL dllimport 44 | #endif 45 | 46 | #ifdef __cplusplus 47 | #define EXTERNC extern "C" 48 | #else 49 | #define EXTERNC 50 | #endif 51 | 52 | #include 53 | //#include 54 | #include 55 | 56 | #ifdef __ANDROID__ 57 | #include 58 | #endif // __ANDROID__ 59 | 60 | #ifndef _WIN32 61 | #include 62 | #include 63 | #endif // _WIN32 64 | 65 | 66 | #if __linux__ // Some versions of uclibc do not define IP_FREEBIND in the correct header file 67 | #ifndef IP_FREEBIND 68 | #define IP_FREEBIND 15 69 | #endif // IP_FREEBIND 70 | #endif // __linux__ 71 | 72 | #ifdef NO_EXTERNAL_DATA 73 | #ifndef UNSAFE_DATA_LOAD 74 | #define UNSAFE_DATA_LOAD 75 | #endif // UNSAFE_DATA_LOAD 76 | #endif // NO_EXTERNAL_DATA 77 | 78 | #if (IP_BINDANY || IP_FREEBIND || IPV6_BINDANY || IP_NONLOCALOK) && !defined(NO_FREEBIND) && !defined(USE_MSRPC) && !defined(SIMPLE_SOCKETS) 79 | #define HAVE_FREEBIND 1 80 | #endif 81 | 82 | #if !defined(NO_GETIFADDRS) && !defined(USE_MSRPC) && !defined(SIMPLE_SOCKETS) && !defined(NO_SOCKETS) && !defined(NO_PRIVATE_IP_DETECT) 83 | #define HAVE_GETIFADDR 1 84 | #endif 85 | 86 | //#if (__minix__ || defined(NO_SOCKETS)) && !defined(NO_STRICT_MODES) 87 | //#define NO_STRICT_MODES 88 | //#endif // __minix__ && !defined(NO_STRICT_MODES) 89 | 90 | #if (defined(NO_STRICT_MODES) || defined(NO_SOCKETS)) && !defined(NO_CLIENT_LIST) 91 | #define NO_CLIENT_LIST 92 | #endif // defined(NO_STRICT_MODES) || defined(NO_SOCKETS) && !defined(NO_CLIENT_LIST) 93 | 94 | #if !_WIN32 && !__CYGWIN__ 95 | 96 | #if !defined(_POSIX_THREADS) || (!defined(_POSIX_THREAD_PROCESS_SHARED) && !defined(USE_THREADS) && !__ANDROID__) 97 | #ifndef NO_CLIENT_LIST 98 | #define NO_CLIENT_LIST 99 | #endif // !NO_CLIENT_LIST 100 | #endif // !defined(_POSIX_THREADS) || (!defined(_POSIX_THREAD_PROCESS_SHARED) && !defined(USE_THREADS)) 101 | 102 | #if !defined(_POSIX_THREADS) && !defined(NO_LIMIT) 103 | #define NO_LIMIT 104 | #endif // !defined(POSIX_THREADS) && !defined(NO_LIMIT) 105 | 106 | #endif // !_WIN32 && !__CYGWIN__ 107 | 108 | #ifndef alloca 109 | #ifdef __GNUC__ 110 | #define alloca(x) __builtin_alloca(x) 111 | #endif // __GNUC__ 112 | #endif // alloca 113 | 114 | 115 | #ifndef alloca 116 | #ifdef __has_builtin // clang feature test 117 | #if __has_builtin(__builtin_alloca) 118 | #define alloca(x) __builtin_alloca(x) 119 | #endif // __has_builtin(__builtin_alloca) 120 | #endif // __has_builtin 121 | #endif // alloca 122 | 123 | #ifndef alloca 124 | #if !_MSC_VER 125 | #include 126 | #else 127 | #include 128 | //#define alloca _malloca 129 | #endif 130 | //#define alloca _malloca 131 | //#endif // _MSC_VER 132 | #endif // alloca 133 | 134 | #ifndef __packed 135 | #if _MSC_VER 136 | #define __packed 137 | #else // !_MSC_VER 138 | #define __packed __attribute__((packed)) 139 | #endif // !_MSC_VER 140 | #endif 141 | 142 | #ifndef __pure 143 | #if _MSC_VER 144 | #define __pure 145 | #else 146 | #define __pure __attribute__((pure)) 147 | #endif 148 | #endif 149 | 150 | #ifndef __noreturn 151 | #if _MSC_VER 152 | #define __noreturn __declspec(noreturn) 153 | #else 154 | #define __noreturn __attribute__((noreturn)) 155 | #endif 156 | #endif 157 | 158 | #define restrict __restrict 159 | 160 | typedef struct __packed 161 | { 162 | uint16_t val[0]; 163 | } PACKED16; 164 | 165 | typedef struct __packed 166 | { 167 | uint32_t val[0]; 168 | } PACKED32; 169 | 170 | typedef struct __packed 171 | { 172 | uint64_t val[0]; 173 | } PACKED64; 174 | 175 | // Deal with Mingw32-w64 C++ header which defines a _countof that is incompatible with vlmcsd 176 | #define vlmcsd_countof(x) ( sizeof(x) / sizeof(x[0]) ) 177 | 178 | // PATH_MAX is optional in Posix. We use a default of 260 here 179 | #ifndef PATH_MAX 180 | #ifdef _WIN32 181 | #define PATH_MAX MAX_PATH 182 | #else 183 | #define PATH_MAX 260 184 | #endif // _WIN32 185 | #endif // !PATH_MAX 186 | 187 | #if PATH_MAX > 260 188 | #define VLMCSD_PATH_MAX 260 189 | #else 190 | #define VLMCSD_PATH_MAX PATH_MAX 191 | #endif 192 | 193 | // Synchronization Objects 194 | 195 | // Mutexes 196 | #ifdef USE_THREADS 197 | #if !defined(_WIN32) && !defined(__CYGWIN__) 198 | #define lock_mutex(x) pthread_mutex_lock(x) 199 | #define unlock_mutex(x) pthread_mutex_unlock(x) 200 | #else 201 | #define lock_mutex(x) EnterCriticalSection(x) 202 | #define unlock_mutex(x) LeaveCriticalSection(x) 203 | #endif 204 | #else // !USE_THREADS 205 | //defines to nothing 206 | #define lock_mutex(x) 207 | #define unlock_mutex(x) 208 | #endif // !USE_THREADS 209 | 210 | // Semaphores 211 | #ifndef _WIN32 212 | #define semaphore_wait(x) sem_wait(x) 213 | #define semaphore_post(x) sem_post(x) 214 | #else // _WIN32 215 | #define semaphore_wait(x) WaitForSingleObject(x, INFINITE) 216 | #define semaphore_post(x) ReleaseSemaphore(x, 1, NULL) 217 | #endif // _WIN32 218 | 219 | // Stupid MingW just uses rand() from msvcrt.dll which uses RAND_MAX of 0x7fff 220 | #if RAND_MAX < 0x7fffffff 221 | #define rand32() ((uint32_t)((rand() << 17) | (rand() << 2) | (rand() & 3))) 222 | #elif RAND_MAX < 0xffffffff 223 | #define rand32(x) ((uint32_t)((rand(x) << 1) | (rand(x) & 1))) 224 | #else 225 | #define rand32(x) (uint32_t)rand(x) 226 | #endif 227 | 228 | #if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(NO_SOCKETS) 229 | #define _NTSERVICE 230 | #else 231 | #ifndef NO_TAP 232 | #define NO_TAP 233 | #endif 234 | #endif 235 | 236 | #if (defined(__CYGWIN__) || defined(_WIN32) || defined(NO_SOCKETS)) && !defined(NO_SIGHUP) 237 | #define NO_SIGHUP 238 | #endif // (defined(__CYGWIN__) || defined(_WIN32) || defined(NO_SOCKETS)) && !defined(NO_SIGHUP) 239 | 240 | #ifdef _WIN32 241 | #ifndef USE_THREADS 242 | #define USE_THREADS 243 | #endif 244 | #endif 245 | 246 | #if defined(USE_THREADS) 247 | #define _TLS __thread 248 | #else 249 | #define _TLS 250 | #endif 251 | 252 | #define GUID_STRING_LENGTH 36 253 | 254 | #if defined(_WIN32) 255 | #include 256 | //#include 257 | 258 | typedef char* sockopt_t; 259 | /* Unknown Winsock error codes */ 260 | #define WSAENODEV -1 261 | 262 | // Map VLMCSD error codes to WSAGetLastError() and GetLastError() codes 263 | // Add more if you need them 264 | #define SOCKET_EADDRINUSE WSAEADDRINUSE 265 | #define SOCKET_ENODEV WSAENODEV 266 | #define SOCKET_EADDRNOTAVAIL WSAEADDRNOTAVAIL 267 | #define SOCKET_EACCES WSAEACCES 268 | #define SOCKET_EINVAL WSAEINVAL 269 | #define SOCKET_ENOTSOCK WSAENOTSOCK 270 | #define SOCKET_EINTR WSAEINTR 271 | #define SOCKET_EINPROGRESS WSAEINPROGRESS 272 | #define SOCKET_ECONNABORTED WSAECONNABORTED 273 | #define SOCKET_EALREADY WSAEALREADY 274 | 275 | #define VLMCSD_EACCES ERROR_ACCESS_DENIED 276 | #define VLMCSD_EINVAL ERROR_INVALID_PARAMETER 277 | #define VLMCSD_ENOMEM ERROR_OUTOFMEMORY 278 | #define VLMCSD_EPERM ERROR_CAN_NOT_COMPLETE 279 | 280 | 281 | #define socket_errno WSAGetLastError() 282 | #define socketclose(x) (closesocket(x)) 283 | #define vlmcsd_strerror(x) win_strerror(x) 284 | #define VLMCSD_SHUT_RD SD_RECEIVE 285 | #define VLMCSD_SHUT_WR SD_SEND 286 | #define VLMCSD_SHUT_RDWR SD_BOTH 287 | 288 | #elif defined(__CYGWIN__) 289 | #include 290 | 291 | 292 | // Resolve conflicts between OpenSSL and MS Crypto API 293 | #ifdef _CRYPTO_OPENSSL 294 | #undef OCSP_RESPONSE 295 | #undef X509_NAME 296 | #endif 297 | 298 | #else 299 | typedef uint32_t DWORD; 300 | typedef uint16_t WORD; 301 | typedef uint8_t BYTE; 302 | typedef uint16_t WCHAR; 303 | typedef int32_t BOOL; 304 | typedef int32_t HRESULT; 305 | #define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0) 306 | #define FAILED(hr) (((HRESULT)(hr)) < 0) 307 | #define S_OK ((HRESULT)0) 308 | 309 | 310 | #define FALSE 0 311 | #define TRUE !0 312 | 313 | typedef struct { 314 | DWORD Data1; 315 | WORD Data2; 316 | WORD Data3; 317 | BYTE Data4[8]; 318 | } /*__packed*/ GUID; 319 | 320 | typedef struct { 321 | DWORD dwLowDateTime; 322 | DWORD dwHighDateTime; 323 | } /*__packed*/ FILETIME; 324 | 325 | #endif // defined(__CYGWIN__) 326 | 327 | #ifndef _WIN32 328 | // Map VLMCSD error codes to POSIX codes 329 | // Add more if you need them 330 | #define SOCKET_EADDRINUSE EADDRINUSE 331 | #define SOCKET_ENODEV ENODEV 332 | #define SOCKET_EADDRNOTAVAIL EADDRNOTAVAIL 333 | #define SOCKET_EACCES EACCES 334 | #define SOCKET_EINVAL EINVAL 335 | #define SOCKET_ENOTSOCK ENOTSOCK 336 | #define SOCKET_EINTR EINTR 337 | #define SOCKET_EINPROGRESS EINPROGRESS 338 | #define SOCKET_ECONNABORTED ECONNABORTED 339 | #define SOCKET_EALREADY EALREADY 340 | 341 | #define VLMCSD_EACCES EACCES 342 | #define VLMCSD_EINVAL EINVAL 343 | #define VLMCSD_EINTR EINTR 344 | #define VLMCSD_ENOMEM ENOMEM 345 | #define VLMCSD_EPERM EPERM 346 | 347 | typedef void* sockopt_t; 348 | #define _countof(x) ( sizeof(x) / sizeof(x[0]) ) 349 | #define SOCKET int 350 | #define INVALID_SOCKET -1 351 | #define socket_errno errno 352 | #define socketclose(x) (close(x)) 353 | #define vlmcsd_strerror strerror 354 | #define VLMCSD_SHUT_RD SHUT_RD 355 | #define VLMCSD_SHUT_WR SHUT_WR 356 | #define VLMCSD_SHUT_RDWR SHUT_RDWR 357 | 358 | #endif // __MINGW__ 359 | #define INVALID_UID ((uid_t)~0) 360 | #define INVALID_GID ((gid_t)~0) 361 | 362 | #undef IsEqualGUID 363 | #define IsEqualGUID(a, b) ( !memcmp(a, b, sizeof(GUID)) ) 364 | 365 | #if !defined(__stdcall) && !_MSC_VER 366 | #define __stdcall 367 | #endif 368 | 369 | #if !defined(__cdecl) && !_MSC_VER 370 | #define __cdecl 371 | #endif 372 | 373 | typedef const char *const * CARGV; 374 | 375 | typedef struct { 376 | SOCKET socket; 377 | DWORD RpcAssocGroup; 378 | } CLDATA, *const PCLDATA; 379 | 380 | 381 | #ifdef _MSC_VER 382 | #define strcasecmp _stricmp 383 | #define strncasecmp _strnicmp 384 | #define vlmcsd_snprintf _snprintf 385 | #define vlmcsd_vsnprintf _vsnprintf 386 | #define vlmcsd_unlink DeleteFile 387 | #define vlmcsd_strtoll _strtoi64 388 | #else // !_MSC_VER 389 | #define vlmcsd_snprintf snprintf 390 | #define vlmcsd_vsnprintf vsnprintf 391 | #define vlmcsd_strtoll strtoll 392 | #define vlmcsd_unlink unlink 393 | #endif // !_MSC_VER 394 | 395 | #endif // __types_h 396 | -------------------------------------------------------------------------------- /crates/kms-sys/src/crypto.c: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG 2 | #define CONFIG "config.h" 3 | #endif // CONFIG 4 | #include CONFIG 5 | 6 | #include "crypto.h" 7 | #include "endian.h" 8 | #include 9 | 10 | const BYTE AesKeyV4[] = { 11 | 0x05, 0x3D, 0x83, 0x07, 0xF9, 0xE5, 0xF0, 0x88, 0xEB, 0x5E, 0xA6, 0x68, 0x6C, 0xF0, 0x37, 0xC7, 0xE4, 0xEF, 0xD2, 0xD6}; 12 | 13 | const BYTE AesKeyV5[] = { 14 | 0xCD, 0x7E, 0x79, 0x6F, 0x2A, 0xB2, 0x5D, 0xCB, 0x55, 0xFF, 0xC8, 0xEF, 0x83, 0x64, 0xC4, 0x70 }; 15 | 16 | const BYTE AesKeyV6[] = { 17 | 0xA9, 0x4A, 0x41, 0x95, 0xE2, 0x01, 0x43, 0x2D, 0x9B, 0xCB, 0x46, 0x04, 0x05, 0xD8, 0x4A, 0x21 }; 18 | 19 | static const BYTE SBox[] = { 20 | 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 21 | 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 22 | 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 23 | 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, 24 | 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 25 | 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 26 | 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 27 | 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 28 | 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 29 | 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 30 | 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 31 | 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 32 | 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 33 | 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 34 | 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 35 | 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 36 | }; 37 | 38 | 39 | void XorBlock(const BYTE *const in, const BYTE *out) // Ensure that this is always 32 bit aligned 40 | { 41 | /*UAA64( out, 0 ) ^= UAA64( in, 0 ); 42 | UAA64( out, 1 ) ^= UAA64( in, 1 );*/ 43 | 44 | uint_fast8_t i; 45 | 46 | for (i = 0; i < AES_BLOCK_WORDS; i++) 47 | { 48 | ((DWORD*)out)[i] ^= ((DWORD*)in)[i]; 49 | } 50 | } 51 | 52 | #define AddRoundKey(d, rk) XorBlock((const BYTE *)rk, (const BYTE *)d) 53 | 54 | #define Mul2(word) (((word & 0x7f7f7f7f) << 1) ^ (((word & 0x80808080) >> 7) * 0x1b)) 55 | #define Mul3(word) (Mul2(word) ^ word) 56 | #define Mul4(word) (Mul2(Mul2(word))) 57 | #define Mul8(word) (Mul2(Mul2(Mul2(word)))) 58 | #define Mul9(word) (Mul8(word) ^ word) 59 | #define MulB(word) (Mul8(word) ^ Mul3(word)) 60 | #define MulD(word) (Mul8(word) ^ Mul4(word) ^ word) 61 | #define MulE(word) (Mul8(word) ^ Mul4(word) ^ Mul2(word)) 62 | 63 | //32 bit Galois Multiplication (generates bigger code than Macros) 64 | /*static DWORD Mul(DWORD x, DWORD y) 65 | { 66 | DWORD result = x, yTemp = y, log2; 67 | 68 | if (!y) return 0; 69 | 70 | for (log2 = 0; yTemp >>= 1; log2++ ) 71 | { 72 | result = Mul2(result); 73 | } 74 | 75 | return result ^ Mul(x, y - (1 << log2)); 76 | }*/ 77 | 78 | 79 | void MixColumnsR(BYTE *restrict state) 80 | { 81 | uint_fast8_t i = 0; 82 | for (; i < AES_BLOCK_WORDS; i++) 83 | { 84 | #if defined(_CRYPTO_OPENSSL) && defined(_OPENSSL_SOFTWARE) && defined(_USE_AES_FROM_OPENSSL) //Always byte swap regardless of endianess 85 | DWORD word = BS32(((DWORD *) state)[i]); 86 | ((DWORD *) state)[i] = BS32(MulE(word) ^ ROR32(MulB(word), 8) ^ ROR32(MulD(word), 16) ^ ROR32(Mul9(word), 24)); 87 | #else 88 | DWORD word = LE32(((DWORD *) state)[i]); 89 | ((DWORD *) state)[i] = LE32(MulE(word) ^ ROR32(MulB(word), 8) ^ ROR32(MulD(word), 16) ^ ROR32(Mul9(word), 24)); 90 | #endif 91 | } 92 | } 93 | 94 | 95 | static DWORD SubDword(DWORD v) 96 | { 97 | BYTE *b = (BYTE *)&v; 98 | uint_fast8_t i = 0; 99 | 100 | for (; i < sizeof(DWORD); i++) b[i] = SBox[b[i]]; 101 | 102 | return v; 103 | } 104 | 105 | 106 | void AesInitKey(AesCtx *Ctx, const BYTE *Key, int_fast8_t IsV6, int RijndaelKeyBytes) 107 | { 108 | int RijndaelKeyDwords = RijndaelKeyBytes / sizeof(DWORD); 109 | Ctx->rounds = (uint_fast8_t)(RijndaelKeyDwords + 6); 110 | 111 | static const DWORD RCon[] = { 112 | 0x00000000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 113 | 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000 }; 114 | 115 | uint_fast8_t i; 116 | DWORD temp; 117 | 118 | memcpy(Ctx->Key, Key, RijndaelKeyBytes); 119 | 120 | for ( i = (uint_fast8_t)RijndaelKeyDwords; i < ( Ctx->rounds + 1 ) << 2; i++ ) 121 | { 122 | temp = Ctx->Key[ i - 1 ]; 123 | 124 | if ( ( i % RijndaelKeyDwords ) == 0 ) 125 | temp = BE32( SubDword( ROR32( BE32(temp), 24) ) ^ RCon[ i / RijndaelKeyDwords ] ); 126 | 127 | Ctx->Key[ i ] = Ctx->Key[ i - RijndaelKeyDwords ] ^ temp; 128 | } 129 | 130 | if ( IsV6 ) 131 | { 132 | BYTE *_p = (BYTE *)Ctx->Key; 133 | 134 | _p[ 4 * 16 ] ^= 0x73; 135 | _p[ 6 * 16 ] ^= 0x09; 136 | _p[ 8 * 16 ] ^= 0xE4; 137 | } 138 | } 139 | 140 | 141 | #if !defined(_CRYPTO_OPENSSL) || !defined(_USE_AES_FROM_OPENSSL) || defined(_OPENSSL_SOFTWARE) 142 | static void SubBytes(BYTE *block) 143 | { 144 | uint_fast8_t i; 145 | 146 | for (i = 0; i < AES_BLOCK_BYTES; i++) 147 | block[i] = SBox[ block[i] ]; 148 | } 149 | 150 | 151 | static void ShiftRows(BYTE *state) 152 | { 153 | BYTE bIn[AES_BLOCK_BYTES]; 154 | uint_fast8_t i; 155 | 156 | memcpy(bIn, state, AES_BLOCK_BYTES); 157 | for (i = 0; i < AES_BLOCK_BYTES; i++) 158 | { 159 | state[i] = bIn[(i + ((i & 3) << 2)) & 0xf]; 160 | } 161 | }; 162 | 163 | 164 | static void MixColumns(BYTE *state) 165 | { 166 | uint_fast8_t i = 0; 167 | for (; i < AES_BLOCK_WORDS; i++) 168 | { 169 | DWORD word = LE32(((DWORD *) state)[i]); 170 | ((DWORD *) state)[i] = LE32(Mul2(word) ^ ROR32(Mul3(word), 8) ^ ROR32(word, 16) ^ ROR32(word, 24)); 171 | } 172 | } 173 | 174 | 175 | void AesEncryptBlock(const AesCtx *const Ctx, BYTE *block) 176 | { 177 | uint_fast8_t i; 178 | 179 | for ( i = 0 ;; i += 4 ) 180 | { 181 | AddRoundKey(block, &Ctx->Key[ i ]); 182 | SubBytes(block); 183 | ShiftRows(block); 184 | 185 | if ( i >= ( Ctx->rounds - 1 ) << 2 ) break; 186 | 187 | MixColumns(block); 188 | } 189 | 190 | AddRoundKey(block, &Ctx->Key[ Ctx->rounds << 2 ]); 191 | } 192 | 193 | 194 | void AesCmacV4(BYTE *Message, size_t MessageSize, BYTE *MacOut) 195 | { 196 | size_t i; 197 | BYTE mac[AES_BLOCK_BYTES]; 198 | AesCtx Ctx; 199 | 200 | AesInitKey(&Ctx, AesKeyV4, FALSE, V4_KEY_BYTES); 201 | 202 | memset(mac, 0, sizeof(mac)); 203 | memset(Message + MessageSize, 0, AES_BLOCK_BYTES); 204 | Message[MessageSize] = 0x80; 205 | 206 | for (i = 0; i <= MessageSize; i += AES_BLOCK_BYTES) 207 | { 208 | XorBlock(Message + i, mac); 209 | AesEncryptBlock(&Ctx, mac); 210 | } 211 | 212 | memcpy(MacOut, mac, AES_BLOCK_BYTES); 213 | } 214 | #endif 215 | 216 | #if !defined(_CRYPTO_OPENSSL) || !defined(_USE_AES_FROM_OPENSSL) 217 | 218 | #ifndef SMALL_AES 219 | 220 | static const BYTE SBoxR[] = { 221 | 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, 222 | 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 223 | 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, 224 | 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, 225 | 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 226 | 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, 227 | 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, 228 | 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 229 | 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, 230 | 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, 231 | 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 232 | 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, 233 | 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, 234 | 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 235 | 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, 236 | 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D 237 | }; 238 | 239 | #define GetSBoxR(x) SBoxR[x] 240 | 241 | #else // SMALL_AES 242 | 243 | static uint8_t SBoxR(uint8_t byte) 244 | { 245 | uint8_t i; 246 | 247 | for (i = 0; TRUE; i++) 248 | { 249 | if (byte == SBox[i]) return i; 250 | } 251 | } 252 | 253 | #define GetSBoxR(x) SBoxR(x) 254 | 255 | #endif // SMALL_AES 256 | 257 | 258 | static void ShiftRowsR(BYTE *state) 259 | { 260 | BYTE b[AES_BLOCK_BYTES]; 261 | uint_fast8_t i; 262 | 263 | memcpy(b, state, AES_BLOCK_BYTES); 264 | 265 | for (i = 0; i < AES_BLOCK_BYTES; i++) 266 | state[i] = b[(i - ((i & 0x3) << 2)) & 0xf]; 267 | } 268 | 269 | 270 | static void SubBytesR(BYTE *block) 271 | { 272 | uint_fast8_t i; 273 | 274 | for (i = 0; i < AES_BLOCK_BYTES; i++) 275 | { 276 | block[i] = GetSBoxR( block[i] ); 277 | } 278 | } 279 | 280 | 281 | void AesEncryptCbc(const AesCtx *const Ctx, BYTE *restrict iv, BYTE *restrict data, size_t *restrict len) 282 | { 283 | // Pad up to blocksize inclusive 284 | size_t i; 285 | uint_fast8_t pad = (~*len & (AES_BLOCK_BYTES - 1)) + 1; 286 | 287 | #if defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ == 8) // gcc 4.8 memset bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56977 288 | for (i = 0; i < pad; i++) data[*len + i] = pad; 289 | #else 290 | memset(data + *len, pad, pad); 291 | #endif 292 | *len += pad; 293 | 294 | if ( iv ) XorBlock(iv, data); 295 | AesEncryptBlock(Ctx, data); 296 | 297 | for (i = *len - AES_BLOCK_BYTES; i; i -= AES_BLOCK_BYTES) 298 | { 299 | XorBlock(data, data + AES_BLOCK_BYTES); 300 | data += AES_BLOCK_BYTES; 301 | AesEncryptBlock(Ctx, data); 302 | } 303 | } 304 | 305 | 306 | void AesDecryptBlock(const AesCtx *const Ctx, BYTE *block) 307 | { 308 | uint_fast8_t i; 309 | 310 | AddRoundKey(block, &Ctx->Key[ Ctx->rounds << 2 ]); 311 | 312 | for ( i = ( Ctx->rounds - 1 ) << 2 ;; i -= 4 ) 313 | { 314 | ShiftRowsR(block); 315 | SubBytesR(block); 316 | AddRoundKey(block, &Ctx->Key[ i ]); 317 | 318 | if ( i == 0 ) break; 319 | 320 | MixColumnsR(block); 321 | } 322 | } 323 | 324 | 325 | void AesDecryptCbc(const AesCtx *const Ctx, BYTE *iv, BYTE *data, size_t len) 326 | { 327 | BYTE *cc; 328 | 329 | for (cc = data + len - AES_BLOCK_BYTES; cc > data; cc -= AES_BLOCK_BYTES) 330 | { 331 | AesDecryptBlock(Ctx, cc); 332 | XorBlock(cc - AES_BLOCK_BYTES, cc); 333 | } 334 | 335 | AesDecryptBlock(Ctx, cc); 336 | if ( iv ) XorBlock(iv, cc); 337 | } 338 | #endif // _CRYPTO_OPENSSL || OPENSSL_VERSION_NUMBER < 0x10000000L 339 | -------------------------------------------------------------------------------- /crates/kms-sys/src/kms.h: -------------------------------------------------------------------------------- 1 | #ifndef __kms_h 2 | #define __kms_h 3 | 4 | #ifndef CONFIG 5 | #define CONFIG "config.h" 6 | #endif // CONFIG 7 | #include CONFIG 8 | 9 | #if _MSC_VER 10 | //#include 11 | #else 12 | #include 13 | #endif // _MSC_VER 14 | //#include 15 | #include "types.h" 16 | // 17 | // REQUEST... types are actually fixed size 18 | // RESPONSE... size may vary, defined here is max possible size 19 | // 20 | 21 | #define MAX_RESPONSE_SIZE 384 22 | #define PID_BUFFER_SIZE 64 23 | #define MAX_REQUEST_SIZE sizeof(REQUEST_V6) 24 | #define WORKSTATION_NAME_BUFFER 64 25 | 26 | // Constants for V6 time stamp interval 27 | #define TIME_C1 0x00000022816889BDULL 28 | #define TIME_C2 0x000000208CBAB5EDULL 29 | #define TIME_C3 0x3156CD5AC628477AULL 30 | 31 | #define VERSION_INFO union \ 32 | { \ 33 | DWORD Version;\ 34 | struct { \ 35 | WORD MinorVer; \ 36 | WORD MajorVer; \ 37 | } /*__packed*/; \ 38 | } /*__packed*/ 39 | 40 | // Aliases for various KMS struct members 41 | #define IsClientVM VMInfo 42 | #define GraceTime BindingExpiration 43 | #define MinutesRemaingInCurrentStatus BindingExpiration 44 | #define ID ActID 45 | #define ApplicationID AppID 46 | #define SkuId ActID 47 | #define KmsId KMSID 48 | #define ClientMachineId CMID 49 | #define MinimumClients N_Policy 50 | #define TimeStamp ClientTime 51 | #define PreviousCLientMachineId CMID_prev 52 | #define Salt IV 53 | #define XorSalt XoredIVs 54 | #define ActivationInterval VLActivationInterval 55 | #define RenewalInterval VLRenewalInterval 56 | 57 | #define MAX_CLIENTS 671 58 | 59 | typedef struct 60 | { 61 | GUID Guid[MAX_CLIENTS]; 62 | int_fast16_t CurrentCount; 63 | int_fast16_t MaxCount; 64 | int_fast16_t CurrentPosition; 65 | } ClientList_t, *PClientList_t; 66 | 67 | typedef struct { 68 | VERSION_INFO; 69 | DWORD VMInfo; // 0 = client is bare metal / 1 = client is VM 70 | DWORD LicenseStatus; // 0 = Unlicensed, 1 = Licensed (Activated), 2 = OOB grace, 3 = OOT grace, 4 = NonGenuineGrace, 5 = Notification, 6 = extended grace 71 | DWORD BindingExpiration; // Expiration of the current status in minutes (e.g. when KMS activation or OOB grace expires). 72 | GUID AppID; // Can currently be Windows, Office2010 or Office2013 (see kms.c, table AppList). 73 | GUID ActID; // Most detailed product list. One product key per ActID (see kms.c, table ExtendedProductList). Is ignored by KMS server. 74 | GUID KMSID; // This is actually what the KMS server uses to grant or refuse activation (see kms.c, table BasicProductList). 75 | GUID CMID; // Client machine id. Used by the KMS server for counting minimum clients. 76 | DWORD N_Policy; // Minimum clients required for activation. 77 | FILETIME ClientTime; // Current client time. 78 | GUID CMID_prev; // previous client machine id. All zeros, if it never changed. 79 | WCHAR WorkstationName[64]; // Workstation name. FQDN if available, NetBIOS otherwise. 80 | } /*__packed*/ REQUEST; 81 | 82 | typedef struct { 83 | VERSION_INFO; 84 | DWORD PIDSize; // Size of PIDData in bytes. 85 | WCHAR KmsPID[PID_BUFFER_SIZE]; // ePID (must include terminating zero) 86 | GUID CMID; // Client machine id. Must be the same as in request. 87 | FILETIME ClientTime; // Current client time. Must be the same as in request. 88 | DWORD Count; // Current activated machines. KMS server counts up to N_Policy << 1 then stops 89 | DWORD VLActivationInterval; // Time in minutes when clients should retry activation if it was unsuccessful (default 2 hours) 90 | DWORD VLRenewalInterval; // Time in minutes when clients should renew KMS activation (default 7 days) 91 | } /*__packed*/ RESPONSE; 92 | 93 | #ifdef _DEBUG 94 | typedef struct { 95 | VERSION_INFO; 96 | DWORD PIDSize; 97 | WCHAR KmsPID[49]; // Set this to the ePID length you want to debug 98 | GUID CMID; 99 | FILETIME ClientTime; 100 | DWORD Count; 101 | DWORD VLActivationInterval; 102 | DWORD VLRenewalInterval; 103 | } __packed RESPONSE_DEBUG; 104 | #endif 105 | 106 | 107 | typedef struct { 108 | REQUEST RequestBase; // Base request 109 | BYTE MAC[16]; // Aes 160 bit CMAC 110 | } /*__packed*/ REQUEST_V4; 111 | 112 | typedef struct { 113 | RESPONSE ResponseBase; // Base response 114 | BYTE MAC[16]; // Aes 160 bit CMAC 115 | } /*__packed*/ RESPONSE_V4; 116 | 117 | 118 | typedef struct { 119 | VERSION_INFO; // unencrypted version info 120 | BYTE IV[16]; // IV 121 | REQUEST RequestBase; // Base Request 122 | BYTE Pad[4]; // since this struct is fixed, we use fixed PKCS pad bytes 123 | } /*__packed*/ REQUEST_V5; 124 | 125 | typedef REQUEST_V5 REQUEST_V6; // v5 and v6 requests are identical 126 | 127 | typedef struct { 128 | VERSION_INFO; 129 | BYTE IV[16]; 130 | RESPONSE ResponseBase; 131 | 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 132 | BYTE Hash[32]; // SHA256 of Random used in RandomXoredIVs 133 | BYTE HwId[8]; // HwId from the KMS server 134 | BYTE XoredIVs[16]; // If RequestIV was used for decryption: decrypted Request IV ^ ResponseIV. If NULL IV was used for decryption: decrypted Request IV. 135 | BYTE HMAC[16]; // V6 Hmac (low 16 bytes only), see kms.c CreateV6Hmac 136 | //BYTE Pad[10]; // Pad is variable sized. So do not include in struct 137 | } /*__packed*/ RESPONSE_V6; 138 | 139 | typedef struct { // not used except for sizeof(). Fields are the same as RESPONSE_V6 140 | VERSION_INFO; 141 | BYTE IV[16]; 142 | RESPONSE ResponseBase; 143 | BYTE RandomXoredIVs[16]; 144 | BYTE Hash[32]; 145 | } /*__packed*/ RESPONSE_V5; 146 | 147 | #ifdef _DEBUG 148 | typedef struct { // Debug structure for direct casting of RPC data in debugger 149 | VERSION_INFO; 150 | BYTE IV[16]; 151 | RESPONSE_DEBUG ResponseBase; 152 | BYTE RandomXoredIVs[16]; 153 | BYTE MAC[32]; 154 | BYTE Unknown[8]; 155 | BYTE XorSalts[16]; 156 | BYTE HMAC[16]; 157 | BYTE Pad[16]; 158 | } __packed RESPONSE_V6_DEBUG; 159 | #endif 160 | 161 | #define V4_PRE_EPID_SIZE ( \ 162 | sizeof(((RESPONSE*)0)->Version) + \ 163 | sizeof(((RESPONSE*)0)->PIDSize) \ 164 | ) 165 | 166 | #define V4_POST_EPID_SIZE ( \ 167 | sizeof(((RESPONSE*)0)->CMID) + \ 168 | sizeof(((RESPONSE*)0)->ClientTime) + \ 169 | sizeof(((RESPONSE*)0)->Count) + \ 170 | sizeof(((RESPONSE*)0)->VLActivationInterval) + \ 171 | sizeof(((RESPONSE*)0)->VLRenewalInterval) \ 172 | ) 173 | 174 | #define V6_DECRYPT_SIZE ( \ 175 | sizeof(((REQUEST_V6*)0)->IV) + \ 176 | sizeof(((REQUEST_V6*)0)->RequestBase) + \ 177 | sizeof(((REQUEST_V6*)0)->Pad) \ 178 | ) 179 | 180 | #define V6_UNENCRYPTED_SIZE ( \ 181 | sizeof(((RESPONSE_V6*)0)->Version) + \ 182 | sizeof(((RESPONSE_V6*)0)->IV) \ 183 | ) 184 | 185 | #define V6_PRE_EPID_SIZE ( \ 186 | V6_UNENCRYPTED_SIZE + \ 187 | sizeof(((RESPONSE*)0)->Version) + \ 188 | sizeof(((RESPONSE*)0)->PIDSize) \ 189 | ) 190 | 191 | #define V5_POST_EPID_SIZE ( \ 192 | V4_POST_EPID_SIZE + \ 193 | sizeof(((RESPONSE_V6*)0)->RandomXoredIVs) + \ 194 | sizeof(((RESPONSE_V6*)0)->Hash) \ 195 | ) 196 | 197 | #define V6_POST_EPID_SIZE ( \ 198 | V5_POST_EPID_SIZE + \ 199 | sizeof(((RESPONSE_V6*)0)->HwId) + \ 200 | sizeof(((RESPONSE_V6*)0)->XoredIVs) + \ 201 | sizeof(((RESPONSE_V6*)0)->HMAC) \ 202 | ) 203 | 204 | #define RESPONSE_RESULT_OK ((1 << 10) - 1) //(9 bits) 205 | typedef union 206 | { 207 | DWORD mask; 208 | struct 209 | { 210 | BOOL HashOK : 1; 211 | BOOL TimeStampOK : 1; 212 | BOOL ClientMachineIDOK : 1; 213 | BOOL VersionOK : 1; 214 | BOOL IVsOK : 1; 215 | BOOL DecryptSuccess : 1; 216 | BOOL HmacSha256OK : 1; 217 | BOOL PidLengthOK : 1; 218 | BOOL RpcOK : 1; 219 | BOOL IVnotSuspicious : 1; 220 | BOOL reserved3 : 1; 221 | BOOL reserved4 : 1; 222 | BOOL reserved5 : 1; 223 | BOOL reserved6 : 1; 224 | uint32_t effectiveResponseSize : 9; 225 | uint32_t correctResponseSize : 9; 226 | }; 227 | } RESPONSE_RESULT; 228 | 229 | typedef BYTE hwid_t[8]; 230 | 231 | typedef enum 232 | { 233 | None = 0, 234 | UseNdr64 = 1 << 0, 235 | UseForEpid = 1 << 1, 236 | MayBeServer = 1 << 2, 237 | } HostBuildFlag; 238 | 239 | typedef struct CsvlkData 240 | { 241 | union 242 | { 243 | uint64_t EPidOffset; 244 | char* EPid; 245 | }; 246 | 247 | int64_t ReleaseDate; 248 | uint32_t GroupId; 249 | uint32_t MinKeyId; 250 | uint32_t MaxKeyId; 251 | uint8_t MinActiveClients; 252 | uint8_t Reserved[3]; 253 | 254 | } CsvlkData_t, *PCsvlkData_t; 255 | 256 | typedef struct VlmcsdData 257 | { 258 | union 259 | { 260 | GUID Guid; 261 | uint8_t GuidBytes[16]; 262 | }; 263 | 264 | union 265 | { 266 | uint64_t NameOffset; 267 | char* Name; 268 | }; 269 | 270 | uint8_t AppIndex; 271 | uint8_t KmsIndex; 272 | uint8_t ProtocolVersion; 273 | uint8_t NCountPolicy; 274 | uint8_t IsRetail; 275 | uint8_t IsPreview; 276 | uint8_t EPidIndex; 277 | uint8_t reserved; 278 | 279 | } VlmcsdData_t, *PVlmcsdData_t; 280 | 281 | typedef struct 282 | { 283 | union 284 | { 285 | uint64_t Offset; 286 | void* Pointer; 287 | }; 288 | } DataPointer_t; 289 | 290 | #define KMS_OPTIONS_USENDR64 1 << 0 291 | 292 | typedef struct HostBuild 293 | { 294 | union 295 | { 296 | uint64_t DisplayNameOffset; 297 | char* DisplayName; 298 | }; 299 | 300 | int64_t ReleaseDate; 301 | int32_t BuildNumber; 302 | int32_t PlatformId; 303 | HostBuildFlag Flags; 304 | uint8_t reserved[4]; 305 | 306 | } HostBuild_t, *PHostBuild_t; 307 | 308 | typedef struct VlmcsdHeader 309 | { 310 | BYTE Magic[4]; 311 | VERSION_INFO; 312 | uint8_t CsvlkCount; 313 | uint8_t Flags; 314 | uint8_t Reserved[2]; 315 | 316 | union 317 | { 318 | int32_t Counts[5]; 319 | 320 | struct 321 | { 322 | int32_t AppItemCount; 323 | int32_t KmsItemCount; 324 | int32_t SkuItemCount; 325 | int32_t HostBuildCount; 326 | int32_t reserved2Counts; 327 | }; 328 | }; 329 | 330 | union 331 | { 332 | DataPointer_t Datapointers[5]; 333 | 334 | struct 335 | { 336 | union 337 | { 338 | uint64_t AppItemOffset; 339 | PVlmcsdData_t AppItemList; 340 | }; 341 | 342 | union 343 | { 344 | uint64_t KmsItemOffset; 345 | PVlmcsdData_t KmsItemList; 346 | }; 347 | 348 | union 349 | { 350 | uint64_t SkuItemOffset; 351 | PVlmcsdData_t SkuItemList; 352 | }; 353 | 354 | union 355 | { 356 | uint64_t HostBuildOffset; 357 | PHostBuild_t HostBuildList; 358 | }; 359 | 360 | union 361 | { 362 | uint64_t Reserved2Offset; 363 | void* Reserved2List; 364 | }; 365 | 366 | CsvlkData_t CsvlkData[1]; 367 | }; 368 | }; 369 | 370 | } VlmcsdHeader_t, *PVlmcsdHeader_t; 371 | 372 | //#define EPID_INDEX_WINDOWS 0 373 | //#define EPID_INDEX_OFFICE2010 1 374 | //#define EPID_INDEX_OFFICE2013 2 375 | //#define EPID_INDEX_OFFICE2016 3 376 | //#define EPID_INDEX_WINCHINAGOV 4 377 | 378 | typedef HRESULT(__stdcall *RequestCallback_t)(REQUEST* baseRequest, RESPONSE *const baseResponse, BYTE *const hwId, const char* const ipstr); 379 | 380 | size_t CreateResponseV4(REQUEST_V4 *const Request, BYTE *const response_data, const char* const ipstr); 381 | size_t CreateResponseV6(REQUEST_V6 *restrict Request, BYTE *const response_data, const char* const ipstr); 382 | BYTE *CreateRequestV4(size_t *size, const REQUEST* requestBase); 383 | BYTE *CreateRequestV6(size_t *size, const REQUEST* requestBase); 384 | void randomPidInit(); 385 | void get16RandomBytes(void* ptr); 386 | RESPONSE_RESULT DecryptResponseV6(RESPONSE_V6* response_v6, int responseSize, BYTE* const response, const BYTE* const rawRequest, BYTE* hwid); 387 | RESPONSE_RESULT DecryptResponseV4(RESPONSE_V4* response_v4, const int responseSize, BYTE* const rawResponse, const BYTE* const rawRequest); 388 | void getUnixTimeAsFileTime(FILETIME* ts); 389 | __pure int64_t fileTimeToUnixTime(FILETIME* ts); 390 | 391 | #ifndef IS_LIBRARY 392 | int32_t getProductIndex(const GUID* guid, const PVlmcsdData_t list, const int32_t count, char** name, char** ePid); 393 | #if !defined(NO_INI_FILE)||!defined(NO_VERBOSE_LOG) 394 | const char* getNextString(const char* s); 395 | #endif // !defined(NO_INI_FILE)||!defined(NO_VERBOSE_LOG) 396 | #endif // IS_LIBRARY 397 | 398 | #ifndef NO_STRICT_MODES 399 | void InitializeClientLists(); 400 | void CleanUpClientLists(); 401 | #endif // !NO_STRICT_MODES 402 | 403 | extern RequestCallback_t CreateResponseBase; 404 | 405 | #ifdef _PEDANTIC 406 | uint16_t IsValidLcid(const uint16_t lcid); 407 | uint32_t IsValidHostBuild(const int32_t hostBuild); 408 | #endif // _PEDANTIC 409 | 410 | #endif // __kms_h 411 | -------------------------------------------------------------------------------- /crates/kms-sys/src/output.c: -------------------------------------------------------------------------------- 1 | #ifndef _DEFAULT_SOURCE 2 | #define _DEFAULT_SOURCE 3 | #endif // _DEFAULT_SOURCE 4 | 5 | #ifndef _CRT_SECURE_NO_WARNINGS 6 | #define _CRT_SECURE_NO_WARNINGS 7 | #endif 8 | 9 | #ifndef CONFIG 10 | #define CONFIG "config.h" 11 | #endif // CONFIG 12 | #include CONFIG 13 | 14 | #include "output.h" 15 | #include "shared_globals.h" 16 | #include "endian.h" 17 | #include "helpers.h" 18 | 19 | // ReSharper disable All 20 | 21 | #ifndef NO_LOG 22 | static void vlogger(const char *message, va_list args) 23 | { 24 | FILE *log; 25 | 26 | # ifdef _NTSERVICE 27 | if (!IsNTService && logstdout) log = stdout; 28 | # else 29 | if (logstdout) log = stdout; 30 | # endif 31 | else 32 | { 33 | if (fn_log == NULL) return; 34 | 35 | # ifndef _WIN32 36 | if (!strcmp(fn_log, "syslog")) 37 | { 38 | openlog("vlmcsd", LOG_CONS | LOG_PID, LOG_USER); 39 | 40 | ////PORTABILITY: vsyslog is not in Posix but virtually all Unixes have it 41 | vsyslog(LOG_INFO, message, args); 42 | 43 | closelog(); 44 | return; 45 | } 46 | # endif // _WIN32 47 | 48 | log = fopen(fn_log, "a"); 49 | if (!log) return; 50 | } 51 | 52 | time_t now = time(0); 53 | 54 | # ifdef USE_THREADS 55 | char mbstr[2048]; 56 | # else 57 | char mbstr[24]; 58 | # endif 59 | 60 | if (LogDateAndTime) 61 | strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %X: ", localtime(&now)); 62 | else 63 | *mbstr = 0; 64 | 65 | # ifndef USE_THREADS 66 | 67 | fprintf(log, "%s", mbstr); 68 | vfprintf(log, message, args); 69 | fflush(log); 70 | 71 | # else // USE_THREADS 72 | 73 | // We write everything to a string before we really log inside the critical section 74 | // so formatting the output can be concurrent 75 | int len = (int)strlen(mbstr); 76 | //# if !_MSC_VER 77 | 78 | vlmcsd_vsnprintf(mbstr + len, sizeof(mbstr) - len, message, args); 79 | //# else 80 | // wvsprintf(mbstr + len, message, args); 81 | //# endif 82 | 83 | lock_mutex(&logmutex); 84 | fprintf(log, "%s", mbstr); 85 | fflush(log); 86 | unlock_mutex(&logmutex); 87 | 88 | # endif // USE_THREADS 89 | if (log != stdout) fclose(log); 90 | } 91 | 92 | 93 | // Always sends to log output 94 | int logger(const char *const fmt, ...) 95 | { 96 | va_list args; 97 | 98 | va_start(args, fmt); 99 | vlogger(fmt, args); 100 | va_end(args); 101 | return 0; 102 | } 103 | 104 | #endif //NO_LOG 105 | 106 | 107 | // Output to stderr if it is available or to log otherwise (e.g. if running as daemon/service) 108 | int printerrorf(const char *const fmt, ...) 109 | { 110 | int error = errno; 111 | va_list arglist; 112 | 113 | va_start(arglist, fmt); 114 | 115 | # ifdef IS_LIBRARY 116 | 117 | size_t len = strlen(ErrorMessage); 118 | vlmcsd_vsnprintf(ErrorMessage + len, MESSAGE_BUFFER_SIZE - len - 1, fmt, arglist); 119 | 120 | # else // !IS_LIBRARY 121 | 122 | # ifndef NO_LOG 123 | # ifdef _NTSERVICE 124 | if (InetdMode || IsNTService) 125 | # else // !_NTSERVICE 126 | if (InetdMode) 127 | # endif // NTSERVIICE 128 | vlogger(fmt, arglist); 129 | else 130 | # endif //NO_LOG 131 | 132 | # endif // IS_LIBRARY 133 | { 134 | vfprintf(stderr, fmt, arglist); 135 | fflush(stderr); 136 | } 137 | 138 | va_end(arglist); 139 | errno = error; 140 | return 0; 141 | } 142 | 143 | 144 | // Always output to stderr 145 | int errorout(const char* fmt, ...) 146 | { 147 | va_list args; 148 | 149 | va_start(args, fmt); 150 | int i = vfprintf(stderr, fmt, args); 151 | va_end(args); 152 | fflush(stderr); 153 | 154 | return i; 155 | } 156 | 157 | 158 | #if !defined(NO_VERBOSE_LOG) && !defined(NO_LOG) 159 | static const char *LicenseStatusText[] = 160 | { 161 | "Unlicensed", "Licensed", "OOB grace", "OOT grace", "Non-Genuine", "Notification", "Extended grace" 162 | }; 163 | #endif // !defined(NO_VERBOSE_LOG) && !defined(NO_LOG) 164 | 165 | 166 | void uuid2StringLE(const GUID *const guid, char *const string) 167 | { 168 | sprintf(string, 169 | # ifdef _WIN32 170 | "%08x-%04x-%04x-%04x-%012I64x", 171 | # else 172 | "%08x-%04x-%04x-%04x-%012llx", 173 | # endif 174 | (unsigned int)LE32(guid->Data1), 175 | (unsigned int)LE16(guid->Data2), 176 | (unsigned int)LE16(guid->Data3), 177 | (unsigned int)BE16(*(uint16_t*)guid->Data4), 178 | (unsigned long long)BE64(*(uint64_t*)(guid->Data4)) & 0xffffffffffffLL 179 | ); 180 | } 181 | 182 | #if !defined(NO_VERBOSE_LOG) && !defined(NO_LOG) 183 | void logRequestVerbose(REQUEST* Request, const PRINTFUNC p) 184 | { 185 | char guidBuffer[GUID_STRING_LENGTH + 1]; 186 | char WorkstationBuffer[3 * WORKSTATION_NAME_BUFFER]; 187 | char* productName; 188 | 189 | p("Protocol version : %u.%u\n", LE16(Request->MajorVer), LE16(Request->MinorVer)); 190 | p("Client is a virtual machine : %s\n", LE32(Request->VMInfo) ? "Yes" : "No"); 191 | p("Licensing status : %u (%s)\n", (uint32_t)LE32(Request->LicenseStatus), LE32(Request->LicenseStatus) < vlmcsd_countof(LicenseStatusText) ? LicenseStatusText[LE32(Request->LicenseStatus)] : "Unknown"); 192 | p("Remaining time (0 = forever) : %i minutes\n", (uint32_t)LE32(Request->BindingExpiration)); 193 | 194 | uuid2StringLE(&Request->AppID, guidBuffer); 195 | getProductIndex(&Request->AppID, KmsData->AppItemList, KmsData->AppItemCount, &productName, NULL); 196 | p("Application ID : %s (%s)\n", guidBuffer, productName); 197 | 198 | uuid2StringLE(&Request->ActID, guidBuffer); 199 | getProductIndex(&Request->ActID, KmsData->SkuItemList, KmsData->SkuItemCount, &productName, NULL); 200 | p("SKU ID (aka Activation ID) : %s (%s)\n", guidBuffer, productName); 201 | 202 | uuid2StringLE(&Request->KMSID, guidBuffer); 203 | getProductIndex(&Request->KMSID, KmsData->KmsItemList, KmsData->KmsItemCount, &productName, NULL); 204 | p("KMS ID (aka KMS counted ID) : %s (%s)\n", guidBuffer, productName); 205 | 206 | uuid2StringLE(&Request->CMID, guidBuffer); 207 | p("Client machine ID : %s\n", guidBuffer); 208 | 209 | uuid2StringLE(&Request->CMID_prev, guidBuffer); 210 | p("Previous client machine ID : %s\n", guidBuffer); 211 | 212 | 213 | char mbstr[64]; 214 | time_t st; 215 | st = fileTimeToUnixTime(&Request->ClientTime); 216 | strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %X", gmtime(&st)); 217 | p("Client request timestamp (UTC) : %s\n", mbstr); 218 | 219 | ucs2_to_utf8(Request->WorkstationName, WorkstationBuffer, WORKSTATION_NAME_BUFFER, sizeof(WorkstationBuffer)); 220 | 221 | p("Workstation name : %s\n", WorkstationBuffer); 222 | p("N count policy (minimum clients): %u\n", (uint32_t)LE32(Request->N_Policy)); 223 | } 224 | 225 | void logResponseVerbose(const char *const ePID, const BYTE *const hwid, RESPONSE* response, const PRINTFUNC p) 226 | { 227 | char guidBuffer[GUID_STRING_LENGTH + 1]; 228 | 229 | p("Protocol version : %u.%u\n", (uint32_t)LE16(response->MajorVer), (uint32_t)LE16(response->MinorVer)); 230 | p("KMS host extended PID : %s\n", ePID); 231 | if (LE16(response->MajorVer) > 5) 232 | # ifndef _WIN32 233 | p("KMS host Hardware ID : %016llX\n", (unsigned long long)BE64(*(uint64_t*)hwid)); 234 | # else // _WIN32 235 | p("KMS host Hardware ID : %016I64X\n", (unsigned long long)BE64(*(uint64_t*)hwid)); 236 | # endif // WIN32 237 | 238 | uuid2StringLE(&response->CMID, guidBuffer); 239 | p("Client machine ID : %s\n", guidBuffer); 240 | 241 | char mbstr[64]; 242 | time_t st; 243 | 244 | st = fileTimeToUnixTime(&response->ClientTime); 245 | strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %X", gmtime(&st)); 246 | p("Client request timestamp (UTC) : %s\n", mbstr); 247 | 248 | p("KMS host current active clients : %u\n", (uint32_t)LE32(response->Count)); 249 | p("Renewal interval policy : %u\n", (uint32_t)LE32(response->VLRenewalInterval)); 250 | p("Activation interval policy : %u\n", (uint32_t)LE32(response->VLActivationInterval)); 251 | } 252 | #endif // !defined(NO_VERBOSE_LOG) && !defined(NO_LOG) 253 | 254 | 255 | #ifndef NO_VERSION_INFORMATION 256 | void printPlatform() 257 | { 258 | int testNumber = 0x1234; 259 | 260 | # if _MSC_VER 261 | printf("Compiler: VC++ %02i.%02i build %i\n", _MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 100000); 262 | # elif defined(VLMCSD_COMPILER) 263 | printf 264 | ( 265 | "Compiler: %s\n", VLMCSD_COMPILER 266 | # ifdef __VERSION__ 267 | " " __VERSION__ 268 | # endif // __VERSION__ 269 | ); 270 | # endif // VLMCSD_COMPILER 271 | 272 | printf 273 | ( 274 | "Intended platform:%s %s\n", "" 275 | 276 | # if __i386__ || _M_IX86 277 | " Intel x86" 278 | # endif 279 | 280 | # if __x86_64__ || __amd64__ || _M_X64 || _M_AMD64 281 | " Intel x86_64" 282 | # endif 283 | 284 | # if _M_ARM || __arm__ 285 | " ARM" 286 | # endif 287 | 288 | # if __thumb__ 289 | " thumb" 290 | # endif 291 | 292 | # if __aarch64__ 293 | " ARM64" 294 | # endif 295 | 296 | # if __hppa__ 297 | " HP/PA RISC" 298 | # endif 299 | 300 | # if __ia64__ 301 | " Intel Itanium" 302 | # endif 303 | 304 | # if __mips__ 305 | " MIPS" 306 | # endif 307 | 308 | # if defined(_MIPS_ARCH) 309 | " " _MIPS_ARCH 310 | # endif 311 | 312 | # if __mips16 313 | " mips16" 314 | # endif 315 | 316 | # if __mips_micromips 317 | " micromips" 318 | # endif 319 | 320 | # if __ppc__ || __powerpc__ 321 | " PowerPC" 322 | # endif 323 | 324 | # if __powerpc64__ || __ppc64__ 325 | " PowerPC64" 326 | # endif 327 | 328 | # if __sparc__ 329 | " SPARC" 330 | # endif 331 | 332 | # if defined(__s390__) && !defined(__zarch__) && !defined(__s390x__) 333 | " IBM S/390" 334 | # endif 335 | 336 | # if __zarch__ || __s390x__ 337 | " IBM z/Arch (S/390x)" 338 | # endif 339 | 340 | # if __m68k__ 341 | " Motorola 68k" 342 | # endif 343 | 344 | # if __ANDROID__ 345 | " Android" 346 | # endif 347 | 348 | # if __ANDROID_API__ 349 | " (API level " ANDROID_API_LEVEL ")" 350 | # endif 351 | 352 | # if __FreeBSD__ || __FreeBSD_kernel__ 353 | " FreeBSD" 354 | # endif 355 | 356 | # if __NetBSD__ 357 | " NetBSD" 358 | # endif 359 | 360 | # if __OpenBSD__ 361 | " OpenBSD" 362 | # endif 363 | 364 | # if __DragonFly__ 365 | " DragonFly BSD" 366 | # endif 367 | 368 | # if defined(__CYGWIN__) && !defined(_WIN64) 369 | " Cygwin32" 370 | # endif 371 | 372 | # if defined(__CYGWIN__) && defined(_WIN64) 373 | " Cygwin64" 374 | # endif 375 | 376 | # if __GNU__ 377 | " GNU" 378 | # endif 379 | 380 | # if __gnu_hurd__ 381 | " Hurd" 382 | # endif 383 | 384 | # if __MACH__ 385 | " Mach" 386 | # endif 387 | 388 | # if __linux__ 389 | " Linux" 390 | # endif 391 | 392 | # if __APPLE__ && __MACH__ 393 | " Darwin" 394 | # endif 395 | 396 | # if __minix__ 397 | " Minix" 398 | # endif 399 | 400 | # if __QNX__ 401 | " QNX" 402 | # endif 403 | 404 | # if __svr4__ || __SVR4 405 | " SYSV R4" 406 | # endif 407 | 408 | # if (defined(__sun__) || defined(sun) || defined(__sun)) && (defined(__SVR4) || defined(__svr4__)) 409 | " Solaris" 410 | # endif 411 | 412 | # if (defined(__sun__) || defined(sun) || defined(__sun)) && !defined(__SVR4) && !defined(__svr4__) 413 | " SunOS" 414 | # endif 415 | 416 | # if defined(_WIN32) && !defined(_WIN64) 417 | " Windows32" 418 | # endif 419 | 420 | # if defined(_WIN32) && defined(_WIN64) 421 | " Windows64" 422 | # endif 423 | 424 | # if __MVS__ || __TOS_MVS__ 425 | " z/OS" 426 | # endif 427 | 428 | # if defined(__GLIBC__) && !defined(__UCLIBC__) 429 | " glibc" 430 | # endif 431 | 432 | # if __UCLIBC__ 433 | " uclibc" 434 | # endif 435 | 436 | # if defined(__linux__) && !defined(__GLIBC__) && !defined(__UCLIBC__) && !defined(__ANDROID__) && !defined(__BIONIC__) 437 | " musl" 438 | # endif 439 | 440 | //# if _MIPSEL || __MIPSEL__ || __ARMEL__ || __THUMBEL__ 441 | // " little-endian" 442 | //# endif 443 | // 444 | //# if _MIPSEB || __MIPSEB__ || __ARMEB__ || __THUMBEB__ 445 | // " big-endian" 446 | //# endif 447 | 448 | # if __PIE__ || __pie__ 449 | " PIE" 450 | # endif 451 | , 452 | *((uint8_t*)&testNumber) == 0x34 ? "little-endian" : "big-endian" 453 | ); 454 | 455 | } 456 | 457 | 458 | void printCommonFlags() 459 | { 460 | printf 461 | ( 462 | "Common flags:%s\n", "" 463 | 464 | # ifdef NO_EXTERNAL_DATA 465 | " NO_EXTERNAL_DATA" 466 | # endif // NO_EXTERNAL_DATA 467 | 468 | # ifdef NO_INTERNAL_DATA 469 | " NO_INTERNAL_DATA" 470 | # endif // NO_INTERNAL_DATA 471 | 472 | # if !defined(NO_EXTERNAL_DATA) 473 | 474 | # ifdef DATA_FILE 475 | " DATA=" DATA_FILE 476 | # endif // DATA_FILE 477 | 478 | # ifdef UNSAFE_DATA_LOAD 479 | " UNSAFE_DATA_LOAD" 480 | # endif // UNSAFE_DATA_LOAD 481 | 482 | # endif // !defined(NO_EXTERNAL_DATA) 483 | 484 | # ifdef USE_MSRPC 485 | " USE_MSRPC" 486 | # endif // USE_MSRPC 487 | 488 | # ifdef _CRYPTO_OPENSSL 489 | " _CRYPTO_OPENSSL" 490 | # endif // _CRYPTO_OPENSSL 491 | 492 | # ifdef _CRYPTO_POLARSSL 493 | " _CRYPTO_POLARSSL" 494 | # endif // _CRYPTO_POLARSSL 495 | 496 | # ifdef _CRYPTO_WINDOWS 497 | " _CRYPTO_WINDOWS" 498 | # endif // _CRYPTO_WINDOWS 499 | 500 | # if defined(_OPENSSL_SOFTWARE) && defined(_CRYPTO_OPENSSL) 501 | " _OPENSSL_SOFTWARE" 502 | # endif // _OPENSSL_SOFTWARE 503 | 504 | # if defined(_USE_AES_FROM_OPENSSL) && defined(_CRYPTO_OPENSSL) 505 | " _USE_AES_FROM_OPENSSL" 506 | # endif // _USE_AES_FROM_OPENSSL 507 | 508 | # if defined(_OPENSSL_NO_HMAC) && defined(_CRYPTO_OPENSSL) 509 | " OPENSSL_HMAC=0" 510 | # endif // _OPENSSL_NO_HMAC 511 | 512 | # ifdef _PEDANTIC 513 | " _PEDANTIC" 514 | # endif // _PEDANTIC 515 | 516 | # ifdef INCLUDE_BETAS 517 | " INCLUDE_BETAS" 518 | # endif // INCLUDE_BETAS 519 | 520 | # if __minix__ || defined(NO_TIMEOUT) 521 | " NO_TIMEOUT=1" 522 | # endif // __minix__ || defined(NO_TIMEOUT) 523 | ); 524 | } 525 | 526 | 527 | void printClientFlags() 528 | { 529 | printf 530 | ( 531 | "vlmcs flags:%s\n", "" 532 | 533 | # ifdef NO_DNS 534 | " NO_DNS=1" 535 | # endif 536 | 537 | # if !defined(NO_DNS) 538 | # if defined(DNS_PARSER_INTERNAL) && !defined(_WIN32) 539 | " DNS_PARSER=internal" 540 | # else // !defined(DNS_PARSER_INTERNAL) || defined(_WIN32) 541 | " DNS_PARSER=OS" 542 | # endif // !defined(DNS_PARSER_INTERNAL) || defined(_WIN32) 543 | # endif // !defined(NO_DNS) 544 | 545 | # if defined(DISPLAY_WIDTH) 546 | " TERMINAL_WIDTH=" DISPLAY_WIDTH 547 | # endif 548 | ); 549 | } 550 | 551 | 552 | void printServerFlags() 553 | { 554 | printf 555 | ( 556 | "vlmcsd flags:%s\n", "" 557 | 558 | # ifdef NO_LOG 559 | " NO_LOG" 560 | # endif // NO_LOG 561 | 562 | # ifdef NO_RANDOM_EPID 563 | " NO_RANDOM_EPID" 564 | # endif // NO_RANDOM_EPID 565 | 566 | # ifdef NO_INI_FILE 567 | " NO_INI_FILE" 568 | # endif // NO_INI_FILE 569 | 570 | # if !defined(NO_INI_FILE) && defined(INI_FILE) 571 | " INI=" INI_FILE 572 | # endif // !defined(NO_INI_FILE) 573 | 574 | # ifdef NO_PID_FILE 575 | " NO_PID_FILE" 576 | # endif // NO_PID_FILE 577 | 578 | # ifdef NO_USER_SWITCH 579 | " NO_USER_SWITCH" 580 | # endif // NO_USER_SWITCH 581 | 582 | # ifdef NO_HELP 583 | " NO_HELP" 584 | # endif // NO_HELP 585 | 586 | # ifdef NO_STRICT_MODES 587 | " NO_STRICT_MODES" 588 | # endif // NO_STRICT_MODES 589 | 590 | # ifdef NO_CUSTOM_INTERVALS 591 | " NO_CUSTOM_INTERVALS" 592 | # endif // NO_CUSTOM_INTERVALS 593 | 594 | # ifdef NO_SOCKETS 595 | " NO_SOCKETS" 596 | # endif // NO_SOCKETS 597 | 598 | # ifdef NO_CL_PIDS 599 | " NO_CL_PIDS" 600 | # endif // NO_CL_PIDS 601 | 602 | # ifdef NO_LIMIT 603 | " NO_LIMIT" 604 | # endif // NO_LIMIT 605 | 606 | # ifdef NO_SIGHUP 607 | " NO_SIGHUP" 608 | # endif // NO_SIGHUP 609 | 610 | # ifdef NO_PROCFS 611 | " NOPROCFS=1" 612 | # endif // NO_PROCFS 613 | 614 | # ifdef USE_THREADS 615 | " THREADS=1" 616 | # endif // USE_THREADS 617 | 618 | # ifdef USE_AUXV 619 | " AUXV=1" 620 | # endif // USE_AUXV 621 | 622 | # if defined(CHILD_HANDLER) || __minix__ 623 | " CHILD_HANDLER=1" 624 | # endif // defined(CHILD_HANDLER) || __minix__ 625 | 626 | # if !defined(NO_SOCKETS) && defined(SIMPLE_SOCKETS) 627 | " SIMPLE_SOCKETS" 628 | # endif // !defined(NO_SOCKETS) && defined(SIMPLE_SOCKETS) 629 | 630 | # ifdef SIMPLE_RPC 631 | " SIMPLE_RPC" 632 | # endif // SIMPLE_RPC 633 | 634 | # ifdef NO_STRICT_MODES 635 | " NO_STRICT_MODES" 636 | # endif // NO_STRICT_MODES 637 | 638 | # ifdef NO_CLIENT_LIST 639 | " NO_CLIENT_LIST" 640 | # endif // NO_CLIENT_LIST 641 | 642 | # if (_WIN32 || __CYGWIN__) && (!defined(USE_MSRPC) || defined(SUPPORT_WINE)) 643 | " SUPPORT_WINE" 644 | # endif // (_WIN32 || __CYGWIN__) && (!defined(USE_MSRPC) || defined(SUPPORT_WINE)) 645 | 646 | # if (_WIN32 || __CYGWIN__) && defined(NO_TAP) 647 | " NO_TAP" 648 | # endif // (_WIN32 || __CYGWIN__) && defined(NO_TAP) 649 | 650 | # if !HAVE_FREEBIND 651 | " NO_FREEBIND" 652 | # endif //!HAVE_FREEBIND 653 | 654 | # if !HAVE_GETIFADDR 655 | " !HAVE_GETIFADDR" 656 | # endif // !HAVE_GETIFADDR 657 | 658 | # if HAVE_GETIFADDR && defined(GETIFADDRS_MUSL) 659 | " GETIFADDRS=musl" 660 | # endif // HAVE_GETIFADDR && defined(GETIFADDRS_MUSL) 661 | 662 | # if defined(NO_PRIVATE_IP_DETECT) 663 | " NO_PRIVATE_IP_DETECT" 664 | # endif // defined(NO_PRIVATE_IP_DETECT) 665 | ); 666 | } 667 | #endif // NO_VERSION_INFORMATION 668 | -------------------------------------------------------------------------------- /crates/kms-sys/src/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H_ 2 | #define CONFIG_H_ 3 | 4 | /* Don't change anything ABOVE this line */ 5 | 6 | /* 7 | * As a best practice do not change the original config.h as distributed with vlmcsd. 8 | * Instead make a copy, e.g. myconfig.h, customize it and type 'make CONFIG=myconfig.h' 9 | * to build vlmcsd. This prevents your copy being overwritten when you upgrade to a 10 | * new version. 11 | */ 12 | 13 | 14 | 15 | /* 16 | * ---------------------------------------------------------------------------------------- 17 | * Useful customizations. These options are mandatory. You cannot comment them out. 18 | * Feel free to change them to fit your needs. 19 | * ---------------------------------------------------------------------------------------- 20 | */ 21 | 22 | #ifndef VERSION 23 | /* 24 | * Define your own version identifier here, e.g. '#define VERSION "my vlmcsd based on 1103"' 25 | */ 26 | 27 | #define VERSION "private build" 28 | 29 | #endif // VERSION 30 | 31 | 32 | 33 | 34 | 35 | #ifndef HWID // HwId from the Ratiborus VM 36 | #define HWID 0x3A, 0x1C, 0x04, 0x96, 0x00, 0xB6, 0x00, 0x76 37 | #endif 38 | 39 | 40 | 41 | 42 | 43 | /* 44 | * Anything below this line is optional. If you want to use any of these options 45 | * uncomment one or more lines starting with "//#define" 46 | */ 47 | 48 | 49 | 50 | /* 51 | * ------------------------------- 52 | * Defaults 53 | * ------------------------------- 54 | */ 55 | 56 | 57 | 58 | #ifndef INI_FILE 59 | /* 60 | * Uncomment and customize the following line if you want vlmcsd to look for an ini file 61 | * at a default location. 62 | */ 63 | 64 | //#define INI_FILE "/etc/vlmcsd.ini" 65 | 66 | #endif // INI_FILE 67 | 68 | 69 | 70 | 71 | 72 | #ifndef DATA_FILE 73 | /* 74 | * Uncomment and customize the following line if you want vlmcsd to look for a KMS data file 75 | * at a custom default location. 76 | */ 77 | 78 | //#define DATA_FILE "/etc/vlmcsd.kmd" 79 | 80 | #endif // DATA_FILE 81 | 82 | 83 | /* 84 | * ---------------------------------------------------------------------------------------- 85 | * Troubleshooting options. Please note that disabling features may also help troubleshooting. 86 | * If you have an old OS that does not support features like pthreads, shared memory or 87 | * semaphores, uncomment "#define NO_LIMIT" and "#define NO_SIGHUP" and leave "#define USE_THREADS" 88 | * commented out. 89 | * ---------------------------------------------------------------------------------------- 90 | */ 91 | 92 | 93 | #ifndef CHILD_HANDLER 94 | /* 95 | * Uncomment the following #define if you are compiling for a platform that does 96 | * not correctly handle the SA_NOCLDWAIT flag when ignoring SIGCHLD, i.e. forked 97 | * processes remain as "zombies" after dying. This option will add a SIGCHLD handler that 98 | * "waits" for a child that has terminated. This is only required for a few 99 | * unixoid OSses. 100 | */ 101 | 102 | //#define CHILD_HANDLER 103 | 104 | #endif // CHILD_HANDLER 105 | 106 | 107 | #ifndef NO_TIMEOUT 108 | /* 109 | * Uncomment the following #define if you are compiling for a platform that does 110 | * not support custom socket send or receive timeouts. 111 | */ 112 | 113 | //#define NO_TIMEOUT 114 | 115 | #endif // NO_TIMEOUT 116 | 117 | 118 | #ifndef NO_DNS 119 | /* 120 | * Uncomment the following #define if you have trouble with accessing routines 121 | * from libresolv. If enabled, vlmcs will be compiled without support for 122 | * detecting KMS servers via DNS. 123 | */ 124 | 125 | //#define NO_DNS 126 | 127 | #endif // NO_DNS 128 | 129 | 130 | #ifndef TERMINAL_FIXED_WIDTH 131 | /* 132 | * Uncomment the following #define and optionally change its value if you are compiling for 133 | * a platform that cannot properly determine the width of a terminal/command prompt. 134 | * This affects the output of "vlmcsd -x" only. It should be rarely necessary to use this. 135 | */ 136 | 137 | //#define TERMINAL_FIXED_WIDTH 80 138 | 139 | #endif // TERMINAL_FIXED_WIDTH 140 | 141 | 142 | 143 | 144 | #ifndef _PEDANTIC 145 | /* 146 | * Uncomment the following #define if you want to do vlmcs and vlmcsd more checks on the data 147 | * it receives over the network. They are normally not necessary but may provide useful if 148 | * you are testing any KMS server or client emulator that may send malformed KMS packets. 149 | */ 150 | 151 | //#define _PEDANTIC 152 | 153 | #endif // _PEDANTIC 154 | 155 | 156 | 157 | 158 | #ifndef NO_PROCFS 159 | /* 160 | * Cygwin, Linux, Android, NetBSD, DragonflyBSD: 161 | * Do not rely on a properly mounted proc filesystem and use the less reliable 162 | * argv[0] to determine the program's executable name. 163 | * Use only if absolutely necessary (very old versions of these OSses). 164 | * 165 | * Minix, OpenBSD: 166 | * This option has no effect since the OS always must use the less reliable argv[0]. 167 | * 168 | * FreeBSD, Mac OS X, iOS, Solaris, Windows: 169 | * This option is not neccessary (and has no effect) since these OSses provide 170 | * a reliable way to determine the executable name. 171 | * 172 | */ 173 | 174 | //#define NO_PROCFS 175 | 176 | #endif // NO_PROCFS 177 | 178 | 179 | 180 | 181 | #ifndef USE_AUXV 182 | /* 183 | * Linux only: 184 | * Use the process' ELF aux vector to determine the executable name. 185 | * This is actually the best method but is supported only with 186 | * 187 | * * the musl library 188 | * * the glbic library 2.16 or newer 189 | * 190 | * It does NOT work with uclibc (most routers and other small devices) and glibc < 2.16. 191 | * Use it only if your system supports it and you do not plan to use the binary on older systems. 192 | * It won't work on debian 7 or Red Hat 6.x. 193 | * 194 | * It is safe to try this by yourself. vlmcsd won't compile if your system doesn't support it. 195 | */ 196 | 197 | //#define USE_AUXV 198 | 199 | #endif // USE_AUXV 200 | 201 | 202 | 203 | 204 | #ifndef _OPENSSL_NO_HMAC 205 | /* 206 | * If you configured vlmcsd to use OpenSSL (which you shouldn't) you may use this option 207 | * to calculate the KMSv6 HMAC with internal code instead of using OpenSSL. 208 | * 209 | * This may be necessary for some embedded devices that have OpenSSL without HMAC support. 210 | */ 211 | 212 | //#define _OPENSSL_NO_HMAC 213 | 214 | #endif // _OPENSSL_NO_HMAC 215 | 216 | 217 | 218 | 219 | /* 220 | * ---------------------------------------------------------------------------------------- 221 | * Modes of operation 222 | * ---------------------------------------------------------------------------------------- 223 | */ 224 | 225 | 226 | #ifndef USE_THREADS 227 | /* 228 | * Do not use fork() but threads to serve your clients. 229 | * 230 | * Unix-like operarting systems: 231 | * You may use this or not. Entirely your choice. Threads do not require explicitly allocating 232 | * a shared memory segment which might be a problem on some systems. Using fork() is more robust 233 | * although the threaded version of vlmcsd is rock solid too. 234 | * 235 | * Some older unixoid OSses may not have pthreads. Do NOT use USE_THREADS and define NO_SIGHUP 236 | * and NO_LIMIT instead to disable use of the pthreads, shared memory and semaphores. 237 | * 238 | * Cygwin: 239 | * It is recommended to use threads since fork() is extremely slow (no copy on write) and somewhat 240 | * unstable. 241 | * 242 | * Windows: 243 | * This option has no effect since fork() is not supported. 244 | */ 245 | 246 | //#define USE_THREADS 247 | 248 | #endif // USE_THREADS 249 | 250 | 251 | 252 | 253 | #ifndef _CRYPTO_POLARSSL 254 | /* 255 | * Not available on native Windows. Can be used with Cygwin. 256 | * 257 | * Use PolarSSL for crypto routines if possible and if it is safe. There is not much benefit by using this 258 | * options since it can be used for SHA256 and HMAC_SHA256 only. It cannot be used for AES calculations because 259 | * KMSv6 uses a modified algorithm that PolarSSL does not support. KMSv4 CMAC is also unsupported since it uses 260 | * a Rijndael keysize (160 bits) that is not part of the AES standard. 261 | * 262 | * It is strongly recommended not to use an external crypto library. 263 | * 264 | * Do not define both _CRYPTO_OPENSSL and _CRYPTO_POLARSSL 265 | */ 266 | 267 | //#define _CRYPTO_POLARSSL 268 | 269 | #endif // _CRYPTO_POLARSSL 270 | 271 | 272 | 273 | 274 | #ifndef _CRYPTO_OPENSSL 275 | /* 276 | * Not available on native Windows. Can be used with Cygwin. 277 | * 278 | * Use OpenSSL for crypto routines if possible and if it is safe. There is not much benefit by using this 279 | * options since it can be used for SHA256 and HMAC_SHA256 only. It cannot be used for AES calculations because 280 | * KMSv6 uses a modified algorithm that OpenSSL does not support. KMSv4 CMAC is also unsupported since it uses 281 | * a Rijndael keysize (160 bits) that is not part of the AES standard. 282 | * 283 | * It is strongly recommended not to use an external crypto library. 284 | * 285 | * Do not define both _CRYPTO_OPENSSL and _CRYPTO_POLARSSL 286 | */ 287 | 288 | //#define _CRYPTO_OPENSSL 289 | 290 | #endif // _CRYPTO_OPENSSL 291 | 292 | 293 | 294 | 295 | #ifndef _USE_AES_FROM_OPENSSL 296 | /* 297 | * DANGEROUS: Tweak OpenSSL to perform KMSv4 CMAC and KMSv6 modified AES. This option creates the expanded 298 | * AES key by itself and then applies modifications to it. OpenSSL will then perfom modified AES operations. 299 | * 300 | * This options tampers with internal structures of OpenSSL that are subject to change or may have a platform 301 | * specific implementation. In this case your resulting binary can only perform KMSv5 operations. 302 | * 303 | * This option has no effect if _CRYPTO_OPENSSL is not defined. 304 | * 305 | * Don't use this except for your own research on the internals of OpenSSL. 306 | */ 307 | 308 | //#define _USE_AES_FROM_OPENSSL 309 | 310 | #endif // _USE_AES_FROM_OPENSSL 311 | 312 | 313 | 314 | 315 | 316 | #ifndef _OPENSSL_SOFTWARE 317 | /* 318 | * Use this only if you have defined _CRYPTO_OPENSSL and _USE_AES_FROM_OPENSSL. It has no effect otherwise. 319 | * 320 | * This options assumes a different internal AES expanded key in OpenSSL which is used mostly if OpenSSL is 321 | * compiled without support for hardware accelerated AES. It's worth a try if _USE_AES_FROM_OPENSSL doesn't work. 322 | */ 323 | 324 | //#define _OPENSSL_SOFTWARE 325 | 326 | #endif // _OPENSSL_SOFTWARE 327 | 328 | 329 | 330 | 331 | #ifndef FULL_INTERNAL_DATA 332 | /* 333 | * Includes the full database in vlmcsd. 334 | */ 335 | 336 | //#define FULL_INTERNAL_DATA 337 | #endif // FULL_INTERNAL_DATA 338 | 339 | 340 | 341 | 342 | /* 343 | * ---------------------------------------------------------------------------------------- 344 | * Removal of features. Allows you to remove features of vlmcsd you do not need or want. 345 | * Use it to get smaller binaries. This is especially useful on very small embedded devices. 346 | * ---------------------------------------------------------------------------------------- 347 | */ 348 | 349 | 350 | #ifndef NO_FREEBIND 351 | /* 352 | * Do not compile support for FREEBIND (Linux) and IP_BINDANY (FreeBSD). This disables the -F1 command 353 | * line option and you can bind only to (listen on) IP addresses that are currently up and running on 354 | * your system. 355 | */ 356 | 357 | //#define NO_FREEBIND 358 | 359 | #endif // NO_FREEBIND 360 | 361 | 362 | 363 | 364 | #ifndef NO_TAP 365 | /* 366 | * Do not compile support for using a VPN adapter under Windows. Disables -O command line option. 367 | */ 368 | 369 | //#define NO_TAP 370 | 371 | #endif // NO_TAP 372 | 373 | 374 | 375 | 376 | #ifndef NO_VERSION_INFORMATION 377 | /* 378 | * Removes the -V option from vlmcsd and vlmcs that displays the version information 379 | */ 380 | 381 | //#define NO_VERSION_INFORMATION 382 | 383 | #endif // NO_VERSION_INFORMATION 384 | 385 | 386 | 387 | 388 | #ifndef NO_VERBOSE_LOG 389 | /* 390 | * Removes the ability to do verbose logging and disables -v and -q in vlmcsd. It does not remove the -v 391 | * option in the vlmcs client. Disables ini file directive LogVerbose. 392 | */ 393 | 394 | //#define NO_VERBOSE_LOG 395 | 396 | #endif // NO_VERBOSE_LOG 397 | 398 | 399 | 400 | 401 | #ifndef NO_LOG 402 | /* 403 | * Disables logging completely. You can neither log to a file nor to the console. -D and -f will 404 | * start vlmcsd in foreground. -e will not be available. Disables ini file directive LogFile. 405 | * Implies NO_VERBOSE_LOG. 406 | */ 407 | 408 | //#define NO_LOG 409 | 410 | #endif // NO_LOG 411 | 412 | 413 | 414 | 415 | #ifndef NO_STRICT_MODES 416 | /* 417 | * Disables emulator detection protection. Removes -M0, -M1, -E0, -E1, -K0, -K1, -K2 and -K3 from 418 | * vlmcsd command line options and WhitelistingLevel from INI file parameters. vlmcsd always behaves 419 | * as if it was started with -K0, -M0. 420 | */ 421 | 422 | //#define NO_STRICT_MODES 423 | 424 | #endif // NO_STRICT_MODES 425 | 426 | 427 | 428 | 429 | 430 | #ifndef NO_CLIENT_LIST 431 | /* 432 | * Disables the ability to maintain a list of Client Machine IDs (CMIDs). Removes -M0, -M1, -E0 and -E1 433 | * from vlmcsd command line options. 434 | */ 435 | 436 | //#define NO_CLIENT_LIST 437 | 438 | #endif // !NO_CLIENT_LIST 439 | 440 | 441 | 442 | #ifndef NO_RANDOM_EPID 443 | /* 444 | * Disables the ability to generate random ePIDs. Useful if you managed to grab ePID/HWID from a 445 | * real KMS server and want to use these. Removes -r from the vlmcsd command line and the ini 446 | * file directive RandomizationLevel (The randomization level will be harcoded to 0). 447 | */ 448 | 449 | //#define NO_RANDOM_EPID 450 | 451 | #endif // NO_RANDOM_EPID 452 | 453 | 454 | 455 | 456 | #ifndef NO_INI_FILE 457 | /* 458 | * Disables the ability to use a configuration file (aka ini file). Removes -i from the command line. 459 | */ 460 | 461 | //#define NO_INI_FILE 462 | 463 | #endif // NO_INI_FILE 464 | 465 | 466 | 467 | 468 | #ifndef NO_PID_FILE 469 | /* 470 | * Disables the abilty to write a pid file containing the process id of vlmcsd. If your init system 471 | * does not need this feature, you can safely disables this but it won't save much space. Disables 472 | * the use of -p from the command line and PidFile from the ini file. 473 | */ 474 | 475 | //#define NO_PID_FILE 476 | 477 | #endif // NO_PID_FILE 478 | 479 | 480 | 481 | 482 | #ifndef NO_EXTERNAL_DATA 483 | /* 484 | * Disables the abilty to load external KMS data from a file. Disables command line options -j 485 | * and ini file parameter KmsData. Implies UNSAFE_DATA_LOAD. 486 | */ 487 | 488 | //#define NO_EXTERNAL_DATA 489 | 490 | #endif // NO_EXTERNAL_DATA 491 | 492 | 493 | 494 | 495 | #ifndef NO_INTERNAL_DATA 496 | /* 497 | * Compiles vlmcsd and vlmcs without an internal database. If no database is found at 498 | * either the default location or the file specified with command line option -j., 499 | * the program exits with an error message. 500 | */ 501 | 502 | //#define NO_INTERNAL_DATA 503 | 504 | #endif // NO_INTERNAL_DATA 505 | 506 | 507 | 508 | 509 | #ifndef UNSAFE_DATA_LOAD 510 | /* 511 | * Does not check an external KMS data file for integrity. 512 | * This save some bytes but it dangerous if you load a KMS data file from an unknown source. 513 | */ 514 | 515 | //#define UNSAFE_DATA_LOAD 516 | 517 | #endif // UNSAFE_DATA_LOAD 518 | 519 | 520 | 521 | 522 | #ifndef NO_USER_SWITCH 523 | /* 524 | * Disables switching to another uid and/or gid after starting the program and setting up the sockets. 525 | * You cannot use -u anf -g on the command line as well as User and Group in the ini file. If your init system 526 | * supports starting daemons as another uid/gid (user/group) you can disable this feature in vlmcsd as long as you 527 | * do not need to run vlmcsd on a privileged port ( < 1024 on most systems). 528 | * 529 | * This setting has no effect on native Windows since -u and -g is not available anyway. It may be used with 530 | * Cygwin. 531 | */ 532 | 533 | //#define NO_USER_SWITCH 534 | 535 | #endif // NO_USER_SWITCH 536 | 537 | 538 | 539 | 540 | #ifndef NO_HELP 541 | /* 542 | * Disables display of help in both vlmcsd and vlmcs. Saves some bytes but only makes sense if you have 543 | * access to the man files vlmcsd.8 and vlmcs.1 544 | */ 545 | 546 | //#define NO_HELP 547 | 548 | #endif // NO_HELP 549 | 550 | 551 | 552 | 553 | #ifndef NO_CUSTOM_INTERVALS 554 | /* 555 | * Disables the ability to specify custom interval for renewing and retrying activation. Newer versions of the Microsoft's 556 | * KMS activation client (as in Win 8.1) do not honor these parameters anyway. Disable them to save some bytes. Removes 557 | * -A and -R from the command line as well as ActivationInterval and RenewalInterval in the ini file. 558 | */ 559 | 560 | //#define NO_CUSTOM_INTERVALS 561 | 562 | #endif // NO_CUSTOM_INTERVALS 563 | 564 | 565 | 566 | 567 | #ifndef NO_PRIVATE_IP_DETECT 568 | /* 569 | * Disables the ability to protect vlmcsd against KMS requests from public IP addresses. 570 | * Removes -o from the command line. 571 | */ 572 | 573 | //#define NO_PRIVATE_IP_DETECT 574 | 575 | #endif // NO_PRIVATE_IP_DETECT 576 | 577 | 578 | 579 | 580 | #ifndef NO_SOCKETS 581 | /* 582 | * Disables standalone startup of vlmcsd. If you use this config directive, you must start vlmcsd from an internet 583 | * superserver like inetd, xinetd, systemd or launchd. Disables -m, -t, -4, -6, -e, -f, -P and -L in the vlmcsd 584 | * command line. Socket setup is the job of your superserver. 585 | */ 586 | 587 | //#define NO_SOCKETS 588 | 589 | #endif // NO_SOCKETS 590 | 591 | 592 | 593 | 594 | #ifndef NO_CL_PIDS 595 | /* 596 | * Disables the ability to specify ePIDs and HWID at the command line. You still may use them in the ini file. 597 | * Removes -0, -3, -w and -H from the vlmcsd command line. 598 | */ 599 | 600 | //#define NO_CL_PIDS 601 | 602 | #endif // NO_CL_PIDS 603 | 604 | 605 | 606 | 607 | #ifndef NO_LIMIT 608 | /* 609 | * Disables the ability to limit the number of worker threads or processes that vlmcsd uses. While you should set a 610 | * limit whenever possible, you may save some bytes by enabling that setting. If you do not use a limit, use vlmcsd 611 | * in a "friendly" environment only, i.e. do not run it without a reasonable limit on the internet. 612 | * 613 | * Removes the ability to use -m in the vlmcsd command line and MaxWorkers in the ini file. 614 | * 615 | * Some older unixoid OSses may not have pthreads. Do NOT use USE_THREADS and define NO_SIGHUP 616 | * and NO_LIMIT instead to disable use of the pthreads, shared memory and semaphores. 617 | */ 618 | 619 | //#define NO_LIMIT 620 | 621 | #endif // NO_LIMIT 622 | 623 | 624 | 625 | 626 | #ifndef NO_SIGHUP 627 | /* 628 | * Disables the ability to signal hangup (SIGHUP) to vlmcsd to restart it (rereading the ini file). The SIGHUP 629 | * handler makes heavy use of OS specific code. It should not cause any trouble on Solaris, Mac OS X and iOS. On Linux 630 | * use "#define USE_AUXV" (see troubleshooting options) if this is supported by your C runtime library. 631 | * 632 | * You may save some bytes by enabling this option. Use it also if the SIGHUP handler causes any trouble on your 633 | * platform. Please note that with no SIGHUP handler at all. vlmcsd will simply terminate (uncleanly) if it receives 634 | * the SIGHUP signal. This is the same behavior as with most other signals. 635 | * 636 | * This option has no effect on native Windows since Posix signaling is not supported. It can be used with Cygwin. 637 | */ 638 | 639 | //#define NO_SIGHUP 640 | 641 | #endif // NO_SIGHUP 642 | 643 | 644 | 645 | 646 | #ifndef SIMPLE_RPC 647 | /* 648 | * Uses a simple version of the RPC protocol which does not support NDR64 and BTFN. 649 | * Supports RPC with the features present in Windows XP and earlier only. Using this creates 650 | * smaller binaries but makes emulator detection easier. 651 | */ 652 | 653 | //#define SIMPLE_RPC 654 | #endif // !SIMPLE_RPC 655 | 656 | 657 | 658 | 659 | #ifndef SIMPLE_SOCKETS 660 | /* 661 | * Disables the ability to choose IP addresses using the -L option in vlmcsd. vlmcsd will listen on all IP addresses. 662 | * It still supports IPv4 and IPv6. 663 | */ 664 | 665 | //#define SIMPLE_SOCKETS 666 | 667 | #endif // SIMPLE_SOCKETS 668 | 669 | 670 | 671 | /* Don't change anything BELOW this line */ 672 | 673 | 674 | #endif /* CONFIG_H_ */ 675 | -------------------------------------------------------------------------------- /crates/kms-sys/src/helpers.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Helper functions used by other modules 3 | */ 4 | 5 | //#ifndef _GNU_SOURCE 6 | //#define _GNU_SOURCE 7 | //#endif 8 | 9 | #ifndef _CRT_SECURE_NO_WARNINGS 10 | #define _CRT_SECURE_NO_WARNINGS 11 | #endif 12 | 13 | #ifndef CONFIG 14 | #define CONFIG "config.h" 15 | #endif // CONFIG 16 | #include CONFIG 17 | 18 | #ifndef _WIN32 19 | #include 20 | #include 21 | #endif // _WIN32 22 | #ifndef _MSC_VER 23 | #include 24 | #else 25 | #include "wingetopt.h" 26 | #endif 27 | #include 28 | #include 29 | #include 30 | #include "helpers.h" 31 | #include "output.h" 32 | #include "endian.h" 33 | #include "shared_globals.h" 34 | 35 | #ifndef NO_INTERNAL_DATA 36 | #include "kmsdata.h" 37 | #endif // NO_INTERNAL_DATA 38 | 39 | #ifdef _WIN32 40 | #include 41 | #endif // _WIN32 42 | 43 | #if __APPLE__ 44 | #include 45 | #endif // __APPLE__ 46 | 47 | #if (__GLIBC__ || __linux__) && defined(USE_AUXV) 48 | #include 49 | #endif 50 | 51 | #if __FreeBSD__ || __FreeBSD_kernel__ 52 | #include 53 | #endif 54 | 55 | /* 56 | * UCS2 <-> UTF-8 functions 57 | * All functions use little endian UCS2 since we only need it to communicate with Windows via RPC 58 | */ 59 | 60 | // Convert one character from UTF-8 to UCS2 61 | // Returns 0xffff, if utf-8 evaluates to > 0xfffe (outside basic multilingual pane) 62 | WCHAR utf8_to_ucs2_char(const unsigned char *input, const unsigned char **end_ptr) 63 | { 64 | *end_ptr = input; 65 | if (input[0] == 0) 66 | return (WCHAR)~0; 67 | 68 | if (input[0] < 0x80) { 69 | *end_ptr = input + 1; 70 | return LE16(input[0]); 71 | } 72 | 73 | if ((input[0] & 0xE0) == 0xE0) { 74 | 75 | if (input[1] == 0 || input[2] == 0) 76 | return (WCHAR)~0; 77 | 78 | *end_ptr = input + 3; 79 | 80 | return 81 | LE16((input[0] & 0x0F) << 12 | 82 | (input[1] & 0x3F) << 6 | 83 | (input[2] & 0x3F)); 84 | } 85 | 86 | if ((input[0] & 0xC0) == 0xC0) { 87 | if (input[1] == 0) 88 | return (WCHAR)~0; 89 | 90 | *end_ptr = input + 2; 91 | 92 | return 93 | LE16((input[0] & 0x1F) << 6 | 94 | (input[1] & 0x3F)); 95 | } 96 | return (WCHAR)~0; 97 | } 98 | 99 | // Convert one character from UCS2 to UTF-8 100 | // Returns length of UTF-8 char (1, 2 or 3) or -1 on error (UTF-16 outside UCS2) 101 | // char *utf8 must be large enough to hold 3 bytes 102 | int ucs2_to_utf8_char(const WCHAR ucs2_le, char *utf8) 103 | { 104 | const WCHAR ucs2 = LE16(ucs2_le); 105 | 106 | if (ucs2 < 0x80) { 107 | utf8[0] = (char)ucs2; 108 | utf8[1] = '\0'; 109 | return 1; 110 | } 111 | 112 | if (ucs2 >= 0x80 && ucs2 < 0x800) { 113 | utf8[0] = (char)((ucs2 >> 6) | 0xC0); 114 | utf8[1] = (char)((ucs2 & 0x3F) | 0x80); 115 | utf8[2] = '\0'; 116 | return 2; 117 | } 118 | 119 | if (ucs2 >= 0x800 && ucs2 < 0xFFFF) { 120 | 121 | if (ucs2 >= 0xD800 && ucs2 <= 0xDFFF) { 122 | /* Ill-formed (UTF-16 ouside of BMP) */ 123 | return -1; 124 | } 125 | 126 | utf8[0] = ((ucs2 >> 12)) | 0xE0; 127 | utf8[1] = ((ucs2 >> 6) & 0x3F) | 0x80; 128 | utf8[2] = ((ucs2) & 0x3F) | 0x80; 129 | utf8[3] = '\0'; 130 | return 3; 131 | } 132 | 133 | return -1; 134 | } 135 | 136 | 137 | // Converts UTF8 to UCS2. Returns size in bytes of the converted string or -1 on error 138 | size_t utf8_to_ucs2(WCHAR* const ucs2_le, const char* const utf8, const size_t maxucs2, const size_t maxutf8) 139 | { 140 | const unsigned char* current_utf8 = (unsigned char*)utf8; 141 | WCHAR* current_ucs2_le = ucs2_le; 142 | 143 | for (; *current_utf8; current_ucs2_le++) 144 | { 145 | size_t size = (char*)current_utf8 - utf8; 146 | 147 | if (size >= maxutf8) return (size_t)-1; 148 | if (((*current_utf8 & 0xc0) == 0xc0) && (size >= maxutf8 - 1)) return (size_t)-1; 149 | if (((*current_utf8 & 0xe0) == 0xe0) && (size >= maxutf8 - 2)) return (size_t)-1; 150 | if (current_ucs2_le - ucs2_le >= (intptr_t)maxucs2 - 1) return (size_t)-1; 151 | 152 | *current_ucs2_le = utf8_to_ucs2_char(current_utf8, ¤t_utf8); 153 | current_ucs2_le[1] = 0; 154 | 155 | if (*current_ucs2_le == (WCHAR)-1) return (size_t)-1; 156 | } 157 | return current_ucs2_le - ucs2_le; 158 | } 159 | 160 | // Converts UCS2 to UTF-8. Returns TRUE or FALSE 161 | BOOL ucs2_to_utf8(const WCHAR* const ucs2_le, char* utf8, size_t maxucs2, size_t maxutf8) 162 | { 163 | char utf8_char[4]; 164 | const WCHAR* current_ucs2 = ucs2_le; 165 | unsigned int index_utf8 = 0; 166 | 167 | for (*utf8 = 0; *current_ucs2; current_ucs2++) 168 | { 169 | if (current_ucs2 - ucs2_le > (intptr_t)maxucs2) return FALSE; 170 | int len = ucs2_to_utf8_char(*current_ucs2, utf8_char); 171 | if (index_utf8 + len > maxutf8) return FALSE; 172 | strncat(utf8, utf8_char, len); 173 | index_utf8 += len; 174 | } 175 | 176 | return TRUE; 177 | } 178 | 179 | /* End of UTF-8 <-> UCS2 conversion */ 180 | 181 | 182 | // Checks, whether a string is a valid integer number between min and max. Returns TRUE or FALSE. Puts int value in *value 183 | BOOL stringToInt(const char *const szValue, const unsigned int min, const unsigned int max, unsigned int *const value) 184 | { 185 | char *nextchar; 186 | 187 | errno = 0; 188 | long long result = vlmcsd_strtoll(szValue, &nextchar, 10); 189 | 190 | if (errno || result < (long long)min || result >(long long)max || *nextchar) 191 | { 192 | return FALSE; 193 | } 194 | 195 | *value = (unsigned int)result; 196 | return TRUE; 197 | } 198 | 199 | 200 | //Converts a String Guid to a host binary guid in host endianess 201 | int_fast8_t string2UuidLE(const char *const restrict input, GUID *const restrict guid) 202 | { 203 | int i; 204 | 205 | if (strlen(input) < GUID_STRING_LENGTH) return FALSE; 206 | if (input[8] != '-' || input[13] != '-' || input[18] != '-' || input[23] != '-') return FALSE; 207 | 208 | for (i = 0; i < GUID_STRING_LENGTH; i++) 209 | { 210 | if (i == 8 || i == 13 || i == 18 || i == 23) continue; 211 | 212 | const char c = (char)toupper((int)input[i]); 213 | 214 | if (c < '0' || c > 'F' || (c > '9' && c < 'A')) return FALSE; 215 | } 216 | 217 | char inputCopy[GUID_STRING_LENGTH + 1]; 218 | strncpy(inputCopy, input, GUID_STRING_LENGTH + 1); 219 | inputCopy[8] = inputCopy[13] = inputCopy[18] = 0; 220 | 221 | hex2bin((BYTE*)&guid->Data1, inputCopy, 8); 222 | hex2bin((BYTE*)&guid->Data2, inputCopy + 9, 4); 223 | hex2bin((BYTE*)&guid->Data3, inputCopy + 14, 4); 224 | hex2bin(guid->Data4, input + 19, 16); 225 | 226 | guid->Data1 = BS32(guid->Data1); 227 | guid->Data2 = BS16(guid->Data2); 228 | guid->Data3 = BS16(guid->Data3); 229 | return TRUE; 230 | } 231 | 232 | 233 | __pure DWORD timeSpanString2Seconds(const char *const restrict argument) 234 | { 235 | char *unitId; 236 | 237 | long long val = vlmcsd_strtoll(argument, &unitId, 10); 238 | 239 | switch (toupper((int)*unitId)) 240 | { 241 | case 'W': 242 | val *= 7; 243 | case 'D': 244 | val *= 24; 245 | case 'H': 246 | val *= 60; 247 | case 0: 248 | case 'M': 249 | val *= 60; 250 | case 'S': 251 | break; 252 | default: 253 | return 0; 254 | } 255 | 256 | if (*unitId && unitId[1]) return 0; 257 | if (val < 1) val = 1; 258 | return (DWORD)(val & UINT_MAX); 259 | } 260 | 261 | 262 | #if !IS_LIBRARY 263 | //Checks a command line argument if it is numeric and between min and max. Returns the numeric value or exits on error 264 | __pure unsigned int getOptionArgumentInt(const char o, const unsigned int min, const unsigned int max) 265 | { 266 | unsigned int result; 267 | 268 | if (!stringToInt(optarg, min, max, &result)) 269 | { 270 | printerrorf("Fatal: Option \"-%c\" must be numeric between %u and %u.\n", o, min, max); 271 | exit(VLMCSD_EINVAL); 272 | } 273 | 274 | return result; 275 | } 276 | 277 | // Resets getopt() to start parsing from the beginning 278 | void optReset(void) 279 | { 280 | #if __minix__ || defined(__BSD__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) 281 | optind = 1; 282 | optreset = 1; // Makes newer BSD getopt happy 283 | #elif defined(__UCLIBC__) // uClibc headers also define __GLIBC__ so be careful here 284 | optind = 0; // uClibc seeks compatibility with GLIBC 285 | #elif defined(__GLIBC__) 286 | optind = 0; // Makes GLIBC getopt happy 287 | #else // Standard for most systems 288 | optind = 1; 289 | #endif 290 | } 291 | #endif // !IS_LIBRARY 292 | 293 | #if _WIN32 || __CYGWIN__ 294 | 295 | // Returns a static message buffer containing text for a given Win32 error. Not thread safe (same as strerror) 296 | char* win_strerror(const int message) 297 | { 298 | #define STRERROR_BUFFER_SIZE 256 299 | static char buffer[STRERROR_BUFFER_SIZE]; 300 | 301 | FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, message, 0, buffer, STRERROR_BUFFER_SIZE, NULL); 302 | return buffer; 303 | } 304 | 305 | #endif // _WIN32 || __CYGWIN__ 306 | 307 | 308 | /* 309 | * parses an address in the form host:[port] in addr 310 | * returns host and port in seperate strings 311 | */ 312 | void parseAddress(char *const addr, char** szHost, char** szPort) 313 | { 314 | *szHost = addr; 315 | 316 | # ifndef NO_SOCKETS 317 | *szPort = (char*)defaultport; 318 | # else // NO_SOCKETS 319 | *szPort = "1688"; 320 | # endif // NO_SOCKETS 321 | 322 | char *lastcolon = strrchr(addr, ':'); 323 | char *firstcolon = strchr(addr, ':'); 324 | char *closingbracket = strrchr(addr, ']'); 325 | 326 | if (*addr == '[' && closingbracket) //Address in brackets 327 | { 328 | *closingbracket = 0; 329 | (*szHost)++; 330 | 331 | if (closingbracket[1] == ':') 332 | *szPort = closingbracket + 2; 333 | } 334 | else if (firstcolon && firstcolon == lastcolon) //IPv4 address or hostname with port 335 | { 336 | *firstcolon = 0; 337 | *szPort = firstcolon + 1; 338 | } 339 | } 340 | 341 | 342 | // Initialize random generator (needs to be done in each thread) 343 | void randomNumberInit() 344 | { 345 | # if _MSC_VER 346 | srand(GetTickCount()); 347 | # else 348 | struct timeval tv; 349 | gettimeofday(&tv, NULL); 350 | srand((unsigned int)(tv.tv_sec ^ tv.tv_usec)); 351 | # endif 352 | } 353 | 354 | 355 | // We always exit immediately if any OOM condition occurs 356 | __noreturn void OutOfMemory(void) 357 | { 358 | errorout("Fatal: Out of memory"); 359 | exit(VLMCSD_ENOMEM); 360 | } 361 | 362 | 363 | void* vlmcsd_malloc(size_t len) 364 | { 365 | void* buf = malloc(len); 366 | if (!buf) OutOfMemory(); 367 | return buf; 368 | } 369 | 370 | char* vlmcsd_strdup(const char* src) 371 | { 372 | # if _MSC_VER 373 | char* dst = _strdup(src); 374 | # else // !_MSC_VER 375 | char* dst = strdup(src); 376 | # endif 377 | 378 | if (!dst) OutOfMemory(); 379 | return dst; 380 | } 381 | 382 | 383 | /* 384 | * Converts hex digits to bytes in big-endian order. 385 | * Ignores any non-hex characters 386 | */ 387 | void hex2bin(BYTE *const bin, const char *hex, const size_t maxbin) 388 | { 389 | static const char *const hexdigits = "0123456789ABCDEF"; 390 | char* nextchar; 391 | size_t i; 392 | 393 | for (i = 0; (i < 16) && utf8_to_ucs2_char((const unsigned char*)hex, (const unsigned char**)&nextchar) != (WCHAR)-1; hex = nextchar) 394 | { 395 | const char* pos = strchr(hexdigits, toupper((int)*hex)); 396 | if (!pos) continue; 397 | 398 | if (!(i & 1)) bin[i >> 1] = 0; 399 | bin[i >> 1] |= (char)(pos - hexdigits); 400 | if (!(i & 1)) bin[i >> 1] <<= 4; 401 | i++; 402 | if (i >> 1 > maxbin) break; 403 | } 404 | } 405 | 406 | 407 | __pure BOOL getArgumentBool(int_fast8_t *result, const char *const argument) 408 | { 409 | if ( 410 | !strncasecmp(argument, "true", 4) || 411 | !strncasecmp(argument, "on", 2) || 412 | !strncasecmp(argument, "yes", 3) || 413 | !strncasecmp(argument, "1", 1) 414 | ) 415 | { 416 | *result = TRUE; 417 | return TRUE; 418 | } 419 | else if ( 420 | !strncasecmp(argument, "false", 5) || 421 | !strncasecmp(argument, "off", 3) || 422 | !strncasecmp(argument, "no", 2) || 423 | !strncasecmp(argument, "0", 1) 424 | ) 425 | { 426 | *result = FALSE; 427 | return TRUE; 428 | } 429 | 430 | return FALSE; 431 | } 432 | 433 | #ifndef IS_LIBRARY 434 | #ifndef NO_EXTERNAL_DATA 435 | __noreturn static void dataFileReadError() 436 | { 437 | const int error = errno; 438 | errorout("Fatal: Could not read %s: %s\n", fn_data, strerror(error)); 439 | exit(error); 440 | } 441 | 442 | __noreturn static void dataFileFormatError() 443 | { 444 | errorout("Fatal: %s is not a KMS data file version 2.x\n", fn_data); 445 | exit(VLMCSD_EINVAL); 446 | } 447 | #endif // NO_EXTERNAL_DATA 448 | 449 | #if !defined(DATA_FILE) || !defined(NO_SIGHUP) 450 | void getExeName() 451 | { 452 | if (fn_exe != NULL) return; 453 | 454 | # if (__GLIBC__ || __linux__) && defined(USE_AUXV) 455 | 456 | fn_exe = (char*)getauxval(AT_EXECFN); 457 | 458 | # elif (__ANDROID__ && __ANDROID_API__ < 16) || (__UCLIBC__ && __UCLIBC_MAJOR__ < 1 && !defined(NO_PROCFS)) // Workaround for older uclibc 459 | 460 | char temp[PATH_MAX + 1]; 461 | 462 | if (realpath("/proc/self/exe", temp) == temp) 463 | { 464 | fn_exe = vlmcsd_strdup(temp); 465 | } 466 | 467 | # elif (__linux__ || __CYGWIN__) && !defined(NO_PROCFS) 468 | 469 | fn_exe = realpath("/proc/self/exe", NULL); 470 | 471 | # elif (__FreeBSD__ || __FreeBSD_kernel__) 472 | 473 | int mib[4]; 474 | mib[0] = CTL_KERN; 475 | mib[1] = KERN_PROC; 476 | mib[2] = KERN_PROC_PATHNAME; 477 | mib[3] = -1; 478 | char path[PATH_MAX + 1]; 479 | size_t cb = sizeof(path); 480 | 481 | if (!sysctl(mib, 4, path, &cb, NULL, 0)) 482 | { 483 | fn_exe = vlmcsd_strdup(path); 484 | } 485 | 486 | # elif (__DragonFly__) && !defined(NO_PROCFS) 487 | 488 | fn_exe = realpath("/proc/curproc/file", NULL); 489 | 490 | # elif __NetBSD__ && !defined(NO_PROCFS) 491 | 492 | fn_exe = realpath("/proc/curproc/exe", NULL); 493 | 494 | # elif __sun__ 495 | 496 | fn_exe = getexecname(); 497 | 498 | # elif __APPLE__ 499 | 500 | char path[PATH_MAX + 1]; 501 | uint32_t size = sizeof(path); 502 | 503 | if (_NSGetExecutablePath(path, &size) == 0) 504 | { 505 | fn_exe = vlmcsd_strdup(path); 506 | } 507 | 508 | # elif _WIN32 509 | 510 | char path[512]; 511 | GetModuleFileName(GetModuleHandle(NULL), path, 512); 512 | path[511] = 0; 513 | fn_exe = vlmcsd_strdup(path); 514 | 515 | # else 516 | // Sorry no exe detection 517 | # endif 518 | } 519 | #endif // defined(DATA_FILE) && defined(NO_SIGHUP) 520 | 521 | #if !defined(DATA_FILE) && !defined(NO_EXTERNAL_DATA) 522 | #ifdef _WIN32 523 | static void getDefaultDataFile() 524 | { 525 | char fileName[MAX_PATH]; 526 | getExeName(); 527 | strncpy(fileName, fn_exe, MAX_PATH); 528 | PathRemoveFileSpec(fileName); 529 | strncat(fileName, "\\vlmcsd.kmd", MAX_PATH - 11); 530 | fn_data = vlmcsd_strdup(fileName); 531 | } 532 | #else // !_WIN32 533 | static void getDefaultDataFile() 534 | { 535 | char fileName[512]; 536 | getExeName(); 537 | 538 | if (!fn_exe) 539 | { 540 | fn_data = (char*)"/etc/vlmcsd.kmd"; 541 | return; 542 | } 543 | 544 | char* fn_exe_copy = vlmcsd_strdup(fn_exe); 545 | strncpy(fileName, dirname(fn_exe_copy), 512); 546 | free(fn_exe_copy); 547 | strncat(fileName, "/vlmcsd.kmd", 500); 548 | fn_data = vlmcsd_strdup(fileName); 549 | } 550 | #endif // !_WIN32 551 | #endif // !defined(DATA_FILE) && !defined(NO_EXTERNAL_DATA) 552 | 553 | void loadKmsData() 554 | { 555 | # ifndef NO_INTERNAL_DATA 556 | KmsData = (PVlmcsdHeader_t)DefaultKmsData; 557 | # endif // NO_INTERNAL_DATA 558 | 559 | # ifndef NO_EXTERNAL_DATA 560 | long size; 561 | # ifndef NO_INTERNAL_DATA 562 | size = (long)getDefaultKmsDataSize(); 563 | # endif // NO_INTERNAL_DATA 564 | 565 | # ifndef DATA_FILE 566 | if (!fn_data) getDefaultDataFile(); 567 | # endif // DATA_FILE 568 | 569 | if (strcmp(fn_data, "-")) 570 | { 571 | FILE *file = fopen(fn_data, "rb"); 572 | 573 | if (!file) 574 | { 575 | # ifndef NO_INTERNAL_DATA 576 | if (ExplicitDataLoad) 577 | # endif // NO_INTERNAL_DATA 578 | { 579 | dataFileReadError(); 580 | } 581 | } 582 | else 583 | { 584 | if (fseek(file, 0, SEEK_END)) dataFileReadError(); 585 | size = ftell(file); 586 | if (size == -1L) dataFileReadError(); 587 | 588 | KmsData = (PVlmcsdHeader_t)vlmcsd_malloc(size); 589 | if (fseek(file, 0, SEEK_SET)) dataFileReadError(); 590 | 591 | const size_t bytesRead = fread(KmsData, 1, size, file); 592 | if ((long)bytesRead != size) dataFileReadError(); 593 | fclose(file); 594 | 595 | # if !defined(NO_LOG) && !defined(NO_SOCKETS) 596 | if (!InetdMode) logger("Read KMS data file version %u.%u %s\n", (unsigned int)LE16(KmsData->MajorVer), (unsigned int)LE16(KmsData->MinorVer), fn_data); 597 | # endif // NO_LOG 598 | } 599 | } 600 | 601 | 602 | # endif // NO_EXTERNAL_DATA 603 | 604 | # ifndef UNSAFE_DATA_LOAD 605 | if (((BYTE*)KmsData)[size - 1] != 0) dataFileFormatError(); 606 | # endif // UNSAFE_DATA_LOAD 607 | 608 | KmsData->MajorVer = LE16(KmsData->MajorVer); 609 | KmsData->MinorVer = LE16(KmsData->MinorVer); 610 | KmsData->AppItemCount = LE32(KmsData->AppItemCount); 611 | KmsData->KmsItemCount = LE32(KmsData->KmsItemCount); 612 | KmsData->SkuItemCount = LE32(KmsData->SkuItemCount); 613 | KmsData->HostBuildCount = LE32(KmsData->HostBuildCount); 614 | 615 | uint32_t i; 616 | 617 | for (i = 0; i < vlmcsd_countof(KmsData->Datapointers); i++) 618 | { 619 | KmsData->Datapointers[i].Pointer = (BYTE*)KmsData + LE64(KmsData->Datapointers[i].Offset); 620 | # ifndef UNSAFE_DATA_LOAD 621 | if ((BYTE*)KmsData->Datapointers[i].Pointer > (BYTE*)KmsData + size) dataFileFormatError(); 622 | # endif // UNSAFE_DATA_LOAD 623 | } 624 | 625 | for (i = 0; i < KmsData->CsvlkCount; i++) 626 | { 627 | PCsvlkData_t csvlkData = &KmsData->CsvlkData[i]; 628 | csvlkData->EPid = (char*)KmsData + LE64(csvlkData->EPidOffset); 629 | csvlkData->ReleaseDate = LE64(csvlkData->ReleaseDate); 630 | # ifndef UNSAFE_DATA_LOAD 631 | if (csvlkData->EPid > (char*)KmsData + size) dataFileFormatError(); 632 | # endif // UNSAFE_DATA_LOAD 633 | 634 | # ifndef NO_RANDOM_EPID 635 | csvlkData->GroupId = LE32(csvlkData->GroupId); 636 | csvlkData->MinKeyId = LE32(csvlkData->MinKeyId); 637 | csvlkData->MaxKeyId = LE32(csvlkData->MaxKeyId); 638 | # endif // NO_RANDOM_EPID 639 | } 640 | 641 | for (i = 0; i < (uint32_t)KmsData->HostBuildCount; i++) 642 | { 643 | PHostBuild_t hostBuild = &KmsData->HostBuildList[i]; 644 | hostBuild->BuildNumber = LE32(hostBuild->BuildNumber); 645 | hostBuild->Flags = LE32(hostBuild->Flags); 646 | hostBuild->PlatformId = LE32(hostBuild->PlatformId); 647 | hostBuild->ReleaseDate = LE64(hostBuild->ReleaseDate); 648 | hostBuild->DisplayName = (char*)KmsData + LE64(hostBuild->DisplayNameOffset); 649 | # ifndef UNSAFE_DATA_LOAD 650 | if (hostBuild->DisplayName > (char*)KmsData + size) dataFileFormatError(); 651 | # endif // UNSAFE_DATA_LOAD 652 | } 653 | 654 | const uint32_t totalItemCount = KmsData->AppItemCount + KmsData->KmsItemCount + KmsData->SkuItemCount; 655 | 656 | # ifndef NO_EXTERNAL_DATA 657 | if ( 658 | memcmp(KmsData->Magic, "KMD", sizeof(KmsData->Magic)) || 659 | KmsData->MajorVer != 2 660 | # ifndef UNSAFE_DATA_LOAD 661 | || 662 | sizeof(VlmcsdHeader_t) + totalItemCount * sizeof(VlmcsdData_t) >= ((uint64_t)size) 663 | # endif //UNSAFE_DATA_LOAD 664 | ) 665 | { 666 | dataFileFormatError(); 667 | } 668 | # endif // NO_EXTERNAL_DATA 669 | 670 | for (i = 0; i < totalItemCount; i++) 671 | { 672 | PVlmcsdData_t item = &KmsData->AppItemList[i]; 673 | item->Name = (char*)KmsData + LE64(item->NameOffset); 674 | 675 | # ifndef UNSAFE_DATA_LOAD 676 | if ( 677 | item->Name >= (char*)KmsData + (uint64_t)size || 678 | (KmsData->AppItemCount && item->AppIndex >= KmsData->AppItemCount) || 679 | item->KmsIndex >= KmsData->KmsItemCount 680 | ) 681 | { 682 | dataFileFormatError(); 683 | } 684 | # endif // UNSAFE_DATA_LOAD 685 | } 686 | } 687 | 688 | #ifndef NO_SOCKETS 689 | void exitOnWarningLevel(const int_fast8_t level) 690 | { 691 | if (ExitLevel >= level) 692 | { 693 | printerrorf("Fatal: Exiting on warning level %i or greater\n", (int)ExitLevel); 694 | exit(-1); 695 | } 696 | } 697 | #endif // !NO_SOCKETS 698 | 699 | #endif // IS_LIBRARY 700 | 701 | 702 | #if __ANDROID__ && !defined(USE_THREADS) // Bionic does not wrap these syscalls (intentionally because Google fears, developers don't know how to use it) 703 | 704 | #ifdef __NR_shmget 705 | int shmget(key_t key, size_t size, int shmflg) 706 | { 707 | return syscall(__NR_shmget, key, size, shmflg); 708 | } 709 | #endif // __NR_shmget 710 | 711 | #ifdef __NR_shmat 712 | void *shmat(int shmid, const void *shmaddr, int shmflg) 713 | { 714 | return (void *)syscall(__NR_shmat, shmid, shmaddr, shmflg); 715 | } 716 | #endif // __NR_shmat 717 | 718 | #ifdef __NR_shmdt 719 | int shmdt(const void *shmaddr) 720 | { 721 | return syscall(__NR_shmdt, shmaddr); 722 | } 723 | #endif // __NR_shmdt 724 | 725 | #ifdef __NR_shmctl 726 | int shmctl(int shmid, int cmd, /*struct shmid_ds*/void *buf) 727 | { 728 | return syscall(__NR_shmctl, shmid, cmd, buf); 729 | } 730 | #endif // __NR_shmctl 731 | 732 | #endif // __ANDROID__ && !defined(USE_THREADS) 733 | 734 | 735 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 2.1, February 1999 3 | 4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | [This is the first released version of the Lesser GPL. It also counts 10 | as the successor of the GNU Library Public License, version 2, hence 11 | the version number 2.1.] 12 | 13 | Preamble 14 | 15 | The licenses for most software are designed to take away your 16 | freedom to share and change it. By contrast, the GNU General Public 17 | Licenses are intended to guarantee your freedom to share and change 18 | free software--to make sure the software is free for all its users. 19 | 20 | This license, the Lesser General Public License, applies to some 21 | specially designated software packages--typically libraries--of the 22 | Free Software Foundation and other authors who decide to use it. You 23 | can use it too, but we suggest you first think carefully about whether 24 | this license or the ordinary General Public License is the better 25 | strategy to use in any particular case, based on the explanations below. 26 | 27 | When we speak of free software, we are referring to freedom of use, 28 | not price. Our General Public Licenses are designed to make sure that 29 | you have the freedom to distribute copies of free software (and charge 30 | for this service if you wish); that you receive source code or can get 31 | it if you want it; that you can change the software and use pieces of 32 | it in new free programs; and that you are informed that you can do 33 | these things. 34 | 35 | To protect your rights, we need to make restrictions that forbid 36 | distributors to deny you these rights or to ask you to surrender these 37 | rights. These restrictions translate to certain responsibilities for 38 | you if you distribute copies of the library or if you modify it. 39 | 40 | For example, if you distribute copies of the library, whether gratis 41 | or for a fee, you must give the recipients all the rights that we gave 42 | you. You must make sure that they, too, receive or can get the source 43 | code. If you link other code with the library, you must provide 44 | complete object files to the recipients, so that they can relink them 45 | with the library after making changes to the library and recompiling 46 | it. And you must show them these terms so they know their rights. 47 | 48 | We protect your rights with a two-step method: (1) we copyright the 49 | library, and (2) we offer you this license, which gives you legal 50 | permission to copy, distribute and/or modify the library. 51 | 52 | To protect each distributor, we want to make it very clear that 53 | there is no warranty for the free library. Also, if the library is 54 | modified by someone else and passed on, the recipients should know 55 | that what they have is not the original version, so that the original 56 | author's reputation will not be affected by problems that might be 57 | introduced by others. 58 | 59 | Finally, software patents pose a constant threat to the existence of 60 | any free program. We wish to make sure that a company cannot 61 | effectively restrict the users of a free program by obtaining a 62 | restrictive license from a patent holder. Therefore, we insist that 63 | any patent license obtained for a version of the library must be 64 | consistent with the full freedom of use specified in this license. 65 | 66 | Most GNU software, including some libraries, is covered by the 67 | ordinary GNU General Public License. This license, the GNU Lesser 68 | General Public License, applies to certain designated libraries, and 69 | is quite different from the ordinary General Public License. We use 70 | this license for certain libraries in order to permit linking those 71 | libraries into non-free programs. 72 | 73 | When a program is linked with a library, whether statically or using 74 | a shared library, the combination of the two is legally speaking a 75 | combined work, a derivative of the original library. The ordinary 76 | General Public License therefore permits such linking only if the 77 | entire combination fits its criteria of freedom. The Lesser General 78 | Public License permits more lax criteria for linking other code with 79 | the library. 80 | 81 | We call this license the "Lesser" General Public License because it 82 | does Less to protect the user's freedom than the ordinary General 83 | Public License. It also provides other free software developers Less 84 | of an advantage over competing non-free programs. These disadvantages 85 | are the reason we use the ordinary General Public License for many 86 | libraries. However, the Lesser license provides advantages in certain 87 | special circumstances. 88 | 89 | For example, on rare occasions, there may be a special need to 90 | encourage the widest possible use of a certain library, so that it becomes 91 | a de-facto standard. To achieve this, non-free programs must be 92 | allowed to use the library. A more frequent case is that a free 93 | library does the same job as widely used non-free libraries. In this 94 | case, there is little to gain by limiting the free library to free 95 | software only, so we use the Lesser General Public License. 96 | 97 | In other cases, permission to use a particular library in non-free 98 | programs enables a greater number of people to use a large body of 99 | free software. For example, permission to use the GNU C Library in 100 | non-free programs enables many more people to use the whole GNU 101 | operating system, as well as its variant, the GNU/Linux operating 102 | system. 103 | 104 | Although the Lesser General Public License is Less protective of the 105 | users' freedom, it does ensure that the user of a program that is 106 | linked with the Library has the freedom and the wherewithal to run 107 | that program using a modified version of the Library. 108 | 109 | The precise terms and conditions for copying, distribution and 110 | modification follow. Pay close attention to the difference between a 111 | "work based on the library" and a "work that uses the library". The 112 | former contains code derived from the library, whereas the latter must 113 | be combined with the library in order to run. 114 | 115 | GNU LESSER GENERAL PUBLIC LICENSE 116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 117 | 118 | 0. This License Agreement applies to any software library or other 119 | program which contains a notice placed by the copyright holder or 120 | other authorized party saying it may be distributed under the terms of 121 | this Lesser General Public License (also called "this License"). 122 | Each licensee is addressed as "you". 123 | 124 | A "library" means a collection of software functions and/or data 125 | prepared so as to be conveniently linked with application programs 126 | (which use some of those functions and data) to form executables. 127 | 128 | The "Library", below, refers to any such software library or work 129 | which has been distributed under these terms. A "work based on the 130 | Library" means either the Library or any derivative work under 131 | copyright law: that is to say, a work containing the Library or a 132 | portion of it, either verbatim or with modifications and/or translated 133 | straightforwardly into another language. (Hereinafter, translation is 134 | included without limitation in the term "modification".) 135 | 136 | "Source code" for a work means the preferred form of the work for 137 | making modifications to it. For a library, complete source code means 138 | all the source code for all modules it contains, plus any associated 139 | interface definition files, plus the scripts used to control compilation 140 | and installation of the library. 141 | 142 | Activities other than copying, distribution and modification are not 143 | covered by this License; they are outside its scope. The act of 144 | running a program using the Library is not restricted, and output from 145 | such a program is covered only if its contents constitute a work based 146 | on the Library (independent of the use of the Library in a tool for 147 | writing it). Whether that is true depends on what the Library does 148 | and what the program that uses the Library does. 149 | 150 | 1. You may copy and distribute verbatim copies of the Library's 151 | complete source code as you receive it, in any medium, provided that 152 | you conspicuously and appropriately publish on each copy an 153 | appropriate copyright notice and disclaimer of warranty; keep intact 154 | all the notices that refer to this License and to the absence of any 155 | warranty; and distribute a copy of this License along with the 156 | Library. 157 | 158 | You may charge a fee for the physical act of transferring a copy, 159 | and you may at your option offer warranty protection in exchange for a 160 | fee. 161 | 162 | 2. You may modify your copy or copies of the Library or any portion 163 | of it, thus forming a work based on the Library, and copy and 164 | distribute such modifications or work under the terms of Section 1 165 | above, provided that you also meet all of these conditions: 166 | 167 | a) The modified work must itself be a software library. 168 | 169 | b) You must cause the files modified to carry prominent notices 170 | stating that you changed the files and the date of any change. 171 | 172 | c) You must cause the whole of the work to be licensed at no 173 | charge to all third parties under the terms of this License. 174 | 175 | d) If a facility in the modified Library refers to a function or a 176 | table of data to be supplied by an application program that uses 177 | the facility, other than as an argument passed when the facility 178 | is invoked, then you must make a good faith effort to ensure that, 179 | in the event an application does not supply such function or 180 | table, the facility still operates, and performs whatever part of 181 | its purpose remains meaningful. 182 | 183 | (For example, a function in a library to compute square roots has 184 | a purpose that is entirely well-defined independent of the 185 | application. Therefore, Subsection 2d requires that any 186 | application-supplied function or table used by this function must 187 | be optional: if the application does not supply it, the square 188 | root function must still compute square roots.) 189 | 190 | These requirements apply to the modified work as a whole. If 191 | identifiable sections of that work are not derived from the Library, 192 | and can be reasonably considered independent and separate works in 193 | themselves, then this License, and its terms, do not apply to those 194 | sections when you distribute them as separate works. But when you 195 | distribute the same sections as part of a whole which is a work based 196 | on the Library, the distribution of the whole must be on the terms of 197 | this License, whose permissions for other licensees extend to the 198 | entire whole, and thus to each and every part regardless of who wrote 199 | it. 200 | 201 | Thus, it is not the intent of this section to claim rights or contest 202 | your rights to work written entirely by you; rather, the intent is to 203 | exercise the right to control the distribution of derivative or 204 | collective works based on the Library. 205 | 206 | In addition, mere aggregation of another work not based on the Library 207 | with the Library (or with a work based on the Library) on a volume of 208 | a storage or distribution medium does not bring the other work under 209 | the scope of this License. 210 | 211 | 3. You may opt to apply the terms of the ordinary GNU General Public 212 | License instead of this License to a given copy of the Library. To do 213 | this, you must alter all the notices that refer to this License, so 214 | that they refer to the ordinary GNU General Public License, version 2, 215 | instead of to this License. (If a newer version than version 2 of the 216 | ordinary GNU General Public License has appeared, then you can specify 217 | that version instead if you wish.) Do not make any other change in 218 | these notices. 219 | 220 | Once this change is made in a given copy, it is irreversible for 221 | that copy, so the ordinary GNU General Public License applies to all 222 | subsequent copies and derivative works made from that copy. 223 | 224 | This option is useful when you wish to copy part of the code of 225 | the Library into a program that is not a library. 226 | 227 | 4. You may copy and distribute the Library (or a portion or 228 | derivative of it, under Section 2) in object code or executable form 229 | under the terms of Sections 1 and 2 above provided that you accompany 230 | it with the complete corresponding machine-readable source code, which 231 | must be distributed under the terms of Sections 1 and 2 above on a 232 | medium customarily used for software interchange. 233 | 234 | If distribution of object code is made by offering access to copy 235 | from a designated place, then offering equivalent access to copy the 236 | source code from the same place satisfies the requirement to 237 | distribute the source code, even though third parties are not 238 | compelled to copy the source along with the object code. 239 | 240 | 5. A program that contains no derivative of any portion of the 241 | Library, but is designed to work with the Library by being compiled or 242 | linked with it, is called a "work that uses the Library". Such a 243 | work, in isolation, is not a derivative work of the Library, and 244 | therefore falls outside the scope of this License. 245 | 246 | However, linking a "work that uses the Library" with the Library 247 | creates an executable that is a derivative of the Library (because it 248 | contains portions of the Library), rather than a "work that uses the 249 | library". The executable is therefore covered by this License. 250 | Section 6 states terms for distribution of such executables. 251 | 252 | When a "work that uses the Library" uses material from a header file 253 | that is part of the Library, the object code for the work may be a 254 | derivative work of the Library even though the source code is not. 255 | Whether this is true is especially significant if the work can be 256 | linked without the Library, or if the work is itself a library. The 257 | threshold for this to be true is not precisely defined by law. 258 | 259 | If such an object file uses only numerical parameters, data 260 | structure layouts and accessors, and small macros and small inline 261 | functions (ten lines or less in length), then the use of the object 262 | file is unrestricted, regardless of whether it is legally a derivative 263 | work. (Executables containing this object code plus portions of the 264 | Library will still fall under Section 6.) 265 | 266 | Otherwise, if the work is a derivative of the Library, you may 267 | distribute the object code for the work under the terms of Section 6. 268 | Any executables containing that work also fall under Section 6, 269 | whether or not they are linked directly with the Library itself. 270 | 271 | 6. As an exception to the Sections above, you may also combine or 272 | link a "work that uses the Library" with the Library to produce a 273 | work containing portions of the Library, and distribute that work 274 | under terms of your choice, provided that the terms permit 275 | modification of the work for the customer's own use and reverse 276 | engineering for debugging such modifications. 277 | 278 | You must give prominent notice with each copy of the work that the 279 | Library is used in it and that the Library and its use are covered by 280 | this License. You must supply a copy of this License. If the work 281 | during execution displays copyright notices, you must include the 282 | copyright notice for the Library among them, as well as a reference 283 | directing the user to the copy of this License. Also, you must do one 284 | of these things: 285 | 286 | a) Accompany the work with the complete corresponding 287 | machine-readable source code for the Library including whatever 288 | changes were used in the work (which must be distributed under 289 | Sections 1 and 2 above); and, if the work is an executable linked 290 | with the Library, with the complete machine-readable "work that 291 | uses the Library", as object code and/or source code, so that the 292 | user can modify the Library and then relink to produce a modified 293 | executable containing the modified Library. (It is understood 294 | that the user who changes the contents of definitions files in the 295 | Library will not necessarily be able to recompile the application 296 | to use the modified definitions.) 297 | 298 | b) Use a suitable shared library mechanism for linking with the 299 | Library. A suitable mechanism is one that (1) uses at run time a 300 | copy of the library already present on the user's computer system, 301 | rather than copying library functions into the executable, and (2) 302 | will operate properly with a modified version of the library, if 303 | the user installs one, as long as the modified version is 304 | interface-compatible with the version that the work was made with. 305 | 306 | c) Accompany the work with a written offer, valid for at 307 | least three years, to give the same user the materials 308 | specified in Subsection 6a, above, for a charge no more 309 | than the cost of performing this distribution. 310 | 311 | d) If distribution of the work is made by offering access to copy 312 | from a designated place, offer equivalent access to copy the above 313 | specified materials from the same place. 314 | 315 | e) Verify that the user has already received a copy of these 316 | materials or that you have already sent this user a copy. 317 | 318 | For an executable, the required form of the "work that uses the 319 | Library" must include any data and utility programs needed for 320 | reproducing the executable from it. However, as a special exception, 321 | the materials to be distributed need not include anything that is 322 | normally distributed (in either source or binary form) with the major 323 | components (compiler, kernel, and so on) of the operating system on 324 | which the executable runs, unless that component itself accompanies 325 | the executable. 326 | 327 | It may happen that this requirement contradicts the license 328 | restrictions of other proprietary libraries that do not normally 329 | accompany the operating system. Such a contradiction means you cannot 330 | use both them and the Library together in an executable that you 331 | distribute. 332 | 333 | 7. You may place library facilities that are a work based on the 334 | Library side-by-side in a single library together with other library 335 | facilities not covered by this License, and distribute such a combined 336 | library, provided that the separate distribution of the work based on 337 | the Library and of the other library facilities is otherwise 338 | permitted, and provided that you do these two things: 339 | 340 | a) Accompany the combined library with a copy of the same work 341 | based on the Library, uncombined with any other library 342 | facilities. This must be distributed under the terms of the 343 | Sections above. 344 | 345 | b) Give prominent notice with the combined library of the fact 346 | that part of it is a work based on the Library, and explaining 347 | where to find the accompanying uncombined form of the same work. 348 | 349 | 8. You may not copy, modify, sublicense, link with, or distribute 350 | the Library except as expressly provided under this License. Any 351 | attempt otherwise to copy, modify, sublicense, link with, or 352 | distribute the Library is void, and will automatically terminate your 353 | rights under this License. However, parties who have received copies, 354 | or rights, from you under this License will not have their licenses 355 | terminated so long as such parties remain in full compliance. 356 | 357 | 9. You are not required to accept this License, since you have not 358 | signed it. However, nothing else grants you permission to modify or 359 | distribute the Library or its derivative works. These actions are 360 | prohibited by law if you do not accept this License. Therefore, by 361 | modifying or distributing the Library (or any work based on the 362 | Library), you indicate your acceptance of this License to do so, and 363 | all its terms and conditions for copying, distributing or modifying 364 | the Library or works based on it. 365 | 366 | 10. Each time you redistribute the Library (or any work based on the 367 | Library), the recipient automatically receives a license from the 368 | original licensor to copy, distribute, link with or modify the Library 369 | subject to these terms and conditions. You may not impose any further 370 | restrictions on the recipients' exercise of the rights granted herein. 371 | You are not responsible for enforcing compliance by third parties with 372 | this License. 373 | 374 | 11. If, as a consequence of a court judgment or allegation of patent 375 | infringement or for any other reason (not limited to patent issues), 376 | conditions are imposed on you (whether by court order, agreement or 377 | otherwise) that contradict the conditions of this License, they do not 378 | excuse you from the conditions of this License. If you cannot 379 | distribute so as to satisfy simultaneously your obligations under this 380 | License and any other pertinent obligations, then as a consequence you 381 | may not distribute the Library at all. For example, if a patent 382 | license would not permit royalty-free redistribution of the Library by 383 | all those who receive copies directly or indirectly through you, then 384 | the only way you could satisfy both it and this License would be to 385 | refrain entirely from distribution of the Library. 386 | 387 | If any portion of this section is held invalid or unenforceable under any 388 | particular circumstance, the balance of the section is intended to apply, 389 | and the section as a whole is intended to apply in other circumstances. 390 | 391 | It is not the purpose of this section to induce you to infringe any 392 | patents or other property right claims or to contest validity of any 393 | such claims; this section has the sole purpose of protecting the 394 | integrity of the free software distribution system which is 395 | implemented by public license practices. Many people have made 396 | generous contributions to the wide range of software distributed 397 | through that system in reliance on consistent application of that 398 | system; it is up to the author/donor to decide if he or she is willing 399 | to distribute software through any other system and a licensee cannot 400 | impose that choice. 401 | 402 | This section is intended to make thoroughly clear what is believed to 403 | be a consequence of the rest of this License. 404 | 405 | 12. If the distribution and/or use of the Library is restricted in 406 | certain countries either by patents or by copyrighted interfaces, the 407 | original copyright holder who places the Library under this License may add 408 | an explicit geographical distribution limitation excluding those countries, 409 | so that distribution is permitted only in or among countries not thus 410 | excluded. In such case, this License incorporates the limitation as if 411 | written in the body of this License. 412 | 413 | 13. The Free Software Foundation may publish revised and/or new 414 | versions of the Lesser General Public License from time to time. 415 | Such new versions will be similar in spirit to the present version, 416 | but may differ in detail to address new problems or concerns. 417 | 418 | Each version is given a distinguishing version number. If the Library 419 | specifies a version number of this License which applies to it and 420 | "any later version", you have the option of following the terms and 421 | conditions either of that version or of any later version published by 422 | the Free Software Foundation. If the Library does not specify a 423 | license version number, you may choose any version ever published by 424 | the Free Software Foundation. 425 | 426 | 14. If you wish to incorporate parts of the Library into other free 427 | programs whose distribution conditions are incompatible with these, 428 | write to the author to ask for permission. For software which is 429 | copyrighted by the Free Software Foundation, write to the Free 430 | Software Foundation; we sometimes make exceptions for this. Our 431 | decision will be guided by the two goals of preserving the free status 432 | of all derivatives of our free software and of promoting the sharing 433 | and reuse of software generally. 434 | 435 | NO WARRANTY 436 | 437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 446 | 447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 456 | DAMAGES. 457 | 458 | END OF TERMS AND CONDITIONS 459 | 460 | How to Apply These Terms to Your New Libraries 461 | 462 | If you develop a new library, and you want it to be of the greatest 463 | possible use to the public, we recommend making it free software that 464 | everyone can redistribute and change. You can do so by permitting 465 | redistribution under these terms (or, alternatively, under the terms of the 466 | ordinary General Public License). 467 | 468 | To apply these terms, attach the following notices to the library. It is 469 | safest to attach them to the start of each source file to most effectively 470 | convey the exclusion of warranty; and each file should have at least the 471 | "copyright" line and a pointer to where the full notice is found. 472 | 473 | 474 | Copyright (C) 475 | 476 | This library is free software; you can redistribute it and/or 477 | modify it under the terms of the GNU Lesser General Public 478 | License as published by the Free Software Foundation; either 479 | version 2.1 of the License, or (at your option) any later version. 480 | 481 | This library is distributed in the hope that it will be useful, 482 | but WITHOUT ANY WARRANTY; without even the implied warranty of 483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 484 | Lesser General Public License for more details. 485 | 486 | You should have received a copy of the GNU Lesser General Public 487 | License along with this library; if not, write to the Free Software 488 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 489 | USA 490 | 491 | Also add information on how to contact you by electronic and paper mail. 492 | 493 | You should also get your employer (if you work as a programmer) or your 494 | school, if any, to sign a "copyright disclaimer" for the library, if 495 | necessary. Here is a sample; alter the names: 496 | 497 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 498 | library `Frob' (a library for tweaking knobs) written by James Random 499 | Hacker. 500 | 501 | , 1 April 1990 502 | Ty Coon, President of Vice 503 | 504 | That's all there is to it! 505 | -------------------------------------------------------------------------------- /crates/kms-sys/src/network.c: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG 2 | #define CONFIG "config.h" 3 | #endif // CONFIG 4 | #include CONFIG 5 | 6 | #ifndef USE_MSRPC 7 | 8 | #ifndef _GNU_SOURCE 9 | #define _GNU_SOURCE 10 | #endif 11 | 12 | #include "types.h" 13 | 14 | #if HAVE_GETIFADDR && _WIN32 15 | #include 16 | #endif 17 | 18 | #include 19 | 20 | #ifndef _WIN32 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #if HAVE_GETIFADDR 29 | 30 | #if __ANDROID__ 31 | #include "ifaddrs-android.h" 32 | #elif defined(GETIFADDRS_MUSL) 33 | #include "ifaddrs-musl.h" 34 | #else // getifaddrs from OS 35 | #include 36 | #endif // getifaddrs from OS 37 | 38 | #endif // HAVE_GETIFADDR 39 | #endif // !WIN32 40 | 41 | #include "network.h" 42 | #include "endian.h" 43 | //#include "output.h" 44 | #include "helpers.h" 45 | #include "shared_globals.h" 46 | #include "rpc.h" 47 | 48 | #ifndef _WIN32 49 | typedef ssize_t(*sendrecv_t)(int, void*, size_t, int); 50 | #else 51 | typedef int (WINAPI *sendrecv_t)(SOCKET, void*, int, int); 52 | #endif 53 | 54 | 55 | // Send or receive a fixed number of bytes regardless if received in one or more chunks 56 | int_fast8_t sendrecv(SOCKET sock, BYTE *data, int len, int_fast8_t do_send) 57 | { 58 | int n; 59 | sendrecv_t f = do_send 60 | ? (sendrecv_t)send 61 | : (sendrecv_t)recv; 62 | 63 | do 64 | { 65 | n = f(sock, data, len, 0); 66 | } while ( 67 | (n < 0 && socket_errno == SOCKET_EINTR) || (n > 0 && (data += n, (len -= n) > 0))); 68 | 69 | return !len; 70 | } 71 | 72 | 73 | static int_fast8_t ip2str(char *restrict result, const size_t resultLength, const struct sockaddr *const restrict socketAddress, const socklen_t socketLength) 74 | { 75 | static const char *const fIPv4 = "%s:%s"; 76 | static const char *const fIPv6 = "[%s]:%s"; 77 | char ipAddress[64], portNumber[8]; 78 | 79 | if (getnameinfo 80 | ( 81 | socketAddress, 82 | socketLength, 83 | ipAddress, 84 | sizeof(ipAddress), 85 | portNumber, 86 | sizeof(portNumber), 87 | NI_NUMERICHOST | NI_NUMERICSERV 88 | )) 89 | { 90 | return FALSE; 91 | } 92 | 93 | if ((unsigned int)vlmcsd_snprintf(result, resultLength, socketAddress->sa_family == AF_INET6 ? fIPv6 : fIPv4, ipAddress, portNumber) > resultLength) return FALSE; 94 | return TRUE; 95 | } 96 | 97 | 98 | static int_fast8_t getSocketList(struct addrinfo **saList, const char *const addr, const int flags, const int AddressFamily) 99 | { 100 | int status; 101 | char *szHost, *szPort; 102 | const size_t len = strlen(addr) + 1; 103 | 104 | // Don't alloca too much 105 | if (len > 264) return FALSE; 106 | 107 | char *addrcopy = (char*)alloca(len); 108 | memcpy(addrcopy, addr, len); 109 | 110 | parseAddress(addrcopy, &szHost, &szPort); 111 | 112 | struct addrinfo hints; 113 | 114 | memset(&hints, 0, sizeof(struct addrinfo)); 115 | 116 | hints.ai_family = AddressFamily; 117 | hints.ai_socktype = SOCK_STREAM; 118 | hints.ai_protocol = IPPROTO_TCP; 119 | hints.ai_flags = flags; 120 | 121 | if ((status = getaddrinfo(szHost, szPort, &hints, saList))) 122 | { 123 | printerrorf("Warning: %s: %s\n", addr, gai_strerror(status)); 124 | return FALSE; 125 | } 126 | 127 | return TRUE; 128 | } 129 | 130 | 131 | static int_fast8_t setBlockingEnabled(SOCKET fd, int_fast8_t blocking) 132 | { 133 | if (fd == INVALID_SOCKET) return FALSE; 134 | 135 | #ifdef _WIN32 136 | 137 | unsigned long mode = blocking ? 0 : 1; 138 | return (ioctlsocket(fd, FIONBIO, &mode) == 0) ? TRUE : FALSE; 139 | 140 | #else // POSIX 141 | 142 | int flags = fcntl(fd, F_GETFL, 0); 143 | 144 | if (flags < 0) return FALSE; 145 | 146 | flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK); 147 | return (fcntl(fd, F_SETFL, flags) == 0) ? TRUE : FALSE; 148 | 149 | #endif // POSIX 150 | } 151 | 152 | 153 | int_fast8_t isDisconnected(const SOCKET s) 154 | { 155 | char buffer[1]; 156 | 157 | if (!setBlockingEnabled(s, FALSE)) return TRUE; 158 | 159 | const int n = recv(s, buffer, 1, MSG_PEEK); 160 | 161 | if (!setBlockingEnabled(s, TRUE)) return TRUE; 162 | if (n == 0) return TRUE; 163 | 164 | return FALSE; 165 | } 166 | 167 | 168 | #if !defined(NO_PRIVATE_IP_DETECT) 169 | // Check, if a sockaddr is a private IPv4 or IPv6 address 170 | static int_fast8_t isPrivateIPAddress(struct sockaddr* addr, socklen_t* length) 171 | { 172 | union v6addr 173 | { 174 | uint8_t bytes[16]; 175 | uint16_t words[8]; 176 | uint32_t dwords[4]; 177 | uint64_t qwords[2]; 178 | }; 179 | 180 | if (addr == NULL) return FALSE; 181 | 182 | switch (addr->sa_family) 183 | { 184 | case AF_INET6: 185 | { 186 | union v6addr* ipv6addr = (union v6addr*)&((struct sockaddr_in6*)addr)->sin6_addr; 187 | 188 | if 189 | ( 190 | (ipv6addr->qwords[0] != 0 || BE64(ipv6addr->qwords[1]) != 1) && // ::1 IPv6 localhost 191 | (BE16(ipv6addr->words[0]) & 0xe000) == 0x2000 // !2000::/3 192 | ) 193 | { 194 | return FALSE; 195 | } 196 | 197 | if (length) *length = sizeof(struct sockaddr_in6); 198 | break; 199 | } 200 | 201 | case AF_INET: 202 | { 203 | const uint32_t ipv4addr = BE32(((struct sockaddr_in*)addr)->sin_addr.s_addr); 204 | 205 | if 206 | ( 207 | (ipv4addr & 0xff000000) != 0x7f000000 && // 127.x.x.x localhost 208 | (ipv4addr & 0xffff0000) != 0xc0a80000 && // 192.168.x.x private routeable 209 | (ipv4addr & 0xffff0000) != 0xa9fe0000 && // 169.254.x.x link local 210 | (ipv4addr & 0xff000000) != 0x0a000000 && // 10.x.x.x private routeable 211 | (ipv4addr & 0xfff00000) != 0xac100000 // 172.16-31.x.x private routeable 212 | ) 213 | { 214 | return FALSE; 215 | } 216 | 217 | if (length) *length = sizeof(struct sockaddr_in); 218 | break; 219 | } 220 | 221 | default: 222 | return FALSE; 223 | } 224 | 225 | return TRUE; 226 | } 227 | #endif // !defined(NO_PRIVATE_IP_DETECT) 228 | 229 | 230 | // Connect to TCP address addr (e.g. "kms.example.com:1688") and return an 231 | // open socket for the connection if successful or INVALID_SOCKET otherwise 232 | SOCKET connectToAddress(const char *const addr, const int AddressFamily, int_fast8_t showHostName) 233 | { 234 | struct addrinfo *saList, *sa; 235 | SOCKET s = INVALID_SOCKET; 236 | char szAddr[128]; 237 | 238 | if (!getSocketList(&saList, addr, 0, AddressFamily)) return INVALID_SOCKET; 239 | 240 | for (sa = saList; sa; sa = sa->ai_next) 241 | { 242 | // struct sockaddr_in* addr4 = (struct sockaddr_in*)sa->ai_addr; 243 | // struct sockaddr_in6* addr6 = (struct sockaddr_in6*)sa->ai_addr; 244 | 245 | if (ip2str(szAddr, sizeof(szAddr), sa->ai_addr, (socklen_t)sa->ai_addrlen)) 246 | { 247 | showHostName ? printf("Connecting to %s (%s) ... ", addr, szAddr) : printf("Connecting to %s ... ", szAddr); 248 | fflush(stdout); 249 | } 250 | 251 | s = socket(sa->ai_family, SOCK_STREAM, IPPROTO_TCP); 252 | 253 | # if !defined(NO_TIMEOUT) && !__minix__ 254 | # ifndef _WIN32 // Standard Posix timeout structure 255 | 256 | struct timeval to; 257 | to.tv_sec = 10; 258 | to.tv_usec = 0; 259 | 260 | # else // Windows requires a DWORD with milliseconds 261 | 262 | DWORD to = 10000; 263 | 264 | # endif // _WIN32 265 | 266 | setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (sockopt_t)&to, sizeof(to)); 267 | setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (sockopt_t)&to, sizeof(to)); 268 | # endif // !defined(NO_TIMEOUT) && !__minix__ 269 | 270 | if (!connect(s, sa->ai_addr, (int)sa->ai_addrlen)) 271 | { 272 | printf("successful\n"); 273 | break; 274 | } 275 | 276 | printerrorf("%s: %s\n", szAddr, socket_errno == SOCKET_EINPROGRESS ? "Timed out" : vlmcsd_strerror(socket_errno)); 277 | 278 | socketclose(s); 279 | s = INVALID_SOCKET; 280 | } 281 | 282 | freeaddrinfo(saList); 283 | return s; 284 | } 285 | 286 | // fix for lame tomato toolchain 287 | # if !defined(IPV6_V6ONLY) && defined(__linux__) 288 | # define IPV6_V6ONLY (26) 289 | # endif // !defined(IPV6_V6ONLY) && defined(__linux__) 290 | 291 | 292 | #ifndef NO_SOCKETS 293 | 294 | static int_fast8_t allowSocketReuse(SOCKET s) 295 | { 296 | # if !__CYGWIN__ 297 | 298 | BOOL socketOption = TRUE; 299 | 300 | # if !_WIN32 301 | # define VLMCSD_SOCKET_OPTION SO_REUSEADDR 302 | # else // _WIN32 303 | # define VLMCSD_SOCKET_OPTION SO_EXCLUSIVEADDRUSE 304 | # endif // _WIN32 305 | 306 | if (setsockopt(s, SOL_SOCKET, VLMCSD_SOCKET_OPTION, (sockopt_t)&socketOption, sizeof(socketOption))) 307 | { 308 | # ifdef _PEDANTIC 309 | printerrorf("Warning: Socket option SO_REUSEADDR unsupported: %s\n", vlmcsd_strerror(socket_errno)); 310 | # endif // _PEDANTIC 311 | } 312 | 313 | # undef VLMCSD_SOCKET_OPTION 314 | # endif // !__CYGWIN__ 315 | 316 | return 0; 317 | } 318 | 319 | 320 | #ifdef SIMPLE_SOCKETS 321 | 322 | int listenOnAllAddresses() 323 | { 324 | uint32_t port_listen; 325 | 326 | if (!stringToInt(defaultport, 1, 65535, &port_listen)) 327 | { 328 | printerrorf("Fatal: Port must be numeric between 1 and 65535.\n"); 329 | exit(VLMCSD_EINVAL); 330 | } 331 | 332 | # if defined(AF_INET6) && defined(IPV6_V6ONLY) 333 | 334 | struct sockaddr_in6 addr; 335 | memset(&addr, 0, sizeof(addr)); 336 | addr.sin6_family = AF_INET6; 337 | addr.sin6_port = BE16((uint16_t)port_listen); 338 | addr.sin6_addr = in6addr_any; 339 | BOOL v6only = FALSE; 340 | s_server = socket(AF_INET6, SOCK_STREAM, 0); 341 | 342 | if (s_server == INVALID_SOCKET 343 | || allowSocketReuse(s_server) 344 | || setsockopt(s_server, IPPROTO_IPV6, IPV6_V6ONLY, (sockopt_t)&v6only, sizeof(v6only)) 345 | || bind(s_server, (struct sockaddr *)&addr, sizeof(addr)) 346 | || listen(s_server, SOMAXCONN)) 347 | { 348 | socketclose(s_server); 349 | # endif // defined(AF_INET6) && defined(IPV6_V6ONLY) 350 | struct sockaddr_in addr4 = { 351 | .sin_family = AF_INET, 352 | .sin_port = BE16((uint16_t)port_listen), 353 | .sin_addr.s_addr = BE32(INADDR_ANY) 354 | }; 355 | 356 | s_server = socket(AF_INET, SOCK_STREAM, 0); 357 | 358 | if (s_server == INVALID_SOCKET 359 | || allowSocketReuse(s_server) 360 | || bind(s_server, (struct sockaddr *)&addr4, sizeof(addr4)) 361 | || listen(s_server, SOMAXCONN)) 362 | { 363 | int error = socket_errno; 364 | printerrorf("Fatal: Cannot bind to TCP port %u: %s\n", port_listen, vlmcsd_strerror(error)); 365 | return error; 366 | } 367 | 368 | # if defined(AF_INET6) && defined(IPV6_V6ONLY) 369 | } 370 | # endif // defined(AF_INET6) && defined(IPV6_V6ONLY) 371 | 372 | #ifndef NO_LOG 373 | logger("Listening on TCP port %u\n", port_listen); 374 | #endif // NO_LOG 375 | 376 | return 0; 377 | } 378 | 379 | #else // !SIMPLE_SOCKETS 380 | 381 | 382 | #if HAVE_GETIFADDR && !defined(NO_PRIVATE_IP_DETECT) 383 | // Get list of private IP addresses. 384 | // Returns 0 on success or an errno error code on failure 385 | void getPrivateIPAddresses(int* numAddresses, char*** ipAddresses) 386 | { 387 | # if _WIN32 388 | 389 | PIP_ADAPTER_ADDRESSES firstAdapter, currentAdapter; 390 | 391 | DWORD dwRetVal; 392 | ULONG outBufLen = 16384; 393 | const ULONG flags = GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME; 394 | 395 | firstAdapter = (PIP_ADAPTER_ADDRESSES)vlmcsd_malloc(outBufLen); 396 | 397 | if ((dwRetVal = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, firstAdapter, &outBufLen)) == ERROR_BUFFER_OVERFLOW) 398 | { 399 | free(firstAdapter); 400 | firstAdapter = (PIP_ADAPTER_ADDRESSES)vlmcsd_malloc(outBufLen); 401 | dwRetVal = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, firstAdapter, &outBufLen); 402 | } 403 | 404 | if (dwRetVal != NO_ERROR) 405 | { 406 | printerrorf("FATAL: Could not get network address list: %s\n", vlmcsd_strerror(dwRetVal)); 407 | exit(dwRetVal); 408 | } 409 | 410 | for (currentAdapter = firstAdapter, *numAddresses = 0; currentAdapter != NULL; currentAdapter = currentAdapter->Next) 411 | { 412 | PIP_ADAPTER_UNICAST_ADDRESS currentAddress; 413 | int length; 414 | 415 | if (currentAdapter->OperStatus != IfOperStatusUp) continue; 416 | 417 | for (currentAddress = currentAdapter->FirstUnicastAddress; currentAddress != NULL; currentAddress = currentAddress->Next) 418 | { 419 | if (isPrivateIPAddress(currentAddress->Address.lpSockaddr, &length)) (*numAddresses)++; 420 | } 421 | } 422 | 423 | *ipAddresses = (char**)vlmcsd_malloc(*numAddresses * sizeof(char*)); 424 | 425 | for (currentAdapter = firstAdapter, *numAddresses = 0; currentAdapter != NULL; currentAdapter = currentAdapter->Next) 426 | { 427 | PIP_ADAPTER_UNICAST_ADDRESS currentAddress; 428 | int length; 429 | 430 | if (currentAdapter->OperStatus != IfOperStatusUp) continue; 431 | 432 | for (currentAddress = currentAdapter->FirstUnicastAddress; currentAddress != NULL; currentAddress = currentAddress->Next) 433 | { 434 | if (!isPrivateIPAddress(currentAddress->Address.lpSockaddr, &length)) continue; 435 | 436 | char *ipAddress = (char*)vlmcsd_malloc(64); 437 | const int error = getnameinfo(currentAddress->Address.lpSockaddr, currentAddress->Address.iSockaddrLength, ipAddress, 64, NULL, 0, NI_NUMERICHOST); 438 | 439 | if (error) 440 | { 441 | printerrorf("WARNING: Could not get IP address from interface list: %s\n", gai_strerror(error)); 442 | *ipAddress = 0; 443 | } 444 | 445 | (*ipAddresses)[(*numAddresses)++] = ipAddress; 446 | } 447 | } 448 | 449 | free(firstAdapter); 450 | 451 | # else // !_WIN32 452 | 453 | struct ifaddrs *addrs, *addr; 454 | 455 | if (getifaddrs(&addrs)) 456 | { 457 | printerrorf("FATAL: Could not get network address list: %s\n", vlmcsd_strerror(errno)); 458 | exit(errno); 459 | } 460 | 461 | socklen_t length; 462 | 463 | for (addr = addrs, *numAddresses = 0; addr != NULL; addr = addr->ifa_next) 464 | { 465 | if (!isPrivateIPAddress(addr->ifa_addr, &length)) continue; 466 | (*numAddresses)++; 467 | } 468 | 469 | *ipAddresses = (char**)vlmcsd_malloc(*numAddresses * sizeof(char*)); 470 | 471 | for (addr = addrs, *numAddresses = 0; addr != NULL; addr = addr->ifa_next) 472 | { 473 | if (!isPrivateIPAddress(addr->ifa_addr, &length)) continue; 474 | 475 | char *ipAddress = (char*)vlmcsd_malloc(64); 476 | int error = getnameinfo(addr->ifa_addr, length, ipAddress, 64, NULL, 0, NI_NUMERICHOST); 477 | 478 | if (error) 479 | { 480 | printerrorf("WARNING: Could not get IP address from interface list: %s\n", gai_strerror(error)); 481 | *ipAddress = 0; 482 | } 483 | 484 | # if __UCLIBC__ || __gnu_hurd__ 485 | 486 | size_t adrlen = strlen(ipAddress); 487 | 488 | if 489 | ( 490 | addr->ifa_addr->sa_family == AF_INET6 && 491 | adrlen > 5 && 492 | !strchr(ipAddress, '%') && 493 | (BE16(*(uint16_t*)&((struct sockaddr_in6*)addr->ifa_addr)->sin6_addr) & 0xffc0) == 0xfe80 494 | ) 495 | { 496 | size_t ifnamelen = strlen(addr->ifa_name); 497 | char* workaroundIpAddress = (char*)vlmcsd_malloc(adrlen + ifnamelen + 2); 498 | strcpy(workaroundIpAddress, ipAddress); 499 | strcat(workaroundIpAddress, "%"); 500 | strcat(workaroundIpAddress, addr->ifa_name); 501 | (*ipAddresses)[(*numAddresses)++] = workaroundIpAddress; 502 | free(ipAddress); 503 | } 504 | else 505 | { 506 | (*ipAddresses)[(*numAddresses)++] = ipAddress; 507 | } 508 | # else // !(__UCLIBC__ || __gnu_hurd__) 509 | 510 | (*ipAddresses)[(*numAddresses)++] = ipAddress; 511 | 512 | # endif // !(__UCLIBC__ || __gnu_hurd__) 513 | } 514 | 515 | freeifaddrs(addrs); 516 | 517 | # endif // !_WIN32 518 | } 519 | #endif // HAVE_GETIFADDR && !defined(NO_PRIVATE_IP_DETECT) 520 | 521 | 522 | 523 | // Create a Listening socket for addrinfo sa and return socket s 524 | // szHost and szPort are for logging only 525 | static int listenOnAddress(const struct addrinfo *const ai, SOCKET *s) 526 | { 527 | int error; 528 | char ipstr[64]; 529 | 530 | ip2str(ipstr, sizeof(ipstr), ai->ai_addr, (socklen_t)ai->ai_addrlen); 531 | 532 | //*s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); 533 | *s = socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP); 534 | 535 | if (*s == INVALID_SOCKET) 536 | { 537 | error = socket_errno; 538 | printerrorf("Warning: %s error. %s\n", ai->ai_family == AF_INET6 ? cIPv6 : cIPv4, vlmcsd_strerror(error)); 539 | return error; 540 | } 541 | 542 | # if !defined(_WIN32) && !defined(NO_SIGHUP) 543 | 544 | int flags = fcntl(*s, F_GETFD, 0); 545 | 546 | if (flags != -1) 547 | { 548 | flags |= FD_CLOEXEC; 549 | fcntl(*s, F_SETFD, flags); 550 | } 551 | # ifdef _PEDANTIC 552 | else 553 | { 554 | printerrorf("Warning: Could not set FD_CLOEXEC flag on %s: %s\n", ipstr, vlmcsd_strerror(errno)); 555 | } 556 | # endif // _PEDANTIC 557 | 558 | # endif // !defined(_WIN32) && !defined(NO_SIGHUP) 559 | 560 | BOOL socketOption = TRUE; 561 | 562 | # ifdef IPV6_V6ONLY 563 | if (ai->ai_family == AF_INET6 && setsockopt(*s, IPPROTO_IPV6, IPV6_V6ONLY, (sockopt_t)&socketOption, sizeof(socketOption))) 564 | { 565 | # ifdef _PEDANTIC 566 | # if defined(_WIN32) || defined(__CYGWIN__) 567 | // if (IsWindowsVistaOrGreater()) //Doesn't work with older version of MingW32-w64 toolchain 568 | if ((GetVersion() & 0xff) > 5) 569 | { 570 | # endif // _WIN32 571 | printerrorf("Warning: %s does not support socket option IPV6_V6ONLY: %s\n", ipstr, vlmcsd_strerror(socket_errno)); 572 | # if defined(_WIN32) || defined(__CYGWIN__) 573 | } 574 | # endif // _WIN32 575 | # endif // _PEDANTIC 576 | } 577 | # endif 578 | 579 | allowSocketReuse(*s); 580 | 581 | # if HAVE_FREEBIND 582 | # if (defined(IP_NONLOCALOK) || __FreeBSD_kernel__ || __FreeBSD__) && !defined(IPV6_BINDANY) 583 | # define IPV6_BINDANY 64 584 | # endif // (defined(IP_NONLOCALOK) || __FreeBSD_kernel__ || __FreeBSD__) && !defined(IPV6_BINDANY) 585 | 586 | if (freebind) 587 | { 588 | # if defined(IP_FREEBIND) // Linux 589 | if (setsockopt(*s, IPPROTO_IP, IP_FREEBIND, (sockopt_t)&socketOption, sizeof(socketOption))) 590 | { 591 | printerrorf("Warning: Cannot use FREEBIND on %s: %s\n", ipstr, vlmcsd_strerror(socket_errno)); 592 | } 593 | # endif // defined(IP_FREEBIND) 594 | 595 | # if defined(IP_BINDANY) // FreeBSD IPv4 596 | if (ai->ai_family == AF_INET && setsockopt(*s, IPPROTO_IP, IP_BINDANY, (sockopt_t)&socketOption, sizeof(socketOption))) 597 | { 598 | printerrorf("Warning: Cannot use BINDANY on %s: %s\n", ipstr, vlmcsd_strerror(socket_errno)); 599 | } 600 | # endif // defined(IP_BINDANY) 601 | 602 | # if defined(IPV6_BINDANY) // FreeBSD IPv6 603 | if (ai->ai_family == AF_INET6 && setsockopt(*s, IPPROTO_IP, IPV6_BINDANY, (sockopt_t)&socketOption, sizeof(socketOption))) 604 | { 605 | # ifdef _PEDANTIC // FreeBSD defines the symbol but doesn't have BINDANY in IPv6 (Kame stack doesn't have it) 606 | printerrorf("Warning: Cannot use BINDANY on %s: %s\n", ipstr, vlmcsd_strerror(socket_errno)); 607 | # endif 608 | } 609 | # endif // defined(IPV6_BINDANY) 610 | 611 | # if defined(IP_NONLOCALOK) && !defined(IP_BINDANY) // FreeBSD with GNU userspace IPv4 612 | if (ai->ai_family == AF_INET && setsockopt(*s, IPPROTO_IP, IP_NONLOCALOK, (sockopt_t)&socketOption, sizeof(socketOption))) 613 | { 614 | printerrorf("Warning: Cannot use BINDANY on %s: %s\n", ipstr, vlmcsd_strerror(socket_errno)); 615 | } 616 | # endif // defined(IP_NONLOCALOK) && !defined(IP_BINDANY) 617 | } 618 | 619 | # endif // HAVE_FREEBIND 620 | 621 | if (bind(*s, ai->ai_addr, (int)ai->ai_addrlen) || listen(*s, SOMAXCONN)) 622 | { 623 | error = socket_errno; 624 | printerrorf("Warning: %s: %s\n", ipstr, vlmcsd_strerror(error)); 625 | socketclose(*s); 626 | return error; 627 | } 628 | 629 | # ifndef NO_LOG 630 | logger("Listening on %s\n", ipstr); 631 | # endif 632 | 633 | return 0; 634 | } 635 | 636 | // Adds a listening socket for an address string, 637 | // e.g. 127.0.0.1:1688 or [2001:db8:dead:beef::1]:1688 638 | BOOL addListeningSocket(const char *const addr) 639 | { 640 | struct addrinfo *aiList, *ai; 641 | int result = FALSE; 642 | SOCKET *s = SocketList + numsockets; 643 | 644 | if (getSocketList(&aiList, addr, AI_PASSIVE | AI_NUMERICHOST, AF_UNSPEC)) 645 | { 646 | for (ai = aiList; ai; ai = ai->ai_next) 647 | { 648 | // struct sockaddr_in* addr4 = (struct sockaddr_in*)sa->ai_addr; 649 | // struct sockaddr_in6* addr6 = (struct sockaddr_in6*)sa->ai_addr; 650 | 651 | if (numsockets >= FD_SETSIZE) 652 | { 653 | #ifdef _PEDANTIC // Do not report this error in normal builds to keep file size low 654 | printerrorf("Warning: Cannot listen on %s. Your OS only supports %u listening sockets in an FD_SET.\n", addr, FD_SETSIZE); 655 | #endif 656 | break; 657 | } 658 | 659 | if (!listenOnAddress(ai, s)) 660 | { 661 | numsockets++; 662 | result = TRUE; 663 | } 664 | else 665 | { 666 | exitOnWarningLevel(1); 667 | } 668 | } 669 | 670 | freeaddrinfo(aiList); 671 | } 672 | return result; 673 | } 674 | 675 | 676 | // Just create some dummy sockets to see if we have a specific protocol (IPv4 or IPv6) 677 | __pure int_fast8_t checkProtocolStack(const int addressfamily) 678 | { 679 | SOCKET s; // = INVALID_SOCKET; 680 | 681 | s = socket(addressfamily, SOCK_STREAM, 0); 682 | const int_fast8_t success = (s != INVALID_SOCKET); 683 | 684 | socketclose(s); 685 | return success; 686 | } 687 | 688 | 689 | // Build an fd_set of all listening socket then use select to wait for an incoming connection 690 | static SOCKET network_accept_any() 691 | { 692 | fd_set ListeningSocketsList; 693 | SOCKET maxSocket, sock; 694 | int i; 695 | int status; 696 | 697 | FD_ZERO(&ListeningSocketsList); 698 | maxSocket = 0; 699 | 700 | for (i = 0; i < numsockets; i++) 701 | { 702 | FD_SET(SocketList[i], &ListeningSocketsList); 703 | if (SocketList[i] > maxSocket) maxSocket = SocketList[i]; 704 | } 705 | 706 | status = select((int)maxSocket + 1, &ListeningSocketsList, NULL, NULL, NULL); 707 | 708 | if (status < 0) return INVALID_SOCKET; 709 | 710 | sock = INVALID_SOCKET; 711 | 712 | for (i = 0; i < numsockets; i++) 713 | { 714 | if (FD_ISSET(SocketList[i], &ListeningSocketsList)) 715 | { 716 | sock = SocketList[i]; 717 | break; 718 | } 719 | } 720 | 721 | if (sock == INVALID_SOCKET) 722 | return INVALID_SOCKET; 723 | else 724 | return accept(sock, NULL, NULL); 725 | } 726 | #endif // !SIMPLE_SOCKETS 727 | 728 | 729 | void closeAllListeningSockets() 730 | { 731 | # ifdef SIMPLE_SOCKETS 732 | 733 | socketclose(s_server); 734 | 735 | # else // !SIMPLE_SOCKETS 736 | 737 | int i; 738 | 739 | for (i = 0; i < numsockets; i++) 740 | { 741 | socketclose(SocketList[i]); 742 | } 743 | 744 | #endif // !SIMPLE_SOCKETS 745 | } 746 | #endif // NO_SOCKETS 747 | 748 | 749 | static void serveClient(const SOCKET s_client, const DWORD RpcAssocGroup) 750 | { 751 | # if !defined(NO_TIMEOUT) && !__minix__ 752 | 753 | # ifndef _WIN32 // Standard Posix timeout structure 754 | 755 | struct timeval to; 756 | to.tv_sec = ServerTimeout; 757 | to.tv_usec = 0; 758 | 759 | #else // Windows requires a DWORD with milliseconds 760 | 761 | DWORD to = ServerTimeout * 1000; 762 | 763 | # endif // _WIN32 764 | 765 | # if !defined(NO_LOG) && defined(_PEDANTIC) 766 | 767 | const int result = 768 | setsockopt(s_client, SOL_SOCKET, SO_RCVTIMEO, (sockopt_t)&to, sizeof(to)) || 769 | setsockopt(s_client, SOL_SOCKET, SO_SNDTIMEO, (sockopt_t)&to, sizeof(to)); 770 | 771 | if (result) logger("Warning: Set timeout failed: %s\n", vlmcsd_strerror(socket_errno)); 772 | 773 | # else // !(!defined(NO_LOG) && defined(_PEDANTIC)) 774 | 775 | setsockopt(s_client, SOL_SOCKET, SO_RCVTIMEO, (sockopt_t)&to, sizeof(to)); 776 | setsockopt(s_client, SOL_SOCKET, SO_SNDTIMEO, (sockopt_t)&to, sizeof(to)); 777 | 778 | # endif // !(!defined(NO_LOG) && defined(_PEDANTIC)) 779 | 780 | # endif // !defined(NO_TIMEOUT) && !__minix__ 781 | 782 | char ipstr[64]; 783 | socklen_t len; 784 | struct sockaddr_storage addr; 785 | 786 | len = sizeof(addr); 787 | 788 | if (getpeername(s_client, (struct sockaddr*)&addr, &len) || 789 | !ip2str(ipstr, sizeof(ipstr), (struct sockaddr*)&addr, len)) 790 | { 791 | # if !defined(NO_LOG) && defined(_PEDANTIC) 792 | logger("Fatal: Cannot determine client's IP address: %s\n", vlmcsd_strerror(errno)); 793 | # endif // !defined(NO_LOG) && defined(_PEDANTIC) 794 | socketclose(s_client); 795 | return; 796 | } 797 | 798 | 799 | # ifndef NO_LOG 800 | const char *const connection_type = addr.ss_family == AF_INET6 ? cIPv6 : cIPv4; 801 | static const char *const cAccepted = "accepted"; 802 | static const char *const cClosed = "closed"; 803 | static const char *const fIP = "%s connection %s: %s.\n"; 804 | 805 | logger(fIP, connection_type, cAccepted, ipstr); 806 | #endif // NO_LOG 807 | 808 | # if !defined(NO_PRIVATE_IP_DETECT) 809 | 810 | if (!(PublicIPProtectionLevel & 2) || isPrivateIPAddress((struct sockaddr*)&addr, NULL)) 811 | { 812 | rpcServer(s_client, RpcAssocGroup, ipstr); 813 | } 814 | # ifndef NO_LOG 815 | else 816 | { 817 | logger("Client with public IP address rejected\n"); 818 | } 819 | # endif // NO_LOG 820 | 821 | # else // defined(NO_PRIVATE_IP_DETECT) 822 | 823 | rpcServer(s_client, RpcAssocGroup, ipstr); 824 | 825 | # endif // defined(NO_PRIVATE_IP_DETECT) 826 | 827 | # ifndef NO_LOG 828 | logger(fIP, connection_type, cClosed, ipstr); 829 | # endif // NO_LOG 830 | 831 | socketclose(s_client); 832 | } 833 | 834 | 835 | #ifndef NO_SOCKETS 836 | static void post_sem(void) 837 | { 838 | #if !defined(NO_LIMIT) && !__minix__ 839 | if (!InetdMode && MaxTasks != SEM_VALUE_MAX) 840 | { 841 | semaphore_post(MaxTaskSemaphore); 842 | } 843 | #endif // !defined(NO_LIMIT) && !__minix__ 844 | } 845 | 846 | 847 | static void wait_sem(void) 848 | { 849 | #if !defined(NO_LIMIT) && !__minix__ 850 | if (!InetdMode && MaxTasks != SEM_VALUE_MAX) 851 | { 852 | semaphore_wait(MaxTaskSemaphore); 853 | } 854 | #endif // !defined(NO_LIMIT) && !__minix__ 855 | } 856 | #endif // NO_SOCKETS 857 | 858 | #if defined(USE_THREADS) && !defined(NO_SOCKETS) 859 | 860 | #if defined(_WIN32) || defined(__CYGWIN__) // Win32 Threads 861 | static DWORD WINAPI serveClientThreadProc(PCLDATA clData) 862 | #else // Posix threads 863 | static void *serveClientThreadProc(PCLDATA clData) 864 | #endif // Thread proc is identical in WIN32 and Posix threads 865 | { 866 | serveClient(clData->socket, clData->RpcAssocGroup); 867 | free(clData); 868 | post_sem(); 869 | 870 | return 0; 871 | } 872 | 873 | #endif // USE_THREADS 874 | 875 | 876 | #ifndef NO_SOCKETS 877 | 878 | #if defined(USE_THREADS) && (defined(_WIN32) || defined(__CYGWIN__)) // Windows Threads 879 | static int serveClientAsyncWinThreads(PCLDATA thr_CLData) 880 | { 881 | wait_sem(); 882 | 883 | HANDLE h = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)serveClientThreadProc, thr_CLData, 0, NULL); 884 | 885 | if (h) 886 | { 887 | CloseHandle(h); 888 | return NO_ERROR; 889 | } 890 | else 891 | { 892 | socketclose(thr_CLData->socket); 893 | free(thr_CLData); 894 | post_sem(); 895 | return GetLastError(); 896 | } 897 | } 898 | #endif // defined(USE_THREADS) && defined(_WIN32) // Windows Threads 899 | 900 | 901 | #if defined(USE_THREADS) && !defined(_WIN32) && !defined(__CYGWIN__) // Posix Threads 902 | static int ServeClientAsyncPosixThreads(const PCLDATA thr_CLData) 903 | { 904 | pthread_t p_thr; 905 | pthread_attr_t attr; 906 | int error; 907 | 908 | wait_sem(); 909 | 910 | // Must set detached state to avoid memory leak 911 | if ((error = pthread_attr_init(&attr)) || 912 | (error = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) || 913 | (error = pthread_create(&p_thr, &attr, (void * (*)(void *))serveClientThreadProc, thr_CLData))) 914 | { 915 | socketclose(thr_CLData->socket); 916 | free(thr_CLData); 917 | post_sem(); 918 | return error; 919 | } 920 | 921 | return 0; 922 | } 923 | #endif // defined(USE_THREADS) && !defined(_WIN32) // Posix Threads 924 | 925 | #ifndef USE_THREADS // fork() implementation 926 | static void ChildSignalHandler(const int signal) 927 | { 928 | if (signal == SIGHUP) return; 929 | 930 | post_sem(); 931 | 932 | #ifndef NO_LOG 933 | logger("Warning: Child killed/crashed by %s\n", strsignal(signal)); 934 | #endif // NO_LOG 935 | 936 | exit(ECHILD); 937 | } 938 | 939 | static int ServeClientAsyncFork(const SOCKET s_client, const DWORD RpcAssocGroup) 940 | { 941 | int pid; 942 | wait_sem(); 943 | 944 | if ((pid = fork()) < 0) 945 | { 946 | return errno; 947 | } 948 | else if (pid) 949 | { 950 | // Parent process 951 | socketclose(s_client); 952 | return 0; 953 | } 954 | else 955 | { 956 | // Child process 957 | 958 | // Setup a Child Handler for most common termination signals 959 | struct sigaction sa; 960 | 961 | sa.sa_flags = 0; 962 | sa.sa_handler = ChildSignalHandler; 963 | 964 | static int signallist[] = { SIGHUP, SIGINT, SIGTERM, SIGSEGV, SIGILL, SIGFPE, SIGBUS }; 965 | 966 | if (!sigemptyset(&sa.sa_mask)) 967 | { 968 | uint_fast8_t i; 969 | 970 | for (i = 0; i < vlmcsd_countof(signallist); i++) 971 | { 972 | sigaction(signallist[i], &sa, NULL); 973 | } 974 | } 975 | 976 | serveClient(s_client, RpcAssocGroup); 977 | post_sem(); 978 | exit(0); 979 | } 980 | } 981 | #endif 982 | 983 | 984 | int serveClientAsync(const SOCKET s_client, const DWORD RpcAssocGroup) 985 | { 986 | #ifndef USE_THREADS // fork() implementation 987 | 988 | return ServeClientAsyncFork(s_client, RpcAssocGroup); 989 | 990 | #else // threads implementation 991 | 992 | PCLDATA thr_CLData = (PCLDATA)vlmcsd_malloc(sizeof(CLDATA)); 993 | thr_CLData->socket = s_client; 994 | thr_CLData->RpcAssocGroup = RpcAssocGroup; 995 | 996 | #if defined(_WIN32) || defined (__CYGWIN__) // Windows threads 997 | 998 | return serveClientAsyncWinThreads(thr_CLData); 999 | 1000 | #else // Posix Threads 1001 | 1002 | return ServeClientAsyncPosixThreads(thr_CLData); 1003 | 1004 | #endif // Posix Threads 1005 | 1006 | #endif // USE_THREADS 1007 | } 1008 | 1009 | #endif // NO_SOCKETS 1010 | 1011 | 1012 | int runServer() 1013 | { 1014 | DWORD RpcAssocGroup = rand32(); 1015 | 1016 | // If compiled for inetd-only mode just serve the stdin socket 1017 | #ifdef NO_SOCKETS 1018 | serveClient(STDIN_FILENO, RpcAssocGroup); 1019 | return 0; 1020 | #else 1021 | // In inetd mode just handle the stdin socket 1022 | if (InetdMode) 1023 | { 1024 | serveClient(STDIN_FILENO, RpcAssocGroup); 1025 | return 0; 1026 | } 1027 | 1028 | for (;;) 1029 | { 1030 | int error; 1031 | SOCKET s_client; 1032 | 1033 | # ifdef SIMPLE_SOCKETS 1034 | if ((s_client = accept(s_server, NULL, NULL)) == INVALID_SOCKET) 1035 | # else // Standalone mode fully featured sockets 1036 | if ((s_client = network_accept_any()) == INVALID_SOCKET) 1037 | # endif // Standalone mode fully featured sockets 1038 | { 1039 | error = socket_errno; 1040 | if (error == SOCKET_EINTR || error == SOCKET_ECONNABORTED) continue; 1041 | 1042 | # ifdef _NTSERVICE 1043 | if (ServiceShutdown) return 0; 1044 | # endif 1045 | 1046 | # ifndef NO_LOG 1047 | logger("Fatal: %s\n", vlmcsd_strerror(error)); 1048 | # endif 1049 | 1050 | return error; 1051 | } 1052 | 1053 | RpcAssocGroup++; 1054 | 1055 | # if !defined(NO_LOG) && defined(_PEDANTIC) 1056 | if ((error = serveClientAsync(s_client, RpcAssocGroup))) 1057 | { 1058 | # ifdef USE_THREADS 1059 | logger("Warning: Could not create client thread: %s\n", vlmcsd_strerror(error)); 1060 | # else // !USE_THREADS 1061 | logger("Warning: Could not fork client: %s\n", vlmcsd_strerror(error)); 1062 | # endif // !USE_THREADS 1063 | } 1064 | # else // NO_LOG || !_PEDANTIC 1065 | serveClientAsync(s_client, RpcAssocGroup); 1066 | # endif // NO_LOG || !_PEDANTIC 1067 | } 1068 | # endif // NO_SOCKETS 1069 | } 1070 | 1071 | #endif // USE_MSRPC 1072 | --------------------------------------------------------------------------------