aboutsummaryrefslogtreecommitdiff
path: root/src/util/crypto_ecc_setup.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-12-19 18:43:38 +0100
committerChristian Grothoff <christian@grothoff.org>2020-12-19 18:43:38 +0100
commit3636ea628d051cf2ba7a9038c50528c561d0aeaa (patch)
tree87664b904950052e8b6997a371ed5ecb1ea4b310 /src/util/crypto_ecc_setup.c
parent74d7528e6bd53cf5acc939c63a5be74a001e5ce1 (diff)
downloadgnunet-3636ea628d051cf2ba7a9038c50528c561d0aeaa.tar.gz
gnunet-3636ea628d051cf2ba7a9038c50528c561d0aeaa.zip
change GNUNET_DISK_fn_write() to always do atomic writes and to NOT overwrite existing files; also change the return value to not return the size of the written file but GNUNET_OK on success, and integrate creating the directory if needed; breaks API, hence bumping libgnunetutil version
Diffstat (limited to 'src/util/crypto_ecc_setup.c')
-rw-r--r--src/util/crypto_ecc_setup.c118
1 files changed, 11 insertions, 107 deletions
diff --git a/src/util/crypto_ecc_setup.c b/src/util/crypto_ecc_setup.c
index 6c71030b2..f7cd8c6d9 100644
--- a/src/util/crypto_ecc_setup.c
+++ b/src/util/crypto_ecc_setup.c
@@ -61,7 +61,7 @@
61 * @param buf_size number of bytes in @a buf 61 * @param buf_size number of bytes in @a buf
62 * @return #GNUNET_OK on success 62 * @return #GNUNET_OK on success
63 */ 63 */
64static int 64static enum GNUNET_GenericReturnValue
65read_from_file (const char *filename, 65read_from_file (const char *filename,
66 void *buf, 66 void *buf,
67 size_t buf_size) 67 size_t buf_size)
@@ -123,104 +123,6 @@ read_from_file (const char *filename,
123 123
124 124
125/** 125/**
126 * Write contents of @a buf atomically to @a filename.
127 * Fail if @a filename already exists or if not exactly
128 * @a buf with @a buf_size bytes could be written to
129 * @a filename.
130 *
131 * @param filename where to write
132 * @param buf buffer to write
133 * @param buf_size number of bytes in @a buf to write
134 * @return #GNUNET_OK on success,
135 * #GNUNET_NO if a file existed under @a filename
136 * #GNUNET_SYSERR on failure
137 */
138static int
139atomic_write_to_file (const char *filename,
140 const void *buf,
141 size_t buf_size)
142{
143 char *tmpl;
144 int fd;
145
146 if (GNUNET_OK !=
147 GNUNET_DISK_directory_create_for_file (filename))
148 {
149 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
150 "mkstemp",
151 filename);
152 return GNUNET_SYSERR;
153 }
154 {
155 char *dname;
156
157 dname = GNUNET_strdup (filename);
158 GNUNET_asprintf (&tmpl,
159 "%s/XXXXXX",
160 dirname (dname));
161 GNUNET_free (dname);
162 }
163 fd = mkstemp (tmpl);
164 if (-1 == fd)
165 {
166 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
167 "mkstemp",
168 tmpl);
169 GNUNET_free (tmpl);
170 return GNUNET_SYSERR;
171 }
172 if (0 != fchmod (fd,
173 S_IRUSR))
174 {
175 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
176 "chmod",
177 tmpl);
178 GNUNET_assert (0 == close (fd));
179 if (0 != unlink (tmpl))
180 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
181 "unlink",
182 tmpl);
183 GNUNET_free (tmpl);
184 return GNUNET_SYSERR;
185 }
186 if (buf_size !=
187 write (fd,
188 buf,
189 buf_size))
190 {
191 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
192 "write",
193 tmpl);
194 GNUNET_assert (0 == close (fd));
195 if (0 != unlink (tmpl))
196 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
197 "unlink",
198 tmpl);
199 GNUNET_free (tmpl);
200 return GNUNET_SYSERR;
201 }
202 GNUNET_assert (0 == close (fd));
203
204 if (0 != link (tmpl,
205 filename))
206 {
207 if (0 != unlink (tmpl))
208 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
209 "unlink",
210 tmpl);
211 GNUNET_free (tmpl);
212 return GNUNET_NO;
213 }
214 if (0 != unlink (tmpl))
215 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
216 "unlink",
217 tmpl);
218 GNUNET_free (tmpl);
219 return GNUNET_OK;
220}
221
222
223/**
224 * @ingroup crypto 126 * @ingroup crypto
225 * @brief Create a new private key by reading it from a file. 127 * @brief Create a new private key by reading it from a file.
226 * 128 *
@@ -235,12 +137,12 @@ atomic_write_to_file (const char *filename,
235 * @return #GNUNET_OK on success, #GNUNET_NO if @a do_create was set but 137 * @return #GNUNET_OK on success, #GNUNET_NO if @a do_create was set but
236 * we found an existing file, #GNUNET_SYSERR on failure 138 * we found an existing file, #GNUNET_SYSERR on failure
237 */ 139 */
238int 140enum GNUNET_GenericReturnValue
239GNUNET_CRYPTO_eddsa_key_from_file (const char *filename, 141GNUNET_CRYPTO_eddsa_key_from_file (const char *filename,
240 int do_create, 142 int do_create,
241 struct GNUNET_CRYPTO_EddsaPrivateKey *pkey) 143 struct GNUNET_CRYPTO_EddsaPrivateKey *pkey)
242{ 144{
243 int ret; 145 enum GNUNET_GenericReturnValue ret;
244 146
245 if (GNUNET_OK == 147 if (GNUNET_OK ==
246 read_from_file (filename, 148 read_from_file (filename,
@@ -251,9 +153,10 @@ GNUNET_CRYPTO_eddsa_key_from_file (const char *filename,
251 return (do_create) ? GNUNET_NO : GNUNET_OK; 153 return (do_create) ? GNUNET_NO : GNUNET_OK;
252 } 154 }
253 GNUNET_CRYPTO_eddsa_key_create (pkey); 155 GNUNET_CRYPTO_eddsa_key_create (pkey);
254 ret = atomic_write_to_file (filename, 156 ret = GNUNET_DISK_fn_write (filename,
255 pkey, 157 pkey,
256 sizeof (*pkey)); 158 sizeof (*pkey),
159 GNUNET_DISK_PERM_USER_READ);
257 if ( (GNUNET_OK == ret) || 160 if ( (GNUNET_OK == ret) ||
258 (GNUNET_SYSERR == ret) ) 161 (GNUNET_SYSERR == ret) )
259 return ret; 162 return ret;
@@ -286,7 +189,7 @@ GNUNET_CRYPTO_eddsa_key_from_file (const char *filename,
286 * @return #GNUNET_OK on success, #GNUNET_NO if @a do_create was set but 189 * @return #GNUNET_OK on success, #GNUNET_NO if @a do_create was set but
287 * we found an existing file, #GNUNET_SYSERR on failure 190 * we found an existing file, #GNUNET_SYSERR on failure
288 */ 191 */
289int 192enum GNUNET_GenericReturnValue
290GNUNET_CRYPTO_ecdsa_key_from_file (const char *filename, 193GNUNET_CRYPTO_ecdsa_key_from_file (const char *filename,
291 int do_create, 194 int do_create,
292 struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey) 195 struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey)
@@ -301,9 +204,10 @@ GNUNET_CRYPTO_ecdsa_key_from_file (const char *filename,
301 } 204 }
302 GNUNET_CRYPTO_ecdsa_key_create (pkey); 205 GNUNET_CRYPTO_ecdsa_key_create (pkey);
303 if (GNUNET_OK == 206 if (GNUNET_OK ==
304 atomic_write_to_file (filename, 207 GNUNET_DISK_fn_write (filename,
305 pkey, 208 pkey,
306 sizeof (*pkey))) 209 sizeof (*pkey),
210 GNUNET_DISK_PERM_USER_READ))
307 return GNUNET_OK; 211 return GNUNET_OK;
308 /* maybe another process succeeded in the meantime, try reading one more time */ 212 /* maybe another process succeeded in the meantime, try reading one more time */
309 if (GNUNET_OK == 213 if (GNUNET_OK ==
@@ -357,7 +261,7 @@ GNUNET_CRYPTO_eddsa_key_create_from_configuration (
357 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the identity 261 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the identity
358 * could not be retrieved 262 * could not be retrieved
359 */ 263 */
360int 264enum GNUNET_GenericReturnValue
361GNUNET_CRYPTO_get_peer_identity (const struct GNUNET_CONFIGURATION_Handle *cfg, 265GNUNET_CRYPTO_get_peer_identity (const struct GNUNET_CONFIGURATION_Handle *cfg,
362 struct GNUNET_PeerIdentity *dst) 266 struct GNUNET_PeerIdentity *dst)
363{ 267{