From 52202f0d4140b86b41785ef8034a4307efcef6fa Mon Sep 17 00:00:00 2001 From: realaltffour <56314286+realaltffour@users.noreply.github.com> Date: Wed, 12 Aug 2020 06:41:02 +0300 Subject: [PATCH] add: register() --- Cargo.toml | 6 +-- DockerFiles/master_server.yml | 2 +- DockerFiles/sandbox.yml | 2 +- src/libtrader/client/account/creation.rs | 16 +++---- src/libtrader/client/initializer.rs | 6 +++ src/libtrader/libtrader.rs | 6 ++- src/libtrader/server/account/creation.rs | 42 +++++++++++-------- .../server/db/sql/005_schema_accounts.sql | 10 ++++- .../server/db/sql/006_table_accounts.sql | 6 +-- src/libtrader/server/network/cmd/register.rs | 15 +++++-- src/libtrader/server/network/handle_data.rs | 19 +++++++++ 11 files changed, 91 insertions(+), 39 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3a054df..941e368 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,6 @@ webpki-roots="0.20" ct-logs="0.7" either="*" arrayref="*" -rust-crypto = "0.2.36" -jsonwebtoken = "*" -lazy_static = "1.4.0" +rust-crypto="0.2.36" +jsonwebtoken="*" +json="*" diff --git a/DockerFiles/master_server.yml b/DockerFiles/master_server.yml index 1782e21..9ca74a9 100644 --- a/DockerFiles/master_server.yml +++ b/DockerFiles/master_server.yml @@ -13,7 +13,7 @@ services: - 5432:5432 volumes: - ./.db:/var/lib/postgresql/data - - ../src/libtrader/db/sql:/docker-entrypoint-initdb.d/ + - ../src/libtrader/server/db/sql:/docker-entrypoint-initdb.d/ adminer: container_name: pt_admin image: adminer diff --git a/DockerFiles/sandbox.yml b/DockerFiles/sandbox.yml index d24ba3e..9390809 100644 --- a/DockerFiles/sandbox.yml +++ b/DockerFiles/sandbox.yml @@ -13,7 +13,7 @@ services: - 5432:5432 volumes: - ./.db:/var/lib/postgresql/data - - ../src/libtrader/db/sql:/docker-entrypoint-initdb.d/ + - ../src/libtrader/server/db/sql:/docker-entrypoint-initdb.d/ adminer: container_name: pt_sandbox_admin image: adminer diff --git a/src/libtrader/client/account/creation.rs b/src/libtrader/client/account/creation.rs index 362881e..b600a2c 100644 --- a/src/libtrader/client/account/creation.rs +++ b/src/libtrader/client/account/creation.rs @@ -1,5 +1,6 @@ use ring::rand::SecureRandom; use ring::{digest, rand}; +use data_encoding::HEXUPPER; use std::io::Write; use crate::common::account::hash::hash; @@ -71,13 +72,14 @@ pub fn acc_create(tls_client: &mut TlsClient, poll: &mut mio::Poll, let password_hash = hash(password, password_salt, 250_000); /* generate message to be sent to the server */ - let mut data = Vec::new(); - data.append(&mut bincode::serialize(&email_hash.to_vec()).unwrap()); - data.append(&mut bincode::serialize(&email_client_salt.to_vec()).unwrap()); - data.append(&mut bincode::serialize(&password_hash.to_vec()).unwrap()); - data.append(&mut bincode::serialize(&password_client_salt.to_vec()).unwrap()); - data.append(&mut bincode::serialize(&username.as_bytes()).unwrap()); - match message_builder(MessageType::Command, CommandInst::Register as i64, 6, 0, 0, data) { + let data = object!{ + email_hash: HEXUPPER.encode(&email_hash), + email_client_salt: HEXUPPER.encode(&email_client_salt), + password_hash: HEXUPPER.encode(&password_hash), + password_client_salt: HEXUPPER.encode(&password_client_salt), + username: username + }; + match message_builder(MessageType::Command, CommandInst::Register as i64, 5, 0, 0, data.dump().as_bytes().to_vec()) { Ok(message) => { tls_client.write(bincode::serialize(&message).unwrap().as_slice()).unwrap(); }, diff --git a/src/libtrader/client/initializer.rs b/src/libtrader/client/initializer.rs index 901bedb..94a669d 100644 --- a/src/libtrader/client/initializer.rs +++ b/src/libtrader/client/initializer.rs @@ -91,6 +91,12 @@ pub fn libtrader_init_client() -> Result<(), String> { for ev in &events { tls_client.ready(&ev); tls_client.reregister(poll.registry()); + + use crate::client::account::creation::acc_create; + match acc_create(&mut tls_client, &mut poll, "test", "email", "password") { + Ok(_) => println!("we did it"), + Err(err) => panic!("panik!"), + } } } } diff --git a/src/libtrader/libtrader.rs b/src/libtrader/libtrader.rs index 3c76890..e3e2f64 100644 --- a/src/libtrader/libtrader.rs +++ b/src/libtrader/libtrader.rs @@ -1,7 +1,9 @@ #[cfg(any(feature="server", feature="client"))] #[macro_use] extern crate log; -#[cfg(any(feature="client", feature="client"))] #[macro_use] extern crate arrayref; +#[cfg(feature="server")] extern crate arrayref; +#[cfg(feature="server")] extern crate json; +#[cfg(feature="client")] #[macro_use] extern crate arrayref; +#[cfg(feature="client")] #[macro_use] extern crate json; -#[cfg(featue="server")] #[macro_use] extern crate lazy_static; extern crate simplelog; extern crate os_type; extern crate bincode; diff --git a/src/libtrader/server/account/creation.rs b/src/libtrader/server/account/creation.rs index c8cf717..d1fe668 100644 --- a/src/libtrader/server/account/creation.rs +++ b/src/libtrader/server/account/creation.rs @@ -1,3 +1,5 @@ +use data_encoding::HEXUPPER; + use crate::common::message::message::Message; use crate::common::account::portfolio::Portfolio; @@ -11,26 +13,29 @@ pub fn acc_create(message: &Message) -> Result<(), String> { /* * Parse account data * */ + /* get json data */ + let stringified_data = std::str::from_utf8(&message.data).unwrap().to_string(); + let data = json::parse(&stringified_data).unwrap(); /* get email, password salts and client hashes */ - let email_hash: Vec = bincode::deserialize(&message.data[..64]).unwrap(); - let email_client_salt: Vec = bincode::deserialize(&message.data[64..96]).unwrap(); - let password_hash: Vec = bincode::deserialize(&message.data[96..160]).unwrap(); - let password_client_salt: Vec = bincode::deserialize(&message.data[160..192]).unwrap(); + let email_hash = data["email_hash"].as_str().unwrap(); + let email_client_salt = data["email_client_salt"].as_str().unwrap(); + let password_hash = data["password_hash"].as_str().unwrap(); + let password_client_salt = data["password_client_salt"].as_str().unwrap(); /* get username */ - let username: Vec = bincode::deserialize(&message.data[192..]).unwrap(); + let username: String = data["username"].as_str().unwrap().to_string(); /* generate account struct */ let mut account: Account = Account { - username: String::from_utf8(username).unwrap(), + username: username, email_hash: "".to_string(), server_email_salt: "".to_string(), - client_email_salt: String::from_utf8(email_client_salt).unwrap(), + client_email_salt: email_client_salt.to_string(), pass_hash: "".to_string(), server_pass_salt: "".to_string(), - client_pass_salt: String::from_utf8(password_client_salt).unwrap(), + client_pass_salt: password_client_salt.to_string(), is_pass: true, portfolio: Portfolio::default(), @@ -45,7 +50,7 @@ pub fn acc_create(message: &Message) -> Result<(), String> { /* search for an account with same name */ for _ in &client.query( - "SELECT username FROM accounts_schema.accounts WHERE username IS ($1)", &[&account.username]).unwrap() { + "SELECT username FROM accounts_schema.accounts WHERE username LIKE $1", &[&account.username]).unwrap() { return Err("ACC_CREATE_FAILED_USERNAME_EXISTS".to_string()); } @@ -53,21 +58,24 @@ pub fn acc_create(message: &Message) -> Result<(), String> { * Hash the email and password. * */ /* hash the email */ - let email_server_hash = hash_email(String::from_utf8(email_hash).unwrap().as_str()).unwrap(); - account.email_hash = String::from_utf8(email_server_hash.0.to_vec()).unwrap(); - account.server_email_salt = String::from_utf8(email_server_hash.1.to_vec()).unwrap(); + let email_server_hash = hash_email(email_hash).unwrap(); + account.email_hash = HEXUPPER.encode(&email_server_hash.0); + account.server_email_salt = HEXUPPER.encode(&email_server_hash.1); /* hash the password */ - let password_server_hash = hash_pwd(String::from_utf8(password_hash).unwrap().as_str()).unwrap(); - account.pass_hash = String::from_utf8(password_server_hash.0.to_vec()).unwrap(); - account.server_pass_salt = String::from_utf8(password_server_hash.1.to_vec()).unwrap(); + let password_server_hash = hash_pwd(password_hash).unwrap(); + account.pass_hash = HEXUPPER.encode(&password_server_hash.0); + account.server_pass_salt = HEXUPPER.encode(&password_server_hash.1); /* * Write the account to the database. * */ match client.execute("INSERT INTO accounts_schema.accounts \ - (username, email, server_email_salt, client_email_salt, pass, server_pass_salt, client_pass_salt) + (username, email_hash, server_email_salt, client_email_salt, pass_hash, server_pass_salt, client_pass_salt) VALUES \ - ($1, $2, $3, $4, $5, $6, $7)", &[]) { + ($1, $2, $3, $4, $5, $6, $7)", + &[&account.username, + &account.email_hash, &account.server_email_salt, &account.client_email_salt, + &account.pass_hash, &account.server_pass_salt, &account.client_pass_salt]) { Ok(_) => return Ok(()), Err(err) => return Err(format!("ACC_CREATE_FAILED_SAVING: {}", err)), } diff --git a/src/libtrader/server/db/sql/005_schema_accounts.sql b/src/libtrader/server/db/sql/005_schema_accounts.sql index b5b2446..c72d192 100644 --- a/src/libtrader/server/db/sql/005_schema_accounts.sql +++ b/src/libtrader/server/db/sql/005_schema_accounts.sql @@ -1,3 +1,11 @@ -CREATE SCHEMA accounts_schema; CREATE ROLE accounts_schema_usr LOGIN PASSWORD 'PASSWORD'; +CREATE SCHEMA accounts_schema AUTHORIZATION accounts_schema_usr; + GRANT CONNECT ON DATABASE pt_db TO accounts_schema_usr; + +GRANT USAGE, CREATE ON SCHEMA accounts_schema TO accounts_schema_usr; +GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA accounts_schema TO accounts_schema_usr; +ALTER DEFAULT PRIVILEGES IN SCHEMA accounts_schema GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO accounts_schema_usr; + +GRANT USAGE ON ALL SEQUENCES IN SCHEMA accounts_schema TO accounts_schema_usr; +ALTER DEFAULT PRIVILEGES IN SCHEMA accounts_schema GRANT USAGE ON SEQUENCES TO accounts_schema_usr; diff --git a/src/libtrader/server/db/sql/006_table_accounts.sql b/src/libtrader/server/db/sql/006_table_accounts.sql index f2ac422..45ca4da 100644 --- a/src/libtrader/server/db/sql/006_table_accounts.sql +++ b/src/libtrader/server/db/sql/006_table_accounts.sql @@ -2,13 +2,13 @@ CREATE TABLE accounts_schema.accounts ( id BIGSERIAL PRIMARY KEY, username TEXT UNIQUE NOT NULL, - email TEXT UNIQUE NOT NULL, + email_hash TEXT UNIQUE NOT NULL, server_email_salt TEXT UNIQUE NOT NULL, client_email_salt TEXT UNIQUE NOT NULL, - pass TEXT UNIQUE NOT NULL, + pass_hash TEXT UNIQUE NOT NULL, server_pass_salt TEXT UNIQUE NOT NULL, client_pass_salt TEXT UNIQUE NOT NULL, transactions transaction[] -) +); diff --git a/src/libtrader/server/network/cmd/register.rs b/src/libtrader/server/network/cmd/register.rs index daf001e..4ef4e65 100644 --- a/src/libtrader/server/network/cmd/register.rs +++ b/src/libtrader/server/network/cmd/register.rs @@ -1,3 +1,5 @@ +use std::io::Write; + use crate::common::message::message::Message; use crate::common::message::message_type::MessageType; use crate::common::message::message_builder::message_builder; @@ -6,11 +8,11 @@ use crate::server::network::tls_connection::TlsConnection; use crate::server::account::creation::acc_create; #[cfg(feature="server")] -pub fn register(_tls_connection: &mut TlsConnection, message: &Message) { +pub fn register(tls_connection: &mut TlsConnection, message: &Message) { /* assert recieved message */ - if message.msgtype != MessageType::Command || message.argument_count != 6 + if message.msgtype != MessageType::Command || message.argument_count != 5 || message.data_message_number != 0 || message.data_message_max != 0 - || message.data.len() != 0 { + || message.data.len() == 0 { warn!("REGISTER_INVALID_MESSAGE"); return; } @@ -19,7 +21,12 @@ pub fn register(_tls_connection: &mut TlsConnection, message: &Message) { match acc_create(message) { Ok(_) => { match message_builder(MessageType::ServerReturn, 1, 0, 0, 0, Vec::new()) { - Ok(_) => {}, + Ok(msg) => { + match tls_connection.tls_session.write(bincode::serialize(&msg).unwrap().as_slice()) { + Ok(_) => return, + Err(err) => warn!("REGISTER_FAILED_SENDING_RESPONSE: {}", err) + } + }, Err(_) => {} } }, diff --git a/src/libtrader/server/network/handle_data.rs b/src/libtrader/server/network/handle_data.rs index def5963..12b805d 100644 --- a/src/libtrader/server/network/handle_data.rs +++ b/src/libtrader/server/network/handle_data.rs @@ -1,4 +1,8 @@ +use std::io::Write; + use crate::common::message::message::Message; +use crate::common::message::message_type::MessageType; +use crate::common::message::message_builder::message_builder; use crate::common::message::inst::CommandInst; use crate::server::network::tls_connection::TlsConnection; @@ -18,6 +22,21 @@ Result<(), String> { /* handle individual client instructions */ match client_response.instruction { + _ if client_response.instruction == CommandInst::GenHashSalt as i64 => { + use ring::rand::SecureRandom; + use ring::{digest, rand}; + let rng = rand::SystemRandom::new(); + let mut salt = [0u8; digest::SHA512_OUTPUT_LEN/2]; + rng.fill(&mut salt).unwrap(); + + let server_response: Message = match message_builder(MessageType::DataTransfer, + CommandInst::GenHashSalt as i64, 1, 0, 1, + salt.to_vec()) { + Ok(message) => message, + Err(_) => panic!("PANIK NO SALT") + }; + connection.tls_session.write(bincode::serialize(&server_response).unwrap().as_slice()).unwrap(); + }, _ if client_response.instruction == CommandInst::Register as i64 => register(connection, &client_response), _ => {}