Login but not working

master
Marco Pacchialat 4 years ago
parent 01c1c8a436
commit 5090a845fd
  1. 120
      Cargo.lock
  2. 6
      Cargo.toml
  3. 183
      src/login.rs
  4. 1
      src/main.rs
  5. 63
      src/request.rs

120
Cargo.lock generated

@ -28,6 +28,12 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "base16"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d27c3610c36aee21ce8ac510e6224498de4228ad772a171ed65643a24693a5a8"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.3.2" version = "1.3.2"
@ -46,6 +52,15 @@ dependencies = [
"generic-array 0.12.4", "generic-array 0.12.4",
] ]
[[package]]
name = "block-buffer"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
dependencies = [
"generic-array 0.14.4",
]
[[package]] [[package]]
name = "block-padding" name = "block-padding"
version = "0.1.5" version = "0.1.5"
@ -77,8 +92,12 @@ checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
name = "calllog" name = "calllog"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"base16",
"html_parser", "html_parser",
"hyper", "hyper",
"json",
"rand",
"sha2",
"srp", "srp",
"tokio", "tokio",
] ]
@ -104,6 +123,15 @@ dependencies = [
"vec_map", "vec_map",
] ]
[[package]]
name = "cpufeatures"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "digest" name = "digest"
version = "0.8.1" version = "0.8.1"
@ -193,6 +221,17 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "getrandom"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]] [[package]]
name = "h2" name = "h2"
version = "0.3.4" version = "0.3.4"
@ -334,6 +373,12 @@ version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
[[package]]
name = "json"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd"
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.4.0" version = "1.4.0"
@ -459,6 +504,12 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
[[package]]
name = "opaque-debug"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.11.2" version = "0.11.2"
@ -539,6 +590,12 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "ppv-lite86"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]] [[package]]
name = "proc-macro-error" name = "proc-macro-error"
version = "1.0.4" version = "1.0.4"
@ -581,6 +638,46 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "rand"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_hc"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
dependencies = [
"rand_core",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.2.10" version = "0.2.10"
@ -639,10 +736,23 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
dependencies = [ dependencies = [
"block-buffer", "block-buffer 0.7.3",
"digest 0.8.1", "digest 0.8.1",
"fake-simd", "fake-simd",
"opaque-debug", "opaque-debug 0.2.3",
]
[[package]]
name = "sha2"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa"
dependencies = [
"block-buffer 0.9.0",
"cfg-if",
"cpufeatures",
"digest 0.9.0",
"opaque-debug 0.3.0",
] ]
[[package]] [[package]]
@ -887,6 +997,12 @@ dependencies = [
"try-lock", "try-lock",
] ]
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.3.9" version = "0.3.9"

@ -9,4 +9,8 @@ edition = "2018"
hyper = { version = "0.14", features = ["full"] } hyper = { version = "0.14", features = ["full"] }
tokio = { version = "1", features = ["full"] } tokio = { version = "1", features = ["full"] }
html_parser = { version = "0.6.2" } html_parser = { version = "0.6.2" }
srp = { version = "0.5.0" } srp = { version = "0.5.0" }
sha2 = { version = "0.9.8" }
rand = { version = "0.8.4" }
base16 = { version = "0.2.1" }
json = { version = "*" }

