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;