Beispiel #1
0
int cloudfs_connect(char *username, char *password, char *authurl, int use_snet)
{
  static struct {
    char username[MAX_HEADER_SIZE], password[MAX_HEADER_SIZE],
         authurl[MAX_URL_SIZE], use_snet;
  } reconnect_args;

  long response = -1;
  static int initialized = 0;

  if (!initialized)
  {
    LIBXML_TEST_VERSION
    init_locks();
    curl_global_init(CURL_GLOBAL_ALL);
    strncpy(reconnect_args.username, username, sizeof(reconnect_args.username));
    strncpy(reconnect_args.password, password, sizeof(reconnect_args.password));
    strncpy(reconnect_args.authurl, authurl, sizeof(reconnect_args.authurl));
    reconnect_args.use_snet = use_snet;
    initialized = 1;
  }
  else
  {
    username = reconnect_args.username;
    password = reconnect_args.password;
    authurl = reconnect_args.authurl;
    use_snet = reconnect_args.use_snet;
  }

  
  pthread_mutex_lock(&pool_mut);
  debugf("Authenticating...");
  storage_token[0] = storage_url[0] = '\0';
  curl_slist *headers = NULL;
  add_header(&headers, "X-Auth-User", username);
  add_header(&headers, "X-Auth-Key", password);
  CURL *curl = curl_easy_init();
  curl_easy_setopt(curl, CURLOPT_VERBOSE, debug);
  curl_easy_setopt(curl, CURLOPT_URL, authurl);
  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
  curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, &header_dispatch);
  curl_easy_setopt(curl, CURLOPT_USERAGENT, USER_AGENT);
  curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
  curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
  curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
  curl_easy_perform(curl);
  curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
  curl_slist_free_all(headers);
  curl_easy_cleanup(curl);
  if (use_snet && storage_url[0])
    rewrite_url_snet(storage_url);
  pthread_mutex_unlock(&pool_mut);
  return (response >= 200 && response < 300 && storage_token[0] && storage_url[0]);
}
Beispiel #2
0
int cloudfs_connect()
{
  long response = -1;
  curl_slist *headers = NULL;
  CURL *curl = curl_easy_init();
  char postdata[8192] = "";
  xmlNode *top_node = NULL, *service_node = NULL, *endpoint_node = NULL;
  xmlParserCtxtPtr xmlctx = NULL;

  if(reconnect_args.token[0] != '\0' && reconnect_args.endpoint[0] != '\0') {
    strncpy(storage_token, reconnect_args.token, sizeof(storage_token));
    strncpy(storage_url, reconnect_args.endpoint, sizeof(storage_url));
    return 1;
  }

  pthread_mutex_lock(&pool_mut);

  storage_token[0] = storage_url[0] = '\0';

  if (reconnect_args.auth_version == 2)
  {
    if (reconnect_args.username[0] && reconnect_args.tenant[0] && reconnect_args.password[0])
    {
      snprintf(postdata, sizeof(postdata), "<?xml version=\"1.0\" encoding"
          "=\"UTF-8\"?><auth xmlns=\"http://docs.openstack.org/identity/ap"
          "i/v2.0\" tenantName=\"%s\"><passwordCredentials username=\"%s\""
          " password=\"%s\"/></auth>", reconnect_args.tenant,
          reconnect_args.username, reconnect_args.password);
    }
    else if (reconnect_args.username[0] && reconnect_args.password[0])
    {
      snprintf(postdata, sizeof(postdata), "<?xml version=\"1.0\" encoding"
          "=\"UTF-8\"?><auth><apiKeyCredentials xmlns=\"http://docs.racksp"
          "ace.com/identity/api/ext/RAX-KSKEY/v1.0\" username=\"%s\" apiKe"
          "y=\"%s\"/></auth>", reconnect_args.username, reconnect_args.password);
    }
    else
    {
      debugf("Unable to determine auth scheme.");
      abort();
    }
    debugf("%s", postdata);

    add_header(&headers, "Content-Type", "application/xml");
    add_header(&headers, "Accept", "application/xml");

    curl_easy_setopt(curl, CURLOPT_POST, 1);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postdata);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(postdata));

    xmlctx = xmlCreatePushParserCtxt(NULL, NULL, "", 0, NULL);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, xmlctx);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &xml_dispatch);
  }
  else
  {
    add_header(&headers, "X-Auth-User", reconnect_args.username);
    add_header(&headers, "X-Auth-Key", reconnect_args.password);
    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, &header_dispatch);
  }

  curl_easy_setopt(curl, CURLOPT_VERBOSE, debug);
  curl_easy_setopt(curl, CURLOPT_URL, reconnect_args.authurl);
  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
  curl_easy_setopt(curl, CURLOPT_USERAGENT, USER_AGENT);
  curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, verify_ssl);
  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, verify_ssl);
  curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
  curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
  curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 1);

  debugf("Sending authentication request.");
  curl_easy_perform(curl);
  curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
  curl_slist_free_all(headers);
  curl_easy_cleanup(curl);

  if (reconnect_args.auth_version == 2)
  {
    xmlParseChunk(xmlctx, "", 0, 1);
    if (xmlctx->wellFormed && response >= 200 && response < 300)
    {
      xmlXPathContextPtr xpctx = xmlXPathNewContext(xmlctx->myDoc);
      xmlXPathRegisterNs(xpctx, "id", "http://docs.openstack.org/identity/api/v2.0");
      xmlXPathObjectPtr obj;

      /* Determine default region if not configured */
      if (!reconnect_args.region[0])
      {
        obj = xmlXPathEval("/id:access/id:user", xpctx);
        if (obj && obj->nodesetval && obj->nodesetval->nodeNr > 0)
        {
          xmlChar *default_region = xmlGetProp(obj->nodesetval->nodeTab[0], "defaultRegion");
          if (default_region && *default_region)
          {
            strncpy(reconnect_args.region, default_region, sizeof(reconnect_args.region));
            xmlFree(default_region);
          }
        }
        xmlXPathFreeNodeSetList(obj);
      }
      debugf("Using region: %s", reconnect_args.region);

      if (reconnect_args.region[0])
      {
        char path[1024];
        snprintf(path, sizeof(path), "/id:access/id:serviceCatalog/id:service"
            "[@type='object-store']/id:endpoint[@region='%s']",
            reconnect_args.region);
        obj = xmlXPathEval(path, xpctx);
      }
      else
        obj = xmlXPathEval("/id:access/id:serviceCatalog/id:service"
            "[@type='object-store']/id:endpoint", xpctx);
      if (obj->nodesetval && obj->nodesetval->nodeNr > 0)
      {
        xmlChar *url;
        if (reconnect_args.use_snet)
          url = xmlGetProp(obj->nodesetval->nodeTab[0], "internalURL");
        else
          url = xmlGetProp(obj->nodesetval->nodeTab[0], "publicURL");
        strncpy(storage_url, url, sizeof(storage_url));
        xmlFree(url);
      }
      else
        debugf("Unable to find endpoint");
      xmlXPathFreeNodeSetList(obj);

      obj = xmlXPathEval("/id:access/id:token", xpctx);
      if (obj->nodesetval && obj->nodesetval->nodeNr > 0)
      {
        xmlChar *token_id = xmlGetProp(obj->nodesetval->nodeTab[0], "id");
        strncpy(storage_token, token_id, sizeof(storage_token));
        xmlFree(token_id);
      }
      xmlXPathFreeNodeSetList(obj);
      xmlXPathFreeContext(xpctx);
      debugf("storage_url: %s", storage_url);
      debugf("storage_token: %s", storage_token);
    }
    xmlFreeParserCtxt(xmlctx);
  }
  else if (reconnect_args.use_snet && storage_url[0])
    rewrite_url_snet(storage_url);
  pthread_mutex_unlock(&pool_mut);
  return (response >= 200 && response < 300 && storage_token[0] && storage_url[0]);
}
Beispiel #3
0
int cloudfs_connect()
{
  long response = -1;

  xmlNode *top_node = NULL, *service_node = NULL, *endpoint_node = NULL;
  xmlParserCtxtPtr xmlctx = NULL;

  char *postdata;
  if (reconnect_args.tenant[0])
  {
      int count = asprintf(&postdata,
         "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
         "<auth xmlns=\"http://docs.openstack.org/identity/api/v2.0\" tenantName=\"%s\">"
         "<passwordCredentials username=\"%s\" password=\"%s\"/>"
         "</auth>",
         reconnect_args.tenant, reconnect_args.username, reconnect_args.password);
      if (count < 0)
      {
        debugf("Unable to asprintf");
        abort();
      }
  }

  pthread_mutex_lock(&pool_mut);
  debugf("Authenticating...");
  storage_token[0] = storage_url[0] = '\0';

  CURL *curl = curl_easy_init();

  curl_slist *headers = NULL;
  if (reconnect_args.tenant[0])
  {
    add_header(&headers, "Content-Type", "application/xml");
    add_header(&headers, "Accept", "application/xml");

    curl_easy_setopt(curl, CURLOPT_POST, 1);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postdata);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(postdata));

    xmlctx = xmlCreatePushParserCtxt(NULL, NULL, "", 0, NULL);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, xmlctx);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &xml_dispatch);
  }
  else
  {
    add_header(&headers, "X-Auth-User", reconnect_args.username);
    add_header(&headers, "X-Auth-Key", reconnect_args.password);
  }

  curl_easy_setopt(curl, CURLOPT_VERBOSE, debug);
  curl_easy_setopt(curl, CURLOPT_URL, reconnect_args.authurl);
  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
  curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, &header_dispatch);
  curl_easy_setopt(curl, CURLOPT_USERAGENT, USER_AGENT);
  curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, verify_ssl);
  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, verify_ssl);
  curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
  curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
  curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 1);

  curl_easy_perform(curl);
  curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
  curl_slist_free_all(headers);
  curl_easy_cleanup(curl);

  if (reconnect_args.tenant[0])
  {
    free(postdata);
    xmlParseChunk(xmlctx, "", 0, 1);
    if (xmlctx->wellFormed && response >= 200 && response < 300)
    {
      xmlNode *root_element = xmlDocGetRootElement(xmlctx->myDoc);
      for (top_node = root_element->children; top_node; top_node = top_node->next)
      {
        if ((top_node->type == XML_ELEMENT_NODE) &&
           (!strcasecmp((const char *)top_node->name, "serviceCatalog")))
        {
          for (service_node = top_node->children; service_node; service_node = service_node->next)
            if ((service_node->type == XML_ELEMENT_NODE) &&
               (!strcasecmp((const char *)service_node->name, "service")))
            {
              xmlChar * serviceType = xmlGetProp(service_node, "type");
              int isObjectStore = serviceType && !strcasecmp(serviceType, "object-store");
              xmlFree(serviceType);

              if (!isObjectStore) continue;

              for (endpoint_node = service_node->children; endpoint_node; endpoint_node = endpoint_node->next)
                if ((endpoint_node->type == XML_ELEMENT_NODE) &&
                   (!strcasecmp((const char *)endpoint_node->name, "endpoint")))
                {
                  xmlChar * publicURL = xmlGetProp(endpoint_node, "publicURL");
                  xmlChar * region = xmlGetProp(endpoint_node, "region");
		  debugf("Found endpoint in region %s, URL is %s",region, publicURL);
                  if (publicURL)
                  {
                    
		    // fix, copy is now int, not char.
                    int copy = 1;
                    if (reconnect_args.region[0])
		    {
			debugf("Region option defined, looking for region %s", reconnect_args.region);
			if(!strcasecmp(reconnect_args.region, region))
			{
				debugf("Found region %s, using this URL %s", region, publicURL);

			}
			else
			{
				debugf("These are not the droids we are looking for... %s", region);
				copy=0;
			}

		    }
                    if (storage_url[0])
                    {
                      if (strstr(publicURL, "cdn"))
                      {
                        copy = 0;
                        debugf("Warning - found multiple object-store services; keeping %s, ignoring %s",
                                                     storage_url, publicURL);
                      }
                      else
		      {
			if(copy)
			{
                        debugf("Warning - found multiple object-store services; using %s instead of %s",
                                                     publicURL, storage_url);
			}
			else
			{
				debugf("Not copying, option override");
			}
		      }
                    }
                    if (copy)
                      strncpy(storage_url, publicURL, sizeof(storage_url));
                  }
		 
                  xmlFree(publicURL);
		  xmlFree(region);
                }
		debugf("Completed search for endpoint, result is %s", storage_url);
            }
        }

        if ((top_node->type == XML_ELEMENT_NODE) &&
            (!strcasecmp((const char *)top_node->name, "token")))
        {
          xmlChar * tokenId = xmlGetProp(top_node, "id");
          if (tokenId)
          {
            if (storage_token[0])
              debugf("Warning - found multiple authentication tokens.");
            strncpy(storage_token, tokenId, sizeof(storage_token));
          }
          xmlFree(tokenId);
        }
      }
    }
    xmlFreeParserCtxt(xmlctx);
  }
  if (reconnect_args.use_snet && storage_url[0])
    rewrite_url_snet(storage_url);
  pthread_mutex_unlock(&pool_mut);
  return (response >= 200 && response < 300 && storage_token[0] && storage_url[0]);
}