Ejemplo n.º 1
0
static gboolean pgpinline_is_signed(MimeInfo *mimeinfo)
{
    PrivacyDataPGP *data = NULL;
    const gchar *sig_indicator = "-----BEGIN PGP SIGNED MESSAGE-----";
    gchar *textdata, *sigpos;

    cm_return_val_if_fail(mimeinfo != NULL, FALSE);

    if (procmime_mimeinfo_parent(mimeinfo) == NULL)
        return FALSE; /* not parent */

    if (mimeinfo->type != MIMETYPE_TEXT &&
            (mimeinfo->type != MIMETYPE_APPLICATION ||
             g_ascii_strcasecmp(mimeinfo->subtype, "pgp")))
        return FALSE;

    /* Seal the deal. This has to be text/plain through and through. */
    if (mimeinfo->type == MIMETYPE_APPLICATION)
    {
        mimeinfo->type = MIMETYPE_TEXT;
        g_free(mimeinfo->subtype);
        mimeinfo->subtype = g_strdup("plain");
    }

    if (mimeinfo->privacy != NULL) {
        data = (PrivacyDataPGP *) mimeinfo->privacy;
        if (data->done_sigtest)
            return data->is_signed;
    }

    textdata = get_part_as_string(mimeinfo);
    if (!textdata)
        return FALSE;

    if ((sigpos = strstr(textdata, sig_indicator)) == NULL) {
        g_free(textdata);
        return FALSE;
    }

    if (!(sigpos == textdata) && !(sigpos[-1] == '\n')) {
        g_free(textdata);
        return FALSE;
    }

    g_free(textdata);

    if (data == NULL) {
        data = pgpinline_new_privacydata();
        mimeinfo->privacy = (PrivacyData *) data;
    }
    if (data != NULL) {
        data->done_sigtest = TRUE;
        data->is_signed = TRUE;
    }

    return TRUE;
}
Ejemplo n.º 2
0
static gboolean pgpmime_is_encrypted(MimeInfo *mimeinfo)
{
	MimeInfo *tmpinfo;
	const gchar *tmpstr;
	const gchar *begin_indicator = "-----BEGIN PGP MESSAGE-----";
	const gchar *end_indicator = "-----END PGP MESSAGE-----";
	gchar *textdata;

	if (mimeinfo->type != MIMETYPE_MULTIPART)
		return FALSE;
	if (g_ascii_strcasecmp(mimeinfo->subtype, "encrypted"))
		return FALSE;
	tmpstr = procmime_mimeinfo_get_parameter(mimeinfo, "protocol");
	if ((tmpstr == NULL) || g_ascii_strcasecmp(tmpstr, "application/pgp-encrypted"))
		return FALSE;
	if (g_node_n_children(mimeinfo->node) != 2)
		return FALSE;
	
	tmpinfo = (MimeInfo *) g_node_nth_child(mimeinfo->node, 0)->data;
	if (tmpinfo->type != MIMETYPE_APPLICATION)
		return FALSE;
	if (g_ascii_strcasecmp(tmpinfo->subtype, "pgp-encrypted"))
		return FALSE;
	
	tmpinfo = (MimeInfo *) g_node_nth_child(mimeinfo->node, 1)->data;
	if (tmpinfo->type != MIMETYPE_APPLICATION)
		return FALSE;
	if (g_ascii_strcasecmp(tmpinfo->subtype, "octet-stream"))
		return FALSE;
	
	textdata = get_part_as_string(tmpinfo);
	if (!textdata)
		return FALSE;
	
	if (!pgp_locate_armor_header(textdata, begin_indicator)) {
		g_free(textdata);
		return FALSE;
	}
	if (!pgp_locate_armor_header(textdata, end_indicator)) {
		g_free(textdata);
		return FALSE;
	}

	g_free(textdata);

	return TRUE;
}
Ejemplo n.º 3
0
static gboolean pgpinline_is_encrypted(MimeInfo *mimeinfo)
{
    const gchar *begin_indicator = "-----BEGIN PGP MESSAGE-----";
    const gchar *end_indicator = "-----END PGP MESSAGE-----";
    gchar *textdata;

    cm_return_val_if_fail(mimeinfo != NULL, FALSE);

    if (procmime_mimeinfo_parent(mimeinfo) == NULL)
        return FALSE; /* not parent */

    if (mimeinfo->type != MIMETYPE_TEXT &&
            (mimeinfo->type != MIMETYPE_APPLICATION ||
             g_ascii_strcasecmp(mimeinfo->subtype, "pgp")))
        return FALSE;

    /* Seal the deal. This has to be text/plain through and through. */
    if (mimeinfo->type == MIMETYPE_APPLICATION)
    {
        mimeinfo->type = MIMETYPE_TEXT;
        g_free(mimeinfo->subtype);
        mimeinfo->subtype = g_strdup("plain");
    }

    textdata = get_part_as_string(mimeinfo);
    if (!textdata)
        return FALSE;

    if (!pgp_locate_armor_header(textdata, begin_indicator)) {
        g_free(textdata);
        return FALSE;
    }
    if (!pgp_locate_armor_header(textdata, end_indicator)) {
        g_free(textdata);
        return FALSE;
    }

    g_free(textdata);

    return TRUE;
}
Ejemplo n.º 4
0
static MimeInfo *pgpinline_decrypt(MimeInfo *mimeinfo)
{
    MimeInfo *decinfo, *parseinfo;
    gpgme_data_t cipher, plain;
    FILE *dstfp;
    gchar *fname;
    gchar *textdata = NULL;
    static gint id = 0;
    const gchar *src_codeset = NULL;
    gpgme_verify_result_t sigstat = 0;
    PrivacyDataPGP *data = NULL;
    gpgme_ctx_t ctx;
    gchar *chars;
    size_t len;
    const gchar *begin_indicator = "-----BEGIN PGP MESSAGE-----";
    const gchar *end_indicator = "-----END PGP MESSAGE-----";
    gchar *pos;

    if (gpgme_new(&ctx) != GPG_ERR_NO_ERROR)
        return NULL;

    gpgme_set_textmode(ctx, 1);
    gpgme_set_armor(ctx, 1);

    cm_return_val_if_fail(mimeinfo != NULL, NULL);
    cm_return_val_if_fail(pgpinline_is_encrypted(mimeinfo), NULL);

    if (procmime_mimeinfo_parent(mimeinfo) == NULL ||
            mimeinfo->type != MIMETYPE_TEXT) {
        gpgme_release(ctx);
        privacy_set_error(_("Couldn't parse mime part."));
        return NULL;
    }

    textdata = get_part_as_string(mimeinfo);
    if (!textdata) {
        gpgme_release(ctx);
        privacy_set_error(_("Couldn't get text data."));
        return NULL;
    }

    debug_print("decrypting '%s'\n", textdata);
    gpgme_data_new_from_mem(&cipher, textdata, (size_t)strlen(textdata), 1);

    plain = sgpgme_decrypt_verify(cipher, &sigstat, ctx);
    if (sigstat && !sigstat->signatures)
        sigstat = NULL;

    gpgme_data_release(cipher);

    if (plain == NULL) {
        gpgme_release(ctx);
        return NULL;
    }

    fname = g_strdup_printf("%s%cplaintext.%08x",
                            get_mime_tmp_dir(), G_DIR_SEPARATOR, ++id);

    if ((dstfp = g_fopen(fname, "wb")) == NULL) {
        FILE_OP_ERROR(fname, "fopen");
        privacy_set_error(_("Couldn't open decrypted file %s"), fname);
        g_free(fname);
        gpgme_data_release(plain);
        gpgme_release(ctx);
        return NULL;
    }

    src_codeset = procmime_mimeinfo_get_parameter(mimeinfo, "charset");
    if (src_codeset == NULL)
        src_codeset = CS_ISO_8859_1;

    if (fprintf(dstfp, "MIME-Version: 1.0\r\n"
                "Content-Type: text/plain; charset=%s\r\n"
                "Content-Transfer-Encoding: 8bit\r\n"
                "\r\n",
                src_codeset) < 0) {
        FILE_OP_ERROR(fname, "fprintf");
        privacy_set_error(_("Couldn't write to decrypted file %s"), fname);
        goto FILE_ERROR;
    }

    /* Store any part before encrypted text */
    pos = pgp_locate_armor_header(textdata, begin_indicator);
    if (pos != NULL && (pos - textdata) > 0) {
        if (fwrite(textdata, 1, pos - textdata, dstfp) < pos - textdata) {
            FILE_OP_ERROR(fname, "fwrite");
            privacy_set_error(_("Couldn't write to decrypted file %s"), fname);
            goto FILE_ERROR;
        }
    }

    if (fwrite(_("\n--- Start of PGP/Inline encrypted data ---\n"), 1,
               strlen(_("\n--- Start of PGP/Inline encrypted data ---\n")),
               dstfp) < strlen(_("\n--- Start of PGP/Inline encrypted data ---\n"))) {
        FILE_OP_ERROR(fname, "fwrite");
        privacy_set_error(_("Couldn't write to decrypted file %s"), fname);
        goto FILE_ERROR;
    }
    chars = sgpgme_data_release_and_get_mem(plain, &len);
    if (len > 0) {
        if (fwrite(chars, 1, len, dstfp) < len) {
            FILE_OP_ERROR(fname, "fwrite");
            g_free(chars);
            privacy_set_error(_("Couldn't write to decrypted file %s"), fname);
            goto FILE_ERROR;
        }
    }
    g_free(chars);
    /* Store any part after encrypted text */
    if (fwrite(_("--- End of PGP/Inline encrypted data ---\n"), 1,
               strlen(_("--- End of PGP/Inline encrypted data ---\n")),
               dstfp) < strlen(_("--- End of PGP/Inline encrypted data ---\n"))) {
        FILE_OP_ERROR(fname, "fwrite");
        privacy_set_error(_("Couldn't write to decrypted file %s"), fname);
        goto FILE_ERROR;
    }
    if (pos != NULL) {
        pos = pgp_locate_armor_header(pos, end_indicator);
        if (pos != NULL && *pos != '\0') {
            pos += strlen(end_indicator);
            if (fwrite(pos, 1, strlen(pos), dstfp) < strlen(pos)) {
                FILE_OP_ERROR(fname, "fwrite");
                privacy_set_error(_("Couldn't write to decrypted file %s"), fname);
                goto FILE_ERROR;
            }
        }
    }

    if (fclose(dstfp) == EOF) {
        FILE_OP_ERROR(fname, "fclose");
        privacy_set_error(_("Couldn't close decrypted file %s"), fname);
        g_free(fname);
        gpgme_data_release(plain);
        gpgme_release(ctx);
        return NULL;
    }

    parseinfo = procmime_scan_file(fname);
    g_free(fname);

    if (parseinfo == NULL) {
        gpgme_release(ctx);
        privacy_set_error(_("Couldn't scan decrypted file."));
        return NULL;
    }
    decinfo = g_node_first_child(parseinfo->node) != NULL ?
              g_node_first_child(parseinfo->node)->data : NULL;

    if (decinfo == NULL) {
        gpgme_release(ctx);
        privacy_set_error(_("Couldn't scan decrypted file parts."));
        return NULL;
    }

    g_node_unlink(decinfo->node);
    procmime_mimeinfo_free_all(parseinfo);

    decinfo->tmp = TRUE;

    if (sigstat != GPGME_SIG_STAT_NONE) {
        if (decinfo->privacy != NULL) {
            data = (PrivacyDataPGP *) decinfo->privacy;
        } else {
            data = pgpinline_new_privacydata();
            decinfo->privacy = (PrivacyData *) data;
        }
        if (data != NULL) {
            data->done_sigtest = TRUE;
            data->is_signed = TRUE;
            data->sigstatus = sigstat;
            if (data->ctx)
                gpgme_release(data->ctx);
            data->ctx = ctx;
        }
    } else
        gpgme_release(ctx);

    return decinfo;

FILE_ERROR:
    fclose(dstfp);
    g_free(fname);
    gpgme_data_release(plain);
    gpgme_release(ctx);
    return NULL;
}
Ejemplo n.º 5
0
static gint pgpinline_check_signature(MimeInfo *mimeinfo)
{
    PrivacyDataPGP *data = NULL;
    gchar *textdata = NULL, *tmp = NULL;
    gpgme_data_t plain = NULL, cipher = NULL;
    gpgme_error_t err;

    cm_return_val_if_fail(mimeinfo != NULL, 0);

    if (procmime_mimeinfo_parent(mimeinfo) == NULL) {
        privacy_set_error(_("Incorrect part"));
        return 0; /* not parent */
    }
    if (mimeinfo->type != MIMETYPE_TEXT) {
        privacy_set_error(_("Not a text part"));
        debug_print("type %d\n", mimeinfo->type);
        return 0;
    }
    cm_return_val_if_fail(mimeinfo->privacy != NULL, 0);
    data = (PrivacyDataPGP *) mimeinfo->privacy;

    textdata = get_part_as_string(mimeinfo);

    if (!textdata) {
        g_free(textdata);
        privacy_set_error(_("Couldn't get text data."));
        return 0;
    }

    /* gtk2: convert back from utf8 */
    tmp = conv_codeset_strdup(textdata, CS_UTF_8,
                              procmime_mimeinfo_get_parameter(mimeinfo, "charset"));
    if (!tmp) {
        tmp = conv_codeset_strdup(textdata, CS_UTF_8,
                                  conv_get_locale_charset_str_no_utf8());
    }
    if (!tmp) {
        g_warning("Can't convert charset to anything sane");
        tmp = conv_codeset_strdup(textdata, CS_UTF_8, CS_US_ASCII);
    }
    g_free(textdata);

    if (!tmp) {
        privacy_set_error(_("Couldn't convert text data to any sane charset."));
        return 0;
    }
    textdata = g_strdup(tmp);
    g_free(tmp);

    if ((err = gpgme_new(&data->ctx)) != GPG_ERR_NO_ERROR) {
        debug_print(("Couldn't initialize GPG context, %s"), gpgme_strerror(err));
        privacy_set_error(_("Couldn't initialize GPG context, %s"), gpgme_strerror(err));
        g_free(textdata);
        return 0;
    }
    gpgme_set_textmode(data->ctx, 1);
    gpgme_set_armor(data->ctx, 1);

    gpgme_data_new_from_mem(&plain, textdata, (size_t)strlen(textdata), 1);
    gpgme_data_new(&cipher);

    data->sigstatus = sgpgme_verify_signature(data->ctx, plain, NULL, cipher);

    gpgme_data_release(plain);
    gpgme_data_release(cipher);

    g_free(textdata);

    return 0;
}