1use base16::decode;
15use debugoff::multi_ptraceme_or_die;
16use goldberg::goldberg_stmts;
17use hmac_sha256::HMAC;
18use httparse::Header;
19use reqwest::header::HeaderMap;
20use reqwest::Client;
21use reqwest::Response;
22use std::collections::HashMap;
23use std::io::Read;
24use std::net::TcpListener;
25use uuid::Uuid;
26
27macro_rules! nodebug {
28 () => {
29 #[cfg(target_os = "linux")]
30 #[cfg(not(debug_assertions))]
31 multi_ptraceme_or_die();
32 };
33}
34
35pub struct Res<T>(Result<T, String>);
36
37impl Default for Res<()> {
38 fn default() -> Self {
39 Res(Err("Default Error".to_string()))
40 }
41}
42
43impl<T> Res<T> {
44 pub fn inner(self) -> Result<T, String> {
45 self.0
46 }
47}
48
49impl<T: Clone> Res<T> {
50 pub fn clone_inner(&self) -> Result<T, String> {
51 self.0.clone()
52 }
53}
54
55struct Resp {
56 res: String,
57 head: HeaderMap,
58}
59
60impl Default for Resp {
61 fn default() -> Self {
62 Resp {
63 res: "Default Resp Error".to_string(),
64 head: HeaderMap::new(),
65 }
66 }
67}
68
69struct Data(String);
70
71impl Data {
72 fn insert<T: ToString, G: ToString>(&mut self, key: T, val: G) {
73 self.0
74 .push_str(&format!("{}={}&", key.to_string(), val.to_string()));
75 }
76}
77
78fn copy_string(bytes: &[u8]) -> String {
79 let bytes: Vec<u8> = bytes.to_vec();
80 let bytes = bytes.clone();
81 let mut string = String::new();
82 for byte in bytes {
83 string.push(byte as char);
84 }
85 string
86}
87
88#[derive(Default, Clone)]
90pub struct KeyauthApi {
91 name: String,
92 owner_id: String,
93 secret: String,
94 version: String,
95 enckey: String,
96 enckey_s: String,
97 session_id: String,
98 pub api_url: String,
99 pub num_keys: String,
100 pub num_online_users: String,
101 pub num_users: String,
102 pub app_version: String,
103 pub customer_panel_link: String,
104 pub username: String,
105 pub ip: String,
106 pub hwid: String,
107 pub create_date: String,
108 pub last_login: String,
109 pub subscription: String,
110 pub message: String,
111 pub success: bool,
112 pub blacklisted: bool,
113 pub response: String,
114}
115
116impl KeyauthApi {
117 pub fn new(name: &str, owner_id: &str, secret: &str, version: &str, api_url: &str) -> Self {
119 let res: Self = goldberg_stmts! {{
120 nodebug!();
121 Self {
122 name: name.to_string(),
123 owner_id: owner_id.to_string(),
124 secret: secret.to_string(),
125 version: version.to_string(),
126 enckey: String::new(),
127 enckey_s: String::new(),
128 session_id: String::new(),
129 num_keys: String::new(),
130 api_url: api_url.to_string(),
131 num_online_users: String::new(),
132 num_users: String::new(),
133 app_version: version.to_string(),
134 customer_panel_link: String::new(),
135 username: String::new(),
136 ip: String::new(),
137 hwid: machine_uuid::get(),
138 create_date: String::new(),
139 last_login: String::new(),
140 subscription: String::new(),
141 message: String::new(),
142 success: false,
143 blacklisted: false,
144 response: String::new(),
145 }}};
146 res
147 }
148
149 pub async fn init(&mut self, hash: Option<&str>) -> Res<()> {
151 let res = goldberg_stmts! {{
152 nodebug!();
153 self.enckey = Uuid::new_v4().simple().to_string();
154 self.enckey_s = format!("{}-{}", self.enckey, self.secret);
155 let mut data = Data(String::new());
156 data.insert("type", "init");
157 if hash.is_some() {
158 data.insert("hash", hash.unwrap());
159 }
160 data.insert("ver", &self.version);
161 data.insert("name", &self.name);
162 data.insert("ownerid", &self.owner_id);
163 data.insert("enckey", &self.enckey);
164
165 let req = Self::request(data, &self.api_url).await;
166 let resp = req.res;
167 let head = req.head;
168
169 if resp == "KeyAuth_Invalid" {
170 return Res(Err("The application doesn't exist".to_string()));
171 }
172 if !head.contains_key("signature") {
173
174 return Res(Err("response was tampered with".to_string()));
175 }
176 let sig = head.get("signature").unwrap().to_str().unwrap();
177 if sig != Self::make_hmac(&resp, &self.secret) {
178
179 return Res(Err("response was tampered with".to_string()));
180 }
181 let json_rep: serde_json::Value = serde_json::from_str(&resp).unwrap();
182 nodebug!();
183 if json_rep["success"].as_bool().unwrap() {
184 self.session_id = json_rep["sessionid"].as_str().unwrap().to_string();
185 self.num_keys = json_rep["appinfo"]["numKeys"].as_str().unwrap().to_string();
186 self.num_online_users = json_rep["appinfo"]["numOnlineUsers"].as_str().unwrap().to_string();
187 self.num_users = json_rep["appinfo"]["numUsers"].as_str().unwrap().to_string();
188 self.customer_panel_link = json_rep["appinfo"]["customerPanelLink"].as_str().unwrap_or("").to_string();
189 Res(Ok(()))
190 } else {
191 if json_rep["message"].as_str().unwrap() == "invalidver" {
192 let download_url = json_rep["download"].as_str().unwrap();
193 if !download_url.is_empty() {
194 webbrowser::open(download_url).unwrap();
195 }
196 }
197 Res(Err(json_rep["message"].as_str().unwrap().to_string()))
198 }}};
199 res
200 }
201
202 pub async fn register(
204 &mut self,
205 username: String,
206 password: String,
207 license: String,
208 hwid: Option<String>,
209 ) -> Res<()> {
210 let res = goldberg_stmts! {{
211 nodebug!();
212 let hwidd = match hwid {
213 Some(hwid) => hwid,
214 None => machine_uuid::get(),
215 };
216 let mut req_data = Data(String::new());
217 req_data.insert("type", "register");
218 req_data.insert("username", &username);
219 req_data.insert("pass", &password);
220 req_data.insert("key", &license);
221 req_data.insert("sessionid", &self.session_id);
222 req_data.insert("name", &self.name);
223 req_data.insert("ownerid", &self.owner_id);
224 req_data.insert("hwid", &hwidd);
225
226
227 let req = Self::request(req_data, &self.api_url).await;
228 let resp = req.res;
229 let head = req.head;
230
231 if !head.contains_key("signature") {
232
233 return Res(Err("response was tampered with".to_string()));
234 }
235 let sig = head.get("signature").unwrap().to_str().unwrap();
236 if sig != Self::make_hmac(&resp, &self.enckey_s) {
237
238 return Res(Err("response was tampered with".to_string()));
239 }
240 let json_rep: serde_json::Value = serde_json::from_str(&resp).unwrap();
241 nodebug!();
242 if json_rep["success"].as_bool().unwrap() {
243 self.username = copy_string(username.as_bytes());
244 self.ip = json_rep["info"]["ip"].as_str().unwrap().to_string();
245 self.create_date = json_rep["info"]["createdate"].as_str().unwrap().to_string();
246 self.last_login = json_rep["info"]["lastlogin"].as_str().unwrap().to_string();
247 self.subscription = json_rep["info"]["subscriptions"][0]["subscription"].as_str().unwrap().to_string();
248 Res(Ok(()))
249 } else {
250 Res(Err(json_rep["message"].as_str().unwrap().to_string()))
251 }}};
252 res
253 }
254
255 pub async fn upgrade(&mut self, username: String, license: String) -> Res<()> {
257 let res = goldberg_stmts! {{
258 nodebug!();
259 let mut req_data = Data(String::new());
260 req_data.insert("type", "upgrade");
261 req_data.insert("username", &username);
262 req_data.insert("key", &license);
263 req_data.insert("sessionid", &self.session_id);
264 req_data.insert("name", &self.name);
265 req_data.insert("ownerid", &self.owner_id);
266
267
268 let req = Self::request(req_data, &self.api_url).await;
269 let resp = req.res;
270 let head = req.head;
271
272 if !head.contains_key("signature") {
273
274 return Res(Err("response was tampered with".to_string()));
275 }
276 let sig = head.get("signature").unwrap().to_str().unwrap();
277 if sig != Self::make_hmac(&resp, &self.enckey_s) {
278
279 return Res(Err("response was tampered with".to_string()));
280 }
281 let json_rep: serde_json::Value = serde_json::from_str(&resp).unwrap();
282 nodebug!();
283 if json_rep["success"].as_bool().unwrap() {
284 Res(Ok(()))
285 } else {
286 Res(Err(json_rep["message"].as_str().unwrap().to_string()))
287 }}};
288 res
289 }
290
291 pub async fn login(
293 &mut self,
294 username: String,
295 password: String,
296 hwid: Option<String>,
297 ) -> Res<()> {
298 let res = goldberg_stmts! {{
299 nodebug!();
300 let hwidd = match hwid {
301 Some(hwid) => hwid,
302 None => machine_uuid::get(),
303 };
304
305 let mut req_data = Data(String::new());
306 req_data.insert("type", "login");
307 req_data.insert("username", &username);
308 req_data.insert("pass", &password);
309 req_data.insert("hwid", &hwidd);
310 req_data.insert("sessionid", &self.session_id);
311 req_data.insert("name", &self.name);
312 req_data.insert("ownerid", &self.owner_id);
313
314
315 let req = Self::request(req_data, &self.api_url).await;
316 let resp = req.res;
317 let head = req.head;
318
319 if !head.contains_key("signature") {
320
321 return Res(Err("response was tampered with".to_string()));
322 }
323 let sig = head.get("signature").unwrap().to_str().unwrap();
324 if sig != Self::make_hmac(&resp, &self.enckey_s) {
325
326 return Res(Err("response was tampered with".to_string()));
327 }
328 let json_rep: serde_json::Value = serde_json::from_str(&resp).unwrap();
329
330 nodebug!();
331 if json_rep["success"].as_bool().unwrap() {
332 self.username = copy_string(username.as_bytes());
333 self.ip = json_rep["info"]["ip"].as_str().unwrap().to_string();
334 self.hwid = copy_string(hwidd.as_bytes());
335 self.create_date = json_rep["info"]["createdate"].as_str().unwrap().to_string();
336 self.last_login = json_rep["info"]["lastlogin"].as_str().unwrap().to_string();
337 self.subscription = json_rep["info"]["subscriptions"][0]["subscription"].as_str().unwrap().to_string();
338 Res(Ok(()))
339 } else {
340 Res(Err(json_rep["message"].as_str().unwrap().to_string()))
341 }}};
342 res
343 }
344
345 pub async fn license(&mut self, license: String, hwid: Option<String>) -> Res<()> {
347 let res = goldberg_stmts! {{
348 nodebug!();
349 let hwidd = match hwid {
350 Some(hwid) => hwid,
351 None => machine_uuid::get(),
352 };
353
354 let mut req_data = Data(String::new());
355 req_data.insert("type", "license");
356 req_data.insert("key", &license);
357 req_data.insert("hwid", &hwidd);
358 req_data.insert("sessionid", &self.session_id);
359 req_data.insert("name", &self.name);
360 req_data.insert("ownerid", &self.owner_id);
361
362
363 let req = Self::request(req_data, &self.api_url).await;
364 let resp = req.res;
365 let head = req.head;
366
367 if !head.contains_key("signature") {
368
369 return Res(Err("response was tampered with".to_string()));
370 }
371 let sig = head.get("signature").unwrap().to_str().unwrap();
372 if sig != Self::make_hmac(&resp, &self.enckey_s) {
373
374 return Res(Err("response was tampered with".to_string()));
375 }
376 let json_rep: serde_json::Value = serde_json::from_str(&resp).unwrap();
377
378 nodebug!();
379 if json_rep["success"].as_bool().unwrap() {
380 self.username = json_rep["info"]["username"].as_str().unwrap().to_string();
381 self.ip = json_rep["info"]["ip"].as_str().unwrap().to_string();
382 self.hwid = copy_string(hwidd.as_bytes());
383 self.create_date = json_rep["info"]["createdate"].as_str().unwrap().to_string();
384 self.last_login = json_rep["info"]["lastlogin"].as_str().unwrap().to_string();
385 self.subscription = json_rep["info"]["subscriptions"][0]["subscription"].as_str().unwrap().to_string();
386 Res(Ok(()))
387 } else {
388 Res(Err(json_rep["message"].as_str().unwrap().to_string()))
389 }}};
390 res
391 }
392
393 pub async fn var(&mut self, varid: String) -> Res<String> {
395 let res = goldberg_stmts! {{
396 nodebug!();
397 let mut req_data = Data(String::new());
398 req_data.insert("type", "var");
399 req_data.insert("varid", &varid);
400 req_data.insert("sessionid", &self.session_id);
401 req_data.insert("name", &self.name);
402 req_data.insert("ownerid", &self.owner_id);
403
404
405 let req = Self::request(req_data, &self.api_url).await;
406 let resp = req.res;
407 let head = req.head;
408
409 if !head.contains_key("signature") {
410
411 return Res(Err("response was tampered with".to_string()));
412 }
413 let sig = head.get("signature").unwrap().to_str().unwrap();
414 if sig != Self::make_hmac(&resp, &self.enckey_s) {
415
416 return Res(Err("response was tampered with".to_string()));
417 }
418 let json_rep: serde_json::Value = serde_json::from_str(&resp).unwrap();
419
420 nodebug!();
421 if json_rep["success"].as_bool().unwrap() {
422 Res(Ok(json_rep["message"].as_str().unwrap().to_string()))
423 } else {
424 Res(Err(json_rep["message"].as_str().unwrap().to_string()))
425 }}};
426 res
427 }
428
429 pub async fn file(&mut self, fileid: String) -> Res<Vec<u8>> {
431 let res = goldberg_stmts! {{
432 nodebug!();
433 let mut req_data = Data(String::new());
434 req_data.insert("type", "file");
435 req_data.insert("fileid", &fileid);
436 req_data.insert("sessionid", &self.session_id);
437 req_data.insert("name", &self.name);
438 req_data.insert("ownerid", &self.owner_id);
439
440
441 let req = Self::request(req_data, &self.api_url).await;
442 let resp = req.res;
443 let head = req.head;
444
445 if !head.contains_key("signature") {
446
447 return Res(Err("response was tampered with".to_string()));
448 }
449 let sig = head.get("signature").unwrap().to_str().unwrap();
450 if sig != Self::make_hmac(&resp, &self.enckey_s) {
451
452 return Res(Err("response was tampered with".to_string()));
453 }
454 let json_rep: serde_json::Value = serde_json::from_str(&resp).unwrap();
455
456 nodebug!();
457 if json_rep["success"].as_bool().unwrap() {
458 Res(Ok(decode(json_rep["contents"].as_str().unwrap()).unwrap()))
459 } else {
460 Res(Err(json_rep["message"].as_str().unwrap().to_string()))
461 }}};
462 res
463 }
464
465 pub async fn webhook(&mut self, webid: String, params: String) -> Res<String> {
467 let res = goldberg_stmts! {{
468 nodebug!();
469 let mut req_data = Data(String::new());
470 req_data.insert("type", "webhook");
471 req_data.insert("webid", &webid);
472 req_data.insert("params", ¶ms);
473 req_data.insert("sessionid", &self.session_id);
474 req_data.insert("name", &self.name);
475 req_data.insert("ownerid", &self.owner_id);
476
477
478 let req = Self::request(req_data, &self.api_url).await;
479 let resp = req.res;
480 let head = req.head;
481
482 if !head.contains_key("signature") {
483
484 return Res(Err("response was tampered with".to_string()));
485 }
486 let sig = head.get("signature").unwrap().to_str().unwrap();
487 if sig != Self::make_hmac(&resp, &self.enckey_s) {
488
489 return Res(Err("response was tampered with".to_string()));
490 }
491 let json_rep: serde_json::Value = serde_json::from_str(&resp).unwrap();
492
493 nodebug!();
494 if json_rep["success"].as_bool().unwrap() {
495 Res(Ok(json_rep["message"].as_str().unwrap().to_string()))
496 } else {
497 Res(Err(json_rep["message"].as_str().unwrap().to_string()))
498 }}};
499 res
500 }
501
502 pub async fn checkblacklist(&mut self) -> Res<()> {
504 let res = goldberg_stmts! {{
505 nodebug!();
506 let mut req_data = Data(String::new());
507 req_data.insert("type", "checkblacklist");
508 req_data.insert("sessionid", &self.session_id);
509 req_data.insert("name", &self.name);
510 req_data.insert("ownerid", &self.owner_id);
511
512 let req = Self::request(req_data, &self.api_url).await;
513 let resp = req.res;
514 let head = req.head;
515
516 if !head.contains_key("signature") {
517
518 return Res(Err("response was tampered with".to_string()));
519 }
520 let sig = head.get("signature").unwrap().to_str().unwrap();
521 if sig != Self::make_hmac(&resp, &self.enckey_s) {
522
523 return Res(Err("response was tampered with".to_string()));
524 }
525 let json_rep: serde_json::Value = serde_json::from_str(&resp).unwrap();
526
527 nodebug!();
528 if json_rep["success"].as_bool().unwrap() {
529 self.blacklisted = true;
530 Res(Ok(()))
531 } else {
532 self.blacklisted = false;
533 Res(Ok(()))
534 }}};
535 res
536 }
537
538 pub async fn check_session(&mut self) -> Res<bool> {
540 let res = goldberg_stmts! {{
541 nodebug!();
542 let mut req_data = Data(String::new());
543 req_data.insert("type", "check");
544 req_data.insert("sessionid", &self.session_id);
545 req_data.insert("name", &self.name);
546 req_data.insert("ownerid", &self.owner_id);
547
548 let req = Self::request(req_data, &self.api_url).await;
549 let resp = req.res;
550 let head = req.head;
551
552 if !head.contains_key("signature") {
553
554 return Res(Err("response was tampered with".to_string()));
555 }
556 let sig = head.get("signature").unwrap().to_str().unwrap();
557 if sig != Self::make_hmac(&resp, &self.enckey_s) {
558
559 return Res(Err("response was tampered with".to_string()));
560 }
561 let json_rep: serde_json::Value = serde_json::from_str(&resp).unwrap();
562
563 nodebug!();
564 Res(Ok(json_rep["success"].as_bool().unwrap()))
565 }};
566 res
567 }
568
569 pub async fn fetch_online(&mut self) -> Res<serde_json::Value> {
571 let res = goldberg_stmts! {{
572 nodebug!();
573 let mut req_data = Data(String::new());
574 req_data.insert("type", "fetchOnline");
575 req_data.insert("sessionid", &self.session_id);
576 req_data.insert("name", &self.name);
577 req_data.insert("ownerid", &self.owner_id);
578
579 let req = Self::request(req_data, &self.api_url).await;
580 let resp = req.res;
581 let head = req.head;
582
583 if !head.contains_key("signature") {
584
585 return Res(Err("response was tampered with".to_string()));
586 }
587 let sig = head.get("signature").unwrap().to_str().unwrap();
588 if sig != Self::make_hmac(&resp, &self.enckey_s) {
589
590 return Res(Err("response was tampered with".to_string()));
591 }
592 let json_rep: serde_json::Value = serde_json::from_str(&resp).unwrap();
593
594 nodebug!();
595 if json_rep["success"].as_bool().unwrap() {
596 Res(Ok(json_rep["users"].clone()))
597 } else {
598 Res(Err(json_rep["message"].as_str().unwrap().to_string()))
599 }}};
600 res
601 }
602
603 pub async fn get_chat(&mut self, channel: String) -> Res<serde_json::Value> {
605 let res = goldberg_stmts! {{
606 nodebug!();
607 let mut req_data = Data(String::new());
608 req_data.insert("type", "chatget");
609 req_data.insert("channel", &channel);
610 req_data.insert("sessionid", &self.session_id);
611 req_data.insert("name", &self.name);
612 req_data.insert("ownerid", &self.owner_id);
613
614 let req = Self::request(req_data, &self.api_url).await;
615 let resp = req.res;
616 let head = req.head;
617
618 if !head.contains_key("signature") {
619
620 return Res(Err("response was tampered with".to_string()));
621 }
622 let sig = head.get("signature").unwrap().to_str().unwrap();
623 if sig != Self::make_hmac(&resp, &self.enckey_s) {
624
625 return Res(Err("response was tampered with".to_string()));
626 }
627 let json_rep: serde_json::Value = serde_json::from_str(&resp).unwrap();
628
629 nodebug!();
630 if json_rep["success"].as_bool().unwrap() {
631 Res(Ok(json_rep["messages"].clone()))
632 } else {
633 Res(Err(json_rep["message"].as_str().unwrap().to_string()))
634 }}};
635 res
636 }
637
638 pub async fn send_chat_message(&mut self, channel: String, message: String) -> Res<()> {
640 let res = goldberg_stmts! {{
641 nodebug!();
642 let mut req_data = Data(String::new());
643 req_data.insert("type", "chatsend");
644 req_data.insert("channel", &channel);
645 req_data.insert("message", &message);
646 req_data.insert("sessionid", &self.session_id);
647 req_data.insert("name", &self.name);
648 req_data.insert("ownerid", &self.owner_id);
649
650 let req = Self::request(req_data, &self.api_url).await;
651 let resp = req.res;
652 let head = req.head;
653
654 if !head.contains_key("signature") {
655
656 return Res(Err("response was tampered with".to_string()));
657 }
658 let sig = head.get("signature").unwrap().to_str().unwrap();
659 if sig != Self::make_hmac(&resp, &self.enckey_s) {
660
661 return Res(Err("response was tampered with".to_string()));
662 }
663 let json_rep: serde_json::Value = serde_json::from_str(&resp).unwrap();
664
665 nodebug!();
666 if json_rep["success"].as_bool().unwrap() {
667 Res(Ok(()))
668 } else {
669 Res(Err(json_rep["message"].as_str().unwrap().to_string()))
670 }}};
671 res
672 }
673
674 pub async fn ban(&mut self) {
676 goldberg_stmts! {{
677 nodebug!();
678 let mut req_data = Data(String::new());
679 req_data.insert("type", "ban");
680 req_data.insert("sessionid", &self.session_id);
681 req_data.insert("name", &self.name);
682 req_data.insert("ownerid", &self.owner_id);
683
684 nodebug!();
685 Self::request(req_data, &self.api_url).await;}};
686 }
687
688 pub async fn setvar(&mut self, varname: String, varvalue: String) -> Res<()> {
690 let res = goldberg_stmts! {{
691 nodebug!();
692 let mut req_data = Data(String::new());
693 req_data.insert("type", "setvar");
694 req_data.insert("var", &varname);
695 req_data.insert("data", &varvalue);
696 req_data.insert("sessionid", &self.session_id);
697 req_data.insert("name", &self.name);
698 req_data.insert("ownerid", &self.owner_id);
699
700 let req = Self::request(req_data, &self.api_url).await;
701 let resp = req.res;
702 let head = req.head;
703
704 if !head.contains_key("signature") {
705
706 return Res(Err("response was tampered with".to_string()));
707 }
708 let sig = head.get("signature").unwrap().to_str().unwrap();
709 if sig != Self::make_hmac(&resp, &self.enckey_s) {
710
711 return Res(Err("response was tampered with".to_string()));
712 }
713 let json_rep: serde_json::Value = serde_json::from_str(&resp).unwrap();
714
715 self.message = json_rep["message"].as_str().unwrap().to_string();
716 self.success = json_rep["success"].as_bool().unwrap();
717 nodebug!();
718 Res(Ok(()))}};
719 res
720 }
721
722 pub async fn getvar(&mut self, varname: String) -> Res<String> {
724 let res = goldberg_stmts! {{
725 nodebug!();
726 let mut req_data = Data(String::new());
727 req_data.insert("type", "getvar");
728 req_data.insert("var", &varname);
729 req_data.insert("sessionid", &self.session_id);
730 req_data.insert("name", &self.name);
731 req_data.insert("ownerid", &self.owner_id);
732
733 let req = Self::request(req_data, &self.api_url).await;
734 let resp = req.res;
735 let head = req.head;
736
737 if !head.contains_key("signature") {
738
739 return Res(Err("response was tampered with".to_string()));
740 }
741 let sig = head.get("signature").unwrap().to_str().unwrap();
742 if sig != Self::make_hmac(&resp, &self.enckey_s) {
743
744 return Res(Err("response was tampered with".to_string()));
745 }
746 let json_rep: serde_json::Value = serde_json::from_str(&resp).unwrap();
747
748 nodebug!();
749 if json_rep["success"].as_bool().unwrap() {
750 Res(Ok(json_rep["response"].as_str().unwrap().to_string()))
751 } else {
752 Res(Err(json_rep["message"].as_str().unwrap().to_string()))
753 }}};
754 res
755 }
756
757 pub async fn log(&mut self, message: String, pcuser: Option<String>) {
759 goldberg_stmts! {{
760 nodebug!();
761 let usr = match pcuser {
762 Some(pcuser) => pcuser,
763 None => self.username.clone(),
764 };
765
766 let mut req_data = Data(String::new());
767 req_data.insert("type", "log");
768 req_data.insert("message", &message);
769 req_data.insert("pcuser", &usr);
770 req_data.insert("sessionid", &self.session_id);
771 req_data.insert("name", &self.name);
772 req_data.insert("ownerid", &self.owner_id);
773
774 nodebug!();
775 Self::request(req_data, &self.api_url).await;}}
776 }
777
778 pub async fn change_username(&mut self, new_username: String) -> Res<String> {
780 let res: Res<String> = goldberg_stmts! {{
781 nodebug!();
782 let mut req_data = Data(String::new());
783 req_data.insert("type", "changeUsername");
784 req_data.insert("newUsername", &new_username);
785 req_data.insert("sessionid", &self.session_id);
786 req_data.insert("name", &self.name);
787 req_data.insert("ownerid", &self.owner_id);
788
789 let req = Self::request(req_data, &self.api_url).await;
790 let resp = req.res;
791 let head = req.head;
792
793 if !head.contains_key("signature") {
794
795 return Res(Err("response was tampered with".to_string()));
796 }
797 let sig = head.get("signature").unwrap().to_str().unwrap();
798 if sig != Self::make_hmac(&resp, &self.enckey_s) {
799
800 return Res(Err("response was tampered with".to_string()));
801 }
802 let json_rep: serde_json::Value = serde_json::from_str(&resp).unwrap();
803
804 nodebug!();
805 if json_rep["success"].as_bool().unwrap() {
806 Res(Ok(json_rep["message"].as_str().unwrap().to_string()))
807 } else {
808 Res(Err(json_rep["message"].as_str().unwrap().to_string()))
809 }
810 }};
811 res
812 }
813
814 #[cfg(feature = "web_loader")]
816 pub async fn web_login(&mut self, hwid: Option<String>) -> Res<()> {
817 use std::io::Write;
818
819 let hwidd = match hwid {
820 Some(hwid) => hwid,
821 None => self.hwid.clone(),
822 };
823
824 let listener = TcpListener::bind("127.0.0.1:1337");
825 if listener.is_err() {
826 return Res(Err("Couldnt bind to port 1337".to_string()));
827 }
828 let listener = listener.unwrap();
829
830 for stream in listener.incoming() {
831 if stream.is_err() {
832 continue;
833 }
834 let mut stream = stream.unwrap();
835 let mut buf = [0u8; 4096];
836 stream.read(&mut buf).unwrap();
837 let mut headers = [httparse::EMPTY_HEADER; 16];
838 let mut req = httparse::Request::new(&mut headers);
839 req.parse(&buf).unwrap();
840 if req.path.unwrap().starts_with("/handshake") {
841 let s = req.path.unwrap();
842 let start = s.find("?user=").unwrap_or(0) + 6;
843 let end = s.rfind("&token=").unwrap_or(s.len());
844 let user = &s[start..end];
845 let start = s.find("&token=").unwrap_or(0) + 7;
846 let token = &s[start..];
847 let mut req_data = Data(String::new());
848 req_data.insert("type", "login");
849 req_data.insert("username", &user);
850 req_data.insert("token", &token);
851 req_data.insert("name", &self.name);
852 req_data.insert("ownerid", &self.owner_id);
853 req_data.insert("hwid", &self.hwid);
854 req_data.insert("sessionid", &self.session_id);
855
856 let req = Self::request(req_data, &self.api_url).await;
857 let resp = req.res;
858 let head = req.head;
859
860 if !head.contains_key("signature") {
861 return Res(Err("response was tampered with".to_string()));
862 }
863 let sig = head.get("signature").unwrap().to_str().unwrap();
864 if sig != Self::make_hmac(&resp, &self.enckey_s) {
865 return Res(Err("Response was tampered with".to_string()));
866 }
867 let json_rep: serde_json::Value = serde_json::from_str(&resp).unwrap();
868 let (status, body) = if json_rep["success"].as_bool().unwrap() {
869 self.username = copy_string(user.as_bytes());
870 self.ip = json_rep["info"]["ip"].as_str().unwrap().to_string();
871 self.hwid = copy_string(hwidd.as_bytes());
872 self.create_date = json_rep["info"]["createdate"].as_str().unwrap().to_string();
873 self.last_login = json_rep["info"]["lastlogin"].as_str().unwrap().to_string();
874 self.subscription = json_rep["info"]["subscriptions"][0]["subscription"]
875 .as_str()
876 .unwrap()
877 .to_string();
878
879 ("420", "SHEESH")
880 } else {
881 ("200", json_rep["message"].as_str().unwrap())
882 };
883 let response = format!(
884 r#"HTTP/1.1 {} OK
885Access-Control-Allow-Methods: Get, Post
886Access-Control-Allow-Origin: *
887Via: hugzho's big brain
888Location: your kernel ;)
889Retry-After: never lmao
890Server: \r\n\r\n
891{}"#,
892 status, body
893 );
894 stream.write_all(response.as_bytes()).unwrap();
895 return Res(Ok(()));
896 }
897 }
898 Res(Ok(()))
899 }
900
901 #[cfg(feature = "web_loader")]
902 pub async fn button(&self, button: &str) -> Res<()> {
903 let res = goldberg_stmts! {{
904 use std::io::Write;
905
906 let listener = TcpListener::bind("127.0.0.1:1337");
907 if listener.is_err() {
908 return Res(Err("Couldnt bind to port 1337".to_string()));
909 }
910 let listener = listener.unwrap();
911
912 for stream in listener.incoming() {
913 if stream.is_err() {
914 continue;
915 }
916 let mut stream = stream.unwrap();
917 let mut buf = [0u8; 4096];
918 stream.read(&mut buf).unwrap();
919 let mut headers = [httparse::EMPTY_HEADER; 16];
920 let mut req = httparse::Request::new(&mut headers);
921 req.parse(&buf).unwrap();
922 if req.path.unwrap().starts_with(format!("/{}", button).as_str()) {
923 let response = format!(r#"HTTP/1.1 {} OK
924Access-Control-Allow-Methods: Get, Post
925Access-Control-Allow-Origin: *
926Via: hugzho's big brain
927Location: your kernel ;)
928Retry-After: never lmao
929Server: \r\n\r\n
930
931{}"#, 420, "SHEESH");
932 stream.write_all(response.as_bytes()).unwrap();
933 return Res(Ok(()));
934 }
935 }
936 Res(Ok(()))}};
937 res
938 }
939
940 async fn request(req_data: Data, url: &str) -> Resp {
941 let res: Resp = goldberg_stmts! {{
942 let client = Client::new();
943 let req_data_str = req_data.0.strip_suffix("&").unwrap().to_string();
944 nodebug!();
945 let res = client.post(url.to_string())
946 .body(req_data_str)
947 .header("User-Agent", "KeyAuth")
948 .header("Content-Type", "application/x-www-form-urlencoded")
949 .send().await.unwrap();
950 let resp = Resp {
951 head: res.headers().clone(),
952 res: res.text().await.unwrap()
953 };
954 resp}};
955 res
956 }
957
958 fn make_hmac(message: &str, key: &str) -> String {
959 let res: String = goldberg_stmts! {{ hex::encode(HMAC::mac(message, key)).to_string()}};
960 res
961 }
962}