-
-
Save txdv/460b59f487567ae6861c to your computer and use it in GitHub Desktop.
libotr usage example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <assert.h> | |
#include <gcrypt.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <libotr/proto.h> | |
#include <libotr/userstate.h> | |
#include <libotr/message.h> | |
#include <libotr/privkey.h> | |
static int file_exists(const char *fname) | |
{ | |
return access(fname, F_OK) != -1; | |
} | |
static void print_hex(char *string) | |
{ | |
int i; | |
for (i = 0; i < strlen(string); i++) { | |
printf("%x", string[i]); | |
} | |
printf("\n"); | |
} | |
static void print_hexa(char *name, char *value) | |
{ | |
printf("%s = '%s'\n", name, value); | |
printf("%s = 0x", name); | |
print_hex(value); | |
} | |
#define PRINT(var) print_hexa(#var, var); | |
OtrlUserState tst1_userstate; | |
OtrlUserState tst2_userstate; | |
OtrlMessageAppOps ui_ops ; | |
OtrlUserState get_userstate(const char *username) | |
{ | |
if (strcmp(username, "tst1")) { | |
return tst1_userstate; | |
} else if(strcmp(username, "tst2")) { | |
return tst2_userstate; | |
} else { | |
/* we really want to blow up so an error is visible immediately */ | |
assert(0); | |
return NULL; | |
} | |
} | |
void load_file(const char *account, const char *fname) | |
{ | |
printf("Generating '%s'\n", fname); | |
if (file_exists(fname)) { | |
otrl_privkey_read(get_userstate(account), fname); | |
} else { | |
otrl_privkey_generate(get_userstate(account), fname, account, "xmpp"); | |
} | |
} | |
static OtrlPolicy policy_cb(void *opdata, ConnContext *context) | |
{ | |
printf("policy_cb\n"); | |
return OTRL_POLICY_DEFAULT; | |
} | |
static void create_privkey_cb(void *opdata, const char *accountname, | |
const char *protocol) | |
{ | |
char *filename = malloc(snprintf(NULL, 0, "keys_%s.txt", accountname) + 1); | |
sprintf(filename, "keys_%s.txt", accountname); | |
printf("create_privkey_cb\n"); | |
printf("account = %s\n", accountname); | |
printf("filename = %s\n", filename); | |
otrl_privkey_generate(get_userstate(accountname), filename, accountname, protocol); | |
otrl_privkey_read(get_userstate(accountname), filename); | |
printf("key generated\n"); | |
} | |
static int is_logged_in_cb(void *opdata, const char *accountname, | |
const char *protocol, const char *recipient) | |
{ | |
printf("is_online_cb\n"); | |
return -1; | |
} | |
static void inject_message_cb(void *opdata, const char *accountname, | |
const char *protocol, const char *recipient, const char *message) | |
{ | |
printf("inject_message_cb\n"); | |
printf("from = %s\n", accountname); | |
printf("to = %s\n", recipient); | |
printf("message = '%s'\n", message); | |
char *msg_decrypt = NULL; | |
int intern_message; | |
intern_message = otrl_message_receiving( | |
get_userstate(recipient), | |
&ui_ops, | |
NULL, | |
recipient, | |
protocol, | |
accountname, | |
message, | |
&msg_decrypt, | |
NULL, | |
NULL, | |
NULL, | |
NULL | |
); | |
printf("decrypted msg = '%s'\n", msg_decrypt); | |
printf("err = %i\n", intern_message); | |
} | |
static void update_context_list_cb(void *opdata) | |
{ | |
printf("update_context_list_cb\n"); | |
} | |
static void new_fingerprint_cb(void *opdata, OtrlUserState us, | |
const char *accountname, const char *protocol, const char *username, | |
unsigned char fingerprint[20]) | |
{ | |
printf("new_fingerprint_cb\n"); | |
} | |
static void write_fingerprints_cb(void *opdata) | |
{ | |
printf("write_fingerprints_cb\n"); | |
} | |
static void gone_secure_cb(void *opdata, ConnContext *context) { | |
printf(" -> gone_secure_cb\n"); | |
return; | |
} | |
static void gone_insecure_cb(void *opdata, ConnContext *context) | |
{ | |
printf("gone_insecure_cb\n"); | |
} | |
static void still_secure_cb(void *opdata, ConnContext *context, int is_reply) | |
{ | |
printf("still_secure_cb\n"); | |
} | |
static int max_message_size_cb(void *opdata, ConnContext *context) | |
{ | |
printf("max_message_size_cb\n"); | |
return 512; | |
} | |
static const char *account_name_cb(void *opdata, const char *account_name, const char *protocol) | |
{ | |
printf("account_name_cb\n"); | |
return 0; | |
} | |
static void account_name_free_cb(void *opdata, const char *account_name) | |
{ | |
printf("account_name_cb\n"); | |
} | |
static void received_symkey_cb(void *opdata, ConnContext *context, unsigned int use, const unsigned char *usedata, size_t usedatalen, const unsigned char *symkey) | |
{ | |
printf("received_symkey_cb\n"); | |
} | |
static const char *otr_error_message_cb(void *opdata, ConnContext *context, OtrlErrorCode err_code) | |
{ | |
printf("otr_error_message_cb\n"); | |
printf("OtrlErrorCode = %i\n", err_code); | |
return 0; | |
} | |
static void otr_error_message_free_cb(void *opdata, const char *err_msg) | |
{ | |
printf("otr_error_message_free\n"); | |
} | |
static const char *resent_msg_prefix_cb(void *opdata, ConnContext *context) | |
{ | |
printf("resent_msg_prefix\n"); | |
return NULL; | |
} | |
static void resent_msg_prefix_free_cb(void *opdata, const char *prefix) | |
{ | |
printf("otr_error_message_free\n"); | |
} | |
static void handle_smp_event_cb(void *opdata, OtrlSMPEvent smp_event, ConnContext *context, unsigned short progress_percent, char *question) | |
{ | |
printf("handle_smp_event\n"); | |
} | |
static void handle_msg_event_cb(void *opdata, OtrlMessageEvent msg_event, ConnContext *context, const char *message, gcry_error_t err) | |
{ | |
printf("handle_msg_event\n"); | |
} | |
static void create_instag(void *opdata, const char *accountname, const char *protocol) | |
{ | |
printf("create_instag(accountname=\"%s\", protocol=\"%s\")\n", accountname, protocol); | |
} | |
static void convert_msg(void *opdata, ConnContext *context, OtrlConvertType convert_type, char **dest, const char *src) | |
{ | |
printf("convert_msg\n"); | |
} | |
static void convert_free(void *opdata, ConnContext *context, char *dest) | |
{ | |
printf("convert_free\n"); | |
} | |
OtrlMessageAppOps ui_ops = { | |
policy_cb, | |
create_privkey_cb, | |
is_logged_in_cb, | |
inject_message_cb, | |
update_context_list_cb, | |
new_fingerprint_cb, | |
write_fingerprints_cb, | |
gone_secure_cb, | |
gone_insecure_cb, | |
still_secure_cb, | |
max_message_size_cb, | |
account_name_cb, | |
account_name_free_cb, | |
received_symkey_cb, | |
otr_error_message_cb, | |
otr_error_message_free_cb, | |
resent_msg_prefix_cb, | |
resent_msg_prefix_free_cb, | |
handle_smp_event_cb, | |
handle_msg_event_cb, | |
create_instag, | |
convert_msg, | |
convert_free | |
}; | |
const char *keys_tst1 = "keys_tst1.txt"; | |
const char *keys_tst2 = "keys_tst2.txt"; | |
int main() { | |
OTRL_INIT; | |
tst1_userstate = otrl_userstate_create(); | |
tst2_userstate = otrl_userstate_create(); | |
load_file("tst1", keys_tst1); | |
load_file("tst2", keys_tst2); | |
otrl_privkey_read_fingerprints(get_userstate("tst1"), "fingerprints1.txt", | |
NULL, NULL); | |
otrl_privkey_read_fingerprints(get_userstate("tst2"), "fingerprints2.txt", | |
NULL, NULL); | |
gcry_error_t err; | |
int ignore_message; // if a message is protocol intern this gets true and msg can be ignored by the client | |
char *msg1_plain = "message 1"; | |
char *msg1_crypt = NULL; | |
char *msg1_decrypt = NULL; | |
printf("sending\n"); | |
err = otrl_message_sending( | |
get_userstate("tst1"), | |
&ui_ops, | |
NULL, | |
"tst1", | |
"xmpp", | |
"tst2", | |
OTRL_INSTAG_BEST, | |
msg1_plain, | |
NULL, | |
&msg1_crypt, | |
OTRL_FRAGMENT_SEND_SKIP, | |
NULL, | |
NULL, | |
NULL | |
); | |
if (!err == GPG_ERR_NO_ERROR) { | |
printf("something went wrong during encrypting\n"); | |
} | |
/* | |
it seems like the first message is not encrypted at first | |
but if you look closely, you will notice that there is a | |
0x2092020999920920920920202020992020920202099202099 | |
attached to the end of it. printf just returns | |
empty spaces for that, so you have print the hex | |
version of it | |
*/ | |
PRINT(msg1_plain); | |
PRINT(msg1_crypt); | |
printf("receiving\n"); | |
ignore_message = otrl_message_receiving( | |
get_userstate("tst2"), | |
&ui_ops, | |
NULL, | |
"tst2", | |
"xmpp", | |
"tst1", | |
msg1_crypt, | |
&msg1_decrypt, | |
NULL, | |
NULL, | |
NULL, | |
NULL | |
); | |
printf("msg_1_decrypt = '%s'\n", msg1_decrypt); | |
char* msg2_plain = "this schould be OTR stuff jessss:)!!!!!:))))))"; | |
char* msg2_crypt = NULL; | |
char* msg2_decrypt = NULL; | |
err = otrl_message_sending( | |
get_userstate("tst1"), | |
&ui_ops, | |
NULL, | |
"tst1", | |
"xmpp", | |
"tst2", | |
OTRL_INSTAG_BEST, | |
msg2_plain, | |
NULL, | |
&msg2_crypt, | |
OTRL_FRAGMENT_SEND_SKIP, | |
NULL, | |
NULL, | |
NULL | |
); | |
if (!err == GPG_ERR_NO_ERROR) { | |
printf("something went wrong during encrypting\n"); | |
} | |
PRINT(msg2_plain); | |
PRINT(msg2_crypt); | |
ignore_message = otrl_message_receiving( | |
get_userstate("tst2"), | |
&ui_ops, | |
NULL, | |
"tst2", | |
"xmpp", | |
"tst1", | |
msg2_crypt, | |
&msg2_decrypt, | |
NULL, | |
NULL, | |
NULL, | |
NULL | |
); | |
printf("msg2_decrypt = %s\n", msg2_decrypt); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
all: example | |
example: example.c | |
gcc example.c -lotr -o example | |
.PHONY: clean | |
clean: | |
rm -f example | |
run: example | |
./example |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment