mirror of
https://github.com/falk-werner/webfused
synced 2024-10-27 20:44:08 +00:00
Compare commits
128 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
e1ab67f6b4 | ||
|
f37a9342ec | ||
|
03332d2f46 | ||
|
e8f36edfce | ||
|
da174ebf22 | ||
|
e42639fc2a | ||
|
fa46f9fd6e | ||
|
d8879cf1d9 | ||
|
3c14ba1cae | ||
|
ce2f70f230 | ||
|
dfd2cd4bc0 | ||
|
3c0fce8eee | ||
|
8ad59f6bfa | ||
|
ea323634b1 | ||
|
977f823a61 | ||
|
c71d04dcbe | ||
|
ea40e93f5b | ||
|
de791d2788 | ||
|
0126bb53cb | ||
|
c972c17bd2 | ||
|
3aaf2a6792 | ||
|
69655c5784 | ||
|
4e168aa324 | ||
|
9487b3c2d4 | ||
|
1b172b5259 | ||
|
2b4d2b31b9 | ||
|
ef72d00d10 | ||
|
9d4ddf271c | ||
|
bbe3b7b669 | ||
|
6e62076d55 | ||
|
b95f537a79 | ||
|
e1705d50cf | ||
|
1d7f0c79ee | ||
|
44f809d7bd | ||
|
7d5e4be311 | ||
|
1660f74f7a | ||
|
b212ecc7a6 | ||
|
3cbf1aa1a3 | ||
|
449e584b30 | ||
|
5a0927c55c | ||
|
55707126ca | ||
|
91f72d9951 | ||
|
fd0b71c394 | ||
|
3dbf7c4561 | ||
|
6ac93184df | ||
|
c17a5749b1 | ||
|
4fba466165 | ||
|
566bf39bba | ||
|
d03d8e9412 | ||
|
45ac961f57 | ||
|
0328572c54 | ||
|
2b77e415ce | ||
|
4da0c4b672 | ||
|
b61a281949 | ||
|
57212f1b96 | ||
|
8d43061014 | ||
|
c3ec82535d | ||
|
343bf6da09 | ||
|
de8411c153 | ||
|
6a118f3e8a | ||
|
8b11eb0ea7 | ||
|
421c76b2e7 | ||
|
9bbe578857 | ||
|
2643b36ed8 | ||
|
0353131770 | ||
|
bc99cbfaab | ||
|
f6583baf5f | ||
|
cba0c5923c | ||
|
dd9e9449d2 | ||
|
944bd9913b | ||
|
563cbf5296 | ||
|
6492b0fd51 | ||
|
390acffe7b | ||
|
bd4323e53b | ||
|
ea56c6e86c | ||
|
90fc495d95 | ||
|
d7fd1fdf83 | ||
|
933789b045 | ||
|
364d19bdea | ||
|
35122136fd | ||
|
1223363c6c | ||
|
ba270f1d0d | ||
|
7553846629 | ||
|
5145129c18 | ||
|
e5aef52fdf | ||
|
ca348795f3 | ||
|
b53e002de0 | ||
|
35e63bb182 | ||
|
ecf967ab85 | ||
|
38f5c60e7b | ||
|
dcc067f258 | ||
|
d252fd7411 | ||
|
46ba61e97d | ||
|
b37e95f724 | ||
|
1cd1b1ddff | ||
|
adbfd45951 | ||
|
1625869696 | ||
|
609fbee24f | ||
|
5a58025e4a | ||
|
b62e9fc67b | ||
|
16c5db6b2c | ||
|
7e7cbd5d42 | ||
|
d90afed1b2 | ||
|
b5cd41d0fa | ||
|
5e90853ecf | ||
|
5dadb6240d | ||
|
0a19daa0ff | ||
|
2e81b8c23d | ||
|
fab2545df1 | ||
|
c10771b28a | ||
|
4ae6665f66 | ||
|
aaf8bcb688 | ||
|
f3743a6e01 | ||
|
892dd6d177 | ||
|
79fa1f6cbf | ||
|
389c27c7eb | ||
|
d8670b742c | ||
|
7e70d396f1 | ||
|
ad01f90bea | ||
|
03dc713649 | ||
|
b5943bd7b6 | ||
|
d304c843bc | ||
|
d8e1fcd426 | ||
|
7169cf9b5c | ||
|
4838740378 | ||
|
1c783e84eb | ||
|
141c857d4e | ||
|
207f18f4fd |
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,2 +1,4 @@
|
||||
/build/
|
||||
/.deps/
|
||||
/.vscode/
|
||||
/subprojects/*
|
||||
!/subprojects/*.wrap
|
69
.travis.yml
69
.travis.yml
@ -16,7 +16,6 @@ addons:
|
||||
- ca-certificates
|
||||
- openssl
|
||||
- libssl-dev
|
||||
- uuid-dev
|
||||
- udev
|
||||
- gettext
|
||||
- python3
|
||||
@ -24,62 +23,30 @@ addons:
|
||||
- python3-setuptools
|
||||
- python3-wheel
|
||||
- ninja-build
|
||||
- libconfig-dev
|
||||
- libpam0g-dev
|
||||
- valgrind
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- BUILD_TYPE=debug COVERAGE=true CHECK_OPTS=
|
||||
- BUILD_TYPE=debug COVERAGE=false CHECK_OPTS=--wrap='valgrind --error-exitcode=42'
|
||||
- BUILD_TYPE=release COVERAGE=false CHECK_OPTS=
|
||||
- BUILD_TYPE=minsize COVERAGE=false CHECK_OPTS=
|
||||
|
||||
|
||||
before_install:
|
||||
- mkdir .deps
|
||||
- cd .deps
|
||||
# libfuse
|
||||
- export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib:/usr/local/lib/x86_64-linux-gnu
|
||||
- sudo pip3 install --system meson
|
||||
- wget https://github.com/libfuse/libfuse/archive/fuse-3.9.0.tar.gz -O fuse.tar.gz
|
||||
- tar -xf fuse.tar.gz
|
||||
- cd libfuse-fuse-3.9.0
|
||||
- mkdir .build
|
||||
- cd .build
|
||||
- meson ..
|
||||
- ninja
|
||||
- sudo ninja install
|
||||
- cd ..
|
||||
- cd ..
|
||||
# libwebsockets
|
||||
- wget https://github.com/warmcat/libwebsockets/archive/v3.2.0.tar.gz -O libwebsockets.tar.gz
|
||||
- tar -xf libwebsockets.tar.gz
|
||||
- cd libwebsockets-3.2.0
|
||||
- mkdir .build
|
||||
- cd .build
|
||||
- cmake ..
|
||||
- make
|
||||
- sudo make install
|
||||
- cd ..
|
||||
- cd ..
|
||||
# jansson
|
||||
- wget https://github.com/akheron/jansson/archive/v2.12.tar.gz -O jansson.tar.gz
|
||||
- tar -xf jansson.tar.gz
|
||||
- cd jansson-2.12
|
||||
- mkdir .build
|
||||
- cd .build
|
||||
- cmake ..
|
||||
- make
|
||||
- sudo make install
|
||||
- cd ..
|
||||
- cd ..
|
||||
# libwebfuse
|
||||
- wget https://github.com/falk-werner/webfuse/archive/v0.2.0.tar.gz -O webfuse.tar.gz
|
||||
- tar -xf webfuse.tar.gz
|
||||
- cd webfuse-0.2.0
|
||||
- mkdir .build
|
||||
- cd .build
|
||||
- cmake -DWITHOUT_TESTS=ON ..
|
||||
- make
|
||||
- sudo make install
|
||||
- cd ..
|
||||
- cd ..
|
||||
- cd ..
|
||||
- bash <(curl -s https://raw.githubusercontent.com/falk-werner/install_deps/main/install_deps.sh) -s
|
||||
|
||||
before_script:
|
||||
- mkdir build
|
||||
- meson -Dbuildtype=$BUILD_TYPE -Db_coverage=$COVERAGE build
|
||||
- cd build
|
||||
- cmake ..
|
||||
- ninja
|
||||
|
||||
script:
|
||||
make
|
||||
- meson test --print-errorlogs -t 10 $CHECK_OPTS
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
@ -1,77 +0,0 @@
|
||||
cmake_minimum_required (VERSION 3.10)
|
||||
project(webfused VERSION 0.1.0 DESCRIPTION "Webfuse daemon")
|
||||
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(FUSE3 REQUIRED fuse3)
|
||||
pkg_check_modules(LWS REQUIRED libwebsockets)
|
||||
pkg_check_modules(JANSSON REQUIRED jansson)
|
||||
pkg_check_modules(UUID REQUIRED uuid)
|
||||
pkg_check_modules(OPENSSL REQUIRED openssl)
|
||||
pkg_check_modules(WEBFUSE REQUIRED libwebfuse-adapter)
|
||||
|
||||
add_definitions(-D_FILE_OFFSET_BITS=64)
|
||||
|
||||
include_directories(
|
||||
"src"
|
||||
${WEBFUSE_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
link_directories(
|
||||
${WEBFUSE_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
set(C_WARNINGS -Wall -Wextra)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
add_library(userdb STATIC
|
||||
src/userdb/userdb.c
|
||||
)
|
||||
|
||||
target_include_directories(userdb PUBLIC
|
||||
${OPENSSL_INCLUDE_DIRS}
|
||||
${JANSSON_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_compile_options(userdb PUBLIC ${OPENSSL_CFLAGS_OTHER})
|
||||
|
||||
|
||||
add_executable(webfused
|
||||
src/daemon/main.c
|
||||
)
|
||||
|
||||
target_link_libraries(webfused PUBLIC
|
||||
userdb
|
||||
${OPENSSL_LIBRARIES}
|
||||
${WEBFUSE_LIBRARIES}
|
||||
${UUID_LIBRARIES}
|
||||
)
|
||||
|
||||
target_compile_options(webfused PUBLIC ${OPENSSL_CFLAGS_OTHER})
|
||||
install(TARGETS webfused DESTINATION bin)
|
||||
|
||||
add_executable(webfuse-passwd
|
||||
src/passwd/main.c
|
||||
)
|
||||
|
||||
target_link_libraries(webfuse-passwd PUBLIC
|
||||
userdb
|
||||
${OPENSSL_LIBRARIES}
|
||||
${JANSSON_LIBRARIES}
|
||||
)
|
||||
|
||||
target_include_directories(webfuse-passwd PUBLIC
|
||||
example/passwd
|
||||
example/lib/userdb/include
|
||||
${OPENSSL_INCLUDE_DIRS}
|
||||
${JANSSON_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_compile_options(webfuse-passwd PUBLIC ${OPENSSL_CFLAGS_OTHER})
|
||||
install(TARGETS webfuse-passwd DESTINATION bin)
|
84
README.md
84
README.md
@ -1,78 +1,22 @@
|
||||
[](https://travis-ci.org/falk-werner/webfused)
|
||||
[](https://codecov.io/gh/falk-werner/webfused)
|
||||
|
||||
# webfused
|
||||
# Webfuse Daemon
|
||||
|
||||
Reference implementation of webfuse daemon.
|
||||
Reference implementation of webfuse daemon (webfused).
|
||||
|
||||
## Build and run
|
||||
**Note:** This repository refers to [webfuse-legacy](https://github.com/falk-werner/webfuse/tree/webfuse-legacy).
|
||||
Since `webfuse-legacy` is out-dated, the repository is archived and will be removed in future.
|
||||
_Please leave an issue if you are still interested in this code._
|
||||
|
||||
To install dependecies, see below.
|
||||
## Further information
|
||||
|
||||
cd webfused
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
./webfused -m test --port=4711
|
||||
- [Build Instructions](doc/build.md)
|
||||
- [Configuration](doc/config.md)
|
||||
- [Webfuse Protocol Specification](https://github.com/falk-werner/webfuse/blob/master/doc/protocol.md)
|
||||
|
||||
## Dependencies
|
||||
## Fellow Repositories
|
||||
|
||||
- [webfuse](https://github.com/falk-werner/webfuse)
|
||||
- [libfuse](https://github.com/libfuse/libfuse/)
|
||||
- [libwebsockets](https://libwebsockets.org/)
|
||||
- [jansson](https://github.com/akheron/jansson)
|
||||
- [openssl](https://www.openssl.org/)
|
||||
|
||||
### Installing dependencies
|
||||
|
||||
#### libfuse
|
||||
|
||||
To install libfuse, meson is needed. Please refer to [meson quick guide](https://mesonbuild.com/Quick-guide.html) for setup instructions.
|
||||
|
||||
wget https://github.com/libfuse/libfuse/archive/fuse-3.9.0.tar.gz -O fuse.tar.gz
|
||||
tar -xf fuse.tar.gz
|
||||
cd libfuse-fuse-3.9.0
|
||||
mkdir .build
|
||||
cd .build
|
||||
meson ..
|
||||
ninja
|
||||
sudo ninja install
|
||||
|
||||
#### libwebsockets
|
||||
|
||||
wget https://github.com/warmcat/libwebsockets/archive/v3.2.0.tar.gz -O libwebsockets.tar.gz
|
||||
tar -xf libwebsockets.tar.gz
|
||||
cd libwebsockets-3.2.0
|
||||
mkdir .build
|
||||
cd .build
|
||||
cmake ..
|
||||
make
|
||||
sudo make install
|
||||
|
||||
|
||||
#### jansson
|
||||
|
||||
wget https://github.com/akheron/jansson/archive/v2.12.tar.gz -O jansson.tar.gz
|
||||
tar -xf jansson.tar.gz
|
||||
cd jansson-2.12
|
||||
mkdir .build
|
||||
cd .build
|
||||
cmake ..
|
||||
make
|
||||
sudo make install
|
||||
|
||||
#### openssl
|
||||
|
||||
sudo apt update
|
||||
sudo install openssl libssl-dev
|
||||
|
||||
#### webfuse
|
||||
|
||||
wget https://github.com/falk-werner/webfuse/archive/v0.2.0.tar.gz -O webfuse.tar.gz
|
||||
tar -xf webfuse.tar.gz
|
||||
cd webfuse-0.2.0
|
||||
mkdir .build
|
||||
cd .build
|
||||
cmake -DWITHOUT_TESTS=ON ..
|
||||
make
|
||||
sudo make install
|
||||
- **[webfuse](https://github.com/falk-werner/webfuse)**: webfuse library
|
||||
- **[webfuse-example](https://github.com/falk-werner/webfuse-example)**: example of webfuse
|
||||
- **[webfuse-provider](https://github.com/falk-werner/webfuse-provider)**: reference implementation of webfuse provider
|
||||
|
42
changelog.md
Normal file
42
changelog.md
Normal file
@ -0,0 +1,42 @@
|
||||
# webfused changelog
|
||||
|
||||
## 0.7.0 _(unknown)_
|
||||
|
||||
* __Chore:__ added changelog
|
||||
|
||||
## 0.6.0 _(Sat Nov 14 2020)_
|
||||
|
||||
* __Feature:__ allow to specify mount options via config file
|
||||
* __Feature:__ make userdb optional
|
||||
* __Feature:__ reduce versions of depencies to required minimum
|
||||
* __Chore:__ updated dependencies (libwebsockets 4.1.3, libjansson 2.13.1, libfuse 3.10.0, webfuse 0.7.0)
|
||||
* __Chore:__ remove meson subprojects (use install_deps to fetch depedencies)
|
||||
* __Fix:__ ensure that syslog ident is valid while logger is active (invalid memory access)
|
||||
|
||||
## 0.5.0 _(Sun Jul 19 2020)_
|
||||
|
||||
* __Chore:__ updated depedencies (webfuse 0.5.0)
|
||||
|
||||
## 0.4.1 _(Sun Jul 05 2020)_
|
||||
|
||||
* __Fix:__ removed gtest dependency, when built without tests
|
||||
|
||||
## 0.4.0 _(Sun Jul 05 2020)_
|
||||
|
||||
* __Feature:__ allow to build without tests
|
||||
* __Chore:__ updated dependencies (libwebsockets 4.0.0, webfuse 0.4.0)
|
||||
|
||||
## 0.3.0 _(Sat Jun 06 2020)_
|
||||
|
||||
* __Chore:__ switched build system to meson
|
||||
|
||||
## 0.2.0 _(Fri Mar 20 2020)_
|
||||
|
||||
* __Feature:__ enabled authentication (pam, userdb)
|
||||
* __Feature:__ use config file
|
||||
* __Feature:__ added syslog logger
|
||||
|
||||
## 0.1.0 _(Mon Mar 09 2020)_
|
||||
|
||||
* __Feature:__ initial version
|
||||
|
4
codecov.yml
Normal file
4
codecov.yml
Normal file
@ -0,0 +1,4 @@
|
||||
ignore:
|
||||
- "test"
|
||||
- "src/passwd"
|
||||
- "src/webfused/main.c"
|
31
deps.sh
Normal file
31
deps.sh
Normal file
@ -0,0 +1,31 @@
|
||||
PACKAGES="fuse3 libwebsockets jansson gtest webfuse"
|
||||
|
||||
fuse3_VERSION=3.10.0
|
||||
fuse3_URL=https://github.com/libfuse/libfuse/archive/fuse-${fuse3_VERSION}.tar.gz
|
||||
fuse3_MD5=22aec9bc9008eea6b17e203653d1b938
|
||||
fuse3_DIR=libfuse-fuse-${fuse3_VERSION}
|
||||
fuse3_TYPE=meson
|
||||
|
||||
libwebsockets_VERSION=4.1.3
|
||||
libwebsockets_URL=https://github.com/warmcat/libwebsockets/archive/v${libwebsockets_VERSION}.tar.gz
|
||||
libwebsockets_MD5=413cbe790ccb089001f53b2ee167b9c2
|
||||
libwebsockets_DIR=libwebsockets-${libwebsockets_VERSION}
|
||||
libwebsockets_TYPE=cmake
|
||||
|
||||
jansson_VERSION=2.13.1
|
||||
jansson_URL=https://github.com/akheron/jansson/archive/v${jansson_VERSION}.tar.gz
|
||||
jansson_MD5=3d589a62053874893715453a46a32a0e
|
||||
jansson_DIR=jansson-${jansson_VERSION}
|
||||
jansson_TYPE=cmake
|
||||
|
||||
gtest_VERSION=1.10.0
|
||||
gtest_URL=https://github.com/google/googletest/archive/release-${gtest_VERSION}.tar.gz
|
||||
gtest_MD5=ecd1fa65e7de707cd5c00bdac56022cd
|
||||
gtest_DIR=googletest-release-${gtest_VERSION}
|
||||
gtest_TYPE=cmake
|
||||
|
||||
webfuse_VERSION=0.7.0
|
||||
webfuse_URL=https://github.com/falk-werner/webfuse/archive/v${webfuse_VERSION}.tar.gz
|
||||
webfuse_MD5=4f8b69196a634016da3c0e4f63e13590
|
||||
webfuse_DIR=webfuse-${webfuse_VERSION}
|
||||
webfuse_TYPE=meson
|
97
doc/build.md
Normal file
97
doc/build.md
Normal file
@ -0,0 +1,97 @@
|
||||
# Build Instructions
|
||||
|
||||
To install dependecies, see below.
|
||||
|
||||
meson build
|
||||
cd build
|
||||
ninja
|
||||
./webfused -f webfused.conf
|
||||
|
||||
## Dependencies
|
||||
|
||||
- [webfuse](https://github.com/falk-werner/webfuse)
|
||||
- [libfuse](https://github.com/libfuse/libfuse/)
|
||||
- [libwebsockets](https://libwebsockets.org/)
|
||||
- [jansson](https://github.com/akheron/jansson)
|
||||
- [openssl](https://www.openssl.org/)
|
||||
- [libconfig](https://hyperrealm.github.io/libconfig/)
|
||||
- [linux-pam](http://www.linux-pam.org/)
|
||||
- [Google Test](https://github.com/google/googletest) *(Test only)*
|
||||
|
||||
It is recommended to provide all dependencies outside of the project.
|
||||
|
||||
To simply development, some dependencies are bundled using meson wrap files. Note that installing webfused will also install subprojects, when they are used (this is typically not what you want).
|
||||
|
||||
### libfuse
|
||||
|
||||
To install libfuse, meson is needed. Please refer to [meson quick guide](https://mesonbuild.com/Quick-guide.html) for setup instructions.
|
||||
|
||||
wget https://github.com/libfuse/libfuse/archive/fuse-3.9.1.tar.gz -O fuse.tar.gz
|
||||
tar -xf fuse.tar.gz
|
||||
cd libfuse-fuse-3.9.1
|
||||
mkdir .build
|
||||
cd .build
|
||||
meson ..
|
||||
ninja
|
||||
sudo ninja install
|
||||
|
||||
### libwebsockets
|
||||
|
||||
wget https://github.com/warmcat/libwebsockets/archive/v4.0.13.tar.gz -O libwebsockets.tar.gz
|
||||
tar -xf libwebsockets.tar.gz
|
||||
cd libwebsockets-4.0.13
|
||||
mkdir .build
|
||||
cd .build
|
||||
cmake ..
|
||||
make
|
||||
sudo make install
|
||||
|
||||
### jansson
|
||||
|
||||
wget https://github.com/akheron/jansson/archive/v2.12.tar.gz -O jansson.tar.gz
|
||||
tar -xf jansson.tar.gz
|
||||
cd jansson-2.12
|
||||
mkdir .build
|
||||
cd .build
|
||||
cmake ..
|
||||
make
|
||||
sudo make install
|
||||
|
||||
### openssl
|
||||
|
||||
sudo apt update
|
||||
sudo install openssl libssl-dev
|
||||
|
||||
### webfuse
|
||||
|
||||
wget https://github.com/falk-werner/webfuse/archive/v0.2.0.tar.gz -O webfuse.tar.gz
|
||||
tar -xf webfuse.tar.gz
|
||||
cd webfuse-0.2.0
|
||||
mkdir .build
|
||||
cd .build
|
||||
cmake -DWITHOUT_TESTS=ON ..
|
||||
make
|
||||
sudo make install
|
||||
|
||||
### libconfig
|
||||
|
||||
sudo apt update
|
||||
sudo apt install libconfig-dev
|
||||
|
||||
### linux-pam
|
||||
|
||||
sudo apt update
|
||||
sudo apt install libpam0g-dev
|
||||
|
||||
### GoogleTest
|
||||
|
||||
Installation of GoogleTest is optional webfuse library, but required to compile tests.
|
||||
|
||||
wget -O gtest-1.10.0.tar.gz https://github.com/google/googletest/archive/release-1.10.0.tar.gz
|
||||
tar -xf gtest-1.10.0.tar.gz
|
||||
cd googletest-release-1.10.0
|
||||
mkdir .build
|
||||
cd .build
|
||||
cmake ..
|
||||
make
|
||||
sudo make install
|
168
doc/config.md
Normal file
168
doc/config.md
Normal file
@ -0,0 +1,168 @@
|
||||
# Configuration
|
||||
|
||||
A config file is used to configure webfuse daemon.
|
||||
|
||||
## Config file
|
||||
|
||||
```
|
||||
version = { major = 1, minor = 1 }
|
||||
|
||||
server:
|
||||
{
|
||||
vhost_name = "localhost"
|
||||
port = 8080
|
||||
|
||||
tls:
|
||||
{
|
||||
certificate = "/etc/webfused/cert.pem"
|
||||
|
||||
key = "/etc/webfused/key.pem"
|
||||
}
|
||||
|
||||
document_root = "/var/www"
|
||||
}
|
||||
|
||||
authentication:
|
||||
(
|
||||
{
|
||||
provider = "pam"
|
||||
settings:
|
||||
{
|
||||
service_name = "webfused"
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
filesystems:
|
||||
(
|
||||
{name = "test", mount_point = "/tmp/webfused", mount_options = () }
|
||||
)
|
||||
|
||||
log:
|
||||
{
|
||||
provider: "syslog"
|
||||
level: "warning"
|
||||
settings:
|
||||
{
|
||||
ident = "webfused"
|
||||
facility = "daemon"
|
||||
log_pid = true
|
||||
}
|
||||
}
|
||||
|
||||
user:
|
||||
{
|
||||
name = "webfused"
|
||||
group = "webfused"
|
||||
}
|
||||
```
|
||||
|
||||
## Version
|
||||
|
||||
The version sections specifies the schema version of the config file.
|
||||
Currently, there is only one schema version defined: 1.0
|
||||
|
||||
## Server
|
||||
|
||||
| Setting | Type | Default value | Description |
|
||||
| ------------- | ------ | ------------- | ------------------------ |
|
||||
| vhostname | string | localhost | Name of the virtual host |
|
||||
| port | int | 8080 | Port number of server |
|
||||
| document_root | string | *-empty-* | Path of HTTP files |
|
||||
| tls | object | *-empty-* | see below |
|
||||
|
||||
When *document_root* is omitted, no HTTP files are served.
|
||||
|
||||
### TLS
|
||||
|
||||
| Setting | Type | Default value | Description |
|
||||
| ----------- | ------ | ------------- | ------------------------------------------- |
|
||||
| certificate | string | *-empty-* | Path to servers own certificate (.pem file) |
|
||||
| key | string | *-empty-* | Path to servers own private key (.pem file) |
|
||||
|
||||
TLS is only activated, when both, *certificate* and *key* are specified.
|
||||
Otherwise, plain websockes without TLS are used.
|
||||
|
||||
## Authentication
|
||||
|
||||
| Setting | Type | Default value | Description |
|
||||
| -------- | ------ | ------------- | ----------------------------------------------- |
|
||||
| provider | string | *-required-* | Name of the authentication provider (see below) |
|
||||
| settings | object | *-empty-* | Provider specific settings (see below)
|
||||
|
||||
Currently, the following providers are supported:
|
||||
|
||||
- *file*: file based authentication
|
||||
- *pam*: authentication based on Linux PAM
|
||||
|
||||
## File Authenticaton Provider
|
||||
|
||||
Allows authentication against a file containing username and password.
|
||||
|
||||
| Setting | Type | Default value | Description |
|
||||
| -------- | ------ | ------------- | ------------------------------- |
|
||||
| file | string | *-required-* | Path to the authentication file |
|
||||
|
||||
## PAM Authenticaton Provider
|
||||
|
||||
Allows authentication using Linux PAM.
|
||||
|
||||
| Setting | Type | Default value | Description |
|
||||
| ------------ | ------ | ------------- | ---------------------- |
|
||||
| service_name | string | webfused | PAM service identifier |
|
||||
|
||||
## Filesystems
|
||||
|
||||
Contains a list of file systems that can be provided by webfuse providers.
|
||||
|
||||
| Setting | Type | Default value | Description |
|
||||
| ----------- | ------ | ------------- | ---------------------------------- |
|
||||
| name | string | *-required-* | Name of the filesystem |
|
||||
| mount_point | string | *-required-* | Local path to mount the filesystem |
|
||||
|
||||
## Log
|
||||
|
||||
| Setting | Type | Default value | Description |
|
||||
| ----------- | ------ | ------------- | -------------------------------------- |
|
||||
| provider | string | *-required-* | Name of log provider (see below) |
|
||||
| level | string | *-required-* | Log level (see below) |
|
||||
| settings | object | *-empty-* | Provider specific settings (see below) |
|
||||
|
||||
The following log levels are supported:
|
||||
|
||||
- *none*: diabled logging
|
||||
- *fatal*: log only fatal errors
|
||||
- *error*: log all kind of errors
|
||||
- *warn*: log errors and warnings
|
||||
- *info*: log info messages, warnings and errors
|
||||
- *debug*: log debug and info messages as well as warnings and errors
|
||||
- *all*: log all kind of messages
|
||||
|
||||
Currently, the following providers are available:
|
||||
|
||||
- *stderr*: logs to console error output
|
||||
- *syslog*: logs to syslog
|
||||
|
||||
### Stderr Logger
|
||||
|
||||
This logger does not provide any settings.
|
||||
|
||||
### Syslog Logger
|
||||
|
||||
| Setting | Type | Default value | Description |
|
||||
| ----------- | ------ | ------------- | ------------------------------------------ |
|
||||
| ident | string | webfused | Syslog ident (see syslog documentation) |
|
||||
| facility | string | daemon | Syslog facility (see syslog documentation) |
|
||||
| log_pid | bool | false | Add process ID to log messages |
|
||||
|
||||
## User
|
||||
|
||||
| Setting | Type | Default value | Description |
|
||||
| ------- | ------ | ------------- | ------------------------------- |
|
||||
| name | string | *-required-* | Name of the user to switch to. |
|
||||
| group | string | *-required-* | Name of the group to switch to. |
|
||||
|
||||
Webfuse daemon will not run as root. If started as root, webfuse daemon tries to
|
||||
switch to *user* and *group* provided in config file.
|
||||
|
||||
*Note*: user and group are not switched, when webfuse daemon is not started as root.
|
58
etc/webfused.conf
Normal file
58
etc/webfused.conf
Normal file
@ -0,0 +1,58 @@
|
||||
# Webfuse deamon configuration file
|
||||
|
||||
version = { major = 1, minor = 1 }
|
||||
|
||||
server:
|
||||
{
|
||||
vhost_name = "localhost"
|
||||
port = 8080
|
||||
|
||||
# tls:
|
||||
# {
|
||||
# certificate = "/etc/webfused/cert.pem"
|
||||
# key = "/etc/webfused/key.pem"
|
||||
# }
|
||||
|
||||
# document_root = "/var/www"
|
||||
}
|
||||
|
||||
authentication:
|
||||
(
|
||||
{
|
||||
provider = "file"
|
||||
settings:
|
||||
{
|
||||
file = "/etc/webfused/passwd"
|
||||
}
|
||||
}
|
||||
# {
|
||||
# provider = "pam"
|
||||
# settings:
|
||||
# {
|
||||
# service_name = "webfused"
|
||||
# }
|
||||
# }
|
||||
)
|
||||
|
||||
filesystems:
|
||||
(
|
||||
{name = "test", mount_point = "/tmp/webfused", mount_options = () }
|
||||
)
|
||||
|
||||
log:
|
||||
{
|
||||
provider: "syslog"
|
||||
level: "warning"
|
||||
settings:
|
||||
{
|
||||
ident = "webfused"
|
||||
facility = "daemon"
|
||||
log_pid = true
|
||||
}
|
||||
}
|
||||
|
||||
#user:
|
||||
#{
|
||||
# name = "webfused"
|
||||
# group = "webfused"
|
||||
#}
|
170
meson.build
Normal file
170
meson.build
Normal file
@ -0,0 +1,170 @@
|
||||
project('webfused', 'c', 'cpp', version: '0.7.0', license: 'LGPL-3.0+',
|
||||
default_options: ['c_std=gnu99', 'cpp_std=gnu++14'])
|
||||
|
||||
without_tests = get_option('without_tests')
|
||||
without_userdb = get_option('without_userdb')
|
||||
|
||||
c_compiler = meson.get_compiler('c')
|
||||
|
||||
libconfig_dep = dependency('libconfig', version: '>=1.5')
|
||||
pam_dep = c_compiler.find_library('pam')
|
||||
|
||||
libwebsockets_dep = dependency('libwebsockets', version: '>=4.0.0')
|
||||
libfuse_dep = dependency('fuse3', version: '>=3.1.0')
|
||||
|
||||
webfuse_adapter_dep = dependency('webfuse', version: '>=0.7.0')
|
||||
|
||||
inc_dir = include_directories('src')
|
||||
|
||||
if not without_userdb
|
||||
openssl_dep = dependency('openssl', version: '>=1.1.1')
|
||||
jansson_dep = dependency('jansson', version: '>=2.7')
|
||||
|
||||
libuserdb = static_library('userdb',
|
||||
'src/userdb/userdb_openssl.c',
|
||||
include_directories: inc_dir,
|
||||
dependencies: [openssl_dep, jansson_dep])
|
||||
|
||||
libuserdb_dep = declare_dependency(
|
||||
include_directories: inc_dir,
|
||||
link_with: libuserdb,
|
||||
dependencies: [openssl_dep, jansson_dep])
|
||||
else
|
||||
libuserdb = static_library('userdb',
|
||||
'src/userdb/userdb_none.c',
|
||||
include_directories: inc_dir)
|
||||
|
||||
libuserdb_dep = declare_dependency(
|
||||
include_directories: inc_dir,
|
||||
link_with: libuserdb)
|
||||
endif
|
||||
|
||||
libwebfused = static_library('webfused',
|
||||
'src/webfused/daemon.c',
|
||||
'src/webfused/mountpoint_factory.c',
|
||||
'src/webfused/change_user.c',
|
||||
'src/webfused/config/config.c',
|
||||
'src/webfused/config/factory.c',
|
||||
'src/webfused/config/settings.c',
|
||||
'src/webfused/auth/authenticator.c',
|
||||
'src/webfused/auth/factory.c',
|
||||
'src/webfused/auth/file_authenticator.c',
|
||||
'src/webfused/auth/pam_authenticator.c',
|
||||
'src/webfused/log/log.c',
|
||||
'src/webfused/log/logger.c',
|
||||
'src/webfused/log/manager.c',
|
||||
'src/webfused/log/stderr_logger.c',
|
||||
'src/webfused/log/syslog_logger.c',
|
||||
'src/webfused/util/string_list.c',
|
||||
include_directories: inc_dir,
|
||||
dependencies: [libuserdb_dep, webfuse_adapter_dep, libconfig_dep, pam_dep],
|
||||
install: false)
|
||||
|
||||
libwebfused_dep = declare_dependency(
|
||||
include_directories: inc_dir,
|
||||
link_with: libwebfused,
|
||||
dependencies: [libuserdb_dep, webfuse_adapter_dep, libconfig_dep, pam_dep])
|
||||
|
||||
webfused = executable('webfused',
|
||||
'src/webfused/main.c',
|
||||
include_directories: inc_dir,
|
||||
dependencies: [libwebfused_dep],
|
||||
install: true)
|
||||
|
||||
install_data('etc/webfused.conf', install_dir: '/etc')
|
||||
|
||||
|
||||
if not without_tests
|
||||
|
||||
gtest_dep = dependency('gtest', version: '>=1.10.0', fallback: ['gtest', 'gtest_dep'])
|
||||
gmock_main_dep = dependency('gmock_main', version: '>=1.10.0', fallback: ['gtest', 'gmock_main_dep'])
|
||||
|
||||
webfused_conf = configure_file(input: 'etc/webfused.conf' , output: 'webfused.conf' , copy: true)
|
||||
invalid_conf = configure_file(input: 'test/invalid.conf' , output: 'invalid.conf' , copy: true)
|
||||
test_passwd_json = configure_file(input: 'test/test_passwd.json', output: 'test_passwd.json', copy: true)
|
||||
|
||||
alltests_sources = [
|
||||
'test/mock/config_builder.cc',
|
||||
'test/mock/logger.cc',
|
||||
'test/mock/credentials.cc',
|
||||
'test/mock/settings.cc',
|
||||
'test/mock/pam.cc',
|
||||
'test/mock/libconfig.cc',
|
||||
'test/mock/linux.cc',
|
||||
'test/mock/server.cc',
|
||||
'test/config/configfile.cc',
|
||||
'test/config/configfile_version.cc',
|
||||
'test/config/configfile_server.cc',
|
||||
'test/config/configfile_auth.cc',
|
||||
'test/config/configfile_filesystem.cc',
|
||||
'test/config/configfile_log.cc',
|
||||
'test/config/configfile_user.cc',
|
||||
'test/config/config.cc',
|
||||
'test/config/settings.cc',
|
||||
'test/auth/factory.cc',
|
||||
'test/auth/pam_authenticator.cc',
|
||||
'test/log/log.cc',
|
||||
'test/log/log_manager.cc',
|
||||
'test/log/stderr_logger.cc',
|
||||
'test/log/syslog_logger.cc',
|
||||
'test/util/string_list.cc',
|
||||
'test/daemon.cc',
|
||||
'test/change_user.cc',
|
||||
'test/mountpoint_factory.cc'
|
||||
]
|
||||
|
||||
if not without_userdb
|
||||
alltests_sources += [
|
||||
'test/auth/file_authenticator.cc',
|
||||
'test/userdb.cc'
|
||||
]
|
||||
endif
|
||||
|
||||
alltests = executable('alltests',
|
||||
alltests_sources,
|
||||
include_directories: ['src', 'test'],
|
||||
link_args: [
|
||||
'-Wl,--wrap=wf_credentials_type',
|
||||
'-Wl,--wrap=wf_credentials_get',
|
||||
|
||||
'-Wl,--wrap=wf_server_create',
|
||||
|
||||
'-Wl,--wrap=wfd_settings_get_string',
|
||||
'-Wl,--wrap=wfd_settings_get_string_or_default',
|
||||
'-Wl,--wrap=wfd_settings_get_bool',
|
||||
|
||||
'-Wl,--wrap=wfd_config_create',
|
||||
'-Wl,--wrap=wfd_config_dispose',
|
||||
'-Wl,--wrap=wfd_config_set_server_vhostname',
|
||||
'-Wl,--wrap=wfd_config_set_server_port',
|
||||
'-Wl,--wrap=wfd_config_set_server_key',
|
||||
'-Wl,--wrap=wfd_config_set_server_cert',
|
||||
'-Wl,--wrap=wfd_config_set_server_document_root',
|
||||
'-Wl,--wrap=wfd_config_add_auth_provider',
|
||||
'-Wl,--wrap=wfd_config_add_filesystem',
|
||||
'-Wl,--wrap=wfd_config_set_logger',
|
||||
'-Wl,--wrap=wfd_config_set_user',
|
||||
|
||||
'-Wl,--wrap=pam_start',
|
||||
'-Wl,--wrap=pam_end',
|
||||
'-Wl,--wrap=pam_strerror',
|
||||
'-Wl,--wrap=pam_authenticate',
|
||||
'-Wl,--wrap=pam_acct_mgmt',
|
||||
|
||||
'-Wl,--wrap=config_setting_get_elem',
|
||||
|
||||
'-Wl,--wrap=getuid',
|
||||
'-Wl,--wrap=getgrnam',
|
||||
'-Wl,--wrap=setgid',
|
||||
'-Wl,--wrap=setgroups',
|
||||
'-Wl,--wrap=getpwnam',
|
||||
'-Wl,--wrap=setuid'
|
||||
],
|
||||
dependencies: [
|
||||
libwebfused_dep,
|
||||
gtest_dep,
|
||||
gmock_main_dep])
|
||||
|
||||
test('alltests', alltests)
|
||||
|
||||
endif
|
2
meson_options.txt
Normal file
2
meson_options.txt
Normal file
@ -0,0 +1,2 @@
|
||||
option('without_tests', type: 'boolean', value: false, description: 'disable unit tests')
|
||||
option('without_userdb', type: 'boolean', value: false, description: 'disable userdb')
|
@ -1,196 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <webfuse_adapter.h>
|
||||
#include <userdb/userdb.h>
|
||||
|
||||
#define SERVICE_TIMEOUT (1 * 1000)
|
||||
|
||||
struct args
|
||||
{
|
||||
struct wf_server_config * config;
|
||||
char * passwd_path;
|
||||
bool show_help;
|
||||
};
|
||||
|
||||
static bool shutdown_requested = false;
|
||||
|
||||
static void show_help(void)
|
||||
{
|
||||
printf(
|
||||
"webfused, Copyright (c) 2019, webfused authors <https://github.com/falk-werner/webfused>\n"
|
||||
"Websocket file system daemon\n"
|
||||
"\n"
|
||||
"Usage: webfused [m <mount_point>] [-d <document_root] [-n <vhost_name>] [-p <port>]\n"
|
||||
" [-c <server_cert_path>] [-k <server_key_path>] [-P <passwd_path>]\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
"\t-m, --mount_point Path of mount point (required)\n"
|
||||
"\t-d, --document_root Path of www directory (default: not set, www disabled)\n"
|
||||
"\t-c, --server_cert_path Path of servers own certificate (default: not set, TLS disabled)\n"
|
||||
"\t-k, --server_key_path Path of servers private key (default: not set, TLS disabled)\n"
|
||||
"\t-n, --vhost_name Name of virtual host (default: \"localhost\")\n"
|
||||
"\t-p, --port Number of servers port (default: 8080)\n"
|
||||
"\t-P, --passwd_path Path to password file (default: not set, authentication disabled)\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
static bool authenticate(struct wf_credentials * creds, void * user_data)
|
||||
{
|
||||
bool result = false;
|
||||
struct args * args = user_data;
|
||||
|
||||
char const * username = wf_credentials_get(creds, "username");
|
||||
char const * password = wf_credentials_get(creds, "password");
|
||||
if ((NULL != username) && (NULL != password))
|
||||
{
|
||||
struct userdb * db = userdb_create("");
|
||||
result = userdb_load(db, args->passwd_path);
|
||||
if (result)
|
||||
{
|
||||
result = userdb_check(db, username, password);
|
||||
}
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int parse_arguments(int argc, char * argv[], struct args * args)
|
||||
{
|
||||
static struct option const options[] =
|
||||
{
|
||||
{"mount_point", required_argument, NULL, 'm'},
|
||||
{"document_root", required_argument, NULL, 'd'},
|
||||
{"server_cert_path", required_argument, NULL, 'c'},
|
||||
{"server_key_path", required_argument, NULL, 'k'},
|
||||
{"vhost_name", required_argument, NULL, 'n'},
|
||||
{"port", required_argument, NULL, 'p'},
|
||||
{"passwd_path", required_argument, NULL, 'P'},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
bool result = EXIT_SUCCESS;
|
||||
bool finished = false;
|
||||
bool has_mountpoint = false;
|
||||
while ((!finished) && (EXIT_SUCCESS == result))
|
||||
{
|
||||
int option_index = 0;
|
||||
int const c = getopt_long(argc, argv, "m:d:c:k:n:p:P:h", options, &option_index);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case -1:
|
||||
finished = true;
|
||||
break;
|
||||
case 'h':
|
||||
args->show_help = true;
|
||||
finished = true;
|
||||
break;
|
||||
case 'm':
|
||||
wf_server_config_set_mountpoint(args->config, optarg);
|
||||
has_mountpoint = true;
|
||||
break;
|
||||
case 'd':
|
||||
wf_server_config_set_documentroot(args->config, optarg);
|
||||
break;
|
||||
case 'c':
|
||||
wf_server_config_set_certpath(args->config, optarg);
|
||||
break;
|
||||
case 'k':
|
||||
wf_server_config_set_keypath(args->config, optarg);
|
||||
break;
|
||||
case 'n':
|
||||
wf_server_config_set_vhostname(args->config, optarg);
|
||||
break;
|
||||
case 'p':
|
||||
wf_server_config_set_port(args->config, atoi(optarg));
|
||||
break;
|
||||
case 'P':
|
||||
free(args->passwd_path);
|
||||
args->passwd_path = strdup(optarg);
|
||||
wf_server_config_add_authenticator(args->config,
|
||||
"username",
|
||||
&authenticate,
|
||||
args);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "error: unknown argument\n");
|
||||
result = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((EXIT_SUCCESS == result) && (!args->show_help))
|
||||
{
|
||||
if (!has_mountpoint)
|
||||
{
|
||||
fprintf(stderr, "error: missing mount point\n");
|
||||
result = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (EXIT_SUCCESS != result)
|
||||
{
|
||||
args->show_help = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void on_interrupt(int signal_id)
|
||||
{
|
||||
(void) signal_id;
|
||||
|
||||
shutdown_requested = true;
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
struct args args;
|
||||
args.config = wf_server_config_create();
|
||||
wf_server_config_set_vhostname(args.config, "localhost");
|
||||
wf_server_config_set_port(args.config, 8080);
|
||||
args.passwd_path = NULL;
|
||||
args.show_help = false;
|
||||
|
||||
int result = parse_arguments(argc, argv, &args);
|
||||
|
||||
if (!args.show_help)
|
||||
{
|
||||
signal(SIGINT, on_interrupt);
|
||||
struct wf_server * server = wf_server_create(args.config);
|
||||
if (NULL != server)
|
||||
{
|
||||
while (!shutdown_requested)
|
||||
{
|
||||
wf_server_service(server, SERVICE_TIMEOUT);
|
||||
}
|
||||
|
||||
wf_server_dispose(server);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "fatal: unable start server\n");
|
||||
result = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
show_help();
|
||||
}
|
||||
|
||||
free(args.passwd_path);
|
||||
wf_server_config_dispose(args.config);
|
||||
return result;
|
||||
}
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <jansson.h>
|
||||
#include <userdb/userdb.h>
|
||||
|
||||
|
||||
@ -131,7 +130,7 @@ static int parse_args(struct args * args, int argc, char * argv[])
|
||||
fprintf(stderr, "error: missing command\n");
|
||||
args->show_help = true;
|
||||
result = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -173,7 +172,7 @@ static int add_user(struct args * args)
|
||||
}
|
||||
|
||||
struct userdb * db = userdb_create(args->pepper);
|
||||
userdb_load(db, args->file);
|
||||
userdb_load_file(db, args->file);
|
||||
userdb_add(db, args->username, args->password);
|
||||
bool result = userdb_save(db, args->file);
|
||||
userdb_dispose(db);
|
||||
@ -191,7 +190,7 @@ static int remove_user(struct args * args)
|
||||
}
|
||||
|
||||
struct userdb * db = userdb_create(args->pepper);
|
||||
userdb_load(db, args->file);
|
||||
userdb_load_file(db, args->file);
|
||||
userdb_remove(db, args->username);
|
||||
bool result = userdb_save(db, args->file);
|
||||
userdb_dispose(db);
|
||||
@ -216,7 +215,7 @@ static int check_password(struct args * args)
|
||||
}
|
||||
|
||||
struct userdb * db = userdb_create(args->pepper);
|
||||
userdb_load(db, args->file);
|
||||
userdb_load_file(db, args->file);
|
||||
bool result = userdb_check(db, args->username, args->password);
|
||||
userdb_dispose(db);
|
||||
|
||||
@ -301,4 +300,4 @@ int main(int argc, char * argv[])
|
||||
args_cleanup(&args);
|
||||
openssl_cleanup();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -21,10 +21,14 @@ extern bool userdb_save(
|
||||
struct userdb * db,
|
||||
char const * filename);
|
||||
|
||||
extern bool userdb_load(
|
||||
extern bool userdb_load_file(
|
||||
struct userdb * db,
|
||||
char const * filename);
|
||||
|
||||
extern bool userdb_load_string(
|
||||
struct userdb * db,
|
||||
char const * contents);
|
||||
|
||||
extern void userdb_add(
|
||||
struct userdb * db,
|
||||
char const * username,
|
||||
|
74
src/userdb/userdb_none.c
Normal file
74
src/userdb/userdb_none.c
Normal file
@ -0,0 +1,74 @@
|
||||
#include "userdb.h"
|
||||
#include <stddef.h>
|
||||
|
||||
struct userdb * userdb_create(
|
||||
char const * pepper)
|
||||
{
|
||||
(void) pepper;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void userdb_dispose(struct userdb * db)
|
||||
{
|
||||
(void) db;
|
||||
}
|
||||
|
||||
bool userdb_save(
|
||||
struct userdb * db,
|
||||
char const * filename)
|
||||
{
|
||||
(void) db;
|
||||
(void) filename;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool userdb_load_file(
|
||||
struct userdb * db,
|
||||
char const * filename)
|
||||
{
|
||||
(void) db;
|
||||
(void) filename;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool userdb_load_string(
|
||||
struct userdb * db,
|
||||
char const * contents)
|
||||
{
|
||||
(void) db;
|
||||
(void) contents;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void userdb_add(
|
||||
struct userdb * db,
|
||||
char const * username,
|
||||
char const * password)
|
||||
{
|
||||
(void) db;
|
||||
(void) username;
|
||||
(void) password;
|
||||
}
|
||||
|
||||
void userdb_remove(
|
||||
struct userdb * db,
|
||||
char const * user)
|
||||
{
|
||||
(void) db;
|
||||
(void) user;
|
||||
}
|
||||
|
||||
bool userdb_check(
|
||||
struct userdb * db,
|
||||
char const * username,
|
||||
char const * password)
|
||||
{
|
||||
(void) db;
|
||||
(void) username;
|
||||
(void) password;
|
||||
|
||||
return false;
|
||||
}
|
@ -77,20 +77,17 @@ static char hex_char(unsigned char value)
|
||||
static char * to_hex(unsigned char const * value, size_t length)
|
||||
{
|
||||
char * result = malloc((2 * length) + 1);
|
||||
if (NULL != result)
|
||||
for (size_t i = 0, j = 0; i < length; i++, j+=2)
|
||||
{
|
||||
for (size_t i = 0, j = 0; i < length; i++, j+=2)
|
||||
{
|
||||
unsigned char high = (value[i] >> 4) & 0x0f;
|
||||
unsigned char low = value[i] & 0x0f;
|
||||
unsigned char high = (value[i] >> 4) & 0x0f;
|
||||
unsigned char low = value[i] & 0x0f;
|
||||
|
||||
result[j ] = hex_char(high);
|
||||
result[j + 1] = hex_char(low);
|
||||
}
|
||||
|
||||
result[2 * length] = '\0';
|
||||
result[j ] = hex_char(high);
|
||||
result[j + 1] = hex_char(low);
|
||||
}
|
||||
|
||||
result[2 * length] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -120,21 +117,46 @@ static char * compute_hash(
|
||||
}
|
||||
|
||||
char * result = NULL;
|
||||
EVP_MD_CTX * context = EVP_MD_CTX_new();
|
||||
EVP_DigestInit_ex(context, digest, NULL);
|
||||
EVP_DigestUpdate(context, password, strlen(password));
|
||||
EVP_DigestUpdate(context, salt, strlen(salt));
|
||||
EVP_DigestUpdate(context, db->pepper, strlen(db->pepper));
|
||||
|
||||
unsigned int hash_size = EVP_MD_size(digest);
|
||||
unsigned char * hash = malloc(hash_size);
|
||||
EVP_DigestFinal_ex(context, hash, &hash_size);
|
||||
EVP_MD_CTX_free(context);
|
||||
|
||||
if (NULL != hash)
|
||||
result = to_hex(hash, hash_size);
|
||||
free(hash);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool userdb_load(
|
||||
struct userdb * db,
|
||||
json_t * container)
|
||||
{
|
||||
bool result = false;
|
||||
if (NULL != container)
|
||||
{
|
||||
EVP_MD_CTX * context = EVP_MD_CTX_new();
|
||||
EVP_DigestInit_ex(context, digest, NULL);
|
||||
EVP_DigestUpdate(context, password, strlen(password));
|
||||
EVP_DigestUpdate(context, salt, strlen(salt));
|
||||
EVP_DigestUpdate(context, db->pepper, strlen(db->pepper));
|
||||
EVP_DigestFinal_ex(context, hash, &hash_size);
|
||||
EVP_MD_CTX_free(context);
|
||||
json_t * meta = json_object_get(container, "meta");
|
||||
json_t * users = json_object_get(container, "users");
|
||||
|
||||
result = to_hex(hash, hash_size);
|
||||
free(hash);
|
||||
if ((is_compatible(meta)) && (json_is_object(users))) {
|
||||
json_t * hash_algorithm = json_object_get(meta, "hash_algorithm");
|
||||
free(db->hash_algorithm);
|
||||
db->hash_algorithm = strdup(json_string_value(hash_algorithm));
|
||||
|
||||
json_decref(db->users);
|
||||
json_incref(users);
|
||||
db->users = users;
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
json_decref(container);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -144,12 +166,9 @@ struct userdb * userdb_create(
|
||||
char const * pepper)
|
||||
{
|
||||
struct userdb * db = malloc(sizeof(struct userdb));
|
||||
if (NULL != db)
|
||||
{
|
||||
db->users = json_object();
|
||||
db->pepper = strdup(pepper);
|
||||
db->hash_algorithm = strdup(USERDB_HASH_ALGORITHM);
|
||||
}
|
||||
db->users = json_object();
|
||||
db->pepper = strdup(pepper);
|
||||
db->hash_algorithm = strdup(USERDB_HASH_ALGORITHM);
|
||||
|
||||
return db;
|
||||
}
|
||||
@ -184,36 +203,23 @@ bool userdb_save(
|
||||
return (0 == result);
|
||||
}
|
||||
|
||||
|
||||
bool userdb_load(
|
||||
bool userdb_load_file(
|
||||
struct userdb * db,
|
||||
char const * filename)
|
||||
{
|
||||
bool result = false;
|
||||
json_t * container = json_load_file(filename, 0, NULL);
|
||||
if (NULL != container)
|
||||
{
|
||||
json_t * meta = json_object_get(container, "meta");
|
||||
json_t * users = json_object_get(container, "users");
|
||||
|
||||
if ((is_compatible(meta)) && (json_is_object(users))) {
|
||||
json_t * hash_algorithm = json_object_get(meta, "hash_algorithm");
|
||||
free(db->hash_algorithm);
|
||||
db->hash_algorithm = strdup(json_string_value(hash_algorithm));
|
||||
|
||||
json_decref(db->users);
|
||||
json_incref(users);
|
||||
db->users = users;
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
json_decref(container);
|
||||
}
|
||||
|
||||
return result;
|
||||
return userdb_load(db, container);
|
||||
}
|
||||
|
||||
bool userdb_load_string(
|
||||
struct userdb * db,
|
||||
char const * contents)
|
||||
{
|
||||
json_t * container = json_loads(contents, 0, NULL);
|
||||
return userdb_load(db, container);
|
||||
}
|
||||
|
||||
|
||||
void userdb_add(
|
||||
struct userdb * db,
|
||||
char const * username,
|
||||
@ -243,7 +249,7 @@ static char const * json_object_get_string(
|
||||
json_t * object,
|
||||
char const * key)
|
||||
{
|
||||
char const * result = NULL;
|
||||
char const * result = "";
|
||||
|
||||
json_t * string_holder = json_object_get(object, key);
|
||||
if (json_is_string(string_holder))
|
24
src/webfused/auth/authenticator.c
Normal file
24
src/webfused/auth/authenticator.c
Normal file
@ -0,0 +1,24 @@
|
||||
#include "webfused/auth/authenticator.h"
|
||||
|
||||
void
|
||||
wfd_authenticator_dispose(
|
||||
struct wfd_authenticator authenticator)
|
||||
{
|
||||
authenticator.vtable->dispose(authenticator.data);
|
||||
}
|
||||
|
||||
extern bool
|
||||
wfd_authenticator_authenticate(
|
||||
struct wfd_authenticator authenticator,
|
||||
struct wf_credentials * credentials)
|
||||
{
|
||||
return authenticator.vtable->authenticate(
|
||||
credentials, authenticator.data);
|
||||
}
|
||||
|
||||
char const *
|
||||
wfd_authenticator_get_type(
|
||||
struct wfd_authenticator authenticator)
|
||||
{
|
||||
return authenticator.vtable->get_type(authenticator.data);
|
||||
}
|
49
src/webfused/auth/authenticator.h
Normal file
49
src/webfused/auth/authenticator.h
Normal file
@ -0,0 +1,49 @@
|
||||
#ifndef WFD_AUTH_AUTHENTICATOR_H
|
||||
#define WFD_AUTH_AUTHENTICATOR_H
|
||||
|
||||
#include "webfuse/authenticate.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef void
|
||||
wfd_authenticator_dispose_fn(
|
||||
void * data);
|
||||
|
||||
typedef char const *
|
||||
wfd_authenticator_get_type_fn(
|
||||
void * data);
|
||||
|
||||
struct wfd_authenticator_vtable
|
||||
{
|
||||
wfd_authenticator_dispose_fn * dispose;
|
||||
wf_authenticate_fn * authenticate;
|
||||
wfd_authenticator_get_type_fn * get_type;
|
||||
};
|
||||
|
||||
struct wfd_authenticator
|
||||
{
|
||||
struct wfd_authenticator_vtable const * vtable;
|
||||
void * data;
|
||||
};
|
||||
|
||||
extern void
|
||||
wfd_authenticator_dispose(
|
||||
struct wfd_authenticator authenticator);
|
||||
|
||||
extern bool
|
||||
wfd_authenticator_authenticate(
|
||||
struct wfd_authenticator authenticator,
|
||||
struct wf_credentials * credentials);
|
||||
|
||||
extern char const *
|
||||
wfd_authenticator_get_type(
|
||||
struct wfd_authenticator authenticator);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
30
src/webfused/auth/factory.c
Normal file
30
src/webfused/auth/factory.c
Normal file
@ -0,0 +1,30 @@
|
||||
#include "webfused/auth/factory.h"
|
||||
#include "webfused/auth/file_authenticator.h"
|
||||
#include "webfused/auth/pam_authenticator.h"
|
||||
#include "webfused/config/settings.h"
|
||||
#include "webfused/log/log.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
bool
|
||||
wfd_authenticator_create(
|
||||
char const * provider,
|
||||
struct wfd_settings * settings,
|
||||
struct wfd_authenticator * authenticator)
|
||||
{
|
||||
bool result = false;
|
||||
if (0 == strcmp("file", provider))
|
||||
{
|
||||
result = wfd_file_authenticator_create(settings, authenticator);
|
||||
}
|
||||
else if (0 == strcmp("pam", provider))
|
||||
{
|
||||
result = wfd_pam_authenticator_create(settings, authenticator);
|
||||
}
|
||||
else
|
||||
{
|
||||
WFD_ERROR("failed to create authenticator: unknown type \"%s\"", provider);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
26
src/webfused/auth/factory.h
Normal file
26
src/webfused/auth/factory.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef WFD_AUTHENTICATION_FACTORY_H
|
||||
#define WFD_AUTHENTICATION_FACTORY_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct wfd_authenticator;
|
||||
struct wfd_settings;
|
||||
|
||||
extern bool
|
||||
wfd_authenticator_create(
|
||||
char const * provider,
|
||||
struct wfd_settings * settings,
|
||||
struct wfd_authenticator * authenticator);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
91
src/webfused/auth/file_authenticator.c
Normal file
91
src/webfused/auth/file_authenticator.c
Normal file
@ -0,0 +1,91 @@
|
||||
#include "webfused/auth/file_authenticator.h"
|
||||
#include "webfused/auth/authenticator.h"
|
||||
#include "webfused/config/settings.h"
|
||||
#include "userdb/userdb.h"
|
||||
#include "webfused/log/log.h"
|
||||
|
||||
#include <webfuse/credentials.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct wfd_file_authenticator
|
||||
{
|
||||
char * filename;
|
||||
};
|
||||
|
||||
static void
|
||||
wfd_file_authenticator_dispose(
|
||||
void * data)
|
||||
{
|
||||
struct wfd_file_authenticator * authenticator = data;
|
||||
|
||||
free(authenticator->filename);
|
||||
free(authenticator);
|
||||
}
|
||||
|
||||
static bool
|
||||
wfd_file_authenticator_authenticate(
|
||||
struct wf_credentials const * credentials,
|
||||
void * user_data)
|
||||
{
|
||||
bool result = false;
|
||||
struct wfd_file_authenticator * authenticator = user_data;
|
||||
|
||||
char const * username = wf_credentials_get(credentials, "username");
|
||||
char const * password = wf_credentials_get(credentials, "password");
|
||||
if ((NULL != username) && (NULL != password))
|
||||
{
|
||||
struct userdb * db = userdb_create("");
|
||||
result = userdb_load_file(db, authenticator->filename);
|
||||
if (result)
|
||||
{
|
||||
result = userdb_check(db, username, password);
|
||||
}
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
WFD_INFO("authenticate user \'%s\': %s",
|
||||
(NULL != username) ? username : "<unknown>",
|
||||
result ? "success" : "failure");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static char const *
|
||||
wfd_file_authenticator_get_type(
|
||||
void * data)
|
||||
{
|
||||
(void) data;
|
||||
return "username";
|
||||
}
|
||||
|
||||
static struct wfd_authenticator_vtable const
|
||||
wfd_file_authenticator_vtable =
|
||||
{
|
||||
.dispose = &wfd_file_authenticator_dispose,
|
||||
.authenticate = &wfd_file_authenticator_authenticate,
|
||||
.get_type = &wfd_file_authenticator_get_type
|
||||
};
|
||||
|
||||
bool
|
||||
wfd_file_authenticator_create(
|
||||
struct wfd_settings * settings,
|
||||
struct wfd_authenticator * authenticator)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
char const * filename = wfd_settings_get_string(settings, "file");
|
||||
if (NULL != filename)
|
||||
{
|
||||
struct wfd_file_authenticator * data = malloc(sizeof(struct wfd_file_authenticator));
|
||||
data->filename = strdup(filename);
|
||||
|
||||
authenticator->vtable = &wfd_file_authenticator_vtable;
|
||||
authenticator->data = data;
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
26
src/webfused/auth/file_authenticator.h
Normal file
26
src/webfused/auth/file_authenticator.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef WFD_AUTH_FILE_AUTHENTICATOR_H
|
||||
#define WFD_AUTH_FILE_AUTHENTICATOR_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct wfd_authenticator;
|
||||
struct wfd_settings;
|
||||
|
||||
extern bool
|
||||
wfd_file_authenticator_create(
|
||||
struct wfd_settings * settings,
|
||||
struct wfd_authenticator * authenticator);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
174
src/webfused/auth/pam_authenticator.c
Normal file
174
src/webfused/auth/pam_authenticator.c
Normal file
@ -0,0 +1,174 @@
|
||||
#include "webfused/auth/pam_authenticator.h"
|
||||
#include "webfused/auth/authenticator.h"
|
||||
#include "webfused/config/settings.h"
|
||||
#include "webfused/log/log.h"
|
||||
|
||||
#include <webfuse/credentials.h>
|
||||
|
||||
#include <security/pam_appl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct wfd_pam_authenticator
|
||||
{
|
||||
char * service_name;
|
||||
};
|
||||
|
||||
struct wfd_pam_credentials
|
||||
{
|
||||
char const * username;
|
||||
char const * password;
|
||||
};
|
||||
|
||||
static int
|
||||
wfd_pam_conversation(
|
||||
int count,
|
||||
struct pam_message const ** messages,
|
||||
struct pam_response * * ret_responses,
|
||||
void * user_data)
|
||||
{
|
||||
int result = PAM_SUCCESS;
|
||||
struct pam_response * responses = malloc(count * sizeof(struct pam_response));
|
||||
struct wfd_pam_credentials * creds = user_data;
|
||||
|
||||
for(int i = 0; (PAM_SUCCESS == result) && (i < count); i++)
|
||||
{
|
||||
struct pam_response * response = &responses[i];
|
||||
struct pam_message const * message = messages[i];
|
||||
|
||||
response->resp_retcode = 0;
|
||||
response->resp = NULL;
|
||||
|
||||
switch (message->msg_style)
|
||||
{
|
||||
case PAM_PROMPT_ECHO_ON:
|
||||
response->resp = strdup(creds->username);
|
||||
break;
|
||||
case PAM_PROMPT_ECHO_OFF:
|
||||
response->resp = strdup(creds->password);
|
||||
break;
|
||||
default:
|
||||
free(responses);
|
||||
result = PAM_CONV_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
if (PAM_SUCCESS == result)
|
||||
{
|
||||
*ret_responses = responses;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
wfd_pam_authenticator_dispose(
|
||||
void * data)
|
||||
{
|
||||
struct wfd_pam_authenticator * authenticator = data;
|
||||
|
||||
free(authenticator->service_name);
|
||||
free(authenticator);
|
||||
}
|
||||
|
||||
static bool
|
||||
wfd_pam_authenticator_authenticate(
|
||||
struct wf_credentials const * credentials,
|
||||
void * user_data)
|
||||
{
|
||||
bool result = false;
|
||||
struct wfd_pam_authenticator * authenticator = user_data;
|
||||
|
||||
char const * username = wf_credentials_get(credentials, "username");
|
||||
char const * password = wf_credentials_get(credentials, "password");
|
||||
if ((NULL != username) && (NULL != password))
|
||||
{
|
||||
struct wfd_pam_credentials creds =
|
||||
{
|
||||
.username = username,
|
||||
.password = password
|
||||
};
|
||||
|
||||
struct pam_conv const conversation =
|
||||
{
|
||||
.conv = &wfd_pam_conversation,
|
||||
.appdata_ptr = &creds
|
||||
};
|
||||
|
||||
pam_handle_t * handle = NULL;
|
||||
bool cleanup_handle = false;
|
||||
result = true;
|
||||
{
|
||||
int rc = pam_start(authenticator->service_name, NULL,
|
||||
&conversation, &handle);
|
||||
result = (PAM_SUCCESS == rc);
|
||||
cleanup_handle = result;
|
||||
if (!result)
|
||||
{
|
||||
WFD_ERROR("failed to start pam conversation: %s", pam_strerror(handle, rc));
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
int rc = pam_authenticate(handle, PAM_DISALLOW_NULL_AUTHTOK);
|
||||
result = (PAM_SUCCESS == rc);
|
||||
if (!result)
|
||||
{
|
||||
WFD_INFO("failed to authenticate user \'%s\' (pam_authenticate): %s",
|
||||
username, pam_strerror(handle, rc));
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
int rc = pam_acct_mgmt(handle, PAM_DISALLOW_NULL_AUTHTOK);
|
||||
result = (PAM_SUCCESS == rc);
|
||||
if (!result)
|
||||
{
|
||||
WFD_INFO("failed to authenticate user \'%s\' (pam_acct_mgmt): %s",
|
||||
username, pam_strerror(handle, rc));
|
||||
}
|
||||
}
|
||||
|
||||
if (cleanup_handle)
|
||||
{
|
||||
pam_end(handle, 0);
|
||||
}
|
||||
}
|
||||
|
||||
WFD_INFO("authenticate user \'%s\': %s",
|
||||
(NULL != username) ? username : "<unknown>",
|
||||
result ? "success" : "failure");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static char const *
|
||||
wfd_pam_authenticator_get_type(
|
||||
void * data)
|
||||
{
|
||||
(void) data;
|
||||
return "username";
|
||||
}
|
||||
|
||||
static struct wfd_authenticator_vtable const
|
||||
wfd_pam_authenticator_vtable =
|
||||
{
|
||||
.dispose = &wfd_pam_authenticator_dispose,
|
||||
.authenticate = &wfd_pam_authenticator_authenticate,
|
||||
.get_type = &wfd_pam_authenticator_get_type
|
||||
};
|
||||
|
||||
bool
|
||||
wfd_pam_authenticator_create(
|
||||
struct wfd_settings * settings,
|
||||
struct wfd_authenticator * authenticator)
|
||||
{
|
||||
struct wfd_pam_authenticator * data = malloc(sizeof(struct wfd_pam_authenticator));
|
||||
data->service_name = strdup(wfd_settings_get_string_or_default(settings, "service_name", "webfused"));
|
||||
|
||||
authenticator->vtable = &wfd_pam_authenticator_vtable;
|
||||
authenticator->data = data;
|
||||
return true;
|
||||
}
|
25
src/webfused/auth/pam_authenticator.h
Normal file
25
src/webfused/auth/pam_authenticator.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef WFD_AUTH_PAM_AUTHENTICATOR_H
|
||||
#define WFD_AUTH_PAM_AUTHENTICATOR_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct wfd_authenticator;
|
||||
struct wfd_settings;
|
||||
|
||||
extern bool
|
||||
wfd_pam_authenticator_create(
|
||||
struct wfd_settings * settings,
|
||||
struct wfd_authenticator * authenticator);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
116
src/webfused/change_user.c
Normal file
116
src/webfused/change_user.c
Normal file
@ -0,0 +1,116 @@
|
||||
#include "webfused/change_user.h"
|
||||
#include "webfused/log/log.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
static bool
|
||||
wfd_switch_group(
|
||||
char const * group_name)
|
||||
{
|
||||
struct group * group = getgrnam(group_name);
|
||||
bool result = (NULL != group);
|
||||
if (!result)
|
||||
{
|
||||
WFD_ERROR("failed to switch group: unknown group \'%s\'", group_name);
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
result = (0 != group->gr_gid);
|
||||
if (!result)
|
||||
{
|
||||
WFD_ERROR("failed to switch group: switch to root (gid 0) is not allowed");
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
result = (0 == setgid(group->gr_gid));
|
||||
if (!result)
|
||||
{
|
||||
WFD_ERROR("failed to set group id: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
result = (0 == setgroups(0, NULL));
|
||||
if (!result)
|
||||
{
|
||||
WFD_ERROR("failed to release supplemenatary groups (setgroups): %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool
|
||||
wfd_switch_user(
|
||||
char const * user_name)
|
||||
{
|
||||
struct passwd * user = getpwnam(user_name);
|
||||
bool result = (NULL != user);
|
||||
if (!result)
|
||||
{
|
||||
WFD_ERROR("failed to switch user: unknown user \'%s\'", user_name);
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
result = (0 != user->pw_uid);
|
||||
if (!result)
|
||||
{
|
||||
WFD_ERROR("failed to switch user: switch to root (uid 0) is not allowed");
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
result = (0 == setuid(user->pw_uid));
|
||||
if (!result)
|
||||
{
|
||||
WFD_ERROR("failed to switch user (setuid): %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
wfd_change_user(
|
||||
char const * user,
|
||||
char const * group)
|
||||
{
|
||||
bool result = true;
|
||||
bool const is_root = (0 == getuid());
|
||||
|
||||
if (is_root)
|
||||
{
|
||||
result = ((NULL != user) && (NULL != group));
|
||||
if (!result)
|
||||
{
|
||||
WFD_ERROR("webfuse daemon cannot be run as root: specify user and group in config");
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
result = wfd_switch_group(group);
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
result = wfd_switch_user(user);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
22
src/webfused/change_user.h
Normal file
22
src/webfused/change_user.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef WFD_CHANGE_USER_H
|
||||
#define WFD_CHANGE_USER_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
extern bool
|
||||
wfd_change_user(
|
||||
char const * user,
|
||||
char const * group);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
177
src/webfused/config/config.c
Normal file
177
src/webfused/config/config.c
Normal file
@ -0,0 +1,177 @@
|
||||
#include "webfused/config/config.h"
|
||||
#include "webfused/config/config_intern.h"
|
||||
#include "webfused/auth/factory.h"
|
||||
#include "webfused/auth/authenticator.h"
|
||||
#include "webfused/mountpoint_factory.h"
|
||||
#include "webfused/log/manager.h"
|
||||
|
||||
#include <webfuse/server_config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define WFD_CONFIG_DEFAULT_PORT (8080)
|
||||
#define WFD_CONFIG_DEFAULT_VHOSTNAME ("localhost")
|
||||
|
||||
struct wfd_config
|
||||
{
|
||||
struct wf_server_config * server;
|
||||
bool has_authenticator;
|
||||
struct wfd_authenticator authenticator;
|
||||
struct wfd_mountpoint_factory * mountpoint_factory;
|
||||
char * user;
|
||||
char * group;
|
||||
};
|
||||
|
||||
struct wfd_config *
|
||||
wfd_config_create(void)
|
||||
{
|
||||
struct wfd_config * config = malloc(sizeof(struct wfd_config));
|
||||
|
||||
config->mountpoint_factory = wfd_mountpoint_factory_create();
|
||||
config->has_authenticator = false;
|
||||
config->server = wf_server_config_create();
|
||||
wf_server_config_set_vhostname(config->server, WFD_CONFIG_DEFAULT_VHOSTNAME);
|
||||
wf_server_config_set_port(config->server, WFD_CONFIG_DEFAULT_PORT);
|
||||
wf_server_config_set_mountpoint_factory(config->server,
|
||||
wfd_mountpoint_factory_create_mountpoint,
|
||||
config->mountpoint_factory);
|
||||
config->user = NULL;
|
||||
config->group = NULL;
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
void
|
||||
wfd_config_dispose(
|
||||
struct wfd_config * config)
|
||||
{
|
||||
wf_server_config_dispose(config->server);
|
||||
if (config->has_authenticator)
|
||||
{
|
||||
wfd_authenticator_dispose(config->authenticator);
|
||||
}
|
||||
wfd_mountpoint_factory_dispose(config->mountpoint_factory);
|
||||
|
||||
free(config->user);
|
||||
free(config->group);
|
||||
free(config);
|
||||
}
|
||||
|
||||
void
|
||||
wfd_config_set_server_vhostname(
|
||||
struct wfd_config * config,
|
||||
char const * vhost_name)
|
||||
{
|
||||
wf_server_config_set_vhostname(config->server, vhost_name);
|
||||
}
|
||||
|
||||
void
|
||||
wfd_config_set_server_port(
|
||||
struct wfd_config * config,
|
||||
int port)
|
||||
{
|
||||
wf_server_config_set_port(config->server, port);
|
||||
}
|
||||
|
||||
void
|
||||
wfd_config_set_server_key(
|
||||
struct wfd_config * config,
|
||||
char const * key_path)
|
||||
{
|
||||
wf_server_config_set_keypath(config->server, key_path);
|
||||
}
|
||||
|
||||
void
|
||||
wfd_config_set_server_cert(
|
||||
struct wfd_config * config,
|
||||
char const * cert_path)
|
||||
{
|
||||
wf_server_config_set_certpath(config->server, cert_path);
|
||||
}
|
||||
|
||||
void
|
||||
wfd_config_set_server_document_root(
|
||||
struct wfd_config * config,
|
||||
char const * document_root)
|
||||
{
|
||||
wf_server_config_set_documentroot(config->server, document_root);
|
||||
}
|
||||
|
||||
bool
|
||||
wfd_config_add_auth_provider(
|
||||
struct wfd_config * config,
|
||||
char const * provider,
|
||||
struct wfd_settings * settings)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (!config->has_authenticator)
|
||||
{
|
||||
result = wfd_authenticator_create(provider, settings, &config->authenticator);
|
||||
if (result)
|
||||
{
|
||||
wf_server_config_add_authenticator(
|
||||
config->server,
|
||||
wfd_authenticator_get_type(config->authenticator),
|
||||
config->authenticator.vtable->authenticate,
|
||||
config->authenticator.data);
|
||||
|
||||
config->has_authenticator = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
wfd_config_add_filesystem(
|
||||
struct wfd_config * config,
|
||||
char const * name,
|
||||
char const * mount_point,
|
||||
struct wfd_string_list const * mount_options)
|
||||
{
|
||||
return wfd_mountpoint_factory_add_filesystem(
|
||||
config->mountpoint_factory, name, mount_point, mount_options);
|
||||
}
|
||||
|
||||
bool
|
||||
wfd_config_set_logger(
|
||||
struct wfd_config * config,
|
||||
char const * provider,
|
||||
int level,
|
||||
struct wfd_settings * settings)
|
||||
{
|
||||
return wfd_log_manager_set_logger(provider, level, settings);
|
||||
}
|
||||
|
||||
void
|
||||
wfd_config_set_user(
|
||||
struct wfd_config * config,
|
||||
char const * user,
|
||||
char const * group)
|
||||
{
|
||||
config->user = strdup(user);
|
||||
config->group = strdup(group);
|
||||
}
|
||||
|
||||
struct wf_server_config *
|
||||
wfd_config_get_server_config(
|
||||
struct wfd_config * config)
|
||||
{
|
||||
return config->server;
|
||||
}
|
||||
|
||||
char const *
|
||||
wfd_config_get_user(
|
||||
struct wfd_config * config)
|
||||
{
|
||||
return config->user;
|
||||
}
|
||||
|
||||
char const *
|
||||
wfd_config_get_group(
|
||||
struct wfd_config * config)
|
||||
{
|
||||
return config->group;
|
||||
}
|
45
src/webfused/config/config.h
Normal file
45
src/webfused/config/config.h
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef WFD_CONFIG_H
|
||||
#define WFD_CONFIG_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#else
|
||||
#include <cstddef>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define WFD_CONFIG_VERSION_MAJOR 1
|
||||
#define WFD_CONFIG_VERSION_MINOR 1
|
||||
|
||||
#define WFD_CONFIG_VERSION_STR_MAJOR "1"
|
||||
#define WFD_CONFIG_VERSION_STR_MINOR "1"
|
||||
|
||||
struct wfd_config;
|
||||
struct wf_server_config;
|
||||
|
||||
extern void
|
||||
wfd_config_dispose(
|
||||
struct wfd_config * config);
|
||||
|
||||
extern struct wf_server_config *
|
||||
wfd_config_get_server_config(
|
||||
struct wfd_config * config);
|
||||
|
||||
extern char const *
|
||||
wfd_config_get_user(
|
||||
struct wfd_config * config);
|
||||
|
||||
extern char const *
|
||||
wfd_config_get_group(
|
||||
struct wfd_config * config);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
75
src/webfused/config/config_intern.h
Normal file
75
src/webfused/config/config_intern.h
Normal file
@ -0,0 +1,75 @@
|
||||
#ifndef WFD_CONFIG_INTERN_H
|
||||
#define WFD_CONFIG_INTERN_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct wfd_settings;
|
||||
struct wfd_config;
|
||||
struct wfd_string_list;
|
||||
|
||||
extern struct wfd_config *
|
||||
wfd_config_create(void);
|
||||
|
||||
extern void
|
||||
wfd_config_set_server_vhostname(
|
||||
struct wfd_config * config,
|
||||
char const * vhost_name);
|
||||
|
||||
extern void
|
||||
wfd_config_set_server_port(
|
||||
struct wfd_config * config,
|
||||
int port);
|
||||
|
||||
extern void
|
||||
wfd_config_set_server_key(
|
||||
struct wfd_config * config,
|
||||
char const * key_path);
|
||||
|
||||
extern void
|
||||
wfd_config_set_server_cert(
|
||||
struct wfd_config * config,
|
||||
char const * cert_path);
|
||||
|
||||
extern void
|
||||
wfd_config_set_server_document_root(
|
||||
struct wfd_config * config,
|
||||
char const * document_root);
|
||||
|
||||
extern bool
|
||||
wfd_config_add_auth_provider(
|
||||
struct wfd_config * config,
|
||||
char const * provider,
|
||||
struct wfd_settings * settings);
|
||||
|
||||
extern bool
|
||||
wfd_config_add_filesystem(
|
||||
struct wfd_config * config,
|
||||
char const * name,
|
||||
char const * mount_point,
|
||||
struct wfd_string_list const * mount_options);
|
||||
|
||||
extern bool
|
||||
wfd_config_set_logger(
|
||||
struct wfd_config * config,
|
||||
char const * provider,
|
||||
int level,
|
||||
struct wfd_settings * settings);
|
||||
|
||||
extern void
|
||||
wfd_config_set_user(
|
||||
struct wfd_config * config,
|
||||
char const * user,
|
||||
char const * group);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
407
src/webfused/config/factory.c
Normal file
407
src/webfused/config/factory.c
Normal file
@ -0,0 +1,407 @@
|
||||
#include "webfused/config/factory.h"
|
||||
#include "webfused/config/config_intern.h"
|
||||
#include "webfused/config/config.h"
|
||||
#include "webfused/config/settings_intern.h"
|
||||
#include "webfused/log/log.h"
|
||||
#include "webfused/util/string_list.h"
|
||||
|
||||
#include <libconfig.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
#if ((LIBCONFIG_VER_MAJOR != 1) || (LIBCONFIG_VER_MINOR < 5))
|
||||
#error "libconfig 1.5 or higher needed"
|
||||
#endif
|
||||
|
||||
static bool
|
||||
wfd_config_check_version(
|
||||
config_t * config)
|
||||
{
|
||||
int version_major;
|
||||
int rc = config_lookup_int(config, "version.major", &version_major);
|
||||
if (CONFIG_TRUE != rc)
|
||||
{
|
||||
WFD_ERROR("failed to load config: missing version.major");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (WFD_CONFIG_VERSION_MAJOR != version_major)
|
||||
{
|
||||
WFD_ERROR("failed to load config: "
|
||||
"incompatible versions: expected %d, but war %d",
|
||||
WFD_CONFIG_VERSION_MAJOR, version_major);
|
||||
return false;
|
||||
}
|
||||
|
||||
int version_minor;
|
||||
rc = config_lookup_int(config, "version.minor", &version_minor);
|
||||
if (CONFIG_TRUE != rc)
|
||||
{
|
||||
WFD_ERROR("failed to load config: missing version.minor");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (WFD_CONFIG_VERSION_MINOR < version_minor)
|
||||
{
|
||||
WFD_WARN("newer config detected: some features might be disabled");
|
||||
}
|
||||
else if (WFD_CONFIG_VERSION_MINOR > version_minor)
|
||||
{
|
||||
WFD_INFO("old config detected: some features might use default values");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
wfd_config_read_logger(
|
||||
config_t * config,
|
||||
struct wfd_config * builder)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
bool hasLogger = (NULL != config_lookup(config, "log"));
|
||||
if (hasLogger)
|
||||
{
|
||||
char const * provider;
|
||||
int rc = config_lookup_string(config, "log.provider", &provider);
|
||||
if (CONFIG_TRUE != rc)
|
||||
{
|
||||
WFD_ERROR("failed to load config: missing log provider");
|
||||
result = false;
|
||||
}
|
||||
|
||||
char const * level_str;
|
||||
if (result)
|
||||
{
|
||||
rc = config_lookup_string(config, "log.level", &level_str);
|
||||
if (CONFIG_TRUE != rc)
|
||||
{
|
||||
WFD_ERROR("failed to load config: missing log level");
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
int level;
|
||||
if (result)
|
||||
{
|
||||
bool success = wfd_log_level_parse(level_str, &level);
|
||||
if (!success)
|
||||
{
|
||||
WFD_ERROR("failed to parse log level: unknown value \'%s\'", level_str);
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
config_setting_t * setting = config_lookup(config, "log.settings");
|
||||
struct wfd_settings settings;
|
||||
wfd_settings_init(&settings, setting);
|
||||
result = wfd_config_set_logger(builder, provider, level, &settings);
|
||||
wfd_settings_cleanup(&settings);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
wfd_config_read_server(
|
||||
config_t * config,
|
||||
struct wfd_config * builder)
|
||||
{
|
||||
char const * vhost_name;
|
||||
int rc = config_lookup_string(config, "server.vhost_name", &vhost_name);
|
||||
if (CONFIG_TRUE == rc)
|
||||
{
|
||||
wfd_config_set_server_vhostname(builder, vhost_name);
|
||||
}
|
||||
|
||||
int port;
|
||||
rc = config_lookup_int(config, "server.port", &port);
|
||||
if (CONFIG_TRUE == rc)
|
||||
{
|
||||
wfd_config_set_server_port(builder, port);
|
||||
}
|
||||
|
||||
char const * cert;
|
||||
rc = config_lookup_string(config, "server.tls.certificate", &cert);
|
||||
if (CONFIG_TRUE == rc)
|
||||
{
|
||||
wfd_config_set_server_cert(builder, cert);
|
||||
}
|
||||
|
||||
char const * key;
|
||||
rc = config_lookup_string(config, "server.tls.key", &key);
|
||||
if (CONFIG_TRUE == rc)
|
||||
{
|
||||
wfd_config_set_server_key(builder, key);
|
||||
}
|
||||
|
||||
char const * doc_root;
|
||||
rc = config_lookup_string(config, "server.document_root", &doc_root);
|
||||
if (CONFIG_TRUE == rc)
|
||||
{
|
||||
wfd_config_set_server_document_root(builder, doc_root);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
wfd_config_read_authenticator(
|
||||
config_setting_t * authenticator,
|
||||
struct wfd_config * builder)
|
||||
{
|
||||
bool result = (NULL != authenticator);
|
||||
if (!result)
|
||||
{
|
||||
WFD_ERROR("failed to load config: invalid authentication section");
|
||||
}
|
||||
|
||||
char const * provider_name = NULL;
|
||||
if (result)
|
||||
{
|
||||
int rc = config_setting_lookup_string(authenticator, "provider", &provider_name);
|
||||
if (CONFIG_TRUE != rc)
|
||||
{
|
||||
WFD_ERROR("failed to load config: missing authentication provider");
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
struct config_setting_t * settings = NULL;
|
||||
if (result)
|
||||
{
|
||||
settings = config_setting_lookup(authenticator, "settings");
|
||||
if (NULL == settings)
|
||||
{
|
||||
WFD_ERROR("failed to load config: missing authentication settings");
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
struct wfd_settings auth_settings;
|
||||
wfd_settings_init(&auth_settings, settings);
|
||||
|
||||
result = wfd_config_add_auth_provider(builder, provider_name, &auth_settings);
|
||||
wfd_settings_cleanup(&auth_settings);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool
|
||||
wfd_config_read_authentication(
|
||||
config_t * config,
|
||||
struct wfd_config * builder)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
config_setting_t * authentication = config_lookup(config, "authentication");
|
||||
if (NULL != authentication)
|
||||
{
|
||||
int length = config_setting_length(authentication);
|
||||
for (int i = 0; (result) && (i < length); i++)
|
||||
{
|
||||
config_setting_t * authenticator = config_setting_get_elem(authentication, i);
|
||||
result = wfd_config_read_authenticator(authenticator, builder);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
wfd_config_read_mountoptions(
|
||||
config_setting_t * filesystem,
|
||||
struct wfd_string_list * mount_options)
|
||||
{
|
||||
config_setting_t * list = config_setting_get_member(filesystem, "mount_options");
|
||||
if ((NULL != list) && (CONFIG_TRUE == config_setting_is_list(list)))
|
||||
{
|
||||
int length = config_setting_length(list);
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
char const * option = config_setting_get_string_elem(list, i);
|
||||
if (NULL != option)
|
||||
{
|
||||
wfd_string_list_add(mount_options, option);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
wfd_config_read_filesystems(
|
||||
config_t * config,
|
||||
struct wfd_config * builder)
|
||||
{
|
||||
bool result = true;
|
||||
config_setting_t * filesystems = config_lookup(config, "filesystems");
|
||||
if (NULL != filesystems)
|
||||
{
|
||||
int length = config_setting_length(filesystems);
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
config_setting_t * fs = config_setting_get_elem(filesystems, i);
|
||||
if (NULL == fs)
|
||||
{
|
||||
WFD_ERROR("failed to load config: invalid filesystem section");
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
||||
char const * name;
|
||||
int rc = config_setting_lookup_string(fs, "name", &name);
|
||||
if (rc != CONFIG_TRUE)
|
||||
{
|
||||
WFD_ERROR("failed to load config: missing required filesystem property \'name\'");
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
||||
char const * mount_point;
|
||||
rc = config_setting_lookup_string(fs, "mount_point", &mount_point);
|
||||
if (rc != CONFIG_TRUE)
|
||||
{
|
||||
WFD_ERROR("failed to load config: missing required filesystem property \'mount_point\'");
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
||||
struct wfd_string_list mount_options;
|
||||
wfd_string_list_init(&mount_options);
|
||||
wfd_config_read_mountoptions(fs, &mount_options);
|
||||
|
||||
result = wfd_config_add_filesystem(builder, name, mount_point, &mount_options);
|
||||
wfd_string_list_cleanup(&mount_options);
|
||||
if (!result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool
|
||||
wfd_config_read_user(
|
||||
config_t * config,
|
||||
struct wfd_config * builder)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
bool has_user = (NULL != config_lookup(config, "user"));
|
||||
if (has_user)
|
||||
{
|
||||
char const * user;
|
||||
{
|
||||
int rc = config_lookup_string(config, "user.name", &user);
|
||||
if (CONFIG_TRUE != rc)
|
||||
{
|
||||
WFD_ERROR("failed to load config: missing required user propert: \'name\'");
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
char const * group;
|
||||
if (result)
|
||||
{
|
||||
int rc = config_lookup_string(config, "user.group", &group);
|
||||
if (CONFIG_TRUE != rc)
|
||||
{
|
||||
WFD_ERROR("failed to load config: missing required user propert: \'group\'");
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
wfd_config_set_user(builder, user, group);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static struct wfd_config *
|
||||
wfd_config_load(
|
||||
config_t * config)
|
||||
{
|
||||
struct wfd_config * result = wfd_config_create();
|
||||
|
||||
bool success = wfd_config_check_version(config)
|
||||
&& wfd_config_read_logger(config, result)
|
||||
&& wfd_config_read_authentication(config, result)
|
||||
&& wfd_config_read_filesystems(config, result)
|
||||
&& wfd_config_read_user(config, result)
|
||||
;
|
||||
|
||||
if (success)
|
||||
{
|
||||
wfd_config_read_server(config, result);
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
wfd_config_dispose(result);
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct wfd_config *
|
||||
wfd_config_load_file(
|
||||
char const * filename)
|
||||
{
|
||||
struct wfd_config * result = NULL;
|
||||
|
||||
config_t config;
|
||||
config_init(&config);
|
||||
int rc = config_read_file(&config, filename);
|
||||
if (CONFIG_TRUE == rc)
|
||||
{
|
||||
result = wfd_config_load(&config);
|
||||
}
|
||||
else
|
||||
{
|
||||
WFD_ERROR("failed to load config: %s: %d: %s",
|
||||
config_error_file(&config),
|
||||
config_error_line(&config),
|
||||
config_error_text(&config));
|
||||
}
|
||||
config_destroy(&config);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct wfd_config *
|
||||
wfd_config_load_string(
|
||||
char const * contents)
|
||||
{
|
||||
struct wfd_config * result = NULL;
|
||||
|
||||
config_t config;
|
||||
config_init(&config);
|
||||
int rc = config_read_string(&config, contents);
|
||||
if (CONFIG_TRUE == rc)
|
||||
{
|
||||
result = wfd_config_load(&config);
|
||||
}
|
||||
else
|
||||
{
|
||||
WFD_ERROR("failed to load config: %d: %s",
|
||||
config_error_line(&config),
|
||||
config_error_text(&config));
|
||||
}
|
||||
config_destroy(&config);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
23
src/webfused/config/factory.h
Normal file
23
src/webfused/config/factory.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef WFD_CONFIG_FACTORY_H
|
||||
#define WFD_CONFIG_FACTORY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct wfd_config;
|
||||
|
||||
extern struct wfd_config *
|
||||
wfd_config_load_file(
|
||||
char const * filename);
|
||||
|
||||
extern struct wfd_config *
|
||||
wfd_config_load_string(
|
||||
char const * contents);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
60
src/webfused/config/settings.c
Normal file
60
src/webfused/config/settings.c
Normal file
@ -0,0 +1,60 @@
|
||||
#include "webfused/config/settings.h"
|
||||
#include "webfused/config/settings_intern.h"
|
||||
|
||||
#include <libconfig.h>
|
||||
#include <stddef.h>
|
||||
|
||||
void
|
||||
wfd_settings_init(
|
||||
struct wfd_settings * settings,
|
||||
struct config_setting_t * setting)
|
||||
{
|
||||
settings->setting = setting;
|
||||
}
|
||||
|
||||
void
|
||||
wfd_settings_cleanup(
|
||||
struct wfd_settings * settings)
|
||||
{
|
||||
settings->setting = NULL;
|
||||
}
|
||||
|
||||
char const *
|
||||
wfd_settings_get_string(
|
||||
struct wfd_settings * settings,
|
||||
char const * key)
|
||||
{
|
||||
if (NULL == settings) {return NULL; }
|
||||
|
||||
char const * result;
|
||||
int rc = config_setting_lookup_string(settings->setting, key, &result);
|
||||
|
||||
return (CONFIG_TRUE == rc) ? result : NULL;
|
||||
}
|
||||
|
||||
char const *
|
||||
wfd_settings_get_string_or_default(
|
||||
struct wfd_settings * settings,
|
||||
char const * key,
|
||||
char const * default_value)
|
||||
{
|
||||
if (NULL == settings) {return default_value; }
|
||||
|
||||
char const * result;
|
||||
int rc = config_setting_lookup_string(settings->setting, key, &result);
|
||||
|
||||
return (CONFIG_TRUE == rc) ? result : default_value;
|
||||
}
|
||||
|
||||
bool
|
||||
wfd_settings_get_bool(
|
||||
struct wfd_settings * settings,
|
||||
char const * key)
|
||||
{
|
||||
if (NULL == settings) {return false; }
|
||||
|
||||
int result;
|
||||
int rc = config_setting_lookup_bool(settings->setting, key, &result);
|
||||
|
||||
return ((CONFIG_TRUE == rc) && (CONFIG_TRUE == result));
|
||||
}
|
37
src/webfused/config/settings.h
Normal file
37
src/webfused/config/settings.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef WFD_CONFIG_SETTINGS_H
|
||||
#define WFD_CONFIG_SETTINGS_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct wfd_settings;
|
||||
|
||||
|
||||
extern char const *
|
||||
wfd_settings_get_string(
|
||||
struct wfd_settings * settings,
|
||||
char const * key);
|
||||
|
||||
extern char const *
|
||||
wfd_settings_get_string_or_default(
|
||||
struct wfd_settings * settings,
|
||||
char const * key,
|
||||
char const * default_value);
|
||||
|
||||
extern bool
|
||||
wfd_settings_get_bool(
|
||||
struct wfd_settings * settings,
|
||||
char const * key);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
30
src/webfused/config/settings_intern.h
Normal file
30
src/webfused/config/settings_intern.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef WFD_CONFIG_SETTINGS_INTERN_H
|
||||
#define WFD_CONFIG_SETTINGS_INTERN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct config_setting_t;
|
||||
|
||||
struct wfd_settings
|
||||
{
|
||||
struct config_setting_t * setting;
|
||||
};
|
||||
|
||||
|
||||
extern void
|
||||
wfd_settings_init(
|
||||
struct wfd_settings * settings,
|
||||
struct config_setting_t * setting);
|
||||
|
||||
extern void
|
||||
wfd_settings_cleanup(
|
||||
struct wfd_settings * settings);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
163
src/webfused/daemon.c
Normal file
163
src/webfused/daemon.c
Normal file
@ -0,0 +1,163 @@
|
||||
#include "webfused/daemon.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <webfuse/webfuse.h>
|
||||
#include "webfused/config/config.h"
|
||||
#include "webfused/config/factory.h"
|
||||
#include "webfused/log/log.h"
|
||||
#include "webfused/log/logger.h"
|
||||
#include "webfused/log/stderr_logger.h"
|
||||
#include "webfused/change_user.h"
|
||||
|
||||
#define WFD_SERVICE_TIMEOUT (1 * 1000)
|
||||
#define WFD_DEFAULT_CONFIG_FILE ("/etc/webfused.conf")
|
||||
|
||||
struct args
|
||||
{
|
||||
char * config_file;
|
||||
bool show_help;
|
||||
};
|
||||
|
||||
static bool shutdown_requested = false;
|
||||
|
||||
static void show_help(void)
|
||||
{
|
||||
printf(
|
||||
"webfused, Copyright (c) 2019-2020, webfused authors <https://github.com/falk-werner/webfused>\n"
|
||||
"Websocket file system daemon\n"
|
||||
"\n"
|
||||
"Usage: webfused [-f <config file>] | -h\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
"\t-f, --config-file Path to config file (default: /etc/webfuse.conf)\n"
|
||||
"\t-h, --help Print this message and terminate\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
static int parse_arguments(int argc, char * argv[], struct args * args)
|
||||
{
|
||||
static struct option const options[] =
|
||||
{
|
||||
{"config-file", required_argument, NULL, 'f'},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
args->config_file = strdup(WFD_DEFAULT_CONFIG_FILE);
|
||||
args->show_help = false;
|
||||
|
||||
bool result = EXIT_SUCCESS;
|
||||
bool finished = false;
|
||||
optind = 0;
|
||||
while ((!finished) && (EXIT_SUCCESS == result))
|
||||
{
|
||||
int option_index = 0;
|
||||
int const c = getopt_long(argc, argv, "f:h", options, &option_index);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case -1:
|
||||
finished = true;
|
||||
break;
|
||||
case 'h':
|
||||
args->show_help = true;
|
||||
finished = true;
|
||||
break;
|
||||
case 'f':
|
||||
free(args->config_file);
|
||||
args->config_file = strdup(optarg);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "error: unknown argument\n");
|
||||
result = EXIT_FAILURE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (EXIT_SUCCESS != result)
|
||||
{
|
||||
args->show_help = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void on_interrupt(int signal_id)
|
||||
{
|
||||
(void) signal_id;
|
||||
|
||||
shutdown_requested = true;
|
||||
}
|
||||
|
||||
int wfd_daemon_run(int argc, char * argv[])
|
||||
{
|
||||
wfd_stderr_logger_init(WFD_LOGLEVEL_ALL, NULL);
|
||||
|
||||
struct args args;
|
||||
int result = parse_arguments(argc, argv, &args);
|
||||
|
||||
if (!args.show_help)
|
||||
{
|
||||
signal(SIGINT, on_interrupt);
|
||||
|
||||
struct wfd_config * config = wfd_config_load_file(args.config_file);
|
||||
bool success = (NULL != config);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
fprintf(stderr, "fatal: failed to load server config\n");
|
||||
result = EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
success = wfd_change_user(
|
||||
wfd_config_get_user(config),
|
||||
wfd_config_get_group(config));
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
struct wf_server_config * server_config = wfd_config_get_server_config(config);
|
||||
struct wf_server * server = wf_server_create(server_config);
|
||||
if (NULL != server)
|
||||
{
|
||||
while (!shutdown_requested)
|
||||
{
|
||||
wf_server_service(server);
|
||||
}
|
||||
|
||||
wf_server_dispose(server);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "fatal: unable start server\n");
|
||||
result = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != config)
|
||||
{
|
||||
wfd_config_dispose(config);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
show_help();
|
||||
}
|
||||
|
||||
wfd_logger_close();
|
||||
free(args.config_file);
|
||||
shutdown_requested = false;
|
||||
return result;
|
||||
}
|
||||
|
15
src/webfused/daemon.h
Normal file
15
src/webfused/daemon.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef WFD_DAEMON_H
|
||||
#define WFD_DAEMON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
extern int wfd_daemon_run(int argc, char * argv[]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
62
src/webfused/log/log.c
Normal file
62
src/webfused/log/log.c
Normal file
@ -0,0 +1,62 @@
|
||||
#include "webfused/log/log.h"
|
||||
#include <strings.h>
|
||||
|
||||
char const *
|
||||
wfd_log_level_tostring(int level)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case WFD_LOGLEVEL_NONE: return "none";
|
||||
case WFD_LOGLEVEL_FATAL: return "fatal";
|
||||
case WFD_LOGLEVEL_ERROR: return "error";
|
||||
case WFD_LOGLEVEL_WARN: return "warn";
|
||||
case WFD_LOGLEVEL_INFO: return "info";
|
||||
case WFD_LOGLEVEL_DEBUG: return "debug";
|
||||
case WFD_LOGLEVEL_ALL: return "all";
|
||||
default: return "<unknown>";
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
wfd_log_level_parse(
|
||||
char const * level,
|
||||
int * result)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
if (0 == strcasecmp("all", level))
|
||||
{
|
||||
*result = WFD_LOGLEVEL_ALL;
|
||||
}
|
||||
else if (0 == strcasecmp("none", level))
|
||||
{
|
||||
*result = WFD_LOGLEVEL_NONE;
|
||||
}
|
||||
else if (0 == strcasecmp("fatal", level))
|
||||
{
|
||||
*result = WFD_LOGLEVEL_FATAL;
|
||||
}
|
||||
else if (0 == strcasecmp("error", level))
|
||||
{
|
||||
*result = WFD_LOGLEVEL_ERROR;
|
||||
}
|
||||
else if ((0 == strcasecmp("warn", level)) ||
|
||||
(0 == strcasecmp("warning", level)))
|
||||
{
|
||||
*result = WFD_LOGLEVEL_WARN;
|
||||
}
|
||||
else if (0 == strcasecmp("info", level))
|
||||
{
|
||||
*result = WFD_LOGLEVEL_INFO;
|
||||
}
|
||||
else if (0 == strcasecmp("debug", level))
|
||||
{
|
||||
*result = WFD_LOGLEVEL_DEBUG;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
68
src/webfused/log/log.h
Normal file
68
src/webfused/log/log.h
Normal file
@ -0,0 +1,68 @@
|
||||
#ifndef WFD_LOG_H
|
||||
#define WFD_LOG_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <cstdarg>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#ifndef WFD_LOGLEVEL
|
||||
#define WFD_LOGLEVEL WFD_LOGLEVEL_ALL
|
||||
#endif
|
||||
|
||||
#define WFD_LOGLEVEL_NONE -1
|
||||
#define WFD_LOGLEVEL_FATAL 1
|
||||
#define WFD_LOGLEVEL_ERROR 3
|
||||
#define WFD_LOGLEVEL_WARN 4
|
||||
#define WFD_LOGLEVEL_INFO 5
|
||||
#define WFD_LOGLEVEL_DEBUG 7
|
||||
#define WFD_LOGLEVEL_ALL 8
|
||||
|
||||
#define WFD_FATAL(...) \
|
||||
WFD_LOG(WFD_LOGLEVEL_FATAL, __VA_ARGS__)
|
||||
|
||||
#define WFD_ERROR(...) \
|
||||
WFD_LOG(WFD_LOGLEVEL_ERROR, __VA_ARGS__)
|
||||
|
||||
#define WFD_WARN(...) \
|
||||
WFD_LOG(WFD_LOGLEVEL_WARN, __VA_ARGS__)
|
||||
|
||||
#define WFD_INFO(...) \
|
||||
WFD_LOG(WFD_LOGLEVEL_INFO, __VA_ARGS__)
|
||||
|
||||
#define WFD_DEBUG(...) \
|
||||
WFD_LOG(WFD_LOGLEVEL_DEBUG, __VA_ARGS__)
|
||||
|
||||
#define WFD_LOG(level, ...) \
|
||||
do { \
|
||||
if (WFD_LOGLEVEL >= (level)) { \
|
||||
wfd_log((level), __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
extern void
|
||||
wfd_log(
|
||||
int level,
|
||||
char const * format,
|
||||
...);
|
||||
|
||||
extern char const *
|
||||
wfd_log_level_tostring(int level);
|
||||
|
||||
extern bool
|
||||
wfd_log_level_parse(
|
||||
char const * level,
|
||||
int * result);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
86
src/webfused/log/logger.c
Normal file
86
src/webfused/log/logger.c
Normal file
@ -0,0 +1,86 @@
|
||||
#include "webfused/log/logger.h"
|
||||
#include "webfused/log/log.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
struct wfd_logger
|
||||
{
|
||||
int level;
|
||||
wfd_logger_log_fn * log;
|
||||
wfd_logger_onclose_fn * onclose;
|
||||
void * user_data;
|
||||
};
|
||||
|
||||
static void wfd_logger_default_log(
|
||||
void * user_data,
|
||||
int level,
|
||||
char const * format,
|
||||
va_list args);
|
||||
|
||||
static struct wfd_logger g_wfd_logger =
|
||||
{
|
||||
.level = WFD_LOGLEVEL_ALL,
|
||||
.log = &wfd_logger_default_log,
|
||||
.onclose = NULL,
|
||||
.user_data = NULL
|
||||
};
|
||||
|
||||
void
|
||||
wfd_logger_init(
|
||||
int level,
|
||||
wfd_logger_log_fn * log,
|
||||
wfd_logger_onclose_fn * onclose,
|
||||
void * user_data)
|
||||
{
|
||||
wfd_logger_close();
|
||||
|
||||
g_wfd_logger.level = level;
|
||||
g_wfd_logger.log = log;
|
||||
g_wfd_logger.onclose = onclose;
|
||||
g_wfd_logger.user_data = user_data;
|
||||
}
|
||||
|
||||
void
|
||||
wfd_logger_close(void)
|
||||
{
|
||||
if (NULL != g_wfd_logger.onclose)
|
||||
{
|
||||
g_wfd_logger.onclose(g_wfd_logger.user_data);
|
||||
}
|
||||
|
||||
g_wfd_logger.level = WFD_LOGLEVEL_ALL;
|
||||
g_wfd_logger.log = &wfd_logger_default_log;
|
||||
g_wfd_logger.onclose = NULL;
|
||||
g_wfd_logger.user_data = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
wfd_log(
|
||||
int level,
|
||||
char const * format,
|
||||
...)
|
||||
{
|
||||
if (g_wfd_logger.level >= level)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
g_wfd_logger.log(
|
||||
g_wfd_logger.user_data,
|
||||
level,
|
||||
format,
|
||||
args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
static void wfd_logger_default_log(
|
||||
void * user_data,
|
||||
int level,
|
||||
char const * format,
|
||||
va_list args)
|
||||
{
|
||||
(void) user_data;
|
||||
(void) level;
|
||||
(void) format;
|
||||
(void) args;
|
||||
}
|
40
src/webfused/log/logger.h
Normal file
40
src/webfused/log/logger.h
Normal file
@ -0,0 +1,40 @@
|
||||
#ifndef WFD_LOGGER_H
|
||||
#define WFD_LOGGER_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <cstdarg>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef void
|
||||
wfd_logger_log_fn(
|
||||
void * user_data,
|
||||
int level,
|
||||
char const * format,
|
||||
va_list args);
|
||||
|
||||
typedef void
|
||||
wfd_logger_onclose_fn(
|
||||
void * user_data);
|
||||
|
||||
extern void
|
||||
wfd_logger_init(
|
||||
int level,
|
||||
wfd_logger_log_fn * log,
|
||||
wfd_logger_onclose_fn * onclose,
|
||||
void * user_data);
|
||||
|
||||
extern void
|
||||
wfd_logger_close(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
30
src/webfused/log/manager.c
Normal file
30
src/webfused/log/manager.c
Normal file
@ -0,0 +1,30 @@
|
||||
#include "webfused/log/manager.h"
|
||||
#include "webfused/log/log.h"
|
||||
#include "webfused/log/stderr_logger.h"
|
||||
#include "webfused/log/syslog_logger.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
bool
|
||||
wfd_log_manager_set_logger(
|
||||
char const * provider,
|
||||
int level,
|
||||
struct wfd_settings * settings)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (0 == strcmp("syslog", provider))
|
||||
{
|
||||
result = wfd_syslog_logger_init(level, settings);
|
||||
}
|
||||
else if (0 == strcmp("stderr", provider))
|
||||
{
|
||||
result = wfd_stderr_logger_init(level, settings);
|
||||
}
|
||||
else
|
||||
{
|
||||
WFD_ERROR("failed to init log: unknown provider \'%s\'", provider);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
25
src/webfused/log/manager.h
Normal file
25
src/webfused/log/manager.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef WFD_LOG_MANAGER_H
|
||||
#define WFD_LOG_MANAGER_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct wfd_settings;
|
||||
|
||||
extern bool
|
||||
wfd_log_manager_set_logger(
|
||||
char const * provider,
|
||||
int level,
|
||||
struct wfd_settings * settings);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
29
src/webfused/log/stderr_logger.c
Normal file
29
src/webfused/log/stderr_logger.c
Normal file
@ -0,0 +1,29 @@
|
||||
#include "webfused/log/stderr_logger.h"
|
||||
#include "webfused/log/logger.h"
|
||||
#include "webfused/log/log.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static void
|
||||
wfd_stderr_logger_log(
|
||||
void * user_data,
|
||||
int level,
|
||||
char const * format,
|
||||
va_list args)
|
||||
{
|
||||
fprintf(stderr, "%s: ", wfd_log_level_tostring(level));
|
||||
vfprintf(stderr, format, args);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
bool
|
||||
wfd_stderr_logger_init(
|
||||
int level,
|
||||
struct wfd_settings * settings)
|
||||
{
|
||||
(void) settings;
|
||||
|
||||
wfd_logger_init(level, &wfd_stderr_logger_log, NULL, NULL);
|
||||
return true;
|
||||
}
|
24
src/webfused/log/stderr_logger.h
Normal file
24
src/webfused/log/stderr_logger.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef WFD_LOG_STDERR_LOGGER_H
|
||||
#define WFD_LOG_STDERR_LOGGER_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct wfd_settings;
|
||||
|
||||
extern bool
|
||||
wfd_stderr_logger_init(
|
||||
int level,
|
||||
struct wfd_settings * settings);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
126
src/webfused/log/syslog_logger.c
Normal file
126
src/webfused/log/syslog_logger.c
Normal file
@ -0,0 +1,126 @@
|
||||
#include "webfused/log/syslog_logger.h"
|
||||
#include "webfused/log/logger.h"
|
||||
#include "webfused/log/log.h"
|
||||
#include "webfused/config/settings.h"
|
||||
|
||||
#include <syslog.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
|
||||
static int
|
||||
wfd_syslog_logger_to_priority(
|
||||
int level)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case WFD_LOGLEVEL_FATAL: return LOG_CRIT;
|
||||
case WFD_LOGLEVEL_ERROR: return LOG_ERR;
|
||||
case WFD_LOGLEVEL_WARN: return LOG_WARNING;
|
||||
case WFD_LOGLEVEL_INFO: return LOG_INFO;
|
||||
case WFD_LOGLEVEL_DEBUG: return LOG_DEBUG;
|
||||
default: return LOG_NOTICE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wfd_syslog_logger_log(
|
||||
void * user_data,
|
||||
int level,
|
||||
char const * format,
|
||||
va_list args)
|
||||
{
|
||||
(void) user_data;
|
||||
|
||||
int prio = wfd_syslog_logger_to_priority(level);
|
||||
vsyslog(prio, format, args);
|
||||
}
|
||||
|
||||
static void
|
||||
wfd_syslog_logger_close(
|
||||
void * user_data)
|
||||
{
|
||||
closelog();
|
||||
free(user_data);
|
||||
}
|
||||
|
||||
struct wfd_syslog_facility
|
||||
{
|
||||
char const * name;
|
||||
int value;
|
||||
};
|
||||
|
||||
static bool
|
||||
wfd_syslog_logger_parse_facility(
|
||||
char const * facility,
|
||||
int * result)
|
||||
{
|
||||
static struct wfd_syslog_facility const facilities[] =
|
||||
{
|
||||
{"auth", LOG_AUTH},
|
||||
{"authpriv", LOG_AUTHPRIV},
|
||||
{"cron", LOG_CRON},
|
||||
{"daemon", LOG_DAEMON},
|
||||
{"fpt", LOG_FTP},
|
||||
{"kern", LOG_KERN},
|
||||
{"local0", LOG_LOCAL0},
|
||||
{"local1", LOG_LOCAL1},
|
||||
{"local2", LOG_LOCAL2},
|
||||
{"local3", LOG_LOCAL3},
|
||||
{"local4", LOG_LOCAL4},
|
||||
{"local5", LOG_LOCAL5},
|
||||
{"local6", LOG_LOCAL6},
|
||||
{"local7", LOG_LOCAL7},
|
||||
{"lpr", LOG_LPR},
|
||||
{"mail", LOG_MAIL},
|
||||
{"news", LOG_NEWS},
|
||||
{"syslog", LOG_SYSLOG},
|
||||
{"user", LOG_USER},
|
||||
{"uucp", LOG_UUCP}
|
||||
};
|
||||
static size_t const facilites_count = sizeof(facilities) / sizeof(facilities[0]);
|
||||
|
||||
for (size_t i = 0; i < facilites_count; i++)
|
||||
{
|
||||
if (0 == strcasecmp(facility, facilities[i].name))
|
||||
{
|
||||
*result = facilities[i].value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
wfd_syslog_logger_init(
|
||||
int level,
|
||||
struct wfd_settings * settings)
|
||||
{
|
||||
char * ident = strdup(wfd_settings_get_string_or_default(settings, "ident", "webfused"));
|
||||
char const * facility_str = wfd_settings_get_string_or_default(settings, "facility", "daemon");
|
||||
bool log_pid = wfd_settings_get_bool(settings, "log_pid");
|
||||
|
||||
int facility;
|
||||
bool result = wfd_syslog_logger_parse_facility(facility_str, &facility);
|
||||
if (result)
|
||||
{
|
||||
int options = (log_pid) ? LOG_PID : 0;
|
||||
wfd_logger_init(level,
|
||||
&wfd_syslog_logger_log,
|
||||
&wfd_syslog_logger_close,
|
||||
ident);
|
||||
|
||||
openlog(ident, options, facility);
|
||||
}
|
||||
else
|
||||
{
|
||||
free(ident);
|
||||
WFD_ERROR("failed to init syslog logger: invalid log facility: \'%s\'", facility_str);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
24
src/webfused/log/syslog_logger.h
Normal file
24
src/webfused/log/syslog_logger.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef WFD_LOG_SYSLOG_LOGGER_H
|
||||
#define WFD_LOG_SYSLOG_LOGGER_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct wfd_settings;
|
||||
|
||||
extern bool
|
||||
wfd_syslog_logger_init(
|
||||
int level,
|
||||
struct wfd_settings * settings);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
6
src/webfused/main.c
Normal file
6
src/webfused/main.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include "webfused/daemon.h"
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
return wfd_daemon_run(argc, argv);
|
||||
}
|
155
src/webfused/mountpoint_factory.c
Normal file
155
src/webfused/mountpoint_factory.c
Normal file
@ -0,0 +1,155 @@
|
||||
#include "webfused/mountpoint_factory.h"
|
||||
#include "webfused/util/string_list.h"
|
||||
#include "webfused/log/log.h"
|
||||
|
||||
#include <webfuse/mountpoint.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define WFD_FILESYSTEM_DEFAULT_CAPACITY 16
|
||||
|
||||
struct wfd_filesystem
|
||||
{
|
||||
char * name;
|
||||
char * mount_point;
|
||||
struct wfd_string_list mount_options;
|
||||
bool in_use;
|
||||
};
|
||||
|
||||
struct wfd_mountpoint_factory
|
||||
{
|
||||
struct wfd_filesystem * filesystems;
|
||||
size_t capacity;
|
||||
size_t count;
|
||||
};
|
||||
|
||||
static struct wfd_filesystem *
|
||||
wfd_mountpoint_factory_find(
|
||||
struct wfd_mountpoint_factory * factory,
|
||||
char const * name)
|
||||
{
|
||||
for (size_t i = 0; i < factory->count; i++)
|
||||
{
|
||||
struct wfd_filesystem * filesystem = &(factory->filesystems[i]);
|
||||
if (0 == strcmp(name, filesystem->name))
|
||||
{
|
||||
return filesystem;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
wfd_mountpoint_factory_release_mountpoint(
|
||||
void * user_data)
|
||||
{
|
||||
bool * in_use = user_data;
|
||||
*in_use = false;
|
||||
}
|
||||
|
||||
struct wfd_mountpoint_factory *
|
||||
wfd_mountpoint_factory_create(void)
|
||||
{
|
||||
struct wfd_mountpoint_factory * factory = malloc(sizeof(struct wfd_mountpoint_factory));
|
||||
factory->filesystems = malloc(sizeof(struct wfd_filesystem) * WFD_FILESYSTEM_DEFAULT_CAPACITY);
|
||||
factory->count = 0;
|
||||
factory->capacity = WFD_FILESYSTEM_DEFAULT_CAPACITY;
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
void
|
||||
wfd_mountpoint_factory_dispose(
|
||||
struct wfd_mountpoint_factory * factory)
|
||||
{
|
||||
for(size_t i = 0; i < factory->count; i++)
|
||||
{
|
||||
struct wfd_filesystem * filesystem = &(factory->filesystems[i]);
|
||||
free(filesystem->name);
|
||||
free(filesystem->mount_point);
|
||||
wfd_string_list_cleanup(&filesystem->mount_options);
|
||||
}
|
||||
|
||||
free(factory->filesystems);
|
||||
free(factory);
|
||||
}
|
||||
|
||||
bool
|
||||
wfd_mountpoint_factory_add_filesystem(
|
||||
struct wfd_mountpoint_factory * factory,
|
||||
char const * name,
|
||||
char const * mount_point,
|
||||
struct wfd_string_list const * mount_options)
|
||||
{
|
||||
bool result = (NULL == wfd_mountpoint_factory_find(factory, name));
|
||||
if (!result)
|
||||
{
|
||||
WFD_ERROR("mount_point already defined: \'%s\'", mount_point);
|
||||
}
|
||||
|
||||
char * path = NULL;
|
||||
if (result)
|
||||
{
|
||||
mkdir(mount_point, 0755);
|
||||
path = realpath(mount_point, NULL);
|
||||
if (NULL == path)
|
||||
{
|
||||
WFD_ERROR("invalid mount_point: \'%s\'", mount_point);
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
if (factory->count >= factory->capacity)
|
||||
{
|
||||
factory->capacity *= 2;
|
||||
factory->filesystems = realloc(factory->filesystems,
|
||||
sizeof(struct wfd_filesystem) * factory->capacity);
|
||||
}
|
||||
|
||||
struct wfd_filesystem * actual = &(factory->filesystems[factory->count]);
|
||||
actual->name = strdup(name);
|
||||
actual->mount_point = path;
|
||||
wfd_string_list_init_copy(&actual->mount_options, mount_options);
|
||||
actual->in_use = false;
|
||||
factory->count++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
extern struct wf_mountpoint *
|
||||
wfd_mountpoint_factory_create_mountpoint(
|
||||
char const * filesystem,
|
||||
void * user_data)
|
||||
{
|
||||
struct wfd_mountpoint_factory * factory = user_data;
|
||||
struct wfd_filesystem * fs = wfd_mountpoint_factory_find(factory, filesystem);
|
||||
if (NULL == fs)
|
||||
{
|
||||
WFD_INFO("failed to create mountpoint: filesystem \'%s\' not found", filesystem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fs->in_use)
|
||||
{
|
||||
WFD_INFO("failed to create mountpoint: filesystem \'%s\' already in use", filesystem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fs->in_use = true;
|
||||
struct wf_mountpoint * result = wf_mountpoint_create(fs->mount_point);
|
||||
wf_mountpoint_set_userdata(result,
|
||||
&fs->in_use, &wfd_mountpoint_factory_release_mountpoint);
|
||||
for (size_t i = 0; i < fs->mount_options.size; i++)
|
||||
{
|
||||
wf_mountpoint_add_mountoption(result, fs->mount_options.items[i]);
|
||||
}
|
||||
|
||||
WFD_INFO("created mountpoint \'%s\' at path \'%s\'", filesystem, fs->mount_point);
|
||||
return result;
|
||||
}
|
41
src/webfused/mountpoint_factory.h
Normal file
41
src/webfused/mountpoint_factory.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef WFD_MOUNTPOINT_FACTORY_H
|
||||
#define WFD_MOUNTPOINT_FACTORY_H
|
||||
|
||||
#include "webfuse/mountpoint_factory.h"
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct wfd_mountpoint_factory;
|
||||
struct wfd_string_list;
|
||||
|
||||
extern struct wfd_mountpoint_factory *
|
||||
wfd_mountpoint_factory_create(void);
|
||||
|
||||
extern void
|
||||
wfd_mountpoint_factory_dispose(
|
||||
struct wfd_mountpoint_factory * factory);
|
||||
|
||||
extern bool
|
||||
wfd_mountpoint_factory_add_filesystem(
|
||||
struct wfd_mountpoint_factory * factory,
|
||||
char const * name,
|
||||
char const * mount_point,
|
||||
struct wfd_string_list const * mount_options);
|
||||
|
||||
extern struct wf_mountpoint *
|
||||
wfd_mountpoint_factory_create_mountpoint(
|
||||
char const * filesystem,
|
||||
void * user_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
62
src/webfused/util/string_list.c
Normal file
62
src/webfused/util/string_list.c
Normal file
@ -0,0 +1,62 @@
|
||||
#include "webfused/util/string_list.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define WFD_STRING_LIST_INITIAL_CAPACITY 8
|
||||
|
||||
void
|
||||
wfd_string_list_init(
|
||||
struct wfd_string_list * list)
|
||||
{
|
||||
list->size = 0;
|
||||
list->capacity = WFD_STRING_LIST_INITIAL_CAPACITY;
|
||||
list->items = malloc(sizeof(char *) * list->capacity);
|
||||
}
|
||||
|
||||
void
|
||||
wfd_string_list_init_copy(
|
||||
struct wfd_string_list * list,
|
||||
struct wfd_string_list const * other)
|
||||
{
|
||||
if (0 < other->size)
|
||||
{
|
||||
list->size = other->size;
|
||||
list->capacity = other->capacity;
|
||||
list->items = malloc(sizeof(char *) * list->capacity);
|
||||
|
||||
for(size_t i = 0; i < other->size; i++)
|
||||
{
|
||||
list->items[i] = strdup(other->items[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wfd_string_list_init(list);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
wfd_string_list_cleanup(
|
||||
struct wfd_string_list * list)
|
||||
{
|
||||
for (size_t i = 0; i < list->size; i++)
|
||||
{
|
||||
free(list->items[i]);
|
||||
}
|
||||
free(list->items);
|
||||
}
|
||||
|
||||
void
|
||||
wfd_string_list_add(
|
||||
struct wfd_string_list * list,
|
||||
char const * item)
|
||||
{
|
||||
if (list->size >= list->capacity)
|
||||
{
|
||||
list->capacity *= 2;
|
||||
list->items = realloc(list->items, sizeof(char *) * list->capacity);
|
||||
}
|
||||
|
||||
list->items[list->size] = strdup(item);
|
||||
list->size++;
|
||||
}
|
44
src/webfused/util/string_list.h
Normal file
44
src/webfused/util/string_list.h
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef WFD_UTIL_STRING_LIST_H
|
||||
#define WFD_UTIL_STRING_LIST_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stddef.h>
|
||||
#else
|
||||
#include <cstddef>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct wfd_string_list
|
||||
{
|
||||
size_t size;
|
||||
size_t capacity;
|
||||
char * * items;
|
||||
};
|
||||
|
||||
extern void
|
||||
wfd_string_list_init(
|
||||
struct wfd_string_list * list);
|
||||
|
||||
extern void
|
||||
wfd_string_list_init_copy(
|
||||
struct wfd_string_list * list,
|
||||
struct wfd_string_list const * other);
|
||||
|
||||
extern void
|
||||
wfd_string_list_cleanup(
|
||||
struct wfd_string_list * list);
|
||||
|
||||
extern void
|
||||
wfd_string_list_add(
|
||||
struct wfd_string_list * list,
|
||||
char const * item);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
20
test/auth/factory.cc
Normal file
20
test/auth/factory.cc
Normal file
@ -0,0 +1,20 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "webfused/auth/factory.h"
|
||||
#include "webfused/auth/authenticator.h"
|
||||
#include "webfused/log/log.h"
|
||||
#include "mock/logger.hpp"
|
||||
|
||||
using ::testing::_;
|
||||
using ::webfused_test::MockLogger;
|
||||
|
||||
|
||||
TEST(auth_factory, fail_unknown_provider)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool result = wfd_authenticator_create("unknown", NULL, &authenticator);
|
||||
ASSERT_FALSE(result);
|
||||
}
|
159
test/auth/file_authenticator.cc
Normal file
159
test/auth/file_authenticator.cc
Normal file
@ -0,0 +1,159 @@
|
||||
#include "webfused/auth/file_authenticator.h"
|
||||
#include "webfused/auth/authenticator.h"
|
||||
#include "webfused/config/settings.h"
|
||||
#include "webfused/auth/factory.h"
|
||||
|
||||
#include "mock/credentials.hpp"
|
||||
#include "mock/settings.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <libconfig.h>
|
||||
|
||||
using ::webfused_test::MockSettings;
|
||||
using ::webfused_test::MockCredentials;
|
||||
using ::testing::Return;
|
||||
using ::testing::StrEq;
|
||||
using ::testing::_;
|
||||
|
||||
TEST(file_authenticator, create)
|
||||
{
|
||||
MockSettings settings;
|
||||
EXPECT_CALL(settings, wfd_settings_get_string(_,StrEq("file"))).Times(1).WillOnce(Return("test_passwd.json"));
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_file_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(file_authenticator, create_fail_missing_file)
|
||||
{
|
||||
MockSettings settings;
|
||||
EXPECT_CALL(settings, wfd_settings_get_string(_,StrEq("file"))).Times(1).WillOnce(Return(nullptr));
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_file_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_FALSE(success);
|
||||
}
|
||||
|
||||
TEST(file_authenticator, create_via_factory)
|
||||
{
|
||||
MockSettings settings;
|
||||
EXPECT_CALL(settings, wfd_settings_get_string(_,StrEq("file"))).Times(1).WillOnce(Return("test_passwd.json"));
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_authenticator_create("file", nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(file_authenticator, authenticate)
|
||||
{
|
||||
MockSettings settings;
|
||||
EXPECT_CALL(settings, wfd_settings_get_string(_,StrEq("file"))).Times(1).WillOnce(Return("test_passwd.json"));
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_file_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
MockCredentials creds;
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("username"))).Times(1).WillOnce(Return("bob"));
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("password"))).Times(1).WillOnce(Return("secret"));
|
||||
|
||||
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
|
||||
ASSERT_TRUE(is_authenticated);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(file_authenticator, authenticate_fail_wrong_passwd)
|
||||
{
|
||||
MockSettings settings;
|
||||
EXPECT_CALL(settings, wfd_settings_get_string(_,StrEq("file"))).Times(1).WillOnce(Return("test_passwd.json"));
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_file_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
MockCredentials creds;
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("username"))).Times(1).WillOnce(Return("bob"));
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("password"))).Times(1).WillOnce(Return("unkown"));
|
||||
|
||||
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
|
||||
ASSERT_FALSE(is_authenticated);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(file_authenticator, authenticate_fail_no_passwd_file)
|
||||
{
|
||||
MockSettings settings;
|
||||
EXPECT_CALL(settings, wfd_settings_get_string(_,StrEq("file"))).Times(1).WillOnce(Return("unknown_passwd.json"));
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_file_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
MockCredentials creds;
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("username"))).Times(1).WillOnce(Return("bob"));
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("password"))).Times(1).WillOnce(Return("secred"));
|
||||
|
||||
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
|
||||
ASSERT_FALSE(is_authenticated);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(file_authenticator, authenticate_fail_missing_username)
|
||||
{
|
||||
MockSettings settings;
|
||||
EXPECT_CALL(settings, wfd_settings_get_string(_,StrEq("file"))).Times(1).WillOnce(Return("test_passwd.json"));
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_file_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
MockCredentials creds;
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("username"))).Times(1).WillOnce(Return(nullptr));
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("password"))).Times(1).WillOnce(Return("unkown"));
|
||||
|
||||
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
|
||||
ASSERT_FALSE(is_authenticated);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(file_authenticator, authenticate_fail_missing_password)
|
||||
{
|
||||
MockSettings settings;
|
||||
EXPECT_CALL(settings, wfd_settings_get_string(_,StrEq("file"))).Times(1).WillOnce(Return("test_passwd.json"));
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_file_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
MockCredentials creds;
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("username"))).Times(1).WillOnce(Return("bob"));
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("password"))).Times(1).WillOnce(Return(nullptr));
|
||||
|
||||
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
|
||||
ASSERT_FALSE(is_authenticated);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(file_authenticator, get_type)
|
||||
{
|
||||
MockSettings settings;
|
||||
EXPECT_CALL(settings, wfd_settings_get_string(_,StrEq("file"))).Times(1).WillOnce(Return("/any/path"));
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_file_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
ASSERT_STREQ("username", wfd_authenticator_get_type(authenticator));
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
279
test/auth/pam_authenticator.cc
Normal file
279
test/auth/pam_authenticator.cc
Normal file
@ -0,0 +1,279 @@
|
||||
#include "webfused/auth/pam_authenticator.h"
|
||||
#include "webfused/auth/authenticator.h"
|
||||
#include "webfused/config/settings.h"
|
||||
#include "webfused/auth/factory.h"
|
||||
|
||||
#include "mock/credentials.hpp"
|
||||
#include "mock/settings.hpp"
|
||||
#include "mock/pam.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
|
||||
using ::webfused_test::MockSettings;
|
||||
using ::webfused_test::MockCredentials;
|
||||
using ::webfused_test::MockPam;
|
||||
using ::testing::_;
|
||||
using ::testing::Return;
|
||||
using ::testing::StrEq;
|
||||
using ::testing::Invoke;
|
||||
using ::testing::StrictMock;
|
||||
|
||||
TEST(pam_authenticator, create)
|
||||
{
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_pam_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(pam_authenticator, create_via_factory)
|
||||
{
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_authenticator_create("pam", nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(pam_authenticator, get_type)
|
||||
{
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_pam_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
ASSERT_STREQ("username", wfd_authenticator_get_type(authenticator));
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(pam_authenticator, authenticate)
|
||||
{
|
||||
MockPam pam;
|
||||
EXPECT_CALL(pam, pam_start(StrEq("webfused"), nullptr, _, _)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
EXPECT_CALL(pam, pam_authenticate(_, PAM_DISALLOW_NULL_AUTHTOK)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
EXPECT_CALL(pam, pam_acct_mgmt(_, PAM_DISALLOW_NULL_AUTHTOK)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
EXPECT_CALL(pam, pam_end(_, _)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_pam_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
MockCredentials creds;
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("username"))).Times(1).WillOnce(Return("bob"));
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("password"))).Times(1).WillOnce(Return("secret"));
|
||||
|
||||
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
|
||||
ASSERT_TRUE(is_authenticated);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(pam_authenticator, authenticate_with_custom_service_name)
|
||||
{
|
||||
MockPam pam;
|
||||
EXPECT_CALL(pam, pam_start(StrEq("brummni"), nullptr, _, _)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
EXPECT_CALL(pam, pam_authenticate(_, PAM_DISALLOW_NULL_AUTHTOK)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
EXPECT_CALL(pam, pam_acct_mgmt(_, PAM_DISALLOW_NULL_AUTHTOK)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
EXPECT_CALL(pam, pam_end(_, _)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
|
||||
MockSettings settings;
|
||||
EXPECT_CALL(settings, wfd_settings_get_string_or_default(_,StrEq("service_name"), StrEq("webfused")))
|
||||
.Times(1).WillOnce(Return("brummni"));
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_pam_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
MockCredentials creds;
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("username"))).Times(1).WillOnce(Return("bob"));
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("password"))).Times(1).WillOnce(Return("secret"));
|
||||
|
||||
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
|
||||
ASSERT_TRUE(is_authenticated);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
int valid_conversation(
|
||||
char const * service_name,
|
||||
char const * user,
|
||||
struct pam_conv const * conv,
|
||||
pam_handle_t * * handle)
|
||||
{
|
||||
(void) service_name;
|
||||
(void) user;
|
||||
(void) handle;
|
||||
|
||||
pam_message request_username = {PAM_PROMPT_ECHO_ON, "username"};
|
||||
pam_message request_password = {PAM_PROMPT_ECHO_OFF, "password"};
|
||||
pam_message const * messages[2] =
|
||||
{
|
||||
&request_username,
|
||||
&request_password
|
||||
};
|
||||
pam_response * responses;
|
||||
int rc = conv->conv(2, messages, &responses, conv->appdata_ptr);
|
||||
if (PAM_SUCCESS == rc)
|
||||
{
|
||||
free(responses[0].resp);
|
||||
free(responses[1].resp);
|
||||
free(responses);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST(pam_authenticator, conversation_with_valid_messages)
|
||||
{
|
||||
MockPam pam;
|
||||
EXPECT_CALL(pam, pam_start(StrEq("webfused"), nullptr, _, _))
|
||||
.Times(1).WillOnce(Invoke(&valid_conversation));
|
||||
EXPECT_CALL(pam, pam_authenticate(_, PAM_DISALLOW_NULL_AUTHTOK)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
EXPECT_CALL(pam, pam_acct_mgmt(_, PAM_DISALLOW_NULL_AUTHTOK)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
EXPECT_CALL(pam, pam_end(_, _)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_pam_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
MockCredentials creds;
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("username"))).Times(1).WillOnce(Return("bob"));
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("password"))).Times(1).WillOnce(Return("secret"));
|
||||
|
||||
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
|
||||
ASSERT_TRUE(is_authenticated);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
int invalid_conversation(
|
||||
char const * service_name,
|
||||
char const * user,
|
||||
struct pam_conv const * conv,
|
||||
pam_handle_t * * handle)
|
||||
{
|
||||
(void) service_name;
|
||||
(void) user;
|
||||
(void) handle;
|
||||
|
||||
pam_message invalid_request = {-1, "invalid"};
|
||||
pam_message const * messages[2] =
|
||||
{
|
||||
&invalid_request
|
||||
};
|
||||
pam_response * responses;
|
||||
int rc = conv->conv(1, messages, &responses, conv->appdata_ptr);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST(pam_authenticator, conversation_with_invalid_messages)
|
||||
{
|
||||
MockPam pam;
|
||||
EXPECT_CALL(pam, pam_start(StrEq("webfused"), nullptr, _, _))
|
||||
.Times(1).WillOnce(Invoke(&invalid_conversation));
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_pam_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
MockCredentials creds;
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("username"))).Times(1).WillOnce(Return("bob"));
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("password"))).Times(1).WillOnce(Return("secret"));
|
||||
|
||||
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
|
||||
ASSERT_FALSE(is_authenticated);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(pam_authenticator, authenticate_fail_authenticate)
|
||||
{
|
||||
MockPam pam;
|
||||
EXPECT_CALL(pam, pam_start(StrEq("webfused"), nullptr, _, _)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
EXPECT_CALL(pam, pam_authenticate(_, PAM_DISALLOW_NULL_AUTHTOK)).Times(1).WillOnce(Return(-1));
|
||||
EXPECT_CALL(pam, pam_end(_, _)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_pam_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
MockCredentials creds;
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("username"))).Times(1).WillOnce(Return("bob"));
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("password"))).Times(1).WillOnce(Return("secret"));
|
||||
|
||||
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
|
||||
ASSERT_FALSE(is_authenticated);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(pam_authenticator, authenticate_fail_acct_mgmt)
|
||||
{
|
||||
MockPam pam;
|
||||
EXPECT_CALL(pam, pam_start(StrEq("webfused"), nullptr, _, _)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
EXPECT_CALL(pam, pam_authenticate(_, PAM_DISALLOW_NULL_AUTHTOK)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
EXPECT_CALL(pam, pam_acct_mgmt(_, PAM_DISALLOW_NULL_AUTHTOK)).Times(1).WillOnce(Return(-1));
|
||||
EXPECT_CALL(pam, pam_end(_, _)).Times(1).WillOnce(Return(PAM_SUCCESS));
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_pam_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
MockCredentials creds;
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("username"))).Times(1).WillOnce(Return("bob"));
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("password"))).Times(1).WillOnce(Return("secret"));
|
||||
|
||||
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
|
||||
ASSERT_FALSE(is_authenticated);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(pam_authenticator, authenticate_fail_missing_username)
|
||||
{
|
||||
StrictMock<MockPam> pam;
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_pam_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
MockCredentials creds;
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("username"))).Times(1).WillOnce(Return(nullptr));
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("password"))).Times(1).WillOnce(Return("secret"));
|
||||
|
||||
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
|
||||
ASSERT_FALSE(is_authenticated);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
||||
|
||||
TEST(pam_authenticator, authenticate_fail_missing_password)
|
||||
{
|
||||
StrictMock<MockPam> pam;
|
||||
|
||||
wfd_authenticator authenticator;
|
||||
bool success = wfd_pam_authenticator_create(nullptr, &authenticator);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
MockCredentials creds;
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("username"))).Times(1).WillOnce(Return("bob"));
|
||||
EXPECT_CALL(creds, wf_credentials_get(_,StrEq("password"))).Times(1).WillOnce(Return(nullptr));
|
||||
|
||||
bool is_authenticated = wfd_authenticator_authenticate(authenticator, nullptr);
|
||||
ASSERT_FALSE(is_authenticated);
|
||||
|
||||
wfd_authenticator_dispose(authenticator);
|
||||
}
|
154
test/change_user.cc
Normal file
154
test/change_user.cc
Normal file
@ -0,0 +1,154 @@
|
||||
#include "webfused/change_user.h"
|
||||
#include "mock/linux.hpp"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using ::webfused_test::MockLinux;
|
||||
using ::testing::StrictMock;
|
||||
using ::testing::Return;
|
||||
using ::testing::StrEq;
|
||||
|
||||
TEST(change_user, nop_id_not_root)
|
||||
{
|
||||
StrictMock<MockLinux> sys;
|
||||
EXPECT_CALL(sys, getuid).Times(1).WillOnce(Return(42));
|
||||
|
||||
bool success = wfd_change_user("webfused", "daemons");
|
||||
ASSERT_TRUE(success);
|
||||
}
|
||||
|
||||
TEST(change_user, change_successfully)
|
||||
{
|
||||
struct group group;
|
||||
group.gr_gid = 23;
|
||||
|
||||
struct passwd userinfo;
|
||||
userinfo.pw_uid = 42;
|
||||
|
||||
StrictMock<MockLinux> sys;
|
||||
EXPECT_CALL(sys, getuid).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getgrnam(StrEq("daemons"))).Times(1).WillOnce(Return(&group));
|
||||
EXPECT_CALL(sys, setgid(23)).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, setgroups(0, nullptr)).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getpwnam("webfused")).Times(1).WillOnce(Return(&userinfo));
|
||||
EXPECT_CALL(sys, setuid(42)).Times(1).WillOnce(Return(0));
|
||||
|
||||
bool success = wfd_change_user("webfused", "daemons");
|
||||
ASSERT_TRUE(success);
|
||||
}
|
||||
|
||||
TEST(change_user, fail_no_username_or_password)
|
||||
{
|
||||
StrictMock<MockLinux> sys;
|
||||
EXPECT_CALL(sys, getuid).WillRepeatedly(Return(0));
|
||||
|
||||
ASSERT_FALSE(wfd_change_user(nullptr, "daemons"));
|
||||
ASSERT_FALSE(wfd_change_user("webfused", nullptr));
|
||||
ASSERT_FALSE(wfd_change_user(nullptr, nullptr));
|
||||
}
|
||||
|
||||
TEST(change_user, fail_setuid)
|
||||
{
|
||||
struct group group;
|
||||
group.gr_gid = 23;
|
||||
|
||||
struct passwd userinfo;
|
||||
userinfo.pw_uid = 42;
|
||||
|
||||
StrictMock<MockLinux> sys;
|
||||
EXPECT_CALL(sys, getuid).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getgrnam(StrEq("daemons"))).Times(1).WillOnce(Return(&group));
|
||||
EXPECT_CALL(sys, setgid(23)).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, setgroups(0, nullptr)).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getpwnam("webfused")).Times(1).WillOnce(Return(&userinfo));
|
||||
EXPECT_CALL(sys, setuid(42)).Times(1).WillOnce(Return(-1));
|
||||
|
||||
bool success = wfd_change_user("webfused", "daemons");
|
||||
ASSERT_FALSE(success);
|
||||
}
|
||||
|
||||
TEST(change_user, fail_getpwnam)
|
||||
{
|
||||
struct group group;
|
||||
group.gr_gid = 23;
|
||||
|
||||
StrictMock<MockLinux> sys;
|
||||
EXPECT_CALL(sys, getuid).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getgrnam(StrEq("daemons"))).Times(1).WillOnce(Return(&group));
|
||||
EXPECT_CALL(sys, setgid(23)).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, setgroups(0, nullptr)).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getpwnam("webfused")).Times(1).WillOnce(Return(nullptr));
|
||||
|
||||
bool success = wfd_change_user("webfused", "daemons");
|
||||
ASSERT_FALSE(success);
|
||||
}
|
||||
|
||||
TEST(change_user, fail_setgroups)
|
||||
{
|
||||
struct group group;
|
||||
group.gr_gid = 23;
|
||||
|
||||
StrictMock<MockLinux> sys;
|
||||
EXPECT_CALL(sys, getuid).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getgrnam(StrEq("daemons"))).Times(1).WillOnce(Return(&group));
|
||||
EXPECT_CALL(sys, setgid(23)).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, setgroups(0, nullptr)).Times(1).WillOnce(Return(-1));
|
||||
|
||||
bool success = wfd_change_user("webfused", "daemons");
|
||||
ASSERT_FALSE(success);
|
||||
}
|
||||
|
||||
TEST(change_user, fail_setgid)
|
||||
{
|
||||
struct group group;
|
||||
group.gr_gid = 23;
|
||||
|
||||
StrictMock<MockLinux> sys;
|
||||
EXPECT_CALL(sys, getuid).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getgrnam(StrEq("daemons"))).Times(1).WillOnce(Return(&group));
|
||||
EXPECT_CALL(sys, setgid(23)).Times(1).WillOnce(Return(-1));
|
||||
|
||||
bool success = wfd_change_user("webfused", "daemons");
|
||||
ASSERT_FALSE(success);
|
||||
}
|
||||
|
||||
TEST(change_user, fail_getgrpnam)
|
||||
{
|
||||
StrictMock<MockLinux> sys;
|
||||
EXPECT_CALL(sys, getuid).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getgrnam(StrEq("daemons"))).Times(1).WillOnce(Return(nullptr));
|
||||
|
||||
bool success = wfd_change_user("webfused", "daemons");
|
||||
ASSERT_FALSE(success);
|
||||
}
|
||||
|
||||
TEST(change_user, fail_switch_to_root)
|
||||
{
|
||||
struct group group;
|
||||
group.gr_gid = 23;
|
||||
|
||||
struct passwd userinfo;
|
||||
userinfo.pw_uid = 0;
|
||||
|
||||
StrictMock<MockLinux> sys;
|
||||
EXPECT_CALL(sys, getuid).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getgrnam(StrEq("daemons"))).Times(1).WillOnce(Return(&group));
|
||||
EXPECT_CALL(sys, setgid(23)).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, setgroups(0, nullptr)).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getpwnam("webfused")).Times(1).WillOnce(Return(&userinfo));
|
||||
|
||||
bool success = wfd_change_user("webfused", "daemons");
|
||||
ASSERT_FALSE(success);
|
||||
}
|
||||
|
||||
TEST(change_user, fail_switch_to_root_group)
|
||||
{
|
||||
struct group group;
|
||||
group.gr_gid = 0;
|
||||
|
||||
StrictMock<MockLinux> sys;
|
||||
EXPECT_CALL(sys, getuid).Times(1).WillOnce(Return(0));
|
||||
EXPECT_CALL(sys, getgrnam(StrEq("daemons"))).Times(1).WillOnce(Return(&group));
|
||||
|
||||
bool success = wfd_change_user("webfused", "daemons");
|
||||
ASSERT_FALSE(success);
|
||||
}
|
110
test/config/config.cc
Normal file
110
test/config/config.cc
Normal file
@ -0,0 +1,110 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "webfused/config/config.h"
|
||||
#include "webfused/config/config_intern.h"
|
||||
#include "mock/settings.hpp"
|
||||
|
||||
#include "webfused/log/logger.h"
|
||||
#include "webfused/log/log.h"
|
||||
#include "webfused/util/string_list.h"
|
||||
#include "mock/logger.hpp"
|
||||
|
||||
using ::webfused_test::MockLogger;
|
||||
using ::testing::_;
|
||||
|
||||
using ::webfused_test::MockSettings;
|
||||
using ::testing::Return;
|
||||
using ::testing::StrEq;
|
||||
|
||||
TEST(config, server_config)
|
||||
{
|
||||
wfd_config * config = wfd_config_create();
|
||||
ASSERT_NE(nullptr, config);
|
||||
|
||||
wfd_config_set_server_vhostname(config, "localhost");
|
||||
wfd_config_set_server_port(config, 8443);
|
||||
wfd_config_set_server_key(config, "/path/to/key.pem");
|
||||
wfd_config_set_server_cert(config, "/path/to/cert.pem");
|
||||
wfd_config_set_server_document_root(config, "/var/www");
|
||||
|
||||
wf_server_config * server_config = wfd_config_get_server_config(config);
|
||||
ASSERT_NE(nullptr, server_config);
|
||||
|
||||
wfd_config_dispose(config);
|
||||
}
|
||||
|
||||
TEST(config, auth_config)
|
||||
{
|
||||
wfd_config * config = wfd_config_create();
|
||||
ASSERT_NE(nullptr, config);
|
||||
|
||||
MockSettings settings;
|
||||
EXPECT_CALL(settings, wfd_settings_get_string(_,StrEq("file"))).Times(1).WillOnce(Return("/any/path"));
|
||||
|
||||
bool success = wfd_config_add_auth_provider(config, "file", nullptr);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
wfd_config_dispose(config);
|
||||
}
|
||||
|
||||
TEST(config, auth_config_failed_to_add_second_provider)
|
||||
{
|
||||
wfd_config * config = wfd_config_create();
|
||||
ASSERT_NE(nullptr, config);
|
||||
|
||||
MockSettings settings;
|
||||
EXPECT_CALL(settings, wfd_settings_get_string(_,StrEq("file"))).Times(1).WillOnce(Return("/any/path"));
|
||||
|
||||
bool success = wfd_config_add_auth_provider(config, "file", nullptr);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
success = wfd_config_add_auth_provider(config, "file", nullptr);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
wfd_config_dispose(config);
|
||||
}
|
||||
|
||||
TEST(config, auth_config_failed_to_add_unknown_provider)
|
||||
{
|
||||
wfd_config * config = wfd_config_create();
|
||||
ASSERT_NE(nullptr, config);
|
||||
|
||||
bool success = wfd_config_add_auth_provider(config, "unknown", nullptr);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
wfd_config_dispose(config);
|
||||
}
|
||||
|
||||
TEST(config, add_filesystem)
|
||||
{
|
||||
wfd_config * config = wfd_config_create();
|
||||
ASSERT_NE(nullptr, config);
|
||||
|
||||
struct wfd_string_list mount_options = {0, 0, nullptr};
|
||||
bool success = wfd_config_add_filesystem(config, "test", "/tmp/test", &mount_options);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
wfd_config_dispose(config);
|
||||
}
|
||||
|
||||
TEST(config, set_logger)
|
||||
{
|
||||
wfd_config * config = wfd_config_create();
|
||||
ASSERT_NE(nullptr, config);
|
||||
|
||||
bool success = wfd_config_set_logger(config, "stderr", WFD_LOGLEVEL_ALL, nullptr);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
wfd_config_dispose(config);
|
||||
}
|
||||
|
||||
TEST(config, do_set_user)
|
||||
{
|
||||
wfd_config * config = wfd_config_create();
|
||||
ASSERT_NE(nullptr, config);
|
||||
|
||||
wfd_config_set_user(config, "some.user", "some.group");
|
||||
ASSERT_STREQ("some.user", wfd_config_get_user(config));
|
||||
ASSERT_STREQ("some.group", wfd_config_get_group(config));
|
||||
|
||||
wfd_config_dispose(config);
|
||||
}
|
75
test/config/configfile.cc
Normal file
75
test/config/configfile.cc
Normal file
@ -0,0 +1,75 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "webfused/config/config.h"
|
||||
#include "webfused/config/factory.h"
|
||||
#include "webfused/log/logger.h"
|
||||
#include "webfused/log/log.h"
|
||||
#include "mock/logger.hpp"
|
||||
#include "mock/config_builder.hpp"
|
||||
#include "mock/libconfig.hpp"
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::Return;
|
||||
using ::testing::StrictMock;
|
||||
using ::testing::StrEq;
|
||||
using ::webfused_test::MockLogger;
|
||||
using ::webfused_test::MockConfigBuilder;
|
||||
using ::webfused_test::MockLibConfig;
|
||||
|
||||
TEST(configfile, is_loadable)
|
||||
{
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_set_logger(_,_,_,_)).Times(1).WillOnce(Return(true));
|
||||
EXPECT_CALL(builder, wfd_config_set_server_vhostname(_,StrEq("localhost"))).Times(1);
|
||||
EXPECT_CALL(builder, wfd_config_set_server_port(_,8080)).Times(1);
|
||||
EXPECT_CALL(builder, wfd_config_add_auth_provider(_,_, _)).Times(1).WillOnce(Return(true));
|
||||
EXPECT_CALL(builder, wfd_config_add_filesystem(_,_,_,_)).Times(1).WillOnce(Return(true));
|
||||
|
||||
struct wfd_config * config = wfd_config_load_file("webfused.conf");
|
||||
ASSERT_NE(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile, minimal_config)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(_, _, _)).Times(0);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
|
||||
char const minimal[] = "version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n";
|
||||
struct wfd_config * config = wfd_config_load_string(minimal);
|
||||
ASSERT_NE(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile, invalid_config)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(0);
|
||||
EXPECT_CALL(builder, wfd_config_dispose(_)).Times(0);
|
||||
|
||||
char const syntax_error[] = "version.major = " WFD_CONFIG_VERSION_STR_MAJOR "\n";
|
||||
|
||||
wfd_config * config = wfd_config_load_string(syntax_error);
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile, invalid_config_file)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(0);
|
||||
EXPECT_CALL(builder, wfd_config_dispose(_)).Times(0);
|
||||
|
||||
struct wfd_config * config = wfd_config_load_file("invalid.conf");
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
139
test/config/configfile_auth.cc
Normal file
139
test/config/configfile_auth.cc
Normal file
@ -0,0 +1,139 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "webfused/config/config.h"
|
||||
#include "webfused/config/factory.h"
|
||||
#include "webfused/log/logger.h"
|
||||
#include "webfused/log/log.h"
|
||||
#include "mock/logger.hpp"
|
||||
#include "mock/config_builder.hpp"
|
||||
#include "mock/libconfig.hpp"
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::Return;
|
||||
using ::testing::StrictMock;
|
||||
using ::testing::StrEq;
|
||||
using ::webfused_test::MockLogger;
|
||||
using ::webfused_test::MockConfigBuilder;
|
||||
using ::webfused_test::MockLibConfig;
|
||||
|
||||
TEST(config_auth, authentication)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(_, _, _)).Times(0);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_add_auth_provider(_,_, _)).Times(1).WillOnce(Return(true));
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"authentication:\n"
|
||||
"(\n"
|
||||
" {\n"
|
||||
" provider = \"test\"\n"
|
||||
" settings: { }\n"
|
||||
" }\n"
|
||||
")\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_NE(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(config_auth, failed_create_authenticator)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(_, _, _)).Times(0);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_dispose(_)).Times(1);
|
||||
EXPECT_CALL(builder, wfd_config_add_auth_provider(_,_, _)).Times(1).WillOnce(Return(false));
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"authentication:\n"
|
||||
"(\n"
|
||||
" {\n"
|
||||
" provider = \"test\"\n"
|
||||
" settings: { }\n"
|
||||
" }\n"
|
||||
")\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(config_auth, failed_missing_auth_provider)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_dispose(_)).Times(1);
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"authentication:\n"
|
||||
"(\n"
|
||||
" {\n"
|
||||
" settings: { }\n"
|
||||
" }\n"
|
||||
")\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(config_auth, failed_missing_auth_settings)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_dispose(_)).Times(1);
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"authentication:\n"
|
||||
"(\n"
|
||||
" {\n"
|
||||
" provider = \"test\"\n"
|
||||
" }\n"
|
||||
")\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(config_auth, failed_auth_settings_get_elem)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_dispose(_)).Times(1);
|
||||
|
||||
MockLibConfig libconfig;
|
||||
EXPECT_CALL(libconfig, config_setting_get_elem(_,_)).Times(1).WillOnce(Return(nullptr));
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR" }\n"
|
||||
"authentication:\n"
|
||||
"(\n"
|
||||
" {\n"
|
||||
" provider = \"test\"\n"
|
||||
" settings: { }\n"
|
||||
" }\n"
|
||||
")\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
199
test/config/configfile_filesystem.cc
Normal file
199
test/config/configfile_filesystem.cc
Normal file
@ -0,0 +1,199 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "webfused/config/config.h"
|
||||
#include "webfused/config/factory.h"
|
||||
#include "webfused/util/string_list.h"
|
||||
#include "webfused/log/logger.h"
|
||||
#include "webfused/log/log.h"
|
||||
#include "mock/logger.hpp"
|
||||
#include "mock/config_builder.hpp"
|
||||
#include "mock/libconfig.hpp"
|
||||
|
||||
using ::testing::Invoke;
|
||||
using ::testing::_;
|
||||
using ::testing::Return;
|
||||
using ::testing::StrictMock;
|
||||
using ::testing::StrEq;
|
||||
using ::webfused_test::MockLogger;
|
||||
using ::webfused_test::MockConfigBuilder;
|
||||
using ::webfused_test::MockLibConfig;
|
||||
|
||||
TEST(configfile_fs, filesystems)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(_, _, _)).Times(0);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_add_filesystem(_,_,_,_)).Times(1).WillOnce(Return(true));
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"filesystems:\n"
|
||||
"(\n"
|
||||
" {name = \"foo\", mount_point = \"/tmp/test\" }\n"
|
||||
")\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_NE(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile_fs, filesystems_empty)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(_, _, _)).Times(0);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_add_filesystem(_,_,_,_)).Times(0);
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"filesystems:\n"
|
||||
"(\n"
|
||||
")\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_NE(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile_fs, filesystems_failed_add)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(_, _, _)).Times(0);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_dispose(_)).Times(1);
|
||||
EXPECT_CALL(builder, wfd_config_add_filesystem(_,_,_,_)).Times(1).WillOnce(Return(false));
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"filesystems:\n"
|
||||
"(\n"
|
||||
" {name = \"foo\", mount_point = \"/tmp/test\", mount_options = () }\n"
|
||||
")\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile_fs, filesystems_failed_missing_name)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_dispose(_)).Times(1);
|
||||
EXPECT_CALL(builder, wfd_config_add_filesystem(_,_,_,_)).Times(0);
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"filesystems:\n"
|
||||
"(\n"
|
||||
" {mount_point = \"/tmp/test\" }\n"
|
||||
")\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile_fs, filesystems_failed_missing_mountpoint)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_dispose(_)).Times(1);
|
||||
EXPECT_CALL(builder, wfd_config_add_filesystem(_,_,_,_)).Times(0);
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"filesystems:\n"
|
||||
"(\n"
|
||||
" {name = \"foo\"}\n"
|
||||
")\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile_fs, filesystems_failed_missing_elem)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_dispose(_)).Times(1);
|
||||
EXPECT_CALL(builder, wfd_config_add_filesystem(_,_,_,_)).Times(0);
|
||||
|
||||
MockLibConfig libconfig;
|
||||
EXPECT_CALL(libconfig, config_setting_get_elem(_,_)).Times(1).WillOnce(Return(nullptr));
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"filesystems:\n"
|
||||
"(\n"
|
||||
" {name = \"foo\", mount_point = \"/tmp/test\" }\n"
|
||||
")\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile_fs, filesystems_failed_add_options)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(_, _, _)).Times(0);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_dispose(_)).Times(1);
|
||||
EXPECT_CALL(builder, wfd_config_add_filesystem(_,_,_,_)).Times(1).WillOnce(Return(false));
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"filesystems:\n"
|
||||
"(\n"
|
||||
" {name = \"foo\", mount_point = \"/tmp/test\", mount_options = (\"-o\", \"allow_other\") }\n"
|
||||
")\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile_fs, with_mountoptions)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(_, _, _)).Times(0);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_add_filesystem(_,_,_,_)).Times(1).WillOnce(Invoke(
|
||||
[](wfd_config * config, char const * name, char const * mountpoint, wfd_string_list const * mount_options) -> bool {
|
||||
std::cout << mount_options->items[0] << std::endl;
|
||||
std::cout << mount_options->items[1] << std::endl;
|
||||
return (2 == mount_options->size);
|
||||
}));
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"filesystems:\n"
|
||||
"(\n"
|
||||
" {name = \"foo\", mount_point = \"/tmp/test\", mount_options = (\"-o\", \"allow_user\") }\n"
|
||||
")\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_NE(nullptr, config);
|
||||
}
|
129
test/config/configfile_log.cc
Normal file
129
test/config/configfile_log.cc
Normal file
@ -0,0 +1,129 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "webfused/config/config.h"
|
||||
#include "webfused/config/factory.h"
|
||||
#include "webfused/log/logger.h"
|
||||
#include "webfused/log/log.h"
|
||||
#include "mock/logger.hpp"
|
||||
#include "mock/config_builder.hpp"
|
||||
#include "mock/libconfig.hpp"
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::Return;
|
||||
using ::testing::StrictMock;
|
||||
using ::testing::StrEq;
|
||||
using ::webfused_test::MockLogger;
|
||||
using ::webfused_test::MockConfigBuilder;
|
||||
using ::webfused_test::MockLibConfig;
|
||||
|
||||
TEST(configfile_log, set_logger)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(_, _, _)).Times(0);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_set_logger(_,_, _, _)).Times(1).WillOnce(Return(true));
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"log:\n"
|
||||
"{\n"
|
||||
" provider = \"stderr\"\n"
|
||||
" level = \"all\"\n"
|
||||
"}\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_NE(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile_log, log_fail_set_logger)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(_, _, _)).Times(0);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_dispose(_)).Times(1);
|
||||
EXPECT_CALL(builder, wfd_config_set_logger(_,_, _, _)).Times(1).WillOnce(Return(false));
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"log:\n"
|
||||
"{\n"
|
||||
" provider = \"stderr\"\n"
|
||||
" level = \"all\"\n"
|
||||
"}\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile_log, log_fail_missing_provider)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_dispose(_)).Times(1);
|
||||
EXPECT_CALL(builder, wfd_config_set_logger(_,_, _, _)).Times(0);
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"log:\n"
|
||||
"{\n"
|
||||
" level = \"all\"\n"
|
||||
"}\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile_log, log_fail_missing_level)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_dispose(_)).Times(1);
|
||||
EXPECT_CALL(builder, wfd_config_set_logger(_,_, _, _)).Times(0);
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"log:\n"
|
||||
"{\n"
|
||||
" provider = \"stderr\"\n"
|
||||
" level = \"fancy\"\n"
|
||||
"}\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile_log, log_fail_invalid_level)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_dispose(_)).Times(1);
|
||||
EXPECT_CALL(builder, wfd_config_set_logger(_, _, _, _)).Times(0);
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"log:\n"
|
||||
"{\n"
|
||||
" provider = \"stderr\"\n"
|
||||
"}\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
128
test/config/configfile_server.cc
Normal file
128
test/config/configfile_server.cc
Normal file
@ -0,0 +1,128 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "webfused/config/config.h"
|
||||
#include "webfused/config/factory.h"
|
||||
#include "webfused/log/logger.h"
|
||||
#include "webfused/log/log.h"
|
||||
#include "mock/logger.hpp"
|
||||
#include "mock/config_builder.hpp"
|
||||
#include "mock/libconfig.hpp"
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::Return;
|
||||
using ::testing::StrictMock;
|
||||
using ::testing::StrEq;
|
||||
using ::webfused_test::MockLogger;
|
||||
using ::webfused_test::MockConfigBuilder;
|
||||
using ::webfused_test::MockLibConfig;
|
||||
|
||||
TEST(configfile_server, vhost_name)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(_, _, _)).Times(0);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_set_server_vhostname(_,StrEq("some.host"))).Times(1);
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"server:\n"
|
||||
"{\n"
|
||||
" vhost_name = \"some.host\"\n"
|
||||
"}\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_NE(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile_server, port)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(_, _, _)).Times(0);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_set_server_port(_,54321)).Times(1);
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"server:\n"
|
||||
"{\n"
|
||||
" port = 54321\n"
|
||||
"}\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_NE(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile_server, tls_certificate)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(_, _, _)).Times(0);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_set_server_cert(_, StrEq("/path/to/cert.pem"))).Times(1);
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"server:\n"
|
||||
"{\n"
|
||||
" tls:\n"
|
||||
" {\n"
|
||||
" certificate = \"/path/to/cert.pem\"\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_NE(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile_server, tls_key)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(_, _, _)).Times(0);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_set_server_key(_,StrEq("/path/to/key.pem"))).Times(1);
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"server:\n"
|
||||
"{\n"
|
||||
" tls:\n"
|
||||
" {\n"
|
||||
" key = \"/path/to/key.pem\"\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_NE(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile_server, document_root)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(_, _, _)).Times(0);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_set_server_document_root(_,StrEq("/var/www"))).Times(1);
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"server:\n"
|
||||
"{\n"
|
||||
" document_root = \"/var/www\"\n"
|
||||
"}\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_NE(nullptr, config);
|
||||
}
|
83
test/config/configfile_user.cc
Normal file
83
test/config/configfile_user.cc
Normal file
@ -0,0 +1,83 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "webfused/config/config.h"
|
||||
#include "webfused/config/factory.h"
|
||||
#include "webfused/log/logger.h"
|
||||
#include "webfused/log/log.h"
|
||||
#include "mock/logger.hpp"
|
||||
#include "mock/config_builder.hpp"
|
||||
#include "mock/libconfig.hpp"
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::Return;
|
||||
using ::testing::StrictMock;
|
||||
using ::testing::StrEq;
|
||||
using ::webfused_test::MockLogger;
|
||||
using ::webfused_test::MockConfigBuilder;
|
||||
using ::webfused_test::MockLibConfig;
|
||||
|
||||
TEST(configfile_user, set_user)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(_, _, _)).Times(0);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_set_user(_, _, _)).Times(1);
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"user:\n"
|
||||
"{\n"
|
||||
" name = \"webfused\"\n"
|
||||
" group = \"webfused\"\n"
|
||||
"}\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_NE(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile_user, set_user_fail_missing_name)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_dispose(_)).Times(1);
|
||||
EXPECT_CALL(builder, wfd_config_set_user(_, _, _)).Times(0);
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"user:\n"
|
||||
"{\n"
|
||||
" group = \"webfused\"\n"
|
||||
"}\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile_user, set_user_fail_missing_group)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_dispose(_)).Times(1);
|
||||
EXPECT_CALL(builder, wfd_config_set_user(_, _, _)).Times(0);
|
||||
|
||||
char const config_text[] =
|
||||
"version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n"
|
||||
"user:\n"
|
||||
"{\n"
|
||||
" name = \"webfused\"\n"
|
||||
"}\n"
|
||||
;
|
||||
struct wfd_config * config = wfd_config_load_string(config_text);
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
111
test/config/configfile_version.cc
Normal file
111
test/config/configfile_version.cc
Normal file
@ -0,0 +1,111 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "webfused/config/config.h"
|
||||
#include "webfused/config/factory.h"
|
||||
#include "webfused/log/logger.h"
|
||||
#include "webfused/log/log.h"
|
||||
#include "mock/logger.hpp"
|
||||
#include "mock/config_builder.hpp"
|
||||
#include "mock/libconfig.hpp"
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::Return;
|
||||
using ::testing::StrictMock;
|
||||
using ::testing::StrEq;
|
||||
using ::webfused_test::MockLogger;
|
||||
using ::webfused_test::MockConfigBuilder;
|
||||
using ::webfused_test::MockLibConfig;
|
||||
|
||||
TEST(configfile_version, invalid_major_version_too_low)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_dispose(_)).Times(1);
|
||||
|
||||
char const too_low[] = "version = { major = 0, minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n";
|
||||
|
||||
struct wfd_config * config= wfd_config_load_string(too_low);
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile_version, invalid_major_version_too_high)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_dispose(_)).Times(1);
|
||||
|
||||
char const too_high[] = "version = { major = 99, minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n";
|
||||
|
||||
struct wfd_config * config = wfd_config_load_string(too_high);
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile_version, invalid_missing_major_version)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_dispose(_)).Times(1);
|
||||
|
||||
char const too_high[] = "version = { minor = " WFD_CONFIG_VERSION_STR_MINOR " }\n";
|
||||
|
||||
struct wfd_config * config = wfd_config_load_string(too_high);
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile_version, invalid_missing_minor_version)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, _, _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
EXPECT_CALL(builder, wfd_config_dispose(_)).Times(1);
|
||||
|
||||
char const too_high[] = "version = { major = " WFD_CONFIG_VERSION_STR_MAJOR " }\n";
|
||||
|
||||
struct wfd_config * config = wfd_config_load_string(too_high);
|
||||
ASSERT_EQ(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile_version, valid_older_minor)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_INFO, _, _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
|
||||
char const valid[] = "version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = -1 }\n";
|
||||
|
||||
struct wfd_config * config = wfd_config_load_string(valid);
|
||||
ASSERT_NE(nullptr, config);
|
||||
}
|
||||
|
||||
TEST(configfile_version, valid_newer_minor)
|
||||
{
|
||||
MockLogger logger;
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_WARN, _, _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
StrictMock<MockConfigBuilder> builder;
|
||||
EXPECT_CALL(builder, wfd_config_create).Times(1).WillOnce(Return(builder.getBuilder()));
|
||||
|
||||
char const valid[] = "version = { major = " WFD_CONFIG_VERSION_STR_MAJOR ", minor = 99 }\n";
|
||||
|
||||
struct wfd_config * config = wfd_config_load_string(valid);
|
||||
ASSERT_NE(nullptr, config);
|
||||
}
|
90
test/config/settings.cc
Normal file
90
test/config/settings.cc
Normal file
@ -0,0 +1,90 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "webfused/config/settings_intern.h"
|
||||
#include "webfused/config/settings.h"
|
||||
#include <libconfig.h>
|
||||
|
||||
TEST(settings, get_string)
|
||||
{
|
||||
char const settings_text[] =
|
||||
"settings:\n"
|
||||
"{\n"
|
||||
" string_value = \"some.string\"\n"
|
||||
" int_value = 42\n"
|
||||
"}\n"
|
||||
;
|
||||
config_t config;
|
||||
config_init(&config);
|
||||
int rc = config_read_string(&config, settings_text);
|
||||
ASSERT_TRUE(CONFIG_TRUE == rc);
|
||||
|
||||
config_setting_t * setting = config_lookup(&config, "settings");
|
||||
ASSERT_NE(nullptr, setting);
|
||||
|
||||
wfd_settings settings;
|
||||
wfd_settings_init(&settings, setting);
|
||||
ASSERT_STREQ("some.string", wfd_settings_get_string(&settings, "string_value"));
|
||||
ASSERT_EQ(nullptr, wfd_settings_get_string(&settings, "int_value"));
|
||||
ASSERT_EQ(nullptr, wfd_settings_get_string(&settings, "invalid_value"));
|
||||
ASSERT_EQ(nullptr, wfd_settings_get_string(NULL, "invalid_value"));
|
||||
|
||||
wfd_settings_cleanup(&settings);
|
||||
config_destroy(&config);
|
||||
}
|
||||
|
||||
TEST(settings, get_string_or_default)
|
||||
{
|
||||
char const settings_text[] =
|
||||
"settings:\n"
|
||||
"{\n"
|
||||
" string_value = \"some.string\"\n"
|
||||
" int_value = 42\n"
|
||||
"}\n"
|
||||
;
|
||||
config_t config;
|
||||
config_init(&config);
|
||||
int rc = config_read_string(&config, settings_text);
|
||||
ASSERT_TRUE(CONFIG_TRUE == rc);
|
||||
|
||||
config_setting_t * setting = config_lookup(&config, "settings");
|
||||
ASSERT_NE(nullptr, setting);
|
||||
|
||||
wfd_settings settings;
|
||||
wfd_settings_init(&settings, setting);
|
||||
ASSERT_STREQ("some.string", wfd_settings_get_string_or_default(&settings, "string_value", "default"));
|
||||
ASSERT_STREQ("default", wfd_settings_get_string_or_default(&settings, "int_value", "default"));
|
||||
ASSERT_STREQ("default", wfd_settings_get_string_or_default(&settings, "invalid_value", "default"));
|
||||
ASSERT_STREQ("default", wfd_settings_get_string_or_default(NULL, "invalid_value", "default"));
|
||||
|
||||
wfd_settings_cleanup(&settings);
|
||||
config_destroy(&config);
|
||||
}
|
||||
|
||||
TEST(settings, get_bool)
|
||||
{
|
||||
char const settings_text[] =
|
||||
"settings:\n"
|
||||
"{\n"
|
||||
" true_value = true\n"
|
||||
" false_value = false\n"
|
||||
" int_value = 42\n"
|
||||
"}\n"
|
||||
;
|
||||
config_t config;
|
||||
config_init(&config);
|
||||
int rc = config_read_string(&config, settings_text);
|
||||
ASSERT_TRUE(CONFIG_TRUE == rc);
|
||||
|
||||
config_setting_t * setting = config_lookup(&config, "settings");
|
||||
ASSERT_NE(nullptr, setting);
|
||||
|
||||
wfd_settings settings;
|
||||
wfd_settings_init(&settings, setting);
|
||||
ASSERT_TRUE(wfd_settings_get_bool(&settings, "true_value"));
|
||||
ASSERT_FALSE(wfd_settings_get_bool(&settings, "false_value"));
|
||||
ASSERT_FALSE(wfd_settings_get_bool(&settings, "int_value"));
|
||||
ASSERT_FALSE(wfd_settings_get_bool(&settings, "invalid_value"));
|
||||
ASSERT_FALSE(wfd_settings_get_bool(NULL, "invalid_value"));
|
||||
|
||||
wfd_settings_cleanup(&settings);
|
||||
config_destroy(&config);
|
||||
}
|
88
test/daemon.cc
Normal file
88
test/daemon.cc
Normal file
@ -0,0 +1,88 @@
|
||||
#include "webfused/daemon.h"
|
||||
|
||||
#include "mock/server.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <cstdlib>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
using ::webfused_test::MockServer;
|
||||
using ::testing::_;
|
||||
using ::testing::Return;
|
||||
|
||||
TEST(daemon, print_usage)
|
||||
{
|
||||
char argv0[] = "daemon";
|
||||
char argv1[] = "--help";
|
||||
char * argv[] = { argv0, argv1, NULL};
|
||||
|
||||
int exit_code = wfd_daemon_run(2, argv);
|
||||
ASSERT_EQ(EXIT_SUCCESS, exit_code);
|
||||
}
|
||||
|
||||
TEST(daemon, print_usage_short)
|
||||
{
|
||||
char argv0[] = "daemon";
|
||||
char argv1[] = "-h";
|
||||
char * argv[] = { argv0, argv1, NULL};
|
||||
|
||||
int exit_code = wfd_daemon_run(2, argv);
|
||||
ASSERT_EQ(EXIT_SUCCESS, exit_code);
|
||||
}
|
||||
|
||||
TEST(daemon, fail_invalid_argument)
|
||||
{
|
||||
char argv0[] = "daemon";
|
||||
char argv1[] = "-x";
|
||||
char * argv[] = { argv0, argv1, NULL};
|
||||
|
||||
int exit_code = wfd_daemon_run(2, argv);
|
||||
ASSERT_EQ(EXIT_FAILURE, exit_code);
|
||||
}
|
||||
|
||||
TEST(daemon, fail_invalid_config_file)
|
||||
{
|
||||
char argv0[] = "daemon";
|
||||
char argv1[] = "-f";
|
||||
char argv2[] = "invalid.conf";
|
||||
char * argv[] = { argv0, argv1, argv2, NULL};
|
||||
|
||||
int exit_code = wfd_daemon_run(3, argv);
|
||||
ASSERT_EQ(EXIT_FAILURE, exit_code);
|
||||
}
|
||||
|
||||
void defered_raise()
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
raise(SIGINT);
|
||||
}
|
||||
|
||||
TEST(daemon, run)
|
||||
{
|
||||
char argv0[] = "daemon";
|
||||
char argv1[] = "-f";
|
||||
char argv2[] = "webfused.conf";
|
||||
char * argv[] = { argv0, argv1, argv2, NULL};
|
||||
|
||||
std::thread thread(defered_raise);
|
||||
|
||||
int exit_code = wfd_daemon_run(3, argv);
|
||||
ASSERT_EQ(EXIT_SUCCESS, exit_code);
|
||||
|
||||
thread.join();
|
||||
}
|
||||
|
||||
TEST(daemon, run_failed_to_create_server)
|
||||
{
|
||||
MockServer server;
|
||||
EXPECT_CALL(server, wf_server_create(_)).Times(1).WillOnce(Return(nullptr));
|
||||
|
||||
char argv0[] = "daemon";
|
||||
char argv1[] = "-f";
|
||||
char argv2[] = "webfused.conf";
|
||||
char * argv[] = { argv0, argv1, argv2, NULL};
|
||||
|
||||
int exit_code = wfd_daemon_run(3, argv);
|
||||
ASSERT_EQ(EXIT_FAILURE, exit_code);
|
||||
}
|
4
test/invalid.conf
Normal file
4
test/invalid.conf
Normal file
@ -0,0 +1,4 @@
|
||||
# This config file is invalid,
|
||||
# since "." is not allowed as separator
|
||||
|
||||
version.major = 1
|
170
test/log/log.cc
Normal file
170
test/log/log.cc
Normal file
@ -0,0 +1,170 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include "webfused/log/logger.h"
|
||||
#include "webfused/log/log.h"
|
||||
#include "mock/logger.hpp"
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::StrEq;
|
||||
using ::webfused_test::MockLogger;
|
||||
|
||||
TEST(log, fatal)
|
||||
{
|
||||
MockLogger logger(true);
|
||||
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_FATAL, StrEq("too bad"), _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
wfd_logger_init(WFD_LOGLEVEL_ALL, &wfd_MockLogger_log, &wfd_MockLogger_onclose, logger.getUserData());
|
||||
WFD_FATAL("too bad");
|
||||
wfd_logger_close();
|
||||
}
|
||||
|
||||
TEST(log, error)
|
||||
{
|
||||
MockLogger logger(true);
|
||||
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_ERROR, StrEq("too bad"), _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
wfd_logger_init(WFD_LOGLEVEL_ALL, &wfd_MockLogger_log, &wfd_MockLogger_onclose, logger.getUserData());
|
||||
WFD_ERROR("too bad");
|
||||
wfd_logger_close();
|
||||
}
|
||||
|
||||
TEST(log, warn)
|
||||
{
|
||||
MockLogger logger(true);
|
||||
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_WARN, StrEq("too bad"), _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
wfd_logger_init(WFD_LOGLEVEL_ALL, &wfd_MockLogger_log, &wfd_MockLogger_onclose, logger.getUserData());
|
||||
WFD_WARN("too bad");
|
||||
wfd_logger_close();
|
||||
}
|
||||
|
||||
TEST(log, info)
|
||||
{
|
||||
MockLogger logger(true);
|
||||
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_INFO, StrEq("too bad"), _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
wfd_logger_init(WFD_LOGLEVEL_ALL, &wfd_MockLogger_log, &wfd_MockLogger_onclose, logger.getUserData());
|
||||
WFD_INFO("too bad");
|
||||
wfd_logger_close();
|
||||
}
|
||||
|
||||
TEST(log, debug)
|
||||
{
|
||||
MockLogger logger(true);
|
||||
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_DEBUG, StrEq("too bad"), _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
wfd_logger_init(WFD_LOGLEVEL_ALL, &wfd_MockLogger_log, &wfd_MockLogger_onclose, logger.getUserData());
|
||||
WFD_DEBUG("too bad");
|
||||
wfd_logger_close();
|
||||
}
|
||||
|
||||
TEST(log, respect_loglevel)
|
||||
{
|
||||
MockLogger logger(true);
|
||||
|
||||
EXPECT_CALL(logger, log(_, _, _)).Times(0);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
wfd_logger_init(WFD_LOGLEVEL_WARN, &wfd_MockLogger_log, &wfd_MockLogger_onclose, logger.getUserData());
|
||||
WFD_DEBUG("too bad");
|
||||
wfd_logger_close();
|
||||
}
|
||||
|
||||
TEST(log, log_same_loglevel)
|
||||
{
|
||||
MockLogger logger(true);
|
||||
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_WARN, StrEq("too bad"), _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(1);
|
||||
|
||||
wfd_logger_init(WFD_LOGLEVEL_WARN, &wfd_MockLogger_log, &wfd_MockLogger_onclose, logger.getUserData());
|
||||
WFD_WARN("too bad");
|
||||
wfd_logger_close();
|
||||
}
|
||||
|
||||
TEST(log, omit_onclose_if_nullptr)
|
||||
{
|
||||
MockLogger logger(true);
|
||||
|
||||
EXPECT_CALL(logger, log(WFD_LOGLEVEL_WARN, StrEq("too bad"), _)).Times(1);
|
||||
EXPECT_CALL(logger, onclose()).Times(0);
|
||||
|
||||
wfd_logger_init(WFD_LOGLEVEL_WARN, &wfd_MockLogger_log, nullptr, logger.getUserData());
|
||||
WFD_WARN("too bad");
|
||||
wfd_logger_close();
|
||||
}
|
||||
|
||||
TEST(log, default_log)
|
||||
{
|
||||
WFD_ERROR("trigger log");
|
||||
}
|
||||
|
||||
TEST(log, loglevel_parse)
|
||||
{
|
||||
int level;
|
||||
|
||||
ASSERT_TRUE(wfd_log_level_parse("fatal", &level));
|
||||
ASSERT_EQ(WFD_LOGLEVEL_FATAL, level);
|
||||
ASSERT_TRUE(wfd_log_level_parse("FATAL", &level));
|
||||
ASSERT_EQ(WFD_LOGLEVEL_FATAL, level);
|
||||
|
||||
ASSERT_TRUE(wfd_log_level_parse("error", &level));
|
||||
ASSERT_EQ(WFD_LOGLEVEL_ERROR, level);
|
||||
ASSERT_TRUE(wfd_log_level_parse("ERROR", &level));
|
||||
ASSERT_EQ(WFD_LOGLEVEL_ERROR, level);
|
||||
|
||||
ASSERT_TRUE(wfd_log_level_parse("warn", &level));
|
||||
ASSERT_EQ(WFD_LOGLEVEL_WARN, level);
|
||||
ASSERT_TRUE(wfd_log_level_parse("WARN", &level));
|
||||
ASSERT_EQ(WFD_LOGLEVEL_WARN, level);
|
||||
ASSERT_TRUE(wfd_log_level_parse("warning", &level));
|
||||
ASSERT_EQ(WFD_LOGLEVEL_WARN, level);
|
||||
ASSERT_TRUE(wfd_log_level_parse("WARNING", &level));
|
||||
ASSERT_EQ(WFD_LOGLEVEL_WARN, level);
|
||||
|
||||
ASSERT_TRUE(wfd_log_level_parse("info", &level));
|
||||
ASSERT_EQ(WFD_LOGLEVEL_INFO, level);
|
||||
ASSERT_TRUE(wfd_log_level_parse("INFO", &level));
|
||||
ASSERT_EQ(WFD_LOGLEVEL_INFO, level);
|
||||
|
||||
ASSERT_TRUE(wfd_log_level_parse("debug", &level));
|
||||
ASSERT_EQ(WFD_LOGLEVEL_DEBUG, level);
|
||||
ASSERT_TRUE(wfd_log_level_parse("DEBUG", &level));
|
||||
ASSERT_EQ(WFD_LOGLEVEL_DEBUG, level);
|
||||
|
||||
ASSERT_FALSE(wfd_log_level_parse("<invalid>", &level));
|
||||
|
||||
ASSERT_TRUE(wfd_log_level_parse("all", &level));
|
||||
ASSERT_EQ(WFD_LOGLEVEL_ALL, level);
|
||||
ASSERT_TRUE(wfd_log_level_parse("ALL", &level));
|
||||
ASSERT_EQ(WFD_LOGLEVEL_ALL, level);
|
||||
|
||||
ASSERT_TRUE(wfd_log_level_parse("none", &level));
|
||||
ASSERT_EQ(WFD_LOGLEVEL_NONE, level);
|
||||
ASSERT_TRUE(wfd_log_level_parse("NONE", &level));
|
||||
ASSERT_EQ(WFD_LOGLEVEL_NONE, level);
|
||||
|
||||
}
|
||||
|
||||
TEST(log, log_level_tostring)
|
||||
{
|
||||
ASSERT_STREQ("none", wfd_log_level_tostring(WFD_LOGLEVEL_NONE));
|
||||
ASSERT_STREQ("fatal", wfd_log_level_tostring(WFD_LOGLEVEL_FATAL));
|
||||
ASSERT_STREQ("error", wfd_log_level_tostring(WFD_LOGLEVEL_ERROR));
|
||||
ASSERT_STREQ("warn", wfd_log_level_tostring(WFD_LOGLEVEL_WARN));
|
||||
ASSERT_STREQ("info", wfd_log_level_tostring(WFD_LOGLEVEL_INFO));
|
||||
ASSERT_STREQ("debug", wfd_log_level_tostring(WFD_LOGLEVEL_DEBUG));
|
||||
ASSERT_STREQ("all", wfd_log_level_tostring(WFD_LOGLEVEL_ALL));
|
||||
ASSERT_STREQ("<unknown>", wfd_log_level_tostring(42));
|
||||
}
|
10
test/log/log_manager.cc
Normal file
10
test/log/log_manager.cc
Normal file
@ -0,0 +1,10 @@
|
||||
#include "webfused/log/manager.h"
|
||||
#include "webfused/log/log.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <stddef.h>
|
||||
|
||||
TEST(log_manager, set_logger_fail_unknown_provider)
|
||||
{
|
||||
ASSERT_FALSE(wfd_log_manager_set_logger("unknown", WFD_LOGLEVEL_ALL, NULL));
|
||||
}
|
33
test/log/stderr_logger.cc
Normal file
33
test/log/stderr_logger.cc
Normal file
@ -0,0 +1,33 @@
|
||||
#include "webfused/log/stderr_logger.h"
|
||||
#include "webfused/log/manager.h"
|
||||
#include "webfused/log/logger.h"
|
||||
#include "webfused/log/log.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <stddef.h>
|
||||
|
||||
TEST(stderr_logger, init)
|
||||
{
|
||||
ASSERT_TRUE(wfd_stderr_logger_init(WFD_LOGLEVEL_ALL, NULL));
|
||||
wfd_logger_close();
|
||||
}
|
||||
|
||||
TEST(stderr_logger, init_via_manager)
|
||||
{
|
||||
ASSERT_TRUE(wfd_log_manager_set_logger("stderr", WFD_LOGLEVEL_ALL, NULL));
|
||||
wfd_logger_close();
|
||||
}
|
||||
|
||||
TEST(stderr_logger, log)
|
||||
{
|
||||
ASSERT_TRUE(wfd_stderr_logger_init(WFD_LOGLEVEL_ALL, NULL));
|
||||
|
||||
WFD_FATAL("webfused test");
|
||||
WFD_ERROR("webfused test");
|
||||
WFD_WARN ("webfused test");
|
||||
WFD_INFO ("webfused test");
|
||||
WFD_DEBUG("webfused test");
|
||||
wfd_log(-1, "webfused test");
|
||||
|
||||
wfd_logger_close();
|
||||
}
|
51
test/log/syslog_logger.cc
Normal file
51
test/log/syslog_logger.cc
Normal file
@ -0,0 +1,51 @@
|
||||
#include "webfused/log/syslog_logger.h"
|
||||
#include "webfused/log/manager.h"
|
||||
#include "webfused/log/logger.h"
|
||||
#include "webfused/log/log.h"
|
||||
|
||||
#include "mock/settings.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <stddef.h>
|
||||
|
||||
using ::webfused_test::MockSettings;
|
||||
using ::testing::StrEq;
|
||||
using ::testing::_;
|
||||
using ::testing::Return;
|
||||
|
||||
TEST(syslog_logger, init)
|
||||
{
|
||||
ASSERT_TRUE(wfd_syslog_logger_init(WFD_LOGLEVEL_ALL, NULL));
|
||||
wfd_logger_close();
|
||||
}
|
||||
|
||||
TEST(syslog_logger, init_fail_invalid_facility)
|
||||
{
|
||||
MockSettings settings;
|
||||
EXPECT_CALL(settings, wfd_settings_get_string_or_default(_,StrEq("ident"), _)).Times(1).WillOnce(Return("webfused_test"));
|
||||
EXPECT_CALL(settings, wfd_settings_get_string_or_default(_,StrEq("facility"), _)).Times(1).WillOnce(Return("invalid"));
|
||||
EXPECT_CALL(settings, wfd_settings_get_bool(_,StrEq("log_pid"))).Times(1).WillOnce(Return(false));
|
||||
|
||||
wfd_settings * fake_settings = reinterpret_cast<wfd_settings*>(0xDEADBEEF);
|
||||
ASSERT_FALSE(wfd_syslog_logger_init(WFD_LOGLEVEL_ALL, fake_settings));
|
||||
}
|
||||
|
||||
TEST(syslog_logger, init_via_manager)
|
||||
{
|
||||
ASSERT_TRUE(wfd_log_manager_set_logger("syslog", WFD_LOGLEVEL_ALL, NULL));
|
||||
wfd_logger_close();
|
||||
}
|
||||
|
||||
TEST(syslog_logger, log)
|
||||
{
|
||||
ASSERT_TRUE(wfd_syslog_logger_init(WFD_LOGLEVEL_ALL, NULL));
|
||||
|
||||
WFD_FATAL("webfused test");
|
||||
WFD_ERROR("webfused test");
|
||||
WFD_WARN ("webfused test");
|
||||
WFD_INFO ("webfused test");
|
||||
WFD_DEBUG("webfused test");
|
||||
wfd_log(-1, "webfused test");
|
||||
|
||||
wfd_logger_close();
|
||||
}
|
40
test/mock/config_builder.cc
Normal file
40
test/mock/config_builder.cc
Normal file
@ -0,0 +1,40 @@
|
||||
#include "mock/config_builder.hpp"
|
||||
#include "util/wrap.hpp"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
static webfused_test::IConfigBuilder * wfd_MockConfigBuilder = nullptr;
|
||||
|
||||
WFD_WRAP_FUNC0(wfd_MockConfigBuilder, wfd_config *, wfd_config_create);
|
||||
WFD_WRAP_FUNC1(wfd_MockConfigBuilder, void, wfd_config_dispose, wfd_config *);
|
||||
WFD_WRAP_FUNC2(wfd_MockConfigBuilder, void, wfd_config_set_server_vhostname, wfd_config *, char const *);
|
||||
WFD_WRAP_FUNC2(wfd_MockConfigBuilder, void, wfd_config_set_server_port, wfd_config *, int);
|
||||
WFD_WRAP_FUNC2(wfd_MockConfigBuilder, void, wfd_config_set_server_key, wfd_config *, char const *);
|
||||
WFD_WRAP_FUNC2(wfd_MockConfigBuilder, void, wfd_config_set_server_cert, wfd_config *, char const *);
|
||||
WFD_WRAP_FUNC2(wfd_MockConfigBuilder, void, wfd_config_set_server_document_root, wfd_config *, char const *);
|
||||
WFD_WRAP_FUNC3(wfd_MockConfigBuilder, bool, wfd_config_add_auth_provider, wfd_config *, char const *, wfd_settings *);
|
||||
WFD_WRAP_FUNC4(wfd_MockConfigBuilder, bool, wfd_config_add_filesystem, wfd_config *, char const *, char const *, wfd_string_list *);
|
||||
WFD_WRAP_FUNC4(wfd_MockConfigBuilder, bool, wfd_config_set_logger, wfd_config *, char const *, int, wfd_settings *);
|
||||
WFD_WRAP_FUNC3(wfd_MockConfigBuilder, void, wfd_config_set_user, wfd_config *, char const *, char const *);
|
||||
}
|
||||
|
||||
namespace webfused_test
|
||||
{
|
||||
|
||||
MockConfigBuilder::MockConfigBuilder()
|
||||
{
|
||||
wfd_MockConfigBuilder = this;
|
||||
}
|
||||
|
||||
MockConfigBuilder::~MockConfigBuilder()
|
||||
{
|
||||
wfd_MockConfigBuilder = nullptr;
|
||||
}
|
||||
|
||||
struct wfd_config * MockConfigBuilder::getBuilder()
|
||||
{
|
||||
IConfigBuilder * config_builder = this;
|
||||
|
||||
return reinterpret_cast<wfd_config *>(config_builder);
|
||||
}
|
||||
}
|
49
test/mock/config_builder.hpp
Normal file
49
test/mock/config_builder.hpp
Normal file
@ -0,0 +1,49 @@
|
||||
#ifndef WFD_MOCK_CONFIG_BUILDER_HPP
|
||||
#define WFD_MOCK_CONFIG_BUILDER_HPP
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include "webfused/config/config_intern.h"
|
||||
|
||||
namespace webfused_test
|
||||
{
|
||||
|
||||
class IConfigBuilder
|
||||
{
|
||||
public:
|
||||
virtual ~IConfigBuilder() = default;
|
||||
virtual wfd_config * wfd_config_create(void) = 0;
|
||||
virtual void wfd_config_dispose(wfd_config * config) = 0;
|
||||
virtual void wfd_config_set_server_vhostname(wfd_config * config, char const * vhostname) = 0;
|
||||
virtual void wfd_config_set_server_port(wfd_config * config, int port) = 0;
|
||||
virtual void wfd_config_set_server_key(wfd_config * config, char const * key_path) = 0;
|
||||
virtual void wfd_config_set_server_cert(wfd_config * config, char const * cert_path) = 0;
|
||||
virtual void wfd_config_set_server_document_root(wfd_config * config, char const * document_root) = 0;
|
||||
virtual bool wfd_config_add_auth_provider(wfd_config * config, char const * provider, wfd_settings * settings) = 0;
|
||||
virtual bool wfd_config_add_filesystem(wfd_config * config, char const * name, char const * mountpoint, wfd_string_list const * mount_options) = 0;
|
||||
virtual bool wfd_config_set_logger(wfd_config * config, char const * provider, int level, wfd_settings * settings) = 0;
|
||||
virtual void wfd_config_set_user(wfd_config * config, char const * user, char const * group) = 0;
|
||||
};
|
||||
|
||||
class MockConfigBuilder: public IConfigBuilder
|
||||
{
|
||||
public:
|
||||
MockConfigBuilder();
|
||||
~MockConfigBuilder() override;
|
||||
MOCK_METHOD0(wfd_config_create, wfd_config * (void));
|
||||
MOCK_METHOD1(wfd_config_dispose, void (wfd_config * config));
|
||||
MOCK_METHOD2(wfd_config_set_server_vhostname, void (wfd_config * config, char const * vhostname));
|
||||
MOCK_METHOD2(wfd_config_set_server_port, void (wfd_config * config, int port));
|
||||
MOCK_METHOD2(wfd_config_set_server_key, void (wfd_config * config, char const * key_path));
|
||||
MOCK_METHOD2(wfd_config_set_server_cert, void (wfd_config * config, char const * cert_path));
|
||||
MOCK_METHOD2(wfd_config_set_server_document_root, void (wfd_config * config, char const * document_root));
|
||||
MOCK_METHOD3(wfd_config_add_auth_provider, bool (wfd_config * config, char const * provider, wfd_settings * settings));
|
||||
MOCK_METHOD4(wfd_config_add_filesystem, bool (wfd_config * config, char const * name, char const * mountpoint, wfd_string_list const * mount_options));
|
||||
MOCK_METHOD4(wfd_config_set_logger, bool (wfd_config * config, char const * provider, int level, wfd_settings * settings));
|
||||
MOCK_METHOD3(wfd_config_set_user, void (wfd_config * config, char const * user, char const * group));
|
||||
|
||||
struct wfd_config * getBuilder();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
26
test/mock/credentials.cc
Normal file
26
test/mock/credentials.cc
Normal file
@ -0,0 +1,26 @@
|
||||
#include "mock/credentials.hpp"
|
||||
#include "util/wrap.hpp"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
static webfused_test::ICredentials * wfd_MockCredentials = nullptr;
|
||||
|
||||
WFD_WRAP_FUNC1(wfd_MockCredentials, char const *, wf_credentials_type, struct wf_credentials const *);
|
||||
WFD_WRAP_FUNC2(wfd_MockCredentials, char const *, wf_credentials_get, struct wf_credentials const *, char const *);
|
||||
}
|
||||
|
||||
|
||||
namespace webfused_test
|
||||
{
|
||||
|
||||
MockCredentials::MockCredentials()
|
||||
{
|
||||
wfd_MockCredentials = this;
|
||||
}
|
||||
|
||||
MockCredentials::~MockCredentials()
|
||||
{
|
||||
wfd_MockCredentials = nullptr;
|
||||
}
|
||||
|
||||
}
|
29
test/mock/credentials.hpp
Normal file
29
test/mock/credentials.hpp
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef WFD_MOCK_CREDENTIALS_HPP
|
||||
#define WFD_MOCK_CREDENTIALS_HPP
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include "webfuse/credentials.h"
|
||||
|
||||
namespace webfused_test
|
||||
{
|
||||
|
||||
class ICredentials
|
||||
{
|
||||
public:
|
||||
virtual ~ICredentials() = default;
|
||||
virtual char const * wf_credentials_type(struct wf_credentials const * credentials) = 0;
|
||||
virtual char const * wf_credentials_get(struct wf_credentials const * credentials, char const * key) = 0;
|
||||
};
|
||||
|
||||
class MockCredentials: public ICredentials
|
||||
{
|
||||
public:
|
||||
MockCredentials();
|
||||
virtual ~MockCredentials();
|
||||
MOCK_METHOD1(wf_credentials_type, char const*(struct wf_credentials const * credentials));
|
||||
MOCK_METHOD2(wf_credentials_get, char const *(struct wf_credentials const * credentials, char const * key));
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
27
test/mock/libconfig.cc
Normal file
27
test/mock/libconfig.cc
Normal file
@ -0,0 +1,27 @@
|
||||
#include "mock/libconfig.hpp"
|
||||
#include "util/wrap.hpp"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
static webfused_test::ILibConfig * wfd_MockLibConfig = nullptr;
|
||||
|
||||
WFD_WRAP_FUNC2(wfd_MockLibConfig, config_setting_t *, config_setting_get_elem,
|
||||
config_setting_t const *, unsigned int);
|
||||
|
||||
}
|
||||
|
||||
namespace webfused_test
|
||||
{
|
||||
|
||||
MockLibConfig::MockLibConfig()
|
||||
{
|
||||
wfd_MockLibConfig = this;
|
||||
}
|
||||
|
||||
MockLibConfig::~MockLibConfig()
|
||||
{
|
||||
wfd_MockLibConfig = nullptr;
|
||||
}
|
||||
|
||||
}
|
32
test/mock/libconfig.hpp
Normal file
32
test/mock/libconfig.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef WFD_MOCK_LIBCONFIG_HPP
|
||||
#define WFD_MOCK_LIBCONFIG_HPP
|
||||
|
||||
#include <libconfig.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
namespace webfused_test
|
||||
{
|
||||
|
||||
class ILibConfig
|
||||
{
|
||||
public:
|
||||
virtual ~ILibConfig() = default;
|
||||
virtual config_setting_t * config_setting_get_elem(
|
||||
config_setting_t const * setting,
|
||||
unsigned int i) = 0;
|
||||
};
|
||||
|
||||
class MockLibConfig: public ILibConfig
|
||||
{
|
||||
public:
|
||||
MockLibConfig();
|
||||
~MockLibConfig() override;
|
||||
MOCK_METHOD2(config_setting_get_elem, config_setting_t * (
|
||||
config_setting_t const * setting,
|
||||
unsigned int i));
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
31
test/mock/linux.cc
Normal file
31
test/mock/linux.cc
Normal file
@ -0,0 +1,31 @@
|
||||
#include "mock/linux.hpp"
|
||||
#include "util/wrap.hpp"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
static webfused_test::ILinux * wfd_MockLinux = nullptr;
|
||||
|
||||
WFD_WRAP_FUNC0( wfd_MockLinux, uid_t, getuid);
|
||||
WFD_WRAP_FUNC1( wfd_MockLinux, struct group *, getgrnam, char const *);
|
||||
WFD_WRAP_FUNC1( wfd_MockLinux, int, setgid, gid_t);
|
||||
WFD_WRAP_FUNC2( wfd_MockLinux, int, setgroups, int, gid_t *);
|
||||
WFD_WRAP_FUNC1( wfd_MockLinux, struct passwd *, getpwnam, char const *);
|
||||
WFD_WRAP_FUNC1( wfd_MockLinux, int, setuid, uid_t);
|
||||
|
||||
}
|
||||
|
||||
namespace webfused_test
|
||||
{
|
||||
|
||||
MockLinux::MockLinux()
|
||||
{
|
||||
wfd_MockLinux = this;
|
||||
}
|
||||
|
||||
MockLinux::~MockLinux()
|
||||
{
|
||||
wfd_MockLinux = nullptr;
|
||||
}
|
||||
|
||||
}
|
41
test/mock/linux.hpp
Normal file
41
test/mock/linux.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef WFD_MOCK_LINUX_HPP
|
||||
#define WFD_MOCK_LINUX_HPP
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
namespace webfused_test
|
||||
{
|
||||
|
||||
class ILinux
|
||||
{
|
||||
public:
|
||||
virtual ~ILinux() = default;
|
||||
virtual uid_t getuid() = 0;
|
||||
virtual struct group * getgrnam(char const * name) = 0;
|
||||
virtual int setgid(gid_t gid) = 0;
|
||||
virtual int setgroups(int size, gid_t * list) = 0;
|
||||
virtual struct passwd * getpwnam(char const * name) = 0;
|
||||
virtual int setuid(uid_t uid) = 0;
|
||||
};
|
||||
|
||||
class MockLinux: public ILinux
|
||||
{
|
||||
public:
|
||||
MockLinux();
|
||||
~MockLinux();
|
||||
MOCK_METHOD0(getuid, uid_t());
|
||||
MOCK_METHOD1(getgrnam, struct group * (char const * name));
|
||||
MOCK_METHOD1(setgid, int (gid_t gid));
|
||||
MOCK_METHOD2(setgroups, int (int size, gid_t * list));
|
||||
MOCK_METHOD1(getpwnam, struct passwd * (char const * name));
|
||||
MOCK_METHOD1(setuid, int (uid_t uid));
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
58
test/mock/logger.cc
Normal file
58
test/mock/logger.cc
Normal file
@ -0,0 +1,58 @@
|
||||
#include "mock/logger.hpp"
|
||||
#include "webfused/log/logger.h"
|
||||
#include "webfused/log/log.h"
|
||||
|
||||
namespace webfused_test
|
||||
{
|
||||
|
||||
MockLogger::MockLogger(bool omit_init)
|
||||
: close_on_destruct(!omit_init)
|
||||
{
|
||||
if (!omit_init)
|
||||
{
|
||||
wfd_logger_init(
|
||||
WFD_LOGLEVEL_ALL,
|
||||
&wfd_MockLogger_log,
|
||||
&wfd_MockLogger_onclose,
|
||||
getUserData());
|
||||
}
|
||||
}
|
||||
|
||||
MockLogger::~MockLogger()
|
||||
{
|
||||
if (close_on_destruct)
|
||||
{
|
||||
wfd_logger_close();
|
||||
}
|
||||
}
|
||||
|
||||
void * MockLogger::getUserData()
|
||||
{
|
||||
ILogger * logger = this;
|
||||
return reinterpret_cast<void*>(logger);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
using webfused_test::ILogger;
|
||||
|
||||
void wfd_MockLogger_log(
|
||||
void * user_data,
|
||||
int level,
|
||||
char const * format,
|
||||
va_list args)
|
||||
{
|
||||
ILogger * logger = reinterpret_cast<ILogger*>(user_data);
|
||||
logger->log(level, format, args);
|
||||
}
|
||||
|
||||
void wfd_MockLogger_onclose(
|
||||
void * user_data)
|
||||
{
|
||||
ILogger * logger = reinterpret_cast<ILogger*>(user_data);
|
||||
logger->onclose();
|
||||
}
|
||||
|
||||
}
|
47
test/mock/logger.hpp
Normal file
47
test/mock/logger.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef WFD_MOCK_LOGGER_HPP
|
||||
#define WFD_MOCK_LOGGER_HPP
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <cstdarg>
|
||||
|
||||
namespace webfused_test
|
||||
{
|
||||
|
||||
class ILogger
|
||||
{
|
||||
public:
|
||||
virtual ~ILogger() = default;
|
||||
virtual void log(int level, char const * format, va_list args) = 0;
|
||||
virtual void onclose() = 0;
|
||||
};
|
||||
|
||||
class MockLogger: public ILogger
|
||||
{
|
||||
public:
|
||||
explicit MockLogger(bool omit_init = false);
|
||||
~MockLogger() override;
|
||||
MOCK_METHOD3(log, void(int level, char const * format, va_list args));
|
||||
MOCK_METHOD0(onclose, void(void));
|
||||
|
||||
void * getUserData();
|
||||
private:
|
||||
bool close_on_destruct;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
extern void wfd_MockLogger_log(
|
||||
void * user_data,
|
||||
int level,
|
||||
char const * format,
|
||||
va_list args);
|
||||
|
||||
extern void wfd_MockLogger_onclose(
|
||||
void * user_data);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
29
test/mock/pam.cc
Normal file
29
test/mock/pam.cc
Normal file
@ -0,0 +1,29 @@
|
||||
#include "mock/pam.hpp"
|
||||
#include "util/wrap.hpp"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
static webfused_test::IPam * wfd_MockPam = nullptr;
|
||||
|
||||
WFD_WRAP_FUNC4(wfd_MockPam, int, pam_start, char const *, char const *, struct pam_conv const *, pam_handle_t **);
|
||||
WFD_WRAP_FUNC2(wfd_MockPam, int, pam_end, pam_handle_t *, int);
|
||||
WFD_WRAP_FUNC2(wfd_MockPam, int, pam_authenticate, pam_handle_t *, int);
|
||||
WFD_WRAP_FUNC2(wfd_MockPam, int, pam_acct_mgmt, pam_handle_t *, int);
|
||||
WFD_WRAP_FUNC2(wfd_MockPam, char const *, pam_strerror, pam_handle_t *, int);
|
||||
|
||||
}
|
||||
|
||||
namespace webfused_test
|
||||
{
|
||||
|
||||
MockPam::MockPam()
|
||||
{
|
||||
wfd_MockPam = this;
|
||||
}
|
||||
|
||||
MockPam::~MockPam()
|
||||
{
|
||||
wfd_MockPam = nullptr;
|
||||
}
|
||||
|
||||
}
|
45
test/mock/pam.hpp
Normal file
45
test/mock/pam.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef WFD_MOCK_PAM_HPP
|
||||
#define WFD_MOCK_PAM_HPP
|
||||
|
||||
#include <security/pam_appl.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
namespace webfused_test
|
||||
{
|
||||
|
||||
class IPam
|
||||
{
|
||||
public:
|
||||
virtual ~IPam() = default;
|
||||
virtual int pam_start(
|
||||
char const * service_name,
|
||||
char const * user,
|
||||
struct pam_conv const * conversation,
|
||||
pam_handle_t * * handle) = 0;
|
||||
virtual int pam_end(pam_handle_t * handle, int status) = 0;
|
||||
virtual int pam_authenticate(pam_handle_t * handle, int flags) = 0;
|
||||
virtual int pam_acct_mgmt(pam_handle_t * handle, int flags) = 0;
|
||||
virtual char const * pam_strerror(pam_handle_t * handle, int errnum) = 0;
|
||||
};
|
||||
|
||||
class MockPam: public IPam
|
||||
{
|
||||
public:
|
||||
MockPam();
|
||||
~MockPam() override;
|
||||
|
||||
MOCK_METHOD4(pam_start, int (
|
||||
char const * service_name,
|
||||
char const * user,
|
||||
struct pam_conv const * conversation,
|
||||
pam_handle_t * * handle));
|
||||
|
||||
MOCK_METHOD2(pam_end, int(pam_handle_t * handle, int status));
|
||||
MOCK_METHOD2(pam_authenticate, int(pam_handle_t * handle, int flags));
|
||||
MOCK_METHOD2(pam_acct_mgmt, int (pam_handle_t * handle, int flags));
|
||||
MOCK_METHOD2(pam_strerror, char const * (pam_handle_t * handle, int errnum));
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
25
test/mock/server.cc
Normal file
25
test/mock/server.cc
Normal file
@ -0,0 +1,25 @@
|
||||
#include "mock/server.hpp"
|
||||
#include "util/wrap.hpp"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
static webfused_test::IServer * wfd_MockServer = nullptr;
|
||||
|
||||
WFD_WRAP_FUNC1(wfd_MockServer, struct wf_server *, wf_server_create, struct wf_server_config *);
|
||||
|
||||
}
|
||||
|
||||
namespace webfused_test
|
||||
{
|
||||
|
||||
MockServer::MockServer()
|
||||
{
|
||||
wfd_MockServer = this;
|
||||
}
|
||||
|
||||
MockServer::~MockServer()
|
||||
{
|
||||
wfd_MockServer = nullptr;
|
||||
}
|
||||
|
||||
}
|
28
test/mock/server.hpp
Normal file
28
test/mock/server.hpp
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef WFD_MOCK_SERVER_HPP
|
||||
#define WFD_MOCK_SERVER_HPP
|
||||
|
||||
#include <webfuse/server.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
namespace webfused_test
|
||||
{
|
||||
|
||||
class IServer
|
||||
{
|
||||
public:
|
||||
virtual ~IServer() = default;
|
||||
virtual struct wf_server * wf_server_create(struct wf_server_config * config) = 0;
|
||||
};
|
||||
|
||||
class MockServer: public IServer
|
||||
{
|
||||
public:
|
||||
MockServer();
|
||||
~MockServer() override;
|
||||
MOCK_METHOD1(wf_server_create, struct wf_server * (struct wf_server_config * config));
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
27
test/mock/settings.cc
Normal file
27
test/mock/settings.cc
Normal file
@ -0,0 +1,27 @@
|
||||
#include "mock/settings.hpp"
|
||||
#include "util/wrap.hpp"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
static webfused_test::ISettings * wfd_MockSettings = nullptr;
|
||||
|
||||
WFD_WRAP_FUNC2(wfd_MockSettings, char const *, wfd_settings_get_string, struct wfd_settings *, char const *);
|
||||
WFD_WRAP_FUNC3(wfd_MockSettings, char const *, wfd_settings_get_string_or_default,
|
||||
struct wfd_settings *, char const *, char const *);
|
||||
WFD_WRAP_FUNC2(wfd_MockSettings, bool, wfd_settings_get_bool, struct wfd_settings *, char const *);
|
||||
}
|
||||
|
||||
namespace webfused_test
|
||||
{
|
||||
|
||||
MockSettings::MockSettings()
|
||||
{
|
||||
wfd_MockSettings = this;
|
||||
}
|
||||
|
||||
MockSettings::~MockSettings()
|
||||
{
|
||||
wfd_MockSettings = nullptr;
|
||||
}
|
||||
|
||||
}
|
33
test/mock/settings.hpp
Normal file
33
test/mock/settings.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef WFD_MOCK_AUTH_SETTINGS_HPP
|
||||
#define WFD_MOCK_AUTH_SETTINGS_HPP
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include "webfused/config/settings.h"
|
||||
|
||||
namespace webfused_test
|
||||
{
|
||||
|
||||
class ISettings
|
||||
{
|
||||
public:
|
||||
virtual ~ISettings() = default;
|
||||
virtual char const * wfd_settings_get_string(wfd_settings * settings, char const * key) = 0;
|
||||
virtual char const * wfd_settings_get_string_or_default(wfd_settings * settings, char const * key, char const * default_value) = 0;
|
||||
virtual bool wfd_settings_get_bool(wfd_settings * settings, char const * key) = 0;
|
||||
};
|
||||
|
||||
class MockSettings: public ISettings
|
||||
{
|
||||
public:
|
||||
MockSettings();
|
||||
~MockSettings() override;
|
||||
MOCK_METHOD2(wfd_settings_get_string, char const * (wfd_settings * settings, char const * key));
|
||||
MOCK_METHOD3(wfd_settings_get_string_or_default, char const * (wfd_settings * settings, char const * key, char const * default_value));
|
||||
MOCK_METHOD2(wfd_settings_get_bool, bool (wfd_settings * settings, char const * key));
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
144
test/mountpoint_factory.cc
Normal file
144
test/mountpoint_factory.cc
Normal file
@ -0,0 +1,144 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "webfused/mountpoint_factory.h"
|
||||
#include "webfused/util/string_list.h"
|
||||
#include <webfuse/mountpoint.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
TEST(mountpoint_factory, create)
|
||||
{
|
||||
wfd_mountpoint_factory * factory = wfd_mountpoint_factory_create();
|
||||
ASSERT_NE(nullptr, factory);
|
||||
|
||||
wfd_mountpoint_factory_dispose(factory);
|
||||
}
|
||||
|
||||
TEST(mountpiont_factory, add_filesystem)
|
||||
{
|
||||
wfd_mountpoint_factory * factory = wfd_mountpoint_factory_create();
|
||||
ASSERT_NE(nullptr, factory);
|
||||
|
||||
struct wfd_string_list mount_options = {0, 0, nullptr};
|
||||
bool success = wfd_mountpoint_factory_add_filesystem(factory, "test", "/tmp/webfused_test", &mount_options);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
wfd_mountpoint_factory_dispose(factory);
|
||||
}
|
||||
|
||||
TEST(mountpiont_factory, add_filesystem_fail_to_add_twice)
|
||||
{
|
||||
wfd_mountpoint_factory * factory = wfd_mountpoint_factory_create();
|
||||
ASSERT_NE(nullptr, factory);
|
||||
|
||||
struct wfd_string_list mount_options = {0, 0, nullptr};
|
||||
bool success = wfd_mountpoint_factory_add_filesystem(factory, "test", "/tmp/webfused_test", &mount_options);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
success = wfd_mountpoint_factory_add_filesystem(factory, "test", "/tmp/webfused_test", &mount_options);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
wfd_mountpoint_factory_dispose(factory);
|
||||
}
|
||||
|
||||
TEST(mountpiont_factory, add_filesystem_multi)
|
||||
{
|
||||
wfd_mountpoint_factory * factory = wfd_mountpoint_factory_create();
|
||||
ASSERT_NE(nullptr, factory);
|
||||
|
||||
|
||||
for (size_t i = 0; i < 24; i++)
|
||||
{
|
||||
char name[10];
|
||||
snprintf(name, 10, "test_%zu", i);
|
||||
struct wfd_string_list mount_options = {0, 0, nullptr};
|
||||
bool success = wfd_mountpoint_factory_add_filesystem(factory, name, "/tmp/webfused_test", &mount_options);
|
||||
ASSERT_TRUE(success) << i;
|
||||
}
|
||||
|
||||
wfd_mountpoint_factory_dispose(factory);
|
||||
}
|
||||
|
||||
TEST(mountpiont_factory, add_filesystem_fail_invalid_path)
|
||||
{
|
||||
wfd_mountpoint_factory * factory = wfd_mountpoint_factory_create();
|
||||
ASSERT_NE(nullptr, factory);
|
||||
|
||||
struct wfd_string_list mount_options = {0, 0, nullptr};
|
||||
bool success = wfd_mountpoint_factory_add_filesystem(factory, "test", "/do/not/allow/nested/paths", &mount_options);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
wfd_mountpoint_factory_dispose(factory);
|
||||
}
|
||||
|
||||
TEST(mountpiont_factory, create_mountpoint)
|
||||
{
|
||||
wfd_mountpoint_factory * factory = wfd_mountpoint_factory_create();
|
||||
ASSERT_NE(nullptr, factory);
|
||||
|
||||
struct wfd_string_list mount_options = {0, 0, nullptr};
|
||||
bool success = wfd_mountpoint_factory_add_filesystem(factory, "test", "/tmp/webfuse_test", &mount_options);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
wf_mountpoint * mountpoint = wfd_mountpoint_factory_create_mountpoint("test", factory);
|
||||
ASSERT_NE(nullptr, mountpoint);
|
||||
ASSERT_STREQ("/tmp/webfuse_test", wf_mountpoint_get_path(mountpoint));
|
||||
|
||||
wf_mountpoint_dispose(mountpoint);
|
||||
wfd_mountpoint_factory_dispose(factory);
|
||||
}
|
||||
|
||||
TEST(mountpiont_factory, create_mountpoint_fail_already_in_use)
|
||||
{
|
||||
wfd_mountpoint_factory * factory = wfd_mountpoint_factory_create();
|
||||
ASSERT_NE(nullptr, factory);
|
||||
|
||||
struct wfd_string_list mount_options = {0, 0, nullptr};
|
||||
bool success = wfd_mountpoint_factory_add_filesystem(factory, "test", "/tmp/webfuse_test", &mount_options);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
wf_mountpoint * mountpoint = wfd_mountpoint_factory_create_mountpoint("test", factory);
|
||||
ASSERT_NE(nullptr, mountpoint);
|
||||
ASSERT_STREQ("/tmp/webfuse_test", wf_mountpoint_get_path(mountpoint));
|
||||
|
||||
wf_mountpoint * mountpoint2 = wfd_mountpoint_factory_create_mountpoint("test", factory);
|
||||
ASSERT_EQ(nullptr, mountpoint2);
|
||||
|
||||
wf_mountpoint_dispose(mountpoint);
|
||||
wfd_mountpoint_factory_dispose(factory);
|
||||
}
|
||||
|
||||
TEST(mountpiont_factory, create_mountpoint_fail_unknown_filesystem)
|
||||
{
|
||||
wfd_mountpoint_factory * factory = wfd_mountpoint_factory_create();
|
||||
ASSERT_NE(nullptr, factory);
|
||||
|
||||
struct wfd_string_list mount_options = {0, 0, nullptr};
|
||||
bool success = wfd_mountpoint_factory_add_filesystem(factory, "test", "/tmp/webfuse_test", &mount_options);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
wf_mountpoint * mountpoint = wfd_mountpoint_factory_create_mountpoint("unkown", factory);
|
||||
ASSERT_EQ(nullptr, mountpoint);
|
||||
|
||||
wfd_mountpoint_factory_dispose(factory);
|
||||
}
|
||||
|
||||
TEST(mountpiont_factory, create_mountpoint_multi)
|
||||
{
|
||||
wfd_mountpoint_factory * factory = wfd_mountpoint_factory_create();
|
||||
ASSERT_NE(nullptr, factory);
|
||||
|
||||
struct wfd_string_list mount_options = {0, 0, nullptr};
|
||||
bool success = wfd_mountpoint_factory_add_filesystem(factory, "test", "/tmp/webfuse_test", &mount_options);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
for(int i = 0; i < 5; i++)
|
||||
{
|
||||
wf_mountpoint * mountpoint = wfd_mountpoint_factory_create_mountpoint("test", factory);
|
||||
ASSERT_NE(nullptr, mountpoint) << i;
|
||||
ASSERT_STREQ("/tmp/webfuse_test", wf_mountpoint_get_path(mountpoint)) << i;
|
||||
|
||||
wf_mountpoint_dispose(mountpoint);
|
||||
}
|
||||
|
||||
wfd_mountpoint_factory_dispose(factory);
|
||||
}
|
14
test/test_passwd.json
Normal file
14
test/test_passwd.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"meta": {
|
||||
"type": "wf-userdb",
|
||||
"major": 1,
|
||||
"minor": 0,
|
||||
"hash_algorithm": "sha512"
|
||||
},
|
||||
"users": {
|
||||
"bob": {
|
||||
"password_hash": "e51e27ce47054feead3d83068d47f2a07307d4877ac67da668ef43e0e466fe8c7b66651af14fdb8d48c51592ef5afa0c63f874d20861c6b9ef8e6513bfcaa330",
|
||||
"salt": "b3be6979921edecfea88c50d0d1ec40b7f8c383831b2276c65969ead18e47c03"
|
||||
}
|
||||
}
|
||||
}
|
407
test/userdb.cc
Normal file
407
test/userdb.cc
Normal file
@ -0,0 +1,407 @@
|
||||
#include "userdb/userdb.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(userdb, load_file)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
|
||||
bool success = userdb_load_file(db, "test_passwd.json");
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
ASSERT_TRUE(userdb_check(db, "bob", "secret"));
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_file_failed_no_file)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
|
||||
bool success = userdb_load_file(db, "non_existing.json");
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, save)
|
||||
{
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
userdb_add(db, "bob", "secret");
|
||||
ASSERT_TRUE(userdb_save(db, "/tmp/webfused_test.json"));
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
ASSERT_TRUE(userdb_load_file(db, "/tmp/webfused_test.json"));
|
||||
ASSERT_TRUE(userdb_check(db, "bob", "secret"));
|
||||
userdb_dispose(db);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(userdb, add)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
|
||||
userdb_add(db, "bob", "secret");
|
||||
ASSERT_TRUE(userdb_check(db, "bob", "secret"));
|
||||
ASSERT_FALSE(userdb_check(db, "bob", "i_dont_know"));
|
||||
ASSERT_FALSE(userdb_check(db, "anna", "secret"));
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, remove)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
ASSERT_NE(nullptr, db);
|
||||
|
||||
userdb_add(db, "bob", "secret");
|
||||
ASSERT_TRUE(userdb_check(db, "bob", "secret"));
|
||||
|
||||
userdb_remove(db, "bob");
|
||||
ASSERT_FALSE(userdb_check(db, "bob", "secret"));
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, update)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
ASSERT_NE(nullptr, db);
|
||||
|
||||
userdb_add(db, "bob", "secret");
|
||||
ASSERT_TRUE(userdb_check(db, "bob", "secret"));
|
||||
|
||||
userdb_add(db, "bob", "new_secret");
|
||||
ASSERT_FALSE(userdb_check(db, "bob", "secret"));
|
||||
ASSERT_TRUE(userdb_check(db, "bob", "new_secret"));
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_string)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"wf-userdb\","
|
||||
" \"major\": 1,"
|
||||
" \"minor\": 0,"
|
||||
" \"hash_algorithm\": \"sha512\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_no_json)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] = "brummni";
|
||||
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_invalid_type)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"any-userdb\","
|
||||
" \"major\": 1,"
|
||||
" \"minor\": 0,"
|
||||
" \"hash_algorithm\": \"sha512\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_invalid_version)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"wf-userdb\","
|
||||
" \"major\": 2,"
|
||||
" \"minor\": 0,"
|
||||
" \"hash_algorithm\": \"sha512\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_missing_type)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"major\": 1,"
|
||||
" \"minor\": 0,"
|
||||
" \"hash_algorithm\": \"sha512\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_type_not_string)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": 42,"
|
||||
" \"major\": 1,"
|
||||
" \"minor\": 0,"
|
||||
" \"hash_algorithm\": \"sha512\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_missing_major_version)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"wf-userdb\","
|
||||
" \"minor\": 0,"
|
||||
" \"hash_algorithm\": \"sha512\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_major_version_not_int)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"wf-userdb\","
|
||||
" \"major\": false,"
|
||||
" \"minor\": 0,"
|
||||
" \"hash_algorithm\": \"sha512\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_missing_minor_version)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"wf-userdb\","
|
||||
" \"major\": 1,"
|
||||
" \"hash_algorithm\": \"sha512\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_minor_version_not_int)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"wf-userdb\","
|
||||
" \"major\": 1,"
|
||||
" \"minor\": false,"
|
||||
" \"hash_algorithm\": \"sha512\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_missing_hash_alg)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"wf-userdb\","
|
||||
" \"major\": 1,"
|
||||
" \"minor\": 0,"
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_hash_alg_not_string)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"wf-userdb\","
|
||||
" \"major\": 1,"
|
||||
" \"minor\": 0,"
|
||||
" \"hash_algorithm\": 42"
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_missing_meta)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, load_fail_unsupported_hash)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"wf-userdb\","
|
||||
" \"major\": 1,"
|
||||
" \"minor\": 0,"
|
||||
" \"hash_algorithm\": \"brummni\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_FALSE(success);
|
||||
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, fail_missing_user_salt)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"wf-userdb\","
|
||||
" \"major\": 1,"
|
||||
" \"minor\": 0,"
|
||||
" \"hash_algorithm\": \"sha512\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
" \"bob\": {"
|
||||
" \"password_hash\": \"e51e27ce47054feead3d83068d47f2a07307d4877ac67da668ef43e0e466fe8c7b66651af14fdb8d48c51592ef5afa0c63f874d20861c6b9ef8e6513bfcaa330\""
|
||||
" }"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
ASSERT_FALSE(userdb_check(db, "bob", "secret"));
|
||||
userdb_dispose(db);
|
||||
}
|
||||
|
||||
TEST(userdb, fail_missing_user_hash)
|
||||
{
|
||||
userdb * db = userdb_create("");
|
||||
char const contents[] =
|
||||
"{"
|
||||
"\"meta\": {"
|
||||
" \"type\": \"wf-userdb\","
|
||||
" \"major\": 1,"
|
||||
" \"minor\": 0,"
|
||||
" \"hash_algorithm\": \"sha512\""
|
||||
"},"
|
||||
"\"users\": {"
|
||||
" \"bob\": {"
|
||||
" \"salt\": \"b3be6979921edecfea88c50d0d1ec40b7f8c383831b2276c65969ead18e47c03\""
|
||||
" }"
|
||||
"}"
|
||||
"}"
|
||||
;
|
||||
bool success = userdb_load_string(db, contents);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
ASSERT_FALSE(userdb_check(db, "bob", "secret"));
|
||||
userdb_dispose(db);
|
||||
}
|
44
test/util/string_list.cc
Normal file
44
test/util/string_list.cc
Normal file
@ -0,0 +1,44 @@
|
||||
#include "webfused/util/string_list.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(string_list, init_cleanup)
|
||||
{
|
||||
wfd_string_list list;
|
||||
wfd_string_list_init(&list);
|
||||
|
||||
ASSERT_EQ(0, list.size);
|
||||
|
||||
wfd_string_list_cleanup(&list);
|
||||
}
|
||||
|
||||
TEST(string_list, add)
|
||||
{
|
||||
wfd_string_list list;
|
||||
wfd_string_list_init(&list);
|
||||
wfd_string_list_add(&list, "value");
|
||||
|
||||
ASSERT_EQ(1, list.size);
|
||||
ASSERT_STREQ("value", list.items[0]);
|
||||
|
||||
wfd_string_list_cleanup(&list);
|
||||
}
|
||||
|
||||
TEST(string_list, add_many)
|
||||
{
|
||||
wfd_string_list list;
|
||||
wfd_string_list_init(&list);
|
||||
|
||||
constexpr size_t count = 256;
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
wfd_string_list_add(&list, "value");
|
||||
}
|
||||
|
||||
ASSERT_EQ(count, list.size);
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
ASSERT_STREQ("value", list.items[i]);
|
||||
}
|
||||
|
||||
wfd_string_list_cleanup(&list);
|
||||
}
|
74
test/util/wrap.hpp
Normal file
74
test/util/wrap.hpp
Normal file
@ -0,0 +1,74 @@
|
||||
#ifndef WFD_UTIL_WRAP_HPP
|
||||
#define WFD_UTIL_WRAP_HPP
|
||||
|
||||
#define WFD_WRAP_FUNC0( GLOBAL_VAR, RETURN_TYPE, FUNC_NAME ) \
|
||||
extern RETURN_TYPE __real_ ## FUNC_NAME (); \
|
||||
RETURN_TYPE __wrap_ ## FUNC_NAME () \
|
||||
{ \
|
||||
if (nullptr == GLOBAL_VAR ) \
|
||||
{ \
|
||||
return __real_ ## FUNC_NAME (); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
return GLOBAL_VAR -> FUNC_NAME(); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define WFD_WRAP_FUNC1( GLOBAL_VAR, RETURN_TYPE, FUNC_NAME, ARG1_TYPE ) \
|
||||
extern RETURN_TYPE __real_ ## FUNC_NAME (ARG1_TYPE); \
|
||||
RETURN_TYPE __wrap_ ## FUNC_NAME (ARG1_TYPE arg1) \
|
||||
{ \
|
||||
if (nullptr == GLOBAL_VAR ) \
|
||||
{ \
|
||||
return __real_ ## FUNC_NAME (arg1); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
return GLOBAL_VAR -> FUNC_NAME(arg1); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define WFD_WRAP_FUNC2( GLOBAL_VAR, RETURN_TYPE, FUNC_NAME, ARG1_TYPE, ARG2_TYPE ) \
|
||||
extern RETURN_TYPE __real_ ## FUNC_NAME (ARG1_TYPE, ARG2_TYPE); \
|
||||
RETURN_TYPE __wrap_ ## FUNC_NAME (ARG1_TYPE arg1, ARG2_TYPE arg2) \
|
||||
{ \
|
||||
if (nullptr == GLOBAL_VAR ) \
|
||||
{ \
|
||||
return __real_ ## FUNC_NAME (arg1, arg2); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
return GLOBAL_VAR -> FUNC_NAME(arg1, arg2); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define WFD_WRAP_FUNC3( GLOBAL_VAR, RETURN_TYPE, FUNC_NAME, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE ) \
|
||||
extern RETURN_TYPE __real_ ## FUNC_NAME (ARG1_TYPE, ARG2_TYPE, ARG3_TYPE); \
|
||||
RETURN_TYPE __wrap_ ## FUNC_NAME (ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3) \
|
||||
{ \
|
||||
if (nullptr == GLOBAL_VAR ) \
|
||||
{ \
|
||||
return __real_ ## FUNC_NAME (arg1, arg2, arg3); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
return GLOBAL_VAR -> FUNC_NAME(arg1, arg2, arg3); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define WFD_WRAP_FUNC4( GLOBAL_VAR, RETURN_TYPE, FUNC_NAME, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE ) \
|
||||
extern RETURN_TYPE __real_ ## FUNC_NAME (ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE); \
|
||||
RETURN_TYPE __wrap_ ## FUNC_NAME (ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4) \
|
||||
{ \
|
||||
if (nullptr == GLOBAL_VAR ) \
|
||||
{ \
|
||||
return __real_ ## FUNC_NAME (arg1, arg2, arg3, arg4); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
return GLOBAL_VAR -> FUNC_NAME(arg1, arg2, arg3, arg4); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user