Beispiel #1
0
END_TEST

START_TEST(remove_test)
{
  dpl_dict_t *dict;
  int i;
  dpl_status_t r;
  char valbuf[128];

  /* create with a small table to ensure we have some chains */
  dict = dpl_dict_new(5);
  dpl_assert_ptr_not_null(dict);

  /* add all the keys */
  for (i = 0 ; i < nkeys ; i++)
    {
      dpl_dict_add(dict, keys[i],
			 make_value(i, valbuf, sizeof(valbuf)),
			 /* lowered */0);
    }
  dpl_assert_int_eq(nkeys, dpl_dict_count(dict));

  /* remove the keys again */
  for (i = 0 ; i < nkeys ; i++)
    {
      dpl_dict_var_t *var = dpl_dict_get(dict, keys[i]);
      dpl_assert_ptr_not_null(var);
      dpl_assert_str_eq(var->key, keys[i]);
      dpl_dict_remove(dict, var);
      dpl_assert_int_eq(nkeys-1-i, dpl_dict_count(dict));
    }

  /* add all the keys back again */
  for (i = 0 ; i < nkeys ; i++)
    {
      dpl_dict_add(dict, keys[i],
			 make_value(i, valbuf, sizeof(valbuf)),
			 /* lowered */0);
    }
  dpl_assert_int_eq(nkeys, dpl_dict_count(dict));

  /* remove the keys again in reverse order; we do
   * this to exercise some hash chain manipulation
   * corner cases */
  for (i = nkeys-1 ; i >= 0 ; i--)
    {
      dpl_dict_var_t *var = dpl_dict_get(dict, keys[i]);
      dpl_assert_ptr_not_null(var);
      dpl_assert_str_eq(var->key, keys[i]);
      dpl_dict_remove(dict, var);
      dpl_assert_int_eq(i, dpl_dict_count(dict));
    }

  dpl_dict_free(dict);
}
Beispiel #2
0
dpl_status_t
dpl_s3_get_authorization_v2_params(const dpl_req_t *req, dpl_dict_t *query_params,
                                   struct tm UNUSED *tm)
{
  dpl_status_t  ret;
  char          expires_str[128], resource_ue[DPL_URL_LENGTH(strlen(req->resource)) + 1];

  snprintf(expires_str, sizeof(expires_str), "%ld", req->expires);

  if ('/' != req->resource[0]) {
    resource_ue[0] = '/';
    dpl_url_encode_no_slashes(req->resource, resource_ue + 1);
  } else
    dpl_url_encode_no_slashes(req->resource, resource_ue);

  ret = dpl_dict_add(query_params, "AWSAccessKeyId", req->ctx->access_key, 0);
  if (ret != DPL_SUCCESS)
    return DPL_FAILURE;

  {
    char sign_str[1024];
    u_int sign_len;
    char hmac_str[1024];
    u_int hmac_len;
    char base64_str[1024];
    u_int base64_len;
    char base64_ue_str[1024];
    const char *method = dpl_method_str(req->method);

    ret = dpl_s3_make_signature_v2(req->ctx, method, req->bucket, resource_ue, NULL,
                                   expires_str, NULL,
                                   sign_str, sizeof (sign_str), &sign_len);
    if (ret != DPL_SUCCESS)
      return DPL_FAILURE;

    DPRINTF("%s\n", sign_str);

    hmac_len = dpl_hmac_sha1(req->ctx->secret_key, strlen(req->ctx->secret_key), sign_str, sign_len, hmac_str);

    base64_len = dpl_base64_encode((const u_char *) hmac_str, hmac_len, (u_char *) base64_str);
    base64_str[base64_len] = 0;

    dpl_url_encode(base64_str, base64_ue_str);

    ret = dpl_dict_add(query_params, "Signature", base64_ue_str, 0);
    if (ret != DPL_SUCCESS)
      return DPL_FAILURE;
  }

  ret = dpl_dict_add(query_params, "Expires", expires_str, 0);
  if (ret != DPL_SUCCESS)
    return DPL_FAILURE;

  return DPL_SUCCESS;
}
Beispiel #3
0
static dpl_status_t
add_authorization_to_headers(const dpl_req_t *req,
                             dpl_dict_t *headers)
{
  int ret, ret2;
  char basic_str[1024];
  int basic_len;
  char base64_str[1024];
  int base64_len;
  char auth_str[1024];

  snprintf(basic_str, sizeof (basic_str), "%s:%s", req->ctx->access_key, req->ctx->secret_key);
  basic_len = strlen(basic_str);

  base64_len = dpl_base64_encode((const u_char *) basic_str, basic_len, (u_char *) base64_str);

  snprintf(auth_str, sizeof (auth_str), "Basic %.*s", base64_len, base64_str);

  ret2 = dpl_dict_add(headers, "Authorization", auth_str, 0);
  if (DPL_SUCCESS != ret2)
    {
      ret = ret2;
      goto end;
    }

  ret = DPL_SUCCESS;

 end:

  return ret;
}
Beispiel #4
0
static dpl_status_t
add_metadata_to_headers(dpl_dict_t *metadata,
                        dpl_dict_t *headers)

{
  int bucket;
  dpl_dict_var_t *var;
  char header[dpl_header_size];
  int ret;

  for (bucket = 0;bucket < metadata->n_buckets;bucket++)
    {
      for (var = metadata->buckets[bucket];var;var = var->prev)
        {
          snprintf(header, sizeof (header), "%s%s", DPL_X_AMZ_META_PREFIX, var->key);

          assert(DPL_VALUE_STRING == var->val->type);
          ret = dpl_dict_add(headers, header,
                             dpl_sbuf_get_str(var->val->string), 0);
          if (DPL_SUCCESS != ret)
            {
              return DPL_FAILURE;
            }
        }
    }

  return DPL_SUCCESS;
}
Beispiel #5
0
dpl_status_t
dpl_req_add_metadatum(dpl_req_t *req,
                      const char *key,
                      const char *value)
{
    return dpl_dict_add(req->metadata, key, value, 0);
}
Beispiel #6
0
END_TEST

