diff --git a/src/config.rs b/src/config.rs index 2c11897b..976fa995 100644 --- a/src/config.rs +++ b/src/config.rs @@ -14,7 +14,7 @@ const AUTHKEY_VAR: &str = "TS_AUTH_KEY"; /// Config for connecting to Tailscale. pub struct Config { /// The cryptographic keys representing this node's identity. - pub key_state: NodeState, + pub key_state: PersistState, // TODO(npry): let clients also define an app name once the sdk-level name moves // to a dedicated field @@ -43,7 +43,7 @@ impl Config { /// the key file. pub async fn default_with_key_file(p: impl AsRef) -> Result { Ok(Config { - key_state: load_key_file(p, Default::default()).await?.into(), + key_state: load_key_file(p, Default::default()).await?, ..Default::default() }) } diff --git a/src/lib.rs b/src/lib.rs index 1ba45cae..25e86b6f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -174,7 +174,7 @@ impl Device { check_magic_env()?; let rt = - ts_runtime::Runtime::spawn(config.into(), auth_key, config.key_state.clone()).await?; + ts_runtime::Runtime::spawn(config.into(), auth_key, (&config.key_state).into()).await?; let channel = rt.channel().await?; Ok(Self { diff --git a/ts_cli_util/src/lib.rs b/ts_cli_util/src/lib.rs index f126306f..bad5094a 100644 --- a/ts_cli_util/src/lib.rs +++ b/ts_cli_util/src/lib.rs @@ -57,7 +57,7 @@ impl CommonArgs { let (client, stream) = ts_control::AsyncControlClient::connect( &(&config).into(), - &config.key_state, + &(&config.key_state).into(), self.auth_key.as_deref(), ) .await?; diff --git a/ts_devtools/src/bin/derp_ping.rs b/ts_devtools/src/bin/derp_ping.rs index 218510a2..6ec3d683 100644 --- a/ts_devtools/src/bin/derp_ping.rs +++ b/ts_devtools/src/bin/derp_ping.rs @@ -40,13 +40,13 @@ async fn main() -> ts_cli_util::Result<()> { tracing::info!(?region_id, "starting derp transport"); - let derp = - ts_transport_derp::Client::connect(&derp_servers, &config.key_state.node_keys).await?; + let derp = ts_transport_derp::Client::connect(&derp_servers, &config.key_state.node_key.into()) + .await?; let derp = Arc::new(derp); let peer = args .send_to_self - .then_some(config.key_state.node_keys.public) + .then_some(config.key_state.node_key.public_key()) .or(args.peer); if let Some(peer) = peer { diff --git a/ts_elixir/native/ts_elixir/src/config.rs b/ts_elixir/native/ts_elixir/src/config.rs index f03190b4..888c9b3a 100644 --- a/ts_elixir/native/ts_elixir/src/config.rs +++ b/ts_elixir/native/ts_elixir/src/config.rs @@ -1,7 +1,6 @@ use std::collections::HashMap; use rustler::{Atom, NifResult, Term}; -use tailscale::keys::{DiscoPrivateKey, MachinePrivateKey, NetworkLockPrivateKey, NodePrivateKey}; mod atoms { rustler::atoms! { @@ -61,22 +60,20 @@ pub fn config_from_erl( pub struct Keystate { pub machine: Vec, pub node: Vec, - pub disco: Vec, pub network_lock: Vec, } -impl From for Keystate { - fn from(value: tailscale::keys::NodeState) -> Self { +impl From for Keystate { + fn from(value: tailscale::keys::PersistState) -> Self { Self { - machine: value.machine_keys.private.to_bytes().into(), - node: value.node_keys.private.to_bytes().into(), - disco: value.disco_keys.private.to_bytes().into(), - network_lock: value.network_lock_keys.private.to_bytes().into(), + machine: value.machine_key.to_bytes().into(), + node: value.node_key.to_bytes().into(), + network_lock: value.network_lock_key.to_bytes().into(), } } } -impl TryFrom for tailscale::keys::NodeState { +impl TryFrom for tailscale::keys::PersistState { type Error = (); fn try_from(value: Keystate) -> Result { @@ -88,10 +85,9 @@ impl TryFrom for tailscale::keys::NodeState { } Ok(Self { - machine_keys: key::(value.machine)?.into(), - node_keys: key::(value.node)?.into(), - disco_keys: key::(value.disco)?.into(), - network_lock_keys: key::(value.network_lock)?.into(), + machine_key: key(value.machine)?, + node_key: key(value.node)?, + network_lock_key: key(value.network_lock)?, }) } } diff --git a/ts_elixir/native/ts_elixir/src/lib.rs b/ts_elixir/native/ts_elixir/src/lib.rs index e8474bfe..5836de49 100644 --- a/ts_elixir/native/ts_elixir/src/lib.rs +++ b/ts_elixir/native/ts_elixir/src/lib.rs @@ -128,11 +128,7 @@ fn connect<'env>( fn load_key_file(env: rustler::Env, path: &str) -> impl Encoder { let result = TOKIO_RUNTIME .block_on(tailscale::config::load_key_file(path, Default::default())) - .map(|keys| { - let keys: tailscale::keys::NodeState = keys.into(); - let result: Keystate = keys.into(); - result - }) + .map(Keystate::from) .map_err(Into::into); erl_result(env, result) diff --git a/ts_ffi/examples/udp_ping.c b/ts_ffi/examples/udp_ping.c index d36fb315..cf6315f0 100644 --- a/ts_ffi/examples/udp_ping.c +++ b/ts_ffi/examples/udp_ping.c @@ -34,7 +34,7 @@ int main(int argc, char** argv) { * See the TCP example for a usage of `ts_init_from_key_file`, which collapses this init to a * single line, using a default config and key state from the selected file. */ - struct ts_node_key_state key_state = {0}; + struct ts_persisted_key_state key_state = {0}; assert(ts_load_key_file(argv[1], false, &key_state) >= 0); struct ts_config config = {0}; diff --git a/ts_ffi/src/config.rs b/ts_ffi/src/config.rs index dcf42879..cd7d8d78 100644 --- a/ts_ffi/src/config.rs +++ b/ts_ffi/src/config.rs @@ -1,6 +1,6 @@ use std::ffi::c_char; -use crate::{keys::node_key_state, util}; +use crate::{keys::persisted_key_state, util}; /// Tailscale configuration. /// @@ -38,7 +38,7 @@ pub struct config<'a> { /// The key state to use. /// /// If `NULL`, ephemeral key state is generated. - pub key_state: Option<&'a mut node_key_state>, + pub key_state: Option<&'a mut persisted_key_state>, } impl config<'_> { diff --git a/ts_ffi/src/keys.rs b/ts_ffi/src/keys.rs index 7d89021c..7543d49a 100644 --- a/ts_ffi/src/keys.rs +++ b/ts_ffi/src/keys.rs @@ -31,12 +31,12 @@ macro_rules! impl_to_from { impl From<$key> for key { fn from(value: $key) -> Self { - key(conv::<[u8; 32]>(value)) + key(value.into()) } } impl From<&$key> for key { fn from(value: &$key) -> Self { - key(conv::<[u8; 32]>(*value)) + key((*value).into()) } } }; @@ -56,48 +56,37 @@ impl_to_from!( /// Tailscale key state for running a device. #[derive(Debug, Default)] #[repr(C)] -pub struct node_key_state { +pub struct persisted_key_state { /// Private key for the node (device) identity. pub node_private_key: key, /// Private key for the machine. pub machine_private_key: key, /// Private key for tailnet lock. pub network_lock_private_key: key, - /// Private key for Tailscale discovery protocol (disco). - pub disco_private_key: key, } -fn conv(u: impl Into) -> T { - u.into() -} - -impl From for ts_keys::NodeState { - fn from(value: node_key_state) -> Self { +impl From for ts_keys::PersistState { + fn from(value: persisted_key_state) -> Self { (&value).into() } } -impl From<&node_key_state> for ts_keys::NodeState { - fn from(value: &node_key_state) -> Self { - ts_keys::NodeState { - disco_keys: conv::(&value.disco_private_key).into(), - machine_keys: conv::(&value.machine_private_key).into(), - network_lock_keys: conv::( - &value.network_lock_private_key, - ) - .into(), - node_keys: conv::(&value.node_private_key).into(), +impl From<&persisted_key_state> for ts_keys::PersistState { + fn from(value: &persisted_key_state) -> Self { + ts_keys::PersistState { + machine_key: (&value.machine_private_key).into(), + network_lock_key: (&value.network_lock_private_key).into(), + node_key: (&value.node_private_key).into(), } } } -impl From for node_key_state { - fn from(value: ts_keys::NodeState) -> Self { +impl From for persisted_key_state { + fn from(value: ts_keys::PersistState) -> Self { Self { - machine_private_key: value.machine_keys.private.into(), - network_lock_private_key: value.network_lock_keys.private.into(), - disco_private_key: value.disco_keys.private.into(), - node_private_key: value.node_keys.private.into(), + machine_private_key: value.machine_key.into(), + network_lock_private_key: value.network_lock_key.into(), + node_private_key: value.node_key.into(), } } } @@ -117,7 +106,7 @@ impl From for node_key_state { pub unsafe extern "C" fn ts_load_key_file( path: *const c_char, overwrite_if_invalid: bool, - key_state: &mut node_key_state, + key_state: &mut persisted_key_state, ) -> ffi::c_int { let s = unsafe { CStr::from_ptr(path) }; let s = match s.to_str() { @@ -138,7 +127,6 @@ pub unsafe extern "C" fn ts_load_key_file( match TOKIO_RUNTIME.block_on(tailscale::config::load_key_file(s, mode)) { Ok(state) => { - let state: tailscale::keys::NodeState = state.into(); *key_state = state.into(); tracing::info!(?key_state, "loaded key state"); diff --git a/ts_ffi/src/lib.rs b/ts_ffi/src/lib.rs index dda7d87e..3ce6c91a 100644 --- a/ts_ffi/src/lib.rs +++ b/ts_ffi/src/lib.rs @@ -135,7 +135,7 @@ pub unsafe extern "C" fn ts_init_from_key_file( key_file: *const c_char, auth_token: *const c_char, ) -> Option> { - let mut state = keys::node_key_state::default(); + let mut state = keys::persisted_key_state::default(); // SAFETY: CStr invariants maintained by function precondition if unsafe { keys::ts_load_key_file(key_file, false, &mut state) } < 0 { diff --git a/ts_python/src/key_state.rs b/ts_python/src/key_state.rs index 67b77c10..b77209b3 100644 --- a/ts_python/src/key_state.rs +++ b/ts_python/src/key_state.rs @@ -1,5 +1,3 @@ -use ts::keys::{DiscoPrivateKey, MachinePrivateKey, NetworkLockPrivateKey, NodePrivateKey}; - /// Tailscale keys. #[derive(Debug, Clone, PartialEq, Eq)] #[pyo3::pyclass(frozen, get_all, from_py_object, module = "tailscale")] @@ -8,8 +6,6 @@ pub struct Keystate { pub machine: Vec, /// Node (device) key. pub node: Vec, - /// Disco key. - pub disco: Vec, /// Network lock key. pub network_lock: Vec, } @@ -17,16 +13,13 @@ pub struct Keystate { #[pyo3::pymethods] impl Keystate { #[new] - #[pyo3(signature = (machine=None, node=None, disco=None, network_lock=None))] + #[pyo3(signature = (machine=None, node=None, network_lock=None))] pub fn new( machine: Option>, node: Option>, - disco: Option>, network_lock: Option>, ) -> Self { - let mut out = Self { - ..ts::keys::NodeState::default().into() - }; + let mut out: Self = ts::keys::PersistState::default().into(); if let Some(machine) = machine { out.machine = machine; @@ -36,10 +29,6 @@ impl Keystate { out.node = node; } - if let Some(disco) = disco { - out.disco = disco; - } - if let Some(network_lock) = network_lock { out.network_lock = network_lock; } @@ -48,14 +37,13 @@ impl Keystate { } pub fn __repr__(&self) -> String { - match tailscale::keys::NodeState::try_from(self) { + match tailscale::keys::PersistState::try_from(self) { Ok(state) => { format!( - "tailscale.Keystate(machine={}, node={}, disco={}, network_lock={})", - hex::encode(state.machine_keys.public.to_bytes()), - hex::encode(state.node_keys.public.to_bytes()), - hex::encode(state.disco_keys.public.to_bytes()), - hex::encode(state.network_lock_keys.public.to_bytes()), + "tailscale.Keystate(machine={}, node={}, network_lock={})", + hex::encode(state.machine_key.public_key().to_bytes()), + hex::encode(state.node_key.public_key().to_bytes()), + hex::encode(state.network_lock_key.public_key().to_bytes()), ) } Err(_) => "tailscale.Keystate()".to_owned(), @@ -63,18 +51,17 @@ impl Keystate { } } -impl From for Keystate { - fn from(value: tailscale::keys::NodeState) -> Self { +impl From for Keystate { + fn from(value: tailscale::keys::PersistState) -> Self { Self { - machine: value.machine_keys.private.to_bytes().into(), - node: value.node_keys.private.to_bytes().into(), - disco: value.disco_keys.private.to_bytes().into(), - network_lock: value.network_lock_keys.private.to_bytes().into(), + machine: value.machine_key.to_bytes().into(), + node: value.node_key.to_bytes().into(), + network_lock: value.network_lock_key.to_bytes().into(), } } } -impl TryFrom<&Keystate> for tailscale::keys::NodeState { +impl TryFrom<&Keystate> for tailscale::keys::PersistState { type Error = (); fn try_from(value: &Keystate) -> Result { @@ -86,10 +73,9 @@ impl TryFrom<&Keystate> for tailscale::keys::NodeState { } Ok(Self { - machine_keys: key::(&value.machine)?.into(), - node_keys: key::(&value.node)?.into(), - disco_keys: key::(&value.disco)?.into(), - network_lock_keys: key::(&value.network_lock)?.into(), + machine_key: key(&value.machine)?, + node_key: key(&value.node)?, + network_lock_key: key(&value.network_lock)?, }) } }