diff --git a/Cargo.lock b/Cargo.lock index 1ede611..63782ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1022,6 +1022,9 @@ name = "ipnet" version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146" +dependencies = [ + "serde", +] [[package]] name = "itertools" @@ -2403,6 +2406,7 @@ dependencies = [ "chrono", "dotenvy", "hex", + "ipnet", "log", "paste", "rand", diff --git a/trifid-api/Cargo.toml b/trifid-api/Cargo.toml index cf1e56d..d63dc22 100644 --- a/trifid-api/Cargo.toml +++ b/trifid-api/Cargo.toml @@ -24,4 +24,5 @@ aes-gcm = "0.10.1" hex = "0.4.3" rand = "0.8.5" trifid-pki = { version = "0.1.3", path = "../trifid-pki" } -sha2 = "0.10.6" \ No newline at end of file +sha2 = "0.10.6" +ipnet = { version = "2.7.1", features = ["serde"] } diff --git a/trifid-api/src/main.rs b/trifid-api/src/main.rs index 92a9ca5..125597a 100644 --- a/trifid-api/src/main.rs +++ b/trifid-api/src/main.rs @@ -180,7 +180,8 @@ async fn main() -> Result<(), Box> { crate::routes::v1::organization::orglist_req, crate::routes::v1::organization::create_org, crate::routes::v1::user::get_user, - crate::routes::v1::user::options + crate::routes::v1::user::options, + crate::routes::v1::organization::createorgoptions, ]) .register("/", catchers![ crate::routes::handler_400, diff --git a/trifid-api/src/routes/v1/ca.rs b/trifid-api/src/routes/v1/ca.rs new file mode 100644 index 0000000..6a67c4c --- /dev/null +++ b/trifid-api/src/routes/v1/ca.rs @@ -0,0 +1,89 @@ +// trifid-api, an open source reimplementation of the Defined Networking nebula management server. +// Copyright (C) 2023 c0repwn3r +// +// 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 . + +use ipnet::Ipv4Net; +use rocket::{post, options, get, State}; +use rocket::http::{ContentType, Status}; +use rocket::serde::json::Json; +use sqlx::PgPool; +use crate::config::TFConfig; +use serde::{Serialize, Deserialize}; +use crate::auth::TOTPAuthenticatedUserInfo; +use crate::org::get_org_ca_pool; + +#[options("/v1/org/<_id>/ca")] +pub fn options(_id: i32) -> &'static str { + "" +} + +#[derive(Serialize, Deserialize)] +#[serde(crate = "rocket::serde")] +pub struct CaList { + pub trusted_cas: Vec, + pub blocklisted_certs: Vec +} + +#[derive(Serialize, Deserialize)] +#[serde(crate = "rocket::serde")] +pub struct CA { + pub fingerprint: String, + pub cert: String +} + +#[get("/v1/org//ca")] +pub async fn get_cas_for_org(id: i32, user: TOTPAuthenticatedUserInfo, db: &State) -> Result<(ContentType, Json), (Status, String)> { + let ca_pool = match get_org_ca_pool(id, db.inner()).await { + Ok(pool) => pool, + Err(e) => { + return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"ERR_QL_QUERY_FAILED\",\"message\":\"unable to load certificates from database - {}\"}}]}}", e))); + } + }; + + let mut trusted_cas = vec![]; + + for (fingerprint, cert) in ca_pool.cas { + trusted_cas.push(CA { + fingerprint, + cert: match cert.serialize_to_pem() { + Ok(pem) => match String::from_utf8(pem) { + Ok(str) => str, + Err(e) => return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"ERR_QL_QUERY_FAILED\",\"message\":\"unable to encode one of the serialized certificates - {}\"}}]}}", e))) + }, + Err(e) => { + return Err((Status::InternalServerError, format!("{{\"errors\":[{{\"code\":\"ERR_QL_QUERY_FAILED\",\"message\":\"unable to serialize one of the certificates - {}\"}}]}}", e))); + } + } + }) + } + + Ok((ContentType::JSON, Json(CaList { + trusted_cas, + blocklisted_certs: ca_pool.cert_blocklist, + }))) +} + +#[derive(Serialize, Deserialize)] +#[serde(crate = "rocket::serde")] +pub struct CreateCARequest { + pub ip_ranges: Vec, + pub subnet_ranges: Vec, + pub groups: Vec +} + +#[post("/v1/org//ca", data = "")] +pub async fn create_signing_ca_req(id: i32, data: Json, user: TOTPAuthenticatedUserInfo, config: &State, db: &State) { + +} \ No newline at end of file diff --git a/trifid-api/src/routes/v1/mod.rs b/trifid-api/src/routes/v1/mod.rs index cae8fbd..b23a49e 100644 --- a/trifid-api/src/routes/v1/mod.rs +++ b/trifid-api/src/routes/v1/mod.rs @@ -20,4 +20,5 @@ pub mod signup; pub mod totp_authenticators; pub mod verify_totp_authenticator; pub mod organization; -pub mod user; \ No newline at end of file +pub mod user; +pub mod ca; \ No newline at end of file diff --git a/trifid-api/src/routes/v1/organization.rs b/trifid-api/src/routes/v1/organization.rs index 013c80a..2c94363 100644 --- a/trifid-api/src/routes/v1/organization.rs +++ b/trifid-api/src/routes/v1/organization.rs @@ -32,6 +32,8 @@ pub fn options() -> &'static str { pub fn orgidoptions(_id: i32) -> &'static str { "" } +#[options("/v1/org")] +pub fn createorgoptions() -> &'static str {""} #[derive(Serialize, Deserialize)] #[serde(crate = "rocket::serde")]