Merge pull request #1036 from 21pages/password

refactor password
This commit is contained in:
RustDesk 2022-07-25 17:00:57 +08:00 committed by GitHub
commit 435ff56e6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 246 additions and 731 deletions

View File

@ -534,9 +534,9 @@ impl Config {
}
}
pub fn get_auto_password() -> String {
pub fn get_auto_password(length: usize) -> String {
let mut rng = rand::thread_rng();
(0..6)
(0..length)
.map(|_| CHARS[rng.gen::<usize>() % CHARS.len()])
.collect()
}
@ -657,7 +657,7 @@ impl Config {
log::info!("id updated from {} to {}", id, new_id);
}
pub fn set_security_password(password: &str) {
pub fn set_permanent_password(password: &str) {
let mut config = CONFIG.write().unwrap();
if password == config.password {
return;
@ -666,7 +666,7 @@ impl Config {
config.store();
}
pub fn get_security_password() -> String {
pub fn get_permanent_password() -> String {
CONFIG.read().unwrap().password.clone()
}
@ -682,7 +682,7 @@ impl Config {
pub fn get_salt() -> String {
let mut salt = CONFIG.read().unwrap().salt.clone();
if salt.is_empty() {
salt = Config::get_auto_password();
salt = Config::get_auto_password(6);
Config::set_salt(&salt);
}
salt

View File

@ -1,182 +1,62 @@
pub mod password {
use crate::config::Config;
use std::{
fmt::Display,
str::FromStr,
sync::{Arc, RwLock},
};
use std::sync::{Arc, RwLock};
lazy_static::lazy_static! {
pub static ref RANDOM_PASSWORD:Arc<RwLock<String>> = Arc::new(RwLock::new(Config::get_auto_password()));
pub static ref TEMPORARY_PASSWORD:Arc<RwLock<String>> = Arc::new(RwLock::new(Config::get_auto_password(temporary_password_length())));
}
const SECURITY_ENABLED: &'static str = "security-password-enabled";
const RANDOM_ENABLED: &'static str = "random-password-enabled";
const ONETIME_ENABLED: &'static str = "onetime-password-enabled";
const ONETIME_ACTIVATED: &'static str = "onetime-password-activated";
const UPDATE_METHOD: &'static str = "random-password-update-method";
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum UpdateMethod {
KEEP,
UPDATE,
DISABLE,
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum VerificationMethod {
OnlyUseTemporaryPassword,
OnlyUsePermanentPassword,
UseBothPasswords,
}
impl FromStr for UpdateMethod {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s == "KEEP" {
Ok(Self::KEEP)
} else if s == "UPDATE" {
Ok(Self::UPDATE)
} else if s == "DISABLE" {
Ok(Self::DISABLE)
} else {
Err(())
}
}
// Should only be called in server
pub fn update_temporary_password() {
*TEMPORARY_PASSWORD.write().unwrap() =
Config::get_auto_password(temporary_password_length());
}
impl Display for UpdateMethod {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
UpdateMethod::KEEP => write!(f, "KEEP"),
UpdateMethod::UPDATE => write!(f, "UPDATE"),
UpdateMethod::DISABLE => write!(f, "DISABLE"),
}
}
// Should only be called in server
pub fn temporary_password() -> String {
TEMPORARY_PASSWORD.read().unwrap().clone()
}
pub fn set_random_password(password: &str) {
*RANDOM_PASSWORD.write().unwrap() = password.to_owned();
}
pub fn random_password() -> String {
let mut password = RANDOM_PASSWORD.read().unwrap().clone();
if password.is_empty() {
password = Config::get_auto_password();
set_random_password(&password);
}
password
}
pub fn random_password_valid() -> bool {
if random_enabled() {
onetime_password_activated() || !onetime_password_enabled()
fn verification_method() -> VerificationMethod {
let method = Config::get_option("verification-method");
if method == "use-temporary-password" {
VerificationMethod::OnlyUseTemporaryPassword
} else if method == "use-permanent-password" {
VerificationMethod::OnlyUsePermanentPassword
} else {
false
VerificationMethod::UseBothPasswords // default
}
}
pub fn passwords() -> Vec<String> {
let mut v = vec![];
if random_password_valid() {
v.push(random_password());
}
if security_enabled() {
v.push(Config::get_security_password());
}
v
}
pub fn after_session(authorized: bool) {
if authorized && random_enabled() {
UpdateMethod::from_str(&update_method())
.map(|method| match method {
UpdateMethod::KEEP => {}
UpdateMethod::UPDATE => set_random_password(&Config::get_auto_password()),
UpdateMethod::DISABLE => set_random_enabled(false),
})
.ok();
}
}
pub fn update_method() -> String {
let mut method = Config::get_option(UPDATE_METHOD);
if UpdateMethod::from_str(&method).is_err() {
method = UpdateMethod::KEEP.to_string(); // default is keep
set_update_method(&method);
}
method
}
pub fn set_update_method(method: &str) {
Config::set_option(UPDATE_METHOD.to_owned(), method.to_owned());
}
pub fn random_enabled() -> bool {
str2bool(RANDOM_ENABLED, true, || {
set_onetime_password_activated(false);
set_random_password(&Config::get_auto_password());
})
}
pub fn set_random_enabled(enabled: bool) {
if enabled != random_enabled() {
Config::set_option(RANDOM_ENABLED.to_owned(), bool2str(enabled));
set_onetime_password_activated(false);
if enabled {
set_random_password(&Config::get_auto_password());
}
}
}
pub fn security_enabled() -> bool {
str2bool(SECURITY_ENABLED, true, || {})
}
pub fn set_security_enabled(enabled: bool) {
if enabled != security_enabled() {
Config::set_option(SECURITY_ENABLED.to_owned(), bool2str(enabled));
}
}
pub fn onetime_password_enabled() -> bool {
str2bool(ONETIME_ENABLED, false, || {
set_onetime_password_activated(false);
set_random_password(&Config::get_auto_password());
})
}
pub fn set_onetime_password_enabled(enabled: bool) {
if enabled != onetime_password_enabled() {
Config::set_option(ONETIME_ENABLED.to_owned(), bool2str(enabled));
set_onetime_password_activated(false);
set_random_password(&Config::get_auto_password());
}
}
pub fn onetime_password_activated() -> bool {
str2bool(ONETIME_ACTIVATED, false, || {})
}
pub fn set_onetime_password_activated(activated: bool) {
if activated != onetime_password_activated() {
Config::set_option(ONETIME_ACTIVATED.to_owned(), bool2str(activated));
if activated {
set_random_password(&Config::get_auto_password());
}
}
}
// notice: Function nesting
fn str2bool(key: &str, default: bool, default_set: impl Fn()) -> bool {
let option = Config::get_option(key);
if option == "Y" {
true
} else if option == "N" {
false
pub fn temporary_password_length() -> usize {
let length = Config::get_option("temporary-password-length");
if length == "8" {
8
} else if length == "10" {
10
} else {
Config::set_option(key.to_owned(), bool2str(default));
default_set();
default
6 // default
}
}
fn bool2str(option: bool) -> String {
if option { "Y" } else { "N" }.to_owned()
pub fn temporary_enabled() -> bool {
verification_method() != VerificationMethod::OnlyUsePermanentPassword
}
pub fn permanent_enabled() -> bool {
verification_method() != VerificationMethod::OnlyUseTemporaryPassword
}
pub fn has_valid_password() -> bool {
temporary_enabled() && !temporary_password().is_empty()
|| permanent_enabled() && !Config::get_permanent_password().is_empty()
}
}

View File

@ -1,4 +1,5 @@
use crate::rendezvous_mediator::RendezvousMediator;
use bytes::Bytes;
#[cfg(not(any(target_os = "android", target_os = "ios")))]
pub use clipboard::ClipbaordFile;
use hbb_common::{
@ -19,20 +20,9 @@ use parity_tokio_ipc::{
};
use serde_derive::{Deserialize, Serialize};
use std::{collections::HashMap, sync::atomic::Ordering};
use bytes::Bytes;
#[cfg(not(windows))]
use std::{fs::File, io::prelude::*};
const STR_RANDOM_PASSWORD: &'static str = "random-password";
const STR_SECURITY_PASSWORD: &'static str = "security-password";
const STR_RANDOM_PASSWORD_UPDATE_METHOD: &'static str = "random-password-update-method";
const STR_RANDOM_PASSWORD_ENABLED: &'static str = "random-password-enabled";
const STR_SECURITY_PASSWORD_ENABLED: &'static str = "security-password-enabled";
const STR_ONETIME_PASSWORD_ENABLED: &'static str = "onetime-password-enabled";
const STR_ONETIME_PASSWORD_ACTIVATED: &'static str = "onetime-password-activated";
const STR_RANDOM_PASSWORD_VALID: &'static str = "random-password-valid";
pub const STR_PASSWORD_DESCRIPTION: &'static str = "password-description";
// State with timestamp, because std::time::Instant cannot be serialized
#[derive(Debug, Serialize, Deserialize, Copy, Clone)]
#[serde(tag = "t", content = "c")]
@ -340,20 +330,10 @@ async fn handle(data: Data, stream: &mut Connection) {
let value;
if name == "id" {
value = Some(Config::get_id());
} else if name == STR_RANDOM_PASSWORD {
value = Some(password::random_password());
} else if name == STR_SECURITY_PASSWORD {
value = Some(Config::get_security_password());
} else if name == STR_RANDOM_PASSWORD_UPDATE_METHOD {
value = Some(password::update_method().to_string());
} else if name == STR_PASSWORD_DESCRIPTION {
value = Some(
password::random_password()
+ &password::security_enabled().to_string()
+ &password::random_enabled().to_string()
+ &password::onetime_password_enabled().to_string()
+ &password::onetime_password_activated().to_string(),
);
} else if name == "temporary-password" {
value = Some(password::temporary_password());
} else if name == "permanent-password" {
value = Some(Config::get_permanent_password());
} else if name == "salt" {
value = Some(Config::get_salt());
} else if name == "rendezvous_server" {
@ -373,12 +353,10 @@ async fn handle(data: Data, stream: &mut Connection) {
if name == "id" {
Config::set_key_confirmed(false);
Config::set_id(&value);
} else if name == STR_RANDOM_PASSWORD {
password::set_random_password(&value);
} else if name == STR_SECURITY_PASSWORD {
Config::set_security_password(&value);
} else if name == STR_RANDOM_PASSWORD_UPDATE_METHOD {
password::set_update_method(&value);
} else if name == "temporary-password" {
password::update_temporary_password();
} else if name == "permanent-password" {
Config::set_permanent_password(&value);
} else if name == "salt" {
Config::set_salt(&value);
} else {
@ -418,36 +396,6 @@ async fn handle(data: Data, stream: &mut Connection) {
Data::TestRendezvousServer => {
crate::test_rendezvous_server();
}
Data::Bool((name, value)) => match value {
None => {
let value;
if name == STR_SECURITY_PASSWORD_ENABLED {
value = Some(password::security_enabled());
} else if name == STR_RANDOM_PASSWORD_ENABLED {
value = Some(password::random_enabled());
} else if name == STR_ONETIME_PASSWORD_ENABLED {
value = Some(password::onetime_password_enabled());
} else if name == STR_ONETIME_PASSWORD_ACTIVATED {
value = Some(password::onetime_password_activated());
} else if name == STR_RANDOM_PASSWORD_VALID {
value = Some(password::random_password_valid());
} else {
return;
}
allow_err!(stream.send(&Data::Bool((name, value))).await);
}
Some(value) => {
if name == STR_SECURITY_PASSWORD_ENABLED {
password::set_security_enabled(value);
} else if name == STR_RANDOM_PASSWORD_ENABLED {
password::set_random_enabled(value);
} else if name == STR_ONETIME_PASSWORD_ENABLED {
password::set_onetime_password_enabled(value);
} else if name == STR_ONETIME_PASSWORD_ACTIVATED {
password::set_onetime_password_activated(value);
}
}
},
_ => {}
}
}
@ -530,10 +478,6 @@ where
.await
}
async fn send_bool(&mut self, name: &str, value: bool) -> ResultType<()> {
self.send(&Data::Bool((name.to_owned(), Some(value)))).await
}
pub async fn next_timeout(&mut self, ms_timeout: u64) -> ResultType<Option<Data>> {
Ok(timeout(ms_timeout, self.next()).await??)
}
@ -605,128 +549,22 @@ pub async fn set_config(name: &str, value: String) -> ResultType<()> {
set_config_async(name, value).await
}
#[tokio::main(flavor = "current_thread")]
async fn get_bool(name: &str) -> ResultType<Option<bool>> {
get_bool_async(name, 1_000).await
pub fn update_temporary_password() -> ResultType<()> {
set_config("temporary-password", "".to_owned())
}
async fn get_bool_async(name: &str, ms_timeout: u64) -> ResultType<Option<bool>> {
let mut c = connect(ms_timeout, "").await?;
c.send(&Data::Bool((name.to_owned(), None))).await?;
if let Some(Data::Bool((name2, value))) = c.next_timeout(ms_timeout).await? {
if name == name2 {
return Ok(value);
}
}
return Ok(None);
}
pub async fn set_bool_async(name: &str, value: bool) -> ResultType<()> {
let mut c = connect(1000, "").await?;
c.send_bool(name, value).await?;
Ok(())
}
#[tokio::main(flavor = "current_thread")]
pub async fn set_bool(name: &str, value: bool) -> ResultType<()> {
set_bool_async(name, value).await
}
pub fn get_random_password() -> String {
if let Ok(Some(password)) = get_config(STR_RANDOM_PASSWORD) {
password::set_random_password(&password);
password
pub fn get_permanent_password() -> String {
if let Ok(Some(v)) = get_config("permanent-password") {
Config::set_permanent_password(&v);
v
} else {
password::random_password()
Config::get_permanent_password()
}
}
pub fn set_random_password(v: String) -> ResultType<()> {
password::set_random_password(&v);
set_config(STR_RANDOM_PASSWORD, v)
}
pub fn set_security_password(v: String) -> ResultType<()> {
Config::set_security_password(&v);
set_config(STR_SECURITY_PASSWORD, v)
}
pub fn random_password_update_method() -> String {
if let Ok(Some(method)) = get_config(STR_RANDOM_PASSWORD_UPDATE_METHOD) {
password::set_update_method(&method);
method
} else {
password::update_method()
}
}
pub fn set_random_password_update_method(method: String) -> ResultType<()> {
password::set_update_method(&method);
set_config(STR_RANDOM_PASSWORD_UPDATE_METHOD, method)
}
pub fn is_random_password_enabled() -> bool {
if let Ok(Some(enabled)) = get_bool(STR_RANDOM_PASSWORD_ENABLED) {
password::set_random_enabled(enabled);
enabled
} else {
password::random_enabled()
}
}
pub fn set_random_password_enabled(enabled: bool) -> ResultType<()> {
password::set_random_enabled(enabled);
set_bool(STR_RANDOM_PASSWORD_ENABLED, enabled)
}
pub fn is_security_password_enabled() -> bool {
if let Ok(Some(enabled)) = get_bool(STR_SECURITY_PASSWORD_ENABLED) {
password::set_security_enabled(enabled);
enabled
} else {
password::security_enabled()
}
}
pub fn set_security_password_enabled(enabled: bool) -> ResultType<()> {
password::set_security_enabled(enabled);
set_bool(STR_SECURITY_PASSWORD_ENABLED, enabled)
}
pub fn is_onetime_password_enabled() -> bool {
if let Ok(Some(enabled)) = get_bool(STR_ONETIME_PASSWORD_ENABLED) {
password::set_onetime_password_enabled(enabled);
enabled
} else {
password::onetime_password_enabled()
}
}
pub fn set_onetime_password_enabled(enabled: bool) -> ResultType<()> {
password::set_onetime_password_enabled(enabled);
set_bool(STR_ONETIME_PASSWORD_ENABLED, enabled)
}
pub fn is_onetime_password_activated() -> bool {
if let Ok(Some(activated)) = get_bool(STR_ONETIME_PASSWORD_ACTIVATED) {
password::set_onetime_password_activated(activated);
activated
} else {
password::onetime_password_activated()
}
}
pub fn set_onetime_password_activated(activated: bool) -> ResultType<()> {
password::set_onetime_password_activated(activated);
set_bool(STR_ONETIME_PASSWORD_ACTIVATED, activated)
}
pub fn is_random_password_valid() -> bool {
if let Ok(Some(valid)) = get_bool(STR_RANDOM_PASSWORD_VALID) {
valid
} else {
password::random_password_valid()
}
pub fn set_permanent_password(v: String) -> ResultType<()> {
Config::set_permanent_password(&v);
set_config("permanent-password", v)
}
pub fn get_id() -> String {

View File

@ -287,18 +287,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Keep RustDesk background service", "保持RustDesk后台服务"),
("Ignore Battery Optimizations", "忽略电池优化"),
("android_open_battery_optimizations_tip", "如需关闭此功能请在接下来的RustDesk应用设置页面中找到并进入 [电源] 页面,取消勾选 [不受限制]"),
("Random Password After Session", "会话结束更新随机密码"),
("Keep", "保持"),
("Update", "更新"),
("Disable", "禁用"),
("Onetime Password", "一次性口令"),
("Verification Method", "密码验证方式"),
("Enable security password", "启用安全密码"),
("Enable random password", "启用随机密码"),
("Enable onetime password", "启用一次性访问功能"),
("Disable onetime password", "禁用一次性访问功能"),
("Activate onetime password", "激活一次性访问功能"),
("Set security password", "设置安全密码"),
("Connection not allowed", "对方不允许连接"),
("Use temporary password", "使用临时密码"),
("Use permanent password", "使用固定密码"),
("Use both passwords", "同时使用两种密码"),
("Set permanent password", "设置固定密码"),
("Set temporary password length", "设置临时密码长度"),
].iter().cloned().collect();
}

View File

@ -287,18 +287,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Keep RustDesk background service", ""),
("Ignore Battery Optimizations", ""),
("android_open_battery_optimizations_tip", ""),
("Random Password After Session", ""),
("Keep", ""),
("Update", ""),
("Disable", ""),
("Onetime Password", ""),
("Verification Method", ""),
("Enable security password", ""),
("Enable random password", ""),
("Enable onetime password", ""),
("Disable onetime password", ""),
("Activate onetime password", ""),
("Set security password", ""),
("Connection not allowed", ""),
("Use temporary password", ""),
("Use permanent password", ""),
("Use both passwords", ""),
("Set permanent password", ""),
("Set temporary password length", ""),
].iter().cloned().collect();
}

View File

@ -287,18 +287,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Keep RustDesk background service", ""),
("Ignore Battery Optimizations", ""),
("android_open_battery_optimizations_tip", ""),
("Random Password After Session", ""),
("Keep", ""),
("Update", ""),
("Disable", ""),
("Onetime Password", ""),
("Verification Method", ""),
("Enable security password", ""),
("Enable random password", ""),
("Enable onetime password", ""),
("Disable onetime password", ""),
("Activate onetime password", ""),
("Set security password", ""),
("Connection not allowed", ""),
("Use temporary password", ""),
("Use permanent password", ""),
("Use both passwords", ""),
("Set permanent password", ""),
("Set temporary password length", ""),
].iter().cloned().collect();
}

View File

@ -287,18 +287,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Keep RustDesk background service", "RustDesk im Hintergrund ausführen"),
("Ignore Battery Optimizations", "Batterieoptimierung ignorieren"),
("android_open_battery_optimizations_tip", "Möchten Sie die Batterieopimierungs-Einstellungen öffnen?"),
("Random Password After Session", "Neues zufälliges Passwort nach jeder Sitzung"),
("Keep", "Behalten"),
("Update", "Aktualisieren"),
("Disable", "Deaktivieren"),
("Onetime Password", "Einmal-Passwort"),
("Verification Method", "Überprüfungsmethode"),
("Enable security password", "Sicheres Passwort aktivieren"),
("Enable random password", "Zufälliges Passwort aktivieren"),
("Enable onetime password", "Einmal-Passwort aktivieren"),
("Disable onetime password", "Einmal-Passwort deaktivieren"),
("Activate onetime password", "Einmal-Passwort aktivieren"),
("Set security password", "Sicheres Passwort setzen"),
("Connection not allowed", "Verbindung abgelehnt"),
("Use temporary password", ""),
("Use permanent password", ""),
("Use both passwords", ""),
("Set permanent password", ""),
("Set temporary password length", ""),
].iter().cloned().collect();
}

View File

@ -287,18 +287,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Keep RustDesk background service", ""),
("Ignore Battery Optimizations", ""),
("android_open_battery_optimizations_tip", ""),
("Random Password After Session", ""),
("Keep", ""),
("Update", ""),
("Disable", ""),
("Onetime Password", ""),
("Verification Method", ""),
("Enable security password", ""),
("Enable random password", ""),
("Enable onetime password", ""),
("Disable onetime password", ""),
("Activate onetime password", ""),
("Set security password", ""),
("Connection not allowed", ""),
("Use temporary password", ""),
("Use permanent password", ""),
("Use both passwords", ""),
("Set permanent password", ""),
("Set temporary password length", ""),
].iter().cloned().collect();
}

View File

@ -287,18 +287,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Keep RustDesk background service", ""),
("Ignore Battery Optimizations", ""),
("android_open_battery_optimizations_tip", ""),
("Random Password After Session", ""),
("Keep", ""),
("Update", ""),
("Disable", ""),
("Onetime Password", ""),
("Verification Method", ""),
("Enable security password", ""),
("Enable random password", ""),
("Enable onetime password", ""),
("Disable onetime password", ""),
("Activate onetime password", ""),
("Set security password", ""),
("Connection not allowed", ""),
("Use temporary password", ""),
("Use permanent password", ""),
("Use both passwords", ""),
("Set permanent password", ""),
("Set temporary password length", ""),
].iter().cloned().collect();
}

View File

@ -287,18 +287,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Keep RustDesk background service", ""),
("Ignore Battery Optimizations", ""),
("android_open_battery_optimizations_tip", ""),
("Random Password After Session", ""),
("Keep", ""),
("Update", ""),
("Disable", ""),
("Onetime Password", ""),
("Verification Method", ""),
("Enable security password", ""),
("Enable random password", ""),
("Enable onetime password", ""),
("Disable onetime password", ""),
("Activate onetime password", ""),
("Set security password", ""),
("Connection not allowed", ""),
("Use temporary password", ""),
("Use permanent password", ""),
("Use both passwords", ""),
("Set permanent password", ""),
("Set temporary password length", ""),
].iter().cloned().collect();
}

View File

@ -287,18 +287,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Keep RustDesk background service", ""),
("Ignore Battery Optimizations", ""),
("android_open_battery_optimizations_tip", ""),
("Random Password After Session", ""),
("Keep", ""),
("Update", ""),
("Disable", ""),
("Onetime Password", ""),
("Verification Method", ""),
("Enable security password", ""),
("Enable random password", ""),
("Enable onetime password", ""),
("Disable onetime password", ""),
("Activate onetime password", ""),
("Set security password", ""),
("Connection not allowed", ""),
("Use temporary password", ""),
("Use permanent password", ""),
("Use both passwords", ""),
("Set permanent password", ""),
("Set temporary password length", ""),
].iter().cloned().collect();
}

View File

@ -287,18 +287,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Keep RustDesk background service", ""),
("Ignore Battery Optimizations", ""),
("android_open_battery_optimizations_tip", ""),
("Random Password After Session", ""),
("Keep", ""),
("Update", ""),
("Disable", ""),
("Onetime Password", ""),
("Verification Method", ""),
("Enable security password", ""),
("Enable random password", ""),
("Enable onetime password", ""),
("Disable onetime password", ""),
("Activate onetime password", ""),
("Set security password", ""),
("Connection not allowed", ""),
("Use temporary password", ""),
("Use permanent password", ""),
("Use both passwords", ""),
("Set permanent password", ""),
("Set temporary password length", ""),
].iter().cloned().collect();
}

View File

@ -287,18 +287,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Keep RustDesk background service", ""),
("Ignore Battery Optimizations", ""),
("android_open_battery_optimizations_tip", ""),
("Random Password After Session", ""),
("Keep", ""),
("Update", ""),
("Disable", ""),
("Onetime Password", ""),
("Verification Method", ""),
("Enable security password", ""),
("Enable random password", ""),
("Enable onetime password", ""),
("Disable onetime password", ""),
("Activate onetime password", ""),
("Set security password", ""),
("Connection not allowed", ""),
("Use temporary password", ""),
("Use permanent password", ""),
("Use both passwords", ""),
("Set permanent password", ""),
("Set temporary password length", ""),
].iter().cloned().collect();
}

