Advertisement
Guest User

Untitled

a guest
Oct 5th, 2018
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.83 KB | None | 0 0
  1. #![feature(plugin, use_extern_macros, proc_macro_path_invoc)]
  2. #![plugin(tarpc_plugins)]
  3.  
  4. #[macro_use]
  5. extern crate tarpc;
  6. extern crate serde;
  7. extern crate serde_json;
  8. extern crate pbkdf2;
  9. extern crate regex;
  10. extern crate chrono;
  11.  
  12. #[macro_use]
  13. extern crate serde_derive;
  14.  
  15. use regex::Regex;
  16. use serde_json::{Value,Error};
  17. use std::fs::OpenOptions;
  18. use std::io::prelude::*;
  19. use std::path::Path;
  20. use std::fs::File;
  21.  
  22. #[derive(Serialize, Deserialize)]
  23. struct JsonData {
  24. data_type: String,
  25. payload: Payload,
  26. }
  27.  
  28. #[derive(Serialize, Deserialize)]
  29. struct Payload {
  30. username: String,
  31. // password: String
  32. }
  33.  
  34. fn parse_json_data(s: &str) -> Result<Value, Error> {
  35. // Parse the string of data into serde_json::Value.
  36. let v: Value = serde_json::from_str(&s)?;
  37. Ok(v)
  38. }
  39.  
  40. fn strip_characters(original : String, to_strip : &str) -> String {
  41. let mut result = String::new();
  42. for c in original.chars() {
  43. if !to_strip.contains(c) {
  44. result.push(c);
  45. }
  46. }
  47. result
  48. }
  49.  
  50. // I URAN, AM NOT PROUD OF THIS FUNCTION !
  51. // password - letters (lowercase AND uppercase) AND numbers, 8-50 characters
  52. fn check_pass_requirement(input: &str) -> bool {
  53.  
  54. // check password length
  55. // check if password has numbers, then check for lowercase letters, then check for uppercase letters
  56. // finally, check there are no special characters?
  57. if input.chars().count() >= 8 && input.chars().count() <=50 {
  58. let re = Regex::new(r"[0-9]+").unwrap();
  59. if re.is_match(&input) {
  60. let re = Regex::new(r"[a-z]+").unwrap();
  61. if re.is_match(&input) {
  62. let re = Regex::new(r"[A-Z]+").unwrap();
  63. if re.is_match(&input) {
  64. let re = Regex::new(r"^[a-zA-Z0-9]+$").unwrap();
  65. if re.is_match(&input) {
  66. return true;
  67. }
  68. }
  69. }
  70. }
  71. }
  72. return false;
  73. }
  74.  
  75.  
  76. use std::sync::mpsc;
  77. use std::thread;
  78. use tarpc::sync::{client, server};
  79. use tarpc::sync::client::ClientExt;
  80. use tarpc::util::{FirstSocketAddr, Never};
  81.  
  82. service! {
  83. rpc hello(name: String) -> String;
  84. }
  85.  
  86. #[derive(Clone)]
  87. struct HelloServer;
  88.  
  89. impl SyncService for HelloServer {
  90. fn hello(&self, name: String) -> Result<String, Never> {
  91. Ok(format!("Hello, {}!", name))
  92. }
  93. }
  94.  
  95. // Authentication part - TO DO
  96. fn authenticate() {
  97.  
  98. }
  99.  
  100. // Create log for login/register attempt
  101. fn create_log(request : &str, username: &str) {
  102.  
  103. let file_name = "authLogFile";
  104.  
  105. // Check if file exists
  106. // If it doesn't, create it
  107. let file_exists : bool = Path::new(file_name).exists();
  108. if !file_exists {
  109. if let Err(e) = File::create(file_name) {
  110. eprintln!("Couldn't create file: {}", e);
  111. return;
  112. }
  113. }
  114.  
  115. // Document the time
  116. let now = chrono::Local::now();
  117. let time = now.format("%Y-%m-%d %H:%M:%S").to_string();
  118.  
  119. // Write to file
  120. let mut file = OpenOptions::new()
  121. .write(true)
  122. .append(true)
  123. .open(file_name)
  124. .unwrap();
  125.  
  126. if let Err(e) = writeln!(file, "[{}]: {} from user: {}", time, request, username) {
  127. eprintln!("Couldn't write to file: {}", e);
  128. }
  129. }
  130.  
  131. fn main() {
  132.  
  133. // Some variables
  134. let request : String;
  135. let username : String;
  136. let password : String;
  137. let hashed_password : String;
  138.  
  139. // This is easier to work with
  140. let json_data = r#"{
  141. "type": "Authenticate",
  142. "username": "james",
  143. "password": "TestPass321"
  144. }"#;
  145.  
  146. // serde_json::from_str seems to return a Result type
  147. // This is the only way I could get Result<T, E>
  148. // to work while returning the parsed JSON data to main()
  149. match parse_json_data(json_data) {
  150. Ok(_v) => {
  151. request = _v["type"].to_string();
  152. username = _v["username"].to_string();
  153. password = _v["password"].to_string();
  154. },
  155. Err(_v) => {
  156. request = "".to_string();
  157. username = "".to_string();
  158. password = "".to_string();
  159. }
  160. }
  161.  
  162. // Remove the parentheses from JSON data received
  163. let request = strip_characters(request, r#"""#);
  164. let username = strip_characters(username, r#"""#);
  165. let password = strip_characters(password, r#"""#);
  166.  
  167. // Add log info to the log file
  168. create_log(&request, &username);
  169.  
  170. // password - letters (lowercase AND uppercase) AND numbers, 8-50 characters
  171. // RegEx in Rust doesn't support look ahead assertion, so the RegEx would be very complicated
  172. if check_pass_requirement(&password) {
  173. println!("Password matches requirements");
  174. } else {
  175. println!("Password doesn't match requirements");
  176. return;
  177. }
  178.  
  179. // // Hash the password
  180. match pbkdf2::pbkdf2_simple(&password, 1000) {
  181. Ok(_hash) => {
  182. hashed_password = _hash;
  183. },
  184. Err(_hash) => {
  185. hashed_password = "".to_string();
  186. }
  187. }
  188.  
  189. // // Check the password hash against the password provided
  190. match pbkdf2::pbkdf2_check(&password, &hashed_password) {
  191. Ok(_x) => println!("Password matches password hash"),
  192. Err(_x) => println!("Password did not match password hash")
  193. }
  194.  
  195. println!("{} {} {} \n{}",request, username, password, hashed_password);
  196.  
  197. let (tx, rx) = mpsc::channel();
  198. thread::spawn(move || {
  199. let mut handle = HelloServer.listen("localhost:0", server::Options::default())
  200. .unwrap();
  201. tx.send(handle.addr()).unwrap();
  202. handle.run();
  203. });
  204. let client = SyncClient::connect(rx.recv().unwrap(), client::Options::default()).unwrap();
  205. println!("{}", client.hello("Mom".to_string()).unwrap());
  206. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement