Example #1
0
/* Find the instance of this context that has the best security level,
   and for which we have most recently received a message from. Note that most
   recent in this case is limited to a one-second resolution. */
ConnContext * otrl_context_find_recent_secure_instance(ConnContext * context)
{
    ConnContext *curp; /* for iteration */
    ConnContext *m_context; /* master */
    ConnContext *cresult = context;  /* best so far */

    if (!context) {
	return cresult;
    }

    m_context = context->m_context;

    for (curp = m_context; curp && curp->m_context == m_context;
	    curp = curp->next) {
	int msgstate_improved = 0; /* 0 == same, 1 == improved   */
	int trust_improved = 0;    /* (will immediately 'continue' if worse
				    * than) */

	if (cresult->msgstate == curp->msgstate) {
	    msgstate_improved = 0;
	} else if (curp->msgstate == OTRL_MSGSTATE_ENCRYPTED ||
		(cresult->msgstate == OTRL_MSGSTATE_PLAINTEXT &&
		curp->msgstate == OTRL_MSGSTATE_FINISHED)) {
	    msgstate_improved = 1;
	} else {
	    continue;
	}


	if (otrl_context_is_fingerprint_trusted(cresult->active_fingerprint) ==
		otrl_context_is_fingerprint_trusted(curp->active_fingerprint)) {

	    trust_improved = 0;
	} else if
		(otrl_context_is_fingerprint_trusted(curp->active_fingerprint)){

	    trust_improved = 1;
	} else {
	    continue;
	}

	if (msgstate_improved || trust_improved ||
		(!msgstate_improved && !trust_improved &&
		curp->context_priv->lastrecv >=
		cresult->context_priv->lastrecv)) {
	    cresult = curp;
	}
    }

    return cresult;
}
Example #2
0
    TrustLevel getTrustLevel(const SessionContext &ctx, OtrlUserState userState, otrl_instag_t instance)
    {
        ConnContext *context = otrl_context_find(
                userState,
                ctx.recipientName.toLocal8Bit(),
                ctx.accountName.toLocal8Bit(),
                ctx.protocol.toLocal8Bit(),
                instance, 0, NULL, NULL, NULL);

        if(context == nullptr) {
            qCWarning(KTP_PROXY) << "Could not get trust level";
            return TrustLevel::NOT_PRIVATE;
        }

        switch(context->msgstate) {
            case OTRL_MSGSTATE_PLAINTEXT:
                return TrustLevel::NOT_PRIVATE;
            case OTRL_MSGSTATE_ENCRYPTED:
                {
                    if(otrl_context_is_fingerprint_trusted(context->active_fingerprint)) {
                        return TrustLevel::VERIFIED;
                    } else {
                        return TrustLevel::UNVERIFIED;
                    }
                }
            case OTRL_MSGSTATE_FINISHED:
                return TrustLevel::FINISHED;
        }
        return TrustLevel::NOT_PRIVATE;
    }
Example #3
0
void input_show_otr(char *arg) {
    if (conn->conn == NULL)
        return;

    printf("\n");
    if (strlen(arg) <= 0) {
        check_key_gen_state();
        return;
    } else {
        b_echostr_s();
        struct BuddyList *buddy = find_buddy(arg);
        if (buddy) {
            printf("[OTR] status for %s\n", arg);
            printf("  local otr: ");
            switch (buddy->otr) {
            case -1:
                printf("disabled\n");
                break;
            case 0:
                printf("inactive\n");
                break;
            case 1:
                printf("active\n");
                break;
            default:
                printf("error\n");
                break;
            }
            if (buddy->otr_context) {
                if (buddy->otr_context->active_fingerprint) {
                    char human_hash[OTRL_PRIVKEY_FPRINT_HUMAN_LEN];
                    otrl_privkey_hash_to_human(human_hash,
                                               buddy->otr_context->active_fingerprint->fingerprint);
                    int ret = otrl_context_is_fingerprint_trusted(buddy->otr_context->active_fingerprint);
                    printf("  fingerprint: %s (%s)\n", human_hash, ret ? "trusted" : "untrusted");
                }
                printf("  context state: ");
                switch (buddy->otr_context->msgstate) {
                case OTRL_MSGSTATE_ENCRYPTED:
                    printf("encrypted\n");
                    break;
                case OTRL_MSGSTATE_PLAINTEXT:
                    printf("plaintext\n");
                    break;
                case OTRL_MSGSTATE_FINISHED:
                    printf("finished\n");
                    break;
                default:
                    printf("error\n");
                    break;
                }
            }
        } else {
            printf("[OTR] buddy not found %s\n", arg);
        }
        return;
    }
}
Example #4
0
/*
 * Trust our peer.
 */
