From df528cefc57a5355fd071c1e03a555fd719bca19 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 9 Dec 2015 18:29:41 +0100 Subject: [PATCH] Using locking winpr file functions for known hosts. --- libfreerdp/crypto/certificate.c | 237 ++++++++++++++++++++++------------------ 1 file changed, 129 insertions(+), 108 deletions(-) diff --git a/libfreerdp/crypto/certificate.c b/libfreerdp/crypto/certificate.c index e8d2923..7665677 100644 --- a/libfreerdp/crypto/certificate.c +++ b/libfreerdp/crypto/certificate.c @@ -116,63 +116,55 @@ fail: static int certificate_data_match_legacy(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data) { - FILE* fp; + HANDLE fp; int match = 1; char* data; char* mdata; char* pline; char* hostname; - long size; + DWORD lowSize, highSize; + UINT64 size; size_t length; + DWORD read; - fp = fopen(certificate_store->legacy_file, "rb"); - if (!fp) + /* Assure POSIX style paths, CreateFile expects either '/' or '\\' */ + PathCchConvertStyleA(certificate_store->legacy_file, strlen(certificate_store->legacy_file), PATH_STYLE_UNIX); + fp = CreateFileA(certificate_store->legacy_file, GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (fp == INVALID_HANDLE_VALUE) return match; - if (fseek(fp, 0, SEEK_END) < 0) + if ((lowSize = GetFileSize(fp, &highSize)) == INVALID_FILE_SIZE) { - WLog_ERR(TAG, "fseek(%s) returned %s [%08X]", - certificate_store->legacy_file, strerror(errno), errno); - fclose(fp); - return match; - } - if ((size = ftell(fp)) < 0) - { - WLog_ERR(TAG, "ftell(%s) returned %s [%08X]", - certificate_store->legacy_file, strerror(errno), errno); - fclose(fp); - return match; - } - if (fseek(fp, 0, SEEK_SET) < 0) - { - WLog_ERR(TAG, "fseek(%s) returned %s [%08X]", - certificate_store->legacy_file, strerror(errno), errno); - fclose(fp); + WLog_ERR(TAG, "GetFileSize(%s) returned %s [%08X]", + certificate_store->legacy_file, strerror(errno), GetLastError()); + CloseHandle(fp); return match; } + size = (UINT64)lowSize | ((UINT64)highSize << 32); if (size < 1) { - fclose(fp); + CloseHandle(fp); return match; } mdata = (char*) malloc(size + 2); if (!mdata) { - fclose(fp); + CloseHandle(fp); return match; } data = mdata; - if (fread(data, size, 1, fp) != 1) + if (!ReadFile(fp, data, size, &read, NULL) || (read != size)) { free(data); - fclose(fp); + CloseHandle(fp); return match; } - fclose(fp); + CloseHandle(fp); data[size] = '\n'; data[size + 1] = '\0'; @@ -243,67 +235,59 @@ static int certificate_data_match_raw(rdpCertificateStore* certificate_store, char** fprint) { BOOL found = FALSE; - FILE* fp; + HANDLE fp; size_t length; char* data; char* mdata; char* pline; int match = 1; - long int size; + DWORD lowSize, highSize; + UINT64 size; char* hostname = NULL; char* subject = NULL; char* issuer = NULL; char* fingerprint = NULL; unsigned short port = 0; + DWORD read; - fp = fopen(certificate_store->file, "rb"); + /* Assure POSIX style paths, CreateFile expects either '/' or '\\' */ + PathCchConvertStyleA(certificate_store->file, strlen(certificate_store->file), PATH_STYLE_UNIX); + fp = CreateFileA(certificate_store->file, GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NORMAL, NULL); - if (!fp) + if (fp == INVALID_HANDLE_VALUE) return match; - if (fseek(fp, 0, SEEK_END) < 0) - { - WLog_ERR(TAG, "fseek(%s) returned %s [%08X]", - certificate_store->file, strerror(errno), errno); - fclose(fp); - return match; - } - if ((size = ftell(fp)) < 0) + if ((lowSize = GetFileSize(fp, &highSize)) == INVALID_FILE_SIZE) { - WLog_ERR(TAG, "ftell(%s) returned %s [%08X]", - certificate_store->file, strerror(errno), errno); - fclose(fp); - return match; - } - if (fseek(fp, 0, SEEK_SET) < 0) - { - WLog_ERR(TAG, "fseek(%s) returned %s [%08X]", - certificate_store->file, strerror(errno), errno); - fclose(fp); + WLog_ERR(TAG, "GetFileSize(%s) returned %s [%08X]", + certificate_store->legacy_file, strerror(errno), GetLastError()); + CloseHandle(fp); return match; } + size = (UINT64)lowSize | ((UINT64)highSize << 32); if (size < 1) { - fclose(fp); + CloseHandle(fp); return match; } mdata = (char*) malloc(size + 2); if (!mdata) { - fclose(fp); + CloseHandle(fp); return match; } data = mdata; - if (fread(data, size, 1, fp) != 1) + if (!ReadFile(fp, data, size, &read, NULL) || (read != size)) { - fclose(fp); free(data); + CloseHandle(fp); return match; } - fclose(fp); + CloseHandle(fp); data[size] = '\n'; data[size + 1] = '\0'; @@ -371,40 +355,36 @@ int certificate_data_match(rdpCertificateStore* certificate_store, BOOL certificate_data_replace(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data) { - FILE* fp; + HANDLE fp; BOOL rc = FALSE; size_t length; char* data; char* sdata; char* pline; - long int size; + UINT64 size; + DWORD read, written; + DWORD lowSize, highSize; - fp = fopen(certificate_store->file, "rb"); + /* Assure POSIX style paths, CreateFile expects either '/' or '\\' */ + PathCchConvertStyleA(certificate_store->file, strlen(certificate_store->file), PATH_STYLE_UNIX); + fp = CreateFileA(certificate_store->file, GENERIC_READ | GENERIC_WRITE, 0, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (!fp) - return FALSE; - /* Read the current contents of the file. */ - if (fseek(fp, 0, SEEK_END) < 0) - { - WLog_ERR(TAG, "fseek(%s) returned %s [%08X]", - certificate_store->file, strerror(errno), errno); - fclose(fp); + if (fp == INVALID_HANDLE_VALUE) return FALSE; - } - if ((size = ftell(fp)) < 0) + if ((lowSize = GetFileSize(fp, &highSize)) == INVALID_FILE_SIZE) { - WLog_ERR(TAG, "ftell(%s) returned %s [%08X]", - certificate_store->file, strerror(errno), errno); - fclose(fp); + WLog_ERR(TAG, "GetFileSize(%s) returned %s [%08X]", + certificate_store->legacy_file, strerror(errno), GetLastError()); + CloseHandle(fp); return FALSE; } + size = (UINT64)lowSize | ((UINT64)highSize << 32); - if (fseek(fp, 0, SEEK_SET) < 0) + if (size < 1) { - WLog_ERR(TAG, "fseek(%s) returned %s [%08X]", - certificate_store->file, strerror(errno), errno); - fclose(fp); + CloseHandle(fp); return FALSE; } @@ -415,22 +395,26 @@ BOOL certificate_data_replace(rdpCertificateStore* certificate_store, return FALSE; } - if (fread(data, size, 1, fp) != 1) + if (!ReadFile(fp, data, size, &read, NULL) || (read != size)) { - fclose(fp); free(data); + CloseHandle(fp); return FALSE; } - fclose(fp); - - fp = fopen(certificate_store->file, "wb"); + if (SetFilePointer(fp, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) + { + WLog_ERR(TAG, "SetFilePointer(%s) returned %s [%08X]", + certificate_store->file, strerror(errno), GetLastError()); + CloseHandle(fp); + return FALSE; + } - if (fp == NULL) + if (!SetEndOfFile(fp)) { - WLog_ERR(TAG, "freopen(%s) returned %s [%08X]", - certificate_store->file, strerror(errno), errno); - free(data); + WLog_ERR(TAG, "SetEndOfFile(%s) returned %s [%08X]", + certificate_store->file, strerror(errno), GetLastError()); + CloseHandle(fp); return FALSE; } @@ -451,6 +435,7 @@ BOOL certificate_data_replace(rdpCertificateStore* certificate_store, char* fingerprint = NULL; char* subject = NULL; char* issuer = NULL; + char* tdata; if (!certificate_split_line(pline, &hostname, &port, &subject, &issuer, &fingerprint)) WLog_WARN(TAG, "Skipping invalid %s entry %s!", @@ -464,26 +449,41 @@ BOOL certificate_data_replace(rdpCertificateStore* certificate_store, fingerprint = certificate_data->fingerprint; rc = TRUE; } - if (fprintf(fp, "%s %hu %s %s %s\n", hostname, port, fingerprint, subject, issuer) < 0) + + size = _snprintf(NULL, 0, "%s %hu %s %s %s\n", hostname, port, fingerprint, subject, issuer); + tdata = malloc(size + 1); + if (!tdata) + { + WLog_ERR(TAG, "malloc(%s) returned %s [%08X]", + certificate_store->file, strerror(errno), errno); + CloseHandle(fp); + return FALSE; + } + + if (_snprintf(tdata, size + 1, "%s %hu %s %s %s\n", hostname, port, fingerprint, subject, issuer) != size) { - WLog_ERR(TAG, "fprintf(%s) returned %s [%08X]", + WLog_ERR(TAG, "_snprintf(%s) returned %s [%08X]", certificate_store->file, strerror(errno), errno); - fclose(fp); + free(tdata); + CloseHandle(fp); return FALSE; } + if (!WriteFile(fp, tdata, size, &written, NULL) || (written != size)) + { + WLog_ERR(TAG, "WriteFile(%s) returned %s [%08X]", + certificate_store->file, strerror(errno), errno); + free(tdata); + CloseHandle(fp); + return FALSE; + } + free(tdata); } } pline = StrSep(&sdata, "\r\n"); } - if (fflush(fp) != 0) - { - WLog_WARN(TAG, "fflush(%s) returned %s [%08X]", - certificate_store->file, strerror(errno), errno); - } - - fclose(fp); + CloseHandle(fp); free(data); return rc; @@ -533,39 +533,60 @@ BOOL certificate_split_line(char* line, char** host, UINT16* port, char** subjec BOOL certificate_data_print(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data) { - FILE* fp; + HANDLE fp; + char* tdata; + UINT64 size; + DWORD written; /* reopen in append mode */ - fp = fopen(certificate_store->file, "ab"); + /* Assure POSIX style paths, CreateFile expects either '/' or '\\' */ + PathCchConvertStyleA(certificate_store->file, strlen(certificate_store->file), PATH_STYLE_UNIX); + fp = CreateFileA(certificate_store->file, GENERIC_WRITE, 0, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (!fp) + if (fp == INVALID_HANDLE_VALUE) return FALSE; - if (fseek(fp, 0, SEEK_END) < 0) + if (SetFilePointer(fp, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER) { - WLog_ERR(TAG, "fseek(%s) returned %s [%08X]", - certificate_store->file, strerror(errno), errno); - fclose(fp); + WLog_ERR(TAG, "SetFilePointer(%s) returned %s [%08X]", + certificate_store->file, strerror(errno), GetLastError()); + CloseHandle(fp); return FALSE; } - if (fprintf(fp, "%s %hu %s %s %s\n", certificate_data->hostname, certificate_data->port, + size = _snprintf(NULL, 0, "%s %hu %s %s %s\n", certificate_data->hostname, certificate_data->port, certificate_data->fingerprint, certificate_data->subject, - certificate_data->issuer) < 0) + certificate_data->issuer); + tdata = malloc(size + 1); + if (!tdata) { - WLog_ERR(TAG, "fprintf(%s) returned %s [%08X]", + WLog_ERR(TAG, "malloc(%s) returned %s [%08X]", certificate_store->file, strerror(errno), errno); - fclose(fp); + CloseHandle(fp); return FALSE; } - - if (fflush(fp) != 0) + if (_snprintf(tdata, size + 1, "%s %hu %s %s %s\n", certificate_data->hostname, certificate_data->port, + certificate_data->fingerprint, certificate_data->subject, + certificate_data->issuer) != size) + { + WLog_ERR(TAG, "_snprintf(%s) returned %s [%08X]", + certificate_store->file, strerror(errno), errno); + free(tdata); + CloseHandle(fp); + return FALSE; + } + if (!WriteFile(fp, tdata, size, &written, NULL) || (written != size)) { - WLog_WARN(TAG, "fflush(%s) returned %s [%08X]", + WLog_ERR(TAG, "WriteFile(%s) returned %s [%08X]", certificate_store->file, strerror(errno), errno); + free(tdata); + CloseHandle(fp); + return FALSE; } + free(tdata); - fclose(fp); + CloseHandle(fp); return TRUE; } -- 2.7.4