From 74596fa6bce3420631fc58980306ba9ef5fcb193 Mon Sep 17 00:00:00 2001 From: YouXam Date: Mon, 13 May 2024 23:23:41 +0800 Subject: [PATCH] Fix authentication bug for BUPT Portal, byr-pet now connects to network Signed-off-by: YouXam --- .gitignore | 1 + src/net/bupt.rs | 31 +++++++++++++++++++++++++------ src/net/mod.rs | 33 +++++++++++++++++++++++++-------- 3 files changed, 51 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 73a638b..1aa6e9c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /.embuild /target /Cargo.lock +.DS_Store \ No newline at end of file diff --git a/src/net/bupt.rs b/src/net/bupt.rs index 56ce31c..2d5bce7 100644 --- a/src/net/bupt.rs +++ b/src/net/bupt.rs @@ -1,6 +1,6 @@ use anyhow::{bail, Result}; use embedded_svc::http::{client::Client, Method}; -use esp_idf_svc::http::client::{Configuration, EspHttpConnection}; +use esp_idf_svc::http::client::{Configuration, EspHttpConnection, FollowRedirectsPolicy}; use std::fmt; use urlencoding::encode; @@ -38,14 +38,27 @@ enum BuptNetStatus { fn check(url: impl AsRef) -> Result { log::debug!("checking bupt network status with url: {}", url.as_ref()); - let connection = EspHttpConnection::new(&Configuration::default())?; + let connection = EspHttpConnection::new(&Configuration{ + follow_redirects_policy: FollowRedirectsPolicy::FollowNone, + ..Default::default() + })?; let mut client = Client::wrap(connection); let request = client.request(Method::Get, url.as_ref(), &[])?; let response = request.submit()?; log::debug!("response status: {}", response.status()); match response.status() { + // Logged in, not redirected 204 => Ok(BuptNetStatus::Authenticated), - 200..=399 => Ok(BuptNetStatus::NotAuthenticated( + // Redirect to login page + 302 => { + let location = response + .header("Location") + .ok_or_else(|| anyhow::anyhow!("no Location header found in response"))?; + log::info!("redirected to: {}", location); + check(location) + } + // Redirected to login page + 200 => Ok(BuptNetStatus::NotAuthenticated( response .header("Set-Cookie") .and_then(|cookie| cookie.split(';').next().map(|cookie| cookie.to_string())), @@ -64,7 +77,7 @@ fn auth(account: BuptAccount, cookie: String) -> Result<()> { let mut request = client.request(Method::Post, "http://10.3.8.216/login", &headers)?; request.write( format!( - "username={}&password={}", + "user={}&pass={}", encode(&account.username), encode(&account.password) ) @@ -73,6 +86,12 @@ fn auth(account: BuptAccount, cookie: String) -> Result<()> { let mut response = request.submit()?; log::debug!("response status: {}", response.status()); match response.status() { + 302 => { + let location = response + .header("Location") + .ok_or_else(|| anyhow::anyhow!("no Location header found in response"))?; + fatal!("unexpected redirect: {}", location) + } 200 => match check(CHECK_URL)? { BuptNetStatus::Authenticated => { log::info!("BUPT-portal authenticated successfully"); @@ -109,6 +128,7 @@ fn auth(account: BuptAccount, cookie: String) -> Result<()> { } pub fn login(account: BuptAccount) -> Result<()> { + log::info!("Checking BUPT-portal status..."); match check(CHECK_URL) { Ok(BuptNetStatus::Authenticated) => { log::info!("BUPT-portal is already authenticated"); @@ -138,8 +158,7 @@ pub fn login(account: BuptAccount) -> Result<()> { } } -#[allow(dead_code)] -fn get(url: impl AsRef) -> Result { +pub fn get(url: impl AsRef) -> Result { let connection = EspHttpConnection::new(&Configuration::default())?; let mut client = Client::wrap(connection); let request = client.request(Method::Get, url.as_ref(), &[])?; diff --git a/src/net/mod.rs b/src/net/mod.rs index 0b990f3..d2f1176 100644 --- a/src/net/mod.rs +++ b/src/net/mod.rs @@ -8,7 +8,6 @@ use esp_idf_svc::{ log::set_target_level, wifi::{AuthMethod, BlockingWifi, ClientConfiguration, Configuration, EspWifi}, }; -use log::info; use std::fmt; fn connect_wifi( @@ -35,34 +34,50 @@ fn connect_wifi( ..Default::default() }))?; - info!("Starting wifi..."); + log::info!("Starting wifi..."); wifi.start()?; - info!("Connecting wifi {}...", ssid); + log::info!("Connecting wifi {}...", ssid); let delay: delay::Delay = Default::default(); for retry in 0..10 { match wifi.connect() { Ok(_) => break, Err(e) => { - info!("Failed to connect: {}, retrying...", e); + log::warn!("Failed to connect wifi: {}, will retry after 10 seconds...", e); } } delay.delay_ms(1000 * 10); if retry == 9 { + log::error!("Retry limit exceeded"); bail!("Failed to connect to wifi"); + } else { + log::info!("Retrying..."); } } - info!("Waiting for DHCP lease..."); + log::info!("Waiting for DHCP lease..."); wifi.wait_netif_up()?; let ip_info = wifi.wifi().sta_netif().get_ip_info()?; - info!("Wifi DHCP info: {:?}", ip_info); + log::info!("Wifi DHCP info: {:?}", ip_info); if let Some(account) = bupt_account { - bupt::login(account)?; + for retry in 0..10 { + match bupt::login(account.clone()) { + Ok(_) => break, + Err(e) => { + log::warn!("Failed to login to BUPT-portal: {}, will retry after 10 seconds...", e); + } + } + delay.delay_ms(1000 * 10); + if retry == 9 { + log::error!("Retry limit exceeded"); + bail!("Failed to login to BUPT-portal"); + } else { + log::info!("Retrying..."); + } + } } - Ok(Box::new(esp_wifi)) } @@ -109,5 +124,7 @@ pub fn connect() -> anyhow::Result<()> { EspSystemEventLoop::take()?, )?; + log::info!("Web Test: {}", bupt::get("http://www.msftconnecttest.com/connecttest.txt")?); + Ok(()) }