27 #include "logprint.h" |
27 #include "logprint.h" |
28 #include "hbuf.h" |
28 #include "hbuf.h" |
29 #include "jab_priv.h" |
29 #include "jab_priv.h" |
30 #include "roster.h" |
30 #include "roster.h" |
31 #include "utils.h" |
31 #include "utils.h" |
|
32 #include "screen.h" |
|
33 #include "settings.h" |
32 |
34 |
33 |
35 |
34 static OtrlUserState userstate = NULL; |
36 static OtrlUserState userstate = NULL; |
35 static char * account = NULL; |
37 static char * account = NULL; |
36 static char * keyfile = NULL; |
38 static char * keyfile = NULL; |
37 static char * fprfile = NULL; |
39 static char * fprfile = NULL; |
38 static enum otr_policy policy = manual; |
|
39 |
40 |
40 |
41 |
41 static OtrlPolicy cb_policy (void *opdata, ConnContext *ctx); |
42 static OtrlPolicy cb_policy (void *opdata, ConnContext *ctx); |
42 static void cb_create_privkey (void *opdata, |
43 static void cb_create_privkey (void *opdata, |
43 const char *accountname, |
44 const char *accountname, |
81 static void cb_log_message (void *opdata, const char *message); |
82 static void cb_log_message (void *opdata, const char *message); |
82 static int cb_max_message_size (void *opdata, ConnContext *context); |
83 static int cb_max_message_size (void *opdata, ConnContext *context); |
83 |
84 |
84 static OtrlMessageAppOps ops = |
85 static OtrlMessageAppOps ops = |
85 { |
86 { |
86 policy: cb_policy, |
87 cb_policy, |
87 create_privkey: cb_create_privkey, |
88 cb_create_privkey, |
88 is_logged_in: cb_is_logged_in, |
89 cb_is_logged_in, |
89 inject_message: cb_inject_message, |
90 cb_inject_message, |
90 notify: cb_notify, |
91 cb_notify, |
91 display_otr_message: cb_display_otr_message, |
92 cb_display_otr_message, |
92 update_context_list: cb_update_context_list, |
93 cb_update_context_list, |
93 protocol_name: cb_protocol_name, |
94 cb_protocol_name, |
94 protocol_name_free: cb_protocol_name_free, |
95 cb_protocol_name_free, |
95 new_fingerprint: cb_new_fingerprint, |
96 cb_new_fingerprint, |
96 write_fingerprints: cb_write_fingerprints, |
97 cb_write_fingerprints, |
97 gone_secure: cb_gone_secure, |
98 cb_gone_secure, |
98 gone_insecure: cb_gone_insecure, |
99 cb_gone_insecure, |
99 still_secure: cb_still_secure, |
100 cb_still_secure, |
100 log_message: cb_log_message, |
101 cb_log_message, |
101 max_message_size: cb_max_message_size |
102 cb_max_message_size, |
|
103 NULL, /*account_name*/ |
|
104 NULL /*account_name_free*/ |
102 }; |
105 }; |
103 |
106 |
104 static void otr_message_disconnect(ConnContext *ctx); |
107 static void otr_message_disconnect(ConnContext *ctx); |
105 static ConnContext * otr_get_context(const char *buddy); |
108 static ConnContext * otr_get_context(const char *buddy); |
106 static void otr_startstop(const char * buddy, int start); |
109 static void otr_startstop(const char * buddy, int start); |
107 static void otr_handle_smp_tlvs(OtrlTLV * tlvs, ConnContext * ctx); |
110 static void otr_handle_smp_tlvs(OtrlTLV * tlvs, ConnContext * ctx); |
108 |
111 |
109 |
112 |
110 int otr_init(const char *jid) |
113 void otr_init(const char *jid) |
111 { |
114 { |
112 char * root = expand_filename("~/.mcabber/otr/"); |
115 char * root = expand_filename("~/.mcabber/otr/"); |
113 account = jidtodisp(jid); |
116 account = jidtodisp(jid); |
114 keyfile = g_strdup_printf("%s%s.key", root, account); |
117 keyfile = g_strdup_printf("%s%s.key", root, account); |
115 fprfile = g_strdup_printf("%s%s.fpr", root, account); |
118 fprfile = g_strdup_printf("%s%s.fpr", root, account); |
399 default: |
402 default: |
400 auth = "unknown auth"; |
403 auth = "unknown auth"; |
401 } |
404 } |
402 if (p == OTRL_POLICY_NEVER) |
405 if (p == OTRL_POLICY_NEVER) |
403 policy = "plain"; |
406 policy = "plain"; |
404 else if (p == OTRL_POLICY_OPPORTUNISTIC & ~OTRL_POLICY_ALLOW_V1) |
407 else if (p == (OTRL_POLICY_OPPORTUNISTIC & ~OTRL_POLICY_ALLOW_V1)) |
405 policy = "opportunistic"; |
408 policy = "opportunistic"; |
406 else if (p == OTRL_POLICY_MANUAL & ~OTRL_POLICY_ALLOW_V1) |
409 else if (p == (OTRL_POLICY_MANUAL & ~OTRL_POLICY_ALLOW_V1)) |
407 policy = "manual"; |
410 policy = "manual"; |
408 else if (p == (OTRL_POLICY_ALWAYS & ~OTRL_POLICY_ALLOW_V1)) |
411 else if (p == (OTRL_POLICY_ALWAYS & ~OTRL_POLICY_ALLOW_V1)) |
409 policy = "always"; |
412 policy = "always"; |
410 else |
413 else |
411 policy = "unknown"; |
414 policy = "unknown"; |
437 "Using SMP without a secret isn't a good idea."); |
440 "Using SMP without a secret isn't a good idea."); |
438 return; |
441 return; |
439 } |
442 } |
440 |
443 |
441 if (ctx) { |
444 if (ctx) { |
442 otrl_message_initiate_smp(userstate, &ops, NULL, ctx, secret, |
445 otrl_message_initiate_smp(userstate, &ops, NULL, ctx, |
|
446 (const unsigned char *)secret, |
443 strlen(secret)); |
447 strlen(secret)); |
444 scr_WriteIncomingMessage(ctx->username, |
448 scr_WriteIncomingMessage(ctx->username, |
445 "OTR: Socialist Millionaires' Protocol " |
449 "OTR: Socialist Millionaires' Protocol " |
446 "initiated.", 0, HBB_PREFIX_INFO); |
450 "initiated.", 0, HBB_PREFIX_INFO, 0); |
447 } |
451 } |
448 } |
452 } |
449 |
453 |
450 void otr_smp_respond(const char * buddy, const char * secret) |
454 void otr_smp_respond(const char * buddy, const char * secret) |
451 { |
455 { |
462 scr_LogPrint(LPRINT_LOGNORM, |
466 scr_LogPrint(LPRINT_LOGNORM, |
463 "Don't call smpr before you haven't received an SMP " |
467 "Don't call smpr before you haven't received an SMP " |
464 "Initiation!"); |
468 "Initiation!"); |
465 return; |
469 return; |
466 } |
470 } |
467 otrl_message_respond_smp(userstate, &ops, NULL, ctx, secret, |
471 otrl_message_respond_smp(userstate, &ops, NULL, ctx, |
|
472 (const unsigned char *)secret, |
468 strlen(secret)); |
473 strlen(secret)); |
469 scr_WriteIncomingMessage(ctx->username, |
474 scr_WriteIncomingMessage(ctx->username, |
470 "OTR: Socialist Millionaires' Protocol: " |
475 "OTR: Socialist Millionaires' Protocol: " |
471 "response sent", 0, HBB_PREFIX_INFO); |
476 "response sent", 0, HBB_PREFIX_INFO, 0); |
472 } |
477 } |
473 } |
478 } |
474 |
479 |
475 void otr_smp_abort(const char * buddy) |
480 void otr_smp_abort(const char * buddy) |
476 { |
481 { |
574 char *sbuf = NULL; |
581 char *sbuf = NULL; |
575 switch (level) { |
582 switch (level) { |
576 case OTRL_NOTIFY_ERROR: type = "error"; break; |
583 case OTRL_NOTIFY_ERROR: type = "error"; break; |
577 case OTRL_NOTIFY_WARNING: type = "warning"; break; |
584 case OTRL_NOTIFY_WARNING: type = "warning"; break; |
578 case OTRL_NOTIFY_INFO: type = "info"; break; |
585 case OTRL_NOTIFY_INFO: type = "info"; break; |
|
586 default: type = "unknown"; |
579 } |
587 } |
580 sbuf = g_strdup_printf("OTR %s:%s\n%s\n%s",type,title, primary, secondary); |
588 sbuf = g_strdup_printf("OTR %s:%s\n%s\n%s",type,title, primary, secondary); |
581 scr_WriteIncomingMessage(username, sbuf, 0, HBB_PREFIX_INFO); |
589 scr_WriteIncomingMessage(username, sbuf, 0, HBB_PREFIX_INFO, 0); |
582 g_free(sbuf); |
590 g_free(sbuf); |
583 } |
591 } |
584 |
592 |
585 /* Display an OTR control message for a particular |
593 /* Display an OTR control message for a particular |
586 * accountname / protocol / username conversation. Return 0 if you are able |
594 * accountname / protocol / username conversation. Return 0 if you are able |
590 * callback. */ |
598 * callback. */ |
591 static int cb_display_otr_message(void *opdata, const char *accountname, |
599 static int cb_display_otr_message(void *opdata, const char *accountname, |
592 const char *protocol, const char *username, |
600 const char *protocol, const char *username, |
593 const char *msg) |
601 const char *msg) |
594 { |
602 { |
595 scr_WriteIncomingMessage(username, msg, 0, HBB_PREFIX_INFO); |
603 scr_WriteIncomingMessage(username, msg, 0, HBB_PREFIX_INFO, 0); |
596 return 0; |
604 return 0; |
597 } |
605 } |
598 |
606 |
599 /* When the list of ConnContexts changes (including a change in |
607 /* When the list of ConnContexts changes (including a change in |
600 * state), this is called so the UI can be updated. */ |
608 * state), this is called so the UI can be updated. */ |
626 char *sbuf = NULL; |
634 char *sbuf = NULL; |
627 char readable[45]; |
635 char readable[45]; |
628 |
636 |
629 otrl_privkey_hash_to_human(readable, fingerprint); |
637 otrl_privkey_hash_to_human(readable, fingerprint); |
630 sbuf = g_strdup_printf("OTR: new fingerprint: %s", readable); |
638 sbuf = g_strdup_printf("OTR: new fingerprint: %s", readable); |
631 scr_WriteIncomingMessage(username, sbuf, 0, HBB_PREFIX_INFO); |
639 scr_WriteIncomingMessage(username, sbuf, 0, HBB_PREFIX_INFO, 0); |
632 g_free(sbuf); |
640 g_free(sbuf); |
633 } |
641 } |
634 |
642 |
635 /* The list of known fingerprints has changed. Write them to disk. */ |
643 /* The list of known fingerprints has changed. Write them to disk. */ |
636 static void cb_write_fingerprints(void *opdata) |
644 static void cb_write_fingerprints(void *opdata) |
640 |
648 |
641 /* A ConnContext has entered a secure state. */ |
649 /* A ConnContext has entered a secure state. */ |
642 static void cb_gone_secure(void *opdata, ConnContext *context) |
650 static void cb_gone_secure(void *opdata, ConnContext *context) |
643 { |
651 { |
644 scr_WriteIncomingMessage(context->username, "OTR: channel established", 0, |
652 scr_WriteIncomingMessage(context->username, "OTR: channel established", 0, |
645 HBB_PREFIX_INFO); |
653 HBB_PREFIX_INFO, 0); |
646 } |
654 } |
647 |
655 |
648 /* A ConnContext has left a secure state. */ |
656 /* A ConnContext has left a secure state. */ |
649 static void cb_gone_insecure(void *opdata, ConnContext *context) |
657 static void cb_gone_insecure(void *opdata, ConnContext *context) |
650 { |
658 { |
651 scr_WriteIncomingMessage(context->username, "OTR: channel closed", 0, |
659 scr_WriteIncomingMessage(context->username, "OTR: channel closed", 0, |
652 HBB_PREFIX_INFO); |
660 HBB_PREFIX_INFO, 0); |
653 } |
661 } |
654 |
662 |
655 /* We have completed an authentication, using the D-H keys we |
663 /* We have completed an authentication, using the D-H keys we |
656 * already knew. is_reply indicates whether we initiated the AKE. */ |
664 * already knew. is_reply indicates whether we initiated the AKE. */ |
657 static void cb_still_secure(void *opdata, ConnContext *context, int is_reply) |
665 static void cb_still_secure(void *opdata, ConnContext *context, int is_reply) |
658 { |
666 { |
659 scr_WriteIncomingMessage(context->username, "OTR: channel reestablished", 0, |
667 scr_WriteIncomingMessage(context->username, "OTR: channel reestablished", 0, |
660 HBB_PREFIX_INFO); |
668 HBB_PREFIX_INFO, 0); |
661 } |
669 } |
662 |
670 |
663 /* Log a message. The passed message will end in "\n". */ |
671 /* Log a message. The passed message will end in "\n". */ |
664 static void cb_log_message(void *opdata, const char *message) |
672 static void cb_log_message(void *opdata, const char *message) |
665 { |
673 { |