View File

@ -287,18 +287,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Keep RustDesk background service", ""),
("Ignore Battery Optimizations", ""),
("android_open_battery_optimizations_tip", ""),
("Random Password After Session", ""),
("Keep", ""),
("Update", ""),
("Disable", ""),
("Onetime Password", ""),
("Verification Method", ""),
("Enable security password", ""),
("Enable random password", ""),
("Enable onetime password", ""),
("Disable onetime password", ""),
("Activate onetime password", ""),
("Set security password", ""),
("Connection not allowed", ""),
("Use temporary password", ""),
("Use permanent password", ""),
("Use both passwords", ""),
("Set permanent password", ""),
("Set temporary password length", ""),
].iter().cloned().collect();
}

View File

@ -287,18 +287,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Keep RustDesk background service", "Сохранить фоновый службу RustDesk"),
("Ignore Battery Optimizations", "Игнорировать оптимизацию батареи"),
("android_open_battery_optimizations_tip", "Перейдите на следующую страницу настроек "),
("Random Password After Session", "Случайный пароль после сеанса"),
("Keep", "Оставить"),
("Update", "Обновить"),
("Disable", "Отключить"),
("Onetime Password", "Одноразовый пароль"),
("Verification Method", "Метод верификации"),
("Enable security password", "Включить пароль безопасности"),
("Enable random password", "Включить случайный пароль"),
("Enable onetime password", "Включить одноразовый пароль"),
("Disable onetime password", "Отключить одноразовый пароль"),
("Activate onetime password", "Активировать одноразовый пароль"),
("Set security password", "Задать пароль безопасности"),
("Connection not allowed", "Подключение не разрешено"),
("Use temporary password", ""),
("Use permanent password", ""),
("Use both passwords", ""),
("Set permanent password", ""),
("Set temporary password length", ""),
].iter().cloned().collect();
}

