Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the D-Bus broker service #177

Merged
merged 2 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ jobs:
libpcre2-dev \
libclang-13-dev \
autoconf \
gettext
gettext \
libdbus-1-dev

- name: "Fetch submodules"
run: git submodule init && git submodule update
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/build_debian_source_package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ jobs:
pkgconf \
debhelper-compat \
devscripts \
libclang-14-dev
libclang-14-dev \
libdbus-1-dev

- name: "[general] - Fetch submodules"
run: |
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/clippy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ jobs:
libpcre2-dev \
libclang-13-dev \
autoconf \
gettext
gettext \
libdbus-1-dev

- name: "Fetch submodules"
run: git submodule init && git submodule update
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ jobs:
libpcre2-dev \
libclang-13-dev \
autoconf \
gettext
gettext \
libdbus-1-dev

- name: "Fetch submodules"
run: git submodule init && git submodule update
Expand Down
10 changes: 6 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ members = [
"src/users",
"src/idmap",
"src/file_permissions",
"src/broker",
]
resolver = "2"

[workspace.package]
version = "0.5.0"
version = "0.6.0"
authors = [
"David Mulder <[email protected]>"
]
Expand All @@ -37,12 +38,12 @@ tracing-subscriber = "^0.3.17"
tracing = "^0.1.37"
himmelblau_unix_common = { path = "src/common" }
kanidm_unix_common = { path = "src/glue" }
libhimmelblau = { version = "0.2.9" }
libhimmelblau = { version = "0.3.0" }
clap = { version = "^4.5", features = ["derive", "env"] }
clap_complete = "^4.4.1"
reqwest = { version = "^0.12.2", features = ["json"] }
anyhow = "^1.0.71"
tokio = { version = "^1.28.1", features = ["rt", "macros", "sync", "time", "net", "io-util", "signal"] }
tokio = { version = "^1.28.1", features = ["rt", "macros", "sync", "time", "net", "io-util", "signal", "rt-multi-thread"] }
tokio-util = { version = "^0.7.8", features = ["codec"] }
async-trait = "^0.1.72"
pem = "^3.0.2"
Expand All @@ -51,6 +52,7 @@ os-release = "^0.1.0"
jsonwebtoken = "^9.2.0"
zeroize = "^1.7.0"
idmap = { path = "src/idmap" }
identity_dbus_broker = "0.1.0"

# Kanidm deps
argon2 = { version = "0.5.2", features = ["alloc"] }
Expand All @@ -76,7 +78,7 @@ tracing-forest = "^0.1.6"
rusqlite = "^0.32.0"
hashbrown = { version = "0.14.0", features = ["serde", "inline-more", "ahash"] }
lru = "^0.12.3"
kanidm_lib_crypto = { path = "./src/crypto", version = "0.5.0" }
kanidm_lib_crypto = { path = "./src/crypto", version = "0.6.0" }
kanidm_utils_users = { path = "./src/users" }
walkdir = "2"
csv = "1.2.2"
Expand Down
3 changes: 3 additions & 0 deletions platform/debian/com.microsoft.identity.broker.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[D-BUS Service]
Name=com.microsoft.identity.broker1
Exec=/usr/sbin/broker
3 changes: 2 additions & 1 deletion platform/debian/himmelblaud.service
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ Description=Himmelblau Authentication Daemon
After=chronyd.service ntpd.service network-online.target

[Service]
BusName=org.samba.himmelblau
DynamicUser=yes
UMask=0027
CacheDirectory=himmelblaud # /var/cache/himmelblaud
RuntimeDirectory=himmelblaud # /run/himmelblaud
StateDirectory=himmelblaud # /var/lib/himmelblaud

Type=simple
Type=dbus
ExecStart=/usr/sbin/himmelblaud

