Пример #1
0
static carray * mailstream_low_cfstream_get_certificate_chain(mailstream_low * s)
{
#if HAVE_CFNETWORK
  struct mailstream_cfstream_data * cfstream_data;
  unsigned int i;
  carray * result;
  
  cfstream_data = (struct mailstream_cfstream_data *) s->data;
  SecTrustRef secTrust = (SecTrustRef)CFReadStreamCopyProperty(cfstream_data->readStream, kCFStreamPropertySSLPeerTrust);
  if (secTrust == NULL)
    return NULL;
  
  CFIndex count = SecTrustGetCertificateCount(secTrust);
  
  result = carray_new(4);
  for(i = 0 ; i < count ; i ++) {
    SecCertificateRef cert = (SecCertificateRef) SecTrustGetCertificateAtIndex(secTrust, i);
    CFDataRef data = SecCertificateCopyData(cert);
    CFIndex length = CFDataGetLength(data);
    const UInt8 * bytes = CFDataGetBytePtr(data);
    MMAPString * str = mmap_string_sized_new(length);
    mmap_string_append_len(str, (char*) bytes, length);
    carray_add(result, str, NULL);
    CFRelease(data);
  }
  
  CFRelease(secTrust);
  
  return result;
#else
  return NULL;
#endif
}
Пример #2
0
MMAPString*
mmap_string_new (const char *init)
{
  MMAPString *string;

  string = mmap_string_sized_new (init ? strlen (init) + 2 : 2);
  if (string == NULL)
    return NULL;

  if (init)
    mmap_string_append (string, init);

  return string;
}
Пример #3
0
int collect(struct mem_message *message, int msg_stream) {
#ifndef MMAP_UNAVAILABLE
  struct stat sb;
#endif
  int len;

  memset(message, 0, sizeof(struct mem_message));

#ifndef MMAP_UNAVAILABLE
  /* if stream is a file whose size is known, try to mmap it */
  if (!fstat(0, &sb) && S_ISREG(sb.st_mode) && sb.st_size >= 0) {
    message->len = sb.st_size;
    if ((message->data = mmap(NULL, message->len, PROT_READ, MAP_SHARED,
			      msg_stream, 0)) != MAP_FAILED)
      return 0;
  }
#endif

  /* read the buffer from stdin by blocks, until EOF or error.
     save the message in a mmap_string */
  if ((message->mstring = mmap_string_sized_new(BLOCKSIZE)) == NULL) {
    perror("mmap_string_new");
    goto error;
  }
  message->len = 0;

  while ((len = _read(msg_stream,
		     message->mstring->str + message->len, BLOCKSIZE)) > 0) {
    message->len += len;
    /* reserve room for next block */
    if ((mmap_string_set_size(message->mstring,
			      message->len + BLOCKSIZE)) == NULL) {
      perror("mmap_string_set_size");
      goto error;
    }
  }

  if (len == 0) {
    message->data = message->mstring->str;
    return 0; /* OK */
  }

  perror("read");

 error:
  if (message->mstring != NULL)
    mmap_string_free(message->mstring);
  return -1;
}
Пример #4
0
MMAPString*
mmap_string_new_len (const char *init,
		     size_t len)    
{
  MMAPString *string;

  if (len <= 0)
    return mmap_string_new (init);
  else
    {
      string = mmap_string_sized_new (len);
      
      if (init)
        mmap_string_append_len (string, init, len);
      
      return string;
    }
}
Пример #5
0
oxws_result oxws_write_response_to_buffer(oxws* oxws, size_t buffer_size_hint) {
    if(oxws == NULL) return OXWS_ERROR_INVALID_PARAMETER;

    oxws_internal* internal = OXWS_INTERNAL(oxws);
    if(internal == NULL) return OXWS_ERROR_INTERNAL;

    curl_easy_setopt(internal->curl, CURLOPT_WRITEFUNCTION, oxws_write_response_to_buffer_callback);
    curl_easy_setopt(internal->curl, CURLOPT_WRITEDATA, internal);

    /* (re)allocate and clear response buffer */
    if(internal->response_buffer) {
        mmap_string_set_size(internal->response_buffer, buffer_size_hint);
        mmap_string_truncate(internal->response_buffer, 0);
    } else {
        internal->response_buffer = mmap_string_sized_new(buffer_size_hint);
    }

    return OXWS_NO_ERROR;
}
Пример #6
0
carray * mailstream_low_ssl_get_certificate_chain(mailstream_low * s)
{
#ifdef USE_SSL
#ifndef USE_GNUTLS
  STACK_OF(X509) * skx;
  struct mailstream_ssl_data * ssl_data;
  carray * result;
  int skpos;
  
  ssl_data = (struct mailstream_ssl_data *) s->data;
  if (!(skx = SSL_get_peer_cert_chain(ssl_data->ssl_conn))) {
    return NULL;
  }
  
  result = carray_new(4);
  for(skpos = 0 ; skpos < sk_num(skx) ; skpos ++) {
    X509 * x = (X509 *) sk_value(skx, skpos);
    unsigned char * p;
    MMAPString * str;
    int length = i2d_X509(x, NULL);
    str = mmap_string_sized_new(length);
    p = (unsigned char *) str->str;
    str->len = length;
    i2d_X509(x, &p);
    carray_add(result, str, NULL);
  }
  
  return result;
#else
  /* TODO: GnuTLS implementation */
  return NULL;
#endif
#else
  return NULL;
#endif
}
Пример #7
0
/* feed_update()
 * Takes initialized feed with url set, fetches the feed from this url,
 * updates rest of Feed struct members and returns HTTP response code
 * we got from url's server. */