static dpl_status_t
send_authenticated_request(const char *username, const char *password, struct request *reqp)
{
  dpl_status_t s;
  dpl_dict_t *prof2;
  char id[41];
  static const char data[] =
    "Carles wolf yr Austin, chambray twee lo-fi iPhone brunch Neutra"
    "slow-carb. Viral";

  prof2 = dpl_dict_dup(profile);
  if (username)
    dpl_assert_int_eq(DPL_SUCCESS, dpl_dict_add(prof2, "access_key", username, 0));
  if (password)
    dpl_assert_int_eq(DPL_SUCCESS, dpl_dict_add(prof2, "secret_key", password, 0));

  /* create an unauthenticated context */
  ctx = dpl_ctx_new_from_dict(prof2);
  dpl_assert_ptr_not_null(ctx);
  dpl_dict_free(prof2);

  s = dpl_gen_random_key(ctx, DPL_STORAGE_CLASS_STANDARD, /*custom*/NULL, id, sizeof(id));
  dpl_assert_int_eq(DPL_SUCCESS, s);

  s = dpl_put_id(ctx,
		"foobucket",
		id,
		/*options*/NULL,
		DPL_FTYPE_REG,
		/*condition*/NULL,
		/*range*/NULL,
		/*metadata*/NULL,
		/*sysmd*/NULL,
		data, sizeof(data)-1);
  if (reqp)
    *reqp = state->request;	/* sample before disconnection */

  dpl_ctx_free(ctx);
  ctx = NULL;

  return s;
}
Beispiel #7
0
END_TEST

/*
 * Test replacing an existing value with dpl_dict_add(
 */
