~klve/poptea

239e09805d35079a7876ea6cbed4be70600a17d8 — klve bunc ntnn 5 months ago 177abd7
Added NoTrustStore for cert verification
5 files changed, 31 insertions(+), 14 deletions(-)

M src/bin/poptea-cli.rs
M src/infra/fs.rs
M src/infra/mod.rs
M src/infra/tls.rs
M src/lib.rs
M src/bin/poptea-cli.rs => src/bin/poptea-cli.rs +12 -7
@@ 7,18 7,23 @@ use std::{

fn main() {
    let url = std::env::args().nth(1).expect("please provide gemini url");
    let fs = Arc::new(Mutex::new(poptea::FileSystem::new(".poptea".into()).expect("failed to init file storage")));
    /* To use file as a trust store uncomment the code bellow */
    // let fs = Arc::new(Mutex::new(
    //     poptea::FileSystem::new(".poptea".into()).expect("failed to init file storage"),
    // ));

    let client = poptea::TlsClient::new(fs.clone());
    let no_ts = poptea::NoTrustStore::default();
    let ts = Arc::new(Mutex::new(no_ts));

    let client = poptea::TlsClient::new(ts.clone());
    let res = client.get(&url).expect("failed to make a request");

    io::stdout()
        .write_all(&res.body.unwrap_or_else(|| b"response has no body".to_vec()))
        .expect("failed to write to stdout");

    fs
        .lock()
        .expect("filesystem mutex deadlock")
        .flush_trust_store()
        .expect("failed to persist known hosts");
    // fs.lock()
    //     .expect("filesystem mutex deadlock")
    //     .flush_trust_store()
    //     .expect("failed to persist known hosts");
}

M src/infra/fs.rs => src/infra/fs.rs +8 -5
@@ 1,9 1,9 @@
use crate::{PopError, PopResult, TrustStore, VerifyStatus};
use std::collections::HashMap;
use std::fs::{create_dir, OpenOptions};
use std::fs::OpenOptions;
use std::io::prelude::*;
use std::io::LineWriter;
use std::io::{self, BufRead};
use crate::{PopError, PopResult, TrustStore, VerifyStatus};

pub struct FileSystem {
    trust_store: HashMap<String, String>,


@@ 21,7 21,7 @@ impl FileSystem {
        })
    }

    fn load_trust_store(pop_dir: &str, store: &mut HashMap<String, String>) -> PopResult<()>{
    fn load_trust_store(pop_dir: &str, store: &mut HashMap<String, String>) -> PopResult<()> {
        let trust_path = format!("{}/known_hosts", pop_dir);
        let file = OpenOptions::new()
            .write(true)


@@ 31,7 31,9 @@ impl FileSystem {

        for line in io::BufReader::new(file).lines() {
            if let Ok(kh) = line {
                let (host, fingerprint) = kh.split_once(" ").ok_or_else(|| PopError::Local("failed parse fingerprint line".into()))?;
                let (host, fingerprint) = kh
                    .split_once(" ")
                    .ok_or_else(|| PopError::Local("failed parse fingerprint line".into()))?;

                store.insert(host.to_string(), fingerprint.to_string());
            }


@@ 50,7 52,8 @@ impl FileSystem {
        let mut file = LineWriter::new(file);

        for (h, f) in &self.trust_store {
            file.write_all(format!("{} {}\n", h, f).as_bytes()).map_err(|e| PopError::Local(e.to_string()))?;
            file.write_all(format!("{} {}\n", h, f).as_bytes())
                .map_err(|e| PopError::Local(e.to_string()))?;
        }

        file.flush().map_err(|e| PopError::Local(e.to_string()))?;

M src/infra/mod.rs => src/infra/mod.rs +1 -1
@@ 2,4 2,4 @@ mod fs;
mod tls;

pub use fs::FileSystem;
pub use tls::TlsClient;
pub use tls::{NoTrustStore, TlsClient};

M src/infra/tls.rs => src/infra/tls.rs +9 -0
@@ 135,3 135,12 @@ impl GeminiClient for TlsClient {
        })
    }
}

#[derive(Default)]
pub struct NoTrustStore {}

impl TrustStore for NoTrustStore {
    fn verify(&mut self, _addr: &str, _fingerprint: String) -> PopResult<VerifyStatus> {
        Ok(VerifyStatus::Trusted)
    }
}

M src/lib.rs => src/lib.rs +1 -1
@@ 2,7 2,7 @@ use std::fmt;
use std::str::FromStr;

mod infra;
pub use infra::{FileSystem, TlsClient};
pub use infra::*;

#[derive(Debug)]
pub enum GemStatus {