Commit ba797894 authored by Harry Stern's avatar Harry Stern

tmp rebase on to master, compiles now but dns code not working

parent 8a37d789
This diff is collapsed.
......@@ -5,6 +5,7 @@ authors = ["Wayne Chang <wayne.chang@consensys.net>", "Harry Stern <harry.stern@
edition = "2018"
[dependencies]
futures = "0.1"
actix-web = "1"
actix-session = "0.2"
askama = "^0.8"
......@@ -26,9 +27,10 @@ uuid = { version = "0.7", features = ["serde", "v4"] }
failure = "0.1"
failure_derive = "0.1"
diesel = { version = "1.0", features = ["postgres"] }
dotenv = "^0.14"
trust-dns = "^0.14"
maplit = "1.0"
jsonwebtoken = "6"
hex = "0.4"
trust-dns = "0.17"
tokio-udp = "0.1"
......@@ -10,6 +10,7 @@ use actix_web::{web, App, HttpRequest, HttpResponse, HttpServer, Responder, guar
use actix_web::error::Result;
use actix_session::{Session, CookieSession};
use futures::Future;
use failure::err_msg;
......@@ -304,40 +305,47 @@ fn verify_domain_input_code_view(_req: HttpRequest, session: Session,
}
fn verify_domain_verify_code_view(_req: HttpRequest,
session: Session) -> Result<HttpResponse> {
let mut verifier = match session.get::<Verification>("dns_verifier").unwrap() {
Some(verifier) => verifier,
None => return Ok(HttpResponse::BadRequest().body("No verifier session data"))
session: Session) -> Box<dyn Future<Item=HttpResponse, Error=actix_web::error::Error>> {
let verifier_fut = match session.get::<Verification>("dns_verifier").unwrap() {
Some(verifier) => futures::future::ok(verifier),
None => return Box::new(futures::future::err(actix_web::error::ErrorBadRequest("No verifier session data")))
};
let r = match verifier.type_() {
verify::Type::Dns{ domain } => {
verify::Verification::check_dns(
domain, &verifier.challenge().unwrap())
},
_ => Ok(None),
};
let code = match r {
Ok(None) => "".to_string(),
Ok(Some(s)) => s.clone(),
Err(err) => return Ok(HttpResponse::BadRequest().body("DNS check failed")),
};
let code_verified = verifier.receive_response(&code);
let fut = verifier_fut.and_then(|verifier| {
match verifier.type_() {
verify::Type::Dns{ domain } => {
let code_fut = verify::Verification::check_dns(
domain, &verifier.challenge().unwrap());
code_fut.map(|code_opt| {
(verifier, code_opt)
})
},
_ => unreachable!("TODO: fix Verification type mess")
}
})
.map(move |(mut verifier, code_opt): (Verification, Option<String>)| {
let code = match code_opt {
None => "".to_string(),
Some(s) => s.clone(),
//Err(err) => return Ok(HttpResponse::BadRequest().body("DNS check failed")),
};
let code_verified = verifier.receive_response(&code);
// success
if code_verified {
session.remove("dns_verifier");
session.set("dns_verifier", verifier).unwrap();
HttpResponse::Ok()
.body("Verification succeeded")
} else {
// show "verification failed" message, show input box and link back to new code page
HttpResponse::Ok()
.body("Verification failed")
}
})
.map_err(|e| actix_web::error::ErrorInternalServerError(e));
// success
if code_verified {
session.remove("dns_verifier");
session.set("dns_verifier", verifier).unwrap();
Ok(HttpResponse::Ok()
.body("Verification succeeded"))
//HttpResponse::SeeOther()
// .header("Location", "/select_did")
// .finish()
} else {
// show "verification failed" message, show input box and link back to new code page
Ok(HttpResponse::Ok()
.body("Verification failed"))
}
Box::new(fut)
}
#[derive(Serialize, Deserialize, Clone, Debug)]
......
......@@ -4,7 +4,6 @@ use crate::did::Document;
use chrono::prelude::*;
use serde::{Serialize, Deserialize};
use uuid::Uuid;
use std::error::Error;
#[derive(Serialize, Deserialize, Debug)]
pub struct Session {
......
......@@ -5,23 +5,29 @@ use uuid::Uuid;
use std::error::Error;
use std::fmt;
use std::env;
use reqwest::{Client, header};
use crate::credential;
use std::str;
use std::net::Ipv4Addr;
use std::str::FromStr;
use trust_dns::op::DnsResponse;
use trust_dns::rr::{DNSClass, Name, RData, Record, RecordType};
use trust_dns::client::{Client as DNSClient, ClientConnection as DNSClientConnection, ClientStreamHandle as DNSClientStreamHandle, SyncClient as DNSSyncClient};
use credential::{Credential, Proof, Subject};
use trust_dns::udp::UdpClientConnection;
use std::collections::{BTreeMap, HashMap as Map};
use trust_dns::client::{ClientFuture as DNSClientFuture, ClientHandle};
use trust_dns::udp::UdpClientStream;
use tokio_udp::UdpSocket;
use serde::{Serialize, Deserialize};
use serde_json::{json, Value, to_string_pretty};
use chrono::prelude::*;
use futures::Future;
use crate::credential;
use credential::{Credential, Proof, Subject};
type Result<T> = std::result::Result<T, Box<dyn Error>>;
#[derive(Debug)]
......@@ -41,7 +47,6 @@ fn error<T>(message: String) -> Result<T> {
Err(Box::new(VerificationError {message: message}))
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Verification {
id: Uuid,
......@@ -164,27 +169,33 @@ impl Verification {
Ok(())
}
pub fn check_dns(domain: &str, challenge: &str
) -> Result<Option<String>> {
pub fn check_dns(domain: &str, challenge: &str) -> impl Future<Item=Option<String>, Error=trust_dns::error::ClientError> {
println!("checking {} for {}", domain, challenge);
let dns_server_address = "8.8.8.8:53".parse()?;
let conn = UdpClientConnection::new(dns_server_address)?;
let client = DNSSyncClient::new(conn);
let name = Name::from_str("www.example.com")?;
let response: DnsResponse = client.query(
&name, DNSClass::IN, RecordType::TXT)?;
let answers: &[Record] = response.answers();
if let &RData::TXT(ref txt) = answers[0].rdata() {
for line in txt.iter() {
let s = str::from_utf8(line)?;
println!("{}", s);
if s == challenge {
return Ok(Some(s.to_string()))
let name = Name::from_str(domain).unwrap();
let dns_server_address = "8.8.8.8:53".parse().unwrap();
let stream = UdpClientStream::<UdpSocket>::new(dns_server_address);
let (bg_task, mut client) = DNSClientFuture::connect(stream);
let response_fut = client.query(
name, DNSClass::IN, RecordType::TXT);
let challenge = challenge.to_string();
response_fut.map(move |response| {
let answers: &[Record] = response.answers();
if let &RData::TXT(ref txt) = answers[0].rdata() {
for line in txt.iter() {
// FIXME: malicious user can crash by putting invalid utf in dns TXT field
let s = str::from_utf8(line).unwrap();
println!("{}", s);
if s == challenge {
return Some(s.to_string())
}
}
}
}
Ok(None)
None
})
}
fn send_oauth2_challenge(issuer: &str, username: &str,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment