From 68b553e0c855e59962530eb02d24ab05cfb9d4e4 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Mon, 27 Dec 2021 09:06:54 -0500 Subject: [PATCH 1/6] upgrade build refs, .h and buildgen bindings to lcg 1.5.2 -- now the fun begins --- build.rs | 4 +- libCwtch.h | 40 ++++++--- src/cwtchlib_go/bindings.rs | 168 ++++++++++++++++++++++++++---------- 3 files changed, 154 insertions(+), 58 deletions(-) diff --git a/build.rs b/build.rs index f57d188..d7379d4 100644 --- a/build.rs +++ b/build.rs @@ -11,6 +11,6 @@ fn main() { println!("cargo:rerun-if-changed=libCwtch.h"); let lib_cwtch_path = Path::new(&out_dir).join("libCwtch.so"); - // https://git.openprivacy.ca/cwtch.im/libcwtch-go/releases v1.2.0 - Command::new("wget").arg("https://git.openprivacy.ca/attachments/e77c69f0-9487-4808-bc23-092d943bc4a6").arg("-O").arg(lib_cwtch_path).output().expect("failed to download libCwtch.so"); + // https://git.openprivacy.ca/cwtch.im/libcwtch-go/releases v1.5.2 + Command::new("wget").arg("https://git.openprivacy.ca/attachments/3e563341-c206-4e69-98e3-e0dca449f947").arg("-O").arg(lib_cwtch_path).output().expect("failed to download libCwtch.so"); } \ No newline at end of file diff --git a/libCwtch.h b/libCwtch.h index 429db59..70c2395 100644 --- a/libCwtch.h +++ b/libCwtch.h @@ -16,6 +16,7 @@ typedef struct { const char *p; ptrdiff_t n; } _GoString_; #endif + /* Start of boilerplate cgo prologue. */ #line 1 "cgo-gcc-export-header-prolog" @@ -73,31 +74,46 @@ extern void c_SendProfileEvent(char* onion_ptr, int onion_len, char* json_ptr, i extern char* c_GetAppBusEvent(); extern void c_CreateProfile(char* nick_ptr, int nick_len, char* pass_ptr, int pass_len); extern void c_LoadProfiles(char* passwordPtr, int passwordLen); -extern void c_AcceptContact(char* profilePtr, int profileLen, char* handlePtr, int handleLen); -extern void c_RejectInvite(char* profilePtr, int profileLen, char* handlePtr, int handleLen); -extern void c_BlockContact(char* profilePtr, int profileLen, char* handlePtr, int handleLen); -extern void c_UpdateMessageFlags(char* profile_ptr, int profile_len, char* handle_ptr, int handle_len, int mIdx, long unsigned int message_flags); +extern void c_AcceptConversation(char* profilePtr, int profileLen, int conversation_id); +extern void c_BlockContact(char* profilePtr, int profileLen, int conversation_id); // the pointer returned from this function **must** be Freed by c_Free -extern char* c_GetMessage(char* profile_ptr, int profile_len, char* handle_ptr, int handle_len, int message_index); +extern char* c_GetMessage(char* profile_ptr, int profile_len, int conversation_id, int message_index); + +// the pointer returned from this function **must** be Freed by c_Free +extern char* c_GetMessageByID(char* profile_ptr, int profile_len, int conversation_id, int message_index); // the pointer returned from this function **must** be freed by calling c_Free -extern char* c_GetMessagesByContentHash(char* profile_ptr, int profile_len, char* handle_ptr, int handle_len, char* contenthash_ptr, int contenthash_len); +extern char* c_GetMessagesByContentHash(char* profile_ptr, int profile_len, int conversation_id, char* contenthash_ptr, int contenthash_len); // Dangerous function. Should only be used as documented in `MEMORY.md` extern void c_FreePointer(char* ptr); -extern void c_SendMessage(char* profile_ptr, int profile_len, char* handle_ptr, int handle_len, char* msg_ptr, int msg_len); -extern void c_SendInvitation(char* profile_ptr, int profile_len, char* handle_ptr, int handle_len, char* target_ptr, int target_len); +extern void c_SendMessage(char* profile_ptr, int profile_len, int conversation_id, char* msg_ptr, int msg_len); +extern void c_SendInvitation(char* profile_ptr, int profile_len, int conversation_id, int target_id); +extern void c_ShareFile(char* profile_ptr, int profile_len, int conversation_id, char* filepath_ptr, int filepath_len); +extern void c_DownloadFile(char* profile_ptr, int profile_len, int conversation_id, char* filepath_ptr, int filepath_len, char* manifestpath_ptr, int manifestpath_len, char* filekey_ptr, int filekey_len); +extern void c_CheckDownloadStatus(char* profilePtr, int profileLen, char* fileKeyPtr, int fileKeyLen); +extern void c_VerifyOrResumeDownload(char* profile_ptr, int profile_len, int conversation_id, char* filekey_ptr, int filekey_len); extern void c_ResetTor(); extern void c_CreateGroup(char* profile_ptr, int profile_len, char* server_ptr, int server_len, char* name_ptr, int name_len); extern void c_DeleteProfile(char* profile_ptr, int profile_len, char* password_ptr, int password_len); -extern void c_ArchiveConversation(char* profile_ptr, int profile_len, char* contact_ptr, int contact_len); -extern void c_DeleteContact(char* profile_ptr, int profile_len, char* hanlde_ptr, int handle_len); +extern void c_ArchiveConversation(char* profile_ptr, int profile_len, int conversation_id); +extern void c_DeleteContact(char* profile_ptr, int profile_len, int conversation_id); extern void c_ImportBundle(char* profile_ptr, int profile_len, char* bundle_ptr, int bundle_len); extern void c_SetProfileAttribute(char* profile_ptr, int profile_len, char* key_ptr, int key_len, char* val_ptr, int val_len); -extern void c_SetContactAttribute(char* profile_ptr, int profile_len, char* contact_ptr, int contact_len, char* key_ptr, int key_len, char* val_ptr, int val_len); -extern void c_SetGroupAttribute(char* profile_ptr, int profile_len, char* group_ptr, int group_len, char* key_ptr, int key_len, char* val_ptr, int val_len); +extern void c_SetConversationAttribute(char* profile_ptr, int profile_len, int conversation_id, char* key_ptr, int key_len, char* val_ptr, int val_len); +extern void c_SetMessageAttribute(char* profile_ptr, int profile_len, int conversation_id, int channel_id, int message_id, char* key_ptr, int key_len, char* val_ptr, int val_len); +extern void c_ChangePassword(char* profile_ptr, int profile_len, char* oldpassword_ptr, int oldpassword_len, char* newpassword_ptr, int newpassword_len, char* newpassword_again_ptr, int newpassword_again_len); extern void c_ShutdownCwtch(); +extern void c_LoadServers(char* passwordPtr, int passwordLen); +extern void c_CreateServer(char* passwordPtr, int passwordLen, char* descPtr, int descLen, char autostart); +extern void c_DeleteServer(char* onionPtr, int onionLen, char* currentPasswordPtr, int currentPasswordLen); +extern void c_LaunchServers(); +extern void c_LaunchServer(char* onionPtr, int onionLen); +extern void c_StopServer(char* onionPtr, int onionLen); +extern void c_StopServers(); +extern void c_DestroyServers(); +extern void c_SetServerAttribute(char* onionPtr, int onionLen, char* keyPtr, int keyLen, char* valPtr, int valLen); #ifdef __cplusplus } diff --git a/src/cwtchlib_go/bindings.rs b/src/cwtchlib_go/bindings.rs index aa967a6..5bbd780 100644 --- a/src/cwtchlib_go/bindings.rs +++ b/src/cwtchlib_go/bindings.rs @@ -1,4 +1,4 @@ -/* automatically generated by rust-bindgen 0.58.1 */ +/* automatically generated by rust-bindgen 0.59.2 */ #[derive(PartialEq, Copy, Clone, Hash, Debug, Default)] #[repr(C)] @@ -240,45 +240,32 @@ extern "C" { ); } extern "C" { - pub fn c_AcceptContact( + pub fn c_AcceptConversation( profilePtr: *mut ::std::os::raw::c_char, profileLen: ::std::os::raw::c_int, - handlePtr: *mut ::std::os::raw::c_char, - handleLen: ::std::os::raw::c_int, - ); -} -extern "C" { - pub fn c_RejectInvite( - profilePtr: *mut ::std::os::raw::c_char, - profileLen: ::std::os::raw::c_int, - handlePtr: *mut ::std::os::raw::c_char, - handleLen: ::std::os::raw::c_int, + conversation_id: ::std::os::raw::c_int, ); } extern "C" { pub fn c_BlockContact( profilePtr: *mut ::std::os::raw::c_char, profileLen: ::std::os::raw::c_int, - handlePtr: *mut ::std::os::raw::c_char, - handleLen: ::std::os::raw::c_int, - ); -} -extern "C" { - pub fn c_UpdateMessageFlags( - profile_ptr: *mut ::std::os::raw::c_char, - profile_len: ::std::os::raw::c_int, - handle_ptr: *mut ::std::os::raw::c_char, - handle_len: ::std::os::raw::c_int, - mIdx: ::std::os::raw::c_int, - message_flags: ::std::os::raw::c_ulong, + conversation_id: ::std::os::raw::c_int, ); } extern "C" { pub fn c_GetMessage( profile_ptr: *mut ::std::os::raw::c_char, profile_len: ::std::os::raw::c_int, - handle_ptr: *mut ::std::os::raw::c_char, - handle_len: ::std::os::raw::c_int, + conversation_id: ::std::os::raw::c_int, + message_index: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +extern "C" { + pub fn c_GetMessageByID( + profile_ptr: *mut ::std::os::raw::c_char, + profile_len: ::std::os::raw::c_int, + conversation_id: ::std::os::raw::c_int, message_index: ::std::os::raw::c_int, ) -> *mut ::std::os::raw::c_char; } @@ -286,8 +273,7 @@ extern "C" { pub fn c_GetMessagesByContentHash( profile_ptr: *mut ::std::os::raw::c_char, profile_len: ::std::os::raw::c_int, - handle_ptr: *mut ::std::os::raw::c_char, - handle_len: ::std::os::raw::c_int, + conversation_id: ::std::os::raw::c_int, contenthash_ptr: *mut ::std::os::raw::c_char, contenthash_len: ::std::os::raw::c_int, ) -> *mut ::std::os::raw::c_char; @@ -299,8 +285,7 @@ extern "C" { pub fn c_SendMessage( profile_ptr: *mut ::std::os::raw::c_char, profile_len: ::std::os::raw::c_int, - handle_ptr: *mut ::std::os::raw::c_char, - handle_len: ::std::os::raw::c_int, + conversation_id: ::std::os::raw::c_int, msg_ptr: *mut ::std::os::raw::c_char, msg_len: ::std::os::raw::c_int, ); @@ -309,10 +294,47 @@ extern "C" { pub fn c_SendInvitation( profile_ptr: *mut ::std::os::raw::c_char, profile_len: ::std::os::raw::c_int, - handle_ptr: *mut ::std::os::raw::c_char, - handle_len: ::std::os::raw::c_int, - target_ptr: *mut ::std::os::raw::c_char, - target_len: ::std::os::raw::c_int, + conversation_id: ::std::os::raw::c_int, + target_id: ::std::os::raw::c_int, + ); +} +extern "C" { + pub fn c_ShareFile( + profile_ptr: *mut ::std::os::raw::c_char, + profile_len: ::std::os::raw::c_int, + conversation_id: ::std::os::raw::c_int, + filepath_ptr: *mut ::std::os::raw::c_char, + filepath_len: ::std::os::raw::c_int, + ); +} +extern "C" { + pub fn c_DownloadFile( + profile_ptr: *mut ::std::os::raw::c_char, + profile_len: ::std::os::raw::c_int, + conversation_id: ::std::os::raw::c_int, + filepath_ptr: *mut ::std::os::raw::c_char, + filepath_len: ::std::os::raw::c_int, + manifestpath_ptr: *mut ::std::os::raw::c_char, + manifestpath_len: ::std::os::raw::c_int, + filekey_ptr: *mut ::std::os::raw::c_char, + filekey_len: ::std::os::raw::c_int, + ); +} +extern "C" { + pub fn c_CheckDownloadStatus( + profilePtr: *mut ::std::os::raw::c_char, + profileLen: ::std::os::raw::c_int, + fileKeyPtr: *mut ::std::os::raw::c_char, + fileKeyLen: ::std::os::raw::c_int, + ); +} +extern "C" { + pub fn c_VerifyOrResumeDownload( + profile_ptr: *mut ::std::os::raw::c_char, + profile_len: ::std::os::raw::c_int, + conversation_id: ::std::os::raw::c_int, + filekey_ptr: *mut ::std::os::raw::c_char, + filekey_len: ::std::os::raw::c_int, ); } extern "C" { @@ -340,16 +362,14 @@ extern "C" { pub fn c_ArchiveConversation( profile_ptr: *mut ::std::os::raw::c_char, profile_len: ::std::os::raw::c_int, - contact_ptr: *mut ::std::os::raw::c_char, - contact_len: ::std::os::raw::c_int, + conversation_id: ::std::os::raw::c_int, ); } extern "C" { pub fn c_DeleteContact( profile_ptr: *mut ::std::os::raw::c_char, profile_len: ::std::os::raw::c_int, - hanlde_ptr: *mut ::std::os::raw::c_char, - handle_len: ::std::os::raw::c_int, + conversation_id: ::std::os::raw::c_int, ); } extern "C" { @@ -371,11 +391,10 @@ extern "C" { ); } extern "C" { - pub fn c_SetContactAttribute( + pub fn c_SetConversationAttribute( profile_ptr: *mut ::std::os::raw::c_char, profile_len: ::std::os::raw::c_int, - contact_ptr: *mut ::std::os::raw::c_char, - contact_len: ::std::os::raw::c_int, + conversation_id: ::std::os::raw::c_int, key_ptr: *mut ::std::os::raw::c_char, key_len: ::std::os::raw::c_int, val_ptr: *mut ::std::os::raw::c_char, @@ -383,17 +402,78 @@ extern "C" { ); } extern "C" { - pub fn c_SetGroupAttribute( + pub fn c_SetMessageAttribute( profile_ptr: *mut ::std::os::raw::c_char, profile_len: ::std::os::raw::c_int, - group_ptr: *mut ::std::os::raw::c_char, - group_len: ::std::os::raw::c_int, + conversation_id: ::std::os::raw::c_int, + channel_id: ::std::os::raw::c_int, + message_id: ::std::os::raw::c_int, key_ptr: *mut ::std::os::raw::c_char, key_len: ::std::os::raw::c_int, val_ptr: *mut ::std::os::raw::c_char, val_len: ::std::os::raw::c_int, ); } +extern "C" { + pub fn c_ChangePassword( + profile_ptr: *mut ::std::os::raw::c_char, + profile_len: ::std::os::raw::c_int, + oldpassword_ptr: *mut ::std::os::raw::c_char, + oldpassword_len: ::std::os::raw::c_int, + newpassword_ptr: *mut ::std::os::raw::c_char, + newpassword_len: ::std::os::raw::c_int, + newpassword_again_ptr: *mut ::std::os::raw::c_char, + newpassword_again_len: ::std::os::raw::c_int, + ); +} extern "C" { pub fn c_ShutdownCwtch(); } +extern "C" { + pub fn c_LoadServers( + passwordPtr: *mut ::std::os::raw::c_char, + passwordLen: ::std::os::raw::c_int, + ); +} +extern "C" { + pub fn c_CreateServer( + passwordPtr: *mut ::std::os::raw::c_char, + passwordLen: ::std::os::raw::c_int, + descPtr: *mut ::std::os::raw::c_char, + descLen: ::std::os::raw::c_int, + autostart: ::std::os::raw::c_char, + ); +} +extern "C" { + pub fn c_DeleteServer( + onionPtr: *mut ::std::os::raw::c_char, + onionLen: ::std::os::raw::c_int, + currentPasswordPtr: *mut ::std::os::raw::c_char, + currentPasswordLen: ::std::os::raw::c_int, + ); +} +extern "C" { + pub fn c_LaunchServers(); +} +extern "C" { + pub fn c_LaunchServer(onionPtr: *mut ::std::os::raw::c_char, onionLen: ::std::os::raw::c_int); +} +extern "C" { + pub fn c_StopServer(onionPtr: *mut ::std::os::raw::c_char, onionLen: ::std::os::raw::c_int); +} +extern "C" { + pub fn c_StopServers(); +} +extern "C" { + pub fn c_DestroyServers(); +} +extern "C" { + pub fn c_SetServerAttribute( + onionPtr: *mut ::std::os::raw::c_char, + onionLen: ::std::os::raw::c_int, + keyPtr: *mut ::std::os::raw::c_char, + keyLen: ::std::os::raw::c_int, + valPtr: *mut ::std::os::raw::c_char, + valLen: ::std::os::raw::c_int, + ); +} From 3f25d8d829228afbde0f33a88ca852579890083a Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Sat, 15 Jan 2022 09:10:55 -0500 Subject: [PATCH 2/6] full lcg 1.5.2 api coverage --- Cargo.toml | 2 +- README.md | 4 +- examples/echobot.rs | 8 ++-- src/bindings_go.rs | 102 ++++++++++++++++++++++++----------------- src/cwtchlib_go/mod.rs | 1 + src/lib.rs | 92 +++++++++++++++++++++++++++---------- 6 files changed, 135 insertions(+), 74 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6f7122b..215df23 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,4 +13,4 @@ documentation = "https://docs.rs/libcwtch/0.1.0/libcwtch/" libc = "0.2" serde_json = "1.0" serde = { version = "1.0.127", features = ["derive"] } -serde_with = { version = "1.10.0" } +serde_with = { version = "1.10.0" } \ No newline at end of file diff --git a/README.md b/README.md index 81f3f5f..02df330 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Example echobot in examples/echobot.rs (`cargo run --example echobot` -- assumes ### Updating libCwtch and bingings.rs with Bindgen -``` +```sh cargo install bindgen ``` @@ -16,7 +16,7 @@ libCwtch.so version is specified in build.rs. If updating, also download the cor the 'preamble from import "C"' section as it imports headers required for the C lib to compile but that we don't want to create rust bindings for (like importing stdlib.h). Then: -``` +```sh bindgen libCwtch.h -o src/cwtchlib_go/bindings.rs ``` diff --git a/examples/echobot.rs b/examples/echobot.rs index d137566..d2fc292 100644 --- a/examples/echobot.rs +++ b/examples/echobot.rs @@ -6,7 +6,9 @@ use libcwtch::CwtchLib; fn main() { let bot_home = "example_cwtch_dir"; - std::fs::remove_dir_all(&bot_home).expect("Error removing previous bot_home directory"); + match std::fs::remove_dir_all(&bot_home) { + _ => () + } std::fs::create_dir_all(&bot_home).expect("Error creating bot_home directory"); let cwtch = libcwtch::new_cwtchlib_go(); @@ -45,14 +47,14 @@ fn main() { } "NewMessageFromPeer" => { let to = &event.data["ProfileOnion"]; - let conversation = &event.data["RemotePeer"]; + let conversation_id = event.data["ConversationID"].parse::().unwrap(); let message: Message = serde_json::from_str(&event.data["Data"]).expect("Error parsing message"); let response = Message { o: 1, d: message.d }; let response_json = serde_json::to_string(&response).expect("Error parsing json response"); - cwtch.send_message(&to, &conversation, &response_json); + cwtch.send_message(&to, conversation_id, &response_json); } _ => eprintln!("unhandled event!"), }; diff --git a/src/bindings_go.rs b/src/bindings_go.rs index 79b966b..af3239c 100644 --- a/src/bindings_go.rs +++ b/src/bindings_go.rs @@ -30,29 +30,31 @@ impl c_str_wrap { impl Drop for c_str_wrap { fn drop(&mut self) { unsafe { - CString::from_raw(self.raw); + drop(CString::from_raw(self.raw)); } } } // c_bind handles setting up c string arguments and freeing them -// c_bind!( $fn_name ( [ $string_args ]* ; [ $non_string_args : $type ]* ) $c_function -> $return_type? ) +// c_bind!( $fn_name ( [ $string_args: &str],* [ $non_string_args : $type ],* ) $c_function -> $return_type? ) macro_rules! c_bind { - // macro for returnless fns - ($func_name:ident ($($str:ident),* ; $($arg:ident: $t:ty),*) $bind_fn:ident) => { - fn $func_name(&self, $($str: &str, )* $($arg: $t, )*) { - $(let $str = c_str_wrap::new($str);)* + // No return + ($func_name:ident ($($str1:ident: &str),* ; $($args:ident: $t:ty),* ; $($str2:ident: &str),*) $bind_fn:ident) => { + fn $func_name(&self, $($str1: &str, )* $($args: $t, )* $($str2: &str, )*) { + $(let $str1 = c_str_wrap::new($str1);)* + $(let $str2 = c_str_wrap::new($str2);)* unsafe { - bindings::$bind_fn($( $str.raw, $str.len, )* $($arg,)* ); + bindings::$bind_fn($( $str1.raw, $str1.len, )* $($args,)* $( $str2.raw, $str2.len, )*); } } }; - // macro for str returning fns - ($func_name:ident ($($str:ident),* ; $($arg:ident: $t:ty),* ) $bind_fn:ident -> String) => { - fn $func_name(&self, $($str: &str, )* $($arg: $t, )*) -> String { - $(let $str = c_str_wrap::new($str);)* + // String return + ($func_name:ident ($($str1:ident: &str),* ; $($args:ident: $t:ty),* ; $($str2:ident: &str),*) $bind_fn:ident -> String) => { + fn $func_name(&self, $($str1: &str, )* $($args: $t, )* $($str2: &str, )*) -> String { + $(let $str1 = c_str_wrap::new($str1);)* + $(let $str2 = c_str_wrap::new($str2);)* unsafe { - let result_ptr = bindings::$bind_fn($( $str.raw, $str.len, )* $($arg,)* ); + let result_ptr = bindings::$bind_fn($( $str1.raw, $str1.len, )* $($args,)* $( $str2.raw, $str2.len, )*); let result = match CStr::from_ptr(result_ptr).to_str() { Ok(s) => s.to_owned(), Err(_) => "".to_string() @@ -63,12 +65,13 @@ macro_rules! c_bind { } } }; - // macro for value returning fns - ($func_name:ident ($($str:ident),* ; $($arg:ident: $t:ty),* ) $bind_fn:ident -> $bind_fn_ty:ty) => { - fn $func_name(&self, $($str: &str, )* $($arg: $t, )*) -> $bind_fn_ty { - $(let $str = c_str_wrap::new($str);)* + // Non String return + ($func_name:ident ($($str1:ident: &str),* ; $($args:ident: $t:ty),* ; $($str2:ident: &str),*) $bind_fn:ident -> $bind_fn_ty:ty) => { + fn $func_name(&self, $($str1: &str, )* $($args: t, )* $($str2: &str, )*) -> $bind_fn_ty { + $(let $str1 = c_str_wrap::new($str1);)* + $(let $str2 = c_str_wrap::new($str2);)* unsafe { - let result = bindings::$bind_fn($( $str.raw, $str.len, )* $($arg,)* ); + let result = bindings::$bind_fn($( $str1.raw, $str1.len, )* $($args,)* $( $str2.raw, $str2.len, )*); result } } @@ -77,41 +80,54 @@ macro_rules! c_bind { pub struct CwtchLibGo {} -impl CwtchLibGo { - c_bind!(send_profile_event(profile, event_json;) c_SendProfileEvent); -} - -impl CwtchLib for CwtchLibGo { - c_bind!(start_cwtch(app_dir, tor_path;) c_StartCwtch -> i32); - c_bind!(send_app_event(event_json;) c_SendAppEvent); - c_bind!(get_appbus_event(;) c_GetAppBusEvent -> String); - c_bind!(create_profile(nick, pass;) c_CreateProfile); - c_bind!(load_profiles(pass;) c_LoadProfiles); - c_bind!(accept_contact(profile, contact;) c_AcceptContact); - c_bind!(reject_invite(profile, contact;) c_RejectInvite); - c_bind!(block_contact(profile, contact;) c_BlockContact); - c_bind!(update_message_flags(profile, contact; message_id: i32, message_flags: u64) c_UpdateMessageFlags); - c_bind!(get_message(profile, contact; message_index: i32) c_GetMessage -> String); - c_bind!(get_message_by_content_hash(profile, contact, hash;) c_GetMessagesByContentHash -> String); - c_bind!(send_message(profile, contact, msg;) c_SendMessage); - c_bind!(send_invitation(profile, contact, target;) c_SendInvitation); +impl CwtchLib for CwtchLibGo { + c_bind!(start_cwtch(app_dir: &str, tor_path: &str;;) c_StartCwtch -> i32); + c_bind!(send_app_event(event_json: &str;;) c_SendAppEvent); + c_bind!(send_profile_event(profile: &str, event_jason: &str;;) c_SendProfileEvent); + c_bind!(get_appbus_event(;;) c_GetAppBusEvent -> String); + c_bind!(create_profile(nick: &str, pass: &str;;) c_CreateProfile); + c_bind!(load_profiles(pass: &str;;) c_LoadProfiles); + c_bind!(accept_conversation(profile: &str ; conversation_id: i32 ;) c_AcceptConversation); + c_bind!(block_contact(profile: &str ; conversation_id: i32; ) c_BlockContact); + // todo 1.5.3 + //c_bind!(unblock_contact(profile: &str ; conversation_id: i32; ) c_UnblockContact); + c_bind!(get_message(profile: &str; conversation_id: i32, message_index: i32 ;) c_GetMessage -> String); + c_bind!(get_message_by_id(profile: &str ; conversation_id: i32, message_id: i32 ;) c_GetMessageByID -> String); + c_bind!(get_message_by_content_hash(profile: &str ; conversation_id: i32 ; hash: &str) c_GetMessagesByContentHash -> String); + c_bind!(send_message(profile: &str; conversation_id: i32; msg: &str) c_SendMessage); + c_bind!(send_invitation(profile: &str; conversation_id: i32, target_id: i32;) c_SendInvitation); + c_bind!(share_file(profile: &str; conversation_id: i32; file_path: &str) c_ShareFile); + c_bind!(download_file(profile: &str; conversation_id: i32; file_path: &str, manifest_path: &str, file_key: &str) c_DownloadFile); + c_bind!(check_download_status(profile: &str, file_key: &str;;) c_CheckDownloadStatus); + c_bind!(verify_or_resume_download(profile: &str; conversation_id: i32; file_key: &str) c_VerifyOrResumeDownload); fn reset_tor(&self) { unsafe { bindings::c_ResetTor(); } } - c_bind!(create_group(profile, server, name;) c_CreateGroup); - c_bind!(delete_profile(profile, pass;) c_DeleteProfile); - c_bind!(archive_conversation(profile, contact;) c_ArchiveConversation); - c_bind!(delete_contact(profile, group;) c_DeleteContact); - c_bind!(import_bundle(profile, bundle;) c_ImportBundle); - c_bind!(set_profile_attribute(profile, key, val;) c_SetProfileAttribute); - c_bind!(set_contact_attribute(profile, contact, key, val;) c_SetContactAttribute); - c_bind!(set_group_attribute(profile, group, key, val;) c_SetGroupAttribute); + c_bind!(create_group(profile: &str, server: &str, name: &str;;) c_CreateGroup); + c_bind!(delete_profile(profile: &str, pass: &str;;) c_DeleteProfile); + c_bind!(archive_conversation(profile: &str; conversation_id: i32;) c_ArchiveConversation); + c_bind!(delete_contact(profile: &str; conversation_id: i32;) c_DeleteContact); + c_bind!(import_bundle(profile: &str, bundle: &str;;) c_ImportBundle); + c_bind!(set_profile_attribute(profile: &str, key: &str, val: &str;;) c_SetProfileAttribute); + c_bind!(set_conversation_attribute(profile: &str; conversation_id: i32; key: &str, val: &str) c_SetConversationAttribute); + c_bind!(set_message_attribute(profile: &str; conversation_id: i32, channel_id: i32, message_id: i32; key: &str, val: &str) c_SetMessageAttribute); + c_bind!(change_password(profile: &str, old_pass: &str, new_pass: &str, new_pass_again: &str;;) c_ChangePassword); fn shutdown_cwtch(&self) { unsafe { bindings::c_ShutdownCwtch(); } } + + c_bind!(load_servers(password: &str;;) c_LoadServers); + c_bind!(create_server(password: &str, description: &str; autostart: i8;) c_CreateServer); + c_bind!(delete_server(onion: &str, current_password: &str;;) c_DeleteServer); + c_bind!(launch_servers(;;) c_LaunchServers); + c_bind!(launch_server(onion: &str;;) c_LaunchServer); + c_bind!(stop_server(onion: &str;;) c_StopServer); + c_bind!(stop_servers(;;) c_StopServers); + c_bind!(destroy_servers(;;) c_DestroyServers); + c_bind!(set_server_attribute(onion: &str, key: &str, val: &str;;) c_SetServerAttribute); } diff --git a/src/cwtchlib_go/mod.rs b/src/cwtchlib_go/mod.rs index b11653b..52fb393 100644 --- a/src/cwtchlib_go/mod.rs +++ b/src/cwtchlib_go/mod.rs @@ -2,5 +2,6 @@ #![allow(non_camel_case_types)] #![allow(non_snake_case)] #![allow(dead_code)] +#![allow(deref_nullptr)] pub mod bindings; \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index c8c2016..70f5da0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,6 +17,9 @@ pub trait CwtchLib { /// Send json of a structs::CwtchEvent to the cwtch app bus fn send_app_event(&self, event_json: &str); + /// Send json of a structs::CwtchEvent to a cwtch profile + fn send_profile_event(&self, profile: &str, event_json: &str); + /// Pull json of a structs::CwtchEvent off the appbus for responding to fn get_appbus_event(&self) -> String; @@ -26,35 +29,42 @@ pub trait CwtchLib { /// Load any profiles encrypted by pass fn load_profiles(&self, pass: &str); - /// Cause profile to accept contact - fn accept_contact(&self, profile: &str, contact: &str); + /// Cause profile to accept conversation + fn accept_conversation(&self, profile: &str, conversation_id: i32); - /// Cause profile to reject contact - fn reject_invite(&self, profile: &str, contact: &str); + /// Cause profile to block conversation + fn block_contact(&self, profile: &str, conversation_id: i32); - /// Cause profile to block contact - fn block_contact(&self, profile: &str, contact: &str); + // TODO 1.5.3 + /// Cause profile to unblock contact + //fn unblock_contact(&self, profile: &str, conversation_id: i32); - /// Cause profile to update contact's message to have it's flags updated - fn update_message_flags( - &self, - profile: &str, - contact: &str, - message_id: i32, - message_flags: u64, - ); + /// Get a specific message for conversation of profile by index + fn get_message(&self, profile: &str, conversation_id: i32, message_index: i32) -> String; - /// Get a specific message for contact of profile by index - fn get_message(&self, profile: &str, contact: &str, message_index: i32) -> String; + /// Get a specific message for a conversation by its id + fn get_message_by_id(&self, profile: &str, conversation_id: i32, message_id: i32) -> String; - /// Get a specific message for contact of profile by hash - fn get_message_by_content_hash(&self, profile: &str, contact: &str, hash: &str) -> String; + /// Get a specific message for conversation of profile by hash + fn get_message_by_content_hash(&self, profile: &str, conversation_id: i32, hash: &str) -> String; /// Send json of a structs::Message from profile to contact - fn send_message(&self, profile: &str, contact: &str, msg: &str); + fn send_message(&self, profile: &str, conversation_id: i32, msg: &str); /// Send profile's contact an invite for/to target - fn send_invitation(&self, profile: &str, contact: &str, target: &str); + fn send_invitation(&self, profile: &str, conversation_id: i32, target_id: i32); + + /// share a file file_path with a conersation + fn share_file(&self, profile: &str, conversation_id: i32, file_path: &str); + + /// download a file from a conversation to the file_path + fn download_file(&self, profile: &str, conversation_id: i32, file_path: &str, manifest_path: &str, file_key: &str); + + /// Query the status of a download + fn check_download_status(&self, profile: &str, file_key: &str); + + /// Verufy a download is done, and if not, resume it + fn verify_or_resume_download(&self, profile: &str, conversation_id: i32, file_key: &str); /// Ask the ACN inside the Cwtch app to restart the tor connection fn reset_tor(&self); @@ -66,10 +76,10 @@ pub trait CwtchLib { fn delete_profile(&self, profile: &str, pass: &str); /// Cause profile to archive conversation with contact - fn archive_conversation(&self, profile: &str, contact: &str); + fn archive_conversation(&self, profile: &str, conversation_id: i32); /// Cause profile to delete contact/group identified by handle - fn delete_contact(&self, profile: &str, handle: &str); + fn delete_contact(&self, profile: &str, conversation_id: i32); /// Cuase profile to attempt to import a contact/group/keybundle identified by bundle fn import_bundle(&self, profile: &str, bundle: &str); @@ -78,13 +88,45 @@ pub trait CwtchLib { fn set_profile_attribute(&self, profile: &str, key: &str, val: &str); /// Set a profile's contact's attribute of key to val - fn set_contact_attribute(&self, profile: &str, contact: &str, key: &str, val: &str); + fn set_conversation_attribute(&self, profile: &str, conversation_id: i32, key: &str, val: &str); - /// Set a profile's group's attribute of key to val - fn set_group_attribute(&self, profile: &str, group: &str, key: &str, val: &str); + /// Set an attribute on a message in a conversation + fn set_message_attribute(&self, profile: &str, conversation_id: i32, channel_id: i32, message_id: i32, attribute_key: &str, attribute_value: &str); + + /// Change a profile's password to new_pass if old_pass is correct + fn change_password(&self, profile: &str, old_pass: &str, new_pass: &str, new_pass_again: &str); /// Shutdown the cwtch app and associated ACN fn shutdown_cwtch(&self); + + /// Server functions require server experiment to be enabled + + /// Load all servers encrypted by password + fn load_servers(&self, password: &str); + + /// Create a new server, encrypted with password, autostart i8 used as bool + fn create_server(&self, password: &str, description: &str, autostart: i8); + + /// Delete the specified server (if password is correct) + fn delete_server(&self, onion: &str, current_password: &str); + + /// Launch all loaded servers + fn launch_servers(&self); + + /// Launch the specified server + fn launch_server(&self, onion: &str); + + /// Stop the specified server + fn stop_server(&self, onion: &str); + + /// Stop all running servers + fn stop_servers(&self); + + /// Destroy all servers leaving htem un-re-runnable. call only on shutdown + fn destroy_servers(&self); + + /// Set the specified server's attribute of key to val + fn set_server_attribute(&self, onion: &str, key: &str, val: &str); } /// Create a new CwtchLib that is backed by bindings to libcwtch-go From 5db5208a54bb79790f7035ba43aa16784d434995 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Sun, 16 Jan 2022 14:00:21 -0500 Subject: [PATCH 3/6] lcg 1.5.2 to 1.5.4 unblock_contact() --- build.rs | 4 ++-- libCwtch.h | 2 +- src/bindings_go.rs | 3 +-- src/cwtchlib_go/bindings.rs | 7 +++++++ src/lib.rs | 3 +-- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/build.rs b/build.rs index d7379d4..f8d4825 100644 --- a/build.rs +++ b/build.rs @@ -11,6 +11,6 @@ fn main() { println!("cargo:rerun-if-changed=libCwtch.h"); let lib_cwtch_path = Path::new(&out_dir).join("libCwtch.so"); - // https://git.openprivacy.ca/cwtch.im/libcwtch-go/releases v1.5.2 - Command::new("wget").arg("https://git.openprivacy.ca/attachments/3e563341-c206-4e69-98e3-e0dca449f947").arg("-O").arg(lib_cwtch_path).output().expect("failed to download libCwtch.so"); + // https://git.openprivacy.ca/cwtch.im/libcwtch-go/releases v1.5.4 + Command::new("wget").arg("https://git.openprivacy.ca/attachments/dd3c6b41-98e4-4e7b-81af-d21893bfe389").arg("-O").arg(lib_cwtch_path).output().expect("failed to download libCwtch.so"); } \ No newline at end of file diff --git a/libCwtch.h b/libCwtch.h index 70c2395..de34689 100644 --- a/libCwtch.h +++ b/libCwtch.h @@ -16,7 +16,6 @@ typedef struct { const char *p; ptrdiff_t n; } _GoString_; #endif - /* Start of boilerplate cgo prologue. */ #line 1 "cgo-gcc-export-header-prolog" @@ -76,6 +75,7 @@ extern void c_CreateProfile(char* nick_ptr, int nick_len, char* pass_ptr, int pa extern void c_LoadProfiles(char* passwordPtr, int passwordLen); extern void c_AcceptConversation(char* profilePtr, int profileLen, int conversation_id); extern void c_BlockContact(char* profilePtr, int profileLen, int conversation_id); +extern void c_UnblockContact(char* profilePtr, int profileLen, int conversation_id); // the pointer returned from this function **must** be Freed by c_Free extern char* c_GetMessage(char* profile_ptr, int profile_len, int conversation_id, int message_index); diff --git a/src/bindings_go.rs b/src/bindings_go.rs index af3239c..9f28e4d 100644 --- a/src/bindings_go.rs +++ b/src/bindings_go.rs @@ -89,8 +89,7 @@ impl CwtchLib for CwtchLibGo { c_bind!(load_profiles(pass: &str;;) c_LoadProfiles); c_bind!(accept_conversation(profile: &str ; conversation_id: i32 ;) c_AcceptConversation); c_bind!(block_contact(profile: &str ; conversation_id: i32; ) c_BlockContact); - // todo 1.5.3 - //c_bind!(unblock_contact(profile: &str ; conversation_id: i32; ) c_UnblockContact); + c_bind!(unblock_contact(profile: &str ; conversation_id: i32; ) c_UnblockContact); c_bind!(get_message(profile: &str; conversation_id: i32, message_index: i32 ;) c_GetMessage -> String); c_bind!(get_message_by_id(profile: &str ; conversation_id: i32, message_id: i32 ;) c_GetMessageByID -> String); c_bind!(get_message_by_content_hash(profile: &str ; conversation_id: i32 ; hash: &str) c_GetMessagesByContentHash -> String); diff --git a/src/cwtchlib_go/bindings.rs b/src/cwtchlib_go/bindings.rs index 5bbd780..cd4ab52 100644 --- a/src/cwtchlib_go/bindings.rs +++ b/src/cwtchlib_go/bindings.rs @@ -253,6 +253,13 @@ extern "C" { conversation_id: ::std::os::raw::c_int, ); } +extern "C" { + pub fn c_UnblockContact( + profilePtr: *mut ::std::os::raw::c_char, + profileLen: ::std::os::raw::c_int, + conversation_id: ::std::os::raw::c_int, + ); +} extern "C" { pub fn c_GetMessage( profile_ptr: *mut ::std::os::raw::c_char, diff --git a/src/lib.rs b/src/lib.rs index 70f5da0..6f16913 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,9 +35,8 @@ pub trait CwtchLib { /// Cause profile to block conversation fn block_contact(&self, profile: &str, conversation_id: i32); - // TODO 1.5.3 /// Cause profile to unblock contact - //fn unblock_contact(&self, profile: &str, conversation_id: i32); + fn unblock_contact(&self, profile: &str, conversation_id: i32); /// Get a specific message for conversation of profile by index fn get_message(&self, profile: &str, conversation_id: i32, message_index: i32) -> String; From a28813fb2ee249d73ce88c9606a07abba3347d7a Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Sun, 16 Jan 2022 14:06:30 -0500 Subject: [PATCH 4/6] rust fmt --- build.rs | 11 ++++++++--- examples/echobot.rs | 2 +- src/bindings_go.rs | 2 +- src/cwtchlib_go/mod.rs | 2 +- src/lib.rs | 26 +++++++++++++++++++++++--- 5 files changed, 34 insertions(+), 9 deletions(-) diff --git a/build.rs b/build.rs index f8d4825..6a64a47 100644 --- a/build.rs +++ b/build.rs @@ -1,6 +1,6 @@ -use std::process::Command; use std::env; use std::path::Path; +use std::process::Command; fn main() { let out_dir = env::var_os("OUT_DIR").unwrap(); @@ -12,5 +12,10 @@ fn main() { let lib_cwtch_path = Path::new(&out_dir).join("libCwtch.so"); // https://git.openprivacy.ca/cwtch.im/libcwtch-go/releases v1.5.4 - Command::new("wget").arg("https://git.openprivacy.ca/attachments/dd3c6b41-98e4-4e7b-81af-d21893bfe389").arg("-O").arg(lib_cwtch_path).output().expect("failed to download libCwtch.so"); -} \ No newline at end of file + Command::new("wget") + .arg("https://git.openprivacy.ca/attachments/dd3c6b41-98e4-4e7b-81af-d21893bfe389") + .arg("-O") + .arg(lib_cwtch_path) + .output() + .expect("failed to download libCwtch.so"); +} diff --git a/examples/echobot.rs b/examples/echobot.rs index d2fc292..fb0aef3 100644 --- a/examples/echobot.rs +++ b/examples/echobot.rs @@ -7,7 +7,7 @@ use libcwtch::CwtchLib; fn main() { let bot_home = "example_cwtch_dir"; match std::fs::remove_dir_all(&bot_home) { - _ => () + _ => (), } std::fs::create_dir_all(&bot_home).expect("Error creating bot_home directory"); diff --git a/src/bindings_go.rs b/src/bindings_go.rs index 9f28e4d..ed1610d 100644 --- a/src/bindings_go.rs +++ b/src/bindings_go.rs @@ -80,7 +80,7 @@ macro_rules! c_bind { pub struct CwtchLibGo {} -impl CwtchLib for CwtchLibGo { +impl CwtchLib for CwtchLibGo { c_bind!(start_cwtch(app_dir: &str, tor_path: &str;;) c_StartCwtch -> i32); c_bind!(send_app_event(event_json: &str;;) c_SendAppEvent); c_bind!(send_profile_event(profile: &str, event_jason: &str;;) c_SendProfileEvent); diff --git a/src/cwtchlib_go/mod.rs b/src/cwtchlib_go/mod.rs index 52fb393..df69845 100644 --- a/src/cwtchlib_go/mod.rs +++ b/src/cwtchlib_go/mod.rs @@ -4,4 +4,4 @@ #![allow(dead_code)] #![allow(deref_nullptr)] -pub mod bindings; \ No newline at end of file +pub mod bindings; diff --git a/src/lib.rs b/src/lib.rs index 6f16913..2bd6cbc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -45,7 +45,12 @@ pub trait CwtchLib { fn get_message_by_id(&self, profile: &str, conversation_id: i32, message_id: i32) -> String; /// Get a specific message for conversation of profile by hash - fn get_message_by_content_hash(&self, profile: &str, conversation_id: i32, hash: &str) -> String; + fn get_message_by_content_hash( + &self, + profile: &str, + conversation_id: i32, + hash: &str, + ) -> String; /// Send json of a structs::Message from profile to contact fn send_message(&self, profile: &str, conversation_id: i32, msg: &str); @@ -57,7 +62,14 @@ pub trait CwtchLib { fn share_file(&self, profile: &str, conversation_id: i32, file_path: &str); /// download a file from a conversation to the file_path - fn download_file(&self, profile: &str, conversation_id: i32, file_path: &str, manifest_path: &str, file_key: &str); + fn download_file( + &self, + profile: &str, + conversation_id: i32, + file_path: &str, + manifest_path: &str, + file_key: &str, + ); /// Query the status of a download fn check_download_status(&self, profile: &str, file_key: &str); @@ -90,7 +102,15 @@ pub trait CwtchLib { fn set_conversation_attribute(&self, profile: &str, conversation_id: i32, key: &str, val: &str); /// Set an attribute on a message in a conversation - fn set_message_attribute(&self, profile: &str, conversation_id: i32, channel_id: i32, message_id: i32, attribute_key: &str, attribute_value: &str); + fn set_message_attribute( + &self, + profile: &str, + conversation_id: i32, + channel_id: i32, + message_id: i32, + attribute_key: &str, + attribute_value: &str, + ); /// Change a profile's password to new_pass if old_pass is correct fn change_password(&self, profile: &str, old_pass: &str, new_pass: &str, new_pass_again: &str); From 2d4e7bb751f09722556a39b5ba3cd4be456cb44a Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Sun, 16 Jan 2022 14:24:22 -0500 Subject: [PATCH 5/6] structs use Result to propagate deserialization errors as per issue #4 --- examples/echobot.rs | 7 +++++-- src/structs.rs | 38 +++++++++++++++++++++++++------------- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/examples/echobot.rs b/examples/echobot.rs index fb0aef3..82f91da 100644 --- a/examples/echobot.rs +++ b/examples/echobot.rs @@ -36,13 +36,16 @@ fn main() { ); // process json for profile, contacts and servers...else { - let profile = Profile::new( + let profile = match Profile::new( &event.data["Identity"], &event.data["name"], &event.data["picture"], &event.data["ContactsJson"], &event.data["ServerList"], - ); + ) { + Ok(p) => p, + Err(e) => panic!("error parsing profile: {}", e) + }; print!("profile: {:?}", profile); } "NewMessageFromPeer" => { diff --git a/src/structs.rs b/src/structs.rs index 12d6ee3..7dd7fb7 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -119,41 +119,53 @@ impl Profile { picture: &str, contacts_json: &str, server_list: &str, - ) -> Profile { - let contacts = Profile::process_contacts(contacts_json); - let servers = Profile::process_servers(server_list); - Profile { + ) -> Result { + let contacts = match Profile::process_contacts(contacts_json){ + Ok(c) => c, + Err(e) => return Err(e) + }; + let servers = match Profile::process_servers(server_list) { + Ok(s) => s, + Err(e) => return Err(e) + }; + Ok(Profile { onion: identity.to_string(), nick: name.to_string(), image_path: picture.to_string(), attr: Default::default(), contacts: contacts, servers: servers, - } + }) } - fn process_contacts(constacts_json: &str) -> HashMap { + fn process_contacts(constacts_json: &str) -> Result, String> { let mut contacts: HashMap = HashMap::new(); if constacts_json == "null" { - return contacts; + return Ok(contacts); } println!("contacts_json: '{}'", constacts_json); - let contacts_map: Vec = serde_json::from_str(constacts_json).unwrap(); + let contacts_map: Vec = match serde_json::from_str(constacts_json) { + Ok(cm) => cm, + Err(e) => return Err(format!("invalid json: {:?}", e)) + }; for contact in contacts_map { contacts.insert(contact.onion.clone(), contact); } - contacts + Ok(contacts) } - fn process_servers(servers_json: &str) -> HashMap { + fn process_servers(servers_json: &str) -> Result, String> { let mut servers: HashMap = HashMap::new(); if servers_json == "null" { - return servers; + return Ok(servers); } - let servers_map: Vec = serde_json::from_str(servers_json).unwrap(); + let servers_map: Vec = match serde_json::from_str(servers_json) { + Ok(sm) => sm, + Err(e) => return Err(format!("invalid jason: {:?}", e)) + }; for server in servers_map { servers.insert(server.onion.clone(), server); } - servers + Ok(servers) } } From 81fbfdd15152ba97fa3d9150f910b91d56aecd41 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Mon, 17 Jan 2022 18:24:58 -0500 Subject: [PATCH 6/6] rm Cargo.lock for lib; add sha512 check to build fetch; typo --- .gitignore | 1 + Cargo.lock | 179 -------------------------------------------- Cargo.toml | 6 +- build.rs | 14 +++- examples/echobot.rs | 3 +- src/structs.rs | 10 +-- 6 files changed, 26 insertions(+), 187 deletions(-) delete mode 100644 Cargo.lock diff --git a/.gitignore b/.gitignore index 42e9ee0..4cb020c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target .idea example_cwtch_dir +Cargo.lock diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index 002e88b..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,179 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "darling" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "757c0ded2af11d8e739c4daea1ac623dd1624b06c844cf3f5a39f1bdbd99bb12" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c34d8efb62d0c2d7f60ece80f75e5c63c1588ba68032740494b0b9a996466e3" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn", -] - -[[package]] -name = "darling_macro" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade7bff147130fe5e6d39f089c6bd49ec0250f35d70b2eebf72afdfc919f15cc" -dependencies = [ - "darling_core", - "quote", - "syn", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "itoa" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" - -[[package]] -name = "libc" -version = "0.2.98" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" - -[[package]] -name = "libcwtch" -version = "0.1.0" -dependencies = [ - "libc", - "serde", - "serde_json", - "serde_with", -] - -[[package]] -name = "proc-macro2" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "quote" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rustversion" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088" - -[[package]] -name = "ryu" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" - -[[package]] -name = "serde" -version = "1.0.127" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.127" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_with" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "062b87e45d8f26714eacfaef0ed9a583e2bfd50ebd96bdd3c200733bd5758e2c" -dependencies = [ - "rustversion", - "serde", - "serde_with_macros", -] - -[[package]] -name = "serde_with_macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98c1fcca18d55d1763e1c16873c4bde0ac3ef75179a28c7b372917e0494625be" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "syn" -version = "1.0.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" diff --git a/Cargo.toml b/Cargo.toml index 215df23..ea8de05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,8 +9,12 @@ repository = "https://git.openprivacy.ca/cwtch.im/libcwtch-rs" readme = "README.md" documentation = "https://docs.rs/libcwtch/0.1.0/libcwtch/" +[build-dependencies] +hex-literal = "0.3.4" +sha2 = "0.10.1" + [dependencies] libc = "0.2" serde_json = "1.0" serde = { version = "1.0.127", features = ["derive"] } -serde_with = { version = "1.10.0" } \ No newline at end of file +serde_with = { version = "1.10.0" } diff --git a/build.rs b/build.rs index 6a64a47..0267d14 100644 --- a/build.rs +++ b/build.rs @@ -1,6 +1,10 @@ -use std::env; +use std::fs; use std::path::Path; use std::process::Command; +use std::{env, io}; + +use hex_literal::hex; +use sha2::{Digest, Sha512}; fn main() { let out_dir = env::var_os("OUT_DIR").unwrap(); @@ -18,4 +22,12 @@ fn main() { .arg(lib_cwtch_path) .output() .expect("failed to download libCwtch.so"); + + let lib_cwtch_path = Path::new(&out_dir).join("libCwtch.so"); + let mut hasher = Sha512::new(); + let mut file = fs::File::open(&lib_cwtch_path).expect("could not open lib to hash"); + io::copy(&mut file, &mut hasher).expect("failed to copy file into hasher"); + let hash_bytes = hasher.finalize(); + + assert_eq!(hash_bytes[..], hex!("776a26076dfad3370d1b2edec9ad954187584f54483ec201163be0dc356c10b0fe74168e8e95f2116f458e5676e1fb07fbd0357cab1e4389ac762fe03bd5ef67")[..]); } diff --git a/examples/echobot.rs b/examples/echobot.rs index 82f91da..93f8b40 100644 --- a/examples/echobot.rs +++ b/examples/echobot.rs @@ -7,6 +7,7 @@ use libcwtch::CwtchLib; fn main() { let bot_home = "example_cwtch_dir"; match std::fs::remove_dir_all(&bot_home) { + // this will always error on first run as we haven't created the directory, it's just a function to clear it on successive runs, so this error is to be ignored _ => (), } std::fs::create_dir_all(&bot_home).expect("Error creating bot_home directory"); @@ -44,7 +45,7 @@ fn main() { &event.data["ServerList"], ) { Ok(p) => p, - Err(e) => panic!("error parsing profile: {}", e) + Err(e) => panic!("error parsing profile: {}", e), }; print!("profile: {:?}", profile); } diff --git a/src/structs.rs b/src/structs.rs index 7dd7fb7..6634370 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -120,13 +120,13 @@ impl Profile { contacts_json: &str, server_list: &str, ) -> Result { - let contacts = match Profile::process_contacts(contacts_json){ + let contacts = match Profile::process_contacts(contacts_json) { Ok(c) => c, - Err(e) => return Err(e) + Err(e) => return Err(e), }; let servers = match Profile::process_servers(server_list) { Ok(s) => s, - Err(e) => return Err(e) + Err(e) => return Err(e), }; Ok(Profile { onion: identity.to_string(), @@ -146,7 +146,7 @@ impl Profile { println!("contacts_json: '{}'", constacts_json); let contacts_map: Vec = match serde_json::from_str(constacts_json) { Ok(cm) => cm, - Err(e) => return Err(format!("invalid json: {:?}", e)) + Err(e) => return Err(format!("invalid json: {:?}", e)), }; for contact in contacts_map { contacts.insert(contact.onion.clone(), contact); @@ -161,7 +161,7 @@ impl Profile { } let servers_map: Vec = match serde_json::from_str(servers_json) { Ok(sm) => sm, - Err(e) => return Err(format!("invalid jason: {:?}", e)) + Err(e) => return Err(format!("invalid json: {:?}", e)), }; for server in servers_map { servers.insert(server.onion.clone(), server);