Mercurial > dropbear
comparison gensignkey.c @ 1336:efad433418c4
Use atomic key generation in all cases
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 19 Nov 2016 00:31:21 +0800 |
parents | 2bb4c662d1c2 |
children | 8747c2b19152 |
comparison
equal
deleted
inserted
replaced
1335:253c08951b96 | 1336:efad433418c4 |
---|---|
74 default: | 74 default: |
75 return 0; | 75 return 0; |
76 } | 76 } |
77 } | 77 } |
78 | 78 |
79 int signkey_generate(enum signkey_type keytype, int bits, const char* filename) | 79 /* if skip_exist is set it will silently return if the key file exists */ |
80 int signkey_generate(enum signkey_type keytype, int bits, const char* filename, int skip_exist) | |
80 { | 81 { |
81 sign_key * key = NULL; | 82 sign_key * key = NULL; |
82 buffer *buf = NULL; | 83 buffer *buf = NULL; |
84 char *fn_temp = NULL; | |
83 int ret = DROPBEAR_FAILURE; | 85 int ret = DROPBEAR_FAILURE; |
84 if (bits == 0) | 86 if (bits == 0) |
85 { | 87 { |
86 bits = get_default_bits(keytype); | 88 bits = get_default_bits(keytype); |
87 } | 89 } |
124 | 126 |
125 buf_put_priv_key(buf, key, keytype); | 127 buf_put_priv_key(buf, key, keytype); |
126 sign_key_free(key); | 128 sign_key_free(key); |
127 key = NULL; | 129 key = NULL; |
128 buf_setpos(buf, 0); | 130 buf_setpos(buf, 0); |
129 ret = buf_writefile(buf, filename); | |
130 | 131 |
131 buf_burn(buf); | 132 fn_temp = m_malloc(strlen(filename) + 30); |
132 buf_free(buf); | 133 snprintf(fn_temp, strlen(filename)+30, "%s.tmp%d", filename, getpid()); |
133 buf = NULL; | 134 ret = buf_writefile(buf, fn_temp); |
135 | |
136 if (ret == DROPBEAR_FAILURE) { | |
137 goto out; | |
138 } | |
139 | |
140 if (link(fn_temp, filename) < 0) { | |
141 /* If generating keys on connection (skipexist) it's OK to get EEXIST | |
142 - we probably just lost a race with another connection to generate the key */ | |
143 if (!(skip_exist && errno == EEXIST)) { | |
144 dropbear_log(LOG_ERR, "Failed moving key file to %s: %s", filename, | |
145 strerror(errno)); | |
146 /* XXX fallback to non-atomic copy for some filesystems? */ | |
147 ret = DROPBEAR_FAILURE; | |
148 goto out; | |
149 } | |
150 } | |
151 | |
152 out: | |
153 if (buf) { | |
154 buf_burn(buf); | |
155 buf_free(buf); | |
156 } | |
157 | |
158 if (fn_temp) { | |
159 unlink(fn_temp); | |
160 m_free(fn_temp); | |
161 } | |
162 | |
134 return ret; | 163 return ret; |
135 } | 164 } |