mirror of
https://github.com/clearml/dropbear
synced 2025-01-31 02:46:58 +00:00
Fallback for key gen without hard link support (#89)
Add a non-atomic fallback for key generation on platforms where link() is not permitted (such as most stock Android installs) or on filesystems without hard link support (such as FAT).
This commit is contained in:
parent
002b79e2f9
commit
a26ad21c0a
29
gensignkey.c
29
gensignkey.c
@ -9,14 +9,21 @@
|
|||||||
#include "dbrandom.h"
|
#include "dbrandom.h"
|
||||||
|
|
||||||
/* Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
|
/* Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
|
||||||
static int buf_writefile(buffer * buf, const char * filename) {
|
static int buf_writefile(buffer * buf, const char * filename, int skip_exist) {
|
||||||
int ret = DROPBEAR_FAILURE;
|
int ret = DROPBEAR_FAILURE;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
|
|
||||||
fd = open(filename, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
|
fd = open(filename, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
dropbear_log(LOG_ERR, "Couldn't create new file %s: %s",
|
/* If generating keys on connection (skip_exist) it's OK to get EEXIST
|
||||||
filename, strerror(errno));
|
- we probably just lost a race with another connection to generate the key */
|
||||||
|
if (skip_exist && errno == EEXIST) {
|
||||||
|
ret = DROPBEAR_SUCCESS;
|
||||||
|
} else {
|
||||||
|
dropbear_log(LOG_ERR, "Couldn't create new file %s: %s",
|
||||||
|
filename, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +151,7 @@ int signkey_generate(enum signkey_type keytype, int bits, const char* filename,
|
|||||||
|
|
||||||
fn_temp = m_malloc(strlen(filename) + 30);
|
fn_temp = m_malloc(strlen(filename) + 30);
|
||||||
snprintf(fn_temp, strlen(filename)+30, "%s.tmp%d", filename, getpid());
|
snprintf(fn_temp, strlen(filename)+30, "%s.tmp%d", filename, getpid());
|
||||||
ret = buf_writefile(buf, fn_temp);
|
ret = buf_writefile(buf, fn_temp, 0);
|
||||||
|
|
||||||
if (ret == DROPBEAR_FAILURE) {
|
if (ret == DROPBEAR_FAILURE) {
|
||||||
goto out;
|
goto out;
|
||||||
@ -154,10 +161,16 @@ int signkey_generate(enum signkey_type keytype, int bits, const char* filename,
|
|||||||
/* If generating keys on connection (skipexist) it's OK to get EEXIST
|
/* If generating keys on connection (skipexist) it's OK to get EEXIST
|
||||||
- we probably just lost a race with another connection to generate the key */
|
- we probably just lost a race with another connection to generate the key */
|
||||||
if (!(skip_exist && errno == EEXIST)) {
|
if (!(skip_exist && errno == EEXIST)) {
|
||||||
dropbear_log(LOG_ERR, "Failed moving key file to %s: %s", filename,
|
if (errno == EPERM || errno == EACCES) {
|
||||||
strerror(errno));
|
/* Non-atomic fallback when hard-links not allowed or unsupported */
|
||||||
/* XXX fallback to non-atomic copy for some filesystems? */
|
buf_setpos(buf, 0);
|
||||||
ret = DROPBEAR_FAILURE;
|
ret = buf_writefile(buf, filename, skip_exist);
|
||||||
|
} else {
|
||||||
|
dropbear_log(LOG_ERR, "Failed moving key file to %s: %s", filename,
|
||||||
|
strerror(errno));
|
||||||
|
ret = DROPBEAR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user