Пример #1
0
int mailmime_smart_remove_part(struct mailmime * mime)
{
  struct mailmime * parent;
  int res;

  parent = mime->mm_parent;
  if (parent == NULL) {
    res = MAILIMF_ERROR_INVAL;
    goto err;
  }

  switch (mime->mm_type) {
  case MAILMIME_MESSAGE:
    if (mime->mm_data.mm_message.mm_msg_mime != NULL) {
      res = MAILIMF_ERROR_INVAL;
      goto err;
    }

    mailmime_remove_part(mime);
    
    mailmime_free(mime);

    return MAILIMF_NO_ERROR;

  case MAILMIME_MULTIPLE:
    if (!clist_isempty(mime->mm_data.mm_multipart.mm_mp_list)) {
      res = MAILIMF_ERROR_INVAL;
      goto err;
    }
      
    mailmime_remove_part(mime);
    
    mailmime_free(mime);
    
    return MAILIMF_NO_ERROR;

  case MAILMIME_SINGLE:
    mailmime_remove_part(mime);

    mailmime_free(mime);

    return MAILIMF_NO_ERROR;
    
  default:
    return MAILIMF_ERROR_INVAL;
  }

 err:
  return res;
}
Пример #2
0
mailmessage * mime_message_init(struct mailmime * mime)
{
  mailmessage * msg;
  int r;
  
  msg = mailmessage_new();
  if (msg == NULL)
    goto err;

  r = mailmessage_init(msg, NULL, mime_message_driver, 0, 0);
  if (r != MAIL_NO_ERROR)
    goto free;
  
  if (mime != NULL) {
    mailmime_free(msg->msg_mime);
    msg->msg_mime = mime;
  }
  
  return msg;
  
 free:
  mailmessage_free(msg);
 err:
  return NULL;
}
Пример #3
0
int mailmessage_encrypt(struct mailprivacy * privacy,
    struct mailmessage * msg,
    char * protocol, char * encryption_method)
{
  int r;
  int res;
  struct mailmime * mime;
  struct mailmime * encrypted_mime;
  struct mailmime * part_to_encrypt;
  
  r = mailprivacy_msg_get_bodystructure(privacy, msg, &mime);
  if (r != MAIL_NO_ERROR) {
    res = r;
    goto err;
  }
  
  part_to_encrypt = mime->mm_data.mm_message.mm_msg_mime;
  
  r = mailprivacy_encrypt_msg(privacy, protocol, encryption_method,
      msg, part_to_encrypt, &encrypted_mime);
  if (r != MAIL_NO_ERROR) {
    res = r;
    goto err;
  }
  
  mime->mm_data.mm_message.mm_msg_mime = encrypted_mime;
  encrypted_mime->mm_parent = mime;
  part_to_encrypt->mm_parent = NULL;
  mailmime_free(part_to_encrypt);
  
  return MAIL_NO_ERROR;
  
 err:
  return res;
}
Пример #4
0
static int smime_sign_encrypt(struct mailprivacy * privacy,
    mailmessage * msg,
    struct mailmime * mime, struct mailmime ** result)
{
  struct mailmime * signed_part;
  struct mailmime * encrypted;
  int r;
  int res;
  
  r = smime_sign(privacy, msg, mime, &signed_part);
  if (r != MAIL_NO_ERROR) {
    res = r;
    goto err;
  }
  
  r = smime_encrypt(privacy, msg, signed_part, &encrypted);
  if (r != MAIL_NO_ERROR) {
    res = r;
    goto free_signed;
  }
  
  * result = encrypted;
  
  return MAIL_NO_ERROR;
  
 free_signed:
  mailprivacy_mime_clear(signed_part);
  mailmime_free(signed_part);
 err:
  return res;
}
Пример #5
0
static void imap_flush(mailmessage * msg_info)
{
  if (msg_info->msg_mime != NULL) {
    mailmime_free(msg_info->msg_mime);
    msg_info->msg_mime = NULL;
  }
}
Пример #6
0
int main(int argc, char ** argv)
{
	struct mailmime * msg_mime;
  struct mailmime * mime;
	struct mailmime * submime;
  struct mailimf_fields * fields;
	int col;
	
	msg_mime = mailmime_new_message_data(NULL);
	fields = build_fields();
	mailmime_set_imf_fields(msg_mime, fields);
	
	mime = get_multipart_mixed(NULL);
  
  submime = get_plain_text_part();
	mailmime_smart_add_part(mime, submime);
  submime = get_sample_file_part();
	mailmime_smart_add_part(mime, submime);
  
  mailmime_add_part(msg_mime, mime);

	col = 0;
	mailmime_write_file(stdout, &col, mime);

	mailmime_free(msg_mime);

	exit(0);
}
Пример #7
0
static void uninitialize(mailmessage * msg)
{
  /* tmp dir name */
  if (msg->msg_data != NULL)
    free(msg->msg_data);
  
  if (msg->msg_mime != NULL)
    mailmime_free(msg->msg_mime);
  msg->msg_mime = NULL;
}
Пример #8
0
static struct mailmime * build_body_text(char * text)
{
  struct mailmime_fields * mime_fields;
  struct mailmime * mime_sub;
  struct mailmime_content * content;
  struct mailmime_parameter * param;
  int r;