View File

@ -287,18 +287,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Keep RustDesk background service", ""),
("Ignore Battery Optimizations", ""),
("android_open_battery_optimizations_tip", ""),
("Random Password After Session", ""),
("Keep", ""),
("Update", ""),
("Disable", ""),
("Onetime Password", ""),
("Verification Method", ""),
("Enable security password", ""),
("Enable random password", ""),
("Enable onetime password", ""),
("Disable onetime password", ""),
("Activate onetime password", ""),
("Set security password", ""),
("Connection not allowed", ""),
("Use temporary password", ""),
("Use permanent password", ""),
("Use both passwords", ""),
("Set permanent password", ""),
("Set temporary password length", ""),
].iter().cloned().collect();
}

View File

@ -287,18 +287,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Keep RustDesk background service", ""),
("Ignore Battery Optimizations", ""),
("android_open_battery_optimizations_tip", ""),
("Random Password After Session", ""),
("Keep", ""),
("Update", ""),
("Disable", ""),
("Onetime Password", ""),
("Verification Method", ""),
("Enable security password", ""),
("Enable random password", ""),
("Enable onetime password", ""),
("Disable onetime password", ""),
("Activate onetime password", ""),
("Set security password", ""),
("Connection not allowed", ""),
("Use temporary password", ""),
("Use permanent password", ""),
("Use both passwords", ""),
("Set permanent password", ""),
("Set temporary password length", ""),
].iter().cloned().collect();
}

