From: Philip Prindeville Date: Mon, 13 Mar 2023 00:27:50 +0000 (-0600) Subject: Merge pull request #20261 from pprindeville/strongswan-update-5.9.9 X-Git-Url: http://git.openwrt.org/?a=commitdiff_plain;h=1dfb13eaebfe2907cdf48bd2053bc0bd7919a42f;hp=ae0a8072d6f51076c5b2e38ef645e4b3431ce7b5;p=feed%2Fpackages.git Merge pull request #20261 from pprindeville/strongswan-update-5.9.9 strongswan: Update to 5.9.9 --- diff --git a/lang/lua-eco/Makefile b/lang/lua-eco/Makefile index c836de92e2..88728ec7e3 100644 --- a/lang/lua-eco/Makefile +++ b/lang/lua-eco/Makefile @@ -1,12 +1,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=lua-eco -PKG_VERSION:=2.0.0 +PKG_VERSION:=2.2.0 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL=https://github.com/zhaojh329/lua-eco/releases/download/v$(PKG_VERSION) -PKG_HASH:=df2bed363ac89ce5c776c02baa914fbf4b096e0b87cbf4347d1a48cb4d3b8428 +PKG_HASH:=b45073ba93123d93ab7521b1e699c0f8f8f7de513342b16e2115a0f5a26f8014 PKG_MAINTAINER:=Jianhui Zhao PKG_LICENSE:=MIT @@ -30,10 +30,9 @@ define Package/lua-eco endef define Package/lua-eco/description - Lua-eco is a Lua interpreter with a built-in libev event loop. It makes all Lua code - running in Lua coroutines so code that does I/O can be suspended until data is ready. - This allows you write code as if you're using blocking I/O, while still allowing code - in other coroutines to run when you'd otherwise wait for I/O. It's kind of like Goroutines. + Lua-eco is a Lua interpreter with a built-in event loop for scheduling + lightweight coroutines automatically, enabling efficient concurrency in + Lua. Build high-performance, scalable applications. endef define Package/lua-eco/Module @@ -56,15 +55,16 @@ Package/lua-eco-ssl=$(call Package/lua-eco/Module,ssl,\ +LUA_ECO_OPENSSL:libopenssl +LUA_ECO_WOLFSSL:libwolfssl \ +LUA_ECO_MBEDTLS:libmbedtls +LUA_ECO_MBEDTLS:zlib +lua-eco-socket) Package/lua-eco-ubus=$(call Package/lua-eco/Module,ubus,+libubus) -Package/lua-eco-termios=$(call Package/lua-eco/Module,termios) Package/lua-eco-http=$(call Package/lua-eco/Module,http/https,+lua-eco-dns +lua-eco-ssl +lua-eco-log) Package/lua-eco-mqtt=$(call Package/lua-eco/Module,mqtt,+lua-eco-socket +lua-eco-dns +lua-mosquitto) Package/lua-eco-websocket=$(call Package/lua-eco/Module,websocket,+lua-eco-http +lua-eco-base64 +lua-eco-sha1) +Package/lua-eco-termios=$(call Package/lua-eco/Module,termios) +Package/lua-eco-network=$(call Package/lua-eco/Module,network) define Package/lua-eco-ssl/config choice prompt "SSL Library" - default LUA_ECO_WOLFSSL + default LUA_ECO_MBEDTLS config LUA_ECO_OPENSSL bool "OpenSSL" @@ -170,6 +170,11 @@ define Package/lua-eco-termios/install $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/lua/eco/termios.so $(1)/usr/lib/lua/eco endef +define Package/lua-eco-network/install + $(INSTALL_DIR) $(1)/usr/lib/lua/eco + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/lua/eco/network.so $(1)/usr/lib/lua/eco +endef + $(eval $(call BuildPackage,lua-eco)) $(eval $(call BuildPackage,lua-eco-log)) $(eval $(call BuildPackage,lua-eco-sys)) @@ -184,3 +189,4 @@ $(eval $(call BuildPackage,lua-eco-http)) $(eval $(call BuildPackage,lua-eco-mqtt)) $(eval $(call BuildPackage,lua-eco-websocket)) $(eval $(call BuildPackage,lua-eco-termios)) +$(eval $(call BuildPackage,lua-eco-network)) diff --git a/lang/perl-ack/Makefile b/lang/perl-ack/Makefile index 6fee0c87e6..fc8202109f 100644 --- a/lang/perl-ack/Makefile +++ b/lang/perl-ack/Makefile @@ -5,12 +5,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=perl-ack -PKG_VERSION:=3.6.0 -PKG_RELEASE:=$(AUTORELEASE) +PKG_VERSION:=3.7.0 +PKG_RELEASE:=1 PKG_SOURCE_URL:=http://www.cpan.org/authors/id/P/PE/PETDANCE/ PKG_SOURCE:=ack-v$(PKG_VERSION).tar.gz -PKG_HASH:=03144d1070649e92f6a1b7d20bdc535e2bb1ac258daabe482e9aa8277b48f005 +PKG_HASH:=ea7caa14f757de083310ed2cba298661ddcca5dee06ec8f18043ea625a79df20 PKG_LICENSE:=Artistic-2.0 PKG_LICENSE_FILE:=LICENSE.md diff --git a/lang/rust/Config.in b/lang/rust/Config.in new file mode 100644 index 0000000000..490322f48a --- /dev/null +++ b/lang/rust/Config.in @@ -0,0 +1,95 @@ +# Rust Language Options +menu "Compiler Options" + visible if PACKAGE_rust + + config RUST_DEBUG + bool "Enables Debugging Environment (--enable-debug)" + + config RUST_DOCS + bool "Build standard library documentation (--enable-docs)" + + config RUST_COMPILER_DOCS + bool "Build compiler documentation (--enable-compiler-docs)" + + config RUST_OPTIMIZE_TESTS + bool "Build tests with optimizations (--enable-optimized-tests)" + + config RUST_PARALLEL + bool "Build with multi-threaded support (--enable-parallel-compiler)" + + config RUST_VERBOSE_TESTS + bool "Enable verbose output when running tests (--enable-verbose-tests)" + + config RUST_CCACHE + bool "Build with ccache enabled (--enable-ccache)" + + config RUST_LLVM_STATIC + bool "Statically link to libstdc++ to LLVM (--enable-llvm-static-stdccp)" + + config RUST_LLVM_SHARED + bool "Prefer shared linking to LLVM (--enable-llvm-link-shared)" + + config RUST_CODEGEN_TESTS + bool "Run the src/test/codegen tests (--enable-codegen-tests)" + + config RUST_OPTION_CHECKING + bool "Complain about unrecognized options in this configure script (--enable-option-checking)" + default y + + config RUST_ENABLE_NINJA + bool "Build LLVM using the Ninja generator (--enable-ninja)" + default y + + config RUST_LOCKED_DEPS + bool "Force Cargo.lock to be up to date (--enable-locked-deps)" + + config RUST_VENDOR + bool "Enable usage of vendored Rust crates (--enable-vendor)" + + config RUST_SANITIZERS + bool "Build the sanitizer runtimes (asan, lsan, msan, tsan) (--enable-sanitizers)" + + config RUST_DIST_SRC + bool "When building tarballs enables building a source tarball (--enable-dist-src)" + + config RUST_CARGO_NATIVE_STATIC + bool "Build static native libraries in Cargo (--enable-cargo-native-static)" + + config RUST_PROFILER + bool "Build the profiler runtime (--enable-profiler)" + + config RUST_FULL_TOOLS + bool "Build all tools (--enable-full-tools)" + + config RUST_MISSING_TOOLS + bool "Allow failures when building tools (--enable-missing-tools)" + default y + + config RUST_USE_LIBCXX + bool "Build LLVM with libc++ (--enable-use-libcxx)" + + config RUST_CONTROL_FLOW_GUARD + bool "Enable Control Flow Guard (--enable-control-flow-guard)" + + config RUST_OPTIMIZE_LLVM + bool "Build optimized LLVM (--enable-optimize-llvm)" + default y + + config RUST_LLVM_ASSERTIONS + bool "Build LLVM with assertions (--enable-llvm-assertions)" + + config RUST_DEBUG_ASSERTIONS + bool "Build with debugging assertions (--enable-debug-assertions)" + + config RUST_LLVM_RELEASE_DEBUGINFO + bool "Build LLVM with debugger metadata (--enable-llvm-release-debuginfo)" + + config RUST_MANAGE_SUBMODULES + bool "Let the build manage the git submodules (--enable-manage-submodules)" + default y + + config RUST_FULL_BOOTSTRAP + bool "Full Bootstrap - Build three compilers instead of two (--enable-full-bootstrap)" + +endmenu + diff --git a/lang/rust/Makefile b/lang/rust/Makefile new file mode 100644 index 0000000000..97d861f58b --- /dev/null +++ b/lang/rust/Makefile @@ -0,0 +1,141 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2023 Luca Barbato and Donald Hoskins + +include $(TOPDIR)/rules.mk + +PKG_NAME:=rust +PKG_VERSION:=1.67.1 +PKG_RELEASE:=1 + +PKG_SOURCE:=rustc-$(PKG_VERSION)-src.tar.gz +PKG_SOURCE_URL:=https://static.rust-lang.org/dist/ +PKG_HASH:=46483d3e5de85a3bd46f8e7a3ae1837496391067dbe713a25d3cf051b3d9ff6e +HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/rustc-$(PKG_VERSION)-src/ + +PKG_MAINTAINER:=Luca Barbato +PKG_LICENSE:=Apache-2.0 MIT +PKG_LICENSE_FILES:=LICENSE-APACHE LICENSE-MIT + +HOST_BUILD_DEPENDS:=python3/host +PKG_HOST_ONLY:=1 + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/host-build.mk + +# rust environment variables +include ./rust-host.mk + +# Rust Temp Directory +RUST_TMP_DIR:=$(TMP_DIR)/rust-install + +RUST_INSTALL_HOST_FILENAME:=$(PKG_NAME)-$(PKG_VERSION)-$(RUSTC_HOST_ARCH)-install.tar.xz +RUST_INSTALL_TARGET_FILENAME:=$(PKG_NAME)-$(PKG_VERSION)-$(RUSTC_TARGET_ARCH)-install.tar.xz + +# Rust-lang has an uninstall script +RUST_UNINSTALL:=$(CARGO_HOME)/lib/rustlib/uninstall.sh + +# Target Flags +TARGET_CONFIGURE_ARGS = \ + --set=target.$(RUSTC_TARGET_ARCH).ar=$(TARGET_AR) \ + --set=target.$(RUSTC_TARGET_ARCH).cc=$(TARGET_CC_NOCACHE) \ + --set=target.$(RUSTC_TARGET_ARCH).cxx=$(TARGET_CXX_NOCACHE) \ + --set=target.$(RUSTC_TARGET_ARCH).linker=$(TARGET_CC_NOCACHE) \ + --set=target.$(RUSTC_TARGET_ARCH).musl-root=$(TOOLCHAIN_DIR) \ + --set=target.$(RUSTC_TARGET_ARCH).ranlib=$(TARGET_RANLIB) + +# CARGO_HOME is an environmental +HOST_CONFIGURE_OPTS += CARGO_HOME="$(CARGO_HOME)" + +# Rust Configuration Arguments +HOST_CONFIGURE_ARGS = \ + --build=$(RUSTC_HOST_ARCH) \ + --target=$(RUSTC_TARGET_ARCH),$(RUSTC_HOST_ARCH) \ + --host=$(RUSTC_HOST_ARCH) \ + --prefix=$(CARGO_HOME) \ + --bindir=$(CARGO_HOME)/bin \ + --libdir=$(CARGO_HOME)/lib \ + --sysconfdir=$(CARGO_HOME)/etc \ + --datadir=$(CARGO_HOME)/share \ + --mandir=$(CARGO_HOME)/man \ + --dist-compression-formats=xz \ + --enable-llvm-link-shared \ + --enable-llvm-plugins \ + --enable-missing-tools \ + --enable-ninja \ + --disable-sanitizers \ + --release-channel=stable \ + --enable-cargo-native-static \ + $(TARGET_CONFIGURE_ARGS) + +define Host/Prepare + # Ensure rust temp directory + [ -d $(RUST_TMP_DIR) ] || \ + mkdir -p $(RUST_TMP_DIR) + + $(call Host/Prepare/Default) +endef + +define Host/Uninstall + # Call the Uninstall script + [ -f $(RUST_UNINSTALL) ] && \ + $(BASH) $(RUST_UNINSTALL) || echo No Uninstall + + rm -rf $(RUST_TMP_DIR) +endef + +# Makes and then packages the dist artifacts +define Host/Compile + cd $(HOST_BUILD_DIR) && \ + $(PYTHON) x.py --config ./config.toml dist build-manifest cargo llvm-tools \ + rustc rust-std rust-src + + $(call Host/PackageDist) +endef + +# Distribution Artifacts are packaged by Host/PackageDist +# We just need to extract and install +define Host/Install + $(TAR) -C $(RUST_TMP_DIR) -xJf $(DL_DIR)/$(RUST_INSTALL_HOST_FILENAME) && \ + $(TAR) -C $(RUST_TMP_DIR) -xJf $(DL_DIR)/$(RUST_INSTALL_TARGET_FILENAME) + + cd $(RUST_TMP_DIR) && \ + find -iname "*.xz" -exec tar -xJf {} ";" && \ + find ./* -type f -name install.sh -execdir sh {} --prefix=$(CARGO_HOME) --disable-ldconfig \; + + echo -e "[target.$(RUSTC_TARGET_ARCH)]\nlinker = \"$(TARGET_CC_NOCACHE)\"\nrustflags = [\"-Ctarget-feature=-crt-static\", \"-Clink-args=$(RUSTC_LDFLAGS)\"]" > $(CARGO_HOME)/config + echo -e "\n[profile.stripped]\ninherits = \"release\"\nopt-level = \"s\"\nstrip = true" >> $(CARGO_HOME)/config +endef + +# Packages the Distribution Artifacts into HOST and TARGET bundles. +define Host/PackageDist + ( \ + cd $(HOST_BUILD_DIR)/build/dist ; \ + $(TAR) -cJf $(DL_DIR)/$(RUST_INSTALL_TARGET_FILENAME) \ + rust-*-$(RUSTC_TARGET_ARCH).tar.xz ; \ + $(TAR) -cJf $(DL_DIR)/$(RUST_INSTALL_HOST_FILENAME) \ + --exclude rust-*-$(RUSTC_TARGET_ARCH).tar.xz *.xz ; \ + ) +endef + +define Package/rust + SECTION:=lang + CATEGORY:=Languages + TITLE:=Rust Programming Language Compiler + URL:=https://www.rust-lang.org/ + DEPENDS:=$(RUST_ARCH_DEPENDS) \ + +pkg-config +libunwind +libopenssl +liblzma +libc +endef + +define Package/rust/description + Rust is a multi-paradigm, general-purpose programming language designed for performance + and safety, especially safe concurrency. Rust is syntactically similar to C++, but can + guarantee memory safety by using a borrow checker to validate references. +endef + +define Package/rust/config + source "$(SOURCE)/Config.in" +endef + +$(eval $(call HostBuild)) +$(eval $(call BuildPackage,rust)) diff --git a/lang/rust/maturin/Makefile b/lang/rust/maturin/Makefile new file mode 100644 index 0000000000..c2ed4bcd14 --- /dev/null +++ b/lang/rust/maturin/Makefile @@ -0,0 +1,53 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2023 Luca Barbato + +include $(TOPDIR)/rules.mk + +PKG_NAME:=maturin +PKG_VERSION:=0.14.10 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/PyO3/maturin/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=8fc9bcdcb7f1535d5e3e8bb500c348ca1bff5a6dce87b0ab7dbc5a49723da28a + +PKG_MAINTAINER:=Luca Barbato +PKG_LICENSE:=Apache-2.0 MIT +PKG_LICENSE_FILES:=license-apache license-mit + +HOST_BUILD_DEPENDS:=rust/host +PKG_BUILD_DEPENDS:=rust/host + +PKG_BUILD_PARALLEL:=1 +PKG_HOST_ONLY:=1 + +include ../rust-package.mk +include $(INCLUDE_DIR)/host-build.mk +include $(INCLUDE_DIR)/package.mk + +define Package/maturin + SECTION:=lang + CATEGORY:=Languages + SUBMENU:=Rust + TITLE:=Build and publish crates as python packages + DEPENDS:=$(RUST_ARCH_DEPENDS) + URL:=https://maturin.rs +endef + +define Host/Compile + $(call Host/Compile/Cargo) +endef + +define Package/maturin/description + Build and publish crates with pyo3, rust-cpython, cffi and uniffi + bindings as well as rust binaries as python packages. +endef + +define Host/Install + $(INSTALL_DIR) $(STAGING_DIR_HOSTPKG)/bin + $(INSTALL_BIN) $(HOST_INSTALL_DIR)/bin/maturin $(STAGING_DIR_HOSTPKG)/bin/maturin +endef + +$(eval $(call HostBuild)) +$(eval $(call BuildPackage,maturin)) diff --git a/lang/rust/patches/0001-Update-xz2-and-use-it-static.patch b/lang/rust/patches/0001-Update-xz2-and-use-it-static.patch new file mode 100644 index 0000000000..8c4ec683e5 --- /dev/null +++ b/lang/rust/patches/0001-Update-xz2-and-use-it-static.patch @@ -0,0 +1,573 @@ +From cfa7506a303537ee7211bd46c39a96bbc5cea9cf Mon Sep 17 00:00:00 2001 +From: Luca Barbato +Date: Fri, 27 Jan 2023 15:34:36 +0100 +Subject: [PATCH] Update xz2 and lzma-sys + +And use the static build. +--- + Cargo.lock | 140 +++++++-------------------------------- + src/bootstrap/Cargo.lock | 8 +-- + src/bootstrap/Cargo.toml | 2 +- + 3 files changed, 28 insertions(+), 122 deletions(-) + +diff --git a/Cargo.lock b/Cargo.lock +index 6a15105805e..d4ecc363071 100644 +--- a/Cargo.lock ++++ b/Cargo.lock +@@ -295,45 +295,44 @@ version = "1.0.9" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "869119e97797867fd90f5e22af7d0bd274bd4635ebb9eb68c04f3f513ae6c412" + dependencies = [ + "serde", + ] + + [[package]] + name = "cargo" +-version = "0.68.0" ++version = "0.67.1" + dependencies = [ + "anyhow", ++ "atty", + "base64", + "bytesize", + "cargo-platform 0.1.2", + "cargo-test-macro", + "cargo-test-support", + "cargo-util", + "clap 4.0.15", + "crates-io", + "curl", + "curl-sys", +- "env_logger 0.10.0", ++ "env_logger 0.9.0", + "filetime", + "flate2", + "fwdansi", + "git2", + "git2-curl", + "glob", + "hex 0.4.2", + "hmac", + "home", +- "http-auth", + "humantime 2.0.1", + "ignore", + "im-rc", + "indexmap", +- "is-terminal", + "itertools", + "jobserver", + "lazy_static", + "lazycell", + "libc", + "libgit2-sys", + "log", + "memchr", +@@ -363,38 +362,38 @@ dependencies = [ + "unicode-xid", + "url", + "walkdir", + "winapi", + ] + + [[package]] + name = "cargo-credential" +-version = "0.2.0" ++version = "0.1.0" + + [[package]] + name = "cargo-credential-1password" +-version = "0.2.0" ++version = "0.1.0" + dependencies = [ + "cargo-credential", + "serde", + "serde_json", + ] + + [[package]] + name = "cargo-credential-macos-keychain" +-version = "0.2.0" ++version = "0.1.0" + dependencies = [ + "cargo-credential", + "security-framework", + ] + + [[package]] + name = "cargo-credential-wincred" +-version = "0.2.0" ++version = "0.1.0" + dependencies = [ + "cargo-credential", + "winapi", + ] + + [[package]] + name = "cargo-miri" + version = "0.1.0" +@@ -438,38 +437,39 @@ dependencies = [ + "cargo-util", + "crates-io", + "filetime", + "flate2", + "git2", + "glob", + "itertools", + "lazy_static", ++ "remove_dir_all", + "serde_json", + "snapbox", + "tar", + "termcolor", + "toml_edit", + "url", + "winapi", + ] + + [[package]] + name = "cargo-util" +-version = "0.2.3" ++version = "0.2.2" + dependencies = [ + "anyhow", + "core-foundation", + "crypto-hash", + "filetime", + "hex 0.4.2", + "jobserver", + "libc", + "log", +- "miow 0.5.0", ++ "miow", + "same-file", + "shell-escape", + "tempfile", + "walkdir", + "winapi", + ] + + [[package]] +@@ -832,17 +832,17 @@ version = "0.0.0" + dependencies = [ + "colored", + "diff", + "getopts", + "glob", + "lazy_static", + "lazycell", + "libc", +- "miow 0.3.7", ++ "miow", + "miropt-test-tools", + "regex", + "rustfix", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", + "unified-diff", +@@ -857,43 +857,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "70489bbb718aea4f92e5f48f2e3b5be670c2051de30e57cb6e5377b4aa08b372" + dependencies = [ + "diff", + "filetime", + "getopts", + "lazy_static", + "libc", + "log", +- "miow 0.3.7", ++ "miow", + "regex", + "rustfix", + "serde", + "serde_derive", + "serde_json", + "tempfile", + "tester", + "winapi", + ] + + [[package]] + name = "concolor" +-version = "0.0.9" ++version = "0.0.8" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "b90f9dcd9490a97db91a85ccd79e38a87e14323f0bb824659ee3274e9143ba37" ++checksum = "015267563b1df20adccdd00cb05257b1dfbea70a04928e9cf88ffb850c1a40af" + dependencies = [ + "atty", + "bitflags", + "concolor-query", + ] + + [[package]] + name = "concolor-query" +-version = "0.1.0" ++version = "0.0.5" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "82a90734b3d5dcf656e7624cca6bce9c3a90ee11f900e80141a7427ccfb3d317" ++checksum = "d6417fe6fc03a8b533fd2177742eeb39a90c7233eedec7bac96d4d6b69a09449" + + [[package]] + name = "content_inspector" + version = "0.2.4" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "b7bda66e858c683005a53a9a60c69a4aca7eeaa45d124526e389f7aec8e62f38" + dependencies = [ + "memchr", +@@ -939,17 +939,17 @@ version = "0.2.5" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" + dependencies = [ + "libc", + ] + + [[package]] + name = "crates-io" +-version = "0.35.0" ++version = "0.34.0" + dependencies = [ + "anyhow", + "curl", + "percent-encoding", + "serde", + "serde_json", + "url", + ] +@@ -1258,50 +1258,16 @@ checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" + dependencies = [ + "atty", + "humantime 2.0.1", + "log", + "regex", + "termcolor", + ] + +-[[package]] +-name = "env_logger" +-version = "0.10.0" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +-dependencies = [ +- "humantime 2.0.1", +- "is-terminal", +- "log", +- "regex", +- "termcolor", +-] +- +-[[package]] +-name = "errno" +-version = "0.2.8" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +-dependencies = [ +- "errno-dragonfly", +- "libc", +- "winapi", +-] +- +-[[package]] +-name = "errno-dragonfly" +-version = "0.1.2" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +-dependencies = [ +- "cc", +- "libc", +-] +- + [[package]] + name = "error_index_generator" + version = "0.0.0" + dependencies = [ + "mdbook", + ] + + [[package]] +@@ -1795,25 +1761,16 @@ dependencies = [ + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn", + ] + +-[[package]] +-name = "http-auth" +-version = "0.1.6" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "c0b40b39d66c28829a0cf4d09f7e139ff8201f7500a5083732848ed3b4b4d850" +-dependencies = [ +- "memchr", +-] +- + [[package]] + name = "humantime" + version = "1.3.0" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" + dependencies = [ + "quick-error", + ] +@@ -2004,38 +1961,16 @@ dependencies = [ + name = "intl_pluralrules" + version = "7.0.2" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972" + dependencies = [ + "unic-langid", + ] + +-[[package]] +-name = "io-lifetimes" +-version = "1.0.2" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "e394faa0efb47f9f227f1cd89978f854542b318a6f64fa695489c9c993056656" +-dependencies = [ +- "libc", +- "windows-sys", +-] +- +-[[package]] +-name = "is-terminal" +-version = "0.4.0" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "aae5bc6e2eb41c9def29a3e0f1306382807764b9b53112030eff57435667352d" +-dependencies = [ +- "hermit-abi 0.2.6", +- "io-lifetimes", +- "rustix", +- "windows-sys", +-] +- + [[package]] + name = "itertools" + version = "0.10.5" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" + dependencies = [ + "either", + ] +@@ -2235,22 +2170,16 @@ checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" + name = "lint-docs" + version = "0.1.0" + dependencies = [ + "serde_json", + "tempfile", + "walkdir", + ] + +-[[package]] +-name = "linux-raw-sys" +-version = "0.1.3" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f" +- + [[package]] + name = "litemap" + version = "0.6.0" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "f34a3f4798fac63fb48cf277eefa38f94d3443baff555bb98e4f56bc9092368e" + + [[package]] + name = "lld-wrapper" +@@ -2272,19 +2201,19 @@ version = "0.4.14" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" + dependencies = [ + "cfg-if 1.0.0", + ] + + [[package]] + name = "lzma-sys" +-version = "0.1.16" ++version = "0.1.20" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "f24f76ec44a8ac23a31915d6e326bca17ce88da03096f1ff194925dc714dac99" ++checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" + dependencies = [ + "cc", + "libc", + "pkg-config", + ] + + [[package]] + name = "mac" +@@ -2434,25 +2363,16 @@ dependencies = [ + name = "miow" + version = "0.3.7" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" + dependencies = [ + "winapi", + ] + +-[[package]] +-name = "miow" +-version = "0.5.0" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "52ffbca2f655e33c08be35d87278e5b18b89550a37dbd598c20db92f6a471123" +-dependencies = [ +- "windows-sys", +-] +- + [[package]] + name = "miri" + version = "0.1.0" + dependencies = [ + "colored", + "env_logger 0.9.0", + "getrandom 0.2.0", + "lazy_static", +@@ -4637,30 +4557,16 @@ dependencies = [ + "term", + "thiserror", + "toml", + "unicode-segmentation", + "unicode-width", + "unicode_categories", + ] + +-[[package]] +-name = "rustix" +-version = "0.36.3" +-source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "0b1fbb4dfc4eb1d390c02df47760bb19a84bb80b301ecc947ab5406394d8223e" +-dependencies = [ +- "bitflags", +- "errno", +- "io-lifetimes", +- "libc", +- "linux-raw-sys", +- "windows-sys", +-] +- + [[package]] + name = "rustversion" + version = "1.0.5" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088" + + [[package]] + name = "ryu" +@@ -4879,19 +4785,19 @@ checksum = "cc88c725d61fc6c3132893370cac4a0200e3fedf5da8331c570664b1987f5ca2" + [[package]] + name = "snap" + version = "1.0.1" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "da73c8f77aebc0e40c300b93f0a5f1bece7a248a36eee287d4e095f35c7b7d6e" + + [[package]] + name = "snapbox" +-version = "0.4.1" ++version = "0.3.3" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "827c00e91b15e2674d8a5270bae91f898693cbf9561cbb58d8eaa31974597293" ++checksum = "44d199ccf8f606592df2d145db26f2aa45344e23c64b074cc5a4047f1d99b0f7" + dependencies = [ + "concolor", + "content_inspector", + "dunce", + "filetime", + "normalize-line-endings", + "similar", + "snapbox-macros", +@@ -5866,19 +5772,19 @@ version = "0.2.2" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" + dependencies = [ + "libc", + ] + + [[package]] + name = "xz2" +-version = "0.1.6" ++version = "0.1.7" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "c179869f34fc7c01830d3ce7ea2086bc3a07e0d35289b667d0a8bf910258926c" ++checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" + dependencies = [ + "lzma-sys", + ] + + [[package]] + name = "yaml-merge-keys" + version = "0.4.1" + source = "registry+https://github.com/rust-lang/crates.io-index" +diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock +index efe8ae3169f..ad115c46110 100644 +--- a/src/bootstrap/Cargo.lock ++++ b/src/bootstrap/Cargo.lock +@@ -346,19 +346,19 @@ version = "0.4.17" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" + dependencies = [ + "cfg-if", + ] + + [[package]] + name = "lzma-sys" +-version = "0.1.17" ++version = "0.1.20" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "bdb4b7c3eddad11d3af9e86c487607d2d2442d185d848575365c4856ba96d619" ++checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" + dependencies = [ + "cc", + "libc", + "pkg-config", + ] + + [[package]] + name = "memchr" +@@ -780,19 +780,19 @@ version = "0.2.3" + source = "registry+https://github.com/rust-lang/crates.io-index" + checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc" + dependencies = [ + "libc", + ] + + [[package]] + name = "xz2" +-version = "0.1.6" ++version = "0.1.7" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "c179869f34fc7c01830d3ce7ea2086bc3a07e0d35289b667d0a8bf910258926c" ++checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" + dependencies = [ + "lzma-sys", + ] + + [[package]] + name = "yansi" + version = "0.5.1" + source = "registry+https://github.com/rust-lang/crates.io-index" +diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml +index ccc7ec1fce9..6d5838439db 100644 +--- a/src/bootstrap/Cargo.toml ++++ b/src/bootstrap/Cargo.toml +@@ -46,17 +46,17 @@ object = { version = "0.29.0", default-features = false, features = ["archive", + serde = { version = "1.0.8", features = ["derive"] } + serde_json = "1.0.2" + sha2 = "0.10" + tar = "0.4" + toml = "0.5" + ignore = "0.4.10" + opener = "0.5" + once_cell = "1.7.2" +-xz2 = "0.1" ++xz2 = { version = "0.1", features = ["static"] } + walkdir = "2" + + # Dependencies needed by the build-metrics feature + sysinfo = { version = "0.26.0", optional = true } + + [target.'cfg(windows)'.dependencies.winapi] + version = "0.3" + features = [ +-- +2.38.0 + diff --git a/lang/rust/rust-host.mk b/lang/rust/rust-host.mk new file mode 100644 index 0000000000..acc93c521d --- /dev/null +++ b/lang/rust/rust-host.mk @@ -0,0 +1,58 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2023 Luca Barbato and Donald Hoskins + +# Rust Environmental Vars +CONFIG_HOST_SUFFIX:=$(word 4, $(subst -, ,$(GNU_HOST_NAME))) +RUSTC_HOST_ARCH:=$(HOST_ARCH)-unknown-linux-$(CONFIG_HOST_SUFFIX) +CARGO_HOME:=$(STAGING_DIR_HOST)/cargo + +# Support only a subset for now. +RUST_ARCH_DEPENDS:=@(aarch64||arm||i386||i686||mips||mipsel||mips64||mips64el||mipsel||powerpc64||x86_64) + +# Common Build Flags +RUST_BUILD_FLAGS = \ + CARGO_HOME="$(CARGO_HOME)" + +# This adds the rust environmental variables to Make calls +MAKE_FLAGS += $(RUST_BUILD_FLAGS) + +# Force linking of the SSP library +ifdef CONFIG_PKG_CC_STACKPROTECTOR_REGULAR + ifeq ($(strip $(PKG_SSP)),1) + RUSTC_LDFLAGS += -lssp_nonshared + endif +endif +ifdef CONFIG_PKG_CC_STACKPROTECTOR_STRONG + ifeq ($(strip $(PKG_SSP)),1) + TARGET_CFLAGS += -lssp_nonshared + endif +endif + +# mips64 openwrt has a specific targed in rustc +ifeq ($(ARCH),mips64) + RUSTC_TARGET_ARCH:=$(REAL_GNU_TARGET_NAME) +else + RUSTC_TARGET_ARCH:=$(subst openwrt,unknown,$(REAL_GNU_TARGET_NAME)) +endif + +RUSTC_TARGET_ARCH:=$(subst muslgnueabi,musleabi,$(RUSTC_TARGET_ARCH)) + +ifeq ($(ARCH),i386) + RUSTC_TARGET_ARCH:=$(subst i486,i586,$(RUSTC_TARGET_ARCH)) +endif + +# ARM Logic +ifeq ($(ARCH),arm) + ifeq ($(CONFIG_arm_v7),y) + RUSTC_TARGET_ARCH:=$(subst arm,armv7,$(RUSTC_TARGET_ARCH)) + endif + + ifeq ($(CONFIG_HAS_FPU),y) + RUSTC_TARGET_ARCH:=$(subst musleabi,musleabihf,$(RUSTC_TARGET_ARCH)) + endif +endif + +ifeq ($(ARCH),aarch64) + RUST_CFLAGS:=-mno-outline-atomics +endif diff --git a/lang/rust/rust-package.mk b/lang/rust/rust-package.mk new file mode 100644 index 0000000000..54c2aa89ac --- /dev/null +++ b/lang/rust/rust-package.mk @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2023 Luca Barbato and Donald Hoskins + +rust_mk_path:=$(dir $(lastword $(MAKEFILE_LIST))) +include $(rust_mk_path)rust-host.mk + +# $(1) path to the package +# $(2) additional arguments to cargo +define Host/Compile/Cargo + ( \ + cd $(HOST_BUILD_DIR) ; \ + export PATH="$(CARGO_HOME)/bin:$(PATH)" ; \ + CARGO_HOME=$(CARGO_HOME) CC=$(HOSTCC) \ + cargo install -v --profile stripped --root $(HOST_INSTALL_DIR) --path "$(if $(strip $(1)),$(strip $(1)),.)" $(2) ; \ + ) +endef + +# $(1) path to the package +# $(2) additional arguments to cargo +define Build/Compile/Cargo + ( \ + cd $(PKG_BUILD_DIR) ; \ + export PATH="$(CARGO_HOME)/bin:$(PATH)" ; \ + CARGO_HOME=$(CARGO_HOME) TARGET_CFLAGS="$(TARGET_CFLAGS) $(RUST_CFLAGS)" TARGET_CC=$(TARGET_CC_NOCACHE) CC=cc \ + cargo install -v --profile stripped --target $(RUSTC_TARGET_ARCH) --root $(PKG_INSTALL_DIR) --path "$(if $(strip $(1)),$(strip $(1)),.)" $(2) ; \ + ) +endef diff --git a/lang/rust/rust_config.mk b/lang/rust/rust_config.mk new file mode 100644 index 0000000000..75017f8a7b --- /dev/null +++ b/lang/rust/rust_config.mk @@ -0,0 +1,119 @@ +ifeq ($(CONFIG_RUST_DEBUG),y) +CONFIGURE_ARGS += --enable-debug +endif + +ifeq ($(CONFIG_RUST_DOCS),y) +CONFIGURE_ARGS += --enable-docs +else +CONFIGURE_ARGS += --disable-docs +endif + +ifeq ($(CONFIG_RUST_COMPILER_DOCS),y) +CONFIGURE_ARGS += --enable-compiler-docs +else +CONFIGURE_ARGS += --disable-compiler-docs +endif + +ifeq ($(CONFIG_RUST_OPTIMIZE_TESTS),y) +CONFIGURE_ARGS += --enable-optimize-tests +endif + +ifeq ($(CONFIG_RUST_PARALLEL),y) +CONFIGURE_ARGS += --enable-parallel-compiler +endif + +ifeq ($(CONFIG_RUST_VERBOSE_TESTS),y) +CONFIGURE_ARGS += --enable-verbose-tests +endif + +ifeq ($(filter $(CONFIG_RUST_CCACHE) $(CCACHE),y),) +CONFIGURE_ARGS += --enable-ccache +endif + +ifeq ($(CONFIG_RUST_CCACHE),y) +CONFIGURE_ARGS += --enable-ccache +endif + +ifeq ($(CONFIG_RUST_LLVM_STATIC),y) +CONFIGURE_ARGS += --enable-llvm-static-stdcpp +endif + +ifeq ($(CONFIG_RUST_LLVM_SHARED),y) +CONFIGURE_ARGS += --enable-llvm-link-shared +endif + +ifeq ($(CONFIG_RUST_CODEGEN_TESTS),y) +CONFIGURE_ARGS += --enable-codegen-tests +endif + +ifeq ($(CONFIG_RUST_OPTION_CHECKING),y) +CONFIGURE_ARGS += --enable-option-checking +endif + +ifeq ($(CONFIG_RUST_ENABLE_NINJA),y) +CONFIGURE_ARGS += --enable-ninja +endif + +ifeq ($(CONFIG_RUST_LOCKED_DEPS),y) +CONFIGURE_ARGS += --enable-locked-deps +endif + +ifeq ($(CONFIG_RUST_VENDOR),y) +CONFIGURE_ARGS += --enable-vendor +endif + +ifeq ($(CONFIG_RUST_SANITIZERS),y) +CONFIGURE_ARGS += --enable-sanitizers +endif + +ifeq ($(CONFIG_RUST_DIST_SRC),y) +CONFIGURE_ARGS += --enable-dist-src +endif + +ifeq ($(CONFIG_RUST_CARGO_NATIVE_STATIC),y) +CONFIGURE_ARGS += --enable-cargo-native-static +endif + +ifeq ($(CONFIG_RUST_PROFILER),y) +CONFIGURE_ARGS += --enable-profiler +endif + +ifeq ($(CONFIG_RUST_FULL_TOOLS),y) +CONFIGURE_ARGS += --enable-full-tools +endif + +ifeq ($(CONFIG_RUST_MISSING_TOOLS),y) +CONFIGURE_ARGS += --enable-missing-tools +endif + +ifeq ($(CONFIG_RUST_USE_LIBCXX),y) +CONFIGURE_ARGS += --enable-use-libcxx +endif + +ifeq ($(CONFIG_RUST_CONTROL_FLOW_GUARD),y) +CONFIGURE_ARGS += --enable-control-flow-guard +endif + +ifeq ($(CONFIG_RUST_OPTIMIZE_LLVM),y) +CONFIGURE_ARGS += --enable-optimize-llvm +endif + +ifeq ($(CONFIG_RUST_LLVM_ASSERTIONS),y) +CONFIGURE_ARGS += --enable-llvm-assertions +endif + +ifeq ($(CONFIG_RUST_DEBUG_ASSERTIONS),y) +CONFIGURE_ARGS += --enable-debug-assertions +endif + +ifeq ($(CONFIG_RUST_LLVM_RELEASE_DEBUGINFO),y) +CONFIGURE_ARGS += --enable-llvm-release-debuginfo +endif + +ifeq ($(CONFIG_RUST_MANAGE_SUBMODULES),y) +CONFIGURE_ARGS += --enable-manage-submodules +endif + +ifeq ($(CONFIG_RUST_FULL_BOOTSTRAP),y) +CONFIGURE_ARGS += --enable-full-bootstrap +endif diff --git a/libs/icu/Makefile b/libs/icu/Makefile index 3534d5d806..b34c226f4e 100644 --- a/libs/icu/Makefile +++ b/libs/icu/Makefile @@ -11,7 +11,7 @@ PKG_NAME:=icu4c MAJOR_VERSION:=72 MINOR_VERSION:=1 PKG_VERSION:=$(MAJOR_VERSION).$(MINOR_VERSION) -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(MAJOR_VERSION)_$(MINOR_VERSION)-src.tgz PKG_SOURCE_URL:=https://github.com/unicode-org/icu/releases/download/release-$(MAJOR_VERSION)-$(MINOR_VERSION) @@ -79,8 +79,8 @@ endef CONFIGURE_CMD:= ./runConfigureICU CONFIGURE_ARGS:= \ Linux/gcc \ - CC="$(TARGET_CC)" \ - CXX="$(TARGET_CXX)" \ + CC="$(TARGET_CC_NOCACHE)" \ + CXX="$(TARGET_CXX_NOCACHE)" \ --target=$(GNU_TARGET_NAME) \ --host=$(GNU_TARGET_NAME) \ --build=$(GNU_HOST_NAME) \ diff --git a/libs/libb64/Makefile b/libs/libb64/Makefile new file mode 100644 index 0000000000..8223975917 --- /dev/null +++ b/libs/libb64/Makefile @@ -0,0 +1,34 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=libb64 +PKG_VERSION:=2.0.0 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/libb64/libb64/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=28c43c47674409fc50e7145d4c2d26dc1f3d200889c41205e7812c2b67f26382 + +PKG_LICENSE:=PublicDomain +PKG_LICENSE_FILES:=LICENSE.md + +PKG_MAINTAINER:=Daniel Golle + +include $(INCLUDE_DIR)/package.mk + +MAKE_FLAGS+=all_src + +define Package/libb64 + SECTION:=libs + CATEGORY:=Libraries + TITLE:=Base64 Encoding/Decoding Routines + URL:=https://github.com/libb64/libb64 + BUILDONLY:=1 +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/b64 $(1)/usr/lib + $(CP) $(PKG_BUILD_DIR)/include/b64/*.h $(1)/usr/include/b64 + $(CP) $(PKG_BUILD_DIR)/src/*.a $(1)/usr/lib/ +endef + +$(eval $(call BuildPackage,libb64)) diff --git a/libs/libb64/patches/100-no-Werror.patch b/libs/libb64/patches/100-no-Werror.patch new file mode 100644 index 0000000000..5485999234 --- /dev/null +++ b/libs/libb64/patches/100-no-Werror.patch @@ -0,0 +1,11 @@ +--- a/src/Makefile ++++ b/src/Makefile +@@ -15,7 +15,7 @@ TARGETS = $(LIBRARIES) + + LINK.o = gcc + +-CFLAGS += -Werror -pedantic ++CFLAGS += -pedantic + CFLAGS += -I../include + + vpath %.h ../include/b64 diff --git a/libs/libdaq3/Makefile b/libs/libdaq3/Makefile index 7d386a1dec..a97eb77552 100644 --- a/libs/libdaq3/Makefile +++ b/libs/libdaq3/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libdaq3 -PKG_VERSION:=3.0.10 +PKG_VERSION:=3.0.11 PKG_RELEASE:=1 PKG_MAINTAINER:=W. Michael Petullo @@ -17,7 +17,7 @@ PKG_LICENSE:=GPL-2.0-only PKG_SOURCE:=libdaq-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/snort3/libdaq/tar.gz/v$(PKG_VERSION)? -PKG_HASH:=a540b8657dbacab61e23ead203564f351ee30af85f0261979f14f2b7159f701f +PKG_HASH:=c9b691e113960cc19c4df6e93eacbdb45c96491da9c81471f3e419b91c04579a PKG_BUILD_DIR:=$(BUILD_DIR)/libdaq-$(PKG_VERSION) PKG_FIXUP:=autoreconf diff --git a/libs/libdeflate/Makefile b/libs/libdeflate/Makefile new file mode 100644 index 0000000000..1eb16c7998 --- /dev/null +++ b/libs/libdeflate/Makefile @@ -0,0 +1,38 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=libdeflate +PKG_VERSION:=1.17 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/ebiggers/libdeflate/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=fa4615af671513fa2a53dc2e7a89ff502792e2bdfc046869ef35160fcc373763 + +PKG_LICENSE:=COPYING +PKG_LICENSE_FILES:=MIT + +PKG_MAINTAINER:=Daniel Golle + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/libdeflate + SECTION:=libs + CATEGORY:=Libraries + TITLE:=library for fast, whole-buffer DEFLATE-based compression and decompression + URL:=https://github.com/ebiggers/libdeflate +endef + +define Package/libdeflate/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libdeflate.so* $(1)/usr/lib/ +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include $(1)/usr/lib/pkgconfig + $(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/ + $(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libdeflate.pc $(1)/usr/lib/pkgconfig/ +endef + +$(eval $(call BuildPackage,libdeflate)) diff --git a/libs/libdht/Makefile b/libs/libdht/Makefile new file mode 100644 index 0000000000..f81847aa82 --- /dev/null +++ b/libs/libdht/Makefile @@ -0,0 +1,41 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=libdht +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/jech/dht +PKG_SOURCE_DATE:=2022-04-27 +PKG_SOURCE_VERSION:=111230894416d400c9a1e038a033586bfeaafc93 +PKG_MIRROR_HASH:=71decd82023e0d3ec872604e9f0d709003906b38266990a8b1bb540907d1d3f0 + +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=LICENSE + +PKG_MAINTAINER:=Daniel Golle + +include $(INCLUDE_DIR)/package.mk + +define Package/libdht + SECTION:=libs + CATEGORY:=Libraries + TITLE:=Kademlia Distributed Hash Table (DHT) library +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/dht $(1)/usr/lib + $(CP) $(PKG_BUILD_DIR)/dht.h $(1)/usr/include/dht + $(CP) $(PKG_BUILD_DIR)/libdht.so $(1)/usr/lib/ +endef + +define Package/libdht/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_BUILD_DIR)/libdht.so $(1)/usr/lib/ +endef + +define Build/Compile + $(TARGET_CC) $(FPIC) -Wall -c -o $(PKG_BUILD_DIR)/dht.o $(PKG_BUILD_DIR)/dht.c + $(TARGET_CC) -shared -lcrypt -o $(PKG_BUILD_DIR)/libdht.so $(PKG_BUILD_DIR)/dht.o +endef + +$(eval $(call BuildPackage,libdht)) diff --git a/libs/libmbim/Makefile b/libs/libmbim/Makefile index abd94d617a..8591b4337f 100644 --- a/libs/libmbim/Makefile +++ b/libs/libmbim/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libmbim -PKG_SOURCE_VERSION:=1.28.2 +PKG_SOURCE_VERSION:=1.28.4 PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://gitlab.freedesktop.org/mobile-broadband/libmbim.git -PKG_MIRROR_HASH:=0b0b46016738fc22355d5a58c8a2d1b2f04906c49c51a50b57a09640d13b00b7 +PKG_MIRROR_HASH:=7ecc6d1e565392817311254045337907bbad015b46ec88542ea63594f47778be PKG_MAINTAINER:=Nicholas Smith diff --git a/libs/libqmi/Makefile b/libs/libqmi/Makefile index bfa3bab7c9..8dac951552 100644 --- a/libs/libqmi/Makefile +++ b/libs/libqmi/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libqmi -PKG_SOURCE_VERSION:=1.32.2 +PKG_SOURCE_VERSION:=1.32.4 PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://gitlab.freedesktop.org/mobile-broadband/libqmi.git -PKG_MIRROR_HASH:=711d16d75a6a9afaefcf2be1bc845a4a6181dff786dfbd079e41e91279a0be91 +PKG_MIRROR_HASH:=674f5848c56c11cdc2fbc82c52e5bc2a3a0fddb56315dc4220544688a7b0e17a PKG_MAINTAINER:=Nicholas Smith diff --git a/libs/libutp/Makefile b/libs/libutp/Makefile new file mode 100644 index 0000000000..28c755d9f4 --- /dev/null +++ b/libs/libutp/Makefile @@ -0,0 +1,46 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=libutp +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/transmission/libutp +PKG_SOURCE_DATE:=2023-02-14 +PKG_SOURCE_VERSION:=c95738b1a6644b919e5b64d3ea9736cfc5894e0b +PKG_MIRROR_HASH:=5e466da0cb45119d58e8dd847da13951c94bfe9f20936f96b43f350d1e49c625 + +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=LICENSE + +PKG_MAINTAINER:=Daniel Golle + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/libutp + SECTION:=libs + CATEGORY:=Libraries + TITLE:=The uTorrent Transport Protocol library + DEPENDS:=+libstdcpp +endef + +# MAKE_VARS+=OPT="-I$(PKG_BUILD_DIR)/include/libutp -I$(PKG_BUILD_DIR)/include" + +CMAKE_OPTIONS += \ + -DLIBUTP_SHARED:BOOL=YES \ + -DLIBUTP_ENABLE_INSTALL:BOOL=YES \ + -DLIBUTP_ENABLE_WERROR:BOOL=YES \ + -DLIBUTP_BUILD_PROGRAMS:BOOL=NO + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/libutp $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/include/libutp/*.h $(1)/usr/include/libutp + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libutp.so $(1)/usr/lib/ +endef + +define Package/libutp/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_BUILD_DIR)/libutp.so $(1)/usr/lib/ +endef + +$(eval $(call BuildPackage,libutp)) diff --git a/libs/msgpack-c/Makefile b/libs/msgpack-c/Makefile index d2d20fe9ea..7cdaae73a0 100644 --- a/libs/msgpack-c/Makefile +++ b/libs/msgpack-c/Makefile @@ -5,12 +5,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=msgpack-c -PKG_VERSION:=5.0.0 +PKG_VERSION:=6.0.0 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/msgpack/msgpack-c/tar.gz/c-$(PKG_VERSION)? -PKG_HASH:=a61288a9a46fd3b3b4cbd48a17736a9568b65419141cb536833f9adfe8fc97d7 +PKG_HASH:=af6f3cf25edb220aa2140b09bb5bdd73ddf00938194bd94ebe5c92090cccb466 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-c-$(PKG_VERSION) PKG_LICENSE:=BSL-1.0 @@ -46,7 +46,7 @@ endef define Package/msgpack-c/install $(INSTALL_DIR) $(1)/usr/lib - $(CP) $(PKG_INSTALL_DIR)/usr/lib/libmsgpackc.so* $(1)/usr/lib/ + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libmsgpack-c.so* $(1)/usr/lib/ endef $(eval $(call BuildPackage,msgpack-c)) diff --git a/libs/msgpack-c/patches/010-no-gtest.patch b/libs/msgpack-c/patches/010-no-gtest.patch deleted file mode 100644 index 7bb4dbeed4..0000000000 --- a/libs/msgpack-c/patches/010-no-gtest.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -74,7 +74,6 @@ IF (MSGPACK_CHAR_SIGN) - SET (CMAKE_C_FLAGS "-f${MSGPACK_CHAR_SIGN}-char ${CMAKE_C_FLAGS}") - ENDIF () - --FIND_PACKAGE (GTest) - FIND_PACKAGE (ZLIB) - FIND_PACKAGE (Threads) - IF (GTEST_FOUND AND ZLIB_FOUND AND THREADS_FOUND) diff --git a/libs/openblas/Makefile b/libs/openblas/Makefile index 7dd5ed9fa1..83d7d7099d 100644 --- a/libs/openblas/Makefile +++ b/libs/openblas/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=OpenBLAS PKG_VERSION:=0.3.21 -PKG_RELEASE:=$(AUTORELEASE) +PKG_RELEASE:=2 PKG_SOURCE:=OpenBLAS-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://github.com/xianyi/OpenBLAS/releases/download/v$(PKG_VERSION)/ @@ -76,6 +76,8 @@ endif MAKE_FLAGS += \ CROSS=1 \ + CC=$(TARGET_CC_NOCACHE) \ + CXX=$(TARGET_CXX_NOCACHE) \ HOSTCC=$(HOSTCC_NOCACHE) \ CROSS_SUFFIX=$(TARGET_CROSS) \ BINARY=$(OPENBLAS_BINARY) \ diff --git a/libs/protobuf-c/Makefile b/libs/protobuf-c/Makefile index 8c79a8884e..b1d1670330 100644 --- a/libs/protobuf-c/Makefile +++ b/libs/protobuf-c/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libprotobuf-c -PKG_VERSION:=1.4.0 -PKG_RELEASE:=$(AUTORELEASE) +PKG_VERSION:=1.4.1 +PKG_RELEASE:=1 PKG_SOURCE:=protobuf-c-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://github.com/protobuf-c/protobuf-c/releases/download/v$(PKG_VERSION) -PKG_HASH:=26d98ee9bf18a6eba0d3f855ddec31dbe857667d269bc0b6017335572f85bbcb +PKG_HASH:=4cc4facd508172f3e0a4d3a8736225d472418aee35b4ad053384b137b220339f PKG_BUILD_DIR:=$(BUILD_DIR)/protobuf-c-$(PKG_VERSION) HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/protobuf-c-$(PKG_VERSION) diff --git a/libs/tiff/Makefile b/libs/tiff/Makefile index 3b65ca7c1b..39d7052324 100644 --- a/libs/tiff/Makefile +++ b/libs/tiff/Makefile @@ -64,7 +64,8 @@ CMAKE_OPTIONS += \ -Dzstd=OFF \ -Dwebp=OFF \ -Djpeg12=OFF \ - -Dcxx=OFF + -Dcxx=OFF \ + -Dlibdeflate=OFF define Build/InstallDev $(call Build/InstallDev/cmake,$(1)) diff --git a/multimedia/yt-dlp/Makefile b/multimedia/yt-dlp/Makefile index ee8e7adc3d..1ec3ebaedd 100644 --- a/multimedia/yt-dlp/Makefile +++ b/multimedia/yt-dlp/Makefile @@ -1,11 +1,11 @@ include $(TOPDIR)/rules.mk PKG_NAME:=yt-dlp -PKG_VERSION:=2023.1.6 +PKG_VERSION:=2023.3.4 PKG_RELEASE:=1 PYPI_NAME:=yt-dlp -PKG_HASH:=3a783a36751ced16368f40b3ba865ab39b30689ed8056f1ee2346aa3839a0b0f +PKG_HASH:=265d5da97a76c15d7d9a4088a67b78acd5dcf6f8cfd8257c52f581ff996ff515 PKG_MAINTAINER:=Michal Vasilek PKG_LICENSE:=Unlicense diff --git a/net/adguardhome/Makefile b/net/adguardhome/Makefile index 309ffec6c3..328c1329eb 100644 --- a/net/adguardhome/Makefile +++ b/net/adguardhome/Makefile @@ -6,13 +6,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=adguardhome -PKG_VERSION:=0.107.24 +PKG_VERSION:=0.107.25 PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_VERSION:=v$(PKG_VERSION) PKG_SOURCE_URL:=https://github.com/AdguardTeam/AdGuardHome -PKG_MIRROR_HASH:=ff5e38d977b8c8f5a546b745ab46894dd4b55f76b447b147287b47d03f6cd507 +PKG_MIRROR_HASH:=609e991f0d03c1541e02fc656f8abea686e64ed350729b85ea87fe25640dd03a PKG_LICENSE:=GPL-3.0-only PKG_LICENSE_FILES:=LICENSE.txt @@ -56,7 +56,7 @@ endef define Build/Compile ( \ pushd $(PKG_BUILD_DIR) ; \ - make js-deps js-build ; \ + NODE_OPTIONS=--openssl-legacy-provider make js-deps js-build ; \ popd ; \ $(call GoPackage/Build/Compile) ; \ ) diff --git a/net/banip/Makefile b/net/banip/Makefile index a75867df3c..7e1d5265a7 100644 --- a/net/banip/Makefile +++ b/net/banip/Makefile @@ -1,5 +1,5 @@ # -# banIP - ban incoming and outgoing ip adresses/subnets via sets in nftables +# banIP - ban incoming and outgoing ip addresses/subnets via sets in nftables # Copyright (c) 2018-2023 Dirk Brenken (dev@brenken.org) # This is free software, licensed under the GNU General Public License v3. # @@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=banip -PKG_VERSION:=0.8.1 +PKG_VERSION:=0.8.2 PKG_RELEASE:=2 PKG_LICENSE:=GPL-3.0-or-later PKG_MAINTAINER:=Dirk Brenken diff --git a/net/banip/files/README.md b/net/banip/files/README.md index f936a8e5b7..8e7afa35d5 100644 --- a/net/banip/files/README.md +++ b/net/banip/files/README.md @@ -31,72 +31,74 @@ IP address blocking is commonly used to protect against brute force attacks, pre | firehol2 | firehol level 2 compilation | x | x | | [Link](https://iplists.firehol.org/?ipset=firehol_level2) | | firehol3 | firehol level 3 compilation | x | x | | [Link](https://iplists.firehol.org/?ipset=firehol_level3) | | firehol4 | firehol level 4 compilation | x | x | | [Link](https://iplists.firehol.org/?ipset=firehol_level4) | -| greensnow | suspicious server IPs | x | x | x | [Link](https://greensnow.co) | +| greensnow | suspicious server IPs | x | x | | [Link](https://greensnow.co) | | iblockads | Advertising IPs | | | x | [Link](https://www.iblocklist.com) | -| iblockspy | Malicious spyware IPs | x | x | x | [Link](https://www.iblocklist.com) | +| iblockspy | Malicious spyware IPs | x | x | | [Link](https://www.iblocklist.com) | | myip | real-time IP blocklist | x | x | | [Link](https://myip.ms) | | nixspam | iX spam protection | x | x | | [Link](http://www.nixspam.org) | | oisdbig | OISD-big IPs | | | x | [Link](https://github.com/dibdot/banIP-IP-blocklists) | | oisdnsfw | OISD-nsfw IPs | | | x | [Link](https://github.com/dibdot/banIP-IP-blocklists) | | oisdsmall | OISD-small IPs | | | x | [Link](https://github.com/dibdot/banIP-IP-blocklists) | | proxy | open proxies | x | | | [Link](https://iplists.firehol.org/?ipset=proxylists) | -| ssbl | SSL botnet IPs | x | x | x | [Link](https://sslbl.abuse.ch) | +| ssbl | SSL botnet IPs | x | x | | [Link](https://sslbl.abuse.ch) | | stevenblack | stevenblack IPs | | | x | [Link](https://github.com/dibdot/banIP-IP-blocklists) | | talos | talos IPs | x | x | | [Link](https://talosintelligence.com/reputation_center) | -| threat | emerging threats | x | x | x | [Link](https://rules.emergingthreats.net) | -| threatview | malicious IPs | x | x | x | [Link](https://threatview.io) | -| tor | tor exit nodes | x | x | x | [Link](https://github.com/SecOps-Institute/Tor-IP-Addresses) | +| threat | emerging threats | x | x | | [Link](https://rules.emergingthreats.net) | +| threatview | malicious IPs | x | x | | [Link](https://threatview.io) | +| tor | tor exit nodes | x | x | | [Link](https://github.com/SecOps-Institute/Tor-IP-Addresses) | | uceprotect1 | spam protection level 1 | x | x | | [Link](http://www.uceprotect.net/en/index.php) | | uceprotect2 | spam protection level 2 | x | x | | [Link](http://www.uceprotect.net/en/index.php) | | uceprotect3 | spam protection level 3 | x | x | | [Link](http://www.uceprotect.net/en/index.php) | | urlhaus | urlhaus IDS IPs | x | x | | [Link](https://urlhaus.abuse.ch) | -| urlvir | malware related IPs | x | x | x | [Link](https://iplists.firehol.org/?ipset=urlvir) | -| webclient | malware related IPs | x | x | x | [Link](https://iplists.firehol.org/?ipset=firehol_webclient) | +| urlvir | malware related IPs | x | x | | [Link](https://iplists.firehol.org/?ipset=urlvir) | +| webclient | malware related IPs | x | x | | [Link](https://iplists.firehol.org/?ipset=firehol_webclient) | | voip | VoIP fraud blocklist | x | x | | [Link](https://voipbl.org) | | yoyo | yoyo IPs | | | x | [Link](https://github.com/dibdot/banIP-IP-blocklists) | -* zero-conf like automatic installation & setup, usually no manual changes needed -* all sets are handled in a separate nft table/namespace 'banIP' -* full IPv4 and IPv6 support -* supports nft atomic set loading -* supports blocking by ASN numbers and by iso country codes -* supports local allow- and blocklist (IPv4, IPv6, CIDR notation or domain names) -* auto-add the uplink subnet to the local allowlist -* provides a small background log monitor to ban unsuccessful login attempts in real-time -* auto-add unsuccessful LuCI, nginx, Asterisk or ssh login attempts to the local blocklist -* fast feed processing as they are handled in parallel as background jobs -* per feed it can be defined whether the wan-input chain, the wan-forward chain or the lan-forward chain should be blocked (default: all chains) -* automatic blocklist backup & restore, the backups will be used in case of download errors or during startup -* automatically selects one of the following download utilities with ssl support: aria2c, curl, uclient-fetch or wget -* supports an 'allowlist only' mode, this option restricts internet access from/to a small number of secure websites/IPs -* deduplicate IPs accross all sets (single IPs only, no intervals) -* provides comprehensive runtime information -* provides a detailed set report -* provides a set search engine for certain IPs -* feed parsing by fast & flexible regex rulesets -* minimal status & error logging to syslog, enable debug logging to receive more output -* procd based init system support (start/stop/restart/reload/status/report/search) -* procd network interface trigger support -* ability to add new banIP feeds on your own +* Zero-conf like automatic installation & setup, usually no manual changes needed +* All sets are handled in a separate nft table/namespace 'banIP' +* Full IPv4 and IPv6 support +* Supports nft atomic set loading +* Supports blocking by ASN numbers and by iso country codes +* Supports local allow- and blocklist (IPv4, IPv6, CIDR notation or domain names) +* Auto-add the uplink subnet to the local allowlist +* Provides a small background log monitor to ban unsuccessful login attempts in real-time +* Auto-add unsuccessful LuCI, nginx, Asterisk or ssh login attempts to the local blocklist +* Fast feed processing as they are handled in parallel as background jobs +* Per feed it can be defined whether the wan-input chain, the wan-forward chain or the lan-forward chain should be blocked (default: all chains) +* Automatic blocklist backup & restore, the backups will be used in case of download errors or during startup +* Automatically selects one of the following download utilities with ssl support: aria2c, curl, uclient-fetch or wget +* Supports an 'allowlist only' mode, this option restricts internet access from/to a small number of secure websites/IPs +* Deduplicate IPs accross all sets (single IPs only, no intervals) +* Provides comprehensive runtime information +* Provides a detailed set report +* Provides a set search engine for certain IPs +* Feed parsing by fast & flexible regex rulesets +* Minimal status & error logging to syslog, enable debug logging to receive more output +* Procd based init system support (start/stop/restart/reload/status/report/search/survey) +* Procd network interface trigger support +* Ability to add new banIP feeds on your own ## Prerequisites -* **[OpenWrt](https://openwrt.org)**, latest stable release or a snapshot with nft/firewall 4 support -* a download utility with SSL support: 'wget', 'uclient-fetch' with one of the 'libustream-*' SSL libraries, 'aria2c' or 'curl' is required -* a certificate store like 'ca-bundle', as banIP checks the validity of the SSL certificates of all download sites by default -* for E-Mail notifications you need to install and setup the additional 'msmtp' package +* **[OpenWrt](https://openwrt.org)**, latest stable release or a snapshot with nft/firewall 4 support +* A download utility with SSL support: 'wget', 'uclient-fetch' with one of the 'libustream-*' SSL libraries, 'aria2c' or 'curl' is required +* A certificate store like 'ca-bundle', as banIP checks the validity of the SSL certificates of all download sites by default +* For E-Mail notifications you need to install and setup the additional 'msmtp' package **Please note the following:** * Devices with less than 256Mb of RAM are **_not_** supported * Any previous installation of ancient banIP 0.7.x must be uninstalled, and the /etc/banip folder and the /etc/config/banip configuration file must be deleted (they are recreated when this version is installed) ## Installation & Usage -* update your local opkg repository (_opkg update_) -* install banIP (_opkg install banip_) - the banIP service is disabled by default -* edit the config file '/etc/config/banip' and enable the service (set ban\_enabled to '1'), then add pre-configured feeds via 'ban\_feed' (see the feed list above) and add/change other options to your needs (see the options reference below) -* start the service with '/etc/init.d/banip start' and check check everything is working by running '/etc/init.d/banip status' +* Update your local opkg repository (_opkg update_) +* Install banIP (_opkg install banip_) - the banIP service is disabled by default +* Install the LuCI companion package 'luci-app-banip' (opkg install luci-app-banip) +* It's strongly recommended to use the LuCI frontend to easily configure all aspects of banIP, the application is located in LuCI under the 'Services' menu +* If you're going to configure banIP via CLI, edit the config file '/etc/config/banip' and enable the service (set ban\_enabled to '1'), then add pre-configured feeds via 'ban\_feed' (see the feed list above) and add/change other options to your needs (see the options reference below) +* Start the service with '/etc/init.d/banip start' and check check everything is working by running '/etc/init.d/banip status' ## banIP CLI interface -* All important banIP functions are accessible via CLI. A LuCI frontend will be available in due course. +* All important banIP functions are accessible via CLI. ``` ~# /etc/init.d/banip Syntax: /etc/init.d/banip [command] @@ -110,7 +112,8 @@ Available commands: disable Disable service autostart enabled Check if service is started on boot report [text|json|mail] Print banIP related set statistics - search [|] Check if an element exists in the banIP sets + search [|] Check if an element exists in a banIP set + survey [] List all elements of a given banIP set running Check if service is running status Service status trace Start with syscall trace @@ -135,6 +138,7 @@ Available commands: | ban_autoallowlist | option | 1 | add wan IPs/subnets automatically to the local allowlist | | ban_autoblocklist | option | 1 | add suspicious attacker IPs automatically to the local blocklist | | ban_allowlistonly | option | 0 | restrict the internet access from/to a small number of secure websites/IPs | +| ban_basedir | option | /tmp | base working directory while banIP processing | | ban_reportdir | option | /tmp/banIP-report | directory where banIP stores the report files | | ban_backupdir | option | /tmp/banIP-backup | directory where banIP stores the compressed backup files | | ban_protov4 | option | - / autodetect | enable IPv4 support | @@ -147,8 +151,10 @@ Available commands: | ban_deduplicate | option | 1 | deduplicate IP addresses across all active sets | | ban_splitsize | option | 0 | split ext. sets after every n lines/members (saves RAM) | | ban_cores | option | - / autodetect | limit the cpu cores used by banIP (saves RAM) | +| ban_nftloglevel | option | warn | nft loglevel, values: emerg, alert, crit, err, warn, notice, info, debug, audit | +| ban_nftpriority | option | -200 | nft priority for the banIP table (default is the prerouting table priority) | +| ban_nftpolicy | option | memory | nft policy for banIP-related sets, values: memory, performance | | ban_nftexpiry | option | - | expiry time for auto added blocklist members, e.g. '5m', '2h' or '1d' | -| ban_nftpriority | option | -200 | nft banIP table priority (default is the prerouting table priority) | | ban_feed | list | - | external download feeds, e.g. 'yoyo', 'doh', 'country' or 'talos' (see feed table) | | ban_asn | list | - | ASNs for the 'asn' feed, e.g.'32934' | | ban_country | list | - | country iso codes for the 'country' feed, e.g. 'ru' | @@ -162,6 +168,7 @@ Available commands: | ban_mailsender | option | no-reply@banIP | sender address for banIP related notification E-Mails | | ban_mailtopic | option | banIP notification | topic for banIP related notification E-Mails | | ban_mailprofile | option | ban_notify | mail profile used in 'msmtp' for banIP related notification E-Mails | +| ban_reportelements | option | 1 | list set elements in the report, disable this to speed up the report significantly | | ban_resolver | option | - | external resolver used for DNS lookups | ## Examples @@ -216,19 +223,19 @@ Available commands: ``` ~# /etc/init.d/banip status ::: banIP runtime information - + status : active - + version : 0.8.1-2 - + element_count : 206644 - + active_feeds : allowlistvMAC, allowlistv4, allowlistv6, torv4, torv6, countryv6, countryv4, dohv4, dohv6, firehol1v4, deblv4, deblv6, - adguardv6, adguardv4, adguardtrackersv6, adguardtrackersv4, adawayv6, adawayv4, oisdsmallv6, oisdsmallv4, stevenblack - v6, stevenblackv4, yoyov6, yoyov4, antipopadsv4, urlhausv4, antipopadsv6, blocklistvMAC, blocklistv4, blocklistv6 - + active_devices : eth2 - + active_interfaces : wan, wan6 - + active_subnets : 91.61.199.218/24, 2a02:910c:0:80:e542:4b0c:846d:1d33/128 - + run_info : base_dir: /tmp, backup_dir: /mnt/data/banIP-backup, report_dir: /mnt/data/banIP-report, feed_file: /etc/banip/banip.feeds - + run_flags : proto (4/6): ✔/✔, log (wan-inp/wan-fwd/lan-fwd): ✔/✔/✔, deduplicate: ✔, split: ✘, allowed only: ✘ - + last_run : action: restart, duration: 1m 6s, date: 2023-02-25 08:55:55 - + system_info : cores: 2, memory: 1826, device: Turris Omnia, OpenWrt SNAPSHOT r22125-52ddb38469 + + status : active (nft: ✔, monitor: ✔) + + version : 0.8.2-2 + + element_count : 211397 + + active_feeds : allowlistvMAC, allowlistv4, allowlistv6, adawayv4, adawayv6, adguardv4, adguardtrackersv4, adguardv6, adguardtrackersv + 6, antipopadsv4, antipopadsv6, cinsscorev4, countryv6, countryv4, deblv4, deblv6, dohv4, dohv6, firehol1v4, oisdsmallv + 6, oisdsmallv4, stevenblackv6, stevenblackv4, webclientv4, blocklistvMAC, blocklistv4, blocklistv6 + + active_devices : eth2 ::: wan, wan6 + + active_subnets : 91.64.148.211/24, 2b02:710c:0:80:e442:4b0c:637d:1d33/128 + + nft_info : priority: -200, policy: memory, loglevel: warn, expiry: - + + run_info : base: /mnt/data/banIP, backup: /mnt/data/banIP/backup, report: /mnt/data/banIP/report, feed: /etc/banip/banip.feeds + + run_flags : auto: ✔, proto (4/6): ✔/✔, log (wan-inp/wan-fwd/lan-fwd): ✔/✔/✔, dedup: ✔, split: ✘, allowed only: ✘ + + last_run : action: restart, duration: 0m 55s, date: 2023-03-10 19:33:08 + + system_info : cores: 2, memory: 1830, device: Turris Omnia, OpenWrt SNAPSHOT r22248-bf055fcdca ``` **banIP search information** @@ -237,9 +244,43 @@ Available commands: ::: ::: banIP Search ::: - Looking for IP 221.228.105.173 on 2023-02-08 22:12:48 + Looking for IP '221.228.105.173' on 2023-02-08 22:12:48 --- - IP found in set oisdbasicv4 + IP found in Set 'oisdbasicv4' +``` + +**banIP survey information** +``` +~# /etc/init.d/banip survey cinsscorev4 +::: +::: banIP Survey +::: + List the elements of Set 'cinsscorev4' on 2023-03-06 14:07:58 + --- +1.10.187.179 +1.10.203.30 +1.10.255.58 +1.11.67.53 +1.11.114.211 +1.11.208.29 +1.12.75.87 +1.12.231.227 +1.12.247.134 +1.12.251.141 +1.14.96.156 +1.14.250.37 +1.15.40.79 +1.15.71.140 +1.15.77.237 +[...] +``` +**default regex for logfile parsing** +``` +list ban_logterm 'Exit before auth from' +list ban_logterm 'luci: failed login' +list ban_logterm 'error: maximum authentication attempts exceeded' +list ban_logterm 'sshd.*Connection closed by.*\[preauth\]' +list ban_logterm 'SecurityEvent=\"InvalidAccountID\".*RemoteAddress=' ``` **allow-/blocklist handling** @@ -257,15 +298,16 @@ banIP only supports logfile scanning via logread, so to monitor attacks on Aster **tweaks for low memory systems** nftables supports the atomic loading of rules/sets/members, which is cool but unfortunately is also very memory intensive. To reduce the memory pressure on low memory systems (i.e. those with 256-512Mb RAM), you should optimize your configuration with the following options: - * point 'ban_reportdir' and 'ban_backupdir' to an external usb drive + * point 'ban_basedir', 'ban_reportdir' and 'ban_backupdir' to an external usb drive * set 'ban_cores' to '1' (only useful on a multicore system) to force sequential feed processing * set 'ban_splitsize' e.g. to '1000' to split the load of an external set after every 1000 lines/members + * set 'ban_reportelements' to '0' to disable the CPU intensive counting of set elements **tweak the download options** By default banIP uses the following pre-configured download options: ``` * aria2c: --timeout=20 --allow-overwrite=true --auto-file-renaming=false --log-level=warn --dir=/ -o - * curl: --connect-timeout 20 --silent --show-error --location -o + * curl: --connect-timeout 20 --fail --silent --show-error --location -o * uclient-fetch: --timeout=20 -O * wget: --no-cache --no-cookies --max-redirect=0 --timeout=20 -O ``` diff --git a/net/banip/files/banip-functions.sh b/net/banip/files/banip-functions.sh index 179d5678a2..6e231a6524 100644 --- a/net/banip/files/banip-functions.sh +++ b/net/banip/files/banip-functions.sh @@ -11,13 +11,15 @@ export LC_ALL=C export PATH="/usr/sbin:/usr/bin:/sbin:/bin" ban_basedir="/tmp" -ban_backupdir="${ban_basedir}/banIP-backup" -ban_reportdir="${ban_basedir}/banIP-report" +ban_backupdir="/tmp/banIP-backup" +ban_reportdir="/tmp/banIP-report" ban_feedfile="/etc/banip/banip.feeds" +ban_allowlist="/etc/banip/banip.allowlist" +ban_blocklist="/etc/banip/banip.blocklist" +ban_mailtemplate="/etc/banip/banip.tpl" ban_pidfile="/var/run/banip.pid" +ban_rtfile="/var/run/banip_runtime.json" ban_lock="/var/run/banip.lock" -ban_blocklist="/etc/banip/banip.blocklist" -ban_allowlist="/etc/banip/banip.allowlist" ban_fetchcmd="" ban_logreadcmd="$(command -v logread)" ban_logcmd="$(command -v logger)" @@ -32,10 +34,11 @@ ban_mailsender="no-reply@banIP" ban_mailreceiver="" ban_mailtopic="banIP notification" ban_mailprofile="ban_notify" -ban_mailtemplate="/etc/banip/banip.tpl" +ban_reportelements="1" +ban_nftloglevel="warn" ban_nftpriority="-200" +ban_nftpolicy="memory" ban_nftexpiry="" -ban_loglevel="warn" ban_loglimit="100" ban_logcount="1" ban_logterm="" @@ -49,7 +52,7 @@ ban_autoallowlist="1" ban_autoblocklist="1" ban_deduplicate="1" ban_splitsize="0" -ban_autodetect="" +ban_autodetect="1" ban_feed="" ban_blockinput="" ban_blockforwardwan="" @@ -281,93 +284,133 @@ f_rmpid() { : >"${ban_pidfile}" } +# get nft/monitor actuals +# +f_actual() { + local nft monitor + + if "${ban_nftcmd}" -t list set inet banIP allowlistvMAC >/dev/null 2>&1; then + nft="$(f_char "1")" + else + nft="$(f_char "0")" + fi + if pgrep -f "logread" -P "$(cat "${ban_pidfile}" 2>/dev/null)" >/dev/null 2>&1; then + monitor="$(f_char "1")" + else + monitor="$(f_char "0")" + fi + printf "%s" "nft: ${nft}, monitor: ${monitor}" +} + # get wan interfaces # f_getif() { - local iface + local iface update="0" - "${ban_ubuscmd}" -t 5 wait_for network.device network.interface 2>/dev/null if [ "${ban_autodetect}" = "1" ]; then if [ -z "${ban_ifv4}" ]; then + network_flush_cache network_find_wan iface - if [ -n "${iface}" ] && ! printf "%s" "${ban_ifv4}" | "${ban_grepcmd}" -q "${iface}"; then + if [ -n "${iface}" ] && "${ban_ubuscmd}" -t 10 wait_for network.interface."${iface}" >/dev/null 2>&1; then ban_protov4="1" - ban_ifv4="${ban_ifv4}${iface} " + ban_ifv4="${iface}" uci_set banip global ban_protov4 "1" uci_add_list banip global ban_ifv4 "${iface}" + f_log "info" "added IPv4 interface '${iface}' to config" fi fi if [ -z "${ban_ifv6}" ]; then + network_flush_cache network_find_wan6 iface - if [ -n "${iface}" ] && ! printf "%s" "${ban_ifv6}" | "${ban_grepcmd}" -q "${iface}"; then + if [ -n "${iface}" ] && "${ban_ubuscmd}" -t 10 wait_for network.interface."${iface}" >/dev/null 2>&1; then ban_protov6="1" - ban_ifv6="${ban_ifv6}${iface} " + ban_ifv6="${iface}" uci_set banip global ban_protov6 "1" uci_add_list banip global ban_ifv6 "${iface}" + f_log "info" "added IPv6 interface '${iface}' to config" fi fi + fi + if [ -n "$(uci -q changes "banip")" ]; then + update="1" + uci_commit "banip" + else ban_ifv4="${ban_ifv4%%?}" ban_ifv6="${ban_ifv6%%?}" - [ -n "$(uci -q changes "banip")" ] && uci_commit "banip" + for iface in ${ban_ifv4} ${ban_ifv6}; do + if ! "${ban_ubuscmd}" -t 10 wait_for network.interface."${iface}" >/dev/null 2>&1; then + f_log "err" "wan interface '${iface}' is not available, please check your configuration" + fi + done fi [ -z "${ban_ifv4}" ] && [ -z "${ban_ifv6}" ] && f_log "err" "wan interfaces not found, please check your configuration" - f_log "debug" "f_getif ::: auto_detect: ${ban_autodetect}, interfaces (4/6): ${ban_ifv4}/${ban_ifv6}, protocols (4/6): ${ban_protov4}/${ban_protov6}" + f_log "debug" "f_getif ::: auto/update: ${ban_autodetect}/${update}, interfaces (4/6): ${ban_ifv4}/${ban_ifv6}, protocols (4/6): ${ban_protov4}/${ban_protov6}" } # get wan devices # f_getdev() { - local dev iface + local dev iface update="0" cnt="0" cnt_max="10" - if [ "${ban_autodetect}" = "1" ] && [ -z "${ban_dev}" ]; then - for iface in ${ban_ifv4} ${ban_ifv6}; do - network_get_device dev "${iface}" - if [ -n "${dev}" ] && ! printf "%s" "${ban_dev}" | "${ban_grepcmd}" -q "${dev}"; then - ban_dev="${ban_dev}${dev} " - uci_add_list banip global ban_dev "${dev}" - else - network_get_physdev dev "${iface}" - if [ -n "${dev}" ] && ! printf "%s" "${ban_dev}" | "${ban_grepcmd}" -q "${dev}"; then - ban_dev="${ban_dev}${dev} " - uci_add_list banip global ban_dev "${dev}" + if [ "${ban_autodetect}" = "1" ]; then + while [ -z "${ban_dev}" ] && [ "${cnt}" -le "${cnt_max}" ]; do + network_flush_cache + for iface in ${ban_ifv4} ${ban_ifv6}; do + network_get_device dev "${iface}" + if [ -n "${dev}" ]; then + if printf "%s" "${dev}" | "${ban_grepcmd}" -qE "pppoe|6in4"; then + dev="${iface}" + fi + if ! printf " %s " "${ban_dev}" | "${ban_grepcmd}" -q " ${dev} "; then + ban_dev="${ban_dev}${dev} " + uci_add_list banip global ban_dev "${dev}" + f_log "info" "added device '${dev}' to config" + fi fi - fi + done + cnt="$((cnt + 1))" + sleep 1 done - ban_dev="${ban_dev%%?}" - [ -n "$(uci -q changes "banip")" ] && uci_commit "banip" fi + if [ -n "$(uci -q changes "banip")" ]; then + update="1" + uci_commit "banip" + fi + ban_dev="${ban_dev%%?}" [ -z "${ban_dev}" ] && f_log "err" "wan devices not found, please check your configuration" - f_log "debug" "f_getdev ::: auto_detect: ${ban_autodetect}, devices: ${ban_dev}" + f_log "debug" "f_getdev ::: auto/update: ${ban_autodetect}/${update}, devices: ${ban_dev}, cnt: ${cnt}" } # get local subnets # f_getsub() { - local sub iface ip + local sub iface ip update="0" - for iface in ${ban_ifv4} ${ban_ifv6}; do - network_get_subnet sub "${iface}" - if [ -n "${sub}" ] && ! printf "%s" "${ban_sub}" | "${ban_grepcmd}" -q "${sub}"; then - ban_sub="${ban_sub} ${sub}" - fi - network_get_subnet6 sub "${iface}" - if [ -n "${sub}" ] && ! printf "%s" "${ban_sub}" | "${ban_grepcmd}" -q "${sub}"; then - ban_sub="${ban_sub} ${sub}" - fi - done if [ "${ban_autoallowlist}" = "1" ]; then + for iface in ${ban_ifv4} ${ban_ifv6}; do + network_flush_cache + network_get_subnet sub "${iface}" + if [ -n "${sub}" ] && ! printf " %s " "${ban_sub}" | "${ban_grepcmd}" -q " ${sub} "; then + ban_sub="${ban_sub}${sub} " + fi + network_get_subnet6 sub "${iface}" + if [ -n "${sub}" ] && ! printf " %s " "${ban_sub}" | "${ban_grepcmd}" -q " ${sub} "; then + ban_sub="${ban_sub}${sub} " + fi + done for ip in ${ban_sub}; do if ! "${ban_grepcmd}" -q "${ip}" "${ban_allowlist}"; then - printf "%-42s%s\n" "${ip}" "added on $(date "+%Y-%m-%d %H:%M:%S")" >>"${ban_allowlist}" - f_log "info" "add subnet '${ip}' to local allowlist" + update="1" + printf "%-42s%s\n" "${ip}" "# subnet added on $(date "+%Y-%m-%d %H:%M:%S")" >>"${ban_allowlist}" + f_log "info" "added subnet '${ip}' to local allowlist" fi done + ban_sub="${ban_sub%%?}" fi - [ -z "${ban_sub}" ] && f_log "err" "wan subnet(s) not found, please check your configuration" - f_log "debug" "f_getsub ::: auto_allowlist: ${ban_autoallowlist}, subnet(s): ${ban_sub:-"-"}" + f_log "debug" "f_getsub ::: auto/update: ${ban_autoallowlist}/${update}, subnet(s): ${ban_sub:-"-"}" } # get set elements @@ -387,7 +430,7 @@ f_nftinit() { # nft header (tables and chains) # printf "%s\n\n" "#!/usr/sbin/nft -f" - if "${ban_nftcmd}" -t list table inet banIP >/dev/null 2>&1; then + if "${ban_nftcmd}" -t list set inet banIP allowlistvMAC >/dev/null 2>&1; then printf "%s\n" "delete table inet banIP" fi printf "%s\n" "add table inet banIP" @@ -422,12 +465,14 @@ f_nftinit() { feed_log="$("${ban_nftcmd}" -f "${file}" 2>&1)" feed_rc="${?}" - f_log "debug" "f_nftinit ::: devices: ${ban_dev}, priority: ${ban_nftpriority}, rc: ${feed_rc:-"-"}, log: ${feed_log:-"-"}" + f_log "debug" "f_nftinit ::: devices: ${ban_dev}, priority: ${ban_nftpriority}, policy: ${ban_nftpolicy}, loglevel: ${ban_nftloglevel}, rc: ${feed_rc:-"-"}, log: ${feed_log:-"-"}" return ${feed_rc} } +# handle downloads +# f_down() { - local log_input log_forwardwan log_forwardlan start_ts end_ts tmp_raw tmp_load tmp_file split_file input_handles forwardwan_handles forwardlan_handles handle + local log_input log_forwardwan log_forwardlan start_ts end_ts tmp_raw tmp_load tmp_file split_file ruleset_raw handle local cnt_set cnt_dl restore_rc feed_direction feed_rc feed_log feed="${1}" proto="${2}" feed_url="${3}" feed_rule="${4}" feed_flag="${5}" start_ts="$(date +%s)" @@ -439,9 +484,9 @@ f_down() { tmp_flush="${ban_tmpfile}.${feed}.flush" tmp_nft="${ban_tmpfile}.${feed}.nft" - [ "${ban_loginput}" = "1" ] && log_input="log level ${ban_loglevel} prefix \"banIP/inp-wan/drp/${feed}: \"" - [ "${ban_logforwardwan}" = "1" ] && log_forwardwan="log level ${ban_loglevel} prefix \"banIP/fwd-wan/drp/${feed}: \"" - [ "${ban_logforwardlan}" = "1" ] && log_forwardlan="log level ${ban_loglevel} prefix \"banIP/fwd-lan/rej/${feed}: \"" + [ "${ban_loginput}" = "1" ] && log_input="log level ${ban_nftloglevel} prefix \"banIP/inp-wan/drp/${feed}: \"" + [ "${ban_logforwardwan}" = "1" ] && log_forwardwan="log level ${ban_nftloglevel} prefix \"banIP/fwd-wan/drp/${feed}: \"" + [ "${ban_logforwardlan}" = "1" ] && log_forwardlan="log level ${ban_nftloglevel} prefix \"banIP/fwd-lan/rej/${feed}: \"" # set source block direction # @@ -458,16 +503,14 @@ f_down() { # chain/rule maintenance # if [ "${ban_action}" = "reload" ] && "${ban_nftcmd}" -t list set inet banIP "${feed}" >/dev/null 2>&1; then - input_handles="$("${ban_nftcmd}" -t --handle --numeric list chain inet banIP wan-input 2>/dev/null)" - forwardwan_handles="$("${ban_nftcmd}" -t --handle --numeric list chain inet banIP wan-forward 2>/dev/null)" - forwardlan_handles="$("${ban_nftcmd}" -t --handle --numeric list chain inet banIP lan-forward 2>/dev/null)" + ruleset_raw="$("${ban_nftcmd}" -tj list ruleset 2>/dev/null)" { printf "%s\n" "flush set inet banIP ${feed}" - handle="$(printf "%s\n" "${input_handles}" | "${ban_awkcmd}" "/@${feed} /{print \$NF}")" + handle="$(printf "%s\n" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"wan-input\"][@.expr[0].match.right=\"@${feed}\"].handle")" [ -n "${handle}" ] && printf "%s\n" "delete rule inet banIP wan-input handle ${handle}" - handle="$(printf "%s\n" "${forwardwan_handles}" | "${ban_awkcmd}" "/@${feed} /{print \$NF}")" + handle="$(printf "%s\n" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"wan-forward\"][@.expr[0].match.right=\"@${feed}\"].handle")" [ -n "${handle}" ] && printf "%s\n" "delete rule inet banIP wan-forward handle ${handle}" - handle="$(printf "%s\n" "${forwardlan_handles}" | "${ban_awkcmd}" "/@${feed} /{print \$NF}")" + handle="$(printf "%s\n" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"lan-forward\"][@.expr[0].match.right=\"@${feed}\"].handle")" [ -n "${handle}" ] && printf "%s\n" "delete rule inet banIP lan-forward handle ${handle}" } >"${tmp_flush}" fi @@ -488,11 +531,11 @@ f_down() { [ -s "${tmp_flush}" ] && cat "${tmp_flush}" if [ "${proto}" = "MAC" ]; then "${ban_awkcmd}" '/^([0-9A-f]{2}:){5}[0-9A-f]{2}([[:space:]]|$)/{printf "%s, ",tolower($1)}' "${ban_allowlist}" >"${tmp_file}" - printf "%s\n" "add set inet banIP ${feed} { type ether_addr; policy memory; $(f_getelements "${tmp_file}") }" + printf "%s\n" "add set inet banIP ${feed} { type ether_addr; policy ${ban_nftpolicy}; $(f_getelements "${tmp_file}") }" [ -z "${feed_direction##*forwardlan*}" ] && printf "%s\n" "add rule inet banIP lan-forward ether saddr @${feed} counter accept" elif [ "${proto}" = "4" ]; then "${ban_awkcmd}" '/^(([0-9]{1,3}\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])(\/(1?[0-9]|2?[0-9]|3?[0-2]))?)([[:space:]]|$)/{printf "%s, ",$1}' "${ban_allowlist}" >"${tmp_file}" - printf "%s\n" "add set inet banIP ${feed} { type ipv4_addr; flags interval; auto-merge; policy memory; $(f_getelements "${tmp_file}") }" + printf "%s\n" "add set inet banIP ${feed} { type ipv4_addr; flags interval; auto-merge; policy ${ban_nftpolicy}; $(f_getelements "${tmp_file}") }" if [ -z "${feed_direction##*input*}" ]; then if [ "${ban_allowlistonly}" = "1" ]; then printf "%s\n" "add rule inet banIP wan-input ip saddr != @${feed} ${log_input} counter drop" @@ -517,7 +560,7 @@ f_down() { elif [ "${proto}" = "6" ]; then "${ban_awkcmd}" '!/^([0-9A-f]{2}:){5}[0-9A-f]{2}([[:space:]]|$)/{printf "%s\n",$1}' "${ban_allowlist}" | "${ban_awkcmd}" '/^(([0-9A-f]{0,4}:){1,7}[0-9A-f]{0,4}:?(\/(1?[0-2][0-8]|[0-9][0-9]))?)([[:space:]]|$)/{printf "%s, ",tolower($1)}' >"${tmp_file}" - printf "%s\n" "add set inet banIP ${feed} { type ipv6_addr; flags interval; auto-merge; policy memory; $(f_getelements "${tmp_file}") }" + printf "%s\n" "add set inet banIP ${feed} { type ipv6_addr; flags interval; auto-merge; policy ${ban_nftpolicy}; $(f_getelements "${tmp_file}") }" if [ -z "${feed_direction##*input*}" ]; then if [ "${ban_allowlistonly}" = "1" ]; then printf "%s\n" "add rule inet banIP wan-input ip6 saddr != @${feed} ${log_input} counter drop" @@ -548,7 +591,7 @@ f_down() { [ -s "${tmp_flush}" ] && cat "${tmp_flush}" if [ "${proto}" = "MAC" ]; then "${ban_awkcmd}" '/^([0-9A-f]{2}:){5}[0-9A-f]{2}([[:space:]]|$)/{printf "%s, ",tolower($1)}' "${ban_blocklist}" >"${tmp_file}" - printf "%s\n" "add set inet banIP ${feed} { type ether_addr; policy memory; $(f_getelements "${tmp_file}") }" + printf "%s\n" "add set inet banIP ${feed} { type ether_addr; policy ${ban_nftpolicy}; $(f_getelements "${tmp_file}") }" [ -z "${feed_direction##*forwardlan*}" ] && printf "%s\n" "add rule inet banIP lan-forward ether saddr @${feed} ${log_forwardlan} counter reject" elif [ "${proto}" = "4" ]; then if [ "${ban_deduplicate}" = "1" ]; then @@ -560,7 +603,7 @@ f_down() { "${ban_awkcmd}" '/^(([0-9]{1,3}\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])(\/(1?[0-9]|2?[0-9]|3?[0-2]))?)([[:space:]]|$)/{printf "%s,\n",$1}' "${ban_blocklist}" >"${tmp_split}" fi "${ban_awkcmd}" '{ORS=" ";print}' "${tmp_split}" 2>/dev/null >"${tmp_file}" - printf "%s\n" "add set inet banIP ${feed} { type ipv4_addr; flags interval, timeout; auto-merge; policy memory; $(f_getelements "${tmp_file}") }" + printf "%s\n" "add set inet banIP ${feed} { type ipv4_addr; flags interval, timeout; auto-merge; policy ${ban_nftpolicy}; $(f_getelements "${tmp_file}") }" [ -z "${feed_direction##*input*}" ] && printf "%s\n" "add rule inet banIP wan-input ip saddr @${feed} ${log_input} counter drop" [ -z "${feed_direction##*forwardwan*}" ] && printf "%s\n" "add rule inet banIP wan-forward ip saddr @${feed} ${log_forwardwan} counter drop" [ -z "${feed_direction##*forwardlan*}" ] && printf "%s\n" "add rule inet banIP lan-forward ip daddr @${feed} ${log_forwardlan} counter reject with icmp type admin-prohibited" @@ -576,7 +619,7 @@ f_down() { "${ban_awkcmd}" '/^(([0-9A-f]{0,4}:){1,7}[0-9A-f]{0,4}:?(\/(1?[0-2][0-8]|[0-9][0-9]))?)([[:space:]]|$)/{printf "%s,\n",tolower($1)}' >"${tmp_split}" fi "${ban_awkcmd}" '{ORS=" ";print}' "${tmp_split}" 2>/dev/null >"${tmp_file}" - printf "%s\n" "add set inet banIP ${feed} { type ipv6_addr; flags interval, timeout; auto-merge; policy memory; $(f_getelements "${tmp_file}") }" + printf "%s\n" "add set inet banIP ${feed} { type ipv6_addr; flags interval, timeout; auto-merge; policy ${ban_nftpolicy}; $(f_getelements "${tmp_file}") }" [ -z "${feed_direction##*input*}" ] && printf "%s\n" "add rule inet banIP wan-input ip6 saddr @${feed} ${log_input} counter drop" [ -z "${feed_direction##*forwardwan*}" ] && printf "%s\n" "add rule inet banIP wan-forward ip6 saddr @${feed} ${log_forwardwan} counter drop" [ -z "${feed_direction##*forwardlan*}" ] && printf "%s\n" "add rule inet banIP lan-forward ip6 daddr @${feed} ${log_forwardlan} counter reject with icmpv6 type admin-prohibited" @@ -671,7 +714,7 @@ f_down() { # printf "%s\n\n" "#!/usr/sbin/nft -f" [ -s "${tmp_flush}" ] && cat "${tmp_flush}" - printf "%s\n" "add set inet banIP ${feed} { type ipv4_addr; flags interval; auto-merge; policy memory; $(f_getelements "${tmp_file}.1") }" + printf "%s\n" "add set inet banIP ${feed} { type ipv4_addr; flags interval; auto-merge; policy ${ban_nftpolicy}; $(f_getelements "${tmp_file}.1") }" # input and forward rules # @@ -685,7 +728,7 @@ f_down() { # printf "%s\n\n" "#!/usr/sbin/nft -f" [ -s "${tmp_flush}" ] && cat "${tmp_flush}" - printf "%s\n" "add set inet banIP ${feed} { type ipv6_addr; flags interval; auto-merge; policy memory; $(f_getelements "${tmp_file}.1") }" + printf "%s\n" "add set inet banIP ${feed} { type ipv6_addr; flags interval; auto-merge; policy ${ban_nftpolicy}; $(f_getelements "${tmp_file}.1") }" # input and forward rules # @@ -717,7 +760,9 @@ f_down() { fi rm -f "${split_file}" done - cnt_set="$("${ban_nftcmd}" -j list set inet banIP "${feed}" 2>/dev/null | jsonfilter -qe '@.nftables[*].set.elem[*]' | wc -l 2>/dev/null)" + if [ "${ban_debug}" = "1" ] && [ "${ban_reportelements}" = "1" ]; then + cnt_set="$("${ban_nftcmd}" -j list set inet banIP "${feed}" 2>/dev/null | jsonfilter -qe '@.nftables[*].set.elem[*]' | wc -l 2>/dev/null)" + fi fi else f_log "info" "empty feed ${feed} will be skipped" @@ -760,44 +805,43 @@ f_restore() { # remove disabled feeds # f_rmset() { - local tmp_del table_sets input_handles forwardwan_handles forwardlan_handles handle sets feed feed_log feed_rc + local tmp_del ruleset_raw table_sets handle set del_set feed_log feed_rc tmp_del="${ban_tmpfile}.final.delete" - table_sets="$("${ban_nftcmd}" -t list table inet banIP 2>/dev/null | "${ban_awkcmd}" '/^[[:space:]]+set [[:alnum:]]+ /{printf "%s ",$2}' 2>/dev/null)" - input_handles="$("${ban_nftcmd}" -t --handle --numeric list chain inet banIP wan-input 2>/dev/null)" - forwardwan_handles="$("${ban_nftcmd}" -t --handle --numeric list chain inet banIP wan-forward 2>/dev/null)" - forwardlan_handles="$("${ban_nftcmd}" -t --handle --numeric list chain inet banIP lan-forward 2>/dev/null)" + ruleset_raw="$("${ban_nftcmd}" -tj list ruleset 2>/dev/null)" + table_sets="$(printf "%s\n" "${ruleset_raw}" | jsonfilter -qe '@.nftables[@.set.table="banIP"].set.name')" { printf "%s\n\n" "#!/usr/sbin/nft -f" - for feed in ${table_sets}; do - if ! printf "%s" "allowlist blocklist ${ban_feed}" | "${ban_grepcmd}" -q "${feed%v*}"; then - sets="${sets}${feed}/" - rm -f "${ban_backupdir}/banIP.${feed}.gz" - printf "%s\n" "flush set inet banIP ${feed}" - handle="$(printf "%s\n" "${input_handles}" | "${ban_awkcmd}" "/@${feed} /{print \$NF}" 2>/dev/null)" + for set in ${table_sets}; do + if ! printf "%s" "allowlist blocklist ${ban_feed}" | "${ban_grepcmd}" -q "${set%v*}"; then + del_set="${del_set}${set}, " + rm -f "${ban_backupdir}/banIP.${set}.gz" + printf "%s\n" "flush set inet banIP ${set}" + handle="$(printf "%s\n" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"wan-input\"][@.expr[0].match.right=\"@${set}\"].handle")" [ -n "${handle}" ] && printf "%s\n" "delete rule inet banIP wan-input handle ${handle}" - handle="$(printf "%s\n" "${forwardwan_handles}" | "${ban_awkcmd}" "/@${feed} /{print \$NF}" 2>/dev/null)" + handle="$(printf "%s\n" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"wan-forward\"][@.expr[0].match.right=\"@${set}\"].handle")" [ -n "${handle}" ] && printf "%s\n" "delete rule inet banIP wan-forward handle ${handle}" - handle="$(printf "%s\n" "${forwardlan_handles}" | "${ban_awkcmd}" "/@${feed} /{print \$NF}" 2>/dev/null)" + handle="$(printf "%s\n" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"lan-forward\"][@.expr[0].match.right=\"@${set}\"].handle")" [ -n "${handle}" ] && printf "%s\n" "delete rule inet banIP lan-forward handle ${handle}" - printf "%s\n\n" "delete set inet banIP ${feed}" + printf "%s\n\n" "delete set inet banIP ${set}" fi done } >"${tmp_del}" - if [ -n "${sets}" ]; then + if [ -n "${del_set}" ]; then + del_set="${del_set%%??}" feed_log="$("${ban_nftcmd}" -f "${tmp_del}" 2>&1)" feed_rc="${?}" fi rm -f "${tmp_del}" - f_log "debug" "f_rmset ::: sets: ${sets:-"-"}, tmp: ${tmp_del}, rc: ${feed_rc:-"-"}, log: ${feed_log:-"-"}" + f_log "debug" "f_rmset ::: sets: ${del_set:-"-"}, rc: ${feed_rc:-"-"}, log: ${feed_log:-"-"}" } # generate status information # f_genstatus() { - local object duration nft_table nft_feeds cnt_elements="0" split="0" status="${1}" + local object duration set table_sets cnt_elements="0" split="0" status="${1}" [ -z "${ban_dev}" ] && f_conf if [ "${status}" = "active" ]; then @@ -805,19 +849,20 @@ f_genstatus() { ban_endtime="$(date "+%s")" duration="$(((ban_endtime - ban_starttime) / 60))m $(((ban_endtime - ban_starttime) % 60))s" fi - nft_table="$("${ban_nftcmd}" -t list table inet banIP 2>/dev/null)" - nft_feeds="$(f_trim "$(printf "%s\n" "${nft_table}" | "${ban_awkcmd}" '/^[[:space:]]+set [[:alnum:]]+ /{printf "%s ",$2}')")" - for object in ${nft_feeds}; do - cnt_elements="$((cnt_elements + $("${ban_nftcmd}" -j list set inet banIP "${object}" 2>/dev/null | jsonfilter -qe '@.nftables[*].set.elem[*]' | wc -l 2>/dev/null)))" - done + table_sets="$("${ban_nftcmd}" -tj list ruleset 2>/dev/null | jsonfilter -qe '@.nftables[@.set.table="banIP"].set.name')" + if [ "${ban_reportelements}" = "1" ]; then + for set in ${table_sets}; do + cnt_elements="$((cnt_elements + $("${ban_nftcmd}" -j list set inet banIP "${set}" 2>/dev/null | jsonfilter -qe '@.nftables[*].set.elem[*]' | wc -l 2>/dev/null)))" + done + fi runtime="action: ${ban_action:-"-"}, duration: ${duration:-"-"}, date: $(date "+%Y-%m-%d %H:%M:%S")" fi f_system [ ${ban_splitsize:-"0"} -gt "0" ] && split="1" - : >"${ban_basedir}/ban_runtime.json" + : >"${ban_rtfile}" json_init - json_load_file "${ban_basedir}/ban_runtime.json" >/dev/null 2>&1 + json_load_file "${ban_rtfile}" >/dev/null 2>&1 json_add_string "status" "${status}" json_add_string "version" "${ban_ver}" json_add_string "element_count" "${cnt_elements}" @@ -827,7 +872,7 @@ f_genstatus() { json_add_string "feed" "-" json_close_object else - for object in ${nft_feeds}; do + for object in ${table_sets}; do json_add_object json_add_string "feed" "${object}" json_close_object @@ -845,14 +890,6 @@ f_genstatus() { json_add_string "device" "${object}" json_close_object done - fi - json_close_array - json_add_array "active_interfaces" - if [ "${status}" != "active" ]; then - json_add_object - json_add_string "interface" "-" - json_close_object - else for object in ${ban_ifv4} ${ban_ifv6}; do json_add_object json_add_string "interface" "${object}" @@ -873,42 +910,66 @@ f_genstatus() { done fi json_close_array + json_add_string "nft_info" "priority: ${ban_nftpriority}, policy: ${ban_nftpolicy}, loglevel: ${ban_nftloglevel}, expiry: ${ban_nftexpiry:-"-"}" json_add_string "run_info" "base: ${ban_basedir}, backup: ${ban_backupdir}, report: ${ban_reportdir}, feed: ${ban_feedfile}" - json_add_string "run_flags" "protocol (4/6): $(f_char ${ban_protov4})/$(f_char ${ban_protov6}), log (wan-inp/wan-fwd/lan-fwd): $(f_char ${ban_loginput})/$(f_char ${ban_logforwardwan})/$(f_char ${ban_logforwardlan}), deduplicate: $(f_char ${ban_deduplicate}), split: $(f_char ${split}), allowed only: $(f_char ${ban_allowlistonly})" + json_add_string "run_flags" "auto: $(f_char ${ban_autodetect}), proto (4/6): $(f_char ${ban_protov4})/$(f_char ${ban_protov6}), log (wan-inp/wan-fwd/lan-fwd): $(f_char ${ban_loginput})/$(f_char ${ban_logforwardwan})/$(f_char ${ban_logforwardlan}), dedup: $(f_char ${ban_deduplicate}), split: $(f_char ${split}), allowed only: $(f_char ${ban_allowlistonly})" json_add_string "last_run" "${runtime:-"-"}" json_add_string "system_info" "cores: ${ban_cores}, memory: ${ban_memory}, device: ${ban_sysver}" - json_dump >"${ban_basedir}/ban_runtime.json" + json_dump >"${ban_rtfile}" } # get status information # f_getstatus() { - local key keylist type value index_value + local key keylist type value index_key1 index_key2 index_value1 index_value2 actual="${1}" [ -z "${ban_dev}" ] && f_conf - json_load_file "${ban_basedir}/ban_runtime.json" >/dev/null 2>&1 + json_load_file "${ban_rtfile}" >/dev/null 2>&1 if json_get_keys keylist; then printf "%s\n" "::: banIP runtime information" for key in ${keylist}; do json_get_var value "${key}" >/dev/null 2>&1 - if [ "${key%_*}" = "active" ]; then + if [ "${key}" = "status" ]; then + value="${value} ($(f_actual))" + elif [ "${key}" = "active_devices" ]; then + json_select "${key}" >/dev/null 2>&1 + index=1 + while json_get_type type "${index}" && [ "${type}" = "object" ]; do + json_get_keys index_key1 "${index}" >/dev/null 2>&1 + json_get_keys index_key2 "$((index + 1))" >/dev/null 2>&1 + json_get_values index_value1 "${index}" >/dev/null 2>&1 + if [ "${index}" = "1" ] && [ "${index_key1// /}" = "device" ] && [ "${index_key2// /}" = "interface" ]; then + json_get_values index_value2 "$((index + 1))" >/dev/null 2>&1 + value="${index_value1} ::: ${index_value2}" + index="$((index + 1))" + elif [ "${index}" = "1" ]; then + value="${index_value1}" + elif [ "${index}" != "1" ] && [ "${index_key1// /}" = "device" ] && [ "${index_key2// /}" = "interface" ]; then + json_get_values index_value2 "$((index + 1))" >/dev/null 2>&1 + value="${value}, ${index_value1} ::: ${index_value2}" + index="$((index + 1))" + elif [ "${index}" != "1" ]; then + value="${value}, ${index_value1}" + fi + index="$((index + 1))" + done + json_select ".." + elif [ "${key%_*}" = "active" ]; then json_select "${key}" >/dev/null 2>&1 index=1 while json_get_type type "${index}" && [ "${type}" = "object" ]; do - json_get_values index_value "${index}" >/dev/null 2>&1 + json_get_values index_value1 "${index}" >/dev/null 2>&1 if [ "${index}" = "1" ]; then - value="${index_value}" + value="${index_value1}" else - value="${value}, ${index_value}" + value="${value}, ${index_value1}" fi - index=$((index + 1)) + index="$((index + 1))" done json_select ".." fi - value="$( - printf "%s" "${value}" | - awk '{NR=1;max=118;if(length($0)>max+1)while($0){if(NR==1){print substr($0,1,max)}else{printf"%-24s%s\n","",substr($0,1,max)}{$0=substr($0,max+1);NR=NR+1}}else print}' - )" + value="$(printf "%s" "${value}" | + awk '{NR=1;max=118;if(length($0)>max+1)while($0){if(NR==1){print substr($0,1,max)}else{printf"%-24s%s\n","",substr($0,1,max)}{$0=substr($0,max+1);NR=NR+1}}else print}')" printf " + %-17s : %s\n" "${key}" "${value:-"-"}" done else @@ -949,9 +1010,9 @@ f_lookup() { fi fi if [ "${feed}" = "allowlist" ] && [ "${ban_autoallowlist}" = "1" ]; then - printf "%-42s%s\n" "${ip}" "# ip of '${domain}' added on $(date "+%Y-%m-%d %H:%M:%S")" >>"${ban_allowlist}" + printf "%-42s%s\n" "${ip}" "# '${domain}' added on $(date "+%Y-%m-%d %H:%M:%S")" >>"${ban_allowlist}" elif [ "${feed}" = "blocklist" ] && [ "${ban_autoblocklist}" = "1" ]; then - printf "%-42s%s\n" "${ip}" "# ip of '${domain}' added on $(date "+%Y-%m-%d %H:%M:%S")" >>"${ban_blocklist}" + printf "%-42s%s\n" "${ip}" "# '${domain}' added on $(date "+%Y-%m-%d %H:%M:%S")" >>"${ban_blocklist}" fi fi fi @@ -964,10 +1025,10 @@ f_lookup() { f_log "debug" "f_lookup ::: name: ${feed}, cnt_domain: ${cnt_domain}, cnt_ip: ${cnt_ip}, duration: ${duration}" } -# banIP table statistics +# table statistics # f_report() { - local report_jsn report_txt set tmp_val nft_raw nft_sets set_cnt set_input set_forwardwan set_forwardlan set_cntinput set_cntforwardwan set_cntforwardlan output="${1}" + local report_jsn report_txt set tmp_val ruleset_raw table_sets set_cnt set_input set_forwardwan set_forwardlan set_cntinput set_cntforwardwan set_cntforwardlan output="${1}" local detail set_details jsnval timestamp autoadd_allow autoadd_block sum_sets sum_setinput sum_setforwardwan sum_setforwardlan sum_setelements sum_cntinput sum_cntforwardwan sum_cntforwardlan [ -z "${ban_dev}" ] && f_conf @@ -977,8 +1038,8 @@ f_report() { # json output preparation # - nft_raw="$("${ban_nftcmd}" -tj list table inet banIP 2>/dev/null)" - nft_sets="$(printf "%s" "${nft_raw}" | jsonfilter -qe '@.nftables[*].set.name')" + ruleset_raw="$("${ban_nftcmd}" -tj list ruleset 2>/dev/null)" + table_sets="$(printf "%s" "${ruleset_raw}" | jsonfilter -qe '@.nftables[@.set.table="banIP"].set.name')" sum_sets="0" sum_setinput="0" sum_setforwardwan="0" @@ -992,12 +1053,17 @@ f_report() { { printf "%s\n" "{" printf "\t%s\n" '"sets": {' - for set in ${nft_sets}; do - set_cnt="$("${ban_nftcmd}" -j list set inet banIP "${set}" 2>/dev/null | jsonfilter -qe '@.nftables[*].set.elem[*]' | wc -l 2>/dev/null)" - sum_setelements="$((sum_setelements + set_cnt))" - set_cntinput="$(printf "%s" "${nft_raw}" | jsonfilter -qe "@.nftables[@.rule.chain=\"wan-input\"][@.expr[*].match.right=\"@${set}\"].expr[*].counter.packets")" - set_cntforwardwan="$(printf "%s" "${nft_raw}" | jsonfilter -qe "@.nftables[@.rule.chain=\"wan-forward\"][@.expr[*].match.right=\"@${set}\"].expr[*].counter.packets")" - set_cntforwardlan="$(printf "%s" "${nft_raw}" | jsonfilter -qe "@.nftables[@.rule.chain=\"lan-forward\"][@.expr[*].match.right=\"@${set}\"].expr[*].counter.packets")" + for set in ${table_sets}; do + set_cntinput="$(printf "%s" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"wan-input\"][@.expr[0].match.right=\"@${set}\"].expr[*].counter.packets")" + set_cntforwardwan="$(printf "%s" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"wan-forward\"][@.expr[0].match.right=\"@${set}\"].expr[*].counter.packets")" + set_cntforwardlan="$(printf "%s" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"lan-forward\"][@.expr[0].match.right=\"@${set}\"].expr[*].counter.packets")" + if [ "${ban_reportelements}" = "1" ]; then + set_cnt="$("${ban_nftcmd}" -j list set inet banIP "${set}" 2>/dev/null | jsonfilter -qe '@.nftables[*].set.elem[*]' | wc -l 2>/dev/null)" + sum_setelements="$((sum_setelements + set_cnt))" + else + set_cnt="" + sum_setelements="n/a" + fi if [ -n "${set_cntinput}" ]; then set_input="OK" sum_setinput="$((sum_setinput + 1))" @@ -1070,14 +1136,14 @@ f_report() { printf "%s\n%s\n%s\n" ":::" "::: banIP Set Statistics" ":::" printf "%s\n" " Timestamp: ${timestamp}" printf "%s\n" " ------------------------------" - printf "%s\n" " auto-added to allowlist: ${autoadd_allow}" - printf "%s\n\n" " auto-added to blocklist: ${autoadd_block}" + printf "%s\n" " auto-added to allowlist today: ${autoadd_allow}" + printf "%s\n\n" " auto-added to blocklist today: ${autoadd_block}" json_select "sets" >/dev/null 2>&1 - json_get_keys nft_sets >/dev/null 2>&1 - if [ -n "${nft_sets}" ]; then + json_get_keys table_sets >/dev/null 2>&1 + if [ -n "${table_sets}" ]; then printf "%-25s%-15s%-24s%-24s%s\n" " Set" "| Elements" "| WAN-Input (packets)" "| WAN-Forward (packets)" "| LAN-Forward (packets)" printf "%s\n" " ---------------------+--------------+-----------------------+-----------------------+------------------------" - for set in ${nft_sets}; do + for set in ${table_sets}; do printf " %-21s" "${set}" json_select "${set}" json_get_keys set_details @@ -1121,10 +1187,10 @@ f_report() { esac } -# banIP set search +# set search # f_search() { - local nft_sets ip proto run_search search="${1}" + local table_sets ip proto run_search search="${1}" f_system run_search="/var/run/banIP.search" @@ -1136,24 +1202,21 @@ f_search() { ip="$(printf "%s" "${search}" | "${ban_awkcmd}" 'BEGIN{RS="([A-Fa-f0-9]{1,4}::?){3,7}[A-Fa-f0-9]{1,4}"}{printf "%s",RT}')" [ -n "${ip}" ] && proto="v6" fi - if [ -n "${proto}" ]; then - nft_sets="$("${ban_nftcmd}" -tj list table inet banIP 2>/dev/null | jsonfilter -qe "@.nftables[@.set.type=\"ip${proto}_addr\"].set.name")" - else - printf "%s\n%s\n%s\n" ":::" "::: no valid search input (single IPv4/IPv6 address)" ":::" - return - fi + fi + if [ -n "${proto}" ]; then + table_sets="$("${ban_nftcmd}" -tj list ruleset 2>/dev/null | jsonfilter -qe "@.nftables[@.set.table=\"banIP\"&&@.set.type=\"ip${proto}_addr\"].set.name")" else - printf "%s\n%s\n%s\n" ":::" "::: no valid search input (single IPv4/IPv6 address)" ":::" + printf "%s\n%s\n%s\n" ":::" "::: no valid search input" ":::" return fi printf "%s\n%s\n%s\n" ":::" "::: banIP Search" ":::" - printf "%s\n" " Looking for IP ${ip} on $(date "+%Y-%m-%d %H:%M:%S")" + printf "%s\n" " Looking for IP '${ip}' on $(date "+%Y-%m-%d %H:%M:%S")" printf "%s\n" " ---" cnt=1 - for set in ${nft_sets}; do + for set in ${table_sets}; do ( if "${ban_nftcmd}" get element inet banIP "${set}" "{ ${ip} }" >/dev/null 2>&1; then - printf "%s\n" " IP found in set ${set}" + printf "%s\n" " IP found in Set '${set}'" : >"${run_search}" fi ) & @@ -1162,8 +1225,29 @@ f_search() { cnt="$((cnt + 1))" done wait - [ ! -f "${run_search}" ] && printf "%s\n" " IP not found" - rm -f "${run_search}" + if [ ! -f "${run_search}" ]; then + printf "%s\n" " IP not found" + else + rm -f "${run_search}" + fi +} + +# set survey +# +f_survey() { + local set_elements set="${1}" + + f_system + [ -n "${set}" ] && set_elements="$("${ban_nftcmd}" -j list set inet banIP "${set}" 2>/dev/null | jsonfilter -qe '@.nftables[*].set.elem[*]')" + + if [ -z "${set}" ] || [ -z "${set_elements}" ]; then + printf "%s\n%s\n%s\n" ":::" "::: no valid survey input" ":::" + return + fi + printf "%s\n%s\n%s\n" ":::" "::: banIP Survey" ":::" + printf "%s\n" " List the elements of Set '${set}' on $(date "+%Y-%m-%d %H:%M:%S")" + printf "%s\n" " ---" + printf "%s\n" "${set_elements}" } # send status mails diff --git a/net/banip/files/banip-service.sh b/net/banip/files/banip-service.sh index 33ac81b1e7..94c1d47edd 100755 --- a/net/banip/files/banip-service.sh +++ b/net/banip/files/banip-service.sh @@ -1,5 +1,5 @@ #!/bin/sh -# banIP main service script - ban incoming and outgoing ip adresses/subnets via sets in nftables +# banIP main service script - ban incoming and outgoing ip addresses/subnets via sets in nftables # Copyright (c) 2018-2023 Dirk Brenken (dev@brenken.org) # This is free software, licensed under the GNU General Public License v3. @@ -44,7 +44,7 @@ fi # init nft namespace # -if [ "${ban_action}" != "reload" ] || ! "${ban_nftcmd}" -t list table inet banIP >/dev/null 2>&1; then +if [ "${ban_action}" != "reload" ] || ! "${ban_nftcmd}" -t list set inet banIP allowlistvMAC >/dev/null 2>&1; then if f_nftinit "${ban_tmpfile}".init.nft; then f_log "info" "nft namespace initialized" else @@ -174,7 +174,7 @@ if [ -x "${ban_logreadcmd}" ] && [ -n "${ban_logterm%%??}" ]; then log_count="$(printf "%s\n" "${log_raw}" | grep -c "found '${ip}'")" if [ "${log_count}" -ge "${ban_logcount}" ]; then if "${ban_nftcmd}" add element inet banIP "blocklist${proto}" "{ ${ip} ${nft_expiry} }" >/dev/null 2>&1; then - f_log "info" "added IP${proto} '${ip}' (${nft_expiry:-"-"}) to blocklist${proto} set" + f_log "info" "added IP${proto} '${ip}' (expiry: ${nft_expiry:-"-"}) to blocklist${proto} set" if [ "${ban_autoblocklist}" = "1" ] && ! grep -q "^${ip}" "${ban_blocklist}"; then printf "%-42s%s\n" "${ip}" "# added on $(date "+%Y-%m-%d %H:%M:%S")" >>"${ban_blocklist}" f_log "info" "added IP${proto} '${ip}' to local blocklist" diff --git a/net/banip/files/banip.conf b/net/banip/files/banip.conf index ce0a9cac14..eaa30989ea 100644 --- a/net/banip/files/banip.conf +++ b/net/banip/files/banip.conf @@ -6,4 +6,4 @@ config banip 'global' list ban_logterm 'luci: failed login' list ban_logterm 'error: maximum authentication attempts exceeded' list ban_logterm 'sshd.*Connection closed by.*\[preauth\]' - list ban_logterm 'SecurityEvent=\"ChallengeResponseFailed\".*RemoteAddress=' + list ban_logterm 'SecurityEvent=\"InvalidAccountID\".*RemoteAddress=' diff --git a/net/banip/files/banip.init b/net/banip/files/banip.init index 61639acfbd..c56004279c 100755 --- a/net/banip/files/banip.init +++ b/net/banip/files/banip.init @@ -10,7 +10,8 @@ START=30 USE_PROCD=1 extra_command "report" "[text|json|mail] Print banIP related set statistics" -extra_command "search" "[|] Check if an element exists in the banIP sets" +extra_command "search" "[|] Check if an element exists in a banIP set" +extra_command "survey" "[] List all elements of a given banIP set" ban_init="/etc/init.d/banip" ban_service="/usr/bin/banip-service.sh" @@ -19,7 +20,7 @@ ban_pidfile="/var/run/banip.pid" ban_lock="/var/run/banip.lock" [ "${action}" = "stop" ] && ! /etc/init.d/banip running && exit 0 -[ ! -r "${ban_funlib}" ] && { [ "${action}" = "start" ] || [ "${action}" = "restart" ] || [ "${action}" = "reload" ] || [ "${action}" = "stop" ] || [ "${action}" = "report" ] || [ "${action}" = "search" ] || [ "${action}" = "status" ]; } && exit 1 +[ ! -r "${ban_funlib}" ] && { [ "${action}" = "start" ] || [ "${action}" = "restart" ] || [ "${action}" = "reload" ] || [ "${action}" = "stop" ] || [ "${action}" = "report" ] || [ "${action}" = "search" ] || [ "${action}" = "survey" ] || [ "${action}" = "status" ]; } && exit 1 [ -d "${ban_lock}" ] && { [ "${action}" = "start" ] || [ "${action}" = "restart" ] || [ "${action}" = "reload" ]; } && exit 1 [ ! -d "${ban_lock}" ] && { [ "${action}" = "start" ] || [ "${action}" = "restart" ] || [ "${action}" = "reload" ]; } && mkdir -p "${ban_lock}" @@ -71,8 +72,10 @@ status() { } status_service() { + local actual="${1}" + [ -z "$(command -v "f_system")" ] && . "${ban_funlib}" - f_getstatus + [ -n "${actual}" ] && f_actual || f_getstatus } report() { @@ -85,11 +88,16 @@ search() { f_search "${1}" } +survey() { + [ -z "$(command -v "f_system")" ] && . "${ban_funlib}" + f_survey "${1}" +} + service_triggers() { local iface trigger delay trigger="$(uci_get banip global ban_trigger)" - delay="$(uci_get banip global ban_triggerdelay "5")" + delay="$(uci_get banip global ban_triggerdelay "10")" PROCD_RELOAD_DELAY=$((delay * 1000)) for iface in ${trigger}; do diff --git a/net/cni-protocol/Makefile b/net/cni-protocol/Makefile new file mode 100644 index 0000000000..dbe1498753 --- /dev/null +++ b/net/cni-protocol/Makefile @@ -0,0 +1,51 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=cni-protocol +PKG_VERSION:=20230217 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=Oskari Rauta + +include $(INCLUDE_DIR)/package.mk + +define Package/cni-protocol + SECTION:=net + CATEGORY:=Network + TITLE:=cni netifd protocol + PKGARCH:=all +endef + +define Package/cni-protocol/description + protocol support for cni networks for netifd + makes defining network for podman and other similar + systems using cni networking much easier and simpler. + + with cni protocol support, on a network, where firewall + and portmapper management is disabled, you may control + firewalling with openwrt's default firewall configuration. + + for example, create a container that hosts web content on + port 80 with static ip on your cni network, if your + network is 10.88.0.0/16, use for eg. 10.88.0.101 as + your containers static ip address. Create a zone, cni + to your firewall and add your interface to it. + + Now you can easily set up redirectiong to 10.88.0.101:80 + to expose it's port 80 to wan for serving your website. + + Protocol has one setting: device, on podman this often + is cni-podman0. +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/cni-protocol/install + $(INSTALL_DIR) $(1)/lib/netifd/proto + $(INSTALL_BIN) ./files/cni.sh $(1)/lib/netifd/proto/cni.sh +endef + +$(eval $(call BuildPackage,cni-protocol)) diff --git a/net/cni-protocol/files/cni.sh b/net/cni-protocol/files/cni.sh new file mode 100755 index 0000000000..c0cbc3b723 --- /dev/null +++ b/net/cni-protocol/files/cni.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +[ -n "$INCLUDE_ONLY" ] || { + . /lib/functions.sh + . ../netifd-proto.sh + init_proto "$@" +} + +proto_cni_init_config() { + no_device=0 + available=0 + no_proto_task=1 + teardown_on_l3_link_down=1 + + proto_config_add_string "device:device" +} + +proto_cni_setup() { + + local cfg="$1" + local device ipaddr netmask broadcast route routemask routesrc + + json_get_var device device + + ipaddr=$(ip -4 -o a show "$device" | awk '{ print $4 }' | cut -d '/' -f1) + netmask=$(ip -4 -o a show "$device" | awk '{ print $4 }' | cut -d '/' -f2) + broadcast=$(ip -4 -o a show "$device" | awk '{ print $6 }') + route=$(ip -4 -o r show dev "$device" | awk '{ print $1 }' | cut -d '/' -f1) + routemask=$(ip -4 -o r show dev "$device" | awk '{ print $1 }' | cut -d '/' -f2) + routesrc=$(ip -4 -o r show dev "$device" | awk '{ print $7 }') + + [ -z "$ipaddr" ] && { + echo "cni network $cfg does not have ip address" + proto_notify_error "$cfg" NO_IPADDRESS + return 1 + } + + proto_init_update "$device" 1 + [ -n "$ipaddr" ] && proto_add_ipv4_address "$ipaddr" "$netmask" "$broadcast" "" + [ -n "$route" ] && proto_add_ipv4_route "$route" "$routemask" "" "$routesrc" "" + proto_send_update "$cfg" +} + +proto_cni_teardown() { + local cfg="$1" + #proto_set_available "$cfg" 0 + return 0 +} + +[ -n "$INCLUDE_ONLY" ] || { + add_protocol cni +} diff --git a/net/frp/Makefile b/net/frp/Makefile index d77066e9be..7adbac02c9 100644 --- a/net/frp/Makefile +++ b/net/frp/Makefile @@ -1,12 +1,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=frp -PKG_VERSION:=0.46.1 +PKG_VERSION:=0.48.0 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/fatedier/frp/tar.gz/v${PKG_VERSION}? -PKG_HASH:=af3e8d9d4144cf520cee2609cd45fb575afe711c03cc7441dc89d0402628a869 +PKG_HASH:=efba8ec9fad3369ce62631369f52b78a7248df426b5b54311e96231adac5cc76 PKG_MAINTAINER:=Richard Yu PKG_LICENSE:=Apache-2.0 diff --git a/net/frp/files/frpc.init b/net/frp/files/frpc.init index e7f06edbd5..68fe43c4e0 100644 --- a/net/frp/files/frpc.init +++ b/net/frp/files/frpc.init @@ -69,6 +69,7 @@ start_service() { procd_open_instance procd_set_param command "$PROG" -c "$conf_file" + procd_set_param file $conf_file procd_set_param stdout $stdout procd_set_param stderr $stderr [ -n "$user" ] && procd_set_param user "$user" @@ -77,8 +78,3 @@ start_service() { [ -n "$env" ] && config_list_foreach "$init_cfg" env "procd_append_param env" procd_close_instance } - -reload_service() { - stop - start -} diff --git a/net/frp/files/frps.init b/net/frp/files/frps.init index b87525cd2a..38f714fb1b 100644 --- a/net/frp/files/frps.init +++ b/net/frp/files/frps.init @@ -67,6 +67,7 @@ start_service() { procd_open_instance procd_set_param command "$PROG" -c "$conf_file" + procd_set_param file $conf_file procd_set_param stdout $stdout procd_set_param stderr $stderr [ -n "$user" ] && procd_set_param user "$user" @@ -75,8 +76,3 @@ start_service() { [ -n "$env" ] && config_list_foreach "$init_cfg" env "procd_append_param env" procd_close_instance } - -reload_service() { - stop - start -} diff --git a/net/haproxy/Makefile b/net/haproxy/Makefile index 5c5189c48e..bf84d48de5 100644 --- a/net/haproxy/Makefile +++ b/net/haproxy/Makefile @@ -10,12 +10,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=haproxy -PKG_VERSION:=2.6.8 +PKG_VERSION:=2.6.9 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://www.haproxy.org/download/2.6/src -PKG_HASH:=a02ad64550dd30a94b25fd0e225ba699649d0c4037bca3b36b20e8e3235bb86f +PKG_HASH:=f01a1c5f465dc1b5cd175d0b28b98beb4dfe82b5b5b63ddcc68d1df433641701 PKG_MAINTAINER:=Thomas Heil , \ Christian Lachner diff --git a/net/haproxy/get-latest-patches.sh b/net/haproxy/get-latest-patches.sh index afd83a13ad..8c17d3e4f8 100755 --- a/net/haproxy/get-latest-patches.sh +++ b/net/haproxy/get-latest-patches.sh @@ -1,7 +1,7 @@ #!/bin/sh CLONEURL=https://git.haproxy.org/git/haproxy-2.6.git -BASE_TAG=v2.6.8 +BASE_TAG=v2.6.9 TMP_REPODIR=tmprepo PATCHESDIR=patches diff --git a/net/ksmbd-tools/Makefile b/net/ksmbd-tools/Makefile index 734dcb5419..1612bd0d21 100644 --- a/net/ksmbd-tools/Makefile +++ b/net/ksmbd-tools/Makefile @@ -1,12 +1,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ksmbd-tools -PKG_RELEASE:=$(AUTORELEASE) +PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/cifsd-team/ksmbd-tools -PKG_SOURCE_VERSION:=3.4.6 -PKG_MIRROR_HASH:=c78dace3320cf8a273738b8f3e67bed24c812695f2fab2fbaeae06ec8a15cb77 +PKG_SOURCE_VERSION:=3.4.7 +PKG_MIRROR_HASH:=9128ecac1a2c463e689ed42fd71952a0eafe956f8bcd1b04af58c7bc66a8baee PKG_LICENSE:=GPL-2.0-or-later PKG_LICENSE_FILES:=COPYING diff --git a/net/ksmbd-tools/patches/010-muon.patch b/net/ksmbd-tools/patches/010-muon.patch deleted file mode 100644 index 967c92702b..0000000000 --- a/net/ksmbd-tools/patches/010-muon.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 3281f325c820a72057ea639e0d11ad68d5703b43 Mon Sep 17 00:00:00 2001 -From: Rosen Penev -Date: Thu, 6 Oct 2022 18:07:01 -0700 -Subject: [PATCH] ksmbd-tools: run meson through muon analyze -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Mostly unused variable removals. Removed pointless [] in -include_directories. - -Signed-off-by: Rosen Penev -Acked-by: Atte Heikkilä -Signed-off-by: Namjae Jeon ---- - addshare/meson.build | 2 +- - adduser/meson.build | 2 +- - control/meson.build | 2 +- - meson.build | 4 ++-- - mountd/meson.build | 2 +- - 5 files changed, 6 insertions(+), 6 deletions(-) - ---- a/addshare/meson.build -+++ b/addshare/meson.build -@@ -1,4 +1,4 @@ --addshare = executable( -+executable( - 'ksmbd.addshare', - 'share_admin.c', - 'addshare.c', ---- a/adduser/meson.build -+++ b/adduser/meson.build -@@ -1,4 +1,4 @@ --adduser = executable( -+executable( - 'ksmbd.adduser', - 'md4_hash.c', - 'user_admin.c', ---- a/control/meson.build -+++ b/control/meson.build -@@ -1,4 +1,4 @@ --control = executable( -+executable( - 'ksmbd.control', - 'control.c', - dependencies: [ ---- a/meson.build -+++ b/meson.build -@@ -13,10 +13,10 @@ exec awk '/define KSMBD_TOOLS_VERSION / - meson_version: '>= 0.51.0', - ) - --tools_incdir = include_directories([ -+tools_incdir = include_directories( - '.', - 'include', --]) -+) - - glib_dep = dependency( - 'glib-2.0', ---- a/mountd/meson.build -+++ b/mountd/meson.build -@@ -1,4 +1,4 @@ --mountd = executable( -+executable( - 'ksmbd.mountd', - 'worker.c', - 'ipc.c', diff --git a/net/ksmbd-tools/patches/020-meson.patch b/net/ksmbd-tools/patches/020-meson.patch deleted file mode 100644 index adc01b655a..0000000000 --- a/net/ksmbd-tools/patches/020-meson.patch +++ /dev/null @@ -1,9190 +0,0 @@ -From 6b74583bd62e2b6ed6b76ff72d8fc7c2d8f26510 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Atte=20Heikkil=C3=A4?= -Date: Thu, 13 Oct 2022 20:08:47 +0300 -Subject: [PATCH] ksmbd-tools: build utilities as a single binary -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Rather than have four different binaries, i.e. ksmbd.addshare, -ksmbd.adduser, ksmbd.control, and ksmbd.mountd, each one including -its own libksmbdtools.a copy, build them instead as a single binary. -This resulting ksmbd.tools acts like BusyBox in that its behavior -depends on the name by which it is called. Then, each utility is made -into a symlink to it, meaning that users keep using the utilities as -usual. ksmbd.tools itself is installed to libexecdir as it is not -something the user should run. - -Instead of libksmbdtools.a, each utility becomes its own static -library, i.e. libaddshare.a, libadduser.a, libcontrol.a, libmountd.a, -which are all linked to the single binary. Note that the single binary -approach is also beneficial when statically linking to any of the -external dependencies, e.g. GLib, as it greatly reduces the overall -binary size when there is overlap in copies otherwise made separately -for multiple utilities. - -Due to install_symlink(), minimum meson version is bumped to 0.62.1, -meaning that it has to be installed using `pip' in Travis, since no -Ubuntu release currently packages that version or newer. However, bump -to Ubuntu Jammy anyways, just for the sake of building against newer -versions of ksmbd-tools' dependencies. - -Signed-off-by: Atte Heikkilä ---- - .travis.yml | 6 ++++-- - Makefile.am | 2 +- - addshare/Makefile.am | 15 ++++++++----- - addshare/addshare.c | 4 ++-- - addshare/meson.build | 22 ++++++++++--------- - addshare/share_admin.c | 2 +- - adduser/Makefile.am | 16 ++++++++------ - adduser/adduser.c | 4 ++-- - adduser/meson.build | 22 ++++++++++--------- - adduser/user_admin.c | 2 +- - configure.ac | 8 ++++--- - control/Makefile.am | 15 ++++++++----- - control/control.c | 4 ++-- - control/meson.build | 22 ++++++++++--------- - include/{ksmbdtools.h => tools.h} | 11 +++++++--- - ksmbd-tools.spec | 3 ++- - meson.build | 6 +++--- - mountd/Makefile.am | 17 +++++++++------ - mountd/ipc.c | 2 +- - mountd/meson.build | 23 +++++++++++--------- - mountd/mountd.c | 4 ++-- - mountd/rpc.c | 2 +- - mountd/rpc_lsarpc.c | 2 +- - mountd/rpc_samr.c | 2 +- - mountd/rpc_srvsvc.c | 2 +- - mountd/rpc_wkssvc.c | 2 +- - mountd/smbacl.c | 2 +- - mountd/worker.c | 2 +- - {lib => tools}/Makefile.am | 15 +++++++------ - {lib => tools}/asn1.c | 0 - {lib => tools}/config_parser.c | 2 +- - {lib => tools}/management/session.c | 2 +- - {lib => tools}/management/share.c | 2 +- - {lib => tools}/management/spnego.c | 2 +- - {lib => tools}/management/spnego_krb5.c | 2 +- - {lib => tools}/management/spnego_mech.h | 0 - {lib => tools}/management/tree_conn.c | 2 +- - {lib => tools}/management/user.c | 2 +- - {lib => tools}/meson.build | 28 ++++++++++++++++--------- - lib/ksmbdtools.c => tools/tools.c | 27 +++++++++++++++++++++++- - 40 files changed, 191 insertions(+), 117 deletions(-) - rename include/{ksmbdtools.h => tools.h} (94%) - rename {lib => tools}/Makefile.am (53%) - rename {lib => tools}/asn1.c (100%) - rename {lib => tools}/config_parser.c (99%) - rename {lib => tools}/management/session.c (99%) - rename {lib => tools}/management/share.c (99%) - rename {lib => tools}/management/spnego.c (99%) - rename {lib => tools}/management/spnego_krb5.c (99%) - rename {lib => tools}/management/spnego_mech.h (100%) - rename {lib => tools}/management/tree_conn.c (99%) - rename {lib => tools}/management/user.c (99%) - rename {lib => tools}/meson.build (60%) - rename lib/ksmbdtools.c => tools/tools.c (89%) - ---- a/.travis.yml -+++ b/.travis.yml -@@ -1,4 +1,4 @@ --dist: focal -+dist: jammy - - language: c - -@@ -6,9 +6,11 @@ notifications: - - email: true - - before_install: -- - sudo apt-get install libnl-3-dev libnl-genl-3-dev krb5-multidev heimdal-multidev meson -+ - sudo apt-get install libnl-3-dev libnl-genl-3-dev krb5-multidev heimdal-multidev ninja-build - - gcc --version - - g++ --version -+ - pip3 install --user meson -+ - PATH=$HOME/.local/bin:$PATH - - jobs: - include: ---- a/Makefile.am -+++ b/Makefile.am -@@ -1,6 +1,6 @@ - ACLOCAL_AMFLAGS = -I m4 - --SUBDIRS = lib mountd adduser addshare control -+SUBDIRS = addshare adduser control mountd tools - - EXTRA_DIST = include \ - README.md \ ---- a/addshare/Makefile.am -+++ b/addshare/Makefile.am -@@ -1,11 +1,8 @@ - AM_CFLAGS = -DSYSCONFDIR='"${sysconfdir}"' -DRUNSTATEDIR='"${runstatedir}"' \ - -I$(top_srcdir)/include $(GLIB_CFLAGS) $(LIBNL_CFLAGS) -fno-common --LIBS = $(GLIB_LIBS) --ksmbd_addshare_LDADD = $(top_builddir)/lib/libksmbdtools.a - --sbin_PROGRAMS = ksmbd.addshare -- --ksmbd_addshare_SOURCES = share_admin.c addshare.c share_admin.h -+noinst_LIBRARIES = libaddshare.a -+libaddshare_a_SOURCES = share_admin.c addshare.c share_admin.h - - EXTRA_DIST = ksmbd.addshare.8.in - -@@ -13,3 +10,11 @@ man_MANS = ksmbd.addshare.8 - $(man_MANS): %: %.in; @$(in_script) $< >$@ - - CLEANFILES = $(man_MANS) -+ -+install-exec-hook: uninstall-hook -+ $(MKDIR_P) $(DESTDIR)$(sbindir) -+ ( cd $(DESTDIR)$(sbindir) && \ -+ $(LN_S) $(libexecdir)/ksmbd.tools ksmbd.addshare ) -+ -+uninstall-hook: -+ -rm $(DESTDIR)$(sbindir)/ksmbd.addshare ---- a/addshare/addshare.c -+++ b/addshare/addshare.c -@@ -18,7 +18,7 @@ - #include - - #include "config_parser.h" --#include "ksmbdtools.h" -+#include "tools.h" - #include "management/share.h" - #include "linux/ksmbd_server.h" - #include "share_admin.h" -@@ -111,7 +111,7 @@ static int sanity_check_share_name_simpl - return 0; - } - --int main(int argc, char *argv[]) -+int addshare_main(int argc, char **argv) - { - int ret = -EINVAL; - char *share = NULL, *options = NULL, *smbconf = NULL; ---- a/addshare/meson.build -+++ b/addshare/meson.build -@@ -1,20 +1,16 @@ --executable( -- 'ksmbd.addshare', -+addshare_lib = static_library( -+ 'addshare', - 'share_admin.c', - 'addshare.c', - 'share_admin.h', -- dependencies: [ -- glib_dep, -- libnl_dep, -- ], -- include_directories: tools_incdir, -- link_with: libksmbdtools, -- install: true, -- install_dir: get_option('sbindir'), -+ include_directories: include_dirs, - c_args: [ - '-DSYSCONFDIR="@0@"'.format(get_option('prefix') / get_option('sysconfdir')), - '-DRUNSTATEDIR="@0@"'.format(runstatedir), - ], -+ dependencies: [ -+ glib_dep, -+ ], - ) - - configure_file( -@@ -23,3 +19,9 @@ configure_file( - install_dir: get_option('mandir') / 'man8', - configuration: in_data, - ) -+ -+install_symlink( -+ 'ksmbd.addshare', -+ install_dir: get_option('sbindir'), -+ pointing_to: '..' / get_option('libexecdir') / 'ksmbd.tools', -+) ---- a/addshare/share_admin.c -+++ b/addshare/share_admin.c -@@ -14,7 +14,7 @@ - #include - - #include --#include -+#include - - #include - ---- a/adduser/Makefile.am -+++ b/adduser/Makefile.am -@@ -1,12 +1,8 @@ - AM_CFLAGS = -DSYSCONFDIR='"${sysconfdir}"' -DRUNSTATEDIR='"${runstatedir}"' \ - -I$(top_srcdir)/include $(GLIB_CFLAGS) $(LIBNL_CFLAGS) -fno-common --LIBS = $(GLIB_LIBS) --ksmbd_adduser_LDADD = $(top_builddir)/lib/libksmbdtools.a - --sbin_PROGRAMS = ksmbd.adduser -- --ksmbd_adduser_SOURCES = md4_hash.c user_admin.c adduser.c md4_hash.h \ -- user_admin.h -+noinst_LIBRARIES = libadduser.a -+libadduser_a_SOURCES = md4_hash.c user_admin.c adduser.c md4_hash.h user_admin.h - - EXTRA_DIST = ksmbd.adduser.8.in - -@@ -14,3 +10,11 @@ man_MANS = ksmbd.adduser.8 - $(man_MANS): %: %.in; @$(in_script) $< >$@ - - CLEANFILES = $(man_MANS) -+ -+install-exec-hook: uninstall-hook -+ $(MKDIR_P) $(DESTDIR)$(sbindir) -+ ( cd $(DESTDIR)$(sbindir) && \ -+ $(LN_S) $(libexecdir)/ksmbd.tools ksmbd.adduser ) -+ -+uninstall-hook: -+ -rm $(DESTDIR)$(sbindir)/ksmbd.adduser ---- a/adduser/adduser.c -+++ b/adduser/adduser.c -@@ -18,7 +18,7 @@ - #include - - #include "config_parser.h" --#include "ksmbdtools.h" -+#include "tools.h" - #include "management/user.h" - #include "management/share.h" - #include "user_admin.h" -@@ -121,7 +121,7 @@ static int sanity_check_user_name_simple - return 0; - } - --int main(int argc, char *argv[]) -+int adduser_main(int argc, char **argv) - { - int ret = -EINVAL; - char *account = NULL, *password = NULL, *pwddb = NULL, *smbconf = NULL; ---- a/adduser/meson.build -+++ b/adduser/meson.build -@@ -1,22 +1,18 @@ --executable( -- 'ksmbd.adduser', -+adduser_lib = static_library( -+ 'adduser', - 'md4_hash.c', - 'user_admin.c', - 'adduser.c', - 'md4_hash.h', - 'user_admin.h', -- dependencies: [ -- glib_dep, -- libnl_dep, -- ], -- include_directories: tools_incdir, -- link_with: libksmbdtools, -- install: true, -- install_dir: get_option('sbindir'), -+ include_directories: include_dirs, - c_args: [ - '-DSYSCONFDIR="@0@"'.format(get_option('prefix') / get_option('sysconfdir')), - '-DRUNSTATEDIR="@0@"'.format(runstatedir), - ], -+ dependencies: [ -+ glib_dep, -+ ], - ) - - configure_file( -@@ -25,3 +21,9 @@ configure_file( - install_dir: get_option('mandir') / 'man8', - configuration: in_data, - ) -+ -+install_symlink( -+ 'ksmbd.adduser', -+ install_dir: get_option('sbindir'), -+ pointing_to: '..' / get_option('libexecdir') / 'ksmbd.tools', -+) ---- a/adduser/user_admin.c -+++ b/adduser/user_admin.c -@@ -15,7 +15,7 @@ - #include - - #include --#include -+#include - - #include - #include ---- a/configure.ac -+++ b/configure.ac -@@ -24,6 +24,8 @@ AC_PROG_CC_STDC - AM_SILENT_RULES([yes]) - AC_PROG_LIBTOOL - AC_PROG_SED -+AC_PROG_MKDIR_P -+AC_PROG_LN_S - - AC_SUBST([in_script], [[\ - '$(SED) -e "s,[@]sbindir[@],$(sbindir),g" \ -@@ -143,11 +145,11 @@ AM_CONDITIONAL(HAVE_LIBKRB5, [test "x$en - - AC_CONFIG_FILES([ - Makefile -- lib/Makefile -- mountd/Makefile -- adduser/Makefile - addshare/Makefile -+ adduser/Makefile - control/Makefile -+ mountd/Makefile -+ tools/Makefile - ]) - - AC_OUTPUT ---- a/control/Makefile.am -+++ b/control/Makefile.am -@@ -1,11 +1,8 @@ - AM_CFLAGS = -DSYSCONFDIR='"${sysconfdir}"' -DRUNSTATEDIR='"${runstatedir}"' \ - -I$(top_srcdir)/include $(GLIB_CFLAGS) $(LIBNL_CFLAGS) -fno-common --LIBS = $(GLIB_LIBS) --ksmbd_control_LDADD = $(top_builddir)/lib/libksmbdtools.a - --sbin_PROGRAMS = ksmbd.control -- --ksmbd_control_SOURCES = control.c -+noinst_LIBRARIES = libcontrol.a -+libcontrol_a_SOURCES = control.c - - EXTRA_DIST = ksmbd.control.8.in - -@@ -13,3 +10,11 @@ man_MANS = ksmbd.control.8 - $(man_MANS): %: %.in; @$(in_script) $< >$@ - - CLEANFILES = $(man_MANS) -+ -+install-exec-hook: uninstall-hook -+ $(MKDIR_P) $(DESTDIR)$(sbindir) -+ ( cd $(DESTDIR)$(sbindir) && \ -+ $(LN_S) $(libexecdir)/ksmbd.tools ksmbd.control ) -+ -+uninstall-hook: -+ -rm $(DESTDIR)$(sbindir)/ksmbd.control ---- a/control/control.c -+++ b/control/control.c -@@ -9,7 +9,7 @@ - #include - #include - --#include "ksmbdtools.h" -+#include "tools.h" - #include "version.h" - - static void usage(int status) -@@ -146,7 +146,7 @@ out: - return ret; - } - --int main(int argc, char *argv[]) -+int control_main(int argc, char **argv) - { - int ret = -EINVAL; - int c; ---- a/control/meson.build -+++ b/control/meson.build -@@ -1,18 +1,14 @@ --executable( -- 'ksmbd.control', -+control_lib = static_library( -+ 'control', - 'control.c', -- dependencies: [ -- glib_dep, -- libnl_dep, -- ], -- include_directories: tools_incdir, -- link_with: libksmbdtools, -- install: true, -- install_dir: get_option('sbindir'), -+ include_directories: include_dirs, - c_args: [ - '-DSYSCONFDIR="@0@"'.format(get_option('prefix') / get_option('sysconfdir')), - '-DRUNSTATEDIR="@0@"'.format(runstatedir), - ], -+ dependencies: [ -+ glib_dep, -+ ], - ) - - configure_file( -@@ -21,3 +17,9 @@ configure_file( - install_dir: get_option('mandir') / 'man8', - configuration: in_data, - ) -+ -+install_symlink( -+ 'ksmbd.control', -+ install_dir: get_option('sbindir'), -+ pointing_to: '..' / get_option('libexecdir') / 'ksmbd.tools', -+) ---- a/include/ksmbdtools.h -+++ /dev/null -@@ -1,172 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0-or-later */ --/* -- * Copyright (C) 2018 Samsung Electronics Co., Ltd. -- * -- * linux-cifsd-devel@lists.sourceforge.net -- */ -- --#ifndef __KSMBDTOOLS_H__ --#define __KSMBDTOOLS_H__ -- --#ifndef _GNU_SOURCE --#define _GNU_SOURCE 1 --#endif -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#ifdef HAVE_CONFIG_H --#include --#endif -- --struct smbconf_global { -- int flags; -- int map_to_guest; -- char *guest_account; -- -- char *server_string; -- char *work_group; -- char *netbios_name; -- char *server_min_protocol; -- char *server_max_protocol; -- char *root_dir; -- int server_signing; -- int sessions_cap; -- int restrict_anon; -- unsigned short tcp_port; -- unsigned short ipc_timeout; -- unsigned int deadtime; -- int bind_interfaces_only; -- char **interfaces; -- unsigned long file_max; -- unsigned int smb2_max_read; -- unsigned int smb2_max_write; -- unsigned int smb2_max_trans; -- unsigned int smb2_max_credits; -- unsigned int smbd_max_io_size; -- unsigned int share_fake_fscaps; -- unsigned int gen_subauth[3]; -- char *krb5_keytab_file; -- char *krb5_service_name; -- char *pwddb; -- char *smbconf; --}; -- --#define KSMBD_LOCK_FILE RUNSTATEDIR "/ksmbd.lock" -- --#define KSMBD_RESTRICT_ANON_TYPE_1 1 --#define KSMBD_RESTRICT_ANON_TYPE_2 2 -- --extern struct smbconf_global global_conf; -- --#define KSMBD_CONF_MAP_TO_GUEST_NEVER (0) --#define KSMBD_CONF_MAP_TO_GUEST_BAD_USER (1 << 0) --#define KSMBD_CONF_MAP_TO_GUEST_BAD_PASSWORD (1 << 1) --#define KSMBD_CONF_MAP_TO_GUEST_BAD_UID (1 << 2) -- --#define KSMBD_CONF_DEFAULT_NETBIOS_NAME "KSMBD SERVER" --#define KSMBD_CONF_DEFAULT_SERVER_STRING "SMB SERVER" --#define KSMBD_CONF_DEFAULT_WORK_GROUP "WORKGROUP" -- --#define KSMBD_CONF_DEFAULT_GUEST_ACCOUNT "nobody" -- --#define KSMBD_CONF_DEFAULT_SESS_CAP 1024 --#define KSMBD_CONF_DEFAULT_TCP_PORT 445 -- --#define KSMBD_CONF_FILE_MAX 10000 -- --#define PATH_PWDDB SYSCONFDIR "/ksmbd/ksmbdpwd.db" --#define PATH_SMBCONF SYSCONFDIR "/ksmbd/ksmbd.conf" --#define PATH_SMBCONF_FALLBACK SYSCONFDIR "/ksmbd/smb.conf" --#define PATH_SUBAUTH SYSCONFDIR "/ksmbd/ksmbd.subauth" -- --#define KSMBD_HEALTH_START (0) --#define KSMBD_HEALTH_RUNNING (1 << 0) --#define KSMBD_SHOULD_RELOAD_CONFIG (1 << 1) -- --extern int ksmbd_health_status; -- --#define TRACING_DUMP_NL_MSG 0 -- --#define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0])) -- --#define STR_HELPER(x) #x --#define STR(x) STR_HELPER(x) -- --//---------------------------------------------------------------// --#define LOGAPP "[%s/%d]:" --#define PRERR LOGAPP" ERROR: " --#define PRINF LOGAPP" INFO: " --#define PRDEBUG LOGAPP" DEBUG: " -- --#define PR_ERROR 0 --#define PR_INFO 1 --#define PR_DEBUG 2 -- --extern int log_level; -- --#define PR_LOGGER_STDIO 0 --#define PR_LOGGER_SYSLOG 1 -- --G_GNUC_PRINTF(2, 3) --extern void __pr_log(int level, const char *fmt, ...); --extern void set_logger_app_name(const char *an); --extern const char *get_logger_app_name(void); --extern void pr_logger_init(int flags); --extern int set_log_level(int level); -- --#define pr_log(l, f, ...) \ -- do { \ -- if ((l) <= log_level) \ -- __pr_log((l), (f), get_logger_app_name(), \ -- getpid(), \ -- ##__VA_ARGS__); \ -- } while (0) -- --#define pr_debug(f, ...) \ -- pr_log(PR_DEBUG, PRDEBUG f, ##__VA_ARGS__) --#define pr_info(f, ...) \ -- pr_log(PR_INFO, PRINF f, ##__VA_ARGS__) --#define pr_err(f, ...) \ -- pr_log(PR_ERROR, PRERR f, ##__VA_ARGS__) -- --//---------------------------------------------------------------// -- --void pr_hex_dump(const void *mem, size_t sz); -- --char *base64_encode(unsigned char *src, size_t srclen); --unsigned char *base64_decode(char const *src, size_t *dstlen); -- --gchar *ksmbd_gconvert(const gchar *str, -- gssize str_len, -- int to_codeset, -- int from_codeset, -- gsize *bytes_read, -- gsize *bytes_written); -- --enum charset_idx { -- KSMBD_CHARSET_UTF8 = 0, -- KSMBD_CHARSET_UTF16LE, -- KSMBD_CHARSET_UCS2LE, -- KSMBD_CHARSET_UTF16BE, -- KSMBD_CHARSET_UCS2BE, -- KSMBD_CHARSET_MAX = 5, --}; -- --#define KSMBD_CHARSET_DEFAULT KSMBD_CHARSET_UTF8 -- --extern char *ksmbd_conv_charsets[KSMBD_CHARSET_MAX + 1]; -- --int send_signal_to_ksmbd_mountd(int signo); --int test_file_access(char *conf); -- --#endif /* __KSMBDTOOLS_H__ */ ---- /dev/null -+++ b/include/tools.h -@@ -0,0 +1,177 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* -+ * Copyright (C) 2018 Samsung Electronics Co., Ltd. -+ * -+ * linux-cifsd-devel@lists.sourceforge.net -+ */ -+ -+#ifndef __TOOLS_H__ -+#define __TOOLS_H__ -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE 1 -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef HAVE_CONFIG_H -+#include -+#endif -+ -+struct smbconf_global { -+ int flags; -+ int map_to_guest; -+ char *guest_account; -+ -+ char *server_string; -+ char *work_group; -+ char *netbios_name; -+ char *server_min_protocol; -+ char *server_max_protocol; -+ char *root_dir; -+ int server_signing; -+ int sessions_cap; -+ int restrict_anon; -+ unsigned short tcp_port; -+ unsigned short ipc_timeout; -+ unsigned int deadtime; -+ int bind_interfaces_only; -+ char **interfaces; -+ unsigned long file_max; -+ unsigned int smb2_max_read; -+ unsigned int smb2_max_write; -+ unsigned int smb2_max_trans; -+ unsigned int smb2_max_credits; -+ unsigned int smbd_max_io_size; -+ unsigned int share_fake_fscaps; -+ unsigned int gen_subauth[3]; -+ char *krb5_keytab_file; -+ char *krb5_service_name; -+ char *pwddb; -+ char *smbconf; -+}; -+ -+#define KSMBD_LOCK_FILE RUNSTATEDIR "/ksmbd.lock" -+ -+#define KSMBD_RESTRICT_ANON_TYPE_1 1 -+#define KSMBD_RESTRICT_ANON_TYPE_2 2 -+ -+extern struct smbconf_global global_conf; -+ -+#define KSMBD_CONF_MAP_TO_GUEST_NEVER (0) -+#define KSMBD_CONF_MAP_TO_GUEST_BAD_USER (1 << 0) -+#define KSMBD_CONF_MAP_TO_GUEST_BAD_PASSWORD (1 << 1) -+#define KSMBD_CONF_MAP_TO_GUEST_BAD_UID (1 << 2) -+ -+#define KSMBD_CONF_DEFAULT_NETBIOS_NAME "KSMBD SERVER" -+#define KSMBD_CONF_DEFAULT_SERVER_STRING "SMB SERVER" -+#define KSMBD_CONF_DEFAULT_WORK_GROUP "WORKGROUP" -+ -+#define KSMBD_CONF_DEFAULT_GUEST_ACCOUNT "nobody" -+ -+#define KSMBD_CONF_DEFAULT_SESS_CAP 1024 -+#define KSMBD_CONF_DEFAULT_TCP_PORT 445 -+ -+#define KSMBD_CONF_FILE_MAX 10000 -+ -+#define PATH_PWDDB SYSCONFDIR "/ksmbd/ksmbdpwd.db" -+#define PATH_SMBCONF SYSCONFDIR "/ksmbd/ksmbd.conf" -+#define PATH_SMBCONF_FALLBACK SYSCONFDIR "/ksmbd/smb.conf" -+#define PATH_SUBAUTH SYSCONFDIR "/ksmbd/ksmbd.subauth" -+ -+#define KSMBD_HEALTH_START (0) -+#define KSMBD_HEALTH_RUNNING (1 << 0) -+#define KSMBD_SHOULD_RELOAD_CONFIG (1 << 1) -+ -+extern int ksmbd_health_status; -+ -+#define TRACING_DUMP_NL_MSG 0 -+ -+#define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0])) -+ -+#define STR_HELPER(x) #x -+#define STR(x) STR_HELPER(x) -+ -+//---------------------------------------------------------------// -+#define LOGAPP "[%s/%d]:" -+#define PRERR LOGAPP" ERROR: " -+#define PRINF LOGAPP" INFO: " -+#define PRDEBUG LOGAPP" DEBUG: " -+ -+#define PR_ERROR 0 -+#define PR_INFO 1 -+#define PR_DEBUG 2 -+ -+extern int log_level; -+ -+#define PR_LOGGER_STDIO 0 -+#define PR_LOGGER_SYSLOG 1 -+ -+G_GNUC_PRINTF(2, 3) -+extern void __pr_log(int level, const char *fmt, ...); -+extern void set_logger_app_name(const char *an); -+extern const char *get_logger_app_name(void); -+extern void pr_logger_init(int flags); -+extern int set_log_level(int level); -+ -+#define pr_log(l, f, ...) \ -+ do { \ -+ if ((l) <= log_level) \ -+ __pr_log((l), (f), get_logger_app_name(), \ -+ getpid(), \ -+ ##__VA_ARGS__); \ -+ } while (0) -+ -+#define pr_debug(f, ...) \ -+ pr_log(PR_DEBUG, PRDEBUG f, ##__VA_ARGS__) -+#define pr_info(f, ...) \ -+ pr_log(PR_INFO, PRINF f, ##__VA_ARGS__) -+#define pr_err(f, ...) \ -+ pr_log(PR_ERROR, PRERR f, ##__VA_ARGS__) -+ -+//---------------------------------------------------------------// -+ -+void pr_hex_dump(const void *mem, size_t sz); -+ -+char *base64_encode(unsigned char *src, size_t srclen); -+unsigned char *base64_decode(char const *src, size_t *dstlen); -+ -+gchar *ksmbd_gconvert(const gchar *str, -+ gssize str_len, -+ int to_codeset, -+ int from_codeset, -+ gsize *bytes_read, -+ gsize *bytes_written); -+ -+enum charset_idx { -+ KSMBD_CHARSET_UTF8 = 0, -+ KSMBD_CHARSET_UTF16LE, -+ KSMBD_CHARSET_UCS2LE, -+ KSMBD_CHARSET_UTF16BE, -+ KSMBD_CHARSET_UCS2BE, -+ KSMBD_CHARSET_MAX = 5, -+}; -+ -+#define KSMBD_CHARSET_DEFAULT KSMBD_CHARSET_UTF8 -+ -+extern char *ksmbd_conv_charsets[KSMBD_CHARSET_MAX + 1]; -+ -+int send_signal_to_ksmbd_mountd(int signo); -+int test_file_access(char *conf); -+ -+int addshare_main(int argc, char **argv); -+int adduser_main(int argc, char **argv); -+int control_main(int argc, char **argv); -+int mountd_main(int argc, char **argv); -+ -+#endif /* __TOOLS_H__ */ ---- a/ksmbd-tools.spec -+++ b/ksmbd-tools.spec -@@ -16,7 +16,7 @@ - # - - Name: ksmbd-tools --Version: 3.4.6 -+Version: master - Release: 0 - Summary: ksmbd kernel server userspace utilities - License: GPL-2.0-or-later -@@ -53,6 +53,7 @@ make %{?_smp_mflags} - %{_sbindir}/ksmbd.adduser - %{_sbindir}/ksmbd.control - %{_sbindir}/ksmbd.mountd -+%{_libexecdir}/ksmbd.tools - %{_mandir}/man8/ksmbd.addshare.8* - %{_mandir}/man8/ksmbd.adduser.8* - %{_mandir}/man8/ksmbd.control.8* ---- a/meson.build -+++ b/meson.build -@@ -10,10 +10,10 @@ exec awk '/define KSMBD_TOOLS_VERSION / - check: true, - ).stdout(), - default_options: 'c_std=gnu99', -- meson_version: '>= 0.51.0', -+ meson_version: '>= 0.61.5', - ) - --tools_incdir = include_directories( -+include_dirs = include_directories( - '.', - 'include', - ) -@@ -151,8 +151,8 @@ configure_file( - configuration: in_data, - ) - --subdir('lib') - subdir('addshare') - subdir('adduser') - subdir('control') - subdir('mountd') -+subdir('tools') ---- a/mountd/Makefile.am -+++ b/mountd/Makefile.am -@@ -1,12 +1,9 @@ - AM_CFLAGS = -DSYSCONFDIR='"${sysconfdir}"' -DRUNSTATEDIR='"${runstatedir}"' \ - -I$(top_srcdir)/include $(GLIB_CFLAGS) $(LIBNL_CFLAGS) -fno-common --LIBS = $(GLIB_LIBS) $(LIBNL_LIBS) $(LIBKRB5_LIBS) --ksmbd_mountd_LDADD = $(top_builddir)/lib/libksmbdtools.a - --sbin_PROGRAMS = ksmbd.mountd -- --ksmbd_mountd_SOURCES = worker.c ipc.c rpc.c rpc_srvsvc.c rpc_wkssvc.c \ -- mountd.c smbacl.c rpc_samr.c rpc_lsarpc.c -+noinst_LIBRARIES = libmountd.a -+libmountd_a_SOURCES = worker.c ipc.c rpc.c rpc_srvsvc.c rpc_wkssvc.c mountd.c \ -+ smbacl.c rpc_samr.c rpc_lsarpc.c - - EXTRA_DIST = ksmbd.mountd.8.in - -@@ -14,3 +11,11 @@ man_MANS = ksmbd.mountd.8 - $(man_MANS): %: %.in; @$(in_script) $< >$@ - - CLEANFILES = $(man_MANS) -+ -+install-exec-hook: uninstall-hook -+ $(MKDIR_P) $(DESTDIR)$(sbindir) -+ ( cd $(DESTDIR)$(sbindir) && \ -+ $(LN_S) $(libexecdir)/ksmbd.tools ksmbd.mountd ) -+ -+uninstall-hook: -+ -rm $(DESTDIR)$(sbindir)/ksmbd.mountd ---- a/mountd/ipc.c -+++ b/mountd/ipc.c -@@ -17,7 +17,7 @@ - - #include - --#include -+#include - #include - #include - #include ---- a/mountd/meson.build -+++ b/mountd/meson.build -@@ -1,5 +1,5 @@ --executable( -- 'ksmbd.mountd', -+mountd_lib = static_library( -+ 'mountd', - 'worker.c', - 'ipc.c', - 'rpc.c', -@@ -9,18 +9,15 @@ executable( - 'smbacl.c', - 'rpc_samr.c', - 'rpc_lsarpc.c', -- dependencies: [ -- glib_dep, -- libnl_dep, -- ], -- include_directories: tools_incdir, -- link_with: libksmbdtools, -- install: true, -- install_dir: get_option('sbindir'), -+ include_directories: include_dirs, - c_args: [ - '-DSYSCONFDIR="@0@"'.format(get_option('prefix') / get_option('sysconfdir')), - '-DRUNSTATEDIR="@0@"'.format(runstatedir), - ], -+ dependencies: [ -+ glib_dep, -+ libnl_dep, -+ ], - ) - - configure_file( -@@ -29,3 +26,9 @@ configure_file( - install_dir: get_option('mandir') / 'man8', - configuration: in_data, - ) -+ -+install_symlink( -+ 'ksmbd.mountd', -+ install_dir: get_option('sbindir'), -+ pointing_to: '..' / get_option('libexecdir') / 'ksmbd.tools', -+) ---- a/mountd/mountd.c -+++ b/mountd/mountd.c -@@ -5,7 +5,7 @@ - * linux-cifsd-devel@lists.sourceforge.net - */ - --#include -+#include - - #ifndef _GNU_SOURCE - #define _GNU_SOURCE -@@ -509,7 +509,7 @@ out: - return 0; - } - --int main(int argc, char *argv[]) -+int mountd_main(int argc, char **argv) - { - int ret = -EINVAL; - int c; ---- a/mountd/rpc.c -+++ b/mountd/rpc.c -@@ -16,7 +16,7 @@ - #include - #include - #include --#include -+#include - - static GHashTable *pipes_table; - static GRWLock pipes_table_lock; ---- a/mountd/rpc_lsarpc.c -+++ b/mountd/rpc_lsarpc.c -@@ -16,7 +16,7 @@ - #include - #include - #include --#include -+#include - - #define LSARPC_OPNUM_DS_ROLE_GET_PRIMARY_DOMAIN_INFO 0 - #define LSARPC_OPNUM_OPEN_POLICY2 44 ---- a/mountd/rpc_samr.c -+++ b/mountd/rpc_samr.c -@@ -15,7 +15,7 @@ - #include - #include - #include --#include -+#include - - #define SAMR_OPNUM_CONNECT5 64 - #define SAMR_OPNUM_ENUM_DOMAIN 6 ---- a/mountd/rpc_srvsvc.c -+++ b/mountd/rpc_srvsvc.c -@@ -15,7 +15,7 @@ - - #include - #include --#include -+#include - - #define SHARE_TYPE_TEMP 0x40000000 - #define SHARE_TYPE_HIDDEN 0x80000000 ---- a/mountd/rpc_wkssvc.c -+++ b/mountd/rpc_wkssvc.c -@@ -15,7 +15,7 @@ - - #include - #include --#include -+#include - - #define WKSSVC_NETWKSTA_GET_INFO (0) - ---- a/mountd/smbacl.c -+++ b/mountd/smbacl.c -@@ -7,7 +7,7 @@ - */ - - #include --#include -+#include - #include - - static const struct smb_sid sid_domain = {1, 1, {0, 0, 0, 0, 0, 5}, ---- a/mountd/worker.c -+++ b/mountd/worker.c -@@ -9,7 +9,7 @@ - #include - #include - --#include -+#include - #include - #include - #include ---- a/lib/Makefile.am -+++ /dev/null -@@ -1,18 +0,0 @@ --AM_CFLAGS = -DSYSCONFDIR='"${sysconfdir}"' -DRUNSTATEDIR='"${runstatedir}"' \ -- -I$(top_srcdir)/include $(GLIB_CFLAGS) $(LIBKRB5_CFLAGS) -fno-common --LIBS = $(GLIB_LIBS) -- --noinst_LIBRARIES = libksmbdtools.a --libksmbdtools_a_SOURCES = management/tree_conn.c \ -- management/user.c \ -- management/share.c \ -- management/session.c \ -- config_parser.c \ -- ksmbdtools.c -- --if HAVE_LIBKRB5 --libksmbdtools_a_SOURCES += management/spnego.c \ -- asn1.c \ -- management/spnego_krb5.c \ -- management/spnego_mech.h --endif ---- /dev/null -+++ b/tools/Makefile.am -@@ -0,0 +1,21 @@ -+AM_CFLAGS = -DSYSCONFDIR='"${sysconfdir}"' -DRUNSTATEDIR='"${runstatedir}"' \ -+ -I$(top_srcdir)/include $(GLIB_CFLAGS) $(LIBKRB5_CFLAGS) -fno-common -+LIBS = $(GLIB_LIBS) $(LIBNL_LIBS) $(LIBKRB5_LIBS) -+ -+libexec_PROGRAMS = ksmbd.tools -+ksmbd_tools_SOURCES = management/tree_conn.c \ -+ management/user.c \ -+ management/share.c \ -+ management/session.c \ -+ config_parser.c \ -+ tools.c -+if HAVE_LIBKRB5 -+ksmbd_tools_SOURCES += management/spnego.c \ -+ asn1.c \ -+ management/spnego_krb5.c \ -+ management/spnego_mech.h -+endif -+ksmbd_tools_LDADD = $(top_builddir)/addshare/libaddshare.a \ -+ $(top_builddir)/adduser/libadduser.a \ -+ $(top_builddir)/control/libcontrol.a \ -+ $(top_builddir)/mountd/libmountd.a ---- a/lib/config_parser.c -+++ /dev/null -@@ -1,770 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-or-later --/* -- * Copyright (C) 2018 Samsung Electronics Co., Ltd. -- * -- * linux-cifsd-devel@lists.sourceforge.net -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include -- --#include --#include --#include --#include -- --struct smbconf_global global_conf; --struct smbconf_parser parser; --struct smbconf_group *global_group, *ipc_group; -- --unsigned long long memparse(const char *v) --{ -- char *eptr; -- -- unsigned long long ret = strtoull(v, &eptr, 0); -- -- switch (*eptr) { -- case 'E': -- case 'e': -- ret <<= 10; -- case 'P': -- case 'p': -- ret <<= 10; -- case 'T': -- case 't': -- ret <<= 10; -- case 'G': -- case 'g': -- ret <<= 10; -- case 'M': -- case 'm': -- ret <<= 10; -- case 'K': -- case 'k': -- ret <<= 10; -- } -- -- return ret; --} -- --static void kv_release_cb(gpointer p) --{ -- g_free(p); --} -- --static int is_ascii_space_tab(char c) --{ -- return c == ' ' || c == '\t'; --} -- --static int is_a_comment(char *line) --{ -- return (*line == 0x00 || *line == ';' || *line == '\n' || *line == '#'); --} -- --static int is_a_group(char *line) --{ -- char *p = line; -- -- if (*p != '[') -- return 0; -- p++; -- while (*p && *p != ']') -- p = g_utf8_find_next_char(p, NULL); -- if (*p != ']') -- return 0; -- return 1; --} -- --static int add_new_group(char *line) --{ -- char *begin = line; -- char *end = line; -- char *name = NULL; -- struct smbconf_group *group = NULL; -- struct smbconf_group *lookup; -- -- while (*end && *end != ']') -- end = g_utf8_find_next_char(end, NULL); -- -- name = g_strndup(begin + 1, end - begin - 1); -- if (!name) -- goto out_free; -- -- lookup = g_hash_table_lookup(parser.groups, name); -- if (lookup) { -- parser.current = lookup; -- pr_info("Multiple definitions for group `%s'\n", name); -- g_free(name); -- return 0; -- } -- -- group = g_malloc(sizeof(struct smbconf_group)); -- group->cb_mode = GROUPS_CALLBACK_NONE; -- group->name = name; -- group->kv = g_hash_table_new_full(g_str_hash, -- g_str_equal, -- kv_release_cb, -- kv_release_cb); -- if (!group->kv) -- goto out_free; -- -- parser.current = group; -- g_hash_table_insert(parser.groups, group->name, group); -- return 0; -- --out_free: -- g_free(name); -- if (group && group->kv) -- g_hash_table_destroy(group->kv); -- g_free(group); -- return -ENOMEM; --} -- --static int add_group_key_value(char *line) --{ -- char *key, *value; -- -- key = strchr(line, '='); -- if (!key) -- return -EINVAL; -- -- value = key; -- *key = 0x00; -- key--; -- value++; -- -- while (is_ascii_space_tab(*key)) -- key--; -- while (is_ascii_space_tab(*value)) -- value++; -- -- if (is_a_comment(value)) -- return 0; -- -- if (g_hash_table_lookup(parser.current->kv, key)) { -- pr_info("Multiple key-value definitions [%s] %s\n", -- parser.current->name, key); -- return 0; -- } -- -- key = g_strndup(line, key - line + 1); -- value = g_strdup(value); -- -- if (!key || !value) { -- g_free(key); -- g_free(value); -- return -ENOMEM; -- } -- -- g_hash_table_insert(parser.current->kv, key, value); -- return 0; --} -- --static int process_smbconf_entry(char *data) --{ -- while (is_ascii_space_tab(*data)) -- data++; -- -- if (is_a_comment(data)) -- return 0; -- -- if (is_a_group(data)) -- return add_new_group(data); -- -- return add_group_key_value(data); --} -- --static int __mmap_parse_file(const char *fname, int (*callback)(char *data)) --{ -- GMappedFile *file; -- GError *err = NULL; -- gchar *contents; -- int len; -- char *delim; -- int fd, ret = 0; -- -- fd = g_open(fname, O_RDONLY, 0); -- if (fd == -1) { -- ret = -errno; -- pr_debug("Can't open `%s': %m\n", fname); -- return ret; -- } -- -- file = g_mapped_file_new_from_fd(fd, FALSE, &err); -- if (err) { -- pr_err("Can't map `%s' to memory: %s\n", fname, err->message); -- g_error_free(err); -- ret = -EINVAL; -- goto out; -- } -- -- contents = g_mapped_file_get_contents(file); -- if (!contents) -- goto out; -- -- len = g_mapped_file_get_length(file); -- while (len > 0) { -- delim = strchr(contents, '\n'); -- if (!delim) -- delim = contents + len - 1; -- -- if (delim) { -- size_t sz = delim - contents; -- char *data; -- -- if (delim == contents) { -- contents = delim + 1; -- len--; -- continue; -- } -- -- if (!sz) -- break; -- -- data = g_strndup(contents, sz); -- ret = callback(data); -- if (ret) { -- g_free(data); -- goto out; -- } -- -- g_free(data); -- contents = delim + 1; -- len -= (sz + 1); -- } -- } -- -- ret = 0; --out: -- if (file) -- g_mapped_file_unref(file); -- -- if (fd) { -- g_close(fd, &err); -- if (err) { -- pr_err("Can't close `%s': %s\n", fname, err->message); -- g_error_free(err); -- } -- } -- return ret; --} -- --static int init_smbconf_parser(void) --{ -- if (parser.groups) -- return 0; -- -- parser.groups = g_hash_table_new(shm_share_name_hash, -- shm_share_name_equal); -- if (!parser.groups) -- return -ENOMEM; -- return 0; --} -- --static void release_smbconf_group(gpointer k, gpointer v, gpointer user_data) --{ -- struct smbconf_group *g = v; -- -- g_hash_table_destroy(g->kv); -- g_free(g->name); -- g_free(g); --} -- --static void release_smbconf_parser(void) --{ -- if (!parser.groups) -- return; -- -- g_hash_table_foreach(parser.groups, release_smbconf_group, NULL); -- g_hash_table_destroy(parser.groups); -- parser.groups = NULL; --} -- --char *cp_ltrim(char *v) --{ -- if (!v) -- return NULL; -- -- while (*v && *v == ' ') -- v++; -- if (*v == 0x00) -- return NULL; -- return v; --} -- --int cp_key_cmp(char *k, char *v) --{ -- if (!k || !v) -- return -1; -- return g_ascii_strncasecmp(k, v, strlen(v)); --} -- --char *cp_get_group_kv_string(char *v) --{ -- return g_strdup(v); --} -- --int cp_get_group_kv_bool(char *v) --{ -- if (!g_ascii_strncasecmp(v, "yes", 3) || -- !g_ascii_strncasecmp(v, "1", 1) || -- !g_ascii_strncasecmp(v, "true", 4) || -- !g_ascii_strncasecmp(v, "enable", 6)) -- return 1; -- return 0; --} -- --int cp_get_group_kv_config_opt(char *v) --{ -- if (!g_ascii_strncasecmp(v, "disabled", 8)) -- return KSMBD_CONFIG_OPT_DISABLED; -- if (!g_ascii_strncasecmp(v, "enabled", 7)) -- return KSMBD_CONFIG_OPT_ENABLED; -- if (!g_ascii_strncasecmp(v, "auto", 4)) -- return KSMBD_CONFIG_OPT_AUTO; -- if (!g_ascii_strncasecmp(v, "mandatory", 9)) -- return KSMBD_CONFIG_OPT_MANDATORY; -- return KSMBD_CONFIG_OPT_DISABLED; --} -- --unsigned long cp_get_group_kv_long_base(char *v, int base) --{ -- return strtoul(v, NULL, base); --} -- --unsigned long cp_get_group_kv_long(char *v) --{ -- return cp_get_group_kv_long_base(v, 10); --} -- --char **cp_get_group_kv_list(char *v) --{ -- /* -- * SMB conf lists are "tabs, spaces, commas" separated. -- */ -- return g_strsplit_set(v, "\t ,", -1); --} -- --void cp_group_kv_list_free(char **list) --{ -- g_strfreev(list); --} -- --static int cp_add_global_guest_account(gpointer _v) --{ -- struct ksmbd_user *user; -- -- if (usm_add_new_user(cp_get_group_kv_string(_v), -- g_strdup("NULL"))) { -- pr_err("Unable to add guest account\n"); -- return -ENOMEM; -- } -- -- user = usm_lookup_user(_v); -- if (!user) { -- pr_err("Unable to find user `%s'\n", (char *) _v); -- return -EINVAL; -- } -- -- set_user_flag(user, KSMBD_USER_FLAG_GUEST_ACCOUNT); -- put_ksmbd_user(user); -- global_conf.guest_account = cp_get_group_kv_string(_v); -- return 0; --} -- --static gboolean global_group_kv(gpointer _k, gpointer _v, gpointer user_data) --{ -- if (!cp_key_cmp(_k, "server string")) { -- global_conf.server_string = cp_get_group_kv_string(_v); -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "workgroup")) { -- global_conf.work_group = cp_get_group_kv_string(_v); -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "netbios name")) { -- global_conf.netbios_name = cp_get_group_kv_string(_v); -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "server min protocol")) { -- global_conf.server_min_protocol = cp_get_group_kv_string(_v); -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "server signing")) { -- global_conf.server_signing = cp_get_group_kv_config_opt(_v); -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "server max protocol")) { -- global_conf.server_max_protocol = cp_get_group_kv_string(_v); -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "guest account")) { -- cp_add_global_guest_account(_v); -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "max active sessions")) { -- global_conf.sessions_cap = cp_get_group_kv_long(_v); -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "tcp port")) { -- if (!global_conf.tcp_port) -- global_conf.tcp_port = cp_get_group_kv_long(_v); -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "ipc timeout")) { -- global_conf.ipc_timeout = cp_get_group_kv_long(_v); -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "max open files")) { -- global_conf.file_max = cp_get_group_kv_long(_v); -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "restrict anonymous")) { -- global_conf.restrict_anon = cp_get_group_kv_long(_v); -- if (global_conf.restrict_anon > KSMBD_RESTRICT_ANON_TYPE_2 || -- global_conf.restrict_anon < 0) { -- global_conf.restrict_anon = 0; -- pr_err("Invalid restrict anonymous value\n"); -- } -- -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "map to guest")) { -- global_conf.map_to_guest = KSMBD_CONF_MAP_TO_GUEST_NEVER; -- if (!cp_key_cmp(_v, "bad user")) -- global_conf.map_to_guest = -- KSMBD_CONF_MAP_TO_GUEST_BAD_USER; -- if (!cp_key_cmp(_v, "bad password")) -- global_conf.map_to_guest = -- KSMBD_CONF_MAP_TO_GUEST_BAD_PASSWORD; -- if (!cp_key_cmp(_v, "bad uid")) -- global_conf.map_to_guest = -- KSMBD_CONF_MAP_TO_GUEST_BAD_UID; -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "bind interfaces only")) { -- global_conf.bind_interfaces_only = cp_get_group_kv_bool(_v); -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "interfaces")) { -- global_conf.interfaces = cp_get_group_kv_list(_v); -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "deadtime")) { -- global_conf.deadtime = cp_get_group_kv_long(_v); -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "smb2 leases")) { -- if (cp_get_group_kv_bool(_v)) -- global_conf.flags |= KSMBD_GLOBAL_FLAG_SMB2_LEASES; -- else -- global_conf.flags &= ~KSMBD_GLOBAL_FLAG_SMB2_LEASES; -- -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "root directory")) { -- global_conf.root_dir = cp_get_group_kv_string(_v); -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "smb2 max read")) { -- global_conf.smb2_max_read = memparse(_v); -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "smb2 max write")) { -- global_conf.smb2_max_write = memparse(_v); -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "smb2 max trans")) { -- global_conf.smb2_max_trans = memparse(_v); -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "smb3 encryption")) { -- if (cp_get_group_kv_bool(_v)) -- global_conf.flags |= KSMBD_GLOBAL_FLAG_SMB3_ENCRYPTION; -- else -- global_conf.flags &= ~KSMBD_GLOBAL_FLAG_SMB3_ENCRYPTION; -- -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "share:fake_fscaps")) { -- global_conf.share_fake_fscaps = cp_get_group_kv_long(_v); -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "kerberos service name")) { -- global_conf.krb5_service_name = cp_get_group_kv_string(_v); -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "kerberos keytab file")) { -- global_conf.krb5_keytab_file = cp_get_group_kv_string(_v); -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "server multi channel support")) { -- if (cp_get_group_kv_bool(_v)) -- global_conf.flags |= KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL; -- else -- global_conf.flags &= ~KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL; -- -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "smb2 max credits")) { -- global_conf.smb2_max_credits = memparse(_v); -- return TRUE; -- } -- -- if (!cp_key_cmp(_k, "smbd max io size")) { -- global_conf.smbd_max_io_size = memparse(_v); -- return TRUE; -- } -- -- /* At this point, this is an option that must be applied to all shares */ -- return FALSE; --} -- --static void global_conf_default(void) --{ -- /* The SPARSE_FILES file system capability flag is set by default */ -- global_conf.share_fake_fscaps = 64; --} -- --static void global_conf_create(void) --{ -- if (!global_group || global_group->cb_mode != GROUPS_CALLBACK_INIT) -- return; -- -- /* -- * This will transfer server options to global_conf, and leave behind -- * in the global parser group, the options that must be applied to every -- * share -- */ -- g_hash_table_foreach_remove(global_group->kv, global_group_kv, NULL); --} -- --static void append_key_value(gpointer _k, gpointer _v, gpointer user_data) --{ -- GHashTable *receiver = (GHashTable *)user_data; -- -- /* Don't override local share options */ -- if (!g_hash_table_lookup(receiver, _k)) -- g_hash_table_insert(receiver, g_strdup(_k), g_strdup(_v)); --} -- --static void global_conf_update(struct smbconf_group *group) --{ -- if (!global_group) -- return; -- -- g_hash_table_foreach(global_group->kv, append_key_value, group->kv); --} -- --static void global_conf_fixup_missing(void) --{ -- /* -- * Set default global parameters which were not specified -- * in smb.conf -- */ -- if (!global_conf.file_max) -- global_conf.file_max = KSMBD_CONF_FILE_MAX; -- if (!global_conf.server_string) -- global_conf.server_string = -- cp_get_group_kv_string( -- KSMBD_CONF_DEFAULT_SERVER_STRING); -- if (!global_conf.netbios_name) -- global_conf.netbios_name = -- cp_get_group_kv_string(KSMBD_CONF_DEFAULT_NETBIOS_NAME); -- if (!global_conf.work_group) -- global_conf.work_group = -- cp_get_group_kv_string(KSMBD_CONF_DEFAULT_WORK_GROUP); -- if (!global_conf.tcp_port) -- global_conf.tcp_port = KSMBD_CONF_DEFAULT_TCP_PORT; -- -- if (global_conf.sessions_cap <= 0) -- global_conf.sessions_cap = KSMBD_CONF_DEFAULT_SESS_CAP; -- -- if (!global_conf.guest_account && -- cp_add_global_guest_account(KSMBD_CONF_DEFAULT_GUEST_ACCOUNT)) -- pr_err("Unable to add guest account\n"); --} -- --static void groups_callback(gpointer _k, gpointer _v, gpointer user_data) --{ -- struct smbconf_group *group = (struct smbconf_group *)_v; -- unsigned short cb_mode = *(unsigned short *)user_data; -- -- if (group == global_group) -- return; -- -- group->cb_mode = cb_mode; -- -- if (group != ipc_group) -- global_conf_update(group); -- -- shm_add_new_share(group); --} -- --static int cp_add_ipc_group(void) --{ -- char *comment = NULL, *guest = NULL; -- int ret = 0; -- -- if (ipc_group) -- return ret; -- -- comment = g_strdup("comment = IPC share"); -- guest = g_strdup("guest ok = yes"); -- ret = add_new_group("[IPC$]"); -- ret |= add_group_key_value(comment); -- ret |= add_group_key_value(guest); -- if (ret) { -- pr_err("Unable to add IPC$ share\n"); -- ret = -EINVAL; -- goto out; -- } -- -- ipc_group = g_hash_table_lookup(parser.groups, "ipc$"); --out: -- g_free(comment); -- g_free(guest); -- return ret; --} -- --static int __cp_parse_smbconfig(const char *smbconf, GHFunc cb, -- unsigned short cb_mode) --{ -- int ret; -- -- global_conf_default(); -- -- ret = cp_smbconfig_hash_create(smbconf); -- if (ret) -- return ret; -- -- ret = cp_add_ipc_group(); -- if (ret) -- goto out; -- -- global_group = g_hash_table_lookup(parser.groups, "global"); -- if (global_group) -- global_group->cb_mode = cb_mode; -- -- global_conf_create(); -- g_hash_table_foreach(parser.groups, groups_callback, &cb_mode); -- global_conf_fixup_missing(); --out: -- cp_smbconfig_destroy(); -- return ret; --} -- --int cp_parse_reload_smbconf(const char *smbconf) --{ -- return __cp_parse_smbconfig(smbconf, groups_callback, -- GROUPS_CALLBACK_REINIT); --} -- --int cp_parse_smbconf(const char *smbconf) --{ -- return __cp_parse_smbconfig(smbconf, groups_callback, -- GROUPS_CALLBACK_INIT); --} -- --int cp_parse_pwddb(const char *pwddb) --{ -- return __mmap_parse_file(pwddb, usm_add_update_user_from_pwdentry); --} -- --int cp_smbconfig_hash_create(const char *smbconf) --{ -- int ret = init_smbconf_parser(); -- -- if (ret) -- return ret; -- return __mmap_parse_file(smbconf, process_smbconf_entry); --} -- --int cp_parse_subauth(void) --{ -- return __mmap_parse_file(PATH_SUBAUTH, usm_add_subauth_global_conf); --} -- --void cp_smbconfig_destroy(void) --{ -- release_smbconf_parser(); --} -- --int cp_parse_external_smbconf_group(char *name, char *opts) --{ -- char *pos; -- int i, len; -- -- if (init_smbconf_parser()) -- return -EINVAL; -- -- if (!opts || !name) -- return -EINVAL; -- -- len = strlen(opts); -- /* fake smb.conf input */ -- for (i = 0; i < KSMBD_SHARE_CONF_MAX; i++) { -- pos = strstr(opts, KSMBD_SHARE_CONF[i]); -- if (!pos) -- continue; -- if (pos != opts) -- *(pos - 1) = '\n'; -- } -- -- if (add_new_group(name)) -- goto error; -- -- /* split input and feed to normal process_smbconf_entry() */ -- while (len) { -- char *delim = strchr(opts, '\n'); -- -- if (delim) { -- *delim = 0x00; -- len -= delim - opts; -- } else { -- len = 0; -- } -- -- process_smbconf_entry(opts); -- if (delim) -- opts = delim + 1; -- } -- return 0; -- --error: -- cp_smbconfig_destroy(); -- return -EINVAL; --} ---- /dev/null -+++ b/tools/config_parser.c -@@ -0,0 +1,770 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Copyright (C) 2018 Samsung Electronics Co., Ltd. -+ * -+ * linux-cifsd-devel@lists.sourceforge.net -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+struct smbconf_global global_conf; -+struct smbconf_parser parser; -+struct smbconf_group *global_group, *ipc_group; -+ -+unsigned long long memparse(const char *v) -+{ -+ char *eptr; -+ -+ unsigned long long ret = strtoull(v, &eptr, 0); -+ -+ switch (*eptr) { -+ case 'E': -+ case 'e': -+ ret <<= 10; -+ case 'P': -+ case 'p': -+ ret <<= 10; -+ case 'T': -+ case 't': -+ ret <<= 10; -+ case 'G': -+ case 'g': -+ ret <<= 10; -+ case 'M': -+ case 'm': -+ ret <<= 10; -+ case 'K': -+ case 'k': -+ ret <<= 10; -+ } -+ -+ return ret; -+} -+ -+static void kv_release_cb(gpointer p) -+{ -+ g_free(p); -+} -+ -+static int is_ascii_space_tab(char c) -+{ -+ return c == ' ' || c == '\t'; -+} -+ -+static int is_a_comment(char *line) -+{ -+ return (*line == 0x00 || *line == ';' || *line == '\n' || *line == '#'); -+} -+ -+static int is_a_group(char *line) -+{ -+ char *p = line; -+ -+ if (*p != '[') -+ return 0; -+ p++; -+ while (*p && *p != ']') -+ p = g_utf8_find_next_char(p, NULL); -+ if (*p != ']') -+ return 0; -+ return 1; -+} -+ -+static int add_new_group(char *line) -+{ -+ char *begin = line; -+ char *end = line; -+ char *name = NULL; -+ struct smbconf_group *group = NULL; -+ struct smbconf_group *lookup; -+ -+ while (*end && *end != ']') -+ end = g_utf8_find_next_char(end, NULL); -+ -+ name = g_strndup(begin + 1, end - begin - 1); -+ if (!name) -+ goto out_free; -+ -+ lookup = g_hash_table_lookup(parser.groups, name); -+ if (lookup) { -+ parser.current = lookup; -+ pr_info("Multiple definitions for group `%s'\n", name); -+ g_free(name); -+ return 0; -+ } -+ -+ group = g_malloc(sizeof(struct smbconf_group)); -+ group->cb_mode = GROUPS_CALLBACK_NONE; -+ group->name = name; -+ group->kv = g_hash_table_new_full(g_str_hash, -+ g_str_equal, -+ kv_release_cb, -+ kv_release_cb); -+ if (!group->kv) -+ goto out_free; -+ -+ parser.current = group; -+ g_hash_table_insert(parser.groups, group->name, group); -+ return 0; -+ -+out_free: -+ g_free(name); -+ if (group && group->kv) -+ g_hash_table_destroy(group->kv); -+ g_free(group); -+ return -ENOMEM; -+} -+ -+static int add_group_key_value(char *line) -+{ -+ char *key, *value; -+ -+ key = strchr(line, '='); -+ if (!key) -+ return -EINVAL; -+ -+ value = key; -+ *key = 0x00; -+ key--; -+ value++; -+ -+ while (is_ascii_space_tab(*key)) -+ key--; -+ while (is_ascii_space_tab(*value)) -+ value++; -+ -+ if (is_a_comment(value)) -+ return 0; -+ -+ if (g_hash_table_lookup(parser.current->kv, key)) { -+ pr_info("Multiple key-value definitions [%s] %s\n", -+ parser.current->name, key); -+ return 0; -+ } -+ -+ key = g_strndup(line, key - line + 1); -+ value = g_strdup(value); -+ -+ if (!key || !value) { -+ g_free(key); -+ g_free(value); -+ return -ENOMEM; -+ } -+ -+ g_hash_table_insert(parser.current->kv, key, value); -+ return 0; -+} -+ -+static int process_smbconf_entry(char *data) -+{ -+ while (is_ascii_space_tab(*data)) -+ data++; -+ -+ if (is_a_comment(data)) -+ return 0; -+ -+ if (is_a_group(data)) -+ return add_new_group(data); -+ -+ return add_group_key_value(data); -+} -+ -+static int __mmap_parse_file(const char *fname, int (*callback)(char *data)) -+{ -+ GMappedFile *file; -+ GError *err = NULL; -+ gchar *contents; -+ int len; -+ char *delim; -+ int fd, ret = 0; -+ -+ fd = g_open(fname, O_RDONLY, 0); -+ if (fd == -1) { -+ ret = -errno; -+ pr_debug("Can't open `%s': %m\n", fname); -+ return ret; -+ } -+ -+ file = g_mapped_file_new_from_fd(fd, FALSE, &err); -+ if (err) { -+ pr_err("Can't map `%s' to memory: %s\n", fname, err->message); -+ g_error_free(err); -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ contents = g_mapped_file_get_contents(file); -+ if (!contents) -+ goto out; -+ -+ len = g_mapped_file_get_length(file); -+ while (len > 0) { -+ delim = strchr(contents, '\n'); -+ if (!delim) -+ delim = contents + len - 1; -+ -+ if (delim) { -+ size_t sz = delim - contents; -+ char *data; -+ -+ if (delim == contents) { -+ contents = delim + 1; -+ len--; -+ continue; -+ } -+ -+ if (!sz) -+ break; -+ -+ data = g_strndup(contents, sz); -+ ret = callback(data); -+ if (ret) { -+ g_free(data); -+ goto out; -+ } -+ -+ g_free(data); -+ contents = delim + 1; -+ len -= (sz + 1); -+ } -+ } -+ -+ ret = 0; -+out: -+ if (file) -+ g_mapped_file_unref(file); -+ -+ if (fd) { -+ g_close(fd, &err); -+ if (err) { -+ pr_err("Can't close `%s': %s\n", fname, err->message); -+ g_error_free(err); -+ } -+ } -+ return ret; -+} -+ -+static int init_smbconf_parser(void) -+{ -+ if (parser.groups) -+ return 0; -+ -+ parser.groups = g_hash_table_new(shm_share_name_hash, -+ shm_share_name_equal); -+ if (!parser.groups) -+ return -ENOMEM; -+ return 0; -+} -+ -+static void release_smbconf_group(gpointer k, gpointer v, gpointer user_data) -+{ -+ struct smbconf_group *g = v; -+ -+ g_hash_table_destroy(g->kv); -+ g_free(g->name); -+ g_free(g); -+} -+ -+static void release_smbconf_parser(void) -+{ -+ if (!parser.groups) -+ return; -+ -+ g_hash_table_foreach(parser.groups, release_smbconf_group, NULL); -+ g_hash_table_destroy(parser.groups); -+ parser.groups = NULL; -+} -+ -+char *cp_ltrim(char *v) -+{ -+ if (!v) -+ return NULL; -+ -+ while (*v && *v == ' ') -+ v++; -+ if (*v == 0x00) -+ return NULL; -+ return v; -+} -+ -+int cp_key_cmp(char *k, char *v) -+{ -+ if (!k || !v) -+ return -1; -+ return g_ascii_strncasecmp(k, v, strlen(v)); -+} -+ -+char *cp_get_group_kv_string(char *v) -+{ -+ return g_strdup(v); -+} -+ -+int cp_get_group_kv_bool(char *v) -+{ -+ if (!g_ascii_strncasecmp(v, "yes", 3) || -+ !g_ascii_strncasecmp(v, "1", 1) || -+ !g_ascii_strncasecmp(v, "true", 4) || -+ !g_ascii_strncasecmp(v, "enable", 6)) -+ return 1; -+ return 0; -+} -+ -+int cp_get_group_kv_config_opt(char *v) -+{ -+ if (!g_ascii_strncasecmp(v, "disabled", 8)) -+ return KSMBD_CONFIG_OPT_DISABLED; -+ if (!g_ascii_strncasecmp(v, "enabled", 7)) -+ return KSMBD_CONFIG_OPT_ENABLED; -+ if (!g_ascii_strncasecmp(v, "auto", 4)) -+ return KSMBD_CONFIG_OPT_AUTO; -+ if (!g_ascii_strncasecmp(v, "mandatory", 9)) -+ return KSMBD_CONFIG_OPT_MANDATORY; -+ return KSMBD_CONFIG_OPT_DISABLED; -+} -+ -+unsigned long cp_get_group_kv_long_base(char *v, int base) -+{ -+ return strtoul(v, NULL, base); -+} -+ -+unsigned long cp_get_group_kv_long(char *v) -+{ -+ return cp_get_group_kv_long_base(v, 10); -+} -+ -+char **cp_get_group_kv_list(char *v) -+{ -+ /* -+ * SMB conf lists are "tabs, spaces, commas" separated. -+ */ -+ return g_strsplit_set(v, "\t ,", -1); -+} -+ -+void cp_group_kv_list_free(char **list) -+{ -+ g_strfreev(list); -+} -+ -+static int cp_add_global_guest_account(gpointer _v) -+{ -+ struct ksmbd_user *user; -+ -+ if (usm_add_new_user(cp_get_group_kv_string(_v), -+ g_strdup("NULL"))) { -+ pr_err("Unable to add guest account\n"); -+ return -ENOMEM; -+ } -+ -+ user = usm_lookup_user(_v); -+ if (!user) { -+ pr_err("Unable to find user `%s'\n", (char *) _v); -+ return -EINVAL; -+ } -+ -+ set_user_flag(user, KSMBD_USER_FLAG_GUEST_ACCOUNT); -+ put_ksmbd_user(user); -+ global_conf.guest_account = cp_get_group_kv_string(_v); -+ return 0; -+} -+ -+static gboolean global_group_kv(gpointer _k, gpointer _v, gpointer user_data) -+{ -+ if (!cp_key_cmp(_k, "server string")) { -+ global_conf.server_string = cp_get_group_kv_string(_v); -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "workgroup")) { -+ global_conf.work_group = cp_get_group_kv_string(_v); -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "netbios name")) { -+ global_conf.netbios_name = cp_get_group_kv_string(_v); -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "server min protocol")) { -+ global_conf.server_min_protocol = cp_get_group_kv_string(_v); -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "server signing")) { -+ global_conf.server_signing = cp_get_group_kv_config_opt(_v); -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "server max protocol")) { -+ global_conf.server_max_protocol = cp_get_group_kv_string(_v); -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "guest account")) { -+ cp_add_global_guest_account(_v); -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "max active sessions")) { -+ global_conf.sessions_cap = cp_get_group_kv_long(_v); -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "tcp port")) { -+ if (!global_conf.tcp_port) -+ global_conf.tcp_port = cp_get_group_kv_long(_v); -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "ipc timeout")) { -+ global_conf.ipc_timeout = cp_get_group_kv_long(_v); -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "max open files")) { -+ global_conf.file_max = cp_get_group_kv_long(_v); -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "restrict anonymous")) { -+ global_conf.restrict_anon = cp_get_group_kv_long(_v); -+ if (global_conf.restrict_anon > KSMBD_RESTRICT_ANON_TYPE_2 || -+ global_conf.restrict_anon < 0) { -+ global_conf.restrict_anon = 0; -+ pr_err("Invalid restrict anonymous value\n"); -+ } -+ -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "map to guest")) { -+ global_conf.map_to_guest = KSMBD_CONF_MAP_TO_GUEST_NEVER; -+ if (!cp_key_cmp(_v, "bad user")) -+ global_conf.map_to_guest = -+ KSMBD_CONF_MAP_TO_GUEST_BAD_USER; -+ if (!cp_key_cmp(_v, "bad password")) -+ global_conf.map_to_guest = -+ KSMBD_CONF_MAP_TO_GUEST_BAD_PASSWORD; -+ if (!cp_key_cmp(_v, "bad uid")) -+ global_conf.map_to_guest = -+ KSMBD_CONF_MAP_TO_GUEST_BAD_UID; -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "bind interfaces only")) { -+ global_conf.bind_interfaces_only = cp_get_group_kv_bool(_v); -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "interfaces")) { -+ global_conf.interfaces = cp_get_group_kv_list(_v); -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "deadtime")) { -+ global_conf.deadtime = cp_get_group_kv_long(_v); -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "smb2 leases")) { -+ if (cp_get_group_kv_bool(_v)) -+ global_conf.flags |= KSMBD_GLOBAL_FLAG_SMB2_LEASES; -+ else -+ global_conf.flags &= ~KSMBD_GLOBAL_FLAG_SMB2_LEASES; -+ -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "root directory")) { -+ global_conf.root_dir = cp_get_group_kv_string(_v); -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "smb2 max read")) { -+ global_conf.smb2_max_read = memparse(_v); -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "smb2 max write")) { -+ global_conf.smb2_max_write = memparse(_v); -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "smb2 max trans")) { -+ global_conf.smb2_max_trans = memparse(_v); -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "smb3 encryption")) { -+ if (cp_get_group_kv_bool(_v)) -+ global_conf.flags |= KSMBD_GLOBAL_FLAG_SMB3_ENCRYPTION; -+ else -+ global_conf.flags &= ~KSMBD_GLOBAL_FLAG_SMB3_ENCRYPTION; -+ -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "share:fake_fscaps")) { -+ global_conf.share_fake_fscaps = cp_get_group_kv_long(_v); -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "kerberos service name")) { -+ global_conf.krb5_service_name = cp_get_group_kv_string(_v); -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "kerberos keytab file")) { -+ global_conf.krb5_keytab_file = cp_get_group_kv_string(_v); -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "server multi channel support")) { -+ if (cp_get_group_kv_bool(_v)) -+ global_conf.flags |= KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL; -+ else -+ global_conf.flags &= ~KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL; -+ -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "smb2 max credits")) { -+ global_conf.smb2_max_credits = memparse(_v); -+ return TRUE; -+ } -+ -+ if (!cp_key_cmp(_k, "smbd max io size")) { -+ global_conf.smbd_max_io_size = memparse(_v); -+ return TRUE; -+ } -+ -+ /* At this point, this is an option that must be applied to all shares */ -+ return FALSE; -+} -+ -+static void global_conf_default(void) -+{ -+ /* The SPARSE_FILES file system capability flag is set by default */ -+ global_conf.share_fake_fscaps = 64; -+} -+ -+static void global_conf_create(void) -+{ -+ if (!global_group || global_group->cb_mode != GROUPS_CALLBACK_INIT) -+ return; -+ -+ /* -+ * This will transfer server options to global_conf, and leave behind -+ * in the global parser group, the options that must be applied to every -+ * share -+ */ -+ g_hash_table_foreach_remove(global_group->kv, global_group_kv, NULL); -+} -+ -+static void append_key_value(gpointer _k, gpointer _v, gpointer user_data) -+{ -+ GHashTable *receiver = (GHashTable *)user_data; -+ -+ /* Don't override local share options */ -+ if (!g_hash_table_lookup(receiver, _k)) -+ g_hash_table_insert(receiver, g_strdup(_k), g_strdup(_v)); -+} -+ -+static void global_conf_update(struct smbconf_group *group) -+{ -+ if (!global_group) -+ return; -+ -+ g_hash_table_foreach(global_group->kv, append_key_value, group->kv); -+} -+ -+static void global_conf_fixup_missing(void) -+{ -+ /* -+ * Set default global parameters which were not specified -+ * in smb.conf -+ */ -+ if (!global_conf.file_max) -+ global_conf.file_max = KSMBD_CONF_FILE_MAX; -+ if (!global_conf.server_string) -+ global_conf.server_string = -+ cp_get_group_kv_string( -+ KSMBD_CONF_DEFAULT_SERVER_STRING); -+ if (!global_conf.netbios_name) -+ global_conf.netbios_name = -+ cp_get_group_kv_string(KSMBD_CONF_DEFAULT_NETBIOS_NAME); -+ if (!global_conf.work_group) -+ global_conf.work_group = -+ cp_get_group_kv_string(KSMBD_CONF_DEFAULT_WORK_GROUP); -+ if (!global_conf.tcp_port) -+ global_conf.tcp_port = KSMBD_CONF_DEFAULT_TCP_PORT; -+ -+ if (global_conf.sessions_cap <= 0) -+ global_conf.sessions_cap = KSMBD_CONF_DEFAULT_SESS_CAP; -+ -+ if (!global_conf.guest_account && -+ cp_add_global_guest_account(KSMBD_CONF_DEFAULT_GUEST_ACCOUNT)) -+ pr_err("Unable to add guest account\n"); -+} -+ -+static void groups_callback(gpointer _k, gpointer _v, gpointer user_data) -+{ -+ struct smbconf_group *group = (struct smbconf_group *)_v; -+ unsigned short cb_mode = *(unsigned short *)user_data; -+ -+ if (group == global_group) -+ return; -+ -+ group->cb_mode = cb_mode; -+ -+ if (group != ipc_group) -+ global_conf_update(group); -+ -+ shm_add_new_share(group); -+} -+ -+static int cp_add_ipc_group(void) -+{ -+ char *comment = NULL, *guest = NULL; -+ int ret = 0; -+ -+ if (ipc_group) -+ return ret; -+ -+ comment = g_strdup("comment = IPC share"); -+ guest = g_strdup("guest ok = yes"); -+ ret = add_new_group("[IPC$]"); -+ ret |= add_group_key_value(comment); -+ ret |= add_group_key_value(guest); -+ if (ret) { -+ pr_err("Unable to add IPC$ share\n"); -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ ipc_group = g_hash_table_lookup(parser.groups, "ipc$"); -+out: -+ g_free(comment); -+ g_free(guest); -+ return ret; -+} -+ -+static int __cp_parse_smbconfig(const char *smbconf, GHFunc cb, -+ unsigned short cb_mode) -+{ -+ int ret; -+ -+ global_conf_default(); -+ -+ ret = cp_smbconfig_hash_create(smbconf); -+ if (ret) -+ return ret; -+ -+ ret = cp_add_ipc_group(); -+ if (ret) -+ goto out; -+ -+ global_group = g_hash_table_lookup(parser.groups, "global"); -+ if (global_group) -+ global_group->cb_mode = cb_mode; -+ -+ global_conf_create(); -+ g_hash_table_foreach(parser.groups, groups_callback, &cb_mode); -+ global_conf_fixup_missing(); -+out: -+ cp_smbconfig_destroy(); -+ return ret; -+} -+ -+int cp_parse_reload_smbconf(const char *smbconf) -+{ -+ return __cp_parse_smbconfig(smbconf, groups_callback, -+ GROUPS_CALLBACK_REINIT); -+} -+ -+int cp_parse_smbconf(const char *smbconf) -+{ -+ return __cp_parse_smbconfig(smbconf, groups_callback, -+ GROUPS_CALLBACK_INIT); -+} -+ -+int cp_parse_pwddb(const char *pwddb) -+{ -+ return __mmap_parse_file(pwddb, usm_add_update_user_from_pwdentry); -+} -+ -+int cp_smbconfig_hash_create(const char *smbconf) -+{ -+ int ret = init_smbconf_parser(); -+ -+ if (ret) -+ return ret; -+ return __mmap_parse_file(smbconf, process_smbconf_entry); -+} -+ -+int cp_parse_subauth(void) -+{ -+ return __mmap_parse_file(PATH_SUBAUTH, usm_add_subauth_global_conf); -+} -+ -+void cp_smbconfig_destroy(void) -+{ -+ release_smbconf_parser(); -+} -+ -+int cp_parse_external_smbconf_group(char *name, char *opts) -+{ -+ char *pos; -+ int i, len; -+ -+ if (init_smbconf_parser()) -+ return -EINVAL; -+ -+ if (!opts || !name) -+ return -EINVAL; -+ -+ len = strlen(opts); -+ /* fake smb.conf input */ -+ for (i = 0; i < KSMBD_SHARE_CONF_MAX; i++) { -+ pos = strstr(opts, KSMBD_SHARE_CONF[i]); -+ if (!pos) -+ continue; -+ if (pos != opts) -+ *(pos - 1) = '\n'; -+ } -+ -+ if (add_new_group(name)) -+ goto error; -+ -+ /* split input and feed to normal process_smbconf_entry() */ -+ while (len) { -+ char *delim = strchr(opts, '\n'); -+ -+ if (delim) { -+ *delim = 0x00; -+ len -= delim - opts; -+ } else { -+ len = 0; -+ } -+ -+ process_smbconf_entry(opts); -+ if (delim) -+ opts = delim + 1; -+ } -+ return 0; -+ -+error: -+ cp_smbconfig_destroy(); -+ return -EINVAL; -+} ---- a/lib/management/session.c -+++ /dev/null -@@ -1,235 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-or-later --/* -- * Copyright (C) 2018 Samsung Electronics Co., Ltd. -- * -- * linux-cifsd-devel@lists.sourceforge.net -- */ -- --#include --#include --#include -- --#include "linux/ksmbd_server.h" --#include "management/session.h" --#include "management/tree_conn.h" --#include "management/user.h" --#include "ksmbdtools.h" -- --static GHashTable *sessions_table; --static GRWLock sessions_table_lock; -- --static void __free_func(gpointer data, gpointer user_data) --{ -- struct ksmbd_tree_conn *tree_conn; -- -- tree_conn = (struct ksmbd_tree_conn *)data; -- tcm_tree_conn_free(tree_conn); --} -- --static void kill_ksmbd_session(struct ksmbd_session *sess) --{ -- g_list_foreach(sess->tree_conns, __free_func, NULL); -- g_list_free(sess->tree_conns); -- g_rw_lock_clear(&sess->update_lock); -- g_free(sess); --} -- --static struct ksmbd_session *new_ksmbd_session(unsigned long long id, -- struct ksmbd_user *user) --{ -- struct ksmbd_session *sess; -- -- sess = g_try_malloc0(sizeof(struct ksmbd_session)); -- if (!sess) -- return NULL; -- -- g_rw_lock_init(&sess->update_lock); -- sess->ref_counter = 1; -- sess->id = id; -- sess->user = user; -- return sess; --} -- --static void free_hash_entry(gpointer k, gpointer s, gpointer user_data) --{ -- kill_ksmbd_session(s); --} -- --static void sm_clear_sessions(void) --{ -- g_hash_table_foreach(sessions_table, free_hash_entry, NULL); --} -- --static int __sm_remove_session(struct ksmbd_session *sess) --{ -- int ret = -EINVAL; -- -- g_rw_lock_writer_lock(&sessions_table_lock); -- if (g_hash_table_remove(sessions_table, &sess->id)) -- ret = 0; -- g_rw_lock_writer_unlock(&sessions_table_lock); -- -- if (!ret) -- kill_ksmbd_session(sess); -- return ret; --} -- --static struct ksmbd_session *__get_session(struct ksmbd_session *sess) --{ -- struct ksmbd_session *ret = NULL; -- -- g_rw_lock_writer_lock(&sess->update_lock); -- if (sess->ref_counter != 0) { -- sess->ref_counter++; -- ret = sess; -- } else { -- ret = NULL; -- } -- g_rw_lock_writer_unlock(&sess->update_lock); -- return ret; --} -- --static void __put_session(struct ksmbd_session *sess) --{ -- int drop = 0; -- -- g_rw_lock_writer_lock(&sess->update_lock); -- sess->ref_counter--; -- drop = !sess->ref_counter; -- g_rw_lock_writer_unlock(&sess->update_lock); -- -- if (drop) -- __sm_remove_session(sess); --} -- --static struct ksmbd_session *__sm_lookup_session(unsigned long long id) --{ -- return g_hash_table_lookup(sessions_table, &id); --} -- --static struct ksmbd_session *sm_lookup_session(unsigned long long id) --{ -- struct ksmbd_session *sess; -- -- g_rw_lock_reader_lock(&sessions_table_lock); -- sess = __sm_lookup_session(id); -- if (sess) -- sess = __get_session(sess); -- g_rw_lock_reader_unlock(&sessions_table_lock); -- return sess; --} -- --int sm_handle_tree_connect(unsigned long long id, -- struct ksmbd_user *user, -- struct ksmbd_tree_conn *tree_conn) --{ -- struct ksmbd_session *sess, *lookup; -- --retry: -- sess = sm_lookup_session(id); -- if (!sess) { -- sess = new_ksmbd_session(id, user); -- if (!sess) -- return -EINVAL; -- -- g_rw_lock_writer_lock(&sessions_table_lock); -- lookup = __sm_lookup_session(id); -- if (lookup) -- lookup = __get_session(lookup); -- if (lookup) { -- kill_ksmbd_session(sess); -- sess = lookup; -- } -- if (!g_hash_table_insert(sessions_table, &(sess->id), sess)) { -- kill_ksmbd_session(sess); -- sess = NULL; -- } -- g_rw_lock_writer_unlock(&sessions_table_lock); -- -- if (!sess) -- goto retry; -- } -- -- g_rw_lock_writer_lock(&sess->update_lock); -- sess->tree_conns = g_list_insert(sess->tree_conns, tree_conn, -1); -- g_rw_lock_writer_unlock(&sess->update_lock); -- return 0; --} -- --int sm_check_sessions_capacity(unsigned long long id) --{ -- int ret = 0; -- struct ksmbd_session *sess; -- -- sess = sm_lookup_session(id); -- if (sess) { -- __put_session(sess); -- return ret; -- } -- -- if (g_atomic_int_add(&global_conf.sessions_cap, -1) < 1) { -- ret = -EINVAL; -- g_atomic_int_inc(&global_conf.sessions_cap); -- } -- return ret; --} -- --static gint lookup_tree_conn(gconstpointer data, gconstpointer user_data) --{ -- struct ksmbd_tree_conn *tree_conn = (struct ksmbd_tree_conn *)data; -- struct ksmbd_tree_conn *dummy = (struct ksmbd_tree_conn *)user_data; -- -- if (tree_conn->id == dummy->id) -- return 0; -- return 1; --} -- --int sm_handle_tree_disconnect(unsigned long long sess_id, -- unsigned long long tree_conn_id) --{ -- struct ksmbd_tree_conn dummy; -- struct ksmbd_session *sess; -- GList *tc_list; -- -- sess = sm_lookup_session(sess_id); -- if (!sess) -- return 0; -- -- g_atomic_int_inc(&global_conf.sessions_cap); -- g_rw_lock_writer_lock(&sess->update_lock); -- dummy.id = tree_conn_id; -- tc_list = g_list_find_custom(sess->tree_conns, -- &dummy, -- lookup_tree_conn); -- if (tc_list) { -- struct ksmbd_tree_conn *tree_conn; -- -- tree_conn = (struct ksmbd_tree_conn *)tc_list->data; -- sess->tree_conns = g_list_remove(sess->tree_conns, tree_conn); -- sess->ref_counter--; -- tcm_tree_conn_free(tree_conn); -- } -- g_rw_lock_writer_unlock(&sess->update_lock); -- -- put_ksmbd_user(sess->user); -- __put_session(sess); -- return 0; --} -- --void sm_destroy(void) --{ -- if (sessions_table) { -- sm_clear_sessions(); -- g_hash_table_destroy(sessions_table); -- } -- g_rw_lock_clear(&sessions_table_lock); --} -- --int sm_init(void) --{ -- sessions_table = g_hash_table_new(g_int64_hash, g_int64_equal); -- if (!sessions_table) -- return -ENOMEM; -- g_rw_lock_init(&sessions_table_lock); -- return 0; --} ---- /dev/null -+++ b/tools/management/session.c -@@ -0,0 +1,235 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Copyright (C) 2018 Samsung Electronics Co., Ltd. -+ * -+ * linux-cifsd-devel@lists.sourceforge.net -+ */ -+ -+#include -+#include -+#include -+ -+#include "linux/ksmbd_server.h" -+#include "management/session.h" -+#include "management/tree_conn.h" -+#include "management/user.h" -+#include "tools.h" -+ -+static GHashTable *sessions_table; -+static GRWLock sessions_table_lock; -+ -+static void __free_func(gpointer data, gpointer user_data) -+{ -+ struct ksmbd_tree_conn *tree_conn; -+ -+ tree_conn = (struct ksmbd_tree_conn *)data; -+ tcm_tree_conn_free(tree_conn); -+} -+ -+static void kill_ksmbd_session(struct ksmbd_session *sess) -+{ -+ g_list_foreach(sess->tree_conns, __free_func, NULL); -+ g_list_free(sess->tree_conns); -+ g_rw_lock_clear(&sess->update_lock); -+ g_free(sess); -+} -+ -+static struct ksmbd_session *new_ksmbd_session(unsigned long long id, -+ struct ksmbd_user *user) -+{ -+ struct ksmbd_session *sess; -+ -+ sess = g_try_malloc0(sizeof(struct ksmbd_session)); -+ if (!sess) -+ return NULL; -+ -+ g_rw_lock_init(&sess->update_lock); -+ sess->ref_counter = 1; -+ sess->id = id; -+ sess->user = user; -+ return sess; -+} -+ -+static void free_hash_entry(gpointer k, gpointer s, gpointer user_data) -+{ -+ kill_ksmbd_session(s); -+} -+ -+static void sm_clear_sessions(void) -+{ -+ g_hash_table_foreach(sessions_table, free_hash_entry, NULL); -+} -+ -+static int __sm_remove_session(struct ksmbd_session *sess) -+{ -+ int ret = -EINVAL; -+ -+ g_rw_lock_writer_lock(&sessions_table_lock); -+ if (g_hash_table_remove(sessions_table, &sess->id)) -+ ret = 0; -+ g_rw_lock_writer_unlock(&sessions_table_lock); -+ -+ if (!ret) -+ kill_ksmbd_session(sess); -+ return ret; -+} -+ -+static struct ksmbd_session *__get_session(struct ksmbd_session *sess) -+{ -+ struct ksmbd_session *ret = NULL; -+ -+ g_rw_lock_writer_lock(&sess->update_lock); -+ if (sess->ref_counter != 0) { -+ sess->ref_counter++; -+ ret = sess; -+ } else { -+ ret = NULL; -+ } -+ g_rw_lock_writer_unlock(&sess->update_lock); -+ return ret; -+} -+ -+static void __put_session(struct ksmbd_session *sess) -+{ -+ int drop = 0; -+ -+ g_rw_lock_writer_lock(&sess->update_lock); -+ sess->ref_counter--; -+ drop = !sess->ref_counter; -+ g_rw_lock_writer_unlock(&sess->update_lock); -+ -+ if (drop) -+ __sm_remove_session(sess); -+} -+ -+static struct ksmbd_session *__sm_lookup_session(unsigned long long id) -+{ -+ return g_hash_table_lookup(sessions_table, &id); -+} -+ -+static struct ksmbd_session *sm_lookup_session(unsigned long long id) -+{ -+ struct ksmbd_session *sess; -+ -+ g_rw_lock_reader_lock(&sessions_table_lock); -+ sess = __sm_lookup_session(id); -+ if (sess) -+ sess = __get_session(sess); -+ g_rw_lock_reader_unlock(&sessions_table_lock); -+ return sess; -+} -+ -+int sm_handle_tree_connect(unsigned long long id, -+ struct ksmbd_user *user, -+ struct ksmbd_tree_conn *tree_conn) -+{ -+ struct ksmbd_session *sess, *lookup; -+ -+retry: -+ sess = sm_lookup_session(id); -+ if (!sess) { -+ sess = new_ksmbd_session(id, user); -+ if (!sess) -+ return -EINVAL; -+ -+ g_rw_lock_writer_lock(&sessions_table_lock); -+ lookup = __sm_lookup_session(id); -+ if (lookup) -+ lookup = __get_session(lookup); -+ if (lookup) { -+ kill_ksmbd_session(sess); -+ sess = lookup; -+ } -+ if (!g_hash_table_insert(sessions_table, &(sess->id), sess)) { -+ kill_ksmbd_session(sess); -+ sess = NULL; -+ } -+ g_rw_lock_writer_unlock(&sessions_table_lock); -+ -+ if (!sess) -+ goto retry; -+ } -+ -+ g_rw_lock_writer_lock(&sess->update_lock); -+ sess->tree_conns = g_list_insert(sess->tree_conns, tree_conn, -1); -+ g_rw_lock_writer_unlock(&sess->update_lock); -+ return 0; -+} -+ -+int sm_check_sessions_capacity(unsigned long long id) -+{ -+ int ret = 0; -+ struct ksmbd_session *sess; -+ -+ sess = sm_lookup_session(id); -+ if (sess) { -+ __put_session(sess); -+ return ret; -+ } -+ -+ if (g_atomic_int_add(&global_conf.sessions_cap, -1) < 1) { -+ ret = -EINVAL; -+ g_atomic_int_inc(&global_conf.sessions_cap); -+ } -+ return ret; -+} -+ -+static gint lookup_tree_conn(gconstpointer data, gconstpointer user_data) -+{ -+ struct ksmbd_tree_conn *tree_conn = (struct ksmbd_tree_conn *)data; -+ struct ksmbd_tree_conn *dummy = (struct ksmbd_tree_conn *)user_data; -+ -+ if (tree_conn->id == dummy->id) -+ return 0; -+ return 1; -+} -+ -+int sm_handle_tree_disconnect(unsigned long long sess_id, -+ unsigned long long tree_conn_id) -+{ -+ struct ksmbd_tree_conn dummy; -+ struct ksmbd_session *sess; -+ GList *tc_list; -+ -+ sess = sm_lookup_session(sess_id); -+ if (!sess) -+ return 0; -+ -+ g_atomic_int_inc(&global_conf.sessions_cap); -+ g_rw_lock_writer_lock(&sess->update_lock); -+ dummy.id = tree_conn_id; -+ tc_list = g_list_find_custom(sess->tree_conns, -+ &dummy, -+ lookup_tree_conn); -+ if (tc_list) { -+ struct ksmbd_tree_conn *tree_conn; -+ -+ tree_conn = (struct ksmbd_tree_conn *)tc_list->data; -+ sess->tree_conns = g_list_remove(sess->tree_conns, tree_conn); -+ sess->ref_counter--; -+ tcm_tree_conn_free(tree_conn); -+ } -+ g_rw_lock_writer_unlock(&sess->update_lock); -+ -+ put_ksmbd_user(sess->user); -+ __put_session(sess); -+ return 0; -+} -+ -+void sm_destroy(void) -+{ -+ if (sessions_table) { -+ sm_clear_sessions(); -+ g_hash_table_destroy(sessions_table); -+ } -+ g_rw_lock_clear(&sessions_table_lock); -+} -+ -+int sm_init(void) -+{ -+ sessions_table = g_hash_table_new(g_int64_hash, g_int64_equal); -+ if (!sessions_table) -+ return -ENOMEM; -+ g_rw_lock_init(&sessions_table_lock); -+ return 0; -+} ---- a/lib/management/share.c -+++ /dev/null -@@ -1,868 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-or-later --/* -- * Copyright (C) 2018 Samsung Electronics Co., Ltd. -- * -- * linux-cifsd-devel@lists.sourceforge.net -- */ -- --#include --#include --#include --#include --#include --#include -- --#include "config_parser.h" --#include "linux/ksmbd_server.h" --#include "management/share.h" --#include "management/user.h" --#include "ksmbdtools.h" -- --#define KSMBD_SHARE_STATE_FREEING 1 -- --/* -- * WARNING: -- * -- * This must match KSMBD_SHARE_CONF enum 1:1. -- * Add new entries ONLY to the bottom. -- */ --char *KSMBD_SHARE_CONF[KSMBD_SHARE_CONF_MAX] = { -- "comment", /* 0 */ -- "path", -- "guest ok", -- "guest account", -- "read only", -- "browseable", /* 5 */ -- "write ok", -- "writeable", -- "store dos attributes", -- "oplocks", -- "create mask", /* 10 */ -- "directory mask", -- "force create mode", -- "force directory mode", -- "force group", -- "force user", /* 15 */ -- "hide dot files", -- "valid users", -- "invalid users", -- "read list", -- "write list", /* 20 */ -- "admin users", -- "hosts allow", -- "hosts deny", -- "max connections", -- "veto files", /* 25 */ -- "inherit owner", -- "follow symlinks", -- "vfs objects", -- "writable", --}; -- --static GHashTable *shares_table; --static GRWLock shares_table_lock; -- --int shm_share_config(char *k, enum KSMBD_SHARE_CONF c) --{ -- if (c >= KSMBD_SHARE_CONF_MAX) -- return 0; -- -- return !cp_key_cmp(k, KSMBD_SHARE_CONF[c]); --} -- --static void list_hosts_callback(gpointer k, gpointer v, gpointer user_data) --{ -- free(k); -- free(v); --} -- --static void free_hosts_map(GHashTable *map) --{ -- if (map) { -- g_hash_table_foreach(map, list_hosts_callback, NULL); -- g_hash_table_destroy(map); -- } --} -- --static void list_user_callback(gpointer k, gpointer u, gpointer user_data) --{ -- put_ksmbd_user((struct ksmbd_user *)u); --} -- --static void free_user_map(GHashTable *map) --{ -- if (map) { -- g_hash_table_foreach(map, list_user_callback, NULL); -- g_hash_table_destroy(map); -- } --} -- --static void kill_ksmbd_share(struct ksmbd_share *share) --{ -- int i; -- -- pr_debug("Kill share `%s'\n", share->name); -- -- for (i = 0; i < KSMBD_SHARE_USERS_MAX; i++) -- free_user_map(share->maps[i]); -- -- free_hosts_map(share->hosts_allow_map); -- free_hosts_map(share->hosts_deny_map); -- -- g_rw_lock_clear(&share->maps_lock); -- -- free(share->name); -- free(share->path); -- free(share->comment); -- free(share->veto_list); -- free(share->guest_account); -- g_rw_lock_clear(&share->update_lock); -- g_free(share); --} -- --static int __shm_remove_share(struct ksmbd_share *share) --{ -- int ret = 0; -- -- if (share->state != KSMBD_SHARE_STATE_FREEING) { -- g_rw_lock_writer_lock(&shares_table_lock); -- if (!g_hash_table_remove(shares_table, share->name)) -- ret = -EINVAL; -- g_rw_lock_writer_unlock(&shares_table_lock); -- } -- if (!ret) -- kill_ksmbd_share(share); -- return ret; --} -- --struct ksmbd_share *get_ksmbd_share(struct ksmbd_share *share) --{ -- g_rw_lock_writer_lock(&share->update_lock); -- if (share->ref_count != 0) { -- share->ref_count++; -- g_rw_lock_writer_unlock(&share->update_lock); -- } else { -- g_rw_lock_writer_unlock(&share->update_lock); -- share = NULL; -- } -- -- return share; --} -- --void put_ksmbd_share(struct ksmbd_share *share) --{ -- int drop; -- -- if (!share) -- return; -- -- g_rw_lock_writer_lock(&share->update_lock); -- share->ref_count--; -- drop = !share->ref_count; -- g_rw_lock_writer_unlock(&share->update_lock); -- -- if (!drop) -- return; -- -- __shm_remove_share(share); --} -- --static gboolean put_share_callback(gpointer _k, gpointer _v, gpointer data) --{ -- struct ksmbd_share *share = (struct ksmbd_share *)_v; -- -- share->state = KSMBD_SHARE_STATE_FREEING; -- put_ksmbd_share(share); -- return TRUE; --} -- --void shm_remove_all_shares(void) --{ -- g_rw_lock_writer_lock(&shares_table_lock); -- g_hash_table_foreach_remove(shares_table, put_share_callback, NULL); -- g_rw_lock_writer_unlock(&shares_table_lock); --} -- --static struct ksmbd_share *new_ksmbd_share(void) --{ -- struct ksmbd_share *share; -- int i; -- -- share = g_try_malloc0(sizeof(struct ksmbd_share)); -- if (!share) -- return NULL; -- -- share->ref_count = 1; -- /* -- * Create maps as needed. NULL maps means that share -- * does not have a corresponding shmbconf entry. -- */ -- for (i = 0; i < KSMBD_SHARE_USERS_MAX; i++) -- share->maps[i] = NULL; -- -- share->hosts_allow_map = NULL; -- share->hosts_deny_map = NULL; -- g_rw_lock_init(&share->maps_lock); -- g_rw_lock_init(&share->update_lock); -- -- return share; --} -- --static void free_hash_entry(gpointer k, gpointer s, gpointer user_data) --{ -- kill_ksmbd_share(s); --} -- --static void shm_clear_shares(void) --{ -- g_hash_table_foreach(shares_table, free_hash_entry, NULL); --} -- --void shm_destroy(void) --{ -- if (shares_table) { -- shm_clear_shares(); -- g_hash_table_destroy(shares_table); -- } -- g_rw_lock_clear(&shares_table_lock); --} -- --static char *shm_casefold_share_name(const char *name, size_t len) --{ -- char *nfdi_name, *nfdicf_name; -- -- nfdi_name = g_utf8_normalize(name, len, G_NORMALIZE_NFD); -- if (!nfdi_name) -- goto out_ascii; -- -- nfdicf_name = g_utf8_casefold(nfdi_name, strlen(nfdi_name)); -- g_free(nfdi_name); -- return nfdicf_name; --out_ascii: -- g_free(nfdi_name); -- return g_ascii_strdown(name, len); --} -- --guint shm_share_name_hash(gconstpointer name) --{ -- char *cf_name; -- guint hash; -- -- cf_name = shm_casefold_share_name(name, strlen(name)); -- hash = g_str_hash(cf_name); -- g_free(cf_name); -- return hash; --} -- --gboolean shm_share_name_equal(gconstpointer lname, gconstpointer rname) --{ -- char *cf_lname, *cf_rname; -- gboolean equal; -- -- cf_lname = shm_casefold_share_name(lname, strlen(lname)); -- cf_rname = shm_casefold_share_name(rname, strlen(rname)); -- equal = g_str_equal(cf_lname, cf_rname); -- g_free(cf_lname); -- g_free(cf_rname); -- return equal; --} -- --int shm_init(void) --{ -- shares_table = g_hash_table_new(shm_share_name_hash, -- shm_share_name_equal); -- if (!shares_table) -- return -ENOMEM; -- g_rw_lock_init(&shares_table_lock); -- return 0; --} -- --static struct ksmbd_share *__shm_lookup_share(char *name) --{ -- return g_hash_table_lookup(shares_table, name); --} -- --struct ksmbd_share *shm_lookup_share(char *name) --{ -- struct ksmbd_share *share, *ret; -- -- g_rw_lock_reader_lock(&shares_table_lock); -- share = __shm_lookup_share(name); -- if (share) { -- ret = get_ksmbd_share(share); -- if (!ret) -- share = NULL; -- } -- g_rw_lock_reader_unlock(&shares_table_lock); -- return share; --} -- --static GHashTable *parse_list(GHashTable *map, char **list, char grc) --{ -- int i; -- -- if (!list) -- return map; -- -- if (!map) -- map = g_hash_table_new(g_str_hash, g_str_equal); -- if (!map) -- return map; -- -- for (i = 0; list[i] != NULL; i++) { -- struct ksmbd_user *user; -- char *p = list[i]; -- -- p = cp_ltrim(p); -- if (!p) -- continue; -- -- if (*p == grc) { -- struct group *gr; -- -- gr = getgrnam(p + 1); -- if (gr) -- parse_list(map, gr->gr_mem, 0x00); -- continue; -- } -- -- user = usm_lookup_user(p); -- if (!user) { -- pr_info("Drop non-existing user `%s'\n", p); -- continue; -- } -- -- if (g_hash_table_lookup(map, user->name)) { -- pr_debug("User `%s' already exists in a map\n", -- user->name); -- continue; -- } -- -- g_hash_table_insert(map, user->name, user); -- } -- -- return map; --} -- --static void make_veto_list(struct ksmbd_share *share) --{ -- int i; -- -- for (i = 0; i < share->veto_list_sz; i++) { -- if (share->veto_list[i] == '/') -- share->veto_list[i] = 0x00; -- } --} -- --static void force_group(struct ksmbd_share *share, char *name) --{ -- struct group *grp; -- -- grp = getgrnam(name); -- if (grp) { -- share->force_gid = grp->gr_gid; -- if (share->force_gid == KSMBD_SHARE_INVALID_GID) -- pr_err("Invalid force GID: %u\n", share->force_gid); -- } else -- pr_err("Unable to lookup up `/etc/group' entry: %s\n", name); --} -- --static void force_user(struct ksmbd_share *share, char *name) --{ -- struct passwd *passwd; -- -- passwd = getpwnam(name); -- if (passwd) { -- share->force_uid = passwd->pw_uid; -- /* -- * smb.conf 'force group' has higher priority than -- * 'force user'. -- */ -- if (share->force_gid == KSMBD_SHARE_INVALID_GID) -- share->force_gid = passwd->pw_gid; -- if (share->force_uid == KSMBD_SHARE_INVALID_UID || -- share->force_gid == KSMBD_SHARE_INVALID_GID) -- pr_err("Invalid force UID/GID: %u/%u\n", -- share->force_uid, share->force_gid); -- } else { -- pr_err("Unable to lookup up `/etc/passwd' entry: %s\n", name); -- } --} -- --static void process_group_kv(gpointer _k, gpointer _v, gpointer user_data) --{ -- struct ksmbd_share *share = user_data; -- char *k = _k; -- char *v = _v; -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_COMMENT)) { -- share->comment = cp_get_group_kv_string(v); -- if (share->comment == NULL) -- set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_PATH)) { -- share->path = cp_get_group_kv_string(v); -- if (share->path == NULL) -- set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_GUEST_OK)) { -- if (cp_get_group_kv_bool(v)) -- set_share_flag(share, KSMBD_SHARE_FLAG_GUEST_OK); -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_GUEST_ACCOUNT)) { -- struct ksmbd_user *user; -- -- if (usm_add_new_user(cp_get_group_kv_string(_v), -- g_strdup("NULL"))) { -- pr_err("Unable to add guest account\n"); -- set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -- return; -- } -- -- user = usm_lookup_user(_v); -- if (user) { -- set_user_flag(user, KSMBD_USER_FLAG_GUEST_ACCOUNT); -- put_ksmbd_user(user); -- } -- share->guest_account = cp_get_group_kv_string(_v); -- if (!share->guest_account) -- set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_READ_ONLY)) { -- if (cp_get_group_kv_bool(v)) { -- set_share_flag(share, KSMBD_SHARE_FLAG_READONLY); -- clear_share_flag(share, KSMBD_SHARE_FLAG_WRITEABLE); -- } else { -- clear_share_flag(share, KSMBD_SHARE_FLAG_READONLY); -- set_share_flag(share, KSMBD_SHARE_FLAG_WRITEABLE); -- } -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_BROWSEABLE)) { -- if (cp_get_group_kv_bool(v)) -- set_share_flag(share, KSMBD_SHARE_FLAG_BROWSEABLE); -- else -- clear_share_flag(share, KSMBD_SHARE_FLAG_BROWSEABLE); -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_WRITE_OK) || -- shm_share_config(k, KSMBD_SHARE_CONF_WRITEABLE) || -- shm_share_config(k, KSMBD_SHARE_CONF_WRITABLE)) { -- if (cp_get_group_kv_bool(v)) -- set_share_flag(share, KSMBD_SHARE_FLAG_WRITEABLE); -- else -- clear_share_flag(share, KSMBD_SHARE_FLAG_WRITEABLE); -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_STORE_DOS_ATTRIBUTES)) { -- if (cp_get_group_kv_bool(v)) -- set_share_flag(share, KSMBD_SHARE_FLAG_STORE_DOS_ATTRS); -- else -- clear_share_flag(share, -- KSMBD_SHARE_FLAG_STORE_DOS_ATTRS); -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_OPLOCKS)) { -- if (cp_get_group_kv_bool(v)) -- set_share_flag(share, KSMBD_SHARE_FLAG_OPLOCKS); -- else -- clear_share_flag(share, KSMBD_SHARE_FLAG_OPLOCKS); -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_CREATE_MASK)) { -- share->create_mask = cp_get_group_kv_long_base(v, 8); -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_DIRECTORY_MASK)) { -- share->directory_mask = cp_get_group_kv_long_base(v, 8); -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_FORCE_CREATE_MODE)) { -- share->force_create_mode = cp_get_group_kv_long_base(v, 8); -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_FORCE_DIRECTORY_MODE)) { -- share->force_directory_mode = cp_get_group_kv_long_base(v, 8); -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_FORCE_GROUP)) { -- force_group(share, v); -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_FORCE_USER)) { -- force_user(share, v); -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_HIDE_DOT_FILES)) { -- if (cp_get_group_kv_bool(v)) -- set_share_flag(share, KSMBD_SHARE_FLAG_HIDE_DOT_FILES); -- else -- clear_share_flag(share, -- KSMBD_SHARE_FLAG_HIDE_DOT_FILES); -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_VALID_USERS)) { -- char **users_list; -- -- users_list = cp_get_group_kv_list(v); -- share->maps[KSMBD_SHARE_VALID_USERS_MAP] = -- parse_list(share->maps[KSMBD_SHARE_VALID_USERS_MAP], -- users_list, '@'); -- if (share->maps[KSMBD_SHARE_VALID_USERS_MAP] == NULL) -- set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -- cp_group_kv_list_free(users_list); -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_INVALID_USERS)) { -- char **users_list; -- -- users_list = cp_get_group_kv_list(v); -- share->maps[KSMBD_SHARE_INVALID_USERS_MAP] = -- parse_list(share->maps[KSMBD_SHARE_INVALID_USERS_MAP], -- users_list, '@'); -- if (share->maps[KSMBD_SHARE_INVALID_USERS_MAP] == NULL) -- set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -- cp_group_kv_list_free(users_list); -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_READ_LIST)) { -- char **users_list; -- -- users_list = cp_get_group_kv_list(v); -- share->maps[KSMBD_SHARE_READ_LIST_MAP] = -- parse_list(share->maps[KSMBD_SHARE_READ_LIST_MAP], -- users_list, '@'); -- if (share->maps[KSMBD_SHARE_READ_LIST_MAP] == NULL) -- set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -- cp_group_kv_list_free(users_list); -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_WRITE_LIST)) { -- char **users_list; -- -- users_list = cp_get_group_kv_list(v); -- share->maps[KSMBD_SHARE_WRITE_LIST_MAP] = -- parse_list(share->maps[KSMBD_SHARE_WRITE_LIST_MAP], -- users_list, '@'); -- if (share->maps[KSMBD_SHARE_WRITE_LIST_MAP] == NULL) -- set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -- cp_group_kv_list_free(users_list); -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_ADMIN_USERS)) { -- char **users_list; -- -- users_list = cp_get_group_kv_list(v); -- share->maps[KSMBD_SHARE_ADMIN_USERS_MAP] = -- parse_list(share->maps[KSMBD_SHARE_ADMIN_USERS_MAP], -- users_list, '@'); -- if (share->maps[KSMBD_SHARE_ADMIN_USERS_MAP] == NULL) -- set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -- cp_group_kv_list_free(users_list); -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_HOSTS_ALLOW)) { -- char **hosts_list; -- -- hosts_list = cp_get_group_kv_list(v); -- share->hosts_allow_map = parse_list(share->hosts_allow_map, -- hosts_list, 0x00); -- if (share->hosts_allow_map == NULL) -- set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -- cp_group_kv_list_free(hosts_list); -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_HOSTS_DENY)) { -- char **hosts_list; -- -- hosts_list = cp_get_group_kv_list(v); -- share->hosts_deny_map = parse_list(share->hosts_deny_map, -- hosts_list, 0x00); -- if (share->hosts_deny_map == NULL) -- set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -- cp_group_kv_list_free(hosts_list); -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_MAX_CONNECTIONS)) { -- share->max_connections = cp_get_group_kv_long_base(v, 10); -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_VETO_FILES)) { -- share->veto_list = cp_get_group_kv_string(v + 1); -- if (share->veto_list == NULL) { -- set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -- } else { -- share->veto_list_sz = strlen(share->veto_list); -- make_veto_list(share); -- } -- return; -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_INHERIT_OWNER)) { -- if (cp_get_group_kv_bool(v)) -- set_share_flag(share, KSMBD_SHARE_FLAG_INHERIT_OWNER); -- else -- clear_share_flag(share, KSMBD_SHARE_FLAG_INHERIT_OWNER); -- } -- -- if (shm_share_config(k, KSMBD_SHARE_CONF_VFS_OBJECTS)) { -- char *p; -- int i; -- char **objects = cp_get_group_kv_list(v); -- -- if (objects) { -- clear_share_flag(share, KSMBD_SHARE_FLAG_ACL_XATTR); -- clear_share_flag(share, KSMBD_SHARE_FLAG_STREAMS); -- for (i = 0; objects[i] != NULL; i++) { -- p = cp_ltrim(objects[i]); -- if (!p) -- continue; -- if (!strcmp(p, "acl_xattr")) -- set_share_flag(share, KSMBD_SHARE_FLAG_ACL_XATTR); -- else if (!strcmp(p, "streams_xattr")) -- set_share_flag(share, KSMBD_SHARE_FLAG_STREAMS); -- } -- cp_group_kv_list_free(objects); -- } -- } -- --} -- --static void fixup_missing_fields(struct ksmbd_share *share) --{ -- if (!share->comment) -- share->comment = strdup(""); --} -- --static void init_share_from_group(struct ksmbd_share *share, -- struct smbconf_group *group) --{ -- share->name = g_strdup(group->name); -- share->create_mask = KSMBD_SHARE_DEFAULT_CREATE_MASK; -- share->directory_mask = KSMBD_SHARE_DEFAULT_DIRECTORY_MASK; -- share->force_create_mode = 0; -- share->force_directory_mode = 0; -- -- share->force_uid = KSMBD_SHARE_INVALID_UID; -- share->force_gid = KSMBD_SHARE_INVALID_GID; -- -- set_share_flag(share, KSMBD_SHARE_FLAG_AVAILABLE); -- set_share_flag(share, KSMBD_SHARE_FLAG_BROWSEABLE); -- set_share_flag(share, KSMBD_SHARE_FLAG_READONLY); -- set_share_flag(share, KSMBD_SHARE_FLAG_HIDE_DOT_FILES); -- set_share_flag(share, KSMBD_SHARE_FLAG_OPLOCKS); -- set_share_flag(share, KSMBD_SHARE_FLAG_STORE_DOS_ATTRS); -- -- if (!g_ascii_strcasecmp(share->name, "ipc$")) -- set_share_flag(share, KSMBD_SHARE_FLAG_PIPE); -- -- if (group->cb_mode == GROUPS_CALLBACK_REINIT) -- set_share_flag(share, KSMBD_SHARE_FLAG_UPDATE); -- -- g_hash_table_foreach(group->kv, process_group_kv, share); -- -- fixup_missing_fields(share); --} -- --int shm_add_new_share(struct smbconf_group *group) --{ -- int ret = 0; -- struct ksmbd_share *share = new_ksmbd_share(); -- -- if (!share) -- return -ENOMEM; -- -- init_share_from_group(share, group); -- if (test_share_flag(share, KSMBD_SHARE_FLAG_INVALID)) { -- pr_err("Share `%s' is invalid\n", share->name); -- kill_ksmbd_share(share); -- return 0; -- } -- -- g_rw_lock_writer_lock(&shares_table_lock); -- if (__shm_lookup_share(share->name)) { -- g_rw_lock_writer_unlock(&shares_table_lock); -- pr_info("Share `%s' already exists\n", share->name); -- kill_ksmbd_share(share); -- return 0; -- } -- -- pr_debug("New share `%s'\n", share->name); -- if (!g_hash_table_insert(shares_table, share->name, share)) { -- kill_ksmbd_share(share); -- ret = -EINVAL; -- } -- g_rw_lock_writer_unlock(&shares_table_lock); -- return ret; --} -- --int shm_lookup_users_map(struct ksmbd_share *share, -- enum share_users map, -- char *name) --{ -- int ret = -ENOENT; -- -- if (map >= KSMBD_SHARE_USERS_MAX) { -- pr_err("Invalid users map index: %d\n", map); -- return 0; -- } -- -- if (!share->maps[map]) -- return -EINVAL; -- -- g_rw_lock_reader_lock(&share->maps_lock); -- if (g_hash_table_lookup(share->maps[map], name)) -- ret = 0; -- g_rw_lock_reader_unlock(&share->maps_lock); -- -- return ret; --} -- --/* -- * FIXME -- * Do a real hosts lookup. IP masks, etc. -- */ --int shm_lookup_hosts_map(struct ksmbd_share *share, -- enum share_hosts map, -- char *host) --{ -- GHashTable *lookup_map = NULL; -- int ret = -ENOENT; -- -- if (map >= KSMBD_SHARE_HOSTS_MAX) { -- pr_err("Invalid hosts map index: %d\n", map); -- return 0; -- } -- -- if (map == KSMBD_SHARE_HOSTS_ALLOW_MAP) -- lookup_map = share->hosts_allow_map; -- if (map == KSMBD_SHARE_HOSTS_DENY_MAP) -- lookup_map = share->hosts_deny_map; -- -- if (!lookup_map) -- return -EINVAL; -- -- g_rw_lock_reader_lock(&share->maps_lock); -- if (g_hash_table_lookup(lookup_map, host)) -- ret = 0; -- g_rw_lock_reader_unlock(&share->maps_lock); -- -- return ret; --} -- --int shm_open_connection(struct ksmbd_share *share) --{ -- int ret = 0; -- -- g_rw_lock_writer_lock(&share->update_lock); -- share->num_connections++; -- if (share->max_connections) { -- if (share->num_connections >= share->max_connections) -- ret = -EINVAL; -- } -- g_rw_lock_writer_unlock(&share->update_lock); -- return ret; --} -- --int shm_close_connection(struct ksmbd_share *share) --{ -- if (!share) -- return 0; -- -- g_rw_lock_writer_lock(&share->update_lock); -- share->num_connections--; -- g_rw_lock_writer_unlock(&share->update_lock); -- return 0; --} -- --void for_each_ksmbd_share(walk_shares cb, gpointer user_data) --{ -- g_rw_lock_reader_lock(&shares_table_lock); -- g_hash_table_foreach(shares_table, cb, user_data); -- g_rw_lock_reader_unlock(&shares_table_lock); --} -- --int shm_share_config_payload_size(struct ksmbd_share *share) --{ -- int sz = 1; -- -- if (share && !test_share_flag(share, KSMBD_SHARE_FLAG_PIPE)) { -- if (share->path) -- sz += strlen(share->path); -- if (global_conf.root_dir) -- sz += strlen(global_conf.root_dir) + 1; -- if (share->veto_list_sz) -- sz += share->veto_list_sz + 1; -- } -- -- return sz; --} -- --int shm_handle_share_config_request(struct ksmbd_share *share, -- struct ksmbd_share_config_response *resp) --{ -- unsigned char *config_payload; -- -- if (!share) -- return -EINVAL; -- -- resp->flags = share->flags; -- resp->create_mask = share->create_mask; -- resp->directory_mask = share->directory_mask; -- resp->force_create_mode = share->force_create_mode; -- resp->force_directory_mode = share->force_directory_mode; -- resp->force_uid = share->force_uid; -- resp->force_gid = share->force_gid; -- *resp->share_name = 0x00; -- strncat(resp->share_name, share->name, KSMBD_REQ_MAX_SHARE_NAME - 1); -- resp->veto_list_sz = share->veto_list_sz; -- -- if (test_share_flag(share, KSMBD_SHARE_FLAG_PIPE)) -- return 0; -- -- if (!share->path) -- return 0; -- -- config_payload = KSMBD_SHARE_CONFIG_VETO_LIST(resp); -- if (resp->veto_list_sz) { -- memcpy(config_payload, -- share->veto_list, -- resp->veto_list_sz); -- config_payload += resp->veto_list_sz + 1; -- } -- if (global_conf.root_dir) -- sprintf(config_payload, -- "%s%s", -- global_conf.root_dir, -- share->path); -- else -- sprintf(config_payload, "%s", share->path); -- return 0; --} ---- /dev/null -+++ b/tools/management/share.c -@@ -0,0 +1,868 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Copyright (C) 2018 Samsung Electronics Co., Ltd. -+ * -+ * linux-cifsd-devel@lists.sourceforge.net -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "config_parser.h" -+#include "linux/ksmbd_server.h" -+#include "management/share.h" -+#include "management/user.h" -+#include "tools.h" -+ -+#define KSMBD_SHARE_STATE_FREEING 1 -+ -+/* -+ * WARNING: -+ * -+ * This must match KSMBD_SHARE_CONF enum 1:1. -+ * Add new entries ONLY to the bottom. -+ */ -+char *KSMBD_SHARE_CONF[KSMBD_SHARE_CONF_MAX] = { -+ "comment", /* 0 */ -+ "path", -+ "guest ok", -+ "guest account", -+ "read only", -+ "browseable", /* 5 */ -+ "write ok", -+ "writeable", -+ "store dos attributes", -+ "oplocks", -+ "create mask", /* 10 */ -+ "directory mask", -+ "force create mode", -+ "force directory mode", -+ "force group", -+ "force user", /* 15 */ -+ "hide dot files", -+ "valid users", -+ "invalid users", -+ "read list", -+ "write list", /* 20 */ -+ "admin users", -+ "hosts allow", -+ "hosts deny", -+ "max connections", -+ "veto files", /* 25 */ -+ "inherit owner", -+ "follow symlinks", -+ "vfs objects", -+ "writable", -+}; -+ -+static GHashTable *shares_table; -+static GRWLock shares_table_lock; -+ -+int shm_share_config(char *k, enum KSMBD_SHARE_CONF c) -+{ -+ if (c >= KSMBD_SHARE_CONF_MAX) -+ return 0; -+ -+ return !cp_key_cmp(k, KSMBD_SHARE_CONF[c]); -+} -+ -+static void list_hosts_callback(gpointer k, gpointer v, gpointer user_data) -+{ -+ free(k); -+ free(v); -+} -+ -+static void free_hosts_map(GHashTable *map) -+{ -+ if (map) { -+ g_hash_table_foreach(map, list_hosts_callback, NULL); -+ g_hash_table_destroy(map); -+ } -+} -+ -+static void list_user_callback(gpointer k, gpointer u, gpointer user_data) -+{ -+ put_ksmbd_user((struct ksmbd_user *)u); -+} -+ -+static void free_user_map(GHashTable *map) -+{ -+ if (map) { -+ g_hash_table_foreach(map, list_user_callback, NULL); -+ g_hash_table_destroy(map); -+ } -+} -+ -+static void kill_ksmbd_share(struct ksmbd_share *share) -+{ -+ int i; -+ -+ pr_debug("Kill share `%s'\n", share->name); -+ -+ for (i = 0; i < KSMBD_SHARE_USERS_MAX; i++) -+ free_user_map(share->maps[i]); -+ -+ free_hosts_map(share->hosts_allow_map); -+ free_hosts_map(share->hosts_deny_map); -+ -+ g_rw_lock_clear(&share->maps_lock); -+ -+ free(share->name); -+ free(share->path); -+ free(share->comment); -+ free(share->veto_list); -+ free(share->guest_account); -+ g_rw_lock_clear(&share->update_lock); -+ g_free(share); -+} -+ -+static int __shm_remove_share(struct ksmbd_share *share) -+{ -+ int ret = 0; -+ -+ if (share->state != KSMBD_SHARE_STATE_FREEING) { -+ g_rw_lock_writer_lock(&shares_table_lock); -+ if (!g_hash_table_remove(shares_table, share->name)) -+ ret = -EINVAL; -+ g_rw_lock_writer_unlock(&shares_table_lock); -+ } -+ if (!ret) -+ kill_ksmbd_share(share); -+ return ret; -+} -+ -+struct ksmbd_share *get_ksmbd_share(struct ksmbd_share *share) -+{ -+ g_rw_lock_writer_lock(&share->update_lock); -+ if (share->ref_count != 0) { -+ share->ref_count++; -+ g_rw_lock_writer_unlock(&share->update_lock); -+ } else { -+ g_rw_lock_writer_unlock(&share->update_lock); -+ share = NULL; -+ } -+ -+ return share; -+} -+ -+void put_ksmbd_share(struct ksmbd_share *share) -+{ -+ int drop; -+ -+ if (!share) -+ return; -+ -+ g_rw_lock_writer_lock(&share->update_lock); -+ share->ref_count--; -+ drop = !share->ref_count; -+ g_rw_lock_writer_unlock(&share->update_lock); -+ -+ if (!drop) -+ return; -+ -+ __shm_remove_share(share); -+} -+ -+static gboolean put_share_callback(gpointer _k, gpointer _v, gpointer data) -+{ -+ struct ksmbd_share *share = (struct ksmbd_share *)_v; -+ -+ share->state = KSMBD_SHARE_STATE_FREEING; -+ put_ksmbd_share(share); -+ return TRUE; -+} -+ -+void shm_remove_all_shares(void) -+{ -+ g_rw_lock_writer_lock(&shares_table_lock); -+ g_hash_table_foreach_remove(shares_table, put_share_callback, NULL); -+ g_rw_lock_writer_unlock(&shares_table_lock); -+} -+ -+static struct ksmbd_share *new_ksmbd_share(void) -+{ -+ struct ksmbd_share *share; -+ int i; -+ -+ share = g_try_malloc0(sizeof(struct ksmbd_share)); -+ if (!share) -+ return NULL; -+ -+ share->ref_count = 1; -+ /* -+ * Create maps as needed. NULL maps means that share -+ * does not have a corresponding shmbconf entry. -+ */ -+ for (i = 0; i < KSMBD_SHARE_USERS_MAX; i++) -+ share->maps[i] = NULL; -+ -+ share->hosts_allow_map = NULL; -+ share->hosts_deny_map = NULL; -+ g_rw_lock_init(&share->maps_lock); -+ g_rw_lock_init(&share->update_lock); -+ -+ return share; -+} -+ -+static void free_hash_entry(gpointer k, gpointer s, gpointer user_data) -+{ -+ kill_ksmbd_share(s); -+} -+ -+static void shm_clear_shares(void) -+{ -+ g_hash_table_foreach(shares_table, free_hash_entry, NULL); -+} -+ -+void shm_destroy(void) -+{ -+ if (shares_table) { -+ shm_clear_shares(); -+ g_hash_table_destroy(shares_table); -+ } -+ g_rw_lock_clear(&shares_table_lock); -+} -+ -+static char *shm_casefold_share_name(const char *name, size_t len) -+{ -+ char *nfdi_name, *nfdicf_name; -+ -+ nfdi_name = g_utf8_normalize(name, len, G_NORMALIZE_NFD); -+ if (!nfdi_name) -+ goto out_ascii; -+ -+ nfdicf_name = g_utf8_casefold(nfdi_name, strlen(nfdi_name)); -+ g_free(nfdi_name); -+ return nfdicf_name; -+out_ascii: -+ g_free(nfdi_name); -+ return g_ascii_strdown(name, len); -+} -+ -+guint shm_share_name_hash(gconstpointer name) -+{ -+ char *cf_name; -+ guint hash; -+ -+ cf_name = shm_casefold_share_name(name, strlen(name)); -+ hash = g_str_hash(cf_name); -+ g_free(cf_name); -+ return hash; -+} -+ -+gboolean shm_share_name_equal(gconstpointer lname, gconstpointer rname) -+{ -+ char *cf_lname, *cf_rname; -+ gboolean equal; -+ -+ cf_lname = shm_casefold_share_name(lname, strlen(lname)); -+ cf_rname = shm_casefold_share_name(rname, strlen(rname)); -+ equal = g_str_equal(cf_lname, cf_rname); -+ g_free(cf_lname); -+ g_free(cf_rname); -+ return equal; -+} -+ -+int shm_init(void) -+{ -+ shares_table = g_hash_table_new(shm_share_name_hash, -+ shm_share_name_equal); -+ if (!shares_table) -+ return -ENOMEM; -+ g_rw_lock_init(&shares_table_lock); -+ return 0; -+} -+ -+static struct ksmbd_share *__shm_lookup_share(char *name) -+{ -+ return g_hash_table_lookup(shares_table, name); -+} -+ -+struct ksmbd_share *shm_lookup_share(char *name) -+{ -+ struct ksmbd_share *share, *ret; -+ -+ g_rw_lock_reader_lock(&shares_table_lock); -+ share = __shm_lookup_share(name); -+ if (share) { -+ ret = get_ksmbd_share(share); -+ if (!ret) -+ share = NULL; -+ } -+ g_rw_lock_reader_unlock(&shares_table_lock); -+ return share; -+} -+ -+static GHashTable *parse_list(GHashTable *map, char **list, char grc) -+{ -+ int i; -+ -+ if (!list) -+ return map; -+ -+ if (!map) -+ map = g_hash_table_new(g_str_hash, g_str_equal); -+ if (!map) -+ return map; -+ -+ for (i = 0; list[i] != NULL; i++) { -+ struct ksmbd_user *user; -+ char *p = list[i]; -+ -+ p = cp_ltrim(p); -+ if (!p) -+ continue; -+ -+ if (*p == grc) { -+ struct group *gr; -+ -+ gr = getgrnam(p + 1); -+ if (gr) -+ parse_list(map, gr->gr_mem, 0x00); -+ continue; -+ } -+ -+ user = usm_lookup_user(p); -+ if (!user) { -+ pr_info("Drop non-existing user `%s'\n", p); -+ continue; -+ } -+ -+ if (g_hash_table_lookup(map, user->name)) { -+ pr_debug("User `%s' already exists in a map\n", -+ user->name); -+ continue; -+ } -+ -+ g_hash_table_insert(map, user->name, user); -+ } -+ -+ return map; -+} -+ -+static void make_veto_list(struct ksmbd_share *share) -+{ -+ int i; -+ -+ for (i = 0; i < share->veto_list_sz; i++) { -+ if (share->veto_list[i] == '/') -+ share->veto_list[i] = 0x00; -+ } -+} -+ -+static void force_group(struct ksmbd_share *share, char *name) -+{ -+ struct group *grp; -+ -+ grp = getgrnam(name); -+ if (grp) { -+ share->force_gid = grp->gr_gid; -+ if (share->force_gid == KSMBD_SHARE_INVALID_GID) -+ pr_err("Invalid force GID: %u\n", share->force_gid); -+ } else -+ pr_err("Unable to lookup up `/etc/group' entry: %s\n", name); -+} -+ -+static void force_user(struct ksmbd_share *share, char *name) -+{ -+ struct passwd *passwd; -+ -+ passwd = getpwnam(name); -+ if (passwd) { -+ share->force_uid = passwd->pw_uid; -+ /* -+ * smb.conf 'force group' has higher priority than -+ * 'force user'. -+ */ -+ if (share->force_gid == KSMBD_SHARE_INVALID_GID) -+ share->force_gid = passwd->pw_gid; -+ if (share->force_uid == KSMBD_SHARE_INVALID_UID || -+ share->force_gid == KSMBD_SHARE_INVALID_GID) -+ pr_err("Invalid force UID/GID: %u/%u\n", -+ share->force_uid, share->force_gid); -+ } else { -+ pr_err("Unable to lookup up `/etc/passwd' entry: %s\n", name); -+ } -+} -+ -+static void process_group_kv(gpointer _k, gpointer _v, gpointer user_data) -+{ -+ struct ksmbd_share *share = user_data; -+ char *k = _k; -+ char *v = _v; -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_COMMENT)) { -+ share->comment = cp_get_group_kv_string(v); -+ if (share->comment == NULL) -+ set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_PATH)) { -+ share->path = cp_get_group_kv_string(v); -+ if (share->path == NULL) -+ set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_GUEST_OK)) { -+ if (cp_get_group_kv_bool(v)) -+ set_share_flag(share, KSMBD_SHARE_FLAG_GUEST_OK); -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_GUEST_ACCOUNT)) { -+ struct ksmbd_user *user; -+ -+ if (usm_add_new_user(cp_get_group_kv_string(_v), -+ g_strdup("NULL"))) { -+ pr_err("Unable to add guest account\n"); -+ set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -+ return; -+ } -+ -+ user = usm_lookup_user(_v); -+ if (user) { -+ set_user_flag(user, KSMBD_USER_FLAG_GUEST_ACCOUNT); -+ put_ksmbd_user(user); -+ } -+ share->guest_account = cp_get_group_kv_string(_v); -+ if (!share->guest_account) -+ set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_READ_ONLY)) { -+ if (cp_get_group_kv_bool(v)) { -+ set_share_flag(share, KSMBD_SHARE_FLAG_READONLY); -+ clear_share_flag(share, KSMBD_SHARE_FLAG_WRITEABLE); -+ } else { -+ clear_share_flag(share, KSMBD_SHARE_FLAG_READONLY); -+ set_share_flag(share, KSMBD_SHARE_FLAG_WRITEABLE); -+ } -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_BROWSEABLE)) { -+ if (cp_get_group_kv_bool(v)) -+ set_share_flag(share, KSMBD_SHARE_FLAG_BROWSEABLE); -+ else -+ clear_share_flag(share, KSMBD_SHARE_FLAG_BROWSEABLE); -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_WRITE_OK) || -+ shm_share_config(k, KSMBD_SHARE_CONF_WRITEABLE) || -+ shm_share_config(k, KSMBD_SHARE_CONF_WRITABLE)) { -+ if (cp_get_group_kv_bool(v)) -+ set_share_flag(share, KSMBD_SHARE_FLAG_WRITEABLE); -+ else -+ clear_share_flag(share, KSMBD_SHARE_FLAG_WRITEABLE); -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_STORE_DOS_ATTRIBUTES)) { -+ if (cp_get_group_kv_bool(v)) -+ set_share_flag(share, KSMBD_SHARE_FLAG_STORE_DOS_ATTRS); -+ else -+ clear_share_flag(share, -+ KSMBD_SHARE_FLAG_STORE_DOS_ATTRS); -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_OPLOCKS)) { -+ if (cp_get_group_kv_bool(v)) -+ set_share_flag(share, KSMBD_SHARE_FLAG_OPLOCKS); -+ else -+ clear_share_flag(share, KSMBD_SHARE_FLAG_OPLOCKS); -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_CREATE_MASK)) { -+ share->create_mask = cp_get_group_kv_long_base(v, 8); -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_DIRECTORY_MASK)) { -+ share->directory_mask = cp_get_group_kv_long_base(v, 8); -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_FORCE_CREATE_MODE)) { -+ share->force_create_mode = cp_get_group_kv_long_base(v, 8); -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_FORCE_DIRECTORY_MODE)) { -+ share->force_directory_mode = cp_get_group_kv_long_base(v, 8); -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_FORCE_GROUP)) { -+ force_group(share, v); -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_FORCE_USER)) { -+ force_user(share, v); -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_HIDE_DOT_FILES)) { -+ if (cp_get_group_kv_bool(v)) -+ set_share_flag(share, KSMBD_SHARE_FLAG_HIDE_DOT_FILES); -+ else -+ clear_share_flag(share, -+ KSMBD_SHARE_FLAG_HIDE_DOT_FILES); -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_VALID_USERS)) { -+ char **users_list; -+ -+ users_list = cp_get_group_kv_list(v); -+ share->maps[KSMBD_SHARE_VALID_USERS_MAP] = -+ parse_list(share->maps[KSMBD_SHARE_VALID_USERS_MAP], -+ users_list, '@'); -+ if (share->maps[KSMBD_SHARE_VALID_USERS_MAP] == NULL) -+ set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -+ cp_group_kv_list_free(users_list); -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_INVALID_USERS)) { -+ char **users_list; -+ -+ users_list = cp_get_group_kv_list(v); -+ share->maps[KSMBD_SHARE_INVALID_USERS_MAP] = -+ parse_list(share->maps[KSMBD_SHARE_INVALID_USERS_MAP], -+ users_list, '@'); -+ if (share->maps[KSMBD_SHARE_INVALID_USERS_MAP] == NULL) -+ set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -+ cp_group_kv_list_free(users_list); -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_READ_LIST)) { -+ char **users_list; -+ -+ users_list = cp_get_group_kv_list(v); -+ share->maps[KSMBD_SHARE_READ_LIST_MAP] = -+ parse_list(share->maps[KSMBD_SHARE_READ_LIST_MAP], -+ users_list, '@'); -+ if (share->maps[KSMBD_SHARE_READ_LIST_MAP] == NULL) -+ set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -+ cp_group_kv_list_free(users_list); -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_WRITE_LIST)) { -+ char **users_list; -+ -+ users_list = cp_get_group_kv_list(v); -+ share->maps[KSMBD_SHARE_WRITE_LIST_MAP] = -+ parse_list(share->maps[KSMBD_SHARE_WRITE_LIST_MAP], -+ users_list, '@'); -+ if (share->maps[KSMBD_SHARE_WRITE_LIST_MAP] == NULL) -+ set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -+ cp_group_kv_list_free(users_list); -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_ADMIN_USERS)) { -+ char **users_list; -+ -+ users_list = cp_get_group_kv_list(v); -+ share->maps[KSMBD_SHARE_ADMIN_USERS_MAP] = -+ parse_list(share->maps[KSMBD_SHARE_ADMIN_USERS_MAP], -+ users_list, '@'); -+ if (share->maps[KSMBD_SHARE_ADMIN_USERS_MAP] == NULL) -+ set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -+ cp_group_kv_list_free(users_list); -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_HOSTS_ALLOW)) { -+ char **hosts_list; -+ -+ hosts_list = cp_get_group_kv_list(v); -+ share->hosts_allow_map = parse_list(share->hosts_allow_map, -+ hosts_list, 0x00); -+ if (share->hosts_allow_map == NULL) -+ set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -+ cp_group_kv_list_free(hosts_list); -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_HOSTS_DENY)) { -+ char **hosts_list; -+ -+ hosts_list = cp_get_group_kv_list(v); -+ share->hosts_deny_map = parse_list(share->hosts_deny_map, -+ hosts_list, 0x00); -+ if (share->hosts_deny_map == NULL) -+ set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -+ cp_group_kv_list_free(hosts_list); -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_MAX_CONNECTIONS)) { -+ share->max_connections = cp_get_group_kv_long_base(v, 10); -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_VETO_FILES)) { -+ share->veto_list = cp_get_group_kv_string(v + 1); -+ if (share->veto_list == NULL) { -+ set_share_flag(share, KSMBD_SHARE_FLAG_INVALID); -+ } else { -+ share->veto_list_sz = strlen(share->veto_list); -+ make_veto_list(share); -+ } -+ return; -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_INHERIT_OWNER)) { -+ if (cp_get_group_kv_bool(v)) -+ set_share_flag(share, KSMBD_SHARE_FLAG_INHERIT_OWNER); -+ else -+ clear_share_flag(share, KSMBD_SHARE_FLAG_INHERIT_OWNER); -+ } -+ -+ if (shm_share_config(k, KSMBD_SHARE_CONF_VFS_OBJECTS)) { -+ char *p; -+ int i; -+ char **objects = cp_get_group_kv_list(v); -+ -+ if (objects) { -+ clear_share_flag(share, KSMBD_SHARE_FLAG_ACL_XATTR); -+ clear_share_flag(share, KSMBD_SHARE_FLAG_STREAMS); -+ for (i = 0; objects[i] != NULL; i++) { -+ p = cp_ltrim(objects[i]); -+ if (!p) -+ continue; -+ if (!strcmp(p, "acl_xattr")) -+ set_share_flag(share, KSMBD_SHARE_FLAG_ACL_XATTR); -+ else if (!strcmp(p, "streams_xattr")) -+ set_share_flag(share, KSMBD_SHARE_FLAG_STREAMS); -+ } -+ cp_group_kv_list_free(objects); -+ } -+ } -+ -+} -+ -+static void fixup_missing_fields(struct ksmbd_share *share) -+{ -+ if (!share->comment) -+ share->comment = strdup(""); -+} -+ -+static void init_share_from_group(struct ksmbd_share *share, -+ struct smbconf_group *group) -+{ -+ share->name = g_strdup(group->name); -+ share->create_mask = KSMBD_SHARE_DEFAULT_CREATE_MASK; -+ share->directory_mask = KSMBD_SHARE_DEFAULT_DIRECTORY_MASK; -+ share->force_create_mode = 0; -+ share->force_directory_mode = 0; -+ -+ share->force_uid = KSMBD_SHARE_INVALID_UID; -+ share->force_gid = KSMBD_SHARE_INVALID_GID; -+ -+ set_share_flag(share, KSMBD_SHARE_FLAG_AVAILABLE); -+ set_share_flag(share, KSMBD_SHARE_FLAG_BROWSEABLE); -+ set_share_flag(share, KSMBD_SHARE_FLAG_READONLY); -+ set_share_flag(share, KSMBD_SHARE_FLAG_HIDE_DOT_FILES); -+ set_share_flag(share, KSMBD_SHARE_FLAG_OPLOCKS); -+ set_share_flag(share, KSMBD_SHARE_FLAG_STORE_DOS_ATTRS); -+ -+ if (!g_ascii_strcasecmp(share->name, "ipc$")) -+ set_share_flag(share, KSMBD_SHARE_FLAG_PIPE); -+ -+ if (group->cb_mode == GROUPS_CALLBACK_REINIT) -+ set_share_flag(share, KSMBD_SHARE_FLAG_UPDATE); -+ -+ g_hash_table_foreach(group->kv, process_group_kv, share); -+ -+ fixup_missing_fields(share); -+} -+ -+int shm_add_new_share(struct smbconf_group *group) -+{ -+ int ret = 0; -+ struct ksmbd_share *share = new_ksmbd_share(); -+ -+ if (!share) -+ return -ENOMEM; -+ -+ init_share_from_group(share, group); -+ if (test_share_flag(share, KSMBD_SHARE_FLAG_INVALID)) { -+ pr_err("Share `%s' is invalid\n", share->name); -+ kill_ksmbd_share(share); -+ return 0; -+ } -+ -+ g_rw_lock_writer_lock(&shares_table_lock); -+ if (__shm_lookup_share(share->name)) { -+ g_rw_lock_writer_unlock(&shares_table_lock); -+ pr_info("Share `%s' already exists\n", share->name); -+ kill_ksmbd_share(share); -+ return 0; -+ } -+ -+ pr_debug("New share `%s'\n", share->name); -+ if (!g_hash_table_insert(shares_table, share->name, share)) { -+ kill_ksmbd_share(share); -+ ret = -EINVAL; -+ } -+ g_rw_lock_writer_unlock(&shares_table_lock); -+ return ret; -+} -+ -+int shm_lookup_users_map(struct ksmbd_share *share, -+ enum share_users map, -+ char *name) -+{ -+ int ret = -ENOENT; -+ -+ if (map >= KSMBD_SHARE_USERS_MAX) { -+ pr_err("Invalid users map index: %d\n", map); -+ return 0; -+ } -+ -+ if (!share->maps[map]) -+ return -EINVAL; -+ -+ g_rw_lock_reader_lock(&share->maps_lock); -+ if (g_hash_table_lookup(share->maps[map], name)) -+ ret = 0; -+ g_rw_lock_reader_unlock(&share->maps_lock); -+ -+ return ret; -+} -+ -+/* -+ * FIXME -+ * Do a real hosts lookup. IP masks, etc. -+ */ -+int shm_lookup_hosts_map(struct ksmbd_share *share, -+ enum share_hosts map, -+ char *host) -+{ -+ GHashTable *lookup_map = NULL; -+ int ret = -ENOENT; -+ -+ if (map >= KSMBD_SHARE_HOSTS_MAX) { -+ pr_err("Invalid hosts map index: %d\n", map); -+ return 0; -+ } -+ -+ if (map == KSMBD_SHARE_HOSTS_ALLOW_MAP) -+ lookup_map = share->hosts_allow_map; -+ if (map == KSMBD_SHARE_HOSTS_DENY_MAP) -+ lookup_map = share->hosts_deny_map; -+ -+ if (!lookup_map) -+ return -EINVAL; -+ -+ g_rw_lock_reader_lock(&share->maps_lock); -+ if (g_hash_table_lookup(lookup_map, host)) -+ ret = 0; -+ g_rw_lock_reader_unlock(&share->maps_lock); -+ -+ return ret; -+} -+ -+int shm_open_connection(struct ksmbd_share *share) -+{ -+ int ret = 0; -+ -+ g_rw_lock_writer_lock(&share->update_lock); -+ share->num_connections++; -+ if (share->max_connections) { -+ if (share->num_connections >= share->max_connections) -+ ret = -EINVAL; -+ } -+ g_rw_lock_writer_unlock(&share->update_lock); -+ return ret; -+} -+ -+int shm_close_connection(struct ksmbd_share *share) -+{ -+ if (!share) -+ return 0; -+ -+ g_rw_lock_writer_lock(&share->update_lock); -+ share->num_connections--; -+ g_rw_lock_writer_unlock(&share->update_lock); -+ return 0; -+} -+ -+void for_each_ksmbd_share(walk_shares cb, gpointer user_data) -+{ -+ g_rw_lock_reader_lock(&shares_table_lock); -+ g_hash_table_foreach(shares_table, cb, user_data); -+ g_rw_lock_reader_unlock(&shares_table_lock); -+} -+ -+int shm_share_config_payload_size(struct ksmbd_share *share) -+{ -+ int sz = 1; -+ -+ if (share && !test_share_flag(share, KSMBD_SHARE_FLAG_PIPE)) { -+ if (share->path) -+ sz += strlen(share->path); -+ if (global_conf.root_dir) -+ sz += strlen(global_conf.root_dir) + 1; -+ if (share->veto_list_sz) -+ sz += share->veto_list_sz + 1; -+ } -+ -+ return sz; -+} -+ -+int shm_handle_share_config_request(struct ksmbd_share *share, -+ struct ksmbd_share_config_response *resp) -+{ -+ unsigned char *config_payload; -+ -+ if (!share) -+ return -EINVAL; -+ -+ resp->flags = share->flags; -+ resp->create_mask = share->create_mask; -+ resp->directory_mask = share->directory_mask; -+ resp->force_create_mode = share->force_create_mode; -+ resp->force_directory_mode = share->force_directory_mode; -+ resp->force_uid = share->force_uid; -+ resp->force_gid = share->force_gid; -+ *resp->share_name = 0x00; -+ strncat(resp->share_name, share->name, KSMBD_REQ_MAX_SHARE_NAME - 1); -+ resp->veto_list_sz = share->veto_list_sz; -+ -+ if (test_share_flag(share, KSMBD_SHARE_FLAG_PIPE)) -+ return 0; -+ -+ if (!share->path) -+ return 0; -+ -+ config_payload = KSMBD_SHARE_CONFIG_VETO_LIST(resp); -+ if (resp->veto_list_sz) { -+ memcpy(config_payload, -+ share->veto_list, -+ resp->veto_list_sz); -+ config_payload += resp->veto_list_sz + 1; -+ } -+ if (global_conf.root_dir) -+ sprintf(config_payload, -+ "%s%s", -+ global_conf.root_dir, -+ share->path); -+ else -+ sprintf(config_payload, "%s", share->path); -+ return 0; -+} ---- a/lib/management/spnego.c -+++ /dev/null -@@ -1,348 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-or-later --/* -- * Copyright (C) 2020 LG Electronics -- * -- * linux-cifsd-devel@lists.sourceforge.net -- */ -- --#include "ksmbdtools.h" -- --#ifndef _GNU_SOURCE --#define _GNU_SOURCE --#endif -- --#include --#include --#include --#include --#include --#include --#include -- --#include --#include --#include --#include "spnego_mech.h" -- --static struct spnego_mech_ctx mech_ctxs[SPNEGO_MAX_MECHS]; -- --static struct spnego_mech_ctx *get_mech(int mech_type) --{ -- if (mech_type >= SPNEGO_MAX_MECHS) -- return NULL; -- return &mech_ctxs[mech_type]; --} -- --int spnego_init(void) --{ -- struct spnego_mech_ctx *mech_ctx; -- int i; -- -- mech_ctx = &mech_ctxs[SPNEGO_MECH_MSKRB5]; -- mech_ctx->ops = &spnego_mskrb5_operations; -- if (global_conf.krb5_service_name) -- mech_ctx->params.krb5.service_name = -- strdup(global_conf.krb5_service_name); -- if (global_conf.krb5_keytab_file) -- mech_ctx->params.krb5.keytab_name = -- strdup(global_conf.krb5_keytab_file); -- -- mech_ctx = &mech_ctxs[SPNEGO_MECH_KRB5]; -- mech_ctx->ops = &spnego_krb5_operations; -- if (global_conf.krb5_service_name) -- mech_ctx->params.krb5.service_name = -- strdup(global_conf.krb5_service_name); -- if (global_conf.krb5_keytab_file) -- mech_ctx->params.krb5.keytab_name = -- strdup(global_conf.krb5_keytab_file); -- -- for (i = 0; i < SPNEGO_MAX_MECHS; i++) { -- if (mech_ctxs[i].ops->setup && -- mech_ctxs[i].ops->setup(&mech_ctxs[i])) { -- pr_err("Failed to init Kerberos 5\n"); -- goto out_err; -- } -- } -- -- return 0; --out_err: -- for (; i >= 0; i--) { -- if (mech_ctxs[i].ops->cleanup) -- mech_ctxs[i].ops->cleanup(&mech_ctxs[i]); -- } -- return -ENOTSUP; --} -- --void spnego_destroy(void) --{ -- int i; -- -- for (i = 0; i < SPNEGO_MAX_MECHS; i++) { -- if (mech_ctxs[i].ops && mech_ctxs[i].ops->cleanup) -- mech_ctxs[i].ops->cleanup(&mech_ctxs[i]); -- } --} -- --static int compare_oid(unsigned long *oid1, unsigned int oid1len, -- unsigned long *oid2, unsigned int oid2len) --{ -- unsigned int i; -- -- if (oid1len != oid2len) -- return 1; -- -- for (i = 0; i < oid1len; i++) { -- if (oid1[i] != oid2[i]) -- return 1; -- } -- return 0; --} -- --static bool is_supported_mech(unsigned long *oid, unsigned int len, -- int *mech_type) --{ -- if (!compare_oid(oid, len, MSKRB5_OID, ARRAY_SIZE(MSKRB5_OID))) { -- *mech_type = SPNEGO_MECH_MSKRB5; -- return true; -- } -- -- if (!compare_oid(oid, len, KRB5_OID, ARRAY_SIZE(KRB5_OID))) { -- *mech_type = SPNEGO_MECH_KRB5; -- return true; -- } -- -- *mech_type = SPNEGO_MAX_MECHS; -- return false; --} -- --static int decode_asn1_header(struct asn1_ctx *ctx, unsigned char **end, -- unsigned int cls, unsigned int con, unsigned int tag) --{ -- unsigned int d_cls, d_con, d_tag; -- -- if (asn1_header_decode(ctx, end, &d_cls, &d_con, &d_tag) == 0 || -- (d_cls != cls || d_con != con || d_tag != tag)) -- return -EINVAL; -- return 0; --} -- --static int decode_negTokenInit(unsigned char *negToken, int token_len, -- int *mech_type, unsigned char **krb5_ap_req, -- unsigned int *req_len) --{ -- struct asn1_ctx ctx; -- unsigned char *end, *mech_types_end, *id; -- unsigned long *oid = NULL; -- unsigned int len; -- -- asn1_open(&ctx, negToken, token_len); -- -- /* GSSAPI header */ -- if (decode_asn1_header(&ctx, &end, ASN1_APL, ASN1_CON, ASN1_EOC)) { -- pr_debug("Error decoding SPNEGO application tag\n"); -- return -EINVAL; -- } -- -- /* SPNEGO oid */ -- if (decode_asn1_header(&ctx, &end, ASN1_UNI, ASN1_PRI, ASN1_OJI) || -- asn1_oid_decode(&ctx, end, &oid, &len) == 0 || -- compare_oid(oid, len, SPNEGO_OID, SPNEGO_OID_LEN)) { -- pr_debug("Error decoding SPNEGO OID\n"); -- g_free(oid); -- return -EINVAL; -- } -- g_free(oid); -- -- /* negoTokenInit */ -- if (decode_asn1_header(&ctx, &end, ASN1_CTX, ASN1_CON, 0) || -- decode_asn1_header(&ctx, &end, -- ASN1_UNI, ASN1_CON, ASN1_SEQ)) { -- pr_debug("Error decoding negTokenInit tag\n"); -- return -EINVAL; -- } -- -- /* mechTypes */ -- if (decode_asn1_header(&ctx, &end, ASN1_CTX, ASN1_CON, 0) || -- decode_asn1_header(&ctx, &end, -- ASN1_UNI, ASN1_CON, ASN1_SEQ)) { -- pr_debug("Error decoding mechTypes tag\n"); -- return -EINVAL; -- } -- -- mech_types_end = end; -- if (decode_asn1_header(&ctx, &end, ASN1_UNI, ASN1_PRI, ASN1_OJI) || -- asn1_oid_decode(&ctx, end, &oid, &len) == 0) { -- pr_debug("Error decoding Kerberos 5 OIDs\n"); -- return -EINVAL; -- } -- -- if (!is_supported_mech(oid, len, mech_type)) { -- g_free(oid); -- pr_debug("Not a supported mechanism\n"); -- return -EINVAL; -- } -- g_free(oid); -- -- ctx.pointer = mech_types_end; -- /* mechToken */ -- if (decode_asn1_header(&ctx, &end, ASN1_CTX, ASN1_CON, 2) || -- decode_asn1_header(&ctx, &end, -- ASN1_UNI, ASN1_PRI, ASN1_OTS)) { -- pr_debug("Error decoding krb5_blob\n"); -- return -EINVAL; -- } -- -- if (decode_asn1_header(&ctx, &end, ASN1_APL, ASN1_CON, ASN1_EOC)) { -- pr_debug("Error decoding GSSAPI application tag\n"); -- return -EINVAL; -- } -- -- /* Kerberos 5 oid */ -- if (decode_asn1_header(&ctx, &end, ASN1_UNI, ASN1_PRI, ASN1_OJI)) { -- pr_debug("Error decoding Kerberos 5 OID tag\n"); -- return -EINVAL; -- } -- -- if (asn1_oid_decode(&ctx, end, &oid, &len) == 0 || -- compare_oid(oid, len, KRB5_OID, -- ARRAY_SIZE(KRB5_OID))) { -- pr_debug("Not a Kerberos 5 OID\n"); -- g_free(oid); -- return -EINVAL; -- } -- g_free(oid); -- -- /* AP_REQ id */ -- if (asn1_read(&ctx, &id, 2) == 0 || id[0] != 1 || id[1] != 0) { -- if (id) -- free(id); -- pr_debug("Error decoding AP_REQ ID\n"); -- return -EINVAL; -- } -- free(id); -- -- /* AP_REQ */ -- *req_len = (unsigned int)(ctx.end - ctx.pointer); -- *krb5_ap_req = ctx.pointer; -- return 0; --} -- --static int encode_negTokenTarg(char *in_blob, int in_len, -- const unsigned long *oid, int oid_len, -- char **out_blob, int *out_len) --{ -- unsigned char *buf; -- unsigned char *sup_oid, *krb5_oid; -- int sup_oid_len, krb5_oid_len; -- unsigned int neg_result_len, sup_mech_len, rep_token_len, len; -- -- if (asn1_oid_encode(oid, oid_len, &sup_oid, &sup_oid_len)) -- return -ENOMEM; -- if (asn1_oid_encode(KRB5_OID, ARRAY_SIZE(KRB5_OID), -- &krb5_oid, &krb5_oid_len)) { -- g_free(sup_oid); -- return -ENOMEM; -- } -- -- neg_result_len = asn1_header_len(1, 2); -- sup_mech_len = asn1_header_len(sup_oid_len, 2); -- rep_token_len = asn1_header_len(krb5_oid_len, 1); -- rep_token_len += 2 + in_len; -- rep_token_len = asn1_header_len(rep_token_len, 3); -- -- *out_len = asn1_header_len( -- neg_result_len + sup_mech_len + rep_token_len, 2); -- *out_blob = g_try_malloc0(*out_len); -- if (*out_blob == NULL) -- return -ENOMEM; -- buf = *out_blob; -- -- /* negTokenTarg */ -- len = *out_len; -- asn1_header_encode(&buf, -- ASN1_CTX, ASN1_CON, 1, -- &len); -- asn1_header_encode(&buf, -- ASN1_UNI, ASN1_CON, ASN1_SEQ, -- &len); -- -- /* negTokenTarg/negResult */ -- len = neg_result_len; -- asn1_header_encode(&buf, -- ASN1_CTX, ASN1_CON, 0, -- &len); -- asn1_header_encode(&buf, -- ASN1_UNI, ASN1_PRI, ASN1_ENUM, -- &len); -- *buf++ = 0; -- -- /* negTokenTarg/supportedMechType */ -- len = sup_mech_len; -- asn1_header_encode(&buf, -- ASN1_CTX, ASN1_CON, 1, -- &len); -- asn1_header_encode(&buf, -- ASN1_UNI, ASN1_PRI, ASN1_OJI, -- &len); -- memcpy(buf, sup_oid, sup_oid_len); -- buf += len; -- -- /* negTokenTarg/responseToken */ -- len = rep_token_len; -- asn1_header_encode(&buf, -- ASN1_CTX, ASN1_CON, 2, -- &len); -- asn1_header_encode(&buf, -- ASN1_UNI, ASN1_PRI, ASN1_OTS, -- &len); -- asn1_header_encode(&buf, -- ASN1_APL, ASN1_CON, 0, -- &len); -- /* negTokenTarg/responseToken/OID */ -- len = asn1_header_len(krb5_oid_len, 1); -- asn1_header_encode(&buf, -- ASN1_UNI, ASN1_PRI, ASN1_OJI, -- &len); -- /* negTokenTarg/responseToken/mechToken*/ -- memcpy(buf, krb5_oid, krb5_oid_len); -- buf += len; -- /* AP_REP id */ -- *buf++ = 2; -- *buf++ = 0; -- memcpy(buf, in_blob, in_len); -- -- g_free(sup_oid); -- g_free(krb5_oid); --} -- --int spnego_handle_authen_request(struct ksmbd_spnego_authen_request *req, -- struct ksmbd_spnego_auth_out *auth_out) --{ -- struct spnego_mech_ctx *mech_ctx; -- unsigned char *mech_token; -- int token_len, mech_type; -- int retval = 0; -- -- if (decode_negTokenInit(req->spnego_blob, (int)req->spnego_blob_len, -- &mech_type, &mech_token, &token_len)) { -- pr_info("Error decoding negTokenInit\n"); -- return -EINVAL; -- } -- -- mech_ctx = get_mech(mech_type); -- if (!mech_ctx) { -- retval = -ENOTSUP; -- pr_info("No support for Kerberos 5\n"); -- goto out; -- } -- -- if (mech_ctx->ops->handle_authen(mech_ctx, -- mech_token, token_len, -- auth_out, encode_negTokenTarg)) { -- retval = -EPERM; -- pr_info("Error authenticating\n"); -- goto out; -- } --out: -- return retval; --} ---- /dev/null -+++ b/tools/management/spnego.c -@@ -0,0 +1,348 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Copyright (C) 2020 LG Electronics -+ * -+ * linux-cifsd-devel@lists.sourceforge.net -+ */ -+ -+#include "tools.h" -+ -+#ifndef _GNU_SOURCE -+#define _GNU_SOURCE -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include "spnego_mech.h" -+ -+static struct spnego_mech_ctx mech_ctxs[SPNEGO_MAX_MECHS]; -+ -+static struct spnego_mech_ctx *get_mech(int mech_type) -+{ -+ if (mech_type >= SPNEGO_MAX_MECHS) -+ return NULL; -+ return &mech_ctxs[mech_type]; -+} -+ -+int spnego_init(void) -+{ -+ struct spnego_mech_ctx *mech_ctx; -+ int i; -+ -+ mech_ctx = &mech_ctxs[SPNEGO_MECH_MSKRB5]; -+ mech_ctx->ops = &spnego_mskrb5_operations; -+ if (global_conf.krb5_service_name) -+ mech_ctx->params.krb5.service_name = -+ strdup(global_conf.krb5_service_name); -+ if (global_conf.krb5_keytab_file) -+ mech_ctx->params.krb5.keytab_name = -+ strdup(global_conf.krb5_keytab_file); -+ -+ mech_ctx = &mech_ctxs[SPNEGO_MECH_KRB5]; -+ mech_ctx->ops = &spnego_krb5_operations; -+ if (global_conf.krb5_service_name) -+ mech_ctx->params.krb5.service_name = -+ strdup(global_conf.krb5_service_name); -+ if (global_conf.krb5_keytab_file) -+ mech_ctx->params.krb5.keytab_name = -+ strdup(global_conf.krb5_keytab_file); -+ -+ for (i = 0; i < SPNEGO_MAX_MECHS; i++) { -+ if (mech_ctxs[i].ops->setup && -+ mech_ctxs[i].ops->setup(&mech_ctxs[i])) { -+ pr_err("Failed to init Kerberos 5\n"); -+ goto out_err; -+ } -+ } -+ -+ return 0; -+out_err: -+ for (; i >= 0; i--) { -+ if (mech_ctxs[i].ops->cleanup) -+ mech_ctxs[i].ops->cleanup(&mech_ctxs[i]); -+ } -+ return -ENOTSUP; -+} -+ -+void spnego_destroy(void) -+{ -+ int i; -+ -+ for (i = 0; i < SPNEGO_MAX_MECHS; i++) { -+ if (mech_ctxs[i].ops && mech_ctxs[i].ops->cleanup) -+ mech_ctxs[i].ops->cleanup(&mech_ctxs[i]); -+ } -+} -+ -+static int compare_oid(unsigned long *oid1, unsigned int oid1len, -+ unsigned long *oid2, unsigned int oid2len) -+{ -+ unsigned int i; -+ -+ if (oid1len != oid2len) -+ return 1; -+ -+ for (i = 0; i < oid1len; i++) { -+ if (oid1[i] != oid2[i]) -+ return 1; -+ } -+ return 0; -+} -+ -+static bool is_supported_mech(unsigned long *oid, unsigned int len, -+ int *mech_type) -+{ -+ if (!compare_oid(oid, len, MSKRB5_OID, ARRAY_SIZE(MSKRB5_OID))) { -+ *mech_type = SPNEGO_MECH_MSKRB5; -+ return true; -+ } -+ -+ if (!compare_oid(oid, len, KRB5_OID, ARRAY_SIZE(KRB5_OID))) { -+ *mech_type = SPNEGO_MECH_KRB5; -+ return true; -+ } -+ -+ *mech_type = SPNEGO_MAX_MECHS; -+ return false; -+} -+ -+static int decode_asn1_header(struct asn1_ctx *ctx, unsigned char **end, -+ unsigned int cls, unsigned int con, unsigned int tag) -+{ -+ unsigned int d_cls, d_con, d_tag; -+ -+ if (asn1_header_decode(ctx, end, &d_cls, &d_con, &d_tag) == 0 || -+ (d_cls != cls || d_con != con || d_tag != tag)) -+ return -EINVAL; -+ return 0; -+} -+ -+static int decode_negTokenInit(unsigned char *negToken, int token_len, -+ int *mech_type, unsigned char **krb5_ap_req, -+ unsigned int *req_len) -+{ -+ struct asn1_ctx ctx; -+ unsigned char *end, *mech_types_end, *id; -+ unsigned long *oid = NULL; -+ unsigned int len; -+ -+ asn1_open(&ctx, negToken, token_len); -+ -+ /* GSSAPI header */ -+ if (decode_asn1_header(&ctx, &end, ASN1_APL, ASN1_CON, ASN1_EOC)) { -+ pr_debug("Error decoding SPNEGO application tag\n"); -+ return -EINVAL; -+ } -+ -+ /* SPNEGO oid */ -+ if (decode_asn1_header(&ctx, &end, ASN1_UNI, ASN1_PRI, ASN1_OJI) || -+ asn1_oid_decode(&ctx, end, &oid, &len) == 0 || -+ compare_oid(oid, len, SPNEGO_OID, SPNEGO_OID_LEN)) { -+ pr_debug("Error decoding SPNEGO OID\n"); -+ g_free(oid); -+ return -EINVAL; -+ } -+ g_free(oid); -+ -+ /* negoTokenInit */ -+ if (decode_asn1_header(&ctx, &end, ASN1_CTX, ASN1_CON, 0) || -+ decode_asn1_header(&ctx, &end, -+ ASN1_UNI, ASN1_CON, ASN1_SEQ)) { -+ pr_debug("Error decoding negTokenInit tag\n"); -+ return -EINVAL; -+ } -+ -+ /* mechTypes */ -+ if (decode_asn1_header(&ctx, &end, ASN1_CTX, ASN1_CON, 0) || -+ decode_asn1_header(&ctx, &end, -+ ASN1_UNI, ASN1_CON, ASN1_SEQ)) { -+ pr_debug("Error decoding mechTypes tag\n"); -+ return -EINVAL; -+ } -+ -+ mech_types_end = end; -+ if (decode_asn1_header(&ctx, &end, ASN1_UNI, ASN1_PRI, ASN1_OJI) || -+ asn1_oid_decode(&ctx, end, &oid, &len) == 0) { -+ pr_debug("Error decoding Kerberos 5 OIDs\n"); -+ return -EINVAL; -+ } -+ -+ if (!is_supported_mech(oid, len, mech_type)) { -+ g_free(oid); -+ pr_debug("Not a supported mechanism\n"); -+ return -EINVAL; -+ } -+ g_free(oid); -+ -+ ctx.pointer = mech_types_end; -+ /* mechToken */ -+ if (decode_asn1_header(&ctx, &end, ASN1_CTX, ASN1_CON, 2) || -+ decode_asn1_header(&ctx, &end, -+ ASN1_UNI, ASN1_PRI, ASN1_OTS)) { -+ pr_debug("Error decoding krb5_blob\n"); -+ return -EINVAL; -+ } -+ -+ if (decode_asn1_header(&ctx, &end, ASN1_APL, ASN1_CON, ASN1_EOC)) { -+ pr_debug("Error decoding GSSAPI application tag\n"); -+ return -EINVAL; -+ } -+ -+ /* Kerberos 5 oid */ -+ if (decode_asn1_header(&ctx, &end, ASN1_UNI, ASN1_PRI, ASN1_OJI)) { -+ pr_debug("Error decoding Kerberos 5 OID tag\n"); -+ return -EINVAL; -+ } -+ -+ if (asn1_oid_decode(&ctx, end, &oid, &len) == 0 || -+ compare_oid(oid, len, KRB5_OID, -+ ARRAY_SIZE(KRB5_OID))) { -+ pr_debug("Not a Kerberos 5 OID\n"); -+ g_free(oid); -+ return -EINVAL; -+ } -+ g_free(oid); -+ -+ /* AP_REQ id */ -+ if (asn1_read(&ctx, &id, 2) == 0 || id[0] != 1 || id[1] != 0) { -+ if (id) -+ free(id); -+ pr_debug("Error decoding AP_REQ ID\n"); -+ return -EINVAL; -+ } -+ free(id); -+ -+ /* AP_REQ */ -+ *req_len = (unsigned int)(ctx.end - ctx.pointer); -+ *krb5_ap_req = ctx.pointer; -+ return 0; -+} -+ -+static int encode_negTokenTarg(char *in_blob, int in_len, -+ const unsigned long *oid, int oid_len, -+ char **out_blob, int *out_len) -+{ -+ unsigned char *buf; -+ unsigned char *sup_oid, *krb5_oid; -+ int sup_oid_len, krb5_oid_len; -+ unsigned int neg_result_len, sup_mech_len, rep_token_len, len; -+ -+ if (asn1_oid_encode(oid, oid_len, &sup_oid, &sup_oid_len)) -+ return -ENOMEM; -+ if (asn1_oid_encode(KRB5_OID, ARRAY_SIZE(KRB5_OID), -+ &krb5_oid, &krb5_oid_len)) { -+ g_free(sup_oid); -+ return -ENOMEM; -+ } -+ -+ neg_result_len = asn1_header_len(1, 2); -+ sup_mech_len = asn1_header_len(sup_oid_len, 2); -+ rep_token_len = asn1_header_len(krb5_oid_len, 1); -+ rep_token_len += 2 + in_len; -+ rep_token_len = asn1_header_len(rep_token_len, 3); -+ -+ *out_len = asn1_header_len( -+ neg_result_len + sup_mech_len + rep_token_len, 2); -+ *out_blob = g_try_malloc0(*out_len); -+ if (*out_blob == NULL) -+ return -ENOMEM; -+ buf = *out_blob; -+ -+ /* negTokenTarg */ -+ len = *out_len; -+ asn1_header_encode(&buf, -+ ASN1_CTX, ASN1_CON, 1, -+ &len); -+ asn1_header_encode(&buf, -+ ASN1_UNI, ASN1_CON, ASN1_SEQ, -+ &len); -+ -+ /* negTokenTarg/negResult */ -+ len = neg_result_len; -+ asn1_header_encode(&buf, -+ ASN1_CTX, ASN1_CON, 0, -+ &len); -+ asn1_header_encode(&buf, -+ ASN1_UNI, ASN1_PRI, ASN1_ENUM, -+ &len); -+ *buf++ = 0; -+ -+ /* negTokenTarg/supportedMechType */ -+ len = sup_mech_len; -+ asn1_header_encode(&buf, -+ ASN1_CTX, ASN1_CON, 1, -+ &len); -+ asn1_header_encode(&buf, -+ ASN1_UNI, ASN1_PRI, ASN1_OJI, -+ &len); -+ memcpy(buf, sup_oid, sup_oid_len); -+ buf += len; -+ -+ /* negTokenTarg/responseToken */ -+ len = rep_token_len; -+ asn1_header_encode(&buf, -+ ASN1_CTX, ASN1_CON, 2, -+ &len); -+ asn1_header_encode(&buf, -+ ASN1_UNI, ASN1_PRI, ASN1_OTS, -+ &len); -+ asn1_header_encode(&buf, -+ ASN1_APL, ASN1_CON, 0, -+ &len); -+ /* negTokenTarg/responseToken/OID */ -+ len = asn1_header_len(krb5_oid_len, 1); -+ asn1_header_encode(&buf, -+ ASN1_UNI, ASN1_PRI, ASN1_OJI, -+ &len); -+ /* negTokenTarg/responseToken/mechToken*/ -+ memcpy(buf, krb5_oid, krb5_oid_len); -+ buf += len; -+ /* AP_REP id */ -+ *buf++ = 2; -+ *buf++ = 0; -+ memcpy(buf, in_blob, in_len); -+ -+ g_free(sup_oid); -+ g_free(krb5_oid); -+} -+ -+int spnego_handle_authen_request(struct ksmbd_spnego_authen_request *req, -+ struct ksmbd_spnego_auth_out *auth_out) -+{ -+ struct spnego_mech_ctx *mech_ctx; -+ unsigned char *mech_token; -+ int token_len, mech_type; -+ int retval = 0; -+ -+ if (decode_negTokenInit(req->spnego_blob, (int)req->spnego_blob_len, -+ &mech_type, &mech_token, &token_len)) { -+ pr_info("Error decoding negTokenInit\n"); -+ return -EINVAL; -+ } -+ -+ mech_ctx = get_mech(mech_type); -+ if (!mech_ctx) { -+ retval = -ENOTSUP; -+ pr_info("No support for Kerberos 5\n"); -+ goto out; -+ } -+ -+ if (mech_ctx->ops->handle_authen(mech_ctx, -+ mech_token, token_len, -+ auth_out, encode_negTokenTarg)) { -+ retval = -EPERM; -+ pr_info("Error authenticating\n"); -+ goto out; -+ } -+out: -+ return retval; -+} ---- a/lib/management/spnego_krb5.c -+++ /dev/null -@@ -1,408 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-or-later --/* -- * Copyright (C) 2020 LG Electronics -- * -- * linux-cifsd-devel@lists.sourceforge.net -- */ -- --#include "ksmbdtools.h" -- --#include --#include --#include --#include --#include --#include --#include -- --#include --#include --#include "spnego_mech.h" -- --#ifndef HAVE_KRB5_AUTH_CON_GETRECVSUBKEY --krb5_error_code krb5_auth_con_getrecvsubkey(krb5_context context, -- krb5_auth_context auth_context, krb5_keyblock **keyblock) --{ -- return krb5_auth_con_getremotesubkey(context, auth_context, keyblock); --} --#endif /* HAVE_KRB5_AUTH_CON_GETRECVSUBKEY */ -- --#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE --#define KRB5_KEY_TYPE(k) ((k)->keytype) --#define KRB5_KEY_LENGTH(k) ((k)->keyvalue.length) --#define KRB5_KEY_DATA(k) ((k)->keyvalue.data) --#else --#define KRB5_KEY_TYPE(k) ((k)->enctype) --#define KRB5_KEY_LENGTH(k) ((k)->length) --#define KRB5_KEY_DATA(k) ((k)->contents) --#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */ -- --struct spnego_krb5_ctx { -- krb5_context context; -- krb5_keytab keytab; -- krb5_creds creds; --}; -- --#define SERVICE_NAME "cifs" -- --#define pr_krb5_err(_context, _retval, _fmt, ...) \ -- do { \ -- const char *msg = krb5_get_error_message(_context, _retval); \ -- pr_err("%s: " _fmt, msg, ##__VA_ARGS__); \ -- krb5_free_error_message(_context, msg); \ -- } while (0) -- --static char *get_service_name(void) --{ -- return strdup(SERVICE_NAME); --} -- --static char *get_host_name(void) --{ -- struct addrinfo hint, *ai; -- char *host_name; -- char hostname[NI_MAXHOST]; -- -- if (gethostname(hostname, sizeof(hostname))) -- return NULL; -- -- memset(&hint, 0, sizeof(hint)); -- hint.ai_family = AF_UNSPEC; -- hint.ai_flags = AI_CANONNAME | AI_ADDRCONFIG; -- if (getaddrinfo(hostname, NULL, &hint, &ai)) -- return NULL; -- -- host_name = strdup(ai->ai_canonname); -- freeaddrinfo(ai); -- return host_name; --} -- --/* Service full name is [/[@REALM>]] */ --static int parse_service_full_name(char *service_full_name, -- char **service_name, -- char **host_name) --{ -- char *name, *delim; -- -- *service_name = NULL; -- *host_name = NULL; -- -- if (!service_full_name) { -- *service_name = get_service_name(); -- *host_name = get_host_name(); -- goto out; -- } -- -- name = service_full_name; -- delim = strchr(name, '/'); -- if (!delim) { -- *service_name = strdup(name); -- *host_name = get_host_name(); -- goto out; -- } -- *service_name = strndup(name, delim - name); -- if (*service_name == NULL) -- return -ENOMEM; -- -- name = delim + 1; -- delim = strchr(name, '@'); -- if (!delim) { -- *host_name = strdup(name); -- goto out; -- } -- *host_name = strndup(name, delim - name); -- if (*host_name == NULL) { -- free(*service_name); -- *service_name = NULL; -- return -ENOMEM; -- } --out: -- /* we assume the host name is FQDN if it has "." */ -- if (*host_name && strchr(*host_name, '.')) -- return 0; -- -- free(*service_name); -- free(*host_name); -- *service_name = NULL; -- *host_name = NULL; -- return -EINVAL; --} -- --static krb5_error_code acquire_creds_from_keytab(krb5_context context, -- char *service_full_name, char *keytab_name, -- krb5_creds *out_creds, krb5_keytab *keytab) --{ -- krb5_error_code retval; -- krb5_principal sprinc = NULL; -- char *host_name = NULL, *service_name = NULL; -- -- if (keytab_name) -- retval = krb5_kt_resolve(context, keytab_name, keytab); -- else -- retval = krb5_kt_default(context, keytab); -- if (retval) { -- pr_krb5_err(context, retval, "while resolving keytab\n"); -- return retval; -- } -- -- if (parse_service_full_name(service_full_name, -- &service_name, &host_name)) { -- retval = KRB5_ERR_HOST_REALM_UNKNOWN; -- pr_krb5_err(context, retval, "while getting host name\n"); -- goto out_err; -- } -- -- retval = krb5_sname_to_principal(context, host_name, service_name, -- KRB5_NT_UNKNOWN, &sprinc); -- if (retval) { -- pr_krb5_err(context, retval, "while generating service name\n"); -- goto out_err; -- } -- -- retval = krb5_get_init_creds_keytab(context, out_creds, sprinc, -- *keytab, 0, NULL, NULL); -- if (retval) { -- char *name; -- -- krb5_unparse_name(context, sprinc, &name); -- pr_krb5_err(context, retval, -- "while getting credentials for %s\n", name); -- krb5_free_unparsed_name(context, name); -- goto out_err; -- } -- -- free(host_name); -- free(service_name); -- return 0; --out_err: -- if (sprinc) -- krb5_free_principal(context, sprinc); -- if (service_name) -- free(service_name); -- if (host_name) -- free(host_name); -- if (*keytab) -- krb5_kt_close(context, *keytab); -- return retval; --} -- --static int handle_krb5_authen(struct spnego_mech_ctx *mech_ctx, -- char *in_blob, unsigned int in_len, -- struct ksmbd_spnego_auth_out *auth_out, -- spnego_encode_t spnego_encode) --{ -- struct spnego_krb5_ctx *krb5_ctx; -- char *client_name; -- krb5_auth_context auth_context; -- krb5_data packet, ap_rep; -- krb5_ticket *ticket = NULL; -- krb5_keyblock *session_key; --#ifdef HAVE_KRB5_AUTH_CON_GETAUTHENTICATOR_DOUBLE_POINTER -- krb5_authenticator *authenti; --#else -- krb5_authenticator authenti; --#endif /* HAVE_KRB5_AUTH_CON_GETAUTHENTICATOR_DOUBLE_POINTER */ -- krb5_principal client; -- int retval = -EINVAL; -- krb5_error_code krb_retval; -- -- krb5_ctx = (struct spnego_krb5_ctx *)mech_ctx->private; -- if (!krb5_ctx) -- return -EINVAL; -- -- krb_retval = krb5_auth_con_init(krb5_ctx->context, &auth_context); -- if (krb_retval) { -- pr_krb5_err(krb5_ctx->context, krb_retval, -- "while initializing auth context\n"); -- return -EINVAL; -- } -- -- packet.length = in_len; -- packet.data = (krb5_pointer)in_blob; -- krb_retval = krb5_rd_req(krb5_ctx->context, &auth_context, &packet, -- krb5_ctx->creds.client, krb5_ctx->keytab, -- NULL, &ticket); -- if (krb_retval) { -- char *name; -- -- krb5_unparse_name(krb5_ctx->context, krb5_ctx->creds.client, -- &name); -- krb5_auth_con_free(krb5_ctx->context, auth_context); -- pr_krb5_err(krb5_ctx->context, krb_retval, -- "while decoding AP_REQ with %s creds\n", name); -- krb5_free_unparsed_name(krb5_ctx->context, name); -- return -EINVAL; -- } -- -- krb_retval = krb5_auth_con_getrecvsubkey(krb5_ctx->context, -- auth_context, &session_key); -- if (krb_retval) { -- pr_krb5_err(krb5_ctx->context, krb_retval, -- "while reading session key\n"); -- goto out_free_con_auth; -- } -- -- krb_retval = krb5_mk_rep(krb5_ctx->context, auth_context, &ap_rep); -- if (krb_retval) { -- pr_krb5_err(krb5_ctx->context, krb_retval, -- "while making AP_REP\n"); -- goto out_free_key; -- } -- -- krb_retval = krb5_auth_con_getauthenticator(krb5_ctx->context, -- auth_context, &authenti); -- if (krb_retval) { -- pr_krb5_err(krb5_ctx->context, krb_retval, -- "while getting authenticator\n"); -- goto out_free_rep; -- } -- --#ifndef HAVE_KRB5_AUTHENTICATOR_CLIENT -- krb_retval = krb5_build_principal_ext(krb5_ctx->context, &client, -- strlen(authenti->crealm), authenti->crealm, 0); -- if (krb_retval) { -- pr_krb5_err(krb5_ctx->context, krb_retval, -- "while getting authenticator client\n"); -- goto out_free_auth; -- } -- krb_retval = copy_PrincipalName(&authenti->cname, &client->name); -- if (krb_retval) { -- pr_krb5_err(krb5_ctx->context, krb_retval, -- "while copying authenticator client name\n"); -- goto out_free_client; -- } --#else -- client = authenti->client; --#endif /* HAVE_KRB5_AUTHENTICATOR_CLIENT */ -- -- krb_retval = krb5_unparse_name_flags(krb5_ctx->context, -- client, -- KRB5_PRINCIPAL_UNPARSE_NO_REALM, &client_name); -- if (krb_retval) { -- pr_krb5_err(krb5_ctx->context, krb_retval, -- "while unparsing client name\n"); -- goto out_free_client; -- } -- -- memset(auth_out, 0, sizeof(*auth_out)); -- auth_out->user_name = strdup(client_name); -- if (!auth_out->user_name) { -- krb5_free_unparsed_name(krb5_ctx->context, client_name); -- retval = -ENOMEM; -- goto out_free_client; -- } -- krb5_free_unparsed_name(krb5_ctx->context, client_name); -- -- auth_out->sess_key = malloc(KRB5_KEY_LENGTH(session_key)); -- if (!auth_out->sess_key) { -- free(auth_out->user_name); -- retval = -ENOMEM; -- goto out_free_client; -- } -- memcpy(auth_out->sess_key, KRB5_KEY_DATA(session_key), KRB5_KEY_LENGTH(session_key)); -- auth_out->key_len = KRB5_KEY_LENGTH(session_key); -- -- if (spnego_encode(ap_rep.data, ap_rep.length, -- mech_ctx->oid, mech_ctx->oid_len, -- &auth_out->spnego_blob, &auth_out->blob_len)) { -- free(auth_out->user_name); -- free(auth_out->sess_key); -- goto out_free_client; -- } -- -- pr_info("Authenticated user `%s'\n", auth_out->user_name); -- retval = 0; -- --out_free_client: --#ifndef HAVE_KRB5_AUTHENTICATOR_CLIENT -- krb5_free_principal(krb5_ctx->context, client); --#endif /* HAVE_KRB5_AUTHENTICATOR_CLIENT */ --out_free_auth: --#ifdef HAVE_KRB5_AUTH_CON_GETAUTHENTICATOR_DOUBLE_POINTER -- krb5_free_authenticator(krb5_ctx->context, authenti); --#else -- krb5_free_authenticator(krb5_ctx->context, &authenti); --#endif /* HAVE_KRB5_AUTH_CON_GETAUTHENTICATOR_DOUBLE_POINTER */ --out_free_rep: -- krb5_free_data_contents(krb5_ctx->context, &ap_rep); --out_free_key: -- krb5_free_keyblock(krb5_ctx->context, session_key); --out_free_con_auth: -- krb5_free_ticket(krb5_ctx->context, ticket); -- krb5_auth_con_free(krb5_ctx->context, auth_context); -- return retval; --} -- --static int setup_krb5_ctx(struct spnego_mech_ctx *mech_ctx) --{ -- struct spnego_krb5_ctx *krb5_ctx; -- krb5_error_code krb_retval; -- -- krb5_ctx = g_try_malloc0(sizeof(*krb5_ctx)); -- if (!krb5_ctx) -- return -ENOMEM; -- -- krb_retval = krb5_init_context(&krb5_ctx->context); -- if (krb_retval) { -- g_free(krb5_ctx); -- pr_err("while initializing krb5 context\n"); -- return -EINVAL; -- } -- -- krb_retval = acquire_creds_from_keytab(krb5_ctx->context, -- mech_ctx->params.krb5.service_name, -- mech_ctx->params.krb5.keytab_name, -- &krb5_ctx->creds, &krb5_ctx->keytab); -- if (krb_retval) { -- krb5_free_context(krb5_ctx->context); -- g_free(krb5_ctx); -- return -EINVAL; -- } -- -- mech_ctx->private = krb5_ctx; -- return 0; --} -- --static int setup_krb5(struct spnego_mech_ctx *mech_ctx) --{ -- mech_ctx->oid = KRB5_OID; -- mech_ctx->oid_len = ARRAY_SIZE(KRB5_OID); -- return setup_krb5_ctx(mech_ctx); --} -- --static int setup_mskrb5(struct spnego_mech_ctx *mech_ctx) --{ -- mech_ctx->oid = MSKRB5_OID; -- mech_ctx->oid_len = ARRAY_SIZE(MSKRB5_OID); -- return setup_krb5_ctx(mech_ctx); --} -- --static void cleanup_krb5(struct spnego_mech_ctx *mech_ctx) --{ -- if (mech_ctx->private) { -- struct spnego_krb5_ctx *krb5_ctx; -- -- krb5_ctx = (struct spnego_krb5_ctx *)mech_ctx->private; -- krb5_free_cred_contents(krb5_ctx->context, &krb5_ctx->creds); -- krb5_kt_close(krb5_ctx->context, krb5_ctx->keytab); -- krb5_free_context(krb5_ctx->context); -- g_free(krb5_ctx); -- mech_ctx->private = NULL; -- } -- if (mech_ctx->params.krb5.service_name) -- free(mech_ctx->params.krb5.service_name); -- if (mech_ctx->params.krb5.keytab_name) -- free(mech_ctx->params.krb5.keytab_name); --} -- --struct spnego_mech_operations spnego_krb5_operations = { -- .setup = setup_krb5, -- .cleanup = cleanup_krb5, -- .handle_authen = handle_krb5_authen, --}; -- --struct spnego_mech_operations spnego_mskrb5_operations = { -- .setup = setup_mskrb5, -- .cleanup = cleanup_krb5, -- .handle_authen = handle_krb5_authen, --}; ---- /dev/null -+++ b/tools/management/spnego_krb5.c -@@ -0,0 +1,408 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Copyright (C) 2020 LG Electronics -+ * -+ * linux-cifsd-devel@lists.sourceforge.net -+ */ -+ -+#include "tools.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include "spnego_mech.h" -+ -+#ifndef HAVE_KRB5_AUTH_CON_GETRECVSUBKEY -+krb5_error_code krb5_auth_con_getrecvsubkey(krb5_context context, -+ krb5_auth_context auth_context, krb5_keyblock **keyblock) -+{ -+ return krb5_auth_con_getremotesubkey(context, auth_context, keyblock); -+} -+#endif /* HAVE_KRB5_AUTH_CON_GETRECVSUBKEY */ -+ -+#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE -+#define KRB5_KEY_TYPE(k) ((k)->keytype) -+#define KRB5_KEY_LENGTH(k) ((k)->keyvalue.length) -+#define KRB5_KEY_DATA(k) ((k)->keyvalue.data) -+#else -+#define KRB5_KEY_TYPE(k) ((k)->enctype) -+#define KRB5_KEY_LENGTH(k) ((k)->length) -+#define KRB5_KEY_DATA(k) ((k)->contents) -+#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */ -+ -+struct spnego_krb5_ctx { -+ krb5_context context; -+ krb5_keytab keytab; -+ krb5_creds creds; -+}; -+ -+#define SERVICE_NAME "cifs" -+ -+#define pr_krb5_err(_context, _retval, _fmt, ...) \ -+ do { \ -+ const char *msg = krb5_get_error_message(_context, _retval); \ -+ pr_err("%s: " _fmt, msg, ##__VA_ARGS__); \ -+ krb5_free_error_message(_context, msg); \ -+ } while (0) -+ -+static char *get_service_name(void) -+{ -+ return strdup(SERVICE_NAME); -+} -+ -+static char *get_host_name(void) -+{ -+ struct addrinfo hint, *ai; -+ char *host_name; -+ char hostname[NI_MAXHOST]; -+ -+ if (gethostname(hostname, sizeof(hostname))) -+ return NULL; -+ -+ memset(&hint, 0, sizeof(hint)); -+ hint.ai_family = AF_UNSPEC; -+ hint.ai_flags = AI_CANONNAME | AI_ADDRCONFIG; -+ if (getaddrinfo(hostname, NULL, &hint, &ai)) -+ return NULL; -+ -+ host_name = strdup(ai->ai_canonname); -+ freeaddrinfo(ai); -+ return host_name; -+} -+ -+/* Service full name is [/[@REALM>]] */ -+static int parse_service_full_name(char *service_full_name, -+ char **service_name, -+ char **host_name) -+{ -+ char *name, *delim; -+ -+ *service_name = NULL; -+ *host_name = NULL; -+ -+ if (!service_full_name) { -+ *service_name = get_service_name(); -+ *host_name = get_host_name(); -+ goto out; -+ } -+ -+ name = service_full_name; -+ delim = strchr(name, '/'); -+ if (!delim) { -+ *service_name = strdup(name); -+ *host_name = get_host_name(); -+ goto out; -+ } -+ *service_name = strndup(name, delim - name); -+ if (*service_name == NULL) -+ return -ENOMEM; -+ -+ name = delim + 1; -+ delim = strchr(name, '@'); -+ if (!delim) { -+ *host_name = strdup(name); -+ goto out; -+ } -+ *host_name = strndup(name, delim - name); -+ if (*host_name == NULL) { -+ free(*service_name); -+ *service_name = NULL; -+ return -ENOMEM; -+ } -+out: -+ /* we assume the host name is FQDN if it has "." */ -+ if (*host_name && strchr(*host_name, '.')) -+ return 0; -+ -+ free(*service_name); -+ free(*host_name); -+ *service_name = NULL; -+ *host_name = NULL; -+ return -EINVAL; -+} -+ -+static krb5_error_code acquire_creds_from_keytab(krb5_context context, -+ char *service_full_name, char *keytab_name, -+ krb5_creds *out_creds, krb5_keytab *keytab) -+{ -+ krb5_error_code retval; -+ krb5_principal sprinc = NULL; -+ char *host_name = NULL, *service_name = NULL; -+ -+ if (keytab_name) -+ retval = krb5_kt_resolve(context, keytab_name, keytab); -+ else -+ retval = krb5_kt_default(context, keytab); -+ if (retval) { -+ pr_krb5_err(context, retval, "while resolving keytab\n"); -+ return retval; -+ } -+ -+ if (parse_service_full_name(service_full_name, -+ &service_name, &host_name)) { -+ retval = KRB5_ERR_HOST_REALM_UNKNOWN; -+ pr_krb5_err(context, retval, "while getting host name\n"); -+ goto out_err; -+ } -+ -+ retval = krb5_sname_to_principal(context, host_name, service_name, -+ KRB5_NT_UNKNOWN, &sprinc); -+ if (retval) { -+ pr_krb5_err(context, retval, "while generating service name\n"); -+ goto out_err; -+ } -+ -+ retval = krb5_get_init_creds_keytab(context, out_creds, sprinc, -+ *keytab, 0, NULL, NULL); -+ if (retval) { -+ char *name; -+ -+ krb5_unparse_name(context, sprinc, &name); -+ pr_krb5_err(context, retval, -+ "while getting credentials for %s\n", name); -+ krb5_free_unparsed_name(context, name); -+ goto out_err; -+ } -+ -+ free(host_name); -+ free(service_name); -+ return 0; -+out_err: -+ if (sprinc) -+ krb5_free_principal(context, sprinc); -+ if (service_name) -+ free(service_name); -+ if (host_name) -+ free(host_name); -+ if (*keytab) -+ krb5_kt_close(context, *keytab); -+ return retval; -+} -+ -+static int handle_krb5_authen(struct spnego_mech_ctx *mech_ctx, -+ char *in_blob, unsigned int in_len, -+ struct ksmbd_spnego_auth_out *auth_out, -+ spnego_encode_t spnego_encode) -+{ -+ struct spnego_krb5_ctx *krb5_ctx; -+ char *client_name; -+ krb5_auth_context auth_context; -+ krb5_data packet, ap_rep; -+ krb5_ticket *ticket = NULL; -+ krb5_keyblock *session_key; -+#ifdef HAVE_KRB5_AUTH_CON_GETAUTHENTICATOR_DOUBLE_POINTER -+ krb5_authenticator *authenti; -+#else -+ krb5_authenticator authenti; -+#endif /* HAVE_KRB5_AUTH_CON_GETAUTHENTICATOR_DOUBLE_POINTER */ -+ krb5_principal client; -+ int retval = -EINVAL; -+ krb5_error_code krb_retval; -+ -+ krb5_ctx = (struct spnego_krb5_ctx *)mech_ctx->private; -+ if (!krb5_ctx) -+ return -EINVAL; -+ -+ krb_retval = krb5_auth_con_init(krb5_ctx->context, &auth_context); -+ if (krb_retval) { -+ pr_krb5_err(krb5_ctx->context, krb_retval, -+ "while initializing auth context\n"); -+ return -EINVAL; -+ } -+ -+ packet.length = in_len; -+ packet.data = (krb5_pointer)in_blob; -+ krb_retval = krb5_rd_req(krb5_ctx->context, &auth_context, &packet, -+ krb5_ctx->creds.client, krb5_ctx->keytab, -+ NULL, &ticket); -+ if (krb_retval) { -+ char *name; -+ -+ krb5_unparse_name(krb5_ctx->context, krb5_ctx->creds.client, -+ &name); -+ krb5_auth_con_free(krb5_ctx->context, auth_context); -+ pr_krb5_err(krb5_ctx->context, krb_retval, -+ "while decoding AP_REQ with %s creds\n", name); -+ krb5_free_unparsed_name(krb5_ctx->context, name); -+ return -EINVAL; -+ } -+ -+ krb_retval = krb5_auth_con_getrecvsubkey(krb5_ctx->context, -+ auth_context, &session_key); -+ if (krb_retval) { -+ pr_krb5_err(krb5_ctx->context, krb_retval, -+ "while reading session key\n"); -+ goto out_free_con_auth; -+ } -+ -+ krb_retval = krb5_mk_rep(krb5_ctx->context, auth_context, &ap_rep); -+ if (krb_retval) { -+ pr_krb5_err(krb5_ctx->context, krb_retval, -+ "while making AP_REP\n"); -+ goto out_free_key; -+ } -+ -+ krb_retval = krb5_auth_con_getauthenticator(krb5_ctx->context, -+ auth_context, &authenti); -+ if (krb_retval) { -+ pr_krb5_err(krb5_ctx->context, krb_retval, -+ "while getting authenticator\n"); -+ goto out_free_rep; -+ } -+ -+#ifndef HAVE_KRB5_AUTHENTICATOR_CLIENT -+ krb_retval = krb5_build_principal_ext(krb5_ctx->context, &client, -+ strlen(authenti->crealm), authenti->crealm, 0); -+ if (krb_retval) { -+ pr_krb5_err(krb5_ctx->context, krb_retval, -+ "while getting authenticator client\n"); -+ goto out_free_auth; -+ } -+ krb_retval = copy_PrincipalName(&authenti->cname, &client->name); -+ if (krb_retval) { -+ pr_krb5_err(krb5_ctx->context, krb_retval, -+ "while copying authenticator client name\n"); -+ goto out_free_client; -+ } -+#else -+ client = authenti->client; -+#endif /* HAVE_KRB5_AUTHENTICATOR_CLIENT */ -+ -+ krb_retval = krb5_unparse_name_flags(krb5_ctx->context, -+ client, -+ KRB5_PRINCIPAL_UNPARSE_NO_REALM, &client_name); -+ if (krb_retval) { -+ pr_krb5_err(krb5_ctx->context, krb_retval, -+ "while unparsing client name\n"); -+ goto out_free_client; -+ } -+ -+ memset(auth_out, 0, sizeof(*auth_out)); -+ auth_out->user_name = strdup(client_name); -+ if (!auth_out->user_name) { -+ krb5_free_unparsed_name(krb5_ctx->context, client_name); -+ retval = -ENOMEM; -+ goto out_free_client; -+ } -+ krb5_free_unparsed_name(krb5_ctx->context, client_name); -+ -+ auth_out->sess_key = malloc(KRB5_KEY_LENGTH(session_key)); -+ if (!auth_out->sess_key) { -+ free(auth_out->user_name); -+ retval = -ENOMEM; -+ goto out_free_client; -+ } -+ memcpy(auth_out->sess_key, KRB5_KEY_DATA(session_key), KRB5_KEY_LENGTH(session_key)); -+ auth_out->key_len = KRB5_KEY_LENGTH(session_key); -+ -+ if (spnego_encode(ap_rep.data, ap_rep.length, -+ mech_ctx->oid, mech_ctx->oid_len, -+ &auth_out->spnego_blob, &auth_out->blob_len)) { -+ free(auth_out->user_name); -+ free(auth_out->sess_key); -+ goto out_free_client; -+ } -+ -+ pr_info("Authenticated user `%s'\n", auth_out->user_name); -+ retval = 0; -+ -+out_free_client: -+#ifndef HAVE_KRB5_AUTHENTICATOR_CLIENT -+ krb5_free_principal(krb5_ctx->context, client); -+#endif /* HAVE_KRB5_AUTHENTICATOR_CLIENT */ -+out_free_auth: -+#ifdef HAVE_KRB5_AUTH_CON_GETAUTHENTICATOR_DOUBLE_POINTER -+ krb5_free_authenticator(krb5_ctx->context, authenti); -+#else -+ krb5_free_authenticator(krb5_ctx->context, &authenti); -+#endif /* HAVE_KRB5_AUTH_CON_GETAUTHENTICATOR_DOUBLE_POINTER */ -+out_free_rep: -+ krb5_free_data_contents(krb5_ctx->context, &ap_rep); -+out_free_key: -+ krb5_free_keyblock(krb5_ctx->context, session_key); -+out_free_con_auth: -+ krb5_free_ticket(krb5_ctx->context, ticket); -+ krb5_auth_con_free(krb5_ctx->context, auth_context); -+ return retval; -+} -+ -+static int setup_krb5_ctx(struct spnego_mech_ctx *mech_ctx) -+{ -+ struct spnego_krb5_ctx *krb5_ctx; -+ krb5_error_code krb_retval; -+ -+ krb5_ctx = g_try_malloc0(sizeof(*krb5_ctx)); -+ if (!krb5_ctx) -+ return -ENOMEM; -+ -+ krb_retval = krb5_init_context(&krb5_ctx->context); -+ if (krb_retval) { -+ g_free(krb5_ctx); -+ pr_err("while initializing krb5 context\n"); -+ return -EINVAL; -+ } -+ -+ krb_retval = acquire_creds_from_keytab(krb5_ctx->context, -+ mech_ctx->params.krb5.service_name, -+ mech_ctx->params.krb5.keytab_name, -+ &krb5_ctx->creds, &krb5_ctx->keytab); -+ if (krb_retval) { -+ krb5_free_context(krb5_ctx->context); -+ g_free(krb5_ctx); -+ return -EINVAL; -+ } -+ -+ mech_ctx->private = krb5_ctx; -+ return 0; -+} -+ -+static int setup_krb5(struct spnego_mech_ctx *mech_ctx) -+{ -+ mech_ctx->oid = KRB5_OID; -+ mech_ctx->oid_len = ARRAY_SIZE(KRB5_OID); -+ return setup_krb5_ctx(mech_ctx); -+} -+ -+static int setup_mskrb5(struct spnego_mech_ctx *mech_ctx) -+{ -+ mech_ctx->oid = MSKRB5_OID; -+ mech_ctx->oid_len = ARRAY_SIZE(MSKRB5_OID); -+ return setup_krb5_ctx(mech_ctx); -+} -+ -+static void cleanup_krb5(struct spnego_mech_ctx *mech_ctx) -+{ -+ if (mech_ctx->private) { -+ struct spnego_krb5_ctx *krb5_ctx; -+ -+ krb5_ctx = (struct spnego_krb5_ctx *)mech_ctx->private; -+ krb5_free_cred_contents(krb5_ctx->context, &krb5_ctx->creds); -+ krb5_kt_close(krb5_ctx->context, krb5_ctx->keytab); -+ krb5_free_context(krb5_ctx->context); -+ g_free(krb5_ctx); -+ mech_ctx->private = NULL; -+ } -+ if (mech_ctx->params.krb5.service_name) -+ free(mech_ctx->params.krb5.service_name); -+ if (mech_ctx->params.krb5.keytab_name) -+ free(mech_ctx->params.krb5.keytab_name); -+} -+ -+struct spnego_mech_operations spnego_krb5_operations = { -+ .setup = setup_krb5, -+ .cleanup = cleanup_krb5, -+ .handle_authen = handle_krb5_authen, -+}; -+ -+struct spnego_mech_operations spnego_mskrb5_operations = { -+ .setup = setup_mskrb5, -+ .cleanup = cleanup_krb5, -+ .handle_authen = handle_krb5_authen, -+}; ---- a/lib/management/tree_conn.c -+++ /dev/null -@@ -1,231 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-or-later --/* -- * Copyright (C) 2018 Samsung Electronics Co., Ltd. -- * -- * linux-cifsd-devel@lists.sourceforge.net -- */ -- --#include --#include --#include -- --#include "linux/ksmbd_server.h" --#include "management/tree_conn.h" --#include "management/session.h" --#include "management/share.h" --#include "management/user.h" --#include "ksmbdtools.h" -- --static struct ksmbd_tree_conn *new_ksmbd_tree_conn(void) --{ -- struct ksmbd_tree_conn *conn; -- -- conn = g_try_malloc0(sizeof(struct ksmbd_tree_conn)); -- if (!conn) -- return NULL; -- -- conn->id = 0; -- return conn; --} -- --void tcm_tree_conn_free(struct ksmbd_tree_conn *conn) --{ -- shm_close_connection(conn->share); -- put_ksmbd_share(conn->share); -- g_free(conn); --} -- --int tcm_handle_tree_connect(struct ksmbd_tree_connect_request *req, -- struct ksmbd_tree_connect_response *resp) --{ -- struct ksmbd_user *user = NULL; -- struct ksmbd_share *share = NULL; -- struct ksmbd_tree_conn *conn = new_ksmbd_tree_conn(); -- int ret; -- -- if (!conn) { -- resp->status = KSMBD_TREE_CONN_STATUS_NOMEM; -- return -ENOMEM; -- } -- -- if (sm_check_sessions_capacity(req->session_id)) { -- resp->status = KSMBD_TREE_CONN_STATUS_TOO_MANY_SESSIONS; -- pr_debug("treecon: Too many active sessions\n"); -- goto out_error; -- } -- -- if (global_conf.map_to_guest == KSMBD_CONF_MAP_TO_GUEST_NEVER) { -- if (req->account_flags & KSMBD_USER_FLAG_BAD_PASSWORD) { -- resp->status = KSMBD_TREE_CONN_STATUS_INVALID_USER; -- pr_debug("treecon: Bad user password\n"); -- goto out_error; -- } -- } -- -- share = shm_lookup_share(req->share); -- if (!share) { -- resp->status = KSMBD_TREE_CONN_STATUS_NO_SHARE; -- pr_err("treecon: Unknown net share: %s\n", req->share); -- goto out_error; -- } -- -- if (test_share_flag(share, KSMBD_SHARE_FLAG_WRITEABLE)) -- set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_WRITABLE); -- if (test_share_flag(share, KSMBD_SHARE_FLAG_READONLY)) -- set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_READ_ONLY); -- if (test_share_flag(share, KSMBD_SHARE_FLAG_UPDATE)) -- set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_UPDATE); -- -- if (shm_open_connection(share)) { -- resp->status = KSMBD_TREE_CONN_STATUS_TOO_MANY_CONNS; -- pr_debug("treecon: Too many connections to net share\n"); -- goto out_error; -- } -- -- ret = shm_lookup_hosts_map(share, -- KSMBD_SHARE_HOSTS_ALLOW_MAP, -- req->peer_addr); -- if (ret == -ENOENT) { -- resp->status = KSMBD_TREE_CONN_STATUS_HOST_DENIED; -- pr_debug("treecon: Host denied: %s\n", req->peer_addr); -- goto out_error; -- } -- -- if (ret != 0) { -- ret = shm_lookup_hosts_map(share, -- KSMBD_SHARE_HOSTS_DENY_MAP, -- req->peer_addr); -- if (ret == 0) { -- resp->status = KSMBD_TREE_CONN_STATUS_HOST_DENIED; -- pr_err("treecon: Host denied: %s\n", req->peer_addr); -- goto out_error; -- } -- } -- -- if (global_conf.restrict_anon >= KSMBD_RESTRICT_ANON_TYPE_1) { -- int deny; -- -- deny = !test_share_flag(share, KSMBD_SHARE_FLAG_GUEST_OK); -- deny |= test_share_flag(share, KSMBD_SHARE_FLAG_PIPE); -- -- if (req->account_flags & KSMBD_USER_FLAG_GUEST_ACCOUNT && -- deny) { -- pr_debug("treecon: Deny, restricted session\n"); -- resp->status = KSMBD_TREE_CONN_STATUS_ERROR; -- goto out_error; -- } -- } -- -- if ((req->account_flags & KSMBD_USER_FLAG_GUEST_ACCOUNT) && -- !test_share_flag(share, KSMBD_SHARE_FLAG_PIPE) && -- !test_share_flag(share, KSMBD_SHARE_FLAG_GUEST_OK)) { -- pr_debug("treecon: Deny, guest not allowed\n"); -- resp->status = KSMBD_TREE_CONN_STATUS_ERROR; -- goto out_error; -- } -- -- if ((req->account_flags & KSMBD_USER_FLAG_GUEST_ACCOUNT) && -- test_share_flag(share, KSMBD_SHARE_FLAG_GUEST_OK)) { -- pr_debug("treecon: Net share permits guest login\n"); -- user = usm_lookup_user(share->guest_account); -- if (user) { -- set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_GUEST_ACCOUNT); -- goto bind; -- } -- -- user = usm_lookup_user(global_conf.guest_account); -- if (user) { -- set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_GUEST_ACCOUNT); -- goto bind; -- } -- } -- -- user = usm_lookup_user(req->account); -- if (!user) { -- resp->status = KSMBD_TREE_CONN_STATUS_NO_USER; -- pr_err("treecon: User `%s' not found\n", req->account); -- goto out_error; -- } -- -- user->failed_login_count = 0; -- user->flags &= ~KSMBD_USER_FLAG_DELAY_SESSION; -- -- if (test_user_flag(user, KSMBD_USER_FLAG_GUEST_ACCOUNT)) -- set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_GUEST_ACCOUNT); -- -- ret = shm_lookup_users_map(share, -- KSMBD_SHARE_ADMIN_USERS_MAP, -- req->account); -- if (ret == 0) { -- set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_ADMIN_ACCOUNT); -- goto bind; -- } -- -- ret = shm_lookup_users_map(share, -- KSMBD_SHARE_INVALID_USERS_MAP, -- req->account); -- if (ret == 0) { -- resp->status = KSMBD_TREE_CONN_STATUS_INVALID_USER; -- pr_err("treecon: User is on invalid users list\n"); -- goto out_error; -- } -- -- ret = shm_lookup_users_map(share, -- KSMBD_SHARE_READ_LIST_MAP, -- req->account); -- if (ret == 0) { -- set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_READ_ONLY); -- clear_conn_flag(conn, KSMBD_TREE_CONN_FLAG_WRITABLE); -- goto bind; -- } -- -- ret = shm_lookup_users_map(share, -- KSMBD_SHARE_WRITE_LIST_MAP, -- req->account); -- if (ret == 0) { -- set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_WRITABLE); -- goto bind; -- } -- -- ret = shm_lookup_users_map(share, -- KSMBD_SHARE_VALID_USERS_MAP, -- req->account); -- if (ret == 0) -- goto bind; -- if (ret == -ENOENT) { -- resp->status = KSMBD_TREE_CONN_STATUS_INVALID_USER; -- pr_err("treecon: User is not on valid users list\n"); -- goto out_error; -- } -- --bind: -- conn->id = req->connect_id; -- conn->share = share; -- resp->status = KSMBD_TREE_CONN_STATUS_OK; -- resp->connection_flags = conn->flags; -- -- if (sm_handle_tree_connect(req->session_id, user, conn)) { -- pr_err("treecon: Unable to bind tree connection\n"); -- tcm_tree_conn_free(conn); -- put_ksmbd_user(user); -- } -- -- g_rw_lock_writer_lock(&share->update_lock); -- clear_share_flag(share, KSMBD_SHARE_FLAG_UPDATE); -- g_rw_lock_writer_unlock(&share->update_lock); -- -- return 0; --out_error: -- tcm_tree_conn_free(conn); -- shm_close_connection(share); -- put_ksmbd_share(share); -- put_ksmbd_user(user); -- return -EINVAL; --} -- --int tcm_handle_tree_disconnect(unsigned long long sess_id, -- unsigned long long tree_conn_id) --{ -- sm_handle_tree_disconnect(sess_id, tree_conn_id); -- return 0; --} ---- /dev/null -+++ b/tools/management/tree_conn.c -@@ -0,0 +1,231 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Copyright (C) 2018 Samsung Electronics Co., Ltd. -+ * -+ * linux-cifsd-devel@lists.sourceforge.net -+ */ -+ -+#include -+#include -+#include -+ -+#include "linux/ksmbd_server.h" -+#include "management/tree_conn.h" -+#include "management/session.h" -+#include "management/share.h" -+#include "management/user.h" -+#include "tools.h" -+ -+static struct ksmbd_tree_conn *new_ksmbd_tree_conn(void) -+{ -+ struct ksmbd_tree_conn *conn; -+ -+ conn = g_try_malloc0(sizeof(struct ksmbd_tree_conn)); -+ if (!conn) -+ return NULL; -+ -+ conn->id = 0; -+ return conn; -+} -+ -+void tcm_tree_conn_free(struct ksmbd_tree_conn *conn) -+{ -+ shm_close_connection(conn->share); -+ put_ksmbd_share(conn->share); -+ g_free(conn); -+} -+ -+int tcm_handle_tree_connect(struct ksmbd_tree_connect_request *req, -+ struct ksmbd_tree_connect_response *resp) -+{ -+ struct ksmbd_user *user = NULL; -+ struct ksmbd_share *share = NULL; -+ struct ksmbd_tree_conn *conn = new_ksmbd_tree_conn(); -+ int ret; -+ -+ if (!conn) { -+ resp->status = KSMBD_TREE_CONN_STATUS_NOMEM; -+ return -ENOMEM; -+ } -+ -+ if (sm_check_sessions_capacity(req->session_id)) { -+ resp->status = KSMBD_TREE_CONN_STATUS_TOO_MANY_SESSIONS; -+ pr_debug("treecon: Too many active sessions\n"); -+ goto out_error; -+ } -+ -+ if (global_conf.map_to_guest == KSMBD_CONF_MAP_TO_GUEST_NEVER) { -+ if (req->account_flags & KSMBD_USER_FLAG_BAD_PASSWORD) { -+ resp->status = KSMBD_TREE_CONN_STATUS_INVALID_USER; -+ pr_debug("treecon: Bad user password\n"); -+ goto out_error; -+ } -+ } -+ -+ share = shm_lookup_share(req->share); -+ if (!share) { -+ resp->status = KSMBD_TREE_CONN_STATUS_NO_SHARE; -+ pr_err("treecon: Unknown net share: %s\n", req->share); -+ goto out_error; -+ } -+ -+ if (test_share_flag(share, KSMBD_SHARE_FLAG_WRITEABLE)) -+ set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_WRITABLE); -+ if (test_share_flag(share, KSMBD_SHARE_FLAG_READONLY)) -+ set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_READ_ONLY); -+ if (test_share_flag(share, KSMBD_SHARE_FLAG_UPDATE)) -+ set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_UPDATE); -+ -+ if (shm_open_connection(share)) { -+ resp->status = KSMBD_TREE_CONN_STATUS_TOO_MANY_CONNS; -+ pr_debug("treecon: Too many connections to net share\n"); -+ goto out_error; -+ } -+ -+ ret = shm_lookup_hosts_map(share, -+ KSMBD_SHARE_HOSTS_ALLOW_MAP, -+ req->peer_addr); -+ if (ret == -ENOENT) { -+ resp->status = KSMBD_TREE_CONN_STATUS_HOST_DENIED; -+ pr_debug("treecon: Host denied: %s\n", req->peer_addr); -+ goto out_error; -+ } -+ -+ if (ret != 0) { -+ ret = shm_lookup_hosts_map(share, -+ KSMBD_SHARE_HOSTS_DENY_MAP, -+ req->peer_addr); -+ if (ret == 0) { -+ resp->status = KSMBD_TREE_CONN_STATUS_HOST_DENIED; -+ pr_err("treecon: Host denied: %s\n", req->peer_addr); -+ goto out_error; -+ } -+ } -+ -+ if (global_conf.restrict_anon >= KSMBD_RESTRICT_ANON_TYPE_1) { -+ int deny; -+ -+ deny = !test_share_flag(share, KSMBD_SHARE_FLAG_GUEST_OK); -+ deny |= test_share_flag(share, KSMBD_SHARE_FLAG_PIPE); -+ -+ if (req->account_flags & KSMBD_USER_FLAG_GUEST_ACCOUNT && -+ deny) { -+ pr_debug("treecon: Deny, restricted session\n"); -+ resp->status = KSMBD_TREE_CONN_STATUS_ERROR; -+ goto out_error; -+ } -+ } -+ -+ if ((req->account_flags & KSMBD_USER_FLAG_GUEST_ACCOUNT) && -+ !test_share_flag(share, KSMBD_SHARE_FLAG_PIPE) && -+ !test_share_flag(share, KSMBD_SHARE_FLAG_GUEST_OK)) { -+ pr_debug("treecon: Deny, guest not allowed\n"); -+ resp->status = KSMBD_TREE_CONN_STATUS_ERROR; -+ goto out_error; -+ } -+ -+ if ((req->account_flags & KSMBD_USER_FLAG_GUEST_ACCOUNT) && -+ test_share_flag(share, KSMBD_SHARE_FLAG_GUEST_OK)) { -+ pr_debug("treecon: Net share permits guest login\n"); -+ user = usm_lookup_user(share->guest_account); -+ if (user) { -+ set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_GUEST_ACCOUNT); -+ goto bind; -+ } -+ -+ user = usm_lookup_user(global_conf.guest_account); -+ if (user) { -+ set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_GUEST_ACCOUNT); -+ goto bind; -+ } -+ } -+ -+ user = usm_lookup_user(req->account); -+ if (!user) { -+ resp->status = KSMBD_TREE_CONN_STATUS_NO_USER; -+ pr_err("treecon: User `%s' not found\n", req->account); -+ goto out_error; -+ } -+ -+ user->failed_login_count = 0; -+ user->flags &= ~KSMBD_USER_FLAG_DELAY_SESSION; -+ -+ if (test_user_flag(user, KSMBD_USER_FLAG_GUEST_ACCOUNT)) -+ set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_GUEST_ACCOUNT); -+ -+ ret = shm_lookup_users_map(share, -+ KSMBD_SHARE_ADMIN_USERS_MAP, -+ req->account); -+ if (ret == 0) { -+ set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_ADMIN_ACCOUNT); -+ goto bind; -+ } -+ -+ ret = shm_lookup_users_map(share, -+ KSMBD_SHARE_INVALID_USERS_MAP, -+ req->account); -+ if (ret == 0) { -+ resp->status = KSMBD_TREE_CONN_STATUS_INVALID_USER; -+ pr_err("treecon: User is on invalid users list\n"); -+ goto out_error; -+ } -+ -+ ret = shm_lookup_users_map(share, -+ KSMBD_SHARE_READ_LIST_MAP, -+ req->account); -+ if (ret == 0) { -+ set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_READ_ONLY); -+ clear_conn_flag(conn, KSMBD_TREE_CONN_FLAG_WRITABLE); -+ goto bind; -+ } -+ -+ ret = shm_lookup_users_map(share, -+ KSMBD_SHARE_WRITE_LIST_MAP, -+ req->account); -+ if (ret == 0) { -+ set_conn_flag(conn, KSMBD_TREE_CONN_FLAG_WRITABLE); -+ goto bind; -+ } -+ -+ ret = shm_lookup_users_map(share, -+ KSMBD_SHARE_VALID_USERS_MAP, -+ req->account); -+ if (ret == 0) -+ goto bind; -+ if (ret == -ENOENT) { -+ resp->status = KSMBD_TREE_CONN_STATUS_INVALID_USER; -+ pr_err("treecon: User is not on valid users list\n"); -+ goto out_error; -+ } -+ -+bind: -+ conn->id = req->connect_id; -+ conn->share = share; -+ resp->status = KSMBD_TREE_CONN_STATUS_OK; -+ resp->connection_flags = conn->flags; -+ -+ if (sm_handle_tree_connect(req->session_id, user, conn)) { -+ pr_err("treecon: Unable to bind tree connection\n"); -+ tcm_tree_conn_free(conn); -+ put_ksmbd_user(user); -+ } -+ -+ g_rw_lock_writer_lock(&share->update_lock); -+ clear_share_flag(share, KSMBD_SHARE_FLAG_UPDATE); -+ g_rw_lock_writer_unlock(&share->update_lock); -+ -+ return 0; -+out_error: -+ tcm_tree_conn_free(conn); -+ shm_close_connection(share); -+ put_ksmbd_share(share); -+ put_ksmbd_user(user); -+ return -EINVAL; -+} -+ -+int tcm_handle_tree_disconnect(unsigned long long sess_id, -+ unsigned long long tree_conn_id) -+{ -+ sm_handle_tree_disconnect(sess_id, tree_conn_id); -+ return 0; -+} ---- a/lib/management/user.c -+++ /dev/null -@@ -1,412 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-or-later --/* -- * Copyright (C) 2018 Samsung Electronics Co., Ltd. -- * -- * linux-cifsd-devel@lists.sourceforge.net -- */ -- --#include --#include --#include -- --#include "linux/ksmbd_server.h" --#include "management/user.h" --#include "ksmbdtools.h" -- --#define KSMBD_USER_STATE_FREEING 1 -- --static GHashTable *users_table; --static GRWLock users_table_lock; -- --static void kill_ksmbd_user(struct ksmbd_user *user) --{ -- pr_debug("Kill user `%s'\n", user->name); -- -- free(user->name); -- free(user->pass_b64); -- free(user->pass); -- g_rw_lock_clear(&user->update_lock); -- g_free(user); --} -- --static int __usm_remove_user(struct ksmbd_user *user) --{ -- int ret = 0; -- -- if (user->state != KSMBD_USER_STATE_FREEING) { -- g_rw_lock_writer_lock(&users_table_lock); -- if (!g_hash_table_remove(users_table, user->name)) -- ret = -EINVAL; -- g_rw_lock_writer_unlock(&users_table_lock); -- } -- if (!ret) -- kill_ksmbd_user(user); -- return ret; --} -- --struct ksmbd_user *get_ksmbd_user(struct ksmbd_user *user) --{ -- g_rw_lock_writer_lock(&user->update_lock); -- if (user->ref_count != 0) { -- user->ref_count++; -- g_rw_lock_writer_unlock(&user->update_lock); -- } else { -- g_rw_lock_writer_unlock(&user->update_lock); -- user = NULL; -- } -- return user; --} -- --void put_ksmbd_user(struct ksmbd_user *user) --{ -- int drop; -- -- if (!user) -- return; -- -- g_rw_lock_writer_lock(&user->update_lock); -- user->ref_count--; -- drop = !user->ref_count; -- g_rw_lock_writer_unlock(&user->update_lock); -- -- if (!drop) -- return; -- -- __usm_remove_user(user); --} -- --static gboolean put_user_callback(gpointer _k, gpointer _v, gpointer data) --{ -- struct ksmbd_user *user = (struct ksmbd_user *)_v; -- -- user->state = KSMBD_USER_STATE_FREEING; -- put_ksmbd_user(user); -- return TRUE; --} -- --void usm_remove_all_users(void) --{ -- g_rw_lock_writer_lock(&users_table_lock); -- g_hash_table_foreach_remove(users_table, put_user_callback, NULL); -- g_rw_lock_writer_unlock(&users_table_lock); --} -- --static struct ksmbd_user *new_ksmbd_user(char *name, char *pwd) --{ -- struct ksmbd_user *user; -- struct passwd *passwd; -- size_t pass_sz; -- -- user = g_try_malloc0(sizeof(struct ksmbd_user)); -- if (!user) -- return NULL; -- -- g_rw_lock_init(&user->update_lock); -- user->name = name; -- user->pass_b64 = pwd; -- user->ref_count = 1; -- user->gid = 9999; -- user->uid = 9999; -- passwd = getpwnam(name); -- if (passwd) { -- user->uid = passwd->pw_uid; -- user->gid = passwd->pw_gid; -- } -- -- user->pass = base64_decode(user->pass_b64, &pass_sz); -- user->pass_sz = (int)pass_sz; -- return user; --} -- --static void free_hash_entry(gpointer k, gpointer u, gpointer user_data) --{ -- kill_ksmbd_user(u); --} -- --static void usm_clear_users(void) --{ -- g_hash_table_foreach(users_table, free_hash_entry, NULL); --} -- --void usm_destroy(void) --{ -- if (users_table) { -- usm_clear_users(); -- g_hash_table_destroy(users_table); -- } -- g_rw_lock_clear(&users_table_lock); --} -- --int usm_init(void) --{ -- users_table = g_hash_table_new(g_str_hash, g_str_equal); -- if (!users_table) -- return -ENOMEM; -- g_rw_lock_init(&users_table_lock); -- return 0; --} -- --static struct ksmbd_user *__usm_lookup_user(char *name) --{ -- return g_hash_table_lookup(users_table, name); --} -- --struct ksmbd_user *usm_lookup_user(char *name) --{ -- struct ksmbd_user *user, *ret; -- -- if (!name) -- return NULL; -- -- g_rw_lock_reader_lock(&users_table_lock); -- user = __usm_lookup_user(name); -- if (user) { -- ret = get_ksmbd_user(user); -- if (!ret) -- user = NULL; -- } -- g_rw_lock_reader_unlock(&users_table_lock); -- return user; --} -- --int usm_add_new_user(char *name, char *pwd) --{ -- int ret = 0; -- struct ksmbd_user *user = new_ksmbd_user(name, pwd); -- -- if (!user) { -- free(name); -- free(pwd); -- return -ENOMEM; -- } -- -- g_rw_lock_writer_lock(&users_table_lock); -- if (__usm_lookup_user(name)) { -- g_rw_lock_writer_unlock(&users_table_lock); -- pr_info("User `%s' already exists\n", name); -- kill_ksmbd_user(user); -- return 0; -- } -- -- pr_debug("New user `%s'\n", user->name); -- if (!g_hash_table_insert(users_table, user->name, user)) { -- kill_ksmbd_user(user); -- ret = -EINVAL; -- } -- g_rw_lock_writer_unlock(&users_table_lock); -- return ret; --} -- --int usm_add_update_user_from_pwdentry(char *data) --{ -- struct ksmbd_user *user; -- char *name; -- char *pwd; -- char *pos = strchr(data, ':'); -- int ret; -- -- if (!pos) { -- pr_err("Invalid pwd entry: %s\n", data); -- return -EINVAL; -- } -- -- *pos = 0x00; -- name = g_strdup(data); -- pwd = g_strdup(pos + 1); -- -- if (!name || !pwd) { -- free(name); -- free(pwd); -- return -ENOMEM; -- } -- -- user = usm_lookup_user(name); -- if (user) { -- ret = usm_update_user_password(user, pwd); -- put_ksmbd_user(user); -- -- free(name); -- free(pwd); -- return ret; -- } -- return usm_add_new_user(name, pwd); --} -- --int usm_add_subauth_global_conf(char *data) --{ -- char *pos = data; -- char *spos; -- -- if (!pos) -- return -EINVAL; -- -- spos = strchr(pos, ':'); -- if (!spos) { -- pr_err("Invalid subauth entry: %s\n", data); -- return -EINVAL; -- } -- -- *spos = 0x00; -- global_conf.gen_subauth[0] = atoi(pos); -- pos = spos + 1; -- -- spos = strchr(pos, ':'); -- if (!spos) { -- pr_err("Invalid subauth entry: %s\n", data); -- return -EINVAL; -- } -- *spos = 0x00; -- global_conf.gen_subauth[1] = atoi(pos); -- global_conf.gen_subauth[2] = atoi(spos + 1); -- -- return 0; --} -- --void for_each_ksmbd_user(walk_users cb, gpointer user_data) --{ -- g_rw_lock_reader_lock(&users_table_lock); -- g_hash_table_foreach(users_table, cb, user_data); -- g_rw_lock_reader_unlock(&users_table_lock); --} -- --int usm_update_user_password(struct ksmbd_user *user, char *pswd) --{ -- size_t pass_sz; -- char *pass_b64 = g_strdup(pswd); -- char *pass = base64_decode(pass_b64, &pass_sz); -- -- if (!pass_b64 || !pass) { -- free(pass_b64); -- free(pass); -- pr_err("Out of memory\n"); -- return -ENOMEM; -- } -- -- pr_debug("Update user password: %s\n", user->name); -- g_rw_lock_writer_lock(&user->update_lock); -- free(user->pass_b64); -- free(user->pass); -- user->pass_b64 = pass_b64; -- user->pass = pass; -- user->pass_sz = (int)pass_sz; -- g_rw_lock_writer_unlock(&user->update_lock); -- -- return 0; --} -- --static int usm_copy_user_passhash(struct ksmbd_user *user, -- char *pass, -- size_t sz) --{ -- int ret = -ENOSPC; -- -- if (test_user_flag(user, KSMBD_USER_FLAG_GUEST_ACCOUNT)) -- return 0; -- -- g_rw_lock_reader_lock(&user->update_lock); -- if (sz >= user->pass_sz) { -- memcpy(pass, user->pass, user->pass_sz); -- ret = user->pass_sz; -- } -- g_rw_lock_reader_unlock(&user->update_lock); -- -- return ret; --} -- --static int usm_copy_user_account(struct ksmbd_user *user, -- char *account, -- size_t sz) --{ -- int account_sz; -- -- if (test_user_flag(user, KSMBD_USER_FLAG_GUEST_ACCOUNT)) -- return 0; -- -- account_sz = strlen(user->name); -- if (sz >= account_sz) { -- memcpy(account, user->name, account_sz); -- return 0; -- } -- pr_err("Cannot copy user data, buffer overrun\n"); -- return -ENOSPC; --} -- --static void __handle_login_request(struct ksmbd_login_response *resp, -- struct ksmbd_user *user) --{ -- int hash_sz; -- -- resp->gid = user->gid; -- resp->uid = user->uid; -- resp->status = user->flags; -- resp->status |= KSMBD_USER_FLAG_OK; -- -- hash_sz = usm_copy_user_passhash(user, -- resp->hash, -- sizeof(resp->hash)); -- if (hash_sz < 0) { -- resp->status = KSMBD_USER_FLAG_INVALID; -- } else { -- resp->hash_sz = (unsigned short)hash_sz; -- if (usm_copy_user_account(user, -- resp->account, -- sizeof(resp->account))) -- resp->status = KSMBD_USER_FLAG_INVALID; -- } --} -- --int usm_handle_login_request(struct ksmbd_login_request *req, -- struct ksmbd_login_response *resp) --{ -- struct ksmbd_user *user = NULL; -- int null_session = 0; -- -- if (req->account[0] == '\0') -- null_session = 1; -- -- if (!null_session) -- user = usm_lookup_user(req->account); -- if (user) { -- __handle_login_request(resp, user); -- put_ksmbd_user(user); -- return 0; -- } -- -- resp->status = KSMBD_USER_FLAG_BAD_USER; -- if (!null_session && -- global_conf.map_to_guest == KSMBD_CONF_MAP_TO_GUEST_NEVER) -- return 0; -- -- if (null_session || -- global_conf.map_to_guest == KSMBD_CONF_MAP_TO_GUEST_BAD_USER) -- user = usm_lookup_user(global_conf.guest_account); -- -- if (!user) -- return 0; -- -- __handle_login_request(resp, user); -- put_ksmbd_user(user); -- return 0; --} -- --int usm_handle_logout_request(struct ksmbd_logout_request *req) --{ -- struct ksmbd_user *user; -- -- user = usm_lookup_user(req->account); -- if (!user) -- return -ENOENT; -- -- if (req->account_flags & KSMBD_USER_FLAG_BAD_PASSWORD) { -- if (user->failed_login_count < 10) -- user->failed_login_count++; -- else -- user->flags |= KSMBD_USER_FLAG_DELAY_SESSION; -- } else { -- user->failed_login_count = 0; -- user->flags &= ~KSMBD_USER_FLAG_DELAY_SESSION; -- } -- -- put_ksmbd_user(user); -- return 0; --} ---- /dev/null -+++ b/tools/management/user.c -@@ -0,0 +1,412 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Copyright (C) 2018 Samsung Electronics Co., Ltd. -+ * -+ * linux-cifsd-devel@lists.sourceforge.net -+ */ -+ -+#include -+#include -+#include -+ -+#include "linux/ksmbd_server.h" -+#include "management/user.h" -+#include "tools.h" -+ -+#define KSMBD_USER_STATE_FREEING 1 -+ -+static GHashTable *users_table; -+static GRWLock users_table_lock; -+ -+static void kill_ksmbd_user(struct ksmbd_user *user) -+{ -+ pr_debug("Kill user `%s'\n", user->name); -+ -+ free(user->name); -+ free(user->pass_b64); -+ free(user->pass); -+ g_rw_lock_clear(&user->update_lock); -+ g_free(user); -+} -+ -+static int __usm_remove_user(struct ksmbd_user *user) -+{ -+ int ret = 0; -+ -+ if (user->state != KSMBD_USER_STATE_FREEING) { -+ g_rw_lock_writer_lock(&users_table_lock); -+ if (!g_hash_table_remove(users_table, user->name)) -+ ret = -EINVAL; -+ g_rw_lock_writer_unlock(&users_table_lock); -+ } -+ if (!ret) -+ kill_ksmbd_user(user); -+ return ret; -+} -+ -+struct ksmbd_user *get_ksmbd_user(struct ksmbd_user *user) -+{ -+ g_rw_lock_writer_lock(&user->update_lock); -+ if (user->ref_count != 0) { -+ user->ref_count++; -+ g_rw_lock_writer_unlock(&user->update_lock); -+ } else { -+ g_rw_lock_writer_unlock(&user->update_lock); -+ user = NULL; -+ } -+ return user; -+} -+ -+void put_ksmbd_user(struct ksmbd_user *user) -+{ -+ int drop; -+ -+ if (!user) -+ return; -+ -+ g_rw_lock_writer_lock(&user->update_lock); -+ user->ref_count--; -+ drop = !user->ref_count; -+ g_rw_lock_writer_unlock(&user->update_lock); -+ -+ if (!drop) -+ return; -+ -+ __usm_remove_user(user); -+} -+ -+static gboolean put_user_callback(gpointer _k, gpointer _v, gpointer data) -+{ -+ struct ksmbd_user *user = (struct ksmbd_user *)_v; -+ -+ user->state = KSMBD_USER_STATE_FREEING; -+ put_ksmbd_user(user); -+ return TRUE; -+} -+ -+void usm_remove_all_users(void) -+{ -+ g_rw_lock_writer_lock(&users_table_lock); -+ g_hash_table_foreach_remove(users_table, put_user_callback, NULL); -+ g_rw_lock_writer_unlock(&users_table_lock); -+} -+ -+static struct ksmbd_user *new_ksmbd_user(char *name, char *pwd) -+{ -+ struct ksmbd_user *user; -+ struct passwd *passwd; -+ size_t pass_sz; -+ -+ user = g_try_malloc0(sizeof(struct ksmbd_user)); -+ if (!user) -+ return NULL; -+ -+ g_rw_lock_init(&user->update_lock); -+ user->name = name; -+ user->pass_b64 = pwd; -+ user->ref_count = 1; -+ user->gid = 9999; -+ user->uid = 9999; -+ passwd = getpwnam(name); -+ if (passwd) { -+ user->uid = passwd->pw_uid; -+ user->gid = passwd->pw_gid; -+ } -+ -+ user->pass = base64_decode(user->pass_b64, &pass_sz); -+ user->pass_sz = (int)pass_sz; -+ return user; -+} -+ -+static void free_hash_entry(gpointer k, gpointer u, gpointer user_data) -+{ -+ kill_ksmbd_user(u); -+} -+ -+static void usm_clear_users(void) -+{ -+ g_hash_table_foreach(users_table, free_hash_entry, NULL); -+} -+ -+void usm_destroy(void) -+{ -+ if (users_table) { -+ usm_clear_users(); -+ g_hash_table_destroy(users_table); -+ } -+ g_rw_lock_clear(&users_table_lock); -+} -+ -+int usm_init(void) -+{ -+ users_table = g_hash_table_new(g_str_hash, g_str_equal); -+ if (!users_table) -+ return -ENOMEM; -+ g_rw_lock_init(&users_table_lock); -+ return 0; -+} -+ -+static struct ksmbd_user *__usm_lookup_user(char *name) -+{ -+ return g_hash_table_lookup(users_table, name); -+} -+ -+struct ksmbd_user *usm_lookup_user(char *name) -+{ -+ struct ksmbd_user *user, *ret; -+ -+ if (!name) -+ return NULL; -+ -+ g_rw_lock_reader_lock(&users_table_lock); -+ user = __usm_lookup_user(name); -+ if (user) { -+ ret = get_ksmbd_user(user); -+ if (!ret) -+ user = NULL; -+ } -+ g_rw_lock_reader_unlock(&users_table_lock); -+ return user; -+} -+ -+int usm_add_new_user(char *name, char *pwd) -+{ -+ int ret = 0; -+ struct ksmbd_user *user = new_ksmbd_user(name, pwd); -+ -+ if (!user) { -+ free(name); -+ free(pwd); -+ return -ENOMEM; -+ } -+ -+ g_rw_lock_writer_lock(&users_table_lock); -+ if (__usm_lookup_user(name)) { -+ g_rw_lock_writer_unlock(&users_table_lock); -+ pr_info("User `%s' already exists\n", name); -+ kill_ksmbd_user(user); -+ return 0; -+ } -+ -+ pr_debug("New user `%s'\n", user->name); -+ if (!g_hash_table_insert(users_table, user->name, user)) { -+ kill_ksmbd_user(user); -+ ret = -EINVAL; -+ } -+ g_rw_lock_writer_unlock(&users_table_lock); -+ return ret; -+} -+ -+int usm_add_update_user_from_pwdentry(char *data) -+{ -+ struct ksmbd_user *user; -+ char *name; -+ char *pwd; -+ char *pos = strchr(data, ':'); -+ int ret; -+ -+ if (!pos) { -+ pr_err("Invalid pwd entry: %s\n", data); -+ return -EINVAL; -+ } -+ -+ *pos = 0x00; -+ name = g_strdup(data); -+ pwd = g_strdup(pos + 1); -+ -+ if (!name || !pwd) { -+ free(name); -+ free(pwd); -+ return -ENOMEM; -+ } -+ -+ user = usm_lookup_user(name); -+ if (user) { -+ ret = usm_update_user_password(user, pwd); -+ put_ksmbd_user(user); -+ -+ free(name); -+ free(pwd); -+ return ret; -+ } -+ return usm_add_new_user(name, pwd); -+} -+ -+int usm_add_subauth_global_conf(char *data) -+{ -+ char *pos = data; -+ char *spos; -+ -+ if (!pos) -+ return -EINVAL; -+ -+ spos = strchr(pos, ':'); -+ if (!spos) { -+ pr_err("Invalid subauth entry: %s\n", data); -+ return -EINVAL; -+ } -+ -+ *spos = 0x00; -+ global_conf.gen_subauth[0] = atoi(pos); -+ pos = spos + 1; -+ -+ spos = strchr(pos, ':'); -+ if (!spos) { -+ pr_err("Invalid subauth entry: %s\n", data); -+ return -EINVAL; -+ } -+ *spos = 0x00; -+ global_conf.gen_subauth[1] = atoi(pos); -+ global_conf.gen_subauth[2] = atoi(spos + 1); -+ -+ return 0; -+} -+ -+void for_each_ksmbd_user(walk_users cb, gpointer user_data) -+{ -+ g_rw_lock_reader_lock(&users_table_lock); -+ g_hash_table_foreach(users_table, cb, user_data); -+ g_rw_lock_reader_unlock(&users_table_lock); -+} -+ -+int usm_update_user_password(struct ksmbd_user *user, char *pswd) -+{ -+ size_t pass_sz; -+ char *pass_b64 = g_strdup(pswd); -+ char *pass = base64_decode(pass_b64, &pass_sz); -+ -+ if (!pass_b64 || !pass) { -+ free(pass_b64); -+ free(pass); -+ pr_err("Out of memory\n"); -+ return -ENOMEM; -+ } -+ -+ pr_debug("Update user password: %s\n", user->name); -+ g_rw_lock_writer_lock(&user->update_lock); -+ free(user->pass_b64); -+ free(user->pass); -+ user->pass_b64 = pass_b64; -+ user->pass = pass; -+ user->pass_sz = (int)pass_sz; -+ g_rw_lock_writer_unlock(&user->update_lock); -+ -+ return 0; -+} -+ -+static int usm_copy_user_passhash(struct ksmbd_user *user, -+ char *pass, -+ size_t sz) -+{ -+ int ret = -ENOSPC; -+ -+ if (test_user_flag(user, KSMBD_USER_FLAG_GUEST_ACCOUNT)) -+ return 0; -+ -+ g_rw_lock_reader_lock(&user->update_lock); -+ if (sz >= user->pass_sz) { -+ memcpy(pass, user->pass, user->pass_sz); -+ ret = user->pass_sz; -+ } -+ g_rw_lock_reader_unlock(&user->update_lock); -+ -+ return ret; -+} -+ -+static int usm_copy_user_account(struct ksmbd_user *user, -+ char *account, -+ size_t sz) -+{ -+ int account_sz; -+ -+ if (test_user_flag(user, KSMBD_USER_FLAG_GUEST_ACCOUNT)) -+ return 0; -+ -+ account_sz = strlen(user->name); -+ if (sz >= account_sz) { -+ memcpy(account, user->name, account_sz); -+ return 0; -+ } -+ pr_err("Cannot copy user data, buffer overrun\n"); -+ return -ENOSPC; -+} -+ -+static void __handle_login_request(struct ksmbd_login_response *resp, -+ struct ksmbd_user *user) -+{ -+ int hash_sz; -+ -+ resp->gid = user->gid; -+ resp->uid = user->uid; -+ resp->status = user->flags; -+ resp->status |= KSMBD_USER_FLAG_OK; -+ -+ hash_sz = usm_copy_user_passhash(user, -+ resp->hash, -+ sizeof(resp->hash)); -+ if (hash_sz < 0) { -+ resp->status = KSMBD_USER_FLAG_INVALID; -+ } else { -+ resp->hash_sz = (unsigned short)hash_sz; -+ if (usm_copy_user_account(user, -+ resp->account, -+ sizeof(resp->account))) -+ resp->status = KSMBD_USER_FLAG_INVALID; -+ } -+} -+ -+int usm_handle_login_request(struct ksmbd_login_request *req, -+ struct ksmbd_login_response *resp) -+{ -+ struct ksmbd_user *user = NULL; -+ int null_session = 0; -+ -+ if (req->account[0] == '\0') -+ null_session = 1; -+ -+ if (!null_session) -+ user = usm_lookup_user(req->account); -+ if (user) { -+ __handle_login_request(resp, user); -+ put_ksmbd_user(user); -+ return 0; -+ } -+ -+ resp->status = KSMBD_USER_FLAG_BAD_USER; -+ if (!null_session && -+ global_conf.map_to_guest == KSMBD_CONF_MAP_TO_GUEST_NEVER) -+ return 0; -+ -+ if (null_session || -+ global_conf.map_to_guest == KSMBD_CONF_MAP_TO_GUEST_BAD_USER) -+ user = usm_lookup_user(global_conf.guest_account); -+ -+ if (!user) -+ return 0; -+ -+ __handle_login_request(resp, user); -+ put_ksmbd_user(user); -+ return 0; -+} -+ -+int usm_handle_logout_request(struct ksmbd_logout_request *req) -+{ -+ struct ksmbd_user *user; -+ -+ user = usm_lookup_user(req->account); -+ if (!user) -+ return -ENOENT; -+ -+ if (req->account_flags & KSMBD_USER_FLAG_BAD_PASSWORD) { -+ if (user->failed_login_count < 10) -+ user->failed_login_count++; -+ else -+ user->flags |= KSMBD_USER_FLAG_DELAY_SESSION; -+ } else { -+ user->failed_login_count = 0; -+ user->flags &= ~KSMBD_USER_FLAG_DELAY_SESSION; -+ } -+ -+ put_ksmbd_user(user); -+ return 0; -+} ---- a/lib/meson.build -+++ /dev/null -@@ -1,31 +0,0 @@ --core_files = [ -- 'management/tree_conn.c', -- 'management/user.c', -- 'management/share.c', -- 'management/session.c', -- 'config_parser.c', -- 'ksmbdtools.c', --] -- --if krb5_dep.found() -- core_files += [ -- 'management/spnego.c', -- 'asn1.c', -- 'management/spnego_krb5.c', -- ] --endif -- --libksmbdtools = static_library( -- 'ksmbdtools', -- core_files, -- include_directories: tools_incdir, -- dependencies: [ -- glib_dep, -- krb5_dep, -- asn1_lib, -- ], -- c_args: [ -- '-DSYSCONFDIR="@0@"'.format(get_option('prefix') / get_option('sysconfdir')), -- '-DRUNSTATEDIR="@0@"'.format(runstatedir), -- ], --) ---- /dev/null -+++ b/tools/meson.build -@@ -0,0 +1,39 @@ -+ksmbd_tools_files = [ -+ 'management/tree_conn.c', -+ 'management/user.c', -+ 'management/share.c', -+ 'management/session.c', -+ 'config_parser.c', -+ 'tools.c', -+] -+ -+if krb5_dep.found() -+ ksmbd_tools_files += [ -+ 'management/spnego.c', -+ 'asn1.c', -+ 'management/spnego_krb5.c', -+ ] -+endif -+ -+executable( -+ 'ksmbd.tools', -+ ksmbd_tools_files, -+ include_directories: include_dirs, -+ c_args: [ -+ '-DSYSCONFDIR="@0@"'.format(get_option('prefix') / get_option('sysconfdir')), -+ '-DRUNSTATEDIR="@0@"'.format(runstatedir), -+ ], -+ dependencies: [ -+ glib_dep, -+ krb5_dep, -+ asn1_lib, -+ ], -+ link_with: [ -+ addshare_lib, -+ adduser_lib, -+ control_lib, -+ mountd_lib, -+ ], -+ install: true, -+ install_dir: get_option('libexecdir'), -+) ---- a/lib/ksmbdtools.c -+++ /dev/null -@@ -1,276 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-or-later --/* -- * Copyright (C) 2018 Samsung Electronics Co., Ltd. -- * -- * linux-cifsd-devel@lists.sourceforge.net -- */ -- --#include -- --#include --#include --#include -- --#include --#include -- --int log_level = PR_INFO; --int ksmbd_health_status; -- --static const char *app_name = "unknown"; --static int log_open; -- --typedef void (*logger)(int level, const char *fmt, va_list list); -- --char *ksmbd_conv_charsets[KSMBD_CHARSET_MAX + 1] = { -- "UTF-8", -- "UTF-16LE", -- "UCS-2LE", -- "UTF-16BE", -- "UCS-2BE", -- "OOPS" --}; -- --static int syslog_level(int level) --{ -- if (level == PR_ERROR) -- return LOG_ERR; -- if (level == PR_INFO) -- return LOG_INFO; -- if (level == PR_DEBUG) -- return LOG_DEBUG; -- -- return LOG_ERR; --} -- --G_GNUC_PRINTF(2, 0) --static void __pr_log_stdio(int level, const char *fmt, va_list list) --{ -- char buf[1024]; -- -- vsnprintf(buf, sizeof(buf), fmt, list); -- printf("%s", buf); --} -- --G_GNUC_PRINTF(2, 0) --static void __pr_log_syslog(int level, const char *fmt, va_list list) --{ -- vsyslog(syslog_level(level), fmt, list); --} -- --static logger __logger = __pr_log_stdio; -- --void set_logger_app_name(const char *an) --{ -- app_name = an; --} -- --const char *get_logger_app_name(void) --{ -- return app_name; --} -- --void __pr_log(int level, const char *fmt, ...) --{ -- va_list list; -- -- va_start(list, fmt); -- __logger(level, fmt, list); -- va_end(list); --} -- --void pr_logger_init(int flag) --{ -- if (flag == PR_LOGGER_SYSLOG) { -- if (log_open) { -- closelog(); -- log_open = 0; -- } -- openlog("ksmbd", LOG_NDELAY, LOG_LOCAL5); -- __logger = __pr_log_syslog; -- log_open = 1; -- } --} -- --int set_log_level(int level) --{ -- int old_level; -- -- if (log_level == PR_DEBUG) -- return log_level; -- -- old_level = log_level; -- log_level = level; -- return old_level; --} -- --#if TRACING_DUMP_NL_MSG --#define PR_HEX_DUMP_WIDTH 160 --void pr_hex_dump(const void *mem, size_t sz) --{ -- char xline[PR_HEX_DUMP_WIDTH]; -- char sline[PR_HEX_DUMP_WIDTH]; -- int xi = 0, si = 0, mi = 0; -- -- while (mi < sz) { -- char c = *((char *)mem + mi); -- -- mi++; -- xi += sprintf(xline + xi, "%02X ", 0xff & c); -- if (c > ' ' && c < '~') -- si += sprintf(sline + si, "%c", c); -- else -- si += sprintf(sline + si, "."); -- if (xi >= PR_HEX_DUMP_WIDTH / 2) { -- pr_err("%s %s\n", xline, sline); -- xi = 0; -- si = 0; -- } -- } -- -- if (xi) { -- int sz = PR_HEX_DUMP_WIDTH / 2 - xi + 1; -- -- if (sz > 0) { -- memset(xline + xi, ' ', sz); -- xline[PR_HEX_DUMP_WIDTH / 2 + 1] = 0x00; -- } -- pr_err("%s %s\n", xline, sline); -- } --} --#else --void pr_hex_dump(const void *mem, size_t sz) --{ --} --#endif -- --char *base64_encode(unsigned char *src, size_t srclen) --{ -- return g_base64_encode(src, srclen); --} -- --unsigned char *base64_decode(char const *src, size_t *dstlen) --{ -- unsigned char *ret = g_base64_decode(src, dstlen); -- -- if (ret) -- ret[*dstlen] = 0x00; -- return ret; --} -- --static int codeset_has_altname(int codeset) --{ -- if (codeset == KSMBD_CHARSET_UTF16LE || -- codeset == KSMBD_CHARSET_UTF16BE) -- return 1; -- return 0; --} -- --gchar *ksmbd_gconvert(const gchar *str, -- gssize str_len, -- int to_codeset, -- int from_codeset, -- gsize *bytes_read, -- gsize *bytes_written) --{ -- gchar *converted; -- GError *err; -- --retry: -- err = NULL; -- if (from_codeset >= KSMBD_CHARSET_MAX) { -- pr_err("Unknown source codeset: %d\n", from_codeset); -- return NULL; -- } -- -- if (to_codeset >= KSMBD_CHARSET_MAX) { -- pr_err("Unknown target codeset: %d\n", to_codeset); -- return NULL; -- } -- -- converted = g_convert(str, -- str_len, -- ksmbd_conv_charsets[to_codeset], -- ksmbd_conv_charsets[from_codeset], -- bytes_read, -- bytes_written, -- &err); -- if (err) { -- int has_altname = 0; -- -- if (codeset_has_altname(to_codeset)) { -- to_codeset++; -- has_altname = 1; -- } -- -- if (codeset_has_altname(from_codeset)) { -- from_codeset++; -- has_altname = 1; -- } -- -- pr_info("%s\n", err->message); -- g_error_free(err); -- -- if (has_altname) { -- pr_info("Will try `%s' and `%s'\n", -- ksmbd_conv_charsets[to_codeset], -- ksmbd_conv_charsets[from_codeset]); -- goto retry; -- } -- -- pr_err("Can't convert string: %s\n", err->message); -- g_error_free(err); -- return NULL; -- } -- -- return converted; --} -- --int send_signal_to_ksmbd_mountd(int signo) --{ -- int fd, ret = -EINVAL; -- char pid_buf[10] = {0}; -- int pid; -- -- fd = open(KSMBD_LOCK_FILE, O_RDONLY); -- if (fd < 0) { -- pr_debug("Can't open `%s': %m\n", KSMBD_LOCK_FILE); -- return ret; -- } -- -- if (read(fd, &pid_buf, sizeof(pid_buf)) == -1) { -- pr_err("Can't read manager PID: %m\n"); -- goto out; -- } -- -- pid = strtol(pid_buf, NULL, 10); -- if (signo) -- pr_debug("Send signal %d (%s) to PID %d\n", -- signo, strsignal(signo), pid); -- if (kill(pid, signo) == -1) { -- ret = -errno; -- if (signo) -- pr_err("Unable to send signal %d (%s) to PID %d: %m\n", -- signo, strsignal(signo), pid); -- goto out; -- } -- -- ret = 0; --out: -- close(fd); -- return ret; --} -- --int test_file_access(char *conf) --{ -- int fd; -- -- fd = open(conf, O_RDWR | O_CREAT, S_IRWXU | S_IRGRP); -- if (fd < 0) { -- pr_debug("Can't open `%s': %m\n", conf); -- return -EINVAL; -- } -- -- close(fd); -- return 0; --} ---- /dev/null -+++ b/tools/tools.c -@@ -0,0 +1,301 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Copyright (C) 2018 Samsung Electronics Co., Ltd. -+ * -+ * linux-cifsd-devel@lists.sourceforge.net -+ */ -+ -+#include -+ -+#include -+#include -+#include -+ -+#include -+#include -+ -+int log_level = PR_INFO; -+int ksmbd_health_status; -+ -+static const char *app_name = "unknown"; -+static int log_open; -+ -+typedef void (*logger)(int level, const char *fmt, va_list list); -+ -+char *ksmbd_conv_charsets[KSMBD_CHARSET_MAX + 1] = { -+ "UTF-8", -+ "UTF-16LE", -+ "UCS-2LE", -+ "UTF-16BE", -+ "UCS-2BE", -+ "OOPS" -+}; -+ -+static int syslog_level(int level) -+{ -+ if (level == PR_ERROR) -+ return LOG_ERR; -+ if (level == PR_INFO) -+ return LOG_INFO; -+ if (level == PR_DEBUG) -+ return LOG_DEBUG; -+ -+ return LOG_ERR; -+} -+ -+G_GNUC_PRINTF(2, 0) -+static void __pr_log_stdio(int level, const char *fmt, va_list list) -+{ -+ char buf[1024]; -+ -+ vsnprintf(buf, sizeof(buf), fmt, list); -+ printf("%s", buf); -+} -+ -+G_GNUC_PRINTF(2, 0) -+static void __pr_log_syslog(int level, const char *fmt, va_list list) -+{ -+ vsyslog(syslog_level(level), fmt, list); -+} -+ -+static logger __logger = __pr_log_stdio; -+ -+void set_logger_app_name(const char *an) -+{ -+ app_name = an; -+} -+ -+const char *get_logger_app_name(void) -+{ -+ return app_name; -+} -+ -+void __pr_log(int level, const char *fmt, ...) -+{ -+ va_list list; -+ -+ va_start(list, fmt); -+ __logger(level, fmt, list); -+ va_end(list); -+} -+ -+void pr_logger_init(int flag) -+{ -+ if (flag == PR_LOGGER_SYSLOG) { -+ if (log_open) { -+ closelog(); -+ log_open = 0; -+ } -+ openlog("ksmbd", LOG_NDELAY, LOG_LOCAL5); -+ __logger = __pr_log_syslog; -+ log_open = 1; -+ } -+} -+ -+int set_log_level(int level) -+{ -+ int old_level; -+ -+ if (log_level == PR_DEBUG) -+ return log_level; -+ -+ old_level = log_level; -+ log_level = level; -+ return old_level; -+} -+ -+#if TRACING_DUMP_NL_MSG -+#define PR_HEX_DUMP_WIDTH 160 -+void pr_hex_dump(const void *mem, size_t sz) -+{ -+ char xline[PR_HEX_DUMP_WIDTH]; -+ char sline[PR_HEX_DUMP_WIDTH]; -+ int xi = 0, si = 0, mi = 0; -+ -+ while (mi < sz) { -+ char c = *((char *)mem + mi); -+ -+ mi++; -+ xi += sprintf(xline + xi, "%02X ", 0xff & c); -+ if (c > ' ' && c < '~') -+ si += sprintf(sline + si, "%c", c); -+ else -+ si += sprintf(sline + si, "."); -+ if (xi >= PR_HEX_DUMP_WIDTH / 2) { -+ pr_err("%s %s\n", xline, sline); -+ xi = 0; -+ si = 0; -+ } -+ } -+ -+ if (xi) { -+ int sz = PR_HEX_DUMP_WIDTH / 2 - xi + 1; -+ -+ if (sz > 0) { -+ memset(xline + xi, ' ', sz); -+ xline[PR_HEX_DUMP_WIDTH / 2 + 1] = 0x00; -+ } -+ pr_err("%s %s\n", xline, sline); -+ } -+} -+#else -+void pr_hex_dump(const void *mem, size_t sz) -+{ -+} -+#endif -+ -+char *base64_encode(unsigned char *src, size_t srclen) -+{ -+ return g_base64_encode(src, srclen); -+} -+ -+unsigned char *base64_decode(char const *src, size_t *dstlen) -+{ -+ unsigned char *ret = g_base64_decode(src, dstlen); -+ -+ if (ret) -+ ret[*dstlen] = 0x00; -+ return ret; -+} -+ -+static int codeset_has_altname(int codeset) -+{ -+ if (codeset == KSMBD_CHARSET_UTF16LE || -+ codeset == KSMBD_CHARSET_UTF16BE) -+ return 1; -+ return 0; -+} -+ -+gchar *ksmbd_gconvert(const gchar *str, -+ gssize str_len, -+ int to_codeset, -+ int from_codeset, -+ gsize *bytes_read, -+ gsize *bytes_written) -+{ -+ gchar *converted; -+ GError *err; -+ -+retry: -+ err = NULL; -+ if (from_codeset >= KSMBD_CHARSET_MAX) { -+ pr_err("Unknown source codeset: %d\n", from_codeset); -+ return NULL; -+ } -+ -+ if (to_codeset >= KSMBD_CHARSET_MAX) { -+ pr_err("Unknown target codeset: %d\n", to_codeset); -+ return NULL; -+ } -+ -+ converted = g_convert(str, -+ str_len, -+ ksmbd_conv_charsets[to_codeset], -+ ksmbd_conv_charsets[from_codeset], -+ bytes_read, -+ bytes_written, -+ &err); -+ if (err) { -+ int has_altname = 0; -+ -+ if (codeset_has_altname(to_codeset)) { -+ to_codeset++; -+ has_altname = 1; -+ } -+ -+ if (codeset_has_altname(from_codeset)) { -+ from_codeset++; -+ has_altname = 1; -+ } -+ -+ pr_info("%s\n", err->message); -+ g_error_free(err); -+ -+ if (has_altname) { -+ pr_info("Will try `%s' and `%s'\n", -+ ksmbd_conv_charsets[to_codeset], -+ ksmbd_conv_charsets[from_codeset]); -+ goto retry; -+ } -+ -+ pr_err("Can't convert string: %s\n", err->message); -+ g_error_free(err); -+ return NULL; -+ } -+ -+ return converted; -+} -+ -+int send_signal_to_ksmbd_mountd(int signo) -+{ -+ int fd, ret = -EINVAL; -+ char pid_buf[10] = {0}; -+ int pid; -+ -+ fd = open(KSMBD_LOCK_FILE, O_RDONLY); -+ if (fd < 0) { -+ pr_debug("Can't open `%s': %m\n", KSMBD_LOCK_FILE); -+ return ret; -+ } -+ -+ if (read(fd, &pid_buf, sizeof(pid_buf)) == -1) { -+ pr_err("Can't read manager PID: %m\n"); -+ goto out; -+ } -+ -+ pid = strtol(pid_buf, NULL, 10); -+ if (signo) -+ pr_debug("Send signal %d (%s) to PID %d\n", -+ signo, strsignal(signo), pid); -+ if (kill(pid, signo) == -1) { -+ ret = -errno; -+ if (signo) -+ pr_err("Unable to send signal %d (%s) to PID %d: %m\n", -+ signo, strsignal(signo), pid); -+ goto out; -+ } -+ -+ ret = 0; -+out: -+ close(fd); -+ return ret; -+} -+ -+int test_file_access(char *conf) -+{ -+ int fd; -+ -+ fd = open(conf, O_RDWR | O_CREAT, S_IRWXU | S_IRGRP); -+ if (fd < 0) { -+ pr_debug("Can't open `%s': %m\n", conf); -+ return -EINVAL; -+ } -+ -+ close(fd); -+ return 0; -+} -+ -+int main(int argc, char **argv) -+{ -+ char *base_name; -+ -+ set_logger_app_name("ksmbd.tools"); -+ -+ if (!*argv) -+ return EXIT_FAILURE; -+ -+ base_name = strrchr(*argv, '/'); -+ base_name = base_name ? base_name + 1 : *argv; -+ -+ if (!strcmp(base_name, "ksmbd.addshare")) -+ return addshare_main(argc, argv); -+ if (!strcmp(base_name, "ksmbd.adduser")) -+ return adduser_main(argc, argv); -+ if (!strcmp(base_name, "ksmbd.control")) -+ return control_main(argc, argv); -+ if (!strcmp(base_name, "ksmbd.mountd")) -+ return mountd_main(argc, argv); -+ -+ pr_err("Unknown base name: %s\n", base_name); -+ return EXIT_FAILURE; -+} ---- a/lib/asn1.c -+++ /dev/null -@@ -1,391 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-or-later --/* -- * The ASB.1/BER parsing code is derived from ip_nat_snmp_basic.c which was in -- * turn derived from the gxsnmp package by Gregory McLean & Jochen Friedrich -- * -- * Copyright (c) 2000 RP Internet (www.rpi.net.au). -- */ -- --/***************************************************************************** -- * -- * Basic ASN.1 decoding routines (gxsnmp author Dirk Wisse) -- * -- *****************************************************************************/ --#include --#include --#include --#include --#include -- --#include "asn1.h" -- --void --asn1_open(struct asn1_ctx *ctx, unsigned char *buf, unsigned int len) --{ -- ctx->begin = buf; -- ctx->end = buf + len; -- ctx->pointer = buf; -- ctx->error = ASN1_ERR_NOERROR; --} -- --static unsigned char --asn1_octet_decode(struct asn1_ctx *ctx, unsigned char *ch) --{ -- if (ctx->pointer >= ctx->end) { -- ctx->error = ASN1_ERR_DEC_EMPTY; -- return 0; -- } -- *ch = *(ctx->pointer)++; -- return 1; --} -- --static unsigned char --asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag) --{ -- unsigned char ch; -- -- *tag = 0; -- -- do { -- if (!asn1_octet_decode(ctx, &ch)) -- return 0; -- *tag <<= 7; -- *tag |= ch & 0x7F; -- } while ((ch & 0x80) == 0x80); -- return 1; --} -- --static unsigned char --asn1_id_decode(struct asn1_ctx *ctx, -- unsigned int *cls, unsigned int *con, unsigned int *tag) --{ -- unsigned char ch; -- -- if (!asn1_octet_decode(ctx, &ch)) -- return 0; -- -- *cls = (ch & 0xC0) >> 6; -- *con = (ch & 0x20) >> 5; -- *tag = (ch & 0x1F); -- -- if (*tag == 0x1F) { -- if (!asn1_tag_decode(ctx, tag)) -- return 0; -- } -- return 1; --} -- --static unsigned char --asn1_length_decode(struct asn1_ctx *ctx, unsigned int *def, unsigned int *len) --{ -- unsigned char ch, cnt; -- -- if (!asn1_octet_decode(ctx, &ch)) -- return 0; -- -- if (ch == 0x80) -- *def = 0; -- else { -- *def = 1; -- -- if (ch < 0x80) -- *len = ch; -- else { -- cnt = (unsigned char) (ch & 0x7F); -- *len = 0; -- -- while (cnt > 0) { -- if (!asn1_octet_decode(ctx, &ch)) -- return 0; -- *len <<= 8; -- *len |= ch; -- cnt--; -- } -- } -- } -- -- /* don't trust len bigger than ctx buffer */ -- if (*len > ctx->end - ctx->pointer) -- return 0; -- -- return 1; --} -- --unsigned char --asn1_header_decode(struct asn1_ctx *ctx, -- unsigned char **eoc, -- unsigned int *cls, unsigned int *con, unsigned int *tag) --{ -- unsigned int def = 0; -- unsigned int len = 0; -- -- if (!asn1_id_decode(ctx, cls, con, tag)) -- return 0; -- -- if (!asn1_length_decode(ctx, &def, &len)) -- return 0; -- -- /* primitive shall be definite, indefinite shall be constructed */ -- if (*con == ASN1_PRI && !def) -- return 0; -- -- if (def) -- *eoc = ctx->pointer + len; -- else -- *eoc = NULL; -- return 1; --} -- --static unsigned char --asn1_eoc_decode(struct asn1_ctx *ctx, unsigned char *eoc) --{ -- unsigned char ch; -- -- if (eoc == NULL) { -- if (!asn1_octet_decode(ctx, &ch)) -- return 0; -- -- if (ch != 0x00) { -- ctx->error = ASN1_ERR_DEC_EOC_MISMATCH; -- return 0; -- } -- -- if (!asn1_octet_decode(ctx, &ch)) -- return 0; -- -- if (ch != 0x00) { -- ctx->error = ASN1_ERR_DEC_EOC_MISMATCH; -- return 0; -- } -- return 1; -- } -- -- if (ctx->pointer != eoc) { -- ctx->error = ASN1_ERR_DEC_LENGTH_MISMATCH; -- return 0; -- } -- return 1; --} -- --unsigned char --asn1_octets_decode(struct asn1_ctx *ctx, -- unsigned char *eoc, -- unsigned char **octets, unsigned int *len) --{ -- unsigned char *ptr; -- -- *len = 0; -- -- *octets = malloc(eoc - ctx->pointer); -- if (*octets == NULL) -- return 0; -- -- ptr = *octets; -- while (ctx->pointer < eoc) { -- if (!asn1_octet_decode(ctx, (unsigned char *) ptr++)) { -- free(*octets); -- *octets = NULL; -- return 0; -- } -- (*len)++; -- } -- return 1; --} -- --unsigned char asn1_read(struct asn1_ctx *ctx, -- unsigned char **buf, unsigned int len) --{ -- *buf = NULL; -- if (ctx->end - ctx->pointer < len) { -- ctx->error = ASN1_ERR_DEC_EMPTY; -- return 0; -- } -- -- *buf = malloc(len); -- if (!*buf) -- return 0; -- memcpy(*buf, ctx->pointer, len); -- ctx->pointer += len; -- return 1; --} -- --static unsigned char --asn1_subid_decode(struct asn1_ctx *ctx, unsigned long *subid) --{ -- unsigned char ch; -- -- *subid = 0; -- -- do { -- if (!asn1_octet_decode(ctx, &ch)) -- return 0; -- -- *subid <<= 7; -- *subid |= ch & 0x7F; -- } while ((ch & 0x80) == 0x80); -- return 1; --} -- --int --asn1_oid_decode(struct asn1_ctx *ctx, -- unsigned char *eoc, unsigned long **oid, unsigned int *len) --{ -- unsigned long subid; -- unsigned int size; -- unsigned long *optr; -- -- size = eoc - ctx->pointer + 1; -- -- /* first subid actually encodes first two subids */ -- if (size < 2 || size > UINT_MAX/sizeof(unsigned long)) -- return 0; -- -- *oid = g_try_malloc0_n(size, sizeof(unsigned long)); -- if (*oid == NULL) -- return 0; -- -- optr = *oid; -- -- if (!asn1_subid_decode(ctx, &subid)) { -- g_free(*oid); -- *oid = NULL; -- return 0; -- } -- -- if (subid < 40) { -- optr[0] = 0; -- optr[1] = subid; -- } else if (subid < 80) { -- optr[0] = 1; -- optr[1] = subid - 40; -- } else { -- optr[0] = 2; -- optr[1] = subid - 80; -- } -- -- *len = 2; -- optr += 2; -- -- while (ctx->pointer < eoc) { -- if (++(*len) > size) { -- ctx->error = ASN1_ERR_DEC_BADVALUE; -- g_free(*oid); -- *oid = NULL; -- return 0; -- } -- -- if (!asn1_subid_decode(ctx, optr++)) { -- g_free(*oid); -- *oid = NULL; -- return 0; -- } -- } -- return 1; --} -- --/* return the size of @depth-nested headers + payload */ --int asn1_header_len(unsigned int payload_len, int depth) --{ -- unsigned int len; -- int i; -- -- len = payload_len; -- for (i = 0; i < depth; i++) { -- /* length */ -- if (len >= (1 << 24)) -- len += 5; -- else if (len >= (1 << 16)) -- len += 4; -- else if (len >= (1 << 8)) -- len += 3; -- else if (len >= (1 << 7)) -- len += 2; -- else -- len += 1; -- /* 1-byte header */ -- len += 1; -- } -- return len; --} -- --int asn1_oid_encode(const unsigned long *in_oid, int in_len, -- unsigned char **out_oid, int *out_len) --{ -- unsigned char *oid; -- unsigned long id; -- int i; -- -- *out_oid = g_try_malloc0_n(in_len, 5); -- if (*out_oid == NULL) -- return -ENOMEM; -- -- oid = *out_oid; -- *oid++ = (unsigned char)(40 * in_oid[0] + in_oid[1]); -- for (i = 2; i < in_len; i++) { -- id = in_oid[i]; -- if (id >= (1 << 28)) -- *oid++ = (0x80 | ((id>>28) & 0x7F)); -- if (id >= (1 << 21)) -- *oid++ = (0x80 | ((id>>21) & 0x7F)); -- if (id >= (1 << 14)) -- *oid++ = (0x80 | ((id>>14) & 0x7F)); -- if (id >= (1 << 7)) -- *oid++ = (0x80 | ((id>>7) & 0x7F)); -- *oid++ = id & 0x7F; -- } -- *out_len = (int)(oid - *out_oid); -- return 0; --} -- --/* -- * @len is the sum of all sizes of header, length and payload. -- * it will be decreased by the sum of sizes of header and length. -- */ --int asn1_header_encode(unsigned char **buf, -- unsigned int cls, unsigned int con, unsigned int tag, -- unsigned int *len) --{ -- unsigned char *loc; -- unsigned int r_len; -- -- /* at least, 1-byte header + 1-byte length is needed. */ -- if (*len < 2) -- return -EINVAL; -- -- loc = *buf; -- r_len = *len; -- -- *loc++ = ((cls & 0x3) << 6) | ((con & 0x1) << 5) | (tag & 0x1F); -- r_len -= 1; -- -- if (r_len - 1 < (1 << 7)) { -- r_len -= 1; -- *loc++ = (unsigned char)(r_len & 0x7F); -- } else if (r_len - 2 < (1 << 8)) { -- r_len -= 2; -- *loc++ = 0x81; -- *loc++ = (unsigned char)(r_len & 0xFF); -- } else if (r_len - 3 < (1 << 16)) { -- r_len -= 3; -- *loc++ = 0x82; -- *loc++ = (unsigned char)((r_len>>8) & 0xFF); -- *loc++ = (unsigned char)(r_len & 0xFF); -- } else if (r_len - 4 < (1 << 24)) { -- r_len -= 4; -- *loc++ = 0x83; -- *loc++ = (unsigned char)((r_len>>16) & 0xFF); -- *loc++ = (unsigned char)((r_len>>8) & 0xFF); -- *loc++ = (unsigned char)(r_len & 0xFF); -- } else { -- r_len -= 5; -- *loc++ = 0x84; -- *loc++ = (unsigned char)((r_len>>24) & 0xFF); -- *loc++ = (unsigned char)((r_len>>16) & 0xFF); -- *loc++ = (unsigned char)((r_len>>8) & 0xFF); -- *loc++ = (unsigned char)(r_len & 0xFF); -- } -- -- *buf = loc; -- *len = r_len; -- return 0; --} ---- a/lib/management/spnego_mech.h -+++ /dev/null -@@ -1,48 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0-or-later */ --/* -- * Copyright (C) 2020 LG Electronics -- * -- * linux-cifsd-devel@lists.sourceforge.net -- */ -- --#ifndef _SPNEGO_MECH_H_ --#define _SPNEGO_MECH_H_ -- --enum { -- SPNEGO_MECH_MSKRB5 = 0, -- SPNEGO_MECH_KRB5, -- SPNEGO_MAX_MECHS, --}; -- --struct spnego_mech_ctx; -- --typedef int (*spnego_encode_t)(char *in_blob, int in_len, -- const unsigned long *oid, int oid_len, -- char **out_blob, int *out_len); -- --struct spnego_mech_operations { -- int (*setup)(struct spnego_mech_ctx *mech_ctx); -- void (*cleanup)(struct spnego_mech_ctx *mech_ctx); -- int (*handle_authen)(struct spnego_mech_ctx *mech_ctx, -- char *in_blob, unsigned int in_len, -- struct ksmbd_spnego_auth_out *auth_out, -- spnego_encode_t encode); --}; -- --struct spnego_mech_ctx { -- const unsigned long *oid; -- int oid_len; -- void *private; -- union { -- struct { -- void *keytab_name; -- void *service_name; -- } krb5; -- } params; -- struct spnego_mech_operations *ops; --}; -- --extern struct spnego_mech_operations spnego_krb5_operations; --extern struct spnego_mech_operations spnego_mskrb5_operations; -- --#endif ---- /dev/null -+++ b/tools/asn1.c -@@ -0,0 +1,391 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * The ASB.1/BER parsing code is derived from ip_nat_snmp_basic.c which was in -+ * turn derived from the gxsnmp package by Gregory McLean & Jochen Friedrich -+ * -+ * Copyright (c) 2000 RP Internet (www.rpi.net.au). -+ */ -+ -+/***************************************************************************** -+ * -+ * Basic ASN.1 decoding routines (gxsnmp author Dirk Wisse) -+ * -+ *****************************************************************************/ -+#include -+#include -+#include -+#include -+#include -+ -+#include "asn1.h" -+ -+void -+asn1_open(struct asn1_ctx *ctx, unsigned char *buf, unsigned int len) -+{ -+ ctx->begin = buf; -+ ctx->end = buf + len; -+ ctx->pointer = buf; -+ ctx->error = ASN1_ERR_NOERROR; -+} -+ -+static unsigned char -+asn1_octet_decode(struct asn1_ctx *ctx, unsigned char *ch) -+{ -+ if (ctx->pointer >= ctx->end) { -+ ctx->error = ASN1_ERR_DEC_EMPTY; -+ return 0; -+ } -+ *ch = *(ctx->pointer)++; -+ return 1; -+} -+ -+static unsigned char -+asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag) -+{ -+ unsigned char ch; -+ -+ *tag = 0; -+ -+ do { -+ if (!asn1_octet_decode(ctx, &ch)) -+ return 0; -+ *tag <<= 7; -+ *tag |= ch & 0x7F; -+ } while ((ch & 0x80) == 0x80); -+ return 1; -+} -+ -+static unsigned char -+asn1_id_decode(struct asn1_ctx *ctx, -+ unsigned int *cls, unsigned int *con, unsigned int *tag) -+{ -+ unsigned char ch; -+ -+ if (!asn1_octet_decode(ctx, &ch)) -+ return 0; -+ -+ *cls = (ch & 0xC0) >> 6; -+ *con = (ch & 0x20) >> 5; -+ *tag = (ch & 0x1F); -+ -+ if (*tag == 0x1F) { -+ if (!asn1_tag_decode(ctx, tag)) -+ return 0; -+ } -+ return 1; -+} -+ -+static unsigned char -+asn1_length_decode(struct asn1_ctx *ctx, unsigned int *def, unsigned int *len) -+{ -+ unsigned char ch, cnt; -+ -+ if (!asn1_octet_decode(ctx, &ch)) -+ return 0; -+ -+ if (ch == 0x80) -+ *def = 0; -+ else { -+ *def = 1; -+ -+ if (ch < 0x80) -+ *len = ch; -+ else { -+ cnt = (unsigned char) (ch & 0x7F); -+ *len = 0; -+ -+ while (cnt > 0) { -+ if (!asn1_octet_decode(ctx, &ch)) -+ return 0; -+ *len <<= 8; -+ *len |= ch; -+ cnt--; -+ } -+ } -+ } -+ -+ /* don't trust len bigger than ctx buffer */ -+ if (*len > ctx->end - ctx->pointer) -+ return 0; -+ -+ return 1; -+} -+ -+unsigned char -+asn1_header_decode(struct asn1_ctx *ctx, -+ unsigned char **eoc, -+ unsigned int *cls, unsigned int *con, unsigned int *tag) -+{ -+ unsigned int def = 0; -+ unsigned int len = 0; -+ -+ if (!asn1_id_decode(ctx, cls, con, tag)) -+ return 0; -+ -+ if (!asn1_length_decode(ctx, &def, &len)) -+ return 0; -+ -+ /* primitive shall be definite, indefinite shall be constructed */ -+ if (*con == ASN1_PRI && !def) -+ return 0; -+ -+ if (def) -+ *eoc = ctx->pointer + len; -+ else -+ *eoc = NULL; -+ return 1; -+} -+ -+static unsigned char -+asn1_eoc_decode(struct asn1_ctx *ctx, unsigned char *eoc) -+{ -+ unsigned char ch; -+ -+ if (eoc == NULL) { -+ if (!asn1_octet_decode(ctx, &ch)) -+ return 0; -+ -+ if (ch != 0x00) { -+ ctx->error = ASN1_ERR_DEC_EOC_MISMATCH; -+ return 0; -+ } -+ -+ if (!asn1_octet_decode(ctx, &ch)) -+ return 0; -+ -+ if (ch != 0x00) { -+ ctx->error = ASN1_ERR_DEC_EOC_MISMATCH; -+ return 0; -+ } -+ return 1; -+ } -+ -+ if (ctx->pointer != eoc) { -+ ctx->error = ASN1_ERR_DEC_LENGTH_MISMATCH; -+ return 0; -+ } -+ return 1; -+} -+ -+unsigned char -+asn1_octets_decode(struct asn1_ctx *ctx, -+ unsigned char *eoc, -+ unsigned char **octets, unsigned int *len) -+{ -+ unsigned char *ptr; -+ -+ *len = 0; -+ -+ *octets = malloc(eoc - ctx->pointer); -+ if (*octets == NULL) -+ return 0; -+ -+ ptr = *octets; -+ while (ctx->pointer < eoc) { -+ if (!asn1_octet_decode(ctx, (unsigned char *) ptr++)) { -+ free(*octets); -+ *octets = NULL; -+ return 0; -+ } -+ (*len)++; -+ } -+ return 1; -+} -+ -+unsigned char asn1_read(struct asn1_ctx *ctx, -+ unsigned char **buf, unsigned int len) -+{ -+ *buf = NULL; -+ if (ctx->end - ctx->pointer < len) { -+ ctx->error = ASN1_ERR_DEC_EMPTY; -+ return 0; -+ } -+ -+ *buf = malloc(len); -+ if (!*buf) -+ return 0; -+ memcpy(*buf, ctx->pointer, len); -+ ctx->pointer += len; -+ return 1; -+} -+ -+static unsigned char -+asn1_subid_decode(struct asn1_ctx *ctx, unsigned long *subid) -+{ -+ unsigned char ch; -+ -+ *subid = 0; -+ -+ do { -+ if (!asn1_octet_decode(ctx, &ch)) -+ return 0; -+ -+ *subid <<= 7; -+ *subid |= ch & 0x7F; -+ } while ((ch & 0x80) == 0x80); -+ return 1; -+} -+ -+int -+asn1_oid_decode(struct asn1_ctx *ctx, -+ unsigned char *eoc, unsigned long **oid, unsigned int *len) -+{ -+ unsigned long subid; -+ unsigned int size; -+ unsigned long *optr; -+ -+ size = eoc - ctx->pointer + 1; -+ -+ /* first subid actually encodes first two subids */ -+ if (size < 2 || size > UINT_MAX/sizeof(unsigned long)) -+ return 0; -+ -+ *oid = g_try_malloc0_n(size, sizeof(unsigned long)); -+ if (*oid == NULL) -+ return 0; -+ -+ optr = *oid; -+ -+ if (!asn1_subid_decode(ctx, &subid)) { -+ g_free(*oid); -+ *oid = NULL; -+ return 0; -+ } -+ -+ if (subid < 40) { -+ optr[0] = 0; -+ optr[1] = subid; -+ } else if (subid < 80) { -+ optr[0] = 1; -+ optr[1] = subid - 40; -+ } else { -+ optr[0] = 2; -+ optr[1] = subid - 80; -+ } -+ -+ *len = 2; -+ optr += 2; -+ -+ while (ctx->pointer < eoc) { -+ if (++(*len) > size) { -+ ctx->error = ASN1_ERR_DEC_BADVALUE; -+ g_free(*oid); -+ *oid = NULL; -+ return 0; -+ } -+ -+ if (!asn1_subid_decode(ctx, optr++)) { -+ g_free(*oid); -+ *oid = NULL; -+ return 0; -+ } -+ } -+ return 1; -+} -+ -+/* return the size of @depth-nested headers + payload */ -+int asn1_header_len(unsigned int payload_len, int depth) -+{ -+ unsigned int len; -+ int i; -+ -+ len = payload_len; -+ for (i = 0; i < depth; i++) { -+ /* length */ -+ if (len >= (1 << 24)) -+ len += 5; -+ else if (len >= (1 << 16)) -+ len += 4; -+ else if (len >= (1 << 8)) -+ len += 3; -+ else if (len >= (1 << 7)) -+ len += 2; -+ else -+ len += 1; -+ /* 1-byte header */ -+ len += 1; -+ } -+ return len; -+} -+ -+int asn1_oid_encode(const unsigned long *in_oid, int in_len, -+ unsigned char **out_oid, int *out_len) -+{ -+ unsigned char *oid; -+ unsigned long id; -+ int i; -+ -+ *out_oid = g_try_malloc0_n(in_len, 5); -+ if (*out_oid == NULL) -+ return -ENOMEM; -+ -+ oid = *out_oid; -+ *oid++ = (unsigned char)(40 * in_oid[0] + in_oid[1]); -+ for (i = 2; i < in_len; i++) { -+ id = in_oid[i]; -+ if (id >= (1 << 28)) -+ *oid++ = (0x80 | ((id>>28) & 0x7F)); -+ if (id >= (1 << 21)) -+ *oid++ = (0x80 | ((id>>21) & 0x7F)); -+ if (id >= (1 << 14)) -+ *oid++ = (0x80 | ((id>>14) & 0x7F)); -+ if (id >= (1 << 7)) -+ *oid++ = (0x80 | ((id>>7) & 0x7F)); -+ *oid++ = id & 0x7F; -+ } -+ *out_len = (int)(oid - *out_oid); -+ return 0; -+} -+ -+/* -+ * @len is the sum of all sizes of header, length and payload. -+ * it will be decreased by the sum of sizes of header and length. -+ */ -+int asn1_header_encode(unsigned char **buf, -+ unsigned int cls, unsigned int con, unsigned int tag, -+ unsigned int *len) -+{ -+ unsigned char *loc; -+ unsigned int r_len; -+ -+ /* at least, 1-byte header + 1-byte length is needed. */ -+ if (*len < 2) -+ return -EINVAL; -+ -+ loc = *buf; -+ r_len = *len; -+ -+ *loc++ = ((cls & 0x3) << 6) | ((con & 0x1) << 5) | (tag & 0x1F); -+ r_len -= 1; -+ -+ if (r_len - 1 < (1 << 7)) { -+ r_len -= 1; -+ *loc++ = (unsigned char)(r_len & 0x7F); -+ } else if (r_len - 2 < (1 << 8)) { -+ r_len -= 2; -+ *loc++ = 0x81; -+ *loc++ = (unsigned char)(r_len & 0xFF); -+ } else if (r_len - 3 < (1 << 16)) { -+ r_len -= 3; -+ *loc++ = 0x82; -+ *loc++ = (unsigned char)((r_len>>8) & 0xFF); -+ *loc++ = (unsigned char)(r_len & 0xFF); -+ } else if (r_len - 4 < (1 << 24)) { -+ r_len -= 4; -+ *loc++ = 0x83; -+ *loc++ = (unsigned char)((r_len>>16) & 0xFF); -+ *loc++ = (unsigned char)((r_len>>8) & 0xFF); -+ *loc++ = (unsigned char)(r_len & 0xFF); -+ } else { -+ r_len -= 5; -+ *loc++ = 0x84; -+ *loc++ = (unsigned char)((r_len>>24) & 0xFF); -+ *loc++ = (unsigned char)((r_len>>16) & 0xFF); -+ *loc++ = (unsigned char)((r_len>>8) & 0xFF); -+ *loc++ = (unsigned char)(r_len & 0xFF); -+ } -+ -+ *buf = loc; -+ *len = r_len; -+ return 0; -+} ---- /dev/null -+++ b/tools/management/spnego_mech.h -@@ -0,0 +1,48 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* -+ * Copyright (C) 2020 LG Electronics -+ * -+ * linux-cifsd-devel@lists.sourceforge.net -+ */ -+ -+#ifndef _SPNEGO_MECH_H_ -+#define _SPNEGO_MECH_H_ -+ -+enum { -+ SPNEGO_MECH_MSKRB5 = 0, -+ SPNEGO_MECH_KRB5, -+ SPNEGO_MAX_MECHS, -+}; -+ -+struct spnego_mech_ctx; -+ -+typedef int (*spnego_encode_t)(char *in_blob, int in_len, -+ const unsigned long *oid, int oid_len, -+ char **out_blob, int *out_len); -+ -+struct spnego_mech_operations { -+ int (*setup)(struct spnego_mech_ctx *mech_ctx); -+ void (*cleanup)(struct spnego_mech_ctx *mech_ctx); -+ int (*handle_authen)(struct spnego_mech_ctx *mech_ctx, -+ char *in_blob, unsigned int in_len, -+ struct ksmbd_spnego_auth_out *auth_out, -+ spnego_encode_t encode); -+}; -+ -+struct spnego_mech_ctx { -+ const unsigned long *oid; -+ int oid_len; -+ void *private; -+ union { -+ struct { -+ void *keytab_name; -+ void *service_name; -+ } krb5; -+ } params; -+ struct spnego_mech_operations *ops; -+}; -+ -+extern struct spnego_mech_operations spnego_krb5_operations; -+extern struct spnego_mech_operations spnego_mskrb5_operations; -+ -+#endif diff --git a/net/miniupnpd/Makefile b/net/miniupnpd/Makefile index 5d4c2a08c2..6373f309c5 100644 --- a/net/miniupnpd/Makefile +++ b/net/miniupnpd/Makefile @@ -8,16 +8,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=miniupnpd - -PKG_SOURCE_PROTO:=git -PKG_SOURCE_URL:=https://github.com/miniupnp/miniupnp.git -PKG_SOURCE_DATE:=2022-08-31 -PKG_SOURCE_VERSION:=68c8ec508a421f4f4af67a63e3eb6f497d2531e1 -PKG_MIRROR_HASH:=68a3170ec73149c4cf4855b1ce6e031557cc12bff85a58421bb94785daaf225d -PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)/miniupnpd - +PKG_VERSION:=2.3.3 PKG_RELEASE:=1 +PKG_SOURCE_URL:=https://miniupnp.tuxfamily.org/files +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_HASH:=6fd7019f936ff88c41e7c822f46f10b51bd72d665978f6586483de75b30c36bf + PKG_MAINTAINER:= PKG_LICENSE:=BSD-3-Clause PKG_LICENSE_FILES:=LICENSE @@ -29,9 +26,6 @@ PKG_BUILD_PARALLEL:=1 include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/version.mk -TAR_OPTIONS+= --strip-components 1 -TAR_CMD=$(HOST_TAR) -C $(1)/.. $(TAR_OPTIONS) - define Package/miniupnpd/Default SECTION:=net CATEGORY:=Network diff --git a/net/modemmanager/Makefile b/net/modemmanager/Makefile index 6cbd6f7383..e27988733d 100644 --- a/net/modemmanager/Makefile +++ b/net/modemmanager/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=modemmanager -PKG_SOURCE_VERSION:=1.20.2 +PKG_SOURCE_VERSION:=1.20.6 PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://gitlab.freedesktop.org/mobile-broadband/ModemManager.git -PKG_MIRROR_HASH:=f138effc693456c5040ec22e17c0a8b41143c3b17b62437462995c297a9150dc +PKG_MIRROR_HASH:=e90103e2e42bb826bbbac83937a9a69f50348cd6ce0d8da655a12b65494ce7c9 PKG_MAINTAINER:=Nicholas Smith PKG_LICENSE:=GPL-2.0-or-later diff --git a/net/netbird/Makefile b/net/netbird/Makefile index 561557203f..6f0a0d716f 100644 --- a/net/netbird/Makefile +++ b/net/netbird/Makefile @@ -1,12 +1,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=netbird -PKG_VERSION:=0.12.0 +PKG_VERSION:=0.14.2 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/netbirdio/netbird/tar.gz/v$(PKG_VERSION)? -PKG_HASH:=c88b65bb9358e5a6f9c34882e77a3414b02d4c5ac13b76fb2e60b952af6a18d7 +PKG_HASH:=8ffef4569572b9eb93891e881cb7b3b9ba98b5596f3ffda3b433b32e364adb56 PKG_MAINTAINER:=Oskari Rauta PKG_LICENSE:=BSD-3-Clause diff --git a/net/netifyd/Makefile b/net/netifyd/Makefile index 85a913ed4e..6695acc659 100644 --- a/net/netifyd/Makefile +++ b/net/netifyd/Makefile @@ -16,10 +16,9 @@ PKG_INSTALL:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://gitlab.com/netify.ai/public/netify-agent.git -PKG_SOURCE_DATE:=2022-11-03 -PKG_SOURCE_VERSION:=v4.2.2 -#PKG_SOURCE_VERSION:=e8d649e170ad3f85017115ea5414ade5f297e9c5 -PKG_MIRROR_HASH:=34a9f89aa88f666e6f9e6e8fcbfaa94b02cfc4ce6e76c521377af9492d12a90d +PKG_SOURCE_DATE:=2023-03-03 +PKG_SOURCE_VERSION:=v4.4.1 +PKG_MIRROR_HASH:=aa3522b6d86e113943abacd50b235738e6452991a36864ec70f5db5b7bec6d13 include $(INCLUDE_DIR)/package.mk @@ -49,11 +48,10 @@ define Package/netifyd/conffiles /etc/netify.d/agent.uuid /etc/netify.d/serial.uuid /etc/netify.d/site.uuid -/etc/netify.d/netify-categories.json endef TARGET_CFLAGS+=-ffunction-sections -fdata-sections -Wno-psabi -TARGET_CXXFLAGS+=-ffunction-sections -fdata-sections -Wno-psabi +TARGET_CXXFLAGS+=-std=c++11 -ffunction-sections -fdata-sections -Wno-psabi TARGET_LDFLAGS+=-Wl,--gc-sections CONFIGURE_ARGS+= \ @@ -74,10 +72,6 @@ CONFIGURE_ARGS+= \ --without-libcurl-zlib endif -define Build/Configure - (cd $(PKG_BUILD_DIR); ./autogen.sh) - $(call Build/Configure/Default) -endef define Build/InstallDev $(INSTALL_DIR) $(1)/usr/include/netifyd @@ -86,6 +80,8 @@ define Build/InstallDev $(CP) $(PKG_INSTALL_DIR)/usr/include/netifyd/pcap-compat/*.h $(1)/usr/include/netifyd/pcap-compat $(INSTALL_DIR) $(1)/usr/include/netifyd/nlohmann $(CP) $(PKG_INSTALL_DIR)/usr/include/netifyd/nlohmann/*.hpp $(1)/usr/include/netifyd/nlohmann + $(INSTALL_DIR) $(1)/usr/include/netifyd/radix + $(CP) $(PKG_INSTALL_DIR)/usr/include/netifyd/radix/*.hpp $(1)/usr/include/netifyd/radix $(INSTALL_DIR) $(1)/usr/include/ndpi $(CP) $(PKG_INSTALL_DIR)/usr/include/ndpi/*.h $(1)/usr/include/ndpi $(INSTALL_DIR) $(1)/usr/lib diff --git a/net/pdns-recursor/Makefile b/net/pdns-recursor/Makefile index 5be05462f9..b976c1d118 100644 --- a/net/pdns-recursor/Makefile +++ b/net/pdns-recursor/Makefile @@ -1,12 +1,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=pdns-recursor -PKG_VERSION:=4.8.2 +PKG_VERSION:=4.8.3 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:=https://downloads.powerdns.com/releases/ -PKG_HASH:=4382d3e84f13401685772779dfede6cbc8157ecf6763fa7fdb1dd33ee3f79ac7 +PKG_HASH:=37b91a5458c54411f4e38e2d1263ecf41e751e43c5fd66e813100d9978f02505 PKG_MAINTAINER:=Peter van Dijk PKG_LICENCE:=GPL-2.0-only diff --git a/net/samba4/Makefile b/net/samba4/Makefile index 77cc23f302..6ed983a2d6 100644 --- a/net/samba4/Makefile +++ b/net/samba4/Makefile @@ -2,8 +2,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=samba -PKG_VERSION:=4.17.2 -PKG_RELEASE:=$(AUTORELEASE) +PKG_VERSION:=4.17.5 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:= \ @@ -13,7 +13,7 @@ PKG_SOURCE_URL:= \ http://www.nic.funet.fi/index/samba/pub/samba/stable/ \ http://samba.mirror.bit.nl/samba/ftp/stable/ \ https://download.samba.org/pub/samba/stable/ -PKG_HASH:=e55ddf4d5178f8c84316abf53c5edd7b35399e3b7d86bcb81b75261c827bb3b8 +PKG_HASH:=ebb7880d474ffc09d73b5fc77bcbd657f6235910337331a9c24d7f69ca11442b PKG_LICENSE:=GPL-3.0-only PKG_LICENSE_FILES:=COPYING diff --git a/net/samba4/patches/021-source4-msgsock-nvram-fix.patch b/net/samba4/patches/021-source4-msgsock-nvram-fix.patch index de1395217c..db846b9048 100644 --- a/net/samba4/patches/021-source4-msgsock-nvram-fix.patch +++ b/net/samba4/patches/021-source4-msgsock-nvram-fix.patch @@ -1,6 +1,6 @@ --- a/source4/lib/messaging/messaging.c +++ b/source4/lib/messaging/messaging.c -@@ -514,7 +514,7 @@ static struct imessaging_context *imessa +@@ -525,7 +525,7 @@ static struct imessaging_context *imessa goto fail; } diff --git a/net/simple-adblock/Makefile b/net/simple-adblock/Makefile index bb4852502e..15169eacb8 100644 --- a/net/simple-adblock/Makefile +++ b/net/simple-adblock/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=simple-adblock PKG_VERSION:=1.9.4 -PKG_RELEASE:=3 +PKG_RELEASE:=4 PKG_MAINTAINER:=Stan Grishin PKG_LICENSE:=GPL-3.0-or-later diff --git a/net/simple-adblock/files/simple-adblock.conf b/net/simple-adblock/files/simple-adblock.conf index 46518c6ee2..7949156aa7 100644 --- a/net/simple-adblock/files/simple-adblock.conf +++ b/net/simple-adblock/files/simple-adblock.conf @@ -64,6 +64,10 @@ config simple-adblock 'config' # block-list too big for most routers # list blocked_hosts_url 'https://cdn.jsdelivr.net/gh/StevenBlack/hosts/hosts' +# File size: 2.0M +# block-list too big for most routers +# list blocked_domains_url https://cdn.jsdelivr.net/gh/bongochong/CombinedPrivacyBlockLists/NoFormatting/cpbl-ctld.txt + # File size: 3.1M # block-list too big for most routers # list blocked_hosts_url 'https://hostsfile.mine.nu/Hosts' diff --git a/net/simple-adblock/files/simple-adblock.init b/net/simple-adblock/files/simple-adblock.init index 1522569abb..87fdfdef76 100644 --- a/net/simple-adblock/files/simple-adblock.init +++ b/net/simple-adblock/files/simple-adblock.init @@ -88,9 +88,6 @@ outputCache= awk='awk' load_environment_flag= -. /lib/functions/network.sh -. /usr/share/libubox/jshn.sh - debug() { local i j; for i in "$@"; do eval "j=\$$i"; echo "${i}: ${j} "; done; } uci_add_list_if_new() { @@ -1562,6 +1559,8 @@ stop_service() { load_validate_config 'config' adb_stop "'$*'"; } version() { echo "$PKG_VERSION"; } load_validate_config() { + . /lib/functions/network.sh + . /usr/share/libubox/jshn.sh local enabled local force_dns local force_dns_port diff --git a/net/sing-box/Makefile b/net/sing-box/Makefile index 921f599cc1..7103e36e12 100644 --- a/net/sing-box/Makefile +++ b/net/sing-box/Makefile @@ -1,12 +1,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=sing-box -PKG_VERSION:=1.1.5 +PKG_VERSION:=1.1.6 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/SagerNet/sing-box/tar.gz/v$(PKG_VERSION)? -PKG_HASH:=a1e642362f41bd0e362cd9c8d2f0d29d2eca6a55a948677f6f03cfb81c4f0657 +PKG_HASH:=2fdf93fd49c9375cd14b2fe2e2163cbad4b65d0cfa422c592855e7810036ef56 PKG_LICENSE:=GPL-3.0-or-later PKG_LICENSE_FILES:=LICENSE @@ -27,7 +27,7 @@ define Package/sing-box SECTION:=net CATEGORY:=Network URL:=https://sing-box.sagernet.org - DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle +kmod-tun + DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle +kmod-inet-diag +kmod-tun USERID:=sing-box=5566:sing-box=5566 endef @@ -42,7 +42,6 @@ define Package/sing-box/config config SINGBOX_WITH_ACME bool "Build with ACME TLS certificate issuer support" - default n config SINGBOX_WITH_CLASH_API bool "Build with Clash API support" @@ -50,15 +49,12 @@ define Package/sing-box/config config SINGBOX_WITH_ECH bool "Build with TLS ECH extension support for TLS outbound" - default n config SINGBOX_WITH_EMBEDDED_TOR bool "Build with embedded Tor support" - default n config SINGBOX_WITH_GRPC bool "Build with standard gRPC support" - default n config SINGBOX_WITH_GVISOR bool "Build with gVisor support" @@ -66,7 +62,6 @@ define Package/sing-box/config config SINGBOX_WITH_LWIP bool "Build with LWIP Tun stack support" - default n config SINGBOX_WITH_QUIC bool "Build with QUIC support" @@ -74,7 +69,6 @@ define Package/sing-box/config config SINGBOX_WITH_SHADOWSOCKSR bool "Build with ShadowsocksR support" - default n config SINGBOX_WITH_UTLS bool "Build with uTLS support for TLS outbound" @@ -82,7 +76,6 @@ define Package/sing-box/config config SINGBOX_WITH_V2RAY_API bool "Build with V2Ray API support" - default n config SINGBOX_WITH_WIREGUARD bool "Build with WireGuard support" diff --git a/net/snort3/Makefile b/net/snort3/Makefile index 9ba0318715..2c989ccb33 100644 --- a/net/snort3/Makefile +++ b/net/snort3/Makefile @@ -6,12 +6,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=snort3 -PKG_VERSION:=3.1.53.0 +PKG_VERSION:=3.1.56.0 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://github.com/snort3/snort3/archive/refs/tags/ -PKG_HASH:=e76429903cc56353ab21c0f4c0ec495054ba82f56d8d94943930bc0c3165be4c +PKG_HASH:=b757705e1ee2a560b94791b3f474fe1c562c98049ebb0c807e8f612c7c38032d PKG_MAINTAINER:=W. Michael Petullo PKG_LICENSE:=GPL-2.0-only diff --git a/net/tmate-ssh-server/Makefile b/net/tmate-ssh-server/Makefile index c5ffe3dece..f45a7f5fa2 100644 --- a/net/tmate-ssh-server/Makefile +++ b/net/tmate-ssh-server/Makefile @@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=tmate-ssh-server PKG_VERSION:=511fd2bd852464e76824279609a34ee93fe148a4 -PKG_RELEASE:=$(AUTORELEASE) +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/tmate-io/tmate-ssh-server/tar.gz/$(PKG_VERSION)? diff --git a/net/tmate-ssh-server/patches/010-msgpack-c.patch b/net/tmate-ssh-server/patches/010-msgpack-c.patch new file mode 100644 index 0000000000..f18fcd5aac --- /dev/null +++ b/net/tmate-ssh-server/patches/010-msgpack-c.patch @@ -0,0 +1,11 @@ +--- a/configure.ac ++++ b/configure.ac +@@ -193,7 +193,7 @@ fi + + PKG_CHECK_MODULES( + MSGPACK, +- msgpack >= 1.2.0, ++ msgpack-c >= 1.2.0, + [ + CPPFLAGS="$MSGPACK_CFLAGS $CPPFLAGS" + LIBS="$MSGPACK_LIBS $LIBS" diff --git a/net/tmate/Makefile b/net/tmate/Makefile index 0ab28a0ba0..ee3c0b588d 100644 --- a/net/tmate/Makefile +++ b/net/tmate/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=tmate PKG_VERSION:=2.4.0 -PKG_RELEASE:=$(AUTORELEASE) +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/tmate-io/tmate/tar.gz/$(PKG_VERSION)? diff --git a/net/tmate/patches/020-msgpack-c.patch b/net/tmate/patches/020-msgpack-c.patch new file mode 100644 index 0000000000..5d0cec6280 --- /dev/null +++ b/net/tmate/patches/020-msgpack-c.patch @@ -0,0 +1,11 @@ +--- a/configure.ac ++++ b/configure.ac +@@ -201,7 +201,7 @@ fi + + PKG_CHECK_MODULES( + MSGPACK, +- msgpack >= 1.1.0, ++ msgpack-c >= 1.1.0, + [ + CPPFLAGS="$MSGPACK_CFLAGS $CPPFLAGS" + LIBS="$MSGPACK_LIBS $LIBS" diff --git a/net/transmission/Makefile b/net/transmission/Makefile index 4626c1b965..dc95537c21 100644 --- a/net/transmission/Makefile +++ b/net/transmission/Makefile @@ -8,20 +8,20 @@ include $(TOPDIR)/rules.mk PKG_NAME:=transmission -PKG_VERSION:=3.00 -PKG_RELEASE:=19 +PKG_VERSION:=4.0.1 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz -PKG_SOURCE_URL:=@GITHUB/transmission/transmission-releases/master -PKG_HASH:=9144652fe742f7f7dd6657716e378da60b751aaeda8bef8344b3eefc4db255f2 +PKG_SOURCE_URL:=https://github.com/transmission/transmission/releases/download/$(PKG_VERSION)/ +PKG_HASH:=8fc5aef23638c983406f6a3ee9918369e4cdc84e3228bd2fb3d01dd55cdad900 PKG_MAINTAINER:=Daniel Golle PKG_LICENSE:=GPL-2.0-or-later PKG_LICENSE_FILES:=COPYING PKG_CPE_ID:=cpe:/a:transmissionbt:transmission -PKG_FIXUP:=autoreconf PKG_INSTALL:=1 +PKG_BUILD_DEPENDS:=libb64 node/host PKG_BUILD_PARALLEL:=1 PKG_CONFIG_DEPENDS:= \ CONFIG_LIBCURL_GNUTLS \ @@ -31,6 +31,7 @@ PKG_CONFIG_DEPENDS:= \ CONFIG_LIBCURL_NOSSL include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk include $(INCLUDE_DIR)/package-seccomp.mk define Package/transmission/template @@ -39,7 +40,10 @@ define Package/transmission/template CATEGORY:=Network TITLE:=BitTorrent client URL:=https://www.transmissionbt.com - DEPENDS:=+libcurl +libevent2 +libminiupnpc +libnatpmp +libpthread +librt +zlib +LIBCURL_NOSSL:libmbedtls +LIBCURL_GNUTLS:libmbedtls + DEPENDS:=+libatomic +libcurl +libdeflate +libdht +libevent2 \ + +libevent2-pthreads +libminiupnpc +libnatpmp +libpthread +libpsl \ + +librt +libutp +zlib +LIBCURL_NOSSL:libmbedtls \ + +LIBCURL_GNUTLS:libmbedtls endef define Package/transmission-daemon @@ -87,23 +91,40 @@ define Package/transmission-daemon/conffiles /etc/config/transmission endef -TARGET_CFLAGS += -ffunction-sections -fdata-sections -flto +TARGET_CFLAGS += -ffunction-sections -fdata-sections -flto -DHAVE_SIZE_T -latomic TARGET_LDFLAGS += -Wl,--gc-sections -Wl,--as-needed -CONFIGURE_ARGS += \ - --enable-cli \ - --enable-daemon \ - --enable-external-natpmp \ - --enable-largefile \ - --enable-lightweight \ - --without-gtk \ - --without-kqueue \ - --without-systemd-daemon \ - $(if $(CONFIG_LIBCURL_NOSSL),--with-crypto=polarssl) \ - $(if $(CONFIG_LIBCURL_GNUTLS),--with-crypto=polarssl) \ - $(if $(CONFIG_LIBCURL_MBEDTLS),--with-crypto=polarssl) \ - $(if $(CONFIG_LIBCURL_OPENSSL),--with-crypto=openssl) \ - $(if $(CONFIG_LIBCURL_WOLFSSL),--with-crypto=cyassl) +CMAKE_OPTIONS += \ + -DENABLE_CLI:BOOL=YES \ + -DENABLE_GTK:BOOL=NO \ + -DENABLE_QT:BOOL=NO \ + -DENABLE_MAC:BOOL=NO \ + -DENABLE_TESTS:BOOL=NO \ + -DENABLE_NLS:BOOL=NO \ + -DENABLE_UTP:BOOL=YES \ + -DRUN_CLANG_TIDY:BOOL=NO \ + -DUSE_SYSTEM_EVENT2:BOOL=YES \ + -DUSE_SYSTEM_DEFLATE:BOOL=YES \ + -DUSE_SYSTEM_DHT:BOOL=YES \ + -DUSE_SYSTEM_MINIUPNPC:BOOL=YES \ + -DUSE_SYSTEM_NATPMP:BOOL=YES \ + -DUSE_SYSTEM_UTP:BOOL=YES \ + -DUSE_SYSTEM_B64:BOOL=YES \ + -DUSE_SYSTEM_PSL:BOOL=YES \ + -DWITH_INOTIFY:BOOL=YES \ + -DWITH_KQUEUE:BOOL=NO \ + -DWITH_SYSTEMD:BOOL=NO \ + -DB64_INCLUDE_DIR=$(STAGING_DIR)/usr/include \ + -DB64_LIBRARY=$(STAGING_DIR)/usr/lib/libb64.a \ + -DDHT_INCLUDE_DIR=$(STAGING_DIR)/usr/include \ + -DDHT_LIBRARY=$(STAGING_DIR)/usr/lib/libdht.so \ + -DUTP_INCLUDE_DIR=$(STAGING_DIR)/usr/include \ + -DUTP_LIBRARY=$(STAGING_DIR)/usr/lib/libutp.so \ + $(if $(CONFIG_LIBCURL_NOSSL),-DWITH_CRYPTO=mbedtls) \ + $(if $(CONFIG_LIBCURL_GNUTLS),-DWITH_CRYPTO=mbedtls) \ + $(if $(CONFIG_LIBCURL_MBEDTLS),-DWITH_CRYPTO=mbedtls) \ + $(if $(CONFIG_LIBCURL_OPENSSL),-DWITH_CRYPTO=openssl) \ + $(if $(CONFIG_LIBCURL_WOLFSSL),-DWITH_CRYPTO=wolfssl) define Package/transmission-daemon/install $(INSTALL_DIR) $(1)/usr/bin @@ -133,7 +154,7 @@ endef define Package/transmission-web/install $(INSTALL_DIR) $(1)/usr/share/transmission - $(CP) $(PKG_INSTALL_DIR)/usr/share/transmission/web $(1)/usr/share/transmission/ + $(CP) $(PKG_INSTALL_DIR)/usr/share/transmission/public_html $(1)/usr/share/transmission/ endef $(eval $(call BuildPackage,transmission-daemon)) diff --git a/net/transmission/files/transmission-daemon.json b/net/transmission/files/transmission-daemon.json index b652d32574..f1fc456ecc 100644 --- a/net/transmission/files/transmission-daemon.json +++ b/net/transmission/files/transmission-daemon.json @@ -17,6 +17,7 @@ "epoll_create1", "epoll_ctl", "epoll_pwait", + "eventfd2", "exit", "exit_group", "faccessat", @@ -87,6 +88,7 @@ "sendto", "setsockopt", "shutdown", + "signalfd4", "sigreturn", "socket", "socketpair", diff --git a/net/transmission/files/transmission.init b/net/transmission/files/transmission.init index a6bc00f01b..a1673087f0 100644 --- a/net/transmission/files/transmission.init +++ b/net/transmission/files/transmission.init @@ -170,7 +170,7 @@ transmission() { procd_add_jail_mount_rw "$download_dir" [ "$incomplete_dir_enabled" = "1" ] && procd_add_jail_mount_rw "$incomplete_dir" [ "$watch_dir_enabled" = "1" ] && procd_add_jail_mount_rw "$watch_dir" - web_home="${web_home:-/usr/share/transmission/web}" + web_home="${web_home:-/usr/share/transmission/public_html}" [ -d "$web_home" ] && procd_add_jail_mount "$web_home" [ -f "$ca_bundle_file" ] && procd_add_jail_mount "$ca_bundle_file" procd_close_instance diff --git a/net/transmission/patches/001-apply-dscp-to-udp-sockets.patch b/net/transmission/patches/001-apply-dscp-to-udp-sockets.patch deleted file mode 100644 index a3fd634412..0000000000 --- a/net/transmission/patches/001-apply-dscp-to-udp-sockets.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 98da2afa58b7bdf5350de16fd99905ddb04e1b0d Mon Sep 17 00:00:00 2001 -From: Dan Walters -Date: Sun, 13 Oct 2019 10:08:36 -0500 -Subject: [PATCH] Apply the configured peer socket TOS to UDP sockets, not just - TCP. - ---- - libtransmission/session.c | 2 ++ - libtransmission/tr-udp.c | 20 ++++++++++++++++++++ - libtransmission/tr-udp.h | 1 + - 3 files changed, 23 insertions(+) - ---- a/libtransmission/session.c -+++ b/libtransmission/session.c -@@ -2274,6 +2274,8 @@ static void toggle_utp(void* data) - - tr_udpSetSocketBuffers(session); - -+ tr_udpSetSocketTOS(session); -+ - /* But don't call tr_utpClose -- see reset_timer in tr-utp.c for an - explanation. */ - } ---- a/libtransmission/tr-udp.c -+++ b/libtransmission/tr-udp.c -@@ -125,6 +125,24 @@ void tr_udpSetSocketBuffers(tr_session* - } - } - -+void tr_udpSetSocketTOS(tr_session* session) -+{ -+ if (session->peerSocketTOS == 0) -+ { -+ return; -+ } -+ -+ if (session->udp_socket != TR_BAD_SOCKET) -+ { -+ tr_netSetTOS(session->udp_socket, session->peerSocketTOS, TR_AF_INET); -+ } -+ -+ if (session->udp6_socket != TR_BAD_SOCKET) -+ { -+ tr_netSetTOS(session->udp6_socket, session->peerSocketTOS, TR_AF_INET6); -+ } -+} -+ - /* BEP-32 has a rather nice explanation of why we need to bind to one - IPv6 address, if I may say so myself. */ - -@@ -363,6 +381,8 @@ ipv6: - - tr_udpSetSocketBuffers(ss); - -+ tr_udpSetSocketTOS(ss); -+ - if (ss->isDHTEnabled) - { - tr_dhtInit(ss); ---- a/libtransmission/tr-udp.h -+++ b/libtransmission/tr-udp.h -@@ -30,5 +30,6 @@ THE SOFTWARE. - void tr_udpInit(tr_session*); - void tr_udpUninit(tr_session*); - void tr_udpSetSocketBuffers(tr_session*); -+void tr_udpSetSocketTOS(tr_session*); - - bool tau_handle_message(tr_session* session, uint8_t const* msg, size_t msglen); diff --git a/net/transmission/patches/010-no-intltool.patch b/net/transmission/patches/010-no-intltool.patch deleted file mode 100644 index ba59092bc5..0000000000 --- a/net/transmission/patches/010-no-intltool.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/configure.ac -+++ b/configure.ac -@@ -555,9 +555,6 @@ dnl it should be safe to re-edit 0.40 ba - use_nls=no - if test "x$enable_nls" = "xyes" ; then - use_nls=yes -- m4_ifdef([IT_PROG_INTLTOOL], -- [IT_PROG_INTLTOOL([0.35.0],[no-xml])], -- [AC_MSG_ERROR("--enable-nls requires intltool to be installed.")]) - AC_CHECK_HEADERS([libintl.h]) - GETTEXT_PACKAGE=transmission-gtk - AC_SUBST(GETTEXT_PACKAGE) diff --git a/net/transmission/patches/020-mbedcrypto.patch b/net/transmission/patches/020-mbedcrypto.patch deleted file mode 100644 index 18c33f5b7c..0000000000 --- a/net/transmission/patches/020-mbedcrypto.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/configure.ac -+++ b/configure.ac -@@ -152,8 +152,8 @@ AS_IF([test "x$want_crypto" = "xauto" -o - ) - ]) - AS_IF([test "x$want_crypto" = "xauto" -o "x$want_crypto" = "xpolarssl"], [ -- PKG_CHECK_MODULES(MBEDTLS, [mbedtls >= $POLARSSL_MINIMUM], -- [want_crypto="polarssl"; CRYPTO_PKG="polarssl"; CRYPTO_CFLAGS="$MBEDTLS_CFLAGS"; CRYPTO_LIBS="$MBEDTLS_LIBS"; POLARSSL_IS_MBEDTLS=yes], -+ AC_CHECK_LIB(mbedcrypto, mbedtls_strerror, -+ [want_crypto="polarssl"; CRYPTO_PKG="polarssl"; CRYPTO_LIBS="-lmbedcrypto"; POLARSSL_IS_MBEDTLS=yes], - [AC_CHECK_HEADER([polarssl/version.h], - [AC_EGREP_CPP([version_ok], [#include - #if defined (POLARSSL_VERSION_NUMBER) && POLARSSL_VERSION_NUMBER >= $POLARSSL_MINIMUM diff --git a/net/transmission/patches/030-wolfssl.patch b/net/transmission/patches/030-wolfssl.patch deleted file mode 100644 index 53e1393d53..0000000000 --- a/net/transmission/patches/030-wolfssl.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 82b5d4028885d75adba9b66d43aeb11592e64914 Mon Sep 17 00:00:00 2001 -From: Rosen Penev -Date: Wed, 13 Oct 2021 18:16:55 -0700 -Subject: [PATCH] fix runtime with wolfSSL and fastmath - -wolfSSL's fastmath support requires options.h to be included before -anything else. Otherwise bad codepaths get taken and a crash occurs -during DH initialization. - -Signed-off-by: Rosen Penev ---- - libtransmission/crypto-utils-cyassl.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/libtransmission/crypto-utils-cyassl.c -+++ b/libtransmission/crypto-utils-cyassl.c -@@ -19,6 +19,7 @@ - #define API_VERSION_HEX LIBCYASSL_VERSION_HEX - #endif - -+#include API_HEADER(options.h) - #include API_HEADER_CRYPT(arc4.h) - #include API_HEADER_CRYPT(dh.h) - #include API_HEADER_CRYPT(error-crypt.h) diff --git a/net/transmission/patches/080-disable-webseeding.patch b/net/transmission/patches/080-disable-webseeding.patch deleted file mode 100644 index f63d78d3e3..0000000000 --- a/net/transmission/patches/080-disable-webseeding.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/libtransmission/webseed.c -+++ b/libtransmission/webseed.c -@@ -510,8 +510,6 @@ static void webseed_timer_func(evutil_so - ++w->retry_tickcount; - } - -- on_idle(w); -- - tr_timerAddMsec(w->timer, TR_IDLE_TIMER_MSEC); - } - diff --git a/net/udp-broadcast-relay-redux-openwrt/Makefile b/net/udp-broadcast-relay-redux-openwrt/Makefile index f3854fb809..8f120d9441 100644 --- a/net/udp-broadcast-relay-redux-openwrt/Makefile +++ b/net/udp-broadcast-relay-redux-openwrt/Makefile @@ -1,7 +1,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=udp-broadcast-relay-redux -PKG_RELEASE:=$(AUTORELEASE) +PKG_RELEASE:=2 PKG_LICENSE:=GPL-2.0 PKG_SOURCE_PROTO:=git diff --git a/net/udp-broadcast-relay-redux-openwrt/files/udp-broadcast-relay-redux.init b/net/udp-broadcast-relay-redux-openwrt/files/udp-broadcast-relay-redux.init index aa35f55462..6694215885 100644 --- a/net/udp-broadcast-relay-redux-openwrt/files/udp-broadcast-relay-redux.init +++ b/net/udp-broadcast-relay-redux-openwrt/files/udp-broadcast-relay-redux.init @@ -58,7 +58,7 @@ udp_broadcast_relay_redux_instance() { procd_append_param command "-t" "$dest_override" fi - procd_add_jail ubr-${PIDCOUNT} + procd_add_jail ubr-${PIDCOUNT} cgroupsns procd_close_instance } diff --git a/net/v2raya/Makefile b/net/v2raya/Makefile index 18b81d15c0..3787374c45 100644 --- a/net/v2raya/Makefile +++ b/net/v2raya/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=v2rayA PKG_VERSION:=1.5.9.1698.1 -PKG_RELEASE:=3 +PKG_RELEASE:=4 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/v2rayA/v2rayA/tar.gz/v$(PKG_VERSION)? @@ -37,13 +37,7 @@ define Package/v2raya SUBMENU:=Web Servers/Proxies DEPENDS:=$(GO_ARCH_DEPENDS) \ +ca-bundle \ - +iptables \ - +IPV6:ip6tables \ - +iptables-mod-conntrack-extra \ - +iptables-mod-extra \ - +iptables-mod-filter \ - +iptables-mod-tproxy \ - +kmod-ipt-nat6 \ + +kmod-nft-tproxy \ +xray-core URL:=https://v2raya.org endef diff --git a/net/v2raya/files/v2raya.config b/net/v2raya/files/v2raya.config index d9ff36581a..131131cf81 100644 --- a/net/v2raya/files/v2raya.config +++ b/net/v2raya/files/v2raya.config @@ -10,7 +10,11 @@ config v2raya 'config' # Make sure your IPv6 network works fine before you turn it on. # Optional values: auto, on, off. - option ipv6_support 'auto' + option ipv6_support 'on' + + # Experimental feature. Make sure you have installed nftables. + # Optional values: auto, on, off. + option nftables_support 'on' # Optional values: trace, debug, info, warn or error option log_level 'info' diff --git a/net/v2raya/files/v2raya.init b/net/v2raya/files/v2raya.init index 4120e90ffd..2b77fa5dcd 100755 --- a/net/v2raya/files/v2raya.init +++ b/net/v2raya/files/v2raya.init @@ -42,7 +42,8 @@ start_service() { append_env_arg "config" "address" "0.0.0.0:2017" append_env_arg "config" "config" "/etc/v2raya" - append_env_arg "config" "ipv6_support" "auto" + append_env_arg "config" "ipv6_support" "on" + append_env_arg "config" "nftables_support" "on" append_env_arg "config" "log_level" "info" append_env_arg "config" "log_file" "/var/log/v2raya/v2raya.log" append_env_arg "config" "log_max_days" "3" diff --git a/net/v2raya/patches/019-fix-simple-obfs.patch b/net/v2raya/patches/019-fix-simple-obfs.patch new file mode 100644 index 0000000000..e76b49cc8d --- /dev/null +++ b/net/v2raya/patches/019-fix-simple-obfs.patch @@ -0,0 +1,88 @@ +From 58a6cf270e43ec3eaeef7d1c65de76278dd6d349 Mon Sep 17 00:00:00 2001 +From: mzz2017 <2017@duck.com> +Date: Mon, 13 Feb 2023 14:42:07 +0800 +Subject: [PATCH] fix: simple-obfs + +--- + service/pkg/plugin/simpleobfs/http.go | 8 +++++++- + service/pkg/plugin/simpleobfs/tls.go | 7 +++++++ + 2 files changed, 14 insertions(+), 1 deletion(-) + +--- a/pkg/plugin/simpleobfs/http.go ++++ b/pkg/plugin/simpleobfs/http.go +@@ -12,6 +12,7 @@ import ( + "net" + "net/http" + "strings" ++ "sync" + ) + + // HTTPObfs is shadowsocks http simple-obfs implementation +@@ -24,9 +25,13 @@ type HTTPObfs struct { + offset int + firstRequest bool + firstResponse bool ++ rMu sync.Mutex ++ wMu sync.Mutex + } + + func (ho *HTTPObfs) Read(b []byte) (int, error) { ++ ho.rMu.Lock() ++ defer ho.rMu.Unlock() + if ho.buf != nil { + n := copy(b, ho.buf[ho.offset:]) + ho.offset += n +@@ -64,6 +69,8 @@ func (ho *HTTPObfs) Read(b []byte) (int, + } + + func (ho *HTTPObfs) Write(b []byte) (int, error) { ++ ho.wMu.Lock() ++ defer ho.wMu.Unlock() + if ho.firstRequest { + randBytes := make([]byte, 16) + rand.Read(randBytes) +@@ -71,7 +78,6 @@ func (ho *HTTPObfs) Write(b []byte) (int + req.Header.Set("User-Agent", fmt.Sprintf("curl/7.%d.%d", rand.Int()%54, rand.Int()%2)) + req.Header.Set("Upgrade", "websocket") + req.Header.Set("Connection", "Upgrade") +- req.Host = ho.host + if ho.port != "80" { + req.Host = fmt.Sprintf("%s:%s", ho.host, ho.port) + } +--- a/pkg/plugin/simpleobfs/tls.go ++++ b/pkg/plugin/simpleobfs/tls.go +@@ -8,6 +8,7 @@ import ( + "io" + "math/rand" + "net" ++ "sync" + "time" + ) + +@@ -26,6 +27,8 @@ type TLSObfs struct { + remain int + firstRequest bool + firstResponse bool ++ rMu sync.Mutex ++ wMu sync.Mutex + } + + func (to *TLSObfs) read(b []byte, discardN int) (int, error) { +@@ -54,6 +57,8 @@ func (to *TLSObfs) read(b []byte, discar + } + + func (to *TLSObfs) Read(b []byte) (int, error) { ++ to.rMu.Lock() ++ defer to.rMu.Unlock() + if to.remain > 0 { + length := to.remain + if length > len(b) { +@@ -77,6 +82,8 @@ func (to *TLSObfs) Read(b []byte) (int, + return to.read(b, 3) + } + func (to *TLSObfs) Write(b []byte) (int, error) { ++ to.wMu.Lock() ++ defer to.wMu.Unlock() + length := len(b) + for i := 0; i < length; i += chunkSize { + end := i + chunkSize diff --git a/net/v2raya/patches/020-feat-add-nftables-support.patch b/net/v2raya/patches/020-feat-add-nftables-support.patch new file mode 100644 index 0000000000..50ef49b9c5 --- /dev/null +++ b/net/v2raya/patches/020-feat-add-nftables-support.patch @@ -0,0 +1,624 @@ +From d10cf52839e848870df0ea852d9a818ac03e7aa3 Mon Sep 17 00:00:00 2001 +From: cubercsl <2014cais01@gmail.com> +Date: Thu, 19 Jan 2023 16:43:30 +0800 +Subject: [PATCH 1/5] feat: add nftables support + +fix: use iptables-nft if nftables-support is on +fix: save nft to V2RAYA_CONFIG +fix: tproxy for ipv6 +chore: small change in table format +--- + service/conf/environmentConfig.go | 1 + + service/core/iptables/dropSpoofing.go | 4 +- + service/core/iptables/iptables.go | 7 +- + service/core/iptables/redirect.go | 142 +++++++++++++++++-- + service/core/iptables/tproxy.go | 195 +++++++++++++++++++++++++- + service/core/iptables/utils.go | 23 ++- + service/core/iptables/watcher.go | 1 + + service/core/v2ray/asset/asset.go | 17 ++- + service/core/v2ray/transparent.go | 9 +- + 9 files changed, 367 insertions(+), 32 deletions(-) + +--- a/conf/environmentConfig.go ++++ b/conf/environmentConfig.go +@@ -24,6 +24,7 @@ type Params struct { + WebDir string `id:"webdir" desc:"v2rayA web files directory. use embedded files if not specify."` + VlessGrpcInboundCertKey []string `id:"vless-grpc-inbound-cert-key" desc:"Specify the certification path instead of automatically generating a self-signed certificate. Example: /etc/v2raya/grpc_certificate.crt,/etc/v2raya/grpc_private.key"` + IPV6Support string `id:"ipv6-support" default:"auto" desc:"Optional values: auto, on, off. Make sure your IPv6 network works fine before you turn it on."` ++ NFTablesSupport string `id:"nftables-support" default:"off" desc:"Optional values: auto, on, off. Experimental feature. Make sure you have installed nftables."` + PassCheckRoot bool `desc:"Skip privilege checking. Use it only when you cannot start v2raya but confirm you have root privilege"` + ResetPassword bool `id:"reset-password"` + LogLevel string `id:"log-level" default:"info" desc:"Optional values: trace, debug, info, warn or error"` +--- a/core/iptables/dropSpoofing.go ++++ b/core/iptables/dropSpoofing.go +@@ -34,7 +34,7 @@ ip6tables -w 2 -I FORWARD -j DROP_SPOOFI + ` + } + return Setter{ +- Cmds: commands, ++ Cmds: commands, + } + } + +@@ -54,6 +54,6 @@ ip6tables -w 2 -X DROP_SPOOFING + ` + } + return Setter{ +- Cmds: commands, ++ Cmds: commands, + } + } +--- a/core/iptables/iptables.go ++++ b/core/iptables/iptables.go +@@ -1,11 +1,12 @@ + package iptables + + import ( +- "github.com/v2rayA/v2rayA/common" +- "github.com/v2rayA/v2rayA/common/cmds" + "strings" + "sync" + "time" ++ ++ "github.com/v2rayA/v2rayA/common" ++ "github.com/v2rayA/v2rayA/common/cmds" + ) + + // http://briteming.hatenablog.com/entry/2019/06/18/175518 +@@ -56,6 +57,10 @@ func (c Setter) Run(stopAtError bool) er + if common.IsDocker() { + commands = strings.ReplaceAll(commands, "iptables", "iptables-legacy") + commands = strings.ReplaceAll(commands, "ip6tables", "ip6tables-legacy") ++ } else if (!cmds.IsCommandValid("iptables") || IsNFTablesSupported()) && ++ cmds.IsCommandValid("iptables-nft") { ++ commands = strings.ReplaceAll(commands, "iptables", "iptables-nft") ++ commands = strings.ReplaceAll(commands, "ip6tables", "ip6tables-nft") + } + var errs []error + if c.PreFunc != nil { +--- a/core/iptables/redirect.go ++++ b/core/iptables/redirect.go +@@ -2,15 +2,34 @@ package iptables + + import ( + "fmt" +- "github.com/v2rayA/v2rayA/common/cmds" ++ "os" + "strings" ++ ++ "github.com/v2rayA/v2rayA/common/cmds" ++ "github.com/v2rayA/v2rayA/core/v2ray/asset" + ) + +-type redirect struct{} ++type redirect interface { ++ AddIPWhitelist(cidr string) ++ RemoveIPWhitelist(cidr string) ++ GetSetupCommands() Setter ++ GetCleanCommands() Setter ++} ++ ++type legacyRedirect struct{} ++type nftRedirect struct{} + + var Redirect redirect + +-func (r *redirect) AddIPWhitelist(cidr string) { ++func init() { ++ if IsNFTablesSupported() { ++ Redirect = &nftRedirect{} ++ } else { ++ Redirect = &legacyRedirect{} ++ } ++} ++ ++func (r *legacyRedirect) AddIPWhitelist(cidr string) { + // avoid duplication + r.RemoveIPWhitelist(cidr) + var commands string +@@ -22,13 +41,13 @@ func (r *redirect) AddIPWhitelist(cidr s + cmds.ExecCommands(commands, false) + } + +-func (r *redirect) RemoveIPWhitelist(cidr string) { ++func (r *legacyRedirect) RemoveIPWhitelist(cidr string) { + var commands string + commands = fmt.Sprintf(`iptables -w 2 -t mangle -D TP_RULE -d %s -j RETURN`, cidr) + cmds.ExecCommands(commands, false) + } + +-func (r *redirect) GetSetupCommands() Setter { ++func (r *legacyRedirect) GetSetupCommands() Setter { + commands := ` + iptables -w 2 -t nat -N TP_OUT + iptables -w 2 -t nat -N TP_PRE +@@ -84,11 +103,11 @@ ip6tables -w 2 -t nat -A TP_OUT -j TP_RU + ` + } + return Setter{ +- Cmds: commands, ++ Cmds: commands, + } + } + +-func (r *redirect) GetCleanCommands() Setter { ++func (r *legacyRedirect) GetCleanCommands() Setter { + commands := ` + iptables -w 2 -t nat -F TP_OUT + iptables -w 2 -t nat -D OUTPUT -p tcp -j TP_OUT +@@ -112,6 +131,113 @@ ip6tables -w 2 -t nat -X TP_RULE + ` + } + return Setter{ +- Cmds: commands, ++ Cmds: commands, ++ } ++} ++ ++func (t *nftRedirect) AddIPWhitelist(cidr string) { ++ command := fmt.Sprintf("nft add element inet v2raya interface { %s }", cidr) ++ if !strings.Contains(cidr, ".") { ++ command = strings.Replace(command, "interface", "interface6", 1) ++ } ++ cmds.ExecCommands(command, false) ++} ++ ++func (t *nftRedirect) RemoveIPWhitelist(cidr string) { ++ command := fmt.Sprintf("nft delete element inet v2raya interface { %s }", cidr) ++ if !strings.Contains(cidr, ".") { ++ command = strings.Replace(command, "interface", "interface6", 1) + } ++ cmds.ExecCommands(command, false) ++} ++ ++func (r *nftRedirect) GetSetupCommands() Setter { ++ // 198.18.0.0/15 and fc00::/7 are reserved for private use but used by fakedns ++ table := ` ++table inet v2raya { ++ set whitelist { ++ type ipv4_addr ++ flags interval ++ auto-merge ++ elements = { ++ 0.0.0.0/32, ++ 10.0.0.0/8, ++ 100.64.0.0/10, ++ 127.0.0.0/8, ++ 169.254.0.0/16, ++ 172.16.0.0/12, ++ 192.0.0.0/24, ++ 192.0.2.0/24, ++ 192.88.99.0/24, ++ 192.168.0.0/16, ++ 198.51.100.0/24, ++ 203.0.113.0/24, ++ 224.0.0.0/4, ++ 240.0.0.0/4 ++ } ++ } ++ ++ set whitelist6 { ++ type ipv6_addr ++ flags interval ++ auto-merge ++ elements = { ++ ::/128, ++ ::1/128, ++ 64:ff9b::/96, ++ 100::/64, ++ 2001::/32, ++ 2001:20::/28, ++ fe80::/10, ++ ff00::/8 ++ } ++ } ++ ++ set interface { ++ type ipv4_addr ++ flags interval ++ auto-merge ++ } ++ ++ set interface6 { ++ type ipv6_addr ++ flags interval ++ auto-merge ++ } ++ ++ chain tp_rule { ++ ip daddr @whitelist return ++ ip daddr @interface return ++ ip6 daddr @whitelist6 return ++ ip6 daddr @interface6 return ++ meta mark & 0x80 == 0x80 return ++ meta l4proto tcp redirect to :32345 ++ } ++ ++ chain tp_pre { ++ type nat hook prerouting priority dstnat - 5 ++ meta nfproto { ipv4, ipv6 } meta l4proto tcp jump tp_rule ++ } ++ ++ chain tp_out { ++ type nat hook output priority -105 ++ meta nfproto { ipv4, ipv6 } meta l4proto tcp jump tp_rule ++ } ++} ++` ++ if !IsIPv6Supported() { ++ table = strings.ReplaceAll(table, "meta nfproto { ipv4, ipv6 }", "meta nfproto ipv4") ++ } ++ ++ nftablesConf := asset.GetNFTablesConfigPath() ++ os.WriteFile(nftablesConf, []byte(table), 0644) ++ ++ command := `nft -f ` + nftablesConf ++ ++ return Setter{Cmds: command} ++} ++ ++func (r *nftRedirect) GetCleanCommands() Setter { ++ command := `nft delete table inet v2raya` ++ return Setter{Cmds: command} + } +--- a/core/iptables/tproxy.go ++++ b/core/iptables/tproxy.go +@@ -2,18 +2,36 @@ package iptables + + import ( + "fmt" ++ "os" ++ "strings" ++ + "github.com/v2rayA/v2rayA/common/cmds" ++ "github.com/v2rayA/v2rayA/core/v2ray/asset" + "github.com/v2rayA/v2rayA/db/configure" +- "strings" + ) + +-type tproxy struct { +- watcher *LocalIPWatcher ++type tproxy interface { ++ AddIPWhitelist(cidr string) ++ RemoveIPWhitelist(cidr string) ++ GetSetupCommands() Setter ++ GetCleanCommands() Setter + } + ++type legacyTproxy struct{} ++ ++type nftTproxy struct{} ++ + var Tproxy tproxy + +-func (t *tproxy) AddIPWhitelist(cidr string) { ++func init() { ++ if IsNFTablesSupported() { ++ Tproxy = &nftTproxy{} ++ } else { ++ Tproxy = &legacyTproxy{} ++ } ++} ++ ++func (t *legacyTproxy) AddIPWhitelist(cidr string) { + // avoid duplication + t.RemoveIPWhitelist(cidr) + pos := 7 +@@ -30,7 +48,7 @@ func (t *tproxy) AddIPWhitelist(cidr str + cmds.ExecCommands(commands, false) + } + +-func (t *tproxy) RemoveIPWhitelist(cidr string) { ++func (t *legacyTproxy) RemoveIPWhitelist(cidr string) { + var commands string + commands = fmt.Sprintf(`iptables -w 2 -t mangle -D TP_RULE -d %s -j RETURN`, cidr) + if !strings.Contains(cidr, ".") { +@@ -40,7 +58,7 @@ func (t *tproxy) RemoveIPWhitelist(cidr + cmds.ExecCommands(commands, false) + } + +-func (t *tproxy) GetSetupCommands() Setter { ++func (t *legacyTproxy) GetSetupCommands() Setter { + commands := ` + ip rule add fwmark 0x40/0xc0 table 100 + ip route add local 0.0.0.0/0 dev lo table 100 +@@ -158,7 +176,7 @@ ip6tables -w 2 -t mangle -A TP_MARK -j C + } + } + +-func (t *tproxy) GetCleanCommands() Setter { ++func (t *legacyTproxy) GetCleanCommands() Setter { + commands := ` + ip rule del fwmark 0x40/0xc0 table 100 + ip route del local 0.0.0.0/0 dev lo table 100 +@@ -195,3 +213,166 @@ ip6tables -w 2 -t mangle -X TP_MARK + Cmds: commands, + } + } ++ ++func (t *nftTproxy) AddIPWhitelist(cidr string) { ++ command := fmt.Sprintf("nft add element inet v2raya interface { %s }", cidr) ++ if !strings.Contains(cidr, ".") { ++ command = strings.Replace(command, "interface", "interface6", 1) ++ } ++ cmds.ExecCommands(command, false) ++} ++ ++func (t *nftTproxy) RemoveIPWhitelist(cidr string) { ++ command := fmt.Sprintf("nft delete element inet v2raya interface { %s }", cidr) ++ if !strings.Contains(cidr, ".") { ++ command = strings.Replace(command, "interface", "interface6", 1) ++ } ++ cmds.ExecCommands(command, false) ++} ++ ++func (t *nftTproxy) GetSetupCommands() Setter { ++ // 198.18.0.0/15 and fc00::/7 are reserved for private use but used by fakedns ++ table := ` ++table inet v2raya { ++ set whitelist { ++ type ipv4_addr ++ flags interval ++ auto-merge ++ elements = { ++ 0.0.0.0/32, ++ 10.0.0.0/8, ++ 100.64.0.0/10, ++ 127.0.0.0/8, ++ 169.254.0.0/16, ++ 172.16.0.0/12, ++ 192.0.0.0/24, ++ 192.0.2.0/24, ++ 192.88.99.0/24, ++ 192.168.0.0/16, ++ 198.51.100.0/24, ++ 203.0.113.0/24, ++ 224.0.0.0/4, ++ 240.0.0.0/4 ++ } ++ } ++ ++ set whitelist6 { ++ type ipv6_addr ++ flags interval ++ auto-merge ++ elements = { ++ ::/128, ++ ::1/128, ++ 64:ff9b::/96, ++ 100::/64, ++ 2001::/32, ++ 2001:20::/28, ++ fe80::/10, ++ ff00::/8 ++ } ++ } ++ ++ set interface { ++ type ipv4_addr ++ flags interval ++ auto-merge ++ } ++ ++ set interface6 { ++ type ipv6_addr ++ flags interval ++ auto-merge ++ } ++ ++ chain tp_out { ++ meta mark & 0x80 == 0x80 return ++ meta l4proto { tcp, udp } fib saddr type local fib daddr type != local jump tp_rule ++ } ++ ++ chain tp_pre { ++ iifname "lo" mark & 0xc0 != 0x40 return ++ meta l4proto { tcp, udp } fib saddr type != local fib daddr type != local jump tp_rule ++ meta l4proto { tcp, udp } mark & 0xc0 == 0x40 tproxy ip to 127.0.0.1:32345 ++ meta l4proto { tcp, udp } mark & 0xc0 == 0x40 tproxy ip6 to [::1]:32345 ++ } ++ ++ chain output { ++ type route hook output priority mangle - 5; policy accept; ++ meta nfproto { ipv4, ipv6 } jump tp_out ++ } ++ ++ chain prerouting { ++ type filter hook prerouting priority mangle - 5; policy accept; ++ meta nfproto { ipv4, ipv6 } jump tp_pre ++ } ++ ++ chain tp_rule { ++ meta mark set ct mark ++ meta mark & 0xc0 == 0x40 return ++ iifname "docker*" return ++ iifname "veth*" return ++ iifname "wg*" return ++ iifname "ppp*" return ++ # anti-pollution ++ ip daddr @interface return ++ ip daddr @whitelist return ++ ip6 daddr @interface6 return ++ ip6 daddr @whitelist6 return ++ jump tp_mark ++ } ++ ++ chain tp_mark { ++ tcp flags & (fin | syn | rst | ack) == syn meta mark set mark | 0x40 ++ meta l4proto udp ct state new meta mark set mark | 0x40 ++ ct mark set mark ++ } ++} ++` ++ if configure.GetSettingNotNil().AntiPollution != configure.AntipollutionClosed { ++ table = strings.ReplaceAll(table, "# anti-pollution", ` ++ meta l4proto { tcp, udp } th dport 53 jump tp_mark ++ meta mark & 0xc0 == 0x40 return ++ `) ++ } ++ ++ if !IsIPv6Supported() { ++ // drop ipv6 packets hooks ++ table = strings.ReplaceAll(table, "meta nfproto { ipv4, ipv6 }", "meta nfproto ipv4") ++ } ++ ++ nftablesConf := asset.GetNFTablesConfigPath() ++ os.WriteFile(nftablesConf, []byte(table), 0644) ++ ++ command := ` ++ip rule add fwmark 0x40/0xc0 table 100 ++ip route add local 0.0.0.0/0 dev lo table 100 ++` ++ if IsIPv6Supported() { ++ command += ` ++ip -6 rule add fwmark 0x40/0xc0 table 100 ++ip -6 route add local ::/0 dev lo table 100 ++` ++ } ++ ++ command += `nft -f ` + nftablesConf ++ return Setter{Cmds: command} ++} ++ ++func (t *nftTproxy) GetCleanCommands() Setter { ++ command := ` ++ip rule del fwmark 0x40/0xc0 table 100 ++ip route del local 0.0.0.0/0 dev lo table 100 ++` ++ if IsIPv6Supported() { ++ command += ` ++ip -6 rule del fwmark 0x40/0xc0 table 100 ++ip -6 route del local ::/0 dev lo table 100 ++ ` ++ } ++ ++ command += `nft delete table inet v2raya` ++ if !IsIPv6Supported() { ++ command = strings.Replace(command, "inet", "ip", 1) ++ } ++ return Setter{Cmds: command} ++} +--- a/core/iptables/utils.go ++++ b/core/iptables/utils.go +@@ -1,12 +1,13 @@ + package iptables + + import ( ++ "net" ++ "strconv" ++ + "github.com/v2rayA/v2rayA/common" + "github.com/v2rayA/v2rayA/common/cmds" + "github.com/v2rayA/v2rayA/conf" + "golang.org/x/net/nettest" +- "net" +- "strconv" + ) + + func IPNet2CIDR(ipnet *net.IPNet) string { +@@ -44,3 +45,21 @@ func IsIPv6Supported() bool { + } + return cmds.IsCommandValid("ip6tables") + } ++ ++func IsNFTablesSupported() bool { ++ ++ switch conf.GetEnvironmentConfig().NFTablesSupport { ++ // Warning: ++ // This is an experimental feature for nftables support. ++ // The default value is "off" for now but may be changed to "auto" in the future ++ case "on": ++ return true ++ case "off": ++ return false ++ default: ++ } ++ if common.IsDocker() { ++ return false ++ } ++ return cmds.IsCommandValid("nft") ++} +--- a/core/iptables/watcher.go ++++ b/core/iptables/watcher.go +@@ -10,6 +10,7 @@ type LocalIPWatcher struct { + cidrPool map[string]struct{} + AddedFunc func(cidr string) + RemovedFunc func(cidr string) ++ UpdateFunc func(cidrs []string) + } + + func NewLocalIPWatcher(interval time.Duration, AddedFunc func(cidr string), RemovedFunc func(cidr string)) *LocalIPWatcher { +--- a/core/v2ray/asset/asset.go ++++ b/core/v2ray/asset/asset.go +@@ -3,12 +3,6 @@ package asset + import ( + "errors" + "fmt" +- "github.com/adrg/xdg" +- "github.com/muhammadmuzzammil1998/jsonc" +- "github.com/v2rayA/v2rayA/common/files" +- "github.com/v2rayA/v2rayA/conf" +- "github.com/v2rayA/v2rayA/core/v2ray/where" +- "github.com/v2rayA/v2rayA/pkg/util/log" + "io" + "io/fs" + "net/http" +@@ -17,6 +11,13 @@ import ( + "path/filepath" + "runtime" + "time" ++ ++ "github.com/adrg/xdg" ++ "github.com/muhammadmuzzammil1998/jsonc" ++ "github.com/v2rayA/v2rayA/common/files" ++ "github.com/v2rayA/v2rayA/conf" ++ "github.com/v2rayA/v2rayA/core/v2ray/where" ++ "github.com/v2rayA/v2rayA/pkg/util/log" + ) + + func GetV2rayLocationAssetOverride() string { +@@ -140,6 +141,10 @@ func GetV2rayConfigDirPath() (p string) + return conf.GetEnvironmentConfig().V2rayConfigDirectory + } + ++func GetNFTablesConfigPath() (p string) { ++ return path.Join(conf.GetEnvironmentConfig().Config, "v2raya.nft") ++} ++ + func Download(url string, to string) (err error) { + log.Info("Downloading %v to %v", url, to) + c := http.Client{Timeout: 90 * time.Second} +--- a/core/v2ray/transparent.go ++++ b/core/v2ray/transparent.go +@@ -2,13 +2,14 @@ package v2ray + + import ( + "fmt" ++ "strings" ++ "time" ++ + "github.com/v2rayA/v2rayA/conf" + "github.com/v2rayA/v2rayA/core/iptables" + "github.com/v2rayA/v2rayA/core/specialMode" + "github.com/v2rayA/v2rayA/db/configure" + "github.com/v2rayA/v2rayA/pkg/util/log" +- "strings" +- "time" + ) + + func deleteTransparentProxyRules() { +@@ -45,12 +46,12 @@ func writeTransparentProxyRules() (err e + } + return fmt.Errorf("not support \"tproxy\" mode of transparent proxy: %w", err) + } +- iptables.SetWatcher(&iptables.Tproxy) ++ iptables.SetWatcher(iptables.Tproxy) + case configure.TransparentRedirect: + if err = iptables.Redirect.GetSetupCommands().Run(true); err != nil { + return fmt.Errorf("not support \"redirect\" mode of transparent proxy: %w", err) + } +- iptables.SetWatcher(&iptables.Redirect) ++ iptables.SetWatcher(iptables.Redirect) + case configure.TransparentSystemProxy: + if err = iptables.SystemProxy.GetSetupCommands().Run(true); err != nil { + return fmt.Errorf("not support \"system proxy\" mode of transparent proxy: %w", err) diff --git a/utils/conmon/Makefile b/utils/conmon/Makefile index c78c97554c..48a149a485 100644 --- a/utils/conmon/Makefile +++ b/utils/conmon/Makefile @@ -1,12 +1,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=conmon -PKG_VERSION:=2.1.6 +PKG_VERSION:=2.1.7 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://github.com/containers/$(PKG_NAME)/archive/v$(PKG_VERSION) -PKG_HASH:=340453f7aac43e6a1f9a5efe31f24471f8a7a997a849ad6d1ff3fb530a9e2874 +PKG_HASH:=7d0f9a2f7cb8a76c51990128ac837aaf0cc89950b6ef9972e94417aa9cf901fe PKG_MAINTAINER:=Oskari Rauta PKG_LICENSE:=Apache-2.0 diff --git a/utils/coremark/Makefile b/utils/coremark/Makefile index 0a3113c472..dc7c13eebd 100644 --- a/utils/coremark/Makefile +++ b/utils/coremark/Makefile @@ -8,13 +8,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=coremark -PKG_SOURCE_DATE:=2022-07-27 -PKG_SOURCE_VERSION:=eefc986ebd3452d6adde22eafaff3e5c859f29e4 +PKG_SOURCE_DATE:=2023-01-25 +PKG_SOURCE_VERSION:=d5fad6bd094899101a4e5fd53af7298160ced6ab PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_DATE).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/eembc/coremark/tar.gz/$(PKG_SOURCE_VERSION)? -PKG_HASH:=a5964bf215786d65d08941b6f9a9a4f4e50524f5391fa3826db2994c47d5e7f3 +PKG_HASH:=76f3b98fc940d277521023dc6e106551ef4a2180fa4c3da8cd5bf933aa494ef2 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_SOURCE_VERSION) PKG_MAINTAINER:=Lim Guo Wei \ diff --git a/utils/lolcat/Makefile b/utils/lolcat/Makefile index 644bd25f8d..8bd5e00800 100644 --- a/utils/lolcat/Makefile +++ b/utils/lolcat/Makefile @@ -1,12 +1,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=lolcat -PKG_VERSION:=1.2 +PKG_VERSION:=1.4 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/jaseg/lolcat/tar.gz/refs/tags/v$(PKG_VERSION)? -PKG_HASH:=b6e1a0e24479fbdd4eb907531339e2cafc0c00b78d19caf70e8377b8b7546331 +PKG_HASH:=6ea43ee2b2bb2f15fc91812b72ebcdaa883052853ed8f055b6f8b38637bda909 PKG_MAINTAINER:=Rui Salvaterra PKG_LICENSE:=WTFPL diff --git a/utils/mv88e6xxx_dump/Makefile b/utils/mv88e6xxx_dump/Makefile index 52bcea5abc..f3042be77d 100644 --- a/utils/mv88e6xxx_dump/Makefile +++ b/utils/mv88e6xxx_dump/Makefile @@ -12,9 +12,9 @@ PKG_FIXUP:=autoreconf PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/lunn/mv88e6xxx_dump -PKG_MIRROR_HASH:=2f1bce89212a10be89e106398ccc2f7eedcc1a7299bf8a1a05b3baf061f779f5 -PKG_SOURCE_DATE:=2022.03.29 -PKG_SOURCE_VERSION:=a3f713f99e0004d17d9282e0cb253505b9ca35b6 +PKG_MIRROR_HASH:=cee56d21347496ca38a15d7572dbd2b0db32dfbfbb19a8ce679b9095f7b5a247 +PKG_SOURCE_DATE:=2023.03.08 +PKG_SOURCE_VERSION:=b4c5247ee8bb5512fb80081503aae183b35ed3c6 PKG_MAINTAINER:=Etienne Champetier PKG_LICENSE:=GPL-2.0-only diff --git a/utils/ripgrep/Makefile b/utils/ripgrep/Makefile new file mode 100644 index 0000000000..fe449bc2d8 --- /dev/null +++ b/utils/ripgrep/Makefile @@ -0,0 +1,46 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2023 Luca Barbato and Donald Hoskins + +include $(TOPDIR)/rules.mk + +PKG_NAME:=ripgrep +PKG_VERSION:=13.0.0 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/BurntSushi/ripgrep/tar.gz/$(PKG_VERSION)? +PKG_HASH:=0fb17aaf285b3eee8ddab17b833af1e190d73de317ff9648751ab0660d763ed2 + +PKG_MAINTAINER:=Luca Barbato +PKG_LICENSE:=MIT Unlicense +PKG_LICENSE_FILES:=LICENSE-MIT UNLICENSE + +PKG_BUILD_DEPENDS:=rust/host + +include ../../lang/rust/rust-package.mk +include $(INCLUDE_DIR)/package.mk + +define Build/Compile + $(call Build/Compile/Cargo,, --features 'pcre2') +endef + +define Package/ripgrep + SECTION:=utils + CATEGORY:=Utilities + TITLE:=ripgrep (rg) regex grep + DEPENDS:=$(RUST_ARCH_DEPENDS) +libpcre2 + URL:=https://github.com/BurntSushi/ripgrep +endef + +define Package/ripgrep/description + ripgrep (rg) recursively searches directories for a regex pattern + while respecting your gitignore +endef + +define Package/ripgrep/install + $(INSTALL_DIR) $(1)/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/target/$(RUSTC_TARGET_ARCH)/stripped/rg $(1)/bin/rg +endef + +$(eval $(call BuildPackage,ripgrep))