/** * Thread entry point */ void key_thread_func() { int ret; fcgienc_crypt fc; int timeout; int authtimeout, mktimeout, dktimeout; int shortest_timeout; unsigned long usec_elapsed = 0; struct timeval start_tv, end_tv; // check parameters if (!fcgienc_username || !fcgienc_password || !fcgienc_authserver || \ !fcgienc_masterkeyserver || !fcgienc_datakeyserver) { return; } memset(&fc, 0, sizeof(fcgienc_crypt)); // init timeout values authtimeout = mktimeout = dktimeout = 0; while (1) { shortest_timeout = KEY_THREAD_DEFAULT_TIMEOUT; timeout = 0; gettimeofday(&start_tv, NULL); // Authentication Token authtimeout -= 30; if (authtimeout <= 30) { fc.token[0] = 0; timeout = get_auth_token(fc.token); if (timeout > 0) { memcache_set(CACHE_KEYNAME_AUTHTOKEN, fc.token, timeout); authtimeout = timeout; shortest_timeout = MIN(shortest_timeout, authtimeout); mktimeout = dktimeout = -1; } else { log_keythread("KEY-THREAD - error fetching auth token from key server"); goto KEY_ERROR; } } ret = memcache_get(CACHE_KEYNAME_AUTHTOKEN, fc.token); if (ret < 0) { log_keythread("KEY-THREAD - error fetching auth token from memcached"); goto KEY_ERROR; } // Data Key dktimeout -= 30; if (dktimeout <= 30) { fc.dataKeyId[0] = 0; fc.encryptedDataKey[0] = 0; timeout = get_data_key(fc.token, fc.masterKeyId, fc.dataKeyId, fc.encryptedDataKey); if (timeout > 0) { memcache_set(CACHE_KEYNAME_MAKSTERKEYID, fc.masterKeyId, timeout); memcache_set(CACHE_KEYNAME_DATAKEYID, fc.dataKeyId, timeout); memcache_set(CACHE_KEYNAME_ENCRYPTEDDATAKEY, fc.encryptedDataKey, timeout); dktimeout = timeout; shortest_timeout = MIN(shortest_timeout, timeout); } else { log_keythread("KEY-THREAD - error fetching data key from key server"); goto KEY_ERROR; } } ret = memcache_get(CACHE_KEYNAME_MAKSTERKEYID, fc.masterKeyId); ret += memcache_get(CACHE_KEYNAME_DATAKEYID, fc.dataKeyId); ret += memcache_get(CACHE_KEYNAME_ENCRYPTEDDATAKEY, fc.encryptedDataKey); if (ret < 0) { log_keythread("KEY-THREAD - error fetching data key from memcache"); goto KEY_ERROR; } // Master Key mktimeout -= 30; if (mktimeout <= 30) { fc.masterKey[0] = 0; fc.initializationVector[0] = 0; timeout = get_master_key(fc.token, fc.masterKeyId, fc.masterKey, fc.initializationVector); if (timeout > 0) { memcache_set(CACHE_KEYNAME_MAKSTERKEY, fc.masterKey, timeout); memcache_set(CACHE_KEYNAME_IV, fc.initializationVector, timeout); shortest_timeout = MIN(shortest_timeout, timeout); mktimeout = timeout; } else { log_keythread("KEY-THREAD - error fetching master key from key server"); goto KEY_ERROR; } } ret = memcache_get(CACHE_KEYNAME_MAKSTERKEY, fc.masterKey); ret += memcache_get(CACHE_KEYNAME_IV, fc.initializationVector); if (ret < 0) { log_keythread("KEY-THREAD - error fetching master key from memcache"); goto KEY_ERROR; } // calculate the real key ret = key_calculate_real(&fc); if (ret == 0) { char dataKeyCacheName[KEY_SIZE]; memset(dataKeyCacheName, 0, KEY_SIZE); sprintf(dataKeyCacheName, "fastcgienc-%s-%s-%s", fc.masterKeyId, fc.dataKeyId, fcgienc_username); memcache_set(dataKeyCacheName, fc.dataKey, KEY_STORE_PERIOD); if (timeout <= 0) timeout = KEY_STORE_PERIOD; memcache_set(CACHE_KEYNAME_DATAKEY, fc.dataKey, 60); } else { log_keythread("KEY-THREAD - error decrypting data key"); goto KEY_ERROR; } gettimeofday(&end_tv, NULL); usec_elapsed = (end_tv.tv_sec * 1000 * 1000 + end_tv.tv_usec) - (start_tv.tv_sec * 1000 * 1000 + start_tv.tv_usec); // only sleep if no key has already expired if (SEC_TO_USEC(shortest_timeout) > usec_elapsed) { #ifdef WIN32 Sleep(1000 * shortest_timeout); #else usleep(SEC_TO_USEC(shortest_timeout) - usec_elapsed); #endif } continue; KEY_ERROR: log_keythread("KEY-THREAD - key error"); authtimeout = mktimeout = dktimeout = -1; #ifdef WIN32 Sleep(1000 * shortest_timeout); #else usleep(SEC_TO_USEC(shortest_timeout)); #endif } return; }
char *request(const char *url) { CURL *curl = NULL; CURLcode status; struct curl_slist *headers = NULL; char *data = NULL; long code; curl_global_init(CURL_GLOBAL_ALL); curl = curl_easy_init(); if(!curl) goto error; data = malloc(BUFFER_SIZE); if(!data) goto error; struct write_result write_result = { .data = data, .pos = 0 }; curl_easy_setopt(curl, CURLOPT_URL, url); headers = curl_slist_append(headers, "User-Agent: sea/0.1"); headers = curl_slist_append(headers, "Content-Type: application/json"); size_t token_size = 255; char *token = (char *)calloc(sizeof(char), token_size); get_auth_token(token, token_size); headers = curl_slist_append(headers, token); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); // headers = curl_slist_append(headers, sprintf("Authorization: Bearer %s", token)); // curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_response); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &write_result); status = curl_easy_perform(curl); if(status != 0) { fprintf(stderr, "error: unable to request data from %s:\n", url); fprintf(stderr, "%s\n", curl_easy_strerror(status)); goto error; } curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code); if(code != 200) { fprintf(stderr, "error: server responded with code %ld\n", code); goto error; } curl_easy_cleanup(curl); curl_slist_free_all(headers); curl_global_cleanup(); /* zero-terminate the result */ data[write_result.pos] = '\0'; return data; error: if(data) free(data); if(curl) curl_easy_cleanup(curl); if(headers) curl_slist_free_all(headers); if(token) free(token); curl_global_cleanup(); return NULL; }