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); }
/* 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; }
/* 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; }
/* 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, ¶ms); 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; }
//! //! 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, ¶ms); 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; }
//! //! 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); }
//! //! 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; }