START_TEST(replace_test)
{
  dpl_dict_t *dict;
  int i;
  dpl_status_t r;
  char valbuf[128];
  /* strings courtesy http://hipsteripsum.me/ */
  static const char key0[] = "Sriracha";
  static const char val0[] = "Banksy";
  static const char val0_new[] = "polaroid";
  static const char key1[] = "trust";
  static const char val1[] = "fund";

  dict = dpl_dict_new(13);
  dpl_assert_ptr_not_null(dict);

  /* add the values */
  dpl_dict_add(dict, key0, val0, /* lowered */0);
  dpl_dict_add(dict, key1, val1, /* lowered */0);
  dpl_assert_int_eq(2, dpl_dict_count(dict));

  /* check the values are there */
  dpl_assert_str_eq(dpl_dict_get_value(dict, key0), val0);
  dpl_assert_str_eq(dpl_dict_get_value(dict, key1), val1);

  /* replace one of the values */
  dpl_dict_add(dict, key0, val0_new, /* lowered */0);

  /* check the element count is correct */
  dpl_assert_int_eq(2, dpl_dict_count(dict));

  /* check the new value is there */
  dpl_assert_str_eq(dpl_dict_get_value(dict, key0), val0_new);
  /* check the other key is unaffected */
  dpl_assert_str_eq(dpl_dict_get_value(dict, key1), val1);

  dpl_dict_free(dict);
}
Beispiel #8
0
void
assign_meta_to_dict(dpl_dict_t *dict,
                    char *meta,
                    unsigned long val)
{
        char *buf = NULL;

        buf = tmpstr_printf("%lu", val);
        LOG(LOG_DEBUG, "meta='%s', value='%s'", meta, buf);

        if (DPL_SUCCESS != dpl_dict_add(dict, meta, buf, 1))
                LOG(LOG_ERR, "can't update value '%s' for '%s'", buf, meta);
}
Beispiel #9
0
void
copy_nameless_object_with_new_md()
{
  dpl_async_task_t *atask = NULL;
  dpl_buf_t *buf = NULL;
  dpl_status_t ret;
  dpl_dict_t *metadata = NULL;

  banner("11 - copy nameless object with new metadata");

  metadata = dpl_dict_new(13);
  if (NULL == metadata)
    {
      ret = DPL_ENOMEM;
      exit(1);
    }

  ret = dpl_dict_add(metadata, "bar", "qux", 0);
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "error updating metadatum: %s (%d)\n", dpl_status_str(ret), ret);
      exit(1);
    }

  /* 
   * note: With Dewpoint, it would be possible to copy nameless object into another nameless object.
   * Does it make sense ? for now we copy it into a named object
   */
  atask = (dpl_async_task_t *) dpl_copy_id_async_prepare(ctx,
                                                         NULL,          //no src bucket
                                                         id1,           //the src resource
                                                         NULL,          //no dst bucket
                                                         file1_path,    //dst resource
                                                         NULL,          //no option
                                                         DPL_FTYPE_REG, //regular file
                                                         DPL_COPY_DIRECTIVE_COPY, //rename
                                                         metadata,      //metadata
                                                         NULL,          //no sysmd
                                                         NULL);         //no server side condition
  
  if (NULL == atask)
    {
      fprintf(stderr, "error preparing task\n");
      exit(1);
    }

  atask->cb_func = cb_copy_nameless_object_with_new_md;
  atask->cb_arg = atask;
  
  dpl_task_pool_put(pool, (dpl_task_t *) atask);
}
Beispiel #10
0
void
update_metadata_named_object()
{
  dpl_async_task_t *atask = NULL;
  dpl_status_t ret;
  dpl_option_t option;
  dpl_dict_t *metadata = NULL;

  banner("6 - append metadata to existing named object");

  metadata = dpl_dict_new(13);
  if (NULL == metadata)
    {
      ret = DPL_ENOMEM;
      exit(1);
    }

  ret = dpl_dict_add(metadata, "foo", "bar", 0);
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "error updating metadatum: %s (%d)\n", dpl_status_str(ret), ret);
      exit(1);
    }
  
  option.mask = DPL_OPTION_APPEND_METADATA;

  atask = (dpl_async_task_t *) dpl_put_async_prepare(ctx,
                                                     NULL,          //no bucket
                                                     file3_path,    //the id
                                                     &option,       //option
                                                     DPL_FTYPE_REG, //regular object
                                                     NULL,          //condition
                                                     NULL,          //range
                                                     metadata,      //the metadata
                                                     NULL,          //no sysmd
                                                     NULL);         //object body

  dpl_dict_free(metadata);

  if (NULL == atask)
    {
      fprintf(stderr, "error preparing task\n");
      exit(1);
    }

  atask->cb_func = cb_update_metadata_named_object;
  atask->cb_arg = atask;
  
  dpl_task_pool_put(pool, (dpl_task_t *) atask);
}
Beispiel #11
0
static dpl_status_t
add_source_to_headers(const dpl_req_t *req,
                      dpl_dict_t *headers)
{
  int ret, ret2;
  char buf[1024];
  u_int len = sizeof (buf);
  char *p;
  char src_resource_ue[DPL_URL_LENGTH(strlen(req->src_resource)) + 1];

  //resource
  if ('/' != req->src_resource[0])
    {
      src_resource_ue[0] = '/';
      dpl_url_encode(req->src_resource, src_resource_ue + 1);
    }
  else
    {
      src_resource_ue[0] = '/'; //some servers do not like encoded slash
      dpl_url_encode(req->src_resource + 1, src_resource_ue + 1);
    }

  p = buf;

  DPL_APPEND_STR("/");
  DPL_APPEND_STR(req->src_bucket);
  DPL_APPEND_STR(src_resource_ue);

  //subresource and query params
  if (NULL != req->src_subresource)
    {
      DPL_APPEND_STR("?");
      DPL_APPEND_STR(req->src_subresource);
    }

  DPL_APPEND_CHAR(0);

  ret2 = dpl_dict_add(headers, "x-amz-copy-source", buf, 0);
  if (DPL_SUCCESS != ret2)
    {
      ret = ret2;
      goto end;
    }

  ret = DPL_SUCCESS;

 end:

  return ret;
}
Beispiel #12
0
dpl_status_t
dpl_add_range_to_headers_internal(const dpl_range_t *range,
                                  const char *field,
                                  dpl_dict_t *headers)
{
  int ret;
  char buf[1024];
  int len = sizeof (buf);
  char *p;
  int first = 1;
  char str[128];

  p = buf;

  DPL_APPEND_STR("bytes=");

  if (1 == first)
    first = 0;
  else
    DPL_APPEND_STR(",");
  
  if (DPL_UNDEF == range->start && DPL_UNDEF == range->end)
    return DPL_EINVAL;
  else if (DPL_UNDEF == range->start)
    {
      snprintf(str, sizeof (str), "-%lu", range->end);
      DPL_APPEND_STR(str);
    }
  else if (DPL_UNDEF == range->end)
    {
      snprintf(str, sizeof (str), "%lu-", range->start);
      DPL_APPEND_STR(str);
    }
  else
    {
      snprintf(str, sizeof (str), "%lu-%lu", range->start, range->end);
      DPL_APPEND_STR(str);
    }

  DPL_APPEND_CHAR(0);
  
  ret = dpl_dict_add(headers, field, buf, 0);
  if (DPL_SUCCESS != ret)
    {
      return DPL_FAILURE;
    }

  return DPL_SUCCESS;
}
Beispiel #13
0
static dpl_status_t
add_date_to_headers(dpl_dict_t *headers)
{
  int ret;
  time_t t;
  struct tm tm_buf;
  char date_str[128];

  (void) time(&t);

  ret = strftime(date_str, sizeof (date_str), "%a, %d %b %Y %H:%M:%S GMT", gmtime_r(&t, &tm_buf));
  if (ret == 0)
    return DPL_FAILURE;
  else
    return dpl_dict_add(headers, "Date", date_str, 0);
}
Beispiel #14
0
void
copy_named_object_with_new_md()
{
  dpl_async_task_t *atask = NULL;
  dpl_buf_t *buf = NULL;
  dpl_status_t ret;
  dpl_dict_t *metadata = NULL;

  banner("12 - copy named object with new metadata");

  metadata = dpl_dict_new(13);
  if (NULL == metadata)
    {
      ret = DPL_ENOMEM;
      exit(1);
    }

  ret = dpl_dict_add(metadata, "qux", "baz", 0);
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "error updating metadatum: %s (%d)\n", dpl_status_str(ret), ret);
      exit(1);
    }

  atask = (dpl_async_task_t *) dpl_copy_async_prepare(ctx,
                                                      NULL,          //no src bucket
                                                      file1_path,    //the src resource
                                                      NULL,          //no dst bucket
                                                      file4_path,    //dst resource
                                                      NULL,          //no option
                                                      DPL_FTYPE_REG, //regular file
                                                      DPL_COPY_DIRECTIVE_COPY, //rename
                                                      metadata,      //metadata
                                                      NULL,          //no sysmd
                                                      NULL);         //no server side condition
  
  if (NULL == atask)
    {
      fprintf(stderr, "error preparing task\n");
      exit(1);
    }

  atask->cb_func = cb_copy_named_object_with_new_md;
  atask->cb_arg = atask;
  
  dpl_task_pool_put(pool, (dpl_task_t *) atask);
}
Beispiel #15
0
/**
 * parse a string of the form query_params1=value1;query_params2=value2...
 *
 * @param query_params
 *
 * @return
 */
