use std::time::Duration; use uuid::Uuid; use crate::pipe::protocol::{supported_actions, AgentMessage, BrowserMessage, PROTOCOL_VERSION}; use crate::pipe::{PipeError, Transport}; use crate::security::derive_session_key; #[derive(Debug, Clone)] pub struct HandshakeResult { pub agent_id: String, pub session_key: Vec, pub capabilities: Vec, } pub fn perform_handshake( transport: &T, timeout: Duration, ) -> Result { let init = transport.recv_timeout(timeout)?; match init { BrowserMessage::Init { version, hmac_seed, capabilities, } => { if version != PROTOCOL_VERSION { return Err(PipeError::Protocol(format!( "unsupported protocol version: {version}" ))); } let session_key = derive_session_key(&hmac_seed)?; let agent_id = Uuid::new_v4().to_string(); let ack = AgentMessage::InitAck { version: PROTOCOL_VERSION.to_string(), agent_id: agent_id.clone(), supported_actions: supported_actions(), }; transport.send(&ack)?; Ok(HandshakeResult { agent_id, session_key, capabilities, }) } other => Err(PipeError::UnexpectedMessage(format!( "expected init as first message, got {other:?}" ))), } }