  /* text/plain part */

  mime_fields = mailmime_fields_new_encoding(MAILMIME_MECHANISM_8BIT);
  if (mime_fields == NULL) {
    goto err;
  }

  content = mailmime_content_new_with_str("text/plain");
  if (content == NULL) {
    goto free_fields;
  }

  param = mailmime_param_new_with_data("charset", DEST_CHARSET);
  if (param == NULL) {
    goto free_content;
  }

  r = clist_append(content->ct_parameters, param);
  if (r < 0) {
    mailmime_parameter_free(param);
    goto free_content;
  }

  mime_sub = mailmime_new_empty(content, mime_fields);
  if (mime_sub == NULL) {
    goto free_content;
  }

  r = mailmime_set_body_text(mime_sub, text, strlen(text));
  if (r != MAILIMF_NO_ERROR) {
    goto free_mime;
  }

  return mime_sub;

 free_mime:
  mailmime_free(mime_sub);
  goto err;
 free_content:
  mailmime_content_free(content);
 free_fields:
  mailmime_fields_free(mime_fields);
 err:
  return NULL;
}
Пример #9
0
void mailmessage_generic_flush(mailmessage * msg_info)
{
  struct generic_message_t * msg;

  if (msg_info->msg_mime != NULL) {
    mailmime_free(msg_info->msg_mime);
    msg_info->msg_mime = NULL;
  }
  msg = msg_info->msg_data;
  if (msg != NULL) {
    if (msg->msg_prefetch_free != NULL)
      msg->msg_prefetch_free(msg);
    msg->msg_fetched = 0;
  }
}
Пример #10
0
int mailprivacy_get_part_from_file(struct mailprivacy * privacy,
    int check_security, int reencode, char * filename,
    struct mailmime ** result_mime)
{
  int fd;
  struct mailmime * mime;
  int r;
  struct stat stat_info;
  int res;
  char * mapping;

  fd = open(filename, O_RDONLY);
  if (fd < 0) {
    res = MAIL_ERROR_FILE;
    goto err;
  }

  r = fstat(fd, &stat_info);
  if (r < 0) {
    res = MAIL_ERROR_FILE;
    goto close;
  }

