nemicosm/src/main.rs

126 lines
3.1 KiB
Rust

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::<Vec<_>>();
// 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<Resolver> {
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<ClientConfig>,
// server: &str,
// port: u16,
// ) -> Result<impl Read + Write> {
// 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<ClientConfig>,
server: &str,
port: u16,
) -> Result<impl Read + Write> {
let connector = TlsConnector::builder()
.danger_accept_invalid_certs(true)
.build()?;
let sock = TcpStream::connect((server, port))?;
let conn = connector.connect(server, sock)?;
Ok(conn)
}