Changeset 6ce2240 for otr.c


Ignore:
Timestamp:
2010-09-30T06:02:01Z (14 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
560129a
Parents:
858ea01 (diff), 4752063 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merging some fixes from pesco. Adds support for the SMP flavour used by Pidgin
(otr smpq).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • otr.c

    r858ea01 r6ce2240  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2008 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2010 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    8787void cmd_otr_disconnect(irc_t *irc, char **args);
    8888void cmd_otr_smp(irc_t *irc, char **args);
     89void cmd_otr_smpq(irc_t *irc, char **args);
    8990void cmd_otr_trust(irc_t *irc, char **args);
    9091void cmd_otr_info(irc_t *irc, char **args);
     
    9697        { "disconnect",  1, &cmd_otr_disconnect, 0 },
    9798        { "smp",         2, &cmd_otr_smp,        0 },
     99        { "smpq",        3, &cmd_otr_smpq,       0 },
    98100        { "trust",       6, &cmd_otr_trust,      0 },
    99101        { "info",        0, &cmd_otr_info,       0 },
     
    154156/* handle SMP TLVs from a received message */
    155157void otr_handle_smp(struct im_connection *ic, const char *handle, OtrlTLV *tlvs);
     158
     159/* combined handler for the 'otr smp' and 'otr smpq' commands */
     160void otr_initiate_smp(irc_t *irc, const char *nick, const char *question,
     161                const char *secret);
    156162
    157163/* update op/voice flag of given user according to encryption state and settings
     
    732738void cmd_otr_smp(irc_t *irc, char **args)
    733739{
    734         irc_user_t *u;
    735         ConnContext *ctx;
    736        
    737         u = irc_user_by_name(irc, args[1]);
    738         if(!u || !u->bu || !u->bu->ic) {
    739                 irc_usermsg(irc, "%s: unknown user", args[1]);
    740                 return;
    741         }
    742         if(!(u->bu->flags & BEE_USER_ONLINE)) {
    743                 irc_usermsg(irc, "%s is offline", args[1]);
    744                 return;
    745         }
    746        
    747         ctx = otrl_context_find(irc->otr->us, u->bu->handle,
    748                 u->bu->ic->acc->user, u->bu->ic->acc->prpl->name, 1, NULL, NULL, NULL);
    749         if(!ctx) {
    750                 /* huh? out of memory or what? */
    751                 return;
    752         }
    753 
    754         if(ctx->smstate->nextExpected != OTRL_SMP_EXPECT1) {
    755                 log_message(LOGLVL_INFO,
    756                         "SMP already in phase %d, sending abort before reinitiating",
    757                         ctx->smstate->nextExpected+1);
    758                 otrl_message_abort_smp(irc->otr->us, &otr_ops, u->bu->ic, ctx);
    759                 otrl_sm_state_free(ctx->smstate);
    760         }
    761        
    762         /* warning: the following assumes that smstates are cleared whenever an SMP
    763            is completed or aborted! */
    764         if(ctx->smstate->secret == NULL) {
    765                 irc_usermsg(irc, "smp: initiating with %s...", u->nick);
    766                 otrl_message_initiate_smp(irc->otr->us, &otr_ops,
    767                         u->bu->ic, ctx, (unsigned char *)args[2], strlen(args[2]));
    768                 /* smp is now in EXPECT2 */
    769         } else {
    770                 /* if we're still in EXPECT1 but smstate is initialized, we must have
    771                    received the SMP1, so let's issue a response */
    772                 irc_usermsg(irc, "smp: responding to %s...", u->nick);
    773                 otrl_message_respond_smp(irc->otr->us, &otr_ops,
    774                         u->bu->ic, ctx, (unsigned char *)args[2], strlen(args[2]));
    775                 /* smp is now in EXPECT3 */
    776         }
     740        otr_initiate_smp(irc, args[1], NULL, args[2]);  /* no question */
     741}
     742
     743void cmd_otr_smpq(irc_t *irc, char **args)
     744{
     745        otr_initiate_smp(irc, args[1], args[2], args[3]);
    777746}
    778747
     
    10981067        if(!context) {
    10991068                /* huh? out of memory or what? */
     1069                irc_usermsg(irc, "smp: failed to get otr context for %s", u->nick);
     1070                otrl_message_abort_smp(us, ops, u->bu->ic, context);
     1071                otrl_sm_state_free(context->smstate);
    11001072                return;
    11011073        }
    11021074        nextMsg = context->smstate->nextExpected;
    11031075
     1076        tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1Q);
     1077        if (tlv) {
     1078                if (nextMsg != OTRL_SMP_EXPECT1) {
     1079                        irc_usermsg(irc, "smp %s: spurious SMP1Q received, aborting", u->nick);
     1080                        otrl_message_abort_smp(us, ops, u->bu->ic, context);
     1081                        otrl_sm_state_free(context->smstate);
     1082                } else {
     1083                        char *question = g_strndup((char *)tlv->data, tlv->len);
     1084                        irc_usermsg(irc, "smp: initiated by %s with question: \"%s\"", u->nick,
     1085                                question);
     1086                        irc_usermsg(irc, "smp: respond with \x02otr smp %s <answer>\x02",
     1087                                u->nick);
     1088                        g_free(question);
     1089                        /* smp stays in EXPECT1 until user responds */
     1090                }
     1091        }
    11041092        tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1);
    11051093        if (tlv) {
     
    11711159                otrl_sm_state_free(context->smstate);
    11721160                /* smp is in back in EXPECT1 */
     1161        }
     1162}
     1163
     1164/* combined handler for the 'otr smp' and 'otr smpq' commands */
     1165void otr_initiate_smp(irc_t *irc, const char *nick, const char *question,
     1166                const char *secret)
     1167{
     1168        irc_user_t *u;
     1169        ConnContext *ctx;
     1170
     1171        u = irc_user_by_name(irc, nick);
     1172        if(!u || !u->bu || !u->bu->ic) {
     1173                irc_usermsg(irc, "%s: unknown user", nick);
     1174                return;
     1175        }
     1176        if(!(u->bu->flags & BEE_USER_ONLINE)) {
     1177                irc_usermsg(irc, "%s is offline", nick);
     1178                return;
     1179        }
     1180       
     1181        ctx = otrl_context_find(irc->otr->us, u->bu->handle,
     1182                u->bu->ic->acc->user, u->bu->ic->acc->prpl->name, 0, NULL, NULL, NULL);
     1183        if(!ctx || ctx->msgstate != OTRL_MSGSTATE_ENCRYPTED) {
     1184                irc_usermsg(irc, "smp: otr inactive with %s, try \x02otr connect"
     1185                                " %s\x02", nick, nick);
     1186                return;
     1187        }
     1188
     1189        if(ctx->smstate->nextExpected != OTRL_SMP_EXPECT1) {
     1190                log_message(LOGLVL_INFO,
     1191                        "SMP already in phase %d, sending abort before reinitiating",
     1192                        ctx->smstate->nextExpected+1);
     1193                otrl_message_abort_smp(irc->otr->us, &otr_ops, u->bu->ic, ctx);
     1194                otrl_sm_state_free(ctx->smstate);
     1195        }
     1196       
     1197        if(question) {
     1198                /* this was 'otr smpq', just initiate */
     1199                irc_usermsg(irc, "smp: initiating with %s...", u->nick);
     1200                otrl_message_initiate_smp_q(irc->otr->us, &otr_ops, u->bu->ic, ctx,
     1201                        question, (unsigned char *)secret, strlen(secret));
     1202                /* smp is now in EXPECT2 */
     1203        } else {
     1204                /* this was 'otr smp', initiate or reply */
     1205                /* warning: the following assumes that smstates are cleared whenever an SMP
     1206                   is completed or aborted! */
     1207                if(ctx->smstate->secret == NULL) {
     1208                        irc_usermsg(irc, "smp: initiating with %s...", u->nick);
     1209                        otrl_message_initiate_smp(irc->otr->us, &otr_ops,
     1210                                u->bu->ic, ctx, (unsigned char *)secret, strlen(secret));
     1211                        /* smp is now in EXPECT2 */
     1212                } else {
     1213                        /* if we're still in EXPECT1 but smstate is initialized, we must have
     1214                           received the SMP1, so let's issue a response */
     1215                        irc_usermsg(irc, "smp: responding to %s...", u->nick);
     1216                        otrl_message_respond_smp(irc->otr->us, &otr_ops,
     1217                                u->bu->ic, ctx, (unsigned char *)secret, strlen(secret));
     1218                        /* smp is now in EXPECT3 */
     1219                }
    11731220        }
    11741221}
Note: See TracChangeset for help on using the changeset viewer.