  mapping = mmap(NULL, stat_info.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
  if (mapping == (char *)MAP_FAILED) {
    res = MAIL_ERROR_FILE;
    goto close;
  }
  
  mime = NULL;
  /* check recursive parts if privacy is set */
  r = mailprivacy_get_mime(privacy, check_security, reencode,
      mapping, stat_info.st_size, &mime);
  if (r != MAIL_NO_ERROR) {
    res =  r;
    goto unmap;
  }

  if (mime->mm_type == MAILMIME_MESSAGE) {
    struct mailmime * submime;
    
    submime = mime->mm_data.mm_message.mm_msg_mime;
    if (mime->mm_data.mm_message.mm_msg_mime != NULL) {
      mailmime_remove_part(submime);
      mailmime_free(mime);
      
      mime = submime;
    }
  }

  munmap(mapping, stat_info.st_size);
  
  close(fd);

  * result_mime = mime;

  return MAIL_NO_ERROR;
  
 unmap:
  munmap(mapping, stat_info.st_size);
 close:
  close(fd);
 err:
  return res;
}
Пример #11
0
struct mailmime *
mailprivacy_new_file_part(struct mailprivacy * privacy,
    char * filename,
    char * default_content_type, int default_encoding)
{
  char basename_buf[PATH_MAX];
  char * name;
  struct mailmime_mechanism * encoding;
  struct mailmime_content * content;
  struct mailmime * mime;
  int r;
  char * dup_filename;
  struct mailmime_fields * mime_fields;
  int encoding_type;
  char * content_type_str;
  int do_encoding;
  
  if (filename != NULL) {
    strncpy(basename_buf, filename, PATH_MAX);
    name = libetpan_basename(basename_buf);
  }
  else {
    name = NULL;
  }
  
  encoding = NULL;
  
  /* default content-type */
  if (default_content_type == NULL)
    content_type_str = "application/octet-stream";
  else
    content_type_str = default_content_type;
    
  content = mailmime_content_new_with_str(content_type_str);
  if (content == NULL) {
    goto free_content;
  }
  
  do_encoding = 1;
  if (content->ct_type->tp_type == MAILMIME_TYPE_COMPOSITE_TYPE) {
    struct mailmime_composite_type * composite;
    
    composite = content->ct_type->tp_data.tp_composite_type;
    
    switch (composite->ct_type) {
    case MAILMIME_COMPOSITE_TYPE_MESSAGE:
      if (strcasecmp(content->ct_subtype, "rfc822") == 0)
        do_encoding = 0;
      break;

    case MAILMIME_COMPOSITE_TYPE_MULTIPART:
      do_encoding = 0;
      break;
    }
  }
  
  if (do_encoding) {
    if (default_encoding == -1)
      encoding_type = MAILMIME_MECHANISM_BASE64;
    else
      encoding_type = default_encoding;
    
    /* default Content-Transfer-Encoding */
    encoding = mailmime_mechanism_new(encoding_type, NULL);
    if (encoding == NULL) {
      goto free_content;
    }
  }
  
  mime_fields = mailmime_fields_new_with_data(encoding,
      NULL, NULL, NULL, NULL);
  if (mime_fields == NULL) {
    goto free_content;
  }
  
  mime = mailmime_new_empty(content, mime_fields);
  if (mime == NULL) {
    goto free_mime_fields;
  }
  
  if ((filename != NULL) && (mime->mm_type == MAILMIME_SINGLE)) {
    /*
      duplicates the file so that the file can be deleted when
      the MIME part is done
    */
    dup_filename = dup_file(privacy, filename);
    if (dup_filename == NULL) {
      goto free_mime;
    }
  
    r = mailmime_set_body_file(mime, dup_filename);
    if (r != MAILIMF_NO_ERROR) {
      free(dup_filename);
      goto free_mime;
    }
  }
  
  return mime;
  
 free_mime:
  mailmime_free(mime);
  goto err;
 free_mime_fields:
  mailmime_fields_free(mime_fields);
  mailmime_content_free(content);
  goto err;
 free_content:
  if (encoding != NULL)
    mailmime_mechanism_free(encoding);
  if (content != NULL)
    mailmime_content_free(content);
 err:
  return NULL;
}
Пример #12
0
static int
smime_verify(struct mailprivacy * privacy,
    mailmessage * msg,
    struct mailmime * mime, struct mailmime ** result)
{
  char smime_filename[PATH_MAX];
  char quoted_smime_filename[PATH_MAX];
  int res;
  int r;
  char command[PATH_MAX];
  int sign_ok;
  struct mailmime * description_mime;
  char description_filename[PATH_MAX];
  struct mailmime * multipart;
  char stripped_filename[PATH_MAX];
  struct mailmime * stripped_mime;
  char check_CA[PATH_MAX];
  char quoted_CAfile[PATH_MAX];
  char noverify[PATH_MAX];
  
  if (store_cert)
    get_cert_from_sig(privacy, msg, mime);
  
  * check_CA = '\0';
  if (CAfile != NULL) {
    r = mail_quote_filename(quoted_CAfile, sizeof(quoted_CAfile), CAfile);
    if (r < 0) {
      res = MAIL_ERROR_MEMORY;
      goto err;
    }
    
    snprintf(check_CA, sizeof(check_CA), "-CAfile '%s'", quoted_CAfile);
  }
  
  * noverify = '\0';
  if (!CA_check) {
    snprintf(noverify, sizeof(noverify), "-noverify");
  }
  
  /* fetch the whole multipart and write it to a file */
  
  r = mailprivacy_fetch_mime_body_to_file(privacy,
      smime_filename, sizeof(smime_filename),
      msg, mime);
  if (r != MAIL_NO_ERROR) {
    res = r;
    goto err;
  }
  
  r = mailprivacy_get_tmp_filename(privacy,stripped_filename,
      sizeof(stripped_filename));
  if (r != MAIL_NO_ERROR) {
    res = r;
    goto unlink_smime;
  }
  
  /* description */
  
  r = mailprivacy_get_tmp_filename(privacy, description_filename,
      sizeof(description_filename));
  if (r != MAIL_NO_ERROR) {
    res = r;
    goto unlink_stripped;
  }
  
  /* run the command */

  r = mail_quote_filename(quoted_smime_filename,
      sizeof(quoted_smime_filename), smime_filename);
  if (r < 0) {
    res = MAIL_ERROR_MEMORY;
    goto unlink_description;
  }

  sign_ok = 0;
  snprintf(command, sizeof(command), "openssl smime -verify -in '%s' %s %s",
      quoted_smime_filename, check_CA, noverify);
  
  r = smime_command_passphrase(privacy, msg, command,
      NULL, stripped_filename, description_filename);
  switch (r) {
  case NO_ERROR_SMIME:
    sign_ok = 1;
    break;
  case ERROR_SMIME_NOPASSPHRASE:
  case ERROR_SMIME_CHECK:
    sign_ok = 0;
    break;
  case ERROR_SMIME_COMMAND:
    res = MAIL_ERROR_COMMAND;
    goto unlink_description;
  case ERROR_SMIME_FILE:
    res = MAIL_ERROR_FILE;
    goto unlink_description;
  }
  
  /* building multipart */
  
  r = mailmime_new_with_content("multipart/x-verified", NULL, &multipart);
  if (r != MAILIMF_NO_ERROR) {
    res = MAIL_ERROR_MEMORY;
    goto unlink_description;
  }
  
  /* building the description part */
  
  description_mime = mailprivacy_new_file_part(privacy,
      description_filename,
      "text/plain", MAILMIME_MECHANISM_8BIT);
  if (description_mime == NULL) {
    mailprivacy_mime_clear(multipart);
    mailmime_free(multipart);
    res = MAIL_ERROR_MEMORY;
    goto unlink_description;
  }
  
  /* adds the description part */
  
  r = mailmime_smart_add_part(multipart, description_mime);
  if (r != MAIL_NO_ERROR) {
    mailprivacy_mime_clear(description_mime);
    mailmime_free(description_mime);
    mailprivacy_mime_clear(multipart);
    mailmime_free(multipart);
    res = MAIL_ERROR_MEMORY;
    goto unlink_description;
  }
  
  /* insert the signed part */
  if (!sign_ok) {
    if (mime->mm_type == MAILMIME_MULTIPLE) {
      clistiter * child_iter;
      struct mailmime * child;
      
      child_iter = clist_begin(mime->mm_data.mm_multipart.mm_mp_list);
      child = clist_content(child_iter);
      
      r = mailprivacy_fetch_mime_body_to_file(privacy,
          stripped_filename, sizeof(stripped_filename),
          msg, child);
    }
  }
  
  r = mailprivacy_get_part_from_file(privacy, 1, 0,
      stripped_filename, &stripped_mime);
  if (r != MAIL_NO_ERROR) {
    mailprivacy_mime_clear(multipart);
    mailmime_free(multipart);
    res = r;
    goto unlink_description;
  }
  
  r = mailmime_smart_add_part(multipart, stripped_mime);
  if (r != MAIL_NO_ERROR) {
    mailprivacy_mime_clear(stripped_mime);
    mailmime_free(stripped_mime);
    mailprivacy_mime_clear(multipart);
    mailmime_free(multipart);
    res = MAIL_ERROR_MEMORY;
    goto unlink_description;
  }
  
  unlink(description_filename);
  unlink(stripped_filename);
  /* unlink(smime_filename); */
  
  * result = multipart;
  
  return MAIL_NO_ERROR;
  
 unlink_description:
  unlink(description_filename);
 unlink_stripped:
  unlink(stripped_filename);
 unlink_smime:
  unlink(smime_filename);
 err:
  return res;
}
Пример #13
0
static int smime_decrypt(struct mailprivacy * privacy,
    mailmessage * msg,
    struct mailmime * mime, struct mailmime ** result)
{
  char smime_filename[PATH_MAX];
  char quoted_smime_filename[PATH_MAX];
  char description_filename[PATH_MAX];
  char decrypted_filename[PATH_MAX];
  char command[PATH_MAX];
  struct mailmime * description_mime;
  struct mailmime * decrypted_mime;
  int r;
  int res;
  int sign_ok;
  struct mailmime * multipart;
  char * smime_cert;
  char * smime_key;
  char quoted_smime_cert[PATH_MAX];
  char quoted_smime_key[PATH_MAX];
  char * email;
  chashiter * iter;
  
  /* fetch the whole multipart and write it to a file */
  
  r = mailprivacy_fetch_mime_body_to_file(privacy,
      smime_filename, sizeof(smime_filename),
      msg, mime);
  if (r != MAIL_NO_ERROR) {
    res = r;
    goto err;
  }
  
  /* we are in a safe directory */
  
  r = mailprivacy_get_tmp_filename(privacy, decrypted_filename,
      sizeof(decrypted_filename));
  if (r != MAIL_NO_ERROR) {
    res = MAIL_ERROR_FILE;
    goto unlink_smime;
  }
  
  /* description */
  
  r = mailprivacy_get_tmp_filename(privacy, description_filename,
      sizeof(description_filename));
  if (r != MAIL_NO_ERROR) {
    res = MAIL_ERROR_FILE;
    goto unlink_decrypted;
  }
  