# Implied by dynamic user.
Expand Down
8 changes: 8 additions & 0 deletions platform/debian/org.samba.himmelblau.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<policy context="default">
<allow own="org.samba.himmelblau"/>
<allow send_destination="org.samba.himmelblau"/>
</policy>
</busconfig>
3 changes: 3 additions & 0 deletions platform/opensuse/com.microsoft.identity.broker.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[D-BUS Service]
Name=com.microsoft.identity.broker1
Exec=/usr/sbin/broker
3 changes: 2 additions & 1 deletion platform/opensuse/himmelblaud.service
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ Description=Himmelblau Authentication Daemon
After=chronyd.service ntpd.service network-online.target suspend.target

[Service]
BusName=org.samba.himmelblau
DynamicUser=yes
UMask=0027
CacheDirectory=himmelblaud # /var/cache/himmelblaud
RuntimeDirectory=himmelblaud # /run/himmelblaud
StateDirectory=himmelblaud # /var/lib/himmelblaud

Type=simple
Type=dbus
ExecStart=/usr/sbin/himmelblaud

# Implied by dynamic user.
Expand Down
8 changes: 8 additions & 0 deletions platform/opensuse/org.samba.himmelblau.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<policy context="default">
<allow own="org.samba.himmelblau"/>
<allow send_destination="org.samba.himmelblau"/>
</policy>
</busconfig>
14 changes: 14 additions & 0 deletions src/broker/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "broker"
version.workspace = true
authors.workspace = true
rust-version.workspace = true
edition.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true

[dependencies]
dbus = "0.9.7"
identity_dbus_broker.workspace = true
tokio.workspace = true
23 changes: 23 additions & 0 deletions src/broker/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
Unix Azure Entra ID implementation
Copyright (C) David Mulder <[email protected]> 2024

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
use identity_dbus_broker::himmelblau_session_broker_serve;

#[tokio::main]
async fn main() -> Result<(), dbus::MethodErr> {
himmelblau_session_broker_serve().await
}
10 changes: 5 additions & 5 deletions src/common/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1093,7 +1093,7 @@ mod tests {
uuid: uuid::uuid!("0302b99c-f0f6-41ab-9492-852692b0fd16"),
shell: None,
groups: Vec::new(),
sshkeys: vec!["key-a".to_string()],
tenant_id: uuid::uuid!("58e8a301-2502-4814-81c5-a4d17c399a45"),
valid: true,
};

Expand Down Expand Up @@ -1266,7 +1266,7 @@ mod tests {
uuid: uuid::uuid!("0302b99c-f0f6-41ab-9492-852692b0fd16"),
shell: None,
groups: vec![gt1.clone(), gt2],
sshkeys: vec!["key-a".to_string()],
tenant_id: uuid::uuid!("58e8a301-2502-4814-81c5-a4d17c399a45"),
valid: true,
};

Expand Down Expand Up @@ -1335,7 +1335,7 @@ mod tests {
uuid: uuid1,
shell: None,
groups: Vec::new(),
sshkeys: vec!["key-a".to_string()],
tenant_id: uuid::uuid!("58e8a301-2502-4814-81c5-a4d17c399a45"),
valid: true,
};

Expand Down Expand Up @@ -1459,7 +1459,7 @@ mod tests {
uuid: uuid::uuid!("0302b99c-f0f6-41ab-9492-852692b0fd16"),
shell: None,
groups: Vec::new(),
sshkeys: vec!["key-a".to_string()],
tenant_id: uuid::uuid!("58e8a301-2502-4814-81c5-a4d17c399a45"),
valid: true,
};

Expand All @@ -1471,7 +1471,7 @@ mod tests {
uuid: uuid::uuid!("799123b2-3802-4b19-b0b8-1ffae2aa9a4b"),
shell: None,
groups: Vec::new(),
sshkeys: vec!["key-a".to_string()],
tenant_id: uuid::uuid!("58e8a301-2502-4814-81c5-a4d17c399a45"),
valid: true,
};

Expand Down
121 changes: 118 additions & 3 deletions src/common/src/idprovider/himmelblau.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,61 @@ impl IdProvider for HimmelblauMultiProvider {
Ok(())
}

