comparison mcabber/mcabber/otr.c @ 2336:0dc317b5599d

Remove support for libotr 3.x libotr 4.0.0 was released in 2012... There should be no distribution with a support lifecycle left that only packages libotr 3.x
author franky
date Sun, 12 May 2019 10:10:12 +0200
parents 746d72c6e1b9
children
comparison
equal deleted inserted replaced
2335:72543547c646 2336:0dc317b5599d
36 36
37 static OtrlUserState userstate = NULL; 37 static OtrlUserState userstate = NULL;
38 static char *account = NULL; 38 static char *account = NULL;
39 static char *keyfile = NULL; 39 static char *keyfile = NULL;
40 static char *fprfile = NULL; 40 static char *fprfile = NULL;
41 static char *tagfile = NULL;
42 static guint otr_timer_source = 0;
41 43
42 static int otr_is_enabled = FALSE; 44 static int otr_is_enabled = FALSE;
43 45
44 static OtrlPolicy cb_policy (void *opdata, ConnContext *ctx); 46 static OtrlPolicy cb_policy (void *opdata, ConnContext *ctx);
45 static void cb_create_privkey (void *opdata, 47 static void cb_create_privkey (void *opdata,
65 static void cb_gone_insecure (void *opdata, ConnContext *context); 67 static void cb_gone_insecure (void *opdata, ConnContext *context);
66 static void cb_still_secure (void *opdata, ConnContext *context, 68 static void cb_still_secure (void *opdata, ConnContext *context,
67 int is_reply); 69 int is_reply);
68 static int cb_max_message_size (void *opdata, ConnContext *context); 70 static int cb_max_message_size (void *opdata, ConnContext *context);
69 71
70 #ifdef HAVE_LIBOTR3
71 static void cb_notify (void *opdata,
72 OtrlNotifyLevel level,
73 const char *accountname,
74 const char *protocol,
75 const char *username,
76 const char *title,
77 const char *primary,
78 const char *secondary);
79 static int cb_display_otr_message(void *opdata,
80 const char *accountname,
81 const char *protocol,
82 const char *username,
83 const char *msg);
84 static const char *cb_protocol_name (void *opdata, const char *protocol);
85 static void cb_protocol_name_free (void *opdata,
86 const char *protocol_name);
87 static void cb_log_message (void *opdata, const char *message);
88
89 static void otr_handle_smp_tlvs (OtrlTLV *tlvs, ConnContext *ctx);
90 #else /* HAVE_LIBOTR3 */
91 static char *tagfile = NULL;
92 static guint otr_timer_source = 0;
93
94 static void cb_handle_smp_event (void *opdata, OtrlSMPEvent event, 72 static void cb_handle_smp_event (void *opdata, OtrlSMPEvent event,
95 ConnContext *context, unsigned short percent, 73 ConnContext *context, unsigned short percent,
96 char *question); 74 char *question);
97 static void cb_handle_msg_event (void *opdata, OtrlMessageEvent event, 75 static void cb_handle_msg_event (void *opdata, OtrlMessageEvent event,
98 ConnContext *context, const char *message, 76 ConnContext *context, const char *message,
99 gcry_error_t err); 77 gcry_error_t err);
100 static void cb_create_instag (void *opdata, const char *accountname, 78 static void cb_create_instag (void *opdata, const char *accountname,
101 const char *protocol); 79 const char *protocol);
102 static void cb_timer_control (void *opdata, unsigned int interval); 80 static void cb_timer_control (void *opdata, unsigned int interval);
103 #endif /* HAVE_LIBOTR3 */
104 81
105 static OtrlMessageAppOps ops = 82 static OtrlMessageAppOps ops =
106 { 83 {
107 cb_policy, 84 cb_policy,
108 cb_create_privkey, 85 cb_create_privkey,
109 cb_is_logged_in, 86 cb_is_logged_in,
110 cb_inject_message, 87 cb_inject_message,
111 #ifdef HAVE_LIBOTR3
112 cb_notify,
113 cb_display_otr_message,
114 #endif
115 cb_update_context_list, 88 cb_update_context_list,
116 #ifdef HAVE_LIBOTR3
117 cb_protocol_name,
118 cb_protocol_name_free,
119 #endif
120 cb_new_fingerprint, 89 cb_new_fingerprint,
121 cb_write_fingerprints, 90 cb_write_fingerprints,
122 cb_gone_secure, 91 cb_gone_secure,
123 cb_gone_insecure, 92 cb_gone_insecure,
124 cb_still_secure, 93 cb_still_secure,
125 #ifdef HAVE_LIBOTR3
126 cb_log_message,
127 #endif
128 cb_max_message_size, 94 cb_max_message_size,
129 NULL, /* account_name */ 95 NULL, /* account_name */
130 NULL, /* account_name_free */ 96 NULL, /* account_name_free */
131 #ifndef HAVE_LIBOTR3
132 NULL, /* received_symkey */ 97 NULL, /* received_symkey */
133 NULL, /* otr_error_message */ 98 NULL, /* otr_error_message */
134 NULL, /* otr_error_message_free */ 99 NULL, /* otr_error_message_free */
135 NULL, /* resent_msg_prefix */ 100 NULL, /* resent_msg_prefix */
136 NULL, /* resent_msg_prefix_free */ 101 NULL, /* resent_msg_prefix_free */
138 cb_handle_msg_event, 103 cb_handle_msg_event,
139 cb_create_instag, 104 cb_create_instag,
140 NULL, /* convert_msg */ 105 NULL, /* convert_msg */
141 NULL, /* convert_free */ 106 NULL, /* convert_free */
142 cb_timer_control, 107 cb_timer_control,
143 #endif
144 }; 108 };
145 109
146 static void otr_message_disconnect(ConnContext *ctx); 110 static void otr_message_disconnect(ConnContext *ctx);
147 static ConnContext *otr_get_context(const char *buddy); 111 static ConnContext *otr_get_context(const char *buddy);
148 static void otr_startstop(const char *buddy, int start); 112 static void otr_startstop(const char *buddy, int start);
172 136
173 if (otrl_privkey_read(userstate, keyfile)){ 137 if (otrl_privkey_read(userstate, keyfile)){
174 scr_LogPrint(LPRINT_LOGNORM, "Could not read OTR key from %s", keyfile); 138 scr_LogPrint(LPRINT_LOGNORM, "Could not read OTR key from %s", keyfile);
175 cb_create_privkey(NULL, account, OTR_PROTOCOL_NAME); 139 cb_create_privkey(NULL, account, OTR_PROTOCOL_NAME);
176 } 140 }
141
177 if (otrl_privkey_read_fingerprints(userstate, fprfile, NULL, NULL)){ 142 if (otrl_privkey_read_fingerprints(userstate, fprfile, NULL, NULL)){
178 scr_LogPrint(LPRINT_LOGNORM, "Could not read OTR fingerprints from %s", 143 scr_LogPrint(LPRINT_LOGNORM, "Could not read OTR fingerprints from %s",
179 fprfile); 144 fprfile);
180 } 145 }
181 #ifndef HAVE_LIBOTR3 146
182 tagfile = g_strdup_printf("%s%s.tag", root, account); 147 tagfile = g_strdup_printf("%s%s.tag", root, account);
183 if (otrl_instag_read(userstate, tagfile)) { 148 if (otrl_instag_read(userstate, tagfile)) {
184 scr_LogPrint(LPRINT_LOGNORM, "Could not read OTR instance tag from %s", tagfile); 149 scr_LogPrint(LPRINT_LOGNORM, "Could not read OTR instance tag from %s", tagfile);
185 cb_create_instag(NULL, account, OTR_PROTOCOL_NAME); 150 cb_create_instag(NULL, account, OTR_PROTOCOL_NAME);
186 } 151 }
187 #endif 152
188 g_free(root); 153 g_free(root);
189 } 154 }
190 155
191 void otr_terminate(void) 156 void otr_terminate(void)
192 { 157 {
193 ConnContext *ctx; 158 ConnContext *ctx;
194 159
195 if (!otr_is_enabled) 160 if (!otr_is_enabled)
196 return; 161 return;
197 162
198 #ifndef HAVE_LIBOTR3
199 if (otr_timer_source > 0) { 163 if (otr_timer_source > 0) {
200 g_source_remove (otr_timer_source); 164 g_source_remove (otr_timer_source);
201 otr_timer_source = 0; 165 otr_timer_source = 0;
202 } 166 }
203 #endif
204 167
205 for (ctx = userstate->context_root; ctx; ctx = ctx->next) 168 for (ctx = userstate->context_root; ctx; ctx = ctx->next)
206 if (ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED) 169 if (ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED)
207 otr_message_disconnect(ctx); 170 otr_message_disconnect(ctx);
208 171
223 userstate = NULL; 186 userstate = NULL;
224 g_free(keyfile); 187 g_free(keyfile);
225 keyfile = NULL; 188 keyfile = NULL;
226 g_free(fprfile); 189 g_free(fprfile);
227 fprfile = NULL; 190 fprfile = NULL;
228 #ifndef HAVE_LIBOTR3
229 g_free(tagfile); 191 g_free(tagfile);
230 tagfile = NULL; 192 tagfile = NULL;
231 #endif
232 } 193 }
233 194
234 static char *otr_get_dir(void) 195 static char *otr_get_dir(void)
235 { 196 {
236 const char *configured_dir = settings_opt_get("otr_dir"); 197 const char *configured_dir = settings_opt_get("otr_dir");
258 ConnContext *ctx; 219 ConnContext *ctx;
259 char *lowcasebuddy = g_strdup(buddy); 220 char *lowcasebuddy = g_strdup(buddy);
260 221
261 mc_strtolower(lowcasebuddy); 222 mc_strtolower(lowcasebuddy);
262 ctx = otrl_context_find(userstate, lowcasebuddy, account, OTR_PROTOCOL_NAME, 223 ctx = otrl_context_find(userstate, lowcasebuddy, account, OTR_PROTOCOL_NAME,
263 #ifdef HAVE_LIBOTR3
264 1, &null, NULL, NULL);
265 #else
266 // INSTAG XXX 224 // INSTAG XXX
267 OTRL_INSTAG_BEST, 1, &null, NULL, NULL); 225 OTRL_INSTAG_BEST, 1, &null, NULL, NULL);
268 #endif
269 g_free(lowcasebuddy); 226 g_free(lowcasebuddy);
270 return ctx; 227 return ctx;
271 } 228 }
272 229
273 static void otr_message_disconnect(ConnContext *ctx) 230 static void otr_message_disconnect(ConnContext *ctx)
274 { 231 {
275 if (ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED) 232 if (ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED)
276 cb_gone_insecure(NULL, ctx); 233 cb_gone_insecure(NULL, ctx);
277 otrl_message_disconnect(userstate, &ops, NULL, ctx->accountname, 234 otrl_message_disconnect(userstate, &ops, NULL, ctx->accountname,
278 #ifdef HAVE_LIBOTR3
279 ctx->protocol, ctx->username);
280 #else
281 // INSTAG XXX 235 // INSTAG XXX
282 ctx->protocol, ctx->username, OTRL_INSTAG_BEST); 236 ctx->protocol, ctx->username, OTRL_INSTAG_BEST);
283 #endif
284 } 237 }
285 238
286 static void otr_startstop(const char *buddy, int start) 239 static void otr_startstop(const char *buddy, int start)
287 { 240 {
288 char *msg = NULL; 241 char *msg = NULL;
345 scr_LogPrint(LPRINT_LOGNORM, "%s [%44s]: %s", ctx->username, fpr, 298 scr_LogPrint(LPRINT_LOGNORM, "%s [%44s]: %s", ctx->username, fpr,
346 tr && *tr ? "trusted" : "untrusted"); 299 tr && *tr ? "trusted" : "untrusted");
347 cb_write_fingerprints(NULL); 300 cb_write_fingerprints(NULL);
348 } 301 }
349 302
350 #ifdef HAVE_LIBOTR3
351
352 static void otr_handle_smp_tlvs(OtrlTLV *tlvs, ConnContext *ctx)
353 {
354 OtrlTLV *tlv = NULL;
355 char *sbuf = NULL;
356 NextExpectedSMP nextMsg = ctx->smstate->nextExpected;
357
358 tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1);
359 if (tlv) {
360 if (nextMsg != OTRL_SMP_EXPECT1)
361 otr_smp_abort(ctx->username);
362 else {
363 sbuf = g_strdup_printf("OTR: Received SMP Initiation. "
364 "Answer with /otr smpr %s $secret",
365 ctx->username);
366 }
367 }
368 tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP2);
369 if (tlv) {
370 if (nextMsg != OTRL_SMP_EXPECT2)
371 otr_smp_abort(ctx->username);
372 else {
373 sbuf = g_strdup("OTR: Received SMP Response.");
374 /* If we received TLV2, we will send TLV3 and expect TLV4 */
375 ctx->smstate->nextExpected = OTRL_SMP_EXPECT4;
376 }
377 }
378 tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP3);
379 if (tlv) {
380 if (nextMsg != OTRL_SMP_EXPECT3)
381 otr_smp_abort(ctx->username);
382 else {
383 /* If we received TLV3, we will send TLV4
384 * We will not expect more messages, so prepare for next SMP */
385 ctx->smstate->nextExpected = OTRL_SMP_EXPECT1;
386 /* Report result to user */
387 if (ctx->active_fingerprint && ctx->active_fingerprint->trust &&
388 *ctx->active_fingerprint->trust != '\0')
389 sbuf = g_strdup("OTR: SMP succeeded");
390 else
391 sbuf = g_strdup("OTR: SMP failed");
392 }
393 }
394 tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP4);
395 if (tlv) {
396 if (nextMsg != OTRL_SMP_EXPECT4)
397 otr_smp_abort(ctx->username);
398 else {
399 /* We will not expect more messages, so prepare for next SMP */
400 ctx->smstate->nextExpected = OTRL_SMP_EXPECT1;
401 /* Report result to user */
402 if (ctx->active_fingerprint && ctx->active_fingerprint->trust &&
403 *ctx->active_fingerprint->trust != '\0')
404 sbuf = g_strdup("OTR: SMP succeeded");
405 else
406 sbuf = g_strdup("OTR: SMP failed");
407 }
408 }
409 tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP_ABORT);
410 if (tlv) {
411 /* The message we are waiting for will not arrive, so reset
412 * and prepare for the next SMP */
413 sbuf = g_strdup("OTR: SMP aborted by your buddy");
414 ctx->smstate->nextExpected = OTRL_SMP_EXPECT1;
415 }
416
417 if (sbuf) {
418 scr_WriteIncomingMessage(ctx->username, sbuf, 0, HBB_PREFIX_INFO, 0);
419 g_free(sbuf);
420 }
421 }
422
423 #else /* HAVE_LIBOTR3 */
424
425 static void cb_handle_smp_event(void *opdata, OtrlSMPEvent event, 303 static void cb_handle_smp_event(void *opdata, OtrlSMPEvent event,
426 ConnContext *context, unsigned short percent, 304 ConnContext *context, unsigned short percent,
427 char *question) 305 char *question)
428 { 306 {
429 const char *msg = NULL; 307 const char *msg = NULL;
540 scr_WriteIncomingMessage(context->username, msg, 0, HBB_PREFIX_INFO, 0); 418 scr_WriteIncomingMessage(context->username, msg, 0, HBB_PREFIX_INFO, 0);
541 g_free(freeme); 419 g_free(freeme);
542 } 420 }
543 } 421 }
544 422
545 #endif /* HAVE_LIBOTR3 */
546 423
547 /* otr_receive 424 /* otr_receive
548 * Returns whether a otr_message was received. 425 * Returns whether a otr_message was received.
549 * Sets *otr_data to NULL, when it was an internal otr message. 426 * Sets *otr_data to NULL, when it was an internal otr message.
550 */ 427 */
563 return 0; 440 return 0;
564 441
565 ignore_message = otrl_message_receiving(userstate, &ops, NULL, 442 ignore_message = otrl_message_receiving(userstate, &ops, NULL,
566 ctx->accountname, ctx->protocol, 443 ctx->accountname, ctx->protocol,
567 ctx->username, *otr_data, 444 ctx->username, *otr_data,
568 #ifdef HAVE_LIBOTR3
569 &newmessage, &tlvs, NULL, NULL);
570 otr_handle_smp_tlvs(tlvs, ctx);
571 #else
572 &newmessage, &tlvs, NULL, NULL, NULL); 445 &newmessage, &tlvs, NULL, NULL, NULL);
573 #endif
574 446
575 tlv = otrl_tlv_find(tlvs, OTRL_TLV_DISCONNECTED); 447 tlv = otrl_tlv_find(tlvs, OTRL_TLV_DISCONNECTED);
576 if (tlv) { 448 if (tlv) {
577 /* Notify the user that the other side disconnected. */ 449 /* Notify the user that the other side disconnected. */
578 cb_gone_insecure(NULL, ctx); 450 cb_gone_insecure(NULL, ctx);
617 if (!buddy || !msg || !msg[0]) 489 if (!buddy || !msg || !msg[0])
618 return NULL; 490 return NULL;
619 491
620 if (ctx->msgstate == OTRL_MSGSTATE_PLAINTEXT) 492 if (ctx->msgstate == OTRL_MSGSTATE_PLAINTEXT)
621 err = otrl_message_sending(userstate, &ops, NULL, ctx->accountname, 493 err = otrl_message_sending(userstate, &ops, NULL, ctx->accountname,
622 #ifdef HAVE_LIBOTR3
623 ctx->protocol, ctx->username, msg, NULL,
624 &newmessage, NULL, NULL);
625 #else
626 // INSTAG XXX 494 // INSTAG XXX
627 ctx->protocol, ctx->username, OTRL_INSTAG_BEST, 495 ctx->protocol, ctx->username, OTRL_INSTAG_BEST,
628 msg, NULL, &newmessage, OTRL_FRAGMENT_SEND_SKIP, 496 msg, NULL, &newmessage, OTRL_FRAGMENT_SEND_SKIP,
629 NULL, NULL, NULL); 497 NULL, NULL, NULL);
630 #endif
631 else { 498 else {
632 err = otrl_message_sending(userstate, &ops, NULL, ctx->accountname, 499 err = otrl_message_sending(userstate, &ops, NULL, ctx->accountname,
633 #ifdef HAVE_LIBOTR3
634 ctx->protocol, ctx->username, msg, NULL,
635 &newmessage, NULL, NULL);
636 #else
637 // INSTAG XXX 500 // INSTAG XXX
638 ctx->protocol, ctx->username, OTRL_INSTAG_BEST, 501 ctx->protocol, ctx->username, OTRL_INSTAG_BEST,
639 msg, NULL, &newmessage, OTRL_FRAGMENT_SEND_SKIP, 502 msg, NULL, &newmessage, OTRL_FRAGMENT_SEND_SKIP,
640 NULL, NULL, NULL); 503 NULL, NULL, NULL);
641 #endif
642 } 504 }
643 505
644 if (err) 506 if (err)
645 return NULL; /* something went wrong, don't send the plain-message! */ 507 return NULL; /* something went wrong, don't send the plain-message! */
646 508
932 { 794 {
933 scr_WriteIncomingMessage(context->username, "OTR: channel reestablished", 0, 795 scr_WriteIncomingMessage(context->username, "OTR: channel reestablished", 0,
934 HBB_PREFIX_INFO, 0); 796 HBB_PREFIX_INFO, 0);
935 } 797 }
936 798
937 #ifdef HAVE_LIBOTR3
938
939 /* Display a notification message for a particular
940 * accountname / protocol / username conversation. */
941 static void cb_notify(void *opdata, OtrlNotifyLevel level,
942 const char *accountname, const char *protocol,
943 const char *username, const char *title,
944 const char *primary, const char *secondary)
945 {
946 char *type;
947 char *sbuf = NULL;
948 switch (level) {
949 case OTRL_NOTIFY_ERROR: type = "error"; break;
950 case OTRL_NOTIFY_WARNING: type = "warning"; break;
951 case OTRL_NOTIFY_INFO: type = "info"; break;
952 default: type = "unknown";
953 }
954 sbuf = g_strdup_printf("OTR %s:%s\n%s\n%s",type,title, primary, secondary);
955 scr_WriteIncomingMessage(username, sbuf, 0, HBB_PREFIX_INFO, 0);
956 g_free(sbuf);
957 }
958
959 /* Display an OTR control message for a particular
960 * accountname / protocol / username conversation. Return 0 if you are able
961 * to successfully display it. If you return non-0 (or if this
962 * function is NULL), the control message will be displayed inline,
963 * as a received message, or else by using the above notify()
964 * callback. */
965 static int cb_display_otr_message(void *opdata, const char *accountname,
966 const char *protocol, const char *username,
967 const char *msg)
968 {
969 char *strippedmsg = html_strip(msg);
970 scr_WriteIncomingMessage(username, strippedmsg, 0, HBB_PREFIX_INFO, 0);
971 g_free(strippedmsg);
972 return 0;
973 }
974
975 /* Return a newly allocated string containing a human-friendly name
976 * for the given protocol id */
977 static const char *cb_protocol_name(void *opdata, const char *protocol)
978 {
979 return protocol;
980 }
981
982 /* Deallocate a string allocated by protocol_name */
983 static void cb_protocol_name_free (void *opdata, const char *protocol_name)
984 {
985 /* We didn't allocated memory, so we don't have to free anything :p */
986 }
987
988 /* Log a message. The passed message will end in "\n". */
989 static void cb_log_message(void *opdata, const char *message)
990 {
991 scr_LogPrint(LPRINT_DEBUG, "OTR: %s", message);
992 }
993
994 #else /* HAVE_LIBOTR3 */
995
996 /* Generate unique instance tag for account. */ 799 /* Generate unique instance tag for account. */
997 static void cb_create_instag(void *opdata, const char *accountname, 800 static void cb_create_instag(void *opdata, const char *accountname,
998 const char *protocol) 801 const char *protocol)
999 { 802 {
1000 if (otrl_instag_generate(userstate, tagfile, accountname, protocol)) { 803 if (otrl_instag_generate(userstate, tagfile, accountname, protocol)) {
1016 } 819 }
1017 if (interval > 0) 820 if (interval > 0)
1018 otr_timer_source = g_timeout_add_seconds(interval, otr_timer_cb, opdata); 821 otr_timer_source = g_timeout_add_seconds(interval, otr_timer_cb, opdata);
1019 } 822 }
1020 823
1021 #endif /* HAVE_LIBOTR3 */
1022
1023 /* Find the maximum message size supported by this protocol. */ 824 /* Find the maximum message size supported by this protocol. */
1024 static int cb_max_message_size(void *opdata, ConnContext *context) 825 static int cb_max_message_size(void *opdata, ConnContext *context)
1025 { 826 {
1026 return 8192; 827 return 8192;
1027 } 828 }