  sign_ok = 0;
  for(iter = chash_begin(private_keys) ; iter != NULL ;
      iter = chash_next(private_keys, iter)) {
    chashdatum key;
    char email_buf[BUF_SIZE];
    
    chash_key(iter, &key);
    
    if (key.len >= sizeof(email_buf))
      continue;
    
    strncpy(email_buf, key.data, key.len);
    email_buf[key.len] = '\0';
    email = email_buf;
    
    /* get encryption key */
    
    smime_key = get_private_key_file(email);
    smime_cert = get_cert_file(email);
    if ((smime_cert == NULL) || (smime_key == NULL)) {
      res = MAIL_ERROR_INVAL;
      goto unlink_description;
    }
  
    r = mail_quote_filename(quoted_smime_cert, sizeof(quoted_smime_cert),
        smime_cert);
    if (r < 0) {
      res = MAIL_ERROR_MEMORY;
      goto unlink_description;
    }
  
    r = mail_quote_filename(quoted_smime_key, sizeof(quoted_smime_key),
        smime_key);
    if (r < 0) {
      res = MAIL_ERROR_MEMORY;
      goto unlink_description;
    }
  
    /* run the command */
  
    r = mail_quote_filename(quoted_smime_filename,
        sizeof(quoted_smime_filename), smime_filename);
    if (r < 0) {
      res = MAIL_ERROR_MEMORY;
      goto unlink_description;
    }
    
    sign_ok = 0;
    snprintf(command, sizeof(command),
        "openssl smime -decrypt -passin fd:0 -in '%s' -inkey '%s' -recip '%s'",
        quoted_smime_filename, quoted_smime_key, quoted_smime_cert);
    
    unlink(description_filename);
    r = smime_command_passphrase(privacy, msg, command,
        email, decrypted_filename, description_filename);
    switch (r) {
    case NO_ERROR_SMIME:
      sign_ok = 1;
      break;
    case ERROR_SMIME_CHECK:
    case ERROR_SMIME_NOPASSPHRASE:
      sign_ok = 0;
      break;
    case ERROR_SMIME_COMMAND:
      res = MAIL_ERROR_COMMAND;
      goto unlink_description;
    case ERROR_SMIME_FILE:
      res = MAIL_ERROR_FILE;
      goto unlink_description;
    }
    
    if (sign_ok) {
      break;
    }
  }
  
  if (!sign_ok) {
    if (chash_count(private_keys) == 0) {
      FILE * description_f;
      
      description_f = mailprivacy_get_tmp_file(privacy, description_filename,
          sizeof(description_filename));
      if (description_f == NULL) {
        res = MAIL_ERROR_FILE;
        goto unlink_decrypted;
      }
      fprintf(description_f, SMIME_DECRYPT_FAILED);
      fclose(description_f);
    }
  }
  else {
    mailprivacy_smime_encryption_id_list_clear(privacy, msg);
  }
  
  /* building multipart */

  r = mailmime_new_with_content("multipart/x-decrypted", NULL, &multipart);
  if (r != MAILIMF_NO_ERROR) {
    res = MAIL_ERROR_MEMORY;
    goto unlink_description;
  }
  
  /* building the description part */
  
  description_mime = mailprivacy_new_file_part(privacy,
      description_filename,
      "text/plain", MAILMIME_MECHANISM_8BIT);
  if (description_mime == NULL) {
    mailprivacy_mime_clear(multipart);
    mailmime_free(multipart);
    res = MAIL_ERROR_MEMORY;
    goto unlink_description;
  }
  
  /* adds the description part */
  
  r = mailmime_smart_add_part(multipart, description_mime);
  if (r != MAIL_NO_ERROR) {
    mailprivacy_mime_clear(description_mime);
    mailmime_free(description_mime);
    mailprivacy_mime_clear(multipart);
    mailmime_free(multipart);
    res = MAIL_ERROR_MEMORY;
    goto unlink_description;
  }
  
  /* building the decrypted part */
  
  r = mailprivacy_get_part_from_file(privacy, 1, 0,
      decrypted_filename, &decrypted_mime);
  if (r == MAIL_NO_ERROR) {
    /* adds the decrypted part */
    
    r = mailmime_smart_add_part(multipart, decrypted_mime);
    if (r != MAIL_NO_ERROR) {
      mailprivacy_mime_clear(decrypted_mime);
      mailmime_free(decrypted_mime);
      mailprivacy_mime_clear(multipart);
      mailmime_free(multipart);
      res = MAIL_ERROR_MEMORY;
      goto unlink_description;
    }
  }
  
  unlink(description_filename);
  unlink(decrypted_filename);
  unlink(smime_filename);
  
  * result = multipart;
  
  return MAIL_NO_ERROR;
  
 unlink_description:
  unlink(description_filename);
 unlink_decrypted:
  unlink(decrypted_filename);
 unlink_smime:
  unlink(smime_filename);
 err:
  return res;
}
Пример #14
0
static int recursive_check_privacy(struct mailprivacy * privacy,
    mailmessage * msg,
    struct mailmime * mime)
{
  int r;
  clistiter * cur;
  struct mailmime * alternative;
  int res;
  struct mailmime * multipart;
  
