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