int newsfeed_update(struct newsfeed * feed, time_t last_update)
{
#if (defined(HAVE_LIBCURL) && defined(HAVE_EXPAT))
  CURL * eh;
  CURLcode curl_res;
  struct newsfeed_parser_context * feed_ctx;
  unsigned int res;
  unsigned int timeout_value;
  long response_code;

  if (feed->feed_url == NULL) {
    res = NEWSFEED_ERROR_BADURL;
    goto err;
  }

  /* Init curl before anything else. */
  eh = curl_easy_init();
  if (eh == NULL) {
    res = NEWSFEED_ERROR_MEMORY;
    goto err;
  }

  /* Curl initialized, create parser context now. */
  feed_ctx = malloc(sizeof(* feed_ctx));
  if (feed_ctx == NULL) {
    res = NEWSFEED_ERROR_MEMORY;
    goto free_eh;
  }

  feed_ctx->parser = XML_ParserCreate(NULL);
  if (feed_ctx->parser == NULL) {
    res = NEWSFEED_ERROR_MEMORY;
    goto free_ctx;
  }
  feed_ctx->depth = 0;
  feed_ctx->str = mmap_string_sized_new(256);
  if (feed_ctx->str == NULL) {
    res = NEWSFEED_ERROR_MEMORY;
    goto free_praser;
  }
  feed_ctx->feed = feed;
  feed_ctx->location = 0;
  feed_ctx->curitem = NULL;
  feed_ctx->error = NEWSFEED_NO_ERROR;

  /* Set initial expat handlers, which will take care of choosing
   * correct parser later. */
  newsfeed_parser_set_expat_handlers(feed_ctx);

  if (feed->feed_timeout != 0)
    timeout_value = feed->feed_timeout;
  else
    timeout_value = mailstream_network_delay.tv_sec;

  curl_easy_setopt(eh, CURLOPT_URL, feed->feed_url);
  curl_easy_setopt(eh, CURLOPT_NOPROGRESS, 1);
#ifdef CURLOPT_MUTE
  curl_easy_setopt(eh, CURLOPT_MUTE, 1);
#endif
  curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, newsfeed_writefunc);
  curl_easy_setopt(eh, CURLOPT_WRITEDATA, feed_ctx);
  curl_easy_setopt(eh, CURLOPT_FOLLOWLOCATION, 1);
  curl_easy_setopt(eh, CURLOPT_MAXREDIRS, 3);
  curl_easy_setopt(eh, CURLOPT_TIMEOUT, timeout_value);
  curl_easy_setopt(eh, CURLOPT_NOSIGNAL, 1);
  curl_easy_setopt(eh, CURLOPT_USERAGENT, "libEtPan!");

  /* Use HTTP's If-Modified-Since feature, if application provided
   * the timestamp of last update. */
  if (last_update != -1) {
    curl_easy_setopt(eh, CURLOPT_TIMECONDITION,
        CURL_TIMECOND_IFMODSINCE);
    curl_easy_setopt(eh, CURLOPT_TIMEVALUE, last_update);
  }

#if LIBCURL_VERSION_NUM >= 0x070a00
  curl_easy_setopt(eh, CURLOPT_SSL_VERIFYPEER, 0);
  curl_easy_setopt(eh, CURLOPT_SSL_VERIFYHOST, 0);
#endif

  curl_res = curl_easy_perform(eh);
  if (curl_res != 0) {
    res = curl_error_convert(curl_res);
    goto free_str;
  }

  curl_easy_getinfo(eh, CURLINFO_RESPONSE_CODE, &response_code);

  curl_easy_cleanup(eh);

  if (feed_ctx->error != NEWSFEED_NO_ERROR) {
    res = feed_ctx->error;
    goto free_str;
  }

  /* Cleanup, we should be done. */
  mmap_string_free(feed_ctx->str);
  XML_ParserFree(feed_ctx->parser);
  free(feed_ctx);

  feed->feed_response_code = (int) response_code;

  return NEWSFEED_NO_ERROR;;

 free_str:
  mmap_string_free(feed_ctx->str);
 free_praser:
  XML_ParserFree(feed_ctx->parser);
 free_ctx:
  free(feed_ctx);
 free_eh:
  curl_easy_cleanup(eh);
 err:
  return res;
#else
  UNUSED(feed);
  UNUSED(last_update);
  return NEWSFEED_ERROR_INTERNAL;
#endif
}
Пример #8
0
carray * mailstream_low_ssl_get_certificate_chain(mailstream_low * s)
{
#ifdef USE_SSL
  struct mailstream_ssl_data * ssl_data;
  carray * result;
  int skpos;
#ifndef USE_GNUTLS
  STACK_OF(X509) * skx;
  
  ssl_data = (struct mailstream_ssl_data *) s->data;
  if (!(skx = SSL_get_peer_cert_chain(ssl_data->ssl_conn))) {
    return NULL;
  }
  
  result = carray_new(4);
  for(skpos = 0 ; skpos < sk_num((_STACK *) skx) ; skpos ++) {
    X509 * x = (X509 *) sk_value((_STACK *) skx, skpos);
    unsigned char * p;
    MMAPString * str;
    int length = i2d_X509(x, NULL);
    str = mmap_string_sized_new(length);
    p = (unsigned char *) str->str;
    str->len = length;
    i2d_X509(x, &p);
    carray_add(result, str, NULL);
  }
  
  return result;
#else
  gnutls_session session = NULL;
  const gnutls_datum *raw_cert_list;
  unsigned int raw_cert_list_length;

  ssl_data = (struct mailstream_ssl_data *) s->data;

  session = ssl_data->session;
  raw_cert_list = gnutls_certificate_get_peers(session, &raw_cert_list_length);

  if (raw_cert_list && gnutls_certificate_type_get(session) == GNUTLS_CRT_X509) {
    result = carray_new(4);
    for(skpos = 0 ; skpos < raw_cert_list_length ; skpos ++) {
      gnutls_x509_crt cert = NULL;
      if (gnutls_x509_crt_init(&cert) >= 0
       && gnutls_x509_crt_import(cert, &raw_cert_list[skpos], GNUTLS_X509_FMT_DER) >= 0) {
         size_t cert_size = 0;
         MMAPString * str = NULL;
         unsigned char * p;

         if (gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, NULL, &cert_size)
	     == GNUTLS_E_SHORT_MEMORY_BUFFER) {
           str = mmap_string_sized_new(cert_size);
           p = (unsigned char *) str->str;
           str->len = cert_size;
	 }
	 if (str != NULL &&
             gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, p, &cert_size) >= 0) {
           carray_add(result, str, NULL);
	 } else {
	   return NULL;
	 }
         gnutls_x509_crt_deinit(cert);
       }
    }
  }

  return result;

  return NULL;
