Beispiel #1
0
static herror_t
_hssl_server_context_init(void)
{
  log_verbose3("enabled=%i, certificate=%p", enabled, certificate);

  if (!enabled || !certificate)
    return H_OK;

  if (!(context = SSL_CTX_new(SSLv23_method())))
  {
    log_error1("Cannot create SSL context");
    return herror_new("_hssl_server_context_init", HSSL_ERROR_CONTEXT,
                      "Unable to create SSL context");
  }

  if (!(SSL_CTX_use_certificate_file(context, certificate, SSL_FILETYPE_PEM)))
  {
    log_error2("Cannot read certificate file: \"%s\"", certificate);
    SSL_CTX_free(context);
    return herror_new("_hssl_server_context_init", HSSL_ERROR_CERTIFICATE,
                      "Unable to use SSL certificate \"%s\"", certificate);
  }

  SSL_CTX_set_default_passwd_cb(context, _hssl_password_callback);

  if (!(SSL_CTX_use_PrivateKey_file(context, certificate, SSL_FILETYPE_PEM)))
  {
    log_error2("Cannot read key file: \"%s\"", certificate);
    SSL_CTX_free(context);
    return herror_new("_hssl_server_context_init", HSSL_ERROR_PEM,
                      "Unable to use private key");
  }

  if (ca_list != NULL && *ca_list != '\0')
  {
    if (!(SSL_CTX_load_verify_locations(context, ca_list, NULL)))
    {
      SSL_CTX_free(context);
      log_error2("Cannot read CA list: \"%s\"", ca_list);
      return herror_new("_hssl_server_context_init", HSSL_ERROR_CA_LIST,
                        "Unable to read certification authorities \"%s\"");
    }

    SSL_CTX_set_client_CA_list(context, SSL_load_client_CA_file(ca_list));
    log_verbose1("Certification authority contacted");
  }

  SSL_CTX_set_verify(context, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE,
                     _hssl_cert_verify_callback);
  log_verbose1("Certificate verification callback registered");

  SSL_CTX_set_mode(context, SSL_MODE_AUTO_RETRY);

  SSL_CTX_set_session_cache_mode(context, SSL_SESS_CACHE_OFF);

  _hssl_superseed();

  return H_OK;
}
Beispiel #2
0
herror_t
hssl_server_ssl(hsocket_t * sock)
{
  SSL *ssl;
  int ret;
  BIO *sbio;

  if (!enabled)
    return H_OK;

  log_verbose2("Starting SSL initialization for socket %d", sock->sock);

  if (!(ssl = SSL_new(context)))
  {
    log_warn1("SSL_new failed");
    return herror_new("hssl_server_ssl", HSSL_ERROR_SERVER,
                      "Cannot create SSL object");
  }
  /* SSL_set_fd(ssl, sock->sock); */

  sbio = BIO_new_socket(sock->sock, BIO_NOCLOSE);

  if (sbio == NULL)
  {
    log_error1("BIO_new_socket failed");
    return NULL;
  }
  // BIO_set_callback(sbio, hssl_bio_cb);
  sbio->method->bread = _hssl_bio_read;
  SSL_set_bio(ssl, sbio, sbio);


  if ((ret = SSL_accept(ssl)) <= 0)
  {
    herror_t err;

    log_error2("SSL_accept failed (%s)", _hssl_get_error(ssl, ret));

    err =
      herror_new("hssl_server_ssl", HSSL_ERROR_SERVER,
                 "SSL_accept failed (%s)", _hssl_get_error(ssl, ret));
    SSL_free(ssl);

    return err;
  }

  sock->ssl = ssl;

  return H_OK;
}
/**
  Send boundary and part header and continue 
  with next part
*/
herror_t
httpc_mime_send_file(httpc_conn_t * conn,
                     const char *content_id,
                     const char *content_type,
                     const char *transfer_encoding, const char *filename)
{
  herror_t status;
  FILE *fd = fopen(filename, "rb");
  byte_t buffer[MAX_FILE_BUFFER_SIZE];
  size_t size;

  if (fd == NULL)
    return herror_new("httpc_mime_send_file", FILE_ERROR_OPEN,
                      "Can not open file '%s'", filename);

  status = httpc_mime_next(conn, content_id, content_type, transfer_encoding);
  if (status != H_OK)
  {
    fclose(fd);
    return status;
  }

  while (!feof(fd))
  {
    size = fread(buffer, 1, MAX_FILE_BUFFER_SIZE, fd);
    if (size == -1)
    {
      fclose(fd);
      return herror_new("httpc_mime_send_file", FILE_ERROR_READ,
                        "Can not read from file '%s'", filename);
    }

    if (size > 0)
    {
      /* DEBUG: fwrite(buffer, 1, size, stdout); */
      status = http_output_stream_write(conn->out, buffer, size);
      if (status != H_OK)
      {
        fclose(fd);
        return status;
      }
    }
  }

  fclose(fd);
  log_verbose1("file sent!");
  return H_OK;
}
herror_t
soap_ctx_add_file(SoapCtx * ctx, const char *filename,
                  const char *content_type, char *dest_href)
{
  char cid[250];
  char id[250];
  part_t *part;
  static int counter = 1;
  FILE *test = fopen(filename, "r");
  if (!test)
    return herror_new("soap_ctx_add_file", FILE_ERROR_OPEN,
                      "Can not open file '%s'", filename);

  fclose(test);

  /* generate an id */
  sprintf(id, "005512345894583%d", counter++);
  sprintf(dest_href, "cid:%s", id);
  sprintf(cid, "<%s>", id);

  /* add part to context */
  part = part_new(cid, filename, content_type, NULL, NULL);
  if (!ctx->attachments)
    ctx->attachments = attachments_new();
  attachments_add_part(ctx->attachments, part);

  return H_OK;
}
Beispiel #5
0
herror_t
soap_env_new_with_response(SoapEnv * request, SoapEnv ** out)
{
  char *method, *res_method;
  herror_t ret;
  char *urn;

  if (request == NULL)
  {
    return herror_new("soap_env_new_with_response",
                      GENERAL_INVALID_PARAM, "request (first param) is NULL");
  }

  if (request->root == NULL)
  {
    return herror_new("soap_env_new_with_response",
                      GENERAL_INVALID_PARAM,
                      "request (first param) has no xml structure");
  }

  if (!(method = soap_env_find_methodname(request)))
  {
    return herror_new("soap_env_new_with_response",
                      GENERAL_INVALID_PARAM,
                      "Method name '%s' not found in request",
                      SAVE_STR(method));
  }

  if (!(urn = soap_env_find_urn(request)))
  {

    /* here we have no chance to find out the namespace */
    /* try to continue without namespace (urn) */
    urn = "";
  }

  if (!(res_method = (char *)malloc(strlen(method)+9)))
    return herror_new("soap_env_new_with_response", GENERAL_INVALID_PARAM, "malloc failed");

  sprintf(res_method, "%sResponse", method);

  ret = soap_env_new_with_method(urn, res_method, out);

  free(res_method);

  return ret;
}
Beispiel #6
0
herror_t
hssl_client_ssl(hsocket_t * sock)
{
  SSL *ssl;
  int ret;

  log_verbose1("Starting SSL client initialization");

  if (!(ssl = SSL_new(context)))
  {
    log_error1("Cannot create new SSL object");
    return herror_new("hssl_client_ssl", HSSL_ERROR_CLIENT, "SSL_new failed");
  }

  SSL_set_fd(ssl, sock->sock);

  if ((ret = SSL_connect(ssl)) <= 0)
  {
    herror_t err;

    log_error2("SSL connect error (%s)", _hssl_get_error(ssl, -1));
    err =
      herror_new("hssl_client_ssl", HSSL_ERROR_CONNECT,
                 "SSL_connect failed (%s)", _hssl_get_error(ssl, ret));
    SSL_free(ssl);
    return err;
  }

  /* SSL_connect should take care of this for us. if
     (SSL_get_peer_certificate(ssl) == NULL) { log_error1("No certificate
     provided"); SSL_free(ssl); return herror_new("hssl_client_ssl",
     HSSL_ERROR_CERTIFICATE, "No certificate provided"); }

     if (SSL_get_verify_result(ssl) != X509_V_OK) { log_error1("Certificate
     did not verify"); SSL_free(ssl); return herror_new("hssl_client_ssl",
     HSSL_ERROR_CERTIFICATE, "Verfiy certificate failed"); } */

  log_verbose1("SSL client initialization completed");

  sock->ssl = ssl;

  return H_OK;
}
Beispiel #7
0
herror_t
hssl_read(hsocket_t * sock, char *buf, size_t len, size_t * received)
{
  int count;

  if ((count = hsocket_select_read(sock->sock, buf, len)) == -1)
    return herror_new("hssl_read", HSOCKET_ERROR_RECEIVE, "recv failed (%s)",
                      strerror(errno));
  *received = count;
  return H_OK;
}
Beispiel #8
0
herror_t
soap_env_new_from_buffer(const char *buffer, SoapEnv ** out)
{
  xmlDocPtr doc;
  herror_t err;

  if (buffer == NULL)
    return herror_new("soap_env_new_from_buffer",
                      GENERAL_INVALID_PARAM, "buffer (first param) is NULL");

  if (!(doc = xmlParseDoc(BAD_CAST buffer)))
    return herror_new("soap_env_new_from_buffer",
                      XML_ERROR_PARSE, "Can not parse xml");

  if ((err = soap_env_new_from_doc(doc, out)) != H_OK)
  {
    xmlFreeDoc(doc);
  }
  return err;
}
Beispiel #9
0
herror_t
hssl_write(hsocket_t * sock, const char *buf, size_t len, size_t * sent)
{
  int count;

  if ((count = send(sock->sock, buf, len, 0)) == -1)
    return herror_new("hssl_write", HSOCKET_ERROR_SEND, "send failed (%s)",
                      strerror(errno));
  *sent = count;
  return H_OK;
}
Beispiel #10
0
herror_t
httpd_register_secure(const char *context, httpd_service func, httpd_auth auth)
{
  hservice_t *service;

  if (!(service = (hservice_t *) malloc(sizeof(hservice_t))))
  {
    log_error("malloc failed (%s)", strerror(errno));
    return herror_new("httpd_register_secure", 0, "malloc failed (%s)", strerror(errno));
  }

  if (!(service->statistics = (struct service_statistics *)malloc(sizeof(struct service_statistics))))
  {
    log_error("malloc failed (%s)", strerror(errno));
    free(service);
    return herror_new("httpd_register_secure", 0, "malloc failed (%s)", strerror(errno));
  }    	
  memset(service->statistics, 0, sizeof(struct service_statistics));
  service->statistics->time.tv_sec = 0;
  service->statistics->time.tv_usec = 0;
  pthread_rwlock_init(&(service->statistics->lock), NULL);

  service->next = NULL;
  service->auth = auth;
  service->func = func;
  service->status = NHTTPD_SERVICE_UP;
  service->context = strdup(context);

  log_verbose("register service (%p) for \"%s\"", service, context);
  if (_httpd_services_head == NULL)
  {
    _httpd_services_head = _httpd_services_tail = service;
  }
  else
  {
    _httpd_services_tail->next = service;
    _httpd_services_tail = service;
  }

  return H_OK;
}
Beispiel #11
0
/**
  Send boundary and part header and continue 
  with next part
*/
herror_t
httpd_mime_send_file(httpd_conn_t * conn, const char *content_id,
                     const char *content_type, const char *transfer_encoding,
                     const char *filename)
{
  unsigned char buffer[MAX_FILE_BUFFER_SIZE];
  herror_t status;
  FILE *fd;
  size_t size;

  if ((fd = fopen(filename, "rb")) == NULL)
    return herror_new("httpd_mime_send_file", FILE_ERROR_OPEN,
                      "Can not open file '%d'", filename);

  status = httpd_mime_next(conn, content_id, content_type, transfer_encoding);
  if (status != H_OK)
  {
    fclose(fd);
    return status;
  }

  while (!feof(fd))
  {
    size = fread(buffer, 1, MAX_FILE_BUFFER_SIZE, fd);
    if (size == -1)
    {
      fclose(fd);
      return herror_new("httpd_mime_send_file", FILE_ERROR_READ,
                        "Can not read from file '%d'", filename);
    }

    if ((status = http_output_stream_write(conn->out, buffer, size)) != H_OK)
    {
      fclose(fd);
      return status;
    }
  }

  fclose(fd);
  return H_OK;
}
Beispiel #12
0
herror_t
soap_env_new_from_doc(xmlDocPtr doc, SoapEnv ** out)
{
  xmlNodePtr node;
  SoapEnv *env;

  if (doc == NULL)
  {
    log_error1("Can not create xml document!");
    return herror_new("soap_env_new_from_doc",
                      GENERAL_INVALID_PARAM,
                      "XML Document (xmlDocPtr) is NULL");
  }

  if (!(node = xmlDocGetRootElement(doc)))
  {
    log_error1("XML document is empty!");
    return herror_new("soap_env_new_from_doc",
                      XML_ERROR_EMPTY_DOCUMENT, "XML Document is empty!");
  }

  if (!(env = (SoapEnv *) malloc(sizeof(SoapEnv))))
  {
    log_error2("malloc failed (%s)", strerror(errno));
    return herror_new("soap_env_from_doc", GENERAL_INVALID_PARAM, "malloc failed");
  }

 
  env->root = node;
  env->header = soap_env_get_header(env);
  env->body = soap_env_get_body(env);
  env->cur = soap_env_get_method(env);

  
  *out = env;

  return H_OK;
}
Beispiel #13
0
herror_t
hssl_write(hsocket_t * sock, const char *buf, size_t len, size_t * sent)
{
  int count;

/*  log_verbose4("sock->sock=%d, sock->ssl=%p, len=%li", sock->sock, sock->ssl, len); */

  if (sock->ssl)
  {
    if ((count = SSL_write(sock->ssl, buf, len)) == -1)
      return herror_new("SSL_write", HSOCKET_ERROR_SEND,
                        "SSL_write failed (%s)", _hssl_get_error(sock->ssl,
                                                                 count));
  }
  else
  {
    if ((count = send(sock->sock, buf, len, 0)) == -1)
      return herror_new("hssl_write", HSOCKET_ERROR_SEND, "send failed (%s)",
                        strerror(errno));
  }
  *sent = count;

  return H_OK;
}
Beispiel #14
0
herror_t
hssl_read(hsocket_t * sock, char *buf, size_t len, size_t * received)
{
  int count;

/* log_verbose4("sock->sock=%d sock->ssl=%p, len=%li", sock->sock, sock->ssl, len); */

  if (sock->ssl)
  {
    if ((count = SSL_read(sock->ssl, buf, len)) < 1)
      return herror_new("SSL_read", HSOCKET_ERROR_RECEIVE,
                        "SSL_read failed (%s)", _hssl_get_error(sock->ssl,
                                                                count));
  }
  else
  {
    if ((count = hsocket_select_read(sock->sock, buf, len)) == -1)
      return herror_new("hssl_read", HSOCKET_ERROR_RECEIVE,
                        "recv failed (%s)", strerror(errno));
  }
  *received = count;

  return H_OK;
}
Beispiel #15
0
herror_t
soap_env_new_with_method(const char *urn, const char *method, SoapEnv ** out)
{
  xmlDocPtr env;
  xmlChar buffer[1054];

  log_verbose2("URN = '%s'", urn);
  log_verbose2("Method = '%s'", method);

  if (!strcmp(urn, ""))
  {
#ifdef USE_XMLSTRING
    xmlStrPrintf(buffer, 1054, BAD_CAST _SOAP_MSG_TEMPLATE_EMPTY_TARGET_,
                 soap_env_ns, soap_env_enc, soap_xsi_ns,
                 soap_xsd_ns, BAD_CAST method, BAD_CAST urn, BAD_CAST method);
#else
    sprintf((char *)buffer, _SOAP_MSG_TEMPLATE_EMPTY_TARGET_,
            soap_env_ns, soap_env_enc, soap_xsi_ns,
            soap_xsd_ns, method, urn, method);
#endif
  }
  else
  {
#ifdef USE_XMLSTRING
    xmlStrPrintf(buffer, 1054, BAD_CAST _SOAP_MSG_TEMPLATE_,
                 soap_env_ns, soap_env_enc, soap_xsi_ns,
                 soap_xsd_ns, BAD_CAST method, BAD_CAST urn, BAD_CAST method);
#else
    sprintf((char *)buffer, _SOAP_MSG_TEMPLATE_,
            soap_env_ns, soap_env_enc, soap_xsi_ns,
            soap_xsd_ns, method, urn, method);
#endif

  }

  if (!(env = xmlParseDoc(buffer)))
    return herror_new("soap_env_new_with_method",
                      XML_ERROR_PARSE, "Can not parse xml");

  return soap_env_new_from_doc(env, out);
}
Beispiel #16
0
herror_t
soap_env_new_with_fault(fault_code_t faultcode,
                        const char *faultstring,
                        const char *faultactor, const char *detail,
                        SoapEnv ** out)
{
  xmlDocPtr doc;
  herror_t err;

  doc = soap_fault_build(faultcode, faultstring, faultactor, detail);
  if (doc == NULL)
    return herror_new("soap_env_new_with_fault",
                      XML_ERROR_PARSE, "Can not parse fault xml");

  if ((err = soap_env_new_from_doc(doc, out)) != H_OK)
  {
    xmlFreeDoc(doc);
  }

  return err;
}
Beispiel #17
0
herror_t
soap_env_new_from_stream(http_input_stream_t * in, SoapEnv ** out, int gbk)
{
  xmlDocPtr doc;

  if (gbk)
        doc = xmlReadIO(_soap_env_xml_io_read_gbk,
                  _soap_env_xml_io_close, in, "", NULL, 0);
  else
        doc = xmlReadIO(_soap_env_xml_io_read,
                  _soap_env_xml_io_close, in, "", NULL, 0);

  if (in->err != H_OK)
    return in->err;

  if (doc == NULL)
    return herror_new("soap_env_new_from_stream",
                      XML_ERROR_PARSE, "Trying to parse not valid xml");

  return soap_env_new_from_doc(doc, out);
}
/*--------------------------------------------------
FUNCTION: httpc_talk_to_server
DESC: This function is the heart of the httpc
module. It will send the request and process the
response.

Here the parameters:

method:
the request method. This can be HTTP_REQUEST_POST and
HTTP_REQUEST_GET.

conn:
the connection object (created with httpc_new())

urlstr:
the complete url in string format.
http://<host>:<port>/<context>
where <port> is not mendatory.

start_cb:
a callback function, which will be called when
the response header is completely arrives.

cb:
a callback function, which will be called everytime
when data arrives.

content_size:
size of content to send.
(only if method is HTTP_REQUEST_POST)

content:
the content data to send.
(only if method is HTTP_REQUEST_POST)

userdata:
a user define data, which will be passed to the
start_cb and cb callbacks as a parameter. This
can also be NULL.


If success, this function will return 0.
>0 otherwise.
----------------------------------------------------*/
static herror_t
httpc_talk_to_server(hreq_method_t method, httpc_conn_t * conn,
                     const char *urlstr)
{

  hurl_t url;
  char buffer[4096];
  herror_t status;
  int ssl;

  if (conn == NULL)
  {
    return herror_new("httpc_talk_to_server",
                      GENERAL_INVALID_PARAM, "httpc_conn_t param is NULL");
  }
  /* Build request header */
  httpc_header_set_date(conn);

  if ((status = hurl_parse(&url, urlstr)) != H_OK)
  {
    log_error2("Can not parse URL '%s'", SAVE_STR(urlstr));
    return status;
  }
/* TODO (#1#): Check for HTTP protocol in URL */

  /* Set hostname */
  httpc_set_header(conn, HEADER_HOST, url.host);

  ssl = url.protocol == PROTOCOL_HTTPS ? 1 : 0;

  /* Open connection */
  if ((status = hsocket_open(&conn->sock, url.host, url.port, ssl)) != H_OK)
    return status;

  switch(method)
  {
    case HTTP_REQUEST_GET:

      sprintf(buffer, "GET %s HTTP/%s\r\n",
        (url.context[0] != '\0') ? url.context : ("/"),
        (conn->version == HTTP_1_0) ? "1.0" : "1.1");
      break;

    case HTTP_REQUEST_POST:

      sprintf(buffer, "POST %s HTTP/%s\r\n",
        (url.context[0] != '\0') ? url.context : ("/"),
        (conn->version == HTTP_1_0) ? "1.0" : "1.1");
      break;

    default:
      log_error1("Unknown method type!");
      return herror_new("httpc_talk_to_server",
        GENERAL_INVALID_PARAM,
        "hreq_method_t must be  HTTP_REQUEST_GET or HTTP_REQUEST_POST");
  }

  log_verbose1("Sending request...");
  if ((status = hsocket_send(&(conn->sock), buffer)) != H_OK)
  {
    log_error2("Cannot send request (%s)", herror_message(status));
    hsocket_close(&(conn->sock));
    return status;
  }

  log_verbose1("Sending header...");
  if ((status = httpc_send_header(conn)) != H_OK)
  {
    log_error2("Cannot send header (%s)", herror_message(status));
    hsocket_close(&(conn->sock));
    return status;
  }

  return H_OK;
}
herror_t
hurl_parse(hurl_t * url, const char *urlstr)
{
  int iprotocol;
  int ihost;
  int iport;
  int len;
  int size;
  char tmp[8];
  char protocol[1024];

  iprotocol = 0;
  len = strlen(urlstr);

  /* find protocol */
  while (urlstr[iprotocol] != ':' && urlstr[iprotocol] != '\0')
  {
    iprotocol++;
  }

  if (iprotocol == 0)
  {
    log_error1("no protocol");
    return herror_new("hurl_parse", URL_ERROR_NO_PROTOCOL, "No protocol");
  }
  if (iprotocol + 3 >= len)
  {
    log_error1("no host");
    return herror_new("hurl_parse", URL_ERROR_NO_HOST, "No host");
  }
  if (urlstr[iprotocol] != ':'
      && urlstr[iprotocol + 1] != '/' && urlstr[iprotocol + 2] != '/')
  {
    log_error1("no protocol");
    return herror_new("hurl_parse", URL_ERROR_NO_PROTOCOL, "No protocol");
  }
  /* find host */
  ihost = iprotocol + 3;
  while (urlstr[ihost] != ':'
         && urlstr[ihost] != '/' && urlstr[ihost] != '\0')
  {
    ihost++;
  }

  if (ihost == iprotocol + 1)
  {
    log_error1("no host");
    return herror_new("hurl_parse", URL_ERROR_NO_HOST, "No host");
  }
  /* find port */
  iport = ihost;
  if (ihost + 1 < len)
  {
    if (urlstr[ihost] == ':')
    {
      while (urlstr[iport] != '/' && urlstr[iport] != '\0')
      {
        iport++;
      }
    }
  }

  /* find protocol */
  strncpy(protocol, urlstr, iprotocol);
  protocol[iprotocol] = '\0';
  if (strcmpigcase(protocol, "http"))
    url->protocol = PROTOCOL_HTTP;
  else if (strcmpigcase(protocol, "https"))
    url->protocol = PROTOCOL_HTTPS;
  else if (strcmpigcase(protocol, "ftp"))
    url->protocol = PROTOCOL_FTP;
  else
    return herror_new("hurl_parse",
                      URL_ERROR_UNKNOWN_PROTOCOL, "Unknown protocol '%s'",
                      protocol);

  /* TODO (#1#): add max of size and URL_MAX_HOST_SIZE */
  size = ihost - iprotocol - 3;
  strncpy(url->host, &urlstr[iprotocol + 3], size);
  url->host[size] = '\0';

  if (iport > ihost)
  {
    size = iport - ihost;
    strncpy(tmp, &urlstr[ihost + 1], size);
    url->port = atoi(tmp);
  }
  else
  {
    switch (url->protocol)
    {
    case PROTOCOL_HTTP:
      url->port = URL_DEFAULT_PORT_HTTP;
      break;
    case PROTOCOL_HTTPS:
      url->port = URL_DEFAULT_PORT_HTTPS;
      break;
    case PROTOCOL_FTP:
      url->port = URL_DEFAULT_PORT_FTP;
      break;
    }
  }

  len = strlen(urlstr);
  if (len > iport)
  {
    /* TODO (#1#): find max of size and URL_MAX_CONTEXT_SIZE */
    size = len - iport;
    strncpy(url->context, &urlstr[iport], size);
    url->context[size] = '\0';
  }
  else
  {
    url->context[0] = '\0';
  }

  hurl_dump(url);

  return H_OK;
}
Beispiel #20
0
herror_t
hurl_parse(struct hurl_t *url, const char *urlstr)
{
  int iprotocol;
  int ihost;
  int iport;
  int len;
  int size;
  char tmp[8];
  char protocol[1024];
  struct servent *entry;

  iprotocol = 0;
  len = strlen(urlstr);

  /* find protocol */
  while (urlstr[iprotocol] != ':' && urlstr[iprotocol] != '\0')
  {
    iprotocol++;
  }

  if (iprotocol == 0)
  {
    log_error("no protocol");
    return herror_new("hurl_parse", URL_ERROR_NO_PROTOCOL, "No protocol");
  }
  if (iprotocol + 3 >= len)
  {
    log_error("no host");
    return herror_new("hurl_parse", URL_ERROR_NO_HOST, "No host");
  }
  if (urlstr[iprotocol] != ':'
      && urlstr[iprotocol + 1] != '/' && urlstr[iprotocol + 2] != '/')
  {
    log_error("no protocol");
    return herror_new("hurl_parse", URL_ERROR_NO_PROTOCOL, "No protocol");
  }

  /* find host */
  ihost = iprotocol + 3;
  while (urlstr[ihost] != ':'
         && urlstr[ihost] != '/' && urlstr[ihost] != '\0')
  {
    ihost++;
  }

  if (ihost == iprotocol + 1)
  {
    log_error("no host");
    return herror_new("hurl_parse", URL_ERROR_NO_HOST, "No host");
  }

  /* find port */
  iport = ihost;
  if (ihost + 1 < len)
  {
    if (urlstr[ihost] == ':')
    {
      while (urlstr[iport] != '/' && urlstr[iport] != '\0')
      {
        iport++;
      }
    }
  }

  /* find protocol */
  strncpy(protocol, urlstr, iprotocol);
  protocol[iprotocol] = '\0';
  if (!strncasecmp(protocol, "http", 5))
    url->protocol = PROTOCOL_HTTP;
  else if (!strncasecmp(protocol, "https", 6))
    url->protocol = PROTOCOL_HTTPS;
  else
    return herror_new("hurl_parse", URL_ERROR_UNKNOWN_PROTOCOL, "Unknown protocol \"%s\"", protocol);

  /* find right port */
  if (!(entry = getservbyname(protocol, "tcp")))
  {
    log_warn("getservbyname(\"%s\", \"tcp\") returned NULL, please edit services database", protocol);

    switch (url->protocol)
    {
    case PROTOCOL_HTTP:
      url->port = HTTP_DEFAULT_PORT;
      break;
    case PROTOCOL_HTTPS:
      url->port = HTTPS_DEFAULT_PORT;
      break;
    }
  }
  else
  {
    url->port = ntohs(entry->s_port);
  }

  size = ihost - iprotocol - 3;
  if (!(url->host = (char *)malloc(size + 1)))
  {
    log_error("malloc failed (%s)", strerror(errno));
    return herror_new("hurl_parse", URL_ERROR, "malloc failed (%s)", strerror(errno));
  }
  strncpy(url->host, &urlstr[iprotocol + 3], size);
  url->host[size] = '\0';

  if (iport > ihost)
  {
    size = iport - ihost;
    strncpy(tmp, &urlstr[ihost + 1], size);
    url->port = atoi(tmp);
  }

  /* find path */
  len = strlen(urlstr);
  if (len > iport)
  {
    size = len - iport;
    if (!(url->context = (char *)malloc(size + 1)))
    {
      log_error("malloc failed (%s)", strerror(errno));
      return herror_new("hurl_parse", URL_ERROR, "malloc failed (%s)", strerror(errno));
    }
    strncpy(url->context, &urlstr[iport], size);
    url->context[size] = '\0';
  }
  else
  {
    url->context = strdup("");
  }

  _hurl_dump(url);

  return H_OK;
}
Beispiel #21
0
herror_t
hresponse_new_from_socket(hsocket_t *sock, hresponse_t ** out)
{
  int i = 0, count;
  herror_t status;
  hresponse_t *res;
  attachments_t *mimeMessage;
  char buffer[MAX_HEADER_SIZE + 1];

read_header:                   /* for errorcode: 100 (continue) */
  /* Read header */
  while (i < MAX_HEADER_SIZE)
  {
    if ((status = hsocket_read(sock, &(buffer[i]), 1, 1, &count)) != H_OK)
    {
      log_error("Socket read error");
      return status;
    }

    buffer[i + 1] = '\0';       /* for strmp */

    if (i > 3)
    {
      if (!strcmp(&(buffer[i - 1]), "\n\n") ||
          !strcmp(&(buffer[i - 2]), "\n\r\n"))
        break;
    }
    i++;
  }

  /* Create response */
  res = _hresponse_parse_header(buffer);
  if (res == NULL)
  {
    log_error("Header parse error");
    return herror_new("hresponse_new_from_socket",
                      GENERAL_HEADER_PARSE_ERROR,
                      "Can not parse response header");
  }

  /* Chec for Errorcode: 100 (continue) */
  if (res->errcode == 100)
  {
    hresponse_free(res);
    i = 0;
    goto read_header;
  }

  /* Create input stream */
  res->in = http_input_stream_new(sock, res->header);


  /* Check for MIME message */
  if ((res->content_type &&
       !strcmp(res->content_type->type, "multipart/related")))
  {
    status = mime_get_attachments(res->content_type, res->in, &mimeMessage);
    if (status != H_OK)
    {
      /* TODO (#1#): Handle error */
      hresponse_free(res);
      return status;
    }
    else
    {
      res->attachments = mimeMessage;
      http_input_stream_free(res->in);
      res->in =
        http_input_stream_new_from_file(mimeMessage->root_part->filename);
      if (!res->in)
      {
        /* TODO (#1#): Handle error */

      }
      else
      {
        /* res->in->deleteOnExit = 1; */
      }
    }
  }
  *out = res;
  return H_OK;
}
herror_t
mime_get_attachments(content_type_t * ctype, http_input_stream_t * in,
                     attachments_t ** dest)
{
  /* MIME variables */
  attachments_t *mimeMessage;
  part_t *part, *tmp_part = NULL;
  char *boundary, *root_id;

  /* Check for MIME message */
  if (!(ctype && !strcmp(ctype->type, "multipart/related")))
    return herror_new("mime_get_attachments", MIME_ERROR_NOT_MIME_MESSAGE,
                      "Not a MIME message '%s'", ctype->type);

  boundary = hpairnode_get(ctype->params, "boundary");
  root_id = hpairnode_get(ctype->params, "start");
  if (boundary == NULL)
  {
    /* TODO (#1#): Handle Error in http form */
    log_error1("'boundary' not set for multipart/related");
    return herror_new("mime_get_attachments", MIME_ERROR_NO_BOUNDARY_PARAM,
                      "'boundary' not set for multipart/related");
  }

  if (root_id == NULL)
  {
    /* TODO (#1#): Handle Error in http form */
    log_error1("'start' not set for multipart/related");
    return herror_new("mime_get_attachments", MIME_ERROR_NO_START_PARAM,
                      "'start' not set for multipart/related");
  }

  mimeMessage =
    mime_message_parse(in, root_id, boundary, ".");
  if (mimeMessage == NULL)
  {
    /* TODO (#1#): Handle Error in http form */
    log_error1("MIME Parse Error");
    return herror_new("mime_get_attachments", MIME_ERROR_PARSE_ERROR,
                      "MIME Parse Error");
  }

  /* Find root */
  if (!mimeMessage->root_part)
  {
    attachments_free(mimeMessage);
    return herror_new("mime_get_attachments", MIME_ERROR_NO_ROOT_PART,
                      "No root part found!");
  }

  /* delete root_part from list */
  part = mimeMessage->parts;
  while (part)
  {
    if (part == mimeMessage->root_part)
    {
      if (tmp_part)
        tmp_part->next = part->next;
      else
        mimeMessage->parts = part->next;

      break;
    }
    tmp_part = part;
    part = part->next;
  }
  *dest = mimeMessage;
  return H_OK;
}