Changeset 6e9ae72 for otr.c


Ignore:
Timestamp:
2011-12-17T13:50:01Z (13 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
18c6d36
Parents:
87dddee (diff), 17f057d (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:

Mainline merge.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • otr.c

    r87dddee r6e9ae72  
    88  OTR support (cf. http://www.cypherpunks.ca/otr/)
    99 
    10   (c) 2008-2010 Sven Moritz Hallberg <pesco@khjk.org>
     10  (c) 2008-2011 Sven Moritz Hallberg <pesco@khjk.org>
    1111  (c) 2008 funded by stonedcoder.org
    1212   
     
    163163                const char *secret);
    164164
     165/* update flags within the irc_user structure to reflect OTR status of context */
     166void otr_update_uflags(ConnContext *context, irc_user_t *u);
     167
    165168/* update op/voice flag of given user according to encryption state and settings
    166169   returns 0 if neither op_buddies nor voice_buddies is set to "encrypted",
     
    182185/* find a private key by fingerprint prefix (given as any number of hex strings) */
    183186OtrlPrivKey *match_privkey(irc_t *irc, const char **args);
     187
     188/* check whether a string is safe to use in a path component */
     189int strsane(const char *s);
    184190
    185191/* functions to be called for certain events */
     
    237243        l = g_slist_prepend( l, "always" );
    238244        s->eval_data = l;
     245
     246        s = set_add( &irc->b->set, "otr_does_html", "true", set_eval_bool, irc );
    239247       
    240248        return TRUE;
     
    270278        int kg=0;
    271279
    272         g_snprintf(s, 511, "%s%s.otr_keys", global.conf->configdir, irc->user->nick);
    273         e = otrl_privkey_read(irc->otr->us, s);
    274         if(e && e!=enoent) {
    275                 irc_usermsg(irc, "otr load: %s: %s", s, gcry_strerror(e));
    276         }
    277         g_snprintf(s, 511, "%s%s.otr_fprints", global.conf->configdir, irc->user->nick);
    278         e = otrl_privkey_read_fingerprints(irc->otr->us, s, NULL, NULL);
    279         if(e && e!=enoent) {
    280                 irc_usermsg(irc, "otr load: %s: %s", s, gcry_strerror(e));
     280        if(strsane(irc->user->nick)) {
     281                g_snprintf(s, 511, "%s%s.otr_keys", global.conf->configdir, irc->user->nick);
     282                e = otrl_privkey_read(irc->otr->us, s);
     283                if(e && e!=enoent) {
     284                        irc_rootmsg(irc, "otr load: %s: %s", s, gcry_strerror(e));
     285                }
     286                g_snprintf(s, 511, "%s%s.otr_fprints", global.conf->configdir, irc->user->nick);
     287                e = otrl_privkey_read_fingerprints(irc->otr->us, s, NULL, NULL);
     288                if(e && e!=enoent) {
     289                        irc_rootmsg(irc, "otr load: %s: %s", s, gcry_strerror(e));
     290                }
    281291        }
    282292       
     
    286296        }
    287297        if(kg) {
    288                 irc_usermsg(irc, "Notice: "
     298                irc_rootmsg(irc, "Notice: "
    289299                        "The accounts above do not have OTR encryption keys associated with them, yet. "
    290300                        "These keys are now being generated in the background. "
     
    301311        gcry_error_t e;
    302312
    303         g_snprintf(s, 511, "%s%s.otr_fprints", global.conf->configdir, irc->user->nick);
    304         e = otrl_privkey_write_fingerprints(irc->otr->us, s);
    305         if(e) {
    306                 irc_usermsg(irc, "otr save: %s: %s", s, gcry_strerror(e));
    307         }
    308         chmod(s, 0600);
     313        if(strsane(irc->user->nick)) {
     314                g_snprintf(s, 511, "%s%s.otr_fprints", global.conf->configdir, irc->user->nick);
     315                e = otrl_privkey_write_fingerprints(irc->otr->us, s);
     316                if(e) {
     317                        irc_rootmsg(irc, "otr save: %s: %s", s, gcry_strerror(e));
     318                }
     319                chmod(s, 0600);
     320        }
    309321}
    310322
     
    313325        char s[512];
    314326       
    315         g_snprintf(s, 511, "%s%s.otr_keys", global.conf->configdir, nick);
    316         unlink(s);
    317         g_snprintf(s, 511, "%s%s.otr_fprints", global.conf->configdir, nick);
    318         unlink(s);
     327        if(strsane(nick)) {
     328                g_snprintf(s, 511, "%s%s.otr_keys", global.conf->configdir, nick);
     329                unlink(s);
     330                g_snprintf(s, 511, "%s%s.otr_fprints", global.conf->configdir, nick);
     331                unlink(s);
     332        }
    319333}
    320334
     
    323337        char s[512], t[512];
    324338       
    325         g_snprintf(s, 511, "%s%s.otr_keys", global.conf->configdir, onick);
    326         g_snprintf(t, 511, "%s%s.otr_keys", global.conf->configdir, nnick);
    327         rename(s,t);
    328         g_snprintf(s, 511, "%s%s.otr_fprints", global.conf->configdir, onick);
    329         g_snprintf(t, 511, "%s%s.otr_fprints", global.conf->configdir, nnick);
    330         rename(s,t);
     339        if(strsane(nnick) && strsane(onick)) {
     340                g_snprintf(s, 511, "%s%s.otr_keys", global.conf->configdir, onick);
     341                g_snprintf(t, 511, "%s%s.otr_keys", global.conf->configdir, nnick);
     342                rename(s,t);
     343                g_snprintf(s, 511, "%s%s.otr_fprints", global.conf->configdir, onick);
     344                g_snprintf(t, 511, "%s%s.otr_fprints", global.conf->configdir, nnick);
     345                rename(s,t);
     346        }
    331347}
    332348
     
    343359        k = otrl_privkey_find(irc->otr->us, a->user, a->prpl->name);
    344360        if(k) {
    345                 irc_usermsg(irc, "otr: %s/%s ready", a->user, a->prpl->name);
     361                irc_rootmsg(irc, "otr: %s/%s ready", a->user, a->prpl->name);
    346362                return 0;
    347363        } if(keygen_in_progress(irc, a->user, a->prpl->name)) {
    348                 irc_usermsg(irc, "otr: keygen for %s/%s already in progress", a->user, a->prpl->name);
     364                irc_rootmsg(irc, "otr: keygen for %s/%s already in progress", a->user, a->prpl->name);
    349365                return 0;
    350366        } else {
    351                 irc_usermsg(irc, "otr: starting background keygen for %s/%s", a->user, a->prpl->name);
     367                irc_rootmsg(irc, "otr: starting background keygen for %s/%s", a->user, a->prpl->name);
    352368                otr_keygen(irc, a->user, a->prpl->name);
    353369                return 1;
     
    360376        char *newmsg = NULL;
    361377        OtrlTLV *tlvs = NULL;
    362         char *colormsg;
    363378        irc_t *irc = iu->irc;
    364379        struct im_connection *ic = iu->bu->ic;
     
    380395        } else if(!newmsg) {
    381396                /* this was a non-OTR message */
    382                 return g_strdup(msg);
     397                return msg;
    383398        } else {
    384399                /* OTR has processed this message */
    385400                ConnContext *context = otrl_context_find(irc->otr->us, iu->bu->handle,
    386401                        ic->acc->user, ic->acc->prpl->name, 0, NULL, NULL, NULL);
    387                 if(context && context->msgstate == OTRL_MSGSTATE_ENCRYPTED &&
    388                    set_getbool(&ic->bee->set, "otr_color_encrypted")) {
    389                         /* color according to f'print trust */
    390                         int color;
    391                         const char *trust = context->active_fingerprint->trust;
    392                         if(trust && trust[0] != '\0')
    393                                 color=3;   /* green */
    394                         else
    395                                 color=5;   /* red */
    396 
    397                         if(newmsg[0] == ',') {
    398                                 /* could be a problem with the color code */
    399                                 /* insert a space between color spec and message */
    400                                 colormsg = g_strdup_printf("\x03%.2d %s\x0F", color, newmsg);
    401                         } else {
    402                                 colormsg = g_strdup_printf("\x03%.2d%s\x0F", color, newmsg);
     402
     403                /* we're done with the original msg, which will be caller-freed. */
     404                /* NB: must not change the newmsg pointer, since we free it. */
     405                msg = newmsg;
     406
     407                if(context && context->msgstate == OTRL_MSGSTATE_ENCRYPTED) {
     408                        /* HTML decoding */
     409                        /* perform any necessary stripping that the top level would miss */
     410                        if(set_getbool(&ic->bee->set, "otr_does_html") &&
     411                           !(ic->flags & OPT_DOES_HTML) &&
     412                           set_getbool(&ic->bee->set, "strip_html")) {
     413                                strip_html(msg);
    403414                        }
    404                 } else {
    405                         colormsg = g_strdup(newmsg);
     415
     416                        /* coloring */
     417                        if(set_getbool(&ic->bee->set, "otr_color_encrypted")) {
     418                                int color;                /* color according to f'print trust */
     419                                char *pre="", *sep="";    /* optional parts */
     420                                const char *trust = context->active_fingerprint->trust;
     421
     422                                if(trust && trust[0] != '\0')
     423                                        color=3;   /* green */
     424                                else
     425                                        color=5;   /* red */
     426
     427                                /* in a query window, keep "/me " uncolored at the beginning */
     428                                if(g_strncasecmp(msg, "/me ", 4) == 0
     429                                   && irc_user_msgdest(iu) == irc->user->nick) {
     430                                        msg += 4;  /* skip */
     431                                        pre = "/me ";
     432                                }
     433
     434                                /* comma in first place could mess with the color code */
     435                                if(msg[0] == ',') {
     436                                    /* insert a space between color spec and message */
     437                                    sep = " ";
     438                                }
     439
     440                                msg = g_strdup_printf("%s\x03%.2d%s%s\x0F", pre,
     441                                        color, sep, msg);
     442                        }
     443                }
     444
     445                if(msg == newmsg) {
     446                        msg = g_strdup(newmsg);
    406447                }
    407448                otrl_message_free(newmsg);
    408                 return colormsg;
     449                return msg;
    409450        }
    410451}
     
    414455        int st;
    415456        char *otrmsg = NULL;
     457        char *emsg = msg;           /* the message as we hand it to libotr */
    416458        ConnContext *ctx = NULL;
    417459        irc_t *irc = iu->irc;
     
    422464                return msg;
    423465        }
    424        
    425         st = otrl_message_sending(irc->otr->us, &otr_ops, ic,
    426                 ic->acc->user, ic->acc->prpl->name, iu->bu->handle,
    427                 msg, NULL, &otrmsg, NULL, NULL);
    428         if(st) {
    429                 return NULL;
    430         }
    431466
    432467        ctx = otrl_context_find(irc->otr->us,
    433468                        iu->bu->handle, ic->acc->user, ic->acc->prpl->name,
    434469                        1, NULL, NULL, NULL);
     470
     471        /* HTML encoding */
     472        /* consider OTR plaintext to be HTML if otr_does_html is set */
     473        if(ctx && ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED &&
     474           set_getbool(&ic->bee->set, "otr_does_html") &&
     475           (g_strncasecmp(msg, "<html>", 6) != 0)) {
     476                emsg = escape_html(msg);
     477        }
     478       
     479        st = otrl_message_sending(irc->otr->us, &otr_ops, ic,
     480                ic->acc->user, ic->acc->prpl->name, iu->bu->handle,
     481                emsg, NULL, &otrmsg, NULL, NULL);
     482        if(emsg != msg) {
     483                g_free(emsg);   /* we're done with this one */
     484        }
     485        if(st) {
     486                return NULL;
     487        }
    435488
    436489        if(otrmsg) {
     
    480533       
    481534        if(!cmd->command) {
    482                 irc_usermsg(irc, "%s: unknown subcommand \"%s\", see \x02help otr\x02",
     535                irc_rootmsg(irc, "%s: unknown subcommand \"%s\", see \x02help otr\x02",
    483536                        args[0], args[1]);
    484537                return;
     
    486539       
    487540        if(!args[cmd->required_parameters+1]) {
    488                 irc_usermsg(irc, "%s %s: not enough arguments (%d req.)",
     541                irc_rootmsg(irc, "%s %s: not enough arguments (%d req.)",
    489542                        args[0], args[1], cmd->required_parameters);
    490543                return;
     
    558611        if (strcmp(accountname, recipient) == 0) {
    559612                /* huh? injecting messages to myself? */
    560                 irc_usermsg(irc, "note to self: %s", message);
     613                irc_rootmsg(irc, "note to self: %s", message);
    561614        } else {
    562615                /* need to drop some consts here :-( */
     
    573626        char *msg = g_strdup(message);
    574627        irc_t *irc = ic->bee->ui_data;
     628        irc_user_t *u = peeruser(irc, username, protocol);
    575629
    576630        strip_html(msg);
    577         irc_usermsg(irc, "otr: %s", msg);
     631        if(u) {
     632                /* display as a notice from this particular user */
     633                irc_usernotice(u, "%s", msg);
     634        } else {
     635                irc_rootmsg(irc, "[otr] %s", msg);
     636        }
    578637
    579638        g_free(msg);
     
    587646        struct im_connection *ic = check_imc(opdata, accountname, protocol);
    588647        irc_t *irc = ic->bee->ui_data;
     648        irc_user_t *u = peeruser(irc, username, protocol);
    589649        char hunam[45];         /* anybody looking? ;-) */
    590650       
    591651        otrl_privkey_hash_to_human(hunam, fingerprint);
    592         irc_usermsg(irc, "new fingerprint for %s: %s",
    593                 peernick(irc, username, protocol), hunam);
     652        if(u) {
     653                irc_usernotice(u, "new fingerprint: %s", hunam);
     654        } else {
     655                /* this case shouldn't normally happen */
     656                irc_rootmsg(irc, "new fingerprint for %s/%s: %s",
     657                        username, protocol, hunam);
     658        }
    594659}
    595660
     
    608673        irc_user_t *u;
    609674        irc_t *irc = ic->bee->ui_data;
    610         const char *trust;
    611675
    612676        u = peeruser(irc, context->username, context->protocol);
     
    618682        }
    619683       
    620         trust = context->active_fingerprint->trust;
    621         if(trust && trust[0])
    622                 u->flags |= IRC_USER_OTR_ENCRYPTED | IRC_USER_OTR_TRUSTED;
    623         else
    624                 u->flags = ( u->flags & ~IRC_USER_OTR_TRUSTED ) | IRC_USER_OTR_ENCRYPTED;
    625         if(!otr_update_modeflags(irc, u))
    626                 irc_usermsg(irc, "conversation with %s is now off the record", u->nick);
     684        otr_update_uflags(context, u);
     685        if(!otr_update_modeflags(irc, u)) {
     686                char *trust = u->flags & IRC_USER_OTR_TRUSTED ? "trusted" : "untrusted!";
     687                irc_usernotice(u, "conversation is now off the record (%s)", trust);
     688        }
    627689}
    628690
     
    641703                return;
    642704        }
    643         u->flags &= ~( IRC_USER_OTR_ENCRYPTED | IRC_USER_OTR_TRUSTED );
     705        otr_update_uflags(context, u);
    644706        if(!otr_update_modeflags(irc, u))
    645                 irc_usermsg(irc, "conversation with %s is now in the clear", u->nick);
     707                irc_usernotice(u, "conversation is now in cleartext");
    646708}
    647709
     
    660722                return;
    661723        }
    662         if(context->active_fingerprint->trust[0])
    663                 u->flags |= IRC_USER_OTR_ENCRYPTED | IRC_USER_OTR_TRUSTED;
    664         else
    665                 u->flags = ( u->flags & ~IRC_USER_OTR_TRUSTED ) | IRC_USER_OTR_ENCRYPTED;
    666         if(!otr_update_modeflags(irc, u))
    667                 irc_usermsg(irc, "otr connection with %s has been refreshed", u->nick);
     724
     725        otr_update_uflags(context, u);
     726        if(!otr_update_modeflags(irc, u)) {
     727                char *trust = u->flags & IRC_USER_OTR_TRUSTED ? "trusted" : "untrusted!";
     728                irc_usernotice(u, "otr connection has been refreshed (%s)", trust);
     729        }
    668730}
    669731
     
    708770        u = irc_user_by_name(irc, args[1]);
    709771        if(!u || !u->bu || !u->bu->ic) {
    710                 irc_usermsg(irc, "%s: unknown user", args[1]);
     772                irc_rootmsg(irc, "%s: unknown user", args[1]);
    711773                return;
    712774        }
     
    733795        u = irc_user_by_name(irc, args[1]);
    734796        if(!u || !u->bu || !u->bu->ic) {
    735                 irc_usermsg(irc, "%s: unknown user", args[1]);
     797                irc_rootmsg(irc, "%s: unknown user", args[1]);
    736798                return;
    737799        }
    738800        if(!(u->bu->flags & BEE_USER_ONLINE)) {
    739                 irc_usermsg(irc, "%s is offline", args[1]);
     801                irc_rootmsg(irc, "%s is offline", args[1]);
    740802                return;
    741803        }
     
    764826        u = irc_user_by_name(irc, args[1]);
    765827        if(!u || !u->bu || !u->bu->ic) {
    766                 irc_usermsg(irc, "%s: unknown user", args[1]);
     828                irc_rootmsg(irc, "%s: unknown user", args[1]);
    767829                return;
    768830        }
     
    771833                u->bu->ic->acc->user, u->bu->ic->acc->prpl->name, 0, NULL, NULL, NULL);
    772834        if(!ctx) {
    773                 irc_usermsg(irc, "%s: no otr context with user", args[1]);
     835                irc_rootmsg(irc, "%s: no otr context with user", args[1]);
    774836                return;
    775837        }
     
    783845                       
    784846                        if(!*p || !*q) {
    785                                 irc_usermsg(irc, "failed: truncated fingerprint block %d", i+1);
     847                                irc_rootmsg(irc, "failed: truncated fingerprint block %d", i+1);
    786848                                return;
    787849                        }
     
    790852                        y = hexval(*q);
    791853                        if(x<0) {
    792                                 irc_usermsg(irc, "failed: %d. hex digit of block %d out of range", 2*j+1, i+1);
     854                                irc_rootmsg(irc, "failed: %d. hex digit of block %d out of range", 2*j+1, i+1);
    793855                                return;
    794856                        }
    795857                        if(y<0) {
    796                                 irc_usermsg(irc, "failed: %d. hex digit of block %d out of range", 2*j+2, i+1);
     858                                irc_rootmsg(irc, "failed: %d. hex digit of block %d out of range", 2*j+2, i+1);
    797859                                return;
    798860                        }
     
    803865        fp = otrl_context_find_fingerprint(ctx, raw, 0, NULL);
    804866        if(!fp) {
    805                 irc_usermsg(irc, "failed: no such fingerprint for %s", args[1]);
     867                irc_rootmsg(irc, "failed: no such fingerprint for %s", args[1]);
    806868        } else {
    807869                char *trust = args[7] ? args[7] : "affirmed";
    808870                otrl_context_set_trust(fp, trust);
    809                 irc_usermsg(irc, "fingerprint match, trust set to \"%s\"", trust);
     871                irc_rootmsg(irc, "fingerprint match, trust set to \"%s\"", trust);
    810872                if(u->flags & IRC_USER_OTR_ENCRYPTED)
    811873                        u->flags |= IRC_USER_OTR_TRUSTED;
     
    835897                        ctx = otrl_context_find(irc->otr->us, handle, myhandle, protocol, 0, NULL, NULL, NULL);
    836898                        if(!ctx) {
    837                                 irc_usermsg(irc, "no such context");
     899                                irc_rootmsg(irc, "no such context");
    838900                                g_free(arg);
    839901                                return;
     
    842904                        irc_user_t *u = irc_user_by_name(irc, args[1]);
    843905                        if(!u || !u->bu || !u->bu->ic) {
    844                                 irc_usermsg(irc, "%s: unknown user", args[1]);
     906                                irc_rootmsg(irc, "%s: unknown user", args[1]);
    845907                                g_free(arg);
    846908                                return;
     
    849911                                u->bu->ic->acc->prpl->name, 0, NULL, NULL, NULL);
    850912                        if(!ctx) {
    851                                 irc_usermsg(irc, "no otr context with %s", args[1]);
     913                                irc_rootmsg(irc, "no otr context with %s", args[1]);
    852914                                g_free(arg);
    853915                                return;
     
    857919                /* show how we resolved the (nick) argument, if we did */
    858920                if(handle!=arg) {
    859                         irc_usermsg(irc, "%s is %s/%s; we are %s/%s to them", args[1],
     921                        irc_rootmsg(irc, "%s is %s/%s; we are %s/%s to them", args[1],
    860922                                ctx->username, ctx->protocol, ctx->accountname, ctx->protocol);
    861923                }
     
    872934        n = atoi(args[1]);
    873935        if(n<0 || (!n && strcmp(args[1], "0"))) {
    874                 irc_usermsg(irc, "%s: invalid account number", args[1]);
     936                irc_rootmsg(irc, "%s: invalid account number", args[1]);
    875937                return;
    876938        }
     
    879941        for(i=0; i<n && a; i++, a=a->next);
    880942        if(!a) {
    881                 irc_usermsg(irc, "%s: no such account", args[1]);
     943                irc_rootmsg(irc, "%s: no such account", args[1]);
    882944                return;
    883945        }
    884946       
    885947        if(keygen_in_progress(irc, a->user, a->prpl->name)) {
    886                 irc_usermsg(irc, "keygen for account %d already in progress", n);
     948                irc_rootmsg(irc, "keygen for account %d already in progress", n);
    887949                return;
    888950        }
     
    906968       
    907969        if(fp == fp->context->active_fingerprint) {
    908                 irc_usermsg(irc, "that fingerprint is active, terminate otr connection first");
     970                irc_rootmsg(irc, "that fingerprint is active, terminate otr connection first");
    909971                return;
    910972        }
     
    922984       
    923985        if(ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED) {
    924                 irc_usermsg(irc, "active otr connection with %s, terminate it first",
     986                irc_rootmsg(irc, "active otr connection with %s, terminate it first",
    925987                        peernick(irc, ctx->username, ctx->protocol));
    926988                return;
     
    9541016               
    9551017                if(!args[3]) {
    956                         irc_usermsg(irc, "otr %s %s: not enough arguments (2 req.)", args[0], args[1]);
     1018                        irc_rootmsg(irc, "otr %s %s: not enough arguments (2 req.)", args[0], args[1]);
    9571019                        return;
    9581020                }
     
    9611023                u = irc_user_by_name(irc, args[2]);
    9621024                if(!u || !u->bu || !u->bu->ic) {
    963                         irc_usermsg(irc, "%s: unknown user", args[2]);
     1025                        irc_rootmsg(irc, "%s: unknown user", args[2]);
    9641026                        return;
    9651027                }
     
    9681030                        u->bu->ic->acc->prpl->name, 0, NULL, NULL, NULL);
    9691031                if(!ctx) {
    970                         irc_usermsg(irc, "no otr context with %s", args[2]);
     1032                        irc_rootmsg(irc, "no otr context with %s", args[2]);
    9711033                        return;
    9721034                }
     
    9791041               
    9801042                if(fp == ctx->active_fingerprint) {
    981                         irc_usermsg(irc, "that fingerprint is active, terminate otr connection first");
     1043                        irc_rootmsg(irc, "that fingerprint is active, terminate otr connection first");
    9821044                        return;
    9831045                }
     
    10041066                u = irc_user_by_name(irc, args[2]);
    10051067                if(!u || !u->bu || !u->bu->ic) {
    1006                         irc_usermsg(irc, "%s: unknown user", args[2]);
     1068                        irc_rootmsg(irc, "%s: unknown user", args[2]);
    10071069                        return;
    10081070                }
     
    10111073                        u->bu->ic->acc->prpl->name, 0, NULL, NULL, NULL);
    10121074                if(!ctx) {
    1013                         irc_usermsg(irc, "no otr context with %s", args[2]);
     1075                        irc_rootmsg(irc, "no otr context with %s", args[2]);
    10141076                        return;
    10151077                }
    10161078               
    10171079                if(ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED) {
    1018                         irc_usermsg(irc, "active otr connection with %s, terminate it first", args[2]);
     1080                        irc_rootmsg(irc, "active otr connection with %s, terminate it first", args[2]);
    10191081                        return;
    10201082                }
     
    10491111        else
    10501112        {
    1051                 irc_usermsg(irc, "otr %s: unknown subcommand \"%s\", see \x02help otr forget\x02",
     1113                irc_rootmsg(irc, "otr %s: unknown subcommand \"%s\", see \x02help otr forget\x02",
    10521114                        args[0], args[1]);
    10531115        }
     
    10751137        if(!context) {
    10761138                /* huh? out of memory or what? */
    1077                 irc_usermsg(irc, "smp: failed to get otr context for %s", u->nick);
     1139                irc_rootmsg(irc, "smp: failed to get otr context for %s", u->nick);
    10781140                otrl_message_abort_smp(us, ops, u->bu->ic, context);
    10791141                otrl_sm_state_free(context->smstate);
     
    10831145
    10841146        if (context->smstate->sm_prog_state == OTRL_SMP_PROG_CHEATED) {
    1085                 irc_usermsg(irc, "smp %s: opponent violated protocol, aborting",
     1147                irc_rootmsg(irc, "smp %s: opponent violated protocol, aborting",
    10861148                        u->nick);
    10871149                otrl_message_abort_smp(us, ops, u->bu->ic, context);
     
    10931155        if (tlv) {
    10941156                if (nextMsg != OTRL_SMP_EXPECT1) {
    1095                         irc_usermsg(irc, "smp %s: spurious SMP1Q received, aborting", u->nick);
     1157                        irc_rootmsg(irc, "smp %s: spurious SMP1Q received, aborting", u->nick);
    10961158                        otrl_message_abort_smp(us, ops, u->bu->ic, context);
    10971159                        otrl_sm_state_free(context->smstate);
    10981160                } else {
    10991161                        char *question = g_strndup((char *)tlv->data, tlv->len);
    1100                         irc_usermsg(irc, "smp: initiated by %s with question: \x02\"%s\"\x02", u->nick,
     1162                        irc_rootmsg(irc, "smp: initiated by %s with question: \x02\"%s\"\x02", u->nick,
    11011163                                question);
    1102                         irc_usermsg(irc, "smp: respond with \x02otr smp %s <answer>\x02",
     1164                        irc_rootmsg(irc, "smp: respond with \x02otr smp %s <answer>\x02",
    11031165                                u->nick);
    11041166                        g_free(question);
     
    11091171        if (tlv) {
    11101172                if (nextMsg != OTRL_SMP_EXPECT1) {
    1111                         irc_usermsg(irc, "smp %s: spurious SMP1 received, aborting", u->nick);
     1173                        irc_rootmsg(irc, "smp %s: spurious SMP1 received, aborting", u->nick);
    11121174                        otrl_message_abort_smp(us, ops, u->bu->ic, context);
    11131175                        otrl_sm_state_free(context->smstate);
    11141176                } else {
    1115                         irc_usermsg(irc, "smp: initiated by %s"
     1177                        irc_rootmsg(irc, "smp: initiated by %s"
    11161178                                " - respond with \x02otr smp %s <secret>\x02",
    11171179                                u->nick, u->nick);
     
    11221184        if (tlv) {
    11231185                if (nextMsg != OTRL_SMP_EXPECT2) {
    1124                         irc_usermsg(irc, "smp %s: spurious SMP2 received, aborting", u->nick);
     1186                        irc_rootmsg(irc, "smp %s: spurious SMP2 received, aborting", u->nick);
    11251187                        otrl_message_abort_smp(us, ops, u->bu->ic, context);
    11261188                        otrl_sm_state_free(context->smstate);
     
    11331195        if (tlv) {
    11341196                if (nextMsg != OTRL_SMP_EXPECT3) {
    1135                         irc_usermsg(irc, "smp %s: spurious SMP3 received, aborting", u->nick);
     1197                        irc_rootmsg(irc, "smp %s: spurious SMP3 received, aborting", u->nick);
    11361198                        otrl_message_abort_smp(us, ops, u->bu->ic, context);
    11371199                        otrl_sm_state_free(context->smstate);
     
    11401202                        if(context->smstate->sm_prog_state == OTRL_SMP_PROG_SUCCEEDED) {
    11411203                                if(context->smstate->received_question) {
    1142                                         irc_usermsg(irc, "smp %s: correct answer, you are trusted",
     1204                                        irc_rootmsg(irc, "smp %s: correct answer, you are trusted",
    11431205                                                u->nick);
    11441206                                } else {
    1145                                         irc_usermsg(irc, "smp %s: secrets proved equal, fingerprint trusted",
     1207                                        irc_rootmsg(irc, "smp %s: secrets proved equal, fingerprint trusted",
    11461208                                                u->nick);
    11471209                                }
    11481210                        } else {
    11491211                                if(context->smstate->received_question) {
    1150                                         irc_usermsg(irc, "smp %s: wrong answer, you are not trusted",
     1212                                        irc_rootmsg(irc, "smp %s: wrong answer, you are not trusted",
    11511213                                                u->nick);
    11521214                                } else {
    1153                                         irc_usermsg(irc, "smp %s: secrets did not match, fingerprint not trusted",
     1215                                        irc_rootmsg(irc, "smp %s: secrets did not match, fingerprint not trusted",
    11541216                                                u->nick);
    11551217                                }
     
    11621224        if (tlv) {
    11631225                if (nextMsg != OTRL_SMP_EXPECT4) {
    1164                         irc_usermsg(irc, "smp %s: spurious SMP4 received, aborting", u->nick);
     1226                        irc_rootmsg(irc, "smp %s: spurious SMP4 received, aborting", u->nick);
    11651227                        otrl_message_abort_smp(us, ops, u->bu->ic, context);
    11661228                        otrl_sm_state_free(context->smstate);
     
    11681230                        /* SMP4 received, otrl_message_receiving will have set fp trust */
    11691231                        if(context->smstate->sm_prog_state == OTRL_SMP_PROG_SUCCEEDED) {
    1170                                 irc_usermsg(irc, "smp %s: secrets proved equal, fingerprint trusted",
     1232                                irc_rootmsg(irc, "smp %s: secrets proved equal, fingerprint trusted",
    11711233                                        u->nick);
    11721234                        } else {
    1173                                 irc_usermsg(irc, "smp %s: secrets did not match, fingerprint not trusted",
     1235                                irc_rootmsg(irc, "smp %s: secrets did not match, fingerprint not trusted",
    11741236                                        u->nick);
    11751237                        }
     
    11801242        tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP_ABORT);
    11811243        if (tlv) {
    1182                 irc_usermsg(irc, "smp: received abort from %s", u->nick);
     1244                irc_rootmsg(irc, "smp: received abort from %s", u->nick);
    11831245                otrl_sm_state_free(context->smstate);
    11841246                /* smp is in back in EXPECT1 */
     
    11951257        u = irc_user_by_name(irc, nick);
    11961258        if(!u || !u->bu || !u->bu->ic) {
    1197                 irc_usermsg(irc, "%s: unknown user", nick);
     1259                irc_rootmsg(irc, "%s: unknown user", nick);
    11981260                return;
    11991261        }
    12001262        if(!(u->bu->flags & BEE_USER_ONLINE)) {
    1201                 irc_usermsg(irc, "%s is offline", nick);
     1263                irc_rootmsg(irc, "%s is offline", nick);
    12021264                return;
    12031265        }
     
    12061268                u->bu->ic->acc->user, u->bu->ic->acc->prpl->name, 0, NULL, NULL, NULL);
    12071269        if(!ctx || ctx->msgstate != OTRL_MSGSTATE_ENCRYPTED) {
    1208                 irc_usermsg(irc, "smp: otr inactive with %s, try \x02otr connect"
     1270                irc_rootmsg(irc, "smp: otr inactive with %s, try \x02otr connect"
    12091271                                " %s\x02", nick, nick);
    12101272                return;
     
    12211283        if(question) {
    12221284                /* this was 'otr smpq', just initiate */
    1223                 irc_usermsg(irc, "smp: initiating with %s...", u->nick);
     1285                irc_rootmsg(irc, "smp: initiating with %s...", u->nick);
    12241286                otrl_message_initiate_smp_q(irc->otr->us, &otr_ops, u->bu->ic, ctx,
    12251287                        question, (unsigned char *)secret, strlen(secret));
     
    12301292                   is completed or aborted! */
    12311293                if(ctx->smstate->secret == NULL) {
    1232                         irc_usermsg(irc, "smp: initiating with %s...", u->nick);
     1294                        irc_rootmsg(irc, "smp: initiating with %s...", u->nick);
    12331295                        otrl_message_initiate_smp(irc->otr->us, &otr_ops,
    12341296                                u->bu->ic, ctx, (unsigned char *)secret, strlen(secret));
     
    12371299                        /* if we're still in EXPECT1 but smstate is initialized, we must have
    12381300                           received the SMP1, so let's issue a response */
    1239                         irc_usermsg(irc, "smp: responding to %s...", u->nick);
     1301                        irc_rootmsg(irc, "smp: responding to %s...", u->nick);
    12401302                        otrl_message_respond_smp(irc->otr->us, &otr_ops,
    12411303                                u->bu->ic, ctx, (unsigned char *)secret, strlen(secret));
     
    13121374}
    13131375
     1376void otr_update_uflags(ConnContext *context, irc_user_t *u)
     1377{
     1378        const char *trust;
     1379
     1380        if(context->active_fingerprint) {
     1381                u->flags |= IRC_USER_OTR_ENCRYPTED;
     1382
     1383                trust = context->active_fingerprint->trust;
     1384                if(trust && trust[0])
     1385                        u->flags |= IRC_USER_OTR_TRUSTED;
     1386                else
     1387                        u->flags &= ~IRC_USER_OTR_TRUSTED;
     1388        } else {
     1389                u->flags &= ~IRC_USER_OTR_ENCRYPTED;
     1390        }
     1391}
     1392
    13141393int otr_update_modeflags(irc_t *irc, irc_user_t *u)
    13151394{
    1316         return 1;
     1395        return 0;
    13171396}
    13181397
     
    13351414                }
    13361415                if(fp == ctx->active_fingerprint) {
    1337                         irc_usermsg(irc, "    \x02%s (%s)\x02", human, trust);
     1416                        irc_rootmsg(irc, "    \x02%s (%s)\x02", human, trust);
    13381417                } else {
    1339                         irc_usermsg(irc, "    %s (%s)", human, trust);
     1418                        irc_rootmsg(irc, "    %s (%s)", human, trust);
    13401419                }
    13411420        }
    13421421        if(count==0)
    1343                 irc_usermsg(irc, "    (none)");
     1422                irc_rootmsg(irc, "    (none)");
    13441423}
    13451424
     
    13601439                       
    13611440                        if(n>=40) {
    1362                                 irc_usermsg(irc, "too many fingerprint digits given, expected at most 40");
     1441                                irc_rootmsg(irc, "too many fingerprint digits given, expected at most 40");
    13631442                                return NULL;
    13641443                        }
     
    13671446                                *(p++) = c;
    13681447                        } else {
    1369                                 irc_usermsg(irc, "invalid hex digit '%c' in block %d", args[i][j], i+1);
     1448                                irc_rootmsg(irc, "invalid hex digit '%c' in block %d", args[i][j], i+1);
    13701449                                return NULL;
    13711450                        }
     
    13881467        }
    13891468        if(!fp) {
    1390                 irc_usermsg(irc, "%s: no match", prefix);
     1469                irc_rootmsg(irc, "%s: no match", prefix);
    13911470                return NULL;
    13921471        }
     
    14011480        }
    14021481        if(fp2) {
    1403                 irc_usermsg(irc, "%s: multiple matches", prefix);
     1482                irc_rootmsg(irc, "%s: multiple matches", prefix);
    14041483                return NULL;
    14051484        }
     
    14241503                       
    14251504                        if(n>=40) {
    1426                                 irc_usermsg(irc, "too many fingerprint digits given, expected at most 40");
     1505                                irc_rootmsg(irc, "too many fingerprint digits given, expected at most 40");
    14271506                                return NULL;
    14281507                        }
     
    14311510                                *(p++) = c;
    14321511                        } else {
    1433                                 irc_usermsg(irc, "invalid hex digit '%c' in block %d", args[i][j], i+1);
     1512                                irc_rootmsg(irc, "invalid hex digit '%c' in block %d", args[i][j], i+1);
    14341513                                return NULL;
    14351514                        }
     
    14521531        }
    14531532        if(!k) {
    1454                 irc_usermsg(irc, "%s: no match", prefix);
     1533                irc_rootmsg(irc, "%s: no match", prefix);
    14551534                return NULL;
    14561535        }
     
    14651544        }
    14661545        if(k2) {
    1467                 irc_usermsg(irc, "%s: multiple matches", prefix);
     1546                irc_rootmsg(irc, "%s: multiple matches", prefix);
    14681547                return NULL;
    14691548        }
     
    14801559
    14811560        /* list all privkeys (including ones being generated) */
    1482         irc_usermsg(irc, "\x1fprivate keys:\x1f");
     1561        irc_rootmsg(irc, "\x1fprivate keys:\x1f");
    14831562        for(key=irc->otr->us->privkey_root; key; key=key->next) {
    14841563                const char *hash;
     
    14861565                switch(key->pubkey_type) {
    14871566                case OTRL_PUBKEY_TYPE_DSA:
    1488                         irc_usermsg(irc, "  %s/%s - DSA", key->accountname, key->protocol);
     1567                        irc_rootmsg(irc, "  %s/%s - DSA", key->accountname, key->protocol);
    14891568                        break;
    14901569                default:
    1491                         irc_usermsg(irc, "  %s/%s - type %d", key->accountname, key->protocol,
     1570                        irc_rootmsg(irc, "  %s/%s - type %d", key->accountname, key->protocol,
    14921571                                key->pubkey_type);
    14931572                }
     
    14981577                hash = otrl_privkey_fingerprint(irc->otr->us, human, key->accountname, key->protocol);
    14991578                if(hash) /* should always succeed */
    1500                         irc_usermsg(irc, "    %s", human);
     1579                        irc_rootmsg(irc, "    %s", human);
    15011580        }
    15021581        if(irc->otr->sent_accountname) {
    1503                 irc_usermsg(irc, "  %s/%s - DSA", irc->otr->sent_accountname,
     1582                irc_rootmsg(irc, "  %s/%s - DSA", irc->otr->sent_accountname,
    15041583                        irc->otr->sent_protocol);
    1505                 irc_usermsg(irc, "    (being generated)");
     1584                irc_rootmsg(irc, "    (being generated)");
    15061585        }
    15071586        for(kg=irc->otr->todo; kg; kg=kg->next) {
    1508                 irc_usermsg(irc, "  %s/%s - DSA", kg->accountname, kg->protocol);
    1509                 irc_usermsg(irc, "    (queued)");
     1587                irc_rootmsg(irc, "  %s/%s - DSA", kg->accountname, kg->protocol);
     1588                irc_rootmsg(irc, "    (queued)");
    15101589        }
    15111590        if(key == irc->otr->us->privkey_root &&
    15121591           !irc->otr->sent_accountname &&
    15131592           kg == irc->otr->todo)
    1514                 irc_usermsg(irc, "  (none)");
     1593                irc_rootmsg(irc, "  (none)");
    15151594
    15161595        /* list all contexts */
    1517         irc_usermsg(irc, "%s", "");
    1518         irc_usermsg(irc, "\x1f" "connection contexts:\x1f (bold=currently encrypted)");
     1596        irc_rootmsg(irc, "%s", "");
     1597        irc_rootmsg(irc, "\x1f" "connection contexts:\x1f (bold=currently encrypted)");
    15191598        for(ctx=irc->otr->us->context_root; ctx; ctx=ctx->next) {\
    15201599                irc_user_t *u;
     
    15301609               
    15311610                if(ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED) {
    1532                         irc_usermsg(irc, "  \x02%s\x02", userstring);
     1611                        irc_rootmsg(irc, "  \x02%s\x02", userstring);
    15331612                } else {
    1534                         irc_usermsg(irc, "  %s", userstring);
     1613                        irc_rootmsg(irc, "  %s", userstring);
    15351614                }
    15361615               
     
    15381617        }
    15391618        if(ctx == irc->otr->us->context_root)
    1540                 irc_usermsg(irc, "  (none)");
     1619                irc_rootmsg(irc, "  (none)");
    15411620}
    15421621
     
    15451624        switch(ctx->otr_offer) {
    15461625        case OFFER_NOT:
    1547                 irc_usermsg(irc, "  otr offer status: none sent");
     1626                irc_rootmsg(irc, "  otr offer status: none sent");
    15481627                break;
    15491628        case OFFER_SENT:
    1550                 irc_usermsg(irc, "  otr offer status: awaiting reply");
     1629                irc_rootmsg(irc, "  otr offer status: awaiting reply");
    15511630                break;
    15521631        case OFFER_ACCEPTED:
    1553                 irc_usermsg(irc, "  otr offer status: accepted our offer");
     1632                irc_rootmsg(irc, "  otr offer status: accepted our offer");
    15541633                break;
    15551634        case OFFER_REJECTED:
    1556                 irc_usermsg(irc, "  otr offer status: ignored our offer");
     1635                irc_rootmsg(irc, "  otr offer status: ignored our offer");
    15571636                break;
    15581637        default:
    1559                 irc_usermsg(irc, "  otr offer status: %d", ctx->otr_offer);
     1638                irc_rootmsg(irc, "  otr offer status: %d", ctx->otr_offer);
    15601639        }
    15611640
    15621641        switch(ctx->msgstate) {
    15631642        case OTRL_MSGSTATE_PLAINTEXT:
    1564                 irc_usermsg(irc, "  connection state: cleartext");
     1643                irc_rootmsg(irc, "  connection state: cleartext");
    15651644                break;
    15661645        case OTRL_MSGSTATE_ENCRYPTED:
    1567                 irc_usermsg(irc, "  connection state: encrypted (v%d)", ctx->protocol_version);
     1646                irc_rootmsg(irc, "  connection state: encrypted (v%d)", ctx->protocol_version);
    15681647                break;
    15691648        case OTRL_MSGSTATE_FINISHED:
    1570                 irc_usermsg(irc, "  connection state: shut down");
     1649                irc_rootmsg(irc, "  connection state: shut down");
    15711650                break;
    15721651        default:
    1573                 irc_usermsg(irc, "  connection state: %d", ctx->msgstate);
    1574         }
    1575 
    1576         irc_usermsg(irc, "  fingerprints: (bold=active)");     
     1652                irc_rootmsg(irc, "  connection state: %d", ctx->msgstate);
     1653        }
     1654
     1655        irc_rootmsg(irc, "  fingerprints: (bold=active)");     
    15771656        show_fingerprints(irc, ctx);
    15781657}
     
    16141693               
    16151694                if(pipe(to) < 0 || pipe(from) < 0) {
    1616                         irc_usermsg(irc, "otr keygen: couldn't create pipe: %s", strerror(errno));
     1695                        irc_rootmsg(irc, "otr keygen: couldn't create pipe: %s", strerror(errno));
    16171696                        return;
    16181697                }
     
    16211700                fromf = fdopen(from[0], "r");
    16221701                if(!tof || !fromf) {
    1623                         irc_usermsg(irc, "otr keygen: couldn't streamify pipe: %s", strerror(errno));
     1702                        irc_rootmsg(irc, "otr keygen: couldn't streamify pipe: %s", strerror(errno));
    16241703                        return;
    16251704                }
     
    16271706                p = fork();
    16281707                if(p<0) {
    1629                         irc_usermsg(irc, "otr keygen: couldn't fork: %s", strerror(errno));
     1708                        irc_rootmsg(irc, "otr keygen: couldn't fork: %s", strerror(errno));
    16301709                        return;
    16311710                }
     
    17071786        myfgets(msg, 512, irc->otr->from);
    17081787       
    1709         irc_usermsg(irc, "%s", msg);
     1788        irc_rootmsg(irc, "%s", msg);
    17101789        if(filename[0]) {
    1711                 char *kf = g_strdup_printf("%s%s.otr_keys", global.conf->configdir, irc->user->nick);
    1712                 char *tmp = g_strdup_printf("%s.new", kf);
    1713                 copyfile(filename, tmp);
    1714                 unlink(filename);
    1715                 rename(tmp,kf);
    1716                 otrl_privkey_read(irc->otr->us, kf);
    1717                 g_free(kf);
    1718                 g_free(tmp);
     1790                if(strsane(irc->user->nick)) {
     1791                        char *kf = g_strdup_printf("%s%s.otr_keys", global.conf->configdir, irc->user->nick);
     1792                        char *tmp = g_strdup_printf("%s.new", kf);
     1793                        copyfile(filename, tmp);
     1794                        unlink(filename);
     1795                        rename(tmp,kf);
     1796                        otrl_privkey_read(irc->otr->us, kf);
     1797                        g_free(kf);
     1798                        g_free(tmp);
     1799                } else {
     1800                        otrl_privkey_read(irc->otr->us, filename);
     1801                        unlink(filename);
     1802                }
    17191803        }
    17201804       
     
    17811865       
    17821866        if(keygen_in_progress(irc, acc->user, acc->prpl->name)) {
    1783                 irc_usermsg(irc, "keygen for %s/%s already in progress",
     1867                irc_rootmsg(irc, "keygen for %s/%s already in progress",
    17841868                        acc->user, acc->prpl->name);
    17851869        } else {
    1786                 irc_usermsg(irc, "starting background keygen for %s/%s",
     1870                irc_rootmsg(irc, "starting background keygen for %s/%s",
    17871871                        acc->user, acc->prpl->name);
    1788                 irc_usermsg(irc, "you will be notified when it completes");
     1872                irc_rootmsg(irc, "you will be notified when it completes");
    17891873                otr_keygen(irc, acc->user, acc->prpl->name);
    17901874        }
    17911875}
     1876
     1877/* check whether a string is safe to use in a path component */
     1878int strsane(const char *s)
     1879{
     1880        return strpbrk(s, "/\\") == NULL;
     1881}
     1882
     1883/* vim: set noet ts=4 sw=4: */
Note: See TracChangeset for help on using the changeset viewer.