#endif
#else
  return NULL;
#endif
}
Пример #9
0
int mailmbox_fetch_msg_headers(struct mailmbox_folder * folder,
			       uint32_t num, char ** result,
			       size_t * result_len)
{
  MMAPString * mmapstr;
  int res;
  char * data;
  size_t len;
  int r;
  size_t fixed_size;
  char * end;

  r = mailmbox_validate_read_lock(folder);
  if (r != MAILMBOX_NO_ERROR) {
    res = r;
    goto err;
  }

  r = mailmbox_fetch_msg_headers_no_lock(folder, num, &data, &len);
  if (r != MAILMBOX_NO_ERROR) {
    res = r;
    goto unlock;
  }

#if 0
  mmapstr = mmap_string_new_len(data, len);
  if (mmapstr == NULL) {
    res = MAILMBOX_ERROR_MEMORY;
    goto unlock;
  }
#endif
  /* size with no uid */
  fixed_size = get_fixed_message_size(data, len, 0, 1 /* force no uid */);
  
  mmapstr = mmap_string_sized_new(fixed_size);
  if (mmapstr == NULL) {
    res = MAILMBOX_ERROR_MEMORY;
    goto unlock;
  }
  
  end = write_fixed_message(mmapstr->str, data, len, 0, 1 /* force no uid */);
  * end = '\0';
  mmapstr->len = fixed_size;

  r = mmap_string_ref(mmapstr);
  if (r < 0) {
    mmap_string_free(mmapstr);
    res = MAILMBOX_ERROR_MEMORY;
    goto unlock;
  }

  * result = mmapstr->str;
  * result_len = mmapstr->len;

  mailmbox_read_unlock(folder);

  return MAILMBOX_NO_ERROR;

 unlock:
  mailmbox_read_unlock(folder);
 err:
  return res;
}
Пример #10
0
static carray * mailstream_low_cfstream_get_certificate_chain(mailstream_low * s)
{
#if HAVE_CFNETWORK
  struct mailstream_cfstream_data * cfstream_data;
  unsigned int i;
  carray * result;
  CFArrayRef certs;
  CFIndex count;
  
  cfstream_data = (struct mailstream_cfstream_data *) s->data;
    
  SecTrustRef secTrust = (SecTrustRef)CFReadStreamCopyProperty(cfstream_data->readStream, kCFStreamPropertySSLPeerTrust);
  if (secTrust) {
      // SecTrustEvaluate() needs to be called before SecTrustGetCertificateCount() in Mac OS X <= 10.8
      SecTrustEvaluate(secTrust, NULL);
      count = SecTrustGetCertificateCount(secTrust);
      result = carray_new(4);
      for(i = 0 ; i < count ; i ++) {
          SecCertificateRef cert = (SecCertificateRef) SecTrustGetCertificateAtIndex(secTrust, i);
          CFDataRef data = SecCertificateCopyData(cert);
          if (data == NULL) {
            carray_free(result);
            CFRelease(secTrust);
            return NULL;
          }
          CFIndex length = CFDataGetLength(data);
          const UInt8 * bytes = CFDataGetBytePtr(data);
          MMAPString * str = mmap_string_sized_new(length);
          mmap_string_append_len(str, (char*) bytes, length);
          carray_add(result, str, NULL);
          CFRelease(data);
      }
      CFRelease(secTrust);
  }
  else {
      certs = CFReadStreamCopyProperty(cfstream_data->readStream, kCFStreamPropertySSLPeerCertificates);
      if (certs) {
          count = CFArrayGetCount(certs);
          result = carray_new(4);
          for(i = 0 ; i < count ; i ++) {
              SecCertificateRef cert = (SecCertificateRef) CFArrayGetValueAtIndex(certs, i);
              CFDataRef data = SecCertificateCopyData(cert);
              if (data == NULL) {
                carray_free(result);
                CFRelease(certs);
                return NULL;
              }
              CFIndex length = CFDataGetLength(data);
              const UInt8 * bytes = CFDataGetBytePtr(data);
              MMAPString * str = mmap_string_sized_new(length);
              mmap_string_append_len(str, (char*) bytes, length);
              carray_add(result, str, NULL);
              CFRelease(data);
          }
          CFRelease(certs);
      }
      else {
          return NULL;
      }
  }
    
  return result;
#else
  return NULL;
#endif
}
Пример #11
0
LIBETPAN_EXPORT
int charconv_buffer(const char * tocode, const char * fromcode,
                    const char * str, size_t length,
                    char ** result, size_t * result_len)
{
#ifdef HAVE_ICONV
    iconv_t conv;
    size_t iconv_r;
    int r;
    char * out;
    char * pout;
    size_t out_size;
    size_t old_out_size;
    size_t count;
#endif
    int res;
    MMAPString * mmapstr;

    if (extended_charconv != NULL) {
        size_t		result_length;
        result_length = length * 6;
        mmapstr = mmap_string_sized_new( result_length + 1);
        *result_len = 0;
        if (mmapstr == NULL) {
            res = MAIL_CHARCONV_ERROR_MEMORY;
        } else {
            res = (*extended_charconv)( tocode, fromcode, str, length, mmapstr->str, &result_length);
            if (res != MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET) {
                if (res == MAIL_CHARCONV_NO_ERROR) {
                    *result = mmapstr->str;
                    res = mmap_string_ref(mmapstr);
                    if (res < 0) {
                        res = MAIL_CHARCONV_ERROR_MEMORY;
                        mmap_string_free(mmapstr);
                    } else {
                        mmap_string_set_size( mmapstr, result_length);	/* can't fail */
                        *result_len = result_length;
                    }
                }
                free( *result);
            }
            return res;
        }
        /* else, let's try with iconv, if available */
    }

#ifndef HAVE_ICONV
    return MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET;
#else

    conv = iconv_open(tocode, fromcode);
    if (conv == (iconv_t) -1) {
        res = MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET;
        goto err;
    }

    out_size = 6 * length; /* UTF-8 can be encoded up to 6 bytes */

    mmapstr = mmap_string_sized_new(out_size + 1);
    if (mmapstr == NULL) {
        res = MAIL_CHARCONV_ERROR_MEMORY;
        goto err;
    }

    out = mmapstr->str;

    pout = out;
    old_out_size = out_size;

    iconv_r = mail_iconv(conv, &str, &length, &pout, &out_size, NULL, "?");

    if (iconv_r == (size_t) -1) {
        res = MAIL_CHARCONV_ERROR_CONV;
        goto free;
    }

    iconv_close(conv);

    * pout = '\0';

    count = old_out_size - out_size;

    r = mmap_string_ref(mmapstr);
    if (r < 0) {
        res = MAIL_CHARCONV_ERROR_MEMORY;
        goto free;
    }

    * result = out;
    * result_len = count;

    return MAIL_CHARCONV_NO_ERROR;

free:
    mmap_string_free(mmapstr);
err:
    return res;
#endif
}