show fingerprint
Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
parent
08c4d2a1cf
commit
1100b2a465
@ -797,6 +797,7 @@ void showToast(String text, {Duration timeout = const Duration(seconds: 2)}) {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 5),
|
||||
child: Text(
|
||||
text,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
decoration: TextDecoration.none,
|
||||
fontWeight: FontWeight.w300,
|
||||
@ -1601,7 +1602,8 @@ bool callUniLinksUriHandler(Uri uri) {
|
||||
String? switch_uuid = param["switch_uuid"];
|
||||
String? password = param["password"];
|
||||
Future.delayed(Duration.zero, () {
|
||||
rustDeskWinManager.newRemoteDesktop(peerId, password: password, switch_uuid: switch_uuid);
|
||||
rustDeskWinManager.newRemoteDesktop(peerId,
|
||||
password: password, switch_uuid: switch_uuid);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
@ -2033,3 +2035,12 @@ Widget futureBuilder(
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void onCopyFingerprint(String value) {
|
||||
if (value.isNotEmpty) {
|
||||
Clipboard.setData(ClipboardData(text: value));
|
||||
showToast('$value\n${translate("Copied")}');
|
||||
} else {
|
||||
showToast(translate("no fingerprints"));
|
||||
}
|
||||
}
|
||||
|
@ -121,6 +121,29 @@ class ConnectionTypeState {
|
||||
Get.find<ConnectionType>(tag: tag(id));
|
||||
}
|
||||
|
||||
class FingerprintState {
|
||||
static String tag(String id) => 'fingerprint_$id';
|
||||
|
||||
static void init(String id) {
|
||||
final key = tag(id);
|
||||
if (!Get.isRegistered(tag: key)) {
|
||||
final RxString state = ''.obs;
|
||||
Get.put(state, tag: key);
|
||||
} else {
|
||||
Get.find<RxString>(tag: key).value = '';
|
||||
}
|
||||
}
|
||||
|
||||
static void delete(String id) {
|
||||
final key = tag(id);
|
||||
if (Get.isRegistered(tag: key)) {
|
||||
Get.delete(tag: key);
|
||||
}
|
||||
}
|
||||
|
||||
static RxString find(String id) => Get.find<RxString>(tag: tag(id));
|
||||
}
|
||||
|
||||
class ShowRemoteCursorState {
|
||||
static String tag(String id) => 'show_remote_cursor_$id';
|
||||
|
||||
@ -269,6 +292,7 @@ initSharedStates(String id) {
|
||||
KeyboardEnabledState.init(id);
|
||||
ShowRemoteCursorState.init(id);
|
||||
RemoteCursorMovedState.init(id);
|
||||
FingerprintState.init(id);
|
||||
PeerBoolOption.init(id, 'zoom-cursor', () => false);
|
||||
}
|
||||
|
||||
@ -279,5 +303,6 @@ removeSharedStates(String id) {
|
||||
ShowRemoteCursorState.delete(id);
|
||||
KeyboardEnabledState.delete(id);
|
||||
RemoteCursorMovedState.delete(id);
|
||||
FingerprintState.delete(id);
|
||||
PeerBoolOption.delete(id, 'zoom-cursor');
|
||||
}
|
||||
|
@ -201,6 +201,13 @@ List<TTextMenu> toolbarControls(BuildContext context, String id, FFI ffi) {
|
||||
),
|
||||
onPressed: () => ffi.recordingModel.toggle()));
|
||||
}
|
||||
// fingerprint
|
||||
if (!isDesktop) {
|
||||
v.add(TTextMenu(
|
||||
child: Text(translate('Copy Fingerprint')),
|
||||
onPressed: () => onCopyFingerprint(FingerprintState.find(id).value),
|
||||
));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
|
@ -1390,11 +1390,18 @@ class _AboutState extends State<_About> {
|
||||
final license = await bind.mainGetLicense();
|
||||
final version = await bind.mainGetVersion();
|
||||
final buildDate = await bind.mainGetBuildDate();
|
||||
return {'license': license, 'version': version, 'buildDate': buildDate};
|
||||
final fingerprint = await bind.mainGetFingerprint();
|
||||
return {
|
||||
'license': license,
|
||||
'version': version,
|
||||
'buildDate': buildDate,
|
||||
'fingerprint': fingerprint
|
||||
};
|
||||
}(), hasData: (data) {
|
||||
final license = data['license'].toString();
|
||||
final version = data['version'].toString();
|
||||
final buildDate = data['buildDate'].toString();
|
||||
final fingerprint = data['fingerprint'].toString();
|
||||
const linkStyle = TextStyle(decoration: TextDecoration.underline);
|
||||
final scrollController = ScrollController();
|
||||
return DesktopScrollWrapper(
|
||||
@ -1415,6 +1422,9 @@ class _AboutState extends State<_About> {
|
||||
SelectionArea(
|
||||
child: Text('${translate('Build Date')}: $buildDate')
|
||||
.marginSymmetric(vertical: 4.0)),
|
||||
SelectionArea(
|
||||
child: Text('${translate('Fingerprint')}: $fingerprint')
|
||||
.marginSymmetric(vertical: 4.0)),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
launchUrlString('https://rustdesk.com/privacy');
|
||||
|
@ -4,6 +4,7 @@ import 'dart:ui' as ui;
|
||||
|
||||
import 'package:desktop_multi_window/desktop_multi_window.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_hbb/common.dart';
|
||||
import 'package:flutter_hbb/common/shared_state.dart';
|
||||
import 'package:flutter_hbb/consts.dart';
|
||||
@ -158,20 +159,36 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
||||
],
|
||||
);
|
||||
} else {
|
||||
final msgDirect = translate(
|
||||
connectionType.direct.value == ConnectionType.strDirect
|
||||
? 'Direct Connection'
|
||||
: 'Relay Connection');
|
||||
final msgSecure = translate(
|
||||
connectionType.secure.value == ConnectionType.strSecure
|
||||
? 'Secure Connection'
|
||||
: 'Insecure Connection');
|
||||
bool secure =
|
||||
connectionType.secure.value == ConnectionType.strSecure;
|
||||
bool direct =
|
||||
connectionType.direct.value == ConnectionType.strDirect;
|
||||
var msgConn;
|
||||
if (secure && direct) {
|
||||
msgConn = translate("Direct and encrypted connection");
|
||||
} else if (secure && !direct) {
|
||||
msgConn = translate("Relayed and encrypted connection");
|
||||
} else if (!secure && direct) {
|
||||
msgConn = translate("Direct and unencrypted connection");
|
||||
} else {
|
||||
msgConn = translate("Relayed and unencrypted connection");
|
||||
}
|
||||
var msgFingerprint = '${translate('Fingerprint')}:\n';
|
||||
var fingerprint = FingerprintState.find(key).value;
|
||||
if (fingerprint.length > 5 * 8) {
|
||||
var first = fingerprint.substring(0, 39);
|
||||
var second = fingerprint.substring(40);
|
||||
msgFingerprint += '$first\n$second';
|
||||
} else {
|
||||
msgFingerprint += fingerprint;
|
||||
}
|
||||
|
||||
final tab = Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
icon,
|
||||
Tooltip(
|
||||
message: '$msgDirect\n$msgSecure',
|
||||
message: '$msgConn\n$msgFingerprint',
|
||||
child: SvgPicture.asset(
|
||||
'assets/${connectionType.secure.value}${connectionType.direct.value}.svg',
|
||||
width: themeConf.iconSize,
|
||||
@ -285,6 +302,17 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
||||
}
|
||||
}
|
||||
|
||||
menu.add(MenuEntryButton<String>(
|
||||
childBuilder: (TextStyle? style) => Text(
|
||||
translate('Copy Fingerprint'),
|
||||
style: style,
|
||||
),
|
||||
proc: () => onCopyFingerprint(FingerprintState.find(key).value),
|
||||
padding: padding,
|
||||
dismissOnClicked: true,
|
||||
dismissCallback: cancelFunc,
|
||||
));
|
||||
|
||||
return mod_menu.PopupMenu<String>(
|
||||
items: menu
|
||||
.map((entry) => entry.build(
|
||||
|
@ -2,6 +2,7 @@ import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:settings_ui/settings_ui.dart';
|
||||
@ -45,6 +46,7 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
||||
var _autoRecordIncomingSession = false;
|
||||
var _localIP = "";
|
||||
var _directAccessPort = "";
|
||||
var _fingerprint = "";
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -135,6 +137,12 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
||||
_directAccessPort = directAccessPort;
|
||||
}
|
||||
|
||||
final fingerprint = await bind.mainGetFingerprint();
|
||||
if (_fingerprint != fingerprint) {
|
||||
update = true;
|
||||
_fingerprint = fingerprint;
|
||||
}
|
||||
|
||||
if (update) {
|
||||
setState(() {});
|
||||
}
|
||||
@ -462,6 +470,14 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
||||
)),
|
||||
),
|
||||
leading: Icon(Icons.info)),
|
||||
SettingsTile.navigation(
|
||||
onPressed: (context) => onCopyFingerprint(_fingerprint),
|
||||
title: Text(translate("Fingerprint")),
|
||||
value: Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 8),
|
||||
child: Text(_fingerprint),
|
||||
),
|
||||
leading: Icon(Icons.fingerprint)),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
@ -224,6 +224,8 @@ class FfiModel with ChangeNotifier {
|
||||
parent.target?.chatModel.onVoiceCallIncoming();
|
||||
} else if (name == "update_voice_call_state") {
|
||||
parent.target?.serverModel.updateVoiceCallState(evt);
|
||||
} else if (name == "fingerprint") {
|
||||
FingerprintState.find(peerId).value = evt['fingerprint'] ?? '';
|
||||
} else {
|
||||
debugPrint("Unknown event name: $name");
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ impl Client {
|
||||
token: &str,
|
||||
conn_type: ConnType,
|
||||
interface: impl Interface,
|
||||
) -> ResultType<(Stream, bool)> {
|
||||
) -> ResultType<(Stream, bool, Option<Vec<u8>>)> {
|
||||
match Self::_start(peer, key, token, conn_type, interface).await {
|
||||
Err(err) => {
|
||||
let err_str = err.to_string();
|
||||
@ -221,7 +221,7 @@ impl Client {
|
||||
token: &str,
|
||||
conn_type: ConnType,
|
||||
interface: impl Interface,
|
||||
) -> ResultType<(Stream, bool)> {
|
||||
) -> ResultType<(Stream, bool, Option<Vec<u8>>)> {
|
||||
// to-do: remember the port for each peer, so that we can retry easier
|
||||
if hbb_common::is_ip_str(peer) {
|
||||
return Ok((
|
||||
@ -231,6 +231,7 @@ impl Client {
|
||||
)
|
||||
.await?,
|
||||
true,
|
||||
None,
|
||||
));
|
||||
}
|
||||
// Allow connect to {domain}:{port}
|
||||
@ -238,6 +239,7 @@ impl Client {
|
||||
return Ok((
|
||||
socket_client::connect_tcp(peer, RENDEZVOUS_TIMEOUT).await?,
|
||||
true,
|
||||
None,
|
||||
));
|
||||
}
|
||||
let (mut rendezvous_server, servers, contained) = crate::get_rendezvous_server(1_000).await;
|
||||
@ -333,7 +335,7 @@ impl Client {
|
||||
my_addr.is_ipv4(),
|
||||
)
|
||||
.await?;
|
||||
Self::secure_connection(
|
||||
let pk = Self::secure_connection(
|
||||
peer,
|
||||
signed_id_pk,
|
||||
key,
|
||||
@ -342,7 +344,7 @@ impl Client {
|
||||
interface,
|
||||
)
|
||||
.await?;
|
||||
return Ok((conn, false));
|
||||
return Ok((conn, false, pk));
|
||||
}
|
||||
_ => {
|
||||
log::error!("Unexpected protobuf msg received: {:?}", msg_in);
|
||||
@ -403,7 +405,7 @@ impl Client {
|
||||
token: &str,
|
||||
conn_type: ConnType,
|
||||
interface: impl Interface,
|
||||
) -> ResultType<(Stream, bool)> {
|
||||
) -> ResultType<(Stream, bool, Option<Vec<u8>>)> {
|
||||
let direct_failures = PeerConfig::load(peer_id).direct_failures;
|
||||
let mut connect_timeout = 0;
|
||||
const MIN: u64 = 1000;
|
||||
@ -473,8 +475,9 @@ impl Client {
|
||||
}
|
||||
let mut conn = conn?;
|
||||
log::info!("{:?} used to establish connection", start.elapsed());
|
||||
Self::secure_connection(peer_id, signed_id_pk, key, &mut conn, direct, interface).await?;
|
||||
Ok((conn, direct))
|
||||
let pk = Self::secure_connection(peer_id, signed_id_pk, key, &mut conn, direct, interface)
|
||||
.await?;
|
||||
Ok((conn, direct, pk))
|
||||
}
|
||||
|
||||
/// Establish secure connection with the server.
|
||||
@ -485,17 +488,19 @@ impl Client {
|
||||
conn: &mut Stream,
|
||||
direct: bool,
|
||||
interface: impl Interface,
|
||||
) -> ResultType<()> {
|
||||
) -> ResultType<Option<Vec<u8>>> {
|
||||
let rs_pk = get_rs_pk(if key.is_empty() {
|
||||
hbb_common::config::RS_PUB_KEY
|
||||
} else {
|
||||
key
|
||||
});
|
||||
let mut sign_pk = None;
|
||||
let mut option_pk = None;
|
||||
if !signed_id_pk.is_empty() && rs_pk.is_some() {
|
||||
if let Ok((id, pk)) = decode_id_pk(&signed_id_pk, &rs_pk.unwrap()) {
|
||||
if id == peer_id {
|
||||
sign_pk = Some(sign::PublicKey(pk));
|
||||
option_pk = Some(pk.to_vec());
|
||||
}
|
||||
}
|
||||
if sign_pk.is_none() {
|
||||
@ -507,7 +512,7 @@ impl Client {
|
||||
None => {
|
||||
// send an empty message out in case server is setting up secure and waiting for first message
|
||||
conn.send(&Message::new()).await?;
|
||||
return Ok(());
|
||||
return Ok(option_pk);
|
||||
}
|
||||
};
|
||||
match timeout(READ_TIMEOUT, conn.next()).await? {
|
||||
@ -560,7 +565,7 @@ impl Client {
|
||||
bail!("Reset by the peer");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
Ok(option_pk)
|
||||
}
|
||||
|
||||
/// Request a relay connection to the server.
|
||||
|
@ -121,9 +121,11 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok((mut peer, direct)) => {
|
||||
Ok((mut peer, direct, pk)) => {
|
||||
self.handler.set_connection_type(peer.is_secured(), direct); // flutter -> connection_ready
|
||||
self.handler.set_connection_info(direct, false);
|
||||
self.handler
|
||||
.set_fingerprint(crate::common::pk_to_fingerprint(pk.unwrap_or_default()));
|
||||
|
||||
// just build for now
|
||||
#[cfg(not(windows))]
|
||||
|
@ -840,3 +840,17 @@ pub fn is_peer_version_ge(v: &str) -> bool {
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
pub fn pk_to_fingerprint(pk: Vec<u8>) -> String {
|
||||
let s: String = pk.iter().map(|u| format!("{:02x}", u)).collect();
|
||||
s.chars()
|
||||
.enumerate()
|
||||
.map(|(i, c)| {
|
||||
if i > 0 && i % 4 == 0 {
|
||||
format!(" {}", c)
|
||||
} else {
|
||||
format!("{}", c)
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
@ -395,6 +395,10 @@ impl InvokeUiSession for FlutterHandler {
|
||||
);
|
||||
}
|
||||
|
||||
fn set_fingerprint(&self, fingerprint: String) {
|
||||
self.push_event("fingerprint", vec![("fingerprint", &fingerprint)]);
|
||||
}
|
||||
|
||||
fn job_error(&self, id: i32, err: String, file_num: i32) {
|
||||
self.push_event(
|
||||
"job_error",
|
||||
|
@ -921,6 +921,10 @@ pub fn main_get_permanent_password() -> String {
|
||||
ui_interface::permanent_password()
|
||||
}
|
||||
|
||||
pub fn main_get_fingerprint() -> String {
|
||||
get_fingerprint()
|
||||
}
|
||||
|
||||
pub fn main_get_online_statue() -> i64 {
|
||||
ONLINE.lock().unwrap().values().max().unwrap_or(&0).clone()
|
||||
}
|
||||
|
12
src/ipc.rs
12
src/ipc.rs
@ -383,6 +383,12 @@ async fn handle(data: Data, stream: &mut Connection) {
|
||||
));
|
||||
} else if name == "rendezvous_servers" {
|
||||
value = Some(Config::get_rendezvous_servers().join(","));
|
||||
} else if name == "fingerprint" {
|
||||
value = if Config::get_key_confirmed() {
|
||||
Some(crate::common::pk_to_fingerprint(Config::get_key_pair().1))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
} else {
|
||||
value = None;
|
||||
}
|
||||
@ -690,6 +696,12 @@ pub fn get_permanent_password() -> String {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_fingerprint() -> String {
|
||||
get_config("fingerprint")
|
||||
.unwrap_or_default()
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn set_permanent_password(v: String) -> ResultType<()> {
|
||||
Config::set_permanent_password(&v);
|
||||
set_config("permanent-password", v)
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", "desktop 未安装"),
|
||||
("no_desktop_text_tip", "请安装 desktop"),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", "指纹"),
|
||||
("Copy Fingerprint", "复制指纹"),
|
||||
("no fingerprints", "没有指纹"),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,7 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", "Es ist kein Desktop verfügbar."),
|
||||
("no_desktop_text_tip", "Bitte installieren Sie den GNOME-Desktop."),
|
||||
("No need to elevate", "Erhöhung der Rechte nicht erforderlich"),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", "Neue RDP-Verbindung"),
|
||||
("Failed to listen on {}: {}", "Lauschen fehlgeschlagen auf Port {}: {}"),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", "No hay escritorio disponible"),
|
||||
("no_desktop_text_tip", "Por favor, instala GNOME Desktop"),
|
||||
("No need to elevate", "No es necesario elevar privilegios"),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", "Nuevo RDP"),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", "هیچ دسکتاپی در دسترس نیست"),
|
||||
("no_desktop_text_tip", "لطفا دسکتاپ گنوم را نصب کنید"),
|
||||
("No need to elevate", "نیازی به ارتقاء نیست"),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", "ریموت جدید"),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -495,5 +495,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("System Sound", "Dispositivo audio sistema"),
|
||||
("Default", "Predefinita"),
|
||||
("New RDP", "Nuovo RDP"),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", "Nėra pasiekiamų nuotolinių darbalaukių"),
|
||||
("no_desktop_text_tip", "Prašom įdiegti GNOME Desktop"),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -495,5 +495,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("System Sound", "Dźwięk Systemowy"),
|
||||
("Default", "Domyślne"),
|
||||
("New RDP", "Nowe RDP"),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", "Нет доступных рабочих столов"),
|
||||
("no_desktop_text_tip", "Установите GNOME Desktop"),
|
||||
("No need to elevate", "Повышение прав не требуется"),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -495,5 +495,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", "沒有可用的桌面"),
|
||||
("no_desktop_text_tip", "請安裝 GNOME 桌面"),
|
||||
("No need to elevate", "不需要提升權限"),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", "新的 RDP"),
|
||||
("Fingerprint", "指紋"),
|
||||
("Copy Fingerprint", "複製指紋"),
|
||||
("no fingerprints", "沒有指紋"),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -492,6 +492,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("no_desktop_title_tip", ""),
|
||||
("no_desktop_text_tip", ""),
|
||||
("No need to elevate", ""),
|
||||
("System Sound", ""),
|
||||
("Default", ""),
|
||||
("New RDP", ""),
|
||||
("Fingerprint", ""),
|
||||
("Copy Fingerprint", ""),
|
||||
("no fingerprints", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -154,7 +154,8 @@ async fn connect_and_login_2(
|
||||
} else {
|
||||
ConnType::PORT_FORWARD
|
||||
};
|
||||
let (mut stream, direct) = Client::start(id, key, token, conn_type, interface.clone()).await?;
|
||||
let (mut stream, direct, _pk) =
|
||||
Client::start(id, key, token, conn_type, interface.clone()).await?;
|
||||
let mut interface = interface;
|
||||
let mut buffer = Vec::new();
|
||||
let mut received = false;
|
||||
|
@ -470,6 +470,10 @@ impl UI {
|
||||
get_version()
|
||||
}
|
||||
|
||||
fn get_fingerprint(&self) -> String {
|
||||
get_fingerprint()
|
||||
}
|
||||
|
||||
fn get_app_name(&self) -> String {
|
||||
get_app_name()
|
||||
}
|
||||
@ -649,6 +653,7 @@ impl sciter::EventHandler for UI {
|
||||
fn get_software_update_url();
|
||||
fn get_new_version();
|
||||
fn get_version();
|
||||
fn get_fingerprint();
|
||||
fn update_me(String);
|
||||
fn show_run_without_install();
|
||||
fn run_without_install();
|
||||
|
@ -364,6 +364,7 @@ class MyIdMenu: Reactor.Component {
|
||||
var name = handler.get_app_name();
|
||||
msgbox("custom-nocancel-nook-hasclose", translate("About") + " " + name, "<div style='line-height: 2em'> \
|
||||
<div>Version: " + handler.get_version() + " \
|
||||
<div>Fingerprint: " + handler.get_fingerprint() + " \
|
||||
<div .link .custom-event url='https://rustdesk.com/privacy'>Privacy Statement</div> \
|
||||
<div .link .custom-event url='https://rustdesk.com'>Website</div> \
|
||||
<div style='background: #2c8cff; color: white; padding: 1em; margin-top: 1em;'>Copyright © 2022 Purslane Ltd.\
|
||||
|
@ -144,6 +144,8 @@ impl InvokeUiSession for SciterHandler {
|
||||
self.call("setConnectionType", &make_args!(is_secured, direct));
|
||||
}
|
||||
|
||||
fn set_fingerprint(&self, _fingerprint: String) {}
|
||||
|
||||
fn job_error(&self, id: i32, err: String, file_num: i32) {
|
||||
self.call("jobError", &make_args!(id, err, file_num));
|
||||
}
|
||||
|
@ -24,13 +24,12 @@ use hbb_common::{
|
||||
rendezvous_proto::*,
|
||||
};
|
||||
|
||||
use crate::common::SOFTWARE_UPDATE_URL;
|
||||
#[cfg(feature = "flutter")]
|
||||
use crate::hbbs_http::account;
|
||||
use crate::{common::SOFTWARE_UPDATE_URL};
|
||||
#[cfg(not(any(target_os = "ios")))]
|
||||
use crate::ipc;
|
||||
|
||||
|
||||
type Message = RendezvousMessage;
|
||||
|
||||
pub type Children = Arc<Mutex<(bool, HashMap<(String, String), Child>)>>;
|
||||
@ -515,8 +514,7 @@ pub fn get_error() -> String {
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
let dtype = crate::platform::linux::get_display_server();
|
||||
if crate::platform::linux::DISPLAY_SERVER_WAYLAND == dtype
|
||||
{
|
||||
if crate::platform::linux::DISPLAY_SERVER_WAYLAND == dtype {
|
||||
return crate::server::wayland::common_get_error();
|
||||
}
|
||||
if dtype != crate::platform::linux::DISPLAY_SERVER_X11 {
|
||||
@ -852,6 +850,17 @@ pub fn get_user_default_option(key: String) -> String {
|
||||
UserDefaultConfig::load().get(&key)
|
||||
}
|
||||
|
||||
pub fn get_fingerprint() -> String {
|
||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||
if Config::get_key_confirmed() {
|
||||
return crate::common::pk_to_fingerprint(Config::get_key_pair().1);
|
||||
} else {
|
||||
return "".to_owned();
|
||||
}
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
return ipc::get_fingerprint();
|
||||
}
|
||||
|
||||
// notice: avoiding create ipc connection repeatedly,
|
||||
// because windows named pipe has serious memory leak issue.
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
|
@ -889,6 +889,7 @@ pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default {
|
||||
fn close_success(&self);
|
||||
fn update_quality_status(&self, qs: QualityStatus);
|
||||
fn set_connection_type(&self, is_secured: bool, direct: bool);
|
||||
fn set_fingerprint(&self, fingerprint: String);
|
||||
fn job_error(&self, id: i32, err: String, file_num: i32);
|
||||
fn job_done(&self, id: i32, file_num: i32);
|
||||
fn clear_all_jobs(&self);
|
||||
|
Loading…
x
Reference in New Issue
Block a user