lic.rs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. use hbb_common::{bail, log, ResultType};
  2. use serde_derive::{Deserialize, Serialize};
  3. use std::io::prelude::*;
  4. use std::path::Path;
  5. #[derive(Debug, PartialEq, Default, Serialize, Deserialize, Clone)]
  6. pub struct Machine {
  7. #[serde(default)]
  8. hostname: String,
  9. #[serde(default)]
  10. uid: String,
  11. #[serde(default)]
  12. mac: String,
  13. }
  14. #[derive(Debug, PartialEq, Default, Serialize, Deserialize, Clone)]
  15. pub struct Post {
  16. #[serde(default)]
  17. machine: String,
  18. #[serde(default)]
  19. email: String,
  20. #[serde(default)]
  21. status: String,
  22. #[serde(default)]
  23. version: String,
  24. #[serde(default)]
  25. next_check_time: u32,
  26. }
  27. const LICENSE_FILE: &'static str = ".license.txt";
  28. pub fn check_lic(email: &str, version: &str) -> bool {
  29. if email.is_empty() {
  30. log::error!("Registered email required (-m option). Please visit https://rustdesk.com/server for more infomration.");
  31. return false;
  32. }
  33. let machine = get_lic();
  34. let path = Path::new(LICENSE_FILE);
  35. if Path::is_file(&path) {
  36. let contents = std::fs::read_to_string(&path).unwrap_or("".to_owned());
  37. if verify(&contents, &machine) {
  38. return true;
  39. }
  40. }
  41. match check_email(machine, email.to_owned(), version.to_owned()) {
  42. Ok(v) => {
  43. return true;
  44. }
  45. Err(err) => {
  46. log::error!("{}", err);
  47. return false;
  48. }
  49. }
  50. }
  51. fn write_lic(lic: &str) {
  52. if let Ok(mut f) = std::fs::File::create(LICENSE_FILE) {
  53. f.write_all(lic.as_bytes()).ok();
  54. f.sync_all().ok();
  55. }
  56. }
  57. fn check_email(machine: String, email: String, version: String) -> ResultType<u32> {
  58. log::info!("Checking email with the server ...");
  59. let resp = minreq::post("http://rustdesk.com/api/check-email")
  60. .with_body(
  61. serde_json::to_string(&Post {
  62. machine: machine.clone(),
  63. version,
  64. email,
  65. ..Default::default()
  66. })
  67. .unwrap(),
  68. )
  69. .send()?;
  70. if resp.reason_phrase == "OK" {
  71. let p: Post = serde_json::from_str(&resp.as_str()?)?;
  72. if !p.status.is_empty() {
  73. bail!("{}", p.status);
  74. }
  75. if !verify(&p.machine, &machine) {
  76. bail!("Verification failure");
  77. }
  78. write_lic(&p.machine);
  79. Ok(p.next_check_time)
  80. } else {
  81. bail!("Server error: {}", resp.reason_phrase);
  82. }
  83. }
  84. fn get_lic() -> String {
  85. let hostname = whoami::hostname();
  86. let uid = machine_uid::get().unwrap_or("".to_owned());
  87. let mac = if let Ok(Some(ma)) = mac_address::get_mac_address() {
  88. base64::encode(ma.bytes())
  89. } else {
  90. "".to_owned()
  91. };
  92. serde_json::to_string(&Machine { hostname, uid, mac }).unwrap()
  93. }
  94. fn verify(enc_str: &str, msg: &str) -> bool {
  95. if let Ok(data) = base64::decode(enc_str) {
  96. let key =
  97. b"\xf1T\xc0\x1c\xffee\x86,S*\xd9.\x91\xcd\x85\x12:\xec\xa9 \x99:\x8a\xa2S\x1f Yy\x93R";
  98. cryptoxide::ed25519::verify(msg.as_bytes(), &key[..], &data)
  99. } else {
  100. false
  101. }
  102. }
  103. pub const EMAIL_ARG: &'static str =
  104. "-m, --email=[EMAIL] 'Sets your email address registered with RustDesk'";