diff --git a/Cargo.lock b/Cargo.lock index 7c24477..f26d3a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -444,7 +444,7 @@ dependencies = [ [[package]] name = "local-mini-kms" -version = "0.1.0" +version = "0.1.1" dependencies = [ "base64", "clap", diff --git a/Cargo.toml b/Cargo.toml index ccb12ad..a09fca9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "local-mini-kms" -version = "0.1.0" +version = "0.1.1" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/cli.rs b/src/cli.rs index ae567c1..9295b6a 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -19,6 +19,7 @@ impl Command for CommandImpl { SubCommand::with_name(self.name()).about("Local mini KMS cli") .arg(Arg::with_name("connect").long("connect").takes_value(true).default_value("127.0.0.1:5567").help("Connect server")) .arg(Arg::with_name("init").long("init").help("Init server")) + .arg(Arg::with_name("direct-init").long("direct-init").help("Direct init server")) .arg(Arg::with_name("offline-init").long("offline-init").help("Offline init server")) .arg(Arg::with_name("encrypt").long("encrypt").help("Encrypt text")) .arg(Arg::with_name("decrypt").long("decrypt").help("Decrypt text")) @@ -29,30 +30,59 @@ impl Command for CommandImpl { fn run(&self, arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError { let init = sub_arg_matches.is_present("init"); + let direct_init = sub_arg_matches.is_present("direct-init"); let offline_init = sub_arg_matches.is_present("offline-init"); let encrypt = sub_arg_matches.is_present("encrypt"); let decrypt = sub_arg_matches.is_present("decrypt"); let rt = tokio::runtime::Runtime::new().expect("Create tokio runtime error"); if init { - rt.block_on(async { - do_init(arg_matches, sub_arg_matches).await - }) + rt.block_on(async { do_init(arg_matches, sub_arg_matches).await }) + } else if direct_init { + rt.block_on(async { do_direct_init(arg_matches, sub_arg_matches).await }) } else if offline_init { do_offline_init(arg_matches, sub_arg_matches) } else if encrypt { - rt.block_on(async { - do_encrypt(arg_matches, sub_arg_matches).await - }) + rt.block_on(async { do_encrypt(arg_matches, sub_arg_matches).await }) } else if decrypt { - rt.block_on(async { - do_decrypt(arg_matches, sub_arg_matches).await - }) + rt.block_on(async { do_decrypt(arg_matches, sub_arg_matches).await }) } else { simple_error!("Need a flag") } } } +async fn do_direct_init(_arg_matches: &ArgMatches<'_>, sub_arg_matches: &ArgMatches<'_>) -> CommandError { + let connect = sub_arg_matches.value_of("connect").expect("Get argument listen error"); + let value_hex = sub_arg_matches.value_of("value-hex"); + let value_base64 = sub_arg_matches.value_of("value-base64"); + + let client = Client::new(); + let uri = format!("http://{}/init", connect); + debugging!("Request uri: {}", &uri); + let body = if let Some(value_hex) = value_hex { + json!({ + "clear_master_key_hex": value_hex, + }) + } else if let Some(value_base64) = value_base64 { + json!({ + "clear_master_key_base64": value_base64, + }) + } else { + return simple_error!("Requires value hex or value base64"); + }; + let body = serde_json::to_string(&body)?; + let req = Request::builder().method(Method::POST).uri(uri).body(Body::from(body))?; + + let req_response = client.request(req).await?; + if req_response.status() != StatusCode::OK { + let status = req_response.status().as_u16(); + let data = response_to_value(req_response).await?; + return simple_error!("Server status is not success: {}, response: {}", status, data); + } + success!("Init finished"); + Ok(Some(0)) +} + async fn do_init(_arg_matches: &ArgMatches<'_>, sub_arg_matches: &ArgMatches<'_>) -> CommandError { let connect = sub_arg_matches.value_of("connect").expect("Get argument listen error");