添加了账号的设置

This commit is contained in:
Yakumo Hokori 2025-09-02 22:46:48 +08:00
parent 699cb26587
commit db336184c3
6 changed files with 62 additions and 7 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

1
Cargo.lock generated
View File

@ -552,6 +552,7 @@ checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
name = "ftphack" name = "ftphack"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"async-trait",
"gtk", "gtk",
"libunftp", "libunftp",
"tokio", "tokio",

View File

@ -8,3 +8,4 @@ gtk = "0.18.2"
libunftp = "0.21.0" libunftp = "0.21.0"
tokio = { version = "1.47.1", features = ["rt-multi-thread"] } tokio = { version = "1.47.1", features = ["rt-multi-thread"] }
unftp-sbe-fs = "0.3.0" unftp-sbe-fs = "0.3.0"
async-trait = "0.1.50"

View File

@ -28,6 +28,8 @@ fn main() {
let ip = ui_clone.ip_entry.text(); let ip = ui_clone.ip_entry.text();
let port: u16 = ui_clone.port_entry.text().parse().unwrap_or(2121); let port: u16 = ui_clone.port_entry.text().parse().unwrap_or(2121);
let dir = ui_clone.dir_entry.text(); let dir = ui_clone.dir_entry.text();
let username = ui_clone.username_entry.text();
let password = ui_clone.password_entry.text();
// Validate directory // Validate directory
let dir_path = PathBuf::from(&dir); let dir_path = PathBuf::from(&dir);
@ -40,7 +42,7 @@ fn main() {
let addr: SocketAddr = format!("{}:{}", ip, port).parse().unwrap(); let addr: SocketAddr = format!("{}:{}", ip, port).parse().unwrap();
// Create and start server // Create and start server
match server::FtpServer::new(addr, dir_path) { match server::FtpServer::new(addr, dir_path, username.to_string(), password.to_string()) {
Ok(mut srv) => { Ok(mut srv) => {
// First start the server (initialize it) // First start the server (initialize it)
if let Err(e) = srv.start() { if let Err(e) = srv.start() {

View File

@ -2,18 +2,39 @@ use std::net::SocketAddr;
use libunftp::{Server, ServerBuilder}; use libunftp::{Server, ServerBuilder};
use unftp_sbe_fs::Filesystem; use unftp_sbe_fs::Filesystem;
use std::sync::Arc; use std::sync::Arc;
use libunftp::auth::{AnonymousAuthenticator, DefaultUser}; use libunftp::auth::{DefaultUser, Authenticator, Credentials, AuthenticationError};
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use async_trait::async_trait;
pub struct FtpServer { pub struct FtpServer {
server: Option<Server<Filesystem, DefaultUser>>, server: Option<Server<Filesystem, DefaultUser>>,
addr: SocketAddr, addr: SocketAddr,
root_dir: std::path::PathBuf, root_dir: std::path::PathBuf,
shutdown_flag: Arc<AtomicBool>, shutdown_flag: Arc<AtomicBool>,
username: String,
password: String,
}
#[derive(Debug)]
struct CustomAuthenticator {
username: String,
password: String,
}
#[async_trait]
impl Authenticator<DefaultUser> for CustomAuthenticator {
#[allow(clippy::type_complexity)]
async fn authenticate(&self, username: &str, creds: &Credentials) -> Result<DefaultUser, AuthenticationError> {
if username == self.username && creds.password.as_ref().map_or(false, |p| p == &self.password) {
Ok(DefaultUser {})
} else {
Err(AuthenticationError::BadPassword)
}
}
} }
impl FtpServer { impl FtpServer {
pub fn new(addr: SocketAddr, root_dir: std::path::PathBuf) -> Result<Self, Box<dyn std::error::Error + Send + Sync>> { pub fn new(addr: SocketAddr, root_dir: std::path::PathBuf, username: String, password: String) -> Result<Self, Box<dyn std::error::Error + Send + Sync>> {
if !root_dir.exists() { if !root_dir.exists() {
return Err(format!("Directory does not exist: {:?}", root_dir).into()); return Err(format!("Directory does not exist: {:?}", root_dir).into());
} }
@ -22,15 +43,21 @@ impl FtpServer {
addr, addr,
root_dir, root_dir,
shutdown_flag: Arc::new(AtomicBool::new(false)), shutdown_flag: Arc::new(AtomicBool::new(false)),
username,
password,
}) })
} }
pub fn start(&mut self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { pub fn start(&mut self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let root_dir = self.root_dir.clone(); let root_dir = self.root_dir.clone();
let username = self.username.clone();
let password = self.password.clone();
let authenticator = CustomAuthenticator { username, password };
let server = ServerBuilder::new(Box::new(move || -> Filesystem { Filesystem::new(&root_dir).unwrap() })) let server = ServerBuilder::new(Box::new(move || -> Filesystem { Filesystem::new(&root_dir).unwrap() }))
.greeting("Welcome to FTP server") .greeting("Welcome to FTP server")
.passive_ports(50000..=60000) .passive_ports(50000..=60000)
.authenticator(Arc::new(AnonymousAuthenticator)) .authenticator(Arc::new(authenticator))
.build()?; .build()?;

View File

@ -10,6 +10,8 @@ pub struct FtpUi {
pub port_entry: gtk::Entry, pub port_entry: gtk::Entry,
pub dir_entry: gtk::Entry, pub dir_entry: gtk::Entry,
pub dir_button: gtk::Button, pub dir_button: gtk::Button,
pub username_entry: gtk::Entry,
pub password_entry: gtk::Entry,
} }
impl FtpUi { impl FtpUi {
@ -55,6 +57,19 @@ impl FtpUi {
.build(); .build();
let dir_button = gtk::Button::with_label("浏览"); let dir_button = gtk::Button::with_label("浏览");
// Username
let username_label = gtk::Label::new(Some("用户名:"));
let username_entry = gtk::Entry::builder()
.text("admin")
.build();
// Password
let password_label = gtk::Label::new(Some("密码:"));
let password_entry = gtk::Entry::builder()
.text("password")
.visibility(false) // Hide password input
.build();
// Status // Status
let status_label = gtk::Label::new(Some("Status: Stopped")); let status_label = gtk::Label::new(Some("Status: Stopped"));
@ -74,10 +89,16 @@ impl FtpUi {
grid.attach(&dir_entry, 1, 2, 1, 1); grid.attach(&dir_entry, 1, 2, 1, 1);
grid.attach(&dir_button, 2, 2, 1, 1); grid.attach(&dir_button, 2, 2, 1, 1);
grid.attach(&status_label, 0, 3, 3, 1); grid.attach(&username_label, 0, 3, 1, 1);
grid.attach(&username_entry, 1, 3, 1, 1);
grid.attach(&start_button, 0, 4, 1, 1); grid.attach(&password_label, 0, 4, 1, 1);
grid.attach(&stop_button, 1, 4, 1, 1); grid.attach(&password_entry, 1, 4, 1, 1);
grid.attach(&status_label, 0, 5, 3, 1);
grid.attach(&start_button, 0, 6, 1, 1);
grid.attach(&stop_button, 1, 6, 1, 1);
window.add(&grid); window.add(&grid);
@ -90,6 +111,8 @@ impl FtpUi {
port_entry, port_entry,
dir_entry, dir_entry,
dir_button, dir_button,
username_entry,
password_entry,
} }
} }
} }