void otr_trust(SERVER_REC *irssi, const char *nick, char *str_fp,
		struct otr_user_state *ustate)
{
	char peerfp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN];
	struct otr_peer_context *opc;
	ConnContext *ctx;
	Fingerprint *fp_trust;

	assert(ustate);

	if (!irssi && !str_fp) {
		IRSSI_NOTICE(NULL, nick, "Need a fingerprint!");
		goto error;
	}

	/* No human string fingerprint given. */
	if (!str_fp) {
		ctx = otr_find_context(irssi, nick, FALSE);
		if (!ctx) {
			goto error;
		}

		opc = ctx->app_data;
		/* Always NEED a peer context or else code error. */
		assert(opc);

		fp_trust = ctx->active_fingerprint;
	} else {
		fp_trust = otr_find_hash_fingerprint_from_human(str_fp, ustate);
	}

	if (fp_trust) {
		int ret;

		ret = otrl_context_is_fingerprint_trusted(fp_trust);
		if (ret) {
			IRSSI_NOTICE(irssi, nick, "Already trusted!");
			goto end;
		}

		/* Trust level is manual at this point. */
		otrl_context_set_trust(fp_trust, "manual");
		key_write_fingerprints(ustate);

		otr_status_change(irssi, nick, OTR_STATUS_TRUST_MANUAL);

		otrl_privkey_hash_to_human(peerfp, fp_trust->fingerprint);
		IRSSI_NOTICE(irssi, nick, "Fingerprint %g%s%n trusted!", peerfp);
	} else {
		IRSSI_NOTICE(irssi, nick, "Fingerprint %y%s%n NOT found",
				(str_fp != NULL) ? str_fp : "");
	}

end:
error:
	return;
}
Example #5
0
/*
 * Distrust a fingerprint.
 *
 * If str_fp is not NULL, it must be on the OTR human format like this:
 * "487FFADA 5073FEDD C5AB5C14 5BB6C1FF 6D40D48A". If str_fp is NULL, get the
 * context of the target nickname, check for the OTR peer context active
 * fingerprint and distrust it.
 */
void otr_distrust(SERVER_REC *irssi, const char *nick, char *str_fp,
		struct otr_user_state *ustate)
{
	int ret;
	char fp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN];
	Fingerprint *fp_distrust;
	ConnContext *ctx;
	struct otr_peer_context *opc;

	if (!irssi && !str_fp) {
		IRSSI_NOTICE(NULL, nick, "Need a fingerprint!");
		goto error;
	}

	/* No human string fingerprint given. */
	if (!str_fp) {
		ctx = otr_find_context(irssi, nick, FALSE);
		if (!ctx) {
			goto error;
		}

		opc = ctx->app_data;
		/* Always NEED a peer context or else code error. */
		assert(opc);

		fp_distrust = opc->active_fingerprint;
	} else {
		fp_distrust = otr_find_hash_fingerprint_from_human(str_fp, ustate);
	}

	if (fp_distrust) {
		ret = otrl_context_is_fingerprint_trusted(fp_distrust);
		if (!ret) {
			/* Fingerprint already not trusted. Do nothing. */
			IRSSI_NOTICE(irssi, nick, "Already not trusting it!");
			goto end;
		}

		otrl_privkey_hash_to_human(fp, fp_distrust->fingerprint);
		otrl_context_set_trust(fp_distrust, "");
		/* Update fingerprints file. */
		key_write_fingerprints(ustate);
		IRSSI_NOTICE(irssi, nick, "Fingerprint %y%s%n distrusted.",
				fp);
	} else {
		IRSSI_NOTICE(irssi, nick, "Fingerprint %y%s%n NOT found",
				(str_fp != NULL) ? str_fp : "");
	}

end:
error:
	return;
}
Example #6
0
/*
 * Gone secure.
 */
static void ops_secure(void *opdata, ConnContext *context)
{
	int ret;
	char ownfp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN];
	char peerfp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN];
	SERVER_REC *irssi = opdata;
	struct otr_peer_context *opc;

	assert(context);
	/* This should *really* not happened */
	assert(context->msgstate == OTRL_MSGSTATE_ENCRYPTED);

	IRSSI_NOTICE(irssi, context->username, "Gone %9secure%9");
	otr_status_change(irssi, context->username, OTR_STATUS_GONE_SECURE);

	opc = context->app_data;
	opc->active_fingerprint = context->active_fingerprint;

	ret = otrl_context_is_fingerprint_trusted(context->active_fingerprint);
	if (ret) {
		/* Secure and trusted */
		goto end;
	}

	/* Not authenticated. Let's print out the fingerprints for comparison. */
	otrl_privkey_hash_to_human(peerfp,
			context->active_fingerprint->fingerprint);
	otrl_privkey_fingerprint(user_state_global->otr_state, ownfp,
			context->accountname, OTR_PROTOCOL_ID);

	IRSSI_NOTICE(irssi, context->username, "Your peer is not "
			"authenticated. To make sure you're talking to the right person you can "
			"either agree on a secret and use the authentication command "
			"%9/otr auth%9 or %9/otr authq [QUESTION] SECRET%9. You can also "
			"use the traditional way and compare fingerprints "
			"(e.g. telephone or GPG-signed mail) and subsequently enter "
			"%9/otr trust%9.");

	IRSSI_NOTICE(irssi, context->username, "Your fingerprint is: %y%s%n",
			ownfp);
	IRSSI_NOTICE(irssi, context->username, "%9%s's%9 fingerprint is: %r%s%n",
			context->username, peerfp);