  if (privacy == NULL)
    return MAIL_NO_ERROR;
  
  if (mime_is_registered(privacy, mime))
    return MAIL_ERROR_INVAL;
  
  r = privacy_handler(privacy, msg, mime, &alternative);
  if (r == MAIL_NO_ERROR) {
    if (privacy->make_alternative) {
      multipart = mime_add_alternative(privacy, msg, mime, alternative);
      if (multipart == NULL) {
        mailprivacy_mime_clear(alternative);
        mailmime_free(alternative);
        return MAIL_ERROR_MEMORY;
      }
    }
    else {
      mailmime_substitute(mime, alternative);
      mailmime_free(mime);
      mime = NULL;
    }
    
    return MAIL_NO_ERROR;
  }
  else {
    switch (mime->mm_type) {
    case MAILMIME_SINGLE:
      return MAIL_ERROR_INVAL;
    
    case MAILMIME_MULTIPLE:
      res = MAIL_ERROR_INVAL;
    
      for(cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ;
          cur != NULL ; cur = clist_next(cur)) {
        struct mailmime * child;
      
        child = clist_content(cur);
      
        r = recursive_check_privacy(privacy, msg, child);
        if (r == MAIL_NO_ERROR)
          res = MAIL_NO_ERROR;
      }
    
      return res;
    
    case MAILMIME_MESSAGE:
      if (mime->mm_data.mm_message.mm_msg_mime != NULL)
        return recursive_check_privacy(privacy, msg,
            mime->mm_data.mm_message.mm_msg_mime);
      return MAIL_ERROR_INVAL;

    default:
      return MAIL_ERROR_INVAL;
    }
  }
}
Пример #15
0
static struct mailmime *
mime_add_alternative(struct mailprivacy * privacy,
    mailmessage * msg,
    struct mailmime * mime,
    struct mailmime * alternative)
{
  struct mailmime * multipart;
  int r;
  struct mailmime * mime_copy;
  char original_filename[PATH_MAX];
  
  if (mime->mm_parent == NULL)
    goto err;
  
  r = mailmime_new_with_content("multipart/alternative", NULL, &multipart);
  if (r != MAILIMF_NO_ERROR)
    goto err;
  
  r = mailmime_smart_add_part(multipart, alternative);
  if (r != MAILIMF_NO_ERROR) {
    goto free_multipart;
  }

  /* get copy of mime part "mime" and set parts */
  
  r = mailprivacy_fetch_mime_body_to_file(privacy,
      original_filename, sizeof(original_filename),
      msg, mime);
  if (r != MAIL_NO_ERROR)
    goto detach_alternative;
  
  r = mailprivacy_get_part_from_file(privacy, 0, 0,
      original_filename, &mime_copy);
  unlink(original_filename);
  if (r != MAIL_NO_ERROR) {
    goto detach_alternative;
  }
  
  r = mailmime_smart_add_part(multipart, mime_copy);
  if (r != MAILIMF_NO_ERROR) {
    goto free_mime_copy;
  }
  
  r = recursive_register_mime(privacy, multipart);
  if (r != MAIL_NO_ERROR)
    goto detach_mime_copy;
  
  mailmime_substitute(mime, multipart);
  
  mailmime_free(mime);
  
  return multipart;
  
 detach_mime_copy:
  mailprivacy_recursive_unregister_mime(privacy, multipart);
  mailmime_remove_part(alternative);
 free_mime_copy:
  mailprivacy_mime_clear(mime_copy);
  mailmime_free(mime_copy);
 detach_alternative:
  mailmime_remove_part(alternative);
 free_multipart:
  mailmime_free(multipart);
 err:
  return NULL;
}
Пример #16
0
int main(int argc, char ** argv)
{
  struct mailimf_fields * fields;
  char * text;
  char * filename;
  struct mailmime * message;
  struct mailmime * text_part;
  struct mailmime * file_part;
  int r;
  int col;

  if (argc < 3) {
    printf("syntax: compose-msg \"text\" filename\n");
    return 1;
  }

  fields = build_fields();
  if (fields == NULL)
    goto err;

  message = build_message(fields);
  if (message == NULL)
    goto free_fields;

  text = argv[1];
  text_part = build_body_text(text);
  if (text_part == NULL)
    goto free_message;

  filename = argv[2];
  file_part = build_body_file(filename);
  if (file_part == NULL)
    goto free_text;

  r = mailmime_smart_add_part(message, text_part);
  if (r != MAILIMF_NO_ERROR)
    goto free_file;

  r = mailmime_smart_add_part(message, file_part);
  if (r != MAILIMF_NO_ERROR)
    goto free_file_alone;
  
  col = 0;
  mailmime_write(stdout, &col, message);

  mailmime_free(message);

  return 0;

 free_file_alone:
  mailmime_free(file_part);
  goto free_text;
 free_file:
  mailmime_free(file_part);
 free_text:
  mailmime_free(text_part);
 free_message:
  mailmime_free(message);
  goto err;
 free_fields:
  mailimf_fields_free(fields);
 err:
  printf("error memory\n");
  return 1;
}
Пример #17
0
static struct mailmime * build_body_file(char * filename)
{
  struct mailmime_fields * mime_fields;
  struct mailmime * mime_sub;
  struct mailmime_content * content;
  struct mailmime_parameter * param;
  char * dup_filename;
  int r;