@ -0,0 +1,183 @@
use std::{fmt::format, io::Read};
use hyper::{body::HttpBody, Body, Client, Method, Request, Uri};
use json::JsonValue;
use rand::Fill;
use sha2::Sha512;
use srp::{
client::{srp_private_key, SrpClient},
groups::G_2048,
};
const AUTH_URI: &'static str = "http://192.168.1.1/authenticate";
fn get_username<'a>() -> &'a str {
"admin"
}
fn get_password<'a>() -> &'a str {
"admin"
}
pub async fn try_login(cookie: &str, csrf_token: &str) -> Result<(), ()> {
let mut a = [0u8; 64];
a.try_fill(&mut rand::thread_rng()).unwrap();
let srp_client = SrpClient::<Sha512>::new(&a, &G_2048);
let a_pub = srp_client.get_a_pub();
let a_pub = base16::encode_lower(&a_pub);
let client = Client::new();
let uri: Uri = AUTH_URI.parse().unwrap();
let req_body = format!("CSRFtoken={}&I={}&A={}", csrf_token, get_username(), a_pub);
println!("{}", &req_body);
let request = Request::builder()
.method(Method::POST)
.uri(uri.clone())
.header("Accept", "application/json, text/javascript, */*; q=0.01")
.header(
"Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8",
)
.header("Cookie", format!("sessionID={}", cookie).as_str())
.header("Host", "192.168.1.1")
.header("Origin", "http://192.168.1.1")
.header("Pragma", "no-cache")
.header("Referer", "http://192.168.1.1/")
.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36 Edg/93.0.961.52")
.header("X-Requested-With", "XMLHttpRequest")
.body(Body::from(req_body))
.unwrap();
match client.request(request).await {
Ok(mut resp) => {
let mut buffer: Vec<u8> = Vec::new();
while let Some(chunk) = resp.body_mut().data().await {
match chunk {
Ok(bytes) => buffer.append(&mut bytes.to_vec()),
Err(e) => panic!("{}", e.to_string()),
}
}
// TODO: handle errors
let buffer = String::from_utf8(buffer).unwrap();
println!("{:?}", buffer);
//let resp = json::parse(&buffer).unwrap();
if let Some((s, b_pub)) = get_salt_and_b_pub(&buffer) {
let s = base16::decode(s.as_bytes()).unwrap();
let b_pub = base16::decode(b_pub.as_bytes()).unwrap();
let private_key = srp_private_key::<Sha512>(
get_username().as_bytes(),
get_password().as_bytes(),
&s,
);
let verifier = srp_client.process_reply(&private_key, &b_pub).unwrap();
let user_proof = verifier.get_proof();
let m = base16::encode_lower(&user_proof);
let req_body = format!("CSRFtoken={}&M={}", csrf_token, m);
let request = Request::builder()
.method(Method::POST)
.uri(uri)
.header("Accept", "application/json, text/javascript, */*; q=0.01")
.header(
"Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8",
)
.header("Cookie", format!("sessionID={}", cookie).as_str())
.header("Host", "192.168.1.1")
.header("Origin", "http://192.168.1.1")
.header("Pragma", "no-cache")
.header("Referer", "http://192.168.1.1/")
.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36 Edg/93.0.961.52")
.header("X-Requested-With", "XMLHttpRequest")
.body(Body::from(req_body))
.unwrap();
match client.request(request).await {
Ok(mut resp) => {
let mut buffer: Vec<u8> = Vec::new();
while let Some(chunk) = resp.body_mut().data().await {
match chunk {
Ok(bytes) => buffer.append(&mut bytes.to_vec()),
Err(e) => panic!("{}", e.to_string()),
}
}
// TODO: handle errors
let buffer = String::from_utf8(buffer).unwrap();
println!("final resp: {:?}", buffer);
}
Err(e) => panic!("{}", e.to_string()),
}
//let server_proof = conn.send_proof(user_proof);
//let key = verifier.verify_server(server_proof).unwrap();
} else {
println!("{:?}", resp);
}
}
Err(e) => panic!("{}", e.to_string()),
}
todo!()
}
fn get_salt_and_b_pub(msg: &str) -> Option<(String, String)> {
let msg = json::parse(&msg).unwrap();
//_get_salt_and_b_pub(&msg, None, None)
if let JsonValue::Object(obj) = msg {
println!("{:?}", obj);
let mut s = String::new();
let mut b = String::new();
for (name, val) in obj.iter() {
if name == "s" {
s = get_json_string(val).unwrap();
} else if name == "B" {
b = get_json_string(val).unwrap();
}
}
Some((s, b))
} else {
None
}
}
fn get_json_string(val: &JsonValue) -> Option<String> {
match val {
JsonValue::Short(val) => Some(val.to_string()),
JsonValue::String(val) => Some(val.to_string()),
_ => None,
}
}
#[cfg(test)]
mod tests {
use crate::login::get_salt_and_b_pub;
#[test]
fn parse_json_resp() {
let msg = "{ \"s\":\"0DEC99D3\", \"B\":\"2FCDB529BB3F7F02BAD0ED15C62995CB9E76AC0352D91F64AD02A1EF06C533565F64A0B25D7235682E5D732CA8FD1C675231CA205D83FF317E8D7BFBC48D863822A7E9A8ADC7BBD54B54A7D59502479872E4926C6169BDDED2E7FD7BFD1714ECA3FE22511C4F48F8FA33240DB8DD289933FC19A1B7DC0EEB4A56337ADB67FFC08684822D05D2A5EC95A3B21E84B4CB0F2C6195454D1D3B59548987485555E200B5E23B7E89E87C60AF3C2AA5834B284DD182C9A508FE479357BA341750385837241ACA56AAC5E380AB3876F80761E4BE33FAA8BBE60863AFC96FEBDB2AC64636AF3035777624EF2ECC581CA7266D3F11BB30CDEF21E9802973CCC7899E375F3E\" }";
println!("{:?}", json::parse(&msg));
assert_eq!(
get_salt_and_b_pub(msg),
Some((String::from("0DEC99D3"), String::from("2FCDB529BB3F7F02BAD0ED15C62995CB9E76AC0352D91F64AD02A1EF06C533565F64A0B25D7235682E5D732CA8FD1C675231CA205D83FF317E8D7BFBC48D863822A7E9A8ADC7BBD54B54A7D59502479872E4926C6169BDDED2E7FD7BFD1714ECA3FE22511C4F48F8FA33240DB8DD289933FC19A1B7DC0EEB4A56337ADB67FFC08684822D05D2A5EC95A3B21E84B4CB0F2C6195454D1D3B59548987485555E200B5E23B7E89E87C60AF3C2AA5834B284DD182C9A508FE479357BA341750385837241ACA56AAC5E380AB3876F80761E4BE33FAA8BBE60863AFC96FEBDB2AC64636AF3035777624EF2ECC581CA7266D3F11BB30CDEF21E9802973CCC7899E375F3E")))
)
}
}