dpl_dict_t *
dpl_parse_query_params(char *query_params)
{
  char *saveptr = NULL;
  char *str, *tok, *p;
  int ret;
  dpl_dict_t *dict;
  char *nquery_params;

  nquery_params = strdup(query_params);
  if (NULL == nquery_params)
    return NULL;

  dict = dpl_dict_new(13);
  if (NULL == dict)
    {
      free(nquery_params);
      return NULL;
    }

  for (str = query_params;;str = NULL)
    {
      tok = strtok_r(str, ";", &saveptr);
      if (NULL == tok)
        break ;

      DPRINTF("tok=%s\n", tok);

      p = index(tok, '=');
      if (NULL == p)
        p = "";
      else
        *p++ = 0;

      ret = dpl_dict_add(dict, tok, p, 0);
      if (DPL_SUCCESS != ret)
        {
          dpl_dict_free(dict);
          free(nquery_params);
          return NULL;
        }
    }

  free(nquery_params);

  return dict;
}
Beispiel #16
0
/**
 * parse a string of the form metadata1=value1;metadata2=value2...
 *
 * @param metadata
 *
 * @return
 */
dpl_dict_t *
dpl_parse_metadata(char *metadata)
{
  char *saveptr = NULL;
  char *str, *tok, *p;
  int ret;
  dpl_dict_t *dict;
  char *nmetadata;

  nmetadata = strdup(metadata);
  if (NULL == nmetadata)
    return NULL;

  dict = dpl_dict_new(13);
  if (NULL == dict)
    {
      free(nmetadata);
      return NULL;
    }

  for (str = metadata;;str = NULL)
    {
      tok = strtok_r(str, ";", &saveptr);
      if (NULL == tok)
        break ;

      DPRINTF("tok=%s\n", tok);

      p = index(tok, '=');
      if (NULL == p)
        p = "";
      else
        *p++ = 0;

      ret = dpl_dict_add(dict, tok, p, 0);
      if (DPL_SUCCESS != ret)
        {
          dpl_dict_free(dict);
          free(nmetadata);
          return NULL;
        }
    }

  free(nmetadata);

  return dict;
}
Beispiel #17
0
dpl_status_t
dpl_s3_add_authorization_v2_to_headers(const dpl_req_t *req,
                                       dpl_dict_t *headers,
                                       const dpl_dict_t UNUSED *query_params,
                                       struct tm UNUSED *tm)
{
  int ret;
  const char *method = dpl_method_str(req->method);
  char resource_ue[DPL_URL_LENGTH(strlen(req->resource)) + 1];
  char sign_str[1024];
  u_int sign_len;
  char hmac_str[1024];
  u_int hmac_len;
  char base64_str[1024];
  u_int base64_len;
  char auth_str[1024];
  char  *date_str = NULL;

  //resource
  if ('/' != req->resource[0]) {
    resource_ue[0] = '/';
    dpl_url_encode_no_slashes(req->resource, resource_ue + 1);
  } else
    dpl_url_encode_no_slashes(req->resource, resource_ue);

  date_str = dpl_dict_get_value(headers, "x-amz-date");
  if (date_str == NULL)
    date_str = dpl_dict_get_value(headers, "Date");

  ret = dpl_s3_make_signature_v2(req->ctx, method, req->bucket, resource_ue, req->subresource,
                                 date_str, headers,
                                 sign_str, sizeof (sign_str), &sign_len);
  if (DPL_SUCCESS != ret)
    return DPL_FAILURE;

  /* DPL_TRACE(req->ctx, DPL_TRACE_REQ, "stringtosign=%.*s", sign_len, sign_str); */

  hmac_len = dpl_hmac_sha1(req->ctx->secret_key, strlen(req->ctx->secret_key), sign_str, sign_len, hmac_str);

  base64_len = dpl_base64_encode((const u_char *) hmac_str, hmac_len, (u_char *) base64_str);

  snprintf(auth_str, sizeof (auth_str), "AWS %s:%.*s", req->ctx->access_key, base64_len, base64_str);

  return dpl_dict_add(headers, "Authorization", auth_str, 0);
}
Beispiel #18
0
static int
cb_ntinydb(const char *key_ptr,
           int key_len,
           void *cb_arg)
{
  struct mdparse_data *arg = (struct mdparse_data *) cb_arg;
  int ret, ret2;
  const char *value_returned = NULL;
  int value_len_returned;
  char *key_str;
  char *value_str;

  DPRINTF("%.*s\n", key_len, key_ptr);
  
  key_str = alloca(key_len + 1);
  memcpy(key_str, key_ptr, key_len);
  key_str[key_len] = 0;

  ret2 = dpl_ntinydb_get(arg->orig, arg->orig_len, key_str, &value_returned, &value_len_returned);
  if (DPL_SUCCESS != ret2)
    {
      ret = -1;
      goto end;
    }

  DPRINTF("%.*s\n", value_len_returned, value_returned);

  value_str = alloca(value_len_returned + 1);
  memcpy(value_str, value_returned, value_len_returned);
  value_str[value_len_returned] = 0;
  
  ret2 = dpl_dict_add(arg->metadata, key_str, value_str, 0);
  if (DPL_SUCCESS != ret2)
    {
      ret = -1;
      goto end;
    }

  ret = 0;
  
 end:

  return ret;
}
Beispiel #19
0
static dpl_status_t
cb_httpreply_header(void *cb_arg,
                    const char *header,
                    const char *value)
{
  struct httreply_conven *hc = (struct httreply_conven *) cb_arg;
  int ret;

  if (NULL == hc->headers)
    {
      hc->headers = dpl_dict_new(13);
      if (NULL == hc->headers)
        return DPL_ENOMEM;
    }

  ret = dpl_dict_add(hc->headers, header, value, 1);
  if (DPL_SUCCESS != ret)
    return DPL_ENOMEM;

  return DPL_SUCCESS;
}
Beispiel #20
0
void
update_metadata()
{
  dpl_async_task_t *atask = NULL;
  dpl_buf_t *buf = NULL;
  dpl_status_t ret;

  fprintf(stderr, "setting MD only\n");

  ret = dpl_dict_add(metadata, "foo", "bar2", 0);
  if (DPL_SUCCESS != ret)
    {
      fprintf(stderr, "error updating metadatum: %s (%d)\n", dpl_status_str(ret), ret);
      exit(1);
    }

  atask = (dpl_async_task_t *) dpl_copy_async_prepare(ctx,           //the context
                                                      NULL,          //no src bucket
                                                      new_path,      //the key
                                                      NULL,          //no dst bucket
                                                      new_path,      //the same key
                                                      NULL,          //no option
                                                      DPL_FTYPE_REG, //object type
                                                      DPL_COPY_DIRECTIVE_METADATA_REPLACE,  //tell server to replace metadata
                                                      metadata,      //the updated metadata
                                                      NULL,          //no sysmd
                                                      NULL);         //no condition
  
  if (NULL == atask)
    {
      fprintf(stderr, "error preparing task\n");
      exit(1);
    }

  atask->cb_func = cb_update_metadata;
  atask->cb_arg = atask;
  
  dpl_task_pool_put(pool, (dpl_task_t *) atask);
}
Beispiel #21
0
static dpl_status_t
add_payload_signature_to_headers(const dpl_req_t *req, dpl_dict_t *headers)
{
  uint8_t               digest[SHA256_DIGEST_LENGTH];
  char                  digest_hex[DPL_HEX_LENGTH(sizeof digest) + 1];
  int                   i;
  dpl_dict_var_t        *var;

  var = dpl_dict_get(headers, "x-amz-content-sha256");
  if (var != NULL)
    return DPL_SUCCESS;

  if (req->data_enabled)
    dpl_sha256((uint8_t *) req->data_buf, req->data_len, digest);
  else
    dpl_sha256((uint8_t *) "", 0, digest);

  for (i = 0; i < sizeof digest; i++)
    sprintf(digest_hex + 2 * i, "%02x", (u_char) digest[i]);

  return dpl_dict_add(headers, "x-amz-content-sha256", digest_hex, 0);
}
Beispiel #22
0
END_TEST