  /* text/plain part */

  dup_filename = strdup(filename);
  if (dup_filename == NULL)
    goto err;

  mime_fields =
    mailmime_fields_new_filename(MAILMIME_DISPOSITION_TYPE_ATTACHMENT,
        dup_filename, MAILMIME_MECHANISM_BASE64);
  if (mime_fields == NULL)
    goto free_dup_filename;

  content = mailmime_content_new_with_str("text/plain");
  if (content == NULL) {
    goto free_fields;
  }

  param = mailmime_param_new_with_data("charset", DEST_CHARSET);
  if (param == NULL) {
    goto free_content;
  }

  r = clist_append(content->ct_parameters, param);
  if (r < 0) {
    mailmime_parameter_free(param);
    goto free_content;
  }

  mime_sub = mailmime_new_empty(content, mime_fields);
  if (mime_sub == NULL) {
    goto free_content;
  }

  dup_filename = strdup(filename);
  if (dup_filename == NULL)
    goto free_mime;

  r = mailmime_set_body_file(mime_sub, dup_filename);
  if (r != MAILIMF_NO_ERROR) {
    goto free_mime;
  }

  return mime_sub;

 free_mime:
  mailmime_free(mime_sub);
  goto err;
 free_content:
  mailmime_content_free(content);
 free_fields:
  mailmime_fields_free(mime_fields);
  goto err;
 free_dup_filename:
  free(dup_filename);
 err:
  return NULL;
}
Пример #18
0
static int imap_get_bodystructure(mailmessage * msg_info,
				  struct mailmime ** result)
{
  int r;
  struct mailimap_set * set;
  struct mailimap_fetch_att * fetch_att;
  struct mailimap_fetch_type * fetch_type;
  clist * fetch_result;
  struct mailimap_msg_att * msg_att;
  struct mailimap_body * imap_body;
  struct mailmime * body;
  int res;
  struct mailimf_fields * fields;
  struct mailmime * new_body;
  struct mailmime_content * content_message;
  struct mailimap_envelope * envelope;
  uint32_t uid;
  char * references;
  size_t ref_size;
  clistiter * cur;

  if (msg_info->msg_mime != NULL) {
    * result = msg_info->msg_mime;

    return MAIL_NO_ERROR;
  }

  set = mailimap_set_new_single(msg_info->msg_index);
  if (set == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto err;
  }

  fetch_type = mailimap_fetch_type_new_fetch_att_list_empty();
  if (fetch_type == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto free_set;
  }

  fetch_att = mailimap_fetch_att_new_uid();
  if (fetch_att == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto free_fetch_type;
  }

  r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
  if (r != MAILIMAP_NO_ERROR) {
    mailimap_fetch_att_free(fetch_att);
    res = MAIL_ERROR_MEMORY;
    goto free_fetch_type;
  }

  fetch_att = mailimap_fetch_att_new_bodystructure();
  if (fetch_att == NULL) {
    res = MAIL_ERROR_MEMORY;
    goto free_fetch_type;
  }

  r = mailimap_fetch_type_new_fetch_att_list_add(fetch_type, fetch_att);
  if (r != MAILIMAP_NO_ERROR) {
    mailimap_fetch_att_free(fetch_att);
    res = MAIL_ERROR_MEMORY;
    goto free_fetch_type;
  }

  r = imap_add_envelope_fetch_att(fetch_type);
  if (r != MAIL_NO_ERROR) {
    res = r;
    goto free_fetch_type;
  }
  

  r = mailimap_uid_fetch(get_imap_session(msg_info), set,
			 fetch_type, &fetch_result);

  mailimap_fetch_type_free(fetch_type);
  mailimap_set_free(set);

  switch (r) {
  case MAILIMAP_NO_ERROR:
    break;
  default:
    return imap_error_to_mail_error(r);
  }

  cur = clist_begin(fetch_result);
  if (cur == NULL) {
    mailimap_fetch_list_free(fetch_result);
    return MAIL_ERROR_FETCH;
  }

  msg_att = clist_content(cur);

