Skip to content
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
8 changes: 5 additions & 3 deletions docs/_docs/user-guide/eldritch.md
Original file line number Diff line number Diff line change
Expand Up @@ -414,21 +414,23 @@ The <b>file.find</b> method finds all files matching the used parameters. Return

## HTTP

The HTTP library also allows the user to allow the http client to ignore TLS validation via the `allow_insecure` optional parameter (defaults to `false`).

### http.download

`http.download(uri: str, dst: str) -> None`
`http.download(uri: str, dst: str, allow_insecure: Option<bool>) -> None`

The <b>http.download</b> method downloads a file at the URI specified in `uri` to the path specified in `dst`. If a file already exists at that location, it will be overwritten.

### http.get

`http.get(uri: str, query_params: Option<Dict<str, str>>, headers: Option<Dict<str, str>>) -> str`
`http.get(uri: str, query_params: Option<Dict<str, str>>, headers: Option<Dict<str, str>>, allow_insecure: Option<bool>) -> str`

The <b>http.get</b> method sends an HTTP GET request to the URI specified in `uri` with the optional query paramters specified in `query_params` and headers specified in `headers`, then return the response body as a string. Note: in order to conform with HTTP2+ all header names are transmuted to lowercase.

### http.post

`http.post(uri: str, body: Option<str>, form: Option<Dict<str, str>>, headers: Option<Dict<str, str>>) -> str`
`http.post(uri: str, body: Option<str>, form: Option<Dict<str, str>>, headers: Option<Dict<str, str>>, allow_insecure: Option<bool>) -> str`

The <b>http.post</b> method sends an HTTP POST request to the URI specified in `uri` with the optional request body specified by `body`, form paramters specified in `form`, and headers specified in `headers`, then return the response body as a string. Note: in order to conform with HTTP2+ all header names are transmuted to lowercase. Other Note: if a `body` and a `form` are supplied the value of `body` will be used.

Expand Down
18 changes: 13 additions & 5 deletions implants/lib/eldritch/src/http/download_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::path::PathBuf;
use tokio::{fs::File, io::AsyncWriteExt};
use tokio_stream::StreamExt;

async fn handle_download(uri: String, dst: String) -> Result<()> {
async fn handle_download(uri: String, dst: String, allow_insecure: bool) -> Result<()> {
// Create our file
let mut dest = {
let fname = PathBuf::from(dst);
Expand All @@ -12,7 +12,10 @@ async fn handle_download(uri: String, dst: String) -> Result<()> {

// Download as a stream of bytes.
// there's no checking at all happening here, for anything
let mut stream = reqwest::get(uri).await?.bytes_stream();
let client = reqwest::Client::builder()
.danger_accept_invalid_certs(allow_insecure)
.build()?;
let mut stream = client.get(uri).send().await?.bytes_stream();

// Write the stream of bytes to the file in chunks
while let Some(chunk_result) = stream.next().await {
Expand All @@ -25,12 +28,17 @@ async fn handle_download(uri: String, dst: String) -> Result<()> {
Ok(())
}

pub fn download(uri: String, dst: String) -> Result<()> {
pub fn download(uri: String, dst: String, allow_insecure: Option<bool>) -> Result<()> {
let runtime = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()?;

let response = runtime.block_on(handle_download(uri, dst));
let mut insecure = false;
if let Some(a) = allow_insecure {
insecure = a;
}

let response = runtime.block_on(handle_download(uri, dst, insecure));

match response {
Ok(_) => Ok(()),
Expand Down Expand Up @@ -63,7 +71,7 @@ mod tests {
let url = server.url("/foo").to_string();

// run our code
download(url, path.clone())?;
download(url, path.clone(), None)?;

// Read the file
let contents = read_to_string(path.clone())?;
Expand Down
45 changes: 21 additions & 24 deletions implants/lib/eldritch/src/http/get_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@ pub fn get(
uri: String,
query_params: Option<SmallMap<String, String>>,
headers: Option<SmallMap<String, String>>,
allow_insecure: Option<bool>,
) -> Result<String> {
let mut query_map = HashMap::new();
let mut headers_map = HeaderMap::new();
let runtime = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()?;

if let Some(q) = query_params {
for (k, v) in q {
Expand All @@ -28,26 +26,25 @@ pub fn get(
}
}

runtime.block_on(handle_get(uri, query_map, headers_map))
}

async fn handle_get(
uri: String,
query_params: HashMap<String, String>,
headers: HeaderMap,
) -> Result<String> {
#[cfg(debug_assertions)]
log::info!(
"eldritch sending HTTP GET request to '{}' with headers '{:#?}'",
"eldritch sending HTTP GET request to '{}' with headers '{:#?}' and query_params '{:#?}'",
uri,
headers
headers_map,
query_map
);

let client = reqwest::Client::new()
.get(uri)
.headers(headers)
.query(&query_params);
let resp = client.send().await?.text().await?;
let mut insecure = false;
if let Some(a) = allow_insecure {
insecure = a;
}

let client = reqwest::blocking::Client::builder()
.danger_accept_invalid_certs(insecure)
.build()?;

let req = client.get(uri).headers(headers_map).query(&query_map);
let resp = req.send()?.text()?;
Ok(resp)
}

Expand All @@ -71,7 +68,7 @@ mod tests {
let url = server.url("/foo").to_string();

// run our code
let contents = get(url, None, None)?;
let contents = get(url, None, None, None)?;

// check request returned correctly
assert_eq!(contents, "test body");
Expand All @@ -92,7 +89,7 @@ mod tests {
let url = server.url("/foo").to_string();

// run our code
let contents = get(url, Some(SmallMap::new()), Some(SmallMap::new()))?;
let contents = get(url, Some(SmallMap::new()), Some(SmallMap::new()), None)?;

// check request returned correctly
assert_eq!(contents, "test body");
Expand Down Expand Up @@ -120,7 +117,7 @@ mod tests {
params.insert("a".to_string(), "true".to_string());
params.insert("b".to_string(), "bar".to_string());
params.insert("c".to_string(), "3".to_string());
let contents = get(url, Some(params), None)?;
let contents = get(url, Some(params), None, None)?;

// check request returned correctly
assert_eq!(contents, "test body");
Expand All @@ -147,7 +144,7 @@ mod tests {
let mut params = SmallMap::new();
params.insert("b".to_string(), "bar".to_string());
params.insert("c".to_string(), "3".to_string());
let contents = get(url, Some(params), None)?;
let contents = get(url, Some(params), None, None)?;

// check request returned correctly
assert_eq!(contents, "test body");
Expand All @@ -173,7 +170,7 @@ mod tests {
let mut headers = SmallMap::new();
headers.insert("A".to_string(), "TRUE".to_string());
headers.insert("b".to_string(), "bar".to_string());
let contents = get(url, None, Some(headers))?;
let contents = get(url, None, Some(headers), None)?;

// check request returned correctly
assert_eq!(contents, "test body");
Expand Down Expand Up @@ -202,7 +199,7 @@ mod tests {
headers.insert("b".to_string(), "bar".to_string());
let mut params = SmallMap::new();
params.insert("c".to_string(), "3".to_string());
let contents = get(url, Some(params), Some(headers))?;
let contents = get(url, Some(params), Some(headers), None)?;

// check request returned correctly
assert_eq!(contents, "test body");
Expand Down
12 changes: 6 additions & 6 deletions implants/lib/eldritch/src/http/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,18 @@ crate::eldritch_lib!(HTTPLibrary, "http_library");
#[allow(clippy::needless_lifetimes, clippy::type_complexity, clippy::too_many_arguments)]
fn methods(builder: &mut MethodsBuilder) {
#[allow(unused_variables)]
fn download(this: &HTTPLibrary, uri: String, dst: String) -> anyhow::Result<NoneType> {
download_impl::download(uri, dst)?;
fn download(this: &HTTPLibrary, uri: String, dst: String, allow_insecure: Option<bool>) -> anyhow::Result<NoneType> {
download_impl::download(uri, dst, allow_insecure)?;
Ok(NoneType{})
}

#[allow(unused_variables)]
fn get(this: &HTTPLibrary, uri: String, query_params: Option<SmallMap<String, String>>, headers: Option<SmallMap<String, String>>) -> anyhow::Result<String> {
get_impl::get(uri, query_params, headers)
fn get(this: &HTTPLibrary, uri: String, query_params: Option<SmallMap<String, String>>, headers: Option<SmallMap<String, String>>, allow_insecure: Option<bool>) -> anyhow::Result<String> {
get_impl::get(uri, query_params, headers, allow_insecure)
}

#[allow(unused_variables)]
fn post(this: &HTTPLibrary, uri: String, body: Option<String>, form: Option<SmallMap<String, String>>, headers: Option<SmallMap<String, String>>) -> anyhow::Result<String> {
post_impl::post(uri, body, form, headers)
fn post(this: &HTTPLibrary, uri: String, body: Option<String>, form: Option<SmallMap<String, String>>, headers: Option<SmallMap<String, String>>, allow_insecure: Option<bool>) -> anyhow::Result<String> {
post_impl::post(uri, body, form, headers, allow_insecure)
}
}
77 changes: 46 additions & 31 deletions implants/lib/eldritch/src/http/post_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ pub fn post(
body: Option<String>,
form: Option<SmallMap<String, String>>,
headers: Option<SmallMap<String, String>>,
allow_insecure: Option<bool>,
) -> Result<String> {
let mut headers_map = HeaderMap::new();
let runtime = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()?;

if let Some(h) = headers {
for (k, v) in h {
Expand All @@ -22,8 +20,27 @@ pub fn post(
}
}

if body.is_some() {
return runtime.block_on(handle_post(uri, body, None, headers_map));
let mut insecure = false;
if let Some(a) = allow_insecure {
insecure = a;
}

let client = reqwest::blocking::Client::builder()
.danger_accept_invalid_certs(insecure)
.build()?;
let req = client.post(uri.clone()).headers(headers_map.clone());

if let Some(b) = body {
#[cfg(debug_assertions)]
log::info!(
"eldritch sending HTTP POST request to '{}' with headers '{:#?}' and body '{}'",
uri,
headers_map,
b.clone()
);

let resp = req.body(b).send()?.text()?;
return Ok(resp);
}

if let Some(f) = form {
Expand All @@ -32,35 +49,26 @@ pub fn post(
form_map.insert(k, v);
}

return runtime.block_on(handle_post(uri, None, Some(form_map), headers_map));
}
#[cfg(debug_assertions)]
log::info!(
"eldritch sending HTTP POST request to '{}' with headers '{:#?}' and form '{:#?}'",
uri,
headers_map,
form_map.clone()
);

runtime.block_on(handle_post(uri, None, None, headers_map))
}
let resp = req.form(&form_map).send()?.text()?;
return Ok(resp);
}

async fn handle_post(
uri: String,
body: Option<String>,
form: Option<HashMap<String, String>>,
headers: HeaderMap,
) -> Result<String> {
#[cfg(debug_assertions)]
log::info!(
"eldritch sending HTTP POST request to '{}' with headers '{:#?}'",
uri,
headers
headers_map
);

let client = reqwest::Client::new().post(uri).headers(headers);
if let Some(b) = body {
let resp = client.body(b).send().await?.text().await?;
return Ok(resp);
}
if let Some(f) = form {
let resp = client.form(&f).send().await?.text().await?;
return Ok(resp);
}
let resp = client.send().await?.text().await?;
let resp = req.send()?.text()?;
Ok(resp)
}

Expand All @@ -84,7 +92,7 @@ mod tests {
let url = server.url("/foo").to_string();

// run our code
let contents = post(url, None, None, None)?;
let contents = post(url, None, None, None, None)?;

// check request returned correctly
assert_eq!(contents, "test body");
Expand All @@ -105,7 +113,13 @@ mod tests {
let url = server.url("/foo").to_string();

// run our code
let contents = post(url, None, Some(SmallMap::new()), Some(SmallMap::new()))?;
let contents = post(
url,
None,
Some(SmallMap::new()),
Some(SmallMap::new()),
None,
)?;

// check request returned correctly
assert_eq!(contents, "test body");
Expand Down Expand Up @@ -133,7 +147,7 @@ mod tests {
params.insert("a".to_string(), "true".to_string());
params.insert("b".to_string(), "bar".to_string());
params.insert("c".to_string(), "3".to_string());
let contents = post(url, None, Some(params), None)?;
let contents = post(url, None, Some(params), None, None)?;

// check request returned correctly
assert_eq!(contents, "test body");
Expand All @@ -159,7 +173,7 @@ mod tests {
let mut headers = SmallMap::new();
headers.insert("A".to_string(), "TRUE".to_string());
headers.insert("b".to_string(), "bar".to_string());
let contents = post(url, None, None, Some(headers))?;
let contents = post(url, None, None, Some(headers), None)?;

// check request returned correctly
assert_eq!(contents, "test body");
Expand Down Expand Up @@ -188,7 +202,7 @@ mod tests {
headers.insert("b".to_string(), "bar".to_string());
let mut params = SmallMap::new();
params.insert("c".to_string(), "3".to_string());
let contents = post(url, None, Some(params), Some(headers))?;
let contents = post(url, None, Some(params), Some(headers), None)?;

// check request returned correctly
assert_eq!(contents, "test body");
Expand Down Expand Up @@ -218,6 +232,7 @@ mod tests {
Some(String::from("the quick brown fox jumps over the lazy dog")),
None,
Some(headers),
None,
)?;

// check request returned correctly
Expand Down