aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--otr.c110
1 files changed, 67 insertions, 43 deletions
diff --git a/otr.c b/otr.c
index 7d64ec35..2baa5c12 100644
--- a/otr.c
+++ b/otr.c
@@ -7,7 +7,7 @@
/*
OTR support (cf. http://www.cypherpunks.ca/otr/)
- 2008, Sven Moritz Hallberg <pesco@khjk.org>
+ 2008-2010, Sven Moritz Hallberg <pesco@khjk.org>
(c) and funded by stonedcoder.org
files used to store OTR data:
@@ -87,6 +87,7 @@ static void cmd_otr(irc_t *irc, char **args);
void cmd_otr_connect(irc_t *irc, char **args);
void cmd_otr_disconnect(irc_t *irc, char **args);
void cmd_otr_smp(irc_t *irc, char **args);
+void cmd_otr_smpq(irc_t *irc, char **args);
void cmd_otr_trust(irc_t *irc, char **args);
void cmd_otr_info(irc_t *irc, char **args);
void cmd_otr_keygen(irc_t *irc, char **args);
@@ -96,6 +97,7 @@ const command_t otr_commands[] = {
{ "connect", 1, &cmd_otr_connect, 0 },
{ "disconnect", 1, &cmd_otr_disconnect, 0 },
{ "smp", 2, &cmd_otr_smp, 0 },
+ { "smpq", 3, &cmd_otr_smpq, 0 },
{ "trust", 6, &cmd_otr_trust, 0 },
{ "info", 0, &cmd_otr_info, 0 },
{ "keygen", 1, &cmd_otr_keygen, 0 },
@@ -155,6 +157,10 @@ irc_user_t *peeruser(irc_t *irc, const char *handle, const char *protocol);
/* handle SMP TLVs from a received message */
void otr_handle_smp(struct im_connection *ic, const char *handle, OtrlTLV *tlvs);
+/* combined handler for the 'otr smp' and 'otr smpq' commands */
+void otr_initiate_smp(irc_t *irc, const char *nick, const char *question,
+ const char *secret);
+
/* update op/voice flag of given user according to encryption state and settings
returns 0 if neither op_buddies nor voice_buddies is set to "encrypted",
i.e. msgstate should be announced seperately */
@@ -728,49 +734,12 @@ void cmd_otr_connect(irc_t *irc, char **args)
void cmd_otr_smp(irc_t *irc, char **args)
{
- irc_user_t *u;
- ConnContext *ctx;
-
- u = irc_user_by_name(irc, args[1]);
- if(!u || !u->bu || !u->bu->ic) {
- irc_usermsg(irc, "%s: unknown user", args[1]);
- return;
- }
- if(!(u->bu->flags & BEE_USER_ONLINE)) {
- irc_usermsg(irc, "%s is offline", args[1]);
- return;
- }
-
- ctx = otrl_context_find(irc->otr->us, u->bu->handle,
- u->bu->ic->acc->user, u->bu->ic->acc->prpl->name, 1, NULL, NULL, NULL);
- if(!ctx) {
- /* huh? out of memory or what? */
- return;
- }
+ otr_initiate_smp(irc, args[1], NULL, args[2]); /* no question */
+}
- if(ctx->smstate->nextExpected != OTRL_SMP_EXPECT1) {
- log_message(LOGLVL_INFO,
- "SMP already in phase %d, sending abort before reinitiating",
- ctx->smstate->nextExpected+1);
- otrl_message_abort_smp(irc->otr->us, &otr_ops, u->bu->ic, ctx);
- otrl_sm_state_free(ctx->smstate);
- }
-
- /* warning: the following assumes that smstates are cleared whenever an SMP
- is completed or aborted! */
- if(ctx->smstate->secret == NULL) {
- irc_usermsg(irc, "smp: initiating with %s...", u->nick);
- otrl_message_initiate_smp(irc->otr->us, &otr_ops,
- u->bu->ic, ctx, (unsigned char *)args[2], strlen(args[2]));
- /* smp is now in EXPECT2 */
- } else {
- /* if we're still in EXPECT1 but smstate is initialized, we must have
- received the SMP1, so let's issue a response */
- irc_usermsg(irc, "smp: responding to %s...", u->nick);
- otrl_message_respond_smp(irc->otr->us, &otr_ops,
- u->bu->ic, ctx, (unsigned char *)args[2], strlen(args[2]));
- /* smp is now in EXPECT3 */
- }
+void cmd_otr_smpq(irc_t *irc, char **args)
+{
+ otr_initiate_smp(irc, args[1], args[2], args[3]);
}
void cmd_otr_trust(irc_t *irc, char **args)
@@ -1186,6 +1155,61 @@ void otr_handle_smp(struct im_connection *ic, const char *handle, OtrlTLV *tlvs)
}
}
+/* combined handler for the 'otr smp' and 'otr smpq' commands */
+void otr_initiate_smp(irc_t *irc, const char *nick, const char *question,
+ const char *secret)
+{
+ irc_user_t *u;
+ ConnContext *ctx;
+
+ u = irc_user_by_name(irc, nick);
+ if(!u || !u->bu || !u->bu->ic) {
+ irc_usermsg(irc, "%s: unknown user", nick);
+ return;
+ }
+ if(!(u->bu->flags & BEE_USER_ONLINE)) {
+ irc_usermsg(irc, "%s is offline", nick);
+ return;
+ }
+
+ ctx = otrl_context_find(irc->otr->us, u->bu->handle,
+ u->bu->ic->acc->user, u->bu->ic->acc->prpl->name, 1, NULL, NULL, NULL);
+ if(!ctx) {
+ /* huh? out of memory or what? */
+ return;
+ }
+
+ if(ctx->smstate->nextExpected != OTRL_SMP_EXPECT1) {
+ log_message(LOGLVL_INFO,
+ "SMP already in phase %d, sending abort before reinitiating",
+ ctx->smstate->nextExpected+1);
+ otrl_message_abort_smp(irc->otr->us, &otr_ops, u->bu->ic, ctx);
+ otrl_sm_state_free(ctx->smstate);
+ }
+
+ /* warning: the following assumes that smstates are cleared whenever an SMP
+ is completed or aborted! */
+ if(ctx->smstate->secret == NULL) {
+ irc_usermsg(irc, "smp: initiating with %s...", u->nick);
+ if(question) {
+ otrl_message_initiate_smp_q(irc->otr->us, &otr_ops,
+ u->bu->ic, ctx, question,
+ (unsigned char *)secret, strlen(secret));
+ } else {
+ otrl_message_initiate_smp(irc->otr->us, &otr_ops,
+ u->bu->ic, ctx, (unsigned char *)secret, strlen(secret));
+ }
+ /* smp is now in EXPECT2 */
+ } else {
+ /* if we're still in EXPECT1 but smstate is initialized, we must have
+ received the SMP1, so let's issue a response */
+ irc_usermsg(irc, "smp: responding to %s...", u->nick);
+ otrl_message_respond_smp(irc->otr->us, &otr_ops,
+ u->bu->ic, ctx, (unsigned char *)secret, strlen(secret));
+ /* smp is now in EXPECT3 */
+ }
+}
+
/* helper to assert that account and protocol names given to ops below always
match the im_connection passed through as opdata */
struct im_connection *check_imc(void *opdata, const char *accountname,