From ffbfe5b9422389af10ca8948684dc2e3afa1c219 Mon Sep 17 00:00:00 2001 From: Hanno Heinrichs Date: Sun, 8 May 2016 14:50:33 +0200 Subject: [PATCH] Create private key file with restrictive permissions --- .../libinfinity/libinfinity-0.7-sections.txt | 1 + libinfinity/common/inf-cert-util.c | 5 +- libinfinity/common/inf-file-util.c | 72 +++++++++++++++++++ libinfinity/common/inf-file-util.h | 6 ++ 4 files changed, 82 insertions(+), 2 deletions(-) diff --git a/docs/reference/libinfinity/libinfinity-0.7-sections.txt b/docs/reference/libinfinity/libinfinity-0.7-sections.txt index f567fff5..2bf4f279 100644 --- a/docs/reference/libinfinity/libinfinity-0.7-sections.txt +++ b/docs/reference/libinfinity/libinfinity-0.7-sections.txt @@ -1420,6 +1420,7 @@ inf_file_util_delete_file inf_file_util_delete_single_directory inf_file_util_delete_directory inf_file_util_delete +inf_file_util_write_private_data
diff --git a/libinfinity/common/inf-cert-util.c b/libinfinity/common/inf-cert-util.c index d277148e..e34aecc8 100644 --- a/libinfinity/common/inf-cert-util.c +++ b/libinfinity/common/inf-cert-util.c @@ -33,6 +33,7 @@ **/ #include +#include #include #include @@ -604,7 +605,7 @@ inf_cert_util_write_private_key(gnutls_x509_privkey_t key, return FALSE; } - result = g_file_set_contents( + result = inf_file_util_write_private_data( filename, string->str, string->len, @@ -980,7 +981,7 @@ inf_cert_util_write_certificate_with_key(gnutls_x509_privkey_t key, return FALSE; } - g_file_set_contents( + result = inf_file_util_write_private_data( filename, string->str, string->len, diff --git a/libinfinity/common/inf-file-util.c b/libinfinity/common/inf-file-util.c index c4e0bcf3..295bc2f5 100644 --- a/libinfinity/common/inf-file-util.c +++ b/libinfinity/common/inf-file-util.c @@ -517,4 +517,76 @@ inf_file_util_delete(const gchar* path, return inf_file_util_delete_file(path, error); } +/** + * inf_file_util_write_private_data: + * @filename: Filename of the file to be written to. + * @data: Data that should be written to file. + * @length: Length of data in bytes. + * @error: Location to store error information, if any, or %NULL. + * + * Writes @data to the file pointed to by @filename. On Unix-like systems, + * @filename is created with 0600 permission. If the function fails, %FALSE is + * returned and @error is set. + * + * Returns: %TRUE on success or %FALSE on error. + */ +gboolean +inf_file_util_write_private_data(const gchar* filename, + const void* data, + size_t length, + GError** error) +{ +#ifdef G_OS_WIN32 + return g_file_set_contents( + filename, + data, + length, + error + ); +#else + gchar *temp_file = g_strconcat(filename, ".XXXXXX", NULL); + gint fd = g_mkstemp_full( + temp_file, + O_WRONLY|O_CREAT|O_TRUNC, + 0600 + ); + if (fd == -1) + { + inf_file_util_set_error_from_errno(error, errno); + g_free(temp_file); + return FALSE; + } + size_t remaining = length; + while (remaining > 0) + { + ssize_t written = write(fd, data, remaining); + if (written == -1) + { + inf_file_util_set_error_from_errno(error, errno); + g_close(fd, NULL); + g_unlink(temp_file); + g_free(temp_file); + return FALSE; + } + remaining -= written; + data = ((gchar*)data) + written; + } + if (g_close(fd, error) == FALSE) + { + g_unlink(temp_file); + g_free(temp_file); + return FALSE; + } + if (g_rename(temp_file, filename) == -1) + { + inf_file_util_set_error_from_errno(error, errno); + g_unlink(temp_file); + g_free(temp_file); + return FALSE; + } + g_free(temp_file); + return TRUE; +#endif +} + /* vim:set et sw=2 ts=2: */ diff --git a/libinfinity/common/inf-file-util.h b/libinfinity/common/inf-file-util.h index e15d21ad..e9829490 100644 --- a/libinfinity/common/inf-file-util.h +++ b/libinfinity/common/inf-file-util.h @@ -94,6 +94,12 @@ gboolean inf_file_util_delete(const gchar* path, GError** error); +gboolean +inf_file_util_write_private_data(const gchar* filename, + const void* data, + size_t length, + GError** error); + G_END_DECLS #endif /* __INF_FILE_UTIL_H__ */