From 0d02a5eb615861518b43d9f98de29b7dec9a34ed Mon Sep 17 00:00:00 2001 From: Andrew McKenzie Date: Thu, 28 Sep 2023 14:29:24 +0100 Subject: [PATCH] verify asserted device type against wifi HB cell type --- Cargo.lock | 6 +++--- Cargo.toml | 4 ++-- mobile_config/src/gateway_info.rs | 17 ++++++++++++++--- mobile_verifier/src/cell_type.rs | 9 +++++++++ mobile_verifier/src/heartbeats/mod.rs | 17 +++++++++++++++++ 5 files changed, 45 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 58d52dd39..f2a31f002 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1130,7 +1130,7 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "beacon" version = "0.1.0" -source = "git+https://github.com/helium/proto?branch=master#d94ed4b4046263eb78003d484d94ad3cbff7a55f" +source = "git+https://github.com/helium/proto?branch=andymck/verify-hb-cell-type#1ac4ca2379ff85ae37c3ef3eb95d91222546e83c" dependencies = [ "base64 0.21.0", "byteorder", @@ -1140,7 +1140,7 @@ dependencies = [ "rand_chacha 0.3.0", "rust_decimal", "serde", - "sha2 0.10.6", + "sha2 0.9.9", "thiserror", ] @@ -2990,7 +2990,7 @@ dependencies = [ [[package]] name = "helium-proto" version = "0.1.0" -source = "git+https://github.com/helium/proto?branch=master#d94ed4b4046263eb78003d484d94ad3cbff7a55f" +source = "git+https://github.com/helium/proto?branch=andymck/verify-hb-cell-type#1ac4ca2379ff85ae37c3ef3eb95d91222546e83c" dependencies = [ "bytes", "prost", diff --git a/Cargo.toml b/Cargo.toml index 49e051553..efacf2433 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,14 +61,14 @@ sqlx = {version = "0", features = [ ]} helium-crypto = {version = "0.8.1", features=["sqlx-postgres", "multisig"]} -helium-proto = {git = "https://github.com/helium/proto", branch = "master", features = ["services"]} +helium-proto = {git = "https://github.com/helium/proto", branch = "andymck/verify-hb-cell-type", features = ["services"]} hextree = "*" solana-client = "1.14" solana-sdk = "1.14" solana-program = "1.11" spl-token = "3.5.0" reqwest = {version = "0", default-features=false, features = ["gzip", "json", "rustls-tls"]} -beacon = { git = "https://github.com/helium/proto", branch = "master" } +beacon = { git = "https://github.com/helium/proto", branch = "andymck/verify-hb-cell-type" } humantime = "2" metrics = "0" metrics-exporter-prometheus = "0" diff --git a/mobile_config/src/gateway_info.rs b/mobile_config/src/gateway_info.rs index 2126d2efb..3c68fe532 100644 --- a/mobile_config/src/gateway_info.rs +++ b/mobile_config/src/gateway_info.rs @@ -3,12 +3,12 @@ use helium_crypto::PublicKeyBinary; use helium_proto::services::mobile_config::{ GatewayInfo as GatewayInfoProto, GatewayMetadata as GatewayMetadataProto, }; - pub type GatewayInfoStream = BoxStream<'static, GatewayInfo>; #[derive(Clone, Debug)] pub struct GatewayMetadata { pub location: u64, + pub device_type: Option, } #[derive(Clone, Debug)] @@ -32,12 +32,17 @@ pub trait GatewayInfoResolver { impl From for GatewayInfo { fn from(info: GatewayInfoProto) -> Self { let metadata = if let Some(metadata) = info.metadata { + let device_type = metadata.device_type.parse().ok(); u64::from_str_radix(&metadata.location, 16) - .map(|location| GatewayMetadata { location }) + .map(|location| GatewayMetadata { + location, + device_type, + }) .ok() } else { None }; + Self { address: info.address.into(), metadata, @@ -52,6 +57,7 @@ impl TryFrom for GatewayInfoProto { let metadata = if let Some(metadata) = info.metadata { Some(GatewayMetadataProto { location: hextree::Cell::from_raw(metadata.location)?.to_string(), + device_type: metadata.device_type.unwrap_or_default(), }) } else { None @@ -67,11 +73,12 @@ pub(crate) mod db { use super::{GatewayInfo, GatewayMetadata}; use futures::stream::{Stream, StreamExt}; use helium_crypto::PublicKeyBinary; + use sqlx::types::Json; use sqlx::{PgExecutor, Row}; use std::str::FromStr; const GET_METADATA_SQL: &str = r#" - select kta.entity_key, infos.location::bigint + select kta.entity_key, infos.location::bigint, infos.device_type from mobile_hotspot_infos infos join key_to_assets kta on infos.asset = kta.asset "#; @@ -102,10 +109,14 @@ pub(crate) mod db { impl sqlx::FromRow<'_, sqlx::postgres::PgRow> for GatewayInfo { fn from_row(row: &sqlx::postgres::PgRow) -> sqlx::Result { + let device_type = row + .get::>, &str>("device_type") + .map(|s| s.to_string()); let metadata = row .get::, &str>("location") .map(|loc| GatewayMetadata { location: loc as u64, + device_type, }); Ok(Self { address: PublicKeyBinary::from_str( diff --git a/mobile_verifier/src/cell_type.rs b/mobile_verifier/src/cell_type.rs index 8ac2db40a..8a9d717e6 100644 --- a/mobile_verifier/src/cell_type.rs +++ b/mobile_verifier/src/cell_type.rs @@ -87,6 +87,15 @@ impl CellType { _ => dec!(1.0), } } + + pub fn from_asserted(s: &Option) -> Option { + // TODO: currently only handling wifi indoor, handle other cell types + // when foundation device type values are in use + match s { + Some(s) if s.eq("wifiIndoor") => Some(CellType::NovaGenericWifiIndoor), + _ => None, + } + } } impl From for CellTypeProto { diff --git a/mobile_verifier/src/heartbeats/mod.rs b/mobile_verifier/src/heartbeats/mod.rs index 2cbb9cb1c..ebe215735 100644 --- a/mobile_verifier/src/heartbeats/mod.rs +++ b/mobile_verifier/src/heartbeats/mod.rs @@ -400,6 +400,23 @@ pub async fn validate_heartbeat( )); }; + // verify the HB cell type matches that on chain + // TODO: currently only handling wifi indoor + // make this check generic and applicable to all cell types + // when device data is available in the db + match ( + heartbeat.hb_type.clone(), + CellType::from_asserted(&metadata.device_type), + ) { + (HBType::Wifi, Some(asserted_celltype)) if asserted_celltype != cell_type => { + return Ok((cell_type, proto::HeartbeatValidity::BadCellType, None)); + } + (HBType::Wifi, None) => { + return Ok((cell_type, proto::HeartbeatValidity::BadCellType, None)) + } + _ => (), + }; + let distance_to_asserted = if heartbeat.hb_type == HBType::Wifi { Some(heartbeat.asserted_distance(metadata.location)?) } else {