interactsh_rs/client/mod.rs
1//! Contains the primary structures necessary for registering and polling
2//! an Interactsh server.
3//!
4//! In order to start a session with an Interactsh server, you must first
5//! build an [UnregisteredClient] using a [ClientBuilder]. Then, call the
6//! [register](UnregisteredClient::register()) function on the client to
7//! turn it into a [RegisteredClient] that can be used to poll the server.
8//! Once you are done with the client, you should call the
9//! [deregister](RegisteredClient::deregister()) function on the client
10//! to deregister with the Interactsh server and dispose of the client.
11//!
12//! The [poll](RegisteredClient::poll()) function can be used to poll the server
13//! once successfully registered. If there are new logs, they will be
14//! returned as a vec of [LogEntry](crate::interaction_log::LogEntry) (see the LogEntry page for more
15//! details).
16//!
17//! ```
18//! use std::time::Duration;
19//! # use std::thread;
20//! use interactsh_rs::prelude::*;
21//!
22//! async fn run() {
23//! // When using ClientBuilder::new(), make sure to set
24//! // all required options (server and rsa key size).
25//! let mut builder = ClientBuilder::new()
26//! .with_server("oast.pro".into())
27//! .with_rsa_key_size(2048);
28//!
29//! // These settings are optional or have default values
30//! builder = builder
31//! .with_auth_token("some-token-string".into()) // optional
32//! .with_timeout(Duration::from_secs(20)) // defaults to 15 seconds
33//! .verify_ssl(true) // defaults to false
34//! .parse_logs(false); // defaults to true
35//!
36//! // Build the client, then register with the server.
37//! let unregistered_client = builder
38//! .build()
39//! .expect("Error when building the client");
40//!
41//! let registered_client = unregistered_client
42//! .register()
43//! .await
44//! .expect("Error when registering the client");
45//!
46//! println!("INTERACTION URL: https://{}", registered_client.get_interaction_fqdn());
47//!
48//! // Start a poll loop
49//! loop {
50//! // --- (omitted) sleep and check if loop should break ---
51//! # thread::sleep(Duration::from_secs(5));
52//! # if should_end() { break; }
53//!
54//! // Poll the server for new logs
55//! let poll_data = registered_client
56//! .poll()
57//! .await
58//! .expect("Error when polling the server");
59//!
60//! let logs = match poll_data {
61//! Some(logs) => logs,
62//! None => continue,
63//! };
64//!
65//! // In the returned vec, each log may be either raw or parsed.
66//! //
67//! // Note: Parsed logs do not implement Display; log formatting
68//! // should be handled by the application using this crate.
69//! for log_entry in logs.iter() {
70//! let output = match log_entry {
71//! LogEntry::ParsedLog(log) => format_logs(log),
72//! LogEntry::RawLog(log) => log.log_entry.clone(),
73//! };
74//!
75//! println!("LOG:\n{}", output);
76//! }
77//! }
78//!
79//! // Deregister the client once completed
80//! registered_client.deregister()
81//! .await
82//! .expect("Error when deregistering the client");
83//! }
84//!
85//! fn format_logs(log_entry: &ParsedLogEntry) -> String {
86//! // --- (omitted) format the parsed logs ---
87//! # format!("{:?}", log_entry)
88//! }
89//!
90//! # fn should_end() -> bool {
91//! # false
92//! # }
93//! ```
94
95pub(crate) mod http_utils;
96
97mod builder;
98pub(crate) mod errors;
99mod registered;
100mod unregistered;
101
102pub use builder::*;
103pub use registered::*;
104pub use unregistered::*;