@ -1,3 +1,4 @@
mod login;
mod parsing; mod parsing;
mod request; mod request;

@ -1,15 +1,15 @@
use std::{io::Read, time::Instant}; use std::time::Instant;
use hyper::{body::HttpBody, Client, Response};
use tokio::sync::mpsc::{Receiver, Sender};
use html_parser::Dom; use html_parser::Dom;
use hyper::{body::HttpBody, Body, Client, Method, Request, Uri};
use tokio::sync::mpsc::{Receiver, Sender};
use crate::parsing::extract_csrf_token_from_node; use crate::{login::try_login, parsing::extract_csrf_token_from_node};
const CALLLOG_URI: &'static str = "http://192.168.1.1/modals/mmpbx-log-modal.lp"; const CALLLOG_URI: &'static str = "http://192.168.1.1/modals/mmpbx-log-modal.lp";
enum ResponseParse { enum ResponseParse {
NotLoggedIn { csrf_token: String }, NotLoggedIn { cookie: String, csrf_token: String },
CallLog(CallLog), CallLog(CallLog),
Error(String), Error(String),
} }
@ -29,9 +29,13 @@ pub async fn fetch_thread(channel: Receiver<Sender<CallLog>>) {
}; };
let mut calllog = loop { let mut calllog = loop {
match try_fetch_updated_data().await { match try_fetch_updated_data(request_cache.cookie.map_or(String::new(), |s| s.clone()))
ResponseParse::NotLoggedIn { csrf_token } => { .await
println!("{}", csrf_token); {
ResponseParse::NotLoggedIn { cookie, csrf_token } => {
// TODO: handle login error
let _res = try_login(&cookie, &csrf_token).await;
todo!() todo!()
} }
ResponseParse::CallLog(log) => break log, ResponseParse::CallLog(log) => break log,
@ -49,13 +53,44 @@ pub async fn fetch_thread(channel: Receiver<Sender<CallLog>>) {
} }
} }
async fn try_fetch_updated_data() -> ResponseParse { async fn try_fetch_updated_data(cookie: String) -> ResponseParse {
let client = Client::new(); let client = Client::new();
let uri = CALLLOG_URI.parse().unwrap(); let uri: Uri = CALLLOG_URI.parse().unwrap();
let mut cookie = cookie;
match client.get(uri).await {
let request = Request::builder()
.method(Method::GET)
.uri(uri)
.header("Cookie", format!("sessionID={}", cookie).as_str())
.header("Host", "192.168.1.1")
.header("Origin", "http://192.168.1.1")
.header("Pragma", "no-cache")
.header("Referer", "http://192.168.1.1/")
.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36 Edg/93.0.961.52")
.header("X-Requested-With", "XMLHttpRequest")
.body(Body::empty())
.unwrap();
match client.request(request).await {
Ok(mut resp) => { Ok(mut resp) => {
if let Some(new_cookie) = resp.headers().get(hyper::header::SET_COOKIE) {
println!("Set-Cookie: {:?}", new_cookie);
let new_cookie = new_cookie
.to_str()
.unwrap()
.split(';')
.map(|s| s.trim())
.find(|s| s.starts_with("sessionID="))
.map_or(String::new(), |s| {
s.split('=')
.skip(1)
.next()
.map_or(String::new(), |s| s.to_owned())
});
println!("Set-Cookie: {:?}", new_cookie);
cookie = new_cookie;
}
let mut buffer: Vec<u8> = Vec::new(); let mut buffer: Vec<u8> = Vec::new();
while let Some(chunk) = resp.body_mut().data().await { while let Some(chunk) = resp.body_mut().data().await {
@ -71,7 +106,7 @@ async fn try_fetch_updated_data() -> ResponseParse {
ResponseParse::CallLog(log) ResponseParse::CallLog(log)
} else { } else {
if let Some(csrf_token) = extract_csfr_token_from_body(&body) { if let Some(csrf_token) = extract_csfr_token_from_body(&body) {
ResponseParse::NotLoggedIn { csrf_token } ResponseParse::NotLoggedIn { cookie, csrf_token }
} else { } else {
todo!() todo!()
} }
@ -90,6 +125,8 @@ fn extract_calllog_from_body(body: &str) -> Option<CallLog> {
} }
fn extract_csfr_token_from_body(body: &str) -> Option<String> { fn extract_csfr_token_from_body(body: &str) -> Option<String> {
println!("{}", body);
let dom = Dom::parse(body); let dom = Dom::parse(body);
if let Ok(dom) = dom { if let Ok(dom) = dom {
for element in dom.children.iter() { for element in dom.children.iter() {

Loading…
Cancel
Save