Пример #1
0
int scInitConfig (void)
{
    struct stat mystat;
    char config [BUFSIZE];
    char * s;

    if (scConfigInit) {
      return 0;
    }
    
    if ((sc_sem = sem_alloc (1, "eucalyptus-storage-semaphore")) == NULL) { /* TODO: use this semaphore to fix the race */
        logprintfl (EUCAERROR, "failed to create and initialize a semaphore\n");
        return 1;
    }
    /* read in configuration */
    char * home = getenv (EUCALYPTUS_ENV_VAR_NAME);
    if (!home) {
        home = strdup(""); /* root by default */
    }
    
    snprintf(config, BUFSIZE, EUCALYPTUS_CONF_LOCATION, home);
    if (stat(config, &mystat)==0) {
        logprintfl (EUCAINFO, "SC is looking for configuration in %s\n", config);
        
        if (get_conf_var(config, INSTANCE_PATH, &s)>0){ 
            sc_instance_path = strdup (s); 
            free (s); 
        }

        if (get_conf_var(config, CONFIG_NC_CACHE_SIZE, &s)>0){ 
            cache_size_mb = atoll (s); 
            cache_free_mb = cache_size_mb;
            free (s); 
        }

        if (get_conf_var(config, CONFIG_NC_SWAP_SIZE, &s)>0){ 
            swap_size_mb = atoll (s); 
            free (s); 
        }
    }
    snprintf(add_key_command_path, BUFSIZE, EUCALYPTUS_ADD_KEY, home, home, home);
    
    /* we need to have valid path */
    if (check_directory(sc_instance_path)) {
	    logprintfl (EUCAERROR, "ERROR: INSTANCE_PATH (%s) does not exist!\n", sc_instance_path);
	    return(1);
    }

    if (euca_init_cert ()) {
        logprintfl (EUCAFATAL, "failed to find cryptographic certificates\n");
        return 1;
    }

    snprintf (disk_convert_command_path, BUFSIZE, EUCALYPTUS_DISK_CONVERT, home, home);

    scConfigInit=1;
    return(0);
}
Пример #2
0
/* caller must free the returned string */
char * euca_get_cert (unsigned char options) 
{
	if (!initialized) euca_init_cert ();
		
    char * cert_str = NULL;
    int s, fp;

    struct stat st;
    if (stat (cert_file, &st) != 0) {
        logprintfl (EUCAERROR, "error: cannot stat the certificate file %s\n", cert_file); 

    } else if ( (s = st.st_size*2) < 1) { /* *2 because we'll add characters */
        logprintfl (EUCAERROR, "error: certificate file %s is too small\n", cert_file); 

    } else if ( (cert_str = malloc (s+1)) == NULL ) { 
        logprintfl (EUCAERROR, "error: out of memory\n");

    } else if ( (fp = open (cert_file, O_RDONLY)) < 0 ) {
        logprintfl (EUCAERROR, "error: failed to open certificate file %s\n", cert_file);
        free (cert_str);
        cert_str = NULL;

    } else {
        ssize_t ret = -1;
        int got = 0; 

        while ( got < s && (ret = read (fp, cert_str + got, 1) ) == 1 ) {
            if ( options & CONCATENATE_CERT ) { /* omit all newlines */
                if ( cert_str [got] == '\n' ) 
                    continue;
            } else {
                if ( options & INDENT_CERT ) /* indent lines 2 through N with TABs */
                    if ( cert_str [got] == '\n' )
                        cert_str [++got] = '\t'; 
            }
            got++;
        }
        
        if (ret != 0) {
            logprintfl (EUCAERROR, "error: failed to read whole certificate file %s\n", cert_file);
            free (cert_str);
            cert_str = NULL;

        } else {
            if ( options & TRIM_CERT ) {
                if ( cert_str [got-1] == '\t' || 
                     cert_str [got-1] == '\n' ) got--;
                if ( cert_str [got-1] == '\n' ) got--; /* because of indenting */ 
            }
            cert_str [got] = '\0';
        }
        close (fp);
    }
    return cert_str;
}
Пример #3
0
/* caller must free the returned string */
char * euca_sign_url (const char * verb, const char * date, const char * url)
{
	if (!initialized) euca_init_cert ();
		
    char * sig_str = NULL;
    RSA * rsa = NULL;
    FILE * fp = NULL;

    if ( verb==NULL || date==NULL || url==NULL ) return NULL;

    if ( ( rsa = RSA_new() ) == NULL ) {
      logprintfl (EUCAERROR, "error: RSA_new() failed\n");
    } else if ( ( fp = fopen (pk_file, "r") ) == NULL) {
      logprintfl (EUCAERROR, "error: failed to open private key file %s\n", pk_file);
      RSA_free (rsa);
    } else {
      logprintfl (EUCADEBUG2, "euca_sign_url(): reading private key file %s\n", pk_file);
      PEM_read_RSAPrivateKey(fp, &rsa, NULL, NULL); /* read the PEM-encoded file into rsa struct */
      if ( rsa==NULL ) {
	logprintfl (EUCAERROR, "error: failed to read private key file %s\n", pk_file);
      } else {
	unsigned char * sig;
        
	// RSA_print_fp (stdout, rsa, 0); /* (for debugging) */
	if ( (sig = malloc(RSA_size(rsa))) == NULL) {
	  logprintfl (EUCAERROR, "error: out of memory (for RSA key)\n");
	} else {
	  unsigned char sha1 [SHA_DIGEST_LENGTH];
#define BUFSIZE 2024
	  char input [BUFSIZE];
	  unsigned int siglen;
	  int ret;
	  
	  /* finally, SHA1 and sign with PK */
	  assert ((strlen(verb)+strlen(date)+strlen(url)+4)<=BUFSIZE);
	  snprintf (input, BUFSIZE, "%s\n%s\n%s\n", verb, date, url);
	  logprintfl (EUCADEBUG2, "euca_sign_url(): signing input %s\n", get_string_stats(input));	
	  SHA1 ((unsigned char *)input, strlen(input), sha1);
	  if ((ret = RSA_sign (NID_sha1, sha1, SHA_DIGEST_LENGTH, sig, &siglen, rsa))!=1) {
	    logprintfl (EUCAERROR, "error: RSA_sign() failed\n");
	  } else {
	    logprintfl (EUCADEBUG2, "euca_sign_url(): signing output %d\n", sig[siglen-1]);	
	    sig_str = base64_enc (sig, siglen);
	    logprintfl (EUCADEBUG2, "euca_sign_url(): base64 signature %s\n", get_string_stats((char *)sig_str));	
	  }
	  free (sig);
	}
	RSA_free (rsa);
      }            
      fclose(fp);
    }
    
    return sig_str;
}
Пример #4
0
/* downloads a decrypted image from Walrus based on the manifest URL,
 * saves it to outfile */
static int walrus_request (const char * walrus_op, const char * verb, const char * requested_url, const char * outfile, const int do_compress)
{
	int code = ERROR;
	char url [BUFSIZE];

    strncpy (url, requested_url, BUFSIZE);
#if defined(CAN_GZIP)
    if (do_compress)
        snprintf (url, BUFSIZE, "%s%s", requested_url, "?IsCompressed=true");
#endif
    logprintfl (EUCAINFO, "walrus_request(): downloading %s\n", outfile);
    logprintfl (EUCAINFO, "                  from %s\n", url);

	/* isolate the PATH in the URL as it will be needed for signing */
	char * url_path; 
	if (strncasecmp (url, "http://", 7)!=0) {
		logprintfl (EUCAERROR, "walrus_request(): URL must start with http://...\n");
		return code;
	}
	if ((url_path=strchr(url+7, '/'))==NULL) { /* find first '/' after hostname */
		logprintfl (EUCAERROR, "walrus_request(): URL has no path\n");
		return code;
	}
	
	if (euca_init_cert()) {
		logprintfl (EUCAERROR, "walrus_request(): failed to initialize certificate\n");
		return code;
	} 

	FILE * fp = fopen64 (outfile, "w");
	if (fp==NULL) {
		logprintfl (EUCAERROR, "walrus_request(): failed to open %s for writing\n", outfile);
		return code;
	}

	CURL * curl;
	CURLcode result;
	curl = curl_easy_init ();
	if (curl==NULL) {
		logprintfl (EUCAERROR, "walrus_request(): could not initialize libcurl\n");
		fclose(fp);
		return code;
	}

	char error_msg [CURL_ERROR_SIZE];
	curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, error_msg);
	curl_easy_setopt (curl, CURLOPT_URL, url); 
	curl_easy_setopt (curl, CURLOPT_HEADERFUNCTION, write_header);

    if (strncmp (verb, "GET", 4)==0) {
        curl_easy_setopt (curl, CURLOPT_HTTPGET, 1L);
    } else if (strncmp (verb, "HEAD", 5)==0) {
        /* TODO: HEAD isn't very useful atm since we don't look at headers */
        curl_easy_setopt (curl, CURLOPT_NOBODY, 1L);
    } else {
	fclose(fp);
        logprintfl (EUCAERROR, "walrus_request(): invalid HTTP verb %s\n", verb);
        return ERROR; /* TODO: dealloc structs before returning! */
    }
	
	/* set up the default write function, but possibly override
     * it below, if compression is desired and possible */
	struct request params;
    params.fp = fp;
    curl_easy_setopt (curl, CURLOPT_WRITEDATA, &params);
    curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, write_data);
#if defined(CAN_GZIP)
	if (do_compress) {
		curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, write_data_zlib);
	}
#endif

	struct curl_slist * headers = NULL; /* beginning of a DLL with headers */
	headers = curl_slist_append (headers, "Authorization: Euca");

	char op_hdr [STRSIZE];
	if(walrus_op != NULL) {
	    snprintf (op_hdr, STRSIZE, "EucaOperation: %s", walrus_op);
	    headers = curl_slist_append (headers, op_hdr);
	}

	time_t t = time(NULL);
	char * date_str = asctime(localtime(&t)); /* points to a static area */
	if (date_str==NULL) {
	       fclose(fp);
       	       return ERROR;
	}
	assert (strlen(date_str)+7<=STRSIZE);
	date_str [strlen(date_str)-1] = '\0'; /* trim off the newline */
	char date_hdr [STRSIZE];
	snprintf (date_hdr, STRSIZE, "Date: %s", date_str);
	headers = curl_slist_append (headers, date_hdr);

	char * cert_str = euca_get_cert (0); /* read the cloud-wide cert */
	if (cert_str==NULL) {
	       fclose(fp);
       	       return ERROR;
	}
	char * cert64_str = base64_enc ((unsigned char *)cert_str, strlen(cert_str));
	assert (strlen(cert64_str)+11<=BUFSIZE);
	char cert_hdr [BUFSIZE];
	snprintf (cert_hdr, BUFSIZE, "EucaCert: %s", cert64_str);
    logprintfl (EUCADEBUG2, "walrus_request(): base64 certificate, %s\n", get_string_stats(cert64_str));
	headers = curl_slist_append (headers, cert_hdr);
	free (cert64_str);
	free (cert_str);

	char * sig_str = euca_sign_url (verb, date_str, url_path); /* create Walrus-compliant sig */
	if (sig_str==NULL) {
	       fclose(fp);
       	       return ERROR;
	}
	assert (strlen(sig_str)+16<=BUFSIZE);
	char sig_hdr [BUFSIZE];
	snprintf (sig_hdr, BUFSIZE, "EucaSignature: %s", sig_str);
	headers = curl_slist_append (headers, sig_hdr);

	curl_easy_setopt (curl, CURLOPT_HTTPHEADER, headers); /* register headers */
    if (walrus_op) {
        logprintfl (EUCADEBUG, "walrus_request(): writing %s/%s output to %s\n", verb, walrus_op, outfile);
    } else {
        logprintfl (EUCADEBUG, "walrus_request(): writing %s output to %s\n", verb, outfile);
	}
    int retries = TOTAL_RETRIES;
    int timeout = FIRST_TIMEOUT;
    do {
        params.total_wrote = 0L;
        params.total_calls = 0L;
#if defined(CAN_GZIP)
        if (do_compress) {
            /* allocate zlib inflate state */
            params.strm.zalloc = Z_NULL;
            params.strm.zfree = Z_NULL;
            params.strm.opaque = Z_NULL;
            params.strm.avail_in = 0;
            params.strm.next_in = Z_NULL;
            params.ret = inflateInit2 (&(params.strm), 31);
            if (params.ret != Z_OK) {
                zerr (params.ret, "walrus_request");
                break;
            }
        }
#endif

        result = curl_easy_perform (curl); /* do it */
        logprintfl (EUCADEBUG, "walrus_request(): wrote %ld bytes in %ld writes\n", params.total_wrote, params.total_calls);

#if defined(CAN_GZIP)
        if (do_compress) {
            inflateEnd(&(params.strm));
            if (params.ret != Z_STREAM_END) {
                zerr (params.ret, "walrus_request");
            }
        }
#endif

        if (result) { // curl error (connection or transfer failed)
            logprintfl (EUCAERROR,     "walrus_request(): %s (%d)\n", error_msg, result);
            if (retries > 0) {
                logprintfl (EUCAERROR, "                  download retry %d of %d will commence in %d seconds\n", retries, TOTAL_RETRIES, timeout);
            }
            sleep (timeout);
            fseek (fp, 0L, SEEK_SET);
            timeout <<= 1;
            retries--;

        } else {
            long httpcode;
            curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &httpcode);
            /* TODO: pull out response message, too */

            switch (httpcode) {
            case 200L: /* all good */
                logprintfl (EUCAINFO, "walrus_request(): saved image in %s\n", outfile);
                code = OK;
		retries = 0;
                break;
	    case 408L: /* timeout, retry */
	      logprintfl (EUCAWARN, "walrus_request(): server responded with HTTP code %ld (timeout), retrying\n", httpcode);
	      logcat (EUCADEBUG, outfile); /* dump the error from outfile into the log */
	      break;
            default: /* some kind of error */
                logprintfl (EUCAERROR, "walrus_request(): server responded with HTTP code %ld, retrying\n", httpcode);
                logcat (EUCADEBUG, outfile); /* dump the error from outfile into the log */
            }
        }
    } while (code!=OK && retries>0);
    fclose (fp);

    if ( code != OK ) {
        logprintfl (EUCAINFO, "walrus_request(): due to error, removing %s\n", outfile);
        remove (outfile);
    }

	free (sig_str);
	curl_slist_free_all (headers);
	curl_easy_cleanup (curl);
	return code;
}
Пример #5
0
//!
//! downloads a decrypted image from Walrus based on the manifest URL,
//! saves it to outfile
//!
//! @param[in] walrus_op
//! @param[in] verb
//! @param[in] requested_url
//! @param[in] outfile
//! @param[in] do_compress
//! @param[in] connect_timeout
//! @param[in] total_timeout
//!
//! @return EUCA_OK on success or proper error code. Known error code returned include: EUCA_ERROR.
//!
static int walrus_request_timeout(const char *walrus_op, const char *verb, const char *requested_url, const char *outfile, const int do_compress,
                                  int connect_timeout, int total_timeout)
{
    int code = EUCA_ERROR;
    char url[BUFSIZE];

    pthread_mutex_lock(&wreq_mutex);    /* lock for curl construction */

    euca_strncpy(url, requested_url, BUFSIZE);
#if defined(CAN_GZIP)
    if (do_compress)
        snprintf(url, BUFSIZE, "%s%s", requested_url, "?IsCompressed=true");
#endif /* CAN_GZIP */

    /* isolate the PATH in the URL as it will be needed for signing */
    char *url_path;
    if (strncasecmp(url, "http://", 7) != 0 && strncasecmp(url, "https://", 8) != 0) {
        logprintfl(EUCAERROR, "Walrus URL must start with http(s)://...\n");
        pthread_mutex_unlock(&wreq_mutex);
        return code;
    }
    if ((url_path = strchr(url + 8, '/')) == NULL) {    /* find first '/' after hostname */
        logprintfl(EUCAERROR, "Walrus URL has no path\n");
        pthread_mutex_unlock(&wreq_mutex);
        return code;
    }

    if (euca_init_cert()) {
        logprintfl(EUCAERROR, "failed to initialize certificate for Walrus request\n");
        pthread_mutex_unlock(&wreq_mutex);
        return code;
    }

    int fd = open(outfile, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);  // we do not truncate the file
    if (fd == -1 || lseek(fd, 0, SEEK_SET) == -1) {
        logprintfl(EUCAERROR, "failed to open %s for writing Walrus request\n", outfile);
        pthread_mutex_unlock(&wreq_mutex);
        if (fd >= 0)
            close(fd);
        return code;
    }

    logprintfl(EUCADEBUG, "will use URL: %s\n", url);

    CURL *curl;
    CURLcode result;
    curl = curl_easy_init();
    if (curl == NULL) {
        logprintfl(EUCAERROR, "could not initialize libcurl for Walrus request\n");
        close(fd);
        pthread_mutex_unlock(&wreq_mutex);
        return code;
    }

    char error_msg[CURL_ERROR_SIZE];
    curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error_msg);
    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, write_header);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); //! @todo make this optional?
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
    curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 360L);  // must have at least a 360 baud modem
    curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, 10L);    // abort if below speed limit for this many seconds
    // curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1); //! @todo remove the comment once we want to follow redirects (e.g., on HTTP 407)

    if (strncmp(verb, "GET", 4) == 0) {
        curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
    } else if (strncmp(verb, "HEAD", 5) == 0) {
        //! @todo HEAD isn't very useful atm since we don't look at headers
        curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
    } else {
        close(fd);
        logprintfl(EUCAERROR, "invalid HTTP verb %s in Walrus request\n", verb);
        pthread_mutex_unlock(&wreq_mutex);
        return EUCA_ERROR;      //! @todo dealloc structs before returning!
    }

    if (connect_timeout > 0) {
        curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, connect_timeout);
    }
    if (total_timeout > 0) {
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, total_timeout);
    }

    /* set up the default write function, but possibly override
     * it below, if compression is desired and possible */
    struct request params;
    params.fd = fd;
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &params);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
#if defined(CAN_GZIP)
    if (do_compress) {
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data_zlib);
    }
#endif /* CAN_GZIP */

    struct curl_slist *headers = NULL;  /* beginning of a DLL with headers */
    headers = curl_slist_append(headers, "Authorization: Euca");

    char op_hdr[STRSIZE];
    if (walrus_op != NULL) {
        snprintf(op_hdr, STRSIZE, "EucaOperation: %s", walrus_op);
        headers = curl_slist_append(headers, op_hdr);
    }

    time_t t = time(NULL);
    char date_str[26];
    if (ctime_r(&t, date_str) == NULL) {
        close(fd);
        pthread_mutex_unlock(&wreq_mutex);
        return EUCA_ERROR;
    }
    assert(strlen(date_str) + 7 <= STRSIZE);
    char *newline = strchr(date_str, '\n');
    if (newline != NULL) {
        *newline = '\0';
    }                           // remove newline that terminates asctime() output
    char date_hdr[STRSIZE];
    snprintf(date_hdr, STRSIZE, "Date: %s", date_str);
    headers = curl_slist_append(headers, date_hdr);

    char *cert_str = euca_get_cert(0);  /* read the cloud-wide cert */
    if (cert_str == NULL) {
        close(fd);
        pthread_mutex_unlock(&wreq_mutex);
        return EUCA_ERROR;
    }
    char *cert64_str = base64_enc((unsigned char *)cert_str, strlen(cert_str));
    assert(strlen(cert64_str) + 11 <= BUFSIZE);
    char cert_hdr[BUFSIZE];
    snprintf(cert_hdr, BUFSIZE, "EucaCert: %s", cert64_str);
    logprintfl(EUCATRACE, "base64 certificate: %s\n", get_string_stats(cert64_str));
    headers = curl_slist_append(headers, cert_hdr);
    EUCA_FREE(cert64_str);
    EUCA_FREE(cert_str);

    char *sig_str = euca_sign_url(verb, date_str, url_path);    /* create Walrus-compliant sig */
    if (sig_str == NULL) {
        close(fd);
        pthread_mutex_unlock(&wreq_mutex);
        return EUCA_ERROR;
    }
    assert(strlen(sig_str) + 16 <= BUFSIZE);
    char sig_hdr[BUFSIZE];
    snprintf(sig_hdr, BUFSIZE, "EucaSignature: %s", sig_str);
    headers = curl_slist_append(headers, sig_hdr);

    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);    /* register headers */
    if (walrus_op) {
        logprintfl(EUCADEBUG, "writing %s/%s output\n", verb, walrus_op);
        logprintfl(EUCADEBUG, "        from %s\n", url);
        logprintfl(EUCADEBUG, "        to %s\n", outfile);
    } else {
        logprintfl(EUCADEBUG, "writing %s output to %s\n", verb, outfile);
    }
    int retries = TOTAL_RETRIES;
    int timeout = FIRST_TIMEOUT;
    do {
        params.total_wrote = 0L;
        params.total_calls = 0L;
#if defined(CAN_GZIP)
        if (do_compress) {
            /* allocate zlib inflate state */
            params.strm.zalloc = Z_NULL;
            params.strm.zfree = Z_NULL;
            params.strm.opaque = Z_NULL;
            params.strm.avail_in = 0;
            params.strm.next_in = Z_NULL;
            params.ret = inflateInit2(&(params.strm), 31);
            if (params.ret != Z_OK) {
                zerr(params.ret, "walrus_request");
                break;
            }
        }
#endif /* CAN_GZIP */

        //! @todo There used to be a 'pthread_mutex_unlock(&wreq_mutex)' before curl invocation
        //! and a 'lock' after it, but under heavy load we were seeing failures inside
        //! libcurl code that would propagate to NC, implying lack of thread safety in
        //! the library. For now, we will serialize all curl operations, but in the future
        //! an approach to parallelizing Walrus downloads is necessary
        result = curl_easy_perform(curl);   /* do it */
        logprintfl(EUCADEBUG, "wrote %lld byte(s) in %lld write(s)\n", params.total_wrote, params.total_calls);

#if defined(CAN_GZIP)
        if (do_compress) {
            inflateEnd(&(params.strm));
            if (params.ret != Z_STREAM_END) {
                zerr(params.ret, "walrus_request");
            }
        }
#endif /* CAN_GZIP */

        if (result) {           // curl error (connection or transfer failed)
            logprintfl(EUCAERROR, "curl error: %s (%d)\n", error_msg, result);

        } else {
            long httpcode;
            curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpcode);
            //! @todo pull out response message, too

            switch (httpcode) {
            case 200L:         /* all good */
                logprintfl(EUCAINFO, "downloaded %s\n", outfile);
                code = EUCA_OK;
                break;
            case 408L:         /* timeout, retry */
                logprintfl(EUCAWARN, "server responded with HTTP code %ld (timeout) for %s\n", httpcode, url);
                //logcat (EUCADEBUG, outfile); /* dump the error from outfile into the log */
                break;
            default:           /* some kind of error */
                logprintfl(EUCAERROR, "server responded with HTTP code %ld for %s\n", httpcode, url);
                //logcat (EUCADEBUG, outfile); /* dump the error from outfile into the log */
                retries = 0;
                break;
            }
        }

        if (code != EUCA_OK && retries > 0) {
            logprintfl(EUCAWARN, "download retry %d of %d will commence in %d sec for %s\n", retries, TOTAL_RETRIES, timeout, url);
            sleep(timeout);
            lseek(fd, 0L, SEEK_SET);
            timeout <<= 1;
            if (timeout > MAX_TIMEOUT)
                timeout = MAX_TIMEOUT;
        }

        retries--;
    } while (code != EUCA_OK && retries > 0);
    close(fd);

    if (code != EUCA_OK) {
        logprintfl(EUCAWARN, "removing %s\n", outfile);
        remove(outfile);
    }

    EUCA_FREE(sig_str);
    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);
    pthread_mutex_unlock(&wreq_mutex);
    return code;
}
Пример #6
0
//!
//! Main entry point of the application
//!
//! @param[in] argc the number of parameter passed on the command line
//! @param[in] argv the list of arguments
//!
//! @return Always return 0 or exit(1) on failure
//!
int main(int argc, char **argv)
{
    char *sc_hostport = NULL;
    char *command = NULL;
    char *ip = NULL;
    char *instance_id = NULL;
    char *iqn = NULL;
    int ch = 0;

    log_file_set(NULL, NULL);
    log_params_set(EUCA_LOG_ALL, 0, 1);

    while ((ch = getopt(argc, argv, "hn:h:s:i:")) != -1) {
        switch (ch) {
        case 's':
            sc_hostport = optarg;
            break;
        case 'i':
            instance_id = optarg;
            break;
        case 'h':
            usage();                   // will exit
            break;
        case '?':
        default:
            fprintf(stderr, "ERROR: unknown parameter (try -h)\n");
            exit(1);
        }
    }
    argc -= optind;
    argv += optind;

    if (argc > 0) {
        command = argv[0];
        if (argc > 1) {
            fprintf(stderr, "WARNING: too many parameters (%d), using first one as command\n", argc);
            for (int i = 0; i <= argc; i++) {
                if (argv[i])
                    fprintf(stderr, "%d = %s\n", i, argv[i]);
            }
        }
    } else {
        fprintf(stderr, "ERROR: command not specified (try -h)\n");
        exit(1);
    }

    char configFile[BUFSIZE], policyFile[BUFSIZE];
    char *euca_home;
    char sc_url[BUFSIZE];

    euca_home = getenv("EUCALYPTUS");
    if (!euca_home) {
        euca_home = "";
    }

    snprintf(configFile, BUFSIZE, EUCALYPTUS_CONF_LOCATION, euca_home);
    snprintf(policyFile, BUFSIZE, EUCALYPTUS_POLICIES_DIR "/sc-client-policy.xml", euca_home);
    snprintf(sc_url, BUFSIZE, "http://%s/services/Storage", sc_hostport);

    char *instances_path;
    int rc;

    rc = get_conf_var(configFile, INSTANCE_PATH, &instances_path);

    char *instance_path = find_instance_path(instances_path, instance_id);
    eucaVolume volumes[EUCA_MAX_VOLUMES];
    char instance_xml[BUFSIZE];
    snprintf(instance_xml, BUFSIZE, "%s/instance.xml", instance_path);

    loop_through_volumes(instance_xml, volumes);

    ip = find_ip_addr();
    iqn = find_local_iqn();

    printf("Found local iqn=%s and local ip=%s\n", iqn, ip);

    for(int i = 0; i < EUCA_MAX_VOLUMES; i++){
        if(strlen(volumes[i].state) == 0 || strcmp(volumes[i].state, VOL_STATE_ATTACHED)) continue;

        printf("Performing operation on volume %d\nid=%s\ntoken=%s\ndevice=%s\nconnectionstring=%s\nbus=%s\nserial=%s\n", 
               i, volumes[i].id, volumes[i].attachment_token, volumes[i].device, volumes[i].connection_string, volumes[i].bus, volumes[i].serial);
        /***********************************************************/
        if (!strcmp(command, "ConnectVolumes")) {
            CHECK_PARAM(ip, "ip");
            CHECK_PARAM(iqn, "iqn");
            CHECK_PARAM(sc_hostport, "sc host and port");

            setup_iscsi(euca_home, configFile);
            euca_init_cert();

            char *libvirt_xml = NULL;
            ebs_volume_data *vol_data = NULL;

            if (connect_ebs_volume(volumes[i].id, volumes[i].serial, volumes[i].bus, sc_url, volumes[i].attachment_token, 1, policyFile, ip, iqn, &libvirt_xml, &vol_data) != EUCA_OK) {
                fprintf(stderr, "Error connecting ebs volume %s\n", volumes[i].id);
                exit(1);
            }

            /***********************************************************/
        } else if (!strcmp(command, "DisconnectVolumes")) {
            CHECK_PARAM(ip, "ip");
            CHECK_PARAM(iqn, "iqn");
            CHECK_PARAM(sc_hostport, "sc host and port");

            setup_iscsi(euca_home, configFile);
            euca_init_cert();

            if (disconnect_ebs_volume(sc_url, 1, policyFile, volumes[i].attachment_token, volumes[i].connection_string, ip, iqn) != EUCA_OK) {
                fprintf(stderr, "Error disconnecting ebs volume %s.\n", volumes[i].id);
                exit(1);
            }

            /***********************************************************/
        } else {
            fprintf(stderr, "ERROR: command %s unknown (try -h)\n", command);
            exit(1);
        }
    }

    _exit(0);
}
Пример #7
0
//!
//! Main entry point of the application
//!
//! @param[in] argc the number of parameter passed on the command line
//! @param[in] argv the list of arguments
//!
//! @return Always return 0
//!
int main(int argc, char **argv)
{
    printf("=====> testing misc.c\n");

    test_command("date");
    test_command("ls / -l | sort");
    test_command("/foo");
    {
        char c = 0;
        long l = 0;
        int i = 0;
        long long ll = 0;

        euca_lscanf("a1\na\na2\n", "a%d", &i);
        assert(i == 1);
        euca_lscanf("a\nab3\na   4\na5", "a %d", &i);
        assert(i == 4);
        euca_lscanf("", "%d", &i);
        euca_lscanf("\n\n\n", "%d", &i);
        euca_lscanf("abcdefg6", "g%d", &i);
        assert(i != 6);
        euca_lscanf("abcdefg", "ab%cdefg", &c);
        assert(c == 'c');
        euca_lscanf("a\na    7\na\n", "a %ld", &l);
        assert(l == 7L);
        euca_lscanf("a\n8a\na9\n", "a %lld", &ll);
        assert(ll == 9L);
    }

    printf("=====> testing auth.c\n");
    {
//int decrypt_string_with_node_and_symmetric_key(char *in_buffer, char *key_buffer, char**out_buffer)
        euca_init_cert();
        char *encrypted_symm_key =
            "YCvEugV7FynwQnyDbNX8hVFstseIpzhBCi6nxWZOUhVbivEf9Frkk7evxvQeSn9GUIvyNSE15Stts/CQmIGNsAKpAmjUoDzkkB/8EUCO9bgVi6IQl6SOzZCqX1hGCMZT1Ir32HXcwZcEbtDl0WpfLahjT9pZQAtDnnRT7H8+qysxUbEoL9Z2Yw5GneF5hRDWcA9Kce617oNbPFiZjLnnQr2iNsxyWb8LVj7KnBweJ8UJumgcWp26VsWoBUUCK/3adPAvOk/kalgrXZAk6fo/TqGUqdokjj1tz3rG7dcvTRuB0qwY1P8KfgRg3HABQcHjriKNvBYTVDhhEFDP2v0fiA==";
        char *encrypted_string =
            "yuDM7HLybe+7DdkYFt+7zXYCeB/WHIdXSw7eF14L8YONEWmZdTEJwgXcGYdRpfDlY821xYi3asgURP6k9gFtPxjDHv/VcEKENJk9i/RbiAp0rEZ+gmkN3HQE9PjfNmS83AS1OyUnDiK2VcFRID7QKHcMdGrL6EXg/0QT1cDuwF0VbL71tdSddpFUHanaHQy2PzqKVPjfAqKWDBanMZWXckhYuHAMDCFkASvx8tU/7TrCJ7O697sScCBUQXqBZFY7930se2Jscg2u0tGlyKEK11gPNAnrIihAmgMVH2ZUzN1Ds9kFtGPrxoyLZbaxwYD5yzrd0qRBRrErZEWvj63nV4SUXKsmI7xmWBBUbosWmQzTp3mcsmnU40mowoCbOpoWt33XrlTJTfxA+dI1pnDWZY00lgISZe9IgQTAgF5o8GECw7uTZoK5b6LCTOSJPZPE57BjH9naeOnKMaXEe/Zl+s3j26hYhA8tP3IQIzOjqHcAhRGe/o2nkgVzLAYfBnaqsppKa8wJ2+qMUyh2f00c0W0GBHaSAAVh1PzcQiTOoLXYx9HDNxxtaZqL0TFfWxXkKm+/VjSQLqZ6HBqZAqiWIatHkD4UU83gCBlfvxw6ML8Z9A0VDUVbuuXTMCA1Z48e+gHK7/m1+S0/h0tW8wTBJeO9G1JkYdCNjaszey9Dl32v0jgGKw3BSgIwM+//lNL3yEdPx3pdhFxsYV0++bLxbFqZ2xpeFXupGmrVAEUyeqo5xcehMCpmKlJmQINTAav5vo2GtXBPvbNJOF7oIRakbr6jDF811V5jU5Dlwu6A9Yn8cPpZplB23Wo+1hsg3DjUCz3RxOwi5uIyF3IRbqqyt9mx3QlaxrXfjA0HweHE7O5TkeWnLWiPTefHR4ldHgKfDV9KScJLpmhEIznuwfEQaO855Z6JovWq6nKyPYXRToajiMwotrf6Sjkod9mQTZkbt/KSK4/PlIex3GhFHAFkUOwKJkI+Qenf1B8hPVDvoJ6PPZTUo7h127USsiUaZfUISgH2mep1YUyAdXlg+obK5iLprLhJqZwXh7dsR4Efn91YFcqEsVtO284CxWASh5Mid+pJD6FxVU8/pbX/EEi963fQgw42SiQxVXCaMySVB/9zlBfPg0dwP8yxwD+SiJz5In+oTDmr+OhpY0vQzkt/UnhORFpvJM7i1scY/rjAz2j6LjsHca4bt/x0JYkM+Vr+tZ90iiS01+fQX/fgFih6l9RoLWsbnilTx39dtwI8pOPitO90glIQ3EvLLmvZN9nvx9JfWTuinAkpOqrlkbc9ccKsAWa1zvvfCzGgqONoJ499rGFsY6H81jXR4h8K2o9n/Xs/8Sp8I8IqWfmS/JKH21JquJi4gLpmmZ38Kv6V4R7j5YcB9YwnIfav/uAJTN9VD9NKOyFwfhDA2YT4ErzMk5UL3sfQIX6UCzaKCiOeH3nKHzM7X4aHSqtSbvVNVxQ0tMYvm2oVEojmaXWGHmWyoylXJ1v0eaK38SDzwdpef6UKXESPEMpnR0krqH8bC7lZyMx2OyKpse9hJbjhzOvgv91lkUG3kidPxKraTUwXUmxVlUgxfcCgknO93U+kopjiffJDe/xILawvpEq0KWBFfbFN679znyz+8AEud2WSYdz7KnYuoX3RmViid/Oj0w==";
        char *decrypted = NULL;
        int out_len = -1;
        if (decrypt_string_with_node_and_symmetric_key(encrypted_string, encrypted_symm_key, &decrypted, &out_len) != EUCA_OK) {
            printf("failed to decrypt using symmetric key\n");
        } else {
            printf("decrypted length: %d\n", out_len);
        }

    }

    printf("=====> testing data.c\n");
    {
#define INSTS 50
        bunchOfInstances *bag = NULL;
        ncInstance *inst = NULL;
        ncInstance *Insts[INSTS];
        int i, n;

        printf("========> testing instance struct management\n");
        free_instance(NULL);
        free_instance(&inst);
        inst = allocate_instance("the-uuid", "i1", NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0);
        assert(inst != NULL);
        free_instance(&inst);
        assert(inst == NULL);

        n = total_instances(&bag);
        assert(n == 0);
        bag = NULL;

        inst = find_instance(&bag, "foo");
        assert(inst == NULL);
        bag = NULL;

        n = remove_instance(&bag, NULL);
        assert(n != EUCA_OK);
        bag = NULL;

        for (i = 0; i < INSTS; i++) {
            char id[10];
            sprintf(id, "i-%d", i);
            inst = Insts[i] = allocate_instance("the-uuid", id, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0);
            assert(inst != NULL);
            n = add_instance(&bag, inst);
            assert(n == EUCA_OK);
        }
        n = total_instances(&bag);
        assert(n == INSTS);
        n = remove_instance(&bag, Insts[0]);
        assert(n == EUCA_OK);
        n = remove_instance(&bag, Insts[INSTS - 1]);
        assert(n == EUCA_OK);
        n = total_instances(&bag);
        assert(n == INSTS - 2);

        printf("========> testing volume struct management\n");
        ncVolume *v;
        inst = allocate_instance("the-uuid", "i2", NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0);
        assert(inst != NULL);
        for (i = 0; i < EUCA_MAX_VOLUMES; i++) {
            char id[10];
            sprintf(id, "v-%d", i);
            v = save_volume(inst, id, "tok", "rd", "ld", "ldr", VOL_STATE_ATTACHED);
            assert(v != NULL);
        }
        assert(is_volume_used(v));
        assert(save_volume(inst, "too-much", "tok", "rd", "ld", "ldr", VOL_STATE_ATTACHED) == NULL);
        assert(save_volume(inst, v->volumeId, NULL, NULL, NULL, NULL, NULL) != NULL);
        assert(save_volume(inst, v->volumeId, NULL, "RD", NULL, NULL, NULL) != NULL);
        assert(save_volume(inst, v->volumeId, NULL, NULL, "LD", NULL, NULL) != NULL);
        assert(save_volume(inst, v->volumeId, NULL, NULL, NULL, "LDR", NULL) != NULL);
        assert(save_volume(inst, v->volumeId, NULL, NULL, NULL, NULL, VOL_STATE_DETACHED) != NULL);
        assert(strcmp(v->attachmentToken, "RD") == 0);
        assert(save_volume(inst, "v-x1", NULL, NULL, NULL, NULL, VOL_STATE_ATTACHING) != NULL);
        assert(save_volume(inst, "v-x2", NULL, NULL, NULL, NULL, VOL_STATE_ATTACHING) == NULL);
        assert(save_volume(inst, "v-x1", NULL, NULL, NULL, NULL, VOL_STATE_DETACHING) != NULL);
        assert(save_volume(inst, "v-x2", NULL, NULL, NULL, NULL, VOL_STATE_ATTACHING) == NULL);
        assert(save_volume(inst, "v-x1", NULL, NULL, NULL, NULL, VOL_STATE_DETACHING_FAILED) != NULL);
        assert(save_volume(inst, "v-x2", NULL, NULL, NULL, NULL, VOL_STATE_ATTACHING) == NULL);
        assert(free_volume(inst, "v-x1") != NULL);
        for (i = 0; i < EUCA_MAX_VOLUMES - 1; i++) {
            char id[10];
            sprintf(id, "v-%d", i);
            v = free_volume(inst, id);
            assert(v != NULL);
        }
        free_instance(&inst);
        assert(inst == NULL);
    }

    printf("OK\n");
    return 0;
}