mcabber/src/otr.c
changeset 1301 37b41ed9ed35
parent 1299 3b338a5c01fc
child 1303 b6fdbfa6b219
equal deleted inserted replaced
1300:0d4a1699accb 1301:37b41ed9ed35
    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);
   282     sbuf = g_strdup("OTR: SMP aborted by your buddy");
   285     sbuf = g_strdup("OTR: SMP aborted by your buddy");
   283     ctx->smstate->nextExpected = OTRL_SMP_EXPECT1;
   286     ctx->smstate->nextExpected = OTRL_SMP_EXPECT1;
   284   }
   287   }
   285 
   288 
   286   if (sbuf) {
   289   if (sbuf) {
   287     scr_WriteIncomingMessage(ctx->username, sbuf, 0, HBB_PREFIX_INFO);
   290     scr_WriteIncomingMessage(ctx->username, sbuf, 0, HBB_PREFIX_INFO, 0);
   288     g_free(sbuf);
   291     g_free(sbuf);
   289   }
   292   }
   290 }
   293 }
   291 
   294 
   292 /*
   295 /*
   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 {
   478 
   483 
   479   if (ctx) {
   484   if (ctx) {
   480     otrl_message_abort_smp(userstate, &ops, NULL, ctx);
   485     otrl_message_abort_smp(userstate, &ops, NULL, ctx);
   481     scr_WriteIncomingMessage(ctx->username,
   486     scr_WriteIncomingMessage(ctx->username,
   482                              "OTR: Socialist Millionaires' Protocol aborted.",
   487                              "OTR: Socialist Millionaires' Protocol aborted.",
   483                              0, HBB_PREFIX_INFO);
   488                              0, HBB_PREFIX_INFO, 0);
   484   }
   489   }
   485 }
   490 }
   486 
   491 
   487 void otr_key(void)
   492 void otr_key(void)
   488 {
   493 {
   515     case manual:
   520     case manual:
   516       return OTRL_POLICY_MANUAL & ~OTRL_POLICY_ALLOW_V1;
   521       return OTRL_POLICY_MANUAL & ~OTRL_POLICY_ALLOW_V1;
   517     case always:
   522     case always:
   518       return OTRL_POLICY_ALWAYS & ~OTRL_POLICY_ALLOW_V1;
   523       return OTRL_POLICY_ALWAYS & ~OTRL_POLICY_ALLOW_V1;
   519   }
   524   }
       
   525 
       
   526   return OTRL_POLICY_MANUAL & ~OTRL_POLICY_ALLOW_V1;
   520 }
   527 }
   521 
   528 
   522 /* Create a private key for the given accountname/protocol if
   529 /* Create a private key for the given accountname/protocol if
   523  * desired. */
   530  * desired. */
   524 static void cb_create_privkey(void *opdata, const char *accountname,
   531 static void cb_create_privkey(void *opdata, const char *accountname,
   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 {