Rewrite buf_write_string_file to buffer_write_file, which is simpler to
use and can deal with not-null-terminated strings. Mostly implemented so
this can be easily reused for tls-crypt-v2 (client) key files.
Signed-off-by: Steffan Karger <steffan.karger@fox-it.com>
Acked-by: Antonio Quartulli <antonio@openvpn.net>
Tested-by: Antonio Quartulli <antonio@openvpn.net>
Message-Id: <1533542553-7383-1-git-send-email-steffan.karger@fox-it.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg17371.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
... | ... |
@@ -343,16 +343,33 @@ convert_to_one_line(struct buffer *buf) |
343 | 343 |
} |
344 | 344 |
} |
345 | 345 |
|
346 |
-/* NOTE: requires that string be null terminated */ |
|
347 |
-void |
|
348 |
-buf_write_string_file(const struct buffer *buf, const char *filename, int fd) |
|
346 |
+bool |
|
347 |
+buffer_write_file(const char *filename, const struct buffer *buf) |
|
349 | 348 |
{ |
350 |
- const int len = strlen((char *) BPTR(buf)); |
|
351 |
- const int size = write(fd, BPTR(buf), len); |
|
352 |
- if (size != len) |
|
349 |
+ bool ret = false; |
|
350 |
+ int fd = platform_open(filename, O_CREAT | O_TRUNC | O_WRONLY, |
|
351 |
+ S_IRUSR | S_IWUSR); |
|
352 |
+ if (fd == -1) |
|
353 |
+ { |
|
354 |
+ msg(M_ERRNO, "Cannot open file '%s' for write", filename); |
|
355 |
+ return false; |
|
356 |
+ } |
|
357 |
+ |
|
358 |
+ const int size = write(fd, BPTR(buf), BLEN(buf)); |
|
359 |
+ if (size != BLEN(buf)) |
|
353 | 360 |
{ |
354 |
- msg(M_ERR, "Write error on file '%s'", filename); |
|
361 |
+ msg(M_ERRNO, "Write error on file '%s'", filename); |
|
362 |
+ goto cleanup; |
|
363 |
+ } |
|
364 |
+ |
|
365 |
+ ret = true; |
|
366 |
+cleanup: |
|
367 |
+ if (close(fd) < 0) |
|
368 |
+ { |
|
369 |
+ msg(M_ERRNO, "Close error on file %s", filename); |
|
370 |
+ ret = false; |
|
355 | 371 |
} |
372 |
+ return ret; |
|
356 | 373 |
} |
357 | 374 |
|
358 | 375 |
/* |
... | ... |
@@ -469,11 +469,15 @@ const char *skip_leading_whitespace(const char *str); |
469 | 469 |
|
470 | 470 |
void string_null_terminate(char *str, int len, int capacity); |
471 | 471 |
|
472 |
-/* |
|
473 |
- * Write string in buf to file descriptor fd. |
|
474 |
- * NOTE: requires that string be null terminated. |
|
472 |
+/** |
|
473 |
+ * Write buffer contents to file. |
|
474 |
+ * |
|
475 |
+ * @param filename The filename to write the buffer to. |
|
476 |
+ * @param buf The buffer to write to the file. |
|
477 |
+ * |
|
478 |
+ * @return true on success, false otherwise. |
|
475 | 479 |
*/ |
476 |
-void buf_write_string_file(const struct buffer *buf, const char *filename, int fd); |
|
480 |
+bool buffer_write_file(const char *filename, const struct buffer *buf); |
|
477 | 481 |
|
478 | 482 |
/* |
479 | 483 |
* write a string to the end of a buffer that was |
... | ... |
@@ -1418,36 +1418,24 @@ read_key_file(struct key2 *key2, const char *file, const unsigned int flags) |
1418 | 1418 |
gc_free(&gc); |
1419 | 1419 |
} |
1420 | 1420 |
|
1421 |
-/* |
|
1422 |
- * Write key to file, return number of random bits |
|
1423 |
- * written. |
|
1424 |
- */ |
|
1425 | 1421 |
int |
1426 | 1422 |
write_key_file(const int nkeys, const char *filename) |
1427 | 1423 |
{ |
1428 | 1424 |
struct gc_arena gc = gc_new(); |
1429 | 1425 |
|
1430 |
- int fd, i; |
|
1431 |
- int nbits = 0; |
|
1426 |
+ int nbits = nkeys * sizeof(struct key) * 8; |
|
1432 | 1427 |
|
1433 | 1428 |
/* must be large enough to hold full key file */ |
1434 | 1429 |
struct buffer out = alloc_buf_gc(2048, &gc); |
1435 |
- struct buffer nbits_head_text = alloc_buf_gc(128, &gc); |
|
1436 | 1430 |
|
1437 | 1431 |
/* how to format the ascii file representation of key */ |
1438 | 1432 |
const int bytes_per_line = 16; |
1439 | 1433 |
|
1440 |
- /* open key file */ |
|
1441 |
- fd = platform_open(filename, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR); |
|
1442 |
- |
|
1443 |
- if (fd == -1) |
|
1444 |
- { |
|
1445 |
- msg(M_ERR, "Cannot open shared secret file '%s' for write", filename); |
|
1446 |
- } |
|
1447 |
- |
|
1434 |
+ /* write header */ |
|
1435 |
+ buf_printf(&out, "#\n# %d bit OpenVPN static key\n#\n", nbits); |
|
1448 | 1436 |
buf_printf(&out, "%s\n", static_key_head); |
1449 | 1437 |
|
1450 |
- for (i = 0; i < nkeys; ++i) |
|
1438 |
+ for (int i = 0; i < nkeys; ++i) |
|
1451 | 1439 |
{ |
1452 | 1440 |
struct key key; |
1453 | 1441 |
char *fmt; |
... | ... |
@@ -1463,9 +1451,6 @@ write_key_file(const int nkeys, const char *filename) |
1463 | 1463 |
"\n", |
1464 | 1464 |
&gc); |
1465 | 1465 |
|
1466 |
- /* increment random bits counter */ |
|
1467 |
- nbits += sizeof(key) * 8; |
|
1468 |
- |
|
1469 | 1466 |
/* write to holding buffer */ |
1470 | 1467 |
buf_printf(&out, "%s\n", fmt); |
1471 | 1468 |
|
... | ... |
@@ -1476,16 +1461,10 @@ write_key_file(const int nkeys, const char *filename) |
1476 | 1476 |
|
1477 | 1477 |
buf_printf(&out, "%s\n", static_key_foot); |
1478 | 1478 |
|
1479 |
- /* write number of bits */ |
|
1480 |
- buf_printf(&nbits_head_text, "#\n# %d bit OpenVPN static key\n#\n", nbits); |
|
1481 |
- buf_write_string_file(&nbits_head_text, filename, fd); |
|
1482 |
- |
|
1483 | 1479 |
/* write key file, now formatted in out, to file */ |
1484 |
- buf_write_string_file(&out, filename, fd); |
|
1485 |
- |
|
1486 |
- if (close(fd)) |
|
1480 |
+ if(!buffer_write_file(filename, &out)) |
|
1487 | 1481 |
{ |
1488 |
- msg(M_ERR, "Close error on shared secret file %s", filename); |
|
1482 |
+ nbits = -1; |
|
1489 | 1483 |
} |
1490 | 1484 |
|
1491 | 1485 |
/* zero memory which held file content (memory will be freed by GC) */ |
... | ... |
@@ -271,6 +271,11 @@ struct crypto_options |
271 | 271 |
#define RKF_INLINE (1<<1) |
272 | 272 |
void read_key_file(struct key2 *key2, const char *file, const unsigned int flags); |
273 | 273 |
|
274 |
+/** |
|
275 |
+ * Write nkeys 1024-bits keys to file. |
|
276 |
+ * |
|
277 |
+ * @returns number of random bits written, or -1 on failure. |
|
278 |
+ */ |
|
274 | 279 |
int write_key_file(const int nkeys, const char *filename); |
275 | 280 |
|
276 | 281 |
int read_passphrase_hash(const char *passphrase_file, |
... | ... |
@@ -1041,6 +1041,10 @@ do_genkey(const struct options *options) |
1041 | 1041 |
} |
1042 | 1042 |
|
1043 | 1043 |
nbits_written = write_key_file(2, options->shared_secret_file); |
1044 |
+ if (nbits_written < 0) |
|
1045 |
+ { |
|
1046 |
+ msg(M_FATAL, "Failed to write key file"); |
|
1047 |
+ } |
|
1044 | 1048 |
|
1045 | 1049 |
msg(D_GENKEY | M_NOPREFIX, |
1046 | 1050 |
"Randomly generated %d bit key written to %s", nbits_written, |