omyacid: default username in /vendor-data

This commit is contained in:
snow flurry 2024-08-15 21:19:59 -07:00
parent 926997c1d1
commit 61c47d735a
4 changed files with 48 additions and 8 deletions

View file

@ -43,7 +43,6 @@ async fn get_meta_data(
inst_name: &inst.name, inst_name: &inst.name,
// XXX: this is very silly imo // XXX: this is very silly imo
ssh_pubkeys: ssh_pubkeys.iter().collect(), ssh_pubkeys: ssh_pubkeys.iter().collect(),
username: Some(ctx.cfg().cloud.admin_user.as_ref()),
}; };
meta.render().map_err(|e| { meta.render().map_err(|e| {
@ -88,6 +87,41 @@ async fn get_user_data(
} }
} }
#[instrument(skip(ctx))]
async fn get_vendor_data(
State(ctx): State<ctx::Context>,
ConnectInfo(addr): ConnectInfo<SocketAddr>,
) -> Result<String, StatusCode> {
tracing::info!("Handling /vendor-data");
// All of the vendor data so far is handled globally, so this isn't really
// necessary. But it might help avoid an attacker trying to sniff for the
// admin username from an unknown instance.
if let IpAddr::V4(ip) = addr.ip() {
match ctx.get_instance(ip).await {
Ok(_) => {
let data = model::VendorData {
username: Some(&ctx.cfg().cloud.admin_user),
};
data.render().map_err(|e| {
tracing::error!("Renderer error: {e}");
StatusCode::INTERNAL_SERVER_ERROR
})
}
Err(err) => {
tracing::error!("{err}");
Err(StatusCode::INTERNAL_SERVER_ERROR)
}
_ => {
tracing::warn!("Request from unregistered server {ip}");
Err(StatusCode::FORBIDDEN)
}
}
} else {
Err(StatusCode::BAD_REQUEST)
}
}
async fn ignored() -> &'static str { async fn ignored() -> &'static str {
"" ""
} }
@ -131,7 +165,7 @@ async fn main() -> ExitCode {
let app = Router::new() let app = Router::new()
.route("/meta-data", get(get_meta_data)) .route("/meta-data", get(get_meta_data))
.route("/user-data", get(get_user_data)) .route("/user-data", get(get_user_data))
.route("/vendor-data", get(ignored)) .route("/vendor-data", get(get_vendor_data))
.route("/network-config", get(ignored)) .route("/network-config", get(ignored))
.with_state(ctx); .with_state(ctx);
if let Err(err) = axum::serve( if let Err(err) = axum::serve(

View file

@ -4,5 +4,10 @@ use askama::Template;
pub struct Metadata<'a> { pub struct Metadata<'a> {
pub inst_name: &'a str, pub inst_name: &'a str,
pub ssh_pubkeys: Vec<&'a String>, pub ssh_pubkeys: Vec<&'a String>,
}
#[derive(Template)]
#[template(path = "vendor-data.yml")]
pub struct VendorData<'a> {
pub username: Option<&'a str>, pub username: Option<&'a str>,
} }

View file

@ -5,9 +5,4 @@ public-keys:
{% for key in ssh_pubkeys -%} {% for key in ssh_pubkeys -%}
- "{{ key }}" - "{{ key }}"
{% endfor %} {% endfor %}
{%- endif -%} {%- endif -%}
{% if let Some(user) = username -%}
system_info:
default_user:
name: "{{ user }}"
{%- endif %}

View file

@ -0,0 +1,6 @@
#cloud-config
{% if let Some(user) = username -%}
system_info:
default_user:
name: "{{ user }}"
{%- endif %}