Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -43,7 +43,7 @@ impl Config {
/// the key file.
pub async fn default_with_key_file(p: impl AsRef<Path>) -> Result<Self, crate::Error> {
Ok(Config {
key_state: load_key_file(p, Default::default()).await?.into(),
key_state: load_key_file(p, Default::default()).await?,
..Default::default()
})
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion ts_cli_util/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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?;
Expand Down
6 changes: 3 additions & 3 deletions ts_devtools/src/bin/derp_ping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
22 changes: 9 additions & 13 deletions ts_elixir/native/ts_elixir/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::collections::HashMap;

use rustler::{Atom, NifResult, Term};
use tailscale::keys::{DiscoPrivateKey, MachinePrivateKey, NetworkLockPrivateKey, NodePrivateKey};

mod atoms {
rustler::atoms! {
Expand Down Expand Up @@ -61,22 +60,20 @@ pub fn config_from_erl(
pub struct Keystate {
pub machine: Vec<u8>,
pub node: Vec<u8>,
pub disco: Vec<u8>,
pub network_lock: Vec<u8>,
}

impl From<tailscale::keys::NodeState> for Keystate {
fn from(value: tailscale::keys::NodeState) -> Self {
impl From<tailscale::keys::PersistState> 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<Self, ()> {
Expand All @@ -88,10 +85,9 @@ impl TryFrom<Keystate> for tailscale::keys::NodeState {
}

Ok(Self {
machine_keys: key::<MachinePrivateKey>(value.machine)?.into(),
node_keys: key::<NodePrivateKey>(value.node)?.into(),
disco_keys: key::<DiscoPrivateKey>(value.disco)?.into(),
network_lock_keys: key::<NetworkLockPrivateKey>(value.network_lock)?.into(),
machine_key: key(value.machine)?,
node_key: key(value.node)?,
network_lock_key: key(value.network_lock)?,
})
}
}
6 changes: 1 addition & 5 deletions ts_elixir/native/ts_elixir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion ts_ffi/examples/udp_ping.c
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
4 changes: 2 additions & 2 deletions ts_ffi/src/config.rs
Original file line number Diff line number Diff line change
@@ -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.
///
Expand Down Expand Up @@ -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<'_> {
Expand Down
46 changes: 17 additions & 29 deletions ts_ffi/src/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
}
};
Expand All @@ -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<T>(u: impl Into<T>) -> T {
u.into()
}

impl From<node_key_state> for ts_keys::NodeState {
fn from(value: node_key_state) -> Self {
impl From<persisted_key_state> 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::<ts_keys::DiscoPrivateKey>(&value.disco_private_key).into(),
machine_keys: conv::<ts_keys::MachinePrivateKey>(&value.machine_private_key).into(),
network_lock_keys: conv::<ts_keys::NetworkLockPrivateKey>(
&value.network_lock_private_key,
)
.into(),
node_keys: conv::<ts_keys::NodePrivateKey>(&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<ts_keys::NodeState> for node_key_state {
fn from(value: ts_keys::NodeState) -> Self {
impl From<ts_keys::PersistState> 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(),
}
}
}
Expand All @@ -117,7 +106,7 @@ impl From<ts_keys::NodeState> 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() {
Expand All @@ -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");

Expand Down
2 changes: 1 addition & 1 deletion ts_ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Box<device>> {
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 {
Expand Down
46 changes: 16 additions & 30 deletions ts_python/src/key_state.rs
Original file line number Diff line number Diff line change
@@ -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")]
Expand All @@ -8,25 +6,20 @@ pub struct Keystate {
pub machine: Vec<u8>,
/// Node (device) key.
pub node: Vec<u8>,
/// Disco key.
pub disco: Vec<u8>,
/// Network lock key.
pub network_lock: Vec<u8>,
}

#[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<Vec<u8>>,
node: Option<Vec<u8>>,
disco: Option<Vec<u8>>,
network_lock: Option<Vec<u8>>,
) -> 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;
Expand All @@ -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;
}
Expand All @@ -48,33 +37,31 @@ 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(<invalid>)".to_owned(),
}
}
}

impl From<tailscale::keys::NodeState> for Keystate {
fn from(value: tailscale::keys::NodeState) -> Self {
impl From<tailscale::keys::PersistState> 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<Self, ()> {
Expand All @@ -86,10 +73,9 @@ impl TryFrom<&Keystate> for tailscale::keys::NodeState {
}

Ok(Self {
machine_keys: key::<MachinePrivateKey>(&value.machine)?.into(),
node_keys: key::<NodePrivateKey>(&value.node)?.into(),
disco_keys: key::<DiscoPrivateKey>(&value.disco)?.into(),
network_lock_keys: key::<NetworkLockPrivateKey>(&value.network_lock)?.into(),
machine_key: key(&value.machine)?,
node_key: key(&value.node)?,
network_lock_key: key(&value.network_lock)?,
})
}
}