/*
 * Use the dict with long key strings; tests
 * some corner cases e.g. in the hash function.
 */
START_TEST(long_key_test)
{
#define N 512
  dpl_dict_t *dict;
  int i;
  int j;
  const char *act;
  const char *exp;
  char keybuf[1024];
  char valbuf[1024];

  dict = dpl_dict_new(13);
  dpl_assert_ptr_not_null(dict);

  for (i = 0 ; i < N ; i++)
    {
      dpl_dict_add(dict, make_key(i, keybuf, sizeof(keybuf)),
			 make_value(i, valbuf, sizeof(valbuf)),
			 /* lowered */0);
    }
  dpl_assert_int_eq(N, dpl_dict_count(dict));

  for (i = 0 ; i < N ; i++)
    {
      act = dpl_dict_get_value(dict, make_key(i, keybuf, sizeof(keybuf)));
      exp = make_value(i, valbuf, sizeof(valbuf));
      dpl_assert_str_eq(act, exp);
    }

  dpl_dict_free(dict);
#undef N
}
Beispiel #23
0
/* Add RFC2617 Basic authorization to a request's headers */
dpl_status_t
dpl_add_basic_authorization_to_headers(const dpl_req_t *req,
				       dpl_dict_t *headers)
{
  int ret, ret2;
  char basic_str[1024];
  int basic_len;
  char base64_str[1024];
  int base64_len;
  char auth_str[1024];

  /* No username or no password in the profile means
   * we silently don't send the header */
  if (NULL == req->ctx->access_key ||
      NULL == req->ctx->secret_key)
    return DPL_SUCCESS;

  snprintf(basic_str, sizeof (basic_str), "%s:%s", req->ctx->access_key, req->ctx->secret_key);
  basic_len = strlen(basic_str);

  base64_len = dpl_base64_encode((const u_char *) basic_str, basic_len, (u_char *) base64_str);

  snprintf(auth_str, sizeof (auth_str), "Basic %.*s", base64_len, base64_str);

  ret2 = dpl_dict_add(headers, "Authorization", auth_str, 0);
  if (DPL_SUCCESS != ret2)
    {
      ret = ret2;
      goto end;
    }

  ret = DPL_SUCCESS;

 end:

  return ret;
}
Beispiel #24
0
dpl_status_t
dpl_add_host_to_headers(dpl_req_t *req,
                        dpl_dict_t *headers)
{
  dpl_status_t ret;

  if (NULL != req->host)
    {
      char buf[256];

      if (strcmp("80", req->port))
        snprintf(buf, sizeof (buf), "%s:%s", req->host, req->port);
      else
        snprintf(buf, sizeof (buf), "%s", req->host);

      ret = dpl_dict_add(headers, "Host", buf, 0);
      if (DPL_SUCCESS != ret)
        {
          return ret;
        }
    }

  return DPL_SUCCESS;
}
Beispiel #25
0
static void
setup(void)
{
  int r;

  unsetenv("DPLDIR");
  unsetenv("DPLPROFILE");
  dpl_init();

  r = toyserver_start(NULL, &state);
  dpl_assert_int_eq(r, 0);

  profile = dpl_dict_new(13);
  dpl_assert_ptr_not_null(profile);
  dpl_assert_int_eq(DPL_SUCCESS, dpl_dict_add(profile, "host", toyserver_addrlist(state), 0));
  dpl_assert_int_eq(DPL_SUCCESS, dpl_dict_add(profile, "backend", "sproxyd", 0));
  dpl_assert_int_eq(DPL_SUCCESS, dpl_dict_add(profile, "base_path", "/proxy/chord", 0));
  dpl_assert_int_eq(DPL_SUCCESS, dpl_dict_add(profile, "droplet_dir", "/never/seen", 0));
  dpl_assert_int_eq(DPL_SUCCESS, dpl_dict_add(profile, "profile_name", "viral", 0));
  /* need this to disable the event log, otherwise the droplet_dir needs to exist */
  dpl_assert_int_eq(DPL_SUCCESS, dpl_dict_add(profile, "pricing_dir", "", 0));
}
Beispiel #26
0
dpl_status_t
dpl_s3_get_authorization_v4_params(const dpl_req_t *req, dpl_dict_t *query_params,
                                   struct tm *i_tm)
{
  dpl_status_t  ret;
  char          date_str[32] = "";
  char          signature[DPL_HEX_LENGTH(SHA256_DIGEST_LENGTH) + 1];
  struct tm     tm;