  uid = 0;
  references = NULL;
  ref_size = 0;
  imap_body = NULL;
  envelope = NULL;

  r = imap_get_msg_att_info(msg_att,
      &uid, &envelope, &references, &ref_size, NULL, &imap_body);
  if (r != MAIL_NO_ERROR) {
    mailimap_fetch_list_free(fetch_result);
    res = r;
    goto err;
  }

  if (uid != msg_info->msg_index) {
    mailimap_fetch_list_free(fetch_result);
    res = MAIL_ERROR_MSG_NOT_FOUND;
    goto err;
  }

  if (imap_body == NULL) {
    mailimap_fetch_list_free(fetch_result);
    res = MAIL_ERROR_FETCH;
    goto err;
  }

  r = imap_body_to_body(imap_body, &body);
  if (r != MAIL_NO_ERROR) {
    mailimap_fetch_list_free(fetch_result);
    res = r;
    goto err;
  }

  fields = NULL;
  if (envelope != NULL) {
    r = imap_env_to_fields(envelope, references, ref_size, &fields);
    if (r != MAIL_NO_ERROR) {
      mailmime_free(body);
      mailimap_fetch_list_free(fetch_result);
      res = r;
      goto err;
    }
  }

  content_message = mailmime_get_content_message();
  if (content_message == NULL) {
    if (fields != NULL)
      mailimf_fields_free(fields);
    mailmime_free(body);
    mailimap_fetch_list_free(fetch_result);
    res = MAIL_ERROR_MEMORY;
    goto err;
  }

  new_body = mailmime_new(MAILMIME_MESSAGE, NULL,
      0, NULL, content_message,
      NULL, NULL, NULL, NULL, fields, body);

  if (new_body == NULL) {
    mailmime_content_free(content_message);
    if (fields != NULL)
      mailimf_fields_free(fields);
    mailmime_free(body);
    mailimap_fetch_list_free(fetch_result);
    res = MAIL_ERROR_MEMORY;
    goto err;
  }
  msg_info->msg_mime = new_body;
  
  mailimap_fetch_list_free(fetch_result);

  * result = new_body;

  return MAIL_NO_ERROR;

 free_fetch_type:
  mailimap_fetch_type_free(fetch_type);
 free_set:
  mailimap_set_free(set);
 err:
  return res;
}
Пример #19
0
int mailmime_smart_add_part(struct mailmime * mime,
    struct mailmime * mime_sub)
{
  struct mailmime * saved_sub;
  struct mailmime * mp;
  int res;
  int r;

  switch (mime->mm_type) {
  case MAILMIME_SINGLE:
    res = MAILIMF_ERROR_INVAL;
    goto err;

  case MAILMIME_MULTIPLE:
    r = mailmime_add_part(mime, mime_sub);
    if (r != MAILIMF_NO_ERROR) {
      res = MAILIMF_ERROR_MEMORY;
      goto err;
    }

    return MAILIMF_NO_ERROR;
  }

  /* MAILMIME_MESSAGE */

  if (mime->mm_data.mm_message.mm_msg_mime == NULL) {
    /* there is no subpart, we can simply attach it */
    
    r = mailmime_add_part(mime, mime_sub);
    if (r != MAILIMF_NO_ERROR) {
      res = MAILIMF_ERROR_MEMORY;
      goto err;
    }

    return MAILIMF_NO_ERROR;
  }

  if (mime->mm_data.mm_message.mm_msg_mime->mm_type == MAILMIME_MULTIPLE) {
    /* in case the subpart is multipart, simply attach it to the subpart */
    
    return mailmime_add_part(mime->mm_data.mm_message.mm_msg_mime, mime_sub);
  }

  /* we save the current subpart, ... */

  saved_sub = mime->mm_data.mm_message.mm_msg_mime;

  /* create a multipart */
  
  mp = mailmime_multiple_new("multipart/mixed");
  if (mp == NULL) {
    res = MAILIMF_ERROR_MEMORY;
    goto err;
  }

  /* detach the saved subpart from the parent */

  mailmime_remove_part(saved_sub);
  
  /* the created multipart is the new child of the parent */

  r = mailmime_add_part(mime, mp);
  if (r != MAILIMF_NO_ERROR) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_mp;
  }

  /* then, attach the saved subpart and ... */
  
  r = mailmime_add_part(mp, saved_sub);
  if (r != MAILIMF_NO_ERROR) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_saved_sub;
  }

  /* the given part to the parent */

  r = mailmime_add_part(mp, mime_sub);
  if (r != MAILIMF_NO_ERROR) {
    res = MAILIMF_ERROR_MEMORY;
    goto free_saved_sub;
  }

  return MAILIMF_NO_ERROR;

 free_mp:
  mailmime_free(mp);
 free_saved_sub:
  mailmime_free(saved_sub);
 err:
  return res;
}