Commit 121e641e authored by Alexander Danilov's avatar Alexander Danilov

Расширен FFI библиотеки, упрощено получение данных из принятого сообщения,...

Расширен FFI библиотеки, упрощено получение данных из принятого сообщения, добавлена поддержка рекурсивных реквестов
parent 4436ffae
......@@ -8,13 +8,15 @@ version = "0.1.0"
authors = ["Alexandr Danilov <[email protected]>"]
[dependencies]
websocket = "^0.20"
serde_cbor = "^0.5"
lazy_static = "^0.2"
openssl = "^0.9"
rustc-serialize = "^0.3"
rand = "^0.3"
websocket = "~0.20"
serde_cbor = "~0.5"
lazy_static = "~0.2"
openssl = "~0.9"
rustc-serialize = "~0.3"
rand = "~0.3"
base64 = "~0.5.0"
sha = {git = "https://github.com/andydude/rust-sha.git", tag = "v0.3.3"}
serde = "0.9.13"
serde_derive = "0.9.13"
serde = "~0.9.13"
serde_derive = "~0.9.13"
libc = "~0.2"
uuid = { version = "0.5", features = ["v4"] }
\ No newline at end of file
......@@ -5,9 +5,16 @@ void trigger_callback() {
printf("trigger_callback!");fflush(stdout);
}
void export_keys(const char* public_key, const char* private_key) {
printf("export_keys!");
printf(public_key);
fflush(stdout);
}
int main()
{
int c;
printf("Hello, world!");
fflush(stdout);
......@@ -19,7 +26,7 @@ int main()
c = getchar( );
skaro_register(x);
skaro_register(x, "emlog", "log", "123");
c = getchar( );
......
typedef void * handle;
extern handle skaro_connect(const char*);
void skaro_authorize(handle);
void skaro_register(handle);
void skaro_register(handle, const char*, const char*, const char*);
void skaro_disconnect(handle);
extern crate websocket;
extern crate serde_cbor;
//#[macro_use]
//extern crate lazy_static;
extern crate openssl;
extern crate base64;
extern crate sha;
......
// FFI
use std::ffi::CStr;
use std::collections::HashMap;
// use std::sync::Mutex;
use std::sync::Mutex;
use serde_cbor;
use serde_cbor::Value;
......@@ -10,31 +13,46 @@ use openssl::rsa::Rsa;
use openssl::rsa::PKCS1_PADDING;
use openssl::symm::Cipher;
// сохранение на диск
use std::io::prelude::*;
use std::fs::File;
// SHA256
use sha::sha256::Sha256;
use sha::utils::Digest;
use sha::utils::DigestExt;
//lazy_static! {
// pub static ref DICT: Mutex<HashMap<&'static str, String>> = {
// let mut map = HashMap::new();
// Mutex::new(map)
// };
//}
use uuid::Uuid;
use lazy_static;
use message;
extern {
fn export_keys(public_key: &CStr, private_key: &CStr);
}
fn __export_keys(ref mut public_key: &Vec<u8>, ref mut private_key: &Vec<u8>) {
let mut buffer_pub = File::create("pub.key.txt").unwrap();
buffer_pub.write(&public_key);
let mut buffer_priv = File::create("priv.key.txt").unwrap();
buffer_priv.write(&private_key);
lazy_static! {
pub static ref DICT: Mutex<HashMap<&'static str, &'static str>> = {
let mut map = HashMap::new();
Mutex::new(map)
};
}
pub fn __request__(message: message::SkaroMessage) -> Result<Result<Vec<u8>, serde_cbor::Error>, &'static str> {
println!("__request__, uuid: {}", message.get_str("uuid"));
let dict = DICT.lock().unwrap();
println!("__request__, uuid: {}", dict.get("key").unwrap_or(&"err"));
match dict.get("key") {
Some(s) => match s {
&"authorize" => Ok(request_authorize(message)),
&&_ => Err("ошибка обработки цепочки"),
},
None => Err("цепочка не найдена в хранилище"),
}
}
//pub fn check_connection(data: message::CheckConnection) {
// println!("{}", data.token);
//
......@@ -43,60 +61,53 @@ fn __export_keys(ref mut public_key: &Vec<u8>, ref mut private_key: &Vec<u8>) {
// // HASHMAP.get(&0).unwrap()
//}
pub fn register() -> Result<Vec<u8>, serde_cbor::Error> {
pub fn register(email: &str, login: &str, password: &str) -> Result<Vec<u8>, serde_cbor::Error> {
// 1. Клиент выбирает себе логин и пароль
// 2. Клиент генерирует ключевую пару RSA.
// Публичный ключ e,N и приватный ключ d,N
let key = Rsa::generate(2048).unwrap();
let public_key = key.public_key_to_pem().unwrap();
let private_key = key.private_key_to_pem_passphrase(Cipher::aes_256_cbc(), b"foobar").unwrap();
// 3. Клиент устанавливает пароль на приватный ключ
let enc = Rsa::private_key_from_pem_passphrase(&private_key, b"foobar").unwrap();
let private_key = key.private_key_to_pem_passphrase(Cipher::aes_256_cbc(), password.as_bytes()).unwrap();
// 4. Клиент сохраняет в локальном хранилище свой публичный ключ и запароленный приватный ключ
//__export_keys(&public_key, &private_key);
//println!("{:?}", public_key);
//println!("{:?}", private_key);
//println!("{:?}", enc);
unsafe {
export_keys(
CStr::from_bytes_with_nul_unchecked(public_key.as_slice()),
CStr::from_bytes_with_nul_unchecked(private_key.as_slice())
);
}
let public_key_string = String::from_utf8(public_key).expect("Found invalid UTF-8");
// 4. Клиент отсылает на сервер, а сервер сохраняет — логин, E-Mail, открытый ключ e,N.
// 5. Клиент отсылает на сервер, а сервер сохраняет — логин, E-Mail, открытый ключ e,N.
let mut data = HashMap::new();
data.insert("chain_uuid", Value::String("455-936-574".to_string()));
let uuid = Uuid::new_v4();
data.insert("chain_uuid", Value::String(uuid.hyphenated().to_string()));
data.insert("type", Value::String("register".to_string()));
data.insert("login", Value::String("modtest".to_string()));
data.insert("email", Value::String("[email protected]".to_string()));
data.insert("login", Value::String(login.to_string()));
data.insert("email", Value::String(email.to_string()));
data.insert("public_key", Value::String(public_key_string));
serde_cbor::to_vec(&data)
}
pub fn authorize() -> Result<Vec<u8>, serde_cbor::Error> {
let mut dict = DICT.lock().unwrap();
dict.insert("key", "authorize");
let mut data = HashMap::new();
data.insert("chain_uuid", Value::String("123-994-356".to_string()));
let uuid = Uuid::new_v4();
data.insert("chain_uuid", Value::String(uuid.hyphenated().to_string()));
data.insert("type", Value::String("authorize".to_string()));
data.insert("login", Value::String("modtest".to_string()));
serde_cbor::to_vec(&data)
}
pub fn request_authorize(obj: HashMap<serde_cbor::ObjectKey, serde_cbor::Value>) -> Result<Vec<u8>, serde_cbor::Error> {
let encrypted_rnd = match obj.get(&serde_cbor::ObjectKey::String("encrypted_rnd".to_string())) {
Some(&Value::String(ref val)) => val.as_str(),
_ => "",
};
let chain_uuid = match obj.get(&serde_cbor::ObjectKey::String("chain_uuid".to_string())) {
Some(&Value::String(ref val)) => val.as_str(),
_ => "",
};
pub fn request_authorize(message: message::SkaroMessage) -> Result<Vec<u8>, serde_cbor::Error> {
println!("start request_authorize()");
let encrypted_rnd = &decode(encrypted_rnd.as_bytes()).unwrap();
let encrypted_rnd = &decode(message.get_str("encrypted_rnd").as_bytes()).unwrap();
let pkey = include_bytes!("priv.key.txt");
let private_key = Rsa::private_key_from_pem_passphrase(pkey, b"foobar").unwrap();
......@@ -109,7 +120,8 @@ pub fn request_authorize(obj: HashMap<serde_cbor::ObjectKey, serde_cbor::Value>)
println!("{:?}", res);
let mut data = HashMap::new();
data.insert("chain_uuid", Value::String(chain_uuid.to_string()));
let uuid = Uuid::new_v4();
data.insert("chain_uuid", Value::String(uuid.hyphenated().to_string()));
data.insert("type", Value::String("request".to_string()));
data.insert("rnd_hash", Value::String(res));
data.insert("status", Value::String("200 OK".to_string()));
......
extern crate websocket;
extern crate serde_cbor;
//#[macro_use]
//extern crate lazy_static;
extern crate openssl;
extern crate base64;
extern crate sha;
extern crate uuid;
#[macro_use]
extern crate lazy_static;
mod dalek;
mod message;
mod handler;
mod parse;
// C API for Skaro library
// C API for Skaro library
extern crate libc;
use std::ffi::CStr;
use std::os::raw::c_char;
use std::any::Any;
......@@ -44,14 +48,23 @@ pub extern fn skaro_authorize(handle: *mut std::sync::mpsc::Sender<websocket::Ow
}
#[no_mangle]
pub extern fn skaro_register(handle: *mut std::sync::mpsc::Sender<websocket::OwnedMessage<>>) {
println!("start skaro_register");
pub extern fn skaro_register(
handle: *mut std::sync::mpsc::Sender<websocket::OwnedMessage<>>,
email: *const c_char,
login: *const c_char,
password: *const c_char
) {
let maybe_channel = unsafe{ handle.as_mut() };
match maybe_channel {
Some(s) => {
s.send(websocket::OwnedMessage::Binary(::handler::register().unwrap()));
let string_email: &str = unsafe{CStr::from_ptr(email)}.to_str().unwrap();
let string_login: &str = unsafe{CStr::from_ptr(login)}.to_str().unwrap();
let string_password: &str = unsafe{CStr::from_ptr(password)}.to_str().unwrap();
s.send(websocket::OwnedMessage::Binary(::handler::register(string_email, string_login, string_password).unwrap()));
},
None => {
println!("null ptr");
......
//#[derive(Debug)]
//pub struct CheckConnection {
// pub token: String,
//}
//#[derive(Debug)]
//pub struct Request {
// pub id: u64,
// pub register_type: String,
//}
//#[derive(Debug)]
//pub struct RequestAuthorize {
// pub encrypted_rnd: String,
// pub id: i64,
//}
//#[derive(Debug)]
//pub struct Error {}
//#[derive(Debug)]
//pub enum ProtocolError {
// Error,
//}
//
//pub enum Mess {
// CheckConnection(CheckConnection),
// Request(Request),
// RequestAuthorize(RequestAuthorize),
// Error(Error),
//}
use std::collections::HashMap;
use serde_cbor::{Value, ObjectKey};
#[derive(Debug, Clone)]
pub struct SkaroMessage(pub HashMap<ObjectKey, Value>);
impl SkaroMessage {
pub fn get_str<'a>(&self, key: &'a str) -> &str {
match self.0.get(&ObjectKey::String(key.to_string())) {
Some(&Value::String(ref s)) => s.as_str(),
_ => "",
}
}
}
\ No newline at end of file
extern crate websocket;
extern crate serde_cbor;
use serde_cbor::{from_slice, Value, value, ObjectKey};
use serde_cbor::{from_slice, Value, value};
use handler;
use message;
use std::collections::HashMap;
pub fn cbor(message: websocket::OwnedMessage) -> Option<Result<Vec<u8>, serde_cbor::Error>> {
pub fn cbor(raw: websocket::OwnedMessage) -> Option<Result<Vec<u8>, serde_cbor::Error>> {
match message {
match raw {
websocket::OwnedMessage::Binary(payload) => {
let value : Value = from_slice(payload.as_slice()).unwrap();
......@@ -22,32 +23,25 @@ pub fn cbor(message: websocket::OwnedMessage) -> Option<Result<Vec<u8>, serde_cb
ret
}
};
let message = message::SkaroMessage(obj.clone());
let message_type = match obj.get(&ObjectKey::String("type".to_string())) {
Some(&Value::String(ref my_string)) => my_string.as_str(),
_ => "",
};
match message_type {
match message.get_str("type") {
"request" => {
handler::__request__(message).ok()
let struct_type = match obj.get(&ObjectKey::String("struct_type".to_string())) {
Some(&Value::String(ref my_string)) => my_string.as_str(),
_ => "",
};
match struct_type {
"authorize_rnd" => {
Some(handler::request_authorize(obj.clone()))
},
"register" => {
println!("Register");
None
},
_ => {
println!("Error! Unexpected 'struct_type'");
None
}
}
// match message.get_str("struct_type") {
// "authorize_rnd" => {
// Some(handler::request_authorize(message))
// },
// "register" => {
// println!("Register");
// None
// },
// _ => {
// println!("Error! Unexpected 'struct_type'");
// None
// }
// }
},
"error" => {
println!("Error type");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment