pwnboard_rs/
lib.rs

1//! HTTP Bindings for Pwnboard!
2//! 
3use reqwest::{Client, Response};
4use serde_json::{json, value::Value};
5use std::error::Error;
6
7/// Struct for Pwnboard client
8/// 
9/// Allows for communicationi between application and API route
10/// 
11/// # Examples
12/// ```
13/// use pwnboard_rs::Pwnboard
14/// 
15/// fn main() {
16///     let pwn = Pwnboard::new("https://pwnboard.win").expect("Failed to create client");
17/// }
18/// ```
19pub struct Pwnboard {
20    pub uri: String,
21    client: Client,
22}
23
24/// Defines Log Level for Log route
25#[derive(Debug)]
26pub enum LogLevel {
27    Loot,
28    Info,
29    Warn,
30    Error,
31}
32
33impl From<LogLevel> for Value {
34    fn from(level: LogLevel) -> Value {
35        format!("{:?}", level).to_lowercase().into()
36    }
37}
38
39impl Pwnboard {
40    /// Creates new Pwnboard client pointing to given URI
41    pub fn new(uri: &str) -> Result<Pwnboard, Box<dyn Error>> {
42        let client = Client::new();
43        let uri = String::from(uri);
44        let last = uri
45            .chars()
46            .last()
47            .ok_or("Unable to check URI last character. Is it blank?")?;
48        if last == '/' {
49            Err("Invalid URI - Please do not provide trailing slash")?
50        } else {
51            Ok(Pwnboard { uri, client })
52        }
53    }
54
55    /// Indicates access to a box via given application
56    pub async fn boxaccess(
57        &self,
58        ip: &str,
59        application: &str,
60        ips: Option<&[&str]>,
61        access_type: Option<&str>,
62        message: Option<&str>,
63    ) -> Result<Response, Box<dyn Error>> {
64        let mut output_json = json!({
65            "ip": ip,
66            "application": application,
67        });
68        if let Some(ip_val) = ips {
69            output_json
70                .as_object_mut()
71                .ok_or("Error in Creating JSON")?
72                .insert("ips".to_owned(), ip_val.into());
73        }
74        if let Some(access_val) = access_type {
75            output_json
76                .as_object_mut()
77                .ok_or("Error in Creating JSON")?
78                .insert("access_type".to_owned(), access_val.into());
79        }
80        if let Some(message_val) = message {
81            output_json
82                .as_object_mut()
83                .ok_or("Error in Creating JSON")?
84                .insert("message".to_owned(), message_val.into());
85        }
86        Ok(self
87            .client
88            .post(&format!("{}/pwn/boxaccess", self.uri))
89            .json(&output_json)
90            .send()
91            .await?)
92    }
93
94    /// Send credentials for box up to Pwnboard
95    pub async fn credential(
96        &self,
97        ip: &str,
98        service: &str,
99        message: Option<&str>,
100        username: Option<&str>,
101        password: &str,
102    ) -> Result<Response, Box<dyn Error>> {
103        let mut output_json = json!({
104            "ip": ip,
105            "service": service,
106            "password": password,
107        });
108        if let Some(message_val) = message {
109            output_json
110                .as_object_mut()
111                .ok_or("Error in Creating JSON")?
112                .insert("message".to_owned(), message_val.into());
113        }
114        if let Some(username_val) = username {
115            output_json
116                .as_object_mut()
117                .ok_or("Error in Creating JSON")?
118                .insert("username".to_owned(), username_val.into());
119        }
120        Ok(self
121            .client
122            .post(&format!("{}/pwn/credential", self.uri))
123            .json(&output_json)
124            .send()
125            .await?)
126    }
127
128    /// Send log to pwnboard for given service
129    pub async fn log(
130        &self,
131        ip: &str,
132        message: &str,
133        service: &str,
134        level: Option<LogLevel>,
135    ) -> Result<Response, Box<dyn Error>> {
136        let mut output_json = json!({
137            "ip": ip,
138            "message": message,
139            "service": service,
140
141        });
142        if let Some(level_val) = level {
143            output_json
144                .as_object_mut()
145                .ok_or("Error in Creating JSON")?
146                .insert("level".to_owned(), level_val.into());
147        }
148        Ok(self
149            .client
150            .post(&format!("{}/pwn/log", self.uri))
151            .json(&output_json)
152            .send()
153            .await?)
154    }
155}