  ret = get_current_utc_date(&tm, i_tm, date_str, sizeof(date_str));
  if (ret != DPL_SUCCESS)
    return ret;

  ret = dpl_dict_add(query_params, "X-Amz-Algorithm", "AWS4-HMAC-SHA256", 0);
  if (ret != DPL_SUCCESS)
    return DPL_FAILURE;

  {
    int         ret2;
    char        credentials[128], date_buf[9];
    char        credentials_ue[DPL_URL_LENGTH(sizeof(credentials)) + 1];

    ret2 = strftime(date_buf, sizeof(date_buf), "%Y%m%d", &tm);
    if (ret2 == 0)
      return DPL_FAILURE;

    snprintf(credentials, sizeof(credentials), "%s/%s/%s/s3/aws4_request",
             req->ctx->access_key, date_buf, req->ctx->aws_region);

    dpl_url_encode(credentials, credentials_ue);

    ret = dpl_dict_add(query_params, "X-Amz-Credential", credentials_ue, 0);
    if (ret != DPL_SUCCESS)
      return DPL_FAILURE;
  }

  ret = dpl_dict_add(query_params, "X-Amz-Date", date_str, 0);
  if (ret != DPL_SUCCESS)
    return DPL_FAILURE;

  {
    char        expires_str[128];

    snprintf(expires_str, sizeof(expires_str), "%ld", req->expires - time(0));

    ret = dpl_dict_add(query_params, "X-Amz-Expires", expires_str, 0);
    if (ret != DPL_SUCCESS)
      return DPL_FAILURE;
  }

  ret = dpl_dict_add(query_params, "X-Amz-SignedHeaders", "host", 0);
  if (ret != DPL_SUCCESS)
    return DPL_FAILURE;

  ret = dpl_s3_insert_signature_v4_params(req, query_params,
                                          &tm, date_str, signature);
  if (ret != DPL_SUCCESS)
    return DPL_FAILURE;

  return dpl_dict_add(query_params, "X-Amz-Signature", signature, 0);
}
Beispiel #27
0
dpl_status_t
dpl_s3_add_authorization_v4_to_headers(const dpl_req_t *req,
                                       dpl_dict_t *headers,
                                       const dpl_dict_t *query_params,
                                       struct tm *i_tm)
{
  int           item;
  dpl_status_t  ret;
  char          canonical_request[4096] = "";
  char          sign_request[1024] = "";
  char          signature[DPL_HEX_LENGTH(SHA256_DIGEST_LENGTH) + 1];
  char          authorization[1024] = "";
  char          date_str[32] = "";
  dpl_vec_t     *canonical_headers;
  dpl_vec_t     *canonical_params;
  struct tm     tm;

  ret = add_payload_signature_to_headers(req, headers);
  if (ret != DPL_SUCCESS)
    return ret;

  ret = get_current_utc_date(&tm, i_tm, date_str, sizeof(date_str));
  if (ret != DPL_SUCCESS)
    return ret;

  ret = dpl_dict_add(headers, "x-amz-date", date_str, 0);
  if (ret != DPL_SUCCESS)
    return ret;

  canonical_headers = get_canonical_headers(headers);
  if (canonical_headers == NULL)
    return DPL_FAILURE;

  canonical_params = get_canonical_params(req->subresource, query_params, 1);
  if (canonical_params == NULL) {
    dpl_vec_free(canonical_headers);
    return DPL_FAILURE;
  }

  ret = create_canonical_request(req, headers,
                                 canonical_headers, canonical_params,
                                 canonical_request, sizeof(canonical_request));

  if (ret == DPL_SUCCESS) {
    DPRINTF("Canonical request:\n%s\n", canonical_request);
    ret = create_sign_request(req, canonical_request, &tm, date_str,
                              sign_request, sizeof(sign_request));
  }

  if (ret == DPL_SUCCESS) {
    DPRINTF("Signing request:\n%s\n", sign_request);
    ret = create_signature(req, &tm, sign_request, signature);
  }

  if (ret == DPL_SUCCESS) {
    DPRINTF("Signature: %s\n", signature);
    ret = create_authorization(req, &tm, canonical_headers, signature,
                               authorization, sizeof(authorization));
  }

  if (ret == DPL_SUCCESS)
    ret = dpl_dict_add(headers, "Authorization", authorization, 0);

  for (item = 0; item < canonical_params->n_items; item++) {
    dpl_dict_var_t    *param = (dpl_dict_var_t *) dpl_vec_get(canonical_params, item);
    free(param->key);
    dpl_dict_var_free(param);
  }
  dpl_vec_free(canonical_params);
  dpl_vec_free(canonical_headers);

