- Timestamp:
- 2008-02-09T17:58:13Z (16 years ago)
- Branches:
- master
- Children:
- f55cfe9
- Parents:
- a13855a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
otr.c
ra13855a r5a71d9c 35 35 void op_gone_secure(void *opdata, ConnContext *context); 36 36 37 void op_gone_secure(void *opdata, ConnContext *context);38 39 37 void op_gone_insecure(void *opdata, ConnContext *context); 40 38 … … 53 51 void cmd_otr_abort(irc_t *irc, char **args); /* TODO: does this cmd even make sense? */ 54 52 void cmd_otr_request(irc_t *irc, char **args); /* TODO: do we even need this? */ 55 void cmd_otr_auth(irc_t *irc, char **args); 53 void cmd_otr_smp(irc_t *irc, char **args); 54 void cmd_otr_trust(irc_t *irc, char **args); 56 55 /* TODO: void cmd_otr_affirm(irc_t *irc, char **args); */ 57 56 void cmd_otr_fprints(irc_t *irc, char **args); … … 62 61 { "abort", 1, &cmd_otr_abort, 0 }, 63 62 { "request", 1, &cmd_otr_request, 0 }, 64 { "auth", 2, &cmd_otr_auth, 0 }, 63 { "smp", 2, &cmd_otr_smp, 0 }, 64 { "trust", 6, &cmd_otr_trust, 0 }, 65 65 { "fprints", 0, &cmd_otr_fprints, 0 }, 66 66 { "info", 1, &cmd_otr_info, 0 }, … … 97 97 const char *protocol); 98 98 99 /* determine the nick for a given handle/protocol pair */ 99 /* determine the nick for a given handle/protocol pair 100 returns "handle/protocol" if not found */ 100 101 const char *peernick(irc_t *irc, const char *handle, const char *protocol); 102 103 /* determine the user_t for a given handle/protocol pair 104 returns NULL if not found */ 105 user_t *peeruser(irc_t *irc, const char *handle, const char *protocol); 101 106 102 107 /* handle SMP TLVs from a received message */ 103 108 void otr_handle_smp(struct im_connection *ic, const char *handle, OtrlTLV *tlvs); 109 110 /* update op/voice flag of given user according to encryption state and settings 111 returns 0 if neither op_buddies nor voice_buddies is set to "encrypted", 112 i.e. msgstate should be announced seperately */ 113 int otr_update_modeflags(irc_t *irc, user_t *u); 104 114 105 115 /* show the list of fingerprints associated with a given context */ … … 239 249 240 250 if(!g_mutex_trylock(ic->irc->otr_mutex)) { 241 /* TODO: queue msgs received during keygen for later */ 242 irc_usermsg(ic->irc, "msg from %s during keygen - dropped", 251 user_t *u = user_findhandle(ic, handle); 252 253 /* fallback for non-otr clients */ 254 if(u && !u->encrypted) { 255 return g_strdup(msg); 256 } 257 258 /* TODO: queue msgs received during keygen for later? */ 259 irc_usermsg(ic->irc, "otr msg from %s during keygen - dropped", 243 260 peernick(ic->irc, handle, ic->acc->prpl->name)); 244 261 return NULL; … … 283 300 int otr_send_message(struct im_connection *ic, const char *handle, const char *msg, int flags) 284 301 { 285 286 287 288 302 int st; 303 char *otrmsg = NULL; 304 ConnContext *ctx = NULL; 305 289 306 if(!g_mutex_trylock(ic->irc->otr_mutex)) { 290 irc_usermsg(ic->irc, "msg to %s during keygen - not sent", 291 peernick(ic->irc, handle, ic->acc->prpl->name)); 292 return 1; 307 user_t *u = user_findhandle(ic, handle); 308 309 /* Fallback for non-otr clients. 310 Yes, we must be very sure this doesn't send stuff in the clear where it 311 shouldn't... */ 312 if(u && !u->encrypted) { 313 return ic->acc->prpl->buddy_msg(ic, (char *)handle, (char *)msg, flags); 314 } 315 316 /* otherwise refuse to send */ 317 irc_usermsg(ic->irc, "otr msg to %s not sent during keygen", 318 peernick(ic->irc, handle, ic->acc->prpl->name)); 319 return 1; 293 320 } 294 321 … … 414 441 415 442 int op_display_otr_message(void *opdata, const char *accountname, 416 const char *protocol, const char *username, const char *m sg)443 const char *protocol, const char *username, const char *message) 417 444 { 418 445 struct im_connection *ic = check_imc(opdata, accountname, protocol); 419 420 log_message(LOGLVL_DEBUG, "op_display_otr_message '%s' '%s' '%s' '%s'", accountname, protocol, username, msg); 421 422 irc_usermsg(ic->irc, "%s", msg); 423 446 char *msg = g_strdup(message); 447 448 log_message(LOGLVL_DEBUG, "op_display_otr_message '%s' '%s' '%s' '%s'", accountname, protocol, username, message); 449 450 strip_html(msg); 451 irc_usermsg(ic->irc, "otr: %s", msg); 452 453 g_free(msg); 424 454 return 0; 425 455 } … … 452 482 struct im_connection *ic = 453 483 check_imc(opdata, context->accountname, context->protocol); 484 user_t *u; 454 485 455 486 log_message(LOGLVL_DEBUG, "op_gone_secure '%s' '%s' '%s'", context->accountname, context->protocol, context->username); 456 487 457 irc_usermsg(ic->irc, "conversation with %s is now off the record", 458 peernick(ic->irc, context->username, context->protocol)); 488 u = peeruser(ic->irc, context->username, context->protocol); 489 if(!u) { 490 log_message(LOGLVL_ERROR, 491 "BUG: otr.c: op_gone_secure: user_t for %s/%s not found!", 492 context->username, context->protocol); 493 return; 494 } 495 if(context->active_fingerprint->trust[0]) 496 u->encrypted = 2; 497 else 498 u->encrypted = 1; 499 if(!otr_update_modeflags(ic->irc, u)) 500 irc_usermsg(ic->irc, "conversation with %s is now off the record", u->nick); 459 501 } 460 502 … … 463 505 struct im_connection *ic = 464 506 check_imc(opdata, context->accountname, context->protocol); 507 user_t *u; 465 508 466 509 log_message(LOGLVL_DEBUG, "op_gone_insecure '%s' '%s' '%s'", context->accountname, context->protocol, context->username); 467 510 468 irc_usermsg(ic->irc, "conversation with %s is now in the clear", 469 peernick(ic->irc, context->username, context->protocol)); 511 u = peeruser(ic->irc, context->username, context->protocol); 512 if(!u) { 513 log_message(LOGLVL_ERROR, 514 "BUG: otr.c: op_gone_insecure: user_t for %s/%s not found!", 515 context->username, context->protocol); 516 return; 517 } 518 u->encrypted = 0; 519 if(!otr_update_modeflags(ic->irc, u)) 520 irc_usermsg(ic->irc, "conversation with %s is now in the clear", u->nick); 470 521 } 471 522 … … 474 525 struct im_connection *ic = 475 526 check_imc(opdata, context->accountname, context->protocol); 527 user_t *u; 476 528 477 529 log_message(LOGLVL_DEBUG, "op_still_secure '%s' '%s' '%s' is_reply=%d", 478 530 context->accountname, context->protocol, context->username, is_reply); 479 531 480 irc_usermsg(ic->irc, "otr connection with %s has been refreshed", 481 peernick(ic->irc, context->username, context->protocol)); 532 u = peeruser(ic->irc, context->username, context->protocol); 533 if(!u) { 534 log_message(LOGLVL_ERROR, 535 "BUG: otr.c: op_still_secure: user_t for %s/%s not found!", 536 context->username, context->protocol); 537 return; 538 } 539 if(context->active_fingerprint->trust[0]) 540 u->encrypted = 2; 541 else 542 u->encrypted = 1; 543 if(!otr_update_modeflags(ic->irc, u)) 544 irc_usermsg(ic->irc, "otr connection with %s has been refreshed", u->nick); 482 545 } 483 546 484 547 void op_log_message(void *opdata, const char *message) 485 548 { 486 log_message(LOGLVL_INFO, "%s", message); 549 char *msg = g_strdup(message); 550 551 strip_html(msg); 552 log_message(LOGLVL_INFO, "otr: %s", msg); 553 g_free(msg); 487 554 } 488 555 489 556 int op_max_message_size(void *opdata, ConnContext *context) 490 557 { 491 /* TODO: make max_message_size a property of the prpl. 492 the values here are taken from the libotr UPGRADING file */ 493 if(!strcmp(context->protocol, "msn")) 494 return 1409; 495 if(!strcmp(context->protocol, "yahoo")) 496 return 832; 497 if(!strcmp(context->protocol, "oscar")) 498 return 2343; 558 struct im_connection *ic = 559 check_imc(opdata, context->accountname, context->protocol); 560 561 return ic->acc->prpl->mms; 499 562 } 500 563 … … 542 605 } 543 606 544 void cmd_otr_ auth(irc_t *irc, char **args)607 void cmd_otr_smp(irc_t *irc, char **args) 545 608 { 546 609 user_t *u; … … 589 652 } 590 653 654 int hexval(char a) 655 { 656 int x=tolower(a); 657 658 if(x>='a' && x<='f') 659 x = x - 'a' + 10; 660 else if(x>='0' && x<='9') 661 x = x - '0'; 662 else 663 return -1; 664 665 return x; 666 } 667 668 void cmd_otr_trust(irc_t *irc, char **args) 669 { 670 user_t *u; 671 ConnContext *ctx; 672 unsigned char raw[20]; 673 Fingerprint *fp; 674 int i,j; 675 676 u = user_find(irc, args[1]); 677 if(!u || !u->ic) { 678 irc_usermsg(irc, "%s: unknown user", args[1]); 679 return; 680 } 681 682 ctx = otrl_context_find(irc->otr_us, u->handle, 683 u->ic->acc->user, u->ic->acc->prpl->name, 0, NULL, NULL, NULL); 684 if(!ctx) { 685 irc_usermsg(irc, "%s: no otr context with user", args[1]); 686 return; 687 } 688 689 /* convert given fingerprint to raw representation */ 690 for(i=0; i<5; i++) { 691 for(j=0; j<4; j++) { 692 char *p = args[2+i]+(2*j); 693 char *q = p+1; 694 int x, y; 695 696 if(!*p || !*q) { 697 irc_usermsg(irc, "failed: truncated fingerprint block %d", i+1); 698 return; 699 } 700 701 x = hexval(*p); 702 y = hexval(*q); 703 if(x<0) { 704 irc_usermsg(irc, "failed: %d. hex digit of block %d out of range", 2*j+1, i+1); 705 return; 706 } 707 if(y<0) { 708 irc_usermsg(irc, "failed: %d. hex digit of block %d out of range", 2*j+2, i+1); 709 return; 710 } 711 712 raw[i*4+j] = x*16 + y; 713 } 714 } 715 fp = otrl_context_find_fingerprint(ctx, raw, 0, NULL); 716 if(!fp) { 717 irc_usermsg(irc, "failed: no such fingerprint for %s", args[1]); 718 } else { 719 char *trust = args[7] ? args[7] : "affirmed"; 720 otrl_context_set_trust(fp, trust); 721 irc_usermsg(irc, "fingerprint match, trust set to \"%s\"", trust); 722 if(u->encrypted) 723 u->encrypted = 2; 724 otr_update_modeflags(irc, u); 725 } 726 } 727 591 728 void cmd_otr_fprints(irc_t *irc, char **args) 592 729 { … … 649 786 u->ic->acc->user, u->ic->acc->prpl->name, 0, NULL, NULL, NULL); 650 787 if(!ctx) { 651 irc_usermsg(irc, "no otr info on%s", args[1]);788 irc_usermsg(irc, "no otr context with %s", args[1]); 652 789 return; 653 790 } … … 672 809 irc_usermsg(irc, " otr offer status: %s", offer_status); 673 810 irc_usermsg(irc, " connection state: %s", message_state); 674 irc_usermsg(irc, " protocol version: %d", ctx->protocol_version); 675 fp = ctx->active_fingerprint; 676 if(!fp) { 677 irc_usermsg(irc, " active f'print: none"); 678 } else { 679 otrl_privkey_hash_to_human(human, fp->fingerprint); 680 if(!fp->trust || fp->trust[0] == '\0') { 681 trust="untrusted"; 811 812 if(ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED) { 813 irc_usermsg(irc, " protocol version: %d", ctx->protocol_version); 814 fp = ctx->active_fingerprint; 815 if(!fp) { 816 irc_usermsg(irc, " active f'print: none?"); 682 817 } else { 683 trust=fp->trust; 684 } 685 irc_usermsg(irc, " active f'print: %s (%s)", human, trust); 818 otrl_privkey_hash_to_human(human, fp->fingerprint); 819 if(!fp->trust || fp->trust[0] == '\0') { 820 trust="untrusted"; 821 } else { 822 trust=fp->trust; 823 } 824 irc_usermsg(irc, " active f'print: %s (%s)", human, trust); 825 } 686 826 } 687 827 } … … 809 949 } 810 950 811 const char *peernick(irc_t *irc, const char *handle, const char *protocol)951 user_t *peeruser(irc_t *irc, const char *handle, const char *protocol) 812 952 { 813 953 user_t *u; 814 static char fallback[512]; 815 816 g_snprintf(fallback, 511, "%s/%s", handle, protocol); 954 817 955 for(u=irc->users; u; u=u->next) { 818 956 struct prpl *prpl; … … 822 960 if(strcmp(prpl->name, protocol) == 0 823 961 && prpl->handle_cmp(u->handle, handle) == 0) { 824 return u->nick; 825 } 826 } 827 828 return fallback; 962 return u; 963 } 964 } 965 966 return NULL; 967 } 968 969 const char *peernick(irc_t *irc, const char *handle, const char *protocol) 970 { 971 static char fallback[512]; 972 973 user_t *u = peeruser(irc, handle, protocol); 974 if(u) { 975 return u->nick; 976 } else { 977 g_snprintf(fallback, 511, "%s/%s", handle, protocol); 978 return fallback; 979 } 980 } 981 982 int otr_update_modeflags(irc_t *irc, user_t *u) 983 { 984 char *vo = set_getstr(&irc->set, "voice_buddies"); 985 char *oo = set_getstr(&irc->set, "op_buddies"); 986 char eflag=0, tflag=0; 987 int e = u->encrypted; 988 int t = (u->encrypted > 1); 989 990 if(!strcmp(vo, "encrypted")) 991 eflag='v'; 992 else if(!strcmp(oo, "encrypted")) 993 eflag='o'; 994 if(!strcmp(vo, "trusted")) 995 tflag='v'; 996 else if(!strcmp(oo, "trusted")) 997 tflag='o'; 998 999 if(!eflag) 1000 return 0; 1001 1002 if(tflag) { 1003 irc_write( irc, ":%s!%s@%s MODE %s %c%c%c%c %s %s", irc->mynick, irc->mynick, irc->myhost, 1004 irc->channel, e?'+':'-', eflag, t?'+':'-', tflag, u->nick, u->nick ); 1005 } else { 1006 irc_write( irc, ":%s!%s@%s MODE %s %c%c %s", irc->mynick, irc->mynick, irc->myhost, 1007 irc->channel, e?'+':'-', eflag, u->nick ); 1008 } 1009 1010 return 1; 829 1011 } 830 1012 … … 966 1148 account_t *acc = (account_t *)data; 967 1149 968 /* TODO: remember that we didn't want a key? */969 1150 irc_usermsg(acc->irc, "proceeding without key, otr inoperable on %s/%s", 970 1151 acc->user, acc->prpl->name); 1152 /* TODO: 1153 irc_usermsg(acc->irc, "setting otr policy for %s/%s to \"never\"", 1154 acc->user, acc->prpl->name); 1155 set_setstr(acc->set, "otr_policy", "never"); 1156 */ 971 1157 } 972 1158
Note: See TracChangeset
for help on using the changeset viewer.