+42
src/bin/resolve.rs
+42
src/bin/resolve.rs
···
1
+
use std::env;
2
+
3
+
use anyhow::Result;
4
+
use smokesignal::config::{default_env, optional_env, version, CertificateBundles, DnsNameservers};
5
+
use tracing_subscriber::{layer::SubscriberExt as _, util::SubscriberInitExt as _};
6
+
7
+
#[tokio::main]
8
+
async fn main() -> Result<()> {
9
+
tracing_subscriber::registry()
10
+
.with(tracing_subscriber::EnvFilter::new(
11
+
std::env::var("RUST_LOG").unwrap_or_else(|_| "trace".into()),
12
+
))
13
+
.with(tracing_subscriber::fmt::layer().pretty())
14
+
.init();
15
+
16
+
let certificate_bundles: CertificateBundles = optional_env("CERTIFICATE_BUNDLES").try_into()?;
17
+
let default_user_agent = format!("smokesignal ({}; +https://smokesignal.events/)", version()?);
18
+
let user_agent = default_env("USER_AGENT", &default_user_agent);
19
+
let dns_nameservers: DnsNameservers = optional_env("DNS_NAMESERVERS").try_into()?;
20
+
21
+
let mut client_builder = reqwest::Client::builder();
22
+
for ca_certificate in certificate_bundles.as_ref() {
23
+
tracing::info!("Loading CA certificate: {:?}", ca_certificate);
24
+
let cert = std::fs::read(ca_certificate)?;
25
+
let cert = reqwest::Certificate::from_pem(&cert)?;
26
+
client_builder = client_builder.add_root_certificate(cert);
27
+
}
28
+
29
+
client_builder = client_builder.user_agent(user_agent);
30
+
let http_client = client_builder.build()?;
31
+
32
+
// Initialize the DNS resolver with configuration from the app config
33
+
let dns_resolver = smokesignal::resolve::create_resolver(dns_nameservers);
34
+
35
+
for subject in env::args() {
36
+
let resolved_did =
37
+
smokesignal::resolve::resolve_subject(&http_client, &dns_resolver, &subject).await;
38
+
tracing::info!(?resolved_did, ?subject, "resolved subject");
39
+
}
40
+
41
+
Ok(())
42
+
}
+1
-1
src/bin/smokesignal.rs
+1
-1
src/bin/smokesignal.rs
···
80
80
let jinja = reload_env::build_env(&config.external_base, &config.version);
81
81
82
82
// Initialize the DNS resolver with configuration from the app config
83
-
let dns_resolver = create_resolver(&config);
83
+
let dns_resolver = create_resolver(config.dns_nameservers.clone());
84
84
85
85
let web_context = WebContext::new(
86
86
pool.clone(),
+4
-4
src/config.rs
+4
-4
src/config.rs
···
56
56
let http_cookie_key: HttpCookieKey =
57
57
require_env("HTTP_COOKIE_KEY").and_then(|value| value.try_into())?;
58
58
59
-
let http_static_path = default_env("HTTP_STATIC_PATH", "static").try_into()?;
59
+
let http_static_path = default_env("HTTP_STATIC_PATH", "static");
60
60
61
61
let external_base = require_env("EXTERNAL_BASE")?;
62
62
···
134
134
}
135
135
}
136
136
137
-
fn require_env(name: &str) -> Result<String> {
137
+
pub fn require_env(name: &str) -> Result<String> {
138
138
std::env::var(name).map_err(|_| ConfigError::EnvVarRequired(name.to_string()).into())
139
139
}
140
140
141
-
fn optional_env(name: &str) -> String {
141
+
pub fn optional_env(name: &str) -> String {
142
142
std::env::var(name).unwrap_or("".to_string())
143
143
}
144
144
145
-
fn default_env(name: &str, default_value: &str) -> String {
145
+
pub fn default_env(name: &str, default_value: &str) -> String {
146
146
std::env::var(name).unwrap_or(default_value.to_string())
147
147
}
148
148
+5
-3
src/did.rs
+5
-3
src/did.rs
···
4
4
use serde_json::Value;
5
5
use std::collections::HashMap;
6
6
7
-
#[derive(Clone, Deserialize)]
7
+
#[derive(Clone, Deserialize, Debug)]
8
8
#[serde(rename_all = "camelCase")]
9
9
pub struct Service {
10
10
pub id: String,
···
14
14
pub service_endpoint: String,
15
15
}
16
16
17
-
#[derive(Clone, Deserialize)]
17
+
#[derive(Clone, Deserialize, Debug)]
18
18
#[serde(tag = "type", rename_all = "camelCase")]
19
19
pub enum VerificationMethod {
20
20
Multikey {
···
30
30
},
31
31
}
32
32
33
-
#[derive(Clone, Deserialize)]
33
+
#[derive(Clone, Deserialize, Debug)]
34
34
#[serde(rename_all = "camelCase")]
35
35
pub struct Document {
36
36
pub id: String,
···
209
209
210
210
pub async fn query_hostname(http_client: &reqwest::Client, hostname: &str) -> Result<Document> {
211
211
let url = format!("https://{}/.well-known/did.json", hostname);
212
+
213
+
tracing::debug!(?url, "query_hostname");
212
214
213
215
http_client
214
216
.get(&url)
+1
-1
src/jose.rs
+1
-1
src/jose.rs
···
97
97
Signature::try_from(signature_bytes.as_slice()).map_err(|_| JoseError::InvalidSignature)?;
98
98
99
99
// Verify signature
100
-
let verifying_key = VerifyingKey::from(public_key.clone());
100
+
let verifying_key = VerifyingKey::from(public_key);
101
101
let content = format!("{}.{}", encoded_header, encoded_claims);
102
102
103
103
verifying_key
+13
-3
src/resolve.rs
+13
-3
src/resolve.rs
···
8
8
use std::collections::HashSet;
9
9
use std::time::Duration;
10
10
11
-
use crate::config::Config;
11
+
use crate::config::DnsNameservers;
12
12
use crate::did::web::query_hostname;
13
13
14
14
pub enum InputType {
···
111
111
)
112
112
.await;
113
113
114
+
tracing::debug!(
115
+
?handle,
116
+
?dns_lookup,
117
+
?http_lookup,
118
+
?did_web_lookup,
119
+
"raw query results"
120
+
);
121
+
114
122
let did_web_lookup_did = did_web_lookup
115
123
.map(|document| document.id)
116
124
.map_err(ResolveError::DIDWebResolutionFailed);
···
122
130
if results.is_empty() {
123
131
return Err(ResolveError::NoDIDsFound);
124
132
}
133
+
134
+
tracing::debug!(?handle, ?results, "query results");
125
135
126
136
let first = results[0].clone();
127
137
if results.iter().all(|result| result == &first) {
···
145
155
///
146
156
/// If custom nameservers are configured in app config, they will be used.
147
157
/// Otherwise, the system default resolver configuration will be used.
148
-
pub fn create_resolver(config: &Config) -> TokioAsyncResolver {
158
+
pub fn create_resolver(nameservers: DnsNameservers) -> TokioAsyncResolver {
149
159
// Initialize the DNS resolver with custom nameservers if configured
150
-
let nameservers = config.dns_nameservers.as_ref();
160
+
let nameservers = nameservers.as_ref();
151
161
let resolver_config = if !nameservers.is_empty() {
152
162
// Use custom nameservers
153
163
tracing::info!("Using custom DNS nameservers: {:?}", nameservers);