  return ret;
}
Beispiel #28
0
dpl_status_t
dpl_add_condition_to_headers(const dpl_condition_t *cond,
                             dpl_dict_t *headers)
{
  int ret;
  char *header;
  int i;

  for (i = 0;i < cond->n_conds;i++)
    {
      const dpl_condition_one_t *condition = &cond->conds[i];

      if (condition->type == DPL_CONDITION_IF_MODIFIED_SINCE ||
          condition->type == DPL_CONDITION_IF_UNMODIFIED_SINCE)
        {
          char date_str[128];
          struct tm tm_buf;
          
          ret = strftime(date_str, sizeof (date_str), "%a, %d %b %Y %H:%M:%S GMT", gmtime_r(&condition->time, &tm_buf));
          if (0 == ret)
            return DPL_FAILURE;
          
          if (condition->type == DPL_CONDITION_IF_MODIFIED_SINCE)
            {
              header = "If-Modified-Since";
              ret = dpl_dict_add(headers, header, date_str, 0);
              if (DPL_SUCCESS != ret)
                {
                  return DPL_FAILURE;
                }
            }
          
          if (condition->type == DPL_CONDITION_IF_UNMODIFIED_SINCE)
            {
              header = "If-Unmodified-Since";
              ret = dpl_dict_add(headers, header, date_str, 0);
              if (DPL_SUCCESS != ret)
                {
                  return DPL_FAILURE;
                }
            }
        }
      
      if (condition->type == DPL_CONDITION_IF_MATCH)
        {
          header = "If-Match";
          ret = dpl_dict_add(headers, header, condition->etag, 0);
          if (DPL_SUCCESS != ret)
            {
              return DPL_FAILURE;
            }
        }
      
      if (condition->type == DPL_CONDITION_IF_NONE_MATCH)
        {
          header = "If-None-Match";
          ret = dpl_dict_add(headers, header, condition->etag, 0);
          if (DPL_SUCCESS != ret)
            {
              return DPL_FAILURE;
            }
        }
    }

  return DPL_SUCCESS;
}
Beispiel #29
0
static dpl_status_t
add_condition_to_headers(const dpl_condition_one_t *condition,
                         dpl_dict_t *headers,
                         int copy_source)
{
  int ret;
  char *header;

  if (condition->type == DPL_CONDITION_IF_MODIFIED_SINCE ||
      condition->type == DPL_CONDITION_IF_UNMODIFIED_SINCE)
    {
      char date_str[128];
      struct tm tm_buf;

      ret = strftime(date_str, sizeof (date_str), "%a, %d %b %Y %H:%M:%S GMT", gmtime_r(&condition->time, &tm_buf));
      if (0 == ret)
        return DPL_FAILURE;

      if (condition->type == DPL_CONDITION_IF_MODIFIED_SINCE)
        {
          if (1 == copy_source)
            header = "x-amz-copy-source-if-modified-since";
          else
            header = "If-Modified-Since";
          ret = dpl_dict_add(headers, header, date_str, 0);
          if (DPL_SUCCESS != ret)
            {
              return DPL_FAILURE;
            }
        }

      if (condition->type == DPL_CONDITION_IF_UNMODIFIED_SINCE)
        {
          if (1 == copy_source)
            header = "x-amz-copy-source-if-unmodified-since";
          else
            header = "If-Unmodified-Since";
          ret = dpl_dict_add(headers, header, date_str, 0);
          if (DPL_SUCCESS != ret)
            {
              return DPL_FAILURE;
            }
        }
    }

  if (condition->type == DPL_CONDITION_IF_MATCH)
    {
      if (1 == copy_source)
        header = "x-amz-copy-source-if-match";
      else
        header = "If-Match";
      ret = dpl_dict_add(headers, header, condition->etag, 0);
      if (DPL_SUCCESS != ret)
        {
          return DPL_FAILURE;
        }
    }

  if (condition->type == DPL_CONDITION_IF_NONE_MATCH)
    {
      if (1 == copy_source)
        header = "x-amz-copy-source-if-none-match";
      else
        header = "If-None-Match";
      ret = dpl_dict_add(headers, header, condition->etag, 0);
      if (DPL_SUCCESS != ret)
        {
          return DPL_FAILURE;
        }
    }

  return DPL_SUCCESS;
}
Beispiel #30
0
/**
 * build headers from request
 *
 * @param req
 * @param headersp
 *
 * @return
 */