end:
	return;
}
Example #7
0
/*
 * Get the OTR status of this conversation.
 */
enum otr_status_format otr_get_status_format(SERVER_REC *irssi,
		const char *nick)
{
	int ret;
	enum otr_status_format code;
	ConnContext *ctx = NULL;

	assert(irssi);

	ctx = otr_find_context(irssi, nick, FALSE);
	if (!ctx) {
		code = TXT_STB_PLAINTEXT;
		goto end;
	}

	switch (ctx->msgstate) {
	case OTRL_MSGSTATE_PLAINTEXT:
		code = TXT_STB_PLAINTEXT;
		break;
	case OTRL_MSGSTATE_ENCRYPTED:
		/* Begin by checking trust. */
		ret = otrl_context_is_fingerprint_trusted(ctx->active_fingerprint);
		if (ret) {
			code = TXT_STB_TRUST;
		} else {
			code = TXT_STB_UNTRUSTED;
		}
		break;
	case OTRL_MSGSTATE_FINISHED:
		code = TXT_STB_FINISHED;
		break;
	default:
		IRSSI_NOTICE(irssi, nick, "BUG Found! "
				"Please write us a mail and describe how you got here");
		code = TXT_STB_UNKNOWN;
		break;
	}

end:
	if (ctx) {
		IRSSI_DEBUG("Code: %d, state: %d, sm_prog_state: %d, auth state: %d",
				code, ctx->msgstate, ctx->smstate->sm_prog_state,
				ctx->auth.authstate);
	}
	return code;
}
Example #8
0
/*
 * Initiate or respond to SMP authentication.
 */
void otr_auth(SERVER_REC *irssi, const char *nick, const char *question,
		const char *secret)
{
	int ret;
	size_t secret_len = 0;
	ConnContext *ctx;
	struct otr_peer_context *opc;

	assert(irssi);
	assert(nick);

	ctx = otr_find_context(irssi, nick, 0);
	if (!ctx) {
		IRSSI_NOTICE(irssi, nick, "Context for %9%s%9 not found.", nick);
		goto end;
	}

	opc = ctx->app_data;
	/* Again, code flow error. */
	assert(opc);

	if (ctx->msgstate != OTRL_MSGSTATE_ENCRYPTED) {
		IRSSI_INFO(irssi, nick,
				"You need to establish an OTR session before you "
				"can authenticate.");
		goto end;
	}

	/* Aborting an ongoing auth */
	if (ctx->smstate->nextExpected != OTRL_SMP_EXPECT1) {
		otr_auth_abort(irssi, nick);
	}

	/* reset trust level */
	if (ctx->active_fingerprint) {
		ret = otrl_context_is_fingerprint_trusted(ctx->active_fingerprint);
		if (!ret) {
			otrl_context_set_trust(ctx->active_fingerprint, "");
			key_write_fingerprints(user_state_global);
		}
	}

	/* Libotr allows empty secret. */
	if (secret) {
		secret_len = strlen(secret);
	}

	if (opc->ask_secret) {
		otrl_message_respond_smp(user_state_global->otr_state, &otr_ops,
				irssi, ctx, (unsigned char *) secret, secret_len);
		otr_status_change(irssi, nick, OTR_STATUS_SMP_RESPONDED);
		IRSSI_NOTICE(irssi, nick, "%yResponding to authentication...%n");
	} else {
		if (question) {
			otrl_message_initiate_smp_q(user_state_global->otr_state,
				&otr_ops, irssi, ctx, question, (unsigned char *) secret,
				secret_len);
		} else {
			otrl_message_initiate_smp(user_state_global->otr_state,
				&otr_ops, irssi, ctx, (unsigned char *) secret, secret_len);
		}
		otr_status_change(irssi, nick, OTR_STATUS_SMP_STARTED);
		IRSSI_NOTICE(irssi, nick, "%yInitiated authentication...%n");
	}

	opc->ask_secret = 0;

end:
	return;
}