Browse Source

...

async_key_management
vb 7 years ago
parent
commit
ef57aafa75
8 changed files with 456 additions and 30 deletions
  1. +63
    -0
      src/etpan_mime.c
  2. +13
    -0
      src/etpan_mime.h
  3. +1
    -1
      src/message_api.c
  4. +351
    -20
      src/mime.c
  5. +2
    -0
      src/pEpEngine.h
  6. +4
    -4
      src/transport.c
  7. +3
    -3
      src/transport.h
  8. +19
    -2
      test/mime_test.cc

+ 63
- 0
src/etpan_mime.c View File

@ -372,3 +372,66 @@ enomem:
return NULL;
}
struct mailimf_field * create_optional_field(
const char *field,
const char *value
)
{
char *_field = NULL;
char *_value = NULL;
struct mailimf_optional_field *optional_field = NULL;
_field = strdup(field);
if (_field == NULL)
goto enomem;
_value = mailmime_encode_subject_header("utf-8", value, 0);
if (_value == NULL)
goto enomem;
optional_field = mailimf_optional_field_new(_field, _value);
if (optional_field == NULL)
goto enomem;
struct mailimf_field * result = calloc(1, sizeof(struct mailimf_field));
assert(result);
if (result == NULL)
goto enomem;
result->fld_type = MAILIMF_FIELD_OPTIONAL_FIELD;
result->fld_data.fld_optional_field = optional_field;
return result;
enomem:
if (optional_field) {
mailimf_optional_field_free(optional_field);
}
else {
free(_field);
free(_value);
}
return NULL;
}
int _append_optional_field(
clist *list,
const char *field,
const char *value
)
{
int r;
struct mailimf_field * optional_field =
create_optional_field(field, value);
if (optional_field == NULL)
return -1;
r = clist_append(list, optional_field);
if (r)
mailimf_field_free(optional_field);
return r;
}

+ 13
- 0
src/etpan_mime.h View File

@ -1,6 +1,8 @@
#pragma once
#include <libetpan/libetpan.h>
#include <libetpan/mailmime.h>
#include <libetpan/mailmime_encode.h>
struct mailmime * part_new_empty(
struct mailmime_content * content,
@ -53,3 +55,14 @@ struct mailimf_mailbox * mailbox_from_string(
const char *address
);
struct mailimf_field * create_optional_field(
const char *field,
const char *value
);
int _append_optional_field(
clist *list,
const char *field,
const char *value
);

+ 1
- 1
src/message_api.c View File

@ -132,7 +132,7 @@ static message * clone_to_empty_message(const message * src)
}
if (src->reply_to) {
msg->reply_to = identity_dup(src->reply_to);
msg->reply_to = identity_list_dup(src->reply_to);
if (msg->reply_to == NULL)
goto enomem;
}


+ 351
- 20
src/mime.c View File

