Changes in otr.c [858ea01:faa75c0e]
Legend:
- Unmodified
- Added
- Removed
-
otr.c
r858ea01 rfaa75c0e 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * 4 * Copyright 2002-20 08Wilmer van der Gaast and others *4 * Copyright 2002-2010 Wilmer van der Gaast and others * 5 5 \********************************************************************/ 6 6 … … 8 8 OTR support (cf. http://www.cypherpunks.ca/otr/) 9 9 10 2008,Sven Moritz Hallberg <pesco@khjk.org>11 (c) andfunded by stonedcoder.org10 (c) 2008-2010 Sven Moritz Hallberg <pesco@khjk.org> 11 (c) 2008 funded by stonedcoder.org 12 12 13 13 files used to store OTR data: … … 87 87 void cmd_otr_disconnect(irc_t *irc, char **args); 88 88 void cmd_otr_smp(irc_t *irc, char **args); 89 void cmd_otr_smpq(irc_t *irc, char **args); 89 90 void cmd_otr_trust(irc_t *irc, char **args); 90 91 void cmd_otr_info(irc_t *irc, char **args); … … 96 97 { "disconnect", 1, &cmd_otr_disconnect, 0 }, 97 98 { "smp", 2, &cmd_otr_smp, 0 }, 99 { "smpq", 3, &cmd_otr_smpq, 0 }, 98 100 { "trust", 6, &cmd_otr_trust, 0 }, 99 101 { "info", 0, &cmd_otr_info, 0 }, … … 154 156 /* handle SMP TLVs from a received message */ 155 157 void otr_handle_smp(struct im_connection *ic, const char *handle, OtrlTLV *tlvs); 158 159 /* combined handler for the 'otr smp' and 'otr smpq' commands */ 160 void otr_smp_or_smpq(irc_t *irc, const char *nick, const char *question, 161 const char *secret); 156 162 157 163 /* update op/voice flag of given user according to encryption state and settings … … 732 738 void cmd_otr_smp(irc_t *irc, char **args) 733 739 { 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_smp_or_smpq(irc, args[1], NULL, args[2]); /* no question */ 741 } 742 743 void cmd_otr_smpq(irc_t *irc, char **args) 744 { 745 otr_smp_or_smpq(irc, args[1], args[2], args[3]); 777 746 } 778 747 … … 1098 1067 if(!context) { 1099 1068 /* 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); 1100 1072 return; 1101 1073 } 1102 1074 nextMsg = context->smstate->nextExpected; 1103 1075 1076 if (context->smstate->sm_prog_state == OTRL_SMP_PROG_CHEATED) { 1077 irc_usermsg(irc, "smp %s: opponent violated protocol, aborting", 1078 u->nick); 1079 otrl_message_abort_smp(us, ops, u->bu->ic, context); 1080 otrl_sm_state_free(context->smstate); 1081 return; 1082 } 1083 1084 tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1Q); 1085 if (tlv) { 1086 if (nextMsg != OTRL_SMP_EXPECT1) { 1087 irc_usermsg(irc, "smp %s: spurious SMP1Q received, aborting", u->nick); 1088 otrl_message_abort_smp(us, ops, u->bu->ic, context); 1089 otrl_sm_state_free(context->smstate); 1090 } else { 1091 char *question = g_strndup((char *)tlv->data, tlv->len); 1092 irc_usermsg(irc, "smp: initiated by %s with question: \x02\"%s\"\x02", u->nick, 1093 question); 1094 irc_usermsg(irc, "smp: respond with \x02otr smp %s <answer>\x02", 1095 u->nick); 1096 g_free(question); 1097 /* smp stays in EXPECT1 until user responds */ 1098 } 1099 } 1104 1100 tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1); 1105 1101 if (tlv) { … … 1134 1130 } else { 1135 1131 /* SMP3 received, otrl_message_receiving will have sent SMP4 and set fp trust */ 1136 const char *trust = context->active_fingerprint->trust; 1137 if(!trust || trust[0]=='\0') { 1138 irc_usermsg(irc, "smp %s: secrets did not match, fingerprint not trusted", 1132 /* as noted above, fp trust SHOULD have been set by libotr. 1133 * however at least version 3.2.0 seems to forget it when 1134 * responding to an smp session that was initiated with SMP1Q 1135 * (question and answer); other cases appear to work fine. 1136 * as a workaround, we explicitly set it below. 1137 */ 1138 if(context->smstate->sm_prog_state == OTRL_SMP_PROG_SUCCEEDED) { 1139 otrl_context_set_trust(context->active_fingerprint, "smp"); 1140 irc_usermsg(irc, "smp %s: secrets proved equal, fingerprint trusted", 1139 1141 u->nick); 1140 1142 } else { 1141 irc_usermsg(irc, "smp %s: secrets proved equal, fingerprint trusted", 1143 otrl_context_set_trust(context->active_fingerprint, ""); 1144 irc_usermsg(irc, "smp %s: secrets did not match, fingerprint not trusted", 1142 1145 u->nick); 1143 1146 } … … 1154 1157 } else { 1155 1158 /* SMP4 received, otrl_message_receiving will have set fp trust */ 1156 const char *trust = context->active_fingerprint->trust; 1157 if(!trust || trust[0]=='\0') { 1158 irc_usermsg(irc, "smp %s: secrets did not match, fingerprint not trusted", 1159 if(context->smstate->sm_prog_state == OTRL_SMP_PROG_SUCCEEDED) { 1160 irc_usermsg(irc, "smp %s: secrets proved equal, fingerprint trusted", 1159 1161 u->nick); 1160 1162 } else { 1161 irc_usermsg(irc, "smp %s: secrets proved equal, fingerprint trusted",1163 irc_usermsg(irc, "smp %s: secrets did not match, fingerprint not trusted", 1162 1164 u->nick); 1163 1165 } … … 1171 1173 otrl_sm_state_free(context->smstate); 1172 1174 /* smp is in back in EXPECT1 */ 1175 } 1176 } 1177 1178 /* combined handler for the 'otr smp' and 'otr smpq' commands */ 1179 void otr_smp_or_smpq(irc_t *irc, const char *nick, const char *question, 1180 const char *secret) 1181 { 1182 irc_user_t *u; 1183 ConnContext *ctx; 1184 1185 u = irc_user_by_name(irc, nick); 1186 if(!u || !u->bu || !u->bu->ic) { 1187 irc_usermsg(irc, "%s: unknown user", nick); 1188 return; 1189 } 1190 if(!(u->bu->flags & BEE_USER_ONLINE)) { 1191 irc_usermsg(irc, "%s is offline", nick); 1192 return; 1193 } 1194 1195 ctx = otrl_context_find(irc->otr->us, u->bu->handle, 1196 u->bu->ic->acc->user, u->bu->ic->acc->prpl->name, 0, NULL, NULL, NULL); 1197 if(!ctx || ctx->msgstate != OTRL_MSGSTATE_ENCRYPTED) { 1198 irc_usermsg(irc, "smp: otr inactive with %s, try \x02otr connect" 1199 " %s\x02", nick, nick); 1200 return; 1201 } 1202 1203 if(ctx->smstate->nextExpected != OTRL_SMP_EXPECT1) { 1204 log_message(LOGLVL_INFO, 1205 "SMP already in phase %d, sending abort before reinitiating", 1206 ctx->smstate->nextExpected+1); 1207 otrl_message_abort_smp(irc->otr->us, &otr_ops, u->bu->ic, ctx); 1208 otrl_sm_state_free(ctx->smstate); 1209 } 1210 1211 if(question) { 1212 /* this was 'otr smpq', just initiate */ 1213 irc_usermsg(irc, "smp: initiating with %s...", u->nick); 1214 otrl_message_initiate_smp_q(irc->otr->us, &otr_ops, u->bu->ic, ctx, 1215 question, (unsigned char *)secret, strlen(secret)); 1216 /* smp is now in EXPECT2 */ 1217 } else { 1218 /* this was 'otr smp', initiate or reply */ 1219 /* warning: the following assumes that smstates are cleared whenever an SMP 1220 is completed or aborted! */ 1221 if(ctx->smstate->secret == NULL) { 1222 irc_usermsg(irc, "smp: initiating with %s...", u->nick); 1223 otrl_message_initiate_smp(irc->otr->us, &otr_ops, 1224 u->bu->ic, ctx, (unsigned char *)secret, strlen(secret)); 1225 /* smp is now in EXPECT2 */ 1226 } else { 1227 /* if we're still in EXPECT1 but smstate is initialized, we must have 1228 received the SMP1, so let's issue a response */ 1229 irc_usermsg(irc, "smp: responding to %s...", u->nick); 1230 otrl_message_respond_smp(irc->otr->us, &otr_ops, 1231 u->bu->ic, ctx, (unsigned char *)secret, strlen(secret)); 1232 /* smp is now in EXPECT3 */ 1233 } 1173 1234 } 1174 1235 }
Note: See TracChangeset
for help on using the changeset viewer.