diff --git a/libkmipclient/kmip.c b/libkmipclient/kmip.c index 1c3a07d4..7d847798 100644 --- a/libkmipclient/kmip.c +++ b/libkmipclient/kmip.c @@ -1489,7 +1489,7 @@ retry: } if (i == 0 && server_cert_pem != NULL) { - fp = fopen(server_cert_pem, "w"); + fp = fopen_nofollow(server_cert_pem, "w"); if (fp == NULL) { rc = -errno; kmip_debug(debug, "Failed to open %s for write", @@ -1507,7 +1507,7 @@ retry: fp = NULL; if (server_pubkey_pem != NULL) { - fp = fopen(server_pubkey_pem, "w"); + fp = fopen_nofollow(server_pubkey_pem, "w"); if (fp == NULL) { rc = -errno; kmip_debug(debug, "Failed to open %s " @@ -1533,7 +1533,7 @@ retry: if (i > 0 && cert_chain_pem != NULL) { if (fp == NULL) - fp = fopen(cert_chain_pem, "w"); + fp = fopen_nofollow(cert_chain_pem, "w"); if (fp == NULL) { rc = -errno; kmip_debug(debug, "Failed to open %s for write", diff --git a/libkmipclient/utils.c b/libkmipclient/utils.c index ef70c453..0baf586c 100644 --- a/libkmipclient/utils.c +++ b/libkmipclient/utils.c @@ -12,9 +12,11 @@ #include #include +#include #include #include #include +#include #include "utils.h" #include "names.h" @@ -726,3 +728,32 @@ enum kmip_tag kmip_find_v1_attribute_name_tag(struct kmip_node *parent) return 0; } +FILE *fopen_nofollow(const char *path, const char *mode) +{ + int flags = O_NOFOLLOW; + int fd; + FILE *fp; + + /* Determine flags based on mode */ + if (mode[0] == 'r') + flags |= (mode[1] == '+') ? O_RDWR : O_RDONLY; + else if (mode[0] == 'w') + flags |= O_CREAT | O_TRUNC | + ((mode[1] == '+') ? O_RDWR : O_WRONLY); + else if (mode[0] == 'a') + flags |= O_CREAT | O_APPEND | + ((mode[1] == '+') ? O_RDWR : O_WRONLY); + else + return NULL; + + fd = open(path, flags, 0600); + if (fd < 0) + return NULL; + + fp = fdopen(fd, mode); + if (fp == NULL) { + close(fd); + return NULL; + } + return fp; +} diff --git a/libkmipclient/utils.h b/libkmipclient/utils.h index 89734feb..a8ef8c5c 100644 --- a/libkmipclient/utils.h +++ b/libkmipclient/utils.h @@ -58,4 +58,6 @@ void kmip_node_dump(struct kmip_node *node, bool debug); enum kmip_tag kmip_find_v1_attribute_name_tag(struct kmip_node *parent); +FILE *fopen_nofollow(const char *path, const char *mode); + #endif