From 06265eddad24618d9f464c56887f5ab79a792815 Mon Sep 17 00:00:00 2001 From: Iwan Timmer Date: Thu, 23 Jul 2015 12:47:04 +0200 Subject: [PATCH] Specify directory to load certificate data from --- libgamestream/client.c | 62 ++++++++++++++++++++++++++++++------------ libgamestream/client.h | 2 +- libgamestream/http.c | 31 +++++++++++---------- libgamestream/http.h | 5 +++- src/main.c | 2 +- 5 files changed, 66 insertions(+), 36 deletions(-) diff --git a/libgamestream/client.c b/libgamestream/client.c index 6c3d569..0070806 100644 --- a/libgamestream/client.c +++ b/libgamestream/client.c @@ -36,10 +36,8 @@ #include #include -static const char *uniqueFileName = "uniqueid.dat"; -static const char *certificateFileName = "client.pem"; -static const char *p12FileName = "client.p12"; -static const char *keyFileName = "key.pem"; +#define UNIQUE_FILE_NAME "uniqueid.dat" +#define P12_FILE_NAME "client.p12" #define UNIQUEID_BYTES 8 #define UNIQUEID_CHARS (UNIQUEID_BYTES*2) @@ -49,42 +47,60 @@ static X509 *cert; static char cert_hex[4096]; static EVP_PKEY *privateKey; -static void load_unique_id() { - FILE *fd = fopen(uniqueFileName, "r"); +static int load_unique_id(const char* keyDirectory) { + char uniqueFilePath[4096]; + sprintf(uniqueFilePath, "%s/%s", keyDirectory, UNIQUE_FILE_NAME); + + FILE *fd = fopen(uniqueFilePath, "r"); if (fd == NULL) { unsigned char unique_data[UNIQUEID_BYTES]; RAND_bytes(unique_data, UNIQUEID_BYTES); for (int i = 0; i < UNIQUEID_BYTES; i++) { sprintf(unique_id + (i * 2), "%02x", unique_data[i]); } - fd = fopen(uniqueFileName, "w"); + fd = fopen(uniqueFilePath, "w"); + if (fd == NULL) + return GS_FAILED; + fwrite(unique_id, UNIQUEID_CHARS, 1, fd); } else { fread(unique_id, UNIQUEID_CHARS, 1, fd); } fclose(fd); unique_id[UNIQUEID_CHARS] = 0; + + return GS_OK; } -static void load_cert() { - FILE *fd = fopen(certificateFileName, "r"); +static int load_cert(const char* keyDirectory) { + char certificateFilePath[4096]; + sprintf(certificateFilePath, "%s/%s", keyDirectory, CERTIFICATE_FILE_NAME); + + char keyFilePath[4096]; + sprintf(&keyFilePath[0], "%s/%s", keyDirectory, KEY_FILE_NAME); + + FILE *fd = fopen(certificateFilePath, "r"); if (fd == NULL) { printf("Generating certificate..."); CERT_KEY_PAIR cert = mkcert_generate(); printf("done\n"); - mkcert_save(certificateFileName, p12FileName, keyFileName, cert); + + char p12FilePath[4096]; + sprintf(p12FilePath, "%s/%s", keyDirectory, P12_FILE_NAME); + + mkcert_save(certificateFilePath, p12FilePath, keyFilePath, cert); mkcert_free(cert); - fd = fopen(certificateFileName, "r"); + fd = fopen(certificateFilePath, "r"); } if (fd == NULL) { fprintf(stderr, "Can't open certificate file\n"); - exit(-1); + return GS_FAILED; } if (!(cert = PEM_read_X509(fd, NULL, NULL, NULL))) { fprintf(stderr, "Error loading cert into memory.\n"); - exit(-1); + return GS_FAILED; } rewind(fd); @@ -99,9 +115,16 @@ static void load_cert() { fclose(fd); - fd = fopen(keyFileName, "r"); + fd = fopen(keyFilePath, "r"); + if (fd == NULL) { + fprintf(stderr, "Error loading key into memory.\n"); + return GS_FAILED; + } + PEM_read_PrivateKey(fd, &privateKey, NULL, NULL); fclose(fd); + + return GS_OK; } static int load_server_status(const char *address, PSERVER_DATA server) { @@ -419,10 +442,13 @@ int gs_quit_app(PSERVER_DATA server) { return ret; } -int gs_init(PSERVER_DATA server, const char *address) { - http_init(); - load_unique_id(); - load_cert(); +int gs_init(PSERVER_DATA server, const char *address, const char *keyDirectory) { + if (load_unique_id(keyDirectory) != GS_OK) + return GS_FAILED; + if (load_cert(keyDirectory)) + return GS_FAILED; + + http_init(keyDirectory); return load_server_status(address, server); } diff --git a/libgamestream/client.h b/libgamestream/client.h index 3cfaad6..f0b3064 100644 --- a/libgamestream/client.h +++ b/libgamestream/client.h @@ -32,7 +32,7 @@ typedef struct _SERVER_DATA { int serverMajorVersion; } SERVER_DATA, *PSERVER_DATA; -int gs_init(PSERVER_DATA server, const char *address); +int gs_init(PSERVER_DATA server, const char *address, const char *keyDirectory); int gs_start_app(PSERVER_DATA server, PSTREAM_CONFIGURATION config, int appId, bool sops, bool localaudio); int gs_applist(PSERVER_DATA server, PAPP_LIST app_list); int gs_pair(PSERVER_DATA server, char* pin); diff --git a/libgamestream/http.c b/libgamestream/http.c index 8cd5202..64c7fc3 100644 --- a/libgamestream/http.c +++ b/libgamestream/http.c @@ -34,10 +34,8 @@ static size_t _write_curl(void *contents, size_t size, size_t nmemb, void *userp PHTTP_DATA mem = (PHTTP_DATA)userp; mem->memory = realloc(mem->memory, mem->size + realsize + 1); - if(mem->memory == NULL) { - fprintf(stderr, "Not enough memory\n"); + if(mem->memory == NULL) return 0; - } memcpy(&(mem->memory[mem->size]), contents, realsize); mem->size += realsize; @@ -46,17 +44,23 @@ static size_t _write_curl(void *contents, size_t size, size_t nmemb, void *userp return realsize; } -int http_init() { +int http_init(const char* keyDirectory) { curl = curl_easy_init(); if (curl) return GS_FAILED; - + + char certificateFilePath[4096]; + sprintf(certificateFilePath, "%s/%s", keyDirectory, CERTIFICATE_FILE_NAME); + + char keyFilePath[4096]; + sprintf(&keyFilePath[0], "%s/%s", keyDirectory, KEY_FILE_NAME); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1L); curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE,"PEM"); - curl_easy_setopt(curl, CURLOPT_SSLCERT, pCertFile); + curl_easy_setopt(curl, CURLOPT_SSLCERT, certificateFilePath); curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM"); - curl_easy_setopt(curl, CURLOPT_SSLKEY, pKeyFile); + curl_easy_setopt(curl, CURLOPT_SSLKEY, keyFilePath); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _write_curl); curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); @@ -71,16 +75,15 @@ int http_request(char* url, PHTTP_DATA data) { if (data->size > 0) { free(data->memory); data->memory = malloc(1); - if(data->memory == NULL) { - fprintf(stderr, "Not enough memory\n"); + if(data->memory == NULL) return GS_OUT_OF_MEMORY; - } + data->size = 0; } CURLcode res = curl_easy_perform(curl); if(res != CURLE_OK) { - fprintf(stderr, "Connection failed: %s\n", curl_easy_strerror(res)); + gs_error = curl_easy_strerror(res); return GS_FAILED; } else if (data->memory == NULL) { return GS_OUT_OF_MEMORY; @@ -95,13 +98,11 @@ void http_cleanup() { PHTTP_DATA http_create_data() { PHTTP_DATA data = malloc(sizeof(HTTP_DATA)); - if (data == NULL) { - fprintf(stderr, "Not enough memory\n"); + if (data == NULL) return NULL; - } + data->memory = malloc(1); if(data->memory == NULL) { - fprintf(stderr, "Not enough memory\n"); free(data); return NULL; } diff --git a/libgamestream/http.h b/libgamestream/http.h index b0355a1..be28344 100644 --- a/libgamestream/http.h +++ b/libgamestream/http.h @@ -21,12 +21,15 @@ #include +#define CERTIFICATE_FILE_NAME "client.pem" +#define KEY_FILE_NAME "key.pem" + typedef struct _HTTP_DATA { char *memory; size_t size; } HTTP_DATA, *PHTTP_DATA; -int http_init(); +int http_init(const char* keyDirectory); PHTTP_DATA http_create_data(); int http_request(char* url, PHTTP_DATA data); void http_free_data(PHTTP_DATA data); diff --git a/src/main.c b/src/main.c index 85e34d8..6ba1e73 100644 --- a/src/main.c +++ b/src/main.c @@ -289,7 +289,7 @@ int main(int argc, char* argv[]) { } PSERVER_DATA server; - if (gs_init(server, address) != GS_OK) { + if (gs_init(server, address, ".") != GS_OK) { fprintf(stderr, "Can't connect to server %s\n", address); exit(-1); }