dpl_status_t
dpl_s3_req_build(const dpl_req_t *req,
                 dpl_s3_req_mask_t req_mask,
                 dpl_dict_t **headersp)
{
  dpl_dict_t *headers = NULL;
  int ret, ret2;
  const char *method = dpl_method_str(req->method);
  char resource_ue[DPL_URL_LENGTH(strlen(req->resource) + (req->subresource ? strlen(req->subresource) : 0)) + 1];

  DPL_TRACE(req->ctx, DPL_TRACE_REQ, "req_build method=%s bucket=%s resource=%s subresource=%s", method, req->bucket, req->resource, req->subresource);

  //resource
  if ('/' != req->resource[0])
    {
      resource_ue[0] = '/';
      dpl_url_encode(req->resource, resource_ue + 1);
    }
  else
    {
      resource_ue[0] = '/'; //some servers do not like encoded slash
      dpl_url_encode(req->resource + 1, resource_ue + 1);
    }

  // Append subresource
  if (req->subresource)
    {
      dpl_url_encode("?", resource_ue + strlen(resource_ue));
      dpl_url_encode(req->subresource, resource_ue + strlen(resource_ue));
    }

  headers = dpl_dict_new(13);
  if (NULL == headers)
    {
      ret = DPL_ENOMEM;
      goto end;
    }

  /*
   * per method headers
   */
  if (DPL_METHOD_GET == req->method ||
      DPL_METHOD_HEAD == req->method)
    {
      if (req->range_enabled)
        {
          ret2 = dpl_add_range_to_headers(&req->range, headers);
          if (DPL_SUCCESS != ret2)
            {
              ret = ret2;
              goto end;
            }
        }

      ret2 = add_conditions_to_headers(&req->condition, headers, 0);
      if (DPL_SUCCESS != ret2)
        {
          ret = ret2;
          goto end;
        }
    }
  else if (DPL_METHOD_PUT == req->method ||
           DPL_METHOD_POST == req->method)
    {
      char buf[64];

      if (NULL != req->cache_control)
        {
          ret2 = dpl_dict_add(headers, "Cache-Control", req->cache_control, 0);
          if (DPL_SUCCESS != ret2)
            {
              ret = ret2;
              goto end;
            }
        }

      if (NULL != req->content_disposition)
        {
          ret2 = dpl_dict_add(headers, "Content-Disposition", req->content_disposition, 0);
          if (DPL_SUCCESS != ret2)
            {
              ret = ret2;
              goto end;
            }
        }

      if (NULL != req->content_encoding)
        {
          ret2 = dpl_dict_add(headers, "Content-Encoding", req->content_encoding, 0);
          if (DPL_SUCCESS != ret2)
            {
              ret = ret2;
              goto end;
            }
        }

      if (req->behavior_flags & DPL_BEHAVIOR_MD5)
        {
          MD5_CTX ctx;
          u_char digest[MD5_DIGEST_LENGTH];
          char b64_digest[DPL_BASE64_LENGTH(MD5_DIGEST_LENGTH) + 1];
          u_int b64_digest_len;

          if (!req->data_enabled)
            {
              ret = DPL_EINVAL;
              goto end;
            }

          MD5_Init(&ctx);
          MD5_Update(&ctx, req->data_buf, req->data_len);
          MD5_Final(digest, &ctx);

          b64_digest_len = dpl_base64_encode(digest, MD5_DIGEST_LENGTH, (u_char *) b64_digest);
          b64_digest[b64_digest_len] = 0;

          ret2 = dpl_dict_add(headers, "Content-MD5", b64_digest, 0);
          if (DPL_SUCCESS != ret2)
            {
              ret = ret2;
              goto end;
            }
        }

      if (req->data_enabled)
        {
          snprintf(buf, sizeof (buf), "%u", req->data_len);
          ret2 = dpl_dict_add(headers, "Content-Length", buf, 0);
          if (DPL_SUCCESS != ret2)
            {
              ret = DPL_ENOMEM;
              goto end;
            }
        }

      if (NULL != req->content_type)
        {
          ret2 = dpl_dict_add(headers, "Content-Type", req->content_type, 0);
          if (DPL_SUCCESS != ret2)
            {
              ret = ret2;
              goto end;
            }
        }

      if (req->behavior_flags & DPL_BEHAVIOR_EXPECT)
        {
          ret2 = dpl_dict_add(headers, "Expect", "100-continue", 0);
          if (DPL_SUCCESS != ret2)
            {
              ret = DPL_ENOMEM;
              goto end;
            }
        }

      if (DPL_CANNED_ACL_UNDEF != req->canned_acl)
        {
          char *str;

          str = dpl_canned_acl_str(req->canned_acl);
          if (NULL == str)
            {
              ret = DPL_FAILURE;
              goto end;
            }

          ret2 = dpl_dict_add(headers, "x-amz-acl", str, 0);
          if (DPL_SUCCESS != ret2)
            {
              ret = DPL_ENOMEM;
              goto end;
            }
        }

      ret2 = add_metadata_to_headers(req->metadata, headers);
      if (DPL_SUCCESS != ret2)
        {
          ret = ret2;
          goto end;
        }

      if (DPL_STORAGE_CLASS_UNDEF != req->storage_class)
        {
          char *str;

          str = dpl_storage_class_str(req->storage_class);
          if (NULL == str)
            {
              ret = DPL_FAILURE;
              goto end;
            }

          ret2 = dpl_dict_add(headers, "x-amz-storage-class", str, 0);
          if (DPL_SUCCESS != ret2)
            {
              ret = DPL_ENOMEM;
              goto end;
            }
        }

      /*
       * copy
       */
      if (req_mask & DPL_S3_REQ_COPY)
        {
          ret2 = add_source_to_headers(req, headers);
          if (DPL_SUCCESS != ret2)
            {
              ret = ret2;
              goto end;
            }

          if (DPL_COPY_DIRECTIVE_UNDEF != req->copy_directive)
            {
              char *str;

              switch (req->copy_directive)
                {
                case DPL_COPY_DIRECTIVE_UNDEF:
                case DPL_COPY_DIRECTIVE_COPY:
                case DPL_COPY_DIRECTIVE_LINK:
                case DPL_COPY_DIRECTIVE_SYMLINK:
                case DPL_COPY_DIRECTIVE_MOVE:
                case DPL_COPY_DIRECTIVE_MKDENT:
                case DPL_COPY_DIRECTIVE_RMDENT:
                case DPL_COPY_DIRECTIVE_MVDENT:
                  ret = DPL_ENOTSUPP;
                  goto end;
                case DPL_COPY_DIRECTIVE_METADATA_REPLACE:
                  str = "REPLACE";
                  break ;
                }

              ret2 = dpl_dict_add(headers, "x-amz-metadata-directive", str, 0);
              if (DPL_SUCCESS != ret2)
                {
                  ret = DPL_ENOMEM;
                  goto end;
                }
            }

          ret2 = add_conditions_to_headers(&req->copy_source_condition, headers, 1);
          if (DPL_SUCCESS != ret2)
            {
              ret = ret2;
              goto end;
            }
        }
    }
  else if (DPL_METHOD_DELETE == req->method)
    {
      //XXX todo x-amz-mfa
    }
  else
    {
      ret = DPL_EINVAL;
      goto end;
    }

  /*
   * common headers
   */
  if (req->behavior_flags & DPL_BEHAVIOR_KEEP_ALIVE)
    {
      ret2 = dpl_dict_add(headers, "Connection", "Keep-Alive", 0);
      if (DPL_SUCCESS != ret2)
        {
          ret = DPL_ENOMEM;
          goto end;
        }
    }

  ret2 = add_date_to_headers(headers);
  if (DPL_SUCCESS != ret2)
    {
      ret = ret2;
      goto end;
    }

  if (NULL != headersp)
    {
      *headersp = headers;
      headers = NULL; //consume it
    }

  ret = DPL_SUCCESS;

 end:

  if (NULL != headers)
    dpl_dict_free(headers);

  return ret;
}