@ -1,6 +1,5 @@
#include "mime.h"
#include <libetpan/mailmime.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
@ -10,6 +9,8 @@
#include "etpan_mime.h"
#include "wrappers.h"
#define NOT_IMPLEMENTED assert(0);
static PEP_STATUS render_mime(struct mailmime *mime, char **mimetext)
{
PEP_STATUS status = PEP_STATUS_OK;
@ -230,7 +231,31 @@ pep_error:
return status;
}
static struct mailimf_mailbox_list * mbl_from_identity(const pEp_identity *ident)
static struct mailimf_mailbox * identity_to_mailbox(const pEp_identity *ident)
{
char *_username = NULL;
struct mailimf_mailbox *mb;
_username = mailmime_encode_subject_header("utf-8", ident->username, 0);
if (_username == NULL)
goto enomem;
mb = mailbox_from_string(_username, ident->address);
if (mb == NULL)
goto enomem;
free(_username);
_username = NULL;
return mb;
enomem:
free(_username);
return NULL;
}
static struct mailimf_mailbox_list * identity_to_mbl(
const pEp_identity *ident)
{
struct mailimf_mailbox_list *mbl = NULL;
struct mailimf_mailbox *mb = NULL;
@ -243,7 +268,7 @@ static struct mailimf_mailbox_list * mbl_from_identity(const pEp_identity *ident
if (list == NULL)
goto enomem;
mb = mailbox_from_string(ident->username, ident->address);
mb = identity_to_mailbox(ident);
if (mb == NULL)
goto enomem;
@ -267,7 +292,7 @@ enomem:
return NULL;
}
static struct mailimf_address_list * mal_from_identity_list(identity_list *il)
static struct mailimf_address_list * identity_list_to_mal(identity_list *il)
{
struct mailimf_address_list *mal = NULL;
struct mailimf_mailbox *mb = NULL;
@ -283,7 +308,7 @@ static struct mailimf_address_list * mal_from_identity_list(identity_list *il)
identity_list *_il;
for (_il = il; _il; _il = _il->next) {
mb = mailbox_from_string(_il->ident->username, _il->ident->address);
mb = identity_to_mailbox(_il->ident);
if (mb == NULL)
goto enomem;
@ -316,7 +341,7 @@ enomem:
return NULL;
}
static clist * clist_from_stringlist(stringlist_t *sl)
static clist * stringlist_to_clist(stringlist_t *sl)
{
clist * cl = clist_new();
assert(cl);
@ -326,7 +351,7 @@ static clist * clist_from_stringlist(stringlist_t *sl)
stringlist_t *_sl;
for (_sl = sl; _sl; _sl = _sl->next) {
int r;
char * value = strdup(_sl->value);
char * value = mailmime_encode_subject_header("utf-8", _sl->value, 0);
assert(value);
if (value == NULL) {
clist_free(cl);
@ -378,7 +403,7 @@ static PEP_STATUS build_fields(const message *msg, struct mailimf_fields **resul
}
/* if (subject) */ {
char *_subject = strdup(subject);
char *_subject = mailmime_encode_subject_header("utf-8", subject, 1);
if (_subject == NULL)
goto enomem;
@ -405,7 +430,7 @@ static PEP_STATUS build_fields(const message *msg, struct mailimf_fields **resul
}
/* if (msg->from) */ {
struct mailimf_mailbox_list *from = mbl_from_identity(msg->from);
struct mailimf_mailbox_list *from = identity_to_mbl(msg->from);
if (from == NULL)
goto enomem;
@ -418,7 +443,7 @@ static PEP_STATUS build_fields(const message *msg, struct mailimf_fields **resul
}
if (msg->to) {
struct mailimf_address_list *to = mal_from_identity_list(msg->to);
struct mailimf_address_list *to = identity_list_to_mal(msg->to);
if (to == NULL)
goto enomem;
@ -431,7 +456,7 @@ static PEP_STATUS build_fields(const message *msg, struct mailimf_fields **resul
}
if (msg->cc) {
struct mailimf_address_list *cc = mal_from_identity_list(msg->cc);
struct mailimf_address_list *cc = identity_list_to_mal(msg->cc);
if (cc == NULL)
goto enomem;
@ -444,7 +469,7 @@ static PEP_STATUS build_fields(const message *msg, struct mailimf_fields **resul
}
if (msg->bcc) {
struct mailimf_address_list *bcc = mal_from_identity_list(msg->bcc);
struct mailimf_address_list *bcc = identity_list_to_mal(msg->bcc);
if (bcc == NULL)
goto enomem;
@ -457,33 +482,33 @@ static PEP_STATUS build_fields(const message *msg, struct mailimf_fields **resul
}
if (msg->reply_to) {
struct mailimf_mailbox_list *reply_to= mbl_from_identity(msg->reply_to);
struct mailimf_address_list *reply_to = identity_list_to_mal(msg->reply_to);
if (reply_to == NULL)
goto enomem;
r = _append_field(fields_list, MAILIMF_FIELD_REPLY_TO,
(_new_func_t) mailimf_reply_to_new, reply_to);
if (r) {
mailimf_mailbox_list_free(reply_to);
mailimf_address_list_free(reply_to);
goto enomem;
}
}
if (msg->in_reply_to) {
char *in_reply_to = strdup(msg->in_reply_to);
clist *in_reply_to = stringlist_to_clist(msg->in_reply_to);
if (in_reply_to == NULL)
goto enomem;
r = _append_field(fields_list, MAILIMF_FIELD_IN_REPLY_TO,
(_new_func_t) mailimf_in_reply_to_new, in_reply_to);
if (r) {
free(in_reply_to);
clist_free(in_reply_to);
goto enomem;
}
}
if (msg->references) {
clist *references = clist_from_stringlist(msg->references);
clist *references = stringlist_to_clist(msg->references);
if (references == NULL)
goto enomem;
@ -496,7 +521,7 @@ static PEP_STATUS build_fields(const message *msg, struct mailimf_fields **resul
}
if (msg->keywords) {
clist *keywords = clist_from_stringlist(msg->keywords);
clist *keywords = stringlist_to_clist(msg->keywords);
if (keywords == NULL)
goto enomem;
@ -509,7 +534,8 @@ static PEP_STATUS build_fields(const message *msg, struct mailimf_fields **resul
}
if (msg->comments) {
char *comments = strdup(msg->comments);
char *comments = mailmime_encode_subject_header("utf-8", msg->comments,
0);
if (comments == NULL)
goto enomem;
@ -521,6 +547,10 @@ static PEP_STATUS build_fields(const message *msg, struct mailimf_fields **resul
}
}
r = _append_optional_field(fields_list, "X-pEp-Version", PEP_VERSION);
if (r)
goto enomem;
fields = mailimf_fields_new(fields_list);
assert(fields);
if (fields == NULL)
@ -663,6 +693,293 @@ pep_error:
return status;
}
static pEp_identity *mailbox_to_identity(const struct mailimf_mailbox * mb)
{
pEp_identity *ident;
char *username = NULL;
size_t index;
int r;
index = 0;
r = mailmime_encoded_phrase_parse("utf-8", mb->mb_display_name,
strlen(mb->mb_display_name), &index, "utf-8", &username);
if (r)
goto enomem;
ident = new_identity(mb->mb_addr_spec, NULL, NULL, username);
if (ident == NULL)
goto enomem;
free(username);
return ident;
enomem:
free(username);
return NULL;
}
static pEp_identity * mbl_to_identity(const struct mailimf_mailbox_list * mbl)
{
struct mailimf_mailbox * mb = clist_content(clist_begin(mbl->mb_list));
return mailbox_to_identity(mb);
}
static identity_list * mal_to_identity_list(
const struct mailimf_address_list *mal
)
{
PEP_STATUS status = PEP_STATUS_OK;
identity_list *il = NULL;
clist *list = mal->ad_list;
struct mailimf_address * addr = NULL;
struct mailimf_mailbox *mb = NULL;
clistiter *cur;
int r;
assert(mal);
il = new_identity_list(NULL);
if (il == NULL)
goto enomem;
identity_list *_il = il;
for (cur = clist_begin(list); cur != NULL ; cur = clist_next(cur)) {
pEp_identity *ident;
addr = clist_content(cur);
switch(addr->ad_type) {
case MAILIMF_ADDRESS_MAILBOX:
ident = mailbox_to_identity(addr->ad_data.ad_mailbox);
if (ident == NULL)
goto enomem;
_il = identity_list_add(_il, ident);
if (_il == NULL)
goto enomem;
break;
case MAILIMF_ADDRESS_GROUP:
{
clistiter *cur2;
struct mailimf_mailbox_list * mbl =
addr->ad_data.ad_group->grp_mb_list;
for (cur2 = clist_begin(mbl->mb_list); cur2 != NULL;
cur2 = clist_next(cur2)) {
ident = mailbox_to_identity(clist_content(cur));
if (ident == NULL)
goto enomem;
_il = identity_list_add(_il, ident);
if (_il == NULL)
goto enomem;
}
}
break;
default:
assert(0);
goto enomem;
}
}
return il;
enomem:
free_identity_list(il);
return NULL;
}
static stringlist_t * clist_to_stringlist(const clist *list)
{
char *text = NULL;;
stringlist_t * sl = new_stringlist(NULL);
if (sl == NULL)
return NULL;
clistiter *cur;
stringlist_t *_sl = sl;
for (cur = clist_begin(list); cur != NULL; cur = clist_next(cur)) {
char *phrase = clist_content(cur);
size_t index;
int r;
index = 0;
r = mailmime_encoded_phrase_parse("utf-8", phrase, strlen(phrase),
&index, "utf-8", &text);
if (r)
goto enomem;
_sl = stringlist_add(_sl, text);
if (_sl == NULL)
goto enomem;
free(text);
text = NULL;
}
return _sl;
enomem:
free_stringlist(sl);
free(text);
return NULL;
}
static PEP_STATUS read_fields(message *msg, clist *fieldlist)
{
PEP_STATUS status = PEP_STATUS_OK;
struct mailimf_field * _field;
clistiter *cur;
size_t index;
int r;
for (cur = clist_begin(fieldlist); cur != NULL; cur = clist_next(cur)) {
_field = clist_content(cur);
switch (_field->fld_type) {
case MAILIMF_FIELD_MESSAGE_ID:
{
char * text = _field->fld_data.fld_message_id->mid_value;
index = 0;
r = mailmime_encoded_phrase_parse("utf-8", text,
strlen(text), &index, "utf-8", &msg->id);
if (r)
goto enomem;
}
break;
case MAILIMF_FIELD_SUBJECT:
{
char * text = _field->fld_data.fld_subject->sbj_value;
index = 0;
r = mailmime_encoded_phrase_parse("utf-8", text,
strlen(text), &index, "utf-8", &msg->shortmsg);
if (r)
goto enomem;
}
break;
case MAILIMF_FIELD_ORIG_DATE:
{
struct mailimf_date_time *date =
_field->fld_data.fld_orig_date->dt_date_time;
msg->sent = etpantime_to_timestamp(date);
if (msg->sent == NULL)
goto enomem;
}
break;
case MAILIMF_FIELD_FROM:
{
struct mailimf_mailbox_list *mbl =
_field->fld_data.fld_from->frm_mb_list;
pEp_identity *ident;
ident = mbl_to_identity(mbl);
if (ident == NULL)
goto pep_error;
msg->from = ident;
}
break;
case MAILIMF_FIELD_TO:
{
struct mailimf_address_list *mal =
_field->fld_data.fld_to->to_addr_list;
identity_list *il = mal_to_identity_list(mal);
if (il == NULL)
goto enomem;
msg->to = il;
}
break;
case MAILIMF_FIELD_CC:
{
struct mailimf_address_list *mal =
_field->fld_data.fld_cc->cc_addr_list;
identity_list *il = mal_to_identity_list(mal);
if (il == NULL)
goto enomem;
msg->cc = il;
}
break;
case MAILIMF_FIELD_BCC:
{
struct mailimf_address_list *mal =
_field->fld_data.fld_bcc->bcc_addr_list;
identity_list *il = mal_to_identity_list(mal);
if (il == NULL)
goto enomem;
msg->bcc = il;
}
break;
case MAILIMF_FIELD_REPLY_TO:
{
struct mailimf_address_list *mal =
_field->fld_data.fld_reply_to->rt_addr_list;
identity_list *il = mal_to_identity_list(mal);
if (il == NULL)
goto enomem;
msg->reply_to = il;
}
break;
case MAILIMF_FIELD_IN_REPLY_TO:
{
clist *list = _field->fld_data.fld_in_reply_to->mid_list;
stringlist_t *sl = clist_to_stringlist(list);
if (sl == NULL)
goto enomem;
msg->in_reply_to = sl;
}
break;
case MAILIMF_FIELD_REFERENCES:
{
clist *list = _field->fld_data.fld_references->mid_list;
stringlist_t *sl = clist_to_stringlist(list);
if (sl == NULL)
goto enomem;
msg->references = sl;
}
break;
case MAILIMF_FIELD_KEYWORDS:
{
clist *list = _field->fld_data.fld_keywords->kw_list;
stringlist_t *sl = clist_to_stringlist(list);
if (sl == NULL)
goto enomem;
msg->keywords = sl;
}
break;
case MAILIMF_FIELD_COMMENTS:
{
char * text = _field->fld_data.fld_comments->cm_value;
index = 0;
r = mailmime_encoded_phrase_parse("utf-8", text,
strlen(text), &index, "utf-8", &msg->comments);
if (r)
goto enomem;
}
break;
}
}
return PEP_STATUS_OK;
enomem:
status = PEP_OUT_OF_MEMORY;
pep_error:
return status;
}
DYNAMIC_API PEP_STATUS mime_decode_message(
const char *mimetext,
message **msg
@ -671,13 +988,15 @@ DYNAMIC_API PEP_STATUS mime_decode_message(
PEP_STATUS status = PEP_STATUS_OK;
struct mailmime * mime = NULL;
int r;
message *_msg = NULL;
size_t index;
assert(mimetext);
assert(msg);
*msg = NULL;
size_t index = 0;
index = 0;
r = mailmime_parse(mimetext, strlen(mimetext), &index, &mime);
assert(r == 0);
assert(mime);
@ -688,7 +1007,17 @@ DYNAMIC_API PEP_STATUS mime_decode_message(
goto err_mime;
}
_msg = calloc(1, sizeof(message));
if (_msg == NULL)
goto enomem;
clist * _fieldlist = mime->mm_data.mm_message.mm_fields->fld_list;
status = read_fields(_msg, _fieldlist);
if (status != PEP_STATUS_OK)
goto pep_error;
mailmime_free(mime);
*msg = _msg;
return status;
@ -700,6 +1029,8 @@ enomem:
status = PEP_OUT_OF_MEMORY;
pep_error:
free_message(_msg);
if (mime)
mailmime_free(mime);


+ 2
- 0
src/pEpEngine.h View File

@ -19,6 +19,8 @@ extern "C" {
#endif
#define PEP_VERSION "1.0"
// pEp Engine API
// caveat:


+ 4
- 4
src/transport.c View File

@ -236,8 +236,8 @@ DYNAMIC_API void free_message(message *msg)
free_identity(msg->recv_by);
free_identity_list(msg->cc);
free_identity_list(msg->bcc);
free_identity(msg->reply_to);
free(msg->in_reply_to);
free_identity_list(msg->reply_to);
free_stringlist(msg->in_reply_to);
free_stringlist(msg->references);
free_stringlist(msg->keywords);
free(msg->comments);
@ -328,13 +328,13 @@ DYNAMIC_API message * message_dup(const message *src)
}
if (src->reply_to) {
msg->reply_to = identity_dup(src->reply_to);
msg->reply_to = identity_list_dup(src->reply_to);
if (msg->reply_to == NULL)
goto enomem;
}
if (src->in_reply_to) {
msg->in_reply_to = strdup(src->in_reply_to);
msg->in_reply_to = stringlist_dup(src->in_reply_to);
assert(msg->in_reply_to);
if (msg->in_reply_to == NULL)
goto enomem;


+ 3
- 3
src/transport.h View File

@ -197,9 +197,9 @@ typedef struct _message {
// is received
identity_list *cc; // whom a CC is being sent
identity_list *bcc; // whom a BCC is being sent
pEp_identity *reply_to; // where a reply should go to
char *in_reply_to; // UTF-8 string with MessageID of
// refering message
identity_list *reply_to; // where a reply should go to
stringlist_t *in_reply_to; // list of UTF-8 strings with
// MessageIDs ofrefering messages
struct _message *refering_msg_ref; // reference to refering message
stringlist_t *references; // list of UTF-8 strings with references
struct _message_ref_list *refered_by; // list of references to messages being


+ 19
- 2
test/mime_test.cc View File

@ -22,8 +22,8 @@ int main() {
// testing multipart/alternative
message *msg2 = new_message(PEP_dir_incoming,
new_identity("vb@dingens.org", NULL, NULL, NULL),
new_identity_list(new_identity("trischa@dingens.org", NULL, NULL, NULL)),
new_identity("vb@dingens.org", NULL, NULL, "Volker Birk"),
new_identity_list(new_identity("trischa@dingens.org", NULL, NULL, "Patricia Bädnar")),
"my sübject");
assert(msg2);
string text2 = "my mèssage to yoü";
@ -44,6 +44,23 @@ int main() {
free(result2);
free_message(msg2);
cout << "opening mime_sample.txt for reading\n";
ifstream inFile3 ("mime_sample.txt");
assert(inFile3.is_open());
string mimetext3;
cout << "reading mime sample\n";
while (!inFile3.eof()) {
static string line;
getline(inFile3, line);
mimetext3 += line + "\n";
}
inFile3.close();
message *msg3;
PEP_STATUS status3 = mime_decode_message(mimetext3.c_str(), &msg3);
cout << "calling release()\n";
release(session);
return 0;


Loading…
Cancel
Save