use std::{ io::{Read, Write}, net::TcpStream, str::FromStr, sync::Arc, }; use anyhow::{bail, Context, Result}; use native_tls::{TlsConnector, TlsConnectorBuilder}; // use rustls::{ClientConfig, ClientConnection, OwnedTrustAnchor, RootCertStore, StreamOwned}; use trust_dns_resolver::{ config::{ResolverConfig, ResolverOpts}, Resolver, }; use uuid::Uuid; fn main() -> Result<()> { let (port, host) = resolve_dns("daeken.dev")?; dbg!(&port); dbg!(&host); // let tls_conf = Arc::new(make_tls_config()); let mut tls_conn = make_tls_connection(&host, port) .with_context(|| format!("Can't connect to {}:{}", host, port))?; // let uuid =// Uuid::new_v4(); let uuid = [b'a'; 16]; dbg!(&uuid); tls_conn.write_all(&uuid).context("Can't write UUID")?; let mut serv_uuid = [0; 16]; tls_conn.read_exact(&mut serv_uuid)?; dbg!(serv_uuid); // Hangs ATM let mut new = [0; 100]; let len = tls_conn.read(&mut new)?; dbg!(&new[..len]); Ok(()) } // TODO: How to cache this? fn resolve_dns(server: &str) -> Result<(u16, String)> { let name = format!("_hypercosm._tls.{}", server); let resp = make_dns_client()? .srv_lookup(name)? .into_iter() .collect::>(); // TODO: Ensure exactly 1 result: I think. let srv = &resp[0]; // TODO: Handle priority and weight. let port = srv.port(); // TODO: Should this be ascii or utf8 let name = srv.target().to_ascii(); Ok((port, name)) } fn make_dns_client() -> Result { Ok(Resolver::new( ResolverConfig::cloudflare_tls(), ResolverOpts::default(), )?) } // fn make_tls_config() -> ClientConfig { // let mut root_store = RootCertStore::empty(); // root_store.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.0.iter().map(|ta| { // OwnedTrustAnchor::from_subject_spki_name_constraints( // ta.subject, // ta.spki, // ta.name_constraints, // ) // })); // let cert_dir = include_bytes!("../cert.der"); // assert_eq!( // root_store.add_parsable_certificates(&[cert_dir.to_vec()]), // (1, 0) // ); // let config = rustls::ClientConfig::builder() // .with_safe_defaults() // .with_root_certificates(root_store) // .with_no_client_auth(); // config // } // fn make_tls_connection( // config: Arc, // server: &str, // port: u16, // ) -> Result { // let server_name = server.try_into()?; // let conn = ClientConnection::new(config, server_name)?; // let sock = TcpStream::connect((server, port))?; // let stream = StreamOwned::new(conn, sock); // Ok(stream) // } fn make_tls_connection( // config: Arc, server: &str, port: u16, ) -> Result { let connector = TlsConnector::builder() .danger_accept_invalid_certs(true) .build()?; let sock = TcpStream::connect((server, port))?; let conn = connector.connect(server, sock)?; Ok(conn) }