Mercurial > ~mikael > mcabber > hg
comparison mcabber/src/otr.c @ 1598:a087125d8fc8
Replace libjabber with loudmouth
author | franky |
---|---|
date | Sun, 11 Oct 2009 15:38:32 +0200 |
parents | 18069a9dca4a |
children | dcd5d4c75199 |
comparison
equal
deleted
inserted
replaced
1597:4f59a414217e | 1598:a087125d8fc8 |
---|---|
22 #include <config.h> | 22 #include <config.h> |
23 #include <glib.h> | 23 #include <glib.h> |
24 | 24 |
25 #ifdef HAVE_LIBOTR | 25 #ifdef HAVE_LIBOTR |
26 | 26 |
27 #include "hbuf.h" | |
28 #include "logprint.h" | |
29 #include "nohtml.h" | |
27 #include "otr.h" | 30 #include "otr.h" |
28 #include "logprint.h" | |
29 #include "hbuf.h" | |
30 #include "jab_priv.h" | |
31 #include "roster.h" | 31 #include "roster.h" |
32 #include "utils.h" | |
33 #include "screen.h" | 32 #include "screen.h" |
34 #include "settings.h" | 33 #include "settings.h" |
35 #include "nohtml.h" | 34 #include "utils.h" |
35 #include "xmpp.h" | |
36 | 36 |
37 #define OTR_PROTOCOL_NAME "jabber" | 37 #define OTR_PROTOCOL_NAME "jabber" |
38 | 38 |
39 static OtrlUserState userstate = NULL; | 39 static OtrlUserState userstate = NULL; |
40 static char * account = NULL; | 40 static char *account = NULL; |
41 static char * keyfile = NULL; | 41 static char *keyfile = NULL; |
42 static char * fprfile = NULL; | 42 static char *fprfile = NULL; |
43 | 43 |
44 static int otr_is_enabled = FALSE; | 44 static int otr_is_enabled = FALSE; |
45 | 45 |
46 static OtrlPolicy cb_policy (void *opdata, ConnContext *ctx); | 46 static OtrlPolicy cb_policy (void *opdata, ConnContext *ctx); |
47 static void cb_create_privkey (void *opdata, | 47 static void cb_create_privkey (void *opdata, |
107 NULL, /*account_name*/ | 107 NULL, /*account_name*/ |
108 NULL /*account_name_free*/ | 108 NULL /*account_name_free*/ |
109 }; | 109 }; |
110 | 110 |
111 static void otr_message_disconnect(ConnContext *ctx); | 111 static void otr_message_disconnect(ConnContext *ctx); |
112 static ConnContext * otr_get_context(const char *buddy); | 112 static ConnContext *otr_get_context(const char *buddy); |
113 static void otr_startstop(const char * buddy, int start); | 113 static void otr_startstop(const char *buddy, int start); |
114 static void otr_handle_smp_tlvs(OtrlTLV * tlvs, ConnContext * ctx); | 114 static void otr_handle_smp_tlvs(OtrlTLV *tlvs, ConnContext *ctx); |
115 | 115 |
116 static char * otr_get_dir(void); | 116 static char *otr_get_dir(void); |
117 | 117 |
118 void otr_init(const char *fjid) | 118 void otr_init(const char *fjid) |
119 { | 119 { |
120 char *root; | 120 char *root; |
121 | 121 |
147 } | 147 } |
148 } | 148 } |
149 | 149 |
150 void otr_terminate(void) | 150 void otr_terminate(void) |
151 { | 151 { |
152 ConnContext * ctx; | 152 ConnContext *ctx; |
153 | 153 |
154 if (!otr_is_enabled) | 154 if (!otr_is_enabled) |
155 return; | 155 return; |
156 | 156 |
157 for (ctx = userstate->context_root; ctx; ctx = ctx->next) | 157 for (ctx = userstate->context_root; ctx; ctx = ctx->next) |
165 * is linked to both gnutls and libotr, libgcrypt will | 165 * is linked to both gnutls and libotr, libgcrypt will |
166 * segfault when we call otrl_userstate_free(). | 166 * segfault when we call otrl_userstate_free(). |
167 * This is reported to be a bug in libgcrypt :-/ | 167 * This is reported to be a bug in libgcrypt :-/ |
168 * Mikael | 168 * Mikael |
169 */ | 169 */ |
170 #if defined(HAVE_GNUTLS) && !defined(HAVE_OPENSSL) | 170 #if defined(HAVE_GNUTLS) && !defined(HAVE_OPENSSL) //TODO: broken now |
171 if (!settings_opt_get_int("ssl")) | 171 if (!settings_opt_get_int("ssl")) |
172 #endif | 172 #endif |
173 otrl_userstate_free(userstate); | 173 otrl_userstate_free(userstate); |
174 | 174 |
175 userstate = NULL; | 175 userstate = NULL; |
176 g_free(keyfile); | 176 g_free(keyfile); |
177 keyfile = NULL; | 177 keyfile = NULL; |
178 } | 178 } |
179 | 179 |
180 static char * otr_get_dir(void) | 180 static char *otr_get_dir(void) |
181 { | 181 { |
182 const char *configured_dir = settings_opt_get("otr_dir"); | 182 const char *configured_dir = settings_opt_get("otr_dir"); |
183 | 183 |
184 if (configured_dir && *configured_dir) { | 184 if (configured_dir && *configured_dir) { |
185 char *xp_conf_dir; | 185 char *xp_conf_dir; |
196 } else { | 196 } else { |
197 return expand_filename("~/.mcabber/otr/"); | 197 return expand_filename("~/.mcabber/otr/"); |
198 } | 198 } |
199 } | 199 } |
200 | 200 |
201 static ConnContext * otr_get_context(const char *buddy) | 201 static ConnContext *otr_get_context(const char *buddy) |
202 { | 202 { |
203 int null = 0; | 203 int null = 0; |
204 ConnContext * ctx; | 204 ConnContext *ctx; |
205 char * lowcasebuddy = g_strdup(buddy); | 205 char *lowcasebuddy = g_strdup(buddy); |
206 | 206 |
207 mc_strtolower(lowcasebuddy); | 207 mc_strtolower(lowcasebuddy); |
208 ctx = otrl_context_find(userstate, lowcasebuddy, account, OTR_PROTOCOL_NAME, | 208 ctx = otrl_context_find(userstate, lowcasebuddy, account, OTR_PROTOCOL_NAME, |
209 1, &null, NULL, NULL); | 209 1, &null, NULL, NULL); |
210 g_free(lowcasebuddy); | 210 g_free(lowcasebuddy); |
217 cb_gone_insecure(NULL, ctx); | 217 cb_gone_insecure(NULL, ctx); |
218 otrl_message_disconnect(userstate, &ops, NULL, ctx->accountname, | 218 otrl_message_disconnect(userstate, &ops, NULL, ctx->accountname, |
219 ctx->protocol, ctx->username); | 219 ctx->protocol, ctx->username); |
220 } | 220 } |
221 | 221 |
222 static void otr_startstop(const char * buddy, int start) | 222 static void otr_startstop(const char *buddy, int start) |
223 { | 223 { |
224 char * msg = NULL; | 224 char *msg = NULL; |
225 ConnContext *ctx = otr_get_context(buddy); | 225 ConnContext *ctx = otr_get_context(buddy); |
226 | 226 |
227 if (!userstate || !ctx) | 227 if (!userstate || !ctx) |
228 return; | 228 return; |
229 | 229 |
249 void otr_establish(const char *buddy) | 249 void otr_establish(const char *buddy) |
250 { | 250 { |
251 otr_startstop(buddy, 1); | 251 otr_startstop(buddy, 1); |
252 } | 252 } |
253 | 253 |
254 void otr_disconnect(const char * buddy) | 254 void otr_disconnect(const char *buddy) |
255 { | 255 { |
256 otr_startstop(buddy, 0); | 256 otr_startstop(buddy, 0); |
257 } | 257 } |
258 | 258 |
259 void otr_fingerprint(const char * buddy, const char * trust) | 259 void otr_fingerprint(const char *buddy, const char *trust) |
260 { | 260 { |
261 char fpr[45], *tr; | 261 char fpr[45], *tr; |
262 ConnContext *ctx = otr_get_context(buddy); | 262 ConnContext *ctx = otr_get_context(buddy); |
263 if (!userstate || !ctx) | 263 if (!userstate || !ctx) |
264 return; | 264 return; |
281 scr_LogPrint(LPRINT_LOGNORM, "%s [%44s]: %s", ctx->username, fpr, | 281 scr_LogPrint(LPRINT_LOGNORM, "%s [%44s]: %s", ctx->username, fpr, |
282 tr && *tr ? "trusted" : "untrusted"); | 282 tr && *tr ? "trusted" : "untrusted"); |
283 cb_write_fingerprints(NULL); | 283 cb_write_fingerprints(NULL); |
284 } | 284 } |
285 | 285 |
286 static void otr_handle_smp_tlvs(OtrlTLV * tlvs, ConnContext * ctx) | 286 static void otr_handle_smp_tlvs(OtrlTLV *tlvs, ConnContext *ctx) |
287 { | 287 { |
288 OtrlTLV *tlv = NULL; | 288 OtrlTLV *tlv = NULL; |
289 char *sbuf = NULL; | 289 char *sbuf = NULL; |
290 NextExpectedSMP nextMsg = ctx->smstate->nextExpected; | 290 NextExpectedSMP nextMsg = ctx->smstate->nextExpected; |
291 | 291 |
356 | 356 |
357 /* | 357 /* |
358 * returns whether a otr_message was received | 358 * returns whether a otr_message was received |
359 * sets *otr_data to NULL, when it was an internal otr message | 359 * sets *otr_data to NULL, when it was an internal otr message |
360 */ | 360 */ |
361 int otr_receive(char **otr_data, const char * buddy, int * free_msg) | 361 int otr_receive(char **otr_data, const char *buddy, int *free_msg) |
362 { | 362 { |
363 int ignore_message; | 363 int ignore_message; |
364 char *newmessage = NULL; | 364 char *newmessage = NULL; |
365 OtrlTLV *tlvs = NULL; | 365 OtrlTLV *tlvs = NULL; |
366 OtrlTLV *tlv = NULL; | 366 OtrlTLV *tlv = NULL; |
367 ConnContext * ctx; | 367 ConnContext *ctx; |
368 | 368 |
369 ctx = otr_get_context(buddy); | 369 ctx = otr_get_context(buddy); |
370 *free_msg = 0; | 370 *free_msg = 0; |
371 ignore_message = otrl_message_receiving(userstate, &ops, NULL, | 371 ignore_message = otrl_message_receiving(userstate, &ops, NULL, |
372 ctx->accountname, ctx->protocol, | 372 ctx->accountname, ctx->protocol, |
404 int otr_send(char **msg, const char *buddy) | 404 int otr_send(char **msg, const char *buddy) |
405 { | 405 { |
406 gcry_error_t err; | 406 gcry_error_t err; |
407 char *newmessage = NULL; | 407 char *newmessage = NULL; |
408 char *htmlmsg; | 408 char *htmlmsg; |
409 ConnContext * ctx = otr_get_context(buddy); | 409 ConnContext *ctx = otr_get_context(buddy); |
410 | 410 |
411 if (ctx->msgstate == OTRL_MSGSTATE_PLAINTEXT) | 411 if (ctx->msgstate == OTRL_MSGSTATE_PLAINTEXT) |
412 err = otrl_message_sending(userstate, &ops, NULL, ctx->accountname, | 412 err = otrl_message_sending(userstate, &ops, NULL, ctx->accountname, |
413 ctx->protocol, ctx->username, *msg, NULL, | 413 ctx->protocol, ctx->username, *msg, NULL, |
414 &newmessage, NULL, NULL); | 414 &newmessage, NULL, NULL); |
432 } | 432 } |
433 return 0; | 433 return 0; |
434 } | 434 } |
435 | 435 |
436 /* Prints OTR connection state */ | 436 /* Prints OTR connection state */ |
437 void otr_print_info(const char * buddy) | 437 void otr_print_info(const char *buddy) |
438 { | 438 { |
439 const char *state, *auth, *policy; | 439 const char *state, *auth, *policy; |
440 ConnContext * ctx = otr_get_context(buddy); | 440 ConnContext *ctx = otr_get_context(buddy); |
441 OtrlPolicy p = cb_policy(ctx->app_data, ctx); | 441 OtrlPolicy p = cb_policy(ctx->app_data, ctx); |
442 | 442 |
443 if (!userstate || !ctx) | 443 if (!userstate || !ctx) |
444 return; | 444 return; |
445 | 445 |
489 | 489 |
490 scr_LogPrint(LPRINT_LOGNORM, "%s: %s (%s) [%s]", | 490 scr_LogPrint(LPRINT_LOGNORM, "%s: %s (%s) [%s]", |
491 ctx->username, state, auth, policy); | 491 ctx->username, state, auth, policy); |
492 } | 492 } |
493 | 493 |
494 static ConnContext * otr_context_encrypted(const char * buddy) | 494 static ConnContext *otr_context_encrypted(const char *buddy) |
495 { | 495 { |
496 ConnContext * ctx = otr_get_context(buddy); | 496 ConnContext *ctx = otr_get_context(buddy); |
497 | 497 |
498 if (!userstate || !ctx || ctx->msgstate != OTRL_MSGSTATE_ENCRYPTED){ | 498 if (!userstate || !ctx || ctx->msgstate != OTRL_MSGSTATE_ENCRYPTED){ |
499 scr_LogPrint(LPRINT_LOGNORM, | 499 scr_LogPrint(LPRINT_LOGNORM, |
500 "You have to start an OTR channel with %s before you can " | 500 "You have to start an OTR channel with %s before you can " |
501 "use SMP.", buddy); | 501 "use SMP.", buddy); |
503 } | 503 } |
504 | 504 |
505 return ctx; | 505 return ctx; |
506 } | 506 } |
507 | 507 |
508 void otr_smp_query(const char * buddy, const char * secret) | 508 void otr_smp_query(const char *buddy, const char *secret) |
509 { | 509 { |
510 ConnContext * ctx = otr_context_encrypted(buddy); | 510 ConnContext *ctx = otr_context_encrypted(buddy); |
511 | 511 |
512 if (!secret) { | 512 if (!secret) { |
513 scr_LogPrint(LPRINT_LOGNORM, | 513 scr_LogPrint(LPRINT_LOGNORM, |
514 "Using SMP without a secret isn't a good idea."); | 514 "Using SMP without a secret isn't a good idea."); |
515 return; | 515 return; |
523 "OTR: Socialist Millionaires' Protocol " | 523 "OTR: Socialist Millionaires' Protocol " |
524 "initiated.", 0, HBB_PREFIX_INFO, 0); | 524 "initiated.", 0, HBB_PREFIX_INFO, 0); |
525 } | 525 } |
526 } | 526 } |
527 | 527 |
528 void otr_smp_respond(const char * buddy, const char * secret) | 528 void otr_smp_respond(const char *buddy, const char *secret) |
529 { | 529 { |
530 ConnContext * ctx = otr_context_encrypted(buddy); | 530 ConnContext *ctx = otr_context_encrypted(buddy); |
531 | 531 |
532 if (!secret) { | 532 if (!secret) { |
533 scr_LogPrint(LPRINT_LOGNORM, | 533 scr_LogPrint(LPRINT_LOGNORM, |
534 "Using SMP without a secret isn't a good idea."); | 534 "Using SMP without a secret isn't a good idea."); |
535 return; | 535 return; |
549 "OTR: Socialist Millionaires' Protocol: " | 549 "OTR: Socialist Millionaires' Protocol: " |
550 "response sent", 0, HBB_PREFIX_INFO, 0); | 550 "response sent", 0, HBB_PREFIX_INFO, 0); |
551 } | 551 } |
552 } | 552 } |
553 | 553 |
554 void otr_smp_abort(const char * buddy) | 554 void otr_smp_abort(const char *buddy) |
555 { | 555 { |
556 ConnContext * ctx = otr_context_encrypted(buddy); | 556 ConnContext *ctx = otr_context_encrypted(buddy); |
557 | 557 |
558 if (ctx) { | 558 if (ctx) { |
559 otrl_message_abort_smp(userstate, &ops, NULL, ctx); | 559 otrl_message_abort_smp(userstate, &ops, NULL, ctx); |
560 scr_WriteIncomingMessage(ctx->username, | 560 scr_WriteIncomingMessage(ctx->username, |
561 "OTR: Socialist Millionaires' Protocol aborted.", | 561 "OTR: Socialist Millionaires' Protocol aborted.", |
563 } | 563 } |
564 } | 564 } |
565 | 565 |
566 void otr_key(void) | 566 void otr_key(void) |
567 { | 567 { |
568 OtrlPrivKey * key; | 568 OtrlPrivKey *key; |
569 char readable[45] = ""; | 569 char readable[45] = ""; |
570 | 570 |
571 if(!userstate) | 571 if(!userstate) |
572 return; | 572 return; |
573 for (key = userstate->privkey_root; key; key = key->next) { | 573 for (key = userstate->privkey_root; key; key = key->next) { |
604 * desired. */ | 604 * desired. */ |
605 static void cb_create_privkey(void *opdata, const char *accountname, | 605 static void cb_create_privkey(void *opdata, const char *accountname, |
606 const char *protocol) | 606 const char *protocol) |
607 { | 607 { |
608 gcry_error_t e; | 608 gcry_error_t e; |
609 char * root; | 609 char *root; |
610 | 610 |
611 scr_LogPrint(LPRINT_LOGNORM, | 611 scr_LogPrint(LPRINT_LOGNORM, |
612 "Generating new OTR key for %s. This may take a while...", | 612 "Generating new OTR key for %s. This may take a while...", |
613 accountname); | 613 accountname); |
614 scr_DoUpdate(); | 614 scr_DoUpdate(); |
641 * accountname/protocol. */ | 641 * accountname/protocol. */ |
642 static void cb_inject_message(void *opdata, const char *accountname, | 642 static void cb_inject_message(void *opdata, const char *accountname, |
643 const char *protocol, const char *recipient, | 643 const char *protocol, const char *recipient, |
644 const char *message) | 644 const char *message) |
645 { | 645 { |
646 char * id = g_strdup("otrinject"); | |
647 if (roster_gettype(recipient) == ROSTER_TYPE_USER) | 646 if (roster_gettype(recipient) == ROSTER_TYPE_USER) |
648 jb_send_msg(recipient, message, ROSTER_TYPE_USER, "", id, NULL, NULL); | 647 xmpp_send_msg(recipient, message, ROSTER_TYPE_USER, "", TRUE, NULL, |
649 g_free(id); | 648 LM_MESSAGE_SUB_TYPE_NOT_SET); |
650 } | 649 } |
651 | 650 |
652 /* Display a notification message for a particular | 651 /* Display a notification message for a particular |
653 * accountname / protocol / username conversation. */ | 652 * accountname / protocol / username conversation. */ |
654 static void cb_notify(void *opdata, OtrlNotifyLevel level, | 653 static void cb_notify(void *opdata, OtrlNotifyLevel level, |
655 const char *accountname, const char *protocol, | 654 const char *accountname, const char *protocol, |
656 const char *username, const char *title, | 655 const char *username, const char *title, |
657 const char *primary, const char *secondary) | 656 const char *primary, const char *secondary) |
658 { | 657 { |
659 char * type; | 658 char *type; |
660 char *sbuf = NULL; | 659 char *sbuf = NULL; |
661 switch (level) { | 660 switch (level) { |
662 case OTRL_NOTIFY_ERROR: type = "error"; break; | 661 case OTRL_NOTIFY_ERROR: type = "error"; break; |
663 case OTRL_NOTIFY_WARNING: type = "warning"; break; | 662 case OTRL_NOTIFY_WARNING: type = "warning"; break; |
664 case OTRL_NOTIFY_INFO: type = "info"; break; | 663 case OTRL_NOTIFY_INFO: type = "info"; break; |