View File

@ -287,18 +287,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Keep RustDesk background service", ""),
("Ignore Battery Optimizations", ""),
("android_open_battery_optimizations_tip", ""),
("Random Password After Session", ""),
("Keep", ""),
("Update", ""),
("Disable", ""),
("Onetime Password", ""),
("Verification Method", ""),
("Enable security password", ""),
("Enable random password", ""),
("Enable onetime password", ""),
("Disable onetime password", ""),
("Activate onetime password", ""),
("Set security password", ""),
("Connection not allowed", ""),
("Use temporary password", ""),
("Use permanent password", ""),
("Use both passwords", ""),
("Set permanent password", ""),
("Set temporary password length", ""),
].iter().cloned().collect();
}

View File

@ -287,18 +287,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Keep RustDesk background service", "保持RustDesk後台服務"),
("Ignore Battery Optimizations", "忽略電池優化"),
("android_open_battery_optimizations_tip", "如需關閉此功能請在接下來的RustDesk應用設置頁面中找到並進入 [電源] 頁面,取消勾選 [不受限制]"),
("Random Password After Session", "會話結束更新隨機密碼"),
("Keep", "保持"),
("Update", "更新"),
("Disable", "禁用"),
("Onetime Password", "一次性口令"),
("Verification Method", "密碼驗證方式"),
("Enable security password", "啟用安全密碼"),
("Enable random password", "啟用隨機密碼"),
("Enable onetime password", "啟用一次性訪問功能"),
("Disable onetime password", "禁用一次性訪問功能"),
("Activate onetime password", "激活一次性訪問功能"),
("Set security password", "設置安全密碼"),
("Connection not allowed", "對方不允許連接"),
("Use temporary password", "使用臨時密碼"),
("Use permanent password", "使用固定密碼"),
("Use both passwords", "同時使用兩種密碼"),
("Set permanent password", "設定固定密碼"),
("Set temporary password length", "設定臨時密碼長度"),
].iter().cloned().collect();
}

View File

@ -152,7 +152,7 @@ fn main() {
return;
} else if args[0] == "--password" {
if args.len() == 2 {
ipc::set_security_password(args[1].to_owned()).unwrap();
ipc::set_permanent_password(args[1].to_owned()).unwrap();
}
return;
} else if args[0] == "--check-hwcodec-config" {

View File

@ -134,7 +134,7 @@ impl Connection {
) {
let hash = Hash {
salt: Config::get_salt(),
challenge: Config::get_auto_password(),
challenge: Config::get_auto_password(6),
..Default::default()
};
let (tx_from_cm_holder, mut rx_from_cm) = mpsc::unbounded_channel::<ipc::Data>();
@ -415,7 +415,9 @@ impl Connection {
video_service::notify_video_frame_feched(id, None);
scrap::codec::Encoder::update_video_encoder(id, scrap::codec::EncoderUpdate::Remove);
video_service::VIDEO_QOS.lock().unwrap().reset();
password::after_session(conn.authorized);
if conn.authorized {
password::update_temporary_password();
}
if let Err(err) = conn.try_port_forward_loop(&mut rx_from_cm).await {
conn.on_close(&err.to_string(), false).await;
}
@ -820,17 +822,9 @@ impl Connection {
}
fn validate_password(&mut self) -> bool {
if password::security_enabled() {
if self.validate_one_password(Config::get_security_password()) {
return true;
}
}
if password::random_password_valid() {
let password = password::random_password();
if password::temporary_enabled() {
let password = password::temporary_password();
if self.validate_one_password(password.clone()) {
if password::onetime_password_activated() {
password::set_onetime_password_activated(false);
}
SESSIONS.lock().unwrap().insert(
self.lr.my_id.clone(),
Session {
@ -843,6 +837,11 @@ impl Connection {
return true;
}
}
if password::permanent_enabled() {
if self.validate_one_password(Config::get_permanent_password()) {
return true;
}
}
false
}
@ -956,7 +955,7 @@ impl Connection {
} else if lr.password.is_empty() {
self.try_start_cm(lr.my_id, lr.my_name, false);
} else {
if password::passwords().len() == 0 {
if !password::has_valid_password() {
self.send_login_error("Connection not allowed").await;
return false;
}

View File

@ -187,16 +187,20 @@ impl UI {
ipc::get_id()
}
fn get_random_password(&self) -> String {
ipc::get_random_password()
fn temporary_password(&mut self) -> String {
self.5.lock().unwrap().clone()
}
fn update_random_password(&self) {
allow_err!(ipc::set_random_password(Config::get_auto_password()));
fn update_temporary_password(&self) {
allow_err!(ipc::update_temporary_password());
}
fn set_security_password(&self, password: String) {
allow_err!(ipc::set_security_password(password));
fn permanent_password(&self) -> String {
ipc::get_permanent_password()
}
fn set_permanent_password(&self, password: String) {
allow_err!(ipc::set_permanent_password(password));
}
fn get_remote_id(&mut self) -> String {
@ -775,54 +779,6 @@ impl UI {
fn get_langs(&self) -> String {
crate::lang::LANGS.to_string()
}
fn random_password_update_method(&self) -> String {
ipc::random_password_update_method()
}
fn set_random_password_update_method(&self, method: String) {
allow_err!(ipc::set_random_password_update_method(method));
}
fn is_random_password_enabled(&self) -> bool {
ipc::is_random_password_enabled()
}
fn set_random_password_enabled(&self, enabled: bool) {
allow_err!(ipc::set_random_password_enabled(enabled));
}
fn is_security_password_enabled(&self) -> bool {
ipc::is_security_password_enabled()
}
fn set_security_password_enabled(&self, enabled: bool) {
allow_err!(ipc::set_security_password_enabled(enabled));
}
fn is_onetime_password_enabled(&self) -> bool {
ipc::is_onetime_password_enabled()
}
fn set_onetime_password_enabled(&self, enabled: bool) {
allow_err!(ipc::set_onetime_password_enabled(enabled));
}
fn is_onetime_password_activated(&self) -> bool {
ipc::is_onetime_password_activated()
}
fn set_onetime_password_activated(&self, activated: bool) {
allow_err!(ipc::set_onetime_password_activated(activated));
}
fn is_random_password_valid(&self) -> bool {
ipc::is_random_password_valid()
}
fn password_description(&mut self) -> String {
self.5.lock().unwrap().clone()
}
}
impl sciter::EventHandler for UI {
@ -832,9 +788,10 @@ impl sciter::EventHandler for UI {
fn is_xfce();
fn using_public_server();
fn get_id();
fn get_random_password();
fn update_random_password();
fn set_security_password(String);
fn temporary_password();
fn update_temporary_password();
fn permanent_password();
fn set_permanent_password(String);
fn get_remote_id();
fn set_remote_id(String);
fn closing(i32, i32, i32, i32);
@ -904,18 +861,6 @@ impl sciter::EventHandler for UI {
fn get_uuid();
fn has_hwcodec();
fn get_langs();
fn random_password_update_method();
fn set_random_password_update_method(String);
fn is_random_password_enabled();
fn set_random_password_enabled(bool);
fn is_security_password_enabled();
fn set_security_password_enabled(bool);
fn is_onetime_password_enabled();
fn set_onetime_password_enabled(bool);
fn is_onetime_password_activated();
fn set_onetime_password_activated(bool);
fn is_random_password_valid();
fn password_description();
}
}
@ -982,7 +927,7 @@ async fn check_connect_status_(
Ok(Some(ipc::Data::Config((name, Some(value))))) => {
if name == "id" {
id = value;
} else if name == ipc::STR_PASSWORD_DESCRIPTION {
} else if name == "temporary-password" {
*password.lock().unwrap() = value;
}
}
@ -1003,7 +948,7 @@ async fn check_connect_status_(
c.send(&ipc::Data::OnlineStatus(None)).await.ok();
c.send(&ipc::Data::Options(None)).await.ok();
c.send(&ipc::Data::Config(("id".to_owned(), None))).await.ok();
c.send(&ipc::Data::Config((ipc::STR_PASSWORD_DESCRIPTION.to_owned(), None))).await.ok();
c.send(&ipc::Data::Config(("temporary-password".to_owned(), None))).await.ok();
}
}
}

View File

@ -529,9 +529,7 @@ class App: Reactor.Component
<MyIdMenu />
{key_confirmed ? <input type="text" readonly value={formatId(get_id())}/> : translate("Generating ...")}
</div>
<div .your-desktop>
<PasswordArea />
</div>
<PasswordArea />
</div>
{!is_win || handler.is_installed() ? "": <InstallMe />}
{software_update_url ? <UpdateMe /> : ""}
@ -802,8 +800,8 @@ function watch_screen_recording() {
class PasswordEyeArea : Reactor.Component {
render() {
var show = handler.is_random_password_valid();
var value = show ? handler.get_random_password() : "-";
var method = handler.get_option('verification-method');
var value = method != 'use-permanent-password' ? password_cache[0] : "-";
return
<div .eye-area style="width: *">
<input|text @{this.input} readonly value={value} />
@ -812,95 +810,49 @@ class PasswordEyeArea : Reactor.Component {
}
event click $(svg#refresh-password) (_, me) {
if (handler.is_random_password_valid()) handler.update_random_password();
handler.update_temporary_password();
this.update();
}
}
var verificationMethodMenu;
class VerificationMethodMenu: Reactor.Component {
var temporaryPasswordLengthMenu;
class TemporaryPasswordLengthMenu: Reactor.Component {
function this() {
verificationMethodMenu = this;
temporaryPasswordLengthMenu = this;
}
function render() {
if (!this.show) return <li />;
var me = this;
var method = handler.get_option('verification-method');
self.timer(1ms, function() { me.toggleMenuState() });
return <li>{translate('Verification Method')}
<menu #verification-method>
<li #verification-method-security><span>{svg_checkmark}</span>{translate('Enable security password')}</li>
<li #verification-method-random><span>{svg_checkmark}</span>{translate('Enable random password')}</li>
return <li disabled={ method == 'use-permanent-password' ? "true" : "false" }>{translate("Set temporary password length")}
<menu #temporary-password-length>
<li #temporary-password-length-6><span>{svg_checkmark}</span>6</li>
<li #temporary-password-length-8><span>{svg_checkmark}</span>8</li>
<li #temporary-password-length-10><span>{svg_checkmark}</span>10</li>
</menu>
</li>;
}
function toggleMenuState() {
var security_enabled = handler.is_security_password_enabled();
var random_enabled = handler.is_random_password_enabled();
var onetime_enabled = handler.is_onetime_password_enabled();
for (var (index, el) in this.$$(menu#verification-method>li)) {
if (index == 0) el.attributes.toggleClass("selected", security_enabled);
if (index == 1) el.attributes.toggleClass("selected", random_enabled);
var length = handler.get_option("temporary-password-length");
var index = ['6', '8', '10'].indexOf(length);
if (index < 0) index = 0;
for (var (i, el) in this.$$(menu#temporary-password-length>li)) {
el.attributes.toggleClass("selected", i == index);
}
}
event click $(menu#verification-method>li) (_, me) {
switch (me.id.substring('verification-method-'.length)) {
case 'security':
{
var security_enabled = handler.is_security_password_enabled();
handler.set_security_password_enabled(!security_enabled);
}
break;
case 'random':
{
var random_enabled = handler.is_random_password_enabled();
handler.set_random_password_enabled(!random_enabled);
}
break;
event click $(menu#temporary-password-length>li) (_, me) {
var length = me.id.substring('temporary-password-length-'.length);
var old_length = handler.get_option('temporary-password-length');
if (length != old_length) {
handler.set_option('temporary-password-length', length);
handler.update_temporary_password();
this.toggleMenuState();
passwordArea.update();
}
this.toggleMenuState();
passwordArea.update();
}
}
var randomPasswordUpdateMethodMenu;
class RandomPasswordUpdateMethodMenu: Reactor.Component {
function this() {
randomPasswordUpdateMethodMenu = this;
}
function render() {
if (!this.show) return <li />;
var me = this;
var random_enabled = handler.is_random_password_enabled();
self.timer(1ms, function() { me.toggleMenuState() });
return <li disabled={ random_enabled ? "false" : "true" }>{translate('Random Password After Session')}
<menu #random-password-update-method>
<li #random-password-update-method-keep><span>{svg_checkmark}</span>{translate('Keep')}</li>
<li #random-password-update-method-update><span>{svg_checkmark}</span>{translate('Update')}</li>
<li #random-password-update-method-disable><span>{svg_checkmark}</span>{translate('Disable')}</li>
</menu>
</li>;
}
function toggleMenuState() {
var method = handler.random_password_update_method();
for (var (index, el) in this.$$(menu#random-password-update-method>li)) {
if (index == 0) el.attributes.toggleClass("selected", method == "KEEP");
if (index == 1) el.attributes.toggleClass("selected", method == "UPDATE");
if (index == 2) el.attributes.toggleClass("selected", method == "DISABLE");
}
}
event click $(menu#random-password-update-method>li) (_, me) {
if (me.id === 'random-password-update-method-keep') handler.set_random_password_update_method("KEEP");
if (me.id === 'random-password-update-method-update') handler.set_random_password_update_method("UPDATE");
if (me.id === 'random-password-update-method-disable') handler.set_random_password_update_method("DISABLE");
this.toggleMenuState();
passwordArea.update();
}
}
@ -911,11 +863,11 @@ class PasswordArea: Reactor.Component {
}
function render() {
var onetime_enabled = handler.is_onetime_password_enabled();
var me = this;
self.timer(1ms, function() { me.toggleMenuState() });
return
<div>
<div>{translate(onetime_enabled ? 'Onetime Password' : 'Password')}</div>
<div .your-desktop>
<div>{translate('Password')}</div>
<div .password style="flow:horizontal">
{this.renderPop()}
<PasswordEyeArea />
@ -925,35 +877,39 @@ class PasswordArea: Reactor.Component {
}
function renderPop() {
var security_enabled = handler.is_security_password_enabled();
var random_enabled = handler.is_random_password_enabled();
var onetime_enabled = handler.is_onetime_password_enabled();
var onetime_activated = handler.is_onetime_password_activated();
var method = handler.get_option('verification-method');
return <popup><menu.context #edit-password-context>
<li #enable-onetime-password disabled={ random_enabled ? "false" : "true" }>{translate(onetime_enabled ? "Disable onetime password" : "Enable onetime password")}</li>
<li #activate-onetime-password disabled={ !random_enabled || !onetime_enabled || onetime_activated ? "true" : "false" }>{translate('Activate onetime password')}</li>
<li #use-temporary-password><span>{svg_checkmark}</span>{translate('Use temporary password')}</li>
<li #use-permanent-password><span>{svg_checkmark}</span>{translate('Use permanent password')}</li>
<li #use-both-passwords><span>{svg_checkmark}</span>{translate('Use both passwords')}</li>
<div .separator />
<VerificationMethodMenu />
<div .separator />
<li #set-password disabled={ security_enabled ? "false" : "true" }>{translate('Set security password')}</li>
<div .separator />
<RandomPasswordUpdateMethodMenu />
<li #set-password disabled={ method == 'use-temporary-password' ? "true" : "false" }>{translate('Set permanent password')}</li>
<TemporaryPasswordLengthMenu />
</menu></popup>;
}
function toggleMenuState() {
var id = handler.get_option('verification-method');
if (id != 'use-temporary-password' && id != 'use-permanent-password')
id = 'use-both-passwords';
for (var el in [this.$(li#use-temporary-password), this.$(li#use-permanent-password), this.$(li#use-both-passwords)]) {
el.attributes.toggleClass("selected", el.id == id);
}
}
event click $(svg#edit) (_, me) {
randomPasswordUpdateMethodMenu.update({show: true });
verificationMethodMenu.update({show: true });
temporaryPasswordLengthMenu.update({show: true });
var menu = $(menu#edit-password-context);
me.popup(menu);
}
event click $(li#set-password) {
var me = this;
var password = handler.permanent_password();
var value_field = password.length == 0 ? "" : "value=" + password;
msgbox("custom-password", translate("Set Password"), "<div .form .set-password> \
<div><span>" + translate('Password') + ":</span><input|password(password) .outline-focus /></div> \
<div><span>" + translate('Confirmation') + ":</span><input|password(confirmation) /></div> \
<div><span>" + translate('Password') + ":</span><input|password(password) .outline-focus " + value_field + " /></div> \
<div><span>" + translate('Confirmation') + ":</span><input|password(confirmation) " + value_field + " /></div> \
</div> \
", function(res=null) {
if (!res) return;
@ -965,31 +921,40 @@ class PasswordArea: Reactor.Component {
if (p0 != p1) {
return translate("The confirmation is not identical.");
}
handler.set_security_password(p0);
handler.set_permanent_password(p0);
me.update();
});
}
event click $(li#enable-onetime-password) {
var onetime_enabled = handler.is_onetime_password_enabled();
handler.set_onetime_password_enabled(!onetime_enabled);
passwordArea.update();
}
event click $(li#activate-onetime-password) {
handler.set_onetime_password_activated(true);
passwordArea.update();
event click $(menu#edit-password-context>li) (_, me) {
if (me.id.indexOf('use-') == 0) {
handler.set_option('verification-method', me.id);
this.toggleMenuState();
passwordArea.update();
}
}
}
var last_password_description = "";
var password_cache = ["","",""];
function updatePasswordArea() {
self.timer(1s, function() {
var description = handler.password_description();
if (last_password_description != description) {
last_password_description = description
passwordArea.update();
var temporary_password = handler.temporary_password();
var verification_method = handler.get_option('verification-method');
var temporary_password_length = handler.get_option('temporary-password-length');
var update = false;
if (password_cache[0] != temporary_password) {
password_cache[0] = temporary_password;
update = true;
}
if (password_cache[1] != verification_method) {
password_cache[1] = verification_method;
update = true;
}
if (password_cache[2] != temporary_password_length) {
password_cache[2] = temporary_password_length;
update = true;
}
if (update) passwordArea.update();
updatePasswordArea();
});
}