static char * save_attachment (CamelMimePart * part, const char *uid, const char *attachment_store) { CamelDataWrapper *content; CamelStream *stream = NULL; CamelStreamFs *stream_fs; char *attach_file = NULL; char *file_url = NULL; const char *mime_filename; content = camel_medium_get_content_object (CAMEL_MEDIUM (part)); mime_filename = camel_mime_part_get_filename (part); attach_file = g_strdup_printf ("%s/%s-%s", attachment_store, uid, mime_filename); stream = camel_stream_fs_new_with_name (attach_file, O_RDWR | O_CREAT | O_TRUNC, 0600); if (stream == NULL) goto end; stream_fs = (CamelStreamFs *) stream; camel_data_wrapper_decode_to_stream (content, stream); file_url = g_strdup_printf ("file://%s", attach_file); end: g_free (attach_file); camel_object_unref (stream); return file_url; }
/** * * "util_get_msg_body" is based on mail-to-task eplugin's get_description function. * which is GPL licensed. * */ static gchar * util_get_msg_body(CamelMimeMessage *message, gchar **text) { CamelDataWrapper *content; CamelStream *mem; CamelContentType *type; CamelMimePart *mime_part = CAMEL_MIME_PART(message); GSList sl; gchar *str, *convert_str = NULL; gsize bytes_read, bytes_written; gint count = 2; content = camel_medium_get_content_object((CamelMedium *) message); if (!content) return; /* * Get non-multipart content from multipart message. */ while (CAMEL_IS_MULTIPART(content) && count > 0) { mime_part = camel_multipart_get_part(CAMEL_MULTIPART(content), 0); content = camel_medium_get_content_object(CAMEL_MEDIUM(mime_part)); count--; } if (!mime_part) return; type = camel_mime_part_get_content_type(mime_part); if (!camel_content_type_is(type, "text", "plain")) return; mem = camel_stream_mem_new(); camel_data_wrapper_decode_to_stream(content, mem); str = g_strndup((const gchar *) ((CamelStreamMem *) mem)->buffer->data, ((CamelStreamMem *) mem)->buffer->len); camel_object_unref(mem); /* convert to UTF-8 string */ if (str && content->mime_type->params && content->mime_type->params->value) { convert_str = g_convert(str, strlen(str), "UTF-8", content->mime_type->params->value, &bytes_read, &bytes_written, NULL); } if (convert_str) *text = convert_str; else *text = str; /*g_free (str); if (convert_str) g_free (convert_str); */ }
static gboolean set_ical_from_mime_part (CamelMimePart * part, ScalixObject * object) { CamelDataWrapper *content; CamelStream *stream; GByteArray *data; icalcomponent *icomp = NULL; icalcomponent *subcomp = NULL; ScalixAppointmentPrivate *priv; priv = SCALIX_APPOINTMENT_GET_PRIVATE (SCALIX_APPOINTMENT (object)); content = camel_medium_get_content_object (CAMEL_MEDIUM (part)); data = g_byte_array_new (); stream = camel_stream_mem_new_with_byte_array (data); camel_data_wrapper_decode_to_stream (content, stream); if (data == NULL || data->data == NULL) { g_print ("Found corrupt ical data\n"); return FALSE; } icomp = icalparser_parse_string ((const char *) data->data); if (icalcomponent_isa (icomp) != ICAL_VCALENDAR_COMPONENT) { icalcomponent_free (icomp); return FALSE; } /* Grab the timezone if any */ subcomp = icalcomponent_get_first_component (icomp, ICAL_VTIMEZONE_COMPONENT); if (subcomp != NULL) { icaltimezone *zone; zone = icaltimezone_new (); icaltimezone_set_component (zone, subcomp); priv->timezone = zone; } /* Grab the main VEVENT */ subcomp = icalcomponent_get_first_component (icomp, ICAL_VEVENT_COMPONENT); e_cal_component_set_icalcomponent (E_CAL_COMPONENT (object), subcomp); return TRUE; }
static CamelCipherValidity * sm_decrypt(CamelCipherContext *context, CamelMimePart *ipart, CamelMimePart *opart, CamelException *ex) { NSSCMSDecoderContext *dec; NSSCMSMessage *cmsg; CamelStreamMem *istream; CamelStream *ostream; CamelCipherValidity *valid = NULL; /* FIXME: This assumes the content is only encrypted. Perhaps its ok for this api to do this ... */ ostream = camel_stream_mem_new(); camel_stream_mem_set_secure((CamelStreamMem *)ostream); /* FIXME: stream this to the decoder incrementally */ istream = (CamelStreamMem *)camel_stream_mem_new(); camel_data_wrapper_decode_to_stream(camel_medium_get_content_object((CamelMedium *)ipart), (CamelStream *)istream); camel_stream_reset((CamelStream *)istream); dec = NSS_CMSDecoder_Start(NULL, sm_write_stream, ostream, /* content callback */ NULL, NULL, NULL, NULL); /* decrypt key callback */ if (NSS_CMSDecoder_Update(dec, (char *) istream->buffer->data, istream->buffer->len) != SECSuccess) { printf("decoder update failed\n"); } camel_object_unref(istream); cmsg = NSS_CMSDecoder_Finish(dec); if (cmsg == NULL) { camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("Decoder failed, error %d"), PORT_GetError()); goto fail; } #if 0 /* not sure if we really care about this? */ if (!NSS_CMSMessage_IsEncrypted(cmsg)) { camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("S/MIME Decrypt: No encrypted content found")); NSS_CMSMessage_Destroy(cmsg); goto fail; } #endif camel_stream_reset(ostream); camel_data_wrapper_construct_from_stream((CamelDataWrapper *)opart, ostream); if (NSS_CMSMessage_IsSigned(cmsg)) { valid = sm_verify_cmsg(context, cmsg, NULL, ex); } else { valid = camel_cipher_validity_new(); valid->encrypt.description = g_strdup(_("Encrypted content")); valid->encrypt.status = CAMEL_CIPHER_VALIDITY_ENCRYPT_ENCRYPTED; } NSS_CMSMessage_Destroy(cmsg); fail: camel_object_unref(ostream); return valid; }
static CamelCipherValidity * sm_verify(CamelCipherContext *context, CamelMimePart *ipart, CamelException *ex) { NSSCMSDecoderContext *dec; NSSCMSMessage *cmsg; CamelStreamMem *mem; CamelStream *constream = NULL; CamelCipherValidity *valid = NULL; CamelContentType *ct; const char *tmp; CamelMimePart *sigpart; CamelDataWrapper *dw; dw = camel_medium_get_content_object((CamelMedium *)ipart); ct = dw->mime_type; /* FIXME: we should stream this to the decoder */ mem = (CamelStreamMem *)camel_stream_mem_new(); if (camel_content_type_is(ct, "multipart", "signed")) { CamelMultipart *mps = (CamelMultipart *)dw; tmp = camel_content_type_param(ct, "protocol"); if (!CAMEL_IS_MULTIPART_SIGNED(mps) || tmp == NULL || (g_ascii_strcasecmp(tmp, context->sign_protocol) != 0 && g_ascii_strcasecmp(tmp, "application/pkcs7-signature") != 0)) { camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot verify message signature: Incorrect message format")); goto fail; } constream = camel_multipart_signed_get_content_stream((CamelMultipartSigned *)mps, ex); if (constream == NULL) goto fail; sigpart = camel_multipart_get_part(mps, CAMEL_MULTIPART_SIGNED_SIGNATURE); if (sigpart == NULL) { camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot verify message signature: Incorrect message format")); goto fail; } } else if (camel_content_type_is(ct, "application", "x-pkcs7-mime")) { sigpart = ipart; } else { camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot verify message signature: Incorrect message format")); goto fail; } dec = NSS_CMSDecoder_Start(NULL, NULL, NULL, /* content callback */ NULL, NULL, /* password callback */ NULL, NULL); /* decrypt key callback */ camel_data_wrapper_decode_to_stream(camel_medium_get_content_object((CamelMedium *)sigpart), (CamelStream *)mem); (void)NSS_CMSDecoder_Update(dec, (char *) mem->buffer->data, mem->buffer->len); cmsg = NSS_CMSDecoder_Finish(dec); if (cmsg == NULL) { camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("Decoder failed")); goto fail; } valid = sm_verify_cmsg(context, cmsg, constream, ex); NSS_CMSMessage_Destroy(cmsg); fail: camel_object_unref(mem); if (constream) camel_object_unref(constream); return valid; }
/* TODO: This is suboptimal, but the only other solution is to pass around NSSCMSMessages */ guint32 camel_smime_context_describe_part(CamelSMIMEContext *context, CamelMimePart *part) { guint32 flags = 0; CamelContentType *ct; const char *tmp; if (!part) return flags; ct = camel_mime_part_get_content_type(part); if (camel_content_type_is(ct, "multipart", "signed")) { tmp = camel_content_type_param(ct, "protocol"); if (tmp && (g_ascii_strcasecmp(tmp, ((CamelCipherContext *)context)->sign_protocol) == 0 || g_ascii_strcasecmp(tmp, "application/pkcs7-signature") == 0)) flags = CAMEL_SMIME_SIGNED; } else if (camel_content_type_is(ct, "application", "x-pkcs7-mime")) { CamelStreamMem *istream; NSSCMSMessage *cmsg; NSSCMSDecoderContext *dec; /* FIXME: stream this to the decoder incrementally */ istream = (CamelStreamMem *)camel_stream_mem_new(); camel_data_wrapper_decode_to_stream(camel_medium_get_content_object((CamelMedium *)part), (CamelStream *)istream); camel_stream_reset((CamelStream *)istream); dec = NSS_CMSDecoder_Start(NULL, NULL, NULL, NULL, NULL, /* password callback */ NULL, NULL); /* decrypt key callback */ NSS_CMSDecoder_Update(dec, (char *) istream->buffer->data, istream->buffer->len); camel_object_unref(istream); cmsg = NSS_CMSDecoder_Finish(dec); if (cmsg) { if (NSS_CMSMessage_IsSigned(cmsg)) { printf("message is signed\n"); flags |= CAMEL_SMIME_SIGNED; } if (NSS_CMSMessage_IsEncrypted(cmsg)) { printf("message is encrypted\n"); flags |= CAMEL_SMIME_ENCRYPTED; } #if 0 if (NSS_CMSMessage_ContainsCertsOrCrls(cmsg)) { printf("message contains certs or crls\n"); flags |= CAMEL_SMIME_CERTS; } #endif NSS_CMSMessage_Destroy(cmsg); } else { printf("Message could not be parsed\n"); } } return flags; }
void org_gnome_format_tnef(void *ep, EMFormatHookTarget *t) { char *tmpdir = NULL, *name = NULL; CamelStream *out; struct dirent *d; DIR *dir; CamelMultipart *mp; CamelMimePart *mainpart; CamelDataWrapper *content; int len; TNEFStruct *tnef; tnef = (TNEFStruct *) g_malloc(sizeof(TNEFStruct)); tmpdir = e_mkdtemp("tnef-attachment-XXXXXX"); if (tmpdir == NULL) return; filepath = tmpdir; name = g_build_filename(tmpdir, ".evo-attachment.tnef", NULL); out = camel_stream_fs_new_with_name(name, O_RDWR|O_CREAT, 0666); if (out == NULL) goto fail; content = camel_medium_get_content_object((CamelMedium *)t->part); if (content == NULL) goto fail; if (camel_data_wrapper_decode_to_stream(content, out) == -1 || camel_stream_close(out) == -1) { camel_object_unref(out); goto fail; } camel_object_unref(out); /* Extracting the winmail.dat */ TNEFInitialize(tnef); tnef->Debug = verbose; if (TNEFParseFile(name, tnef) == -1) { printf("ERROR processing file\n"); } processTnef(tnef); TNEFFree(tnef); /* Extraction done */ dir = opendir(tmpdir); if (dir == NULL) goto fail; mainpart = camel_mime_part_new(); mp = camel_multipart_new(); camel_data_wrapper_set_mime_type((CamelDataWrapper *)mp, "multipart/mixed"); camel_multipart_set_boundary(mp, NULL); camel_medium_set_content_object((CamelMedium *)mainpart, (CamelDataWrapper *)mp); while ((d = readdir(dir))) { CamelMimePart *part; CamelDataWrapper *content; CamelStream *stream; char *path; const char *type; if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..") || !strcmp(d->d_name, ".evo-attachment.tnef")) continue; path = g_build_filename(tmpdir, d->d_name, NULL); stream = camel_stream_fs_new_with_name(path, O_RDONLY, 0); content = camel_data_wrapper_new(); camel_data_wrapper_construct_from_stream(content, stream); camel_object_unref(stream); part = camel_mime_part_new(); camel_mime_part_set_encoding(part, CAMEL_TRANSFER_ENCODING_BINARY); camel_medium_set_content_object((CamelMedium *)part, content); camel_object_unref(content); type = em_utils_snoop_type(part); if (type) camel_data_wrapper_set_mime_type((CamelDataWrapper *)part, type); camel_mime_part_set_filename(part, d->d_name); g_free(path); camel_multipart_add_part(mp, part); } closedir(dir); len = t->format->part_id->len; g_string_append_printf(t->format->part_id, ".tnef"); if (camel_multipart_get_number(mp) > 0) em_format_part_as(t->format, t->stream, mainpart, "multipart/mixed"); else if (t->item->handler.old) t->item->handler.old->handler(t->format, t->stream, t->part, t->item->handler.old); g_string_truncate(t->format->part_id, len); camel_object_unref(mainpart); goto ok; fail: if (t->item->handler.old) t->item->handler.old->handler(t->format, t->stream, t->part, t->item->handler.old); ok: g_free(name); g_free(tmpdir); }