| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- use clap::App;
- use hbb_common::{anyhow::Context, log, ResultType};
- use ini::Ini;
- use sodiumoxide::crypto::sign;
- use std::{
- io::prelude::*,
- io::Read,
- net::SocketAddr,
- time::{Instant, SystemTime},
- };
- pub(crate) fn get_expired_time() -> Instant {
- let now = Instant::now();
- now.checked_sub(std::time::Duration::from_secs(3600))
- .unwrap_or(now)
- }
- pub(crate) fn test_if_valid_server(host: &str, name: &str) -> ResultType<SocketAddr> {
- use std::net::ToSocketAddrs;
- let res = if host.contains(":") {
- host.to_socket_addrs()?.next().context("")
- } else {
- format!("{}:{}", host, 0)
- .to_socket_addrs()?
- .next()
- .context("")
- };
- if res.is_err() {
- log::error!("Invalid {} {}: {:?}", name, host, res);
- }
- res
- }
- pub(crate) fn get_servers(s: &str, tag: &str) -> Vec<String> {
- let servers: Vec<String> = s
- .split(",")
- .filter(|x| !x.is_empty() && test_if_valid_server(x, tag).is_ok())
- .map(|x| x.to_owned())
- .collect();
- log::info!("{}={:?}", tag, servers);
- servers
- }
- #[inline]
- fn arg_name(name: &str) -> String {
- name.to_uppercase().replace("_", "-")
- }
- pub fn init_args(args: &str, name: &str, about: &str) {
- let matches = App::new(name)
- .version(crate::version::VERSION)
- .author("Purslane Ltd. <info@rustdesk.com>")
- .about(about)
- .args_from_usage(&args)
- .get_matches();
- if let Ok(v) = Ini::load_from_file(".env") {
- if let Some(section) = v.section(None::<String>) {
- section
- .iter()
- .for_each(|(k, v)| std::env::set_var(arg_name(k), v));
- }
- }
- if let Some(config) = matches.value_of("config") {
- if let Ok(v) = Ini::load_from_file(config) {
- if let Some(section) = v.section(None::<String>) {
- section
- .iter()
- .for_each(|(k, v)| std::env::set_var(arg_name(k), v));
- }
- }
- }
- for (k, v) in matches.args {
- if let Some(v) = v.vals.get(0) {
- std::env::set_var(arg_name(k), v.to_string_lossy().to_string());
- }
- }
- }
- #[inline]
- pub fn get_arg(name: &str) -> String {
- get_arg_or(name, "".to_owned())
- }
- #[inline]
- pub fn get_arg_or(name: &str, default: String) -> String {
- std::env::var(arg_name(name)).unwrap_or(default)
- }
- #[inline]
- pub fn now() -> u64 {
- SystemTime::now()
- .duration_since(SystemTime::UNIX_EPOCH)
- .map(|x| x.as_secs())
- .unwrap_or_default()
- }
- pub fn gen_sk(wait: u64) -> (String, Option<sign::SecretKey>) {
- let sk_file = "id_ed25519";
- if wait > 0 && !std::path::Path::new(sk_file).exists() {
- std::thread::sleep(std::time::Duration::from_millis(wait));
- }
- if let Ok(mut file) = std::fs::File::open(sk_file) {
- let mut contents = String::new();
- if file.read_to_string(&mut contents).is_ok() {
- let sk = base64::decode(&contents).unwrap_or_default();
- if sk.len() == sign::SECRETKEYBYTES {
- let mut tmp = [0u8; sign::SECRETKEYBYTES];
- tmp[..].copy_from_slice(&sk);
- let pk = base64::encode(&tmp[sign::SECRETKEYBYTES / 2..]);
- log::info!("Private key comes from {}", sk_file);
- return (pk, Some(sign::SecretKey(tmp)));
- }
- }
- } else {
- let gen_func = || {
- let (tmp, sk) = sign::gen_keypair();
- (base64::encode(tmp), sk)
- };
- let (mut pk, mut sk) = gen_func();
- for _ in 0..300 {
- if !pk.contains("/") && !pk.contains(":") {
- break;
- }
- (pk, sk) = gen_func();
- }
- let pub_file = format!("{}.pub", sk_file);
- if let Ok(mut f) = std::fs::File::create(&pub_file) {
- f.write_all(pk.as_bytes()).ok();
- if let Ok(mut f) = std::fs::File::create(sk_file) {
- let s = base64::encode(&sk);
- if f.write_all(s.as_bytes()).is_ok() {
- log::info!("Private/public key written to {}/{}", sk_file, pub_file);
- log::debug!("Public key: {}", pk);
- return (pk, Some(sk));
- }
- }
- }
- }
- ("".to_owned(), None)
- }
|