예제 #1
0
static MimeViewer *get_viewer_for_mimeinfo(MimeView *mimeview, MimeInfo *partinfo)
{
	gchar *content_type = NULL;
	MimeViewer *viewer = NULL;

	if ((partinfo->type == MIMETYPE_APPLICATION) &&
            (!g_strcasecmp(partinfo->subtype, "octet-stream"))) {
		const gchar *filename;

		filename = procmime_mimeinfo_get_parameter(partinfo, "filename");
		if (filename == NULL)
			filename = procmime_mimeinfo_get_parameter(partinfo, "name");
		if (filename != NULL)
			content_type = procmime_get_mime_type(filename);
	} else {
		content_type = procmime_get_content_type_str(partinfo->type, partinfo->subtype);
	}

	if (content_type != NULL) {
		viewer = get_viewer_for_content_type(mimeview, content_type);
		g_free(content_type);
	}

	return viewer;
}
예제 #2
0
gchar *get_part_as_string(MimeInfo *mimeinfo)
{
	gchar *textdata = NULL;
	gchar *filename = NULL;
	FILE *fp;

	cm_return_val_if_fail(mimeinfo != NULL, 0);
	procmime_decode_content(mimeinfo);
	
	if (mimeinfo->content == MIMECONTENT_MEM)
		textdata = g_strdup(mimeinfo->data.mem);
	else {
		filename = procmime_get_tmp_file_name(mimeinfo);
		if (procmime_get_part(filename, mimeinfo) < 0) {
			g_warning("error dumping temporary file '%s'", filename);
			g_free(filename);
			return NULL;
		}
		fp = claws_fopen(filename,"rb");
		if (!fp) {
			g_warning("error opening temporary file '%s'", filename);
			g_free(filename);
			return NULL;
		}
		textdata = fp_read_noconv(fp);
		claws_fclose(fp);
		g_unlink(filename);
		g_free(filename);
	}

	if (!g_utf8_validate(textdata, -1, NULL)) {
		gchar *tmp = NULL;
		codeconv_set_strict(TRUE);
		if (procmime_mimeinfo_get_parameter(mimeinfo, "charset")) {
			tmp = conv_codeset_strdup(textdata,
				procmime_mimeinfo_get_parameter(mimeinfo, "charset"),
				CS_UTF_8);
		}
		if (!tmp) {
			tmp = conv_codeset_strdup(textdata,
				conv_get_locale_charset_str_no_utf8(), 
				CS_UTF_8);
		}
		codeconv_set_strict(FALSE);
		if (!tmp) {
			tmp = conv_codeset_strdup(textdata,
				conv_get_locale_charset_str_no_utf8(), 
				CS_UTF_8);
		}
		if (tmp) {
			g_free(textdata);
			textdata = tmp;
		}
	}

	return textdata;	
}
예제 #3
0
static const gchar *get_part_name(MimeInfo *partinfo)
{
	const gchar *name;

	name = procmime_mimeinfo_get_parameter(partinfo, "filename");
	if (name == NULL)
		name = procmime_mimeinfo_get_parameter(partinfo, "name");
	if (name == NULL)
		name = "";

	return name;
}
예제 #4
0
static gboolean pgpmime_is_signed(MimeInfo *mimeinfo)
{
	MimeInfo *parent;
	MimeInfo *signature;
	const gchar *protocol;
	PrivacyDataPGP *data = NULL;
	
	cm_return_val_if_fail(mimeinfo != NULL, FALSE);
	if (mimeinfo->privacy != NULL) {
		data = (PrivacyDataPGP *) mimeinfo->privacy;
		if (data->done_sigtest)
			return data->is_signed;
	}
	
	/* check parent */
	parent = procmime_mimeinfo_parent(mimeinfo);
	if (parent == NULL)
		return FALSE;
	if ((parent->type != MIMETYPE_MULTIPART) ||
	    g_ascii_strcasecmp(parent->subtype, "signed"))
		return FALSE;
	protocol = procmime_mimeinfo_get_parameter(parent, "protocol");
	if ((protocol == NULL) || 
	    (g_ascii_strcasecmp(protocol, "application/pgp-signature")))
		return FALSE;

	/* check if mimeinfo is the first child */
	if (parent->node->children->data != mimeinfo)
		return FALSE;

	/* check signature */
	signature = parent->node->children->next != NULL ? 
	    (MimeInfo *) parent->node->children->next->data : NULL;
	if (signature == NULL)
		return FALSE;
	if ((signature->type != MIMETYPE_APPLICATION) ||
	    (g_ascii_strcasecmp(signature->subtype, "pgp-signature")))
		return FALSE;

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

	return TRUE;
}
예제 #5
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;
}
예제 #6
0
파일: pgpinline.c 프로젝트: buzz/claws
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;
}
예제 #7
0
파일: pgpinline.c 프로젝트: buzz/claws
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;
}