From: Steinar H. Gunderson Date: Sun, 15 Nov 2020 12:56:18 +0000 (+0100) Subject: Serialize JSON using serde_json instead of string concatenation. X-Git-Url: https://git.sesse.net/?p=linux-dallas-multipass;a=commitdiff_plain;h=c6421d3f060df4096791375f78bdef879be90098 Serialize JSON using serde_json instead of string concatenation. --- diff --git a/multipass.rs b/multipass.rs index 629d07e..073e929 100644 --- a/multipass.rs +++ b/multipass.rs @@ -4,6 +4,8 @@ extern crate pcsc; #[macro_use] extern crate simple_error; +#[macro_use] +extern crate serde_json; use pcsc::*; use core::task::{Context, Poll}; @@ -161,20 +163,21 @@ async fn apdu_service(req: Request) -> Result, hyper::Error *response.status_mut() = StatusCode::BAD_REQUEST; } (&Method::POST, "/scard/version/") => { - *response.body_mut() = Body::from("{\"version\":\"1.3.9.46\"}"); + let reply = json!({ + "version": "1.3.9.46" + }); + *response.body_mut() = Body::from(reply.to_string()); } (&Method::POST, "/scard/list/") => { return unwrap_result_into_response(get_readers(), response); } (&Method::POST, "/scard/disconnect/") => { - *response.body_mut() = Body::from("{\"errorcode\":0,\"errordetail\":0,\"apduresponses\":null}"); + *response.body_mut() = Body::from(""); println!("Disconnecting from card."); let mut card = GLOBAL_CARD.lock().unwrap(); *card = None; } (&Method::POST, "/scard/getref/") => { - let mut reply = "{\"data\":\"".to_owned(); - // This is seemingly so that the PIN isn't sent “in the clear”, over TLS, to localhost. // We send a key (in the form of 16 bytes) with an ID (the reference), // the first four bytes are XORed with the next four bytes, and the PIN @@ -183,10 +186,12 @@ async fn apdu_service(req: Request) -> Result, hyper::Error // be a noop. (The reference is a handle to the key, in case we've given // out multiple ones. We set it to some dummy value.) let random_bytes = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; - reply += &hex::encode(random_bytes).to_ascii_uppercase(); - reply += "\",\"ref\":195948557}"; - println!("Reply: {}", reply); - *response.body_mut() = Body::from(reply); + let reply = json!({ + "data": &hex::encode(random_bytes).to_ascii_uppercase(), + "ref": 195948557 + }); + println!("Reply: {}", reply.to_string()); + *response.body_mut() = Body::from(reply.to_string()); } // Catch-all 404. _ => { @@ -228,30 +233,29 @@ fn get_readers() -> Result> // Establish a PC/SC context. let ctx = pcsc::Context::establish(Scope::User)?; - let mut reply : String = "{\"errorcode\":0,\"errordetail\":0,\"readers\":[".to_owned(); - // List available readers. let mut readers_buf = [0; 2048]; - let mut reader_json : Vec = Vec::new(); + let mut reader_json : Vec = Vec::new(); for r in ctx.list_readers(&mut readers_buf)? { // Check the card status by connecting to it. let status = match ctx.connect(r, ShareMode::Shared, Protocols::ANY) { - Ok(_) => "302", - Err(_) => "303" + Ok(_) => 302, + Err(_) => 303 }; - let mut json = "{\"cardstatus\":".to_owned(); - json += status; - json += ",\"name\":\""; - json += r.to_str()?; - json += "\"}"; - reader_json.push(json); + reader_json.push(json!({ + "cardstatus": status, + "name": r.to_str()? + })); } - reply += &reader_json.join(","); - reply += "]}"; - println!("Reply: {}", reply); - return Ok(Body::from(reply)); + let reply = json!({ + "errorcode": 0, + "errordetail": 0, + "readers": reader_json + }); + println!("Reply: {}", reply.to_string()); + return Ok(Body::from(reply.to_string())); } fn transmit_apdu(card: &Card, mut apdu: &[u8]) -> Result> { @@ -348,18 +352,18 @@ fn run_apdu(reader_name: &str, apdus: Vec>) -> Result = Vec::new(); + let mut response_json : Vec = Vec::new(); for apdu in apdus { - let mut reply : String = "{\"apdu\":\"".to_owned(); - reply += &transmit_apdu(card.as_mut().unwrap(), &apdu)?; - reply += "\"}"; - response_json.push(reply); + let reply = &transmit_apdu(card.as_mut().unwrap(), &apdu)?; + response_json.push(json!({ + "apdu": reply + })); } - - reply += &response_json.join(","); - reply += "]}"; - println!("Reply: {}", reply); - return Ok(Body::from(reply)); + let reply = json!({ + "errorcode": 0, + "errordetail": 0, + "apduresponses": response_json + }); + println!("Reply: {}", reply.to_string()); + return Ok(Body::from(reply.to_string())); }