async fn unix_user_access(
&self,
id: &Id,
scopes: Vec<String>,
old_token: Option<&UserToken>,
tpm: &mut tpm::BoxedDynTpm,
machine_key: &tpm::MachineKey,
) -> Result<UnixUserToken, IdpError> {
let account_id = match old_token {
Some(token) => token.spn.clone(),
None => id.to_string().clone(),
};
match split_username(&account_id) {
Some((_sam, domain)) => {
let providers = self.providers.read().await;
match providers.get(domain) {
Some(provider) => {
provider
.unix_user_access(id, scopes, old_token, tpm, machine_key)
.await
}
None => Err(IdpError::NotFound),
}
}
None => Err(IdpError::NotFound),
}
}

async fn unix_user_prt_cookie(
&self,
id: &Id,
old_token: Option<&UserToken>,
tpm: &mut tpm::BoxedDynTpm,
machine_key: &tpm::MachineKey,
) -> Result<String, IdpError> {
let account_id = match old_token {
Some(token) => token.spn.clone(),
None => id.to_string().clone(),
};
match split_username(&account_id) {
Some((_sam, domain)) => {
let providers = self.providers.read().await;
match providers.get(domain) {
Some(provider) => {
provider
.unix_user_prt_cookie(id, old_token, tpm, machine_key)
.await
}
None => Err(IdpError::NotFound),
}
}
None => Err(IdpError::NotFound),
}
}

async fn unix_user_get(
&self,
id: &Id,
Expand Down Expand Up @@ -491,6 +546,61 @@ impl IdProvider for HimmelblauProvider {
}
}

async fn unix_user_access(
&self,
id: &Id,
scopes: Vec<String>,
old_token: Option<&UserToken>,
tpm: &mut tpm::BoxedDynTpm,
machine_key: &tpm::MachineKey,
) -> Result<UnixUserToken, IdpError> {
/* Use the prt mem cache to refresh the user token */
let account_id = match old_token {
Some(token) => token.spn.clone(),
None => id.to_string().clone(),
};
let prt = self.refresh_cache.refresh_token(&account_id).await?;
self.client
.write()
.await
.exchange_prt_for_access_token(
&prt,
scopes.iter().map(|s| s.as_ref()).collect(),
None,
tpm,
machine_key,
)
.await
.map_err(|e| {
error!("{:?}", e);
IdpError::BadRequest
})
}

async fn unix_user_prt_cookie(
&self,
id: &Id,
old_token: Option<&UserToken>,
tpm: &mut tpm::BoxedDynTpm,
machine_key: &tpm::MachineKey,
) -> Result<String, IdpError> {
/* Use the prt mem cache to refresh the user token */
let account_id = match old_token {
Some(token) => token.spn.clone(),
None => id.to_string().clone(),
};
let prt = self.refresh_cache.refresh_token(&account_id).await?;
self.client
.write()
.await
.acquire_prt_sso_cookie(&prt, tpm, machine_key)
.await
.map_err(|e| {
error!("Failed to request prt cookie: {:?}", e);
IdpError::BadRequest
})
}

async fn unix_user_get(
&self,
id: &Id,
Expand Down Expand Up @@ -555,7 +665,10 @@ impl IdProvider for HimmelblauProvider {
displayname: "".to_string(),
shell: Some(config.get_shell(Some(&self.domain))),
groups,
sshkeys: vec![],
tenant_id: Uuid::parse_str(&self.tenant_id).map_err(|e| {
error!("{:?}", e);
IdpError::BadRequest
})?,
valid: true,
});
} else {
Expand Down Expand Up @@ -1344,7 +1457,6 @@ impl HimmelblauProvider {
groups = vec![];
}
};
let sshkeys: Vec<String> = vec![];
let valid = true;
let idmap = self.idmap.read().await;
let gidnumber = match config.get_id_attr_map() {
Expand Down Expand Up @@ -1376,7 +1488,10 @@ impl HimmelblauProvider {
displayname: value.id_token.name.clone(),
shell: Some(config.get_shell(Some(&self.domain))),
groups,
sshkeys,
tenant_id: Uuid::parse_str(&self.tenant_id).map_err(|e| {
error!("{:?}", e);
IdpError::BadRequest
})?,
valid,
})
}
Expand Down
Loading