mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 12:37:00 +01:00
Windows build support (#903)
`kanidmd` builds and runs in Windows now. Currently skipping file permissions checks on startup, but it's tested OK on a Windows 10 box.
This commit is contained in:
parent
4830479bd5
commit
fedc21ddca
4
.github/workflows/windows_build.yml
vendored
4
.github/workflows/windows_build.yml
vendored
|
@ -28,7 +28,7 @@ jobs:
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: build
|
command: build
|
||||||
args: --release -p kanidm_client -p kanidm_tools -p orca
|
args: --release -p kanidm_client -p kanidm_tools -p orca -p daemon
|
||||||
windows_test_kanidm:
|
windows_test_kanidm:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
steps:
|
steps:
|
||||||
|
@ -47,4 +47,4 @@ jobs:
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: test
|
command: test
|
||||||
args: -p kanidm_client -p kanidm_tools -p orca
|
args: -p kanidm_client -p kanidm_tools -p orca -p daemon -p score
|
||||||
|
|
13
Cargo.lock
generated
13
Cargo.lock
generated
|
@ -1046,6 +1046,7 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
"toml",
|
"toml",
|
||||||
"users",
|
"users",
|
||||||
|
"whoami",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2069,6 +2070,7 @@ dependencies = [
|
||||||
"validator",
|
"validator",
|
||||||
"webauthn-authenticator-rs",
|
"webauthn-authenticator-rs",
|
||||||
"webauthn-rs",
|
"webauthn-rs",
|
||||||
|
"whoami",
|
||||||
"zxcvbn",
|
"zxcvbn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2252,6 +2254,7 @@ version = "0.24.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14"
|
checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"cc",
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
"vcpkg",
|
"vcpkg",
|
||||||
]
|
]
|
||||||
|
@ -4471,6 +4474,16 @@ dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "whoami"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "524b58fa5a20a2fb3014dd6358b70e6579692a56ef6fce928834e488f42f65e8"
|
||||||
|
dependencies = [
|
||||||
|
"wasm-bindgen",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
|
|
|
@ -61,6 +61,25 @@ sudo apt-get install libsqlite3-dev libudev-dev libssl-dev pkg-config libpam0g-d
|
||||||
|
|
||||||
Tested with Ubuntu 20.04 and 22.04.
|
Tested with Ubuntu 20.04 and 22.04.
|
||||||
|
|
||||||
|
#### Windows
|
||||||
|
|
||||||
|
You need [rustup](https://rustup.rs/) to install a Rust toolchain.
|
||||||
|
|
||||||
|
An easy way to grab the dependencies is to install [vcpkg](https://vcpkg.io/en/getting-started.html).
|
||||||
|
|
||||||
|
This is how it works in the automated build:
|
||||||
|
|
||||||
|
1. Enable use of installed packages for the user system-wide:
|
||||||
|
```shell
|
||||||
|
vcpkg integrate install
|
||||||
|
```
|
||||||
|
2. Install the openssl dependency, which compiles it from source. This downloads all sorts of dependencies, including perl for the build.
|
||||||
|
```shell
|
||||||
|
vcpkg install openssl:x64-windows-static-md
|
||||||
|
```
|
||||||
|
|
||||||
|
There's a powershell script in the root directory of the repository which, in concert with `openssl` will generate a config file and certs for testing.
|
||||||
|
|
||||||
### Get Involved
|
### Get Involved
|
||||||
|
|
||||||
To get started, you'll need to fork or branch, and we'll merge based on pull
|
To get started, you'll need to fork or branch, and we'll merge based on pull
|
||||||
|
@ -140,8 +159,11 @@ Once you have the source code, you need encryption certificates to use with the
|
||||||
because without certificates, authentication will fail.
|
because without certificates, authentication will fail.
|
||||||
|
|
||||||
We recommend using [Let's Encrypt](https://letsencrypt.org), but if this is not
|
We recommend using [Let's Encrypt](https://letsencrypt.org), but if this is not
|
||||||
possible, please use our insecure certificate tool (`insecure_generate_tls.sh`). The
|
possible, please use our insecure certificate tool (`insecure_generate_tls.sh`).
|
||||||
insecure certificate tool creates `/tmp/kanidm` and puts some self-signed certificates there.
|
|
||||||
|
__NOTE:__ Windows developers can use `insecure_generate_tls.ps1`, which puts everything (including a templated confi gfile) in `$TEMP\kanidm`. Please adjust paths below to suit.
|
||||||
|
|
||||||
|
The insecure certificate tool creates `/tmp/kanidm` and puts some self-signed certificates there.
|
||||||
|
|
||||||
You can now build and run the server with the commands below. It will use a database
|
You can now build and run the server with the commands below. It will use a database
|
||||||
in `/tmp/kanidm.db`.
|
in `/tmp/kanidm.db`.
|
||||||
|
|
106
insecure_generate_tls.ps1
Normal file
106
insecure_generate_tls.ps1
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
$KANI_TMP="$Env:TEMP\kanidm\"
|
||||||
|
|
||||||
|
$ALTNAME_FILE="${KANI_TMP}altnames.cnf"
|
||||||
|
$CACERT="${KANI_TMP}ca.pem"
|
||||||
|
$CAKEY="${KANI_TMP}cakey.pem"
|
||||||
|
|
||||||
|
$KEYFILE="${KANI_TMP}key.pem"
|
||||||
|
$CERTFILE="${KANI_TMP}cert.pem"
|
||||||
|
$CSRFILE="${KANI_TMP}cert.csr"
|
||||||
|
$CHAINFILE="${KANI_TMP}chain.pem"
|
||||||
|
# $DHFILE="${KANI_TMP}dh.pem"
|
||||||
|
$CONFIG_FILE="${KANI_TMP}server.toml"
|
||||||
|
|
||||||
|
|
||||||
|
if (Test-Path -Path "$KANI_TMP" ) {
|
||||||
|
Write-Output "Output dir exists at $KANI_TMP"
|
||||||
|
} else {
|
||||||
|
Write-Warning "Output dir missing at $KANI_TMP"
|
||||||
|
$result = New-Item -Path "$KANI_TMP" -ItemType Directory
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ( $(Test-Path -Path "examples\insecure_server.toml") -eq $false ) {
|
||||||
|
Write-Error "You need to run this from the base dir of the repo!"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
# Building the config file
|
||||||
|
$CONFIG = Get-Content "examples\insecure_server.toml"
|
||||||
|
$CONFIG = $CONFIG -replace "/tmp/kanidm/", "$KANI_TMP"
|
||||||
|
$CONFIG = $CONFIG -replace "\\", "/"
|
||||||
|
|
||||||
|
$CONFIG | Set-Content "${CONFIG_FILE}" -Force
|
||||||
|
|
||||||
|
$ALTNAME_FILE_CONTENTS = @'
|
||||||
|
[req]
|
||||||
|
nsComment = "Certificate"
|
||||||
|
distinguished_name = req_distinguished_name
|
||||||
|
req_extensions = v3_req
|
||||||
|
|
||||||
|
[ req_distinguished_name ]
|
||||||
|
|
||||||
|
countryName = Country Name (2 letter code)
|
||||||
|
countryName_default = AU
|
||||||
|
countryName_min = 2
|
||||||
|
countryName_max = 2
|
||||||
|
|
||||||
|
stateOrProvinceName = State or Province Name (full name)
|
||||||
|
stateOrProvinceName_default = Queensland
|
||||||
|
|
||||||
|
localityName = Locality Name (eg, city)
|
||||||
|
localityName_default = Brisbane
|
||||||
|
|
||||||
|
0.organizationName = Organization Name (eg, company)
|
||||||
|
0.organizationName_default = INSECURE EXAMPLE
|
||||||
|
|
||||||
|
organizationalUnitName = Organizational Unit Name (eg, section)
|
||||||
|
organizationalUnitName_default = kanidm
|
||||||
|
|
||||||
|
commonName = Common Name (eg, your name or your servers hostname)
|
||||||
|
commonName_max = 64
|
||||||
|
commonName_default = localhost
|
||||||
|
|
||||||
|
[ v3_req ]
|
||||||
|
basicConstraints = CA:FALSE
|
||||||
|
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||||
|
subjectAltName = @alt_names
|
||||||
|
|
||||||
|
[alt_names]
|
||||||
|
DNS.1 = localhost
|
||||||
|
IP.1 = 127.0.0.1
|
||||||
|
'@
|
||||||
|
|
||||||
|
Write-Output "Creating cert template"
|
||||||
|
$result = New-Item -Path "$ALTNAME_FILE" -ItemType File -Value "$ALTNAME_FILE_CONTENTS" -Force
|
||||||
|
|
||||||
|
write-debug $result
|
||||||
|
|
||||||
|
Write-Output "Generate the CA"
|
||||||
|
openssl req -x509 -new -newkey rsa:4096 -sha256 -keyout "${CAKEY}" -out "${CACERT}" -days 31 -subj "/C=AU/ST=Queensland/L=Brisbane/O=INSECURE/CN=insecure.ca.localhost" -nodes
|
||||||
|
if ( $LastExitCode -ne 0 ){
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Output "Generating the private key"
|
||||||
|
openssl genrsa -out "${KEYFILE}" 4096
|
||||||
|
if ( $LastExitCode -ne 0 ){
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Output "Generating the certficate signing request"
|
||||||
|
openssl req -sha256 -config "${ALTNAME_FILE}" -days 31 -new -extensions v3_req -key "${KEYFILE}" -out "${CSRFILE}"
|
||||||
|
if ( $LastExitCode -ne 0 ){
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
Write-Output "Signing the certificate"
|
||||||
|
openssl x509 -req -days 31 -extfile "${ALTNAME_FILE}" -CA "${CACERT}" -CAkey "${CAKEY}" -CAcreateserial -in "${CSRFILE}" -out "${CERTFILE}" -extensions v3_req -sha256
|
||||||
|
|
||||||
|
Write-Output "Creating the certificate chain"
|
||||||
|
Get-Content "${CERTFILE}" ,"${CACERT}" | Set-Content "${CHAINFILE}" -Force
|
||||||
|
|
||||||
|
Write-Output "Certificate chain is at: ${CHAINFILE}"
|
||||||
|
Write-Output "Private key is at: ${KEYFILE}"
|
||||||
|
Write-Output "The configuration file is at: ${CONFIG_FILE}"
|
|
@ -11,7 +11,7 @@ fi
|
||||||
echo "Using config file: ${CONFIG_FILE}"
|
echo "Using config file: ${CONFIG_FILE}"
|
||||||
|
|
||||||
if [ ! -d "/tmp/kanidm/" ]; then
|
if [ ! -d "/tmp/kanidm/" ]; then
|
||||||
echo "Can't find /tmp/kanidm - you might need to run insecure_generate_certs.sh"
|
echo "Can't find /tmp/kanidm - you might need to run insecure_generate_tls.sh"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Starting the dev container..."
|
echo "Starting the dev container..."
|
||||||
|
|
|
@ -71,8 +71,6 @@ r2d2_sqlite = "^0.20.0"
|
||||||
reqwest = "^0.11.11"
|
reqwest = "^0.11.11"
|
||||||
|
|
||||||
users = "^0.11.0"
|
users = "^0.11.0"
|
||||||
#async-std = { version = "^1.11.0", features = ["tokio1"] }
|
|
||||||
|
|
||||||
|
|
||||||
lru = "^0.7.7"
|
lru = "^0.7.7"
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,15 @@ kanidm = { path = "../idm" }
|
||||||
kanidm_proto = { path = "../../kanidm_proto" }
|
kanidm_proto = { path = "../../kanidm_proto" }
|
||||||
score = { path = "../score" }
|
score = { path = "../score" }
|
||||||
clap = { version = "^3.2", features = ["derive", "env"] }
|
clap = { version = "^3.2", features = ["derive", "env"] }
|
||||||
users = "^0.11.0"
|
|
||||||
serde = { version = "^1.0.138", features = ["derive"] }
|
serde = { version = "^1.0.138", features = ["derive"] }
|
||||||
tokio = { version = "^1.19.1", features = ["rt-multi-thread", "macros", "signal"] }
|
tokio = { version = "^1.19.1", features = ["rt-multi-thread", "macros", "signal"] }
|
||||||
toml = "0.5.9"
|
toml = "0.5.9"
|
||||||
|
|
||||||
|
[target.'cfg(target_family = "windows")'.dependencies]
|
||||||
|
whoami = "^1.2.1"
|
||||||
|
|
||||||
[target.'cfg(not(target_family = "windows"))'.dependencies]
|
[target.'cfg(not(target_family = "windows"))'.dependencies]
|
||||||
|
users = "^0.11.0"
|
||||||
tikv-jemallocator = "0.5"
|
tikv-jemallocator = "0.5"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
|
|
@ -14,7 +14,10 @@
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
|
static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
|
||||||
|
|
||||||
|
#[cfg(not(target_family = "windows"))] // not needed for windows builds
|
||||||
use users::{get_current_gid, get_current_uid, get_effective_gid, get_effective_uid};
|
use users::{get_current_gid, get_current_uid, get_effective_gid, get_effective_uid};
|
||||||
|
#[cfg(target_family = "windows")] // for windows builds
|
||||||
|
use whoami;
|
||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::fs::{metadata, File, Metadata};
|
use std::fs::{metadata, File, Metadata};
|
||||||
|
@ -30,6 +33,7 @@ use std::str::FromStr;
|
||||||
use kanidm::audit::LogLevel;
|
use kanidm::audit::LogLevel;
|
||||||
use kanidm::config::{Configuration, OnlineBackup, ServerRole};
|
use kanidm::config::{Configuration, OnlineBackup, ServerRole};
|
||||||
use kanidm::tracing_tree;
|
use kanidm::tracing_tree;
|
||||||
|
#[cfg(not(target_family = "windows"))]
|
||||||
use kanidm::utils::file_permissions_readonly;
|
use kanidm::utils::file_permissions_readonly;
|
||||||
use score::{
|
use score::{
|
||||||
backup_server_core, create_server_core, dbscan_get_id2entry_core, dbscan_list_id2entry_core,
|
backup_server_core, create_server_core, dbscan_get_id2entry_core, dbscan_list_id2entry_core,
|
||||||
|
@ -120,11 +124,9 @@ fn read_file_metadata(path: &PathBuf) -> Metadata {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
/// Gets the user details if we're running in unix-land
|
||||||
async fn main() {
|
#[cfg(not(target_family = "windows"))]
|
||||||
tracing_tree::main_init();
|
fn get_user_details_unix() -> (u32, u32) {
|
||||||
|
|
||||||
// Get info about who we are.
|
|
||||||
let cuid = get_current_uid();
|
let cuid = get_current_uid();
|
||||||
let ceuid = get_effective_uid();
|
let ceuid = get_effective_uid();
|
||||||
let cgid = get_current_gid();
|
let cgid = get_current_gid();
|
||||||
|
@ -141,29 +143,59 @@ async fn main() {
|
||||||
eprintln!("ERROR: Refusing to run - uid and euid OR gid and egid must be consistent.");
|
eprintln!("ERROR: Refusing to run - uid and euid OR gid and egid must be consistent.");
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
(cuid, ceuid)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get information on the windows username
|
||||||
|
#[cfg(target_family = "windows")]
|
||||||
|
fn get_user_details_windows() {
|
||||||
|
eprintln!(
|
||||||
|
"Running on windows, current username is: {:?}",
|
||||||
|
whoami::username()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
tracing_tree::main_init();
|
||||||
|
|
||||||
|
// Get information on the windows username
|
||||||
|
#[cfg(target_family = "windows")]
|
||||||
|
get_user_details_windows();
|
||||||
|
|
||||||
|
// Get info about who we are.
|
||||||
|
#[cfg(target_family = "unix")]
|
||||||
|
let (cuid, ceuid) = get_user_details_unix();
|
||||||
|
|
||||||
// Read cli args, determine if we should backup/restore
|
// Read cli args, determine if we should backup/restore
|
||||||
let opt = KanidmdParser::parse();
|
let opt = KanidmdParser::parse();
|
||||||
|
|
||||||
let mut config = Configuration::new();
|
let mut config = Configuration::new();
|
||||||
// Check the permissions are sane.
|
// Check the permissions are OK.
|
||||||
|
#[cfg(target_family = "unix")]
|
||||||
|
{
|
||||||
let cfg_meta = read_file_metadata(&(opt.commands.commonopt().config_path));
|
let cfg_meta = read_file_metadata(&(opt.commands.commonopt().config_path));
|
||||||
|
|
||||||
|
#[cfg(target_family = "unix")]
|
||||||
if !file_permissions_readonly(&cfg_meta) {
|
if !file_permissions_readonly(&cfg_meta) {
|
||||||
eprintln!("WARNING: permissions on {} may not be secure. Should be readonly to running uid. This could be a security risk ...",
|
eprintln!("WARNING: permissions on {} may not be secure. Should be readonly to running uid. This could be a security risk ...",
|
||||||
opt.commands.commonopt().config_path.to_str().unwrap_or("invalid file path"));
|
opt.commands.commonopt().config_path.to_str().unwrap_or("invalid file path"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_family = "unix")]
|
||||||
if cfg_meta.mode() & 0o007 != 0 {
|
if cfg_meta.mode() & 0o007 != 0 {
|
||||||
eprintln!("WARNING: {} has 'everyone' permission bits in the mode. This could be a security risk ...",
|
eprintln!("WARNING: {} has 'everyone' permission bits in the mode. This could be a security risk ...",
|
||||||
opt.commands.commonopt().config_path.to_str().unwrap_or("invalid file path")
|
opt.commands.commonopt().config_path.to_str().unwrap_or("invalid file path")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_family = "unix")]
|
||||||
if cfg_meta.uid() == cuid || cfg_meta.uid() == ceuid {
|
if cfg_meta.uid() == cuid || cfg_meta.uid() == ceuid {
|
||||||
eprintln!("WARNING: {} owned by the current uid, which may allow file permission changes. This could be a security risk ...",
|
eprintln!("WARNING: {} owned by the current uid, which may allow file permission changes. This could be a security risk ...",
|
||||||
opt.commands.commonopt().config_path.to_str().unwrap_or("invalid file path")
|
opt.commands.commonopt().config_path.to_str().unwrap_or("invalid file path")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Read our config
|
// Read our config
|
||||||
let sconfig = match ServerConfig::new(&(opt.commands.commonopt().config_path)) {
|
let sconfig = match ServerConfig::new(&(opt.commands.commonopt().config_path)) {
|
||||||
|
@ -205,14 +237,18 @@ async fn main() {
|
||||||
);
|
);
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: windows support for DB folder permissions checks
|
||||||
|
#[cfg(target_family = "unix")]
|
||||||
|
{
|
||||||
if !file_permissions_readonly(&i_meta) {
|
if !file_permissions_readonly(&i_meta) {
|
||||||
eprintln!("WARNING: DB folder permissions on {} indicate it may not be RW. This could cause the server start up to fail!", db_par_path_buf.to_str().unwrap_or("invalid file path"));
|
eprintln!("WARNING: DB folder permissions on {} indicate it may not be RW. This could cause the server start up to fail!", db_par_path_buf.to_str().unwrap_or("invalid file path"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if i_meta.mode() & 0o007 != 0 {
|
if i_meta.mode() & 0o007 != 0 {
|
||||||
eprintln!("WARNING: DB folder {} has 'everyone' permission bits in the mode. This could be a security risk ...", db_par_path_buf.to_str().unwrap_or("invalid file path"));
|
eprintln!("WARNING: DB folder {} has 'everyone' permission bits in the mode. This could be a security risk ...", db_par_path_buf.to_str().unwrap_or("invalid file path"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
config.update_log_level(ll);
|
config.update_log_level(ll);
|
||||||
config.update_db_path(&sconfig.db_path.as_str());
|
config.update_db_path(&sconfig.db_path.as_str());
|
||||||
|
@ -251,23 +287,37 @@ async fn main() {
|
||||||
|
|
||||||
if let Some(i_str) = &(sconfig.tls_chain) {
|
if let Some(i_str) = &(sconfig.tls_chain) {
|
||||||
let i_path = PathBuf::from(i_str.as_str());
|
let i_path = PathBuf::from(i_str.as_str());
|
||||||
|
// TODO: windows support for DB folder permissions checks
|
||||||
|
#[cfg(not(target_family = "unix"))]
|
||||||
|
eprintln!("WARNING: permissions checks on windows aren't implemented, cannot check TLS Key at {:?}", i_path);
|
||||||
|
|
||||||
|
#[cfg(target_family = "unix")]
|
||||||
|
{
|
||||||
let i_meta = read_file_metadata(&i_path);
|
let i_meta = read_file_metadata(&i_path);
|
||||||
if !file_permissions_readonly(&i_meta) {
|
if !file_permissions_readonly(&i_meta) {
|
||||||
eprintln!("WARNING: permissions on {} may not be secure. Should be readonly to running uid. This could be a security risk ...", i_str);
|
eprintln!("WARNING: permissions on {} may not be secure. Should be readonly to running uid. This could be a security risk ...", i_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(i_str) = &(sconfig.tls_key) {
|
if let Some(i_str) = &(sconfig.tls_key) {
|
||||||
let i_path = PathBuf::from(i_str.as_str());
|
let i_path = PathBuf::from(i_str.as_str());
|
||||||
|
// TODO: windows support for DB folder permissions checks
|
||||||
|
#[cfg(not(target_family = "unix"))]
|
||||||
|
eprintln!("WARNING: permissions checks on windows aren't implemented, cannot check TLS Key at {:?}", i_path);
|
||||||
|
|
||||||
|
// TODO: windows support for DB folder permissions checks
|
||||||
|
#[cfg(target_family = "unix")]
|
||||||
|
{
|
||||||
let i_meta = read_file_metadata(&i_path);
|
let i_meta = read_file_metadata(&i_path);
|
||||||
if !file_permissions_readonly(&i_meta) {
|
if !file_permissions_readonly(&i_meta) {
|
||||||
eprintln!("WARNING: permissions on {} may not be secure. Should be readonly to running uid. This could be a security risk ...", i_str);
|
eprintln!("WARNING: permissions on {} may not be secure. Should be readonly to running uid. This could be a security risk ...", i_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
if i_meta.mode() & 0o007 != 0 {
|
if i_meta.mode() & 0o007 != 0 {
|
||||||
eprintln!("WARNING: {} has 'everyone' permission bits in the mode. This could be a security risk ...", i_str);
|
eprintln!("WARNING: {} has 'everyone' permission bits in the mode. This could be a security risk ...", i_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let sctx = create_server_core(config, config_test).await;
|
let sctx = create_server_core(config, config_test).await;
|
||||||
if !config_test {
|
if !config_test {
|
||||||
|
|
|
@ -40,7 +40,6 @@ r2d2 = "^0.8.9"
|
||||||
r2d2_sqlite = "^0.20.0"
|
r2d2_sqlite = "^0.20.0"
|
||||||
rand = "^0.8.5"
|
rand = "^0.8.5"
|
||||||
regex = "^1.5.6"
|
regex = "^1.5.6"
|
||||||
rusqlite = "^0.27.0"
|
|
||||||
saffron = "^0.1.0"
|
saffron = "^0.1.0"
|
||||||
serde = { version = "^1.0.138", features = ["derive"] }
|
serde = { version = "^1.0.138", features = ["derive"] }
|
||||||
serde_cbor = "^0.11.2"
|
serde_cbor = "^0.11.2"
|
||||||
|
@ -58,12 +57,27 @@ tracing = { version = "^0.1.35", features = ["attributes"] }
|
||||||
tracing-serde = "^0.1.3"
|
tracing-serde = "^0.1.3"
|
||||||
tracing-subscriber = { version = "^0.3.14", features = ["env-filter"] }
|
tracing-subscriber = { version = "^0.3.14", features = ["env-filter"] }
|
||||||
url = { version = "^2.2.2", features = ["serde"] }
|
url = { version = "^2.2.2", features = ["serde"] }
|
||||||
users = "^0.11.0"
|
|
||||||
uuid = { version = "^1.1.2", features = ["serde", "v4" ] }
|
uuid = { version = "^1.1.2", features = ["serde", "v4" ] }
|
||||||
validator = { version = "^0.15.0", features = ["phone"] }
|
validator = { version = "^0.15.0", features = ["phone"] }
|
||||||
webauthn-rs = "^0.3.2"
|
webauthn-rs = "^0.3.2"
|
||||||
zxcvbn = "^2.2.1"
|
zxcvbn = "^2.2.1"
|
||||||
|
|
||||||
|
# because windows really can't build without the bundled one
|
||||||
|
[target.'cfg(target_family = "windows")'.dependencies.rusqlite]
|
||||||
|
version = "^0.27.0"
|
||||||
|
features = ["bundled"]
|
||||||
|
|
||||||
|
[target.'cfg(not(target_family = "windows"))'.dependencies.rusqlite]
|
||||||
|
version = "^0.27.0"
|
||||||
|
|
||||||
|
[target.'cfg(target_family = "windows")'.dependencies]
|
||||||
|
whoami = "^1.2.1"
|
||||||
|
|
||||||
|
|
||||||
|
[target.'cfg(not(target_family = "windows"))'.dependencies]
|
||||||
|
users = "^0.11.0"
|
||||||
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# default = [ "libsqlite3-sys/bundled", "openssl/vendored" ]
|
# default = [ "libsqlite3-sys/bundled", "openssl/vendored" ]
|
||||||
|
|
||||||
|
|
|
@ -10,14 +10,16 @@ use uuid::{Builder, Uuid};
|
||||||
use rand::distributions::Distribution;
|
use rand::distributions::Distribution;
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
|
|
||||||
|
#[cfg(not(target_family = "windows"))]
|
||||||
use std::fs::Metadata;
|
use std::fs::Metadata;
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
use std::os::linux::fs::MetadataExt;
|
use std::os::linux::fs::MetadataExt;
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
use std::os::macos::fs::MetadataExt;
|
use std::os::macos::fs::MetadataExt;
|
||||||
#[cfg(target_os = "windows")]
|
// #[cfg(target_os = "windows")]
|
||||||
use std::os::windows::fs::MetadataExt;
|
// use std::os::windows::fs::MetadataExt;
|
||||||
|
|
||||||
|
#[cfg(target_family = "unix")]
|
||||||
use users::{get_current_gid, get_current_uid};
|
use users::{get_current_gid, get_current_uid};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
@ -32,6 +32,7 @@ mod ldaps;
|
||||||
use async_std::task;
|
use async_std::task;
|
||||||
use compact_jwt::JwsSigner;
|
use compact_jwt::JwsSigner;
|
||||||
use kanidm::prelude::*;
|
use kanidm::prelude::*;
|
||||||
|
#[cfg(not(target_family = "windows"))]
|
||||||
use libc::umask;
|
use libc::umask;
|
||||||
|
|
||||||
use kanidm::actors::v1_read::QueryServerReadV1;
|
use kanidm::actors::v1_read::QueryServerReadV1;
|
||||||
|
@ -551,7 +552,10 @@ pub async fn create_server_core(config: Configuration, config_test: bool) -> Res
|
||||||
config
|
config
|
||||||
);
|
);
|
||||||
// Setup umask, so that every we touch or create is secure.
|
// Setup umask, so that every we touch or create is secure.
|
||||||
let _ = unsafe { umask(0o0027) };
|
#[cfg(not(target_family = "windows"))]
|
||||||
|
unsafe {
|
||||||
|
umask(0o0027)
|
||||||
|
};
|
||||||
|
|
||||||
// Similar, create a stats task which aggregates statistics from the
|
// Similar, create a stats task which aggregates statistics from the
|
||||||
// server as they come in.
|
// server as they come in.
|
||||||
|
|
Loading…
Reference in a new issue